/wp-includes/plugin.php

  1. <?php 
  2. /** 
  3. * The plugin API is located in this file, which allows for creating actions 
  4. * and filters and hooking functions, and methods. The functions or methods will 
  5. * then be run when the action or filter is called. 
  6. * 
  7. * The API callback examples reference functions, but can be methods of classes. 
  8. * To hook methods, you'll need to pass an array one of two ways. 
  9. * 
  10. * Any of the syntaxes explained in the PHP documentation for the 
  11. * {@link https://secure.php.net/manual/en/language.pseudo-types.php#language.types.callback 'callback'} 
  12. * type are valid. 
  13. * 
  14. * Also see the {@link https://codex.wordpress.org/Plugin_API Plugin API} for 
  15. * more information and examples on how to use a lot of these functions. 
  16. * 
  17. * @package WordPress 
  18. * @subpackage Plugin 
  19. * @since 1.5.0 
  20. */ 
  21.  
  22. // Initialize the filter globals. 
  23. global $wp_filter, $wp_actions, $merged_filters, $wp_current_filter; 
  24.  
  25. if ( ! isset( $wp_filter ) ) 
  26. $wp_filter = array(); 
  27.  
  28. if ( ! isset( $wp_actions ) ) 
  29. $wp_actions = array(); 
  30.  
  31. if ( ! isset( $merged_filters ) ) 
  32. $merged_filters = array(); 
  33.  
  34. if ( ! isset( $wp_current_filter ) ) 
  35. $wp_current_filter = array(); 
  36.  
  37. /** 
  38. * Hook a function or method to a specific filter action. 
  39. * 
  40. * WordPress offers filter hooks to allow plugins to modify 
  41. * various types of internal data at runtime. 
  42. * 
  43. * A plugin can modify data by binding a callback to a filter hook. When the filter 
  44. * is later applied, each bound callback is run in order of priority, and given 
  45. * the opportunity to modify a value by returning a new value. 
  46. * 
  47. * The following example shows how a callback function is bound to a filter hook. 
  48. * 
  49. * Note that `$example` is passed to the callback, (maybe) modified, then returned: 
  50. * 
  51. * function example_callback( $example ) { 
  52. * // Maybe modify $example in some way. 
  53. * return $example; 
  54. * } 
  55. * add_filter( 'example_filter', 'example_callback' ); 
  56. * 
  57. * Bound callbacks can accept from none to the total number of arguments passed as parameters 
  58. * in the corresponding apply_filters() call. 
  59. * 
  60. * In other words, if an apply_filters() call passes four total arguments, callbacks bound to 
  61. * it can accept none (the same as 1) of the arguments or up to four. The important part is that 
  62. * the `$accepted_args` value must reflect the number of arguments the bound callback *actually* 
  63. * opted to accept. If no arguments were accepted by the callback that is considered to be the 
  64. * same as accepting 1 argument. For example: 
  65. * 
  66. * // Filter call. 
  67. * $value = apply_filters( 'hook', $value, $arg2, $arg3 ); 
  68. * 
  69. * // Accepting zero/one arguments. 
  70. * function example_callback() { 
  71. * ... 
  72. * return 'some value'; 
  73. * } 
  74. * add_filter( 'hook', 'example_callback' ); // Where $priority is default 10, $accepted_args is default 1. 
  75. * 
  76. * // Accepting two arguments (three possible). 
  77. * function example_callback( $value, $arg2 ) { 
  78. * ... 
  79. * return $maybe_modified_value; 
  80. * } 
  81. * add_filter( 'hook', 'example_callback', 10, 2 ); // Where $priority is 10, $accepted_args is 2. 
  82. * 
  83. * *Note:* The function will return true whether or not the callback is valid. 
  84. * It is up to you to take care. This is done for optimization purposes, so 
  85. * everything is as quick as possible. 
  86. * 
  87. * @since 0.71 
  88. * 
  89. * @global array $wp_filter A multidimensional array of all hooks and the callbacks hooked to them. 
  90. * @global array $merged_filters Tracks the tags that need to be merged for later. If the hook is added,  
  91. * it doesn't need to run through that process. 
  92. * 
  93. * @param string $tag The name of the filter to hook the $function_to_add callback to. 
  94. * @param callable $function_to_add The callback to be run when the filter is applied. 
  95. * @param int $priority Optional. Used to specify the order in which the functions 
  96. * associated with a particular action are executed. Default 10. 
  97. * Lower numbers correspond with earlier execution,  
  98. * and functions with the same priority are executed 
  99. * in the order in which they were added to the action. 
  100. * @param int $accepted_args Optional. The number of arguments the function accepts. Default 1. 
  101. * @return true 
  102. */ 
  103. function add_filter( $tag, $function_to_add, $priority = 10, $accepted_args = 1 ) { 
  104. global $wp_filter, $merged_filters; 
  105.  
  106. $idx = _wp_filter_build_unique_id($tag, $function_to_add, $priority); 
  107. $wp_filter[$tag][$priority][$idx] = array('function' => $function_to_add, 'accepted_args' => $accepted_args); 
  108. unset( $merged_filters[ $tag ] ); 
  109. return true; 
  110.  
  111. /** 
  112. * Check if any filter has been registered for a hook. 
  113. * 
  114. * @since 2.5.0 
  115. * 
  116. * @global array $wp_filter Stores all of the filters. 
  117. * 
  118. * @param string $tag The name of the filter hook. 
  119. * @param callable|bool $function_to_check Optional. The callback to check for. Default false. 
  120. * @return false|int If $function_to_check is omitted, returns boolean for whether the hook has 
  121. * anything registered. When checking a specific function, the priority of that 
  122. * hook is returned, or false if the function is not attached. When using the 
  123. * $function_to_check argument, this function may return a non-boolean value 
  124. * that evaluates to false (e.g.) 0, so use the === operator for testing the 
  125. * return value. 
  126. */ 
  127. function has_filter($tag, $function_to_check = false) { 
  128. // Don't reset the internal array pointer 
  129. $wp_filter = $GLOBALS['wp_filter']; 
  130.  
  131. $has = ! empty( $wp_filter[ $tag ] ); 
  132.  
  133. // Make sure at least one priority has a filter callback 
  134. if ( $has ) { 
  135. $exists = false; 
  136. foreach ( $wp_filter[ $tag ] as $callbacks ) { 
  137. if ( ! empty( $callbacks ) ) { 
  138. $exists = true; 
  139. break; 
  140.  
  141. if ( ! $exists ) { 
  142. $has = false; 
  143.  
  144. if ( false === $function_to_check || false === $has ) 
  145. return $has; 
  146.  
  147. if ( !$idx = _wp_filter_build_unique_id($tag, $function_to_check, false) ) 
  148. return false; 
  149.  
  150. foreach ( (array) array_keys($wp_filter[$tag]) as $priority ) { 
  151. if ( isset($wp_filter[$tag][$priority][$idx]) ) 
  152. return $priority; 
  153.  
  154. return false; 
  155.  
  156. /** 
  157. * Call the functions added to a filter hook. 
  158. * 
  159. * The callback functions attached to filter hook $tag are invoked by calling 
  160. * this function. This function can be used to create a new filter hook by 
  161. * simply calling this function with the name of the new hook specified using 
  162. * the $tag parameter. 
  163. * 
  164. * The function allows for additional arguments to be added and passed to hooks. 
  165. * 
  166. * // Our filter callback function 
  167. * function example_callback( $string, $arg1, $arg2 ) { 
  168. * // (maybe) modify $string 
  169. * return $string; 
  170. * } 
  171. * add_filter( 'example_filter', 'example_callback', 10, 3 ); 
  172. * 
  173. * /** 
  174. * * Apply the filters by calling the 'example_callback' function we 
  175. * * "hooked" to 'example_filter' using the add_filter() function above. 
  176. * * - 'example_filter' is the filter hook $tag 
  177. * * - 'filter me' is the value being filtered 
  178. * * - $arg1 and $arg2 are the additional arguments passed to the callback. 
  179. * $value = apply_filters( 'example_filter', 'filter me', $arg1, $arg2 ); 
  180. * 
  181. * @since 0.71 
  182. * 
  183. * @global array $wp_filter Stores all of the filters. 
  184. * @global array $merged_filters Merges the filter hooks using this function. 
  185. * @global array $wp_current_filter Stores the list of current filters with the current one last. 
  186. * 
  187. * @param string $tag The name of the filter hook. 
  188. * @param mixed $value The value on which the filters hooked to `$tag` are applied on. 
  189. * @param mixed $var, ... Additional variables passed to the functions hooked to `$tag`. 
  190. * @return mixed The filtered value after all hooked functions are applied to it. 
  191. */ 
  192. function apply_filters( $tag, $value ) { 
  193. global $wp_filter, $merged_filters, $wp_current_filter; 
  194.  
  195. $args = array(); 
  196.  
  197. // Do 'all' actions first. 
  198. if ( isset($wp_filter['all']) ) { 
  199. $wp_current_filter[] = $tag; 
  200. $args = func_get_args(); 
  201. _wp_call_all_hook($args); 
  202.  
  203. if ( !isset($wp_filter[$tag]) ) { 
  204. if ( isset($wp_filter['all']) ) 
  205. array_pop($wp_current_filter); 
  206. return $value; 
  207.  
  208. if ( !isset($wp_filter['all']) ) 
  209. $wp_current_filter[] = $tag; 
  210.  
  211. // Sort. 
  212. if ( !isset( $merged_filters[ $tag ] ) ) { 
  213. ksort($wp_filter[$tag]); 
  214. $merged_filters[ $tag ] = true; 
  215.  
  216. reset( $wp_filter[ $tag ] ); 
  217.  
  218. if ( empty($args) ) 
  219. $args = func_get_args(); 
  220.  
  221. do { 
  222. foreach ( (array) current($wp_filter[$tag]) as $the_ ) 
  223. if ( !is_null($the_['function']) ) { 
  224. $args[1] = $value; 
  225. $value = call_user_func_array($the_['function'], array_slice($args, 1, (int) $the_['accepted_args'])); 
  226.  
  227. } while ( next($wp_filter[$tag]) !== false ); 
  228.  
  229. array_pop( $wp_current_filter ); 
  230.  
  231. return $value; 
  232.  
  233. /** 
  234. * Execute functions hooked on a specific filter hook, specifying arguments in an array. 
  235. * 
  236. * @since 3.0.0 
  237. * 
  238. * @see apply_filters() This function is identical, but the arguments passed to the 
  239. * functions hooked to `$tag` are supplied using an array. 
  240. * 
  241. * @global array $wp_filter Stores all of the filters 
  242. * @global array $merged_filters Merges the filter hooks using this function. 
  243. * @global array $wp_current_filter Stores the list of current filters with the current one last 
  244. * 
  245. * @param string $tag The name of the filter hook. 
  246. * @param array $args The arguments supplied to the functions hooked to $tag. 
  247. * @return mixed The filtered value after all hooked functions are applied to it. 
  248. */ 
  249. function apply_filters_ref_array($tag, $args) { 
  250. global $wp_filter, $merged_filters, $wp_current_filter; 
  251.  
  252. // Do 'all' actions first 
  253. if ( isset($wp_filter['all']) ) { 
  254. $wp_current_filter[] = $tag; 
  255. $all_args = func_get_args(); 
  256. _wp_call_all_hook($all_args); 
  257.  
  258. if ( !isset($wp_filter[$tag]) ) { 
  259. if ( isset($wp_filter['all']) ) 
  260. array_pop($wp_current_filter); 
  261. return $args[0]; 
  262.  
  263. if ( !isset($wp_filter['all']) ) 
  264. $wp_current_filter[] = $tag; 
  265.  
  266. // Sort 
  267. if ( !isset( $merged_filters[ $tag ] ) ) { 
  268. ksort($wp_filter[$tag]); 
  269. $merged_filters[ $tag ] = true; 
  270.  
  271. reset( $wp_filter[ $tag ] ); 
  272.  
  273. do { 
  274. foreach ( (array) current($wp_filter[$tag]) as $the_ ) 
  275. if ( !is_null($the_['function']) ) 
  276. $args[0] = call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args'])); 
  277.  
  278. } while ( next($wp_filter[$tag]) !== false ); 
  279.  
  280. array_pop( $wp_current_filter ); 
  281.  
  282. return $args[0]; 
  283.  
  284. /** 
  285. * Removes a function from a specified filter hook. 
  286. * 
  287. * This function removes a function attached to a specified filter hook. This 
  288. * method can be used to remove default functions attached to a specific filter 
  289. * hook and possibly replace them with a substitute. 
  290. * 
  291. * To remove a hook, the $function_to_remove and $priority arguments must match 
  292. * when the hook was added. This goes for both filters and actions. No warning 
  293. * will be given on removal failure. 
  294. * 
  295. * @since 1.2.0 
  296. * 
  297. * @global array $wp_filter Stores all of the filters 
  298. * @global array $merged_filters Merges the filter hooks using this function. 
  299. * 
  300. * @param string $tag The filter hook to which the function to be removed is hooked. 
  301. * @param callable $function_to_remove The name of the function which should be removed. 
  302. * @param int $priority Optional. The priority of the function. Default 10. 
  303. * @return bool Whether the function existed before it was removed. 
  304. */ 
  305. function remove_filter( $tag, $function_to_remove, $priority = 10 ) { 
  306. $function_to_remove = _wp_filter_build_unique_id( $tag, $function_to_remove, $priority ); 
  307.  
  308. $r = isset( $GLOBALS['wp_filter'][ $tag ][ $priority ][ $function_to_remove ] ); 
  309.  
  310. if ( true === $r ) { 
  311. unset( $GLOBALS['wp_filter'][ $tag ][ $priority ][ $function_to_remove ] ); 
  312. if ( empty( $GLOBALS['wp_filter'][ $tag ][ $priority ] ) ) { 
  313. unset( $GLOBALS['wp_filter'][ $tag ][ $priority ] ); 
  314. if ( empty( $GLOBALS['wp_filter'][ $tag ] ) ) { 
  315. $GLOBALS['wp_filter'][ $tag ] = array(); 
  316. unset( $GLOBALS['merged_filters'][ $tag ] ); 
  317.  
  318. return $r; 
  319.  
  320. /** 
  321. * Remove all of the hooks from a filter. 
  322. * 
  323. * @since 2.7.0 
  324. * 
  325. * @global array $wp_filter Stores all of the filters 
  326. * @global array $merged_filters Merges the filter hooks using this function. 
  327. * 
  328. * @param string $tag The filter to remove hooks from. 
  329. * @param int|bool $priority Optional. The priority number to remove. Default false. 
  330. * @return true True when finished. 
  331. */ 
  332. function remove_all_filters( $tag, $priority = false ) { 
  333. global $wp_filter, $merged_filters; 
  334.  
  335. if ( isset( $wp_filter[ $tag ]) ) { 
  336. if ( false === $priority ) { 
  337. $wp_filter[ $tag ] = array(); 
  338. } elseif ( isset( $wp_filter[ $tag ][ $priority ] ) ) { 
  339. $wp_filter[ $tag ][ $priority ] = array(); 
  340.  
  341. unset( $merged_filters[ $tag ] ); 
  342.  
  343. return true; 
  344.  
  345. /** 
  346. * Retrieve the name of the current filter or action. 
  347. * 
  348. * @since 2.5.0 
  349. * 
  350. * @global array $wp_current_filter Stores the list of current filters with the current one last 
  351. * 
  352. * @return string Hook name of the current filter or action. 
  353. */ 
  354. function current_filter() { 
  355. global $wp_current_filter; 
  356. return end( $wp_current_filter ); 
  357.  
  358. /** 
  359. * Retrieve the name of the current action. 
  360. * 
  361. * @since 3.9.0 
  362. * 
  363. * @return string Hook name of the current action. 
  364. */ 
  365. function current_action() { 
  366. return current_filter(); 
  367.  
  368. /** 
  369. * Retrieve the name of a filter currently being processed. 
  370. * 
  371. * The function current_filter() only returns the most recent filter or action 
  372. * being executed. did_action() returns true once the action is initially 
  373. * processed. 
  374. * 
  375. * This function allows detection for any filter currently being 
  376. * executed (despite not being the most recent filter to fire, in the case of 
  377. * hooks called from hook callbacks) to be verified. 
  378. * 
  379. * @since 3.9.0 
  380. * 
  381. * @see current_filter() 
  382. * @see did_action() 
  383. * @global array $wp_current_filter Current filter. 
  384. * 
  385. * @param null|string $filter Optional. Filter to check. Defaults to null, which 
  386. * checks if any filter is currently being run. 
  387. * @return bool Whether the filter is currently in the stack. 
  388. */ 
  389. function doing_filter( $filter = null ) { 
  390. global $wp_current_filter; 
  391.  
  392. if ( null === $filter ) { 
  393. return ! empty( $wp_current_filter ); 
  394.  
  395. return in_array( $filter, $wp_current_filter ); 
  396.  
  397. /** 
  398. * Retrieve the name of an action currently being processed. 
  399. * 
  400. * @since 3.9.0 
  401. * 
  402. * @param string|null $action Optional. Action to check. Defaults to null, which checks 
  403. * if any action is currently being run. 
  404. * @return bool Whether the action is currently in the stack. 
  405. */ 
  406. function doing_action( $action = null ) { 
  407. return doing_filter( $action ); 
  408.  
  409. /** 
  410. * Hooks a function on to a specific action. 
  411. * 
  412. * Actions are the hooks that the WordPress core launches at specific points 
  413. * during execution, or when specific events occur. Plugins can specify that 
  414. * one or more of its PHP functions are executed at these points, using the 
  415. * Action API. 
  416. * 
  417. * @since 1.2.0 
  418. * 
  419. * @param string $tag The name of the action to which the $function_to_add is hooked. 
  420. * @param callable $function_to_add The name of the function you wish to be called. 
  421. * @param int $priority Optional. Used to specify the order in which the functions 
  422. * associated with a particular action are executed. Default 10. 
  423. * Lower numbers correspond with earlier execution,  
  424. * and functions with the same priority are executed 
  425. * in the order in which they were added to the action. 
  426. * @param int $accepted_args Optional. The number of arguments the function accepts. Default 1. 
  427. * @return true Will always return true. 
  428. */ 
  429. function add_action($tag, $function_to_add, $priority = 10, $accepted_args = 1) { 
  430. return add_filter($tag, $function_to_add, $priority, $accepted_args); 
  431.  
  432. /** 
  433. * Execute functions hooked on a specific action hook. 
  434. * 
  435. * This function invokes all functions attached to action hook `$tag`. It is 
  436. * possible to create new action hooks by simply calling this function,  
  437. * specifying the name of the new hook using the `$tag` parameter. 
  438. * 
  439. * You can pass extra arguments to the hooks, much like you can with apply_filters(). 
  440. * 
  441. * @since 1.2.0 
  442. * 
  443. * @global array $wp_filter Stores all of the filters 
  444. * @global array $wp_actions Increments the amount of times action was triggered. 
  445. * @global array $merged_filters Merges the filter hooks using this function. 
  446. * @global array $wp_current_filter Stores the list of current filters with the current one last 
  447. * 
  448. * @param string $tag The name of the action to be executed. 
  449. * @param mixed $arg, ... Optional. Additional arguments which are passed on to the 
  450. * functions hooked to the action. Default empty. 
  451. */ 
  452. function do_action($tag, $arg = '') { 
  453. global $wp_filter, $wp_actions, $merged_filters, $wp_current_filter; 
  454.  
  455. if ( ! isset($wp_actions[$tag]) ) 
  456. $wp_actions[$tag] = 1; 
  457. else 
  458. ++$wp_actions[$tag]; 
  459.  
  460. // Do 'all' actions first 
  461. if ( isset($wp_filter['all']) ) { 
  462. $wp_current_filter[] = $tag; 
  463. $all_args = func_get_args(); 
  464. _wp_call_all_hook($all_args); 
  465.  
  466. if ( !isset($wp_filter[$tag]) ) { 
  467. if ( isset($wp_filter['all']) ) 
  468. array_pop($wp_current_filter); 
  469. return; 
  470.  
  471. if ( !isset($wp_filter['all']) ) 
  472. $wp_current_filter[] = $tag; 
  473.  
  474. $args = array(); 
  475. if ( is_array($arg) && 1 == count($arg) && isset($arg[0]) && is_object($arg[0]) ) // array(&$this) 
  476. $args[] =& $arg[0]; 
  477. else 
  478. $args[] = $arg; 
  479. for ( $a = 2, $num = func_num_args(); $a < $num; $a++ ) 
  480. $args[] = func_get_arg($a); 
  481.  
  482. // Sort 
  483. if ( !isset( $merged_filters[ $tag ] ) ) { 
  484. ksort($wp_filter[$tag]); 
  485. $merged_filters[ $tag ] = true; 
  486.  
  487. reset( $wp_filter[ $tag ] ); 
  488.  
  489. do { 
  490. foreach ( (array) current($wp_filter[$tag]) as $the_ ) 
  491. if ( !is_null($the_['function']) ) 
  492. call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args'])); 
  493.  
  494. } while ( next($wp_filter[$tag]) !== false ); 
  495.  
  496. array_pop($wp_current_filter); 
  497.  
  498. /** 
  499. * Retrieve the number of times an action is fired. 
  500. * 
  501. * @since 2.1.0 
  502. * 
  503. * @global array $wp_actions Increments the amount of times action was triggered. 
  504. * 
  505. * @param string $tag The name of the action hook. 
  506. * @return int The number of times action hook $tag is fired. 
  507. */ 
  508. function did_action($tag) { 
  509. global $wp_actions; 
  510.  
  511. if ( ! isset( $wp_actions[ $tag ] ) ) 
  512. return 0; 
  513.  
  514. return $wp_actions[$tag]; 
  515.  
  516. /** 
  517. * Execute functions hooked on a specific action hook, specifying arguments in an array. 
  518. * 
  519. * @since 2.1.0 
  520. * 
  521. * @see do_action() This function is identical, but the arguments passed to the 
  522. * functions hooked to $tag< are supplied using an array. 
  523. * @global array $wp_filter Stores all of the filters 
  524. * @global array $wp_actions Increments the amount of times action was triggered. 
  525. * @global array $merged_filters Merges the filter hooks using this function. 
  526. * @global array $wp_current_filter Stores the list of current filters with the current one last 
  527. * 
  528. * @param string $tag The name of the action to be executed. 
  529. * @param array $args The arguments supplied to the functions hooked to `$tag`. 
  530. */ 
  531. function do_action_ref_array($tag, $args) { 
  532. global $wp_filter, $wp_actions, $merged_filters, $wp_current_filter; 
  533.  
  534. if ( ! isset($wp_actions[$tag]) ) 
  535. $wp_actions[$tag] = 1; 
  536. else 
  537. ++$wp_actions[$tag]; 
  538.  
  539. // Do 'all' actions first 
  540. if ( isset($wp_filter['all']) ) { 
  541. $wp_current_filter[] = $tag; 
  542. $all_args = func_get_args(); 
  543. _wp_call_all_hook($all_args); 
  544.  
  545. if ( !isset($wp_filter[$tag]) ) { 
  546. if ( isset($wp_filter['all']) ) 
  547. array_pop($wp_current_filter); 
  548. return; 
  549.  
  550. if ( !isset($wp_filter['all']) ) 
  551. $wp_current_filter[] = $tag; 
  552.  
  553. // Sort 
  554. if ( !isset( $merged_filters[ $tag ] ) ) { 
  555. ksort($wp_filter[$tag]); 
  556. $merged_filters[ $tag ] = true; 
  557.  
  558. reset( $wp_filter[ $tag ] ); 
  559.  
  560. do { 
  561. foreach ( (array) current($wp_filter[$tag]) as $the_ ) 
  562. if ( !is_null($the_['function']) ) 
  563. call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args'])); 
  564.  
  565. } while ( next($wp_filter[$tag]) !== false ); 
  566.  
  567. array_pop($wp_current_filter); 
  568.  
  569. /** 
  570. * Check if any action has been registered for a hook. 
  571. * 
  572. * @since 2.5.0 
  573. * 
  574. * @see has_filter() has_action() is an alias of has_filter(). 
  575. * 
  576. * @param string $tag The name of the action hook. 
  577. * @param callable|bool $function_to_check Optional. The callback to check for. Default false. 
  578. * @return bool|int If $function_to_check is omitted, returns boolean for whether the hook has 
  579. * anything registered. When checking a specific function, the priority of that 
  580. * hook is returned, or false if the function is not attached. When using the 
  581. * $function_to_check argument, this function may return a non-boolean value 
  582. * that evaluates to false (e.g.) 0, so use the === operator for testing the 
  583. * return value. 
  584. */ 
  585. function has_action($tag, $function_to_check = false) { 
  586. return has_filter($tag, $function_to_check); 
  587.  
  588. /** 
  589. * Removes a function from a specified action hook. 
  590. * 
  591. * This function removes a function attached to a specified action hook. This 
  592. * method can be used to remove default functions attached to a specific filter 
  593. * hook and possibly replace them with a substitute. 
  594. * 
  595. * @since 1.2.0 
  596. * 
  597. * @param string $tag The action hook to which the function to be removed is hooked. 
  598. * @param callable $function_to_remove The name of the function which should be removed. 
  599. * @param int $priority Optional. The priority of the function. Default 10. 
  600. * @return bool Whether the function is removed. 
  601. */ 
  602. function remove_action( $tag, $function_to_remove, $priority = 10 ) { 
  603. return remove_filter( $tag, $function_to_remove, $priority ); 
  604.  
  605. /** 
  606. * Remove all of the hooks from an action. 
  607. * 
  608. * @since 2.7.0 
  609. * 
  610. * @param string $tag The action to remove hooks from. 
  611. * @param int|bool $priority The priority number to remove them from. Default false. 
  612. * @return true True when finished. 
  613. */ 
  614. function remove_all_actions($tag, $priority = false) { 
  615. return remove_all_filters($tag, $priority); 
  616.  
  617. /** 
  618. * Fires functions attached to a deprecated filter hook. 
  619. * 
  620. * When a filter hook is deprecated, the apply_filters() call is replaced with 
  621. * apply_filters_deprecated(), which triggers a deprecation notice and then fires 
  622. * the original filter hook. 
  623. * 
  624. * @since 4.6.0 
  625. * 
  626. * @see _deprecated_hook() 
  627. * 
  628. * @param string $tag The name of the filter hook. 
  629. * @param array $args Array of additional function arguments to be passed to apply_filters(). 
  630. * @param string $version The version of WordPress that deprecated the hook. 
  631. * @param string $replacement Optional. The hook that should have been used. Default false. 
  632. * @param string $message Optional. A message regarding the change. Default null. 
  633. */ 
  634. function apply_filters_deprecated( $tag, $args, $version, $replacement = false, $message = null ) { 
  635. if ( ! has_filter( $tag ) ) { 
  636. return $args[0]; 
  637.  
  638. _deprecated_hook( $tag, $version, $replacement, $message ); 
  639.  
  640. return apply_filters_ref_array( $tag, $args ); 
  641.  
  642. /** 
  643. * Fires functions attached to a deprecated action hook. 
  644. * 
  645. * When an action hook is deprecated, the do_action() call is replaced with 
  646. * do_action_deprecated(), which triggers a deprecation notice and then fires 
  647. * the original hook. 
  648. * 
  649. * @since 4.6.0 
  650. * 
  651. * @see _deprecated_hook() 
  652. * 
  653. * @param string $tag The name of the action hook. 
  654. * @param array $args Array of additional function arguments to be passed to do_action(). 
  655. * @param string $version The version of WordPress that deprecated the hook. 
  656. * @param string $replacement Optional. The hook that should have been used. 
  657. * @param string $message Optional. A message regarding the change. 
  658. */ 
  659. function do_action_deprecated( $tag, $args, $version, $replacement = false, $message = null ) { 
  660. if ( ! has_action( $tag ) ) { 
  661. return; 
  662.  
  663. _deprecated_hook( $tag, $version, $replacement, $message ); 
  664.  
  665. do_action_ref_array( $tag, $args ); 
  666.  
  667. // 
  668. // Functions for handling plugins. 
  669. // 
  670.   
  671. /** 
  672. * Gets the basename of a plugin. 
  673. * 
  674. * This method extracts the name of a plugin from its filename. 
  675. * 
  676. * @since 1.5.0 
  677. * 
  678. * @global array $wp_plugin_paths 
  679. * 
  680. * @param string $file The filename of plugin. 
  681. * @return string The name of a plugin. 
  682. */ 
  683. function plugin_basename( $file ) { 
  684. global $wp_plugin_paths; 
  685.  
  686. // $wp_plugin_paths contains normalized paths. 
  687. $file = wp_normalize_path( $file ); 
  688.  
  689. arsort( $wp_plugin_paths ); 
  690. foreach ( $wp_plugin_paths as $dir => $realdir ) { 
  691. if ( strpos( $file, $realdir ) === 0 ) { 
  692. $file = $dir . substr( $file, strlen( $realdir ) ); 
  693.  
  694. $plugin_dir = wp_normalize_path( WP_PLUGIN_DIR ); 
  695. $mu_plugin_dir = wp_normalize_path( WPMU_PLUGIN_DIR ); 
  696.  
  697. $file = preg_replace('#^' . preg_quote($plugin_dir, '#') . '/|^' . preg_quote($mu_plugin_dir, '#') . '/#', '', $file); // get relative path from plugins dir 
  698. $file = trim($file, '/'); 
  699. return $file; 
  700.  
  701. /** 
  702. * Register a plugin's real path. 
  703. * 
  704. * This is used in plugin_basename() to resolve symlinked paths. 
  705. * 
  706. * @since 3.9.0 
  707. * 
  708. * @see wp_normalize_path() 
  709. * 
  710. * @global array $wp_plugin_paths 
  711. * 
  712. * @staticvar string $wp_plugin_path 
  713. * @staticvar string $wpmu_plugin_path 
  714. * 
  715. * @param string $file Known path to the file. 
  716. * @return bool Whether the path was able to be registered. 
  717. */ 
  718. function wp_register_plugin_realpath( $file ) { 
  719. global $wp_plugin_paths; 
  720.  
  721. // Normalize, but store as static to avoid recalculation of a constant value 
  722. static $wp_plugin_path = null, $wpmu_plugin_path = null; 
  723. if ( ! isset( $wp_plugin_path ) ) { 
  724. $wp_plugin_path = wp_normalize_path( WP_PLUGIN_DIR ); 
  725. $wpmu_plugin_path = wp_normalize_path( WPMU_PLUGIN_DIR ); 
  726.  
  727. $plugin_path = wp_normalize_path( dirname( $file ) ); 
  728. $plugin_realpath = wp_normalize_path( dirname( realpath( $file ) ) ); 
  729.  
  730. if ( $plugin_path === $wp_plugin_path || $plugin_path === $wpmu_plugin_path ) { 
  731. return false; 
  732.  
  733. if ( $plugin_path !== $plugin_realpath ) { 
  734. $wp_plugin_paths[ $plugin_path ] = $plugin_realpath; 
  735.  
  736. return true; 
  737.  
  738. /** 
  739. * Get the filesystem directory path (with trailing slash) for the plugin __FILE__ passed in. 
  740. * 
  741. * @since 2.8.0 
  742. * 
  743. * @param string $file The filename of the plugin (__FILE__). 
  744. * @return string the filesystem path of the directory that contains the plugin. 
  745. */ 
  746. function plugin_dir_path( $file ) { 
  747. return trailingslashit( dirname( $file ) ); 
  748.  
  749. /** 
  750. * Get the URL directory path (with trailing slash) for the plugin __FILE__ passed in. 
  751. * 
  752. * @since 2.8.0 
  753. * 
  754. * @param string $file The filename of the plugin (__FILE__). 
  755. * @return string the URL path of the directory that contains the plugin. 
  756. */ 
  757. function plugin_dir_url( $file ) { 
  758. return trailingslashit( plugins_url( '', $file ) ); 
  759.  
  760. /** 
  761. * Set the activation hook for a plugin. 
  762. * 
  763. * When a plugin is activated, the action 'activate_PLUGINNAME' hook is 
  764. * called. In the name of this hook, PLUGINNAME is replaced with the name 
  765. * of the plugin, including the optional subdirectory. For example, when the 
  766. * plugin is located in wp-content/plugins/sampleplugin/sample.php, then 
  767. * the name of this hook will become 'activate_sampleplugin/sample.php'. 
  768. * 
  769. * When the plugin consists of only one file and is (as by default) located at 
  770. * wp-content/plugins/sample.php the name of this hook will be 
  771. * 'activate_sample.php'. 
  772. * 
  773. * @since 2.0.0 
  774. * 
  775. * @param string $file The filename of the plugin including the path. 
  776. * @param callable $function The function hooked to the 'activate_PLUGIN' action. 
  777. */ 
  778. function register_activation_hook($file, $function) { 
  779. $file = plugin_basename($file); 
  780. add_action('activate_' . $file, $function); 
  781.  
  782. /** 
  783. * Set the deactivation hook for a plugin. 
  784. * 
  785. * When a plugin is deactivated, the action 'deactivate_PLUGINNAME' hook is 
  786. * called. In the name of this hook, PLUGINNAME is replaced with the name 
  787. * of the plugin, including the optional subdirectory. For example, when the 
  788. * plugin is located in wp-content/plugins/sampleplugin/sample.php, then 
  789. * the name of this hook will become 'deactivate_sampleplugin/sample.php'. 
  790. * 
  791. * When the plugin consists of only one file and is (as by default) located at 
  792. * wp-content/plugins/sample.php the name of this hook will be 
  793. * 'deactivate_sample.php'. 
  794. * 
  795. * @since 2.0.0 
  796. * 
  797. * @param string $file The filename of the plugin including the path. 
  798. * @param callable $function The function hooked to the 'deactivate_PLUGIN' action. 
  799. */ 
  800. function register_deactivation_hook($file, $function) { 
  801. $file = plugin_basename($file); 
  802. add_action('deactivate_' . $file, $function); 
  803.  
  804. /** 
  805. * Set the uninstallation hook for a plugin. 
  806. * 
  807. * Registers the uninstall hook that will be called when the user clicks on the 
  808. * uninstall link that calls for the plugin to uninstall itself. The link won't 
  809. * be active unless the plugin hooks into the action. 
  810. * 
  811. * The plugin should not run arbitrary code outside of functions, when 
  812. * registering the uninstall hook. In order to run using the hook, the plugin 
  813. * will have to be included, which means that any code laying outside of a 
  814. * function will be run during the uninstall process. The plugin should not 
  815. * hinder the uninstall process. 
  816. * 
  817. * If the plugin can not be written without running code within the plugin, then 
  818. * the plugin should create a file named 'uninstall.php' in the base plugin 
  819. * folder. This file will be called, if it exists, during the uninstall process 
  820. * bypassing the uninstall hook. The plugin, when using the 'uninstall.php' 
  821. * should always check for the 'WP_UNINSTALL_PLUGIN' constant, before 
  822. * executing. 
  823. * 
  824. * @since 2.7.0 
  825. * 
  826. * @param string $file Plugin file. 
  827. * @param callable $callback The callback to run when the hook is called. Must be 
  828. * a static method or function. 
  829. */ 
  830. function register_uninstall_hook( $file, $callback ) { 
  831. if ( is_array( $callback ) && is_object( $callback[0] ) ) { 
  832. _doing_it_wrong( __FUNCTION__, __( 'Only a static class method or function can be used in an uninstall hook.' ), '3.1.0' ); 
  833. return; 
  834.  
  835. /** 
  836. * The option should not be autoloaded, because it is not needed in most 
  837. * cases. Emphasis should be put on using the 'uninstall.php' way of 
  838. * uninstalling the plugin. 
  839. */ 
  840. $uninstallable_plugins = (array) get_option('uninstall_plugins'); 
  841. $uninstallable_plugins[plugin_basename($file)] = $callback; 
  842.  
  843. update_option('uninstall_plugins', $uninstallable_plugins); 
  844.  
  845. /** 
  846. * Call the 'all' hook, which will process the functions hooked into it. 
  847. * 
  848. * The 'all' hook passes all of the arguments or parameters that were used for 
  849. * the hook, which this function was called for. 
  850. * 
  851. * This function is used internally for apply_filters(), do_action(), and 
  852. * do_action_ref_array() and is not meant to be used from outside those 
  853. * functions. This function does not check for the existence of the all hook, so 
  854. * it will fail unless the all hook exists prior to this function call. 
  855. * 
  856. * @since 2.5.0 
  857. * @access private 
  858. * 
  859. * @global array $wp_filter Stores all of the filters 
  860. * 
  861. * @param array $args The collected parameters from the hook that was called. 
  862. */ 
  863. function _wp_call_all_hook($args) { 
  864. global $wp_filter; 
  865.  
  866. reset( $wp_filter['all'] ); 
  867. do { 
  868. foreach ( (array) current($wp_filter['all']) as $the_ ) 
  869. if ( !is_null($the_['function']) ) 
  870. call_user_func_array($the_['function'], $args); 
  871.  
  872. } while ( next($wp_filter['all']) !== false ); 
  873.  
  874. /** 
  875. * Build Unique ID for storage and retrieval. 
  876. * 
  877. * The old way to serialize the callback caused issues and this function is the 
  878. * solution. It works by checking for objects and creating a new property in 
  879. * the class to keep track of the object and new objects of the same class that 
  880. * need to be added. 
  881. * 
  882. * It also allows for the removal of actions and filters for objects after they 
  883. * change class properties. It is possible to include the property $wp_filter_id 
  884. * in your class and set it to "null" or a number to bypass the workaround. 
  885. * However this will prevent you from adding new classes and any new classes 
  886. * will overwrite the previous hook by the same class. 
  887. * 
  888. * Functions and static method callbacks are just returned as strings and 
  889. * shouldn't have any speed penalty. 
  890. * 
  891. * @link https://core.trac.wordpress.org/ticket/3875 
  892. * 
  893. * @since 2.2.3 
  894. * @access private 
  895. * 
  896. * @global array $wp_filter Storage for all of the filters and actions. 
  897. * @staticvar int $filter_id_count 
  898. * 
  899. * @param string $tag Used in counting how many hooks were applied 
  900. * @param callable $function Used for creating unique id 
  901. * @param int|bool $priority Used in counting how many hooks were applied. If === false 
  902. * and $function is an object reference, we return the unique 
  903. * id only if it already has one, false otherwise. 
  904. * @return string|false Unique ID for usage as array key or false if $priority === false 
  905. * and $function is an object reference, and it does not already have 
  906. * a unique id. 
  907. */ 
  908. function _wp_filter_build_unique_id($tag, $function, $priority) { 
  909. global $wp_filter; 
  910. static $filter_id_count = 0; 
  911.  
  912. if ( is_string($function) ) 
  913. return $function; 
  914.  
  915. if ( is_object($function) ) { 
  916. // Closures are currently implemented as objects 
  917. $function = array( $function, '' ); 
  918. } else { 
  919. $function = (array) $function; 
  920.  
  921. if (is_object($function[0]) ) { 
  922. // Object Class Calling 
  923. if ( function_exists('spl_object_hash') ) { 
  924. return spl_object_hash($function[0]) . $function[1]; 
  925. } else { 
  926. $obj_idx = get_class($function[0]).$function[1]; 
  927. if ( !isset($function[0]->wp_filter_id) ) { 
  928. if ( false === $priority ) 
  929. return false; 
  930. $obj_idx .= isset($wp_filter[$tag][$priority]) ? count((array)$wp_filter[$tag][$priority]) : $filter_id_count; 
  931. $function[0]->wp_filter_id = $filter_id_count; 
  932. ++$filter_id_count; 
  933. } else { 
  934. $obj_idx .= $function[0]->wp_filter_id; 
  935.  
  936. return $obj_idx; 
  937. } elseif ( is_string( $function[0] ) ) { 
  938. // Static Calling 
  939. return $function[0] . '::' . $function[1]; 
.