CMS Made Simple PHP Cross Reference Content Management Systems

Source: /lib/misc.functions.php - 2313 lines - 60915 bytes - Summary - Text - Print

Description: Misc functions

   1  <?php
   2  #CMS - CMS Made Simple
   3  #(c)2004-2012 by Ted Kulp (wishy@users.sf.net)
   4  #This project's homepage is: http://www.cmsmadesimple.org
   5  #
   6  #This program is free software; you can redistribute it and/or modify
   7  #it under the terms of the GNU General Public License as published by
   8  #the Free Software Foundation; either version 2 of the License, or
   9  #(at your option) any later version.
  10  #
  11  #This program is distributed in the hope that it will be useful,
  12  #but WITHOUT ANY WARRANTY; without even the implied warranty of
  13  #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14  #GNU General Public License for more details.
  15  #You should have received a copy of the GNU General Public License
  16  #along with this program; if not, write to the Free Software
  17  #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18  #
  19  #$Id: misc.functions.php 9235 2014-01-27 15:25:37Z uniqu3 $
  20  
  21  /**
  22   * Misc functions
  23   *
  24   * @package CMS
  25   */
  26  
  27  
  28   
  29  /**
  30   * Redirects to relative URL on the current site
  31   *
  32   * @author http://www.edoceo.com/
  33   * @since 0.1
  34   * @param string The url to redirect to
  35   * @return void
  36   */
  37  function redirect($to, $noappend=false)
  38  {
  39    $_SERVER['PHP_SELF'] = null;
  40  
  41    $schema = 'http';
  42    if( isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off' ) $schema = 'https';
  43  
  44    $host = strlen($_SERVER['HTTP_HOST'])?$_SERVER['HTTP_HOST']:$_SERVER['SERVER_NAME'];
  45  
  46      $components = parse_url($to);
  47      if(count($components) > 0)
  48      {
  49          $to =  (isset($components['scheme']) && startswith($components['scheme'], 'http') ? $components['scheme'] : $schema) . '://';
  50          $to .= isset($components['host']) ? $components['host'] : $host;
  51          $to .= isset($components['port']) ? ':' . $components['port'] : '';
  52          if(isset($components['path']))
  53          {
  54              if(in_array(substr($components['path'],0,1),array('\\','/')))//Path is absolute, just append.
  55              {
  56                  $to .= $components['path'];
  57              }
  58              //Path is relative, append current directory first.
  59              else if (isset($_SERVER['PHP_SELF']) && !is_null($_SERVER['PHP_SELF'])) //Apache
  60              {
  61                  $to .= (strlen(dirname($_SERVER['PHP_SELF'])) > 1 ?  dirname($_SERVER['PHP_SELF']).'/' : '/') . $components['path'];
  62              }
  63              else if (isset($_SERVER['REQUEST_URI']) && !is_null($_SERVER['REQUEST_URI'])) //Lighttpd
  64              {
  65                  if (endswith($_SERVER['REQUEST_URI'], '/'))
  66                      $to .= (strlen($_SERVER['REQUEST_URI']) > 1 ? $_SERVER['REQUEST_URI'] : '/') . $components['path'];
  67                  else
  68                      $to .= (strlen(dirname($_SERVER['REQUEST_URI'])) > 1 ? dirname($_SERVER['REQUEST_URI']).'/' : '/') . $components['path'];
  69              }
  70          }
  71          $to .= isset($components['query']) ? '?' . $components['query'] : '';
  72          $to .= isset($components['fragment']) ? '#' . $components['fragment'] : '';
  73      }
  74      else
  75      {
  76          $to = $schema."://".$host."/".$to;
  77      }
  78  
  79      session_write_close();
  80  
  81      $debug = false;
  82      if( class_exists('CmsApp') )
  83        {
  84      $config = cmsms()->GetConfig();
  85      $debug = $config['debug'];
  86        }
  87  
  88      if (headers_sent() && !$debug)
  89      {
  90          // use javascript instead
  91          echo '<script type="text/javascript">
  92              <!--
  93                  location.replace("'.$to.'");
  94              // -->
  95              </script>
  96              <noscript>
  97                  <meta http-equiv="Refresh" content="0;URL='.$to.'">
  98              </noscript>';
  99          exit;
 100  
 101      }
 102      else
 103      {
 104          if ( $debug )
 105          {
 106              echo "Debug is on.  Redirecting disabled...  Please click this link to continue.<br />";
 107              echo "<a href=\"".$to."\">".$to."</a><br />";
 108              echo '<div id="DebugFooter">';
 109              global $sql_queries;
 110              if (FALSE == empty($sql_queries))
 111                {
 112                  echo "<div>".$sql_queries."</div>\n";
 113                }
 114              foreach (cmsms()->get_errors() as $error)
 115              {
 116                  echo $error;
 117              }
 118              echo '</div> <!-- end DebugFooter -->';
 119              exit();
 120          }
 121          else
 122          {
 123              header("Location: $to");
 124              exit();
 125          }
 126      }
 127  }
 128  
 129  
 130  
 131  /**
 132   * Given a page ID or an alias, redirect to it
 133   * Retrieves the URL of the specified page, and performs a redirect
 134   *
 135   * @param mixed An integer page id or a string page alias.
 136   * @return void
 137   */
 138  function redirect_to_alias($alias)
 139  {
 140    $manager = cmsms()->GetHierarchyManager();
 141    $node = $manager->sureGetNodeByAlias($alias);
 142    if( !$node ) {
 143      // put mention into the admin log
 144      audit('','Core','Attempt to redirect to invalid alias: '.$alias);
 145      return;
 146    }
 147    $content = $node->GetContent();
 148    if (!is_object($content)) {
 149      audit('','Core','Attempt to redirect to invalid alias: '.$alias);
 150      return;
 151    }
 152    if ($content->GetURL() != '') {
 153      redirect($content->GetURL());
 154    }
 155  }
 156  
 157  
 158  
 159  /**
 160   * Calculate the difference in seconds between two microtime() values
 161   *
 162   * @since 0.3
 163   * @param string Microtime value A
 164   * @param string Microtime value B
 165   * @return integer The difference.
 166   */
 167  function microtime_diff($a, $b) {
 168      list($a_dec, $a_sec) = explode(" ", $a);
 169      list($b_dec, $b_sec) = explode(" ", $b);
 170      return $b_sec - $a_sec + $b_dec - $a_dec;
 171  }
 172  
 173  
 174  
 175  /**
 176   * Joins a path together using proper directory separators
 177   * Taken from: http://www.php.net/manual/en/ref.dir.php
 178   *
 179   * This method accepts a variable number of string arguments.
 180   *
 181   * @since 0.14
 182   * @return string
 183   */
 184  function cms_join_path()
 185  {
 186      $args = func_get_args();
 187          return implode(DIRECTORY_SEPARATOR,$args);
 188  }
 189  
 190  
 191  
 192  /**
 193   * Return the global cmsms() object
 194   *
 195   * @since 1.7
 196   * @return object
 197   */
 198  function &cmsms()
 199  {
 200     return CmsApp::get_instance();
 201  }
 202  
 203  
 204  
 205  /**
 206   * Shows a very close approximation of an Apache generated 404 error.
 207   *
 208   * Shows a very close approximation of an Apache generated 404 error.
 209   * It also sends the actual header along as well, so that generic
 210   * browser error pages (like what IE does) will be displayed.
 211   *
 212   * @since 0.3
 213   * @deprecated
 214   * @internal
 215   * Rolf: function used in /index.php
 216   */
 217  function ErrorHandler404()
 218  {
 219          @ob_end_clean();
 220          header("HTTP/1.0 404 Not Found");
 221          header("Status: 404 Not Found");
 222          echo '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
 223  <html><head>
 224  <title>404 Not Found</title>
 225  </head><body>
 226  <h1>Not Found</h1>
 227  <p>The requested URL was not found on this server.</p>
 228  </body></html>';
 229          exit();
 230  }
 231  
 232  
 233  
 234  /**
 235   * A method to perform HTML entity conversion on a string
 236   *
 237   * @see htmlentities
 238   * @param string The input string
 239   * @param string A flag indicating how quotes should be handled (see htmlentities) (ignored)
 240   * @param string The input character set (ignored)
 241   * @param boolean A flag indicating wether single quotes should be converted to entities.
 242   * @return string the converted string.
 243   */
 244  function cms_htmlentities($val, $param=ENT_QUOTES, $charset="UTF-8", $convert_single_quotes = false)
 245  {
 246    if ($val == "") return "";
 247  
 248    $val = str_replace( "&#032;", " ", $val );
 249    $val = str_replace( "&"            , "&amp;"         , $val );
 250    $val = str_replace( "<!--"         , "&#60;&#33;--"  , $val );
 251    $val = str_replace( "-->"          , "--&#62;"       , $val );
 252    $val = preg_replace( "/<script/i"  , "&#60;script"   , $val );
 253    $val = str_replace( ">"            , "&gt;"          , $val );
 254    $val = str_replace( "<"            , "&lt;"          , $val );
 255    $val = str_replace( "\""           , "&quot;"        , $val );
 256    $val = preg_replace( "/\\$/"      , "&#036;"        , $val );
 257    $val = str_replace( "!"            , "&#33;"         , $val );
 258    $val = str_replace( "'"            , "&#39;"         , $val );
 259  
 260    if ($convert_single_quotes)
 261      {
 262        $val = str_replace("\\'", "&apos;", $val);
 263        $val = str_replace("'", "&apos;", $val);
 264      }
 265  
 266    return $val;
 267  }
 268  
 269  
 270  
 271  /**
 272   * @ignore
 273   */
 274  define('CLEANED_FILENAME','BAD_FILE');
 275  
 276  
 277  
 278  /**
 279   * Clean up the filename, and ensure that the filename resides underneath
 280   * the cms_root directory, if it does not replace it with the hardcoded
 281   * string CLEANED_FILENAME
 282   *
 283   * @internal
 284   * @param string The complete file specification
 285   * @return string the cleaned file path.
 286   * Rolf: only used in this file
 287   */
 288  function cms_cleanfile($filename)
 289  {
 290      $realpath = realpath($filename);
 291      if( $realpath === FALSE ) {
 292          return CLEANED_FILENAME;
 293      }
 294  
 295      // This ensures that the file specified is somewhere
 296      // underneath the cms root path
 297      $config = cmsms()->GetConfig();
 298      if( strpos($realpath, $config['root_path']) !== 0 ) {
 299          return CLEANED_FILENAME;
 300      }
 301      return $realpath;
 302  }
 303  
 304  
 305  
 306  
 307  /**
 308   * A replacement for the built in htmlentities method.
 309   *
 310   * @ignore
 311   * @deprecated
 312   * @param string  input string
 313   * @param boolean A flag wether or not to handle single quotes.
 314   * @return string
 315   */
 316  function my_htmlentities($val, $convert_single_quotes = false)
 317  {
 318    return cms_htmlentities($val,ENT_QUOTES,'UTF-8',$convert_single_quotes);
 319  }
 320  
 321  
 322  
 323  /**
 324   * A method to convert a string into UTF-8 entities
 325   *
 326   * @internal
 327   * @deprecated
 328   * @param string Input string
 329   * @return string
 330   * Rolf: used in admin/listmodules.php
 331   */
 332  function cms_utf8entities($val)
 333  {
 334      if ($val == "")
 335      {
 336          return "";
 337      }
 338      $val = str_replace( "&#032;", " ", $val );
 339      $val = str_replace( "&"            , "\u0026"         , $val );
 340      $val = str_replace( ">"            , "\u003E"          , $val );
 341      $val = str_replace( "<"            , "\u003C"          , $val );
 342  
 343  
 344      $val = str_replace( "\""           , "\u0022"        , $val );
 345      $val = str_replace( "!"            , "\u0021"         , $val );
 346      $val = str_replace( "'"            , "\u0027"         , $val );
 347  
 348      return $val;
 349  }
 350  
 351  
 352  
 353  /**
 354   * A function to put a backtrace into the generated log file.
 355   * 
 356   * @see debug_to_log, debug_bt
 357   * @return void
 358   * Rolf: Looks like not used
 359   */
 360  function debug_bt_to_log()
 361  {
 362    if( cmsms()->config['debug_to_log'] || check_login(TRUE) ) {
 363        $bt=debug_backtrace();
 364        $file = $bt[0]['file'];
 365        $line = $bt[0]['line'];
 366  
 367        $out = array();
 368        $out[] = "Backtrace in $file on line $line";
 369  
 370        $bt = array_reverse($bt);
 371        foreach($bt as $trace) {
 372      if( $trace['function'] == 'debug_bt_to_log' ) continue;
 373  
 374      $file = $line = '';
 375      if( isset($trace['file']) ) $file = $trace['file'];
 376      if( isset($trace['line']) ) $line = $trace['line'];
 377      $function = $trace['function'];
 378      $out[] = "$function at $file:$line"; 
 379        }
 380  
 381        $filename = TMP_CACHE_LOCATION . '/debug.log';
 382        foreach ($out as $txt) {
 383      error_log($txt . "\n", 3, $filename);
 384        }
 385      }
 386  }
 387  
 388  
 389  
 390  /**
 391   * A function to generate a backtrace in a readable format.
 392   *
 393   * @return void
 394   * Rolf: looks like not used
 395   */
 396  function debug_bt()
 397  {
 398      $bt=debug_backtrace();
 399      $file = $bt[0]['file'];
 400      $line = $bt[0]['line'];
 401  
 402      echo "\n\n<p><b>Backtrace in $file on line $line</b></p>\n";
 403  
 404      $bt = array_reverse($bt);
 405      echo "<pre><dl>\n";
 406      foreach($bt as $trace)
 407      {
 408          $file = $trace['file'];
 409          $line = $trace['line'];
 410          $function = $trace['function'];
 411          $args = implode(',', $trace['args']);
 412          echo "
 413          <dt><b>$function</b>($args) </dt>
 414          <dd>$file on line $line</dd>
 415          ";
 416      }
 417      echo "</dl></pre>\n";
 418  }
 419  
 420  
 421  
 422  /**
 423  * Debug function to display $var nicely in html.
 424  *
 425  * @param mixed $var
 426  * @param string $title (optional)
 427  * @param boolean $echo_to_screen (optional)
 428  * @return string
 429  */
 430  function debug_display($var, $title="", $echo_to_screen = true, $use_html = true)
 431  {
 432      $variables =& cmsms()->variables;
 433  
 434      $starttime = microtime();
 435      if (isset($variables['starttime']))
 436          $starttime = $variables['starttime'];
 437      else
 438          $variables['starttime'] = $starttime;
 439  
 440      $titleText = "Debug: ";
 441      if($title)
 442      {
 443          $titleText = "Debug display of '$title':";
 444      }
 445      $titleText .= '(' . microtime_diff($starttime,microtime()) . ')';
 446  
 447      if (function_exists('memory_get_usage'))
 448      {
 449        $titleText .= ' - (usage: '.memory_get_usage().')';
 450      }
 451  
 452      $memory_peak = (function_exists('memory_get_peak_usage')?memory_get_peak_usage():'');
 453      if( $memory_peak )
 454        {
 455          $titleText .= ' - (peak: '.$memory_peak.')';
 456        }
 457  
 458      ob_start();
 459      if ($use_html)
 460        {
 461          echo "<div><b>$titleText</b>\n";
 462        }
 463      else
 464        {
 465          echo "$titleText\n";
 466        }
 467  
 468      if(FALSE == empty($var))
 469      {
 470          if ($use_html)
 471          {
 472              echo '<pre>';
 473          }
 474          if(is_array($var))
 475          {
 476              echo "Number of elements: " . count($var) . "\n";
 477              print_r($var);
 478          }
 479          elseif(is_object($var))
 480          {
 481              print_r($var);
 482          }
 483          elseif(is_string($var))
 484          {
 485            if( $use_html )
 486              {
 487              print_r(htmlentities(str_replace("\t", '  ', $var)));
 488              }
 489            else
 490              {
 491                 print_r($var);
 492              }
 493          }
 494          elseif(is_bool($var))
 495          {
 496              echo $var === true ? 'true' : 'false';
 497          }
 498          else
 499          {
 500              print_r($var);
 501          }
 502          if ($use_html)
 503          {
 504              echo '</pre>';
 505          }
 506      }
 507      if ($use_html)
 508          echo "</div>\n";
 509  
 510      $output = ob_get_contents();
 511      ob_end_clean();
 512  
 513      if($echo_to_screen)
 514      {
 515        echo $output;
 516      }
 517  
 518      return $output;
 519  }
 520  
 521  
 522  
 523  /**
 524   * Display $var nicely only if $config["debug"] is set
 525   *
 526   * @param mixed $var
 527   * @param string $title
 528   */
 529  function debug_output($var, $title="")
 530  {
 531    if(cmsms()->config["debug"] == true)
 532      {
 533          debug_display($var, $title, true);
 534      }
 535  
 536  }
 537  
 538  
 539  
 540  /**
 541   * Debug function to output debug information about a variable in a formatted matter
 542   * to a debug file.
 543   *
 544   * @param mixed data to display
 545   * @param string Optional title.
 546   */
 547  function debug_to_log($var, $title='',$filename = '')
 548  {
 549    if( cmsms()->config['debug_to_log'] || check_login(TRUE) ) {
 550      if( $filename == '' ) {
 551        $filename = TMP_CACHE_LOCATION . '/debug.log';
 552        $x = @filemtime($filename);
 553        if( $x !== FALSE && $x < (time() - 24 * 3600) ) @unlink($filename);
 554      }
 555      $errlines = explode("\n",debug_display($var, $title, false, false));
 556      foreach ($errlines as $txt) {
 557        error_log($txt . "\n", 3, $filename);
 558      }
 559    }
 560  }
 561  
 562  
 563  
 564  /**
 565   * Display $var nicely to the cmsms()->errors array if $config['debug'] is set
 566   *
 567   * @param mixed $var
 568   * @param string $title
 569   */
 570  function debug_buffer($var, $title="")
 571  {
 572    $config = cmsms()->GetConfig();
 573    if($config["debug"] == true)
 574      {
 575        cmsms()->add_error(debug_display($var, $title, false, true));
 576      }
 577  }
 578  
 579  
 580  
 581  /**
 582   * Debug an sql command
 583   *
 584   * @internal
 585   * @param string SQL query
 586   * @param boolean (unused)
 587   * Rolf: only used in lib/adodb.functions.php
 588   */
 589  function debug_sql($str, $newline = false)
 590  {
 591    $config = cmsms()->GetConfig();
 592    if($config["debug"] == true)
 593      {
 594        cmsms()->add_error(debug_display($str, '', false, true));
 595      }
 596  }
 597  
 598  
 599  
 600  /**
 601  * Retrieve value from $_REQUEST. Returns $default_value if
 602  *        value is not in $_REQUEST or is not the same basic type as
 603  *        $default_value.
 604  *        If $session_key is set, then will return session value in preference
 605  *        to $default_value if $_REQUEST[$value] is not set.
 606  *
 607  * @param string $value
 608  * @param mixed $default_value (optional)
 609  * @param string $session_key (optional)
 610  * @deprecated
 611  * @return mixed
 612  * Rolf: looks like not used
 613  */
 614  function get_request_value($value, $default_value = '', $session_key = '')
 615  {
 616      if($session_key != '')
 617      {
 618          if(isset($_SESSION['request_values'][$session_key][$value]))
 619          {
 620              $default_value = $_SESSION['request_values'][$session_key][$value];
 621          }
 622      }
 623      if(isset($_REQUEST[$value]))
 624      {
 625          $result = get_value_with_default($_REQUEST[$value], $default_value);
 626      }
 627      else
 628      {
 629          $result = $default_value;
 630      }
 631  
 632      if($session_key != '')
 633      {
 634          $_SESSION['request_values'][$session_key][$value] = $result;
 635      }
 636  
 637      return $result;
 638  }
 639  
 640  
 641  
 642  /**
 643  * Return $value if it's set and same basic type as $default_value,
 644  *            otherwise return $default_value. Note. Also will trim($value)
 645  *            if $value is not numeric.
 646  *
 647  * @param string $value
 648  * @param mixed $default_value
 649  * @deprecated
 650  * @return mixed
 651  * Rolf: only used in this file
 652  */
 653  function get_value_with_default($value, $default_value = '', $session_key = '')
 654  {
 655      if($session_key != '')
 656      {
 657          if(isset($_SESSION['default_values'][$session_key]))
 658          {
 659              $default_value = $_SESSION['default_values'][$session_key];
 660          }
 661      }
 662  
 663      // set our return value to the default initially and overwrite with $value if we like it.
 664      $return_value = $default_value;
 665  
 666      if(isset($value))
 667      {
 668          if(is_array($value))
 669          {
 670              // $value is an array - validate each element.
 671              $return_value = array();
 672              foreach($value as $element)
 673              {
 674                  $return_value[] = get_value_with_default($element, $default_value);
 675              }
 676          }
 677          else
 678          {
 679              if(is_numeric($default_value))
 680              {
 681                  if(is_numeric($value))
 682                  {
 683                      $return_value = $value;
 684                  }
 685              }
 686              else
 687              {
 688                  $return_value = trim($value);
 689              }
 690          }
 691      }
 692  
 693      if($session_key != '')
 694      {
 695          $_SESSION['default_values'][$session_key] = $return_value;
 696      }
 697  
 698      return $return_value;
 699  }
 700  
 701  
 702  
 703  /**
 704   * Retrieve the $value from the $parameters array checking for
 705   * $parameters[$value] and $params[$id.$value]. Returns $default
 706   * if $value is not in $params array.
 707   * Note: This function will also trim() string values.
 708   *
 709   * @param array $parameters
 710   * @param string $value
 711   * @param mixed $default_value
 712   * @param string $session_key
 713   * @return mixed
 714   * Rolf: looks like not used
 715   */
 716  function get_parameter_value($parameters, $value, $default_value = '', $session_key = '')
 717  {
 718      if($session_key != '')
 719      {
 720          if(isset($_SESSION['parameter_values'][$session_key]))
 721          {
 722              $default_value = $_SESSION['parameter_values'][$session_key];
 723          }
 724      }
 725  
 726      // set our return value to the default initially and overwrite with $value if we like it.
 727      $return_value = $default_value;
 728      if(isset($parameters[$value]))
 729      {
 730          if(is_bool($default_value))
 731          {
 732              // want a boolean return_value
 733              if(isset($parameters[$value]))
 734              {
 735                  $return_value = (boolean)$parameters[$value];
 736              }
 737          }
 738          else
 739          {
 740              // is $default_value a number?
 741              $is_number = false;
 742              if(is_numeric($default_value))
 743              {
 744                  $is_number = true;
 745              }
 746  
 747              if(is_array($parameters[$value]))
 748              {
 749                  // $parameters[$value] is an array - validate each element.
 750                  $return_value = array();
 751                  foreach($parameters[$value] as $element)
 752                  {
 753                      $return_value[] = get_value_with_default($element, $default_value);
 754                  }
 755              }
 756              else
 757              {
 758                  if(is_numeric($default_value))
 759                  {
 760                      // default value is a number, we only like $parameters[$value] if it's a number too.
 761                      if(is_numeric($parameters[$value]))
 762                      {
 763                          $return_value = $parameters[$value];
 764                      }
 765                  }
 766                  elseif(is_string($default_value))
 767                  {
 768                      $return_value = trim($parameters[$value]);
 769                  }
 770                  else
 771                  {
 772                      $return_value = $parameters[$value];
 773                  }
 774              }
 775          }
 776      }
 777  
 778      if($session_key != '')
 779      {
 780          $_SESSION['parameter_values'][$session_key] = $return_value;
 781      }
 782  
 783      return $return_value;
 784  }
 785  
 786  
 787  
 788  /**
 789   * A convenience function to create a dropdown control with supported encodings.
 790   *
 791   * @internal
 792   * @param string A name for the control
 793   * @param string The name of the option that should be selected.
 794   * @return string
 795   * Rolf: only used in admin/edittemplate.php
 796   */
 797  function create_encoding_dropdown($name = 'encoding', $selected = '')
 798  {
 799      $result = '';
 800  
 801      $encodings = array(''=>'Default','UTF-8'=>'Unicode','ISO-8859-1'=>'Latin 1/West European','ISO-8859-2'=>'Latin 2/Central European','ISO-8859-3'=>'Latin 3/South European','ISO-8859-4'=>'Latin 4/North European','ISO-8859-5'=>'Cyrilic','ISO-8859-6'=>'Arabic','ISO-8859-7'=>'Greek','ISO-8859-8'=>'Hebrew','ISO-8859-9'=>'Latin 5/Turkish','ISO-8859-11'=>'TIS-620/Thai','ISO-8859-14'=>'Latin 8','ISO-8859-15'=>'Latin 9','Big5'=>'Taiwanese','GB2312'=>'Chinese','EUC-JP'=>'Japanese','EUC-KR'=>'Korean','KOI8-R'=>'Russian','Windows-1250'=>'Central Europe','Windows-1251'=>'Cyrilic','Windows-1252'=>'Latin 1','Windows-1253'=>'Greek','Windows-1254'=>'Turkish','Windows-1255'=>'Hebrew','Windows-1256'=>'Arabic','Windows-1257'=>'Baltic','Windows-1258'=>'Vietnam');
 802  
 803      $result .= '<select name="'.$name.'">';
 804      foreach ($encodings as $key=>$value)
 805      {
 806          $result .= '<option value="'.$key.'"';
 807          if ($selected == $key)
 808          {
 809              $result .= ' selected="selected"';
 810          }
 811          $result .= '>'.$key.($key!=''?' - ':'').$value.'</option>';
 812      }
 813      $result .= '</select>';
 814  
 815      return $result;
 816  }
 817  
 818  
 819  
 820  /**
 821   * A method to remove a permission from the database.
 822   *
 823   * @internal
 824   * @access private
 825   * @param string The permission name
 826   */
 827  function cms_mapi_remove_permission($permission_name)
 828  {
 829    $db = cmsms()->GetDB();
 830  
 831    $query = "SELECT permission_id FROM ".cms_db_prefix()."permissions WHERE permission_name = ?";
 832    $row = &$db->GetRow($query, array($permission_name));
 833  
 834    if ($row)
 835      {
 836        $id = $row["permission_id"];
 837  
 838        $query = "DELETE FROM ".cms_db_prefix()."group_perms WHERE permission_id = ?";
 839        $db->Execute($query, array($id));
 840  
 841        $query = "DELETE FROM ".cms_db_prefix()."permissions WHERE permission_id = ?";
 842        $db->Execute($query, array($id));
 843      }
 844  }
 845  
 846  
 847  
 848  /**
 849   * A method to add a permission to the CMSMS permissions table
 850   *
 851   * @internal
 852   * @access private
 853   * @param unknown (ignored)
 854   * @param string  The permission name
 855   * @param string  The permission human readable text.
 856   */
 857  function cms_mapi_create_permission($cms, $permission_name, $permission_text)
 858  {
 859    $db = cmsms()->GetDb();
 860  
 861      $query = "SELECT permission_id FROM ".cms_db_prefix()."permissions WHERE permission_name =" . $db->qstr($permission_name);
 862      $result = $db->Execute($query);
 863  
 864      if ($result && $result->RecordCount() < 1) {
 865  
 866          $new_id = $db->GenID(cms_db_prefix()."permissions_seq");
 867          $query = "INSERT INTO ".cms_db_prefix()."permissions (permission_id, permission_name, permission_text, create_date, modified_date) VALUES ($new_id, ".$db->qstr($permission_name).",".$db->qstr($permission_text).",".$db->DBTimeStamp(time()).",".$db->DBTimeStamp(time()).")";
 868          $db->Execute($query);
 869      }
 870  
 871      if ($result)
 872      {
 873          $result->Close();
 874          return true;
 875      }
 876      return false;
 877  }
 878  
 879  
 880  
 881  /**
 882   * A function to test if a file specification matches an array of
 883   * file specifications that indicate it should be excluded
 884   *
 885   * @internal
 886   * @deprecated
 887   * @access private
 888   * @param string Flle specification
 889   * @param array  Array of regular expressions.
 890   * @return boolean
 891   * Rolf: only used in this file
 892   */
 893  function filespec_is_excluded( $file, $excludes )
 894  {
 895    // strip the path from the file
 896    if( empty($excludes) ) return false;
 897    foreach( $excludes as $excl )
 898      {
 899        if( @preg_match( "/".$excl."/i", basename($file) ) )
 900      {
 901        return true;
 902      }
 903      }
 904    return false;
 905  }
 906  
 907  
 908  
 909  /**
 910   * Check the permissions of a directory recursively to make sure that
 911   * we have write permission to all files
 912   *
 913   * @param  string  Start directory.
 914   * @return boolean
 915   */
 916  function is_directory_writable( $path )
 917  {
 918    if ( substr ( $path , strlen ( $path ) - 1 ) != '/' )
 919      {
 920        $path .= '/' ;
 921      }
 922  
 923    $result = true;
 924    if( $handle = @opendir( $path ) )
 925      {
 926        while( false !== ( $file = readdir( $handle ) ) )
 927      {
 928        if( $file == '.' || $file == '..' )
 929          {
 930            continue;
 931          }
 932  
 933        $p = $path.$file;
 934  
 935        if( !@is_writable( $p ) )
 936          {
 937            return false;
 938          }
 939  
 940        if( @is_dir( $p ) )
 941          {
 942            $result = is_directory_writable( $p );
 943            if( !$result )
 944          {
 945            return false;
 946          }
 947          }
 948      }
 949        @closedir( $handle );
 950      }
 951    else
 952      {
 953        return false;
 954      }
 955  
 956    return true;
 957  }
 958  
 959  
 960  
 961  /**
 962   * Return an array containing a list of files in a directory
 963   * performs a non recursive search
 964   *
 965   * @internal
 966   * @param path - path to search
 967   * @param extensions - include only files matching these extensions
 968   *                     case insensitive, comma delimited
 969   * Rolf: only used in this file
 970   */
 971  function get_matching_files($dir,$extensions = '',$excludedot = true,$excludedir = true, $fileprefix='',$excludefiles=1)
 972  {
 973    $dh = @opendir($dir);
 974    if( !$dh ) return false;
 975  
 976    if( !empty($extensions) )
 977      {
 978        $extensions = explode(',',strtolower($extensions));
 979      }
 980    $results = array();
 981    while( false !== ($file = readdir($dh)) )
 982      {
 983        if( $file == '.' || $file == '..' ) continue;
 984        if( startswith($file,'.') && $excludedot ) continue;
 985        if( is_dir(cms_join_path($dir,$file)) && $excludedir ) continue;
 986        if( !empty($fileprefix) )
 987      {
 988        if( $excludefiles == 1 && startswith($file,$fileprefix) ) continue;
 989        if( $excludefiles == 0 && !startswith($file,$fileprefix) ) continue;
 990      }
 991  
 992        $ext = strtolower(substr($file,strrpos($file,'.')+1));
 993        if( is_array($extensions) && count($extensions) && !in_array($ext,$extensions) ) continue;
 994  
 995        $results[] = $file;
 996      }
 997    closedir($dh);
 998    if( !count($results) ) return false;
 999    return $results;
1000  }
1001  
1002  
1003  
1004  /**
1005   * Return an array containing a list of files in a directory
1006   * performs a recursive search
1007   *
1008   * @internal
1009   * @param  string    Start Path.
1010   * @param  array     Array of regular expressions indicating files to exclude.
1011   * @param  int       How deep to browse (-1=unlimited)
1012   * @param  string    "FULL"|"DIRS"|"FILES"
1013   * @param  d         for internal use only
1014   * @return  array
1015  **/
1016  function get_recursive_file_list ( $path , $excludes, $maxdepth = -1 , $mode = "FULL" , $d = 0 )
1017  {
1018     if ( substr ( $path , strlen ( $path ) - 1 ) != '/' ) { $path .= '/' ; }
1019     $dirlist = array () ;
1020     if ( $mode != "FILES" ) { $dirlist[] = $path ; }
1021     if ( $handle = opendir ( $path ) )
1022     {
1023         while ( false !== ( $file = readdir ( $handle ) ) )
1024         {
1025       if( $file == '.' || $file == '..' ) continue;
1026       if( filespec_is_excluded( $file, $excludes ) ) continue;
1027  
1028       $file = $path . $file ;
1029       if ( ! @is_dir ( $file ) ) { if ( $mode != "DIRS" ) { $dirlist[] = $file ; } }
1030       elseif ( $d >=0 && ($d < $maxdepth || $maxdepth < 0) )
1031         {
1032           $result = get_recursive_file_list ( $file . '/' , $excludes, $maxdepth , $mode , $d + 1 ) ;
1033           $dirlist = array_merge ( $dirlist , $result ) ;
1034         }
1035         }
1036         closedir ( $handle ) ;
1037     }
1038     if ( $d == 0 ) { natcasesort ( $dirlist ) ; }
1039     return ( $dirlist ) ;
1040  }
1041  
1042  
1043  
1044  /**
1045   * A function to recursively delete all files and folders in a directory
1046   * synonymous with rm -r
1047   *
1048   * @param string The directory name
1049   * @return boolean
1050   */
1051  function recursive_delete( $dirname )
1052  {
1053    // all subdirectories and contents:
1054    if(is_dir($dirname))$dir_handle=opendir($dirname);
1055    while($file=readdir($dir_handle))
1056    {
1057      if($file!="." && $file!="..")
1058      {
1059        if(!is_dir($dirname."/".$file))
1060      {
1061        if( !@unlink ($dirname."/".$file) )
1062          {
1063            closedir( $dir_handle );
1064            return false;
1065          }
1066      }
1067        else
1068      {
1069        recursive_delete($dirname."/".$file);
1070      }
1071      }
1072    }
1073    closedir($dir_handle);
1074    if( ! @rmdir($dirname) )
1075      {
1076        return false;
1077      }
1078    return true;
1079  }
1080  
1081  
1082  
1083  /**
1084   * A function to recursively chmod all files and folders in a directory
1085   *
1086   * @see chmod
1087   * @param string The start location
1088   * @param integer The mode
1089   * Rolf: only used in admin/listmodules.php
1090   */
1091  function chmod_r( $path, $mode )
1092  {
1093    if( !is_dir( $path ) )
1094      return chmod( $path, $mode );
1095  
1096    $dh = @opendir( $path );
1097    if( !$dh ) return FALSE;
1098  
1099    while( $file = readdir( $dh ) )
1100    {
1101      if( $file == '.' || $file == '..' ) continue;
1102  
1103      $p = $path.DIRECTORY_SEPARATOR.$file;
1104      if( is_dir( $p ) )
1105      {
1106        if( !@chmod_r( $p, $mode ) )
1107      {
1108        closedir( $dh );
1109        return false;
1110      }
1111      }
1112      else if( !is_link( $p ) )
1113      {
1114        if( !@chmod( $p, $mode ) )
1115      {
1116        closedir( $dh );
1117        return false;
1118      }
1119      }
1120    }
1121    @closedir( $dh );
1122    return @chmod( $path, $mode );
1123  }
1124  
1125  
1126  
1127  /**
1128   * A method to serialize an object and encode it for storage or transport.
1129   *
1130   * @internal
1131   * @param object The object to serialize
1132   * @return string
1133   */
1134  function SerializeObject(&$object)
1135  {
1136      return base64_encode(serialize($object));
1137  }
1138  
1139  
1140  
1141  /**
1142   * A function unserialize data into an object
1143   *
1144   * @internal
1145   * @param string The serialized text.
1146   * @return object  A valid object on success, or null
1147   * Rolf: only used in admin/editcontent_extra.php
1148   */
1149  function UnserializeObject(&$serialized)
1150  {
1151      return  unserialize(base64_decode($serialized));
1152  }
1153  
1154  
1155  
1156  /**
1157   * A convenience function to test wether one string starts with another
1158   *
1159   * i.e:  startswith('The Quick Brown Fox','The');
1160   *
1161   * @param string The string to test against
1162   * @param string The search string
1163   * @return boolean
1164   */
1165  function startswith( $str, $sub )
1166  {
1167      return ( substr( $str, 0, strlen( $sub ) ) == $sub );
1168  }
1169  
1170  
1171  
1172  /**
1173   * Similar to the startswith method, this function tests with string A ends with string B
1174   *
1175   * i.e: endswith('The Quick Brown Fox','Fox');
1176   *
1177   * @param string The string to test against
1178   * @param string The search string
1179   * @return boolean
1180   */
1181  function endswith( $str, $sub )
1182  {
1183      return ( substr( $str, strlen( $str ) - strlen( $sub ) ) == $sub );
1184  }
1185  
1186  
1187  
1188  /**
1189   * convert a human readable string into something that is suitable for use in URLS
1190   * because many browsers don't support UTF-8 characters in URLS
1191   *
1192   * @internal
1193   * @param string String to convert
1194   * @param boolean indicates whether output string should be converted to lower case
1195   * @param boolean indicates wether slashes should be allowed in the input.
1196   * @return string
1197   */
1198  function munge_string_to_url($alias, $tolower = false, $withslash = false)
1199  {
1200      // replacement.php is encoded utf-8 and must be the first modification of alias
1201      include(dirname(__FILE__) . '/replacement.php');
1202      $alias = str_replace($toreplace, $replacement, $alias);
1203  
1204      // lowercase only on empty aliases
1205      if ($tolower == true)
1206      {
1207          $alias = strtolower($alias);
1208      }
1209  
1210      $expr = '/[^a-z0-9-_]+/i';
1211      if( $withslash )
1212        {
1213          $expr = '/[^a-z0-9-_\/]+/i';
1214        }
1215      $alias = preg_replace($expr,'-',$alias);
1216  
1217      for( $i = 0; $i < 5; $i++ )
1218        {
1219          $tmp = str_replace('--','-',$alias);
1220          if( $tmp == $alias ) break;
1221          $alias = $tmp;
1222        }
1223      $alias = trim($alias, '-');
1224      $alias = trim($alias);
1225  
1226      return $alias;
1227  }
1228  
1229  
1230  /**
1231   * Rolf: only used in admin/style.php
1232   */
1233  function cms_readfile($filename)
1234  {
1235    @ob_start();
1236    echo file_get_contents($filename);
1237    $result = @ob_get_contents();
1238    @ob_end_clean();
1239    if( !empty($result) ) {
1240      echo $result;
1241      return TRUE;
1242    }
1243    return FALSE;
1244  }
1245  
1246  
1247  /*
1248   * Sanitize input to prevent against XSS and other nasty stuff.
1249   * Taken from cakephp (http://cakephp.org)
1250   * Licensed under the MIT License
1251   * 
1252   * @internal
1253   * @param string input
1254   * @return string
1255   */
1256  function cleanValue($val) {
1257      if ($val == "") {
1258          return $val;
1259      }
1260      //Replace odd spaces with safe ones
1261      $val = str_replace(" ", " ", $val);
1262      $val = str_replace(chr(0xCA), "", $val);
1263      //Encode any HTML to entities (including \n --> <br />)
1264      $val = cleanHtml($val);
1265      //Double-check special chars and remove carriage returns
1266      //For increased SQL security
1267      $val = preg_replace("/\\\$/", "$", $val);
1268      $val = preg_replace("/\r/", "", $val);
1269      $val = str_replace("!", "!", $val);
1270      $val = str_replace("'", "'", $val);
1271      //Allow unicode (?)
1272      $val = preg_replace("/&amp;#([0-9]+);/s", "&#\\1;", $val);
1273      //Add slashes for SQL
1274      //$val = $this->sql($val);
1275      //Swap user-inputted backslashes (?)
1276      $val = preg_replace("/\\\(?!&amp;#|\?#)/", "\\", $val);
1277      return $val;
1278  }
1279  
1280  
1281  
1282  /*
1283   * Method to sanitize incoming html.
1284   * Take from cakephp (http://cakephp.org)
1285   * Licensed under the MIT License
1286   *
1287   * @param string Input HTML code.
1288   * @param boolean Wether HTML tags should be removed.
1289   * @return string
1290   * Rolf: only used in this file
1291   */
1292  function cleanHtml($string, $remove = false) {
1293      if ($remove) {
1294          $string = strip_tags($string);
1295      } else {
1296          $patterns = array("/\&/", "/%/", "/</", "/>/", '/"/', "/'/", "/\(/", "/\)/", "/\+/", "/-/");
1297          $replacements = array("&amp;", "&#37;", "&lt;", "&gt;", "&quot;", "&#39;", "&#40;", "&#41;", "&#43;", "&#45;");
1298          $string = preg_replace($patterns, $replacements, $string);
1299      }
1300      return $string;
1301  }
1302  
1303  define('CLEAN_INT','CLEAN_INT');
1304  define('CLEAN_FLOAT','CLEAN_FLOAT');
1305  define('CLEAN_NONE','CLEAN_NONE');
1306  define('CLEAN_STRING','CLEAN_STRING');
1307  define('CLEAN_REGEXP','regexp:');
1308  define('CLEAN_FILE','CLEAN_FILE');
1309  
1310  
1311  
1312  /**
1313   * Method to sanitize all entries in a hash
1314   * This method is called by the module api to clean incomming parameters in the frontend.
1315   * It uses the map created with the SetParameterType() method in the module api.
1316   *
1317   * @internal
1318   * @param string Module Name
1319   * @param array  Hash data
1320   * @param array  A map of param names and type information
1321   * @param boolean A flag indicating wether unknown keys in the input data should be allowed.
1322   * @param boolean A flag indicating wether keys should be treated as strings and cleaned.
1323   * Rolf: only used in lib/classes/class.CMSModule.php
1324  */
1325  function cleanParamHash($modulename,$data,$map = false,
1326              $allow_unknown = false,$clean_keys = true)
1327  {
1328    $mappedcount = 0;
1329    $result = array();
1330    foreach( $data as $key => $value )
1331      {
1332        $mapped = false;
1333        $paramtype = '';
1334        if( is_array($map) )
1335          {
1336            if( isset($map[$key]) )
1337              {
1338                  $paramtype = $map[$key];
1339              }
1340            else {
1341                // Key not found in the map
1342                // see if one matches via regular expressions
1343                foreach( $map as $mk => $mv ) {
1344                    if(strstr($mk,CLEAN_REGEXP) === FALSE) continue;
1345  
1346                    // mk is a regular expression
1347                    $ss = substr($mk,strlen(CLEAN_REGEXP));
1348                    if( $ss !== FALSE ) {
1349                        if( preg_match($ss, $key) ) {
1350                            // it matches, we now know what type to use
1351                            $paramtype = $mv;
1352                            break;
1353                        }
1354                    }
1355                }
1356            } // else
1357  
1358            if( $paramtype != '' ) {
1359                switch( $paramtype ) {
1360                case 'CLEAN_INT':
1361                    $mappedcount++;
1362                    $mapped = true;
1363                    $value = (int) $value;
1364                    break;
1365                case 'CLEAN_FLOAT':
1366                    $mappedcount++;
1367                    $mapped = true;
1368                    $value = (float) $value;
1369                    break;
1370                case 'CLEAN_NONE':
1371                    // pass through without cleaning.
1372                    $mappedcount++;
1373                    $mapped = true;
1374                    break;
1375                case 'CLEAN_STRING':
1376                    $value = cms_htmlentities($value);
1377                    $mappedcount++;
1378                    $mapped = true;
1379                    break;
1380                case 'CLEAN_FILE':
1381                    $value = cms_cleanfile($value);
1382                    $mappedcount++;
1383                    $mapped = true;
1384                    break;
1385                default:
1386                    $mappedcount++;
1387                    $mapped = true;
1388                    $value = cms_htmlentities($value);
1389                    break;
1390                } // switch
1391            } // if $paramtype
1392  
1393          }
1394  
1395        // we didn't clean this yet
1396        if( $allow_unknown && !$mapped )
1397          {
1398            // but we're allowing unknown stuff so we'll just clean it.
1399            $value = cms_htmlentities($value);
1400            $mappedcount++;
1401            $mapped = true;
1402          }
1403  
1404        if( $clean_keys )
1405          {
1406            $key = cms_htmlentities($key);
1407          }
1408  
1409        if( !$mapped && !$allow_unknown )
1410          {
1411            trigger_error('Parameter '.$key.' is not known by module '.$modulename.' dropped',E_USER_WARNING);
1412            continue;
1413          }
1414        $result[$key]=$value;
1415      }
1416    return $result;
1417  }
1418  
1419  
1420  
1421  /**
1422   * Returns all parameters sent that are destined for the module with
1423   * the given $id.  This method reads the parameters directly from the $_REQUEST
1424   *
1425   * @internal
1426   * @param string ID (the module instance ID to use for extracting parameters)
1427   * @return array
1428   */
1429  function GetModuleParameters($id)
1430  {
1431    $params = array();
1432  
1433    if ($id != '')
1434      {
1435        foreach ($_REQUEST as $key=>$value)
1436      {
1437        if (strpos($key, (string)$id) !== FALSE && strpos($key, (string)$id) == 0)
1438          {
1439            $key = str_replace($id, '', $key);
1440            if( $key == 'id' || $key == 'returnid' )
1441          {
1442            $value = (int)$value;
1443          }
1444            $params[$key] = $value;
1445          }
1446      }
1447      }
1448  
1449    return $params;
1450  }
1451  
1452  
1453  
1454  /**
1455   * A function to test if permissions, and php configuration is setup correctly
1456   * to allow an administrator to upload files to CMSMS
1457   *
1458   * @internal
1459   * @return boolean
1460   */
1461  function can_admin_upload()
1462  {
1463    # first, check to see if safe mode is enabled
1464    # if it is, then check to see the owner of the index.php, moduleinterface.php
1465    # and the uploads and modules directory.  if they all match, then we
1466    # can upload files.
1467    # if safe mode is off, then we just have to check the permissions.
1468    $file_index = cmsms()->config['root_path'].DIRECTORY_SEPARATOR.'index.php';
1469    $file_moduleinterface = cmsms()->config['root_path'].DIRECTORY_SEPARATOR.
1470      cmsms()->config['admin_dir'].DIRECTORY_SEPARATOR.'moduleinterface.php';
1471    $dir_uploads = cmsms()->config['uploads_path'];
1472    $dir_modules = cmsms()->config['root_path'].DIRECTORY_SEPARATOR.'modules';
1473  
1474    $stat_index = @stat($file_index);
1475    $stat_moduleinterface = @stat($file_moduleinterface);
1476    $stat_uploads = @stat($dir_uploads);
1477    $stat_modules = @stat($dir_modules);
1478  
1479    $my_uid = @getmyuid();
1480  
1481    if( $my_uid === FALSE || $stat_index == FALSE ||
1482        $stat_moduleinterface == FALSE || $stat_uploads == FALSE ||
1483        $stat_modules == FALSE )
1484      {
1485        // couldn't get some necessary information.
1486        return FALSE;
1487      }
1488  
1489    $safe_mode = ini_get_boolean('safe_mode');
1490    if( $safe_mode )
1491      {
1492        // we're in safe mode.
1493        if( ($stat_moduleinterface[4] != $stat_modules[4]) ||
1494        ($stat_moduleinterface[4] != $stat_uploads[4]) ||
1495        ($my_uid != $stat_moduleinterface[4]) )
1496      {
1497        // owners don't match
1498        return FALSE;
1499      }
1500      }
1501  
1502    // now check to see if we can write to the directories
1503    if( !is_writable( $dir_modules ) )
1504      {
1505        return FALSE;
1506      }
1507    if( !is_writable( $dir_uploads ) )
1508      {
1509        return FALSE;
1510      }
1511  
1512    // It all worked.
1513    return TRUE;
1514  }
1515  
1516  
1517  
1518  /** 
1519   * A convenience function to interpret octal permissions, and return 
1520   * a human readable string.  Uses the lang() function for translation.
1521   *
1522   * @internal
1523   * @param int The permissions to test.
1524   * @return string
1525   * Rolf: only used in admin/siteprefs.php
1526   */
1527  function interpret_permissions($perms)
1528  {
1529    $owner = array();
1530    $group = array();
1531    $other = array();
1532  
1533    if( $perms & 0400 )
1534      {
1535        $owner[] = lang('read');
1536      }
1537      
1538    if( $perms & 0200 )
1539      {
1540        $owner[] = lang('write');
1541      }
1542      
1543    if( $perms & 0100 )
1544      {
1545        $owner[] = lang('execute');
1546      }
1547  
1548    if( $perms & 0040 )
1549      {
1550        $group[] = lang('read');
1551      }
1552      
1553    if( $perms & 0020 )
1554      {
1555        $group[] = lang('write');
1556      }
1557      
1558    if( $perms & 0010 )
1559      {
1560        $group[] = lang('execute');
1561      }
1562  
1563    if( $perms & 0004 )
1564      {
1565        $other[] = lang('read');
1566      }
1567      
1568    if( $perms & 0002 )
1569      {
1570        $other[] = lang('write');
1571      }
1572      
1573    if( $perms & 0001 )
1574      {
1575        $other[] = lang('execute');
1576      }
1577  
1578    return array($owner,$group,$other);
1579  }
1580  
1581  
1582  
1583  /**
1584   * A convenience function to return a boolean variable given a php ini key that represents a boolean
1585   *
1586   * @param string  The php ini key
1587   * @return integer
1588   * Rolf: only used in admin/header.php
1589   */
1590  function ini_get_boolean($str)
1591  {
1592    $val1 = ini_get($str);
1593    $val2 = strtolower($val1);
1594  
1595    $ret = 0;
1596    if( $val2 == 1 || $val2 == '1' || $val2 == 'yes' || $val2 == 'true' || $val2 == 'on' )
1597       $ret = 1;
1598    return $ret;
1599  }
1600  
1601  
1602  
1603  /**
1604   * Another convenience function to output a human readable function stack trace
1605   *
1606   * @return void
1607   */
1608  function stack_trace()
1609  {
1610    $stack = debug_backtrace();
1611    foreach( $stack as $elem )
1612      {
1613        if( $elem['function'] == 'stack_trace' ) continue;
1614        if( isset($elem['file'])  )
1615      {
1616        echo $elem['file'].':'.$elem['line'].' - '.$elem['function'].'<br/>';
1617      }
1618        else
1619      {
1620        echo ' - '.$elem['function'].'<br/>';
1621      }
1622      }
1623  }
1624  
1625  
1626  
1627  /** 
1628   * A wrapper around move_uploaded_file that attempts to ensure permissions on uploaded
1629   * files are set correctly.
1630   *
1631   * @param string The temporary file specification
1632   * @param string The destination file specification
1633   * @return boolean.
1634   */
1635  function cms_move_uploaded_file( $tmpfile, $destination )
1636  {
1637     $config = cmsms()->GetConfig();
1638  
1639     if( !@move_uploaded_file( $tmpfile, $destination ) )
1640     {
1641        return false;
1642     }
1643  
1644     @chmod($destination,octdec($config['default_upload_permission']));
1645     return true;
1646  }
1647  
1648  
1649  
1650  /**
1651   * A function to read CSS cache information
1652   *
1653   * @deprecated
1654   * @internal
1655   * @param string Filename containing cash information
1656   * @return array of css cache information
1657   * Rolf: only used in admin/editcss.php
1658   */
1659  function csscache_csvfile_to_hash($filename)
1660  {
1661    if( !is_readable($filename) ) return false;
1662    $tmp = @file($filename);
1663    if( !is_array($tmp) || !count($tmp) ) return false;
1664  
1665    $result = array();
1666    foreach( $tmp as $one )
1667      {
1668        $vals = explode(',',trim($one));
1669        $result[$vals[0]] = $vals[1];
1670      }
1671    return $result;
1672  }
1673  
1674  
1675  
1676  /**
1677   * A function to take hash information representing CSS cache data and store it in a CSV file
1678   *
1679   * @deprecated
1680   * @internal
1681   * @param string Filename to output information to
1682   * @param array  Hash of CSS cache information.
1683   * @return void
1684   * Rolf: only used in admin/editcss.php
1685   */
1686  function csscache_hash_to_csvfile($filename,$hash)
1687  {
1688    $fh = @fopen($filename,'w');
1689    if( !$fh ) return false;
1690    foreach( $hash as $key => $val )
1691      {
1692        $key = trim($key); $val = trim($val);
1693        $line = "$key,$val\n";
1694        fwrite($fh,$line);
1695      }
1696    fclose($fh);
1697  }
1698  
1699  
1700  /**
1701   * A function to test wether an IP address matches a list of expressions
1702   * Credits to J.Adams <jna@retins.net>
1703   *
1704   * Expressions can be of the form
1705   *   xxx.xxx.xxx.xxx        (exact)
1706   *   xxx.xxx.xxx.[yyy-zzz]  (range)
1707   *   xxx.xxx.xxx.xxx/nn    (nn = # bits, cisco style -- i.e. /24 = class C)
1708   *
1709   * @param string IP address to test
1710   * @param array  Array of match expressions
1711   * @return boolean
1712   * Rolf: only used in lib/content.functions.php
1713   */
1714  function cms_ipmatches($ip,$checklist)
1715  {
1716    if( !function_exists('__testip') ) {
1717    function __testip($range,$ip)
1718    {
1719      $result = 1;
1720  
1721      // IP Pattern Matcher
1722      // J.Adams <jna@retina.net>
1723      //
1724      // Matches:
1725      //
1726      // xxx.xxx.xxx.xxx        (exact)
1727      // xxx.xxx.xxx.[yyy-zzz]  (range)
1728      // xxx.xxx.xxx.xxx/nn    (nn = # bits, cisco style -- i.e. /24 = class C)
1729      //
1730      // Does not match:
1731      // xxx.xxx.xxx.xx[yyy-zzz]  (range, partial octets not supported)
1732  
1733      $regs = array();
1734      if (preg_match("/([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)\/([0-9]+)/",$range,$regs)) {
1735        // perform a mask match
1736        $ipl = ip2long($ip);
1737        $rangel = ip2long($regs[1] . "." . $regs[2] . "." . $regs[3] . "." . $regs[4]);
1738  
1739        $maskl = 0;
1740  
1741        for ($i = 0; $i< 31; $i++) {
1742      if ($i < $regs[5]-1) {
1743        $maskl = $maskl + pow(2,(30-$i));
1744      }
1745        }
1746  
1747        if (($maskl & $rangel) == ($maskl & $ipl)) {
1748      return 1;
1749        } else {
1750      return 0;
1751        }
1752      } else {
1753        // range based
1754        $maskocts = explode('.',$range);
1755        $ipocts = explode('.',$ip);
1756  
1757        if( count($maskocts) != count($ipocts) && count($maskocts) != 4 )
1758      {
1759        return 0;
1760      }
1761  
1762        // perform a range match
1763        for ($i=0; $i<4; $i++) {
1764      if (preg_match("/\[([0-9]+)\-([0-9]+)\]/",$maskocts[$i],$regs)) {
1765        if ( ($ipocts[$i] > $regs[2]) || ($ipocts[$i] < $regs[1])) {
1766          $result = 0;
1767        }
1768      }
1769      else
1770        {
1771          if ($maskocts[$i] <> $ipocts[$i]) {
1772            $result = 0;
1773          }
1774        }
1775        }
1776      }
1777      return $result;
1778    } // __testip
1779    } // if
1780  
1781    if( !is_array($checklist) )
1782      {
1783        $checklist = explode(',',$checklist);
1784      }
1785    foreach( $checklist as $one )
1786      {
1787        if( __testip(trim($one),$ip) ) return TRUE;
1788      }
1789    return FALSE;
1790  }
1791  
1792  /**
1793   * @author    Dominic Sayers <dominic_sayers@hotmail.com>
1794   * @copyright    2009 Dominic Sayers
1795   * @license    http://www.opensource.org/licenses/cpal_1.0 Common Public Attribution License Version 1.0 (CPAL) license
1796   * @link    http://www.dominicsayers.com/isemail
1797   * @version    1.9 - Minor modifications to make it compatible with PHPLint
1798   * @return boolean
1799   * @param string  $email
1800   * @param boolean $checkDNS
1801  */
1802  function is_email( $email, $checkDNS=false ) {
1803      // Check that $email is a valid address. Read the following RFCs to understand the constraints:
1804      //     (http://tools.ietf.org/html/rfc5322)
1805      //     (http://tools.ietf.org/html/rfc3696)
1806      //     (http://tools.ietf.org/html/rfc5321)
1807      //     (http://tools.ietf.org/html/rfc4291#section-2.2)
1808      //     (http://tools.ietf.org/html/rfc1123#section-2.1)
1809  
1810      // the upper limit on address lengths should normally be considered to be 256
1811      //     (http://www.rfc-editor.org/errata_search.php?rfc=3696)
1812      //     NB I think John Klensin is misreading RFC 5321 and the the limit should actually be 254
1813      //     However, I will stick to the published number until it is changed.
1814      //
1815      // The maximum total length of a reverse-path or forward-path is 256
1816      // characters (including the punctuation and element separators)
1817      //     (http://tools.ietf.org/html/rfc5321#section-4.5.3.1.3)
1818      $emailLength = strlen($email);
1819      if ($emailLength > 256)    return false;    // Too long
1820  
1821      // Contemporary email addresses consist of a "local part" separated from
1822      // a "domain part" (a fully-qualified domain name) by an at-sign ("@").
1823      //     (http://tools.ietf.org/html/rfc3696#section-3)
1824      $atIndex = strrpos($email,'@');
1825  
1826      if ($atIndex === false) return false;    // No at-sign
1827      if ($atIndex === 0) return false;    // No local part
1828      if ($atIndex === $emailLength) return false;    // No domain part
1829  
1830      // Sanitize comments
1831      // - remove nested comments, quotes and dots in comments
1832      // - remove parentheses and dots from quoted strings
1833      $braceDepth    = 0;
1834      $inQuote    = false;
1835      $escapeThisChar    = false;
1836  
1837      for ($i = 0; $i < $emailLength; ++$i) {
1838          $char = $email[$i];
1839          $replaceChar = false;
1840  
1841          if ($char === '\\') {
1842              $escapeThisChar = !$escapeThisChar;    // Escape the next character?
1843          } else {
1844              switch ($char) {
1845              case '(':
1846                  if ($escapeThisChar) {
1847                      $replaceChar = true;
1848                  } else {
1849                      if ($inQuote) {
1850                          $replaceChar = true;
1851                      } else {
1852                          if ($braceDepth++ > 0) $replaceChar = true;    // Increment brace depth
1853                      }
1854                  }
1855  
1856                  break;
1857              case ')':
1858                  if ($escapeThisChar) {
1859                      $replaceChar = true;
1860                  } else {
1861                      if ($inQuote) {
1862                          $replaceChar = true;
1863                      } else {
1864                          if (--$braceDepth > 0) $replaceChar = true;    // Decrement brace depth
1865                          if ($braceDepth < 0) $braceDepth = 0;
1866                      }
1867                  }
1868  
1869                  break;
1870              case '"':
1871                  if ($escapeThisChar) {
1872                      $replaceChar = true;
1873                  } else {
1874                      if ($braceDepth === 0) {
1875                          $inQuote = !$inQuote;    // Are we inside a quoted string?
1876                      } else {
1877                          $replaceChar = true;
1878                      }
1879                  }
1880  
1881                  break;
1882              case '.':    // Dots don't help us either
1883                  if ($escapeThisChar) {
1884                      $replaceChar = true;
1885                  } else {
1886                      if ($braceDepth > 0) $replaceChar = true;
1887                  }
1888  
1889                  break;
1890              default:
1891              }
1892  
1893              $escapeThisChar = false;
1894              if ($replaceChar) $email[$i] = 'x';    // Replace the offending character with something harmless
1895          }
1896      }
1897  
1898      $localPart    = substr($email, 0, $atIndex);
1899      $domain        = substr($email, $atIndex + 1);
1900      $FWS        = "(?:(?:(?:[ \\t]*(?:\\r\\n))?[ \\t]+)|(?:[ \\t]+(?:(?:\\r\\n)[ \\t]+)*))";    // Folding white space
1901      // Let's check the local part for RFC compliance...
1902      //
1903      // local-part      =       dot-atom / quoted-string / obs-local-part
1904      // obs-local-part  =       word *("." word)
1905      //     (http://tools.ietf.org/html/rfc5322#section-3.4.1)
1906      //
1907      // Problem: need to distinguish between "first.last" and "first"."last"
1908      // (i.e. one element or two). And I suck at regexes.
1909      $dotArray = preg_split('/\\.(?=(?:[^\\"]*\\"[^\\"]*\\")*(?![^\\"]*\\"))/m', $localPart);
1910      $partLength    = 0;
1911  
1912      foreach ($dotArray as $element) {
1913          // Remove any leading or trailing FWS
1914          $element = preg_replace("/^$FWS|$FWS\$/", '', $element);
1915  
1916          // Then we need to remove all valid comments (i.e. those at the start or end of the element
1917          $elementLength = strlen($element);
1918  
1919          if ($element[0] === '(') {
1920              $indexBrace = strpos($element, ')');
1921              if ($indexBrace !== false) {
1922                  if (preg_match('/(?<!\\\\)[\\(\\)]/', substr($element, 1, $indexBrace - 1)) > 0) {
1923                      return false;    // Illegal characters in comment
1924                  }
1925                  $element = substr($element, $indexBrace + 1, $elementLength - $indexBrace - 1);
1926                  $elementLength = strlen($element);
1927              }
1928          }
1929  
1930          if ($element[$elementLength - 1] === ')') {
1931              $indexBrace = strrpos($element, '(');
1932              if ($indexBrace !== false) {
1933                  if (preg_match('/(?<!\\\\)(?:[\\(\\)])/', substr($element, $indexBrace + 1, $elementLength - $indexBrace - 2)) > 0) {
1934                      return false;    // Illegal characters in comment
1935                  }
1936                  $element = substr($element, 0, $indexBrace);
1937                  $elementLength = strlen($element);
1938              }
1939          }
1940  
1941          // Remove any leading or trailing FWS around the element (inside any comments)
1942          $element = preg_replace("/^$FWS|$FWS\$/", '', $element);
1943  
1944          // What's left counts towards the maximum length for this part
1945          if ($partLength > 0) $partLength++;    // for the dot
1946          $partLength += strlen($element);
1947  
1948          // Each dot-delimited component can be an atom or a quoted string
1949          // (because of the obs-local-part provision)
1950          if (preg_match('/^"(?:.)*"$/s', $element) > 0) {
1951              // Quoted-string tests:
1952              //
1953              // Remove any FWS
1954              $element = preg_replace("/(?<!\\\\)$FWS/", '', $element);
1955              // My regex skillz aren't up to distinguishing between \" \\" \\\" \\\\" etc.
1956              // So remove all \\ from the string first...
1957              $element = preg_replace('/\\\\\\\\/', ' ', $element);
1958              if (preg_match('/(?<!\\\\|^)["\\r\\n\\x00](?!$)|\\\\"$|""/', $element) > 0)    return false;    // ", CR, LF and NUL must be escaped, "" is too short
1959          } else {
1960              // Unquoted string tests:
1961              //
1962              // Period (".") may...appear, but may not be used to start or end the
1963              // local part, nor may two or more consecutive periods appear.
1964              //     (http://tools.ietf.org/html/rfc3696#section-3)
1965              //
1966              // A zero-length element implies a period at the beginning or end of the
1967              // local part, or two periods together. Either way it's not allowed.
1968              if ($element === '') return false;    // Dots in wrong place
1969  
1970              // Any ASCII graphic (printing) character other than the
1971              // at-sign ("@"), backslash, double quote, comma, or square brackets may
1972              // appear without quoting.  If any of that list of excluded characters
1973              // are to appear, they must be quoted
1974              //     (http://tools.ietf.org/html/rfc3696#section-3)
1975              //
1976              // Any excluded characters? i.e. 0x00-0x20, (, ), <, >, [, ], :, ;, @, \, comma, period, "
1977              if (preg_match('/[\\x00-\\x20\\(\\)<>\\[\\]:;@\\\\,\\."]/', $element) > 0) return false;    // These characters must be in a quoted string
1978          }
1979      }
1980  
1981      if ($partLength > 64) return false;    // Local part must be 64 characters or less
1982  
1983      // Now let's check the domain part...
1984      // The domain name can also be replaced by an IP address in square brackets
1985      //     (http://tools.ietf.org/html/rfc3696#section-3)
1986      //     (http://tools.ietf.org/html/rfc5321#section-4.1.3)
1987      //     (http://tools.ietf.org/html/rfc4291#section-2.2)
1988      if (preg_match('/^\\[(.)+]$/', $domain) === 1) {
1989          // It's an address-literal
1990          $addressLiteral = substr($domain, 1, strlen($domain) - 2);
1991          $matchesIP = array();
1992  
1993          // Extract IPv4 part from the end of the address-literal (if there is one)
1994          if (preg_match('/\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/', $addressLiteral, $matchesIP) > 0) {
1995              $index = strrpos($addressLiteral, $matchesIP[0]);
1996  
1997              if ($index === 0) {
1998                  // Nothing there except a valid IPv4 address, so...
1999                  return true;
2000              } else {
2001                  // Assume it's an attempt at a mixed address (IPv6 + IPv4)
2002                  if ($addressLiteral[$index - 1] !== ':') return false;    // Character preceding IPv4 address must be ':'
2003                  if (substr($addressLiteral, 0, 5) !== 'IPv6:') return false;    // RFC5321 section 4.1.3
2004                  $IPv6 = substr($addressLiteral, 5, ($index ===7) ? 2 : $index - 6);
2005                  $groupMax = 6;
2006              }
2007          } else {
2008              // It must be an attempt at pure IPv6
2009              if (substr($addressLiteral, 0, 5) !== 'IPv6:') return false;    // RFC5321 section 4.1.3
2010              $IPv6 = substr($addressLiteral, 5);
2011              $groupMax = 8;
2012          }
2013  
2014          $groupCount    = preg_match_all('/^[0-9a-fA-F]{0,4}|\\:[0-9a-fA-F]{0,4}|(.)/', $IPv6, $matchesIP);
2015          $index = strpos($IPv6,'::');
2016  
2017          if ($index === false) {
2018              // We need exactly the right number of groups
2019              if ($groupCount !== $groupMax) return false;    // RFC5321 section 4.1.3
2020          } else {
2021              if ($index !== strrpos($IPv6,'::')) return false;    // More than one '::'
2022              $groupMax = ($index === 0 || $index === (strlen($IPv6) - 2)) ? $groupMax : $groupMax - 1;
2023              if ($groupCount > $groupMax) return false;    // Too many IPv6 groups in address
2024          }
2025  
2026          // Check for unmatched characters
2027          array_multisort($matchesIP[1], SORT_DESC);
2028          if ($matchesIP[1][0] !== '') return false;    // Illegal characters in address
2029  
2030          // It's a valid IPv6 address, so...
2031          return true;
2032      } else {
2033          // It's a domain name...
2034  
2035          // The syntax of a legal Internet host name was specified in RFC-952
2036          // One aspect of host name syntax is hereby changed: the
2037          // restriction on the first character is relaxed to allow either a
2038          // letter or a digit.
2039          //     (http://tools.ietf.org/html/rfc1123#section-2.1)
2040          //
2041          // NB RFC 1123 updates RFC 1035, but this is not currently apparent from reading RFC 1035.
2042          //
2043          // Most common applications, including email and the Web, will generally not
2044          // permit...escaped strings
2045          //     (http://tools.ietf.org/html/rfc3696#section-2)
2046          //
2047          // the better strategy has now become to make the "at least one period" test,
2048          // to verify LDH conformance (including verification that the apparent TLD name
2049          // is not all-numeric)
2050          //     (http://tools.ietf.org/html/rfc3696#section-2)
2051          //
2052          // Characters outside the set of alphabetic characters, digits, and hyphen MUST NOT appear in domain name
2053          // labels for SMTP clients or servers
2054          //     (http://tools.ietf.org/html/rfc5321#section-4.1.2)
2055          //
2056          // RFC5321 precludes the use of a trailing dot in a domain name for SMTP purposes
2057          //     (http://tools.ietf.org/html/rfc5321#section-4.1.2)
2058          $dotArray = preg_split('/\\.(?=(?:[^\\"]*\\"[^\\"]*\\")*(?![^\\"]*\\"))/m', $domain);
2059          $partLength = 0;
2060          if (count($dotArray) === 1) return false;    // Mail host can't be a TLD
2061  
2062          foreach ($dotArray as $element) {
2063              // Remove any leading or trailing FWS
2064              $element = preg_replace("/^$FWS|$FWS\$/", '', $element);
2065  
2066              // Then we need to remove all valid comments (i.e. those at the start or end of the element
2067              $elementLength = strlen($element);
2068  
2069              if ($element[0] === '(') {
2070                  $indexBrace = strpos($element, ')');
2071                  if ($indexBrace !== false) {
2072                      if (preg_match('/(?<!\\\\)[\\(\\)]/', substr($element, 1, $indexBrace - 1)) > 0) {
2073                          return false;    // Illegal characters in comment
2074                      }
2075                      $element = substr($element, $indexBrace + 1, $elementLength - $indexBrace - 1);
2076                      $elementLength = strlen($element);
2077                  }
2078              }
2079  
2080              if ($element[$elementLength - 1] === ')') {
2081                  $indexBrace = strrpos($element, '(');
2082                  if ($indexBrace !== false) {
2083                      if (preg_match('/(?<!\\\\)(?:[\\(\\)])/', substr($element, $indexBrace + 1, $elementLength - $indexBrace - 2)) > 0) {
2084                          return false;    // Illegal characters in comment
2085                      }
2086                      $element = substr($element, 0, $indexBrace);
2087                      $elementLength = strlen($element);
2088                  }
2089              }
2090  
2091              // Remove any leading or trailing FWS around the element (inside any comments)
2092              $element = preg_replace("/^$FWS|$FWS\$/", '', $element);
2093  
2094              // What's left counts towards the maximum length for this part
2095              if ($partLength > 0) $partLength++;    // for the dot
2096              $partLength += strlen($element);
2097  
2098              // The DNS defines domain name syntax very generally -- a
2099              // string of labels each containing up to 63 8-bit octets,
2100              // separated by dots, and with a maximum total of 255
2101              // octets.
2102              //     (http://tools.ietf.org/html/rfc1123#section-6.1.3.5)
2103              if ($elementLength > 63) return false;    // Label must be 63 characters or less
2104  
2105              // Each dot-delimited component must be atext
2106              // A zero-length element implies a period at the beginning or end of the
2107              // local part, or two periods together. Either way it's not allowed.
2108              if ($elementLength === 0) return false;    // Dots in wrong place
2109  
2110              // Any ASCII graphic (printing) character other than the
2111              // at-sign ("@"), backslash, double quote, comma, or square brackets may
2112              // appear without quoting.  If any of that list of excluded characters
2113              // are to appear, they must be quoted
2114              //     (http://tools.ietf.org/html/rfc3696#section-3)
2115              //
2116              // If the hyphen is used, it is not permitted to appear at
2117              // either the beginning or end of a label.
2118              //     (http://tools.ietf.org/html/rfc3696#section-2)
2119              //
2120              // Any excluded characters? i.e. 0x00-0x20, (, ), <, >, [, ], :, ;, @, \, comma, period, "
2121              //if (preg_match('/[\\x00-\\x20\\(\\)<>\\[\\]:;@\\\\,\\."]|^-|-$/', $element) > 0) {
2122              if (preg_match('/[\\x00-\\x20\\(\\)<>\\[\\]:;@\\\\,\\."]$/', $element) > 0) {
2123                  return false;
2124              }
2125          }
2126  
2127          if ($partLength > 255) return false;    // Local part must be 64 characters or less
2128          if (preg_match('/^[0-9]+$/', $element) > 0)    return false;    // TLD can't be all-numeric
2129  
2130          // Check DNS?
2131          if ($checkDNS && function_exists('checkdnsrr')) {
2132              if (!(checkdnsrr($domain, 'A') || checkdnsrr($domain, 'MX'))) {
2133                  return false;    // Domain doesn't actually exist
2134              }
2135          }
2136      }
2137  
2138      // Eliminate all other factors, and the one which remains must be the truth.
2139      // (Sherlock Holmes, The Sign of Four)
2140      return true;
2141  }
2142  
2143  
2144  
2145  /**
2146   * A convenience method to output the secure param tag that is used on all admin links
2147   *
2148   * @internal
2149   * @access private
2150   * @return string
2151   * Rolf: only used in admin/imagefiles.php
2152   */
2153  function get_secure_param()
2154  {
2155    $urlext = '?';
2156    $str = strtolower(ini_get('session.use_cookies'));
2157    if( $str == '0' || $str == 'off' ) {
2158      $urlext .= htmlspecialchars(SID).'&';
2159    }
2160    $urlext .= CMS_SECURE_PARAM_NAME.'='.$_SESSION[CMS_USER_KEY];
2161    return $urlext;
2162  }
2163  
2164  
2165  
2166  /**
2167   * Rolf: only used in lib/classes/contenttypes/Content.inc.php
2168   */
2169  function cms_to_bool($str)
2170  {
2171    if( is_numeric($str) )
2172    {
2173      return ((int)$str != 0)?TRUE:FALSE;
2174    }
2175  
2176    $str = strtolower($str);
2177    if( $str == 'y' || $str == 'yes' || $str == 'true' ) return TRUE;
2178    return FALSE;
2179  }
2180  
2181  
2182  
2183  /**
2184   *
2185   */
2186  function cms_get_jquery($exclude = '',$ssl = null,$cdn = false,$append = '',$custom_root='')
2187  {
2188    $config = cms_config::get_instance();
2189    $scripts = array();
2190    $base_url = $config['root_url'];
2191    if( is_null($ssl) ) {
2192      $base_url = $config->smart_root_url();
2193    }
2194    else if( $ssl === true || $ssl === TRUE ) {
2195      $base_url = $config['ssl_url'];
2196    }
2197    $basePath=$custom_root!=''?trim($custom_root,'/'):$base_url;
2198    
2199    // Scripts to include
2200    $scripts['jquery.min.js'] = '<script type="text/javascript" src="'.($cdn?'https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js':$basePath.'/lib/jquery/js/jquery-1.11.0.min.js').'"></script>'."\n"
2201    . '<script type="text/javascript" src="' . $basePath .'/lib/jquery/js/jquery-migrate-1.2.1.min.js"></script>' . "\n";
2202    $scripts['jquery-ui.min.js'] = '<script type="text/javascript" src="'.($cdn?'https://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js':$basePath.'/lib/jquery/js/jquery-ui-1.10.4.custom.min.js').'"></script>'."\n";
2203    $scripts['jquery.ui.nestedSortable.js'] = '<script type="text/javascript" src="'.$basePath.'/lib/jquery/js/jquery.ui.nestedSortable-1.3.4.js"></script>'."\n";
2204    $scripts['jquery.json.min.js'] = '<script type="text/javascript" src="'.$basePath.'/lib/jquery/js/jquery.json-2.3.min.js"></script>'."\n";
2205    
2206    // Check if we need exclude some script
2207    if(!empty($exclude)) {
2208      
2209      $exclude_list = explode(",", trim(str_replace(' ','',$exclude)));
2210      foreach($exclude_list as $one) {
2211        if ($one == 'jquery-1.6.2.min.js') {
2212            $one = 'jquery.min.js';
2213        }
2214        if ($one == 'jquery-ui-1.8.14.min.js') {
2215            $one = 'jquery-ui.min.js';
2216        }
2217        if ($one == 'jquery.json-2.2.js') {
2218            $one = 'jquery.json.min.js';
2219        }
2220        if ($one == 'jquery.ui.nestedSortable-1.3.4.js') {
2221            $one = 'jquery.ui.nestedSortable.js';
2222        }
2223        
2224        unset($scripts[$one]);
2225      }        
2226    }
2227    // let them add scripts to the end ie: a jQuery plugin
2228    if(!empty($append)) {
2229      $append_list = explode(",", trim(str_replace(' ','',$append)));
2230      foreach($append_list as $key => $item) {
2231        $scripts['user_'+$key]='<script type="text/javascript" src="'.($item).'"></script>'."\n";;
2232      }        
2233    }
2234    // Output
2235  
2236    $output = '';
2237    foreach($scripts as $script) {
2238      $output .= $script;        
2239    }
2240    return $output;
2241  }
2242      
2243      
2244  
2245  /**
2246   * Rolf: only used in lib/classes/class.CMSModule.php
2247   */    
2248  if(!function_exists('get_called_class')) {
2249    function get_called_class() {
2250      try {
2251        return cms_function_help::get_called_class();
2252      }
2253      catch( Exception $e ) {
2254        // ignore
2255      }
2256    }
2257    // this class must exist in this file until CMSMS 1.12 when we dont have to worry abut PHP 5.2
2258    // this file is loaded before the autoloader runs.
2259    class cms_function_help {
2260  
2261      public static function get_called_class($bt = false,$l = 1) 
2262      {
2263        if (!$bt) $bt = debug_backtrace();
2264        if (!isset($bt[$l])) throw new Exception("Cannot find called class -> stack level too deep.");
2265        if (!isset($bt[$l]['type'])) { 
2266          if( $l >= 2 ) {
2267        throw new Exception ('type not set');
2268          }
2269          else {
2270            return self::get_called_class($bt,$l+1);
2271          }
2272        }
2273        else switch ($bt[$l]['type']) {
2274        case '::':
2275      $lines = file($bt[$l]['file']);
2276      $i = 0;
2277      $callerLine = '';
2278      do {
2279        $i++;
2280        $callerLine = $lines[$bt[$l]['line']-$i] . $callerLine;
2281      } while (stripos($callerLine,$bt[$l]['function']) === false);
2282      preg_match('/([a-zA-Z0-9\_]+)::'.$bt[$l]['function'].'/',
2283             $callerLine,
2284             $matches);
2285      if (!isset($matches[1])) {
2286           
2287        // must be an edge case.
2288        throw new Exception ("Could not find caller class: originating method call is obscured.");
2289      }
2290      switch ($matches[1]) {
2291      case 'self':
2292      case 'parent':
2293        return self::get_called_class($bt,$l+1);
2294      default:
2295        return $matches[1];
2296      }
2297      // won't get here.
2298        case '->': switch ($bt[$l]['function']) {
2299      case '__get':
2300        // edge case -> get class of calling object
2301        if (!is_object($bt[$l]['object'])) throw new Exception ("Edge case fail. __get called on non object.");
2302        return get_class($bt[$l]['object']);
2303      default: return $bt[$l]['class'];
2304      }
2305  
2306        default: throw new Exception ("Unknown backtrace method type");
2307        }
2308      }
2309    }
2310   }
2311  
2312  # vim:ts=4 sw=4 noet
2313  ?>

title

Description

title

Description

title

Description

title

title

Body