1<?php
2/*********************************************************************
3    class.misc.php
4
5    Misc collection of useful generic helper functions.
6
7    Peter Rotich <peter@osticket.com>
8    Copyright (c)  2006-2013 osTicket
9    http://www.osticket.com
10
11    Released under the GNU General Public License WITHOUT ANY WARRANTY.
12    See LICENSE.TXT for details.
13
14    vim: expandtab sw=4 ts=4 sts=4:
15**********************************************************************/
16
17class Misc {
18
19	function randCode($len=8, $chars=false) {
20        $chars = $chars ?: 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890_=';
21
22        // Determine the number of bits we need
23        $char_count = strlen($chars);
24        $bits_per_char = ceil(log($char_count, 2));
25        $bytes = ceil(4 * $len / floor(32 / $bits_per_char));
26        // Pad to 4 byte boundary
27        $bytes += (4 - ($bytes % 4)) % 4;
28
29        // Fetch some random data blocks
30        $data = Crypto::random($bytes);
31
32        $mask = (1 << $bits_per_char) - 1;
33        $loops = (int) (32 / $bits_per_char);
34        $output = '';
35        $ints = unpack('V*', $data);
36        foreach ($ints as $int) {
37            for ($i = $loops; $i > 0; $i--) {
38                $output .= $chars[($int & $mask) % $char_count];
39                $int >>= $bits_per_char;
40            }
41        }
42        return substr($output, 0, $len);
43	}
44
45    function __rand_seed($value=0) {
46        // Form a 32-bit figure for the random seed with the lower 16-bits
47        // the microseconds of the current time, and the upper 16-bits from
48        // received value
49        $seed = ((int) $value % 65535) << 16;
50        $seed += (int) ((double) microtime() * 1000000) % 65535;
51        mt_srand($seed);
52    }
53
54    /* Helper used to generate ticket IDs */
55    function randNumber($len=6) {
56        $number = '';
57        for ($i=0; $i<$len; $i++) {
58            $min = ($i == 0) ? 1 : 0;
59            $number .= mt_rand($min, 9);
60        }
61
62        return (int) $number;
63    }
64
65    /* misc date helpers...this will go away once we move to php 5 */
66    function db2gmtime($var){
67        static $dbtz;
68        global $cfg;
69
70        if (!$var || !$cfg)
71            return;
72
73        if (!isset($dbtz))
74            $dbtz = new DateTimeZone($cfg->getDbTimezone());
75
76        $dbtime = is_int($var) ? $var : strtotime($var);
77        $D = DateTime::createFromFormat('U', $dbtime);
78        if (!$D)
79            // This happens e.g. from negative timestamps
80            return $var;
81
82        return $dbtime - $dbtz->getOffset($D);
83    }
84
85    // Take user's time and return GMT time.
86    function user2gmtime($timestamp=null, $user=null) {
87        global $cfg;
88
89        $tz = new DateTimeZone($cfg->getTimezone($user));
90
91        if ($timestamp && is_int($timestamp)) {
92            if (!($date = DateTime::createFromFormat('U', $timestamp)))
93                return $timestamp;
94
95            return $timestamp - $tz->getOffset($date);
96        }
97
98        $date = Format::parseDateTime($timestamp ?: 'now');
99        if ($tz)
100            $date->setTimezone($tz);
101
102        return $date ? $date->getTimestamp() : $timestamp;
103    }
104
105    //Take user time or gmtime and return db (mysql) time.
106    function dbtime($var=null){
107        static $dbtz;
108        global $cfg;
109
110        if (is_null($var) || !$var) {
111            // Default timezone is set to UTC
112            $time = time();
113        } else {
114            // User time to UTC
115            $time = self::user2gmtime($var);
116        }
117
118        if (!isset($dbtz)) {
119            $dbtz = new DateTimeZone($cfg->getDbTimezone());
120        }
121        // UTC to db time
122        $D = DateTime::createFromFormat('U', $time);
123        return $time + $dbtz->getOffset($D);
124    }
125
126    /*Helper get GM time based on timezone offset*/
127    function gmtime($time=false, $user=false) {
128        global $cfg;
129
130        $tz = new DateTimeZone($user ? $cfg->getDbTimezone($user) : 'UTC');
131
132       if ($time && is_numeric($time))
133          $time = DateTime::createFromFormat('U', $time);
134        elseif (!($time = new DateTime($time ?: 'now'))) {
135            // Old standard
136            return time() - date('Z');
137        }
138
139        return $time->getTimestamp() - $tz->getOffset($time);
140    }
141
142    /* Needed because of PHP 4 support */
143    function micro_time() {
144        list($usec, $sec) = explode(" ", microtime());
145
146        return ((float)$usec + (float)$sec);
147    }
148
149    // Date range for the period in a given time
150    function date_range($period, $time=false, $tz=null) {
151        $time = $time ?: self::gmtime();
152        if (!($dt = Format::parseDateTime($time)))
153            return null;
154        // Force UTC if timezone is not provided
155        $tz = $tz ?: new DateTimeZone('UTC');
156        $dt->setTimezone($tz);
157
158        // Make dt Immutable.
159        $dt = DateTimeImmutable::createFromMutable($dt);
160	 switch ($period) {
161            case 'td':
162            case 'today':
163                $start = $end = $dt->modify('today');
164                break;
165            case 'yd':
166            case 'yesterday':
167                $start = $end = $dt->modify('yesterday');
168                break;
169            case 'tw':
170            case 'this-week':
171                $N = $dt->format('N');
172                $start = $dt->modify($N == 1 ? 'today' : 'last monday');
173                $end = $start->modify('next sunday');
174                break;
175            case 'tm':
176            case 'this-month';
177                $start = $dt->modify('first day of this month');
178                $end = $dt->modify('last day of this month');
179                break;
180            case 'tq':
181            case 'this-quarter':
182                $offset = ($dt->format('m') - 1) % 3;
183                $start = $dt->modify(" - $offset month")
184                    ->modify('first day of this month');
185                $end = $start->modify('+ 3 month')->modify('- 1 day');
186                break;
187            case 'ty':
188            case 'this-year':
189                $start = $dt->modify('january')->modify('first day of this month');
190                $end = $dt->modify('december')->modify('last day of this month');
191                break;
192            case 'lw':
193            case 'last-week':
194                //TODO: address edge cases
195                $start = $dt->modify('- 1 week')->modify('last monday');
196                $end = $start->modify('next sunday');
197                break;
198            case 'lm':
199            case 'last-month';
200                $start = $dt->modify('- 1 month')->modify('first day of this month');
201                $end = $start->modify('last day of this month');
202                break;
203            case 'lq':
204            case 'last-quarter':
205                $offset = (($dt->format('m') - 1) % 3)+3;
206                $start = $dt->modify(" - $offset month")
207                    ->modify('first day of this month');
208                $end = $start->modify('+ 3 month')->modify('- 1 day');
209                break;
210            case 'ly':
211            case 'last-year':
212                $start = $dt->modify('- 1 year')
213                    ->modify('january')
214                    ->modify('first day of this month');
215                $end = $start->modify('december')->modify('last day of this month');
216                break;
217            default:
218                return null;
219        }
220
221        if ($start)
222            $start = $start->setTime(00, 00, 00);
223        if ($end)
224            $end = $end->setTime(23, 59, 59);
225
226        return (object) array('start' => $start, 'end' => $end);
227    }
228
229    //Current page
230    function currentURL() {
231
232        $str = 'http';
233        if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') {
234            $str .='s';
235        }
236        $str .= '://';
237        if (!isset($_SERVER['REQUEST_URI'])) { //IIS???
238            $_SERVER['REQUEST_URI'] = substr($_SERVER['PHP_SELF'],1 );
239            if (isset($_SERVER['QUERY_STRING'])) {
240                $_SERVER['REQUEST_URI'].='?'.$_SERVER['QUERY_STRING'];
241            }
242        }
243        if ($_SERVER['SERVER_PORT']!=80) {
244            $str .= $_SERVER['SERVER_NAME'].':'.$_SERVER['SERVER_PORT'].$_SERVER['REQUEST_URI'];
245        } else {
246            $str .= $_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
247        }
248
249        return $str;
250    }
251
252    function realpath($path) {
253        $rp = realpath($path);
254        return $rp ? $rp : $path;
255    }
256
257}
258?>
259