diff --git src/wp-includes/class-wp-query.php src/wp-includes/class-wp-query.php
index eb68f21..3b56ee5 100644
|
|
class WP_Query { |
346 | 346 | public $is_comment_feed = false; |
347 | 347 | |
348 | 348 | /** |
| 349 | * Set if query is home feed display. |
| 350 | * |
| 351 | * @since 4.7.1 |
| 352 | * @access public |
| 353 | * @var bool |
| 354 | */ |
| 355 | public $is_home_feed = false; |
| 356 | |
| 357 | /** |
| 358 | * Set if query is custom feed display. |
| 359 | * |
| 360 | * @since 4.7.1 |
| 361 | * @access public |
| 362 | * @var bool |
| 363 | */ |
| 364 | public $is_custom_feed = false; |
| 365 | |
| 366 | /** |
349 | 367 | * Set if query is trackback. |
350 | 368 | * |
351 | 369 | * @since 1.5.0 |
… |
… |
class WP_Query { |
511 | 529 | $this->is_search = false; |
512 | 530 | $this->is_feed = false; |
513 | 531 | $this->is_comment_feed = false; |
| 532 | $this->is_home_feed = false; |
| 533 | $this->is_custom_feed = false; |
514 | 534 | $this->is_trackback = false; |
515 | 535 | $this->is_home = false; |
516 | 536 | $this->is_404 = false; |
… |
… |
class WP_Query { |
927 | 947 | $this->is_archive = true; |
928 | 948 | } |
929 | 949 | |
930 | | if ( '' != $qv['feed'] ) |
| 950 | if ( '' != $qv['feed'] ) { |
931 | 951 | $this->is_feed = true; |
| 952 | if ( ! in_array( $qv['feed'], array( 'feed', 'rss', 'rss2', 'atom', 'rdf' ) ) ) { |
| 953 | $this->is_custom_feed = true; |
| 954 | } |
| 955 | } |
932 | 956 | |
933 | 957 | if ( '' != $qv['embed'] ) { |
934 | 958 | $this->is_embed = true; |
… |
… |
class WP_Query { |
957 | 981 | if ( $this->is_feed && ( !empty($qv['withcomments']) || ( empty($qv['withoutcomments']) && $this->is_singular ) ) ) |
958 | 982 | $this->is_comment_feed = true; |
959 | 983 | |
960 | | if ( !( $this->is_singular || $this->is_archive || $this->is_search || $this->is_feed || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) || $this->is_trackback || $this->is_404 || $this->is_admin || $this->is_robots ) ) |
961 | | $this->is_home = true; |
| 984 | |
| 985 | |
| 986 | if ( !( $this->is_singular || $this->is_archive || $this->is_search || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) || $this->is_trackback || $this->is_404 || $this->is_admin || $this->is_robots || $this->is_custom_feed ) ) { |
| 987 | if ( $this->is_feed ) { |
| 988 | if ( ! $this->is_comment_feed ) { |
| 989 | $this->is_home_feed = true; |
| 990 | } |
| 991 | } else { |
| 992 | $this->is_home = true; |
| 993 | } |
| 994 | |
| 995 | } |
962 | 996 | |
963 | 997 | // Correct is_* for page_on_front and page_for_posts |
964 | 998 | if ( $this->is_home && 'page' == get_option('show_on_front') && get_option('page_on_front') ) { |
… |
… |
class WP_Query { |
3668 | 3702 | } |
3669 | 3703 | |
3670 | 3704 | /** |
| 3705 | * Is the query for a hompage feed? |
| 3706 | * |
| 3707 | * @since 4.7.1 |
| 3708 | * |
| 3709 | * @return bool |
| 3710 | */ |
| 3711 | public function is_home_feed() { |
| 3712 | return (bool) $this->is_home_feed; |
| 3713 | } |
| 3714 | |
| 3715 | /** |
| 3716 | * Is the query for a custom feed? |
| 3717 | * |
| 3718 | * @since 4.7.1 |
| 3719 | * |
| 3720 | * @return bool |
| 3721 | */ |
| 3722 | public function is_custom_feed() { |
| 3723 | return (bool) $this->is_custom_feed; |
| 3724 | } |
| 3725 | |
| 3726 | /** |
3671 | 3727 | * Is the query for the front page of the site? |
3672 | 3728 | * |
3673 | 3729 | * This is for what is displayed at your site's main URL. |
diff --git src/wp-includes/functions.php src/wp-includes/functions.php
index 914cbb9..733a718 100644
|
|
function do_feed() { |
1221 | 1221 | * search result, or main comments. By checking for the absense of posts we can prevent rendering the feed |
1222 | 1222 | * templates at invalid endpoints. e.g.) /wp-content/plugins/feed/ |
1223 | 1223 | */ |
1224 | | if ( ! $wp_query->have_posts() && ! ( $wp_query->is_archive() || $wp_query->is_search() || $is_main_comments_feed ) ) { |
| 1224 | if ( ! $wp_query->have_posts() && ! ( $wp_query->is_archive() || $wp_query->is_search() || $is_main_comments_feed || $wp_query->is_home_feed() || $wp_query->is_custom_feed() ) ) { |
1225 | 1225 | wp_die( __( 'ERROR: This is not a valid feed.' ), '', array( 'response' => 404 ) ); |
1226 | 1226 | } |
1227 | 1227 | |
diff --git src/wp-includes/query.php src/wp-includes/query.php
index 744610f..db399f1 100644
|
|
function is_comment_feed() { |
383 | 383 | } |
384 | 384 | |
385 | 385 | /** |
| 386 | * Is the query for the blog homepage feed? |
| 387 | * |
| 388 | * @since 4.7.1 |
| 389 | * |
| 390 | * @global WP_Query $wp_query Global WP_Query instance. |
| 391 | * |
| 392 | * @return bool |
| 393 | */ |
| 394 | function is_home_feed() { |
| 395 | global $wp_query; |
| 396 | |
| 397 | if ( ! isset( $wp_query ) ) { |
| 398 | _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' ); |
| 399 | return false; |
| 400 | } |
| 401 | |
| 402 | return $wp_query->is_home_feed(); |
| 403 | } |
| 404 | |
| 405 | /** |
| 406 | * Is the query for the custom feed? |
| 407 | * |
| 408 | * @since 4.7.1 |
| 409 | * |
| 410 | * @global WP_Query $wp_query Global WP_Query instance. |
| 411 | * |
| 412 | * @return bool |
| 413 | */ |
| 414 | function is_custom_feed() { |
| 415 | global $wp_query; |
| 416 | |
| 417 | if ( ! isset( $wp_query ) ) { |
| 418 | _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' ); |
| 419 | return false; |
| 420 | } |
| 421 | |
| 422 | return $wp_query->is_custom_feed(); |
| 423 | } |
| 424 | |
| 425 | /** |
386 | 426 | * Is the query for the front page of the site? |
387 | 427 | * |
388 | 428 | * This is for what is displayed at your site's main URL. |
diff --git tests/phpunit/includes/testcase.php tests/phpunit/includes/testcase.php
index 8990504..681bcd0 100644
|
|
class WP_UnitTestCase extends PHPUnit_Framework_TestCase { |
597 | 597 | 'is_day', |
598 | 598 | 'is_embed', |
599 | 599 | 'is_feed', |
| 600 | 'is_home_feed', |
| 601 | 'is_custom_feed', |
600 | 602 | 'is_front_page', |
601 | 603 | 'is_home', |
602 | 604 | 'is_month', |
diff --git tests/phpunit/tests/feed/rss2.php tests/phpunit/tests/feed/rss2.php
index fab3726..dd13839 100644
|
|
class Tests_Feeds_RSS2 extends WP_UnitTestCase { |
63 | 63 | |
64 | 64 | $this->set_permalink_structure( '/%year%/%monthnum%/%day%/%postname%/' ); |
65 | 65 | create_initial_taxonomies(); |
| 66 | |
| 67 | // Add a custom feed |
| 68 | add_feed( 'custom', 'do_rss2' ); |
| 69 | |
66 | 70 | } |
67 | 71 | |
68 | 72 | /** |
… |
… |
class Tests_Feeds_RSS2 extends WP_UnitTestCase { |
296 | 300 | $this->go_to( 'feed/' ); |
297 | 301 | |
298 | 302 | // Verify the query object is a feed. |
299 | | $this->assertQueryTrue( 'is_feed' ); |
| 303 | $this->assertQueryTrue( 'is_feed', 'is_home_feed' ); |
300 | 304 | |
301 | 305 | // Queries performed on valid feed endpoints should contain posts. |
302 | 306 | $this->assertTrue( have_posts() ); |
… |
… |
class Tests_Feeds_RSS2 extends WP_UnitTestCase { |
313 | 317 | $this->assertEquals( 1, count( $rss ) ); |
314 | 318 | } |
315 | 319 | |
| 320 | function test_valid_custom_feed_endpoint() { |
| 321 | // An example of a valid home feed endpoint. |
| 322 | $this->go_to( 'feed/custom' ); |
| 323 | |
| 324 | // Verify the query object is a feed. |
| 325 | $this->assertQueryTrue( 'is_feed', 'is_custom_feed' ); |
| 326 | |
| 327 | // Check to see if we have the expected XML output from the feed template. |
| 328 | $feed = $this->do_rss2(); |
| 329 | |
| 330 | $xml = xml_to_array( $feed ); |
| 331 | |
| 332 | // Get the <rss> child element of <xml>. |
| 333 | $rss = xml_find( $xml, 'rss' ); |
| 334 | |
| 335 | // There should only be one <rss> child element. |
| 336 | $this->assertEquals( 1, count( $rss ) ); |
| 337 | } |
| 338 | |
316 | 339 | /* |
317 | 340 | * Check to make sure we are rendering feed templates for the taxonomy feeds. |
318 | 341 | * e.g. https://example.com/category/foo/feed/ |
… |
… |
class Tests_Feeds_RSS2 extends WP_UnitTestCase { |
408 | 431 | * |
409 | 432 | * @ticket 30210 |
410 | 433 | */ |
411 | | function test_valid_single_post_comment_feed_endpoint() { |
| 434 | function test_valid_singular_comment_feed_endpoint() { |
412 | 435 | // An example of an valid date archive feed endpoint. |
413 | 436 | $this->go_to( get_post_comments_feed_link( self::$posts[0] ) ); |
414 | 437 | |
diff --git tests/phpunit/tests/query/conditionals.php tests/phpunit/tests/query/conditionals.php
index 8cceaa5..323ba67 100644
|
|
class Tests_Query_Conditionals extends WP_UnitTestCase { |
253 | 253 | // long version |
254 | 254 | foreach ($feeds as $feed) { |
255 | 255 | $this->go_to("/feed/{$feed}/"); |
256 | | $this->assertQueryTrue('is_feed'); |
| 256 | $this->assertQueryTrue('is_feed', 'is_home_feed'); |
257 | 257 | } |
258 | 258 | |
259 | 259 | // short version |
260 | 260 | foreach ($feeds as $feed) { |
261 | 261 | $this->go_to("/{$feed}/"); |
262 | | $this->assertQueryTrue('is_feed'); |
| 262 | $this->assertQueryTrue('is_feed', 'is_home_feed'); |
263 | 263 | } |
264 | 264 | |
265 | 265 | } |
… |
… |
class Tests_Query_Conditionals extends WP_UnitTestCase { |
269 | 269 | $types = array('rss2', 'rss', 'atom'); |
270 | 270 | foreach ($types as $type) { |
271 | 271 | $this->go_to(get_feed_link($type)); |
272 | | $this->assertQueryTrue('is_feed'); |
| 272 | $this->assertQueryTrue('is_feed', 'is_home_feed'); |
273 | 273 | } |
274 | 274 | } |
275 | 275 | |
… |
… |
class Tests_Query_Conditionals extends WP_UnitTestCase { |
369 | 369 | } |
370 | 370 | } |
371 | 371 | |
| 372 | function test_invalid_category_feed() { |
| 373 | // check the long form |
| 374 | $types = array( 'feed', 'rdf', 'rss', 'rss2', 'atom' ); |
| 375 | foreach ( $types as $type ) { |
| 376 | $this->go_to( "/category/four-oh-four-cat/feed/{$type}/" ); |
| 377 | $this->assertQueryTrue( 'is_404' ); |
| 378 | } |
| 379 | |
| 380 | // check the short form |
| 381 | $types = array( 'feed', 'rdf', 'rss', 'rss2', 'atom' ); |
| 382 | foreach ( $types as $type ) { |
| 383 | $this->go_to( "/category/four-oh-four-cat/{$type}/" ); |
| 384 | $this->assertQueryTrue( 'is_404' ); |
| 385 | } |
| 386 | } |
| 387 | |
372 | 388 | // 'category/(.+?)/page/?([0-9]{1,})/?$' => 'index.php?category_name=$matches[1]&paged=$matches[2]', |
373 | 389 | function test_category_paged() { |
374 | 390 | update_option( 'posts_per_page', 2 ); |