#30988 closed defect (bug) (fixed)
Setting's default value doesn't apply on preview window
Reported by: | Aniruddh | Owned by: | ocean90 |
---|---|---|---|
Milestone: | 4.1.1 | Priority: | normal |
Severity: | normal | Version: | 4.1 |
Component: | Customize | Keywords: | has-patch fixed-major |
Focuses: | administration | Cc: |
Description
Hello,
Ever since I have upgraded my wordpress installation from 4.0 to 4.1, I am seeing the default value of my Cutsomizer's setting doesn't apply on preview window. The options table is empty and customizer's preview window is supposed to read default values I have mentioned. ( Just like it did in previous versions )
/* BG COLOR */ $wp_customize->add_setting( 'my_settings[bg_color]', array( 'default' => '#CCCCCC', 'capability' => 'edit_theme_options', 'type' => 'option', ) );
I read it on frontend this way:
$my_option = get_option( 'my_settings' ); $my_option['bg_color'];
Attachments (6)
Change History (36)
#3
@
10 years ago
- Keywords needs-testing needs-unit-tests has-patch added; needs-patch removed
In 30988.diff:
- Add
$default
param toWP_Customize_Manager::post_value()
(and add protectedWP_Customize_Manager::parse_post_data()
method) - Update
WP_Customize_Setting::_preview_filter()
to use original or default value if nopost_value
supplied for setting
#4
@
10 years ago
I've been working on unit tests and, as usual, I found some edge cases that I didn't account for in my initial patch. Latest work can be seen here: https://github.com/xwp/wordpress-develop/pull/62/files#diff-8582bb972a2a8283eebe2050f95f3c19
@
10 years ago
Additional changes: https://github.com/xwp/wordpress-develop/compare/724e16d...3feec2c
#5
@
10 years ago
- Keywords needs-unit-tests removed
- Owner changed from westonruter to ocean90
- Status changed from assigned to reviewing
In 30988.2.diff:
9e00392
Userequire_once
instead ofrequire
in WP_Customize_Manager (for unit testing, but also good regardless)daf6183
Updatemultidimensional
to account for an array overriding a string or object value (otherwise fatal error can ensue)6a86c92
Store the response ofvalue()
when callingpreview()
for use if nopost_value()
(this is the key commit for this ticket)- Add unit tests for
WP_Customize_Setting::__construct()
andWP_Customize_Setting::preview()
, with 139 assertions. (See also #28579)
Full changes in PR: https://github.com/xwp/wordpress-develop/pull/62/files
#6
follow-up:
↓ 7
@
10 years ago
- Keywords needs-patch added; has-patch removed
After further testing ( with patched class-wp-customize-manager.php & class-wp-customize-settings.php ) I have found out that customizer does not save the default values to the database. It only saves the values of the settings whose values are changed.
#7
in reply to:
↑ 6
@
10 years ago
- Owner changed from ocean90 to westonruter
Replying to Aniruddh:
After further testing ( with patched class-wp-customize-manager.php & class-wp-customize-settings.php ) I have found out that customizer does not save the default values to the database. It only saves the values of the settings whose values are changed.
Thanks for discovering that. It makes sense in the case of options specifically, because update_option()
will do no-op if it detects that the value being saved is identical to the value already in the DB. So I think what may be happening is that since we're filtering the DB value to be the default value, when you try save a default into the DB then it does a no-op.
#8
follow-ups:
↓ 9
↓ 19
@
10 years ago
Sorry, I did not mention that when I tested the patch, I deleted the option row from the table.
So, I was under impression that customizer will save default values to empty table row but instead it saved values of those settings whose default values were changed.
#9
in reply to:
↑ 8
@
10 years ago
- Keywords reporter-feedback added
Replying to Aniruddh:
Sorry, I did not mention that when I tested the patch, I deleted the option row from the table.
So, I was under impression that customizer will save default values to empty table row but instead it saved values of those settings whose default values were changed.
So you did delete_option( 'my_settings' )
before testing? And then when saving the my_settings[bg_color]
setting with the value #CCCCCC
the result was that no my_settings
option was added? And yet if you were to try saving my_settings[bg_color]
to something else, like #000000
, then it succeeded in creating the my_settings
option?
I don't see why this would happen according to my theory above, because the setting's preview()
method doesn't get called when a customize_save
WP Ajax request is made. I tried registering a setting for a non-existent option, and when I tried saving the setting with the default value, the value was successfully saved to the DB as a new option. (Could your issue actually be #28701? Do you have an external object cache?)
Could you share some more of your sample code, preferably a self-contained plugin, which I can use to reproduce the issue?
This ticket was mentioned in Slack in #core-customize by westonruter. View the logs.
10 years ago
#11
@
10 years ago
- Keywords has-patch added; needs-patch removed
- Owner changed from westonruter to ocean90
I couldn't reproduce any defect with the patch I wrote, and it does fix a flaw where default values fail to apply (though in reality any default value supplied to the WP_Customize_Setting
should be used as the second $default
arg to get_option
and get_theme_mod
anyway).
@Aniruddh: Please provide more detailed steps to reproduce the problem, if it still exists with the patch.
#12
@
10 years ago
- Tests: It's not clear enough which test is specific for this issue. Also there are to many assertions in one tests. These should be splitted up. Closures should be removed too.
parse_post_data()
: Can't we introduceprivate function post_values()
and use$this->post_values();
instead of$this->parse_post_data();
$this->_post_values;`?- I'm missing a test case to verify the issue.
#13
@
10 years ago
- Keywords needs-patch added; has-patch removed
- Owner changed from ocean90 to westonruter
This ticket was mentioned in Slack in #core by westonruter. View the logs.
10 years ago
@
10 years ago
Additional changes: https://github.com/xwp/wordpress-develop/compare/3feec2c...2da22194
#15
@
10 years ago
- Keywords has-patch added; needs-testing reporter-feedback needs-patch removed
- Owner changed from westonruter to ocean90
@ocean90: in 30988.3.diff:
- Add specific test case for issue in this ticket: https://github.com/xwp/wordpress-develop/commit/2da22194ecceb45eaf2a4b404beefb363c4fe40a
- Split up test case method in half, trying to keep things DRY: https://github.com/xwp/wordpress-develop/commit/2c92f831d04626ef661b0b1a77a6885d286db0d3
- Removed closures: https://github.com/xwp/wordpress-develop/compare/c4a0da93112e942ab35d6378c467e3d2fdde8ac5...edf7836af3bed880502b4ed5050fbb294be05fb4
- Removed separate
parse_post_data
method, but keeping$default
argument on thepost_value()
method: https://github.com/xwp/wordpress-develop/commit/39d5d8f34dbee10c8883d9e1be3f84adab2987bc
Full changes in PR: https://github.com/xwp/wordpress-develop/pull/62/files
@
10 years ago
Additional changes: https://github.com/xwp/wordpress-develop/compare/2da22194...2fb9fd4
#16
@
10 years ago
@ocean90: in 30988.4.diff:
- Restore
parse_post_values()
asunsanitized_post_values()
(incorporating feedback above), since I just realized it is needed by #30936; usearray_key_exists
instead ofisset
to account fornull
values; improve PhpDoc: https://github.com/xwp/wordpress-develop/commit/23523a9c945c269d5f70b83beb3620cc304e0089 - Add unit test for
WP_Customize_Manager
: https://github.com/xwp/wordpress-develop/commit/2fb9fd4d7b1f2d0d19a7b185b14ba800f6d68e72
Full changes in PR: https://github.com/xwp/wordpress-develop/pull/62/files
#17
@
10 years ago
In 30988.5.diff, I made WP_Customize_Manager::unsanitized_post_values()
public instead of private for the sake of #30936. I also include a unit test.
This ticket was mentioned in Slack in #core-customize by ocean90. View the logs.
10 years ago
#19
in reply to:
↑ 8
;
follow-up:
↓ 20
@
10 years ago
Replying to Aniruddh:
So, I was under impression that customizer will save default values to empty table row but instead it saved values of those settings whose default values were changed.
I could reproduce this issue or at least a regression from 4.0.
My code:
add_action( 'customize_register', function() { global $wp_customize; $wp_customize->add_panel( 'foo', array( 'title' => 'Foo', 'capability' => 'edit_theme_options', ) ); $wp_customize->add_section( 'bar', array( 'title' => 'Bar', 'capability' => 'edit_theme_options', 'panel' => 'foo' ) ); $wp_customize->add_setting( 'foo_text', array( 'default' => 'Lorem', 'capability' => 'edit_posts', 'type' => 'option', ) ); $wp_customize->add_control( 'foo_text', array( 'label' => 'Foo & bar', 'section' => 'bar', 'type' => 'textarea', ) ); $wp_customize->add_setting( 'foo_color', array( 'default' => '#f00', 'capability' => 'edit_theme_options', 'type' => 'option', ) ); $wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'foo_color', array( 'label' => 'Color', 'section' => 'bar', ) ) ); }); add_action( 'wp_head', function() { var_dump( get_option( 'foo_color' ) ); var_dump( get_option( 'foo_text' ) ); });
4.0:
Front page without Customizer:
bool(false) bool(false)
Front page in Customizer:
string(4) "#f00" string(5) "Lorem"
Front page in Customizer, color changed:
string(7) "#6900db" string(5) "Lorem"
Changes saved, and front page without Customizer:
string(7) "#6900db" string(5) "Lorem" ) // Default value is stored
Trunk with patch applied:
Front page without Customizer:
bool(false) bool(false)
Front page in Customizer:
string(4) "#f00" string(5) "Lorem"
Front page in Customizer, color changed:
string(7) "#6900db" string(5) "Lorem"
Changes saved, and front page without Customizer:
string(7) "#6900db" bool(false) // Default value isn't stored
#20
in reply to:
↑ 19
@
10 years ago
Replying to ocean90:
I could reproduce this issue or at least a regression from 4.0.
This is actually expected. Remember in 4.1 via #29983 we only POST
dirty settings (ones that have changed), so the default value attached to a setting will always be directly used in the Customizer preview as opposed to the post value if the setting was not changed.
I think your plugin code needs to be tweaked, for instance:
-
30988-plugin.php
1 1 <?php 2 $foo_color_default = '#f00'; 3 $foo_text_default = 'Lorem'; 2 4 3 add_action( 'customize_register', function() { 5 // These add_option() eliminate the need for supplying default values for settings, 6 // and it eliminates the need to supply the 2nd $default arg to get_option() 7 add_option( 'foo_color', $foo_color_default ); 8 add_option( 'foo_text', $foo_text_default ); 9 10 add_action( 'customize_register', function() use ( $foo_color_default, $foo_text_default ) { 4 11 global $wp_customize; 5 12 6 13 $wp_customize->add_panel( 'foo', array( … … add_action( 'customize_register', function() { 15 22 ) ); 16 23 17 24 $wp_customize->add_setting( 'foo_text', array( 18 'default' => 'Lorem',25 'default' => $foo_text_default, // not really needed because add_option() call used with default supplied 19 26 'capability' => 'edit_posts', 20 27 'type' => 'option', 21 28 ) ); … … add_action( 'customize_register', function() { 27 34 ) ); 28 35 29 36 $wp_customize->add_setting( 'foo_color', array( 30 'default' => '#f00',37 'default' => $foo_color_default, // not really needed because add_option() call used with default supplied 31 38 'capability' => 'edit_theme_options', 32 39 'type' => 'option', 33 40 ) ); … … add_action( 'customize_register', function() { 38 45 ) ) ); 39 46 }); 40 47 41 add_action( 'wp_head', function() {42 var_dump( get_option( 'foo_color' ) );43 var_dump( get_option( 'foo_text' ) );48 add_action( 'wp_head', function() use ( $foo_color_default, $foo_text_default ) { 49 var_dump( get_option( 'foo_color', $foo_color_default ) ); // second argument not needed since add_option() call used 50 var_dump( get_option( 'foo_text', $foo_text_default ) ); // second argument not needed since add_option() call used 44 51 });
https://gist.github.com/westonruter/1717cadbb3ef581291ba
Without doing add_option()
or supplying the default arg to the get_option()
call, then the frontend would not get the default values to display without first visiting the Customizer.
This ticket was mentioned in Slack in #core-customize by westonruter. View the logs.
10 years ago
#23
@
10 years ago
- Keywords fixed-major added
- Resolution fixed deleted
- Status changed from closed to reopened
I believe this is a regression introduced by [30102] in #28580. Now that we only POST settings to the Customizer preview if they have actually been changes in them (if they're dirty), the preview filter needs to be updated to use the setting's default value if the option/theme_mod doesn't already exist.