PageRenderTime 73ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/core/MyHelpers.class.inc.php

https://github.com/adiakin/itop
PHP | 500 lines | 409 code | 35 blank | 56 comment | 35 complexity | a5906f45fddf42b46c4b89db5babf081 MD5 | raw file
  1. <?php
  2. // Copyright (C) 2010 Combodo SARL
  3. //
  4. // This program is free software; you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation; version 3 of the License.
  7. //
  8. // This program is distributed in the hope that it will be useful,
  9. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. // GNU General Public License for more details.
  12. //
  13. // You should have received a copy of the GNU General Public License
  14. // along with this program; if not, write to the Free Software
  15. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  16. /**
  17. * Various dev/debug helpers
  18. * TODO: cleanup or at least re-organize
  19. *
  20. * @author Erwan Taloc <erwan.taloc@combodo.com>
  21. * @author Romain Quetiez <romain.quetiez@combodo.com>
  22. * @author Denis Flaven <denis.flaven@combodo.com>
  23. * @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
  24. */
  25. /**
  26. * MyHelpers
  27. *
  28. * @package iTopORM
  29. */
  30. class MyHelpers
  31. {
  32. public static function CheckValueInArray($sDescription, $value, $aData)
  33. {
  34. if (!in_array($value, $aData))
  35. {
  36. self::HandleWrongValue($sDescription, $value, $aData);
  37. }
  38. }
  39. public static function CheckKeyInArray($sDescription, $key, $aData)
  40. {
  41. if (!array_key_exists($key, $aData))
  42. {
  43. self::HandleWrongValue($sDescription, $key, array_keys($aData));
  44. }
  45. }
  46. public static function HandleWrongValue($sDescription, $value, $aData)
  47. {
  48. if (count($aData) == 0)
  49. {
  50. $sArrayDesc = "{}";
  51. }
  52. else
  53. {
  54. $sArrayDesc = "{".implode(", ", $aData)."}";
  55. }
  56. // exit!
  57. throw new CoreException("Wrong value for $sDescription, found '$value' while expecting a value in $sArrayDesc");
  58. }
  59. // getmicrotime()
  60. // format sss.mmmuuupppnnn
  61. public static function getmicrotime()
  62. {
  63. list($usec, $sec) = explode(" ",microtime());
  64. return ((float)$usec + (float)$sec);
  65. }
  66. /*
  67. * MakeSQLComment
  68. * converts hash into text comment which we can use in a (mySQL) query
  69. */
  70. public static function MakeSQLComment ($aHash)
  71. {
  72. if (empty($aHash)) return "";
  73. $sComment = "";
  74. {
  75. foreach($aHash as $sKey=>$sValue)
  76. {
  77. $sComment .= "\n-- ". $sKey ."=>" . $sValue;
  78. }
  79. }
  80. return $sComment;
  81. }
  82. public static function var_dump_html($aWords, $bFullDisplay = false)
  83. {
  84. echo "<pre>\n";
  85. if ($bFullDisplay)
  86. {
  87. print_r($aWords); // full dump!
  88. }
  89. else
  90. {
  91. var_dump($aWords); // truncate things when they are too big
  92. }
  93. echo "\n</pre>\n";
  94. }
  95. public static function arg_dump_html()
  96. {
  97. echo "<pre>\n";
  98. echo "GET:\n";
  99. var_dump($_GET);
  100. echo "POST:\n";
  101. var_dump($_POST);
  102. echo "\n</pre>\n";
  103. }
  104. public static function var_dump_string($var)
  105. {
  106. ob_start();
  107. print_r($var);
  108. $sRet = ob_get_clean();
  109. return $sRet;
  110. }
  111. protected static function first_diff_line($s1, $s2)
  112. {
  113. $aLines1 = explode("\n", $s1);
  114. $aLines2 = explode("\n", $s2);
  115. for ($i = 0 ; $i < min(count($aLines1), count($aLines2)) ; $i++)
  116. {
  117. if ($aLines1[$i] != $aLines2[$i]) return $i;
  118. }
  119. return false;
  120. }
  121. protected static function highlight_line($sMultiline, $iLine, $sHighlightStart = '<b>', $sHightlightEnd = '</b>')
  122. {
  123. $aLines = explode("\n", $sMultiline);
  124. $aLines[$iLine] = $sHighlightStart.$aLines[$iLine].$sHightlightEnd;
  125. return implode("\n", $aLines);
  126. }
  127. protected static function first_diff($s1, $s2)
  128. {
  129. // do not work fine with multiline strings
  130. $iLen1 = strlen($s1);
  131. $iLen2 = strlen($s2);
  132. for ($i = 0 ; $i < min($iLen1, $iLen2) ; $i++)
  133. {
  134. if ($s1[$i] !== $s2[$i]) return $i;
  135. }
  136. return false;
  137. }
  138. protected static function last_diff($s1, $s2)
  139. {
  140. // do not work fine with multiline strings
  141. $iLen1 = strlen($s1);
  142. $iLen2 = strlen($s2);
  143. for ($i = 0 ; $i < min(strlen($s1), strlen($s2)) ; $i++)
  144. {
  145. if ($s1[$iLen1 - $i - 1] !== $s2[$iLen2 - $i - 1]) return array($iLen1 - $i, $iLen2 - $i);
  146. }
  147. return false;
  148. }
  149. protected static function text_cmp_html($sText1, $sText2, $sHighlight)
  150. {
  151. $iDiffPos = self::first_diff_line($sText1, $sText2);
  152. $sDisp1 = self::highlight_line($sText1, $iDiffPos, '<div style="'.$sHighlight.'">', '</div>');
  153. $sDisp2 = self::highlight_line($sText2, $iDiffPos, '<div style="'.$sHighlight.'">', '</div>');
  154. echo "<table style=\"valign=top;\">\n";
  155. echo "<tr>\n";
  156. echo "<td><pre>$sDisp1</pre></td>\n";
  157. echo "<td><pre>$sDisp2</pre></td>\n";
  158. echo "</tr>\n";
  159. echo "</table>\n";
  160. }
  161. protected static function string_cmp_html($s1, $s2, $sHighlight)
  162. {
  163. $iDiffPos = self::first_diff($s1, $s2);
  164. if ($iDiffPos === false)
  165. {
  166. echo "strings are identical";
  167. return;
  168. }
  169. $sStart = substr($s1, 0, $iDiffPos);
  170. $aLastDiff = self::last_diff($s1, $s2);
  171. $sEnd = substr($s1, $aLastDiff[0]);
  172. $sMiddle1 = substr($s1, $iDiffPos, $aLastDiff[0] - $iDiffPos);
  173. $sMiddle2 = substr($s2, $iDiffPos, $aLastDiff[1] - $iDiffPos);
  174. echo "<p>$sStart<span style=\"$sHighlight\">$sMiddle1</span>$sEnd</p>\n";
  175. echo "<p>$sStart<span style=\"$sHighlight\">$sMiddle2</span>$sEnd</p>\n";
  176. }
  177. protected static function object_cmp_html($oObj1, $oObj2, $sHighlight)
  178. {
  179. $sObj1 = self::var_dump_string($oObj1);
  180. $sObj2 = self::var_dump_string($oObj2);
  181. return self::text_cmp_html($sObj1, $sObj2, $sHighlight);
  182. }
  183. public static function var_cmp_html($var1, $var2, $sHighlight = 'color:red; font-weight:bold;')
  184. {
  185. if (is_object($var1))
  186. {
  187. return self::object_cmp_html($var1, $var2, $sHighlight);
  188. }
  189. else if (count(explode("\n", $var1)) > 1)
  190. {
  191. // multiline string
  192. return self::text_cmp_html($var1, $var2, $sHighlight);
  193. }
  194. else
  195. {
  196. return self::string_cmp_html($var1, $var2, $sHighlight);
  197. }
  198. }
  199. public static function get_callstack_html($iLevelsToIgnore = 0, $aCallStack = null)
  200. {
  201. if ($aCallStack == null) $aCallStack = debug_backtrace();
  202. $aCallStack = array_slice($aCallStack, $iLevelsToIgnore);
  203. $aDigestCallStack = array();
  204. $bFirstLine = true;
  205. foreach ($aCallStack as $aCallInfo)
  206. {
  207. $sLine = empty($aCallInfo['line']) ? "" : $aCallInfo['line'];
  208. $sFile = empty($aCallInfo['file']) ? "" : $aCallInfo['file'];
  209. $sClass = empty($aCallInfo['class']) ? "" : $aCallInfo['class'];
  210. $sType = empty($aCallInfo['type']) ? "" : $aCallInfo['type'];
  211. $sFunction = empty($aCallInfo['function']) ? "" : $aCallInfo['function'];
  212. if ($bFirstLine)
  213. {
  214. $bFirstLine = false;
  215. // For this line do not display the "function name" because
  216. // that will be the name of our error handler for sure !
  217. $sFunctionInfo = "N/A";
  218. }
  219. else
  220. {
  221. $args = '';
  222. if (empty($aCallInfo['args'])) $aCallInfo['args'] = array();
  223. foreach ($aCallInfo['args'] as $a)
  224. {
  225. if (!empty($args))
  226. {
  227. $args .= ', ';
  228. }
  229. switch (gettype($a))
  230. {
  231. case 'integer':
  232. case 'double':
  233. $args .= $a;
  234. break;
  235. case 'string':
  236. $a = Str::pure2html(self::beautifulstr($a, 1024, true, true));
  237. $args .= "\"$a\"";
  238. break;
  239. case 'array':
  240. $args .= 'Array('.count($a).')';
  241. break;
  242. case 'object':
  243. $args .= 'Object('.get_class($a).')';
  244. break;
  245. case 'resource':
  246. $args .= 'Resource('.strstr($a, '#').')';
  247. break;
  248. case 'boolean':
  249. $args .= $a ? 'True' : 'False';
  250. break;
  251. case 'NULL':
  252. $args .= 'Null';
  253. break;
  254. default:
  255. $args .= 'Unknown';
  256. }
  257. }
  258. $sFunctionInfo = "$sClass $sType $sFunction($args)";
  259. }
  260. $aDigestCallStack[] = array('File'=>$sFile, 'Line'=>$sLine, 'Function'=>$sFunctionInfo);
  261. }
  262. return self::make_table_from_assoc_array($aDigestCallStack);
  263. }
  264. public static function dump_callstack($iLevelsToIgnore = 0, $aCallStack = null)
  265. {
  266. return self::get_callstack_html($iLevelsToIgnore, $aCallStack);
  267. }
  268. ///////////////////////////////////////////////////////////////////////////////
  269. // Source: New
  270. // Last modif: 2004/12/20 RQU
  271. ///////////////////////////////////////////////////////////////////////////////
  272. public static function make_table_from_assoc_array(&$aData)
  273. {
  274. if (!is_array($aData)) throw new CoreException("make_table_from_assoc_array: Error - the passed argument is not an array");
  275. $aFirstRow = reset($aData);
  276. if (count($aData) == 0) return '';
  277. if (!is_array($aFirstRow)) throw new CoreException("make_table_from_assoc_array: Error - the passed argument is not a bi-dimensional array");
  278. $sOutput = "";
  279. $sOutput .= "<TABLE WIDTH=\"100%\" BORDER=\"0\" CELLSPACING=\"1\" CELLPADDING=\"1\">\n";
  280. // Table header
  281. //
  282. $sOutput .= " <TR CLASS=celltitle>\n";
  283. foreach ($aFirstRow as $fieldname=>$trash) {
  284. $sOutput .= " <TD><B>".$fieldname."</B></TD>\n";
  285. }
  286. $sOutput .= " </TR>\n";
  287. // Table contents
  288. //
  289. $iCount = 0;
  290. foreach ($aData as $aRow) {
  291. $sStyle = ($iCount++ % 2 ? "STYLE=\"background-color : #eeeeee\"" : "");
  292. $sOutput .= " <TR $sStyle CLASS=cell>\n";
  293. foreach ($aRow as $data) {
  294. if (strlen($data) == 0) {
  295. $data = "&nbsp;";
  296. }
  297. $sOutput .= " <TD>".$data."</TD>\n";
  298. }
  299. $sOutput .= " </TR>\n";
  300. }
  301. $sOutput .= "</TABLE>\n";
  302. return $sOutput;
  303. }
  304. public static function debug_breakpoint($arg)
  305. {
  306. echo "<H1> Debug breakpoint </H1>\n";
  307. MyHelpers::var_dump_html($arg);
  308. MyHelpers::dump_callstack();
  309. exit;
  310. }
  311. public static function debug_breakpoint_notempty($arg)
  312. {
  313. if (empty($arg)) return;
  314. echo "<H1> Debug breakpoint (triggered on non-empty value) </H1>\n";
  315. MyHelpers::var_dump_html($arg);
  316. MyHelpers::dump_callstack();
  317. exit;
  318. }
  319. /**
  320. * xmlentities()
  321. * ... same as htmlentities, but designed for xml !
  322. */
  323. public static function xmlentities($string)
  324. {
  325. return str_replace( array( '&', '"', "'", '<', '>' ), array ( '&amp;' , '&quot;', '&apos;' , '&lt;' , '&gt;' ), $string );
  326. }
  327. /**
  328. * xmlencode()
  329. * Encodes a string so that for sure it can be output as an xml data string
  330. */
  331. public static function xmlencode($string)
  332. {
  333. return xmlentities(iconv("UTF-8", "UTF-8//IGNORE",$string));
  334. }
  335. ///////////////////////////////////////////////////////////////////////////////
  336. // Source: New - format strings for output
  337. // Last modif: 2005/01/18 RQU
  338. ///////////////////////////////////////////////////////////////////////////////
  339. public static function beautifulstr($sLongString, $iMaxLen, $bShowLen=false, $bShowTooltip=true)
  340. {
  341. if (!is_string($sLongString)) throw new CoreException("beautifulstr: expect a string as 1st argument");
  342. // Nothing to do if the string is short
  343. if (strlen($sLongString) <= $iMaxLen) return $sLongString;
  344. // Truncate the string
  345. $sSuffix = "...";
  346. if ($bShowLen) {
  347. $sSuffix .= "(".strlen($sLongString)." chars)...";
  348. }
  349. $sOutput = substr($sLongString, 0, $iMaxLen - strlen($sSuffix)).$sSuffix;
  350. $sOutput = htmlspecialchars($sOutput);
  351. // Add tooltip if required
  352. //if ($bShowTooltip) {
  353. // $oTooltip = new gui_tooltip($sLongString);
  354. // $sOutput = "<SPAN ".$oTooltip->get_mouseOver_code().">".$sOutput."</SPAN>";
  355. //}
  356. return $sOutput;
  357. }
  358. }
  359. /**
  360. Utility class: static methods for cleaning & escaping untrusted (i.e.
  361. user-supplied) strings.
  362. Any string can (usually) be thought of as being in one of these 'modes':
  363. pure = what the user actually typed / what you want to see on the page /
  364. what is actually stored in the DB
  365. gpc = incoming GET, POST or COOKIE data
  366. sql = escaped for passing safely to RDBMS via SQL (also, data from DB
  367. queries and file reads if you have magic_quotes_runtime on--which
  368. is rare)
  369. html = safe for html display (htmlentities applied)
  370. Always knowing what mode your string is in--using these methods to
  371. convert between modes--will prevent SQL injection and cross-site scripting.
  372. This class refers to its own namespace (so it can work in PHP 4--there is no
  373. self keyword until PHP 5). Do not change the name of the class w/o changing
  374. all the internal references.
  375. Example usage: a POST value that you want to query with:
  376. $username = Str::gpc2sql($_POST['username']);
  377. */
  378. //This sets SQL escaping to use slashes; for Sybase(/MSSQL)-style escaping
  379. // ( ' --> '' ), set to true.
  380. define('STR_SYBASE', false);
  381. class Str
  382. {
  383. public static function gpc2sql($gpc, $maxLength = false)
  384. {
  385. return self::pure2sql(self::gpc2pure($gpc), $maxLength);
  386. }
  387. public static function gpc2html($gpc, $maxLength = false)
  388. {
  389. return self::pure2html(self::gpc2pure($gpc), $maxLength);
  390. }
  391. public static function gpc2pure($gpc)
  392. {
  393. if (ini_get('magic_quotes_sybase')) $pure = str_replace("''", "'", $gpc);
  394. else $pure = get_magic_quotes_gpc() ? stripslashes($gpc) : $gpc;
  395. return $pure;
  396. }
  397. public static function html2pure($html)
  398. {
  399. return html_entity_decode($html);
  400. }
  401. public static function html2sql($html, $maxLength = false)
  402. {
  403. return self::pure2sql(self::html2pure($html), $maxLength);
  404. }
  405. public static function pure2html($pure, $maxLength = false)
  406. {
  407. // Check for HTML entities, but be careful the DB is in UTF-8
  408. return $maxLength
  409. ? htmlentities(substr($pure, 0, $maxLength), ENT_QUOTES, 'UTF-8')
  410. : htmlentities($pure, ENT_QUOTES, 'UTF-8');
  411. }
  412. public static function pure2sql($pure, $maxLength = false)
  413. {
  414. if ($maxLength) $pure = substr($pure, 0, $maxLength);
  415. return (STR_SYBASE)
  416. ? str_replace("'", "''", $pure)
  417. : addslashes($pure);
  418. }
  419. public static function sql2html($sql, $maxLength = false)
  420. {
  421. $pure = self::sql2pure($sql);
  422. if ($maxLength) $pure = substr($pure, 0, $maxLength);
  423. return self::pure2html($pure);
  424. }
  425. public static function sql2pure($sql)
  426. {
  427. return (STR_SYBASE)
  428. ? str_replace("''", "'", $sql)
  429. : stripslashes($sql);
  430. }
  431. public static function xml2pure($xml)
  432. {
  433. // #@# - not implemented
  434. return $xml;
  435. }
  436. public static function pure2xml($pure)
  437. {
  438. return self::xmlencode($pure);
  439. }
  440. protected static function xmlentities($string)
  441. {
  442. return str_replace( array( '&', '"', "'", '<', '>' ), array ( '&amp;' , '&quot;', '&apos;' , '&lt;' , '&gt;' ), $string );
  443. }
  444. /**
  445. * xmlencode()
  446. * Encodes a string so that for sure it can be output as an xml data string
  447. */
  448. protected static function xmlencode($string)
  449. {
  450. return self::xmlentities(iconv("UTF-8", "UTF-8//IGNORE",$string));
  451. }
  452. public static function islowcase($sString)
  453. {
  454. return (strtolower($sString) == $sString);
  455. }
  456. }
  457. ?>