Zikula_Core
[ class tree: Zikula_Core ] [ index: Zikula_Core ] [ all elements ]

Source for file DataUtil.class.php

Documentation is available at DataUtil.class.php

  1. <?php
  2. /**
  3.  * Zikula Application Framework
  4.  *
  5.  * @copyright Robert Gasch
  6.  * @link http://www.zikula.org
  7.  * @version $Id: DataUtil.class.php 24342 2008-06-06 12:03:14Z markwest $
  8.  * @license GNU/GPL - http://www.gnu.org/copyleft/gpl.html
  9.  * @author Robert Gasch rgasch@gmail.com
  10.  * @uses generic data utililty class
  11.  * @package Zikula_Core
  12.  */
  13.  
  14. /**
  15.  * DataUtil
  16.  *
  17.  * @package Zikula_Core
  18.  * @subpackage DataUtil
  19.  */
  20. class DataUtil
  21. {
  22.     /**
  23.      * Clean a variable, remove slashes. This method is recursive array safe.
  24.      *
  25.      * @param var        The variable to clean
  26.      *
  27.      * @return The formatted variable
  28.      */
  29.     function cleanVar ($var)
  30.     {
  31.         if (!get_magic_quotes_gpc()) {
  32.             return $var;
  33.         }
  34.  
  35.         if (is_array($var)) {
  36.             foreach ($var as $k => $v{
  37.                 $var[$kDataUtil::cleanVar($v);
  38.             }
  39.         else {
  40.             pnStripslashes($var);
  41.         }
  42.  
  43.         return $var;
  44.     }
  45.  
  46.     /**
  47.      * Decode a character a previously encoded character
  48.      *
  49.      * @param value      The value we wish to encode
  50.      *
  51.      * @return The decoded value
  52.      */
  53.     function decode ($value)
  54.     {
  55.         return base64_decode($value);
  56.     }
  57.  
  58.     /**
  59.      * Decrypt the given value using the mcrypt library function. If the mcrypt
  60.      * functions do not exist, we fallback to the RC4 implementation which is
  61.      * shipped with Zikula.
  62.      *
  63.      * @param value      The value we wish to decrypt
  64.      * @param key        The encryption key to use (optional) (default=null)
  65.      * @param alg        The encryption algirthm to use (only used with mcrypt functions) (optional) (default=null, signifies MCRYPT_RIJNDAEL_128)
  66.      * @param encoded    Whether or not the value is base64 encoded (optional) (default=true)
  67.      *
  68.      * @return The decrypted value
  69.      */
  70.     function decrypt ($value$key=null$alg=null$encoded=true)
  71.     {
  72.         $res false;
  73.         $key ($key $key 'ZikulaEncryptionKey');
  74.         $val ($encoded DataUtil::decode ($value$value);
  75.  
  76.         if (function_exists('mcrypt_create_iv'&& function_exists('mcrypt_decrypt')) {
  77.             $alg ($alg $alg MCRYPT_RIJNDAEL_128);
  78.             $iv  mcrypt_create_iv(mcrypt_get_iv_size($algMCRYPT_MODE_ECB)crc32($key));
  79.             $res mcrypt_decrypt($alg$key$valMCRYPT_MODE_CBC);
  80.         }
  81.         else {
  82.             Loader::requireOnce('includes/classes/encryption/rc4crypt.class.php');
  83.             $res rc4crypt::decrypt($key$val);
  84.         }
  85.  
  86.         return $res;
  87.     }
  88.  
  89.     /**
  90.      * Encode a character sting such that it's 8-bit clean. It maps to base64_encode().
  91.      *
  92.      * @param value      The value we wish to encode
  93.      *
  94.      * @return The encoded value
  95.      */
  96.     function encode ($value)
  97.     {
  98.         return base64_encode($value);
  99.     }
  100.  
  101.     /**
  102.      * Encrypt the given value using the mcrypt library function. If the mcrypt
  103.      * functions do not exist, we fallback to the RC4 implementation which is
  104.      * shipped with Zikula.
  105.      *
  106.      * @param value      The value we wish to decrypt
  107.      * @param key        The encryption key to use (optional) (default=null)
  108.      * @param alg        The encryption algirthm to use (only used with mcrypt functions) (optional) (default=null, signifies MCRYPT_RIJNDAEL_128)
  109.      * @param encoded    Whether or not the value is base64 encoded (optional) (default=true)
  110.      *
  111.      * @return The encrypted value
  112.      */
  113.     function encrypt ($value$key=null$alg=null$encoded=true)
  114.     {
  115.         $res false;
  116.         $key ($key $key 'ZikulaEncryptionKey');
  117.  
  118.         if (function_exists('mcrypt_create_iv'&& function_exists('mcrypt_decrypt')) {
  119.             $alg ($alg $alg MCRYPT_RIJNDAEL_128);
  120.             $iv  mcrypt_create_iv(mcrypt_get_iv_size($algMCRYPT_MODE_ECB)crc32($key));
  121.             $res mcrypt_encrypt($alg$key$valueMCRYPT_MODE_CBC);
  122.         }
  123.         else {
  124.             Loader::requireOnce('includes/classes/encryption/rc4crypt.class.php');
  125.             $res rc4crypt::encrypt($key$value);
  126.         }
  127.  
  128.         return ($encoded && $res DataUtil::encode ($res$res);
  129.     }
  130.  
  131.     /**
  132.      * Format a variable for display. This method is recursive array safe.
  133.      *
  134.      * @param var        The variable to format
  135.      *
  136.      * @return The formatted variable
  137.      */
  138.     function formatForDisplay ($var)
  139.     {
  140.         // This search and replace finds the text 'x@y' and replaces
  141.         // it with HTML entities, this provides protection against
  142.         // email harvesters
  143.         static $search array('/(.)@(.)/se');
  144.  
  145.         static $replace array('"&#" .
  146.                                 sprintf("%03d", ord("\\1")) .
  147.                                 ";&#064;&#" .
  148.                                 sprintf("%03d", ord("\\2")) . ";";');
  149.  
  150.         if (is_array($var)) {
  151.             foreach ($var as $k => $v{
  152.                 $var[$kDataUtil::formatForDisplay($v);
  153.             }
  154.         else {
  155.             $var htmlspecialchars((string)$var);
  156.             $var preg_replace($search$replace$var);
  157.         }
  158.  
  159.         return $var;
  160.     }
  161.  
  162.  
  163.     /**
  164.      * Format a variable for HTML display. This method is recursive array safe.
  165.      *
  166.      * @param var        The variable to format
  167.      *
  168.      * @return The formatted variable
  169.      */
  170.     function formatForDisplayHTML ($var)
  171.     {
  172.         // This search and replace finds the text 'x@y' and replaces
  173.         // it with HTML entities, this provides protection against
  174.         // email harvesters
  175.         //
  176.         // Note that the use of \024 and \022 are needed to ensure that
  177.         // this does not break HTML tags that might be around either
  178.         // the username or the domain name
  179.         static $search array('/([^\024])@([^\022])/se');
  180.  
  181.         static $replace array('"&#" .
  182.                                 sprintf("%03d", ord("\\1")) .
  183.                                 ";&#064;&#" .
  184.                                 sprintf("%03d", ord("\\2")) . ";";');
  185.  
  186.         static $allowedtags NULL;
  187.         static $outputfilter;
  188.  
  189.         if (!isset($allowedtags)) {
  190.             $allowedHTML array();
  191.             $allowableHTML pnConfigGetVar('AllowableHTML');
  192.             if (is_array($allowableHTML)) {
  193.                 foreach($allowableHTML as $k => $v{
  194.                     if ($k == '!--'{
  195.                         if ($v <> 0{
  196.                             $allowedHTML["$k.*?--";
  197.                         }
  198.                     else {
  199.                         switch($v{
  200.                             case 0:
  201.                                 break;
  202.                             case 1:
  203.                                 $allowedHTML["/?$k\s*/?";
  204.                                 break;
  205.                             case 2:
  206.                                 // intelligent regex to deal with > in parameters, bug #1782 credits to jln
  207.                                 $allowedHTML["/?\s*$k"(\s+[\w:]+\s*=\s*(\"[^\"]*\"|'[^']*'))*" '\s*/?';
  208.                                 break;
  209.                         }
  210.                     }
  211.                 }
  212.             }
  213.  
  214.             if (count($allowedHTML0{
  215.                 // 2nd part of bugfix #1782
  216.                 $allowedtags '~<\s*(' join('|',$allowedHTML')\s*>~is';
  217.             else {
  218.                 $allowedtags '';
  219.             }
  220.         }
  221.  
  222.         if (!isset($outputfilter)) {
  223.             if (pnModAvailable('SecurityCenter'&& !defined('_PNINSTALLVER')) {
  224.                 $outputfilter pnConfigGetVar('outputfilter');
  225.             else {
  226.                 $outputfilter 0;
  227.             }
  228.         }
  229.  
  230.         if (is_array($var)) {
  231.             foreach ($var as $k => $v{
  232.                 $var[$kDataUtil::formatForDisplayHTML($v);
  233.             }
  234.         else {
  235.             // Run additional filters
  236.             if ($outputfilter 0{
  237.                 $var pnModAPIFunc('SecurityCenter''user''secureoutput'array('var' => $var'filter' => $outputfilter));
  238.             }
  239.  
  240.             // Preparse var to mark the HTML that we want
  241.             if (!empty($allowedtags)) {
  242.                 $var preg_replace($allowedtags"\022\\1\024"$var);
  243.             }
  244.  
  245.             // Encode email addresses
  246.             $var preg_replace($search$replace$var);
  247.  
  248.             // Fix html entities
  249.             $var htmlspecialchars($var);
  250.  
  251.             // Fix the HTML that we want
  252.             $var preg_replace_callback('/\022([^\024]*)\024/''DataUtil_pnVarPrepHTMLDisplay__callback'$var);
  253.  
  254.             // Fix entities if required
  255.             if (pnConfigGetVar('htmlentities')) {
  256.                 $var preg_replace('/&amp;([a-z#0-9]+);/i'"&\\1;"$var);
  257.             }
  258.         }
  259.  
  260.         return $var;
  261.     }
  262.  
  263.  
  264.     /**
  265.      * Format a variable for DB-storage. This method is recursive array safe.
  266.      *
  267.      * @param var        The variable to format
  268.      *
  269.      * @return The formatted variable
  270.      */
  271.     function formatForStore ($var)
  272.     {
  273.         if (is_array($var)) {
  274.             foreach ($var as $k=>$v{
  275.                 $var[$kDataUtil::formatForStore ($v);
  276.             }
  277.         else {
  278.             $dbType DBConnectionStack::getConnectionDBType();
  279.             if ($dbType=='mssql' || $dbType=='oci8' || $dbType=='oracle'{
  280.                 $var str_replace ("'""''"$var);
  281.             }
  282.             else
  283.                 $var addslashes($var);
  284.         }
  285.  
  286.         return $var;
  287.     }
  288.  
  289.  
  290.     /**
  291.      * Format a variable for operating-system usage. This method is recursive array safe.
  292.      *
  293.      * @param var        The variable to format
  294.      * @param absolute   Allow absolute paths (default=false) (optional)
  295.      *
  296.      * @return The formatted variable
  297.      */
  298.     function formatForOS ($var,$absolute=false)
  299.     {
  300.         if (is_array($var)) {
  301.             foreach ($var as $k=>$v{
  302.                 $var[$kDataUtil::formatForOS ($v);
  303.             }
  304.         else {
  305.             static $cached;
  306.             if ($cached == null)
  307.                 $cached array();
  308.  
  309.             if (isset($cached[$var]))
  310.                 return $cached[$var];
  311.             $orgVar $var;
  312.  
  313.             $clean_array array();
  314.  
  315.             //if we're supporting absolute paths and the first charater is a slash and , then
  316.             //an absolute path is passed
  317.             $absolutepathused ($absolute && substr($var,0,1== '/');
  318.  
  319.             // Split the path at possible path delimiters.
  320.             // Setting PREG_SPLIT_NOEMPTY eliminates double delimiters on the fly.
  321.             $dirty_array preg_split('#[:/\\\\]#'$var-1PREG_SPLIT_NO_EMPTY);
  322.  
  323.             // now walk the path and do the relevant things
  324.             foreach ($dirty_array as $current{
  325.                 if ($current == '.'{
  326.                     // current path element is a dot, so we don't do anything
  327.                 elseif ($current == '..'{
  328.                     // current path element is .., so we remove the last path in case of relative paths
  329.                     if (!$absolutepathused){
  330.                         array_pop($clean_array);
  331.                     }
  332.                 else {
  333.                     // current path element is valid, so we add it to the path
  334.                     $clean_array[$current;
  335.                 }
  336.             }
  337.  
  338.             // build the path
  339.             // should we use DIRECTORY_SEPARATOR here?
  340.             $var implode('/'$clean_array);
  341.             //if an absolute path was passed to the function, we need to make it absolute again
  342.             if ($absolutepathused){
  343.                 $var '/'.$var;
  344.             }
  345.  
  346.             // Prepare var
  347.             if (!$GLOBALS['PNRuntime']['magic_quotes_runtime']{
  348.                 $var addslashes($var);
  349.             }
  350.  
  351.             $cached[$orgVar$var;
  352.         }
  353.  
  354.         return $var;
  355.     }
  356.  
  357.     function formatForURL ($var)
  358.     {
  359.          return DataUtil::formatPermalink($var);
  360.     }
  361.  
  362.     function formatPermalink ($var)
  363.     {
  364.         static $permalinksseparator;
  365.         if (!isset($permalinksseparator)) {
  366.             $permalinksseparator pnConfigGetVar('shorturlsseparator');
  367.         }
  368.         $var strip_tags($var);
  369.         $var preg_replace("/&[#a-z0-9]+;/iU"""$var)// remove &....;
  370.         $var strtr($var," ",$permalinksseparator)//words separation
  371.  
  372.         if strtolower(_CHARSET!= 'utf-8' && strtolower(_CHARSET!= 'utf8' {
  373.             $var strtr($var,"ÀÁÂÃÄÅàáâãäåÒÓÔÕÖØòóôõöøÈÉÊËèéêëÇçÌÍÎÏìíîïÙÚÛÜùúûüÿÑñ","aaaaaaaaaaaaooooooooooooeeeeeeeecciiiiiiiiuuuuuuuuynn")//accents deletion
  374.             $var preg_replace("/[^a-z0-9_{$permalinksseparator}]/i"''$var);
  375.             $var trim($var$permalinksseparator);
  376.         else {
  377.             $res ini_get('mbstring.func_overload');
  378.             if $res 4{
  379.                 // any mb charsets and permalinks won't work
  380.                 // add: PHP_VALUE mbstring.func_overload 6
  381.                 // to your .htaccess or php.ini file
  382.                 // sure, a hack - needs to be replaced with a more generic check
  383.                 if (pnConfigGetVar('shorturls')  &&  pnConfigGetVar('language'== 'jpn' {
  384.                     $msg "put 'PHP_VALUE mbstring.func_overload 4' into .htaccess or php.ini - otherwise short urls won't work";
  385.                     LogUtil::registerError ($msg);
  386.                 }
  387.             }
  388.             $var ereg_replace("[[:space:]]"$permalinksseparator$var);                
  389.         }
  390.         return $var;
  391.     }
  392.  
  393.     /**
  394.      * Censor variable contents. This method is recursive array safe.
  395.      *
  396.      * @param var        The variable to censor
  397.      *
  398.      * @return The censored variable
  399.      */
  400.     function censor ($var)
  401.     {
  402.         static $doCensor;
  403.         if (!isset($doCensor)) {
  404.             $doCensor pnModAvailable('MultiHook');
  405.         }
  406.  
  407.         if (!$doCensor{
  408.             return $var;
  409.         }
  410.  
  411.         if (is_array($var)) {
  412.             foreach ($var as $k=>$v{
  413.                 $var[$kDataUtil::censor ($v);
  414.             }
  415.         else {
  416.             $var pnModAPIFunc('MultiHook','user','censor'array('word' => $var));  // preg_replace($search, $replace, $var);
  417.         }
  418.  
  419.         return $var;
  420.     }
  421.  
  422.  
  423.     /**
  424.      * Perform SHA1 or SHA256 hashing on a string using native
  425.      * PHP functions if available and if not uses own classes.
  426.      *
  427.      * @author Drak
  428.      * @param $string string to be hashed
  429.      * @param $type string md5, sha1 (default), sha256
  430.      * @return string hex hash
  431.      */
  432.     function hash ($string$type='sha1')
  433.     {
  434.         $type strtolower($type);
  435.         if ($type == 'sha1'{
  436.             return sha1($string);
  437.         }
  438.         else if ($type == 'sha256'{
  439.             if (function_exists('mhash')) {
  440.                 return bin2hex(mhash(MHASH_SHA256$string));
  441.             else {
  442.                 if (!class_exists('SHA256')) {
  443.                     Loader::requireOnce('includes/classes/hashes/sha256.class.php');
  444.                 }
  445.                 return SHA256::hash($string);
  446.             }
  447.         }
  448.         else if ($type == 'md5'{
  449.             return md5($string);
  450.         }
  451.  
  452.         return false;
  453.     }
  454.  
  455.     /**
  456.      * This method converts the several possible return values from
  457.      * allegedly "boolean" ini settings to proper booleans
  458.      * Properly converted input values are: 'off', 'on', 'false', 'true', '0', '1'
  459.      * If the ini_value doesn't match any of those, the value is returned as-is.
  460.      *
  461.      * @author Ed Finkler
  462.      * @param string $ini_key   the ini_key you need the value of
  463.      * @return boolean|mixed
  464.      */
  465.     function getBooleanIniValue($ini_key)
  466.     {
  467.         $ini_val ini_get($ini_key);
  468.         switch (strtolower($ini_val)) {
  469.             case 'off':
  470.                 return false;
  471.                 break;
  472.             case 'on':
  473.                 return true;
  474.                 break;
  475.             case 'false':
  476.                 return false;
  477.                 break;
  478.             case 'true':
  479.                 return true;
  480.                 break;
  481.             case '0':
  482.                 return false;
  483.                 break;
  484.             case '1':
  485.                 return true;
  486.                 break;
  487.             default:
  488.                 return $ini_val;
  489.         }
  490.     }
  491.  
  492.  
  493.     /**
  494.      * check for serialization
  495.      *
  496.      * @param string $string 
  497.      * @return bool 
  498.      */
  499.     function is_serialized($string)
  500.     {
  501.         if (is_string($string&& preg_match('/^(a|b|d|i|o|s)(.*);/si'$string)) {
  502.             return true;
  503.         }
  504.         return false;
  505.     }
  506.  
  507.     /**
  508.      * convertToUTF8()
  509.      * converts a string or an array (recursivly) to utf-8
  510.      *
  511.      * @param input - string or array to convert to utf-8
  512.      * @return converted string or array
  513.      * @author Frank Schummertz
  514.      *
  515.      */
  516.     function convertToUTF8($input='')
  517.     {
  518.         if (is_array($input)) {
  519.             $return array();
  520.             foreach($input as $key => $value{
  521.                 $return[$keyDataUtil::convertToUTF8($value);
  522.             }
  523.             return $return;
  524.         elseif (is_string($input)) {
  525.             if (function_exists('mb_convert_encoding')) {
  526.                 return mb_convert_encoding($input'UTF-8'_CHARSET);
  527.             else {
  528.                 return utf8_encode($input);
  529.             }
  530.         else {
  531.             return $input;
  532.         }
  533.     }
  534.  
  535.     /**
  536.      * convertFromUTF8()
  537.      * converts a string from utf-8
  538.      *
  539.      * @param input - string or array to convert from utf-8
  540.      * @return converted string
  541.      * @author Frank Schummertz
  542.      *
  543.      */
  544.     function convertFromUTF8($input='')
  545.     {
  546.         if (is_array($input)) {
  547.             $return array();
  548.             foreach($input as $key => $value{
  549.                 $return[$keyDataUtil::convertFromUTF8($value);
  550.             }
  551.             return $return;
  552.         elseif (is_string($input)) {
  553.             if (function_exists('mb_convert_encoding')) {
  554.                 return mb_convert_encoding($input_CHARSET'UTF-8');
  555.             else {
  556.                 return utf8_decode($input);
  557.             }
  558.         else {
  559.             return $input;
  560.         }
  561.     }
  562.  
  563. }
  564.  
  565.  
  566. /**
  567.  * Callback function for pnVarPrepHTMLDisplay
  568.  *
  569.  * @author Xaraya development team
  570.  * @access private
  571.  */
  572. function DataUtil_pnVarPrepHTMLDisplay__callback($matches)
  573. {
  574.     if (empty($matches)) {
  575.         return;
  576.     }
  577.  
  578.     $res '<' strtr($matches[1],
  579.                        array('&gt;' => '>',
  580.                              '&lt;' => '<',
  581.                              '&quot;' => '"'/*,
  582.                              '&amp;' => '&'*/)) '>';
  583.  
  584.     return $res;
  585. }

Documentation generated on Fri, 18 Jul 2008 21:44:32 +0200 by phpDocumentor 1.4.1