Last active
July 24, 2019 21:53
-
-
Save aristath/5f354e6f37332d140f835e368c07d9b2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Plugin Name: parent-theme-mods-loader | |
*/ | |
add_action( | |
'customize_register', | |
/** | |
* Hooks in customize_register to load our control, register settings and do what needs to be done. | |
* | |
* @param WP_Customize_Manager $wp_customize The WordPress Customizer object. | |
* @return void | |
*/ | |
function( $wp_customize ) { | |
/** | |
* A custom control. | |
* Contains a simple button to allow loading a set of options. | |
* | |
* TODO: This class should be on a separate file. | |
*/ | |
class WPTRT_Parent_Theme_Mods_Loader_Button extends \WP_Customize_Control { | |
/** | |
* The control type. | |
* | |
* @access public | |
* @var string | |
*/ | |
public $type = 'wptrt-load-settings-buttons'; | |
/** | |
* An array of options that will be passed-on to the JS. | |
* | |
* @access public | |
* @var array | |
*/ | |
public $choices; | |
/** | |
* Enqueue scripts. | |
* | |
* @access public | |
* @return void | |
*/ | |
public function enqueue() { | |
// TODO: Enqueue script (currently added via an anonymous function in customize_controls_print_footer_scripts). | |
} | |
/** | |
* Pass variables to our JS template. | |
* | |
* @access public | |
* @return void | |
*/ | |
public function to_json() { | |
parent::to_json(); | |
$this->json['choices'] = $this->choices; | |
} | |
/** | |
* JS template for the control. | |
* | |
* @access public | |
* @return void | |
*/ | |
protected function content_template() { | |
?> | |
<label> | |
<span class="customize-control-title">{{{ data.label }}}</span> | |
<# if ( data.description ) { #> | |
<span class="description customize-control-description">{{{ data.description }}}</span> | |
<# } #> | |
</label> | |
<button class="button">{{ data.choices.button_text }}</button> | |
<?php | |
} | |
} | |
// Register control-type. Whitelists the control for JS templating. | |
$wp_customize->register_control_type( 'WPTRT_Parent_Theme_Mods_Loader_Button' ); | |
// Get theme details. | |
$theme = wp_get_theme(); | |
// Get the template name (parent theme). | |
$template = $theme->get( 'Template' ); | |
// If we found a parent theme, add control. | |
if ( $template ) { | |
// Add control. | |
$wp_customize->add_control( | |
new \WPTRT_Parent_Theme_Mods_Loader_Button( | |
$wp_customize, | |
'wptrt_load_parent_theme_mods', | |
[ | |
'section' => 'title_tagline', | |
'settings' => [], | |
'priority' => 999, | |
'choices' => [ | |
'setting' => 'theme_mods_' . $template, | |
'button_text' => esc_html__( 'Load parent theme settings' ), | |
], | |
] | |
) | |
); | |
} | |
} | |
); | |
add_action( | |
'customize_controls_print_footer_scripts', | |
/** | |
* Add footer scripts. | |
* | |
* @return void | |
*/ | |
function() { | |
/** | |
* TODO: This should be on a separate file that gets enqueued | |
* in the WPTRT_Parent_Theme_Mods_Loader_Button::enqueue() method. | |
*/ | |
?> | |
<script> | |
wp.customize.controlConstructor['wptrt-load-settings-buttons'] = wp.customize.Control.extend( { | |
/** | |
* Runs when the control is ready. | |
*/ | |
ready: function() { | |
var control = this, | |
button = control.container.find( 'button' ); | |
// When we click on the button trigger the loadSettings method. | |
button.on( 'click', function( event ) { | |
event.preventDefault(); | |
control.loadSettings(); | |
}); | |
}, | |
/** | |
* Load settings and replace existing values in controls. | |
*/ | |
loadSettings: function() { | |
// Data for the AJAX request. | |
let data = { | |
action: 'wptrt_load_parent_theme_mods', | |
nonce: '<?php echo esc_html( wp_create_nonce( 'wptrt_load_parent_theme_mods' ) ); ?>', | |
setting: this.params.choices.setting | |
}; | |
// Make the call. | |
jQuery.post( ajaxurl, data, function( response ) { | |
let settings = []; | |
// Try to decode the response. | |
try { | |
settings = JSON.parse( response ); | |
} catch (error) { | |
// Nothing to do. | |
} | |
// Make sure the response is an object now. | |
if ( _.isObject( settings ) ) { | |
// Loop settings. | |
_.each( settings, function( val, key ) { | |
// Find the control. | |
let control = wp.customize.control( key ); | |
// If the control exists, change its value. | |
if ( control ) { | |
control.setting.set( val ); | |
} | |
} ); | |
} | |
} ); | |
} | |
} ); | |
</script> | |
<?php | |
}, | |
999 | |
); | |
add_action( | |
'wp_ajax_wptrt_load_parent_theme_mods', | |
/** | |
* AJAX Callback. | |
*/ | |
function() { | |
// Security: Check if the nonce is valid. | |
check_ajax_referer( 'wptrt_load_parent_theme_mods', 'nonce' ); | |
// Sanity check: Make sure we've got everything we need. | |
if ( isset( $_POST['action'] ) && 'wptrt_load_parent_theme_mods' === $_POST['action'] && isset( $_POST['setting'] ) ) { | |
// Get the setting-name. | |
$setting = sanitize_text_field( wp_unslash( $_POST['setting'] ) ); | |
// Print the option value. | |
echo wp_json_encode( get_option( $setting, [] ) ); | |
} | |
wp_die(); | |
} | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I had a thought.
theme_mods is a sparse array. I wonder if it would be desired to fill the holes with the parent theme's default values. Doing that is a little trickier.