[ Index ]

Source Code Reference for V1.00

title

Body

[close]

/includes/ -> main_functions.php (source)

   1  <?php /* $Id: main_functions.php 226 2008-09-05 09:47:47Z pedroix $ $URL: https://web2project.svn.sourceforge.net/svnroot/web2project/trunk/includes/main_functions.php $ */
   2  ##
   3  ## Global General Purpose Functions
   4  ##
   5  if (!defined('W2P_BASE_DIR')) {
   6      die('You should not access this file directly.');
   7  }
   8  
   9  define('SECONDS_PER_DAY', 60 * 60 * 24);
  10  
  11  ##
  12  ## Returns the best color based on a background color (x is cross-over)
  13  ##
  14  function bestColor($bg, $lt = '#ffffff', $dk = '#000000') {
  15      // cross-over color = x
  16      $x = 128;
  17      $r = hexdec(substr($bg, 0, 2));
  18      $g = hexdec(substr($bg, 2, 2));
  19      $b = hexdec(substr($bg, 4, 2));
  20  
  21      if ($r < $x && $g < $x || $r < $x && $b < $x || $b < $x && $g < $x) {
  22          return $lt;
  23      } else {
  24          return $dk;
  25      }
  26  }
  27  
  28  ##
  29  ## returns a select box based on an key,value array where selected is based on key
  30  ##
  31  function arraySelect(&$arr, $select_name, $select_attribs, $selected, $translate = false) {
  32      global $AppUI;
  33      if (!is_array($arr)) {
  34          dprint(__file__, __line__, 0, 'arraySelect called with no array');
  35          return '';
  36      }
  37      reset($arr);
  38      $s = '<select id="' . $select_name . '" name="' . $select_name . '" ' . $select_attribs . '>';
  39      $did_selected = 0;
  40      foreach ($arr as $k => $v) {
  41          if ($translate) {
  42              $v = $AppUI->_($v);
  43              // This is supplied to allow some Hungarian characters to
  44              // be translated correctly. There are probably others.
  45              // As such a more general approach probably based upon an
  46              // array lookup for replacements would be a better approach. AJD.
  47              $v = str_replace('&#369;', '�', $v);
  48              $v = str_replace('&#337;', '�', $v);
  49          }
  50          $s .= '<option value="' . $k . '"' . ((($k == $selected && strcmp($k, $selected) == 0) && !$did_selected) ? ' selected="selected"' : '') . '>' . $v . '</option>';
  51          if (($k == $selected && strcmp($k, $selected) == 0)) {
  52              $did_selected = 1;
  53          }
  54      }
  55      $s .= '</select>';
  56      return $s;
  57  }
  58  
  59  ##
  60  ## returns a select box based on an key,value array where selected is based on key
  61  ##
  62  function arraySelectTree(&$arr, $select_name, $select_attribs, $selected, $translate = false) {
  63      global $AppUI;
  64      reset($arr);
  65  
  66      $children = array();
  67      // first pass - collect children
  68      foreach ($arr as $k => $v) {
  69          $id = $v[0];
  70          $pt = $v[2];
  71          $list = $children[$pt] ? $children[$pt] : array();
  72          array_push($list, $v);
  73          $children[$pt] = $list;
  74      }
  75      $list = tree_recurse($arr[0][2], '', array(), $children);
  76      return arraySelect($list, $select_name, $select_attribs, $selected, $translate);
  77  }
  78  
  79  function tree_recurse($id, $indent, $list, $children) {
  80      if ($children[$id]) {
  81          foreach ($children[$id] as $v) {
  82              $id = $v[0];
  83              $txt = $v[1];
  84              $pt = $v[2];
  85              $list[$id] = $indent . ' ' . $txt;
  86              $list = tree_recurse($id, $indent . '--', $list, $children);
  87          }
  88      }
  89      return $list;
  90  }
  91  
  92  /**
  93   **    Provide Projects Selectbox sorted by Companies
  94   **    @author gregorerhardt with special thanks to original author aramis
  95   **    @param     int         userID
  96   **    @param     string     HTML select box name identifier
  97   **    @param    string    HTML attributes
  98   **    @param    int            Proejct ID for preselection
  99   **    @param     int            Project ID which will be excluded from the list 
 100   **                                    (e.g. in the tasks import list exclude the project to import into)
 101   **    @return    string     HTML selectbox
 102  
 103   */
 104  
 105  function projectSelectWithOptGroup($user_id, $select_name, $select_attribs, $selected, $excludeProjWithId = null) {
 106      global $AppUI;
 107      $q = new DBQuery();
 108      $q->addTable('projects', 'pr');
 109      $q->addQuery('pr.project_id, co.company_name, project_name');
 110      if (!empty($excludeProjWithId)) {
 111          $q->addWhere('pr.project_id <> ' . $excludeProjWithId);
 112      }
 113      $proj = new CProject();
 114      $proj->setAllowedSQL($user_id, $q, null, 'pr');
 115      $q->addOrder('co.company_name, project_name');
 116      $projects = $q->loadList();
 117      $s = '<select name="' . $select_name . '" ' . $select_attribs . '>';
 118      $s .= '<option value="0" ' . ($selected == 0 ? 'selected="selected"' : '') . ' >' . $AppUI->_('None') . '</option>';
 119      $current_company = '';
 120      foreach ($projects as $p) {
 121          if ($p['company_name'] != $current_company) {
 122              $current_company = $p['company_name'];
 123              $s .= '<optgroup label="' . $current_company . '" >' . $current_company . '</optgroup>';
 124          }
 125          $s .= '<option value="' . $p['project_id'] . '" ' . ($selected == $p['project_id'] ? 'selected="selected"' : '') . '>&nbsp;&nbsp;&nbsp;' . $p['project_name'] . '</option>';
 126      }
 127      $s .= '</select>';
 128      return $s;
 129  }
 130  
 131  ##
 132  ## Merges arrays maintaining/overwriting shared numeric indicees
 133  ##
 134  function arrayMerge($a1, $a2) {
 135      foreach ($a2 as $k => $v) {
 136          $a1[$k] = $v;
 137      }
 138      return $a1;
 139  }
 140  
 141  ##
 142  ## breadCrumbs - show a separated list of crumbs
 143  ## array is in the form url => title
 144  ##
 145  function breadCrumbs(&$arr) {
 146      global $AppUI;
 147      $crumbs = array();
 148      foreach ($arr as $k => $v) {
 149          $crumbs[] = '<a class="button" href="' . $k . '"><span>' . $AppUI->_($v) . '</span></a>';
 150      }
 151      return implode('</td><td align="left" nowrap="nowrap">', $crumbs);
 152  }
 153  ##
 154  ## generate link for context help -- old version
 155  ##
 156  function contextHelp($title, $link = '') {
 157      return w2PcontextHelp($title, $link);
 158  }
 159  
 160  function w2PcontextHelp($title, $link = '') {
 161      global $AppUI;
 162      return '<a href="#' . $link . '" onclick="javascript:window.open(\'?m=help&amp;dialog=1&amp;hid=' . $link . '\', \'contexthelp\', \'width=400, height=400, left=50, top=50, scrollbars=yes, resizable=yes\')">' . $AppUI->_($title) . '</a>';
 163  }
 164  
 165  /**
 166   * Retrieves a configuration setting.
 167   * @param $key string The name of a configuration setting
 168   * @param $default string The default value to return if the key not found.
 169   * @return The value of the setting, or the default value if not found.
 170   */
 171  function w2PgetConfig($key, $default = null) {
 172      global $w2Pconfig;
 173      if (array_key_exists($key, $w2Pconfig)) {
 174          return $w2Pconfig[$key];
 175      } else {
 176          return $default;
 177      }
 178  }
 179  
 180  function w2PgetUsername($user) {
 181      $q = new DBQuery;
 182      $q->addTable('users');
 183      $q->addQuery('contact_first_name, contact_last_name');
 184      $q->addJoin('contacts', 'con', 'contact_id = user_contact', 'inner');
 185      $q->addWhere('user_username like \'' . $user . '\' OR user_id = ' . (int)$user);
 186      $r = $q->loadList();
 187      return $r[0]['contact_first_name'] . ' ' . $r[0]['contact_last_name'];
 188  }
 189  
 190  function w2PgetUsernameFromID($user) {
 191      $q = new DBQuery;
 192      $q->addTable('users');
 193      $q->addQuery('contact_first_name, contact_last_name');
 194      $q->addJoin('contacts', 'con', 'contact_id = user_contact', 'inner');
 195      $q->addWhere('user_id = ' . (int)$user);
 196      $r = $q->loadList();
 197      return $r[0]['contact_first_name'] . ' ' . $r[0]['contact_last_name'];
 198  }
 199  
 200  function w2PgetUsers($module = '') {
 201      global $AppUI;
 202      $q = new DBQuery;
 203      $q->addTable('users');
 204      $q->addQuery('user_id, concat_ws(\' \', contact_first_name, contact_last_name) as name');
 205      $q->addJoin('contacts', 'con', 'contact_id = user_contact', 'inner');
 206      $q->addOrder('contact_first_name,contact_last_name');
 207  
 208      // get CCompany() to filter by company
 209      require_once ($AppUI->getModuleClass('companies'));
 210      $obj = new CCompany();
 211      $companies = $obj->getAllowedSQL($AppUI->user_id, 'company_id');
 212      $q->addJoin('companies', 'com', 'company_id = contact_company');
 213      if ($companies) {
 214          $q->addWhere('(' . implode(' OR ', $companies) . ' OR contact_company=\'\' OR contact_company IS NULL OR contact_company = 0)');
 215      }
 216      require_once ($AppUI->getModuleClass('departments'));
 217      $dpt = new CDepartment();
 218      $depts = $dpt->getAllowedSQL($AppUI->user_id, 'dept_id');
 219      $q->addJoin('departments', 'dep', 'dept_id = contact_department');
 220      if ($depts) {
 221          $q->addWhere('(' . implode(' OR ', $depts) . ' OR contact_department=0)');
 222      }
 223      //print_r($q->prepare());
 224  
 225      return arrayMerge(array(0 => $AppUI->_('All Users')), $q->loadHashList());
 226  }
 227  
 228  function w2PgetUsersList($stub = null, $where = null, $orderby = 'contact_first_name, contact_last_name') {
 229      global $AppUI;
 230      $q = new DBQuery;
 231      $q->addTable('users');
 232      $q->addQuery('DISTINCT(user_id), user_username, contact_last_name, contact_first_name,
 233           contact_email, company_name, contact_company, dept_id, dept_name, CONCAT(contact_first_name,\' \',contact_last_name) contact_name, user_type');
 234      $q->addJoin('contacts', 'con', 'contact_id = user_contact', 'inner');
 235      if ($stub) {
 236          $q->addWhere('(UPPER(user_username) LIKE \'' . $stub . '%\' or UPPER(contact_first_name) LIKE \'' . $stub . '%\' OR UPPER(contact_last_name) LIKE \'' . $stub . '%\')');
 237      } elseif ($where) {
 238          $where = $q->quote('%' . $where . '%');
 239          $q->addWhere('(UPPER(user_username) LIKE ' . $where . ' OR UPPER(contact_first_name) LIKE ' . $where . ' OR UPPER(contact_last_name) LIKE ' . $where . ')');
 240      }
 241  
 242      $q->addGroup('user_id');
 243      $q->addOrder($orderby);
 244  
 245      // get CCompany() to filter by company
 246      require_once ($AppUI->getModuleClass('companies'));
 247      $obj = new CCompany();
 248      $companies = $obj->getAllowedSQL($AppUI->user_id, 'company_id');
 249      $q->addJoin('companies', 'com', 'company_id = contact_company');
 250      if ($companies) {
 251          $q->addWhere('(' . implode(' OR ', $companies) . ' OR contact_company=\'\' OR contact_company IS NULL OR contact_company = 0)');
 252      }
 253      require_once ($AppUI->getModuleClass('departments'));
 254      $dpt = new CDepartment();
 255      $depts = $dpt->getAllowedSQL($AppUI->user_id, 'dept_id');
 256      $q->addJoin('departments', 'dep', 'dept_id = contact_department');
 257      if ($depts) {
 258          $q->addWhere('(' . implode(' OR ', $depts) . ' OR contact_department=0)');
 259      }
 260      //print_r($q->prepare());
 261  
 262      return $q->loadList();
 263  }
 264  
 265  function w2PgetUsersHashList($stub = null, $where = null, $orderby = 'contact_first_name, contact_last_name') {
 266      global $AppUI;
 267      $q = new DBQuery;
 268      $q->addTable('users');
 269      $q->addQuery('DISTINCT(user_id), user_username, contact_last_name, contact_first_name,
 270           contact_email, company_name, contact_company, dept_id, dept_name, CONCAT(contact_first_name,\' \',contact_last_name) contact_name, user_type');
 271      $q->addJoin('contacts', 'con', 'contact_id = user_contact', 'inner');
 272      if ($stub) {
 273          $q->addWhere('(UPPER(user_username) LIKE \'' . $stub . '%\' or UPPER(contact_first_name) LIKE \'' . $stub . '%\' OR UPPER(contact_last_name) LIKE \'' . $stub . '%\')');
 274      } elseif ($where) {
 275          $where = $q->quote('%' . $where . '%');
 276          $q->addWhere('(UPPER(user_username) LIKE ' . $where . ' OR UPPER(contact_first_name) LIKE ' . $where . ' OR UPPER(contact_last_name) LIKE ' . $where . ')');
 277      }
 278  
 279      $q->addGroup('user_id');
 280      $q->addOrder($orderby);
 281  
 282      // get CCompany() to filter by company
 283      require_once ($AppUI->getModuleClass('companies'));
 284      $obj = new CCompany();
 285      $companies = $obj->getAllowedSQL($AppUI->user_id, 'company_id');
 286      $q->addJoin('companies', 'com', 'company_id = contact_company');
 287      if ($companies) {
 288          $q->addWhere('(' . implode(' OR ', $companies) . ' OR contact_company=\'\' OR contact_company IS NULL OR contact_company = 0)');
 289      }
 290      require_once ($AppUI->getModuleClass('departments'));
 291      $dpt = new CDepartment();
 292      $depts = $dpt->getAllowedSQL($AppUI->user_id, 'dept_id');
 293      $q->addJoin('departments', 'dep', 'dept_id = contact_department');
 294      if ($depts) {
 295          $q->addWhere('(' . implode(' OR ', $depts) . ' OR contact_department=0)');
 296      }
 297      //print_r($q->prepare());
 298  
 299      return $q->loadHashList('user_id');
 300  }
 301  
 302  ##
 303  ## displays the configuration array of a module for informational purposes
 304  ##
 305  function w2PshowModuleConfig($config) {
 306      global $AppUI;
 307      $s = '<table cellspacing="2" cellpadding="2" border="0" class="std" width="50%">';
 308      $s .= '<tr><th colspan="2">' . $AppUI->_('Module Configuration') . '</th></tr>';
 309      foreach ($config as $k => $v) {
 310          $s .= '<tr><td width="50%">' . $AppUI->_($k) . '</td><td width="50%" class="hilite">' . $AppUI->_($v) . '</td></tr>';
 311      }
 312      $s .= '</table>';
 313      return ($s);
 314  }
 315  
 316  /**
 317   *    Function to recussively find an image in a number of places
 318   *    @param string The name of the image
 319   *    @param string Optional name of the current module
 320   */
 321  function w2PfindImage($name, $module = null) {
 322      // uistyle must be declared globally
 323      global $uistyle;
 324      //print_r($name.' '.$module.' '.w2PgetConfig('host_style'));
 325      if ($module && file_exists(W2P_BASE_DIR . '/modules/' . $module . '/images/' . $name)) {
 326          return './modules/' . $module . '/images/' . $name;
 327      } elseif ($module && file_exists(W2P_BASE_DIR . '/style/' . $uistyle . '/images/modules/' . $module . '/' . $name)) {
 328          return './style/' . $uistyle . '/images/modules/' . $module . '/' . $name;
 329      } elseif (file_exists(W2P_BASE_DIR . '/style/' . $uistyle . '/images/icons/' . $name)) {
 330          return './style/' . $uistyle . '/images/icons/' . $name;
 331      } elseif (file_exists(W2P_BASE_DIR . '/style/' . $uistyle . '/images/obj/' . $name)) {
 332          return './style/' . $uistyle . '/images/obj/' . $name;
 333      } elseif (file_exists(W2P_BASE_DIR . '/style/' . $uistyle . '/images/' . $name)) {
 334          return './style/' . $uistyle . '/images/' . $name;
 335      } elseif ($module && file_exists(W2P_BASE_DIR . '/style/' . w2PgetConfig('host_style') . '/images/modules/' . $module . '/' . $name)) {
 336          return './style/' . w2PgetConfig('host_style') . '/images/modules/' . $module . '/' . $name;
 337      } elseif (file_exists(W2P_BASE_DIR . '/style/' . w2PgetConfig('host_style') . '/images/icons/' . $name)) {
 338          return './style/' . w2PgetConfig('host_style') . '/images/icons/' . $name;
 339      } elseif (file_exists(W2P_BASE_DIR . '/style/' . w2PgetConfig('host_style') . '/images/obj/' . $name)) {
 340          return './style/' . w2PgetConfig('host_style') . '/images/obj/' . $name;
 341      } else {
 342          return './style/' . w2PgetConfig('host_style') . '/images/' . $name;
 343      }
 344  }
 345  
 346  /**
 347   *    Workaround removed due to problems in Opera and other issues
 348   *    with IE6.
 349   *    Workaround to display png images with alpha-transparency in IE6.0
 350   *    @param string The name of the image
 351   *    @param string The image width
 352   *    @param string The image height
 353   *    @param string The alt text for the image
 354   */
 355  function w2PshowImage($src, $wid = '', $hgt = '', $alt = '', $title = '', $module = null) {
 356      global $AppUI, $m;
 357      /*
 358      if (strpos( $src, '.png' ) > 0 && strpos( $_SERVER['HTTP_USER_AGENT'], 'MSIE 6.0' ) !== false) {
 359      return "<div style=\"height:{$hgt}px; width:{$wid}px; filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='$src', sizingMethod='scale');\" ></div>";
 360      } else {
 361      */
 362      if ($src == '') {
 363          return '';
 364      } elseif ($module) {
 365          $src = w2PfindImage($src, $module);
 366      } else {
 367          $src = w2PfindImage($src, $m);
 368      }
 369  
 370      if (!$alt && !$title) {
 371          $result = '';
 372      } elseif ($alt && $title) {
 373          $result = w2PtoolTip($alt, $title);
 374      } elseif ($alt && !$title) {
 375          $result = w2PtoolTip($m, $alt);
 376      } elseif (!$alt && $title) {
 377          $result = w2PtoolTip($m, $title);
 378      }
 379      $result .= '<img src="' . $src . '" alt="" ';
 380      if ($wid) {
 381          $result .= ' width="' . $wid . '"';
 382      }
 383      if ($hgt) {
 384          $result .= ' height="' . $hgt . '"';
 385      }
 386      $result .= ' border="0" />';
 387      if (!$alt && !$title) {
 388          //do nothing
 389      } elseif ($alt && $title) {
 390          $result .= w2PendTip();
 391      } elseif ($alt && !$title) {
 392          $result .= w2PendTip();
 393      } elseif (!$alt && $title) {
 394          $result .= w2PendTip();
 395      }
 396  
 397      return $result;
 398  }
 399  
 400  /**
 401   * function to return a default value if a variable is not set
 402   */
 403  function defVal($var, $def) {
 404      return isset($var) ? $var : $def;
 405  }
 406  
 407  /**
 408   * Utility function to return a value from a named array or a specified default, and avoid poisoning the URL by denying:
 409   * 1) the use of spaces (for SQL and XSS injection)
 410   * 2) the use of <, ", [, ; and { (for XSS injection)
 411   */
 412  function w2PgetParam(&$arr, $name, $def = null) {
 413      global $AppUI;
 414      if ((strpos($arr[$name], ' ') === false && strpos($arr[$name], '<') === false && strpos($arr[$name], '"') === false && strpos($arr[$name], '[') === false && strpos($arr[$name], ';') === false && strpos($arr[$name], '{') === false) || ($arr == $_POST)) {
 415          return isset($arr[$name]) ? $arr[$name] : $def;        
 416      } else {
 417          /*echo('<pre>');
 418          print_r(debug_backtrace());
 419          echo('</pre>');
 420          print_r($arr[$name]);die;*/
 421          //Hack attempt detected
 422          //return isset($arr[$name]) ? str_replace(' ','',$arr[$name]) : $def;
 423          $AppUI->setMsg('Poisoning attempt to the URL detected. Issue logged.', UI_MSG_ALERT);
 424          $AppUI->redirect('m=public&a=access_denied');
 425      }
 426  }
 427  
 428  /**
 429   * Alternative to protect from XSS attacks.
 430   */
 431  function w2PgetCleanParam(&$arr, $name, $def = null) {
 432      $val = isset($arr[$name]) ? $arr[$name] : $def;
 433      if (empty($val)) {
 434          return $val;
 435      }
 436      // Code from http://quickwired.com/kallahar/smallprojects/php_xss_filter_function.php
 437      // remove all non-printable characters. CR(0a) and LF(0b) and TAB(9) are allowed
 438      // this prevents some character re-spacing such as <java\0script>
 439      // note that you have to handle splits with \n, \r, and \t later since they *are* allowed in some inputs
 440      $val = preg_replace('/([\x00-\x08][\x0b-\x0c][\x0e-\x20])/', '', $val);
 441  
 442      // straight replacements, the user should never need these since they're normal characters
 443      // this prevents like <IMG SRC=&#X40&#X61&#X76&#X61&#X73&#X63&#X72&#X69&#X70&#X74&#X3A&#X61&#X6C&#X65&#X72&#X74&#X28&#X27&#X58&#X53&#X53&#X27&#X29>
 444      $search = 'abcdefghijklmnopqrstuvwxyz';
 445      $search .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
 446      $search .= '1234567890!@#$%^&*()';
 447      $search .= '~`";:?+/={}[]-_|\'\\';
 448      for ($i = 0, $i_cmp = strlen($search); $i < $i_cmp; $i++) {
 449          // ;? matches the ;, which is optional
 450          // 0{0,7} matches any padded zeros, which are optional and go up to 8 chars
 451  
 452          // &#x0040 @ search for the hex values
 453          $val = preg_replace('/(&#[x|X]0{0,8}' . dechex(ord($search[$i])) . ';?)/i', $search[$i], $val); // with a ;
 454          // &#00064 @ 0{0,7} matches '0' zero to seven times
 455          $val = preg_replace('/(&#0{0,8}' . ord($search[$i]) . ';?)/', $search[$i], $val); // with a ;
 456      }
 457  
 458      // now the only remaining whitespace attacks are \t, \n, and \r
 459      $ra1 = array('javascript', 'vbscript', 'expression', 'applet', 'meta', 'xml', 'blink', 'link', 'style', 'script', 'embed', 'object', 'iframe', 'frame', 'frameset', 'ilayer', 'layer', 'bgsound', 'title', 'base');
 460      $ra2 = array('onabort', 'onactivate', 'onafterprint', 'onafterupdate', 'onbeforeactivate', 'onbeforecopy', 'onbeforecut', 'onbeforedeactivate', 'onbeforeeditfocus', 'onbeforepaste', 'onbeforeprint', 'onbeforeunload', 'onbeforeupdate', 'onblur', 'onbounce', 'oncellchange', 'onchange', 'onclick', 'oncontextmenu', 'oncontrolselect', 'oncopy', 'oncut', 'ondataavailable', 'ondatasetchanged', 'ondatasetcomplete', 'ondblclick', 'ondeactivate', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onerror', 'onerrorupdate', 'onfilterchange', 'onfinish', 'onfocus', 'onfocusin', 'onfocusout', 'onhelp', 'onkeydown', 'onkeypress', 'onkeyup', 'onlayoutcomplete', 'onload', 'onlosecapture', 'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmouseout',
 461          'onmouseover', 'onmouseup', 'onmousewheel', 'onmove', 'onmoveend', 'onmovestart', 'onpaste', 'onpropertychange', 'onreadystatechange', 'onreset', 'onresize', 'onresizeend', 'onresizestart', 'onrowenter', 'onrowexit', 'onrowsdelete', 'onrowsinserted', 'onscroll', 'onselect', 'onselectionchange', 'onselectstart', 'onstart', 'onstop', 'onsubmit', 'onunload');
 462      $ra = array_merge($ra1, $ra2);
 463  
 464      $found = true; // keep replacing as long as the previous round replaced something
 465      while ($found == true) {
 466          $val_before = $val;
 467          for ($i = 0, $i_cmp = sizeof($ra); $i < $i_cmp; $i++) {
 468              $pattern = '/';
 469              for ($j = 0, $j_cmp = strlen($ra[$i]); $j < $j_cmp; $j++) {
 470                  if ($j > 0) {
 471                      $pattern .= '(';
 472                      $pattern .= '(&#[x|X]0{0,8}([9][a][b]);?)?';
 473                      $pattern .= '|(&#0{0,8}([9][10][13]);?)?';
 474                      $pattern .= ')?';
 475                  }
 476                  $pattern .= $ra[$i][$j];
 477              }
 478              $pattern .= '/i';
 479              $replacement = substr($ra[$i], 0, 2) . '<x>' . substr($ra[$i], 2); // add in <> to nerf the tag
 480              $val = (in_array($arr[$name], $ra)) ? preg_replace($pattern, $replacement, $val) : $val; // filter out the hex tags
 481              if ($val_before == $val) {
 482                  // no replacements were made, so exit the loop
 483                  $found = false;
 484              }
 485          }
 486      }
 487      return $val;
 488  }
 489  
 490  #
 491  # add history entries for tracking changes
 492  #
 493  
 494  function addHistory($table, $id, $action = 'modify', $description = '', $project_id = 0) {
 495      global $AppUI;
 496      /*
 497      * TODO:
 498      * 1) description should be something like:
 499      *         command(arg1, arg2...)
 500      *  The command should be as module_action
 501      *  for example:
 502      *         forums_new('Forum Name', 'URL')
 503      *
 504      * This way, the history module will be able to display descriptions
 505      * using locale definitions:
 506      *         "forums_new" -> "New forum '%s' was created" -> "Se ha creado un nuevo foro llamado '%s'"
 507      *
 508      * 2) project_id and module_id should be provided in order to filter history entries
 509      *
 510      */
 511      if (!w2PgetConfig('log_changes')) {
 512          return;
 513      }
 514      $description = str_replace("'", "\'", $description);
 515      $q = new DBQuery;
 516      $q->addTable('modules');
 517      $q->addWhere('mod_name = \'History\' and mod_active = 1');
 518      $qid = $q->exec();
 519  
 520      if (!$qid || db_num_rows($qid) == 0) {
 521          $AppUI->setMsg('History module is not loaded, but your config file has requested that changes be logged.  You must either change the config file or install and activate the history module to log changes.', UI_MSG_ALERT);
 522          $q->clear();
 523          return;
 524      }
 525  
 526      $q->clear();
 527      $q->addTable('history');
 528      $q->addInsert('history_action', $action);
 529      $q->addInsert('history_item', $id);
 530      $q->addInsert('history_description', $description);
 531      $q->addInsert('history_user', $AppUI->user_id);
 532      $q->addInsert('history_date', 'now()', false, true);
 533      $q->addInsert('history_project', $project_id);
 534      $q->addInsert('history_table', $table);
 535      $q->exec();
 536      echo db_error();
 537      $q->clear();
 538  }
 539  
 540  ##
 541  ## Looks up a value from the SYSVALS table
 542  ##
 543  function w2PgetSysVal($title) {
 544      $q = new DBQuery;
 545      $q->addTable('sysvals');
 546      $q->addQuery('sysval_value_id, sysval_value');
 547      $q->addWhere('sysval_title = \'' . $title . '\'');
 548      $q->addOrder('sysval_value_id ASC');
 549      $rows = $q->loadList();
 550      $q->clear();
 551  
 552      $arr = array();
 553      // We use trim() to make sure a numeric that has spaces
 554      // is properly treated as a numeric
 555      $key_sort = SORT_NUMERIC;
 556      foreach ($rows as $key => $item) {
 557          if ($item) {
 558              $arr[trim($item['sysval_value_id'])] = trim($item['sysval_value']);
 559              if (!is_numeric(trim($item['sysval_value_id']))) {
 560                  $key_sort = SORT_REGULAR;
 561              }
 562          }
 563      }
 564      ksort($arr, $key_sort);
 565      return $arr;
 566  }
 567  
 568  function w2PuserHasRole($name) {
 569      global $AppUI;
 570      $uid = $AppUI->user_id;
 571      $q = new DBQuery;
 572      $q->addTable('roles', 'r');
 573      $q->addTable('user_roles', 'ur');
 574      $q->addQuery('r.role_id');
 575      $q->addWhere('ur.user_id = ' . $uid . ' AND ur.role_id = r.role_id AND r.role_name = \'' . $name . '\'');
 576      return $q->loadResult();
 577  }
 578  
 579  function w2PformatDuration($x) {
 580      global $AppUI;
 581      $dur_day = floor($x / w2PgetConfig('daily_working_hours'));
 582      //$dur_hour = fmod($x, w2PgetConfig('daily_working_hours'));
 583      $dur_hour = $x - $dur_day * w2PgetConfig('daily_working_hours');
 584      $str = '';
 585      if ($dur_day > 1) {
 586          $str .= $dur_day . ' ' . $AppUI->_('days') . ' ';
 587      } elseif ($dur_day == 1) {
 588          $str .= $dur_day . ' ' . $AppUI->_('day') . ' ';
 589      }
 590  
 591      if ($dur_hour > 1) {
 592          $str .= $dur_hour . ' ' . $AppUI->_('hours');
 593      } elseif ($dur_hour > 0 and $dur_hour <= 1) {
 594          $str .= $dur_hour . ' ' . $AppUI->_('hour');
 595      }
 596  
 597      if ($str == '') {
 598          $str = $AppUI->_('n/a');
 599      }
 600  
 601      return $str;
 602  
 603  }
 604  
 605  /**
 606   */
 607  function w2PsetMicroTime() {
 608      global $microTimeSet;
 609      list($usec, $sec) = explode(' ', microtime());
 610      $microTimeSet = (float)$usec + (float)$sec;
 611  }
 612  
 613  /**
 614   */
 615  function w2PgetMicroDiff() {
 616      global $microTimeSet;
 617      $mt = $microTimeSet;
 618      w2PsetMicroTime();
 619      return sprintf('%.3f', $microTimeSet - $mt);
 620  }
 621  
 622  /**
 623   * Make text safe to output into double-quote enclosed attirbutes of an HTML tag
 624   */
 625  function w2PformSafe($txt, $deslash = false) {
 626      global $locale_char_set;
 627  
 628      if (!$locale_char_set) {
 629          $locale_char_set = 'utf-8';
 630      }
 631  
 632      if (is_object($txt)) {
 633          foreach (get_object_vars($txt) as $k => $v) {
 634              if ($deslash) {
 635                  $obj->$k = htmlspecialchars(stripslashes($v), ENT_COMPAT, $locale_char_set);
 636              } else {
 637                  $obj->$k = htmlspecialchars($v, ENT_COMPAT, $locale_char_set);
 638              }
 639          }
 640      } elseif (is_array($txt)) {
 641          foreach ($txt as $k => $v) {
 642              if ($deslash) {
 643                  $txt[$k] = htmlspecialchars(stripslashes($v), ENT_COMPAT, $locale_char_set);
 644              } else {
 645                  $txt[$k] = htmlspecialchars($v, ENT_COMPAT, $locale_char_set);
 646              }
 647          }
 648      } else {
 649          if ($deslash) {
 650              $txt = htmlspecialchars(stripslashes($txt), ENT_COMPAT, $locale_char_set);
 651          } else {
 652              $txt = htmlspecialchars($txt, ENT_COMPAT, $locale_char_set);
 653          }
 654      }
 655      return $txt;
 656  }
 657  
 658  function convert2days($durn, $units) {
 659      switch ($units) {
 660          case 0:
 661          case 1:
 662              return $durn / w2PgetConfig('daily_working_hours');
 663              break;
 664          case 24:
 665              return $durn;
 666      }
 667  }
 668  
 669  function formatTime($uts) {
 670      global $AppUI;
 671      $date = new CDate();
 672      $date->setDate($uts, DATE_FORMAT_UNIXTIME);
 673      return $date->format($AppUI->getPref('SHDATEFORMAT'));
 674  }
 675  
 676  /**
 677   * This function is necessary because Windows likes to
 678   * write their own standards.  Nothing that depends on locales
 679   * can be trusted in Windows.
 680   */
 681  function formatCurrency($number, $format) {
 682      global $AppUI, $locale_char_set;
 683  
 684      if (!$format) {
 685          $format = $AppUI->getPref('SHCURRFORMAT');
 686      }
 687      // If the requested locale doesn't work, don't fail,
 688      // revert to the system default.
 689      if ($locale_char_set != 'utf-8' || !setlocale(LC_MONETARY, $format . '.UTF8')) {
 690          if (!setlocale(LC_MONETARY, $format)) {
 691              setlocale(LC_MONETARY, '');
 692          }
 693      }
 694  
 695      // Technically this should be acheivable with the following, however
 696      // it seems that some versions of PHP will set this incorrectly
 697      // and you end up with everything using locale C.
 698      // setlocale(LC_MONETARY, $format . '.UTF8', $format, '');
 699  
 700      if (function_exists('money_format')) {
 701          return money_format('%i', $number);
 702      }
 703  
 704      // NOTE: This is called if money format doesn't exist.
 705      // Money_format only exists on non-windows 4.3.x sites.
 706      // This uses localeconv to get the information required
 707      // to format the money.  It tries to set reasonable defaults.
 708      $mondat = localeconv();
 709      if (!isset($mondat['int_frac_digits']) || $mondat['int_frac_digits'] > 100) {
 710          $mondat['int_frac_digits'] = 2;
 711      }
 712      if (!isset($mondat['int_curr_symbol'])) {
 713          $mondat['int_curr_symbol'] = '';
 714      }
 715      if (!isset($mondat['mon_decimal_point'])) {
 716          $mondat['mon_decimal_point'] = '.';
 717      }
 718      if (!isset($mondat['mon_thousands_sep'])) {
 719          $mondat['mon_thousands_sep'] = ',';
 720      }
 721      $numeric_portion = number_format(abs($number), $mondat['int_frac_digits'], $mondat['mon_decimal_point'], $mondat['mon_thousands_sep']);
 722      // Not sure, but most countries don't put the sign in if it is positive.
 723      $letter = 'p';
 724      $currency_prefix = '';
 725      $currency_suffix = '';
 726      $prefix = '';
 727      $suffix = '';
 728      if ($number < 0) {
 729          $sign = $mondat['negative_sign'];
 730          $letter = 'n';
 731          switch ($mondat['n_sign_posn']) {
 732              case 0:
 733                  $prefix = '(';
 734                  $suffix = ')';
 735                  break;
 736              case 1:
 737                  $prefix = $sign;
 738                  break;
 739              case 2:
 740                  $suffix = $sign;
 741                  break;
 742              case 3:
 743                  $currency_prefix = $sign;
 744                  break;
 745              case 4:
 746                  $currency_suffix = $sign;
 747                  break;
 748          }
 749      }
 750      $currency .= $currency_prefix . $mondat['int_curr_symbol'] . $currency_suffix;
 751      $space = '';
 752      if ($mondat[$letter . '_sep_by_space']) {
 753          $space = ' ';
 754      }
 755      if ($mondat[$letter . '_cs_precedes']) {
 756          $result = $currency . $space . $numeric_portion;
 757      } else {
 758          $result = $numeric_portion . $space . $currency;
 759      }
 760      return $result;
 761  }
 762  
 763  function format_backtrace($bt, $file, $line, $msg) {
 764      echo '<pre>';
 765      echo 'ERROR: ' . $file . '(' . $line . ') : ' . $msg . "\n";
 766      echo 'Backtrace:' . "\n";
 767      foreach ($bt as $level => $frame) {
 768          echo $level . ' ' . $frame['file'] . ':' . $frame['line'] . ' ' . $frame['function'] . '(';
 769          $in = false;
 770          foreach ($frame['args'] as $arg) {
 771              if ($in) {
 772                  echo ',';
 773              } else {
 774                  $in = true;
 775              }
 776              echo var_export($arg, true);
 777          }
 778          echo ")\n";
 779      }
 780  }
 781  
 782  function dprint($file, $line, $level, $msg) {
 783      $max_level = 0;
 784      $max_level = (int)w2PgetConfig('debug');
 785      $display_debug = w2PgetConfig('display_debug', false);
 786      if ($level <= $max_level) {
 787          error_log($file . '(' . $line . '): ' . $msg);
 788          if ($display_debug) {
 789              echo $file . '(' . $line . '): ' . $msg . ' <br />';
 790          }
 791          if ($level == 0 && $max_level > 0 && version_compare(phpversion(), '4.3.0') >= 0) {
 792              format_backtrace(debug_backtrace(), $file, $line, $msg);
 793          }
 794      }
 795  }
 796  
 797  /**
 798   * Return a list of modules that are associated with tabs for this
 799   * page.  This can be used to find post handlers, for instance.
 800   */
 801  function findTabModules($module, $file = null) {
 802      $modlist = array();
 803      if (!isset($_SESSION['all_tabs']) || !isset($_SESSION['all_tabs'][$module])) {
 804          return $modlist;
 805      }
 806  
 807      if (isset($file)) {
 808          if (isset($_SESSION['all_tabs'][$module][$file]) && is_array($_SESSION['all_tabs'][$module][$file])) {
 809              $tabs_array = &$_SESSION['all_tabs'][$module][$file];
 810          } else {
 811              return $modlist;
 812          }
 813      } else {
 814          $tabs_array = &$_SESSION['all_tabs'][$module];
 815      }
 816      foreach ($tabs_array as $tab) {
 817          if (isset($tab['module'])) {
 818              $modlist[] = $tab['module'];
 819          }
 820      }
 821      return array_unique($modlist);
 822  }
 823  
 824  /**
 825   * Return a list of modules that are associated with crumbs for this
 826   * page.  This can be used to find post handlers, for instance.
 827   */
 828  function findCrumbModules($module, $file = null) {
 829      $modlist = array();
 830      if (!isset($_SESSION['all_crumbs']) || !isset($_SESSION['all_crumbs'][$module])) {
 831          return $modlist;
 832      }
 833  
 834      if (isset($file)) {
 835          if (isset($_SESSION['all_crumbs'][$module][$file]) && is_array($_SESSION['all_crumbs'][$module][$file])) {
 836              $crumbs_array = &$_SESSION['all_crumbs'][$module][$file];
 837          } else {
 838              return $modlist;
 839          }
 840      } else {
 841          $crumbs_array = &$_SESSION['all_crumbs'][$module];
 842      }
 843      foreach ($crumbs_array as $crumb) {
 844          if (isset($crumb['module'])) {
 845              $modlist[] = $crumb['module'];
 846          }
 847      }
 848      return array_unique($modlist);
 849  }
 850  
 851  /**
 852   * @return void
 853   * @param mixed $var
 854   * @param char $title
 855   * @desc Show an estructure (array/object) formatted
 856   */
 857  function showFVar(&$var, $title = '') {
 858      echo '<h1>' . $title . '</h1>';
 859      echo '<pre>';
 860      print_r($var);
 861      echo '</pre>';
 862  }
 863  
 864  function getUsersArray() {
 865      return w2PgetUsersHashList();
 866  
 867  }
 868  
 869  function getUsersCombo($default_user_id = 0, $first_option = 'All users') {
 870      global $AppUI;
 871  
 872      $parsed = '<select name="user_id" class="text">';
 873      if ($first_option != '') {
 874          $parsed .= '<option value="0" ' . (!$default_user_id ? 'selected="selected"' : '') . '>' . $AppUI->_($first_option) . '</option>';
 875      }
 876      foreach (getUsersArray() as $user_id => $user) {
 877          $selected = $user_id == $default_user_id ? ' selected="selected"' : '';
 878          $parsed .= '<option value="' . $user_id . '"' . $selected . '>' . $user['contact_first_name'] . ' ' . $user['contact_last_name'] . '</option>';
 879      }
 880      $parsed .= '</select>';
 881      return $parsed;
 882  }
 883  
 884  /**
 885   * Function to format hours into useful numbers.
 886   * Supplied by GrahamJB.
 887   */
 888  function formatHours($hours) {
 889      global $AppUI;
 890  
 891      $hours = (int)$hours;
 892      $working_hours = w2PgetConfig('daily_working_hours');
 893  
 894      if ($hours < $working_hours) {
 895          if ($hours == 1) {
 896              return '1 ' . $AppUI->_('hour');
 897          } else {
 898              return $hours . ' ' . $AppUI->_('hours');
 899          }
 900      }
 901  
 902      $hoursPart = $hours % $working_hours;
 903      $daysPart = (int)($hours / $working_hours);
 904      if ($hoursPart == 0) {
 905          if ($daysPart == 1) {
 906              return '1 ' . $AppUI->_('day');
 907          } else {
 908              return $daysPart . ' ' . $AppUI->_('days');
 909          }
 910      }
 911  
 912      if ($daysPart == 1) {
 913          return '1 ' . $AppUI->_('day') . ' ' . $hoursPart . ' ' . $AppUI->_('hr');
 914      } else {
 915          return $daysPart . ' ' . $AppUI->_('days') . ' ' . $hoursPart . ' ' . $AppUI->_('hr');
 916      }
 917  }
 918  
 919  /**
 920   * PHP doesn't come with a signum function
 921   */
 922  function w2Psgn($x) {
 923      return $x ? ($x > 0 ? 1 : -1) : 0;
 924  }
 925  
 926  /**
 927   * This function is now deprecated and will be removed.
 928   * In the interim it now does nothing.
 929   */
 930  function dpRealPath($file) {
 931      return $file;
 932  }
 933  
 934  /*
 935  ** Create the Required Fields (From Sysvals) JavaScript Code
 936  ** For instance implemented in projects and tasks addedit.php
 937  ** @param array required field array from SysVals
 938  */
 939  function w2PrequiredFields($requiredFields) {
 940      global $AppUI, $m;
 941      $buffer = 'var foc=false;';
 942  
 943      if (!empty($requiredFields)) {
 944          foreach ($requiredFields as $rf => $comparator) {
 945              $buffer .= 'if (' . $rf . html_entity_decode($comparator, ENT_QUOTES) . ') {';
 946              $buffer .= 'msg += "\n' . $AppUI->_('required_field_' . $rf, UI_OUTPUT_JS) . '";';
 947  
 948              /* MSIE cannot handle the focus command for some disabled or hidden fields like the start/end date fields
 949              ** Another workaround would be to check whether the field is disabled, 
 950              ** but then one would for instance need to use end_date instead of project_end_date in the projects addedit site.
 951              ** As this cannot be guaranteed since these fields are grabbed from a user-specifiable 
 952              ** System Value it's IMHO more safe to disable the focus for MSIE.
 953              */
 954              $r = strstr($rf, '.');
 955              $buffer .= 'if((foc==false) && (navigator.userAgent.indexOf(\'MSIE\')== -1)) {';
 956              $buffer .= 'f.' . substr($r, 1, strpos($r, '.', 1) - 1) . '.focus();';
 957              $buffer .= 'foc=true;}}';
 958          }
 959      }
 960      return $buffer;
 961  }
 962  
 963  /*
 964  * Make function htmlspecialchar_decode for older PHP versions
 965  */
 966  if (!function_exists('htmlspecialchars_decode')) {
 967  	function htmlspecialchars_decode($str) {
 968          return strtr($str, array_flip(get_html_translation_table(HTML_SPECIALCHARS)));
 969      }
 970  }
 971  
 972  /**
 973   * Return the number of bytes represented by a PHP.INI value
 974   */
 975  function w2PgetBytes($str) {
 976      $val = $str;
 977      if (preg_match('/^([0-9]+)([kmg])?$/i', $str, $match)) {
 978          if (!empty($match[2])) {
 979              switch (strtolower($match[2])) {
 980                  case 'k':
 981                      $val = $match[1] * 1024;
 982                      break;
 983                  case 'm':
 984                      $val = $match[1] * 1024 * 1024;
 985                      break;
 986                  case 'g':
 987                      $val = $match[1] * 1024 * 1024 * 1024;
 988                      break;
 989              }
 990          }
 991      }
 992      return $val;
 993  }
 994  
 995  /**
 996   * Check for a memory limit, if we can't generate it then we fail.
 997   * @param int $min minimum amount of memory needed
 998   * @param bool $revert revert back to original config after test.
 999   * @return bool true if we have the minimum amount of RAM and if we can modify RAM
1000   */
1001  function w2PcheckMem($min = 0, $revert = false) {
1002      // First of all check if we have the minimum memory requirement.
1003      $want = w2PgetBytes($GLOBALS['w2Pconfig']['reset_memory_limit']);
1004      $have = ini_get('memory_limit');
1005      // Try upping the memory limit based on our config
1006      ini_set('memory_limit', $GLOBALS['w2Pconfig']['reset_memory_limit']);
1007      $now = w2PgetBytes(ini_get('memory_limit'));
1008      // Revert, if necessary, back to the original after testing.
1009      if ($revert) {
1010          ini_set('memory_limit', $have);
1011      }
1012      if ($now < $want || $now < $min) {
1013          return false;
1014      } else {
1015          return true;
1016      }
1017  }
1018  
1019  /**
1020   * decode HTML entities
1021   */
1022  function w2PHTMLDecode($txt) {
1023      global $locale_char_set;
1024  
1025      if (!$locale_char_set) {
1026          $locale_char_set = 'utf-8';
1027      }
1028  
1029      if (is_object($txt)) {
1030          foreach (get_object_vars($txt) as $k => $v) {
1031              $obj->$k = html_entity_decode($v, ENT_COMPAT);
1032          }
1033      } else
1034          if (is_array($txt)) {
1035              foreach ($txt as $k => $v) {
1036                  $txt[$k] = html_entity_decode($v, ENT_COMPAT);
1037              }
1038          } else {
1039              $txt = html_entity_decode($txt, ENT_COMPAT);
1040          }
1041          return $txt;
1042  }
1043  
1044  function w2PtoolTip($header = '', $tip = '', $raw = false, $id = '') {
1045      global $AppUI;
1046      if ($raw) {
1047          $starttip = '<span id="' . $id . '" title="' . nl2br($AppUI->_($header)) . '::' . nl2br($AppUI->_($tip)) . '">';
1048      } else {
1049          $starttip = '<span id="' . $id . '" title="' . nl2br(ucwords(strtolower($AppUI->_($header)))) . '::' . nl2br(strtolower($AppUI->_($tip))) . '">';
1050      }
1051      return $starttip;
1052  }
1053  
1054  function w2PendTip() {
1055      $endtip = '</span>';
1056      return $endtip;
1057  }
1058  
1059  function w2Phtmlspecialchars($string) {
1060      $trans_tbl = array();
1061      $trans_tbl['"'] = '&quot;';
1062      $trans_tbl["'"] = '&#39;';
1063      $trans_tbl['\\'] = '&#92;';
1064      $trans_tbl['`'] = '&#96;';
1065      $trans_tbl['~'] = '&#126;';
1066      $trans_tbl['¡'] = '&iexcl;';
1067      $trans_tbl['¢'] = '&cent;';
1068      $trans_tbl['£'] = '&pound;';
1069      $trans_tbl['¤'] = '&curren;';
1070      $trans_tbl['¥'] = '&yen;';
1071      $trans_tbl['¦'] = '&brvbar;';
1072      $trans_tbl['§'] = '&sect;';
1073      $trans_tbl['¨'] = '&uml;';
1074      $trans_tbl['©'] = '&copy;';
1075      $trans_tbl['ª'] = '&ordf;';
1076      $trans_tbl['«'] = '&laquo;';
1077      $trans_tbl['¬'] = '&not;';
1078      $trans_tbl['­'] = '&shy;';
1079      $trans_tbl['®'] = '&reg;';
1080      $trans_tbl['¯'] = '&macr;';
1081      $trans_tbl['°'] = '&deg;';
1082      $trans_tbl['±'] = '&plusmn;';
1083      $trans_tbl['²'] = '&sup2;';
1084      $trans_tbl['³'] = '&sup3;';
1085      $trans_tbl['´'] = '&acute;';
1086      $trans_tbl['µ'] = '&micro;';
1087      $trans_tbl['¶'] = '&para;';
1088      $trans_tbl['·'] = '&middot;';
1089      $trans_tbl['¸'] = '&cedil;';
1090      $trans_tbl['¹'] = '&sup1;';
1091      $trans_tbl['º'] = '&ordm;';
1092      $trans_tbl['»'] = '&raquo;';
1093      $trans_tbl['¼'] = '&frac14;';
1094      $trans_tbl['½'] = '&frac12;';
1095      $trans_tbl['¾'] = '&frac34;';
1096      $trans_tbl['¿'] = '&iquest;';
1097      $trans_tbl['À'] = '&Agrave;';
1098      $trans_tbl['Á'] = '&Aacute;';
1099      $trans_tbl['Â'] = '&Acirc;';
1100      $trans_tbl['Ã'] = '&Atilde;';
1101      $trans_tbl['Ä'] = '&Auml;';
1102      $trans_tbl['Å'] = '&Aring;';
1103      $trans_tbl['Æ'] = '&AElig;';
1104      $trans_tbl['Ç'] = '&Ccedil;';
1105      $trans_tbl['È'] = '&Egrave;';
1106      $trans_tbl['É'] = '&Eacute;';
1107      $trans_tbl['Ê'] = '&Ecirc;';
1108      $trans_tbl['Ë'] = '&Euml;';
1109      $trans_tbl['Ì'] = '&Igrave;';
1110      $trans_tbl['Í'] = '&Iacute;';
1111      $trans_tbl['Î'] = '&Icirc;';
1112      $trans_tbl['Ï'] = '&Iuml;';
1113      $trans_tbl['Ð'] = '&ETH;';
1114      $trans_tbl['Ñ'] = '&Ntilde;';
1115      $trans_tbl['Ò'] = '&Ograve;';
1116      $trans_tbl['Ó'] = '&Oacute;';
1117      $trans_tbl['Ô'] = '&Ocirc;';
1118      $trans_tbl['Õ'] = '&Otilde;';
1119      $trans_tbl['Ö'] = '&Ouml;';
1120      $trans_tbl['×'] = '&times;';
1121      $trans_tbl['Ø'] = '&Oslash;';
1122      $trans_tbl['Ù'] = '&Ugrave;';
1123      $trans_tbl['Ú'] = '&Uacute;';
1124      $trans_tbl['Û'] = '&Ucirc;';
1125      $trans_tbl['Ü'] = '&Uuml;';
1126      $trans_tbl['Ý'] = '&Yacute;';
1127      $trans_tbl['Þ'] = '&THORN;';
1128      $trans_tbl['ß'] = '&szlig;';
1129      $trans_tbl['ß'] = '&szlig;';
1130      $trans_tbl['à'] = '&agrave;';
1131      $trans_tbl['á'] = '&aacute;';
1132      $trans_tbl['â'] = '&acirc;';
1133      $trans_tbl['ã'] = '&atilde;';
1134      $trans_tbl['ä'] = '&auml;';
1135      $trans_tbl['å'] = '&aring;';
1136      $trans_tbl['æ'] = '&aelig;';
1137      $trans_tbl['ç'] = '&ccedil;';
1138      $trans_tbl['è'] = '&egrave;';
1139      $trans_tbl['é'] = '&eacute;';
1140      $trans_tbl['ê'] = '&ecirc;';
1141      $trans_tbl['ë'] = '&euml;';
1142      $trans_tbl['ì'] = '&igrave;';
1143      $trans_tbl['í'] = '&iacute;';
1144      $trans_tbl['î'] = '&icirc;';
1145      $trans_tbl['ï'] = '&iuml;';
1146      $trans_tbl['ð'] = '&eth;';
1147      $trans_tbl['ñ'] = '&ntilde;';
1148      $trans_tbl['ò'] = '&ograve;';
1149      $trans_tbl['ó'] = '&oacute;';
1150      $trans_tbl['ô'] = '&ocirc;';
1151      $trans_tbl['õ'] = '&otilde;';
1152      $trans_tbl['ö'] = '&ouml;';
1153      $trans_tbl['÷'] = '&divide;';
1154      $trans_tbl['ø'] = '&oslash;';
1155      $trans_tbl['ù'] = '&ugrave;';
1156      $trans_tbl['ú'] = '&uacute;';
1157      $trans_tbl['û'] = '&ucirc;';
1158      $trans_tbl['ü'] = '&uuml;';
1159      $trans_tbl['ý'] = '&yacute;';
1160      $trans_tbl['þ'] = '&thorn;';
1161      $trans_tbl['ÿ'] = '&yuml;';
1162      $trans_tbl['Œ'] = '&OElig;';
1163      $trans_tbl['œ'] = '&oelig;';
1164      $trans_tbl['Š'] = '&Scaron;';
1165      $trans_tbl['š'] = '&scaron;';
1166      $trans_tbl['Ÿ'] = '&Yuml;';
1167      $trans_tbl['ƒ'] = '&fnof;';
1168      $trans_tbl['ˆ'] = '&circ;';
1169      $trans_tbl['˜'] = '&tilde;';
1170      $trans_tbl['Α'] = '&Alpha;';
1171      $trans_tbl['Β'] = '&Beta;';
1172      $trans_tbl['Γ'] = '&Gamma;';
1173      $trans_tbl['Δ'] = '&Delta;';
1174      $trans_tbl['Ε'] = '&Epsilon;';
1175      $trans_tbl['Ζ'] = '&Zeta;';
1176      $trans_tbl['Η'] = '&Eta;';
1177      $trans_tbl['Θ'] = '&Theta;';
1178      $trans_tbl['Ι'] = '&Iota;';
1179      $trans_tbl['Κ'] = '&Kappa;';
1180      $trans_tbl['Λ'] = '&Lambda;';
1181      $trans_tbl['Μ'] = '&Mu;';
1182      $trans_tbl['Ν'] = '&Nu;';
1183      $trans_tbl['Ξ'] = '&Xi;';
1184      $trans_tbl['Ο'] = '&Omicron;';
1185      $trans_tbl['Π'] = '&Pi;';
1186      $trans_tbl['Ρ'] = '&Rho;';
1187      $trans_tbl['Σ'] = '&Sigma;';
1188      $trans_tbl['Τ'] = '&Tau;';
1189      $trans_tbl['Υ'] = '&Upsilon;';
1190      $trans_tbl['Φ'] = '&Phi;';
1191      $trans_tbl['Χ'] = '&Chi;';
1192      $trans_tbl['Ψ'] = '&Psi;';
1193      $trans_tbl['Ω'] = '&Omega;';
1194      $trans_tbl['α'] = '&alpha;';
1195      $trans_tbl['β'] = '&beta;';
1196      $trans_tbl['γ'] = '&gamma;';
1197      $trans_tbl['δ'] = '&delta;';
1198      $trans_tbl['ε'] = '&epsilon;';
1199      $trans_tbl['ζ'] = '&zeta;';
1200      $trans_tbl['η'] = '&eta;';
1201      $trans_tbl['θ'] = '&theta;';
1202      $trans_tbl['ι'] = '&iota;';
1203      $trans_tbl['κ'] = '&kappa;';
1204      $trans_tbl['λ'] = '&lambda;';
1205      $trans_tbl['μ'] = '&mu;';
1206      $trans_tbl['ν'] = '&nu;';
1207      $trans_tbl['ξ'] = '&xi;';
1208      $trans_tbl['ο'] = '&omicron;';
1209      $trans_tbl['π'] = '&pi;';
1210      $trans_tbl['ρ'] = '&rho;';
1211      $trans_tbl['ς'] = '&sigmaf;';
1212      $trans_tbl['σ'] = '&sigma;';
1213      $trans_tbl['τ'] = '&tau;';
1214      $trans_tbl['υ'] = '&upsilon;';
1215      $trans_tbl['φ'] = '&phi;';
1216      $trans_tbl['χ'] = '&chi;';
1217      $trans_tbl['ψ'] = '&psi;';
1218      $trans_tbl['ω'] = '&omega;';
1219      $trans_tbl['‌'] = '&zwnj;';
1220      $trans_tbl['‍'] = '&zwj;';
1221      $trans_tbl['‎'] = '&lrm;';
1222      $trans_tbl['‏'] = '&rlm;';
1223      $trans_tbl['–'] = '&ndash;';
1224      $trans_tbl['—'] = '&mdash;';
1225      $trans_tbl['‘'] = '&lsquo;';
1226      $trans_tbl['’'] = '&rsquo;';
1227      $trans_tbl['‚'] = '&sbquo;';
1228      $trans_tbl['“'] = '&ldquo;';
1229      $trans_tbl['”'] = '&rdquo;';
1230      $trans_tbl['„'] = '&bdquo;';
1231      $trans_tbl['†'] = '&dagger;';
1232      $trans_tbl['‡'] = '&Dagger;';
1233      $trans_tbl['•'] = '&bull;';
1234      $trans_tbl['…'] = '&hellip;';
1235      $trans_tbl['‰'] = '&permil;';
1236      $trans_tbl['´'] = '&prime;';
1237      $trans_tbl['″'] = '&Prime;';
1238      $trans_tbl['‹'] = '&lsaquo;';
1239      $trans_tbl['›'] = '&rsaquo;';
1240      $trans_tbl['‾'] = '&oline;';
1241      $trans_tbl['⁄'] = '&frasl;';
1242      $trans_tbl['€'] = '&euro;';
1243      $trans_tbl['™'] = '&trade;';
1244      $trans_tbl['←'] = '&larr;';
1245      $trans_tbl['↑'] = '&uarr;';
1246      $trans_tbl['→'] = '&rarr;';
1247      $trans_tbl['↓'] = '&darr;';
1248      $trans_tbl['↔'] = '&harr;';
1249      $trans_tbl['∂'] = '&part;';
1250      $trans_tbl['∏'] = '&prod;';
1251      $trans_tbl['∑'] = '&sum;';
1252      $trans_tbl['−'] = '&minus;';
1253      $trans_tbl['√'] = '&radic;';
1254      $trans_tbl['∞'] = '&infin;';
1255      $trans_tbl['∩'] = '&cap;';
1256      $trans_tbl['∫'] = '&int;';
1257      $trans_tbl['≈'] = '&asymp;';
1258      $trans_tbl['≠'] = '&ne;';
1259      $trans_tbl['≡'] = '&equiv;';
1260      $trans_tbl['≤'] = '&le;';
1261      $trans_tbl['≥'] = '&ge;';
1262      $trans_tbl['◊'] = '&loz;';
1263      $trans_tbl['♠'] = '&spades;';
1264      $trans_tbl['♣'] = '&clubs;';
1265      $trans_tbl['♥'] = '&hearts;';
1266      $trans_tbl['♦'] = '&diams;';
1267      return strtr($string, $trans_tbl);
1268  }
1269  
1270  function w2Phtml_entity_decode($string) {
1271      // replace numeric entities
1272      $string = preg_replace('~&#x([0-9a-f]+);~ei', 'chr(hexdec("\\1"))', $string);
1273      $string = preg_replace('~&#([0-9]+);~e', 'chr(\\1)', $string);
1274      // replace literal entities
1275      $trans_tbl = get_html_translation_table(HTML_ENTITIES);
1276      $trans_tbl = array_flip($trans_tbl);
1277      $trans_tbl['&iexcl;'] = '¡';
1278      $trans_tbl['&cent;'] = '¢';
1279      $trans_tbl['&pound;'] = '£';
1280      $trans_tbl['&curren;'] = '¤';
1281      $trans_tbl['&yen;'] = '¥';
1282      $trans_tbl['&brvbar;'] = '¦';
1283      $trans_tbl['&sect;'] = '§';
1284      $trans_tbl['&uml;'] = '¨';
1285      $trans_tbl['&copy;'] = '©';
1286      $trans_tbl['&ordf;'] = 'ª';
1287      $trans_tbl['&laquo;'] = '«';
1288      $trans_tbl['&not;'] = '¬';
1289      $trans_tbl['&shy;'] = '­';
1290      $trans_tbl['&reg;'] = '®';
1291      $trans_tbl['&macr;'] = '¯';
1292      $trans_tbl['&deg;'] = '°';
1293      $trans_tbl['&plusmn;'] = '±';
1294      $trans_tbl['&sup2;'] = '²';
1295      $trans_tbl['&sup3;'] = '³';
1296      $trans_tbl['&acute;'] = '´';
1297      $trans_tbl['&micro;'] = 'µ';
1298      $trans_tbl['&para;'] = '¶';
1299      $trans_tbl['&middot;'] = '·';
1300      $trans_tbl['&cedil;'] = '¸';
1301      $trans_tbl['&sup1;'] = '¹';
1302      $trans_tbl['&ordm;'] = 'º';
1303      $trans_tbl['&raquo;'] = '»';
1304      $trans_tbl['&frac14;'] = '¼';
1305      $trans_tbl['&frac12;'] = '½';
1306      $trans_tbl['&frac34;'] = '¾';
1307      $trans_tbl['&iquest;'] = '¿';
1308      $trans_tbl['&Agrave;'] = 'À';
1309      $trans_tbl['&Aacute;'] = 'Á';
1310      $trans_tbl['&Acirc;'] = 'Â';
1311      $trans_tbl['&Atilde;'] = 'Ã';
1312      $trans_tbl['&Auml;'] = 'Ä';
1313      $trans_tbl['&Aring;'] = 'Å';
1314      $trans_tbl['&AElig;'] = 'Æ';
1315      $trans_tbl['&Ccedil;'] = 'Ç';
1316      $trans_tbl['&Egrave;'] = 'È';
1317      $trans_tbl['&Eacute;'] = 'É';
1318      $trans_tbl['&Ecirc;'] = 'Ê';
1319      $trans_tbl['&Euml;'] = 'Ë';
1320      $trans_tbl['&Igrave;'] = 'Ì';
1321      $trans_tbl['&Iacute;'] = 'Í';
1322      $trans_tbl['&Icirc;'] = 'Î';
1323      $trans_tbl['&Iuml;'] = 'Ï';
1324      $trans_tbl['&ETH;'] = 'Ð';
1325      $trans_tbl['&Ntilde;'] = 'Ñ';
1326      $trans_tbl['&Ograve;'] = 'Ò';
1327      $trans_tbl['&Oacute;'] = 'Ó';
1328      $trans_tbl['&Ocirc;'] = 'Ô';
1329      $trans_tbl['&Otilde;'] = 'Õ';
1330      $trans_tbl['&Ouml;'] = 'Ö';
1331      $trans_tbl['&times;'] = '×';
1332      $trans_tbl['&Oslash;'] = 'Ø';
1333      $trans_tbl['&Ugrave;'] = 'Ù';
1334      $trans_tbl['&Uacute;'] = 'Ú';
1335      $trans_tbl['&Ucirc;'] = 'Û';
1336      $trans_tbl['&Uuml;'] = 'Ü';
1337      $trans_tbl['&Yacute;'] = 'Ý';
1338      $trans_tbl['&THORN;'] = 'Þ';
1339      $trans_tbl['&szlig;'] = 'ß';
1340      $trans_tbl['&szlig;'] = 'ß';
1341      $trans_tbl['&agrave;'] = 'à';
1342      $trans_tbl['&aacute;'] = 'á';
1343      $trans_tbl['&acirc;'] = 'â';
1344      $trans_tbl['&atilde;'] = 'ã';
1345      $trans_tbl['&auml;'] = 'ä';
1346      $trans_tbl['&aring;'] = 'å';
1347      $trans_tbl['&aelig;'] = 'æ';
1348      $trans_tbl['&ccedil;'] = 'ç';
1349      $trans_tbl['&egrave;'] = 'è';
1350      $trans_tbl['&eacute;'] = 'é';
1351      $trans_tbl['&ecirc;'] = 'ê';
1352      $trans_tbl['&euml;'] = 'ë';
1353      $trans_tbl['&igrave;'] = 'ì';
1354      $trans_tbl['&iacute;'] = 'í';
1355      $trans_tbl['&icirc;'] = 'î';
1356      $trans_tbl['&iuml;'] = 'ï';
1357      $trans_tbl['&eth;'] = 'ð';
1358      $trans_tbl['&ntilde;'] = 'ñ';
1359      $trans_tbl['&ograve;'] = 'ò';
1360      $trans_tbl['&oacute;'] = 'ó';
1361      $trans_tbl['&ocirc;'] = 'ô';
1362      $trans_tbl['&otilde;'] = 'õ';
1363      $trans_tbl['&ouml;'] = 'ö';
1364      $trans_tbl['&divide;'] = '÷';
1365      $trans_tbl['&oslash;'] = 'ø';
1366      $trans_tbl['&ugrave;'] = 'ù';
1367      $trans_tbl['&uacute;'] = 'ú';
1368      $trans_tbl['&ucirc;'] = 'û';
1369      $trans_tbl['&uuml;'] = 'ü';
1370      $trans_tbl['&yacute;'] = 'ý';
1371      $trans_tbl['&thorn;'] = 'þ';
1372      $trans_tbl['&yuml;'] = 'ÿ';
1373      $trans_tbl['&OElig;'] = 'Œ';
1374      $trans_tbl['&oelig;'] = 'œ';
1375      $trans_tbl['&Scaron;'] = 'Š';
1376      $trans_tbl['&scaron;'] = 'š';
1377      $trans_tbl['&Yuml;'] = 'Ÿ';
1378      $trans_tbl['&fnof;'] = 'ƒ';
1379      $trans_tbl['&circ;'] = 'ˆ';
1380      $trans_tbl['&tilde;'] = '˜';
1381      $trans_tbl['&Alpha;'] = 'Α';
1382      $trans_tbl['&Beta;'] = 'Β';
1383      $trans_tbl['&Gamma;'] = 'Γ';
1384      $trans_tbl['&Delta;'] = 'Δ';
1385      $trans_tbl['&Epsilon;'] = 'Ε';
1386      $trans_tbl['&Zeta;'] = 'Ζ';
1387      $trans_tbl['&Eta;'] = 'Η';
1388      $trans_tbl['&Theta;'] = 'Θ';
1389      $trans_tbl['&Iota;'] = 'Ι';
1390      $trans_tbl['&Kappa;'] = 'Κ';
1391      $trans_tbl['&Lambda;'] = 'Λ';
1392      $trans_tbl['&Mu;'] = 'Μ';
1393      $trans_tbl['&Nu;'] = 'Ν';
1394      $trans_tbl['&Xi;'] = 'Ξ';
1395      $trans_tbl['&Omicron;'] = 'Ο';
1396      $trans_tbl['&Pi;'] = 'Π';
1397      $trans_tbl['&Rho;'] = 'Ρ';
1398      $trans_tbl['&Sigma;'] = 'Σ';
1399      $trans_tbl['&Tau;'] = 'Τ';
1400      $trans_tbl['&Upsilon;'] = 'Υ';
1401      $trans_tbl['&Phi;'] = 'Φ';
1402      $trans_tbl['&Chi;'] = 'Χ';
1403      $trans_tbl['&Psi;'] = 'Ψ';
1404      $trans_tbl['&Omega;'] = 'Ω';
1405      $trans_tbl['&alpha;'] = 'α';
1406      $trans_tbl['&beta;'] = 'β';
1407      $trans_tbl['&gamma;'] = 'γ';
1408      $trans_tbl['&delta;'] = 'δ';
1409      $trans_tbl['&epsilon;'] = 'ε';
1410      $trans_tbl['&zeta;'] = 'ζ';
1411      $trans_tbl['&eta;'] = 'η';
1412      $trans_tbl['&theta;'] = 'θ';
1413      $trans_tbl['&iota;'] = 'ι';
1414      $trans_tbl['&kappa;'] = 'κ';
1415      $trans_tbl['&lambda;'] = 'λ';
1416      $trans_tbl['&mu;'] = 'μ';
1417      $trans_tbl['&nu;'] = 'ν';
1418      $trans_tbl['&xi;'] = 'ξ';
1419      $trans_tbl['&omicron;'] = 'ο';
1420      $trans_tbl['&pi;'] = 'π';
1421      $trans_tbl['&rho;'] = 'ρ';
1422      $trans_tbl['&sigmaf;'] = 'ς';
1423      $trans_tbl['&sigma;'] = 'σ';
1424      $trans_tbl['&tau;'] = 'τ';
1425      $trans_tbl['&upsilon;'] = 'υ';
1426      $trans_tbl['&phi;'] = 'φ';
1427      $trans_tbl['&chi;'] = 'χ';
1428      $trans_tbl['&psi;'] = 'ψ';
1429      $trans_tbl['&omega;'] = 'ω';
1430      $trans_tbl['&zwnj;'] = '‌';
1431      $trans_tbl['&zwj;'] = '‍';
1432      $trans_tbl['&lrm;'] = '‎';
1433      $trans_tbl['&rlm;'] = '‏';
1434      $trans_tbl['&ndash;'] = '–';
1435      $trans_tbl['&mdash;'] = '—';
1436      $trans_tbl['&lsquo;'] = '‘';
1437      $trans_tbl['&rsquo;'] = '’';
1438      $trans_tbl['&sbquo;'] = '‚';
1439      $trans_tbl['&ldquo;'] = '“';
1440      $trans_tbl['&rdquo;'] = '”';
1441      $trans_tbl['&bdquo;'] = '„';
1442      $trans_tbl['&dagger;'] = '†';
1443      $trans_tbl['&Dagger;'] = '‡';
1444      $trans_tbl['&bull;'] = '•';
1445      $trans_tbl['&hellip;'] = '…';
1446      $trans_tbl['&permil;'] = '‰';
1447      $trans_tbl['&prime;'] = "′";
1448      $trans_tbl['&Prime;'] = '″';
1449      $trans_tbl['&lsaquo;'] = '‹';
1450      $trans_tbl['&rsaquo;'] = '›';
1451      $trans_tbl['&oline;'] = '‾';
1452      $trans_tbl['&frasl;'] = '⁄';
1453      $trans_tbl['&euro;'] = '€';
1454      $trans_tbl['&trade;'] = '™';
1455      $trans_tbl['&larr;'] = '←';
1456      $trans_tbl['&uarr;'] = '↑';
1457      $trans_tbl['&rarr;'] = '→';
1458      $trans_tbl['&darr;'] = '↓';
1459      $trans_tbl['&harr;'] = '↔';
1460      $trans_tbl['&part;'] = '∂';
1461      $trans_tbl['&prod;'] = '∏';
1462      $trans_tbl['&sum;'] = '∑';
1463      $trans_tbl['&minus;'] = '−';
1464      $trans_tbl['&radic;'] = '√';
1465      $trans_tbl['&infin;'] = '∞';
1466      $trans_tbl['&cap;'] = '∩';
1467      $trans_tbl['&int;'] = '∫';
1468      $trans_tbl['&asymp;'] = '≈';
1469      $trans_tbl['&ne;'] = '≠';
1470      $trans_tbl['&equiv;'] = '≡';
1471      $trans_tbl['&le;'] = '≤';
1472      $trans_tbl['&ge;'] = '≥';
1473      $trans_tbl['&loz;'] = '◊';
1474      $trans_tbl['&spades;'] = '♠';
1475      $trans_tbl['&clubs;'] = '♣';
1476      $trans_tbl['&hearts;'] = '♥';
1477      $trans_tbl['&diams;'] = '♦';
1478      $trans_tbl['&nbsp;'] = ' ';
1479  
1480      return strtr($string, $trans_tbl);
1481  }
1482  
1483  /**
1484   *    Corrects the charset name if needed be
1485   *
1486   *    @param string $charset the charset string to be checked
1487   *    @access public
1488   */
1489  function w2PcheckCharset($charset) {
1490      if (!(strpos($charset, 'iso') === false)) {
1491          if (strpos($charset, 'iso-') === false) {
1492              return str_replace('iso', 'iso-', $charset);
1493          }
1494      }
1495      return $charset;
1496  }
1497  
1498  /**
1499   *    Write debugging to debug.log file
1500   *
1501   *    @param string $s the debug message
1502   *    @param string $t the header of the message
1503   *    @param string $f the script filename
1504   *    @param string $l the script line 
1505   *    @access public
1506   */
1507  $debug_file = W2P_BASE_DIR . '/files/debug.log';
1508  function w2PwriteDebug($s, $t = '', $f = '?', $l = '?') {
1509      global $debug, $debug_file;
1510      if ($debug && ($fp = fopen($debug_file, "at"))) {
1511          fputs($fp, "Debug message from file [$f], line [$l], at: " . strftime('%H:%S'));
1512          if ($t) {
1513              fputs($fp, "\n * * $t * *\n");
1514          }
1515          fputs($fp, "\n$s\n\n");
1516          fclose($fp);
1517      }
1518  }
1519  ?>


Generated: Sat Jul 17 03:00:04 2010 Cross-referenced by PHPXref 0.7