Changeset 3721:c34ce89e190b for inc
- Timestamp:
- 02/25/18 09:36:58 (8 years ago)
- Branch:
- default
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
inc/public/lib.tpl.context.php
r3567 r3721 10 10 # 11 11 # -- END LICENSE BLOCK ----------------------------------------- 12 if (!defined('DC_RC_PATH')) { return;}12 if (!defined('DC_RC_PATH')) {return;} 13 13 14 14 class context 15 15 { 16 public $stack = array(); 17 18 public function __set($name,$var) 19 { 20 if ($var === null) { 21 $this->pop($name); 22 } else { 23 $this->stack[$name][] =& $var; 24 if ($var instanceof record) { 25 $this->stack['cur_loop'][] =& $var; 26 } 27 } 28 } 29 30 public function __get($name) 31 { 32 if (!isset($this->stack[$name])) { 33 return null; 34 } 35 36 $n = count($this->stack[$name]); 37 if ($n > 0) { 38 return $this->stack[$name][($n-1)]; 39 } 40 41 return null; 42 } 43 44 public function exists($name) 45 { 46 return isset($this->stack[$name][0]); 47 } 48 49 public function pop($name) 50 { 51 if (isset($this->stack[$name])) { 52 $v = array_pop($this->stack[$name]); 53 if ($v instanceof record) { 54 array_pop($this->stack['cur_loop']); 55 } 56 unset($v); 57 } 58 } 59 60 # Loop position tests 61 public function loopPosition($start,$length=null,$even=null,$modulo=null) 62 { 63 if (!$this->cur_loop) { 64 return false; 65 } 66 67 $index = $this->cur_loop->index(); 68 $size = $this->cur_loop->count(); 69 70 $test = false; 71 if ($start >= 0) 72 { 73 $test = $index >= $start; 74 if ($length !== null) { 75 if ($length >= 0) { 76 $test = $test && $index < $start + $length; 77 } else { 78 $test = $test && $index < $size + $length; 79 } 80 } 81 } 82 else 83 { 84 $test = $index >= $size + $start; 85 if ($length !== null) { 86 if ($length >= 0) { 87 $test = $test && $index < $size + $start + $length; 88 } else { 89 $test = $test && $index < $size + $length; 90 } 91 } 92 } 93 94 if ($even !== null) { 95 $test = $test && $index%2 == $even; 96 } 97 98 if ($modulo !== null) { 99 $test = $test && ($index % $modulo == 0); 100 } 101 102 return $test; 103 } 104 105 /** 106 @deprecated since version 2.11 , use tpl_context::global_filters instead 107 */ 108 public static function global_filter($str, 109 $encode_xml, $remove_html, $cut_string, $lower_case, $upper_case ,$encode_url ,$tag='') 110 { 111 return self::global_filters( 112 $str, 113 array(0 => null, 114 'encode_xml' => $encode_xml, 115 'remove_html' => $remove_html, 116 'cut_string' => $cut_string, 117 'lower_case' => $lower_case, 118 'upper_case' => ($upper_case == 1 ? 1 : 0), 119 'capitalize' => ($upper_case == 2 ? 1 : 0), 120 'encode_url' => $encode_url), 121 $tag); 122 } 123 124 public static function global_filters($str,$args,$tag='') 125 { 126 $args[0] = &$str; 127 128 # --BEHAVIOR-- publicBeforeContentFilter 129 $res = $GLOBALS['core']->callBehavior('publicBeforeContentFilter',$GLOBALS['core'],$tag,$args); 130 $str = $args[0]; 131 132 if ($args['strip_tags']) { 133 $str = self::strip_tags($str); 134 } 135 if ($args['remove_html']) { 136 $str = self::remove_html($str); 137 $str = preg_replace('/\s+/',' ',$str); 138 } 139 if ($args['encode_xml'] || $args['encode_html']) { 140 $str = self::encode_xml($str); 141 } 142 143 if ($args['cut_string'] > 0) { 144 $str = self::cut_string($str,(integer) $args['cut_string']); 145 } 146 147 if ($args['lower_case']) { 148 $str = self::lower_case($str); 149 } elseif ($args['capitalize']) { 150 $str = self::capitalize($str); 151 } elseif ($args['upper_case']) { 152 $str = self::upper_case($str); 153 } 154 155 if ($args['encode_url']) { 156 $str = self::encode_url($str); 157 } 158 159 # --BEHAVIOR-- publicAfterContentFilter 160 $res = $GLOBALS['core']->callBehavior('publicAfterContentFilter',$GLOBALS['core'],$tag,$args); 161 $str = $args[0]; 162 163 return $str; 164 } 165 166 public static function encode_url($str) 167 { 168 return urlencode($str); 169 } 170 171 public static function cut_string($str,$l) 172 { 173 return text::cutString($str,$l); 174 } 175 176 public static function encode_xml($str) 177 { 178 return html::escapeHTML($str); 179 } 180 181 public static function remove_html($str) 182 { 183 return html::decodeEntities(html::clean($str)); 184 } 185 186 public static function strip_tags($str) 187 { 188 return trim(preg_replace('/ {2,}/',' ',str_replace(array("\r","\n","\t"),' ',html::clean($str)))); 189 } 190 191 public static function lower_case($str) 192 { 193 return mb_strtolower($str); 194 } 195 196 public static function upper_case($str) 197 { 198 return mb_strtoupper($str); 199 } 200 201 public static function capitalize($str) 202 { 203 if ($str != '') { 204 $str[0] = mb_strtoupper($str[0]); 205 } 206 return $str; 207 } 208 209 public static function categoryPostParam(&$p) 210 { 211 $not = substr($p['cat_url'],0,1) == '!'; 212 if ($not) { 213 $p['cat_url'] = substr($p['cat_url'],1); 214 } 215 216 $p['cat_url'] = preg_split('/\s*,\s*/',$p['cat_url'],-1,PREG_SPLIT_NO_EMPTY); 217 218 foreach ($p['cat_url'] as &$v) 219 { 220 if ($not) { 221 $v .= ' ?not'; 222 } 223 if ($GLOBALS['_ctx']->exists('categories') && preg_match('/#self/',$v)) { 224 $v = preg_replace('/#self/',$GLOBALS['_ctx']->categories->cat_url,$v); 225 } elseif ($GLOBALS['_ctx']->exists('posts') && preg_match('/#self/',$v)) { 226 $v = preg_replace('/#self/',$GLOBALS['_ctx']->posts->cat_url,$v); 227 } 228 } 229 } 230 231 # Static methods for pagination 232 public static function PaginationNbPages() 233 { 234 global $_ctx; 235 236 if ($_ctx->pagination === null) { 237 return false; 238 } 239 240 $nb_posts = $_ctx->pagination->f(0); 241 if (($GLOBALS['core']->url->type == 'default') || ($GLOBALS['core']->url->type == 'default-page')) { 242 $nb_pages = ceil(($nb_posts - $_ctx->nb_entry_first_page) / $_ctx->nb_entry_per_page + 1); 243 } else { 244 $nb_pages = ceil($nb_posts / $_ctx->nb_entry_per_page); 245 } 246 247 return $nb_pages; 248 } 249 250 public static function PaginationPosition($offset=0) 251 { 252 if (isset($GLOBALS['_page_number'])) { 253 $p = $GLOBALS['_page_number']; 254 } else { 255 $p = 1; 256 } 257 258 $p = $p+$offset; 259 260 $n = self::PaginationNbPages(); 261 if (!$n) { 262 return $p; 263 } 264 265 if ($p > $n || $p <= 0) { 266 return 1; 267 } else { 268 return $p; 269 } 270 } 271 272 public static function PaginationStart() 273 { 274 if (isset($GLOBALS['_page_number'])) { 275 return self::PaginationPosition() == 1; 276 } 277 278 return true; 279 } 280 281 public static function PaginationEnd() 282 { 283 if (isset($GLOBALS['_page_number'])) { 284 return self::PaginationPosition() == self::PaginationNbPages(); 285 } 286 287 return false; 288 } 289 290 public static function PaginationURL($offset=0) 291 { 292 $args = $_SERVER['URL_REQUEST_PART']; 293 294 $n = self::PaginationPosition($offset); 295 296 $args = preg_replace('#(^|/)page/([0-9]+)$#','',$args); 297 298 $url = $GLOBALS['core']->blog->url.$args; 299 300 if ($n > 1) { 301 $url = preg_replace('#/$#','',$url); 302 $url .= '/page/'.$n; 303 } 304 305 # If search param 306 if (!empty($_GET['q'])) { 307 $s = strpos($url,'?') !== false ? '&' : '?'; 308 $url .= $s.'q='.rawurlencode($_GET['q']); 309 } 310 return $url; 311 } 312 313 # Robots policy 314 public static function robotsPolicy($base,$over) 315 { 316 $pol = array('INDEX' => 'INDEX','FOLLOW' => 'FOLLOW', 'ARCHIVE' => 'ARCHIVE'); 317 $base = array_flip(preg_split('/\s*,\s*/',$base)); 318 $over = array_flip(preg_split('/\s*,\s*/',$over)); 319 320 foreach ($pol as $k => &$v) 321 { 322 if (isset($base[$k]) || isset($base['NO'.$k])) { 323 $v = isset($base['NO'.$k]) ? 'NO'.$k : $k; 324 } 325 if (isset($over[$k]) || isset($over['NO'.$k])) { 326 $v = isset($over['NO'.$k]) ? 'NO'.$k : $k; 327 } 328 } 329 330 if ($pol['ARCHIVE'] == 'ARCHIVE') { 331 unset($pol['ARCHIVE']); 332 } 333 334 return implode(', ',$pol); 335 } 336 337 # Smilies static methods 338 public static function getSmilies($blog) 339 { 340 $path = array(); 341 if (isset($GLOBALS['__theme'])) { 342 $path[] = $GLOBALS['__theme']; 343 if (isset($GLOBALS['__parent_theme'])) { 344 $path[] = $GLOBALS['__parent_theme']; 345 } 346 } 347 $path[] = 'default'; 348 $definition = $blog->themes_path.'/%s/smilies/smilies.txt'; 349 $base_url = $blog->settings->system->themes_url.'/%s/smilies/'; 350 351 $res = array(); 352 353 foreach ($path as $t) 354 { 355 if (file_exists(sprintf($definition,$t))) { 356 $base_url = sprintf($base_url,$t); 357 return self::smiliesDefinition(sprintf($definition,$t),$base_url); 358 } 359 } 360 return false; 361 } 362 363 public static function smiliesDefinition($f,$url) 364 { 365 $def = file($f); 366 367 $res = array(); 368 foreach($def as $v) 369 { 370 $v = trim($v); 371 if (preg_match('|^([^\t]*)[\t]+(.*)$|',$v,$matches)) 372 { 373 $r = '/(\G|[\s]+|>)('.preg_quote($matches[1],'/').')([\s]+|[<]|\Z)/ms'; 374 $s = '$1<img src="'.$url.$matches[2].'" '. 375 'alt="$2" class="smiley" />$3'; 376 $res[$r] = $s; 377 } 378 } 379 380 return $res; 381 } 382 383 public static function addSmilies($str) 384 { 385 if (!isset($GLOBALS['__smilies']) || !is_array($GLOBALS['__smilies'])) { 386 return $str; 387 } 388 389 # Process part adapted from SmartyPants engine (J. Gruber et al.) : 390 391 $tokens = self::tokenizeHTML($str); 392 $result = ''; 393 $in_pre = 0; # Keep track of when we're inside <pre> or <code> tags. 394 395 foreach ($tokens as $cur_token) { 396 if ($cur_token[0] == "tag") { 397 # Don't mess with quotes inside tags. 398 $result .= $cur_token[1]; 399 if (preg_match('@<(/?)(?:pre|code|kbd|script|math)[\s>]@', $cur_token[1], $matches)) { 400 $in_pre = isset($matches[1]) && $matches[1] == '/' ? 0 : 1; 401 } 402 } else { 403 $t = $cur_token[1]; 404 if (!$in_pre) { 405 $t = preg_replace(array_keys($GLOBALS['__smilies']),array_values($GLOBALS['__smilies']),$t); 406 } 407 $result .= $t; 408 } 409 } 410 411 return $result; 412 } 413 414 private static function tokenizeHTML($str) 415 { 416 # Function from SmartyPants engine (J. Gruber et al.) 417 # 418 # Parameter: String containing HTML markup. 419 # Returns: An array of the tokens comprising the input 420 # string. Each token is either a tag (possibly with nested, 421 # tags contained therein, such as <a href="<MTFoo>">, or a 422 # run of text between tags. Each element of the array is a 423 # two-element array; the first is either 'tag' or 'text'; 424 # the second is the actual value. 425 # 426 # 427 # Regular expression derived from the _tokenize() subroutine in 428 # Brad Choate's MTRegex plugin. 429 # <http://www.bradchoate.com/past/mtregex.php> 430 # 431 $index = 0; 432 $tokens = array(); 433 434 $match = '(?s:<!(?:--.*?--\s*)+>)|'. # comment 435 '(?s:<\?.*?\?>)|'. # processing instruction 436 # regular tags 437 '(?:<[/!$]?[-a-zA-Z0-9:]+\b(?>[^"\'>]+|"[^"]*"|\'[^\']*\')*>)'; 438 439 $parts = preg_split("{($match)}", $str, -1, PREG_SPLIT_DELIM_CAPTURE); 440 441 foreach ($parts as $part) { 442 if (++$index % 2 && $part != '') 443 $tokens[] = array('text', $part); 444 else 445 $tokens[] = array('tag', $part); 446 } 447 return $tokens; 448 } 449 450 451 # First post image helpers 452 public static function EntryFirstImageHelper($size,$with_category,$class="",$no_tag=false,$content_only=false,$cat_only=false) 453 { 454 global $core, $_ctx; 455 456 try { 457 $media = new dcMedia($core); 458 $sizes = implode('|',array_keys($media->thumb_sizes)).'|o'; 459 if (!preg_match('/^'.$sizes.'$/',$size)) { 460 $size = 's'; 461 } 462 $p_url = $core->blog->settings->system->public_url; 463 $p_site = preg_replace('#^(.+?//.+?)/(.*)$#','$1',$core->blog->url); 464 $p_root = $core->blog->public_path; 465 466 $pattern = '(?:'.preg_quote($p_site,'/').')?'.preg_quote($p_url,'/'); 467 $pattern = sprintf('/<img.+?src="%s(.*?\.(?:jpg|jpeg|gif|png))"[^>]+/msui',$pattern); 468 469 $src = ''; 470 $alt = ''; 471 472 # We first look in post content 473 if (!$cat_only && $_ctx->posts) 474 { 475 $subject = ($content_only ? '' : $_ctx->posts->post_excerpt_xhtml).$_ctx->posts->post_content_xhtml; 476 if (preg_match_all($pattern,$subject,$m) > 0) 477 { 478 foreach ($m[1] as $i => $img) { 479 if (($src = self::ContentFirstImageLookup($p_root,$img,$size)) !== false) { 480 $dirname = str_replace('\\', '/', dirname($img)); 481 $src = $p_url.($dirname != '/' ? $dirname : '').'/'.$src; 482 if (preg_match('/alt="([^"]+)"/',$m[0][$i],$malt)) { 483 $alt = $malt[1]; 484 } 485 break; 486 } 487 } 488 } 489 } 490 491 # No src, look in category description if available 492 if (!$src && $with_category && $_ctx->posts->cat_desc) 493 { 494 if (preg_match_all($pattern,$_ctx->posts->cat_desc,$m) > 0) 495 { 496 foreach ($m[1] as $i => $img) { 497 if (($src = self::ContentFirstImageLookup($p_root,$img,$size)) !== false) { 498 $dirname = str_replace('\\', '/', dirname($img)); 499 $src = $p_url.($dirname != '/' ? $dirname : '').'/'.$src; 500 if (preg_match('/alt="([^"]+)"/',$m[0][$i],$malt)) { 501 $alt = $malt[1]; 502 } 503 break; 504 } 505 } 506 }; 507 } 508 509 if ($src) { 510 if ($no_tag) { 511 return $src; 512 } else { 513 return '<img alt="'.$alt.'" src="'.$src.'" class="'.$class.'" />'; 514 } 515 } 516 517 } catch (Exception $e) { 518 $core->error->add($e->getMessage()); 519 } 520 } 521 522 private static function ContentFirstImageLookup($root,$img,$size) 523 { 524 global $core; 525 526 # Get base name and extension 527 $info = path::info($img); 528 $base = $info['base']; 529 530 try { 531 $media = new dcMedia($core); 532 $sizes = implode('|',array_keys($media->thumb_sizes)); 533 if (preg_match('/^\.(.+)_('.$sizes.')$/',$base,$m)) { 534 $base = $m[1]; 535 } 536 537 $res = false; 538 if ($size != 'o' && file_exists($root.'/'.$info['dirname'].'/.'.$base.'_'.$size.'.jpg')) 539 { 540 $res = '.'.$base.'_'.$size.'.jpg'; 541 } 542 elseif ($size != 'o' && file_exists($root.'/'.$info['dirname'].'/.'.$base.'_'.$size.'.png')) 543 { 544 $res = '.'.$base.'_'.$size.'.png'; 545 } 546 else 547 { 548 $f = $root.'/'.$info['dirname'].'/'.$base; 549 if (file_exists($f.'.'.$info['extension'])) { 550 $res = $base.'.'.$info['extension']; 551 } elseif (file_exists($f.'.jpg')) { 552 $res = $base.'.jpg'; 553 } elseif (file_exists($f.'.jpeg')) { 554 $res = $base.'.jpeg'; 555 } elseif (file_exists($f.'.png')) { 556 $res = $base.'.png'; 557 } elseif (file_exists($f.'.gif')) { 558 $res = $base.'.gif'; 559 } elseif (file_exists($f.'.JPG')) { 560 $res = $base.'.JPG'; 561 } elseif (file_exists($f.'.JPEG')) { 562 $res = $base.'.JPEG'; 563 } elseif (file_exists($f.'.PNG')) { 564 $res = $base.'.PNG'; 565 } elseif (file_exists($f.'.GIF')) { 566 $res = $base.'.GIF'; 567 } 568 } 569 } catch (Exception $e) { 570 $core->error->add($e->getMessage()); 571 } 572 573 if ($res) { 574 return $res; 575 } 576 return false; 577 } 16 public $stack = array(); 17 18 public function __set($name, $var) 19 { 20 if ($var === null) { 21 $this->pop($name); 22 } else { 23 $this->stack[$name][] = &$var; 24 if ($var instanceof record) { 25 $this->stack['cur_loop'][] = &$var; 26 } 27 } 28 } 29 30 public function __get($name) 31 { 32 if (!isset($this->stack[$name])) { 33 return; 34 } 35 36 $n = count($this->stack[$name]); 37 if ($n > 0) { 38 return $this->stack[$name][($n - 1)]; 39 } 40 41 return; 42 } 43 44 public function exists($name) 45 { 46 return isset($this->stack[$name][0]); 47 } 48 49 public function pop($name) 50 { 51 if (isset($this->stack[$name])) { 52 $v = array_pop($this->stack[$name]); 53 if ($v instanceof record) { 54 array_pop($this->stack['cur_loop']); 55 } 56 unset($v); 57 } 58 } 59 60 # Loop position tests 61 public function loopPosition($start, $length = null, $even = null, $modulo = null) 62 { 63 if (!$this->cur_loop) { 64 return false; 65 } 66 67 $index = $this->cur_loop->index(); 68 $size = $this->cur_loop->count(); 69 70 $test = false; 71 if ($start >= 0) { 72 $test = $index >= $start; 73 if ($length !== null) { 74 if ($length >= 0) { 75 $test = $test && $index < $start + $length; 76 } else { 77 $test = $test && $index < $size + $length; 78 } 79 } 80 } else { 81 $test = $index >= $size + $start; 82 if ($length !== null) { 83 if ($length >= 0) { 84 $test = $test && $index < $size + $start + $length; 85 } else { 86 $test = $test && $index < $size + $length; 87 } 88 } 89 } 90 91 if ($even !== null) { 92 $test = $test && $index % 2 == $even; 93 } 94 95 if ($modulo !== null) { 96 $test = $test && ($index % $modulo == 0); 97 } 98 99 return $test; 100 } 101 102 /** 103 @deprecated since version 2.11 , use tpl_context::global_filters instead 104 */ 105 public static function global_filter($str, 106 $encode_xml, $remove_html, $cut_string, $lower_case, $upper_case, $encode_url, $tag = '') { 107 return self::global_filters( 108 $str, 109 array(0 => null, 110 'encode_xml' => $encode_xml, 111 'remove_html' => $remove_html, 112 'cut_string' => $cut_string, 113 'lower_case' => $lower_case, 114 'upper_case' => ($upper_case == 1 ? 1 : 0), 115 'capitalize' => ($upper_case == 2 ? 1 : 0), 116 'encode_url' => $encode_url), 117 $tag); 118 } 119 120 public static function global_filters($str, $args, $tag = '') 121 { 122 $args[0] = &$str; 123 $params = new ArrayObject($args); 124 125 # --BEHAVIOR-- publicBeforeContentFilter 126 $res = $GLOBALS['core']->callBehavior('publicBeforeContentFilter', $GLOBALS['core'], $tag, $params); 127 $str = $params[0]; 128 129 if ($params['strip_tags']) { 130 $str = self::strip_tags($str); 131 } 132 if ($params['remove_html']) { 133 $str = self::remove_html($str); 134 $str = preg_replace('/\s+/', ' ', $str); 135 } 136 if ($params['encode_xml'] || $params['encode_html']) { 137 $str = self::encode_xml($str); 138 } 139 140 if ($params['cut_string'] > 0) { 141 $str = self::cut_string($str, (integer) $params['cut_string']); 142 } 143 144 if ($params['lower_case']) { 145 $str = self::lower_case($str); 146 } elseif ($params['capitalize']) { 147 $str = self::capitalize($str); 148 } elseif ($params['upper_case']) { 149 $str = self::upper_case($str); 150 } 151 152 if ($params['encode_url']) { 153 $str = self::encode_url($str); 154 } 155 156 # --BEHAVIOR-- publicAfterContentFilter 157 $res = $GLOBALS['core']->callBehavior('publicAfterContentFilter', $GLOBALS['core'], $tag, $params); 158 $str = $params[0]; 159 160 return $str; 161 } 162 163 public static function encode_url($str) 164 { 165 return urlencode($str); 166 } 167 168 public static function cut_string($str, $l) 169 { 170 return text::cutString($str, $l); 171 } 172 173 public static function encode_xml($str) 174 { 175 return html::escapeHTML($str); 176 } 177 178 public static function remove_html($str) 179 { 180 return html::decodeEntities(html::clean($str)); 181 } 182 183 public static function strip_tags($str) 184 { 185 return trim(preg_replace('/ {2,}/', ' ', str_replace(array("\r", "\n", "\t"), ' ', html::clean($str)))); 186 } 187 188 public static function lower_case($str) 189 { 190 return mb_strtolower($str); 191 } 192 193 public static function upper_case($str) 194 { 195 return mb_strtoupper($str); 196 } 197 198 public static function capitalize($str) 199 { 200 if ($str != '') { 201 $str[0] = mb_strtoupper($str[0]); 202 } 203 return $str; 204 } 205 206 public static function categoryPostParam(&$p) 207 { 208 $not = substr($p['cat_url'], 0, 1) == '!'; 209 if ($not) { 210 $p['cat_url'] = substr($p['cat_url'], 1); 211 } 212 213 $p['cat_url'] = preg_split('/\s*,\s*/', $p['cat_url'], -1, PREG_SPLIT_NO_EMPTY); 214 215 foreach ($p['cat_url'] as &$v) { 216 if ($not) { 217 $v .= ' ?not'; 218 } 219 if ($GLOBALS['_ctx']->exists('categories') && preg_match('/#self/', $v)) { 220 $v = preg_replace('/#self/', $GLOBALS['_ctx']->categories->cat_url, $v); 221 } elseif ($GLOBALS['_ctx']->exists('posts') && preg_match('/#self/', $v)) { 222 $v = preg_replace('/#self/', $GLOBALS['_ctx']->posts->cat_url, $v); 223 } 224 } 225 } 226 227 # Static methods for pagination 228 public static function PaginationNbPages() 229 { 230 global $_ctx; 231 232 if ($_ctx->pagination === null) { 233 return false; 234 } 235 236 $nb_posts = $_ctx->pagination->f(0); 237 if (($GLOBALS['core']->url->type == 'default') || ($GLOBALS['core']->url->type == 'default-page')) { 238 $nb_pages = ceil(($nb_posts - $_ctx->nb_entry_first_page) / $_ctx->nb_entry_per_page + 1); 239 } else { 240 $nb_pages = ceil($nb_posts / $_ctx->nb_entry_per_page); 241 } 242 243 return $nb_pages; 244 } 245 246 public static function PaginationPosition($offset = 0) 247 { 248 if (isset($GLOBALS['_page_number'])) { 249 $p = $GLOBALS['_page_number']; 250 } else { 251 $p = 1; 252 } 253 254 $p = $p + $offset; 255 256 $n = self::PaginationNbPages(); 257 if (!$n) { 258 return $p; 259 } 260 261 if ($p > $n || $p <= 0) { 262 return 1; 263 } else { 264 return $p; 265 } 266 } 267 268 public static function PaginationStart() 269 { 270 if (isset($GLOBALS['_page_number'])) { 271 return self::PaginationPosition() == 1; 272 } 273 274 return true; 275 } 276 277 public static function PaginationEnd() 278 { 279 if (isset($GLOBALS['_page_number'])) { 280 return self::PaginationPosition() == self::PaginationNbPages(); 281 } 282 283 return false; 284 } 285 286 public static function PaginationURL($offset = 0) 287 { 288 $args = $_SERVER['URL_REQUEST_PART']; 289 290 $n = self::PaginationPosition($offset); 291 292 $args = preg_replace('#(^|/)page/([0-9]+)$#', '', $args); 293 294 $url = $GLOBALS['core']->blog->url . $args; 295 296 if ($n > 1) { 297 $url = preg_replace('#/$#', '', $url); 298 $url .= '/page/' . $n; 299 } 300 301 # If search param 302 if (!empty($_GET['q'])) { 303 $s = strpos($url, '?') !== false ? '&' : '?'; 304 $url .= $s . 'q=' . rawurlencode($_GET['q']); 305 } 306 return $url; 307 } 308 309 # Robots policy 310 public static function robotsPolicy($base, $over) 311 { 312 $pol = array('INDEX' => 'INDEX', 'FOLLOW' => 'FOLLOW', 'ARCHIVE' => 'ARCHIVE'); 313 $base = array_flip(preg_split('/\s*,\s*/', $base)); 314 $over = array_flip(preg_split('/\s*,\s*/', $over)); 315 316 foreach ($pol as $k => &$v) { 317 if (isset($base[$k]) || isset($base['NO' . $k])) { 318 $v = isset($base['NO' . $k]) ? 'NO' . $k : $k; 319 } 320 if (isset($over[$k]) || isset($over['NO' . $k])) { 321 $v = isset($over['NO' . $k]) ? 'NO' . $k : $k; 322 } 323 } 324 325 if ($pol['ARCHIVE'] == 'ARCHIVE') { 326 unset($pol['ARCHIVE']); 327 } 328 329 return implode(', ', $pol); 330 } 331 332 # Smilies static methods 333 public static function getSmilies($blog) 334 { 335 $path = array(); 336 if (isset($GLOBALS['__theme'])) { 337 $path[] = $GLOBALS['__theme']; 338 if (isset($GLOBALS['__parent_theme'])) { 339 $path[] = $GLOBALS['__parent_theme']; 340 } 341 } 342 $path[] = 'default'; 343 $definition = $blog->themes_path . '/%s/smilies/smilies.txt'; 344 $base_url = $blog->settings->system->themes_url . '/%s/smilies/'; 345 346 $res = array(); 347 348 foreach ($path as $t) { 349 if (file_exists(sprintf($definition, $t))) { 350 $base_url = sprintf($base_url, $t); 351 return self::smiliesDefinition(sprintf($definition, $t), $base_url); 352 } 353 } 354 return false; 355 } 356 357 public static function smiliesDefinition($f, $url) 358 { 359 $def = file($f); 360 361 $res = array(); 362 foreach ($def as $v) { 363 $v = trim($v); 364 if (preg_match('|^([^\t]*)[\t]+(.*)$|', $v, $matches)) { 365 $r = '/(\G|[\s]+|>)(' . preg_quote($matches[1], '/') . ')([\s]+|[<]|\Z)/ms'; 366 $s = '$1<img src="' . $url . $matches[2] . '" ' . 367 'alt="$2" class="smiley" />$3'; 368 $res[$r] = $s; 369 } 370 } 371 372 return $res; 373 } 374 375 public static function addSmilies($str) 376 { 377 if (!isset($GLOBALS['__smilies']) || !is_array($GLOBALS['__smilies'])) { 378 return $str; 379 } 380 381 # Process part adapted from SmartyPants engine (J. Gruber et al.) : 382 383 $tokens = self::tokenizeHTML($str); 384 $result = ''; 385 $in_pre = 0; # Keep track of when we're inside <pre> or <code> tags. 386 387 foreach ($tokens as $cur_token) { 388 if ($cur_token[0] == "tag") { 389 # Don't mess with quotes inside tags. 390 $result .= $cur_token[1]; 391 if (preg_match('@<(/?)(?:pre|code|kbd|script|math)[\s>]@', $cur_token[1], $matches)) { 392 $in_pre = isset($matches[1]) && $matches[1] == '/' ? 0 : 1; 393 } 394 } else { 395 $t = $cur_token[1]; 396 if (!$in_pre) { 397 $t = preg_replace(array_keys($GLOBALS['__smilies']), array_values($GLOBALS['__smilies']), $t); 398 } 399 $result .= $t; 400 } 401 } 402 403 return $result; 404 } 405 406 private static function tokenizeHTML($str) 407 { 408 # Function from SmartyPants engine (J. Gruber et al.) 409 # 410 # Parameter: String containing HTML markup. 411 # Returns: An array of the tokens comprising the input 412 # string. Each token is either a tag (possibly with nested, 413 # tags contained therein, such as <a href="<MTFoo>">, or a 414 # run of text between tags. Each element of the array is a 415 # two-element array; the first is either 'tag' or 'text'; 416 # the second is the actual value. 417 # 418 # 419 # Regular expression derived from the _tokenize() subroutine in 420 # Brad Choate's MTRegex plugin. 421 # <http://www.bradchoate.com/past/mtregex.php> 422 # 423 $index = 0; 424 $tokens = array(); 425 426 $match = '(?s:<!(?:--.*?--\s*)+>)|' . # comment 427 '(?s:<\?.*?\?>)|' . # processing instruction 428 # regular tags 429 '(?:<[/!$]?[-a-zA-Z0-9:]+\b(?>[^"\'>]+|"[^"]*"|\'[^\']*\')*>)'; 430 431 $parts = preg_split("{($match)}", $str, -1, PREG_SPLIT_DELIM_CAPTURE); 432 433 foreach ($parts as $part) { 434 if (++$index % 2 && $part != '') { 435 $tokens[] = array('text', $part); 436 } else { 437 $tokens[] = array('tag', $part); 438 } 439 440 } 441 return $tokens; 442 } 443 444 # First post image helpers 445 public static function EntryFirstImageHelper($size, $with_category, $class = "", $no_tag = false, $content_only = false, $cat_only = false) 446 { 447 global $core, $_ctx; 448 449 try { 450 $media = new dcMedia($core); 451 $sizes = implode('|', array_keys($media->thumb_sizes)) . '|o'; 452 if (!preg_match('/^' . $sizes . '$/', $size)) { 453 $size = 's'; 454 } 455 $p_url = $core->blog->settings->system->public_url; 456 $p_site = preg_replace('#^(.+?//.+?)/(.*)$#', '$1', $core->blog->url); 457 $p_root = $core->blog->public_path; 458 459 $pattern = '(?:' . preg_quote($p_site, '/') . ')?' . preg_quote($p_url, '/'); 460 $pattern = sprintf('/<img.+?src="%s(.*?\.(?:jpg|jpeg|gif|png))"[^>]+/msui', $pattern); 461 462 $src = ''; 463 $alt = ''; 464 465 # We first look in post content 466 if (!$cat_only && $_ctx->posts) { 467 $subject = ($content_only ? '' : $_ctx->posts->post_excerpt_xhtml) . $_ctx->posts->post_content_xhtml; 468 if (preg_match_all($pattern, $subject, $m) > 0) { 469 foreach ($m[1] as $i => $img) { 470 if (($src = self::ContentFirstImageLookup($p_root, $img, $size)) !== false) { 471 $dirname = str_replace('\\', '/', dirname($img)); 472 $src = $p_url . ($dirname != '/' ? $dirname : '') . '/' . $src; 473 if (preg_match('/alt="([^"]+)"/', $m[0][$i], $malt)) { 474 $alt = $malt[1]; 475 } 476 break; 477 } 478 } 479 } 480 } 481 482 # No src, look in category description if available 483 if (!$src && $with_category && $_ctx->posts->cat_desc) { 484 if (preg_match_all($pattern, $_ctx->posts->cat_desc, $m) > 0) { 485 foreach ($m[1] as $i => $img) { 486 if (($src = self::ContentFirstImageLookup($p_root, $img, $size)) !== false) { 487 $dirname = str_replace('\\', '/', dirname($img)); 488 $src = $p_url . ($dirname != '/' ? $dirname : '') . '/' . $src; 489 if (preg_match('/alt="([^"]+)"/', $m[0][$i], $malt)) { 490 $alt = $malt[1]; 491 } 492 break; 493 } 494 } 495 }; 496 } 497 498 if ($src) { 499 if ($no_tag) { 500 return $src; 501 } else { 502 return '<img alt="' . $alt . '" src="' . $src . '" class="' . $class . '" />'; 503 } 504 } 505 506 } catch (Exception $e) { 507 $core->error->add($e->getMessage()); 508 } 509 } 510 511 private static function ContentFirstImageLookup($root, $img, $size) 512 { 513 global $core; 514 515 # Get base name and extension 516 $info = path::info($img); 517 $base = $info['base']; 518 519 try { 520 $media = new dcMedia($core); 521 $sizes = implode('|', array_keys($media->thumb_sizes)); 522 if (preg_match('/^\.(.+)_(' . $sizes . ')$/', $base, $m)) { 523 $base = $m[1]; 524 } 525 526 $res = false; 527 if ($size != 'o' && file_exists($root . '/' . $info['dirname'] . '/.' . $base . '_' . $size . '.jpg')) { 528 $res = '.' . $base . '_' . $size . '.jpg'; 529 } elseif ($size != 'o' && file_exists($root . '/' . $info['dirname'] . '/.' . $base . '_' . $size . '.png')) { 530 $res = '.' . $base . '_' . $size . '.png'; 531 } else { 532 $f = $root . '/' . $info['dirname'] . '/' . $base; 533 if (file_exists($f . '.' . $info['extension'])) { 534 $res = $base . '.' . $info['extension']; 535 } elseif (file_exists($f . '.jpg')) { 536 $res = $base . '.jpg'; 537 } elseif (file_exists($f . '.jpeg')) { 538 $res = $base . '.jpeg'; 539 } elseif (file_exists($f . '.png')) { 540 $res = $base . '.png'; 541 } elseif (file_exists($f . '.gif')) { 542 $res = $base . '.gif'; 543 } elseif (file_exists($f . '.JPG')) { 544 $res = $base . '.JPG'; 545 } elseif (file_exists($f . '.JPEG')) { 546 $res = $base . '.JPEG'; 547 } elseif (file_exists($f . '.PNG')) { 548 $res = $base . '.PNG'; 549 } elseif (file_exists($f . '.GIF')) { 550 $res = $base . '.GIF'; 551 } 552 } 553 } catch (Exception $e) { 554 $core->error->add($e->getMessage()); 555 } 556 557 if ($res) { 558 return $res; 559 } 560 return false; 561 } 578 562 }
Note: See TracChangeset
for help on using the changeset viewer.