mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-23 18:48:51 +02:00
Moved under "trunk" to be able to track releases under "tags"
SVN:trunk[55]
This commit is contained in:
491
core/MyHelpers.class.inc.php
Normal file
491
core/MyHelpers.class.inc.php
Normal file
@@ -0,0 +1,491 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* MyHelpers
|
||||
* various dev/debug helpers, to cleanup or at least re-organize
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
|
||||
class MyHelpers
|
||||
{
|
||||
public static function CheckValueInArray($sDescription, $value, $aData)
|
||||
{
|
||||
if (!in_array($value, $aData))
|
||||
{
|
||||
self::HandleWrongValue($sDescription, $value, $aData);
|
||||
}
|
||||
}
|
||||
|
||||
public static function CheckKeyInArray($sDescription, $key, $aData)
|
||||
{
|
||||
if (!array_key_exists($key, $aData))
|
||||
{
|
||||
self::HandleWrongValue($sDescription, $key, array_keys($aData));
|
||||
}
|
||||
}
|
||||
|
||||
public static function HandleWrongValue($sDescription, $value, $aData)
|
||||
{
|
||||
if (count($aData) == 0)
|
||||
{
|
||||
$sArrayDesc = "{}";
|
||||
}
|
||||
else
|
||||
{
|
||||
$sArrayDesc = "{".implode(", ", $aData)."}";
|
||||
}
|
||||
// exit!
|
||||
throw new CoreException("Wrong value for $sDescription, found '$value' while expecting a value in $sArrayDesc");
|
||||
}
|
||||
|
||||
// getmicrotime()
|
||||
// format sss.mmmuuupppnnn
|
||||
public static function getmicrotime()
|
||||
{
|
||||
list($usec, $sec) = explode(" ",microtime());
|
||||
return ((float)$usec + (float)$sec);
|
||||
}
|
||||
|
||||
/*
|
||||
* MakeSQLComment
|
||||
* converts hash into text comment which we can use in a (mySQL) query
|
||||
*/
|
||||
public static function MakeSQLComment ($aHash)
|
||||
{
|
||||
if (empty($aHash)) return "";
|
||||
$sComment = "";
|
||||
{
|
||||
foreach($aHash as $sKey=>$sValue)
|
||||
{
|
||||
$sComment .= "\n-- ". $sKey ."=>" . $sValue;
|
||||
}
|
||||
}
|
||||
return $sComment;
|
||||
}
|
||||
|
||||
public static function var_dump_html($aWords, $bFullDisplay = false)
|
||||
{
|
||||
echo "<pre>\n";
|
||||
if ($bFullDisplay)
|
||||
{
|
||||
print_r($aWords); // full dump!
|
||||
}
|
||||
else
|
||||
{
|
||||
var_dump($aWords); // truncate things when they are too big
|
||||
}
|
||||
echo "\n</pre>\n";
|
||||
}
|
||||
|
||||
public static function arg_dump_html()
|
||||
{
|
||||
echo "<pre>\n";
|
||||
echo "GET:\n";
|
||||
var_dump($_GET);
|
||||
echo "POST:\n";
|
||||
var_dump($_POST);
|
||||
echo "\n</pre>\n";
|
||||
}
|
||||
|
||||
public static function var_dump_string($var)
|
||||
{
|
||||
ob_start();
|
||||
print_r($var);
|
||||
$sRet = ob_get_clean();
|
||||
return $sRet;
|
||||
}
|
||||
|
||||
protected static function first_diff_line($s1, $s2)
|
||||
{
|
||||
$aLines1 = explode("\n", $s1);
|
||||
$aLines2 = explode("\n", $s2);
|
||||
for ($i = 0 ; $i < min(count($aLines1), count($aLines2)) ; $i++)
|
||||
{
|
||||
if ($aLines1[$i] != $aLines2[$i]) return $i;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected static function highlight_line($sMultiline, $iLine, $sHighlightStart = '<b>', $sHightlightEnd = '</b>')
|
||||
{
|
||||
$aLines = explode("\n", $sMultiline);
|
||||
$aLines[$iLine] = $sHighlightStart.$aLines[$iLine].$sHightlightEnd;
|
||||
return implode("\n", $aLines);
|
||||
}
|
||||
|
||||
protected static function first_diff($s1, $s2)
|
||||
{
|
||||
// do not work fine with multiline strings
|
||||
$iLen1 = strlen($s1);
|
||||
$iLen2 = strlen($s2);
|
||||
for ($i = 0 ; $i < min($iLen1, $iLen2) ; $i++)
|
||||
{
|
||||
if ($s1[$i] !== $s2[$i]) return $i;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected static function last_diff($s1, $s2)
|
||||
{
|
||||
// do not work fine with multiline strings
|
||||
$iLen1 = strlen($s1);
|
||||
$iLen2 = strlen($s2);
|
||||
for ($i = 0 ; $i < min(strlen($s1), strlen($s2)) ; $i++)
|
||||
{
|
||||
if ($s1[$iLen1 - $i - 1] !== $s2[$iLen2 - $i - 1]) return array($iLen1 - $i, $iLen2 - $i);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected static function text_cmp_html($sText1, $sText2, $sHighlight)
|
||||
{
|
||||
$iDiffPos = self::first_diff_line($sText1, $sText2);
|
||||
$sDisp1 = self::highlight_line($sText1, $iDiffPos, '<div style="'.$sHighlight.'">', '</div>');
|
||||
$sDisp2 = self::highlight_line($sText2, $iDiffPos, '<div style="'.$sHighlight.'">', '</div>');
|
||||
echo "<table style=\"valign=top;\">\n";
|
||||
echo "<tr>\n";
|
||||
echo "<td><pre>$sDisp1</pre></td>\n";
|
||||
echo "<td><pre>$sDisp2</pre></td>\n";
|
||||
echo "</tr>\n";
|
||||
echo "</table>\n";
|
||||
}
|
||||
|
||||
protected static function string_cmp_html($s1, $s2, $sHighlight)
|
||||
{
|
||||
$iDiffPos = self::first_diff($s1, $s2);
|
||||
if ($iDiffPos === false)
|
||||
{
|
||||
echo "strings are identical";
|
||||
return;
|
||||
}
|
||||
$sStart = substr($s1, 0, $iDiffPos);
|
||||
|
||||
$aLastDiff = self::last_diff($s1, $s2);
|
||||
$sEnd = substr($s1, $aLastDiff[0]);
|
||||
|
||||
$sMiddle1 = substr($s1, $iDiffPos, $aLastDiff[0] - $iDiffPos);
|
||||
$sMiddle2 = substr($s2, $iDiffPos, $aLastDiff[1] - $iDiffPos);
|
||||
|
||||
echo "<p>$sStart<span style=\"$sHighlight\">$sMiddle1</span>$sEnd</p>\n";
|
||||
echo "<p>$sStart<span style=\"$sHighlight\">$sMiddle2</span>$sEnd</p>\n";
|
||||
}
|
||||
|
||||
protected static function object_cmp_html($oObj1, $oObj2, $sHighlight)
|
||||
{
|
||||
$sObj1 = self::var_dump_string($oObj1);
|
||||
$sObj2 = self::var_dump_string($oObj2);
|
||||
return self::text_cmp_html($sObj1, $sObj2, $sHighlight);
|
||||
}
|
||||
|
||||
public static function var_cmp_html($var1, $var2, $sHighlight = 'color:red; font-weight:bold;')
|
||||
{
|
||||
if (is_object($var1))
|
||||
{
|
||||
return self::object_cmp_html($var1, $var2, $sHighlight);
|
||||
}
|
||||
else if (count(explode("\n", $var1)) > 1)
|
||||
{
|
||||
// multiline string
|
||||
return self::text_cmp_html($var1, $var2, $sHighlight);
|
||||
}
|
||||
else
|
||||
{
|
||||
return self::string_cmp_html($var1, $var2, $sHighlight);
|
||||
}
|
||||
}
|
||||
|
||||
public static function get_callstack_html($iLevelsToIgnore = 0, $aCallStack = null)
|
||||
{
|
||||
if ($aCallStack == null) $aCallStack = debug_backtrace();
|
||||
|
||||
$aCallStack = array_slice($aCallStack, $iLevelsToIgnore);
|
||||
|
||||
$aDigestCallStack = array();
|
||||
$bFirstLine = true;
|
||||
foreach ($aCallStack as $aCallInfo)
|
||||
{
|
||||
$sLine = empty($aCallInfo['line']) ? "" : $aCallInfo['line'];
|
||||
$sFile = empty($aCallInfo['file']) ? "" : $aCallInfo['file'];
|
||||
$sClass = empty($aCallInfo['class']) ? "" : $aCallInfo['class'];
|
||||
$sType = empty($aCallInfo['type']) ? "" : $aCallInfo['type'];
|
||||
$sFunction = empty($aCallInfo['function']) ? "" : $aCallInfo['function'];
|
||||
|
||||
if ($bFirstLine)
|
||||
{
|
||||
$bFirstLine = false;
|
||||
// For this line do not display the "function name" because
|
||||
// that will be the name of our error handler for sure !
|
||||
$sFunctionInfo = "N/A";
|
||||
}
|
||||
else
|
||||
{
|
||||
$args = '';
|
||||
if (empty($aCallInfo['args'])) $aCallInfo['args'] = array();
|
||||
foreach ($aCallInfo['args'] as $a)
|
||||
{
|
||||
if (!empty($args))
|
||||
{
|
||||
$args .= ', ';
|
||||
}
|
||||
switch (gettype($a))
|
||||
{
|
||||
case 'integer':
|
||||
case 'double':
|
||||
$args .= $a;
|
||||
break;
|
||||
case 'string':
|
||||
$a = Str::pure2html(self::beautifulstr($a, 1024, true, true));
|
||||
$args .= "\"$a\"";
|
||||
break;
|
||||
case 'array':
|
||||
$args .= 'Array('.count($a).')';
|
||||
break;
|
||||
case 'object':
|
||||
$args .= 'Object('.get_class($a).')';
|
||||
break;
|
||||
case 'resource':
|
||||
$args .= 'Resource('.strstr($a, '#').')';
|
||||
break;
|
||||
case 'boolean':
|
||||
$args .= $a ? 'True' : 'False';
|
||||
break;
|
||||
case 'NULL':
|
||||
$args .= 'Null';
|
||||
break;
|
||||
default:
|
||||
$args .= 'Unknown';
|
||||
}
|
||||
}
|
||||
$sFunctionInfo = "$sClass $sType $sFunction($args)";
|
||||
}
|
||||
$aDigestCallStack[] = array('File'=>$sFile, 'Line'=>$sLine, 'Function'=>$sFunctionInfo);
|
||||
}
|
||||
return self::make_table_from_assoc_array($aDigestCallStack);
|
||||
}
|
||||
|
||||
public static function dump_callstack($iLevelsToIgnore = 0, $aCallStack = null)
|
||||
{
|
||||
return self::get_callstack_html($iLevelsToIgnore, $aCallStack);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Source: New
|
||||
// Last modif: 2004/12/20 RQU
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
public static function make_table_from_assoc_array(&$aData)
|
||||
{
|
||||
if (!is_array($aData)) throw new CoreException("make_table_from_assoc_array: Error - the passed argument is not an array");
|
||||
$aFirstRow = reset($aData);
|
||||
if (count($aData) == 0) return '';
|
||||
if (!is_array($aFirstRow)) throw new CoreException("make_table_from_assoc_array: Error - the passed argument is not a bi-dimensional array");
|
||||
$sOutput = "";
|
||||
$sOutput .= "<TABLE WIDTH=\"100%\" BORDER=\"0\" CELLSPACING=\"1\" CELLPADDING=\"1\">\n";
|
||||
|
||||
// Table header
|
||||
//
|
||||
$sOutput .= " <TR CLASS=celltitle>\n";
|
||||
foreach ($aFirstRow as $fieldname=>$trash) {
|
||||
$sOutput .= " <TD><B>".$fieldname."</B></TD>\n";
|
||||
}
|
||||
$sOutput .= " </TR>\n";
|
||||
|
||||
// Table contents
|
||||
//
|
||||
$iCount = 0;
|
||||
foreach ($aData as $aRow) {
|
||||
$sStyle = ($iCount++ % 2 ? "STYLE=\"background-color : #eeeeee\"" : "");
|
||||
$sOutput .= " <TR $sStyle CLASS=cell>\n";
|
||||
foreach ($aRow as $data) {
|
||||
if (strlen($data) == 0) {
|
||||
$data = " ";
|
||||
}
|
||||
$sOutput .= " <TD>".$data."</TD>\n";
|
||||
}
|
||||
$sOutput .= " </TR>\n";
|
||||
}
|
||||
|
||||
$sOutput .= "</TABLE>\n";
|
||||
return $sOutput;
|
||||
}
|
||||
|
||||
public static function debug_breakpoint($arg)
|
||||
{
|
||||
echo "<H1> Debug breakpoint </H1>\n";
|
||||
MyHelpers::var_dump_html($arg);
|
||||
MyHelpers::dump_callstack();
|
||||
exit;
|
||||
}
|
||||
public static function debug_breakpoint_notempty($arg)
|
||||
{
|
||||
if (empty($arg)) return;
|
||||
echo "<H1> Debug breakpoint (triggered on non-empty value) </H1>\n";
|
||||
MyHelpers::var_dump_html($arg);
|
||||
MyHelpers::dump_callstack();
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* utf8... converts non ASCII chars into '?'
|
||||
* Decided after some complex investigations, to have the tools work fine (Oracle+Perl vs mySQL+PHP...)
|
||||
*/
|
||||
public static function utf8($strText)
|
||||
{
|
||||
return iconv("WINDOWS-1252", "ASCII//TRANSLIT", $strText);
|
||||
}
|
||||
|
||||
/**
|
||||
* xmlentities()
|
||||
* ... same as htmlentities, but designed for xml !
|
||||
*/
|
||||
public static function xmlentities($string)
|
||||
{
|
||||
return str_replace( array( '&', '"', "'", '<', '>' ), array ( '&' , '"', ''' , '<' , '>' ), $string );
|
||||
}
|
||||
|
||||
/**
|
||||
* xmlencode()
|
||||
* Encodes a string so that for sure it can be output as an xml data string
|
||||
*/
|
||||
public static function xmlencode($string)
|
||||
{
|
||||
return xmlentities(iconv("UTF-8", "UTF-8//IGNORE",$string));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Source: New - format strings for output
|
||||
// Last modif: 2005/01/18 RQU
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
public static function beautifulstr($sLongString, $iMaxLen, $bShowLen=false, $bShowTooltip=true)
|
||||
{
|
||||
if (!is_string($sLongString)) throw new CoreException("beautifulstr: expect a string as 1st argument");
|
||||
|
||||
// Nothing to do if the string is short
|
||||
if (strlen($sLongString) <= $iMaxLen) return $sLongString;
|
||||
|
||||
// Truncate the string
|
||||
$sSuffix = "...";
|
||||
if ($bShowLen) {
|
||||
$sSuffix .= "(".strlen($sLongString)." chars)...";
|
||||
}
|
||||
$sOutput = substr($sLongString, 0, $iMaxLen - strlen($sSuffix)).$sSuffix;
|
||||
$sOutput = htmlspecialchars($sOutput);
|
||||
|
||||
// Add tooltip if required
|
||||
//if ($bShowTooltip) {
|
||||
// $oTooltip = new gui_tooltip($sLongString);
|
||||
// $sOutput = "<SPAN ".$oTooltip->get_mouseOver_code().">".$sOutput."</SPAN>";
|
||||
//}
|
||||
return $sOutput;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Utility class: static methods for cleaning & escaping untrusted (i.e.
|
||||
user-supplied) strings.
|
||||
Any string can (usually) be thought of as being in one of these 'modes':
|
||||
pure = what the user actually typed / what you want to see on the page /
|
||||
what is actually stored in the DB
|
||||
gpc = incoming GET, POST or COOKIE data
|
||||
sql = escaped for passing safely to RDBMS via SQL (also, data from DB
|
||||
queries and file reads if you have magic_quotes_runtime on--which
|
||||
is rare)
|
||||
html = safe for html display (htmlentities applied)
|
||||
Always knowing what mode your string is in--using these methods to
|
||||
convert between modes--will prevent SQL injection and cross-site scripting.
|
||||
This class refers to its own namespace (so it can work in PHP 4--there is no
|
||||
self keyword until PHP 5). Do not change the name of the class w/o changing
|
||||
all the internal references.
|
||||
Example usage: a POST value that you want to query with:
|
||||
$username = Str::gpc2sql($_POST['username']);
|
||||
*/
|
||||
//This sets SQL escaping to use slashes; for Sybase(/MSSQL)-style escaping
|
||||
// ( ' --> '' ), set to true.
|
||||
define('STR_SYBASE', false);
|
||||
class Str
|
||||
{
|
||||
public static function gpc2sql($gpc, $maxLength = false)
|
||||
{
|
||||
return self::pure2sql(self::gpc2pure($gpc), $maxLength);
|
||||
}
|
||||
public static function gpc2html($gpc, $maxLength = false)
|
||||
{
|
||||
return self::pure2html(self::gpc2pure($gpc), $maxLength);
|
||||
}
|
||||
public static function gpc2pure($gpc)
|
||||
{
|
||||
if (ini_get('magic_quotes_sybase')) $pure = str_replace("''", "'", $gpc);
|
||||
else $pure = get_magic_quotes_gpc() ? stripslashes($gpc) : $gpc;
|
||||
return $pure;
|
||||
}
|
||||
public static function html2pure($html)
|
||||
{
|
||||
return html_entity_decode($html);
|
||||
}
|
||||
public static function html2sql($html, $maxLength = false)
|
||||
{
|
||||
return self::pure2sql(self::html2pure($html), $maxLength);
|
||||
}
|
||||
public static function pure2html($pure, $maxLength = false)
|
||||
{
|
||||
return $maxLength
|
||||
? htmlentities(substr($pure, 0, $maxLength))
|
||||
: htmlentities($pure);
|
||||
}
|
||||
public static function pure2sql($pure, $maxLength = false)
|
||||
{
|
||||
if ($maxLength) $pure = substr($pure, 0, $maxLength);
|
||||
return (STR_SYBASE)
|
||||
? str_replace("'", "''", $pure)
|
||||
: addslashes($pure);
|
||||
}
|
||||
public static function sql2html($sql, $maxLength = false)
|
||||
{
|
||||
$pure = self::sql2pure($sql);
|
||||
if ($maxLength) $pure = substr($pure, 0, $maxLength);
|
||||
return self::pure2html($pure);
|
||||
}
|
||||
public static function sql2pure($sql)
|
||||
{
|
||||
return (STR_SYBASE)
|
||||
? str_replace("''", "'", $sql)
|
||||
: stripslashes($sql);
|
||||
}
|
||||
|
||||
public static function xml2pure($xml)
|
||||
{
|
||||
// #@# - not implemented
|
||||
return $xml;
|
||||
}
|
||||
public static function pure2xml($pure)
|
||||
{
|
||||
return self::xmlencode($pure);
|
||||
}
|
||||
|
||||
protected static function xmlentities($string)
|
||||
{
|
||||
return str_replace( array( '&', '"', "'", '<', '>' ), array ( '&' , '"', ''' , '<' , '>' ), $string );
|
||||
}
|
||||
|
||||
/**
|
||||
* xmlencode()
|
||||
* Encodes a string so that for sure it can be output as an xml data string
|
||||
*/
|
||||
protected static function xmlencode($string)
|
||||
{
|
||||
return self::xmlentities(iconv("ISO-8859-1", "UTF-8//IGNORE",$string));
|
||||
}
|
||||
|
||||
public static function islowcase($sString)
|
||||
{
|
||||
return (strtolower($sString) == $sString);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
Reference in New Issue
Block a user