Проверьте наличие обновления по сравнению с новой публикацией в действии сохранить публикацию


Возможно ли в действии save_post определить, создается ли новая запись или обновляется существующая запись?

Author: hereswhatidid, 2012-04-11

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();
}
 18
Author: Nicolai, 2019-03-20 17:54:51

Способ, которым я выполняю эту проверку (в рамках подключенной функции), заключается в сравнении даты публикации и даты изменения (в 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 секунду в любом случае, если во время создания сообщения пройдет секунда.

 12
Author: James Cushing, 2020-08-17 17:42:46

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

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');
 6
Author: hereswhatidid, 2012-04-17 21:50:50

Пример ответа на иалоцин с помощью пареметра "обновить":

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 );
 3
Author: Goran Jakovljevic, 2015-12-01 17:53:53

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

 1
Author: Darshan Thanki, 2012-08-06 12:08:44

Как намекнул Даршан Благодари (и Стивен Харрис более подробно), вы можете использовать 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 (чего обычно достаточно, по крайней мере, для того, что мы с ним делаем).

 1
Author: Qix - MONICA WAS MISTREATED, 2015-01-06 21:05:25

Я только что столкнулся с save_post о новых и обновлениях. После прочтения исходного кода, чтобы понять поток. Я обнаружил, что следующий метод может быть полезен. Так как об этом еще не упоминалось ранее. Посмотрите, пригодится ли это кому-нибудь. (Тест является основным 5.3.3)

Поток создания после создания примерно равен:

  1. После нажатия кнопки Добавить новое (Опубликовать)
  2. $post = get_default_post_to_edit($post_type, true); будет вызываться, где
  3. get_default_post_to_edit() получить аргумент $create_in_db =истина
  4. таким образом, немедленно вызывается wp_insert_post(), auto-draft создается сообщение, даже если оно не сохраняется, каждый раз при нажатии Add New создается auto-draft
  5. $обновление всегда верно для публикации. Поэтому, когда публикуете новый пост, это правда.

Сравнивая объект $_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
    }
}
 1
Author: simongcc, 2020-05-03 15:14:40

При срабатывании 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');

Однако это непроверено. =)

 0
Author: moraleida, 2012-04-12 04:27:21

Другой подход, который использует встроенную функцию и не требует добавления в базу данных, будет включать 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.
 0
Author: John112, 2014-12-12 03:00:17

Поскольку параметр $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);
 0
Author: wpclevel, 2020-09-09 20:26:12