Problema con l'archiviazione di array usando update_user_meta
Sto scrivendo una funzione che aggiunge un numero ID a un array e inserisce l'array nei usermeta. $_GET['auction']
è il post_id
.
Ecco la funzione:
$reminders = get_user_meta( $current_user->ID, "reminders" );
print_r( $reminders );
if( in_array( $_GET['auction'], $reminders ) ) {
echo "Errore: Asta già presente nella lista";
} else {
array_push( $reminders, intval( $_GET['auction'] ) );
if ( update_user_meta( $current_user->ID, "reminders", $reminders ) ) {
echo "Successo";
} else {
echo "Errore: Impossibile aggiornare i metadati utente";
}
}
print_r( $reminders );
Ecco l'output dopo aver aggiunto un'asta:
Array ( )
Successo
Array ( [0] => 7 )
Ecco l'output dopo aver aggiunto due aste:
Array ( [0] => Array ( [0] => 7 ) )
Successo
Array ( [0] => Array ( [0] => 7 ) [1] => 73 )
Ecco l'output dopo aver aggiunto tre aste:
Array ( [0] => Array ( [0] => Array ( [0] => 7 ) [1] => 73 ) )
Successo
Array ( [0] => Array ( [0] => Array ( [0] => 7 ) [1] => 73 ) [1] => 0 )
Nota che aggiungere un nuovo elemento all'array usando array_push
funziona correttamente. Ma quando l'array viene archiviato nei usermeta e poi recuperato nuovamente, l'ultimo elemento nell'array viene inserito in un array a sé stante, creando un array a dimensioni infinite. Preferirei mantenere questo array monodimensionale.
Esiste un modo per utilizzare update_user_meta
e get_user_meta
senza che modifichino la struttura del mio array?

Ho avuto lo stesso problema e l'ho risolto con questo piccolo snippet, che inserisce tutti i nuovi valori in un singolo array salvato come metadato dell'utente:
//Dove $access_key è il valore successivo (aggiunto)
$get_access_keys_from_wp = get_user_meta($user_id,'wsm_capability');
$current_access_keys = $get_access_keys_from_wp[0];
$new_access_keys = array();
$new_access_keys[]=$access_key;
foreach($current_access_keys as $key => $value){
$new_access_keys[]=$value;
}
delete_user_meta( $user_id, 'wsm_capability');//Svuota i metadati...
update_user_meta( $user_id, 'wsm_capability', $new_access_keys);
Array prima del salvataggio/aggiornamento per la meta key (da get_user_meta):
Array
(
[0] => access_9
)
Array risultante (dopo l'aggiornamento dei metadati) aggiungendo il valore 'access_5':
Array
(
[0] => access_5
[1] => access_9
)
Se hai bisogno che il nuovo valore venga aggiunto alla fine dell'array, fai invece così:
//Dove $access_key è il valore successivo (aggiunto)
$get_access_keys_from_wp = get_user_meta($user_id,'wsm_capability');
$current_access_keys = $get_access_keys_from_wp[0];
$new_access_keys = array();
foreach($current_access_keys as $key => $value){
$new_access_keys[]=$value;
}
$new_access_keys[]=$access_key;
Poi aggiorna i metadati...
Bryan

Non ho utilizzato la funzione per un bel po' di tempo, ma immagino che il tuo problema sia che stai inserendo un array in un array. Quindi controlla se intval($_GET['auction'])
è un array:
echo '<pre>';
print_r(intval($_GET['auction']));
echo '</pre>';
Modifica #1: Potresti dover ottenere il valore da quell'array e poi inserirlo con array_push. Quindi qualcosa come array_push( $reminders, $_GET['auction'][0]) );
- se stai aggiungendo solo un singolo valore. Potresti anche fare qualcosa come $reminders[] = $_GET['auction'][0];
per aggiungerlo alla fine del tuo array.
Modifica #2: Dando un'occhiata al file core: sì. update_user_meta()
è solo un alias di update_metadata()
che prende l'ID + il valore e lo inserisce nel database come array.
// Da /wp-includes/meta.php ~ riga 135
$where = array( $column => $object_id, 'meta_key' => $meta_key );
if ( !empty( $prev_value ) ) {
$prev_value = maybe_serialize($prev_value);
$where['meta_value'] = $prev_value;
}

Sembrava che il problema fosse con la serializzazione/desserializzazione dell'array, quindi ho semplicemente riscritto la funzione per utilizzare una stringa separata da virgole:
$reminders = get_user_meta($current_user->ID,"reminders",TRUE);
if(is_int(strpos($reminders,$_GET['auction']))) {
echo "Errore: L'asta è già presente nella lista";
} else {
$reminders .= ",".intval($_GET['auction']);
if(substr($reminders,0,1) == ",") { //Rimuove la virgola iniziale se esiste
$reminders = substr($reminders,1,strlen($reminders)-1);
}
if(update_user_meta($current_user->ID,"reminders",$reminders)) {
echo "Successo";
} else {
echo "Errore: Impossibile aggiornare i metadati utente";
}
}

Ciao @Jarred, alla fine hai risolto? Ho un'esigenza simile per il mio sito web. Ho delle opzioni di checkbox nei metadati utente (un array) che devo aggiornare per ogni utente (più di 1500 utenti). E ho bisogno di un modo per aggiornare ogni utente, assegnando loro selezioni diverse, ma su larga scala. La nostra soluzione sembra possa funzionare, ma non sono sicuro di come implementare la scelta di opzioni diverse per ogni singolo utente. Vorrei lavorare con il tuo esempio, ma ho bisogno di aiuto per personalizzarlo in base alla mia necessità, che sarebbe fare selezioni uniche per ogni utente e poi aggiornare.

La risposta di Shaun era corretta ma sento che necessita di maggiori chiarimenti. Puoi inserire un array in una voce di meta utente, ma quando lo recuperi devi comunque recuperarlo con l'argomento single impostato su true altrimenti otterrai un array di array. Ecco il mio codice:
$past_orders = get_user_meta($order_userID, 'qr-replacement-orders', true);
//verifica se questo nuovo ordine è già stato processato
if(in_array($_GET["oid"], $past_orders))
{
echo '<p>Questo ordine è già stato processato.</p>';
//debug
//var_dump($past_orders);
}
else
{
//aggiungi il numero dell'ordine all'array degli ordini passati e memorizzalo
//se la lista è vuota, inizializzala come array vuoto
if($past_orders == '')
{
$past_orders = array();
}
//aggiungi il nuovo ordine alla lista
array_push($past_orders, $_GET["oid"]);
//aggiungi la nuova lista al DB
update_user_meta($order_userID, 'qr-replacement-orders', $past_orders);
echo '<p>La tua carta è stata acquistata e ti verrà inviata via posta. Grazie!</p>';
//debug: conferma che ha funzionato
//$past_orders = get_user_meta($order_userID, 'qr-replacement-orders', true);
//var_dump($past_orders);
}
