Save_post eyleminde güncelleme ile yeni gönderi kontrolü yap


21

Save_post eylemi içinde yeni bir yayın mı oluşturulduğunu ya da mevcut bir yayını mı güncellediğini belirlemek mümkün mü?


Bunun mümkün olduğunu sanmıyorum. Yorumumu aşağıya bakın @ moraleida's answer. Yeni bir gönderi olup olmadığını neden bilmek zorundasınız? Etrafta bir çalışma veya alternatif bir yaklaşım olabilir.
Stephen Harris

Yanıtlar:


16

WordPress sürüm 3.7'den beri. - IIRC - save_postkanca - kanca ve Kod Referansındasave_post kullanımı hakkında daha fazla bilgi : ve Kodeksi:save_post - $updateSadece bunu belirlemek için kullanılabilecek üçüncü bir parametreye sahiptir.

@ param int $ post_ID Gönderi Kimliği.
@param WP_Post $ post Nesne yaz.
@param bool $ update Bunun mevcut bir gönderi olup olmadığı güncellenmektedir.


Not:

$updateher zaman değildir true- aşağıdaki kodla kendiniz görebilir ve test edebilirsiniz. Yine de, muhtemelen en iyi şekilde adlandırılmış olmaktan uzak bir şekilde belgelenmiştir ve bu nedenle yanıltıcı beklentiler yaratır. Bazı kod hata ayıklama işlemleri için aşağıdaki kod kullanılabilir, kod çalıştırma işlemine ne zaman müdahale edeceğinizi bilemezsiniz, çünkü aksi halde bilgi / mesajları görmezsiniz. Bence aldatıcı davranışlardaki suçlu revizyonların ve otomatik tasarrufların ele alınmasıdır - ki bunlar devre dışı bırakılabilir, ancak bunu önermiyorum ve test etmedim. Bu bir Trac Ticket'i garanti ettiğinden emin değilim , bu yüzden bir tane açmadım , eğer düşünüyorsanız, lütfen bağlantıyı takip edin ve kendiniz yapın. Bunun dışında, yorumlarda belirtildiği gibi, belirli bir sorununuz varsa, yeni bir soru gönderin.

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();
}

3
$updateYeni bir mesaj olduğunda bile değer mutlaka doğrudur. Yani bu parametre işe yaramaz. Hiç işe yarayıp yaramadığından emin değil, ama cehennemin, Wordpress 4.8'in en son sürümünde belgelendiği şekilde çalışmadığından emin.
Solomon Closson,

@SolomonClosson Bir bakarsanız wp_publish_post, o zaman evet. Ancak bu kullanım için doğru değil wp_insert_post. Bir hata ayıklama işlevi yazdım, cevaba ekliyorum.
Nicolai

@SolomonClosson Eğer gerçek bir somut sorununuz varsa, lütfen yeni bir soru sorun. Hata ayıklama işlevinin revizyonlarına bir açıklama yapın.
Nicolai,

save_postKanca hep böyle değildi emin bu değil diğer kanca hakkında konuşan diğer kancalarla ne ilgisi var, TRUE olarak ayarlanmıştır 3. bir parametresi vardır. Cevabınızdaki kancadan bahsediyorum. Bu yanlış.
Solomon Closson

@SolomonClosson olarak ben kanca iki kez gerçekleşiyor söyledi: wp_insert_post(), wp_publish_post(). İkincisi sadece gelecekteki mesajlar, $updateher zaman olduğu gibi ayarlanmıştır true. Aksi takdirde, söz konusu olduğunda wp_insert_post(), $updateher zaman değildir true.
Nicolai

11

Bu kontrolü yapmamın yolu (çengelli bir fonksiyon içinde), kayıt tarihini ve değiştirilmiş tarihi (standartlaştırma için GMT'de) karşılaştırmaktır.

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' );

Bu işe yaramaktadır, çünkü yaratılışta bile gönderinin kendisine eklenmiş bir 'değiştirilmiş' tarihi vardır, bu da 'oluşturulmuş' tarihle tamamen aynıdır, ancak oluşturma sırasında bir saniye geçmesi durumunda her iki şekilde de 1 saniyelik bir varyansa izin veriyoruz posta.


1
Bazen post_date_gmtise 2019-03-12 01:31:30ve post_modified_gmtolduğu 2019-03-12 01:31:31. :(
He Yifei,

1
@HeYifei iyi bir nokta, eğer işlem verilen bir saniyenin sonunda başlarsa, bu olabilirdi. Cevabımı güncelledim, teşekkürler
James Cushing

Çocuklar, sadece bir bilgi. Kanca, bir gönderiyi geri yükleme ve silme işlemine başlar.
melvin

6

Ayarlamadan önce sadece özel bir değerin varlığını kontrol ettim. Bu şekilde, yeni oluşturulmuş bir gönderiyse, özel değer henüz mevcut olmazdı.

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');

Bunun çalışması için, önce add_post_meta kullanarak özel alan oluşturmalısınız?
MF1

Kodeks uyarınca: [update_post_meta], add_post_meta () işlevi yerine kullanılabilir. codex.wordpress.org/Function_Reference/update_post_meta
21'de

Gönderiler kod kancası bir eklenti etkinleştirme ile etkinleştirilmeden önce yaratılmışsa, bu başarısız olabilir. Daha eski yayınlar meta kümesine sahip değildir, bu nedenle onlar için ilk güncelleme yeni olarak kabul edilir.
Vasu Chawla

4

"Update" paremeter ile ialocin cevabı örneği:

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 );

2
Bunu yapılandırmanın daha iyi bir yolu ya güncelleme bloğunu önce koymak, hem if($update)de yeni bloğu ilk önce yapmak, ancak kullanmaktan korumaktır if( ! $update ). Sonuncusu OP'yi daha iyi bir şekilde uygulayacaktır ve üçlü operatör
James Cushing

1

Güncelleme kodu için pre_post_update eylem kancasını ve yeni posta kodu için save_post komutunu kullanabilirsiniz. Bir gönderi güncellenmeden önce çalışır.


4
save_postKanca ateşlendiğinde hem bir post oluşturulan ve (WordPress veritabanına kaydedilir sonra) güncellendiğinde. pre_post_updateBir gönderi güncellendiğinde kovulur, ancak gönderi güncellenmeden önce bu önemli olabilir.
Stephen Harris

1

Darshan Thanki'nin belirttiği gibi (ve Stephen Harris daha ayrıntılı olarak hazırlandı) pre_post_update kendi avantajınıza .

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;
}

Global kullanmamın sebebi function is_new_post() use ( &$new_post ) PHP'de (şok edici ...) geçerli olmamasıdır, bu yüzden bu değişkeni fonksiyon kapsamına sokmak işe yaramaz - bu nedenle geneldir.

Bunun, save_postetkinliğin içinde / sonrasında yalnızca güvenilir bir şekilde kullanılabileceğini unutmayın (en azından bununla yaptığımız şey için genellikle yeterlidir).


0

Save_post tetiklendiğinde, bu gönderi hakkındaki tüm bilgiler zaten kullanılabilir durumdadır, bu nedenle teoride kullanabilirsiniz.

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');

Bu olsa da denenmemiş. =)


3
Gönderiye ulaştığınız zaman save_postzaten veritabanına kaydedilmiş olacaktı - get_postsgeçerli yazıyı döndürecekti.
Stephen Harris

Doğru, sadece Kodeks'te kontrol ettim. Yardımların için teşekkürler.
moraleida

0

Yerleşik bir işlev kullanan ve veritabanına hiçbir ekleme yapılmayan bir başka yaklaşım söz konusudur get_post_status().

$post_status = get_post_status();
if ( $post_status != 'draft' ) {
    //draft
} else { 
    //not a draft: can be published, pending, etc. 
}

Bununla birlikte, durumu daha sonra tekrar "taslak" olarak ayarlamayı planlıyorsanız, bunun uygun olmayabileceğini unutmayın; bir sonraki sefer güncelleme işleminde talimatlarınız tekrarlanacaktır. Bağlama bağlı olarak, tarafından döndürülebilen çeşitli dizeleri dikkate almak isteyebilirsiniz.get_post_status() daha uygun bir senaryo oluşturmak .

Get_post_status () ve Mesaj Durumu için Kodeksi'ne bakın.

Olası değerler:

  • 'yayınla' - Yayınlanmış bir yayın veya sayfa
  • 'beklemede' - yayın incelenmeyi bekliyor
  • 'taslak' - taslak statüsünde bir gönderi
  • 'otomatik taslak' - içeriği olmayan yeni oluşturulmuş bir yayın
  • 'gelecek' - gelecekte yayınlanacak bir gönderi
  • 'private' - giriş yapmamış kullanıcılar tarafından görülemez
  • 'miras' - bir revizyon. bkz. get_children.
  • 'çöp' - posta çöp kutusunda. 2.9 sürümüyle eklendi.

Bunun isteneni yaptığını sanmıyorum. Yeni bir gönderi oluşturup daha sonra 'Yayınla' ya save_post()basarsam, ilk kez yürütülür, ancak bu yürütme sırasında get_post_status()zaten yalnızca yayınlanma sürecinde olmasına rağmen 'taslak' değil 'taslak' döndürür.
cgogolin
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.