Cum migrezi de la Thinkific la WordPress. Partea 4: Import recenzii

Cum migrezi de la Thinkific la WordPress. Partea 4: Import recenzii

acum 3 luni ·
· 5 min de citit

În articolul anterior, partea a treia a acestei serii de 5 articole, am descris implementarea comenzii WP-CLI de importare a progresului cursurilor pentru utilizatori.

În partea a patra voi descrie funcționalitatea comenzii WP-CLI pentru a importa recenziile date de utilizatori cursurilor. Mai jos îți las și lista de articole din serie:

Cuprins

Declararea metodei de import recenzii

Încep din nou cu declararea metodei și a variabilelor ajutătoare pentru citirea din fișier:

class-wpcli.php
public function import_reviews(): void {
    global $wp_filesystem, $wpdb;
 
    include_once ABSPATH . 'wp-admin/includes/file.php';
    WP_Filesystem();
 
    $files = array( 'course-1-reviews.json', 'course-2-reviews.json', 'course-3-reviews', 'course-4-reviews.json' );
    //...
}

Am declarat și o variabilă de tip vector cu lista fișierelor cu recenzii pentru cursuri pe care o voi parcurge iterativ cu foreach ( $files as $file ).

Citirea din fișier

Structura fișierului JSON

Mai pun aici încă o dată structura fișierului de recenzii în format JSON:

course-*-reviews.json
{
  "@context": "http://schema.org",
  "@type": "Product",
  "name": "<nume-curs>",
  "aggregateRating": { "@type": "AggregateRating", "ratingValue": "4.6", "reviewCount": 5 },
  "review": [
    {
      "@type": "Review",
      "author": { "@type": "Person", "name": "<nume-recenzor>" },
      "description": "<descriere-recenzie>",
      "name": "<titlu-recenzie>",
      "date": "November 26, 2021",
      "reviewRating": { "@type": "Rating", "bestRating": 5, "ratingValue": 5, "worstRating": 0 }
    },
    // ...
  ],
    "image": "<url-imagine-curs>"
}

Ca și în articolele precendente, citirea din fișiere se face aproximativ la fel, doar că de această dată nu voi mai folosi metoda ajutătoare parse_csv_content de compunere a vectorului cu liniile din fișierul CSV, ci voi folosi funcția json_decode pentru interpretarea codului JSON:

class-wpcli.php
$file_path    = plugin_dir_path( __FILE__ ) . '/data/reviews/' . $file;
$file_content = $wp_filesystem->get_contents( $file_path );
$json         = json_decode( $file_content );
 
$course_name  = $json->name;
$review_count = count( $json->review );
 
$course = get_page_by_title( $course_name, OBJECT, 'courses' );

Am declarat și alte câteva variabile care-mi vor folosi mai departe. M-am asigurat că numele cursurilor din fișierele cu recenzii din câmpul name corespund cu numele cursurilor create în Tutor LMS.

Procesarea recenziilor

Am început apoi să parcurg recenziile din vectorul review din JSON și am procedat astfel mai departe:

class-wpcli.php
foreach ( $json->review as $review ) {
    $user_id = $this->search_user_by_name( $review->author->name );
    $new_comment  = wp_insert_comment(
        array(
            'comment_post_ID'  => $course->ID,
            'comment_author'   => $review->author->name,
            'comment_date'     => gmdate( 'Y-m-d H:i:s', strtotime( $review->date ) ),
            'comment_content'  => $review->description,
            'comment_agent'    => 'TutorLMSPlugin',
            'comment_type'     => 'tutor_course_rating',
            'comment_approved' => 'approved',
            'user_id'          => $user_id,
            'comment_meta'     => array( 'tutor_rating' => $review->reviewRating->ratingValue ), // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
        )
    );
 
    if ( is_wp_error( $new_comment ) ) {
        \WP_CLI::warning( sprintf( 'Review of "%s" for "%s" not imported.', $review->author->name, $course_name ) );
    }
}

Am făcut o căutare după numele utilizatorului pentru a-i lua ID-ul din baza de date, folosind metoda de ajutor search_user_by_name, descrisă ceva mai jos. Apoi am folosit funcția wp_insert_comment pentru crearea recenziei, căreia i-am transmis valorile necesare:

Metoda de căutare a utilizatorului după nume și prenume este aici:

class-wpcli.php
protected function search_user_by_name( string $name ): int {
    $normalized_name = str_replace( '  ', ' ', trim( $name ) );
    $names           = explode( ' ', $normalized_name );
    $last_name       = array_pop( $names );
    $first_name      = implode( ' ', $names );
 
    $wp_user_query = new WP_User_Query(
        array(
            'role'       => 'subscriber',
            'meta_query' => array(
                'relation' => 'AND',
                array(
                    'key'     => 'first_name',
                    'value'   => $first_name,
                    'compare' => '=',
                ),
                array(
                    'key'     => 'last_name',
                    'value'   => $last_name,
                    'compare' => '=',
                ),
            ),
        )
    );
 
    $authors = $wp_user_query->get_results();
 
    return $authors[0]->ID;
}

În primă fază am făcut o mică normalizare a numelui, în speță am eliminaț spațiile din extremități și am înlocuit spațiile duble din nume cu unul singur. Am observat foarte multe neconcordanțe de acest gen în fișierul exportat JSON obținut din paginile cursurilor din Thinkific.

Apoi (în linile 3-5) am împărțit numele după spațiu pentru a putea apoi să obțin numele și prenumele, chiar și atunci când numele complet este format din 3 nume. În acest caz am folosit ChatGPT și așa a ieșit combinația dintre funcțiile explode, array_pop și implode.

Mai departe am folosit clasa WP_User_Query pentru interogarea complexă și găsirea utilizatorului după numele și prenumele lui și în final am returnat ID-ul.

Încheiere

Cu rularea ultimei comenzi WP-CLI avem și recenziile adăugate:

$ wp thinkific import reviews

Migrarea este finalizată, în următorul articol voi mai face câteva adaptări ale temei, ale șabloanelor Tutor LMS și WooCommerce.

Dacă ai nevoie de o astfel de migrare, dă clic mai jos și hai să discutăm.

Contactează-mă

Partajează pe: