Make WordPress Core


Ignore:
Timestamp:
05/26/2015 04:50:03 PM (10 years ago)
Author:
westonruter
Message:

Add support for WP_Widget::get_settings() returning ArrayIterator/ArrayObject instances.

Plugins can use pre_option_widget_{$id_base} filters to return ArrayIterator/ArrayObject instances instead of primitive arrays. This makes possible for widget instance data to be drawn from somewhere else than wp_options, such as a custom post type.

Add unit tests for widgets.

Fixes #32474.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/widgets.php

    r32545 r32602  
    215215        $empty = true;
    216216
    217         if ( is_array($settings) ) {
    218             foreach ( array_keys($settings) as $number ) {
    219                 if ( is_numeric($number) ) {
    220                     $this->_set($number);
    221                     $this->_register_one($number);
     217        // When $settings is an array-like object, get an intrinsic array for use with array_keys().
     218        if ( $settings instanceof ArrayObject || $settings instanceof ArrayIterator ) {
     219            $settings = $settings->getArrayCopy();
     220        }
     221
     222        if ( is_array( $settings ) ) {
     223            foreach ( array_keys( $settings ) as $number ) {
     224                if ( is_numeric( $number ) ) {
     225                    $this->_set( $number );
     226                    $this->_register_one( $number );
    222227                    $empty = false;
    223228                }
     
    226231
    227232        if ( $empty ) {
    228             // If there are none, we register the widget's existence with a
    229             // generic template
    230             $this->_set(1);
     233            // If there are none, we register the widget's existence with a generic template.
     234            $this->_set( 1 );
    231235            $this->_register_one();
    232236        }
     
    295299     */
    296300    public function display_callback( $args, $widget_args = 1 ) {
    297         if ( is_numeric($widget_args) )
     301        if ( is_numeric( $widget_args ) ) {
    298302            $widget_args = array( 'number' => $widget_args );
     303        }
    299304
    300305        $widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) );
    301306        $this->_set( $widget_args['number'] );
    302         $instance = $this->get_settings();
    303 
    304         if ( array_key_exists( $this->number, $instance ) ) {
    305             $instance = $instance[$this->number];
     307        $instances = $this->get_settings();
     308
     309        if ( isset( $instances[ $this->number ] ) ) {
     310            $instance = $instances[ $this->number ];
    306311
    307312            /**
     
    425430     *
    426431     * @param int|array $widget_args Widget instance number or array of widget arguments.
     432     * @return string|null
    427433     */
    428434    public function form_callback( $widget_args = 1 ) {
     
    517523    public function get_settings() {
    518524
    519         $settings = get_option($this->option_name);
    520 
    521         if ( false === $settings && isset($this->alt_option_name) )
    522             $settings = get_option($this->alt_option_name);
    523 
    524         if ( !is_array($settings) )
     525        $settings = get_option( $this->option_name );
     526
     527        if ( false === $settings && isset( $this->alt_option_name ) ) {
     528            $settings = get_option( $this->alt_option_name );
     529        }
     530
     531        if ( ! is_array( $settings ) && ! ( $settings instanceof ArrayObject || $settings instanceof ArrayIterator ) ) {
    525532            $settings = array();
    526 
    527         if ( !empty($settings) && !array_key_exists('_multiwidget', $settings) ) {
    528             // old format, convert if single widget
    529             $settings = wp_convert_widget_settings($this->id_base, $this->option_name, $settings);
    530         }
    531 
    532         unset($settings['_multiwidget'], $settings['__i__']);
     533        }
     534
     535        if ( ! empty( $settings ) && ! isset( $settings['_multiwidget'] ) ) {
     536            // Old format, convert if single widget.
     537            $settings = wp_convert_widget_settings( $this->id_base, $this->option_name, $settings );
     538        }
     539
     540        unset( $settings['_multiwidget'], $settings['__i__'] );
    533541        return $settings;
    534542    }
Note: See TracChangeset for help on using the changeset viewer.