diff --git a/feed.php b/feed.php new file mode 100644 --- /dev/null +++ b/feed.php @@ -0,0 +1,126 @@ + + */ + +if(!defined('DOKU_INC')) define('DOKU_INC', realpath(dirname(__FILE__) . '/../../../') . '/'); +if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/'); +require_once(DOKU_INC . 'inc/init.php'); +require_once(DOKU_INC . 'inc/common.php'); +require_once(DOKU_INC . 'inc/events.php'); +require_once(DOKU_INC . 'inc/parserutils.php'); +require_once(DOKU_INC . 'inc/feedcreator.class.php'); +require_once(DOKU_INC . 'inc/auth.php'); +require_once(DOKU_INC . 'inc/pageutils.php'); +require_once(DOKU_INC . 'inc/httputils.php'); + +//close session +session_write_close(); + +$id = $_REQUEST['id']; + +$type = $conf['rss_type']; + +switch($type) { + case 'rss': + $type = 'RSS0.91'; + $mime = 'text/xml'; + break; + case 'rss2': + $type = 'RSS2.0'; + $mime = 'text/xml'; + break; + case 'atom': + $type = 'ATOM0.3'; + $mime = 'application/xml'; + break; + case 'atom1': + $type = 'ATOM1.0'; + $mime = 'application/atom+xml'; + break; + default: + $type = 'RSS1.0'; + $mime = 'application/xml'; +} + +// the feed is dynamic - we need a cache for each combo +// (but most people just use the default feed so it's still effective) +$cache = getCacheName($id . $_SERVER['REMOTE_USER'], '.feed'); +$cmod = @filemtime($cache); // 0 if not exists +if($cmod && (@filemtime(DOKU_CONF . 'local.php') > $cmod + || @filemtime(DOKU_CONF . 'dokuwiki.php') > $cmod) +) { + // ignore cache if feed prefs may have changed + $cmod = 0; +} + +// check cacheage and deliver if nothing has changed since last +// time or the update interval has not passed, also handles conditional requests +header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); +header('Pragma: public'); +header('Content-Type: application/xml; charset=utf-8'); + +if($cmod && ( + ($cmod + $conf['rss_update'] > time()) + || ( + ($cmod > @filemtime($conf['changelog'])) + ) + )) { + http_conditionalRequest($cmod); + if($conf['allowdebug']) header("X-CacheUsed: $cache"); + print io_readFile($cache); + exit; +} else { + http_conditionalRequest(time()); +} + +// create new feed +$rss = new DokuWikiFeedCreator(); +$rss->title = p_get_metadata($id, 'title', METADATA_DONT_RENDER); +$rss->title .= ' · ' . $conf['title']; +$rss->link = DOKU_URL; +$rss->syndicationURL = DOKU_PLUGIN . 'csstimeline/feed.php'; +$rss->cssStyleSheet = DOKU_URL . 'lib/exe/css.php?s=feed'; + +$author = p_get_metadata($id, 'creator', METADATA_DONT_RENDER); + +$image = new FeedImage(); +$image->title = $conf['title']; +$image->url = DOKU_URL . "lib/images/favicon.ico"; +$image->link = DOKU_URL; +$rss->image = $image; + +$page = rawWiki($id);// get pages here +$po = &plugin_load('helper', 'csstimeline'); +preg_match('/'.str_replace('/', '\/', $po->specialPattern).'/si', $page, $matches); + +foreach($matches as $match) +{ + $data = $po->handleMatch($match); + foreach($data['entries'] as $entry) + { + $item = new FeedItem(); + $item->title = htmlspecialchars_decode($entry['title']); + if($entry['link']) + $item->link = htmlspecialchars_decode($entry['link']); + else + $item->link = wl($id, '', true, '&'); + $item->description = hsc(strip_tags(htmlspecialchars_decode($entry['description']))); + $item->date = date('r', strtotime($entry['date'])); + $item->author = $author; + $rss->addItem($item); + + } +} + +$feed = $rss->createFeed($type, 'utf-8'); + +// save cachefile +io_saveFile($cache, $feed); + +// finally deliver +print $feed; + diff --git a/helper.php b/helper.php new file mode 100644 --- /dev/null +++ b/helper.php @@ -0,0 +1,50 @@ +.*'; + + public function handleMatch($match) + { + $match = substr($match, 13, -14); + $lines = explode("\n",$match); + $data = array(); + $cnt = 0; + $data['entries'] = array(); + foreach($lines as $line) + { + $line = trim($line); + if($line) + { + $lineSplit = explode(':', $line, 2); + switch(trim($lineSplit[0])) + { + case '': + break; + case '': + $cnt++; + break; + case 'description': + $data['entries'][$cnt]['description'] = $this->render_text(trim($lineSplit[1])); + break; + default: + $data['entries'][$cnt][$lineSplit[0]] = hsc(trim($lineSplit[1])); + + + } + } + } + return $data; + } + +} diff --git a/syntax.php b/syntax.php --- a/syntax.php +++ b/syntax.php @@ -1,123 +1,103 @@ * * date: 04.12.2014 * title: My first timeline entry * description: Within the description, you can even use Wiki markup * * * date: 06.01.2015 * title: My second timeline entry * description: This one is rendered at the other side of the timeline * * * * * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author Andreas Böhler */ if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); require_once(DOKU_PLUGIN.'syntax.php'); /** * All DokuWiki plugins to extend the parser/rendering mechanism * need to inherit from this class */ class syntax_plugin_csstimeline extends DokuWiki_Syntax_Plugin { + protected $_helper = null; + + // Load the helper plugin + public function syntax_plugin_csstimeline() { + $this->_helper =& plugin_load('helper', 'csstimeline'); + } + function getType() { return 'substition'; } function getPType() { return 'normal'; } function getAllowedTypes() { return array('container','substition','protected','disabled','paragraphs','formatting'); } function getSort() { return 777; } function connectTo($mode) { - $this->Lexer->addSpecialPattern('.*',$mode,'plugin_csstimeline'); + $this->Lexer->addSpecialPattern($this->_helper->specialPattern,$mode,'plugin_csstimeline'); } /** * Handle the match. Use either the standard linking mechanism or, when enabled, * pass the title through the parser */ function handle($match, $state, $pos, Doku_Handler $handler) { - $match = substr($match, 13, -14); - $lines = explode("\n",$match); - $data = array(); - $cnt = 0; - $data['entries'] = array(); - foreach($lines as $line) - { - $line = trim($line); - if($line) - { - $lineSplit = explode(':', $line, 2); - switch(trim($lineSplit[0])) - { - case '': - break; - case '': - $cnt++; - break; - case 'description': - $data['entries'][$cnt]['description'] = $this->render_text(trim($lineSplit[1])); - break; - default: - $data['entries'][$cnt][$lineSplit[0]] = hsc(trim($lineSplit[1])); - - - } - } - } + $data = $this->_helper->handleMatch($match); return $data; } /** * Create output. This is largely based on the internal linking mechanism. */ function render($mode, Doku_Renderer $renderer, $data) { if (empty($data)) return false; if($mode == 'xhtml') { $direction = 'r'; $renderer->doc .= '
'; } return false; } }