PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.1.6.9
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.1.6.9
4.4.8 4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 4.1.7.3.1 4.1.7.3.2 4.2.0 All 139 releases
learnpress / inc / databases / class-lp-db.php

class-lp-db.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.1.6.9, at inc/databases/class-lp-db.php

702 lines 16.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Class LP_Database
4 *
5 * @author tungnx
6 * @since 3.2.7.5
7 * @version 2.0.1
8 */
9 defined( 'ABSPATH' ) || exit();
10
11 //require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
12
13 class LP_Database {
14 private static $_instance;
15 public $wpdb;
16 public $tb_lp_user_items, $tb_lp_user_itemmeta;
17 public $tb_posts, $tb_postmeta, $tb_options;
18 public $tb_terms, $tb_term_relationships;
19 public $tb_lp_order_items, $tb_lp_order_itemmeta;
20 public $tb_lp_sections, $tb_lp_section_items;
21 public $tb_lp_quiz_questions;
22 public $tb_lp_user_item_results;
23 public $tb_lp_question_answers;
24 public $tb_lp_question_answermeta;
25 public $tb_lp_upgrade_db;
26 public $tb_lp_sessions;
27 private $collate = '';
28 public $max_index_length = '191';
29
30 protected function __construct() {
31 /**
32 * @global wpdb
33 */
34 global $wpdb;
35 $prefix = $wpdb->prefix;
36
37 $this->wpdb = $wpdb;
38 $this->tb_users = $wpdb->users;
39 $this->tb_posts = $wpdb->posts;
40 $this->tb_postmeta = $wpdb->postmeta;
41 $this->tb_options = $wpdb->options;
42 $this->tb_terms = $wpdb->terms;
43 $this->tb_term_relationships = $wpdb->term_relationships;
44 $this->tb_lp_user_items = $prefix . 'learnpress_user_items';
45 $this->tb_lp_user_itemmeta = $prefix . 'learnpress_user_itemmeta';
46 $this->tb_lp_order_items = $prefix . 'learnpress_order_items';
47 $this->tb_lp_order_itemmeta = $prefix . 'learnpress_order_itemmeta';
48 $this->tb_lp_section_items = $prefix . 'learnpress_section_items';
49 $this->tb_lp_sections = $prefix . 'learnpress_sections';
50 $this->tb_lp_quiz_questions = $prefix . 'learnpress_quiz_questions';
51 $this->tb_lp_user_item_results = $prefix . 'learnpress_user_item_results';
52 $this->tb_lp_question_answers = $prefix . 'learnpress_question_answers';
53 $this->tb_lp_question_answermeta = $prefix . 'learnpress_question_answermeta';
54 $this->tb_lp_upgrade_db = $prefix . 'learnpress_upgrade_db';
55 $this->tb_lp_sessions = $prefix . 'learnpress_sessions';
56 $this->wpdb->hide_errors();
57 $this->set_collate();
58 }
59
60 /**
61 * Get Instance
62 *
63 * @return LP_Database
64 */
65 public static function getInstance() {
66 if ( is_null( self::$_instance ) ) {
67 self::$_instance = new self();
68 }
69
70 return self::$_instance;
71 }
72
73 public function set_collate() {
74 $collate = '';
75
76 if ( $this->wpdb->has_cap( 'collation' ) ) {
77 if ( ! empty( $this->wpdb->charset ) ) {
78 $collate .= 'DEFAULT CHARACTER SET ' . $this->wpdb->charset;
79 }
80
81 if ( ! empty( $this->wpdb->collate ) ) {
82 $collate .= ' COLLATE ' . $this->wpdb->collate;
83 }
84 }
85
86 $this->collate = $collate;
87 }
88
89 public function get_collate(): string {
90 return $this->collate;
91 }
92
93 /**
94 * Get total Item by post type and user id
95 *
96 * @param LP_Post_Type_Filter $filter
97 *
98 * @return int
99 * @since 3.2.8
100 */
101 public function get_count_post_of_user( LP_Post_Type_Filter $filter ): int {
102 $query_append = '';
103
104 $cache_key = _count_posts_cache_key( $filter->post_type );
105
106 // Get cache
107 $counts = wp_cache_get( $cache_key );
108 if ( false !== $counts ) {
109 return $counts;
110 }
111
112 if ( ! empty( $filter->post_status ) ) {
113 $query_append .= $this->wpdb->prepare( ' AND post_status = %s', $filter->post_status );
114 }
115
116 $query = $this->wpdb->prepare(
117 "SELECT Count(ID) FROM $this->tb_posts
118 WHERE post_type = %s
119 AND post_author = %d
120 {$query_append}",
121 $filter->post_type,
122 $filter->post_author
123 );
124
125 $query = apply_filters( 'learnpress/query/get_total_post_of_user', $query );
126
127 $counts = (int) $this->wpdb->get_var( $query );
128
129 // Set cache
130 wp_cache_set( $cache_key, $counts );
131
132 return $counts;
133 }
134
135 /**
136 * Get post by post_type and slug
137 *
138 * @param string $post_type .
139 * @param string $slug .
140 *
141 * @return string
142 */
143 public function getPostAuthorByTypeAndSlug( $post_type = '', $slug = '' ) {
144 $query = $this->wpdb->prepare(
145 "
146 SELECT post_author FROM $this->tb_posts
147 WHERE post_type = %s
148 AND post_name = %s",
149 $post_type,
150 $slug
151 );
152
153 return $this->wpdb->get_var( $query );
154 }
155
156 /**
157 * Check table exists.
158 *
159 * @param string $name_table
160 *
161 * @return bool|int
162 */
163 public function check_table_exists( string $name_table ) {
164 return $this->wpdb->query( $this->wpdb->prepare( "SHOW TABLES LIKE '%s'", $name_table ) );
165 }
166
167 /**
168 * Clone table
169 *
170 * @param string $name_table .
171 *
172 * @throws Exception
173 */
174 public function clone_table( string $name_table ):bool {
175 if ( ! current_user_can( ADMIN_ROLE ) ) {
176 throw new Exception( 'You don\'t have permission' );
177 }
178
179 $table_bk = $name_table . '_bk';
180
181 // Drop table bk if exists.
182 $this->drop_table( $table_bk );
183
184 // Clone table
185 $this->wpdb->query( "CREATE TABLE {$table_bk} LIKE {$name_table}" );
186 $this->wpdb->query( "INSERT INTO {$table_bk} SELECT * FROM {$name_table}" );
187
188 /*dbDelta(
189 "CREATE TABLE $table_bk LIKE $name_table;
190 INSERT INTO $table_bk SELECT * FROM $name_table;"
191 );*/
192
193 $this->check_execute_has_error();
194
195 return true;
196 }
197
198 /**
199 * Check column table
200 *
201 * @param string $name_table .
202 * @param string $name_col .
203 *
204 * @return bool|int
205 */
206 public function check_col_table( string $name_table = '', string $name_col = '' ) {
207 $query = $this->wpdb->prepare( "SHOW COLUMNS FROM $name_table LIKE '%s'", $name_col );
208
209 return $this->wpdb->query( $query );
210 }
211
212 /**
213 * Drop Column of Table
214 *
215 * @param string $name_table .
216 * @param string $name_col .
217 *
218 * @return bool|int
219 * @throws Exception
220 */
221 public function drop_col_table( string $name_table = '', string $name_col = '' ) {
222 if ( ! current_user_can( 'administrator' ) ) {
223 return false;
224 }
225
226 $check_table = $this->check_col_table( $this->tb_lp_user_items, $name_col );
227
228 if ( $check_table ) {
229 $execute = $this->wpdb->query( "ALTER TABLE $name_table DROP COLUMN $name_col" );
230
231 $this->check_execute_has_error();
232
233 return $execute;
234 }
235
236 return true;
237 }
238
239 /**
240 * Add Column of Table
241 *
242 * @param string $name_table .
243 * @param string $name_col .
244 * @param string $type .
245 * @param string $after_col .
246 *
247 * @return bool|int
248 * @throws Exception
249 */
250 public function add_col_table( string $name_table, string $name_col, string $type, string $after_col = '' ) {
251 if ( ! current_user_can( ADMIN_ROLE ) ) {
252 throw new Exception( 'You don\'t have permission' );
253 }
254
255 $query_add = '';
256
257 $col_exists = $this->check_col_table( $name_table, $name_col );
258
259 if ( ! empty( $after_col ) ) {
260 $query_add .= "AFTER $after_col";
261 }
262
263 if ( ! $col_exists ) {
264 $execute = $this->wpdb->query( "ALTER TABLE $name_table ADD COLUMN $name_col $type $query_add" );
265
266 $this->check_execute_has_error();
267
268 return $execute;
269 }
270
271 return true;
272 }
273
274 /**
275 * Drop Index of Table
276 *
277 * @param string $name_table .
278 *
279 * @return bool|int
280 * @throws Exception
281 */
282 public function drop_indexs_table( string $name_table ) {
283 $show_index = "SHOW INDEX FROM $name_table";
284 $indexs = $this->wpdb->get_results( $show_index );
285
286 foreach ( $indexs as $index ) {
287 if ( 'PRIMARY' === $index->Key_name || '1' !== $index->Seq_in_index ) {
288 continue;
289 }
290
291 $query = $this->wpdb->prepare( "ALTER TABLE $name_table DROP INDEX $index->Key_name", 1 );
292
293 $this->wpdb->query( $query );
294 $this->check_execute_has_error();
295 }
296 }
297
298 /**
299 * Add Index of Table
300 *
301 * @param string $name_table .
302 * @param array $indexs.
303 *
304 * @return bool|int
305 * @throws Exception
306 */
307 public function add_indexs_table( string $name_table, array $indexs ) {
308 $add_index = '';
309 $count_indexs = count( $indexs ) - 1;
310
311 // Drop indexs .
312 $this->drop_indexs_table( $name_table );
313
314 foreach ( $indexs as $index ) {
315 if ( $count_indexs === array_search( $index, $indexs ) ) {
316 $add_index .= ' ADD INDEX ' . $index . ' (' . $index . ')';
317 } else {
318 $add_index .= ' ADD INDEX ' . $index . ' (' . $index . '),';
319 }
320 }
321
322 $execute = $this->wpdb->query(
323 "
324 ALTER TABLE {$name_table}
325 $add_index
326 "
327 );
328
329 $this->check_execute_has_error();
330
331 return $execute;
332 }
333
334 /**
335 * Drop table
336 *
337 * @param string $name_table .
338 *
339 * @return bool|int
340 * @throws Exception
341 */
342 public function drop_table( string $name_table = '' ) {
343 if ( ! current_user_can( ADMIN_ROLE ) ) {
344 throw new Exception( 'You don\'t have permission' );
345 }
346
347 // Check table exists.
348 $tb_exists = $this->check_table_exists( $name_table );
349 if ( $tb_exists ) {
350 $execute = $this->wpdb->query( "DROP TABLE $name_table" );
351
352 $this->check_execute_has_error();
353
354 return $execute;
355 }
356
357 return true;
358 }
359
360 /**
361 * Get list columns name of table
362 *
363 * @param string $name_table
364 *
365 * @return array
366 * @throws Exception
367 * @version 1.0.0
368 * @since 4.1.6
369 * @author tungnx
370 */
371 public function get_cols_of_table( string $name_table ): array {
372 $query = "SHOW COLUMNS FROM $name_table";
373
374 $result = $this->wpdb->get_col( $query );
375
376 $this->check_execute_has_error();
377
378 return $result;
379 }
380
381 /**
382 * Create table learnpress_user_item_results
383 *
384 * @return bool|int
385 * @throws Exception
386 */
387 public function create_tb_lp_user_item_results() {
388 $collate = $this->get_collate();
389
390 $execute = $this->wpdb->query(
391 "
392 CREATE TABLE IF NOT EXISTS $this->tb_lp_user_item_results(
393 id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
394 user_item_id bigint(20) unsigned NOT NULL,
395 result longtext,
396 PRIMARY KEY (id),
397 KEY user_item_id (user_item_id)
398 ) $collate
399 "
400 );
401
402 $this->check_execute_has_error();
403
404 return $execute;
405 }
406
407 /**
408 * Create table learnpress_upgrade_db
409 *
410 * @return bool|int
411 * @throws Exception
412 */
413 public function create_tb_lp_upgrade_db() {
414 $collate = $this->get_collate();
415
416 $execute = $this->wpdb->query(
417 "
418 CREATE TABLE IF NOT EXISTS {$this->tb_lp_upgrade_db}(
419 step varchar(50) PRIMARY KEY UNIQUE,
420 status varchar(10),
421 KEY status (status)
422 ) $collate
423 "
424 );
425
426 $this->check_execute_has_error();
427
428 return $execute;
429 }
430
431 /**
432 * Set step completed.
433 *
434 * @param string $step .
435 * @param string $status .
436 *
437 * @return int|bool
438 */
439 public function set_step_complete( string $step, string $status ) {
440 if ( ! current_user_can( 'administrator' ) ) {
441 return false;
442 }
443
444 return $this->wpdb->insert(
445 $this->tb_lp_upgrade_db,
446 array(
447 'step' => $step,
448 'status' => $status,
449 ),
450 array( '%s', '%s' )
451 );
452 }
453
454 /**
455 * Get steps completed.
456 *
457 * @return array|object|null
458 */
459 public function get_steps_completed() {
460 return $this->wpdb->get_results( "SELECT step, status FROM {$this->tb_lp_upgrade_db}", OBJECT_K );
461 }
462
463 /**
464 * Check execute current has any errors.
465 *
466 * @throws Exception
467 */
468 public function check_execute_has_error() {
469 if ( $this->wpdb->last_error ) {
470 throw new Exception( $this->wpdb->last_error );
471 }
472 }
473
474 /**
475 * Important: Reason need set again indexes for table options of WP
476 * because if want change value of "option_name" will error "database error Duplicate entry"
477 * So before set must drop and add when done all
478 *
479 * @author tungnx
480 * @version 1.0.0
481 * @since 4.0.3
482 * @throws Exception
483 */
484 public function create_indexes_tb_options() {
485 $this->drop_indexs_table( $this->tb_options );
486 $result = $this->wpdb->query(
487 "
488 ALTER TABLE $this->tb_options
489 ADD UNIQUE option_name (option_name),
490 ADD INDEX autoload (autoload)
491 "
492 );
493
494 $this->check_execute_has_error();
495
496 return $result;
497 }
498
499 /**
500 * Rename table
501 *
502 * @author tungnx
503 * @version 1.0.0
504 * @since 4.0.3
505 * @throws Exception
506 */
507 public function rename_table( string $name_table = '', string $new_name = '' ) {
508 if ( ! current_user_can( ADMIN_ROLE ) ) {
509 throw new Exception( 'You don\'t have permission' );
510 }
511
512 $tb_exists = $this->check_table_exists( $name_table );
513
514 if ( ! $tb_exists ) {
515 throw new Exception( 'Table not exists' );
516 }
517
518 $result = $this->wpdb->query(
519 "
520 ALTER TABLE $name_table
521 RENAME $new_name
522 "
523 );
524 $this->check_execute_has_error();
525
526 return $result;
527 }
528
529 /**
530 * Check key postmeta exist on Database
531 *
532 * @param int $post_id
533 * @param string $key
534 *
535 * @return bool|int
536 */
537 public function check_key_postmeta_exists( int $post_id = 0, string $key = '' ) {
538 return $this->wpdb->query(
539 $this->wpdb->prepare(
540 "
541 SELECT meta_id FROM $this->tb_postmeta
542 WHERE meta_key = %s
543 AND post_id = %d
544 ",
545 $key,
546 $post_id
547 )
548 );
549 }
550
551 /**
552 * Get total pages
553 *
554 * @param int $limit
555 * @param int $total_rows
556 *
557 * @return false|float
558 */
559 public static function get_total_pages( int $limit = 0, int $total_rows = 0 ) {
560 if ( $limit == 0 ) {
561 return 0;
562 }
563
564 $total_pages = floor( $total_rows / $limit );
565 if ( $total_rows % $limit !== 0 ) {
566 $total_pages++;
567 }
568
569 return $total_pages;
570 }
571
572 /**
573 * Get result query
574 *
575 * @return array|null|int|string
576 * @throws Exception
577 * @author tungnx
578 * @version 1.0.0
579 * @since 4.1.6
580 */
581 public function execute( LP_Filter $filter, int &$total_rows = 0 ) {
582 $result = null;
583
584 // Where
585 $WHERE = array( 'WHERE 1=1' );
586
587 // Fields select
588 $FIELDS = '*';
589 if ( ! empty( $filter->only_fields ) ) {
590 $FIELDS = implode( ',', array_unique( $filter->only_fields ) );
591 } elseif ( ! empty( $filter->fields ) ) {
592 // exclude more fields
593 if ( ! empty( $filter->exclude_fields ) ) {
594 foreach ( $filter->exclude_fields as $field ) {
595 $index_field = array_search( $field, $filter->fields );
596 if ( $index_field ) {
597 unset( $filter->fields[ $index_field ] );
598 }
599 }
600 }
601 $FIELDS = implode( ',', array_unique( $filter->fields ) );
602 }
603 $FIELDS = apply_filters( 'lp/query/fields', $FIELDS, $filter );
604
605 $INNER_JOIN = array();
606 $INNER_JOIN = array_merge( $INNER_JOIN, $filter->join );
607 $INNER_JOIN = apply_filters( 'lp/query/inner_join', $INNER_JOIN, $filter );
608 $INNER_JOIN = implode( ' ', array_unique( $INNER_JOIN ) );
609
610 $WHERE = array_merge( $WHERE, $filter->where );
611 $WHERE = apply_filters( 'lp/query/where', $WHERE, $filter );
612 $WHERE = implode( ' ', array_unique( $WHERE ) );
613
614 // Group by
615 $GROUP_BY = '';
616 if ( $filter->group_by ) {
617 $GROUP_BY .= 'GROUP BY ' . $filter->group_by;
618 $GROUP_BY = apply_filters( 'lp/query/group_by', $GROUP_BY, $filter );
619 }
620
621 // Order by
622 $ORDER_BY = '';
623 if ( ! $filter->return_string_query && $filter->order_by ) {
624 $ORDER_BY .= 'ORDER BY ' . $filter->order_by . ' ' . $filter->order . ' ';
625 $ORDER_BY = apply_filters( 'lp/query/order_by', $ORDER_BY, $filter );
626 }
627
628 // Limit
629 $LIMIT = '';
630 if ( ! $filter->return_string_query ) {
631 $filter->limit = absint( $filter->limit );
632 if ( $filter->limit > $filter->max_limit ) {
633 $filter->limit = $filter->max_limit;
634 }
635 $offset = $filter->limit * ( $filter->page - 1 );
636 $LIMIT = $this->wpdb->prepare( 'LIMIT %d, %d', $offset, $filter->limit );
637 }
638
639 $COLLECTION = '';
640 if ( ! empty( $filter->collection ) ) {
641 $COLLECTION = $filter->collection;
642 }
643
644 $ALIAS_COLLECTION = 'X';
645 if ( ! empty( $filter->collection_alias ) ) {
646 $ALIAS_COLLECTION = $filter->collection_alias;
647 }
648
649 // Query
650 $query = "SELECT $FIELDS FROM $COLLECTION AS $ALIAS_COLLECTION
651 $INNER_JOIN
652 $WHERE
653 $GROUP_BY
654 $ORDER_BY
655 $LIMIT
656 ";
657
658 if ( $filter->return_string_query ) {
659 return $query;
660 } elseif ( ! empty( $filter->union ) ) {
661 $query = implode( ' UNION ', array_unique( $filter->union ) );
662 $query .= $GROUP_BY;
663 $query .= $ORDER_BY;
664 $query .= $LIMIT;
665 }
666
667 if ( ! $filter->query_count ) {
668 $result = $this->wpdb->get_results( $query );
669 }
670
671 // Query total rows
672 $query = str_replace( array( $LIMIT, $ORDER_BY ), '', $query );
673 $query_total = "SELECT COUNT($filter->field_count) FROM ($query) AS $ALIAS_COLLECTION";
674 $total_rows = (int) $this->wpdb->get_var( $query_total );
675
676 $this->check_execute_has_error();
677
678 if ( $filter->query_count ) {
679 return $total_rows;
680 }
681
682 return $result;
683 }
684
685 /**
686 * Get values of list object by key
687 *
688 * @param array $arr_object
689 * @param string $key
690 *
691 * @return array
692 */
693 public static function get_values_by_key( array $arr_object, string $key = 'ID' ): array {
694 $arr_object_ids = array();
695 foreach ( $arr_object as $object ) {
696 $arr_object_ids[] = $object->{$key};
697 }
698
699 return $arr_object_ids;
700 }
701 }
702