mirror of
https://github.com/10h30/vietnam-payment-gateways.git
synced 2026-07-12 03:06:19 +09:00
878 lines
28 KiB
PHP
878 lines
28 KiB
PHP
<?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;
|
|
}
|
|
}
|