Caravel CMS PHP Cross Reference Content Management Systems

Source: /apps/RSS/RSSReader.php - 401 lines - 18001 bytes - Summary - Text - Print

   1  <?php
   2  
   3  /**
   4  * Name:      RSSReader.php
   5  * App:       RSS - Reader mode
   6  * Desc:      Designed to select and display RSS news feeds.
   7               At the moment the feeds can only be fetched by URL; eventually
   8               you should be able to subscribe to channels from other template sites.
   9  * Creator:   David Glick <david@nonsensesofware.com>
  10  */
  11  class RSSReader
  12      {   
  13      var $feedSrc = ''; 
  14      var $numLinks = 'n';
  15      var $descLength = 'n';
  16      var $titleType = 'default';
  17      var $title = '';
  18      var $style = 'table';
  19      var $link = '';
  20      var $dispDate = false;
  21      
  22      var $parent;
  23      var $params;
  24      
  25      function init($parent)
  26          {
  27          // the way we are doing this right now is so ugly.  we need to enable multiple apps per folder to fix it.
  28          $obj = new RSSReader;
  29          $obj->parent =& $parent;
  30          $obj->params =& $parent->params;
  31          $obj->httpVars =& $parent->httpVars;
  32          $obj->sectionPathArray =& $parent->sectionPathArray;
  33          $obj->blockID = $parent->blockID;
  34  
  35          // make sure checkboxes get unset if necessary
  36          if ( isset($obj->params['update']) )
  37              {   
  38              $obj->params['numLinksUnlimited'] = isset($obj->parent->httpVars['numLinksUnlimited']) ? 'y' : '';
  39              $obj->params['descLengthUnlimited'] = isset($obj->parent->httpVars['descLengthUnlimited']) ? 'y' : '';
  40              $obj->params['dispDate'] = isset($obj->parent->httpVars['dispDate']) ? 'y' : '';
  41                $obj->params['dispAuth'] = isset($obj->parent->httpVars['dispAuth']) ? 'y' : '';
  42              }
  43          $obj->srcType = isset($obj->params['srcType']) ? $obj->params['srcType'] : 'url';
  44  
  45          if ($obj->srcType == 'url')
  46              $obj->feedSrc = isset($obj->params['srcURL']) ? $obj->params['srcURL'] : '';
  47          else
  48              $obj->feedSrc = isset($obj->params['srcDN']) ? $obj->params['srcDN'] : '';
  49  
  50          $obj->numLinks = isset($obj->params['numLinks']) ? $obj->params['numLinks'] : 10;
  51          $obj->descLength = isset($obj->params['descLength']) ? $obj->params['descLength'] : 25;
  52          $obj->titleType = isset($obj->params['titleType']) ? $obj->params['titleType'] : 'default';
  53          $obj->title = isset($obj->params['title']) ? $obj->params['title'] : '';
  54          $obj->dispDate = @$obj->params['dispDate'] ? 1 : 0;
  55          $obj->dispAuth = @$obj->params['dispAuth'] ? 1 : 0;
  56          $obj->style = isset($obj->params['displayStyle']) ? $obj->params['displayStyle'] : 'table';
  57          
  58          if(@$obj->params['numLinksUnlimited']) $obj->numLinks = 'n';
  59          if(@$obj->params['descLengthUnlimited']) $obj->descLength = 'n';
  60                  
  61          return $obj;
  62          }
  63          
  64      function getContent()
  65          {
  66          if ($this->srcType == 'url')
  67              return $this->viewRSS();
  68          else
  69              return $this->viewChannel();
  70          }    
  71          
  72      function viewRSS( )
  73          {
  74          if($this->feedSrc)
  75              {
  76              // include the Magpie RSS parser and set cache dir
  77              require_once  'magpie/rss_fetch.inc';
  78              if (!defined('MAGPIE_CACHE_DIR')) define('MAGPIE_CACHE_DIR', T_CACHE . 'rss/magpie');
  79              
  80              // turn off cache for immediate updates -- davidig 10/30/2003
  81              // turn back on because immediate updates annoy other servers' admins -- davidig 5/24/2005
  82              // if (!defined('MAGPIE_CACHE_ON')) define('MAGPIE_CACHE_ON', 0);
  83  
  84              // and fetch headlines
  85              $rss = fetch_rss($this->feedSrc);
  86              if ($rss)
  87                  $items = $rss->items;
  88              else
  89                  {
  90                  if ($this->parent->can('config') || $this->parent->can('rss'))
  91                      return 'Error reading news feed:' . magpie_error();
  92                  else
  93                      return 'Unable to contact news source.  Please inform the webmaster.';
  94                  }
  95  
  96              if(count($items))
  97                  {
  98                  // initialize template
  99                  $tpl = new Template_PHPLIB(T_APP_BASE . 'RSS');
 100                  $tpl->setFile(array('main' => "RSSReaderView_$this->style.tpl.html"));
 101                  $tpl->setVar('colWidth', isset($this->parent->colWidth) ? $this->parent->colWidth : 300);
 102  
 103                  $tpl->setBlock('main', 'titleBlock', 'titleB');
 104                  $tpl->setVar('titleB', '');
 105                  $tpl->setBlock('main', 'navBlock', 'navB');
 106                  $tpl->setVar('navB', '');
 107                  $tpl->setBlock('main','itemBlock','items');
 108                  $tpl->setVar('items', '');
 109  
 110                  if ($this->titleType == 'text')
 111                      $tpl->setVar('feedTitle', $this->title);
 112                  else
 113                      $tpl->setVar('feedTitle', $rss->channel['title'] );
 114                  $tpl->setVar( 'feedSite', $this->link ? $this->link : $rss->channel['link']);
 115                  if ($this->titleType != 'none')
 116                      $tpl->parse('titleB', 'titleBlock');
 117                      
 118                  $i = 0;
 119                  foreach ($items as $item)
 120                      {
 121                      if ( ++$i > $this->numLinks and $this->numLinks != 'n' )
 122                          break;
 123  
 124                      $tpl->setVar('rowClass', $i % 2 ? 'table1' : 'table2');
 125                      $tpl->setVar('itemURL', @$item['link'] );
 126                      $tpl->setVar('itemTitle', @$item['title'] );
 127                      $content = isset($item['description']) ? $item['description'] : (isset($item['atom_content']) ? $item['atom_content'] : '');
 128                      $tpl->setVar('itemDescription', RSSReader::abbreviate_description($content, $this->descLength));
 129                      if (isset($item['author_name']) and $this->dispAuth)
 130                          $tpl->setVar('itemAuthor', '<br /><div class="rssAuthor">' . $item['author_name'] . '</div>');
 131                      if (isset($item['pubdate']) and $this->dispDate)
 132                          $tpl->setVar('itemDate', '<br />' . date('M j', strtotime(@$item['pubdate'])));
 133                      $tpl->parse('items', 'itemBlock', true);
 134                      }
 135  
 136                  return $tpl->subst('main');                
 137                  }
 138              else
 139                  // no items
 140                  return '';
 141              }
 142          else
 143              // no feed source
 144              return '';
 145          }
 146          
 147      function viewChannel()
 148          {
 149          if($this->feedSrc)
 150              {
 151              // load channel from ldap
 152              $channel = Channel::load($this->feedSrc, $this->parent->ldap);
 153              if (mnError::isError($channel))
 154                  return 'Error loading channel.';
 155              
 156              $tpl = new Template_PHPLIB(T_APP_BASE . 'RSS');
 157              $tpl->setFile(array('main' => "RSSReaderView_$this->style.tpl.html"));
 158              $tpl->setVar('colWidth', isset($this->colWidth) ? $this->colWidth : 300);
 159  
 160              $tpl->setBlock('main', 'titleBlock', 'titleB');
 161              $tpl->setVar('titleB', '');
 162              $tpl->setBlock('main', 'navBlock', 'navB');
 163              $tpl->setVar('navB', '');
 164              $tpl->setBlock('main','itemBlock','items');
 165              $tpl->setVar('items', '');
 166  
 167              $channelLinks = '';
 168              if ($channel->checkOwnership())
 169                  $channelLinks .= $this->linkToEdit(array('mode' => 'editChannel', 'channel' => $channel->dn), 'Edit Channel Preferences', 'icons/prefs_16.png');
 170              if ($channel->checkPostingRights())
 171                  $channelLinks .= $this->linkToEdit(array('mode' => 'post', 'channels' => $channel->dn), 'Post to This Channel', 'icons/add_16.png');
 172              if ($channelLinks)
 173                  $channelLinks .= '&nbsp;';
 174              $tpl->setVar('channelLinks', $channelLinks);
 175  
 176              $title = '';
 177              if ($this->titleType == 'text')
 178                  $title = $this->title;
 179              else if ($this->titleType == 'default')
 180                  $title = $channel->name;
 181              $tpl->setVar('feedTitle', $title);
 182              $tpl->setVar('feedSite', $this->link ? $this->link : '#' );
 183              if ($this->titleType != 'none')
 184                  $tpl->parse('titleB', 'titleBlock');
 185  
 186              if ($this->numLinks > $channel->params['numLinks']) $this->numLinks = $channel->params['numLinks'];
 187              
 188              // handle links to external channels
 189              if(isset($channel->params['url']))
 190                  {
 191                  $this->feedSrc = $channel->params['url'];
 192                  if ($this->titleType == 'default')
 193                      {
 194                      $this->title = $channel->name;
 195                      $this->titleType = 'text';
 196                      }
 197                  return $this->viewRSS();
 198                  }
 199              
 200              // retrieve article links
 201              if(!isset($this->params['p'])) $this->params['p'] = 0;
 202              $items = $channel->articles($this->params['p'], $this->numLinks == 'n' ? null : $this->numLinks);
 203              if(mnError::isError($items))
 204                  return new mnError('RSSReader::view(): ' . $res->getMessage(), __FILE__, __LINE__);
 205  
 206              if(count($items))
 207                  {
 208                  $i = 0;
 209                  $is_owner = $channel->checkOwnership();
 210                  foreach ($items as $item )
 211                      {
 212                      $itemLinks = '';
 213                      if ($is_owner || ($item['owner_id'] == $_SESSION['auth']->userDN))
 214                          {
 215                          $itemLinks .= $this->linkToEdit(array('mode' => 'post', 'channels' => $channel->dn, 'id' => $item['id']), 'Edit This Post', 'icons/edit_16.png');
 216                          $itemLinks .= $this->linkToEdit(array('mode' => 'post', 'delete' => 1, 'channels' => $channel->dn, 'id' => $item['id']), 'Delete This Post', 'icons/remov_16.png', false, true);
 217                          }
 218                      if ($itemLinks)
 219                          $itemLinks .= '&nbsp;';
 220                      $tpl->setVar('itemLinks', $itemLinks);                    
 221                      
 222                      $tpl->setVar('rowClass', ++$i % 2 ? 'table1' : 'table2');
 223                      $tpl->setVar('itemURL', @$item['target'] );
 224                      $tpl->setVar('itemTitle', @$item['title'] );
 225                      $tpl->setVar('itemDescription', RSSReader::abbreviate_description(@$item['info'], $this->descLength) );
 226                      if (isset($item['created']) and $this->dispDate)
 227                          {
 228                          preg_match('/^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/', $item['created'], $t);
 229                          $tpl->setVar('itemDate', '<br>' . date('M j', mktime($t[4], $t[5], $t[6], $t[2], $t[3], $t[1]) ));
 230                          }
 231                      $tpl->parse('items', 'itemBlock', true);
 232                      }
 233  
 234                  $useNav = false;
 235                  $count = $channel->articleCount();
 236                  if(@$this->params['p'])
 237                      {
 238                      $p = $this->params['p'] <= $this->numLinks ? 0 : $this->params['p'] - $this->numLinks;
 239                      $tpl->setVar('prev', '<a ' . ($this->style == 'table' ? 'class="secondary" ' : '') . 'href="' . $this->parent->linkToSelf(array('p' => $p) + $this->parent->httpVars) . '">Previous ' . ($p ? $this->numLinks : $this->numLinks - $p) . '</a>');
 240                      $useNav = true;
 241                      }
 242                  if( $this->params['p'] + $this->numLinks < $count )
 243                      {
 244                      $p = $this->params['p'] + $this->numLinks;
 245                      $tpl->setVar('next', '<a ' . ($this->style == 'table' ? 'class="secondary" ' : '') . 'href="' . $this->parent->linkToSelf(array('p' => $p) + $this->parent->httpVars) . '">Next ' . ($p + $this->numLinks > $count ? $count - $p : $this->numLinks) . '</a>');
 246                      $useNav = true;
 247                      }
 248                  $tpl->setVar('total', $count);
 249                  if ($useNav)
 250                      $tpl->parse('navB', 'navBlock');
 251                  }
 252    
 253              // print meta tag for channel auto-discovery
 254              $auto = '<link rel="alternate" type="application/rss+xml" title="' . $title . '" href="' . $channel->getURL() . '" />';
 255              return $auto . $tpl->subst('main');
 256              }
 257          else
 258              // no feed source
 259              return '';
 260      }
 261  
 262      // for backwards compatibility
 263      function view( $feedSrc = null, $numLinks = null, $descLength = null, $style = null, $title = null, $link = null, $dispDate = null)
 264          {
 265          $obj = RSSReader::init($this);
 266          if(isset($feedSrc)) $obj->feedSrc = $feedSrc;
 267              else return;
 268          if(isset($numLinks)) $obj->numLinks = $numLinks;
 269          if(isset($descLength)) $obj->descLength = $descLength;
 270          if(isset($style)) $obj->style = $style;
 271          if(isset($title)) 
 272              {
 273              $obj->title = $title;
 274              $obj->titleType = 'text';
 275              }
 276          if(isset($link)) $obj->link = $link;
 277          if(isset($dispDate)) $obj->dispDate = $dispDate;
 278          if(substr($feedSrc, 0, 6) == 'mnRSS=')
 279              return $obj->viewChannel();
 280          else
 281              return $obj->viewRSS();
 282          }
 283  
 284      function getConfig()
 285          {
 286          $f = FormWidget::init($this->parent->linkToSelf());
 287          $f->name('rss' . $this->parent->blockID);
 288          $f->section();
 289  
 290          $f->RSSTypeSelector('src', @$this->params[ 'srcType'] ,
 291                                     @$this->params['srcURL'],
 292                                     @$this->params[ 'srcDN'],
 293                                     $this->parent->ldap);
 294  
 295          $f->field('Title');
 296          $f->radio('titleType', array(
 297              'default'    => 'default',
 298              'none'        => 'none',
 299              'text'        => array('text: ' . FormWidget::text('title', @$this->params['title'], $little_text))
 300              ), @$this->params['titleType'], 'default', '<br />', array(), false);
 301              
 302          $f->field('Links per page');
 303          $f->text('numLinks', $this->numLinks, 2);
 304          $f->html(' links ');
 305          $f->checkbox('numLinksUnlimited', @$this->parent->params['numLinksUnlimited'], 'no limit');
 306          
 307          $f->field('Max Description Length');
 308          $f->text('descLength', $this->descLength, 2);
 309          $f->html(' words ');
 310          $f->checkbox('descLengthUnlimited', @$this->parent->params['descLengthUnlimited'], 'no limit');
 311          
 312          $f->field('Display Options');
 313          $f->checkbox('dispDate', @$this->params['dispDate'], 'Show date');
 314          $f->html('<br />');
 315          $f->checkbox('dispAuth', @$this->params['dispAuth'], 'Show author');
 316          $f->html('<br />(if available)');
 317          
 318          $f->field('Display Style');
 319          $f->dropdown('displayStyle', array('table'=>'table','plain'=>'plain'), @$this->params['displayStyle'], 'table');
 320          
 321          $f->field();
 322          $f->hidden('update', '');
 323          $f->defaultButtons();
 324          
 325          // preview selected channel if it has been set
 326          $reader = RSSReader::init($this->parent);
 327          if((@$this->params['srcType'] == 'url' and $this->feedSrc) or (@$this->params['srcType'] == 'dn' and $this->params['srcDN']))
 328              $preview = 'Preview:' . $reader->getContent();
 329  
 330          return $f->get() . $preview;
 331          }
 332  
 333  	function onSave()
 334          {
 335          // save settings
 336          @$settings['srcType'] = $this->params['srcType'];
 337          @$settings['srcDN'] = $this->params['srcDN'];
 338          @$settings['srcURL'] = $this->feedSrc;
 339          @$settings['numLinks'] = $this->params['numLinks'];
 340          @$settings['numLinksUnlimited'] = $this->params['numLinksUnlimited'];
 341          @$settings['descLength'] = $this->params['descLength'];
 342          @$settings['descLengthUnlimited'] = $this->params['descLengthUnlimited'];
 343          @$settings['displayStyle'] = $this->params['displayStyle'];
 344          @$settings['dispDate'] = $this->params['dispDate'];
 345          @$settings['dispAuth'] = $this->params['dispAuth'];
 346          @$settings['title'] = $this->params['title'];
 347          @$settings['titleType'] = $this->params['titleType'];
 348  
 349          $res = $this->parent->saveSettings($settings);
 350          if(mnError::isError($res))
 351              return new mnError('RSSReader::getContent(): ' . $res->getMessage(), __FILE__, __LINE__);
 352          }
 353  
 354      /**
 355      * limits number of words in an RSS link description
 356      *
 357      * Truncates a phrase to a certain number of words (descLength), adding ... at the end.
 358      * Leaves phrase as is if descLengthUnlimited is true.
 359      * Strips html tags.
 360      *
 361      * @param  string    phrase to truncate
 362      * @access private
 363      * @return string    truncated phrase
 364      */
 365      function abbreviate_description( $description, $descLength = 25 )
 366          {
 367              if (is_numeric($descLength))
 368                  {
 369                  if ( $descLength == 0 )
 370                      return '';
 371                  }
 372              else
 373                  return $description;
 374                  
 375              $description = strip_tags($description);
 376  
 377              // limit a string to a maximum of $max_words words; add ... at the end
 378              $short = preg_replace( '/^\s*(\S+(\s+\S+){' . ($descLength - 1) . '}).*$/s', '$1...', $description );
 379              return $short;
 380          }
 381    
 382  	function linkToEdit($params, $title, $icon, $single = true, $confirm = false)
 383          {
 384          if ($this->parent->blockID != 'tmpRSS' and ($this->parent->edit or $this->parent->publish))
 385              return '';
 386              
 387          $link = $this->parent->linkToSelf($params, $single);
 388          $icon = '<img src="/.cWimg/' . $icon . '" border=0 style="vertical-align:middle;">';
 389          $confirm = $confirm ? "if(!confirm('Press OK if you are sure you want to delete this post.'))return false;" : '';
 390          if (T_SINGLE_BLOCK || !$single)
 391              if ($confirm)
 392                  return '<a href="#" title="' . $title .'" onclick="' . $confirm . "window.location.replace('$link');" . '">' . $icon . '</a>';
 393              else
 394                  return '<a href="' . $link . '" title="' . $title .'">' . $icon . '</a>';
 395          else
 396              return '<a href="#" onclick="' . $confirm . "popup('$link', 'RSS', 600, 500)" . '" title="' . $title . '">' . $icon . '</a>';
 397          }
 398          
 399      function paramName($a) { return $this->parent->paramName($a); }    
 400      }
 401  ?>

title

Description

title

Description

title

Description

title

title

Body