functions.php 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. <?php
  2. require_once __DIR__ . '/class-basic-object.php';
  3. /**
  4. * Retrieves PHPUnit runner version.
  5. *
  6. * @return double The version number.
  7. */
  8. function tests_get_phpunit_version() {
  9. if ( class_exists( 'PHPUnit_Runner_Version' ) ) {
  10. $version = PHPUnit_Runner_Version::id();
  11. } elseif ( class_exists( 'PHPUnit\Runner\Version' ) ) {
  12. $version = PHPUnit\Runner\Version::id();
  13. } else {
  14. $version = 0;
  15. }
  16. return $version;
  17. }
  18. /**
  19. * Resets various `$_SERVER` variables that can get altered during tests.
  20. */
  21. function tests_reset__SERVER() { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.FunctionNameInvalid
  22. $_SERVER['HTTP_HOST'] = WP_TESTS_DOMAIN;
  23. $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
  24. $_SERVER['REQUEST_METHOD'] = 'GET';
  25. $_SERVER['REQUEST_URI'] = '';
  26. $_SERVER['SERVER_NAME'] = WP_TESTS_DOMAIN;
  27. $_SERVER['SERVER_PORT'] = '80';
  28. $_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.1';
  29. unset( $_SERVER['HTTP_REFERER'] );
  30. unset( $_SERVER['HTTPS'] );
  31. }
  32. /**
  33. * Adds hooks before loading WP.
  34. *
  35. * @see add_filter()
  36. *
  37. * @param string $tag The name of the filter to hook the $function_to_add callback to.
  38. * @param callable $function_to_add The callback to be run when the filter is applied.
  39. * @param int $priority Optional. Used to specify the order in which the functions
  40. * associated with a particular action are executed.
  41. * Lower numbers correspond with earlier execution,
  42. * and functions with the same priority are executed
  43. * in the order in which they were added to the action. Default 10.
  44. * @param int $accepted_args Optional. The number of arguments the function accepts. Default 1.
  45. * @return true
  46. */
  47. function tests_add_filter( $tag, $function_to_add, $priority = 10, $accepted_args = 1 ) {
  48. global $wp_filter;
  49. if ( function_exists( 'add_filter' ) ) {
  50. add_filter( $tag, $function_to_add, $priority, $accepted_args );
  51. } else {
  52. $idx = _test_filter_build_unique_id( $tag, $function_to_add, $priority );
  53. $wp_filter[ $tag ][ $priority ][ $idx ] = array(
  54. 'function' => $function_to_add,
  55. 'accepted_args' => $accepted_args,
  56. );
  57. }
  58. return true;
  59. }
  60. /**
  61. * Generates a unique function ID based on the given arguments.
  62. *
  63. * @see _wp_filter_build_unique_id()
  64. *
  65. * @param string $tag Unused. The name of the filter to build ID for.
  66. * @param callable $function The function to generate ID for.
  67. * @param int $priority Unused. The order in which the functions
  68. * associated with a particular action are executed.
  69. * @return string Unique function ID for usage as array key.
  70. */
  71. function _test_filter_build_unique_id( $tag, $function, $priority ) {
  72. if ( is_string( $function ) ) {
  73. return $function;
  74. }
  75. if ( is_object( $function ) ) {
  76. // Closures are currently implemented as objects.
  77. $function = array( $function, '' );
  78. } else {
  79. $function = (array) $function;
  80. }
  81. if ( is_object( $function[0] ) ) {
  82. // Object class calling.
  83. return spl_object_hash( $function[0] ) . $function[1];
  84. } elseif ( is_string( $function[0] ) ) {
  85. // Static calling.
  86. return $function[0] . '::' . $function[1];
  87. }
  88. }
  89. /**
  90. * Deletes all data from the database.
  91. */
  92. function _delete_all_data() {
  93. global $wpdb;
  94. foreach ( array(
  95. $wpdb->posts,
  96. $wpdb->postmeta,
  97. $wpdb->comments,
  98. $wpdb->commentmeta,
  99. $wpdb->term_relationships,
  100. $wpdb->termmeta,
  101. ) as $table ) {
  102. //phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
  103. $wpdb->query( "DELETE FROM {$table}" );
  104. }
  105. foreach ( array(
  106. $wpdb->terms,
  107. $wpdb->term_taxonomy,
  108. ) as $table ) {
  109. //phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
  110. $wpdb->query( "DELETE FROM {$table} WHERE term_id != 1" );
  111. }
  112. $wpdb->query( "UPDATE {$wpdb->term_taxonomy} SET count = 0" );
  113. $wpdb->query( "DELETE FROM {$wpdb->users} WHERE ID != 1" );
  114. $wpdb->query( "DELETE FROM {$wpdb->usermeta} WHERE user_id != 1" );
  115. }
  116. /**
  117. * Deletes all posts from the database.
  118. */
  119. function _delete_all_posts() {
  120. global $wpdb;
  121. $all_posts = $wpdb->get_results( "SELECT ID, post_type from {$wpdb->posts}", ARRAY_A );
  122. if ( ! $all_posts ) {
  123. return;
  124. }
  125. foreach ( $all_posts as $data ) {
  126. if ( 'attachment' === $data['post_type'] ) {
  127. wp_delete_attachment( $data['ID'], true );
  128. } else {
  129. wp_delete_post( $data['ID'], true );
  130. }
  131. }
  132. }
  133. /**
  134. * Handles the WP die handler by outputting the given values as text.
  135. *
  136. * @param string $message The message.
  137. * @param string $title The title.
  138. * @param array $args Array with arguments.
  139. */
  140. function _wp_die_handler( $message, $title = '', $args = array() ) {
  141. if ( ! $GLOBALS['_wp_die_disabled'] ) {
  142. _wp_die_handler_txt( $message, $title, $args );
  143. } else {
  144. // Ignore at our peril.
  145. }
  146. }
  147. /**
  148. * Disables the WP die handler.
  149. */
  150. function _disable_wp_die() {
  151. $GLOBALS['_wp_die_disabled'] = true;
  152. }
  153. /**
  154. * Enables the WP die handler.
  155. */
  156. function _enable_wp_die() {
  157. $GLOBALS['_wp_die_disabled'] = false;
  158. }
  159. /**
  160. * Returns the die handler.
  161. *
  162. * @return string The die handler.
  163. */
  164. function _wp_die_handler_filter() {
  165. return '_wp_die_handler';
  166. }
  167. /**
  168. * Returns the die handler.
  169. *
  170. * @return string The die handler.
  171. */
  172. function _wp_die_handler_filter_exit() {
  173. return '_wp_die_handler_exit';
  174. }
  175. /**
  176. * Dies without an exit.
  177. *
  178. * @param string $message The message.
  179. * @param string $title The title.
  180. * @param array $args Array with arguments.
  181. */
  182. function _wp_die_handler_txt( $message, $title, $args ) {
  183. echo "\nwp_die called\n";
  184. echo "Message: $message\n";
  185. if ( ! empty( $title ) ) {
  186. echo "Title: $title\n";
  187. }
  188. if ( ! empty( $args ) ) {
  189. echo "Args: \n";
  190. foreach ( $args as $k => $v ) {
  191. echo "\t $k : $v\n";
  192. }
  193. }
  194. }
  195. /**
  196. * Dies with an exit.
  197. *
  198. * @param string $message The message.
  199. * @param string $title The title.
  200. * @param array $args Array with arguments.
  201. */
  202. function _wp_die_handler_exit( $message, $title, $args ) {
  203. echo "\nwp_die called\n";
  204. echo "Message: $message\n";
  205. if ( ! empty( $title ) ) {
  206. echo "Title: $title\n";
  207. }
  208. if ( ! empty( $args ) ) {
  209. echo "Args: \n";
  210. foreach ( $args as $k => $v ) {
  211. echo "\t $k : $v\n";
  212. }
  213. }
  214. exit( 1 );
  215. }
  216. /**
  217. * Set a permalink structure.
  218. *
  219. * Hooked as a callback to the 'populate_options' action, we use this function to set a permalink structure during
  220. * `wp_install()`, so that WP doesn't attempt to do a time-consuming remote request.
  221. *
  222. * @since 4.2.0
  223. */
  224. function _set_default_permalink_structure_for_tests() {
  225. update_option( 'permalink_structure', '/%year%/%monthnum%/%day%/%postname%/' );
  226. }
  227. /**
  228. * Helper used with the `upload_dir` filter to remove the /year/month sub directories from the uploads path and URL.
  229. *
  230. * @return array The altered array.
  231. */
  232. function _upload_dir_no_subdir( $uploads ) {
  233. $subdir = $uploads['subdir'];
  234. $uploads['subdir'] = '';
  235. $uploads['path'] = str_replace( $subdir, '', $uploads['path'] );
  236. $uploads['url'] = str_replace( $subdir, '', $uploads['url'] );
  237. return $uploads;
  238. }
  239. /**
  240. * Helper used with the `upload_dir` filter to set https upload URL.
  241. *
  242. * @return array The altered array.
  243. */
  244. function _upload_dir_https( $uploads ) {
  245. $uploads['url'] = str_replace( 'http://', 'https://', $uploads['url'] );
  246. $uploads['baseurl'] = str_replace( 'http://', 'https://', $uploads['baseurl'] );
  247. return $uploads;
  248. }
  249. /**
  250. * Use the Spy_REST_Server class for the REST server.
  251. *
  252. * @return string The server class name.
  253. */
  254. function _wp_rest_server_class_filter() {
  255. return 'Spy_REST_Server';
  256. }
  257. // Skip `setcookie` calls in auth_cookie functions due to warning:
  258. // Cannot modify header information - headers already sent by...
  259. tests_add_filter( 'send_auth_cookies', '__return_false' );
  260. /**
  261. * After the init action has been run once, trying to re-register block types can cause
  262. * _doing_it_wrong warnings. To avoid this, unhook the block registration functions.
  263. *
  264. * @since 5.0.0
  265. */
  266. function _unhook_block_registration() {
  267. remove_action( 'init', 'register_block_core_archives' );
  268. remove_action( 'init', 'register_block_core_block' );
  269. remove_action( 'init', 'register_block_core_calendar' );
  270. remove_action( 'init', 'register_block_core_categories' );
  271. remove_action( 'init', 'register_block_core_latest_comments' );
  272. remove_action( 'init', 'register_block_core_latest_posts' );
  273. remove_action( 'init', 'register_block_core_rss' );
  274. remove_action( 'init', 'register_block_core_search' );
  275. remove_action( 'init', 'register_block_core_shortcode' );
  276. remove_action( 'init', 'register_block_core_social_link' );
  277. remove_action( 'init', 'register_block_core_social_link' );
  278. remove_action( 'init', 'register_block_core_tag_cloud' );
  279. remove_action( 'init', 'register_core_block_types_from_metadata' );
  280. }
  281. tests_add_filter( 'init', '_unhook_block_registration', 1000 );