Make WordPress Core

Ticket #65267: mu-plugin.php

File mu-plugin.php, 2.0 KB (added by mkormendy, 4 months ago)

A workaround (in mu-plugin).

Line 
1<?php
2/**
3 * Plugin Name: Must-use Plugin
4 * Description: Custom must-use code
5 * Author: Mike Kormendy
6 * Author URI: https://www.mikekormendy.com
7 */
8
9//////////////////////////////////////////////////
10// Preserve Query Strings on Old-Slug Redirects //
11//////////////////////////////////////////////////
12/**
13 * WordPress's wp_old_slug_redirect() (wp-includes/query.php) builds its
14 * redirect destination via get_permalink() and drops the original request's
15 * query string entirely. This filter re-appends unknown query args so that
16 * UTM tags, custom params, and any non-WP-internal values survive the 301.
17 *
18 * The "WP-internal" args to strip are sourced live from $wp->public_query_vars
19 * + $wp->private_query_vars (not a hardcoded list) so the set stays in sync
20 * with WordPress core and any plugin that registers its own query vars.
21 */
22add_filter( 'old_slug_redirect_url', function ( $link ) {
23 if ( empty( $link ) || empty( $_SERVER['QUERY_STRING'] ) ) {
24 return $link;
25 }
26
27 parse_str( (string) $_SERVER['QUERY_STRING'], $args );
28
29 $wp_internals = [];
30 if ( isset( $GLOBALS['wp'] ) && $GLOBALS['wp'] instanceof WP ) {
31 $wp_internals = array_merge(
32 (array) $GLOBALS['wp']->public_query_vars,
33 (array) $GLOBALS['wp']->private_query_vars
34 );
35 }
36
37 $strip = array_merge(
38 $wp_internals,
39 wp_removable_query_args(),
40 // Preview/security tokens — never carry these through a 301:
41 [ 'preview', 'preview_id', 'preview_nonce' ],
42 // Owned by Block_User_Enumeration above (intentionally dropped):
43 [ 'author' ]
44 );
45 foreach ( $strip as $key ) {
46 unset( $args[ $key ] );
47 }
48
49 if ( ! $args ) {
50 return $link;
51 }
52
53 // Mirror redirect_canonical()'s encoding (canonical.php:586-593): rawurlencode
54 // keys+values so add_query_arg() emits a query string that round-trips cleanly
55 // (e.g. preserves '%2B' rather than letting it decode to '+').
56 $args = array_combine(
57 rawurlencode_deep( array_keys( $args ) ),
58 rawurlencode_deep( array_values( $args ) )
59 );
60
61 return add_query_arg( $args, $link );
62} );