Làm thế nào để lưu trữ dữ liệu trường widget dưới dạng một mảng?


11

Tôi đang tạo một widget, nó cần lưu trữ khoảng 10 ID. Hiện tại tôi đang sử dụng phương pháp trường sau để lưu trữ từng ID trong một trường riêng biệt. Nó lưu trữ dữ liệu của từng trường trong một wordpress riêng biệt. Có thể lưu trữ dữ liệu của tất cả các trường chỉ trong một hàng trong wordpress cho kỳ thi bằng cách sử dụng một mảng không?

<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']; ?>" 
    />

1
$instance một mảng và chứa tất cả các giá trị. Và ý bạn là gì khi 'lưu trữ dữ liệu của tất cả các trường chỉ trong một hàng'? Ý của bạn là một hàng cơ sở dữ liệu?
Ralf912

Câu trả lời:


8

Bạn phải thu thập nhiều lĩnh vực dưới cùng một tên như thế này

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

Liên kết và điều chỉnh logic widget của bạn để này.

Đây là một tiện ích demo rất đơn giản:

<?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__ );
    }
}

Cuối tuần

nhập mô tả hình ảnh ở đây

Frontend

nhập mô tả hình ảnh ở đây


+1 printfCú pháp rất tao nhã

Câu trả lời tuyệt vời trên nhiều lĩnh vực, nhưng có thể một số cập nhật về việc có 2 trường liên tiếp không? Tôi đang cố gắng sử dụng điều này trên widget của mình nhưng tôi cần phải có 2 trường liên tiếp như giá / đích, nhưng tôi không thể tìm ra cách để có được nó, tôi luôn gặp một số lỗi.
Aleksandar Đorđević

@ AleksandarĐorđević Chỉ cần viết HTML cho điều đó và không sử dụng class="widefat"cho các trường.
fuxia

Nếu tôi chỉ thông minh như bạn nghĩ. Tôi hiểu rằng tôi phải có được nó để lưu trong cơ sở dữ liệu dưới dạng trường [0] [price] và trường [0] [đích], v.v. nhưng bằng cách nào đó tôi không làm cho nó được thực hiện đúng.
Aleksandar Đorđević

Có thể foo là một mảng có các cặp khóa / giá trị?
worldwildwebdev

5

Câu trả lời trên là tốt nếu bạn cần các trường được đánh số. Trong trường hợp của tôi, tôi đã không. Tôi có một tiện ích với các tùy chọn cho phép người dùng chọn bất kỳ số lượng danh mục sẽ được sử dụng trong tiện ích.

phụ tùng

Đây là widget của tôi form. - Ba điều quan trọng ở đây

  1. Đảm bảo mặc định giá trị thành trống array()nếu giá trị của widget không được đặt
  2. Trong <label> namethuộc tính biểu mẫu , lưu ý rằng tôi đính kèm []ở cuối. Điều này nói với PHP rằng tôi đang gửi một loạt các giá trị cho khóa này
  3. Bọc hộp kiểm trong nhãn như <label><input type="checkbox" ...></label>. - Mỗi hộp kiểm của chúng tôi sẽ không có idthuộc tính duy nhất , vì vậy <label> forthuộc tính sẽ không hoạt động. Chúng tôi có thể tạo ID duy nhất, nhưng đó là một rắc rối. Nếu bạn chỉ bọc nhãn xung quanh đầu vào, nhãn sẽ được liên kết chính xác mà không gặp rắc rối khi kết nối for+id

Bây giờ mã

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
}

Và đây là chức năng cập nhật của tôi

Tôi đang quan tâm đến việc tiết kiệm các ID loại trong một mảng, mà là những con số, vì vậy tôi sử dụng array_mapvới intvalđể đảm bảo rằng tất cả các dữ kiện nộp là các số nguyên có giá trị. Ngoài ra, tôi sử dụng array_filterđể loại bỏ bất kỳ đệ trình không hợp lệ.

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

Thật khó để mô tả công cụ WordPress này. Nếu bạn có bất kỳ câu hỏi nào, tôi sẽ vui lòng giải thích.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.