mirror of
https://github.com/10h30/vietnam-payment-gateways.git
synced 2026-07-19 22:53:52 +09:00
Restructure folder and add options page
This commit is contained in:
@@ -0,0 +1,878 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* RationalOptionPages class
|
||||
*
|
||||
* @category WordPress Development
|
||||
* @package RationalOptionPages
|
||||
* @author Jeremy Hixon <jeremy@jeremyhixon.com>
|
||||
* @copyright Copyright (c) 2016
|
||||
* @link http://jeremyhixon.com
|
||||
* @version 1.0.0
|
||||
*/
|
||||
class RationalOptionPages {
|
||||
/* ==========================================================================
|
||||
Vars
|
||||
========================================================================== */
|
||||
protected $attributes = array(
|
||||
'input' => array(
|
||||
'autocomplete' => false,
|
||||
'autofocus' => false,
|
||||
'disabled' => false,
|
||||
'list' => false,
|
||||
'max' => false,
|
||||
'maxlength' => false,
|
||||
'min' => false,
|
||||
'pattern' => false,
|
||||
'readonly' => false,
|
||||
'required' => false,
|
||||
'size' => false,
|
||||
'step' => false,
|
||||
),
|
||||
'select' => array(
|
||||
'multiple' => false,
|
||||
'size' => 4,
|
||||
),
|
||||
'textarea' => array(
|
||||
'cols' => 20,
|
||||
'rows' => 2,
|
||||
'wrap' => 'soft',
|
||||
),
|
||||
);
|
||||
protected $defaults = array(
|
||||
'add_menu_page' => array(
|
||||
'page_title' => 'Option Page',
|
||||
'menu_title' => 'Option Page',
|
||||
'capability' => 'manage_options',
|
||||
'menu_slug' => 'option_page',
|
||||
'callback' => false,
|
||||
'icon_url' => false,
|
||||
'position' => null,
|
||||
),
|
||||
'add_settings_field' => array(
|
||||
'id' => 'settings_field',
|
||||
'title' => 'Settings Field',
|
||||
'callback' => false,
|
||||
'page' => 'option_page',
|
||||
'section' => 'settings_section',
|
||||
'args' => false,
|
||||
),
|
||||
'add_settings_section' => array(
|
||||
'id' => 'settings_section',
|
||||
'title' => 'Settings Section',
|
||||
'callback' => false,
|
||||
'page' => 'option_page',
|
||||
),
|
||||
'add_submenu_page' => array(
|
||||
'parent_slug' => 'option_page',
|
||||
'page_title' => 'Sub Option Page',
|
||||
'menu_title' => 'Sub Option Page',
|
||||
'capability' => 'manage_options',
|
||||
'menu_slug' => 'sub_option_page',
|
||||
'callback' => false,
|
||||
),
|
||||
);
|
||||
protected $errors;
|
||||
protected $fields = array(
|
||||
'checkbox' => array(
|
||||
'checked' => false,
|
||||
'value' => 'on',
|
||||
),
|
||||
'text' => array(
|
||||
'class' => 'regular-text',
|
||||
'placeholder' => '',
|
||||
'value' => false,
|
||||
),
|
||||
'textarea' => array(
|
||||
'class' => 'large-text',
|
||||
'placeholder' => '',
|
||||
'rows' => 10,
|
||||
'value' => false,
|
||||
),
|
||||
'wp_editor' => array(
|
||||
'wpautop' => true,
|
||||
'media_buttons' => true,
|
||||
'textarea_rows' => 'default',
|
||||
'tabindex' => false,
|
||||
'editor_css' => false,
|
||||
'editor_class' => '',
|
||||
'editor_height' => false,
|
||||
'teeny' => false,
|
||||
'dfw' => false,
|
||||
'tinymce' => true,
|
||||
'quicktags' => true,
|
||||
'drag_drop_upload' => false,
|
||||
),
|
||||
);
|
||||
protected $media_script = false;
|
||||
protected $notices;
|
||||
protected $options;
|
||||
protected $pages = array();
|
||||
protected $subpages = array();
|
||||
protected $points;
|
||||
|
||||
/* ==========================================================================
|
||||
Magic methods
|
||||
========================================================================== */
|
||||
/**
|
||||
* Catches unknown method calls
|
||||
*
|
||||
* @param string $method The method being requested
|
||||
* @param array $arguments Array of arguments passed to the method
|
||||
*/
|
||||
public function __call( $method, $arguments ) {
|
||||
$request = explode( '|', $method );
|
||||
$source = $request[0];
|
||||
$page_key = !empty( $request[1] ) ? $request[1] : false;
|
||||
$section_key = !empty( $request[2] ) ? $request[2] : false;
|
||||
$field_key = !empty( $request[3] ) ? $request[3] : false;
|
||||
|
||||
switch ( $source ) {
|
||||
case 'add_menu_page':
|
||||
case 'add_submenu_page':
|
||||
$this->build_menu_page( $page_key );
|
||||
break;
|
||||
case 'add_settings_section':
|
||||
$this->build_settings_section( $page_key, $section_key );
|
||||
break;
|
||||
case 'add_settings_field':
|
||||
$this->build_settings_field( $page_key, $section_key, $field_key );
|
||||
break;
|
||||
case 'register_setting':
|
||||
$input = $this->sanitize_setting( $page_key, $arguments[0] );
|
||||
return $input;
|
||||
break;
|
||||
default:
|
||||
$this->submit_notice( $method );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class construct method. Configures class and hooks into WordPress.
|
||||
*
|
||||
* @param array $pages Array of option pages
|
||||
*/
|
||||
public function __construct( $pages = array() ) {
|
||||
foreach ( $pages as $page_key => $page_params ) {
|
||||
$this->pages[ $page_key ] = $this->validate_page( $page_key, $page_params );
|
||||
}
|
||||
$this->pages = array_merge( $this->pages, $this->subpages );
|
||||
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
|
||||
add_action( 'admin_head', array( $this, 'admin_head' ) );
|
||||
add_action( 'admin_init', array( $this, 'admin_init' ) );
|
||||
add_action( 'admin_menu', array( $this, 'admin_menu' ) );
|
||||
add_action( 'admin_notices', array( $this, 'admin_notices' ) );
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
WordPress hooks
|
||||
========================================================================== */
|
||||
/**
|
||||
* Action: admin_enqueue_scripts
|
||||
* Conditionally queue's up jQuery and the media uploader script
|
||||
*/
|
||||
public function admin_enqueue_scripts() {
|
||||
if ( $this->media_script ) {
|
||||
wp_enqueue_script( 'jquery' );
|
||||
wp_enqueue_media();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Action: admin_head
|
||||
* Conditionally adds the script to manage media uploads
|
||||
*/
|
||||
public function admin_head() {
|
||||
if ( $this->media_script ) {
|
||||
?> <script>
|
||||
jQuery.noConflict();
|
||||
(function($) {
|
||||
$(function() {
|
||||
var mediaUploader,
|
||||
rationalMediaButton = $( '.rational-media-upload' ),
|
||||
rationalMediaAttachment;
|
||||
|
||||
rationalMediaButton.click( function( e ) {
|
||||
e.preventDefault();
|
||||
var rationalMediaDestination = $( this ).prev( 'input' );
|
||||
|
||||
if ( mediaUploader ) {
|
||||
mediaUploader.open();
|
||||
return;
|
||||
}
|
||||
|
||||
mediaUploader = wp.media.frames.file_frame = wp.media( {
|
||||
title: 'Choose File',
|
||||
button: {
|
||||
text: 'Choose File',
|
||||
},
|
||||
multiple: false,
|
||||
} );
|
||||
|
||||
mediaUploader.on( 'select', function() {
|
||||
rationalMediaAttachment = mediaUploader.state().get('selection').first().toJSON();
|
||||
rationalMediaDestination.val( rationalMediaAttachment.url );
|
||||
} );
|
||||
|
||||
mediaUploader.open();
|
||||
} );
|
||||
});
|
||||
})(jQuery);
|
||||
</script>
|
||||
<?php }
|
||||
}
|
||||
|
||||
/**
|
||||
* Action: admin_init
|
||||
* Registers settings, adds sections and fields
|
||||
*/
|
||||
public function admin_init() {
|
||||
foreach ( $this->pages as $page_key => $page_params ) {
|
||||
// Finalize sanitize
|
||||
if ( empty( $page_params['custom'] ) && !is_array( $page_params['sanitize'] ) ) {
|
||||
$page_params['sanitize'] = array( $this, $page_params['sanitize'] );
|
||||
}
|
||||
|
||||
register_setting(
|
||||
$page_key,
|
||||
$page_key,
|
||||
$page_params['sanitize']
|
||||
);
|
||||
|
||||
if ( !empty( $page_params['sections'] ) ) {
|
||||
foreach ( $page_params['sections'] as $section_key => $section_params ) {
|
||||
// Sort and trim the array for the function
|
||||
$sort_order = array_keys( $this->defaults['add_settings_section'] );
|
||||
$params = $this->sort_array( $section_params, $sort_order );
|
||||
$params = array_slice( $params, 0, count( $this->defaults['add_settings_section'] ) );
|
||||
|
||||
// Finalize callback
|
||||
if ( empty( $params['custom'] ) && !is_array( $params['callback'] ) ) {
|
||||
$params['callback'] = array( $this, $params['callback'] );
|
||||
}
|
||||
|
||||
call_user_func_array( 'add_settings_section', array_values( $params ) );
|
||||
|
||||
if ( !empty( $section_params['fields'] ) ) {
|
||||
foreach ( $section_params['fields'] as $field_key => $field_params ) {
|
||||
// Check for "media" type for adding script
|
||||
if ( !$this->media_script && $field_params['type'] === 'media' ) {
|
||||
$this->media_script = true;
|
||||
}
|
||||
|
||||
// Sort and trim the array for the function
|
||||
$sort_order = array_keys( $this->defaults['add_settings_field'] );
|
||||
$params = $this->sort_array( $field_params, $sort_order );
|
||||
$params = array_slice( $params, 0, count( $this->defaults['add_settings_field'] ) );
|
||||
|
||||
// Add label wrapper on title
|
||||
if (
|
||||
!in_array( $field_params['type'], array( 'radio' ) ) &&
|
||||
( empty( $field_params['no_label'] ) || $field_params['no_label'] === false )
|
||||
) {
|
||||
$params['title'] = "<label for='{$params["id"]}'>".__($params['title'],'text-domain')."</label>";
|
||||
}
|
||||
|
||||
// Finalize callback
|
||||
if ( empty( $params['custom'] ) && !is_array( $params['callback'] ) ) {
|
||||
$params['callback'] = array( $this, $params['callback'] );
|
||||
}
|
||||
|
||||
call_user_func_array( 'add_settings_field', array_values( $params ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Action: admin_menu. Adding the option pages to the admin menu.
|
||||
*/
|
||||
public function admin_menu() {
|
||||
$all_pages = array_merge( $this->pages, $this->subpages );
|
||||
|
||||
foreach ( $all_pages as $page ) {
|
||||
// Sort and trim the array for the function
|
||||
$sort_order = array_keys( $this->defaults[ $page['function'] ] );
|
||||
$params = $this->sort_array( $page, $sort_order );
|
||||
$params = array_slice( $params, 0, count( $this->defaults[ $page['function'] ] ) );
|
||||
|
||||
// Finalize callback
|
||||
$params['callback'] = array( $this, $params['callback'] );
|
||||
|
||||
|
||||
call_user_func_array( $page['function'], array_values( $params ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Action: admin_notices. Spitting out notices when needed.
|
||||
*/
|
||||
public function admin_notices() {
|
||||
// notice-error, notice-warning, notice-success, or notice-info.
|
||||
if ( !empty( $this->errors ) ) {
|
||||
foreach ( $this->errors as $error ) {
|
||||
echo $error;
|
||||
}
|
||||
}
|
||||
if ( !empty( $this->notices ) ) {
|
||||
foreach ( $this->notices as $notice ) {
|
||||
echo $notice;
|
||||
}
|
||||
}
|
||||
|
||||
// update point in array for future reference
|
||||
$this->points['admin_notices'] = true;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Helpers
|
||||
========================================================================== */
|
||||
public function add_page( $page_key, $page_params ) {
|
||||
$this->pages[ $page_key ] = $this->validate_page( $page_key, $page_params );
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the menu page
|
||||
*
|
||||
* @param string $page_key The array key of the page needing built
|
||||
*/
|
||||
protected function build_menu_page( $page_key ) {
|
||||
$page = $this->pages[ $page_key ];
|
||||
$this->options = get_option( $page_key, array() );
|
||||
settings_errors();
|
||||
?><div class="wrap">
|
||||
<h1><?php _e($GLOBALS['title'],'text-domain'); ?></h1><?php
|
||||
|
||||
if ( !empty( $page['sections'] ) ) {
|
||||
?><form action="options.php" method="post"><?php
|
||||
settings_errors( $page_key );
|
||||
settings_fields( $page_key );
|
||||
do_settings_sections( $page['menu_slug'] );
|
||||
if ( $this->has_fields( $page ) ) {
|
||||
submit_button();
|
||||
}
|
||||
?></form><?php
|
||||
}
|
||||
?></div><?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the fields themselves
|
||||
*
|
||||
* @param string $page_key The array key of the page
|
||||
* @param string $section_key The array key of the section
|
||||
* @param string $field_key The array key of the field
|
||||
*/
|
||||
protected function build_settings_field( $page_key, $section_key, $field_key ) {
|
||||
$page = $this->pages[ $page_key ];
|
||||
$section = $page['sections'][ $section_key ];
|
||||
$field = $section['fields'][ $field_key ];
|
||||
|
||||
if ( isset( $field['value'] ) && $field['type'] !== 'checkbox' ) {
|
||||
$field['value'] = !empty( $this->options[ $field['id'] ] ) ? $this->options[ $field['id'] ] : $field['value'];
|
||||
}
|
||||
|
||||
// Additional attributes
|
||||
if ( !empty( $field['attributes'] ) ) {
|
||||
$attributes = array();
|
||||
foreach ( $field['attributes'] as $attribute => $value ) {
|
||||
if ( !empty( $value ) ) {
|
||||
$attributes[] = "{$attribute}='{$value}'";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sanitize field values, unless 'sanitize' was set to false for this field.
|
||||
if ( ( !isset( $field['sanitize'] ) || $field['sanitize'] ) && $field['type'] !== 'wp_editor' ) {
|
||||
if (!empty($field['attributes']) && isset($field['attributes']['multiple']) && $field['attributes']['multiple']) {
|
||||
for ( $i = 0; $i < count( $field['value'] ); $i++ ) {
|
||||
$field['value'][ $i ] = strip_tags($field['value'][ $i ]); // Removes HTML tags
|
||||
$field['value'][ $i ] = esc_attr($field['value'][ $i ]); // Escapes field for HTML attributes
|
||||
}
|
||||
} else {
|
||||
$field['value'] = strip_tags($field['value']); // Removes HTML tags
|
||||
$field['value'] = esc_attr($field['value']); // Escapes field for HTML attributes
|
||||
}
|
||||
}
|
||||
|
||||
switch ( $field['type'] ) {
|
||||
case 'checkbox':
|
||||
$checked = $field['checked'] ? 'checked' : '';
|
||||
if ( isset( $this->options[ $field['id'] ] ) ) {
|
||||
$checked = checked( $field['value'], $this->options[ $field['id'] ], false );
|
||||
}
|
||||
printf(
|
||||
'<label><input %s %s id="%s" name="%s" title="%s" type="checkbox" value="%s"> %s</label>',
|
||||
$checked, // checked
|
||||
!empty( $field['class'] ) ? "class='{$field['class']}'" : '', // class
|
||||
$field['id'], // id
|
||||
"{$page_key}[{$field['id']}]", // name
|
||||
$field['title_attr'], // title
|
||||
$field['value'], // value
|
||||
!empty( $field['text'] ) ? __($field['text'],'text-domain') : '' // text
|
||||
);
|
||||
break;
|
||||
case 'media':
|
||||
$upload_button = sprintf(
|
||||
'<input class="button rational-media-upload" type="button" value="Upload">'
|
||||
);
|
||||
printf(
|
||||
'<input %s id="%s" name="%s" %s title="%s" type="text" value="%s" %s>%s%s',
|
||||
!empty( $field['class'] ) ? "class='{$field['class']}'" : '', // class
|
||||
$field['id'], // id
|
||||
"{$page_key}[{$field['id']}]", // name
|
||||
!empty( $field['placeholder'] ) ? 'placeholder="'.__($field['placeholder'],'text-domain').'"' : '', // placeholder
|
||||
$field['title_attr'], // title
|
||||
$field['value'], // value
|
||||
!empty( $attributes ) ? implode( ' ', $attributes ) : '', // additional attributes
|
||||
$upload_button, // upload button
|
||||
!empty( $field['text'] ) ? '<p class="help">'.__($field['text'],'text-domain').'</p>' : '' // text
|
||||
);
|
||||
break;
|
||||
case 'radio':
|
||||
echo '<fieldset><legend class="screen-reader-text">' . __($field['title'],'text-domain') . '</legend>';
|
||||
$c = 0;
|
||||
foreach ( $field['choices'] as $value => $label ) {
|
||||
$checked = $value === $field['value'] ? 'checked' : '';
|
||||
if ( isset( $this->options[ $field['id'] ] ) ) {
|
||||
$checked = $value === $this->options[ $field['id'] ] ? 'checked' : '';
|
||||
}
|
||||
printf(
|
||||
'<label><input %s %s id="%s" name="%s" type="radio" title="%s" value="%s"> %s</label>%s',
|
||||
$checked, // checked
|
||||
!empty( $field['class'] ) ? "class='{$field['class']}'" : '', // class
|
||||
$field['id'], // id
|
||||
"{$page_key}[{$field['id']}]", // name
|
||||
__($label,'text-domain'), // title
|
||||
$value, // value
|
||||
__($label,'text-domain'), // label
|
||||
$c < count( $field['choices'] ) - 1 ? '<br>' : '' // line-break
|
||||
);
|
||||
$c++;
|
||||
}
|
||||
echo '</fieldset>';
|
||||
break;
|
||||
case 'select':
|
||||
if (!empty($field['attributes']) && isset($field['attributes']['multiple']) && $field['attributes']['multiple']) {
|
||||
$field_tag_name = "{$page_key}[{$field['id']}][]";
|
||||
$field_name = "{$field['id']}[]";
|
||||
}
|
||||
else {
|
||||
$field_tag_name = "{$page_key}[{$field['id']}]";
|
||||
$field_name = "{$field['id']}";
|
||||
}
|
||||
printf(
|
||||
'<select %s %s id="%s" name="%s" title="%s">',
|
||||
!empty( $field['class'] ) ? "class='{$field['class']}'" : '', // class
|
||||
!empty( $attributes ) ? implode(' ', $attributes) : '',
|
||||
$field['id'], // id
|
||||
$field_tag_name, // name
|
||||
__($field['title_attr'],'text-domain') // title
|
||||
);
|
||||
foreach ( $field['choices'] as $value => $text ) {
|
||||
$selected = $value === $field['value'] ? 'selected' : '';
|
||||
if ( isset( $this->options[ $field['id'] ] ) ) {
|
||||
if (!is_array($this->options[ $field['id'] ] ) ) {
|
||||
$selected = $value === $this->options[ $field['id'] ] ? 'selected="selected"' : '';
|
||||
}
|
||||
else {
|
||||
$selected = in_array( $value, $this->options[ $field['id'] ] ) ? 'selected="selected"' : '';
|
||||
}
|
||||
}
|
||||
printf(
|
||||
'<option %s value="%s">%s</option>',
|
||||
$selected, // selected
|
||||
$value, // value
|
||||
__($text,'text-domain') // text
|
||||
);
|
||||
}
|
||||
echo '</select>';
|
||||
break;
|
||||
case 'textarea':
|
||||
printf(
|
||||
'<textarea %s id="%s" name="%s" %s %s %s %s title="%s">%s</textarea>%s',
|
||||
!empty( $field['class'] ) ? "class='{$field['class']}'" : '', // class
|
||||
$field['id'], // id
|
||||
"{$page_key}[{$field['id']}]", // name
|
||||
!empty( $field['placeholder'] ) ? 'placeholder="'.__($field['placeholder'],'text-domain').'"' : '', // placeholder
|
||||
!empty( $field['rows'] ) ? "rows='{$field['rows']}'" : '', // rows
|
||||
!empty( $field['cols'] ) ? "cols='{$field['cols']}'" : '', // cols
|
||||
!empty( $field['wrap'] ) ? "wrap='{$field['wrap']}'" : '', // wrap
|
||||
$field['title_attr'], // title
|
||||
$field['value'], // value
|
||||
!empty( $field['text'] ) ? '<p class="help">'.__($field['text'],'text-domain').'</p>' : '' // text
|
||||
);
|
||||
break;
|
||||
case 'wp_editor':
|
||||
$field['textarea_name'] = "{$page_key}[{$field['id']}]";
|
||||
wp_editor( isset( $field['value'] ) ? $field['value'] : '', $field['id'], array(
|
||||
'textarea_name' => $field['textarea_name'],
|
||||
) );
|
||||
echo !empty( $field['text'] ) ? '<p class="help">'.__($field['text'],'text-domain').'</p>' : '';
|
||||
break;
|
||||
default:
|
||||
printf(
|
||||
'<input %s id="%s" name="%s" %s title="%s" type="%s" value="%s" %s>%s',
|
||||
!empty( $field['class'] ) ? "class='{$field['class']}'" : '', // class
|
||||
$field['id'], // id
|
||||
"{$page_key}[{$field['id']}]", // name
|
||||
!empty( $field['placeholder'] ) ? 'placeholder="'.__($field['placeholder'],'text-domain').'"' : '', // placeholder
|
||||
$field['title_attr'], // title
|
||||
$field['type'], // type
|
||||
$field['value'], // value
|
||||
!empty( $attributes ) ? implode( ' ', $attributes ) : '', // additional attributes
|
||||
!empty( $field['text'] ) ? '<p class="help">'.__($field['text'],'text-domain').'</p>' : '' // text
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the settings sections
|
||||
*
|
||||
* @param string $page_key The array key of the page
|
||||
* @param type $section_key The array key of the section
|
||||
*/
|
||||
protected function build_settings_section( $page_key, $section_key ) {
|
||||
$page = $this->pages[ $page_key ];
|
||||
$section = $page['sections'][ $section_key ];
|
||||
|
||||
echo !empty( $section['text'] ) ? $section['text'] : '';
|
||||
|
||||
if ( !empty( $section['include'] ) ) {
|
||||
include $section['include'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the option page has fields or not
|
||||
*
|
||||
* @param array $page The page array
|
||||
*
|
||||
* @return boolean True if fields are found, false otherwise
|
||||
*/
|
||||
protected function has_fields( $page ) {
|
||||
if ( !empty( $page['sections'] ) ) {
|
||||
foreach ( $page['sections'] as $section ) {
|
||||
if ( !empty( $section['fields'] ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up the option page submissions before submitting to the DB
|
||||
*
|
||||
* @param string $page_key The array key of the page
|
||||
*
|
||||
* @return array The sanitized post input
|
||||
*/
|
||||
protected function sanitize_setting( $page_key, $input ) {
|
||||
$page = $this->pages[ $page_key ];
|
||||
|
||||
if ( !empty( $page['sections'] ) ) {
|
||||
foreach ( $page['sections'] as $section ) {
|
||||
if ( !empty( $section['fields'] ) ) {
|
||||
foreach ( $section['fields'] as $field ) {
|
||||
if ( isset( $field['sanitize'] ) && !$field['sanitize'] ) {
|
||||
continue;
|
||||
}
|
||||
switch ( $field['type'] ) {
|
||||
case 'select':
|
||||
if ( !empty($input[$field['id']]) && !empty($input['attributes']['multiple']) ) {
|
||||
$input[ $field['id'] ] = $input[ $field['id'] ];
|
||||
}
|
||||
break;
|
||||
case 'checkbox':
|
||||
if ( empty( $input[ $field['id'] ] ) ) {
|
||||
$input[ $field['id'] ] = false;
|
||||
}
|
||||
break;
|
||||
case 'wp_editor':
|
||||
$input[ $field['id'] ] = wp_kses_post( $input[ $field['id'] ] );
|
||||
break;
|
||||
default:
|
||||
// Sanitize by default; skip if this field's 'sanitize' setting is false.
|
||||
$input[ $field['id'] ] = sanitize_text_field( $input[ $field['id'] ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts human-readable strings into more machine-friendly formats
|
||||
*
|
||||
* @param string $text String to be formatted
|
||||
* @param string $separator The character that fills in spaces
|
||||
*
|
||||
* @return string Formatted text
|
||||
*/
|
||||
protected function slugify( $text, $separator = '_' ) {
|
||||
$text = preg_replace( '~[^\\pL\d]+~u', $separator, $text );
|
||||
$text = trim( $text, $separator );
|
||||
$text = iconv( 'utf-8', 'windows-1251//TRANSLIT', $text );
|
||||
$text = strtolower( $text );
|
||||
$text = preg_replace( '~[^-\w]+~', '', $text );
|
||||
if ( empty( $text ) ) {
|
||||
return 'n-a';
|
||||
}
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts one array using a second as a guide
|
||||
*
|
||||
* @param array $array Array to be sorted
|
||||
* @param array $order_array Guide array
|
||||
*
|
||||
* @return array Sorted array
|
||||
*/
|
||||
protected function sort_array( $array, $order_array ) {
|
||||
$ordered = array();
|
||||
foreach ( $order_array as $key ) {
|
||||
if ( array_key_exists( $key, $array ) ) {
|
||||
$ordered[ $key ] = $array[ $key ];
|
||||
unset( $array[ $key ] );
|
||||
}
|
||||
}
|
||||
return $ordered + $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Conditionally outputs an error in WordPress admin
|
||||
*
|
||||
* @param string $error The error to be output
|
||||
*/
|
||||
public function submit_error( $error ) {
|
||||
$error = sprintf(
|
||||
'<div class="notice notice-error"><p>%s</p></div>',
|
||||
is_array( $error ) || is_object( $error ) ? '<pre>' . htmlspecialchars( print_r( $error, true ) ) . '</pre>' : $error
|
||||
);
|
||||
if ( empty( $this->points['admin_notices'] ) ) {
|
||||
$this->errors[] = $error;
|
||||
} else {
|
||||
echo $error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Conditionally outputs a notice in WordPress admin
|
||||
*
|
||||
* @param string $notice The text to be output
|
||||
*/
|
||||
public function submit_notice( $notice ) {
|
||||
$notice = sprintf(
|
||||
'<div class="notice notice-info"><p>%s</p></div>',
|
||||
is_array( $notice ) || is_object( $notice ) ? '<pre>' . htmlspecialchars( print_r( $notice, true ) ) . '</pre>' : $notice
|
||||
);
|
||||
if ( empty( $this->points['admin_notices'] ) ) {
|
||||
$this->notices[] = $notice;
|
||||
} else {
|
||||
echo $notice;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the field data submitted to the class
|
||||
*
|
||||
* @param array $field Field array
|
||||
* @param string $page_key Array key of the associated page
|
||||
* @param string $section_key Array key of the associated section
|
||||
* @param string $field_key Array key of the field
|
||||
* @param string $page ID of the associated page
|
||||
* @param type $section ID of the associated section
|
||||
*
|
||||
* @return array The validated field array
|
||||
*/
|
||||
protected function validate_field( $field, $page_key, $section_key, $field_key, $page, $section ) {
|
||||
// Label
|
||||
if ( empty( $field['title'] ) ) {
|
||||
$this->submit_error( __('Field parameter "title" is required','text-domain') );
|
||||
}
|
||||
|
||||
// ID
|
||||
if ( empty( $field['id'] ) ) {
|
||||
$field['id'] = $this->slugify( $field['title'] );
|
||||
}
|
||||
|
||||
// Callback
|
||||
$field['callback'] = empty( $field['callback'] ) ? "add_settings_field|{$page_key}|{$section_key}|{$field_key}" : $field['callback'];
|
||||
|
||||
// Page
|
||||
$field['page'] = $page;
|
||||
|
||||
// Section
|
||||
$field['section'] = $section;
|
||||
|
||||
// Type
|
||||
$field['type'] = empty( $field['type'] ) ? 'text' : $field['type'];
|
||||
|
||||
// Title attribute
|
||||
$field['title_attr'] = empty( $field['title_attr'] ) ? __($field['title'],'text-domain') : $field['title_attr'];
|
||||
|
||||
// Choices
|
||||
if ( empty( $field['choices'] ) && in_array( $field['type'], array( 'radio', 'select' ) ) ) {
|
||||
$this->submit_error( 'Field parameter "choices" is required for the "radio" and "select" type' );
|
||||
}
|
||||
|
||||
// Other attributes
|
||||
if ( !empty( $field['attributes'] ) ) {
|
||||
switch ( $field['type'] ) {
|
||||
case 'select':
|
||||
case 'textarea':
|
||||
$field['attributes'] = wp_parse_args( $field['attributes'], $this->attributes[ $field['type'] ] );
|
||||
break;
|
||||
default:
|
||||
$field['attributes'] = wp_parse_args( $field['attributes'], $this->attributes['input'] );
|
||||
}
|
||||
}
|
||||
|
||||
// Making sure we haven't missed anything
|
||||
switch ( $field['type'] ) {
|
||||
case 'checkbox':
|
||||
$field = wp_parse_args( $field, $this->fields['checkbox'] );
|
||||
break;
|
||||
case 'color':
|
||||
case 'radio':
|
||||
case 'range':
|
||||
break;
|
||||
case 'date':
|
||||
$field['value'] = date( 'Y-m-d', strtotime( $field['value'] ) );
|
||||
$field = wp_parse_args( $field, $this->fields['text'] );
|
||||
break;
|
||||
case 'datetime':
|
||||
case 'datetime-local':
|
||||
$field['value'] = date( 'Y-m-d\TH:i:s', strtotime( $field['value'] ) );
|
||||
$field = wp_parse_args( $field, $this->fields['text'] );
|
||||
break;
|
||||
case 'month':
|
||||
$field['value'] = date( 'Y-m', strtotime( $field['value'] ) );
|
||||
$field = wp_parse_args( $field, $this->fields['text'] );
|
||||
break;
|
||||
case 'textarea':
|
||||
$field = wp_parse_args( $field, $this->fields[ $field['type'] ] );
|
||||
break;
|
||||
case 'time':
|
||||
$field['value'] = date( 'H:i:s', strtotime( $field['value'] ) );
|
||||
$field = wp_parse_args( $field, $this->fields['text'] );
|
||||
break;
|
||||
case 'week':
|
||||
$field['value'] = date( 'Y-\WW', strtotime( $field['value'] ) );
|
||||
$field = wp_parse_args( $field, $this->fields['text'] );
|
||||
break;
|
||||
case 'wp_editor':
|
||||
$field = wp_parse_args( $field, $this->fields['wp_editor'] );
|
||||
break;
|
||||
default:
|
||||
$field = wp_parse_args( $field, $this->fields['text'] );
|
||||
}
|
||||
|
||||
return $field;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the information submitted to the class
|
||||
*
|
||||
* @param string $page_key Array key of the page
|
||||
* @param array $page Array of page parameters
|
||||
* @param string $parent_slug Menu slug of the parent page if there is one
|
||||
*
|
||||
* @return array Validated array of page parameters
|
||||
*/
|
||||
protected function validate_page( $page_key, $page_params, $parent_slug = false ) {
|
||||
// Page title
|
||||
if ( empty( $page_params['page_title'] ) ) {
|
||||
$this->submit_error( __('Page parameter "page_title" is required','text-domain') );
|
||||
}
|
||||
|
||||
// Menu title
|
||||
if ( empty( $page_params['menu_title'] ) ) {
|
||||
$page_params['menu_title'] = __($page_params['page_title'],'text-domain');
|
||||
}
|
||||
|
||||
// Menu slug
|
||||
if ( empty( $page_params['menu_slug'] ) ) {
|
||||
// Basing it off the page title cause it's likely to be more unique than the menu title
|
||||
$page_params['menu_slug'] = $this->slugify( $page_params['page_title'] );
|
||||
}
|
||||
|
||||
// Menu or submenu item?
|
||||
if ( empty( $page_params['parent_slug'] ) && !$parent_slug ) {
|
||||
$page_params['function'] = 'add_menu_page';
|
||||
} else {
|
||||
$page_params['function'] = 'add_submenu_page';
|
||||
$page_params['parent_slug'] = $parent_slug ? $parent_slug : $page_params['parent_slug'];
|
||||
}
|
||||
|
||||
// Callback
|
||||
$page_params['callback'] = "{$page_params['function']}|{$page_key}";
|
||||
|
||||
// Sanitize
|
||||
$page_params['sanitize'] = empty( $page_params['sanitize'] ) ? "register_setting|{$page_key}" : $page_params['sanitize'];
|
||||
|
||||
// Make sure we haven't missed anything
|
||||
$page_params = wp_parse_args( $page_params, $this->defaults[ $page_params['function'] ] );
|
||||
|
||||
// Subpages?
|
||||
if ( !empty( $page_params['subpages'] ) ) {
|
||||
foreach ( $page_params['subpages'] as $subpage_key => $subpage ) {
|
||||
$this->subpages[ $subpage_key ] = $this->validate_page( $subpage_key, $subpage, $page_params['menu_slug'] );
|
||||
}
|
||||
unset( $page_params['subpages'] );
|
||||
}
|
||||
|
||||
// Sections?
|
||||
if ( !empty( $page_params['sections'] ) ) {
|
||||
foreach ( $page_params['sections'] as $section_key => $section_params ) {
|
||||
$page_params['sections'][ $section_key ] = $this->validate_section( $section_params, $page_key, $section_key, $page_params['menu_slug'] );
|
||||
}
|
||||
}
|
||||
|
||||
return $page_params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the section data submitted to the class
|
||||
*
|
||||
* @param array $section Section array
|
||||
* @param string $page_key Array key of the associated page
|
||||
* @param string $section_key Array key of the associated page
|
||||
* @param string $page ID of the associated page
|
||||
*
|
||||
* @return array Validated section array
|
||||
*/
|
||||
protected function validate_section( $section, $page_key, $section_key, $page ) {
|
||||
// Title
|
||||
if ( empty( $section['title'] ) ) {
|
||||
$this->submit_error( __('Section parameter "title" is required','text-domain') );
|
||||
}
|
||||
|
||||
// ID
|
||||
if ( empty( $section['id'] ) ) {
|
||||
$section['id'] = $this->slugify( $section['title'] );
|
||||
}
|
||||
|
||||
// Callback
|
||||
$section['callback'] = empty( $section['callback'] ) ? "add_settings_section|{$page_key}|{$section_key}" : $section['callback'];
|
||||
|
||||
// Page
|
||||
$section['page'] = $page;
|
||||
|
||||
// Fields?
|
||||
if ( !empty( $section['fields'] ) ) {
|
||||
foreach ( $section['fields'] as $field_key => $field_params ) {
|
||||
$section['fields'][ $field_key ] = $this->validate_field( $field_params, $page_key, $section_key, $field_key, $page, $section['id'] );
|
||||
}
|
||||
}
|
||||
|
||||
return $section;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user