class-wp-widget-factory.php 3.7 KB

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