1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
<?php
namespace Yoast\WP\SEO\Integrations\Front_End;
use Yoast\WP\SEO\Conditionals\Front_End_Conditional; use Yoast\WP\SEO\Integrations\Integration_Interface; use Yoast\WP\SEO\Wrappers\WP_Query_Wrapper;
/** * Handles intercepting requests. */ class Handle_404 implements Integration_Interface {
/** * The WP Query wrapper. * * @var WP_Query_Wrapper */ private $query_wrapper;
/** * Returns the conditionals based in which this loadable should be active. * * @return array */ public static function get_conditionals() { return [ Front_End_Conditional::class ]; }
/** * Initializes the integration. * * This is the place to register hooks and filters. * * @return void */ public function register_hooks() { \add_filter( 'pre_handle_404', [ $this, 'handle_404' ] ); }
/** * Handle_404 constructor. * * @codeCoverageIgnore Handles dependencies. * * @param WP_Query_Wrapper $query_wrapper The query wrapper. */ public function __construct( WP_Query_Wrapper $query_wrapper ) { $this->query_wrapper = $query_wrapper; }
/** * Handles the 404 status code. * * @param bool $handled Whether we've handled the request. * * @return bool True if it's 404. */ public function handle_404( $handled ) { if ( ! $this->is_feed_404() ) { return $handled; }
$this->set_404(); $this->set_headers();
\add_filter( 'old_slug_redirect_url', '__return_false' ); \add_filter( 'redirect_canonical', '__return_false' );
return true; }
/** * If there are no posts in a feed, make it 404 instead of sending an empty RSS feed. * * @return bool True if it's 404. */ protected function is_feed_404() { if ( ! \is_feed() ) { return false; }
$wp_query = $this->query_wrapper->get_query();
// Don't 404 if the query contains post(s) or an object. if ( $wp_query->posts || $wp_query->get_queried_object() ) { return false; }
// Don't 404 if it isn't archive or singular. if ( ! $wp_query->is_archive() && ! $wp_query->is_singular() ) { return false; }
return true; }
/** * Sets the 404 status code. */ protected function set_404() { $wp_query = $this->query_wrapper->get_query(); $wp_query->is_feed = false; $wp_query->set_404(); $this->query_wrapper->set_query( $wp_query ); }
/** * Sets the headers for http. * * @codeCoverageIgnore */ protected function set_headers() { // Overwrite Content-Type header. if ( ! \headers_sent() ) { \header( 'Content-Type: ' . \get_option( 'html_type' ) . '; charset=' . \get_option( 'blog_charset' ) ); }
\status_header( 404 ); \nocache_headers(); } }
|