Como atualizar o valor de um array

3

Eu criei um novo campo personalizado nos meus itens de menu de navegação como várias opções de seleção que usei update_post_meta() como abaixo

function YPE_update_custom_fields($menu_id, $menu_item_db_id, $menu_item_data) {
    if (is_array($_REQUEST['menu-item-content-multiple'])) {
        update_post_meta($menu_item_db_id, '_menu_item_content_multiple', $_REQUEST['menu-item-content-multiple'][$menu_item_db_id]);
    }
}
add_action('wp_update_nav_menu_item', 'YPE_update_custom_fields', 10, 3);

function YPE_setup_custom_fields($item) {
    $item->content_multiple = get_post_meta($item->ID, '_menu_item_content_multiple', true);
    return $item;
}
add_filter('wp_setup_nav_menu_item', 'YPE_setup_custom_fields');

Em seguida, adiciono novo campo no arquivo Walker_Nav_Menu_Edit como abaixo

EDITADO

<?php
$select_options = array (
    'key_1' => 'option1', 
    'key_2' => 'option2', 
    'key_3' => 'option3'
); 
?>
<p class="field-content-multiple description description-thin">
<label for="edit-menu-item-content-multiple-<?php echo $item_id; ?>">
    <?php _e( 'Multiple Content' ); ?><br />
    <select name="menu-item-content-multiple[<?php echo $item_id; ?>][]" id="edit-menu-item-content-multiple-<?php echo $item_id; ?>" class="widefat code edit-menu-item-content-multiple" multiple="multiple">
            <?php foreach ($select_options as $key => $value): ?>
                <option value="<?php echo $key; ?>"  <?php echo selected(in_array($key, $item->content_multiple)); ?>><?php echo $value;?></option>
            <?php endforeach ?>
    </select>
</label>
</p>

Meu código funciona com a caixa de seleção única sem nenhum problema, mas quando eu uso in_array() em vários casos de seleção, retorne esse erro

Warning: in_array() expects parameter 2 to be array, null given
    
por Shwan Namiq 19.10.2016 / 11:00

2 respostas

8

Você faz isso:

$item->content_multiple = get_post_meta($item->ID, '_menu_item_content_multiple', true);

Observe como você define o terceiro parâmetro de get_post_meta() para true , o que significa que apenas um valor será retornado. Se você ler os documentos , verá que, se o terceiro parâmetro for false , você receberá uma matriz com todos os valores para esse campo meta.

Lembre-se de que os meta campos podem ser únicos ou múltiplos. Ou pode ser exclusivo com uma string de dados serializada.

Como está, seu código parece armazenar todos os valores do select em um único campo meta. Assim, você obtém uma matriz na solicitação e a transmite como valor único do campo meta. Quando o valor de um campo meta é uma matriz, o WordPress converte-o para uma string serializada antes de ser armazenado no banco de dados ; isso é feito internamente com a função maybe_serialize() . Então, quando você tenta obter o valor do meta-campo, se for uma string serializada, o WordPress passa-o através de maybe_unserialize() , então a string serializada é convertida de volta para a matriz:

Vamos explicar com um exemplo genérico.

Esta será a matriz de valores a serem armazenados no banco de dados:

$values = [ 'red', 'yellow', 'blue', 'pink' ];

Se a sua meta-chave é "cor", você tem duas opções:

Múltiplas entradas para a mesma meta key

$values = [ 'red', 'yellow', 'blue', 'pink' ];
foreach( $values as $value ) {
    // This method uses 'add_post_meta()' instead of 'update_post_meta()'
    add_post_meta( $item_id, 'color', $value );
}

Agora, o item identificado com $item_id terá várias entradas para a chave meta color . Em seguida, você pode usar get_post_meta() com o terceiro parâmetro definido como false e você receberá uma matriz com todos os valores:

// You don't really need the set the third parameter
// because it is false vay default
$colors = get_post_meta( $item_id, 'color' );

// $colors should an array with all the meta values for the color meta key
var_dump( $colors );

Armazene o array em uma única meta entrada

Nesse caso, a matriz de valores é serializada antes de ser gravada no banco de dados:

$values = [ 'red', 'yellow', 'blue', 'pink' ];
// WordPress does this automatically when an array is passed as meta value
// $values = maybe_serialize( $values );
update_post_meta( $item_id, 'color', $values );

Agora, o item identificado com $item_id terá apenas uma entrada para a chave meta color ; o valor é uma string serializada que representa a matriz original. Em seguida, você pode usar get_post_meta() , com o terceiro parâmetro definido como true, pois você tem apenas uma entrada e, em seguida, desserializa a string para recuperar a matriz:

$colors = get_post_meta( $item_id, 'color', true );
// WordPress does this automatically when the meta value is a serialized array
// $colors = maybe_unserialize( $colors );

// $colors should be an array
var_dump( $colors );

Você pode seguir a mesma abordagem com o múltiplo selecionado do seu formulário.

Com apenas uma entrada para a chave meta:

if( ! empty( $_REQUEST['menu-item-content-multiple'][$menu_item_db_id] ) ) {
    $meta_field_value = $_REQUEST['menu-item-content-multiple'][$menu_item_db_id];
    // $meta_field_value will be serialized automatically by WordPress
    update_post_meta( $menu_item_db_id, '_menu_item_content_multiple', $meta_field_value );
}

Depois, você pode usar o valor como array:

 // The value returned by get_post_meta() is unserialized automatically by WordPress
 $item->content_multiple = get_post_meta( $item->ID, '_menu_item_content_multiple', true );

Com várias entradas:

O conceito aqui é um pouco diferente; você terá várias entradas no banco de dados com a mesma meta key, então você precisa usar add_post_meta() em vez de update_post_meta() para adicionar uma nova entrada para cada valor.

if( ! empty( $_REQUEST['menu-item-content-multiple'][$menu_item_db_id] ) ) {
    $values = $_REQUEST[ 'menu-item-content-multiple' . $menu_item_db_id ];
    foreach( $values as $value ) {
        add_post_meta( $menu_item_db_id, '_menu_item_content_multiple', $value );
    }
}

Agora, você pode usar get_post_meta() com o terceiro parâmetro definido como false (é o valor padrão, portanto você pode omiti-lo):

$item->content_multiple = get_post_meta( $item->ID, '_menu_item_content_multiple', false );

Ambas as opções são aceitáveis, você deve decidir qual delas é melhor para organizar os dados dentro do seu projeto.

Nota lateral : você deve fazer alguma santização antes de usar os dados de entrada, mas eu não sei os requisitos para você, aqui um exemplo:

array_map( 'sanitize_text_field', wp_unslash( $_REQUEST['menu-item-content-multiple'][$menu_item_db_id] ) );
    
por cybmeta 19.10.2016 / 12:01
0

Você não usa a função selected() corretamente. selected() precisa de 1 parâmetros obrigatórios e 2 opções. No seu caso, é melhor usar $ selecionado e $ atual.

Você perdeu o sublinhado antes do seu nome de meta-campo no nome de seleção.

Para selecionado ():

selected( $selected, $current, $echo);

você pode ler mais sobre isso na referência de função do códice selecionada ()

Sua seleção deve ser assim:

<select name="_menu-item-content-multiple[]" multiple>
     <?php 
        foreach ($select_options as $key => $value) {
            echo '<option value="'.$key.'" '.selected(in_array($key, $item->content_multiple), $key).'>'.$value.'</option>';
        }
     ?>
</select>
    
por Benoti 19.10.2016 / 11:12