PluginProbe
Debug Log Viewer / 2.2.3
Debug Log Viewer v2.2.3
2.5 2.5.1 2.5.2 2.4 trunk 1.0.2 1.0.3 1.1 1.1.1 1.2 1.2.1 1.3 1.4 1.4.1 1.4.2 1.4.3 2.0.1 2.0.3 2.0.4 2.0.5 2.1 2.2.3
debug-log-viewer / admin / controllers / AlertController.php

AlertController.php in Debug Log Viewer 2.2.3, at admin/controllers/AlertController.php

297 lines 7.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace DebugLogViewer\Admin\Controllers;
4
5 use DebugLogViewer\Admin\Services\EmailService;
6 use DebugLogViewer\Admin\Models\LogModel;
7
8 if (!defined('ABSPATH')) {
9 exit;
10 // Exit if accessed directly
11 }
12
13 class AlertController {
14
15
16 public $action;
17 public $options;
18 public $emailRecurrences;
19 public $sendTestEmailHandler;
20
21 public function __construct() {
22 $this->action = LogController::SCHEDULE_MAIL_SEND;
23 $this->sendTestEmailHandler = [ $this, 'sendTestEmail' ];
24
25 $this->emailRecurrences = [
26 'hourly' => __('Hourly', 'debug-log-viewer'),
27 'twicedaily' => __('Twice Daily', 'debug-log-viewer'),
28 'daily' => __('Daily', 'debug-log-viewer'),
29 'weekly' => __('Weekly', 'debug-log-viewer'),
30 ];
31 $this->options = get_option($this->buildUniqueEventName());
32 }
33
34 public function buildUniqueEventName() {
35 return strtoupper($this->action . '_user_' . \wp_get_current_user()->ID);
36 }
37
38 public function getNotificationEmails() {
39 if ($this->options && array_key_exists('dbg_lv_notifications_emails', $this->options)) {
40 return $this->options['dbg_lv_notifications_emails'];
41 }
42
43 return [];
44 }
45
46 public function isEnabled() {
47 return (bool) $this->options && array_key_exists('dbg_lv_notifications_emails', $this->options);
48 }
49
50 public function getRecurrence() {
51 foreach ($this->emailRecurrences as $key => $value) {
52 $selected = $key == $this->getRecurrences() ? 'selected="selected"' : '';
53 printf('<option value="%s" %s>%s</option>', esc_attr($key), esc_html($selected), esc_html($value));
54 }
55 }
56
57 private function getRecurrences() {
58 if (!$this->options) {
59 return null;
60 }
61
62 if (array_key_exists('dbg_lv_notifications_email_recurrence', $this->options)) {
63 return $this->options['dbg_lv_notifications_email_recurrence'];
64 }
65 return null;
66 }
67
68 public function getLevelsToReport() {
69 if ($this->options && array_key_exists('dbg_lv_notifications_levels', $this->options)) {
70 return $this->options['dbg_lv_notifications_levels'];
71 }
72
73 // Default levels if none are configured
74 return [
75 LogModel::LOG_LEVEL_DATABASE,
76 LogModel::LOG_LEVEL_FATAL,
77 LogModel::LOG_LEVEL_PARSE,
78 LogModel::LOG_LEVEL_DEPRECATED,
79 ];
80 }
81
82 public function getAllAvailableLevels() {
83 return [
84 LogModel::LOG_LEVEL_DATABASE => __('Database Errors', 'debug-log-viewer'),
85 LogModel::LOG_LEVEL_FATAL => __('Fatal Errors', 'debug-log-viewer'),
86 LogModel::LOG_LEVEL_PARSE => __('Parse Errors', 'debug-log-viewer'),
87 LogModel::LOG_LEVEL_DEPRECATED => __('Deprecated', 'debug-log-viewer'),
88 LogModel::LOG_LEVEL_WARNING => __('Warnings', 'debug-log-viewer'),
89 LogModel::LOG_LEVEL_NOTICE => __('Notices', 'debug-log-viewer'),
90 LogModel::LOG_LEVEL_CUSTOM => __('Custom', 'debug-log-viewer'),
91 ];
92 }
93
94 public function getSelectedLevels() {
95 // Always return the levels that should be selected (either saved or defaults)
96 return $this->getLevelsToReport();
97 }
98
99 private function sendTestEmail( $args ) {
100 $emails = $args['dbg_lv_notifications_emails'] ?? [];
101
102 if (empty($emails)) {
103 return;
104 }
105
106 $entries = [];
107 foreach ($this->getLevelsToReport() as $type) {
108 $timestamp = new \DateTime();
109 $datetime = $timestamp->format('Y-m-d H:i:s e');
110 $text = $type . ' error test description';
111 $hash = md5($text . '::' . $datetime);
112
113 $entries[ $type ][ $hash ] = [
114 'datetime' => $datetime,
115 'line' => wp_rand(1, 100),
116 'file' => 'example.php',
117 'type' => $type,
118 'description' => [
119 'text' => $text,
120 'stack_trace' => null,
121 ],
122 'hits' => 1,
123 ];
124 }
125
126 $emailService = new EmailService();
127 $emailService->setEmails($emails);
128 $emailService->setSubject(__('Debug Log Viewer: Log Monitoring Test Email', 'debug-log-viewer'));
129 $emailService->prepare(
130 'monitoring.tpl',
131 [
132 'website' => get_site_url(),
133 'entries' => $entries,
134 ]
135 );
136 $emailService->send();
137 }
138
139 public function sendTestEmailToRecipients( $options ) {
140 if (isset($this->sendTestEmailHandler) && is_callable($this->sendTestEmailHandler)) {
141 call_user_func($this->sendTestEmailHandler, $options);
142 }
143 }
144
145 public function sendLogsHandler( $event ) {
146 $options = get_option($event);
147
148 if (!$options) {
149 // Clean up orphaned scheduled event and exit silently
150 wp_clear_scheduled_hook($this->action, [ $event ]);
151 return;
152 }
153
154 $emails = $options['dbg_lv_notifications_emails'] ?? [];
155
156 if (empty($emails)) {
157 wp_clear_scheduled_hook($this->action, [ $event ]);
158 error_log(__('Alert email was not found in the options for the event ', 'debug-log-viewer') . $event);
159 return;
160 }
161
162 if (!array_key_exists('dbg_lv_notifications_email_recurrence', $options)) {
163 wp_clear_scheduled_hook($this->action, [ $event ]);
164 error_log(__('Alert email recurrence was not found in the options for the event ', 'debug-log-viewer') . $event);
165 return;
166 }
167
168 $recurrence = $options['dbg_lv_notifications_email_recurrence'];
169
170 $entries = ( new LogController() )->getEntriesByLevel($recurrence);
171
172 if (!$entries) {
173 return;
174 }
175
176 $emailService = new EmailService();
177 $emailService->setEmails($emails);
178 $emailService->setSubject(__('Debug Log Viewer: Monitoring has detected some problems on your website', 'debug-log-viewer'));
179 $emailService->prepare(
180 'monitoring.tpl',
181 [
182 'website' => get_site_url(),
183 'entries' => $entries,
184 ]
185 );
186 $emailService->send();
187 }
188
189 public function getNextScheduledTime() {
190 if (!$this->isEnabled()) {
191 return null;
192 }
193
194 $event_name = $this->buildUniqueEventName();
195 $timestamp = wp_next_scheduled($this->action, [ $event_name ]);
196
197 if ($timestamp) {
198 return $timestamp;
199 }
200
201 return null;
202 }
203
204 public function getFormattedNextScheduledTime() {
205 $timestamp = $this->getNextScheduledTime();
206
207 if (!$timestamp) {
208 return __('Not scheduled', 'debug-log-viewer');
209 }
210
211 $datetime = new \DateTime();
212 $datetime->setTimestamp($timestamp);
213 $datetime->setTimezone(new \DateTimeZone(wp_timezone_string()));
214
215 $date_format = get_option('date_format');
216 $time_format = get_option('time_format');
217
218 return sprintf(
219 /* translators: %1$s: date, %2$s: time */
220 __('Next run: %1$s at %2$s', 'debug-log-viewer'),
221 $datetime->format($date_format),
222 $datetime->format($time_format)
223 );
224 }
225
226 public function getTimeUntilNextEmail() {
227 $timestamp = $this->getNextScheduledTime();
228
229 if (!$timestamp) {
230 return null;
231 }
232
233 // Use time() instead of current_time('timestamp') to get UTC timestamp
234 $current_time = time();
235 $time_diff = $timestamp - $current_time;
236
237 if ($time_diff <= 0) {
238 return __('Sending soon...', 'debug-log-viewer');
239 }
240
241 $days = floor($time_diff / 86400); // 86400 seconds in a day
242 $hours = floor(( $time_diff % 86400 ) / 3600);
243 $minutes = floor(( $time_diff % 3600 ) / 60);
244
245 if ($days > 0) {
246 if ($hours > 0) {
247 return sprintf(
248 /* translators: %d: number of days */
249 _n('%d day', '%d days', $days, 'debug-log-viewer') . ' ' .
250 /* translators: %d: number of hours */
251 _n('%d hour', '%d hours', $hours, 'debug-log-viewer'),
252 $days,
253 $hours
254 );
255 } else {
256 return sprintf(
257 /* translators: %d: number of days */
258 _n('%d day', '%d days', $days, 'debug-log-viewer'),
259 $days
260 );
261 }
262 } elseif ($hours > 0) {
263 return sprintf(
264 /* translators: %d: number of hours */
265 _n('%d hour', '%d hours', $hours, 'debug-log-viewer'),
266 $hours
267 );
268 } else {
269 return sprintf(
270 /* translators: %d: number of minutes */
271 _n('%d minute', '%d minutes', $minutes, 'debug-log-viewer'),
272 $minutes
273 );
274 }
275 }
276
277 public function getNextScheduledTimeForAjax() {
278 $timestamp = $this->getNextScheduledTime();
279
280 if (!$timestamp) {
281 return [
282 'success' => true,
283 'scheduled' => false,
284 'message' => __('Not scheduled', 'debug-log-viewer'),
285 ];
286 }
287
288 return [
289 'success' => true,
290 'scheduled' => true,
291 'timestamp' => $timestamp,
292 'formatted_time' => $this->getFormattedNextScheduledTime(),
293 'time_until' => $this->getTimeUntilNextEmail(),
294 ];
295 }
296 }
297