Özel alanlar kaydedilirken doğrulama ve hata işleme eklenir mi?


27

Bir yazı tipinde özel bir alanı tanımlayan bir işleve sahibim. Alanın "alt başlık" olduğunu söyleyin.

Gönderi kaydedildiğinde, girdi üzerinde bir miktar doğrulama yapmak ve gerekirse yazı düzenleme ekranında bir hata mesajı görüntülemek istiyorum. Gibi bir şey:

// Handle post updating
function wpse_update_post_custom_values($post_id, $post) {

    // Do some checking...
    if($_POST['subhead'] != 'value i expect') {

        // Add an error here
        $errors->add('oops', 'There was an error.');

    }

    return $errors;

} 
add_action('save_post','wpse_update_post_custom_values',1,2);

Bunu save_post eylemine bağlamaya çalışıyorum, ancak hataları nasıl ele alacağımı bulamıyorum. İşleve iletilen bir hata nesnesi görünmüyor ve kendi WP_Error objemi oluşturup geri döndürürsem, düzenleme sonrası sayfada hataları yayan herhangi bir mekanizmaya saygı duymuyor.

Şu anda özel meta kutumun içinde sayfa içi bir hata mesajı var, ancak bu idealden daha az. WP normalde gösterdiği gibi büyük, kırmızı, en üstte bir hatam olmasını tercih ederim.

Herhangi bir fikir?

GÜNCELLEŞTİRME:

@Denis'in cevabına dayanarak birkaç farklı şey denedim. Hataları bir genel olarak saklamak işe yaramadı çünkü Wordpress, onu görmeden önce genelini öldüren save_post işlemi sırasında bir yönlendirme yapıyor.

Onları meta bir alanda sakladım. Bununla ilgili sorun, onları temizlemeniz gerekmesi veya başka bir sayfaya gittiğinizde kaybolmamalarıdır, bu yüzden sadece hataları gideren admin_footer'a bağlı başka bir işlev eklemek zorunda kaldım.

Bu kadar yaygın olan bir şey için hata işlemenin (gönderilerin güncellenmesi) bu kadar zor olacağını ummazdım. Açıkça net bir şey mi eksik yoksa bu en iyi yaklaşım mı?

// Handle post updating
function wpse_5102_update_post_custom_values($post_id, $post) {

    // To keep the errors in
    $errors = false;

    // Do some validation...
    if($_POST['subhead'] != 'value i expect') {

        // Add an error here
        $errors .= 'whoops...there was an error.';

    }

    update_option('my_admin_errors', $errors);

    return;

} 
add_action('save_post','wpse_5102_update_post_custom_values',1,2);


// Display any errors
function wpse_5102_admin_notice_handler() {

    $errors = get_option('my_admin_errors');

    if($errors) {

        echo '<div class="error"><p>' . $errors . '</p></div>';

    }   

}
add_action( 'admin_notices', 'wpse_5102_admin_notice_handler' );


// Clear any errors
function wpse_5102__clear_errors() {

    update_option('my_admin_errors', false);

}
add_action( 'admin_footer', 'wpse_5102_clear_errors' );

İyi soru. admin_footerDikkat işleyicisi işlevinin sonundaki hataları giderirseniz , kancadan kurtulabileceğinizi düşünüyorum . İşleri bir parça basitleştirir.
Geert

Form alanlarını yeniden doldurmayla nasıl başa çıkıyorsunuz (olası geçersiz verilerle)?
Geert

Temel bir sorum var. Hangi Wordpress php dosyası içinde bu?

@Karen Bu, özel bir eklenti dosyasında veya functions.php dosyasında olacaktır.
MathSmath

Açıkça belli bir şeyi kaçırmış olabilirim, ancak update_option('my_admin_errors', false);sonunda if ifadesinden hemen sonra çalıştırmak biraz daha etkili olur wpse_5102_admin_notice_handler()mu?
Andrew Odri

Yanıtlar:


6

Hataları sınıfınızda veya global olarak, muhtemelen geçici veya metada saklayın ve POST isteklerinde yönetici bildirimlerinde görüntüleyin. WP herhangi bir flash mesaj işleyicisi içermez.


Beni bu yöne yönlendirdiğiniz için teşekkürler! Hataları saklamak için bir meta kullandım, çünkü bunu global ya da mülk olarak yapmaya çalışırken sorun yaşadım. Şu anda nasıl yaptığımı açıklamak için şu anda cevabımı güncelliyorum ... lütfen bunu önerdiğin türden biriyse, ya da alamadığım daha iyi bir yol varsa bana bildirin.
MathSmath

Bu tür bir şey, evet. Belki de, ikinci düşüncelere rağmen, bir oturum değişkeninde saklayın. Bu, birden fazla yazarın aynı anda yayınları düzenlemesini sağlamak için. :-) Ayrıca, bir seçenekte yanlış saklamanın mümkün olmadığına inanıyorum. Bunun yerine boş bir dize saklayın.
Denis de Bernardy

6

İki kullanıcı aynı anda düzenleme yaparken garip efektler oluşturmayacağından oturumları kullanmanızı öneririm. Demek istediğim bu:

Oturumlar wordpress ile başlatılmaz. Bu yüzden eklentinizdeki bir oturumu başlatmanız gerekiyor , Fonksiyonlar.

if (!session_id())
  session_start();

Gönderiyi kaydederken, oturuma hatalar ve bildirimler ekleyin:

function my_save_post($post_id, $post) {
   if($something_went_wrong) {
     //Append error notice if something went wrong
     $_SESSION['my_admin_notices'] .= '<div class="error"><p>This or that went wrong</p></div>';
     return false; //might stop processing here
   }
   if($somthing_to_notice) {  //i.e. successful saving
     //Append notice if something went wrong
     $_SESSION['my_admin_notices'] .= '<div class="updated"><p>Post updated</p></div>';
   }

   return true;
} 
add_action('save_post','my_save_post');

Bildirimleri ve hataları yazdırın ve ardından oturumdaki mesajları temizleyin:

function my_admin_notices(){
  if(!empty($_SESSION['my_admin_notices'])) print  $_SESSION['my_admin_notices'];
  unset ($_SESSION['my_admin_notices']);
}
add_action( 'admin_notices', 'my_admin_notices' );

oturum sürümü için düzeltme: oturum değişkeni kullanıldığında ilk kullanımda kullanılmaz. = only = hata ayıklamayı açarsanız nedenini kontrol edebilirsiniz ...

3
Bunu ben de yapıyorum, ancak böyle bir kitleye bir eklenti yayınlarsanız, insanlar sizden nefret eder. Wordpress oturumları başlatmaz çünkü vatansız olacak ve onlara ihtiyaç duymayacak şekilde tasarlanmıştır ve bazı garip sunucu kurulumları onu kıracaktır. Geçici API'yi kullanın - oturumlar yerine codex.wordpress.org/Transients_API . Sadece bunu burada yapmamak için bir neden işaretlemeye değdiğini düşündüm.
pospi

@pospi bu, get_option ve update_option işlevlerinin orijinal kullanımıyla benzer sorunlara sahip görünüyor. Yani çözüm mevcut kullanıcının kimliğini anahtara eklemek olur mu?
Gazillion

Evet bu kesinlikle işe yarar! Madem benzersiz olarak mesajlar (kullanıcılar giriş arasına karışmış kapatılmasını önler kullanıcıyı tanımlamak için bir şey eklemek gibidir:
pospi

5

Posi 'nin geçici kullanım önerisine dayanarak aşağıdakileri gündeme getirdim. Tek sorun, mesajı diğer mesajların gittiği yerin altına koymak için bir kanca olmadığı için, oraya ulaşmak için bir jQuery kesmek zorunda kaldım.h2

İlk önce, save_post(veya benzeri) işleyicinizi duyan hata mesajını kaydedin . 60 saniyelik kısa bir ömür veririm, bu yüzden yönlendirmenin gerçekleşmesi için yeterince uzun bir süre var.

if($has_error)
{
  set_transient( "acme_plugin_error_msg_$post_id", $error_msg, 60 );
}

Ardından, bir sonraki sayfadaki bu hata iletisini alın ve görüntüleyin. Ayrıca iki kez görüntülenmeyecek şekilde silerim.

add_action('admin_notices', 'acme_plugin_show_messages');

function acme_plugin_show_messages()
{
  global $post;
  if ( false !== ( $msg = get_transient( "acme_plugin_error_msg_{$post->ID}" ) ) && $msg) {
    delete_transient( "acme_plugin_error_msg_{$post->ID}" );
    echo "<div id=\"acme-plugin-message\" class=\"error below-h2\"><p>$msg</p></div>";
  }
}

Yana admin_noticesbirincil sayfa içeriğinden önce yangınları oluşturulan diğer sonrası düzenleme mesajları nereye, ihbar onu orada taşımak için bu jQuery kullanmak zorunda, değil:

jQuery('h2').after(jQuery('#acme-plugin-message'));

Posta kimliği geçici adın bir parçası olduğundan, bu, birden fazla kullanıcının aynı anda aynı yayını düzenlemesi dışında çoğu çok kullanıcılı ortamlarda çalışmalıdır.


"Posta kimliği geçici adın bir parçası olduğu için" konusunu ayrıntılı olarak açıklayabilir misiniz? Bu tekniği kullanarak hata mesajlarını işlemek için bir sınıf oluşturdum, ancak kurucumun bir user_ID'yi geçmesini istiyorum. Geçici API, anahtarı birleştirirken user_id kullanıyor mu? (Soruyorum, çünkü kodeks bundan bahsediyor gibi görünmüyor)
Gazillion

Hayır, ancak elle ekleyebilirsiniz. Ben yukarıda yayınlanan kodda, geçici adıdır acme_plugin_error_msg_POSTID. Sadece buna benzer bir kullanıcı kimliği ekleyebilirsiniz acme_plugin_error_msg_POSTID_USERID.
Joshua Coady

2

Çalıştığında save_post, yayını zaten veritabanına kaydetti.

Daha spesifik olarak, WordPress çekirdek koduna bakıldığında wp-includes/post.phpbireyin update_post()fonksiyonu, hiçbir orada yerleşik şekline istihbarat bilgisine bir istek bu veritabanına kaydedilir önce.

Ancak, kanca pre_post_updateve kullanım header()ve get_post_edit_link()kaydedilmesini yazı önlemek için.

<?php

/**
*   Performs validation before saving/inserting custom post type
*/
function custom_post_site_save($post_id, $post_data) {
    // If this is just a revision, don't do anything.
    if (wp_is_post_revision($post_id))
        return;

    if ($post_data['post_type'] == 'my_custom_post_type') {
        // Deny post titles with less than 5 characters
        if (strlen($post_data['post_title'] < 5)) {
            header('Location: '.get_edit_post_link($post_id, 'redirect'));
            exit;
        }
    }
}
add_action( 'pre_post_update', 'custom_post_site_save', 10, 2);

Kullanıcıya neyin yanlış gittiğini bildirirseniz, bu özü işaretleyin: https://gist.github.com/Luc45/09f2f9d0c0e574c0285051b288a0f935


Bunun için teşekkür ederiz, ister ilk kez yayınlar, ister gönderiyi güncelleyerek, doğrulamayı mükemmel şekilde yerine getirir. Az önce bana çok zaman ve emek kazandırdı.
Zade

1

Neden alanınızı biraz Javascript yardımı ile doğrulamıyorsunuz? Bunun için en iyi yaklaşım olacağını düşünüyorum.


Önerin için teşekkürler! Soru dışında bıraktığım şey (basitlik uğruna), dosya yükleme hatalarını ele almaya çalışıyorum, bu yüzden sunucu tarafında olması gerekiyor. Öneriniz için teşekkürler!
MathSmath

javascript doğrulama bazı saldırılardan korunmaz, sunucu tarafında doğrulama tek güvenlidir. Ayrıca, wordpress kullanıcı verilerini doğrulamak için bazı iyi araçlar sunar. Ancak veriyi sunucuya göndermeden önce sadece bazı değerleri kontrol ederseniz haklısınız, düşük sunucuda biraz zaman
kazanabilirsiniz

1

Yukarıdaki betiği kullanmaya çalışırken, garip bir sorunla karşılaştım. Güncelleme sonrası, düzenleme ekranında iki mesaj gösterilir. Biri, önceki kaydetmeden gelen içeriğin durumunu ve bir diğeri mevcut olanı gösteriyor. Örneğin, gönderiyi düzgün bir şekilde kaydedersem ve sonra bir hata yaparsam, ilk önce "hata" ve ikincisi "tamam" dır - bunlar aynı anda üretilse de. Eğer betiği değiştirip sadece bir mesaj eklersem (örneğin "hata"), "error" ile bir güncelleme başlat ve ardından "ok" olan "error" mesajı kalmaya devam ediyor (ikinci kez gösteriliyor). Ondan kurtulmak için bir kez daha "Tamam" ile kurtarmalıyım. Neyin yanlış olduğunu gerçekten bilmiyorum, üç farklı yerel sunucuda test ettim ve her birinde aynı sorun var.


Basitleştirici hakkında biraz daha testler yaptım, yukarıda bahsettiğim komut dosyasının ikinci sürümü ve "hata" mesajı gerçekten oturum dizisine eklenmişse düzenleme ekranında göründüğü görülüyor. Hiçbir mesaj yoksa (her şey yolunda) ve önceki mesaj yanlıştıysa, ekranda belirir. Tuhaf olan, tasarruf sırasında üretilir (önbelleğe alınmamış) - Hata mesajı gövdesinde date () kullanarak kontrol ettim. Şimdi tamamen kafam karıştı.
jlub

Tamam, başka birinin kafasından saç çıkarması durumunda, Wordpress revizyon sisteminin sorun olduğu ortaya çıktı (muhtemelen bir tür böcek?). Onu devre dışı bıraktım ve şimdi her şey yolunda.

0

Sonradan düzenleme ekranları için hızlı bir hata işleme ekleyen ve gerekli alanlar doldurulana kadar yayınların yayınlanmasını önleyen bir eklenti yazdım:

https://github.com/interconnectit/required-fields

Herhangi bir gönderi alanını zorunlu hale getirmenize olanak tanır, ancak özelleştirilebilir bir hata mesajı ve doğrulama işlevi ile gerekli olan herhangi bir özel alanı oluşturmak için sağladığı API'yi kullanabilirsiniz. Alanın boş olup olmadığını kontrol etmek için varsayılan ayardır.


Karşılaştığınız takdirde github ile ilgili herhangi bir sorun eklemek için tereddüt etmeyin. Kullanabileceğiniz bazı adiditional filtreler olduğu için API'yi biraz daha iyi belgelendirmem gerekiyor.
sanchothefat
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.