[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 3 22:46:36 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:  Permalinks    |    Version:  trunk
 Severity:  normal        |   Keywords:
  Focuses:                |
--------------------------+-----------------------------
 To reproduce:

 1. Enable permalinks.
 2. Subscribe to the filter {{{option_rewrite_rules}}}
 3. Insert an additional rule inside your callback function for this
 filter.
 4. Call {{{flush_rewrite_rules(...)}}} or
 {{{WP_Rewrite::flush_rules(...)}}}
 5. Go to any page of your site that's not the front / home page via its
 permalink, and you'll get a page not found 404 error. (Because the rewrite
 rules will not be properly regenerated).

 The rewrite rules will not get regenerated because the method
 {{{WP_Rewrite::wp_rewrite_rules()}}}, which is called internally via
 {{{WP_Rewrite::flush_rules(...)}}}, is unable to do so when its current
 list of rewrite rules is not completely empty.  You can see this on line
 1475 of the current revision {{{wp-includes/class-wp-rewrite.php}}}
 https://github.com/WordPress/WordPress/blob/ada44f2e13cde6a2134bb9a4df628068f7c82dcb
 /wp-includes/class-wp-rewrite.php#L1475

 There is an if-conditional there that prevents the rewrite rules from
 getting regenerated when the rewrite rules list is not empty.  And the
 rewrite rules list is prevented from getting empty by that
 {{{option_rewrite_rules}}} filter callback.

 This means that calling {{{WP_Rewrite::flush_rules(...)}}} will delete all
 the rewrite rules except those inserted by the {{{option_rewrite_rules}}}
 filter, which will result in 404s for most of the permalinks.

 This problem is currently reproducible if running combinations of some
 popular plugins / themes, such as the Gravity Forms plugin with the Web
 API enabled together with the Jupiter Theme.

 The Gravity Forms plugin is inserting its rewrite rules using this
 problematic filter here https://github.com/wp-
 premium/gravityforms/blob/1b22ba00f53542f94d65d285e84a91d790f5b72c/includes/webapi/webapi.php#L365
 and the Jupiter Theme is calling {{{WP_Rewrite::flush_rules(...)}}} here
 https://gist.github.com/maratbn/af888ceaf42a1d797d0be962ec1c4c25#file-
 general-functions-php-L91

 But the underlying crux of this problem is that using a filter in an
 apparently legal way is breaking the flush-rewrite-rules core
 functionality, which should not be happening, and what this ticket is
 about.

 Perhaps the method {{{WP_Rewrite::wp_rewrite_rules()}}} could use a new
 optional parameter 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(...)}}}.

 Otherwise there needs to be some advisory to not use the filter
 {{{option_rewrite_rules}}}, and perhaps use {{{rewrite_rules_array}}}
 instead.

--
Ticket URL: <https://core.trac.wordpress.org/ticket/37561>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list