PluginProbe ʕ •ᴥ•ʔ
WP Mail SMTP by WPForms – The Most Popular SMTP and Email Log Plugin / 4.9.0
WP Mail SMTP by WPForms – The Most Popular SMTP and Email Log Plugin v4.9.0
4.9.0 0.9.6 1.0.0 1.0.1 1.0.2 1.1.0 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.3.0 1.3.1 1.3.2 1.3.3 1.4.0 1.4.1 1.4.2 1.5.0 1.5.1 1.5.2 1.6.0 1.6.2 1.7.0 1.7.1 1.8.0 1.8.1 1.9.0 2.0.0 2.0.1 2.1.1 2.2.1 2.3.1 2.4.0 2.5.0 2.5.1 2.6.0 2.7.0 2.8.0 2.9.0 3.0.1 3.0.2 3.0.3 3.1.0 3.10.0 3.11.0 3.11.1 3.2.0 3.2.1 3.3.0 3.4.0 3.5.0 3.5.1 3.5.2 3.6.1 3.7.0 3.8.0 3.8.2 3.9.0 4.0.1 4.1.0 4.1.1 4.2.0 4.3.0 4.4.0 4.5.0 4.6.0 4.7.0 4.7.1 4.8.0 trunk 0.10.0 0.10.1 0.11.1 0.11.2 0.3.1 0.3.2 0.4 0.4.1 0.4.2 0.5.0 0.5.1 0.5.2 0.6 0.7 0.8 0.8.2 0.8.3 0.8.4 0.8.5 0.8.6 0.8.7 0.9.0 0.9.1 0.9.2 0.9.3 0.9.4 0.9.5
wp-mail-smtp / src / Admin / DebugEvents / EventsCollection.php
wp-mail-smtp / src / Admin / DebugEvents Last commit date
DebugEvents.php 6 days ago Event.php 6 days ago EventsCollection.php 6 days ago Migration.php 6 days ago Table.php 6 days ago
EventsCollection.php
422 lines
1 <?php
2
3 namespace WPMailSMTP\Admin\DebugEvents;
4
5 use WPMailSMTP\WP;
6
7 /**
8 * Debug Events Collection.
9 *
10 * @since 3.0.0
11 */
12 class EventsCollection implements \Countable, \Iterator {
13
14 /**
15 * Default number of log entries per page.
16 *
17 * @since 3.0.0
18 *
19 * @var int
20 */
21 const PER_PAGE = 10;
22
23 /**
24 * Number of log entries per page.
25 *
26 * @since 3.0.0
27 *
28 * @var int
29 */
30 public static $per_page;
31
32 /**
33 * List of all Event instances.
34 *
35 * @since 3.0.0
36 *
37 * @var array
38 */
39 private $list = [];
40
41 /**
42 * List of current collection instance parameters.
43 *
44 * @since 3.0.0
45 *
46 * @var array
47 */
48 private $params;
49
50 /**
51 * Used for \Iterator when iterating through Queue in loops.
52 *
53 * @since 3.0.0
54 *
55 * @var int
56 */
57 private $iterator_position = 0;
58
59 /**
60 * Collection constructor.
61 * $events = new EventsCollection( [ 'type' => 0 ] );
62 *
63 * @since 3.0.0
64 *
65 * @param array $params The events collection parameters.
66 */
67 public function __construct( array $params = [] ) {
68
69 $this->set_per_page();
70 $this->params = $this->process_params( $params );
71 }
72
73 /**
74 * Set the per page attribute to the screen options value.
75 *
76 * @since 3.0.0
77 */
78 protected function set_per_page() {
79
80 $per_page = (int) get_user_meta(
81 get_current_user_id(),
82 'wp_mail_smtp_debug_events_per_page',
83 true
84 );
85
86 if ( $per_page < 1 ) {
87 $per_page = self::PER_PAGE;
88 }
89
90 self::$per_page = $per_page;
91 }
92
93 /**
94 * Verify, sanitize, and populate with default values
95 * all the passed parameters, which participate in DB queries.
96 *
97 * @since 3.0.0
98 *
99 * @param array $params The events collection parameters.
100 *
101 * @return array
102 */
103 public function process_params( $params ) { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.MaxExceeded
104
105 $params = (array) $params;
106 $processed = [];
107
108 /*
109 * WHERE.
110 */
111 // Single ID.
112 if ( ! empty( $params['id'] ) ) {
113 $processed['id'] = (int) $params['id'];
114 }
115
116 // Multiple IDs.
117 if (
118 ! empty( $params['ids'] ) &&
119 is_array( $params['ids'] )
120 ) {
121 $processed['ids'] = array_unique( array_filter( array_map( 'intval', array_values( $params['ids'] ) ) ) );
122 }
123
124 // Type.
125 if (
126 isset( $params['type'] ) &&
127 in_array( $params['type'], array_keys( Event::get_types() ), true )
128 ) {
129 $processed['type'] = (int) $params['type'];
130 }
131
132 // Search.
133 if ( ! empty( $params['search'] ) ) {
134 $processed['search'] = sanitize_text_field( $params['search'] );
135 }
136
137 /*
138 * LIMIT.
139 */
140 if ( ! empty( $params['offset'] ) ) {
141 $processed['offset'] = (int) $params['offset'];
142 }
143
144 if ( ! empty( $params['per_page'] ) ) {
145 $processed['per_page'] = (int) $params['per_page'];
146 }
147
148 /*
149 * Sent date.
150 */
151 if ( ! empty( $params['date'] ) ) {
152 if ( is_string( $params['date'] ) ) {
153 $params['date'] = array_fill( 0, 2, $params['date'] );
154 } elseif ( is_array( $params['date'] ) && count( $params['date'] ) === 1 ) {
155 $params['date'] = array_fill( 0, 2, $params['date'][0] );
156 }
157
158 // We pass array and treat it as a range from:to.
159 if ( is_array( $params['date'] ) && count( $params['date'] ) === 2 ) {
160 $date_start = WP::get_day_period_date( 'start_of_day', strtotime( $params['date'][0] ), 'Y-m-d H:i:s', true );
161 $date_end = WP::get_day_period_date( 'end_of_day', strtotime( $params['date'][1] ), 'Y-m-d H:i:s', true );
162
163 if ( ! empty( $date_start ) && ! empty( $date_end ) ) {
164 $processed['date'] = [ $date_start, $date_end ];
165 }
166 }
167 }
168
169 // Merge missing values with defaults.
170 return wp_parse_args(
171 $processed,
172 $this->get_default_params()
173 );
174 }
175
176 /**
177 * Get the list of default params for a usual query.
178 *
179 * @since 3.0.0
180 *
181 * @return array
182 */
183 protected function get_default_params() {
184
185 return [
186 'offset' => 0,
187 'per_page' => self::$per_page,
188 'order' => 'DESC',
189 'orderby' => 'id',
190 'search' => '',
191 ];
192 }
193
194 /**
195 * Get the SQL-ready string of WHERE part for a query.
196 *
197 * @since 3.0.0
198 *
199 * @return string
200 */
201 private function build_where() { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh
202
203 global $wpdb;
204
205 $where = [ '1=1' ];
206
207 // Shortcut single ID or multiple IDs.
208 if ( ! empty( $this->params['id'] ) || ! empty( $this->params['ids'] ) ) {
209 if ( ! empty( $this->params['id'] ) ) {
210 $where[] = $wpdb->prepare( 'id = %d', $this->params['id'] );
211 } elseif ( ! empty( $this->params['ids'] ) ) {
212 $where[] = 'id IN (' . implode( ',', $this->params['ids'] ) . ')';
213 }
214
215 // When some ID(s) defined - we should ignore all other possible filtering options.
216 return implode( ' AND ', $where );
217 }
218
219 // Type.
220 if ( isset( $this->params['type'] ) ) {
221 $where[] = $wpdb->prepare( 'event_type = %d', $this->params['type'] );
222 }
223
224 // Search.
225 if ( ! empty( $this->params['search'] ) ) {
226 $where[] = '(' .
227 $wpdb->prepare(
228 'content LIKE %s',
229 '%' . $wpdb->esc_like( $this->params['search'] ) . '%'
230 )
231 . ' OR ' .
232 $wpdb->prepare(
233 'initiator LIKE %s',
234 '%' . $wpdb->esc_like( $this->params['search'] ) . '%'
235 )
236 . ')';
237 }
238
239 // Sent date.
240 if (
241 ! empty( $this->params['date'] ) &&
242 is_array( $this->params['date'] ) &&
243 count( $this->params['date'] ) === 2
244 ) {
245 $where[] = $wpdb->prepare(
246 '( created_at >= %s AND created_at <= %s )',
247 $this->params['date'][0],
248 $this->params['date'][1]
249 );
250 }
251
252 return implode( ' AND ', $where );
253 }
254
255 /**
256 * Get the SQL-ready string of ORDER part for a query.
257 * Order is always in the params, as per our defaults.
258 *
259 * @since 3.0.0
260 *
261 * @return string
262 */
263 private function build_order() {
264
265 return 'ORDER BY ' . $this->params['orderby'] . ' ' . $this->params['order'];
266 }
267
268 /**
269 * Get the SQL-ready string of LIMIT part for a query.
270 * Limit is always in the params, as per our defaults.
271 *
272 * @since 3.0.0
273 *
274 * @return string
275 */
276 private function build_limit() {
277
278 return 'LIMIT ' . $this->params['offset'] . ', ' . $this->params['per_page'];
279 }
280
281 /**
282 * Count the number of DB records according to filters.
283 * Do not retrieve actual records.
284 *
285 * @since 3.0.0
286 *
287 * @return int
288 */
289 public function get_count() {
290
291 $table = DebugEvents::get_table_name();
292
293 $where = $this->build_where();
294
295 // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
296 return (int) WP::wpdb()->get_var(
297 "SELECT COUNT(id) FROM $table
298 WHERE {$where}"
299 );
300 // phpcs:enable
301 }
302
303 /**
304 * Get the list of DB records.
305 * You can either use array returned there OR iterate over the whole object,
306 * as it implements Iterator interface.
307 *
308 * @since 3.0.0
309 *
310 * @return EventsCollection
311 */
312 public function get() {
313
314 $table = DebugEvents::get_table_name();
315
316 $where = $this->build_where();
317 $limit = $this->build_limit();
318 $order = $this->build_order();
319
320 // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
321 $data = WP::wpdb()->get_results(
322 "SELECT * FROM $table
323 WHERE {$where}
324 {$order}
325 {$limit}"
326 );
327 // phpcs:enable
328
329 if ( ! empty( $data ) ) {
330 // As we got raw data we need to convert each row to Event.
331 foreach ( $data as $row ) {
332 $this->list[] = new Event( $row );
333 }
334 }
335
336 return $this;
337 }
338
339 /*********************************************************************************************
340 * ****************************** \Counter interface method. *********************************
341 *********************************************************************************************/
342
343 /**
344 * Count number of Record in a Queue.
345 *
346 * @since 3.0.0
347 *
348 * @return int
349 */
350 #[\ReturnTypeWillChange]
351 public function count() {
352
353 return count( $this->list );
354 }
355
356 /*********************************************************************************************
357 * ****************************** \Iterator interface methods. *******************************
358 *********************************************************************************************/
359
360 /**
361 * Rewind the Iterator to the first element.
362 *
363 * @since 3.0.0
364 */
365 #[\ReturnTypeWillChange]
366 public function rewind() {
367
368 $this->iterator_position = 0;
369 }
370
371 /**
372 * Return the current element.
373 *
374 * @since 3.0.0
375 *
376 * @return Event|null Return null when no items in collection.
377 */
378 #[\ReturnTypeWillChange]
379 public function current() {
380
381 return $this->valid() ? $this->list[ $this->iterator_position ] : null;
382 }
383
384 /**
385 * Return the key of the current element.
386 *
387 * @since 3.0.0
388 *
389 * @return int
390 */
391 #[\ReturnTypeWillChange]
392 public function key() {
393
394 return $this->iterator_position;
395 }
396
397 /**
398 * Move forward to next element.
399 *
400 * @since 3.0.0
401 */
402 #[\ReturnTypeWillChange]
403 public function next() {
404
405 ++ $this->iterator_position;
406 }
407
408 /**
409 * Checks if current position is valid.
410 *
411 * @since 3.0.0
412 *
413 * @return bool
414 */
415 #[\ReturnTypeWillChange]
416 public function valid() {
417
418 return isset( $this->list[ $this->iterator_position ] );
419 }
420
421 }
422