1<?php 2/** 3 * Date: Run the php command strftime or date. 4 * Usage: 5 * {{date>format}} 6 * 7 * Replacers are handled in a simple key/value pair method. 8 * {{date>format|key=val|key2=val|key3=val}} 9 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 10 * @author Marcel Pietschmann <mpietsch@astro.physik.uni-potsdam.de> 11 * @version 1.20 12 */ 13 14// must be run within DokuWiki 15if(!defined('DOKU_INC')) die(); 16 17if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 18require_once(DOKU_PLUGIN.'syntax.php'); 19 20/** 21 * All DokuWiki plugins to extend the parser/rendering mechanism 22 * need to inherit from this class 23 */ 24class syntax_plugin_date extends DokuWiki_Syntax_Plugin { 25 26 /** 27 * What kind of syntax are we? 28 */ 29 30 function getType() { return 'substition'; } 31 32 // function getAllowedTypes(){ return array('container','substition','protected','disabled','formatting'); } 33 34 /** 35 * Paragraph Type 36 */ 37 // function getPType(){ return 'normal'; } 38 // function getAllowedTypes() { return array('substition','protected','disabled','formatting','container'); } 39 40 /** 41 * Where to sort in? 42 */ 43 function getSort(){ return 195; } 44 45 /** 46 * Connect pattern to lexer 47 */ 48 function connectTo($mode) { 49 $this->Lexer->addSpecialPattern('{{date>.+?}}',$mode,'plugin_date'); 50 $this->Lexer->addSpecialPattern('{{date=.+?}}',$mode,'plugin_date'); 51 } 52 53 /** 54 * Handle the match 55 */ 56 function handle($match, $state, $pos, Doku_Handler $handler){ 57 //strip strings for non-constant 58 if (strpos($match,'date>',2) !== false) { 59 // strip markup 60 $match = substr($match,7,-2); 61 // Get the key values pairs 62 $replacers = preg_split('/(?<!\\\\)\|/', $match); 63 64 // cut format key 65 $dataformat = array_shift($replacers); 66 67 // handle key=value 68 $replacers = $this->_GetKeyValues($replacers); 69 70 $cnst = null; 71 } else { 72 // strip markup for constanst 73 $cnst = substr($match, 7, -2); 74 } 75 return array($dataformat,$replacers,$cnst); 76 } 77 78 /** 79 * Create output 80 */ 81 function render($mode, Doku_Renderer $renderer, $data) { 82 // for XHTML output 83 if ($mode == 'xhtml') { 84 85 // format for the output 86 $format = $data[0]; 87 88 // Check if some keys are set -> array has length greater than 0 89 if (count($data[1]) > 0) { 90 91 // search the keys in array and get position in array 92 $timestamp_key = array_search("timestamp",$data[1]['keys']); 93 $now_key = array_search("now",$data[1]['keys']); 94 $locale_key = array_search("locale",$data[1]['keys']); 95 $mode_key = array_search("mode",$data[1]['keys']); 96 $cnst = FALSE; 97 } else { 98 // set FALSE values for correct going 99 $timestamp_key = FALSE; 100 $now_key = FALSE; 101 $locale_key = FALSE; 102 $mode_key = FALSE; 103 if ($data[2] === '') { 104 $cnst = FALSE; 105 } else { 106 $cnst = $data[2]; 107 } 108 } 109 110 // set locale LC_TIME setting, if some locale key is giving 111 if (!empty($locale_key)) { 112 // save actually settings 113 $localestore = setlocale(LC_TIME,"0"); 114 // get values from array 115 $locale_value = $data[1]['vals'][$locale_key]; 116 // set LC_TIME 117 setlocale(LC_TIME,$locale_value); 118 } 119 120 if ($mode_key !== false) { 121 // get value from array 122 $mode_value = $data[1]['vals'][$mode_key]; 123 } else { 124 $mode_value = "strftime"; 125 } 126 127 // check for the different possibilities 128 if ( $timestamp_key !== FALSE and $now_key !== FALSE and $cnst == FALSE ) { 129 // timestamp and now keys are set 130 131 // get values from array 132 $timestamp_value = $data[1]['vals'][$timestamp_key]; 133 $now_value = $data[1]['vals'][$now_key]; 134 135 // replace " with ' for correct eval 136 $timestamp_value = str_replace('"',"'",$timestamp_value); 137 $now_value = str_replace('"',"'",$now_value); 138 139 // check if in timestamp string the function strtotime is used 140 $pos = strpos($timestamp_value, "strtotime"); 141 if ($pos === false) { 142 // strtotime is not used, so don't use now value 143 $timestamp_with_now_value = $timestamp_value; 144 } else { 145 // // strtotime is used, so use now value 146 $timestamp_with_now_value = substr($timestamp_value,0,strlen($timestamp_value)-1).", ".$now_value.substr($timestamp_value,-1); 147 } 148 149 // eval the timestamp string 150 eval ("\$timestamp_with_now_value = $timestamp_with_now_value;"); 151 152 // do the magic date function 153 if ($mode_value == "date") { 154 $xhtml = date($format, $timestamp_with_now_value); 155 } else { 156 $xhtml = strftime($format, $timestamp_with_now_value); 157 } 158 159 } else if ( $timestamp_key !== FALSE and $cnst == FALSE ) { 160 // only timestamp key is set 161 162 // get values from array 163 $timestamp_value = $data[1]['vals'][$timestamp_key]; 164 // replace " witch ' for correct eval 165 $timestamp_value = str_replace('"',"'",$timestamp_value); 166 // eval the timestamp string 167 eval ("\$timestamp_value = $timestamp_value;"); 168 169 // do the magic date function 170 if ($mode_value == "date") { 171 $xhtml = date($format, $timestamp_value); 172 } else { 173 $xhtml = strftime($format, $timestamp_value); 174 } 175 176 } else if ($cnst == FALSE) { 177 // no keys are set 178 // do the magic date function 179 if ($mode_value == "date") { 180 $xhtml = date($format); 181 } else { 182 $xhtml = strftime($format); 183 } 184 } 185 186 if ($cnst != FALSE) { 187 $dformat = $this->getConf('dpformat'); 188 // handle with the constants 189 if ( strcasecmp($cnst,'today') == 0 ) { 190 $xhtml = strftime($dformat); 191 } else if ( strcasecmp($cnst,'tomorrow') == 0 ) { 192 $xhtml = strftime($dformat, strtotime("+1 day")); 193 } else if ( strcasecmp($cnst,'yesterday') == 0 ) { 194 $xhtml = strftime($dformat, strtotime("-1 day")); 195 } else if ( strcasecmp($cnst,'year') == 0 ) { 196 $xhtml = strftime('%Y'); 197 } else if ( strcasecmp($cnst,'nyear') == 0 ) { 198 $xhtml = strftime('%Y',strtotime("+1 year"));; 199 } else if ( strcasecmp($cnst,'pyear') == 0 ) { 200 $xhtml = strftime('%Y',strtotime("-1 year")); 201 } else if ( strcasecmp($cnst,'month') == 0 ) { 202 $xhtml = strftime('%m'); 203 } else if ( strcasecmp($cnst,'nmonth') == 0 ) { 204 $xhtml = strftime('%m',strtotime("+1 month")); 205 } else if ( strcasecmp($cnst,'pmonth') == 0 ) { 206 $xhtml = strftime('%m',strtotime("-1 month")); 207 } else if ( strcasecmp($cnst,'week') == 0 ) { 208 $xhtml = strftime('%W'); 209 } else if ( strcasecmp($cnst,'nweek') == 0 ) { 210 $xhtml = strftime('%W',strtotime("+1 week")); 211 } else if ( strcasecmp($cnst,'pweek') == 0 ) { 212 $xhtml = strftime('%W',strtotime("-1 week")); 213 } else if ( strcasecmp($cnst,'dayofmonth') == 0 ) { 214 $xhtml = strftime('%d'); 215 } else if ( strcasecmp($cnst,'dayofmonth2') == 0 ) { 216 $xhtml = strftime('%e'); 217 } else if ( strcasecmp($cnst,'dayofyear') == 0 ) { 218 $xhtml = strftime('%j'); 219 } else if ( strcasecmp($cnst,'weekday') == 0 ) { 220 $xhtml = strftime('%w'); 221 } else if ( strcasecmp($cnst,'time') == 0 ) { 222 $xhtml = strftime('%T'); 223 } else { 224 // for unknown match render original 225 $xhtml = "{date={$cnst}}"; 226 } 227 } 228 229 // unset cache, so that the page is always up to date 230 $renderer->info['cache'] = false; 231 // print out the date 232 $renderer->doc .= $xhtml; 233 234 // set locale LC_TIME setting to stored settings 235 if (isset($locale_key)) { 236 setlocale(LC_TIME,$localestore); 237 } 238 239 return true; 240 } 241 return false; 242 } 243 244 245 /** 246 * Handles the key=value array 247 */ 248 function _GetKeyValues($replacers) 249 { 250 $r = array(); 251 if (is_null($replacers)) { 252 $r['keys'] = null; 253 $r['vals'] = null; 254 } else if (is_string($replacers)) { 255 list ($k, $v) = explode('=', $replacers, 2); 256 // $r['keys'] = BEGIN_REPLACE_DELIMITER.trim($k).END_REPLACE_DELIMITER; 257 $r['keys'] = trim($k); 258 $r['vals'] = trim(str_replace('\|','|',$v)); 259 } else if (is_array($replacers)) { 260 foreach($replacers as $rep) { 261 list ($k, $v) = explode('=', $rep, 2); 262 // $r['keys'][] = BEGIN_REPLACE_DELIMITER.trim($k).END_REPLACE_DELIMITER; 263 $r['keys'][] = trim($k); 264 $r['vals'][] = trim(str_replace('\|','|',$v)); 265 } 266 } else { 267 // This is an assertion failure. We should NEVER get here. 268 //die("FATAL ERROR! Unknown type passed to syntax_plugin_templater::massageReplaceMentArray() can't massage syntax_plugin_templater::\$replacers! Type is:".gettype($r)." Value is:".$r); 269 $r['keys'] = null; 270 $r['vals'] = null; 271 } 272 return $r; 273 } 274 } 275?> 276