PluginProbe
404 Solution / 4.3.0
404 Solution v4.3.0
4.3.5 4.3.4 4.3.3 4.3.2 4.3.1 4.3.0 4.2.0 4.1.19 4.1.18 4.1.17 4.1.16 4.1.15 4.1.13 4.1.12 4.1.11 4.1.10 4.1.9 4.1.8 4.1.7 4.1.6 4.1.5 4.1.4 4.1.3 trunk 2.30.0 All 109 releases
404-solution / includes / logs / LogTimestampFormatter.php

LogTimestampFormatter.php in 404 Solution 4.3.0, at includes/logs/LogTimestampFormatter.php

69 lines 2.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if (!defined('ABSPATH')) {
4 exit;
5 }
6
7 /**
8 * Formats the current instant as a log-line timestamp in the site's configured
9 * timezone.
10 *
11 * Both WordPress option sources this reads (`timezone_string` and `gmt_offset`)
12 * can hold garbage on a corrupted site: a stray value written into the wrong
13 * options row, an out-of-range offset, a non-IANA name. A bad value must never
14 * fatal the logging path, so DateTimeZone construction for either source shares
15 * one guarded fallback to the server default and emits a breadcrumb through the
16 * raw PHP fallback sink (never through the logger itself, which would risk
17 * recursion if the timezone failure also breaks the logger's own DateTime use).
18 *
19 * Pure formatting policy: no business decisions, no data store of its own.
20 */
21 class ABJ_404_Solution_LogTimestampFormatter {
22
23 /**
24 * Current time formatted for the active site timezone.
25 *
26 * @return string A `Y-m-d H:i:s T` timestamp.
27 */
28 public function format(): string {
29 $timezoneStringRaw = get_option('timezone_string');
30 $timezoneString = is_string($timezoneStringRaw) ? $timezoneStringRaw : '';
31
32 if (!empty($timezoneString)) {
33 // WordPress stores an IANA name (e.g. "America/New_York") here.
34 $tzString = $timezoneString;
35 } else {
36 $gmtOffsetRaw = get_option('gmt_offset');
37 // WordPress's gmt_offset is hours and may be fractional
38 // (e.g. 5.5 India, 5.75 Nepal, -3.5 Newfoundland).
39 $gmtOffsetHours = is_scalar($gmtOffsetRaw) ? (float)$gmtOffsetRaw : 0.0;
40 $totalMinutes = (int) round($gmtOffsetHours * 60);
41 $sign = $totalMinutes < 0 ? '-' : '+';
42 $absMinutes = abs($totalMinutes);
43 $tzString = sprintf('%s%02d:%02d', $sign, intdiv($absMinutes, 60), $absMinutes % 60);
44 }
45
46 // Both option sources can hold garbage on a corrupted site: a stray
47 // value written into the wrong options row, an out-of-range offset,
48 // etc. A bad value must never fatal the logging path, so the
49 // DateTimeZone construction for EITHER source shares one guarded
50 // fallback to the server default.
51 try {
52 $date = new DateTime('@' . abj_clock()->now());
53 $date->setTimezone(new DateTimeZone($tzString));
54 } catch (Exception $e) {
55 // Use the raw fallback sink because this method is part of
56 // the logging path; calling warn here would risk recursion if
57 // timezone failure also breaks warn's own DateTime use.
58 abj404_logPhpFallback(
59 'logger-internal',
60 'timezone constructor failed (' . $e->getMessage() . '); using server default'
61 );
62 $date = new DateTime('@' . abj_clock()->now());
63 $date->setTimezone(new DateTimeZone(date_default_timezone_get()));
64 }
65
66 return $date->format('Y-m-d H:i:s T');
67 }
68 }
69