Ticket #39692: 39692.3.diff
File 39692.3.diff, 8.6 KB (added by , 7 years ago) |
---|
-
src/wp-includes/default-filters.php
diff --git src/wp-includes/default-filters.php src/wp-includes/default-filters.php index 9212e42..8a8b6a9 100644
add_action( 'wp_footer', 'wp_print_footer_scripts', 20 ); 262 262 add_action( 'template_redirect', 'wp_shortlink_header', 11, 0 ); 263 263 add_action( 'wp_print_footer_scripts', '_wp_footer_scripts' ); 264 264 add_action( 'init', 'check_theme_switched', 99 ); 265 add_action( 'after_switch_theme', '_wp_menus_changed' ); 265 266 add_action( 'after_switch_theme', '_wp_sidebars_changed' ); 266 267 add_action( 'wp_print_styles', 'print_emoji_styles' ); 267 268 -
src/wp-includes/nav-menu.php
diff --git src/wp-includes/nav-menu.php src/wp-includes/nav-menu.php index 1585c62..1a32a2b 100644
function _wp_delete_customize_changeset_dependent_auto_drafts( $post_id ) { 1026 1026 } 1027 1027 add_action( 'delete_post', '_wp_delete_customize_changeset_dependent_auto_drafts' ); 1028 1028 } 1029 1030 /** 1031 * Handle menu config after theme change. 1032 * 1033 * @access private 1034 * @since 4.9.0 1035 */ 1036 function _wp_menus_changed() { 1037 $old_nav_menu_locations = get_option( 'theme_switch_menu_locations', array() ); 1038 $new_nav_menu_locations = get_nav_menu_locations(); 1039 $registered_nav_menus = get_registered_nav_menus(); 1040 1041 1042 if ( ! empty( $old_nav_menu_locations ) ) { 1043 // If old and new theme have just one location, map it. 1044 if ( 1 === count( $old_nav_menu_locations ) && 1 === count( $registered_nav_menus ) ) { 1045 $new_nav_menu_locations[ key( $registered_nav_menus ) ] = array_pop( $old_nav_menu_locations ); 1046 } else { 1047 $old_locations = array_keys( $old_nav_menu_locations ); 1048 1049 // Map locations with the same slug. 1050 foreach ( $registered_nav_menus as $location => $name ) { 1051 if ( in_array( $location, $old_locations, true ) ) { 1052 $new_nav_menu_locations[ $location ] = $old_nav_menu_locations[ $location ]; 1053 unset( $old_nav_menu_locations[ $location ] ); 1054 } 1055 } 1056 1057 /* 1058 * If old and new theme both have locations that contain phrases 1059 * from within the same group, make an educated guess and map it. 1060 */ 1061 $common_slug_groups = array( 1062 array( 'header', 'main', 'navigation', 'primary', 'top' ), 1063 array( 'bottom', 'footer', 'secondary', 'subsidiary' ), 1064 array( 'social' ), 1065 // TODO: Find a second slug or remove, since locations with same slug are already mapped. 1066 ); 1067 1068 // Go through each group... 1069 foreach ( $common_slug_groups as $slug_group ) { 1070 1071 // ...and see if any of these slugs... 1072 foreach ( $slug_group as $slug ) { 1073 1074 // ...and any of the new menu locations... 1075 foreach ( $registered_nav_menus as $new_location => $name ) { 1076 1077 // ...actually match! 1078 if ( false !== stripos( $new_location, $slug ) || false !== stripos( $slug, $new_location ) ) { 1079 1080 // Then see if any of the old locations... 1081 foreach ( $old_nav_menu_locations as $location => $menu_id ) { 1082 1083 // ...match a slug in the same group. 1084 foreach ( $slug_group as $slug ) { 1085 if ( false !== stripos( $location, $slug ) || false !== stripos( $slug, $location ) ) { 1086 1087 // Make sure this location wasn't mapped and removed previously. 1088 if ( ! empty( $old_nav_menu_locations[ $location ] ) ) { 1089 1090 // We have a match that can be mapped! 1091 $new_nav_menu_locations[ $new_location ] = $old_nav_menu_locations[ $location ]; 1092 1093 // Remove the mapped location so it can't be mapped again. 1094 unset( $old_nav_menu_locations[ $location ] ); 1095 1096 // Go back and check the next new menu location. 1097 continue 3; 1098 } 1099 } 1100 } 1101 } 1102 } 1103 } 1104 } 1105 } 1106 } 1107 } 1108 1109 set_theme_mod( 'nav_menu_locations', $new_nav_menu_locations ); 1110 delete_option( 'theme_switch_menu_locations' ); 1111 } -
src/wp-includes/theme.php
diff --git src/wp-includes/theme.php src/wp-includes/theme.php index 2b2fbf2..1d55f4f 100644
function switch_theme( $stylesheet ) { 691 691 } 692 692 693 693 $nav_menu_locations = get_theme_mod( 'nav_menu_locations' ); 694 add_option( 'theme_switch_menu_locations', $nav_menu_locations ); 694 695 695 696 if ( func_num_args() > 1 ) { 696 697 $stylesheet = func_get_arg( 1 ); … … function switch_theme( $stylesheet ) { 731 732 if ( 'wp_ajax_customize_save' === current_action() ) { 732 733 remove_theme_mod( 'sidebars_widgets' ); 733 734 } 734 735 if ( ! empty( $nav_menu_locations ) ) {736 $nav_mods = get_theme_mod( 'nav_menu_locations' );737 if ( empty( $nav_mods ) ) {738 set_theme_mod( 'nav_menu_locations', $nav_menu_locations );739 }740 }741 735 } 742 736 743 737 update_option( 'theme_switched', $old_theme->get_stylesheet() ); -
new file tests/phpunit/tests/menu/nav-menu.php
diff --git tests/phpunit/tests/menu/nav-menu.php tests/phpunit/tests/menu/nav-menu.php new file mode 100644 index 0000000..b38f1e6
- + 1 <?php 2 3 /** 4 * @group navmenus 5 */ 6 class Tests_Nav_Menu_Theme_Change extends WP_UnitTestCase { 7 8 function setUp() { 9 register_nav_menus( array( 10 'primary' => 'Primary', 11 ) ); 12 13 parent::setUp(); 14 } 15 16 function tearDown() { 17 global $_wp_registered_nav_menus; 18 19 remove_theme_mod( 'nav_menu_locations' ); 20 $_wp_registered_nav_menus = array(); 21 22 parent::tearDown(); 23 } 24 25 /** 26 * Two themes with one location each should just map. 27 */ 28 function test_one_location_each() { 29 $old_nav_menu_locations = array( 'unique-slug' => 1 ); 30 update_option( 'theme_switch_menu_locations', $old_nav_menu_locations ); 31 32 _wp_menus_changed(); 33 $this->assertEqualSets( get_theme_mod( 'nav_menu_locations' ), $old_nav_menu_locations ); 34 } 35 36 /** 37 * Locations with the same name should map. 38 */ 39 function test_locations_with_same_slug() { 40 $old_nav_menu_locations = array( 'primary' => 1, 'secondary' => 2 ); 41 update_option( 'theme_switch_menu_locations', $old_nav_menu_locations ); 42 register_nav_menu( 'secondary', 'Secondary' ); 43 44 _wp_menus_changed(); 45 $this->assertEqualSets( get_theme_mod( 'nav_menu_locations' ), $old_nav_menu_locations ); 46 } 47 48 /** 49 * If the new theme was previously active, we should fall back to that data. 50 */ 51 function test_new_theme_previously_active() { 52 $old_nav_menu_locations = array( 'primary' => 3 ); 53 update_option( 'theme_switch_menu_locations', $old_nav_menu_locations ); 54 $previous_locations = array( 'primary' => 1, 'secondary' => 2 ); 55 set_theme_mod( 'nav_menu_locations', $previous_locations ); 56 57 _wp_menus_changed(); 58 $this->assertEqualSets( get_theme_mod( 'nav_menu_locations' ), array_merge( $previous_locations, $old_nav_menu_locations ) ); 59 } 60 61 /** 62 * Make educated guesses on theme locations. 63 */ 64 function test_location_guessing() { 65 $old_nav_menu_locations = array( 'header' => 1, 'footer' => 2 ); 66 update_option( 'theme_switch_menu_locations', $old_nav_menu_locations ); 67 register_nav_menu( 'secondary', 'Secondary' ); 68 69 _wp_menus_changed(); 70 $this->assertEqualSets( get_theme_mod( 'nav_menu_locations' ), array( 'primary' => 1, 'secondary' => 2 ) ); 71 } 72 73 /** 74 * Make sure two locations that fall in the same group don't get the same menu assigned. 75 */ 76 function test_location_guessing_one_menu_per_group() { 77 $old_nav_menu_locations = array( 'top-menu' => 1, 'secondary' => 2 ); 78 update_option( 'theme_switch_menu_locations', $old_nav_menu_locations ); 79 register_nav_menu( 'main', 'Main' ); 80 81 _wp_menus_changed(); 82 $this->assertEqualSets( get_theme_mod( 'nav_menu_locations' ), array( 'main' => 1 ) ); 83 } 84 85 /** 86 * Make sure two locations that fall in the same group get menus assigned from the same group. 87 */ 88 function test_location_guessing_one_menu_per_location() { 89 $old_nav_menu_locations = array( 'navigation-menu' => 1, 'top-menu' => 2 ); 90 update_option( 'theme_switch_menu_locations', $old_nav_menu_locations ); 91 register_nav_menu( 'main', 'Main' ); 92 93 _wp_menus_changed(); 94 $this->assertEqualSets( get_theme_mod( 'nav_menu_locations' ), array( 'main' => 1, 'primary' => 2 ) ); 95 } 96 97 /** 98 * Technically possible to register menu locations numerically. 99 */ 100 function test_numerical_locations() { 101 $old_nav_menu_locations = array( 'main' => 1, 'secondary' => 2, 'tertiary' => 3 ); 102 update_option( 'theme_switch_menu_locations', $old_nav_menu_locations ); 103 register_nav_menu( 1 , 'First' ); 104 105 _wp_menus_changed(); 106 $this->assertEqualSets( get_theme_mod( 'nav_menu_locations' ), array( 'primary' => 1 ) ); 107 } 108 }