PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 2.6.1
Tutor LMS – eLearning and online course solution v2.6.1
3.9.14 3.9.13 3.9.12 3.9.11 trunk 1.0.0 1.0.0-alpha 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.2.0 1.2.1 1.2.11 1.2.12 1.2.13 1.2.20 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.7 1.7.8 1.7.9 1.8.0 1.8.1 1.8.10 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9.0 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.14 1.9.15 1.9.16 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1 2.0.10 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.1.1 2.1.10 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.3.0 2.4.0 2.5.0 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 3.0.0 3.0.1 3.0.2 3.1.0 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.7.0 3.7.1 3.7.2 3.7.3 3.7.4 3.8.0 3.8.1 3.8.2 3.8.3 3.9.0 3.9.1 3.9.10 3.9.2 3.9.3 3.9.4 3.9.5 3.9.6 3.9.7 3.9.8 3.9.9
tutor / helpers / QueryHelper.php
tutor / helpers Last commit date
QueryHelper.php 2 years ago SessionHelper.php 3 years ago ValidationHelper.php 2 years ago
QueryHelper.php
453 lines
1 <?php
2 /**
3 * Query helper class contains static helper methods to perform basic
4 * operations
5 *
6 * @package Tutor\Helper
7 * @since v2.0.7
8 */
9
10 namespace Tutor\Helpers;
11
12 /**
13 * Do the common db operations through helper
14 * methods
15 */
16 class QueryHelper {
17
18 /**
19 * Insert data in the table
20 *
21 * @param string $table table name.
22 * @param array $data | data to insert in the table.
23 *
24 * @return int, inserted id.
25 *
26 * @since v2.0.7
27 */
28 public static function insert( string $table, array $data ): int {
29 global $wpdb;
30 // Sanitize text field.
31 $data = array_map(
32 function( $value ) {
33 return sanitize_text_field( $value );
34 },
35 $data
36 );
37
38 $insert = $wpdb->insert(
39 $table,
40 $data
41 );
42 return $insert ? $wpdb->insert_id : 0;
43 }
44
45 /**
46 * Update data
47 *
48 * @param string $table table name.
49 * @param array $data | data to update in the table.
50 * @param array $where | condition array.
51 *
52 * @return bool, true on success false on failure
53 *
54 * @since v2.0.7
55 */
56 public static function update( string $table, array $data, array $where ): bool {
57 global $wpdb;
58 // Sanitize text field.
59 $data = array_map(
60 function( $value ) {
61 return sanitize_text_field( $value );
62 },
63 $data
64 );
65
66 $where = array_map(
67 function( $value ) {
68 return sanitize_text_field( $value );
69 },
70 $where
71 );
72
73 $update = $wpdb->update(
74 $table,
75 $data,
76 $where
77 );
78 return $update ? true : false;
79 }
80
81 /**
82 * Delete rows from table
83 *
84 * @param string $table table name.
85 * @param array $where key value pairs.Where key is the name of
86 * column & value is the value to match.
87 * For ex: [ 'id' => 1 ].
88 *
89 * @since v2.0.7
90 */
91 public static function delete( string $table, array $where ): bool {
92 global $wpdb;
93 $delete = $wpdb->delete(
94 $table,
95 $where
96 );
97 return $delete ? true : false;
98 }
99
100 /**
101 * Clean everything from table
102 *
103 * @since v2.0.7
104 *
105 * @param string $table table name.
106 *
107 * @return bool
108 */
109 public static function table_clean( string $table ): bool {
110 global $wpdb;
111 $delete = $wpdb->query(
112 $wpdb->prepare(
113 "DELETE FROM
114 {$table}
115 WHERE 1 = %d
116 ",
117 1
118 )
119 );
120 return $delete ? true : false;
121 }
122
123 /**
124 * Insert multiple rows without knowing key value
125 *
126 * @since v2.0.7
127 *
128 * @param string $table table name.
129 * @param array $request two dimensional array
130 * for ex: [ [id => 1], [id => 2] ].
131 *
132 * @return mixed wpdb response true or int on success,
133 * false on failure
134 */
135 public static function insert_multiple_rows( $table, $request ) {
136 global $wpdb;
137 $column_keys = '';
138 $column_values = '';
139 $sql = '';
140 $last_key = array_key_last( $request );
141 $first_key = array_key_first( $request );
142 foreach ( $request as $k => $value ) {
143 $keys = array_keys( $value );
144
145 // Prepare column keys & values.
146 foreach ( $keys as $v ) {
147 $column_keys .= sanitize_key( $v ) . ',';
148 $sanitize_value = sanitize_text_field( $value[ $v ] );
149 $column_values .= is_numeric( $sanitize_value ) ? $sanitize_value . ',' : "'$sanitize_value'" . ',';
150 }
151 // Trim trailing comma.
152 $column_keys = rtrim( $column_keys, ',' );
153 $column_values = rtrim( $column_values, ',' );
154 if ( $first_key === $k ) {
155 $sql .= "INSERT INTO {$table} ($column_keys) VALUES ($column_values)";
156 if ( count( $request ) > 1 ) {
157 $sql .= ',';
158 }
159 } elseif ( $last_key == $k ) {
160 $sql .= "($column_values)";
161 } else {
162 $sql .= "($column_values),";
163 }
164
165 // Reset keys & values to avoid duplication.
166 $column_keys = '';
167 $column_values = '';
168 }
169
170 $wpdb->query( $sql );
171
172 // If error occurred then throw new exception.
173 if ( $wpdb->last_error ) {
174 throw new \Exception( $wpdb->last_error );
175 }
176
177 return true;
178 }
179
180 /**
181 * Build where clause string
182 *
183 * @param array $where assoc array with field and value
184 * @return string
185 *
186 * @since 2.0.9
187 */
188 private function build_where_clause( array $where ) {
189 $arr = array();
190 foreach ( $where as $field => $value ) {
191 $value = is_numeric( $value ) ? ( $value + 0 ) : "'" . $value . "'";
192 $arr[] = "{$field}={$value}";
193 }
194
195 return implode( ' AND ', $arr );
196 }
197
198 /**
199 * Sanitize assoc array
200 *
201 * @param array $array an assoc array
202 * @return array
203 *
204 * @since 2.0.9
205 */
206 private function sanitize_assoc_array( array $array ) {
207 return array_map(
208 function( $value ) {
209 return sanitize_text_field( $value );
210 },
211 $array
212 );
213 }
214
215 /**
216 * Delete comment with associate meta data
217 *
218 * @param array $where associative array with field and value.
219 * Example: array( 'comment_type' => 'comment', 'comment_id' => 1 )
220 * @return bool
221 *
222 * @since 2.0.9
223 */
224 public static function delete_comment_with_meta( array $where ) {
225 if ( count( $where ) === 0 || ! tutor_utils()->is_assoc( $where ) ) {
226 return false;
227 }
228
229 $obj = new self();
230 $where = $obj->build_where_clause( $obj->sanitize_assoc_array( $where ) );
231
232 global $wpdb;
233 $ids = $wpdb->get_col( "SELECT comment_id FROM {$wpdb->comments} WHERE {$where}" );
234
235 if ( is_array( $ids ) && count( $ids ) ) {
236 $ids_str = "'" . implode( "','", $ids ) . "'";
237 // delete comment metas
238 $wpdb->query( "DELETE FROM {$wpdb->commentmeta} WHERE comment_id IN({$ids_str}) " );
239 // delete comment
240 $wpdb->query( "DELETE FROM {$wpdb->comments} WHERE {$where}" );
241
242 return true;
243 }
244
245 return false;
246 }
247
248 /**
249 * Delete post with associate meta data
250 *
251 * @param array $where associative array with field and value.
252 * Example: array( 'post_type' => 'post', 'id' => 1 )
253 * @return bool
254 *
255 * @since 2.0.9
256 */
257 public static function delete_post_with_meta( array $where ) {
258 if ( count( $where ) === 0 || ! tutor_utils()->is_assoc( $where ) ) {
259 return false;
260 }
261
262 $obj = new self();
263 $where = $obj->build_where_clause( $obj->sanitize_assoc_array( $where ) );
264
265 global $wpdb;
266 $ids = $wpdb->get_col( "SELECT id FROM {$wpdb->posts} WHERE {$where}" );
267
268 if ( is_array( $ids ) && count( $ids ) ) {
269 $ids_str = "'" . implode( "','", $ids ) . "'";
270 // delete post metas
271 $wpdb->query( "DELETE FROM {$wpdb->postmeta} WHERE post_id IN({$ids_str}) " );
272 // delete post
273 $wpdb->query( "DELETE FROM {$wpdb->posts} WHERE {$where}" );
274
275 return true;
276 }
277
278 return false;
279 }
280
281 /**
282 * Get a single row from any table with where clause
283 *
284 * @param string $table table name with prefix.
285 *
286 * @param array $where assoc_array. For ex: [col_name => value ].
287 * @param string $order_by order by column name.
288 * @param string $order DESC or ASC, default is DESC.
289 * @param string $output expected output type, default is object.
290 *
291 * @return mixed based on output param, default object
292 */
293 public static function get_row( string $table, array $where, string $order_by, string $order = 'DESC', string $output = 'OBJECT' ) {
294 global $wpdb;
295 $obj = new self();
296 $where_clause = $obj->build_where_clause( $where );
297 $query = $wpdb->prepare(
298 "SELECT *
299 FROM {$table}
300 WHERE {$where_clause}
301 ORDER BY {$order_by} {$order}
302 LIMIT %d
303 ",
304 1
305 );
306 return $wpdb->get_row(
307 $query,
308 $output
309 );
310 }
311
312 /**
313 * Get all row from any table with where clause
314 *
315 * @since 2.2.1
316 *
317 * @param string $table table name with prefix.
318 *
319 * @param array $where assoc_array. For ex: [col_name => value ].
320 * @param string $order_by order by column name.
321 * @param int $limit default is 1000.
322 * @param string $order DESC or ASC, default is DESC.
323 * @param string $output expected output type, default is object.
324 *
325 * @return mixed based on output param, default object
326 */
327 public static function get_all( string $table, array $where, string $order_by, $limit = 1000, string $order = 'DESC', string $output = 'OBJECT' ) {
328 global $wpdb;
329 $obj = new self();
330 $where_clause = $obj->build_where_clause( $where );
331 $limit = sanitize_text_field( $limit );
332 $query = $wpdb->prepare(
333 "SELECT *
334 FROM {$table}
335 WHERE {$where_clause}
336 ORDER BY {$order_by} {$order}
337 LIMIT %d
338 ",
339 $limit
340 );
341 return $wpdb->get_results(
342 $query,
343 $output
344 );
345 }
346
347
348 /**
349 * Update multiple rows by using where in
350 * clause
351 *
352 * @since v2.1.0
353 *
354 * @param string $table table name.
355 * @param array $data assoc_array data to update
356 * ex: [id => 2, name => 'john' ].
357 * @param string $where_in comma separated values, ex: 1,2,3.
358 * @param string $where_col default is ID but could be other.
359 *
360 * @return bool true on success, false on failure
361 */
362 public static function update_where_in( string $table, array $data, string $where_in, string $where_col = 'ID' ) {
363 global $wpdb;
364 if ( empty( $where_in ) || empty( $where_col ) ) {
365 return false;
366 }
367 $set_clause = self::prepare_set_clause( $data );
368 if ( '' === $set_clause ) {
369 return false;
370 }
371 // @codingStandardsIgnoreStart
372 $query = $wpdb->prepare(
373 "UPDATE {$table}
374 {$set_clause}
375 WHERE $where_col IN ( $where_in )
376 AND 1 = %d
377 ",
378 1
379 );
380 return $wpdb->query( $query ) ? true : false;
381 }
382
383 /**
384 * Prepare MySQL SET clause for update query
385 *
386 * @since v2.1.0
387 *
388 * @param array $data single dimension assoc_array.
389 *
390 * @return string
391 */
392 public static function prepare_set_clause( array $data ) {
393 $set = '';
394 foreach ( $data as $key => $value ) {
395 if ( $key === array_key_first ( $data ) ) {
396 $set .= "SET ";
397 }
398 // Multi dimension not allowed.
399 if ( is_array( $value ) ) {
400 continue;
401 }
402 $value = sanitize_text_field( $value );
403 $set .= is_numeric( $value ) ? "$key = $value" : "$key = '" . $value ."'";
404 $set .= ",";
405 }
406 return rtrim( $set, ',' );
407 }
408
409 /**
410 * Make sanitized SQL IN clause value from an array
411 *
412 * @param array $arr a sequentital array.
413 * @return string
414 * @since 2.1.1
415 */
416 public static function prepare_in_clause( array $arr ) {
417 $escaped = array_map(
418 function( $value ) {
419 global $wpdb;
420 $escaped_value = null;
421 if ( is_int( $value ) ) {
422 $escaped_value = $wpdb->prepare( '%d', $value );
423 } else if( is_float( $value ) ) {
424 list( $whole, $decimal ) = explode( '.', $value );
425 $expression = '%.'. strlen( $decimal ) . 'f';
426 $escaped_value = $wpdb->prepare( $expression, $value );
427 } else {
428 $escaped_value = $wpdb->prepare( '%s', $value );
429 }
430 return $escaped_value;
431 },
432 $arr
433 );
434
435 return implode( ',', $escaped );
436 }
437
438 /**
439 * Check table exist in database.
440 *
441 * @since 2.5.0
442 *
443 * @param string $table table name.
444 *
445 * @return bool
446 */
447 public static function table_exists( $table ) {
448 global $wpdb;
449 $sql = "SHOW TABLES LIKE '{$table}'";
450 return $wpdb->get_var( $sql ) === $table;
451 }
452 }
453