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