[ Index ] |
PHP Cross Reference of Textpattern 4.0.8 |
[Summary view] [Print] [Text view]
1 <?php 2 3 /* 4 $HeadURL: https://textpattern.googlecode.com/svn/releases/4.0.8/source/textpattern/lib/txplib_misc.php $ 5 $LastChangedRevision: 3074 $ 6 */ 7 8 // ------------------------------------------------------------- 9 function doArray($in,$function) 10 { 11 return is_array($in) ? array_map($function,$in) : $function($in); 12 } 13 14 // ------------------------------------------------------------- 15 function doStrip($in) 16 { 17 return doArray($in,'stripslashes'); 18 } 19 20 // ------------------------------------------------------------- 21 function doStripTags($in) 22 { 23 return doArray($in,'strip_tags'); 24 } 25 26 // ------------------------------------------------------------- 27 function doDeEnt($in) 28 { 29 return doArray($in,'deEntBrackets'); 30 } 31 32 // ------------------------------------------------------------- 33 function deEntBrackets($in) 34 { 35 $array = array( 36 '<' => '<', 37 '<' => '<', 38 '<' => '<', 39 '>' => '>', 40 '>' => '>', 41 '>' => '>' 42 ); 43 44 foreach($array as $k=>$v){ 45 $in = preg_replace("/".preg_quote($k)."/i",$v, $in); 46 } 47 return $in; 48 } 49 50 // ------------------------------------------------------------- 51 function doSlash($in) 52 { 53 return doArray($in,'mysql_real_escape_string'); 54 } 55 56 // ------------------------------------------------------------- 57 function doSpecial($in) 58 { 59 return doArray($in,'htmlspecialchars'); 60 } 61 62 // ------------------------------------------------------------- 63 function _null($a) 64 { 65 return NULL; 66 } 67 // ------------------------------------------------------------- 68 function array_null($in) 69 { 70 return array_map('_null', $in); 71 } 72 73 // ------------------------------------------------------------- 74 function escape_title($title) 75 { 76 return strtr($title, 77 array( 78 '<' => '<', 79 '>' => '>', 80 "'" => ''', 81 '"' => '"', 82 ) 83 ); 84 } 85 86 // ------------------------------------------------------------- 87 // deprecated, use htmlspecialchars instead. Remove in crockery 88 function escape_output($str) 89 { 90 return htmlspecialchars($str); 91 } 92 93 // ------------------------------------------------------------- 94 // unused function => deprecate and remove in crockery? 95 function escape_tags($str) 96 { 97 return strtr($str, 98 array( 99 '<' => '<', 100 '>' => '>', 101 ) 102 ); 103 } 104 105 // ------------------------------------------------------------- 106 function escape_cdata($str) 107 { 108 return '<![CDATA['.str_replace(']]>', ']]]><![CDATA[]>', $str).']]>'; 109 } 110 111 //------------------------------------------------------------- 112 function gTxt($var, $atts=array()) 113 { 114 global $textarray; 115 if(isset($textarray[strtolower($var)])) { 116 $out = $textarray[strtolower($var)]; 117 return strtr($out, $atts); 118 } 119 120 if ($atts) 121 return $var.': '.join(', ', $atts); 122 return $var; 123 } 124 125 //------------------------------------------------------------- 126 function gTime($timestamp) 127 { 128 return safe_strftime('%d %b %Y %X', $timestamp); 129 } 130 131 // ------------------------------------------------------------- 132 function dmp() 133 { 134 static $f = FALSE; 135 136 if(defined('txpdmpfile')) 137 { 138 global $prefs; 139 140 if(!$f) $f = fopen($prefs['tempdir'].'/'.txpdmpfile, 'a'); 141 142 fwrite($f, "\n[".safe_strftime('iso8601')."]\n"); 143 } 144 145 $a = func_get_args(); 146 147 if(!$f) echo "<pre>".n; 148 149 foreach ($a as $thing) 150 { 151 $out = is_scalar($thing) ? strval($thing) : var_export($thing, true); 152 153 if ($f) 154 { 155 fwrite($f, $out."\n"); 156 } 157 else 158 { 159 echo htmlspecialchars($out), n; 160 } 161 } 162 163 if(!$f) echo "</pre>".n; 164 } 165 166 // ------------------------------------------------------------- 167 function load_lang($lang) 168 { 169 global $txpcfg; 170 171 foreach(array($lang, 'en-gb') as $lang_code) 172 { 173 $rs = (txpinterface == 'admin') 174 ? safe_rows_start('name, data','txp_lang',"lang='".doSlash($lang_code)."'") 175 : safe_rows_start('name, data','txp_lang',"lang='".doSlash($lang_code)."' AND ( event='public' OR event='common')"); 176 177 if (mysql_num_rows($rs)) break; 178 } 179 180 $out = array(); 181 182 if ($rs && mysql_num_rows($rs) > 0) 183 { 184 while ($a = nextRow($rs)) 185 { 186 $out[$a['name']] = $a['data']; 187 } 188 }else{ 189 #backward compatibility stuff. Remove when necessary. 190 $filename = is_file(txpath.'/lang/'.$lang.'.txt') 191 ? txpath.'/lang/'.$lang.'.txt' 192 : txpath.'/lang/en-gb.txt'; 193 194 $file = @fopen($filename, "r"); 195 if ($file) { 196 while (!feof($file)) { 197 $line = fgets($file, 4096); 198 if($line[0]=='#') continue; 199 @list($name,$val) = explode(' => ',trim($line)); 200 $out[$name] = $val; 201 } 202 @fclose($filename); 203 } 204 } 205 206 return $out; 207 } 208 209 // ------------------------------------------------------------- 210 function load_lang_dates($lang) 211 { 212 global $txpcfg; 213 $filename = is_file(txpath.'/lang/'.$lang.'_dates.txt')? 214 txpath.'/lang/'.$lang.'_dates.txt': 215 txpath.'/lang/en-gb_dates.txt'; 216 $file = @file(txpath.'/lang/'.$lang.'_dates.txt','r'); 217 if(is_array($file)) { 218 foreach($file as $line) { 219 if($line[0]=='#' || strlen($line) < 2) continue; 220 list($name,$val) = explode('=>',$line,2); 221 $out[trim($name)] = trim($val); 222 } 223 return $out; 224 } 225 return false; 226 } 227 // ------------------------------------------------------------- 228 229 function load_lang_event($event) 230 { 231 global $txpcfg; 232 $lang = LANG; 233 234 $installed = safe_field('name', 'txp_lang',"lang='".doSlash($lang)."' limit 1"); 235 236 $lang_code = ($installed)? $lang : 'en-gb'; 237 238 $rs = safe_rows_start('name, data','txp_lang',"lang='".doSlash($lang_code)."' AND event='".doSlash($event)."'"); 239 240 $out = array(); 241 242 if ($rs && !empty($rs)) 243 { 244 while ($a = nextRow($rs)) 245 { 246 $out[$a['name']] = $a['data']; 247 } 248 } 249 return ($out) ? $out : ''; 250 } 251 252 // ------------------------------------------------------------- 253 function check_privs() 254 { 255 global $txp_user; 256 $privs = safe_field("privs", "txp_users", "name='".doSlash($txp_user)."'"); 257 $args = func_get_args(); 258 if(!in_array($privs,$args)) { 259 exit(pageTop('Restricted').'<p style="margin-top:3em;text-align:center">'. 260 gTxt('restricted_area').'</p>'); 261 } 262 } 263 264 // ------------------------------------------------------------- 265 function add_privs($res, $perm = '1') // perm = '1,2,3' 266 { 267 global $txp_permissions; 268 // Don't let them override privs that exist 269 if (!isset($txp_permissions[$res])) 270 $txp_permissions[$res] = $perm; 271 } 272 273 // ------------------------------------------------------------- 274 function has_privs($res, $user='') 275 { 276 global $txp_user, $txp_permissions; 277 static $privs; 278 279 // If no user name is supplied, assume the current login name 280 if (empty($user)) 281 $user = $txp_user; 282 283 if (!isset($privs[$user])) 284 { 285 $privs[$user] = safe_field("privs", "txp_users", "name='".doSlash($user)."'"); 286 } 287 288 if (isset($txp_permissions[$res])) 289 { 290 return in_array($privs[$user], explode(',', $txp_permissions[$res])); 291 } 292 293 else 294 { 295 return false; 296 } 297 } 298 299 // ------------------------------------------------------------- 300 function require_privs($res, $user='') 301 { 302 if (!has_privs($res, $user)) 303 exit(pageTop('Restricted').'<p style="margin-top:3em;text-align:center">'. 304 gTxt('restricted_area').'</p>'); 305 } 306 307 // ------------------------------------------------------------- 308 function sizeImage($name) 309 { 310 $size = @getimagesize($name); 311 return(is_array($size)) ? $size[3] : false; 312 } 313 314 // ------------------------------------------------------------- 315 function gps($thing) // checks GET and POST for a named variable, or creates it blank 316 { 317 if (isset($_GET[$thing])) { 318 if (MAGIC_QUOTES_GPC) { 319 return doStrip($_GET[$thing]); 320 } else { 321 return $_GET[$thing]; 322 } 323 } elseif (isset($_POST[$thing])) { 324 if (MAGIC_QUOTES_GPC) { 325 return doStrip($_POST[$thing]); 326 } else { 327 return $_POST[$thing]; 328 } 329 } 330 return ''; 331 } 332 333 // ------------------------------------------------------------- 334 function gpsa($array) // performs gps() on an array of variable names 335 { 336 if(is_array($array)) { 337 $out = array(); 338 foreach($array as $a) { 339 $out[$a] = gps($a); 340 } 341 return $out; 342 } 343 return false; 344 } 345 346 // ------------------------------------------------------------- 347 function ps($thing) // checks POST for a named variable, or creates it blank 348 { 349 if (isset($_POST[$thing])) { 350 if (MAGIC_QUOTES_GPC) { 351 return doStrip($_POST[$thing]); 352 } else { 353 return $_POST[$thing]; 354 } 355 } 356 return ''; 357 } 358 359 // ------------------------------------------------------------- 360 function psa($array) // performs ps on an array of variable names 361 { 362 foreach($array as $a) { 363 $out[$a] = ps($a); 364 } 365 return $out; 366 } 367 368 // ------------------------------------------------------------- 369 function psas($array) // same as above, but does strip_tags on post values 370 { 371 foreach($array as $a) { 372 $out[$a] = strip_tags(ps($a)); 373 } 374 return $out; 375 } 376 377 // ------------------------------------------------------------- 378 function stripPost() 379 { 380 if (isset($_POST)) { 381 if (MAGIC_QUOTES_GPC) { 382 return doStrip($_POST); 383 } else { 384 return $_POST; 385 } 386 } 387 return ''; 388 } 389 390 // ------------------------------------------------------------- 391 function serverSet($thing) // Get a var from $_SERVER global array, or create it 392 { 393 return (isset($_SERVER[$thing])) ? $_SERVER[$thing] : ''; 394 } 395 396 // ------------------------------------------------------------- 397 function pcs($thing) // Get a var from POST or COOKIE; if not, create it 398 { 399 if (isset($_COOKIE["txp_".$thing])) { 400 if (MAGIC_QUOTES_GPC) { 401 return doStrip($_COOKIE["txp_".$thing]); 402 } else return $_COOKIE["txp_".$thing]; 403 } elseif (isset($_POST[$thing])) { 404 if (MAGIC_QUOTES_GPC) { 405 return doStrip($_POST[$thing]); 406 } else return $_POST[$thing]; 407 } 408 return ''; 409 } 410 411 // ------------------------------------------------------------- 412 function cs($thing) // Get a var from COOKIE; if not, create it 413 { 414 if (isset($_COOKIE[$thing])) { 415 if (MAGIC_QUOTES_GPC) { 416 return doStrip($_COOKIE[$thing]); 417 } else return $_COOKIE[$thing]; 418 } 419 return ''; 420 } 421 422 // ------------------------------------------------------------- 423 function yes_no($status) 424 { 425 return ($status==0) ? (gTxt('no')) : (gTxt('yes')); 426 } 427 428 // ------------------------------------------------------------- 429 function getmicrotime() 430 { 431 list($usec, $sec) = explode(" ",microtime()); 432 return ((float)$usec + (float)$sec); 433 } 434 435 // ------------------------------------------------------------- 436 function load_plugin($name) 437 { 438 global $plugins, $plugins_ver, $prefs, $txp_current_plugin; 439 440 if (is_array($plugins) and in_array($name,$plugins)) { 441 return true; 442 } 443 444 if (!empty($prefs['plugin_cache_dir'])) { 445 $dir = rtrim($prefs['plugin_cache_dir'], '/') . '/'; 446 # in case it's a relative path 447 if (!is_dir($dir)) 448 $dir = rtrim(realpath(txpath.'/'.$dir), '/') . '/'; 449 if (is_file($dir . $name . '.php')) { 450 $plugins[] = $name; 451 set_error_handler("pluginErrorHandler"); 452 if (isset($txp_current_plugin)) $txp_parent_plugin = $txp_current_plugin; 453 $txp_current_plugin = $name; 454 include($dir . $name . '.php'); 455 $txp_current_plugin = (isset($txp_parent_plugin) ? $txp_parent_plugin : NULL); 456 $plugins_ver[$name] = @$plugin['version']; 457 restore_error_handler(); 458 return true; 459 } 460 } 461 462 $rs = safe_row("name,code,version","txp_plugin","status = 1 AND name='".doSlash($name)."'"); 463 if ($rs) { 464 $plugins[] = $rs['name']; 465 $plugins_ver[$rs['name']] = $rs['version']; 466 467 set_error_handler("pluginErrorHandler"); 468 if (isset($txp_current_plugin)) $txp_parent_plugin = $txp_current_plugin; 469 $txp_current_plugin = $rs['name']; 470 eval($rs['code']); 471 $txp_current_plugin = (isset($txp_parent_plugin) ? $txp_parent_plugin : NULL); 472 restore_error_handler(); 473 474 return true; 475 } 476 477 return false; 478 } 479 480 // ------------------------------------------------------------- 481 function require_plugin($name) 482 { 483 if (!load_plugin($name)) 484 trigger_error("Unable to include required plugin \"{$name}\"",E_USER_ERROR); 485 } 486 487 // ------------------------------------------------------------- 488 function include_plugin($name) 489 { 490 if (!load_plugin($name)) 491 trigger_error("Unable to include plugin \"{$name}\"",E_USER_WARNING); 492 } 493 494 // ------------------------------------------------------------- 495 function pluginErrorHandler($errno, $errstr, $errfile, $errline) 496 { 497 $error = array( E_WARNING => "Warning", E_NOTICE => "Notice", E_USER_ERROR => "User_Error", 498 E_USER_WARNING => "User_Warning", E_USER_NOTICE => "User_Notice"); 499 500 if (!($errno & error_reporting())) return; 501 502 global $txp_current_plugin, $production_status; 503 printf ("<pre>".gTxt('plugin_load_error').' <b>%s</b> -> <b>%s: %s on line %s</b></pre>', 504 $txp_current_plugin, $error[$errno], $errstr, $errline); 505 if ($production_status == 'debug') 506 print "\n<pre style=\"padding-left: 2em;\" class=\"backtrace\"><code>".htmlspecialchars(join("\n", get_caller(10)))."</code></pre>"; 507 } 508 509 // ------------------------------------------------------------- 510 function tagErrorHandler($errno, $errstr, $errfile, $errline) 511 { 512 global $production_status; 513 514 $error = array( E_WARNING => "Warning", E_NOTICE => "Notice", E_USER_ERROR => "Textpattern Error", 515 E_USER_WARNING => "Textpattern Warning", E_USER_NOTICE => "Textpattern Notice"); 516 517 if (!($errno & error_reporting())) return; 518 if ($production_status == 'live') return; 519 520 global $txp_current_tag; 521 $errline = ($errstr === 'unknown_tag') ? '' : " on line $errline"; 522 printf ("<pre>".gTxt('tag_error').' <b>%s</b> -> <b> %s: %s %s</b></pre>', 523 htmlspecialchars($txp_current_tag), $error[$errno], $errstr, $errline ); 524 if ($production_status == 'debug') 525 { 526 print "\n<pre style=\"padding-left: 2em;\" class=\"backtrace\"><code>".htmlspecialchars(join("\n", get_caller(10)))."</code></pre>"; 527 528 $trace_msg = gTxt('tag_error').' '.$txp_current_tag.' -> '.$error[$errno].': '.$errstr.' '.$errline; 529 trace_add( $trace_msg ); 530 } 531 } 532 533 // ------------------------------------------------------------- 534 function feedErrorHandler($errno, $errstr, $errfile, $errline) 535 { 536 global $production_status; 537 538 if ($production_status != 'debug') return; 539 540 return tagErrorHandler($errno, $errstr, $errfile, $errline); 541 } 542 543 // ------------------------------------------------------------- 544 function load_plugins($type=0) 545 { 546 global $prefs,$plugins, $plugins_ver; 547 548 if (!is_array($plugins)) $plugins = array(); 549 550 if (!empty($prefs['plugin_cache_dir'])) { 551 $dir = rtrim($prefs['plugin_cache_dir'], '/') . '/'; 552 # in case it's a relative path 553 if (!is_dir($dir)) 554 $dir = rtrim(realpath(txpath.'/'.$dir), '/') . '/'; 555 foreach (glob($dir.'*.php') as $f) { 556 load_plugin(basename($f, '.php')); 557 } 558 } 559 560 $where = 'status = 1 AND type IN ('.($type ? '1,3' : '0,1').')'; 561 562 $rs = safe_rows("name, code, version", "txp_plugin", $where.' order by load_order'); 563 if ($rs) { 564 $old_error_handler = set_error_handler("pluginErrorHandler"); 565 foreach($rs as $a) { 566 if (!in_array($a['name'],$plugins)) { 567 $plugins[] = $a['name']; 568 $plugins_ver[$a['name']] = $a['version']; 569 $GLOBALS['txp_current_plugin'] = $a['name']; 570 $eval_ok = eval($a['code']); 571 if ($eval_ok === FALSE) 572 echo gTxt('plugin_load_error_above').strong($a['name']).n.br; 573 unset($GLOBALS['txp_current_plugin']); 574 } 575 } 576 restore_error_handler(); 577 } 578 } 579 580 // ------------------------------------------------------------- 581 function register_callback($func, $event, $step='', $pre=0) 582 { 583 global $plugin_callback; 584 585 $plugin_callback[] = array('function'=>$func, 'event'=>$event, 'step'=>$step, 'pre'=>$pre); 586 } 587 588 // ------------------------------------------------------------- 589 function register_page_extension($func, $event, $step='', $top=0) 590 { 591 # For now this just does the same as register_callback 592 register_callback($func, $event, $step, $top); 593 } 594 595 // ------------------------------------------------------------- 596 function callback_event($event, $step='', $pre=0) 597 { 598 global $plugin_callback; 599 600 if (!is_array($plugin_callback)) 601 return; 602 $return_value = ''; 603 foreach ($plugin_callback as $c) { 604 if ($c['event'] == $event and (empty($c['step']) or $c['step'] == $step) and $c['pre'] == $pre) { 605 if (is_callable($c['function'])) { 606 $return_value .= call_user_func($c['function'], $event, $step); 607 } 608 } 609 } 610 return $return_value; 611 } 612 613 // ------------------------------------------------------------- 614 function register_tab($area, $event, $title) 615 { 616 global $plugin_areas; 617 618 $plugin_areas[$area][$title] = $event; 619 } 620 621 // ------------------------------------------------------------- 622 // deprecated, use lAtts instead. Remove in crockery 623 function getAtt($name, $default=NULL) 624 { 625 global $theseatts; 626 return isset($theseatts[$name]) ? $theseatts[$name] : $default; 627 } 628 629 // ------------------------------------------------------------- 630 // deprecated, use lAtts instead. Remove in crockery 631 function gAtt(&$atts, $name, $default=NULL) 632 { 633 return isset($atts[$name]) ? $atts[$name] : $default; 634 } 635 636 // ------------------------------------------------------------- 637 function lAtts($pairs, $atts, $warn=1) 638 { 639 global $production_status; 640 641 foreach($atts as $name => $value) 642 { 643 if (array_key_exists($name, $pairs)) 644 { 645 $pairs[$name] = $value; 646 } 647 elseif ($warn and $production_status != 'live') 648 { 649 trigger_error(gTxt('unknown_attribute', array('{att}' => $name))); 650 } 651 } 652 653 return ($pairs) ? $pairs : false; 654 } 655 656 // ------------------------------------------------------------- 657 function select_buttons() 658 { 659 return 660 gTxt('select').': '. 661 fInput('button','selall',gTxt('all'),'smallerboxsp','select all','selectall();'). 662 fInput('button','selnone',gTxt('none'),'smallerboxsp','select none','deselectall();'). 663 fInput('button','selrange',gTxt('range'),'smallerboxsp','select range','selectrange();'); 664 } 665 666 // ------------------------------------------------------------- 667 function stripSpace($text, $force=0) 668 { 669 global $prefs; 670 if ($force or !empty($prefs['attach_titles_to_permalinks'])) 671 { 672 $text = sanitizeForUrl($text); 673 if ($prefs['permalink_title_format']) { 674 return strtolower($text); 675 } else { 676 return str_replace('-','',$text); 677 } 678 } 679 } 680 681 // ------------------------------------------------------------- 682 function sanitizeForUrl($text) 683 { 684 // Remove names entities and tags 685 $text = preg_replace("/(^|&\S+;)|(<[^>]*>)/U","",dumbDown($text)); 686 // Dashify high-order chars leftover from dumbDown() 687 $text = preg_replace("/[\x80-\xff]/","-",$text); 688 // Collapse spaces, minuses, (back-)slashes and non-words 689 $text = preg_replace('/[\s\-\/\\\\]+/', '-', trim(preg_replace('/[^\w\s\-\/\\\\]/', '', $text))); 690 // Remove all non-whitelisted characters 691 $text = preg_replace("/[^A-Za-z0-9\-_]/","",$text); 692 return $text; 693 } 694 695 // ------------------------------------------------------------- 696 function dumbDown($str, $lang=LANG) 697 { 698 static $array; 699 if (empty($array[$lang])) { 700 $array[$lang] = array( // nasty, huh?. 701 'À'=>'A','À'=>'A','Á'=>'A','Á'=>'A','Â'=>'A','Â'=>'A', 702 'Ã'=>'A','Ã'=>'A','Ä'=>'Ae','Ä'=>'A','Å'=>'A','Å'=>'A', 703 'Æ'=>'Ae','Æ'=>'AE', 704 'Ā'=>'A','Ą'=>'A','Ă'=>'A', 705 'Ç'=>'C','Ç'=>'C','Ć'=>'C','Č'=>'C','Ĉ'=>'C','Ċ'=>'C', 706 'Ď'=>'D','Đ'=>'D','Ð'=>'D','Ð'=>'D', 707 'È'=>'E','È'=>'E','É'=>'E','É'=>'E','Ê'=>'E','Ê'=>'E','Ë'=>'E','Ë'=>'E', 708 'Ē'=>'E','Ę'=>'E','Ě'=>'E','Ĕ'=>'E','Ė'=>'E', 709 'Ĝ'=>'G','Ğ'=>'G','Ġ'=>'G','Ģ'=>'G', 710 'Ĥ'=>'H','Ħ'=>'H', 711 'Ì'=>'I','Ì'=>'I','Í'=>'I','Í'=>'I','Î'=>'I','Î'=>'I','Ï'=>'I','Ï'=>'I', 712 'Ī'=>'I','Ĩ'=>'I','Ĭ'=>'I','Į'=>'I','İ'=>'I', 713 'IJ'=>'IJ', 714 'Ĵ'=>'J', 715 'Ķ'=>'K', 716 'Ł'=>'K','Ľ'=>'K','Ĺ'=>'K','Ļ'=>'K','Ŀ'=>'K', 717 'Ñ'=>'N','Ñ'=>'N','Ń'=>'N','Ň'=>'N','Ņ'=>'N','Ŋ'=>'N', 718 'Ò'=>'O','Ò'=>'O','Ó'=>'O','Ó'=>'O','Ô'=>'O','Ô'=>'O','Õ'=>'O','Õ'=>'O', 719 'Ö'=>'Oe','Ö'=>'Oe', 720 'Ø'=>'O','Ø'=>'O','Ō'=>'O','Ő'=>'O','Ŏ'=>'O', 721 'Œ'=>'OE', 722 'Ŕ'=>'R','Ř'=>'R','Ŗ'=>'R', 723 'Ś'=>'S','Š'=>'S','Ş'=>'S','Ŝ'=>'S','Ș'=>'S', 724 'Ť'=>'T','Ţ'=>'T','Ŧ'=>'T','Ț'=>'T', 725 'Ù'=>'U','Ù'=>'U','Ú'=>'U','Ú'=>'U','Û'=>'U','Û'=>'U', 726 'Ü'=>'Ue','Ū'=>'U','Ü'=>'Ue', 727 'Ů'=>'U','Ű'=>'U','Ŭ'=>'U','Ũ'=>'U','Ų'=>'U', 728 'Ŵ'=>'W', 729 'Ý'=>'Y','Ý'=>'Y','Ŷ'=>'Y','Ÿ'=>'Y', 730 'Ź'=>'Z','Ž'=>'Z','Ż'=>'Z', 731 'Þ'=>'T','Þ'=>'T', 732 'à'=>'a','á'=>'a','â'=>'a','ã'=>'a','ä'=>'ae', 733 'ä'=>'ae', 734 'å'=>'a','ā'=>'a','ą'=>'a','ă'=>'a','å'=>'a', 735 'æ'=>'ae', 736 'ç'=>'c','ć'=>'c','č'=>'c','ĉ'=>'c','ċ'=>'c', 737 'ď'=>'d','đ'=>'d','ð'=>'d', 738 'è'=>'e','é'=>'e','ê'=>'e','ë'=>'e','ē'=>'e', 739 'ę'=>'e','ě'=>'e','ĕ'=>'e','ė'=>'e', 740 'ƒ'=>'f', 741 'ĝ'=>'g','ğ'=>'g','ġ'=>'g','ģ'=>'g', 742 'ĥ'=>'h','ħ'=>'h', 743 'ì'=>'i','í'=>'i','î'=>'i','ï'=>'i','ī'=>'i', 744 'ĩ'=>'i','ĭ'=>'i','į'=>'i','ı'=>'i', 745 'ij'=>'ij', 746 'ĵ'=>'j', 747 'ķ'=>'k','ĸ'=>'k', 748 'ł'=>'l','ľ'=>'l','ĺ'=>'l','ļ'=>'l','ŀ'=>'l', 749 'ñ'=>'n','ń'=>'n','ň'=>'n','ņ'=>'n','ʼn'=>'n', 750 'ŋ'=>'n', 751 'ò'=>'o','ó'=>'o','ô'=>'o','õ'=>'o','ö'=>'oe', 752 'ö'=>'oe', 753 'ø'=>'o','ō'=>'o','ő'=>'o','ŏ'=>'o', 754 'œ'=>'oe', 755 'ŕ'=>'r','ř'=>'r','ŗ'=>'r', 756 'š'=>'s', 757 'ù'=>'u','ú'=>'u','û'=>'u','ü'=>'ue','ū'=>'u', 758 'ü'=>'ue', 759 'ů'=>'u','ű'=>'u','ŭ'=>'u','ũ'=>'u','ų'=>'u', 760 'ŵ'=>'w', 761 'ý'=>'y','ÿ'=>'y','ŷ'=>'y', 762 'ž'=>'z','ż'=>'z','ź'=>'z', 763 'þ'=>'t', 764 'ß'=>'ss', 765 'ſ'=>'ss', 766 'à'=>'a','á'=>'a','â'=>'a','ã'=>'a','ä'=>'ae', 767 'å'=>'a','æ'=>'ae','ç'=>'c','ð'=>'d', 768 'è'=>'e','é'=>'e','ê'=>'e','ë'=>'e', 769 'ì'=>'i','í'=>'i','î'=>'i','ï'=>'i', 770 'ñ'=>'n', 771 'ò'=>'o','ó'=>'o','ô'=>'o','õ'=>'o','ö'=>'oe', 772 'ø'=>'o', 773 'ù'=>'u','ú'=>'u','û'=>'u','ü'=>'ue', 774 'ý'=>'y','ÿ'=>'y', 775 'þ'=>'t', 776 'ß'=>'ss' 777 ); 778 779 780 if (is_file(txpath.'/lib/i18n-ascii.txt')) { 781 $i18n = parse_ini_file(txpath.'/lib/i18n-ascii.txt', true); 782 # load the global map 783 if (@is_array($i18n['default'])) { 784 $array[$lang] = array_merge($array[$lang], $i18n['default']); 785 # base language overrides: 'de-AT' applies the 'de' section 786 if (preg_match('/([a-zA-Z]+)-.+/', $lang, $m)) { 787 if (@is_array($i18n[$m[1]])) 788 $array[$lang] = array_merge($array[$lang], $i18n[$m[1]]); 789 }; 790 # regional language overrides: 'de-AT' applies the 'de-AT' section 791 if (@is_array($i18n[$lang])) 792 $array[$lang] = array_merge($array[$lang], $i18n[$lang]); 793 } 794 # load an old file (no sections) just in case 795 else 796 $array[$lang] = array_merge($array[$lang], $i18n); 797 } 798 } 799 800 return strtr($str, $array[$lang]); 801 } 802 803 // ------------------------------------------------------------- 804 function clean_url($url) 805 { 806 return preg_replace("/\"|'|(?:\s.*$)/",'',$url); 807 } 808 809 // ------------------------------------------------------------- 810 function noWidow($str) 811 { 812 // replace the last space with a nbsp 813 if (REGEXP_UTF8 == 1) 814 return preg_replace('@[ ]+([[:punct:]]?\pL+[[:punct:]]?)$@u', ' $1', rtrim($str)); 815 return preg_replace('@[ ]+([[:punct:]]?\w+[[:punct:]]?)$@', ' $1', rtrim($str)); 816 } 817 818 // ------------------------------------------------------------- 819 function is_blacklisted($ip, $checks = '') 820 { 821 global $prefs; 822 823 if (!$checks) 824 { 825 $checks = do_list($prefs['spam_blacklists']); 826 } 827 828 $rip = join('.', array_reverse(explode('.', $ip))); 829 830 foreach ($checks as $a) 831 { 832 $parts = explode(':', $a, 2); 833 $rbl = $parts[0]; 834 835 if (isset($parts[1])) 836 { 837 foreach (explode(':', $parts[1]) as $code) 838 { 839 $codes[] = strpos($code, '.') ? $code : '127.0.0.'.$code; 840 } 841 } 842 843 $hosts = $rbl ? @gethostbynamel($rip.'.'.trim($rbl, '. ').'.') : FALSE; 844 845 if ($hosts and (!isset($codes) or array_intersect($hosts, $codes))) 846 { 847 $listed[] = $rbl; 848 } 849 } 850 851 return (!empty($listed)) ? join(', ', $listed) : false; 852 } 853 854 // ------------------------------------------------------------- 855 function is_logged_in($user = '') 856 { 857 $name = substr(cs('txp_login_public'), 10); 858 859 if (!strlen($name) or strlen($user) and $user !== $name) 860 { 861 return FALSE; 862 } 863 864 $rs = safe_row('nonce, name, RealName, email, privs', 'txp_users', "name = '".doSlash($name)."'"); 865 866 if ($rs and substr(md5($rs['nonce']), -10) === substr(cs('txp_login_public'), 0, 10)) 867 { 868 unset($rs['nonce']); 869 return $rs; 870 } 871 else 872 { 873 return FALSE; 874 } 875 } 876 877 // ------------------------------------------------------------- 878 function updateSitePath($here) 879 { 880 $here = doSlash($here); 881 $rs = safe_field ("name",'txp_prefs',"name = 'path_to_site'"); 882 if (!$rs) { 883 safe_insert("txp_prefs","prefs_id=1,name='path_to_site',val='$here'"); 884 } else { 885 safe_update('txp_prefs',"val='$here'","name='path_to_site'"); 886 } 887 } 888 889 // ------------------------------------------------------------- 890 function splat($text) 891 { 892 $atts = array(); 893 894 if (preg_match_all('@(\w+)\s*=\s*(?:"((?:[^"]|"")*)"|\'((?:[^\']|\'\')*)\'|([^\s\'"/>]+))@s', $text, $match, PREG_SET_ORDER)) 895 { 896 foreach ($match as $m) 897 { 898 switch (count($m)) 899 { 900 case 3: 901 $val = str_replace('""', '"', $m[2]); 902 break; 903 case 4: 904 $val = str_replace("''", "'", $m[3]); 905 906 if (strpos($m[3], '<txp:') !== FALSE) 907 { 908 trace_add("[attribute '".$m[1]."']"); 909 $val = parse($val); 910 trace_add("[/attribute]"); 911 } 912 913 break; 914 case 5: 915 $val = $m[4]; 916 trigger_error(gTxt('attribute_values_must_be_quoted'), E_USER_WARNING); 917 break; 918 } 919 920 $atts[strtolower($m[1])] = $val; 921 } 922 923 } 924 925 return $atts; 926 } 927 928 // ------------------------------------------------------------- 929 function maxMemUsage($message = 'none', $returnit = 0) 930 { 931 static $memory_top = 0; 932 static $memory_message; 933 934 if (is_callable('memory_get_usage')) 935 { 936 $memory_now = memory_get_usage(); 937 if ($memory_now > $memory_top) 938 { 939 $memory_top = $memory_now; 940 $memory_message = $message; 941 } 942 } 943 944 if ($returnit != 0) 945 { 946 if (is_callable('memory_get_usage')) 947 return n.comment(sprintf('Memory: %sKb, %s', 948 ceil($memory_top/1024),$memory_message)); 949 else 950 return n.comment('Memory: no info available'); 951 } 952 } 953 954 // ------------------------------------------------------------- 955 function strip_rn($str) 956 { 957 return strtr($str, "\r\n", ' '); 958 } 959 960 // ------------------------------------------------------------- 961 962 function is_valid_email($address) 963 { 964 return preg_match('/^[a-z0-9](\.?[a-z0-9_+%-])*@([a-z0-9](-*[a-z0-9])*\.)+[a-z]{2,6}$/i', $address); 965 } 966 967 // ------------------------------------------------------------- 968 969 function txpMail($to_address, $subject, $body, $reply_to = null) 970 { 971 global $txp_user, $prefs; 972 973 // if mailing isn't possible, don't even try 974 if (is_disabled('mail')) 975 { 976 return false; 977 } 978 979 // Likely sending passwords 980 if (isset($txp_user)) 981 { 982 extract(safe_row('RealName, email', 'txp_users', "name = '".doSlash($txp_user)."'")); 983 } 984 985 // Likely sending comments -> "to" equals "from" 986 else 987 { 988 extract(safe_row('RealName, email', 'txp_users', "email = '".doSlash($to_address)."'")); 989 } 990 991 if ($prefs['override_emailcharset'] and is_callable('utf8_decode')) 992 { 993 $charset = 'ISO-8859-1'; 994 995 $RealName = utf8_decode($RealName); 996 $subject = utf8_decode($subject); 997 $body = utf8_decode($body); 998 } 999 1000 else 1001 { 1002 $charset = 'UTF-8'; 1003 } 1004 1005 $RealName = encode_mailheader(strip_rn($RealName), 'phrase'); 1006 $subject = encode_mailheader(strip_rn($subject), 'text'); 1007 $email = strip_rn($email); 1008 1009 if (!is_null($reply_to)) 1010 { 1011 $reply_to = strip_rn($reply_to); 1012 } 1013 1014 $sep = !is_windows() ? "\n" : "\r\n"; 1015 1016 $body = str_replace("\r\n", "\n", $body); 1017 $body = str_replace("\r", "\n", $body); 1018 $body = str_replace("\n", $sep, $body); 1019 1020 $headers = "From: $RealName <$email>". 1021 $sep.'Reply-To: '.( isset($reply_to) ? $reply_to : "$RealName <$email>" ). 1022 $sep.'X-Mailer: Textpattern'. 1023 $sep.'Content-Transfer-Encoding: 8bit'. 1024 $sep.'Content-Type: text/plain; charset="'.$charset.'"'. 1025 $sep; 1026 1027 if (is_valid_email($prefs['smtp_from'])) 1028 { 1029 if (is_windows()) 1030 { 1031 ini_set('sendmail_from', $prefs['smtp_from']); 1032 } 1033 elseif (!ini_get('safe_mode')) 1034 { 1035 return mail($to_address, $subject, $body, $headers, '-f'.$prefs['smtp_from']); 1036 } 1037 } 1038 1039 return mail($to_address, $subject, $body, $headers); 1040 } 1041 1042 // ------------------------------------------------------------- 1043 function encode_mailheader($string, $type) 1044 { 1045 global $prefs; 1046 if (!strstr($string,'=?') and !preg_match('/[\x00-\x1F\x7F-\xFF]/', $string)) { 1047 if ("phrase" == $type) { 1048 if (preg_match('/[][()<>@,;:".\x5C]/', $string)) { 1049 $string = '"'. strtr($string, array("\\" => "\\\\", '"' => '\"')) . '"'; 1050 } 1051 } 1052 elseif ( "text" != $type) { 1053 trigger_error( 'Unknown encode_mailheader type', E_USER_WARNING); 1054 } 1055 return $string; 1056 } 1057 if ($prefs['override_emailcharset'] and is_callable('utf8_decode')) { 1058 $start = '=?ISO-8859-1?B?'; 1059 $pcre = '/.{1,42}/s'; 1060 } 1061 else { 1062 $start = '=?UTF-8?B?'; 1063 $pcre = '/.{1,45}(?=[\x00-\x7F\xC0-\xFF]|$)/s'; 1064 } 1065 $end = '?='; 1066 $sep = is_windows() ? "\r\n" : "\n"; 1067 preg_match_all($pcre, $string, $matches); 1068 return $start . join($end.$sep.' '.$start, array_map('base64_encode',$matches[0])) . $end; 1069 } 1070 1071 // ------------------------------------------------------------- 1072 function stripPHP($in) 1073 { 1074 return preg_replace("/".chr(60)."\?(?:php)?|\?".chr(62)."/i",'',$in); 1075 } 1076 1077 // ------------------------------------------------------------- 1078 1079 /** 1080 * PEDRO: 1081 * Helper functions for common textpattern event files actions. 1082 * Code refactoring from original files. Intended to do easy and less error 1083 * prone the future build of new textpattern extensions, and to add new 1084 * events to multiedit forms. 1085 */ 1086 1087 function event_category_popup($name, $cat = '', $id = '') 1088 { 1089 $arr = array(''); 1090 $rs = getTree('root', $name); 1091 1092 if ($rs) 1093 { 1094 return treeSelectInput('category', $rs, $cat, $id); 1095 } 1096 1097 return false; 1098 } 1099 1100 // ------------------------------------------------------------- 1101 function event_change_pageby($name) 1102 { 1103 $qty = gps('qty'); 1104 $pageby = $name.'_list_pageby'; 1105 $GLOBALS[$pageby] = $qty; 1106 1107 safe_update('txp_prefs', "val='".doSlash($qty)."'", "name='".doSlash($pageby)."'"); 1108 1109 return; 1110 } 1111 1112 // ------------------------------------------------------------- 1113 1114 function event_multiedit_form($name, $methods = null, $page, $sort, $dir, $crit, $search_method) 1115 { 1116 $method = ps('edit_method'); 1117 1118 if ($methods === NULL) 1119 { 1120 $methods = array( 1121 'delete' => gTxt('delete') 1122 ); 1123 } 1124 1125 return '<label for="withselected">'.gTxt('with_selected').'</label>'.sp. 1126 selectInput('edit_method', $methods, $method, 1, ' id="withselected" onchange="poweredit(this); return false;"'). 1127 n.eInput($name). 1128 n.sInput($name.'_multi_edit'). 1129 n.hInput('page', $page). 1130 ( $sort ? n.hInput('sort', $sort).n.hInput('dir', $dir) : '' ). 1131 ( $crit ? n.hInput('crit', $crit).n.hInput('search_method', $search_method) : '' ). 1132 n.fInput('submit', '', gTxt('go'), 'smallerbox'); 1133 } 1134 1135 // ------------------------------------------------------------- 1136 1137 function event_multi_edit($table, $id_key) 1138 { 1139 $method = ps('edit_method'); 1140 $selected = ps('selected'); 1141 1142 if ($selected) 1143 { 1144 if ($method == 'delete') 1145 { 1146 foreach ($selected as $id) 1147 { 1148 $id = assert_int($id); 1149 1150 if (safe_delete($table, "$id_key = $id")) 1151 { 1152 $ids[] = $id; 1153 } 1154 } 1155 1156 return join(', ', $ids); 1157 } 1158 } 1159 1160 return ''; 1161 } 1162 1163 // ------------------------------------------------------------- 1164 function since($stamp) 1165 { 1166 $diff = (time() - $stamp); 1167 if ($diff <= 3600) { 1168 $mins = round($diff / 60); 1169 $since = ($mins <= 1) 1170 ? ($mins==1) 1171 ? '1 '.gTxt('minute') 1172 : gTxt('a_few_seconds') 1173 : "$mins ".gTxt('minutes'); 1174 } else if (($diff <= 86400) && ($diff > 3600)) { 1175 $hours = round($diff / 3600); 1176 $since = ($hours <= 1) ? '1 '.gTxt('hour') : "$hours ".gTxt('hours'); 1177 } else if ($diff >= 86400) { 1178 $days = round($diff / 86400); 1179 $since = ($days <= 1) ? "1 ".gTxt('day') : "$days ".gTxt('days'); 1180 } 1181 return $since.' '.gTxt('ago'); // sorry, this needs to be hacked until a truly multilingual version is done 1182 } 1183 1184 // ------------------------------------------------------------- 1185 // Calculate the offset between the server local time and the 1186 // user's selected time zone 1187 function tz_offset() 1188 { 1189 global $gmtoffset, $is_dst; 1190 1191 extract(getdate()); 1192 $serveroffset = gmmktime(0,0,0,$mon,$mday,$year) - mktime(0,0,0,$mon,$mday,$year); 1193 $offset = $gmtoffset - $serveroffset; 1194 1195 return $offset + ($is_dst ? 3600 : 0); 1196 } 1197 1198 // ------------------------------------------------------------- 1199 // Format a time, respecting the locale and local time zone, 1200 // and make sure the output string is safe for UTF-8 1201 function safe_strftime($format, $time='', $gmt=0, $override_locale='') 1202 { 1203 global $locale; 1204 $old_locale = $locale; 1205 1206 if (!$time) 1207 $time = time(); 1208 1209 # we could add some other formats here 1210 if ($format == 'iso8601' or $format == 'w3cdtf') { 1211 $format = '%Y-%m-%dT%H:%M:%SZ'; 1212 $gmt = 1; 1213 } 1214 elseif ($format == 'rfc822') { 1215 $format = '%a, %d %b %Y %H:%M:%S GMT'; 1216 $gmt = 1; 1217 $override_locale = 'en-gb'; 1218 } 1219 1220 if ($override_locale) 1221 getlocale($override_locale); 1222 1223 if ($format == 'since') 1224 $str = since($time); 1225 elseif ($gmt) 1226 $str = gmstrftime($format, $time); 1227 else 1228 $str = strftime($format, $time + tz_offset()); 1229 1230 @list($lang, $charset) = explode('.', $locale); 1231 if (empty($charset)) 1232 $charset = 'ISO-8859-1'; 1233 elseif (is_windows() and is_numeric($charset)) 1234 // Score -1 for consistent naming conventions 1235 $charset = 'Windows-'.$charset; 1236 1237 if ($charset != 'UTF-8' and $format != 'since') { 1238 $new = ''; 1239 if (is_callable('iconv')) 1240 $new = @iconv($charset, 'UTF-8', $str); 1241 1242 if ($new) 1243 $str = $new; 1244 elseif (is_callable('utf8_encode')) 1245 $str = utf8_encode($str); 1246 } 1247 1248 # revert to the old locale 1249 if ($override_locale) 1250 $locale = setlocale(LC_ALL, $old_locale); 1251 1252 return $str; 1253 } 1254 1255 // ------------------------------------------------------------- 1256 // Convert a time string from the Textpattern time zone to GMT 1257 function safe_strtotime($time_str) 1258 { 1259 return strtotime($time_str, time()+tz_offset()) - tz_offset(); 1260 } 1261 1262 // ------------------------------------------------------------- 1263 function myErrorHandler($errno, $errstr, $errfile, $errline) 1264 { 1265 # error_reporting() returns 0 when the '@' suppression 1266 # operator is used 1267 if (!error_reporting()) 1268 return; 1269 1270 echo '<pre>'.n.n."$errno: $errstr in $errfile at line $errline\n"; 1271 # Requires PHP 4.3 1272 if (is_callable('debug_backtrace')) { 1273 echo "Backtrace:\n"; 1274 $trace = debug_backtrace(); 1275 foreach($trace as $ent) { 1276 if(isset($ent['file'])) echo $ent['file'].':'; 1277 if(isset($ent['function'])) { 1278 echo $ent['function'].'('; 1279 if(isset($ent['args'])) { 1280 $args=''; 1281 foreach($ent['args'] as $arg) { $args.=$arg.','; } 1282 echo rtrim($args,','); 1283 } 1284 echo ') '; 1285 } 1286 if(isset($ent['line'])) echo 'at line '.$ent['line'].' '; 1287 if(isset($ent['file'])) echo 'in '.$ent['file']; 1288 echo "\n"; 1289 } 1290 } 1291 echo "</pre>"; 1292 } 1293 1294 // ------------------------------------------------------------- 1295 function find_temp_dir() 1296 { 1297 global $path_to_site, $img_dir; 1298 1299 if (is_windows()) { 1300 $guess = array(txpath.DS.'tmp', getenv('TMP'), getenv('TEMP'), getenv('SystemRoot').DS.'Temp', 'C:'.DS.'Temp', $path_to_site.DS.$img_dir); 1301 foreach ($guess as $k=>$v) 1302 if (empty($v)) unset($guess[$k]); 1303 } 1304 else 1305 $guess = array(txpath.DS.'tmp', '', DS.'tmp', $path_to_site.DS.$img_dir); 1306 1307 foreach ($guess as $dir) { 1308 $tf = @tempnam($dir, 'txp_'); 1309 if ($tf) $tf = realpath($tf); 1310 if ($tf and file_exists($tf)) { 1311 unlink($tf); 1312 return dirname($tf); 1313 } 1314 } 1315 1316 return false; 1317 } 1318 1319 // ------------------------------------------------------------- 1320 function get_uploaded_file($f, $dest='') 1321 { 1322 global $tempdir; 1323 1324 if (!is_uploaded_file($f)) 1325 return false; 1326 1327 if ($dest) { 1328 $newfile = $dest; 1329 } 1330 else { 1331 $newfile = tempnam($tempdir, 'txp_'); 1332 if (!$newfile) 1333 return false; 1334 } 1335 1336 # $newfile is created by tempnam(), but move_uploaded_file 1337 # will overwrite it 1338 if (move_uploaded_file($f, $newfile)) 1339 return $newfile; 1340 } 1341 1342 // -------------------------------------------------------------- 1343 function set_error_level($level) 1344 { 1345 1346 if ($level == 'debug') { 1347 error_reporting(E_ALL); 1348 } 1349 elseif ($level == 'live') { 1350 // don't show errors on screen 1351 error_reporting(E_ALL ^ (E_WARNING | E_NOTICE)); 1352 @ini_set("display_errors","1"); 1353 } 1354 else { 1355 // default is 'testing': display everything except notices 1356 error_reporting(E_ALL ^ (E_NOTICE)); 1357 } 1358 } 1359 1360 1361 // ------------------------------------------------------------- 1362 function shift_uploaded_file($f, $dest) 1363 { 1364 // Rename might not work, but it's worth a try 1365 if (@rename($f, $dest)) 1366 return true; 1367 1368 if (@copy($f, $dest)) { 1369 unlink($f); 1370 return true; 1371 } 1372 } 1373 // ------------------------------------------------------------- 1374 function upload_get_errormsg($err_code) 1375 { 1376 $msg = ''; 1377 switch ($err_code) 1378 { 1379 // Value: 0; There is no error, the file uploaded with success. 1380 case UPLOAD_ERR_OK : $msg = '';break; 1381 // Value: 1; The uploaded file exceeds the upload_max_filesize directive in php.ini. 1382 case UPLOAD_ERR_INI_SIZE : $msg = gTxt('upload_err_ini_size');break; 1383 // Value: 2; The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form. 1384 case UPLOAD_ERR_FORM_SIZE : $msg = gTxt('upload_err_form_size');break; 1385 // Value: 3; The uploaded file was only partially uploaded. 1386 case UPLOAD_ERR_PARTIAL : $msg = gTxt('upload_err_partial');break; 1387 // Value: 4; No file was uploaded. 1388 case UPLOAD_ERR_NO_FILE : $msg = gTxt('upload_err_no_file');break; 1389 // Value: 6; Missing a temporary folder. Introduced in PHP 4.3.10 and PHP 5.0.3. 1390 case UPLOAD_ERR_NO_TMP_DIR : $msg = gTxt('upload_err_tmp_dir');break; 1391 // Value: 7; Failed to write file to disk. Introduced in PHP 5.1.0. 1392 case UPLOAD_ERR_CANT_WRITE : $msg = gTxt('upload_err_cant_write');break; 1393 // Value: 8; File upload stopped by extension. Introduced in PHP 5.2.0. 1394 case UPLOAD_ERR_EXTENSION : $msg = gTxt('upload_err_extension');break; 1395 } 1396 return $msg; 1397 } 1398 1399 // ------------------------------------------------------------- 1400 function is_windows() 1401 { 1402 return (PHP_OS == 'WINNT' or PHP_OS == 'WIN32' or PHP_OS == 'Windows'); 1403 } 1404 1405 // ------------------------------------------------------------- 1406 function is_cgi() 1407 { 1408 return IS_CGI; 1409 } 1410 1411 // ------------------------------------------------------------- 1412 function is_mod_php() 1413 { 1414 return IS_APACHE; 1415 } 1416 1417 // ------------------------------------------------------------- 1418 1419 function is_disabled($function) 1420 { 1421 static $disabled; 1422 1423 if (!isset($disabled)) 1424 { 1425 $disabled = explode(',', ini_get('disable_functions')); 1426 } 1427 1428 return in_array($function, $disabled); 1429 } 1430 1431 // -------------------------------------------------------------- 1432 function build_file_path($base,$path) 1433 { 1434 $base = rtrim($base,'/\\'); 1435 $path = ltrim($path,'/\\'); 1436 1437 return $base.DIRECTORY_SEPARATOR.$path; 1438 } 1439 1440 // -------------------------------------------------------------- 1441 function get_author_name($name) 1442 { 1443 static $authors = array(); 1444 1445 if (isset($authors[$name])) 1446 return $authors[$name]; 1447 1448 $realname = fetch('RealName','txp_users','name',doSlash($name)); 1449 $authors[$name] = $realname; 1450 return ($realname) ? $realname : $name; 1451 } 1452 1453 1454 // -------------------------------------------------------------- 1455 function EvalElse($thing, $condition) 1456 { 1457 global $txp_current_tag; 1458 1459 trace_add("[$txp_current_tag: ".($condition ? gTxt('true') : gTxt('false'))."]"); 1460 1461 $els = strpos($thing, '<txp:else'); 1462 1463 if ($els === FALSE) 1464 { 1465 return $condition ? $thing : ''; 1466 } 1467 elseif ($els === strpos($thing, '<txp:')) 1468 { 1469 return $condition 1470 ? substr($thing, 0, $els) 1471 : substr($thing, strpos($thing, '>', $els) + 1); 1472 } 1473 1474 $tag = FALSE; 1475 $level = 0; 1476 $str = ''; 1477 $regex = '@(</?txp:\w+(?:\s+\w+\s*=\s*(?:"(?:[^"]|"")*"|\'(?:[^\']|\'\')*\'|[^\s\'"/>]+))*\s*/?'.chr(62).')@s'; 1478 $parsed = preg_split($regex, $thing, -1, PREG_SPLIT_DELIM_CAPTURE); 1479 1480 foreach ($parsed as $chunk) 1481 { 1482 if ($tag) 1483 { 1484 if ($level === 0 and strpos($chunk, 'else') === 5 and substr($chunk, -2, 1) === '/') 1485 { 1486 return $condition 1487 ? $str 1488 : substr($thing, strlen($str)+strlen($chunk)); 1489 } 1490 elseif (substr($chunk, 1, 1) === '/') 1491 { 1492 $level--; 1493 } 1494 elseif (substr($chunk, -2, 1) !== '/') 1495 { 1496 $level++; 1497 } 1498 } 1499 1500 $tag = !$tag; 1501 $str .= $chunk; 1502 } 1503 1504 return $condition ? $thing : ''; 1505 } 1506 1507 // -------------------------------------------------------------- 1508 function fetch_form($name) 1509 { 1510 static $forms = array(); 1511 1512 if (isset($forms[$name])) 1513 $f = $forms[$name]; 1514 else { 1515 $row = safe_row('Form', 'txp_form',"name='".doSlash($name)."'"); 1516 if (!$row) { 1517 trigger_error(gTxt('form_not_found').': '.$name); 1518 return; 1519 } 1520 $f = $row['Form']; 1521 $forms[$name] = $f; 1522 } 1523 1524 trace_add('['.gTxt('form').': '.$name.']'); 1525 return $f; 1526 } 1527 1528 // -------------------------------------------------------------- 1529 function parse_form($name) 1530 { 1531 static $stack = array(); 1532 1533 $f = fetch_form($name); 1534 if ($f) { 1535 if (in_array($name, $stack)) { 1536 trigger_error(gTxt('form_circular_reference', array('{name}' => $name))); 1537 return; 1538 } 1539 array_push($stack, $name); 1540 $out = parse($f); 1541 array_pop($stack); 1542 return $out; 1543 } 1544 } 1545 1546 // -------------------------------------------------------------- 1547 function fetch_category_title($name, $type='article') 1548 { 1549 static $cattitles = array(); 1550 global $thiscategory; 1551 1552 if (isset($cattitles[$type][$name])) 1553 return $cattitles[$type][$name]; 1554 1555 if(!empty($thiscategory['title']) && $thiscategory['name'] == $name && $thiscategory['type'] == $type) 1556 { 1557 $cattitles[$type][$name] = $thiscategory['title']; 1558 return $thiscategory['title']; 1559 } 1560 1561 $f = safe_field('title','txp_category',"name='".doSlash($name)."' and type='".doSlash($type)."'"); 1562 $cattitles[$type][$name] = $f; 1563 return $f; 1564 } 1565 1566 // ------------------------------------------------------------- 1567 function fetch_section_title($name) 1568 { 1569 static $sectitles = array(); 1570 global $thissection; 1571 1572 // try cache 1573 if (isset($sectitles[$name])) 1574 return $sectitles[$name]; 1575 1576 // try global set by section_list() 1577 if(!empty($thissection['title']) && $thissection['name'] == $name) 1578 { 1579 $sectitles[$name] = $thissection['title']; 1580 return $thissection['title']; 1581 } 1582 1583 if($name == 'default' or empty($name)) 1584 return ''; 1585 1586 $f = safe_field('title','txp_section',"name='".doSlash($name)."'"); 1587 $sectitles[$name] = $f; 1588 return $f; 1589 } 1590 1591 // ------------------------------------------------------------- 1592 function update_comments_count($id) 1593 { 1594 $id = assert_int($id); 1595 $thecount = safe_field('count(*)','txp_discuss','parentid='.$id.' and visible='.VISIBLE); 1596 $thecount = assert_int($thecount); 1597 $updated = safe_update('textpattern','comments_count='.$thecount,'ID='.$id); 1598 return ($updated) ? true : false; 1599 } 1600 1601 // ------------------------------------------------------------- 1602 function clean_comment_counts($parentids) 1603 { 1604 $parentids = array_map('assert_int',$parentids); 1605 $rs = safe_rows_start('parentid, count(*) as thecount','txp_discuss','parentid IN ('.implode(',',$parentids).') AND visible='.VISIBLE.' group by parentid'); 1606 if (!$rs) return; 1607 1608 $updated = array(); 1609 while($a = nextRow($rs)) { 1610 safe_update('textpattern',"comments_count=".$a['thecount'],"ID=".$a['parentid']); 1611 $updated[] = $a['parentid']; 1612 } 1613 // We still need to update all those, that have zero comments left. 1614 $leftover = array_diff($parentids, $updated); 1615 if ($leftover) 1616 safe_update('textpattern',"comments_count=0","ID IN (".implode(',',$leftover).")"); 1617 } 1618 1619 // ------------------------------------------------------------- 1620 1621 function markup_comment($msg) 1622 { 1623 global $prefs; 1624 1625 $disallow_images = !empty($prefs['comments_disallow_images']); 1626 $lite = empty($prefs['comments_use_fat_textile']); 1627 1628 $rel = !empty($prefs['comment_nofollow']) ? 'nofollow' : ''; 1629 1630 include_once txpath.'/lib/classTextile.php'; 1631 1632 $textile = new Textile(); 1633 1634 return $textile->TextileRestricted($msg, $lite, $disallow_images, $rel); 1635 } 1636 1637 //------------------------------------------------------------- 1638 function update_lastmod() { 1639 safe_upsert("txp_prefs", "val = now()", "name = 'lastmod'"); 1640 } 1641 1642 //------------------------------------------------------------- 1643 function get_lastmod($unix_ts=NULL) { 1644 global $prefs; 1645 1646 if ($unix_ts === NULL) 1647 $unix_ts = @strtotime($prefs['lastmod']); 1648 1649 # check for future articles that are now visible 1650 if ($max_article = safe_field('unix_timestamp(Posted)', 'textpattern', "Posted <= now() and Status >= 4 order by Posted desc limit 1")) { 1651 $unix_ts = max($unix_ts, $max_article); 1652 } 1653 1654 return $unix_ts; 1655 } 1656 1657 //------------------------------------------------------------- 1658 function handle_lastmod($unix_ts=NULL, $exit=1) { 1659 global $prefs; 1660 extract($prefs); 1661 1662 if($send_lastmod and $production_status == 'live') { 1663 $unix_ts = get_lastmod($unix_ts); 1664 1665 # make sure lastmod isn't in the future 1666 $unix_ts = min($unix_ts, time()); 1667 # or too far in the past (7 days) 1668 $unix_ts = max($unix_ts, time() - 3600*24*7); 1669 1670 $last = safe_strftime('rfc822', $unix_ts, 1); 1671 header("Last-Modified: $last"); 1672 header('Cache-Control: no-cache'); 1673 1674 $hims = serverset('HTTP_IF_MODIFIED_SINCE'); 1675 if ($hims and @strtotime($hims) >= $unix_ts) { 1676 log_hit('304'); 1677 if (!$exit) 1678 return array('304', $last); 1679 txp_status_header('304 Not Modified'); 1680 # some mod_deflate versions have a bug that breaks subsequent 1681 # requests when keepalive is used. dropping the connection 1682 # is the only reliable way to fix this. 1683 if (empty($lastmod_keepalive)) 1684 header('Connection: close'); 1685 header('Content-Length: 0'); 1686 # discard all output 1687 while (@ob_end_clean()); 1688 exit; 1689 } 1690 1691 if (!$exit) 1692 return array('200', $last); 1693 } 1694 } 1695 1696 //------------------------------------------------------------- 1697 function set_pref($name, $val, $event='publish', $type=0, $html='text_input', $position=0) 1698 { 1699 extract(doSlash(func_get_args())); 1700 1701 if (!safe_row("*", 'txp_prefs', "name = '$name'") ) { 1702 return safe_insert('txp_prefs', " 1703 name = '$name', 1704 val = '$val', 1705 event = '$event', 1706 html = '$html', 1707 type = '$type', 1708 position = '$position', 1709 prefs_id = 1" 1710 ); 1711 } else { 1712 return safe_update('txp_prefs', "val = '$val'","name like '$name'"); 1713 } 1714 return false; 1715 } 1716 1717 // ------------------------------------------------------------- 1718 function txp_status_header($status='200 OK') 1719 { 1720 if (IS_FASTCGI) 1721 header("Status: $status"); 1722 elseif ($_SERVER['SERVER_PROTOCOL'] == 'HTTP/1.0') 1723 header("HTTP/1.0 $status"); 1724 else 1725 header("HTTP/1.1 $status"); 1726 } 1727 1728 // ------------------------------------------------------------- 1729 function txp_die($msg, $status='503') 1730 { 1731 // 503 status might discourage search engines from indexing or caching the error message 1732 1733 //Make it possible to call this function as a tag, e.g. in an article <txp:txp_die status="410" /> 1734 if (is_array($msg)) 1735 extract(lAtts(array('msg' => '', 'status' => '503'),$msg)); 1736 1737 // Intentionally incomplete - just the ones we're likely to use 1738 $codes = array( 1739 '200' => 'OK', 1740 '301' => 'Moved Permanently', 1741 '302' => 'Found', 1742 '304' => 'Not Modified', 1743 '307' => 'Temporary Redirect', 1744 '401' => 'Unauthorized', 1745 '403' => 'Forbidden', 1746 '404' => 'Not Found', 1747 '410' => 'Gone', 1748 '414' => 'Request-URI Too Long', 1749 '500' => 'Internal Server Error', 1750 '501' => 'Not Implemented', 1751 '503' => 'Service Unavailable', 1752 ); 1753 1754 if ($status) { 1755 if (isset($codes[strval($status)])) 1756 $status = strval($status) . ' ' . $codes[$status]; 1757 1758 txp_status_header($status); 1759 } 1760 1761 $code = ''; 1762 if ($status and $parts = @explode(' ', $status, 2)) { 1763 $code = @$parts[0]; 1764 } 1765 1766 if (@$GLOBALS['connected']) { 1767 $out = safe_field('user_html','txp_page',"name='error_".doSlash($code)."'"); 1768 if (empty($out)) 1769 $out = safe_field('user_html','txp_page',"name='error_default'"); 1770 } 1771 1772 if (empty($out)) 1773 $out = <<<eod 1774 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 1775 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 1776 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 1777 <head> 1778 <meta http-equiv="content-type" content="text/html; charset=utf-8" /> 1779 <title>Textpattern Error: <txp:error_status /></title> 1780 </head> 1781 <body> 1782 <p align="center" style="margin-top:4em"><txp:error_message /></p> 1783 </body> 1784 </html> 1785 eod; 1786 1787 header("Content-type: text/html; charset=utf-8"); 1788 1789 if (is_callable('parse')) { 1790 1791 $GLOBALS['txp_error_message'] = $msg; 1792 $GLOBALS['txp_error_status'] = $status; 1793 $GLOBALS['txp_error_code'] = $code; 1794 1795 set_error_handler("tagErrorHandler"); 1796 die(parse($out)); 1797 } 1798 else { 1799 $out = preg_replace(array('@<txp:error_status[^>]*/>@', '@<txp:error_message[^>]*/>@'), 1800 array($status, $msg), 1801 $out); 1802 die($out); 1803 } 1804 } 1805 1806 // ------------------------------------------------------------- 1807 function join_qs($q) 1808 { 1809 $qs = array(); 1810 foreach ($q as $k=>$v) 1811 if ($v) 1812 $qs[] = urlencode($k) . '=' . urlencode($v); 1813 1814 $str = join('&', $qs); 1815 return ($str ? '?'.$str : ''); 1816 } 1817 1818 // ------------------------------------------------------------- 1819 1820 function pagelinkurl($parts, $inherit = array()) 1821 { 1822 global $permlink_mode, $prefs; 1823 1824 // $inherit can be used to add parameters to an existing url, e.g: 1825 // $url = pagelinkurl(array('pg'=>2), $pretext); 1826 $keys = array_merge($inherit, $parts); 1827 1828 if (isset($prefs['custom_url_func']) 1829 and is_callable($prefs['custom_url_func']) 1830 and ($url = call_user_func($prefs['custom_url_func'], $keys, PAGELINKURL)) !== FALSE) 1831 { 1832 return $url; 1833 } 1834 1835 // can't use this to link to an article 1836 if (isset($keys['id'])) 1837 { 1838 unset($keys['id']); 1839 } 1840 1841 if (@$keys['s'] == 'default') 1842 { 1843 unset($keys['s']); 1844 } 1845 1846 if ($permlink_mode == 'messy') 1847 { 1848 return hu.'index.php'.join_qs($keys); 1849 } 1850 1851 else 1852 { 1853 // all clean URL modes use the same schemes for list pages 1854 $url = ''; 1855 1856 if (!empty($keys['rss'])) 1857 { 1858 $url = hu.'rss/'; 1859 unset($keys['rss']); 1860 return $url.join_qs($keys); 1861 } 1862 1863 elseif (!empty($keys['atom'])) 1864 { 1865 $url = hu.'atom/'; 1866 unset($keys['atom']); 1867 return $url.join_qs($keys); 1868 } 1869 1870 elseif (!empty($keys['s'])) 1871 { 1872 $url = hu.urlencode($keys['s']).'/'; 1873 unset($keys['s']); 1874 return $url.join_qs($keys); 1875 } 1876 1877 elseif (!empty($keys['author'])) 1878 { 1879 $url = hu.strtolower(urlencode(gTxt('author'))).'/'.urlencode($keys['author']).'/'; 1880 unset($keys['author']); 1881 return $url.join_qs($keys); 1882 } 1883 1884 elseif (!empty($keys['c'])) 1885 { 1886 $url = hu.strtolower(urlencode(gTxt('category'))).'/'.urlencode($keys['c']).'/'; 1887 unset($keys['c']); 1888 return $url.join_qs($keys); 1889 } 1890 1891 return hu.join_qs($keys); 1892 } 1893 } 1894 1895 // ------------------------------------------------------------- 1896 function filedownloadurl($id, $filename='') 1897 { 1898 global $permlink_mode; 1899 1900 $filename = urlencode($filename); 1901 #FIXME: work around yet another mod_deflate problem (double compression) 1902 # http://blogs.msdn.com/wndp/archive/2006/08/21/Content-Encoding-not-equal-Content-Type.aspx 1903 if (preg_match('/gz$/i', $filename)) 1904 $filename .= a; 1905 return ($permlink_mode == 'messy') ? 1906 hu.'index.php?s=file_download'.a.'id='.$id : 1907 hu.gTxt('file_download').'/'.$id.($filename ? '/'.$filename : ''); 1908 } 1909 1910 // ------------------------------------------------------------- 1911 1912 function in_list($val, $list, $delim = ',') 1913 { 1914 $args = do_list($list, $delim); 1915 1916 return in_array($val, $args); 1917 } 1918 1919 // ------------------------------------------------------------- 1920 1921 function do_list($list, $delim = ',') 1922 { 1923 return array_map('trim', explode($delim, $list)); 1924 } 1925 1926 // ------------------------------------------------------------- 1927 function doQuote($val) 1928 { 1929 return "'$val'"; 1930 } 1931 1932 // ------------------------------------------------------------- 1933 function quote_list($in) 1934 { 1935 $out = doSlash($in); 1936 return doArray($out, 'doQuote'); 1937 } 1938 1939 // ------------------------------------------------------------- 1940 function trace_add($msg) 1941 { 1942 global $production_status; 1943 1944 if ($production_status === 'debug') 1945 { 1946 global $txptrace,$txptracelevel; 1947 1948 $txptrace[] = str_repeat("\t", $txptracelevel).$msg; 1949 } 1950 } 1951 1952 //------------------------------------------------------------- 1953 function article_push() { 1954 global $thisarticle, $stack_article; 1955 $stack_article[] = @$thisarticle; 1956 } 1957 1958 //------------------------------------------------------------- 1959 function article_pop() { 1960 global $thisarticle, $stack_article; 1961 $thisarticle = array_pop($stack_article); 1962 } 1963 // ------------------------------------------------------------- 1964 1965 function relative_path($path, $pfx=NULL) 1966 { 1967 if ($pfx === NULL) 1968 $pfx = dirname(txpath); 1969 return preg_replace('@^/'.preg_quote(ltrim($pfx, '/'), '@').'/?@', '', $path); 1970 } 1971 1972 // ------------------------------------------------------------- 1973 function get_caller($num=1,$start=2) 1974 { 1975 $out = array(); 1976 if (!is_callable('debug_backtrace')) 1977 return $out; 1978 1979 $bt = debug_backtrace(); 1980 for ($i=$start; $i< $num+$start; $i++) { 1981 if (!empty($bt[$i])) { 1982 $t = ''; 1983 if (!empty($bt[$i]['file'])) 1984 $t .= relative_path($bt[$i]['file']); 1985 if (!empty($bt[$i]['line'])) 1986 $t .= ':'.$bt[$i]['line']; 1987 if ($t) 1988 $t .= ' '; 1989 if (!empty($bt[$i]['class'])) 1990 $t .= $bt[$i]['class']; 1991 if (!empty($bt[$i]['type'])) 1992 $t .= $bt[$i]['type']; 1993 if (!empty($bt[$i]['function'])) { 1994 $t .= $bt[$i]['function']; 1995 1996 $t .= '()'; 1997 } 1998 1999 2000 $out[] = $t; 2001 } 2002 } 2003 return $out; 2004 } 2005 2006 //------------------------------------------------------------- 2007 // function name is misleading but remains for legacy reasons 2008 // this actually sets the locale 2009 function getlocale($lang) { 2010 global $locale; 2011 2012 if (empty($locale)) 2013 $locale = @setlocale(LC_TIME, '0'); 2014 2015 // Locale identifiers vary from system to system. The 2016 // following code will attempt to discover which identifiers 2017 // are available. We'll need to expand these lists to 2018 // improve support. 2019 // ISO identifiers: http://www.w3.org/WAI/ER/IG/ert/iso639.htm 2020 // Windows: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt_language_strings.asp 2021 $guesses = array( 2022 'ar-dz' => array('ar_DZ.UTF-8', 'ar_DZ', 'ara', 'ar', 'arabic', 'ar_DZ.ISO_8859-6'), 2023 'bg-bg' => array('bg_BG.UTF-8', 'bg_BG', 'bg', 'bul', 'bulgarian', 'bg_BG.ISO8859-5'), 2024 'ca-es' => array('ca_ES.UTF-8', 'ca_ES', 'cat', 'ca', 'catalan', 'ca_ES.ISO_8859-1'), 2025 'cs-cz' => array('cs_CZ.UTF-8', 'cs_CZ', 'ces', 'cze', 'cs', 'csy', 'czech', 'cs_CZ.cs_CZ.ISO_8859-2'), 2026 'da-dk' => array('da_DK.UTF-8', 'da_DK'), 2027 'de-de' => array('de_DE.UTF-8', 'de_DE', 'de', 'deu', 'german', 'de_DE.ISO_8859-1'), 2028 'en-gb' => array('en_GB.UTF-8', 'en_GB', 'en_UK', 'eng', 'en', 'english-uk', 'english', 'en_GB.ISO_8859-1','C'), 2029 'en-us' => array('en_US.UTF-8', 'en_US', 'english-us', 'en_US.ISO_8859-1'), 2030 'es-es' => array('es_ES.UTF-8', 'es_ES', 'esp', 'spanish', 'es_ES.ISO_8859-1'), 2031 'et-ee' => array('et_EE.UTF-8', 'et_EE'), 2032 'el-gr' => array('el_GR.UTF-8', 'el_GR', 'el', 'gre', 'greek', 'el_GR.ISO_8859-7'), 2033 'fi-fi' => array('fi_FI.UTF-8', 'fi_FI', 'fin', 'fi', 'finnish', 'fi_FI.ISO_8859-1'), 2034 'fr-fr' => array('fr_FR.UTF-8', 'fr_FR', 'fra', 'fre', 'fr', 'french', 'fr_FR.ISO_8859-1'), 2035 'gl-gz' => array('gl_GZ.UTF-8', 'gl_GZ', 'glg', 'gl', '', ''), 2036 'he_il' => array('he_IL.UTF-8', 'he_IL', 'heb', 'he', 'hebrew', 'he_IL.ISO_8859-8'), 2037 'hr-hr' => array('hr_HR.UTF-8', 'hr_HR', 'hr'), 2038 'hu-hu' => array('hu_HU.UTF-8', 'hu_HU', 'hun', 'hu', 'hungarian', 'hu_HU.ISO8859-2'), 2039 'id-id' => array('id_ID.UTF-8', 'id_ID', 'id', 'ind', 'indonesian','id_ID.ISO_8859-1'), 2040 'is-is' => array('is_IS.UTF-8', 'is_IS'), 2041 'it-it' => array('it_IT.UTF-8', 'it_IT', 'it', 'ita', 'italian', 'it_IT.ISO_8859-1'), 2042 'ja-jp' => array('ja_JP.UTF-8', 'ja_JP', 'ja', 'jpn', 'japanese', 'ja_JP.ISO_8859-1'), 2043 'ko-kr' => array('ko_KR.UTF-8', 'ko_KR', 'ko', 'kor', 'korean'), 2044 'lv-lv' => array('lv_LV.UTF-8', 'lv_LV', 'lv', 'lav'), 2045 'nl-nl' => array('nl_NL.UTF-8', 'nl_NL', 'dut', 'nla', 'nl', 'nld', 'dutch', 'nl_NL.ISO_8859-1'), 2046 'no-no' => array('no_NO.UTF-8', 'no_NO', 'no', 'nor', 'norwegian', 'no_NO.ISO_8859-1'), 2047 'pl-pl' => array('pl_PL.UTF-8', 'pl_PL', 'pl', 'pol', 'polish', ''), 2048 'pt-br' => array('pt_BR.UTF-8', 'pt_BR', 'pt', 'ptb', 'portuguese-brazil', ''), 2049 'pt-pt' => array('pt_PT.UTF-8', 'pt_PT', 'por', 'portuguese', 'pt_PT.ISO_8859-1'), 2050 'ro-ro' => array('ro_RO.UTF-8', 'ro_RO', 'ron', 'rum', 'ro', 'romanian', 'ro_RO.ISO8859-2'), 2051 'ru-ru' => array('ru_RU.UTF-8', 'ru_RU', 'ru', 'rus', 'russian', 'ru_RU.ISO8859-5'), 2052 'sk-sk' => array('sk_SK.UTF-8', 'sk_SK', 'sk', 'slo', 'slk', 'sky', 'slovak', 'sk_SK.ISO_8859-1'), 2053 'sv-se' => array('sv_SE.UTF-8', 'sv_SE', 'sv', 'swe', 'sve', 'swedish', 'sv_SE.ISO_8859-1'), 2054 'th-th' => array('th_TH.UTF-8', 'th_TH', 'th', 'tha', 'thai', 'th_TH.ISO_8859-11'), 2055 'uk-ua' => array('uk_UA.UTF-8', 'uk_UA', 'uk', 'ukr'), 2056 'vi-vn' => array('vi_VN.UTF-8', 'vi_VN', 'vi', 'vie'), 2057 'zh-cn' => array('zh_CN.UTF-8', 'zh_CN'), 2058 'zh-tw' => array('zh_TW.UTF-8', 'zh_TW'), 2059 ); 2060 2061 if (!empty($guesses[$lang])) { 2062 $l = @setlocale(LC_TIME, $guesses[$lang]); 2063 if ($l !== false) 2064 $locale = $l; 2065 } 2066 @setlocale(LC_TIME, $locale); 2067 2068 return $locale; 2069 } 2070 2071 //------------------------------------------------------------- 2072 function assert_article() { 2073 global $thisarticle; 2074 if (empty($thisarticle)) 2075 trigger_error(gTxt('error_article_context')); 2076 } 2077 2078 //------------------------------------------------------------- 2079 function assert_comment() { 2080 global $thiscomment; 2081 if (empty($thiscomment)) 2082 trigger_error(gTxt('error_comment_context')); 2083 } 2084 2085 //------------------------------------------------------------- 2086 function assert_file() { 2087 global $thisfile; 2088 if (empty($thisfile)) 2089 trigger_error(gTxt('error_file_context')); 2090 } 2091 2092 //------------------------------------------------------------- 2093 function assert_link() { 2094 global $thislink; 2095 if (empty($thislink)) 2096 trigger_error(gTxt('error_link_context')); 2097 } 2098 2099 //------------------------------------------------------------- 2100 function assert_section() { 2101 global $thissection; 2102 if (empty($thissection)) 2103 trigger_error(gTxt('error_section_context')); 2104 } 2105 2106 //------------------------------------------------------------- 2107 function assert_category() { 2108 global $thiscategory; 2109 if (empty($thiscategory)) 2110 trigger_error(gTxt('error_category_context')); 2111 } 2112 2113 //------------------------------------------------------------- 2114 function assert_int($myvar) { 2115 global $production_status; 2116 2117 if (is_numeric($myvar) and $myvar == intval($myvar)) { 2118 return (int) $myvar; 2119 } 2120 2121 if (($production_status == 'debug') || (txpinterface == 'admin')) 2122 { 2123 trigger_error("<pre>Error: '".htmlspecialchars($myvar)."' is not an integer</pre>". 2124 n.'<pre style="padding-left: 2em;" class="backtrace"><code>'. 2125 htmlspecialchars(join(n, get_caller(5,1))).'</code></pre>', E_USER_ERROR); 2126 } 2127 else 2128 { 2129 trigger_error("'".htmlspecialchars($myvar)."' is not an integer.", E_USER_ERROR); 2130 } 2131 2132 return false; 2133 } 2134 2135 //------------------------------------------------------------- 2136 function replace_relative_urls($html, $permalink='') { 2137 2138 global $siteurl; 2139 2140 # urls like "/foo/bar" - relative to the domain 2141 if (serverSet('HTTP_HOST')) { 2142 $html = preg_replace('@(<a[^>]+href=")/@','$1'.PROTOCOL.serverSet('HTTP_HOST').'/',$html); 2143 $html = preg_replace('@(<img[^>]+src=")/@','$1'.PROTOCOL.serverSet('HTTP_HOST').'/',$html); 2144 } 2145 # "foo/bar" - relative to the textpattern root 2146 # leave "http:", "mailto:" et al. as absolute urls 2147 $html = preg_replace('@(<a[^>]+href=")(?!\w+:)@','$1'.PROTOCOL.$siteurl.'/$2',$html); 2148 $html = preg_replace('@(<img[^>]+src=")(?!\w+:)@','$1'.PROTOCOL.$siteurl.'/$2',$html); 2149 2150 if ($permalink) 2151 $html = preg_replace("/href=\\\"#(.*)\"/","href=\"".$permalink."#\\1\"",$html); 2152 return ($html); 2153 } 2154 2155 //------------------------------------------------------------- 2156 function show_clean_test($pretext) { 2157 echo md5(@$pretext['req']).n; 2158 if (serverSet('SERVER_ADDR') == serverSet('REMOTE_ADDR')) 2159 { 2160 var_export($pretext); 2161 } 2162 } 2163 2164 //------------------------------------------------------------- 2165 2166 function pager($total, $limit, $page) { 2167 $total = (int) $total; 2168 $limit = (int) $limit; 2169 $page = (int) $page; 2170 2171 $num_pages = ceil($total / $limit); 2172 2173 $page = min(max($page, 1), $num_pages); 2174 2175 $offset = max(($page - 1) * $limit, 0); 2176 2177 return array($page, $offset, $num_pages); 2178 } 2179 2180 //------------------------------------------------------------- 2181 // word-wrap a string using a zero width space 2182 function soft_wrap($text, $width, $break='​') 2183 { 2184 $wbr = chr(226).chr(128).chr(139); 2185 $words = explode(' ', $text); 2186 foreach($words as $wordnr => $word) { 2187 $word = preg_replace('|([,./\\>?!:;@-]+)(?=.)|', '$1 ', $word); 2188 $parts = explode(' ', $word); 2189 foreach($parts as $partnr => $part) { 2190 $len = strlen(utf8_decode($part)); 2191 if (!$len) continue; 2192 $parts[$partnr] = preg_replace('/(.{'.ceil($len/ceil($len/$width)).'})(?=.)/u', '$1'.$wbr, $part); 2193 } 2194 $words[$wordnr] = join($wbr, $parts); 2195 } 2196 return join(' ', $words); 2197 } 2198 2199 //------------------------------------------------------------- 2200 function strip_prefix($str, $pfx) { 2201 return preg_replace('/^'.preg_quote($pfx, '/').'/', '', $str); 2202 } 2203 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu May 21 23:03:01 2009 | Cross-referenced by PHPXref 0.7 |