web-dev-qa-db-fra.com

Comment stocker les données de champs de widgets sous forme de tableau?

Je crée un widget, il doit stocker environ 10 identifiants. En ce moment, j'utilise la méthode de champ suivant pour stocker chaque ID dans un champ séparé. Il stocke les données de chaque champ séparément dans le wordpress. Est-il possible de stocker les données de tous les champs sur une seule ligne dans wordpress, par exemple, à l'aide d'un tableau?

<input 
    class="widefat" 
    id="<?php echo $this->get_field_id('item1_id'); ?>" 
    name="<?php echo $this->get_field_name('item1_id'); ?>" 
    value="<?php echo $instance['item1_id']; ?>" 
    />

<input 
    class="widefat" 
    id="<?php echo $this->get_field_id('item2_id'); ?>" 
    name="<?php echo $this->get_field_name('item2_id'); ?>" 
    value="<?php echo $instance['item2_id']; ?>" 
    />
11
jay

Vous devez collecter plusieurs champs sous le même nom, comme ceci…

name="collect[1]"
name="collect[2]"

… Et ajustez la logique de votre widget à cela.

Voici un widget de démonstration très simple:

<?php  # -*- coding: utf-8 -*-
/* Plugin Name: Store Options as array */

add_action( 'widgets_init', array ( 'T5_Array_Options_Widget', 'register' ) );

class T5_Array_Options_Widget extends WP_Widget
{
    /**
     * Constructor.
     */
    public function __construct()
    {
        parent::__construct( strtolower( __CLASS__ ), 'Array Demo' );
    }

    /**
     * Echo the settings update form
     *
     * @param array $instance Current settings
     */
    public function form( $instance )
    {
        $title = isset ( $instance['title'] ) ? $instance['title'] : '';
        $title = esc_attr( $title );

        printf(
            '<p><label for="%1$s">%2$s</label><br />
            <input type="text" name="%3$s" id="%1$s" value="%4$s" class="widefat"></p>',
            $this->get_field_id( 'title' ),
            'Title',
            $this->get_field_name( 'title' ),
            $title
        );

        $fields = isset ( $instance['fields'] ) ? $instance['fields'] : array();
        $field_num = count( $fields );
        $fields[ $field_num + 1 ] = '';
        $fields_html = array();
        $fields_counter = 0;

        foreach ( $fields as $name => $value )
        {
            $fields_html[] = sprintf(
                '<input type="text" name="%1$s[%2$s]" value="%3$s" class="widefat">',
                $this->get_field_name( 'fields' ),
                $fields_counter,
                esc_attr( $value )
            );
            $fields_counter += 1;
        }

        print 'Fields<br />' . join( '<br />', $fields_html );
    }

    /**
     * Renders the output.
     *
     * @see WP_Widget::widget()
     */
    public function widget( $args, $instance )
    {
        print $args['before_widget']
        . $args['before_title']
        . apply_filters( 'widget_title', $instance['title'] )
        . $args['after_title']
        . join( '<br />', $instance['fields'] )
        . $args['after_widget'];
    }

    /**
     * Prepares the content. Not.
     *
     * @param  array $new_instance New content
     * @param  array $old_instance Old content
     * @return array New content
     */
    public function update( $new_instance, $old_instance )
    {
        $instance          = $old_instance;
        $instance['title'] = esc_html( $new_instance['title'] );

        $instance['fields'] = array();

        if ( isset ( $new_instance['fields'] ) )
        {
            foreach ( $new_instance['fields'] as $value )
            {
                if ( '' !== trim( $value ) )
                    $instance['fields'][] = $value;
            }
        }

        return $instance;
    }

    /**
     * Tell WP we want to use this widget.
     *
     * @wp-hook widgets_init
     * @return void
     */
    public static function register()
    {
        register_widget( __CLASS__ );
    }
}

Backend

enter image description here

L'extrémité avant

enter image description here

9
fuxia

La réponse ci-dessus est bonne si vous avez besoin que les champs soient numérotés. Dans mon cas, je ne l'ai pas fait. J'ai un widget avec des options qui permettent à l'utilisateur de sélectionner un nombre quelconque de catégories à utiliser dans le widget.

 widget 

Voici mon widget form. - Trois choses importantes ici

  1. Assurez-vous de définir par défaut la valeur sur array() vide si la valeur du widget n'est pas définie.
  2. Dans l'attribut <label>name, notez que je joins un [] à la fin. Ceci indique à PHP que je soumets un tableau de valeurs pour cette clé
  3. Enveloppez la case à cocher dans l'étiquette comme <label><input type="checkbox" ...></label>. - Chacune de nos cases à cocher n'aura pas d'attribut id unique, donc l'attribut <label>for ne fonctionnera pas. Nous pourrions générer des identifiants uniques, mais c'est un problème. Si vous venez d’envelopper l’étiquette around l’entrée, l’étiquette sera associée correctement sans la contrainte de connecter la variable for + id

Maintenant le code

public function form($instance) {
  $title = isset($instance['title']) ? $instance['title'] : '';
  $categories = isset($instance['categories']) ? $instance['categories'] : array();
  ?>

  <p>
    <label for="<?php echo $this->get_field_id('title') ?>">
      <?php _e( 'Title:' ) ?>
    </label>
    <input class="widefat"
           id="<?php echo $this->get_field_id('title') ?>"
           name="<?php echo $this->get_field_name('title') ?>"
           value="<?php echo $title ?>" />
  </p>

  <p>Categories</p>
  <ul>
  <?php foreach (\get_categories() as $category): ?>
    <li>
      <label>
        <input type="checkbox"
             class="checkbox"
             name="<?php echo $this->get_field_name('categories') ?>[]"
             value="<?php echo $category->cat_ID ?>"
             <?php checked(in_array($category->cat_ID, $categories)) ?> />
        <?php echo $category->name ?>
      </label>
    </li>
  <?php endforeach ?>
  </ul>
  <?php
}

Et voici ma fonction de mise à jour

Je souhaite enregistrer les ID de catégorie dans un tableau, qui sont des nombres. J'utilise donc array_map avec intval pour m'assurer que tous les points de données soumis sont des entiers valides. De plus, j'utilise array_filter pour supprimer toute soumission invalide.

// @param array $a - the new instance options
// @param arram $b - the old instance options
public function update($a, $b) {
  return array(
    'title'      => isset($a['title']) ? strip_tags($a['title']) : $b['title'],
    'categories' => isset($a['categories']) ? array_filter(array_map(function($id) { return intval($id); }, (array) $a['categories'])) : (array) $b['title']
  );
}

C'est particulièrement difficile de décrire ce genre de choses sur WordPress. Si vous avez des questions, je me ferai un plaisir de vous donner plus de précisions.

4
user633183