web-dev-qa-db-ja.com

ACF値でパーマリンクを変更する

私は、ACFフロントエンドフォームを通して送信/編集されるカスタム投稿タイプのプロファイルをユーザーに作成させるサイトを運営しています。ユーザーが両方とも同じ「見出し」(サニタイズされ、パーマリンクとして使用されている)を使用している場合を除き、すべて正常に機能します。

私はパーマリンクに次の '構造'を持たせたい:/ post-type/city/{post-title} - {post-id}。私の考えは投稿IDを追加することだったので、それぞれのリンクはユニークになるでしょう、しかし私は今これが事実ではないことを知りました。

私は2つのプロファイルがある場合:www.domain.com/profile/city/i-am-cool-123

それからwww.domain.com/profile/city/i-am-cool-456はwww.domain.com/profile/city/i-am-cool-123にリダイレクトします。

私はあなたが2つの同じパーマリンクを持つことができないことを知っていました、しかし私はパーマリンクがどのように「登録される」か誤解したかもしれません。

以下が私のコードです。

最初に、新しい変数に必要なクエリ変数を追加し、カスタム書き換えタグを追加しました。

function sd_custom_rewrite_tag() {
    add_rewrite_tag( '%city%', '([^&]+)', 'city=' );
    add_rewrite_tag( '%postname%', '([^&]+)', 'name=' );
}
add_action( 'init', 'sd_custom_rewrite_tag', 10, 0 );

function sd_add_query_vars( $vars ) {
    $vars[] = "city";
    $vars[] = "postname";

    return $vars;
}
add_filter( 'query_vars', 'sd_add_query_vars' );

私が欲しいパーマリンクを得るために、私は代わりに次のコードを持っています。

function sd_new_profile_permalink( $permalink, $post, $leavename = false ) {

    if ( strpos( $permalink, '%city%' ) === FALSE ) {
        return $permalink;
    }

    // Get post
    if ( ! $post ) {
        return $permalink;
    }

    // Get custom info
    $city_info  = get_field( 'sd_city_selector', $post->ID );
    $post_slug  = $post->post_name;
    if ( ! is_wp_error( $city_info ) && ! empty( $city_info ) ) {
        $city_replace  = str_replace( '\'', '', $city_info[ 'cityName' ] );
        $city_replace  = str_replace( ' ', '-', $city_replace );
        $city_slug     = strtolower( $city_replace );
        $new_permalink = str_replace( array( '%city%', '%postname%', '%post_id%' ), array( $city_slug, $post_slug, $post->ID ), $permalink );

        return $new_permalink;
    }
    return $permalink;
}
add_filter( 'post_link', 'sd_new_profile_permalink', 10, 3 );
add_filter( 'post_type_link', 'sd_new_profile_permalink', 10, 3 );

これまでのところ奇妙なことは何も起こっていません、これはそれがするべきであることをすべてやっています、しかし今我々は問題に取り掛かります(私は思います)。

下記のように、投稿が送信された後、私はWPDBアクションを通してスラッグを更新します。

function set_profile_title_from_headline( $post_id ) {

    if ( empty( $_POST[ 'acf' ] ) ) {
        return;
    }

    if ( ! empty( $_POST[ 'acf' ][ 'field_57e3ed6c92ea0' ] ) ) {
        $entered_title = $_POST[ 'acf' ][ 'field_57e3ed6c92ea0' ];
        $cleaned_title = preg_replace( '/[^A-Za-z0-9\-\s]/', '', $entered_title ); 
        $post_name     = sanitize_title( $cleaned_title );
        update_field( 'sd_ad_title', $cleaned_title, $post_id ); 

        global $wpdb;
        $wpdb->update(
            $wpdb->posts,
            array(
                'post_title'  => $cleaned_title,
                'post_name'   => $post_name
            ),
            array(
                'ID' => $post_id
            )
        );

        clean_post_cache( $post_id );

    }

}
add_action( 'acf/save_post', 'set_profile_title_from_headline', 20 );

そして最後にURLを書き換えます。

function sd_single_profile_rewrite() {
    global $wp_rewrite;
    $wp_rewrite->add_permastruct( 'profile', 'profile/%city%/%postname%-%post_id%/', false );
    add_rewrite_rule( 'profile\/([a-z-]+)\/(.+)-[0-9]+\/?$', 'index.php?post_type=profile&p=$matches[2]&city=$matches[1]&name=$matches[2]', 'top' );
}
add_action( 'init', 'sd_single_profile_rewrite' );

基本的に私の質問は:私がやりたいことを「やる」方法はありますか?そしてもしそうなら、どうやって:)

2
Beee

私はあまりにも「難しい」と考えていました。新しいパーマリンク構造を再構築する代わりに、新しいパーマリンクを自分の望む通りに簡単に更新できたはずです。

そこで、書き換え部分全体を削除し、acf/save_post内のクエリを次のように変更しました。

if ( ! empty( $_POST[ 'acf' ][ $ad_title ] ) ) {

    $entered_title = $_POST[ 'acf' ][ $ad_title ];
    $cleaned_title = preg_replace( '/[^A-Za-z0-9\-\s]/', '', 
    $entered_title ); // Removes special chars.
    $post_name     = sanitize_title( $cleaned_title );
    $city_name     = get_field( 'sd_city_search_value', $post_id );
    $new_slug      = strtolower( $city_name ) . '-' . $post_name . '-' . $post_id;

    // update acf field
    update_field( 'sd_ad_title', $cleaned_title, $post_id );

    // update post status + post title (if needed)
    global $wpdb;
    $wpdb->update(
        $wpdb->posts,
        array(
            'post_title'  => $cleaned_title,
            'post_name'   => strtolower( get_field( 'sd_city_search_value', $post_id ) ) . '-' . $post_name . '-' . $post_id
        ),
        array(
            'ID' => $post_id
        )
    );

    clean_post_cache( $post_id );

}
2
Beee