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