Чи можна в рамках дії save_post визначити, чи створюється нова публікація, чи наявна публікація оновлюється?
Чи можна в рамках дії save_post визначити, чи створюється нова публікація, чи наявна публікація оновлюється?
Відповіді:
Оскільки WordPress версії 3.7. - IIRC - save_post
гачок - додаткова інформація про гачок та його використання у Code Reference:save_post
та Codex:save_post
- має третій параметр, $update
який можна використовувати для визначення саме цього.
@param int $ post_ID Ідентифікатор допису.
@param WP_Post $ post Об’єкт повідомлення.
@param bool $ update Невже це наявна публікація, що оновлюється чи ні.
Примітка:
$update
не завжди true
- ви можете побачити і протестувати його самостійно за допомогою наведеного нижче коду. Це не добре зафіксовано, хоча, можливо, далеко не оптимально названо, а отже, створює оманливі очікування. Нижче код можна використовувати для налагодження, пограйте з тим, коли потрібно перехопити виконання коду, оскільки в іншому випадку ви не побачите інформацію / повідомлення. Я думаю, що винуватцем оманливої поведінки є поправка з ревізіями та автоматичними збереженнями - які можуть бути відключені, але я не рекомендую цього і не перевіряв. Не впевнений, чи це вимагає квитка на Trac , тому я не відкрив його, якщо ви так вважаєте, перейдіть за посиланням і зробіть це самостійно. Крім цього, як зазначено в коментарях, якщо у вас є конкретні проблеми, поставте нове запитання.
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();
}
$update
Параметр завжди вірно , навіть якщо це новий пост. Тож цей параметр марний. Не впевнений, чи взагалі колись це працювало, але впевнений, що пекло не працює так, як це зафіксовано в останній версії wordpress 4.8.
wp_publish_post
, то так. Але це не вірно для його використання в wp_insert_post
. Я написав функцію налагодження, додаю її у відповідь.
save_post
гака є 3-й параметр, який завжди встановлено на TRUE, тому не впевнений, що це стосується інших гачків, не кажучи про інші гачки. Я кажу про гачок у вашій відповіді. Це неправильно.
wp_insert_post()
, wp_publish_post()
. Останнє - це лише майбутні посади, $update
налаштоване завжди true
. Інакше, що стосується wp_insert_post()
, $update
це не завжди true
.
Те, як я виконую цю перевірку (в межах підключеної функції), полягає в порівнянні дати публікації та модифікованої дати (в 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 );
if( abs( $post_created->diff( $post_modified )->s ) <= 1 ){
// New post
}else{
// Updated post
}
}
add_action('save_post', 'check_new_vs_update' );
Це працює, тому що навіть під час створення публікації додається "модифікована" дата, яка точно така ж, як і "створена" дата, але ми допускаємо відхилення в 1 секунду в будь-якому випадку, у випадку, якщо другий відмічається під час створення пошта.
post_date_gmt
є 2019-03-12 01:31:30
і post_modified_gmt
є 2019-03-12 01:31:31
. :(
Я закінчив лише перевірити наявність спеціального значення перед його встановленням. Таким чином, якщо це новостворена публікація, власні значення ще не існували б.
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 );
if($update)
або зберігати новий блок спочатку, але використовувати if( ! $update )
. Останній отримає ОП в кращій практиці, і він надає перевагу над вашим методом стандартами кодування WordPress у таких випадках, як термінальний оператор
Ви можете використовувати гачок дій pre_post_update для оновлення коду та save_post для нового поштового коду. Він працює до оновлення публікації.
save_post
гак знімається як під час створення публікації, так і оновлення (після того, як WordPress збереже її до бази даних). pre_post_update
знімається, коли повідомлення оновлюється, але перед оновленням повідомлення - це може бути важливо.
Як натякнув Даршан Тонкі (і Стівен Гарріс далі докладно), ви можете скористатися 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, вся інформація про цю публікацію вже доступна, тому теоретично ви могли б використовувати
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');
це, проте, не перевірено. =)
save_post
самої публікації, вона вже була б збережена в базі даних - так get_posts
би поверталася поточна публікація.
Інший підхід, який використовує вбудовану функцію і не має доповнення до бази даних 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()
щоб створити більш відповідний сценарій.
Дивіться Codex для get_post_status () та стану публікації
Можливі значення:
- 'опублікувати' - опублікована публікація або сторінка
- "очікує на розгляд" - публікація очікує на розгляд
- 'чернетка' - посада в статусі чернетки
- "авто-чернетка" - щойно створена публікація без вмісту
- 'майбутнє' - публікація, яку слід опублікувати в майбутньому
- 'приватний' - не видно користувачам, які не ввійшли в систему
- ‘успадковувати’ - перегляд. дивіться get_children.
- 'сміття' - повідомлення знаходиться в кошику. додано до версії 2.9.
save_post()
виконується вперше, але під час цього виконання get_post_status()
вже повертає "опублікувати", а не "чернетку", навіть якщо вона опублікована лише в процесі.