web-dev-qa-db-ja.com

公開前に同じ投稿スラッグが使用されていないかどうかを確認するにはどうすればよいですか。

インディーロックアジェンダのために、イベント投稿を作成しました。 JavaScriptの助けを借りて、投稿を公開または更新するときにカスタムフィールドの値(バンド、場所、選択ボックスで選択された日付情報)が投稿のタイトルとしてコピーされます。タイトルが変わるたびにスラッグを更新するカスタム関数もあります。 。問題:他のユーザーがまったく同じカスタムフィールド値を選択して新しい投稿を作成すると、まったく同じスラッグを持つ他の投稿が作成されます。そして、同じスラッグを持つ2つの投稿が作成された場合、どちらか一方が手動で削除されるまで、両方とも404エラーページが表示されます。私の質問:投稿スラッグをデータベース内の古い投稿と比較して「検証」する方法はありますか。ご協力いただきありがとうございます !

3
Pierre

Ajaxの方法(少し汚れていますが、簡単に拡張できます)

Functions.php(またはプラグイン、あるいは他の場所へ):

function my_ajax_update(){
    if (isset($_POST['title'])){
        global $wpdb;
        $title = esc_sql($_POST['title']);
        if(!$title) return;
        $page = $wpdb->get_results("
            SELECT *
            FROM $wpdb->posts
            WHERE post_title LIKE '$title'
            AND post_type = 'event'
            AND post_status = 'publish'
            LIMIT 1
        ");
        if ($page) echo "This title already exists !";
    }
}
add_action("wp_ajax_check_double_post", "my_ajax_update");

そしてあなたのメタボックステンプレートのどこかに(あるいはアクションを介してロードされます):

jQuery(document).ready(function($){
    var the_title = $('#title').val();
    $('#publish').click(function(e){
        e.preventDefault();
        $.post(
            ajaxurl,
            {
                action:"check_double_post",
                title: the_title
            },
            function(data){
                if ((data) != 0) {
                    message = $('<div id="message" class="error below-h2" />').html('<p>Warning, this title already exists!</p>')
                    $('h2').after(message);
                    $('#ajax-loading').hide();
                    $('#publish').removeClass('button-primary-disabled');
                }
                else {
                    $(this).submit();
                }
            }
        );
    });
});
2
Volpeo

あなたはこれがどれほどトリッキーであることが判明したかに驚かれるでしょう。一番近いのはsave_postアクションへのフックです。投稿を保存できないようにするためのフックするアクションはないようです。update_post()write_post()に対するすべてのアクションが直接の干渉を許しているようには見えません。だから私が思いついた非常にシンプルで素早いオプションはフックの中で死ぬことを含みます。それでも、死にかけているかどうかにかかわらず、投稿は重複した名前で保存されます。

function check_post_title( $pid ) {
    $post = get_post( $pid );
    $events = get_posts( 's='.$post->post_title.'&post_type=event' );

    foreach( (array)$events as $event ) {
        if ( $event->ID == $post->ID ) continue;
        if ( $event->post_title == $post->post_title ) die('Oh noes! A post with this title already exits, go back and change it, please.');
    }
}

add_action( 'save_post', 'check_post_title' );

save_postアクションは、保存した投稿の投稿IDをフックに渡します。その後、あなたのページで通常のWordPress検索を使用して検索するのと同じように、イベントは 's'引数を使用して検索されます。その後、イベントは繰り返し処理され、チェックオンの投稿以外のIDを持つ投稿が、このチェックオンの投稿と一致するタイトルで見つかった場合は終了します。

投稿が公開されたときに、より役立つもので、より簡潔なものには、カスタムメッセージが含まれます。

function check_post_title( $pid ) {
    $post = get_post( $pid );
    $events = get_posts( 's='.$post->post_title.'&post_type=event' );

    foreach( (array)$events as $event ) {
        if ( $event->ID == $post->ID ) continue;
        if ( $event->post_title == $post->post_title ) {
            add_filter( 'redirect_post_location', 'event_exists' );
        }
    }
}

/* Alter the message */
function event_exists( $redirect_url ) {
    $messages = array( 'message=1', 'message=2' );
    return str_replace( $messages, 'message=100', $redirect_url );
}

/* Add a custom event message */
function custom_event_message( $messages ) {
    $messages['post']['100'] = 'Oh noes! An event with this name already exists, so go ahead and pick another.';
    return $messages;
}

add_filter( 'post_updated_messages', 'custom_event_message' );

add_action( 'save_post', 'check_post_title' );

これは手っ取り早い解決策で、もっと複雑なことはおそらく、タイトルが重複しないという規則を侵害した保存された投稿にタイトルを変更して関数で保存し直さなければならないことを意味します。 [ここのタイトル] 'および投稿ステータスを'保留 'に戻す.

黄色いメッセージは非常に微妙なようで、出版社には気付かれないかもしれません、死ぬことはもっと注意を引くようです。

これが助けになり、あなたをあまり混乱させないことを願っています。問題に対するより良い解決策があるかもしれません、誰かがやって来て私たちが解決策を改善するのを助けてくれることを願いましょう。この時点で任意のアイデアをいただければ幸いです。

1
soulseekah

独自のクエリを作成する代わりに、単に関数post_exists()を使用しないのはなぜでしょうか。 post_title、content、およびdateを取ります(オプション)。この関数はpost_typeをテストしませんが、コンテンツに同じpost_titleがあることはまれです。

よろしく、Rahe。

0
Rahe