如何在插件停用时运行flush_rewrite_rules

时间:2014-02-14 19:20:40

标签: wordpress-plugin wordpress

我希望我的插件在停用时删除/刷新它正在设置的重写规则。这就是我所拥有的。我不知道为什么,即使插件已停用,重写规则仍然有效。

由于

<?php
if(!class_exists('MyPlugin'))
{
    class MyPlugin
    {

        public function __construct() {
            add_action('init', array( &$this, 'add_rewrite_rule' ) );
            add_action('init', array( &$this, 'add_rewrite_tag' ) );
        } 

        public static function activate() {  } 

        public static function deactivate() {
            flush_rewrite_rules();
        } 

        public function add_rewrite_rule(){
            global $wp_rewrite;
            add_rewrite_rule('^content/([^/]*)/?$','index.php?page_id=10&myuniquepid=$matches[1]','top');
            $wp_rewrite->flush_rules();
        }

        public function add_rewrite_tag(){
            add_rewrite_tag('%myuniquepid%','([^&]+)');
        }

    } // END class MyPlugin
} // END if(!class_exists('MyPlugin'))

if(class_exists('MyPlugin'))
{
    // Installation and uninstallation hooks
    register_activation_hook(__FILE__, array('MyPlugin', 'activate'));
    register_deactivation_hook(__FILE__, array('MyPlugin', 'deactivate'));

    // instantiate the plugin class
    $myplugin = new MyPlugin();
}

1 个答案:

答案 0 :(得分:0)

重要

如评论中所述,请确保仅在需要时才使用flush_rewrite_rules。这是一项昂贵的操作,因此只能在绝对必要时使用。

问题

register_activation_hook()运行之前, initplugins_loaded操作。

register_deactivation_hook() initplugins_loaded动作之后运行。

如果您要处理数据库的创建/删除操作,而不是在我们要添加或清理重写规则的情况下,这很好。

大多数插件使用initplugins_loaded操作来加载所有内容并生成重写规则。激活钩子在此之前被调用。

停用钩子在周期的后期运行,因此您的rewrite_rules逻辑得到处理,并且在停用时也被添加,没有任何清理。

可能的解决方案

下面是一个非常基本的插件示例,该示例在(de)激活操作中处理flush_rewrite_rules。未经测试,我将其与我正在构建的插件放在一起。

<?php
/*
  Plugin Name: Flush Rewrite Rules testing
  Plugin URI: https://fake.com
  Description: flsuh rewrite rules on activation/deactivation
  Version: 0.0.1
  Author: Bjorn
  Author URI: https://fake.com
*/

if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly

register_activation_hook( __FILE__, 'frrt_activation');
register_deactivation_hook( __FILE__, 'frrt_deactivation');
add_action('init', 'frrt_flush_rewrite_rules');

function frrt_activation() {
  if ( ! get_option( 'frrt_flush_rewrite_rules_flag' ) ) add_option( 'frrt_flush_rewrite_rules_flag', true );
}

function frrt_deactivation() {
  flush_rewrite_rules();
}

function frrt_flush_rewrite_rules() {
  if( get_option( 'frrt_flush_rewrite_rules_flag' ) ) {
    add_filter('generate_rewrite_rules', 'frrt_generate_rewrite_rules');
    flush_rewrite_rules();
    delete_option( 'frrt_flush_rewrite_rules_flag' );
  }
}

function frrt_generate_rewrite_rules($wp_rewrite) {
  $wp_rewrite->rules = array_merge(
    ['some-base-url/([^/]+)/?$' => 'index.php?example_query_var=$matches[1]'],
    $wp_rewrite->rules
  );
}

在激活时设置一个标志(选项),以便我们可以生成并刷新init操作上的重写规则。停用工作按预期进行,因为我们仅在激活时生成重写规则。

我认为这根本不是理想的选择,因为我们对每个get_option()动作都执行一次数据库查询(init),这不需要99,9999%的时间... 但这是唯一对我有用的解决方法。

WP认为这不是错误,请参阅此Trac ticket

如果有人有更好的解决方案,请分享;-)。