This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point'); |
||
3 | /********************************************************************************* |
||
4 | * SugarCRM Community Edition is a customer relationship management program developed by |
||
5 | * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc. |
||
6 | |||
7 | * SuiteCRM is an extension to SugarCRM Community Edition developed by Salesagility Ltd. |
||
8 | * Copyright (C) 2011 - 2014 Salesagility Ltd. |
||
9 | * |
||
10 | * This program is free software; you can redistribute it and/or modify it under |
||
11 | * the terms of the GNU Affero General Public License version 3 as published by the |
||
12 | * Free Software Foundation with the addition of the following permission added |
||
13 | * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK |
||
14 | * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY |
||
15 | * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. |
||
16 | * |
||
17 | * This program is distributed in the hope that it will be useful, but WITHOUT |
||
18 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
||
19 | * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more |
||
20 | * details. |
||
21 | * |
||
22 | * You should have received a copy of the GNU Affero General Public License along with |
||
23 | * this program; if not, see http://www.gnu.org/licenses or write to the Free |
||
24 | * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
||
25 | * 02110-1301 USA. |
||
26 | * |
||
27 | * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, |
||
28 | * SW2-130, Cupertino, CA 95014, USA. or at email address [email protected]. |
||
29 | * |
||
30 | * The interactive user interfaces in modified source and object code versions |
||
31 | * of this program must display Appropriate Legal Notices, as required under |
||
32 | * Section 5 of the GNU Affero General Public License version 3. |
||
33 | * |
||
34 | * In accordance with Section 7(b) of the GNU Affero General Public License version 3, |
||
35 | * these Appropriate Legal Notices must retain the display of the "Powered by |
||
36 | * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not |
||
37 | * reasonably feasible for technical reasons, the Appropriate Legal Notices must |
||
38 | * display the words "Powered by SugarCRM" and "Supercharged by SuiteCRM". |
||
39 | ********************************************************************************/ |
||
40 | |||
41 | require_once 'include/SugarDateTime.php'; |
||
42 | |||
43 | /** |
||
44 | * New Time & Date handling class |
||
45 | * @api |
||
46 | * Migration notes: |
||
47 | * - to_db_time() requires either full datetime or time, won't work with just date |
||
48 | * The reason is that it's not possible to know if short string has only date or only time, |
||
49 | * and it makes more sense to assume time for the time conversion function. |
||
50 | */ |
||
51 | class TimeDate |
||
52 | { |
||
53 | const DB_DATE_FORMAT = 'Y-m-d'; |
||
54 | const DB_TIME_FORMAT = 'H:i:s'; |
||
55 | // little optimization |
||
56 | const DB_DATETIME_FORMAT = 'Y-m-d H:i:s'; |
||
57 | const RFC2616_FORMAT = 'D, d M Y H:i:s \G\M\T'; |
||
58 | |||
59 | const SECONDS_IN_A_DAY = 86400; |
||
60 | |||
61 | // Standard DB date/time formats |
||
62 | // they are constant, vars are for compatibility |
||
63 | public $dbDayFormat = self::DB_DATE_FORMAT; |
||
64 | public $dbTimeFormat = self::DB_TIME_FORMAT; |
||
65 | |||
66 | /** |
||
67 | * Regexp for matching format elements |
||
68 | * @var array |
||
69 | */ |
||
70 | protected static $format_to_regexp = array( |
||
71 | 'a' => '[ ]*[ap]m', |
||
72 | 'A' => '[ ]*[AP]M', |
||
73 | 'd' => '[0-9]{1,2}', |
||
74 | 'j' => '[0-9]{1,2}', |
||
75 | 'h' => '[0-9]{1,2}', |
||
76 | 'H' => '[0-9]{1,2}', |
||
77 | 'g' => '[0-9]{1,2}', |
||
78 | 'G' => '[0-9]{1,2}', |
||
79 | 'i' => '[0-9]{1,2}', |
||
80 | 'm' => '[0-9]{1,2}', |
||
81 | 'n' => '[0-9]{1,2}', |
||
82 | 'Y' => '[0-9]{4}', |
||
83 | 's' => '[0-9]{1,2}', |
||
84 | 'F' => '\w+', |
||
85 | "M" => '[\w]{1,3}', |
||
86 | ); |
||
87 | |||
88 | /** |
||
89 | * Relation between date() and strftime() formats |
||
90 | * @var array |
||
91 | */ |
||
92 | public static $format_to_str = array( |
||
93 | // date |
||
94 | 'Y' => '%Y', |
||
95 | |||
96 | 'm' => '%m', |
||
97 | 'M' => '%b', |
||
98 | 'F' => '%B', |
||
99 | 'n' => '%m', |
||
100 | |||
101 | 'd' => '%d', |
||
102 | //'j' => '%e', |
||
103 | // time |
||
104 | 'a' => '%P', |
||
105 | 'A' => '%p', |
||
106 | |||
107 | 'h' => '%I', |
||
108 | 'H' => '%H', |
||
109 | //'g' => '%l', |
||
110 | //'G' => '%H', |
||
111 | |||
112 | 'i' => '%M', |
||
113 | 's' => '%S', |
||
114 | ); |
||
115 | |||
116 | /** |
||
117 | * GMT timezone object |
||
118 | * |
||
119 | * @var DateTimeZone |
||
120 | */ |
||
121 | protected static $gmtTimezone; |
||
122 | |||
123 | /** |
||
124 | * Current time |
||
125 | * @var SugarDateTime |
||
126 | */ |
||
127 | protected $now; |
||
128 | |||
129 | /** |
||
130 | * The current user |
||
131 | * |
||
132 | * @var User |
||
133 | */ |
||
134 | protected $user; |
||
135 | |||
136 | /** |
||
137 | * Current user's ID |
||
138 | * |
||
139 | * @var string |
||
140 | */ |
||
141 | protected $current_user_id; |
||
142 | /** |
||
143 | * Current user's TZ |
||
144 | * @var DateTimeZone |
||
145 | */ |
||
146 | protected $current_user_tz; |
||
147 | |||
148 | /** |
||
149 | * Separator for current user time format |
||
150 | * |
||
151 | * @var string |
||
152 | */ |
||
153 | protected $time_separator; |
||
154 | |||
155 | /** |
||
156 | * Always consider user TZ to be GMT and date format DB format - for SOAP etc. |
||
157 | * |
||
158 | * @var bool |
||
159 | */ |
||
160 | protected $always_db = false; |
||
161 | |||
162 | /** |
||
163 | * Global instance of TimeDate |
||
164 | * @var TimeDate |
||
165 | */ |
||
166 | protected static $timedate; |
||
167 | |||
168 | /** |
||
169 | * Allow returning cached now() value |
||
170 | * If false, new system time is checked each time now() is required |
||
171 | * If true, same value is returned for whole request. |
||
172 | * Also, current user's timezone is cached. |
||
173 | * @var bool |
||
174 | */ |
||
175 | public $allow_cache = true; |
||
176 | |||
177 | /** |
||
178 | * Create TimeDate handler |
||
179 | * @param User $user User to work with, default if current user |
||
180 | */ |
||
181 | 2 | public function __construct(User $user = null) |
|
182 | { |
||
183 | 2 | if (self::$gmtTimezone == null) { |
|
184 | self::$gmtTimezone = new DateTimeZone("UTC"); |
||
185 | } |
||
186 | 2 | $this->now = new SugarDateTime(); |
|
187 | 2 | $this->tzGMT($this->now); |
|
188 | 2 | $this->user = $user; |
|
189 | 2 | } |
|
190 | |||
191 | /** |
||
192 | * Set flag specifying we should always use DB format |
||
193 | * @param bool $flag |
||
194 | * @return TimeDate |
||
195 | */ |
||
196 | public function setAlwaysDb($flag = true) |
||
197 | { |
||
198 | $this->always_db = $flag; |
||
199 | $this->clearCache(); |
||
200 | return $this; |
||
201 | } |
||
202 | |||
203 | /** |
||
204 | * Get "always use DB format" flag |
||
205 | * @return bool |
||
206 | */ |
||
207 | 167 | public function isAlwaysDb() |
|
208 | { |
||
209 | 167 | return !empty($GLOBALS['disable_date_format']) || $this->always_db; |
|
210 | } |
||
211 | |||
212 | /** |
||
213 | * Get TimeDate instance |
||
214 | * @return TimeDate |
||
215 | */ |
||
216 | 30 | public static function getInstance() |
|
217 | { |
||
218 | 30 | if(empty(self::$timedate)) { |
|
219 | if(ini_get('date.timezone') == '') { |
||
220 | // Remove warning about default timezone |
||
221 | date_default_timezone_set(@date('e')); |
||
222 | try { |
||
223 | $tz = self::guessTimezone(); |
||
224 | } catch(Exception $e) { |
||
225 | $tz = "UTC"; // guess failed, switch to UTC |
||
226 | } |
||
227 | if(isset($GLOBALS['log'])) { |
||
228 | $GLOBALS['log']->fatal("Configuration variable date.timezone is not set, guessed timezone $tz. Please set date.timezone=\"$tz\" in php.ini!"); |
||
229 | } |
||
230 | date_default_timezone_set($tz); |
||
231 | } |
||
232 | self::$timedate = new self; |
||
233 | } |
||
234 | 30 | return self::$timedate; |
|
235 | } |
||
236 | |||
237 | /** |
||
238 | * Set current user for this object |
||
239 | * |
||
240 | * @param User $user User object, default is current user |
||
241 | * @return TimeDate |
||
242 | */ |
||
243 | public function setUser(User $user = null) |
||
244 | { |
||
245 | $this->user = $user; |
||
246 | $this->clearCache(); |
||
247 | return $this; |
||
248 | } |
||
249 | |||
250 | /** |
||
251 | * Figure out what the required user is |
||
252 | * |
||
253 | * The order is: supplied parameter, TimeDate's user, global current user |
||
254 | * |
||
255 | * @param User $user User object, default is current user |
||
256 | * @internal |
||
257 | * @return User |
||
258 | */ |
||
259 | 167 | protected function _getUser(User $user = null) |
|
260 | { |
||
261 | 167 | if (empty($user)) { |
|
262 | 163 | $user = $this->user; |
|
263 | } |
||
264 | 167 | if (empty($user)) { |
|
265 | 163 | $user = $GLOBALS['current_user']; |
|
266 | } |
||
267 | 167 | return $user; |
|
268 | } |
||
269 | |||
270 | /** |
||
271 | * Get timezone for the specified user |
||
272 | * |
||
273 | * @param User $user User object, default is current user |
||
274 | * @return DateTimeZone |
||
275 | */ |
||
276 | 159 | protected function _getUserTZ(User $user = null) |
|
277 | { |
||
278 | 159 | $user = $this->_getUser($user); |
|
279 | 159 | if (empty($user) || $this->isAlwaysDb()) { |
|
280 | return self::$gmtTimezone; |
||
281 | } |
||
282 | |||
283 | 159 | if ($this->allow_cache && $user->id == $this->current_user_id && ! empty($this->current_user_tz)) { |
|
284 | // current user is cached |
||
285 | return $this->current_user_tz; |
||
286 | } |
||
287 | |||
288 | 159 | $usertimezone = $user->getPreference('timezone'); |
|
289 | 159 | if(empty($usertimezone)) { |
|
290 | 159 | return self::$gmtTimezone; |
|
291 | } |
||
292 | try { |
||
293 | $tz = new DateTimeZone($usertimezone); |
||
294 | } catch (Exception $e) { |
||
295 | $GLOBALS['log']->fatal('Unknown timezone: ' . $usertimezone); |
||
296 | return self::$gmtTimezone; |
||
297 | } |
||
298 | |||
299 | if (empty($this->current_user_id)) { |
||
300 | $this->current_user_id = $user->id; |
||
301 | $this->current_user_tz = $tz; |
||
302 | } |
||
303 | |||
304 | return $tz; |
||
305 | } |
||
306 | |||
307 | /** |
||
308 | * Clears all cached data regarding current user |
||
309 | */ |
||
310 | public function clearCache() |
||
311 | { |
||
312 | $this->current_user_id = null; |
||
313 | $this->current_user_tz = null; |
||
314 | $this->time_separator = null; |
||
315 | $this->now = new SugarDateTime(); |
||
316 | } |
||
317 | |||
318 | /** |
||
319 | * Get user date format. |
||
320 | * @todo add caching |
||
321 | * |
||
322 | * @param User $user user object, current user if not specified |
||
323 | * @return string |
||
324 | */ |
||
325 | 57 | public function get_date_format(User $user = null) |
|
326 | { |
||
327 | 57 | $user = $this->_getUser($user); |
|
328 | |||
329 | 57 | if (empty($user) || $this->isAlwaysDb()) { |
|
330 | return self::DB_DATE_FORMAT; |
||
331 | } |
||
332 | |||
333 | 57 | $datef = $user->getPreference('datef'); |
|
334 | 57 | if(empty($datef) && isset($GLOBALS['current_user']) && $GLOBALS['current_user'] !== $user) { |
|
335 | // if we got another user and it has no date format, try current user |
||
336 | $datef = $GLOBALS['current_user']->getPreference('datef'); |
||
337 | } |
||
338 | 57 | if (empty($datef)) { |
|
339 | $datef = $GLOBALS['sugar_config']['default_date_format']; |
||
340 | } |
||
341 | 57 | if (empty($datef)) { |
|
342 | $datef = ''; |
||
343 | } |
||
344 | |||
345 | 57 | return $datef; |
|
346 | } |
||
347 | |||
348 | /** |
||
349 | * Get user time format. |
||
350 | * @todo add caching |
||
351 | * |
||
352 | * @param User $user user object, current user if not specified |
||
353 | * @return string |
||
354 | */ |
||
355 | 25 | public function get_time_format(/*User*/ $user = null) |
|
356 | { |
||
357 | 25 | if(is_bool($user) || func_num_args() > 1) { |
|
358 | // BC dance - old signature was boolean, User |
||
359 | $GLOBALS['log']->fatal('TimeDate::get_time_format(): Deprecated API used, please update you code - get_time_format() now has one argument of type User'); |
||
360 | if(func_num_args() > 1) { |
||
361 | $user = func_get_arg(1); |
||
362 | } else { |
||
363 | $user = null; |
||
364 | } |
||
365 | } |
||
366 | 25 | $user = $this->_getUser($user); |
|
367 | |||
368 | 25 | if (empty($user) || $this->isAlwaysDb()) { |
|
369 | return self::DB_TIME_FORMAT; |
||
370 | } |
||
371 | |||
372 | 25 | $timef = $user->getPreference('timef'); |
|
373 | 25 | if(empty($timef) && isset($GLOBALS['current_user']) && $GLOBALS['current_user'] !== $user) { |
|
374 | // if we got another user and it has no time format, try current user |
||
375 | $timef = $GLOBALS['current_user']->getPreference('$timef'); |
||
376 | } |
||
377 | 25 | if (empty($timef)) { |
|
378 | $timef = $GLOBALS['sugar_config']['default_time_format']; |
||
379 | } |
||
380 | 25 | if (empty($timef)) { |
|
381 | $timef = ''; |
||
382 | } |
||
383 | 25 | return $timef; |
|
384 | } |
||
385 | |||
386 | /** |
||
387 | * Get user datetime format. |
||
388 | * |
||
389 | * @param User $user user object, current user if not specified |
||
390 | * @return string |
||
391 | */ |
||
392 | 129 | public function get_date_time_format($user = null) |
|
393 | { |
||
394 | // BC fix - had (bool, user) signature before |
||
395 | 129 | if(!($user instanceof User)) { |
|
396 | 124 | if(func_num_args() > 1) { |
|
397 | $user = func_get_arg(1); |
||
398 | if(!($user instanceof User)) { |
||
399 | $user = null; |
||
400 | } |
||
401 | } else { |
||
402 | 124 | $user = null; |
|
403 | } |
||
404 | } |
||
405 | |||
406 | 129 | $cacheKey= $this->get_date_time_format_cache_key($user); |
|
407 | 129 | $cachedValue = sugar_cache_retrieve($cacheKey); |
|
408 | |||
409 | 129 | if(!empty($cachedValue) ) |
|
410 | { |
||
411 | 129 | return $cachedValue; |
|
412 | } |
||
413 | else |
||
414 | { |
||
415 | 2 | $value = $this->merge_date_time($this->get_date_format($user), $this->get_time_format($user)); |
|
416 | 2 | sugar_cache_put($cacheKey,$value,0); |
|
417 | 2 | return $value; |
|
418 | } |
||
419 | } |
||
420 | |||
421 | /** |
||
422 | * Retrieve the cache key used for user date/time formats |
||
423 | * |
||
424 | * @param $user |
||
425 | * @return string |
||
426 | */ |
||
427 | 129 | public function get_date_time_format_cache_key($user) |
|
428 | { |
||
429 | 129 | $cacheKey = get_class($this) ."dateTimeFormat"; |
|
430 | 129 | $user = $this->_getUser($user); |
|
431 | |||
432 | 129 | if($user instanceof User) |
|
433 | { |
||
434 | 129 | $cacheKey .= "_{$user->id}"; |
|
435 | } |
||
436 | |||
437 | 129 | if( $this->isAlwaysDb() ) |
|
438 | $cacheKey .= '_asdb'; |
||
439 | |||
440 | 129 | return $cacheKey; |
|
441 | } |
||
442 | |||
443 | /** |
||
444 | * Get user's first day of week setting. |
||
445 | * |
||
446 | * @param User $user user object, current user if not specified |
||
447 | * @return int Day, 0 = Sunday, 1 = Monday, etc... |
||
448 | */ |
||
449 | public function get_first_day_of_week(User $user = null) |
||
450 | { |
||
451 | $user = $this->_getUser($user); |
||
452 | $fdow = 0; |
||
453 | |||
454 | if (!empty($user)) |
||
455 | { |
||
456 | $fdow = $user->getPreference('fdow'); |
||
457 | if (empty($fdow)) |
||
458 | $fdow = 0; |
||
459 | } |
||
460 | |||
461 | return $fdow; |
||
462 | } |
||
463 | |||
464 | |||
465 | /** |
||
466 | * Make one datetime string from date string and time string |
||
467 | * |
||
468 | * @param string $date |
||
469 | * @param string $time |
||
470 | * @return string New datetime string |
||
471 | */ |
||
472 | 9 | function merge_date_time($date, $time) |
|
473 | { |
||
474 | 9 | return $date . ' ' . $time; |
|
475 | } |
||
476 | |||
477 | /** |
||
478 | * Split datetime string into date & time |
||
479 | * |
||
480 | * @param string $datetime |
||
481 | * @return array |
||
482 | */ |
||
483 | 4 | function split_date_time($datetime) |
|
484 | { |
||
485 | 4 | return explode(' ', $datetime, 2); |
|
486 | } |
||
487 | |||
488 | |||
489 | /** |
||
490 | * Get user date format in Javascript form |
||
491 | * @return string |
||
492 | */ |
||
493 | 13 | function get_cal_date_format() |
|
494 | { |
||
495 | 13 | return str_replace(array_keys(self::$format_to_str), array_values(self::$format_to_str), $this->get_date_format()); |
|
496 | } |
||
497 | |||
498 | /** |
||
499 | * Get user time format in Javascript form |
||
500 | * @return string |
||
501 | */ |
||
502 | function get_cal_time_format() |
||
503 | { |
||
504 | return str_replace(array_keys(self::$format_to_str), array_values(self::$format_to_str), $this->get_time_format()); |
||
505 | } |
||
506 | |||
507 | /** |
||
508 | * Get user date&time format in Javascript form |
||
509 | * @return string |
||
510 | */ |
||
511 | function get_cal_date_time_format() |
||
512 | { |
||
513 | return str_replace(array_keys(self::$format_to_str), array_values(self::$format_to_str), $this->get_date_time_format()); |
||
514 | } |
||
515 | |||
516 | /** |
||
517 | * Verify if the date string conforms to a format |
||
518 | * |
||
519 | * @param string $date |
||
520 | * @param string $format Format to check |
||
521 | * |
||
522 | * @internal |
||
523 | * @return bool Is the date ok? |
||
524 | */ |
||
525 | public function check_matching_format($date, $format) |
||
526 | { |
||
527 | try { |
||
528 | $dt = SugarDateTime::createFromFormat($format, $date); |
||
529 | if (!is_object($dt)) { |
||
530 | return false; |
||
531 | } |
||
532 | } catch (Exception $e) { |
||
533 | return false; |
||
534 | } |
||
535 | return true; |
||
536 | } |
||
537 | |||
538 | /** |
||
539 | * Format DateTime object as DB datetime |
||
540 | * |
||
541 | * @param DateTime $date |
||
542 | * @return string |
||
543 | */ |
||
544 | 86 | public function asDb(DateTime $date) |
|
545 | { |
||
546 | 86 | $date->setTimezone(self::$gmtTimezone); |
|
547 | 86 | return $date->format($this->get_db_date_time_format()); |
|
548 | } |
||
549 | |||
550 | /** |
||
551 | * Format date as DB-formatted field type |
||
552 | * @param DateTime $date |
||
553 | * @param string $type Field type - date, time, datetime[combo] |
||
554 | * @return string Formatted date |
||
555 | */ |
||
556 | public function asDbType(DateTime $date, $type) |
||
557 | { |
||
558 | switch($type) { |
||
559 | case "date": |
||
560 | return $this->asDbDate($date); |
||
561 | break; |
||
0 ignored issues
–
show
|
|||
562 | case 'time': |
||
563 | return $this->asDbtime($date); |
||
564 | break; |
||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. ![]() |
|||
565 | case 'datetime': |
||
566 | case 'datetimecombo': |
||
567 | default: |
||
568 | return $this->asDb($date); |
||
569 | } |
||
570 | } |
||
571 | |||
572 | /** |
||
573 | * Format DateTime object as user datetime |
||
574 | * |
||
575 | * @param DateTime $date |
||
576 | * @param User $user |
||
577 | * @return string |
||
578 | */ |
||
579 | 38 | public function asUser(DateTime $date, User $user = null) |
|
580 | { |
||
581 | 38 | $this->tzUser($date, $user); |
|
582 | 38 | return $date->format($this->get_date_time_format($user)); |
|
583 | } |
||
584 | |||
585 | /** |
||
586 | * Format date as user-formatted field type |
||
587 | * @param DateTime $date |
||
588 | * @param string $type Field type - date, time, datetime[combo] |
||
589 | * @param User $user |
||
590 | * @return string |
||
591 | */ |
||
592 | public function asUserType(DateTime $date, $type, User $user = null) |
||
593 | { |
||
594 | switch($type) { |
||
595 | case "date": |
||
596 | return $this->asUserDate($date, true, $user); |
||
597 | break; |
||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. ![]() |
|||
598 | case 'time': |
||
599 | return $this->asUserTime($date, true, $user); |
||
0 ignored issues
–
show
The call to
TimeDate::asUserTime() has too many arguments starting with $user .
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue. If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. In this case you can add the ![]() |
|||
600 | break; |
||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. ![]() |
|||
601 | case 'datetime': |
||
602 | case 'datetimecombo': |
||
603 | default: |
||
604 | return $this->asUser($date, $user); |
||
605 | } |
||
606 | } |
||
607 | |||
608 | /** |
||
609 | * Produce timestamp offset by user's timezone |
||
610 | * |
||
611 | * So if somebody converts it to format assuming GMT, it would actually display user's time. |
||
612 | * This is used by Javascript. |
||
613 | * |
||
614 | * @param DateTime $date |
||
615 | * @param User $user |
||
616 | * @return int |
||
617 | */ |
||
618 | 3 | public function asUserTs(DateTime $date, User $user = null) |
|
619 | { |
||
620 | 3 | return $date->format('U')+$this->_getUserTZ($user)->getOffset($date); |
|
621 | } |
||
622 | |||
623 | /** |
||
624 | * Format DateTime object as DB date |
||
625 | * Note: by default does not convert TZ! |
||
626 | * @param DateTime $date |
||
627 | * @param boolean $tz Perform TZ conversion? |
||
628 | * @return string |
||
629 | */ |
||
630 | 4 | public function asDbDate(DateTime $date, $tz = false) |
|
631 | { |
||
632 | 4 | if($tz) $date->setTimezone(self::$gmtTimezone); |
|
633 | 4 | return $date->format($this->get_db_date_format()); |
|
634 | } |
||
635 | |||
636 | /** |
||
637 | * Format DateTime object as user date |
||
638 | * Note: by default does not convert TZ! |
||
639 | * @param DateTime $date |
||
640 | * @param boolean $tz Perform TZ conversion? |
||
641 | * @param User $user |
||
642 | * @return string |
||
643 | */ |
||
644 | 37 | public function asUserDate(DateTime $date, $tz = false, User $user = null) |
|
645 | { |
||
646 | 37 | if($tz) $this->tzUser($date, $user); |
|
647 | 37 | return $date->format($this->get_date_format($user)); |
|
648 | } |
||
649 | |||
650 | /** |
||
651 | * Format DateTime object as DB time |
||
652 | * |
||
653 | * @param DateTime $date |
||
654 | * @return string |
||
655 | */ |
||
656 | 2 | public function asDbTime(DateTime $date) |
|
657 | { |
||
658 | 2 | $date->setTimezone(self::$gmtTimezone); |
|
659 | 2 | return $date->format($this->get_db_time_format()); |
|
660 | } |
||
661 | |||
662 | /** |
||
663 | * Format DateTime object as user time |
||
664 | * |
||
665 | * @param DateTime $date |
||
666 | * @param User $user |
||
667 | * @return string |
||
668 | */ |
||
669 | 1 | public function asUserTime(DateTime $date, User $user = null) |
|
670 | { |
||
671 | 1 | $this->tzUser($date, $user); |
|
672 | 1 | return $date->format($this->get_time_format($user)); |
|
673 | } |
||
674 | |||
675 | /** |
||
676 | * Get DateTime from DB datetime string |
||
677 | * |
||
678 | * @param string $date |
||
679 | * @return SugarDateTime |
||
680 | */ |
||
681 | 12 | public function fromDb($date) |
|
682 | { |
||
683 | try { |
||
684 | 12 | return SugarDateTime::createFromFormat(self::DB_DATETIME_FORMAT, $date, self::$gmtTimezone); |
|
685 | } catch (Exception $e) { |
||
686 | $GLOBALS['log']->error("fromDb: Conversion of $date from DB format failed: {$e->getMessage()}"); |
||
687 | return null; |
||
688 | } |
||
689 | } |
||
690 | |||
691 | /** |
||
692 | * Create a date from a certain type of field in DB format |
||
693 | * The types are: date, time, datatime[combo] |
||
694 | * @param string $date the datetime string |
||
695 | * @param string $type string type |
||
696 | * @return SugarDateTime |
||
697 | */ |
||
698 | public function fromDbType($date, $type) |
||
699 | { |
||
700 | switch($type) { |
||
701 | case "date": |
||
702 | return $this->fromDbDate($date); |
||
703 | break; |
||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. ![]() |
|||
704 | case 'time': |
||
705 | return $this->fromDbFormat($date, self::DB_TIME_FORMAT); |
||
706 | break; |
||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. ![]() |
|||
707 | case 'datetime': |
||
708 | case 'datetimecombo': |
||
709 | default: |
||
710 | return $this->fromDb($date); |
||
711 | } |
||
712 | } |
||
713 | |||
714 | /** |
||
715 | * Get DateTime from DB date string |
||
716 | * |
||
717 | * @param string $date |
||
718 | * @return SugarDateTime |
||
719 | */ |
||
720 | public function fromDbDate($date) |
||
721 | { |
||
722 | try { |
||
723 | return SugarDateTime::createFromFormat(self::DB_DATE_FORMAT, $date, self::$gmtTimezone); |
||
724 | } catch (Exception $e) { |
||
725 | $GLOBALS['log']->error("fromDbDate: Conversion of $date from DB format failed: {$e->getMessage()}"); |
||
726 | return null; |
||
727 | } |
||
728 | } |
||
729 | |||
730 | /** |
||
731 | * Get DateTime from DB datetime string using non-standard format |
||
732 | * |
||
733 | * Non-standard format usually would be only date, only time, etc. |
||
734 | * |
||
735 | * @param string $date |
||
736 | * @param string $format format to accept |
||
737 | * @return SugarDateTime |
||
738 | */ |
||
739 | public function fromDbFormat($date, $format) |
||
740 | { |
||
741 | try { |
||
742 | return SugarDateTime::createFromFormat($format, $date, self::$gmtTimezone); |
||
743 | } catch (Exception $e) { |
||
744 | $GLOBALS['log']->error("fromDbFormat: Conversion of $date from DB format $format failed: {$e->getMessage()}"); |
||
745 | return null; |
||
746 | } |
||
747 | } |
||
748 | |||
749 | /** |
||
750 | * Get DateTime from user datetime string |
||
751 | * |
||
752 | * @param string $date |
||
753 | * @param User $user |
||
754 | * @return SugarDateTime |
||
755 | */ |
||
756 | 7 | public function fromUser($date, User $user = null) |
|
757 | { |
||
758 | 7 | $res = null; |
|
759 | try { |
||
760 | 7 | $res = SugarDateTime::createFromFormat($this->get_date_time_format($user), $date, $this->_getUserTZ($user)); |
|
761 | } catch (Exception $e) { |
||
762 | $GLOBALS['log']->error("fromUser: Conversion of $date exception: {$e->getMessage()}"); |
||
763 | } |
||
764 | 7 | if(!($res instanceof DateTime)) { |
|
765 | 4 | $uf = $this->get_date_time_format($user); |
|
766 | 4 | $GLOBALS['log']->error("fromUser: Conversion of $date from user format $uf failed"); |
|
767 | 4 | return null; |
|
768 | } |
||
769 | 3 | return $res; |
|
770 | } |
||
771 | |||
772 | /** |
||
773 | * Create a date from a certain type of field in user format |
||
774 | * The types are: date, time, datatime[combo] |
||
775 | * @param string $date the datetime string |
||
776 | * @param string $type string type |
||
777 | * @param User $user |
||
778 | * @return SugarDateTime |
||
779 | */ |
||
780 | public function fromUserType($date, $type, $user = null) |
||
781 | { |
||
782 | switch($type) { |
||
783 | case "date": |
||
784 | return $this->fromUserDate($date, $user); |
||
785 | break; |
||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. ![]() |
|||
786 | case 'time': |
||
787 | return $this->fromUserTime($date, $user); |
||
788 | break; |
||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. ![]() |
|||
789 | case 'datetime': |
||
790 | case 'datetimecombo': |
||
791 | default: |
||
792 | return $this->fromUser($date, $user); |
||
793 | } |
||
794 | } |
||
795 | |||
796 | /** |
||
797 | * Get DateTime from user time string |
||
798 | * |
||
799 | * @param string $date |
||
800 | * @param User $user |
||
801 | * @return SugarDateTime |
||
802 | */ |
||
803 | public function fromUserTime($date, User $user = null) |
||
804 | { |
||
805 | try { |
||
806 | return SugarDateTime::createFromFormat($this->get_time_format($user), $date, $this->_getUserTZ($user)); |
||
807 | } catch (Exception $e) { |
||
808 | $uf = $this->get_time_format($user); |
||
809 | $GLOBALS['log']->error("fromUserTime: Conversion of $date from user format $uf failed: {$e->getMessage()}"); |
||
810 | return null; |
||
811 | } |
||
812 | } |
||
813 | |||
814 | /** |
||
815 | * Get DateTime from user date string |
||
816 | * Usually for calendar-related functions like holidays |
||
817 | * Note: by default does not convert tz! |
||
818 | * @param string $date |
||
819 | * @param bool $convert_tz perform TZ converson? |
||
820 | * @param User $user |
||
821 | * @return SugarDateTime |
||
822 | */ |
||
823 | 13 | public function fromUserDate($date, $convert_tz = false, User $user = null) |
|
824 | { |
||
825 | try { |
||
826 | 13 | return SugarDateTime::createFromFormat($this->get_date_format($user), $date, $convert_tz?$this->_getUserTZ($user):self::$gmtTimezone); |
|
827 | } catch (Exception $e) { |
||
828 | $uf = $this->get_date_format($user); |
||
829 | $GLOBALS['log']->error("fromUserDate: Conversion of $date from user format $uf failed: {$e->getMessage()}"); |
||
830 | return null; |
||
831 | } |
||
832 | } |
||
833 | |||
834 | /** |
||
835 | * Create a date object from any string |
||
836 | * |
||
837 | * Same formats accepted as for DateTime ctor |
||
838 | * |
||
839 | * @param string $date |
||
840 | * @param User $user |
||
841 | * @return SugarDateTime |
||
842 | */ |
||
843 | 18 | public function fromString($date, User $user = null) |
|
844 | { |
||
845 | try { |
||
846 | 18 | return new SugarDateTime($date, $this->_getUserTZ($user)); |
|
847 | } catch (Exception $e) { |
||
848 | $GLOBALS['log']->error("fromString: Conversion of $date from string failed: {$e->getMessage()}"); |
||
849 | return null; |
||
850 | } |
||
851 | } |
||
852 | |||
853 | /** |
||
854 | * Create DateTime from timestamp |
||
855 | * |
||
856 | * @param interger|string $ts |
||
857 | * @return SugarDateTime |
||
858 | */ |
||
859 | 2 | public function fromTimestamp($ts) |
|
860 | { |
||
861 | 2 | return new SugarDateTime("@$ts"); |
|
862 | } |
||
863 | |||
864 | /** |
||
865 | * Convert DateTime to GMT timezone |
||
866 | * @param DateTime $date |
||
867 | * @return DateTime |
||
868 | */ |
||
869 | 2 | public function tzGMT(DateTime $date) |
|
870 | { |
||
871 | 2 | return $date->setTimezone(self::$gmtTimezone); |
|
872 | } |
||
873 | |||
874 | /** |
||
875 | * Convert DateTime to user timezone |
||
876 | * @param DateTime $date |
||
877 | * @param User $user |
||
878 | * @return DateTime |
||
879 | */ |
||
880 | 76 | public function tzUser(DateTime $date, User $user = null) |
|
881 | { |
||
882 | 76 | return $date->setTimezone($this->_getUserTZ($user)); |
|
883 | } |
||
884 | |||
885 | /** |
||
886 | * Get string defining midnight in current user's format |
||
887 | * @param string $format Time format to use |
||
888 | * @return string |
||
889 | */ |
||
890 | 4 | protected function _get_midnight($format = null) |
|
891 | { |
||
892 | 4 | $zero = new DateTime("@0", self::$gmtTimezone); |
|
893 | 4 | return $zero->format($format?$format:$this->get_time_format()); |
|
894 | } |
||
895 | |||
896 | /** |
||
897 | * |
||
898 | * Basic conversion function |
||
899 | * |
||
900 | * Converts between two string dates in different formats and timezones |
||
901 | * |
||
902 | * @param string $date |
||
903 | * @param string $fromFormat |
||
904 | * @param DateTimeZone $fromTZ |
||
905 | * @param string $toFormat |
||
906 | * @param DateTimeZone|null $toTZ |
||
907 | * @param bool $expand If string lacks time, expand it to include time |
||
908 | * @return string |
||
909 | */ |
||
910 | 100 | protected function _convert($date, $fromFormat, $fromTZ, $toFormat, $toTZ, $expand = false) |
|
911 | { |
||
912 | 100 | $date = trim($date); |
|
913 | 100 | if (empty($date)) { |
|
914 | 3 | return $date; |
|
915 | } |
||
916 | try { |
||
917 | 98 | if ($expand && strlen($date) <= 10) { |
|
918 | 4 | $date = $this->expandDate($date, $fromFormat); |
|
919 | } |
||
920 | 98 | $phpdate = SugarDateTime::createFromFormat($fromFormat, $date, $fromTZ); |
|
921 | 98 | if ($phpdate == false) { |
|
922 | 1 | $GLOBALS['log']->error("convert: Conversion of $date from $fromFormat to $toFormat failed"); |
|
923 | 1 | return ''; |
|
924 | } |
||
925 | 97 | if ($fromTZ !== $toTZ && $toTZ != null) { |
|
926 | $phpdate->setTimeZone($toTZ); |
||
927 | } |
||
928 | 97 | return $phpdate->format($toFormat); |
|
929 | } catch (Exception $e) { |
||
930 | $GLOBALS['log']->error("Conversion of $date from $fromFormat to $toFormat failed: {$e->getMessage()}"); |
||
931 | return ''; |
||
932 | } |
||
933 | } |
||
934 | |||
935 | /** |
||
936 | * Convert DB datetime to local datetime |
||
937 | * |
||
938 | * TZ conversion is controlled by parameter |
||
939 | * |
||
940 | * @param string $date Original date in DB format |
||
941 | * @param bool $meridiem Ignored for BC |
||
942 | * @param bool $convert_tz Perform TZ conversion? |
||
943 | * @param User $user User owning the conversion formats |
||
944 | * @return string Date in display format |
||
945 | */ |
||
946 | 85 | function to_display_date_time($date, $meridiem = true, $convert_tz = true, $user = null) |
|
947 | { |
||
948 | 85 | return $this->_convert($date, self::DB_DATETIME_FORMAT, self::$gmtTimezone, $this->get_date_time_format($user), |
|
949 | 85 | $convert_tz ? $this->_getUserTZ($user) : self::$gmtTimezone, true); |
|
950 | } |
||
951 | |||
952 | /** |
||
953 | * Converts DB time string to local time string |
||
954 | * |
||
955 | * TZ conversion depends on parameter |
||
956 | * |
||
957 | * @param string $date Time in DB format |
||
958 | * @param bool $meridiem |
||
959 | * @param bool $convert_tz Perform TZ conversion? |
||
960 | * @return string Time in user-defined format |
||
961 | */ |
||
962 | 4 | public function to_display_time($date, $meridiem = true, $convert_tz = true) |
|
963 | { |
||
964 | 4 | if($convert_tz && strpos($date, ' ') === false) { |
|
965 | // we need TZ adjustment but have no date, assume today |
||
966 | $date = $this->expandTime($date, self::DB_DATETIME_FORMAT, self::$gmtTimezone); |
||
967 | } |
||
968 | 4 | return $this->_convert($date, |
|
969 | 4 | $convert_tz ? self::DB_DATETIME_FORMAT : self::DB_TIME_FORMAT, self::$gmtTimezone, |
|
970 | 4 | $this->get_time_format(), $convert_tz ? $this->_getUserTZ() : self::$gmtTimezone); |
|
971 | } |
||
972 | |||
973 | /** |
||
974 | * Splits time in given format into components |
||
975 | * |
||
976 | * Components: h, m, s, a (am/pm) if format requires it |
||
977 | * If format has am/pm, hour is 12-based, otherwise 24-based |
||
978 | * |
||
979 | * @param string $date |
||
980 | * @param string $format |
||
981 | * @return array |
||
982 | */ |
||
983 | public function splitTime($date, $format) |
||
984 | { |
||
985 | if (! ($date instanceof DateTime)) { |
||
986 | $date = SugarDateTime::createFromFormat($format, $date); |
||
987 | } |
||
988 | $ampm = strpbrk($format, 'aA'); |
||
989 | $datearr = array( |
||
990 | "h" => ($ampm == false) ? $date->format("H") : $date->format("h"), |
||
0 ignored issues
–
show
|
|||
991 | 'm' => $date->format("i"), |
||
992 | 's' => $date->format("s") |
||
993 | ); |
||
994 | if ($ampm) { |
||
995 | $datearr['a'] = ($ampm{0} == 'a') ? $date->format("a") : $date->format("A"); |
||
996 | } |
||
997 | return $datearr; |
||
998 | } |
||
999 | |||
1000 | /** |
||
1001 | * Converts DB date string to local date string |
||
1002 | * |
||
1003 | * TZ conversion depens on parameter |
||
1004 | * |
||
1005 | * @param string $date Date in DB format |
||
1006 | * @param bool $convert_tz Perform TZ conversion? |
||
1007 | * @return string Date in user-defined format |
||
1008 | */ |
||
1009 | 2 | public function to_display_date($date, $convert_tz = true) |
|
1010 | { |
||
1011 | 2 | return $this->_convert($date, |
|
1012 | 2 | self::DB_DATETIME_FORMAT, self::$gmtTimezone, |
|
1013 | 2 | $this->get_date_format(), $convert_tz ? $this->_getUserTZ() : self::$gmtTimezone, true); |
|
1014 | } |
||
1015 | |||
1016 | /** |
||
1017 | * Convert date from format to format |
||
1018 | * |
||
1019 | * No TZ conversion is performed! |
||
1020 | * |
||
1021 | * @param string $date |
||
1022 | * @param string $from Source format |
||
1023 | * @param string $to Destination format |
||
1024 | * @return string Converted date |
||
1025 | */ |
||
1026 | function to_display($date, $from, $to) |
||
1027 | { |
||
1028 | return $this->_convert($date, $from, self::$gmtTimezone, $to, self::$gmtTimezone); |
||
1029 | } |
||
1030 | |||
1031 | /** |
||
1032 | * Get DB datetime format |
||
1033 | * @return string |
||
1034 | */ |
||
1035 | 87 | public function get_db_date_time_format() |
|
1036 | { |
||
1037 | 87 | return self::DB_DATETIME_FORMAT; |
|
1038 | } |
||
1039 | |||
1040 | /** |
||
1041 | * Get DB date format |
||
1042 | * @return string |
||
1043 | */ |
||
1044 | 4 | public function get_db_date_format() |
|
1045 | { |
||
1046 | 4 | return self::DB_DATE_FORMAT; |
|
1047 | } |
||
1048 | |||
1049 | /** |
||
1050 | * Get DB time format |
||
1051 | * @return string |
||
1052 | */ |
||
1053 | 2 | public function get_db_time_format() |
|
1054 | { |
||
1055 | 2 | return self::DB_TIME_FORMAT; |
|
1056 | } |
||
1057 | |||
1058 | /** |
||
1059 | * Convert date from local datetime to GMT-based DB datetime |
||
1060 | * |
||
1061 | * Includes TZ conversion. |
||
1062 | * |
||
1063 | * @param string $date |
||
1064 | * @return string Datetime in DB format |
||
1065 | */ |
||
1066 | 11 | public function to_db($date) |
|
1067 | { |
||
1068 | 11 | return $this->_convert($date, |
|
1069 | 11 | $this->get_date_time_format(), $this->_getUserTZ(), |
|
1070 | 11 | $this->get_db_date_time_format(), self::$gmtTimezone, |
|
1071 | 11 | true); |
|
1072 | } |
||
1073 | |||
1074 | /** |
||
1075 | * Convert local datetime to DB date |
||
1076 | * |
||
1077 | * TZ conversion depends on parameter. If false, only format conversion is performed. |
||
1078 | * |
||
1079 | * @param string $date Local date |
||
1080 | * @param bool $convert_tz Should time and TZ be taken into account? |
||
1081 | * @return string Date in DB format |
||
1082 | */ |
||
1083 | 5 | public function to_db_date($date, $convert_tz = true) |
|
1084 | { |
||
1085 | 5 | return $this->_convert($date, |
|
1086 | 5 | $this->get_date_time_format(), $convert_tz ? $this->_getUserTZ() : self::$gmtTimezone, |
|
1087 | 5 | self::DB_DATE_FORMAT, self::$gmtTimezone, true); |
|
1088 | } |
||
1089 | |||
1090 | /** |
||
1091 | * Convert local datetime to DB time |
||
1092 | * |
||
1093 | * TZ conversion depends on parameter. If false, only format conversion is performed. |
||
1094 | * |
||
1095 | * @param string $date Local date |
||
1096 | * @param bool $convert_tz Should time and TZ be taken into account? |
||
1097 | * @return string Time in DB format |
||
1098 | */ |
||
1099 | public function to_db_time($date, $convert_tz = true) |
||
1100 | { |
||
1101 | $format = $this->get_date_time_format(); |
||
1102 | $tz = $convert_tz ? $this->_getUserTZ() : self::$gmtTimezone; |
||
1103 | if($convert_tz && strpos($date, ' ') === false) { |
||
1104 | // we need TZ adjustment but have short string, expand it to full one |
||
1105 | // FIXME: if the string is short, should we assume date or time? |
||
1106 | $date = $this->expandTime($date, $format, $tz); |
||
1107 | } |
||
1108 | return $this->_convert($date, |
||
1109 | $convert_tz ? $format : $this->get_time_format(), |
||
1110 | $tz, |
||
1111 | self::DB_TIME_FORMAT, self::$gmtTimezone); |
||
1112 | } |
||
1113 | |||
1114 | /** |
||
1115 | * Takes a Date & Time value in local format and converts them to DB format |
||
1116 | * No TZ conversion! |
||
1117 | * |
||
1118 | * @param string $date |
||
1119 | * @param string $time |
||
1120 | * @return array Date & time in DB format |
||
1121 | **/ |
||
1122 | public function to_db_date_time($date, $time) |
||
1123 | { |
||
1124 | try { |
||
1125 | $phpdate = SugarDateTime::createFromFormat($this->get_date_time_format(), |
||
1126 | $this->merge_date_time($date, $time), self::$gmtTimezone); |
||
1127 | if ($phpdate == false) { |
||
1128 | return array('', ''); |
||
1129 | } |
||
1130 | return array($this->asDbDate($phpdate), $this->asDbTime($phpdate)); |
||
1131 | } catch (Exception $e) { |
||
1132 | $GLOBALS['log']->error("Conversion of $date,$time failed"); |
||
1133 | return array('', ''); |
||
1134 | } |
||
1135 | } |
||
1136 | |||
1137 | /** |
||
1138 | * Return current time in DB format |
||
1139 | * @return string |
||
1140 | */ |
||
1141 | 86 | public function nowDb() |
|
1142 | { |
||
1143 | 86 | if(!$this->allow_cache) { |
|
1144 | $nowGMT = $this->getNow(); |
||
1145 | } else { |
||
1146 | 86 | $nowGMT = $this->now; |
|
1147 | } |
||
1148 | 86 | return $this->asDb($nowGMT); |
|
1149 | } |
||
1150 | |||
1151 | /** |
||
1152 | * Return current date in DB format |
||
1153 | * @return string |
||
1154 | */ |
||
1155 | 1 | public function nowDbDate() |
|
1156 | { |
||
1157 | 1 | if(!$this->allow_cache) { |
|
1158 | $nowGMT = $this->getNow(); |
||
1159 | } else { |
||
1160 | 1 | $nowGMT = $this->now; |
|
1161 | } |
||
1162 | 1 | return $this->asDbDate($nowGMT, true); |
|
1163 | } |
||
1164 | |||
1165 | /** |
||
1166 | * Get 'now' DateTime object |
||
1167 | * @param bool $userTz return in user timezone? |
||
1168 | * @return SugarDateTime |
||
1169 | */ |
||
1170 | 84 | public function getNow($userTz = false) |
|
1171 | { |
||
1172 | 84 | if(!$this->allow_cache) { |
|
1173 | return new SugarDateTime("now", $userTz?$this->_getUserTz():self::$gmtTimezone); |
||
1174 | } |
||
1175 | // TODO: should we return clone? |
||
1176 | 84 | $now = clone $this->now; |
|
1177 | 84 | if($userTz) { |
|
1178 | 62 | return $this->tzUser($now); |
|
1179 | } |
||
1180 | 29 | return $now; |
|
1181 | } |
||
1182 | |||
1183 | /** |
||
1184 | * Set 'now' time |
||
1185 | * For testability - predictable time value |
||
1186 | * @param DateTime $now |
||
1187 | * @return TimeDate $this |
||
1188 | */ |
||
1189 | public function setNow($now) |
||
1190 | { |
||
1191 | $this->now = $now; |
||
0 ignored issues
–
show
$now is of type object<DateTime> , but the property $now was declared to be of type object<SugarDateTime> . Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly. Either this assignment is in error or an instanceof check should be added for that assignment. class Alien {}
class Dalek extends Alien {}
class Plot
{
/** @var Dalek */
public $villain;
}
$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
$plot->villain = $alien;
}
![]() |
|||
1192 | return $this; |
||
1193 | } |
||
1194 | |||
1195 | /** |
||
1196 | * Return current datetime in local format |
||
1197 | * @return string |
||
1198 | */ |
||
1199 | 7 | public function now() |
|
1200 | { |
||
1201 | 7 | return $this->asUser($this->getNow()); |
|
1202 | } |
||
1203 | |||
1204 | /** |
||
1205 | * Return current date in User format |
||
1206 | * @return string |
||
1207 | */ |
||
1208 | 1 | public function nowDate() |
|
1209 | { |
||
1210 | 1 | return $this->asUserDate($this->getNow()); |
|
1211 | } |
||
1212 | |||
1213 | /** |
||
1214 | * Get user format's time separator |
||
1215 | * @return string |
||
1216 | */ |
||
1217 | 4 | public function timeSeparator() |
|
1218 | { |
||
1219 | 4 | if (empty($this->time_separator)) { |
|
1220 | 4 | $this->time_separator = $this->timeSeparatorFormat($this->get_time_format()); |
|
1221 | } |
||
1222 | 4 | return $this->time_separator; |
|
1223 | } |
||
1224 | |||
1225 | /** |
||
1226 | * Find out format's time separator |
||
1227 | * @param string $timeformat Time format |
||
1228 | * @return stringS |
||
1229 | */ |
||
1230 | 4 | public function timeSeparatorFormat($timeformat) |
|
1231 | { |
||
1232 | 4 | $date = $this->_convert("00:11:22", self::DB_TIME_FORMAT, null, $timeformat, null); |
|
1233 | 4 | if (preg_match('/\d+(.+?)11/', $date, $matches)) { |
|
1234 | 4 | $sep = $matches[1]; |
|
1235 | } else { |
||
1236 | $sep = ':'; |
||
1237 | } |
||
1238 | 4 | return $sep; |
|
1239 | } |
||
1240 | |||
1241 | /** |
||
1242 | * Returns start and end of a certain local date in GMT |
||
1243 | * Example: for May 19 in PDT start would be 2010-05-19 07:00:00, end would be 2010-05-20 06:59:59 |
||
1244 | * @param string|DateTime $date Date in any suitable format |
||
1245 | * @param User $user |
||
1246 | * @return array Start & end date in start, startdate, starttime, end, enddate, endtime |
||
1247 | */ |
||
1248 | public function getDayStartEndGMT($date, User $user = null) |
||
1249 | { |
||
1250 | if ($date instanceof DateTime) { |
||
1251 | $min = clone $date; |
||
1252 | $min->setTimezone($this->_getUserTZ($user)); |
||
1253 | $max = clone $date; |
||
1254 | $max->setTimezone($this->_getUserTZ($user)); |
||
1255 | } else { |
||
1256 | $min = new DateTime($date, $this->_getUserTZ($user)); |
||
1257 | $max = new DateTime($date, $this->_getUserTZ($user)); |
||
1258 | } |
||
1259 | $min->setTime(0, 0); |
||
1260 | $max->setTime(23, 59, 59); |
||
1261 | |||
1262 | $min->setTimezone(self::$gmtTimezone); |
||
1263 | $max->setTimezone(self::$gmtTimezone); |
||
1264 | |||
1265 | $result['start'] = $this->asDb($min); |
||
1266 | $result['startdate'] = $this->asDbDate($min); |
||
1267 | $result['starttime'] = $this->asDbTime($min); |
||
1268 | $result['end'] = $this->asDb($max); |
||
1269 | $result['enddate'] = $this->asDbDate($max); |
||
1270 | $result['endtime'] = $this->asDbtime($max); |
||
1271 | |||
1272 | return $result; |
||
1273 | } |
||
1274 | |||
1275 | /** |
||
1276 | * Expand date format by adding midnight to it |
||
1277 | * Note: date is assumed to be in target format already |
||
1278 | * @param string $date |
||
1279 | * @param string $format Target format |
||
1280 | * @return string |
||
1281 | */ |
||
1282 | 4 | public function expandDate($date, $format) |
|
1283 | { |
||
1284 | 4 | $formats = $this->split_date_time($format); |
|
1285 | 4 | if(isset($formats[1])) { |
|
1286 | 4 | return $this->merge_date_time($date, $this->_get_midnight($formats[1])); |
|
1287 | } |
||
1288 | return $date; |
||
1289 | } |
||
1290 | |||
1291 | /** |
||
1292 | * Expand time format by adding today to it |
||
1293 | * Note: time is assumed to be in target format already |
||
1294 | * @param string $date |
||
1295 | * @param string $format Target format |
||
1296 | * @param DateTimeZone $tz |
||
1297 | * @return string |
||
1298 | */ |
||
1299 | public function expandTime($date, $format, $tz) |
||
1300 | { |
||
1301 | $formats = $this->split_date_time($format); |
||
1302 | if(isset($formats[1])) { |
||
1303 | $now = clone $this->getNow(); |
||
1304 | $now->setTimezone($tz); |
||
1305 | return $this->merge_date_time($now->format($formats[0]), $date); |
||
1306 | } |
||
1307 | return $date; |
||
1308 | } |
||
1309 | |||
1310 | /** |
||
1311 | * Get midnight (start of the day) in local time format |
||
1312 | * |
||
1313 | * @return Time string |
||
1314 | */ |
||
1315 | function get_default_midnight() |
||
1316 | { |
||
1317 | return $this->_get_midnight($this->get_time_format()); |
||
1318 | } |
||
1319 | |||
1320 | /** |
||
1321 | * Get the name of the timezone for the user |
||
1322 | * @param User $user User, default - current user |
||
1323 | * @return string |
||
1324 | */ |
||
1325 | 8 | public static function userTimezone(User $user = null) |
|
1326 | { |
||
1327 | 8 | $user = self::getInstance()->_getUser($user); |
|
1328 | 8 | if(empty($user)) { |
|
1329 | return ''; |
||
1330 | } |
||
1331 | 8 | $tz = self::getInstance()->_getUserTZ($user); |
|
1332 | 8 | if($tz) { |
|
1333 | 8 | return $tz->getName(); |
|
1334 | } |
||
1335 | return ''; |
||
1336 | } |
||
1337 | |||
1338 | /** |
||
1339 | * Guess the timezone for the current user |
||
1340 | * @param int $userOffset Offset from GMT in minutes |
||
1341 | * @return string |
||
1342 | */ |
||
1343 | public static function guessTimezone($userOffset = 0) |
||
1344 | { |
||
1345 | if(!is_numeric($userOffset)) { |
||
1346 | return ''; |
||
1347 | } |
||
1348 | $defaultZones= array( |
||
1349 | 'America/Anchorage', 'America/Los_Angeles', 'America/Phoenix', 'America/Chicago', |
||
1350 | 'America/New_York', 'America/Argentina/Buenos_Aires', 'America/Montevideo', |
||
1351 | 'Europe/London', 'Europe/Amsterdam', 'Europe/Athens', 'Europe/Moscow', |
||
1352 | 'Asia/Tbilisi', 'Asia/Omsk', 'Asia/Jakarta', 'Asia/Hong_Kong', |
||
1353 | 'Asia/Tokyo', 'Pacific/Guam', 'Australia/Sydney', 'Australia/Perth', |
||
1354 | ); |
||
1355 | |||
1356 | $now = new DateTime(); |
||
1357 | $tzlist = timezone_identifiers_list(); |
||
1358 | if($userOffset == 0) { |
||
1359 | $gmtOffset = date('Z'); |
||
1360 | $nowtz = date('e'); |
||
1361 | if(in_array($nowtz, $tzlist)) { |
||
1362 | array_unshift($defaultZones, $nowtz); |
||
1363 | } else { |
||
1364 | $nowtz = timezone_name_from_abbr(date('T'), $gmtOffset, date('I')); |
||
1365 | if(in_array($nowtz, $tzlist)) { |
||
1366 | array_unshift($defaultZones, $nowtz); |
||
1367 | } |
||
1368 | } |
||
1369 | } else { |
||
1370 | $gmtOffset = $userOffset * 60; |
||
1371 | } |
||
1372 | foreach($defaultZones as $zoneName) { |
||
1373 | $tz = new DateTimeZone($zoneName); |
||
1374 | if($tz->getOffset($now) == $gmtOffset) { |
||
1375 | return $tz->getName(); |
||
1376 | } |
||
1377 | } |
||
1378 | // try all zones |
||
1379 | foreach($tzlist as $zoneName) { |
||
1380 | $tz = new DateTimeZone($zoneName); |
||
1381 | if($tz->getOffset($now) == $gmtOffset) { |
||
1382 | return $tz->getName(); |
||
1383 | } |
||
1384 | } |
||
1385 | return null; |
||
1386 | } |
||
1387 | |||
1388 | /** |
||
1389 | * Get the description of the user timezone for specific date |
||
1390 | * Like: PST(+08:00) |
||
1391 | * We need the date because it can be DST or non-DST |
||
1392 | * Note it's different from TZ name in tzName() that relates to current date |
||
1393 | * @param DateTime $date Current date |
||
1394 | * @param User $user User, default - current user |
||
1395 | * @return string |
||
1396 | */ |
||
1397 | 5 | public static function userTimezoneSuffix(DateTime $date, User $user = null) |
|
1398 | { |
||
1399 | 5 | $user = self::getInstance()->_getUser($user); |
|
1400 | 5 | if(empty($user)) { |
|
1401 | return ''; |
||
1402 | } |
||
1403 | 5 | self::getInstance()->tzUser($date, $user); |
|
1404 | 5 | return $date->format('T(P)'); |
|
1405 | } |
||
1406 | |||
1407 | /** |
||
1408 | * Get display name for a certain timezone |
||
1409 | * Note: it uses current date for GMT offset, so it may be not suitable for displaying generic dates |
||
1410 | * @param string|DateTimeZone $name TZ name |
||
1411 | * @return string |
||
1412 | */ |
||
1413 | 7 | public static function tzName($name) |
|
1414 | { |
||
1415 | 7 | if(empty($name)) { |
|
1416 | return ''; |
||
1417 | } |
||
1418 | 7 | if($name instanceof DateTimeZone) { |
|
1419 | $tz = $name; |
||
1420 | } else { |
||
1421 | 7 | $tz = timezone_open($name); |
|
1422 | } |
||
1423 | 7 | if(!$tz) { |
|
1424 | return "???"; |
||
1425 | } |
||
1426 | 7 | $now = new DateTime("now", $tz); |
|
1427 | 7 | $off = $now->getOffset(); |
|
1428 | 7 | $translated = translate('timezone_dom','',$name); |
|
0 ignored issues
–
show
It seems like
$name defined by parameter $name on line 1413 can also be of type object<DateTimeZone> ; however, translate() does only seem to accept string , maybe add an additional type check?
This check looks at variables that have been passed in as parameters and are passed out again to other methods. If the outgoing method call has stricter type requirements than the method itself, an issue is raised. An additional type check may prevent trouble. ![]() |
|||
1429 | 7 | if(is_string($translated) && !empty($translated)) { |
|
1430 | $name = $translated; |
||
1431 | } |
||
1432 | 7 | return sprintf("%s (GMT%+2d:%02d)%s", str_replace('_',' ', $name), $off/3600, (abs($off)/60)%60, "");//$now->format('I')==1?"(+DST)":""); |
|
1433 | } |
||
1434 | |||
1435 | |||
1436 | /** |
||
1437 | * Timezone sorting helper |
||
1438 | * Sorts by name |
||
1439 | * @param array $a |
||
1440 | * @param array $b |
||
1441 | * @internal |
||
1442 | * @return int |
||
1443 | */ |
||
1444 | public static function _sortTz($a, $b) |
||
1445 | { |
||
1446 | if($a[0] == $b[0]) { |
||
1447 | return strcmp($a[1], $b[1]); |
||
1448 | } else { |
||
1449 | return $a[0]<$b[0]?-1:1; |
||
1450 | } |
||
1451 | } |
||
1452 | |||
1453 | /** |
||
1454 | * Get list of all timezones in the system |
||
1455 | * @return array |
||
1456 | */ |
||
1457 | public static function getTimezoneList() |
||
1458 | { |
||
1459 | $now = new DateTime(); |
||
1460 | $res_zones = $zones = array(); |
||
1461 | foreach(timezone_identifiers_list() as $zoneName) { |
||
1462 | $tz = new DateTimeZone($zoneName); |
||
1463 | $zones[$zoneName] = array($tz->getOffset($now), self::tzName($zoneName)); |
||
1464 | } |
||
1465 | uasort($zones, array('TimeDate', '_sortTz')); |
||
1466 | foreach($zones as $name => $zonedef) { |
||
1467 | $res_zones[$name] = $zonedef[1]; |
||
1468 | } |
||
1469 | return $res_zones; |
||
1470 | } |
||
1471 | |||
1472 | /** |
||
1473 | * Print timestamp in RFC2616 format: |
||
1474 | * @param int|null $ts Null means current ts |
||
1475 | * @return string |
||
1476 | */ |
||
1477 | public static function httpTime($ts = null) |
||
1478 | { |
||
1479 | if($ts === null) { |
||
1480 | $ts = time(); |
||
1481 | } |
||
1482 | return gmdate(self::RFC2616_FORMAT, $ts); |
||
1483 | } |
||
1484 | |||
1485 | /** |
||
1486 | * Create datetime object from calendar array |
||
1487 | * @param array $time |
||
1488 | * @return SugarDateTime |
||
1489 | */ |
||
1490 | public function fromTimeArray($time) |
||
1491 | { |
||
1492 | if (! isset( $time) || count($time) == 0 ) |
||
1493 | { |
||
1494 | return $this->nowDb(); |
||
1495 | } |
||
1496 | elseif ( isset( $time['ts'])) |
||
1497 | { |
||
1498 | return $this->fromTimestamp($time['ts']); |
||
1499 | } |
||
1500 | elseif ( isset( $time['date_str'])) |
||
1501 | { |
||
1502 | return $this->fromDb($time['date_str']); |
||
1503 | } |
||
1504 | else |
||
1505 | { |
||
1506 | $hour = 0; |
||
1507 | $min = 0; |
||
1508 | $sec = 0; |
||
1509 | $now = $this->getNow(true); |
||
1510 | $day = $now->day; |
||
1511 | $month = $now->month; |
||
1512 | $year = $now->year; |
||
1513 | if (isset($time['sec'])) |
||
1514 | { |
||
1515 | $sec = $time['sec']; |
||
1516 | } |
||
1517 | if (isset($time['min'])) |
||
1518 | { |
||
1519 | $min = $time['min']; |
||
1520 | } |
||
1521 | if (isset($time['hour'])) |
||
1522 | { |
||
1523 | $hour = $time['hour']; |
||
1524 | } |
||
1525 | if (isset($time['day'])) |
||
1526 | { |
||
1527 | $day = $time['day']; |
||
1528 | } |
||
1529 | if (isset($time['month'])) |
||
1530 | { |
||
1531 | $month = $time['month']; |
||
1532 | } |
||
1533 | if (isset($time['year']) && $time['year'] >= 1970) |
||
1534 | { |
||
1535 | $year = $time['year']; |
||
1536 | } |
||
1537 | return $now->setDate($year, $month, $day)->setTime($hour, $min, $sec)->setTimeZone(self::$gmtTimezone); |
||
1538 | } |
||
1539 | return null; |
||
0 ignored issues
–
show
return null; does not seem to be reachable.
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed. Unreachable code is most often the result of function fx() {
try {
doSomething();
return true;
}
catch (\Exception $e) {
return false;
}
return false;
}
In the above example, the last ![]() |
|||
1540 | } |
||
1541 | |||
1542 | /** |
||
1543 | * Returns the date portion of a datetime string |
||
1544 | * |
||
1545 | * @param string $datetime |
||
1546 | * @return string |
||
1547 | */ |
||
1548 | public function getDatePart($datetime) |
||
1549 | { |
||
1550 | list($date, $time) = $this->split_date_time($datetime); |
||
0 ignored issues
–
show
The assignment to
$time is unused. Consider omitting it like so list($first,,$third) .
This checks looks for assignemnts to variables using the Consider the following code example. <?php
function returnThreeValues() {
return array('a', 'b', 'c');
}
list($a, $b, $c) = returnThreeValues();
print $a . " - " . $c;
Only the variables Instead, the list call could have been. list($a,, $c) = returnThreeValues();
![]() |
|||
1551 | return $date; |
||
1552 | } |
||
1553 | |||
1554 | /** |
||
1555 | * Returns the time portion of a datetime string |
||
1556 | * |
||
1557 | * @param string $datetime |
||
1558 | * @return string |
||
1559 | */ |
||
1560 | public function getTimePart($datetime) |
||
1561 | { |
||
1562 | list($date, $time) = $this->split_date_time($datetime); |
||
0 ignored issues
–
show
The assignment to
$date is unused. Consider omitting it like so list($first,,$third) .
This checks looks for assignemnts to variables using the Consider the following code example. <?php
function returnThreeValues() {
return array('a', 'b', 'c');
}
list($a, $b, $c) = returnThreeValues();
print $a . " - " . $c;
Only the variables Instead, the list call could have been. list($a,, $c) = returnThreeValues();
![]() |
|||
1563 | return $time; |
||
1564 | } |
||
1565 | |||
1566 | /** |
||
1567 | * Returns the offset from user's timezone to GMT |
||
1568 | * @param User $user |
||
1569 | * @param DateTime $time When the offset is taken, default is now |
||
1570 | * @return int Offset in minutes |
||
1571 | */ |
||
1572 | 12 | public function getUserUTCOffset(User $user = null, DateTime $time = null) |
|
1573 | { |
||
1574 | 12 | if(empty($time)) { |
|
1575 | 12 | $time = $this->now; |
|
1576 | } |
||
1577 | 12 | return $this->_getUserTZ($user)->getOffset($time) / 60; |
|
1578 | } |
||
1579 | |||
1580 | /** |
||
1581 | * Create regexp from datetime format |
||
1582 | * @param string $format |
||
1583 | * @return string Regular expression string |
||
1584 | */ |
||
1585 | 4 | public static function get_regular_expression($format) |
|
1586 | { |
||
1587 | 4 | $newFormat = ''; |
|
1588 | 4 | $regPositions = array(); |
|
1589 | 4 | $ignoreNextChar = false; |
|
1590 | 4 | $count = 1; |
|
1591 | 4 | foreach (str_split($format) as $char) { |
|
1592 | 4 | if (! $ignoreNextChar && isset(self::$format_to_regexp[$char])) { |
|
1593 | 4 | $newFormat .= '(' . self::$format_to_regexp[$char] . ')'; |
|
1594 | 4 | $regPositions[$char] = $count; |
|
1595 | 4 | $count ++; |
|
1596 | } else { |
||
1597 | 4 | $ignoreNextChar = false; |
|
1598 | 4 | $newFormat .= $char; |
|
1599 | |||
1600 | } |
||
1601 | 4 | if ($char == "\\") { |
|
1602 | 4 | $ignoreNextChar = true; |
|
1603 | } |
||
1604 | } |
||
1605 | |||
1606 | 4 | return array('format' => $newFormat, 'positions' => $regPositions); |
|
1607 | } |
||
1608 | |||
1609 | // format - date expression ('' means now) for start and end of the range |
||
1610 | protected $date_expressions = array( |
||
1611 | 'yesterday' => array("-1 day", "-1 day"), |
||
1612 | 'today' => array("", ""), |
||
1613 | 'tomorrow' => array("+1 day", "+1 day"), |
||
1614 | 'last_7_days' => array("-6 days", ""), |
||
1615 | 'next_7_days' => array("", "+6 days"), |
||
1616 | 'last_30_days' => array("-29 days", ""), |
||
1617 | 'next_30_days' => array("", "+29 days"), |
||
1618 | ); |
||
1619 | |||
1620 | /** |
||
1621 | * Parse date template |
||
1622 | * @internal |
||
1623 | * @param string $template Date expression |
||
1624 | * @param bool $daystart Do we want start or end of the day? |
||
1625 | * @param User $user |
||
1626 | * @param bool $adjustForTimezone |
||
1627 | * @return SugarDateTime |
||
1628 | */ |
||
1629 | protected function parseFromTemplate($template, $daystart, User $user = null, $adjustForTimezone = true) |
||
1630 | { |
||
1631 | $rawTime = $this->getNow(); |
||
1632 | $now = $adjustForTimezone?$this->tzUser($rawTime, $user):$rawTime; |
||
1633 | if(!empty($template)) { |
||
1634 | $now->modify($template); |
||
1635 | } |
||
1636 | if($daystart) { |
||
1637 | return $now->get_day_begin(); |
||
0 ignored issues
–
show
It seems like you code against a specific sub-type and not the parent class
DateTime as the method get_day_begin() does only exist in the following sub-classes of DateTime : SugarDateTime . Maybe you want to instanceof check for one of these explicitly?
Let’s take a look at an example: abstract class User
{
/** @return string */
abstract public function getPassword();
}
class MyUser extends User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
![]() |
|||
1638 | } else { |
||
1639 | return $now->get_day_end(); |
||
0 ignored issues
–
show
It seems like you code against a specific sub-type and not the parent class
DateTime as the method get_day_end() does only exist in the following sub-classes of DateTime : SugarDateTime . Maybe you want to instanceof check for one of these explicitly?
Let’s take a look at an example: abstract class User
{
/** @return string */
abstract public function getPassword();
}
class MyUser extends User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
![]() |
|||
1640 | } |
||
1641 | } |
||
1642 | |||
1643 | /** |
||
1644 | * Get month-long range mdiff months from now |
||
1645 | * @internal |
||
1646 | * @param int $mdiff |
||
1647 | * @param User $user |
||
1648 | * @param bool $adjustForTimezone |
||
1649 | * @return array |
||
1650 | */ |
||
1651 | protected function diffMon($mdiff, User $user = null, $adjustForTimezone = true) |
||
1652 | { |
||
1653 | $rawTime = $this->getNow(); |
||
1654 | $now = $adjustForTimezone?$this->tzUser($rawTime, $user):$rawTime; |
||
1655 | $now->setDate($now->year, $now->month+$mdiff, 1); |
||
1656 | $start = $now->get_day_begin(); |
||
0 ignored issues
–
show
It seems like you code against a specific sub-type and not the parent class
DateTime as the method get_day_begin() does only exist in the following sub-classes of DateTime : SugarDateTime . Maybe you want to instanceof check for one of these explicitly?
Let’s take a look at an example: abstract class User
{
/** @return string */
abstract public function getPassword();
}
class MyUser extends User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
![]() |
|||
1657 | $end = $now->setDate($now->year, $now->month, $now->days_in_month)->setTime(23, 59, 59); |
||
1658 | return array($start, $end); |
||
1659 | } |
||
1660 | |||
1661 | /** |
||
1662 | * Get year-long range ydiff years from now |
||
1663 | * @internal |
||
1664 | * @param int $ydiff |
||
1665 | * @param User $user |
||
1666 | * @param bool $adjustForTimezone |
||
1667 | * @return array |
||
1668 | */ |
||
1669 | protected function diffYear($ydiff, User $user = null, $adjustForTimezone = true) |
||
1670 | { |
||
1671 | $rawTime = $this->getNow(); |
||
1672 | $now = $adjustForTimezone?$this->tzUser($rawTime, $user):$rawTime; |
||
1673 | $now->setDate($now->year+$ydiff, 1, 1); |
||
1674 | $start = $now->get_day_begin(); |
||
0 ignored issues
–
show
It seems like you code against a specific sub-type and not the parent class
DateTime as the method get_day_begin() does only exist in the following sub-classes of DateTime : SugarDateTime . Maybe you want to instanceof check for one of these explicitly?
Let’s take a look at an example: abstract class User
{
/** @return string */
abstract public function getPassword();
}
class MyUser extends User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
![]() |
|||
1675 | $end = $now->setDate($now->year, 12, 31)->setTime(23, 59, 59); |
||
1676 | return array($start, $end); |
||
1677 | } |
||
1678 | |||
1679 | /** |
||
1680 | * Parse date range expression |
||
1681 | * Returns beginning and end of the range as a date |
||
1682 | * @param string $range |
||
1683 | * @param User $user |
||
1684 | * @param bool $adjustForTimezone Do we need to adjust for timezone? |
||
1685 | * @return array of two Date objects, start & end |
||
1686 | */ |
||
1687 | public function parseDateRange($range, User $user = null, $adjustForTimezone = true) |
||
1688 | { |
||
1689 | if(isset($this->date_expressions[$range])) { |
||
1690 | return array($this->parseFromTemplate($this->date_expressions[$range][0], true, $user, $adjustForTimezone), |
||
1691 | $this->parseFromTemplate($this->date_expressions[$range][1], false, $user, $adjustForTimezone) |
||
1692 | ); |
||
1693 | } |
||
1694 | switch($range) { |
||
1695 | case 'next_month': |
||
1696 | return $this->diffMon(1, $user, $adjustForTimezone); |
||
1697 | case 'last_month': |
||
1698 | return $this->diffMon(-1, $user, $adjustForTimezone); |
||
1699 | case 'this_month': |
||
1700 | return $this->diffMon(0, $user, $adjustForTimezone); |
||
1701 | case 'last_year': |
||
1702 | return $this->diffYear(-1, $user, $adjustForTimezone); |
||
1703 | case 'this_year': |
||
1704 | return $this->diffYear(0, $user, $adjustForTimezone); |
||
1705 | case 'next_year': |
||
1706 | return $this->diffYear(1, $user, $adjustForTimezone); |
||
1707 | default: |
||
1708 | return null; |
||
1709 | } |
||
1710 | } |
||
1711 | |||
1712 | /********************* OLD functions, should not be used publicly anymore ****************/ |
||
1713 | /** |
||
1714 | * Merge time without am/pm with am/pm string |
||
1715 | * @TODO find better way to do this! |
||
1716 | * @deprecated for public use |
||
1717 | * @param string $date |
||
1718 | * @param string $format User time format |
||
1719 | * @param string $mer |
||
1720 | * @return string |
||
1721 | */ |
||
1722 | function merge_time_meridiem($date, $format, $mer) |
||
1723 | { |
||
1724 | $date = trim($date); |
||
1725 | if (empty($date)) { |
||
1726 | return $date; |
||
1727 | } |
||
1728 | $fakeMerFormat = str_replace(array('a', 'A'), array('@~@', '@~@'), $format); |
||
1729 | $noMerFormat = trim(str_replace(array('a', 'A'), array('', ''), $format)); |
||
1730 | $newDate = $this->swap_formats($date, $noMerFormat, $fakeMerFormat); |
||
0 ignored issues
–
show
The method
TimeDate::swap_formats() has been deprecated with message: for public useConvert date from one format to another This method has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead. ![]() |
|||
1731 | return str_replace('@~@', $mer, $newDate); |
||
1732 | } |
||
1733 | |||
1734 | /** |
||
1735 | * @deprecated for public use |
||
1736 | * Convert date from one format to another |
||
1737 | * |
||
1738 | * @param string $date |
||
1739 | * @param string $from |
||
1740 | * @param string $to |
||
1741 | * @return string |
||
1742 | */ |
||
1743 | public function swap_formats($date, $from, $to) |
||
1744 | { |
||
1745 | return $this->_convert($date, $from, self::$gmtTimezone, $to, self::$gmtTimezone); |
||
1746 | } |
||
1747 | |||
1748 | /** |
||
1749 | * @deprecated for public use |
||
1750 | * handles offset values for Timezones and DST |
||
1751 | * @param $date string date/time formatted in user's selected format |
||
1752 | * @param $format string destination format value as passed to PHP's date() funtion |
||
1753 | * @param $to boolean |
||
1754 | * @param $user object user object from which Timezone and DST |
||
1755 | * @param $usetimezone string timezone name |
||
1756 | * values will be derived |
||
1757 | * @return string date formatted and adjusted for TZ and DST |
||
1758 | */ |
||
1759 | 2 | function handle_offset($date, $format, $to = true, $user = null, $usetimezone = null) |
|
1760 | { |
||
1761 | 2 | $tz = empty($usetimezone)?$this->_getUserTZ($user):new DateTimeZone($usetimezone); |
|
1762 | 2 | $dateobj = new SugarDateTime($date, $to? self::$gmtTimezone : $tz); |
|
1763 | 2 | $dateobj->setTimezone($to ? $tz: self::$gmtTimezone); |
|
1764 | 2 | return $dateobj->format($format); |
|
1765 | // return $this->_convert($date, $format, $to ? self::$gmtTimezone : $tz, $format, $to ? $tz : self::$gmtTimezone); |
||
1766 | } |
||
1767 | |||
1768 | /** |
||
1769 | * @deprecated for public use |
||
1770 | * Get current GMT datetime in DB format |
||
1771 | * @return string |
||
1772 | */ |
||
1773 | function get_gmt_db_datetime() |
||
1774 | { |
||
1775 | return $this->nowDb(); |
||
1776 | } |
||
1777 | |||
1778 | /** |
||
1779 | * @deprecated for public use |
||
1780 | * Get current GMT date in DB format |
||
1781 | * @return string |
||
1782 | */ |
||
1783 | function get_gmt_db_date() |
||
1784 | { |
||
1785 | return $this->nowDbDate(); |
||
1786 | } |
||
1787 | |||
1788 | /** |
||
1789 | * @deprecated for public use |
||
1790 | * this method will take an input $date variable (expecting Y-m-d format) |
||
1791 | * and get the GMT equivalent - with an hour-level granularity : |
||
1792 | * return the max value of a given locale's |
||
1793 | * date+time in GMT metrics (i.e., if in PDT, "2005-01-01 23:59:59" would be |
||
1794 | * "2005-01-02 06:59:59" in GMT metrics) |
||
1795 | * @param $date |
||
1796 | * @return array |
||
1797 | */ |
||
1798 | function handleOffsetMax($date) |
||
1799 | { |
||
1800 | $min = new DateTime($date, $this->_getUserTZ()); |
||
1801 | $min->setTime(0, 0); |
||
1802 | $max = new DateTime($date, $this->_getUserTZ()); |
||
1803 | $max->setTime(23, 59, 59); |
||
1804 | |||
1805 | $min->setTimezone(self::$gmtTimezone); |
||
1806 | $max->setTimezone(self::$gmtTimezone); |
||
1807 | |||
1808 | $gmtDateTime['date'] = $this->asDbDate($max, false); |
||
1809 | $gmtDateTime['time'] = $this->asDbDate($max, false); |
||
1810 | $gmtDateTime['min'] = $this->asDb($min); |
||
1811 | $gmtDateTime['max'] = $this->asDb($max); |
||
1812 | |||
1813 | return $gmtDateTime; |
||
1814 | } |
||
1815 | |||
1816 | /** |
||
1817 | * @deprecated for public use |
||
1818 | * this returns the adjustment for a user against the server time |
||
1819 | * |
||
1820 | * @return integer number of minutes to adjust a time by to get the appropriate time for the user |
||
1821 | */ |
||
1822 | public function adjustmentForUserTimeZone() |
||
1823 | { |
||
1824 | $tz = $this->_getUserTZ(); |
||
1825 | $server_tz = new DateTimeZone(date_default_timezone_get()); |
||
1826 | if ($tz && $server_tz) { |
||
1827 | return ($server_tz->getOffset($this->now) - $tz->getOffset($this->now)) / 60; |
||
1828 | } |
||
1829 | return 0; |
||
1830 | } |
||
1831 | |||
1832 | /** |
||
1833 | * @deprecated for public use |
||
1834 | * assumes that olddatetime is in Y-m-d H:i:s format |
||
1835 | * @param $olddatetime |
||
1836 | * @return string |
||
1837 | */ |
||
1838 | function convert_to_gmt_datetime($olddatetime) |
||
1839 | { |
||
1840 | if (! empty($olddatetime)) { |
||
1841 | return date('Y-m-d H:i:s', strtotime($olddatetime) - date('Z')); |
||
1842 | } |
||
1843 | return ''; |
||
1844 | } |
||
1845 | |||
1846 | /** |
||
1847 | * @deprecated for public use |
||
1848 | * get user timezone info |
||
1849 | * @param User $user |
||
1850 | * @return array |
||
1851 | */ |
||
1852 | public function getUserTimeZone(User $user = null) |
||
1853 | { |
||
1854 | $tz = $this->_getUserTZ($user); |
||
1855 | return array("gmtOffset" => $tz->getOffset($this->now) / 60); |
||
1856 | } |
||
1857 | |||
1858 | /** |
||
1859 | * @deprecated for public use |
||
1860 | * get timezone start & end |
||
1861 | * @param $year |
||
1862 | * @param string $zone |
||
1863 | * @return array |
||
1864 | */ |
||
1865 | public function getDSTRange($year, $zone = null) |
||
1866 | { |
||
1867 | if(!empty($zone)) { |
||
1868 | $tz = timezone_open($zone); |
||
1869 | } |
||
1870 | if(empty($tz)) { |
||
1871 | $tz = $this->_getUserTZ(); |
||
1872 | } |
||
1873 | |||
1874 | $year_date = SugarDateTime::createFromFormat("Y", $year, self::$gmtTimezone); |
||
1875 | $year_end = clone $year_date; |
||
1876 | $year_end->setDate((int) $year, 12, 31); |
||
1877 | $year_end->setTime(23, 59, 59); |
||
1878 | $year_date->setDate((int) $year, 1, 1); |
||
1879 | $year_date->setTime(0, 0, 0); |
||
1880 | $result = array(); |
||
1881 | $transitions = $tz->getTransitions($year_date->ts, $year_end->ts); |
||
1882 | $idx = 0; |
||
1883 | if(version_compare(PHP_VERSION, '5.3.0', '<')) { |
||
1884 | // <5.3.0 ignores parameters, advance manually to current year |
||
1885 | $start_ts = $year_date->ts; |
||
1886 | while(isset($transitions[$idx]) && $transitions[$idx]["ts"] < $start_ts) $idx++; |
||
1887 | } |
||
1888 | // get DST start |
||
1889 | while (isset($transitions[$idx]) && !$transitions[$idx]["isdst"]) $idx++; |
||
1890 | if(isset($transitions[$idx])) { |
||
1891 | $result["start"] = $this->fromTimestamp($transitions[$idx]["ts"])->asDb(); |
||
1892 | } |
||
1893 | // get DST end |
||
1894 | while (isset($transitions[$idx]) && $transitions[$idx]["isdst"]) $idx++; |
||
1895 | if(isset($transitions[$idx])) { |
||
1896 | $result["end"] = $this->fromTimestamp($transitions[$idx]["ts"])->asDb(); |
||
1897 | } |
||
1898 | return $result; |
||
1899 | } |
||
1900 | |||
1901 | /****************** GUI stuff that really shouldn't be here, will be moved ************/ |
||
1902 | /** |
||
1903 | * Get Javascript variables setup for user date format validation |
||
1904 | * @deprecated moved to SugarView |
||
1905 | * @return string JS code |
||
1906 | */ |
||
1907 | function get_javascript_validation() |
||
1908 | { |
||
1909 | return SugarView::getJavascriptValidation(); |
||
1910 | } |
||
1911 | |||
1912 | /** |
||
1913 | * AMPMMenu |
||
1914 | * This method renders a SELECT HTML form element based on the |
||
1915 | * user's time format preferences, with give date's value highlighted. |
||
1916 | * |
||
1917 | * If user's prefs have no AM/PM string, returns empty string. |
||
1918 | * |
||
1919 | * @todo There is hardcoded HTML in here that does not allow for localization |
||
1920 | * of the AM/PM am/pm Strings in this drop down menu. Also, perhaps |
||
1921 | * change to the substr_count function calls to strpos |
||
1922 | * TODO: Remove after full switch to fields |
||
1923 | * @deprecated |
||
1924 | * @param string $prefix Prefix for SELECT |
||
1925 | * @param string $date Date in display format |
||
1926 | * @param string $attrs Additional attributes for SELECT |
||
1927 | * @return string SELECT HTML |
||
1928 | */ |
||
1929 | 4 | function AMPMMenu($prefix, $date, $attrs = '') |
|
1930 | { |
||
1931 | 4 | $tf = $this->get_time_format(); |
|
1932 | 4 | $am = strpbrk($tf, 'aA'); |
|
1933 | 4 | if ($am == false) { |
|
0 ignored issues
–
show
|
|||
1934 | 4 | return ''; |
|
1935 | } |
||
1936 | $selected = array("am" => "", "pm" => "", "AM" => "", "PM" => ""); |
||
1937 | if (preg_match('/([ap]m)/i', $date, $match)) { |
||
1938 | $selected[$match[1]] = " selected"; |
||
1939 | } |
||
1940 | |||
1941 | $menu = "<select name='" . $prefix . "meridiem' " . $attrs . ">"; |
||
1942 | if ($am{0} == 'a') { |
||
1943 | $menu .= "<option value='am'{$selected["am"]}>am"; |
||
1944 | $menu .= "<option value='pm'{$selected["pm"]}>pm"; |
||
1945 | } else { |
||
1946 | $menu .= "<option value='AM'{$selected["AM"]}>AM"; |
||
1947 | $menu .= "<option value='PM'{$selected["PM"]}>PM"; |
||
1948 | } |
||
1949 | |||
1950 | return $menu . '</select>'; |
||
1951 | } |
||
1952 | |||
1953 | /** |
||
1954 | * Get user format in JS form |
||
1955 | * TODO: Remove after full switch to fields |
||
1956 | * @return string |
||
1957 | */ |
||
1958 | 9 | function get_user_date_format() |
|
1959 | { |
||
1960 | 9 | return str_replace(array('Y', 'm', 'd'), array('yyyy', 'mm', 'dd'), $this->get_date_format()); |
|
1961 | } |
||
1962 | |||
1963 | /** |
||
1964 | * Get user time format example |
||
1965 | * TODO: Remove after full switch to fields |
||
1966 | * @deprecated |
||
1967 | * @return string |
||
1968 | */ |
||
1969 | 9 | function get_user_time_format() |
|
1970 | { |
||
1971 | 9 | global $sugar_config; |
|
1972 | 9 | $time_pref = $this->get_time_format(); |
|
1973 | |||
1974 | 9 | if (! empty($time_pref) && ! empty($sugar_config['time_formats'][$time_pref])) { |
|
1975 | 9 | return $sugar_config['time_formats'][$time_pref]; |
|
1976 | } |
||
1977 | |||
1978 | return '23:00'; //default |
||
1979 | } |
||
1980 | |||
1981 | } |
||
1982 |
The break statement is not necessary if it is preceded for example by a return statement:
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.