@@ -504,4 +504,116 @@ public function test_flush_rules_does_not_delete_option() {
504504 $ this ->assertIsArray ( $ rewrite_rules );
505505 $ this ->assertNotEmpty ( $ rewrite_rules );
506506 }
507+
508+ /**
509+ * @ticket 43746
510+ */
511+ public function test_cpt_with_no_archive_and_explicit_feeds_true_generates_single_post_feed_rules () {
512+ global $ wp_rewrite ;
513+
514+ register_post_type (
515+ 'cpt_43746_rules ' ,
516+ array (
517+ 'public ' => true ,
518+ 'has_archive ' => false ,
519+ 'rewrite ' => array (
520+ 'slug ' => 'cpt-43746-rules ' ,
521+ 'feeds ' => true ,
522+ ),
523+ )
524+ );
525+
526+ $ wp_rewrite ->flush_rules ();
527+ $ rules = $ wp_rewrite ->rewrite_rules ();
528+
529+ $ feed_rule_found = false ;
530+ foreach ( array_keys ( $ rules ) as $ pattern ) {
531+ // Match direct single-post feed patterns.
532+ if ( str_contains ( $ pattern , 'cpt-43746-rules/([^/]+)/ ' ) && str_contains ( $ pattern , 'feed ' ) ) {
533+ $ feed_rule_found = true ;
534+ break ;
535+ }
536+ }
537+
538+ _unregister_post_type ( 'cpt_43746_rules ' );
539+ $ wp_rewrite ->flush_rules ();
540+
541+ $ this ->assertTrue ( $ feed_rule_found , 'Feed rewrite rules should be generated for a CPT with has_archive=false and feeds=true ' );
542+ }
543+
544+ /**
545+ * @ticket 43746
546+ */
547+ public function test_cpt_with_no_archive_and_feeds_false_does_not_generate_single_post_feed_rules () {
548+ global $ wp_rewrite ;
549+
550+ register_post_type (
551+ 'cpt_43746_norules ' ,
552+ array (
553+ 'public ' => true ,
554+ 'has_archive ' => false ,
555+ 'rewrite ' => array (
556+ 'slug ' => 'cpt-43746-norules ' ,
557+ 'feeds ' => false ,
558+ ),
559+ )
560+ );
561+
562+ $ wp_rewrite ->flush_rules ();
563+ $ rules = $ wp_rewrite ->rewrite_rules ();
564+
565+ $ feed_rule_found = false ;
566+ foreach ( array_keys ( $ rules ) as $ pattern ) {
567+ // Only look for direct single-post feed patterns.
568+ if ( str_contains ( $ pattern , 'cpt-43746-norules/([^/]+)/ ' ) && str_contains ( $ pattern , 'feed ' ) ) {
569+ $ feed_rule_found = true ;
570+ break ;
571+ }
572+ }
573+
574+ _unregister_post_type ( 'cpt_43746_norules ' );
575+ $ wp_rewrite ->flush_rules ();
576+
577+ $ this ->assertFalse ( $ feed_rule_found , 'No feed rewrite rules should be generated for a CPT with has_archive=false and feeds=false ' );
578+ }
579+
580+ /**
581+ * @ticket 43746
582+ */
583+ public function test_cpt_with_no_archive_and_explicit_feeds_true_does_not_generate_archive_feed_rules () {
584+ global $ wp_rewrite ;
585+
586+ register_post_type (
587+ 'cpt_43746_noarch ' ,
588+ array (
589+ 'public ' => true ,
590+ 'has_archive ' => false ,
591+ 'rewrite ' => array (
592+ 'slug ' => 'cpt-43746-noarch ' ,
593+ 'feeds ' => true ,
594+ ),
595+ )
596+ );
597+
598+ $ wp_rewrite ->flush_rules ();
599+ $ rules = $ wp_rewrite ->rewrite_rules ();
600+
601+ $ archive_feed_rule_found = false ;
602+ foreach ( $ rules as $ pattern => $ query ) {
603+ // Archive feed rules point directly to post_type=cpt_43746_noarch&feed= (no post slug segment).
604+ if ( str_contains ( $ pattern , 'cpt-43746-noarch ' )
605+ && str_contains ( $ pattern , 'feed ' )
606+ && str_contains ( $ query , 'post_type=cpt_43746_noarch&feed= ' )
607+ && ! str_contains ( $ query , 'cpt_43746_noarch= ' )
608+ ) {
609+ $ archive_feed_rule_found = true ;
610+ break ;
611+ }
612+ }
613+
614+ _unregister_post_type ( 'cpt_43746_noarch ' );
615+ $ wp_rewrite ->flush_rules ();
616+
617+ $ this ->assertFalse ( $ archive_feed_rule_found , 'Archive feed rewrite rules should NOT be generated when has_archive is false, even if feeds is true ' );
618+ }
507619}
0 commit comments