@@ -1255,3 +1255,129 @@ function generate_postdata( $post ) {
12551255
12561256 return false ;
12571257}
1258+
1259+ /**
1260+ * Redirect old term slugs to the correct term link.
1261+ *
1262+ * Attempts to find the current term slug from the past slugs.
1263+ *
1264+ * @since x.x.x
1265+ */
1266+ function wp_old_slug_term_redirect () {
1267+ if ( ! is_404 () ) {
1268+ return ;
1269+ }
1270+
1271+ $ taxonomy = '' ;
1272+ $ slug = '' ;
1273+
1274+ if ( '' !== get_query_var ( 'category_name ' ) ) {
1275+ $ taxonomy = 'category ' ;
1276+ $ slug = get_query_var ( 'category_name ' );
1277+ } elseif ( '' !== get_query_var ( 'tag ' ) ) {
1278+ $ taxonomy = 'post_tag ' ;
1279+ $ slug = get_query_var ( 'tag ' );
1280+ } elseif ( '' !== get_query_var ( 'taxonomy ' ) && '' !== get_query_var ( 'term ' ) ) {
1281+ $ taxonomy = get_query_var ( 'taxonomy ' );
1282+ $ slug = get_query_var ( 'term ' );
1283+ }
1284+
1285+ if ( str_contains ( $ slug , '/ ' ) ) {
1286+ $ slug = basename ( $ slug );
1287+ }
1288+
1289+ if ( '' === $ taxonomy || '' === $ slug ) {
1290+ return ;
1291+ }
1292+
1293+ $ term_id = _find_term_by_old_slug ( $ slug , $ taxonomy );
1294+
1295+ if ( ! $ term_id ) {
1296+ return ;
1297+ }
1298+
1299+ /**
1300+ * Filters the old slug redirect term ID.
1301+ *
1302+ * @since x.x.x
1303+ *
1304+ * @param int $term_id The redirect term ID.
1305+ */
1306+ $ term_id = apply_filters ( 'old_slug_redirect_term_id ' , $ term_id );
1307+
1308+ if ( ! $ term_id ) {
1309+ return ;
1310+ }
1311+
1312+ $ link = get_term_link ( (int ) $ term_id , $ taxonomy );
1313+
1314+ if ( is_wp_error ( $ link ) ) {
1315+ return ;
1316+ }
1317+
1318+ if ( get_query_var ( 'paged ' ) > 1 ) {
1319+ if ( get_option ( 'permalink_structure ' ) ) {
1320+ $ link = trailingslashit ( $ link ) . 'page/ ' . get_query_var ( 'paged ' );
1321+ } else {
1322+ $ link = add_query_arg ( 'paged ' , get_query_var ( 'paged ' ), $ link );
1323+ }
1324+ } elseif ( is_feed () ) {
1325+ if ( get_option ( 'permalink_structure ' ) ) {
1326+ $ link = trailingslashit ( $ link ) . 'feed ' ;
1327+ } else {
1328+ $ link = add_query_arg ( 'feed ' , get_default_feed (), $ link );
1329+ }
1330+ }
1331+
1332+ /**
1333+ * Filters the old slug redirect URL.
1334+ *
1335+ * @since 4.4.0
1336+ *
1337+ * @param string $link The redirect URL.
1338+ */
1339+ $ link = apply_filters ( 'old_slug_redirect_url ' , $ link );
1340+
1341+ if ( ! $ link ) {
1342+ return ;
1343+ }
1344+
1345+ wp_redirect ( $ link , 301 );
1346+ exit ;
1347+ }
1348+
1349+ /**
1350+ * Find the term ID for redirecting an old slug.
1351+ *
1352+ * @since x.x.x
1353+ * @access private
1354+ *
1355+ * @see wp_old_slug_term_redirect()
1356+ * @global wpdb $wpdb WordPress database abstraction object.
1357+ *
1358+ * @param string $slug The term slug to search for.
1359+ * @param string $taxonomy The taxonomy to search within.
1360+ * @return int The term ID.
1361+ */
1362+ function _find_term_by_old_slug ( $ slug , $ taxonomy ) {
1363+ global $ wpdb ;
1364+
1365+ $ query = $ wpdb ->prepare (
1366+ "SELECT tm.term_id FROM $ wpdb ->termmeta AS tm INNER JOIN $ wpdb ->term_taxonomy AS tt ON tm.term_id = tt.term_id WHERE tm.meta_key = '_wp_old_slug' AND tm.meta_value = %s AND tt.taxonomy = %s " ,
1367+ $ slug ,
1368+ $ taxonomy
1369+ );
1370+
1371+ $ last_changed = wp_cache_get_last_changed ( 'terms ' );
1372+ $ key = md5 ( $ query );
1373+ $ cache_key = "find_term_by_old_slug: $ key " ;
1374+ $ cache = wp_cache_get_salted ( $ cache_key , 'term-queries ' , $ last_changed );
1375+ if ( false !== $ cache ) {
1376+ return (int ) $ cache ;
1377+ }
1378+
1379+ $ term_id = (int ) $ wpdb ->get_var ( $ query );
1380+ wp_cache_set_salted ( $ cache_key , $ term_id , 'term-queries ' , $ last_changed );
1381+
1382+ return $ term_id ;
1383+ }
0 commit comments