2 // +----------------------------------------------------------------------+
 
   3 // | Anuko Time Tracker
 
   4 // +----------------------------------------------------------------------+
 
   5 // | Copyright (c) Anuko International Ltd. (https://www.anuko.com)
 
   6 // +----------------------------------------------------------------------+
 
   7 // | LIBERAL FREEWARE LICENSE: This source code document may be used
 
   8 // | by anyone for any purpose, and freely redistributed alone or in
 
   9 // | combination with other software, provided that the license is obeyed.
 
  11 // | There are only two ways to violate the license:
 
  13 // | 1. To redistribute this code in source form, with the copyright
 
  14 // |    notice or license removed or altered. (Distributing in compiled
 
  15 // |    forms without embedded copyright notices is permitted).
 
  17 // | 2. To redistribute modified versions of this code in *any* form
 
  18 // |    that bears insufficient indications that the modifications are
 
  19 // |    not the work of the original author(s).
 
  21 // | This license applies to this document only, not any other software
 
  22 // | that it may be combined with.
 
  24 // +----------------------------------------------------------------------+
 
  26 // | https://www.anuko.com/time_tracker/credits.htm
 
  27 // +----------------------------------------------------------------------+
 
  32          * @param version = "" unknown
 
  35         function import( $class_name ) {
 
  37                         dirname($_SERVER["SCRIPT_FILENAME"]),
 
  41             $pos = strpos($class_name, ".");
 
  42         if (!($pos === false)) {
 
  43             $peaces = explode(".", $class_name);
 
  45             for ($i=0; $i<count($peaces)-1; $i++) {
 
  46                 $p = $p . "/" . $peaces[$i];
 
  48                         $libs = array_merge(array(LIBRARY_DIR . $p),$libs);
 
  49             $class_name = $peaces[count($peaces)-1];
 
  52                 $filename = $class_name . '.class.php';
 
  54                 foreach($libs as $lib) {
 
  55                         $inc_filename = $lib . '/' . $filename;
 
  56                         if (file_exists($inc_filename)) {
 
  57                                         require_once($inc_filename);
 
  62                 print '<br><b>load_class: error loading file "'.$filename.'"</b>';
 
  66         // The mu_sort function is used to sort a multi-dimensional array.
 
  67         // It looks like the code example is taken from the PHP manual http://ca2.php.net/manual/en/function.sort.php
 
  68         function mu_sort($array, $key_sort) {
 
  70                 if (!is_array($array) || count($array)==0)
 
  73                 $key_sorta = explode(",", $key_sort);
 
  74                 $keys = array_keys($array[0]);
 
  76                 for($m=0; $m < count($key_sorta); $m++) {
 
  77                         $nkeys[$m] = trim($key_sorta[$m]);
 
  79                 $n += count($key_sorta);
 
  81                 for($i=0; $i < count($keys); $i++) {
 
  82                         if(!in_array($keys[$i], $key_sorta)) {
 
  83                                 $nkeys[$n] = $keys[$i];
 
  88                 for($u=0;$u<count($array); $u++) {
 
  90                         for($s=0; $s<count($nkeys); $s++) {
 
  92                                 $output[$u][$k] = $array[$u][$k];
 
 102          * @param unknown $value
 
 105         function toFloat($value) {
 
 106                 if (isset($value) && (strlen($value) > 0)) {
 
 107                         $value = str_replace(",",".",$value);
 
 108                         return floatval($value);
 
 113         function stripslashes_deep($value) {
 
 114             $value = is_array($value) ?
 
 115                 array_map('stripslashes_deep', $value) :
 
 116                 stripslashes($value);
 
 120         function &getConnection() {
 
 121         if (!isset($GLOBALS["_MDB2_CONNECTION"])) {
 
 123                 require_once('MDB2.php');
 
 125                 $mdb2 = MDB2::connect(DSN);
 
 126                         if (is_a($mdb2, 'PEAR_Error')) {
 
 127                         die($mdb2->getMessage());
 
 130                         $mdb2->setOption('debug', true);
 
 131                         $mdb2->setFetchMode(MDB2_FETCHMODE_ASSOC);
 
 133                         $GLOBALS["_MDB2_CONNECTION"] = $mdb2;
 
 135         return $GLOBALS["_MDB2_CONNECTION"];
 
 139         function closeConnection() {
 
 140                 if (isset($GLOBALS["_DB_CONNECTION"])) {
 
 141                         $GLOBALS["_DB_CONNECTION"]->close();
 
 142                         unset($GLOBALS["_DB_CONNECTION"]);
 
 146 function time_to_decimal($a) {
 
 147   $tmp = explode(":", $a);
 
 148   if($tmp[1]{0}=="0") $tmp[1] = $tmp[1]{1};
 
 150   $m = round($tmp[1]*100/60);
 
 152   if($m<10) $m = "0".$m;
 
 153   $time = $tmp[0].".".$m;
 
 157 function sec_to_time_fmt_hm($sec)
 
 159   return sprintf("%d:%02d", $sec / 3600, $sec % 3600 / 60);
 
 162 function magic_quotes_off()
 
 164   // if (get_magic_quotes_gpc()) { // This check is now done before calling this function.
 
 165     $_POST = array_map('stripslashes_deep', $_POST);
 
 166     $_GET = array_map('stripslashes_deep', $_GET);
 
 167     $_COOKIE = array_map('stripslashes_deep', $_COOKIE);
 
 171 // check_extension checks whether a required PHP extension is loaded and dies if not so.
 
 172 function check_extension($ext)
 
 174   if (!extension_loaded($ext))
 
 175     die("PHP extension '{$ext}' is required but is not loaded. Read Time Tracker Install Guide for help.");
 
 178 // isTrue is a helper function to return correct false for older config.php values defined as a string 'false'.
 
 179 function isTrue($val)
 
 181   return ($val == false || $val === 'false') ? false : true;
 
 184 // ttValidString is used to check user input to validate a string.
 
 185 function ttValidString($val, $emptyValid = false)
 
 188   if (strlen($val) == 0 && !$emptyValid)
 
 191   // String must not be XSS evil (to insert JavaScript).
 
 192   if (stristr($val, '<script>') || stristr($val, '<script '))
 
 198 // ttValidEmail is used to check user input to validate an email string.
 
 199 function ttValidEmail($val, $emptyValid = false)
 
 202   if (strlen($val) == 0)
 
 203     return ($emptyValid ? true : false);
 
 205   // String must not be XSS evil (to insert JavaScript).
 
 206   if (stristr($val, '<script>') || stristr($val, '<script '))
 
 209   // Validate a single email address. TODO: improve for compliancy with RFC.
 
 210   if (!preg_match("/^[_a-zA-Z\d\'-\.]+@([_a-zA-Z\d\-]+(\.[_a-zA-Z\d\-]+)+)$/", $val))
 
 216 // ttValidEmailList is used to check user input to validate an email string.
 
 217 function ttValidEmailList($val, $emptyValid = false)
 
 220   if (strlen($val) == 0)
 
 221     return ($emptyValid ? true : false);
 
 223   // String must not be XSS evil (to insert JavaScript).
 
 224   if (stristr($val, '<script>') || stristr($val, '<script '))
 
 227   // Validates a list of email addresses separated by a comma with optional spaces.
 
 228   if (!preg_match("/^[_a-zA-Z\d\'-\.]+@([_a-zA-Z\d\-]+(\.[_a-zA-Z\d\-]+)+)(,\s*[_a-zA-Z\d\'-\.]+@([_a-zA-Z\d\-]+(\.[_a-zA-Z\d\-]+)+))*$/", $val))
 
 234 // ttValidFloat is used to check user input to validate a float value.
 
 235 function ttValidFloat($val, $emptyValid = false)
 
 238   if (strlen($val) == 0)
 
 239     return ($emptyValid ? true : false);
 
 242   $decimal = $user->decimal_mark;
 
 244   if (!preg_match('/^-?[0-9'.$decimal.']+$/', $val))
 
 250 // ttValidDate is used to check user input to validate a date.
 
 251 function ttValidDate($val)
 
 254   if (strlen($val) == 0)
 
 257   // This should accept a string in format 'YYYY-MM-DD', 'MM/DD/YYYY', 'DD.MM.YYYY', or 'DD.MM.YYYY whatever'.
 
 258   if (!preg_match('/^\d\d\d\d-\d\d-\d\d$/', $val) &&
 
 259     !preg_match('/^\d\d\/\d\d\/\d\d\d\d$/', $val) &&
 
 260     !preg_match('/^\d\d\.\d\d\.\d\d\d\d$/', $val) &&
 
 261     !preg_match('/^\d\d\.\d\d\.\d\d\d\d .+$/', $val))
 
 267 // ttValidInteger is used to check user input to validate an integer.
 
 268 function ttValidInteger($val, $emptyValid = false)
 
 271   if (strlen($val) == 0)
 
 272     return ($emptyValid ? true : false);
 
 274   if (!preg_match('/^[0-9]+$/', $val))
 
 280 // ttValidCronSpec is used to check user input to validate cron specification.
 
 281 function ttValidCronSpec($val)
 
 283   // This code is adapted from http://stackoverflow.com/questions/235504/validating-crontab-entries-w-php
 
 286      'hour'=>'[01]?\d|2[0-3]',
 
 287      'day'=>'0?[1-9]|[12]\d|3[01]',
 
 288      'month'=>'[1-9]|1[012]',
 
 292   foreach($numbers as $field=>$number) {
 
 293     $range= "($number)(-($number)(\/\d+)?)?";
 
 294     $field_re[$field]= "\*(\/\d+)?|$range(,$range)*";
 
 297   $field_re['month'].='|jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec';
 
 298   $field_re['dow'].='|mon|tue|wed|thu|fri|sat|sun';
 
 300   $fields_re= '('.join(')\s+(', $field_re).')';
 
 303   $replacements= '@reboot|@yearly|@annually|@monthly|@weekly|@daily|@midnight|@hourly';
 
 310                 "|($replacements)\s+\S".
 
 313   // The above block from the link did not work for me.
 
 316   $regexp = '/^'.$fields_re.'$/';
 
 318   if (!preg_match($regexp, $val))
 
 324 // ttAccessCheck is used to check whether user is allowed to proceed. This function is used
 
 325 // as an initial check on all publicly available pages.
 
 326 function ttAccessCheck($required_rights)
 
 331   // Redirect to login page if user is not authenticated.
 
 332   if (!$auth->isAuthenticated()) {
 
 333     header('Location: login.php');
 
 338   if (!($required_rights & $user->rights))