Problema al guardar el valor del campo Select2 en el backend de WooCommerce

6 minutos de lectura

avatar de usuario
Vladímir Kyatipov

Estoy usando un código para inicializar un campo select2 en WooCommerce Backend. El campo de selección funciona bien, pero tengo problemas después de guardar el producto.

No puedo obtener el valor de db y ser preseleccionado. Tampoco se puede guardar así.

¿Alguien puede dar un consejo con esto? ¿Deberían guardarse los datos como una matriz?

Mi código:

function woocommerce_wp_product_select2( $field ) {
    global $thepostid, $post, $woocommerce;
    $thepostid              = empty( $thepostid ) ? $post->ID : $thepostid;
    $field['class']         = isset( $field['class'] ) ? $field['class'] : 'select short';
    $field['wrapper_class'] = isset( $field['wrapper_class'] ) ? $field['wrapper_class'] : '';
    $field['name']          = isset( $field['name'] ) ? $field['name'] : $field['id'];
    echo '<p class="form-field ' . esc_attr( $field['id'] ) . '_field ' . esc_attr( $field['wrapper_class'] ) . '"><label for="' . esc_attr( $field['id'] ) . '">' . wp_kses_post( $field['label'] ) . '</label><select id="' . esc_attr( $field['id'] ) . '" name="' . esc_attr( $field['name'] ) . '" class="wc-product-search ' . esc_attr( $field['class'] ) . '" multiple="multiple" data-maximum-selection-length="1">';
    foreach ( $field['value'][0] as $key => $value ) {
        echo '<option value="'.$value.'" selected="selected">'.wc_get_product( $value )->name.' (#'.$value.')</option>';
    }
    echo '</select> ';
    if ( ! empty( $field['description'] ) ) {
        if ( isset( $field['desc_tip'] ) && false !== $field['desc_tip'] ) {
            echo '<span class="woocommerce-help-tip" data-tip="' . esc_attr( $field['description'] ) . '"></span>';
        } else {
          echo '<span class="description">' . wp_kses_post( $field['description'] ) . '</span>';
        }
    }
    echo '</p>';
}

add_filter( 'woocommerce_product_data_tabs', 'kyatipov_promo_tab', 10, 1 );
function kyatipov_promo_tab($default_tabs) {

    $default_tabs['promo'] = array(
        'label'   =>  __( 'Промоция', 'domain' ),
        'target'  =>  'kyatipov_promo_tab_content',
        'priority' => 60,
        'class'   => array('promo-tab-produkti')
    );
    return $default_tabs;
}

add_action( 'woocommerce_product_data_panels', 'kyatipov_promo_tab_content' );
function kyatipov_promo_tab_content() {
    global $woocommerce, $post;
    ?>
    <div id="kyatipov_promo_tab_content" class="panel woocommerce_options_panel">
        
     <style>
        #woocommerce-product-data ul li.promo_options.promo_tab.promo-tab-produkti a::before {
            font-family: Dashicons;
            content: "\f198";
        }
         h4#ízbran-produkt, h4#iztrii-izbran-prod {
             margin-left: 12px;
         }
         .iztrii-container {
             display: flex;
         }
         h4#iztrii-izbran-prod::after {
             font-family: Dashicons;
             content: "\f182";
             color: red;
             font-size: 26px;
         }
         h4#iztrii-izbran-prod {
             margin-top: 0;
         }
         h4#iztrii-izbran-prod:hover {
             cursor: -webkit-grabbing; cursor: grabbing;
         }
         select#wc_product_ids + span.select2 {
             width: 350px !IMPORTANT;
         }
    </style>
 
    <?php
    woocommerce_wp_checkbox( array( 
        'id'            => '_enable_promo_for_current_product', 
        //'wrapper_class' => 'show_if_simple', 
        'label'         => __( 'Включи промо', 'woocommerce' ),
        'description'   => __( 'Тази опция е задължителна, ако желаете да ползвате промо фу-ота за този продукт!', 'my_text_domain' ),
        'default'       => '0',
        'desc_tip'      => true,
    ) );    
    
    
    $save_data = get_post_meta( $post->ID, 'wc_product_ids' );
    echo $save_data;
    print_r($save_data);

    woocommerce_wp_product_select2([
        'id'      => 'wc_product_ids',
        'label'   => __( 'Продукт', 'woocommerce' ),
        'class' => '',
        'name' => 'wc_product_ids[]',
        'value'   => $save_data,
        'desc_tip' => true,
        'description' => __( 'Избери продукт за промоция', 'wc' ),
    ]);
    
    echo '</div>';
}

// Save Meta
add_action('woocommerce_process_product_meta', 'kyatipov_custom_field_save');
function kyatipov_custom_field_save( $post_id ){
        
    // Select
    $izbran_promo_prod = $_POST['wc_product_ids'];
    if( !empty( $izbran_promo_prod ) )
        update_post_meta( $post_id, 'wc_product_ids', esc_attr( $izbran_promo_prod ) );
    
    $izbran_promo_prod2 = $_POST['save_data'];
    if( !empty( $izbran_promo_prod2 ) )
        update_post_meta( $post_id, 'save_data', esc_attr( $izbran_promo_prod2 ) );
    
}

En primer lugar, modifiqué el woocommerce_wp_product_select2() función que está utilizando:

  • he añadido $field['placeholder'] a la función, de modo que se pueda usar un marcador de posición si se desea
  • data-exclude="<?php echo $thepostid; ?>" se ha agregado para que el producto actual no se pueda seleccionar
  • $field['value'] = ! empty( $field['value'] ) ? $field['value'] : array(); también se agregó a la función, para evitar un mensaje de error cuando los metadatos no existen/aún no existen

Cuando se trata de ahorrar, estás cometiendo el error de que esc_attr() se usa con una matriz, mientras que espera una cadena

ps para guardar campos puedes usar el woocommerce_admin_process_product_object gancho, frente al anticuado woocommerce_process_product_meta gancho

Entonces obtienes:

function woocommerce_wp_product_select2( $field ) {
    global $thepostid, $post;

    $thepostid              = empty( $thepostid ) ? $post->ID : $thepostid;
    $field['placeholder']   = isset( $field['placeholder'] ) ? $field['placeholder'] : '';
    $field['class']         = isset( $field['class'] ) ? $field['class'] : 'select short';
    $field['wrapper_class'] = isset( $field['wrapper_class'] ) ? $field['wrapper_class'] : '';
    $field['value']         = ! empty( $field['value'] ) ? $field['value'] : array();
    $field['name']          = isset( $field['name'] ) ? $field['name'] : $field['id'];

    echo '<p class="form-field ' . esc_attr( $field['id'] ) . '_field ' . esc_attr( $field['wrapper_class'] ) . '"><label for="' . esc_attr( $field['id'] ) . '">' . wp_kses_post( $field['label'] ) . '</label><select id="' . esc_attr( $field['id'] ) . '" name="' . esc_attr( $field['name'] ) . '" class="wc-product-search ' . esc_attr( $field['class'] ) . '" multiple="multiple" style="width: 50%;" data-maximum-selection-length="1" data-placeholder="' . esc_attr( $field['placeholder'] ) . '" data-exclude="<?php echo $thepostid; ?>" >';

    foreach ( $field['value'] as $key => $value ) {
        $product = wc_get_product( $value );
        if ( is_object( $product ) ) {
            echo '<option value="' . esc_attr( $value ) . '"' . selected( true, true, false ) . '>' . esc_html( wp_strip_all_tags( $product->get_formatted_name() ) ) . '</option>';
        }
    }

    echo '</select> ';

    if ( ! empty( $field['description'] ) ) {
        if ( isset( $field['desc_tip'] ) && false !== $field['desc_tip'] ) {
            echo '<span class="woocommerce-help-tip" data-tip="' . esc_attr( $field['description'] ) . '"></span>';
        } else {
          echo '<span class="description">' . wp_kses_post( $field['description'] ) . '</span>';
        }
    }

    echo '</p>';
}

function filter_woocommerce_product_data_tabs( $default_tabs ) {
    $default_tabs['promo'] = array(
        'label'     =>  __( 'Промоция', 'domain' ),
        'target'    =>  'kyatipov_promo_tab_content',
        'priority'  => 60,
        'class'     => array( 'promo-tab-produkti' )
    );

    return $default_tabs;
}
add_filter( 'woocommerce_product_data_tabs', 'filter_woocommerce_product_data_tabs', 10, 1 );

function action_woocommerce_product_data_panels() {
    global $post;

    echo '<div id="kyatipov_promo_tab_content" class="panel woocommerce_options_panel">';
    
    // Get data
    $data = get_post_meta( $post->ID, '_wc_product_ids', true );

    // Add field via custom function
    woocommerce_wp_product_select2(
        array(
            'id'            => 'wc_product_ids',
            'label'         => __( 'Продукт', 'woocommerce' ),
            'placeholder'   => __( 'My placeholder', 'woocommerce' ),
            'class'         => '',
            'name'          => 'wc_product_ids[]',
            'value'         => $data,
            'desc_tip'      => true,
            'description'   => __( 'Избери продукт за промоция', 'woocommerce' ),
        )
    );
    
    echo '</div>';
}
add_action( 'woocommerce_product_data_panels', 'action_woocommerce_product_data_panels' );

// Save
function action_woocommerce_admin_process_product_object( $product ) {
    // Good idea to make sure things are set before using them
    $data = isset( $_POST['wc_product_ids'] ) ? (array) $_POST['wc_product_ids'] : array();

    // Update
    $product->update_meta_data( '_wc_product_ids', array_map( 'esc_attr', $data ) );
}
add_action( 'woocommerce_admin_process_product_object', 'action_woocommerce_admin_process_product_object', 10, 1 );

Relacionado: agregue un campo de búsqueda select2 personalizado en el metabox de datos del producto WooCommerce

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad