get_terms nu va afișa product_cat sau alte taxonomii personalizate când sunt specificate

17 feb. 2017, 21:17:50
Vizualizări: 22.3K
Voturi: 4

Mă întreb dacă ați putea avea câteva idei despre această problemă. Am căutat pe Google zile întregi dar nu pot găsi o soluție.

Iată unde mă aflu:

Am o meta box pentru tipul de postare 'products' din Woocommerce. În interiorul meta box există un 'type' => 'select' pe care vreau să-l populez cu o listă a tuturor 'taxonomy' => 'product_cat' disponibile.

Pot face caseta de selectare să se populeze și să funcționeze cu categoriile standard de postări, 'taxonomy' => 'category' folosind următorul cod:

function product_cats() {
$options = array();

$categories = get_terms( array( 'taxonomy' => 'category' ) );
foreach( $categories as $category ) {
    $options[$category->term_id] = array(
        'label' => $category->name,
        'value' => $category->slug
    );
}
// returnează array('options'=>$options);
return $options;
}

Totul se strică însă când încerc să folosesc 'taxonomy' => 'product_cat' sau orice altă taxonomie personalizată pe care o am.

Am crezut că problema era că încerc să accesez taxonomia personalizată înainte de a fi înregistrată, așa că am schimbat ordinea unor declarații/apeluri în fișierul function.php (cele care apelează CPT, meta boxes și woocommerce) pentru a schimba potențial ordinea în care rulează lucrurile, dar fără succes.

DAR, bazat pe întrebarea și răspunsul de mai jos, pot confirma acum că funcția poate 'vedea' și afișa toate termenele, în toate taxonomiile. Dacă exclud 'taxonomy =>' din argumente, returnează termeni din toate tipurile de postări personalizate și taxonomii.

În mod ideal funcția de bază ar arăta așa:

function product_cats() {
$options = array();

$categories = get_terms( array( 'taxonomy' => 'product_cat' ) );
foreach( $categories as $category ) {
    $options[$category->term_id] = array(
        'label' => $category->name,
        'value' => $category->slug
    );
}
// returnează array('options'=>$options);
return $options;
}

Mă întrebam dacă aveți vreo părere generală? Știu că e dificil fără a vedea întreaga bază de cod, dar m-am gândit că merită să întreb.

Versiune WordPress 4.7.2

Versiune WooCommerce 2.6.14

ACTUALIZARE:

Încet încerc să-mi localizez problema.

Se pare că 'product_cat' poate fi accesat până la urmă (bine) dar returnează un array care nu se afișează corect.

Acest lucru mă confuză deoarece dacă folosesc simplu get_terms() fără parametri, sau specificând 'taxonomy' => 'category' codul de mai sus funcționează perfect

Celelalte bucăți de cod cu care trebuie să lucrez sunt:

Array-ul în care aș dori să se afișeze lista de opțiuni

    array(  
        'label'=> 'Colecții',
        'desc'  => 'Selectați colecția pe care doriți să o afișați',
        'id'    => $prefix.'collection',
        'type'    => 'select',  
        'options' => product_cats()
),

codul care generează lista de selectare (folosit pentru alte câmpuri meta)

// select
case 'select':
echo '<select name="'.$field['id'].'" id="'.$field['id'].'">';
foreach ($field['options'] as $option) {
    echo '<option', $meta == $option['value'] ? ' selected="selected"' : '', ' value="'.$option['value'].'">'.$option['label'].'</option>';
}
echo '</select><br /><span class="description">'.$field['desc'].'</span>';
break;

Nu am nicio problemă cu alte câmpuri meta care funcționează sau se afișează, inclusiv listele de selectare.

Mai degrabă nu aș rescrie întreaga meta box cu toate câmpurile sale, așa că încerc să lucrez cu ce am în acest moment.

5
Comentarii

Am testat codul sub În mod ideal, funcția de bază ar trebui să fie: și funcționează pentru mine. Categoriile de produse sunt listate într-o cutie meta pe pagina de editare a produsului. WP 4.7.2, WC 2.6.9.

Dave Romsey Dave Romsey
17 feb. 2017 22:44:14

Vrei să împărtășești codul? Deoarece, deși răspunsul tău este util spunând că ar trebui să funcționeze, nu oferă nicio informație utilă.

Kevin Van Lierop Kevin Van Lierop
17 feb. 2017 22:46:35

Sigur, poți face la fel?

Dave Romsey Dave Romsey
17 feb. 2017 22:47:37

Fără a împărtăși codul întregului site, nu prea am ce altceva să mai împărtășesc. Funcția funcționează, până la un punct, deci ceva se strică sau lipsește în interiorul ei. Dacă ar fi existat cod suplimentar pentru funcție, l-aș fi împărtășit cu siguranță.

Kevin Van Lierop Kevin Van Lierop
17 feb. 2017 22:49:38

Voi vedea ce altceva mai pot descoperi.

Kevin Van Lierop Kevin Van Lierop
17 feb. 2017 22:51:27
Toate răspunsurile la întrebare 4
5

Probabil rulezi o versiune veche de WordPress (anterioră versiunii 4.5).

Înainte de WordPress 4.5.0, primul parametru al funcției get_terms() era o taxonomie sau o listă de taxonomii, iar începând cu versiunea 4.5.0, taxonomiile trebuie transmise prin argumentul 'taxonomy' în tabloul $args (așa cum faci tu, ar trebui să funcționeze astfel).

Găsești toate detaliile despre aceste modificări pe pagina de referință get_terms().

ACTUALIZARE: Scuze, am verificat codul meu și am folosit get_categories() nu get_terms, și așa este, get_terms() nu funcționează!

Iată un exemplu funcțional pentru a lista toate categoriile de produse (product_cat):

$product_categories = get_categories( array(
    'taxonomy'     => 'product_cat',
    'orderby'      => 'name',
    'pad_counts'   => false,
    'hierarchical' => 1,
    'hide_empty'   => false
) );

Sper că te ajută!

17 feb. 2017 22:37:03
Comentarii

Versiunea WordPress este: Versiunea 4.7.2 (Voi adăuga mai multe detalii la problemele inițiale)

Kevin Van Lierop Kevin Van Lierop
17 feb. 2017 22:42:02

fără succes, dacă vrei să adaugi un meta_box pe ecranul de editare al produsului, folosești acțiunea add_meta_boxes sau altă acțiune pentru a declanșa add_meta_box() ?

Benoti Benoti
17 feb. 2017 22:46:40

folosesc add_meta_boxes. Nu cred că e o problemă cu meta box-ul ci mai degrabă cu accesarea termenilor product_cat

Kevin Van Lierop Kevin Van Lierop
17 feb. 2017 22:47:50

După cum ți-a spus Dave Romsey în comentariu, ar trebui să funcționeze, funcționează și la mine.

Benoti Benoti
17 feb. 2017 22:49:57

Am făcut o actualizare la răspunsul meu.

Benoti Benoti
17 feb. 2017 23:08:33
0

Pentru viața mea, chiar vreau să fac asta să funcționeze corect. Dar, la naiba, nu reușesc să înțeleg cum să integrez.

Anterior, m-am uitat la wp_dropdown_categories() și am crezut că ar fi o soluție mai bună (și mai ușoară). Am ajuns să lucrez la problema de mai sus pentru că nu am reușit să înțeleg cum să o fac să funcționeze cu sintaxa existentă a cutiei meta.

Pentru moment, am optat pentru soluția temporară găsită mai jos. Nu este ideală și cu siguranță nu cea mai bună metodă, dar îmi permite să avansez în utilizarea valorilor în șabloanele care vor folosi acest câmp.

// Încapsulează toate categoriile într-o funcție
function product_cats() {
    $output = array();
    $categories = get_terms( array(
    'orderby'      => 'name',
    'pad_counts'   => false,
    'hierarchical' => 1,
    'hide_empty'   => true,
    ) );
    foreach( $categories as $category ) {
        if ($category->taxonomy == 'product_cat' ) {
            $output[$category->slug] = array(
                'label' => $category->name,
                'value' => $category->slug
            );
        }
    }
    //return array('options'=>$output);
    return $output;
}

Voi actualiza pe măsură ce avansez.

18 feb. 2017 15:26:42
2

Probabil că nu va rezolva problema, dar am vrut să împărtășesc: Am întâlnit aceeași problemă astăzi și a fost cauzată de faptul că nu aveam niciun produs în categoriile mele. Dacă și în cazul tău este așa, asigură-te să adaugi 'hide_empty' => false.

Cu toate acestea. Când apelezi get_terms() fără niciun argument. Care este rezultatul?

17 feb. 2017 21:54:13
Comentarii

Adăugarea opțiunii 'hide_empty' => false nu ajută deloc.

În ceea ce privește rularea funcției get_terms() fără niciun argument, nici măcar specificând taxonomia, obțin o listă masivă a TOȚI termenilor, din toate taxonomiile în care apar (inclusiv product_cat pe care încerc să-l accesez).

Ceea ce mă face să mă întreb care este problema, deoarece se pare că 'vede' categoriile de produse până la urmă.

Va trebui să fac câteva teste pentru a verifica dacă acestea apar cu adevărat.

Kevin Van Lierop Kevin Van Lierop
17 feb. 2017 21:57:23

Am confirmat, dacă exclud parametrul 'taxonomy' => din argumente, returnează termeni din toate tipurile de postări personalizate și taxonomii.

Ceea ce reprezintă un pas în direcția bună.

Kevin Van Lierop Kevin Van Lierop
17 feb. 2017 22:06:58
2

Iată un exemplu complet funcțional al unei căsuțe meta care afișează o listă derulantă cu categorii de produse. Căsuța meta va apărea pe tipul de postare "product".

add_action( 'add_meta_boxes', 'wpse256897_add_meta_box' );
add_action( 'save_post',     'wpse256897_save' );
/**
 * Adaugă containerul căsuței meta.
 */
function wpse256897_add_meta_box( $post_type ) {
    // Limităm căsuța meta la anumite tipuri de postări.
    $post_types = array( 'product' );

    if ( in_array( $post_type, $post_types ) ) {
        add_meta_box(
            'product_cat_selection',
             __( 'Selectare categorie produs', 'textdomain' ),
             'wpse256897_render_meta_box_content',
             $post_type,
             'advanced',
             'high'
        );
    }
}

/**
 * Salvează metadatele când postarea este salvată.
 *
 * @param int $post_id ID-ul postării care se salvează.
 */
function wpse256897_save( $post_id ) {
    /*
     * Trebuie să verificăm că această acțiune vine de pe ecranul nostru și cu autorizația corespunzătoare,
     * deoarece save_post poate fi declanșat în alte momente.
     */

    // Verifică dacă nonce-ul nostru este setat.
    if ( ! isset( $_POST['myplugin_inner_custom_box_nonce'] ) ) {
            return $post_id;
    }

    $nonce = $_POST['myplugin_inner_custom_box_nonce'];

    // Verifică dacă nonce-ul este valid.
    if ( ! wp_verify_nonce( $nonce, 'myplugin_inner_custom_box' ) ) {
            return $post_id;
    }

    /*
     * Dacă aceasta este o salvare automată, formularul nostru nu a fost trimis,
     * așa că nu vrem să facem nimic.
     */
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
            return $post_id;
    }

    // Verifică permisiunile utilizatorului.
    if ( 'page' == $_POST['post_type'] ) {
            if ( ! current_user_can( 'edit_page', $post_id ) ) {
                    return $post_id;
            }
    } else {
            if ( ! current_user_can( 'edit_post', $post_id ) ) {
                    return $post_id;
            }
    }

    /* OK, acum este sigur să salvăm datele. */

    // Curăță input-ul utilizatorului.
    $mydata = sanitize_text_field( $_POST['product_cat_selection'] );

    // Actualizează câmpul meta.
    update_post_meta( $post_id, '_product_cat_selection', $mydata );
}

/**
 * Randare conținut căsuță meta.
 *
 * @param WP_Post $post Obiectul post.
 */
function wpse256897_render_meta_box_content( $post ) {
    // Adaugă un câmp nonce pentru a-l putea verifica mai târziu.
    wp_nonce_field( 'myplugin_inner_custom_box', 'myplugin_inner_custom_box_nonce' );

    // Folosește get_post_meta pentru a prelua o valoare existentă din baza de date.
    $current_product_cat = get_post_meta( $post->ID, '_product_cat_selection', true );

    // Afișează formularul, folosind valoarea curentă.
    $product_cats = wpse256897_product_cats();
    if ( !empty ( $product_cats ) ) {
        echo '<select name="product_cat_selection" id="product_cat_selection">';
        foreach ( $product_cats as $product_cat_id => $product_cat ) { ?>
            <option value="<?php echo esc_attr( $product_cat['value'] ); ?>" <?php if ( isset ( $current_product_cat ) ) selected( $current_product_cat, $product_cat['value'] ); ?>><?php echo esc_html( $product_cat['label'] ); ?></option><?php
        }
        echo '</select>';
    }
}               

function wpse256897_product_cats() {
    $options = array();
    $categories = get_terms( array( 'taxonomy' => 'product_cat' ) );

    foreach( $categories as $category ) {
        $options[$category->term_id] = array(
                'label' => $category->name,
                'value' => $category->slug
        );
    }

    return $options;
}

Acesta nu este cel mai elegant exemplu (convențiile de denumire ar putea fi mai bune). A fost adaptat rapid din notele contribuite pe pagina de referință Add Meta Box, dar demonstrează că funcția wpse256897_product_cats() obține categoriile de produse și că acestea pot fi salvate și afișate într-o listă derulantă pe pagina de produs în cadrul unei căsuțe meta.

Aș mai adăuga că ar putea fi util să verificați funcția wp_dropdown_categories(). Care, în ciuda numelui, funcționează și cu taxonomii personalizate. Acest lucru v-ar scuti de crearea propriului markup pentru lista derulantă de categorii.

Actualizare: Se pare că structura array-ului returnat de funcția product_cats() nu se potrivește cu implementarea căsuței meta. Observați că în exemplul meu de mai sus, am folosit această linie pentru a parcurge categoriile la generarea opțiunilor pentru elementul select:

foreach ( $product_cats as $product_cat_id => $product_cat ) { ?>

Acest lucru se întâmplă deoarece $product_cats este un array asociativ de ID-uri de categorii, fiecare conținând un alt array cu label și slug pentru fiecare ID de categorie.

Se pare că ați putea folosi această versiune alternativă a funcției product_cats() care formatează valoarea returnată $options într-un mod compatibil cu codul căsuței meta:

function product_cats_alternate() {
    $options = array();

    $categories = get_terms( array( 'taxonomy' => 'product_cat' ) );
    foreach( $categories as $category ) {
            $options[] = array(
              'label' => $category->name,
              'value' => $category->slug
            );
    }
    return $options;
}
17 feb. 2017 23:16:51
Comentarii

Mulțumesc, Dave. Acest lucru m-a ajutat să înțeleg mai bine care este problema mea reală (am actualizat postul original). Aș prefera să nu fiu nevoit să actualizez întreaga mea cutie meta (deși dacă trebuie, o voi face), dar încerc să lucrez cu ce am la momentul actual. Mulțumesc că m-ai ajutat să înțeleg.

notă: Am încercat wp_dropdown_categories, dar am avut și mai multe dificultăți în a-l face să populeze o listă de selectare.

Kevin Van Lierop Kevin Van Lierop
18 feb. 2017 04:06:56

Ați înțeles! Am adăugat o mică actualizare la răspunsul meu original.

Dave Romsey Dave Romsey
18 feb. 2017 04:34:48