Add_action не вызывает функцию обратного вызова

Вопрос или проблема

В настоящее время я пытаюсь создать плагин для WordPress для создания страницы настроек. Но по какой-то причине, когда я использую add_action("admin_init", array(class_object, 'function_name')), функция add_action выполняется, но не доходит до обратного вызова. Она просто пропускает его.

Я попробовал создать тестовый класс с одной функцией так же, как в основном классе, и это работает. Значит, я делаю что-то не так где-то, но не знаю, что именно.

Вот код. Я разделил код на 3 разных файла, и я размещу его в порядке включения файлов.

Файл индекса для плагина

include('admin/options.php');

function social_share_menu_item() {
    add_submenu_page("options-general.php", "Social Share", "Social Share", "manage_options", "social-share", 'socialShareOptions');
}
add_action("admin_menu", "social_share_menu_item");

...

options.php

include_once('settings/SocialOptions.class.php');

function socialShareOptions(){

    $options = array(
        array(
            'type'  => 'checkbox',
            'name'  => 'social-share-facebook',
            'value' => 1,
            'title' => 'Показать Facebook '
        ),
        array(
            'type'  => 'checkbox',
            'name'  => 'social-share-twitter',
            'value' => 1,
            'title' => 'Показать Twitter'
        ),
        array(
            'type'  => 'checkbox',
            'name'  => 'social-share-instagram',
            'value' => 1,
            'title' => 'Показать Instagram'
        )
    );

    $socialOptions = new SocialOptions($options);
    $socialOptions->buildSettingsPage();
    add_action("admin_init", array($socialOptions, 'setOptions') );
}

SocialOptions.class.php

class SocialOptions {

    private $_optionsArray;

    function __construct( $options = array() ) {

        $this->_optionsArray = $options;

    }

    public function setOptions() {

        add_settings_section("social_share_config_section", "", null, "social-share");

        foreach ( $this->_optionsArray as $option) {
            add_settings_field("social-share-facebook", $option['title'], array($this, 'option'), "social-share", "social_share_config_section", $option);
        }
        foreach ( $this->_optionsArray as $option) {
            register_setting("social_share_config_section", $option['name']);
        }
    }

    public function option( $fieldData ){
        ?>
        <input type="<?php echo $fieldData['type'] ?> " name="<?php echo $fieldData['name']; ?>" value="<?php echo $fieldData['value'] ?>"<?php checked(1, get_option($fieldData['name']), true)?> /><?php echo $fieldData['title'] ?>
        <?php
    }

    public function buildSettingsPage() {

        $html="<div class="wrap social-admin-style">

                    <div class="title">
                        <h1>Настройки социального обмена</h1>
                    </div>

                    <div class="main-content">

                        <form method="post" action="options.php">

                            " . settings_fields("social_share_config_section") . ' 

                            ' . do_settings_sections("social-share") . '

                            '. submit_button() . '

                        </form>

                    </div>

                </div>';

        echo $html;

    }

}

Как уже упоминалось, при отладке кода я вижу, что функция add_action выполняется, но в какой-то момент она просто пропускает конец функции и никогда не заходит в метод setOptions.

Когда я создаю следующее, все работает нормально:

options.php

include_once('settings/SocialOptions.class.php');

class Test {
    function testing(){
     return 'ничего';
    }
}

function socialShareOptions(){

    $options = array(
        ...
    );

    $socialOptions = new SocialOptions($options);
    $socialOptions->buildSettingsPage();

    /*ОБРАТИТЕ ВНИМАНИЕ НА ЭТУ ЧАСТЬ*/
    $test = new Test();
    add_action("admin_init", array($test, 'testing') );
}

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

Дополнительная информация

подсказано B. Schuiling
В php error logs я не вижу никаких ошибок.

Надеюсь, вы сможете помочь. Спасибо, что уделили время для чтения этого. Если вам нужна дополнительная информация, пожалуйста, дайте мне знать.

ИЗМЕНЕНИЕ
Хотя первоначальный ответ не указывал на причину проблемы, я хотел бы, чтобы вы все ссылались на ответ B. Schuiling. В комментариях он объяснил, что add_action был вызван слишком поздно и поэтому не выполнялся.

Ниже приведена измененная страница options.php (я пропустил очевидный код, чтобы сократить объем).

пс хотя это работает, я собираюсь изменить код на синглтон. Это также основано на ссылке, которую B. Schuiling разместил в комментариях к своему собственному ответу ниже.

Обратите внимание, что массив опций и инстанцирование класса теперь вне функции socialShareOptions.

include_once('settings/SocialOptions.class.php');

$options = array(
    ...
    )
);
$socialOptions = new SocialOptions($options);
add_action("admin_init", array($socialOptions, 'setOptions'));

function socialShareOptions(){
    global $socialOptions;

    $socialOptions->buildSettingsPage();
}

В вашем классе ваша функция называется ‘public function setOption()’, а не setOptionS. Проверьте свой лог ошибок на предмет подобных проблем.

Также в вашем коде я не вижу, чтобы функция ‘socialShareOptions’ на самом деле вызывалась где-либо.

Ответ или решение

Диагностика проблемы: add_action не вызывает функцию обратного вызова

В процессе разработки плагина для WordPress может возникнуть проблема, когда функция обратного вызова, назначенная с помощью add_action, не вызывается, даже если add_action сам по себе выполняется. Давайте подробно разберем вашу ситуацию, чтобы установить причину и предложить решение.

Описание проблемы

Вы столкнулись с тем, что функция setOptions вашего класса SocialOptions не вызывается в результате выполнения действия admin_init. Вместо этого WordPress просто пропускает выполнение этой функции. Данная проблема часто связана с порядком вызова и временем выполнения ваших функций относительно хуков WordPress.

Пример кода

Ваш код состоит из трех частей: основного файла плагина, файла options.php и файла класса SocialOptions.class.php. Это создает определенную структуру для добавления элементов на страницу настроек, но неявные проблемы могут возникнуть из-за некоторых нюансов.

Анализ имеющегося кода

  1. Функция socialShareOptions():

    • Вы добавляете действие add_action("admin_init", array($socialOptions, 'setOptions')); внутри функции socialShareOptions().
    • Однако функция socialShareOptions не вызывается по умолчанию, что может привести к тому, что действие admin_init вообще не выполнится, и, следовательно, ваша функция setOptions не будет вызвана.
  2. Проблема с порядком выполнения:

    • add_action должен быть вызван до того, как работа с хуками начнется. Если в момент добавления действия WordPress уже инициировал хук admin_init, ваша функция не будет зарегистрирована. В вашем случае функция setOptions не будет вызвана, поскольку добавление действия осуществляется только после вызова socialShareOptions().

Решение проблемы

Для исправления кода рекомендуется вынести добавление действия add_action из функции socialShareOptions(), чтобы оно вызывалось на этапе инициализации, а не тогда, когда обрабатывается функция отображения страницы настроек.

Модифицированный код options.php:

include_once('settings/SocialOptions.class.php');

// Определяем массив опций
$options = array(
    array(
        'type'  => 'checkbox',
        'name'  => 'social-share-facebook',
        'value' => 1,
        'title' => 'Показать Facebook'
    ),
    array(
        'type'  => 'checkbox',
        'name'  => 'social-share-twitter',
        'value' => 1,
        'title' => 'Показать Twitter'
    ),
    array(
        'type'  => 'checkbox',
        'name'  => 'social-share-instagram',
        'value' => 1,
        'title' => 'Показать Instagram'
    )
);

// Создаем экземпляр класса вне функции
$socialOptions = new SocialOptions($options);

// Добавляем действие на admin_init до вызова socialShareOptions
add_action("admin_init", array($socialOptions, 'setOptions'));

function socialShareOptions() {
    global $socialOptions;
    $socialOptions->buildSettingsPage();
}

Вывод

Ключевой аспект, который необходимо помнить — это порядок выполнения и инициализации ваших функций и хуков в WordPress. Если функция, к которой вы хотите обратиться, вызывается внутри другой функции, то сначала убедитесь, что первая функция будет вызвана. Как вы и заметили, исходная проблема заключалась в том, что действие добавлялось слишком поздно в цепочке вызовов.

Переход к паттерну с синглтоном, как вы упомянули, также может быть полезным для улучшения управления экземплярами классов и повышения читаемости кода.

Если будут возникать дополнительные вопросы или сложности, не стесняйтесь обращаться за помощью. Удачи в развитии вашего плагина!

Оцените материал
Добавить комментарий

Капча загружается...