Source for file typeinfo.php

Documentation is available at typeinfo.php

  1. <?php
  2. /**
  3. * functions for handling types, comparisons, conversions, validation etc
  4. *
  5. @author    Stuart Prescott
  6. @copyright  Copyright Stuart Prescott
  7. @license    http://opensource.org/licenses/gpl-license.php GNU Public License
  8. @version    $Id$
  9. @package    Bumblebee
  10. @subpackage Misc
  11. */
  12.  
  13.  
  14. function checkValidInclude({
  15.   if (defined('BUMBLEBEE')) {
  16.     die('Internal error: access denied to this location.');
  17.   }
  18. }
  19.  
  20. /**
  21. * If an array key is set, return that value, else return a default
  22. *
  23. * Combines isset and ternary operator to make for cleaner code that
  24. * is quiet when run with E_ALL.
  25. *
  26. @param array &$a (passed by ref for efficiency only) array to lookup
  27. @param string $k  the key to be checked
  28. @param mixed $default (optional) the default value to return if not index not set
  29. @return mixed  returns either $a[$k] if it exists or $default
  30. */
  31. function issetSet(&$a$k$default=NULL{
  32.   return (isset($a[$k]$a[$k$default);
  33. }
  34.  
  35. /**
  36. * simple debugging function to print out arrays and objects
  37. *
  38. * uses print_r/var_dump or dBug within HTML pre tags for easier inspection of classes and arrays
  39. @param mixed $v  object or array to print
  40. */
  41. function preDump($v{
  42.   // either use the dBug class for pretty printing or var_dump/print_r
  43.   $conf ConfigReader::getInstance();
  44.   if ($conf->value('error_handling''UseDBug')) {
  45.     include_once 'dBug.php';
  46.     new dBug($v);
  47.   else {
  48.     echo '<pre>';
  49.     var_dump($v);
  50.     #print_r($v);
  51.     echo '</pre>'."\n";
  52.   }
  53. }
  54.  
  55. /**
  56. * debugging function to conditionally print data to the browser
  57. @param mixed $v  variable to be printed
  58. @param boolean $DEBUG   print data if true
  59. */
  60. function echoData($v$DEBUG=0{
  61.   $conf ConfigReader::getInstance();
  62.   if ($conf->VerboseData || $DEBUG{
  63.     preDump($v);
  64.   }
  65. }
  66.  
  67.  
  68. /**
  69. * is variable composed purely of alphabetic data [A-Za-z_-]
  70. @param string $var string to be tested
  71. @return boolean 
  72. */
  73. function is_alphabetic($var{
  74.   return preg_match('/^\w+$/'$var);
  75. }
  76.  
  77. /**
  78. * Quote data for passing to the database, enclosing data in quotes etc
  79. *
  80. @param string $v string to be quoted
  81. @return string '$v' with slashes added as appropriate.
  82. */
  83. function qw($v{
  84.   return "'".q($v)."'";
  85. }
  86.  
  87. /**
  88. * Quote data for passing to the database
  89. *
  90. * Fixes programatically generated data so that it is correctly escaped. Deals
  91. * with magic_quotes_gpc to remove slashes so that the input is sensible and
  92. * doesn't end up accummulating escape characters with multiple submissions.
  93. *
  94. * Also tests that the supplied string is actually UTF-8 encoded, as if it is
  95. * correctly UTF-8 encoded then we can be sure that we are protected against
  96. * byte munging multibyte attacks that addslashes() is normally susceptible to.
  97. * (that is where the last byte of a multibyte sequence is 0x5c (\) so
  98. * addslashes() is braindead enough to try and escape it creating a multibyte
  99. * character followed by a backslash.... thus addslashes() has created a SQL
  100. * injection vector rather than closing it.
  101. * For more info see:          http://shiflett.org/archive/184
  102. *
  103. @param string     $v string to be quoted
  104. @return string    $v with slashes added as appropriate.
  105. */
  106. function q($v{
  107.   if (isUTF8($v)) {
  108.     $orig $v;
  109.     // badness is here. this means that the user has tried to change the input
  110.     // encoding to something other than the UTF-8 that was requested.
  111.     // We will *try* to fix the string:
  112.     if (function_exists("mb_convert_encoding")) {
  113.       $v mb_convert_encoding($v'UTF-8');
  114.     elseif (function_exists("iconv")) {
  115.       $v iconv('''UTF-8//IGNORE'$v);
  116.     else {
  117.       // try converting from windows encoding to UTF-8
  118.       $v cp1252_to_utf8($v);
  119.     }
  120.     if (!isUTF8($v)) {
  121.       // then we really don't know what to do so kill the data
  122.       // better not to have a compromised db, really...
  123.       $v '';
  124.     }
  125.     logmsg(9"Non UTF-8 data received. '$origwas converted to '$v'.");
  126.     //logmsg(9, "Bacon saved? '".addslashes($orig)."' was converted to '".addslashes($v)."'.");
  127.   }
  128.   // magic-quotes-gpc is a pain in the backside: I would rather I was just given
  129.   // the data the user entered.
  130.   // We can't just return the data if magic_quotes_gpc is turned on because
  131.   // that would be wrong if there was programatically set data in there.
  132.   if (get_magic_quotes_gpc()) {
  133.     // first remove any (partial or full) escaping then add it in properly
  134.     $v addslashes(stripslashes($v));
  135.   else {
  136.     // just add in the slashes
  137.     $v addslashes($v);
  138.   }
  139.   return $v;
  140. }
  141.  
  142. /**
  143. * Quote each element in a set of values.
  144. *
  145. @param array $list    list of values to qw quote for use in SQL
  146. @returns array  list of quoted strings
  147. */
  148. function array_qw($list{
  149.   $newlist array();
  150.   foreach ($list as $a{
  151.     $newlist[qw($a);
  152.   }
  153.   return $newlist;
  154. }
  155.  
  156. /**
  157. * Remove quoting around expressions and remove slashes in data to escape bad chars
  158. *
  159. @param string $v string to be unquoted
  160. @return string unquoted string
  161. */
  162. function unqw($v{
  163.   if (preg_match("/'(.+)'/"$v$match)) {
  164.     $v $match[1];
  165.   }
  166.   return stripslashes($v);
  167. }
  168.  
  169. /**
  170. * Verifies that the supplied string is correctly UTF-8 encoded
  171. *
  172. * Two versions are presented here -- the simple version with just the
  173. * /u regexp is significantly faster than the more complicated byte-checking
  174. * version but the /u regexp doesn't always catch bad UTF-8 sequences.
  175. *
  176. * PCRE /u version from:
  177. *      http://www.phpwact.org/php/i18n/charsets%23checking_utf-8_for_well_formedness
  178. *
  179. * Regexp version from
  180. *      http://w3.org/International/questions/qa-forms-utf-8.html
  181. *
  182. @param string $v string to be tested
  183. @return boolean string is UTF-8 encoded
  184. */
  185. function isUTF8($v{
  186.   return preg_match('@^(?:
  187.           [\x09\x0A\x0D\x20-\x7E]            # ASCII
  188.         | [\xC2-\xDF][\x80-\xBF]             # non-overlong 2-byte
  189.         |  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
  190.         | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
  191.         |  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
  192.         |  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
  193.         | [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
  194.         |  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
  195.   )*$@x'$v);
  196.  
  197. /*
  198.   if ( strlen($str) == 0 ) {
  199.       return TRUE;
  200.   }
  201.   // If even just the first character can be matched, when the /u
  202.   // modifier is used, then it's valid UTF-8. If the UTF-8 is somehow
  203.   // invalid, nothing at all will match, even if the string contains
  204.   // some valid sequences
  205.   return (preg_match('/^.{1}/us',$str,$ar) == 1);
  206. */
  207. }
  208.  
  209. /**
  210. * Converts Windows characters (charset cp-1252 or windows-1252) to UTF-8
  211. *
  212. @param string $v string to be tested
  213. @return string UTF-8 string
  214. */
  215. function cp1252_to_utf8($str{
  216.   if (function_exists('utf8_encode')) return $str;
  217.   $cp1252_map array(
  218.     "\xc2\x80" => "\xe2\x82\xac"/* EURO SIGN */
  219.     "\xc2\x82" => "\xe2\x80\x9a"/* SINGLE LOW-9 QUOTATION MARK */
  220.     "\xc2\x83" => "\xc6\x92",     /* LATIN SMALL LETTER F WITH HOOK */
  221.     "\xc2\x84" => "\xe2\x80\x9e"/* DOUBLE LOW-9 QUOTATION MARK */
  222.     "\xc2\x85" => "\xe2\x80\xa6"/* HORIZONTAL ELLIPSIS */
  223.     "\xc2\x86" => "\xe2\x80\xa0"/* DAGGER */
  224.     "\xc2\x87" => "\xe2\x80\xa1"/* DOUBLE DAGGER */
  225.     "\xc2\x88" => "\xcb\x86",     /* MODIFIER LETTER CIRCUMFLEX ACCENT */
  226.     "\xc2\x89" => "\xe2\x80\xb0"/* PER MILLE SIGN */
  227.     "\xc2\x8a" => "\xc5\xa0",     /* LATIN CAPITAL LETTER S WITH CARON */
  228.     "\xc2\x8b" => "\xe2\x80\xb9"/* SINGLE LEFT-POINTING ANGLE QUOTATION */
  229.     "\xc2\x8c" => "\xc5\x92",     /* LATIN CAPITAL LIGATURE OE */
  230.     "\xc2\x8e" => "\xc5\xbd",     /* LATIN CAPITAL LETTER Z WITH CARON */
  231.     "\xc2\x91" => "\xe2\x80\x98"/* LEFT SINGLE QUOTATION MARK */
  232.     "\xc2\x92" => "\xe2\x80\x99"/* RIGHT SINGLE QUOTATION MARK */
  233.     "\xc2\x93" => "\xe2\x80\x9c"/* LEFT DOUBLE QUOTATION MARK */
  234.     "\xc2\x94" => "\xe2\x80\x9d"/* RIGHT DOUBLE QUOTATION MARK */
  235.     "\xc2\x95" => "\xe2\x80\xa2"/* BULLET */
  236.     "\xc2\x96" => "\xe2\x80\x93"/* EN DASH */
  237.     "\xc2\x97" => "\xe2\x80\x94"/* EM DASH */
  238.     "\xc2\x98" => "\xcb\x9c",     /* SMALL TILDE */
  239.     "\xc2\x99" => "\xe2\x84\xa2"/* TRADE MARK SIGN */
  240.     "\xc2\x9a" => "\xc5\xa1",     /* LATIN SMALL LETTER S WITH CARON */
  241.     "\xc2\x9b" => "\xe2\x80\xba"/* SINGLE RIGHT-POINTING ANGLE QUOTATION*/
  242.     "\xc2\x9c" => "\xc5\x93",     /* LATIN SMALL LIGATURE OE */
  243.     "\xc2\x9e" => "\xc5\xbe",     /* LATIN SMALL LETTER Z WITH CARON */
  244.     "\xc2\x9f" => "\xc5\xb8"      /* LATIN CAPITAL LETTER Y WITH DIAERESIS*/
  245.   );
  246.   // utf8_encode() converts from ISO-8859-1 to UTF-8; the strtr() converts the
  247.   // differences between Windows-1252 and ISO-8859-1.
  248.   return  strtr(utf8_encode($str)$cp1252_map);
  249. }
  250.  
  251. /**
  252. * quote words against XSS attacks by converting tags to html entities
  253. *
  254. * replace some bad HTML characters with entities to protext against
  255. * cross-site scripting attacks. the generated code should be clean of
  256. * nasty HTML
  257. *
  258. @param string $v string to be quoted
  259. @param boolean $strip   strip slashes first
  260. @return string $v with html converted to entities
  261. */
  262. function xssqw($v$strip=true{
  263.   // once again magic_quotes_gpc gets in the way
  264.   if ($strip && get_magic_quotes_gpc()) {
  265.     // first remove any (partial or full) escaping then we'll do it properly below
  266.     $v stripslashes($v);
  267.   }
  268.   $replace array(
  269.         "/'/"                             =>   "&#039;",
  270.         '/"/'                             =>   "&#034;",
  271.         '@<@'                             =>   '&lt;',
  272.         '@>@'                             =>   '&gt;',
  273.         '@&(?!(\#\d{1,4})|(\w{2,4});)@'   =>   '&amp;'  // allow &#123; and &lt; through
  274.   );
  275.   return preg_replace(array_keys($replace)array_values($replace)$v);
  276.   #return htmlentities($v, ENT_QUOTES);
  277. }
  278.  
  279.  
  280. /**
  281. * quote words against XSS attacks but allow some html tags through
  282. * (unsafe attributes are removed)
  283. *
  284. @param string $v string to be quoted
  285. @return string $v with html converted to entities
  286. */
  287. function xssqw_relaxed($v{
  288.   // once again magic_quotes_gpc gets in the way
  289.   if (get_magic_quotes_gpc()) {
  290.     // first remove any (partial or full) escaping then we'll do it properly below
  291.     $v stripslashes($v);
  292.   }
  293.   $keep array(
  294.           "i"     => array("style""class"),
  295.           "u"     => array("style""class"),
  296.           "b"     => array("style""class"),
  297.           "a"     => array("style""class""href""id""name"),
  298.           "div"   => array("style""class""id"),
  299.           "br"    => array(),
  300.           "hr"    => array("style""class""id")
  301.         );
  302.  
  303.   $s xssqw($v);
  304.   foreach ($keep as $tag => $attribs{
  305.     $s preg_replace("@&lt;\s*($tag)((?:(?!&gt;).)*)&gt;"
  306.                       ."((?:(?!&lt;\s*/\s*$tag).)*)"  // negative lookahead: no closing tag
  307.                       ."&lt;\s*/$tag\s*&gt;@ise",
  308.                       'xssqw_relaxed_helper($keep, "\1", "\2", "\3");',
  309.                       $s);
  310.     #echo $s;
  311.   }
  312.   return $s;
  313. }
  314.  
  315. function xssqw_relaxed_helper($tags$tag$attribs$content){
  316.   #echo "tag='$tag'; attribs='$attribs'; content='$content'<br />\n";
  317.   $attrlist array();
  318.   foreach ($tags[$tagas $a{
  319.     $attrmatch "@$a\s*=\s*(&#039;|&#034;)((?:[^\\1])*)\\1@";
  320.     $m array();
  321.     if (preg_match($attrmatch$attribs$m)) {
  322.       $attrlist["$a='$m[2]'";
  323.     }
  324.   }
  325.   $attrs join($attrlist" ");
  326.   return "<$tag $attrs>$content</$tag>";
  327. }
  328.  
  329. /**
  330. * quote all elements of an array against XSS attacks using xssqw function
  331. *
  332. @param array $a array of strings to be quoted
  333. @return array $a of strings quoted
  334. */
  335. function array_xssqw($a{
  336.   return array_map('xssqw'$a);
  337. }
  338.  
  339. /**
  340. * tests if string is non-empty
  341. *
  342. * note that in PHP, '' == '0' etc so test has to use strlen
  343. @param string $v string to test for emptiness
  344. @return boolean 
  345. */
  346. function is_nonempty_string($v{
  347.   #echo "'val=$v' ";
  348.   return !(strlen($v== 0);
  349. }
  350.  
  351. /**
  352. * tests if string is a plausible member of a radio-button choice set
  353. *
  354. @param string $v string to test
  355. @return boolean 
  356. */
  357. function choice_set($v{
  358.   #echo "'val=$v' ";
  359.   return !($v == NULL || $v == '');
  360. }
  361.  
  362. /**
  363. * tests if string is a member of a radio button choice set
  364. *
  365. @param string $v string to test
  366. @return boolean 
  367. */
  368. function is_valid_radiochoice($v{
  369.   #echo "'val=$v' ";
  370.   return (choice_set($v&& is_numeric($v&& $v >= -1);
  371. }
  372.  
  373. /**
  374. * tests if string is a sensible email format
  375. *
  376. * does not test full RFC822 compliance or that the address exists, just that it looks
  377. * like a standard email address with a username part @ and domain part with at least one dot
  378. @param string $v string to test for email format
  379. @return boolean 
  380. */
  381. function is_email_format($v{
  382.   #echo "'val=$v' ";
  383.   #$pattern = '/^\w.+\@[A-Z_\-]+\.[A-Z_\-]/i';
  384.   $pattern '/^[_a-z0-9\-]+(?:\.[_a-z0-9\-]+)*@[a-z0-9\-]+(?:\.[a-z0-9\-]{2,})+$/i';
  385.   return (preg_match($pattern$v));
  386. }
  387.  
  388. /**
  389. * tests if string is number
  390. *
  391. @param string $v string to test if it is a number
  392. @return boolean 
  393. */
  394. function is_number($v{
  395.   return is_numeric($v);
  396. }
  397.  
  398. /**
  399. * tests if string is a amount for a price
  400. *
  401. @param string $v string to test if it is a valid cost
  402. @return boolean 
  403. @todo //TODO: strengthen this test?
  404. */
  405. function is_cost_amount($v{
  406.    return is_numeric($v);
  407. }
  408.  
  409. /**
  410. * tests if string is a amount for a price but allows blank entries
  411. *
  412. @param string $v string to test if it is a valid cost
  413. @return boolean 
  414. */
  415. function is_cost_amount_or_blank($v{
  416.    return is_number($v|| $v === '' || $v === null;
  417. }
  418.  
  419. /**
  420. * tests if string is valid date-time expression YYYY-MM-DD HH:MM
  421. *
  422. @param string $v string to test it is a date-time string
  423. @return boolean 
  424. @todo //TODO: can this be relaxed to be more user-friendly without introducing errors
  425. */
  426. function is_valid_datetime($v{
  427.   return (preg_match('/^\d\d\d\d-\d\d-\d\d \d\d:\d\d/',$v));
  428. }
  429.  
  430. /**
  431. * tests if string is valid time expression HH:MM or HH:MM:SS format
  432. *
  433. @param string $v string to test it is a time string
  434. @return boolean 
  435. @todo //TODO: can this be relaxed to be more user-friendly without introducing errors
  436. */
  437. function is_valid_time($v{
  438.   return (preg_match('/^\d\d:\d\d/',$v|| preg_match('/^\d\d:\d\d:\d\d/',$v));
  439. }
  440.  
  441. /**
  442. * tests if string is valid time expression HH:MM or HH:MM:SS format other than 00:00:00
  443. *
  444. @param string $v string to test if it is a time string
  445. @return boolean 
  446. @todo //TODO: can this be relaxed to be more user-friendly without introducing errors
  447. */
  448. function is_valid_nonzero_time($v{
  449.   return (preg_match('/^\d\d:\d\d/',$v|| preg_match('/^\d\d:\d\d:\d\d/',$v))
  450.             && preg_match('/^00:00/',$v&& preg_match('/^00:00:00/',$v);
  451. }
  452.  
  453. /**
  454. * tests if a set of numbers add to 100 (set of percentages should add to 100)
  455. *
  456. @param array $vs list of values to test if sum is 100
  457. @return boolean 
  458. */
  459. function sum_is_100($vs{
  460.   #echo "<br/>Checking sum<br/>";
  461.   $sum=0;
  462.   foreach ($vs as $v{
  463.     #echo "'$v', ";
  464.     $sum += $v;
  465.   }
  466.   return ($sum == 100);
  467. }
  468.  
  469. function currencyValueCleaner($value{
  470.   $conf ConfigReader::getInstance();
  471.   $re $conf->value('language''removedCurrencySymbols');
  472.   if ($re == '' || $re == nullreturn;
  473.  
  474.   $re preg_quote($re'@');
  475.   $value preg_replace("@[$re]@"''$value);
  476.   return trim($value);
  477. }
  478.  
  479. function numberFormatter($value$dp{
  480.   $conf ConfigReader::getInstance();
  481.   return number_format($value$dp,
  482.                        $conf->value('language''decimal_separator',   '.'),
  483.                        $conf->value('language''thousands_separator'''));
  484. }
  485.  
  486. function currencyFormatter($value{
  487.   $conf ConfigReader::getInstance();
  488.   $s number_format($value,
  489.                       $conf->value('language''money_decimal_places',   2),
  490.                       $conf->value('language''decimal_separator',      '.'),
  491.                       $conf->value('language''thousands_separator',    ''));
  492.   return sprintf($conf->value('language''money_format',   '$%s')$s);
  493. }
  494.  
  495. function commaFloat($str{
  496.   if(strstr($str',')) {
  497.     $str str_replace('.''',  $str)// remove dots that are (thousand seps)
  498.     $str str_replace(',''.'$str)// replace ',' with '.'
  499.   }
  500.   return floatval($str)// take some last chances with floatval
  501. }
  502.  
  503.  
  504. ?>

Documentation generated on Tue, 06 Mar 2007 10:02:05 +0000 by phpDocumentor 1.3.0