Plugin Directory

source: codepress-admin-columns/trunk/classes/ListScreen.php @ 2293580

Last change on this file since 2293580 was 2293580, checked in by tschutter, 5 years ago

trunk

File size: 16.7 KB
Line 
1<?php
2
3namespace AC;
4
5use AC\Column\Placeholder;
6use AC\Type\ListScreenId;
7use DateTime;
8use LogicException;
9use ReflectionClass;
10use ReflectionException;
11
12/**
13 * List Screen
14 * @since 2.0
15 */
16abstract class ListScreen {
17
18        /**
19         * @deprecated 4.0
20         */
21        const OPTIONS_KEY = 'cpac_options_';
22
23        /**
24         * Unique Identifier for List Screen.
25         * @since 2.0
26         * @var string
27         */
28        private $key;
29
30        /**
31         * @since 2.0
32         * @var string
33         */
34        private $label;
35
36        /**
37         * @since 2.3.5
38         * @var string
39         */
40        private $singular_label;
41
42        /**
43         * Meta type of list screen; post, user, comment. Mostly used for fetching meta data.
44         * @since 3.0
45         * @var string
46         */
47        private $meta_type;
48
49        /**
50         * Page menu slug. Applies only when a menu page is used.
51         * @since 2.4.10
52         * @var string
53         */
54        private $page;
55
56        /**
57         * Group slug. Used for menu.
58         * @var string
59         */
60        private $group;
61
62        /**
63         * Name of the base PHP file (without extension).
64         * @see   \WP_Screen::base
65         * @since 2.0
66         * @var string
67         */
68        private $screen_base;
69
70        /**
71         * The unique ID of the screen.
72         * @see   \WP_Screen::id
73         * @since 2.5
74         * @var string
75         */
76        private $screen_id;
77
78        /**
79         * @since 2.0.1
80         * @var Column[]
81         */
82        private $columns;
83
84        /**
85         * @since 2.2
86         * @var Column[]
87         */
88        private $column_types;
89
90        /**
91         * @var array [ Column name => Label ]
92         */
93        private $original_columns;
94
95        /**
96         * @var string Layout ID
97         */
98        private $layout_id;
99
100        /**
101         * @var string Storage key used for saving column data to the database
102         */
103        private $storage_key;
104
105        /**
106         * @var array Column settings data
107         */
108        private $settings = [];
109
110        /**
111         * @var array ListScreen settings data
112         */
113        private $preferences = [];
114
115        /**
116         * @var bool True when column settings can not be overwritten
117         */
118        private $read_only = false;
119
120        /**
121         * @var bool
122         */
123        private $network_only = false;
124
125        /** @var string */
126        private $title;
127
128        /**
129         * @var DateTime
130         */
131        private $updated;
132
133        /**
134         * @return bool
135         */
136        public function has_id() {
137                return ListScreenId::is_valid_id( $this->layout_id );
138        }
139
140        /**
141         * @return ListScreenId
142         */
143        public function get_id() {
144                if ( ! $this->has_id() ) {
145                        throw new LogicException( 'ListScreen has no identity.' );
146                }
147
148                return new ListScreenId( $this->layout_id );
149        }
150
151        /**
152         * Contains the hook that contains the manage_value callback
153         * @return void
154         */
155        abstract public function set_manage_value_callback();
156
157        /**
158         * Register column types
159         * @return void
160         */
161        abstract protected function register_column_types();
162
163        /**
164         * @return string
165         */
166        public function get_heading_hookname() {
167                return 'manage_' . $this->get_screen_id() . '_columns';
168        }
169
170        /**
171         * @return string
172         */
173        public function get_key() {
174                return $this->key;
175        }
176
177        /**
178         * @param string $key
179         *
180         * @return self
181         */
182        protected function set_key( $key ) {
183                $this->key = $key;
184
185                return $this;
186        }
187
188        /**
189         * @return string
190         */
191        public function get_label() {
192                return $this->label;
193        }
194
195        /**
196         * @param string $label
197         *
198         * @return self
199         */
200        protected function set_label( $label ) {
201                $this->label = $label;
202
203                return $this;
204        }
205
206        /**
207         * @return string
208         */
209        public function get_singular_label() {
210                if ( null === $this->singular_label ) {
211                        $this->set_singular_label( $this->label );
212                }
213
214                return $this->singular_label;
215        }
216
217        /**
218         * @param string $label
219         *
220         * @return self
221         */
222        protected function set_singular_label( $label ) {
223                $this->singular_label = $label;
224
225                return $this;
226        }
227
228        /**
229         * @return string
230         */
231        public function get_meta_type() {
232                return $this->meta_type;
233        }
234
235        /**
236         * @param string $meta_type
237         *
238         * @return self
239         */
240        protected function set_meta_type( $meta_type ) {
241                $this->meta_type = $meta_type;
242
243                return $this;
244        }
245
246        /**
247         * @return string
248         */
249        public function get_screen_base() {
250                return $this->screen_base;
251        }
252
253        /**
254         * @param string $screen_base
255         *
256         * @return self
257         */
258        protected function set_screen_base( $screen_base ) {
259                $this->screen_base = $screen_base;
260
261                return $this;
262        }
263
264        /**
265         * @return string
266         */
267        public function get_screen_id() {
268                return $this->screen_id;
269        }
270
271        /**
272         * @param string $screen_id
273         *
274         * @return self
275         */
276        protected function set_screen_id( $screen_id ) {
277                $this->screen_id = $screen_id;
278
279                return $this;
280        }
281
282        /**
283         * @return string
284         */
285        public function get_page() {
286                return $this->page;
287        }
288
289        /**
290         * @param string $page
291         *
292         * @return self
293         */
294        protected function set_page( $page ) {
295                $this->page = $page;
296
297                return $this;
298        }
299
300        /**
301         * @return string
302         */
303        public function get_group() {
304                return $this->group;
305        }
306
307        /**
308         * @param string $group
309         *
310         * @return self
311         */
312        public function set_group( $group ) {
313                $this->group = $group;
314
315                return $this;
316        }
317
318        /**
319         * @return string
320         */
321        public function get_title() {
322                return $this->title;
323        }
324
325        /**
326         * @param string $title
327         *
328         * @return $this
329         */
330        public function set_title( $title ) {
331                $this->title = $title;
332
333                return $this;
334        }
335
336        /**
337         * @return string
338         */
339        public function get_storage_key() {
340                if ( null === $this->storage_key ) {
341                        $this->set_storage_key( $this->get_key() );
342                }
343
344                return $this->storage_key;
345        }
346
347        /**
348         * @param string $key
349         */
350        private function set_storage_key( $key ) {
351                $this->storage_key = $key;
352        }
353
354        /**
355         * @return string
356         */
357        public function get_layout_id() {
358                return $this->layout_id;
359        }
360
361        /**
362         * @param string $layout_id
363         *
364         * @return self
365         */
366        public function set_layout_id( $layout_id ) {
367                $this->layout_id = $layout_id;
368
369                $this->set_storage_key( $this->get_key() . $layout_id );
370
371                return $this;
372        }
373
374        /**
375         * ID attribute of targeted list table
376         * @return string
377         * @since 3.0
378         */
379        public function get_table_attr_id() {
380                return '#the-list';
381        }
382
383        /**
384         * @param $wp_screen
385         *
386         * @return boolean
387         * @since 2.0.3
388         */
389        public function is_current_screen( $wp_screen ) {
390                return $wp_screen && $wp_screen->id === $this->get_screen_id() && $wp_screen->base === $this->get_screen_base();
391        }
392
393        /**
394         * Settings can not be overwritten
395         */
396        public function is_read_only() {
397                return $this->read_only;
398        }
399
400        /**
401         * @param bool $read_only
402         *
403         * @return $this
404         */
405        public function set_read_only( $read_only ) {
406                $this->read_only = (bool) $read_only;
407
408                return $this;
409        }
410
411        /**
412         * Settings can not be overwritten
413         */
414        public function is_network_only() {
415                return $this->network_only;
416        }
417
418        /**
419         * @param bool $network_only
420         */
421        public function set_network_only( $network_only ) {
422                $this->network_only = (bool) $network_only;
423        }
424
425        /**
426         * @param DateTime $updated
427         *
428         * @return $this
429         */
430        public function set_updated( DateTime $updated ) {
431                $this->updated = $updated;
432
433                return $this;
434        }
435
436        /**
437         * @return DateTime
438         */
439        public function get_updated() {
440                return $this->updated
441                        ? $this->updated
442                        : new DateTime();
443        }
444
445        /**
446         * @return string
447         */
448        protected function get_admin_url() {
449                return admin_url( $this->get_screen_base() . '.php' );
450        }
451
452        /**
453         * @return string Link
454         * @since 2.0
455         */
456        public function get_screen_link() {
457                return add_query_arg( [
458                        'page'   => $this->get_page(),
459                        'layout' => $this->get_layout_id(),
460                ], $this->get_admin_url() );
461        }
462
463        /**
464         * @since 2.0
465         */
466        public function get_edit_link() {
467                return add_query_arg( [
468                        'list_screen' => $this->key,
469                        'layout_id'   => $this->get_layout_id(),
470                ], ac_get_admin_url( 'columns' ) );
471        }
472
473        /**
474         * @return Column[]
475         * @since 3.0
476         */
477        public function get_columns() {
478                if ( null === $this->columns ) {
479                        $this->set_columns();
480                }
481
482                return $this->columns;
483        }
484
485        /**
486         * @return Column[]
487         */
488        public function get_column_types() {
489                if ( null === $this->column_types ) {
490                        $this->set_column_types();
491                }
492
493                return $this->column_types;
494        }
495
496        /**
497         * @param $name
498         *
499         * @return false|Column
500         * @since 2.0
501         */
502        public function get_column_by_name( $name ) {
503                $columns = $this->get_columns();
504
505                foreach ( $columns as $column ) {
506                        // Do not do a strict comparision. All column names are stored as strings, even integers.
507                        if ( $column->get_name() == $name ) {
508                                return $column;
509                        }
510                }
511
512                return false;
513        }
514
515        /**
516         * @param string $type
517         *
518         * @return false|Column
519         */
520        public function get_column_by_type( $type ) {
521                $column_types = $this->get_column_types();
522
523                if ( ! isset( $column_types[ $type ] ) ) {
524                        return false;
525                }
526
527                return $column_types[ $type ];
528        }
529
530        /**
531         * @param string $type
532         *
533         * @return false|string
534         */
535        public function get_class_by_type( $type ) {
536                $column = $this->get_column_by_type( $type );
537
538                if ( ! $column ) {
539                        return false;
540                }
541
542                return get_class( $column );
543        }
544
545        /**
546         * @param string $type Column type
547         */
548        public function deregister_column_type( $type ) {
549                if ( isset( $this->column_types[ $type ] ) ) {
550                        unset( $this->column_types[ $type ] );
551                }
552        }
553
554        /**
555         * @param Column $column
556         */
557        public function register_column_type( Column $column ) {
558                if ( ! $column->get_type() ) {
559                        return;
560                }
561
562                $column->set_list_screen( $this );
563
564                if ( ! $column->is_valid() ) {
565                        return;
566                }
567
568                // Skip the custom registered columns which are marked 'original' but are not available for this list screen
569                if ( $column->is_original() && ! array_key_exists( $column->get_type(), $this->get_original_columns() ) ) {
570                        return;
571                }
572
573                $this->column_types[ $column->get_type() ] = $column;
574        }
575
576        /**
577         * @param string $type
578         *
579         * @return string Label
580         */
581        public function get_original_label( $type ) {
582                $columns = $this->get_original_columns();
583
584                if ( ! isset( $columns[ $type ] ) ) {
585                        return false;
586                }
587
588                return $columns[ $type ];
589        }
590
591        /**
592         * @return array
593         */
594        public function get_original_columns() {
595                return ( new DefaultColumnsRepository() )->get( $this->get_key() );
596        }
597
598        /**
599         * @param array $columns
600         */
601        public function set_original_columns( $columns ) {
602                $this->original_columns = (array) $columns;
603        }
604
605        /**
606         * Available column types
607         */
608        private function set_column_types() {
609                $this->column_types = [];
610
611                // Register default columns
612                foreach ( $this->get_original_columns() as $type => $label ) {
613
614                        // Ignore the mandatory checkbox column
615                        if ( 'cb' === $type ) {
616                                continue;
617                        }
618
619                        $column = new Column();
620
621                        $column
622                                ->set_type( $type )
623                                ->set_original( true );
624
625                        $this->register_column_type( $column );
626                }
627
628                // Placeholder columns
629                foreach ( new Integrations() as $integration ) {
630                        if ( ! $integration->show_placeholder( $this ) ) {
631                                continue;
632                        }
633
634                        $plugin_info = new PluginInformation( $integration->get_basename() );
635
636                        if ( $integration->is_plugin_active() && ! $plugin_info->is_active() ) {
637                                $column = new Placeholder();
638                                $column->set_integration( $integration );
639
640                                $this->register_column_type( $column );
641                        }
642                }
643
644                // Load Custom columns
645                $this->register_column_types();
646
647                /**
648                 * Register column types
649                 *
650                 * @param ListScreen $this
651                 */
652                do_action( 'ac/column_types', $this );
653        }
654
655        /**
656         * @param string $namespace Namespace from the current path
657         *
658         * @throws ReflectionException
659         */
660        public function register_column_types_from_dir( $namespace ) {
661                $classes = Autoloader::instance()->get_class_names_from_dir( $namespace );
662
663                foreach ( $classes as $class ) {
664                        $reflection = new ReflectionClass( $class );
665
666                        if ( $reflection->isInstantiable() ) {
667                                $this->register_column_type( new $class );
668                        }
669                }
670        }
671
672        /**
673         * @param string $type Column type
674         *
675         * @return bool
676         */
677        private function is_original_column( $type ) {
678                $column = $this->get_column_by_type( $type );
679
680                if ( ! $column ) {
681                        return false;
682                }
683
684                return $column->is_original();
685        }
686
687        /**
688         * @param string $column_name Column name
689         *
690         * @since 3.0
691         */
692        public function deregister_column( $column_name ) {
693                unset( $this->columns[ $column_name ] );
694        }
695
696        /**
697         * @param array $settings Column options
698         *
699         * @return Column|false
700         */
701        public function create_column( array $settings ) {
702                if ( ! isset( $settings['type'] ) ) {
703                        return false;
704                }
705
706                $class = $this->get_class_by_type( $settings['type'] );
707
708                if ( ! $class ) {
709                        return false;
710                }
711
712                /* @var Column $column */
713                $column = new $class();
714                $column->set_list_screen( $this )
715                       ->set_type( $settings['type'] );
716
717                if ( isset( $settings['name'] ) ) {
718                        $column->set_name( $settings['name'] );
719                }
720
721                // Mark as original
722                if ( $this->is_original_column( $settings['type'] ) ) {
723                        $column->set_original( true );
724                        $column->set_name( $settings['type'] );
725                }
726
727                $column->set_options( $settings );
728
729                do_action( 'ac/list_screen/column_created', $column, $this );
730
731                return $column;
732        }
733
734        /**
735         * @param Column $column
736         */
737        protected function register_column( Column $column ) {
738                $this->columns[ $column->get_name() ] = $column;
739
740                /**
741                 * Fires when a column is registered to a list screen, i.e. when it is created. Can be used
742                 * to attach additional functionality to a column, such as exporting, sorting or filtering
743                 *
744                 * @param Column     $column      Column type object
745                 * @param ListScreen $list_screen List screen object to which the column was registered
746                 *
747                 * @since 3.0.5
748                 */
749                do_action( 'ac/list_screen/column_registered', $column, $this );
750        }
751
752        /**
753         * @param array $settings
754         *
755         * @return self
756         */
757        public function set_settings( array $settings ) {
758                $this->settings = $settings;
759
760                return $this;
761        }
762
763        /**
764         * @since 3.0
765         */
766        private function set_columns() {
767                foreach ( $this->get_settings() as $name => $data ) {
768                        $data['name'] = $name;
769                        $column = $this->create_column( $data );
770
771                        if ( $column ) {
772                                $this->register_column( $column );
773                        }
774                }
775
776                // Nothing stored. Use WP default columns.
777                if ( null === $this->columns ) {
778                        foreach ( $this->get_original_columns() as $type => $label ) {
779                                if ( $column = $this->create_column( [ 'type' => $type, 'original' => true ] ) ) {
780                                        $this->register_column( $column );
781                                }
782                        }
783                }
784
785                if ( null === $this->columns ) {
786                        $this->columns = [];
787                }
788        }
789
790        /**
791         * @return array
792         */
793        public function get_settings() {
794                return $this->settings;
795        }
796
797        public function set_preferences( array $preferences ) {
798                $this->preferences = $preferences;
799
800                return $this;
801        }
802
803        /**
804         * @return array
805         */
806        public function get_preferences() {
807                return $this->preferences;
808        }
809
810        /**
811         * @param string $key
812         *
813         * @return mixed|null
814         */
815        public function get_preference( $key ) {
816                if ( ! isset( $this->preferences[ $key ] ) ) {
817                        return null;
818                }
819
820                return $this->preferences[ $key ];
821        }
822
823        /**
824         * @param string $column_name
825         * @param int    $id
826         * @param null   $original_value
827         *
828         * @return string
829         */
830        public function get_display_value_by_column_name( $column_name, $id, $original_value = null ) {
831                $column = $this->get_column_by_name( $column_name );
832
833                if ( ! $column ) {
834                        return $original_value;
835                }
836
837                $value = $column->get_value( $id );
838
839                // You can overwrite the display value for original columns by making sure get_value() does not return an empty string.
840                if ( $column->is_original() && ac_helper()->string->is_empty( $value ) ) {
841                        return $original_value;
842                }
843
844                /**
845                 * Column display value
846                 *
847                 * @param string $value  Column display value
848                 * @param int    $id     Object ID
849                 * @param Column $column Column object
850                 *
851                 * @since 3.0
852                 */
853                $value = apply_filters( 'ac/column/value', $value, $id, $column );
854
855                return $value;
856        }
857
858        /**
859         * @param array $columns
860         *
861         * @deprecated 4.0
862         */
863        public function save_default_headings( $columns ) {
864                _deprecated_function( __METHOD__, '4.0', 'AC\DefaultColumns::update( $key, $columns )' );
865
866                ( new DefaultColumnsRepository() )->update( $this->get_key(), $columns && is_array( $columns ) ? $columns : [] );
867        }
868
869        /**
870         * @return array
871         * @deprecated 4.0
872         */
873        public function get_stored_default_headings() {
874                _deprecated_function( __METHOD__, '4.0', 'AC\DefaultColumnsRepository()::get( $key )' );
875
876                return ( new DefaultColumnsRepository() )->get( $this->get_key() );
877        }
878
879        /**
880         * @return void
881         */
882        public function delete_default_headings() {
883                _deprecated_function( __METHOD__, '4.0', 'AC\DefaultColumnsRepository()::delete( $key )' );
884
885                ( new DefaultColumnsRepository() )->delete( $this->get_key() );
886        }
887
888        /**
889         * @return bool
890         * @deprecated 4.0
891         */
892        public function delete() {
893                _deprecated_function( __METHOD__, '4.0' );
894
895                return false;
896        }
897
898        /**
899         * Get default column headers
900         * @return array
901         * @deprecated 4.0
902         */
903        public function get_default_column_headers() {
904                _deprecated_function( __METHOD__, '4.0' );
905
906                return [];
907        }
908
909        /**
910         * Clears columns variable, which allow it to be repopulated by get_columns().
911         * @deprecated 4.0
912         * @since      2.5
913         */
914        public function reset() {
915                _deprecated_function( __METHOD__, '4.0' );
916        }
917
918        /**
919         * @deprecated 4.0
920         */
921        public function populate_settings() {
922                _deprecated_function( __METHOD__, '4.0' );
923        }
924
925        /**
926         * Reset original columns
927         * @deprecated 4.0
928         */
929        public function reset_original_columns() {
930                _deprecated_function( __METHOD__, '4.0' );
931
932                $this->original_columns = null;
933        }
934
935        /**
936         * Store column data
937         *
938         * @param array $column_data
939         *
940         * @deprecated 4.0
941         */
942        public function store( $column_data ) {
943                _deprecated_function( __METHOD__, '4.0' );
944        }
945
946}
Note: See TracBrowser for help on using the repository browser.