[wp-trac] [WordPress Trac] #37561: Inserting rewrite rules using the filter 'option_rewrite_rules' breaks 'WP_Rewrite::flush_rules()', causing 404 errors
WordPress Trac
noreply at wordpress.org
Wed Aug 10 23:17:53 UTC 2016
#37561: Inserting rewrite rules using the filter 'option_rewrite_rules' breaks
'WP_Rewrite::flush_rules()', causing 404 errors
---------------------------+------------------------------
Reporter: maratbn | Owner:
Type: defect (bug) | Status: new
Priority: normal | Milestone: Awaiting Review
Component: Rewrite Rules | Version:
Severity: normal | Resolution:
Keywords: close | Focuses:
---------------------------+------------------------------
Comment (by maratbn):
Replying to [comment:5 SergeyBiryukov]:
> Replying to [comment:4 maratbn]:
> > b/c the Jupiter theme is flushing rewrite rules inside page requests
>
> That sounds like a bad practice the
[https://codex.wordpress.org/flush_rewrite_rules#Usage Codex specifically
warns against].
Well yeah. Since they're doing it after their admin settings are updated,
my guess is that doing it directly from an admin dashboard page request
caused them some other issues and conflicts, so they switched to
{{{wp_loaded}}} inside regular page requests, and to their credit they
have special logic to not do it on subsequent page requests.
Perhaps WordPress could use a kind of a non-optimal code warning feature,
to detect if there is a call to {{{flush_rewrite_rules()}}} inside an
incorrect action, or if some other core operation is being performed
inside an incorrect callback, and to append a warning to a log that could
be displayed in the admin dashboard to warn admins that they're running
themes / plugins with non-optimal logic. This way these problems would
become apparent sooner, and the developers would also try harder to use
the appropriate actions/filters, and to file bug reports when they are
having unusual issues and conflicts using recommended callbacks.
As far as my earlier idea regarding adding a new optional parameter to
{{{wp_rewrite_rules()}}} that will force it to call the method
{{{WP_Rewrite::rewrite_rules()}}} regardless of whether
{{{get_option('rewrite_rules')}}} returns an empty list or not, and that
optional parameter should be passed-in from
{{{WP_Rewrite::flush_rules(...)}}}, what do you guys think about that?
Here's what the patch for that looks like:
{{{
--- wp-includes/class-wp-rewrite.php--BACKUP--2016-08-02--01 2016-08-02
14:57:51.615661000 -0700
+++ wp-includes/class-wp-rewrite.php 2016-08-10 15:47:04.412482000
-0700
@@ -1468,11 +1468,23 @@
* @since 1.5.0
* @access public
*
+ * @param bool $flag_dont_check_cache Optional Whether to always
regenerate the rewrite rules even if they already appear to be present due
to phantom rules being inserted into the cache via the filter
'option_rewrite_rules'.
+ * Default false.
+ *
* @return array Rewrite rules.
*/
- public function wp_rewrite_rules() {
- $this->rules = get_option('rewrite_rules');
- if ( empty($this->rules) ) {
+ public function wp_rewrite_rules($flag_dont_check_cache = false) {
+
+ $flag_actually_rewrite = $flag_dont_check_cache;
+
+ if (!$flag_actually_rewrite) {
+ $this->rules = get_option('rewrite_rules');
+ if ( empty($this->rules) ) {
+ $flag_actually_rewrite = true;
+ }
+ }
+
+ if ($flag_actually_rewrite) {
$this->matches = 'matches';
$this->rewrite_rules();
update_option('rewrite_rules', $this->rules);
@@ -1810,8 +1822,7 @@
unset( $do_hard_later );
}
- update_option( 'rewrite_rules', '' );
- $this->wp_rewrite_rules();
+ $this->wp_rewrite_rules(true);
/**
* Filter whether a "hard" rewrite rule flush should be
performed when requested.
}}}
Alternatively, what about not applying {{{option_rewrite_rules}}} when
retrieving the cached rewrite rules? The patch for that looks like this:
{{{
--- wp-includes/option.php--BACKUP--2016-08-10--01 2016-08-10
15:53:47.104482000 -0700
+++ wp-includes/option.php 2016-08-10 16:11:32.744482000 -0700
@@ -25,9 +25,12 @@
*
* @param string $option Name of option to retrieve. Expected to not be
SQL-escaped.
* @param mixed $default Optional. Default value to return if the option
does not exist.
+ * @param bool $flag_dont_filter
+ * Optional. Don't apply filter 'option_[option
name]'.
+ * Default false.
* @return mixed Value set for the option.
*/
-function get_option( $option, $default = false ) {
+function get_option( $option, $default = false, $flag_dont_filter = false
) {
global $wpdb;
$option = trim( $option );
@@ -120,6 +123,10 @@
if ( in_array( $option, array('siteurl', 'home', 'category_base',
'tag_base') ) )
$value = untrailingslashit( $value );
+ if ($flag_dont_filter) {
+ return maybe_unserialize( $value );
+ }
+
/**
* Filter the value of an existing option.
*
--- wp-includes/class-wp-rewrite.php--BACKUP--2016-08-02--01 2016-08-02
14:57:51.615661000 -0700
+++ wp-includes/class-wp-rewrite.php 2016-08-10 16:10:38.800482000
-0700
@@ -1471,7 +1471,7 @@
* @return array Rewrite rules.
*/
public function wp_rewrite_rules() {
- $this->rules = get_option('rewrite_rules');
+ $this->rules = get_option('rewrite_rules', null, true);
if ( empty($this->rules) ) {
$this->matches = 'matches';
$this->rewrite_rules();
}}}
--
Ticket URL: <https://core.trac.wordpress.org/ticket/37561#comment:6>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list