[ Index ]

PHP Cross Reference of MyBB 1.8.29

title

Body

[close]

/inc/ -> class_feedparser.php (source)

   1  <?php
   2  /**
   3   * MyBB 1.8
   4   * Copyright 2014 MyBB Group, All Rights Reserved
   5   *
   6   * Website: http://www.mybb.com
   7   * License: http://www.mybb.com/about/license
   8   *
   9   */
  10  
  11  class FeedParser
  12  {
  13      /**
  14       * Array of all of the items
  15       *
  16       * @var array
  17       */
  18      public $items = array();
  19  
  20      /**
  21       * Array of the channel information.
  22       *
  23       * @var array
  24       */
  25      public $channel = array();
  26  
  27      /**
  28       * Any error the feed parser may encounter
  29       *
  30       * @var string
  31       */
  32      public $error;
  33  
  34      /**
  35       * Parses a feed with the specified filename (or URL)
  36       *
  37       * @param string $feed The path or URL of the feed
  38       * @return boolean True if parsing was a success, false if failure
  39       */
  40  	function parse_feed($feed)
  41      {
  42          // Load the feed we want to parse
  43          $contents = fetch_remote_file($feed);
  44  
  45          // This is to work around some dodgy bug we've detected with certain installations of PHP
  46          // where certain characters would magically appear between the fetch_remote_file call
  47          // and here which break the feed being imported.
  48          if(strpos($contents, "<") !== 0)
  49          {
  50              $contents = substr($contents, strpos($contents, "<"));
  51          }
  52          if(strrpos($contents, ">")+1 !== strlen($contents))
  53          {
  54              $contents = substr($contents, 0, strrpos($contents, ">")+1);
  55          }
  56  
  57          // Could not load the feed, return an error
  58          if(!$contents)
  59          {
  60              $this->error = "invalid_file";
  61              return false;
  62          }
  63  
  64          // Parse the feed and get the tree
  65          $parser = create_xml_parser($contents);
  66          $tree = $parser->get_tree();
  67  
  68          // If the feed is invalid, throw back an error
  69          if($tree == false)
  70          {
  71              $this->error = "invalid_feed_xml";
  72              return false;
  73          }
  74  
  75          // Change array key names to lower case
  76          $tree = $this->keys_to_lowercase($tree);
  77  
  78          // This is an RSS feed, parse it
  79          if(array_key_exists("rss", $tree))
  80          {
  81              $this->parse_rss($tree['rss']);
  82          }
  83  
  84          // We don't know how to parse this feed
  85          else
  86          {
  87              $this->error = "unknown_feed_type";
  88              return false;
  89          }
  90  
  91          return true;
  92      }
  93  
  94      /**
  95       * Parses an XML structure in the format of an RSS feed
  96       *
  97       * @param array $feed_contents PHP XML parser structure
  98       * @return boolean true
  99       */
 100  	function parse_rss($feed_contents)
 101      {
 102          foreach(array('title', 'link', 'description', 'pubdate') as $value)
 103          {
 104              if(!isset($feed_contents['channel'][$value]['value']))
 105              {
 106                  $feed_contents['channel'][$value]['value'] = '';
 107              }
 108          }
 109  
 110          // Fetch channel information from the parsed feed
 111          $this->channel = array(
 112              "title" => $feed_contents['channel']['title']['value'],
 113              "link" => $feed_contents['channel']['link']['value'],
 114              "description" => $feed_contents['channel']['description']['value'],
 115              "date" => $feed_contents['channel']['pubdate']['value'],
 116              "date_timestamp" => $this->get_rss_timestamp($feed_contents['channel']['pubdate']['value'])
 117          );
 118  
 119          // The XML parser does not create a multidimensional array of items if there is one item, so fake it
 120          if(!array_key_exists("0", $feed_contents['channel']['item']))
 121          {
 122              $feed_contents['channel']['item'] = array($feed_contents['channel']['item']);
 123          }
 124  
 125          // Loop through each of the items in the feed
 126          foreach($feed_contents['channel']['item'] as $feed_item)
 127          {
 128              // Here is a nice long stretch of code for parsing items, we do it this way because most elements are optional in an
 129              // item and we only want to assign what we have.
 130  
 131              $item = array();
 132  
 133  
 134              // Set the item title if we have it
 135              if(array_key_exists("title", $feed_item))
 136              {
 137                  $item['title'] = $feed_item['title']['value'];
 138              }
 139  
 140              if(isset($feed_item['description']['value']))
 141              {
 142                  $item['description'] = $feed_item['description']['value'];
 143              }
 144              else
 145              {
 146                  $item['description'] = '';
 147              }
 148  
 149              if(array_key_exists("link", $feed_item))
 150              {
 151                  $item['link'] = $feed_item['link']['value'];
 152              }
 153  
 154              // If we have a pub date, store it and attempt to generate a unix timestamp from it
 155              if(array_key_exists("pubdate", $feed_item))
 156              {
 157                  $item['date'] = $feed_item['pubdate']['value'];
 158                  $item['date_timestamp'] = $this->get_rss_timestamp($item['date']);
 159              }
 160  
 161              // If we have a GUID
 162              if(array_key_exists("guid", $feed_item))
 163              {
 164                  $item['guid'] = $feed_item['guid']['value'];
 165              }
 166              // Otherwise, attempt to generate one from the link and item title
 167              else
 168              {
 169                  $item['guid'] = md5($item['link'].$item['title']);
 170              }
 171  
 172              // If we have some content, set it
 173              if(array_key_exists("content:encoded", $feed_item))
 174              {
 175                  $item['content'] = $feed_item['content:encoded']['value'];
 176              }
 177              else if(array_key_exists("content", $feed_item))
 178              {
 179                  $item['content'] = $feed_item['content']['value'];
 180              }
 181  
 182              // We have a DC based creator, set it
 183              if(array_key_exists("dc:creator", $feed_item))
 184              {
 185                  $item['author'] = $feed_item['dc:creator']['value'];
 186              }
 187              // Otherwise, attempt to use the author if we have it
 188              else if(array_key_exists("author", $feed_item))
 189              {
 190                  $item['author'] = $feed_item['author']['value'];
 191              }
 192  
 193              // Assign the item to our list of items
 194              $this->items[] = $item;
 195          }
 196          return true;
 197      }
 198  
 199      /**
 200       * Convert all array keys within an array to lowercase
 201       *
 202       * @param array $array The array to be converted
 203       * @return array The converted array
 204       */
 205  	function keys_to_lowercase($array)
 206      {
 207          $new_array = array();
 208          foreach($array as $key => $value)
 209          {
 210              $new_key = strtolower($key);
 211              if(is_array($value))
 212              {
 213                  $new_array[$new_key] = $this->keys_to_lowercase($value);
 214              }
 215              else
 216              {
 217                  $new_array[$new_key] = $value;
 218              }
 219          }
 220          return $new_array;
 221      }
 222  
 223      /**
 224       * Converts an RSS date stamp in to a unix timestamp
 225       *
 226       * @param string $date The RSS date
 227       * @return integer The unix timestamp (if successful), 0 if unsuccessful
 228       */
 229  	function get_rss_timestamp($date)
 230      {
 231          $stamp = strtotime($date);
 232          if($stamp <= 0)
 233          {
 234              if(preg_match("#\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\+\d{2}:\d{2}#", $date, $result))
 235              {
 236                  $date = str_replace(array("T", "+"), array(" ", " +"), $date);
 237                  $date[23] = "";
 238              }
 239              $stamp = strtotime($date);
 240          }
 241          return $stamp;
 242      }
 243  }


2005 - 2021 © MyBB.de | Alle Rechte vorbehalten! | Sponsor: netcup Cross-referenced by PHPXref