You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

153 lines
3.8 KiB

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