Czy w ramach akcji save_post można ustalić, czy jest to nowy post, czy istniejący wpis jest aktualizowany?
Czy w ramach akcji save_post można ustalić, czy jest to nowy post, czy istniejący wpis jest aktualizowany?
Odpowiedzi:
Od wersji WordPress 3.7. - IIRC - save_post
hook - więcej informacji na temat hooka i jego wykorzystania w Code Reference:save_post
i Codex:save_post
- ma trzeci parametr, $update
którego można użyć do określenia właśnie tego.
@param int $ post_ID Identyfikator postu.
@param WP_Post $ post Obiekt obiektu.
@param bool $ update Czy jest to istniejący wpis jest aktualizowany, czy nie.
Uwaga:
$update
nie zawsze true
- możesz to zobaczyć i przetestować samodzielnie za pomocą poniższego kodu. Nie jest to jednak dobrze udokumentowane, być może dalekie od optymalnej nazwy, a zatem stwarza mylące oczekiwania. Poniższy kod może być użyty do debugowania, pobaw się, kiedy przechwycić wykonanie kodu, ponieważ w przeciwnym razie nie zobaczysz informacji / komunikatów. Myślę, że winowajcą jest zachowanie poprawek i automatycznych zapisów - które można wyłączyć, ale nie polecam go i nie przetestowałem. Nie jestem pewien, czy to uzasadnia bilet Trac , więc nie otworzyłem go, jeśli tak uważasz, skorzystaj z linku i zrób to sam. Oprócz tego, jak stwierdzono w komentarzach, jeśli masz konkretny problem, opublikuj nowe pytanie.
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
parametr jest ZAWSZE prawdziwy, nawet jeśli jest to nowy post. Ten parametr jest więc bezużyteczny. Nie jestem pewien, czy kiedykolwiek w ogóle działało, ale na pewno nie działa tak, jak zostało to udokumentowane w najnowszej wersji wordpress 4.8.
wp_publish_post
, to tak. Ale to nie dotyczy jego użycia w wp_insert_post
. Napisałem funkcję debugowania, dodaję ją do odpowiedzi.
save_post
Hak ma 3rd parametr, który jest zawsze ustawiony na true, więc nie wiem, co to ma wspólnego z innymi haki, nie mówiąc o innych haków. Mówię o haczyku w twojej odpowiedzi. To jest niepoprawne.
wp_insert_post()
, wp_publish_post()
. Ten ostatni to tylko przyszłe posty, $update
zawsze będzie true
. W przeciwnym razie, w odniesieniu do wp_insert_post()
, $update
nie zawsze tak jest true
.
Sposób, w jaki przeprowadzam to sprawdzenie (w ramach funkcji przechwyconej) polega na porównaniu daty publikacji i daty modyfikacji (w GMT w celu standaryzacji)
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' );
Działa to, ponieważ nawet podczas tworzenia postu jest do niego dołączona data „zmodyfikowana”, która jest dokładnie taka sama jak data „utworzona”, ale dopuszczamy odchylenie 1 sekundy w obu kierunkach, w przypadku gdy sekunda tyka podczas tworzenia Poczta.
post_date_gmt
jest 2019-03-12 01:31:30
i post_modified_gmt
jest 2019-03-12 01:31:31
. :(
Skończyło się na sprawdzeniu istnienia niestandardowej wartości przed jej ustawieniem. W ten sposób, jeśli jest to nowo utworzony post, wartość niestandardowa jeszcze nie istniałaby.
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');
Przykład odpowiedzi na ialocin za pomocą paremetera „update”:
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)
lub utrzymanie nowego bloku na pierwszym miejscu, ale użycie if( ! $update )
. Ta ostatnia wprowadzi OP do lepszej praktyki i jest preferowana w stosunku do twojej metody przez standardy kodowania WordPress w przypadkach takich jak operator trójskładnikowy
Możesz użyć haka akcji pre_post_update dla kodu aktualizacji i save_post dla nowego kodu pocztowego. Działa przed aktualizacją posta.
save_post
hook jest uruchamiany zarówno po utworzeniu, jak i aktualizacji posta (po zapisaniu go przez WordPress w bazie danych). pre_post_update
jest uruchamiany, gdy post jest aktualizowany, ale przed aktualizacją postu - może to być ważne.
Jak podpowiedział Darshan Thanki (a Stephen Harris dalej rozwijał), możesz skorzystać pre_post_update
na swoją korzyść.
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;
}
Powodem, dla którego użyłem globałów jest to, że function is_new_post() use ( &$new_post )
nie jest poprawne w PHP (szokujące ...), więc wciągnięcie tej zmiennej do zakresu funkcji nie działa - stąd globalne.
Zauważ, że tak naprawdę można to niezawodnie wykorzystać tylko w / po save_post
zdarzeniu (co zwykle jest wystarczające, przynajmniej do tego, co robimy).
Po uruchomieniu save_post wszystkie informacje o tym poście są już dostępne, więc teoretycznie możesz ich użyć
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');
jest to jednak niesprawdzone. =)
save_post
samego posta, byłby on już zapisany w bazie danych - get_posts
zwróci więc bieżący post.
Inne podejście, które wykorzystuje wbudowaną funkcję i nie wymaga dodawania do bazy danych get_post_status()
.
$post_status = get_post_status();
if ( $post_status != 'draft' ) {
//draft
} else {
//not a draft: can be published, pending, etc.
}
Pamiętaj jednak, że może nie być właściwe, jeśli planujesz później przywrócić status „szkic” - instrukcje zostaną powtórzone przy następnej aktualizacji posta. W zależności od kontekstu warto rozważyć różne ciągi znaków, które mogą zostać zwrócone, get_post_status()
aby zbudować bardziej odpowiedni scenariusz.
Zobacz Codex dla get_post_status () i Statusu Postu
Możliwe wartości to:
- „opublikuj” - opublikowany post lub strona
- „w toku” - wpis oczekuje na sprawdzenie
- „projekt” - post w stanie roboczym
- „auto-draft” - nowo utworzony post, bez zawartości
- „przyszłość” - post do opublikowania w przyszłości
- „prywatny” - niewidoczny dla użytkowników, którzy nie są zalogowani
- „dziedziczenie” - wersja. patrz get_children.
- „kosz” - post znajduje się w koszu. dodano w wersji 2.9.
save_post()
jest wykonywany po raz pierwszy, ale podczas tego wykonania jest get_post_status()
już zwracany komunikat „publikuj”, a nie „wersja robocza”, nawet jeśli jest on dopiero publikowany.