[ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Dependencies API: WP_Dependencies base class 4 * 5 * @since 2.6.0 6 * 7 * @package WordPress 8 * @subpackage Dependencies 9 */ 10 11 /** 12 * Core base class extended to register items. 13 * 14 * @since 2.6.0 15 * 16 * @see _WP_Dependency 17 */ 18 #[AllowDynamicProperties] 19 class WP_Dependencies { 20 /** 21 * An array of all registered dependencies keyed by handle. 22 * 23 * @since 2.6.8 24 * 25 * @var _WP_Dependency[] 26 */ 27 public $registered = array(); 28 29 /** 30 * An array of handles of queued dependencies. 31 * 32 * @since 2.6.8 33 * 34 * @var string[] 35 */ 36 public $queue = array(); 37 38 /** 39 * An array of handles of dependencies to queue. 40 * 41 * @since 2.6.0 42 * 43 * @var string[] 44 */ 45 public $to_do = array(); 46 47 /** 48 * An array of handles of dependencies already queued. 49 * 50 * @since 2.6.0 51 * 52 * @var string[] 53 */ 54 public $done = array(); 55 56 /** 57 * An array of additional arguments passed when a handle is registered. 58 * 59 * Arguments are appended to the item query string. 60 * 61 * @since 2.6.0 62 * 63 * @var array 64 */ 65 public $args = array(); 66 67 /** 68 * An array of dependency groups to enqueue. 69 * 70 * Each entry is keyed by handle and represents the integer group level or boolean 71 * false if the handle has no group. 72 * 73 * @since 2.8.0 74 * 75 * @var (int|false)[] 76 */ 77 public $groups = array(); 78 79 /** 80 * A handle group to enqueue. 81 * 82 * @since 2.8.0 83 * 84 * @deprecated 4.5.0 85 * @var int 86 */ 87 public $group = 0; 88 89 /** 90 * Cached lookup array of flattened queued items and dependencies. 91 * 92 * @since 5.4.0 93 * 94 * @var array 95 */ 96 private $all_queued_deps; 97 98 /** 99 * List of assets enqueued before details were registered. 100 * 101 * @since 5.9.0 102 * 103 * @var array 104 */ 105 private $queued_before_register = array(); 106 107 /** 108 * Processes the items and dependencies. 109 * 110 * Processes the items passed to it or the queue, and their dependencies. 111 * 112 * @since 2.6.0 113 * @since 2.8.0 Added the `$group` parameter. 114 * 115 * @param string|string[]|false $handles Optional. Items to be processed: queue (false), 116 * single item (string), or multiple items (array of strings). 117 * Default false. 118 * @param int|false $group Optional. Group level: level (int), no group (false). 119 * @return string[] Array of handles of items that have been processed. 120 */ 121 public function do_items( $handles = false, $group = false ) { 122 /* 123 * If nothing is passed, print the queue. If a string is passed, 124 * print that item. If an array is passed, print those items. 125 */ 126 $handles = false === $handles ? $this->queue : (array) $handles; 127 $this->all_deps( $handles ); 128 129 foreach ( $this->to_do as $key => $handle ) { 130 if ( ! in_array( $handle, $this->done, true ) && isset( $this->registered[ $handle ] ) ) { 131 /* 132 * Attempt to process the item. If successful, 133 * add the handle to the done array. 134 * 135 * Unset the item from the to_do array. 136 */ 137 if ( $this->do_item( $handle, $group ) ) { 138 $this->done[] = $handle; 139 } 140 141 unset( $this->to_do[ $key ] ); 142 } 143 } 144 145 return $this->done; 146 } 147 148 /** 149 * Processes a dependency. 150 * 151 * @since 2.6.0 152 * @since 5.5.0 Added the `$group` parameter. 153 * 154 * @param string $handle Name of the item. Should be unique. 155 * @param int|false $group Optional. Group level: level (int), no group (false). 156 * Default false. 157 * @return bool True on success, false if not set. 158 */ 159 public function do_item( $handle, $group = false ) { 160 return isset( $this->registered[ $handle ] ); 161 } 162 163 /** 164 * Determines dependencies. 165 * 166 * Recursively builds an array of items to process taking 167 * dependencies into account. Does NOT catch infinite loops. 168 * 169 * @since 2.1.0 170 * @since 2.6.0 Moved from `WP_Scripts`. 171 * @since 2.8.0 Added the `$group` parameter. 172 * 173 * @param string|string[] $handles Item handle (string) or item handles (array of strings). 174 * @param bool $recursion Optional. Internal flag that function is calling itself. 175 * Default false. 176 * @param int|false $group Optional. Group level: level (int), no group (false). 177 * Default false. 178 * @return bool True on success, false on failure. 179 */ 180 public function all_deps( $handles, $recursion = false, $group = false ) { 181 $handles = (array) $handles; 182 if ( ! $handles ) { 183 return false; 184 } 185 186 foreach ( $handles as $handle ) { 187 $handle_parts = explode( '?', $handle ); 188 $handle = $handle_parts[0]; 189 $queued = in_array( $handle, $this->to_do, true ); 190 191 if ( in_array( $handle, $this->done, true ) ) { // Already done. 192 continue; 193 } 194 195 $moved = $this->set_group( $handle, $recursion, $group ); 196 $new_group = $this->groups[ $handle ]; 197 198 if ( $queued && ! $moved ) { // Already queued and in the right group. 199 continue; 200 } 201 202 $keep_going = true; 203 if ( ! isset( $this->registered[ $handle ] ) ) { 204 $keep_going = false; // Item doesn't exist. 205 } elseif ( $this->registered[ $handle ]->deps && array_diff( $this->registered[ $handle ]->deps, array_keys( $this->registered ) ) ) { 206 $keep_going = false; // Item requires dependencies that don't exist. 207 } elseif ( $this->registered[ $handle ]->deps && ! $this->all_deps( $this->registered[ $handle ]->deps, true, $new_group ) ) { 208 $keep_going = false; // Item requires dependencies that don't exist. 209 } 210 211 if ( ! $keep_going ) { // Either item or its dependencies don't exist. 212 if ( $recursion ) { 213 return false; // Abort this branch. 214 } else { 215 continue; // We're at the top level. Move on to the next one. 216 } 217 } 218 219 if ( $queued ) { // Already grabbed it and its dependencies. 220 continue; 221 } 222 223 if ( isset( $handle_parts[1] ) ) { 224 $this->args[ $handle ] = $handle_parts[1]; 225 } 226 227 $this->to_do[] = $handle; 228 } 229 230 return true; 231 } 232 233 /** 234 * Register an item. 235 * 236 * Registers the item if no item of that name already exists. 237 * 238 * @since 2.1.0 239 * @since 2.6.0 Moved from `WP_Scripts`. 240 * 241 * @param string $handle Name of the item. Should be unique. 242 * @param string|false $src Full URL of the item, or path of the item relative 243 * to the WordPress root directory. If source is set to false, 244 * the item is an alias of other items it depends on. 245 * @param string[] $deps Optional. An array of registered item handles this item depends on. 246 * Default empty array. 247 * @param string|bool|null $ver Optional. String specifying item version number, if it has one, 248 * which is added to the URL as a query string for cache busting purposes. 249 * If version is set to false, a version number is automatically added 250 * equal to current installed WordPress version. 251 * If set to null, no version is added. 252 * @param mixed $args Optional. Custom property of the item. NOT the class property $args. 253 * Examples: $media, $in_footer. 254 * @return bool Whether the item has been registered. True on success, false on failure. 255 */ 256 public function add( $handle, $src, $deps = array(), $ver = false, $args = null ) { 257 if ( isset( $this->registered[ $handle ] ) ) { 258 return false; 259 } 260 $this->registered[ $handle ] = new _WP_Dependency( $handle, $src, $deps, $ver, $args ); 261 262 // If the item was enqueued before the details were registered, enqueue it now. 263 if ( array_key_exists( $handle, $this->queued_before_register ) ) { 264 if ( ! is_null( $this->queued_before_register[ $handle ] ) ) { 265 $this->enqueue( $handle . '?' . $this->queued_before_register[ $handle ] ); 266 } else { 267 $this->enqueue( $handle ); 268 } 269 270 unset( $this->queued_before_register[ $handle ] ); 271 } 272 273 return true; 274 } 275 276 /** 277 * Add extra item data. 278 * 279 * Adds data to a registered item. 280 * 281 * @since 2.6.0 282 * 283 * @param string $handle Name of the item. Should be unique. 284 * @param string $key The data key. 285 * @param mixed $value The data value. 286 * @return bool True on success, false on failure. 287 */ 288 public function add_data( $handle, $key, $value ) { 289 if ( ! isset( $this->registered[ $handle ] ) ) { 290 return false; 291 } 292 293 return $this->registered[ $handle ]->add_data( $key, $value ); 294 } 295 296 /** 297 * Get extra item data. 298 * 299 * Gets data associated with a registered item. 300 * 301 * @since 3.3.0 302 * 303 * @param string $handle Name of the item. Should be unique. 304 * @param string $key The data key. 305 * @return mixed Extra item data (string), false otherwise. 306 */ 307 public function get_data( $handle, $key ) { 308 if ( ! isset( $this->registered[ $handle ] ) ) { 309 return false; 310 } 311 312 if ( ! isset( $this->registered[ $handle ]->extra[ $key ] ) ) { 313 return false; 314 } 315 316 return $this->registered[ $handle ]->extra[ $key ]; 317 } 318 319 /** 320 * Un-register an item or items. 321 * 322 * @since 2.1.0 323 * @since 2.6.0 Moved from `WP_Scripts`. 324 * 325 * @param string|string[] $handles Item handle (string) or item handles (array of strings). 326 */ 327 public function remove( $handles ) { 328 foreach ( (array) $handles as $handle ) { 329 unset( $this->registered[ $handle ] ); 330 } 331 } 332 333 /** 334 * Queue an item or items. 335 * 336 * Decodes handles and arguments, then queues handles and stores 337 * arguments in the class property $args. For example in extending 338 * classes, $args is appended to the item url as a query string. 339 * Note $args is NOT the $args property of items in the $registered array. 340 * 341 * @since 2.1.0 342 * @since 2.6.0 Moved from `WP_Scripts`. 343 * 344 * @param string|string[] $handles Item handle (string) or item handles (array of strings). 345 */ 346 public function enqueue( $handles ) { 347 foreach ( (array) $handles as $handle ) { 348 $handle = explode( '?', $handle ); 349 350 if ( ! in_array( $handle[0], $this->queue, true ) && isset( $this->registered[ $handle[0] ] ) ) { 351 $this->queue[] = $handle[0]; 352 353 // Reset all dependencies so they must be recalculated in recurse_deps(). 354 $this->all_queued_deps = null; 355 356 if ( isset( $handle[1] ) ) { 357 $this->args[ $handle[0] ] = $handle[1]; 358 } 359 } elseif ( ! isset( $this->registered[ $handle[0] ] ) ) { 360 $this->queued_before_register[ $handle[0] ] = null; // $args 361 362 if ( isset( $handle[1] ) ) { 363 $this->queued_before_register[ $handle[0] ] = $handle[1]; 364 } 365 } 366 } 367 } 368 369 /** 370 * Dequeue an item or items. 371 * 372 * Decodes handles and arguments, then dequeues handles 373 * and removes arguments from the class property $args. 374 * 375 * @since 2.1.0 376 * @since 2.6.0 Moved from `WP_Scripts`. 377 * 378 * @param string|string[] $handles Item handle (string) or item handles (array of strings). 379 */ 380 public function dequeue( $handles ) { 381 foreach ( (array) $handles as $handle ) { 382 $handle = explode( '?', $handle ); 383 $key = array_search( $handle[0], $this->queue, true ); 384 385 if ( false !== $key ) { 386 // Reset all dependencies so they must be recalculated in recurse_deps(). 387 $this->all_queued_deps = null; 388 389 unset( $this->queue[ $key ] ); 390 unset( $this->args[ $handle[0] ] ); 391 } elseif ( array_key_exists( $handle[0], $this->queued_before_register ) ) { 392 unset( $this->queued_before_register[ $handle[0] ] ); 393 } 394 } 395 } 396 397 /** 398 * Recursively search the passed dependency tree for a handle. 399 * 400 * @since 4.0.0 401 * 402 * @param string[] $queue An array of queued _WP_Dependency handles. 403 * @param string $handle Name of the item. Should be unique. 404 * @return bool Whether the handle is found after recursively searching the dependency tree. 405 */ 406 protected function recurse_deps( $queue, $handle ) { 407 if ( isset( $this->all_queued_deps ) ) { 408 return isset( $this->all_queued_deps[ $handle ] ); 409 } 410 411 $all_deps = array_fill_keys( $queue, true ); 412 $queues = array(); 413 $done = array(); 414 415 while ( $queue ) { 416 foreach ( $queue as $queued ) { 417 if ( ! isset( $done[ $queued ] ) && isset( $this->registered[ $queued ] ) ) { 418 $deps = $this->registered[ $queued ]->deps; 419 if ( $deps ) { 420 $all_deps += array_fill_keys( $deps, true ); 421 array_push( $queues, $deps ); 422 } 423 $done[ $queued ] = true; 424 } 425 } 426 $queue = array_pop( $queues ); 427 } 428 429 $this->all_queued_deps = $all_deps; 430 431 return isset( $this->all_queued_deps[ $handle ] ); 432 } 433 434 /** 435 * Query the list for an item. 436 * 437 * @since 2.1.0 438 * @since 2.6.0 Moved from `WP_Scripts`. 439 * 440 * @param string $handle Name of the item. Should be unique. 441 * @param string $status Optional. Status of the item to query. Default 'registered'. 442 * @return bool|_WP_Dependency Found, or object Item data. 443 */ 444 public function query( $handle, $status = 'registered' ) { 445 switch ( $status ) { 446 case 'registered': 447 case 'scripts': // Back compat. 448 if ( isset( $this->registered[ $handle ] ) ) { 449 return $this->registered[ $handle ]; 450 } 451 return false; 452 453 case 'enqueued': 454 case 'queue': // Back compat. 455 if ( in_array( $handle, $this->queue, true ) ) { 456 return true; 457 } 458 return $this->recurse_deps( $this->queue, $handle ); 459 460 case 'to_do': 461 case 'to_print': // Back compat. 462 return in_array( $handle, $this->to_do, true ); 463 464 case 'done': 465 case 'printed': // Back compat. 466 return in_array( $handle, $this->done, true ); 467 } 468 469 return false; 470 } 471 472 /** 473 * Set item group, unless already in a lower group. 474 * 475 * @since 2.8.0 476 * 477 * @param string $handle Name of the item. Should be unique. 478 * @param bool $recursion Internal flag that calling function was called recursively. 479 * @param int|false $group Group level: level (int), no group (false). 480 * @return bool Not already in the group or a lower group. 481 */ 482 public function set_group( $handle, $recursion, $group ) { 483 $group = (int) $group; 484 485 if ( isset( $this->groups[ $handle ] ) && $this->groups[ $handle ] <= $group ) { 486 return false; 487 } 488 489 $this->groups[ $handle ] = $group; 490 491 return true; 492 } 493 494 /** 495 * Get etag header for cache validation. 496 * 497 * @since 6.7.0 498 * 499 * @global string $wp_version The WordPress version string. 500 * 501 * @param string[] $load Array of script or style handles to load. 502 * @return string Etag header. 503 */ 504 public function get_etag( $load ) { 505 /* 506 * Note: wp_get_wp_version() is not used here, as this file can be included 507 * via wp-admin/load-scripts.php or wp-admin/load-styles.php, in which case 508 * wp-includes/functions.php is not loaded. 509 */ 510 global $wp_version; 511 512 $etag = "WP:{$wp_version};"; 513 514 foreach ( $load as $handle ) { 515 if ( ! array_key_exists( $handle, $this->registered ) ) { 516 continue; 517 } 518 519 $ver = $this->registered[ $handle ]->ver ?? $wp_version; 520 $etag .= "{$handle}:{$ver};"; 521 } 522 523 /* 524 * This is not intended to be cryptographically secure, just a fast way to get 525 * a fixed length string based on the script versions. As this file does not 526 * load the full WordPress environment, it is not possible to use the salted 527 * wp_hash() function. 528 */ 529 return 'W/"' . md5( $etag ) . '"'; 530 } 531 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated : Thu Nov 21 08:20:01 2024 | Cross-referenced by PHPXref |