PluginProbe
GamiPress – Gamification plugin to reward points, badges & ranks in WordPress, now with AI / 8.0.1
GamiPress – Gamification plugin to reward points, badges & ranks in WordPress, now with AI v8.0.1
8.0.1 8.0.2 8.0.0 7.9.9.7 7.9.9.6 7.9.9.5 7.9.9.4 7.9.9.3 7.9.9.2 7.9.9.1 7.9.9 7.9.8 7.9.7 7.9.6 7.9.5 7.9.4 7.9.3 7.9.2 7.9.1 7.9.0 7.8.9 7.8.8 7.8.7 7.8.6 7.8.5 All 44 releases
gamipress / libraries / ct / includes / class-ct-table.php

class-ct-table.php in GamiPress – Gamification plugin to reward points, badges & ranks in WordPress, now with AI 8.0.1, at libraries/ct/includes/class-ct-table.php

810 lines 26.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Table class
4 *
5 * Based on WP_Post_Type class
6 *
7 * @author GamiPress <contact@gamipress.com>, Ruben Garcia <rubengcdev@gamil.com>
8 *
9 * @since 1.0.0
10 */
11 // Exit if accessed directly
12 defined( 'ABSPATH' ) || exit;
13
14 if ( ! class_exists( 'CT_Table' ) ) :
15
16 class CT_Table {
17
18 /**
19 * Table key.
20 *
21 * @since 1.0.0
22 * @access public
23 * @var string $name
24 */
25 public $name;
26
27 /**
28 * Table database.
29 *
30 * @since 1.0.0
31 * @access public
32 * @var CT_DataBase $db
33 */
34 public $db;
35
36 /**
37 * Table ciews.
38 *
39 * @since 1.0.0
40 * @access public
41 * @var stdClass $views
42 */
43 public $views;
44
45 /**
46 * Table Meta (if supports contains 'meta').
47 *
48 * @since 1.0.0
49 * @access public
50 * @var CT_Table_Meta $meta
51 */
52 public $meta;
53
54 /**
55 * Table key.
56 *
57 * @since 1.0.0
58 * @access public
59 * @var string $name
60 */
61 public $singular;
62
63 /**
64 * Table key.
65 *
66 * @since 1.0.0
67 * @access public
68 * @var string $name
69 */
70 public $plural;
71
72 /**
73 * Name of the post type shown in the menu. Usually plural.
74 *
75 * @since 1.0.0
76 * @access public
77 * @var string $label
78 */
79 public $label;
80
81 /**
82 * Labels object for this post type.
83 *
84 * If not set, post labels are inherited for non-hierarchical types
85 * and page labels for hierarchical ones.
86 *
87 * @see ct_get_table_labels()
88 *
89 * @since 1.0.0
90 * @access public
91 * @var object $labels
92 */
93 public $labels;
94
95 /**
96 * Whether to exclude posts with this post type from front end search
97 * results.
98 *
99 * Default is the opposite value of $public.
100 *
101 * @since 1.0.0
102 * @access public
103 * @var bool $exclude_from_search
104 */
105 public $exclude_from_search = null;
106
107 /**
108 * Whether queries can be performed on the front end for the post type as part of `parse_request()`.
109 *
110 * Endpoints would include:
111 * - `?post_type={post_type_key}`
112 * - `?{post_type_key}={single_post_slug}`
113 * - `?{post_type_query_var}={single_post_slug}`
114 *
115 * Default is the value of $public.
116 *
117 * @since 1.0.0
118 * @access public
119 * @var bool $publicly_queryable
120 */
121 public $publicly_queryable = null;
122
123 /**
124 * Whether to generate and allow a UI for managing this post type in the admin.
125 *
126 * Default is the value of $public.
127 *
128 * @since 1.0.0
129 * @access public
130 * @var bool $show_ui
131 */
132 public $show_ui = null;
133
134 /**
135 * Where to show the post type in the admin menu.
136 *
137 * To work, $show_ui must be true. If true, the post type is shown in its own top level menu. If false, no menu is
138 * shown. If a string of an existing top level menu (eg. 'tools.php' or 'edit.php?post_type=page'), the post type
139 * will be placed as a sub-menu of that.
140 *
141 * Default is the value of $show_ui.
142 *
143 * @since 1.0.0
144 * @access public
145 * @var bool $show_in_menu
146 */
147 public $show_in_menu = null;
148
149 /**
150 * Makes this post type available for selection in navigation menus.
151 *
152 * Default is the value $public.
153 *
154 * @since 1.0.0
155 * @access public
156 * @var bool $show_in_nav_menus
157 */
158 public $show_in_nav_menus = null;
159
160 /**
161 * Makes this post type available via the admin bar.
162 *
163 * Default is the value of $show_in_menu.
164 *
165 * @since 1.0.0
166 * @access public
167 * @var bool $show_in_admin_bar
168 */
169 public $show_in_admin_bar = null;
170
171 /**
172 * The position in the menu order the post type should appear.
173 *
174 * To work, $show_in_menu must be true. Default null (at the bottom).
175 *
176 * @since 1.0.0
177 * @access public
178 * @var int $menu_position
179 */
180 public $menu_position = null;
181
182 /**
183 * The URL to the icon to be used for this menu.
184 *
185 * Pass a base64-encoded SVG using a data URI, which will be colored to match the color scheme.
186 * This should begin with 'data:image/svg+xml;base64,'. Pass the name of a Dashicons helper class
187 * to use a font icon, e.g. 'dashicons-chart-pie'. Pass 'none' to leave div.wp-menu-image empty
188 * so an icon can be added via CSS.
189 *
190 * Defaults to use the posts icon.
191 *
192 * @since 1.0.0
193 * @access public
194 * @var string $menu_icon
195 */
196 public $menu_icon = null;
197
198 /**
199 * The string to use to build the read, edit, and delete capabilities.
200 *
201 * May be passed as an array to allow for alternative plurals when using
202 * this argument as a base to construct the capabilities, e.g.
203 * array( 'story', 'stories' ). Default 'post'.
204 *
205 * @since 1.0.0
206 * @access public
207 * @var string $capability_type
208 */
209 public $capability_type = 'post';
210
211 /**
212 * Whether to use the internal default meta capability handling.
213 *
214 * Default false.
215 *
216 * @since 1.0.0
217 * @access public
218 * @var bool $map_meta_cap
219 */
220 public $map_meta_cap = false;
221
222 /**
223 * Provide a callback function that sets up the meta boxes for the edit form.
224 *
225 * Do `remove_meta_box()` and `add_meta_box()` calls in the callback. Default null.
226 *
227 * @since 1.0.0
228 * @access public
229 * @var string $register_meta_box_cb
230 */
231 public $register_meta_box_cb = null;
232
233 /**
234 * An array of taxonomy identifiers that will be registered for the post type.
235 *
236 * Taxonomies can be registered later with `register_taxonomy()` or `register_taxonomy_for_object_type()`.
237 *
238 * Default empty array.
239 *
240 * @since 1.0.0
241 * @access public
242 * @var array $taxonomies
243 */
244 public $taxonomies = array();
245
246 /**
247 * Whether there should be post type archives, or if a string, the archive slug to use.
248 *
249 * Will generate the proper rewrite rules if $rewrite is enabled. Default false.
250 *
251 * @since 1.0.0
252 * @access public
253 * @var bool|string $has_archive
254 */
255 public $has_archive = false;
256
257 /**
258 * Sets the query_var key for this post type.
259 *
260 * Defaults to $post_type key. If false, a post type cannot be loaded at `?{query_var}={post_slug}`.
261 * If specified as a string, the query `?{query_var_string}={post_slug}` will be valid.
262 *
263 * @since 1.0.0
264 * @access public
265 * @var string|bool $query_var
266 */
267 public $query_var;
268
269 /**
270 * Whether to allow this post type to be exported.
271 *
272 * Default true.
273 *
274 * @since 1.0.0
275 * @access public
276 * @var bool $can_export
277 */
278 public $can_export = true;
279
280 /**
281 * Whether to delete posts of this type when deleting a user.
282 *
283 * If true, posts of this type belonging to the user will be moved to trash when then user is deleted.
284 * If false, posts of this type belonging to the user will *not* be trashed or deleted.
285 * If not set (the default), posts are trashed if post_type_supports( 'author' ).
286 * Otherwise posts are not trashed or deleted. Default null.
287 *
288 * @since 1.0.0
289 * @access public
290 * @var bool $delete_with_user
291 */
292 public $delete_with_user = null;
293
294 /**
295 * Whether this table is a native or "built-in" post_type.
296 *
297 * Default false.
298 *
299 * @since 1.0.0
300 * @access public
301 * @var bool $_builtin
302 */
303 public $_builtin = false;
304
305 /**
306 * URL segment to use for edit link of this table.
307 *
308 * Default 'post.php?post=%d'.
309 *
310 * @since 1.0.0
311 * @access public
312 * @var string $_edit_link
313 */
314 public $_edit_link = 'post.php?post=%d';
315
316 /**
317 * Table capabilities.
318 *
319 * @since 1.0.0
320 * @access public
321 * @var object $cap
322 */
323 public $cap;
324
325 /**
326 * Table capability to access.
327 *
328 * @since 1.0.0
329 * @access public
330 * @var string $capability
331 */
332 public $capability;
333
334 /**
335 * Triggers the handling of rewrites for this post type.
336 *
337 * Defaults to true, using $post_type as slug.
338 *
339 * @since 1.0.0
340 * @access public
341 * @var array|false $rewrite
342 */
343 public $rewrite;
344
345 /**
346 * The features supported by the post type.
347 *
348 * @since 1.0.0
349 * @access public
350 * @var array|bool $supports
351 */
352 public $supports;
353
354 /**
355 * Whether this post type should appear in the REST API.
356 *
357 * Default false. If true, standard endpoints will be registered with
358 * respect to $rest_base and $rest_controller_class.
359 *
360 * @since 4.7.4
361 * @access public
362 * @var bool $show_in_rest
363 */
364 public $show_in_rest;
365
366 /**
367 * The base path for this post type's REST API endpoints.
368 *
369 * @since 4.7.4
370 * @access public
371 * @var string|bool $rest_base
372 */
373 public $rest_base;
374
375 /**
376 * The controller for this post type's REST API endpoints.
377 *
378 * Custom controllers must extend WP_REST_Controller.
379 *
380 * @since 4.7.4
381 * @access public
382 * @var string|bool $rest_controller_class
383 */
384 public $rest_controller_class;
385
386 /**
387 * @since 4.7.4
388 * @access public
389 */
390 public $group;
391
392 /**
393 * @since 4.7.4
394 * @access public
395 */
396 public $schema;
397
398 /**
399 * @since 4.7.4
400 * @access public
401 */
402 public $engine;
403
404 /**
405 * @since 4.7.4
406 * @access public
407 */
408 public $global;
409
410 /**
411 * @since 4.7.4
412 * @access public
413 * @var string $version
414 */
415 public $version;
416
417 /**
418 * @since 4.7.4
419 * @access public
420 */
421 public $primary_key;
422
423 /**
424 * @since 4.7.4
425 * @access public
426 */
427 public $hierarchical;
428
429 /**
430 * @since 4.7.4
431 * @access public
432 * @var string|bool $public
433 */
434 public $public;
435
436 /**
437 * @since 4.7.4
438 * @access public
439 * @var string $description
440 */
441 public $description;
442
443 /**
444 * @since 4.7.4
445 * @access public
446 * @var array $relationship
447 */
448 public $relationship;
449
450 /**
451 * Constructor.
452 *
453 * Will populate object properties from the provided arguments and assign other
454 * default properties based on that information.
455 *
456 * @since 1.0.0
457 * @access public
458 *
459 * @see ct_register_table()
460 *
461 * @param string $name Table key.
462 * @param array|string $args Optional. Array or string of arguments for registering a post type.
463 * Default empty array.
464 */
465 public function __construct( $name, $args = array() ) {
466
467 // Table name
468 $this->name = $name;
469
470 $this->set_props( $args );
471
472 }
473
474 /**
475 * Sets table properties.
476 *
477 * @since 1.0.0
478 * @access public
479 *
480 * @param array|string $args Array or string of arguments for registering a post type.
481 */
482 public function set_props( $args ) {
483 $args = wp_parse_args( $args );
484
485 /**
486 * Filters the arguments for registering a table.
487 *
488 * @since 1.0.0
489 *
490 * @param array $args Array of arguments for registering a post type.
491 * @param string $post_type Table key.
492 */
493 $args = apply_filters( 'ct_register_table_args', $args, $this->name );
494
495 $has_edit_link = ! empty( $args['_edit_link'] );
496
497 // Args prefixed with an underscore are reserved for internal use.
498 $defaults = array(
499 'singular' => $this->name,
500 'plural' => $this->name . 's',
501 'labels' => array(),
502 'description' => '',
503 'group' => '',
504 'public' => false,
505 'hierarchical' => false,
506 'exclude_from_search' => null,
507 'publicly_queryable' => null,
508 'show_ui' => null,
509 'show_in_menu' => null,
510 'show_in_nav_menus' => null,
511 'show_in_admin_bar' => null,
512 'menu_position' => null,
513 'menu_icon' => null,
514 'capability_type' => 'item',
515 'capabilities' => array(),
516 'map_meta_cap' => null,
517 'supports' => array(),
518 'relationship' => array(),
519 'register_meta_box_cb' => null,
520 //'taxonomies' => array(),
521 'has_archive' => false,
522 'rewrite' => true,
523 'query_var' => true,
524 'can_export' => true,
525 'delete_with_user' => null,
526 //'_builtin' => false,
527 //'_edit_link' => 'post.php?post=%d',
528 // Rest defaults
529 'show_in_rest' => false,
530 'rest_base' => false,
531 'rest_controller_class' => false,
532 // Database defaults
533 'primary_key' => '',
534 'version' => 1,
535 'global' => false,
536 //'schema' => '',
537 'engine' => 'InnoDB',
538 // Shortcuts
539 'capability' => '',
540 );
541
542 $args = array_merge( $defaults, $args );
543
544 $args['name'] = $this->name;
545
546 if ( empty( $args['group'] ) ) {
547 $args['group'] = strtok( $this->name, '_');
548 }
549
550 // If not set, default to the setting for public.
551 if ( null === $args['publicly_queryable'] ) {
552 $args['publicly_queryable'] = $args['public'];
553 }
554
555 // If not set, default to the setting for public.
556 if ( null === $args['show_ui'] ) {
557 $args['show_ui'] = $args['public'];
558 }
559
560 // If not set, default to the setting for show_ui.
561 if ( null === $args['show_in_menu'] || ! $args['show_ui'] ) {
562 $args['show_in_menu'] = $args['show_ui'];
563 }
564
565 // If not set, default to the whether the full UI is shown.
566 if ( null === $args['show_in_admin_bar'] ) {
567 $args['show_in_admin_bar'] = (bool) $args['show_in_menu'];
568 }
569
570 // If not set, default to the setting for public.
571 if ( null === $args['show_in_nav_menus'] ) {
572 $args['show_in_nav_menus'] = $args['public'];
573 }
574
575 // If not set, default to true if not public, false if public.
576 if ( null === $args['exclude_from_search'] ) {
577 $args['exclude_from_search'] = ! $args['public'];
578 }
579
580 // Back compat with quirky handling in version 3.0. #14122.
581 if ( empty( $args['capabilities'] ) && null === $args['map_meta_cap'] && in_array( $args['capability_type'], array( 'post', 'page' ) ) ) {
582 $args['map_meta_cap'] = true;
583 }
584
585 // If not set, default to false.
586 if ( null === $args['map_meta_cap'] ) {
587 $args['map_meta_cap'] = false;
588 }
589
590 // If there's no specified edit link and no UI, remove the edit link.
591 if ( ! $args['show_ui'] && ! $has_edit_link ) {
592 $args['_edit_link'] = '';
593 }
594
595 $this->cap = ct_get_table_capabilities( (object) $args );
596 $this->capability = $args['capability'];
597
598 unset( $args['capabilities'] );
599
600 if ( is_array( $args['capability_type'] ) ) {
601 $args['capability_type'] = $args['capability_type'][0];
602 }
603
604 if ( false !== $args['query_var'] ) {
605 if ( true === $args['query_var'] ) {
606 $args['query_var'] = $this->name;
607 } else {
608 $args['query_var'] = sanitize_title_with_dashes( $args['query_var'] );
609 }
610 }
611
612 if ( false !== $args['rewrite'] && ( is_admin() || '' != get_option( 'permalink_structure' ) ) ) {
613 if ( ! is_array( $args['rewrite'] ) ) {
614 $args['rewrite'] = array();
615 }
616 if ( empty( $args['rewrite']['slug'] ) ) {
617 $args['rewrite']['slug'] = $this->name;
618 }
619 if ( ! isset( $args['rewrite']['with_front'] ) ) {
620 $args['rewrite']['with_front'] = true;
621 }
622 if ( ! isset( $args['rewrite']['pages'] ) ) {
623 $args['rewrite']['pages'] = true;
624 }
625 if ( ! isset( $args['rewrite']['feeds'] ) || ! $args['has_archive'] ) {
626 $args['rewrite']['feeds'] = (bool) $args['has_archive'];
627 }
628 if ( ! isset( $args['rewrite']['ep_mask'] ) ) {
629 if ( isset( $args['permalink_epmask'] ) ) {
630 $args['rewrite']['ep_mask'] = $args['permalink_epmask'];
631 } else {
632 $args['rewrite']['ep_mask'] = EP_PERMALINK;
633 }
634 }
635 }
636
637 foreach ( $args as $property_name => $property_value ) {
638 $this->$property_name = $property_value;
639 }
640
641 // Backward compatibility
642 // Do not pass singular and plural, use "ct_{table}_labels" hook instead
643 // See: ct_load_table_labels()
644 if( $args['singular'] !== $this->name ) {
645 $this->singular = $args['singular'];
646 $this->plural = $args['plural'];
647
648 $labels = array();
649
650 // Custom defined labels overrides default
651 if( isset( $args['labels'] ) && is_array( $args['labels'] ) ) {
652 $labels = $args['labels'];
653 }
654
655 // Backward compatibility for views titles
656 if( isset( $args['views'] ) && is_array( $args['views'] ) ) {
657 // List
658 if( isset( $args['views']['list'] ) && is_array( $args['views']['list'] ) ) {
659 if( isset( $args['views']['list']['page_title'] ) ) {
660 $labels['list_page_title'] = $args['views']['list']['page_title'];
661 }
662
663 if( isset( $args['views']['list']['menu_title'] ) ) {
664 $labels['list_menu_title'] = $args['views']['list']['menu_title'];
665 }
666 }
667
668 // Add
669 if( isset( $args['views']['add'] ) && is_array( $args['views']['add'] ) ) {
670 if( isset( $args['views']['add']['page_title'] ) ) {
671 $labels['add_page_title'] = $args['views']['add']['page_title'];
672 }
673
674 if( isset( $args['views']['add']['menu_title'] ) ) {
675 $labels['add_menu_title'] = $args['views']['add']['menu_title'];
676 }
677 }
678
679 // Edit should not have any menu entry
680 }
681
682 $this->labels = (object) $labels;
683
684 if( property_exists( $this->labels, 'name' ) ) {
685 $this->label = $this->labels->name;
686 } else {
687 $this->label = $this->singular;
688 }
689 }
690
691 if( isset( $args['relationship'] ) ) {
692 $this->relationship = (object) $args['relationship'];
693 } else {
694 $this->relationship = false;
695 }
696
697 // Table database
698
699 if( isset( $args['db'] ) ) {
700 if( is_array( $args['db'] ) ) {
701 // Table as array of args to pass to CT_DataBase
702 $this->db = new CT_DataBase( $this->name, $args['db'] );
703 } else if( $args['db'] instanceof CT_DataBase || is_subclass_of( $args['db'], 'CT_DataBase' ) ) {
704 // Table as custom object
705 $this->db = $args['db'];
706 }
707 } else {
708 // Default database initialization
709 $this->db = new CT_DataBase( $this->name, $args );
710 }
711
712 // Views (list, add, edit)
713
714 $views_defaults = array(
715 'list' => array(
716 'menu_slug' => $this->name,
717 'parent_slug' => $this->name,
718 'show_in_menu' => $this->show_ui,
719
720 // Specific view args
721 'per_page' => 20,
722 'columns' => array(),
723 'add_form' => false,
724 ),
725 'add' => array(
726 'menu_slug' => 'add_' . $this->name,
727 'parent_slug' => $this->name,
728 'show_in_menu' => $this->show_ui,
729
730 // Specific view args
731 'columns' => 2,
732 ),
733 'edit' => array(
734 'menu_slug' => 'edit_' . $this->name,
735 'parent_slug' => '',
736 'show_in_menu' => false,
737
738 // Specific view args
739 'columns' => 2,
740 ),
741 );
742
743 if( isset( $args['views'] ) && is_array( $args['views'] ) ) {
744
745 $views = array();
746
747 // Ensure default views (list, add, edit) are in
748 foreach( $views_defaults as $view => $view_args ) {
749 if( ! isset( $args['views'][$view] ) ) {
750 $args['views'][$view] = $view_args;
751 }
752 }
753
754 foreach( $args['views'] as $view => $view_args ) {
755
756 if( is_array( $view_args ) ) {
757
758 // Parse default view args
759 if( isset( $views_defaults[$view] ) ) {
760 $view_args = wp_parse_args( $view_args, $views_defaults[$view] );
761 }
762
763 // View as array of args to pass to CT_View
764 switch( $view ) {
765 case 'list':
766 $views[$view] = new CT_List_View( $this->name, $view_args );
767 break;
768 case 'add':
769 $views[$view] = new CT_Edit_View( $this->name, $view_args );
770 break;
771 case 'edit':
772 $views[$view] = new CT_Edit_View( $this->name, $view_args );
773 break;
774 default:
775 $views[$view] = new CT_View( $this->name, $view_args );
776 break;
777 }
778 } else if( $view_args instanceof CT_View || is_subclass_of( $view_args, 'CT_View' ) ) {
779 // View as custom object
780 $views[$view] = $view_args;
781 }
782 }
783
784 // Ensure to add all default views
785 foreach( array( 'list', 'add', 'edit' ) as $view ) {
786 if( ! isset( $views[$view] ) ) {
787 $views[$view] = false;
788 }
789 }
790
791 $this->views = (object) $views;
792
793 } else {
794 // Default views initialization
795 $this->views = (object) array(
796 'list' => new CT_List_View( $this->name, $views_defaults['list'] ),
797 'add' => new CT_Edit_View( $this->name, $views_defaults['add'] ),
798 'edit' => new CT_Edit_View( $this->name, $views_defaults['edit'] ),
799 );
800 }
801
802 // Meta data
803 if( in_array( 'meta', $this->supports ) ) {
804 $this->meta = new CT_Table_Meta( $this );
805 }
806 }
807
808 }
809
810 endif;