1<?php 2/** 3 * Syntax Component Blog 4 */ 5 6// must be run within Dokuwiki 7if (!defined('DOKU_INC')) die(); 8 9/** 10 * Covers all <blog *> syntax commands 11 */ 12class syntax_plugin_blogtng_blog extends DokuWiki_Syntax_Plugin { 13 14 /** 15 * Default configuration for all setups 16 */ 17 var $config = array( 18 'sortorder' => 'DESC', 19 'sortby' => 'created', 20 'tpl' => 'default', 21 'limit' => 5, 22 'offset' => 0, 23 'blog' => null, 24 'tags' => array(), 25 'page' => false, 26 'cache' => false, 27 'title' => '', 28 'format' => ':blog:%Y:%m:%{title}', 29 'listwrap' => 0, //default depends on syntax type 30 ); 31 32 /** @var helper_plugin_blogtng_entry */ 33 var $entryhelper = null; 34 /** @var helper_plugin_blogtng_tools */ 35 var $tools = null; 36 /** @var helper_plugin_blogtng_comments */ 37 var $commenthelper = null; 38 /** @var helper_plugin_blogtng_tags */ 39 var $taghelper; 40 41 /** 42 * Types we accept in our syntax 43 */ 44 var $type_whitelist = array('list', 'pagination', 'related', 'recentcomments', 'newform', 'tagcloud', 'tagsearch'); 45 46 /** 47 * Values accepted in syntax 48 */ 49 var $data_whitelist = array( 50 'sortyorder' => array('asc', 'desc'), 51 'sortby' => array('created', 'lastmod', 'title', 'page', 'random'), 52 ); 53 54 // default plugin functions... 55 /** 56 * Syntax Type 57 * 58 * @return string 59 */ 60 function getType() { return 'substition'; } 61 62 /** 63 * Paragraph Type 64 * 65 * @return string 66 */ 67 function getPType() { return 'block'; } 68 69 /** 70 * Sort for applying this mode 71 * 72 * @return int 73 */ 74 function getSort() { return 300; } 75 76 /** 77 * Register the <blog *></blog> syntax 78 * 79 * @param string $mode 80 */ 81 function connectTo($mode) { 82 $this->Lexer->addSpecialPattern('<blog ?[^>]*>.*?</blog>', $mode, 'plugin_blogtng_blog'); 83 } 84 85 /** 86 * Parse the type and configuration data from the syntax 87 * 88 * @param string $match The text matched by the patterns 89 * @param int $state The lexer state for the match 90 * @param int $pos The character position of the matched text 91 * @param Doku_Handler $handler The Doku_Handler object 92 * @return bool|array Return an array with all data you want to use in render, false don't add an instruction 93 */ 94 public function handle($match, $state, $pos, Doku_Handler $handler) { 95 $match = substr(trim($match), 5, -7); // strip '<blog' and '</blog>' 96 list($type,$conf) = explode('>',$match,2); 97 $type = trim($type); 98 $conf = trim($conf); 99 $conf = linesToHash(explode("\n", $conf)); 100 if(!$type) $type = 'list'; 101 102 // check type 103 if(!in_array($type,$this->type_whitelist)){ 104 msg('Unknown blog syntax type "'.hsc($type).'" using "list" instead',-1); 105 $type = 'list'; 106 } 107 108 // handle multi keys 109 $conf['blog'] = array_filter(array_map('trim', explode(',', $conf['blog']))); 110 $conf['tags'] = array_filter(array_map('trim', explode(',', $conf['tags']))); 111 $conf['type'] = array_filter(array_map('trim', explode(',', $conf['type']))); 112 113 if (($type != 'tagsearch') && (!count($conf['blog']))) { 114 115 $conf['blog'] = array('default'); 116 117 } 118 119 // higher default limit for tag cloud 120 if($type == 'tagcloud' && !$conf['limit']) { 121 $conf['limit'] = 25; 122 } 123 124 // default to listwrap for recent comments 125 if(($type == 'recentcomments' || $type == 'tagsearch') && !isset($conf['listwrap'])){ 126 $conf['listwrap'] = 1; 127 } 128 129 // reversed listwrap syntax 130 if($conf['nolistwrap']) { 131 $conf['listwrap'] = 0; 132 unset($conf['nolistwrap']); 133 } 134 // reversed nolist to listwrap syntax (backward compatibility) 135 if($conf['nolist']) { 136 $conf['listwrap'] = 0; 137 unset($conf['nolist']); 138 } 139 140 // merge with default config 141 $conf = array_merge($this->config, $conf); 142 143 return array('type'=>$type, 'conf'=>$conf); 144 } 145 146 /** 147 * Handles the actual output creation. 148 * 149 * @param string $mode output format being rendered 150 * @param Doku_Renderer $renderer the current renderer object 151 * @param array $data data created by handler() 152 * @return boolean rendered correctly? (however, returned value is not used at the moment) 153 */ 154 public function render($mode, Doku_Renderer $renderer, $data) { 155 if($mode != 'xhtml') return false; 156 157 $this->loadHelpers(); 158 159 // set target if not set yet 160 global $ID; 161 if(!isset($data['conf']['target'])) $data['conf']['target'] = $ID; 162 163 // add additional data from request parameters 164 if($start = $this->tools->getParam('pagination/start')){ // start offset 165 $data['conf']['offset'] = (int) $start; 166 } 167 168 if($tags = $this->tools->getParam('post/tags')){ // tags 169 $data['conf']['tags'] = array_merge( 170 $data['conf']['tags'], 171 explode(',',$tags)); 172 } 173 $data['conf']['tags'] = array_map('trim',$data['conf']['tags']); 174 $data['conf']['tags'] = array_unique($data['conf']['tags']); 175 $data['conf']['tags'] = array_filter($data['conf']['tags']); 176 177 // dispatch to the correct type handler 178 $renderer->info['cache'] = (bool)$data['conf']['cache']; 179 switch($data['type']){ 180 case 'related': 181 $renderer->doc .= $this->entryhelper->xhtml_related($data['conf']); 182 break; 183 case 'pagination': 184 $renderer->doc .= $this->entryhelper->xhtml_pagination($data['conf']); 185 break; 186 case 'newform': 187 $renderer->info['cache'] = false; //never cache this 188 $renderer->doc .= $this->entryhelper->xhtml_newform($data['conf']); 189 break; 190 case 'recentcomments': 191 // FIXME to cache or not to cache? 192 $renderer->doc .= $this->commenthelper->xhtml_recentcomments($data['conf']); 193 break; 194 case 'tagcloud': 195 $renderer->info['cache'] = false; // never cache this 196 $renderer->doc .= $this->taghelper->xhtml_tagcloud($data['conf']); 197 break; 198 case 'tagsearch': 199 $renderer->doc .= $this->entryhelper->xhtml_tagsearch($data['conf'], $renderer); 200 break; 201 default: 202 $renderer->doc .= $this->entryhelper->xhtml_list($data['conf'], $renderer); 203 } 204 205 return true; 206 } 207 208 /** 209 * Parse options given in the syntax 210 * 211 * @param $opt 212 */ 213 function _parse_opt($opt) { 214 switch(true) { 215 case (in_array($opt, $this->data_whitelist['sortorder'])): 216 $this->config['sortorder'] = strtoupper($opt); 217 break; 218 case (in_array($opt, $this->data_whitelist['sortby'])): 219 $this->config['sortby'] = substr($opt, 2); 220 break; 221 case (preg_match('/^\d$/', $opt)): 222 $this->config['limit'] = $opt; 223 break; 224 case (preg_match('/^\+(\d+)$/', $opt, $match)): 225 $this->config['order'] = $match[1]; 226 break; 227 case (preg_match('/^tpl(\w+)$/', $opt, $match)): 228 $this->config['tpl'] = $match[1]; 229 break; 230 default; 231 continue; 232 } 233 } 234 235 /** 236 * Load required helper plugins. 237 */ 238 private function loadHelpers() { 239 $this->entryhelper = plugin_load('helper', 'blogtng_entry'); 240 $this->tools = plugin_load('helper', 'blogtng_tools'); 241 $this->commenthelper = plugin_load('helper', 'blogtng_comments'); 242 $this->taghelper = plugin_load('helper', 'blogtng_tags'); 243 } 244} 245// vim:ts=4:sw=4:et: 246