PluginProbe
Stream – Activity Log & Audit Trail / 3.9.2
Stream – Activity Log & Audit Trail v3.9.2
4.4.0 4.3.0 4.2.2 4.2.1 trunk 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.1 3.1.1 3.10.0 3.2.0 3.2.1 3.2.2 3.2.3 All 50 releases
← All changes | classes/class-query.php +74 -143 3.0.13.9.2 View file →
@@ -1,14 +1,18 @@
1 1 <?php
2 +/**
3 + * Queries the database for stream records.
4 + *
5 + * @package WP_Stream
6 + */
7 +
2 8 namespace WP_Stream;
3 9
10 +/**
11 + * Class - Query
12 + */
4 13 class Query {
5 14 /**
6 - * @var DB
7 - */
8 - public $db;
9 -
10 - /**
11 15 * Hold the number of records found
12 16 *
13 17 * @var int
14 18 */
@@ -14,20 +18,11 @@
14 18 */
15 19 public $found_records = 0;
16 20
17 21 /**
18 - * Class constructor.
19 - *
20 - * @param DB $db The parent database class.
21 - */
22 - public function __construct( $db ) {
23 - $this->db = $db;
24 - }
25 -
26 - /**
27 22 * Query records
28 23 *
29 - * @param array Query args
24 + * @param array $args Arguments to filter the records by.
30 25 *
31 26 * @return array Stream Records
32 27 */
33 28 public function query( $args ) {
@@ -32,72 +27,8 @@
32 27 */
33 28 public function query( $args ) {
34 29 global $wpdb;
35 30
36 - $defaults = array(
37 - // Search param
38 - 'search' => null,
39 - 'search_field' => 'summary',
40 - 'record_after' => null, // Deprecated, use date_after instead
41 - // Date-based filters
42 - 'date' => null, // Ex: 2015-07-01
43 - 'date_from' => null, // Ex: 2015-07-01
44 - 'date_to' => null, // Ex: 2015-07-01
45 - 'date_after' => null, // Ex: 2015-07-01T15:19:21+00:00
46 - 'date_before' => null, // Ex: 2015-07-01T15:19:21+00:00
47 - // Record ID filters
48 - 'record' => null,
49 - 'record__in' => array(),
50 - 'record__not_in' => array(),
51 - // Pagination params
52 - 'records_per_page' => get_option( 'posts_per_page', 20 ),
53 - 'paged' => 1,
54 - // Order
55 - 'order' => 'desc',
56 - 'orderby' => 'date',
57 - // Fields selection
58 - 'fields' => array(),
59 - );
60 -
61 - // Additional property fields
62 - $properties = array(
63 - 'user_id' => null,
64 - 'user_role' => null,
65 - 'ip' => null,
66 - 'object_id' => null,
67 - 'site_id' => null,
68 - 'blog_id' => null,
69 - 'connector' => null,
70 - 'context' => null,
71 - 'action' => null,
72 - );
73 -
74 - /**
75 - * Filter allows additional query properties to be added
76 - *
77 - * @return array Array of query properties
78 - */
79 - $properties = apply_filters( 'wp_stream_query_properties', $properties );
80 -
81 - // Add property fields to defaults, including their __in/__not_in variations
82 - foreach ( $properties as $property => $default ) {
83 - if ( ! isset( $defaults[ $property ] ) ) {
84 - $defaults[ $property ] = $default;
85 - }
86 -
87 - $defaults[ "{$property}__in" ] = array();
88 - $defaults[ "{$property}__not_in" ] = array();
89 - }
90 -
91 - $args = wp_parse_args( $args, $defaults );
92 -
93 - /**
94 - * Filter allows additional arguments to query $args
95 - *
96 - * @return array Array of query arguments
97 - */
98 - $args = apply_filters( 'wp_stream_query_args', $args );
99 -
100 31 $join = '';
101 32 $where = '';
102 33
103 34 /**
@@ -123,10 +54,15 @@
123 54 $where .= $wpdb->prepare( " AND $wpdb->stream.user_role = %s", $args['user_role'] );
124 55 }
125 56
126 57 if ( ! empty( $args['search'] ) ) {
127 - $field = ! empty( $args['search_field'] ) ? $args['search_field'] : 'summary';
128 - $where .= $wpdb->prepare( " AND $wpdb->stream.{$field} LIKE %s", "%{$args['search']}%" );
58 + $field = ! empty( $args['search_field'] ) ? $args['search_field'] : 'summary';
59 +
60 + // Sanitize field.
61 + $allowed_fields = array( 'ID', 'site_id', 'blog_id', 'object_id', 'user_id', 'user_role', 'created', 'summary', 'connector', 'context', 'action', 'ip' );
62 + if ( in_array( $field, $allowed_fields, true ) ) {
63 + $where .= $wpdb->prepare( " AND $wpdb->stream.{$field} LIKE %s", "%{$args['search']}%" ); // @codingStandardsIgnoreLine can't prepare column name
64 + }
129 65 }
130 66
131 67 if ( ! empty( $args['connector'] ) ) {
132 68 $where .= $wpdb->prepare( " AND $wpdb->stream.connector = %s", $args['connector'] );
@@ -146,33 +82,33 @@
146 82
147 83 /**
148 84 * PARSE DATE PARAM FAMILY
149 85 */
86 + if ( ! empty( $args['date'] ) ) {
87 + $args['date_from'] = $args['date'];
88 + $args['date_to'] = $args['date'];
89 + }
90 +
150 91 if ( ! empty( $args['date_from'] ) ) {
151 - $date = get_gmt_from_date( date( 'Y-m-d H:i:s', strtotime( $args['date_from'] . ' 00:00:00' ) ) );
92 + $date = get_gmt_from_date( gmdate( 'Y-m-d H:i:s', strtotime( $args['date_from'] . ' 00:00:00' ) ) );
152 93 $where .= $wpdb->prepare( " AND DATE($wpdb->stream.created) >= %s", $date );
153 94 }
154 95
155 96 if ( ! empty( $args['date_to'] ) ) {
156 - $date = get_gmt_from_date( date( 'Y-m-d H:i:s', strtotime( $args['date_to'] . ' 23:59:59' ) ) );
97 + $date = get_gmt_from_date( gmdate( 'Y-m-d H:i:s', strtotime( $args['date_to'] . ' 23:59:59' ) ) );
157 98 $where .= $wpdb->prepare( " AND DATE($wpdb->stream.created) <= %s", $date );
158 99 }
159 100
160 101 if ( ! empty( $args['date_after'] ) ) {
161 - $date = get_gmt_from_date( date( 'Y-m-d H:i:s', strtotime( $args['date_after'] ) ) );
102 + $date = get_gmt_from_date( gmdate( 'Y-m-d H:i:s', strtotime( $args['date_after'] ) ) );
162 103 $where .= $wpdb->prepare( " AND DATE($wpdb->stream.created) > %s", $date );
163 104 }
164 105
165 106 if ( ! empty( $args['date_before'] ) ) {
166 - $date = get_gmt_from_date( date( 'Y-m-d H:i:s', strtotime( $args['date_before'] ) ) );
107 + $date = get_gmt_from_date( gmdate( 'Y-m-d H:i:s', strtotime( $args['date_before'] ) ) );
167 108 $where .= $wpdb->prepare( " AND DATE($wpdb->stream.created) < %s", $date );
168 109 }
169 110
170 - if ( ! empty( $args['date'] ) ) {
171 - $args['date_from'] = date( 'Y-m-d', strtotime( $args['date'] ) ) . ' 00:00:00';
172 - $args['date_to'] = date( 'Y-m-d', strtotime( $args['date'] ) ) . ' 23:59:59';
173 - }
174 -
175 111 /**
176 112 * PARSE __IN PARAM FAMILY
177 113 */
178 114 $ins = array();
@@ -194,9 +130,9 @@
194 130 $type = is_numeric( array_shift( $value ) ) ? '%d' : '%s';
195 131
196 132 if ( ! empty( $value ) ) {
197 133 $format = '(' . join( ',', array_fill( 0, count( $value ), $type ) ) . ')';
198 - $where .= $wpdb->prepare( " AND $wpdb->stream.%s IN {$format}", $field, $value );
134 + $where .= $wpdb->prepare( " AND $wpdb->stream.%s IN {$format}", $field, $value ); // @codingStandardsIgnoreLine prepare okay
199 135 }
200 136 }
201 137 }
202 138
@@ -222,9 +158,9 @@
222 158 $type = is_numeric( array_shift( $value ) ) ? '%d' : '%s';
223 159
224 160 if ( ! empty( $value ) ) {
225 161 $format = '(' . join( ',', array_fill( 0, count( $value ), $type ) ) . ')';
226 - $where .= $wpdb->prepare( " AND $wpdb->stream.%s NOT IN {$format}", $field, $value );
162 + $where .= $wpdb->prepare( " AND $wpdb->stream.%s NOT IN {$format}", $field, $value ); // @codingStandardsIgnoreLine prepare okay
227 163 }
228 164 }
229 165 }
230 166
@@ -242,24 +178,29 @@
242 178
243 179 /**
244 180 * PARSE ORDER PARAMS
245 181 */
246 - $order = esc_sql( $args['order'] );
247 - $orderby = esc_sql( $args['orderby'] );
248 182 $orderable = array( 'ID', 'site_id', 'blog_id', 'object_id', 'user_id', 'user_role', 'summary', 'created', 'connector', 'context', 'action' );
249 183
250 - if ( in_array( $orderby, $orderable ) ) {
251 - $orderby = sprintf( '%s.%s', $wpdb->stream, $orderby );
252 - } elseif ( 'meta_value_num' === $orderby && ! empty( $args['meta_key'] ) ) {
184 + // Default to sorting by record ID.
185 + $orderby = "$wpdb->stream.ID";
186 +
187 + if ( in_array( $args['orderby'], $orderable, true ) ) {
188 + $orderby = sprintf( '%s.%s', $wpdb->stream, $args['orderby'] );
189 + } elseif ( 'meta_value_num' === $args['orderby'] && ! empty( $args['meta_key'] ) ) {
253 190 $orderby = "CAST($wpdb->streammeta.meta_value AS SIGNED)";
254 - } elseif ( 'meta_value' === $orderby && ! empty( $args['meta_key'] ) ) {
191 + } elseif ( 'meta_value' === $args['orderby'] && ! empty( $args['meta_key'] ) ) {
255 192 $orderby = "$wpdb->streammeta.meta_value";
256 - } else {
257 - $orderby = "$wpdb->stream.ID";
258 193 }
259 194
260 - $orderby = "ORDER BY {$orderby} {$order}";
195 + // Show the recent records first by default.
196 + $order = 'DESC';
197 + if ( 'ASC' === strtoupper( $args['order'] ) ) {
198 + $order = 'ASC';
199 + }
261 200
201 + $orderby = sprintf( 'ORDER BY %s %s', $orderby, $order );
202 +
262 203 /**
263 204 * PARSE FIELDS PARAMETER
264 205 */
265 206 $fields = (array) $args['fields'];
@@ -266,9 +207,9 @@
266 207 $selects = array();
267 208
268 209 if ( ! empty( $fields ) ) {
269 210 foreach ( $fields as $field ) {
270 - // We'll query the meta table later
211 + // We'll query the meta table later.
271 212 if ( 'meta' === $field ) {
272 213 continue;
273 214 }
274 215
@@ -280,11 +221,21 @@
280 221
281 222 $select = implode( ', ', $selects );
282 223
283 224 /**
225 + * Filters query WHERE statement as an alternative to filtering
226 + * the $query using the hook below.
227 + *
228 + * @param string $where WHERE statement.
229 + *
230 + * @return string
231 + */
232 + $where = apply_filters( 'wp_stream_db_query_where', $where );
233 +
234 + /**
284 235 * BUILD THE FINAL QUERY
285 236 */
286 - $query = "SELECT SQL_CALC_FOUND_ROWS {$select}
237 + $query = "SELECT {$select}
287 238 FROM $wpdb->stream
288 239 {$join}
289 240 WHERE 1=1 {$where}
290 241 {$orderby}
@@ -299,51 +250,31 @@
299 250 * @return string
300 251 */
301 252 $query = apply_filters( 'wp_stream_db_query', $query, $args );
302 253
254 + // Build result count query.
255 + $count_query = "SELECT COUNT(*) as found
256 + FROM $wpdb->stream
257 + {$join}
258 + WHERE 1=1 {$where}";
259 +
303 260 /**
261 + * Filter allows the result count query to be modified before execution.
262 + *
263 + * @param string $query
264 + * @param array $args
265 + *
266 + * @return string
267 + */
268 + $count_query = apply_filters( 'wp_stream_db_count_query', $count_query, $args );
269 +
270 + /**
304 271 * QUERY THE DATABASE FOR RESULTS
305 272 */
306 - $results = $wpdb->get_results( $query );
307 -
308 - // Hold the number of records found
309 - $this->found_records = absint( $wpdb->get_var( 'SELECT FOUND_ROWS()' ) );
310 -
311 - // Add meta to the records, when applicable
312 - if ( empty( $fields ) || in_array( 'meta', $fields ) ) {
313 - $results = $this->add_record_meta( $results );
314 - }
315 -
316 - return (array) $results;
317 - }
318 -
319 - /**
320 - * Add meta to a set of records
321 - *
322 - * @param array $records
323 - *
324 - * @return array
325 - */
326 - public function add_record_meta( $records ) {
327 - global $wpdb;
328 -
329 - $record_ids = array_map( 'absint', wp_list_pluck( $records, 'ID' ) );
330 -
331 - if ( empty( $record_ids ) ) {
332 - return (array) $records;
333 - }
334 -
335 - $sql_meta = sprintf(
336 - "SELECT * FROM $wpdb->streammeta WHERE record_id IN ( %s )",
337 - implode( ',', $record_ids )
273 + $result = array(
274 + 'items' => $wpdb->get_results( $query ), // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
275 + 'count' => absint( $wpdb->get_var( $count_query ) ), // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
338 276 );
339 277
340 - $meta = $wpdb->get_results( $sql_meta );
341 - $ids_f = array_flip( $record_ids );
342 -
343 - foreach ( $meta as $meta_record ) {
344 - $records[ $ids_f[ $meta_record->record_id ] ]->meta[ $meta_record->meta_key ] = maybe_unserialize( $meta_record->meta_value );
345 - }
346 -
347 - return (array) $records;
278 + return $result;
348 279 }
349 280 }