Действие save_post для произвольного типа записи не срабатывает

10 дек. 2012 г., 18:33:04
Просмотры: 20.9K
Голосов: 5

Извините, если этот вопрос уже был здесь отвечен. Я искал, но не нашел ответов на свой вопрос, поэтому решил создать свой собственный.

Я разрабатываю плагин для клиента, который собирает отзывы клиентов о недавно завершенном проекте.

Администратор будет использовать систему для отправки "запроса" клиенту, прося его оставить отзыв со ссылкой на форму на сайте.

Я создал произвольный тип записи "customer_prompts", который имеет только поле заголовка и несколько пользовательских полей, которые хранятся в пользовательской таблице базы данных, а не в метаданных записи.

Ниже мой код для действия save_post. Похоже, что когда я нажимаю "Опубликовать", действие save_post не срабатывает и сохраняется только значение заголовка в wp_posts.

add_action('save_post', 'save_prompt');
function save_prompt($post_id){
$post = get_post($post_id);

    // Проверка выполнения автосохранения
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) 
          return;

    // Проверка типа записи и прав пользователя
    if ( 'customer_prompt' == $_POST['post_type'] ) 
    {
        if ( !current_user_can( 'edit_page', $post_id ) )
            return;
    }
    else
    {
        if ( !current_user_can( 'edit_post', $post_id ) )
        return;
    }

    global $wpdb;

    $prompt_id = com_create_guid();
    $customer_feedback_name = $_POST['_sdg_customer_feedback_name'];
    $customer_feedback_email = $_POST['_sdg_customer_feedback_email'];
    $salesperson = $_POST['_sdg_salesperson'];

    $values = array(
        'id' => $prompt_id, 
        'sdg_customer_name' => $customer_feedback_name,
        'sdg_customer_email' => $customer_feedback_email,
        'sdg_salesperson' => $salesperson,
        'sdg_post_id' => $post->id
    );

    $insert = $wpdb->insert($table_name, $values);

    if($insert) {
        mail($customer_feedback_email, 'hello', 'hello');
    }

}

Буду очень признателен за любую помощь, так как я не могу понять, что здесь происходит.

Спасибо, Джейми.

5
Комментарии

Сработает ли, если убрать проверки для типа записи и прав доступа? Возможно, логическая ошибка.

fuxia fuxia
10 дек. 2012 г. 18:35:37

Я попробовал их закомментировать, но всё равно не работает.

JamieCassidy JamieCassidy
10 дек. 2012 г. 18:43:12

Попробуй использовать первый пример из кодекса1

M-R M-R
10 дек. 2012 г. 18:55:34

Пробовал это, но всё равно не работает. Похоже, что действие save_post выполняется при создании нового поста из боковой панели, но не выполняется при нажатии кнопки "Опубликовать". Я пробовал разные хуки действий, такие как publish_post и edit_post, но ни один из них не работает.

JamieCassidy JamieCassidy
11 дек. 2012 г. 11:06:27

Просто вывод глобальной переменной $_POST и метод die(); в начале функции должны показать, что находится в массиве $_POST, чтобы убедиться, что WordPress правильно его обработал. Также убедитесь, что meta id правильно указан в значении "name" поля ввода, если это верно. Тогда вы быстро найдёте ошибку.

Stanley Aloh Stanley Aloh
4 дек. 2020 г. 12:21:05
Все ответы на вопрос 6
1
15

Действие "save_post" вызывается только при фактическом изменении чего-либо в форме страницы записи. Если просто нажать кнопку обновления, не меняя ничего, действие "save_post" не будет вызвано.

Это важно при редактировании произвольного типа записи с пользовательскими метабоксами. Если полагаться на действие "save_post" и изменять только данные в пользовательских метабоксах, ничего не произойдет.

Решение заключается в использовании хука "pre_post_update" вместо "save_post".

http://wordpress.org/support/topic/save_post-not-working-getting-called#post-2335557

17 мар. 2013 г. 00:03:11
Комментарии

Это не работает, если вы нажимаете "Предварительный просмотр изменений".

Sam Rueby Sam Rueby
18 янв. 2018 г. 23:58:30
3

правка Вы пробовали добавить print_r('hello world'); die(); после function save_prompt($post_id){, чтобы убедиться, что функция действительно срабатывает через хук действия? /правка

Возможны несколько проблем:

1: Ваш global wpdb должен быть в самом начале функции, перед всеми условными операторами.

2: Для ваших $_POST переменных следует добавить проверки типа if(isset($_POST['food'])), чтобы убедиться, что данные действительно передаются перед вызовом функции, иначе это может вызывать фатальную ошибку, препятствуя записи в БД.

3: Попробуйте добавить global $post в начале функции, тогда вы сможете обращаться к переменным поста, например $post->post_type, через объект $post.

4: Добавьте $wpdb->print_errors; die(); после $insert = $wpdb->insert($table_name, $values); на случай, если ваш SQL-запрос некорректен.

Надеюсь, одно из этих решений поможет исправить вашу проблему.

11 дек. 2012 г. 11:38:40
Комментарии

Импорт глобальной переменной в область видимости функции должен происходить до её использования, но не обязательно в самом начале функции.

fuxia fuxia
11 дек. 2012 г. 11:53:00

Однако, согласно лучшим практикам, встречались случаи, когда глобальные переменные не работали из-за того, что не были объявлены в начале функции.

Caleuanhopkins Caleuanhopkins
11 дек. 2012 г. 12:04:21

Я пробовал выводить что-то в самом начале функции, и это действительно появлялось в верхней части страницы после нажатия "Добавить новый" в боковой панели. Однако после публикации это исчезает, как будто функция вообще не срабатывает при нажатии на кнопку "Опубликовать".

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

JamieCassidy JamieCassidy
11 дек. 2012 г. 14:00:14
0

Прежде всего, я рекомендую настроить ваш сайт на WordPress для удобной отладки http://codex.wordpress.org/Debugging_in_WordPress

Так будет проще видеть что происходит ;)

Для хука действия, полагаю, вам нужно подключить его так:

add_action('save_post', 'save_prompt', 10, 2);
function save_prompt( $post_id, $post ){
//делаем что нужно
}

Хук save_post передаёт 2 аргумента.

10 янв. 2013 г. 17:53:51
0

Со мной случилось то же самое. Оказалось, что у меня был установлен шаблон страницы (значение post-meta для _wp_page_template), который больше не существовал после смены темы. Вот этот фрагмент кода в wp-includes/post.php:

if ( ! empty( $postarr['page_template'] ) ) {
    $post->page_template = $postarr['page_template'];
    $page_templates = wp_get_theme()->get_page_templates( $post );
    if ( 'default' != $postarr['page_template'] && ! isset( $page_templates[ $postarr['page_template'] ] ) ) {
        if ( $wp_error ) {
            return new WP_Error( 'invalid_page_template', __( 'Неверный шаблон страницы.' ) );
        }
        ...

прерывает выполнение перед вызовом save_post.

22 дек. 2017 г. 22:42:27
0

Я думаю, var_dump в add_action('save_post', callback функция не отображается!

Добавьте

$fp = fopen('c:\data.txt', 'w');
fwrite($fp, print_r($post_id, true));
fclose($fp);

и проверьте, существует ли файл 'data.txt' - да, это работает при save_post.

:)

14 окт. 2018 г. 22:00:06
0

У меня была точно такая же проблема, и я решил добавить свой вариант ответа, чтобы помочь сэкономить кому-то время. Это была очень простая проблема, на выявление которой у меня ушло несколько дней (сейчас я немного лысее — и чувствую себя немного глупо)...

Оказалось, что форма метабокса содержала поле "action", которое перезаписывало поле "action" формы, сгенерированной WordPress. Форма использовалась только для пользовательского типа записи, и в результате при POST-запросе на 'wp-admin/post.php' передавалось неправильное действие, которое обрабатывалось обработчиком по умолчанию (в конце оператора switch).

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

Решение заключалось в удалении скрытого элемента формы 'action' для метабокса.

Надеюсь, это поможет кому-то...

13 нояб. 2018 г. 10:51:12