web-dev-qa-db-fra.com

Changer les permaliens avec les valeurs ACF

J'utilise un site sur lequel je laisse les utilisateurs créer un profil, qui est un type de publication personnalisé, qui est soumis/modifié via un formulaire ACF front-end. Tout fonctionne comme prévu, sauf lorsque les utilisateurs utilisent tous deux le même "titre" (qui est assaini et utilisé comme lien permanent).

Je veux que le permalien ait la 'structure' suivante:/post-type/ville/{post-titre} - {post-id}. Je pensais ajouter un identifiant de publication pour que chaque lien soit unique, mais je découvre maintenant que ce n'est pas le cas.

Si j'avais 2 profils: www.domain.com/profile/city/i-am-cool-123 www.domain.com/profile/city/i-am-cool-456

Ensuite, www.domain.com/profile/city/i-am-cool-456 est redirigé vers www.domaine.com/profile/city/i-am-cool-123.

Je savais que vous ne pouviez pas avoir les mêmes permaliens, mais j’ai peut-être mal compris comment les permaliens sont "enregistrés".

Ci-dessous mon code.

D'abord, j'ai ajouté les vars de requête nécessaires aux nouveaux vars, ainsi que des balises de réécriture personnalisées.

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

Pour obtenir le permalien que je souhaite, j’ai mis en place le code suivant.

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

Jusqu'à présent, rien de bizarre ne se passe, tout cela fait ce qu'il est censé faire, mais maintenant, nous nous en tenons au problème (je pense).

Je mets à jour le slug via une action WPDB, une fois le message soumis, comme indiqué ci-dessous.

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

Et puis finalement je réécris l'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' );

En gros, ma question est la suivante: existe-t-il un moyen de "faire" ce que je veux faire? Et si oui, comment :)

2
Beee

Je pensais trop 'difficile'. Au lieu de reconstruire une nouvelle structure de permalien, j'aurais facilement pu mettre à jour le nouveau permalien comme je le souhaite.

J'ai donc supprimé la totalité de la partie réécriture et modifié la requête dans acf/save_post comme suit:

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