Проверьте наличие обновления по сравнению с новой публикацией в действии сохранить публикацию
Возможно ли в действии save_post определить, создается ли новая запись или обновляется существующая запись?
10 answers
Начиная с версии WordPress 3.7. - IIRC - крючок save_post
- дополнительная информация о крючке и его использовании в Ссылка на код: save_post
и Кодекс: save_post
- имеет третий параметр $update
, который можно использовать для определения именно этого.
@param int $идентификатор записи Идентификатор должности.
@param WP_Post $разместить объект публикации.
@param bool $обновить Независимо от того, обновляется ли это существующее сообщение или нет.
Примечание:
$update
не всегда true
– вы можете увидеть и проверить это самостоятельно с помощью приведенного ниже кода. Однако он недостаточно хорошо документирован, возможно, далек от оптимального названия, и, следовательно, создает обманчивые ожидания. Приведенный ниже код можно использовать для некоторой отладки, поиграйте с тем, когда перехватывать выполнение кода, потому что в противном случае вы не увидите информацию/сообщения. Я думаю, что виновником обманчивого поведения является обработка исправлений и автоматическое сохранение, которые может быть отключен, но я не рекомендую его и не тестировал. Не уверен, что это гарантирует Билет на проезд, поэтому я его не открывал, если вы так думаете, пожалуйста, перейдите по ссылке и сделайте это самостоятельно. Кроме того, как указано в комментариях, если у вас есть конкретная проблема, задайте новый вопрос.
add_action( 'save_post', 'debug_save_post_update', 10, 3 );
function debug_save_post_update( $ID, $post, $update ) {
echo '<pre>';
print_r( $post ); echo '<br>';
echo '$update == ';
echo $update ? 'true' : 'false';
//conditions
if( ! $update && $post->post_status == "auto-draft" ) {
// applies to new post
echo ' && $post->post_status == "auto-draft"';
//die();
} else if ( ! $update ) {
// applies basically to the (auto saved) revision
//die();
} else {
// applies to updating a published post
// when there is a revision, which is normally the case,
// standard behavior of WordPress, then it is considered
// an update, which is where the confusion sets in
// there are other methods, like checking time or post status
// depending on your use case it might be more appropriate
// to use one of those alternatives
//die();
}
echo '</pre>';
//die();
}
Способ, которым я выполняю эту проверку (в рамках подключенной функции), заключается в сравнении даты публикации и даты изменения (в GMT для стандартизации)
function check_new_vs_update( $post_id ){
$myPost = get_post($post_id);
$post_created = new DateTime( $myPost->post_date_gmt );
$post_modified = new DateTime( $myPost->post_modified_gmt );
$diff = $created->diff( $modified );
$seconds_difference = ((($diff->y * 365.25 + $diff->m * 30 + $diff->d) * 24 + $diff->h) * 60 + $diff->i)*60 + $diff->s;
if( $seconds_difference <= 1 ){
// New post
}else{
// Updated post
}
}
add_action('save_post', 'check_new_vs_update' );
Это работает, потому что даже при создании к сообщению прикреплена "измененная" дата, которая в точности совпадает с датой "создания", но мы допускаем отклонение в 1 секунду в любом случае, если во время создания сообщения пройдет секунда.
В итоге я просто проверил наличие пользовательского значения перед его установкой. Таким образом, если это недавно созданная запись, пользовательское значение еще не существовало бы.
function attributes_save_postdata($post_id) {
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
if (!wp_verify_nonce($_POST['_attributes_noncename'], plugin_basename(__FILE__))) return;
if ('page' == $_POST['post_type']) {
if (!current_user_can('edit_page', $post_id)) return;
} else {
if (!current_user_can('edit_post', $post_id)) return;
}
$termid = get_post_meta($post_id, '_termid', true);
if ($termid != '') {
// it's a new record
$termid = 'update';
} else {
// it's an existing record
}
update_post_meta($post_id, '_termid', $termid);
}
add_action('save_post', 'attributes_save_postdata');
Пример ответа на иалоцин с помощью пареметра "обновить":
function save_func($ID, $post,$update) {
if($update == false) {
// do something if its first time publish
} else {
// Do something if its update
}
}
add_action( 'save_post', 'save_func', 10, 3 );
Вы можете использовать крючок действия pre_post_update для кода обновления и save_post для нового почтового кода. Это работает до того, как сообщение будет обновлено.
Как намекнул Даршан Благодари (и Стивен Харрис более подробно), вы можете использовать pre_post_update
в своих интересах.
global $___new_post;
$___new_post = true;
add_action(
'pre_post_update',
function() {
global $___new_post;
$___new_post = false;
},
0
);
function is_new_post() {
global $___new_post;
return $___new_post;
}
Причина, по которой я использовал глобальные значения, заключается в том, что function is_new_post() use ( &$new_post )
недопустимо в PHP (шокирует...), поэтому включение этой переменной в область действия функции не работает - следовательно, глобальная.
Обратите внимание, что это действительно может быть надежно использовано только в/после события save_post
(чего обычно достаточно, по крайней мере, для того, что мы с ним делаем).
Я только что столкнулся с save_post
о новых и обновлениях. После прочтения исходного кода, чтобы понять поток. Я обнаружил, что следующий метод может быть полезен. Так как об этом еще не упоминалось ранее. Посмотрите, пригодится ли это кому-нибудь. (Тест является основным 5.3.3)
Поток создания после создания примерно равен:
- После нажатия кнопки Добавить новое (Опубликовать)
- $post = get_default_post_to_edit($post_type, true); будет вызываться, где
- get_default_post_to_edit() получить аргумент $create_in_db =истина
- таким образом, немедленно вызывается wp_insert_post(),
auto-draft
создается сообщение, даже если оно не сохраняется, каждый раз при нажатииAdd New
создаетсяauto-draft
- $обновление всегда верно для публикации. Поэтому, когда публикуете новый пост, это правда.
Сравнивая объект $_POST для новой публикации и публикации обновления или повторной публикации, заметной разницей является значение _wp_http_referer
, новая запись /wp-admin/post-new.php
Предположение: предполагается, что должность опубликовано/добавлено из пользовательского интерфейса. Если это делается с помощью другого механизма, пользовательского кода, проверка необходима для настройки.
add_action( 'save_post', 'test_save_post_check', 0, 3 );
function test_save_post_check( $post_ID, $post, $update ) {
// other tests + this
// checking the 'post-new' position from the '_wp_http_referer'
if( strpos( wp_get_raw_referer(), 'post-new' ) > 0 ) {
// new
} else {
// update
}
}
При срабатывании save_post вся информация об этом сообщении уже доступна, поэтому теоретически вы могли бы использовать
function f4553265_check_post() {
if (!get_posts($post_id)) {
// if this is a new post get_posts($post_id) should return null
} else {
// $post_id already exists on the database
}
}
add_action('save_post','f4553265_check_post');
Однако это непроверено. =)
Другой подход, который использует встроенную функцию и не требует добавления в базу данных, будет включать get_post_status()
.
$post_status = get_post_status();
if ( $post_status != 'draft' ) {
//draft
} else {
//not a draft: can be published, pending, etc.
}
Однако обратите внимание, что это может быть неуместно, если вы планируете позже вернуть статус "черновик" – ваши инструкции будут повторены при следующем обновлении публикации.
В зависимости от контекста вы можете рассмотреть различные строки, которые могут быть возвращены get_post_status()
, чтобы построить более подходящий сценарий.
См. Кодекс для get_post_status() и Статус публикации
Возможные значения:
- "опубликовать" - опубликованный пост или страница
- "в ожидании" - сообщение ожидает рассмотрения
- "черновик" - должность в статусе черновика
- "автоматический черновик" - недавно созданная запись без содержимого
- "будущее" - пост, который будет опубликован в будущем
- "личный" - не виден пользователям, которые не вошли в систему
- "наследовать" - пересмотр. см. get_children.
- "мусор" - сообщение находится в мусорной корзине. добавлено в версии 2.9.
Поскольку параметр $update
бесполезен, это самый быстрый способ, который я тестировал:
function wpse48678_check_is_post_new($post_id, $post, $update)
{
if (false !== strpos($_POST['_wp_http_referer'], 'post-new.php')) {
return true; // Or do something else.
} else {
return false; // Or do something else.
}
}
add_action('save_post_{$post_type}', 'wpse48678_check_is_post_new', 10, 3);