Version Description
(2021-09-30) = - Updated the settings page library. - Updated name of templates folder for consistent prefixing. - Added an option so that, if you offer online ordering, you can enter the URL of your order page (can be on the same site or external) and a link to it will display in your contact card. - Past exceptions no longer show in the schedule/opening hours, and are now automatically removed when the options are saved. - Added "Image URL" field to the list of elements on the schema create/edit screen for the Organization schema type. - Moved contact card block into its own category/section.
Download this release
Release Info
Developer | Rustaurius |
Plugin | Business Profile |
Version | 2.1.5 |
Comparing to | |
See all releases |
Code changes from version 2.1.4 to 2.1.5
- assets/css/admin.css +2 -2
- assets/css/contact-card.css +5 -0
- assets/js/block-contact-card.js +1 -1
- assets/js/blocks.build.js +1 -1
- {templates → bpfwp-templates}/contact-card.php +0 -0
- {templates → bpfwp-templates}/opening-hours.php +0 -0
- business-profile.php +13 -5
- includes/class-blocks.php +21 -2
- includes/class-contact-card-widget.php +2 -0
- includes/class-custom-post-types.php +2 -2
- includes/class-deactivation-survey.php +2 -2
- includes/class-installation-walkthrough.php +12 -1
- includes/class-permissions.php +1 -0
- includes/class-review-ask.php +1 -1
- includes/class-sap-scheduler-meta.php +2 -2
- includes/class-schema-cpt.php +9 -1
- includes/class-schemas-manager.php +4 -0
- includes/class-settings.php +67 -3
- includes/class-template-loader.php +1 -1
- includes/helper-functions.php +1 -3
- includes/schemas/class-schema-organization.php +6 -0
- includes/template-functions.php +44 -1
- lib/simple-admin-pages/README.md +434 -431
- lib/simple-admin-pages/classes/AdminPage.Menu.class.php +32 -32
- lib/simple-admin-pages/classes/AdminPage.Submenu.class.php +38 -38
- lib/simple-admin-pages/classes/AdminPage.Themes.class.php +15 -15
- lib/simple-admin-pages/classes/AdminPage.class.php +232 -232
- lib/simple-admin-pages/classes/AdminPageSection.class.php +188 -188
- lib/simple-admin-pages/classes/AdminPageSetting.Address.class.php +156 -156
- lib/simple-admin-pages/classes/AdminPageSetting.Checkbox.class.php +67 -52
- lib/simple-admin-pages/classes/AdminPageSetting.ColorPicker.class.php +39 -39
- lib/simple-admin-pages/classes/AdminPageSetting.Count.class.php +117 -111
- lib/simple-admin-pages/classes/AdminPageSetting.Editor.class.php +44 -44
- lib/simple-admin-pages/classes/AdminPageSetting.FileUpload.class.php +71 -0
- lib/simple-admin-pages/classes/AdminPageSetting.HTML.class.php +33 -33
- lib/simple-admin-pages/classes/AdminPageSetting.Image.class.php +62 -62
- lib/simple-admin-pages/classes/AdminPageSetting.InfiniteTable.class.php +201 -149
- lib/simple-admin-pages/classes/AdminPageSetting.McApiKey.class.php +223 -221
- lib/simple-admin-pages/classes/AdminPageSetting.McListMerge.class.php +255 -255
- lib/simple-admin-pages/classes/AdminPageSetting.Number.class.php +37 -0
- lib/simple-admin-pages/classes/AdminPageSetting.OpeningHours.class.php +182 -182
- lib/simple-admin-pages/classes/AdminPageSetting.Ordering.class.php +94 -0
- lib/simple-admin-pages/classes/AdminPageSetting.Radio.class.php +53 -52
- lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php +703 -703
- lib/simple-admin-pages/classes/AdminPageSetting.Select.class.php +61 -61
- lib/simple-admin-pages/classes/AdminPageSetting.SelectMenu.class.php +57 -57
- lib/simple-admin-pages/classes/AdminPageSetting.SelectPost.class.php +65 -65
- lib/simple-admin-pages/classes/AdminPageSetting.SelectTaxonomy.class.php +68 -68
- lib/simple-admin-pages/classes/AdminPageSetting.Text.class.php +37 -37
- lib/simple-admin-pages/classes/AdminPageSetting.Textarea.class.php +58 -58
- lib/simple-admin-pages/classes/AdminPageSetting.Toggle.class.php +54 -52
- lib/simple-admin-pages/classes/AdminPageSetting.WarningTip.class.php +41 -0
- lib/simple-admin-pages/classes/AdminPageSetting.class.php +358 -344
- lib/simple-admin-pages/classes/Library.class.php +480 -462
- lib/simple-admin-pages/css/admin-settings.css +658 -0
- lib/simple-admin-pages/css/admin.css +247 -247
- lib/simple-admin-pages/css/infinite_table.css +3 -0
- lib/simple-admin-pages/css/ordering.css +27 -0
- lib/simple-admin-pages/css/spectrum.css +507 -0
- lib/simple-admin-pages/img/options-asset-exclamation.png +0 -0
- lib/simple-admin-pages/img/options-asset-info.png +0 -0
- lib/simple-admin-pages/img/options-asset-lock.png +0 -0
- lib/simple-admin-pages/img/options-asset-star.png +0 -0
- lib/simple-admin-pages/img/options-asset-starX2.png +0 -0
- lib/simple-admin-pages/js/address.js +116 -116
- lib/simple-admin-pages/js/admin-settings.js +81 -0
- lib/simple-admin-pages/js/count.js +10 -0
- lib/simple-admin-pages/js/file_upload.js +41 -0
- lib/simple-admin-pages/js/image.js +53 -53
- lib/simple-admin-pages/js/infinite_table.js +85 -0
- lib/simple-admin-pages/js/opening-hours.js +20 -20
- lib/simple-admin-pages/js/ordering.js +38 -0
- lib/simple-admin-pages/js/scheduler.js +403 -403
- lib/simple-admin-pages/js/spectrum.js +2317 -0
- lib/simple-admin-pages/lib/pickadate/legacy.js +9 -9
- lib/simple-admin-pages/lib/pickadate/picker.date.js +4 -4
- lib/simple-admin-pages/lib/pickadate/picker.js +6 -6
- lib/simple-admin-pages/lib/pickadate/picker.time.js +4 -4
- lib/simple-admin-pages/lib/pickadate/themes/default.css +3 -3
- lib/simple-admin-pages/lib/pickadate/themes/rtl.css +2 -2
- lib/simple-admin-pages/simple-admin-pages.php +52 -52
- readme.txt +9 -1
assets/css/admin.css
CHANGED
@@ -1864,5 +1864,5 @@ NEW
|
|
1864 |
.bpfwp-meta-input label {
|
1865 |
display: inline-block;
|
1866 |
vertical-align: text-bottom;
|
1867 |
-
min-width:
|
1868 |
-
}
|
1864 |
.bpfwp-meta-input label {
|
1865 |
display: inline-block;
|
1866 |
vertical-align: text-bottom;
|
1867 |
+
min-width: none;
|
1868 |
+
}
|
assets/css/contact-card.css
CHANGED
@@ -69,6 +69,7 @@
|
|
69 |
.bp-directions:before,
|
70 |
.bp-phone:before,
|
71 |
.bp-contact:before,
|
|
|
72 |
.bp-booking:before,
|
73 |
.bp-opening-hours-brief:before,
|
74 |
.bp-opening-hours .bp-title:before {
|
@@ -97,6 +98,10 @@
|
|
97 |
content: "\f470";
|
98 |
}
|
99 |
|
|
|
|
|
|
|
|
|
100 |
.bp-contact:before {
|
101 |
content: "\f466";
|
102 |
}
|
69 |
.bp-directions:before,
|
70 |
.bp-phone:before,
|
71 |
.bp-contact:before,
|
72 |
+
.bp-ordering-link:before,
|
73 |
.bp-booking:before,
|
74 |
.bp-opening-hours-brief:before,
|
75 |
.bp-opening-hours .bp-title:before {
|
98 |
content: "\f470";
|
99 |
}
|
100 |
|
101 |
+
.bp-ordering-link::before {
|
102 |
+
content: "\f116";
|
103 |
+
}
|
104 |
+
|
105 |
.bp-contact:before {
|
106 |
content: "\f466";
|
107 |
}
|
assets/js/block-contact-card.js
CHANGED
@@ -6,7 +6,7 @@ const { locationOptions } = bpfwp_blocks;
|
|
6 |
|
7 |
registerBlockType( 'business-profile/contact-card', {
|
8 |
title: __( 'Contact Card', 'business-profile' ),
|
9 |
-
category: '
|
10 |
icon: 'location',
|
11 |
attributes: {
|
12 |
location: {
|
6 |
|
7 |
registerBlockType( 'business-profile/contact-card', {
|
8 |
title: __( 'Contact Card', 'business-profile' ),
|
9 |
+
category: 'bpfwp-blocks',
|
10 |
icon: 'location',
|
11 |
attributes: {
|
12 |
location: {
|
assets/js/blocks.build.js
CHANGED
@@ -1 +1 @@
|
|
1 |
-
!function(e){function n(t){if(o[t])return o[t].exports;var l=o[t]={i:t,l:!1,exports:{}};return e[t].call(l.exports,l,l.exports,n),l.l=!0,l.exports}var o={};n.m=e,n.c=o,n.d=function(e,o,t){n.o(e,o)||Object.defineProperty(e,o,{configurable:!1,enumerable:!0,get:t})},n.n=function(e){var o=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(o,"a",o),o},n.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},n.p="",n(n.s=0)}([function(e,n,o){e.exports=o(1)},function(e,n){var o=wp.i18n.__,t=wp.blocks.registerBlockType,l=wp.components,s=l.SelectControl,r=l.CheckboxControl,a=l.PanelBody,i=l.ServerSideRender,c=l.Disabled,p=wp.editor.InspectorControls,u=bpfwp_blocks,h=u.locationOptions;t("business-profile/contact-card",{title:o("Contact Card","business-profile"),category:"
|
1 |
+
!function(e){function n(t){if(o[t])return o[t].exports;var l=o[t]={i:t,l:!1,exports:{}};return e[t].call(l.exports,l,l.exports,n),l.l=!0,l.exports}var o={};n.m=e,n.c=o,n.d=function(e,o,t){n.o(e,o)||Object.defineProperty(e,o,{configurable:!1,enumerable:!0,get:t})},n.n=function(e){var o=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(o,"a",o),o},n.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},n.p="",n(n.s=0)}([function(e,n,o){e.exports=o(1)},function(e,n){var o=wp.i18n.__,t=wp.blocks.registerBlockType,l=wp.components,s=l.SelectControl,r=l.CheckboxControl,a=l.PanelBody,i=l.ServerSideRender,c=l.Disabled,p=wp.editor.InspectorControls,u=bpfwp_blocks,h=u.locationOptions;t("business-profile/contact-card",{title:o("Contact Card","business-profile"),category:"bpfwp-blocks",icon:"location",attributes:{location:{type:"number",default:0},show_name:{type:"boolean",default:!0},show_address:{type:"boolean",default:!0},show_get_directions:{type:"boolean",default:!0},show_phone:{type:"boolean",default:!0},show_contact:{type:"boolean",default:!0},show_opening_hours:{type:"boolean",default:!0},show_opening_hours_brief:{type:"boolean",default:!1},show_map:{type:"boolean",default:!0}},supports:{html:!1},edit:function(e){var n=e.attributes,t=e.setAttributes;return wp.element.createElement("div",null,wp.element.createElement(p,null,wp.element.createElement(a,null,h.length?wp.element.createElement(s,{label:o("Select a Location","business-profile"),value:n.location,onChange:function(e){return t({location:parseInt(e,10)})},options:h}):"",wp.element.createElement(r,{label:o("Show Name","business-profile"),checked:n.show_name,onChange:function(e){t({show_name:e})}}),wp.element.createElement(r,{label:o("Show Address","business-profile"),checked:n.show_address,onChange:function(e){t({show_address:e})}}),wp.element.createElement(r,{label:o("Show link to get directions on Google Maps","business-profile"),checked:n.show_get_directions,onChange:function(e){t({show_get_directions:e})}}),wp.element.createElement(r,{label:o("Show Phone number","business-profile"),checked:n.show_phone,onChange:function(e){t({show_phone:e})}}),wp.element.createElement(r,{label:o("Show contact details","business-profile"),checked:n.show_contact,onChange:function(e){t({show_contact:e})}}),wp.element.createElement(r,{label:o("Show Opening Hours","business-profile"),checked:n.show_opening_hours,onChange:function(e){t({show_opening_hours:e})}}),wp.element.createElement(r,{label:o("Show brief opening hours on one line","business-profile"),checked:n.show_opening_hours_brief,onChange:function(e){t({show_opening_hours_brief:e})}}),wp.element.createElement(r,{label:o("Show Google Map","business-profile"),checked:n.show_map,onChange:function(e){t({show_map:e})}}))),wp.element.createElement(c,null,wp.element.createElement(i,{block:"business-profile/contact-card",attributes:n})))},save:function(){return null}})}]);
|
{templates → bpfwp-templates}/contact-card.php
RENAMED
File without changes
|
{templates → bpfwp-templates}/opening-hours.php
RENAMED
File without changes
|
business-profile.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
* Plugin Name: Five Star Business Profile and Schema
|
4 |
* Plugin URI: https://www.fivestarplugins.com/plugins/business-profile/
|
5 |
* Description: Add schema structured data to any page or post type. Create an SEO friendly contact card with your business info and associated schema. Supports Google Map, opening hours and more.
|
6 |
-
* Version: 2.1.
|
7 |
* Author: Five Star Plugins
|
8 |
* Author URI: https://www.fivestarplugins.com
|
9 |
* License: GPLv3
|
@@ -123,7 +123,7 @@ if ( ! class_exists( 'bpfwpInit', false ) ) :
|
|
123 |
define( 'BPFWP_PLUGIN_DIR', untrailingslashit( plugin_dir_path( __FILE__ ) ) );
|
124 |
define( 'BPFWP_PLUGIN_URL', untrailingslashit( plugin_dir_url( __FILE__ ) ) );
|
125 |
define( 'BPFWP_PLUGIN_FNAME', plugin_basename( __FILE__ ) );
|
126 |
-
define( 'BPFWP_VERSION', '2.0.
|
127 |
}
|
128 |
|
129 |
/**
|
@@ -158,12 +158,14 @@ if ( ! class_exists( 'bpfwpInit', false ) ) :
|
|
158 |
* @return void
|
159 |
*/
|
160 |
protected function instantiate() {
|
|
|
161 |
new bpfwpCompatibility();
|
162 |
new bpfwpIntegrations(); // Deprecated in v1.1.
|
163 |
new bpfwpDeactivationSurvey();
|
164 |
new bpfwpReviewAsk();
|
165 |
new bpfwpInstallationWalkthrough();
|
166 |
-
|
|
|
167 |
$this->schemas = new bpfwpSchemasManager();
|
168 |
$this->settings = new bpfwpSettings();
|
169 |
$this->cpts = new bpfwpCustomPostTypes();
|
@@ -247,7 +249,7 @@ if ( ! class_exists( 'bpfwpInit', false ) ) :
|
|
247 |
$screen = get_current_screen();
|
248 |
$screenID = $screen->id;
|
249 |
$screenPostType = $screen->post_type;
|
250 |
-
$settings = get_option( 'bpfwp-settings' );
|
251 |
|
252 |
if ( $screenID != 'business-profile_page_bpfwp-settings' && $screenID != 'business-profile_page_bpfwp-dashboard' && $screenPostType != 'location' && $screenPostType != 'schema' ) {return;}
|
253 |
|
@@ -298,7 +300,13 @@ if ( ! class_exists( 'bpfwpInit', false ) ) :
|
|
298 |
$screen = get_current_screen();
|
299 |
$screenPostType = $screen->post_type;
|
300 |
|
301 |
-
if (
|
|
|
|
|
|
|
|
|
|
|
|
|
302 |
//if ( $this->settings->get_setting( 'multiple-locations' ) && $this->cpts->location_cpt_slug === $post->post_type ) {
|
303 |
wp_enqueue_style( 'bpfwp-admin-location', BPFWP_PLUGIN_URL . '/assets/css/admin.css', array(), BPFWP_VERSION );
|
304 |
wp_enqueue_script( 'bpfwp-admin-js', BPFWP_PLUGIN_URL . '/assets/js/admin.js', array( 'jquery' ), BPFWP_VERSION, true );
|
3 |
* Plugin Name: Five Star Business Profile and Schema
|
4 |
* Plugin URI: https://www.fivestarplugins.com/plugins/business-profile/
|
5 |
* Description: Add schema structured data to any page or post type. Create an SEO friendly contact card with your business info and associated schema. Supports Google Map, opening hours and more.
|
6 |
+
* Version: 2.1.5
|
7 |
* Author: Five Star Plugins
|
8 |
* Author URI: https://www.fivestarplugins.com
|
9 |
* License: GPLv3
|
123 |
define( 'BPFWP_PLUGIN_DIR', untrailingslashit( plugin_dir_path( __FILE__ ) ) );
|
124 |
define( 'BPFWP_PLUGIN_URL', untrailingslashit( plugin_dir_url( __FILE__ ) ) );
|
125 |
define( 'BPFWP_PLUGIN_FNAME', plugin_basename( __FILE__ ) );
|
126 |
+
define( 'BPFWP_VERSION', '2.0.5' );
|
127 |
}
|
128 |
|
129 |
/**
|
158 |
* @return void
|
159 |
*/
|
160 |
protected function instantiate() {
|
161 |
+
|
162 |
new bpfwpCompatibility();
|
163 |
new bpfwpIntegrations(); // Deprecated in v1.1.
|
164 |
new bpfwpDeactivationSurvey();
|
165 |
new bpfwpReviewAsk();
|
166 |
new bpfwpInstallationWalkthrough();
|
167 |
+
|
168 |
+
$this->permissions = new bpfwpPermissions();
|
169 |
$this->schemas = new bpfwpSchemasManager();
|
170 |
$this->settings = new bpfwpSettings();
|
171 |
$this->cpts = new bpfwpCustomPostTypes();
|
249 |
$screen = get_current_screen();
|
250 |
$screenID = $screen->id;
|
251 |
$screenPostType = $screen->post_type;
|
252 |
+
$settings = get_option( 'bpfwp-settings', [] );
|
253 |
|
254 |
if ( $screenID != 'business-profile_page_bpfwp-settings' && $screenID != 'business-profile_page_bpfwp-dashboard' && $screenPostType != 'location' && $screenPostType != 'schema' ) {return;}
|
255 |
|
300 |
$screen = get_current_screen();
|
301 |
$screenPostType = $screen->post_type;
|
302 |
|
303 |
+
if (
|
304 |
+
'post-new.php' === $hook_suffix
|
305 |
+
|| 'post.php' === $hook_suffix
|
306 |
+
|| $screenPostType == 'location'
|
307 |
+
|| $screenPostType == 'schema'
|
308 |
+
|| $screen->id == 'business-profile_page_bpfwp-settings'
|
309 |
+
) {
|
310 |
//if ( $this->settings->get_setting( 'multiple-locations' ) && $this->cpts->location_cpt_slug === $post->post_type ) {
|
311 |
wp_enqueue_style( 'bpfwp-admin-location', BPFWP_PLUGIN_URL . '/assets/css/admin.css', array(), BPFWP_VERSION );
|
312 |
wp_enqueue_script( 'bpfwp-admin-js', BPFWP_PLUGIN_URL . '/assets/js/admin.js', array( 'jquery' ), BPFWP_VERSION, true );
|
includes/class-blocks.php
CHANGED
@@ -27,7 +27,10 @@ if ( ! class_exists( 'bpfwpBlocks', false ) ) :
|
|
27 |
* @return void
|
28 |
*/
|
29 |
public function run() {
|
|
|
30 |
add_action( 'init', array( $this, 'register' ) );
|
|
|
|
|
31 |
}
|
32 |
|
33 |
/**
|
@@ -46,7 +49,8 @@ if ( ! class_exists( 'bpfwpBlocks', false ) ) :
|
|
46 |
wp_register_script(
|
47 |
'business-profile-blocks',
|
48 |
BPFWP_PLUGIN_URL . '/assets/js/blocks.build.js',
|
49 |
-
array( 'wp-blocks', 'wp-i18n', 'wp-element', 'wp-editor' )
|
|
|
50 |
);
|
51 |
|
52 |
wp_register_script(
|
@@ -60,7 +64,8 @@ if ( ! class_exists( 'bpfwpBlocks', false ) ) :
|
|
60 |
wp_register_style(
|
61 |
'bpfwp-default',
|
62 |
BPFWP_PLUGIN_URL . '/assets/css/contact-card.css',
|
63 |
-
array()
|
|
|
64 |
);
|
65 |
|
66 |
register_block_type( 'business-profile/contact-card', array(
|
@@ -159,5 +164,19 @@ if ( ! class_exists( 'bpfwpBlocks', false ) ) :
|
|
159 |
'before'
|
160 |
);
|
161 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
162 |
}
|
163 |
endif;
|
27 |
* @return void
|
28 |
*/
|
29 |
public function run() {
|
30 |
+
|
31 |
add_action( 'init', array( $this, 'register' ) );
|
32 |
+
|
33 |
+
add_filter( 'block_categories_all', array( $this, 'add_block_category' ) );
|
34 |
}
|
35 |
|
36 |
/**
|
49 |
wp_register_script(
|
50 |
'business-profile-blocks',
|
51 |
BPFWP_PLUGIN_URL . '/assets/js/blocks.build.js',
|
52 |
+
array( 'wp-blocks', 'wp-i18n', 'wp-element', 'wp-editor' ),
|
53 |
+
BPFWP_VERSION
|
54 |
);
|
55 |
|
56 |
wp_register_script(
|
64 |
wp_register_style(
|
65 |
'bpfwp-default',
|
66 |
BPFWP_PLUGIN_URL . '/assets/css/contact-card.css',
|
67 |
+
array(),
|
68 |
+
BPFWP_VERSION
|
69 |
);
|
70 |
|
71 |
register_block_type( 'business-profile/contact-card', array(
|
164 |
'before'
|
165 |
);
|
166 |
}
|
167 |
+
|
168 |
+
/**
|
169 |
+
* Create a new category of blocks to hold our block
|
170 |
+
* @since 2.0.0
|
171 |
+
*/
|
172 |
+
public function add_block_category( $categories ) {
|
173 |
+
|
174 |
+
$categories[] = array(
|
175 |
+
'slug' => 'bpfwp-blocks',
|
176 |
+
'title' => __( 'Five Star Business Profile and Schema', 'business-profile' ),
|
177 |
+
);
|
178 |
+
|
179 |
+
return $categories;
|
180 |
+
}
|
181 |
}
|
182 |
endif;
|
includes/class-contact-card-widget.php
CHANGED
@@ -40,6 +40,7 @@ if ( ! class_exists( 'bpfwpContactCardWidget', false ) ) :
|
|
40 |
'show_address' => __( 'Show Address', 'business-profile' ),
|
41 |
'show_get_directions' => __( 'Show link to get directions on Google Maps', 'business-profile' ),
|
42 |
'show_phone' => __( 'Show Phone number', 'business-profile' ),
|
|
|
43 |
'show_contact' => __( 'Show contact details', 'business-profile' ),
|
44 |
'show_opening_hours' => __( 'Show Opening Hours', 'business-profile' ),
|
45 |
'show_opening_hours_brief' => __( 'Show brief opening hours on one line', 'business-profile' ),
|
@@ -70,6 +71,7 @@ if ( ! class_exists( 'bpfwpContactCardWidget', false ) ) :
|
|
70 |
$title = apply_filters( 'widget_title', $instance['title'] );
|
71 |
echo $args['before_title'] . $title . $args['after_title'];
|
72 |
}
|
|
|
73 |
echo bpwfwp_print_contact_card( $instance );
|
74 |
echo $args['after_widget'];
|
75 |
}
|
40 |
'show_address' => __( 'Show Address', 'business-profile' ),
|
41 |
'show_get_directions' => __( 'Show link to get directions on Google Maps', 'business-profile' ),
|
42 |
'show_phone' => __( 'Show Phone number', 'business-profile' ),
|
43 |
+
'show_ordering_link' => __( 'Show Ordering Link', 'business-profile' ),
|
44 |
'show_contact' => __( 'Show contact details', 'business-profile' ),
|
45 |
'show_opening_hours' => __( 'Show Opening Hours', 'business-profile' ),
|
46 |
'show_opening_hours_brief' => __( 'Show brief opening hours on one line', 'business-profile' ),
|
71 |
$title = apply_filters( 'widget_title', $instance['title'] );
|
72 |
echo $args['before_title'] . $title . $args['after_title'];
|
73 |
}
|
74 |
+
|
75 |
echo bpwfwp_print_contact_card( $instance );
|
76 |
echo $args['after_widget'];
|
77 |
}
|
includes/class-custom-post-types.php
CHANGED
@@ -465,7 +465,7 @@ if ( ! class_exists( 'bpfwpCustomPostTypes', false ) ) :
|
|
465 |
$scheduler = $this->get_scheduler_meta_object( get_post_meta( $post->ID, 'opening_hours', true ) );
|
466 |
|
467 |
// Load required scripts and styles.
|
468 |
-
wp_enqueue_style( 'bpfwp-admin-location-sap', BPFWP_PLUGIN_URL . '/lib/simple-admin-pages/css/admin.css' );
|
469 |
foreach ( $scheduler->styles as $handle => $style ) {
|
470 |
wp_enqueue_style( $handle, BPFWP_PLUGIN_URL . '/lib/simple-admin-pages/' . $style['path'], $style['dependencies'], $style['version'], $style['media'] );
|
471 |
}
|
@@ -528,7 +528,7 @@ if ( ! class_exists( 'bpfwpCustomPostTypes', false ) ) :
|
|
528 |
$schema_fields = $post_is_set ? $bpfwp_controller->schemas->schema_cpts[$post->ID]->schema_class->fields : array();
|
529 |
|
530 |
// Add in the schema selector script and pass post_type, post, page, etc. data to javascript
|
531 |
-
wp_enqueue_script( 'bpfwp-admin-schema-selector', BPFWP_PLUGIN_URL . '/assets/js/admin-schema-selector.js', array( 'jquery' ) );
|
532 |
wp_localize_script(
|
533 |
'bpfwp-admin-schema-selector',
|
534 |
'schema_option_data',
|
465 |
$scheduler = $this->get_scheduler_meta_object( get_post_meta( $post->ID, 'opening_hours', true ) );
|
466 |
|
467 |
// Load required scripts and styles.
|
468 |
+
wp_enqueue_style( 'bpfwp-admin-location-sap', BPFWP_PLUGIN_URL . '/lib/simple-admin-pages/css/admin.css', array(), BPFWP_VERSION );
|
469 |
foreach ( $scheduler->styles as $handle => $style ) {
|
470 |
wp_enqueue_style( $handle, BPFWP_PLUGIN_URL . '/lib/simple-admin-pages/' . $style['path'], $style['dependencies'], $style['version'], $style['media'] );
|
471 |
}
|
528 |
$schema_fields = $post_is_set ? $bpfwp_controller->schemas->schema_cpts[$post->ID]->schema_class->fields : array();
|
529 |
|
530 |
// Add in the schema selector script and pass post_type, post, page, etc. data to javascript
|
531 |
+
wp_enqueue_script( 'bpfwp-admin-schema-selector', BPFWP_PLUGIN_URL . '/assets/js/admin-schema-selector.js', array( 'jquery' ), BPFWP_VERSION );
|
532 |
wp_localize_script(
|
533 |
'bpfwp-admin-schema-selector',
|
534 |
'schema_option_data',
|
includes/class-deactivation-survey.php
CHANGED
@@ -21,8 +21,8 @@ class bpfwpDeactivationSurvey {
|
|
21 |
}
|
22 |
|
23 |
public function enqueue_deactivation_scripts() {
|
24 |
-
wp_enqueue_style( 'bpfwp-deactivation-css', BPFWP_PLUGIN_URL . '/assets/css/plugin-deactivation.css' );
|
25 |
-
wp_enqueue_script( 'bpfwp-deactivation-js', BPFWP_PLUGIN_URL . '/assets/js/plugin-deactivation.js', array( 'jquery' ) );
|
26 |
|
27 |
wp_localize_script( 'bpfwp-deactivation-js', 'bpfwp_deactivation_data', array( 'site_url' => site_url() ) );
|
28 |
}
|
21 |
}
|
22 |
|
23 |
public function enqueue_deactivation_scripts() {
|
24 |
+
wp_enqueue_style( 'bpfwp-deactivation-css', BPFWP_PLUGIN_URL . '/assets/css/plugin-deactivation.css', array(), BPFWP_VERSION );
|
25 |
+
wp_enqueue_script( 'bpfwp-deactivation-js', BPFWP_PLUGIN_URL . '/assets/js/plugin-deactivation.js', array( 'jquery' ), BPFWP_VERSION );
|
26 |
|
27 |
wp_localize_script( 'bpfwp-deactivation-js', 'bpfwp_deactivation_data', array( 'site_url' => site_url() ) );
|
28 |
}
|
includes/class-installation-walkthrough.php
CHANGED
@@ -69,7 +69,18 @@ class bpfwpInstallationWalkthrough {
|
|
69 |
'class' => 'bpfwp-opening-hours'
|
70 |
)
|
71 |
);
|
72 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
|
74 |
add_action('wp_ajax_bpfwp_welcome_add_contact_page', array($this, 'add_contact_page'));
|
75 |
add_action('wp_ajax_bpfwp_welcome_set_contact_information', array($this, 'set_contact_information'));
|
69 |
'class' => 'bpfwp-opening-hours'
|
70 |
)
|
71 |
);
|
72 |
+
|
73 |
+
|
74 |
+
// This is required otherwise SAP_VERSION will throw error.
|
75 |
+
require_once BPFWP_PLUGIN_DIR . '/lib/simple-admin-pages/simple-admin-pages.php';
|
76 |
+
$sap = sap_initialize_library(
|
77 |
+
array(
|
78 |
+
'version' => '2.5.5',
|
79 |
+
'lib_url' => BPFWP_PLUGIN_URL . '/lib/simple-admin-pages/',
|
80 |
+
)
|
81 |
+
);
|
82 |
+
|
83 |
+
$this->scheduler = new sapAdminPageSettingScheduler_2_5_5( $args );
|
84 |
|
85 |
add_action('wp_ajax_bpfwp_welcome_add_contact_page', array($this, 'add_contact_page'));
|
86 |
add_action('wp_ajax_bpfwp_welcome_set_contact_information', array($this, 'set_contact_information'));
|
includes/class-permissions.php
CHANGED
@@ -17,6 +17,7 @@ class bpfwpPermissions {
|
|
17 |
"premium" => 2,
|
18 |
"locations" => 2,
|
19 |
"integrations" => 2,
|
|
|
20 |
);
|
21 |
}
|
22 |
|
17 |
"premium" => 2,
|
18 |
"locations" => 2,
|
19 |
"integrations" => 2,
|
20 |
+
"api_usage" => 2
|
21 |
);
|
22 |
}
|
23 |
|
includes/class-review-ask.php
CHANGED
@@ -68,7 +68,7 @@ class bpfwpReviewAsk {
|
|
68 |
}
|
69 |
|
70 |
public function enqueue_review_ask_scripts() {
|
71 |
-
wp_enqueue_style( 'bpfwp-review-ask-css', BPFWP_PLUGIN_URL . '/assets/css/dashboard-review-ask.css' );
|
72 |
wp_enqueue_script( 'bpfwp-review-ask-js', BPFWP_PLUGIN_URL . '/assets/js/dashboard-review-ask.js', array( 'jquery' ), BPFWP_VERSION, true );
|
73 |
}
|
74 |
|
68 |
}
|
69 |
|
70 |
public function enqueue_review_ask_scripts() {
|
71 |
+
wp_enqueue_style( 'bpfwp-review-ask-css', BPFWP_PLUGIN_URL . '/assets/css/dashboard-review-ask.css', array(),BPFWP_VERSION );
|
72 |
wp_enqueue_script( 'bpfwp-review-ask-js', BPFWP_PLUGIN_URL . '/assets/js/dashboard-review-ask.js', array( 'jquery' ), BPFWP_VERSION, true );
|
73 |
}
|
74 |
|
includes/class-sap-scheduler-meta.php
CHANGED
@@ -15,7 +15,7 @@ defined( 'ABSPATH' ) || exit;
|
|
15 |
|
16 |
require_once BPFWP_PLUGIN_DIR . '/lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php';
|
17 |
|
18 |
-
if ( ! class_exists( 'bpfwpSAPSchedulerMeta', false ) && class_exists( '
|
19 |
|
20 |
/**
|
21 |
* Class to extend the Simple Admin Pages Scheduler component for use on
|
@@ -23,7 +23,7 @@ if ( ! class_exists( 'bpfwpSAPSchedulerMeta', false ) && class_exists( 'sapAdmin
|
|
23 |
*
|
24 |
* @since 1.1
|
25 |
*/
|
26 |
-
class bpfwpSAPSchedulerMeta extends
|
27 |
|
28 |
/**
|
29 |
* Generate an option input field name. The default component appends
|
15 |
|
16 |
require_once BPFWP_PLUGIN_DIR . '/lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php';
|
17 |
|
18 |
+
if ( ! class_exists( 'bpfwpSAPSchedulerMeta', false ) && class_exists( 'sapAdminPageSettingScheduler_2_5_5' ) ) :
|
19 |
|
20 |
/**
|
21 |
* Class to extend the Simple Admin Pages Scheduler component for use on
|
23 |
*
|
24 |
* @since 1.1
|
25 |
*/
|
26 |
+
class bpfwpSAPSchedulerMeta extends sapAdminPageSettingScheduler_2_5_5 {
|
27 |
|
28 |
/**
|
29 |
* Generate an option input field name. The default component appends
|
includes/class-schema-cpt.php
CHANGED
@@ -135,7 +135,7 @@ if ( ! class_exists( 'bpfwpSchemaCPT' ) ) :
|
|
135 |
add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
|
136 |
add_action( 'save_post', array( $this, 'save_meta' ) );
|
137 |
|
138 |
-
wp_enqueue_script( 'schema-cpt', BPFWP_PLUGIN_URL . '/assets/js/schema-cpt.js', array( 'jquery') );
|
139 |
}
|
140 |
|
141 |
|
@@ -345,6 +345,8 @@ if ( ! class_exists( 'bpfwpSchemaCPT' ) ) :
|
|
345 |
* @return int $post_id The current post ID.
|
346 |
*/
|
347 |
public function save_meta( $post_id ) {
|
|
|
|
|
348 |
if ( ! isset( $_POST['bpfwp_schema_meta_nonce'] ) || ! wp_verify_nonce( sanitize_key( $_POST['bpfwp_schema_meta_nonce'] ), 'bpfwp_schema_meta' ) ) { // Input var okay.
|
349 |
return $post_id;
|
350 |
}
|
@@ -356,6 +358,12 @@ if ( ! class_exists( 'bpfwpSchemaCPT' ) ) :
|
|
356 |
if ( ! current_user_can( 'edit_post', $post_id ) ) {
|
357 |
return $post_id;
|
358 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
359 |
|
360 |
if ( ! $this->validate_target( get_post( $post_id ) ) ) {
|
361 |
return $post_id;
|
135 |
add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
|
136 |
add_action( 'save_post', array( $this, 'save_meta' ) );
|
137 |
|
138 |
+
wp_enqueue_script( 'schema-cpt', BPFWP_PLUGIN_URL . '/assets/js/schema-cpt.js', array( 'jquery'), BPFWP_VERSION );
|
139 |
}
|
140 |
|
141 |
|
345 |
* @return int $post_id The current post ID.
|
346 |
*/
|
347 |
public function save_meta( $post_id ) {
|
348 |
+
global $bpfwp_controller;
|
349 |
+
|
350 |
if ( ! isset( $_POST['bpfwp_schema_meta_nonce'] ) || ! wp_verify_nonce( sanitize_key( $_POST['bpfwp_schema_meta_nonce'] ), 'bpfwp_schema_meta' ) ) { // Input var okay.
|
351 |
return $post_id;
|
352 |
}
|
358 |
if ( ! current_user_can( 'edit_post', $post_id ) ) {
|
359 |
return $post_id;
|
360 |
}
|
361 |
+
|
362 |
+
$post = get_post( $post_id );
|
363 |
+
|
364 |
+
if ($post->post_type !== $bpfwp_controller->cpts->schema_cpt_slug) {
|
365 |
+
return;
|
366 |
+
}
|
367 |
|
368 |
if ( ! $this->validate_target( get_post( $post_id ) ) ) {
|
369 |
return $post_id;
|
includes/class-schemas-manager.php
CHANGED
@@ -52,6 +52,10 @@ if ( ! class_exists( 'bpfwpSchemasManager' ) ) :
|
|
52 |
public function create_schema_cpts() {
|
53 |
global $bpfwp_controller;
|
54 |
|
|
|
|
|
|
|
|
|
55 |
require_once BPFWP_PLUGIN_DIR . '/includes/class-schema-cpt.php';
|
56 |
//require_once BPFWP_PLUGIN_DIR . '/includes/class-schema-cpt-post_type.php';
|
57 |
|
52 |
public function create_schema_cpts() {
|
53 |
global $bpfwp_controller;
|
54 |
|
55 |
+
if( ! is_a( $bpfwp_controller, 'bpfwpInit') ) {
|
56 |
+
return;
|
57 |
+
}
|
58 |
+
|
59 |
require_once BPFWP_PLUGIN_DIR . '/includes/class-schema-cpt.php';
|
60 |
//require_once BPFWP_PLUGIN_DIR . '/includes/class-schema-cpt-post_type.php';
|
61 |
|
includes/class-settings.php
CHANGED
@@ -58,6 +58,9 @@ if ( ! class_exists( 'bpfwpSettings' ) ) :
|
|
58 |
add_action( 'init', array( $this, 'set_defaults' ) );
|
59 |
|
60 |
add_action( 'init', array( $this, 'load_settings_panel' ) );
|
|
|
|
|
|
|
61 |
}
|
62 |
|
63 |
/**
|
@@ -102,11 +105,12 @@ if ( ! class_exists( 'bpfwpSettings' ) ) :
|
|
102 |
'show_address' => true,
|
103 |
'show_get_directions' => true,
|
104 |
'show_phone' => true,
|
|
|
105 |
'show_contact' => true,
|
106 |
'show_opening_hours' => true,
|
107 |
'show_opening_hours_brief' => false,
|
108 |
'show_map' => true,
|
109 |
-
'show_image' => false
|
110 |
)
|
111 |
);
|
112 |
|
@@ -253,7 +257,7 @@ if ( ! class_exists( 'bpfwpSettings' ) ) :
|
|
253 |
require_once BPFWP_PLUGIN_DIR . '/lib/simple-admin-pages/simple-admin-pages.php';
|
254 |
$sap = sap_initialize_library(
|
255 |
$args = array(
|
256 |
-
'version' => '2.
|
257 |
'lib_url' => BPFWP_PLUGIN_URL . '/lib/simple-admin-pages/',
|
258 |
)
|
259 |
);
|
@@ -325,6 +329,22 @@ if ( ! class_exists( 'bpfwpSettings' ) ) :
|
|
325 |
)
|
326 |
);
|
327 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
328 |
$sap->add_section(
|
329 |
'bpfwp-settings',
|
330 |
array(
|
@@ -347,7 +367,6 @@ if ( ! class_exists( 'bpfwpSettings' ) ) :
|
|
347 |
'label_for' => 'bpfwp-settings[name]',
|
348 |
'class' => 'bpfwp-name'
|
349 |
)
|
350 |
-
|
351 |
)
|
352 |
);
|
353 |
|
@@ -775,6 +794,51 @@ if ( ! class_exists( 'bpfwpSettings' ) ) :
|
|
775 |
|
776 |
}
|
777 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
778 |
/**
|
779 |
* Array of schema type options
|
780 |
*
|
58 |
add_action( 'init', array( $this, 'set_defaults' ) );
|
59 |
|
60 |
add_action( 'init', array( $this, 'load_settings_panel' ) );
|
61 |
+
|
62 |
+
// Order schedule exceptions and remove past exceptions
|
63 |
+
add_filter( 'sanitize_option_bpfwp-settings', array( $this, 'clean_schedule_exceptions' ), 100 );
|
64 |
}
|
65 |
|
66 |
/**
|
105 |
'show_address' => true,
|
106 |
'show_get_directions' => true,
|
107 |
'show_phone' => true,
|
108 |
+
'show_ordering_link' => true,
|
109 |
'show_contact' => true,
|
110 |
'show_opening_hours' => true,
|
111 |
'show_opening_hours_brief' => false,
|
112 |
'show_map' => true,
|
113 |
+
'show_image' => false
|
114 |
)
|
115 |
);
|
116 |
|
257 |
require_once BPFWP_PLUGIN_DIR . '/lib/simple-admin-pages/simple-admin-pages.php';
|
258 |
$sap = sap_initialize_library(
|
259 |
$args = array(
|
260 |
+
'version' => '2.5.5',
|
261 |
'lib_url' => BPFWP_PLUGIN_URL . '/lib/simple-admin-pages/',
|
262 |
)
|
263 |
);
|
329 |
)
|
330 |
);
|
331 |
|
332 |
+
$sap->add_setting(
|
333 |
+
'bpfwp-settings',
|
334 |
+
'bpfwp-seo',
|
335 |
+
'text',
|
336 |
+
array(
|
337 |
+
'id' => 'ordering-link',
|
338 |
+
'title' => __( 'Ordering Link', 'business-profile' ),
|
339 |
+
'description' => __( 'If you offer online ordering, enter the URL of your order page here (can be on this site or external) and a link to it will display in your contact card.', 'business-profile' ),
|
340 |
+
'placeholder' => 'https://example.com',
|
341 |
+
'args' => array(
|
342 |
+
'label_for' => 'bpfwp-settings[ordering-link]',
|
343 |
+
'class' => 'bpfwp-ordering-link'
|
344 |
+
)
|
345 |
+
)
|
346 |
+
);
|
347 |
+
|
348 |
$sap->add_section(
|
349 |
'bpfwp-settings',
|
350 |
array(
|
367 |
'label_for' => 'bpfwp-settings[name]',
|
368 |
'class' => 'bpfwp-name'
|
369 |
)
|
|
|
370 |
)
|
371 |
);
|
372 |
|
794 |
|
795 |
}
|
796 |
|
797 |
+
/**
|
798 |
+
* Sort the schedule exceptions and remove past exceptions before saving
|
799 |
+
*
|
800 |
+
* @since 2.1.5
|
801 |
+
*/
|
802 |
+
public function clean_schedule_exceptions( $val ) {
|
803 |
+
|
804 |
+
if ( empty( $val['exceptions'] ) ) {
|
805 |
+
return $val;
|
806 |
+
}
|
807 |
+
|
808 |
+
// Sort by date
|
809 |
+
$exceptions = $val['exceptions'];
|
810 |
+
usort( $exceptions, array( $this, 'sort_by_date' ) );
|
811 |
+
|
812 |
+
// Remove exceptions more than a day old
|
813 |
+
$week_ago = time() - 24*3600;
|
814 |
+
for( $i = 0; $i < count( $exceptions ); $i++ ) {
|
815 |
+
if ( strtotime( $exceptions[$i]['date'] ) > $week_ago ) {
|
816 |
+
break;
|
817 |
+
}
|
818 |
+
}
|
819 |
+
if ( $i ) {
|
820 |
+
$exceptions = array_slice( $exceptions, $i );
|
821 |
+
}
|
822 |
+
|
823 |
+
$val['exceptions'] = $exceptions;
|
824 |
+
|
825 |
+
return $val;
|
826 |
+
}
|
827 |
+
|
828 |
+
/**
|
829 |
+
* Sort an associative array by the value's date parameter
|
830 |
+
*
|
831 |
+
* @usedby self::clean_schedule_exceptions()
|
832 |
+
* @since 2.1.5
|
833 |
+
*/
|
834 |
+
public function sort_by_date( $a, $b ) {
|
835 |
+
|
836 |
+
$ad = empty( $a['date'] ) ? 0 : strtotime( $a['date'] );
|
837 |
+
$bd = empty( $b['date'] ) ? 0 : strtotime( $b['date'] );
|
838 |
+
|
839 |
+
return $ad - $bd;
|
840 |
+
}
|
841 |
+
|
842 |
/**
|
843 |
* Array of schema type options
|
844 |
*
|
includes/class-template-loader.php
CHANGED
@@ -66,5 +66,5 @@ class bpfwpTemplateLoader extends Bpfwp_Gamajo_Template_Loader {
|
|
66 |
* @access protected
|
67 |
* @var string
|
68 |
*/
|
69 |
-
protected $plugin_template_directory = 'templates';
|
70 |
}
|
66 |
* @access protected
|
67 |
* @var string
|
68 |
*/
|
69 |
+
protected $plugin_template_directory = 'bpfwp-templates';
|
70 |
}
|
includes/helper-functions.php
CHANGED
@@ -96,6 +96,4 @@ if ( ! function_exists( 'bpfwp_wc_get_most_recent_review_author' ) ) {
|
|
96 |
return $most_recent_comment->comment_author;
|
97 |
}
|
98 |
}
|
99 |
-
}
|
100 |
-
|
101 |
-
?>
|
96 |
return $most_recent_comment->comment_author;
|
97 |
}
|
98 |
}
|
99 |
+
}
|
|
|
|
includes/schemas/class-schema-organization.php
CHANGED
@@ -56,6 +56,12 @@ if ( ! class_exists( 'bpfwpSchemaOrganization' ) ) :
|
|
56 |
'recommended' => true,
|
57 |
'callback' => apply_filters( 'bpfwp_schema_field_callback', 'option blogname', 'name', $this->slug )
|
58 |
) ),
|
|
|
|
|
|
|
|
|
|
|
|
|
59 |
new bpfwpSchemaField( array(
|
60 |
'slug' => 'email',
|
61 |
'name' => 'Email',
|
56 |
'recommended' => true,
|
57 |
'callback' => apply_filters( 'bpfwp_schema_field_callback', 'option blogname', 'name', $this->slug )
|
58 |
) ),
|
59 |
+
new bpfwpSchemaField( array(
|
60 |
+
'slug' => 'image',
|
61 |
+
'name' => 'Image',
|
62 |
+
'input' => 'url',
|
63 |
+
'callback' => apply_filters( 'bpfwp_schema_field_callback', 'function bpfwp_get_post_image_url', 'image', $this->slug )
|
64 |
+
) ),
|
65 |
new bpfwpSchemaField( array(
|
66 |
'slug' => 'email',
|
67 |
'name' => 'Email',
|
includes/template-functions.php
CHANGED
@@ -109,11 +109,12 @@ if ( ! function_exists( 'bpwfwp_print_contact_card' ) ) {
|
|
109 |
'name' => 'bpwfwp_print_name',
|
110 |
'address' => 'bpwfwp_print_address',
|
111 |
'phone' => 'bpwfwp_print_phone',
|
|
|
112 |
'contact' => 'bpwfwp_print_contact',
|
113 |
'exceptions' => 'bpwfwp_print_exceptions',
|
114 |
'opening_hours' => 'bpwfwp_print_opening_hours', // opening-hours
|
115 |
'map' => 'bpwfwp_print_map',
|
116 |
-
'parent_organization' => 'bpfwp_print_parent_organization'
|
117 |
)
|
118 |
);
|
119 |
|
@@ -155,6 +156,44 @@ if ( ! function_exists( 'bpwfwp_print_contact_card' ) ) {
|
|
155 |
}
|
156 |
}
|
157 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
158 |
if ( ! function_exists( 'bpwfwp_print_name' ) ) {
|
159 |
/**
|
160 |
* Print the name.
|
@@ -601,6 +640,10 @@ if ( ! function_exists( 'bpwfwp_print_exceptions' ) ) {
|
|
601 |
);
|
602 |
|
603 |
foreach ( $exceptions as $exception ) {
|
|
|
|
|
|
|
|
|
604 |
|
605 |
if ( array_key_exists( 'time', $exception ) ) {
|
606 |
// special opening-hours
|
109 |
'name' => 'bpwfwp_print_name',
|
110 |
'address' => 'bpwfwp_print_address',
|
111 |
'phone' => 'bpwfwp_print_phone',
|
112 |
+
'ordering-link' => 'bpfwp_print_ordering_link',
|
113 |
'contact' => 'bpwfwp_print_contact',
|
114 |
'exceptions' => 'bpwfwp_print_exceptions',
|
115 |
'opening_hours' => 'bpwfwp_print_opening_hours', // opening-hours
|
116 |
'map' => 'bpwfwp_print_map',
|
117 |
+
'parent_organization' => 'bpfwp_print_parent_organization'
|
118 |
)
|
119 |
);
|
120 |
|
156 |
}
|
157 |
}
|
158 |
|
159 |
+
if ( ! function_exists( 'bpfwp_print_ordering_link' ) ) {
|
160 |
+
/**
|
161 |
+
* Print the menu link
|
162 |
+
*
|
163 |
+
* @since 2.1.5
|
164 |
+
* @access public
|
165 |
+
* @return array
|
166 |
+
*/
|
167 |
+
function bpfwp_print_ordering_link( $location = false ) {
|
168 |
+
|
169 |
+
$return_data = array();
|
170 |
+
|
171 |
+
$link = bpfwp_setting( 'menu', $location );
|
172 |
+
|
173 |
+
$ordering_link = bpfwp_setting( 'ordering-link', $location );
|
174 |
+
|
175 |
+
if( ! $link ) {
|
176 |
+
$return_data['hasMenu'] = $ordering_link;
|
177 |
+
}
|
178 |
+
else {
|
179 |
+
$return_data['hasMenu'] = get_permalink( $link );
|
180 |
+
}
|
181 |
+
|
182 |
+
if ( bpfwp_get_display( 'show_ordering_link' ) && ! empty( $ordering_link ) ) :
|
183 |
+
?>
|
184 |
+
<div class="bp-ordering-link">
|
185 |
+
<a href="<?php echo esc_url( $ordering_link ); ?>" target="blank">
|
186 |
+
<?php _e( 'Place an Order', 'business-profile' ); ?>
|
187 |
+
</a>
|
188 |
+
</div>
|
189 |
+
<?php
|
190 |
+
endif;
|
191 |
+
|
192 |
+
return $return_data;
|
193 |
+
}
|
194 |
+
}
|
195 |
+
|
196 |
+
|
197 |
if ( ! function_exists( 'bpwfwp_print_name' ) ) {
|
198 |
/**
|
199 |
* Print the name.
|
640 |
);
|
641 |
|
642 |
foreach ( $exceptions as $exception ) {
|
643 |
+
|
644 |
+
if ( empty( $exception['date'] ) ) { continue; }
|
645 |
+
|
646 |
+
if ( time() > strtotime( $exception['date'] ) + 24*3600 ) { continue; }
|
647 |
|
648 |
if ( array_key_exists( 'time', $exception ) ) {
|
649 |
// special opening-hours
|
lib/simple-admin-pages/README.md
CHANGED
@@ -1,431 +1,434 @@
|
|
1 |
-
Simple Admin Pages for WordPress
|
2 |
-
================================
|
3 |
-
|
4 |
-
Simple Admin Pages is a very small utility library to easily add new admin
|
5 |
-
pages to the WordPress admin interface. It collects WordPress' useful
|
6 |
-
Settings API into reuseable classes and implements a set of simple controls.
|
7 |
-
|
8 |
-
|
9 |
-
## Settings Pages Supported
|
10 |
-
|
11 |
-
- Settings sub-page
|
12 |
-
- Themes sub-page
|
13 |
-
- Submenu pages for custom menu items
|
14 |
-
|
15 |
-
## General Controls Supported
|
16 |
-
|
17 |
-
- Text field
|
18 |
-
- Textarea field
|
19 |
-
- Image field
|
20 |
-
- Toggle (checkbox to enable/disable setting)
|
21 |
-
- Select dropdown with custom options
|
22 |
-
- Select dropdown of any post type
|
23 |
-
- Select dropdown of any taxonomy type
|
24 |
-
- HTML Content (for instructions, links or other inert text)
|
25 |
-
- WordPress Editor
|
26 |
-
|
27 |
-
## Controls Supported for Special Use Cases
|
28 |
-
|
29 |
-
- Date and Time Scheduler
|
30 |
-
- Google Map Address (with GeoLocation)
|
31 |
-
- Business Opening Hours
|
32 |
-
|
33 |
-
## Usage
|
34 |
-
|
35 |
-
Here's an example of how you can use this library to create an admin page.
|
36 |
-
|
37 |
-
```
|
38 |
-
// Instantiate the Simple Admin Library
|
39 |
-
require_once( 'path/to/simple-admin-pages/simple-admin-pages.php' );
|
40 |
-
$sap = sap_initialize_library(
|
41 |
-
array(
|
42 |
-
'version' => '2.
|
43 |
-
'lib_url' => PLUGIN_URL . '/lib/simple-admin-pages/', // URL path to sap library
|
44 |
-
)
|
45 |
-
);
|
46 |
-
|
47 |
-
// Create a page for the options under the Settings (options) menu
|
48 |
-
$sap->add_page(
|
49 |
-
'options', // Admin menu which this page should be added to
|
50 |
-
array( // Array of key/value pairs matching the AdminPage class constructor variables
|
51 |
-
'id' => 'basic-settings',
|
52 |
-
'title' => __( 'Page Title', 'textdomain' ),
|
53 |
-
'menu_title' => __( 'menu Title', 'textdomain' ),
|
54 |
-
'description' => '',
|
55 |
-
'capability' => 'manage_options' // User permissions access level
|
56 |
-
)
|
57 |
-
);
|
58 |
-
|
59 |
-
// Create a basic details section
|
60 |
-
$sap->add_section(
|
61 |
-
'basic-settings', // Page to add this section to
|
62 |
-
array( // Array of key/value pairs matching the AdminPageSection class constructor variables
|
63 |
-
'id' => 'basic-details',
|
64 |
-
'title' => __( 'Basic Details', 'textdomain' ),
|
65 |
-
'description' => __( 'This section includes some basic details for you to configure.', 'textdomain' )
|
66 |
-
)
|
67 |
-
);
|
68 |
-
|
69 |
-
// Create the options fields
|
70 |
-
$sap->add_setting(
|
71 |
-
'basic-settings', // Page to add this setting to
|
72 |
-
'basic-details', // Section to add this setting to
|
73 |
-
'select', // Type of setting (see sapLibrary::get_setting_classname()
|
74 |
-
array(
|
75 |
-
'id' => 'select-field',
|
76 |
-
'title' => __( 'Select Field', 'textdomain' ),
|
77 |
-
'description' => __( 'A demonstration of the select field type.', 'textdomain' ),
|
78 |
-
'options' => array(
|
79 |
-
'one' => __( 'Option 1', 'textdomain' ),
|
80 |
-
'two' => __( 'Option 2', 'textdomain' ),
|
81 |
-
'three' => __( 'Option 3', 'textdomain' )
|
82 |
-
)
|
83 |
-
)
|
84 |
-
);
|
85 |
-
|
86 |
-
// Allow third-party addons to hook into your settings page
|
87 |
-
$sap = apply_filters( 'sap_page_setup', $sap );
|
88 |
-
|
89 |
-
// Register all admin pages and settings with WordPress
|
90 |
-
$sap->add_admin_menus();
|
91 |
-
```
|
92 |
-
|
93 |
-
Check out the documentation section below for more examples and explanation.
|
94 |
-
|
95 |
-
## License
|
96 |
-
|
97 |
-
Simple Admin Pages is released under the GNU GPL 2 or later.
|
98 |
-
|
99 |
-
## Requirements
|
100 |
-
|
101 |
-
Simple Admin Pages has been tested with WordPress versions 3.5 and above.
|
102 |
-
|
103 |
-
## Roadmap
|
104 |
-
|
105 |
-
- Better documentation
|
106 |
-
- Support custom top-level admin pages
|
107 |
-
- More custom data types
|
108 |
-
|
109 |
-
## Documentation
|
110 |
-
|
111 |
-
### sap_initialize_library()
|
112 |
-
Instantiate the library by loading the simple-admin-pages.php file and calling sap_initialize_library. You'll do everything with the $sap object that is returned.
|
113 |
-
|
114 |
-
**args**
|
115 |
-
An array of properties to pass to the library.
|
116 |
-
|
117 |
-
*version*
|
118 |
-
(required)
|
119 |
-
|
120 |
-
This used to ensure that plugins can play well together even if they use different versions of the library. The version will convert . to _ and append that to the class names which are loaded. If version 1.0 is passed, the library will attempt to load a class named sapAdminPage_1_0.
|
121 |
-
|
122 |
-
*lib_url*
|
123 |
-
(required)
|
124 |
-
|
125 |
-
The lib_url is used to print stylesheets or scripts attached to the library.
|
126 |
-
|
127 |
-
```
|
128 |
-
require_once( 'path/to/simple-admin-pages/simple-admin-pages.php' );
|
129 |
-
$sap = sap_initialize_library(
|
130 |
-
$args = array(
|
131 |
-
'version' => '2.
|
132 |
-
'lib_url' => PLUGIN_URL . '/lib/simple-admin-pages/', // URL path to sap library
|
133 |
-
)
|
134 |
-
);
|
135 |
-
```
|
136 |
-
|
137 |
-
### sapLibrary::add_page()
|
138 |
-
Create a new page with the library by calling the add_page() method. You can attach the page to the options (Settings) or themes (Appearance) menus or any custom menu.
|
139 |
-
|
140 |
-
**type**
|
141 |
-
(required)
|
142 |
-
|
143 |
-
What type of admin menu page to create. Accepts:
|
144 |
-
|
145 |
-
- "options" - A subpage of the Settings menu
|
146 |
-
- "themes" - A subpage of the Appearance menu
|
147 |
-
- "submenu" - A subpage of any top-level menu item
|
148 |
-
|
149 |
-
**args**
|
150 |
-
|
151 |
-
An array of properties to pass to the page.
|
152 |
-
|
153 |
-
*id*
|
154 |
-
(required)
|
155 |
-
|
156 |
-
All settings attached to this page will be stored with the page ID and can be retrieved with get_options( $page_id ).
|
157 |
-
|
158 |
-
*title*
|
159 |
-
(required)
|
160 |
-
|
161 |
-
This will be displayed at the top of the page.
|
162 |
-
|
163 |
-
*menu_title*
|
164 |
-
(required)
|
165 |
-
|
166 |
-
The title to display in the menu.
|
167 |
-
|
168 |
-
*description*
|
169 |
-
(optional)
|
170 |
-
|
171 |
-
Actually, I think this one isn't used at the moment.
|
172 |
-
|
173 |
-
*capability*
|
174 |
-
(required)
|
175 |
-
|
176 |
-
The user permissions access level (capability in WP terms) required to access and edit this page.
|
177 |
-
|
178 |
-
*default_tab*
|
179 |
-
(optional)
|
180 |
-
|
181 |
-
If your page will have multiple tabs, you need to specify a default tab to display when the page is initially loaded. This must match the ID used in the add_section() method. *Leave this parameter out if you don't need any tabs.*
|
182 |
-
|
183 |
-
```
|
184 |
-
$sap->add_page(
|
185 |
-
$type,
|
186 |
-
$args = array(
|
187 |
-
'id' => 'my-settings',
|
188 |
-
'title' => __( 'Page Title', 'textdomain' ),
|
189 |
-
'menu_title' => __( 'menu Title', 'textdomain' ),
|
190 |
-
'description' => '',
|
191 |
-
'capability' => 'manage_options'
|
192 |
-
'default_tab' => 'tab-one',
|
193 |
-
)
|
194 |
-
);
|
195 |
-
```
|
196 |
-
|
197 |
-
### sapLibrary::add_section()
|
198 |
-
Create a new section to attach it to an existing page.
|
199 |
-
|
200 |
-
Sections can act as Tabs or as internal sections within the normal settings flow of a Tab or Page. In other words, you can define a section as a tab, attach a section to another section which is acting as a tab, or ignore tabs altogether to display all of your sections at once. The example below adds a tab and then adds a sub-section to that tab.
|
201 |
-
|
202 |
-
**page_id**
|
203 |
-
|
204 |
-
Page this section should be attached to. Must match the id passed in add_page().
|
205 |
-
|
206 |
-
**args**
|
207 |
-
|
208 |
-
An array of properties to pass to the section.
|
209 |
-
|
210 |
-
*id*
|
211 |
-
|
212 |
-
(required)
|
213 |
-
Unique slug to which settings will be attached.
|
214 |
-
|
215 |
-
*title*
|
216 |
-
(required)
|
217 |
-
|
218 |
-
This will be displayed at the top of the settings section.
|
219 |
-
|
220 |
-
*description*
|
221 |
-
(optional)
|
222 |
-
|
223 |
-
An optional description to display below the title.
|
224 |
-
|
225 |
-
*is_tab*
|
226 |
-
(optional)
|
227 |
-
|
228 |
-
Set this to true if this section should act like a tab.
|
229 |
-
|
230 |
-
*tab*
|
231 |
-
(optional)
|
232 |
-
|
233 |
-
Use this to attach a section to an existing tab.
|
234 |
-
|
235 |
-
#### Add a section to a page with no tabs:
|
236 |
-
```
|
237 |
-
$sap->add_section(
|
238 |
-
$page_id,
|
239 |
-
$args = array(
|
240 |
-
'id' => 'basic-details-section',
|
241 |
-
'title' => __( 'Basic Details', 'textdomain' ),
|
242 |
-
'description' => __( 'This section includes some basic details for you to configure.', 'textdomain' )
|
243 |
-
)
|
244 |
-
);
|
245 |
-
```
|
246 |
-
|
247 |
-
#### Add a tab and a sub-section to a page with tabs:
|
248 |
-
```
|
249 |
-
/**
|
250 |
-
* Create a section that acts as a tab with the is_tab parameter.
|
251 |
-
*/
|
252 |
-
$sap->add_section(
|
253 |
-
$page_id,
|
254 |
-
$args = array(
|
255 |
-
'id' => 'tab-one',
|
256 |
-
'title' => __( 'Tab One', 'textdomain' ),
|
257 |
-
'description' => __( 'This tab includes some settings for you to configure.', 'textdomain' ),
|
258 |
-
'is_tab' => true,
|
259 |
-
)
|
260 |
-
);
|
261 |
-
|
262 |
-
/**
|
263 |
-
* Create a sub-section of the tab we just created with the tab parameter.
|
264 |
-
*/
|
265 |
-
$sap->add_section(
|
266 |
-
$page_id,
|
267 |
-
$args = array(
|
268 |
-
'id' => 'section-one-under-tab-one',
|
269 |
-
'title' => __( 'Section One', 'textdomain' ),
|
270 |
-
'description' => __( 'This section includes some settings for you to configure.', 'textdomain' ),
|
271 |
-
'tab' => 'tab-one',
|
272 |
-
)
|
273 |
-
);
|
274 |
-
```
|
275 |
-
|
276 |
-
### sapLibrary::add_setting()
|
277 |
-
Create a new setting and attach to an existing section.
|
278 |
-
|
279 |
-
There are several types of settings, each with their own input arguments. I'll try to document it more in the future. For now, check out the AdminPageSetting.*.class.php files in /classes/.
|
280 |
-
|
281 |
-
**page_id**
|
282 |
-
(required)
|
283 |
-
|
284 |
-
Page this setting should be attached to. Must match the id passed in add_page().
|
285 |
-
|
286 |
-
**section_id**
|
287 |
-
(required)
|
288 |
-
|
289 |
-
Section this setting should be attached to. Must match the id passed in add_setting().
|
290 |
-
|
291 |
-
**type**
|
292 |
-
(required)
|
293 |
-
|
294 |
-
Type of setting to add. There are currently several types supported and you can extend the library with your own. I'll try to document this further. For now, you can see all the types supported by default at sapLibrary::get_setting_classname().
|
295 |
-
|
296 |
-
**args**
|
297 |
-
|
298 |
-
An array of properties to pass to the setting.
|
299 |
-
|
300 |
-
*id*
|
301 |
-
(required)
|
302 |
-
|
303 |
-
Unique slug under which the setting will be saved. You would then retrieve the setting with:
|
304 |
-
|
305 |
-
```
|
306 |
-
$options = get_option( $page_id );
|
307 |
-
$options[$setting_id];
|
308 |
-
```
|
309 |
-
|
310 |
-
*title*
|
311 |
-
(required)
|
312 |
-
|
313 |
-
Title of the setting. Typically acts as the field label.
|
314 |
-
|
315 |
-
*description*
|
316 |
-
(optional)
|
317 |
-
|
318 |
-
An optional description to display with the setting. Useful for instructions.
|
319 |
-
|
320 |
-
*...*
|
321 |
-
|
322 |
-
Several setting types have additional parameters. I'll try to document them further.
|
323 |
-
|
324 |
-
```
|
325 |
-
$sap->add_setting(
|
326 |
-
$page_id,
|
327 |
-
$section_id,
|
328 |
-
$type,
|
329 |
-
array(
|
330 |
-
'id' => 'my-first-setting',
|
331 |
-
'title' => __( 'My First Setting', 'textdomain' ),
|
332 |
-
'description' => __( 'A demonstration of my first setting', 'textdomain' );
|
333 |
-
...
|
334 |
-
)
|
335 |
-
);
|
336 |
-
```
|
337 |
-
|
338 |
-
### sapLibrary::add_admin_menus()
|
339 |
-
Once everything is configured, run this method to register the pages with WordPress.
|
340 |
-
|
341 |
-
```
|
342 |
-
// Before you run add_admin_menus, filter the whole library so that
|
343 |
-
// third-party addons can hook into your settings page to add new settings
|
344 |
-
// or adjust existing ones.
|
345 |
-
$sap = apply_filters( 'sap_page_setup', $sap );
|
346 |
-
|
347 |
-
$sap->add_admin_menus();
|
348 |
-
```
|
349 |
-
|
350 |
-
### Backwards Compatibility
|
351 |
-
Version 2.0 introduced changes which break backwards compatibility due to the way that the library now stores data in the database. If you are upgrading the version of this library used in your plugin or theme, you must call ```$sap->port_data(2);``` **after** you have declared all of your settings but **before** you call ```$sap->add_admin_menus();```.
|
352 |
-
|
353 |
-
*Note: to ensure all of the old options are found and ported, you shouldn't change any of the structure or ids of your settings. Just drop this method into your existing flow.*
|
354 |
-
|
355 |
-
This changes the way that your settings are stored in the database. Previously, each setting was stored as its own option. Now all the settings on a page are stored in one row.
|
356 |
-
|
357 |
-
You will need to update your plugin to retrieve the settings from their new location. If you previously accessed a setting this way:
|
358 |
-
|
359 |
-
```
|
360 |
-
$my_setting = get_option( $my_setting_id );
|
361 |
-
```
|
362 |
-
|
363 |
-
You should now access the setting this way:
|
364 |
-
|
365 |
-
```
|
366 |
-
$all_page_settings = get_option( $settings_page_id );
|
367 |
-
$all_page_settings[ $my_setting_id ];
|
368 |
-
```
|
369 |
-
|
370 |
-
## Changelog
|
371 |
-
|
372 |
-
- 2.
|
373 |
-
-
|
374 |
-
|
375 |
-
|
376 |
-
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
-
|
381 |
-
-
|
382 |
-
|
383 |
-
- 2.
|
384 |
-
-
|
385 |
-
|
386 |
-
- 2.0 -
|
387 |
-
- Allow
|
388 |
-
|
389 |
-
- 2.0
|
390 |
-
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
-
|
395 |
-
-
|
396 |
-
|
397 |
-
|
398 |
-
-
|
399 |
-
-
|
400 |
-
|
401 |
-
|
402 |
-
-
|
403 |
-
-
|
404 |
-
|
405 |
-
|
406 |
-
-
|
407 |
-
-
|
408 |
-
|
409 |
-
- 2.0.a.
|
410 |
-
-
|
411 |
-
|
412 |
-
|
413 |
-
-
|
414 |
-
|
415 |
-
-
|
416 |
-
- Fix
|
417 |
-
|
418 |
-
|
419 |
-
-
|
420 |
-
- Add
|
421 |
-
|
422 |
-
|
423 |
-
-
|
424 |
-
-
|
425 |
-
|
426 |
-
-
|
427 |
-
-
|
428 |
-
|
429 |
-
|
430 |
-
-
|
431 |
-
-
|
|
|
|
|
|
1 |
+
Simple Admin Pages for WordPress
|
2 |
+
================================
|
3 |
+
|
4 |
+
Simple Admin Pages is a very small utility library to easily add new admin
|
5 |
+
pages to the WordPress admin interface. It collects WordPress' useful
|
6 |
+
Settings API into reuseable classes and implements a set of simple controls.
|
7 |
+
|
8 |
+
|
9 |
+
## Settings Pages Supported
|
10 |
+
|
11 |
+
- Settings sub-page
|
12 |
+
- Themes sub-page
|
13 |
+
- Submenu pages for custom menu items
|
14 |
+
|
15 |
+
## General Controls Supported
|
16 |
+
|
17 |
+
- Text field
|
18 |
+
- Textarea field
|
19 |
+
- Image field
|
20 |
+
- Toggle (checkbox to enable/disable setting)
|
21 |
+
- Select dropdown with custom options
|
22 |
+
- Select dropdown of any post type
|
23 |
+
- Select dropdown of any taxonomy type
|
24 |
+
- HTML Content (for instructions, links or other inert text)
|
25 |
+
- WordPress Editor
|
26 |
+
|
27 |
+
## Controls Supported for Special Use Cases
|
28 |
+
|
29 |
+
- Date and Time Scheduler
|
30 |
+
- Google Map Address (with GeoLocation)
|
31 |
+
- Business Opening Hours
|
32 |
+
|
33 |
+
## Usage
|
34 |
+
|
35 |
+
Here's an example of how you can use this library to create an admin page.
|
36 |
+
|
37 |
+
```
|
38 |
+
// Instantiate the Simple Admin Library
|
39 |
+
require_once( 'path/to/simple-admin-pages/simple-admin-pages.php' );
|
40 |
+
$sap = sap_initialize_library(
|
41 |
+
array(
|
42 |
+
'version' => '2.4.0', // Version of the library
|
43 |
+
'lib_url' => PLUGIN_URL . '/lib/simple-admin-pages/', // URL path to sap library
|
44 |
+
)
|
45 |
+
);
|
46 |
+
|
47 |
+
// Create a page for the options under the Settings (options) menu
|
48 |
+
$sap->add_page(
|
49 |
+
'options', // Admin menu which this page should be added to
|
50 |
+
array( // Array of key/value pairs matching the AdminPage class constructor variables
|
51 |
+
'id' => 'basic-settings',
|
52 |
+
'title' => __( 'Page Title', 'textdomain' ),
|
53 |
+
'menu_title' => __( 'menu Title', 'textdomain' ),
|
54 |
+
'description' => '',
|
55 |
+
'capability' => 'manage_options' // User permissions access level
|
56 |
+
)
|
57 |
+
);
|
58 |
+
|
59 |
+
// Create a basic details section
|
60 |
+
$sap->add_section(
|
61 |
+
'basic-settings', // Page to add this section to
|
62 |
+
array( // Array of key/value pairs matching the AdminPageSection class constructor variables
|
63 |
+
'id' => 'basic-details',
|
64 |
+
'title' => __( 'Basic Details', 'textdomain' ),
|
65 |
+
'description' => __( 'This section includes some basic details for you to configure.', 'textdomain' )
|
66 |
+
)
|
67 |
+
);
|
68 |
+
|
69 |
+
// Create the options fields
|
70 |
+
$sap->add_setting(
|
71 |
+
'basic-settings', // Page to add this setting to
|
72 |
+
'basic-details', // Section to add this setting to
|
73 |
+
'select', // Type of setting (see sapLibrary::get_setting_classname()
|
74 |
+
array(
|
75 |
+
'id' => 'select-field',
|
76 |
+
'title' => __( 'Select Field', 'textdomain' ),
|
77 |
+
'description' => __( 'A demonstration of the select field type.', 'textdomain' ),
|
78 |
+
'options' => array(
|
79 |
+
'one' => __( 'Option 1', 'textdomain' ),
|
80 |
+
'two' => __( 'Option 2', 'textdomain' ),
|
81 |
+
'three' => __( 'Option 3', 'textdomain' )
|
82 |
+
)
|
83 |
+
)
|
84 |
+
);
|
85 |
+
|
86 |
+
// Allow third-party addons to hook into your settings page
|
87 |
+
$sap = apply_filters( 'sap_page_setup', $sap );
|
88 |
+
|
89 |
+
// Register all admin pages and settings with WordPress
|
90 |
+
$sap->add_admin_menus();
|
91 |
+
```
|
92 |
+
|
93 |
+
Check out the documentation section below for more examples and explanation.
|
94 |
+
|
95 |
+
## License
|
96 |
+
|
97 |
+
Simple Admin Pages is released under the GNU GPL 2 or later.
|
98 |
+
|
99 |
+
## Requirements
|
100 |
+
|
101 |
+
Simple Admin Pages has been tested with WordPress versions 3.5 and above.
|
102 |
+
|
103 |
+
## Roadmap
|
104 |
+
|
105 |
+
- Better documentation
|
106 |
+
- Support custom top-level admin pages
|
107 |
+
- More custom data types
|
108 |
+
|
109 |
+
## Documentation
|
110 |
+
|
111 |
+
### sap_initialize_library()
|
112 |
+
Instantiate the library by loading the simple-admin-pages.php file and calling sap_initialize_library. You'll do everything with the $sap object that is returned.
|
113 |
+
|
114 |
+
**args**
|
115 |
+
An array of properties to pass to the library.
|
116 |
+
|
117 |
+
*version*
|
118 |
+
(required)
|
119 |
+
|
120 |
+
This used to ensure that plugins can play well together even if they use different versions of the library. The version will convert . to _ and append that to the class names which are loaded. If version 1.0 is passed, the library will attempt to load a class named sapAdminPage_1_0.
|
121 |
+
|
122 |
+
*lib_url*
|
123 |
+
(required)
|
124 |
+
|
125 |
+
The lib_url is used to print stylesheets or scripts attached to the library.
|
126 |
+
|
127 |
+
```
|
128 |
+
require_once( 'path/to/simple-admin-pages/simple-admin-pages.php' );
|
129 |
+
$sap = sap_initialize_library(
|
130 |
+
$args = array(
|
131 |
+
'version' => '2.4.0', // Version of the library
|
132 |
+
'lib_url' => PLUGIN_URL . '/lib/simple-admin-pages/', // URL path to sap library
|
133 |
+
)
|
134 |
+
);
|
135 |
+
```
|
136 |
+
|
137 |
+
### sapLibrary::add_page()
|
138 |
+
Create a new page with the library by calling the add_page() method. You can attach the page to the options (Settings) or themes (Appearance) menus or any custom menu.
|
139 |
+
|
140 |
+
**type**
|
141 |
+
(required)
|
142 |
+
|
143 |
+
What type of admin menu page to create. Accepts:
|
144 |
+
|
145 |
+
- "options" - A subpage of the Settings menu
|
146 |
+
- "themes" - A subpage of the Appearance menu
|
147 |
+
- "submenu" - A subpage of any top-level menu item
|
148 |
+
|
149 |
+
**args**
|
150 |
+
|
151 |
+
An array of properties to pass to the page.
|
152 |
+
|
153 |
+
*id*
|
154 |
+
(required)
|
155 |
+
|
156 |
+
All settings attached to this page will be stored with the page ID and can be retrieved with get_options( $page_id ).
|
157 |
+
|
158 |
+
*title*
|
159 |
+
(required)
|
160 |
+
|
161 |
+
This will be displayed at the top of the page.
|
162 |
+
|
163 |
+
*menu_title*
|
164 |
+
(required)
|
165 |
+
|
166 |
+
The title to display in the menu.
|
167 |
+
|
168 |
+
*description*
|
169 |
+
(optional)
|
170 |
+
|
171 |
+
Actually, I think this one isn't used at the moment.
|
172 |
+
|
173 |
+
*capability*
|
174 |
+
(required)
|
175 |
+
|
176 |
+
The user permissions access level (capability in WP terms) required to access and edit this page.
|
177 |
+
|
178 |
+
*default_tab*
|
179 |
+
(optional)
|
180 |
+
|
181 |
+
If your page will have multiple tabs, you need to specify a default tab to display when the page is initially loaded. This must match the ID used in the add_section() method. *Leave this parameter out if you don't need any tabs.*
|
182 |
+
|
183 |
+
```
|
184 |
+
$sap->add_page(
|
185 |
+
$type,
|
186 |
+
$args = array(
|
187 |
+
'id' => 'my-settings',
|
188 |
+
'title' => __( 'Page Title', 'textdomain' ),
|
189 |
+
'menu_title' => __( 'menu Title', 'textdomain' ),
|
190 |
+
'description' => '',
|
191 |
+
'capability' => 'manage_options'
|
192 |
+
'default_tab' => 'tab-one',
|
193 |
+
)
|
194 |
+
);
|
195 |
+
```
|
196 |
+
|
197 |
+
### sapLibrary::add_section()
|
198 |
+
Create a new section to attach it to an existing page.
|
199 |
+
|
200 |
+
Sections can act as Tabs or as internal sections within the normal settings flow of a Tab or Page. In other words, you can define a section as a tab, attach a section to another section which is acting as a tab, or ignore tabs altogether to display all of your sections at once. The example below adds a tab and then adds a sub-section to that tab.
|
201 |
+
|
202 |
+
**page_id**
|
203 |
+
|
204 |
+
Page this section should be attached to. Must match the id passed in add_page().
|
205 |
+
|
206 |
+
**args**
|
207 |
+
|
208 |
+
An array of properties to pass to the section.
|
209 |
+
|
210 |
+
*id*
|
211 |
+
|
212 |
+
(required)
|
213 |
+
Unique slug to which settings will be attached.
|
214 |
+
|
215 |
+
*title*
|
216 |
+
(required)
|
217 |
+
|
218 |
+
This will be displayed at the top of the settings section.
|
219 |
+
|
220 |
+
*description*
|
221 |
+
(optional)
|
222 |
+
|
223 |
+
An optional description to display below the title.
|
224 |
+
|
225 |
+
*is_tab*
|
226 |
+
(optional)
|
227 |
+
|
228 |
+
Set this to true if this section should act like a tab.
|
229 |
+
|
230 |
+
*tab*
|
231 |
+
(optional)
|
232 |
+
|
233 |
+
Use this to attach a section to an existing tab.
|
234 |
+
|
235 |
+
#### Add a section to a page with no tabs:
|
236 |
+
```
|
237 |
+
$sap->add_section(
|
238 |
+
$page_id,
|
239 |
+
$args = array(
|
240 |
+
'id' => 'basic-details-section',
|
241 |
+
'title' => __( 'Basic Details', 'textdomain' ),
|
242 |
+
'description' => __( 'This section includes some basic details for you to configure.', 'textdomain' )
|
243 |
+
)
|
244 |
+
);
|
245 |
+
```
|
246 |
+
|
247 |
+
#### Add a tab and a sub-section to a page with tabs:
|
248 |
+
```
|
249 |
+
/**
|
250 |
+
* Create a section that acts as a tab with the is_tab parameter.
|
251 |
+
*/
|
252 |
+
$sap->add_section(
|
253 |
+
$page_id,
|
254 |
+
$args = array(
|
255 |
+
'id' => 'tab-one',
|
256 |
+
'title' => __( 'Tab One', 'textdomain' ),
|
257 |
+
'description' => __( 'This tab includes some settings for you to configure.', 'textdomain' ),
|
258 |
+
'is_tab' => true,
|
259 |
+
)
|
260 |
+
);
|
261 |
+
|
262 |
+
/**
|
263 |
+
* Create a sub-section of the tab we just created with the tab parameter.
|
264 |
+
*/
|
265 |
+
$sap->add_section(
|
266 |
+
$page_id,
|
267 |
+
$args = array(
|
268 |
+
'id' => 'section-one-under-tab-one',
|
269 |
+
'title' => __( 'Section One', 'textdomain' ),
|
270 |
+
'description' => __( 'This section includes some settings for you to configure.', 'textdomain' ),
|
271 |
+
'tab' => 'tab-one',
|
272 |
+
)
|
273 |
+
);
|
274 |
+
```
|
275 |
+
|
276 |
+
### sapLibrary::add_setting()
|
277 |
+
Create a new setting and attach to an existing section.
|
278 |
+
|
279 |
+
There are several types of settings, each with their own input arguments. I'll try to document it more in the future. For now, check out the AdminPageSetting.*.class.php files in /classes/.
|
280 |
+
|
281 |
+
**page_id**
|
282 |
+
(required)
|
283 |
+
|
284 |
+
Page this setting should be attached to. Must match the id passed in add_page().
|
285 |
+
|
286 |
+
**section_id**
|
287 |
+
(required)
|
288 |
+
|
289 |
+
Section this setting should be attached to. Must match the id passed in add_setting().
|
290 |
+
|
291 |
+
**type**
|
292 |
+
(required)
|
293 |
+
|
294 |
+
Type of setting to add. There are currently several types supported and you can extend the library with your own. I'll try to document this further. For now, you can see all the types supported by default at sapLibrary::get_setting_classname().
|
295 |
+
|
296 |
+
**args**
|
297 |
+
|
298 |
+
An array of properties to pass to the setting.
|
299 |
+
|
300 |
+
*id*
|
301 |
+
(required)
|
302 |
+
|
303 |
+
Unique slug under which the setting will be saved. You would then retrieve the setting with:
|
304 |
+
|
305 |
+
```
|
306 |
+
$options = get_option( $page_id );
|
307 |
+
$options[$setting_id];
|
308 |
+
```
|
309 |
+
|
310 |
+
*title*
|
311 |
+
(required)
|
312 |
+
|
313 |
+
Title of the setting. Typically acts as the field label.
|
314 |
+
|
315 |
+
*description*
|
316 |
+
(optional)
|
317 |
+
|
318 |
+
An optional description to display with the setting. Useful for instructions.
|
319 |
+
|
320 |
+
*...*
|
321 |
+
|
322 |
+
Several setting types have additional parameters. I'll try to document them further.
|
323 |
+
|
324 |
+
```
|
325 |
+
$sap->add_setting(
|
326 |
+
$page_id,
|
327 |
+
$section_id,
|
328 |
+
$type,
|
329 |
+
array(
|
330 |
+
'id' => 'my-first-setting',
|
331 |
+
'title' => __( 'My First Setting', 'textdomain' ),
|
332 |
+
'description' => __( 'A demonstration of my first setting', 'textdomain' );
|
333 |
+
...
|
334 |
+
)
|
335 |
+
);
|
336 |
+
```
|
337 |
+
|
338 |
+
### sapLibrary::add_admin_menus()
|
339 |
+
Once everything is configured, run this method to register the pages with WordPress.
|
340 |
+
|
341 |
+
```
|
342 |
+
// Before you run add_admin_menus, filter the whole library so that
|
343 |
+
// third-party addons can hook into your settings page to add new settings
|
344 |
+
// or adjust existing ones.
|
345 |
+
$sap = apply_filters( 'sap_page_setup', $sap );
|
346 |
+
|
347 |
+
$sap->add_admin_menus();
|
348 |
+
```
|
349 |
+
|
350 |
+
### Backwards Compatibility
|
351 |
+
Version 2.0 introduced changes which break backwards compatibility due to the way that the library now stores data in the database. If you are upgrading the version of this library used in your plugin or theme, you must call ```$sap->port_data(2);``` **after** you have declared all of your settings but **before** you call ```$sap->add_admin_menus();```.
|
352 |
+
|
353 |
+
*Note: to ensure all of the old options are found and ported, you shouldn't change any of the structure or ids of your settings. Just drop this method into your existing flow.*
|
354 |
+
|
355 |
+
This changes the way that your settings are stored in the database. Previously, each setting was stored as its own option. Now all the settings on a page are stored in one row.
|
356 |
+
|
357 |
+
You will need to update your plugin to retrieve the settings from their new location. If you previously accessed a setting this way:
|
358 |
+
|
359 |
+
```
|
360 |
+
$my_setting = get_option( $my_setting_id );
|
361 |
+
```
|
362 |
+
|
363 |
+
You should now access the setting this way:
|
364 |
+
|
365 |
+
```
|
366 |
+
$all_page_settings = get_option( $settings_page_id );
|
367 |
+
$all_page_settings[ $my_setting_id ];
|
368 |
+
```
|
369 |
+
|
370 |
+
## Changelog
|
371 |
+
|
372 |
+
- 2.4.0 - 2020-12-04
|
373 |
+
- Updating to make this a more global library that can be used by multiple plugins.
|
374 |
+
|
375 |
+
- 2.3.0 - 2019-03-18
|
376 |
+
- Update pickadate.js to 3.6.1 to fix regression in Chromium
|
377 |
+
https://github.com/amsul/pickadate.js/issues/1138
|
378 |
+
|
379 |
+
- 2.1.1 - 2018-09-26
|
380 |
+
- Allow address geolookup field to receive a Google Maps API key
|
381 |
+
- Use https when requesting google maps lookup
|
382 |
+
|
383 |
+
- 2.1 - 2017-04-21
|
384 |
+
- Add an Image setting type
|
385 |
+
|
386 |
+
- 2.0.1 - 2017-03-14
|
387 |
+
- Allow settings to receive $args passed to add_settings_field
|
388 |
+
|
389 |
+
- 2.0 - 2015-10-28
|
390 |
+
- Allow page capability to be modified after the page class is instantiated
|
391 |
+
|
392 |
+
- 2.0.a.10 - 2015-08-19
|
393 |
+
- Use h1 tags for page titles, in line with WP 4.3 changes
|
394 |
+
- Check for has_position before calling on a setting, in case of custom third-party settings being loaded
|
395 |
+
- Update pickadate.js lib
|
396 |
+
|
397 |
+
- 2.0.a.9 - 2014-11-12
|
398 |
+
- SelectPost: Use WP_Query instead of get_posts() so that filters can effect the list
|
399 |
+
- Require translateable strings to be declared when adding the setting so the library can conform to the upcoming single textdomain best practice in the .org repos
|
400 |
+
|
401 |
+
- 2.0.a.7 - 2014-08-20
|
402 |
+
- Only enqueue assets on appropriate admin pages to prevent version conflicts and be a good citizen
|
403 |
+
- Enforce stored date/time formats so date format is reliable
|
404 |
+
|
405 |
+
- 2.0.a.6 - 2014-08-12
|
406 |
+
- Add Google Map Address component
|
407 |
+
- Custom settings loaded through the extension path should not use versions
|
408 |
+
|
409 |
+
- 2.0.a.5 - 2014-05-15
|
410 |
+
- Fix a bug with the Textarea component callback
|
411 |
+
|
412 |
+
- 2.0.a.4 - 2014-05-15
|
413 |
+
- Only load assets when component is called
|
414 |
+
- Revert adding version number to script handles
|
415 |
+
- Fix localized script handler for Scheduler
|
416 |
+
- Fix pickadate CSS rule specificity
|
417 |
+
|
418 |
+
- 2.0.a.3 - 2014-05-14
|
419 |
+
- Fix undefined function error in Scheduler javascript when using Firefox
|
420 |
+
- Add version number to style and script handles so different versions will be enqueued
|
421 |
+
|
422 |
+
- 2.0.a.2 - 2014-05-11
|
423 |
+
- Add support for top-level menus
|
424 |
+
- Support line breaks in textarea components
|
425 |
+
|
426 |
+
- 2.0.a.1 - 2014-04-03
|
427 |
+
- Save all data on a page as one row in wp_options
|
428 |
+
|
429 |
+
- 1.1 - never released
|
430 |
+
- Support themes pages
|
431 |
+
- Support submenu pages for custom menu items
|
432 |
+
|
433 |
+
- 1.0 - 2013-11-20
|
434 |
+
- Initial release
|
lib/simple-admin-pages/classes/AdminPage.Menu.class.php
CHANGED
@@ -1,32 +1,32 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Register, display and save an settings page as a submenu item in the
|
5 |
-
* WordPress admin menu.
|
6 |
-
*
|
7 |
-
* @since 1.1
|
8 |
-
* @package Simple Admin Pages
|
9 |
-
*/
|
10 |
-
|
11 |
-
class
|
12 |
-
|
13 |
-
public $setup_function = 'add_menu_page'; // WP function to register the page
|
14 |
-
|
15 |
-
/**
|
16 |
-
* Add the page to the appropriate menu slot.
|
17 |
-
* @since 1.0
|
18 |
-
*/
|
19 |
-
public function add_admin_menu() {
|
20 |
-
|
21 |
-
call_user_func(
|
22 |
-
$this->setup_function,
|
23 |
-
$this->title,
|
24 |
-
$this->menu_title,
|
25 |
-
$this->capability,
|
26 |
-
$this->id,
|
27 |
-
array( $this, 'display_admin_menu' ),
|
28 |
-
$this->icon,
|
29 |
-
$this->position
|
30 |
-
);
|
31 |
-
}
|
32 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save an settings page as a submenu item in the
|
5 |
+
* WordPress admin menu.
|
6 |
+
*
|
7 |
+
* @since 1.1
|
8 |
+
* @package Simple Admin Pages
|
9 |
+
*/
|
10 |
+
|
11 |
+
class sapAdminPageMenu_2_5_5 extends sapAdminPage_2_5_5 {
|
12 |
+
|
13 |
+
public $setup_function = 'add_menu_page'; // WP function to register the page
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Add the page to the appropriate menu slot.
|
17 |
+
* @since 1.0
|
18 |
+
*/
|
19 |
+
public function add_admin_menu() {
|
20 |
+
|
21 |
+
call_user_func(
|
22 |
+
$this->setup_function,
|
23 |
+
$this->title,
|
24 |
+
$this->menu_title,
|
25 |
+
$this->capability,
|
26 |
+
$this->id,
|
27 |
+
array( $this, 'display_admin_menu' ),
|
28 |
+
$this->icon,
|
29 |
+
$this->position
|
30 |
+
);
|
31 |
+
}
|
32 |
+
}
|
lib/simple-admin-pages/classes/AdminPage.Submenu.class.php
CHANGED
@@ -1,38 +1,38 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Register, display and save an settings page as a submenu item in the
|
5 |
-
* WordPress admin menu.
|
6 |
-
*
|
7 |
-
* @since 1.1
|
8 |
-
* @package Simple Admin Pages
|
9 |
-
*/
|
10 |
-
|
11 |
-
class
|
12 |
-
|
13 |
-
public $setup_function = 'add_submenu_page'; // WP function to register the page
|
14 |
-
|
15 |
-
public $parent_menu = null; // Which menu to attach this submenu page to
|
16 |
-
|
17 |
-
/**
|
18 |
-
* Add the page to the appropriate menu slot.
|
19 |
-
* @since 1.0
|
20 |
-
*/
|
21 |
-
public function add_admin_menu() {
|
22 |
-
|
23 |
-
// Don't register if no parent menu is specified
|
24 |
-
if ( !$this->parent_menu ) {
|
25 |
-
return;
|
26 |
-
}
|
27 |
-
|
28 |
-
call_user_func(
|
29 |
-
$this->setup_function,
|
30 |
-
$this->parent_menu,
|
31 |
-
$this->title,
|
32 |
-
$this->menu_title,
|
33 |
-
$this->capability,
|
34 |
-
$this->id,
|
35 |
-
array( $this, 'display_admin_menu' )
|
36 |
-
);
|
37 |
-
}
|
38 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save an settings page as a submenu item in the
|
5 |
+
* WordPress admin menu.
|
6 |
+
*
|
7 |
+
* @since 1.1
|
8 |
+
* @package Simple Admin Pages
|
9 |
+
*/
|
10 |
+
|
11 |
+
class sapAdminPageSubmenu_2_5_5 extends sapAdminPage_2_5_5 {
|
12 |
+
|
13 |
+
public $setup_function = 'add_submenu_page'; // WP function to register the page
|
14 |
+
|
15 |
+
public $parent_menu = null; // Which menu to attach this submenu page to
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Add the page to the appropriate menu slot.
|
19 |
+
* @since 1.0
|
20 |
+
*/
|
21 |
+
public function add_admin_menu() {
|
22 |
+
|
23 |
+
// Don't register if no parent menu is specified
|
24 |
+
if ( !$this->parent_menu ) {
|
25 |
+
return;
|
26 |
+
}
|
27 |
+
|
28 |
+
call_user_func(
|
29 |
+
$this->setup_function,
|
30 |
+
$this->parent_menu,
|
31 |
+
$this->title,
|
32 |
+
$this->menu_title,
|
33 |
+
$this->capability,
|
34 |
+
$this->id,
|
35 |
+
array( $this, 'display_admin_menu' )
|
36 |
+
);
|
37 |
+
}
|
38 |
+
}
|
lib/simple-admin-pages/classes/AdminPage.Themes.class.php
CHANGED
@@ -1,15 +1,15 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Register, display and save a settings page in the WordPress admin Appearance
|
5 |
-
* menu.
|
6 |
-
*
|
7 |
-
* @since 1.0
|
8 |
-
* @package Simple Admin Pages
|
9 |
-
*/
|
10 |
-
|
11 |
-
class
|
12 |
-
|
13 |
-
public $setup_function = 'add_theme_page'; // WP function to register the page
|
14 |
-
|
15 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save a settings page in the WordPress admin Appearance
|
5 |
+
* menu.
|
6 |
+
*
|
7 |
+
* @since 1.0
|
8 |
+
* @package Simple Admin Pages
|
9 |
+
*/
|
10 |
+
|
11 |
+
class sapAdminPageThemes_2_5_5 extends sapAdminPage_2_5_5 {
|
12 |
+
|
13 |
+
public $setup_function = 'add_theme_page'; // WP function to register the page
|
14 |
+
|
15 |
+
}
|
lib/simple-admin-pages/classes/AdminPage.class.php
CHANGED
@@ -1,232 +1,232 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Register, display and save a settings page in the WordPress admin menu.
|
5 |
-
*
|
6 |
-
* @since 1.0
|
7 |
-
* @package Simple Admin Pages
|
8 |
-
*/
|
9 |
-
|
10 |
-
class
|
11 |
-
|
12 |
-
public $title;
|
13 |
-
public $menu_title;
|
14 |
-
public $description; // optional description for this page
|
15 |
-
public $capability; // user permissions needed to edit this panel
|
16 |
-
public $id; // id of this page
|
17 |
-
public $sections = array(); // array of sections to display on this page
|
18 |
-
public $show_button = true; // whether or not to show the Save Changes button
|
19 |
-
|
20 |
-
public $setup_function = 'add_options_page'; // WP function to register the page
|
21 |
-
|
22 |
-
|
23 |
-
/**
|
24 |
-
* Initialize the page
|
25 |
-
* @since 1.0
|
26 |
-
*/
|
27 |
-
public function __construct( $args ) {
|
28 |
-
|
29 |
-
// Parse the values passed
|
30 |
-
$this->parse_args( $args );
|
31 |
-
}
|
32 |
-
|
33 |
-
/**
|
34 |
-
* Parse the arguments passed in the construction and assign them to
|
35 |
-
* internal variables.
|
36 |
-
* @since 1.1
|
37 |
-
*/
|
38 |
-
private function parse_args( $args ) {
|
39 |
-
foreach ( $args as $key => $val ) {
|
40 |
-
switch ( $key ) {
|
41 |
-
|
42 |
-
case 'id' :
|
43 |
-
$this->{$key} = esc_attr( $val );
|
44 |
-
|
45 |
-
default :
|
46 |
-
$this->{$key} = $val;
|
47 |
-
|
48 |
-
}
|
49 |
-
}
|
50 |
-
}
|
51 |
-
|
52 |
-
/**
|
53 |
-
* Modify the capability required to save settings on this page
|
54 |
-
* @since 2.0
|
55 |
-
*/
|
56 |
-
public function modify_required_capability( $cap ) {
|
57 |
-
return $this->capability;
|
58 |
-
}
|
59 |
-
|
60 |
-
/**
|
61 |
-
* Add the page to the appropriate menu slot.
|
62 |
-
* @note The default will be to post to the options page, but other classes
|
63 |
-
* should override this function.
|
64 |
-
* @since 1.0
|
65 |
-
*/
|
66 |
-
public function add_admin_menu() {
|
67 |
-
call_user_func( $this->setup_function, $this->title, $this->menu_title, $this->capability, $this->id, array( $this, 'display_admin_menu' ) );
|
68 |
-
}
|
69 |
-
|
70 |
-
/**
|
71 |
-
* Add a section to the page
|
72 |
-
* @since 1.0
|
73 |
-
*/
|
74 |
-
public function add_section( $section ) {
|
75 |
-
|
76 |
-
if ( !$section ) {
|
77 |
-
return;
|
78 |
-
}
|
79 |
-
|
80 |
-
$this->sections[ $section->id ] = $section;
|
81 |
-
|
82 |
-
}
|
83 |
-
|
84 |
-
/**
|
85 |
-
* Register the settings and sanitization callbacks for each setting
|
86 |
-
* @since 1.0
|
87 |
-
*/
|
88 |
-
public function register_admin_menu() {
|
89 |
-
|
90 |
-
foreach ( $this->sections as $section ) {
|
91 |
-
$section->add_settings_section();
|
92 |
-
|
93 |
-
foreach ( $section->settings as $setting ) {
|
94 |
-
$setting->add_settings_field( $section->id );
|
95 |
-
}
|
96 |
-
}
|
97 |
-
|
98 |
-
register_setting( $this->id, $this->id, array( $this, 'sanitize_callback' ) );
|
99 |
-
|
100 |
-
// Modify capability required to save the settings if it's not
|
101 |
-
// the default `manage_options`
|
102 |
-
if ( !empty( $this->capability ) && $this->capability !== 'manage_options') {
|
103 |
-
add_filter( 'option_page_capability_' . $this->id, array( $this, 'modify_required_capability' ) );
|
104 |
-
}
|
105 |
-
}
|
106 |
-
|
107 |
-
/**
|
108 |
-
* Loop through the settings and sanitize the data
|
109 |
-
* @since 2.0
|
110 |
-
*/
|
111 |
-
public function sanitize_callback( $value ) {
|
112 |
-
|
113 |
-
if ( empty( $_POST['_wp_http_referer'] ) ) {
|
114 |
-
return $value;
|
115 |
-
}
|
116 |
-
|
117 |
-
// Get the current page/tab so we only update those settings
|
118 |
-
parse_str( $_POST['_wp_http_referer'], $referrer );
|
119 |
-
$current_page = $this->get_current_page( $referrer );
|
120 |
-
|
121 |
-
// Use a new empty value so only values for settings that were added are
|
122 |
-
// passed to the db.
|
123 |
-
$new_value = array();
|
124 |
-
|
125 |
-
foreach ( $this->sections as $section ) {
|
126 |
-
foreach ( $section->settings as $setting ) {
|
127 |
-
if ( $setting->tab == $current_page ) {
|
128 |
-
$setting_value = isset( $value[$setting->id] ) ? $value[$setting->id] : '';
|
129 |
-
$new_value[$setting->id] = $setting->sanitize_callback_wrapper( $setting_value );
|
130 |
-
}
|
131 |
-
}
|
132 |
-
}
|
133 |
-
|
134 |
-
// Pull in the existing values so we never overwrite values that were
|
135 |
-
// on a different tab
|
136 |
-
$old_value = get_option( $this->id );
|
137 |
-
|
138 |
-
if ( is_array( $old_value ) ) {
|
139 |
-
return array_merge( $old_value, $new_value );
|
140 |
-
} else {
|
141 |
-
return $new_value;
|
142 |
-
}
|
143 |
-
|
144 |
-
}
|
145 |
-
|
146 |
-
/**
|
147 |
-
* Get the current page/tab being viewed
|
148 |
-
* @since 2.0
|
149 |
-
*/
|
150 |
-
public function get_current_page( $request ) {
|
151 |
-
|
152 |
-
if ( !empty( $request['tab'] ) ) {
|
153 |
-
return $request['tab'];
|
154 |
-
} elseif ( !empty( $this->default_tab ) ) {
|
155 |
-
return $this->default_tab;
|
156 |
-
} else {
|
157 |
-
return $this->id;
|
158 |
-
}
|
159 |
-
|
160 |
-
}
|
161 |
-
|
162 |
-
/**
|
163 |
-
* Output the settings passed to this page
|
164 |
-
* @since 1.0
|
165 |
-
*/
|
166 |
-
public function display_admin_menu() {
|
167 |
-
|
168 |
-
if ( !$this->title && !count( $this->settings ) ) {
|
169 |
-
return;
|
170 |
-
}
|
171 |
-
|
172 |
-
if ( !current_user_can( $this->capability ) ) {
|
173 |
-
wp_die( __('You do not have sufficient permissions to access this page.') );
|
174 |
-
}
|
175 |
-
|
176 |
-
$current_page = $this->get_current_page( $_GET );
|
177 |
-
|
178 |
-
?>
|
179 |
-
|
180 |
-
<div class="wrap">
|
181 |
-
|
182 |
-
<?php $this->display_page_title(); ?>
|
183 |
-
|
184 |
-
<?php if ( isset( $this->default_tab ) ) : ?>
|
185 |
-
<h2 class="nav-tab-wrapper">
|
186 |
-
<?php
|
187 |
-
foreach( $this->sections as $section ) {
|
188 |
-
|
189 |
-
if ( isset( $section->is_tab ) && $section->is_tab === true ) {
|
190 |
-
|
191 |
-
$tab_url = add_query_arg(
|
192 |
-
array(
|
193 |
-
'settings-updated' => false,
|
194 |
-
'tab' => $section->id
|
195 |
-
)
|
196 |
-
);
|
197 |
-
|
198 |
-
$active = $current_page == $section->id ? ' nav-tab-active' : '';
|
199 |
-
echo '<a href="' . esc_url( $tab_url ) . '" title="' . esc_attr( $section->title ) . '" class="nav-tab' . $active . '">';
|
200 |
-
echo esc_html( $section->title );
|
201 |
-
echo '</a>';
|
202 |
-
}
|
203 |
-
}
|
204 |
-
?>
|
205 |
-
</h2>
|
206 |
-
<?php endif; ?>
|
207 |
-
|
208 |
-
<form method="post" action="options.php">
|
209 |
-
<?php settings_fields( $this->id ); ?>
|
210 |
-
<?php do_settings_sections( $current_page ); ?>
|
211 |
-
<?php if ( $this->show_button ) { submit_button(); } ?>
|
212 |
-
</form>
|
213 |
-
</div>
|
214 |
-
|
215 |
-
<?php
|
216 |
-
}
|
217 |
-
|
218 |
-
/**
|
219 |
-
* Output the title of the page
|
220 |
-
* @since 1.0
|
221 |
-
*/
|
222 |
-
public function display_page_title() {
|
223 |
-
|
224 |
-
if ( empty( $this->title ) ) {
|
225 |
-
return;
|
226 |
-
}
|
227 |
-
?>
|
228 |
-
<h1><?php echo $this->title; ?></h1>
|
229 |
-
<?php
|
230 |
-
}
|
231 |
-
|
232 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save a settings page in the WordPress admin menu.
|
5 |
+
*
|
6 |
+
* @since 1.0
|
7 |
+
* @package Simple Admin Pages
|
8 |
+
*/
|
9 |
+
|
10 |
+
class sapAdminPage_2_5_5 {
|
11 |
+
|
12 |
+
public $title;
|
13 |
+
public $menu_title;
|
14 |
+
public $description; // optional description for this page
|
15 |
+
public $capability; // user permissions needed to edit this panel
|
16 |
+
public $id; // id of this page
|
17 |
+
public $sections = array(); // array of sections to display on this page
|
18 |
+
public $show_button = true; // whether or not to show the Save Changes button
|
19 |
+
|
20 |
+
public $setup_function = 'add_options_page'; // WP function to register the page
|
21 |
+
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Initialize the page
|
25 |
+
* @since 1.0
|
26 |
+
*/
|
27 |
+
public function __construct( $args ) {
|
28 |
+
|
29 |
+
// Parse the values passed
|
30 |
+
$this->parse_args( $args );
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Parse the arguments passed in the construction and assign them to
|
35 |
+
* internal variables.
|
36 |
+
* @since 1.1
|
37 |
+
*/
|
38 |
+
private function parse_args( $args ) {
|
39 |
+
foreach ( $args as $key => $val ) {
|
40 |
+
switch ( $key ) {
|
41 |
+
|
42 |
+
case 'id' :
|
43 |
+
$this->{$key} = esc_attr( $val );
|
44 |
+
|
45 |
+
default :
|
46 |
+
$this->{$key} = $val;
|
47 |
+
|
48 |
+
}
|
49 |
+
}
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Modify the capability required to save settings on this page
|
54 |
+
* @since 2.0
|
55 |
+
*/
|
56 |
+
public function modify_required_capability( $cap ) {
|
57 |
+
return $this->capability;
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Add the page to the appropriate menu slot.
|
62 |
+
* @note The default will be to post to the options page, but other classes
|
63 |
+
* should override this function.
|
64 |
+
* @since 1.0
|
65 |
+
*/
|
66 |
+
public function add_admin_menu() {
|
67 |
+
call_user_func( $this->setup_function, $this->title, $this->menu_title, $this->capability, $this->id, array( $this, 'display_admin_menu' ) );
|
68 |
+
}
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Add a section to the page
|
72 |
+
* @since 1.0
|
73 |
+
*/
|
74 |
+
public function add_section( $section ) {
|
75 |
+
|
76 |
+
if ( !$section ) {
|
77 |
+
return;
|
78 |
+
}
|
79 |
+
|
80 |
+
$this->sections[ $section->id ] = $section;
|
81 |
+
|
82 |
+
}
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Register the settings and sanitization callbacks for each setting
|
86 |
+
* @since 1.0
|
87 |
+
*/
|
88 |
+
public function register_admin_menu() {
|
89 |
+
|
90 |
+
foreach ( $this->sections as $section ) {
|
91 |
+
$section->add_settings_section();
|
92 |
+
|
93 |
+
foreach ( $section->settings as $setting ) {
|
94 |
+
$setting->add_settings_field( $section->id );
|
95 |
+
}
|
96 |
+
}
|
97 |
+
|
98 |
+
register_setting( $this->id, $this->id, array( $this, 'sanitize_callback' ) );
|
99 |
+
|
100 |
+
// Modify capability required to save the settings if it's not
|
101 |
+
// the default `manage_options`
|
102 |
+
if ( !empty( $this->capability ) && $this->capability !== 'manage_options') {
|
103 |
+
add_filter( 'option_page_capability_' . $this->id, array( $this, 'modify_required_capability' ) );
|
104 |
+
}
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Loop through the settings and sanitize the data
|
109 |
+
* @since 2.0
|
110 |
+
*/
|
111 |
+
public function sanitize_callback( $value ) {
|
112 |
+
|
113 |
+
if ( empty( $_POST['_wp_http_referer'] ) ) {
|
114 |
+
return $value;
|
115 |
+
}
|
116 |
+
|
117 |
+
// Get the current page/tab so we only update those settings
|
118 |
+
parse_str( $_POST['_wp_http_referer'], $referrer );
|
119 |
+
$current_page = $this->get_current_page( $referrer );
|
120 |
+
|
121 |
+
// Use a new empty value so only values for settings that were added are
|
122 |
+
// passed to the db.
|
123 |
+
$new_value = array();
|
124 |
+
|
125 |
+
foreach ( $this->sections as $section ) {
|
126 |
+
foreach ( $section->settings as $setting ) {
|
127 |
+
if ( $setting->tab == $current_page ) {
|
128 |
+
$setting_value = isset( $value[$setting->id] ) ? $value[$setting->id] : '';
|
129 |
+
$new_value[$setting->id] = $setting->sanitize_callback_wrapper( $setting_value );
|
130 |
+
}
|
131 |
+
}
|
132 |
+
}
|
133 |
+
|
134 |
+
// Pull in the existing values so we never overwrite values that were
|
135 |
+
// on a different tab
|
136 |
+
$old_value = get_option( $this->id );
|
137 |
+
|
138 |
+
if ( is_array( $old_value ) ) {
|
139 |
+
return array_merge( $old_value, $new_value );
|
140 |
+
} else {
|
141 |
+
return $new_value;
|
142 |
+
}
|
143 |
+
|
144 |
+
}
|
145 |
+
|
146 |
+
/**
|
147 |
+
* Get the current page/tab being viewed
|
148 |
+
* @since 2.0
|
149 |
+
*/
|
150 |
+
public function get_current_page( $request ) {
|
151 |
+
|
152 |
+
if ( !empty( $request['tab'] ) ) {
|
153 |
+
return $request['tab'];
|
154 |
+
} elseif ( !empty( $this->default_tab ) ) {
|
155 |
+
return $this->default_tab;
|
156 |
+
} else {
|
157 |
+
return $this->id;
|
158 |
+
}
|
159 |
+
|
160 |
+
}
|
161 |
+
|
162 |
+
/**
|
163 |
+
* Output the settings passed to this page
|
164 |
+
* @since 1.0
|
165 |
+
*/
|
166 |
+
public function display_admin_menu() {
|
167 |
+
|
168 |
+
if ( !$this->title && !count( $this->settings ) ) {
|
169 |
+
return;
|
170 |
+
}
|
171 |
+
|
172 |
+
if ( !current_user_can( $this->capability ) ) {
|
173 |
+
wp_die( __('You do not have sufficient permissions to access this page.') );
|
174 |
+
}
|
175 |
+
|
176 |
+
$current_page = $this->get_current_page( $_GET );
|
177 |
+
|
178 |
+
?>
|
179 |
+
|
180 |
+
<div class="wrap sap-settings-page">
|
181 |
+
|
182 |
+
<?php $this->display_page_title(); ?>
|
183 |
+
|
184 |
+
<?php if ( isset( $this->default_tab ) ) : ?>
|
185 |
+
<h2 class="nav-tab-wrapper">
|
186 |
+
<?php
|
187 |
+
foreach( $this->sections as $section ) {
|
188 |
+
|
189 |
+
if ( isset( $section->is_tab ) && $section->is_tab === true ) {
|
190 |
+
|
191 |
+
$tab_url = add_query_arg(
|
192 |
+
array(
|
193 |
+
'settings-updated' => false,
|
194 |
+
'tab' => $section->id
|
195 |
+
)
|
196 |
+
);
|
197 |
+
|
198 |
+
$active = $current_page == $section->id ? ' nav-tab-active' : '';
|
199 |
+
echo '<a href="' . esc_url( $tab_url ) . '" title="' . esc_attr( $section->title ) . '" class="nav-tab' . $active . '">';
|
200 |
+
echo esc_html( $section->title );
|
201 |
+
echo '</a>';
|
202 |
+
}
|
203 |
+
}
|
204 |
+
?>
|
205 |
+
</h2>
|
206 |
+
<?php endif; ?>
|
207 |
+
|
208 |
+
<form method="post" action="options.php" class="sap-parent-form">
|
209 |
+
<?php settings_fields( $this->id ); ?>
|
210 |
+
<?php do_settings_sections( $current_page ); ?>
|
211 |
+
<?php if ( $this->show_button ) { submit_button(); } ?>
|
212 |
+
</form>
|
213 |
+
</div>
|
214 |
+
|
215 |
+
<?php
|
216 |
+
}
|
217 |
+
|
218 |
+
/**
|
219 |
+
* Output the title of the page
|
220 |
+
* @since 1.0
|
221 |
+
*/
|
222 |
+
public function display_page_title() {
|
223 |
+
|
224 |
+
if ( empty( $this->title ) ) {
|
225 |
+
return;
|
226 |
+
}
|
227 |
+
?>
|
228 |
+
<h1><?php echo $this->title; ?></h1>
|
229 |
+
<?php
|
230 |
+
}
|
231 |
+
|
232 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSection.class.php
CHANGED
@@ -1,188 +1,188 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Register, display and save a section on a custom admin menu
|
5 |
-
*
|
6 |
-
* @since 1.0
|
7 |
-
* @package Simple Admin Pages
|
8 |
-
*/
|
9 |
-
|
10 |
-
class
|
11 |
-
|
12 |
-
// Page defaults
|
13 |
-
public $id; // unique id for this section
|
14 |
-
public $title; // optional title to display above this section
|
15 |
-
public $description; // optional description of the section
|
16 |
-
public $settings = array(); // Array of settings to display in this option set
|
17 |
-
public $disabled = false; // whether a setting should be disabled
|
18 |
-
|
19 |
-
// Array to store errors
|
20 |
-
public $errors = array();
|
21 |
-
|
22 |
-
/**
|
23 |
-
* Initialize the section
|
24 |
-
* @since 1.0
|
25 |
-
*/
|
26 |
-
public function __construct( $args ) {
|
27 |
-
|
28 |
-
// Parse the values passed
|
29 |
-
$this->parse_args( $args );
|
30 |
-
|
31 |
-
// Set an error if there is no id for this section
|
32 |
-
if ( !isset( $this->id ) ) {
|
33 |
-
$this->set_error(
|
34 |
-
array(
|
35 |
-
'type' => 'missing_data',
|
36 |
-
'data' => 'id'
|
37 |
-
)
|
38 |
-
);
|
39 |
-
}
|
40 |
-
|
41 |
-
}
|
42 |
-
|
43 |
-
/**
|
44 |
-
* Parse the arguments passed in the construction and assign them to
|
45 |
-
* internal variables.
|
46 |
-
* @since 1.0
|
47 |
-
*/
|
48 |
-
private function parse_args( $args ) {
|
49 |
-
foreach ( $args as $key => $val ) {
|
50 |
-
switch ( $key ) {
|
51 |
-
|
52 |
-
case 'id' :
|
53 |
-
$this->{$key} = esc_attr( $val );
|
54 |
-
|
55 |
-
default :
|
56 |
-
$this->{$key} = $val;
|
57 |
-
|
58 |
-
}
|
59 |
-
}
|
60 |
-
}
|
61 |
-
|
62 |
-
/**
|
63 |
-
* Add a setting to this section
|
64 |
-
* @since 1.0
|
65 |
-
*/
|
66 |
-
public function add_setting( $setting ) {
|
67 |
-
|
68 |
-
if ( !$setting ) {
|
69 |
-
return;
|
70 |
-
}
|
71 |
-
|
72 |
-
if ( $this->disabled ) {
|
73 |
-
$setting->disabled = true;
|
74 |
-
}
|
75 |
-
|
76 |
-
if ( method_exists( $setting, 'has_position' ) && $setting->has_position() ) {
|
77 |
-
|
78 |
-
// Top
|
79 |
-
if ( $setting->position[0] == 'top' ) {
|
80 |
-
$this->settings = array_merge( array( $setting->id => $setting ), $this->settings );
|
81 |
-
return;
|
82 |
-
}
|
83 |
-
|
84 |
-
// Position setting relative to another setting
|
85 |
-
if ( !empty( $setting->position[1] ) ) {
|
86 |
-
|
87 |
-
$new_settings = array();
|
88 |
-
foreach( $this->settings as $id => $current ) {
|
89 |
-
|
90 |
-
// Above
|
91 |
-
if ( $setting->position[1] == $id && $setting->position[0] == 'above' ) {
|
92 |
-
$new_settings[ $setting->id ] = $setting;
|
93 |
-
}
|
94 |
-
|
95 |
-
$new_settings[ $id ] = $current;
|
96 |
-
|
97 |
-
// Below
|
98 |
-
if ( $setting->position[1] == $id && $setting->position[0] == 'below' ) {
|
99 |
-
$new_settings[ $setting->id ] = $setting;
|
100 |
-
}
|
101 |
-
}
|
102 |
-
|
103 |
-
$this->settings = $new_settings;
|
104 |
-
|
105 |
-
return;
|
106 |
-
}
|
107 |
-
}
|
108 |
-
|
109 |
-
// Fallback to appending it at the end
|
110 |
-
$this->settings[ $setting->id ] = $setting;
|
111 |
-
}
|
112 |
-
|
113 |
-
/**
|
114 |
-
* Display the description for this section
|
115 |
-
* @since 1.0
|
116 |
-
*/
|
117 |
-
public function display_section() {
|
118 |
-
|
119 |
-
if ( !count( $this->settings ) ) {
|
120 |
-
return;
|
121 |
-
}
|
122 |
-
|
123 |
-
if ( !empty( $this->description ) ) :
|
124 |
-
?>
|
125 |
-
|
126 |
-
<p class="description"><?php echo $this->description; ?></p>
|
127 |
-
|
128 |
-
<?php
|
129 |
-
endif;
|
130 |
-
|
131 |
-
if ( $this->disabled and isset($this->disabled_image) ) {
|
132 |
-
|
133 |
-
?>
|
134 |
-
|
135 |
-
<?php echo ( isset($this->purchase_link ) ? "<div class='
|
136 |
-
<div class="section-disabled">
|
137 |
-
<img src="<?php echo
|
138 |
-
<p>Access this section by
|
139 |
-
<a href="
|
140 |
-
</div>
|
141 |
-
<?php echo ( isset($this->purchase_link ) ? "</div>" : '' ); ?>
|
142 |
-
|
143 |
-
<?php
|
144 |
-
|
145 |
-
}
|
146 |
-
}
|
147 |
-
|
148 |
-
/**
|
149 |
-
* Add the settings section to the page in WordPress
|
150 |
-
* @since 1.0
|
151 |
-
*/
|
152 |
-
public function add_settings_section() {
|
153 |
-
add_settings_section( $this->id, $this->title, array( $this, 'display_section' ), $this->get_page_slug() );
|
154 |
-
}
|
155 |
-
|
156 |
-
/**
|
157 |
-
* Determine the page slug to use when calling add_settings_section.
|
158 |
-
*
|
159 |
-
* Tabs should use their own ID and settings that are attached to tabs
|
160 |
-
* should use that tab's ID.
|
161 |
-
* @since 2.0
|
162 |
-
*/
|
163 |
-
public function get_page_slug() {
|
164 |
-
if ( isset( $this->is_tab ) && $this->is_tab === true ) {
|
165 |
-
return $this->id;
|
166 |
-
} elseif ( isset( $this->tab ) ) {
|
167 |
-
return $this->tab;
|
168 |
-
} else {
|
169 |
-
return $this->page;
|
170 |
-
}
|
171 |
-
}
|
172 |
-
|
173 |
-
/**
|
174 |
-
* Set an error
|
175 |
-
* @since 1.0
|
176 |
-
*/
|
177 |
-
public function set_error( $error ) {
|
178 |
-
$this->errors[] = array_merge(
|
179 |
-
$error,
|
180 |
-
array(
|
181 |
-
'class' => get_class( $this ),
|
182 |
-
'id' => $this->id,
|
183 |
-
'backtrace' => debug_backtrace()
|
184 |
-
)
|
185 |
-
);
|
186 |
-
}
|
187 |
-
|
188 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save a section on a custom admin menu
|
5 |
+
*
|
6 |
+
* @since 1.0
|
7 |
+
* @package Simple Admin Pages
|
8 |
+
*/
|
9 |
+
|
10 |
+
class sapAdminPageSection_2_5_5 {
|
11 |
+
|
12 |
+
// Page defaults
|
13 |
+
public $id; // unique id for this section
|
14 |
+
public $title; // optional title to display above this section
|
15 |
+
public $description; // optional description of the section
|
16 |
+
public $settings = array(); // Array of settings to display in this option set
|
17 |
+
public $disabled = false; // whether a setting should be disabled
|
18 |
+
|
19 |
+
// Array to store errors
|
20 |
+
public $errors = array();
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Initialize the section
|
24 |
+
* @since 1.0
|
25 |
+
*/
|
26 |
+
public function __construct( $args ) {
|
27 |
+
|
28 |
+
// Parse the values passed
|
29 |
+
$this->parse_args( $args );
|
30 |
+
|
31 |
+
// Set an error if there is no id for this section
|
32 |
+
if ( !isset( $this->id ) ) {
|
33 |
+
$this->set_error(
|
34 |
+
array(
|
35 |
+
'type' => 'missing_data',
|
36 |
+
'data' => 'id'
|
37 |
+
)
|
38 |
+
);
|
39 |
+
}
|
40 |
+
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Parse the arguments passed in the construction and assign them to
|
45 |
+
* internal variables.
|
46 |
+
* @since 1.0
|
47 |
+
*/
|
48 |
+
private function parse_args( $args ) {
|
49 |
+
foreach ( $args as $key => $val ) {
|
50 |
+
switch ( $key ) {
|
51 |
+
|
52 |
+
case 'id' :
|
53 |
+
$this->{$key} = esc_attr( $val );
|
54 |
+
|
55 |
+
default :
|
56 |
+
$this->{$key} = $val;
|
57 |
+
|
58 |
+
}
|
59 |
+
}
|
60 |
+
}
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Add a setting to this section
|
64 |
+
* @since 1.0
|
65 |
+
*/
|
66 |
+
public function add_setting( $setting ) {
|
67 |
+
|
68 |
+
if ( !$setting ) {
|
69 |
+
return;
|
70 |
+
}
|
71 |
+
|
72 |
+
if ( $this->disabled ) {
|
73 |
+
$setting->disabled = true;
|
74 |
+
}
|
75 |
+
|
76 |
+
if ( method_exists( $setting, 'has_position' ) && $setting->has_position() ) {
|
77 |
+
|
78 |
+
// Top
|
79 |
+
if ( $setting->position[0] == 'top' ) {
|
80 |
+
$this->settings = array_merge( array( $setting->id => $setting ), $this->settings );
|
81 |
+
return;
|
82 |
+
}
|
83 |
+
|
84 |
+
// Position setting relative to another setting
|
85 |
+
if ( !empty( $setting->position[1] ) ) {
|
86 |
+
|
87 |
+
$new_settings = array();
|
88 |
+
foreach( $this->settings as $id => $current ) {
|
89 |
+
|
90 |
+
// Above
|
91 |
+
if ( $setting->position[1] == $id && $setting->position[0] == 'above' ) {
|
92 |
+
$new_settings[ $setting->id ] = $setting;
|
93 |
+
}
|
94 |
+
|
95 |
+
$new_settings[ $id ] = $current;
|
96 |
+
|
97 |
+
// Below
|
98 |
+
if ( $setting->position[1] == $id && $setting->position[0] == 'below' ) {
|
99 |
+
$new_settings[ $setting->id ] = $setting;
|
100 |
+
}
|
101 |
+
}
|
102 |
+
|
103 |
+
$this->settings = $new_settings;
|
104 |
+
|
105 |
+
return;
|
106 |
+
}
|
107 |
+
}
|
108 |
+
|
109 |
+
// Fallback to appending it at the end
|
110 |
+
$this->settings[ $setting->id ] = $setting;
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Display the description for this section
|
115 |
+
* @since 1.0
|
116 |
+
*/
|
117 |
+
public function display_section() {
|
118 |
+
|
119 |
+
if ( !count( $this->settings ) ) {
|
120 |
+
return;
|
121 |
+
}
|
122 |
+
|
123 |
+
if ( !empty( $this->description ) ) :
|
124 |
+
?>
|
125 |
+
|
126 |
+
<p class="description"><?php echo $this->description; ?></p>
|
127 |
+
|
128 |
+
<?php
|
129 |
+
endif;
|
130 |
+
|
131 |
+
if ( $this->disabled and isset($this->disabled_image) ) {
|
132 |
+
|
133 |
+
?>
|
134 |
+
|
135 |
+
<?php echo ( isset($this->purchase_link ) ? "<div class='sap-premium-options-table-overlay'>" : '' ); ?>
|
136 |
+
<div class="section-disabled">
|
137 |
+
<img src="<?php echo plugins_url( '../img/options-asset-lock.png', __FILE__ ); ?>" alt="Upgrade to Premium">
|
138 |
+
<p>Access this section by upgrading to premium</p>
|
139 |
+
<a href="<?php echo $this->purchase_link; ?>" class="sap-dashboard-get-premium-widget-button" target="_blank">UPGRADE NOW</a>
|
140 |
+
</div>
|
141 |
+
<?php echo ( isset( $this->purchase_link ) ? "</div>" : '' ); ?>
|
142 |
+
|
143 |
+
<?php
|
144 |
+
|
145 |
+
}
|
146 |
+
}
|
147 |
+
|
148 |
+
/**
|
149 |
+
* Add the settings section to the page in WordPress
|
150 |
+
* @since 1.0
|
151 |
+
*/
|
152 |
+
public function add_settings_section() {
|
153 |
+
add_settings_section( $this->id, $this->title, array( $this, 'display_section' ), $this->get_page_slug() );
|
154 |
+
}
|
155 |
+
|
156 |
+
/**
|
157 |
+
* Determine the page slug to use when calling add_settings_section.
|
158 |
+
*
|
159 |
+
* Tabs should use their own ID and settings that are attached to tabs
|
160 |
+
* should use that tab's ID.
|
161 |
+
* @since 2.0
|
162 |
+
*/
|
163 |
+
public function get_page_slug() {
|
164 |
+
if ( isset( $this->is_tab ) && $this->is_tab === true ) {
|
165 |
+
return $this->id;
|
166 |
+
} elseif ( isset( $this->tab ) ) {
|
167 |
+
return $this->tab;
|
168 |
+
} else {
|
169 |
+
return $this->page;
|
170 |
+
}
|
171 |
+
}
|
172 |
+
|
173 |
+
/**
|
174 |
+
* Set an error
|
175 |
+
* @since 1.0
|
176 |
+
*/
|
177 |
+
public function set_error( $error ) {
|
178 |
+
$this->errors[] = array_merge(
|
179 |
+
$error,
|
180 |
+
array(
|
181 |
+
'class' => get_class( $this ),
|
182 |
+
'id' => $this->id,
|
183 |
+
'backtrace' => debug_backtrace()
|
184 |
+
)
|
185 |
+
);
|
186 |
+
}
|
187 |
+
|
188 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSetting.Address.class.php
CHANGED
@@ -1,156 +1,156 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Register, display and save a textarea field setting in the admin menu
|
5 |
-
*
|
6 |
-
* @since 2.0.a.5
|
7 |
-
* @package Simple Admin Pages
|
8 |
-
*/
|
9 |
-
|
10 |
-
class
|
11 |
-
|
12 |
-
/*
|
13 |
-
* Size of this textarea
|
14 |
-
*
|
15 |
-
* This is put directly into a css class [size]-text,
|
16 |
-
* and setting this to 'large' will link into WordPress's existing textarea
|
17 |
-
* style for full-width textareas.
|
18 |
-
*/
|
19 |
-
public $size = 'small';
|
20 |
-
|
21 |
-
/*
|
22 |
-
* A Google Maps API key for geolocating addresses
|
23 |
-
*/
|
24 |
-
public $api_key = '';
|
25 |
-
|
26 |
-
/*
|
27 |
-
* A jQuery selector pointing to the input element where the Google Maps API
|
28 |
-
* key can be retrieved.
|
29 |
-
*/
|
30 |
-
public $api_key_selector = '';
|
31 |
-
|
32 |
-
/**
|
33 |
-
* Scripts that must be loaded for this component
|
34 |
-
* @since 2.0.a.5
|
35 |
-
*/
|
36 |
-
public $scripts = array(
|
37 |
-
'sap-address' => array(
|
38 |
-
'path' => 'js/address.js',
|
39 |
-
'dependencies' => array( 'jquery' ),
|
40 |
-
'version' =>
|
41 |
-
'footer' => true,
|
42 |
-
),
|
43 |
-
);
|
44 |
-
|
45 |
-
public $sanitize_callback = 'sanitize_text_field';
|
46 |
-
|
47 |
-
/**
|
48 |
-
* Translateable strings required for this component
|
49 |
-
* @since 2.0.a.8
|
50 |
-
*/
|
51 |
-
public $strings = array(
|
52 |
-
'sep-action-links' => null, // _x( ' | ', 'separator between admin action links in address component', 'textdomain' ),
|
53 |
-
'sep-lat-lon' => null, // _x( ', ', 'separates latitude and longitude', 'textdomain' ),
|
54 |
-
'no-setting' => null, // __( 'No map coordinates set.', 'textdomain' ),
|
55 |
-
'retrieving' => null, // __( 'Requesting new coordinates', 'textdomain' ),
|
56 |
-
'select' => null, // __( 'Select a match below', 'textdomain' ),
|
57 |
-
'view' => null, // __( 'View', 'textdomain' ),
|
58 |
-
'retrieve' => null, // __( 'Retrieve map coordinates', 'textdomain' ),
|
59 |
-
'remove' => null, // __( 'Remove map coordinates', 'textdomain' ),
|
60 |
-
'try_again' => null, // __( 'Try again?', 'textdomain' ),
|
61 |
-
'result_error' => null, // __( 'Error', 'textdomain' ),
|
62 |
-
'result_invalid' => null, // __( 'Invalid request. Be sure to fill out the address field before retrieving coordinates.', 'textdomain' ),
|
63 |
-
'result_denied' => null, // __( 'Request denied.', 'textdomain' ),
|
64 |
-
'result_limit' => null, // __( 'Request denied because you are over your request quota.', 'textdomain' ),
|
65 |
-
'result_empty' => null, // __( 'Nothing was found at that address', 'textdomain' ),
|
66 |
-
);
|
67 |
-
|
68 |
-
/**
|
69 |
-
* Escape the value to display it safely HTML textarea fields
|
70 |
-
* @since 2.0.a.5
|
71 |
-
*/
|
72 |
-
public function esc_value( $val ) {
|
73 |
-
|
74 |
-
$escaped = array();
|
75 |
-
$escaped['text'] = empty( $val['text'] ) ? '' : esc_textarea( $val['text'] );
|
76 |
-
$escaped['lat'] = empty( $val['lat'] ) ? '' : esc_textarea( $val['lat'] );
|
77 |
-
$escaped['lon'] = empty( $val['lon'] ) ? '' : esc_textarea( $val['lon'] );
|
78 |
-
|
79 |
-
return $escaped;
|
80 |
-
}
|
81 |
-
|
82 |
-
/**
|
83 |
-
* Set the size of this textarea field
|
84 |
-
* @since 1.0
|
85 |
-
*/
|
86 |
-
public function set_size( $size ) {
|
87 |
-
$this->size = esc_attr( $size );
|
88 |
-
}
|
89 |
-
|
90 |
-
/**
|
91 |
-
* Wrapper for the sanitization callback function.
|
92 |
-
*
|
93 |
-
* This just reduces code duplication for child classes that need a custom
|
94 |
-
* callback function.
|
95 |
-
* @since 2.0.a.5
|
96 |
-
*/
|
97 |
-
public function sanitize_callback_wrapper( $value ) {
|
98 |
-
|
99 |
-
$sanitized = array();
|
100 |
-
$sanitized['text'] = empty( $value['text'] ) ? '' : wp_kses_post( $value['text'] );
|
101 |
-
$sanitized['lat'] = empty( $value['lat'] ) ? '' : sanitize_text_field( $value['lat'] );
|
102 |
-
$sanitized['lon'] = empty( $value['lon'] ) ? '' : sanitize_text_field( $value['lon'] );
|
103 |
-
|
104 |
-
return $sanitized;
|
105 |
-
}
|
106 |
-
|
107 |
-
/**
|
108 |
-
* Display this setting
|
109 |
-
* @since 2.0.a.5
|
110 |
-
*/
|
111 |
-
public function display_setting() {
|
112 |
-
|
113 |
-
wp_localize_script(
|
114 |
-
'sap-address',
|
115 |
-
'sap_address',
|
116 |
-
array(
|
117 |
-
'strings' => $this->strings,
|
118 |
-
'api_key' => $this->api_key,
|
119 |
-
'api_key_selector' => $this->api_key_selector,
|
120 |
-
)
|
121 |
-
);
|
122 |
-
|
123 |
-
$this->display_description();
|
124 |
-
|
125 |
-
?>
|
126 |
-
|
127 |
-
<div class="sap-address" id="<?php echo $this->id; ?>">
|
128 |
-
<textarea name="<?php echo $this->get_input_name(); ?>[text]" id="<?php echo $this->get_input_name(); ?>" class="<?php echo $this->size; ?>-text"<?php echo !empty( $this->placeholder ) ? ' placeholder="' . esc_attr( $this->placeholder ) . '"' : ''; ?> <?php echo ( $this->disabled ? 'disabled' : ''); ?>><?php echo $this->value['text']; ?></textarea>
|
129 |
-
<p class="sap-map-coords-wrapper">
|
130 |
-
<span class="dashicons dashicons-location-alt"></span>
|
131 |
-
<span class="sap-map-coords">
|
132 |
-
<?php if ( empty( $this->value['lat'] ) || empty( $this->value['lon'] ) ) : ?>
|
133 |
-
<?php echo $this->strings['no-setting']; ?>
|
134 |
-
<?php else : ?>
|
135 |
-
<?php echo $this->value['lat'] . $this->strings['sep-lat-lon'] . $this->value['lon']; ?>
|
136 |
-
<a href="//maps.google.com/maps?q=<?php echo esc_attr( $this->value['lat'] ) . ',' . esc_attr( $this->value['lon'] ); ?>" class="sap-view-coords" target="_blank"><?php echo $this->strings['view']; ?></a>
|
137 |
-
<?php endif; ?>
|
138 |
-
</span>
|
139 |
-
</p>
|
140 |
-
<p class="sap-coords-action-wrapper">
|
141 |
-
<a href="#" class="sap-get-coords">
|
142 |
-
<?php echo $this->strings['retrieve']; ?>
|
143 |
-
</a>
|
144 |
-
<?php echo $this->strings['sep-action-links']; ?>
|
145 |
-
<a href="#" class="sap-remove-coords">
|
146 |
-
<?php echo $this->strings['remove']; ?>
|
147 |
-
</a>
|
148 |
-
</p>
|
149 |
-
<input type="hidden" class="lat" name="<?php echo $this->get_input_name(); ?>[lat]" value="<?php echo $this->value['lat']; ?>">
|
150 |
-
<input type="hidden" class="lon" name="<?php echo $this->get_input_name(); ?>[lon]" value="<?php echo $this->value['lon']; ?>">
|
151 |
-
</div>
|
152 |
-
|
153 |
-
<?php
|
154 |
-
}
|
155 |
-
|
156 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save a textarea field setting in the admin menu
|
5 |
+
*
|
6 |
+
* @since 2.0.a.5
|
7 |
+
* @package Simple Admin Pages
|
8 |
+
*/
|
9 |
+
|
10 |
+
class sapAdminPageSettingAddress_2_5_5 extends sapAdminPageSetting_2_5_5 {
|
11 |
+
|
12 |
+
/*
|
13 |
+
* Size of this textarea
|
14 |
+
*
|
15 |
+
* This is put directly into a css class [size]-text,
|
16 |
+
* and setting this to 'large' will link into WordPress's existing textarea
|
17 |
+
* style for full-width textareas.
|
18 |
+
*/
|
19 |
+
public $size = 'small';
|
20 |
+
|
21 |
+
/*
|
22 |
+
* A Google Maps API key for geolocating addresses
|
23 |
+
*/
|
24 |
+
public $api_key = '';
|
25 |
+
|
26 |
+
/*
|
27 |
+
* A jQuery selector pointing to the input element where the Google Maps API
|
28 |
+
* key can be retrieved.
|
29 |
+
*/
|
30 |
+
public $api_key_selector = '';
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Scripts that must be loaded for this component
|
34 |
+
* @since 2.0.a.5
|
35 |
+
*/
|
36 |
+
public $scripts = array(
|
37 |
+
'sap-address' => array(
|
38 |
+
'path' => 'js/address.js',
|
39 |
+
'dependencies' => array( 'jquery' ),
|
40 |
+
'version' => SAP_VERSION,
|
41 |
+
'footer' => true,
|
42 |
+
),
|
43 |
+
);
|
44 |
+
|
45 |
+
public $sanitize_callback = 'sanitize_text_field';
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Translateable strings required for this component
|
49 |
+
* @since 2.0.a.8
|
50 |
+
*/
|
51 |
+
public $strings = array(
|
52 |
+
'sep-action-links' => null, // _x( ' | ', 'separator between admin action links in address component', 'textdomain' ),
|
53 |
+
'sep-lat-lon' => null, // _x( ', ', 'separates latitude and longitude', 'textdomain' ),
|
54 |
+
'no-setting' => null, // __( 'No map coordinates set.', 'textdomain' ),
|
55 |
+
'retrieving' => null, // __( 'Requesting new coordinates', 'textdomain' ),
|
56 |
+
'select' => null, // __( 'Select a match below', 'textdomain' ),
|
57 |
+
'view' => null, // __( 'View', 'textdomain' ),
|
58 |
+
'retrieve' => null, // __( 'Retrieve map coordinates', 'textdomain' ),
|
59 |
+
'remove' => null, // __( 'Remove map coordinates', 'textdomain' ),
|
60 |
+
'try_again' => null, // __( 'Try again?', 'textdomain' ),
|
61 |
+
'result_error' => null, // __( 'Error', 'textdomain' ),
|
62 |
+
'result_invalid' => null, // __( 'Invalid request. Be sure to fill out the address field before retrieving coordinates.', 'textdomain' ),
|
63 |
+
'result_denied' => null, // __( 'Request denied.', 'textdomain' ),
|
64 |
+
'result_limit' => null, // __( 'Request denied because you are over your request quota.', 'textdomain' ),
|
65 |
+
'result_empty' => null, // __( 'Nothing was found at that address', 'textdomain' ),
|
66 |
+
);
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Escape the value to display it safely HTML textarea fields
|
70 |
+
* @since 2.0.a.5
|
71 |
+
*/
|
72 |
+
public function esc_value( $val ) {
|
73 |
+
|
74 |
+
$escaped = array();
|
75 |
+
$escaped['text'] = empty( $val['text'] ) ? '' : esc_textarea( $val['text'] );
|
76 |
+
$escaped['lat'] = empty( $val['lat'] ) ? '' : esc_textarea( $val['lat'] );
|
77 |
+
$escaped['lon'] = empty( $val['lon'] ) ? '' : esc_textarea( $val['lon'] );
|
78 |
+
|
79 |
+
return $escaped;
|
80 |
+
}
|
81 |
+
|
82 |
+
/**
|
83 |
+
* Set the size of this textarea field
|
84 |
+
* @since 1.0
|
85 |
+
*/
|
86 |
+
public function set_size( $size ) {
|
87 |
+
$this->size = esc_attr( $size );
|
88 |
+
}
|
89 |
+
|
90 |
+
/**
|
91 |
+
* Wrapper for the sanitization callback function.
|
92 |
+
*
|
93 |
+
* This just reduces code duplication for child classes that need a custom
|
94 |
+
* callback function.
|
95 |
+
* @since 2.0.a.5
|
96 |
+
*/
|
97 |
+
public function sanitize_callback_wrapper( $value ) {
|
98 |
+
|
99 |
+
$sanitized = array();
|
100 |
+
$sanitized['text'] = empty( $value['text'] ) ? '' : wp_kses_post( $value['text'] );
|
101 |
+
$sanitized['lat'] = empty( $value['lat'] ) ? '' : sanitize_text_field( $value['lat'] );
|
102 |
+
$sanitized['lon'] = empty( $value['lon'] ) ? '' : sanitize_text_field( $value['lon'] );
|
103 |
+
|
104 |
+
return $sanitized;
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Display this setting
|
109 |
+
* @since 2.0.a.5
|
110 |
+
*/
|
111 |
+
public function display_setting() {
|
112 |
+
|
113 |
+
wp_localize_script(
|
114 |
+
'sap-address',
|
115 |
+
'sap_address',
|
116 |
+
array(
|
117 |
+
'strings' => $this->strings,
|
118 |
+
'api_key' => $this->api_key,
|
119 |
+
'api_key_selector' => $this->api_key_selector,
|
120 |
+
)
|
121 |
+
);
|
122 |
+
|
123 |
+
$this->display_description();
|
124 |
+
|
125 |
+
?>
|
126 |
+
|
127 |
+
<div class="sap-address" id="<?php echo $this->id; ?>">
|
128 |
+
<textarea name="<?php echo $this->get_input_name(); ?>[text]" id="<?php echo $this->get_input_name(); ?>" class="<?php echo $this->size; ?>-text"<?php echo !empty( $this->placeholder ) ? ' placeholder="' . esc_attr( $this->placeholder ) . '"' : ''; ?> <?php echo ( $this->disabled ? 'disabled' : ''); ?>><?php echo $this->value['text']; ?></textarea>
|
129 |
+
<p class="sap-map-coords-wrapper">
|
130 |
+
<span class="dashicons dashicons-location-alt"></span>
|
131 |
+
<span class="sap-map-coords">
|
132 |
+
<?php if ( empty( $this->value['lat'] ) || empty( $this->value['lon'] ) ) : ?>
|
133 |
+
<?php echo $this->strings['no-setting']; ?>
|
134 |
+
<?php else : ?>
|
135 |
+
<?php echo $this->value['lat'] . $this->strings['sep-lat-lon'] . $this->value['lon']; ?>
|
136 |
+
<a href="//maps.google.com/maps?q=<?php echo esc_attr( $this->value['lat'] ) . ',' . esc_attr( $this->value['lon'] ); ?>" class="sap-view-coords" target="_blank"><?php echo $this->strings['view']; ?></a>
|
137 |
+
<?php endif; ?>
|
138 |
+
</span>
|
139 |
+
</p>
|
140 |
+
<p class="sap-coords-action-wrapper">
|
141 |
+
<a href="#" class="sap-get-coords">
|
142 |
+
<?php echo $this->strings['retrieve']; ?>
|
143 |
+
</a>
|
144 |
+
<?php echo $this->strings['sep-action-links']; ?>
|
145 |
+
<a href="#" class="sap-remove-coords">
|
146 |
+
<?php echo $this->strings['remove']; ?>
|
147 |
+
</a>
|
148 |
+
</p>
|
149 |
+
<input type="hidden" class="lat" name="<?php echo $this->get_input_name(); ?>[lat]" value="<?php echo $this->value['lat']; ?>">
|
150 |
+
<input type="hidden" class="lon" name="<?php echo $this->get_input_name(); ?>[lon]" value="<?php echo $this->value['lon']; ?>">
|
151 |
+
</div>
|
152 |
+
|
153 |
+
<?php
|
154 |
+
}
|
155 |
+
|
156 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSetting.Checkbox.class.php
CHANGED
@@ -1,52 +1,67 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Register, display and save an option with multiple checkboxes.
|
5 |
-
*
|
6 |
-
* This setting accepts the following arguments in its constructor function.
|
7 |
-
*
|
8 |
-
* $args = array(
|
9 |
-
* 'id' => 'setting_id', // Unique id
|
10 |
-
* 'title' => 'My Setting', // Title or label for the setting
|
11 |
-
* 'description' => 'Description', // Help text description
|
12 |
-
* 'options' => array(
|
13 |
-
* 'value' => 'Name'
|
14 |
-
* ), // The checkbox values and text
|
15 |
-
* );
|
16 |
-
* );
|
17 |
-
*
|
18 |
-
* @since 2.0
|
19 |
-
* @package Simple Admin Pages
|
20 |
-
*/
|
21 |
-
|
22 |
-
class
|
23 |
-
|
24 |
-
//public $sanitize_callback = 'sanitize_text_field';
|
25 |
-
|
26 |
-
/**
|
27 |
-
* Display this setting
|
28 |
-
* @since 2.0
|
29 |
-
*/
|
30 |
-
public function display_setting() {
|
31 |
-
|
32 |
-
$input_name = $this->get_input_name();
|
33 |
-
$values = (is_array($this->value) ? $this->value : array());
|
34 |
-
|
35 |
-
?>
|
36 |
-
<fieldset
|
37 |
-
<?php foreach ( $this->options as $id => $title ) : ?>
|
38 |
-
<label title="<?php echo $title; ?>" class="
|
39 |
-
<input type="checkbox" name="<?php echo $input_name; ?>[]" id="<?php echo $input_name . "-" . $id; ?>" value="<?php echo $id; ?>" <?php echo ( in_array($id, $values) ? 'checked="checked"' : '' ) ?> <?php echo ( $this->disabled ? 'disabled' : ''); ?> />
|
40 |
-
<span class='
|
41 |
-
</label>
|
42 |
-
|
43 |
-
<?php
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save an option with multiple checkboxes.
|
5 |
+
*
|
6 |
+
* This setting accepts the following arguments in its constructor function.
|
7 |
+
*
|
8 |
+
* $args = array(
|
9 |
+
* 'id' => 'setting_id', // Unique id
|
10 |
+
* 'title' => 'My Setting', // Title or label for the setting
|
11 |
+
* 'description' => 'Description', // Help text description
|
12 |
+
* 'options' => array(
|
13 |
+
* 'value' => 'Name'
|
14 |
+
* ), // The checkbox values and text
|
15 |
+
* );
|
16 |
+
* );
|
17 |
+
*
|
18 |
+
* @since 2.0
|
19 |
+
* @package Simple Admin Pages
|
20 |
+
*/
|
21 |
+
|
22 |
+
class sapAdminPageSettingCheckbox_2_5_5 extends sapAdminPageSetting_2_5_5 {
|
23 |
+
|
24 |
+
//public $sanitize_callback = 'sanitize_text_field';
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Display this setting
|
28 |
+
* @since 2.0
|
29 |
+
*/
|
30 |
+
public function display_setting() {
|
31 |
+
|
32 |
+
$input_name = $this->get_input_name();
|
33 |
+
$values = ( is_array( $this->value ) ? $this->value : array() );
|
34 |
+
|
35 |
+
?>
|
36 |
+
<fieldset <?php echo ( isset( $this->columns ) ? 'class="sap-setting-columns-' . $this->columns . '"' : '' ); ?>>
|
37 |
+
<?php foreach ( $this->options as $id => $title ) : ?>
|
38 |
+
<label title="<?php echo ( strpos( $title, '<' ) === false ? $title : ''); ?>" class="sap-admin-input-container">
|
39 |
+
<input type="checkbox" name="<?php echo $input_name; ?>[]" id="<?php echo $input_name . "-" . $id; ?>" value="<?php echo $id; ?>" <?php echo ( in_array($id, $values) ? 'checked="checked"' : '' ) ?> <?php echo ( $this->disabled ? 'disabled' : ''); ?> />
|
40 |
+
<span class='sap-admin-checkbox'></span> <span><?php echo $title; ?></span>
|
41 |
+
</label>
|
42 |
+
<?php endforeach; ?>
|
43 |
+
<?php $this->display_disabled(); ?>
|
44 |
+
</fieldset>
|
45 |
+
<?php
|
46 |
+
|
47 |
+
$this->display_description();
|
48 |
+
|
49 |
+
}
|
50 |
+
|
51 |
+
public function sanitize_callback_wrapper( $values ) {
|
52 |
+
|
53 |
+
return is_array( $values ) ? array_map( $this->sanitize_callback, $values ) : array();
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Escape the value to display it safely HTML textarea fields
|
58 |
+
*/
|
59 |
+
public function esc_value( $values ) {
|
60 |
+
|
61 |
+
$return = is_array( $values ) ? array_map( 'esc_attr', $values ) : $values;
|
62 |
+
$return = is_string( $return ) ? esc_attr( $return ) : $return;
|
63 |
+
|
64 |
+
return $return;
|
65 |
+
}
|
66 |
+
|
67 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSetting.ColorPicker.class.php
CHANGED
@@ -1,39 +1,39 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Register, display and save a color picker field setting in the admin menu
|
5 |
-
*
|
6 |
-
* @since 1.0
|
7 |
-
* @package Simple Admin Pages
|
8 |
-
*/
|
9 |
-
|
10 |
-
class
|
11 |
-
|
12 |
-
public $sanitize_callback = 'sanitize_text_field';
|
13 |
-
|
14 |
-
/**
|
15 |
-
* Placeholder string for the input field
|
16 |
-
* @since 2.0
|
17 |
-
*/
|
18 |
-
public $placeholder = '';
|
19 |
-
|
20 |
-
/**
|
21 |
-
* Display this setting
|
22 |
-
* @since 1.0
|
23 |
-
*/
|
24 |
-
public function display_setting() {
|
25 |
-
?>
|
26 |
-
|
27 |
-
<fieldset>
|
28 |
-
<input class="
|
29 |
-
|
30 |
-
<?php $this->display_disabled(); ?>
|
31 |
-
</fieldset>
|
32 |
-
|
33 |
-
<?php
|
34 |
-
|
35 |
-
$this->display_description();
|
36 |
-
|
37 |
-
}
|
38 |
-
|
39 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save a color picker field setting in the admin menu
|
5 |
+
*
|
6 |
+
* @since 1.0
|
7 |
+
* @package Simple Admin Pages
|
8 |
+
*/
|
9 |
+
|
10 |
+
class sapAdminPageSettingColorPicker_2_5_5 extends sapAdminPageSetting_2_5_5 {
|
11 |
+
|
12 |
+
public $sanitize_callback = 'sanitize_text_field';
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Placeholder string for the input field
|
16 |
+
* @since 2.0
|
17 |
+
*/
|
18 |
+
public $placeholder = '';
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Display this setting
|
22 |
+
* @since 1.0
|
23 |
+
*/
|
24 |
+
public function display_setting() {
|
25 |
+
?>
|
26 |
+
|
27 |
+
<fieldset class="sap-colorpicker">
|
28 |
+
<input class="sap-spectrum" name="<?php echo $this->get_input_name(); ?>" type="text" id="<?php echo $this->get_input_name(); ?>" value="<?php echo $this->value; ?>"<?php echo !empty( $this->placeholder ) ? ' placeholder="' . esc_attr( $this->placeholder ) . '"' : ''; ?> class="regular-text" <?php echo ( $this->disabled ? 'disabled' : ''); ?> />
|
29 |
+
|
30 |
+
<?php $this->display_disabled(); ?>
|
31 |
+
</fieldset>
|
32 |
+
|
33 |
+
<?php
|
34 |
+
|
35 |
+
$this->display_description();
|
36 |
+
|
37 |
+
}
|
38 |
+
|
39 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSetting.Count.class.php
CHANGED
@@ -1,111 +1,117 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Register, display and save a count/unit option with drop-down menus.
|
5 |
-
*
|
6 |
-
* This setting accepts the following arguments in its constructor function.
|
7 |
-
*
|
8 |
-
* $args = array(
|
9 |
-
* 'id' => 'setting_id', // Unique id
|
10 |
-
* 'title' => 'My Setting', // Title or label for the setting
|
11 |
-
* 'description' => 'Description', // Help text description
|
12 |
-
* 'blank_option' => true, // Whether or not to show a blank option
|
13 |
-
* 'min_value' => 0, // The lowest value to include
|
14 |
-
* 'max_value' => 10, // The highest value to include
|
15 |
-
* 'increment' => 1, // How many values to increase by each loop
|
16 |
-
* 'units' => array( // An array of key/value pairs which
|
17 |
-
* 'unit_one' => 'Unit 1', // Define the units.
|
18 |
-
* 'unit_two' => 'Unit 2',
|
19 |
-
* ...
|
20 |
-
* );
|
21 |
-
* );
|
22 |
-
*
|
23 |
-
* @since 2.0
|
24 |
-
* @package Simple Admin Pages
|
25 |
-
*/
|
26 |
-
|
27 |
-
class
|
28 |
-
|
29 |
-
public $sanitize_callback = 'sanitize_text_field';
|
30 |
-
|
31 |
-
/**
|
32 |
-
* Add in the JS requried for rows to be added and the values to be stored
|
33 |
-
* @since 2.0
|
34 |
-
*/
|
35 |
-
public $scripts = array(
|
36 |
-
'sap-
|
37 |
-
'path' => 'js/count.js',
|
38 |
-
'dependencies' => array( 'jquery' ),
|
39 |
-
'version' =>
|
40 |
-
'footer' => true,
|
41 |
-
),
|
42 |
-
);
|
43 |
-
|
44 |
-
// Whether or not to display a blank option
|
45 |
-
public $blank_option = true;
|
46 |
-
|
47 |
-
// The default value for the field when none has been set
|
48 |
-
public $default;
|
49 |
-
|
50 |
-
// The lowest value to include
|
51 |
-
public $min_value = 0;
|
52 |
-
|
53 |
-
// The lowest value to include
|
54 |
-
public $max_value = 10;
|
55 |
-
|
56 |
-
// The lowest value to include
|
57 |
-
public $increment = 1;
|
58 |
-
|
59 |
-
// An array of options for this select field, accepted as a key/value pair.
|
60 |
-
public $units = array();
|
61 |
-
|
62 |
-
/**
|
63 |
-
* Display this setting
|
64 |
-
* @since 1.0
|
65 |
-
*/
|
66 |
-
public function display_setting() {
|
67 |
-
|
68 |
-
$this->value = $this->value ? $this->value : $this->default;
|
69 |
-
|
70 |
-
$count = substr( $this->value, 0, strpos( $this->value, '_' ) );
|
71 |
-
$unit = substr( $this->value, strpos( $this->value, '_' ) + 1 );
|
72 |
-
|
73 |
-
?>
|
74 |
-
|
75 |
-
<fieldset>
|
76 |
-
<input id='<?php echo $this->id; ?>' type='hidden' name='<?php echo $this->get_input_name(); ?>' value='<?php echo $this->value; ?>' />
|
77 |
-
<select id="<?php echo $this->id; ?>_count" <?php echo ( $this->disabled ? 'disabled' : ''); ?> class='sap-count-count' data-id='<?php echo $this->id; ?>'>
|
78 |
-
|
79 |
-
<?php if ( $this->blank_option === true ) : ?>
|
80 |
-
<option></option>
|
81 |
-
<?php endif; ?>
|
82 |
-
|
83 |
-
<?php for ( $i = $this->min_value; $i <= $this->max_value; $i = $i + $this->increment ) : ?>
|
84 |
-
<option value="<?php echo $i; ?>"<?php if( $count == $i ) : ?> selected="selected"<?php endif; ?>><?php echo $i; ?></option>
|
85 |
-
<?php endfor; ?>
|
86 |
-
|
87 |
-
</select>
|
88 |
-
|
89 |
-
<?php if ( ! empty($this->units) ) { ?>
|
90 |
-
|
91 |
-
|
92 |
-
<?php
|
93 |
-
|
94 |
-
<?php
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save a count/unit option with drop-down menus.
|
5 |
+
*
|
6 |
+
* This setting accepts the following arguments in its constructor function.
|
7 |
+
*
|
8 |
+
* $args = array(
|
9 |
+
* 'id' => 'setting_id', // Unique id
|
10 |
+
* 'title' => 'My Setting', // Title or label for the setting
|
11 |
+
* 'description' => 'Description', // Help text description
|
12 |
+
* 'blank_option' => true, // Whether or not to show a blank option
|
13 |
+
* 'min_value' => 0, // The lowest value to include
|
14 |
+
* 'max_value' => 10, // The highest value to include
|
15 |
+
* 'increment' => 1, // How many values to increase by each loop
|
16 |
+
* 'units' => array( // An array of key/value pairs which
|
17 |
+
* 'unit_one' => 'Unit 1', // Define the units.
|
18 |
+
* 'unit_two' => 'Unit 2',
|
19 |
+
* ...
|
20 |
+
* );
|
21 |
+
* );
|
22 |
+
*
|
23 |
+
* @since 2.0
|
24 |
+
* @package Simple Admin Pages
|
25 |
+
*/
|
26 |
+
|
27 |
+
class sapAdminPageSettingCount_2_5_5 extends sapAdminPageSetting_2_5_5 {
|
28 |
+
|
29 |
+
public $sanitize_callback = 'sanitize_text_field';
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Add in the JS requried for rows to be added and the values to be stored
|
33 |
+
* @since 2.0
|
34 |
+
*/
|
35 |
+
public $scripts = array(
|
36 |
+
'sap-count' => array(
|
37 |
+
'path' => 'js/count.js',
|
38 |
+
'dependencies' => array( 'jquery' ),
|
39 |
+
'version' => SAP_VERSION,
|
40 |
+
'footer' => true,
|
41 |
+
),
|
42 |
+
);
|
43 |
+
|
44 |
+
// Whether or not to display a blank option
|
45 |
+
public $blank_option = true;
|
46 |
+
|
47 |
+
// The default value for the field when none has been set
|
48 |
+
public $default;
|
49 |
+
|
50 |
+
// The lowest value to include
|
51 |
+
public $min_value = 0;
|
52 |
+
|
53 |
+
// The lowest value to include
|
54 |
+
public $max_value = 10;
|
55 |
+
|
56 |
+
// The lowest value to include
|
57 |
+
public $increment = 1;
|
58 |
+
|
59 |
+
// An array of options for this select field, accepted as a key/value pair.
|
60 |
+
public $units = array();
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Display this setting
|
64 |
+
* @since 1.0
|
65 |
+
*/
|
66 |
+
public function display_setting() {
|
67 |
+
|
68 |
+
$this->value = $this->value ? $this->value : $this->default;
|
69 |
+
|
70 |
+
$count = strpos( $this->value, '_' ) !== false ? substr( $this->value, 0, strpos( $this->value, '_' ) ) : $this->value;
|
71 |
+
$unit = substr( $this->value, strpos( $this->value, '_' ) + 1 );
|
72 |
+
|
73 |
+
?>
|
74 |
+
|
75 |
+
<fieldset>
|
76 |
+
<input id='<?php echo $this->id; ?>' type='hidden' name='<?php echo $this->get_input_name(); ?>' value='<?php echo $this->value; ?>' />
|
77 |
+
<select id="<?php echo $this->id; ?>_count" <?php echo ( $this->disabled ? 'disabled' : ''); ?> class='sap-count-count' data-id='<?php echo $this->id; ?>'>
|
78 |
+
|
79 |
+
<?php if ( $this->blank_option === true ) : ?>
|
80 |
+
<option></option>
|
81 |
+
<?php endif; ?>
|
82 |
+
|
83 |
+
<?php for ( $i = $this->min_value; $i <= $this->max_value; $i = $i + $this->increment ) : ?>
|
84 |
+
<option value="<?php echo $i; ?>"<?php if( $count == $i ) : ?> selected="selected"<?php endif; ?>><?php echo $i; ?></option>
|
85 |
+
<?php endfor; ?>
|
86 |
+
|
87 |
+
</select>
|
88 |
+
|
89 |
+
<?php if ( ! empty($this->units) ) { ?>
|
90 |
+
|
91 |
+
<?php if ( sizeof( $this->units ) == 1 ) { ?>
|
92 |
+
<input type='hidden' id='<?php echo $this->id; ?>_unit' data-id='<?php echo $this->id; ?>' /><span><?php echo esc_html( reset( $this->units ) ); ?></span>
|
93 |
+
<?php } else { ?>
|
94 |
+
<select id='<?php echo $this->id; ?>_unit' <?php echo ( $this->disabled ? 'disabled' : ''); ?> class='sap-count-unit' data-id='<?php echo $this->id; ?>'>
|
95 |
+
|
96 |
+
<?php if ( $this->blank_option === true ) : ?>
|
97 |
+
<option></option>
|
98 |
+
<?php endif; ?>
|
99 |
+
|
100 |
+
<?php foreach ( $this->units as $id => $title ) : ?>
|
101 |
+
<option value='<?php echo esc_attr( $id ); ?>' <?php if( $unit == $id ) : ?> selected="selected"<?php endif; ?>><?php echo esc_html( $title ); ?></option>
|
102 |
+
<?php endforeach; ?>
|
103 |
+
|
104 |
+
</select>
|
105 |
+
<?php } ?>
|
106 |
+
|
107 |
+
<?php } ?>
|
108 |
+
<?php $this->display_disabled(); ?>
|
109 |
+
</fieldset>
|
110 |
+
|
111 |
+
<?php
|
112 |
+
|
113 |
+
$this->display_description();
|
114 |
+
|
115 |
+
}
|
116 |
+
|
117 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSetting.Editor.class.php
CHANGED
@@ -1,44 +1,44 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Register, display and save a TinyMC Editor field setting in the admin menu
|
5 |
-
*
|
6 |
-
* @since 1.0
|
7 |
-
* @package Simple Admin Pages
|
8 |
-
*/
|
9 |
-
|
10 |
-
class
|
11 |
-
|
12 |
-
public $sanitize_callback = 'wp_kses_post';
|
13 |
-
|
14 |
-
/**
|
15 |
-
* List of arguments accepted by wp_editor
|
16 |
-
* @since 2.0
|
17 |
-
*/
|
18 |
-
public $args = array();
|
19 |
-
|
20 |
-
/**
|
21 |
-
* wp_editor() will handle the escaping
|
22 |
-
* @since 2.0
|
23 |
-
*/
|
24 |
-
public function esc_value( $val ) {
|
25 |
-
return $val;
|
26 |
-
}
|
27 |
-
|
28 |
-
/**
|
29 |
-
* Display this setting
|
30 |
-
* @since 2.0
|
31 |
-
*/
|
32 |
-
public function display_setting() {
|
33 |
-
|
34 |
-
$this->args['textarea_name'] = $this->get_input_name();
|
35 |
-
|
36 |
-
$value = empty( $this->value ) && !empty( $this->default ) ? $this->default : $this->value;
|
37 |
-
|
38 |
-
wp_editor( $value, preg_replace( '/[^\da-z]/i', '', $this->id), $this->args );
|
39 |
-
|
40 |
-
$this->display_description();
|
41 |
-
|
42 |
-
}
|
43 |
-
|
44 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save a TinyMC Editor field setting in the admin menu
|
5 |
+
*
|
6 |
+
* @since 1.0
|
7 |
+
* @package Simple Admin Pages
|
8 |
+
*/
|
9 |
+
|
10 |
+
class sapAdminPageSettingEditor_2_5_5 extends sapAdminPageSetting_2_5_5 {
|
11 |
+
|
12 |
+
public $sanitize_callback = 'wp_kses_post';
|
13 |
+
|
14 |
+
/**
|
15 |
+
* List of arguments accepted by wp_editor
|
16 |
+
* @since 2.0
|
17 |
+
*/
|
18 |
+
public $args = array();
|
19 |
+
|
20 |
+
/**
|
21 |
+
* wp_editor() will handle the escaping
|
22 |
+
* @since 2.0
|
23 |
+
*/
|
24 |
+
public function esc_value( $val ) {
|
25 |
+
return $val;
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Display this setting
|
30 |
+
* @since 2.0
|
31 |
+
*/
|
32 |
+
public function display_setting() {
|
33 |
+
|
34 |
+
$this->args['textarea_name'] = $this->get_input_name();
|
35 |
+
|
36 |
+
$value = empty( $this->value ) && !empty( $this->default ) ? $this->default : $this->value;
|
37 |
+
|
38 |
+
wp_editor( $value, preg_replace( '/[^\da-z]/i', '', $this->id), $this->args );
|
39 |
+
|
40 |
+
$this->display_description();
|
41 |
+
|
42 |
+
}
|
43 |
+
|
44 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSetting.FileUpload.class.php
ADDED
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save an option for uploading an image/file.
|
5 |
+
*
|
6 |
+
* This setting accepts the following arguments in its constructor function.
|
7 |
+
*
|
8 |
+
* $args = array(
|
9 |
+
* 'id' => 'setting_id', // Unique id
|
10 |
+
* 'title' => 'My Setting', // Title or label for the setting
|
11 |
+
* 'description' => 'Description', // Help text description
|
12 |
+
* );
|
13 |
+
*
|
14 |
+
* @since 2.5
|
15 |
+
* @package Simple Admin Pages
|
16 |
+
*/
|
17 |
+
|
18 |
+
class sapAdminPageSettingFileUpload_2_5_5 extends sapAdminPageSetting_2_5_5 {
|
19 |
+
|
20 |
+
public $sanitize_callback = 'esc_url_raw';
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Add in the JS requried to allow file uploading
|
24 |
+
* @since 2.5
|
25 |
+
*/
|
26 |
+
public $scripts = array(
|
27 |
+
'sap-file-upload' => array(
|
28 |
+
'path' => 'js/file_upload.js',
|
29 |
+
'dependencies' => array( 'jquery' ),
|
30 |
+
'version' => SAP_VERSION,
|
31 |
+
'footer' => true,
|
32 |
+
),
|
33 |
+
);
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Display this setting
|
37 |
+
* @since 2.5
|
38 |
+
*/
|
39 |
+
public function display_setting() {
|
40 |
+
|
41 |
+
?>
|
42 |
+
|
43 |
+
<span class="sap-file-upload-preview">
|
44 |
+
|
45 |
+
<span class="sap-file-upload-preview-label">
|
46 |
+
<?php _e( 'Current image:', 'simple-admin-pages' ); ?>
|
47 |
+
</span>
|
48 |
+
|
49 |
+
<span class="sap-file-upload-preview-value">
|
50 |
+
<?php echo $this->value; ?>
|
51 |
+
</span>
|
52 |
+
|
53 |
+
</span>
|
54 |
+
|
55 |
+
<?php echo ( $this->value != '' ? '<br /><br />' : '' ); ?>
|
56 |
+
|
57 |
+
<input name="<?php echo $this->get_input_name(); ?>" type="hidden" id="<?php echo $this->get_input_name(); ?>" class="file-upload" value="<?php echo $this->value; ?>" />
|
58 |
+
|
59 |
+
<input class="button sap-file-upload-button" type="button" value="<?php _e( 'Upload Image', 'simple-admin-pages' ); ?>" />
|
60 |
+
|
61 |
+
<br /><br />
|
62 |
+
|
63 |
+
<?php $this->display_disabled(); ?>
|
64 |
+
|
65 |
+
<?php
|
66 |
+
|
67 |
+
$this->display_description();
|
68 |
+
|
69 |
+
}
|
70 |
+
|
71 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSetting.HTML.class.php
CHANGED
@@ -1,33 +1,33 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Register and save an arbitrary HTML chunk in the admin menu
|
5 |
-
*
|
6 |
-
* This allows you to easily add in a dummy "setting" with any arbitrary HTML
|
7 |
-
* code. It's good for displaying a link to documentation, upgrades or anything
|
8 |
-
* else you can think of.
|
9 |
-
*
|
10 |
-
* Data in this field will not be saved or passed. It's purely for presenting
|
11 |
-
* information.
|
12 |
-
*
|
13 |
-
* @since 1.0
|
14 |
-
* @package Simple Admin Pages
|
15 |
-
*/
|
16 |
-
|
17 |
-
class
|
18 |
-
|
19 |
-
public $sanitize_callback = 'sanitize_text_field';
|
20 |
-
|
21 |
-
/**
|
22 |
-
* Display this setting
|
23 |
-
* @since 1.0
|
24 |
-
*/
|
25 |
-
public function display_setting() {
|
26 |
-
|
27 |
-
echo $this->html;
|
28 |
-
|
29 |
-
$this->display_description();
|
30 |
-
|
31 |
-
}
|
32 |
-
|
33 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register and save an arbitrary HTML chunk in the admin menu
|
5 |
+
*
|
6 |
+
* This allows you to easily add in a dummy "setting" with any arbitrary HTML
|
7 |
+
* code. It's good for displaying a link to documentation, upgrades or anything
|
8 |
+
* else you can think of.
|
9 |
+
*
|
10 |
+
* Data in this field will not be saved or passed. It's purely for presenting
|
11 |
+
* information.
|
12 |
+
*
|
13 |
+
* @since 1.0
|
14 |
+
* @package Simple Admin Pages
|
15 |
+
*/
|
16 |
+
|
17 |
+
class sapAdminPageSettingHTML_2_5_5 extends sapAdminPageSetting_2_5_5 {
|
18 |
+
|
19 |
+
public $sanitize_callback = 'sanitize_text_field';
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Display this setting
|
23 |
+
* @since 1.0
|
24 |
+
*/
|
25 |
+
public function display_setting() {
|
26 |
+
|
27 |
+
echo $this->html;
|
28 |
+
|
29 |
+
$this->display_description();
|
30 |
+
|
31 |
+
}
|
32 |
+
|
33 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSetting.Image.class.php
CHANGED
@@ -1,62 +1,62 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Register, display and save an image field setting in the admin menu
|
5 |
-
*
|
6 |
-
* @since 1.0
|
7 |
-
* @package Simple Admin Pages
|
8 |
-
*/
|
9 |
-
|
10 |
-
class
|
11 |
-
|
12 |
-
public $sanitize_callback = 'absint';
|
13 |
-
|
14 |
-
/**
|
15 |
-
* Scripts that must be loaded for this component
|
16 |
-
* @since 2.1.0
|
17 |
-
*/
|
18 |
-
public $scripts = array(
|
19 |
-
'sap-image' => array(
|
20 |
-
'path' => 'js/image.js',
|
21 |
-
'dependencies' => array( 'jquery' ),
|
22 |
-
'version' =>
|
23 |
-
'footer' => true,
|
24 |
-
),
|
25 |
-
);
|
26 |
-
|
27 |
-
/**
|
28 |
-
* Translateable strings required for this component
|
29 |
-
* @since 2.1.0
|
30 |
-
*/
|
31 |
-
public $strings = array(
|
32 |
-
'add_image' => null, // __( 'Add Image', 'textdomain' ),
|
33 |
-
'change_image' => null, // __( 'Change Image', 'textdomain' ),
|
34 |
-
'remove_image' => null, // __( 'Remove Image', 'textdomain' ),
|
35 |
-
);
|
36 |
-
|
37 |
-
/**
|
38 |
-
* Display this setting
|
39 |
-
* @since 1.0
|
40 |
-
*/
|
41 |
-
public function display_setting() {
|
42 |
-
$image_url = $this->value ? wp_get_attachment_url( $this->value ) : '';
|
43 |
-
?>
|
44 |
-
|
45 |
-
<div class="sap-image-wrapper <?php echo $this->value ? 'sap-image-wrapper-has-image' : 'sap-image-wrapper-no-image'; ?>" data-id="sap-<?php echo $this->id; ?>">
|
46 |
-
<input name="<?php echo $this->get_input_name(); ?>" type="hidden" id="sap-<?php echo $this->id; ?>" value="<?php echo $this->value; ?>">
|
47 |
-
<img src="<?php echo esc_attr( $image_url ); ?>">
|
48 |
-
<button class="button sap-image-btn-add" id="sap-<?php echo $this->id; ?>-add"><?php echo esc_html( $this->strings['add_image'] ); ?></button>
|
49 |
-
<button class="button sap-image-btn-change" id="sap-<?php echo $this->id; ?>-change"><?php echo esc_html( $this->strings['change_image'] ); ?></button>
|
50 |
-
<button class="button sap-image-btn-remove" id="sap-<?php echo $this->id; ?>-remove"><?php echo esc_html( $this->strings['remove_image'] ); ?></button>
|
51 |
-
</div>
|
52 |
-
|
53 |
-
<?php
|
54 |
-
|
55 |
-
// global $wp_scripts;
|
56 |
-
// print_r( $wp_scripts );
|
57 |
-
|
58 |
-
$this->display_description();
|
59 |
-
|
60 |
-
}
|
61 |
-
|
62 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save an image field setting in the admin menu
|
5 |
+
*
|
6 |
+
* @since 1.0
|
7 |
+
* @package Simple Admin Pages
|
8 |
+
*/
|
9 |
+
|
10 |
+
class sapAdminPageSettingImage_2_5_5 extends sapAdminPageSetting_2_5_5 {
|
11 |
+
|
12 |
+
public $sanitize_callback = 'absint';
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Scripts that must be loaded for this component
|
16 |
+
* @since 2.1.0
|
17 |
+
*/
|
18 |
+
public $scripts = array(
|
19 |
+
'sap-image' => array(
|
20 |
+
'path' => 'js/image.js',
|
21 |
+
'dependencies' => array( 'jquery' ),
|
22 |
+
'version' => SAP_VERSION,
|
23 |
+
'footer' => true,
|
24 |
+
),
|
25 |
+
);
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Translateable strings required for this component
|
29 |
+
* @since 2.1.0
|
30 |
+
*/
|
31 |
+
public $strings = array(
|
32 |
+
'add_image' => null, // __( 'Add Image', 'textdomain' ),
|
33 |
+
'change_image' => null, // __( 'Change Image', 'textdomain' ),
|
34 |
+
'remove_image' => null, // __( 'Remove Image', 'textdomain' ),
|
35 |
+
);
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Display this setting
|
39 |
+
* @since 1.0
|
40 |
+
*/
|
41 |
+
public function display_setting() {
|
42 |
+
$image_url = $this->value ? wp_get_attachment_url( $this->value ) : '';
|
43 |
+
?>
|
44 |
+
|
45 |
+
<div class="sap-image-wrapper <?php echo $this->value ? 'sap-image-wrapper-has-image' : 'sap-image-wrapper-no-image'; ?>" data-id="sap-<?php echo $this->id; ?>">
|
46 |
+
<input name="<?php echo $this->get_input_name(); ?>" type="hidden" id="sap-<?php echo $this->id; ?>" value="<?php echo $this->value; ?>">
|
47 |
+
<img src="<?php echo esc_attr( $image_url ); ?>">
|
48 |
+
<button class="button sap-image-btn-add" id="sap-<?php echo $this->id; ?>-add"><?php echo esc_html( $this->strings['add_image'] ); ?></button>
|
49 |
+
<button class="button sap-image-btn-change" id="sap-<?php echo $this->id; ?>-change"><?php echo esc_html( $this->strings['change_image'] ); ?></button>
|
50 |
+
<button class="button sap-image-btn-remove" id="sap-<?php echo $this->id; ?>-remove"><?php echo esc_html( $this->strings['remove_image'] ); ?></button>
|
51 |
+
</div>
|
52 |
+
|
53 |
+
<?php
|
54 |
+
|
55 |
+
// global $wp_scripts;
|
56 |
+
// print_r( $wp_scripts );
|
57 |
+
|
58 |
+
$this->display_description();
|
59 |
+
|
60 |
+
}
|
61 |
+
|
62 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSetting.InfiniteTable.class.php
CHANGED
@@ -1,149 +1,201 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Register, display and save an option with multiple checkboxes.
|
5 |
-
*
|
6 |
-
* This setting accepts the following arguments in its constructor function.
|
7 |
-
*
|
8 |
-
* $args = array(
|
9 |
-
* 'id' => 'setting_id', // Unique id
|
10 |
-
* 'title' => 'My Setting', // Title or label for the setting
|
11 |
-
* 'add_label' => 'Add Row', // Text for the "Add Row" button
|
12 |
-
* 'description' => 'Description', // Help text description
|
13 |
-
* 'fields' => array(
|
14 |
-
* 'field' => array(
|
15 |
-
* 'type' => 'text' //text, select
|
16 |
-
* 'label' => 'Name'
|
17 |
-
* 'required' => false,
|
18 |
-
* 'options' => array()
|
19 |
-
* )
|
20 |
-
* ) // The attributes and labels for the fields
|
21 |
-
* );
|
22 |
-
*
|
23 |
-
* @since 2.0
|
24 |
-
* @package Simple Admin Pages
|
25 |
-
*/
|
26 |
-
|
27 |
-
class
|
28 |
-
|
29 |
-
public $sanitize_callback = '
|
30 |
-
|
31 |
-
/**
|
32 |
-
* Add in the JS requried for rows to be added and the values to be stored
|
33 |
-
* @since 2.0
|
34 |
-
*/
|
35 |
-
public $scripts = array(
|
36 |
-
'sap-infinite-table' => array(
|
37 |
-
'path' => 'js/infinite_table.js',
|
38 |
-
'dependencies' => array( 'jquery' ),
|
39 |
-
'version' =>
|
40 |
-
'footer' => true,
|
41 |
-
),
|
42 |
-
);
|
43 |
-
|
44 |
-
/**
|
45 |
-
* Add in the CSS requried for rows to be displayed correctly
|
46 |
-
* @since 2.0
|
47 |
-
*/
|
48 |
-
public $styles = array(
|
49 |
-
'sap-infinite-table' => array(
|
50 |
-
'path' => 'css/infinite_table.css',
|
51 |
-
'dependencies' => array( ),
|
52 |
-
'version' =>
|
53 |
-
'media'
|
54 |
-
),
|
55 |
-
);
|
56 |
-
|
57 |
-
/**
|
58 |
-
* Display this setting
|
59 |
-
* @since 2.0
|
60 |
-
*/
|
61 |
-
public function display_setting() {
|
62 |
-
|
63 |
-
$
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
<?php
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
<?php
|
97 |
-
|
98 |
-
|
99 |
-
<?php
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
<?php
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save an option with multiple checkboxes.
|
5 |
+
*
|
6 |
+
* This setting accepts the following arguments in its constructor function.
|
7 |
+
*
|
8 |
+
* $args = array(
|
9 |
+
* 'id' => 'setting_id', // Unique id
|
10 |
+
* 'title' => 'My Setting', // Title or label for the setting
|
11 |
+
* 'add_label' => 'Add Row', // Text for the "Add Row" button
|
12 |
+
* 'description' => 'Description', // Help text description
|
13 |
+
* 'fields' => array(
|
14 |
+
* 'field' => array(
|
15 |
+
* 'type' => 'text' //text, select
|
16 |
+
* 'label' => 'Name'
|
17 |
+
* 'required' => false,
|
18 |
+
* 'options' => array()
|
19 |
+
* )
|
20 |
+
* ) // The attributes and labels for the fields
|
21 |
+
* );
|
22 |
+
*
|
23 |
+
* @since 2.0
|
24 |
+
* @package Simple Admin Pages
|
25 |
+
*/
|
26 |
+
|
27 |
+
class sapAdminPageSettingInfiniteTable_2_5_5 extends sapAdminPageSetting_2_5_5 {
|
28 |
+
|
29 |
+
public $sanitize_callback = 'sanitize_textarea_field';
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Add in the JS requried for rows to be added and the values to be stored
|
33 |
+
* @since 2.0
|
34 |
+
*/
|
35 |
+
public $scripts = array(
|
36 |
+
'sap-infinite-table' => array(
|
37 |
+
'path' => 'js/infinite_table.js',
|
38 |
+
'dependencies' => array( 'jquery' ),
|
39 |
+
'version' => SAP_VERSION,
|
40 |
+
'footer' => true,
|
41 |
+
),
|
42 |
+
);
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Add in the CSS requried for rows to be displayed correctly
|
46 |
+
* @since 2.0
|
47 |
+
*/
|
48 |
+
public $styles = array(
|
49 |
+
'sap-infinite-table' => array(
|
50 |
+
'path' => 'css/infinite_table.css',
|
51 |
+
'dependencies' => array( ),
|
52 |
+
'version' => SAP_VERSION,
|
53 |
+
'media' => 'all',
|
54 |
+
),
|
55 |
+
);
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Display this setting
|
59 |
+
* @since 2.0
|
60 |
+
*/
|
61 |
+
public function display_setting() {
|
62 |
+
|
63 |
+
$input_name = $this->get_input_name();
|
64 |
+
$values = json_decode( html_entity_decode( $this->value ) );
|
65 |
+
|
66 |
+
if ( ! is_array( $values ) )
|
67 |
+
$values = array();
|
68 |
+
|
69 |
+
$fields = '';
|
70 |
+
foreach ($this->fields as $field_id => $field) {
|
71 |
+
$fields .= $field_id . ",";
|
72 |
+
}
|
73 |
+
$fields = trim($fields, ',');
|
74 |
+
|
75 |
+
?>
|
76 |
+
|
77 |
+
<fieldset>
|
78 |
+
<div class='sap-infinite-table <?php echo ( $this->disabled ? 'disabled' : ''); ?>' data-fieldids='<?php echo $fields; ?>'>
|
79 |
+
<input type='hidden' id="sap-infinite-table-main-input" name='<?php echo $input_name; ?>' value='<?php echo $this->value; ?>' />
|
80 |
+
<table>
|
81 |
+
<thead>
|
82 |
+
<tr>
|
83 |
+
<?php foreach ($this->fields as $field) { ?>
|
84 |
+
<th><?php echo $field['label']; ?></th>
|
85 |
+
<?php } ?>
|
86 |
+
<th></th>
|
87 |
+
</tr>
|
88 |
+
</thead>
|
89 |
+
<tbody>
|
90 |
+
<?php foreach ($values as $row) { ?>
|
91 |
+
<tr class='sap-infinite-table-row'>
|
92 |
+
<?php foreach ($this->fields as $field_id => $field) { ?>
|
93 |
+
<td>
|
94 |
+
<?php if ($field['type'] == 'text') : ?>
|
95 |
+
<input type='text' data-name='<?php echo $field_id; ?>' value='<?php echo $row->$field_id; ?>' />
|
96 |
+
<?php endif; ?>
|
97 |
+
<?php if ($field['type'] == 'textarea') : ?>
|
98 |
+
<textarea data-name='<?php echo $field_id; ?>'><?php echo $row->$field_id; ?></textarea>
|
99 |
+
<?php endif; ?>
|
100 |
+
<?php if ($field['type'] == 'hidden') : ?>
|
101 |
+
<span class='sap-infinite-table-hidden-value'><?php echo $row->$field_id; ?></span>
|
102 |
+
<input type='hidden' data-name='<?php echo $field_id; ?>' value='<?php echo $row->$field_id; ?>' />
|
103 |
+
<?php endif; ?>
|
104 |
+
<?php if ($field['type'] == 'select') : ?>
|
105 |
+
<select data-name='<?php echo $field_id; ?>'>
|
106 |
+
<?php if ( ! empty( $field['blank_option'] ) ) { ?><option></option><?php } ?>
|
107 |
+
<?php $this->print_options( $field['options'], $row, $field_id ); ?>
|
108 |
+
</select>
|
109 |
+
<?php endif; ?>
|
110 |
+
<?php if ($field['type'] == 'toggle') : ?>
|
111 |
+
<label class="sap-admin-switch">
|
112 |
+
<input type="checkbox" class="sap-admin-option-toggle" data-name="<?php echo $field_id; ?>" <?php if( $row->$field_id == '1' ) {echo "checked='checked'";} ?> >
|
113 |
+
<span class="sap-admin-switch-slider round"></span>
|
114 |
+
</label>
|
115 |
+
<?php endif; ?>
|
116 |
+
</td>
|
117 |
+
<?php } ?>
|
118 |
+
<td class='sap-infinite-table-row-delete'><?php echo $this->del_label; ?></td>
|
119 |
+
</tr>
|
120 |
+
<?php } ?>
|
121 |
+
</tbody>
|
122 |
+
<tfoot>
|
123 |
+
<tr class='sap-infinite-table-row-template sap-hidden'>
|
124 |
+
<?php foreach ($this->fields as $field_id => $field) { ?>
|
125 |
+
<td>
|
126 |
+
<?php if ($field['type'] == 'text') : ?>
|
127 |
+
<input type='text' data-name='<?php echo $field_id; ?>' value='' />
|
128 |
+
<?php endif; ?>
|
129 |
+
<?php if ($field['type'] == 'textarea') : ?>
|
130 |
+
<textarea data-name='<?php echo $field_id; ?>'></textarea>
|
131 |
+
<?php endif; ?>
|
132 |
+
<?php if ($field['type'] == 'hidden') : ?>
|
133 |
+
<span class='sap-infinite-table-hidden-value'></span>
|
134 |
+
<input type='hidden' data-name='<?php echo $field_id; ?>' value='' />
|
135 |
+
<?php endif; ?>
|
136 |
+
<?php if ($field['type'] == 'select') : ?>
|
137 |
+
<select data-name='<?php echo $field_id; ?>'>
|
138 |
+
<?php if ( ! empty( $field['blank_option'] ) ) { ?><option></option><?php } ?>
|
139 |
+
<?php $this->print_options( $field['options'] ); ?>
|
140 |
+
</select>
|
141 |
+
<?php endif; ?>
|
142 |
+
<?php if ($field['type'] == 'toggle') : ?>
|
143 |
+
<label class="sap-admin-switch">
|
144 |
+
<input type="checkbox" class="sap-admin-option-toggle" data-name="<?php echo $field_id; ?>" checked >
|
145 |
+
<span class="sap-admin-switch-slider round"></span>
|
146 |
+
</label>
|
147 |
+
<?php endif; ?>
|
148 |
+
</td>
|
149 |
+
<?php } ?>
|
150 |
+
<td class='sap-infinite-table-row-delete'><?php echo $this->del_label; ?></td>
|
151 |
+
</tr>
|
152 |
+
<tr class='sap-infinite-table-add-row'>
|
153 |
+
<td colspan="4">
|
154 |
+
<a class="sap-new-admin-add-button"><?php echo $this->add_label; ?></a>
|
155 |
+
</td>
|
156 |
+
</tr>
|
157 |
+
</tfoot>
|
158 |
+
</table>
|
159 |
+
</div>
|
160 |
+
|
161 |
+
<?php $this->display_disabled(); ?>
|
162 |
+
</fieldset>
|
163 |
+
|
164 |
+
<?php
|
165 |
+
|
166 |
+
$this->display_description();
|
167 |
+
|
168 |
+
}
|
169 |
+
|
170 |
+
/**
|
171 |
+
* Recursively print out select options
|
172 |
+
* @since 2.5.3
|
173 |
+
*/
|
174 |
+
public function print_options( $options, $row = false, $field_id = 0 ) {
|
175 |
+
|
176 |
+
foreach ( $options as $option_value => $option_name ) {
|
177 |
+
|
178 |
+
if ( is_array( $option_name ) ) { ?>
|
179 |
+
|
180 |
+
<optgroup label='<?php echo esc_attr( $option_value ); ?>'>
|
181 |
+
<?php $this->print_options( $option_name, $row, $field_id ); ?>
|
182 |
+
</optgroup>
|
183 |
+
|
184 |
+
<?php
|
185 |
+
|
186 |
+
continue;
|
187 |
+
}
|
188 |
+
|
189 |
+
$selected_value = $row ? $row->$field_id : false;
|
190 |
+
|
191 |
+
?>
|
192 |
+
|
193 |
+
<option value='<?php echo $option_value; ?>' <?php echo ($selected_value == $option_value ? 'selected="selected"' : ''); ?>>
|
194 |
+
<?php echo $option_name; ?>
|
195 |
+
</option>
|
196 |
+
|
197 |
+
<?php
|
198 |
+
}
|
199 |
+
}
|
200 |
+
|
201 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSetting.McApiKey.class.php
CHANGED
@@ -1,221 +1,223 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Add a setting to Simple Admin Pages to register and verify a
|
5 |
-
* MailChimp API key
|
6 |
-
*
|
7 |
-
* This class is modelled on AdminPageSetting.class.php in the Simple
|
8 |
-
* Admin Pages library. It should work just like an extended class, but
|
9 |
-
* due to the way the library embeds the version into the class name,
|
10 |
-
* that could cause problems if the library is updated in the parent
|
11 |
-
* plugin.
|
12 |
-
*
|
13 |
-
* See: https://github.com/NateWr/simple-admin-pages
|
14 |
-
*
|
15 |
-
*/
|
16 |
-
|
17 |
-
class
|
18 |
-
|
19 |
-
/**
|
20 |
-
* Scripts and styles to load for this component
|
21 |
-
* (not used but required as part of the library)
|
22 |
-
*/
|
23 |
-
public $scripts = array();
|
24 |
-
public $styles = array();
|
25 |
-
|
26 |
-
/**
|
27 |
-
* Initialize the setting
|
28 |
-
*/
|
29 |
-
public function __construct( $args ) {
|
30 |
-
|
31 |
-
// Parse the values passed
|
32 |
-
$this->parse_args( $args );
|
33 |
-
|
34 |
-
// Get any existing value
|
35 |
-
$this->set_value();
|
36 |
-
|
37 |
-
// Set an error if the object is missing necessary data
|
38 |
-
if ( $this->missing_data() ) {
|
39 |
-
$this->set_error();
|
40 |
-
}
|
41 |
-
}
|
42 |
-
|
43 |
-
/**
|
44 |
-
* Parse the arguments passed in the construction and assign them to
|
45 |
-
* internal variables. This function will be overwritten for most subclasses
|
46 |
-
*/
|
47 |
-
private function parse_args( $args ) {
|
48 |
-
foreach ( $args as $key => $val ) {
|
49 |
-
switch ( $key ) {
|
50 |
-
|
51 |
-
case 'id' :
|
52 |
-
$this->{$key} = esc_attr( $val );
|
53 |
-
|
54 |
-
case 'title' :
|
55 |
-
$this->{$key} = esc_attr( $val );
|
56 |
-
|
57 |
-
default :
|
58 |
-
$this->{$key} = $val;
|
59 |
-
|
60 |
-
}
|
61 |
-
}
|
62 |
-
}
|
63 |
-
|
64 |
-
/**
|
65 |
-
* Check for missing data when setup.
|
66 |
-
*/
|
67 |
-
private function missing_data() {
|
68 |
-
|
69 |
-
// Required fields
|
70 |
-
if ( empty( $this->id ) ) {
|
71 |
-
$this->set_error(
|
72 |
-
array(
|
73 |
-
'type' => 'missing_data',
|
74 |
-
'data' => 'id'
|
75 |
-
)
|
76 |
-
);
|
77 |
-
}
|
78 |
-
if ( empty( $this->title ) ) {
|
79 |
-
$this->set_error(
|
80 |
-
array(
|
81 |
-
'type' => 'missing_data',
|
82 |
-
'data' => 'title'
|
83 |
-
)
|
84 |
-
);
|
85 |
-
}
|
86 |
-
}
|
87 |
-
|
88 |
-
/**
|
89 |
-
* Set a value
|
90 |
-
*/
|
91 |
-
public function set_value( $val = null ) {
|
92 |
-
|
93 |
-
if ( $val === null ) {
|
94 |
-
$option_group_value = get_option( $this->page );
|
95 |
-
$val = isset( $option_group_value[ $this->id ] ) ? $option_group_value[ $this->id ] : '';
|
96 |
-
}
|
97 |
-
|
98 |
-
$this->value = $this->esc_value( $val );
|
99 |
-
}
|
100 |
-
|
101 |
-
/**
|
102 |
-
* Escape the value to display it in text fields and other input fields
|
103 |
-
*/
|
104 |
-
public function esc_value( $val ) {
|
105 |
-
|
106 |
-
$value = array(
|
107 |
-
'api_key' => '',
|
108 |
-
'status' => false,
|
109 |
-
);
|
110 |
-
|
111 |
-
if ( empty( $val ) || empty( $val['api_key'] ) ) {
|
112 |
-
return $value;
|
113 |
-
}
|
114 |
-
|
115 |
-
$value['api_key'] = esc_attr( $val['api_key'] );
|
116 |
-
$value['status'] = (bool) $val['status'];
|
117 |
-
|
118 |
-
return $value;
|
119 |
-
}
|
120 |
-
|
121 |
-
/**
|
122 |
-
* Display this setting
|
123 |
-
*/
|
124 |
-
public function display_setting() {
|
125 |
-
?>
|
126 |
-
|
127 |
-
<input name="<?php echo $this->get_input_name(); ?>[api_key]" type="text" id="<?php echo $this->get_input_name(); ?>[api_key]" value="<?php echo $this->value['api_key']; ?>"<?php echo !empty( $this->placeholder ) ? ' placeholder="' . esc_attr( $this->placeholder ) . '"' : ''; ?> class="regular-text">
|
128 |
-
|
129 |
-
<?php if ( !empty( $this->value['api_key'] ) && $this->value['status'] === true ) : ?>
|
130 |
-
<span class="mcfrtb-status mcfrtb-status-connected"><?php echo $this->string_status_connected; ?></span>
|
131 |
-
<?php elseif( !empty( $this->value['api_key'] ) ) : ?>
|
132 |
-
<span class="mcfrtb-status mcfrtb-status-error"><?php echo $this->string_status_error; ?></span>
|
133 |
-
<?php endif; ?>
|
134 |
-
|
135 |
-
<input name="<?php echo $this->get_input_name(); ?>[status]" type="hidden" id="<?php echo $this->get_input_name(); ?>[status]" value="<?php echo $this->value['status']; ?>"<?php echo !empty( $this->placeholder ) ? ' placeholder="' . esc_attr( $this->placeholder ) . '"' : ''; ?>>
|
136 |
-
|
137 |
-
<?php
|
138 |
-
|
139 |
-
$this->display_description();
|
140 |
-
}
|
141 |
-
|
142 |
-
/**
|
143 |
-
* Display a description for this setting
|
144 |
-
*/
|
145 |
-
public function display_description() {
|
146 |
-
|
147 |
-
if ( !empty( $this->description ) ) : ?>
|
148 |
-
|
149 |
-
<p class="description"><?php echo $this->description; ?></p>
|
150 |
-
|
151 |
-
<?php endif;
|
152 |
-
}
|
153 |
-
|
154 |
-
/**
|
155 |
-
* Generate an option input field name, using the grouped schema.
|
156 |
-
*/
|
157 |
-
public function get_input_name() {
|
158 |
-
return esc_attr( $this->page ) . '[' . esc_attr( $this->id ) . ']';
|
159 |
-
}
|
160 |
-
|
161 |
-
|
162 |
-
/**
|
163 |
-
* Sanitize the array of text inputs for this setting
|
164 |
-
*/
|
165 |
-
public function sanitize_callback_wrapper( $values ) {
|
166 |
-
global $
|
167 |
-
|
168 |
-
$output = array(
|
169 |
-
'api_key' => '',
|
170 |
-
'status' => false,
|
171 |
-
);
|
172 |
-
|
173 |
-
// Return an empty key and status if the values don't look right
|
174 |
-
if ( !is_array( $values ) || empty( $values ) || empty( $values['api_key'] ) ) {
|
175 |
-
return $output;
|
176 |
-
}
|
177 |
-
|
178 |
-
// Sanitize the API key
|
179 |
-
$output['api_key'] = sanitize_text_field( $values['api_key'] );
|
180 |
-
|
181 |
-
$
|
182 |
-
|
183 |
-
// Check for a valid API key
|
184 |
-
$output['status'] = $
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
*
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
$this->
|
201 |
-
$
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
'
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
}
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Add a setting to Simple Admin Pages to register and verify a
|
5 |
+
* MailChimp API key
|
6 |
+
*
|
7 |
+
* This class is modelled on AdminPageSetting.class.php in the Simple
|
8 |
+
* Admin Pages library. It should work just like an extended class, but
|
9 |
+
* due to the way the library embeds the version into the class name,
|
10 |
+
* that could cause problems if the library is updated in the parent
|
11 |
+
* plugin.
|
12 |
+
*
|
13 |
+
* See: https://github.com/NateWr/simple-admin-pages
|
14 |
+
*
|
15 |
+
*/
|
16 |
+
|
17 |
+
class mcfrtbAdminPageSettingMcApiKey_2_5_5 {
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Scripts and styles to load for this component
|
21 |
+
* (not used but required as part of the library)
|
22 |
+
*/
|
23 |
+
public $scripts = array();
|
24 |
+
public $styles = array();
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Initialize the setting
|
28 |
+
*/
|
29 |
+
public function __construct( $args ) {
|
30 |
+
|
31 |
+
// Parse the values passed
|
32 |
+
$this->parse_args( $args );
|
33 |
+
|
34 |
+
// Get any existing value
|
35 |
+
$this->set_value();
|
36 |
+
|
37 |
+
// Set an error if the object is missing necessary data
|
38 |
+
if ( $this->missing_data() ) {
|
39 |
+
$this->set_error();
|
40 |
+
}
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Parse the arguments passed in the construction and assign them to
|
45 |
+
* internal variables. This function will be overwritten for most subclasses
|
46 |
+
*/
|
47 |
+
private function parse_args( $args ) {
|
48 |
+
foreach ( $args as $key => $val ) {
|
49 |
+
switch ( $key ) {
|
50 |
+
|
51 |
+
case 'id' :
|
52 |
+
$this->{$key} = esc_attr( $val );
|
53 |
+
|
54 |
+
case 'title' :
|
55 |
+
$this->{$key} = esc_attr( $val );
|
56 |
+
|
57 |
+
default :
|
58 |
+
$this->{$key} = $val;
|
59 |
+
|
60 |
+
}
|
61 |
+
}
|
62 |
+
}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Check for missing data when setup.
|
66 |
+
*/
|
67 |
+
private function missing_data() {
|
68 |
+
|
69 |
+
// Required fields
|
70 |
+
if ( empty( $this->id ) ) {
|
71 |
+
$this->set_error(
|
72 |
+
array(
|
73 |
+
'type' => 'missing_data',
|
74 |
+
'data' => 'id'
|
75 |
+
)
|
76 |
+
);
|
77 |
+
}
|
78 |
+
if ( empty( $this->title ) ) {
|
79 |
+
$this->set_error(
|
80 |
+
array(
|
81 |
+
'type' => 'missing_data',
|
82 |
+
'data' => 'title'
|
83 |
+
)
|
84 |
+
);
|
85 |
+
}
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Set a value
|
90 |
+
*/
|
91 |
+
public function set_value( $val = null ) {
|
92 |
+
|
93 |
+
if ( $val === null ) {
|
94 |
+
$option_group_value = get_option( $this->page );
|
95 |
+
$val = isset( $option_group_value[ $this->id ] ) ? $option_group_value[ $this->id ] : '';
|
96 |
+
}
|
97 |
+
|
98 |
+
$this->value = $this->esc_value( $val );
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Escape the value to display it in text fields and other input fields
|
103 |
+
*/
|
104 |
+
public function esc_value( $val ) {
|
105 |
+
|
106 |
+
$value = array(
|
107 |
+
'api_key' => '',
|
108 |
+
'status' => false,
|
109 |
+
);
|
110 |
+
|
111 |
+
if ( empty( $val ) || empty( $val['api_key'] ) ) {
|
112 |
+
return $value;
|
113 |
+
}
|
114 |
+
|
115 |
+
$value['api_key'] = esc_attr( $val['api_key'] );
|
116 |
+
$value['status'] = (bool) $val['status'];
|
117 |
+
|
118 |
+
return $value;
|
119 |
+
}
|
120 |
+
|
121 |
+
/**
|
122 |
+
* Display this setting
|
123 |
+
*/
|
124 |
+
public function display_setting() {
|
125 |
+
?>
|
126 |
+
|
127 |
+
<input name="<?php echo $this->get_input_name(); ?>[api_key]" type="text" id="<?php echo $this->get_input_name(); ?>[api_key]" value="<?php echo $this->value['api_key']; ?>"<?php echo !empty( $this->placeholder ) ? ' placeholder="' . esc_attr( $this->placeholder ) . '"' : ''; ?> class="regular-text">
|
128 |
+
|
129 |
+
<?php if ( !empty( $this->value['api_key'] ) && $this->value['status'] === true ) : ?>
|
130 |
+
<span class="mcfrtb-status mcfrtb-status-connected"><?php echo $this->string_status_connected; ?></span>
|
131 |
+
<?php elseif( !empty( $this->value['api_key'] ) ) : ?>
|
132 |
+
<span class="mcfrtb-status mcfrtb-status-error"><?php echo $this->string_status_error; ?></span>
|
133 |
+
<?php endif; ?>
|
134 |
+
|
135 |
+
<input name="<?php echo $this->get_input_name(); ?>[status]" type="hidden" id="<?php echo $this->get_input_name(); ?>[status]" value="<?php echo $this->value['status']; ?>"<?php echo !empty( $this->placeholder ) ? ' placeholder="' . esc_attr( $this->placeholder ) . '"' : ''; ?>>
|
136 |
+
|
137 |
+
<?php
|
138 |
+
|
139 |
+
$this->display_description();
|
140 |
+
}
|
141 |
+
|
142 |
+
/**
|
143 |
+
* Display a description for this setting
|
144 |
+
*/
|
145 |
+
public function display_description() {
|
146 |
+
|
147 |
+
if ( !empty( $this->description ) ) : ?>
|
148 |
+
|
149 |
+
<p class="description"><?php echo $this->description; ?></p>
|
150 |
+
|
151 |
+
<?php endif;
|
152 |
+
}
|
153 |
+
|
154 |
+
/**
|
155 |
+
* Generate an option input field name, using the grouped schema.
|
156 |
+
*/
|
157 |
+
public function get_input_name() {
|
158 |
+
return esc_attr( $this->page ) . '[' . esc_attr( $this->id ) . ']';
|
159 |
+
}
|
160 |
+
|
161 |
+
|
162 |
+
/**
|
163 |
+
* Sanitize the array of text inputs for this setting
|
164 |
+
*/
|
165 |
+
public function sanitize_callback_wrapper( $values ) {
|
166 |
+
// global $ulb_controller;
|
167 |
+
|
168 |
+
$output = array(
|
169 |
+
'api_key' => '',
|
170 |
+
'status' => false,
|
171 |
+
);
|
172 |
+
|
173 |
+
// Return an empty key and status if the values don't look right
|
174 |
+
if ( !is_array( $values ) || empty( $values ) || empty( $values['api_key'] ) ) {
|
175 |
+
return $output;
|
176 |
+
}
|
177 |
+
|
178 |
+
// Sanitize the API key
|
179 |
+
$output['api_key'] = sanitize_text_field( $values['api_key'] );
|
180 |
+
|
181 |
+
// $ulb_controller->mailchimp->load_api( $output['api_key'] );
|
182 |
+
|
183 |
+
// Check for a valid API key
|
184 |
+
// $output['status'] = $ulb_controller->mailchimp->is_valid_api_key();
|
185 |
+
|
186 |
+
$output['status'] = strpos( $output['api_key'], '-' ) === false ? false : true;
|
187 |
+
|
188 |
+
return $output;
|
189 |
+
}
|
190 |
+
|
191 |
+
/**
|
192 |
+
* Add and register this setting
|
193 |
+
*
|
194 |
+
* @since 1.0
|
195 |
+
*/
|
196 |
+
public function add_settings_field( $section_id ) {
|
197 |
+
|
198 |
+
add_settings_field(
|
199 |
+
$this->id,
|
200 |
+
$this->title,
|
201 |
+
array( $this, 'display_setting' ),
|
202 |
+
$this->tab,
|
203 |
+
$section_id
|
204 |
+
);
|
205 |
+
|
206 |
+
}
|
207 |
+
|
208 |
+
/**
|
209 |
+
* Set an error
|
210 |
+
* @since 1.0
|
211 |
+
*/
|
212 |
+
public function set_error( $error ) {
|
213 |
+
$this->errors[] = array_merge(
|
214 |
+
$error,
|
215 |
+
array(
|
216 |
+
'class' => get_class( $this ),
|
217 |
+
'id' => $this->id,
|
218 |
+
'backtrace' => debug_backtrace()
|
219 |
+
)
|
220 |
+
);
|
221 |
+
}
|
222 |
+
|
223 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSetting.McListMerge.class.php
CHANGED
@@ -1,255 +1,255 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Add a setting to Simple Admin Pages to select a list and define
|
5 |
-
* merge fields for that list.
|
6 |
-
*
|
7 |
-
* This class is modelled on AdminPageSetting.class.php in the Simple
|
8 |
-
* Admin Pages library. It should work just like an extended class, but
|
9 |
-
* due to the way the library embeds the version into the class name,
|
10 |
-
* that could cause problems if the library is updated in the parent
|
11 |
-
* plugin.
|
12 |
-
*
|
13 |
-
* See: https://github.com/NateWr/simple-admin-pages
|
14 |
-
*
|
15 |
-
*/
|
16 |
-
|
17 |
-
class
|
18 |
-
|
19 |
-
/**
|
20 |
-
* Scripts and styles to load for this component
|
21 |
-
* (not used but required as part of the library)
|
22 |
-
*/
|
23 |
-
public $scripts = array();
|
24 |
-
public $styles = array();
|
25 |
-
|
26 |
-
/**
|
27 |
-
* List of fields available for merging
|
28 |
-
*/
|
29 |
-
public $fields = array();
|
30 |
-
|
31 |
-
/**
|
32 |
-
* Initialize the setting
|
33 |
-
*/
|
34 |
-
public function __construct( $args ) {
|
35 |
-
|
36 |
-
// Parse the values passed
|
37 |
-
$this->parse_args( $args );
|
38 |
-
|
39 |
-
// Get any existing value
|
40 |
-
$this->set_value();
|
41 |
-
|
42 |
-
// Set an error if the object is missing necessary data
|
43 |
-
if ( $this->missing_data() ) {
|
44 |
-
$this->set_error();
|
45 |
-
}
|
46 |
-
}
|
47 |
-
|
48 |
-
/**
|
49 |
-
* Parse the arguments passed in the construction and assign them to
|
50 |
-
* internal variables. This function will be overwritten for most subclasses
|
51 |
-
*/
|
52 |
-
private function parse_args( $args ) {
|
53 |
-
foreach ( $args as $key => $val ) {
|
54 |
-
switch ( $key ) {
|
55 |
-
|
56 |
-
case 'id' :
|
57 |
-
$this->{$key} = esc_attr( $val );
|
58 |
-
|
59 |
-
case 'title' :
|
60 |
-
$this->{$key} = esc_attr( $val );
|
61 |
-
|
62 |
-
case 'fields' :
|
63 |
-
$this->{$key} = is_array( $val ) ? $val : array();
|
64 |
-
|
65 |
-
default :
|
66 |
-
$this->{$key} = $val;
|
67 |
-
|
68 |
-
}
|
69 |
-
}
|
70 |
-
}
|
71 |
-
|
72 |
-
/**
|
73 |
-
* Check for missing data when setup.
|
74 |
-
*/
|
75 |
-
private function missing_data() {
|
76 |
-
|
77 |
-
// Required fields
|
78 |
-
if ( empty( $this->id ) ) {
|
79 |
-
$this->set_error(
|
80 |
-
array(
|
81 |
-
'type' => 'missing_data',
|
82 |
-
'data' => 'id'
|
83 |
-
)
|
84 |
-
);
|
85 |
-
}
|
86 |
-
if ( empty( $this->title ) ) {
|
87 |
-
$this->set_error(
|
88 |
-
array(
|
89 |
-
'type' => 'missing_data',
|
90 |
-
'data' => 'title'
|
91 |
-
)
|
92 |
-
);
|
93 |
-
}
|
94 |
-
if ( empty( $this->fields ) ) {
|
95 |
-
$this->set_error(
|
96 |
-
array(
|
97 |
-
'type' => 'missing_data',
|
98 |
-
'data' => 'fields'
|
99 |
-
)
|
100 |
-
);
|
101 |
-
}
|
102 |
-
if ( empty( $this->string_loading ) ) {
|
103 |
-
$this->set_error(
|
104 |
-
array(
|
105 |
-
'type' => 'missing_data',
|
106 |
-
'data' => 'string_loading'
|
107 |
-
)
|
108 |
-
);
|
109 |
-
}
|
110 |
-
}
|
111 |
-
|
112 |
-
/**
|
113 |
-
* Set a value
|
114 |
-
*/
|
115 |
-
public function set_value( $val = null ) {
|
116 |
-
|
117 |
-
if ( $val === null ) {
|
118 |
-
$option_group_value = get_option( $this->page );
|
119 |
-
$val = isset( $option_group_value[ $this->id ] ) ? $option_group_value[ $this->id ] : '';
|
120 |
-
}
|
121 |
-
|
122 |
-
$this->value = $this->esc_value( $val );
|
123 |
-
}
|
124 |
-
|
125 |
-
/**
|
126 |
-
* Escape the value to display it in text fields and other input fields
|
127 |
-
*/
|
128 |
-
public function esc_value( $val ) {
|
129 |
-
|
130 |
-
$value = array(
|
131 |
-
'list' => '',
|
132 |
-
'fields' => array(),
|
133 |
-
);
|
134 |
-
|
135 |
-
if ( empty( $val ) || empty( $val['list'] ) ) {
|
136 |
-
return $value;
|
137 |
-
}
|
138 |
-
|
139 |
-
$value['list'] = esc_attr( $val['list'] );
|
140 |
-
|
141 |
-
// Escape the id/title of each merge field
|
142 |
-
foreach( $val['fields'] as $id => $val ) {
|
143 |
-
$value['fields'][$id] = esc_html( $val );
|
144 |
-
}
|
145 |
-
|
146 |
-
return $value;
|
147 |
-
}
|
148 |
-
|
149 |
-
/**
|
150 |
-
* Display this setting
|
151 |
-
*/
|
152 |
-
public function display_setting() {
|
153 |
-
|
154 |
-
?>
|
155 |
-
|
156 |
-
<span class="
|
157 |
-
|
158 |
-
<span class="
|
159 |
-
<span class="spinner"></span>
|
160 |
-
<span><?php echo $this->string_loading; ?></span>
|
161 |
-
</span>
|
162 |
-
|
163 |
-
<?php $this->display_description(); ?>
|
164 |
-
|
165 |
-
<div id="mcfrtb-merge-controls" data-input-name="<?php echo $this->get_input_name(); ?>"></div>
|
166 |
-
|
167 |
-
<?php
|
168 |
-
}
|
169 |
-
|
170 |
-
/**
|
171 |
-
* Display a description for this setting
|
172 |
-
*/
|
173 |
-
public function display_description() {
|
174 |
-
|
175 |
-
if ( !empty( $this->description ) ) : ?>
|
176 |
-
|
177 |
-
<p class="description"><?php echo $this->description; ?></p>
|
178 |
-
|
179 |
-
<?php endif;
|
180 |
-
}
|
181 |
-
|
182 |
-
/**
|
183 |
-
* Generate an option input field name, using the grouped schema.
|
184 |
-
*/
|
185 |
-
public function get_input_name() {
|
186 |
-
return esc_attr( $this->page ) . '[' . esc_attr( $this->id ) . ']';
|
187 |
-
}
|
188 |
-
|
189 |
-
|
190 |
-
/**
|
191 |
-
* Sanitize the array of text inputs for this setting
|
192 |
-
*/
|
193 |
-
public function sanitize_callback_wrapper( $values ) {
|
194 |
-
|
195 |
-
$output = array(
|
196 |
-
'list' => '',
|
197 |
-
'fields' => array(),
|
198 |
-
);
|
199 |
-
|
200 |
-
// Return an empty value if we're missing anything important
|
201 |
-
if ( !is_array( $values ) || empty( $values ) || empty( $values['list'] ) ) {
|
202 |
-
return $output;
|
203 |
-
}
|
204 |
-
|
205 |
-
// Sanitize the list
|
206 |
-
$output['list'] = sanitize_text_field( $values['list'] );
|
207 |
-
|
208 |
-
// Sanitize each merge field
|
209 |
-
$val_log = array();
|
210 |
-
foreach( $values['fields'] as $id => $val ) {
|
211 |
-
|
212 |
-
// Make sure that a merge field isn't assigned to multiple data
|
213 |
-
if ( !in_array( $val, $val_log ) ) {
|
214 |
-
$output['fields'][$id] = sanitize_text_field( $val );
|
215 |
-
}
|
216 |
-
|
217 |
-
$val_log[] = $val;
|
218 |
-
}
|
219 |
-
|
220 |
-
return $output;
|
221 |
-
}
|
222 |
-
|
223 |
-
/**
|
224 |
-
* Add and register this setting
|
225 |
-
*
|
226 |
-
* @since 1.0
|
227 |
-
*/
|
228 |
-
public function add_settings_field( $section_id ) {
|
229 |
-
|
230 |
-
add_settings_field(
|
231 |
-
$this->id,
|
232 |
-
$this->title,
|
233 |
-
array( $this, 'display_setting' ),
|
234 |
-
$this->tab,
|
235 |
-
$section_id
|
236 |
-
);
|
237 |
-
|
238 |
-
}
|
239 |
-
|
240 |
-
/**
|
241 |
-
* Set an error
|
242 |
-
* @since 1.0
|
243 |
-
*/
|
244 |
-
public function set_error( $error ) {
|
245 |
-
$this->errors[] = array_merge(
|
246 |
-
$error,
|
247 |
-
array(
|
248 |
-
'class' => get_class( $this ),
|
249 |
-
'id' => $this->id,
|
250 |
-
'backtrace' => debug_backtrace()
|
251 |
-
)
|
252 |
-
);
|
253 |
-
}
|
254 |
-
|
255 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Add a setting to Simple Admin Pages to select a list and define
|
5 |
+
* merge fields for that list.
|
6 |
+
*
|
7 |
+
* This class is modelled on AdminPageSetting.class.php in the Simple
|
8 |
+
* Admin Pages library. It should work just like an extended class, but
|
9 |
+
* due to the way the library embeds the version into the class name,
|
10 |
+
* that could cause problems if the library is updated in the parent
|
11 |
+
* plugin.
|
12 |
+
*
|
13 |
+
* See: https://github.com/NateWr/simple-admin-pages
|
14 |
+
*
|
15 |
+
*/
|
16 |
+
|
17 |
+
class mcfrtbAdminPageSettingMcListMerge_2_5_5 {
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Scripts and styles to load for this component
|
21 |
+
* (not used but required as part of the library)
|
22 |
+
*/
|
23 |
+
public $scripts = array();
|
24 |
+
public $styles = array();
|
25 |
+
|
26 |
+
/**
|
27 |
+
* List of fields available for merging
|
28 |
+
*/
|
29 |
+
public $fields = array();
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Initialize the setting
|
33 |
+
*/
|
34 |
+
public function __construct( $args ) {
|
35 |
+
|
36 |
+
// Parse the values passed
|
37 |
+
$this->parse_args( $args );
|
38 |
+
|
39 |
+
// Get any existing value
|
40 |
+
$this->set_value();
|
41 |
+
|
42 |
+
// Set an error if the object is missing necessary data
|
43 |
+
if ( $this->missing_data() ) {
|
44 |
+
$this->set_error();
|
45 |
+
}
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Parse the arguments passed in the construction and assign them to
|
50 |
+
* internal variables. This function will be overwritten for most subclasses
|
51 |
+
*/
|
52 |
+
private function parse_args( $args ) {
|
53 |
+
foreach ( $args as $key => $val ) {
|
54 |
+
switch ( $key ) {
|
55 |
+
|
56 |
+
case 'id' :
|
57 |
+
$this->{$key} = esc_attr( $val );
|
58 |
+
|
59 |
+
case 'title' :
|
60 |
+
$this->{$key} = esc_attr( $val );
|
61 |
+
|
62 |
+
case 'fields' :
|
63 |
+
$this->{$key} = is_array( $val ) ? $val : array();
|
64 |
+
|
65 |
+
default :
|
66 |
+
$this->{$key} = $val;
|
67 |
+
|
68 |
+
}
|
69 |
+
}
|
70 |
+
}
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Check for missing data when setup.
|
74 |
+
*/
|
75 |
+
private function missing_data() {
|
76 |
+
|
77 |
+
// Required fields
|
78 |
+
if ( empty( $this->id ) ) {
|
79 |
+
$this->set_error(
|
80 |
+
array(
|
81 |
+
'type' => 'missing_data',
|
82 |
+
'data' => 'id'
|
83 |
+
)
|
84 |
+
);
|
85 |
+
}
|
86 |
+
if ( empty( $this->title ) ) {
|
87 |
+
$this->set_error(
|
88 |
+
array(
|
89 |
+
'type' => 'missing_data',
|
90 |
+
'data' => 'title'
|
91 |
+
)
|
92 |
+
);
|
93 |
+
}
|
94 |
+
if ( empty( $this->fields ) ) {
|
95 |
+
$this->set_error(
|
96 |
+
array(
|
97 |
+
'type' => 'missing_data',
|
98 |
+
'data' => 'fields'
|
99 |
+
)
|
100 |
+
);
|
101 |
+
}
|
102 |
+
if ( empty( $this->string_loading ) ) {
|
103 |
+
$this->set_error(
|
104 |
+
array(
|
105 |
+
'type' => 'missing_data',
|
106 |
+
'data' => 'string_loading'
|
107 |
+
)
|
108 |
+
);
|
109 |
+
}
|
110 |
+
}
|
111 |
+
|
112 |
+
/**
|
113 |
+
* Set a value
|
114 |
+
*/
|
115 |
+
public function set_value( $val = null ) {
|
116 |
+
|
117 |
+
if ( $val === null ) {
|
118 |
+
$option_group_value = get_option( $this->page );
|
119 |
+
$val = isset( $option_group_value[ $this->id ] ) ? $option_group_value[ $this->id ] : '';
|
120 |
+
}
|
121 |
+
|
122 |
+
$this->value = $this->esc_value( $val );
|
123 |
+
}
|
124 |
+
|
125 |
+
/**
|
126 |
+
* Escape the value to display it in text fields and other input fields
|
127 |
+
*/
|
128 |
+
public function esc_value( $val ) {
|
129 |
+
|
130 |
+
$value = array(
|
131 |
+
'list' => '',
|
132 |
+
'fields' => array(),
|
133 |
+
);
|
134 |
+
|
135 |
+
if ( empty( $val ) || empty( $val['list'] ) ) {
|
136 |
+
return $value;
|
137 |
+
}
|
138 |
+
|
139 |
+
$value['list'] = esc_attr( $val['list'] );
|
140 |
+
|
141 |
+
// Escape the id/title of each merge field
|
142 |
+
foreach( $val['fields'] as $id => $val ) {
|
143 |
+
$value['fields'][$id] = esc_html( $val );
|
144 |
+
}
|
145 |
+
|
146 |
+
return $value;
|
147 |
+
}
|
148 |
+
|
149 |
+
/**
|
150 |
+
* Display this setting
|
151 |
+
*/
|
152 |
+
public function display_setting() {
|
153 |
+
|
154 |
+
?>
|
155 |
+
|
156 |
+
<span class="mcf-list-select"></span>
|
157 |
+
|
158 |
+
<span class="mcf-sap_loading">
|
159 |
+
<span class="spinner"></span>
|
160 |
+
<span><?php echo $this->string_loading; ?></span>
|
161 |
+
</span>
|
162 |
+
|
163 |
+
<?php $this->display_description(); ?>
|
164 |
+
|
165 |
+
<div id="mcfrtb-merge-controls" data-input-name="<?php echo $this->get_input_name(); ?>"></div>
|
166 |
+
|
167 |
+
<?php
|
168 |
+
}
|
169 |
+
|
170 |
+
/**
|
171 |
+
* Display a description for this setting
|
172 |
+
*/
|
173 |
+
public function display_description() {
|
174 |
+
|
175 |
+
if ( !empty( $this->description ) ) : ?>
|
176 |
+
|
177 |
+
<p class="description"><?php echo $this->description; ?></p>
|
178 |
+
|
179 |
+
<?php endif;
|
180 |
+
}
|
181 |
+
|
182 |
+
/**
|
183 |
+
* Generate an option input field name, using the grouped schema.
|
184 |
+
*/
|
185 |
+
public function get_input_name() {
|
186 |
+
return esc_attr( $this->page ) . '[' . esc_attr( $this->id ) . ']';
|
187 |
+
}
|
188 |
+
|
189 |
+
|
190 |
+
/**
|
191 |
+
* Sanitize the array of text inputs for this setting
|
192 |
+
*/
|
193 |
+
public function sanitize_callback_wrapper( $values ) {
|
194 |
+
|
195 |
+
$output = array(
|
196 |
+
'list' => '',
|
197 |
+
'fields' => array(),
|
198 |
+
);
|
199 |
+
|
200 |
+
// Return an empty value if we're missing anything important
|
201 |
+
if ( !is_array( $values ) || empty( $values ) || empty( $values['list'] ) ) {
|
202 |
+
return $output;
|
203 |
+
}
|
204 |
+
|
205 |
+
// Sanitize the list
|
206 |
+
$output['list'] = sanitize_text_field( $values['list'] );
|
207 |
+
|
208 |
+
// Sanitize each merge field
|
209 |
+
$val_log = array();
|
210 |
+
foreach( $values['fields'] as $id => $val ) {
|
211 |
+
|
212 |
+
// Make sure that a merge field isn't assigned to multiple data
|
213 |
+
if ( !in_array( $val, $val_log ) ) {
|
214 |
+
$output['fields'][$id] = sanitize_text_field( $val );
|
215 |
+
}
|
216 |
+
|
217 |
+
$val_log[] = $val;
|
218 |
+
}
|
219 |
+
|
220 |
+
return $output;
|
221 |
+
}
|
222 |
+
|
223 |
+
/**
|
224 |
+
* Add and register this setting
|
225 |
+
*
|
226 |
+
* @since 1.0
|
227 |
+
*/
|
228 |
+
public function add_settings_field( $section_id ) {
|
229 |
+
|
230 |
+
add_settings_field(
|
231 |
+
$this->id,
|
232 |
+
$this->title,
|
233 |
+
array( $this, 'display_setting' ),
|
234 |
+
$this->tab,
|
235 |
+
$section_id
|
236 |
+
);
|
237 |
+
|
238 |
+
}
|
239 |
+
|
240 |
+
/**
|
241 |
+
* Set an error
|
242 |
+
* @since 1.0
|
243 |
+
*/
|
244 |
+
public function set_error( $error ) {
|
245 |
+
$this->errors[] = array_merge(
|
246 |
+
$error,
|
247 |
+
array(
|
248 |
+
'class' => get_class( $this ),
|
249 |
+
'id' => $this->id,
|
250 |
+
'backtrace' => debug_backtrace()
|
251 |
+
)
|
252 |
+
);
|
253 |
+
}
|
254 |
+
|
255 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSetting.Number.class.php
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save a text field setting in the admin menu
|
5 |
+
*
|
6 |
+
* @since 1.0
|
7 |
+
* @package Simple Admin Pages
|
8 |
+
*/
|
9 |
+
|
10 |
+
class sapAdminPageSettingNumber_2_5_5 extends sapAdminPageSetting_2_5_5 {
|
11 |
+
|
12 |
+
public $sanitize_callback = 'sanitize_text_field';
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Placeholder string for the input field
|
16 |
+
* @since 2.0
|
17 |
+
*/
|
18 |
+
public $placeholder = '';
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Display this setting
|
22 |
+
* @since 1.0
|
23 |
+
*/
|
24 |
+
public function display_setting() {
|
25 |
+
?>
|
26 |
+
|
27 |
+
<input name="<?php echo $this->get_input_name(); ?>" type="number" id="<?php echo $this->get_input_name(); ?>" value="<?php echo $this->value; ?>"<?php echo !empty( $this->placeholder ) ? ' placeholder="' . esc_attr( $this->placeholder ) . '"' : ''; ?> class="regular-text" <?php echo ( $this->disabled ? 'disabled' : ''); ?> />
|
28 |
+
|
29 |
+
<?php $this->display_disabled(); ?>
|
30 |
+
|
31 |
+
<?php
|
32 |
+
|
33 |
+
$this->display_description();
|
34 |
+
|
35 |
+
}
|
36 |
+
|
37 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSetting.OpeningHours.class.php
CHANGED
@@ -1,182 +1,182 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Register, display and save a series of fields to specify the opening hours
|
5 |
-
* of a business/company.
|
6 |
-
*
|
7 |
-
* This setting accepts the following arguments in its constructor function.
|
8 |
-
*
|
9 |
-
* $args = array(
|
10 |
-
* 'id' => 'setting_id', // Unique id
|
11 |
-
* 'title' => 'My Setting', // Title or label for the setting
|
12 |
-
* 'description' => 'Description', // Help text description
|
13 |
-
* 'weekday_names' => array( // Optional array of custom
|
14 |
-
* 'monday' => 'Monday', // weekday names. These can be
|
15 |
-
* 'tuesday' => 'Tuesday', // passed in any order to
|
16 |
-
* 'wednesday' => 'Wednesday', // set a new start of the week.
|
17 |
-
* 'thursday' => 'Thursday',
|
18 |
-
* 'friday' => 'Friday',
|
19 |
-
* 'saturday' => 'Saturday',
|
20 |
-
* 'sunday' => 'Sunday'
|
21 |
-
* );
|
22 |
-
* );
|
23 |
-
*
|
24 |
-
* @since 1.0
|
25 |
-
* @package Simple Admin Pages
|
26 |
-
*/
|
27 |
-
|
28 |
-
class
|
29 |
-
|
30 |
-
public $sanitize_callback = 'sanitize_text_field';
|
31 |
-
|
32 |
-
/**
|
33 |
-
* Scripts that must be loaded for this component
|
34 |
-
* @since 2.0.a.4
|
35 |
-
*/
|
36 |
-
public $scripts = array(
|
37 |
-
'sap-opening-hours' => array(
|
38 |
-
'path' => 'js/opening-hours.js',
|
39 |
-
'dependencies' => array( 'jquery' ),
|
40 |
-
'version' =>
|
41 |
-
'footer' => true,
|
42 |
-
),
|
43 |
-
);
|
44 |
-
|
45 |
-
// Array of days of the week
|
46 |
-
public $weekdays = array(
|
47 |
-
'monday' => 'Monday',
|
48 |
-
'tuesday' => 'Tuesday',
|
49 |
-
'wednesday' => 'Wednesday',
|
50 |
-
'thursday' => 'Thursday',
|
51 |
-
'friday' => 'Friday',
|
52 |
-
'saturday' => 'Saturday',
|
53 |
-
'sunday' => 'Sunday'
|
54 |
-
);
|
55 |
-
|
56 |
-
/**
|
57 |
-
* Parse the arguments passed in the construction and assign them to
|
58 |
-
* internal variables.
|
59 |
-
* @since 1.0
|
60 |
-
*/
|
61 |
-
private function parse_args( $args ) {
|
62 |
-
foreach ( $args as $key => $val ) {
|
63 |
-
switch ( $key ) {
|
64 |
-
|
65 |
-
case 'id' :
|
66 |
-
$this->{$key} = esc_attr( $val );
|
67 |
-
|
68 |
-
case 'weekdays' :
|
69 |
-
|
70 |
-
$this->weekdays = $val;
|
71 |
-
|
72 |
-
default :
|
73 |
-
$this->{$key} = $val;
|
74 |
-
|
75 |
-
}
|
76 |
-
}
|
77 |
-
}
|
78 |
-
|
79 |
-
/**
|
80 |
-
* Escape the value to display it in text fields and other input fields
|
81 |
-
*
|
82 |
-
* @since 1.0
|
83 |
-
*/
|
84 |
-
public function esc_value( $val ) {
|
85 |
-
|
86 |
-
$value = array();
|
87 |
-
|
88 |
-
// Loop over the values and sanitize them
|
89 |
-
for ( $i = 0; $i < 7; $i++ ) {
|
90 |
-
$value[$i]['day'] = isset( $val[$i] ) && isset( $val[$i]['day'] ) ? esc_attr( $val[$i]['day'] ) : '';
|
91 |
-
$value[$i]['hours'] = isset( $val[$i] ) && isset( $val[$i]['hours'] ) ? esc_attr( $val[$i]['hours'] ) : '';
|
92 |
-
}
|
93 |
-
|
94 |
-
return $value;
|
95 |
-
}
|
96 |
-
|
97 |
-
/**
|
98 |
-
* Get a day's display name
|
99 |
-
* @since 1.0
|
100 |
-
*/
|
101 |
-
private function get_day_name( $day ) {
|
102 |
-
foreach ( $this->weekdays as $id => $name ) {
|
103 |
-
if ( $day == $id ) {
|
104 |
-
return $name;
|
105 |
-
}
|
106 |
-
}
|
107 |
-
|
108 |
-
return '';
|
109 |
-
}
|
110 |
-
|
111 |
-
/**
|
112 |
-
* Display this setting
|
113 |
-
* @since 1.0
|
114 |
-
* @todo integrate time picker
|
115 |
-
*/
|
116 |
-
public function display_setting() {
|
117 |
-
|
118 |
-
$this->display_description();
|
119 |
-
|
120 |
-
for ($i = 0; $i < 7; $i++) {
|
121 |
-
|
122 |
-
?>
|
123 |
-
|
124 |
-
<table class="sap-opening-hours <?php echo ( $this->disabled ? 'disabled' : ''); ?>">
|
125 |
-
<tr>
|
126 |
-
<td>
|
127 |
-
<input type="hidden" id="sap-opening-hours-day-<?php echo $i; ?>-name" name="<?php echo $this->get_input_name(); ?>[<?php echo $i; ?>][day_name]" value="<?php echo esc_attr( $this->get_day_name( $this->value[$i]['day'] ) ); ?>">
|
128 |
-
<select name="<?php echo $this->get_input_name(); ?>[<?php echo $i; ?>][day]" id="<?php echo $this->id . '-' . $i; ?>-day" class="sap-opening-hours-day" data-target="#sap-opening-hours-day-<?php echo $i; ?>-name">
|
129 |
-
<option value=""></option>
|
130 |
-
|
131 |
-
<?php foreach ( $this->weekdays as $id => $name ) : ?>
|
132 |
-
|
133 |
-
<option value="<?php echo $id; ?>" data-name="<?php echo esc_attr( $name ); ?>"<?php if ( $this->value[$i]['day'] == $id ) : ?> selected<?php endif; ?>>
|
134 |
-
<?php echo $name; ?>
|
135 |
-
</option>
|
136 |
-
|
137 |
-
<?php endforeach; ?>
|
138 |
-
|
139 |
-
</select>
|
140 |
-
</td>
|
141 |
-
<td>
|
142 |
-
<input name="<?php echo $this->get_input_name(); ?>[<?php echo $i; ?>][hours]" type="text" id="<?php echo $this->id . '-' . $i; ?>-hours" value="<?php echo $this->value[$i]['hours']; ?>" class="regular-text sap-opening-hours-hours" />
|
143 |
-
</td>
|
144 |
-
</tr>
|
145 |
-
</table>
|
146 |
-
|
147 |
-
<?php $this->display_disabled(); ?>
|
148 |
-
|
149 |
-
<?php
|
150 |
-
|
151 |
-
}
|
152 |
-
|
153 |
-
}
|
154 |
-
|
155 |
-
/**
|
156 |
-
* Sanitize the array of text inputs for this setting
|
157 |
-
* @since 1.0
|
158 |
-
*/
|
159 |
-
public function sanitize_callback_wrapper( $values ) {
|
160 |
-
|
161 |
-
// If no sanitization callback exists, don't register the setting.
|
162 |
-
if ( !isset( $this->sanitize_callback ) || !trim( $this->sanitize_callback ) ) {
|
163 |
-
return;
|
164 |
-
}
|
165 |
-
|
166 |
-
// If this isn't an array, just sanitize it as a string
|
167 |
-
if (!is_array( $values ) ) {
|
168 |
-
return call_user_func( $this->sanitize_callback, $values );
|
169 |
-
}
|
170 |
-
|
171 |
-
// Loop over the values and sanitize them
|
172 |
-
for ( $i = 0; $i < 7; $i++ ) {
|
173 |
-
if ( isset( $values[ $i ] ) && is_array( $values[ $i ] ) ) {
|
174 |
-
$values[$i]['day'] = call_user_func( $this->sanitize_callback, $values[$i]['day'] );
|
175 |
-
$values[$i]['hours'] = call_user_func( $this->sanitize_callback, $values[$i]['hours'] );
|
176 |
-
}
|
177 |
-
}
|
178 |
-
|
179 |
-
return $values;
|
180 |
-
}
|
181 |
-
|
182 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save a series of fields to specify the opening hours
|
5 |
+
* of a business/company.
|
6 |
+
*
|
7 |
+
* This setting accepts the following arguments in its constructor function.
|
8 |
+
*
|
9 |
+
* $args = array(
|
10 |
+
* 'id' => 'setting_id', // Unique id
|
11 |
+
* 'title' => 'My Setting', // Title or label for the setting
|
12 |
+
* 'description' => 'Description', // Help text description
|
13 |
+
* 'weekday_names' => array( // Optional array of custom
|
14 |
+
* 'monday' => 'Monday', // weekday names. These can be
|
15 |
+
* 'tuesday' => 'Tuesday', // passed in any order to
|
16 |
+
* 'wednesday' => 'Wednesday', // set a new start of the week.
|
17 |
+
* 'thursday' => 'Thursday',
|
18 |
+
* 'friday' => 'Friday',
|
19 |
+
* 'saturday' => 'Saturday',
|
20 |
+
* 'sunday' => 'Sunday'
|
21 |
+
* );
|
22 |
+
* );
|
23 |
+
*
|
24 |
+
* @since 1.0
|
25 |
+
* @package Simple Admin Pages
|
26 |
+
*/
|
27 |
+
|
28 |
+
class sapAdminPageSettingOpeningHours_2_5_5 extends sapAdminPageSetting_2_5_5 {
|
29 |
+
|
30 |
+
public $sanitize_callback = 'sanitize_text_field';
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Scripts that must be loaded for this component
|
34 |
+
* @since 2.0.a.4
|
35 |
+
*/
|
36 |
+
public $scripts = array(
|
37 |
+
'sap-opening-hours' => array(
|
38 |
+
'path' => 'js/opening-hours.js',
|
39 |
+
'dependencies' => array( 'jquery' ),
|
40 |
+
'version' => SAP_VERSION,
|
41 |
+
'footer' => true,
|
42 |
+
),
|
43 |
+
);
|
44 |
+
|
45 |
+
// Array of days of the week
|
46 |
+
public $weekdays = array(
|
47 |
+
'monday' => 'Monday',
|
48 |
+
'tuesday' => 'Tuesday',
|
49 |
+
'wednesday' => 'Wednesday',
|
50 |
+
'thursday' => 'Thursday',
|
51 |
+
'friday' => 'Friday',
|
52 |
+
'saturday' => 'Saturday',
|
53 |
+
'sunday' => 'Sunday'
|
54 |
+
);
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Parse the arguments passed in the construction and assign them to
|
58 |
+
* internal variables.
|
59 |
+
* @since 1.0
|
60 |
+
*/
|
61 |
+
private function parse_args( $args ) {
|
62 |
+
foreach ( $args as $key => $val ) {
|
63 |
+
switch ( $key ) {
|
64 |
+
|
65 |
+
case 'id' :
|
66 |
+
$this->{$key} = esc_attr( $val );
|
67 |
+
|
68 |
+
case 'weekdays' :
|
69 |
+
|
70 |
+
$this->weekdays = $val;
|
71 |
+
|
72 |
+
default :
|
73 |
+
$this->{$key} = $val;
|
74 |
+
|
75 |
+
}
|
76 |
+
}
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Escape the value to display it in text fields and other input fields
|
81 |
+
*
|
82 |
+
* @since 1.0
|
83 |
+
*/
|
84 |
+
public function esc_value( $val ) {
|
85 |
+
|
86 |
+
$value = array();
|
87 |
+
|
88 |
+
// Loop over the values and sanitize them
|
89 |
+
for ( $i = 0; $i < 7; $i++ ) {
|
90 |
+
$value[$i]['day'] = isset( $val[$i] ) && isset( $val[$i]['day'] ) ? esc_attr( $val[$i]['day'] ) : '';
|
91 |
+
$value[$i]['hours'] = isset( $val[$i] ) && isset( $val[$i]['hours'] ) ? esc_attr( $val[$i]['hours'] ) : '';
|
92 |
+
}
|
93 |
+
|
94 |
+
return $value;
|
95 |
+
}
|
96 |
+
|
97 |
+
/**
|
98 |
+
* Get a day's display name
|
99 |
+
* @since 1.0
|
100 |
+
*/
|
101 |
+
private function get_day_name( $day ) {
|
102 |
+
foreach ( $this->weekdays as $id => $name ) {
|
103 |
+
if ( $day == $id ) {
|
104 |
+
return $name;
|
105 |
+
}
|
106 |
+
}
|
107 |
+
|
108 |
+
return '';
|
109 |
+
}
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Display this setting
|
113 |
+
* @since 1.0
|
114 |
+
* @todo integrate time picker
|
115 |
+
*/
|
116 |
+
public function display_setting() {
|
117 |
+
|
118 |
+
$this->display_description();
|
119 |
+
|
120 |
+
for ($i = 0; $i < 7; $i++) {
|
121 |
+
|
122 |
+
?>
|
123 |
+
|
124 |
+
<table class="sap-opening-hours <?php echo ( $this->disabled ? 'disabled' : ''); ?>">
|
125 |
+
<tr>
|
126 |
+
<td>
|
127 |
+
<input type="hidden" id="sap-opening-hours-day-<?php echo $i; ?>-name" name="<?php echo $this->get_input_name(); ?>[<?php echo $i; ?>][day_name]" value="<?php echo esc_attr( $this->get_day_name( $this->value[$i]['day'] ) ); ?>">
|
128 |
+
<select name="<?php echo $this->get_input_name(); ?>[<?php echo $i; ?>][day]" id="<?php echo $this->id . '-' . $i; ?>-day" class="sap-opening-hours-day" data-target="#sap-opening-hours-day-<?php echo $i; ?>-name">
|
129 |
+
<option value=""></option>
|
130 |
+
|
131 |
+
<?php foreach ( $this->weekdays as $id => $name ) : ?>
|
132 |
+
|
133 |
+
<option value="<?php echo $id; ?>" data-name="<?php echo esc_attr( $name ); ?>"<?php if ( $this->value[$i]['day'] == $id ) : ?> selected<?php endif; ?>>
|
134 |
+
<?php echo $name; ?>
|
135 |
+
</option>
|
136 |
+
|
137 |
+
<?php endforeach; ?>
|
138 |
+
|
139 |
+
</select>
|
140 |
+
</td>
|
141 |
+
<td>
|
142 |
+
<input name="<?php echo $this->get_input_name(); ?>[<?php echo $i; ?>][hours]" type="text" id="<?php echo $this->id . '-' . $i; ?>-hours" value="<?php echo $this->value[$i]['hours']; ?>" class="regular-text sap-opening-hours-hours" />
|
143 |
+
</td>
|
144 |
+
</tr>
|
145 |
+
</table>
|
146 |
+
|
147 |
+
<?php $this->display_disabled(); ?>
|
148 |
+
|
149 |
+
<?php
|
150 |
+
|
151 |
+
}
|
152 |
+
|
153 |
+
}
|
154 |
+
|
155 |
+
/**
|
156 |
+
* Sanitize the array of text inputs for this setting
|
157 |
+
* @since 1.0
|
158 |
+
*/
|
159 |
+
public function sanitize_callback_wrapper( $values ) {
|
160 |
+
|
161 |
+
// If no sanitization callback exists, don't register the setting.
|
162 |
+
if ( !isset( $this->sanitize_callback ) || !trim( $this->sanitize_callback ) ) {
|
163 |
+
return;
|
164 |
+
}
|
165 |
+
|
166 |
+
// If this isn't an array, just sanitize it as a string
|
167 |
+
if (!is_array( $values ) ) {
|
168 |
+
return call_user_func( $this->sanitize_callback, $values );
|
169 |
+
}
|
170 |
+
|
171 |
+
// Loop over the values and sanitize them
|
172 |
+
for ( $i = 0; $i < 7; $i++ ) {
|
173 |
+
if ( isset( $values[ $i ] ) && is_array( $values[ $i ] ) ) {
|
174 |
+
$values[$i]['day'] = call_user_func( $this->sanitize_callback, $values[$i]['day'] );
|
175 |
+
$values[$i]['hours'] = call_user_func( $this->sanitize_callback, $values[$i]['hours'] );
|
176 |
+
}
|
177 |
+
}
|
178 |
+
|
179 |
+
return $values;
|
180 |
+
}
|
181 |
+
|
182 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSetting.Ordering.class.php
ADDED
@@ -0,0 +1,94 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register and display a table for saving the order of a list of items.
|
5 |
+
*
|
6 |
+
* This setting accepts the following arguments in its constructor function.
|
7 |
+
*
|
8 |
+
* $args = array(
|
9 |
+
* 'id' => 'setting_id', // Unique id
|
10 |
+
* 'title' => 'My Setting', // Title or label for the setting
|
11 |
+
* 'description' => 'Description', // Help text description
|
12 |
+
* 'items' => array(
|
13 |
+
* 'item' => 'Label' // The items to be re-ordered
|
14 |
+
* )
|
15 |
+
* );
|
16 |
+
*
|
17 |
+
* @since 2.5
|
18 |
+
* @package Simple Admin Pages
|
19 |
+
*/
|
20 |
+
|
21 |
+
class sapAdminPageSettingOrdering_2_5_5 extends sapAdminPageSetting_2_5_5 {
|
22 |
+
|
23 |
+
public $sanitize_callback = 'sanitize_text_field';
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Add in the JS requried for the values to be stored
|
27 |
+
* @since 2.5
|
28 |
+
*/
|
29 |
+
public $scripts = array(
|
30 |
+
'sap-ordering-table' => array(
|
31 |
+
'path' => 'js/ordering.js',
|
32 |
+
'dependencies' => array( 'jquery' ),
|
33 |
+
'version' => SAP_VERSION,
|
34 |
+
'footer' => true,
|
35 |
+
),
|
36 |
+
);
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Add in the CSS requried for rows to be displayed correctly
|
40 |
+
* @since 2.5
|
41 |
+
*/
|
42 |
+
public $styles = array(
|
43 |
+
'sap-ordering-table' => array(
|
44 |
+
'path' => 'css/ordering.css',
|
45 |
+
'dependencies' => array( ),
|
46 |
+
'version' => SAP_VERSION,
|
47 |
+
'media' => 'all',
|
48 |
+
),
|
49 |
+
);
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Display this setting
|
53 |
+
* @since 2.0
|
54 |
+
*/
|
55 |
+
public function display_setting() {
|
56 |
+
|
57 |
+
$input_name = $this->get_input_name();
|
58 |
+
$values = is_array( $this->value ) ? $this->value : json_decode( html_entity_decode( $this->value ), true );
|
59 |
+
|
60 |
+
if ( ! is_array( $values ) )
|
61 |
+
$values = array();
|
62 |
+
|
63 |
+
if ( empty( $values ) and is_string( $this->items ) )
|
64 |
+
$values = array_merge( $values, json_decode( $this->items, true ) );
|
65 |
+
|
66 |
+
?>
|
67 |
+
|
68 |
+
<fieldset>
|
69 |
+
<div class='sap-ordering-table <?php echo ( $this->disabled ? 'disabled' : ''); ?>'>
|
70 |
+
<input type='hidden' id="sap-ordering-table-main-input" name='<?php echo $input_name; ?>' value='<?php echo esc_attr( json_encode( $values ) ); ?>' />
|
71 |
+
<table>
|
72 |
+
<tbody>
|
73 |
+
<?php foreach ( $values as $value => $label ) { ?>
|
74 |
+
<tr class='sap-ordering-table-row'>
|
75 |
+
<td>
|
76 |
+
<input type='hidden' value='<?php echo esc_attr( $value ); ?>' />
|
77 |
+
<span><?php echo esc_html( $label ); ?></span>
|
78 |
+
</td>
|
79 |
+
</tr>
|
80 |
+
<?php } ?>
|
81 |
+
</tbody>
|
82 |
+
</table>
|
83 |
+
</div>
|
84 |
+
|
85 |
+
<?php $this->display_disabled(); ?>
|
86 |
+
</fieldset>
|
87 |
+
|
88 |
+
<?php
|
89 |
+
|
90 |
+
$this->display_description();
|
91 |
+
|
92 |
+
}
|
93 |
+
|
94 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSetting.Radio.class.php
CHANGED
@@ -1,52 +1,53 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Register, display and save an option with radio buttons.
|
5 |
-
*
|
6 |
-
* This setting accepts the following arguments in its constructor function.
|
7 |
-
*
|
8 |
-
* $args = array(
|
9 |
-
* 'id' => 'setting_id', // Unique id
|
10 |
-
* 'title' => 'My Setting', // Title or label for the setting
|
11 |
-
* 'description' => 'Description', // Help text description
|
12 |
-
* 'options' => array(
|
13 |
-
* 'value' => 'Name'
|
14 |
-
* ), // The radio buttons values and text
|
15 |
-
* );
|
16 |
-
* );
|
17 |
-
*
|
18 |
-
* @since 2.0
|
19 |
-
* @package Simple Admin Pages
|
20 |
-
*/
|
21 |
-
|
22 |
-
class
|
23 |
-
|
24 |
-
public $sanitize_callback = 'sanitize_text_field';
|
25 |
-
|
26 |
-
/**
|
27 |
-
* Display this setting
|
28 |
-
* @since 2.0
|
29 |
-
*/
|
30 |
-
public function display_setting() {
|
31 |
-
|
32 |
-
$input_name = $this->get_input_name();
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save an option with radio buttons.
|
5 |
+
*
|
6 |
+
* This setting accepts the following arguments in its constructor function.
|
7 |
+
*
|
8 |
+
* $args = array(
|
9 |
+
* 'id' => 'setting_id', // Unique id
|
10 |
+
* 'title' => 'My Setting', // Title or label for the setting
|
11 |
+
* 'description' => 'Description', // Help text description
|
12 |
+
* 'options' => array(
|
13 |
+
* 'value' => 'Name'
|
14 |
+
* ), // The radio buttons values and text
|
15 |
+
* );
|
16 |
+
* );
|
17 |
+
*
|
18 |
+
* @since 2.0
|
19 |
+
* @package Simple Admin Pages
|
20 |
+
*/
|
21 |
+
|
22 |
+
class sapAdminPageSettingRadio_2_5_5 extends sapAdminPageSetting_2_5_5 {
|
23 |
+
|
24 |
+
public $sanitize_callback = 'sanitize_text_field';
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Display this setting
|
28 |
+
* @since 2.0
|
29 |
+
*/
|
30 |
+
public function display_setting() {
|
31 |
+
|
32 |
+
$input_name = $this->get_input_name();
|
33 |
+
|
34 |
+
if ( empty( $this->value ) ) { $this->value = $this->get_default_setting(); }
|
35 |
+
|
36 |
+
?>
|
37 |
+
<fieldset <?php echo ( isset( $this->columns ) ? 'class="sap-setting-columns-' . $this->columns . '"' : '' ); ?>>
|
38 |
+
<?php foreach ( $this->options as $id => $title ) : ?>
|
39 |
+
<label title="<?php echo ( strpos( $title, '<' ) === false ? $title : ''); ?>" class="sap-admin-input-container">
|
40 |
+
<input type="radio" name="<?php echo $input_name; ?>" id="<?php echo $input_name . "-" . $id; ?>" value="<?php echo $id; ?>" <?php echo ( $id == $this->value ? 'checked="checked"' : '' ) ?> <?php echo ( $this->disabled ? 'disabled' : ''); ?> />
|
41 |
+
<span class='sap-admin-radio-button'></span> <span><?php echo $title; ?></span>
|
42 |
+
</label>
|
43 |
+
<?php endforeach; ?>
|
44 |
+
|
45 |
+
<?php $this->display_disabled(); ?>
|
46 |
+
</fieldset>
|
47 |
+
<?php
|
48 |
+
|
49 |
+
$this->display_description();
|
50 |
+
|
51 |
+
}
|
52 |
+
|
53 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php
CHANGED
@@ -1,703 +1,703 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Register, display and save a schedule of dates and times.
|
5 |
-
*
|
6 |
-
* This is designed for use for opening hours, a booking schedule or anything
|
7 |
-
* that requires recurring dates and times.
|
8 |
-
*
|
9 |
-
* @since 2.0
|
10 |
-
* @package Simple Admin Pages
|
11 |
-
*/
|
12 |
-
|
13 |
-
class
|
14 |
-
|
15 |
-
public $sanitize_callback = 'sanitize_text_field';
|
16 |
-
|
17 |
-
/**
|
18 |
-
* Scripts that must be loaded for this component
|
19 |
-
* @since 2.0.a.4
|
20 |
-
*/
|
21 |
-
public $scripts = array(
|
22 |
-
'pickadate' => array(
|
23 |
-
'path' => 'lib/pickadate/picker.js',
|
24 |
-
'dependencies' => array( 'jquery' ),
|
25 |
-
'version' => '3.
|
26 |
-
'footer' => true,
|
27 |
-
),
|
28 |
-
'pickadate-date' => array(
|
29 |
-
'path' => 'lib/pickadate/picker.date.js',
|
30 |
-
'dependencies' => array( 'jquery' ),
|
31 |
-
'version' => '3.
|
32 |
-
'footer' => true,
|
33 |
-
),
|
34 |
-
'pickadate-time' => array(
|
35 |
-
'path' => 'lib/pickadate/picker.time.js',
|
36 |
-
'dependencies' => array( 'jquery' ),
|
37 |
-
'version' => '3.
|
38 |
-
'footer' => true,
|
39 |
-
),
|
40 |
-
'pickadate-legacy' => array(
|
41 |
-
'path' => 'lib/pickadate/legacy.js',
|
42 |
-
'dependencies' => array( 'jquery' ),
|
43 |
-
'version' => '3.
|
44 |
-
'footer' => true,
|
45 |
-
),
|
46 |
-
'sap-scheduler' => array(
|
47 |
-
'path' => 'js/scheduler.js',
|
48 |
-
'dependencies' => array( 'jquery' ),
|
49 |
-
'version' =>
|
50 |
-
'footer' => true,
|
51 |
-
),
|
52 |
-
// @todo there should be some way to load alternate language .js files
|
53 |
-
// and RTL CSS scripts
|
54 |
-
);
|
55 |
-
|
56 |
-
/**
|
57 |
-
* Styles that must be loaded for this component
|
58 |
-
* @since 2.0.a.4
|
59 |
-
*/
|
60 |
-
public $styles = array(
|
61 |
-
'pickadate-default' => array(
|
62 |
-
'path' => 'lib/pickadate/themes/default.css',
|
63 |
-
'dependencies' => '',
|
64 |
-
'version' => '3.
|
65 |
-
'media' => null,
|
66 |
-
),
|
67 |
-
'pickadate-date' => array(
|
68 |
-
'path' => 'lib/pickadate/themes/default.date.css',
|
69 |
-
'dependencies' => '',
|
70 |
-
'version' => '3.
|
71 |
-
'media' => null,
|
72 |
-
),
|
73 |
-
'pickadate-time' => array(
|
74 |
-
'path' => 'lib/pickadate/themes/default.time.css',
|
75 |
-
'dependencies' => '',
|
76 |
-
'version' => '3.
|
77 |
-
'media' => null,
|
78 |
-
),
|
79 |
-
);
|
80 |
-
|
81 |
-
/**
|
82 |
-
* Used for data storage. Not translated
|
83 |
-
*/
|
84 |
-
public $weekdays = array(
|
85 |
-
'monday' => 'Mo',
|
86 |
-
'tuesday' => 'Tu',
|
87 |
-
'wednesday' => 'We',
|
88 |
-
'thursday' => 'Th',
|
89 |
-
'friday' => 'Fr',
|
90 |
-
'saturday' => 'Sa',
|
91 |
-
'sunday' => 'Su',
|
92 |
-
);
|
93 |
-
|
94 |
-
/**
|
95 |
-
* Used for data storage. Not translated
|
96 |
-
*/
|
97 |
-
public $weeks = array(
|
98 |
-
'first' => '1st',
|
99 |
-
'second' => '2nd',
|
100 |
-
'third' => '3rd',
|
101 |
-
'fourth' => '4th',
|
102 |
-
'last' => 'last',
|
103 |
-
);
|
104 |
-
|
105 |
-
/**
|
106 |
-
* Translateable strings required for this component
|
107 |
-
* @since 2.0.a.8
|
108 |
-
*/
|
109 |
-
public $strings = array(
|
110 |
-
'add_rule' => null, // __( 'Add new scheduling rule', 'textdomain' ),
|
111 |
-
'weekly' => null, // _x( 'Weekly', 'Format of a scheduling rule', 'textdomain' ),
|
112 |
-
'monthly' => null, // _x( 'Monthly', 'Format of a scheduling rule', 'textdomain' ),
|
113 |
-
'date' => null, // _x( 'Date', 'Format of a scheduling rule', 'textdomain' ),
|
114 |
-
'weekdays' => null, // _x( 'Days of the week', 'Label for selecting days of the week in a scheduling rule', 'textdomain' ),
|
115 |
-
'month_weeks' => null, // _x( 'Weeks of the month', 'Label for selecting weeks of the month in a scheduling rule', 'textdomain' ),
|
116 |
-
'date_label' => null, // _x( 'Date', 'Label to select a date for a scheduling rule', 'textdomain' ),
|
117 |
-
'time_label' => null, // _x( 'Time', 'Label to select a time slot for a scheduling rule', 'textdomain' ),
|
118 |
-
'allday' => null, // _x( 'All day', 'Label to set a scheduling rule to last all day', 'textdomain' ),
|
119 |
-
'start' => null, // _x( 'Start', 'Label for the starting time of a scheduling rule', 'textdomain' ),
|
120 |
-
'end' => null, // _x( 'End', 'Label for the ending time of a scheduling rule', 'textdomain' ),
|
121 |
-
'set_time_prompt' => null, // _x( 'All day long. Want to %sset a time slot%s?', 'Prompt displayed when a scheduling rule is set without any time restrictions', 'textdomain' ),
|
122 |
-
'toggle' => null, // _x( 'Open and close this rule', 'Toggle a scheduling rule open and closed', 'textdomain' ),
|
123 |
-
'delete' => null, // _x( 'Delete rule', 'Delete a scheduling rule', 'textdomain' ),
|
124 |
-
'delete_schedule' => null, // __( 'Delete scheduling rule', 'textdomain' ),
|
125 |
-
'never' => null, // _x( 'Never', 'Brief default description of a scheduling rule when no weekdays or weeks are included in the rule', 'textdomain' ),
|
126 |
-
'weekly_always' => null, // _x( 'Every day', 'Brief default description of a scheduling rule when all the weekdays/weeks are included in the rule', 'textdomain' ),
|
127 |
-
'monthly_weekdays' => null, // _x( '%s on the %s week of the month', 'Brief default description of a scheduling rule when some weekdays are included on only some weeks of the month. %s should be left alone and will be replaced by a comma-separated list of days and weeks in the following format: M, T, W on the first, second week of the month', 'textdomain' ),
|
128 |
-
'monthly_weeks' => null, // _x( '%s week of the month', 'Brief default description of a scheduling rule when some weeks of the month are included but all or no weekdays are selected. %s should be left alone and will be replaced by a comma-separated list of weeks in the following format: First, second week of the month', 'textdomain' ),
|
129 |
-
'all_day' => null, // _x( 'All day', 'Brief default description of a scheduling rule when no times are set', 'textdomain' ),
|
130 |
-
'before' => null, // _x( 'Ends at', 'Brief default description of a scheduling rule when an end time is set but no start time. If the end time is 6pm, it will read: Ends at 6pm', 'textdomain' ),
|
131 |
-
'after' => null, // _x( 'Starts at', 'Brief default description of a scheduling rule when a start time is set but no end time. If the start time is 6pm, it will read: Starts at 6pm', 'textdomain' ),
|
132 |
-
'separator' => null, // _x( '—', 'Separator between times of a scheduling rule', 'textdomain' ),
|
133 |
-
);
|
134 |
-
|
135 |
-
/**
|
136 |
-
* Number of minutes between time selection intervals
|
137 |
-
*/
|
138 |
-
public $time_interval = 15;
|
139 |
-
|
140 |
-
/**
|
141 |
-
* Display format for time selection
|
142 |
-
* See http://amsul.ca/pickadate.js/ for formatting options
|
143 |
-
*/
|
144 |
-
public $time_format = 'h:i A';
|
145 |
-
|
146 |
-
/**
|
147 |
-
* Display format for date selection
|
148 |
-
* See http://amsul.ca/pickadate.js/ for formatting options
|
149 |
-
*/
|
150 |
-
public $date_format = 'd mmmm, yyyy';
|
151 |
-
|
152 |
-
/**
|
153 |
-
* Boolean to disable the weekday selection option
|
154 |
-
*/
|
155 |
-
public $disable_weekdays = false;
|
156 |
-
|
157 |
-
/**
|
158 |
-
* Boolean to disable the weeks selection option
|
159 |
-
*/
|
160 |
-
public $disable_weeks = false;
|
161 |
-
|
162 |
-
/**
|
163 |
-
* Boolean to disable the date selection option
|
164 |
-
*/
|
165 |
-
public $disable_date = false;
|
166 |
-
|
167 |
-
/**
|
168 |
-
* Boolean to disable the time selection option
|
169 |
-
*/
|
170 |
-
public $disable_time = false;
|
171 |
-
|
172 |
-
/**
|
173 |
-
* Boolean to disable the end time selection option
|
174 |
-
*/
|
175 |
-
public $disable_end_time = false;
|
176 |
-
|
177 |
-
/**
|
178 |
-
* Boolean to disable multiple rules per component
|
179 |
-
*/
|
180 |
-
public $disable_multiple = false;
|
181 |
-
|
182 |
-
/**
|
183 |
-
* Escape the value to display it in text fields and other input fields
|
184 |
-
* @since 2.0
|
185 |
-
*/
|
186 |
-
public function esc_value( $val ) {
|
187 |
-
|
188 |
-
$value = array();
|
189 |
-
|
190 |
-
if ( empty( $val ) ) {
|
191 |
-
return $value;
|
192 |
-
}
|
193 |
-
|
194 |
-
foreach ( $val as $i => $rule ) {
|
195 |
-
|
196 |
-
if ( !empty( $rule['weekdays'] ) ) {
|
197 |
-
$value[$i]['weekdays'] = array();
|
198 |
-
foreach ( $rule['weekdays'] as $day => $flag ) {
|
199 |
-
if ( $flag !== '1' ) {
|
200 |
-
continue;
|
201 |
-
}
|
202 |
-
|
203 |
-
$value[$i]['weekdays'][$day] = $flag;
|
204 |
-
}
|
205 |
-
}
|
206 |
-
|
207 |
-
if ( !empty( $rule['weeks'] ) ) {
|
208 |
-
$value[$i]['weeks'] = array();
|
209 |
-
foreach ( $rule['weeks'] as $week => $flag ) {
|
210 |
-
if ( $flag !== '1' ) {
|
211 |
-
continue;
|
212 |
-
}
|
213 |
-
|
214 |
-
$value[$i]['weeks'][$week] = $flag;
|
215 |
-
}
|
216 |
-
}
|
217 |
-
|
218 |
-
if ( !empty( $rule['date'] ) ) {
|
219 |
-
$value[$i]['date'] = esc_attr( $rule['date'] );
|
220 |
-
}
|
221 |
-
|
222 |
-
if ( !empty( $rule['time']['start'] ) ) {
|
223 |
-
$value[$i]['time']['start'] = esc_attr( $rule['time']['start'] );
|
224 |
-
}
|
225 |
-
if ( !empty( $rule['time']['end'] ) ) {
|
226 |
-
$value[$i]['time']['end'] = esc_attr( $rule['time']['end'] );
|
227 |
-
}
|
228 |
-
}
|
229 |
-
|
230 |
-
return $value;
|
231 |
-
}
|
232 |
-
|
233 |
-
/**
|
234 |
-
* Compile and pass configurable variables to the javascript file, so they
|
235 |
-
* can be used when we initialize the pickadate components
|
236 |
-
* @since 2.0
|
237 |
-
*/
|
238 |
-
public function pass_to_scripts() {
|
239 |
-
|
240 |
-
// Create a global variable containing settings for all schedulers
|
241 |
-
// that are being rendered on the page. This allows us to pass different
|
242 |
-
// settings for different schedulers on the same page.
|
243 |
-
global $sap_scheduler_settings;
|
244 |
-
|
245 |
-
if ( !isset( $sap_scheduler_settings ) ) {
|
246 |
-
$sap_scheduler_settings = array();
|
247 |
-
}
|
248 |
-
|
249 |
-
$sap_scheduler_settings[ $this->id ] = array(
|
250 |
-
'time_interval' => $this->time_interval,
|
251 |
-
'time_format' => $this->time_format,
|
252 |
-
'date_format' => $this->date_format,
|
253 |
-
'template' => $this->get_template(),
|
254 |
-
'weekdays' => $this->weekdays,
|
255 |
-
'weeks' => $this->weeks,
|
256 |
-
'disable_weekdays' => $this->disable_weekdays,
|
257 |
-
'disable_weeks' => $this->disable_weeks,
|
258 |
-
'disable_date' => $this->disable_date,
|
259 |
-
'disable_time' => $this->disable_time,
|
260 |
-
'disable_multiple' => $this->disable_multiple,
|
261 |
-
'summaries' => $this->schedule_summaries,
|
262 |
-
);
|
263 |
-
|
264 |
-
// This gets called multiple times, but only the last call is actually
|
265 |
-
// pushed to the script.
|
266 |
-
wp_localize_script(
|
267 |
-
'sap-scheduler',
|
268 |
-
'sap_scheduler',
|
269 |
-
array(
|
270 |
-
'settings' => $sap_scheduler_settings
|
271 |
-
)
|
272 |
-
);
|
273 |
-
|
274 |
-
}
|
275 |
-
|
276 |
-
/**
|
277 |
-
* Display this setting
|
278 |
-
* @since 2.0
|
279 |
-
*/
|
280 |
-
public function display_setting() {
|
281 |
-
|
282 |
-
$this->display_description();
|
283 |
-
|
284 |
-
// Define summary text to use when a rule is displayed in brief
|
285 |
-
$this->set_schedule_summaries();
|
286 |
-
|
287 |
-
// Pass data to the script files to handle js interactions
|
288 |
-
$this->pass_to_scripts();
|
289 |
-
|
290 |
-
?>
|
291 |
-
|
292 |
-
<div class="sap-scheduler <?php echo ( $this->disabled ? 'disabled' : ''); ?>" id="<?php echo $this->id; ?>">
|
293 |
-
<?php
|
294 |
-
foreach ( $this->value as $id => $rule ) {
|
295 |
-
echo $this->get_template( $id, $rule, true );
|
296 |
-
}
|
297 |
-
?>
|
298 |
-
</div>
|
299 |
-
|
300 |
-
<div class="sap-add-scheduler<?php if ( $this->disable_multiple && count( $this->value ) ) : ?> disabled<?php endif; ?> <?php echo ( $this->disabled ? 'disabled' : ''); ?>">
|
301 |
-
<a href="#" class="button">
|
302 |
-
<?php echo $this->strings['add_rule']; ?>
|
303 |
-
</a>
|
304 |
-
</div>
|
305 |
-
|
306 |
-
<?php $this->display_disabled(); ?>
|
307 |
-
|
308 |
-
<?php
|
309 |
-
}
|
310 |
-
|
311 |
-
/**
|
312 |
-
* Retrieve the template for a scheduling rule
|
313 |
-
* @since 2.0
|
314 |
-
*/
|
315 |
-
public function get_template( $id = 0, $values = array(), $list = false ) {
|
316 |
-
|
317 |
-
$date_format = $this->get_date_format( $values );
|
318 |
-
$time_format = $this->get_time_format( $values );
|
319 |
-
|
320 |
-
ob_start();
|
321 |
-
?>
|
322 |
-
|
323 |
-
<div class="sap-scheduler-rule clearfix<?php echo $list ? ' list' : ''; ?>">
|
324 |
-
<div class="sap-scheduler-date <?php echo $date_format; echo $this->disable_time === true ? ' full-width' : ''; ?>">
|
325 |
-
<ul class="sap-selector">
|
326 |
-
|
327 |
-
<?php if ( !$this->has_multiple_date_formats() ) : ?>
|
328 |
-
<li>
|
329 |
-
<div class="dashicons dashicons-calendar"></div>
|
330 |
-
<?php if ( $date_format == 'weekly' ) : ?>
|
331 |
-
<?php echo $this->strings['weekly']; ?>
|
332 |
-
<?php elseif ( $date_format == 'monthly' ) : ?>
|
333 |
-
<?php echo $this->strings['monthly']; ?>
|
334 |
-
<?php elseif ( $date_format == 'date' ) : ?>
|
335 |
-
<?php echo $this->strings['date']; ?>
|
336 |
-
<?php endif; ?>
|
337 |
-
</li>
|
338 |
-
<?php else : ?>
|
339 |
-
|
340 |
-
<?php if ( $this->disable_weekdays === false ) : ?>
|
341 |
-
<li>
|
342 |
-
<div class="dashicons dashicons-calendar"></div>
|
343 |
-
<a href="#" data-format="weekly"<?php echo $date_format == 'weekly' ? ' class="selected"' : ''; ?>>
|
344 |
-
<?php echo $this->strings['weekly']; ?>
|
345 |
-
</a>
|
346 |
-
</li>
|
347 |
-
<?php endif; ?>
|
348 |
-
|
349 |
-
<?php if ( $this->disable_weeks === false ) : ?>
|
350 |
-
<li>
|
351 |
-
<a href="#" data-format="monthly"<?php echo $date_format == 'monthly' ? ' class="selected"' : ''; ?>>
|
352 |
-
<?php echo $this->strings['monthly']; ?>
|
353 |
-
</a>
|
354 |
-
</li>
|
355 |
-
<?php endif; ?>
|
356 |
-
|
357 |
-
<?php if ( $this->disable_date === false ) : ?>
|
358 |
-
<li>
|
359 |
-
<a href="#" data-format="date"<?php echo $date_format == 'date' ? ' class="selected"' : ''; ?>>
|
360 |
-
<?php echo $this->strings['date']; ?>
|
361 |
-
</a>
|
362 |
-
</li>
|
363 |
-
<?php endif; ?>
|
364 |
-
|
365 |
-
<?php endif; ?>
|
366 |
-
</ul>
|
367 |
-
|
368 |
-
<?php if ( $this->disable_weekdays === false ) : ?>
|
369 |
-
<ul class="sap-scheduler-weekdays">
|
370 |
-
<li class="label">
|
371 |
-
<?php echo $this->strings['weekdays']; ?>
|
372 |
-
</li>
|
373 |
-
<?php
|
374 |
-
foreach ( $this->weekdays as $slug => $label ) :
|
375 |
-
$input_name = $this->get_input_name() . '[' . $id . '][weekdays][' . esc_attr( $slug ) . ']';
|
376 |
-
?>
|
377 |
-
<li>
|
378 |
-
<input type="checkbox" name="<?php echo $input_name; ?>" id="<?php echo $input_name; ?>" value="1"<?php echo empty( $values['weekdays'][$slug] ) ? '' : ' checked="checked"'; ?> data-day="<?php echo esc_attr( $slug ); ?>"><label for="<?php echo $input_name; ?>"><?php echo ucfirst( $label ); ?></label>
|
379 |
-
</li>
|
380 |
-
<?php endforeach; ?>
|
381 |
-
</ul>
|
382 |
-
<?php endif; ?>
|
383 |
-
|
384 |
-
<?php if ( $this->disable_weeks === false ) : ?>
|
385 |
-
<ul class="sap-scheduler-weeks">
|
386 |
-
<li class="label">
|
387 |
-
<?php echo $this->strings['month_weeks']; ?>
|
388 |
-
</li>
|
389 |
-
<?php
|
390 |
-
foreach ( $this->weeks as $slug => $label ) :
|
391 |
-
$input_name = $this->get_input_name() . '[' . $id . '][weeks][' . esc_attr( $slug ) . ']';
|
392 |
-
?>
|
393 |
-
<li>
|
394 |
-
<input type="checkbox" name="<?php echo $input_name; ?>" id="<?php echo $input_name; ?>" value="1"<?php echo empty( $values['weeks'][$slug] ) ? '' : ' checked="checked"'; ?> data-week="<?php echo esc_attr( $slug ); ?>"><label for="<?php echo $input_name; ?>"><?php echo ucfirst( $label ); ?></label>
|
395 |
-
</li>
|
396 |
-
<?php endforeach; ?>
|
397 |
-
</ul>
|
398 |
-
<?php endif; ?>
|
399 |
-
|
400 |
-
<?php if ( $this->disable_date === false ) : ?>
|
401 |
-
<div class="sap-scheduler-date-input">
|
402 |
-
<label for="<?php echo $this->get_input_name(); ?>[<?php echo $id; ?>][date]">
|
403 |
-
<?php echo $this->strings['date_label']; ?>
|
404 |
-
</label>
|
405 |
-
<input type="text" name="<?php echo $this->get_input_name(); ?>[<?php echo $id; ?>][date]" id="<?php echo $this->get_input_name(); ?>[<?php echo $id; ?>][date]" value="<?php echo empty( $values['date'] ) ? '' : $values['date']; ?>">
|
406 |
-
</div>
|
407 |
-
<?php endif; ?>
|
408 |
-
|
409 |
-
</div>
|
410 |
-
|
411 |
-
<?php if ( $this->disable_time === false ) : ?>
|
412 |
-
<div class="sap-scheduler-time <?php echo $time_format; ?>">
|
413 |
-
|
414 |
-
<ul class="sap-selector">
|
415 |
-
<li>
|
416 |
-
<div class="dashicons dashicons-clock"></div>
|
417 |
-
<a href="#" data-format="time-slot"<?php echo $time_format == 'time-slot' ? ' class="selected"' : ''; ?>>
|
418 |
-
<?php echo $this->strings['time_label']; ?>
|
419 |
-
</a>
|
420 |
-
</li>
|
421 |
-
<li>
|
422 |
-
<a href="#" data-format="all-day"<?php echo $time_format == 'all-day' ? ' class="selected"' : ''; ?>>
|
423 |
-
<?php echo $this->strings['allday']; ?>
|
424 |
-
</a>
|
425 |
-
</li>
|
426 |
-
</ul>
|
427 |
-
|
428 |
-
<div class="sap-scheduler-time-input clearfix">
|
429 |
-
|
430 |
-
<div class="start">
|
431 |
-
<label for="<?php echo $this->get_input_name(); ?>[<?php echo $id; ?>][time][start]">
|
432 |
-
<?php echo $this->strings['start']; ?>
|
433 |
-
</label>
|
434 |
-
<input type="text" name="<?php echo $this->get_input_name() . '[' . $id . '][time][start]'; ?>" id="<?php echo $this->get_input_name() . '[' . $id . '][time][start]'; ?>" value="<?php echo empty( $values['time']['start'] ) ? '' : $values['time']['start']; ?>">
|
435 |
-
</div>
|
436 |
-
|
437 |
-
<?php if ( $this->disable_end_time === false ) : ?>
|
438 |
-
<div class="end">
|
439 |
-
<label for="<?php echo $this->get_input_name(); ?>[<?php echo $id; ?>][time][end]">
|
440 |
-
<?php echo $this->strings['end']; ?>
|
441 |
-
</label>
|
442 |
-
<input type="text" name="<?php echo $this->get_input_name() . '[' . $id . '][time][end]'; ?>" id="<?php echo $this->get_input_name() . '[' . $id . '][time][end]'; ?>" value="<?php echo empty( $values['time']['end'] ) ? '' : $values['time']['end']; ?>">
|
443 |
-
</div>
|
444 |
-
<?php endif; ?>
|
445 |
-
|
446 |
-
</div>
|
447 |
-
|
448 |
-
<div class="sap-scheduler-all-day">
|
449 |
-
<?php printf( $this->strings['set_time_prompt'], '<a href="#" data-format="time-slot">', '</a>' ); ?>
|
450 |
-
</div>
|
451 |
-
|
452 |
-
</div>
|
453 |
-
<?php endif; ?>
|
454 |
-
|
455 |
-
<div class="sap-scheduler-brief">
|
456 |
-
<div class="date">
|
457 |
-
<div class="dashicons dashicons-calendar"></div>
|
458 |
-
<span class="value"><?php echo $this->get_date_summary( $values ); ?></span>
|
459 |
-
</div>
|
460 |
-
<?php if ( $this->disable_time === false ) : ?>
|
461 |
-
<div class="time">
|
462 |
-
<div class="dashicons dashicons-clock"></div>
|
463 |
-
<span class="value"><?php echo $this->get_time_summary( $values ); ?></span>
|
464 |
-
</div>
|
465 |
-
<?php endif; ?>
|
466 |
-
</div>
|
467 |
-
<div class="sap-scheduler-control">
|
468 |
-
<a href="#" class="toggle" title="<?php echo $this->strings['toggle']; ?>">
|
469 |
-
<div class="dashicons dashicons-<?php echo $list ? 'edit' : 'arrow-up-alt2'; ?>"></div>
|
470 |
-
<span class="screen-reader-text">
|
471 |
-
<?php echo $this->strings['toggle']; ?>
|
472 |
-
</span>
|
473 |
-
</a>
|
474 |
-
<a href="#" class="delete" title="<?php echo $this->strings['delete']; ?>">
|
475 |
-
<div class="dashicons dashicons-dismiss"></div>
|
476 |
-
<span class="screen-reader-text">
|
477 |
-
<?php echo $this->strings['delete_schedule']; ?>
|
478 |
-
</span>
|
479 |
-
</a>
|
480 |
-
</div>
|
481 |
-
</div>
|
482 |
-
|
483 |
-
<?php
|
484 |
-
$output = ob_get_clean();
|
485 |
-
|
486 |
-
return $output;
|
487 |
-
}
|
488 |
-
|
489 |
-
/**
|
490 |
-
* Determine the date format of a rule (weeky/monthly/date)
|
491 |
-
* @since 2.0
|
492 |
-
*/
|
493 |
-
public function get_date_format( $values ) {
|
494 |
-
|
495 |
-
if ( !empty( $values['date'] ) ) {
|
496 |
-
return 'date';
|
497 |
-
} elseif ( !empty( $values['weeks'] ) ) {
|
498 |
-
return 'monthly';
|
499 |
-
} elseif ( !empty( $values['weekdays'] ) ) {
|
500 |
-
return 'weekly';
|
501 |
-
}
|
502 |
-
|
503 |
-
if ( $this->disable_weekdays === false ) {
|
504 |
-
return 'weekly';
|
505 |
-
}
|
506 |
-
if ( $this->disable_weeks === false ) {
|
507 |
-
return 'monthly';
|
508 |
-
}
|
509 |
-
if ( $this->disable_date === false ) {
|
510 |
-
return 'date';
|
511 |
-
}
|
512 |
-
}
|
513 |
-
|
514 |
-
/**
|
515 |
-
* Determine the time format of a rule (time-slot/all-day)
|
516 |
-
* @since 2.0
|
517 |
-
*/
|
518 |
-
public function get_time_format( $values ) {
|
519 |
-
if ( empty( $values['time']['start'] ) && empty( $values['time']['end'] ) ) {
|
520 |
-
return 'all-day';
|
521 |
-
}
|
522 |
-
|
523 |
-
return 'time-slot';
|
524 |
-
}
|
525 |
-
|
526 |
-
/**
|
527 |
-
* Determine if multiple date formats are enabled
|
528 |
-
* @since 2.0
|
529 |
-
*/
|
530 |
-
public function has_multiple_date_formats() {
|
531 |
-
$i = 0;
|
532 |
-
if ( $this->disable_weekdays === false ) {
|
533 |
-
$i++;
|
534 |
-
}
|
535 |
-
if ( $this->disable_weeks === false ) {
|
536 |
-
$i++;
|
537 |
-
}
|
538 |
-
if ( $this->disable_date === false ) {
|
539 |
-
$i++;
|
540 |
-
}
|
541 |
-
|
542 |
-
if ( $i > 1 ) {
|
543 |
-
return true;
|
544 |
-
} else {
|
545 |
-
return false;
|
546 |
-
}
|
547 |
-
}
|
548 |
-
|
549 |
-
/**
|
550 |
-
* Set some default summary strings that can be used when the scheduler
|
551 |
-
* rule is shown in brief
|
552 |
-
* @since 2.0
|
553 |
-
*/
|
554 |
-
public function set_schedule_summaries() {
|
555 |
-
|
556 |
-
if ( !empty( $this->schedule_summaries ) ) {
|
557 |
-
return;
|
558 |
-
}
|
559 |
-
|
560 |
-
$this->schedule_summaries = array(
|
561 |
-
'never' => $this->strings['never'],
|
562 |
-
'weekly_always' => $this->strings['weekly_always'],
|
563 |
-
'monthly_weekdays' => sprintf( $this->strings['monthly_weekdays'], '{days}', '{weeks}' ),
|
564 |
-
'monthly_weeks' => sprintf( $this->strings['monthly_weeks'], '{weeks}' ),
|
565 |
-
'all_day' => $this->strings['all_day'],
|
566 |
-
'before' => $this->strings['before'],
|
567 |
-
'after' => $this->strings['after'],
|
568 |
-
'separator' => $this->strings['separator'],
|
569 |
-
);
|
570 |
-
}
|
571 |
-
|
572 |
-
/**
|
573 |
-
* Print the date phrase, a brief description of the date settings
|
574 |
-
* @since 2.0
|
575 |
-
*/
|
576 |
-
public function get_date_summary( $values = array() ) {
|
577 |
-
|
578 |
-
if ( !empty( $values['date'] ) ) {
|
579 |
-
return $values['date'];
|
580 |
-
}
|
581 |
-
|
582 |
-
if ( empty( $values['weekdays'] ) && $this->disable_weekdays === false ) {
|
583 |
-
return $this->schedule_summaries['never'];
|
584 |
-
}
|
585 |
-
|
586 |
-
if ( empty( $values['weekdays'] ) ) {
|
587 |
-
$weekdays = '';
|
588 |
-
} elseif ( count( $values['weekdays'] ) == 7 ) {
|
589 |
-
$weekdays = $this->schedule_summaries['weekly_always'];
|
590 |
-
} else {
|
591 |
-
$arr = array();
|
592 |
-
foreach ( $values['weekdays'] as $weekday => $state ) {
|
593 |
-
$arr[] = $this->weekdays[$weekday];
|
594 |
-
}
|
595 |
-
$weekdays = join( ', ', $arr );
|
596 |
-
}
|
597 |
-
|
598 |
-
if ( ( empty( $values['weeks'] ) || count( $values['weeks'] ) == 5 ) && $this->disable_weekdays === false ) {
|
599 |
-
return $weekdays;
|
600 |
-
}
|
601 |
-
|
602 |
-
if ( empty( $values['weeks'] ) ) {
|
603 |
-
return $this->schedule_summaries['never'];
|
604 |
-
}
|
605 |
-
|
606 |
-
$arr = array();
|
607 |
-
foreach ( $values['weeks'] as $weeks => $state ) {
|
608 |
-
$arr[] = $this->weeks[$weeks];
|
609 |
-
}
|
610 |
-
$weeks = join( ', ', $arr );
|
611 |
-
|
612 |
-
if ( !empty( $weekdays ) ) {
|
613 |
-
return str_replace( array( '{days}', '{weeks}' ), array( $weekdays, $weeks ), $this->schedule_summaries['monthly_weekdays'] );
|
614 |
-
} else {
|
615 |
-
return str_replace( '{weeks}', ucfirst( $weeks ), $this->schedule_summaries['monthly_weeks'] );
|
616 |
-
}
|
617 |
-
|
618 |
-
}
|
619 |
-
|
620 |
-
/**
|
621 |
-
* Print the time phrase, a brief description of the time settings
|
622 |
-
* @since 2.0
|
623 |
-
*/
|
624 |
-
public function get_time_summary( $values = array() ) {
|
625 |
-
|
626 |
-
if ( empty( $values['time']['start'] ) && empty( $values['time']['end'] ) ) {
|
627 |
-
return $this->schedule_summaries['all_day'];
|
628 |
-
}
|
629 |
-
|
630 |
-
if ( empty( $values['time']['start'] ) ) {
|
631 |
-
return $this->schedule_summaries['before'] . ' ' . $values['time']['end'];
|
632 |
-
}
|
633 |
-
|
634 |
-
if ( empty( $values['time']['end'] ) ) {
|
635 |
-
return $this->schedule_summaries['after'] . ' ' . $values['time']['start'];
|
636 |
-
}
|
637 |
-
|
638 |
-
return $values['time']['start'] . $this->schedule_summaries['separator'] . $values['time']['end'];
|
639 |
-
|
640 |
-
}
|
641 |
-
|
642 |
-
/**
|
643 |
-
* Sanitize the array of text inputs for this setting
|
644 |
-
* @since 2.0
|
645 |
-
*/
|
646 |
-
public function sanitize_callback_wrapper( $values ) {
|
647 |
-
|
648 |
-
$output = array();
|
649 |
-
|
650 |
-
if ( !is_array( $values ) || !count( $values ) ) {
|
651 |
-
return $output;
|
652 |
-
}
|
653 |
-
|
654 |
-
foreach ( $values as $i => $rule ) {
|
655 |
-
|
656 |
-
if ( !empty( $rule['weekdays'] ) ) {
|
657 |
-
$output[$i]['weekdays'] = array();
|
658 |
-
foreach ( $rule['weekdays'] as $day => $flag ) {
|
659 |
-
if ( $flag !== '1' ||
|
660 |
-
( $day !== 'monday' && $day !== 'tuesday' && $day !== 'wednesday' && $day !== 'thursday' && $day !== 'friday' && $day !== 'saturday' && $day !== 'sunday' ) ) {
|
661 |
-
continue;
|
662 |
-
}
|
663 |
-
|
664 |
-
$output[$i]['weekdays'][$day] = $flag;
|
665 |
-
}
|
666 |
-
}
|
667 |
-
|
668 |
-
if ( !empty( $rule['weeks'] ) ) {
|
669 |
-
$output[$i]['weeks'] = array();
|
670 |
-
foreach ( $rule['weeks'] as $week => $flag ) {
|
671 |
-
if ( $flag !== '1' ||
|
672 |
-
( $week !== 'first' && $week !== 'second' && $week !== 'third' && $week !== 'fourth' && $week !== 'last' ) ) {
|
673 |
-
continue;
|
674 |
-
}
|
675 |
-
|
676 |
-
$output[$i]['weeks'][$week] = $flag;
|
677 |
-
}
|
678 |
-
}
|
679 |
-
|
680 |
-
if ( !empty( $rule['date'] ) ) {
|
681 |
-
$date = new DateTime( $rule['date'] );
|
682 |
-
if ( checkdate( $date->format( 'n' ), $date->format( 'j' ), $date->format( 'Y' ) ) ) {
|
683 |
-
$output[$i]['date'] = call_user_func( $this->sanitize_callback, $rule['date'] );
|
684 |
-
}
|
685 |
-
}
|
686 |
-
|
687 |
-
if ( !empty( $rule['time']['start'] ) ) {
|
688 |
-
$output[$i]['time']['start'] = call_user_func( $this->sanitize_callback, $rule['time']['start'] );
|
689 |
-
}
|
690 |
-
if ( !empty( $rule['time']['end'] ) ) {
|
691 |
-
$output[$i]['time']['end'] = call_user_func( $this->sanitize_callback, $rule['time']['end'] );
|
692 |
-
}
|
693 |
-
}
|
694 |
-
|
695 |
-
// Only return the first rule if multiple rules are disabled
|
696 |
-
if ( $this->disable_multiple && count( $output ) > 1 ) {
|
697 |
-
$output = array( array_shift( $output ) );
|
698 |
-
}
|
699 |
-
|
700 |
-
return $output;
|
701 |
-
}
|
702 |
-
|
703 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save a schedule of dates and times.
|
5 |
+
*
|
6 |
+
* This is designed for use for opening hours, a booking schedule or anything
|
7 |
+
* that requires recurring dates and times.
|
8 |
+
*
|
9 |
+
* @since 2.0
|
10 |
+
* @package Simple Admin Pages
|
11 |
+
*/
|
12 |
+
|
13 |
+
class sapAdminPageSettingScheduler_2_5_5 extends sapAdminPageSetting_2_5_5 {
|
14 |
+
|
15 |
+
public $sanitize_callback = 'sanitize_text_field';
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Scripts that must be loaded for this component
|
19 |
+
* @since 2.0.a.4
|
20 |
+
*/
|
21 |
+
public $scripts = array(
|
22 |
+
'pickadate' => array(
|
23 |
+
'path' => 'lib/pickadate/picker.js',
|
24 |
+
'dependencies' => array( 'jquery' ),
|
25 |
+
'version' => '3.6.1',
|
26 |
+
'footer' => true,
|
27 |
+
),
|
28 |
+
'pickadate-date' => array(
|
29 |
+
'path' => 'lib/pickadate/picker.date.js',
|
30 |
+
'dependencies' => array( 'jquery' ),
|
31 |
+
'version' => '3.6.1',
|
32 |
+
'footer' => true,
|
33 |
+
),
|
34 |
+
'pickadate-time' => array(
|
35 |
+
'path' => 'lib/pickadate/picker.time.js',
|
36 |
+
'dependencies' => array( 'jquery' ),
|
37 |
+
'version' => '3.6.1',
|
38 |
+
'footer' => true,
|
39 |
+
),
|
40 |
+
'pickadate-legacy' => array(
|
41 |
+
'path' => 'lib/pickadate/legacy.js',
|
42 |
+
'dependencies' => array( 'jquery' ),
|
43 |
+
'version' => '3.6.1',
|
44 |
+
'footer' => true,
|
45 |
+
),
|
46 |
+
'sap-scheduler' => array(
|
47 |
+
'path' => 'js/scheduler.js',
|
48 |
+
'dependencies' => array( 'jquery' ),
|
49 |
+
'version' => SAP_VERSION,
|
50 |
+
'footer' => true,
|
51 |
+
),
|
52 |
+
// @todo there should be some way to load alternate language .js files
|
53 |
+
// and RTL CSS scripts
|
54 |
+
);
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Styles that must be loaded for this component
|
58 |
+
* @since 2.0.a.4
|
59 |
+
*/
|
60 |
+
public $styles = array(
|
61 |
+
'pickadate-default' => array(
|
62 |
+
'path' => 'lib/pickadate/themes/default.css',
|
63 |
+
'dependencies' => '',
|
64 |
+
'version' => '3.6.1',
|
65 |
+
'media' => null,
|
66 |
+
),
|
67 |
+
'pickadate-date' => array(
|
68 |
+
'path' => 'lib/pickadate/themes/default.date.css',
|
69 |
+
'dependencies' => '',
|
70 |
+
'version' => '3.6.1',
|
71 |
+
'media' => null,
|
72 |
+
),
|
73 |
+
'pickadate-time' => array(
|
74 |
+
'path' => 'lib/pickadate/themes/default.time.css',
|
75 |
+
'dependencies' => '',
|
76 |
+
'version' => '3.6.1',
|
77 |
+
'media' => null,
|
78 |
+
),
|
79 |
+
);
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Used for data storage. Not translated
|
83 |
+
*/
|
84 |
+
public $weekdays = array(
|
85 |
+
'monday' => 'Mo',
|
86 |
+
'tuesday' => 'Tu',
|
87 |
+
'wednesday' => 'We',
|
88 |
+
'thursday' => 'Th',
|
89 |
+
'friday' => 'Fr',
|
90 |
+
'saturday' => 'Sa',
|
91 |
+
'sunday' => 'Su',
|
92 |
+
);
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Used for data storage. Not translated
|
96 |
+
*/
|
97 |
+
public $weeks = array(
|
98 |
+
'first' => '1st',
|
99 |
+
'second' => '2nd',
|
100 |
+
'third' => '3rd',
|
101 |
+
'fourth' => '4th',
|
102 |
+
'last' => 'last',
|
103 |
+
);
|
104 |
+
|
105 |
+
/**
|
106 |
+
* Translateable strings required for this component
|
107 |
+
* @since 2.0.a.8
|
108 |
+
*/
|
109 |
+
public $strings = array(
|
110 |
+
'add_rule' => null, // __( 'Add new scheduling rule', 'textdomain' ),
|
111 |
+
'weekly' => null, // _x( 'Weekly', 'Format of a scheduling rule', 'textdomain' ),
|
112 |
+
'monthly' => null, // _x( 'Monthly', 'Format of a scheduling rule', 'textdomain' ),
|
113 |
+
'date' => null, // _x( 'Date', 'Format of a scheduling rule', 'textdomain' ),
|
114 |
+
'weekdays' => null, // _x( 'Days of the week', 'Label for selecting days of the week in a scheduling rule', 'textdomain' ),
|
115 |
+
'month_weeks' => null, // _x( 'Weeks of the month', 'Label for selecting weeks of the month in a scheduling rule', 'textdomain' ),
|
116 |
+
'date_label' => null, // _x( 'Date', 'Label to select a date for a scheduling rule', 'textdomain' ),
|
117 |
+
'time_label' => null, // _x( 'Time', 'Label to select a time slot for a scheduling rule', 'textdomain' ),
|
118 |
+
'allday' => null, // _x( 'All day', 'Label to set a scheduling rule to last all day', 'textdomain' ),
|
119 |
+
'start' => null, // _x( 'Start', 'Label for the starting time of a scheduling rule', 'textdomain' ),
|
120 |
+
'end' => null, // _x( 'End', 'Label for the ending time of a scheduling rule', 'textdomain' ),
|
121 |
+
'set_time_prompt' => null, // _x( 'All day long. Want to %sset a time slot%s?', 'Prompt displayed when a scheduling rule is set without any time restrictions', 'textdomain' ),
|
122 |
+
'toggle' => null, // _x( 'Open and close this rule', 'Toggle a scheduling rule open and closed', 'textdomain' ),
|
123 |
+
'delete' => null, // _x( 'Delete rule', 'Delete a scheduling rule', 'textdomain' ),
|
124 |
+
'delete_schedule' => null, // __( 'Delete scheduling rule', 'textdomain' ),
|
125 |
+
'never' => null, // _x( 'Never', 'Brief default description of a scheduling rule when no weekdays or weeks are included in the rule', 'textdomain' ),
|
126 |
+
'weekly_always' => null, // _x( 'Every day', 'Brief default description of a scheduling rule when all the weekdays/weeks are included in the rule', 'textdomain' ),
|
127 |
+
'monthly_weekdays' => null, // _x( '%s on the %s week of the month', 'Brief default description of a scheduling rule when some weekdays are included on only some weeks of the month. %s should be left alone and will be replaced by a comma-separated list of days and weeks in the following format: M, T, W on the first, second week of the month', 'textdomain' ),
|
128 |
+
'monthly_weeks' => null, // _x( '%s week of the month', 'Brief default description of a scheduling rule when some weeks of the month are included but all or no weekdays are selected. %s should be left alone and will be replaced by a comma-separated list of weeks in the following format: First, second week of the month', 'textdomain' ),
|
129 |
+
'all_day' => null, // _x( 'All day', 'Brief default description of a scheduling rule when no times are set', 'textdomain' ),
|
130 |
+
'before' => null, // _x( 'Ends at', 'Brief default description of a scheduling rule when an end time is set but no start time. If the end time is 6pm, it will read: Ends at 6pm', 'textdomain' ),
|
131 |
+
'after' => null, // _x( 'Starts at', 'Brief default description of a scheduling rule when a start time is set but no end time. If the start time is 6pm, it will read: Starts at 6pm', 'textdomain' ),
|
132 |
+
'separator' => null, // _x( '—', 'Separator between times of a scheduling rule', 'textdomain' ),
|
133 |
+
);
|
134 |
+
|
135 |
+
/**
|
136 |
+
* Number of minutes between time selection intervals
|
137 |
+
*/
|
138 |
+
public $time_interval = 15;
|
139 |
+
|
140 |
+
/**
|
141 |
+
* Display format for time selection
|
142 |
+
* See http://amsul.ca/pickadate.js/ for formatting options
|
143 |
+
*/
|
144 |
+
public $time_format = 'h:i A';
|
145 |
+
|
146 |
+
/**
|
147 |
+
* Display format for date selection
|
148 |
+
* See http://amsul.ca/pickadate.js/ for formatting options
|
149 |
+
*/
|
150 |
+
public $date_format = 'd mmmm, yyyy';
|
151 |
+
|
152 |
+
/**
|
153 |
+
* Boolean to disable the weekday selection option
|
154 |
+
*/
|
155 |
+
public $disable_weekdays = false;
|
156 |
+
|
157 |
+
/**
|
158 |
+
* Boolean to disable the weeks selection option
|
159 |
+
*/
|
160 |
+
public $disable_weeks = false;
|
161 |
+
|
162 |
+
/**
|
163 |
+
* Boolean to disable the date selection option
|
164 |
+
*/
|
165 |
+
public $disable_date = false;
|
166 |
+
|
167 |
+
/**
|
168 |
+
* Boolean to disable the time selection option
|
169 |
+
*/
|
170 |
+
public $disable_time = false;
|
171 |
+
|
172 |
+
/**
|
173 |
+
* Boolean to disable the end time selection option
|
174 |
+
*/
|
175 |
+
public $disable_end_time = false;
|
176 |
+
|
177 |
+
/**
|
178 |
+
* Boolean to disable multiple rules per component
|
179 |
+
*/
|
180 |
+
public $disable_multiple = false;
|
181 |
+
|
182 |
+
/**
|
183 |
+
* Escape the value to display it in text fields and other input fields
|
184 |
+
* @since 2.0
|
185 |
+
*/
|
186 |
+
public function esc_value( $val ) {
|
187 |
+
|
188 |
+
$value = array();
|
189 |
+
|
190 |
+
if ( empty( $val ) ) {
|
191 |
+
return $value;
|
192 |
+
}
|
193 |
+
|
194 |
+
foreach ( $val as $i => $rule ) {
|
195 |
+
|
196 |
+
if ( !empty( $rule['weekdays'] ) ) {
|
197 |
+
$value[$i]['weekdays'] = array();
|
198 |
+
foreach ( $rule['weekdays'] as $day => $flag ) {
|
199 |
+
if ( $flag !== '1' ) {
|
200 |
+
continue;
|
201 |
+
}
|
202 |
+
|
203 |
+
$value[$i]['weekdays'][$day] = $flag;
|
204 |
+
}
|
205 |
+
}
|
206 |
+
|
207 |
+
if ( !empty( $rule['weeks'] ) ) {
|
208 |
+
$value[$i]['weeks'] = array();
|
209 |
+
foreach ( $rule['weeks'] as $week => $flag ) {
|
210 |
+
if ( $flag !== '1' ) {
|
211 |
+
continue;
|
212 |
+
}
|
213 |
+
|
214 |
+
$value[$i]['weeks'][$week] = $flag;
|
215 |
+
}
|
216 |
+
}
|
217 |
+
|
218 |
+
if ( !empty( $rule['date'] ) ) {
|
219 |
+
$value[$i]['date'] = esc_attr( $rule['date'] );
|
220 |
+
}
|
221 |
+
|
222 |
+
if ( !empty( $rule['time']['start'] ) ) {
|
223 |
+
$value[$i]['time']['start'] = esc_attr( $rule['time']['start'] );
|
224 |
+
}
|
225 |
+
if ( !empty( $rule['time']['end'] ) ) {
|
226 |
+
$value[$i]['time']['end'] = esc_attr( $rule['time']['end'] );
|
227 |
+
}
|
228 |
+
}
|
229 |
+
|
230 |
+
return $value;
|
231 |
+
}
|
232 |
+
|
233 |
+
/**
|
234 |
+
* Compile and pass configurable variables to the javascript file, so they
|
235 |
+
* can be used when we initialize the pickadate components
|
236 |
+
* @since 2.0
|
237 |
+
*/
|
238 |
+
public function pass_to_scripts() {
|
239 |
+
|
240 |
+
// Create a global variable containing settings for all schedulers
|
241 |
+
// that are being rendered on the page. This allows us to pass different
|
242 |
+
// settings for different schedulers on the same page.
|
243 |
+
global $sap_scheduler_settings;
|
244 |
+
|
245 |
+
if ( !isset( $sap_scheduler_settings ) ) {
|
246 |
+
$sap_scheduler_settings = array();
|
247 |
+
}
|
248 |
+
|
249 |
+
$sap_scheduler_settings[ $this->id ] = array(
|
250 |
+
'time_interval' => $this->time_interval,
|
251 |
+
'time_format' => $this->time_format,
|
252 |
+
'date_format' => $this->date_format,
|
253 |
+
'template' => $this->get_template(),
|
254 |
+
'weekdays' => $this->weekdays,
|
255 |
+
'weeks' => $this->weeks,
|
256 |
+
'disable_weekdays' => $this->disable_weekdays,
|
257 |
+
'disable_weeks' => $this->disable_weeks,
|
258 |
+
'disable_date' => $this->disable_date,
|
259 |
+
'disable_time' => $this->disable_time,
|
260 |
+
'disable_multiple' => $this->disable_multiple,
|
261 |
+
'summaries' => $this->schedule_summaries,
|
262 |
+
);
|
263 |
+
|
264 |
+
// This gets called multiple times, but only the last call is actually
|
265 |
+
// pushed to the script.
|
266 |
+
wp_localize_script(
|
267 |
+
'sap-scheduler',
|
268 |
+
'sap_scheduler',
|
269 |
+
array(
|
270 |
+
'settings' => $sap_scheduler_settings
|
271 |
+
)
|
272 |
+
);
|
273 |
+
|
274 |
+
}
|
275 |
+
|
276 |
+
/**
|
277 |
+
* Display this setting
|
278 |
+
* @since 2.0
|
279 |
+
*/
|
280 |
+
public function display_setting() {
|
281 |
+
|
282 |
+
$this->display_description();
|
283 |
+
|
284 |
+
// Define summary text to use when a rule is displayed in brief
|
285 |
+
$this->set_schedule_summaries();
|
286 |
+
|
287 |
+
// Pass data to the script files to handle js interactions
|
288 |
+
$this->pass_to_scripts();
|
289 |
+
|
290 |
+
?>
|
291 |
+
|
292 |
+
<div class="sap-scheduler <?php echo ( $this->disabled ? 'disabled' : ''); ?>" id="<?php echo $this->id; ?>">
|
293 |
+
<?php
|
294 |
+
foreach ( $this->value as $id => $rule ) {
|
295 |
+
echo $this->get_template( $id, $rule, true );
|
296 |
+
}
|
297 |
+
?>
|
298 |
+
</div>
|
299 |
+
|
300 |
+
<div class="sap-add-scheduler<?php if ( $this->disable_multiple && count( $this->value ) ) : ?> disabled<?php endif; ?> <?php echo ( $this->disabled ? 'disabled' : ''); ?>">
|
301 |
+
<a href="#" class="button">
|
302 |
+
<?php echo $this->strings['add_rule']; ?>
|
303 |
+
</a>
|
304 |
+
</div>
|
305 |
+
|
306 |
+
<?php $this->display_disabled(); ?>
|
307 |
+
|
308 |
+
<?php
|
309 |
+
}
|
310 |
+
|
311 |
+
/**
|
312 |
+
* Retrieve the template for a scheduling rule
|
313 |
+
* @since 2.0
|
314 |
+
*/
|
315 |
+
public function get_template( $id = 0, $values = array(), $list = false ) {
|
316 |
+
|
317 |
+
$date_format = $this->get_date_format( $values );
|
318 |
+
$time_format = $this->get_time_format( $values );
|
319 |
+
|
320 |
+
ob_start();
|
321 |
+
?>
|
322 |
+
|
323 |
+
<div class="sap-scheduler-rule clearfix<?php echo $list ? ' list' : ''; ?>">
|
324 |
+
<div class="sap-scheduler-date <?php echo $date_format; echo $this->disable_time === true ? ' full-width' : ''; ?>">
|
325 |
+
<ul class="sap-selector">
|
326 |
+
|
327 |
+
<?php if ( !$this->has_multiple_date_formats() ) : ?>
|
328 |
+
<li>
|
329 |
+
<div class="dashicons dashicons-calendar"></div>
|
330 |
+
<?php if ( $date_format == 'weekly' ) : ?>
|
331 |
+
<?php echo $this->strings['weekly']; ?>
|
332 |
+
<?php elseif ( $date_format == 'monthly' ) : ?>
|
333 |
+
<?php echo $this->strings['monthly']; ?>
|
334 |
+
<?php elseif ( $date_format == 'date' ) : ?>
|
335 |
+
<?php echo $this->strings['date']; ?>
|
336 |
+
<?php endif; ?>
|
337 |
+
</li>
|
338 |
+
<?php else : ?>
|
339 |
+
|
340 |
+
<?php if ( $this->disable_weekdays === false ) : ?>
|
341 |
+
<li>
|
342 |
+
<div class="dashicons dashicons-calendar"></div>
|
343 |
+
<a href="#" data-format="weekly"<?php echo $date_format == 'weekly' ? ' class="selected"' : ''; ?>>
|
344 |
+
<?php echo $this->strings['weekly']; ?>
|
345 |
+
</a>
|
346 |
+
</li>
|
347 |
+
<?php endif; ?>
|
348 |
+
|
349 |
+
<?php if ( $this->disable_weeks === false ) : ?>
|
350 |
+
<li>
|
351 |
+
<a href="#" data-format="monthly"<?php echo $date_format == 'monthly' ? ' class="selected"' : ''; ?>>
|
352 |
+
<?php echo $this->strings['monthly']; ?>
|
353 |
+
</a>
|
354 |
+
</li>
|
355 |
+
<?php endif; ?>
|
356 |
+
|
357 |
+
<?php if ( $this->disable_date === false ) : ?>
|
358 |
+
<li>
|
359 |
+
<a href="#" data-format="date"<?php echo $date_format == 'date' ? ' class="selected"' : ''; ?>>
|
360 |
+
<?php echo $this->strings['date']; ?>
|
361 |
+
</a>
|
362 |
+
</li>
|
363 |
+
<?php endif; ?>
|
364 |
+
|
365 |
+
<?php endif; ?>
|
366 |
+
</ul>
|
367 |
+
|
368 |
+
<?php if ( $this->disable_weekdays === false ) : ?>
|
369 |
+
<ul class="sap-scheduler-weekdays">
|
370 |
+
<li class="label">
|
371 |
+
<?php echo $this->strings['weekdays']; ?>
|
372 |
+
</li>
|
373 |
+
<?php
|
374 |
+
foreach ( $this->weekdays as $slug => $label ) :
|
375 |
+
$input_name = $this->get_input_name() . '[' . $id . '][weekdays][' . esc_attr( $slug ) . ']';
|
376 |
+
?>
|
377 |
+
<li>
|
378 |
+
<input type="checkbox" name="<?php echo $input_name; ?>" id="<?php echo $input_name; ?>" value="1"<?php echo empty( $values['weekdays'][$slug] ) ? '' : ' checked="checked"'; ?> data-day="<?php echo esc_attr( $slug ); ?>"><label for="<?php echo $input_name; ?>"><?php echo ucfirst( $label ); ?></label>
|
379 |
+
</li>
|
380 |
+
<?php endforeach; ?>
|
381 |
+
</ul>
|
382 |
+
<?php endif; ?>
|
383 |
+
|
384 |
+
<?php if ( $this->disable_weeks === false ) : ?>
|
385 |
+
<ul class="sap-scheduler-weeks">
|
386 |
+
<li class="label">
|
387 |
+
<?php echo $this->strings['month_weeks']; ?>
|
388 |
+
</li>
|
389 |
+
<?php
|
390 |
+
foreach ( $this->weeks as $slug => $label ) :
|
391 |
+
$input_name = $this->get_input_name() . '[' . $id . '][weeks][' . esc_attr( $slug ) . ']';
|
392 |
+
?>
|
393 |
+
<li>
|
394 |
+
<input type="checkbox" name="<?php echo $input_name; ?>" id="<?php echo $input_name; ?>" value="1"<?php echo empty( $values['weeks'][$slug] ) ? '' : ' checked="checked"'; ?> data-week="<?php echo esc_attr( $slug ); ?>"><label for="<?php echo $input_name; ?>"><?php echo ucfirst( $label ); ?></label>
|
395 |
+
</li>
|
396 |
+
<?php endforeach; ?>
|
397 |
+
</ul>
|
398 |
+
<?php endif; ?>
|
399 |
+
|
400 |
+
<?php if ( $this->disable_date === false ) : ?>
|
401 |
+
<div class="sap-scheduler-date-input">
|
402 |
+
<label for="<?php echo $this->get_input_name(); ?>[<?php echo $id; ?>][date]">
|
403 |
+
<?php echo $this->strings['date_label']; ?>
|
404 |
+
</label>
|
405 |
+
<input type="text" name="<?php echo $this->get_input_name(); ?>[<?php echo $id; ?>][date]" id="<?php echo $this->get_input_name(); ?>[<?php echo $id; ?>][date]" value="<?php echo empty( $values['date'] ) ? '' : $values['date']; ?>">
|
406 |
+
</div>
|
407 |
+
<?php endif; ?>
|
408 |
+
|
409 |
+
</div>
|
410 |
+
|
411 |
+
<?php if ( $this->disable_time === false ) : ?>
|
412 |
+
<div class="sap-scheduler-time <?php echo $time_format; ?>">
|
413 |
+
|
414 |
+
<ul class="sap-selector">
|
415 |
+
<li>
|
416 |
+
<div class="dashicons dashicons-clock"></div>
|
417 |
+
<a href="#" data-format="time-slot"<?php echo $time_format == 'time-slot' ? ' class="selected"' : ''; ?>>
|
418 |
+
<?php echo $this->strings['time_label']; ?>
|
419 |
+
</a>
|
420 |
+
</li>
|
421 |
+
<li>
|
422 |
+
<a href="#" data-format="all-day"<?php echo $time_format == 'all-day' ? ' class="selected"' : ''; ?>>
|
423 |
+
<?php echo $this->strings['allday']; ?>
|
424 |
+
</a>
|
425 |
+
</li>
|
426 |
+
</ul>
|
427 |
+
|
428 |
+
<div class="sap-scheduler-time-input clearfix">
|
429 |
+
|
430 |
+
<div class="start">
|
431 |
+
<label for="<?php echo $this->get_input_name(); ?>[<?php echo $id; ?>][time][start]">
|
432 |
+
<?php echo $this->strings['start']; ?>
|
433 |
+
</label>
|
434 |
+
<input type="text" name="<?php echo $this->get_input_name() . '[' . $id . '][time][start]'; ?>" id="<?php echo $this->get_input_name() . '[' . $id . '][time][start]'; ?>" value="<?php echo empty( $values['time']['start'] ) ? '' : $values['time']['start']; ?>">
|
435 |
+
</div>
|
436 |
+
|
437 |
+
<?php if ( $this->disable_end_time === false ) : ?>
|
438 |
+
<div class="end">
|
439 |
+
<label for="<?php echo $this->get_input_name(); ?>[<?php echo $id; ?>][time][end]">
|
440 |
+
<?php echo $this->strings['end']; ?>
|
441 |
+
</label>
|
442 |
+
<input type="text" name="<?php echo $this->get_input_name() . '[' . $id . '][time][end]'; ?>" id="<?php echo $this->get_input_name() . '[' . $id . '][time][end]'; ?>" value="<?php echo empty( $values['time']['end'] ) ? '' : $values['time']['end']; ?>">
|
443 |
+
</div>
|
444 |
+
<?php endif; ?>
|
445 |
+
|
446 |
+
</div>
|
447 |
+
|
448 |
+
<div class="sap-scheduler-all-day">
|
449 |
+
<?php printf( $this->strings['set_time_prompt'], '<a href="#" data-format="time-slot">', '</a>' ); ?>
|
450 |
+
</div>
|
451 |
+
|
452 |
+
</div>
|
453 |
+
<?php endif; ?>
|
454 |
+
|
455 |
+
<div class="sap-scheduler-brief">
|
456 |
+
<div class="date">
|
457 |
+
<div class="dashicons dashicons-calendar"></div>
|
458 |
+
<span class="value"><?php echo $this->get_date_summary( $values ); ?></span>
|
459 |
+
</div>
|
460 |
+
<?php if ( $this->disable_time === false ) : ?>
|
461 |
+
<div class="time">
|
462 |
+
<div class="dashicons dashicons-clock"></div>
|
463 |
+
<span class="value"><?php echo $this->get_time_summary( $values ); ?></span>
|
464 |
+
</div>
|
465 |
+
<?php endif; ?>
|
466 |
+
</div>
|
467 |
+
<div class="sap-scheduler-control">
|
468 |
+
<a href="#" class="toggle" title="<?php echo $this->strings['toggle']; ?>">
|
469 |
+
<div class="dashicons dashicons-<?php echo $list ? 'edit' : 'arrow-up-alt2'; ?>"></div>
|
470 |
+
<span class="screen-reader-text">
|
471 |
+
<?php echo $this->strings['toggle']; ?>
|
472 |
+
</span>
|
473 |
+
</a>
|
474 |
+
<a href="#" class="delete" title="<?php echo $this->strings['delete']; ?>">
|
475 |
+
<div class="dashicons dashicons-dismiss"></div>
|
476 |
+
<span class="screen-reader-text">
|
477 |
+
<?php echo $this->strings['delete_schedule']; ?>
|
478 |
+
</span>
|
479 |
+
</a>
|
480 |
+
</div>
|
481 |
+
</div>
|
482 |
+
|
483 |
+
<?php
|
484 |
+
$output = ob_get_clean();
|
485 |
+
|
486 |
+
return $output;
|
487 |
+
}
|
488 |
+
|
489 |
+
/**
|
490 |
+
* Determine the date format of a rule (weeky/monthly/date)
|
491 |
+
* @since 2.0
|
492 |
+
*/
|
493 |
+
public function get_date_format( $values ) {
|
494 |
+
|
495 |
+
if ( !empty( $values['date'] ) ) {
|
496 |
+
return 'date';
|
497 |
+
} elseif ( !empty( $values['weeks'] ) ) {
|
498 |
+
return 'monthly';
|
499 |
+
} elseif ( !empty( $values['weekdays'] ) ) {
|
500 |
+
return 'weekly';
|
501 |
+
}
|
502 |
+
|
503 |
+
if ( $this->disable_weekdays === false ) {
|
504 |
+
return 'weekly';
|
505 |
+
}
|
506 |
+
if ( $this->disable_weeks === false ) {
|
507 |
+
return 'monthly';
|
508 |
+
}
|
509 |
+
if ( $this->disable_date === false ) {
|
510 |
+
return 'date';
|
511 |
+
}
|
512 |
+
}
|
513 |
+
|
514 |
+
/**
|
515 |
+
* Determine the time format of a rule (time-slot/all-day)
|
516 |
+
* @since 2.0
|
517 |
+
*/
|
518 |
+
public function get_time_format( $values ) {
|
519 |
+
if ( empty( $values['time']['start'] ) && empty( $values['time']['end'] ) ) {
|
520 |
+
return 'all-day';
|
521 |
+
}
|
522 |
+
|
523 |
+
return 'time-slot';
|
524 |
+
}
|
525 |
+
|
526 |
+
/**
|
527 |
+
* Determine if multiple date formats are enabled
|
528 |
+
* @since 2.0
|
529 |
+
*/
|
530 |
+
public function has_multiple_date_formats() {
|
531 |
+
$i = 0;
|
532 |
+
if ( $this->disable_weekdays === false ) {
|
533 |
+
$i++;
|
534 |
+
}
|
535 |
+
if ( $this->disable_weeks === false ) {
|
536 |
+
$i++;
|
537 |
+
}
|
538 |
+
if ( $this->disable_date === false ) {
|
539 |
+
$i++;
|
540 |
+
}
|
541 |
+
|
542 |
+
if ( $i > 1 ) {
|
543 |
+
return true;
|
544 |
+
} else {
|
545 |
+
return false;
|
546 |
+
}
|
547 |
+
}
|
548 |
+
|
549 |
+
/**
|
550 |
+
* Set some default summary strings that can be used when the scheduler
|
551 |
+
* rule is shown in brief
|
552 |
+
* @since 2.0
|
553 |
+
*/
|
554 |
+
public function set_schedule_summaries() {
|
555 |
+
|
556 |
+
if ( !empty( $this->schedule_summaries ) ) {
|
557 |
+
return;
|
558 |
+
}
|
559 |
+
|
560 |
+
$this->schedule_summaries = array(
|
561 |
+
'never' => $this->strings['never'],
|
562 |
+
'weekly_always' => $this->strings['weekly_always'],
|
563 |
+
'monthly_weekdays' => sprintf( $this->strings['monthly_weekdays'], '{days}', '{weeks}' ),
|
564 |
+
'monthly_weeks' => sprintf( $this->strings['monthly_weeks'], '{weeks}' ),
|
565 |
+
'all_day' => $this->strings['all_day'],
|
566 |
+
'before' => $this->strings['before'],
|
567 |
+
'after' => $this->strings['after'],
|
568 |
+
'separator' => $this->strings['separator'],
|
569 |
+
);
|
570 |
+
}
|
571 |
+
|
572 |
+
/**
|
573 |
+
* Print the date phrase, a brief description of the date settings
|
574 |
+
* @since 2.0
|
575 |
+
*/
|
576 |
+
public function get_date_summary( $values = array() ) {
|
577 |
+
|
578 |
+
if ( !empty( $values['date'] ) ) {
|
579 |
+
return $values['date'];
|
580 |
+
}
|
581 |
+
|
582 |
+
if ( empty( $values['weekdays'] ) && $this->disable_weekdays === false ) {
|
583 |
+
return $this->schedule_summaries['never'];
|
584 |
+
}
|
585 |
+
|
586 |
+
if ( empty( $values['weekdays'] ) ) {
|
587 |
+
$weekdays = '';
|
588 |
+
} elseif ( count( $values['weekdays'] ) == 7 ) {
|
589 |
+
$weekdays = $this->schedule_summaries['weekly_always'];
|
590 |
+
} else {
|
591 |
+
$arr = array();
|
592 |
+
foreach ( $values['weekdays'] as $weekday => $state ) {
|
593 |
+
$arr[] = $this->weekdays[$weekday];
|
594 |
+
}
|
595 |
+
$weekdays = join( ', ', $arr );
|
596 |
+
}
|
597 |
+
|
598 |
+
if ( ( empty( $values['weeks'] ) || count( $values['weeks'] ) == 5 ) && $this->disable_weekdays === false ) {
|
599 |
+
return $weekdays;
|
600 |
+
}
|
601 |
+
|
602 |
+
if ( empty( $values['weeks'] ) ) {
|
603 |
+
return $this->schedule_summaries['never'];
|
604 |
+
}
|
605 |
+
|
606 |
+
$arr = array();
|
607 |
+
foreach ( $values['weeks'] as $weeks => $state ) {
|
608 |
+
$arr[] = $this->weeks[$weeks];
|
609 |
+
}
|
610 |
+
$weeks = join( ', ', $arr );
|
611 |
+
|
612 |
+
if ( !empty( $weekdays ) ) {
|
613 |
+
return str_replace( array( '{days}', '{weeks}' ), array( $weekdays, $weeks ), $this->schedule_summaries['monthly_weekdays'] );
|
614 |
+
} else {
|
615 |
+
return str_replace( '{weeks}', ucfirst( $weeks ), $this->schedule_summaries['monthly_weeks'] );
|
616 |
+
}
|
617 |
+
|
618 |
+
}
|
619 |
+
|
620 |
+
/**
|
621 |
+
* Print the time phrase, a brief description of the time settings
|
622 |
+
* @since 2.0
|
623 |
+
*/
|
624 |
+
public function get_time_summary( $values = array() ) {
|
625 |
+
|
626 |
+
if ( empty( $values['time']['start'] ) && empty( $values['time']['end'] ) ) {
|
627 |
+
return $this->schedule_summaries['all_day'];
|
628 |
+
}
|
629 |
+
|
630 |
+
if ( empty( $values['time']['start'] ) ) {
|
631 |
+
return $this->schedule_summaries['before'] . ' ' . $values['time']['end'];
|
632 |
+
}
|
633 |
+
|
634 |
+
if ( empty( $values['time']['end'] ) ) {
|
635 |
+
return $this->schedule_summaries['after'] . ' ' . $values['time']['start'];
|
636 |
+
}
|
637 |
+
|
638 |
+
return $values['time']['start'] . $this->schedule_summaries['separator'] . $values['time']['end'];
|
639 |
+
|
640 |
+
}
|
641 |
+
|
642 |
+
/**
|
643 |
+
* Sanitize the array of text inputs for this setting
|
644 |
+
* @since 2.0
|
645 |
+
*/
|
646 |
+
public function sanitize_callback_wrapper( $values ) {
|
647 |
+
|
648 |
+
$output = array();
|
649 |
+
|
650 |
+
if ( !is_array( $values ) || !count( $values ) ) {
|
651 |
+
return $output;
|
652 |
+
}
|
653 |
+
|
654 |
+
foreach ( $values as $i => $rule ) {
|
655 |
+
|
656 |
+
if ( !empty( $rule['weekdays'] ) ) {
|
657 |
+
$output[$i]['weekdays'] = array();
|
658 |
+
foreach ( $rule['weekdays'] as $day => $flag ) {
|
659 |
+
if ( $flag !== '1' ||
|
660 |
+
( $day !== 'monday' && $day !== 'tuesday' && $day !== 'wednesday' && $day !== 'thursday' && $day !== 'friday' && $day !== 'saturday' && $day !== 'sunday' ) ) {
|
661 |
+
continue;
|
662 |
+
}
|
663 |
+
|
664 |
+
$output[$i]['weekdays'][$day] = $flag;
|
665 |
+
}
|
666 |
+
}
|
667 |
+
|
668 |
+
if ( !empty( $rule['weeks'] ) ) {
|
669 |
+
$output[$i]['weeks'] = array();
|
670 |
+
foreach ( $rule['weeks'] as $week => $flag ) {
|
671 |
+
if ( $flag !== '1' ||
|
672 |
+
( $week !== 'first' && $week !== 'second' && $week !== 'third' && $week !== 'fourth' && $week !== 'last' ) ) {
|
673 |
+
continue;
|
674 |
+
}
|
675 |
+
|
676 |
+
$output[$i]['weeks'][$week] = $flag;
|
677 |
+
}
|
678 |
+
}
|
679 |
+
|
680 |
+
if ( !empty( $rule['date'] ) ) {
|
681 |
+
$date = new DateTime( $rule['date'] );
|
682 |
+
if ( checkdate( $date->format( 'n' ), $date->format( 'j' ), $date->format( 'Y' ) ) ) {
|
683 |
+
$output[$i]['date'] = call_user_func( $this->sanitize_callback, $rule['date'] );
|
684 |
+
}
|
685 |
+
}
|
686 |
+
|
687 |
+
if ( !empty( $rule['time']['start'] ) ) {
|
688 |
+
$output[$i]['time']['start'] = call_user_func( $this->sanitize_callback, $rule['time']['start'] );
|
689 |
+
}
|
690 |
+
if ( !empty( $rule['time']['end'] ) ) {
|
691 |
+
$output[$i]['time']['end'] = call_user_func( $this->sanitize_callback, $rule['time']['end'] );
|
692 |
+
}
|
693 |
+
}
|
694 |
+
|
695 |
+
// Only return the first rule if multiple rules are disabled
|
696 |
+
if ( $this->disable_multiple && count( $output ) > 1 ) {
|
697 |
+
$output = array( array_shift( $output ) );
|
698 |
+
}
|
699 |
+
|
700 |
+
return $output;
|
701 |
+
}
|
702 |
+
|
703 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSetting.Select.class.php
CHANGED
@@ -1,61 +1,61 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Register, display and save a selection option with a drop-down menu.
|
5 |
-
*
|
6 |
-
* This setting accepts the following arguments in its constructor function.
|
7 |
-
*
|
8 |
-
* $args = array(
|
9 |
-
* 'id' => 'setting_id', // Unique id
|
10 |
-
* 'title' => 'My Setting', // Title or label for the setting
|
11 |
-
* 'description' => 'Description', // Help text description
|
12 |
-
* 'blank_option' => true, // Whether or not to show a blank option
|
13 |
-
* 'options' => array( // An array of key/value pairs which
|
14 |
-
* 'option1' => 'Option 1', // define the options.
|
15 |
-
* 'option2' => 'Option 2',
|
16 |
-
* ...
|
17 |
-
* );
|
18 |
-
* );
|
19 |
-
*
|
20 |
-
* @since 1.0
|
21 |
-
* @package Simple Admin Pages
|
22 |
-
*/
|
23 |
-
|
24 |
-
class
|
25 |
-
|
26 |
-
public $sanitize_callback = 'sanitize_text_field';
|
27 |
-
|
28 |
-
// Whether or not to display a blank option
|
29 |
-
public $blank_option = true;
|
30 |
-
|
31 |
-
// An array of options for this select field, accepted as a key/value pair.
|
32 |
-
public $options = array();
|
33 |
-
|
34 |
-
/**
|
35 |
-
* Display this setting
|
36 |
-
* @since 1.0
|
37 |
-
*/
|
38 |
-
public function display_setting() {
|
39 |
-
|
40 |
-
?>
|
41 |
-
|
42 |
-
<select name="<?php echo $this->get_input_name(); ?>" id="<?php echo $this->id; ?>" <?php echo ( $this->disabled ? 'disabled' : ''); ?>>
|
43 |
-
|
44 |
-
<?php if ( $this->blank_option === true ) : ?>
|
45 |
-
<option></option>
|
46 |
-
<?php endif; ?>
|
47 |
-
|
48 |
-
<?php foreach ( $this->options as $id => $title ) : ?>
|
49 |
-
<option value="<?php echo esc_attr( $id ); ?>"<?php if( $this->value == $id ) : ?> selected="selected"<?php endif; ?>><?php echo esc_html( $title ); ?></option>
|
50 |
-
<?php endforeach; ?>
|
51 |
-
|
52 |
-
</select>
|
53 |
-
<?php $this->display_disabled(); ?>
|
54 |
-
|
55 |
-
<?php
|
56 |
-
|
57 |
-
$this->display_description();
|
58 |
-
|
59 |
-
}
|
60 |
-
|
61 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save a selection option with a drop-down menu.
|
5 |
+
*
|
6 |
+
* This setting accepts the following arguments in its constructor function.
|
7 |
+
*
|
8 |
+
* $args = array(
|
9 |
+
* 'id' => 'setting_id', // Unique id
|
10 |
+
* 'title' => 'My Setting', // Title or label for the setting
|
11 |
+
* 'description' => 'Description', // Help text description
|
12 |
+
* 'blank_option' => true, // Whether or not to show a blank option
|
13 |
+
* 'options' => array( // An array of key/value pairs which
|
14 |
+
* 'option1' => 'Option 1', // define the options.
|
15 |
+
* 'option2' => 'Option 2',
|
16 |
+
* ...
|
17 |
+
* );
|
18 |
+
* );
|
19 |
+
*
|
20 |
+
* @since 1.0
|
21 |
+
* @package Simple Admin Pages
|
22 |
+
*/
|
23 |
+
|
24 |
+
class sapAdminPageSettingSelect_2_5_5 extends sapAdminPageSetting_2_5_5 {
|
25 |
+
|
26 |
+
public $sanitize_callback = 'sanitize_text_field';
|
27 |
+
|
28 |
+
// Whether or not to display a blank option
|
29 |
+
public $blank_option = true;
|
30 |
+
|
31 |
+
// An array of options for this select field, accepted as a key/value pair.
|
32 |
+
public $options = array();
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Display this setting
|
36 |
+
* @since 1.0
|
37 |
+
*/
|
38 |
+
public function display_setting() {
|
39 |
+
|
40 |
+
?>
|
41 |
+
|
42 |
+
<select name="<?php echo $this->get_input_name(); ?>" id="<?php echo $this->id; ?>" <?php echo ( $this->disabled ? 'disabled' : ''); ?>>
|
43 |
+
|
44 |
+
<?php if ( $this->blank_option === true ) : ?>
|
45 |
+
<option></option>
|
46 |
+
<?php endif; ?>
|
47 |
+
|
48 |
+
<?php foreach ( $this->options as $id => $title ) : ?>
|
49 |
+
<option value="<?php echo esc_attr( $id ); ?>"<?php if( $this->value == $id ) : ?> selected="selected"<?php endif; ?>><?php echo esc_html( $title ); ?></option>
|
50 |
+
<?php endforeach; ?>
|
51 |
+
|
52 |
+
</select>
|
53 |
+
<?php $this->display_disabled(); ?>
|
54 |
+
|
55 |
+
<?php
|
56 |
+
|
57 |
+
$this->display_description();
|
58 |
+
|
59 |
+
}
|
60 |
+
|
61 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSetting.SelectMenu.class.php
CHANGED
@@ -1,57 +1,57 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Register, display and save a selection with a drop-down list of any post type
|
5 |
-
*
|
6 |
-
* This setting accepts the following arguments in its constructor function.
|
7 |
-
*
|
8 |
-
* $args = array(
|
9 |
-
* 'id' => 'setting_id', // Unique id
|
10 |
-
* 'title' => 'My Setting', // Title or label for the setting
|
11 |
-
* 'description' => 'Description', // Help text description
|
12 |
-
* 'blank_option' => true, // Whether or not to show a blank option
|
13 |
-
* 'args' => array(); // Arguments to pass to WordPress's get_post() function
|
14 |
-
* );
|
15 |
-
*
|
16 |
-
* @since 1.0
|
17 |
-
* @package Simple Admin Pages
|
18 |
-
*/
|
19 |
-
|
20 |
-
class
|
21 |
-
|
22 |
-
public $sanitize_callback = 'intval';
|
23 |
-
|
24 |
-
// Whether or not to display a blank option
|
25 |
-
public $blank_option = true;
|
26 |
-
|
27 |
-
/**
|
28 |
-
* An array of arguments accepted by get_posts().
|
29 |
-
* See: http://codex.wordpress.org/Template_Tags/get_posts
|
30 |
-
*/
|
31 |
-
public $args = array();
|
32 |
-
|
33 |
-
/**
|
34 |
-
* Display this setting
|
35 |
-
* @since 1.0
|
36 |
-
*/
|
37 |
-
public function display_setting() {
|
38 |
-
|
39 |
-
$menus = get_terms( 'nav_menu', array( 'hide_empty' => true ) );
|
40 |
-
?>
|
41 |
-
<select name="<?php echo $this->get_input_name(); ?>" id="<?php echo $this->get_input_name(); ?>">
|
42 |
-
|
43 |
-
<?php if ( $this->blank_option === true ) : ?>
|
44 |
-
<option></option>
|
45 |
-
<?php endif; ?>
|
46 |
-
|
47 |
-
<?php foreach($menus as $menu){ ?>
|
48 |
-
<option value="<?php echo absint( $menu->term_id ); ?>" <?php selected( $this->value, $menu->term_id ); ?>><?php echo esc_attr( $menu->name ); ?></option>
|
49 |
-
<?php } ?>
|
50 |
-
|
51 |
-
</select>
|
52 |
-
<?php
|
53 |
-
$this->display_description();
|
54 |
-
|
55 |
-
}
|
56 |
-
|
57 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save a selection with a drop-down list of any post type
|
5 |
+
*
|
6 |
+
* This setting accepts the following arguments in its constructor function.
|
7 |
+
*
|
8 |
+
* $args = array(
|
9 |
+
* 'id' => 'setting_id', // Unique id
|
10 |
+
* 'title' => 'My Setting', // Title or label for the setting
|
11 |
+
* 'description' => 'Description', // Help text description
|
12 |
+
* 'blank_option' => true, // Whether or not to show a blank option
|
13 |
+
* 'args' => array(); // Arguments to pass to WordPress's get_post() function
|
14 |
+
* );
|
15 |
+
*
|
16 |
+
* @since 1.0
|
17 |
+
* @package Simple Admin Pages
|
18 |
+
*/
|
19 |
+
|
20 |
+
class sapAdminPageSettingSelectMenu_2_5_5 extends sapAdminPageSetting_2_5_5 {
|
21 |
+
|
22 |
+
public $sanitize_callback = 'intval';
|
23 |
+
|
24 |
+
// Whether or not to display a blank option
|
25 |
+
public $blank_option = true;
|
26 |
+
|
27 |
+
/**
|
28 |
+
* An array of arguments accepted by get_posts().
|
29 |
+
* See: http://codex.wordpress.org/Template_Tags/get_posts
|
30 |
+
*/
|
31 |
+
public $args = array();
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Display this setting
|
35 |
+
* @since 1.0
|
36 |
+
*/
|
37 |
+
public function display_setting() {
|
38 |
+
|
39 |
+
$menus = get_terms( 'nav_menu', array( 'hide_empty' => true ) );
|
40 |
+
?>
|
41 |
+
<select name="<?php echo $this->get_input_name(); ?>" id="<?php echo $this->get_input_name(); ?>">
|
42 |
+
|
43 |
+
<?php if ( $this->blank_option === true ) : ?>
|
44 |
+
<option></option>
|
45 |
+
<?php endif; ?>
|
46 |
+
|
47 |
+
<?php foreach($menus as $menu){ ?>
|
48 |
+
<option value="<?php echo absint( $menu->term_id ); ?>" <?php selected( $this->value, $menu->term_id ); ?>><?php echo esc_attr( $menu->name ); ?></option>
|
49 |
+
<?php } ?>
|
50 |
+
|
51 |
+
</select>
|
52 |
+
<?php
|
53 |
+
$this->display_description();
|
54 |
+
|
55 |
+
}
|
56 |
+
|
57 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSetting.SelectPost.class.php
CHANGED
@@ -1,65 +1,65 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Register, display and save a selection with a drop-down list of any post type
|
5 |
-
*
|
6 |
-
* This setting accepts the following arguments in its constructor function.
|
7 |
-
*
|
8 |
-
* $args = array(
|
9 |
-
* 'id' => 'setting_id', // Unique id
|
10 |
-
* 'title' => 'My Setting', // Title or label for the setting
|
11 |
-
* 'description' => 'Description', // Help text description
|
12 |
-
* 'blank_option' => true, // Whether or not to show a blank option
|
13 |
-
* 'args' => array(); // Arguments to pass to WordPress's get_post() function
|
14 |
-
* );
|
15 |
-
*
|
16 |
-
* @since 1.0
|
17 |
-
* @package Simple Admin Pages
|
18 |
-
*/
|
19 |
-
|
20 |
-
class
|
21 |
-
|
22 |
-
public $sanitize_callback = 'intval';
|
23 |
-
|
24 |
-
// Whether or not to display a blank option
|
25 |
-
public $blank_option = true;
|
26 |
-
|
27 |
-
/**
|
28 |
-
* An array of arguments accepted by get_posts().
|
29 |
-
* See: http://codex.wordpress.org/Template_Tags/get_posts
|
30 |
-
*/
|
31 |
-
public $args = array();
|
32 |
-
|
33 |
-
/**
|
34 |
-
* Display this setting
|
35 |
-
* @since 1.0
|
36 |
-
*/
|
37 |
-
public function display_setting() {
|
38 |
-
|
39 |
-
$posts = new WP_Query( $this->args );
|
40 |
-
|
41 |
-
?>
|
42 |
-
|
43 |
-
<select name="<?php echo $this->get_input_name(); ?>" id="<?php echo $this->get_input_name(); ?>" <?php echo ( $this->disabled ? 'disabled' : ''); ?>>
|
44 |
-
|
45 |
-
<?php if ( $this->blank_option === true ) : ?>
|
46 |
-
<option></option>
|
47 |
-
<?php endif; ?>
|
48 |
-
|
49 |
-
<?php while( $posts->have_posts() ) : $posts->next_post(); ?>
|
50 |
-
<option value="<?php echo absint( $posts->post->ID ); ?>" <?php selected( $this->value, $posts->post->ID ); ?>><?php echo esc_attr( $posts->post->post_title ); ?></option>
|
51 |
-
<?php endwhile; ?>
|
52 |
-
|
53 |
-
</select>
|
54 |
-
|
55 |
-
<?php $this->display_disabled(); ?>
|
56 |
-
|
57 |
-
<?php
|
58 |
-
|
59 |
-
wp_reset_postdata();
|
60 |
-
|
61 |
-
$this->display_description();
|
62 |
-
|
63 |
-
}
|
64 |
-
|
65 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save a selection with a drop-down list of any post type
|
5 |
+
*
|
6 |
+
* This setting accepts the following arguments in its constructor function.
|
7 |
+
*
|
8 |
+
* $args = array(
|
9 |
+
* 'id' => 'setting_id', // Unique id
|
10 |
+
* 'title' => 'My Setting', // Title or label for the setting
|
11 |
+
* 'description' => 'Description', // Help text description
|
12 |
+
* 'blank_option' => true, // Whether or not to show a blank option
|
13 |
+
* 'args' => array(); // Arguments to pass to WordPress's get_post() function
|
14 |
+
* );
|
15 |
+
*
|
16 |
+
* @since 1.0
|
17 |
+
* @package Simple Admin Pages
|
18 |
+
*/
|
19 |
+
|
20 |
+
class sapAdminPageSettingSelectPost_2_5_5 extends sapAdminPageSetting_2_5_5 {
|
21 |
+
|
22 |
+
public $sanitize_callback = 'intval';
|
23 |
+
|
24 |
+
// Whether or not to display a blank option
|
25 |
+
public $blank_option = true;
|
26 |
+
|
27 |
+
/**
|
28 |
+
* An array of arguments accepted by get_posts().
|
29 |
+
* See: http://codex.wordpress.org/Template_Tags/get_posts
|
30 |
+
*/
|
31 |
+
public $args = array();
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Display this setting
|
35 |
+
* @since 1.0
|
36 |
+
*/
|
37 |
+
public function display_setting() {
|
38 |
+
|
39 |
+
$posts = new WP_Query( $this->args );
|
40 |
+
|
41 |
+
?>
|
42 |
+
|
43 |
+
<select name="<?php echo $this->get_input_name(); ?>" id="<?php echo $this->get_input_name(); ?>" <?php echo ( $this->disabled ? 'disabled' : ''); ?>>
|
44 |
+
|
45 |
+
<?php if ( $this->blank_option === true ) : ?>
|
46 |
+
<option></option>
|
47 |
+
<?php endif; ?>
|
48 |
+
|
49 |
+
<?php while( $posts->have_posts() ) : $posts->next_post(); ?>
|
50 |
+
<option value="<?php echo absint( $posts->post->ID ); ?>" <?php selected( $this->value, $posts->post->ID ); ?>><?php echo esc_attr( $posts->post->post_title ); ?></option>
|
51 |
+
<?php endwhile; ?>
|
52 |
+
|
53 |
+
</select>
|
54 |
+
|
55 |
+
<?php $this->display_disabled(); ?>
|
56 |
+
|
57 |
+
<?php
|
58 |
+
|
59 |
+
wp_reset_postdata();
|
60 |
+
|
61 |
+
$this->display_description();
|
62 |
+
|
63 |
+
}
|
64 |
+
|
65 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSetting.SelectTaxonomy.class.php
CHANGED
@@ -1,68 +1,68 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Register, display and save a selection with a drop-down list of any taxonomy
|
5 |
-
*
|
6 |
-
* This setting accepts the following arguments in its constructor function.
|
7 |
-
*
|
8 |
-
* $args = array(
|
9 |
-
* 'id' => 'setting_id', // Unique id
|
10 |
-
* 'title' => 'My Setting', // Title or label for the setting
|
11 |
-
* 'description' => 'Description', // Help text description
|
12 |
-
* 'taxonomies' => array(); // Array of taxonomies to fetch (required)
|
13 |
-
* 'blank_option' => true, // Whether or not to show a blank option
|
14 |
-
* 'args' => array(); // Arguments to pass to WordPress's get_terms() function
|
15 |
-
* );
|
16 |
-
* type
|
17 |
-
*
|
18 |
-
* @since 1.0
|
19 |
-
* @package Simple Admin Pages
|
20 |
-
*/
|
21 |
-
|
22 |
-
class
|
23 |
-
|
24 |
-
public $sanitize_callback = 'intval';
|
25 |
-
|
26 |
-
// Whether or not to display a blank option
|
27 |
-
public $blank_option = true;
|
28 |
-
|
29 |
-
// Arrays of taxonomies to fetch (required)
|
30 |
-
public $taxonomies;
|
31 |
-
|
32 |
-
/**
|
33 |
-
* Array of options accepted by get_terms()
|
34 |
-
* See: http://codex.wordpress.org/Function_Reference/get_terms
|
35 |
-
*/
|
36 |
-
public $args = array();
|
37 |
-
|
38 |
-
/**
|
39 |
-
* Display this setting
|
40 |
-
* @since 1.0
|
41 |
-
*/
|
42 |
-
public function display_setting() {
|
43 |
-
|
44 |
-
$terms = get_terms( $this->taxonomies, $this->args );
|
45 |
-
|
46 |
-
?>
|
47 |
-
|
48 |
-
<select name="<?php echo $this->get_input_name(); ?>" id="<?php echo $this->get_input_name(); ?>" <?php echo ( $this->disabled ? 'disabled' : ''); ?>>
|
49 |
-
|
50 |
-
<?php if ( $this->blank_option === true ) : ?>
|
51 |
-
<option></option>
|
52 |
-
<?php endif; ?>
|
53 |
-
|
54 |
-
<?php foreach ( $terms as $term ) : ?>
|
55 |
-
<option value="<?php echo esc_attr( $term->term_id ); ?>"<?php if( $this->value == $term->term_id ) : ?> selected="selected"<?php endif; ?>><?php echo esc_html( $term->name ); ?></option>
|
56 |
-
<?php endforeach; ?>
|
57 |
-
|
58 |
-
</select>
|
59 |
-
|
60 |
-
<?php $this->display_disabled(); ?>
|
61 |
-
|
62 |
-
<?php
|
63 |
-
|
64 |
-
$this->display_description();
|
65 |
-
|
66 |
-
}
|
67 |
-
|
68 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save a selection with a drop-down list of any taxonomy
|
5 |
+
*
|
6 |
+
* This setting accepts the following arguments in its constructor function.
|
7 |
+
*
|
8 |
+
* $args = array(
|
9 |
+
* 'id' => 'setting_id', // Unique id
|
10 |
+
* 'title' => 'My Setting', // Title or label for the setting
|
11 |
+
* 'description' => 'Description', // Help text description
|
12 |
+
* 'taxonomies' => array(); // Array of taxonomies to fetch (required)
|
13 |
+
* 'blank_option' => true, // Whether or not to show a blank option
|
14 |
+
* 'args' => array(); // Arguments to pass to WordPress's get_terms() function
|
15 |
+
* );
|
16 |
+
* type
|
17 |
+
*
|
18 |
+
* @since 1.0
|
19 |
+
* @package Simple Admin Pages
|
20 |
+
*/
|
21 |
+
|
22 |
+
class sapAdminPageSettingSelectTaxonomy_2_5_5 extends sapAdminPageSetting_2_5_5 {
|
23 |
+
|
24 |
+
public $sanitize_callback = 'intval';
|
25 |
+
|
26 |
+
// Whether or not to display a blank option
|
27 |
+
public $blank_option = true;
|
28 |
+
|
29 |
+
// Arrays of taxonomies to fetch (required)
|
30 |
+
public $taxonomies;
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Array of options accepted by get_terms()
|
34 |
+
* See: http://codex.wordpress.org/Function_Reference/get_terms
|
35 |
+
*/
|
36 |
+
public $args = array();
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Display this setting
|
40 |
+
* @since 1.0
|
41 |
+
*/
|
42 |
+
public function display_setting() {
|
43 |
+
|
44 |
+
$terms = get_terms( $this->taxonomies, $this->args );
|
45 |
+
|
46 |
+
?>
|
47 |
+
|
48 |
+
<select name="<?php echo $this->get_input_name(); ?>" id="<?php echo $this->get_input_name(); ?>" <?php echo ( $this->disabled ? 'disabled' : ''); ?>>
|
49 |
+
|
50 |
+
<?php if ( $this->blank_option === true ) : ?>
|
51 |
+
<option></option>
|
52 |
+
<?php endif; ?>
|
53 |
+
|
54 |
+
<?php foreach ( $terms as $term ) : ?>
|
55 |
+
<option value="<?php echo esc_attr( $term->term_id ); ?>"<?php if( $this->value == $term->term_id ) : ?> selected="selected"<?php endif; ?>><?php echo esc_html( $term->name ); ?></option>
|
56 |
+
<?php endforeach; ?>
|
57 |
+
|
58 |
+
</select>
|
59 |
+
|
60 |
+
<?php $this->display_disabled(); ?>
|
61 |
+
|
62 |
+
<?php
|
63 |
+
|
64 |
+
$this->display_description();
|
65 |
+
|
66 |
+
}
|
67 |
+
|
68 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSetting.Text.class.php
CHANGED
@@ -1,37 +1,37 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Register, display and save a text field setting in the admin menu
|
5 |
-
*
|
6 |
-
* @since 1.0
|
7 |
-
* @package Simple Admin Pages
|
8 |
-
*/
|
9 |
-
|
10 |
-
class
|
11 |
-
|
12 |
-
public $sanitize_callback = 'sanitize_text_field';
|
13 |
-
|
14 |
-
/**
|
15 |
-
* Placeholder string for the input field
|
16 |
-
* @since 2.0
|
17 |
-
*/
|
18 |
-
public $placeholder = '';
|
19 |
-
|
20 |
-
/**
|
21 |
-
* Display this setting
|
22 |
-
* @since 1.0
|
23 |
-
*/
|
24 |
-
public function display_setting() {
|
25 |
-
?>
|
26 |
-
|
27 |
-
<input name="<?php echo $this->get_input_name(); ?>" type="text" id="<?php echo $this->get_input_name(); ?>" value="<?php echo $this->value; ?>"<?php echo !empty( $this->placeholder ) ? ' placeholder="' . esc_attr( $this->placeholder ) . '"' : ''; ?> class="regular-text" <?php echo ( $this->disabled ? 'disabled' : ''); ?> />
|
28 |
-
|
29 |
-
<?php $this->display_disabled(); ?>
|
30 |
-
|
31 |
-
<?php
|
32 |
-
|
33 |
-
$this->display_description();
|
34 |
-
|
35 |
-
}
|
36 |
-
|
37 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save a text field setting in the admin menu
|
5 |
+
*
|
6 |
+
* @since 1.0
|
7 |
+
* @package Simple Admin Pages
|
8 |
+
*/
|
9 |
+
|
10 |
+
class sapAdminPageSettingText_2_5_5 extends sapAdminPageSetting_2_5_5 {
|
11 |
+
|
12 |
+
public $sanitize_callback = 'sanitize_text_field';
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Placeholder string for the input field
|
16 |
+
* @since 2.0
|
17 |
+
*/
|
18 |
+
public $placeholder = '';
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Display this setting
|
22 |
+
* @since 1.0
|
23 |
+
*/
|
24 |
+
public function display_setting() {
|
25 |
+
?>
|
26 |
+
|
27 |
+
<input name="<?php echo $this->get_input_name(); ?>" type="text" id="<?php echo $this->get_input_name(); ?>" value="<?php echo $this->value; ?>"<?php echo !empty( $this->placeholder ) ? ' placeholder="' . esc_attr( $this->placeholder ) . '"' : ''; ?> class="regular-text<?php echo ( $this->small ? ' sap-small-text-input' : '' ); ?>" <?php echo ( $this->disabled ? 'disabled' : ''); ?> />
|
28 |
+
|
29 |
+
<?php $this->display_disabled(); ?>
|
30 |
+
|
31 |
+
<?php
|
32 |
+
|
33 |
+
$this->display_description();
|
34 |
+
|
35 |
+
}
|
36 |
+
|
37 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSetting.Textarea.class.php
CHANGED
@@ -1,58 +1,58 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Register, display and save a textarea field setting in the admin menu
|
5 |
-
*
|
6 |
-
* @since 1.0
|
7 |
-
* @package Simple Admin Pages
|
8 |
-
*
|
9 |
-
* @todo textareas should have an option to swap new lines for <br>s
|
10 |
-
*/
|
11 |
-
|
12 |
-
class
|
13 |
-
|
14 |
-
/*
|
15 |
-
* Size of this textarea
|
16 |
-
*
|
17 |
-
* This is put directly into a css class [size]-text,
|
18 |
-
* and setting this to 'large' will link into WordPress's existing textarea
|
19 |
-
* style for full-width textareas.
|
20 |
-
*/
|
21 |
-
public $size = 'small';
|
22 |
-
|
23 |
-
public $sanitize_callback = 'wp_kses_post';
|
24 |
-
|
25 |
-
/**
|
26 |
-
* Escape the value to display it safely HTML textarea fields
|
27 |
-
* @since 1.0
|
28 |
-
*/
|
29 |
-
public function esc_value( $val ) {
|
30 |
-
return esc_textarea( $val );
|
31 |
-
}
|
32 |
-
|
33 |
-
/**
|
34 |
-
* Set the size of this textarea field
|
35 |
-
* @since 1.0
|
36 |
-
*/
|
37 |
-
public function set_size( $size ) {
|
38 |
-
$this->size = esc_attr( $size );
|
39 |
-
}
|
40 |
-
|
41 |
-
/**
|
42 |
-
* Display this setting
|
43 |
-
* @since 1.0
|
44 |
-
*/
|
45 |
-
public function display_setting() {
|
46 |
-
?>
|
47 |
-
|
48 |
-
<textarea name="<?php echo $this->get_input_name(); ?>" id="<?php echo $this->get_input_name(); ?>" class="<?php echo $this->size; ?>-text"<?php echo !empty( $this->placeholder ) ? ' placeholder="' . esc_attr( $this->placeholder ) . '"' : ''; ?> <?php echo ( $this->disabled ? 'disabled' : ''); ?>><?php echo $this->value; ?></textarea>
|
49 |
-
|
50 |
-
<?php $this->display_disabled(); ?>
|
51 |
-
|
52 |
-
<?php
|
53 |
-
|
54 |
-
$this->display_description();
|
55 |
-
|
56 |
-
}
|
57 |
-
|
58 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save a textarea field setting in the admin menu
|
5 |
+
*
|
6 |
+
* @since 1.0
|
7 |
+
* @package Simple Admin Pages
|
8 |
+
*
|
9 |
+
* @todo textareas should have an option to swap new lines for <br>s
|
10 |
+
*/
|
11 |
+
|
12 |
+
class sapAdminPageSettingTextarea_2_5_5 extends sapAdminPageSetting_2_5_5 {
|
13 |
+
|
14 |
+
/*
|
15 |
+
* Size of this textarea
|
16 |
+
*
|
17 |
+
* This is put directly into a css class [size]-text,
|
18 |
+
* and setting this to 'large' will link into WordPress's existing textarea
|
19 |
+
* style for full-width textareas.
|
20 |
+
*/
|
21 |
+
public $size = 'small';
|
22 |
+
|
23 |
+
public $sanitize_callback = 'wp_kses_post';
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Escape the value to display it safely HTML textarea fields
|
27 |
+
* @since 1.0
|
28 |
+
*/
|
29 |
+
public function esc_value( $val ) {
|
30 |
+
return esc_textarea( $val );
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Set the size of this textarea field
|
35 |
+
* @since 1.0
|
36 |
+
*/
|
37 |
+
public function set_size( $size ) {
|
38 |
+
$this->size = esc_attr( $size );
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Display this setting
|
43 |
+
* @since 1.0
|
44 |
+
*/
|
45 |
+
public function display_setting() {
|
46 |
+
?>
|
47 |
+
|
48 |
+
<textarea name="<?php echo $this->get_input_name(); ?>" id="<?php echo $this->get_input_name(); ?>" class="<?php echo $this->size; ?>-text"<?php echo !empty( $this->placeholder ) ? ' placeholder="' . esc_attr( $this->placeholder ) . '"' : ''; ?> <?php echo ( $this->disabled ? 'disabled' : ''); ?>><?php echo $this->value; ?></textarea>
|
49 |
+
|
50 |
+
<?php $this->display_disabled(); ?>
|
51 |
+
|
52 |
+
<?php
|
53 |
+
|
54 |
+
$this->display_description();
|
55 |
+
|
56 |
+
}
|
57 |
+
|
58 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSetting.Toggle.class.php
CHANGED
@@ -1,52 +1,54 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Register, display and save an option with a single checkbox.
|
5 |
-
*
|
6 |
-
* This setting accepts the following arguments in its constructor function.
|
7 |
-
*
|
8 |
-
* $args = array(
|
9 |
-
* 'id' => 'setting_id', // Unique id
|
10 |
-
* 'title' => 'My Setting', // Title or label for the setting
|
11 |
-
* 'description' => 'Description', // Help text description
|
12 |
-
* 'label' => 'Label', // Checkbox label text
|
13 |
-
* );
|
14 |
-
* );
|
15 |
-
*
|
16 |
-
* @since 1.0
|
17 |
-
* @package Simple Admin Pages
|
18 |
-
*/
|
19 |
-
|
20 |
-
class
|
21 |
-
|
22 |
-
public $sanitize_callback = 'sanitize_text_field';
|
23 |
-
|
24 |
-
/**
|
25 |
-
* Display this setting
|
26 |
-
* @since 1.0
|
27 |
-
*/
|
28 |
-
public function display_setting() {
|
29 |
-
|
30 |
-
$input_name = $this->get_input_name();
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
}
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save an option with a single checkbox.
|
5 |
+
*
|
6 |
+
* This setting accepts the following arguments in its constructor function.
|
7 |
+
*
|
8 |
+
* $args = array(
|
9 |
+
* 'id' => 'setting_id', // Unique id
|
10 |
+
* 'title' => 'My Setting', // Title or label for the setting
|
11 |
+
* 'description' => 'Description', // Help text description
|
12 |
+
* 'label' => 'Label', // Checkbox label text
|
13 |
+
* );
|
14 |
+
* );
|
15 |
+
*
|
16 |
+
* @since 1.0
|
17 |
+
* @package Simple Admin Pages
|
18 |
+
*/
|
19 |
+
|
20 |
+
class sapAdminPageSettingToggle_2_5_5 extends sapAdminPageSetting_2_5_5 {
|
21 |
+
|
22 |
+
public $sanitize_callback = 'sanitize_text_field';
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Display this setting
|
26 |
+
* @since 1.0
|
27 |
+
*/
|
28 |
+
public function display_setting() {
|
29 |
+
|
30 |
+
$input_name = $this->get_input_name();
|
31 |
+
|
32 |
+
if ( ! isset( $this->value ) ) { $this->value = $this->get_default_setting(); }
|
33 |
+
|
34 |
+
?>
|
35 |
+
|
36 |
+
<fieldset>
|
37 |
+
<div class="sap-admin-hide-radios">
|
38 |
+
<input type="checkbox" name="<?php echo $input_name; ?>" id="<?php echo $input_name; ?>" value="1"<?php if( $this->value == '1' ) : ?> checked="checked"<?php endif; ?> <?php echo ( $this->disabled ? 'disabled' : ''); ?>>
|
39 |
+
<label for="<?php echo $input_name; ?>"><?php echo $this->title; ?></label>
|
40 |
+
</div>
|
41 |
+
<label class="sap-admin-switch">
|
42 |
+
<input type="checkbox" class="sap-admin-option-toggle" data-inputname="<?php echo $input_name; ?>" <?php if($this->value == '1') {echo "checked='checked'";} ?> <?php echo ( $this->disabled ? 'disabled' : ''); ?>>
|
43 |
+
<span class="sap-admin-switch-slider round"></span>
|
44 |
+
</label>
|
45 |
+
<?php $this->display_disabled(); ?>
|
46 |
+
</fieldset>
|
47 |
+
|
48 |
+
<?php
|
49 |
+
|
50 |
+
$this->display_description();
|
51 |
+
|
52 |
+
}
|
53 |
+
|
54 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSetting.WarningTip.class.php
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save a warning/tip in the admin menu
|
5 |
+
*
|
6 |
+
* @since 2.3.0
|
7 |
+
* @package Simple Admin Pages
|
8 |
+
*/
|
9 |
+
|
10 |
+
class sapAdminPageSettingWarningTip_2_5_5 extends sapAdminPageSetting_2_5_5 {
|
11 |
+
|
12 |
+
public $sanitize_callback = 'sanitize_text_field';
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Placeholder string for the input field
|
16 |
+
* @since 2.0
|
17 |
+
*/
|
18 |
+
public $placeholder = '';
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Display this setting
|
22 |
+
* @since 1.0
|
23 |
+
*/
|
24 |
+
public function display_setting() {
|
25 |
+
?>
|
26 |
+
|
27 |
+
<fieldset class="fdm-warning-tip">
|
28 |
+
<div class="fdm-shortcode-reminder">
|
29 |
+
<?php echo '<strong>' . $this->title . '</strong> ' . $this->placeholder; ?>
|
30 |
+
</div>
|
31 |
+
|
32 |
+
<?php $this->display_disabled(); ?>
|
33 |
+
</fieldset>
|
34 |
+
|
35 |
+
<?php
|
36 |
+
|
37 |
+
$this->display_description();
|
38 |
+
|
39 |
+
}
|
40 |
+
|
41 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSetting.class.php
CHANGED
@@ -1,344 +1,358 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Register, display and save a setting on a custom admin menu
|
5 |
-
*
|
6 |
-
* All settings accept the following arguments in their constructor functions.
|
7 |
-
*
|
8 |
-
* $args = array(
|
9 |
-
* 'id' => 'setting_id', // Unique id
|
10 |
-
* 'title' => 'My Setting', // Title or label for the setting
|
11 |
-
* 'description' => 'Description' // Help text description
|
12 |
-
* 'args' => array(); // Arguments to pass to WordPress's add_settings_field() function
|
13 |
-
* );
|
14 |
-
*
|
15 |
-
* @since 1.0
|
16 |
-
* @package Simple Admin Pages
|
17 |
-
*/
|
18 |
-
|
19 |
-
abstract class
|
20 |
-
|
21 |
-
// Page defaults
|
22 |
-
public $id; // used in form fields and database to track and store setting
|
23 |
-
public $title; // setting label
|
24 |
-
public $description; // optional description of the setting
|
25 |
-
public $value; // value of the setting, if a value exists
|
26 |
-
public $disabled = false; // whether a setting should be disabled
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
*
|
41 |
-
*
|
42 |
-
*
|
43 |
-
*
|
44 |
-
*
|
45 |
-
*
|
46 |
-
*
|
47 |
-
* array( '
|
48 |
-
* array( '
|
49 |
-
*
|
50 |
-
*
|
51 |
-
*
|
52 |
-
*
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
*
|
60 |
-
*
|
61 |
-
*
|
62 |
-
*
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
*
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
'
|
79 |
-
'
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
*
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
'
|
97 |
-
'
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
*
|
106 |
-
*
|
107 |
-
*
|
108 |
-
*
|
109 |
-
*
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
*
|
123 |
-
*
|
124 |
-
*
|
125 |
-
*
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
*
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
*
|
216 |
-
*
|
217 |
-
*
|
218 |
-
*
|
219 |
-
*
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
*
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
*
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save a setting on a custom admin menu
|
5 |
+
*
|
6 |
+
* All settings accept the following arguments in their constructor functions.
|
7 |
+
*
|
8 |
+
* $args = array(
|
9 |
+
* 'id' => 'setting_id', // Unique id
|
10 |
+
* 'title' => 'My Setting', // Title or label for the setting
|
11 |
+
* 'description' => 'Description' // Help text description
|
12 |
+
* 'args' => array(); // Arguments to pass to WordPress's add_settings_field() function
|
13 |
+
* );
|
14 |
+
*
|
15 |
+
* @since 1.0
|
16 |
+
* @package Simple Admin Pages
|
17 |
+
*/
|
18 |
+
|
19 |
+
abstract class sapAdminPageSetting_2_5_5 {
|
20 |
+
|
21 |
+
// Page defaults
|
22 |
+
public $id; // used in form fields and database to track and store setting
|
23 |
+
public $title; // setting label
|
24 |
+
public $description; // optional description of the setting
|
25 |
+
public $value; // value of the setting, if a value exists
|
26 |
+
public $disabled = false; // whether a setting should be disabled
|
27 |
+
public $small = false; // whether a text input should use the small styling
|
28 |
+
public $columns; // to be used for the number of columns for settings, like radio and checkbox, with lots of options/values
|
29 |
+
|
30 |
+
/**
|
31 |
+
* An array of arguments accepted by add_settings_field.
|
32 |
+
* See: https://codex.wordpress.org/Function_Reference/add_settings_field
|
33 |
+
*/
|
34 |
+
public $args = array();
|
35 |
+
|
36 |
+
// Array to store errors
|
37 |
+
public $errors = array();
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Position in section
|
41 |
+
*
|
42 |
+
* An array with two elements describing where this setting should
|
43 |
+
* be placed in its section. The first element describes a position
|
44 |
+
* and the second (optional) element identifies the id of an
|
45 |
+
* existing setting. Examples:
|
46 |
+
*
|
47 |
+
* array( 'bottom' ) // Default. bottom of section
|
48 |
+
* array( 'top' ) // top of section
|
49 |
+
* array( 'before', 'my-setting' ) // before a specific setting
|
50 |
+
* array( 'after', 'my-setting' ) // after a specific setting
|
51 |
+
*
|
52 |
+
* This setting is intended for use when you have to hook in after
|
53 |
+
* the settings page has been defined, such as adding a new setting
|
54 |
+
* from a third-party plugin.
|
55 |
+
*/
|
56 |
+
public $position;
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Function to use when sanitizing the data
|
60 |
+
*
|
61 |
+
* We set this to a strict sanitization function as a default, but a
|
62 |
+
* setting should override this in an extended class when needed.
|
63 |
+
*
|
64 |
+
* @since 1.0
|
65 |
+
*/
|
66 |
+
public $sanitize_callback = 'sanitize_text_field';
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Scripts that must be loaded for this component
|
70 |
+
* @since 2.0.a.4
|
71 |
+
*/
|
72 |
+
public $scripts = array(
|
73 |
+
/**
|
74 |
+
* Example
|
75 |
+
* See: http://codex.wordpress.org/Function_Reference/wp_enqueue_script
|
76 |
+
*
|
77 |
+
'handle' => array(
|
78 |
+
'path' => 'path/from/simple-admin-pages/file.js',
|
79 |
+
'dependencies' => array( 'jquery' ),
|
80 |
+
'version' => '3.5.0',
|
81 |
+
'footer' => true,
|
82 |
+
),
|
83 |
+
*/
|
84 |
+
);
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Styles that must be loaded for this component
|
88 |
+
* @since 2.0.a.4
|
89 |
+
*/
|
90 |
+
public $styles = array(
|
91 |
+
/**
|
92 |
+
* Example
|
93 |
+
* See: http://codex.wordpress.org/Function_Reference/wp_enqueue_style
|
94 |
+
*
|
95 |
+
'handle' => array(
|
96 |
+
'path' => 'path/from/simple-admin-pages/file.css',
|
97 |
+
'dependencies' => 'array( 'another-handle')', // or empty string
|
98 |
+
'version' => '3.5.0',
|
99 |
+
'media' => null,
|
100 |
+
),
|
101 |
+
*/
|
102 |
+
);
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Translateable strings required for this component
|
106 |
+
*
|
107 |
+
* Settings classes which require translateable strings should be
|
108 |
+
* defined with string id's pointing to null values. The actual
|
109 |
+
* strings should be passed with the $sap->add_setting() call.
|
110 |
+
*
|
111 |
+
* @since 2.0.a.8
|
112 |
+
*/
|
113 |
+
public $strings = array(
|
114 |
+
/**
|
115 |
+
* Example
|
116 |
+
*
|
117 |
+
'string_id' => null
|
118 |
+
*/
|
119 |
+
);
|
120 |
+
|
121 |
+
/**
|
122 |
+
* Initialize the setting
|
123 |
+
*
|
124 |
+
* By default, every setting takes an id, title and description in the $args
|
125 |
+
* array.
|
126 |
+
*
|
127 |
+
* @since 1.0
|
128 |
+
*/
|
129 |
+
public function __construct( $args ) {
|
130 |
+
|
131 |
+
// Parse the values passed
|
132 |
+
$this->parse_args( $args );
|
133 |
+
|
134 |
+
// Get any existing value
|
135 |
+
$this->set_value();
|
136 |
+
|
137 |
+
// Check for missing data
|
138 |
+
$this->missing_data();
|
139 |
+
}
|
140 |
+
|
141 |
+
/**
|
142 |
+
* Parse the arguments passed in the construction and assign them to
|
143 |
+
* internal variables. This function will be overwritten for most subclasses
|
144 |
+
* @since 1.0
|
145 |
+
*/
|
146 |
+
private function parse_args( $args ) {
|
147 |
+
foreach ( $args as $key => $val ) {
|
148 |
+
switch ( $key ) {
|
149 |
+
|
150 |
+
case 'id' :
|
151 |
+
$this->{$key} = esc_attr( $val );
|
152 |
+
|
153 |
+
default :
|
154 |
+
$this->{$key} = $val;
|
155 |
+
|
156 |
+
}
|
157 |
+
}
|
158 |
+
}
|
159 |
+
|
160 |
+
/**
|
161 |
+
* Check for missing data when setup.
|
162 |
+
* @since 1.0
|
163 |
+
*/
|
164 |
+
private function missing_data() {
|
165 |
+
|
166 |
+
$error_type = 'missing_data';
|
167 |
+
|
168 |
+
// Required fields
|
169 |
+
if ( empty( $this->id ) ) {
|
170 |
+
$this->set_error(
|
171 |
+
array(
|
172 |
+
'type' => $error_type,
|
173 |
+
'data' => 'id'
|
174 |
+
)
|
175 |
+
);
|
176 |
+
}
|
177 |
+
if ( empty( $this->title ) ) {
|
178 |
+
$this->set_error(
|
179 |
+
array(
|
180 |
+
'type' => $error_type,
|
181 |
+
'data' => 'title'
|
182 |
+
)
|
183 |
+
);
|
184 |
+
}
|
185 |
+
|
186 |
+
// Check for strings
|
187 |
+
foreach ( $this->strings as $id => $string ) {
|
188 |
+
|
189 |
+
if ( $string === null ) {
|
190 |
+
$this->set_error(
|
191 |
+
array(
|
192 |
+
'type' => $error_type,
|
193 |
+
'data' => 'string: ' . $id,
|
194 |
+
)
|
195 |
+
);
|
196 |
+
}
|
197 |
+
}
|
198 |
+
}
|
199 |
+
|
200 |
+
/**
|
201 |
+
* Set a value
|
202 |
+
* @since 2.0
|
203 |
+
*/
|
204 |
+
public function set_value( $val = null ) {
|
205 |
+
|
206 |
+
if ( $val === null ) {
|
207 |
+
$option_group_value = get_option( $this->page );
|
208 |
+
$val = isset( $option_group_value[ $this->id ] ) ? $option_group_value[ $this->id ] : '';
|
209 |
+
}
|
210 |
+
|
211 |
+
$this->value = $this->esc_value( $val );
|
212 |
+
}
|
213 |
+
|
214 |
+
/**
|
215 |
+
* Escape the value to display it in text fields and other input fields
|
216 |
+
*
|
217 |
+
* We use esc_attr() here so that the default is quite strict, but other
|
218 |
+
* setting types should override this function with the appropriate escape
|
219 |
+
* function. See: http://codex.wordpress.org/Data_Validation
|
220 |
+
*
|
221 |
+
* @since 1.0
|
222 |
+
*/
|
223 |
+
public function esc_value( $val ) {
|
224 |
+
|
225 |
+
if ( is_array( $val ) ) { return array_map( 'esc_attr', $val );}
|
226 |
+
|
227 |
+
return esc_attr( $val );
|
228 |
+
}
|
229 |
+
|
230 |
+
/**
|
231 |
+
* Wrapper for the sanitization callback function.
|
232 |
+
*
|
233 |
+
* This just reduces code duplication for child classes that need a custom
|
234 |
+
* callback function.
|
235 |
+
* @since 1.0
|
236 |
+
*/
|
237 |
+
public function sanitize_callback_wrapper( $value ) {
|
238 |
+
return call_user_func( $this->sanitize_callback, $value );
|
239 |
+
}
|
240 |
+
|
241 |
+
/**
|
242 |
+
* Display this setting
|
243 |
+
* @since 1.0
|
244 |
+
*/
|
245 |
+
abstract public function display_setting();
|
246 |
+
|
247 |
+
/**
|
248 |
+
* Display a description for this setting
|
249 |
+
* @since 1.0
|
250 |
+
*/
|
251 |
+
public function display_description() {
|
252 |
+
|
253 |
+
if ( !empty( $this->description ) ) {
|
254 |
+
|
255 |
+
?>
|
256 |
+
|
257 |
+
<p class="description<?php echo ( $this->disabled ? ' disabled' : ''); ?>"><?php echo $this->description; ?></p>
|
258 |
+
|
259 |
+
<?php
|
260 |
+
|
261 |
+
}
|
262 |
+
}
|
263 |
+
|
264 |
+
/**
|
265 |
+
* Display a disabled image for this section and possibly a link to upgrade
|
266 |
+
* @since 2.0
|
267 |
+
*/
|
268 |
+
public function display_disabled() {
|
269 |
+
|
270 |
+
if ( $this->disabled and isset($this->disabled_image) ) {
|
271 |
+
|
272 |
+
?>
|
273 |
+
|
274 |
+
<?php echo ( isset($this->purchase_link ) ? "<a href='" . $this->purchase_link . "'>" : '' ); ?>
|
275 |
+
<div class="disabled"><img src='<?php echo $this->disabled_image; ?>;' /></div>
|
276 |
+
<?php echo ( isset($this->purchase_link ) ? "</a>" : '' ); ?>
|
277 |
+
|
278 |
+
<?php
|
279 |
+
|
280 |
+
}
|
281 |
+
}
|
282 |
+
|
283 |
+
/**
|
284 |
+
* Generate an option input field name, using the grouped schema:
|
285 |
+
* "page[option_name]"
|
286 |
+
* @since 1.2
|
287 |
+
*/
|
288 |
+
public function get_input_name() {
|
289 |
+
return esc_attr( $this->page ) . '[' . esc_attr( $this->id ) . ']';
|
290 |
+
}
|
291 |
+
|
292 |
+
/**
|
293 |
+
* Get the default value for a setting if value is currently empty
|
294 |
+
*
|
295 |
+
* @since 2.4.1
|
296 |
+
*/
|
297 |
+
public function get_default_setting() {
|
298 |
+
return ! empty( $this->default ) ? $this->default : $this->value;
|
299 |
+
}
|
300 |
+
|
301 |
+
/**
|
302 |
+
* Add and register this setting
|
303 |
+
*
|
304 |
+
* @since 1.0
|
305 |
+
*/
|
306 |
+
public function add_settings_field( $section_id ) {
|
307 |
+
|
308 |
+
// If no sanitization callback exists, don't register the setting.
|
309 |
+
if ( !$this->has_sanitize_callback() ) {
|
310 |
+
return;
|
311 |
+
}
|
312 |
+
|
313 |
+
add_settings_field(
|
314 |
+
$this->id,
|
315 |
+
$this->title,
|
316 |
+
array( $this, 'display_setting' ),
|
317 |
+
$this->tab,
|
318 |
+
$section_id,
|
319 |
+
$this->args
|
320 |
+
);
|
321 |
+
|
322 |
+
}
|
323 |
+
|
324 |
+
/**
|
325 |
+
* Check if this field has a sanitization callback set
|
326 |
+
* @since 1.2
|
327 |
+
*/
|
328 |
+
public function has_sanitize_callback() {
|
329 |
+
if ( isset( $this->sanitize_callback ) && trim( $this->sanitize_callback ) ) {
|
330 |
+
return true;
|
331 |
+
}
|
332 |
+
|
333 |
+
return false;
|
334 |
+
}
|
335 |
+
|
336 |
+
/**
|
337 |
+
* Set an error
|
338 |
+
* @since 1.0
|
339 |
+
*/
|
340 |
+
public function set_error( $error ) {
|
341 |
+
$this->errors[] = array_merge(
|
342 |
+
$error,
|
343 |
+
array(
|
344 |
+
'class' => get_class( $this ),
|
345 |
+
'id' => $this->id,
|
346 |
+
'backtrace' => debug_backtrace()
|
347 |
+
)
|
348 |
+
);
|
349 |
+
}
|
350 |
+
|
351 |
+
/**
|
352 |
+
* Check if a setting has a position
|
353 |
+
* @since 2.0.a.9
|
354 |
+
*/
|
355 |
+
public function has_position() {
|
356 |
+
return !empty( $this->position ) && is_array( $this->position ) && !empty( $this->position[0] );
|
357 |
+
}
|
358 |
+
}
|
lib/simple-admin-pages/classes/Library.class.php
CHANGED
@@ -1,462 +1,480 @@
|
|
1 |
-
<?php
|
2 |
-
if ( !class_exists( '
|
3 |
-
/**
|
4 |
-
* This library class loads and provides access to the correct version of the
|
5 |
-
* Simple Admin Pages library.
|
6 |
-
*
|
7 |
-
* @since 1.0
|
8 |
-
* @package Simple Admin Pages
|
9 |
-
*/
|
10 |
-
class
|
11 |
-
|
12 |
-
// Version of the library
|
13 |
-
private $version = '2.
|
14 |
-
|
15 |
-
// A full URL to the library which is used to correctly link scripts and
|
16 |
-
// stylesheets.
|
17 |
-
public $lib_url;
|
18 |
-
|
19 |
-
// A relative path to any custom library extension classes. When
|
20 |
-
// instantiating a custom setting class, the library will search in its own
|
21 |
-
// directory of classes adn also the $lib_extension_path. This way,
|
22 |
-
// developers can add on their own classes without mixing them with the
|
23 |
-
// default classes.
|
24 |
-
public $lib_extension_path;
|
25 |
-
|
26 |
-
// An array of pages to add to the admin menus
|
27 |
-
public $pages = array();
|
28 |
-
|
29 |
-
// Collects errors for debugging
|
30 |
-
public $errors = array();
|
31 |
-
|
32 |
-
// Set debug mode to true to stop and print errors found while processing.
|
33 |
-
// @note This is not related to your PHP error reporting setting, but is an
|
34 |
-
// internal error tracking mechanism to catch missing or malformed data
|
35 |
-
// during development.
|
36 |
-
public $debug_mode = false;
|
37 |
-
|
38 |
-
/**
|
39 |
-
* Initialize the library with the appropriate version
|
40 |
-
* @since 1.0
|
41 |
-
*/
|
42 |
-
public function __construct( $args ) {
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
'
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
case '
|
129 |
-
require_once('AdminPageSetting.
|
130 |
-
return $this->get_versioned_classname( '
|
131 |
-
|
132 |
-
case '
|
133 |
-
require_once('AdminPageSetting.
|
134 |
-
return $this->get_versioned_classname( '
|
135 |
-
|
136 |
-
case '
|
137 |
-
require_once('AdminPageSetting.
|
138 |
-
return $this->get_versioned_classname( '
|
139 |
-
|
140 |
-
case '
|
141 |
-
require_once('AdminPageSetting.
|
142 |
-
return $this->get_versioned_classname( '
|
143 |
-
|
144 |
-
case '
|
145 |
-
require_once('AdminPageSetting.
|
146 |
-
return $this->get_versioned_classname( '
|
147 |
-
|
148 |
-
case '
|
149 |
-
require_once('AdminPageSetting.
|
150 |
-
return $this->get_versioned_classname( '
|
151 |
-
|
152 |
-
case '
|
153 |
-
require_once('AdminPageSetting.
|
154 |
-
return $this->get_versioned_classname( '
|
155 |
-
|
156 |
-
case '
|
157 |
-
require_once('AdminPageSetting.
|
158 |
-
return $this->get_versioned_classname( '
|
159 |
-
|
160 |
-
case '
|
161 |
-
require_once('AdminPageSetting.
|
162 |
-
return $this->get_versioned_classname( '
|
163 |
-
|
164 |
-
case '
|
165 |
-
require_once('AdminPageSetting.
|
166 |
-
return $this->get_versioned_classname( '
|
167 |
-
|
168 |
-
case '
|
169 |
-
require_once('AdminPageSetting.
|
170 |
-
return $this->get_versioned_classname( '
|
171 |
-
|
172 |
-
case '
|
173 |
-
require_once('AdminPageSetting.
|
174 |
-
return $this->get_versioned_classname( '
|
175 |
-
|
176 |
-
case '
|
177 |
-
require_once('AdminPageSetting.
|
178 |
-
return $this->get_versioned_classname( '
|
179 |
-
|
180 |
-
case '
|
181 |
-
require_once('AdminPageSetting.
|
182 |
-
return $this->get_versioned_classname( '
|
183 |
-
|
184 |
-
case '
|
185 |
-
require_once('AdminPageSetting.
|
186 |
-
return $this->get_versioned_classname( '
|
187 |
-
|
188 |
-
case '
|
189 |
-
require_once('AdminPageSetting.
|
190 |
-
return $this->get_versioned_classname( '
|
191 |
-
|
192 |
-
case '
|
193 |
-
require_once('AdminPageSetting.
|
194 |
-
return $this->get_versioned_classname( '
|
195 |
-
|
196 |
-
case '
|
197 |
-
require_once('AdminPageSetting.
|
198 |
-
return $this->get_versioned_classname( '
|
199 |
-
|
200 |
-
case '
|
201 |
-
require_once('AdminPageSetting.
|
202 |
-
return $this->get_versioned_classname( '
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
//
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
$args['
|
280 |
-
}
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
if
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
}
|
462 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
if ( !class_exists( 'sapLibrary_2_5_5' ) ) {
|
3 |
+
/**
|
4 |
+
* This library class loads and provides access to the correct version of the
|
5 |
+
* Simple Admin Pages library.
|
6 |
+
*
|
7 |
+
* @since 1.0
|
8 |
+
* @package Simple Admin Pages
|
9 |
+
*/
|
10 |
+
class sapLibrary_2_5_5 {
|
11 |
+
|
12 |
+
// Version of the library
|
13 |
+
private $version = '2.5.5';
|
14 |
+
|
15 |
+
// A full URL to the library which is used to correctly link scripts and
|
16 |
+
// stylesheets.
|
17 |
+
public $lib_url;
|
18 |
+
|
19 |
+
// A relative path to any custom library extension classes. When
|
20 |
+
// instantiating a custom setting class, the library will search in its own
|
21 |
+
// directory of classes adn also the $lib_extension_path. This way,
|
22 |
+
// developers can add on their own classes without mixing them with the
|
23 |
+
// default classes.
|
24 |
+
public $lib_extension_path;
|
25 |
+
|
26 |
+
// An array of pages to add to the admin menus
|
27 |
+
public $pages = array();
|
28 |
+
|
29 |
+
// Collects errors for debugging
|
30 |
+
public $errors = array();
|
31 |
+
|
32 |
+
// Set debug mode to true to stop and print errors found while processing.
|
33 |
+
// @note This is not related to your PHP error reporting setting, but is an
|
34 |
+
// internal error tracking mechanism to catch missing or malformed data
|
35 |
+
// during development.
|
36 |
+
public $debug_mode = false;
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Initialize the library with the appropriate version
|
40 |
+
* @since 1.0
|
41 |
+
*/
|
42 |
+
public function __construct( $args ) {
|
43 |
+
|
44 |
+
if ( ! defined( 'SAP_VERSION' ) ) {
|
45 |
+
define( 'SAP_VERSION', '2.5.5' );
|
46 |
+
}
|
47 |
+
|
48 |
+
// If no URL path to the library is passed, we won't be able to add the
|
49 |
+
// CSS and Javascript to the admin panel
|
50 |
+
if ( !isset( $args['lib_url'] ) ) {
|
51 |
+
$this->set_error(
|
52 |
+
array(
|
53 |
+
'id' => 'no-lib-url',
|
54 |
+
'desc' => 'No URL path to the library provided when the libary was created.',
|
55 |
+
'var' => $args,
|
56 |
+
'line' => __LINE__,
|
57 |
+
'function' => __FUNCTION__
|
58 |
+
)
|
59 |
+
);
|
60 |
+
} else {
|
61 |
+
$this->lib_url = $args['lib_url'];
|
62 |
+
}
|
63 |
+
|
64 |
+
// Set a library extension path if passed
|
65 |
+
if ( isset( $args['lib_extension_path'] ) ) {
|
66 |
+
$this->lib_extension_path = $args['lib_extension_path'];
|
67 |
+
}
|
68 |
+
|
69 |
+
// Set the debug mode
|
70 |
+
if ( isset( $args['debug_mode'] ) && $args['debug_mode'] === true ) {
|
71 |
+
$this->debug_mode = true;
|
72 |
+
}
|
73 |
+
|
74 |
+
// Ensure we have access to WordPress' plugin functions
|
75 |
+
require_once(ABSPATH . '/wp-admin/includes/plugin.php');
|
76 |
+
|
77 |
+
// Load the required classes
|
78 |
+
$this->load_class( 'sapAdminPage', 'AdminPage.class.php' );
|
79 |
+
$this->load_class( 'sapAdminPageSection', 'AdminPageSection.class.php' );
|
80 |
+
$this->load_class( 'sapAdminPageSetting', 'AdminPageSetting.class.php' );
|
81 |
+
|
82 |
+
// Add the scripts to the admin pages
|
83 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
|
84 |
+
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Load the class if it isn't already loaded
|
89 |
+
* @since 1.0
|
90 |
+
*/
|
91 |
+
private function load_class( $class, $file ) {
|
92 |
+
|
93 |
+
if ( !class_exists( $this->get_versioned_classname( $class ) ) ) {
|
94 |
+
require_once( $file );
|
95 |
+
}
|
96 |
+
}
|
97 |
+
|
98 |
+
/**
|
99 |
+
* Return the version suffix for a class
|
100 |
+
* @since 1.0
|
101 |
+
*/
|
102 |
+
private function get_versioned_classname( $class ) {
|
103 |
+
return $class . '_' . str_replace( '.', '_', $this->version );
|
104 |
+
}
|
105 |
+
|
106 |
+
/**
|
107 |
+
* Check if the correct version of a class exists
|
108 |
+
* @since 1.0
|
109 |
+
*/
|
110 |
+
private function versioned_class_exists( $class ) {
|
111 |
+
if ( class_exists( $this->get_versioned_classname( $class ) ) ) {
|
112 |
+
return true;
|
113 |
+
} else {
|
114 |
+
return false;
|
115 |
+
}
|
116 |
+
}
|
117 |
+
|
118 |
+
/**
|
119 |
+
* Load the files for a specific setting type and return the class
|
120 |
+
* to use when instantiating the setting object.
|
121 |
+
*
|
122 |
+
* @since 1.0
|
123 |
+
*/
|
124 |
+
public function get_setting_classname( $type ) {
|
125 |
+
|
126 |
+
switch( $type ) {
|
127 |
+
|
128 |
+
case 'text' :
|
129 |
+
require_once('AdminPageSetting.Text.class.php');
|
130 |
+
return $this->get_versioned_classname( 'sapAdminPageSettingText' );
|
131 |
+
|
132 |
+
case 'number' :
|
133 |
+
require_once('AdminPageSetting.Number.class.php');
|
134 |
+
return $this->get_versioned_classname( 'sapAdminPageSettingNumber' );
|
135 |
+
|
136 |
+
case 'colorpicker' :
|
137 |
+
require_once('AdminPageSetting.ColorPicker.class.php');
|
138 |
+
return $this->get_versioned_classname( 'sapAdminPageSettingColorPicker' );
|
139 |
+
|
140 |
+
case 'textarea' :
|
141 |
+
require_once('AdminPageSetting.Textarea.class.php');
|
142 |
+
return $this->get_versioned_classname( 'sapAdminPageSettingTextarea' );
|
143 |
+
|
144 |
+
case 'select' :
|
145 |
+
require_once('AdminPageSetting.Select.class.php');
|
146 |
+
return $this->get_versioned_classname( 'sapAdminPageSettingSelect' );
|
147 |
+
|
148 |
+
case 'toggle' :
|
149 |
+
require_once('AdminPageSetting.Toggle.class.php');
|
150 |
+
return $this->get_versioned_classname( 'sapAdminPageSettingToggle' );
|
151 |
+
|
152 |
+
case 'image' :
|
153 |
+
require_once('AdminPageSetting.Image.class.php');
|
154 |
+
return $this->get_versioned_classname( 'sapAdminPageSettingImage' );
|
155 |
+
|
156 |
+
case 'radio' :
|
157 |
+
require_once('AdminPageSetting.Radio.class.php');
|
158 |
+
return $this->get_versioned_classname( 'sapAdminPageSettingRadio' );
|
159 |
+
|
160 |
+
case 'checkbox' :
|
161 |
+
require_once('AdminPageSetting.Checkbox.class.php');
|
162 |
+
return $this->get_versioned_classname( 'sapAdminPageSettingCheckbox' );
|
163 |
+
|
164 |
+
case 'infinite_table' :
|
165 |
+
require_once('AdminPageSetting.InfiniteTable.class.php');
|
166 |
+
return $this->get_versioned_classname( 'sapAdminPageSettingInfiniteTable' );
|
167 |
+
|
168 |
+
case 'count' :
|
169 |
+
require_once('AdminPageSetting.Count.class.php');
|
170 |
+
return $this->get_versioned_classname( 'sapAdminPageSettingCount' );
|
171 |
+
|
172 |
+
case 'post' :
|
173 |
+
require_once('AdminPageSetting.SelectPost.class.php');
|
174 |
+
return $this->get_versioned_classname( 'sapAdminPageSettingSelectPost' );
|
175 |
+
|
176 |
+
case 'menu' :
|
177 |
+
require_once('AdminPageSetting.SelectMenu.class.php');
|
178 |
+
return $this->get_versioned_classname( 'sapAdminPageSettingSelectMenu' );
|
179 |
+
|
180 |
+
case 'taxonomy' :
|
181 |
+
require_once('AdminPageSetting.SelectTaxonomy.class.php');
|
182 |
+
return $this->get_versioned_classname( 'sapAdminPageSettingSelectTaxonomy' );
|
183 |
+
|
184 |
+
case 'editor' :
|
185 |
+
require_once('AdminPageSetting.Editor.class.php');
|
186 |
+
return $this->get_versioned_classname( 'sapAdminPageSettingEditor' );
|
187 |
+
|
188 |
+
case 'html' :
|
189 |
+
require_once('AdminPageSetting.HTML.class.php');
|
190 |
+
return $this->get_versioned_classname( 'sapAdminPageSettingHTML' );
|
191 |
+
|
192 |
+
case 'scheduler' :
|
193 |
+
require_once('AdminPageSetting.Scheduler.class.php');
|
194 |
+
return $this->get_versioned_classname( 'sapAdminPageSettingScheduler' );
|
195 |
+
|
196 |
+
case 'opening-hours' :
|
197 |
+
require_once('AdminPageSetting.OpeningHours.class.php');
|
198 |
+
return $this->get_versioned_classname( 'sapAdminPageSettingOpeningHours' );
|
199 |
+
|
200 |
+
case 'address' :
|
201 |
+
require_once('AdminPageSetting.Address.class.php');
|
202 |
+
return $this->get_versioned_classname( 'sapAdminPageSettingAddress' );
|
203 |
+
|
204 |
+
case 'file-upload' :
|
205 |
+
require_once('AdminPageSetting.FileUpload.class.php');
|
206 |
+
return $this->get_versioned_classname( 'sapAdminPageSettingFileUpload' );
|
207 |
+
|
208 |
+
case 'ordering-table' :
|
209 |
+
require_once('AdminPageSetting.Ordering.class.php');
|
210 |
+
return $this->get_versioned_classname( 'sapAdminPageSettingOrdering' );
|
211 |
+
|
212 |
+
case 'mcapikey' :
|
213 |
+
require_once('AdminPageSetting.McApiKey.class.php');
|
214 |
+
return $this->get_versioned_classname( 'mcfrtbAdminPageSettingMcApiKey' );
|
215 |
+
|
216 |
+
case 'mclistmerge' :
|
217 |
+
require_once('AdminPageSetting.McListMerge.class.php');
|
218 |
+
return $this->get_versioned_classname( 'mcfrtbAdminPageSettingMcListMerge' );
|
219 |
+
|
220 |
+
default :
|
221 |
+
|
222 |
+
// Exit early if a custom type is declared without providing the
|
223 |
+
// details to find the type class
|
224 |
+
if ( ( !is_array( $type ) || !isset( $type['id'] ) ) ||
|
225 |
+
( !isset( $type['class'] ) || !isset( $type['filename'] ) ) ) {
|
226 |
+
return false;
|
227 |
+
}
|
228 |
+
|
229 |
+
// Load the custom type file. Look for the file in the library's
|
230 |
+
// folder or check the custom library extension path.
|
231 |
+
if ( file_exists( $type['filename'] ) ) {
|
232 |
+
require_once( $type['filename'] );
|
233 |
+
} elseif ( isset( $this->lib_extension_path ) && file_exists( $this->lib_extension_path . $type['filename'] ) ) {
|
234 |
+
require_once( $this->lib_extension_path . '/' . $type['filename'] );
|
235 |
+
if ( !class_exists( $type['class'] ) ) {
|
236 |
+
return false;
|
237 |
+
} else {
|
238 |
+
return $type['class'];
|
239 |
+
}
|
240 |
+
} else {
|
241 |
+
return false;
|
242 |
+
}
|
243 |
+
|
244 |
+
|
245 |
+
// Check that we've loaded the appropriate class
|
246 |
+
if ( !$this->versioned_class_exists( $type['class'] ) ) {
|
247 |
+
return false;
|
248 |
+
}
|
249 |
+
|
250 |
+
return $this->get_versioned_classname( $type['class'] );
|
251 |
+
|
252 |
+
}
|
253 |
+
|
254 |
+
}
|
255 |
+
|
256 |
+
/**
|
257 |
+
* Initialize a page
|
258 |
+
* @since 1.0
|
259 |
+
*
|
260 |
+
* @todo perform some checks on args to ensure a valid page can be constructed
|
261 |
+
*/
|
262 |
+
public function add_page( $menu_location, $args = array() ) {
|
263 |
+
|
264 |
+
// default should be 'options'
|
265 |
+
$class = $this->get_versioned_classname( 'sapAdminPage' );
|
266 |
+
|
267 |
+
if ( $menu_location == 'themes' ) {
|
268 |
+
$this->load_class( 'sapAdminPageThemes', 'AdminPage.Themes.class.php' );
|
269 |
+
$class = $this->get_versioned_classname( 'sapAdminPageThemes' );
|
270 |
+
} elseif ( $menu_location == 'menu' ) {
|
271 |
+
$this->load_class( 'sapAdminPageMenu', 'AdminPage.Menu.class.php' );
|
272 |
+
$class = $this->get_versioned_classname( 'sapAdminPageMenu' );
|
273 |
+
} elseif ( $menu_location == 'submenu' ) {
|
274 |
+
$this->load_class( 'sapAdminPageSubmenu', 'AdminPage.Submenu.class.php' );
|
275 |
+
$class = $this->get_versioned_classname( 'sapAdminPageSubmenu' );
|
276 |
+
}
|
277 |
+
|
278 |
+
if ( class_exists( $class ) ) {
|
279 |
+
$this->pages[ $args['id'] ] = new $class( $args );
|
280 |
+
}
|
281 |
+
|
282 |
+
}
|
283 |
+
|
284 |
+
/**
|
285 |
+
* Initialize a section
|
286 |
+
* @since 1.0
|
287 |
+
*
|
288 |
+
* @todo perform some checks on args to ensure a valid section can be constructed
|
289 |
+
*/
|
290 |
+
public function add_section( $page, $args = array() ) {
|
291 |
+
|
292 |
+
if ( !isset( $this->pages[ $page ] ) ) {
|
293 |
+
return false;
|
294 |
+
} else {
|
295 |
+
$args['page'] = $page;
|
296 |
+
}
|
297 |
+
|
298 |
+
$class = $this->get_versioned_classname( 'sapAdminPageSection' );
|
299 |
+
if ( class_exists( $class ) ) {
|
300 |
+
$this->pages[ $page ]->add_section( new $class( $args ) );
|
301 |
+
}
|
302 |
+
|
303 |
+
}
|
304 |
+
|
305 |
+
/**
|
306 |
+
* Initialize a setting
|
307 |
+
*
|
308 |
+
* The type variable can be a string pointing to a pre-defined setting type,
|
309 |
+
* or an array consisting of an id, classname and filename which references
|
310 |
+
* a custom setting type. @sa get_setting_classname()
|
311 |
+
*
|
312 |
+
* @since 1.0
|
313 |
+
*/
|
314 |
+
public function add_setting( $page, $section, $type, $args = array() ) {
|
315 |
+
|
316 |
+
if ( !isset( $this->pages[ $page ] ) || !isset( $this->pages[ $page ]->sections[ $section ] ) ) {
|
317 |
+
return false;
|
318 |
+
} else {
|
319 |
+
$args['page'] = $page;
|
320 |
+
$args['tab'] = $this->pages[$page]->sections[ $section ]->get_page_slug();
|
321 |
+
}
|
322 |
+
|
323 |
+
$class = $this->get_setting_classname( $type );
|
324 |
+
if ( $class && class_exists( $class ) ) {
|
325 |
+
$this->pages[ $page ]->sections[ $section ]->add_setting( new $class( $args ) );
|
326 |
+
}
|
327 |
+
|
328 |
+
}
|
329 |
+
|
330 |
+
/**
|
331 |
+
* Register all page, section and settings content with WordPress
|
332 |
+
* @since 1.0
|
333 |
+
*/
|
334 |
+
public function add_admin_menus() {
|
335 |
+
|
336 |
+
// If the library is run in debug mode, check for any errors in content,
|
337 |
+
// print any errors found, and don't add the menu if there are errors
|
338 |
+
if ( $this->debug_mode ) {
|
339 |
+
$errors = array();
|
340 |
+
foreach ( $this->pages as $page ) {
|
341 |
+
foreach ( $page->sections as $section ) {
|
342 |
+
if ( count( $section->errors ) ) {
|
343 |
+
array_merge( $errors, $section->errors );
|
344 |
+
}
|
345 |
+
foreach ( $section->settings as $setting ) {
|
346 |
+
if ( count( $setting->errors ) ) {
|
347 |
+
$errors = array_merge( $errors, $setting->errors );
|
348 |
+
}
|
349 |
+
}
|
350 |
+
}
|
351 |
+
}
|
352 |
+
if ( count( $errors ) ) {
|
353 |
+
print_r( $errors );
|
354 |
+
return;
|
355 |
+
}
|
356 |
+
}
|
357 |
+
|
358 |
+
// Add the action hooks
|
359 |
+
foreach ( $this->pages as $id => $page ) {
|
360 |
+
add_action( 'admin_menu', array( $page, 'add_admin_menu' ) );
|
361 |
+
add_action( 'admin_init', array( $page, 'register_admin_menu' ) );
|
362 |
+
}
|
363 |
+
}
|
364 |
+
|
365 |
+
/**
|
366 |
+
* Port data from a previous version to the current version
|
367 |
+
*
|
368 |
+
* Version 2.0 of the library changes the structure of how it stores data.
|
369 |
+
* In order to upgrade the version of the library your plugin/theme is
|
370 |
+
* using, this method must be called after all of your pages and settings
|
371 |
+
* have been declared but before you run add_admin_menus().
|
372 |
+
*
|
373 |
+
* This method will loop over all of the settings data and port any existing
|
374 |
+
* data to the new data structure. It will check if the data has been ported
|
375 |
+
* first before it updates the data. The old data will be removed to keep
|
376 |
+
* the database clean.
|
377 |
+
*
|
378 |
+
* @var int target_version Which data version the library should update to.
|
379 |
+
* @since 2.0
|
380 |
+
*/
|
381 |
+
public function port_data( $target_version, $delete_old_data = true ) {
|
382 |
+
|
383 |
+
// Port data to the storage structure in version 2
|
384 |
+
if ( $target_version == 2 ) {
|
385 |
+
|
386 |
+
foreach ( $this->pages as $page_id => $page ) {
|
387 |
+
|
388 |
+
// Skip if this page has already been ported
|
389 |
+
if ( get_option( $page_id ) !== false ) {
|
390 |
+
continue;
|
391 |
+
}
|
392 |
+
|
393 |
+
$page_values = array();
|
394 |
+
|
395 |
+
foreach ( $page->sections as $section ) {
|
396 |
+
foreach ( $section->settings as $setting ) {
|
397 |
+
$value = get_option( $setting->id );
|
398 |
+
if ( $value !== false ) {
|
399 |
+
$page_values[ $setting->id ] = $value;
|
400 |
+
}
|
401 |
+
}
|
402 |
+
}
|
403 |
+
|
404 |
+
if ( count( $page_values ) ) {
|
405 |
+
$result = add_option( $page_id, $page_values );
|
406 |
+
|
407 |
+
// Delete old data if the flag is set and the new data was
|
408 |
+
// saved successfully.
|
409 |
+
if ( $delete_old_data === true && $result !== false ) {
|
410 |
+
foreach( $page_values as $setting_id => $setting_value ) {
|
411 |
+
delete_option( $setting_id );
|
412 |
+
}
|
413 |
+
}
|
414 |
+
|
415 |
+
// Reset settings values
|
416 |
+
if ( $result === true ) {
|
417 |
+
|
418 |
+
foreach ( $page->sections as $section ) {
|
419 |
+
foreach ( $section->settings as $setting ) {
|
420 |
+
$setting->set_value();
|
421 |
+
}
|
422 |
+
}
|
423 |
+
|
424 |
+
}
|
425 |
+
}
|
426 |
+
}
|
427 |
+
}
|
428 |
+
|
429 |
+
}
|
430 |
+
|
431 |
+
/**
|
432 |
+
* Enqueue the stylesheets and scripts
|
433 |
+
* @since 1.0
|
434 |
+
*/
|
435 |
+
public function enqueue_scripts() {
|
436 |
+
|
437 |
+
$screen = get_current_screen();
|
438 |
+
|
439 |
+
foreach ( $this->pages as $page_id => $page ) {
|
440 |
+
|
441 |
+
// Only enqueue assets for the current page
|
442 |
+
if ( strpos( $screen->base, $page_id ) !== false ) {
|
443 |
+
wp_enqueue_style( 'sap-admin-style-' . $this->version, $this->lib_url . 'css/admin.css', array(), $this->version );
|
444 |
+
wp_enqueue_style( 'sap-spectrum-css-' . $this->version, $this->lib_url . 'css/spectrum.css', array(), $this->version );
|
445 |
+
wp_enqueue_style( 'sap-admin-settings-css-' . $this->version, $this->lib_url . 'css/admin-settings.css', array(), $this->version );
|
446 |
+
wp_enqueue_script( 'sap-spectrum-js-' . $this->version, $this->lib_url . 'js/spectrum.js', array( 'jquery' ), $this->version );
|
447 |
+
wp_enqueue_script( 'sap-admin-settings-js-' . $this->version, $this->lib_url . 'js/admin-settings.js', array( 'jquery', 'sap-spectrum-js-' . $this->version ), $this->version );
|
448 |
+
wp_enqueue_media();
|
449 |
+
|
450 |
+
foreach ( $page->sections as $section ) {
|
451 |
+
foreach ( $section->settings as $setting ) {
|
452 |
+
foreach( $setting->scripts as $handle => $script ) {
|
453 |
+
wp_enqueue_script( $handle, $this->lib_url . $script['path'], $script['dependencies'], $script['version'], $script['footer'] );
|
454 |
+
}
|
455 |
+
foreach( $setting->styles as $handle => $style ) {
|
456 |
+
wp_enqueue_style( $handle, $this->lib_url . $style['path'], $style['dependencies'], $style['version'], $style['media'] );
|
457 |
+
}
|
458 |
+
}
|
459 |
+
}
|
460 |
+
}
|
461 |
+
}
|
462 |
+
}
|
463 |
+
|
464 |
+
/**
|
465 |
+
* Set an error
|
466 |
+
* @since 1.0
|
467 |
+
*/
|
468 |
+
public function set_error( $error ) {
|
469 |
+
$this->errors[] = array_merge(
|
470 |
+
$error,
|
471 |
+
array(
|
472 |
+
'class' => get_class( $this ),
|
473 |
+
'id' => $this->id,
|
474 |
+
'backtrace' => debug_backtrace()
|
475 |
+
)
|
476 |
+
);
|
477 |
+
}
|
478 |
+
|
479 |
+
}
|
480 |
+
} // endif;
|
lib/simple-admin-pages/css/admin-settings.css
ADDED
@@ -0,0 +1,658 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/************************/
|
2 |
+
/***** OPTIONS PAGE *****/
|
3 |
+
/************************/
|
4 |
+
|
5 |
+
.wrap.sap-settings-page h1 {
|
6 |
+
width: 100%;
|
7 |
+
}
|
8 |
+
|
9 |
+
/* Side Menu */
|
10 |
+
.wrap.sap-settings-page h2.nav-tab-wrapper {
|
11 |
+
position: relative;
|
12 |
+
float: left;
|
13 |
+
border: none;
|
14 |
+
width: 180px;
|
15 |
+
box-shadow: -1px 1px 8px #ccc;
|
16 |
+
overflow: hidden;
|
17 |
+
padding-top: 0;
|
18 |
+
margin-top: 20px;
|
19 |
+
}
|
20 |
+
.wrap.sap-settings-page h2.nav-tab-wrapper a {
|
21 |
+
clear: both;
|
22 |
+
display: block;
|
23 |
+
position: relative;
|
24 |
+
float: left;
|
25 |
+
background-color: #e2e2e2;
|
26 |
+
border: none;
|
27 |
+
border-bottom: 1px solid #f1f1f1;
|
28 |
+
color: #555;
|
29 |
+
font-weight: bold;
|
30 |
+
padding-left: 20px;
|
31 |
+
width: calc(100% - 20px);
|
32 |
+
text-align: left;
|
33 |
+
margin: 0;
|
34 |
+
height: 34px;
|
35 |
+
line-height: 34px;
|
36 |
+
font-size: 13px;
|
37 |
+
}
|
38 |
+
.wrap.sap-settings-page h2.nav-tab-wrapper a:last-of-type {
|
39 |
+
border-bottom: none;
|
40 |
+
}
|
41 |
+
.wrap.sap-settings-page h2.nav-tab-wrapper a.nav-tab-active {
|
42 |
+
box-shadow: none;
|
43 |
+
background-color: #fff !important;
|
44 |
+
color: #1b335f;
|
45 |
+
border-left: 4px solid #1b335f;
|
46 |
+
}
|
47 |
+
.wrap.sap-settings-page h2.nav-tab-wrapper a:hover {
|
48 |
+
color: #1b335f;
|
49 |
+
background-color: rgba(199,199,199, 0.5);
|
50 |
+
box-shadow: none;
|
51 |
+
border-left: 4px solid #1b335f;
|
52 |
+
}
|
53 |
+
.wrap.sap-settings-page h2.nav-tab-wrapper a.nav-tab-active:hover {
|
54 |
+
color: #1b335f;
|
55 |
+
background-color: #fff;
|
56 |
+
border-left: 4px solid #1b335f;
|
57 |
+
}
|
58 |
+
|
59 |
+
/* Right side */
|
60 |
+
.wrap.sap-settings-page form {
|
61 |
+
display: block;
|
62 |
+
position: relative;
|
63 |
+
float: left;
|
64 |
+
width: calc(100% - 276px);
|
65 |
+
padding: 32px 48px;
|
66 |
+
z-index: 999;
|
67 |
+
background:#fff;
|
68 |
+
margin: 20px 0 0 !important;
|
69 |
+
min-height: 400px;
|
70 |
+
border: none;
|
71 |
+
}
|
72 |
+
|
73 |
+
.wrap.sap-settings-page form h2:first-of-type {
|
74 |
+
font-size: 18px;
|
75 |
+
color: #1b335f;
|
76 |
+
margin: 0 0 32px !important;
|
77 |
+
}
|
78 |
+
|
79 |
+
.wrap.sap-settings-page form h2:nth-of-type(1n+2) {
|
80 |
+
position: relative;
|
81 |
+
float: left;
|
82 |
+
background: #1b335f;
|
83 |
+
margin: 8px 0 0;
|
84 |
+
font-size: 15px;
|
85 |
+
font-weight: bold;
|
86 |
+
color: #fff;
|
87 |
+
padding: 12px 2%;
|
88 |
+
width: 96%;
|
89 |
+
text-transform: uppercase;
|
90 |
+
z-index: 2;
|
91 |
+
}
|
92 |
+
.wrap.sap-settings-page form .form-table {
|
93 |
+
width: 100%;
|
94 |
+
box-sizing: border-box;
|
95 |
+
margin: 0 auto 16px;
|
96 |
+
box-shadow: 0 1px 12px #ddd;
|
97 |
+
display: block;
|
98 |
+
padding: 11px 5%;
|
99 |
+
}
|
100 |
+
.wrap.sap-settings-page form .form-table tr {
|
101 |
+
width: 20%;
|
102 |
+
}
|
103 |
+
.wrap.sap-settings-page form .form-table td {
|
104 |
+
width: 80%;
|
105 |
+
}
|
106 |
+
|
107 |
+
.wrap.sap-settings-page form p.description {
|
108 |
+
display: none;
|
109 |
+
}
|
110 |
+
.wrap.sap-settings-page form .form-table p.description {
|
111 |
+
display: block;
|
112 |
+
}
|
113 |
+
.wrap.sap-settings-page form .form-table p.description.disabled {
|
114 |
+
color: #b5b5b5;
|
115 |
+
}
|
116 |
+
|
117 |
+
|
118 |
+
.ulb-premium-options-table-overlay + table th,
|
119 |
+
.ulb-premium-options-table-overlay + table td {
|
120 |
+
color: #b5b5b5;
|
121 |
+
}
|
122 |
+
|
123 |
+
|
124 |
+
|
125 |
+
/************************
|
126 |
+
TOGGLE SWITCHES
|
127 |
+
************************/
|
128 |
+
.sap-admin-hide-radios {
|
129 |
+
display: none;
|
130 |
+
}
|
131 |
+
|
132 |
+
/* The switch - the box around the slider */
|
133 |
+
.sap-admin-switch {
|
134 |
+
position: relative;
|
135 |
+
display: inline-block;
|
136 |
+
width: 40px;
|
137 |
+
height: 22px;
|
138 |
+
}
|
139 |
+
|
140 |
+
/* Hide default HTML checkbox */
|
141 |
+
.sap-admin-switch input {
|
142 |
+
display: none;
|
143 |
+
}
|
144 |
+
|
145 |
+
/* The slider */
|
146 |
+
.sap-admin-switch-slider {
|
147 |
+
position: absolute;
|
148 |
+
cursor: pointer;
|
149 |
+
top: 0;
|
150 |
+
left: 0;
|
151 |
+
right: 0;
|
152 |
+
bottom: 0;
|
153 |
+
background-color: #ccc;
|
154 |
+
-webkit-transition: .4s;
|
155 |
+
transition: .4s;
|
156 |
+
}
|
157 |
+
|
158 |
+
.sap-admin-switch-slider:before {
|
159 |
+
position: absolute;
|
160 |
+
content: "";
|
161 |
+
height: 14px;
|
162 |
+
width: 14px;
|
163 |
+
left: 4px;
|
164 |
+
bottom: 4px;
|
165 |
+
background-color: white;
|
166 |
+
-webkit-transition: .4s;
|
167 |
+
transition: .4s;
|
168 |
+
}
|
169 |
+
|
170 |
+
input:checked + .sap-admin-switch-slider {
|
171 |
+
background-color: #1b335f;
|
172 |
+
}
|
173 |
+
|
174 |
+
input:focus + .sap-admin-switch-slider {
|
175 |
+
box-shadow: 0 0 1px #1b335f;
|
176 |
+
}
|
177 |
+
|
178 |
+
input:checked + .sap-admin-switch-slider:before {
|
179 |
+
-webkit-transform: translateX(18px);
|
180 |
+
-ms-transform: translateX(18px);
|
181 |
+
transform: translateX(18px);
|
182 |
+
}
|
183 |
+
|
184 |
+
/* Rounded sliders */
|
185 |
+
.sap-admin-switch-slider.round {
|
186 |
+
border-radius: 34px;
|
187 |
+
}
|
188 |
+
|
189 |
+
.sap-admin-switch-slider.round:before {
|
190 |
+
border-radius: 50%;
|
191 |
+
}
|
192 |
+
|
193 |
+
|
194 |
+
/* RADIO BUTTON AND CHECKBOX */
|
195 |
+
.wrap.sap-settings-page form .form-table fieldset label {
|
196 |
+
line-height: 1.4em;
|
197 |
+
margin: .25em 0 .5em;
|
198 |
+
display: inline-block;
|
199 |
+
font-size: 14px;
|
200 |
+
}
|
201 |
+
|
202 |
+
.sap-admin-input-container input, .sap-admin-input-container input:disabled {
|
203 |
+
position: absolute;
|
204 |
+
opacity: 0;
|
205 |
+
}
|
206 |
+
.sap-admin-radio-button {
|
207 |
+
position: relative;
|
208 |
+
float: left;
|
209 |
+
height: 14px;
|
210 |
+
width: 14px;
|
211 |
+
top: 1px;
|
212 |
+
margin-right: 12px;
|
213 |
+
background-color: #fff;
|
214 |
+
border: 2px solid #aaa;
|
215 |
+
border-radius: 50%;
|
216 |
+
}
|
217 |
+
.sap-admin-input-container:hover input ~ .sap-admin-radio-button {
|
218 |
+
background-color: #E6FFFB;
|
219 |
+
border-color: #1b335f;
|
220 |
+
}
|
221 |
+
.sap-admin-input-container input:checked ~ .sap-admin-radio-button {
|
222 |
+
border-color: #1b335f;
|
223 |
+
background-color: #fff;
|
224 |
+
}
|
225 |
+
.sap-admin-radio-button:after {
|
226 |
+
content: "";
|
227 |
+
position: absolute;
|
228 |
+
display: none;
|
229 |
+
}
|
230 |
+
.sap-admin-input-container input:checked ~ .sap-admin-radio-button:after {
|
231 |
+
display: block;
|
232 |
+
}
|
233 |
+
.sap-admin-input-container .sap-admin-radio-button:after {
|
234 |
+
top: 3px;
|
235 |
+
left: 3px;
|
236 |
+
width: 8px;
|
237 |
+
height: 8px;
|
238 |
+
border-radius: 50%;
|
239 |
+
background: #1b335f;
|
240 |
+
}
|
241 |
+
|
242 |
+
.sap-admin-checkbox {
|
243 |
+
position: relative;
|
244 |
+
float: left;
|
245 |
+
height: 14px;
|
246 |
+
width: 14px;
|
247 |
+
top: 1px;
|
248 |
+
margin-right: 12px;
|
249 |
+
background-color: #fff;
|
250 |
+
border: 2px solid #aaa;
|
251 |
+
}
|
252 |
+
.sap-admin-input-container:hover input ~ .sap-admin-checkbox {
|
253 |
+
background-color: #E6FFFB;
|
254 |
+
border-color: #1b335f;
|
255 |
+
}
|
256 |
+
.sap-admin-input-container input:checked ~ .sap-admin-checkbox {
|
257 |
+
border-color: #1b335f;
|
258 |
+
background-color: #fff;
|
259 |
+
}
|
260 |
+
.sap-admin-checkbox:after {
|
261 |
+
content: "";
|
262 |
+
position: absolute;
|
263 |
+
display: none;
|
264 |
+
}
|
265 |
+
.sap-admin-input-container input:checked ~ .sap-admin-checkbox:after {
|
266 |
+
display: block;
|
267 |
+
}
|
268 |
+
.sap-admin-input-container .sap-admin-checkbox:after {
|
269 |
+
left: 4px;
|
270 |
+
top: 1px;
|
271 |
+
width: 4px;
|
272 |
+
height: 8px;
|
273 |
+
border: solid #1b335f;
|
274 |
+
border-width: 0 2px 2px 0;
|
275 |
+
-webkit-transform: rotate(45deg);
|
276 |
+
-ms-transform: rotate(45deg);
|
277 |
+
transform: rotate(45deg);
|
278 |
+
}
|
279 |
+
|
280 |
+
/* Textbox and Text Area and Select boxes */
|
281 |
+
.wrap.sap-settings-page form .form-table input[type=text],
|
282 |
+
.wrap.sap-settings-page form .form-table input[type=search],
|
283 |
+
.wrap.sap-settings-page form .form-table input[type=tel],
|
284 |
+
.wrap.sap-settings-page form .form-table input[type=url],
|
285 |
+
.wrap.sap-settings-page form .form-table input[type=week],
|
286 |
+
.wrap.sap-settings-page form .form-table input[type=password],
|
287 |
+
.wrap.sap-settings-page form .form-table input[type=color],
|
288 |
+
.wrap.sap-settings-page form .form-table input[type=email],
|
289 |
+
.wrap.sap-settings-page form .form-table input[type=number],
|
290 |
+
.wrap.sap-settings-page form .form-table textarea,
|
291 |
+
.wrap.sap-settings-page form .form-table select {
|
292 |
+
border: 2px solid #ccc;
|
293 |
+
border-radius: 5px;
|
294 |
+
box-shadow: none;
|
295 |
+
}
|
296 |
+
.wrap.sap-settings-page form .form-table select,
|
297 |
+
.wrap.sap-settings-page form .form-table textarea {
|
298 |
+
width: auto !important;
|
299 |
+
min-width: 50%;
|
300 |
+
max-width: 100% !important;
|
301 |
+
}
|
302 |
+
#sap-dining-block-length_count,
|
303 |
+
#sap-dining-block-length_unit {
|
304 |
+
min-width: 0;
|
305 |
+
}
|
306 |
+
|
307 |
+
.wrap.sap-settings-page form .form-table textarea {
|
308 |
+
min-width: 300px;
|
309 |
+
min-height: 200px;
|
310 |
+
}
|
311 |
+
.wrap.sap-settings-page form .form-table .wp-editor-wrap textarea {
|
312 |
+
border: none;
|
313 |
+
border-radius: 0;
|
314 |
+
min-width: 0;
|
315 |
+
max-width: 100%;
|
316 |
+
min-height: 0;
|
317 |
+
}
|
318 |
+
|
319 |
+
|
320 |
+
/*SMALL TEXT INPUTS*/
|
321 |
+
.sap-small-text-input {
|
322 |
+
border-radius: 2px !important;
|
323 |
+
width: 100px;
|
324 |
+
}
|
325 |
+
|
326 |
+
|
327 |
+
/*SETTINGS COLUMNS*/
|
328 |
+
.sap-admin-input-container {
|
329 |
+
position: relative;
|
330 |
+
float: left;
|
331 |
+
width: 100%;
|
332 |
+
}
|
333 |
+
.sap-setting-columns-2 .sap-admin-input-container {
|
334 |
+
width: 50%;
|
335 |
+
}
|
336 |
+
.sap-setting-columns-3 .sap-admin-input-container {
|
337 |
+
width: 33.33333%;
|
338 |
+
width: calc(100% / 3);
|
339 |
+
}
|
340 |
+
.sap-setting-columns-8 .sap-admin-input-container {
|
341 |
+
width: 12.5%;
|
342 |
+
}
|
343 |
+
|
344 |
+
|
345 |
+
/*COLOUR PICKERS*/
|
346 |
+
fieldset.sap-colorpicker {
|
347 |
+
position: relative;
|
348 |
+
}
|
349 |
+
.sap-colorpicker input.sap-spectrum {
|
350 |
+
position: absolute;
|
351 |
+
right: 0;
|
352 |
+
bottom: 0;
|
353 |
+
border: none !important;
|
354 |
+
margin: 0 !important;
|
355 |
+
width: calc(100% - 42px);
|
356 |
+
border-radius: 0;
|
357 |
+
background: transparent !important;
|
358 |
+
color: #888 !important;
|
359 |
+
padding: 0;
|
360 |
+
font-size: 12px;
|
361 |
+
}
|
362 |
+
.sap-colorpicker .sp-replacer {
|
363 |
+
padding: 0 !important;
|
364 |
+
margin-right: 8px !important;
|
365 |
+
border-radius: 2px;
|
366 |
+
}
|
367 |
+
.sap-colorpicker .sp-preview {
|
368 |
+
width: 32px !important;
|
369 |
+
height: 32px !important;
|
370 |
+
margin: 0 !important;
|
371 |
+
border: none !important
|
372 |
+
}
|
373 |
+
.sap-colorpicker .sp-dd {
|
374 |
+
display: none !important;
|
375 |
+
}
|
376 |
+
|
377 |
+
|
378 |
+
/**************************
|
379 |
+
OTHER OPTION PAGE STYLING
|
380 |
+
**************************/
|
381 |
+
|
382 |
+
/*LOCK PREMIUM CONTENT*/
|
383 |
+
.sap-premium-options-table {
|
384 |
+
position: relative;
|
385 |
+
min-height: 240px;
|
386 |
+
}
|
387 |
+
.sap-premium-options-table.Yes {
|
388 |
+
min-height: 0;
|
389 |
+
}
|
390 |
+
.sap-premium-options-table-overlay {
|
391 |
+
position: absolute;
|
392 |
+
top: 0;
|
393 |
+
left: 0;
|
394 |
+
width: 1000px;
|
395 |
+
height: 500px;
|
396 |
+
background: rgba(0,0,0,.45);
|
397 |
+
z-index: 2;
|
398 |
+
}
|
399 |
+
.section-disabled {
|
400 |
+
position: absolute;
|
401 |
+
margin-top: 16px;
|
402 |
+
width: 200px;
|
403 |
+
height: 200px;
|
404 |
+
padding: 16px;
|
405 |
+
background: #fff;
|
406 |
+
left: calc(50% - 116px);
|
407 |
+
}
|
408 |
+
.section-disabled img {
|
409 |
+
position: relative;
|
410 |
+
float: left;
|
411 |
+
width: 40px;
|
412 |
+
height: auto;
|
413 |
+
margin: 16px 80px 24px;
|
414 |
+
}
|
415 |
+
.section-disabled p {
|
416 |
+
margin: 16px 0;
|
417 |
+
text-align: center;
|
418 |
+
color: #888;
|
419 |
+
}
|
420 |
+
.section-disabled .sap-dashboard-get-premium-widget-button {
|
421 |
+
clear: both;
|
422 |
+
position: relative;
|
423 |
+
float: left;
|
424 |
+
width: calc(100% - 20px);
|
425 |
+
margin: 16px 8px;
|
426 |
+
border: 2px solid #1b335f;
|
427 |
+
background-color: #1b335f;
|
428 |
+
color: #fff;
|
429 |
+
padding: 6px 0;
|
430 |
+
font-size: 12px;
|
431 |
+
text-decoration: none;
|
432 |
+
text-align: center;
|
433 |
+
font-weight: bold;
|
434 |
+
border-radius: 2px;
|
435 |
+
}
|
436 |
+
.section-disabled .sap-dashboard-get-premium-widget-button:hover {
|
437 |
+
background-color: #6f2fc9;
|
438 |
+
border-color: #6f2fc9;
|
439 |
+
color: #fff;
|
440 |
+
}
|
441 |
+
|
442 |
+
|
443 |
+
/*************
|
444 |
+
RESPONSIVE
|
445 |
+
*************/
|
446 |
+
@media screen and (max-width: 1099px) {
|
447 |
+
.wrap.sap-settings-page h2.nav-tab-wrapper {
|
448 |
+
clear: both;
|
449 |
+
width: 100%;
|
450 |
+
}
|
451 |
+
.wrap.sap-settings-page form {
|
452 |
+
clear: both;
|
453 |
+
width: calc(100% - 96px);
|
454 |
+
}
|
455 |
+
}
|
456 |
+
@media screen and (max-width: 782px) {
|
457 |
+
.wrap.sap-settings-page h2.nav-tab-wrapper {
|
458 |
+
margin: 0 0 20px 0;
|
459 |
+
}
|
460 |
+
.wrap.sap-settings-page form {
|
461 |
+
width: calc(100% - 96px);
|
462 |
+
}
|
463 |
+
.sap-admin-section-heading {
|
464 |
+
text-align: center;
|
465 |
+
}
|
466 |
+
.wrap.sap-settings-page form .form-table {
|
467 |
+
box-shadow: none;
|
468 |
+
}
|
469 |
+
.wrap.sap-settings-page form .form-table,
|
470 |
+
.wrap.sap-settings-page form .form-table tbody,
|
471 |
+
.wrap.sap-settings-page form .form-table tr,
|
472 |
+
.wrap.sap-settings-page form .form-table th,
|
473 |
+
.wrap.sap-settings-page form .form-table td {
|
474 |
+
clear: both;
|
475 |
+
float: left;
|
476 |
+
width: 100%;
|
477 |
+
}
|
478 |
+
.wrap.sap-settings-page form .form-table {
|
479 |
+
padding: 11px 0;
|
480 |
+
}
|
481 |
+
.wrap.sap-settings-page form .form-table th {
|
482 |
+
padding: 20px 5% 8px;
|
483 |
+
width: 90%;
|
484 |
+
height: auto;
|
485 |
+
margin: 0;
|
486 |
+
background-image: url(../images/options-asset-info.png);
|
487 |
+
background-position: 95% 20px;
|
488 |
+
background-size: 18px 18px;
|
489 |
+
background-repeat: no-repeat;
|
490 |
+
cursor: pointer;
|
491 |
+
}
|
492 |
+
.wrap.sap-settings-page form .form-table td {
|
493 |
+
padding-top: 4px;
|
494 |
+
}
|
495 |
+
.wrap.sap-settings-page form .form-table td fieldset {
|
496 |
+
position: relative;
|
497 |
+
}
|
498 |
+
.wrap.sap-settings-page form .form-table td label {
|
499 |
+
position: relative;
|
500 |
+
clear: both;
|
501 |
+
float: left;
|
502 |
+
width: 90%;
|
503 |
+
margin-left: 5% !important;
|
504 |
+
}
|
505 |
+
.wrap.sap-settings-page form .form-table td label.sap-admin-switch {
|
506 |
+
position: absolute;
|
507 |
+
width: 40px;
|
508 |
+
top: -35px;
|
509 |
+
right: 5%;
|
510 |
+
}
|
511 |
+
.wrap.sap-settings-page form .form-table td p {
|
512 |
+
display: none;
|
513 |
+
position: relative;
|
514 |
+
float: left;
|
515 |
+
width: 90%;
|
516 |
+
padding: 10px 5% 24px;
|
517 |
+
background: #f3f3f3;
|
518 |
+
border-bottom: 1px solid #ccc;
|
519 |
+
font-size: 13px;
|
520 |
+
}
|
521 |
+
.wrap.sap-settings-page form .form-table td input[type="button"] {
|
522 |
+
display: block;
|
523 |
+
margin: 10px auto 4px;
|
524 |
+
}
|
525 |
+
.sap-admin-input-container {
|
526 |
+
width: calc(100% - 16px);
|
527 |
+
padding-left: 16px;
|
528 |
+
}
|
529 |
+
}
|
530 |
+
|
531 |
+
|
532 |
+
|
533 |
+
/******************************************************************
|
534 |
+
NEW STYLING FOR ADD/DELETE AREAS LIKE CUSTOM FIELDS
|
535 |
+
******************************************************************/
|
536 |
+
.sap-infinite-table table th {
|
537 |
+
padding: 0 10px !important;
|
538 |
+
}
|
539 |
+
.sap-new-admin-add-button {
|
540 |
+
position: relative;
|
541 |
+
float: left;
|
542 |
+
width: calc(100% - 4px);
|
543 |
+
border: 2px dotted #bbb;
|
544 |
+
text-align: center;
|
545 |
+
padding: 12px 0;
|
546 |
+
color: #999;
|
547 |
+
}
|
548 |
+
.sap-new-admin-add-button:hover {
|
549 |
+
background: #f5f5f5;
|
550 |
+
color: #888;
|
551 |
+
}
|
552 |
+
.sap-infinite-table-row-delete,
|
553 |
+
.sap-custom-fields-add-nutrional-information {
|
554 |
+
cursor: pointer;
|
555 |
+
color: #1b335f;
|
556 |
+
}
|
557 |
+
.sap-infinite-table-row-delete:hover,
|
558 |
+
.sap-custom-fields-add-nutrional-information:hover {
|
559 |
+
color: #4366A6;
|
560 |
+
}
|
561 |
+
|
562 |
+
|
563 |
+
/******************************************************************
|
564 |
+
EXPORT BUTTON
|
565 |
+
******************************************************************/
|
566 |
+
.sap-export-button {
|
567 |
+
position: relative;
|
568 |
+
width: 150px;
|
569 |
+
padding: 0 !important;
|
570 |
+
}
|
571 |
+
.sap-export-button span {
|
572 |
+
position: absolute;
|
573 |
+
top: 4px;
|
574 |
+
left: 8px;
|
575 |
+
}
|
576 |
+
input[name="sap_export"] {
|
577 |
+
position: absolute;
|
578 |
+
top: 0;
|
579 |
+
left: 0;
|
580 |
+
width: 100%;
|
581 |
+
height: 100%;
|
582 |
+
box-sizing: border-box;
|
583 |
+
background: none;
|
584 |
+
border: none;
|
585 |
+
cursor: pointer;
|
586 |
+
color: #0071a1;
|
587 |
+
padding: 0 0 0 32px;
|
588 |
+
text-align: left;
|
589 |
+
}
|
590 |
+
|
591 |
+
|
592 |
+
|
593 |
+
/******************************************************************
|
594 |
+
CONTROLS AND ICONS SCREENS
|
595 |
+
******************************************************************/
|
596 |
+
|
597 |
+
/*
|
598 |
+
Lightbox control element selection
|
599 |
+
*/
|
600 |
+
.ulb-admin-one-third,
|
601 |
+
.ulb-admin-one-sixth {
|
602 |
+
float: left;
|
603 |
+
margin-bottom: 18px;
|
604 |
+
}
|
605 |
+
.ulb-admin-one-third {
|
606 |
+
width: 30%;
|
607 |
+
}
|
608 |
+
.ulb-admin-one-sixth {
|
609 |
+
width: auto;
|
610 |
+
}
|
611 |
+
|
612 |
+
.ulb-toolbar-control {
|
613 |
+
width: 40px;
|
614 |
+
float: left;
|
615 |
+
cursor: pointer;
|
616 |
+
}
|
617 |
+
.ewd-ulb-selected-control {
|
618 |
+
background: #333333;
|
619 |
+
color: #FFFFFF;
|
620 |
+
}
|
621 |
+
|
622 |
+
.ulb-add-button,
|
623 |
+
.ulb-remove-button {
|
624 |
+
width: 96px;
|
625 |
+
padding: 6px 0;
|
626 |
+
margin: 0 auto;
|
627 |
+
margin-bottom: 8px;
|
628 |
+
background: #111;
|
629 |
+
color: #fff;
|
630 |
+
border: 2px solid #111;
|
631 |
+
border-radius: 2px;
|
632 |
+
text-align: center;
|
633 |
+
cursor: pointer;
|
634 |
+
transition: background .3s, color .3s;
|
635 |
+
}
|
636 |
+
.ulb-add-button:hover,
|
637 |
+
.ulb-remove-button:hover {
|
638 |
+
background: transparent;
|
639 |
+
color: #111;
|
640 |
+
}
|
641 |
+
|
642 |
+
/*
|
643 |
+
Lightbox Icon Selection
|
644 |
+
*/
|
645 |
+
|
646 |
+
.ewd-ulb-control-icons span {
|
647 |
+
font-size: 1.8em;
|
648 |
+
letter-spacing: 3px;
|
649 |
+
}
|
650 |
+
|
651 |
+
/*TOOLBAR SELECT ITEMS*/
|
652 |
+
.ulb-toolbar-controls {
|
653 |
+
background: #f4f4f4;
|
654 |
+
padding: 8px;
|
655 |
+
margin-right: 8px;
|
656 |
+
margin-left: 8px;
|
657 |
+
height: 60px;
|
658 |
+
}
|
lib/simple-admin-pages/css/admin.css
CHANGED
@@ -1,247 +1,247 @@
|
|
1 |
-
/*
|
2 |
-
* CSS Stylesheet for Simple Admin Pages library
|
3 |
-
*
|
4 |
-
* This stylesheet formats the display components placed into the WordPress
|
5 |
-
* admin menu. It attempts to replicate WordPress's existing admin menu style.
|
6 |
-
*
|
7 |
-
* @package Simple Admin Pages
|
8 |
-
*/
|
9 |
-
|
10 |
-
/**
|
11 |
-
* Clear floats
|
12 |
-
*/
|
13 |
-
.clearfix:before,
|
14 |
-
.clearfix:after {
|
15 |
-
content: " ";
|
16 |
-
display: table;
|
17 |
-
}
|
18 |
-
.clearfix:after {
|
19 |
-
clear: both;
|
20 |
-
}
|
21 |
-
|
22 |
-
/**
|
23 |
-
* Textarea
|
24 |
-
*/
|
25 |
-
textarea.small-text {
|
26 |
-
width: 25em;
|
27 |
-
height: 10em;
|
28 |
-
}
|
29 |
-
textarea.large-text {
|
30 |
-
height: 30em;
|
31 |
-
}
|
32 |
-
|
33 |
-
/**
|
34 |
-
* Image
|
35 |
-
*/
|
36 |
-
.sap-image-wrapper img {
|
37 |
-
display: block;
|
38 |
-
width: 100%;
|
39 |
-
height: auto;
|
40 |
-
max-width: 500px;
|
41 |
-
margin-bottom: 1em;
|
42 |
-
}
|
43 |
-
.sap-image-wrapper-no-image .sap-image-btn-change,
|
44 |
-
.sap-image-wrapper-no-image .sap-image-btn-remove,
|
45 |
-
.sap-image-wrapper-no-image img {
|
46 |
-
display: none;
|
47 |
-
}
|
48 |
-
.sap-image-wrapper-has-image .sap-image-btn-add {
|
49 |
-
display: none;
|
50 |
-
}
|
51 |
-
|
52 |
-
/*
|
53 |
-
* Opening Hours
|
54 |
-
*/
|
55 |
-
.sap-opening-hours td {
|
56 |
-
padding-left: 0;
|
57 |
-
padding-right: 1em;
|
58 |
-
padding-top: 0;
|
59 |
-
}
|
60 |
-
input.sap-opening-hours-day {
|
61 |
-
width: 15em;
|
62 |
-
}
|
63 |
-
input.sap-opening-hours-hours {
|
64 |
-
width: 9em;
|
65 |
-
}
|
66 |
-
|
67 |
-
/*
|
68 |
-
* Scheduler
|
69 |
-
*/
|
70 |
-
.sap-add-scheduler {
|
71 |
-
margin-top: 1em;
|
72 |
-
}
|
73 |
-
.sap-scheduler-rule {
|
74 |
-
position: relative;
|
75 |
-
padding: 1em;
|
76 |
-
margin: 1em 0;
|
77 |
-
max-width: 800px;
|
78 |
-
background: #fff;
|
79 |
-
-webkit-box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);
|
80 |
-
box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);
|
81 |
-
}
|
82 |
-
.sap-selector {
|
83 |
-
display: inline-block;
|
84 |
-
margin-top: 0;
|
85 |
-
margin-right: 1em;
|
86 |
-
border-bottom: 1px solid #ccc;
|
87 |
-
}
|
88 |
-
.sap-selector li {
|
89 |
-
display: inline-block;
|
90 |
-
margin-right: 1em;
|
91 |
-
line-height: 20px;
|
92 |
-
}
|
93 |
-
.sap-selector a {
|
94 |
-
text-decoration: none;
|
95 |
-
}
|
96 |
-
.sap-selector .selected {
|
97 |
-
font-weight: 600;
|
98 |
-
color: #666;
|
99 |
-
}
|
100 |
-
.sap-scheduler-weekdays li,
|
101 |
-
.sap-scheduler-weeks li {
|
102 |
-
display: inline-block;
|
103 |
-
margin-right: 0.5em;
|
104 |
-
text-align: center;
|
105 |
-
}
|
106 |
-
.sap-scheduler-date .label,
|
107 |
-
.sap-scheduler-date-input label {
|
108 |
-
display: block;
|
109 |
-
font-style: italic;
|
110 |
-
text-align: left;
|
111 |
-
margin-bottom: 0;
|
112 |
-
}
|
113 |
-
.sap-scheduler-weekdays input,
|
114 |
-
.sap-scheduler-weeks input {
|
115 |
-
margin-top: 6px;
|
116 |
-
margin-bottom: 7px;
|
117 |
-
}
|
118 |
-
.sap-scheduler-date label {
|
119 |
-
display: block;
|
120 |
-
}
|
121 |
-
.sap-scheduler-date-input {
|
122 |
-
display: none;
|
123 |
-
margin-top: 1em;
|
124 |
-
}
|
125 |
-
.sap-scheduler-date.date .sap-scheduler-weeks,
|
126 |
-
.sap-scheduler-date.date .sap-scheduler-weekdays {
|
127 |
-
display: none;
|
128 |
-
}
|
129 |
-
.sap-scheduler-date.weekly .sap-scheduler-weeks,
|
130 |
-
.sap-scheduler-date.date .sap-scheduler-weeks {
|
131 |
-
display: none;
|
132 |
-
}
|
133 |
-
.sap-scheduler-date.date .sap-scheduler-date-input {
|
134 |
-
display: block;
|
135 |
-
}
|
136 |
-
.sap-scheduler-time {
|
137 |
-
margin-top: 4em;
|
138 |
-
}
|
139 |
-
.sap-scheduler-time.all-day .sap-scheduler-time-input {
|
140 |
-
display: none;
|
141 |
-
}
|
142 |
-
.sap-scheduler-time-input .start,
|
143 |
-
.sap-scheduler-time-input .end {
|
144 |
-
margin-top: 1em;
|
145 |
-
display: inline-block;
|
146 |
-
}
|
147 |
-
.sap-scheduler-time-input .start {
|
148 |
-
margin-right: 1em;
|
149 |
-
}
|
150 |
-
.sap-scheduler-time-input label {
|
151 |
-
display: block;
|
152 |
-
font-style: italic;
|
153 |
-
}
|
154 |
-
.sap-scheduler-time-input input {
|
155 |
-
max-width: 8em;
|
156 |
-
}
|
157 |
-
.sap-scheduler-all-day {
|
158 |
-
display: block;
|
159 |
-
margin-top: 1.7em;
|
160 |
-
font-style: italic;
|
161 |
-
padding: 1em;
|
162 |
-
background: #eee;
|
163 |
-
}
|
164 |
-
.sap-scheduler-all-day p {
|
165 |
-
margin-top: 0;
|
166 |
-
}
|
167 |
-
.sap-scheduler-time.time-slot .sap-scheduler-all-day {
|
168 |
-
display: none;
|
169 |
-
}
|
170 |
-
.sap-scheduler-control {
|
171 |
-
clear: both;
|
172 |
-
line-height: 1.5em;
|
173 |
-
}
|
174 |
-
.sap-scheduler-control {
|
175 |
-
position: absolute;
|
176 |
-
top: 1em;
|
177 |
-
right: 1em;
|
178 |
-
}
|
179 |
-
.sap-scheduler-control a {
|
180 |
-
text-decoration: none;
|
181 |
-
}
|
182 |
-
.sap-scheduler-control .delete {
|
183 |
-
color: #a00;
|
184 |
-
}
|
185 |
-
.sap-scheduler-control .delete:hover,
|
186 |
-
.sap-scheduler-control .delete:focus {
|
187 |
-
color: red;
|
188 |
-
}
|
189 |
-
.sap-scheduler-rule.list .sap-scheduler-date,
|
190 |
-
.sap-scheduler-rule.list .sap-scheduler-time {
|
191 |
-
display: none;
|
192 |
-
}
|
193 |
-
.sap-scheduler-rule .sap-scheduler-brief {
|
194 |
-
display: none;
|
195 |
-
clear: both;
|
196 |
-
}
|
197 |
-
.sap-scheduler-rule.list .sap-scheduler-brief {
|
198 |
-
display: block;
|
199 |
-
}
|
200 |
-
.sap-scheduler-brief {
|
201 |
-
margin-right: 4em;
|
202 |
-
line-height: 1.5em;
|
203 |
-
}
|
204 |
-
.sap-scheduler-brief .date,
|
205 |
-
.sap-scheduler-brief .time {
|
206 |
-
display: inline-block;
|
207 |
-
}
|
208 |
-
.sap-scheduler-brief .date {
|
209 |
-
margin-right: 1em;
|
210 |
-
}
|
211 |
-
.sap-add-scheduler.disabled {
|
212 |
-
display: none;
|
213 |
-
}
|
214 |
-
@media (min-width: 783px) {
|
215 |
-
.sap-selector li {
|
216 |
-
font-size: 13px;
|
217 |
-
}
|
218 |
-
.sap-scheduler-time {
|
219 |
-
margin-top: 0;
|
220 |
-
}
|
221 |
-
.sap-scheduler-date {
|
222 |
-
float: left;
|
223 |
-
width: 50%;
|
224 |
-
}
|
225 |
-
.sap-scheduler-date.full-width {
|
226 |
-
float: none;
|
227 |
-
width: 100%;
|
228 |
-
}
|
229 |
-
.sap-scheduler-time {
|
230 |
-
float: right;
|
231 |
-
width: 50%;
|
232 |
-
}
|
233 |
-
}
|
234 |
-
|
235 |
-
/**
|
236 |
-
* Adjustements to pickadate library css to override WP admin styles
|
237 |
-
*/
|
238 |
-
.picker .picker__table {
|
239 |
-
table-layout: auto;
|
240 |
-
}
|
241 |
-
.picker .picker__table th,
|
242 |
-
.picker .picker__table td {
|
243 |
-
text-align: center;
|
244 |
-
display: table-cell;
|
245 |
-
padding: 0.5em;
|
246 |
-
font-size: 1em;
|
247 |
-
}
|
1 |
+
/*
|
2 |
+
* CSS Stylesheet for Simple Admin Pages library
|
3 |
+
*
|
4 |
+
* This stylesheet formats the display components placed into the WordPress
|
5 |
+
* admin menu. It attempts to replicate WordPress's existing admin menu style.
|
6 |
+
*
|
7 |
+
* @package Simple Admin Pages
|
8 |
+
*/
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Clear floats
|
12 |
+
*/
|
13 |
+
.clearfix:before,
|
14 |
+
.clearfix:after {
|
15 |
+
content: " ";
|
16 |
+
display: table;
|
17 |
+
}
|
18 |
+
.clearfix:after {
|
19 |
+
clear: both;
|
20 |
+
}
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Textarea
|
24 |
+
*/
|
25 |
+
textarea.small-text {
|
26 |
+
width: 25em;
|
27 |
+
height: 10em;
|
28 |
+
}
|
29 |
+
textarea.large-text {
|
30 |
+
height: 30em;
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Image
|
35 |
+
*/
|
36 |
+
.sap-image-wrapper img {
|
37 |
+
display: block;
|
38 |
+
width: 100%;
|
39 |
+
height: auto;
|
40 |
+
max-width: 500px;
|
41 |
+
margin-bottom: 1em;
|
42 |
+
}
|
43 |
+
.sap-image-wrapper-no-image .sap-image-btn-change,
|
44 |
+
.sap-image-wrapper-no-image .sap-image-btn-remove,
|
45 |
+
.sap-image-wrapper-no-image img {
|
46 |
+
display: none;
|
47 |
+
}
|
48 |
+
.sap-image-wrapper-has-image .sap-image-btn-add {
|
49 |
+
display: none;
|
50 |
+
}
|
51 |
+
|
52 |
+
/*
|
53 |
+
* Opening Hours
|
54 |
+
*/
|
55 |
+
.sap-opening-hours td {
|
56 |
+
padding-left: 0;
|
57 |
+
padding-right: 1em;
|
58 |
+
padding-top: 0;
|
59 |
+
}
|
60 |
+
input.sap-opening-hours-day {
|
61 |
+
width: 15em;
|
62 |
+
}
|
63 |
+
input.sap-opening-hours-hours {
|
64 |
+
width: 9em;
|
65 |
+
}
|
66 |
+
|
67 |
+
/*
|
68 |
+
* Scheduler
|
69 |
+
*/
|
70 |
+
.sap-add-scheduler {
|
71 |
+
margin-top: 1em;
|
72 |
+
}
|
73 |
+
.sap-scheduler-rule {
|
74 |
+
position: relative;
|
75 |
+
padding: 1em;
|
76 |
+
margin: 1em 0;
|
77 |
+
max-width: 800px;
|
78 |
+
background: #fff;
|
79 |
+
-webkit-box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);
|
80 |
+
box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);
|
81 |
+
}
|
82 |
+
.sap-selector {
|
83 |
+
display: inline-block;
|
84 |
+
margin-top: 0;
|
85 |
+
margin-right: 1em;
|
86 |
+
border-bottom: 1px solid #ccc;
|
87 |
+
}
|
88 |
+
.sap-selector li {
|
89 |
+
display: inline-block;
|
90 |
+
margin-right: 1em;
|
91 |
+
line-height: 20px;
|
92 |
+
}
|
93 |
+
.sap-selector a {
|
94 |
+
text-decoration: none;
|
95 |
+
}
|
96 |
+
.sap-selector .selected {
|
97 |
+
font-weight: 600;
|
98 |
+
color: #666;
|
99 |
+
}
|
100 |
+
.sap-scheduler-weekdays li,
|
101 |
+
.sap-scheduler-weeks li {
|
102 |
+
display: inline-block;
|
103 |
+
margin-right: 0.5em;
|
104 |
+
text-align: center;
|
105 |
+
}
|
106 |
+
.sap-scheduler-date .label,
|
107 |
+
.sap-scheduler-date-input label {
|
108 |
+
display: block;
|
109 |
+
font-style: italic;
|
110 |
+
text-align: left;
|
111 |
+
margin-bottom: 0;
|
112 |
+
}
|
113 |
+
.sap-scheduler-weekdays input,
|
114 |
+
.sap-scheduler-weeks input {
|
115 |
+
margin-top: 6px;
|
116 |
+
margin-bottom: 7px;
|
117 |
+
}
|
118 |
+
.sap-scheduler-date label {
|
119 |
+
display: block;
|
120 |
+
}
|
121 |
+
.sap-scheduler-date-input {
|
122 |
+
display: none;
|
123 |
+
margin-top: 1em;
|
124 |
+
}
|
125 |
+
.sap-scheduler-date.date .sap-scheduler-weeks,
|
126 |
+
.sap-scheduler-date.date .sap-scheduler-weekdays {
|
127 |
+
display: none;
|
128 |
+
}
|
129 |
+
.sap-scheduler-date.weekly .sap-scheduler-weeks,
|
130 |
+
.sap-scheduler-date.date .sap-scheduler-weeks {
|
131 |
+
display: none;
|
132 |
+
}
|
133 |
+
.sap-scheduler-date.date .sap-scheduler-date-input {
|
134 |
+
display: block;
|
135 |
+
}
|
136 |
+
.sap-scheduler-time {
|
137 |
+
margin-top: 4em;
|
138 |
+
}
|
139 |
+
.sap-scheduler-time.all-day .sap-scheduler-time-input {
|
140 |
+
display: none;
|
141 |
+
}
|
142 |
+
.sap-scheduler-time-input .start,
|
143 |
+
.sap-scheduler-time-input .end {
|
144 |
+
margin-top: 1em;
|
145 |
+
display: inline-block;
|
146 |
+
}
|
147 |
+
.sap-scheduler-time-input .start {
|
148 |
+
margin-right: 1em;
|
149 |
+
}
|
150 |
+
.sap-scheduler-time-input label {
|
151 |
+
display: block;
|
152 |
+
font-style: italic;
|
153 |
+
}
|
154 |
+
.sap-scheduler-time-input input {
|
155 |
+
max-width: 8em;
|
156 |
+
}
|
157 |
+
.sap-scheduler-all-day {
|
158 |
+
display: block;
|
159 |
+
margin-top: 1.7em;
|
160 |
+
font-style: italic;
|
161 |
+
padding: 1em;
|
162 |
+
background: #eee;
|
163 |
+
}
|
164 |
+
.sap-scheduler-all-day p {
|
165 |
+
margin-top: 0;
|
166 |
+
}
|
167 |
+
.sap-scheduler-time.time-slot .sap-scheduler-all-day {
|
168 |
+
display: none;
|
169 |
+
}
|
170 |
+
.sap-scheduler-control {
|
171 |
+
clear: both;
|
172 |
+
line-height: 1.5em;
|
173 |
+
}
|
174 |
+
.sap-scheduler-control {
|
175 |
+
position: absolute;
|
176 |
+
top: 1em;
|
177 |
+
right: 1em;
|
178 |
+
}
|
179 |
+
.sap-scheduler-control a {
|
180 |
+
text-decoration: none;
|
181 |
+
}
|
182 |
+
.sap-scheduler-control .delete {
|
183 |
+
color: #a00;
|
184 |
+
}
|
185 |
+
.sap-scheduler-control .delete:hover,
|
186 |
+
.sap-scheduler-control .delete:focus {
|
187 |
+
color: red;
|
188 |
+
}
|
189 |
+
.sap-scheduler-rule.list .sap-scheduler-date,
|
190 |
+
.sap-scheduler-rule.list .sap-scheduler-time {
|
191 |
+
display: none;
|
192 |
+
}
|
193 |
+
.sap-scheduler-rule .sap-scheduler-brief {
|
194 |
+
display: none;
|
195 |
+
clear: both;
|
196 |
+
}
|
197 |
+
.sap-scheduler-rule.list .sap-scheduler-brief {
|
198 |
+
display: block;
|
199 |
+
}
|
200 |
+
.sap-scheduler-brief {
|
201 |
+
margin-right: 4em;
|
202 |
+
line-height: 1.5em;
|
203 |
+
}
|
204 |
+
.sap-scheduler-brief .date,
|
205 |
+
.sap-scheduler-brief .time {
|
206 |
+
display: inline-block;
|
207 |
+
}
|
208 |
+
.sap-scheduler-brief .date {
|
209 |
+
margin-right: 1em;
|
210 |
+
}
|
211 |
+
.sap-add-scheduler.disabled {
|
212 |
+
display: none;
|
213 |
+
}
|
214 |
+
@media (min-width: 783px) {
|
215 |
+
.sap-selector li {
|
216 |
+
font-size: 13px;
|
217 |
+
}
|
218 |
+
.sap-scheduler-time {
|
219 |
+
margin-top: 0;
|
220 |
+
}
|
221 |
+
.sap-scheduler-date {
|
222 |
+
float: left;
|
223 |
+
width: 50%;
|
224 |
+
}
|
225 |
+
.sap-scheduler-date.full-width {
|
226 |
+
float: none;
|
227 |
+
width: 100%;
|
228 |
+
}
|
229 |
+
.sap-scheduler-time {
|
230 |
+
float: right;
|
231 |
+
width: 50%;
|
232 |
+
}
|
233 |
+
}
|
234 |
+
|
235 |
+
/**
|
236 |
+
* Adjustements to pickadate library css to override WP admin styles
|
237 |
+
*/
|
238 |
+
.picker .picker__table {
|
239 |
+
table-layout: auto;
|
240 |
+
}
|
241 |
+
.picker .picker__table th,
|
242 |
+
.picker .picker__table td {
|
243 |
+
text-align: center;
|
244 |
+
display: table-cell;
|
245 |
+
padding: 0.5em;
|
246 |
+
font-size: 1em;
|
247 |
+
}
|
lib/simple-admin-pages/css/infinite_table.css
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
1 |
+
.sap-hidden {
|
2 |
+
display: none;
|
3 |
+
}
|
lib/simple-admin-pages/css/ordering.css
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/****************************
|
2 |
+
ORDERING TABLE
|
3 |
+
****************************/
|
4 |
+
.sap-ordering-table table {
|
5 |
+
width: 100%;
|
6 |
+
border-collapse: collapse;
|
7 |
+
}
|
8 |
+
.sap-ordering-table table th, .sap-ordering-table table td {
|
9 |
+
background: #f1f1f1;
|
10 |
+
padding: 8px 16px;
|
11 |
+
width: calc(100% - 32px);
|
12 |
+
}
|
13 |
+
.sap-ordering-table table td {
|
14 |
+
border-bottom: 1px solid #ccc;
|
15 |
+
cursor: move;
|
16 |
+
}
|
17 |
+
.sap-ordering-table table td:first-of-type {
|
18 |
+
border-top: 1px solid #ccc;
|
19 |
+
}
|
20 |
+
.sap-ordering-table table tr:nth-of-type(2n+2) td {
|
21 |
+
background: #fafafa;
|
22 |
+
}
|
23 |
+
.sap-ordering-table table th {
|
24 |
+
background: #662D91;
|
25 |
+
color: #fff;
|
26 |
+
text-align: left;
|
27 |
+
}
|
lib/simple-admin-pages/css/spectrum.css
ADDED
@@ -0,0 +1,507 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/***
|
2 |
+
Spectrum Colorpicker v1.7.1
|
3 |
+
https://github.com/bgrins/spectrum
|
4 |
+
Author: Brian Grinstead
|
5 |
+
License: MIT
|
6 |
+
***/
|
7 |
+
|
8 |
+
.sp-container {
|
9 |
+
position:absolute;
|
10 |
+
top:0;
|
11 |
+
left:0;
|
12 |
+
display:inline-block;
|
13 |
+
*display: inline;
|
14 |
+
*zoom: 1;
|
15 |
+
/* https://github.com/bgrins/spectrum/issues/40 */
|
16 |
+
z-index: 9999994;
|
17 |
+
overflow: hidden;
|
18 |
+
}
|
19 |
+
.sp-container.sp-flat {
|
20 |
+
position: relative;
|
21 |
+
}
|
22 |
+
|
23 |
+
/* Fix for * { box-sizing: border-box; } */
|
24 |
+
.sp-container,
|
25 |
+
.sp-container * {
|
26 |
+
-webkit-box-sizing: content-box;
|
27 |
+
-moz-box-sizing: content-box;
|
28 |
+
box-sizing: content-box;
|
29 |
+
}
|
30 |
+
|
31 |
+
/* http://ansciath.tumblr.com/post/7347495869/css-aspect-ratio */
|
32 |
+
.sp-top {
|
33 |
+
position:relative;
|
34 |
+
width: 100%;
|
35 |
+
display:inline-block;
|
36 |
+
}
|
37 |
+
.sp-top-inner {
|
38 |
+
position:absolute;
|
39 |
+
top:0;
|
40 |
+
left:0;
|
41 |
+
bottom:0;
|
42 |
+
right:0;
|
43 |
+
}
|
44 |
+
.sp-color {
|
45 |
+
position: absolute;
|
46 |
+
top:0;
|
47 |
+
left:0;
|
48 |
+
bottom:0;
|
49 |
+
right:20%;
|
50 |
+
}
|
51 |
+
.sp-hue {
|
52 |
+
position: absolute;
|
53 |
+
top:0;
|
54 |
+
right:0;
|
55 |
+
bottom:0;
|
56 |
+
left:84%;
|
57 |
+
height: 100%;
|
58 |
+
}
|
59 |
+
|
60 |
+
.sp-clear-enabled .sp-hue {
|
61 |
+
top:33px;
|
62 |
+
height: 77.5%;
|
63 |
+
}
|
64 |
+
|
65 |
+
.sp-fill {
|
66 |
+
padding-top: 80%;
|
67 |
+
}
|
68 |
+
.sp-sat, .sp-val {
|
69 |
+
position: absolute;
|
70 |
+
top:0;
|
71 |
+
left:0;
|
72 |
+
right:0;
|
73 |
+
bottom:0;
|
74 |
+
}
|
75 |
+
|
76 |
+
.sp-alpha-enabled .sp-top {
|
77 |
+
margin-bottom: 18px;
|
78 |
+
}
|
79 |
+
.sp-alpha-enabled .sp-alpha {
|
80 |
+
display: block;
|
81 |
+
}
|
82 |
+
.sp-alpha-handle {
|
83 |
+
position:absolute;
|
84 |
+
top:-4px;
|
85 |
+
bottom: -4px;
|
86 |
+
width: 6px;
|
87 |
+
left: 50%;
|
88 |
+
cursor: pointer;
|
89 |
+
border: 1px solid black;
|
90 |
+
background: white;
|
91 |
+
opacity: .8;
|
92 |
+
}
|
93 |
+
.sp-alpha {
|
94 |
+
display: none;
|
95 |
+
position: absolute;
|
96 |
+
bottom: -14px;
|
97 |
+
right: 0;
|
98 |
+
left: 0;
|
99 |
+
height: 8px;
|
100 |
+
}
|
101 |
+
.sp-alpha-inner {
|
102 |
+
border: solid 1px #333;
|
103 |
+
}
|
104 |
+
|
105 |
+
.sp-clear {
|
106 |
+
display: none;
|
107 |
+
}
|
108 |
+
|
109 |
+
.sp-clear.sp-clear-display {
|
110 |
+
background-position: center;
|
111 |
+
}
|
112 |
+
|
113 |
+
.sp-clear-enabled .sp-clear {
|
114 |
+
display: block;
|
115 |
+
position:absolute;
|
116 |
+
top:0px;
|
117 |
+
right:0;
|
118 |
+
bottom:0;
|
119 |
+
left:84%;
|
120 |
+
height: 28px;
|
121 |
+
}
|
122 |
+
|
123 |
+
/* Don't allow text selection */
|
124 |
+
.sp-container, .sp-replacer, .sp-preview, .sp-dragger, .sp-slider, .sp-alpha, .sp-clear, .sp-alpha-handle, .sp-container.sp-dragging .sp-input, .sp-container button {
|
125 |
+
-webkit-user-select:none;
|
126 |
+
-moz-user-select: -moz-none;
|
127 |
+
-o-user-select:none;
|
128 |
+
user-select: none;
|
129 |
+
}
|
130 |
+
|
131 |
+
.sp-container.sp-input-disabled .sp-input-container {
|
132 |
+
display: none;
|
133 |
+
}
|
134 |
+
.sp-container.sp-buttons-disabled .sp-button-container {
|
135 |
+
display: none;
|
136 |
+
}
|
137 |
+
.sp-container.sp-palette-buttons-disabled .sp-palette-button-container {
|
138 |
+
display: none;
|
139 |
+
}
|
140 |
+
.sp-palette-only .sp-picker-container {
|
141 |
+
display: none;
|
142 |
+
}
|
143 |
+
.sp-palette-disabled .sp-palette-container {
|
144 |
+
display: none;
|
145 |
+
}
|
146 |
+
|
147 |
+
.sp-initial-disabled .sp-initial {
|
148 |
+
display: none;
|
149 |
+
}
|
150 |
+
|
151 |
+
|
152 |
+
/* Gradients for hue, saturation and value instead of images. Not pretty... but it works */
|
153 |
+
.sp-sat {
|
154 |
+
background-image: -webkit-gradient(linear, 0 0, 100% 0, from(#FFF), to(rgba(204, 154, 129, 0)));
|
155 |
+
background-image: -webkit-linear-gradient(left, #FFF, rgba(204, 154, 129, 0));
|
156 |
+
background-image: -moz-linear-gradient(left, #fff, rgba(204, 154, 129, 0));
|
157 |
+
background-image: -o-linear-gradient(left, #fff, rgba(204, 154, 129, 0));
|
158 |
+
background-image: -ms-linear-gradient(left, #fff, rgba(204, 154, 129, 0));
|
159 |
+
background-image: linear-gradient(to right, #fff, rgba(204, 154, 129, 0));
|
160 |
+
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(GradientType = 1, startColorstr=#FFFFFFFF, endColorstr=#00CC9A81)";
|
161 |
+
filter : progid:DXImageTransform.Microsoft.gradient(GradientType = 1, startColorstr='#FFFFFFFF', endColorstr='#00CC9A81');
|
162 |
+
}
|
163 |
+
.sp-val {
|
164 |
+
background-image: -webkit-gradient(linear, 0 100%, 0 0, from(#000000), to(rgba(204, 154, 129, 0)));
|
165 |
+
background-image: -webkit-linear-gradient(bottom, #000000, rgba(204, 154, 129, 0));
|
166 |
+
background-image: -moz-linear-gradient(bottom, #000, rgba(204, 154, 129, 0));
|
167 |
+
background-image: -o-linear-gradient(bottom, #000, rgba(204, 154, 129, 0));
|
168 |
+
background-image: -ms-linear-gradient(bottom, #000, rgba(204, 154, 129, 0));
|
169 |
+
background-image: linear-gradient(to top, #000, rgba(204, 154, 129, 0));
|
170 |
+
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#00CC9A81, endColorstr=#FF000000)";
|
171 |
+
filter : progid:DXImageTransform.Microsoft.gradient(startColorstr='#00CC9A81', endColorstr='#FF000000');
|
172 |
+
}
|
173 |
+
|
174 |
+
.sp-hue {
|
175 |
+
background: -moz-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
|
176 |
+
background: -ms-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
|
177 |
+
background: -o-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
|
178 |
+
background: -webkit-gradient(linear, left top, left bottom, from(#ff0000), color-stop(0.17, #ffff00), color-stop(0.33, #00ff00), color-stop(0.5, #00ffff), color-stop(0.67, #0000ff), color-stop(0.83, #ff00ff), to(#ff0000));
|
179 |
+
background: -webkit-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
|
180 |
+
background: linear-gradient(to bottom, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
|
181 |
+
}
|
182 |
+
|
183 |
+
/* IE filters do not support multiple color stops.
|
184 |
+
Generate 6 divs, line them up, and do two color gradients for each.
|
185 |
+
Yes, really.
|
186 |
+
*/
|
187 |
+
.sp-1 {
|
188 |
+
height:17%;
|
189 |
+
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0000', endColorstr='#ffff00');
|
190 |
+
}
|
191 |
+
.sp-2 {
|
192 |
+
height:16%;
|
193 |
+
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffff00', endColorstr='#00ff00');
|
194 |
+
}
|
195 |
+
.sp-3 {
|
196 |
+
height:17%;
|
197 |
+
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ff00', endColorstr='#00ffff');
|
198 |
+
}
|
199 |
+
.sp-4 {
|
200 |
+
height:17%;
|
201 |
+
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ffff', endColorstr='#0000ff');
|
202 |
+
}
|
203 |
+
.sp-5 {
|
204 |
+
height:16%;
|
205 |
+
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0000ff', endColorstr='#ff00ff');
|
206 |
+
}
|
207 |
+
.sp-6 {
|
208 |
+
height:17%;
|
209 |
+
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff00ff', endColorstr='#ff0000');
|
210 |
+
}
|
211 |
+
|
212 |
+
.sp-hidden {
|
213 |
+
display: none !important;
|
214 |
+
}
|
215 |
+
|
216 |
+
/* Clearfix hack */
|
217 |
+
.sp-cf:before, .sp-cf:after { content: ""; display: table; }
|
218 |
+
.sp-cf:after { clear: both; }
|
219 |
+
.sp-cf { *zoom: 1; }
|
220 |
+
|
221 |
+
/* Mobile devices, make hue slider bigger so it is easier to slide */
|
222 |
+
@media (max-device-width: 480px) {
|
223 |
+
.sp-color { right: 40%; }
|
224 |
+
.sp-hue { left: 63%; }
|
225 |
+
.sp-fill { padding-top: 60%; }
|
226 |
+
}
|
227 |
+
.sp-dragger {
|
228 |
+
border-radius: 5px;
|
229 |
+
height: 5px;
|
230 |
+
width: 5px;
|
231 |
+
border: 1px solid #fff;
|
232 |
+
background: #000;
|
233 |
+
cursor: pointer;
|
234 |
+
position:absolute;
|
235 |
+
top:0;
|
236 |
+
left: 0;
|
237 |
+
}
|
238 |
+
.sp-slider {
|
239 |
+
position: absolute;
|
240 |
+
top:0;
|
241 |
+
cursor:pointer;
|
242 |
+
height: 3px;
|
243 |
+
left: -1px;
|
244 |
+
right: -1px;
|
245 |
+
border: 1px solid #000;
|
246 |
+
background: white;
|
247 |
+
opacity: .8;
|
248 |
+
}
|
249 |
+
|
250 |
+
/*
|
251 |
+
Theme authors:
|
252 |
+
Here are the basic themeable display options (colors, fonts, global widths).
|
253 |
+
See http://bgrins.github.io/spectrum/themes/ for instructions.
|
254 |
+
*/
|
255 |
+
|
256 |
+
.sp-container {
|
257 |
+
border-radius: 0;
|
258 |
+
background-color: #ECECEC;
|
259 |
+
border: solid 1px #f0c49B;
|
260 |
+
padding: 0;
|
261 |
+
}
|
262 |
+
.sp-container, .sp-container button, .sp-container input, .sp-color, .sp-hue, .sp-clear {
|
263 |
+
font: normal 12px "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Geneva, Verdana, sans-serif;
|
264 |
+
-webkit-box-sizing: border-box;
|
265 |
+
-moz-box-sizing: border-box;
|
266 |
+
-ms-box-sizing: border-box;
|
267 |
+
box-sizing: border-box;
|
268 |
+
}
|
269 |
+
.sp-top {
|
270 |
+
margin-bottom: 3px;
|
271 |
+
}
|
272 |
+
.sp-color, .sp-hue, .sp-clear {
|
273 |
+
border: solid 1px #666;
|
274 |
+
}
|
275 |
+
|
276 |
+
/* Input */
|
277 |
+
.sp-input-container {
|
278 |
+
float:right;
|
279 |
+
width: 100px;
|
280 |
+
margin-bottom: 4px;
|
281 |
+
}
|
282 |
+
.sp-initial-disabled .sp-input-container {
|
283 |
+
width: 100%;
|
284 |
+
}
|
285 |
+
.sp-input {
|
286 |
+
font-size: 12px !important;
|
287 |
+
border: 1px inset;
|
288 |
+
padding: 4px 5px;
|
289 |
+
margin: 0;
|
290 |
+
width: 100%;
|
291 |
+
background:transparent;
|
292 |
+
border-radius: 3px;
|
293 |
+
color: #222;
|
294 |
+
}
|
295 |
+
.sp-input:focus {
|
296 |
+
border: 1px solid orange;
|
297 |
+
}
|
298 |
+
.sp-input.sp-validation-error {
|
299 |
+
border: 1px solid red;
|
300 |
+
background: #fdd;
|
301 |
+
}
|
302 |
+
.sp-picker-container , .sp-palette-container {
|
303 |
+
float:left;
|
304 |
+
position: relative;
|
305 |
+
padding: 10px;
|
306 |
+
padding-bottom: 300px;
|
307 |
+
margin-bottom: -290px;
|
308 |
+
}
|
309 |
+
.sp-picker-container {
|
310 |
+
width: 172px;
|
311 |
+
border-left: solid 1px #fff;
|
312 |
+
}
|
313 |
+
|
314 |
+
/* Palettes */
|
315 |
+
.sp-palette-container {
|
316 |
+
border-right: solid 1px #ccc;
|
317 |
+
}
|
318 |
+
|
319 |
+
.sp-palette-only .sp-palette-container {
|
320 |
+
border: 0;
|
321 |
+
}
|
322 |
+
|
323 |
+
.sp-palette .sp-thumb-el {
|
324 |
+
display: block;
|
325 |
+
position:relative;
|
326 |
+
float:left;
|
327 |
+
width: 24px;
|
328 |
+
height: 15px;
|
329 |
+
margin: 3px;
|
330 |
+
cursor: pointer;
|
331 |
+
border:solid 2px transparent;
|
332 |
+
}
|
333 |
+
.sp-palette .sp-thumb-el:hover, .sp-palette .sp-thumb-el.sp-thumb-active {
|
334 |
+
border-color: orange;
|
335 |
+
}
|
336 |
+
.sp-thumb-el {
|
337 |
+
position:relative;
|
338 |
+
}
|
339 |
+
|
340 |
+
/* Initial */
|
341 |
+
.sp-initial {
|
342 |
+
float: left;
|
343 |
+
border: solid 1px #333;
|
344 |
+
}
|
345 |
+
.sp-initial span {
|
346 |
+
width: 30px;
|
347 |
+
height: 25px;
|
348 |
+
border:none;
|
349 |
+
display:block;
|
350 |
+
float:left;
|
351 |
+
margin:0;
|
352 |
+
}
|
353 |
+
|
354 |
+
.sp-initial .sp-clear-display {
|
355 |
+
background-position: center;
|
356 |
+
}
|
357 |
+
|
358 |
+
/* Buttons */
|
359 |
+
.sp-palette-button-container,
|
360 |
+
.sp-button-container {
|
361 |
+
float: right;
|
362 |
+
}
|
363 |
+
|
364 |
+
/* Replacer (the little preview div that shows up instead of the <input>) */
|
365 |
+
.sp-replacer {
|
366 |
+
margin:0;
|
367 |
+
overflow:hidden;
|
368 |
+
cursor:pointer;
|
369 |
+
padding: 4px;
|
370 |
+
display:inline-block;
|
371 |
+
*zoom: 1;
|
372 |
+
*display: inline;
|
373 |
+
border: solid 1px #91765d;
|
374 |
+
background: #eee;
|
375 |
+
color: #333;
|
376 |
+
vertical-align: middle;
|
377 |
+
}
|
378 |
+
.sp-replacer:hover, .sp-replacer.sp-active {
|
379 |
+
border-color: #F0C49B;
|
380 |
+
color: #111;
|
381 |
+
}
|
382 |
+
.sp-replacer.sp-disabled {
|
383 |
+
cursor:default;
|
384 |
+
border-color: silver;
|
385 |
+
color: silver;
|
386 |
+
}
|
387 |
+
.sp-dd {
|
388 |
+
padding: 2px 0;
|
389 |
+
height: 16px;
|
390 |
+
line-height: 16px;
|
391 |
+
float:left;
|
392 |
+
font-size:10px;
|
393 |
+
}
|
394 |
+
.sp-preview {
|
395 |
+
position:relative;
|
396 |
+
width:25px;
|
397 |
+
height: 20px;
|
398 |
+
border: solid 1px #222;
|
399 |
+
margin-right: 5px;
|
400 |
+
float:left;
|
401 |
+
z-index: 0;
|
402 |
+
}
|
403 |
+
|
404 |
+
.sp-palette {
|
405 |
+
*width: 220px;
|
406 |
+
max-width: 220px;
|
407 |
+
}
|
408 |
+
.sp-palette .sp-thumb-el {
|
409 |
+
width:16px;
|
410 |
+
height: 16px;
|
411 |
+
margin:2px 1px;
|
412 |
+
border: solid 1px #d0d0d0;
|
413 |
+
}
|
414 |
+
|
415 |
+
.sp-container {
|
416 |
+
padding-bottom:0;
|
417 |
+
}
|
418 |
+
|
419 |
+
|
420 |
+
/* Buttons: http://hellohappy.org/css3-buttons/ */
|
421 |
+
.sp-container button {
|
422 |
+
background-color: #eeeeee;
|
423 |
+
background-image: -webkit-linear-gradient(top, #eeeeee, #cccccc);
|
424 |
+
background-image: -moz-linear-gradient(top, #eeeeee, #cccccc);
|
425 |
+
background-image: -ms-linear-gradient(top, #eeeeee, #cccccc);
|
426 |
+
background-image: -o-linear-gradient(top, #eeeeee, #cccccc);
|
427 |
+
background-image: linear-gradient(to bottom, #eeeeee, #cccccc);
|
428 |
+
border: 1px solid #ccc;
|
429 |
+
border-bottom: 1px solid #bbb;
|
430 |
+
border-radius: 3px;
|
431 |
+
color: #333;
|
432 |
+
font-size: 14px;
|
433 |
+
line-height: 1;
|
434 |
+
padding: 5px 4px;
|
435 |
+
text-align: center;
|
436 |
+
text-shadow: 0 1px 0 #eee;
|
437 |
+
vertical-align: middle;
|
438 |
+
}
|
439 |
+
.sp-container button:hover {
|
440 |
+
background-color: #dddddd;
|
441 |
+
background-image: -webkit-linear-gradient(top, #dddddd, #bbbbbb);
|
442 |
+
background-image: -moz-linear-gradient(top, #dddddd, #bbbbbb);
|
443 |
+
background-image: -ms-linear-gradient(top, #dddddd, #bbbbbb);
|
444 |
+
background-image: -o-linear-gradient(top, #dddddd, #bbbbbb);
|
445 |
+
background-image: linear-gradient(to bottom, #dddddd, #bbbbbb);
|
446 |
+
border: 1px solid #bbb;
|
447 |
+
border-bottom: 1px solid #999;
|
448 |
+
cursor: pointer;
|
449 |
+
text-shadow: 0 1px 0 #ddd;
|
450 |
+
}
|
451 |
+
.sp-container button:active {
|
452 |
+
border: 1px solid #aaa;
|
453 |
+
border-bottom: 1px solid #888;
|
454 |
+
-webkit-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
|
455 |
+
-moz-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
|
456 |
+
-ms-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
|
457 |
+
-o-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
|
458 |
+
box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
|
459 |
+
}
|
460 |
+
.sp-cancel {
|
461 |
+
font-size: 11px;
|
462 |
+
color: #d93f3f !important;
|
463 |
+
margin:0;
|
464 |
+
padding:2px;
|
465 |
+
margin-right: 5px;
|
466 |
+
vertical-align: middle;
|
467 |
+
text-decoration:none;
|
468 |
+
|
469 |
+
}
|
470 |
+
.sp-cancel:hover {
|
471 |
+
color: #d93f3f !important;
|
472 |
+
text-decoration: underline;
|
473 |
+
}
|
474 |
+
|
475 |
+
|
476 |
+
.sp-palette span:hover, .sp-palette span.sp-thumb-active {
|
477 |
+
border-color: #000;
|
478 |
+
}
|
479 |
+
|
480 |
+
.sp-preview, .sp-alpha, .sp-thumb-el {
|
481 |
+
position:relative;
|
482 |
+
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==);
|
483 |
+
}
|
484 |
+
.sp-preview-inner, .sp-alpha-inner, .sp-thumb-inner {
|
485 |
+
display:block;
|
486 |
+
position:absolute;
|
487 |
+
top:0;left:0;bottom:0;right:0;
|
488 |
+
}
|
489 |
+
|
490 |
+
.sp-palette .sp-thumb-inner {
|
491 |
+
background-position: 50% 50%;
|
492 |
+
background-repeat: no-repeat;
|
493 |
+
}
|
494 |
+
|
495 |
+
.sp-palette .sp-thumb-light.sp-thumb-active .sp-thumb-inner {
|
496 |
+
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAIVJREFUeNpiYBhsgJFMffxAXABlN5JruT4Q3wfi/0DsT64h8UD8HmpIPCWG/KemIfOJCUB+Aoacx6EGBZyHBqI+WsDCwuQ9mhxeg2A210Ntfo8klk9sOMijaURm7yc1UP2RNCMbKE9ODK1HM6iegYLkfx8pligC9lCD7KmRof0ZhjQACDAAceovrtpVBRkAAAAASUVORK5CYII=);
|
497 |
+
}
|
498 |
+
|
499 |
+
.sp-palette .sp-thumb-dark.sp-thumb-active .sp-thumb-inner {
|
500 |
+
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAMdJREFUOE+tkgsNwzAMRMugEAahEAahEAZhEAqlEAZhEAohEAYh81X2dIm8fKpEspLGvudPOsUYpxE2BIJCroJmEW9qJ+MKaBFhEMNabSy9oIcIPwrB+afvAUFoK4H0tMaQ3XtlrggDhOVVMuT4E5MMG0FBbCEYzjYT7OxLEvIHQLY2zWwQ3D+9luyOQTfKDiFD3iUIfPk8VqrKjgAiSfGFPecrg6HN6m/iBcwiDAo7WiBeawa+Kwh7tZoSCGLMqwlSAzVDhoK+6vH4G0P5wdkAAAAASUVORK5CYII=);
|
501 |
+
}
|
502 |
+
|
503 |
+
.sp-clear-display {
|
504 |
+
background-repeat:no-repeat;
|
505 |
+
background-position: center;
|
506 |
+
background-image: url(data:image/gif;base64,R0lGODlhFAAUAPcAAAAAAJmZmZ2dnZ6enqKioqOjo6SkpKWlpaampqenp6ioqKmpqaqqqqurq/Hx8fLy8vT09PX19ff39/j4+Pn5+fr6+vv7+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAP8ALAAAAAAUABQAAAihAP9FoPCvoMGDBy08+EdhQAIJCCMybCDAAYUEARBAlFiQQoMABQhKUJBxY0SPICEYHBnggEmDKAuoPMjS5cGYMxHW3IiT478JJA8M/CjTZ0GgLRekNGpwAsYABHIypcAgQMsITDtWJYBR6NSqMico9cqR6tKfY7GeBCuVwlipDNmefAtTrkSzB1RaIAoXodsABiZAEFB06gIBWC1mLVgBa0AAOw==);
|
507 |
+
}
|
lib/simple-admin-pages/img/options-asset-exclamation.png
ADDED
Binary file
|
lib/simple-admin-pages/img/options-asset-info.png
ADDED
Binary file
|
lib/simple-admin-pages/img/options-asset-lock.png
ADDED
Binary file
|
lib/simple-admin-pages/img/options-asset-star.png
ADDED
Binary file
|
lib/simple-admin-pages/img/options-asset-starX2.png
ADDED
Binary file
|
lib/simple-admin-pages/js/address.js
CHANGED
@@ -1,116 +1,116 @@
|
|
1 |
-
/**
|
2 |
-
* Javascript functions for Address component
|
3 |
-
*
|
4 |
-
* @package Simple Admin Pages
|
5 |
-
*/
|
6 |
-
|
7 |
-
jQuery(document).ready(function ($) {
|
8 |
-
|
9 |
-
/**
|
10 |
-
* Set coordinate that have been received
|
11 |
-
*/
|
12 |
-
function sap_address_set_coords( control, lat, lon ) {
|
13 |
-
control.find( '.sap-coords-result' ).remove();
|
14 |
-
control.find( 'input.lat' ).val( lat );
|
15 |
-
control.find( 'input.lon' ).val( lon );
|
16 |
-
|
17 |
-
if ( lat == '' && lon == '' ) {
|
18 |
-
control.find( '.sap-map-coords' ).text( lat + sap_address.strings['no-setting'] + lon ).attr( 'style', '' );
|
19 |
-
} else {
|
20 |
-
control.find( '.sap-map-coords' ).text( lat + sap_address.strings['sep-lat-lon'] + lon ).attr( 'style', '' );
|
21 |
-
}
|
22 |
-
|
23 |
-
var url = 'https://maps.google.com/maps?q=' + lat + ',' + lon;
|
24 |
-
if ( control.find( '.sap-view-coords' ).length ) {
|
25 |
-
control.find( '.sap-view-coords' ).attr( 'href', url );
|
26 |
-
} else {
|
27 |
-
control.find( '.sap-map-coords-wrapper' ).append( '<a class="sap-view-coords" href="' + url + '" target="_blank">' + sap_address.strings.view + '</a>' );
|
28 |
-
}
|
29 |
-
}
|
30 |
-
|
31 |
-
/**
|
32 |
-
* Retrieve coordinates
|
33 |
-
*/
|
34 |
-
$('.sap-get-coords').click( function(e) {
|
35 |
-
|
36 |
-
e.stopPropagation();
|
37 |
-
e.preventDefault();
|
38 |
-
|
39 |
-
var control = $(this).parent().parent();
|
40 |
-
var address = control.find( 'textarea' ).val();
|
41 |
-
var params = {
|
42 |
-
sensor: false,
|
43 |
-
address: address,
|
44 |
-
};
|
45 |
-
if ( sap_address.api_key_selector ) {
|
46 |
-
var $input = $( sap_address.api_key_selector );
|
47 |
-
if ( $input.length && $input.val() ) {
|
48 |
-
params.key = $input.val();
|
49 |
-
}
|
50 |
-
} else if ( sap_address.api_key ) {
|
51 |
-
params.key = sap_address.api_key;
|
52 |
-
}
|
53 |
-
|
54 |
-
// Reset messages
|
55 |
-
control.find( '.sap-coords-result' ).remove();
|
56 |
-
control.find( '.error' ).remove();
|
57 |
-
control.find( '.sap-view-coords' ).remove();
|
58 |
-
control.find( '.sap-map-coords' ).text( sap_address.strings.retrieving ).attr( 'style', 'opacity: 0.3' );
|
59 |
-
|
60 |
-
// Call Google Maps geocoding API
|
61 |
-
// See: https://developers.google.com/maps/documentation/geocoding/
|
62 |
-
var req = $.get(
|
63 |
-
'https://maps.googleapis.com/maps/api/geocode/json',
|
64 |
-
params,
|
65 |
-
function( data ) {
|
66 |
-
|
67 |
-
if ( data.status == 'OK' ) {
|
68 |
-
if ( data.results.length == 1 ) {
|
69 |
-
sap_address_set_coords( control, data.results[0].geometry.location.lat, data.results[0].geometry.location.lng );
|
70 |
-
|
71 |
-
} else {
|
72 |
-
for ( var key in data.results ) {
|
73 |
-
control.append( '<p class="sap-coords-result">' + data.results[key].formatted_address + ' <span class="dashicons dashicons-arrow-right"></span> <a href="#" data-lat="' + data.results[key].geometry.location.lat + '" data-lon="' + data.results[key].geometry.location.lng + '">Set</a></p>' );
|
74 |
-
}
|
75 |
-
control.find( '.sap-map-coords' ).text( sap_address.strings.select ).attr( 'style', '' );
|
76 |
-
|
77 |
-
control.find( '.sap-coords-result a' ).click( function() {
|
78 |
-
sap_address_set_coords( control, $(this).data( 'lat' ), $(this).data( 'lon' ) );
|
79 |
-
});
|
80 |
-
|
81 |
-
}
|
82 |
-
|
83 |
-
} else {
|
84 |
-
sap_address_set_coords( control, control.find( 'input.lat' ).val(), control.find( 'input.lon' ).val() );
|
85 |
-
|
86 |
-
if ( data.status == 'UNKNOWN_ERROR' ) {
|
87 |
-
control.find( '.sap-coords-action-wrapper' ).prepend( '<div class="error">' + sap_address.strings.result_error + '</div>' );
|
88 |
-
} else if ( data.status == 'INVALID_REQUEST' ) {
|
89 |
-
control.find( '.sap-coords-action-wrapper' ).prepend( '<div class="error">' + sap_address.strings.result_invalid + '</div>' );
|
90 |
-
} else if ( data.status == 'INVALID_REQUEST' ) {
|
91 |
-
control.find( '.sap-coords-action-wrapper' ).prepend( '<div class="error">' + sap_address.strings.result_error + '</div>' );
|
92 |
-
} else if ( data.status == 'REQUEST_DENIED' ) {
|
93 |
-
control.find( '.sap-coords-action-wrapper' ).prepend( '<div class="error">' + sap_address.strings.result_denied + '</div>' );
|
94 |
-
} else if ( data.status == 'OVER_QUERY_LIMIT' ) {
|
95 |
-
control.find( '.sap-coords-action-wrapper' ).prepend( '<div class="error">' + sap_address.strings.result_limit + '</div>' );
|
96 |
-
} else if ( data.status == 'ZERO_RESULTS' ) {
|
97 |
-
control.find( '.sap-coords-action-wrapper' ).prepend( '<div class="error">' + sap_address.strings.result_empty + '</div>' );
|
98 |
-
}
|
99 |
-
}
|
100 |
-
}
|
101 |
-
)
|
102 |
-
});
|
103 |
-
|
104 |
-
/**
|
105 |
-
* Remove coordinates from settings
|
106 |
-
*/
|
107 |
-
$('.sap-remove-coords').click( function(e) {
|
108 |
-
|
109 |
-
e.stopPropagation();
|
110 |
-
e.preventDefault();
|
111 |
-
|
112 |
-
var control = $(this).parent().parent();
|
113 |
-
sap_address_set_coords( control, '', '' );
|
114 |
-
});
|
115 |
-
|
116 |
-
});
|
1 |
+
/**
|
2 |
+
* Javascript functions for Address component
|
3 |
+
*
|
4 |
+
* @package Simple Admin Pages
|
5 |
+
*/
|
6 |
+
|
7 |
+
jQuery(document).ready(function ($) {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Set coordinate that have been received
|
11 |
+
*/
|
12 |
+
function sap_address_set_coords( control, lat, lon ) {
|
13 |
+
control.find( '.sap-coords-result' ).remove();
|
14 |
+
control.find( 'input.lat' ).val( lat );
|
15 |
+
control.find( 'input.lon' ).val( lon );
|
16 |
+
|
17 |
+
if ( lat == '' && lon == '' ) {
|
18 |
+
control.find( '.sap-map-coords' ).text( lat + sap_address.strings['no-setting'] + lon ).attr( 'style', '' );
|
19 |
+
} else {
|
20 |
+
control.find( '.sap-map-coords' ).text( lat + sap_address.strings['sep-lat-lon'] + lon ).attr( 'style', '' );
|
21 |
+
}
|
22 |
+
|
23 |
+
var url = 'https://maps.google.com/maps?q=' + lat + ',' + lon;
|
24 |
+
if ( control.find( '.sap-view-coords' ).length ) {
|
25 |
+
control.find( '.sap-view-coords' ).attr( 'href', url );
|
26 |
+
} else {
|
27 |
+
control.find( '.sap-map-coords-wrapper' ).append( '<a class="sap-view-coords" href="' + url + '" target="_blank">' + sap_address.strings.view + '</a>' );
|
28 |
+
}
|
29 |
+
}
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Retrieve coordinates
|
33 |
+
*/
|
34 |
+
$('.sap-get-coords').click( function(e) {
|
35 |
+
|
36 |
+
e.stopPropagation();
|
37 |
+
e.preventDefault();
|
38 |
+
|
39 |
+
var control = $(this).parent().parent();
|
40 |
+
var address = control.find( 'textarea' ).val();
|
41 |
+
var params = {
|
42 |
+
sensor: false,
|
43 |
+
address: address,
|
44 |
+
};
|
45 |
+
if ( sap_address.api_key_selector ) {
|
46 |
+
var $input = $( sap_address.api_key_selector );
|
47 |
+
if ( $input.length && $input.val() ) {
|
48 |
+
params.key = $input.val();
|
49 |
+
}
|
50 |
+
} else if ( sap_address.api_key ) {
|
51 |
+
params.key = sap_address.api_key;
|
52 |
+
}
|
53 |
+
|
54 |
+
// Reset messages
|
55 |
+
control.find( '.sap-coords-result' ).remove();
|
56 |
+
control.find( '.error' ).remove();
|
57 |
+
control.find( '.sap-view-coords' ).remove();
|
58 |
+
control.find( '.sap-map-coords' ).text( sap_address.strings.retrieving ).attr( 'style', 'opacity: 0.3' );
|
59 |
+
|
60 |
+
// Call Google Maps geocoding API
|
61 |
+
// See: https://developers.google.com/maps/documentation/geocoding/
|
62 |
+
var req = $.get(
|
63 |
+
'https://maps.googleapis.com/maps/api/geocode/json',
|
64 |
+
params,
|
65 |
+
function( data ) {
|
66 |
+
|
67 |
+
if ( data.status == 'OK' ) {
|
68 |
+
if ( data.results.length == 1 ) {
|
69 |
+
sap_address_set_coords( control, data.results[0].geometry.location.lat, data.results[0].geometry.location.lng );
|
70 |
+
|
71 |
+
} else {
|
72 |
+
for ( var key in data.results ) {
|
73 |
+
control.append( '<p class="sap-coords-result">' + data.results[key].formatted_address + ' <span class="dashicons dashicons-arrow-right"></span> <a href="#" data-lat="' + data.results[key].geometry.location.lat + '" data-lon="' + data.results[key].geometry.location.lng + '">Set</a></p>' );
|
74 |
+
}
|
75 |
+
control.find( '.sap-map-coords' ).text( sap_address.strings.select ).attr( 'style', '' );
|
76 |
+
|
77 |
+
control.find( '.sap-coords-result a' ).click( function() {
|
78 |
+
sap_address_set_coords( control, $(this).data( 'lat' ), $(this).data( 'lon' ) );
|
79 |
+
});
|
80 |
+
|
81 |
+
}
|
82 |
+
|
83 |
+
} else {
|
84 |
+
sap_address_set_coords( control, control.find( 'input.lat' ).val(), control.find( 'input.lon' ).val() );
|
85 |
+
|
86 |
+
if ( data.status == 'UNKNOWN_ERROR' ) {
|
87 |
+
control.find( '.sap-coords-action-wrapper' ).prepend( '<div class="error">' + sap_address.strings.result_error + '</div>' );
|
88 |
+
} else if ( data.status == 'INVALID_REQUEST' ) {
|
89 |
+
control.find( '.sap-coords-action-wrapper' ).prepend( '<div class="error">' + sap_address.strings.result_invalid + '</div>' );
|
90 |
+
} else if ( data.status == 'INVALID_REQUEST' ) {
|
91 |
+
control.find( '.sap-coords-action-wrapper' ).prepend( '<div class="error">' + sap_address.strings.result_error + '</div>' );
|
92 |
+
} else if ( data.status == 'REQUEST_DENIED' ) {
|
93 |
+
control.find( '.sap-coords-action-wrapper' ).prepend( '<div class="error">' + sap_address.strings.result_denied + '</div>' );
|
94 |
+
} else if ( data.status == 'OVER_QUERY_LIMIT' ) {
|
95 |
+
control.find( '.sap-coords-action-wrapper' ).prepend( '<div class="error">' + sap_address.strings.result_limit + '</div>' );
|
96 |
+
} else if ( data.status == 'ZERO_RESULTS' ) {
|
97 |
+
control.find( '.sap-coords-action-wrapper' ).prepend( '<div class="error">' + sap_address.strings.result_empty + '</div>' );
|
98 |
+
}
|
99 |
+
}
|
100 |
+
}
|
101 |
+
)
|
102 |
+
});
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Remove coordinates from settings
|
106 |
+
*/
|
107 |
+
$('.sap-remove-coords').click( function(e) {
|
108 |
+
|
109 |
+
e.stopPropagation();
|
110 |
+
e.preventDefault();
|
111 |
+
|
112 |
+
var control = $(this).parent().parent();
|
113 |
+
sap_address_set_coords( control, '', '' );
|
114 |
+
});
|
115 |
+
|
116 |
+
});
|
lib/simple-admin-pages/js/admin-settings.js
ADDED
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
jQuery(document).ready(function() {
|
2 |
+
|
3 |
+
if ( ! jQuery.isFunction( jQuery.fn.spectrum ) ) { return; }
|
4 |
+
|
5 |
+
jQuery('.sap-spectrum').spectrum({
|
6 |
+
showInput: true,
|
7 |
+
showInitial: true,
|
8 |
+
preferredFormat: "hex",
|
9 |
+
allowEmpty: true
|
10 |
+
});
|
11 |
+
|
12 |
+
jQuery('.sap-spectrum').css('display', 'inline');
|
13 |
+
|
14 |
+
jQuery('.sap-spectrum').on('change', function() {
|
15 |
+
if (jQuery(this).val() != "") {
|
16 |
+
jQuery(this).css('background', jQuery(this).val());
|
17 |
+
var rgb = EWD_SAP_hexToRgb(jQuery(this).val());
|
18 |
+
var Brightness = (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1000;
|
19 |
+
if (Brightness < 100) {jQuery(this).css('color', '#ffffff');}
|
20 |
+
else {jQuery(this).css('color', '#000000');}
|
21 |
+
}
|
22 |
+
else {
|
23 |
+
jQuery(this).css('background', 'none');
|
24 |
+
}
|
25 |
+
});
|
26 |
+
|
27 |
+
jQuery('.sap-spectrum').each(function() {
|
28 |
+
if (jQuery(this).val() != "") {
|
29 |
+
jQuery(this).css('background', jQuery(this).val());
|
30 |
+
var rgb = EWD_SAP_hexToRgb(jQuery(this).val());
|
31 |
+
var Brightness = (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1000;
|
32 |
+
if (Brightness < 100) {jQuery(this).css('color', '#ffffff');}
|
33 |
+
else {jQuery(this).css('color', '#000000');}
|
34 |
+
}
|
35 |
+
});
|
36 |
+
});
|
37 |
+
|
38 |
+
function EWD_SAP_hexToRgb(hex) {
|
39 |
+
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
40 |
+
return result ? {
|
41 |
+
r: parseInt(result[1], 16),
|
42 |
+
g: parseInt(result[2], 16),
|
43 |
+
b: parseInt(result[3], 16)
|
44 |
+
} : null;
|
45 |
+
}
|
46 |
+
|
47 |
+
//OPTIONS PAGE YES/NO TOGGLE SWITCHES
|
48 |
+
jQuery(document).ready(function($){
|
49 |
+
$('.sap-admin-option-toggle').on('change', function() {
|
50 |
+
var Input_Name = $(this).data('inputname'); console.log(Input_Name);
|
51 |
+
if ($(this).is(':checked')) {
|
52 |
+
$('input[name="' + Input_Name + '"][value="1"]').prop('checked', true).trigger('change');
|
53 |
+
$('input[name="' + Input_Name + '"][value=""]').prop('checked', false);
|
54 |
+
}
|
55 |
+
else {
|
56 |
+
$('input[name="' + Input_Name + '"][value="1"]').prop('checked', false).trigger('change');
|
57 |
+
$('input[name="' + Input_Name + '"][value=""]').prop('checked', true);
|
58 |
+
}
|
59 |
+
});
|
60 |
+
});
|
61 |
+
|
62 |
+
/*LOCK BOXES*/
|
63 |
+
jQuery( document ).ready( function() {
|
64 |
+
setTimeout( resizeLockdownBoxes, 750 );
|
65 |
+
jQuery( window ).on( 'resize', resizeLockdownBoxes );
|
66 |
+
});
|
67 |
+
|
68 |
+
function resizeLockdownBoxes() {
|
69 |
+
jQuery('.sap-premium-options-table-overlay').each(function(){
|
70 |
+
|
71 |
+
var eachProTableOverlay = jQuery( this );
|
72 |
+
var associatedTable = eachProTableOverlay.next();
|
73 |
+
associatedTable.css('min-height', '260px');
|
74 |
+
var tablePosition = associatedTable.position();
|
75 |
+
|
76 |
+
eachProTableOverlay.css( 'width', associatedTable.outerWidth(true) + 'px' );
|
77 |
+
eachProTableOverlay.css( 'height', associatedTable.outerHeight() + 'px' );
|
78 |
+
eachProTableOverlay.css( 'left', tablePosition.left + 'px' );
|
79 |
+
eachProTableOverlay.css( 'top', tablePosition.top + 'px' );
|
80 |
+
});
|
81 |
+
}
|
lib/simple-admin-pages/js/count.js
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
jQuery(document).ready(function() {
|
2 |
+
jQuery('.sap-count-count, .sap-count-unit').on('change', function() {
|
3 |
+
var id = jQuery(this).data('id');
|
4 |
+
|
5 |
+
var count = jQuery('#' + id + '_count').val();
|
6 |
+
var unit = jQuery('#' + id + '_unit').val();
|
7 |
+
|
8 |
+
jQuery('#' + id).val(count + '_' + unit);
|
9 |
+
})
|
10 |
+
})
|
lib/simple-admin-pages/js/file_upload.js
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
jQuery(document).ready(function($){
|
2 |
+
|
3 |
+
var custom_uploader;
|
4 |
+
var input_field;
|
5 |
+
var preview_value;
|
6 |
+
|
7 |
+
jQuery( '.sap-file-upload-button' ).click(function(e) {
|
8 |
+
|
9 |
+
e.preventDefault();
|
10 |
+
|
11 |
+
input_field = jQuery( this ).parent().find( 'input[type="hidden"]' );
|
12 |
+
preview_value = jQuery( this ).parent().find( '.sap-file-upload-preview-value' );
|
13 |
+
|
14 |
+
//If the uploader object has already been created, reopen the dialog
|
15 |
+
if ( custom_uploader ) {
|
16 |
+
custom_uploader.open();
|
17 |
+
return;
|
18 |
+
}
|
19 |
+
|
20 |
+
//Extend the wp.media object
|
21 |
+
custom_uploader = wp.media.frames.file_frame = wp.media({
|
22 |
+
title: 'Choose File',
|
23 |
+
button: {
|
24 |
+
text: 'Choose File'
|
25 |
+
},
|
26 |
+
multiple: false
|
27 |
+
});
|
28 |
+
|
29 |
+
//When a file is selected, grab the URL and set it as the text field's value
|
30 |
+
custom_uploader.on( 'select', function() {
|
31 |
+
|
32 |
+
attachment = custom_uploader.state().get( 'selection' ).first().toJSON();
|
33 |
+
input_field.val( attachment.url );
|
34 |
+
preview_value.html( attachment.url );
|
35 |
+
});
|
36 |
+
|
37 |
+
//Open the uploader dialog
|
38 |
+
custom_uploader.open();
|
39 |
+
|
40 |
+
});
|
41 |
+
});
|
lib/simple-admin-pages/js/image.js
CHANGED
@@ -1,53 +1,53 @@
|
|
1 |
-
/**
|
2 |
-
* Javascript functions for Image component
|
3 |
-
*
|
4 |
-
* @package Simple Admin Pages
|
5 |
-
*/
|
6 |
-
|
7 |
-
jQuery(document).ready(function ($) {
|
8 |
-
|
9 |
-
var current_setting_id;
|
10 |
-
|
11 |
-
function openMediaManager(e) {
|
12 |
-
e.stopPropagation();
|
13 |
-
e.preventDefault();
|
14 |
-
current_setting_id = $( this ).parents( '.sap-image-wrapper' ).data( 'id' );
|
15 |
-
wp.media.frames.
|
16 |
-
}
|
17 |
-
|
18 |
-
function setImage( setting_id, image_id, image_url ) {
|
19 |
-
var $control = $( '.sap-image-wrapper[data-id="' + setting_id + '"]' );
|
20 |
-
$control.find( 'img' ).attr( 'src', image_url );
|
21 |
-
$control.find( '#' + setting_id ).val( image_id );
|
22 |
-
$control.removeClass( 'sap-image-wrapper-no-image' ).addClass( 'sap-image-wrapper-has-image' );
|
23 |
-
}
|
24 |
-
|
25 |
-
function removeImage(e) {
|
26 |
-
e.stopPropagation();
|
27 |
-
e.preventDefault();
|
28 |
-
var $control = $( this ).parents( '.sap-image-wrapper' );
|
29 |
-
$control.find( 'img' ).attr( 'src', '' );
|
30 |
-
$control.find( '#' + $control.data( 'id' ) ).val( '' );
|
31 |
-
$control.removeClass( 'sap-image-wrapper-has-image' ).addClass( 'sap-image-wrapper-no-image' );
|
32 |
-
}
|
33 |
-
|
34 |
-
wp.media.frames.
|
35 |
-
title: 'Select image',
|
36 |
-
multiple: false,
|
37 |
-
library: {
|
38 |
-
type: 'image',
|
39 |
-
},
|
40 |
-
button: {
|
41 |
-
text: 'Use selected image',
|
42 |
-
},
|
43 |
-
} );
|
44 |
-
|
45 |
-
wp.media.frames.
|
46 |
-
var image = wp.media.frames.
|
47 |
-
setImage( current_setting_id, image.id, image.url );
|
48 |
-
});
|
49 |
-
|
50 |
-
$( '.sap-image-wrapper .sap-image-btn-add, .sap-image-wrapper .sap-image-btn-change' ).click(openMediaManager);
|
51 |
-
|
52 |
-
$( '.sap-image-wrapper .sap-image-btn-remove' ).click(removeImage);
|
53 |
-
});
|
1 |
+
/**
|
2 |
+
* Javascript functions for Image component
|
3 |
+
*
|
4 |
+
* @package Simple Admin Pages
|
5 |
+
*/
|
6 |
+
|
7 |
+
jQuery(document).ready(function ($) {
|
8 |
+
|
9 |
+
var current_setting_id;
|
10 |
+
|
11 |
+
function openMediaManager(e) {
|
12 |
+
e.stopPropagation();
|
13 |
+
e.preventDefault();
|
14 |
+
current_setting_id = $( this ).parents( '.sap-image-wrapper' ).data( 'id' );
|
15 |
+
wp.media.frames.sap_frame.open();
|
16 |
+
}
|
17 |
+
|
18 |
+
function setImage( setting_id, image_id, image_url ) {
|
19 |
+
var $control = $( '.sap-image-wrapper[data-id="' + setting_id + '"]' );
|
20 |
+
$control.find( 'img' ).attr( 'src', image_url );
|
21 |
+
$control.find( '#' + setting_id ).val( image_id );
|
22 |
+
$control.removeClass( 'sap-image-wrapper-no-image' ).addClass( 'sap-image-wrapper-has-image' );
|
23 |
+
}
|
24 |
+
|
25 |
+
function removeImage(e) {
|
26 |
+
e.stopPropagation();
|
27 |
+
e.preventDefault();
|
28 |
+
var $control = $( this ).parents( '.sap-image-wrapper' );
|
29 |
+
$control.find( 'img' ).attr( 'src', '' );
|
30 |
+
$control.find( '#' + $control.data( 'id' ) ).val( '' );
|
31 |
+
$control.removeClass( 'sap-image-wrapper-has-image' ).addClass( 'sap-image-wrapper-no-image' );
|
32 |
+
}
|
33 |
+
|
34 |
+
wp.media.frames.sap_frame = wp.media( {
|
35 |
+
title: 'Select image',
|
36 |
+
multiple: false,
|
37 |
+
library: {
|
38 |
+
type: 'image',
|
39 |
+
},
|
40 |
+
button: {
|
41 |
+
text: 'Use selected image',
|
42 |
+
},
|
43 |
+
} );
|
44 |
+
|
45 |
+
wp.media.frames.sap_frame.on( 'select', function() {
|
46 |
+
var image = wp.media.frames.sap_frame.state().get( 'selection' ).first().toJSON();
|
47 |
+
setImage( current_setting_id, image.id, image.url );
|
48 |
+
});
|
49 |
+
|
50 |
+
$( '.sap-image-wrapper .sap-image-btn-add, .sap-image-wrapper .sap-image-btn-change' ).click( openMediaManager );
|
51 |
+
|
52 |
+
$( '.sap-image-wrapper .sap-image-btn-remove' ).click( removeImage );
|
53 |
+
});
|
lib/simple-admin-pages/js/infinite_table.js
ADDED
@@ -0,0 +1,85 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* Javascript functions for Infinite Table
|
3 |
+
*
|
4 |
+
* @package Simple Admin Pages
|
5 |
+
*/
|
6 |
+
|
7 |
+
jQuery(document).ready(function ($) {
|
8 |
+
|
9 |
+
// disable options where not required initially
|
10 |
+
$('.sap-infinite-table table tbody tr').each((idx_tr, tr) => {
|
11 |
+
let val = $(tr).find('[data-name="cf_type"]').val();
|
12 |
+
|
13 |
+
if(!['dropdown', 'checkbox', 'radio'].includes(val)) {
|
14 |
+
$(tr).find('[data-name="cf_options"]').val('').prop('readonly', true);
|
15 |
+
}
|
16 |
+
});
|
17 |
+
|
18 |
+
// process fields
|
19 |
+
$('.sap-parent-form').on('submit', function (ev) {
|
20 |
+
var _form = $(this), ignore;
|
21 |
+
|
22 |
+
$('.sap-infinite-table').each( function() {
|
23 |
+
|
24 |
+
var main_input = $(this).find('#sap-infinite-table-main-input');
|
25 |
+
|
26 |
+
var main_input_val = [];
|
27 |
+
|
28 |
+
$(this).find('table tbody tr').each((idx_tr, tr) => {
|
29 |
+
let record = {}; ignore = false;
|
30 |
+
|
31 |
+
$(tr).find('td').each((idx_td, td) => {
|
32 |
+
let elm = $(td).find('select, input, textarea, checkbox');
|
33 |
+
|
34 |
+
ignore = 'cf_field_name' == elm.data('name') && elm.val().length < 1 ? true : ignore;
|
35 |
+
|
36 |
+
if(!ignore) {
|
37 |
+
|
38 |
+
if ( elm.prop( 'type' ) == 'checkbox' ) { record[ elm.data('name') ] = elm.is( ':checked' ); }
|
39 |
+
else { record[elm.data('name')] = elm.val(); }
|
40 |
+
}
|
41 |
+
});
|
42 |
+
|
43 |
+
!ignore ? main_input_val.push(record) : null;
|
44 |
+
});
|
45 |
+
|
46 |
+
main_input.val(JSON.stringify(main_input_val));
|
47 |
+
|
48 |
+
});
|
49 |
+
});
|
50 |
+
|
51 |
+
// Add new field
|
52 |
+
$('.sap-infinite-table-add-row .sap-new-admin-add-button').on('click', function (ev) {
|
53 |
+
let _template_tr = $( this ).parents( 'tfoot' ).find( '.sap-infinite-table-row-template' ).clone();
|
54 |
+
_template_tr
|
55 |
+
.hide()
|
56 |
+
.removeClass()
|
57 |
+
.addClass('sap-infinite-table-row');
|
58 |
+
$( this ).parents( 'table' ).first().find( 'tbody' ).append(_template_tr);
|
59 |
+
_template_tr.fadeIn('fast');
|
60 |
+
_template_tr.find('[data-name="cf_options"]').prop('readonly', true);
|
61 |
+
});
|
62 |
+
|
63 |
+
// update options field
|
64 |
+
$(document).on('change', '.sap-infinite-table-row [data-name="cf_type"]', function (ev) {
|
65 |
+
let parent_tr = $(this).parents('tr').eq(0);
|
66 |
+
|
67 |
+
if(!['dropdown', 'checkbox', 'radio'].includes($(this).val())) {
|
68 |
+
parent_tr.find('[data-name="cf_options"]').val('').prop('readonly', true);
|
69 |
+
}
|
70 |
+
else {
|
71 |
+
parent_tr.find('[data-name="cf_options"]').prop('readonly', false);
|
72 |
+
}
|
73 |
+
});
|
74 |
+
|
75 |
+
// Remvoe field
|
76 |
+
$(document).on('click', '.sap-infinite-table-row .sap-infinite-table-row-delete', function (ev) {
|
77 |
+
let parent_tr = $(this).parents('tr').eq(0);
|
78 |
+
parent_tr.fadeOut('fast', () => parent_tr.remove());
|
79 |
+
});
|
80 |
+
|
81 |
+
$('.sap-infinite-table table tbody').sortable({
|
82 |
+
axis: 'y'
|
83 |
+
});
|
84 |
+
|
85 |
+
})
|
lib/simple-admin-pages/js/opening-hours.js
CHANGED
@@ -1,20 +1,20 @@
|
|
1 |
-
/**
|
2 |
-
* Javascript functions for Opening Hours component
|
3 |
-
*
|
4 |
-
* @package Simple Admin Pages
|
5 |
-
*/
|
6 |
-
|
7 |
-
jQuery(document).ready(function ($) {
|
8 |
-
|
9 |
-
/**
|
10 |
-
* Opening Hours
|
11 |
-
***************/
|
12 |
-
|
13 |
-
/**
|
14 |
-
* Update the name of each day when the select option is changed
|
15 |
-
*/
|
16 |
-
$( '.sap-opening-hours-day' ).change( function() {
|
17 |
-
$( $(this).data( 'target' ) ).val( $(this).children( 'option:selected' ).data( 'name' ) );
|
18 |
-
});
|
19 |
-
|
20 |
-
});
|
1 |
+
/**
|
2 |
+
* Javascript functions for Opening Hours component
|
3 |
+
*
|
4 |
+
* @package Simple Admin Pages
|
5 |
+
*/
|
6 |
+
|
7 |
+
jQuery(document).ready(function ($) {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Opening Hours
|
11 |
+
***************/
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Update the name of each day when the select option is changed
|
15 |
+
*/
|
16 |
+
$( '.sap-opening-hours-day' ).change( function() {
|
17 |
+
$( $(this).data( 'target' ) ).val( $(this).children( 'option:selected' ).data( 'name' ) );
|
18 |
+
});
|
19 |
+
|
20 |
+
});
|
lib/simple-admin-pages/js/ordering.js
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* Javascript functions for Ordering Table
|
3 |
+
*
|
4 |
+
* @package Simple Admin Pages
|
5 |
+
*/
|
6 |
+
|
7 |
+
jQuery(document).ready(function ($) {
|
8 |
+
|
9 |
+
// process fields
|
10 |
+
$('.sap-parent-form').on('submit', function (ev) {
|
11 |
+
var _form = $(this), ignore;
|
12 |
+
|
13 |
+
$('.sap-ordering-table').each( function() {
|
14 |
+
|
15 |
+
var main_input = $(this).find('#sap-ordering-table-main-input');
|
16 |
+
|
17 |
+
var main_input_val = {};
|
18 |
+
|
19 |
+
$(this).find('table tbody tr').each((idx_tr, tr) => {
|
20 |
+
|
21 |
+
$(tr).find('td').each((idx_td, td) => {
|
22 |
+
let elm = $(td).find('input');
|
23 |
+
|
24 |
+
main_input_val[elm.val()] = $(td).find('span').html();
|
25 |
+
});
|
26 |
+
|
27 |
+
});
|
28 |
+
|
29 |
+
main_input.val(JSON.stringify(main_input_val));
|
30 |
+
|
31 |
+
});
|
32 |
+
});
|
33 |
+
|
34 |
+
$('.sap-ordering-table table tbody').sortable({
|
35 |
+
axis: 'y'
|
36 |
+
});
|
37 |
+
|
38 |
+
})
|
lib/simple-admin-pages/js/scheduler.js
CHANGED
@@ -1,403 +1,403 @@
|
|
1 |
-
/**
|
2 |
-
* Javascript functions for the Scheduler component
|
3 |
-
*
|
4 |
-
* @package Simple Admin Pages
|
5 |
-
*/
|
6 |
-
|
7 |
-
jQuery(document).ready(function ($) {
|
8 |
-
|
9 |
-
/**
|
10 |
-
* Scheduler
|
11 |
-
***********/
|
12 |
-
|
13 |
-
if ( typeof sap_scheduler != 'undefined' ) {
|
14 |
-
|
15 |
-
/**
|
16 |
-
* Register event handlers on the scheduler rules. This is run on page load
|
17 |
-
* and every time a rule is added.
|
18 |
-
*/
|
19 |
-
function sap_scheduler_register_events() {
|
20 |
-
|
21 |
-
/**
|
22 |
-
* Open and close the full view of a scheduling rule
|
23 |
-
*/
|
24 |
-
$( '.sap-scheduler-rule .toggle' ).off( 'click' ).click( function() {
|
25 |
-
|
26 |
-
var controls = $(this).parent();
|
27 |
-
|
28 |
-
if ( $(this).parent().parent().hasClass( 'list' ) ) {
|
29 |
-
controls.hide();
|
30 |
-
$(this).children( '.dashicons-edit' ).removeClass( 'dashicons-edit' ).addClass( 'dashicons-arrow-up-alt2' );
|
31 |
-
controls.siblings( '.sap-scheduler-brief' ).hide();
|
32 |
-
controls.siblings( '.sap-scheduler-date, .sap-scheduler-time' ).slideDown( function() {
|
33 |
-
$(this).parent().removeClass( 'list' );
|
34 |
-
controls.fadeIn();
|
35 |
-
});
|
36 |
-
|
37 |
-
} else {
|
38 |
-
controls.hide();
|
39 |
-
$(this).children( '.dashicons-arrow-up-alt2' ).removeClass( 'dashicons-arrow-up-alt2' ).addClass( 'dashicons-edit' );
|
40 |
-
controls.siblings( '.sap-scheduler-brief' ).fadeIn();
|
41 |
-
controls.siblings( '.sap-scheduler-time' ).slideUp();
|
42 |
-
controls.siblings( '.sap-scheduler-date' ).slideUp( function() {
|
43 |
-
|
44 |
-
var scheduler_rule = $(this).parent();
|
45 |
-
var scheduler_id = scheduler_rule.parent().attr( 'id' );
|
46 |
-
|
47 |
-
scheduler_rule.addClass( 'list' );
|
48 |
-
controls.fadeIn();
|
49 |
-
|
50 |
-
sap_scheduler_set_date_phrase( scheduler_rule, scheduler_id );
|
51 |
-
sap_scheduler_set_time_phrase( scheduler_rule, scheduler_id );
|
52 |
-
});
|
53 |
-
}
|
54 |
-
|
55 |
-
return false;
|
56 |
-
});
|
57 |
-
|
58 |
-
/**
|
59 |
-
* Update current selection for selector lists
|
60 |
-
*/
|
61 |
-
$( '.sap-selector a' ).off( 'switch.sap' ).on( 'switch.sap', function() {
|
62 |
-
$(this).parent().parent().find( 'a' ).removeClass( 'selected' );
|
63 |
-
$(this).addClass( 'selected' );
|
64 |
-
|
65 |
-
return false;
|
66 |
-
});
|
67 |
-
|
68 |
-
/**
|
69 |
-
* Switch between weekly, monthly and date options
|
70 |
-
*/
|
71 |
-
$( '.sap-scheduler-date .sap-selector a' ).off( 'click' ).click( function() {
|
72 |
-
|
73 |
-
$(this).trigger( 'switch.sap' );
|
74 |
-
|
75 |
-
var date = $(this).closest( '.sap-scheduler-date' );
|
76 |
-
|
77 |
-
if ( $(this).data( 'format' ) == 'weekly' && date.hasClass( 'weekly' ) === false ) {
|
78 |
-
date.children( '.sap-scheduler-weeks' ).slideUp( function() {
|
79 |
-
$(this).find( 'input' ).prop('checked', false);
|
80 |
-
});
|
81 |
-
date.children( '.sap-scheduler-date-input' ).slideUp( function() {
|
82 |
-
$(this).find( 'input' ).val( '' );
|
83 |
-
});
|
84 |
-
date.children( '.sap-scheduler-weekdays' ).slideDown( function() {
|
85 |
-
date.removeClass( 'monthly date' );
|
86 |
-
date.addClass( 'weekly' );
|
87 |
-
});
|
88 |
-
|
89 |
-
} else if ( $(this).data( 'format' ) == 'monthly' && date.hasClass( 'monthly' ) === false ) {
|
90 |
-
date.children( '.sap-scheduler-date-input' ).slideUp( function() {
|
91 |
-
$(this).find( 'input' ).val( '' );
|
92 |
-
});
|
93 |
-
date.children( '.sap-scheduler-weekdays' ).slideDown();
|
94 |
-
date.children( '.sap-scheduler-weeks' ).slideDown( function() {
|
95 |
-
date.removeClass( 'weekly date' );
|
96 |
-
date.addClass( 'monthly' );
|
97 |
-
});
|
98 |
-
|
99 |
-
} else if ( $(this).data( 'format' ) == 'date' && date.hasClass( 'date' ) === false ) {
|
100 |
-
date.children( '.sap-scheduler-weekdays' ).slideUp( function() {
|
101 |
-
$(this).find( 'input' ).prop('checked', false);
|
102 |
-
});
|
103 |
-
date.children( '.sap-scheduler-weeks' ).slideUp( function() {
|
104 |
-
$(this).find( 'input' ).prop('checked', false);
|
105 |
-
});
|
106 |
-
date.children( '.sap-scheduler-date-input' ).slideDown( function() {
|
107 |
-
date.removeClass( 'weekly monthly' );
|
108 |
-
date.addClass( 'date' );
|
109 |
-
});
|
110 |
-
}
|
111 |
-
|
112 |
-
return false;
|
113 |
-
});
|
114 |
-
|
115 |
-
/**
|
116 |
-
* Show or hide time slot options
|
117 |
-
*/
|
118 |
-
$( '.sap-scheduler-time .sap-selector a' ).off( 'click' ).click( function() {
|
119 |
-
|
120 |
-
$(this).trigger( 'switch.sap' );
|
121 |
-
|
122 |
-
var time = $(this).closest( '.sap-scheduler-time' );
|
123 |
-
|
124 |
-
if ( $(this).data( 'format' ) == 'time-slot' && time.hasClass( 'time-slot' ) === false ) {
|
125 |
-
time.children( '.sap-scheduler-time-input' ).slideDown();
|
126 |
-
time.children( '.sap-scheduler-all-day' ).slideUp( function() {
|
127 |
-
time.removeClass( 'all-day' );
|
128 |
-
time.addClass( 'time-slot' );
|
129 |
-
});
|
130 |
-
|
131 |
-
} else if ( $(this).data( 'format' ) == 'all-day' && time.hasClass( 'all-day' ) === false ) {
|
132 |
-
time.children( '.sap-scheduler-all-day' ).slideDown();
|
133 |
-
time.children( '.sap-scheduler-time-input' ).slideUp( function() {
|
134 |
-
time.removeClass( 'time-slot' );
|
135 |
-
time.addClass( 'all-day' );
|
136 |
-
time.find( 'input' ).val( '' );
|
137 |
-
});
|
138 |
-
}
|
139 |
-
|
140 |
-
return false;
|
141 |
-
});
|
142 |
-
|
143 |
-
/**
|
144 |
-
* Show time slot options from the link in the all-day notice
|
145 |
-
*/
|
146 |
-
$( '.sap-scheduler-all-day a' ).off( 'click' ).click( function() {
|
147 |
-
$(this).closest( '.sap-scheduler-time' ).children( '.sap-selector' ).find( 'a[data-format="time-slot"]' ).trigger( 'click' );
|
148 |
-
|
149 |
-
return false;
|
150 |
-
});
|
151 |
-
|
152 |
-
/**
|
153 |
-
* Delete a scheduling rule panel
|
154 |
-
*/
|
155 |
-
$( '.sap-scheduler-control .delete' ).off( 'click' ).click( function() {
|
156 |
-
var scheduler = $(this).closest( '.sap-scheduler' );
|
157 |
-
$(this).parent().parent().fadeOut( function() {
|
158 |
-
$(this).remove();
|
159 |
-
|
160 |
-
// Reset the index of each rule
|
161 |
-
// @todo optimize this excessive use of regex (32x per rule).
|
162 |
-
// maybe set a data-slug attribute on .sap-scheduler-rule and a
|
163 |
-
// data-slug prop on each input/select/label, then use these to
|
164 |
-
// construct the new attributes: rule-slug[index][input-slug]
|
165 |
-
scheduler.children( '.sap-scheduler-rule' ).each( function( i ) {
|
166 |
-
var index = i.toString();
|
167 |
-
$(this).find( 'input' ).each( function() {
|
168 |
-
var name = $(this).attr( 'name' ).replace( /\[\d*\]/g, '[' + index + ']' );
|
169 |
-
$(this).attr( 'name', name );
|
170 |
-
$(this).attr( 'id', name );
|
171 |
-
var aria_owns = $(this).attr( 'aria-owns' );
|
172 |
-
if ( typeof aria_owns !== 'undefined' && aria_owns !== false) {
|
173 |
-
$(this).attr( 'aria-owns', name );
|
174 |
-
}
|
175 |
-
});
|
176 |
-
$(this).find( 'label' ).each( function() {
|
177 |
-
var name = $(this).attr( 'for' ).replace( /\[\d*\]/g, '[' + index + ']' );
|
178 |
-
$(this).attr( 'for', name );
|
179 |
-
});
|
180 |
-
$(this).find( '.picker' ).each( function() {
|
181 |
-
var name = $(this).attr( 'id' ).replace( /\[\d*\]/g, '[' + index + ']' );
|
182 |
-
$(this).attr( 'id', name );
|
183 |
-
});
|
184 |
-
});
|
185 |
-
|
186 |
-
// Show the add rule button when multiple rules are
|
187 |
-
// disabled and there are no more children
|
188 |
-
var scheduler_id = scheduler.attr( 'id' );
|
189 |
-
if ( sap_scheduler.settings[scheduler_id].disable_multiple && !scheduler.children().length ) {
|
190 |
-
sap_scheduler_toggle_button( true, scheduler );
|
191 |
-
}
|
192 |
-
});
|
193 |
-
|
194 |
-
return false;
|
195 |
-
});
|
196 |
-
}
|
197 |
-
|
198 |
-
/**
|
199 |
-
* Set the summary phrase for a scheduler rule's date. This phrase is shown
|
200 |
-
* when the rule's view is minimized.
|
201 |
-
*/
|
202 |
-
function sap_scheduler_set_date_phrase( scheduler_rule, scheduler_id ) {
|
203 |
-
|
204 |
-
var date_value = scheduler_rule.find( '.sap-scheduler-date-input input' ).val();
|
205 |
-
if ( typeof date_value !== 'undefined' && date_value != '' ) {
|
206 |
-
scheduler_rule.find( '.sap-scheduler-brief .date .value' ).html( date_value );
|
207 |
-
|
208 |
-
return;
|
209 |
-
}
|
210 |
-
|
211 |
-
var weekdays = 0;
|
212 |
-
var weekday_arr = new Array();
|
213 |
-
scheduler_rule.find( '.sap-scheduler-weekdays input' ).each( function() {
|
214 |
-
if ( $(this).prop( 'checked' ) !== false ) {
|
215 |
-
weekdays += 1;
|
216 |
-
weekday_arr.push( sap_scheduler.settings[scheduler_id]['weekdays'][ $(this).data( 'day' ) ] );
|
217 |
-
}
|
218 |
-
});
|
219 |
-
|
220 |
-
if ( weekdays == 0 && sap_scheduler.settings[ scheduler_id ].disable_weekdays === false ) {
|
221 |
-
scheduler_rule.find( '.sap-scheduler-brief .date .value' ).html( sap_scheduler.settings[scheduler_id].summaries['never'] );
|
222 |
-
|
223 |
-
return;
|
224 |
-
|
225 |
-
} else if ( weekdays == 7 ) {
|
226 |
-
var weekday_string = sap_scheduler.settings[scheduler_id].summaries['weekly_always'];
|
227 |
-
|
228 |
-
} else {
|
229 |
-
var weekday_string = weekday_arr.join( ', ' );
|
230 |
-
}
|
231 |
-
|
232 |
-
var weeks = 0;
|
233 |
-
var weeks_arr = new Array();
|
234 |
-
scheduler_rule.find( '.sap-scheduler-weeks input' ).each( function() {
|
235 |
-
if ( $(this).prop( 'checked' ) !== false ) {
|
236 |
-
weeks +=1;
|
237 |
-
weeks_arr.push( sap_scheduler.settings[scheduler_id]['weeks'][ $(this).data( 'week' ) ] );
|
238 |
-
}
|
239 |
-
});
|
240 |
-
|
241 |
-
if ( ( weeks == 0 || weeks == 5 ) && sap_scheduler.settings[ scheduler_id ].disable_weekdays === false ) {
|
242 |
-
scheduler_rule.find( '.sap-scheduler-brief .date .value' ).html( weekday_string );
|
243 |
-
|
244 |
-
return;
|
245 |
-
}
|
246 |
-
|
247 |
-
if ( weeks == 0 ) {
|
248 |
-
scheduler_rule.find( '.sap-scheduler-brief .date .value' ).html( sap_scheduler.settings[scheduler_id].summaries['never'] );
|
249 |
-
|
250 |
-
return;
|
251 |
-
}
|
252 |
-
|
253 |
-
if ( weekday_string != '' ) {
|
254 |
-
scheduler_rule.find( '.sap-scheduler-brief .date .value' ).html( sap_scheduler.settings[scheduler_id].summaries['monthly_weekdays'].replace( '{days}', weekday_arr.join( ', ' ) ).replace( '{weeks}', weeks_arr.join( ', ' ) ) );
|
255 |
-
} else {
|
256 |
-
scheduler_rule.find( '.sap-scheduler-brief .date .value' ).html( sap_scheduler.settings[scheduler_id].summaries['monthly_weeks'].replace( '{weeks}', weeks_arr.join( ', ' ) ) );
|
257 |
-
}
|
258 |
-
}
|
259 |
-
|
260 |
-
/**
|
261 |
-
* Set the summary phrase for a scheduler rule's time. This phrase is shown
|
262 |
-
* when the rule's view is minimized.
|
263 |
-
*/
|
264 |
-
function sap_scheduler_set_time_phrase( scheduler_rule, scheduler_id ) {
|
265 |
-
|
266 |
-
var start = scheduler_rule.find( '.sap-scheduler-time-input .start input' ).val();
|
267 |
-
var end = scheduler_rule.find( '.sap-scheduler-time-input .end input' ).val();
|
268 |
-
|
269 |
-
if ( start == '' && ( end == '' || typeof end == 'undefined' ) ) {
|
270 |
-
scheduler_rule.find( '.sap-scheduler-brief .time .value' ).html( sap_scheduler.settings[scheduler_id].summaries['all_day'] );
|
271 |
-
|
272 |
-
return;
|
273 |
-
}
|
274 |
-
|
275 |
-
if ( start == '' ) {
|
276 |
-
scheduler_rule.find( '.sap-scheduler-brief .time .value' ).html( sap_scheduler.settings[scheduler_id].summaries['before'] + ' ' + end );
|
277 |
-
|
278 |
-
return;
|
279 |
-
}
|
280 |
-
|
281 |
-
if ( end == '' || typeof end == 'undefined' ) {
|
282 |
-
scheduler_rule.find( '.sap-scheduler-brief .time .value' ).html( sap_scheduler.settings[scheduler_id].summaries['after'] + ' ' + start );
|
283 |
-
|
284 |
-
return;
|
285 |
-
}
|
286 |
-
|
287 |
-
if ( typeof end == 'undefined' ) {
|
288 |
-
return scheduler_rule.find( '.sap-scheduler-brief .time .value' ).html( start );
|
289 |
-
} else {
|
290 |
-
return scheduler_rule.find( '.sap-scheduler-brief .time .value' ).html( start + sap_scheduler.settings[scheduler_id].summaries['separator'] + end );
|
291 |
-
}
|
292 |
-
}
|
293 |
-
|
294 |
-
/**
|
295 |
-
* Register a new datepicker on an element
|
296 |
-
*/
|
297 |
-
function sap_scheduler_register_datepicker( el ) {
|
298 |
-
|
299 |
-
el.pickadate({
|
300 |
-
format: obj.date_format,
|
301 |
-
formatSubmit: 'yyyy/mm/dd',
|
302 |
-
hiddenName: true,
|
303 |
-
|
304 |
-
// Select the value when loaded if a value has been set
|
305 |
-
onStart: function() {
|
306 |
-
if ( this.get() !== '' ) {
|
307 |
-
var date = new Date( this.get() );
|
308 |
-
if ( Object.prototype.toString.call( date ) === "[object Date]" ) {
|
309 |
-
this.set( 'select', date );
|
310 |
-
}
|
311 |
-
}
|
312 |
-
}
|
313 |
-
});
|
314 |
-
}
|
315 |
-
|
316 |
-
/**
|
317 |
-
* Register a new timepicker on an element
|
318 |
-
*/
|
319 |
-
function sap_scheduler_register_timepicker( el ) {
|
320 |
-
|
321 |
-
el.pickatime({
|
322 |
-
interval: obj.time_interval,
|
323 |
-
format: obj.time_format,
|
324 |
-
formatSubmit: 'h:i A',
|
325 |
-
hiddenName: true,
|
326 |
-
|
327 |
-
// Select the value when loaded if a value has been set
|
328 |
-
onStart: function() {
|
329 |
-
if ( this.get() !== '' ) {
|
330 |
-
var today = new Date();
|
331 |
-
var today_date = today.getFullYear() + '/' + ( today.getMonth() + 1 ) + '/' + today.getDate();
|
332 |
-
var time = new Date( today_date + ' ' + this.get() );
|
333 |
-
if ( Object.prototype.toString.call( time ) === "[object Date]" ) {
|
334 |
-
this.set( 'select', time );
|
335 |
-
}
|
336 |
-
}
|
337 |
-
}
|
338 |
-
});
|
339 |
-
}
|
340 |
-
|
341 |
-
|
342 |
-
/**
|
343 |
-
* Register click events on load
|
344 |
-
*/
|
345 |
-
sap_scheduler_register_events();
|
346 |
-
|
347 |
-
/**
|
348 |
-
* Enable datepickers on load
|
349 |
-
*/
|
350 |
-
if ( typeof sap_scheduler.settings != 'undefined' ) {
|
351 |
-
for ( var key in sap_scheduler.settings ) {
|
352 |
-
var obj = sap_scheduler.settings[key];
|
353 |
-
sap_scheduler_register_datepicker( $( '#' + key + ' .sap-scheduler-date-input input[type="text"]' ) );
|
354 |
-
sap_scheduler_register_timepicker( $( '#' + key + ' .sap-scheduler-time-input input[type="text"]' ) );
|
355 |
-
|
356 |
-
$( '#' + key + ' .sap-scheduler-rule' ).each( function() {
|
357 |
-
sap_scheduler_set_date_phrase( $(this), $( '#' + key ).attr( 'id' ) );
|
358 |
-
sap_scheduler_set_time_phrase( $(this), $( '#' + key ).attr( 'id' ) );
|
359 |
-
});
|
360 |
-
}
|
361 |
-
}
|
362 |
-
|
363 |
-
/**
|
364 |
-
* Add a new scheduler panel
|
365 |
-
*/
|
366 |
-
$( '.sap-add-scheduler a' ).click( function(e) {
|
367 |
-
|
368 |
-
if ( $(this).parent().hasClass( 'disabled' ) ) {
|
369 |
-
e.preventDefault();
|
370 |
-
return;
|
371 |
-
}
|
372 |
-
|
373 |
-
var scheduler = $(this).parent().siblings( '.sap-scheduler' );
|
374 |
-
var scheduler_id = scheduler.attr( 'id' );
|
375 |
-
var scheduler_settings = sap_scheduler.settings[ scheduler_id ];
|
376 |
-
scheduler.append( scheduler_settings.template.replace( /\[0\]/g, '[' + scheduler.children( '.sap-scheduler-rule' ).length + ']' ) );
|
377 |
-
sap_scheduler_register_datepicker( scheduler.last( '#' + scheduler_id + ' .sap-scheduler-rule' ).find( '.sap-scheduler-date-input input[type="text"]' ) );
|
378 |
-
sap_scheduler_register_timepicker( scheduler.last( '#' + scheduler_id + ' .sap-scheduler-rule' ).find( '.sap-scheduler-time-input input[type="text"]' ) );
|
379 |
-
sap_scheduler_register_events();
|
380 |
-
|
381 |
-
// Hide the add rule button if we've disabled multiple rules
|
382 |
-
if ( sap_scheduler.settings[scheduler_id].disable_multiple ) {
|
383 |
-
sap_scheduler_toggle_button( false, scheduler );
|
384 |
-
}
|
385 |
-
|
386 |
-
return false;
|
387 |
-
});
|
388 |
-
|
389 |
-
/**
|
390 |
-
* Enable/disable the add new rule button
|
391 |
-
*/
|
392 |
-
function sap_scheduler_toggle_button( on, scheduler ) {
|
393 |
-
if ( on ) {
|
394 |
-
scheduler.siblings( '.sap-add-scheduler' ).removeClass( 'disabled' );
|
395 |
-
} else {
|
396 |
-
scheduler.siblings( '.sap-add-scheduler' ).addClass( 'disabled' );
|
397 |
-
}
|
398 |
-
}
|
399 |
-
|
400 |
-
|
401 |
-
}
|
402 |
-
|
403 |
-
});
|
1 |
+
/**
|
2 |
+
* Javascript functions for the Scheduler component
|
3 |
+
*
|
4 |
+
* @package Simple Admin Pages
|
5 |
+
*/
|
6 |
+
|
7 |
+
jQuery(document).ready(function ($) {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Scheduler
|
11 |
+
***********/
|
12 |
+
|
13 |
+
if ( typeof sap_scheduler != 'undefined' ) {
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Register event handlers on the scheduler rules. This is run on page load
|
17 |
+
* and every time a rule is added.
|
18 |
+
*/
|
19 |
+
function sap_scheduler_register_events() {
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Open and close the full view of a scheduling rule
|
23 |
+
*/
|
24 |
+
$( '.sap-scheduler-rule .toggle' ).off( 'click' ).click( function() {
|
25 |
+
|
26 |
+
var controls = $(this).parent();
|
27 |
+
|
28 |
+
if ( $(this).parent().parent().hasClass( 'list' ) ) {
|
29 |
+
controls.hide();
|
30 |
+
$(this).children( '.dashicons-edit' ).removeClass( 'dashicons-edit' ).addClass( 'dashicons-arrow-up-alt2' );
|
31 |
+
controls.siblings( '.sap-scheduler-brief' ).hide();
|
32 |
+
controls.siblings( '.sap-scheduler-date, .sap-scheduler-time' ).slideDown( function() {
|
33 |
+
$(this).parent().removeClass( 'list' );
|
34 |
+
controls.fadeIn();
|
35 |
+
});
|
36 |
+
|
37 |
+
} else {
|
38 |
+
controls.hide();
|
39 |
+
$(this).children( '.dashicons-arrow-up-alt2' ).removeClass( 'dashicons-arrow-up-alt2' ).addClass( 'dashicons-edit' );
|
40 |
+
controls.siblings( '.sap-scheduler-brief' ).fadeIn();
|
41 |
+
controls.siblings( '.sap-scheduler-time' ).slideUp();
|
42 |
+
controls.siblings( '.sap-scheduler-date' ).slideUp( function() {
|
43 |
+
|
44 |
+
var scheduler_rule = $(this).parent();
|
45 |
+
var scheduler_id = scheduler_rule.parent().attr( 'id' );
|
46 |
+
|
47 |
+
scheduler_rule.addClass( 'list' );
|
48 |
+
controls.fadeIn();
|
49 |
+
|
50 |
+
sap_scheduler_set_date_phrase( scheduler_rule, scheduler_id );
|
51 |
+
sap_scheduler_set_time_phrase( scheduler_rule, scheduler_id );
|
52 |
+
});
|
53 |
+
}
|
54 |
+
|
55 |
+
return false;
|
56 |
+
});
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Update current selection for selector lists
|
60 |
+
*/
|
61 |
+
$( '.sap-selector a' ).off( 'switch.sap' ).on( 'switch.sap', function() {
|
62 |
+
$(this).parent().parent().find( 'a' ).removeClass( 'selected' );
|
63 |
+
$(this).addClass( 'selected' );
|
64 |
+
|
65 |
+
return false;
|
66 |
+
});
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Switch between weekly, monthly and date options
|
70 |
+
*/
|
71 |
+
$( '.sap-scheduler-date .sap-selector a' ).off( 'click' ).click( function() {
|
72 |
+
|
73 |
+
$(this).trigger( 'switch.sap' );
|
74 |
+
|
75 |
+
var date = $(this).closest( '.sap-scheduler-date' );
|
76 |
+
|
77 |
+
if ( $(this).data( 'format' ) == 'weekly' && date.hasClass( 'weekly' ) === false ) {
|
78 |
+
date.children( '.sap-scheduler-weeks' ).slideUp( function() {
|
79 |
+
$(this).find( 'input' ).prop('checked', false);
|
80 |
+
});
|
81 |
+
date.children( '.sap-scheduler-date-input' ).slideUp( function() {
|
82 |
+
$(this).find( 'input' ).val( '' );
|
83 |
+
});
|
84 |
+
date.children( '.sap-scheduler-weekdays' ).slideDown( function() {
|
85 |
+
date.removeClass( 'monthly date' );
|
86 |
+
date.addClass( 'weekly' );
|
87 |
+
});
|
88 |
+
|
89 |
+
} else if ( $(this).data( 'format' ) == 'monthly' && date.hasClass( 'monthly' ) === false ) {
|
90 |
+
date.children( '.sap-scheduler-date-input' ).slideUp( function() {
|
91 |
+
$(this).find( 'input' ).val( '' );
|
92 |
+
});
|
93 |
+
date.children( '.sap-scheduler-weekdays' ).slideDown();
|
94 |
+
date.children( '.sap-scheduler-weeks' ).slideDown( function() {
|
95 |
+
date.removeClass( 'weekly date' );
|
96 |
+
date.addClass( 'monthly' );
|
97 |
+
});
|
98 |
+
|
99 |
+
} else if ( $(this).data( 'format' ) == 'date' && date.hasClass( 'date' ) === false ) {
|
100 |
+
date.children( '.sap-scheduler-weekdays' ).slideUp( function() {
|
101 |
+
$(this).find( 'input' ).prop('checked', false);
|
102 |
+
});
|
103 |
+
date.children( '.sap-scheduler-weeks' ).slideUp( function() {
|
104 |
+
$(this).find( 'input' ).prop('checked', false);
|
105 |
+
});
|
106 |
+
date.children( '.sap-scheduler-date-input' ).slideDown( function() {
|
107 |
+
date.removeClass( 'weekly monthly' );
|
108 |
+
date.addClass( 'date' );
|
109 |
+
});
|
110 |
+
}
|
111 |
+
|
112 |
+
return false;
|
113 |
+
});
|
114 |
+
|
115 |
+
/**
|
116 |
+
* Show or hide time slot options
|
117 |
+
*/
|
118 |
+
$( '.sap-scheduler-time .sap-selector a' ).off( 'click' ).click( function() {
|
119 |
+
|
120 |
+
$(this).trigger( 'switch.sap' );
|
121 |
+
|
122 |
+
var time = $(this).closest( '.sap-scheduler-time' );
|
123 |
+
|
124 |
+
if ( $(this).data( 'format' ) == 'time-slot' && time.hasClass( 'time-slot' ) === false ) {
|
125 |
+
time.children( '.sap-scheduler-time-input' ).slideDown();
|
126 |
+
time.children( '.sap-scheduler-all-day' ).slideUp( function() {
|
127 |
+
time.removeClass( 'all-day' );
|
128 |
+
time.addClass( 'time-slot' );
|
129 |
+
});
|
130 |
+
|
131 |
+
} else if ( $(this).data( 'format' ) == 'all-day' && time.hasClass( 'all-day' ) === false ) {
|
132 |
+
time.children( '.sap-scheduler-all-day' ).slideDown();
|
133 |
+
time.children( '.sap-scheduler-time-input' ).slideUp( function() {
|
134 |
+
time.removeClass( 'time-slot' );
|
135 |
+
time.addClass( 'all-day' );
|
136 |
+
time.find( 'input' ).val( '' );
|
137 |
+
});
|
138 |
+
}
|
139 |
+
|
140 |
+
return false;
|
141 |
+
});
|
142 |
+
|
143 |
+
/**
|
144 |
+
* Show time slot options from the link in the all-day notice
|
145 |
+
*/
|
146 |
+
$( '.sap-scheduler-all-day a' ).off( 'click' ).click( function() {
|
147 |
+
$(this).closest( '.sap-scheduler-time' ).children( '.sap-selector' ).find( 'a[data-format="time-slot"]' ).trigger( 'click' );
|
148 |
+
|
149 |
+
return false;
|
150 |
+
});
|
151 |
+
|
152 |
+
/**
|
153 |
+
* Delete a scheduling rule panel
|
154 |
+
*/
|
155 |
+
$( '.sap-scheduler-control .delete' ).off( 'click' ).click( function() {
|
156 |
+
var scheduler = $(this).closest( '.sap-scheduler' );
|
157 |
+
$(this).parent().parent().fadeOut( function() {
|
158 |
+
$(this).remove();
|
159 |
+
|
160 |
+
// Reset the index of each rule
|
161 |
+
// @todo optimize this excessive use of regex (32x per rule).
|
162 |
+
// maybe set a data-slug attribute on .sap-scheduler-rule and a
|
163 |
+
// data-slug prop on each input/select/label, then use these to
|
164 |
+
// construct the new attributes: rule-slug[index][input-slug]
|
165 |
+
scheduler.children( '.sap-scheduler-rule' ).each( function( i ) {
|
166 |
+
var index = i.toString();
|
167 |
+
$(this).find( 'input' ).each( function() {
|
168 |
+
var name = $(this).attr( 'name' ).replace( /\[\d*\]/g, '[' + index + ']' );
|
169 |
+
$(this).attr( 'name', name );
|
170 |
+
$(this).attr( 'id', name );
|
171 |
+
var aria_owns = $(this).attr( 'aria-owns' );
|
172 |
+
if ( typeof aria_owns !== 'undefined' && aria_owns !== false) {
|
173 |
+
$(this).attr( 'aria-owns', name );
|
174 |
+
}
|
175 |
+
});
|
176 |
+
$(this).find( 'label' ).each( function() {
|
177 |
+
var name = $(this).attr( 'for' ).replace( /\[\d*\]/g, '[' + index + ']' );
|
178 |
+
$(this).attr( 'for', name );
|
179 |
+
});
|
180 |
+
$(this).find( '.picker' ).each( function() {
|
181 |
+
var name = $(this).attr( 'id' ).replace( /\[\d*\]/g, '[' + index + ']' );
|
182 |
+
$(this).attr( 'id', name );
|
183 |
+
});
|
184 |
+
});
|
185 |
+
|
186 |
+
// Show the add rule button when multiple rules are
|
187 |
+
// disabled and there are no more children
|
188 |
+
var scheduler_id = scheduler.attr( 'id' );
|
189 |
+
if ( sap_scheduler.settings[scheduler_id].disable_multiple && !scheduler.children().length ) {
|
190 |
+
sap_scheduler_toggle_button( true, scheduler );
|
191 |
+
}
|
192 |
+
});
|
193 |
+
|
194 |
+
return false;
|
195 |
+
});
|
196 |
+
}
|
197 |
+
|
198 |
+
/**
|
199 |
+
* Set the summary phrase for a scheduler rule's date. This phrase is shown
|
200 |
+
* when the rule's view is minimized.
|
201 |
+
*/
|
202 |
+
function sap_scheduler_set_date_phrase( scheduler_rule, scheduler_id ) {
|
203 |
+
|
204 |
+
var date_value = scheduler_rule.find( '.sap-scheduler-date-input input' ).val();
|
205 |
+
if ( typeof date_value !== 'undefined' && date_value != '' ) {
|
206 |
+
scheduler_rule.find( '.sap-scheduler-brief .date .value' ).html( date_value );
|
207 |
+
|
208 |
+
return;
|
209 |
+
}
|
210 |
+
|
211 |
+
var weekdays = 0;
|
212 |
+
var weekday_arr = new Array();
|
213 |
+
scheduler_rule.find( '.sap-scheduler-weekdays input' ).each( function() {
|
214 |
+
if ( $(this).prop( 'checked' ) !== false ) {
|
215 |
+
weekdays += 1;
|
216 |
+
weekday_arr.push( sap_scheduler.settings[scheduler_id]['weekdays'][ $(this).data( 'day' ) ] );
|
217 |
+
}
|
218 |
+
});
|
219 |
+
|
220 |
+
if ( weekdays == 0 && sap_scheduler.settings[ scheduler_id ].disable_weekdays === false ) {
|
221 |
+
scheduler_rule.find( '.sap-scheduler-brief .date .value' ).html( sap_scheduler.settings[scheduler_id].summaries['never'] );
|
222 |
+
|
223 |
+
return;
|
224 |
+
|
225 |
+
} else if ( weekdays == 7 ) {
|
226 |
+
var weekday_string = sap_scheduler.settings[scheduler_id].summaries['weekly_always'];
|
227 |
+
|
228 |
+
} else {
|
229 |
+
var weekday_string = weekday_arr.join( ', ' );
|
230 |
+
}
|
231 |
+
|
232 |
+
var weeks = 0;
|
233 |
+
var weeks_arr = new Array();
|
234 |
+
scheduler_rule.find( '.sap-scheduler-weeks input' ).each( function() {
|
235 |
+
if ( $(this).prop( 'checked' ) !== false ) {
|
236 |
+
weeks +=1;
|
237 |
+
weeks_arr.push( sap_scheduler.settings[scheduler_id]['weeks'][ $(this).data( 'week' ) ] );
|
238 |
+
}
|
239 |
+
});
|
240 |
+
|
241 |
+
if ( ( weeks == 0 || weeks == 5 ) && sap_scheduler.settings[ scheduler_id ].disable_weekdays === false ) {
|
242 |
+
scheduler_rule.find( '.sap-scheduler-brief .date .value' ).html( weekday_string );
|
243 |
+
|
244 |
+
return;
|
245 |
+
}
|
246 |
+
|
247 |
+
if ( weeks == 0 ) {
|
248 |
+
scheduler_rule.find( '.sap-scheduler-brief .date .value' ).html( sap_scheduler.settings[scheduler_id].summaries['never'] );
|
249 |
+
|
250 |
+
return;
|
251 |
+
}
|
252 |
+
|
253 |
+
if ( weekday_string != '' ) {
|
254 |
+
scheduler_rule.find( '.sap-scheduler-brief .date .value' ).html( sap_scheduler.settings[scheduler_id].summaries['monthly_weekdays'].replace( '{days}', weekday_arr.join( ', ' ) ).replace( '{weeks}', weeks_arr.join( ', ' ) ) );
|
255 |
+
} else {
|
256 |
+
scheduler_rule.find( '.sap-scheduler-brief .date .value' ).html( sap_scheduler.settings[scheduler_id].summaries['monthly_weeks'].replace( '{weeks}', weeks_arr.join( ', ' ) ) );
|
257 |
+
}
|
258 |
+
}
|
259 |
+
|
260 |
+
/**
|
261 |
+
* Set the summary phrase for a scheduler rule's time. This phrase is shown
|
262 |
+
* when the rule's view is minimized.
|
263 |
+
*/
|
264 |
+
function sap_scheduler_set_time_phrase( scheduler_rule, scheduler_id ) {
|
265 |
+
|
266 |
+
var start = scheduler_rule.find( '.sap-scheduler-time-input .start input' ).val();
|
267 |
+
var end = scheduler_rule.find( '.sap-scheduler-time-input .end input' ).val();
|
268 |
+
|
269 |
+
if ( start == '' && ( end == '' || typeof end == 'undefined' ) ) {
|
270 |
+
scheduler_rule.find( '.sap-scheduler-brief .time .value' ).html( sap_scheduler.settings[scheduler_id].summaries['all_day'] );
|
271 |
+
|
272 |
+
return;
|
273 |
+
}
|
274 |
+
|
275 |
+
if ( start == '' ) {
|
276 |
+
scheduler_rule.find( '.sap-scheduler-brief .time .value' ).html( sap_scheduler.settings[scheduler_id].summaries['before'] + ' ' + end );
|
277 |
+
|
278 |
+
return;
|
279 |
+
}
|
280 |
+
|
281 |
+
if ( end == '' || typeof end == 'undefined' ) {
|
282 |
+
scheduler_rule.find( '.sap-scheduler-brief .time .value' ).html( sap_scheduler.settings[scheduler_id].summaries['after'] + ' ' + start );
|
283 |
+
|
284 |
+
return;
|
285 |
+
}
|
286 |
+
|
287 |
+
if ( typeof end == 'undefined' ) {
|
288 |
+
return scheduler_rule.find( '.sap-scheduler-brief .time .value' ).html( start );
|
289 |
+
} else {
|
290 |
+
return scheduler_rule.find( '.sap-scheduler-brief .time .value' ).html( start + sap_scheduler.settings[scheduler_id].summaries['separator'] + end );
|
291 |
+
}
|
292 |
+
}
|
293 |
+
|
294 |
+
/**
|
295 |
+
* Register a new datepicker on an element
|
296 |
+
*/
|
297 |
+
function sap_scheduler_register_datepicker( el ) {
|
298 |
+
|
299 |
+
el.pickadate({
|
300 |
+
format: obj.date_format,
|
301 |
+
formatSubmit: 'yyyy/mm/dd',
|
302 |
+
hiddenName: true,
|
303 |
+
|
304 |
+
// Select the value when loaded if a value has been set
|
305 |
+
onStart: function() {
|
306 |
+
if ( this.get() !== '' ) {
|
307 |
+
var date = new Date( this.get() );
|
308 |
+
if ( Object.prototype.toString.call( date ) === "[object Date]" ) {
|
309 |
+
this.set( 'select', date );
|
310 |
+
}
|
311 |
+
}
|
312 |
+
}
|
313 |
+
});
|
314 |
+
}
|
315 |
+
|
316 |
+
/**
|
317 |
+
* Register a new timepicker on an element
|
318 |
+
*/
|
319 |
+
function sap_scheduler_register_timepicker( el ) {
|
320 |
+
|
321 |
+
el.pickatime({
|
322 |
+
interval: obj.time_interval,
|
323 |
+
format: obj.time_format,
|
324 |
+
formatSubmit: 'h:i A',
|
325 |
+
hiddenName: true,
|
326 |
+
|
327 |
+
// Select the value when loaded if a value has been set
|
328 |
+
onStart: function() {
|
329 |
+
if ( this.get() !== '' ) {
|
330 |
+
var today = new Date();
|
331 |
+
var today_date = today.getFullYear() + '/' + ( today.getMonth() + 1 ) + '/' + today.getDate();
|
332 |
+
var time = new Date( today_date + ' ' + this.get() );
|
333 |
+
if ( Object.prototype.toString.call( time ) === "[object Date]" ) {
|
334 |
+
this.set( 'select', time );
|
335 |
+
}
|
336 |
+
}
|
337 |
+
}
|
338 |
+
});
|
339 |
+
}
|
340 |
+
|
341 |
+
|
342 |
+
/**
|
343 |
+
* Register click events on load
|
344 |
+
*/
|
345 |
+
sap_scheduler_register_events();
|
346 |
+
|
347 |
+
/**
|
348 |
+
* Enable datepickers on load
|
349 |
+
*/
|
350 |
+
if ( typeof sap_scheduler.settings != 'undefined' ) {
|
351 |
+
for ( var key in sap_scheduler.settings ) {
|
352 |
+
var obj = sap_scheduler.settings[key];
|
353 |
+
sap_scheduler_register_datepicker( $( '#' + key + ' .sap-scheduler-date-input input[type="text"]' ) );
|
354 |
+
sap_scheduler_register_timepicker( $( '#' + key + ' .sap-scheduler-time-input input[type="text"]' ) );
|
355 |
+
|
356 |
+
$( '#' + key + ' .sap-scheduler-rule' ).each( function() {
|
357 |
+
sap_scheduler_set_date_phrase( $(this), $( '#' + key ).attr( 'id' ) );
|
358 |
+
sap_scheduler_set_time_phrase( $(this), $( '#' + key ).attr( 'id' ) );
|
359 |
+
});
|
360 |
+
}
|
361 |
+
}
|
362 |
+
|
363 |
+
/**
|
364 |
+
* Add a new scheduler panel
|
365 |
+
*/
|
366 |
+
$( '.sap-add-scheduler a' ).click( function(e) {
|
367 |
+
|
368 |
+
if ( $(this).parent().hasClass( 'disabled' ) ) {
|
369 |
+
e.preventDefault();
|
370 |
+
return;
|
371 |
+
}
|
372 |
+
|
373 |
+
var scheduler = $(this).parent().siblings( '.sap-scheduler' );
|
374 |
+
var scheduler_id = scheduler.attr( 'id' );
|
375 |
+
var scheduler_settings = sap_scheduler.settings[ scheduler_id ];
|
376 |
+
scheduler.append( scheduler_settings.template.replace( /\[0\]/g, '[' + scheduler.children( '.sap-scheduler-rule' ).length + ']' ) );
|
377 |
+
sap_scheduler_register_datepicker( scheduler.last( '#' + scheduler_id + ' .sap-scheduler-rule' ).find( '.sap-scheduler-date-input input[type="text"]' ) );
|
378 |
+
sap_scheduler_register_timepicker( scheduler.last( '#' + scheduler_id + ' .sap-scheduler-rule' ).find( '.sap-scheduler-time-input input[type="text"]' ) );
|
379 |
+
sap_scheduler_register_events();
|
380 |
+
|
381 |
+
// Hide the add rule button if we've disabled multiple rules
|
382 |
+
if ( sap_scheduler.settings[scheduler_id].disable_multiple ) {
|
383 |
+
sap_scheduler_toggle_button( false, scheduler );
|
384 |
+
}
|
385 |
+
|
386 |
+
return false;
|
387 |
+
});
|
388 |
+
|
389 |
+
/**
|
390 |
+
* Enable/disable the add new rule button
|
391 |
+
*/
|
392 |
+
function sap_scheduler_toggle_button( on, scheduler ) {
|
393 |
+
if ( on ) {
|
394 |
+
scheduler.siblings( '.sap-add-scheduler' ).removeClass( 'disabled' );
|
395 |
+
} else {
|
396 |
+
scheduler.siblings( '.sap-add-scheduler' ).addClass( 'disabled' );
|
397 |
+
}
|
398 |
+
}
|
399 |
+
|
400 |
+
|
401 |
+
}
|
402 |
+
|
403 |
+
});
|
lib/simple-admin-pages/js/spectrum.js
ADDED
@@ -0,0 +1,2317 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// Spectrum Colorpicker v1.7.1
|
2 |
+
// https://github.com/bgrins/spectrum
|
3 |
+
// Author: Brian Grinstead
|
4 |
+
// License: MIT
|
5 |
+
|
6 |
+
(function (factory) {
|
7 |
+
"use strict";
|
8 |
+
|
9 |
+
if (typeof define === 'function' && define.amd) { // AMD
|
10 |
+
define(['jquery'], factory);
|
11 |
+
}
|
12 |
+
else if (typeof exports == "object" && typeof module == "object") { // CommonJS
|
13 |
+
module.exports = factory;
|
14 |
+
}
|
15 |
+
else { // Browser
|
16 |
+
factory(jQuery);
|
17 |
+
}
|
18 |
+
})(function($, undefined) {
|
19 |
+
"use strict";
|
20 |
+
|
21 |
+
var defaultOpts = {
|
22 |
+
|
23 |
+
// Callbacks
|
24 |
+
beforeShow: noop,
|
25 |
+
move: noop,
|
26 |
+
change: noop,
|
27 |
+
show: noop,
|
28 |
+
hide: noop,
|
29 |
+
|
30 |
+
// Options
|
31 |
+
color: false,
|
32 |
+
flat: false,
|
33 |
+
showInput: false,
|
34 |
+
allowEmpty: false,
|
35 |
+
showButtons: true,
|
36 |
+
clickoutFiresChange: true,
|
37 |
+
showInitial: false,
|
38 |
+
showPalette: false,
|
39 |
+
showPaletteOnly: false,
|
40 |
+
hideAfterPaletteSelect: false,
|
41 |
+
togglePaletteOnly: false,
|
42 |
+
showSelectionPalette: true,
|
43 |
+
localStorageKey: false,
|
44 |
+
appendTo: "body",
|
45 |
+
maxSelectionSize: 7,
|
46 |
+
cancelText: "cancel",
|
47 |
+
chooseText: "choose",
|
48 |
+
togglePaletteMoreText: "more",
|
49 |
+
togglePaletteLessText: "less",
|
50 |
+
clearText: "Clear Color Selection",
|
51 |
+
noColorSelectedText: "No Color Selected",
|
52 |
+
preferredFormat: false,
|
53 |
+
className: "", // Deprecated - use containerClassName and replacerClassName instead.
|
54 |
+
containerClassName: "",
|
55 |
+
replacerClassName: "",
|
56 |
+
showAlpha: false,
|
57 |
+
theme: "sp-light",
|
58 |
+
palette: [["#ffffff", "#000000", "#ff0000", "#ff8000", "#ffff00", "#008000", "#0000ff", "#4b0082", "#9400d3"]],
|
59 |
+
selectionPalette: [],
|
60 |
+
disabled: false,
|
61 |
+
offset: null
|
62 |
+
},
|
63 |
+
spectrums = [],
|
64 |
+
IE = !!/msie/i.exec( window.navigator.userAgent ),
|
65 |
+
rgbaSupport = (function() {
|
66 |
+
function contains( str, substr ) {
|
67 |
+
return !!~('' + str).indexOf(substr);
|
68 |
+
}
|
69 |
+
|
70 |
+
var elem = document.createElement('div');
|
71 |
+
var style = elem.style;
|
72 |
+
style.cssText = 'background-color:rgba(0,0,0,.5)';
|
73 |
+
return contains(style.backgroundColor, 'rgba') || contains(style.backgroundColor, 'hsla');
|
74 |
+
})(),
|
75 |
+
replaceInput = [
|
76 |
+
"<div class='sp-replacer'>",
|
77 |
+
"<div class='sp-preview'><div class='sp-preview-inner'></div></div>",
|
78 |
+
"<div class='sp-dd'>▼</div>",
|
79 |
+
"</div>"
|
80 |
+
].join(''),
|
81 |
+
markup = (function () {
|
82 |
+
|
83 |
+
// IE does not support gradients with multiple stops, so we need to simulate
|
84 |
+
// that for the rainbow slider with 8 divs that each have a single gradient
|
85 |
+
var gradientFix = "";
|
86 |
+
if (IE) {
|
87 |
+
for (var i = 1; i <= 6; i++) {
|
88 |
+
gradientFix += "<div class='sp-" + i + "'></div>";
|
89 |
+
}
|
90 |
+
}
|
91 |
+
|
92 |
+
return [
|
93 |
+
"<div class='sp-container sp-hidden'>",
|
94 |
+
"<div class='sp-palette-container'>",
|
95 |
+
"<div class='sp-palette sp-thumb sp-cf'></div>",
|
96 |
+
"<div class='sp-palette-button-container sp-cf'>",
|
97 |
+
"<button type='button' class='sp-palette-toggle'></button>",
|
98 |
+
"</div>",
|
99 |
+
"</div>",
|
100 |
+
"<div class='sp-picker-container'>",
|
101 |
+
"<div class='sp-top sp-cf'>",
|
102 |
+
"<div class='sp-fill'></div>",
|
103 |
+
"<div class='sp-top-inner'>",
|
104 |
+
"<div class='sp-color'>",
|
105 |
+
"<div class='sp-sat'>",
|
106 |
+
"<div class='sp-val'>",
|
107 |
+
"<div class='sp-dragger'></div>",
|
108 |
+
"</div>",
|
109 |
+
"</div>",
|
110 |
+
"</div>",
|
111 |
+
"<div class='sp-clear sp-clear-display'>",
|
112 |
+
"</div>",
|
113 |
+
"<div class='sp-hue'>",
|
114 |
+
"<div class='sp-slider'></div>",
|
115 |
+
gradientFix,
|
116 |
+
"</div>",
|
117 |
+
"</div>",
|
118 |
+
"<div class='sp-alpha'><div class='sp-alpha-inner'><div class='sp-alpha-handle'></div></div></div>",
|
119 |
+
"</div>",
|
120 |
+
"<div class='sp-input-container sp-cf'>",
|
121 |
+
"<input class='sp-input' type='text' spellcheck='false' />",
|
122 |
+
"</div>",
|
123 |
+
"<div class='sp-initial sp-thumb sp-cf'></div>",
|
124 |
+
"<div class='sp-button-container sp-cf'>",
|
125 |
+
"<a class='sp-cancel' href='#'></a>",
|
126 |
+
"<button type='button' class='sp-choose'></button>",
|
127 |
+
"</div>",
|
128 |
+
"</div>",
|
129 |
+
"</div>"
|
130 |
+
].join("");
|
131 |
+
})();
|
132 |
+
|
133 |
+
function paletteTemplate (p, color, className, opts) {
|
134 |
+
var html = [];
|
135 |
+
for (var i = 0; i < p.length; i++) {
|
136 |
+
var current = p[i];
|
137 |
+
if(current) {
|
138 |
+
var tiny = tinycolor(current);
|
139 |
+
var c = tiny.toHsl().l < 0.5 ? "sp-thumb-el sp-thumb-dark" : "sp-thumb-el sp-thumb-light";
|
140 |
+
c += (tinycolor.equals(color, current)) ? " sp-thumb-active" : "";
|
141 |
+
var formattedString = tiny.toString(opts.preferredFormat || "rgb");
|
142 |
+
var swatchStyle = rgbaSupport ? ("background-color:" + tiny.toRgbString()) : "filter:" + tiny.toFilter();
|
143 |
+
html.push('<span title="' + formattedString + '" data-color="' + tiny.toRgbString() + '" class="' + c + '"><span class="sp-thumb-inner" style="' + swatchStyle + ';" /></span>');
|
144 |
+
} else {
|
145 |
+
var cls = 'sp-clear-display';
|
146 |
+
html.push($('<div />')
|
147 |
+
.append($('<span data-color="" style="background-color:transparent;" class="' + cls + '"></span>')
|
148 |
+
.attr('title', opts.noColorSelectedText)
|
149 |
+
)
|
150 |
+
.html()
|
151 |
+
);
|
152 |
+
}
|
153 |
+
}
|
154 |
+
return "<div class='sp-cf " + className + "'>" + html.join('') + "</div>";
|
155 |
+
}
|
156 |
+
|
157 |
+
function hideAll() {
|
158 |
+
for (var i = 0; i < spectrums.length; i++) {
|
159 |
+
if (spectrums[i]) {
|
160 |
+
spectrums[i].hide();
|
161 |
+
}
|
162 |
+
}
|
163 |
+
}
|
164 |
+
|
165 |
+
function instanceOptions(o, callbackContext) {
|
166 |
+
var opts = $.extend({}, defaultOpts, o);
|
167 |
+
opts.callbacks = {
|
168 |
+
'move': bind(opts.move, callbackContext),
|
169 |
+
'change': bind(opts.change, callbackContext),
|
170 |
+
'show': bind(opts.show, callbackContext),
|
171 |
+
'hide': bind(opts.hide, callbackContext),
|
172 |
+
'beforeShow': bind(opts.beforeShow, callbackContext)
|
173 |
+
};
|
174 |
+
|
175 |
+
return opts;
|
176 |
+
}
|
177 |
+
|
178 |
+
function spectrum(element, o) {
|
179 |
+
|
180 |
+
var opts = instanceOptions(o, element),
|
181 |
+
flat = opts.flat,
|
182 |
+
showSelectionPalette = opts.showSelectionPalette,
|
183 |
+
localStorageKey = opts.localStorageKey,
|
184 |
+
theme = opts.theme,
|
185 |
+
callbacks = opts.callbacks,
|
186 |
+
resize = throttle(reflow, 10),
|
187 |
+
visible = false,
|
188 |
+
isDragging = false,
|
189 |
+
dragWidth = 0,
|
190 |
+
dragHeight = 0,
|
191 |
+
dragHelperHeight = 0,
|
192 |
+
slideHeight = 0,
|
193 |
+
slideWidth = 0,
|
194 |
+
alphaWidth = 0,
|
195 |
+
alphaSlideHelperWidth = 0,
|
196 |
+
slideHelperHeight = 0,
|
197 |
+
currentHue = 0,
|
198 |
+
currentSaturation = 0,
|
199 |
+
currentValue = 0,
|
200 |
+
currentAlpha = 1,
|
201 |
+
palette = [],
|
202 |
+
paletteArray = [],
|
203 |
+
paletteLookup = {},
|
204 |
+
selectionPalette = opts.selectionPalette.slice(0),
|
205 |
+
maxSelectionSize = opts.maxSelectionSize,
|
206 |
+
draggingClass = "sp-dragging",
|
207 |
+
shiftMovementDirection = null;
|
208 |
+
|
209 |
+
var doc = element.ownerDocument,
|
210 |
+
body = doc.body,
|
211 |
+
boundElement = $(element),
|
212 |
+
disabled = false,
|
213 |
+
container = $(markup, doc).addClass(theme),
|
214 |
+
pickerContainer = container.find(".sp-picker-container"),
|
215 |
+
dragger = container.find(".sp-color"),
|
216 |
+
dragHelper = container.find(".sp-dragger"),
|
217 |
+
slider = container.find(".sp-hue"),
|
218 |
+
slideHelper = container.find(".sp-slider"),
|
219 |
+
alphaSliderInner = container.find(".sp-alpha-inner"),
|
220 |
+
alphaSlider = container.find(".sp-alpha"),
|
221 |
+
alphaSlideHelper = container.find(".sp-alpha-handle"),
|
222 |
+
textInput = container.find(".sp-input"),
|
223 |
+
paletteContainer = container.find(".sp-palette"),
|
224 |
+
initialColorContainer = container.find(".sp-initial"),
|
225 |
+
cancelButton = container.find(".sp-cancel"),
|
226 |
+
clearButton = container.find(".sp-clear"),
|
227 |
+
chooseButton = container.find(".sp-choose"),
|
228 |
+
toggleButton = container.find(".sp-palette-toggle"),
|
229 |
+
isInput = boundElement.is("input"),
|
230 |
+
isInputTypeColor = isInput && boundElement.attr("type") === "color" && inputTypeColorSupport(),
|
231 |
+
shouldReplace = isInput && !flat,
|
232 |
+
replacer = (shouldReplace) ? $(replaceInput).addClass(theme).addClass(opts.className).addClass(opts.replacerClassName) : $([]),
|
233 |
+
offsetElement = (shouldReplace) ? replacer : boundElement,
|
234 |
+
previewElement = replacer.find(".sp-preview-inner"),
|
235 |
+
initialColor = opts.color || (isInput && boundElement.val()),
|
236 |
+
colorOnShow = false,
|
237 |
+
preferredFormat = opts.preferredFormat,
|
238 |
+
currentPreferredFormat = preferredFormat,
|
239 |
+
clickoutFiresChange = !opts.showButtons || opts.clickoutFiresChange,
|
240 |
+
isEmpty = !initialColor,
|
241 |
+
allowEmpty = opts.allowEmpty && !isInputTypeColor;
|
242 |
+
|
243 |
+
function applyOptions() {
|
244 |
+
|
245 |
+
if (opts.showPaletteOnly) {
|
246 |
+
opts.showPalette = true;
|
247 |
+
}
|
248 |
+
|
249 |
+
toggleButton.text(opts.showPaletteOnly ? opts.togglePaletteMoreText : opts.togglePaletteLessText);
|
250 |
+
|
251 |
+
if (opts.palette) {
|
252 |
+
palette = opts.palette.slice(0);
|
253 |
+
paletteArray = $.isArray(palette[0]) ? palette : [palette];
|
254 |
+
paletteLookup = {};
|
255 |
+
for (var i = 0; i < paletteArray.length; i++) {
|
256 |
+
for (var j = 0; j < paletteArray[i].length; j++) {
|
257 |
+
var rgb = tinycolor(paletteArray[i][j]).toRgbString();
|
258 |
+
paletteLookup[rgb] = true;
|
259 |
+
}
|
260 |
+
}
|
261 |
+
}
|
262 |
+
|
263 |
+
container.toggleClass("sp-flat", flat);
|
264 |
+
container.toggleClass("sp-input-disabled", !opts.showInput);
|
265 |
+
container.toggleClass("sp-alpha-enabled", opts.showAlpha);
|
266 |
+
container.toggleClass("sp-clear-enabled", allowEmpty);
|
267 |
+
container.toggleClass("sp-buttons-disabled", !opts.showButtons);
|
268 |
+
container.toggleClass("sp-palette-buttons-disabled", !opts.togglePaletteOnly);
|
269 |
+
container.toggleClass("sp-palette-disabled", !opts.showPalette);
|
270 |
+
container.toggleClass("sp-palette-only", opts.showPaletteOnly);
|
271 |
+
container.toggleClass("sp-initial-disabled", !opts.showInitial);
|
272 |
+
container.addClass(opts.className).addClass(opts.containerClassName);
|
273 |
+
|
274 |
+
reflow();
|
275 |
+
}
|
276 |
+
|
277 |
+
function initialize() {
|
278 |
+
|
279 |
+
if (IE) {
|
280 |
+
container.find("*:not(input)").attr("unselectable", "on");
|
281 |
+
}
|
282 |
+
|
283 |
+
applyOptions();
|
284 |
+
|
285 |
+
if (shouldReplace) {
|
286 |
+
boundElement.after(replacer).hide();
|
287 |
+
}
|
288 |
+
|
289 |
+
if (!allowEmpty) {
|
290 |
+
clearButton.hide();
|
291 |
+
}
|
292 |
+
|
293 |
+
if (flat) {
|
294 |
+
boundElement.after(container).hide();
|
295 |
+
}
|
296 |
+
else {
|
297 |
+
|
298 |
+
var appendTo = opts.appendTo === "parent" ? boundElement.parent() : $(opts.appendTo);
|
299 |
+
if (appendTo.length !== 1) {
|
300 |
+
appendTo = $("body");
|
301 |
+
}
|
302 |
+
|
303 |
+
appendTo.append(container);
|
304 |
+
}
|
305 |
+
|
306 |
+
updateSelectionPaletteFromStorage();
|
307 |
+
|
308 |
+
offsetElement.bind("click.spectrum touchstart.spectrum", function (e) {
|
309 |
+
if (!disabled) {
|
310 |
+
toggle();
|
311 |
+
}
|
312 |
+
|
313 |
+
e.stopPropagation();
|
314 |
+
|
315 |
+
if (!$(e.target).is("input")) {
|
316 |
+
e.preventDefault();
|
317 |
+
}
|
318 |
+
});
|
319 |
+
|
320 |
+
if(boundElement.is(":disabled") || (opts.disabled === true)) {
|
321 |
+
disable();
|
322 |
+
}
|
323 |
+
|
324 |
+
// Prevent clicks from bubbling up to document. This would cause it to be hidden.
|
325 |
+
container.click(stopPropagation);
|
326 |
+
|
327 |
+
// Handle user typed input
|
328 |
+
textInput.change(setFromTextInput);
|
329 |
+
textInput.bind("paste", function () {
|
330 |
+
setTimeout(setFromTextInput, 1);
|
331 |
+
});
|
332 |
+
textInput.keydown(function (e) { if (e.keyCode == 13) { setFromTextInput(); } });
|
333 |
+
|
334 |
+
cancelButton.text(opts.cancelText);
|
335 |
+
cancelButton.bind("click.spectrum", function (e) {
|
336 |
+
e.stopPropagation();
|
337 |
+
e.preventDefault();
|
338 |
+
revert();
|
339 |
+
hide();
|
340 |
+
});
|
341 |
+
|
342 |
+
clearButton.attr("title", opts.clearText);
|
343 |
+
clearButton.bind("click.spectrum", function (e) {
|
344 |
+
e.stopPropagation();
|
345 |
+
e.preventDefault();
|
346 |
+
isEmpty = true;
|
347 |
+
move();
|
348 |
+
|
349 |
+
if(flat) {
|
350 |
+
//for the flat style, this is a change event
|
351 |
+
updateOriginalInput(true);
|
352 |
+
}
|
353 |
+
});
|
354 |
+
|
355 |
+
chooseButton.text(opts.chooseText);
|
356 |
+
chooseButton.bind("click.spectrum", function (e) {
|
357 |
+
e.stopPropagation();
|
358 |
+
e.preventDefault();
|
359 |
+
|
360 |
+
if (IE && textInput.is(":focus")) {
|
361 |
+
textInput.trigger('change');
|
362 |
+
}
|
363 |
+
|
364 |
+
if (isValid()) {
|
365 |
+
updateOriginalInput(true);
|
366 |
+
hide();
|
367 |
+
}
|
368 |
+
});
|
369 |
+
|
370 |
+
toggleButton.text(opts.showPaletteOnly ? opts.togglePaletteMoreText : opts.togglePaletteLessText);
|
371 |
+
toggleButton.bind("click.spectrum", function (e) {
|
372 |
+
e.stopPropagation();
|
373 |
+
e.preventDefault();
|
374 |
+
|
375 |
+
opts.showPaletteOnly = !opts.showPaletteOnly;
|
376 |
+
|
377 |
+
// To make sure the Picker area is drawn on the right, next to the
|
378 |
+
// Palette area (and not below the palette), first move the Palette
|
379 |
+
// to the left to make space for the picker, plus 5px extra.
|
380 |
+
// The 'applyOptions' function puts the whole container back into place
|
381 |
+
// and takes care of the button-text and the sp-palette-only CSS class.
|
382 |
+
if (!opts.showPaletteOnly && !flat) {
|
383 |
+
container.css('left', '-=' + (pickerContainer.outerWidth(true) + 5));
|
384 |
+
}
|
385 |
+
applyOptions();
|
386 |
+
});
|
387 |
+
|
388 |
+
draggable(alphaSlider, function (dragX, dragY, e) {
|
389 |
+
currentAlpha = (dragX / alphaWidth);
|
390 |
+
isEmpty = false;
|
391 |
+
if (e.shiftKey) {
|
392 |
+
currentAlpha = Math.round(currentAlpha * 10) / 10;
|
393 |
+
}
|
394 |
+
|
395 |
+
move();
|
396 |
+
}, dragStart, dragStop);
|
397 |
+
|
398 |
+
draggable(slider, function (dragX, dragY) {
|
399 |
+
currentHue = parseFloat(dragY / slideHeight);
|
400 |
+
isEmpty = false;
|
401 |
+
if (!opts.showAlpha) {
|
402 |
+
currentAlpha = 1;
|
403 |
+
}
|
404 |
+
move();
|
405 |
+
}, dragStart, dragStop);
|
406 |
+
|
407 |
+
draggable(dragger, function (dragX, dragY, e) {
|
408 |
+
|
409 |
+
// shift+drag should snap the movement to either the x or y axis.
|
410 |
+
if (!e.shiftKey) {
|
411 |
+
shiftMovementDirection = null;
|
412 |
+
}
|
413 |
+
else if (!shiftMovementDirection) {
|
414 |
+
var oldDragX = currentSaturation * dragWidth;
|
415 |
+
var oldDragY = dragHeight - (currentValue * dragHeight);
|
416 |
+
var furtherFromX = Math.abs(dragX - oldDragX) > Math.abs(dragY - oldDragY);
|
417 |
+
|
418 |
+
shiftMovementDirection = furtherFromX ? "x" : "y";
|
419 |
+
}
|
420 |
+
|
421 |
+
var setSaturation = !shiftMovementDirection || shiftMovementDirection === "x";
|
422 |
+
var setValue = !shiftMovementDirection || shiftMovementDirection === "y";
|
423 |
+
|
424 |
+
if (setSaturation) {
|
425 |
+
currentSaturation = parseFloat(dragX / dragWidth);
|
426 |
+
}
|
427 |
+
if (setValue) {
|
428 |
+
currentValue = parseFloat((dragHeight - dragY) / dragHeight);
|
429 |
+
}
|
430 |
+
|
431 |
+
isEmpty = false;
|
432 |
+
if (!opts.showAlpha) {
|
433 |
+
currentAlpha = 1;
|
434 |
+
}
|
435 |
+
|
436 |
+
move();
|
437 |
+
|
438 |
+
}, dragStart, dragStop);
|
439 |
+
|
440 |
+
if (!!initialColor) {
|
441 |
+
set(initialColor);
|
442 |
+
|
443 |
+
// In case color was black - update the preview UI and set the format
|
444 |
+
// since the set function will not run (default color is black).
|
445 |
+
updateUI();
|
446 |
+
currentPreferredFormat = preferredFormat || tinycolor(initialColor).format;
|
447 |
+
|
448 |
+
addColorToSelectionPalette(initialColor);
|
449 |
+
}
|
450 |
+
else {
|
451 |
+
updateUI();
|
452 |
+
}
|
453 |
+
|
454 |
+
if (flat) {
|
455 |
+
show();
|
456 |
+
}
|
457 |
+
|
458 |
+
function paletteElementClick(e) {
|
459 |
+
if (e.data && e.data.ignore) {
|
460 |
+
set($(e.target).closest(".sp-thumb-el").data("color"));
|
461 |
+
move();
|
462 |
+
}
|
463 |
+
else {
|
464 |
+
set($(e.target).closest(".sp-thumb-el").data("color"));
|
465 |
+
move();
|
466 |
+
updateOriginalInput(true);
|
467 |
+
if (opts.hideAfterPaletteSelect) {
|
468 |
+
hide();
|
469 |
+
}
|
470 |
+
}
|
471 |
+
|
472 |
+
return false;
|
473 |
+
}
|
474 |
+
|
475 |
+
var paletteEvent = IE ? "mousedown.spectrum" : "click.spectrum touchstart.spectrum";
|
476 |
+
paletteContainer.delegate(".sp-thumb-el", paletteEvent, paletteElementClick);
|
477 |
+
initialColorContainer.delegate(".sp-thumb-el:nth-child(1)", paletteEvent, { ignore: true }, paletteElementClick);
|
478 |
+
}
|
479 |
+
|
480 |
+
function updateSelectionPaletteFromStorage() {
|
481 |
+
|
482 |
+
if (localStorageKey && window.localStorage) {
|
483 |
+
|
484 |
+
// Migrate old palettes over to new format. May want to remove this eventually.
|
485 |
+
try {
|
486 |
+
var oldPalette = window.localStorage[localStorageKey].split(",#");
|
487 |
+
if (oldPalette.length > 1) {
|
488 |
+
delete window.localStorage[localStorageKey];
|
489 |
+
$.each(oldPalette, function(i, c) {
|
490 |
+
addColorToSelectionPalette(c);
|
491 |
+
});
|
492 |
+
}
|
493 |
+
}
|
494 |
+
catch(e) { }
|
495 |
+
|
496 |
+
try {
|
497 |
+
selectionPalette = window.localStorage[localStorageKey].split(";");
|
498 |
+
}
|
499 |
+
catch (e) { }
|
500 |
+
}
|
501 |
+
}
|
502 |
+
|
503 |
+
function addColorToSelectionPalette(color) {
|
504 |
+
if (showSelectionPalette) {
|
505 |
+
var rgb = tinycolor(color).toRgbString();
|
506 |
+
if (!paletteLookup[rgb] && $.inArray(rgb, selectionPalette) === -1) {
|
507 |
+
selectionPalette.push(rgb);
|
508 |
+
while(selectionPalette.length > maxSelectionSize) {
|
509 |
+
selectionPalette.shift();
|
510 |
+
}
|
511 |
+
}
|
512 |
+
|
513 |
+
if (localStorageKey && window.localStorage) {
|
514 |
+
try {
|
515 |
+
window.localStorage[localStorageKey] = selectionPalette.join(";");
|
516 |
+
}
|
517 |
+
catch(e) { }
|
518 |
+
}
|
519 |
+
}
|
520 |
+
}
|
521 |
+
|
522 |
+
function getUniqueSelectionPalette() {
|
523 |
+
var unique = [];
|
524 |
+
if (opts.showPalette) {
|
525 |
+
for (var i = 0; i < selectionPalette.length; i++) {
|
526 |
+
var rgb = tinycolor(selectionPalette[i]).toRgbString();
|
527 |
+
|
528 |
+
if (!paletteLookup[rgb]) {
|
529 |
+
unique.push(selectionPalette[i]);
|
530 |
+
}
|
531 |
+
}
|
532 |
+
}
|
533 |
+
|
534 |
+
return unique.reverse().slice(0, opts.maxSelectionSize);
|
535 |
+
}
|
536 |
+
|
537 |
+
function drawPalette() {
|
538 |
+
|
539 |
+
var currentColor = get();
|
540 |
+
|
541 |
+
var html = $.map(paletteArray, function (palette, i) {
|
542 |
+
return paletteTemplate(palette, currentColor, "sp-palette-row sp-palette-row-" + i, opts);
|
543 |
+
});
|
544 |
+
|
545 |
+
updateSelectionPaletteFromStorage();
|
546 |
+
|
547 |
+
if (selectionPalette) {
|
548 |
+
html.push(paletteTemplate(getUniqueSelectionPalette(), currentColor, "sp-palette-row sp-palette-row-selection", opts));
|
549 |
+
}
|
550 |
+
|
551 |
+
paletteContainer.html(html.join(""));
|
552 |
+
}
|
553 |
+
|
554 |
+
function drawInitial() {
|
555 |
+
if (opts.showInitial) {
|
556 |
+
var initial = colorOnShow;
|
557 |
+
var current = get();
|
558 |
+
initialColorContainer.html(paletteTemplate([initial, current], current, "sp-palette-row-initial", opts));
|
559 |
+
}
|
560 |
+
}
|
561 |
+
|
562 |
+
function dragStart() {
|
563 |
+
if (dragHeight <= 0 || dragWidth <= 0 || slideHeight <= 0) {
|
564 |
+
reflow();
|
565 |
+
}
|
566 |
+
isDragging = true;
|
567 |
+
container.addClass(draggingClass);
|
568 |
+
shiftMovementDirection = null;
|
569 |
+
boundElement.trigger('dragstart.spectrum', [ get() ]);
|
570 |
+
}
|
571 |
+
|
572 |
+
function dragStop() {
|
573 |
+
isDragging = false;
|
574 |
+
container.removeClass(draggingClass);
|
575 |
+
boundElement.trigger('dragstop.spectrum', [ get() ]);
|
576 |
+
}
|
577 |
+
|
578 |
+
function setFromTextInput() {
|
579 |
+
|
580 |
+
var value = textInput.val();
|
581 |
+
|
582 |
+
if ((value === null || value === "") && allowEmpty) {
|
583 |
+
set(null);
|
584 |
+
updateOriginalInput(true);
|
585 |
+
}
|
586 |
+
else {
|
587 |
+
var tiny = tinycolor(value);
|
588 |
+
if (tiny.isValid()) {
|
589 |
+
set(tiny);
|
590 |
+
updateOriginalInput(true);
|
591 |
+
}
|
592 |
+
else {
|
593 |
+
textInput.addClass("sp-validation-error");
|
594 |
+
}
|
595 |
+
}
|
596 |
+
}
|
597 |
+
|
598 |
+
function toggle() {
|
599 |
+
if (visible) {
|
600 |
+
hide();
|
601 |
+
}
|
602 |
+
else {
|
603 |
+
show();
|
604 |
+
}
|
605 |
+
}
|
606 |
+
|
607 |
+
function show() {
|
608 |
+
var event = $.Event('beforeShow.spectrum');
|
609 |
+
|
610 |
+
if (visible) {
|
611 |
+
reflow();
|
612 |
+
return;
|
613 |
+
}
|
614 |
+
|
615 |
+
boundElement.trigger(event, [ get() ]);
|
616 |
+
|
617 |
+
if (callbacks.beforeShow(get()) === false || event.isDefaultPrevented()) {
|
618 |
+
return;
|
619 |
+
}
|
620 |
+
|
621 |
+
hideAll();
|
622 |
+
visible = true;
|
623 |
+
|
624 |
+
$(doc).bind("keydown.spectrum", onkeydown);
|
625 |
+
$(doc).bind("click.spectrum", clickout);
|
626 |
+
$(window).bind("resize.spectrum", resize);
|
627 |
+
replacer.addClass("sp-active");
|
628 |
+
container.removeClass("sp-hidden");
|
629 |
+
|
630 |
+
reflow();
|
631 |
+
updateUI();
|
632 |
+
|
633 |
+
colorOnShow = get();
|
634 |
+
|
635 |
+
drawInitial();
|
636 |
+
callbacks.show(colorOnShow);
|
637 |
+
boundElement.trigger('show.spectrum', [ colorOnShow ]);
|
638 |
+
}
|
639 |
+
|
640 |
+
function onkeydown(e) {
|
641 |
+
// Close on ESC
|
642 |
+
if (e.keyCode === 27) {
|
643 |
+
hide();
|
644 |
+
}
|
645 |
+
}
|
646 |
+
|
647 |
+
function clickout(e) {
|
648 |
+
// Return on right click.
|
649 |
+
if (e.button == 2) { return; }
|
650 |
+
|
651 |
+
// If a drag event was happening during the mouseup, don't hide
|
652 |
+
// on click.
|
653 |
+
if (isDragging) { return; }
|
654 |
+
|
655 |
+
if (clickoutFiresChange) {
|
656 |
+
updateOriginalInput(true);
|
657 |
+
}
|
658 |
+
else {
|
659 |
+
revert();
|
660 |
+
}
|
661 |
+
hide();
|
662 |
+
}
|
663 |
+
|
664 |
+
function hide() {
|
665 |
+
// Return if hiding is unnecessary
|
666 |
+
if (!visible || flat) { return; }
|
667 |
+
visible = false;
|
668 |
+
|
669 |
+
$(doc).unbind("keydown.spectrum", onkeydown);
|
670 |
+
$(doc).unbind("click.spectrum", clickout);
|
671 |
+
$(window).unbind("resize.spectrum", resize);
|
672 |
+
|
673 |
+
replacer.removeClass("sp-active");
|
674 |
+
container.addClass("sp-hidden");
|
675 |
+
|
676 |
+
callbacks.hide(get());
|
677 |
+
boundElement.trigger('hide.spectrum', [ get() ]);
|
678 |
+
}
|
679 |
+
|
680 |
+
function revert() {
|
681 |
+
set(colorOnShow, true);
|
682 |
+
}
|
683 |
+
|
684 |
+
function set(color, ignoreFormatChange) {
|
685 |
+
if (tinycolor.equals(color, get())) {
|
686 |
+
// Update UI just in case a validation error needs
|
687 |
+
// to be cleared.
|
688 |
+
updateUI();
|
689 |
+
return;
|
690 |
+
}
|
691 |
+
|
692 |
+
var newColor, newHsv;
|
693 |
+
if (!color && allowEmpty) {
|
694 |
+
isEmpty = true;
|
695 |
+
} else {
|
696 |
+
isEmpty = false;
|
697 |
+
newColor = tinycolor(color);
|
698 |
+
newHsv = newColor.toHsv();
|
699 |
+
|
700 |
+
currentHue = (newHsv.h % 360) / 360;
|
701 |
+
currentSaturation = newHsv.s;
|
702 |
+
currentValue = newHsv.v;
|
703 |
+
currentAlpha = newHsv.a;
|
704 |
+
}
|
705 |
+
updateUI();
|
706 |
+
|
707 |
+
if (newColor && newColor.isValid() && !ignoreFormatChange) {
|
708 |
+
currentPreferredFormat = preferredFormat || newColor.getFormat();
|
709 |
+
}
|
710 |
+
}
|
711 |
+
|
712 |
+
function get(opts) {
|
713 |
+
opts = opts || { };
|
714 |
+
|
715 |
+
if (allowEmpty && isEmpty) {
|
716 |
+
return null;
|
717 |
+
}
|
718 |
+
|
719 |
+
return tinycolor.fromRatio({
|
720 |
+
h: currentHue,
|
721 |
+
s: currentSaturation,
|
722 |
+
v: currentValue,
|
723 |
+
a: Math.round(currentAlpha * 100) / 100
|
724 |
+
}, { format: opts.format || currentPreferredFormat });
|
725 |
+
}
|
726 |
+
|
727 |
+
function isValid() {
|
728 |
+
return !textInput.hasClass("sp-validation-error");
|
729 |
+
}
|
730 |
+
|
731 |
+
function move() {
|
732 |
+
updateUI();
|
733 |
+
|
734 |
+
callbacks.move(get());
|
735 |
+
boundElement.trigger('move.spectrum', [ get() ]);
|
736 |
+
}
|
737 |
+
|
738 |
+
function updateUI() {
|
739 |
+
|
740 |
+
textInput.removeClass("sp-validation-error");
|
741 |
+
|
742 |
+
updateHelperLocations();
|
743 |
+
|
744 |
+
// Update dragger background color (gradients take care of saturation and value).
|
745 |
+
var flatColor = tinycolor.fromRatio({ h: currentHue, s: 1, v: 1 });
|
746 |
+
dragger.css("background-color", flatColor.toHexString());
|
747 |
+
|
748 |
+
// Get a format that alpha will be included in (hex and names ignore alpha)
|
749 |
+
var format = currentPreferredFormat;
|
750 |
+
if (currentAlpha < 1 && !(currentAlpha === 0 && format === "name")) {
|
751 |
+
if (format === "hex" || format === "hex3" || format === "hex6" || format === "name") {
|
752 |
+
format = "rgb";
|
753 |
+
}
|
754 |
+
}
|
755 |
+
|
756 |
+
var realColor = get({ format: format }),
|
757 |
+
displayColor = '';
|
758 |
+
|
759 |
+
//reset background info for preview element
|
760 |
+
previewElement.removeClass("sp-clear-display");
|
761 |
+
previewElement.css('background-color', 'transparent');
|
762 |
+
|
763 |
+
if (!realColor && allowEmpty) {
|
764 |
+
// Update the replaced elements background with icon indicating no color selection
|
765 |
+
previewElement.addClass("sp-clear-display");
|
766 |
+
}
|
767 |
+
else {
|
768 |
+
var realHex = realColor.toHexString(),
|
769 |
+
realRgb = realColor.toRgbString();
|
770 |
+
|
771 |
+
// Update the replaced elements background color (with actual selected color)
|
772 |
+
if (rgbaSupport || realColor.alpha === 1) {
|
773 |
+
previewElement.css("background-color", realRgb);
|
774 |
+
}
|
775 |
+
else {
|
776 |
+
previewElement.css("background-color", "transparent");
|
777 |
+
previewElement.css("filter", realColor.toFilter());
|
778 |
+
}
|
779 |
+
|
780 |
+
if (opts.showAlpha) {
|
781 |
+
var rgb = realColor.toRgb();
|
782 |
+
rgb.a = 0;
|
783 |
+
var realAlpha = tinycolor(rgb).toRgbString();
|
784 |
+
var gradient = "linear-gradient(left, " + realAlpha + ", " + realHex + ")";
|
785 |
+
|
786 |
+
if (IE) {
|
787 |
+
alphaSliderInner.css("filter", tinycolor(realAlpha).toFilter({ gradientType: 1 }, realHex));
|
788 |
+
}
|
789 |
+
else {
|
790 |
+
alphaSliderInner.css("background", "-webkit-" + gradient);
|
791 |
+
alphaSliderInner.css("background", "-moz-" + gradient);
|
792 |
+
alphaSliderInner.css("background", "-ms-" + gradient);
|
793 |
+
// Use current syntax gradient on unprefixed property.
|
794 |
+
alphaSliderInner.css("background",
|
795 |
+
"linear-gradient(to right, " + realAlpha + ", " + realHex + ")");
|
796 |
+
}
|
797 |
+
}
|
798 |
+
|
799 |
+
displayColor = realColor.toString(format);
|
800 |
+
}
|
801 |
+
|
802 |
+
// Update the text entry input as it changes happen
|
803 |
+
if (opts.showInput) {
|
804 |
+
textInput.val(displayColor);
|
805 |
+
}
|
806 |
+
|
807 |
+
if (opts.showPalette) {
|
808 |
+
drawPalette();
|
809 |
+
}
|
810 |
+
|
811 |
+
drawInitial();
|
812 |
+
}
|
813 |
+
|
814 |
+
function updateHelperLocations() {
|
815 |
+
var s = currentSaturation;
|
816 |
+
var v = currentValue;
|
817 |
+
|
818 |
+
if(allowEmpty && isEmpty) {
|
819 |
+
//if selected color is empty, hide the helpers
|
820 |
+
alphaSlideHelper.hide();
|
821 |
+
slideHelper.hide();
|
822 |
+
dragHelper.hide();
|
823 |
+
}
|
824 |
+
else {
|
825 |
+
//make sure helpers are visible
|
826 |
+
alphaSlideHelper.show();
|
827 |
+
slideHelper.show();
|
828 |
+
dragHelper.show();
|
829 |
+
|
830 |
+
// Where to show the little circle in that displays your current selected color
|
831 |
+
var dragX = s * dragWidth;
|
832 |
+
var dragY = dragHeight - (v * dragHeight);
|
833 |
+
dragX = Math.max(
|
834 |
+
-dragHelperHeight,
|
835 |
+
Math.min(dragWidth - dragHelperHeight, dragX - dragHelperHeight)
|
836 |
+
);
|
837 |
+
dragY = Math.max(
|
838 |
+
-dragHelperHeight,
|
839 |
+
Math.min(dragHeight - dragHelperHeight, dragY - dragHelperHeight)
|
840 |
+
);
|
841 |
+
dragHelper.css({
|
842 |
+
"top": dragY + "px",
|
843 |
+
"left": dragX + "px"
|
844 |
+
});
|
845 |
+
|
846 |
+
var alphaX = currentAlpha * alphaWidth;
|
847 |
+
alphaSlideHelper.css({
|
848 |
+
"left": (alphaX - (alphaSlideHelperWidth / 2)) + "px"
|
849 |
+
});
|
850 |
+
|
851 |
+
// Where to show the bar that displays your current selected hue
|
852 |
+
var slideY = (currentHue) * slideHeight;
|
853 |
+
slideHelper.css({
|
854 |
+
"top": (slideY - slideHelperHeight) + "px"
|
855 |
+
});
|
856 |
+
}
|
857 |
+
}
|
858 |
+
|
859 |
+
function updateOriginalInput(fireCallback) {
|
860 |
+
var color = get(),
|
861 |
+
displayColor = '',
|
862 |
+
hasChanged = !tinycolor.equals(color, colorOnShow);
|
863 |
+
|
864 |
+
if (color) {
|
865 |
+
displayColor = color.toString(currentPreferredFormat);
|
866 |
+
// Update the selection palette with the current color
|
867 |
+
addColorToSelectionPalette(color);
|
868 |
+
}
|
869 |
+
|
870 |
+
if (isInput) {
|
871 |
+
boundElement.val(displayColor);
|
872 |
+
}
|
873 |
+
|
874 |
+
if (fireCallback && hasChanged) {
|
875 |
+
callbacks.change(color);
|
876 |
+
boundElement.trigger('change', [ color ]);
|
877 |
+
}
|
878 |
+
}
|
879 |
+
|
880 |
+
function reflow() {
|
881 |
+
dragWidth = dragger.width();
|
882 |
+
dragHeight = dragger.height();
|
883 |
+
dragHelperHeight = dragHelper.height();
|
884 |
+
slideWidth = slider.width();
|
885 |
+
slideHeight = slider.height();
|
886 |
+
slideHelperHeight = slideHelper.height();
|
887 |
+
alphaWidth = alphaSlider.width();
|
888 |
+
alphaSlideHelperWidth = alphaSlideHelper.width();
|
889 |
+
|
890 |
+
if (!flat) {
|
891 |
+
container.css("position", "absolute");
|
892 |
+
if (opts.offset) {
|
893 |
+
container.offset(opts.offset);
|
894 |
+
} else {
|
895 |
+
container.offset(getOffset(container, offsetElement));
|
896 |
+
}
|
897 |
+
}
|
898 |
+
|
899 |
+
updateHelperLocations();
|
900 |
+
|
901 |
+
if (opts.showPalette) {
|
902 |
+
drawPalette();
|
903 |
+
}
|
904 |
+
|
905 |
+
boundElement.trigger('reflow.spectrum');
|
906 |
+
}
|
907 |
+
|
908 |
+
function destroy() {
|
909 |
+
boundElement.show();
|
910 |
+
offsetElement.unbind("click.spectrum touchstart.spectrum");
|
911 |
+
container.remove();
|
912 |
+
replacer.remove();
|
913 |
+
spectrums[spect.id] = null;
|
914 |
+
}
|
915 |
+
|
916 |
+
function option(optionName, optionValue) {
|
917 |
+
if (optionName === undefined) {
|
918 |
+
return $.extend({}, opts);
|
919 |
+
}
|
920 |
+
if (optionValue === undefined) {
|
921 |
+
return opts[optionName];
|
922 |
+
}
|
923 |
+
|
924 |
+
opts[optionName] = optionValue;
|
925 |
+
applyOptions();
|
926 |
+
}
|
927 |
+
|
928 |
+
function enable() {
|
929 |
+
disabled = false;
|
930 |
+
boundElement.attr("disabled", false);
|
931 |
+
offsetElement.removeClass("sp-disabled");
|
932 |
+
}
|
933 |
+
|
934 |
+
function disable() {
|
935 |
+
hide();
|
936 |
+
disabled = true;
|
937 |
+
boundElement.attr("disabled", true);
|
938 |
+
offsetElement.addClass("sp-disabled");
|
939 |
+
}
|
940 |
+
|
941 |
+
function setOffset(coord) {
|
942 |
+
opts.offset = coord;
|
943 |
+
reflow();
|
944 |
+
}
|
945 |
+
|
946 |
+
initialize();
|
947 |
+
|
948 |
+
var spect = {
|
949 |
+
show: show,
|
950 |
+
hide: hide,
|
951 |
+
toggle: toggle,
|
952 |
+
reflow: reflow,
|
953 |
+
option: option,
|
954 |
+
enable: enable,
|
955 |
+
disable: disable,
|
956 |
+
offset: setOffset,
|
957 |
+
set: function (c) {
|
958 |
+
set(c);
|
959 |
+
updateOriginalInput();
|
960 |
+
},
|
961 |
+
get: get,
|
962 |
+
destroy: destroy,
|
963 |
+
container: container
|
964 |
+
};
|
965 |
+
|
966 |
+
spect.id = spectrums.push(spect) - 1;
|
967 |
+
|
968 |
+
return spect;
|
969 |
+
}
|
970 |
+
|
971 |
+
/**
|
972 |
+
* checkOffset - get the offset below/above and left/right element depending on screen position
|
973 |
+
* Thanks https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.datepicker.js
|
974 |
+
*/
|
975 |
+
function getOffset(picker, input) {
|
976 |
+
var extraY = 0;
|
977 |
+
var dpWidth = picker.outerWidth();
|
978 |
+
var dpHeight = picker.outerHeight();
|
979 |
+
var inputHeight = input.outerHeight();
|
980 |
+
var doc = picker[0].ownerDocument;
|
981 |
+
var docElem = doc.documentElement;
|
982 |
+
var viewWidth = docElem.clientWidth + $(doc).scrollLeft();
|
983 |
+
var viewHeight = docElem.clientHeight + $(doc).scrollTop();
|
984 |
+
var offset = input.offset();
|
985 |
+
offset.top += inputHeight;
|
986 |
+
|
987 |
+
offset.left -=
|
988 |
+
Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
|
989 |
+
Math.abs(offset.left + dpWidth - viewWidth) : 0);
|
990 |
+
|
991 |
+
offset.top -=
|
992 |
+
Math.min(offset.top, ((offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
|
993 |
+
Math.abs(dpHeight + inputHeight - extraY) : extraY));
|
994 |
+
|
995 |
+
return offset;
|
996 |
+
}
|
997 |
+
|
998 |
+
/**
|
999 |
+
* noop - do nothing
|
1000 |
+
*/
|
1001 |
+
function noop() {
|
1002 |
+
|
1003 |
+
}
|
1004 |
+
|
1005 |
+
/**
|
1006 |
+
* stopPropagation - makes the code only doing this a little easier to read in line
|
1007 |
+
*/
|
1008 |
+
function stopPropagation(e) {
|
1009 |
+
e.stopPropagation();
|
1010 |
+
}
|
1011 |
+
|
1012 |
+
/**
|
1013 |
+
* Create a function bound to a given object
|
1014 |
+
* Thanks to underscore.js
|
1015 |
+
*/
|
1016 |
+
function bind(func, obj) {
|
1017 |
+
var slice = Array.prototype.slice;
|
1018 |
+
var args = slice.call(arguments, 2);
|
1019 |
+
return function () {
|
1020 |
+
return func.apply(obj, args.concat(slice.call(arguments)));
|
1021 |
+
};
|
1022 |
+
}
|
1023 |
+
|
1024 |
+
/**
|
1025 |
+
* Lightweight drag helper. Handles containment within the element, so that
|
1026 |
+
* when dragging, the x is within [0,element.width] and y is within [0,element.height]
|
1027 |
+
*/
|
1028 |
+
function draggable(element, onmove, onstart, onstop) {
|
1029 |
+
onmove = onmove || function () { };
|
1030 |
+
onstart = onstart || function () { };
|
1031 |
+
onstop = onstop || function () { };
|
1032 |
+
var doc = document;
|
1033 |
+
var dragging = false;
|
1034 |
+
var offset = {};
|
1035 |
+
var maxHeight = 0;
|
1036 |
+
var maxWidth = 0;
|
1037 |
+
var hasTouch = ('ontouchstart' in window);
|
1038 |
+
|
1039 |
+
var duringDragEvents = {};
|
1040 |
+
duringDragEvents["selectstart"] = prevent;
|
1041 |
+
duringDragEvents["dragstart"] = prevent;
|
1042 |
+
duringDragEvents["touchmove mousemove"] = move;
|
1043 |
+
duringDragEvents["touchend mouseup"] = stop;
|
1044 |
+
|
1045 |
+
function prevent(e) {
|
1046 |
+
if (e.stopPropagation) {
|
1047 |
+
e.stopPropagation();
|
1048 |
+
}
|
1049 |
+
if (e.preventDefault) {
|
1050 |
+
e.preventDefault();
|
1051 |
+
}
|
1052 |
+
e.returnValue = false;
|
1053 |
+
}
|
1054 |
+
|
1055 |
+
function move(e) {
|
1056 |
+
if (dragging) {
|
1057 |
+
// Mouseup happened outside of window
|
1058 |
+
if (IE && doc.documentMode < 9 && !e.button) {
|
1059 |
+
return stop();
|
1060 |
+
}
|
1061 |
+
|
1062 |
+
var t0 = e.originalEvent && e.originalEvent.touches && e.originalEvent.touches[0];
|
1063 |
+
var pageX = t0 && t0.pageX || e.pageX;
|
1064 |
+
var pageY = t0 && t0.pageY || e.pageY;
|
1065 |
+
|
1066 |
+
var dragX = Math.max(0, Math.min(pageX - offset.left, maxWidth));
|
1067 |
+
var dragY = Math.max(0, Math.min(pageY - offset.top, maxHeight));
|
1068 |
+
|
1069 |
+
if (hasTouch) {
|
1070 |
+
// Stop scrolling in iOS
|
1071 |
+
prevent(e);
|
1072 |
+
}
|
1073 |
+
|
1074 |
+
onmove.apply(element, [dragX, dragY, e]);
|
1075 |
+
}
|
1076 |
+
}
|
1077 |
+
|
1078 |
+
function start(e) {
|
1079 |
+
var rightclick = (e.which) ? (e.which == 3) : (e.button == 2);
|
1080 |
+
|
1081 |
+
if (!rightclick && !dragging) {
|
1082 |
+
if (onstart.apply(element, arguments) !== false) {
|
1083 |
+
dragging = true;
|
1084 |
+
maxHeight = $(element).height();
|
1085 |
+
maxWidth = $(element).width();
|
1086 |
+
offset = $(element).offset();
|
1087 |
+
|
1088 |
+
$(doc).bind(duringDragEvents);
|
1089 |
+
$(doc.body).addClass("sp-dragging");
|
1090 |
+
|
1091 |
+
move(e);
|
1092 |
+
|
1093 |
+
prevent(e);
|
1094 |
+
}
|
1095 |
+
}
|
1096 |
+
}
|
1097 |
+
|
1098 |
+
function stop() {
|
1099 |
+
if (dragging) {
|
1100 |
+
$(doc).unbind(duringDragEvents);
|
1101 |
+
$(doc.body).removeClass("sp-dragging");
|
1102 |
+
|
1103 |
+
// Wait a tick before notifying observers to allow the click event
|
1104 |
+
// to fire in Chrome.
|
1105 |
+
setTimeout(function() {
|
1106 |
+
onstop.apply(element, arguments);
|
1107 |
+
}, 0);
|
1108 |
+
}
|
1109 |
+
dragging = false;
|
1110 |
+
}
|
1111 |
+
|
1112 |
+
$(element).bind("touchstart mousedown", start);
|
1113 |
+
}
|
1114 |
+
|
1115 |
+
function throttle(func, wait, debounce) {
|
1116 |
+
var timeout;
|
1117 |
+
return function () {
|
1118 |
+
var context = this, args = arguments;
|
1119 |
+
var throttler = function () {
|
1120 |
+
timeout = null;
|
1121 |
+
func.apply(context, args);
|
1122 |
+
};
|
1123 |
+
if (debounce) clearTimeout(timeout);
|
1124 |
+
if (debounce || !timeout) timeout = setTimeout(throttler, wait);
|
1125 |
+
};
|
1126 |
+
}
|
1127 |
+
|
1128 |
+
function inputTypeColorSupport() {
|
1129 |
+
return $.fn.spectrum.inputTypeColorSupport();
|
1130 |
+
}
|
1131 |
+
|
1132 |
+
/**
|
1133 |
+
* Define a jQuery plugin
|
1134 |
+
*/
|
1135 |
+
var dataID = "spectrum.id";
|
1136 |
+
$.fn.spectrum = function (opts, extra) {
|
1137 |
+
|
1138 |
+
if (typeof opts == "string") {
|
1139 |
+
|
1140 |
+
var returnValue = this;
|
1141 |
+
var args = Array.prototype.slice.call( arguments, 1 );
|
1142 |
+
|
1143 |
+
this.each(function () {
|
1144 |
+
var spect = spectrums[$(this).data(dataID)];
|
1145 |
+
if (spect) {
|
1146 |
+
var method = spect[opts];
|
1147 |
+
if (!method) {
|
1148 |
+
throw new Error( "Spectrum: no such method: '" + opts + "'" );
|
1149 |
+
}
|
1150 |
+
|
1151 |
+
if (opts == "get") {
|
1152 |
+
returnValue = spect.get();
|
1153 |
+
}
|
1154 |
+
else if (opts == "container") {
|
1155 |
+
returnValue = spect.container;
|
1156 |
+
}
|
1157 |
+
else if (opts == "option") {
|
1158 |
+
returnValue = spect.option.apply(spect, args);
|
1159 |
+
}
|
1160 |
+
else if (opts == "destroy") {
|
1161 |
+
spect.destroy();
|
1162 |
+
$(this).removeData(dataID);
|
1163 |
+
}
|
1164 |
+
else {
|
1165 |
+
method.apply(spect, args);
|
1166 |
+
}
|
1167 |
+
}
|
1168 |
+
});
|
1169 |
+
|
1170 |
+
return returnValue;
|
1171 |
+
}
|
1172 |
+
|
1173 |
+
// Initializing a new instance of spectrum
|
1174 |
+
return this.spectrum("destroy").each(function () {
|
1175 |
+
var options = $.extend({}, opts, $(this).data());
|
1176 |
+
var spect = spectrum(this, options);
|
1177 |
+
$(this).data(dataID, spect.id);
|
1178 |
+
});
|
1179 |
+
};
|
1180 |
+
|
1181 |
+
$.fn.spectrum.load = true;
|
1182 |
+
$.fn.spectrum.loadOpts = {};
|
1183 |
+
$.fn.spectrum.draggable = draggable;
|
1184 |
+
$.fn.spectrum.defaults = defaultOpts;
|
1185 |
+
$.fn.spectrum.inputTypeColorSupport = function inputTypeColorSupport() {
|
1186 |
+
if (typeof inputTypeColorSupport._cachedResult === "undefined") {
|
1187 |
+
var colorInput = $("<input type='color'/>")[0]; // if color element is supported, value will default to not null
|
1188 |
+
inputTypeColorSupport._cachedResult = colorInput.type === "color" && colorInput.value !== "";
|
1189 |
+
}
|
1190 |
+
return inputTypeColorSupport._cachedResult;
|
1191 |
+
};
|
1192 |
+
|
1193 |
+
$.spectrum = { };
|
1194 |
+
$.spectrum.localization = { };
|
1195 |
+
$.spectrum.palettes = { };
|
1196 |
+
|
1197 |
+
$.fn.spectrum.processNativeColorInputs = function () {
|
1198 |
+
var colorInputs = $("input[type=color]");
|
1199 |
+
if (colorInputs.length && !inputTypeColorSupport()) {
|
1200 |
+
colorInputs.spectrum({
|
1201 |
+
preferredFormat: "hex6"
|
1202 |
+
});
|
1203 |
+
}
|
1204 |
+
};
|
1205 |
+
|
1206 |
+
// TinyColor v1.1.2
|
1207 |
+
// https://github.com/bgrins/TinyColor
|
1208 |
+
// Brian Grinstead, MIT License
|
1209 |
+
|
1210 |
+
(function() {
|
1211 |
+
|
1212 |
+
var trimLeft = /^[\s,#]+/,
|
1213 |
+
trimRight = /\s+$/,
|
1214 |
+
tinyCounter = 0,
|
1215 |
+
math = Math,
|
1216 |
+
mathRound = math.round,
|
1217 |
+
mathMin = math.min,
|
1218 |
+
mathMax = math.max,
|
1219 |
+
mathRandom = math.random;
|
1220 |
+
|
1221 |
+
var tinycolor = function(color, opts) {
|
1222 |
+
|
1223 |
+
color = (color) ? color : '';
|
1224 |
+
opts = opts || { };
|
1225 |
+
|
1226 |
+
// If input is already a tinycolor, return itself
|
1227 |
+
if (color instanceof tinycolor) {
|
1228 |
+
return color;
|
1229 |
+
}
|
1230 |
+
// If we are called as a function, call using new instead
|
1231 |
+
if (!(this instanceof tinycolor)) {
|
1232 |
+
return new tinycolor(color, opts);
|
1233 |
+
}
|
1234 |
+
|
1235 |
+
var rgb = inputToRGB(color);
|
1236 |
+
this._originalInput = color,
|
1237 |
+
this._r = rgb.r,
|
1238 |
+
this._g = rgb.g,
|
1239 |
+
this._b = rgb.b,
|
1240 |
+
this._a = rgb.a,
|
1241 |
+
this._roundA = mathRound(100*this._a) / 100,
|
1242 |
+
this._format = opts.format || rgb.format;
|
1243 |
+
this._gradientType = opts.gradientType;
|
1244 |
+
|
1245 |
+
// Don't let the range of [0,255] come back in [0,1].
|
1246 |
+
// Potentially lose a little bit of precision here, but will fix issues where
|
1247 |
+
// .5 gets interpreted as half of the total, instead of half of 1
|
1248 |
+
// If it was supposed to be 128, this was already taken care of by `inputToRgb`
|
1249 |
+
if (this._r < 1) { this._r = mathRound(this._r); }
|
1250 |
+
if (this._g < 1) { this._g = mathRound(this._g); }
|
1251 |
+
if (this._b < 1) { this._b = mathRound(this._b); }
|
1252 |
+
|
1253 |
+
this._ok = rgb.ok;
|
1254 |
+
this._tc_id = tinyCounter++;
|
1255 |
+
};
|
1256 |
+
|
1257 |
+
tinycolor.prototype = {
|
1258 |
+
isDark: function() {
|
1259 |
+
return this.getBrightness() < 128;
|
1260 |
+
},
|
1261 |
+
isLight: function() {
|
1262 |
+
return !this.isDark();
|
1263 |
+
},
|
1264 |
+
isValid: function() {
|
1265 |
+
return this._ok;
|
1266 |
+
},
|
1267 |
+
getOriginalInput: function() {
|
1268 |
+
return this._originalInput;
|
1269 |
+
},
|
1270 |
+
getFormat: function() {
|
1271 |
+
return this._format;
|
1272 |
+
},
|
1273 |
+
getAlpha: function() {
|
1274 |
+
return this._a;
|
1275 |
+
},
|
1276 |
+
getBrightness: function() {
|
1277 |
+
var rgb = this.toRgb();
|
1278 |
+
return (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1000;
|
1279 |
+
},
|
1280 |
+
setAlpha: function(value) {
|
1281 |
+
this._a = boundAlpha(value);
|
1282 |
+
this._roundA = mathRound(100*this._a) / 100;
|
1283 |
+
return this;
|
1284 |
+
},
|
1285 |
+
toHsv: function() {
|
1286 |
+
var hsv = rgbToHsv(this._r, this._g, this._b);
|
1287 |
+
return { h: hsv.h * 360, s: hsv.s, v: hsv.v, a: this._a };
|
1288 |
+
},
|
1289 |
+
toHsvString: function() {
|
1290 |
+
var hsv = rgbToHsv(this._r, this._g, this._b);
|
1291 |
+
var h = mathRound(hsv.h * 360), s = mathRound(hsv.s * 100), v = mathRound(hsv.v * 100);
|
1292 |
+
return (this._a == 1) ?
|
1293 |
+
"hsv(" + h + ", " + s + "%, " + v + "%)" :
|
1294 |
+
"hsva(" + h + ", " + s + "%, " + v + "%, "+ this._roundA + ")";
|
1295 |
+
},
|
1296 |
+
toHsl: function() {
|
1297 |
+
var hsl = rgbToHsl(this._r, this._g, this._b);
|
1298 |
+
return { h: hsl.h * 360, s: hsl.s, l: hsl.l, a: this._a };
|
1299 |
+
},
|
1300 |
+
toHslString: function() {
|
1301 |
+
var hsl = rgbToHsl(this._r, this._g, this._b);
|
1302 |
+
var h = mathRound(hsl.h * 360), s = mathRound(hsl.s * 100), l = mathRound(hsl.l * 100);
|
1303 |
+
return (this._a == 1) ?
|
1304 |
+
"hsl(" + h + ", " + s + "%, " + l + "%)" :
|
1305 |
+
"hsla(" + h + ", " + s + "%, " + l + "%, "+ this._roundA + ")";
|
1306 |
+
},
|
1307 |
+
toHex: function(allow3Char) {
|
1308 |
+
return rgbToHex(this._r, this._g, this._b, allow3Char);
|
1309 |
+
},
|
1310 |
+
toHexString: function(allow3Char) {
|
1311 |
+
return '#' + this.toHex(allow3Char);
|
1312 |
+
},
|
1313 |
+
toHex8: function() {
|
1314 |
+
return rgbaToHex(this._r, this._g, this._b, this._a);
|
1315 |
+
},
|
1316 |
+
toHex8String: function() {
|
1317 |
+
return '#' + this.toHex8();
|
1318 |
+
},
|
1319 |
+
toRgb: function() {
|
1320 |
+
return { r: mathRound(this._r), g: mathRound(this._g), b: mathRound(this._b), a: this._a };
|
1321 |
+
},
|
1322 |
+
toRgbString: function() {
|
1323 |
+
return (this._a == 1) ?
|
1324 |
+
"rgb(" + mathRound(this._r) + ", " + mathRound(this._g) + ", " + mathRound(this._b) + ")" :
|
1325 |
+
"rgba(" + mathRound(this._r) + ", " + mathRound(this._g) + ", " + mathRound(this._b) + ", " + this._roundA + ")";
|
1326 |
+
},
|
1327 |
+
toPercentageRgb: function() {
|
1328 |
+
return { r: mathRound(bound01(this._r, 255) * 100) + "%", g: mathRound(bound01(this._g, 255) * 100) + "%", b: mathRound(bound01(this._b, 255) * 100) + "%", a: this._a };
|
1329 |
+
},
|
1330 |
+
toPercentageRgbString: function() {
|
1331 |
+
return (this._a == 1) ?
|
1332 |
+
"rgb(" + mathRound(bound01(this._r, 255) * 100) + "%, " + mathRound(bound01(this._g, 255) * 100) + "%, " + mathRound(bound01(this._b, 255) * 100) + "%)" :
|
1333 |
+
"rgba(" + mathRound(bound01(this._r, 255) * 100) + "%, " + mathRound(bound01(this._g, 255) * 100) + "%, " + mathRound(bound01(this._b, 255) * 100) + "%, " + this._roundA + ")";
|
1334 |
+
},
|
1335 |
+
toName: function() {
|
1336 |
+
if (this._a === 0) {
|
1337 |
+
return "transparent";
|
1338 |
+
}
|
1339 |
+
|
1340 |
+
if (this._a < 1) {
|
1341 |
+
return false;
|
1342 |
+
}
|
1343 |
+
|
1344 |
+
return hexNames[rgbToHex(this._r, this._g, this._b, true)] || false;
|
1345 |
+
},
|
1346 |
+
toFilter: function(secondColor) {
|
1347 |
+
var hex8String = '#' + rgbaToHex(this._r, this._g, this._b, this._a);
|
1348 |
+
var secondHex8String = hex8String;
|
1349 |
+
var gradientType = this._gradientType ? "GradientType = 1, " : "";
|
1350 |
+
|
1351 |
+
if (secondColor) {
|
1352 |
+
var s = tinycolor(secondColor);
|
1353 |
+
secondHex8String = s.toHex8String();
|
1354 |
+
}
|
1355 |
+
|
1356 |
+
return "progid:DXImageTransform.Microsoft.gradient("+gradientType+"startColorstr="+hex8String+",endColorstr="+secondHex8String+")";
|
1357 |
+
},
|
1358 |
+
toString: function(format) {
|
1359 |
+
var formatSet = !!format;
|
1360 |
+
format = format || this._format;
|
1361 |
+
|
1362 |
+
var formattedString = false;
|
1363 |
+
var hasAlpha = this._a < 1 && this._a >= 0;
|
1364 |
+
var needsAlphaFormat = !formatSet && hasAlpha && (format === "hex" || format === "hex6" || format === "hex3" || format === "name");
|
1365 |
+
|
1366 |
+
if (needsAlphaFormat) {
|
1367 |
+
// Special case for "transparent", all other non-alpha formats
|
1368 |
+
// will return rgba when there is transparency.
|
1369 |
+
if (format === "name" && this._a === 0) {
|
1370 |
+
return this.toName();
|
1371 |
+
}
|
1372 |
+
return this.toRgbString();
|
1373 |
+
}
|
1374 |
+
if (format === "rgb") {
|
1375 |
+
formattedString = this.toRgbString();
|
1376 |
+
}
|
1377 |
+
if (format === "prgb") {
|
1378 |
+
formattedString = this.toPercentageRgbString();
|
1379 |
+
}
|
1380 |
+
if (format === "hex" || format === "hex6") {
|
1381 |
+
formattedString = this.toHexString();
|
1382 |
+
}
|
1383 |
+
if (format === "hex3") {
|
1384 |
+
formattedString = this.toHexString(true);
|
1385 |
+
}
|
1386 |
+
if (format === "hex8") {
|
1387 |
+
formattedString = this.toHex8String();
|
1388 |
+
}
|
1389 |
+
if (format === "name") {
|
1390 |
+
formattedString = this.toName();
|
1391 |
+
}
|
1392 |
+
if (format === "hsl") {
|
1393 |
+
formattedString = this.toHslString();
|
1394 |
+
}
|
1395 |
+
if (format === "hsv") {
|
1396 |
+
formattedString = this.toHsvString();
|
1397 |
+
}
|
1398 |
+
|
1399 |
+
return formattedString || this.toHexString();
|
1400 |
+
},
|
1401 |
+
|
1402 |
+
_applyModification: function(fn, args) {
|
1403 |
+
var color = fn.apply(null, [this].concat([].slice.call(args)));
|
1404 |
+
this._r = color._r;
|
1405 |
+
this._g = color._g;
|
1406 |
+
this._b = color._b;
|
1407 |
+
this.setAlpha(color._a);
|
1408 |
+
return this;
|
1409 |
+
},
|
1410 |
+
lighten: function() {
|
1411 |
+
return this._applyModification(lighten, arguments);
|
1412 |
+
},
|
1413 |
+
brighten: function() {
|
1414 |
+
return this._applyModification(brighten, arguments);
|
1415 |
+
},
|
1416 |
+
darken: function() {
|
1417 |
+
return this._applyModification(darken, arguments);
|
1418 |
+
},
|
1419 |
+
desaturate: function() {
|
1420 |
+
return this._applyModification(desaturate, arguments);
|
1421 |
+
},
|
1422 |
+
saturate: function() {
|
1423 |
+
return this._applyModification(saturate, arguments);
|
1424 |
+
},
|
1425 |
+
greyscale: function() {
|
1426 |
+
return this._applyModification(greyscale, arguments);
|
1427 |
+
},
|
1428 |
+
spin: function() {
|
1429 |
+
return this._applyModification(spin, arguments);
|
1430 |
+
},
|
1431 |
+
|
1432 |
+
_applyCombination: function(fn, args) {
|
1433 |
+
return fn.apply(null, [this].concat([].slice.call(args)));
|
1434 |
+
},
|
1435 |
+
analogous: function() {
|
1436 |
+
return this._applyCombination(analogous, arguments);
|
1437 |
+
},
|
1438 |
+
complement: function() {
|
1439 |
+
return this._applyCombination(complement, arguments);
|
1440 |
+
},
|
1441 |
+
monochromatic: function() {
|
1442 |
+
return this._applyCombination(monochromatic, arguments);
|
1443 |
+
},
|
1444 |
+
splitcomplement: function() {
|
1445 |
+
return this._applyCombination(splitcomplement, arguments);
|
1446 |
+
},
|
1447 |
+
triad: function() {
|
1448 |
+
return this._applyCombination(triad, arguments);
|
1449 |
+
},
|
1450 |
+
tetrad: function() {
|
1451 |
+
return this._applyCombination(tetrad, arguments);
|
1452 |
+
}
|
1453 |
+
};
|
1454 |
+
|
1455 |
+
// If input is an object, force 1 into "1.0" to handle ratios properly
|
1456 |
+
// String input requires "1.0" as input, so 1 will be treated as 1
|
1457 |
+
tinycolor.fromRatio = function(color, opts) {
|
1458 |
+
if (typeof color == "object") {
|
1459 |
+
var newColor = {};
|
1460 |
+
for (var i in color) {
|
1461 |
+
if (color.hasOwnProperty(i)) {
|
1462 |
+
if (i === "a") {
|
1463 |
+
newColor[i] = color[i];
|
1464 |
+
}
|
1465 |
+
else {
|
1466 |
+
newColor[i] = convertToPercentage(color[i]);
|
1467 |
+
}
|
1468 |
+
}
|
1469 |
+
}
|
1470 |
+
color = newColor;
|
1471 |
+
}
|
1472 |
+
|
1473 |
+
return tinycolor(color, opts);
|
1474 |
+
};
|
1475 |
+
|
1476 |
+
// Given a string or object, convert that input to RGB
|
1477 |
+
// Possible string inputs:
|
1478 |
+
//
|
1479 |
+
// "red"
|
1480 |
+
// "#f00" or "f00"
|
1481 |
+
// "#ff0000" or "ff0000"
|
1482 |
+
// "#ff000000" or "ff000000"
|
1483 |
+
// "rgb 255 0 0" or "rgb (255, 0, 0)"
|
1484 |
+
// "rgb 1.0 0 0" or "rgb (1, 0, 0)"
|
1485 |
+
// "rgba (255, 0, 0, 1)" or "rgba 255, 0, 0, 1"
|
1486 |
+
// "rgba (1.0, 0, 0, 1)" or "rgba 1.0, 0, 0, 1"
|
1487 |
+
// "hsl(0, 100%, 50%)" or "hsl 0 100% 50%"
|
1488 |
+
// "hsla(0, 100%, 50%, 1)" or "hsla 0 100% 50%, 1"
|
1489 |
+
// "hsv(0, 100%, 100%)" or "hsv 0 100% 100%"
|
1490 |
+
//
|
1491 |
+
function inputToRGB(color) {
|
1492 |
+
|
1493 |
+
var rgb = { r: 0, g: 0, b: 0 };
|
1494 |
+
var a = 1;
|
1495 |
+
var ok = false;
|
1496 |
+
var format = false;
|
1497 |
+
|
1498 |
+
if (typeof color == "string") {
|
1499 |
+
color = stringInputToObject(color);
|
1500 |
+
}
|
1501 |
+
|
1502 |
+
if (typeof color == "object") {
|
1503 |
+
if (color.hasOwnProperty("r") && color.hasOwnProperty("g") && color.hasOwnProperty("b")) {
|
1504 |
+
rgb = rgbToRgb(color.r, color.g, color.b);
|
1505 |
+
ok = true;
|
1506 |
+
format = String(color.r).substr(-1) === "%" ? "prgb" : "rgb";
|
1507 |
+
}
|
1508 |
+
else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("v")) {
|
1509 |
+
color.s = convertToPercentage(color.s);
|
1510 |
+
color.v = convertToPercentage(color.v);
|
1511 |
+
rgb = hsvToRgb(color.h, color.s, color.v);
|
1512 |
+
ok = true;
|
1513 |
+
format = "hsv";
|
1514 |
+
}
|
1515 |
+
else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("l")) {
|
1516 |
+
color.s = convertToPercentage(color.s);
|
1517 |
+
color.l = convertToPercentage(color.l);
|
1518 |
+
rgb = hslToRgb(color.h, color.s, color.l);
|
1519 |
+
ok = true;
|
1520 |
+
format = "hsl";
|
1521 |
+
}
|
1522 |
+
|
1523 |
+
if (color.hasOwnProperty("a")) {
|
1524 |
+
a = color.a;
|
1525 |
+
}
|
1526 |
+
}
|
1527 |
+
|
1528 |
+
a = boundAlpha(a);
|
1529 |
+
|
1530 |
+
return {
|
1531 |
+
ok: ok,
|
1532 |
+
format: color.format || format,
|
1533 |
+
r: mathMin(255, mathMax(rgb.r, 0)),
|
1534 |
+
g: mathMin(255, mathMax(rgb.g, 0)),
|
1535 |
+
b: mathMin(255, mathMax(rgb.b, 0)),
|
1536 |
+
a: a
|
1537 |
+
};
|
1538 |
+
}
|
1539 |
+
|
1540 |
+
|
1541 |
+
// Conversion Functions
|
1542 |
+
// --------------------
|
1543 |
+
|
1544 |
+
// `rgbToHsl`, `rgbToHsv`, `hslToRgb`, `hsvToRgb` modified from:
|
1545 |
+
// <http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript>
|
1546 |
+
|
1547 |
+
// `rgbToRgb`
|
1548 |
+
// Handle bounds / percentage checking to conform to CSS color spec
|
1549 |
+
// <http://www.w3.org/TR/css3-color/>
|
1550 |
+
// *Assumes:* r, g, b in [0, 255] or [0, 1]
|
1551 |
+
// *Returns:* { r, g, b } in [0, 255]
|
1552 |
+
function rgbToRgb(r, g, b){
|
1553 |
+
return {
|
1554 |
+
r: bound01(r, 255) * 255,
|
1555 |
+
g: bound01(g, 255) * 255,
|
1556 |
+
b: bound01(b, 255) * 255
|
1557 |
+
};
|
1558 |
+
}
|
1559 |
+
|
1560 |
+
// `rgbToHsl`
|
1561 |
+
// Converts an RGB color value to HSL.
|
1562 |
+
// *Assumes:* r, g, and b are contained in [0, 255] or [0, 1]
|
1563 |
+
// *Returns:* { h, s, l } in [0,1]
|
1564 |
+
function rgbToHsl(r, g, b) {
|
1565 |
+
|
1566 |
+
r = bound01(r, 255);
|
1567 |
+
g = bound01(g, 255);
|
1568 |
+
b = bound01(b, 255);
|
1569 |
+
|
1570 |
+
var max = mathMax(r, g, b), min = mathMin(r, g, b);
|
1571 |
+
var h, s, l = (max + min) / 2;
|
1572 |
+
|
1573 |
+
if(max == min) {
|
1574 |
+
h = s = 0; // achromatic
|
1575 |
+
}
|
1576 |
+
else {
|
1577 |
+
var d = max - min;
|
1578 |
+
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
1579 |
+
switch(max) {
|
1580 |
+
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
|
1581 |
+
case g: h = (b - r) / d + 2; break;
|
1582 |
+
case b: h = (r - g) / d + 4; break;
|
1583 |
+
}
|
1584 |
+
|
1585 |
+
h /= 6;
|
1586 |
+
}
|
1587 |
+
|
1588 |
+
return { h: h, s: s, l: l };
|
1589 |
+
}
|
1590 |
+
|
1591 |
+
// `hslToRgb`
|
1592 |
+
// Converts an HSL color value to RGB.
|
1593 |
+
// *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100]
|
1594 |
+
// *Returns:* { r, g, b } in the set [0, 255]
|
1595 |
+
function hslToRgb(h, s, l) {
|
1596 |
+
var r, g, b;
|
1597 |
+
|
1598 |
+
h = bound01(h, 360);
|
1599 |
+
s = bound01(s, 100);
|
1600 |
+
l = bound01(l, 100);
|
1601 |
+
|
1602 |
+
function hue2rgb(p, q, t) {
|
1603 |
+
if(t < 0) t += 1;
|
1604 |
+
if(t > 1) t -= 1;
|
1605 |
+
if(t < 1/6) return p + (q - p) * 6 * t;
|
1606 |
+
if(t < 1/2) return q;
|
1607 |
+
if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
1608 |
+
return p;
|
1609 |
+
}
|
1610 |
+
|
1611 |
+
if(s === 0) {
|
1612 |
+
r = g = b = l; // achromatic
|
1613 |
+
}
|
1614 |
+
else {
|
1615 |
+
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
1616 |
+
var p = 2 * l - q;
|
1617 |
+
r = hue2rgb(p, q, h + 1/3);
|
1618 |
+
g = hue2rgb(p, q, h);
|
1619 |
+
b = hue2rgb(p, q, h - 1/3);
|
1620 |
+
}
|
1621 |
+
|
1622 |
+
return { r: r * 255, g: g * 255, b: b * 255 };
|
1623 |
+
}
|
1624 |
+
|
1625 |
+
// `rgbToHsv`
|
1626 |
+
// Converts an RGB color value to HSV
|
1627 |
+
// *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1]
|
1628 |
+
// *Returns:* { h, s, v } in [0,1]
|
1629 |
+
function rgbToHsv(r, g, b) {
|
1630 |
+
|
1631 |
+
r = bound01(r, 255);
|
1632 |
+
g = bound01(g, 255);
|
1633 |
+
b = bound01(b, 255);
|
1634 |
+
|
1635 |
+
var max = mathMax(r, g, b), min = mathMin(r, g, b);
|
1636 |
+
var h, s, v = max;
|
1637 |
+
|
1638 |
+
var d = max - min;
|
1639 |
+
s = max === 0 ? 0 : d / max;
|
1640 |
+
|
1641 |
+
if(max == min) {
|
1642 |
+
h = 0; // achromatic
|
1643 |
+
}
|
1644 |
+
else {
|
1645 |
+
switch(max) {
|
1646 |
+
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
|
1647 |
+
case g: h = (b - r) / d + 2; break;
|
1648 |
+
case b: h = (r - g) / d + 4; break;
|
1649 |
+
}
|
1650 |
+
h /= 6;
|
1651 |
+
}
|
1652 |
+
return { h: h, s: s, v: v };
|
1653 |
+
}
|
1654 |
+
|
1655 |
+
// `hsvToRgb`
|
1656 |
+
// Converts an HSV color value to RGB.
|
1657 |
+
// *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100]
|
1658 |
+
// *Returns:* { r, g, b } in the set [0, 255]
|
1659 |
+
function hsvToRgb(h, s, v) {
|
1660 |
+
|
1661 |
+
h = bound01(h, 360) * 6;
|
1662 |
+
s = bound01(s, 100);
|
1663 |
+
v = bound01(v, 100);
|
1664 |
+
|
1665 |
+
var i = math.floor(h),
|
1666 |
+
f = h - i,
|
1667 |
+
p = v * (1 - s),
|
1668 |
+
q = v * (1 - f * s),
|
1669 |
+
t = v * (1 - (1 - f) * s),
|
1670 |
+
mod = i % 6,
|
1671 |
+
r = [v, q, p, p, t, v][mod],
|
1672 |
+
g = [t, v, v, q, p, p][mod],
|
1673 |
+
b = [p, p, t, v, v, q][mod];
|
1674 |
+
|
1675 |
+
return { r: r * 255, g: g * 255, b: b * 255 };
|
1676 |
+
}
|
1677 |
+
|
1678 |
+
// `rgbToHex`
|
1679 |
+
// Converts an RGB color to hex
|
1680 |
+
// Assumes r, g, and b are contained in the set [0, 255]
|
1681 |
+
// Returns a 3 or 6 character hex
|
1682 |
+
function rgbToHex(r, g, b, allow3Char) {
|
1683 |
+
|
1684 |
+
var hex = [
|
1685 |
+
pad2(mathRound(r).toString(16)),
|
1686 |
+
pad2(mathRound(g).toString(16)),
|
1687 |
+
pad2(mathRound(b).toString(16))
|
1688 |
+
];
|
1689 |
+
|
1690 |
+
// Return a 3 character hex if possible
|
1691 |
+
if (allow3Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1)) {
|
1692 |
+
return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0);
|
1693 |
+
}
|
1694 |
+
|
1695 |
+
return hex.join("");
|
1696 |
+
}
|
1697 |
+
// `rgbaToHex`
|
1698 |
+
// Converts an RGBA color plus alpha transparency to hex
|
1699 |
+
// Assumes r, g, b and a are contained in the set [0, 255]
|
1700 |
+
// Returns an 8 character hex
|
1701 |
+
function rgbaToHex(r, g, b, a) {
|
1702 |
+
|
1703 |
+
var hex = [
|
1704 |
+
pad2(convertDecimalToHex(a)),
|
1705 |
+
pad2(mathRound(r).toString(16)),
|
1706 |
+
pad2(mathRound(g).toString(16)),
|
1707 |
+
pad2(mathRound(b).toString(16))
|
1708 |
+
];
|
1709 |
+
|
1710 |
+
return hex.join("");
|
1711 |
+
}
|
1712 |
+
|
1713 |
+
// `equals`
|
1714 |
+
// Can be called with any tinycolor input
|
1715 |
+
tinycolor.equals = function (color1, color2) {
|
1716 |
+
if (!color1 || !color2) { return false; }
|
1717 |
+
return tinycolor(color1).toRgbString() == tinycolor(color2).toRgbString();
|
1718 |
+
};
|
1719 |
+
tinycolor.random = function() {
|
1720 |
+
return tinycolor.fromRatio({
|
1721 |
+
r: mathRandom(),
|
1722 |
+
g: mathRandom(),
|
1723 |
+
b: mathRandom()
|
1724 |
+
});
|
1725 |
+
};
|
1726 |
+
|
1727 |
+
|
1728 |
+
// Modification Functions
|
1729 |
+
// ----------------------
|
1730 |
+
// Thanks to less.js for some of the basics here
|
1731 |
+
// <https://github.com/cloudhead/less.js/blob/master/lib/less/functions.js>
|
1732 |
+
|
1733 |
+
function desaturate(color, amount) {
|
1734 |
+
amount = (amount === 0) ? 0 : (amount || 10);
|
1735 |
+
var hsl = tinycolor(color).toHsl();
|
1736 |
+
hsl.s -= amount / 100;
|
1737 |
+
hsl.s = clamp01(hsl.s);
|
1738 |
+
return tinycolor(hsl);
|
1739 |
+
}
|
1740 |
+
|
1741 |
+
function saturate(color, amount) {
|
1742 |
+
amount = (amount === 0) ? 0 : (amount || 10);
|
1743 |
+
var hsl = tinycolor(color).toHsl();
|
1744 |
+
hsl.s += amount / 100;
|
1745 |
+
hsl.s = clamp01(hsl.s);
|
1746 |
+
return tinycolor(hsl);
|
1747 |
+
}
|
1748 |
+
|
1749 |
+
function greyscale(color) {
|
1750 |
+
return tinycolor(color).desaturate(100);
|
1751 |
+
}
|
1752 |
+
|
1753 |
+
function lighten (color, amount) {
|
1754 |
+
amount = (amount === 0) ? 0 : (amount || 10);
|
1755 |
+
var hsl = tinycolor(color).toHsl();
|
1756 |
+
hsl.l += amount / 100;
|
1757 |
+
hsl.l = clamp01(hsl.l);
|
1758 |
+
return tinycolor(hsl);
|
1759 |
+
}
|
1760 |
+
|
1761 |
+
function brighten(color, amount) {
|
1762 |
+
amount = (amount === 0) ? 0 : (amount || 10);
|
1763 |
+
var rgb = tinycolor(color).toRgb();
|
1764 |
+
rgb.r = mathMax(0, mathMin(255, rgb.r - mathRound(255 * - (amount / 100))));
|
1765 |
+
rgb.g = mathMax(0, mathMin(255, rgb.g - mathRound(255 * - (amount / 100))));
|
1766 |
+
rgb.b = mathMax(0, mathMin(255, rgb.b - mathRound(255 * - (amount / 100))));
|
1767 |
+
return tinycolor(rgb);
|
1768 |
+
}
|
1769 |
+
|
1770 |
+
function darken (color, amount) {
|
1771 |
+
amount = (amount === 0) ? 0 : (amount || 10);
|
1772 |
+
var hsl = tinycolor(color).toHsl();
|
1773 |
+
hsl.l -= amount / 100;
|
1774 |
+
hsl.l = clamp01(hsl.l);
|
1775 |
+
return tinycolor(hsl);
|
1776 |
+
}
|
1777 |
+
|
1778 |
+
// Spin takes a positive or negative amount within [-360, 360] indicating the change of hue.
|
1779 |
+
// Values outside of this range will be wrapped into this range.
|
1780 |
+
function spin(color, amount) {
|
1781 |
+
var hsl = tinycolor(color).toHsl();
|
1782 |
+
var hue = (mathRound(hsl.h) + amount) % 360;
|
1783 |
+
hsl.h = hue < 0 ? 360 + hue : hue;
|
1784 |
+
return tinycolor(hsl);
|
1785 |
+
}
|
1786 |
+
|
1787 |
+
// Combination Functions
|
1788 |
+
// ---------------------
|
1789 |
+
// Thanks to jQuery xColor for some of the ideas behind these
|
1790 |
+
// <https://github.com/infusion/jQuery-xcolor/blob/master/jquery.xcolor.js>
|
1791 |
+
|
1792 |
+
function complement(color) {
|
1793 |
+
var hsl = tinycolor(color).toHsl();
|
1794 |
+
hsl.h = (hsl.h + 180) % 360;
|
1795 |
+
return tinycolor(hsl);
|
1796 |
+
}
|
1797 |
+
|
1798 |
+
function triad(color) {
|
1799 |
+
var hsl = tinycolor(color).toHsl();
|
1800 |
+
var h = hsl.h;
|
1801 |
+
return [
|
1802 |
+
tinycolor(color),
|
1803 |
+
tinycolor({ h: (h + 120) % 360, s: hsl.s, l: hsl.l }),
|
1804 |
+
tinycolor({ h: (h + 240) % 360, s: hsl.s, l: hsl.l })
|
1805 |
+
];
|
1806 |
+
}
|
1807 |
+
|
1808 |
+
function tetrad(color) {
|
1809 |
+
var hsl = tinycolor(color).toHsl();
|
1810 |
+
var h = hsl.h;
|
1811 |
+
return [
|
1812 |
+
tinycolor(color),
|
1813 |
+
tinycolor({ h: (h + 90) % 360, s: hsl.s, l: hsl.l }),
|
1814 |
+
tinycolor({ h: (h + 180) % 360, s: hsl.s, l: hsl.l }),
|
1815 |
+
tinycolor({ h: (h + 270) % 360, s: hsl.s, l: hsl.l })
|
1816 |
+
];
|
1817 |
+
}
|
1818 |
+
|
1819 |
+
function splitcomplement(color) {
|
1820 |
+
var hsl = tinycolor(color).toHsl();
|
1821 |
+
var h = hsl.h;
|
1822 |
+
return [
|
1823 |
+
tinycolor(color),
|
1824 |
+
tinycolor({ h: (h + 72) % 360, s: hsl.s, l: hsl.l}),
|
1825 |
+
tinycolor({ h: (h + 216) % 360, s: hsl.s, l: hsl.l})
|
1826 |
+
];
|
1827 |
+
}
|
1828 |
+
|
1829 |
+
function analogous(color, results, slices) {
|
1830 |
+
results = results || 6;
|
1831 |
+
slices = slices || 30;
|
1832 |
+
|
1833 |
+
var hsl = tinycolor(color).toHsl();
|
1834 |
+
var part = 360 / slices;
|
1835 |
+
var ret = [tinycolor(color)];
|
1836 |
+
|
1837 |
+
for (hsl.h = ((hsl.h - (part * results >> 1)) + 720) % 360; --results; ) {
|
1838 |
+
hsl.h = (hsl.h + part) % 360;
|
1839 |
+
ret.push(tinycolor(hsl));
|
1840 |
+
}
|
1841 |
+
return ret;
|
1842 |
+
}
|
1843 |
+
|
1844 |
+
function monochromatic(color, results) {
|
1845 |
+
results = results || 6;
|
1846 |
+
var hsv = tinycolor(color).toHsv();
|
1847 |
+
var h = hsv.h, s = hsv.s, v = hsv.v;
|
1848 |
+
var ret = [];
|
1849 |
+
var modification = 1 / results;
|
1850 |
+
|
1851 |
+
while (results--) {
|
1852 |
+
ret.push(tinycolor({ h: h, s: s, v: v}));
|
1853 |
+
v = (v + modification) % 1;
|
1854 |
+
}
|
1855 |
+
|
1856 |
+
return ret;
|
1857 |
+
}
|
1858 |
+
|
1859 |
+
// Utility Functions
|
1860 |
+
// ---------------------
|
1861 |
+
|
1862 |
+
tinycolor.mix = function(color1, color2, amount) {
|
1863 |
+
amount = (amount === 0) ? 0 : (amount || 50);
|
1864 |
+
|
1865 |
+
var rgb1 = tinycolor(color1).toRgb();
|
1866 |
+
var rgb2 = tinycolor(color2).toRgb();
|
1867 |
+
|
1868 |
+
var p = amount / 100;
|
1869 |
+
var w = p * 2 - 1;
|
1870 |
+
var a = rgb2.a - rgb1.a;
|
1871 |
+
|
1872 |
+
var w1;
|
1873 |
+
|
1874 |
+
if (w * a == -1) {
|
1875 |
+
w1 = w;
|
1876 |
+
} else {
|
1877 |
+
w1 = (w + a) / (1 + w * a);
|
1878 |
+
}
|
1879 |
+
|
1880 |
+
w1 = (w1 + 1) / 2;
|
1881 |
+
|
1882 |
+
var w2 = 1 - w1;
|
1883 |
+
|
1884 |
+
var rgba = {
|
1885 |
+
r: rgb2.r * w1 + rgb1.r * w2,
|
1886 |
+
g: rgb2.g * w1 + rgb1.g * w2,
|
1887 |
+
b: rgb2.b * w1 + rgb1.b * w2,
|
1888 |
+
a: rgb2.a * p + rgb1.a * (1 - p)
|
1889 |
+
};
|
1890 |
+
|
1891 |
+
return tinycolor(rgba);
|
1892 |
+
};
|
1893 |
+
|
1894 |
+
|
1895 |
+
// Readability Functions
|
1896 |
+
// ---------------------
|
1897 |
+
// <http://www.w3.org/TR/AERT#color-contrast>
|
1898 |
+
|
1899 |
+
// `readability`
|
1900 |
+
// Analyze the 2 colors and returns an object with the following properties:
|
1901 |
+
// `brightness`: difference in brightness between the two colors
|
1902 |
+
// `color`: difference in color/hue between the two colors
|
1903 |
+
tinycolor.readability = function(color1, color2) {
|
1904 |
+
var c1 = tinycolor(color1);
|
1905 |
+
var c2 = tinycolor(color2);
|
1906 |
+
var rgb1 = c1.toRgb();
|
1907 |
+
var rgb2 = c2.toRgb();
|
1908 |
+
var brightnessA = c1.getBrightness();
|
1909 |
+
var brightnessB = c2.getBrightness();
|
1910 |
+
var colorDiff = (
|
1911 |
+
Math.max(rgb1.r, rgb2.r) - Math.min(rgb1.r, rgb2.r) +
|
1912 |
+
Math.max(rgb1.g, rgb2.g) - Math.min(rgb1.g, rgb2.g) +
|
1913 |
+
Math.max(rgb1.b, rgb2.b) - Math.min(rgb1.b, rgb2.b)
|
1914 |
+
);
|
1915 |
+
|
1916 |
+
return {
|
1917 |
+
brightness: Math.abs(brightnessA - brightnessB),
|
1918 |
+
color: colorDiff
|
1919 |
+
};
|
1920 |
+
};
|
1921 |
+
|
1922 |
+
// `readable`
|
1923 |
+
// http://www.w3.org/TR/AERT#color-contrast
|
1924 |
+
// Ensure that foreground and background color combinations provide sufficient contrast.
|
1925 |
+
// *Example*
|
1926 |
+
// tinycolor.isReadable("#000", "#111") => false
|
1927 |
+
tinycolor.isReadable = function(color1, color2) {
|
1928 |
+
var readability = tinycolor.readability(color1, color2);
|
1929 |
+
return readability.brightness > 125 && readability.color > 500;
|
1930 |
+
};
|
1931 |
+
|
1932 |
+
// `mostReadable`
|
1933 |
+
// Given a base color and a list of possible foreground or background
|
1934 |
+
// colors for that base, returns the most readable color.
|
1935 |
+
// *Example*
|
1936 |
+
// tinycolor.mostReadable("#123", ["#fff", "#000"]) => "#000"
|
1937 |
+
tinycolor.mostReadable = function(baseColor, colorList) {
|
1938 |
+
var bestColor = null;
|
1939 |
+
var bestScore = 0;
|
1940 |
+
var bestIsReadable = false;
|
1941 |
+
for (var i=0; i < colorList.length; i++) {
|
1942 |
+
|
1943 |
+
// We normalize both around the "acceptable" breaking point,
|
1944 |
+
// but rank brightness constrast higher than hue.
|
1945 |
+
|
1946 |
+
var readability = tinycolor.readability(baseColor, colorList[i]);
|
1947 |
+
var readable = readability.brightness > 125 && readability.color > 500;
|
1948 |
+
var score = 3 * (readability.brightness / 125) + (readability.color / 500);
|
1949 |
+
|
1950 |
+
if ((readable && ! bestIsReadable) ||
|
1951 |
+
(readable && bestIsReadable && score > bestScore) ||
|
1952 |
+
((! readable) && (! bestIsReadable) && score > bestScore)) {
|
1953 |
+
bestIsReadable = readable;
|
1954 |
+
bestScore = score;
|
1955 |
+
bestColor = tinycolor(colorList[i]);
|
1956 |
+
}
|
1957 |
+
}
|
1958 |
+
return bestColor;
|
1959 |
+
};
|
1960 |
+
|
1961 |
+
|
1962 |
+
// Big List of Colors
|
1963 |
+
// ------------------
|
1964 |
+
// <http://www.w3.org/TR/css3-color/#svg-color>
|
1965 |
+
var names = tinycolor.names = {
|
1966 |
+
aliceblue: "f0f8ff",
|
1967 |
+
antiquewhite: "faebd7",
|
1968 |
+
aqua: "0ff",
|
1969 |
+
aquamarine: "7fffd4",
|
1970 |
+
azure: "f0ffff",
|
1971 |
+
beige: "f5f5dc",
|
1972 |
+
bisque: "ffe4c4",
|
1973 |
+
black: "000",
|
1974 |
+
blanchedalmond: "ffebcd",
|
1975 |
+
blue: "00f",
|
1976 |
+
blueviolet: "8a2be2",
|
1977 |
+
brown: "a52a2a",
|
1978 |
+
burlywood: "deb887",
|
1979 |
+
burntsienna: "ea7e5d",
|
1980 |
+
cadetblue: "5f9ea0",
|
1981 |
+
chartreuse: "7fff00",
|
1982 |
+
chocolate: "d2691e",
|
1983 |
+
coral: "ff7f50",
|
1984 |
+
cornflowerblue: "6495ed",
|
1985 |
+
cornsilk: "fff8dc",
|
1986 |
+
crimson: "dc143c",
|
1987 |
+
cyan: "0ff",
|
1988 |
+
darkblue: "00008b",
|
1989 |
+
darkcyan: "008b8b",
|
1990 |
+
darkgoldenrod: "b8860b",
|
1991 |
+
darkgray: "a9a9a9",
|
1992 |
+
darkgreen: "006400",
|
1993 |
+
darkgrey: "a9a9a9",
|
1994 |
+
darkkhaki: "bdb76b",
|
1995 |
+
darkmagenta: "8b008b",
|
1996 |
+
darkolivegreen: "556b2f",
|
1997 |
+
darkorange: "ff8c00",
|
1998 |
+
darkorchid: "9932cc",
|
1999 |
+
darkred: "8b0000",
|
2000 |
+
darksalmon: "e9967a",
|
2001 |
+
darkseagreen: "8fbc8f",
|
2002 |
+
darkslateblue: "483d8b",
|
2003 |
+
darkslategray: "2f4f4f",
|
2004 |
+
darkslategrey: "2f4f4f",
|
2005 |
+
darkturquoise: "00ced1",
|
2006 |
+
darkviolet: "9400d3",
|
2007 |
+
deeppink: "ff1493",
|
2008 |
+
deepskyblue: "00bfff",
|
2009 |
+
dimgray: "696969",
|
2010 |
+
dimgrey: "696969",
|
2011 |
+
dodgerblue: "1e90ff",
|
2012 |
+
firebrick: "b22222",
|
2013 |
+
floralwhite: "fffaf0",
|
2014 |
+
forestgreen: "228b22",
|
2015 |
+
fuchsia: "f0f",
|
2016 |
+
gainsboro: "dcdcdc",
|
2017 |
+
ghostwhite: "f8f8ff",
|
2018 |
+
gold: "ffd700",
|
2019 |
+
goldenrod: "daa520",
|
2020 |
+
gray: "808080",
|
2021 |
+
green: "008000",
|
2022 |
+
greenyellow: "adff2f",
|
2023 |
+
grey: "808080",
|
2024 |
+
honeydew: "f0fff0",
|
2025 |
+
hotpink: "ff69b4",
|
2026 |
+
indianred: "cd5c5c",
|
2027 |
+
indigo: "4b0082",
|
2028 |
+
ivory: "fffff0",
|
2029 |
+
khaki: "f0e68c",
|
2030 |
+
lavender: "e6e6fa",
|
2031 |
+
lavenderblush: "fff0f5",
|
2032 |
+
lawngreen: "7cfc00",
|
2033 |
+
lemonchiffon: "fffacd",
|
2034 |
+
lightblue: "add8e6",
|
2035 |
+
lightcoral: "f08080",
|
2036 |
+
lightcyan: "e0ffff",
|
2037 |
+
lightgoldenrodyellow: "fafad2",
|
2038 |
+
lightgray: "d3d3d3",
|
2039 |
+
lightgreen: "90ee90",
|
2040 |
+
lightgrey: "d3d3d3",
|
2041 |
+
lightpink: "ffb6c1",
|
2042 |
+
lightsalmon: "ffa07a",
|
2043 |
+
lightseagreen: "20b2aa",
|
2044 |
+
lightskyblue: "87cefa",
|
2045 |
+
lightslategray: "789",
|
2046 |
+
lightslategrey: "789",
|
2047 |
+
lightsteelblue: "b0c4de",
|
2048 |
+
lightyellow: "ffffe0",
|
2049 |
+
lime: "0f0",
|
2050 |
+
limegreen: "32cd32",
|
2051 |
+
linen: "faf0e6",
|
2052 |
+
magenta: "f0f",
|
2053 |
+
maroon: "800000",
|
2054 |
+
mediumaquamarine: "66cdaa",
|
2055 |
+
mediumblue: "0000cd",
|
2056 |
+
mediumorchid: "ba55d3",
|
2057 |
+
mediumpurple: "9370db",
|
2058 |
+
mediumseagreen: "3cb371",
|
2059 |
+
mediumslateblue: "7b68ee",
|
2060 |
+
mediumspringgreen: "00fa9a",
|
2061 |
+
mediumturquoise: "48d1cc",
|
2062 |
+
mediumvioletred: "c71585",
|
2063 |
+
midnightblue: "191970",
|
2064 |
+
mintcream: "f5fffa",
|
2065 |
+
mistyrose: "ffe4e1",
|
2066 |
+
moccasin: "ffe4b5",
|
2067 |
+
navajowhite: "ffdead",
|
2068 |
+
navy: "000080",
|
2069 |
+
oldlace: "fdf5e6",
|
2070 |
+
olive: "808000",
|
2071 |
+
olivedrab: "6b8e23",
|
2072 |
+
orange: "ffa500",
|
2073 |
+
orangered: "ff4500",
|
2074 |
+
orchid: "da70d6",
|
2075 |
+
palegoldenrod: "eee8aa",
|
2076 |
+
palegreen: "98fb98",
|
2077 |
+
paleturquoise: "afeeee",
|
2078 |
+
palevioletred: "db7093",
|
2079 |
+
papayawhip: "ffefd5",
|
2080 |
+
peachpuff: "ffdab9",
|
2081 |
+
peru: "cd853f",
|
2082 |
+
pink: "ffc0cb",
|
2083 |
+
plum: "dda0dd",
|
2084 |
+
powderblue: "b0e0e6",
|
2085 |
+
purple: "800080",
|
2086 |
+
rebeccapurple: "663399",
|
2087 |
+
red: "f00",
|
2088 |
+
rosybrown: "bc8f8f",
|
2089 |
+
royalblue: "4169e1",
|
2090 |
+
saddlebrown: "8b4513",
|
2091 |
+
salmon: "fa8072",
|
2092 |
+
sandybrown: "f4a460",
|
2093 |
+
seagreen: "2e8b57",
|
2094 |
+
seashell: "fff5ee",
|
2095 |
+
sienna: "a0522d",
|
2096 |
+
silver: "c0c0c0",
|
2097 |
+
skyblue: "87ceeb",
|
2098 |
+
slateblue: "6a5acd",
|
2099 |
+
slategray: "708090",
|
2100 |
+
slategrey: "708090",
|
2101 |
+
snow: "fffafa",
|
2102 |
+
springgreen: "00ff7f",
|
2103 |
+
steelblue: "4682b4",
|
2104 |
+
tan: "d2b48c",
|
2105 |
+
teal: "008080",
|
2106 |
+
thistle: "d8bfd8",
|
2107 |
+
tomato: "ff6347",
|
2108 |
+
turquoise: "40e0d0",
|
2109 |
+
violet: "ee82ee",
|
2110 |
+
wheat: "f5deb3",
|
2111 |
+
white: "fff",
|
2112 |
+
whitesmoke: "f5f5f5",
|
2113 |
+
yellow: "ff0",
|
2114 |
+
yellowgreen: "9acd32"
|
2115 |
+
};
|
2116 |
+
|
2117 |
+
// Make it easy to access colors via `hexNames[hex]`
|
2118 |
+
var hexNames = tinycolor.hexNames = flip(names);
|
2119 |
+
|
2120 |
+
|
2121 |
+
// Utilities
|
2122 |
+
// ---------
|
2123 |
+
|
2124 |
+
// `{ 'name1': 'val1' }` becomes `{ 'val1': 'name1' }`
|
2125 |
+
function flip(o) {
|
2126 |
+
var flipped = { };
|
2127 |
+
for (var i in o) {
|
2128 |
+
if (o.hasOwnProperty(i)) {
|
2129 |
+
flipped[o[i]] = i;
|
2130 |
+
}
|
2131 |
+
}
|
2132 |
+
return flipped;
|
2133 |
+
}
|
2134 |
+
|
2135 |
+
// Return a valid alpha value [0,1] with all invalid values being set to 1
|
2136 |
+
function boundAlpha(a) {
|
2137 |
+
a = parseFloat(a);
|
2138 |
+
|
2139 |
+
if (isNaN(a) || a < 0 || a > 1) {
|
2140 |
+
a = 1;
|
2141 |
+
}
|
2142 |
+
|
2143 |
+
return a;
|
2144 |
+
}
|
2145 |
+
|
2146 |
+
// Take input from [0, n] and return it as [0, 1]
|
2147 |
+
function bound01(n, max) {
|
2148 |
+
if (isOnePointZero(n)) { n = "100%"; }
|
2149 |
+
|
2150 |
+
var processPercent = isPercentage(n);
|
2151 |
+
n = mathMin(max, mathMax(0, parseFloat(n)));
|
2152 |
+
|
2153 |
+
// Automatically convert percentage into number
|
2154 |
+
if (processPercent) {
|
2155 |
+
n = parseInt(n * max, 10) / 100;
|
2156 |
+
}
|
2157 |
+
|
2158 |
+
// Handle floating point rounding errors
|
2159 |
+
if ((math.abs(n - max) < 0.000001)) {
|
2160 |
+
return 1;
|
2161 |
+
}
|
2162 |
+
|
2163 |
+
// Convert into [0, 1] range if it isn't already
|
2164 |
+
return (n % max) / parseFloat(max);
|
2165 |
+
}
|
2166 |
+
|
2167 |
+
// Force a number between 0 and 1
|
2168 |
+
function clamp01(val) {
|
2169 |
+
return mathMin(1, mathMax(0, val));
|
2170 |
+
}
|
2171 |
+
|
2172 |
+
// Parse a base-16 hex value into a base-10 integer
|
2173 |
+
function parseIntFromHex(val) {
|
2174 |
+
return parseInt(val, 16);
|
2175 |
+
}
|
2176 |
+
|
2177 |
+
// Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1
|
2178 |
+
// <http://stackoverflow.com/questions/7422072/javascript-how-to-detect-number-as-a-decimal-including-1-0>
|
2179 |
+
function isOnePointZero(n) {
|
2180 |
+
return typeof n == "string" && n.indexOf('.') != -1 && parseFloat(n) === 1;
|
2181 |
+
}
|
2182 |
+
|
2183 |
+
// Check to see if string passed in is a percentage
|
2184 |
+
function isPercentage(n) {
|
2185 |
+
return typeof n === "string" && n.indexOf('%') != -1;
|
2186 |
+
}
|
2187 |
+
|
2188 |
+
// Force a hex value to have 2 characters
|
2189 |
+
function pad2(c) {
|
2190 |
+
return c.length == 1 ? '0' + c : '' + c;
|
2191 |
+
}
|
2192 |
+
|
2193 |
+
// Replace a decimal with it's percentage value
|
2194 |
+
function convertToPercentage(n) {
|
2195 |
+
if (n <= 1) {
|
2196 |
+
n = (n * 100) + "%";
|
2197 |
+
}
|
2198 |
+
|
2199 |
+
return n;
|
2200 |
+
}
|
2201 |
+
|
2202 |
+
// Converts a decimal to a hex value
|
2203 |
+
function convertDecimalToHex(d) {
|
2204 |
+
return Math.round(parseFloat(d) * 255).toString(16);
|
2205 |
+
}
|
2206 |
+
// Converts a hex value to a decimal
|
2207 |
+
function convertHexToDecimal(h) {
|
2208 |
+
return (parseIntFromHex(h) / 255);
|
2209 |
+
}
|
2210 |
+
|
2211 |
+
var matchers = (function() {
|
2212 |
+
|
2213 |
+
// <http://www.w3.org/TR/css3-values/#integers>
|
2214 |
+
var CSS_INTEGER = "[-\\+]?\\d+%?";
|
2215 |
+
|
2216 |
+
// <http://www.w3.org/TR/css3-values/#number-value>
|
2217 |
+
var CSS_NUMBER = "[-\\+]?\\d*\\.\\d+%?";
|
2218 |
+
|
2219 |
+
// Allow positive/negative integer/number. Don't capture the either/or, just the entire outcome.
|
2220 |
+
var CSS_UNIT = "(?:" + CSS_NUMBER + ")|(?:" + CSS_INTEGER + ")";
|
2221 |
+
|
2222 |
+
// Actual matching.
|
2223 |
+
// Parentheses and commas are optional, but not required.
|
2224 |
+
// Whitespace can take the place of commas or opening paren
|
2225 |
+
var PERMISSIVE_MATCH3 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
|
2226 |
+
var PERMISSIVE_MATCH4 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
|
2227 |
+
|
2228 |
+
return {
|
2229 |
+
rgb: new RegExp("rgb" + PERMISSIVE_MATCH3),
|
2230 |
+
rgba: new RegExp("rgba" + PERMISSIVE_MATCH4),
|
2231 |
+
hsl: new RegExp("hsl" + PERMISSIVE_MATCH3),
|
2232 |
+
hsla: new RegExp("hsla" + PERMISSIVE_MATCH4),
|
2233 |
+
hsv: new RegExp("hsv" + PERMISSIVE_MATCH3),
|
2234 |
+
hsva: new RegExp("hsva" + PERMISSIVE_MATCH4),
|
2235 |
+
hex3: /^([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
|
2236 |
+
hex6: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,
|
2237 |
+
hex8: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/
|
2238 |
+
};
|
2239 |
+
})();
|
2240 |
+
|
2241 |
+
// `stringInputToObject`
|
2242 |
+
// Permissive string parsing. Take in a number of formats, and output an object
|
2243 |
+
// based on detected format. Returns `{ r, g, b }` or `{ h, s, l }` or `{ h, s, v}`
|
2244 |
+
function stringInputToObject(color) {
|
2245 |
+
|
2246 |
+
color = color.replace(trimLeft,'').replace(trimRight, '').toLowerCase();
|
2247 |
+
var named = false;
|
2248 |
+
if (names[color]) {
|
2249 |
+
color = names[color];
|
2250 |
+
named = true;
|
2251 |
+
}
|
2252 |
+
else if (color == 'transparent') {
|
2253 |
+
return { r: 0, g: 0, b: 0, a: 0, format: "name" };
|
2254 |
+
}
|
2255 |
+
|
2256 |
+
// Try to match string input using regular expressions.
|
2257 |
+
// Keep most of the number bounding out of this function - don't worry about [0,1] or [0,100] or [0,360]
|
2258 |
+
// Just return an object and let the conversion functions handle that.
|
2259 |
+
// This way the result will be the same whether the tinycolor is initialized with string or object.
|
2260 |
+
var match;
|
2261 |
+
if ((match = matchers.rgb.exec(color))) {
|
2262 |
+
return { r: match[1], g: match[2], b: match[3] };
|
2263 |
+
}
|
2264 |
+
if ((match = matchers.rgba.exec(color))) {
|
2265 |
+
return { r: match[1], g: match[2], b: match[3], a: match[4] };
|
2266 |
+
}
|
2267 |
+
if ((match = matchers.hsl.exec(color))) {
|
2268 |
+
return { h: match[1], s: match[2], l: match[3] };
|
2269 |
+
}
|
2270 |
+
if ((match = matchers.hsla.exec(color))) {
|
2271 |
+
return { h: match[1], s: match[2], l: match[3], a: match[4] };
|
2272 |
+
}
|
2273 |
+
if ((match = matchers.hsv.exec(color))) {
|
2274 |
+
return { h: match[1], s: match[2], v: match[3] };
|
2275 |
+
}
|
2276 |
+
if ((match = matchers.hsva.exec(color))) {
|
2277 |
+
return { h: match[1], s: match[2], v: match[3], a: match[4] };
|
2278 |
+
}
|
2279 |
+
if ((match = matchers.hex8.exec(color))) {
|
2280 |
+
return {
|
2281 |
+
a: convertHexToDecimal(match[1]),
|
2282 |
+
r: parseIntFromHex(match[2]),
|
2283 |
+
g: parseIntFromHex(match[3]),
|
2284 |
+
b: parseIntFromHex(match[4]),
|
2285 |
+
format: named ? "name" : "hex8"
|
2286 |
+
};
|
2287 |
+
}
|
2288 |
+
if ((match = matchers.hex6.exec(color))) {
|
2289 |
+
return {
|
2290 |
+
r: parseIntFromHex(match[1]),
|
2291 |
+
g: parseIntFromHex(match[2]),
|
2292 |
+
b: parseIntFromHex(match[3]),
|
2293 |
+
format: named ? "name" : "hex"
|
2294 |
+
};
|
2295 |
+
}
|
2296 |
+
if ((match = matchers.hex3.exec(color))) {
|
2297 |
+
return {
|
2298 |
+
r: parseIntFromHex(match[1] + '' + match[1]),
|
2299 |
+
g: parseIntFromHex(match[2] + '' + match[2]),
|
2300 |
+
b: parseIntFromHex(match[3] + '' + match[3]),
|
2301 |
+
format: named ? "name" : "hex"
|
2302 |
+
};
|
2303 |
+
}
|
2304 |
+
|
2305 |
+
return false;
|
2306 |
+
}
|
2307 |
+
|
2308 |
+
window.tinycolor = tinycolor;
|
2309 |
+
})();
|
2310 |
+
|
2311 |
+
$(function () {
|
2312 |
+
if ($.fn.spectrum.load) {
|
2313 |
+
$.fn.spectrum.processNativeColorInputs();
|
2314 |
+
}
|
2315 |
+
});
|
2316 |
+
|
2317 |
+
});
|
lib/simple-admin-pages/lib/pickadate/legacy.js
CHANGED
@@ -1,10 +1,10 @@
|
|
1 |
-
/*!
|
2 |
-
* Legacy browser support
|
3 |
-
*/
|
4 |
-
[].map||(Array.prototype.map=function(a,b){for(var c=this,d=c.length,e=new Array(d),f=0;f<d;f++)f in c&&(e[f]=a.call(b,c[f],f,c));return e}),[].filter||(Array.prototype.filter=function(a){if(null==this)throw new TypeError;var b=Object(this),c=b.length>>>0;if("function"!=typeof a)throw new TypeError;for(var d=[],e=arguments[1],f=0;f<c;f++)if(f in b){var g=b[f];a.call(e,g,f,b)&&d.push(g)}return d}),[].indexOf||(Array.prototype.indexOf=function(a){if(null==this)throw new TypeError;var b=Object(this),c=b.length>>>0;if(0===c)return-1;var d=0;if(arguments.length>1&&(d=Number(arguments[1]),d!=d?d=0:0!==d&&d!=1/0&&d!=-1/0&&(d=(d>0||-1)*Math.floor(Math.abs(d)))),d>=c)return-1;for(var e=d>=0?d:Math.max(c-Math.abs(d),0);e<c;e++)if(e in b&&b[e]===a)return e;return-1});/*!
|
5 |
-
* Cross-Browser Split 1.1.1
|
6 |
-
* Copyright 2007-2012 Steven Levithan <stevenlevithan.com>
|
7 |
-
* Available under the MIT License
|
8 |
-
* http://blog.stevenlevithan.com/archives/cross-browser-split
|
9 |
-
*/
|
10 |
var nativeSplit=String.prototype.split,compliantExecNpcg=void 0===/()??/.exec("")[1];String.prototype.split=function(a,b){var c=this;if("[object RegExp]"!==Object.prototype.toString.call(a))return nativeSplit.call(c,a,b);var d,e,f,g,h=[],i=(a.ignoreCase?"i":"")+(a.multiline?"m":"")+(a.extended?"x":"")+(a.sticky?"y":""),j=0;for(a=new RegExp(a.source,i+"g"),c+="",compliantExecNpcg||(d=new RegExp("^"+a.source+"$(?!\\s)",i)),b=void 0===b?-1>>>0:b>>>0;(e=a.exec(c))&&!((f=e.index+e[0].length)>j&&(h.push(c.slice(j,e.index)),!compliantExecNpcg&&e.length>1&&e[0].replace(d,function(){for(var a=1;a<arguments.length-2;a++)void 0===arguments[a]&&(e[a]=void 0)}),e.length>1&&e.index<c.length&&Array.prototype.push.apply(h,e.slice(1)),g=e[0].length,j=f,h.length>=b));)a.lastIndex===e.index&&a.lastIndex++;return j===c.length?!g&&a.test("")||h.push(""):h.push(c.slice(j)),h.length>b?h.slice(0,b):h};
|
1 |
+
/*!
|
2 |
+
* Legacy browser support
|
3 |
+
*/
|
4 |
+
[].map||(Array.prototype.map=function(a,b){for(var c=this,d=c.length,e=new Array(d),f=0;f<d;f++)f in c&&(e[f]=a.call(b,c[f],f,c));return e}),[].filter||(Array.prototype.filter=function(a){if(null==this)throw new TypeError;var b=Object(this),c=b.length>>>0;if("function"!=typeof a)throw new TypeError;for(var d=[],e=arguments[1],f=0;f<c;f++)if(f in b){var g=b[f];a.call(e,g,f,b)&&d.push(g)}return d}),[].indexOf||(Array.prototype.indexOf=function(a){if(null==this)throw new TypeError;var b=Object(this),c=b.length>>>0;if(0===c)return-1;var d=0;if(arguments.length>1&&(d=Number(arguments[1]),d!=d?d=0:0!==d&&d!=1/0&&d!=-1/0&&(d=(d>0||-1)*Math.floor(Math.abs(d)))),d>=c)return-1;for(var e=d>=0?d:Math.max(c-Math.abs(d),0);e<c;e++)if(e in b&&b[e]===a)return e;return-1});/*!
|
5 |
+
* Cross-Browser Split 1.1.1
|
6 |
+
* Copyright 2007-2012 Steven Levithan <stevenlevithan.com>
|
7 |
+
* Available under the MIT License
|
8 |
+
* http://blog.stevenlevithan.com/archives/cross-browser-split
|
9 |
+
*/
|
10 |
var nativeSplit=String.prototype.split,compliantExecNpcg=void 0===/()??/.exec("")[1];String.prototype.split=function(a,b){var c=this;if("[object RegExp]"!==Object.prototype.toString.call(a))return nativeSplit.call(c,a,b);var d,e,f,g,h=[],i=(a.ignoreCase?"i":"")+(a.multiline?"m":"")+(a.extended?"x":"")+(a.sticky?"y":""),j=0;for(a=new RegExp(a.source,i+"g"),c+="",compliantExecNpcg||(d=new RegExp("^"+a.source+"$(?!\\s)",i)),b=void 0===b?-1>>>0:b>>>0;(e=a.exec(c))&&!((f=e.index+e[0].length)>j&&(h.push(c.slice(j,e.index)),!compliantExecNpcg&&e.length>1&&e[0].replace(d,function(){for(var a=1;a<arguments.length-2;a++)void 0===arguments[a]&&(e[a]=void 0)}),e.length>1&&e.index<c.length&&Array.prototype.push.apply(h,e.slice(1)),g=e[0].length,j=f,h.length>=b));)a.lastIndex===e.index&&a.lastIndex++;return j===c.length?!g&&a.test("")||h.push(""):h.push(c.slice(j)),h.length>b?h.slice(0,b):h};
|
lib/simple-admin-pages/lib/pickadate/picker.date.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
-
/*!
|
2 |
-
* Date picker for pickadate.js v3.6.1
|
3 |
-
* http://amsul.github.io/pickadate.js/date.htm
|
4 |
-
*/
|
5 |
!function(a){"function"==typeof define&&define.amd?define(["./picker","jquery"],a):"object"==typeof exports?module.exports=a(require("./picker.js"),require("jquery")):a(Picker,jQuery)}(function(a,b){function c(a,b){var c=this,d=a.$node[0],e=d.value,f=a.$node.data("value"),g=f||e,h=f?b.formatSubmit:b.format,i=function(){return d.currentStyle?"rtl"==d.currentStyle.direction:"rtl"==getComputedStyle(a.$root[0]).direction};c.settings=b,c.$node=a.$node,c.queue={min:"measure create",max:"measure create",now:"now create",select:"parse create validate",highlight:"parse navigate create validate",view:"parse create validate viewset",disable:"deactivate",enable:"activate"},c.item={},c.item.clear=null,c.item.disable=(b.disable||[]).slice(0),c.item.enable=-function(a){return!0===a[0]?a.shift():-1}(c.item.disable),c.set("min",b.min).set("max",b.max).set("now"),g?c.set("select",g,{format:h,defaultValue:!0}):c.set("select",null).set("highlight",c.item.now),c.key={40:7,38:-7,39:function(){return i()?-1:1},37:function(){return i()?1:-1},go:function(a){var b=c.item.highlight,d=new Date(b.year,b.month,b.date+a);c.set("highlight",d,{interval:a}),this.render()}},a.on("render",function(){a.$root.find("."+b.klass.selectMonth).on("change",function(){var c=this.value;c&&(a.set("highlight",[a.get("view").year,c,a.get("highlight").date]),a.$root.find("."+b.klass.selectMonth).trigger("focus"))}),a.$root.find("."+b.klass.selectYear).on("change",function(){var c=this.value;c&&(a.set("highlight",[c,a.get("view").month,a.get("highlight").date]),a.$root.find("."+b.klass.selectYear).trigger("focus"))})},1).on("open",function(){var d="";c.disabled(c.get("now"))&&(d=":not(."+b.klass.buttonToday+")"),a.$root.find("button"+d+", select").attr("disabled",!1)},1).on("close",function(){a.$root.find("button, select").attr("disabled",!0)},1)}var d=7,e=a._;c.prototype.set=function(a,b,c){var d=this,e=d.item;return null===b?("clear"==a&&(a="select"),e[a]=b,d):(e["enable"==a?"disable":"flip"==a?"enable":a]=d.queue[a].split(" ").map(function(e){return b=d[e](a,b,c)}).pop(),"select"==a?d.set("highlight",e.select,c):"highlight"==a?d.set("view",e.highlight,c):a.match(/^(flip|min|max|disable|enable)$/)&&(e.select&&d.disabled(e.select)&&d.set("select",e.select,c),e.highlight&&d.disabled(e.highlight)&&d.set("highlight",e.highlight,c)),d)},c.prototype.get=function(a){return this.item[a]},c.prototype.create=function(a,c,d){var f,g=this;return c=void 0===c?a:c,c==-1/0||c==1/0?f=c:b.isPlainObject(c)&&e.isInteger(c.pick)?c=c.obj:b.isArray(c)?(c=new Date(c[0],c[1],c[2]),c=e.isDate(c)?c:g.create().obj):c=e.isInteger(c)||e.isDate(c)?g.normalize(new Date(c),d):g.now(a,c,d),{year:f||c.getFullYear(),month:f||c.getMonth(),date:f||c.getDate(),day:f||c.getDay(),obj:f||c,pick:f||c.getTime()}},c.prototype.createRange=function(a,c){var d=this,f=function(a){return!0===a||b.isArray(a)||e.isDate(a)?d.create(a):a};return e.isInteger(a)||(a=f(a)),e.isInteger(c)||(c=f(c)),e.isInteger(a)&&b.isPlainObject(c)?a=[c.year,c.month,c.date+a]:e.isInteger(c)&&b.isPlainObject(a)&&(c=[a.year,a.month,a.date+c]),{from:f(a),to:f(c)}},c.prototype.withinRange=function(a,b){return a=this.createRange(a.from,a.to),b.pick>=a.from.pick&&b.pick<=a.to.pick},c.prototype.overlapRanges=function(a,b){var c=this;return a=c.createRange(a.from,a.to),b=c.createRange(b.from,b.to),c.withinRange(a,b.from)||c.withinRange(a,b.to)||c.withinRange(b,a.from)||c.withinRange(b,a.to)},c.prototype.now=function(a,b,c){return b=new Date,c&&c.rel&&b.setDate(b.getDate()+c.rel),this.normalize(b,c)},c.prototype.navigate=function(a,c,d){var e,f,g,h,i=b.isArray(c),j=b.isPlainObject(c),k=this.item.view;if(i||j){for(j?(f=c.year,g=c.month,h=c.date):(f=+c[0],g=+c[1],h=+c[2]),d&&d.nav&&k&&k.month!==g&&(f=k.year,g=k.month),e=new Date(f,g+(d&&d.nav?d.nav:0),1),f=e.getFullYear(),g=e.getMonth();new Date(f,g,h).getMonth()!==g;)h-=1;c=[f,g,h]}return c},c.prototype.normalize=function(a){return a.setHours(0,0,0,0),a},c.prototype.measure=function(a,b){var c=this;return e.isInteger(b)?b=c.now(a,b,{rel:b}):b?"string"==typeof b&&(b=c.parse(a,b)):b="min"==a?-1/0:1/0,b},c.prototype.viewset=function(a,b){return this.create([b.year,b.month,1])},c.prototype.validate=function(a,c,d){var f,g,h,i,j=this,k=c,l=d&&d.interval?d.interval:1,m=-1===j.item.enable,n=j.item.min,o=j.item.max,p=m&&j.item.disable.filter(function(a){if(b.isArray(a)){var d=j.create(a).pick;d<c.pick?f=!0:d>c.pick&&(g=!0)}return e.isInteger(a)}).length;if((!d||!d.nav&&!d.defaultValue)&&(!m&&j.disabled(c)||m&&j.disabled(c)&&(p||f||g)||!m&&(c.pick<=n.pick||c.pick>=o.pick)))for(m&&!p&&(!g&&l>0||!f&&l<0)&&(l*=-1);j.disabled(c)&&(Math.abs(l)>1&&(c.month<k.month||c.month>k.month)&&(c=k,l=l>0?1:-1),c.pick<=n.pick?(h=!0,l=1,c=j.create([n.year,n.month,n.date+(c.pick===n.pick?0:-1)])):c.pick>=o.pick&&(i=!0,l=-1,c=j.create([o.year,o.month,o.date+(c.pick===o.pick?0:1)])),!h||!i);)c=j.create([c.year,c.month,c.date+l]);return c},c.prototype.disabled=function(a){var c=this,d=c.item.disable.filter(function(d){return e.isInteger(d)?a.day===(c.settings.firstDay?d:d-1)%7:b.isArray(d)||e.isDate(d)?a.pick===c.create(d).pick:b.isPlainObject(d)?c.withinRange(d,a):void 0});return d=d.length&&!d.filter(function(a){return b.isArray(a)&&"inverted"==a[3]||b.isPlainObject(a)&&a.inverted}).length,-1===c.item.enable?!d:d||a.pick<c.item.min.pick||a.pick>c.item.max.pick},c.prototype.parse=function(a,b,c){var d=this,f={};return b&&"string"==typeof b?(c&&c.format||(c=c||{},c.format=d.settings.format),d.formats.toArray(c.format).map(function(a){var c=d.formats[a],g=c?e.trigger(c,d,[b,f]):a.replace(/^!/,"").length;c&&(f[a]=b.substr(0,g)),b=b.substr(g)}),[f.yyyy||f.yy,+(f.mm||f.m)-1,f.dd||f.d]):b},c.prototype.formats=function(){function a(a,b,c){var d=a.match(/[^\x00-\x7F]+|\w+/)[0];return c.mm||c.m||(c.m=b.indexOf(d)+1),d.length}function b(a){return a.match(/\w+/)[0].length}return{d:function(a,b){return a?e.digits(a):b.date},dd:function(a,b){return a?2:e.lead(b.date)},ddd:function(a,c){return a?b(a):this.settings.weekdaysShort[c.day]},dddd:function(a,c){return a?b(a):this.settings.weekdaysFull[c.day]},m:function(a,b){return a?e.digits(a):b.month+1},mm:function(a,b){return a?2:e.lead(b.month+1)},mmm:function(b,c){var d=this.settings.monthsShort;return b?a(b,d,c):d[c.month]},mmmm:function(b,c){var d=this.settings.monthsFull;return b?a(b,d,c):d[c.month]},yy:function(a,b){return a?2:(""+b.year).slice(2)},yyyy:function(a,b){return a?4:b.year},toArray:function(a){return a.split(/(d{1,4}|m{1,4}|y{4}|yy|!.)/g)},toString:function(a,b){var c=this;return c.formats.toArray(a).map(function(a){return e.trigger(c.formats[a],c,[0,b])||a.replace(/^!/,"")}).join("")}}}(),c.prototype.isDateExact=function(a,c){var d=this;return e.isInteger(a)&&e.isInteger(c)||"boolean"==typeof a&&"boolean"==typeof c?a===c:(e.isDate(a)||b.isArray(a))&&(e.isDate(c)||b.isArray(c))?d.create(a).pick===d.create(c).pick:!(!b.isPlainObject(a)||!b.isPlainObject(c))&&d.isDateExact(a.from,c.from)&&d.isDateExact(a.to,c.to)},c.prototype.isDateOverlap=function(a,c){var d=this,f=d.settings.firstDay?1:0;return e.isInteger(a)&&(e.isDate(c)||b.isArray(c))?(a=a%7+f)===d.create(c).day+1:e.isInteger(c)&&(e.isDate(a)||b.isArray(a))?(c=c%7+f)===d.create(a).day+1:!(!b.isPlainObject(a)||!b.isPlainObject(c))&&d.overlapRanges(a,c)},c.prototype.flipEnable=function(a){var b=this.item;b.enable=a||(-1==b.enable?1:-1)},c.prototype.deactivate=function(a,c){var d=this,f=d.item.disable.slice(0);return"flip"==c?d.flipEnable():!1===c?(d.flipEnable(1),f=[]):!0===c?(d.flipEnable(-1),f=[]):c.map(function(a){for(var c,g=0;g<f.length;g+=1)if(d.isDateExact(a,f[g])){c=!0;break}c||(e.isInteger(a)||e.isDate(a)||b.isArray(a)||b.isPlainObject(a)&&a.from&&a.to)&&f.push(a)}),f},c.prototype.activate=function(a,c){var d=this,f=d.item.disable,g=f.length;return"flip"==c?d.flipEnable():!0===c?(d.flipEnable(1),f=[]):!1===c?(d.flipEnable(-1),f=[]):c.map(function(a){var c,h,i,j;for(i=0;i<g;i+=1){if(h=f[i],d.isDateExact(h,a)){c=f[i]=null,j=!0;break}if(d.isDateOverlap(h,a)){b.isPlainObject(a)?(a.inverted=!0,c=a):b.isArray(a)?(c=a,c[3]||c.push("inverted")):e.isDate(a)&&(c=[a.getFullYear(),a.getMonth(),a.getDate(),"inverted"]);break}}if(c)for(i=0;i<g;i+=1)if(d.isDateExact(f[i],a)){f[i]=null;break}if(j)for(i=0;i<g;i+=1)if(d.isDateOverlap(f[i],a)){f[i]=null;break}c&&f.push(c)}),f.filter(function(a){return null!=a})},c.prototype.nodes=function(a){var b=this,c=b.settings,f=b.item,g=f.now,h=f.select,i=f.highlight,j=f.view,k=f.disable,l=f.min,m=f.max,n=function(a,b){return c.firstDay&&(a.push(a.shift()),b.push(b.shift())),e.node("thead",e.node("tr",e.group({min:0,max:d-1,i:1,node:"th",item:function(d){return[a[d],c.klass.weekdays,'scope=col title="'+b[d]+'"']}})))}((c.showWeekdaysFull?c.weekdaysFull:c.weekdaysShort).slice(0),c.weekdaysFull.slice(0)),o=function(a){return e.node("div"," ",c.klass["nav"+(a?"Next":"Prev")]+(a&&j.year>=m.year&&j.month>=m.month||!a&&j.year<=l.year&&j.month<=l.month?" "+c.klass.navDisabled:""),"data-nav="+(a||-1)+" "+e.ariaAttr({role:"button",controls:b.$node[0].id+"_table"})+' title="'+(a?c.labelMonthNext:c.labelMonthPrev)+'"')},p=function(){var d=c.showMonthsShort?c.monthsShort:c.monthsFull;return c.selectMonths?e.node("select",e.group({min:0,max:11,i:1,node:"option",item:function(a){return[d[a],0,"value="+a+(j.month==a?" selected":"")+(j.year==l.year&&a<l.month||j.year==m.year&&a>m.month?" disabled":"")]}}),c.klass.selectMonth,(a?"":"disabled")+" "+e.ariaAttr({controls:b.$node[0].id+"_table"})+' title="'+c.labelMonthSelect+'"'):e.node("div",d[j.month],c.klass.month)},q=function(){var d=j.year,f=!0===c.selectYears?5:~~(c.selectYears/2);if(f){var g=l.year,h=m.year,i=d-f,k=d+f;if(g>i&&(k+=g-i,i=g),h<k){var n=i-g,o=k-h;i-=n>o?o:n,k=h}return e.node("select",e.group({min:i,max:k,i:1,node:"option",item:function(a){return[a,0,"value="+a+(d==a?" selected":"")]}}),c.klass.selectYear,(a?"":"disabled")+" "+e.ariaAttr({controls:b.$node[0].id+"_table"})+' title="'+c.labelYearSelect+'"')}return e.node("div",d,c.klass.year)};return e.node("div",(c.selectYears?q()+p():p()+q())+o()+o(1),c.klass.header)+e.node("table",n+e.node("tbody",e.group({min:0,max:5,i:1,node:"tr",item:function(a){var f=c.firstDay&&0===b.create([j.year,j.month,1]).day?-7:0;return[e.group({min:d*a-j.day+f+1,max:function(){return this.min+d-1},i:1,node:"td",item:function(a){a=b.create([j.year,j.month,a+(c.firstDay?1:0)]);var d=h&&h.pick==a.pick,f=i&&i.pick==a.pick,n=k&&b.disabled(a)||a.pick<l.pick||a.pick>m.pick,o=e.trigger(b.formats.toString,b,[c.format,a]);return[e.node("div",a.date,function(b){return b.push(j.month==a.month?c.klass.infocus:c.klass.outfocus),g.pick==a.pick&&b.push(c.klass.now),d&&b.push(c.klass.selected),f&&b.push(c.klass.highlighted),n&&b.push(c.klass.disabled),b.join(" ")}([c.klass.day]),"data-pick="+a.pick+" "+e.ariaAttr({role:"gridcell",label:o,selected:!(!d||b.$node.val()!==o)||null,activedescendant:!!f||null,disabled:!!n||null})),"",e.ariaAttr({role:"presentation"})]}})]}})),c.klass.table,'id="'+b.$node[0].id+'_table" '+e.ariaAttr({role:"grid",controls:b.$node[0].id,readonly:!0}))+e.node("div",e.node("button",c.today,c.klass.buttonToday,"type=button data-pick="+g.pick+(a&&!b.disabled(g)?"":" disabled")+" "+e.ariaAttr({controls:b.$node[0].id}))+e.node("button",c.clear,c.klass.buttonClear,"type=button data-clear=1"+(a?"":" disabled")+" "+e.ariaAttr({controls:b.$node[0].id}))+e.node("button",c.close,c.klass.buttonClose,"type=button data-close=true "+(a?"":" disabled")+" "+e.ariaAttr({controls:b.$node[0].id})),c.klass.footer)},c.defaults=function(a){return{labelMonthNext:"Next month",labelMonthPrev:"Previous month",labelMonthSelect:"Select a month",labelYearSelect:"Select a year",monthsFull:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],weekdaysFull:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],weekdaysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],today:"Today",clear:"Clear",close:"Close",closeOnSelect:!0,closeOnClear:!0,updateInput:!0,format:"d mmmm, yyyy",klass:{table:a+"table",header:a+"header",navPrev:a+"nav--prev",navNext:a+"nav--next",navDisabled:a+"nav--disabled",month:a+"month",year:a+"year",selectMonth:a+"select--month",selectYear:a+"select--year",weekdays:a+"weekday",day:a+"day",disabled:a+"day--disabled",selected:a+"day--selected",highlighted:a+"day--highlighted",now:a+"day--today",infocus:a+"day--infocus",outfocus:a+"day--outfocus",footer:a+"footer",buttonClear:a+"button--clear",buttonToday:a+"button--today",buttonClose:a+"button--close"}}}(a.klasses().picker+"__"),a.extend("pickadate",c)});
|
1 |
+
/*!
|
2 |
+
* Date picker for pickadate.js v3.6.1
|
3 |
+
* http://amsul.github.io/pickadate.js/date.htm
|
4 |
+
*/
|
5 |
!function(a){"function"==typeof define&&define.amd?define(["./picker","jquery"],a):"object"==typeof exports?module.exports=a(require("./picker.js"),require("jquery")):a(Picker,jQuery)}(function(a,b){function c(a,b){var c=this,d=a.$node[0],e=d.value,f=a.$node.data("value"),g=f||e,h=f?b.formatSubmit:b.format,i=function(){return d.currentStyle?"rtl"==d.currentStyle.direction:"rtl"==getComputedStyle(a.$root[0]).direction};c.settings=b,c.$node=a.$node,c.queue={min:"measure create",max:"measure create",now:"now create",select:"parse create validate",highlight:"parse navigate create validate",view:"parse create validate viewset",disable:"deactivate",enable:"activate"},c.item={},c.item.clear=null,c.item.disable=(b.disable||[]).slice(0),c.item.enable=-function(a){return!0===a[0]?a.shift():-1}(c.item.disable),c.set("min",b.min).set("max",b.max).set("now"),g?c.set("select",g,{format:h,defaultValue:!0}):c.set("select",null).set("highlight",c.item.now),c.key={40:7,38:-7,39:function(){return i()?-1:1},37:function(){return i()?1:-1},go:function(a){var b=c.item.highlight,d=new Date(b.year,b.month,b.date+a);c.set("highlight",d,{interval:a}),this.render()}},a.on("render",function(){a.$root.find("."+b.klass.selectMonth).on("change",function(){var c=this.value;c&&(a.set("highlight",[a.get("view").year,c,a.get("highlight").date]),a.$root.find("."+b.klass.selectMonth).trigger("focus"))}),a.$root.find("."+b.klass.selectYear).on("change",function(){var c=this.value;c&&(a.set("highlight",[c,a.get("view").month,a.get("highlight").date]),a.$root.find("."+b.klass.selectYear).trigger("focus"))})},1).on("open",function(){var d="";c.disabled(c.get("now"))&&(d=":not(."+b.klass.buttonToday+")"),a.$root.find("button"+d+", select").attr("disabled",!1)},1).on("close",function(){a.$root.find("button, select").attr("disabled",!0)},1)}var d=7,e=a._;c.prototype.set=function(a,b,c){var d=this,e=d.item;return null===b?("clear"==a&&(a="select"),e[a]=b,d):(e["enable"==a?"disable":"flip"==a?"enable":a]=d.queue[a].split(" ").map(function(e){return b=d[e](a,b,c)}).pop(),"select"==a?d.set("highlight",e.select,c):"highlight"==a?d.set("view",e.highlight,c):a.match(/^(flip|min|max|disable|enable)$/)&&(e.select&&d.disabled(e.select)&&d.set("select",e.select,c),e.highlight&&d.disabled(e.highlight)&&d.set("highlight",e.highlight,c)),d)},c.prototype.get=function(a){return this.item[a]},c.prototype.create=function(a,c,d){var f,g=this;return c=void 0===c?a:c,c==-1/0||c==1/0?f=c:b.isPlainObject(c)&&e.isInteger(c.pick)?c=c.obj:b.isArray(c)?(c=new Date(c[0],c[1],c[2]),c=e.isDate(c)?c:g.create().obj):c=e.isInteger(c)||e.isDate(c)?g.normalize(new Date(c),d):g.now(a,c,d),{year:f||c.getFullYear(),month:f||c.getMonth(),date:f||c.getDate(),day:f||c.getDay(),obj:f||c,pick:f||c.getTime()}},c.prototype.createRange=function(a,c){var d=this,f=function(a){return!0===a||b.isArray(a)||e.isDate(a)?d.create(a):a};return e.isInteger(a)||(a=f(a)),e.isInteger(c)||(c=f(c)),e.isInteger(a)&&b.isPlainObject(c)?a=[c.year,c.month,c.date+a]:e.isInteger(c)&&b.isPlainObject(a)&&(c=[a.year,a.month,a.date+c]),{from:f(a),to:f(c)}},c.prototype.withinRange=function(a,b){return a=this.createRange(a.from,a.to),b.pick>=a.from.pick&&b.pick<=a.to.pick},c.prototype.overlapRanges=function(a,b){var c=this;return a=c.createRange(a.from,a.to),b=c.createRange(b.from,b.to),c.withinRange(a,b.from)||c.withinRange(a,b.to)||c.withinRange(b,a.from)||c.withinRange(b,a.to)},c.prototype.now=function(a,b,c){return b=new Date,c&&c.rel&&b.setDate(b.getDate()+c.rel),this.normalize(b,c)},c.prototype.navigate=function(a,c,d){var e,f,g,h,i=b.isArray(c),j=b.isPlainObject(c),k=this.item.view;if(i||j){for(j?(f=c.year,g=c.month,h=c.date):(f=+c[0],g=+c[1],h=+c[2]),d&&d.nav&&k&&k.month!==g&&(f=k.year,g=k.month),e=new Date(f,g+(d&&d.nav?d.nav:0),1),f=e.getFullYear(),g=e.getMonth();new Date(f,g,h).getMonth()!==g;)h-=1;c=[f,g,h]}return c},c.prototype.normalize=function(a){return a.setHours(0,0,0,0),a},c.prototype.measure=function(a,b){var c=this;return e.isInteger(b)?b=c.now(a,b,{rel:b}):b?"string"==typeof b&&(b=c.parse(a,b)):b="min"==a?-1/0:1/0,b},c.prototype.viewset=function(a,b){return this.create([b.year,b.month,1])},c.prototype.validate=function(a,c,d){var f,g,h,i,j=this,k=c,l=d&&d.interval?d.interval:1,m=-1===j.item.enable,n=j.item.min,o=j.item.max,p=m&&j.item.disable.filter(function(a){if(b.isArray(a)){var d=j.create(a).pick;d<c.pick?f=!0:d>c.pick&&(g=!0)}return e.isInteger(a)}).length;if((!d||!d.nav&&!d.defaultValue)&&(!m&&j.disabled(c)||m&&j.disabled(c)&&(p||f||g)||!m&&(c.pick<=n.pick||c.pick>=o.pick)))for(m&&!p&&(!g&&l>0||!f&&l<0)&&(l*=-1);j.disabled(c)&&(Math.abs(l)>1&&(c.month<k.month||c.month>k.month)&&(c=k,l=l>0?1:-1),c.pick<=n.pick?(h=!0,l=1,c=j.create([n.year,n.month,n.date+(c.pick===n.pick?0:-1)])):c.pick>=o.pick&&(i=!0,l=-1,c=j.create([o.year,o.month,o.date+(c.pick===o.pick?0:1)])),!h||!i);)c=j.create([c.year,c.month,c.date+l]);return c},c.prototype.disabled=function(a){var c=this,d=c.item.disable.filter(function(d){return e.isInteger(d)?a.day===(c.settings.firstDay?d:d-1)%7:b.isArray(d)||e.isDate(d)?a.pick===c.create(d).pick:b.isPlainObject(d)?c.withinRange(d,a):void 0});return d=d.length&&!d.filter(function(a){return b.isArray(a)&&"inverted"==a[3]||b.isPlainObject(a)&&a.inverted}).length,-1===c.item.enable?!d:d||a.pick<c.item.min.pick||a.pick>c.item.max.pick},c.prototype.parse=function(a,b,c){var d=this,f={};return b&&"string"==typeof b?(c&&c.format||(c=c||{},c.format=d.settings.format),d.formats.toArray(c.format).map(function(a){var c=d.formats[a],g=c?e.trigger(c,d,[b,f]):a.replace(/^!/,"").length;c&&(f[a]=b.substr(0,g)),b=b.substr(g)}),[f.yyyy||f.yy,+(f.mm||f.m)-1,f.dd||f.d]):b},c.prototype.formats=function(){function a(a,b,c){var d=a.match(/[^\x00-\x7F]+|\w+/)[0];return c.mm||c.m||(c.m=b.indexOf(d)+1),d.length}function b(a){return a.match(/\w+/)[0].length}return{d:function(a,b){return a?e.digits(a):b.date},dd:function(a,b){return a?2:e.lead(b.date)},ddd:function(a,c){return a?b(a):this.settings.weekdaysShort[c.day]},dddd:function(a,c){return a?b(a):this.settings.weekdaysFull[c.day]},m:function(a,b){return a?e.digits(a):b.month+1},mm:function(a,b){return a?2:e.lead(b.month+1)},mmm:function(b,c){var d=this.settings.monthsShort;return b?a(b,d,c):d[c.month]},mmmm:function(b,c){var d=this.settings.monthsFull;return b?a(b,d,c):d[c.month]},yy:function(a,b){return a?2:(""+b.year).slice(2)},yyyy:function(a,b){return a?4:b.year},toArray:function(a){return a.split(/(d{1,4}|m{1,4}|y{4}|yy|!.)/g)},toString:function(a,b){var c=this;return c.formats.toArray(a).map(function(a){return e.trigger(c.formats[a],c,[0,b])||a.replace(/^!/,"")}).join("")}}}(),c.prototype.isDateExact=function(a,c){var d=this;return e.isInteger(a)&&e.isInteger(c)||"boolean"==typeof a&&"boolean"==typeof c?a===c:(e.isDate(a)||b.isArray(a))&&(e.isDate(c)||b.isArray(c))?d.create(a).pick===d.create(c).pick:!(!b.isPlainObject(a)||!b.isPlainObject(c))&&d.isDateExact(a.from,c.from)&&d.isDateExact(a.to,c.to)},c.prototype.isDateOverlap=function(a,c){var d=this,f=d.settings.firstDay?1:0;return e.isInteger(a)&&(e.isDate(c)||b.isArray(c))?(a=a%7+f)===d.create(c).day+1:e.isInteger(c)&&(e.isDate(a)||b.isArray(a))?(c=c%7+f)===d.create(a).day+1:!(!b.isPlainObject(a)||!b.isPlainObject(c))&&d.overlapRanges(a,c)},c.prototype.flipEnable=function(a){var b=this.item;b.enable=a||(-1==b.enable?1:-1)},c.prototype.deactivate=function(a,c){var d=this,f=d.item.disable.slice(0);return"flip"==c?d.flipEnable():!1===c?(d.flipEnable(1),f=[]):!0===c?(d.flipEnable(-1),f=[]):c.map(function(a){for(var c,g=0;g<f.length;g+=1)if(d.isDateExact(a,f[g])){c=!0;break}c||(e.isInteger(a)||e.isDate(a)||b.isArray(a)||b.isPlainObject(a)&&a.from&&a.to)&&f.push(a)}),f},c.prototype.activate=function(a,c){var d=this,f=d.item.disable,g=f.length;return"flip"==c?d.flipEnable():!0===c?(d.flipEnable(1),f=[]):!1===c?(d.flipEnable(-1),f=[]):c.map(function(a){var c,h,i,j;for(i=0;i<g;i+=1){if(h=f[i],d.isDateExact(h,a)){c=f[i]=null,j=!0;break}if(d.isDateOverlap(h,a)){b.isPlainObject(a)?(a.inverted=!0,c=a):b.isArray(a)?(c=a,c[3]||c.push("inverted")):e.isDate(a)&&(c=[a.getFullYear(),a.getMonth(),a.getDate(),"inverted"]);break}}if(c)for(i=0;i<g;i+=1)if(d.isDateExact(f[i],a)){f[i]=null;break}if(j)for(i=0;i<g;i+=1)if(d.isDateOverlap(f[i],a)){f[i]=null;break}c&&f.push(c)}),f.filter(function(a){return null!=a})},c.prototype.nodes=function(a){var b=this,c=b.settings,f=b.item,g=f.now,h=f.select,i=f.highlight,j=f.view,k=f.disable,l=f.min,m=f.max,n=function(a,b){return c.firstDay&&(a.push(a.shift()),b.push(b.shift())),e.node("thead",e.node("tr",e.group({min:0,max:d-1,i:1,node:"th",item:function(d){return[a[d],c.klass.weekdays,'scope=col title="'+b[d]+'"']}})))}((c.showWeekdaysFull?c.weekdaysFull:c.weekdaysShort).slice(0),c.weekdaysFull.slice(0)),o=function(a){return e.node("div"," ",c.klass["nav"+(a?"Next":"Prev")]+(a&&j.year>=m.year&&j.month>=m.month||!a&&j.year<=l.year&&j.month<=l.month?" "+c.klass.navDisabled:""),"data-nav="+(a||-1)+" "+e.ariaAttr({role:"button",controls:b.$node[0].id+"_table"})+' title="'+(a?c.labelMonthNext:c.labelMonthPrev)+'"')},p=function(){var d=c.showMonthsShort?c.monthsShort:c.monthsFull;return c.selectMonths?e.node("select",e.group({min:0,max:11,i:1,node:"option",item:function(a){return[d[a],0,"value="+a+(j.month==a?" selected":"")+(j.year==l.year&&a<l.month||j.year==m.year&&a>m.month?" disabled":"")]}}),c.klass.selectMonth,(a?"":"disabled")+" "+e.ariaAttr({controls:b.$node[0].id+"_table"})+' title="'+c.labelMonthSelect+'"'):e.node("div",d[j.month],c.klass.month)},q=function(){var d=j.year,f=!0===c.selectYears?5:~~(c.selectYears/2);if(f){var g=l.year,h=m.year,i=d-f,k=d+f;if(g>i&&(k+=g-i,i=g),h<k){var n=i-g,o=k-h;i-=n>o?o:n,k=h}return e.node("select",e.group({min:i,max:k,i:1,node:"option",item:function(a){return[a,0,"value="+a+(d==a?" selected":"")]}}),c.klass.selectYear,(a?"":"disabled")+" "+e.ariaAttr({controls:b.$node[0].id+"_table"})+' title="'+c.labelYearSelect+'"')}return e.node("div",d,c.klass.year)};return e.node("div",(c.selectYears?q()+p():p()+q())+o()+o(1),c.klass.header)+e.node("table",n+e.node("tbody",e.group({min:0,max:5,i:1,node:"tr",item:function(a){var f=c.firstDay&&0===b.create([j.year,j.month,1]).day?-7:0;return[e.group({min:d*a-j.day+f+1,max:function(){return this.min+d-1},i:1,node:"td",item:function(a){a=b.create([j.year,j.month,a+(c.firstDay?1:0)]);var d=h&&h.pick==a.pick,f=i&&i.pick==a.pick,n=k&&b.disabled(a)||a.pick<l.pick||a.pick>m.pick,o=e.trigger(b.formats.toString,b,[c.format,a]);return[e.node("div",a.date,function(b){return b.push(j.month==a.month?c.klass.infocus:c.klass.outfocus),g.pick==a.pick&&b.push(c.klass.now),d&&b.push(c.klass.selected),f&&b.push(c.klass.highlighted),n&&b.push(c.klass.disabled),b.join(" ")}([c.klass.day]),"data-pick="+a.pick+" "+e.ariaAttr({role:"gridcell",label:o,selected:!(!d||b.$node.val()!==o)||null,activedescendant:!!f||null,disabled:!!n||null})),"",e.ariaAttr({role:"presentation"})]}})]}})),c.klass.table,'id="'+b.$node[0].id+'_table" '+e.ariaAttr({role:"grid",controls:b.$node[0].id,readonly:!0}))+e.node("div",e.node("button",c.today,c.klass.buttonToday,"type=button data-pick="+g.pick+(a&&!b.disabled(g)?"":" disabled")+" "+e.ariaAttr({controls:b.$node[0].id}))+e.node("button",c.clear,c.klass.buttonClear,"type=button data-clear=1"+(a?"":" disabled")+" "+e.ariaAttr({controls:b.$node[0].id}))+e.node("button",c.close,c.klass.buttonClose,"type=button data-close=true "+(a?"":" disabled")+" "+e.ariaAttr({controls:b.$node[0].id})),c.klass.footer)},c.defaults=function(a){return{labelMonthNext:"Next month",labelMonthPrev:"Previous month",labelMonthSelect:"Select a month",labelYearSelect:"Select a year",monthsFull:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],weekdaysFull:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],weekdaysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],today:"Today",clear:"Clear",close:"Close",closeOnSelect:!0,closeOnClear:!0,updateInput:!0,format:"d mmmm, yyyy",klass:{table:a+"table",header:a+"header",navPrev:a+"nav--prev",navNext:a+"nav--next",navDisabled:a+"nav--disabled",month:a+"month",year:a+"year",selectMonth:a+"select--month",selectYear:a+"select--year",weekdays:a+"weekday",day:a+"day",disabled:a+"day--disabled",selected:a+"day--selected",highlighted:a+"day--highlighted",now:a+"day--today",infocus:a+"day--infocus",outfocus:a+"day--outfocus",footer:a+"footer",buttonClear:a+"button--clear",buttonToday:a+"button--today",buttonClose:a+"button--close"}}}(a.klasses().picker+"__"),a.extend("pickadate",c)});
|
lib/simple-admin-pages/lib/pickadate/picker.js
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
-
/*!
|
2 |
-
* pickadate.js v3.6.1, 2019/03/15
|
3 |
-
* By Amsul, http://amsul.ca
|
4 |
-
* Hosted on http://amsul.github.io/pickadate.js
|
5 |
-
* Licensed under MIT
|
6 |
-
*/
|
7 |
!function(a){"function"==typeof define&&define.amd?define("picker",["jquery"],a):"object"==typeof exports?module.exports=a(require("jquery")):this.Picker=a(jQuery)}(function(a){function b(h,i,k,m){function o(){return b._.node("div",b._.node("div",b._.node("div",b._.node("div",C.component.nodes(x.open),z.box),z.wrap),z.frame),z.holder,'tabindex="-1"')}function p(){A.data(i,C).addClass(z.input).val(A.data("value")?C.get("select",y.format):h.value).on("focus."+x.id+" click."+x.id,f(function(a){a.preventDefault(),C.open()},50)),y.editable||A.on("keydown."+x.id,v),g(h,{haspopup:!0,expanded:!1,readonly:!1,owns:h.id+"_root"})}function q(){g(C.$root[0],"hidden",!0)}function r(){C.$holder.on({keydown:v,"focus.toOpen":u,blur:function(){A.removeClass(z.target)},focusin:function(a){C.$root.removeClass(z.focused),a.stopPropagation()},"mousedown click":function(b){var c=e(b,h);c!=C.$holder[0]&&(b.stopPropagation(),"mousedown"!=b.type||a(c).is("input, select, textarea, button, option")||(b.preventDefault(),C.$holder.eq(0).focus()))}}).on("click","[data-pick], [data-nav], [data-clear], [data-close]",function(){var b=a(this),c=b.data(),d=b.hasClass(z.navDisabled)||b.hasClass(z.disabled),e=j();e=e&&(e.type||e.href?e:null),(d||e&&!a.contains(C.$root[0],e))&&C.$holder.eq(0).focus(),!d&&c.nav?C.set("highlight",C.component.item.highlight,{nav:c.nav}):!d&&"pick"in c?(C.set("select",c.pick),y.closeOnSelect&&C.close(!0)):c.clear?(C.clear(),y.closeOnClear&&C.close(!0)):c.close&&C.close(!0)})}function s(){var b;!0===y.hiddenName?(b=h.name,h.name=""):(b=["string"==typeof y.hiddenPrefix?y.hiddenPrefix:"","string"==typeof y.hiddenSuffix?y.hiddenSuffix:"_submit"],b=b[0]+h.name+b[1]),C._hidden=a('<input type=hidden name="'+b+'"'+(A.data("value")||h.value?' value="'+C.get("select",y.formatSubmit)+'"':"")+">")[0],A.on("change."+x.id,function(){C._hidden.value=h.value?C.get("select",y.formatSubmit):""})}function t(){w&&n?C.$holder.find("."+z.frame).one("transitionend",function(){C.$holder.eq(0).focus()}):setTimeout(function(){C.$holder.eq(0).focus()},0)}function u(a){a.stopPropagation(),A.addClass(z.target),C.$root.addClass(z.focused),C.open()}function v(a){var b=a.keyCode,c=/^(8|46)$/.test(b);if(27==b)return C.close(!0),!1;(32==b||c||!x.open&&C.component.key[b])&&(a.preventDefault(),a.stopPropagation(),c?C.clear().close():C.open())}if(!h)return b;var w=!1,x={id:h.id||"P"+Math.abs(~~(Math.random()*new Date))},y=k?a.extend(!0,{},k.defaults,m):m||{},z=a.extend({},b.klasses(),y.klass),A=a(h),B=function(){return this.start()},C=B.prototype={constructor:B,$node:A,start:function(){return x&&x.start?C:(x.methods={},x.start=!0,x.open=!1,x.type=h.type,h.autofocus=h==j(),h.readOnly=!y.editable,h.id=h.id||x.id,"text"!=h.type&&(h.type="text"),C.component=new k(C,y),C.$root=a('<div class="'+z.picker+'" id="'+h.id+'_root" />'),q(),C.$holder=a(o()).appendTo(C.$root),r(),y.formatSubmit&&s(),p(),y.containerHidden?a(y.containerHidden).append(C._hidden):A.after(C._hidden),y.container?a(y.container).append(C.$root):A.after(C.$root),C.on({start:C.component.onStart,render:C.component.onRender,stop:C.component.onStop,open:C.component.onOpen,close:C.component.onClose,set:C.component.onSet}).on({start:y.onStart,render:y.onRender,stop:y.onStop,open:y.onOpen,close:y.onClose,set:y.onSet}),w=c(C.$holder[0]),h.autofocus&&C.open(),C.trigger("start").trigger("render"))},render:function(b){return b?(C.$holder=a(o()),r(),C.$root.html(C.$holder)):C.$root.find("."+z.box).html(C.component.nodes(x.open)),C.trigger("render")},stop:function(){return x.start?(C.close(),C._hidden&&C._hidden.parentNode.removeChild(C._hidden),C.$root.remove(),A.removeClass(z.input).removeData(i),setTimeout(function(){A.off("."+x.id)},0),h.type=x.type,h.readOnly=!1,C.trigger("stop"),x.methods={},x.start=!1,C):C},open:function(c){return x.open?C:(A.addClass(z.active),g(h,"expanded",!0),setTimeout(function(){C.$root.addClass(z.opened),g(C.$root[0],"hidden",!1)},0),!1!==c&&(x.open=!0,w&&a("body").css("overflow","hidden").css("padding-right","+="+d()),t(),l.on("click."+x.id+" focusin."+x.id,function(a){var b=e(a,h);a.isSimulated||b==h||b==document||3==a.which||C.close(b===C.$holder[0])}).on("keydown."+x.id,function(c){var d=c.keyCode,f=C.component.key[d],g=e(c,h);27==d?C.close(!0):g!=C.$holder[0]||!f&&13!=d?a.contains(C.$root[0],g)&&13==d&&(c.preventDefault(),g.click()):(c.preventDefault(),f?b._.trigger(C.component.key.go,C,[b._.trigger(f)]):C.$root.find("."+z.highlighted).hasClass(z.disabled)||(C.set("select",C.component.item.highlight),y.closeOnSelect&&C.close(!0)))})),C.trigger("open"))},close:function(b){return b&&(y.editable?h.focus():(C.$holder.off("focus.toOpen").focus(),setTimeout(function(){C.$holder.on("focus.toOpen",u)},0))),A.removeClass(z.active),g(h,"expanded",!1),setTimeout(function(){C.$root.removeClass(z.opened+" "+z.focused),g(C.$root[0],"hidden",!0)},0),x.open?(x.open=!1,w&&a("body").css("overflow","").css("padding-right","-="+d()),l.off("."+x.id),C.trigger("close")):C},clear:function(a){return C.set("clear",null,a)},set:function(b,c,d){var e,f,g=a.isPlainObject(b),h=g?b:{};if(d=g&&a.isPlainObject(c)?c:d||{},b){g||(h[b]=c);for(e in h)f=h[e],e in C.component.item&&(void 0===f&&(f=null),C.component.set(e,f,d)),"select"!=e&&"clear"!=e||!y.updateInput||A.val("clear"==e?"":C.get(e,y.format)).trigger("change");C.render()}return d.muted?C:C.trigger("set",h)},get:function(a,c){if(a=a||"value",null!=x[a])return x[a];if("valueSubmit"==a){if(C._hidden)return C._hidden.value;a="value"}if("value"==a)return h.value;if(a in C.component.item){if("string"==typeof c){var d=C.component.get(a);return d?b._.trigger(C.component.formats.toString,C.component,[c,d]):""}return C.component.get(a)}},on:function(b,c,d){var e,f,g=a.isPlainObject(b),h=g?b:{};if(b){g||(h[b]=c);for(e in h)f=h[e],d&&(e="_"+e),x.methods[e]=x.methods[e]||[],x.methods[e].push(f)}return C},off:function(){var a,b,c=arguments;for(a=0,namesCount=c.length;a<namesCount;a+=1)(b=c[a])in x.methods&&delete x.methods[b];return C},trigger:function(a,c){var d=function(a){var d=x.methods[a];d&&d.map(function(a){b._.trigger(a,C,[c])})};return d("_"+a),d(a),C}};return new B}function c(a){var b,c="position";return a.currentStyle?b=a.currentStyle[c]:window.getComputedStyle&&(b=getComputedStyle(a)[c]),"fixed"==b}function d(){if(m.height()<=k.height())return 0;var b=a('<div style="visibility:hidden;width:100px" />').appendTo("body"),c=b[0].offsetWidth;b.css("overflow","scroll");var d=a('<div style="width:100%" />').appendTo(b),e=d[0].offsetWidth;return b.remove(),c-e}function e(a,b){var c=[];return a.path&&(c=a.path),a.originalEvent&&a.originalEvent.path&&(c=a.originalEvent.path),c&&c.length>0?b&&c.indexOf(b)>=0?b:c[0]:a.target}function f(a,b,c){var d;return function(){var e=this,f=arguments,g=function(){d=null,c||a.apply(e,f)},h=c&&!d;clearTimeout(d),d=setTimeout(g,b),h&&a.apply(e,f)}}function g(b,c,d){if(a.isPlainObject(c))for(var e in c)h(b,e,c[e]);else h(b,c,d)}function h(a,b,c){a.setAttribute(("role"==b?"":"aria-")+b,c)}function i(b,c){a.isPlainObject(b)||(b={attribute:c}),c="";for(var d in b){var e=("role"==d?"":"aria-")+d;c+=null==b[d]?"":e+'="'+b[d]+'"'}return c}function j(){try{return document.activeElement}catch(a){}}var k=a(window),l=a(document),m=a(document.documentElement),n=null!=document.documentElement.style.transition;return b.klasses=function(a){return a=a||"picker",{picker:a,opened:a+"--opened",focused:a+"--focused",input:a+"__input",active:a+"__input--active",target:a+"__input--target",holder:a+"__holder",frame:a+"__frame",wrap:a+"__wrap",box:a+"__box"}},b._={group:function(a){for(var c,d="",e=b._.trigger(a.min,a);e<=b._.trigger(a.max,a,[e]);e+=a.i)c=b._.trigger(a.item,a,[e]),d+=b._.node(a.node,c[0],c[1],c[2]);return d},node:function(b,c,d,e){return c?(c=a.isArray(c)?c.join(""):c,d=d?' class="'+d+'"':"",e=e?" "+e:"","<"+b+d+e+">"+c+"</"+b+">"):""},lead:function(a){return(a<10?"0":"")+a},trigger:function(a,b,c){return"function"==typeof a?a.apply(b,c||[]):a},digits:function(a){return/\d/.test(a[1])?2:1},isDate:function(a){return{}.toString.call(a).indexOf("Date")>-1&&this.isInteger(a.getDate())},isInteger:function(a){return{}.toString.call(a).indexOf("Number")>-1&&a%1==0},ariaAttr:i},b.extend=function(c,d){a.fn[c]=function(e,f){var g=this.data(c);return"picker"==e?g:g&&"string"==typeof e?b._.trigger(g[e],g,[f]):this.each(function(){a(this).data(c)||new b(this,c,d,e)})},a.fn[c].defaults=d.defaults},b});
|
1 |
+
/*!
|
2 |
+
* pickadate.js v3.6.1, 2019/03/15
|
3 |
+
* By Amsul, http://amsul.ca
|
4 |
+
* Hosted on http://amsul.github.io/pickadate.js
|
5 |
+
* Licensed under MIT
|
6 |
+
*/
|
7 |
!function(a){"function"==typeof define&&define.amd?define("picker",["jquery"],a):"object"==typeof exports?module.exports=a(require("jquery")):this.Picker=a(jQuery)}(function(a){function b(h,i,k,m){function o(){return b._.node("div",b._.node("div",b._.node("div",b._.node("div",C.component.nodes(x.open),z.box),z.wrap),z.frame),z.holder,'tabindex="-1"')}function p(){A.data(i,C).addClass(z.input).val(A.data("value")?C.get("select",y.format):h.value).on("focus."+x.id+" click."+x.id,f(function(a){a.preventDefault(),C.open()},50)),y.editable||A.on("keydown."+x.id,v),g(h,{haspopup:!0,expanded:!1,readonly:!1,owns:h.id+"_root"})}function q(){g(C.$root[0],"hidden",!0)}function r(){C.$holder.on({keydown:v,"focus.toOpen":u,blur:function(){A.removeClass(z.target)},focusin:function(a){C.$root.removeClass(z.focused),a.stopPropagation()},"mousedown click":function(b){var c=e(b,h);c!=C.$holder[0]&&(b.stopPropagation(),"mousedown"!=b.type||a(c).is("input, select, textarea, button, option")||(b.preventDefault(),C.$holder.eq(0).focus()))}}).on("click","[data-pick], [data-nav], [data-clear], [data-close]",function(){var b=a(this),c=b.data(),d=b.hasClass(z.navDisabled)||b.hasClass(z.disabled),e=j();e=e&&(e.type||e.href?e:null),(d||e&&!a.contains(C.$root[0],e))&&C.$holder.eq(0).focus(),!d&&c.nav?C.set("highlight",C.component.item.highlight,{nav:c.nav}):!d&&"pick"in c?(C.set("select",c.pick),y.closeOnSelect&&C.close(!0)):c.clear?(C.clear(),y.closeOnClear&&C.close(!0)):c.close&&C.close(!0)})}function s(){var b;!0===y.hiddenName?(b=h.name,h.name=""):(b=["string"==typeof y.hiddenPrefix?y.hiddenPrefix:"","string"==typeof y.hiddenSuffix?y.hiddenSuffix:"_submit"],b=b[0]+h.name+b[1]),C._hidden=a('<input type=hidden name="'+b+'"'+(A.data("value")||h.value?' value="'+C.get("select",y.formatSubmit)+'"':"")+">")[0],A.on("change."+x.id,function(){C._hidden.value=h.value?C.get("select",y.formatSubmit):""})}function t(){w&&n?C.$holder.find("."+z.frame).one("transitionend",function(){C.$holder.eq(0).focus()}):setTimeout(function(){C.$holder.eq(0).focus()},0)}function u(a){a.stopPropagation(),A.addClass(z.target),C.$root.addClass(z.focused),C.open()}function v(a){var b=a.keyCode,c=/^(8|46)$/.test(b);if(27==b)return C.close(!0),!1;(32==b||c||!x.open&&C.component.key[b])&&(a.preventDefault(),a.stopPropagation(),c?C.clear().close():C.open())}if(!h)return b;var w=!1,x={id:h.id||"P"+Math.abs(~~(Math.random()*new Date))},y=k?a.extend(!0,{},k.defaults,m):m||{},z=a.extend({},b.klasses(),y.klass),A=a(h),B=function(){return this.start()},C=B.prototype={constructor:B,$node:A,start:function(){return x&&x.start?C:(x.methods={},x.start=!0,x.open=!1,x.type=h.type,h.autofocus=h==j(),h.readOnly=!y.editable,h.id=h.id||x.id,"text"!=h.type&&(h.type="text"),C.component=new k(C,y),C.$root=a('<div class="'+z.picker+'" id="'+h.id+'_root" />'),q(),C.$holder=a(o()).appendTo(C.$root),r(),y.formatSubmit&&s(),p(),y.containerHidden?a(y.containerHidden).append(C._hidden):A.after(C._hidden),y.container?a(y.container).append(C.$root):A.after(C.$root),C.on({start:C.component.onStart,render:C.component.onRender,stop:C.component.onStop,open:C.component.onOpen,close:C.component.onClose,set:C.component.onSet}).on({start:y.onStart,render:y.onRender,stop:y.onStop,open:y.onOpen,close:y.onClose,set:y.onSet}),w=c(C.$holder[0]),h.autofocus&&C.open(),C.trigger("start").trigger("render"))},render:function(b){return b?(C.$holder=a(o()),r(),C.$root.html(C.$holder)):C.$root.find("."+z.box).html(C.component.nodes(x.open)),C.trigger("render")},stop:function(){return x.start?(C.close(),C._hidden&&C._hidden.parentNode.removeChild(C._hidden),C.$root.remove(),A.removeClass(z.input).removeData(i),setTimeout(function(){A.off("."+x.id)},0),h.type=x.type,h.readOnly=!1,C.trigger("stop"),x.methods={},x.start=!1,C):C},open:function(c){return x.open?C:(A.addClass(z.active),g(h,"expanded",!0),setTimeout(function(){C.$root.addClass(z.opened),g(C.$root[0],"hidden",!1)},0),!1!==c&&(x.open=!0,w&&a("body").css("overflow","hidden").css("padding-right","+="+d()),t(),l.on("click."+x.id+" focusin."+x.id,function(a){var b=e(a,h);a.isSimulated||b==h||b==document||3==a.which||C.close(b===C.$holder[0])}).on("keydown."+x.id,function(c){var d=c.keyCode,f=C.component.key[d],g=e(c,h);27==d?C.close(!0):g!=C.$holder[0]||!f&&13!=d?a.contains(C.$root[0],g)&&13==d&&(c.preventDefault(),g.click()):(c.preventDefault(),f?b._.trigger(C.component.key.go,C,[b._.trigger(f)]):C.$root.find("."+z.highlighted).hasClass(z.disabled)||(C.set("select",C.component.item.highlight),y.closeOnSelect&&C.close(!0)))})),C.trigger("open"))},close:function(b){return b&&(y.editable?h.focus():(C.$holder.off("focus.toOpen").focus(),setTimeout(function(){C.$holder.on("focus.toOpen",u)},0))),A.removeClass(z.active),g(h,"expanded",!1),setTimeout(function(){C.$root.removeClass(z.opened+" "+z.focused),g(C.$root[0],"hidden",!0)},0),x.open?(x.open=!1,w&&a("body").css("overflow","").css("padding-right","-="+d()),l.off("."+x.id),C.trigger("close")):C},clear:function(a){return C.set("clear",null,a)},set:function(b,c,d){var e,f,g=a.isPlainObject(b),h=g?b:{};if(d=g&&a.isPlainObject(c)?c:d||{},b){g||(h[b]=c);for(e in h)f=h[e],e in C.component.item&&(void 0===f&&(f=null),C.component.set(e,f,d)),"select"!=e&&"clear"!=e||!y.updateInput||A.val("clear"==e?"":C.get(e,y.format)).trigger("change");C.render()}return d.muted?C:C.trigger("set",h)},get:function(a,c){if(a=a||"value",null!=x[a])return x[a];if("valueSubmit"==a){if(C._hidden)return C._hidden.value;a="value"}if("value"==a)return h.value;if(a in C.component.item){if("string"==typeof c){var d=C.component.get(a);return d?b._.trigger(C.component.formats.toString,C.component,[c,d]):""}return C.component.get(a)}},on:function(b,c,d){var e,f,g=a.isPlainObject(b),h=g?b:{};if(b){g||(h[b]=c);for(e in h)f=h[e],d&&(e="_"+e),x.methods[e]=x.methods[e]||[],x.methods[e].push(f)}return C},off:function(){var a,b,c=arguments;for(a=0,namesCount=c.length;a<namesCount;a+=1)(b=c[a])in x.methods&&delete x.methods[b];return C},trigger:function(a,c){var d=function(a){var d=x.methods[a];d&&d.map(function(a){b._.trigger(a,C,[c])})};return d("_"+a),d(a),C}};return new B}function c(a){var b,c="position";return a.currentStyle?b=a.currentStyle[c]:window.getComputedStyle&&(b=getComputedStyle(a)[c]),"fixed"==b}function d(){if(m.height()<=k.height())return 0;var b=a('<div style="visibility:hidden;width:100px" />').appendTo("body"),c=b[0].offsetWidth;b.css("overflow","scroll");var d=a('<div style="width:100%" />').appendTo(b),e=d[0].offsetWidth;return b.remove(),c-e}function e(a,b){var c=[];return a.path&&(c=a.path),a.originalEvent&&a.originalEvent.path&&(c=a.originalEvent.path),c&&c.length>0?b&&c.indexOf(b)>=0?b:c[0]:a.target}function f(a,b,c){var d;return function(){var e=this,f=arguments,g=function(){d=null,c||a.apply(e,f)},h=c&&!d;clearTimeout(d),d=setTimeout(g,b),h&&a.apply(e,f)}}function g(b,c,d){if(a.isPlainObject(c))for(var e in c)h(b,e,c[e]);else h(b,c,d)}function h(a,b,c){a.setAttribute(("role"==b?"":"aria-")+b,c)}function i(b,c){a.isPlainObject(b)||(b={attribute:c}),c="";for(var d in b){var e=("role"==d?"":"aria-")+d;c+=null==b[d]?"":e+'="'+b[d]+'"'}return c}function j(){try{return document.activeElement}catch(a){}}var k=a(window),l=a(document),m=a(document.documentElement),n=null!=document.documentElement.style.transition;return b.klasses=function(a){return a=a||"picker",{picker:a,opened:a+"--opened",focused:a+"--focused",input:a+"__input",active:a+"__input--active",target:a+"__input--target",holder:a+"__holder",frame:a+"__frame",wrap:a+"__wrap",box:a+"__box"}},b._={group:function(a){for(var c,d="",e=b._.trigger(a.min,a);e<=b._.trigger(a.max,a,[e]);e+=a.i)c=b._.trigger(a.item,a,[e]),d+=b._.node(a.node,c[0],c[1],c[2]);return d},node:function(b,c,d,e){return c?(c=a.isArray(c)?c.join(""):c,d=d?' class="'+d+'"':"",e=e?" "+e:"","<"+b+d+e+">"+c+"</"+b+">"):""},lead:function(a){return(a<10?"0":"")+a},trigger:function(a,b,c){return"function"==typeof a?a.apply(b,c||[]):a},digits:function(a){return/\d/.test(a[1])?2:1},isDate:function(a){return{}.toString.call(a).indexOf("Date")>-1&&this.isInteger(a.getDate())},isInteger:function(a){return{}.toString.call(a).indexOf("Number")>-1&&a%1==0},ariaAttr:i},b.extend=function(c,d){a.fn[c]=function(e,f){var g=this.data(c);return"picker"==e?g:g&&"string"==typeof e?b._.trigger(g[e],g,[f]):this.each(function(){a(this).data(c)||new b(this,c,d,e)})},a.fn[c].defaults=d.defaults},b});
|
lib/simple-admin-pages/lib/pickadate/picker.time.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
-
/*!
|
2 |
-
* Time picker for pickadate.js v3.6.1
|
3 |
-
* http://amsul.github.io/pickadate.js/time.htm
|
4 |
-
*/
|
5 |
!function(a){"function"==typeof define&&define.amd?define(["./picker","jquery"],a):"object"==typeof exports?module.exports=a(require("./picker.js"),require("jquery")):a(Picker,jQuery)}(function(a,b){function c(a,b){var c=this,d=a.$node[0].value,e=a.$node.data("value"),f=e||d,g=e?b.formatSubmit:b.format;c.settings=b,c.$node=a.$node,c.queue={interval:"i",min:"measure create",max:"measure create",now:"now create",select:"parse create validate",highlight:"parse create validate",view:"parse create validate",disable:"deactivate",enable:"activate"},c.item={},c.item.clear=null,c.item.interval=b.interval||30,c.item.disable=(b.disable||[]).slice(0),c.item.enable=-function(a){return!0===a[0]?a.shift():-1}(c.item.disable),c.set("min",b.min).set("max",b.max).set("now"),f?c.set("select",f,{format:g}):c.set("select",null).set("highlight",c.item.now),c.key={40:1,38:-1,39:1,37:-1,go:function(a){c.set("highlight",c.item.highlight.pick+a*c.item.interval,{interval:a*c.item.interval}),this.render()}},a.on("render",function(){var c=a.$root.children(),d=c.find("."+b.klass.viewset),e=function(a){return["webkit","moz","ms","o",""].map(function(b){return(b?"-"+b+"-":"")+a})},f=function(a,b){e("transform").map(function(c){a.css(c,b)}),e("transition").map(function(c){a.css(c,b)})};d.length&&(f(c,"none"),c[0].scrollTop=~~d.position().top-2*d[0].clientHeight,f(c,""))},1).on("open",function(){a.$root.find("button").attr("disabled",!1)},1).on("close",function(){a.$root.find("button").attr("disabled",!0)},1)}var d=24,e=60,f=12,g=d*e,h=a._;c.prototype.set=function(a,b,c){var d=this,e=d.item;return null===b?("clear"==a&&(a="select"),e[a]=b,d):(e["enable"==a?"disable":"flip"==a?"enable":a]=d.queue[a].split(" ").map(function(e){return b=d[e](a,b,c)}).pop(),"select"==a?d.set("highlight",e.select,c):"highlight"==a?d.set("view",e.highlight,c):"interval"==a?d.set("min",e.min,c).set("max",e.max,c):a.match(/^(flip|min|max|disable|enable)$/)&&(e.select&&d.disabled(e.select)&&d.set("select",b,c),e.highlight&&d.disabled(e.highlight)&&d.set("highlight",b,c),"min"==a&&d.set("max",e.max,c)),d)},c.prototype.get=function(a){return this.item[a]},c.prototype.create=function(a,c,f){var i=this;return c=void 0===c?a:c,h.isDate(c)&&(c=[c.getHours(),c.getMinutes()]),b.isPlainObject(c)&&h.isInteger(c.pick)?c=c.pick:b.isArray(c)?c=+c[0]*e+ +c[1]:h.isInteger(c)||(c=i.now(a,c,f)),"max"==a&&c<i.item.min.pick&&(c+=g),"min"!=a&&"max"!=a&&(c-i.item.min.pick)%i.item.interval!=0&&(c+=i.item.interval),c=i.normalize(a,c,f),{hour:~~(d+c/e)%d,mins:(e+c%e)%e,time:(g+c)%g,pick:c%g}},c.prototype.createRange=function(a,c){var d=this,e=function(a){return!0===a||b.isArray(a)||h.isDate(a)?d.create(a):a};return h.isInteger(a)||(a=e(a)),h.isInteger(c)||(c=e(c)),h.isInteger(a)&&b.isPlainObject(c)?a=[c.hour,c.mins+a*d.settings.interval]:h.isInteger(c)&&b.isPlainObject(a)&&(c=[a.hour,a.mins+c*d.settings.interval]),{from:e(a),to:e(c)}},c.prototype.withinRange=function(a,b){return a=this.createRange(a.from,a.to),b.pick>=a.from.pick&&b.pick<=a.to.pick},c.prototype.overlapRanges=function(a,b){var c=this;return a=c.createRange(a.from,a.to),b=c.createRange(b.from,b.to),c.withinRange(a,b.from)||c.withinRange(a,b.to)||c.withinRange(b,a.from)||c.withinRange(b,a.to)},c.prototype.now=function(a,b){var c,d=this.item.interval,f=new Date,g=f.getHours()*e+f.getMinutes(),i=h.isInteger(b);return g-=g%d,c=b<0&&d*b+g<=-d,g+="min"==a&&c?0:d,i&&(g+=d*(c&&"max"!=a?b+1:b)),g},c.prototype.normalize=function(a,b){var c=this.item.interval,d=this.item.min&&this.item.min.pick||0;return b-="min"==a?0:(b-d)%c},c.prototype.measure=function(a,c,f){var g=this;return c||(c="min"==a?[0,0]:[d-1,e-1]),"string"==typeof c?c=g.parse(a,c):!0===c||h.isInteger(c)?c=g.now(a,c,f):b.isPlainObject(c)&&h.isInteger(c.pick)&&(c=g.normalize(a,c.pick,f)),c},c.prototype.validate=function(a,b,c){var d=this,e=c&&c.interval?c.interval:d.item.interval;return d.disabled(b)&&(b=d.shift(b,e)),b=d.scope(b),d.disabled(b)&&(b=d.shift(b,-1*e)),b},c.prototype.disabled=function(a){var c=this,d=c.item.disable.filter(function(d){return h.isInteger(d)?a.hour==d:b.isArray(d)||h.isDate(d)?a.pick==c.create(d).pick:b.isPlainObject(d)?c.withinRange(d,a):void 0});return d=d.length&&!d.filter(function(a){return b.isArray(a)&&"inverted"==a[2]||b.isPlainObject(a)&&a.inverted}).length,-1===c.item.enable?!d:d||a.pick<c.item.min.pick||a.pick>c.item.max.pick},c.prototype.shift=function(a,b){var c=this,d=c.item.min.pick,e=c.item.max.pick;for(b=b||c.item.interval;c.disabled(a)&&(a=c.create(a.pick+=b),!(a.pick<=d||a.pick>=e)););return a},c.prototype.scope=function(a){var b=this.item.min.pick,c=this.item.max.pick;return this.create(a.pick>c?c:a.pick<b?b:a)},c.prototype.parse=function(a,b,c){var d,f,g,i,j,k=this,l={};if(!b||"string"!=typeof b)return b;c&&c.format||(c=c||{},c.format=k.settings.format),k.formats.toArray(c.format).map(function(a){var c,d=k.formats[a],e=d?h.trigger(d,k,[b,l]):a.replace(/^!/,"").length;d&&(c=b.substr(0,e),l[a]=c.match(/^\d+$/)?+c:c),b=b.substr(e)});for(i in l)j=l[i],h.isInteger(j)?i.match(/^(h|hh)$/i)?(d=j,"h"!=i&&"hh"!=i||(d%=12)):"i"==i&&(f=j):i.match(/^a$/i)&&j.match(/^p/i)&&("h"in l||"hh"in l)&&(g=!0);return(g?d+12:d)*e+f},c.prototype.formats={h:function(a,b){return a?h.digits(a):b.hour%f||f},hh:function(a,b){return a?2:h.lead(b.hour%f||f)},H:function(a,b){return a?h.digits(a):""+b.hour%24},HH:function(a,b){return a?h.digits(a):h.lead(b.hour%24)},i:function(a,b){return a?2:h.lead(b.mins)},a:function(a,b){return a?4:g/2>b.time%g?"a.m.":"p.m."},A:function(a,b){return a?2:g/2>b.time%g?"AM":"PM"},toArray:function(a){return a.split(/(h{1,2}|H{1,2}|i|a|A|!.)/g)},toString:function(a,b){var c=this;return c.formats.toArray(a).map(function(a){return h.trigger(c.formats[a],c,[0,b])||a.replace(/^!/,"")}).join("")}},c.prototype.isTimeExact=function(a,c){var d=this;return h.isInteger(a)&&h.isInteger(c)||"boolean"==typeof a&&"boolean"==typeof c?a===c:(h.isDate(a)||b.isArray(a))&&(h.isDate(c)||b.isArray(c))?d.create(a).pick===d.create(c).pick:!(!b.isPlainObject(a)||!b.isPlainObject(c))&&(d.isTimeExact(a.from,c.from)&&d.isTimeExact(a.to,c.to))},c.prototype.isTimeOverlap=function(a,c){var d=this;return h.isInteger(a)&&(h.isDate(c)||b.isArray(c))?a===d.create(c).hour:h.isInteger(c)&&(h.isDate(a)||b.isArray(a))?c===d.create(a).hour:!(!b.isPlainObject(a)||!b.isPlainObject(c))&&d.overlapRanges(a,c)},c.prototype.flipEnable=function(a){var b=this.item;b.enable=a||(-1==b.enable?1:-1)},c.prototype.deactivate=function(a,c){var d=this,e=d.item.disable.slice(0);return"flip"==c?d.flipEnable():!1===c?(d.flipEnable(1),e=[]):!0===c?(d.flipEnable(-1),e=[]):c.map(function(a){for(var c,f=0;f<e.length;f+=1)if(d.isTimeExact(a,e[f])){c=!0;break}c||(h.isInteger(a)||h.isDate(a)||b.isArray(a)||b.isPlainObject(a)&&a.from&&a.to)&&e.push(a)}),e},c.prototype.activate=function(a,c){var d=this,e=d.item.disable,f=e.length;return"flip"==c?d.flipEnable():!0===c?(d.flipEnable(1),e=[]):!1===c?(d.flipEnable(-1),e=[]):c.map(function(a){var c,g,i,j;for(i=0;i<f;i+=1){if(g=e[i],d.isTimeExact(g,a)){c=e[i]=null,j=!0;break}if(d.isTimeOverlap(g,a)){b.isPlainObject(a)?(a.inverted=!0,c=a):b.isArray(a)?(c=a,c[2]||c.push("inverted")):h.isDate(a)&&(c=[a.getFullYear(),a.getMonth(),a.getDate(),"inverted"]);break}}if(c)for(i=0;i<f;i+=1)if(d.isTimeExact(e[i],a)){e[i]=null;break}if(j)for(i=0;i<f;i+=1)if(d.isTimeOverlap(e[i],a)){e[i]=null;break}c&&e.push(c)}),e.filter(function(a){return null!=a})},c.prototype.i=function(a,b){return h.isInteger(b)&&b>0?b:this.item.interval},c.prototype.nodes=function(a){var b=this,c=b.settings,d=b.item.select,e=b.item.highlight,f=b.item.view,g=b.item.disable;return h.node("ul",h.group({min:b.item.min.pick,max:b.item.max.pick,i:b.item.interval,node:"li",item:function(a){a=b.create(a);var i=a.pick,j=d&&d.pick==i,k=e&&e.pick==i,l=g&&b.disabled(a),m=h.trigger(b.formats.toString,b,[c.format,a]);return[h.trigger(b.formats.toString,b,[h.trigger(c.formatLabel,b,[a])||c.format,a]),function(a){return j&&a.push(c.klass.selected),k&&a.push(c.klass.highlighted),f&&f.pick==i&&a.push(c.klass.viewset),l&&a.push(c.klass.disabled),a.join(" ")}([c.klass.listItem]),"data-pick="+a.pick+" "+h.ariaAttr({role:"option",label:m,selected:!(!j||b.$node.val()!==m)||null,activedescendant:!!k||null,disabled:!!l||null})]}})+h.node("li",h.node("button",c.clear,c.klass.buttonClear,"type=button data-clear=1"+(a?"":" disabled")+" "+h.ariaAttr({controls:b.$node[0].id})),"",h.ariaAttr({role:"presentation"})),c.klass.list,h.ariaAttr({role:"listbox",controls:b.$node[0].id}))},c.defaults=function(a){return{clear:"Clear",format:"h:i A",interval:30,closeOnSelect:!0,closeOnClear:!0,updateInput:!0,klass:{picker:a+" "+a+"--time",holder:a+"__holder",list:a+"__list",listItem:a+"__list-item",disabled:a+"__list-item--disabled",selected:a+"__list-item--selected",highlighted:a+"__list-item--highlighted",viewset:a+"__list-item--viewset",now:a+"__list-item--now",buttonClear:a+"__button--clear"}}}(a.klasses().picker),a.extend("pickatime",c)});
|
1 |
+
/*!
|
2 |
+
* Time picker for pickadate.js v3.6.1
|
3 |
+
* http://amsul.github.io/pickadate.js/time.htm
|
4 |
+
*/
|
5 |
!function(a){"function"==typeof define&&define.amd?define(["./picker","jquery"],a):"object"==typeof exports?module.exports=a(require("./picker.js"),require("jquery")):a(Picker,jQuery)}(function(a,b){function c(a,b){var c=this,d=a.$node[0].value,e=a.$node.data("value"),f=e||d,g=e?b.formatSubmit:b.format;c.settings=b,c.$node=a.$node,c.queue={interval:"i",min:"measure create",max:"measure create",now:"now create",select:"parse create validate",highlight:"parse create validate",view:"parse create validate",disable:"deactivate",enable:"activate"},c.item={},c.item.clear=null,c.item.interval=b.interval||30,c.item.disable=(b.disable||[]).slice(0),c.item.enable=-function(a){return!0===a[0]?a.shift():-1}(c.item.disable),c.set("min",b.min).set("max",b.max).set("now"),f?c.set("select",f,{format:g}):c.set("select",null).set("highlight",c.item.now),c.key={40:1,38:-1,39:1,37:-1,go:function(a){c.set("highlight",c.item.highlight.pick+a*c.item.interval,{interval:a*c.item.interval}),this.render()}},a.on("render",function(){var c=a.$root.children(),d=c.find("."+b.klass.viewset),e=function(a){return["webkit","moz","ms","o",""].map(function(b){return(b?"-"+b+"-":"")+a})},f=function(a,b){e("transform").map(function(c){a.css(c,b)}),e("transition").map(function(c){a.css(c,b)})};d.length&&(f(c,"none"),c[0].scrollTop=~~d.position().top-2*d[0].clientHeight,f(c,""))},1).on("open",function(){a.$root.find("button").attr("disabled",!1)},1).on("close",function(){a.$root.find("button").attr("disabled",!0)},1)}var d=24,e=60,f=12,g=d*e,h=a._;c.prototype.set=function(a,b,c){var d=this,e=d.item;return null===b?("clear"==a&&(a="select"),e[a]=b,d):(e["enable"==a?"disable":"flip"==a?"enable":a]=d.queue[a].split(" ").map(function(e){return b=d[e](a,b,c)}).pop(),"select"==a?d.set("highlight",e.select,c):"highlight"==a?d.set("view",e.highlight,c):"interval"==a?d.set("min",e.min,c).set("max",e.max,c):a.match(/^(flip|min|max|disable|enable)$/)&&(e.select&&d.disabled(e.select)&&d.set("select",b,c),e.highlight&&d.disabled(e.highlight)&&d.set("highlight",b,c),"min"==a&&d.set("max",e.max,c)),d)},c.prototype.get=function(a){return this.item[a]},c.prototype.create=function(a,c,f){var i=this;return c=void 0===c?a:c,h.isDate(c)&&(c=[c.getHours(),c.getMinutes()]),b.isPlainObject(c)&&h.isInteger(c.pick)?c=c.pick:b.isArray(c)?c=+c[0]*e+ +c[1]:h.isInteger(c)||(c=i.now(a,c,f)),"max"==a&&c<i.item.min.pick&&(c+=g),"min"!=a&&"max"!=a&&(c-i.item.min.pick)%i.item.interval!=0&&(c+=i.item.interval),c=i.normalize(a,c,f),{hour:~~(d+c/e)%d,mins:(e+c%e)%e,time:(g+c)%g,pick:c%g}},c.prototype.createRange=function(a,c){var d=this,e=function(a){return!0===a||b.isArray(a)||h.isDate(a)?d.create(a):a};return h.isInteger(a)||(a=e(a)),h.isInteger(c)||(c=e(c)),h.isInteger(a)&&b.isPlainObject(c)?a=[c.hour,c.mins+a*d.settings.interval]:h.isInteger(c)&&b.isPlainObject(a)&&(c=[a.hour,a.mins+c*d.settings.interval]),{from:e(a),to:e(c)}},c.prototype.withinRange=function(a,b){return a=this.createRange(a.from,a.to),b.pick>=a.from.pick&&b.pick<=a.to.pick},c.prototype.overlapRanges=function(a,b){var c=this;return a=c.createRange(a.from,a.to),b=c.createRange(b.from,b.to),c.withinRange(a,b.from)||c.withinRange(a,b.to)||c.withinRange(b,a.from)||c.withinRange(b,a.to)},c.prototype.now=function(a,b){var c,d=this.item.interval,f=new Date,g=f.getHours()*e+f.getMinutes(),i=h.isInteger(b);return g-=g%d,c=b<0&&d*b+g<=-d,g+="min"==a&&c?0:d,i&&(g+=d*(c&&"max"!=a?b+1:b)),g},c.prototype.normalize=function(a,b){var c=this.item.interval,d=this.item.min&&this.item.min.pick||0;return b-="min"==a?0:(b-d)%c},c.prototype.measure=function(a,c,f){var g=this;return c||(c="min"==a?[0,0]:[d-1,e-1]),"string"==typeof c?c=g.parse(a,c):!0===c||h.isInteger(c)?c=g.now(a,c,f):b.isPlainObject(c)&&h.isInteger(c.pick)&&(c=g.normalize(a,c.pick,f)),c},c.prototype.validate=function(a,b,c){var d=this,e=c&&c.interval?c.interval:d.item.interval;return d.disabled(b)&&(b=d.shift(b,e)),b=d.scope(b),d.disabled(b)&&(b=d.shift(b,-1*e)),b},c.prototype.disabled=function(a){var c=this,d=c.item.disable.filter(function(d){return h.isInteger(d)?a.hour==d:b.isArray(d)||h.isDate(d)?a.pick==c.create(d).pick:b.isPlainObject(d)?c.withinRange(d,a):void 0});return d=d.length&&!d.filter(function(a){return b.isArray(a)&&"inverted"==a[2]||b.isPlainObject(a)&&a.inverted}).length,-1===c.item.enable?!d:d||a.pick<c.item.min.pick||a.pick>c.item.max.pick},c.prototype.shift=function(a,b){var c=this,d=c.item.min.pick,e=c.item.max.pick;for(b=b||c.item.interval;c.disabled(a)&&(a=c.create(a.pick+=b),!(a.pick<=d||a.pick>=e)););return a},c.prototype.scope=function(a){var b=this.item.min.pick,c=this.item.max.pick;return this.create(a.pick>c?c:a.pick<b?b:a)},c.prototype.parse=function(a,b,c){var d,f,g,i,j,k=this,l={};if(!b||"string"!=typeof b)return b;c&&c.format||(c=c||{},c.format=k.settings.format),k.formats.toArray(c.format).map(function(a){var c,d=k.formats[a],e=d?h.trigger(d,k,[b,l]):a.replace(/^!/,"").length;d&&(c=b.substr(0,e),l[a]=c.match(/^\d+$/)?+c:c),b=b.substr(e)});for(i in l)j=l[i],h.isInteger(j)?i.match(/^(h|hh)$/i)?(d=j,"h"!=i&&"hh"!=i||(d%=12)):"i"==i&&(f=j):i.match(/^a$/i)&&j.match(/^p/i)&&("h"in l||"hh"in l)&&(g=!0);return(g?d+12:d)*e+f},c.prototype.formats={h:function(a,b){return a?h.digits(a):b.hour%f||f},hh:function(a,b){return a?2:h.lead(b.hour%f||f)},H:function(a,b){return a?h.digits(a):""+b.hour%24},HH:function(a,b){return a?h.digits(a):h.lead(b.hour%24)},i:function(a,b){return a?2:h.lead(b.mins)},a:function(a,b){return a?4:g/2>b.time%g?"a.m.":"p.m."},A:function(a,b){return a?2:g/2>b.time%g?"AM":"PM"},toArray:function(a){return a.split(/(h{1,2}|H{1,2}|i|a|A|!.)/g)},toString:function(a,b){var c=this;return c.formats.toArray(a).map(function(a){return h.trigger(c.formats[a],c,[0,b])||a.replace(/^!/,"")}).join("")}},c.prototype.isTimeExact=function(a,c){var d=this;return h.isInteger(a)&&h.isInteger(c)||"boolean"==typeof a&&"boolean"==typeof c?a===c:(h.isDate(a)||b.isArray(a))&&(h.isDate(c)||b.isArray(c))?d.create(a).pick===d.create(c).pick:!(!b.isPlainObject(a)||!b.isPlainObject(c))&&(d.isTimeExact(a.from,c.from)&&d.isTimeExact(a.to,c.to))},c.prototype.isTimeOverlap=function(a,c){var d=this;return h.isInteger(a)&&(h.isDate(c)||b.isArray(c))?a===d.create(c).hour:h.isInteger(c)&&(h.isDate(a)||b.isArray(a))?c===d.create(a).hour:!(!b.isPlainObject(a)||!b.isPlainObject(c))&&d.overlapRanges(a,c)},c.prototype.flipEnable=function(a){var b=this.item;b.enable=a||(-1==b.enable?1:-1)},c.prototype.deactivate=function(a,c){var d=this,e=d.item.disable.slice(0);return"flip"==c?d.flipEnable():!1===c?(d.flipEnable(1),e=[]):!0===c?(d.flipEnable(-1),e=[]):c.map(function(a){for(var c,f=0;f<e.length;f+=1)if(d.isTimeExact(a,e[f])){c=!0;break}c||(h.isInteger(a)||h.isDate(a)||b.isArray(a)||b.isPlainObject(a)&&a.from&&a.to)&&e.push(a)}),e},c.prototype.activate=function(a,c){var d=this,e=d.item.disable,f=e.length;return"flip"==c?d.flipEnable():!0===c?(d.flipEnable(1),e=[]):!1===c?(d.flipEnable(-1),e=[]):c.map(function(a){var c,g,i,j;for(i=0;i<f;i+=1){if(g=e[i],d.isTimeExact(g,a)){c=e[i]=null,j=!0;break}if(d.isTimeOverlap(g,a)){b.isPlainObject(a)?(a.inverted=!0,c=a):b.isArray(a)?(c=a,c[2]||c.push("inverted")):h.isDate(a)&&(c=[a.getFullYear(),a.getMonth(),a.getDate(),"inverted"]);break}}if(c)for(i=0;i<f;i+=1)if(d.isTimeExact(e[i],a)){e[i]=null;break}if(j)for(i=0;i<f;i+=1)if(d.isTimeOverlap(e[i],a)){e[i]=null;break}c&&e.push(c)}),e.filter(function(a){return null!=a})},c.prototype.i=function(a,b){return h.isInteger(b)&&b>0?b:this.item.interval},c.prototype.nodes=function(a){var b=this,c=b.settings,d=b.item.select,e=b.item.highlight,f=b.item.view,g=b.item.disable;return h.node("ul",h.group({min:b.item.min.pick,max:b.item.max.pick,i:b.item.interval,node:"li",item:function(a){a=b.create(a);var i=a.pick,j=d&&d.pick==i,k=e&&e.pick==i,l=g&&b.disabled(a),m=h.trigger(b.formats.toString,b,[c.format,a]);return[h.trigger(b.formats.toString,b,[h.trigger(c.formatLabel,b,[a])||c.format,a]),function(a){return j&&a.push(c.klass.selected),k&&a.push(c.klass.highlighted),f&&f.pick==i&&a.push(c.klass.viewset),l&&a.push(c.klass.disabled),a.join(" ")}([c.klass.listItem]),"data-pick="+a.pick+" "+h.ariaAttr({role:"option",label:m,selected:!(!j||b.$node.val()!==m)||null,activedescendant:!!k||null,disabled:!!l||null})]}})+h.node("li",h.node("button",c.clear,c.klass.buttonClear,"type=button data-clear=1"+(a?"":" disabled")+" "+h.ariaAttr({controls:b.$node[0].id})),"",h.ariaAttr({role:"presentation"})),c.klass.list,h.ariaAttr({role:"listbox",controls:b.$node[0].id}))},c.defaults=function(a){return{clear:"Clear",format:"h:i A",interval:30,closeOnSelect:!0,closeOnClear:!0,updateInput:!0,klass:{picker:a+" "+a+"--time",holder:a+"__holder",list:a+"__list",listItem:a+"__list-item",disabled:a+"__list-item--disabled",selected:a+"__list-item--selected",highlighted:a+"__list-item--highlighted",viewset:a+"__list-item--viewset",now:a+"__list-item--now",buttonClear:a+"__button--clear"}}}(a.klasses().picker),a.extend("pickatime",c)});
|
lib/simple-admin-pages/lib/pickadate/themes/default.css
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
.picker{font-size:16px;text-align:left;line-height:1.2;color:#000;position:absolute;z-index:10000;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;outline:0}.picker__input{cursor:default}.picker__input.picker__input--active{border-color:#0089ec}.picker__holder{width:100%;overflow-y:auto;-webkit-overflow-scrolling:touch;position:fixed;transition:background .15s ease-out,transform 0s .15s;-webkit-backface-visibility:hidden}/*!
|
2 |
-
* Default mobile-first, responsive styling for pickadate.js
|
3 |
-
* Demo: http://amsul.github.io/pickadate.js
|
4 |
*/.picker__frame,.picker__holder{top:0;bottom:0;left:0;right:0;-ms-transform:translateY(100%);transform:translateY(100%)}.picker__frame{position:absolute;margin:0 auto;min-width:256px;max-width:666px;width:100%;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";filter:alpha(opacity=0);-moz-opacity:0;opacity:0;transition:all .15s ease-out}.picker__wrap{display:table;width:100%;height:100%}@media (min-height:33.875em){.picker__frame{overflow:visible;top:auto;bottom:-100%;max-height:80%}.picker__wrap{display:block}}.picker__box{background:#fff;display:table-cell;vertical-align:middle}@media (min-height:26.5em){.picker__box{font-size:1.25em}}@media (min-height:33.875em){.picker__box{display:block;font-size:1.33em;border:1px solid #777;border-top-color:#898989;border-bottom-width:0;border-radius:5px 5px 0 0;box-shadow:0 12px 36px 16px rgba(0,0,0,.24)}.picker--opened .picker__frame{top:auto;bottom:0}}@media (min-height:40.125em){.picker__frame{margin-bottom:7.5%}.picker__box{font-size:1.5em;border-bottom-width:1px;border-radius:5px}}.picker--opened .picker__holder{-ms-transform:translateY(0);transform:translateY(0);zoom:1;background:rgba(0,0,0,.32);transition:background .15s ease-out}.picker--opened .picker__frame{-ms-transform:translateY(0);transform:translateY(0);-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";filter:alpha(opacity=100);-moz-opacity:1;opacity:1}
|
1 |
+
.picker{font-size:16px;text-align:left;line-height:1.2;color:#000;position:absolute;z-index:10000;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;outline:0}.picker__input{cursor:default}.picker__input.picker__input--active{border-color:#0089ec}.picker__holder{width:100%;overflow-y:auto;-webkit-overflow-scrolling:touch;position:fixed;transition:background .15s ease-out,transform 0s .15s;-webkit-backface-visibility:hidden}/*!
|
2 |
+
* Default mobile-first, responsive styling for pickadate.js
|
3 |
+
* Demo: http://amsul.github.io/pickadate.js
|
4 |
*/.picker__frame,.picker__holder{top:0;bottom:0;left:0;right:0;-ms-transform:translateY(100%);transform:translateY(100%)}.picker__frame{position:absolute;margin:0 auto;min-width:256px;max-width:666px;width:100%;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";filter:alpha(opacity=0);-moz-opacity:0;opacity:0;transition:all .15s ease-out}.picker__wrap{display:table;width:100%;height:100%}@media (min-height:33.875em){.picker__frame{overflow:visible;top:auto;bottom:-100%;max-height:80%}.picker__wrap{display:block}}.picker__box{background:#fff;display:table-cell;vertical-align:middle}@media (min-height:26.5em){.picker__box{font-size:1.25em}}@media (min-height:33.875em){.picker__box{display:block;font-size:1.33em;border:1px solid #777;border-top-color:#898989;border-bottom-width:0;border-radius:5px 5px 0 0;box-shadow:0 12px 36px 16px rgba(0,0,0,.24)}.picker--opened .picker__frame{top:auto;bottom:0}}@media (min-height:40.125em){.picker__frame{margin-bottom:7.5%}.picker__box{font-size:1.5em;border-bottom-width:1px;border-radius:5px}}.picker--opened .picker__holder{-ms-transform:translateY(0);transform:translateY(0);zoom:1;background:rgba(0,0,0,.32);transition:background .15s ease-out}.picker--opened .picker__frame{-ms-transform:translateY(0);transform:translateY(0);-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";filter:alpha(opacity=100);-moz-opacity:1;opacity:1}
|
lib/simple-admin-pages/lib/pickadate/themes/rtl.css
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
-
/*!
|
2 |
-
* Styling for RTL (right-to-left) languages using pickadate.js
|
3 |
*/.picker{direction:rtl}.picker__nav--next{right:auto;left:-1em}.picker__nav--prev{left:auto;right:-1em}.picker__nav--next:before{border-left:0;border-right:.75em solid #000}.picker__nav--prev:before{border-right:0;border-left:.75em solid #000}
|
1 |
+
/*!
|
2 |
+
* Styling for RTL (right-to-left) languages using pickadate.js
|
3 |
*/.picker{direction:rtl}.picker__nav--next{right:auto;left:-1em}.picker__nav--prev{left:auto;right:-1em}.picker__nav--next:before{border-left:0;border-right:.75em solid #000}.picker__nav--prev:before{border-right:0;border-left:.75em solid #000}
|
lib/simple-admin-pages/simple-admin-pages.php
CHANGED
@@ -1,52 +1,52 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Simple Admin Pages
|
5 |
-
*
|
6 |
-
* This is a very small utility library to easily add new admin pages to the
|
7 |
-
* WordPress admin interface. It simply collects WordPress' useful Settings API
|
8 |
-
* into reuseable classes.
|
9 |
-
*
|
10 |
-
* Created by Nate Wright
|
11 |
-
*
|
12 |
-
*
|
13 |
-
* @since 1.0
|
14 |
-
* @package Simple Admin Pages
|
15 |
-
* @license GNU GPL 2 or later
|
16 |
-
*/
|
17 |
-
|
18 |
-
/**
|
19 |
-
* Always load the library files attached to this copy of SAP
|
20 |
-
*
|
21 |
-
* This fixes a compatibility bug if two versions of the library are being
|
22 |
-
* loaded by different plugins/themes. However, versions prior to 2.0 do not
|
23 |
-
* include this and can cause compatibility issues.
|
24 |
-
*/
|
25 |
-
require_once( 'classes/Library.class.php' );
|
26 |
-
|
27 |
-
/**
|
28 |
-
* Initialize the appropriate version of the libary.
|
29 |
-
*
|
30 |
-
* This function should remain backwards compatible at all times, so that the
|
31 |
-
* initialization function from version 1.0 will still be able to initialize
|
32 |
-
* the library appropriately for version 2.0. This way, if two plugins exist
|
33 |
-
* with different versions, the plugin creator will still be able to initialize
|
34 |
-
* their library.
|
35 |
-
*
|
36 |
-
* @since 1.0
|
37 |
-
*/
|
38 |
-
if ( !function_exists( 'sap_initialize_library' ) ) {
|
39 |
-
|
40 |
-
function sap_initialize_library( $args = array() ) {
|
41 |
-
|
42 |
-
// Exit early if no version was provided
|
43 |
-
if ( !isset( $args['version'] ) ) {
|
44 |
-
return null;
|
45 |
-
}
|
46 |
-
|
47 |
-
$lib_class_name = 'sapLibrary_' . str_replace( '.', '_', $args['version'] );
|
48 |
-
|
49 |
-
return new $lib_class_name( $args );
|
50 |
-
}
|
51 |
-
|
52 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Simple Admin Pages
|
5 |
+
*
|
6 |
+
* This is a very small utility library to easily add new admin pages to the
|
7 |
+
* WordPress admin interface. It simply collects WordPress' useful Settings API
|
8 |
+
* into reuseable classes.
|
9 |
+
*
|
10 |
+
* Created by Nate Wright
|
11 |
+
*
|
12 |
+
*
|
13 |
+
* @since 1.0
|
14 |
+
* @package Simple Admin Pages
|
15 |
+
* @license GNU GPL 2 or later
|
16 |
+
*/
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Always load the library files attached to this copy of SAP
|
20 |
+
*
|
21 |
+
* This fixes a compatibility bug if two versions of the library are being
|
22 |
+
* loaded by different plugins/themes. However, versions prior to 2.0 do not
|
23 |
+
* include this and can cause compatibility issues.
|
24 |
+
*/
|
25 |
+
require_once( 'classes/Library.class.php' );
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Initialize the appropriate version of the libary.
|
29 |
+
*
|
30 |
+
* This function should remain backwards compatible at all times, so that the
|
31 |
+
* initialization function from version 1.0 will still be able to initialize
|
32 |
+
* the library appropriately for version 2.0. This way, if two plugins exist
|
33 |
+
* with different versions, the plugin creator will still be able to initialize
|
34 |
+
* their library.
|
35 |
+
*
|
36 |
+
* @since 1.0
|
37 |
+
*/
|
38 |
+
if ( !function_exists( 'sap_initialize_library' ) ) {
|
39 |
+
|
40 |
+
function sap_initialize_library( $args = array() ) {
|
41 |
+
|
42 |
+
// Exit early if no version was provided
|
43 |
+
if ( !isset( $args['version'] ) ) {
|
44 |
+
return null;
|
45 |
+
}
|
46 |
+
|
47 |
+
$lib_class_name = 'sapLibrary_' . str_replace( '.', '_', $args['version'] );
|
48 |
+
|
49 |
+
return new $lib_class_name( $args );
|
50 |
+
}
|
51 |
+
|
52 |
+
}
|
readme.txt
CHANGED
@@ -5,7 +5,7 @@ Plugin URL: https://www.fivestarplugins.com/plugins/business-profile/
|
|
5 |
Requires at Least: 5.3
|
6 |
Tested Up To: 5.8
|
7 |
Tags: business profile, seo, local seo, schema, address, google map, contact, phone, contact card, vcard, contact info, business location, business address, business map, business schema, organization schema, corporation schema, contact schema, address schema, location schema, map schema, business structured data, business microdata, address microdata, location structured data, location microdata, contact shortcode, location shortcode, address shortcode, schema shortcode, gutenberg schema, gutenberg address
|
8 |
-
Stable tag: 2.1.
|
9 |
License: GPLv3
|
10 |
License URI:http://www.gnu.org/licenses/gpl-3.0.html
|
11 |
|
@@ -192,6 +192,14 @@ You'll find more help in the [User Guide](http://doc.themeofthecrop.com/plugins/
|
|
192 |
|
193 |
== Changelog ==
|
194 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
195 |
= 2.1.4 (2021-07-21) =
|
196 |
- The plugin has been tested up to WordPress version 5.8.
|
197 |
|
5 |
Requires at Least: 5.3
|
6 |
Tested Up To: 5.8
|
7 |
Tags: business profile, seo, local seo, schema, address, google map, contact, phone, contact card, vcard, contact info, business location, business address, business map, business schema, organization schema, corporation schema, contact schema, address schema, location schema, map schema, business structured data, business microdata, address microdata, location structured data, location microdata, contact shortcode, location shortcode, address shortcode, schema shortcode, gutenberg schema, gutenberg address
|
8 |
+
Stable tag: 2.1.5
|
9 |
License: GPLv3
|
10 |
License URI:http://www.gnu.org/licenses/gpl-3.0.html
|
11 |
|
192 |
|
193 |
== Changelog ==
|
194 |
|
195 |
+
= 2.1.5 (2021-09-30) =
|
196 |
+
- Updated the settings page library.
|
197 |
+
- Updated name of templates folder for consistent prefixing.
|
198 |
+
- Added an option so that, if you offer online ordering, you can enter the URL of your order page (can be on the same site or external) and a link to it will display in your contact card.
|
199 |
+
- Past exceptions no longer show in the schedule/opening hours, and are now automatically removed when the options are saved.
|
200 |
+
- Added "Image URL" field to the list of elements on the schema create/edit screen for the Organization schema type.
|
201 |
+
- Moved contact card block into its own category/section.
|
202 |
+
|
203 |
= 2.1.4 (2021-07-21) =
|
204 |
- The plugin has been tested up to WordPress version 5.8.
|
205 |
|