Wordpress 4.6
[autoinstalls/wordpress.git] / wp-includes / class-wp-widget-factory.php
1 <?php
2 /**
3  * Widget API: WP_Widget_Factory class
4  *
5  * @package WordPress
6  * @subpackage Widgets
7  * @since 4.4.0
8  */
9
10 /**
11  * Singleton that registers and instantiates WP_Widget classes.
12  *
13  * @since 2.8.0
14  * @since 4.4.0 Moved to its own file from wp-includes/widgets.php
15  */
16 class WP_Widget_Factory {
17
18         /**
19          * Widgets array.
20          *
21          * @since 2.8.0
22          * @access public
23          * @var array
24          */
25         public $widgets = array();
26
27         /**
28          * PHP5 constructor.
29          *
30          * @since 4.3.0
31          * @access public
32          */
33         public function __construct() {
34                 add_action( 'widgets_init', array( $this, '_register_widgets' ), 100 );
35         }
36
37         /**
38          * PHP4 constructor.
39          *
40          * @since 2.8.0
41          * @access public
42          */
43         public function WP_Widget_Factory() {
44                 _deprecated_constructor( 'WP_Widget_Factory', '4.2.0' );
45                 self::__construct();
46         }
47
48         /**
49          * Memory for the number of times unique class instances have been hashed.
50          *
51          * This can be eliminated in favor of straight spl_object_hash() when 5.3
52          * is the minimum requirement for PHP.
53          *
54          * @since 4.6.0
55          * @access private
56          * @var array
57          *
58          * @see WP_Widget_Factory::hash_object()
59          */
60         private $hashed_class_counts = array();
61
62         /**
63          * Hashes an object, doing fallback of `spl_object_hash()` if not available.
64          *
65          * This can be eliminated in favor of straight spl_object_hash() when 5.3
66          * is the minimum requirement for PHP.
67          *
68          * @since 4.6.0
69          * @access private
70          *
71          * @param WP_Widget $widget Widget.
72          * @return string Object hash.
73          */
74         private function hash_object( $widget ) {
75                 if ( function_exists( 'spl_object_hash' ) ) {
76                         return spl_object_hash( $widget );
77                 } else {
78                         $class_name = get_class( $widget );
79                         $hash = $class_name;
80                         if ( ! isset( $widget->_wp_widget_factory_hash_id ) ) {
81                                 if ( ! isset( $this->hashed_class_counts[ $class_name ] ) ) {
82                                         $this->hashed_class_counts[ $class_name ] = 0;
83                                 }
84                                 $this->hashed_class_counts[ $class_name ] += 1;
85                                 $widget->_wp_widget_factory_hash_id = $this->hashed_class_counts[ $class_name ];
86                         }
87                         $hash .= ':' . $widget->_wp_widget_factory_hash_id;
88                         return $hash;
89                 }
90         }
91
92         /**
93          * Registers a widget subclass.
94          *
95          * @since 2.8.0
96          * @since 4.6.0 Updated the `$widget` parameter to also accept a WP_Widget instance object
97          *              instead of simply a `WP_Widget` subclass name.
98          * @access public
99          *
100          * @param string|WP_Widget $widget Either the name of a `WP_Widget` subclass or an instance of a `WP_Widget` subclass.
101          */
102         public function register( $widget ) {
103                 if ( $widget instanceof WP_Widget ) {
104                         $this->widgets[ $this->hash_object( $widget ) ] = $widget;
105                 } else {
106                         $this->widgets[ $widget ] = new $widget();
107                 }
108         }
109
110         /**
111          * Un-registers a widget subclass.
112          *
113          * @since 2.8.0
114          * @since 4.6.0 Updated the `$widget` parameter to also accept a WP_Widget instance object
115          *              instead of simply a `WP_Widget` subclass name.
116          * @access public
117          *
118          * @param string|WP_Widget $widget Either the name of a `WP_Widget` subclass or an instance of a `WP_Widget` subclass.
119          */
120         public function unregister( $widget ) {
121                 if ( $widget instanceof WP_Widget ) {
122                         unset( $this->widgets[ $this->hash_object( $widget ) ] );
123                 } else {
124                         unset( $this->widgets[ $widget ] );
125                 }
126         }
127
128         /**
129          * Serves as a utility method for adding widgets to the registered widgets global.
130          *
131          * @since 2.8.0
132          * @access public
133          *
134          * @global array $wp_registered_widgets
135          */
136         public function _register_widgets() {
137                 global $wp_registered_widgets;
138                 $keys = array_keys($this->widgets);
139                 $registered = array_keys($wp_registered_widgets);
140                 $registered = array_map('_get_widget_id_base', $registered);
141
142                 foreach ( $keys as $key ) {
143                         // don't register new widget if old widget with the same id is already registered
144                         if ( in_array($this->widgets[$key]->id_base, $registered, true) ) {
145                                 unset($this->widgets[$key]);
146                                 continue;
147                         }
148
149                         $this->widgets[$key]->_register();
150                 }
151         }
152 }