Changeset 41555 for trunk/src/wp-includes/widgets.php
- Timestamp:
- 09/21/2017 06:45:03 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/widgets.php
r41340 r41555 920 920 * @access private 921 921 * 922 * @global array $_wp_sidebars_widgets 922 923 * @param array $sidebars_widgets Sidebar widgets and their settings. 923 924 */ 924 925 function wp_set_sidebars_widgets( $sidebars_widgets ) { 925 if ( !isset( $sidebars_widgets['array_version'] ) ) 926 global $_wp_sidebars_widgets; 927 928 // Clear cached value used in wp_get_sidebars_widgets(). 929 $_wp_sidebars_widgets = null; 930 931 if ( ! isset( $sidebars_widgets['array_version'] ) ) { 926 932 $sidebars_widgets['array_version'] = 3; 933 } 934 927 935 update_option( 'sidebars_widgets', $sidebars_widgets ); 928 936 } … … 1114 1122 * @param string|bool $theme_changed Whether the theme was changed as a boolean. A value 1115 1123 * of 'customize' defers updates for the Customizer. 1116 * @return array |void1124 * @return array Updated sidebars widgets. 1117 1125 */ 1118 1126 function retrieve_widgets( $theme_changed = false ) { 1119 1127 global $wp_registered_sidebars, $sidebars_widgets, $wp_registered_widgets; 1120 1128 1121 $registered_sidebar_keys = array_keys( $wp_registered_sidebars ); 1122 $orphaned = 0; 1123 1124 $old_sidebars_widgets = get_theme_mod( 'sidebars_widgets' ); 1125 if ( is_array( $old_sidebars_widgets ) ) { 1126 // time() that sidebars were stored is in $old_sidebars_widgets['time'] 1127 $_sidebars_widgets = $old_sidebars_widgets['data']; 1128 1129 if ( 'customize' !== $theme_changed ) { 1130 remove_theme_mod( 'sidebars_widgets' ); 1131 } 1132 1133 foreach ( $_sidebars_widgets as $sidebar => $widgets ) { 1134 if ( 'wp_inactive_widgets' === $sidebar || 'orphaned_widgets' === substr( $sidebar, 0, 16 ) ) { 1135 continue; 1136 } 1137 1138 if ( !in_array( $sidebar, $registered_sidebar_keys ) ) { 1139 $_sidebars_widgets['orphaned_widgets_' . ++$orphaned] = $widgets; 1140 unset( $_sidebars_widgets[$sidebar] ); 1141 } 1142 } 1143 } else { 1144 if ( empty( $sidebars_widgets ) ) 1145 return; 1129 $registered_sidebars_keys = array_keys( $wp_registered_sidebars ); 1130 $registered_widgets_ids = array_keys( $wp_registered_widgets ); 1131 1132 if ( ! is_array( get_theme_mod( 'sidebars_widgets' ) ) ) { 1133 if ( empty( $sidebars_widgets ) ) { 1134 return array(); 1135 } 1146 1136 1147 1137 unset( $sidebars_widgets['array_version'] ); 1148 1138 1149 $old = array_keys($sidebars_widgets); 1150 sort($old); 1151 sort($registered_sidebar_keys); 1152 1153 if ( $old == $registered_sidebar_keys ) 1154 return; 1155 1156 $_sidebars_widgets = array( 1157 'wp_inactive_widgets' => !empty( $sidebars_widgets['wp_inactive_widgets'] ) ? $sidebars_widgets['wp_inactive_widgets'] : array() 1158 ); 1159 1160 unset( $sidebars_widgets['wp_inactive_widgets'] ); 1161 1162 foreach ( $wp_registered_sidebars as $id => $settings ) { 1163 if ( $theme_changed ) { 1164 $_sidebars_widgets[$id] = array_shift( $sidebars_widgets ); 1165 } else { 1166 // no theme change, grab only sidebars that are currently registered 1167 if ( isset( $sidebars_widgets[$id] ) ) { 1168 $_sidebars_widgets[$id] = $sidebars_widgets[$id]; 1169 unset( $sidebars_widgets[$id] ); 1170 } 1171 } 1172 } 1173 1174 foreach ( $sidebars_widgets as $val ) { 1175 if ( is_array($val) && ! empty( $val ) ) 1176 $_sidebars_widgets['orphaned_widgets_' . ++$orphaned] = $val; 1177 } 1178 } 1179 1180 // discard invalid, theme-specific widgets from sidebars 1181 $shown_widgets = array(); 1182 1183 foreach ( $_sidebars_widgets as $sidebar => $widgets ) { 1184 if ( !is_array($widgets) ) 1185 continue; 1186 1187 $_widgets = array(); 1188 foreach ( $widgets as $widget ) { 1189 if ( isset($wp_registered_widgets[$widget]) ) 1190 $_widgets[] = $widget; 1191 } 1192 1193 $_sidebars_widgets[$sidebar] = $_widgets; 1194 $shown_widgets = array_merge($shown_widgets, $_widgets); 1195 } 1196 1197 $sidebars_widgets = $_sidebars_widgets; 1198 unset($_sidebars_widgets, $_widgets); 1199 1200 // find hidden/lost multi-widget instances 1201 $lost_widgets = array(); 1202 foreach ( $wp_registered_widgets as $key => $val ) { 1203 if ( in_array($key, $shown_widgets, true) ) 1204 continue; 1205 1206 $number = preg_replace('/.+?-([0-9]+)$/', '$1', $key); 1207 1208 if ( 2 > (int) $number ) 1209 continue; 1210 1211 $lost_widgets[] = $key; 1212 } 1213 1214 $sidebars_widgets['wp_inactive_widgets'] = array_merge($lost_widgets, (array) $sidebars_widgets['wp_inactive_widgets']); 1139 $sidebars_widgets_keys = array_keys( $sidebars_widgets ); 1140 sort( $sidebars_widgets_keys ); 1141 sort( $registered_sidebars_keys ); 1142 1143 if ( $sidebars_widgets_keys === $registered_sidebars_keys ) { 1144 $sidebars_widgets = _wp_remove_unregistered_widgets( $sidebars_widgets, $registered_widgets_ids ); 1145 1146 return $sidebars_widgets; 1147 } 1148 } 1149 1150 1151 // Discard invalid, theme-specific widgets from sidebars. 1152 $sidebars_widgets = _wp_remove_unregistered_widgets( $sidebars_widgets, $registered_widgets_ids ); 1153 $sidebars_widgets = wp_map_sidebars_widgets( $sidebars_widgets ); 1154 1155 // Find hidden/lost multi-widget instances. 1156 $shown_widgets = call_user_func_array( 'array_merge', $sidebars_widgets ); 1157 $lost_widgets = array_diff( $registered_widgets_ids, $shown_widgets ); 1158 1159 foreach ( $lost_widgets as $key => $widget_id ) { 1160 $number = preg_replace( '/.+?-([0-9]+)$/', '$1', $widget_id ); 1161 1162 // Only keep active and default widgets. 1163 if ( is_numeric( $number ) && (int) $number < 2 ) { 1164 unset( $lost_widgets[ $key ] ); 1165 } 1166 } 1167 $sidebars_widgets['wp_inactive_widgets'] = array_merge( $lost_widgets, (array) $sidebars_widgets['wp_inactive_widgets'] ); 1168 1215 1169 if ( 'customize' !== $theme_changed ) { 1216 1170 wp_set_sidebars_widgets( $sidebars_widgets ); 1171 } 1172 1173 return $sidebars_widgets; 1174 } 1175 1176 /** 1177 * Compares a list of sidebars with their widgets against a whitelist. 1178 * 1179 * @since 4.9.0 1180 * 1181 * @param array $existing_sidebars_widgets List of sidebars and their widget instance IDs. 1182 * @return array Mapped sidebars widgets. 1183 */ 1184 function wp_map_sidebars_widgets( $existing_sidebars_widgets ) { 1185 global $wp_registered_sidebars; 1186 1187 $new_sidebars_widgets = array( 1188 'wp_inactive_widgets' => array(), 1189 ); 1190 1191 // Short-circuit if there are no sidebars to map. 1192 if ( ! is_array( $existing_sidebars_widgets ) || empty( $existing_sidebars_widgets ) ) { 1193 return $new_sidebars_widgets; 1194 } 1195 1196 foreach ( $existing_sidebars_widgets as $sidebar => $widgets ) { 1197 if ( 'wp_inactive_widgets' === $sidebar || 'orphaned_widgets' === substr( $sidebar, 0, 16 ) ) { 1198 $new_sidebars_widgets['wp_inactive_widgets'] = array_merge( $new_sidebars_widgets['wp_inactive_widgets'], (array) $widgets ); 1199 unset( $existing_sidebars_widgets[ $sidebar ] ); 1200 } 1201 } 1202 1203 // If old and new theme have just one sidebar, map it and we're done. 1204 if ( 1 === count( $existing_sidebars_widgets ) && 1 === count( $wp_registered_sidebars ) ) { 1205 $new_sidebars_widgets[ key( $wp_registered_sidebars ) ] = array_pop( $existing_sidebars_widgets ); 1206 1207 return $new_sidebars_widgets; 1208 } 1209 1210 // Map locations with the same slug. 1211 $existing_sidebars = array_keys( $existing_sidebars_widgets ); 1212 1213 foreach ( $wp_registered_sidebars as $sidebar => $name ) { 1214 if ( in_array( $sidebar, $existing_sidebars, true ) ) { 1215 $new_sidebars_widgets[ $sidebar ] = $existing_sidebars_widgets[ $sidebar ]; 1216 unset( $existing_sidebars_widgets[ $sidebar ] ); 1217 } else { 1218 $new_sidebars_widgets[ $sidebar ] = array(); 1219 } 1220 } 1221 1222 // If there are no old sidebars left, then we're done. 1223 if ( empty( $existing_sidebars_widgets ) ) { 1224 return $new_sidebars_widgets; 1225 } 1226 1227 /* 1228 * If old and new theme both have sidebars that contain phrases 1229 * from within the same group, make an educated guess and map it. 1230 */ 1231 $common_slug_groups = array( 1232 array( 'sidebar', 'primary', 'main', 'right' ), 1233 array( 'second', 'left' ), 1234 array( 'sidebar-2', 'footer', 'bottom' ), 1235 array( 'header', 'top' ), 1236 ); 1237 1238 // Go through each group... 1239 foreach ( $common_slug_groups as $slug_group ) { 1240 1241 // ...and see if any of these slugs... 1242 foreach ( $slug_group as $slug ) { 1243 1244 // ...and any of the new sidebars... 1245 foreach ( $wp_registered_sidebars as $new_sidebar => $args ) { 1246 1247 // ...actually match! 1248 if ( false === stripos( $new_sidebar, $slug ) && false === stripos( $slug, $new_sidebar ) ) { 1249 continue; 1250 } 1251 1252 // Then see if any of the existing sidebars... 1253 foreach ( $existing_sidebars_widgets as $sidebar => $widgets ) { 1254 1255 // ...and any slug in the same group... 1256 foreach ( $slug_group as $slug ) { 1257 1258 // ... have a match as well. 1259 if ( false === stripos( $sidebar, $slug ) && false === stripos( $slug, $sidebar ) ) { 1260 continue; 1261 } 1262 1263 // Make sure this sidebar wasn't mapped and removed previously. 1264 if ( ! empty( $existing_sidebars_widgets[ $sidebar ] ) ) { 1265 1266 // We have a match that can be mapped! 1267 $new_sidebars_widgets[ $new_sidebar ] = array_merge( $new_sidebars_widgets[ $new_sidebar ], $existing_sidebars_widgets[ $sidebar ] ); 1268 1269 // Remove the mapped sidebar so it can't be mapped again. 1270 unset( $existing_sidebars_widgets[ $sidebar ] ); 1271 1272 // Go back and check the next new sidebar. 1273 continue 3; 1274 } 1275 } // endforeach ( $slug_group as $slug ) 1276 } // endforeach ( $existing_sidebars_widgets as $sidebar => $widgets ) 1277 } // endforeach foreach ( $wp_registered_sidebars as $new_sidebar => $args ) 1278 } // endforeach ( $slug_group as $slug ) 1279 } // endforeach ( $common_slug_groups as $slug_group ) 1280 1281 // Move any left over widgets to inactive sidebar. 1282 foreach ( $existing_sidebars_widgets as $widgets ) { 1283 if ( is_array( $widgets ) && ! empty( $widgets ) ) { 1284 $new_sidebars_widgets['wp_inactive_widgets'] = array_merge( $new_sidebars_widgets['wp_inactive_widgets'], $widgets ); 1285 } 1286 } 1287 1288 // Sidebars_widgets settings from when this theme was previously active. 1289 $old_sidebars_widgets = get_theme_mod( 'sidebars_widgets' ); 1290 1291 if ( is_array( $old_sidebars_widgets ) ) { 1292 1293 // Only check sidebars that are empty or have not been mapped to yet. 1294 foreach ( $new_sidebars_widgets as $new_sidebar => $new_widgets ) { 1295 if ( array_key_exists( $new_sidebar, $old_sidebars_widgets ) && ! empty( $new_widgets ) ) { 1296 unset( $old_sidebars_widgets[ $new_sidebar ] ); 1297 } 1298 } 1299 1300 // Remove orphaned widgets, we're only interested in previously active sidebars. 1301 foreach ( $old_sidebars_widgets as $sidebar => $widgets ) { 1302 if ( 'orphaned_widgets' === substr( $sidebar, 0, 16 ) ) { 1303 unset( $old_sidebars_widgets[ $sidebar ] ); 1304 } 1305 } 1306 1307 $old_sidebars_widgets = _wp_remove_unregistered_widgets( $old_sidebars_widgets ); 1308 1309 if ( ! empty( $old_sidebars_widgets ) ) { 1310 1311 // Go through each remaining sidebar... 1312 foreach ( $old_sidebars_widgets as $old_sidebar => $old_widgets ) { 1313 1314 // ...and check every new sidebar... 1315 foreach ( $new_sidebars_widgets as $new_sidebar => $new_widgets ) { 1316 1317 // ...for every widget we're trying to revive. 1318 foreach ( $old_widgets as $key => $widget_id ) { 1319 $active_key = array_search( $widget_id, $new_widgets, true ); 1320 1321 // If the widget is used elsewhere... 1322 if ( false !== $active_key ) { 1323 1324 // ...and that elsewhere is inactive widgets... 1325 if ( 'wp_inactive_widgets' === $new_sidebar ) { 1326 1327 // ...remove it from there and keep the active version... 1328 unset( $new_sidebars_widgets['wp_inactive_widgets'][ $active_key ] ); 1329 } else { 1330 1331 // ...otherwise remove it from the old sidebar and keep it in the new one. 1332 unset( $old_sidebars_widgets[ $old_sidebar ][ $key ] ); 1333 } 1334 } // endif ( $active_key ) 1335 } // endforeach ( $old_widgets as $key => $widget_id ) 1336 } // endforeach ( $new_sidebars_widgets as $new_sidebar => $new_widgets ) 1337 } // endforeach ( $old_sidebars_widgets as $old_sidebar => $old_widgets ) 1338 } // endif ( ! empty( $old_sidebars_widgets ) ) 1339 1340 1341 // Restore widget settings from when theme was previously active. 1342 $new_sidebars_widgets = array_merge( $new_sidebars_widgets, $old_sidebars_widgets ); 1343 } 1344 1345 return $new_sidebars_widgets; 1346 } 1347 1348 /** 1349 * Compares a list of sidebars with their widgets against a whitelist. 1350 * 1351 * @since 4.9.0 1352 * 1353 * @param array $sidebars_widgets List of sidebars and their widget instance IDs. 1354 * @param array $whitelist Optional. List of widget IDs to compare against. Default: Registered widgets. 1355 * @return array Sidebars with whitelisted widgets. 1356 */ 1357 function _wp_remove_unregistered_widgets( $sidebars_widgets, $whitelist = array() ) { 1358 if ( empty( $whitelist ) ) { 1359 $whitelist = array_keys( $GLOBALS['wp_registered_widgets'] ); 1360 } 1361 1362 foreach ( $sidebars_widgets as $sidebar => $widgets ) { 1363 if ( is_array( $widgets ) ) { 1364 $sidebars_widgets[ $sidebar ] = array_intersect( $widgets, $whitelist ); 1365 } 1217 1366 } 1218 1367
Note: See TracChangeset
for help on using the changeset viewer.