class-handle-404.php 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. <?php
  2. /**
  3. * WPSEO plugin file.
  4. *
  5. * @package WPSEO\Frontend
  6. */
  7. /**
  8. * Class WPSEO_Handle_404
  9. *
  10. * Handles intercepting requests.
  11. *
  12. * @since 9.4
  13. */
  14. class WPSEO_Handle_404 implements WPSEO_WordPress_Integration {
  15. /**
  16. * Registers all hooks to WordPress.
  17. *
  18. * @return void
  19. */
  20. public function register_hooks() {
  21. add_filter( 'pre_handle_404', [ $this, 'handle_404' ] );
  22. }
  23. /**
  24. * Handle the 404 status code.
  25. *
  26. * @param bool $handled Whether we've handled the request.
  27. *
  28. * @return bool True if it's 404.
  29. */
  30. public function handle_404( $handled ) {
  31. if ( is_feed() ) {
  32. return $this->is_feed_404( $handled );
  33. }
  34. return $handled;
  35. }
  36. /**
  37. * If there are no posts in a feed, make it 404 instead of sending an empty RSS feed.
  38. *
  39. * @global WP_Query $wp_query
  40. *
  41. * @param bool $handled Whether we've handled the request.
  42. *
  43. * @return bool True if it's 404.
  44. */
  45. protected function is_feed_404( $handled ) {
  46. global $wp_query;
  47. // Don't 404 if the query contains post(s) or an object.
  48. if ( $wp_query->posts || $wp_query->get_queried_object() ) {
  49. return $handled;
  50. }
  51. // Don't 404 if it isn't archive or singular.
  52. if ( ! $wp_query->is_archive() && ! $wp_query->is_singular() ) {
  53. return $handled;
  54. }
  55. $wp_query->is_feed = false;
  56. $this->set_404();
  57. add_filter( 'old_slug_redirect_url', '__return_false' );
  58. add_filter( 'redirect_canonical', '__return_false' );
  59. return true;
  60. }
  61. /**
  62. * Sets the 404 status code.
  63. *
  64. * @global WP_Query $wp_query
  65. *
  66. * @return void
  67. */
  68. private function set_404() {
  69. global $wp_query;
  70. // Overwrite Content-Type header.
  71. if ( ! headers_sent() ) {
  72. header( 'Content-Type: ' . get_option( 'html_type' ) . '; charset=' . get_option( 'blog_charset' ) );
  73. }
  74. $wp_query->set_404();
  75. status_header( 404 );
  76. nocache_headers();
  77. }
  78. }