/** * @see WP_Customize_Widget_Setting::value() */ function test_value() { $id_base = 'categories'; $sample_data = $this->get_sample_widget_instance_data($id_base); $old_setting = new \WP_Customize_Setting($this->customize_manager, $sample_data['setting_id'], array('type' => 'option')); $args = $this->customize_manager->widgets->get_setting_args($sample_data['setting_id']); $new_setting = new WP_Customize_Widget_Setting($this->customize_manager, $sample_data['setting_id'], $args); $this->assertEquals($sample_data['instance'], $old_setting->value()); $this->assertEquals($old_setting->value(), $new_setting->value()); }
function setUp() { parent::setUp(); require_once ABSPATH . WPINC . '/class-wp-customize-manager.php'; add_theme_support('customize-selective-refresh-widgets'); $user_id = self::factory()->user->create(array('role' => 'administrator')); wp_set_current_user($user_id); $GLOBALS['wp_customize'] = new WP_Customize_Manager(); $this->manager = $GLOBALS['wp_customize']; unset($GLOBALS['_wp_sidebars_widgets']); // clear out cache set by wp_get_sidebars_widgets() $sidebars_widgets = wp_get_sidebars_widgets(); $this->assertEqualSets(array('wp_inactive_widgets', 'sidebar-1'), array_keys(wp_get_sidebars_widgets())); $this->assertContains('search-2', $sidebars_widgets['sidebar-1']); $this->assertContains('categories-2', $sidebars_widgets['sidebar-1']); $this->assertArrayHasKey(2, get_option('widget_search')); $widget_categories = get_option('widget_categories'); $this->assertArrayHasKey(2, $widget_categories); $this->assertEquals('', $widget_categories[2]['title']); // @todo We should not be including a theme anyway remove_action('after_setup_theme', 'twentyfifteen_setup'); remove_action('after_setup_theme', 'twentysixteen_setup'); remove_action('customize_register', 'twentysixteen_customize_register', 11); $this->backup_registered_sidebars = $GLOBALS['wp_registered_sidebars']; // Reset protected static var on class. WP_Customize_Setting::reset_aggregated_multidimensionals(); }
public function value() { $value = parent::value(); if (!is_array($value)) { $value = array(); } return $value; }
/** * WP_Customize_REST_Resource_Setting constructor. * * @param \WP_Customize_Manager $manager Manager. * @param string $id Setting ID. * @param array $args Setting args. * @throws Exception If the ID is in an invalid format. */ public function __construct($manager, $id, $args = array()) { if (!isset($args['sanitize_callback'])) { $args['sanitize_callback'] = array($this, 'sanitize'); } if (!preg_match('#^rest_resource\\[(?P<route>.+?)]$#', $id, $matches)) { throw new Exception('Illegal setting id: ' . $id); } $this->route = trim($matches['route'], '/'); if (!isset($args['plugin']) || !$args['plugin'] instanceof Plugin) { throw new Exception(sprintf('Missing plugin arg for %s', get_class($this))); } parent::__construct($manager, $id, $args); }
/** * Constructor. * * Any supplied $args override class property defaults. * * @param \WP_Customize_Manager $manager Manager instance. * @param string $id An specific ID of the setting. Can be a * theme mod or option name. * @param array $args Setting arguments. * @throws Exception If $id is not valid for a widget. */ public function __construct(\WP_Customize_Manager $manager, $id, array $args = array()) { unset($args['type']); if (!preg_match(static::WIDGET_SETTING_ID_PATTERN, $id, $matches)) { throw new Exception("Illegal widget setting ID: {$id}"); } $this->widget_id_base = $matches['widget_id_base']; if (isset($matches['widget_number'])) { $this->widget_number = intval($matches['widget_number']); } parent::__construct($manager, $id, $args); if (empty($this->widget_posts)) { throw new Exception('Missing argument: widget_posts'); } }
/** * Overwrites the `update()` method so we can save some extra data. * * @since 3.0.0 * @access public * @param string $value * @return string */ protected function update($value) { if ($value) { $post_id = attachment_url_to_postid($value); if ($post_id) { $image = wp_get_attachment_image_src($post_id); if ($image) { // Set up a custom array of data to save. $data = array('url' => esc_url_raw($image[0]), 'width' => absint($image[1]), 'height' => absint($image[2]), 'id' => absint($post_id)); set_theme_mod("{$this->id_data['base']}_data", $data); } } } // No media? Remove the data mod. if (empty($value) || empty($post_id) || empty($image)) { remove_theme_mod("{$this->id_data['base']}_data"); } // Let's send this back up and let the parent class do its thing. return parent::update($value); }
/** * Preview changes made to a nav menu. * * Filters nav menu display to show customized items in the customized order. * * @since Menu Customizer 0.0 * * @param array $value Array of the menu items to preview, in order. * @param WP_Customize_Setting $setting WP_Customize_Setting instance. */ function menu_customizer_preview_nav_menu($setting) { $menu_id = str_replace('nav_menu_', '', $setting->id); // Ensure that $menu_id is valid. $menu_id = (int) $menu_id; $menu = wp_get_nav_menu_object($menu_id); if (!$menu || !$menu_id) { return new WP_Error('invalid_menu_id', __('Invalid menu ID.')); } if (is_wp_error($menu)) { return $menu; } $menu_id = $menu->term_id; // @todo don't use a closure for PHP 5.2 add_filter('wp_get_nav_menu_items', function ($items, $menu, $args) use($menu_id, $setting) { $preview_menu_id = $menu->term_id; if ($menu_id == $preview_menu_id) { $new_ids = $setting->post_value(); $new_items = array(); $i = 0; // For each item, get object and update menu order property. foreach ($new_ids as $item_id) { $item = get_post($item_id); $item = wp_setup_nav_menu_item($item); $item->menu_order = $i; $new_items[] = $item; $i++; } return $new_items; } else { return $items; } }, 10, 3); }
/** * Constructor. * * Any supplied $args override class property defaults. * * @since 4.3.0 * @access public * * @param WP_Customize_Manager $manager Bootstrap Customizer instance. * @param string $id An specific ID of the setting. Can be a * theme mod or option name. * @param array $args Optional. Setting arguments. * * @throws Exception If $id is not valid for this setting type. */ public function __construct(WP_Customize_Manager $manager, $id, array $args = array()) { if (empty($manager->nav_menus)) { throw new Exception('Expected WP_Customize_Manager::$nav_menus to be set.'); } if (!preg_match(self::ID_PATTERN, $id, $matches)) { throw new Exception("Illegal widget setting ID: {$id}"); } $this->term_id = intval($matches['id']); parent::__construct($manager, $id, $args); }
public function __construct($manager, $id, $args = array()) { parent::__construct($manager, $id, $args); // set up the id_data, etc. if (!WeaverX_Customize_Setting::$filter_added) { add_filter('pre_option_' . $this->id_data['base'], 'WeaverX_Customize_Setting::_preview_filter_cache'); add_filter('option_' . $this->id_data['base'], 'WeaverX_Customize_Setting::_preview_filter_cache'); add_filter('default_option_' . $this->id_data['base'], 'WeaverX_Customize_Setting::_preview_filter_cache'); WeaverX_Customize_Setting::$filter_added = true; } }
/** * Test specific fix for setting's default value not applying on preview window * * @ticket 30988 */ function test_non_posted_setting_applying_default_value_in_preview() { $type = 'option'; $name = 'unset_option_without_post_value'; $default = "default_value_{$name}"; $setting = new WP_Customize_Setting( $this->manager, $name, compact( 'type', 'default' ) ); $this->assertEquals( $this->undefined, get_option( $name, $this->undefined ) ); $this->assertEquals( $default, $setting->value() ); $setting->preview(); $this->assertEquals( $default, get_option( $name, $this->undefined ), sprintf( 'Expected get_option(%s) to return setting default: %s.', $name, $default ) ); $this->assertEquals( $default, $setting->value() ); }
/** * Test validate. * * @see WP_Customize_Setting::validate() */ public function test_validate() { $setting = new WP_Customize_Setting($this->manager, 'name', array('type' => 'key', 'validate_callback' => array($this, 'filter_validate_for_test_validate'))); $validity = $setting->validate('BAD!'); $this->assertInstanceOf('WP_Error', $validity); $this->assertEquals('invalid_key', $validity->get_error_code()); }
function set_wp2android_theme_menu($wp_customize) { $setting = new WP_Customize_Setting($wp_customize, 'wp2android_theme_menu', array('default' => '')); $menu = $setting->post_value(); $wp_customize->add_setting($setting); if (!empty($menu)) { wp2android_plugin_menus()->setMenu($menu); } }
/** * Save data in special option for better performance in query * * @param \WP_Customize_Setting $setting */ protected function _save_post_id($setting) { Posts::update($setting->id, $setting->post_value()); }
/** * Ensure that WP_Customize_Setting::value() can return a previewed value for aggregated multidimensionals. * * @ticket 37294 */ public function test_multidimensional_value_when_previewed() { WP_Customize_Setting::reset_aggregated_multidimensionals(); $initial_value = 456; set_theme_mod('nav_menu_locations', array('primary' => $initial_value)); $setting_id = 'nav_menu_locations[primary]'; $setting = new WP_Customize_Setting($this->manager, $setting_id); $this->assertEquals($initial_value, $setting->value()); $override_value = -123456; $this->manager->set_post_value($setting_id, $override_value); $setting->preview(); $this->assertEquals($override_value, $setting->value()); }
/** * Decode the $_POST['customized'] values for a specific Customize Setting. * * @since 3.4.0 * * @param WP_Customize_Setting $setting A WP_Customize_Setting derived object * @return string $post_value Sanitized value */ public function post_value($setting) { if (!isset($this->_post_values)) { if (isset($_POST['customized'])) { $this->_post_values = json_decode(wp_unslash($_POST['customized']), true); } else { $this->_post_values = false; } } if (isset($this->_post_values[$setting->id])) { return $setting->sanitize($this->_post_values[$setting->id]); } }
/** * Publish the auto-draft posts that were created for nav menu items. * * The post IDs will have been sanitized by already by * `WP_Customize_Nav_Menu_Items::sanitize_nav_menus_created_posts()` to * remove any post IDs for which the user cannot publish or for which the * post is not an auto-draft. * * @since 4.7.0 * @access public * * @param WP_Customize_Setting $setting Customizer setting object. */ public function save_nav_menus_created_posts($setting) { $post_ids = $setting->post_value(); if (!empty($post_ids)) { foreach ($post_ids as $post_id) { wp_publish_post($post_id); } } }
/** * Publish the auto-draft posts that were created for nav menu items. * * The post IDs will have been sanitized by already by * `WP_Customize_Nav_Menu_Items::sanitize_nav_menus_created_posts()` to * remove any post IDs for which the user cannot publish or for which the * post is not an auto-draft. * * @since 4.7.0 * @access public * * @param WP_Customize_Setting $setting Customizer setting object. */ public function save_nav_menus_created_posts($setting) { $post_ids = $setting->post_value(); if (!empty($post_ids)) { foreach ($post_ids as $post_id) { // Note that wp_publish_post() cannot be used because unique slugs need to be assigned. wp_update_post(array('ID' => $post_id, 'post_status' => 'publish')); } } }
/** * Ensure that previewing a setting is disabled when the current blog is switched. * * @ticket 31428 * @group multisite */ function test_previewing_with_switch_to_blog() { if ( ! is_multisite() ) { $this->markTestSkipped( 'Cannot test WP_Customize_Setting::is_current_blog_previewed() with switch_to_blog() if not on multisite.' ); } $type = 'option'; $name = 'blogdescription'; $post_value = rand_str(); $this->manager->set_post_value( $name, $post_value ); $setting = new WP_Customize_Setting( $this->manager, $name, compact( 'type' ) ); $this->assertNull( $setting->is_current_blog_previewed() ); $setting->preview(); $this->assertTrue( $setting->is_current_blog_previewed() ); $blog_id = $this->factory->blog->create(); switch_to_blog( $blog_id ); $this->assertFalse( $setting->is_current_blog_previewed() ); $this->assertNotEquals( $post_value, $setting->value() ); $this->assertNotEquals( $post_value, get_option( $name ) ); restore_current_blog(); }
/** * Constructor. * * Any supplied $args override class property defaults. * * @since 4.3.0 * @access public * * @param WP_Customize_Manager $manager Bootstrap Customizer instance. * @param string $id An specific ID of the setting. Can be a * theme mod or option name. * @param array $args Optional. Setting arguments. * * @throws Exception If $id is not valid for this setting type. */ public function __construct(WP_Customize_Manager $manager, $id, array $args = array()) { if (empty($manager->nav_menus)) { throw new Exception('Expected WP_Customize_Manager::$nav_menus to be set.'); } if (!preg_match(self::ID_PATTERN, $id, $matches)) { throw new Exception("Illegal widget setting ID: {$id}"); } $this->post_id = intval($matches['id']); add_action('wp_update_nav_menu_item', array($this, 'flush_cached_value'), 10, 2); parent::__construct($manager, $id, $args); // Ensure that an initially-supplied value is valid. if (isset($this->value)) { $this->populate_value(); foreach (array_diff(array_keys($this->default), array_keys($this->value)) as $missing) { throw new Exception("Supplied nav_menu_item value missing property: {$missing}"); } } }
/** * Publish the auto-draft posts that were created for nav menu items. * * The post IDs will have been sanitized by already by * `WP_Customize_Nav_Menu_Items::sanitize_nav_menus_created_posts()` to * remove any post IDs for which the user cannot publish or for which the * post is not an auto-draft. * * @since 4.7.0 * @access public * * @param WP_Customize_Setting $setting Customizer setting object. */ public function save_nav_menus_created_posts($setting) { $post_ids = $setting->post_value(); if (!empty($post_ids)) { foreach ($post_ids as $post_id) { $target_status = 'attachment' === get_post_type($post_id) ? 'inherit' : 'publish'; $args = array('ID' => $post_id, 'post_status' => $target_status); $post_name = get_post_meta($post_id, '_customize_draft_post_name', true); if ($post_name) { $args['post_name'] = $post_name; } // Note that wp_publish_post() cannot be used because unique slugs need to be assigned. wp_update_post(wp_slash($args)); delete_post_meta($post_id, '_customize_draft_post_name'); } } }
/** * Returns the sanitized value for a given setting from the request's POST data. * * @since 3.4.0 * @since 4.1.1 Introduced the `$default` parameter. * @since 4.6.0 `$default` is now returned early when the setting post value is invalid. * @access public * * @see WP_REST_Server::dispatch() * @see WP_Rest_Request::sanitize_params() * @see WP_Rest_Request::has_valid_params() * * @param WP_Customize_Setting $setting A WP_Customize_Setting derived object. * @param mixed $default Value returned $setting has no post value (added in 4.2.0) * or the post value is invalid (added in 4.6.0). * @return string|mixed $post_value Sanitized value or the $default provided. */ public function post_value($setting, $default = null) { $post_values = $this->unsanitized_post_values(); if (!array_key_exists($setting->id, $post_values)) { return $default; } $value = $post_values[$setting->id]; $valid = $setting->validate($value); if (is_wp_error($valid)) { return $default; } $value = $setting->sanitize($value); if (is_null($value) || is_wp_error($value)) { return $default; } return $value; }
/** * @ticket 33499 */ function test_option_autoloading() { global $wpdb; wp_set_current_user(self::factory()->user->create(array('role' => 'administrator'))); $name = 'autoloaded1'; $setting = new WP_Customize_Setting($this->manager, $name, array('type' => 'option')); $value = 'value1'; $this->manager->set_post_value($setting->id, $value); $setting->save(); $autoload = $wpdb->get_var($wpdb->prepare("SELECT autoload FROM {$wpdb->options} WHERE option_name = %s", $setting->id)); $this->assertEquals('yes', $autoload); $this->assertEquals($value, get_option($name)); $name = 'autoloaded2'; $setting = new WP_Customize_Setting($this->manager, $name, array('type' => 'option', 'autoload' => true)); $value = 'value2'; $this->manager->set_post_value($setting->id, $value); $setting->save(); $autoload = $wpdb->get_var($wpdb->prepare("SELECT autoload FROM {$wpdb->options} WHERE option_name = %s", $setting->id)); $this->assertEquals('yes', $autoload); $this->assertEquals($value, get_option($name)); $name = 'not-autoloaded1'; $setting = new WP_Customize_Setting($this->manager, $name, array('type' => 'option', 'autoload' => false)); $value = 'value3'; $this->manager->set_post_value($setting->id, $value); $setting->save(); $autoload = $wpdb->get_var($wpdb->prepare("SELECT autoload FROM {$wpdb->options} WHERE option_name = %s", $setting->id)); $this->assertEquals('no', $autoload); $this->assertEquals($value, get_option($name)); $id_base = 'multi-not-autoloaded'; $setting1 = new WP_Customize_Setting($this->manager, $id_base . '[foo]', array('type' => 'option')); $setting2 = new WP_Customize_Setting($this->manager, $id_base . '[bar]', array('type' => 'option', 'autoload' => false)); $this->manager->set_post_value($setting1->id, 'value1'); $this->manager->set_post_value($setting2->id, 'value2'); $setting1->save(); $autoload = $wpdb->get_var($wpdb->prepare("SELECT autoload FROM {$wpdb->options} WHERE option_name = %s", $id_base)); $this->assertEquals('no', $autoload, 'Even though setting1 did not indicate autoload (thus normally true), since another multidimensional option setting of the base did say autoload=false, it should be autoload=no'); }
/** * Reset `$aggregated_multidimensionals` static variable. * * This is intended only for use by unit tests. * * @since 4.5.0 * @access public * @ignore */ public static function reset_aggregated_multidimensionals() { self::$aggregated_multidimensionals = array(); }
/** * Validate CSS. * * Checks for imbalanced braces, brackets, and comments. * Notifications are rendered when the customizer state is saved. * * @todo There are cases where valid CSS can be incorrectly marked as invalid when strings or comments include balancing characters. To fix, CSS tokenization needs to be used. * * @since 4.7.0 * @access public * * @param string $css The input string. * @return true|WP_Error True if the input was validated, otherwise WP_Error. */ public function validate($css) { $validity = new WP_Error(); if (preg_match('#</?\\w+#', $css)) { $validity->add('illegal_markup', __('Markup is not allowed in CSS.')); } $imbalanced = false; // Make sure that there is a closing brace for each opening brace. if (!$this->validate_balanced_characters('{', '}', $css)) { $validity->add('imbalanced_curly_brackets', __('Your curly brackets <code>{}</code> are imbalanced. Make sure there is a closing <code>}</code> for every opening <code>{</code>.')); $imbalanced = true; } // Ensure brackets are balanced. if (!$this->validate_balanced_characters('[', ']', $css)) { $validity->add('imbalanced_braces', __('Your brackets <code>[]</code> are imbalanced. Make sure there is a closing <code>]</code> for every opening <code>[</code>.')); $imbalanced = true; } // Ensure parentheses are balanced. if (!$this->validate_balanced_characters('(', ')', $css)) { $validity->add('imbalanced_parentheses', __('Your parentheses <code>()</code> are imbalanced. Make sure there is a closing <code>)</code> for every opening <code>(</code>.')); $imbalanced = true; } // Ensure single quotes are equal. if (!$this->validate_equal_characters('\'', $css)) { $validity->add('unequal_single_quotes', __('Your single quotes <code>\'</code> are uneven. Make sure there is a closing <code>\'</code> for every opening <code>\'</code>.')); $imbalanced = true; } // Ensure single quotes are equal. if (!$this->validate_equal_characters('"', $css)) { $validity->add('unequal_double_quotes', __('Your double quotes <code>"</code> are uneven. Make sure there is a closing <code>"</code> for every opening <code>"</code>.')); $imbalanced = true; } /* * Make sure any code comments are closed properly. * * The first check could miss stray an unpaired comment closing figure, so if * The number appears to be balanced, then check for equal numbers * of opening/closing comment figures. * * Although it may initially appear redundant, we use the first method * to give more specific feedback to the user. */ $unclosed_comment_count = $this->validate_count_unclosed_comments($css); if (0 < $unclosed_comment_count) { $validity->add('unclosed_comment', sprintf(_n('There is %s unclosed code comment. Close each comment with <code>*/</code>.', 'There are %s unclosed code comments. Close each comment with <code>*/</code>.', $unclosed_comment_count), $unclosed_comment_count)); $imbalanced = true; } elseif (!$this->validate_balanced_characters('/*', '*/', $css)) { $validity->add('imbalanced_comments', __('There is an extra <code>*/</code>, indicating an end to a comment. Be sure that there is an opening <code>/*</code> for every closing <code>*/</code>.')); $imbalanced = true; } if ($imbalanced && $this->is_possible_content_error($css)) { $validity->add('possible_false_positive', __('Imbalanced/unclosed character errors can be caused by <code>content: "";</code> declarations. You may need to remove this or add it to a custom CSS file.')); } if (empty($validity->errors)) { $validity = parent::validate($css); } return $validity; }
/** * Return the sanitized value for a given setting from the request's POST data. * * @since 3.4.0 * @since 4.1.1 Introduced 'default' parameter. * * @param WP_Customize_Setting $setting A WP_Customize_Setting derived object * @param mixed $default value returned $setting has no post value (added in 4.2.0). * @return string|mixed $post_value Sanitized value or the $default provided */ public function post_value($setting, $default = null) { $post_values = $this->unsanitized_post_values(); if (array_key_exists($setting->id, $post_values)) { return $setting->sanitize($post_values[$setting->id]); } else { return $default; } }
/** * Publish the auto-draft posts that were created for nav menu items. * * The post IDs will have been sanitized by already by * `WP_Customize_Nav_Menu_Items::sanitize_nav_menus_created_posts()` to * remove any post IDs for which the user cannot publish or for which the * post is not an auto-draft. * * @since 4.7.0 * @access public * * @param WP_Customize_Setting $setting Customizer setting object. */ public function save_nav_menus_created_posts($setting) { $post_ids = $setting->post_value(); if (!empty($post_ids)) { foreach ($post_ids as $post_id) { $target_status = 'attachment' === get_post_type($post_id) ? 'inherit' : 'publish'; // Note that wp_publish_post() cannot be used because unique slugs need to be assigned. wp_update_post(array('ID' => $post_id, 'post_status' => $target_status)); } } }