web-dev-qa-db-ja.com

カスタム投稿タイプのカスタムフィールドを検証する方法

カスタムフィールドを持つカスタム投稿タイプを作成するプラグインを書きました。ユーザーが誤った情報を入力しないようにするには、データを検証する方法を教えてください。

Save_postフック関数がフィールド検証を処理すると想定しましたが、エラーをユーザーに表示する簡単な方法を見つけることはできません。

このための組み込みのワードプレス機能/機能はありますか?カスタムフィールド検証を実行するための一般的な手法は何ですか?

6
Force Flow

あなたは正しい方向に進んでいます。私はsave_postコールバックの中のフィールドをテストし、そして admin notices を使ってフィールドが検証に失敗したときにエラーを表示します。 WordPress自身が生成するエラーやメッセージと同じように、それらはページ上部のハイライトされたボックスに表示されます。

これは管理者通知を作成する簡単な例です。

function my_admin_notice()
{
    ?>

    <div class="updated">
       <p>Aenean eros ante, porta commodo lacinia.</p>
    </div>

    <?php
}
add_action( 'admin_notices', 'my_admin_notice' );

しかし、それはあまり実用的ではありません。このような状況では、メッセージを渡すことができる関数がほしいと思うだけです。何かのようなもの、

if( $pizza != 'warm' )
    $notices->enqueue( 'Pizza is not warm', 'error' );

そのため、enqueue()関数を(通知を印刷する関数と一緒に)自分で書くことも、 IDAdminNotices のようなライブラリを含めることもできます。

これは からの例です - 私が書いたプラグイン。これは、外部ライブラリを含めるのではなく、クラス自体に組み込まれているnoticeエンキュー/印刷関数を使用します。

public function saveCustomFields( $postID )
{
    // ...

    if( filter_var( $_POST[ self::PREFIX . 'zIndex'], FILTER_VALIDATE_INT ) === FALSE )
    {
        update_post_meta( $post->ID, self::PREFIX . 'zIndex', 0 );
        $this->enqueueMessage( 'The stacking order has to be an integer.', 'error' );
    }   
    else
        update_post_meta( $post->ID, self::PREFIX . 'zIndex', $_POST[ self::PREFIX . 'zIndex'] );

    // ...
}
add_action( 'save_post',    array( $this, 'saveCustomFields' );
6
Ian Dunn

カスタム投稿タイプの入力フィールドを検証するだけでなく、Javascriptを使用せずにデフォルトの管理者通知を削除する小さなプラグインを作成しました。

ここにいくつかのコードがあります

/検証フィルタ

$title = $album->post_title;
if ( ! $title ) {
    $errors['title'] = "The title is required";
}

// if we have errors lets setup some messages
if (! empty($errors)) {

    // we must remove this action or it will loop for ever
    remove_action('save_post', 'album_save_post');

    // save the errors as option
    update_option('album_errors', $errors);

    // Change post from published to draft
    $album->post_status = 'draft';

    // update the post
    wp_update_post( $album );

    // we must add back this action
    add_action('save_post', 'album_save_post');

    // admin_notice is create by a $_GET['message'] with a number that wordpress uses to
    // display the admin message so we will add a filter for replacing default admin message with a redirect
    add_filter( 'redirect_post_location', 'album_post_redirect_filter' );
}

完全なチュートリアルを見ることができます ここ

4
Kevin Phillips

save_postが実行されるとき、それはすでにデータベースに投稿を保存しています。

ACFを使用している場合は、組み込みの検証機能があります。

ただし、post_titleのようにACFの外部で検証する必要がある場合は、もう少し複雑になります。

WordPressのコアコード、特にwp-includes/post.phpupdate_post()関数に目を向けると、要求がデータベースに保存される前にそれを傍受するための組み込みの方法はありません。

ただし、投稿が保存されないようにするためにpre_post_updateをフックしてheader()get_post_edit_link()を使用することができます。

<?php

/**
*   Performs custom validation on custom post type "Site"
*/
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'] == 'site') {
        # In this example, we will deny post titles with less than 5 characters
        if (strlen($post_data['post_title'] < 5)) {
            # Add a notification
            update_option('my_notifications', json_encode(array('error', 'Post title can\'t be less than 5 characters.')));
            # And redirect
            header('Location: '.get_edit_post_link($post_id, 'redirect'));
            exit;
        }
    }
}
add_action( 'pre_post_update', 'custom_post_site_save', 10, 2);

/**
*   Shows custom notifications on wordpress admin panel
*/
function my_notification() {
    $notifications = get_option('my_notifications');

    if (!empty($notifications)) {
        $notifications = json_decode($notifications);
        #notifications[0] = (string) Type of notification: error, updated or update-nag
        #notifications[1] = (string) Message
        #notifications[2] = (boolean) is_dismissible?
        switch ($notifications[0]) {
            case 'error': # red
            case 'updated': # green
            case 'update-nag': # ?
                $class = $notifications[0];
                break;
            default:
                # Defaults to error just in case
                $class = 'error';
                break;
        }

        $is_dismissable = '';
        if (isset($notifications[2]) && $notifications[2] == true)
            $is_dismissable = 'is_dismissable';

        echo '<div class="'.$class.' notice '.$is_dismissable.'">';
           echo '<p>'.$notifications[1].'</p>';
        echo '</div>';

        # Let's reset the notification
        update_option('my_notifications', false);
    }
}
add_action( 'admin_notices', 'my_notification' );
0