[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/vendor/openpsa/universalfeedcreator/lib/Creator/ -> FeedCreator.php (source)

   1  <?php
   2  
   3  /**
   4   * FeedCreator is the abstract base implementation for concrete
   5   * implementations that implement a specific format of syndication.
   6   *
   7   * @author  Kai Blankenhorn <kaib@bitfolge.de>
   8   * @since   1.4
   9   */
  10  abstract class FeedCreator extends HtmlDescribable
  11  {
  12  
  13      /**
  14       * Mandatory attributes of a feed.
  15       */
  16      public $title, $description, $link;
  17      public $format = 'BASE';
  18  
  19      /**
  20       * Optional attributes of a feed.
  21       */
  22      public $syndicationURL, $image, $language, $copyright, $pubDate, $lastBuildDate, $editor, $editorEmail, $webmaster, $category, $docs, $ttl, $rating, $skipHours, $skipDays;
  23  
  24      /**
  25       * The url of the external xsl stylesheet used to format the naked rss feed.
  26       * Ignored in the output when empty.
  27       */
  28      public $xslStyleSheet = "";
  29  
  30      public $cssStyleSheet = "";
  31  
  32      /** @var FeedItem[] */
  33      public $items = Array();
  34  
  35      /**
  36       * Generator string
  37       */
  38      public $generator = "info@mypapit.net";
  39  
  40      /**
  41       * This feed's MIME content type.
  42       *
  43       * @since  1.4
  44       * @access private
  45       */
  46      protected $contentType = "application/xml";
  47  
  48      /**
  49       * This feed's character encoding.
  50       *
  51       * @since 1.6.1
  52       */
  53      protected $encoding = "UTF-8"; //"ISO-8859-1";
  54  
  55      protected $_timeout;  # lib/Creator/FeedCreator.php  line 238
  56  
  57      /**
  58       * Any additional elements to include as an associated array. All $key => $value pairs
  59       * will be included unencoded in the feed in the form
  60       *     <$key>$value</$key>
  61       * Again: No encoding will be used! This means you can invalidate or enhance the feed
  62       * if $value contains markup. This may be abused to embed tags not implemented by
  63       * the FeedCreator class used.
  64       */
  65      public $additionalElements = Array();
  66  
  67      /**
  68       * Adds a FeedItem to the feed.
  69       *
  70       * @param FeedItem $item The FeedItem to add to the feed.
  71       */
  72      public function addItem($item)
  73      {
  74          $this->items[] = $item;
  75      }
  76  
  77      /**
  78       * Get the version string for the generator
  79       *
  80       * @return string
  81       */
  82      public function version()
  83      {
  84          return FEEDCREATOR_VERSION." (".$this->generator.")";
  85      }
  86  
  87      /**
  88       * Truncates a string to a certain length at the most sensible point.
  89       * First, if there's a '.' character near the end of the string, the string is truncated after this character.
  90       * If there is no '.', the string is truncated after the last ' ' character.
  91       * If the string is truncated, " ..." is appended.
  92       * If the string is already shorter than $length, it is returned unchanged.
  93       *
  94       * @param string $string A string to be truncated.
  95       * @param int $length    the maximum length the string should be truncated to
  96       * @return string the truncated string
  97       */
  98      public static function iTrunc($string, $length)
  99      {
 100          if (strlen($string) <= $length) {
 101              return $string;
 102          }
 103  
 104          $pos = strrpos($string, ".");
 105          if ($pos >= $length - 4) {
 106              $string = substr($string, 0, $length - 4);
 107              $pos = strrpos($string, ".");
 108          }
 109          if ($pos >= $length * 0.4) {
 110              return substr($string, 0, $pos + 1)." ...";
 111          }
 112  
 113          $pos = strrpos($string, " ");
 114          if ($pos >= $length - 4) {
 115              $string = substr($string, 0, $length - 4);
 116              $pos = strrpos($string, " ");
 117          }
 118          if ($pos >= $length * 0.4) {
 119              return substr($string, 0, $pos)." ...";
 120          }
 121  
 122          return substr($string, 0, $length - 4)." ...";
 123  
 124      }
 125  
 126      /**
 127       * Creates a comment indicating the generator of this feed.
 128       * The format of this comment seems to be recognized by
 129       * Syndic8.com.
 130       */
 131      protected function _createGeneratorComment()
 132      {
 133          return "<!-- generator=\"".FEEDCREATOR_VERSION."\" -->\n";
 134      }
 135  
 136      /**
 137       * Creates a string containing all additional elements specified in
 138       * $additionalElements.
 139       *
 140       * @param array $elements      an associative array containing key => value pairs
 141       * @param string $indentString a string that will be inserted before every generated line
 142       * @return string the XML tags corresponding to $additionalElements
 143       */
 144      protected function _createAdditionalElements($elements, $indentString = "")
 145      {
 146          $ae = "";
 147          if (is_array($elements)) {
 148              foreach ($elements AS $key => $value) {
 149                  $ae .= $indentString."<$key>$value</$key>\n";
 150              }
 151          }
 152  
 153          return $ae;
 154      }
 155  
 156      protected function _createStylesheetReferences()
 157      {
 158          $xml = "";
 159          if (!empty($this->cssStyleSheet)) {
 160              $xml .= "<?xml-stylesheet href=\"".$this->cssStyleSheet."\" type=\"text/css\"?>\n";
 161          }
 162          if (!empty($this->xslStyleSheet)) {
 163              $xml .= "<?xml-stylesheet href=\"".$this->xslStyleSheet."\" type=\"text/xsl\"?>\n";
 164          }
 165  
 166          return $xml;
 167      }
 168  
 169      /**
 170       * Builds the feed's text.
 171       *
 172       * @return string the feed's complete text
 173       */
 174      abstract public function createFeed();
 175  
 176      /**
 177       * Generate a filename for the feed cache file. The result will be $_SERVER["SCRIPT_NAME"] with the extension changed
 178       * to .xml. For example: echo $_SERVER["SCRIPT_NAME"]."\n"; echo FeedCreator::_generateFilename(); would produce:
 179       * /rss/latestnews.php
 180       * latestnews.xml
 181       *
 182       * @return string the feed cache filename
 183       * @since  1.4
 184       * @access private
 185       */
 186      protected function _generateFilename()
 187      {
 188          $fileInfo = pathinfo($_SERVER["SCRIPT_NAME"]);
 189  
 190          return substr($fileInfo["basename"], 0, -(strlen($fileInfo["extension"]) + 1)).".xml";
 191      }
 192  
 193      /**
 194       * Send given file to Browser
 195       *
 196       * @since 1.4
 197       * @param string $filename
 198       */
 199      protected function _redirect($filename)
 200      {
 201          // attention, heavily-commented-out-area
 202  
 203          // maybe use this in addition to file time checking
 204          //header("Expires: ".date("r",time()+$this->_timeout));
 205  
 206          /* no caching at all, doesn't seem to work as good:
 207           header("Cache-Control: no-cache");
 208          header("Pragma: no-cache");
 209          */
 210  
 211          // HTTP redirect, some feed readers' simple HTTP implementations don't follow it
 212          //header("Location: ".$filename);
 213  
 214          header("Content-Type: ".$this->contentType."; charset=".$this->encoding."; filename=".basename($filename));
 215          if (preg_match('/\.(kml|gpx)$/', $filename)) {
 216              header("Content-Disposition: attachment; filename=".basename($filename));
 217          } else {
 218              header("Content-Disposition: inline; filename=".basename($filename));
 219          }
 220          readfile($filename);
 221          exit();
 222      }
 223  
 224      /**
 225       * Turns on caching and checks if there is a recent version of this feed in the cache.
 226       * If there is, an HTTP redirect header is sent.
 227       * To effectively use caching, you should create the FeedCreator object and call this method
 228       * before anything else, especially before you do the time consuming task to build the feed
 229       * (web fetching, for example).
 230       *
 231       * @since 1.4
 232       * @param string $filename optional    the filename where a recent version of the feed is saved. If not specified,
 233       *                         the filename is $_SERVER["SCRIPT_NAME"] with the extension changed to .xml (see
 234       *                         _generateFilename()).
 235       * @param int $timeout     optional    the timeout in seconds before a cached version is refreshed (defaults to
 236       *                         3600 = 1 hour)
 237       */
 238      public function useCached($filename = "", $timeout = 3600)
 239      {
 240          $this->_timeout = $timeout;
 241          if ($filename == "") {
 242              $filename = $this->_generateFilename();
 243          }
 244          if (file_exists($filename) AND (time() - filemtime($filename) < $timeout)) {
 245              $this->_redirect($filename);
 246          }
 247      }
 248  
 249      /**
 250       * Saves this feed as a file on the local disk. After the file is saved, a redirect
 251       * header may be sent to redirect the user to the newly created file.
 252       *
 253       * @since 1.4
 254       * @param string $filename      optional    the filename where a recent version of the feed is saved. If not
 255       *                              specified, the filename is $_SERVER["SCRIPT_NAME"] with the extension changed to .xml
 256       *                              (see _generateFilename()).
 257       * @param bool $displayContents optional    send an HTTP redirect header or not. If true, the user will be
 258       *                              automatically redirected to the created file.
 259       */
 260      public function saveFeed($filename = "", $displayContents = true)
 261      {
 262          if ($filename == "") {
 263              $filename = $this->_generateFilename();
 264          }
 265          $feedFile = fopen($filename, "w+");
 266          if ($feedFile) {
 267              fputs($feedFile, $this->createFeed());
 268              fclose($feedFile);
 269              if ($displayContents) {
 270                  $this->_redirect($filename);
 271              }
 272          } else {
 273              echo "<br /><b>Error creating feed file, please check write permissions.</b><br />";
 274          }
 275      }
 276  }