Как удалить фильтр, который является анонимным объектом?

В моем файле functions.php я хотел бы удалить приведенный ниже фильтр, но я не уверен, как это сделать, поскольку он находится в классе. Как должна выглядеть remove_filter() ?

add_filter('comments_array',array( &$this, 'FbComments' ));

Понравилась статья? Поделиться с друзьями:
WPAsk
Ответов: 3
  1. Hamed Momeni

    Вы должны сохранить ссылку на объект в статическом свойстве вашего класса и затем вернуть эту статическую переменную из статического метода. Примерно так:

    class MyClass{
        private static $ref;
        function MyClass(){
            $ref = &$this;
        }
        public static function getReference(){
            return self::$ref;
        }
    }
    
  2. hakre

    Пока вам известен объект, то можете просто удалить его с помощью remove_filter() . Все, что вам нужно запомнить, это объект, имя метода и приоритет (если используется):

    remove_filter('comment_array', [$this, 'FbComments']);
    
  3. fuxia

    Это очень хороший вопрос. Это относится к API плагина и лучших практик программирования.

    Вот пример плагина, чтобы проиллюстрировать проблему.

    <?php # -*- coding: utf-8 -*-
    /* Plugin Name: Anonymous OOP Action */
    
    if ( ! class_exists( 'Anonymous_Object' ) )
    {
        /**
         * Добавьте некоторые действия с рандомизированными глобальными идентификаторами.
         */
        class Anonymous_Object
        {
            public function __construct()
            {
                add_action( 'wp_footer', array ( $this, 'print_message_1' ), 5 );
                add_action( 'wp_footer', array ( $this, 'print_message_2' ), 5 );
                add_action( 'wp_footer', array ( $this, 'print_message_3' ), 12 );
            }
    
            public function print_message_1()
            {
                print '<p>Kill me!</p>';
            }
    
            public function print_message_2()
            {
                print '<p>Me too!</p>';
            }
    
            public function print_message_3()
            {
                print '<p>Aaaand me!</p>';
            }
        }
    
       
        new Anonymous_Object;
    }
    

    В итоге вы увидите:

    enter image description here

    WordPress нужно имя для фильтра. Мы не предоставили его, поэтому WordPress вызывает _wp_filter_build_unique_id() и создает его. Это имя не предсказуемо, поскольку оно использует spl_object_hash() .

    Если вызывается var_export() в $GLOBALS['wp_filter'][ 'wp_footer' ] мы получаем что-то вроде этого:

    array (
      5 => 
      array (
        '000000002296220e0000000013735e2bprint_message_1' => 
        array (
          'function' => 
          array (
            0 => 
            Anonymous_Object::__set_state(array(
            )),
            1 => 'print_message_1',
          ),
          'accepted_args' => 1,
        ),
        '000000002296220e0000000013735e2bprint_message_2' => 
        array (
          'function' => 
          array (
            0 => 
            Anonymous_Object::__set_state(array(
            )),
            1 => 'print_message_2',
          ),
          'accepted_args' => 1,
        ),
      ),
      12 => 
      array (
        '000000002296220e0000000013735e2bprint_message_3' => 
        array (
          'function' => 
          array (
            0 => 
            Anonymous_Object::__set_state(array(
            )),
            1 => 'print_message_3',
          ),
          'accepted_args' => 1,
        ),
      ),
      20 => 
      array (
        'wp_print_footer_scripts' => 
        array (
          'function' => 'wp_print_footer_scripts',
          'accepted_args' => 1,
        ),
      ),
      1000 => 
      array (
        'wp_admin_bar_render' => 
        array (
          'function' => 'wp_admin_bar_render',
          'accepted_args' => 1,
        ),
      ),
    )
    

    Создадим функцию:

    if ( ! function_exists( 'remove_anonymous_object_filter' ) )
    {
        /**
         * Удалить анонимный объект фильтра.
         *
         * @param  string $tag    Hook name.
         * @param  string $class  Class name
         * @param  string $method Method name
         * @return void
         */
        function remove_anonymous_object_filter( $tag, $class, $method )
        {
            $filters = $GLOBALS['wp_filter'][ $tag ];
    
            if ( empty ( $filters ) )
            {
                return;
            }
    
            foreach ( $filters as $priority => $filter )
            {
                foreach ( $filter as $identifier => $function )
                {
                    if ( is_array( $function)
                        and is_a( $function['function'][0], $class )
                        and $method === $function['function'][1]
                    )
                    {
                        remove_filter(
                            $tag,
                            array ( $function['function'][0], $method ),
                            $priority
                        );
                    }
                }
            }
        }
    }
    

    Когда мы вызываем эту функцию? Невозможно точно знать, когда создается исходный объект. Может быть, иногда до 'plugins_loaded' . А может быть позже.

    Мы используем точно такой же хук, с которым связан объект, и очень рано переключаемся с приоритетом 0 . Это единственный способ быть уверенным. Вот как мы должны удалить метод print_message_3() :

    add_action( 'wp_footer', 'kill_anonymous_example', 0 );
    
    function kill_anonymous_example()
    {
        remove_anonymous_object_filter(
            'wp_footer',
            'Anonymous_Object',
            'print_message_3'
        );
    }
    

    Результат:

    enter image description here

    Удалить действие из вашего вопроса (не проверено):

    add_action( 'comments_array', 'kill_FbComments', 0 );
    
    function kill_FbComments()
    {
        remove_anonymous_object_filter(
            'comments_array',
            'SEOFacebookComments',
            'FbComments'
        );
    }
    
Добавить ответ

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: