Make WordPress Core


Ignore:
Timestamp:
02/08/2015 11:10:05 PM (10 years ago)
Author:
ocean90
Message:

Customizer: Introduce an API to create WP_Customize_Settings for dynamically-created settings.

  • Introduce WP_Customize_Manager::add_dynamic_settings() to register dynamically-created settings.
  • Introduce customize_dynamic_setting_args filter to pass an array of args to a dynamic setting's constructor.
  • Add unit tests for WP_Customize_Manager and WP_Customize_Widgets.
  • See WP_Customize_Widgets as an example.

props westonruter.
fixes #30936.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-customize-manager.php

    r31360 r31370  
    6666     * Unsanitized values for Customize Settings parsed from $_POST['customized'].
    6767     *
    68      * @var array|false
     68     * @var array
    6969     */
    7070    private $_post_values;
     
    103103
    104104        add_action( 'customize_register',                 array( $this, 'register_controls' ) );
     105        add_action( 'customize_register',                 array( $this, 'register_dynamic_settings' ), 11 ); // allow code to create settings first
    105106        add_action( 'customize_controls_init',            array( $this, 'prepare_controls' ) );
    106107        add_action( 'customize_controls_enqueue_scripts', array( $this, 'enqueue_control_scripts' ) );
     
    111112     *
    112113     * @since 3.4.0
    113      *
     114     * @since 4.2.0 Added $action param.
     115     *
     116     * @param string|null $action whether the supplied Ajax action is being run.
    114117     * @return bool
    115118     */
    116     public function doing_ajax() {
    117         return isset( $_POST['customized'] ) || ( defined( 'DOING_AJAX' ) && DOING_AJAX );
     119    public function doing_ajax( $action = null ) {
     120        $doing_ajax = ( defined( 'DOING_AJAX' ) && DOING_AJAX );
     121        if ( ! $doing_ajax ) {
     122            return false;
     123        }
     124
     125        if ( ! $action ) {
     126            return true;
     127        } else {
     128            // Note: we can't just use doing_action( "wp_ajax_{$action}" ) because we need to check before admin-ajax.php gets to that point
     129            return isset( $_REQUEST['action'] ) && wp_unslash( $_REQUEST['action'] ) === $action;
     130        }
    118131    }
    119132
     
    412425                $this->_post_values = json_decode( wp_unslash( $_POST['customized'] ), true );
    413426            }
    414             if ( empty( $this->_post_values ) ) { // if not isset or of JSON error
    415                 $this->_post_values = false;
     427            if ( empty( $this->_post_values ) ) { // if not isset or if JSON error
     428                $this->_post_values = array();
    416429            }
    417430        }
     
    440453            return $default;
    441454        }
     455    }
     456
     457    /**
     458     * Override a setting's (unsanitized) value as found in any incoming $_POST['customized']
     459     *
     460     * @since 4.2.0
     461     *
     462     * @param string $setting_id  The ID for the WP_Customize_Setting instance.
     463     * @param mixed $value
     464     */
     465    public function set_post_value( $setting_id, $value ) {
     466        $this->unsanitized_post_values();
     467        $this->_post_values[ $setting_id ] = $value;
    442468    }
    443469
     
    728754
    729755    /**
     756     * Register any dynamically-created settings, such as those from $_POST['customized'] that have no corresponding setting created.
     757     *
     758     * This is a mechanism to "wake up" settings that have been dynamically created
     759     * on the frontend and have been sent to WordPress in $_POST['customized']. When WP
     760     * loads, the dynamically-created settings then will get created and previewed
     761     * even though they are not directly created statically with code.
     762     *
     763     * @since 4.2.0
     764     *
     765     * @param string[] $setting_ids The setting IDs to add.
     766     * @return WP_Customize_Setting[] The settings added.
     767     */
     768    public function add_dynamic_settings( $setting_ids ) {
     769        $new_settings = array();
     770        foreach ( $setting_ids as $setting_id ) {
     771            // Skip settings already created
     772            if ( $this->get_setting( $setting_id ) ) {
     773                continue;
     774            }
     775
     776            $setting_args = false;
     777            $setting_class = 'WP_Customize_Setting';
     778
     779            /**
     780             * Filter a dynamic setting's constructor args.
     781             *
     782             * For a dynamic setting to be registered, this filter must be employed
     783             * to override the default false value with an array of args to pass to
     784             * the WP_Customize_Setting constructor.
     785             *
     786             * @since 4.2.0
     787             *
     788             * @param false|array $setting_args  The arguments to the WP_Customize_Setting constructor.
     789             * @param string      $setting_id    ID for dynamic setting, usually coming from $_POST['customized'].
     790             */
     791            $setting_args = apply_filters( 'customize_dynamic_setting_args', $setting_args, $setting_id );
     792            if ( false === $setting_args ) {
     793                continue;
     794            }
     795
     796            /**
     797             * Allow non-statically created settings to be constructed with custom WP_Customize_Setting subclass.
     798             *
     799             * @since 4.2.0
     800             *
     801             * @param string $setting_class  WP_Customize_Setting or a subclass.
     802             * @param string $setting_id     ID for dynamic setting, usually coming from $_POST['customized'].
     803             * @param string $setting_args   WP_Customize_Setting or a subclass.
     804             */
     805            $setting_class = apply_filters( 'customize_dynamic_setting_class', $setting_class, $setting_id, $setting_args );
     806
     807            $setting = new $setting_class( $this, $setting_id, $setting_args );
     808            $this->add_setting( $setting );
     809            $new_settings[] = $setting;
     810        }
     811        return $new_settings;
     812    }
     813
     814    /**
    730815     * Retrieve a customize setting.
    731816     *
     
    736821     */
    737822    public function get_setting( $id ) {
    738         if ( isset( $this->settings[ $id ] ) )
     823        if ( isset( $this->settings[ $id ] ) ) {
    739824            return $this->settings[ $id ];
     825        }
    740826    }
    741827
     
    12731359            ) );
    12741360        }
     1361    }
     1362
     1363    /**
     1364     * Add settings from the POST data that were not added with code, e.g. dynamically-created settings for Widgets
     1365     *
     1366     * @since 4.2.0
     1367     */
     1368    public function register_dynamic_settings() {
     1369        $this->add_dynamic_settings( array_keys( $this->unsanitized_post_values() ) );
    12751370    }
    12761371
Note: See TracChangeset for help on using the changeset viewer.