<?php
/**
 * Plugin Name: Must-use Plugin
 * Description: Custom must-use code
 * Author: Mike Kormendy
 * Author URI: https://www.mikekormendy.com
 */
 
//////////////////////////////////////////////////
// Preserve Query Strings on Old-Slug Redirects //
//////////////////////////////////////////////////
/**
 * WordPress's wp_old_slug_redirect() (wp-includes/query.php) builds its
 * redirect destination via get_permalink() and drops the original request's
 * query string entirely. This filter re-appends unknown query args so that
 * UTM tags, custom params, and any non-WP-internal values survive the 301.
 *
 * The "WP-internal" args to strip are sourced live from $wp->public_query_vars
 * + $wp->private_query_vars (not a hardcoded list) so the set stays in sync
 * with WordPress core and any plugin that registers its own query vars.
 */
add_filter( 'old_slug_redirect_url', function ( $link ) {
	if ( empty( $link ) || empty( $_SERVER['QUERY_STRING'] ) ) {
		return $link;
	}

	parse_str( (string) $_SERVER['QUERY_STRING'], $args );

	$wp_internals = [];
	if ( isset( $GLOBALS['wp'] ) && $GLOBALS['wp'] instanceof WP ) {
		$wp_internals = array_merge(
			(array) $GLOBALS['wp']->public_query_vars,
			(array) $GLOBALS['wp']->private_query_vars
		);
	}

	$strip = array_merge(
		$wp_internals,
		wp_removable_query_args(),
		// Preview/security tokens — never carry these through a 301:
		[ 'preview', 'preview_id', 'preview_nonce' ],
		// Owned by Block_User_Enumeration above (intentionally dropped):
		[ 'author' ]
	);
	foreach ( $strip as $key ) {
		unset( $args[ $key ] );
	}

	if ( ! $args ) {
		return $link;
	}

	// Mirror redirect_canonical()'s encoding (canonical.php:586-593): rawurlencode
	// keys+values so add_query_arg() emits a query string that round-trips cleanly
	// (e.g. preserves '%2B' rather than letting it decode to '+').
	$args = array_combine(
		rawurlencode_deep( array_keys( $args ) ),
		rawurlencode_deep( array_values( $args ) )
	);

	return add_query_arg( $args, $link );
} );