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