[ Index ]

PHP Cross Reference of MyBB

title

Body

[close]

/inc/ -> class_feedparser.php (source)

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


Generated: Tue Oct 8 19:19:50 2013 Cross-referenced by PHPXref 0.7.1