phpDocumentor Rss
[ class tree: Rss ] [ index: Rss ] [ all elements ]

Source for file rss.class.php

Documentation is available at rss.class.php

  1. <?php
  2.  
  3. /**
  4. * RSS generating class
  5. * generates RSS 2.0 feed according to given data
  6. @author Matej Finwe Humpal <finwe@finwe.info>
  7. @license http://creativecommons.org/licenses/by-sa/2.5/ Creative Commons Attribution-ShareAlike 2.5
  8. @link http://weblog.finwe.info/item/php-trida-generujici-rss Tutorial Article at finwe.info (cs-CZ)
  9. @link http://blogs.law.harvard.edu/tech/rss RSS 2.0 Specification
  10. @package Rss
  11. */
  12.  
  13. /**
  14. * Class Rss
  15. * If making derivative works, you MUST attribute the author in one or more of following ways:<br>
  16. * Leave rss generator tags and comments in the output<br>
  17. * Place the link http://weblog.finwe.info/item/php-trida-generujici-rss to your product documentation<br>
  18. * Place the link http://weblog.finwe.info/item/php-trida-generujici-rss to your product website
  19. @author Matej Finwe Humpal <finwe@finwe.info>
  20. @version Rss.class.php, v 1.3 2007/02/17 14:48:00
  21. @license http://creativecommons.org/licenses/by-sa/2.5/ Creative Commons Attribution-ShareAlike 2.5
  22. @package Rss
  23. @link http://weblog.finwe.info/item/php-trida-generujici-rss Tutorial Article at finwe.info (cs_CZ)
  24. @example rss.php Basic example
  25. */
  26.  
  27. class Rss 
  28. {
  29.     
  30.     /**
  31.      * Data retrieval handler setting.
  32.      * 
  33.      * Allows user to define his own data-retrieval function, even outside of the class.
  34.      * 
  35.      * string 'getData' will call function gatData
  36.      * array('pgSql','getData') will staticaly call method getData of pgSql object (pgSql::getData()).
  37.      * 
  38.      * there are two pre-prepared methods - getMysqlData() and getMysqliData().
  39.      * They both use db parameters specific for Rss class
  40.      * 
  41.      * @var mixed Either string for external static function or array with two parametres (Class,Method) for calling the method staticaly
  42.      */
  43.      
  44.     private $dbCallback = array('Rss''getMysqlData');
  45.     
  46.     /**
  47.      * DB host. defaults localhost
  48.      * @var string 
  49.      */
  50.     
  51.     private $dbHost = 'localhost';
  52.     
  53.     /**
  54.      * DB user.
  55.      * @var string 
  56.      */
  57.      
  58.     private $dbUser = '';
  59.     
  60.     /**
  61.      * DB password.
  62.      * @var string 
  63.      */
  64.     
  65.     private $dbPass = '';
  66.     
  67.     /**
  68.      * Name of the database to use.
  69.      * @var string 
  70.      */
  71.     
  72.     private $dbName = '';
  73.     
  74.     /**
  75.      * Database Port.
  76.      * @var string 
  77.      */
  78.     
  79.     private $dbPort = '';
  80.     
  81.     /**
  82.      * Title of the feed. Should be the same as the page title.
  83.      * @var string 
  84.      */
  85.     
  86.     private $title = '';
  87.     
  88.     /**
  89.      * Base url of the page.
  90.      * @var string 
  91.      */
  92.      
  93.     private $link = '';
  94.     
  95.     /**
  96.      * Feed description.
  97.      * @var string 
  98.      */
  99.     
  100.     private $descripton = '';
  101.     
  102.     /**
  103.      * Language of the feed.
  104.      * @var string 
  105.      */
  106.     
  107.     private $language = '';
  108.     
  109.     /**
  110.      * Oprional feed namespaces.
  111.      * @var array 
  112.      */
  113.     
  114.     private $namespaces = array();
  115.     
  116.     /**
  117.      * Custom channel subelements (pubDate, ttl, skipHours etc.)
  118.      * @var array 
  119.      */
  120.     
  121.     private $channelSubelements = array();
  122.  
  123.     
  124.     /**
  125.      * URL of feed image.
  126.      * @var string 
  127.      */
  128.     
  129.     private $image = '';
  130.     
  131.     /**
  132.      * Array of database fields to use.
  133.      * 
  134.      * Key is a name of RSS tag, value is name of database field, from which the data are to be taken.
  135.      * Value can be an array of db field names for usage with link, comments and guid tags. @see $postLink
  136.      * 
  137.      * @see prepareData()
  138.      * @var array 
  139.      */
  140.     
  141.     private $dbFields = array();
  142.     
  143.     /**
  144.      * SQL query to run on given database.
  145.      * @var string 
  146.      */
  147.     
  148.     private $dbSql = '';
  149.     
  150.     /**
  151.      * String of item-link.
  152.      * 
  153.      * Is prepared for sprintf or vsprintf. Instead of %s variables, data from database will be used.
  154.      * If multiple variables used, $dbFields must be set accordingly (array in array value)
  155.      * 
  156.      * '/item/%s' string with one variable
  157.      * '/item/%s-%s' string with multiple variables
  158.      * 
  159.      * @example rss.php Basic example
  160.      * @var string 
  161.      * @see dbFields
  162.      */
  163.     
  164.     private $postLink = '';
  165.     
  166.     /**
  167.      * String of item-comment-link.
  168.      * 
  169.      * Is prepared for sprintf or vsprintf. Instead of %s variables, data from database will be used.
  170.      * If multiple variables used, $dbFields must be set accordingly (array in array value)
  171.      * 
  172.      * '/item/%s' string with one variable
  173.      * '/item/%s-%s' string with multiple variables
  174.      * 
  175.      * @example rss.php Basic example
  176.      * @var string 
  177.      * @see dbFields
  178.      */
  179.      
  180.     private $commentsLink = '';
  181.     
  182.     /**
  183.      * Feed encoding.
  184.      * 
  185.      * @var string 
  186.      */
  187.     
  188.     private $encoding = 'utf-8';
  189.     
  190.     /**
  191.      * Method overloading - allows user to set Rss variables.
  192.      */ 
  193.     
  194.     public function __call($name,$args)
  195.     {
  196.         
  197.         $forbidden array('namespaces');
  198.         
  199.         if (substr($name03== 'set' && $var substr($name3)) {
  200.              $var strtolower(substr($var,0,1)).substr($var,1);
  201.              if (isset($this->$var)) {
  202.                   $this->$var $args[0];
  203.              else {
  204.                  throw new Exception(sprintf('Non-existing method %s::%s() called in %s, line %s'__CLASS__$name__FILE____LINE__));
  205.              }   
  206.         }
  207.     }
  208.     
  209.     /**
  210.      * Sets page header
  211.      * 
  212.      * @param string $context Page context-type.
  213.      */
  214.     
  215.     protected function setHeader($context 'text/plain')
  216.     {
  217.         header('Content-type: ' $context '; charset=' $this->encoding);    
  218.     }
  219.     
  220.     /**
  221.      * Adds user-defined namespace
  222.      * 
  223.      * @param string $namespace Namespace itself
  224.      * @param string $link link to namespace definition
  225.      * @param string $link link to namespace definition
  226.      * @uses Rss::$namespaces
  227.      */
  228.     
  229.     public function addNamespace($namespace,$link)
  230.     {
  231.         $this->namespaces[$namespace.'="'.$link.'"';
  232.     }
  233.     
  234.     /**
  235.      * Writes namespaces
  236.      * 
  237.      * @return string Namespaces
  238.      * @uses Rss::$namespaces
  239.      */
  240.     
  241.     protected function writeNamespaces()
  242.     {
  243.         $namespaces implode(' ',$this->namespaces);
  244.         return $namespaces;
  245.     }
  246.     
  247.     /**
  248.      * Adds user-defined channel subelement
  249.      * 
  250.      * @param string $element name of the tag
  251.      * @param mixed $data tag data
  252.      * @see writeChannelSubelements()
  253.      * @uses Rss::$channelSubelements
  254.      */
  255.     
  256.     public function addChannelSubelement($element,$data)
  257.     {
  258.         $this->channelSubelements[$element$data;
  259.     }
  260.     
  261.     /**
  262.      * writes Channel Subelements XML
  263.      * 
  264.      * @return string XML of channel subelements
  265.      * @uses Rss::$channelSubelements
  266.      */
  267.      
  268.     private function writeChannelSubelements({
  269.         
  270.         $out '';
  271.         
  272.         foreach ($this->channelSubelements as $key => $val{
  273.             switch ($key{
  274.                 case 'copyright':
  275.                     // fall through
  276.                 case 'managingEditor':
  277.                     // fall through
  278.                 case 'webMaster':
  279.                     // fall through
  280.                 case 'category':
  281.                     // fall through
  282.                 case 'rating':
  283.                     // fall through        
  284.                 case 'ttl':
  285.                     $out .= '<' $key '>' $val '</' $key '>'."\n";
  286.                     break;
  287.                 case 'cloud':
  288.                     $out .= '<' $key ' domain="' $val["domain"'"  port="' $val["port"'"  path="' $val["path"'"  registerProcedure="' $val["registerProcedure"'"  protocol="' $val["protocol"'" />'."\n";
  289.                     break;
  290.                 case 'skipHours':
  291.                     // fall through
  292.                 case 'skipDays':
  293.                     $out .= '<' $key '>'."\n";
  294.                     foreach ($val as $skip{
  295.                         $out .= "\t".'<hour>' $skip '</hour>'."\n";
  296.                     }
  297.                     $out .= '</' $key '>'."\n";
  298.                     break;
  299.                 default:
  300.                     break;
  301.             }
  302.         }
  303.         
  304.         return $out;
  305.         
  306.     }
  307.     
  308.     /**
  309.      * Writes RSS prologue with Channel obligatory tags
  310.      */
  311.     
  312.     protected function rssHead()
  313.     {
  314.         $out =  '';
  315.         $out .=    '<?xml version="1.0" encoding="' $this->encoding . '" ?>'."\n";
  316.         $out .= '<!-- generator="Rss PHP class (http://weblog.finwe.info/item/php-trida-generujici-rss)" -->'."\n";
  317.         $out .= '<rss version="2.0" ' $this->writeNamespaces('>'."\n";
  318.         $out .= '<channel>'."\n";
  319.         $out .= '<title>' $this->title . '</title>'."\n";
  320.         $out .= '<link>' $this->link . '</link>'."\n";
  321.         $out .= '<description>' $this->descripton . '</description>'."\n";
  322.         $out .= '<generator>Rss PHP class (http://weblog.finwe.info/item/php-trida-generujici-rss)</generator>'."\n";
  323.         $out .= (!empty($this->image)) '<image>' $this->image . '</image>'."\n" '';
  324.         $out .= '<pubDate>' date('r''</pubDate>';
  325.         $out .= '<language>' $this->language . '</language>'."\n";
  326.         $out .= $this->writeChannelSubelements();
  327.         
  328.         print($out);
  329.         
  330.     }
  331.     
  332.     /**
  333.      * By RSS Spec, description text should be 450 chars max. Lets ensure it is.
  334.      * 
  335.      * @author Monte Ohrt <monte at ohrt dot com>
  336.      * @return string Truncated string
  337.      */
  338.     
  339.     protected function splitLongText($string$length 450$etc '...'$break_words false$middle false)
  340.     {
  341.         if ($length == 0)
  342.             return '';
  343.  
  344.         if (strlen($string$length{
  345.             $length -= strlen($etc);
  346.             if (!$break_words && !$middle{
  347.                 $string preg_replace('/\s+?(\S+)?$/'''substr($string0$length+1));
  348.             }
  349.             if(!$middle{
  350.                 return substr($string0$length).$etc;
  351.             else {
  352.                 return substr($string0$length/2$etc substr($string-$length/2);
  353.             }
  354.         else {
  355.             return $string;
  356.         }
  357.     }
  358.     
  359.     /**
  360.      * Database data withdrawal, mysql driver
  361.      * 
  362.      * @return array $return Data fetched from MySQL < 4.1 database
  363.      */
  364.     
  365.     protected function getMysqlData()
  366.     {
  367.         $return array();
  368.         
  369.         $db mysql_connect($this->dbHost,$this->dbUser,$this->dbPass);
  370.         mysql_select_db($this->dbName,$db);
  371.         
  372.         $query mysql_query($this->dbSqlor die(mysql_error());
  373.         while($array mysql_fetch_array($query,MYSQLI_ASSOC)){
  374.             $return[$array;
  375.         }
  376.         
  377.         mysql_close($db);
  378.         
  379.         return $return;
  380.     }
  381.     
  382.     /**
  383.      * Database data withdrawal, mysqli driver
  384.      * 
  385.      * @return array $returnData fetched from MySQL >= 4.1 database
  386.      */
  387.     
  388.     protected function getMysqliData()
  389.     {
  390.         $return array();
  391.         
  392.         $db new mysqli($this->dbHost,$this->dbUser,$this->dbPass,$this->dbName);
  393.         $db->query("SET CHARACTER SET UTF8");
  394.         
  395.         $query $db->query($this->dbSqlor die($db->error);
  396.         while($array $query->fetch_array(MYSQLI_ASSOC)){
  397.             $return[$array;
  398.         }
  399.         
  400.         $db->close();
  401.         
  402.         return $return;
  403.     }
  404.     
  405.     /**
  406.      * Prepares array of data for further usage
  407.      * 
  408.      * @return array $return Data prepared for insertion to XML
  409.      */
  410.     
  411.     protected function prepareData()
  412.     {
  413.         
  414.         $return array();
  415.         $i 0;
  416.             
  417.         
  418.         if (!is_array($this->dbFields)) {
  419.             throw new Exception('dbFields parameter is suppossed to be an array');
  420.         }
  421.         
  422.         $data call_user_func($this->dbCallback);
  423.         
  424.         foreach($data as $array){
  425.             foreach ($this->dbFields as $key => $val{
  426.                 switch ($key{
  427.                     case 'link'
  428.                         if (!is_array($val)) {
  429.                             $return[$i][$keysprintf($this->postLink,$array[$val]);
  430.                         else {
  431.                             $return[$i][$keyvsprintf($this->postLink,array_reverse(array_intersect_key($arrayarray_flip($val))));
  432.                         }
  433.                         break;
  434.                     case 'description':
  435.                         $return[$i][$key'<![CDATA[' $this->splitLongText($array[$val]']]>';
  436.                         break;                        
  437.                     case 'comments':
  438.                         if (!is_array($val)) {
  439.                             $return[$i][$keysprintf($this->commentsLink,$array[$val]);
  440.                         else {
  441.                             $return[$i][$keyvsprintf($this->commentsLink,array_reverse(array_intersect_key($arrayarray_flip($val))));
  442.                         }
  443.                         break;    
  444.                     case 'category':
  445.                         // fall through    
  446.                     case 'enclosure':
  447.                         $return[$i][$key$array[$val];
  448.                         break;
  449.                     case 'pubDate':
  450.                         $return[$i][$keydate('r',$array[$val]);
  451.                         break;
  452.                     case 'guid':
  453.                         // fall through                            
  454.                     case 'title':    
  455.                         // fall through
  456.                     case 'author':
  457.                         // fall through                        
  458.                     case 'source':
  459.                         // fall through        
  460.                     default:
  461.                         if (!is_array($val)){
  462.                             $return[$i][$key$array[$val];
  463.                         else {
  464.                             if (!is_array($val[0])) {
  465.                                 $return[$i][$keysprintf($val[1],$array[$val[0]]);
  466.                             else {
  467.                                 $return[$i][$keyvsprintf($val[1],$array[$val[0]]);
  468.                             }
  469.                         }
  470.                         break;                            
  471.                 }
  472.             }
  473.             $i++;            
  474.         }
  475.         
  476.         return $return;
  477.  
  478.     }
  479.     
  480.     /**
  481.      * Writes ITEM tags of RSS from values prepared by prepareData()
  482.      * 
  483.      * @param array $data Data prepared from {@link prepareData()}
  484.      * 
  485.      */
  486.     
  487.     protected function rssBody($data){
  488.         
  489.         $out '';
  490.         
  491.         if (!is_array($data)) {
  492.             throw new Exception('Data has to be an array');
  493.         }
  494.         
  495.         foreach ($data as $item{
  496.             
  497.             $out .= '<item>'."\n";
  498.             foreach ($item as $key => $val{
  499.                 $out .= (!empty($val)) "\t".'<' $key '>' $val '</' $key '>'."\n" '';
  500.             }
  501.             $out .= '</item>'."\n";
  502.         }
  503.         print($out);
  504.     }
  505.     
  506.     /**
  507.      * Writes RSS epilogue
  508.      */
  509.     
  510.     protected function rssFoot()
  511.     {
  512.         $out =  '';
  513.         $out .= '</channel>'."\n";
  514.         $out .= '</rss>';
  515.         
  516.         print($out);
  517.     }
  518.     
  519.     /**
  520.      * Complete method for final usage.
  521.      */
  522.     
  523.     public function display()
  524.     {
  525.             $this->setHeader('text/xml');
  526.             $this->rssHead();
  527.             $this->rssBody($this->prepareData('getMysqliData'));
  528.             $this->rssFoot();
  529.     }
  530. }        
  531.           
  532. ?>

Documentation generated on Sat, 17 Feb 2007 14:51:23 +0100 by phpDocumentor 1.3.1