get_terms non visualizza product_cat o altre tassonomie personalizzate quando specificate

17 feb 2017, 21:17:50
Visualizzazioni: 22.3K
Voti: 4

Mi chiedo se potreste avere qualche idea su questo problema. Ho cercato su Google per giorni ma non riesco a trovare una soluzione.

Ecco dove mi trovo:

Ho una meta box per il tipo di post 'products' di Woocommerce. All'interno della meta box c'è un 'type' => 'select' che voglio popolare con un elenco di tutti i 'taxonomy' => 'product_cat' disponibili.

Riesco a popolare e far funzionare la select box con le categorie standard dei post, 'taxonomy' => 'category' usando il seguente codice:

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
    );
}
// restituisce array('options'=>$options);
return $options;
}

Tutto si rompe però quando provo a usare 'taxonomy' => 'product_cat' o qualsiasi altra tassonomia personalizzata che ho.

Pensavo che il problema fosse che sto cercando di accedere alla tassonomia personalizzata prima che venga registrata, quindi ho scambiato alcune dichiarazioni/chiamate nel mio file function.php (quelle che richiamano il CPT, meta box e woocommerce) per potenzialmente cambiare l'ordine in cui vengono eseguite le cose ma senza successo.

MA, basandomi sulla domanda e risposta qui sotto, posso ora confermare che la funzione può 'vedere' e visualizzare tutti i termini, attraverso le tassonomie. Se escludo 'taxonomy => dagli argomenti restituisce i termini da tutti i tipi di post personalizzati e le tassonomie.

Idealmente la funzione base dovrebbe essere:

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
    );
}
// restituisce array('options'=>$options);
return $options;
}

Mi chiedevo se aveste qualche pensiero generale? So che è difficile senza vedere l'intero codice, ma pensavo valesse la pena chiedere.

Versione WordPress 4.7.2

Versione WooCommerce 2.6.14

AGGIORNAMENTO:

Lentamente sto cercando di individuare il mio problema.

Sembra che 'product_cat' possa essere accessibile dopo tutto (bene) ma sta restituendo un array che non viene visualizzato correttamente.

Questo mi confonde perché se uso semplicemente get_terms() senza parametri, o specificando 'taxonomy' => 'category' il codice sopra funziona perfettamente

Gli altri pezzi di codice che ho bisogno che funzionino con questo sono:

L'array in cui vorrei che l'elenco delle opzioni venga inserito

    array(  
        'label'=> 'Collezioni',
        'desc'  => 'Seleziona la collezione che vorresti visualizzare',
        'id'    => $prefix.'collection',
        'type'    => 'select',  
        'options' => product_cats()
),

il codice che genera la lista select (usato per altri campi 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;

Non ho alcun problema con altri campi meta che funzionano o vengono visualizzati, incluse le liste select.

Preferirei non riscrivere l'intera meta box con tutti i suoi campi quindi sto cercando di lavorare con quello che ho al momento.

5
Commenti

Ho testato il codice sotto Ideally the basic function would read: e funziona per me. Le categorie di prodotti sono elencate all'interno di una meta box nella pagina di modifica del prodotto. WP 4.7.2, WC 2.6.9.

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

Vuoi condividere il codice? Perché mentre la tua risposta è utile nel dire che dovrebbe funzionare, non fornisce alcuna informazione utile.

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

Certo, puoi fare lo stesso?

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

Senza condividere il codice dell'intero sito non c'è molto altro da mostrare. La funzione funziona, fino a un certo punto, quindi qualcosa si sta interrompendo o manca al suo interno. Se ci fosse del codice aggiuntivo per la funzione lo condividerò sicuramente.

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

Vedrò cos'altro riesco a trovare.

Kevin Van Lierop Kevin Van Lierop
17 feb 2017 22:51:27
Tutte le risposte alla domanda 4
5

Potresti star utilizzando una versione obsoleta di WordPress (antecedente alla 4.5).

Prima di WordPress 4.5.0, il primo parametro di get_terms() era una tassonomia o una lista di tassonomie. A partire dalla versione 4.5.0, le tassonomie devono essere passate tramite l'argomento 'taxonomy' nell'array $args (proprio come stai facendo, dovrebbe funzionare così).

Troverai tutti i dettagli su questi cambiamenti nella pagina di riferimento di get_terms().

AGGIORNAMENTO: Mi scuso, ho verificato il mio codice e in realtà utilizzo get_categories() non get_terms, ed è corretto che get_terms() non funzioni!

Ecco un esempio funzionante per elencare tutte le mie product_cat

$product_categories = get_categories( array(
    'taxonomy'     => 'product_cat',  // Specifica la tassonomia delle categorie prodotto
    'orderby'      => 'name',         // Ordina per nome
    'pad_counts'   => false,          // Non mostra conteggi annidati
    'hierarchical' => 1,              // Mostra gerarchicamente
    'hide_empty'   => false           // Mostra anche categorie vuote
) );

Spero sia utile!

17 feb 2017 22:37:03
Commenti

La versione di WordPress è: Versione 4.7.2 (Aggiungerò ulteriori dettagli ai problemi iniziali)

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

nessuna fortuna, se vuoi aggiungere un meta_box nella schermata di modifica prodotto, stai usando l'azione add_meta_boxes o un'altra per attivare la add_meta_box() ?

Benoti Benoti
17 feb 2017 22:46:40

sto usando add_meta_boxes. Non credo sia un problema con il meta box ma piuttosto con l'accesso ai termini di product_cat

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

Come Dave Romsey ti ha detto nel commento, dovrebbe funzionare, funziona anche per me.

Benoti Benoti
17 feb 2017 22:49:57

Ho fatto un aggiornamento alla mia risposta.

Benoti Benoti
17 feb 2017 23:08:33
0

Per la mia vita, voglio davvero far funzionare questo nel modo giusto. Per la mia vita, non riesco a capire l'integrazione.

In precedenza avevo considerato wp_dropdown_categories() e pensavo fosse una soluzione migliore (e più semplice). Sono finito a lavorare sul problema sopra perché non riuscivo a capire come farlo funzionare con la sintassi esistente della meta box.

Per ora ho optato per la soluzione temporanea trovata qui sotto. Non è ideale e certamente non è il modo migliore, ma mi permette di andare avanti con il richiamo dei valori nei template che utilizzeranno questo campo.

// Incapsula tutte le categorie in una funzione
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;
}

Aggiornerò man mano che procedo.

18 feb 2017 15:26:42
2

Probabilmente non risolverà il problema, ma volevo condividere: mi sono imbattuto nello stesso problema oggi ed era causato dal fatto che non avevo prodotti nelle mie categorie. Se è lo stesso anche per te, assicurati di aggiungere 'hide_empty' => false.

Detto questo. Quando esegui get_terms() senza alcun argomento. Qual è l'output?

17 feb 2017 21:54:13
Commenti

Aggiungere 'hide_empty' => false non aiuta affatto.

Per quanto riguarda l'esecuzione di get_terms() senza alcun argomento, nemmeno specificando la tassonomia, ottengo un enorme elenco di TUTTI i termini, attraverso tutte le tassonomie in cui appaiono (incluso product_cat che sto cercando di accedere.

Il che mi porta a chiedermi quale sia il problema, dato che sembra "vedere" le categorie di prodotti dopo tutto.

Dovrò fare qualche test per vedere se effettivamente appaiono.

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

Confermato, se escludo 'taxonomy' => dagli argomenti, restituisce termini da tutti i tipi di post personalizzati e tassonomie.

Il che è un passo nella giusta direzione.

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

Ecco un esempio completamente funzionante di una meta box che mostra una select box per le categorie di prodotti. La meta box apparirà sul post type "product".

add_action( 'add_meta_boxes', 'wpse256897_add_meta_box' );
add_action( 'save_post',     'wpse256897_save' );
/**
 * Aggiunge il contenitore della meta box.
 */
function wpse256897_add_meta_box( $post_type ) {
    // Limita la meta box a specifici post type.
    $post_types = array( 'product' );

    if ( in_array( $post_type, $post_types ) ) {
        add_meta_box(
            'product_cat_selection',
             __( 'Selezione Categoria Prodotto', 'textdomain' ),
             'wpse256897_render_meta_box_content',
             $post_type,
             'advanced',
             'high'
        );
    }
}

/**
 * Salva i meta quando il post viene salvato.
 *
 * @param int $post_id L'ID del post che viene salvato.
 */
function wpse256897_save( $post_id ) {
    /*
     * Dobbiamo verificare che questa richiesta provenga dalla nostra schermata e con la giusta autorizzazione,
     * perché save_post può essere attivato in altri momenti.
     */

    // Controlla se il nostro nonce è impostato.
    if ( ! isset( $_POST['myplugin_inner_custom_box_nonce'] ) ) {
            return $post_id;
    }

    $nonce = $_POST['myplugin_inner_custom_box_nonce'];

    // Verifica che il nonce sia valido.
    if ( ! wp_verify_nonce( $nonce, 'myplugin_inner_custom_box' ) ) {
            return $post_id;
    }

    /*
     * Se questo è un autosave, il nostro form non è stato inviato,
     * quindi non vogliamo fare nulla.
     */
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
            return $post_id;
    }

    // Controlla i permessi dell'utente.
    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, ora è sicuro salvare i dati. */

    // Sanitizza l'input dell'utente.
    $mydata = sanitize_text_field( $_POST['product_cat_selection'] );

    // Aggiorna il campo meta.
    update_post_meta( $post_id, '_product_cat_selection', $mydata );
}

/**
 * Renderizza il contenuto della Meta Box.
 *
 * @param WP_Post $post L'oggetto post.
 */
function wpse256897_render_meta_box_content( $post ) {
    // Aggiunge un campo nonce per poterlo verificare dopo.
    wp_nonce_field( 'myplugin_inner_custom_box', 'myplugin_inner_custom_box_nonce' );

    // Usa get_post_meta per recuperare un valore esistente dal database.
    $current_product_cat = get_post_meta( $post->ID, '_product_cat_selection', true );

    // Mostra il form, usando il valore corrente.
    $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;
}

Questo non è l'esempio più elegante (le convenzioni di denominazione potrebbero essere migliori). È stato rapidamente adattato dalle note contribuite nella pagina di riferimento Add Meta Box, ma dimostra che wpse256897_product_cats() ottiene effettivamente le categorie di prodotti e che possono essere salvate e visualizzate in una select box nella pagina del prodotto all'interno di una meta box.

Vorrei anche aggiungere che potrebbe valere la pena dare un'occhiata alla funzione wp_dropdown_categories(). Nonostante il nome, funziona anche con tassonomie personalizzate. Questo ti eviterebbe di dover creare il tuo markup per il dropdown delle categorie.

Aggiornamento: Sembra che la struttura dell'array restituito dalla funzione product_cats() non sia compatibile con la tua implementazione della meta box. Nota che nel mio esempio sopra ho usato questa riga per ciclare sulle categorie quando generavo le opzioni per l'elemento select:

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

Questo perché $product_cats è un array associativo di ID categoria che contengono a loro volta un altro array con label e slug per ogni ID categoria.

Sembra che tu possa usare questa versione alternativa di product_cats() che formatta il valore di ritorno $options in modo compatibile con il tuo codice della metabox:

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
Commenti

Grazie Dave. Questo mi ha aiutato a capire meglio qual è il mio problema effettivo (ho aggiornato il post originale). Vorrei evitare di dover aggiornare l'intero meta box (anche se se necessario lo farò) ma piuttosto cercare di lavorare con quello che ho al momento. Grazie per avermi aiutato a capire.

Nota: ho provato wp_dropdown_categories ma ho avuto ancora più difficoltà a farlo popolare una lista di selezione.

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

Perfetto! Ho aggiunto un piccolo aggiornamento alla mia risposta originale.

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