Действие save_post для произвольного типа записи не срабатывает
Извините, если этот вопрос уже был здесь отвечен. Я искал, но не нашел ответов на свой вопрос, поэтому решил создать свой собственный.
Я разрабатываю плагин для клиента, который собирает отзывы клиентов о недавно завершенном проекте.
Администратор будет использовать систему для отправки "запроса" клиенту, прося его оставить отзыв со ссылкой на форму на сайте.
Я создал произвольный тип записи "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');
}
}
Буду очень признателен за любую помощь, так как я не могу понять, что здесь происходит.
Спасибо, Джейми.

Действие "save_post" вызывается только при фактическом изменении чего-либо в форме страницы записи. Если просто нажать кнопку обновления, не меняя ничего, действие "save_post" не будет вызвано.
Это важно при редактировании произвольного типа записи с пользовательскими метабоксами. Если полагаться на действие "save_post" и изменять только данные в пользовательских метабоксах, ничего не произойдет.
Решение заключается в использовании хука "pre_post_update" вместо "save_post".
http://wordpress.org/support/topic/save_post-not-working-getting-called#post-2335557

правка Вы пробовали добавить 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-запрос некорректен.
Надеюсь, одно из этих решений поможет исправить вашу проблему.

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

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

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

Прежде всего, я рекомендую настроить ваш сайт на 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 аргумента.

Со мной случилось то же самое. Оказалось, что у меня был установлен шаблон страницы (значение 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
.

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