source: trunk/prototype/app/plugins/davicalCliente/AWLUtilities.php @ 5341

Revision 5341, 23.9 KB checked in by wmerlotto, 12 years ago (diff)

Ticket #2434 - Commit inicial do novo módulo de agenda do Expresso - expressoCalendar

Line 
1<?php
2/**
3* Utility functions of a general nature which are used by
4* most AWL library classes.
5*
6* @package   awl
7* @subpackage   Utilities
8* @author    Andrew McMillan <andrew@mcmillan.net.nz>
9* @copyright Catalyst IT Ltd, Morphoss Ltd <http://www.morphoss.com/>
10* @license   http://www.gnu.org/licenses/lgpl-3.0.txt  GNU LGPL version 3 or later
11*/
12
13if ( !function_exists('dbg_error_log') ) {
14  /**
15  * Writes a debug message into the error log using printf syntax.  If the first
16  * parameter is "ERROR" then the message will _always_ be logged.
17  * Otherwise, the first parameter is a "component" name, and will only be logged
18  * if $c->dbg["component"] is set to some non-null value.
19  *
20  * If you want to see every log message then $c->dbg["ALL"] can be set, to
21  * override the debugging status of the individual components.
22  *
23  * @var string $component The component to identify itself, or "ERROR", or "LOG:component"
24  * @var string $format A format string for the log message
25  * @var [string $parameter ...] Parameters for the format string.
26  */
27  function dbg_error_log() {
28    global $c;
29    $args = func_get_args();
30    $type = "DBG";
31    $component = array_shift($args);
32    if ( substr( $component, 0, 3) == "LOG" ) {
33      // Special escape case for stuff that always gets logged.
34      $type = 'LOG';
35      $component = substr($component,4);
36    }
37    else if ( $component == "ERROR" ) {
38      $type = "***";
39    }
40    else if ( isset($c->dbg["ALL"]) ) {
41      $type = "ALL";
42    }
43    else if ( !isset($c->dbg[strtolower($component)]) ) return;
44
45    $argc = func_num_args();
46    if ( 2 <= $argc ) {
47      $format = array_shift($args);
48    }
49    else {
50      $format = "%s";
51    }
52    @error_log( $c->sysabbr.": $type: $component:". vsprintf( $format, $args ) );
53  }
54}
55
56
57if ( !function_exists('fatal') ) {
58  function fatal() {
59    global $c;
60    $args = func_get_args();
61    $argc = func_num_args();
62    if ( 2 <= $argc ) {
63      $format = array_shift($args);
64    }
65    else {
66      $format = "%s";
67    }
68    @error_log( $c->sysabbr.": FATAL: $component:". vsprintf( $format, $args ) );
69   
70    @error_log( "================= Stack Trace ===================" );
71       
72        $trace = array_reverse(debug_backtrace());
73    array_pop($trace);
74    foreach( $trace AS $k => $v ) {
75          @error_log( sprintf(" ===>  %s[%d] calls %s%s%s()",
76                       $v['file'],
77                       $v['line'],
78                       (isset($v['class'])?$v['class']:''),
79                       (isset($v['type'])?$v['type']:''),
80                       (isset($v['function'])?$v['function']:'')
81              ));
82    }
83    echo "Fatal Error";
84    exit();
85  }
86}
87
88
89if ( !function_exists('trace_bug') ) {
90/**
91* Not as sever as a fatal() call, but we want to log and trace it
92*/
93  function trace_bug() {
94    global $c;
95    $args = func_get_args();
96    $argc = func_num_args();
97    if ( 2 <= $argc ) {
98      $format = array_shift($args);
99    }
100    else {
101      $format = "%s";
102    }
103    @error_log( $c->sysabbr.": BUG: $component:". vsprintf( $format, $args ) );
104   
105    @error_log( "================= Stack Trace ===================" );
106       
107        $trace = array_reverse(debug_backtrace());
108    array_pop($trace);
109    foreach( $trace AS $k => $v ) {
110          @error_log( sprintf(" ===>  %s[%d] calls %s%s%s()",
111                       $v['file'],
112                       $v['line'],
113                       (isset($v['class'])?$v['class']:''),
114                       (isset($v['type'])?$v['type']:''),
115                       (isset($v['function'])?$v['function']:'')
116              ));
117    }
118  }
119}
120
121
122if ( !function_exists('apache_request_headers') ) {
123  /**
124  * Compatibility so we can use the apache function name and still work with CGI
125  * @package awl
126  */
127  eval('
128    function apache_request_headers() {
129        foreach($_SERVER as $key=>$value) {
130            if (substr($key,0,5)=="HTTP_") {
131                $key=str_replace(" ","-",ucwords(strtolower(str_replace("_"," ",substr($key,5)))));
132                $out[$key]=$value;
133            }
134        }
135        return $out;
136    }
137  ');
138}
139
140
141
142if ( !function_exists('dbg_log_array') ) {
143  /**
144  * Function to dump an array to the error log, possibly recursively
145  *
146  * @var string $component Which component should this log message identify itself from
147  * @var string $name What name should this array dump identify itself as
148  * @var array $arr The array to be dumped.
149  * @var boolean $recursive Should the dump recurse into arrays/objects in the array
150  */
151  function dbg_log_array( $component, $name, $arr, $recursive = false ) {
152    if ( !isset($arr) || (gettype($arr) != 'array' && gettype($arr) != 'object') ) {
153      dbg_error_log( $component, "%s: array is not set, or is not an array!", $name);
154      return;
155    }
156    foreach ($arr as $key => $value) {
157      dbg_error_log( $component, "%s: >>%s<< = >>%s<<", $name, $key,
158                      (gettype($value) == 'array' || gettype($value) == 'object' ? gettype($value) : $value) );
159      if ( $recursive && (gettype($value) == 'array' || (gettype($value) == 'object' && "$key" != 'self' && "$key" != 'parent') ) ) {
160        dbg_log_array( $component, "$name"."[$key]", $value, $recursive );
161      }
162    }
163  }
164}
165
166
167
168if ( !function_exists("session_simple_md5") ) {
169  /**
170  * Make a plain MD5 hash of a string, identifying the type of hash it is
171  *
172  * @param string $instr The string to be salted and MD5'd
173  * @return string The *MD5* and the MD5 of the string
174  */
175  function session_simple_md5( $instr ) {
176    global $c;
177    if ( isset($c->dbg['password']) ) dbg_error_log( "Login", "Making plain MD5: instr=$instr, md5($instr)=".md5($instr) );
178    return ( '*MD5*'. md5($instr) );
179  }
180}
181
182
183
184if ( !function_exists("session_salted_md5") ) {
185  /**
186  * Make a salted MD5 string, given a string and (possibly) a salt.
187  *
188  * If no salt is supplied we will generate a random one.
189  *
190  * @param string $instr The string to be salted and MD5'd
191  * @param string $salt Some salt to sprinkle into the string to be MD5'd so we don't get the same PW always hashing to the same value.
192  * @return string The salt, a * and the MD5 of the salted string, as in SALT*SALTEDHASH
193  */
194  function session_salted_md5( $instr, $salt = "" ) {
195    if ( $salt == "" ) $salt = substr( md5(rand(100000,999999)), 2, 8);
196    global $c;
197    if ( isset($c->dbg['password']) ) dbg_error_log( "Login", "Making salted MD5: salt=$salt, instr=$instr, md5($salt$instr)=".md5($salt . $instr) );
198    return ( sprintf("*%s*%s", $salt, md5($salt . $instr) ) );
199  }
200}
201
202
203
204if ( !function_exists("session_salted_sha1") ) {
205  /**
206  * Make a salted SHA1 string, given a string and (possibly) a salt.  PHP5 only (although it
207  * could be made to work on PHP4 (@see http://www.openldap.org/faq/data/cache/347.html). The
208  * algorithm used here is compatible with OpenLDAP so passwords generated through this function
209  * should be able to be migrated to OpenLDAP by using the part following the second '*', i.e.
210  * the '{SSHA}....' part.
211  *
212  * If no salt is supplied we will generate a random one.
213  *
214  * @param string $instr The string to be salted and SHA1'd
215  * @param string $salt Some salt to sprinkle into the string to be SHA1'd so we don't get the same PW always hashing to the same value.
216  * @return string A *, the salt, a * and the SHA1 of the salted string, as in *SALT*SALTEDHASH
217  */
218  function session_salted_sha1( $instr, $salt = "" ) {
219    if ( $salt == "" ) $salt = substr( str_replace('*','',base64_encode(sha1(rand(100000,9999999),true))), 2, 9);
220    global $c;
221    if ( isset($c->dbg['password']) ) dbg_error_log( "Login", "Making salted SHA1: salt=$salt, instr=$instr, encoded($instr$salt)=".base64_encode(sha1($instr . $salt, true).$salt) );
222    return ( sprintf("*%s*{SSHA}%s", $salt, base64_encode(sha1($instr.$salt, true) . $salt ) ) );
223  }
224}
225
226
227if ( !function_exists("session_validate_password") ) {
228  /**
229  * Checks what a user entered against the actual password on their account.
230  * @param string $they_sent What the user entered.
231  * @param string $we_have What we have in the database as their password.  Which may (or may not) be a salted MD5.
232  * @return boolean Whether or not the users attempt matches what is already on file.
233  */
234  function session_validate_password( $they_sent, $we_have ) {
235    if ( preg_match('/^\*\*.+$/', $we_have ) ) {
236      //  The "forced" style of "**plaintext" to allow easier admin setting
237      return ( "**$they_sent" == $we_have );
238    }
239
240    if ( preg_match('/^\*(.+)\*{[A-Z]+}.+$/', $we_have, $regs ) ) {
241      if ( function_exists("session_salted_sha1") ) {
242        // A nicely salted sha1sum like "*<salt>*{SSHA}<salted_sha1>"
243        $salt = $regs[1];
244        $sha1_sent = session_salted_sha1( $they_sent, $salt ) ;
245        return ( $sha1_sent == $we_have );
246      }
247      else {
248        dbg_error_log( "ERROR", "Password is salted SHA-1 but you are using PHP4!" );
249        echo <<<EOERRMSG
250<html>
251<head>
252<title>Salted SHA1 Password format not supported with PHP4</title>
253</head>
254<body>
255<h1>Salted SHA1 Password format not supported with PHP4</h1>
256<p>At some point you have used PHP5 to set the password for this user and now you are
257   using PHP4.  You will need to assign a new password to this user using PHP4, or ensure
258   you use PHP5 everywhere (recommended).</p>
259<p>AWL has now switched to using salted SHA-1 passwords by preference in a format
260   compatible with OpenLDAP.</p>
261</body>
262</html>
263EOERRMSG;
264        exit;
265      }
266    }
267
268    if ( preg_match('/^\*MD5\*.+$/', $we_have, $regs ) ) {
269      // A crappy unsalted md5sum like "*MD5*<md5>"
270      $md5_sent = session_simple_md5( $they_sent ) ;
271      return ( $md5_sent == $we_have );
272    }
273    else if ( preg_match('/^\*(.+)\*.+$/', $we_have, $regs ) ) {
274      // A nicely salted md5sum like "*<salt>*<salted_md5>"
275      $salt = $regs[1];
276      $md5_sent = session_salted_md5( $they_sent, $salt ) ;
277      return ( $md5_sent == $we_have );
278    }
279
280    // Anything else is bad
281    return false;
282
283  }
284}
285
286
287
288if ( !function_exists("replace_uri_params") ) {
289  /**
290  * Given a URL (presumably the current one) and a parameter, replace the value of parameter,
291  * extending the URL as necessary if the parameter is not already there.
292  * @param string $uri The URI we will be replacing parameters in.
293  * @param array $replacements An array of replacement pairs array( "replace_this" => "with this" )
294  * @return string The URI with the replacements done.
295  */
296  function replace_uri_params( $uri, $replacements ) {
297    $replaced = $uri;
298    foreach( $replacements AS $param => $new_value ) {
299      $rxp = preg_replace( '/([\[\]])/', '\\\\$1', $param );  // Some parameters may be arrays.
300      $regex = "/([&?])($rxp)=([^&]+)/";
301      dbg_error_log("core", "Looking for [%s] to replace with [%s] regex is %s and searching [%s]", $param, $new_value, $regex, $replaced );
302      if ( preg_match( $regex, $replaced ) )
303        $replaced = preg_replace( $regex, "\$1$param=$new_value", $replaced);
304      else
305        $replaced .= "&$param=$new_value";
306    }
307    if ( ! preg_match( '/\?/', $replaced  ) ) {
308      $replaced = preg_replace("/&(.+)$/", "?\$1", $replaced);
309    }
310    $replaced = str_replace("&amp;", "--AmPeRsAnD--", $replaced);
311    $replaced = str_replace("&", "&amp;", $replaced);
312    $replaced = str_replace("--AmPeRsAnD--", "&amp;", $replaced);
313    dbg_error_log("core", "URI <<$uri>> morphed to <<$replaced>>");
314    return $replaced;
315  }
316}
317
318
319if ( !function_exists("uuid") ) {
320/**
321 * Generates a Universally Unique IDentifier, version 4.
322 *
323 * RFC 4122 (http://www.ietf.org/rfc/rfc4122.txt) defines a special type of Globally
324 * Unique IDentifiers (GUID), as well as several methods for producing them. One
325 * such method, described in section 4.4, is based on truly random or pseudo-random
326 * number generators, and is therefore implementable in a language like PHP.
327 *
328 * We choose to produce pseudo-random numbers with the Mersenne Twister, and to always
329 * limit single generated numbers to 16 bits (ie. the decimal value 65535). That is
330 * because, even on 32-bit systems, PHP's RAND_MAX will often be the maximum *signed*
331 * value, with only the equivalent of 31 significant bits. Producing two 16-bit random
332 * numbers to make up a 32-bit one is less efficient, but guarantees that all 32 bits
333 * are random.
334 *
335 * The algorithm for version 4 UUIDs (ie. those based on random number generators)
336 * states that all 128 bits separated into the various fields (32 bits, 16 bits, 16 bits,
337 * 8 bits and 8 bits, 48 bits) should be random, except : (a) the version number should
338 * be the last 4 bits in the 3rd field, and (b) bits 6 and 7 of the 4th field should
339 * be 01. We try to conform to that definition as efficiently as possible, generating
340 * smaller values where possible, and minimizing the number of base conversions.
341 *
342 * @copyright  Copyright (c) CFD Labs, 2006. This function may be used freely for
343 *              any purpose ; it is distributed without any form of warranty whatsoever.
344 * @author      David Holmes <dholmes@cfdsoftware.net>
345 *
346 * @return  string  A UUID, made up of 32 hex digits and 4 hyphens.
347 */
348
349  function uuid() {
350
351    // The field names refer to RFC 4122 section 4.1.2
352
353    return sprintf('%04x%04x-%04x-%03x4-%04x-%04x%04x%04x',
354        mt_rand(0, 65535), mt_rand(0, 65535), // 32 bits for "time_low"
355        mt_rand(0, 65535), // 16 bits for "time_mid"
356        mt_rand(0, 4095),  // 12 bits before the 0100 of (version) 4 for "time_hi_and_version"
357        bindec(substr_replace(sprintf('%016b', mt_rand(0, 65535)), '01', 6, 2)),
358            // 8 bits, the last two of which (positions 6 and 7) are 01, for "clk_seq_hi_res"
359            // (hence, the 2nd hex digit after the 3rd hyphen can only be 1, 5, 9 or d)
360            // 8 bits for "clk_seq_low"
361        mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535) // 48 bits for "node"
362    );
363  }
364}
365
366if ( !function_exists("translate") ) {
367    require_once ROOTPATH.'/app/plugins/davicalCliente/Translation.php';
368
369}
370
371 if ( !function_exists("clone") && version_compare(phpversion(), '5.0') < 0) {
372  /**
373  * PHP5 screws with the assignment operator changing so that $a = $b means that
374  * $a becomes a reference to $b.  There is a clone() that we can use in PHP5, so
375  * we have to emulate that for PHP4.  Bleargh.
376  */
377  eval( 'function clone($object) { return $object; }' );
378}
379
380if ( !function_exists("quoted_printable_encode") ) {
381  /**
382  * Process a string to fit the requirements of RFC2045 section 6.7.  Note that
383  * this works, but replaces more characters than the minimum set. For readability
384  * the spaces aren't encoded as =20 though.
385  */
386  function quoted_printable_encode($string) {
387    return preg_replace('/[^\r\n]{73}[^=\r\n]{2}/', "$0=\r\n", str_replace("%","=",str_replace("%20"," ",rawurlencode($string))));
388  }
389}
390
391
392if ( !function_exists("check_by_regex") ) {
393  /**
394  * Verify a value is OK by testing a regex against it.  If it is an array apply it to
395  * each element in the array recursively.  If it is an object we don't mess
396  * with it.
397  */
398  function check_by_regex( $val, $regex ) {
399    if ( is_null($val) ) return null;
400    switch( $regex ) {
401      case 'int':     $regex = '#^\d+$#';     break;
402    }
403    if ( is_array($val) ) {
404      foreach( $val AS $k => $v ) {
405        $val[$k] = check_by_regex($v,$regex);
406      }
407    }
408    else if ( ! is_object($val) ) {
409      if ( preg_match( $regex, $val, $matches) ) {
410        $val = $matches[0];
411      }
412      else {
413        $val = '';
414      }
415    }
416    return $val;
417  }
418}
419
420
421if ( !function_exists("param_to_global") ) {
422  /**
423  * Convert a parameter to a global.  We first look in _POST and then in _GET,
424  * and if they passed in a bunch of valid characters, we will make sure the
425  * incoming is cleaned to only match that set.
426  *
427  * @param string $varname The name of the global variable to put the answer in
428  * @param string $match_regex The part of the parameter matching this regex will be returned
429  * @param string $alias1  An alias for the name that we should look for first.
430  * @param    "    ...     More aliases, in the order which they should be examined.  $varname will be appended to the end.
431  */
432  function param_to_global( ) {
433    $args = func_get_args();
434
435    $varname = array_shift($args);
436    $GLOBALS[$varname] = null;
437
438    $match_regex = null;
439    $argc = func_num_args();
440    if ( $argc > 1 ) {
441      $match_regex = array_shift($args);
442    }
443
444    $args[] = $varname;
445    foreach( $args AS $k => $name ) {
446      if ( isset($_POST[$name]) ) {
447        $result = $_POST[$name];
448        break;
449      }
450      else if ( isset($_GET[$name]) ) {
451        $result = $_GET[$name];
452        break;
453      }
454    }
455    if ( !isset($result) ) return null;
456
457    if ( isset($match_regex) ) {
458      $result = check_by_regex( $result, $match_regex );
459    }
460
461    $GLOBALS[$varname] = $result;
462    return $result;
463  }
464}
465
466
467if ( !function_exists("get_fields") ) {
468  /**
469  * @var array $_AWL_field_cache is a cache of the field names for a table
470  */
471  $_AWL_field_cache = array();
472 
473  /**
474  * Get the names of the fields for a particular table
475  * @param string $tablename The name of the table.
476  * @return array of string The public fields in the table.
477  */
478  function get_fields( $tablename ) {
479    global $_AWL_field_cache;
480
481    if ( !isset($_AWL_field_cache[$tablename]) ) {
482      dbg_error_log( "core", ":get_fields: Loading fields for table '$tablename'" );
483      $qry = new AwlQuery();
484      $db = $qry->GetConnection();
485      $qry->SetSQL($db->GetFields($tablename));
486      $qry->Exec("core");
487      $fields = array();
488      while( $row = $qry->Fetch() ) {
489        $fields[$row->fieldname] = $row->typename . ($row->precision >= 0 ? sprintf('(%d)',$row->precision) : '');
490      }
491      $_AWL_field_cache[$tablename] = $fields;
492    }
493    return $_AWL_field_cache[$tablename];
494  }
495}
496
497
498if ( !function_exists("force_utf8") ) {
499  function define_byte_mappings() {
500    global $byte_map, $nibble_good_chars;
501
502    # Needed for using Grant McLean's byte mappings code
503    $ascii_char = '[\x00-\x7F]';
504    $cont_byte  = '[\x80-\xBF]';
505
506    $utf8_2     = '[\xC0-\xDF]' . $cont_byte;
507    $utf8_3     = '[\xE0-\xEF]' . $cont_byte . '{2}';
508    $utf8_4     = '[\xF0-\xF7]' . $cont_byte . '{3}';
509    $utf8_5     = '[\xF8-\xFB]' . $cont_byte . '{4}';
510
511    $nibble_good_chars = "/^($ascii_char+|$utf8_2|$utf8_3|$utf8_4|$utf8_5)(.*)$/s";
512
513    # From http://unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1252.TXT
514    $byte_map = array(
515        "\x80" => "\xE2\x82\xAC",  # EURO SIGN
516        "\x82" => "\xE2\x80\x9A",  # SINGLE LOW-9 QUOTATION MARK
517        "\x83" => "\xC6\x92",      # LATIN SMALL LETTER F WITH HOOK
518        "\x84" => "\xE2\x80\x9E",  # DOUBLE LOW-9 QUOTATION MARK
519        "\x85" => "\xE2\x80\xA6",  # HORIZONTAL ELLIPSIS
520        "\x86" => "\xE2\x80\xA0",  # DAGGER
521        "\x87" => "\xE2\x80\xA1",  # DOUBLE DAGGER
522        "\x88" => "\xCB\x86",      # MODIFIER LETTER CIRCUMFLEX ACCENT
523        "\x89" => "\xE2\x80\xB0",  # PER MILLE SIGN
524        "\x8A" => "\xC5\xA0",      # LATIN CAPITAL LETTER S WITH CARON
525        "\x8B" => "\xE2\x80\xB9",  # SINGLE LEFT-POINTING ANGLE QUOTATION MARK
526        "\x8C" => "\xC5\x92",      # LATIN CAPITAL LIGATURE OE
527        "\x8E" => "\xC5\xBD",      # LATIN CAPITAL LETTER Z WITH CARON
528        "\x91" => "\xE2\x80\x98",  # LEFT SINGLE QUOTATION MARK
529        "\x92" => "\xE2\x80\x99",  # RIGHT SINGLE QUOTATION MARK
530        "\x93" => "\xE2\x80\x9C",  # LEFT DOUBLE QUOTATION MARK
531        "\x94" => "\xE2\x80\x9D",  # RIGHT DOUBLE QUOTATION MARK
532        "\x95" => "\xE2\x80\xA2",  # BULLET
533        "\x96" => "\xE2\x80\x93",  # EN DASH
534        "\x97" => "\xE2\x80\x94",  # EM DASH
535        "\x98" => "\xCB\x9C",      # SMALL TILDE
536        "\x99" => "\xE2\x84\xA2",  # TRADE MARK SIGN
537        "\x9A" => "\xC5\xA1",      # LATIN SMALL LETTER S WITH CARON
538        "\x9B" => "\xE2\x80\xBA",  # SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
539        "\x9C" => "\xC5\x93",      # LATIN SMALL LIGATURE OE
540        "\x9E" => "\xC5\xBE",      # LATIN SMALL LETTER Z WITH CARON
541        "\x9F" => "\xC5\xB8",      # LATIN CAPITAL LETTER Y WITH DIAERESIS
542    );
543
544    for( $i=160; $i < 256; $i++ ) {
545      $ch = chr($i);
546      $byte_map[$ch] = iconv('ISO-8859-1', 'UTF-8', $ch);
547    }
548  }
549  define_byte_mappings();
550
551  function force_utf8( $input ) {
552    global $byte_map, $nibble_good_chars;
553
554    $output = '';
555    $char   = '';
556    $rest   = '';
557    while( $input != '' ) {
558      if ( preg_match( $nibble_good_chars, $input, $matches ) ) {
559        $output .= $matches[1];
560        $rest = $matches[2];
561      }
562      else {
563        preg_match( '/^(.)(.*)$/s', $input, $matches );
564        $char = $matches[1];
565        $rest = $matches[2];
566        if ( isset($byte_map[$char]) ) {
567          $output .= $byte_map[$char];
568        }
569        else {
570          # Must be valid UTF8 already
571          $output .= $char;
572        }
573      }
574      $input = $rest;
575    }
576    return $output;
577  }
578
579}
580
581
582/**
583* Try and extract something like "Pacific/Auckland" or "America/Indiana/Indianapolis" if possible.
584*/
585function olson_from_tzstring( $tzstring ) {
586  global $c;
587 
588  if ( function_exists('timezone_identifiers_list') && in_array($tzstring,timezone_identifiers_list()) ) return $tzstring;
589  if ( preg_match( '{((Antarctica|America|Africa|Atlantic|Asia|Australia|Indian|Europe|Pacific)/(([^/]+)/)?[^/]+)$}', $tzstring, $matches ) ) {
590//    dbg_error_log( 'INFO', 'Found timezone "%s" from string "%s"', $matches[1], $tzstring );
591    return $matches[1];
592  }
593  switch( $tzstring ) {
594    case 'New Zealand Standard Time': case 'New Zealand Daylight Time':
595         return 'Pacific/Auckland';
596         break;
597    case 'Central Standard Time':     case 'Central Daylight Time':     case 'US/Central':
598         return 'America/Chicago';
599         break;
600    case 'Eastern Standard Time':     case 'Eastern Daylight Time':     case 'US/Eastern':
601    case '(UTC-05:00) Eastern Time (US & Canada)':
602         return 'America/New_York';
603         break;
604    case 'Pacific Standard Time':     case 'Pacific Daylight Time':     case 'US/Pacific':
605         return 'America/Los_Angeles';
606         break;
607    case 'Mountain Standard Time':    case 'Mountain Daylight Time':    case 'US/Mountain':    case 'Mountain Time':
608         return 'America/Denver';
609         // The US 'Mountain Time' can in fact be America/(Denver|Boise|Phoenix|Shiprock) which
610         // all vary to some extent due to differing DST rules.
611         break;
612    case '(GMT-07.00) Arizona':
613         return 'America/Phoenix';
614         break;
615    default:
616         if ( isset($c->timezone_translations) && is_array($c->timezone_translations)
617                      && !empty($c->timezone_translations[$tzstring]) )
618           return $c->timezone_translations[$tzstring];     
619  }
620  return null;
621}
622
623if ( !function_exists("deprecated") ) {
624  function deprecated( $method ) {
625    global $c;
626    if ( isset($c->dbg['ALL']) || isset($c->dbg['deprecated']) ) {
627      $stack = debug_backtrace();
628      array_shift($stack);
629      if ( preg_match( '{/inc/iCalendar.php$}', $stack[0]['file'] ) && $stack[0]['line'] > __LINE__ ) return;
630      @error_log( sprintf( $c->sysabbr.':DEPRECATED: Call to deprecated method "%s"', $method));
631      foreach( $stack AS $k => $v ) {
632        @error_log( sprintf( $c->sysabbr.':  ==>  called from line %4d of %s', $v['line'], $v['file']));
633      }
634    }
635  }
636}
637
638
639if ( !function_exists("gzdecode") ) {
640  function gzdecode( $instring ) {
641    global $c;
642    if ( !isset($c->use_pipe_gunzip) || $c->use_pipe_gunzip ) {
643      $descriptorspec = array(
644         0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
645         1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
646         2 => array("file", "/dev/null", "a") // stderr is discarded
647      );
648      $process = proc_open('gunzip',$descriptorspec, $pipes);
649      if ( is_resource($process) ) {
650        fwrite($pipes[0],$instring);
651        fclose($pipes[0]);
652       
653        $outstring = stream_get_contents($pipes[1]);
654        fclose($pipes[1]);
655       
656        proc_close($process);
657        return $outstring;
658      }
659      return '';
660    }
661    else {
662      $g=tempnam('./','gz');
663      file_put_contents($g,$instring);
664      ob_start();
665      readgzfile($g);
666      $d=ob_get_clean();
667      unlink($g);
668      return $d;
669    }
670  }
671}
672
673/**
674 * Return the AWL version
675 */
676function awl_version() {
677  global $c;
678$c->awl_library_version = 0.49;
679  return $c->awl_library_version;
680}
Note: See TracBrowser for help on using the repository browser.