Ottieni meta_id insieme a meta_key e meta_value

19 ago 2013, 23:48:26
Visualizzazioni: 21.1K
Voti: 5

È in qualche modo possibile ottenere con get_post_meta o get_post_custom il meta_id restituito insieme al meta_value? Per esempio:

$data = get_post_meta( $post_id, 'my_key' );
// restituisce questo:
array( 0 => array('myvalue1', 1002 ), 1 => array( 'myvalue2', 1003 ));

L'idea di base è che poiché potrebbero esserci più meta_values per lo stesso meta_key, dovrei conoscere il meta_id per poter aggiornare/eliminare in modo affidabile i meta del post.

5
Commenti

get_post_meta(); richiede il terzo parametro come true che stai tralasciando get_post_meta( $post_id, 'my_key', true );

Anjum Anjum
20 ago 2013 00:03:50

@Anjum il terzo parametro non è obbligatorio, è opzionale. Se passi il terzo parametro come true otterrai solo un valore... quindi per l'OP passare quel parametro è sbagliato.

gmazzap gmazzap
20 ago 2013 00:06:02

@G. M cosa dice il codex di WordPress: $single (boolean) (opzionale) Se impostato a true la funzione restituirà un singolo risultato, come stringa. Se false, o non impostato, la funzione restituirà un array dei campi personalizzati. Questo potrebbe non essere intuitivo nel contesto di array serializzati. Se recuperi un array serializzato con questo metodo, vuoi che $single sia true per ottenere effettivamente un array deserializzato. Se passi false, o lo ometterai, avrai un array di un elemento, e il valore all'indice 0 sarà la stringa serializzata. Default: false

Anjum Anjum
20 ago 2013 00:10:14

@Anjum è esattamente quello che ho detto. Ma se leggi la domanda: potrebbero esserci più meta_values per lo stesso meta_key capisci che in questo caso usare il 3° parametro come true è sbagliato.

gmazzap gmazzap
20 ago 2013 00:14:19

Sì, nel mio caso ho bisogno di ottenere più meta_values per lo stesso meta_key.

ragulka ragulka
20 ago 2013 10:21:59
Tutte le risposte alla domanda 6
0

Questa funzione ha funzionato per me:

function get_complete_meta( $post_id, $meta_key ) {
  global $wpdb;
  $mid = $wpdb->get_results( $wpdb->prepare("SELECT * FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = %s", $post_id, $meta_key) );
  if( $mid != '' )
    return $mid;

  return false;
}

restituirà un array di oggetti come:

Array
(
    [0] => stdClass Object
        (
            [meta_id] => 1002
            [post_id] => 1
            [meta_key] => my_key
            [meta_value] => my_value
        )
    [1] => stdClass Object
        (
            [meta_id] => 1003
            [post_id] => 668
            [meta_key] => my_key
            [meta_value] => another value
        )
)
8 nov 2013 14:39:57
6

Non sono a conoscenza di una funzione/metodo di WordPress Core per recuperare i meta dei post con la chiave. Questo non significa che non esista definitivamente. Potrebbe esserci. Non so tutto su WordPress, faccio solo finta :) O forse mi è sfuggito in questo momento.

Tuttavia, il quarto parametro di update_post_meta serve a garantire che aggiorni solo il valore che desideri aggiornare nei casi in cui ci sono più chiavi.

$prev_value
(mixed) (opzionale) Il vecchio valore del campo personalizzato che desideri modificare. Questo serve a differenziare tra diversi campi con la stessa chiave. Se omesso, e ci sono più righe per questo post e meta chiave, tutti i valori meta verranno aggiornati.

Inserisci il valore precedentemente salvato in quel quarto parametro e solo quella voce verrà aggiornata.

delete_post_meta funziona in modo simile, ma con il terzo parametro invece del quarto.

20 ago 2013 00:00:08
Commenti

@s_ha_dum come valuti la pertinenza di questa risposta alla domanda? Chi ha posto la domanda necessita di ottenere l'id meta tramite la chiave meta e l'id del post, cosa che la mia funzione restituirà.

Anjum Anjum
20 ago 2013 00:16:54

L'OP afferma: "L'idea di base è che, poiché potrebbero esserci più meta_values per la stessa meta_key, dovrei conoscere il meta_id per aggiornare/eliminare in modo affidabile i post meta." Cioè, il problema/preoccupazione riguarda l'aggiornamento affidabile dei post meta quando ci sono più chiavi. La parte che dice "dovrei conoscere il meta_id per aggiornare/eliminare in modo affidabile i post meta" è errata. Non è necessario e il codice di WordPress Core adotta un approccio diverso al problema.

s_ha_dum s_ha_dum
20 ago 2013 00:25:45

Penso che l'OP abbia un problema XY nella domanda, in altre parole.

s_ha_dum s_ha_dum
20 ago 2013 00:26:22

Arrivo a una conclusione simile nella mia risposta: http://wordpress.stackexchange.com/a/110780/178

hakre hakre
20 ago 2013 00:36:54

Ho effettivamente provato questa soluzione, ma mi sembra un po' strano fare affidamento sul meta value quando si ha a che fare con meta valori serializzati. Speravo ci fosse un modo per ottenere il meta_id insieme ai meta_values, in modo da poter usare update_metadata_by_mid e delete_metadata_by_mid

ragulka ragulka
20 ago 2013 10:21:08

Cosa c'è di strano? Il processo è invisibile dal tuo punto di vista. Il Core fa il lavoro.

s_ha_dum s_ha_dum
20 ago 2013 16:29:55
Mostra i restanti 1 commenti
1

aggiungi questo codice nel tuo functions.php

function get_mid_by_key( $post_id, $meta_key ) {
    global $wpdb;
    $mid = $wpdb->get_var( $wpdb->prepare("SELECT meta_id FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = %s", $post_id, $meta_key) );
    if( $mid != '' )
    return (int) $mid;

    return false;
}

e poi chiamalo dove vuoi in questo modo

$meta_id = get_mid_by_key( your_post_id, 'your_meta_key' );
19 ago 2013 23:57:13
Commenti

Funziona solo quando esiste un'unica istanza di un determinato meta_key. Si interromperà quando ci sono più meta_values con lo stesso meta_key.

ragulka ragulka
20 ago 2013 10:09:49
0

È strano che WordPress fornisca funzioni per ottenere, aggiornare ed eliminare i meta tramite meta_id dalla versione 3.3, ma a partire dalla versione 3.7 non abbia alcuna funzione che restituisca l'id del meta. Quindi, utilizzando le funzioni principali da meta.php come riferimento, ho implementato le seguenti funzioni per poter recuperare sia gli id dei meta che i loro valori.

Soluzione

Utilizza la funzione personalizzata get_post_meta_db() qui sotto per ottenere gli id e i valori delle chiavi meta, poi usa le funzioni di WordPress update_meta() e delete_meta() per manipolare i post meta.

Ad esempio:

$meta = get_post_meta_db( $post_id, 'my_key', true ); // Restituisce array( 
//   'post_id' => 5, 
//   'meta_id' = 33, 
//   'meta_key' => 'my_key', 
//   'meta_value' => 'the_value_for_my_key' );
update_meta( $meta['meta_id'], $meta['meta_key'], 'new_value' );

Ecco le definizioni delle funzioni personalizzate:

/**
 * Alternativa a get_post_meta(), per recuperare i meta_id. @see get_meta_db()
 */
function get_post_meta_db( $post_id, $meta_key = null, $single = false, $meta_val = null, $output = OBJECT ){
    return get_meta_db( 'post', $post_id, $meta_key, $meta_val, $single, $output );
}

/**
 * Alternativa a get_metadata(). Differenze:
 *  - restituisce tutti i campi meta (invece di solo meta_values)
 *  - bypassa i filtri/azioni dei meta
 *  - interroga il database, bypassando la cache
 *  - restituisce i meta_values grezzi (senza unserializzare gli array)
 *
 * @param string $meta_type Tipo di oggetto a cui è associato il metadata (es. comment, post, o user)
 * @param int    $object_id ID dell'oggetto a cui è associato il metadata
 * @param string $meta_key  Opzionale. Chiave del metadata da recuperare. Di default, restituisce tutti i metadata per l'oggetto specificato.
 * @param mixed  $meta_val  Opzionale. Se specificato, restituirà solo le righe con questo meta_value.
 * @param bool   $single    Opzionale. Se true, restituisce una singola riga, altrimenti un array di righe.
 * @param string $output    Opzionale. Una delle costanti ARRAY_A | ARRAY_N | OBJECT | OBJECT_K. @see wpdb::get_results()
 *
 * @return array Singola riga di metadata, array di righe, array vuoto se nessun risultato, o false in caso di errore.
 */
function get_meta_db( $meta_type, $object_id = null, $meta_key = null, $meta_val = null, $single = false, $output = OBJECT ){

    if( !$meta_type || !$table = _get_meta_table( $meta_type ) ) 
        return false;

    // Costruisci la query
    global $wpdb;
    $query = $wpdb->prepare( "SELECT * FROM $table", $object_id );
    // Aggiungi condizioni alla query
    $where = array();
    if( $object_id = absint( $object_id ) )
        $where[] = $wpdb->prepare( sanitize_key( $meta_type.'_id' ).' = %d', $object_id );
    if( !empty($meta_key) )
        $where[] = $wpdb->prepare( 'meta_key = %s', wp_unslash( $meta_key ) );
    if( null !== $meta_val )
        $where[] = $wpdb->prepare( 'meta_value = %s', maybe_serialize(wp_unslash($meta_val)));
    if( !empty($where) )
        $query .= ' WHERE '.implode(' AND ', $where );
    if( $single )
        $query .= ' LIMIT 1';

    $rows = $wpdb->get_results( $query, $output );

    if( empty( $rows ) )
        return ( $single ? null : array() );

    /* 
    Scommenta questa sezione per far sì che la funzione unserializzi i valori (come get_metadata())
    NOTA: Questo può essere implementato più efficientemente usando array_map
    // Unserializza i meta_values serializzati
    foreach( $rows as &$r ){
        $v =& ($output==ARRAY_A ? $r['meta_value'] : $output==ARRAY_N ? $r[3] : $r->meta_value );
        $v = maybe_unserialize( $v );
    } */

    return ( $single ? reset( $rows ) : $rows );
}

Note:

  • Queste funzioni interrogano il database, quindi usale con parsimonia!
  • Questa implementazione segue la convenzione vista in get_metadata_by_mid(), non utilizzando i pre-filtri "get_post_metadata"/"get_user_metadata" e non aggiornando la cache.
  • Nel mio caso, avevo bisogno solo dei dati grezzi, quindi a differenza di get_metadata_by_mid(), questa implementazione non unserializza i valori dei meta.
  • Queste funzioni permettono di selezionare i metadata per post_id/user_id, meta key, meta value, o qualsiasi combinazione di questi.
6 nov 2013 19:47:45
0

L'idea di base è che poiché possono esserci più valori meta_values per la stessa meta_key, dovrei conoscere l'meta_id per poter aggiornare/eliminare in modo affidabile i meta dei post.

Ciò che chiami meta_id qui tecnicamente non esiste in Wordpress. Esiste l'post_id e quello è anche l'id per tutti i meta (nel linguaggio meta questo è l'object_id).

Accanto a ciò c'è la meta_key e come giustamente scrivi, poiché può esserci più di un valore per ogni meta_key sullo stesso object_id, c'è ambiguità perché tutto dipende dall'ordine in cui il database presenta i valori qui - e solo indirettamente, perché i valori meta hanno anche la loro cache, l'object cache.

Quindi anche se puoi vedere un meta_id nel database, non viene ulteriormente utilizzato se non per avere una chiave primaria nel db.

Non fa parte del risultato del database che viene utilizzato all'interno del codice PHP di Wordpress e quindi non fa parte della meta-cache e quindi non arriva mai alle funzioni dell'API meta (perché accedono al database tramite l'API della meta cache).

Il che porta alla conclusione finale:

Poiché parli di meta_id e questo esiste solo nel database (tabella dbprefix_postmeta), la tua domanda può significare solo eliminare/aggiornare una voce in quella tabella. Semplici operazioni SQL normali dovrebbero essere sufficienti.

20 ago 2013 00:33:13
0

La funzione core di WordPress has_meta restituisce array associativi di metadati. Ogni array di metadati contiene il meta_id.

Valore di ritorno

(array[]) Array di array di metadati per l'ID del post specificato.

  • '...$0' (array) Array associativo di metadati.
    • 'meta_key' (string) Chiave del meta.
    • 'meta_value' (mixed) Valore del meta.
    • 'meta_id' (string) ID del meta come stringa numerica.
    • 'post_id' (string) ID del post come stringa numerica.

È possibile aggiornare ed eliminare in modo affidabile i valori dei meta che condividono la stessa chiave utilizzando has_meta insieme a update_metadata_by_mid e delete_metadata_by_mid.

Nell'esempio dell'OP, per aggiornare array('myvalue1', 1002) ed eliminare array('myvalue2', 1003):

$metadata = has_meta( $post_id );

foreach ( $metadata as $item ) {
    // Converti la stringa numerica meta_id in un intero
    $meta_id    = intval( $item[ 'meta_id' ] );
    $meta_key   = $item[ 'meta_key' ];
    $meta_value = $item[ 'meta_value' ];

    if ( $meta_key === 'my_key' && $meta_value === 'myvalue1' ) {
        update_metadata_by_mid( 'post', $meta_id, 'new value' );
    } else if ( $meta_key === 'my_key' && $meta_value === 'myvalue2' ) {
        delete_metadata_by_mid( 'post', $meta_id );
    }
}

Riferimento: has_meta viene utilizzato dal core di WordPress per popolare i campi del form nel pannello Campi Personalizzati.

1 set 2022 20:26:10