Server IP : 180.180.241.3 / Your IP : 216.73.216.252 Web Server : Microsoft-IIS/7.5 System : Windows NT NETWORK-NHRC 6.1 build 7601 (Windows Server 2008 R2 Standard Edition Service Pack 1) i586 User : IUSR ( 0) PHP Version : 5.3.28 Disable Function : NONE MySQL : ON | cURL : ON | WGET : OFF | Perl : OFF | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : C:/AppServ/www/app/webroot/news/administrator/components/com_jfusion/models/ |
Upload File : |
<?php /** * PHP version 5 * * @category JFusion * @package Models * @author JFusion Team <webmaster@jfusion.org> * @copyright 2008 JFusion. All rights reserved. * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL * @link http://www.jfusion.org */ // no direct access defined('_JEXEC') or die('Restricted access'); /** * Debugging functions for time * * @category JFusion * @package Models * @author JFusion Team <webmaster@jfusion.org> * @copyright 2008 JFusion. All rights reserved. * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL * @link http://www.jfusion.org */ class std { /** * getMicroTime * * @returns array the actual tim in seconds */ public static function getMicroTime() { list($usec, $sec) = explode(" ", microtime()); return ($usec + $sec); } /** * getRequest * merges HTTP_GET, HTTP_POST and HTTP-FILE requests together so that you have * afterwards an all in one array * * @param array $post The HTTP_POST request ($_POST) * @param array $get The HTTP-GET request ($_GET) * @param array $files The HTTP-FILE request, if a form uploaded Files ($_FILES) * * @uses arrayfunc::recursiveMerge * * @return array a recursively merged Array */ public static function getRequest($post, $get, $files) { // Setzt verschiedene $_REQUEST-Daten sinnvoll zusammen $files = std::rearrangeFiles($files); //debug::show($files); $request = arrayfunc::recursiveMerge($files, $get); //debug::show($request); $request = arrayfunc::recursiveMerge($request, $post); //debug::show($request); return $request; } /** * rearrangeFiles - PRIVATE * re-arranges the HTTP-FILE-REQUEST array so that its * organized like the POST and GET array afterwards * * @param array $files the raw FILE-Array * * @return array a POST/GET-Like structured Array */ private static function rearrangeFiles($files) { // Hilfsfunktion for std::getRequest() (recursive) $retArr = array(); foreach ($files as $key => $value) { if (arrayfunc::isOneDimensional($value)) { $retArr[$key] = $value; } else { $tmpArr = array(); foreach ($value as $httpKey => $subValue) { foreach ($subValue as $k => $v) { $tmpArr[$k][$httpKey] = $v; } } $retArr[$key] = std::rearrangeFiles($tmpArr); } } return $retArr; } /** * removeEmptyLines * * removes Empty Lines from a Text * * @param string $text the Text to remove the empty Lines From * @param string $newLineChar - OPTIONAL - the New-Line indicator, default is "\n" * * @return string the text without blank lines */ public static function removeEmptyLines($text, $newLineChar = "\n") { $lines = explode($newLineChar, $text); foreach ($lines as $idx => $line) { if (trim($line) == '') unset($lines[$idx]); } return join($newLineChar, $lines); } } /** * Main debugging class which is used for detailed outputs * * @category JFusion * @package Models * @author JFusion Team <webmaster@jfusion.org> * @copyright 2008 JFusion. All rights reserved. * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL * @link http://www.jfusion.org */ class debug { /** * Will get a globally defined JS-Function * - change the name if it messes up with your own JavaScript functions * - ..or set it to the empty-String to disable value-toggling */ static $toggleFunctionName = 'tns'; static $colorScheme = array(); static $colorSchemeInited = array(); static $toggleScriptInited = false; static $callback = null; /** * initializes the colorScheme * would be a Constructors task if the debug would be instantated, since in debug all methods are static, * call this method before the first time you need color scheme * * The meaning of the keys: * - vc = ValueColor, the background of shown Values * - akc = ArrayKeyColor, the background of array-Keys * - okc = ObjectKeyColor, the background of shown "object keys" i.e. the names of public accessible object/class-Variables * - tc = ValueColor, the background of the (optional) Title * - gc = ValueColor, the color of the structuring-grid, i.e. the background of the table */ private static function initColorScheme() { debug::$colorScheme[] = array('vc' => "#ecf8fd", 'akc' => "#dbfede", 'okc' => "#dbfede", 'tc' => '#d6f2ff', 'gc' => '#fbfed6'); debug::$colorScheme[] = array('vc' => "#f2bb94", 'akc' => "#cc9e7c", 'okc' => "#a68065", 'tc' => '#CCCCCC', 'gc' => '#AAAAFF'); debug::$colorScheme[] = array('vc' => "#faea37", 'akc' => "#d4c62f", 'okc' => "#ada226", 'tc' => '#CCCCCC', 'gc' => '#AAAAFF'); debug::$colorScheme[] = array('vc' => "#4bf8d0", 'akc' => "#3fd1af", 'okc' => "#33ab8f", 'tc' => '#CCCCCC', 'gc' => '#AAAAFF'); debug::$colorScheme[] = array('vc' => "#7a7a7a", 'akc' => "#a1a1a1", 'okc' => "#c7c7c7", 'tc' => '#CCCCCC', 'gc' => '#AAAAFF'); debug::$colorScheme[] = array('vc' => "#0099cc", 'akc' => "#009999", 'okc' => "#00ff00", 'tc' => '#CCCCCC', 'gc' => '#AAAAFF'); debug::$colorScheme[] = array('vc' => "#cfc", 'akc' => "#cf6", 'okc' => "#cf0", 'tc' => '#CCCCCC', 'gc' => '#AAAAFF'); debug::$colorScheme[] = array('vc' => "#ffc", 'akc' => "#ff6", 'okc' => "#ff0", 'tc' => '#CCCCCC', 'gc' => '#AAAAFF'); debug::$colorScheme[] = array('vc' => "#f96", 'akc' => "#c66", 'okc' => "#966", 'tc' => '#CCCCCC', 'gc' => '#AAAAFF'); } /** * Creates and returns the JavaScript-Snippet used to toggle values by klicking on the keys * returns the code only once, i.e. the first time, print it to the standard output if you get the snippet * * @return string */ private static function getToggleScript() { $script = ''; if (debug::$toggleScriptInited == false && debug::$toggleFunctionName != '') { $toggleFunctionName = debug::$toggleFunctionName; $script = '<script type="text/javascript">'; $script .= <<<JS function {$toggleFunctionName}(event) { var evtSource; if (window.event) evtSource = window.event.srcElement; else evtSource = event.target; while (evtSource.nextSibling == null) { evtSource = evtSource.parentNode; } var tNode = evtSource.nextSibling; while (tNode.nodeType != 1) { tNode = tNode.nextSibling; } tNode.style.display = (tNode.style.display != "none") ? 'none' : 'block'; } JS; $script .= '</script>'; debug::$toggleScriptInited = true; } return $script; } /** * Creates the style information for a color schema if needed * i.e. this schema is used the first time, print it to the standard output if you need it * * @param int $schema the index of the desired color schema * @return string style-code if needed */ private static function setStylesForScheme($schema) { $style = ''; if (count(debug::$colorScheme) == 0) debug::initColorScheme(); if (!isset(debug::$colorSchemeInited[$schema])) { $vc = debug::$colorScheme[$schema]['vc']; $akc = debug::$colorScheme[$schema]['akc']; $okc = debug::$colorScheme[$schema]['okc']; $tc = debug::$colorScheme[$schema]['tc']; $gc = debug::$colorScheme[$schema]['gc']; $style = '<style type="text/css">'; $style .= <<<CSS div.debug_{$schema} .value { min-width: 100px; background-color: {$vc}; } div.debug_{$schema} .a_key { min-width: 100px; background-color: {$akc}; } div.debug_{$schema} .o_key { min-width: 100px; background-color: {$okc}; } div.debug_{$schema} .title { background-color: {$tc}; } div.debug_{$schema} .grid { font-family:arial; background-color: {$gc}; vertical-align:top; } CSS; $style.= '</style>'; debug::$colorSchemeInited[$schema] = true; //print($style); } return $style; } /** ************************* * Craetes and returns a HTML-Code that shows nicely * the Structure and Value(s) of any PHP-Variable, the given Value can be from a simple Integer * to a complex object-structure. This function works recursively. * * @param mixed $arr the PHP-Variable to look in * @param mixed $start a title for the created structure-table, if numeric passed as $height * @param mixed $height optional height of scrollzone div, will be interpreted as the color schema if $start is interpreted as height * @param int $schema optional 0 - 9 colorscheme, will be ignored if $start is interpreted as height * * @return string a HTML-Code Snippet (e.g. to be Viewed in a Browser) ** ************************* */ public static function get($arr, $start = true, $height = false, $schema = 0) { $str = ''; $name = ''; if (is_numeric($start)) { // All Arguments "move" 1 to the left $height = $start; $start = true; } if (is_string($start)) { // Indicates that we are on "root"-Level $name = $start; $start = true; } if (is_array($arr) || is_object($arr)) { if ($start == true) { // the "root" run $neededScriptCode = debug::getToggleScript(); $neededStyleCode = debug::setStylesForScheme($schema); $styling = ''; if (is_numeric($height)) $styling = 'style="max-height:'.$height.'px; overflow:auto;'; $str = $neededScriptCode . '<div class="debug_'.$schema.'" '.$styling.'>'."\n" . $neededStyleCode; } $emptyWhat = 'empty-array'; $keyClass = 'a_key'; if (is_object($arr)) { $keyClass = 'o_key'; $emptyWhat = 'empty-object'; } if (debug::isOneDimensional($arr) && !$start) { if (count($arr) == 0) { $str.= '<span class="'.$keyClass.'">'.$emptyWhat.'</span><br>'."\n"; } foreach ($arr as $key => $value) { $style = ''; if (debug::$callback) { list($target,$function,$args) = debug::$callback; list($style,$value) = $target->$function($key,$value,$args); } $str.= '<span class="'.$keyClass.'" style="'.$style.'"> ' . debug::decorateValue($key) . '</span> '; $str.= '<span class="value" style="'.$style.'" > ' . debug::decorateValue($value) . '</span><br/>'; } } else { $onClick = ''; if (debug::$toggleFunctionName != '') $onClick = 'onclick="' . debug::$toggleFunctionName . '(event)"'; $str.= '<table class="grid" width="100%">'; if ($name != '') { $str.= '<thead '.$onClick.'><tr><th colspan="2" class="title">'.$name.'</th></tr></thead>'; } $str.= '<tbody>'; if (count($arr) == 0) { $str.= '<tr><td colspan="2" class="'.$keyClass.'">$emptyWhat</td></tr>'; } foreach ($arr as $key => $value) { $style = ''; if (debug::$callback) { list($target,$function,$args) = debug::$callback; list($style,$value) = $target->$function($key,$value,$args); } $str.= '<tr>'; $str.= '<td class="'.$keyClass.'" '.$onClick.' style="'.$style.'">'.debug::decorateValue($key).'</td>'; $str.= '<td class="value" style="'.$style.'">'.debug::get($value, false).'</td>'; $str.= '</tr>'; } $str.= '</tbody></table>'; } if ($start == true) { // the top-Level run $str.= '</div>'; } } else { // the "leave"-run $str = debug::decorateValue($arr); if ($name != '') $str = '<div class="debug_0"><table class="grid" width="100%"><thead onclick="tns(event)"><tr><th class="title">'.$name.'</th></tr></thead><tbody><tr><td class="a_key" onclick="tns(event)">'.$str.'</td></tr></tbody></table></div>'; //flush(); } return $str; } /** * Craetes and returns a String in html code. that shows nicely in copy paste * * @param mixed $arr : the PHP-Variable to look in * @param mixed $start : a title for the created structure-table * @param int $level * * @return string a html string with no tags */ public static function getText($arr, $start = true, $level=1) { $levelText = ''; for ($i = 0; $i < $level; $i++) { $levelText .= "\t"; } $str = ''; if (is_string($start)) { $str.= $start.' - ↓'."\n"; } if (is_array($arr) || is_object($arr)) { $emptyWhat = 'empty-array'; if (is_object($arr)) { $emptyWhat = 'empty-object'; } if (debug::isOneDimensional($arr)) { if (count($arr) == 0) { $str.= $levelText.$emptyWhat."\n"; } else { foreach ($arr as $key => $value) { if (debug::$callback) { list($target,$function,$args) = debug::$callback; list($style,$value) = $target->$function($key,$value,$args); } $str.= $levelText.$key.' → '.$value."\n"; } } } else { if (count($arr) == 0) { $str.= $emptyWhat."\n"; } else { foreach ($arr as $key => $value) { $emptyWhat = 'empty-array'; if (is_object($value)) { $emptyWhat = 'empty-object'; } if (debug::$callback) { list($target,$function,$args) = debug::$callback; list($style,$value) = $target->$function($key,$value,$args); } if ( is_array($value) || is_object($value) ) { if (count($value) == 0) { $str.= $emptyWhat."\n"; } $str.= $levelText.$key.' - ↓ '."\n".debug::getText($value, false,$level+1); } else { $str.= $levelText.$key.' → '.$value."\n"; } } } } } else { $str = $levelText.$arr."\n"; } return $str; } /** * Checks if an array is one-dimensional, i.e. if no one of the values is an array or abject again * The public version of this function is in arrayfunc, this here is just to use by debug::get * To avoid that the basic methods debug::get and debug::show have dependencies of other classes * * @param array|object $arr: the array to check * * @return boolean if it is one-dimensional */ private static function isOneDimensional($arr) { if (!is_array($arr) && !is_object($arr)) { $result = false; return $result; } foreach ($arr as $val) { if (is_array($val) || is_object($val)) { $result = false; return $result; } } $result = true; return $result; } /** * Same as debug::get, but prints the created HTML-Code directly to the Standard Output. * NOTE: This is the one and only debuging Tool!! * * @param mixed $arr the PHP-Variable to look in * @param mixed $title a title for the created structure-table * * @return void */ public static function show($arr, $title = false) { print (debug::get($arr, $title)); //flush(); } static $messungen; static $lastTime; /** * Starts a time measurement, deprecated, use starMessung and stopMessung instead. * * @param string $name: The name for this time measurement. * the measurement stops if this function is called again with another name. * measurements with the same name will be summated. * */ function messung($name) { $nowTime = std::getMicroTime(); if (!isset(debug::$messungen[$name])) debug::$messungen[$name] = 0; if (isset(debug::$lastTime)) { debug::$messungen[$name]+= (($nowTime - debug::$lastTime) * 1000); } debug::$lastTime = $nowTime; } /** * Shows the result of the measurements * Prints them HTML-Encoded to the Standard-Output (i.e. Browser) * * @uses debug::show() */ function showTime() { debug::show(debug::$messungen, "Zeitmessungen"); } /** * Returns the results of the measurements, HTML-Encoded * * @uses debug::get() * * @return string the HTML-Code */ function getTime() { return debug::get(debug::$messungen, "Zeitmessungen"); } /** * Shows the Stacktrace * * @uses debug::show() */ function showTrace() { $stack = debug_backtrace(); $niceStack = array(); for ($n = 1;$n < count($stack);$n++) { $key = "{$stack[$n]['file']} ({$stack[$n]['line']})"; $argv = array(); foreach ($stack[$n]['args'] as $arg) { $argv[] = var_export($arg, true); } $arglist = join(', ', $argv); $niceStack[$key] = $stack[$n]['class'] . $stack[$n]['type'] . $stack[$n]['function'] . '(' . $arglist . ')'; } debug::show($niceStack, "{$stack[0]['file']} ({$stack[0]['line']})"); } static $laufzeit = array(); static $laufzeitStack = array(); static $stackName = array(); /** * Starts a new (time-)measurement with the given Name * Measurements can be Started within other measurements * Measurements with the same can be started and stopped multiple times, they will be counted ans summated. * e.g. within once quicksort, 100 times "HD-read" and 40 times "HD-write" * - inner Measurements MUST be stopped before the outer measurment stops! * - all Measurements MUST be stopped before showing the Results! * * @param string $name The Name for this measurement (e.g. "Quicksearch") * the measurement stops stops if stopMessung is Called and the given name is identical * */ static function startMessung($name) { if (count(debug::$laufzeitStack) == 0) { $prtLaufzeit = & debug::$laufzeit; } else { $prtLaufzeit = & debug::$laufzeitStack[count(debug::$laufzeitStack) - 1]; } if (!isset($prtLaufzeit['childs'][$name])) { $prtLaufzeit['childs'][$name] = array('count' => 0, 'time' => 0); } $prtLaufzeit['childs'][$name]['start'] = std::getMicroTime(); debug::$laufzeitStack[count(debug::$laufzeitStack) ] = & $prtLaufzeit['childs'][$name]; debug::$stackName[count(debug::$stackName) ] = $name; } /** * stops the Measurement with teh given Name * * @param string $name the Name of the Measurement to stop */ static function stopMessung($name) { $tiefe = 0; for ($n = count(debug::$laufzeitStack) - 1;$n >= 0;$n--) { if (debug::$stackName[$n] == $name) $tiefe = max($tiefe, $n); } $cnt = count(debug::$laufzeitStack); for ($n = $tiefe;$n < $cnt;$n++) { $aktLz = & debug::$laufzeitStack[$n]; if ($n == $tiefe) { $aktLz['time']+= std::getMicroTime() - $aktLz['start']; $aktLz['count']++; } else { $aktLz['time']+= std::getMicroTime() - $aktLz['start']; $aktLz['count'] = 'Error, Measurement ' . debug::$stackName[$n] . ' not closed'; } unset(debug::$laufzeitStack[$n]); unset(debug::$stackName[$n]); } } /** * PRIVATE - This function works recursively. * * Rearranges the results from all Measurements so that they will get human-understandable * * @param array $laufzeit the raw-array produced by calling start- and stopMessung * * @return array a humen-understandable Version */ private static function createLaufzeitResult($laufzeit) { $result = array(); if (isset($laufzeit['childs'])) { $childTime = 0; if (isset($laufzeit['time'])) $result['Calls'] = $laufzeit['count']; foreach ($laufzeit['childs'] as $name => $child) { $result[$name] = debug::createLaufzeitResult($child); $childTime+= $child['time']; } if (isset($laufzeit['time'])) { $result['Difference'] = ($laufzeit['time'] - $childTime) * 1000; $result['TOTAL'] = $laufzeit['time'] * 1000; } } else { $result = array('Calls' => $laufzeit['count'], 'time' => $laufzeit['time'] * 1000); } return $result; } /** * Shows the measurements results (they from start- and stopMessung) * prints HTML-Encoded Results directly to the Standard-Output * * @uses debug::show() * */ function showLaufzeit() { $lz_nice = debug::createLaufzeitResult(debug::$laufzeit); debug::show($lz_nice, "Time measurements in ms"); } /** * Returns the measurements results HTML-Encoded(they from start- and stopMessung). * * @uses debug::get() * @return string the HTML-Code * */ function getLaufzeit() { $lz_nice = debug::createLaufzeitResult(debug::$laufzeit); // $str = debug::get(debug::$laufzeit, "Zeitmessungen in s"); return debug::get($lz_nice, "Time measurements in ms"); } /** * Prepares Values to be used in debug::show / debug::get used to indicate a values type * - Strings will be * - in double-quotes if they are empty (to see something) * - Normal if not empty * - < and > will be replaced by "<", ">" to avoid tag-Interpretation by a Browser * - boolean and all numbers will be bold. * - the null-Value will be bold and italic * * @param mixed $value the Value to HTML-Encode * * @return string the HTML-Encoded Value */ private static function decorateValue($value) { if (is_string($value)) { if (trim($value) == '') $decValue = '"'.$value.'"'; else $decValue = str_replace(array('<', '>'), array('<', '>'), $value); } else if (is_bool($value)) { if ($value) $decValue = 'true'; else $decValue = 'false'; $decValue = '<b>'.$decValue.'</b>'; } else if (is_null($value)) { $decValue = '<b><i>null</i></b>'; } else { $decValue = '<b>'.$value.'</b>'; } return $decValue; } } /** * Transposing functions * * @category JFusion * @package Models * @author JFusion Team <webmaster@jfusion.org> * @copyright 2008 JFusion. All rights reserved. * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL * @link http://www.jfusion.org */ class trans { static $jsSpecialChars = array("\\", '"', "\n", "\r"); static $jsReplaceTo = array("\\\\", '\"', '\n', '\r'); /** * Creates a JavaScript-Code that initializes a JavaScript Variable that contains * the value of the given PHP-Variable * * The PHP-Variable can be from a simple integer to a complex object / array * * @param string $jsVarName, the name the Variable should have in the JavaScript * @param mixed $phpvar, the Value the JS-Variable should be initialized with * @uses trans::phpValue2js() * * @return string, the JavaScriptCode */ function php2js($jsVarName, $phpvar) { $jsCode = 'var '.$jsVarName.' = ' . trans::phpValue2js($phpvar) . ";\n"; return $jsCode; } /** * Converts a PHP-Value into a JSON-String * This function works recursively * * @param mixed $phpValue: the Value to transform into JSON * @return string the JSON String */ public static function phpValue2js($phpValue) { $jsCode = false; if (is_long($phpValue)) $jsCode = $phpValue; if (is_float($phpValue)) $jsCode = $phpValue; if (is_integer($phpValue)) $jsCode = $phpValue; if (is_int($phpValue)) $jsCode = $phpValue; if (is_double($phpValue)) $jsCode = $phpValue; if (!$jsCode && $jsCode !== false) $jsCode = '0'; if (is_bool($phpValue)) { if ($phpValue) $jsCode = 'true'; else $jsCode = 'false'; } if (is_string($phpValue)) $jsCode = '"' . str_replace(trans::$jsSpecialChars, trans::$jsReplaceTo, $phpValue) . '"'; if (is_null($phpValue)) $jsCode = 'null'; if (is_array($phpValue)) { $elems = array(); $numeric = arrayfunc::is_numeric_array($phpValue); foreach ($phpValue as $key => $seg) { $part = array(); if ($numeric == false) $part[] = '"' . str_replace(trans::$jsSpecialChars, trans::$jsReplaceTo, $key) . '"'; $part[] = trans::phpValue2js($seg); $elems[] = join(':', $part); } if ($numeric) $jsCode = '[' . join(',', $elems) . ']'; else $jsCode = '{' . join(',', $elems) . '}'; } if ($jsCode == '') $jsCode = '"Type not supported yet"'; return $jsCode; /* If the JSON-Extention is available this would (hopefully) run much faster! $f = $r = array(); foreach (array_merge(range(0, 7), array(11), range(14, 31)) as $v) { $f[] = chr($v); $r[] = "\\u00".sprintf("%02x", $v); } return str_replace($f, $r, json_encode($phpValue)); */ } /* function jsEscape($val) { return str_replace(trans::$jsSpecialChars, trans::$jsReplaceTo, $val); } */ /** * Creates a PHP-Code that initializes a PHP Variable that contains * the value of the given PHP-Variable, this function works recursively. * * The PHP-Variable can be from a simple integer to a complex object / array * * @param string $phpVarName, the name the Variable should have * @param mixed $phpvar, the Value the New-Variable should be initialized with * @param string $firstDimSpacer - OPTIONAL - Just to butify the Output * * @return string, the PHP-Code */ public static function php2phpCode($phpVarName, $phpvar, $firstDimSpacer = '') { $phpCode = ''; $pre = '$'; if (is_numeric($phpvar)) $phpCode = $pre.$phpVarName.' = '.$phpvar.";\n"; if (is_bool($phpvar)) { if ($phpvar) $phpCode = $pre.$phpVarName.' = true;'."\n"; else $phpCode = $pre.$phpVarName.' = false;'."\n"; } if (is_string($phpvar) && !is_numeric($phpvar)) $phpCode = $pre.$phpVarName.' = "' . trans::replaceChars($phpvar) . '";'."\n"; if (is_null($phpvar)) $phpCode = $pre.$phpVarName.' = null;'."\n"; if (is_array($phpvar)) { if (arrayfunc::isOneDimensional($phpvar)) { $phpCode = $pre.$phpVarName.' = array('; foreach ($phpvar as $key => $value) { if (!is_numeric($value)) $value = trans::replaceChars($value); if (is_int($key) && $key >= 0) $phpCode.= "$key => \"$value\", "; else $phpCode.= "\"$key\" => \"$value\", "; } if (count($phpvar) > 0) { $phpCode = substr($phpCode, 0, -2); } $phpCode.= ");\n"; } else { $phpCode = $pre.$phpVarName.' = array();'."\n"; foreach ($phpvar as $key => $value) { if (is_int($key) && $key >= 0) $name = $phpVarName . '[' . $key . ']'; else $name = $phpVarName . '[\'' . $key . '\']'; $phpCode.= trans::php2phpCode($name, $value) . $firstDimSpacer; } } } if ($phpCode == '') $phpCode = $pre.$phpVarName.' = "Type not supported yet";'."\n"; return $phpCode; } /** * replaces Characters which would cause Problems in PHP-Code * * @param string $str: the raw String * @return string the escaped String */ public static function replaceChars($str) { $patterns = array("\"", "\n", "\t", "\r", '$'); $replacements = array("\\\"", "\\\n", "\\\t", "\\\r", "\\\\$"); return str_replace($patterns, $replacements, $str); } /** * converts a HTML-Encoded String into Plaintext * - all tags will be removed * - some special tabs will be replaced by a newline char * - the <td>-Tag will be replaced ba a tabulator Char * * @param string $htmlstr the HTML-Encoded String * @param string $newLineChar - OPTIONAL - the Character to be used as newline.Char, default: "\n" * @param string $tabChar - OPTIONAL - the Character to be used as tabulator.Char, default: "\t" * * @return string the plaintext */ function html2plaintext($htmlstr, $newLineChar = "\n", $tabChar = "\t") { $DEF_TAGLIST_LINEBREAK = array("br", "h1", "h2", "h3", "h4", "h5", "h6", "p", "div", "tr"); $DEF_TAGLIST_TAB = array("td"); $htmlstr = str_replace("\n", "", $htmlstr); $htmlstr = str_replace("\r", "", $htmlstr); $htmlstr = str_replace("<br>", $newLineChar, $htmlstr); foreach ($DEF_TAGLIST_LINEBREAK as $tag) { $htmlstr = str_replace("</$tag>", $newLineChar, $htmlstr); $htmlstr = str_replace("<$tag />", $newLineChar, $htmlstr); $htmlstr = str_replace("<$tag/>", $newLineChar, $htmlstr); } foreach ($DEF_TAGLIST_TAB as $tag) { $htmlstr = str_replace("</$tag>", $tabChar, $htmlstr); $htmlstr = str_replace("<$tag />", $tabChar, $htmlstr); $htmlstr = str_replace("<$tag/>", $tabChar, $htmlstr); } $str = trans::decodeHTML($htmlstr); return strip_tags($str); } /** * * NOT USED ANYMORE - HOPEFULLY * */ /* function conv($str, $what) { $what = strtoupper($what); switch ($what) { case 'IV': $str = str_replace("'", "'", $str); $str = str_replace('"', """, $str); break; case 'DBV': break; case 'URL': break; case 'JS': $str = addcslashes(addslashes($str), "\n,\r,\t"); break; case 'SAMP': break; } return $str; } */ /** * Explodes a string into a Hashtable * * @param string $delim1, the delimiter that separates the entries * @param string $delim2, the delimiter that separates the key from the Value * @param string $string the String to explode * * Example : String: "width: 100px; height:50px" * delim1: ";" * delim2: ":" * ==> array('width' => '100px', 'height':'50px'); * * @return array the created hashtable */ function hashExplode($delim1, $delim2, $string) { if ($string == '') return array(); $arr = explode($delim1, $string); $hashy = array(); foreach ($arr as $zuw) { $arr2 = explode($delim2, $zuw); if (count($arr2) == 1) $hashy[$arr2[0]] = $arr2[0]; // 040928 hinzugef�gt (tylmann) if (count($arr2) == 2) $hashy[$arr2[0]] = $arr2[1]; if (count($arr2) > 2) $hashy[array_shift($arr2) ] = implode($delim2, $arr2); // 040928 hinzugef�gt (tylmann) } return $hashy; } /** * Joins a Hashtable to a String * * Just the opposite of trans::hashExplode * * @param string $delim1, the delimiter that separates the entries * @param string $delim2, the delimiter that separates the key from the Value * @param array $hashy the Hashtable to join * * @return string the created string */ function hashJoin($delim1, $delim2, $hashy) { $arr = array(); foreach ($hashy as $key => $val) { $arr[] = $key . $delim2 . $val; } return join($delim1, $arr); } /** * Like trans::hashJoin except the the Values will be Quoted with the giver Quote Character * * Useful to build-up attribute-lists for HTML Tags * * @param array $hashy the Hashtable to join * @param string $delim, the delimiter that separates the entries, typically ' ' * @param string $Quote, The Character used to Quote the Values, typically '"' * @param string $equiv, the delimiter that separates the key from the Value, typically '=' * * @return string the created string */ function joinToAttrList($hashy, $delim, $Quote, $equiv) { $arr = array(); foreach ($hashy as $key => $val) { $val = htmlentities($val); $arr[] = $key . $equiv . $Quote . $val . $Quote; } return join($delim, $arr); } /** * Creates a Mail-Header String from the given hashtable * * @param array $header the Hashtable to use * * a shortcut for trans::hashJoin("\r\n", ": ", $header); * * @return string the created string */ function mailHeaderFromHash($header) { $headers = ''; foreach ($header as $arg => $value) { $headers.= "$arg: $value\r\n"; } return $headers; } /** * Builds up the query-part of an URL that represents the given data * data can be from a simple integer up to a complex object / array * This function works recursively * If a complex array/object is given the keys will be the Variablenames in the query * * NOTE: Due to an URL-Query must by a String this function is NOT type-safe * * @param mixed $data, the data that should be contained in the Query * @param string $prefix, the name of the Variable in the query, optional if the given Data is an array/object * * @return string the URL-Query, values will be URL-Encoded */ public static function http_build_query($data, $prefix = '') { if (!is_array($data) && !is_object($data)) { return $prefix . '=' . urlencode($data); } $cmds = array(); foreach ($data as $key => $value) { if ($prefix != '') $cmds[] = trans::http_build_query($value, $prefix . '[' . $key . ']'); else $cmds[] = trans::http_build_query($value, $key); } foreach ($cmds as $idx => $cmd) { if ($cmd == '') unset($cmds[$idx]); // avoid empty-arrays } return join('&', $cmds); } /** * Builds up an array from an XML-Encoded String * * NOTE: On error a HTML-formatted Error Message will be sent to the standard output. * This is to simplify debugging, remove this in production releases or use ob_start() and ob_clean() * * @param string $xml, the XML-String to interpreted * @return array the built up array representing the XML-String, false if it fails */ function xml2array($xml) { $xp = xml_parser_create(); xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, false); xml_parser_set_option($xp, XML_OPTION_SKIP_WHITE, true); xml_parse_into_struct($xp, trim($xml), $vals, $index); $err = xml_get_error_code($xp); $result = false; if ($err != 0) { $error['Code'] = $err; $error['Text'] = xml_error_string($err); $error['Zeile'] = xml_get_current_line_number($xp); $error['Spalte'] = xml_get_current_column_number($xp); $error['Byte'] = xml_get_current_byte_index($xp); debug::show($error, "XML-Fehler"); } else { $data = array(); $parentList = array($data); foreach ($vals as $value) { $parent = & $parentList[count($parentList) - 1]; if ($value['value'] == null) $value['value'] = ''; switch ($value['type']) { case 'open': $node = array('tag' => $value['tag'], 'attributes' => $value['attributes'], 'value' => $value['value'], 'childs' => array()); $parent['childs'][] = $node; $parentList[count($parentList) ] = & $parent['childs'][count($parent['childs']) - 1]; break; case 'complete': $node = array('tag' => $value['tag'], 'attributes' => $value['attributes'], 'value' => $value['value'], 'childs' => array()); $parent['childs'][] = $node; break; case 'close': unset($parentList[count($parentList) - 1]); break; } } $result = $data['childs'][0]; } xml_parser_free($xp); return $result; } /** * Decodes HTML-Entities (>, ä , etc..) * * @param string $string, the string to decode * @return string, the String Where the HTML Entities are replaced by "normal" Characters */ private static function decodeHTML($string) { $string = strtr($string, array_flip(get_html_translation_table(HTML_ENTITIES))); $string = preg_replace("/&#([0-9]+);/me", "chr('\\1')", $string); return $string; } } /** * Array functions * * @category JFusion * @package Models * @author JFusion Team <webmaster@jfusion.org> * @copyright 2008 JFusion. All rights reserved. * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL * @link http://www.jfusion.org */ class arrayfunc { var $EQUAL = '='; var $LIKE = 'LIKE'; var $SMALLER = '<'; var $GREATER = '>'; /** * Sorts a 2-Dimensional Array, the intention is to sort arrays like Tables in SQL (by "Column") * So the $data should be an array of "rows" (represented as Hashtable where the Key will be the * "column-name" and the Value the Velu od the actual Cell), the keys in each row should be the same * * @param array $data, the data to sort, an array of rows * @param mixed $criteria, the "columnname" to sort, can be comma-separated e.g. "date,time"; * can also be an array e.g. array('date', 'time'); * @param mixed $direction the sort Direction ASC or DESC, OPTIONAL, ASC is default * can also be comma-separated or array, MUST have the same "length" as $criteria * @param boolean $holdIndizes - OPTIONAL, default: false, if the indizes of the "rows" should stay at their * rows. This is useful if the row-indizes represent e.g. * - the Primary keys of the according Database-Entries * - Filenames * - URL's, etc... * * * @return array the sorted array * * NOTE: - To test what happens with the different options use debug::show() before and after sorting * - Runtime: O(n * ln(n)) if one criteria is given, O(m * (n * ln(n)) if m criterias given (worst case!!) */ public static function tableSort($data, $criteria, $direction = 'ASC', $holdIndizes = false) { debug::startMessung('tableSort'); $sortArr = array(); $retArr = array(); if (!is_array($criteria)) $criteria = explode(',', $criteria); if (!is_array($direction)) $direction = explode(',', $direction); $thisCrit = $criteria[0]; $thisDir = $direction[0]; unset($criteria[0]); unset($direction[0]); foreach ($data as $idx => $row) { $sortArr[$row[$thisCrit]][$idx] = $row; } if (count($criteria) > 0) { if (count($direction) == 0) $direction = array(); foreach ($sortArr as $critValue => $matches) { $sortArr[$critValue] = arrayfunc::tableSort($matches, join(',', $criteria), join(',', $direction), $holdIndizes); } } if (strtolower($thisDir) == 'desc') krsort($sortArr); else ksort($sortArr); foreach ($sortArr as $subArr) { foreach ($subArr as $idx => $row) { if ($holdIndizes) $retArr[$idx] = $row; else $retArr[] = $row; } } debug::stopMessung('tableSort'); return $retArr; } /*------------ HOW TO ------------------------- $data : 2 Dimensionales Array, keys des 2. Dimension kommen als Kriterium in Frage $criteria : String oder 1-Dimsionales Array von kriterien, meherere Krinerien k�nnen auch komma-getrennt als String �bergeben werden --------------------------------------------------*/ /** * Groups a 2-Dimensional Array. Like in tableSort the imagination is that we Group a Table * The data must be an Array of "rows", row must be Hashtables (colname => cellValue) * * This function groups all rows together where the "cellValue" of the given "column" is the same * One can also say separates the given Array n Parts where n is the number of different entries in the * given "column" * * @param array $data, the data to Group * @param mixed $criteria, the Column to use for the separation, can also be a comma-separated string or * an array * @param boolean $holdIndizes - OPTIONAL, default: false, if the indizes of the "rows" should stay at their * rows. This is useful if the row-indizes represent e.g. * - the Primary keys of the according Database-Entries * - Filenames * - URL's, etc... * @return array the grouped data * * NOTE: - To test what happens with the different options use debug::show() before and after grouping * - Runtime: O(n) if one criteria is given O(m * n) if m criterias given */ public static function tableGroup($data, $criteria, $holdIndizes = false) { debug::startMessung('tableGroup'); $groupedArr = array(); if (!is_array($criteria)) $criteria = explode(',', $criteria); $thisCrit = trim($criteria[0]); unset($criteria[0]); foreach ($data as $idx => $row) { if ($holdIndizes) $groupedArr[$row[$thisCrit]][$idx] = $row; else $groupedArr[$row[$thisCrit]][] = $row; } if (count($criteria) > 0) { foreach ($groupedArr as $critValue => $matches) { $groupedArr[$critValue] = arrayfunc::tableGroup($matches, join(',', $criteria)); } } debug::stopMessung('tableGroup'); return $groupedArr; } /** * A Bit like tableGroup, but assumes that the values in the grouping-Column(s) are unique * => so not an Array of rows will be contained in each section of the grouped array but only * that single row where the grouping-Column has this value! * * @param array $data the data to Group * @param mixed $criteria the Column to use for the separation, can also be a comma-separated string or an array * @param mixed $field - OPTIONAL - if you are not interested in the whole Row in each section but only one * "cell-Value" u can specify from which column this value should be taken. * * @return array the grouped data * * NOTE: - To test what happens with the different options use debug::show() before and after grouping * - Runtime: O(n) if one criteria is given O(m * n) if m criterias given * - YOU as user of this function are responsible that the values in the grouping "Column" are unique * !! IF NOT YOU WILL LOOSE DATA WITHOUT WARNING !! */ public static function uniqueTableGroup($data, $criteria, $field = false) { debug::startMessung('uniqueTableGroup'); $groupedArr = array(); if (!is_array($criteria)) $criteria = explode(',', $criteria); $thisCrit = trim($criteria[0]); foreach ($data as $row) { if (count($criteria) == 1) { if ($field == false) $groupedArr[$row[$thisCrit]] = $row; else $groupedArr[$row[$thisCrit]] = $row[$field]; } else { $groupedArr[$row[$thisCrit]][] = $row; } } unset($criteria[0]); if (count($criteria) > 0) { foreach ($groupedArr as $critValue => $matches) { $groupedArr[$critValue] = arrayfunc::uniqueTableGroup($matches, join(",", $criteria), $field); } } debug::stopMessung('uniqueTableGroup'); return $groupedArr; } /** * Used for an SQL-Like Descriptive search for "records" * Like at the other tableXXX functions the imagination is to have an Array * of Hashtables representing the rows of a table. The hashkeys will specify the column. * * Runs through the given dataArray and returns all rows in a new array which mach * with the given filter. A Filter must at least consist out of an "column"-Name (the hashkey * of the "Rows" to use) an operator and a value. More than one filter can be given. * * @param array $data, tha data to filter. * @param mixed $filter filter the Filter tu use. * * Filterformats: * - 1. as String : 1a [Column] [operator] [value]: "name = Hans", the spaces must be set! * or 1b [Column] [operator] [value] AND [Column] [operator] [value]: "name = Hans AND firstname = Andi" * - Only "AND" is possible * - 2. As Array : 2a: array(Column, operator, value) : array('name', '=', 'Hans'); * 2b: an array of Strings formatted as shown in 1a: array("name = Hans", "firstname = Andi"); * 2c: an array of arrays formatted as shown in 2a * Possible operators: "=", "LIKE", "<", ">" * * @return array the filtered rows */ public static function tableFilter($data, $filter) { $operatorOrder = array('=', 'LIKE', '<', '>'); $filter = arrayfunc::parseFilter($filter, $operatorOrder); $filters = arrayfunc::tableGroup($filter, 1); foreach ($operatorOrder as $operator) { if (isset($filters[$operator])) { foreach ($filters[$operator] as $actualFilter) { $data = arrayfunc::primitiveFilter($data, $actualFilter[0], $actualFilter[1], $actualFilter[2]); } } } return $data; } /** * Summates all values of a particular column * * @param array $data: an Array of "tableRows", tablerows as a Hashtable colName => value * @param string $field: the column to summate * * @return number, the sum of the spec. column, * */ function tableSum($data, $field) { $sum = 0; foreach ($data as $row) { $sum+= $row[$field]; } return $sum; } /** * Checks if an array is a Hashtable (i.e. it is NOT a numeric array) * * @param array $var: the array to check * * @return boolean if it is associative */ function is_assoc_array($var) { if (!is_array($var)) { $result = false; return $result; } $n = 0; foreach ($var as $key => $value) { if ($key != $n || !is_int($key)) { $result = true; return $result; } $n++; } $result = false; return $result; } /** * Checks if an array is numeric, i.e. if all keys are integer and * and countin up form 0 to the (length - 1) of the array. * * @param array $var: the array to check * * @return boolean if it is numeric */ public static function is_numeric_array($var) { if (!is_array($var)) { $result = false; return $result; } $n = 0; foreach ($var as $key => $value) { if (!($key === $n)) { $result = false; return $result; } $n++; } $result = true; return $result; } /** * Checks if an array is one-dimensional, i.e. if no one of the values is an array or abject again * * @param array $arr: the array to check * * @return boolean if it is one-dimensional */ public static function isOneDimensional($arr) { if (!is_array($arr) && !is_object($arr)) { $result = false; return $result; } foreach ($arr as $val) { if (is_array($val) || is_object($val)) { $result = false; return $result; } } $result = true; return $result; } /** * Parses a filter given to the tableFilter function into an 2-dimensional array that represents * the filter-format 2c described in tableFilter * * @param mixed $filter the filter given to the tableFilter function (cam be any Variant, from 1a to 2c) * @param array $operators the known operators * * @return mixed the 2c-like formatted filter array * * @see arrayfunc::tableFilter */ private static function parseFilter($filter, $operators) { if (is_string($filter)) { $filter = explode(' AND ', $filter); } if (count($filter) == 3 && in_array($filter[1], $operators)) { $newFilter = array($filter); $filter = $newFilter; } else { foreach ($filter as $idx => $fil) { if (is_string($fil)) $filter[$idx] = explode(' ', $fil); } } return $filter; } /** * Filters an array of Hashtbales * * @param array $data the data to filter * @param string $field, specifies the hash-key to compare * @param string $operator, specifies the comparison operator to use: one of : "=", "<", ">", "LIKE" * @param string $value, the value the the compared value should have (or should being greater..) * * @return array an array of these hashtables which matched * * @see arrayfunc::tableFilter, this function is internally user by tableFilter */ private static function primitiveFilter($data, $field, $operator, $value) { // show("PrimitiveFiltering: $field, $operator, $value<br>\n"); $result = array(); foreach ($data as $row) { if (arrayfunc::compare($row[$field], $operator, $value)) { // print("Vergleich {$row[$field]}, $operator, $value, OK<br>\n"); $result[] = $row; } else { // print("Vergleich {$row[$field]}, $operator, $value, FEHLGESHLAGEN<br>\n"); } } return $result; } /** * Compares 2 Values * * @param string $LHS the Left-Hand-Side Value * @param string $operator, specifies the comparison operator to use: one of : "=", "<", ">", "LIKE" * @param string $RHS the Right-Hand-Side Value * * @return boolean if the LHS and RHS match (according to the given operator) */ private static function compare($LHS, $operator, $RHS) { if ($operator == '=') return ($LHS == $RHS); if ($operator == '<') return ($LHS < $RHS); if ($operator == '>') return ($LHS > $RHS); if ($operator == 'LIKE') return arrayfunc::likeCompare($LHS, $RHS); $result = false; return $result; } /** * Performs a Database LIKE-Compare, Case-Insensitive * '%' as wild-card is understood, '_' as char for exactly one Character NOT * * @param string $value the value to check * @param string $pattern the "target"-Value that my contain the wildcards * * @return boolean, if the value matches the given pattern */ private static function likeCompare($value, $pattern) { $pattern = strtolower($pattern); // Damit das ganze Case-INsensitive l�uft $value = strtolower($value); $pttrn = explode('%', $pattern); $lastIdx = count($pttrn) - 1; if ($lastIdx == 0) return ($pattern == $value); $failed = false; foreach ($pttrn as $idx => $str) { if ($str != '' && $failed === false) { $pos = strpos($value, $str); if ($pos === false) $failed = true; // str gar nicht vorhanden => RAUS if ($idx == 0 && $pos > 0) $failed = true; // anfang, pos muss = 0 sein sonst => RAUS if ($idx == $lastIdx) { $pos = strrpos($value, $str); if ($pos != strlen($value) - strlen($str)) $failed = true; // letzes, pos muss am ende sein, sonst => RAUS } if ($failed === false) { $value = substr($value, $pos + strlen($str)); // Alles vor und mit dem gefundenen Wert abhacken. } } } return ($failed === false); } /** * Uses an array of arrays, retrieves maximum length of the arrays contained in the give array * * @param array $arr an array of arrays; * * @return int the maximum length; */ function getMax2ndDimLength($arr) { $max = 0; foreach ($arr as $value) { if (is_array($value)) $max = max($max, count($value)); } return $max; } /** * Recursively merges two arrays * If two keys are identical the second one will be chosen * If two identical keys are integer both will be taken * * @param array $arr1, the first array * @param array $arr2, the second array * * @return array the merged array */ public static function recursiveMerge($arr1, $arr2) { if (is_array($arr1) && is_array($arr2)) { $result = $arr1; foreach ($arr2 as $key => $value) { if (isset($result[$key])) { if (is_integer($key) && !(is_array($result[$key]) && (is_array($arr2[$key])))) $result[] = $value; else $result[$key] = arrayfunc::recursiveMerge($result[$key], $arr2[$key]); } else { $result[$key] = $value; } } } else { $result = $arr2; } return $result; } /** * Generates a list of all values of a given "column" in a array of Hashtables * * @param array $data the array of hastables to use * @param string $fieldName the hashkey of the value to be taken into the list * @param boolean $holdIndizes - OPTIONAL - if the indizes in the list should be the same as in the dataset * default: false => the list will be a numeric array from 0 to length-1 * true => use this option if the indizes of the array represtent e.g. database Primary keys * * @return array the newly generated list */ function getListOfField($data, $fieldName, $holdIndizes = false) { $liste = array(); foreach ($data as $idx => $row) { if ($holdIndizes) $liste[$idx] = $row[$fieldName]; else $liste[] = $row[$fieldName]; } return $liste; } }