Wie speichere ich Widgetfelddaten als Array?

11

Ich erstelle ein Widget, es muss ungefähr 10 IDs speichern. Im Moment verwende ich die folgende Feldmethode, um jede ID in einem separaten Feld zu speichern. Es speichert Daten von jedem Feld in einem separaten im WordPress. Ist es möglich, die Daten aller Felder in nur einer Zeile in WordPress zum Beispiel mithilfe eines Arrays zu speichern?

<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']; ?>" 
    />
Jay
quelle
1
$instance ist ein Array und enthält alle Werte. Und was meinen Sie mit "Speichern der Daten aller Felder in nur einer Zeile"? Meinten Sie eine Datenbankzeile?
Ralf912

Antworten:

8

Sie müssen mehrere Felder unter demselben Namen wie folgt sammeln ...

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

… Und passen Sie Ihre Widget-Logik daran an.

Hier ist ein sehr einfaches Demo-Widget:

<?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

Geben Sie hier die Bildbeschreibung ein

Vorderes Ende

Geben Sie hier die Bildbeschreibung ein

Fuxia
quelle
+1 Sehr elegante printfSyntax
Gute Antwort auf mehrere Felder, aber ist es möglich, dass zwei Felder hintereinander aktualisiert werden? Ich versuche, dies auf meinem Widget zu verwenden, aber ich muss 2 Felder in einer Reihe wie Preis / Ziel haben, aber ich kann nicht herausfinden, wie ich es bekomme, ich bekomme immer eine Art Fehler.
Aleksandar Đorđević
@ AleksandarĐorđević Schreibe einfach den HTML-Code dafür und verwende ihn nicht class="widefat"für die Felder.
Fuxia
Wenn ich nur schlau bin, wie du denkst. Ich verstehe, dass ich es in Feld als Feld [0] [Preis] und Feld [0] [Ziel] und so weiter in der Datenbank speichern soll? aber irgendwie verstehe ich es nicht richtig.
Aleksandar Đorđević
Ist es möglich, dass foo ein Array mit Schlüssel / Wert-Paaren ist?
worldwildwebdev
5

Die obige Antwort ist gut, wenn die Felder nummeriert werden müssen. In meinem Fall habe ich nicht. Ich habe ein Widget mit Optionen, mit denen der Benutzer eine beliebige Anzahl von Kategorien auswählen kann, die innerhalb des Widgets verwendet werden sollen.

Widget

Hier ist mein Widget form. - Drei wichtige Dinge hier

  1. Stellen Sie sicher, dass der Wert standardmäßig leer ist, array()wenn der Wert des Widgets nicht festgelegt ist
  2. Beachten Sie im Formularattribut <label> name, dass ich []am Ende ein anhänge. Dies teilt PHP mit, dass ich ein Array von Werten für diesen Schlüssel sende
  3. Wickeln Sie das Kontrollkästchen in das Etikett ein als <label><input type="checkbox" ...></label>. - Jedes unserer Kontrollkästchen hat kein eindeutiges idAttribut, daher <label> forfunktioniert das Attribut nicht. Wir könnten eindeutige IDs generieren, aber das ist ein Ärger. Wenn Sie das Etikett nur um die Eingabe wickeln , wird das Etikett ordnungsgemäß zugeordnet, ohne dass das for+ mühsam angeschlossen werden mussid

Nun der 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
}

Und hier ist meine Update-Funktion

Ich bin in die Rettung der Kategorie IDs in einem Array interessiert, die Zahlen sind, so dass ich array_mapmit , intvalum sicherzustellen , dass alle eingereichten Datum gültig ganze Zahlen sind. Außerdem array_filterentferne ich ungültige Einsendungen.

// @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']
  );
}

Es ist besonders schwierig, dieses WordPress-Zeug zu beschreiben. Wenn Sie Fragen haben, werde ich gerne näher darauf eingehen.


quelle