Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save ahmadawais/85cf2a4606d651dcab5679082d457347 to your computer and use it in GitHub Desktop.
Save ahmadawais/85cf2a4606d651dcab5679082d457347 to your computer and use it in GitHub Desktop.
Notify on Save only! Plugin demonstration of Customize Setting Validation: validates Customizer settings that contain titles to ensure they are not empty, and then blocks saving the Customizer until they are populated. See https://github.com/xwp/wp-customize-setting-validation
/* global wp, _customizeValidateEntitledSettingsExports */
/* exported customizeValidateEntitledSettings */
var customizeValidateEntitledSettings = ( function( $, api, exports ) {
var self = {
l10n: {
invalid_value: ''
}
};
if ( exports ) {
$.extend( self, exports );
}
/**
* Add validation to a control if it is entitled (has a title or is a title).
*
* @param {wp.customize.Control} setting - Control.
* @param {wp.customize.Value} setting.validationMessage - Validation message.
* @return {boolean} Whether validation was added.
*/
self.addValidationForEntitledSetting = function( setting ) {
var initialValidate;
if ( ! self.isEntitledSetting( setting ) ) {
return false;
}
initialValidate = setting.validate;
/**
* Wrap the setting's validate() method to do validation on the value to be sent to the server.
*
* @param {mixed} newValue - New value being assigned to the setting.
* @returns {*}
*/
setting.validate = function( newValue ) {
var title, setting = this;
// Note: if we want to get the old value, just do oldValue = this.get()
if ( _.isObject( newValue ) ) {
title = newValue.title;
} else {
title = newValue;
}
newValue = initialValidate.call( this, newValue );
if ( _.isString( title ) ) {
setting.validationMessage.set( '' );
}
return newValue;
};
return true;
};
/**
* Return whether the setting is entitled (i.e. if it is a title or has a title).
*
* @param {wp.customize.Setting} setting - Setting.
* @returns {boolean}
*/
self.isEntitledSetting = function( setting ) {
return (
'blogname' === setting.id ||
/^(nav_menu_item|widget_.+?)\[/.test( setting.id )
);
};
api.bind( 'add', function( setting ) {
self.addValidationForEntitledSetting( setting );
} );
return self;
}( jQuery, wp.customize, _customizeValidateEntitledSettingsExports ) );
<?php
/**
* Plugin name: Customize Validate Entitled Settings
* Description: Prevent the site title, nav menu items, and widget instances from being saved without titles. Depends on <a href="https://github.com/xwp/wp-customize-setting-validation">Customize Setting Validation</a> plugin.
* Author: Weston Ruter, XWP.
* Plugin URL: https://gist.github.com/westonruter/1016332b18ee7946dec3
* Version: 0.1
* Author: XWP
* Author URI: https://xwp.co/
* License: GPLv2+
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt
* Text Domain: customize-validate-entitled-settings
*
* Copyright (c) 2015 XWP (https://xwp.co/)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2 or, at
* your discretion, any later version, as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* Class Customize_Validate_Entitled_Settings
*/
class Customize_Validate_Entitled_Settings {
/**
* Most recent instance of this class.
*
* @var Customize_Validate_Entitled_Settings
*/
public static $instance;
/**
* Translated strings
*
* @var array
*/
public $l10n = array();
/**
* Return a new plugin instance.
*
* @return Customize_Validate_Entitled_Settings
*/
public static function instantiate() {
self::$instance = new self();
return self::$instance;
}
/**
* Customize_Validate_Entitled_Settings constructor.
*/
public function __construct() {
add_action( 'customize_validate_settings', array( $this, 'add_filters_for_setting_validation' ) );
add_action( 'customize_controls_enqueue_scripts', array( $this, 'customize_controls_enqueue_scripts' ) );
$this->l10n = array(
'invalid_value' => __( 'You must supply a title.', 'customize-validate-entitled-settings' ),
);
}
/**
* Enqueue scripts.
*
* @action customize_controls_enqueue_scripts
*/
public function customize_controls_enqueue_scripts() {
$handle = 'customize-validate-entitled-setting';
$src = plugin_dir_url( __FILE__ ) . 'customize-validate-entitled-settings.js';
$deps = array( 'customize-setting-validation' );
wp_enqueue_script( $handle, $src, $deps );
$exports = array(
'l10n' => $this->l10n,
);
wp_scripts()->add_data( $handle, 'data', sprintf( 'var _customizeValidateEntitledSettingsExports = %s;', wp_json_encode( $exports ) ) );
}
/**
* Add filters for setting validation.
*
* @param WP_Customize_Manager $wp_customize Customize manager.
*/
public function add_filters_for_setting_validation( WP_Customize_Manager $wp_customize ) {
/*
* Note that the priority needs to be greater than the default priority of 10
* that is set in WP_Customize_Setting::__construct() in the case that an
* existing filter has been added to sanitize the value, and so that we don't
* end up returning a WP_Error instance and cause any existing filters to
* erroneously manipulate a WP_Error object.
*/
$sanitize_priority = 20;
/*
* Note that the following filters will only work for settings that rely on
* the `customize_sanitize_{$setting_id}` as is the default in
* `WP_Customize_Setting::sanitize()`. If, however, a setting subclass
* implements its own non-filter sanitization logic, then this filter may
* not apply.
*/
add_filter( 'customize_sanitize_blogname', array( $this, 'validate_title' ), $sanitize_priority );
// Add filters to all nav menu items and widget instances.
foreach ( $wp_customize->settings() as $setting ) {
if ( $setting instanceof WP_Customize_Nav_Menu_Item_Setting || preg_match( '/^widget_.+\[/', $setting->id ) ) {
add_filter( "customize_sanitize_{$setting->id}", array( $this, 'validate_array_containing_title' ) );
}
}
}
/**
* Validate a title field after sanitizing with ucfirst() for demonstration purposes.
*
* @param string $value Title.
* @return string|WP_Error String if valid, error if not.
*/
public function validate_title( $value ) {
// Sanitize.
if ( is_string( $value ) ) {
$value = ucfirst( $value );
}
// Validate.
if ( doing_action( 'customize_validate_settings' ) && '' === sanitize_text_field( $value ) ) {
$value = new WP_Error( 'invalid_value', $this->l10n['invalid_value'] );
}
return $value;
}
/**
* Validate an array containing a title property.
*
* @param array $data {
* Array containing a title.
*
* @type string [$title] Title.
* }
*
* @return array|WP_Error Returns sanitized array if title is valid, WP_Error otherwise.
*/
public function validate_array_containing_title( $data ) {
if ( ! array_key_exists( 'title', $data ) ) {
return $data;
}
$validated_title = $this->validate_title( $data['title'] );
if ( is_wp_error( $validated_title ) ) {
return $validated_title;
} else {
$data['title'] = $validated_title;
}
return $data;
}
}
add_action( 'plugins_loaded', array( 'Customize_Validate_Entitled_Settings', 'instantiate' ) );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment