Version Description
- 2019-08-19 =
Fixed
- Fatal error with
RWMB_About::redirect()
- Ensure change event fires when editors change
- Fix
rwmb_{$field_id}_choice_label
not working for cloneable fields - Fix missing dependency (underscore) for datepicker JS
- Fix unindex notice for key_value field
- Fix alignment for video field
Changed
- Update notification sytem
- Improve sanitization for fields. See documentation for details.
Download this release
Release Info
Developer | rilwis |
Plugin | Meta Box |
Version | 5.1.0 |
Comparing to | |
See all releases |
Code changes from version 5.0.1 to 5.1.0
- css/style.css +6 -5
- css/video.css +4 -5
- inc/about/about.php +1 -1
- inc/clone.php +9 -9
- inc/field.php +32 -2
- inc/fields/datetime.php +2 -2
- inc/fields/key-value.php +2 -1
- inc/fields/taxonomy-advanced.php +2 -20
- inc/loader.php +8 -5
- inc/media-modal.php +1 -9
- inc/meta-box.php +1 -9
- inc/sanitizer.php +230 -26
- inc/update/checker.php +54 -38
- inc/update/notification.php +195 -0
- inc/update/option.php +50 -0
- inc/update/settings.php +73 -108
- js/notification.js +16 -0
- js/wysiwyg.js +5 -0
- meta-box.php +1 -1
- readme.txt +18 -1
css/style.css
CHANGED
@@ -60,19 +60,20 @@
|
|
60 |
}
|
61 |
.rwmb-button.remove-clone {
|
62 |
text-decoration: none;
|
63 |
-
color: #
|
64 |
-
background: #e74c3c;
|
65 |
-
border-radius: 50%;
|
66 |
display: inline-block;
|
67 |
position: absolute;
|
68 |
top: 0;
|
69 |
right: 0;
|
70 |
width: 20px;
|
71 |
height: 20px;
|
|
|
72 |
}
|
73 |
.rwmb-button.remove-clone .dashicons {
|
74 |
-
font-size:
|
75 |
-
|
|
|
|
|
76 |
}
|
77 |
.remove-clone:focus {
|
78 |
outline: 0;
|
60 |
}
|
61 |
.rwmb-button.remove-clone {
|
62 |
text-decoration: none;
|
63 |
+
color: #ccc;
|
|
|
|
|
64 |
display: inline-block;
|
65 |
position: absolute;
|
66 |
top: 0;
|
67 |
right: 0;
|
68 |
width: 20px;
|
69 |
height: 20px;
|
70 |
+
transition: color 200ms;
|
71 |
}
|
72 |
.rwmb-button.remove-clone .dashicons {
|
73 |
+
font-size: 20px;
|
74 |
+
}
|
75 |
+
.rwmb-button.remove-clone:hover {
|
76 |
+
color: #dc3232;
|
77 |
}
|
78 |
.remove-clone:focus {
|
79 |
outline: 0;
|
css/video.css
CHANGED
@@ -1,9 +1,8 @@
|
|
1 |
-
/* Video */
|
2 |
.rwmb-video-item {
|
3 |
position: relative;
|
4 |
float: left;
|
5 |
-
padding:
|
6 |
-
margin: 0
|
7 |
box-sizing: border-box;
|
8 |
width: 300px;
|
9 |
}
|
@@ -11,7 +10,7 @@
|
|
11 |
.rwmb-video-item .rwmb-media-preview {
|
12 |
width: 100%;
|
13 |
float: none;
|
14 |
-
background: #
|
15 |
}
|
16 |
|
17 |
.rwmb-video-item video {
|
@@ -21,5 +20,5 @@
|
|
21 |
|
22 |
.rwmb-video-item .rwmb-media-info {
|
23 |
margin-left: 0;
|
24 |
-
padding: 10px;
|
25 |
}
|
|
|
1 |
.rwmb-video-item {
|
2 |
position: relative;
|
3 |
float: left;
|
4 |
+
padding: 8px;
|
5 |
+
margin: 0;
|
6 |
box-sizing: border-box;
|
7 |
width: 300px;
|
8 |
}
|
10 |
.rwmb-video-item .rwmb-media-preview {
|
11 |
width: 100%;
|
12 |
float: none;
|
13 |
+
background: #eee;
|
14 |
}
|
15 |
|
16 |
.rwmb-video-item video {
|
20 |
|
21 |
.rwmb-video-item .rwmb-media-info {
|
22 |
margin-left: 0;
|
23 |
+
padding: 10px 0;
|
24 |
}
|
inc/about/about.php
CHANGED
@@ -152,7 +152,7 @@ class RWMB_About {
|
|
152 |
* @param bool $network_wide Whether to enable the plugin for all sites in the network
|
153 |
* or just the current site. Multisite only. Default is false.
|
154 |
*/
|
155 |
-
public function redirect( $plugin, $network_wide ) {
|
156 |
if ( 'cli' !== php_sapi_name() && ! $network_wide && 'meta-box/meta-box.php' === $plugin && ! $this->is_bundled() ) {
|
157 |
wp_safe_redirect( $this->get_menu_link() );
|
158 |
die;
|
152 |
* @param bool $network_wide Whether to enable the plugin for all sites in the network
|
153 |
* or just the current site. Multisite only. Default is false.
|
154 |
*/
|
155 |
+
public function redirect( $plugin, $network_wide = false ) {
|
156 |
if ( 'cli' !== php_sapi_name() && ! $network_wide && 'meta-box/meta-box.php' === $plugin && ! $this->is_bundled() ) {
|
157 |
wp_safe_redirect( $this->get_menu_link() );
|
158 |
die;
|
inc/clone.php
CHANGED
@@ -71,26 +71,26 @@ class RWMB_Clone {
|
|
71 |
/**
|
72 |
* Set value of meta before saving into database
|
73 |
*
|
74 |
-
* @param mixed $new
|
75 |
-
* @param mixed $old
|
76 |
-
* @param int $
|
77 |
-
* @param array $field
|
78 |
*
|
79 |
* @return mixed
|
80 |
*/
|
81 |
-
public static function value( $new, $old, $
|
82 |
if ( ! is_array( $new ) ) {
|
83 |
$new = array();
|
84 |
}
|
85 |
|
86 |
if ( in_array( $field['type'], array( 'file', 'image' ), true ) ) {
|
87 |
-
return RWMB_Field::call( $field, 'value', $new, '', $
|
88 |
}
|
89 |
|
90 |
foreach ( $new as $key => $value ) {
|
91 |
$old_value = isset( $old[ $key ] ) ? $old[ $key ] : null;
|
92 |
-
$value = RWMB_Field::call( $field, 'value', $value, $old_value, $
|
93 |
-
$new[ $key ] = RWMB_Field::filter( 'sanitize', $value, $field );
|
94 |
}
|
95 |
|
96 |
// Remove empty clones.
|
@@ -123,7 +123,7 @@ class RWMB_Clone {
|
|
123 |
* @return string $html
|
124 |
*/
|
125 |
public static function remove_clone_button( $field ) {
|
126 |
-
$text = RWMB_Field::filter( 'remove_clone_button_text', '<
|
127 |
return '<a href="#" class="rwmb-button remove-clone">' . $text . '</a>';
|
128 |
}
|
129 |
}
|
71 |
/**
|
72 |
* Set value of meta before saving into database
|
73 |
*
|
74 |
+
* @param mixed $new The submitted meta value.
|
75 |
+
* @param mixed $old The existing meta value.
|
76 |
+
* @param int $object_id The object ID.
|
77 |
+
* @param array $field The field parameters.
|
78 |
*
|
79 |
* @return mixed
|
80 |
*/
|
81 |
+
public static function value( $new, $old, $object_id, $field ) {
|
82 |
if ( ! is_array( $new ) ) {
|
83 |
$new = array();
|
84 |
}
|
85 |
|
86 |
if ( in_array( $field['type'], array( 'file', 'image' ), true ) ) {
|
87 |
+
return RWMB_Field::call( $field, 'value', $new, '', $object_id );
|
88 |
}
|
89 |
|
90 |
foreach ( $new as $key => $value ) {
|
91 |
$old_value = isset( $old[ $key ] ) ? $old[ $key ] : null;
|
92 |
+
$value = RWMB_Field::call( $field, 'value', $value, $old_value, $object_id );
|
93 |
+
$new[ $key ] = RWMB_Field::filter( 'sanitize', $value, $field, $old_value, $object_id );
|
94 |
}
|
95 |
|
96 |
// Remove empty clones.
|
123 |
* @return string $html
|
124 |
*/
|
125 |
public static function remove_clone_button( $field ) {
|
126 |
+
$text = RWMB_Field::filter( 'remove_clone_button_text', '<span class="dashicons dashicons-dismiss"></span>', $field );
|
127 |
return '<a href="#" class="rwmb-button remove-clone">' . $text . '</a>';
|
128 |
}
|
129 |
}
|
inc/field.php
CHANGED
@@ -246,6 +246,28 @@ abstract class RWMB_Field {
|
|
246 |
return is_array( $meta ) ? array_map( __METHOD__, $meta ) : esc_attr( $meta );
|
247 |
}
|
248 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
249 |
/**
|
250 |
* Set value of meta before saving into database.
|
251 |
*
|
@@ -337,9 +359,16 @@ abstract class RWMB_Field {
|
|
337 |
'required' => false,
|
338 |
'autofocus' => false,
|
339 |
'attributes' => array(),
|
|
|
|
|
340 |
)
|
341 |
);
|
342 |
|
|
|
|
|
|
|
|
|
|
|
343 |
if ( $field['clone_default'] ) {
|
344 |
$field['attributes'] = wp_parse_args(
|
345 |
$field['attributes'],
|
@@ -574,8 +603,9 @@ abstract class RWMB_Field {
|
|
574 |
'rwmb_' . $name,
|
575 |
'rwmb_' . $field['type'] . '_' . $name,
|
576 |
);
|
577 |
-
if (
|
578 |
-
$
|
|
|
579 |
}
|
580 |
|
581 |
// Filter params: value, field, other params. Note: value is changed after each run.
|
246 |
return is_array( $meta ) ? array_map( __METHOD__, $meta ) : esc_attr( $meta );
|
247 |
}
|
248 |
|
249 |
+
/**
|
250 |
+
* Process the submitted value before saving into the database.
|
251 |
+
*
|
252 |
+
* @param mixed $value The submitted value.
|
253 |
+
* @param int $object_id The object ID.
|
254 |
+
* @param array $field The field settings.
|
255 |
+
*/
|
256 |
+
public static function process_value( $value, $object_id, $field ) {
|
257 |
+
$old_value = self::call( $field, 'raw_meta', $object_id );
|
258 |
+
|
259 |
+
// Allow field class change the value.
|
260 |
+
if ( $field['clone'] ) {
|
261 |
+
$value = RWMB_Clone::value( $value, $old_value, $object_id, $field );
|
262 |
+
} else {
|
263 |
+
$value = self::call( $field, 'value', $value, $old_value, $object_id );
|
264 |
+
$value = self::filter( 'sanitize', $value, $field, $old_value, $object_id );
|
265 |
+
}
|
266 |
+
$value = self::filter( 'value', $value, $field, $old_value, $object_id );
|
267 |
+
|
268 |
+
return $value;
|
269 |
+
}
|
270 |
+
|
271 |
/**
|
272 |
* Set value of meta before saving into database.
|
273 |
*
|
359 |
'required' => false,
|
360 |
'autofocus' => false,
|
361 |
'attributes' => array(),
|
362 |
+
|
363 |
+
'sanitize_callback' => null,
|
364 |
)
|
365 |
);
|
366 |
|
367 |
+
// Store the original ID to run correct filters for the clonable field.
|
368 |
+
if ( $field['clone'] ) {
|
369 |
+
$field['_original_id'] = $field['id'];
|
370 |
+
}
|
371 |
+
|
372 |
if ( $field['clone_default'] ) {
|
373 |
$field['attributes'] = wp_parse_args(
|
374 |
$field['attributes'],
|
603 |
'rwmb_' . $name,
|
604 |
'rwmb_' . $field['type'] . '_' . $name,
|
605 |
);
|
606 |
+
if ( $field['id'] ) {
|
607 |
+
$field_id = $field['clone'] ? $field['_original_id'] : $field['id'];
|
608 |
+
$filters[] = 'rwmb_' . $field_id . '_' . $name;
|
609 |
}
|
610 |
|
611 |
// Filter params: value, field, other params. Note: value is changed after each run.
|
inc/fields/datetime.php
CHANGED
@@ -67,8 +67,8 @@ class RWMB_Datetime_Field extends RWMB_Text_Field {
|
|
67 |
wp_register_script( 'jquery-ui-timepicker', "$url/jquery-ui-timepicker-addon.min.js", array( 'jquery-ui-datepicker', 'jquery-ui-slider' ), '1.5.0', true );
|
68 |
wp_register_script( 'jquery-ui-timepicker-i18n', "$url/jquery-ui-timepicker-addon-i18n.min.js", array( 'jquery-ui-timepicker' ), '1.5.0', true );
|
69 |
|
70 |
-
wp_register_script( 'rwmb-datetime', RWMB_JS_URL . 'datetime.js', array( 'jquery-ui-datepicker', 'jquery-ui-timepicker-i18n' ), RWMB_VER, true );
|
71 |
-
wp_register_script( 'rwmb-date', RWMB_JS_URL . 'date.js', array( 'jquery-ui-datepicker' ), RWMB_VER, true );
|
72 |
wp_register_script( 'rwmb-time', RWMB_JS_URL . 'time.js', array( 'jquery-ui-timepicker-i18n' ), RWMB_VER, true );
|
73 |
|
74 |
$handles = array( 'datetime', 'time' );
|
67 |
wp_register_script( 'jquery-ui-timepicker', "$url/jquery-ui-timepicker-addon.min.js", array( 'jquery-ui-datepicker', 'jquery-ui-slider' ), '1.5.0', true );
|
68 |
wp_register_script( 'jquery-ui-timepicker-i18n', "$url/jquery-ui-timepicker-addon-i18n.min.js", array( 'jquery-ui-timepicker' ), '1.5.0', true );
|
69 |
|
70 |
+
wp_register_script( 'rwmb-datetime', RWMB_JS_URL . 'datetime.js', array( 'jquery-ui-datepicker', 'jquery-ui-timepicker-i18n', 'underscore' ), RWMB_VER, true );
|
71 |
+
wp_register_script( 'rwmb-date', RWMB_JS_URL . 'date.js', array( 'jquery-ui-datepicker', 'underscore' ), RWMB_VER, true );
|
72 |
wp_register_script( 'rwmb-time', RWMB_JS_URL . 'time.js', array( 'jquery-ui-timepicker-i18n' ), RWMB_VER, true );
|
73 |
|
74 |
$handles = array( 'datetime', 'time' );
|
inc/fields/key-value.php
CHANGED
@@ -124,9 +124,10 @@ class RWMB_Key_Value_Field extends RWMB_Text_Field {
|
|
124 |
* @return array
|
125 |
*/
|
126 |
public static function normalize( $field ) {
|
127 |
-
$field = parent::normalize( $field );
|
128 |
$field['clone'] = true;
|
129 |
$field['multiple'] = true;
|
|
|
|
|
130 |
$field['attributes']['type'] = 'text';
|
131 |
$field['placeholder'] = wp_parse_args(
|
132 |
(array) $field['placeholder'],
|
124 |
* @return array
|
125 |
*/
|
126 |
public static function normalize( $field ) {
|
|
|
127 |
$field['clone'] = true;
|
128 |
$field['multiple'] = true;
|
129 |
+
$field = parent::normalize( $field );
|
130 |
+
|
131 |
$field['attributes']['type'] = 'text';
|
132 |
$field['placeholder'] = wp_parse_args(
|
133 |
(array) $field['placeholder'],
|
inc/fields/taxonomy-advanced.php
CHANGED
@@ -34,26 +34,8 @@ class RWMB_Taxonomy_Advanced_Field extends RWMB_Taxonomy_Field {
|
|
34 |
* @param array $field The field parameters.
|
35 |
*/
|
36 |
public static function save( $new, $old, $post_id, $field ) {
|
37 |
-
|
38 |
-
|
39 |
-
}
|
40 |
-
$storage = $field['storage'];
|
41 |
-
|
42 |
-
if ( ! $new ) {
|
43 |
-
$storage->delete( $post_id, $field['id'] );
|
44 |
-
return;
|
45 |
-
}
|
46 |
-
|
47 |
-
if ( ! $field['clone'] || ! $field['clone_as_multiple'] ) {
|
48 |
-
$storage->update( $post_id, $field['id'], $new );
|
49 |
-
return;
|
50 |
-
}
|
51 |
-
|
52 |
-
// clone and clone_as_multiple.
|
53 |
-
$storage->delete( $post_id, $field['id'] );
|
54 |
-
foreach ( $new as $value ) {
|
55 |
-
$storage->add( $post_id, $field['id'], $value );
|
56 |
-
}
|
57 |
}
|
58 |
|
59 |
/**
|
34 |
* @param array $field The field parameters.
|
35 |
*/
|
36 |
public static function save( $new, $old, $post_id, $field ) {
|
37 |
+
$field['multiple'] = false; // Force to save in 1 row in the database.
|
38 |
+
RWMB_Field::save( $new, $old, $post_id, $field );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
}
|
40 |
|
41 |
/**
|
inc/loader.php
CHANGED
@@ -18,7 +18,7 @@ class RWMB_Loader {
|
|
18 |
*/
|
19 |
protected function constants() {
|
20 |
// Script version, used to add version for scripts and styles.
|
21 |
-
define( 'RWMB_VER', '5.0
|
22 |
|
23 |
list( $path, $url ) = self::get_path( dirname( dirname( __FILE__ ) ) );
|
24 |
|
@@ -96,8 +96,8 @@ class RWMB_Loader {
|
|
96 |
// Validation module.
|
97 |
new RWMB_Validation();
|
98 |
|
99 |
-
$
|
100 |
-
$
|
101 |
|
102 |
$media_modal = new RWMB_Media_Modal();
|
103 |
$media_modal->init();
|
@@ -107,10 +107,13 @@ class RWMB_Loader {
|
|
107 |
$wpml->init();
|
108 |
|
109 |
// Update.
|
110 |
-
$
|
|
|
111 |
$update_checker->init();
|
112 |
-
$update_settings = new RWMB_Update_Settings( $update_checker );
|
113 |
$update_settings->init();
|
|
|
|
|
114 |
|
115 |
// Public functions.
|
116 |
require_once RWMB_INC_DIR . 'functions.php';
|
18 |
*/
|
19 |
protected function constants() {
|
20 |
// Script version, used to add version for scripts and styles.
|
21 |
+
define( 'RWMB_VER', '5.1.0' );
|
22 |
|
23 |
list( $path, $url ) = self::get_path( dirname( dirname( __FILE__ ) ) );
|
24 |
|
96 |
// Validation module.
|
97 |
new RWMB_Validation();
|
98 |
|
99 |
+
$sanitizer = new RWMB_Sanitizer();
|
100 |
+
$sanitizer->init();
|
101 |
|
102 |
$media_modal = new RWMB_Media_Modal();
|
103 |
$media_modal->init();
|
107 |
$wpml->init();
|
108 |
|
109 |
// Update.
|
110 |
+
$update_option = new RWMB_Update_Option();
|
111 |
+
$update_checker = new RWMB_Update_Checker( $update_option );
|
112 |
$update_checker->init();
|
113 |
+
$update_settings = new RWMB_Update_Settings( $update_checker, $update_option );
|
114 |
$update_settings->init();
|
115 |
+
$update_notification = new RWMB_Update_Notification( $update_checker, $update_option );
|
116 |
+
$update_notification->init();
|
117 |
|
118 |
// Public functions.
|
119 |
require_once RWMB_INC_DIR . 'functions.php';
|
inc/media-modal.php
CHANGED
@@ -81,17 +81,9 @@ class RWMB_Media_Modal {
|
|
81 |
foreach ( $this->fields as $field ) {
|
82 |
$key = $field['id'];
|
83 |
|
84 |
-
$old = RWMB_Field::call( $field, 'raw_meta', $post['ID'] );
|
85 |
$new = isset( $attachment[ $key ] ) ? $attachment[ $key ] : '';
|
86 |
|
87 |
-
|
88 |
-
if ( $field['clone'] ) {
|
89 |
-
$new = RWMB_Clone::value( $new, $old, $post['ID'], $field );
|
90 |
-
} else {
|
91 |
-
$new = RWMB_Field::call( $field, 'value', $new, $old, $post['ID'] );
|
92 |
-
$new = RWMB_Field::filter( 'sanitize', $new, $field );
|
93 |
-
}
|
94 |
-
$new = RWMB_Field::filter( 'value', $new, $field, $old );
|
95 |
|
96 |
// Call defined method to save meta value, if there's no methods, call common one.
|
97 |
RWMB_Field::call( $field, 'save', $new, $old, $post['ID'] );
|
81 |
foreach ( $this->fields as $field ) {
|
82 |
$key = $field['id'];
|
83 |
|
|
|
84 |
$new = isset( $attachment[ $key ] ) ? $attachment[ $key ] : '';
|
85 |
|
86 |
+
$new = RWMB_Field::process_value( $new, $post['ID'], $field );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
87 |
|
88 |
// Call defined method to save meta value, if there's no methods, call common one.
|
89 |
RWMB_Field::call( $field, 'save', $new, $old, $post['ID'] );
|
inc/meta-box.php
CHANGED
@@ -303,15 +303,7 @@ class RW_Meta_Box {
|
|
303 |
$old = RWMB_Field::call( $field, 'raw_meta', $this->object_id );
|
304 |
// @codingStandardsIgnoreLine
|
305 |
$new = isset( $_POST[ $field['id'] ] ) ? $_POST[ $field['id'] ] : ( $single ? '' : array() );
|
306 |
-
|
307 |
-
// Allow field class change the value.
|
308 |
-
if ( $field['clone'] ) {
|
309 |
-
$new = RWMB_Clone::value( $new, $old, $this->object_id, $field );
|
310 |
-
} else {
|
311 |
-
$new = RWMB_Field::call( $field, 'value', $new, $old, $this->object_id );
|
312 |
-
$new = RWMB_Field::filter( 'sanitize', $new, $field );
|
313 |
-
}
|
314 |
-
$new = RWMB_Field::filter( 'value', $new, $field, $old );
|
315 |
|
316 |
// Filter to allow the field to be modified.
|
317 |
$field = RWMB_Field::filter( 'field', $field, $field, $new, $old );
|
303 |
$old = RWMB_Field::call( $field, 'raw_meta', $this->object_id );
|
304 |
// @codingStandardsIgnoreLine
|
305 |
$new = isset( $_POST[ $field['id'] ] ) ? $_POST[ $field['id'] ] : ( $single ? '' : array() );
|
306 |
+
$new = RWMB_Field::process_value( $new, $this->object_id, $field );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
307 |
|
308 |
// Filter to allow the field to be modified.
|
309 |
$field = RWMB_Field::filter( 'field', $field, $field, $new, $old );
|
inc/sanitizer.php
CHANGED
@@ -9,34 +9,94 @@
|
|
9 |
* Sanitize class.
|
10 |
*/
|
11 |
class RWMB_Sanitizer {
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
|
13 |
/**
|
14 |
-
*
|
15 |
*
|
16 |
-
* @
|
|
|
|
|
|
|
17 |
*/
|
18 |
-
|
19 |
-
|
20 |
-
'
|
21 |
-
|
22 |
-
|
23 |
-
|
|
|
|
|
|
|
|
|
24 |
|
25 |
/**
|
26 |
-
*
|
|
|
|
|
|
|
27 |
*/
|
28 |
-
|
29 |
-
//
|
30 |
-
|
31 |
-
|
32 |
}
|
33 |
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
}
|
41 |
|
42 |
/**
|
@@ -47,18 +107,162 @@ class RWMB_Sanitizer {
|
|
47 |
* @param string $value Checkbox value.
|
48 |
* @return int
|
49 |
*/
|
50 |
-
|
51 |
return (int) ! empty( $value );
|
52 |
}
|
53 |
|
54 |
/**
|
55 |
-
*
|
56 |
-
* This prevents using default value once the switch has been unchecked.
|
57 |
*
|
58 |
-
* @param
|
59 |
-
* @return int
|
60 |
*/
|
61 |
-
|
62 |
-
return (
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
}
|
64 |
}
|
9 |
* Sanitize class.
|
10 |
*/
|
11 |
class RWMB_Sanitizer {
|
12 |
+
/**
|
13 |
+
* Register hook to sanitize field value.
|
14 |
+
*/
|
15 |
+
public function init() {
|
16 |
+
add_filter( 'rwmb_sanitize', array( $this, 'sanitize' ), 10, 4 );
|
17 |
+
}
|
18 |
|
19 |
/**
|
20 |
+
* Sanitize a field value.
|
21 |
*
|
22 |
+
* @param mixed $value The submitted new value.
|
23 |
+
* @param array $field The field settings.
|
24 |
+
* @param mixed $old_value The old field value in the database.
|
25 |
+
* @param int $object_id The object ID.
|
26 |
*/
|
27 |
+
public function sanitize( $value, $field, $old_value, $object_id ) {
|
28 |
+
// Allow developers to bypass the sanitization.
|
29 |
+
if ( 'none' === $field['sanitize_callback'] ) {
|
30 |
+
return $value;
|
31 |
+
}
|
32 |
+
|
33 |
+
$callback = $this->get_callback( $field );
|
34 |
+
|
35 |
+
return is_callable( $callback ) ? call_user_func( $callback, $value, $field, $old_value, $object_id ) : $value;
|
36 |
+
}
|
37 |
|
38 |
/**
|
39 |
+
* Get sanitize callback for a field.
|
40 |
+
*
|
41 |
+
* @param array $field Field settings.
|
42 |
+
* @return callable
|
43 |
*/
|
44 |
+
private function get_callback( $field ) {
|
45 |
+
// User-defined callback.
|
46 |
+
if ( is_callable( $field['sanitize_callback'] ) ) {
|
47 |
+
return $field['sanitize_callback'];
|
48 |
}
|
49 |
|
50 |
+
$callbacks = array(
|
51 |
+
'autocomplete' => array( $this, 'sanitize_choice' ),
|
52 |
+
'background' => array( $this, 'sanitize_background' ),
|
53 |
+
'button_group' => array( $this, 'sanitize_choice' ),
|
54 |
+
'checkbox' => array( $this, 'sanitize_checkbox' ),
|
55 |
+
'checkbox_list' => array( $this, 'sanitize_choice' ),
|
56 |
+
'color' => array( $this, 'sanitize_color' ),
|
57 |
+
'date' => array( $this, 'sanitize_datetime' ),
|
58 |
+
'datetime' => array( $this, 'sanitize_datetime' ),
|
59 |
+
'email' => 'sanitize_email',
|
60 |
+
'fieldset_text' => array( $this, 'sanitize_text' ),
|
61 |
+
'file' => array( $this, 'sanitize_file' ),
|
62 |
+
'file_advanced' => array( $this, 'sanitize_object' ),
|
63 |
+
'file_input' => 'esc_url_raw',
|
64 |
+
'file_upload' => array( $this, 'sanitize_object' ),
|
65 |
+
'hidden' => 'sanitize_text_field',
|
66 |
+
'image' => array( $this, 'sanitize_file' ),
|
67 |
+
'image_advanced' => array( $this, 'sanitize_object' ),
|
68 |
+
'image_select' => array( $this, 'sanitize_choice' ),
|
69 |
+
'image_upload' => array( $this, 'sanitize_object' ),
|
70 |
+
'key_value' => array( $this, 'sanitize_text' ),
|
71 |
+
'map' => array( $this, 'sanitize_map' ),
|
72 |
+
'number' => array( $this, 'sanitize_number' ),
|
73 |
+
'oembed' => 'esc_url_raw',
|
74 |
+
'osm' => array( $this, 'sanitize_map' ),
|
75 |
+
'password' => 'sanitize_text_field',
|
76 |
+
'post' => array( $this, 'sanitize_object' ),
|
77 |
+
'radio' => array( $this, 'sanitize_choice' ),
|
78 |
+
'range' => array( $this, 'sanitize_number' ),
|
79 |
+
'select' => array( $this, 'sanitize_choice' ),
|
80 |
+
'select_advanced' => array( $this, 'sanitize_choice' ),
|
81 |
+
'sidebar' => array( $this, 'sanitize_text' ),
|
82 |
+
'single_image' => 'absint',
|
83 |
+
'slider' => array( $this, 'sanitize_slider' ),
|
84 |
+
'switch' => array( $this, 'sanitize_checkbox' ),
|
85 |
+
'taxonomy' => array( $this, 'sanitize_object' ),
|
86 |
+
'taxonomy_advanced' => array( $this, 'sanitize_taxonomy_advanced' ),
|
87 |
+
'text' => 'sanitize_text_field',
|
88 |
+
'text_list' => array( $this, 'sanitize_text' ),
|
89 |
+
'textarea' => 'wp_kses_post',
|
90 |
+
'time' => 'sanitize_text_field',
|
91 |
+
'url' => 'esc_url_raw',
|
92 |
+
'user' => array( $this, 'sanitize_object' ),
|
93 |
+
'video' => array( $this, 'sanitize_object' ),
|
94 |
+
'wysiwyg' => 'wp_kses_post',
|
95 |
+
);
|
96 |
+
|
97 |
+
$type = $field['type'];
|
98 |
+
|
99 |
+
return isset( $callbacks[ $type ] ) ? $callbacks[ $type ] : null;
|
100 |
}
|
101 |
|
102 |
/**
|
107 |
* @param string $value Checkbox value.
|
108 |
* @return int
|
109 |
*/
|
110 |
+
private function sanitize_checkbox( $value ) {
|
111 |
return (int) ! empty( $value );
|
112 |
}
|
113 |
|
114 |
/**
|
115 |
+
* Sanitize numeric value.
|
|
|
116 |
*
|
117 |
+
* @param int|float $value The number value.
|
118 |
+
* @return int|float
|
119 |
*/
|
120 |
+
private function sanitize_number( $value ) {
|
121 |
+
return is_numeric( $value ) ? $value : 0;
|
122 |
+
}
|
123 |
+
|
124 |
+
/**
|
125 |
+
* Sanitize color value.
|
126 |
+
*
|
127 |
+
* @param string $value The color value.
|
128 |
+
* @return string
|
129 |
+
*/
|
130 |
+
private function sanitize_color( $value ) {
|
131 |
+
if ( false === strpos( $value, 'rgba' ) ) {
|
132 |
+
return sanitize_hex_color( $value );
|
133 |
+
}
|
134 |
+
|
135 |
+
// rgba value.
|
136 |
+
$red = '';
|
137 |
+
$green = '';
|
138 |
+
$blue = '';
|
139 |
+
$alpha = '';
|
140 |
+
sscanf( $value, 'rgba(%d,%d,%d,%f)', $red, $green, $blue, $alpha );
|
141 |
+
|
142 |
+
return 'rgba(' . $red . ',' . $green . ',' . $blue . ',' . $alpha . ')';
|
143 |
+
}
|
144 |
+
|
145 |
+
/**
|
146 |
+
* Sanitize value for a choice field.
|
147 |
+
*
|
148 |
+
* @param string|array $value The submitted value.
|
149 |
+
* @param array $field The field settings.
|
150 |
+
* @return string|array
|
151 |
+
*/
|
152 |
+
private function sanitize_choice( $value, $field ) {
|
153 |
+
$options = $field['options'];
|
154 |
+
return is_array( $value ) ? array_intersect( $value, array_keys( $options ) ) : ( isset( $options[ $value ] ) ? $value : '' );
|
155 |
+
}
|
156 |
+
|
157 |
+
/**
|
158 |
+
* Sanitize object & media field.
|
159 |
+
*
|
160 |
+
* @param int|array $value The submitted value.
|
161 |
+
* @return int|array
|
162 |
+
*/
|
163 |
+
private function sanitize_object( $value ) {
|
164 |
+
return is_array( $value ) ? array_map( 'absint', $value ) : absint( $value );
|
165 |
+
}
|
166 |
+
|
167 |
+
/**
|
168 |
+
* Sanitize background field.
|
169 |
+
*
|
170 |
+
* @param array $value The submitted value.
|
171 |
+
* @return array
|
172 |
+
*/
|
173 |
+
private function sanitize_background( $value ) {
|
174 |
+
$value = wp_parse_args(
|
175 |
+
$value,
|
176 |
+
array(
|
177 |
+
'color' => '',
|
178 |
+
'image' => '',
|
179 |
+
'repeat' => '',
|
180 |
+
'attachment' => '',
|
181 |
+
'position' => '',
|
182 |
+
'size' => '',
|
183 |
+
)
|
184 |
+
);
|
185 |
+
$value['color'] = $this->sanitize_color( $value['color'] );
|
186 |
+
$value['image'] = esc_url_raw( $value['image'] );
|
187 |
+
|
188 |
+
$value['repeat'] = in_array( $value['repeat'], array( 'no-repeat', 'repeat', 'repeat-x', 'repeat-y', 'inherit' ), true ) ? $value['repeat'] : '';
|
189 |
+
$value['position'] = in_array( $value['repeat'], array( 'top left', 'top center', 'top right', 'center left', 'center center', 'center right', 'bottom left', 'bottom center', 'bottom right' ), true ) ? $value['position'] : '';
|
190 |
+
$value['attachment'] = in_array( $value['repeat'], array( 'fixed', 'scroll', 'inherit' ), true ) ? $value['attachment'] : '';
|
191 |
+
$value['size'] = in_array( $value['repeat'], array( 'inherit', 'cover', 'contain' ), true ) ? $value['attachment'] : '';
|
192 |
+
|
193 |
+
return $value;
|
194 |
+
}
|
195 |
+
|
196 |
+
/**
|
197 |
+
* Sanitize text field.
|
198 |
+
*
|
199 |
+
* @param string|array $value The submitted value.
|
200 |
+
* @return string|array
|
201 |
+
*/
|
202 |
+
private function sanitize_text( $value ) {
|
203 |
+
return is_array( $value ) ? array_map( __METHOD__, $value ) : sanitize_text_field( $value );
|
204 |
+
}
|
205 |
+
|
206 |
+
/**
|
207 |
+
* Sanitize file, image field.
|
208 |
+
*
|
209 |
+
* @param array $value The submitted value.
|
210 |
+
* @param array $field The field settings.
|
211 |
+
* @return array
|
212 |
+
*/
|
213 |
+
private function sanitize_file( $value, $field ) {
|
214 |
+
return $field['upload_dir'] ? array_map( 'esc_url_raw', $value ) : array_map( 'absint', $value );
|
215 |
+
}
|
216 |
+
|
217 |
+
/**
|
218 |
+
* Sanitize slider field.
|
219 |
+
*
|
220 |
+
* @param mixed $value The submitted value.
|
221 |
+
* @param array $field The field settings.
|
222 |
+
* @return string|int|float
|
223 |
+
*/
|
224 |
+
private function sanitize_slider( $value, $field ) {
|
225 |
+
return true === $field['js_options']['range'] ? sanitize_text_field( $value ) : $this->sanitize_number( $value );
|
226 |
+
}
|
227 |
+
|
228 |
+
/**
|
229 |
+
* Sanitize datetime field.
|
230 |
+
*
|
231 |
+
* @param mixed $value The submitted value.
|
232 |
+
* @param array $field The field settings.
|
233 |
+
* @return float|string
|
234 |
+
*/
|
235 |
+
private function sanitize_datetime( $value, $field ) {
|
236 |
+
return $field['timestamp'] ? floor( abs( (float) $value ) ) : sanitize_text_field( $value );
|
237 |
+
}
|
238 |
+
|
239 |
+
/**
|
240 |
+
* Sanitize map field.
|
241 |
+
*
|
242 |
+
* @param mixed $value The submitted value.
|
243 |
+
* @return string
|
244 |
+
*/
|
245 |
+
private function sanitize_map( $value ) {
|
246 |
+
$value = sanitize_text_field( $value );
|
247 |
+
list( $latitude, $longitude, $zoom ) = explode( ',', $value . ',,' );
|
248 |
+
|
249 |
+
$latitude = (float) $latitude;
|
250 |
+
$longitude = (float) $longitude;
|
251 |
+
$zoom = (int) $zoom;
|
252 |
+
|
253 |
+
return "$latitude,$longitude,$zoom";
|
254 |
+
}
|
255 |
+
|
256 |
+
/**
|
257 |
+
* Sanitize taxonomy advanced field.
|
258 |
+
*
|
259 |
+
* @param mixed $value The submitted value.
|
260 |
+
* @return string
|
261 |
+
*/
|
262 |
+
private function sanitize_taxonomy_advanced( $value ) {
|
263 |
+
$value = RWMB_Helpers_Array::from_csv( $value );
|
264 |
+
$value = array_map( 'absint', $value );
|
265 |
+
|
266 |
+
return implode( ',', $value );
|
267 |
}
|
268 |
}
|
inc/update/checker.php
CHANGED
@@ -6,7 +6,7 @@
|
|
6 |
*/
|
7 |
|
8 |
/**
|
9 |
-
* The
|
10 |
*
|
11 |
* @package Meta Box
|
12 |
*/
|
@@ -19,11 +19,20 @@ class RWMB_Update_Checker {
|
|
19 |
private $api_url = 'https://metabox.io/index.php';
|
20 |
|
21 |
/**
|
22 |
-
* The update option.
|
23 |
*
|
24 |
-
* @var
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
*/
|
26 |
-
|
|
|
|
|
27 |
|
28 |
/**
|
29 |
* Add hooks to check plugin updates.
|
@@ -48,6 +57,16 @@ class RWMB_Update_Checker {
|
|
48 |
* @return bool
|
49 |
*/
|
50 |
public function has_extensions() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
if ( ! function_exists( 'get_plugins' ) ) {
|
52 |
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
53 |
}
|
@@ -76,9 +95,7 @@ class RWMB_Update_Checker {
|
|
76 |
$plugins = get_plugins();
|
77 |
$plugins = array_map( 'dirname', array_keys( $plugins ) );
|
78 |
|
79 |
-
|
80 |
-
|
81 |
-
return ! empty( $installed_extensions );
|
82 |
}
|
83 |
|
84 |
/**
|
@@ -89,14 +106,14 @@ class RWMB_Update_Checker {
|
|
89 |
* @return mixed
|
90 |
*/
|
91 |
public function check_updates( $data ) {
|
92 |
-
static $
|
93 |
|
94 |
// Make sure to send remote request once.
|
95 |
-
if ( null === $
|
96 |
-
$
|
97 |
}
|
98 |
|
99 |
-
if ( false === $
|
100 |
return $data;
|
101 |
}
|
102 |
|
@@ -104,18 +121,21 @@ class RWMB_Update_Checker {
|
|
104 |
$data->response = array();
|
105 |
}
|
106 |
|
107 |
-
$plugins = array_filter( $
|
108 |
foreach ( $plugins as $plugin ) {
|
|
|
|
|
|
|
|
|
109 |
$data->response[ $plugin->plugin ] = $plugin;
|
110 |
}
|
111 |
|
112 |
-
$
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
}
|
119 |
|
120 |
return $data;
|
121 |
}
|
@@ -130,20 +150,19 @@ class RWMB_Update_Checker {
|
|
130 |
* @return mixed
|
131 |
*/
|
132 |
public function get_info( $data, $action, $args ) {
|
133 |
-
$
|
134 |
-
$plugins = isset( $option['plugins'] ) ? $option['plugins'] : array();
|
135 |
if ( 'plugin_information' !== $action || ! isset( $args->slug ) || ! in_array( $args->slug, $plugins, true ) ) {
|
136 |
return $data;
|
137 |
}
|
138 |
|
139 |
-
$
|
140 |
array(
|
141 |
'action' => 'get_info',
|
142 |
'product' => $args->slug,
|
143 |
)
|
144 |
);
|
145 |
|
146 |
-
return false === $
|
147 |
}
|
148 |
|
149 |
/**
|
@@ -154,10 +173,13 @@ class RWMB_Update_Checker {
|
|
154 |
* @return mixed
|
155 |
*/
|
156 |
public function request( $args = '' ) {
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
|
|
|
|
|
|
161 |
|
162 |
$request = wp_remote_post(
|
163 |
$this->api_url,
|
@@ -167,13 +189,7 @@ class RWMB_Update_Checker {
|
|
167 |
);
|
168 |
|
169 |
$response = wp_remote_retrieve_body( $request );
|
170 |
-
|
171 |
-
$data = @unserialize( $response );
|
172 |
-
|
173 |
-
return $data;
|
174 |
-
}
|
175 |
-
|
176 |
-
return false;
|
177 |
}
|
178 |
|
179 |
/**
|
@@ -190,11 +206,11 @@ class RWMB_Update_Checker {
|
|
190 |
}
|
191 |
|
192 |
/**
|
193 |
-
* Get
|
194 |
*
|
195 |
-
* @return
|
196 |
*/
|
197 |
-
|
198 |
-
return
|
199 |
}
|
200 |
}
|
6 |
*/
|
7 |
|
8 |
/**
|
9 |
+
* The update checker class for Meta Box extensions
|
10 |
*
|
11 |
* @package Meta Box
|
12 |
*/
|
19 |
private $api_url = 'https://metabox.io/index.php';
|
20 |
|
21 |
/**
|
22 |
+
* The update option object.
|
23 |
*
|
24 |
+
* @var object
|
25 |
+
*/
|
26 |
+
private $option;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Constructor.
|
30 |
+
*
|
31 |
+
* @param object $option Update option object.
|
32 |
*/
|
33 |
+
public function __construct( $option ) {
|
34 |
+
$this->option = $option;
|
35 |
+
}
|
36 |
|
37 |
/**
|
38 |
* Add hooks to check plugin updates.
|
57 |
* @return bool
|
58 |
*/
|
59 |
public function has_extensions() {
|
60 |
+
$extensions = $this->get_extensions();
|
61 |
+
return ! empty( $extensions );
|
62 |
+
}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Get installed premium extensions.
|
66 |
+
*
|
67 |
+
* @return array Array of extension slugs.
|
68 |
+
*/
|
69 |
+
public function get_extensions() {
|
70 |
if ( ! function_exists( 'get_plugins' ) ) {
|
71 |
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
72 |
}
|
95 |
$plugins = get_plugins();
|
96 |
$plugins = array_map( 'dirname', array_keys( $plugins ) );
|
97 |
|
98 |
+
return array_intersect( $extensions, $plugins );
|
|
|
|
|
99 |
}
|
100 |
|
101 |
/**
|
106 |
* @return mixed
|
107 |
*/
|
108 |
public function check_updates( $data ) {
|
109 |
+
static $response = null;
|
110 |
|
111 |
// Make sure to send remote request once.
|
112 |
+
if ( null === $response ) {
|
113 |
+
$response = $this->request( array( 'action' => 'check_updates' ) );
|
114 |
}
|
115 |
|
116 |
+
if ( false === $response ) {
|
117 |
return $data;
|
118 |
}
|
119 |
|
121 |
$data->response = array();
|
122 |
}
|
123 |
|
124 |
+
$plugins = array_filter( $response['data'], array( $this, 'has_update' ) );
|
125 |
foreach ( $plugins as $plugin ) {
|
126 |
+
if ( empty( $plugin->package ) ) {
|
127 |
+
$plugin->upgrade_notice = __( 'UPDATE UNAVAILABLE! Please enter a valid license key to enable automatic updates.', 'meta-box' );
|
128 |
+
}
|
129 |
+
|
130 |
$data->response[ $plugin->plugin ] = $plugin;
|
131 |
}
|
132 |
|
133 |
+
$this->option->update(
|
134 |
+
array(
|
135 |
+
'status' => $response['status'],
|
136 |
+
'plugins' => array_keys( $plugins ),
|
137 |
+
)
|
138 |
+
);
|
|
|
139 |
|
140 |
return $data;
|
141 |
}
|
150 |
* @return mixed
|
151 |
*/
|
152 |
public function get_info( $data, $action, $args ) {
|
153 |
+
$plugins = $this->option->get( 'plugins', array() );
|
|
|
154 |
if ( 'plugin_information' !== $action || ! isset( $args->slug ) || ! in_array( $args->slug, $plugins, true ) ) {
|
155 |
return $data;
|
156 |
}
|
157 |
|
158 |
+
$response = $this->request(
|
159 |
array(
|
160 |
'action' => 'get_info',
|
161 |
'product' => $args->slug,
|
162 |
)
|
163 |
);
|
164 |
|
165 |
+
return false === $response ? $data : $response['data'];
|
166 |
}
|
167 |
|
168 |
/**
|
173 |
* @return mixed
|
174 |
*/
|
175 |
public function request( $args = '' ) {
|
176 |
+
$args = wp_parse_args(
|
177 |
+
$args,
|
178 |
+
array(
|
179 |
+
'api_key' => $this->get_api_key(),
|
180 |
+
)
|
181 |
+
);
|
182 |
+
$args = array_filter( $args );
|
183 |
|
184 |
$request = wp_remote_post(
|
185 |
$this->api_url,
|
189 |
);
|
190 |
|
191 |
$response = wp_remote_retrieve_body( $request );
|
192 |
+
return $response ? @unserialize( $response ) : false;
|
|
|
|
|
|
|
|
|
|
|
|
|
193 |
}
|
194 |
|
195 |
/**
|
206 |
}
|
207 |
|
208 |
/**
|
209 |
+
* Get the API key.
|
210 |
*
|
211 |
+
* @return string
|
212 |
*/
|
213 |
+
public function get_api_key() {
|
214 |
+
return defined( 'META_BOX_KEY' ) ? META_BOX_KEY : $this->option->get( 'api_key' );
|
215 |
}
|
216 |
}
|
inc/update/notification.php
ADDED
@@ -0,0 +1,195 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* This class notifies users to enter or update license key.
|
4 |
+
*
|
5 |
+
* @package Meta Box
|
6 |
+
*/
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Meta Box Update Notification class
|
10 |
+
*
|
11 |
+
* @package Meta Box
|
12 |
+
*/
|
13 |
+
class RWMB_Update_Notification {
|
14 |
+
/**
|
15 |
+
* The update option object.
|
16 |
+
*
|
17 |
+
* @var object
|
18 |
+
*/
|
19 |
+
private $option;
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Settings page URL.
|
23 |
+
*
|
24 |
+
* @var string
|
25 |
+
*/
|
26 |
+
private $settings_page;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* The update checker object.
|
30 |
+
*
|
31 |
+
* @var object
|
32 |
+
*/
|
33 |
+
private $checker;
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Constructor.
|
37 |
+
*
|
38 |
+
* @param object $checker Update checker object.
|
39 |
+
* @param object $option Update option object.
|
40 |
+
*/
|
41 |
+
public function __construct( $checker, $option ) {
|
42 |
+
$this->checker = $checker;
|
43 |
+
$this->option = $option;
|
44 |
+
|
45 |
+
$this->settings_page = is_multisite() ? network_admin_url( 'settings.php?page=meta-box-updater' ) : admin_url( 'admin.php?page=meta-box-updater' );
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Add hooks to show admin notice.
|
50 |
+
*/
|
51 |
+
public function init() {
|
52 |
+
if ( ! $this->checker->has_extensions() ) {
|
53 |
+
return;
|
54 |
+
}
|
55 |
+
|
56 |
+
// Show update message on Plugins page.
|
57 |
+
$extensions = $this->checker->get_extensions();
|
58 |
+
foreach ( $extensions as $extension ) {
|
59 |
+
$file = "{$extension}/{$extension}.php";
|
60 |
+
add_action( "in_plugin_update_message-$file", array( $this, 'show_update_message' ), 10, 2 );
|
61 |
+
add_filter( "plugin_action_links_$file", array( $this, 'plugin_links' ), 20 );
|
62 |
+
}
|
63 |
+
|
64 |
+
// Show global update notification.
|
65 |
+
if ( $this->is_dismissed() ) {
|
66 |
+
return;
|
67 |
+
}
|
68 |
+
|
69 |
+
$admin_notices_hook = is_multisite() ? 'network_admin_notices' : 'admin_notices';
|
70 |
+
add_action( $admin_notices_hook, array( $this, 'notify' ) );
|
71 |
+
|
72 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue' ) );
|
73 |
+
add_action( 'wp_ajax_mb_dismiss_notification', array( $this, 'dismiss' ) );
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Enqueue the notification script.
|
78 |
+
*/
|
79 |
+
public function enqueue() {
|
80 |
+
wp_enqueue_script( 'mb-notification', RWMB_JS_URL . 'notification.js', array( 'jquery' ), RWMB_VER, true );
|
81 |
+
wp_localize_script( 'mb-notification', 'MBNotification', array( 'nonce' => wp_create_nonce( 'dismiss' ) ) );
|
82 |
+
}
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Dismiss the notification permanently via ajax.
|
86 |
+
*/
|
87 |
+
public function dismiss() {
|
88 |
+
check_ajax_referer( 'dismiss', 'nonce' );
|
89 |
+
|
90 |
+
$this->option->update(
|
91 |
+
array(
|
92 |
+
'notification_dismissed' => 1,
|
93 |
+
'notification_dismissed_time' => time(),
|
94 |
+
)
|
95 |
+
);
|
96 |
+
|
97 |
+
wp_send_json_success();
|
98 |
+
}
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Notify users to enter license key.
|
102 |
+
*/
|
103 |
+
public function notify() {
|
104 |
+
// Do not show notification on License page.
|
105 |
+
$screen = get_current_screen();
|
106 |
+
if ( 'meta-box_page_meta-box-updater' === $screen->id ) {
|
107 |
+
return;
|
108 |
+
}
|
109 |
+
|
110 |
+
$messages = array(
|
111 |
+
// Translators: %1$s - URL to the settings page, %2$s - URL to the pricing page.
|
112 |
+
'no_key' => __( 'You have not set your Meta Box license key yet, which means you are missing out on automatic updates and support! Please <a href="%1$s">enter your license key</a> or <a href="%2$s" target="_blank">get a new one here</a>.', 'meta-box' ),
|
113 |
+
// Translators: %1$s - URL to the settings page, %2$s - URL to the pricing page.
|
114 |
+
'invalid' => __( 'Your license key for Meta Box is <b>invalid</b>. Please <a href="%1$s">update your license key</a> or <a href="%2$s" target="_blank">get a new one</a> to enable automatic updates.', 'meta-box' ),
|
115 |
+
// Translators: %1$s - URL to the settings page, %2$s - URL to the pricing page.
|
116 |
+
'error' => __( 'Your license key for Meta Box is <b>invalid</b>. Please <a href="%1$s">update your license key</a> or <a href="%2$s" target="_blank">get a new one</a> to enable automatic updates.', 'meta-box' ),
|
117 |
+
// Translators: %3$s - URL to the My Account page.
|
118 |
+
'expired' => __( 'Your license key for Meta Box is <b>expired</b>. Please <a href="%3$s" target="_blank">renew your license</a> to get automatic updates and premium support.', 'meta-box' ),
|
119 |
+
);
|
120 |
+
$status = $this->get_license_status();
|
121 |
+
if ( ! isset( $messages[ $status ] ) ) {
|
122 |
+
return;
|
123 |
+
}
|
124 |
+
|
125 |
+
echo '<div id="meta-box-notification" class="notice notice-warning is-dismissible"><p><span class="dashicons dashicons-warning" style="color: #f56e28"></span> ', wp_kses_post( sprintf( $messages[ $status ], $this->settings_page, 'https://metabox.io/pricing/', 'https://metabox.io/my-account/' ) ), '</p></div>';
|
126 |
+
}
|
127 |
+
|
128 |
+
/**
|
129 |
+
* Show update message on Plugins page.
|
130 |
+
*
|
131 |
+
* @param array $plugin_data Plugin data.
|
132 |
+
* @param object $response Available plugin update data.
|
133 |
+
*/
|
134 |
+
public function show_update_message( $plugin_data, $response ) {
|
135 |
+
// Users have an active license.
|
136 |
+
if ( ! empty( $response->package ) ) {
|
137 |
+
return;
|
138 |
+
}
|
139 |
+
|
140 |
+
$messages = array(
|
141 |
+
// Translators: %1$s - URL to the settings page, %2$s - URL to the pricing page.
|
142 |
+
'no_key' => __( 'Please <a href="%1$s">enter your license key</a> or <a href="%2$s" target="_blank">get a new one here</a>.', 'meta-box' ),
|
143 |
+
// Translators: %1$s - URL to the settings page, %2$s - URL to the pricing page.
|
144 |
+
'invalid' => __( 'Your license key is <b>invalid</b>. Please <a href="%1$s">update your license key</a> or <a href="%2$s" target="_blank">get a new one here</a>.', 'meta-box' ),
|
145 |
+
// Translators: %1$s - URL to the settings page, %2$s - URL to the pricing page.
|
146 |
+
'error' => __( 'Your license key is <b>invalid</b>. Please <a href="%1$s">update your license key</a> or <a href="%2$s" target="_blank">get a new one here</a>.', 'meta-box' ),
|
147 |
+
// Translators: %3$s - URL to the My Account page.
|
148 |
+
'expired' => __( 'Your license key is <b>expired</b>. Please <a href="%3$s" target="_blank">renew your license</a>.', 'meta-box' ),
|
149 |
+
);
|
150 |
+
$status = $this->get_license_status();
|
151 |
+
if ( ! isset( $messages[ $status ] ) ) {
|
152 |
+
return;
|
153 |
+
}
|
154 |
+
|
155 |
+
echo '<br><span style="width: 26px; height: 20px; display: inline-block;"> </span>' . wp_kses_post( sprintf( $messages[ $status ], $this->settings_page, 'https://metabox.io/pricing/', 'https://metabox.io/my-account/' ) );
|
156 |
+
}
|
157 |
+
|
158 |
+
/**
|
159 |
+
* Add link for activate or update the license key.
|
160 |
+
*
|
161 |
+
* @param array $links Array of plugin links.
|
162 |
+
*
|
163 |
+
* @return array
|
164 |
+
*/
|
165 |
+
public function plugin_links( $links ) {
|
166 |
+
$status = $this->get_license_status();
|
167 |
+
if ( 'active' === $status ) {
|
168 |
+
return $links;
|
169 |
+
}
|
170 |
+
|
171 |
+
$text = 'no_key' === $status ? __( 'Activate License', 'meta-box' ) : __( 'Update License', 'meta-box' );
|
172 |
+
$links[] = '<a href="' . esc_url( $this->settings_page ) . '" style="color: #39b54a; font-weight: bold">' . esc_html( $text ) . '</a>';
|
173 |
+
|
174 |
+
return $links;
|
175 |
+
}
|
176 |
+
|
177 |
+
/**
|
178 |
+
* Get license status.
|
179 |
+
*/
|
180 |
+
private function get_license_status() {
|
181 |
+
return $this->checker->get_api_key() ? $this->option->get( 'status', 'active' ) : 'no_key';
|
182 |
+
}
|
183 |
+
|
184 |
+
/**
|
185 |
+
* Check if the global notification is dismissed.
|
186 |
+
* Auto re-enable the notification every 2 weeks after it's dissmissed.
|
187 |
+
*
|
188 |
+
* @return bool
|
189 |
+
*/
|
190 |
+
private function is_dismissed() {
|
191 |
+
$time = $this->option->get( 'notification_dismissed_time' );
|
192 |
+
|
193 |
+
return $this->option->get( 'notification_dismissed' ) && time() - $time < 14 * DAY_IN_SECONDS;
|
194 |
+
}
|
195 |
+
}
|
inc/update/option.php
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* This class handles getting and saving the updater option.
|
4 |
+
*
|
5 |
+
* @package Meta Box
|
6 |
+
*/
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Meta Box Update Option class
|
10 |
+
*
|
11 |
+
* @package Meta Box
|
12 |
+
*/
|
13 |
+
class RWMB_Update_Option {
|
14 |
+
/**
|
15 |
+
* Option name.
|
16 |
+
*
|
17 |
+
* @var string
|
18 |
+
*/
|
19 |
+
private $option = 'meta_box_updater';
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Get an option.
|
23 |
+
*
|
24 |
+
* @param string $name Option name. Pass null to return the option array.
|
25 |
+
* @param mixed $default Default value.
|
26 |
+
*
|
27 |
+
* @return mixed Option value or option array.
|
28 |
+
*/
|
29 |
+
public function get( $name = null, $default = null ) {
|
30 |
+
$option = is_multisite() ? get_site_option( $this->option, array() ) : get_option( $this->option, array() );
|
31 |
+
|
32 |
+
return null === $name ? $option : ( isset( $option[ $name ] ) ? $option[ $name ] : $default );
|
33 |
+
}
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Update the option array.
|
37 |
+
*
|
38 |
+
* @param array $option Option value.
|
39 |
+
*/
|
40 |
+
public function update( $option ) {
|
41 |
+
$old_option = (array) $this->get();
|
42 |
+
|
43 |
+
$option = array_merge( $old_option, $option );
|
44 |
+
if ( is_multisite() ) {
|
45 |
+
update_site_option( $this->option, $option );
|
46 |
+
} else {
|
47 |
+
update_option( $this->option, $option );
|
48 |
+
}
|
49 |
+
}
|
50 |
+
}
|
inc/update/settings.php
CHANGED
@@ -12,25 +12,11 @@
|
|
12 |
*/
|
13 |
class RWMB_Update_Settings {
|
14 |
/**
|
15 |
-
*
|
16 |
*
|
17 |
-
* @var
|
18 |
-
*/
|
19 |
-
private $option = 'meta_box_updater';
|
20 |
-
|
21 |
-
/**
|
22 |
-
* Settings page ID.
|
23 |
-
*
|
24 |
-
* @var string
|
25 |
-
*/
|
26 |
-
private $page_id = 'meta-box-updater';
|
27 |
-
|
28 |
-
/**
|
29 |
-
* Settings page hook.
|
30 |
-
*
|
31 |
-
* @var string
|
32 |
*/
|
33 |
-
private $
|
34 |
|
35 |
/**
|
36 |
* The update checker object
|
@@ -43,51 +29,53 @@ class RWMB_Update_Settings {
|
|
43 |
* Constructor.
|
44 |
*
|
45 |
* @param object $checker Update checker object.
|
|
|
46 |
*/
|
47 |
-
public function __construct( $checker ) {
|
48 |
$this->checker = $checker;
|
|
|
49 |
}
|
50 |
|
51 |
/**
|
52 |
-
* Add hooks to create the settings page
|
53 |
*/
|
54 |
public function init() {
|
55 |
// Whether to enable Meta Box menu. Priority 1 makes sure it runs before adding Meta Box menu.
|
56 |
add_action( 'admin_menu', array( $this, 'enable_menu' ), 1 );
|
57 |
-
|
58 |
-
// Add submenu. Use priority 80 to show it just above the About page (priority = 90).
|
59 |
-
$admin_menu_hook = is_multisite() ? 'network_admin_menu' : 'admin_menu';
|
60 |
-
add_action( $admin_menu_hook, array( $this, 'add_settings_page' ), 80 );
|
61 |
-
|
62 |
-
$admin_notices_hook = is_multisite() ? 'network_admin_notices' : 'admin_notices';
|
63 |
-
add_action( $admin_notices_hook, array( $this, 'notify' ) );
|
64 |
}
|
65 |
|
66 |
/**
|
67 |
-
*
|
68 |
*/
|
69 |
public function enable_menu() {
|
70 |
-
if ( $this->checker->has_extensions() ) {
|
71 |
-
|
72 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
}
|
74 |
|
75 |
/**
|
76 |
* Add settings page.
|
77 |
*/
|
78 |
public function add_settings_page() {
|
79 |
-
$parent
|
80 |
-
$capability
|
81 |
-
$title
|
82 |
-
$
|
83 |
$parent,
|
84 |
$title,
|
85 |
$title,
|
86 |
$capability,
|
87 |
-
|
88 |
array( $this, 'render' )
|
89 |
);
|
90 |
-
add_action( "load-{$
|
91 |
}
|
92 |
|
93 |
/**
|
@@ -96,34 +84,46 @@ class RWMB_Update_Settings {
|
|
96 |
public function render() {
|
97 |
?>
|
98 |
<div class="wrap">
|
99 |
-
<h1><?php esc_html_e( 'Meta Box License' ); ?></h1>
|
100 |
-
<p><?php esc_html_e( 'Please enter your license key to
|
101 |
<p>
|
102 |
<?php
|
103 |
printf(
|
104 |
-
// Translators: %s - URL to
|
105 |
-
wp_kses_post( __( 'To get the license key,
|
106 |
-
'https://metabox.io/my-account/'
|
|
|
107 |
);
|
108 |
?>
|
109 |
</p>
|
110 |
|
111 |
<form action="" method="post">
|
112 |
-
<?php wp_nonce_field( 'meta-box
|
113 |
-
|
114 |
-
<?php
|
115 |
-
$option = is_multisite() ? get_site_option( $this->option ) : get_option( $this->option );
|
116 |
-
$key = isset( $option['api_key'] ) ? $option['api_key'] : '';
|
117 |
-
?>
|
118 |
|
119 |
<table class="form-table">
|
120 |
<tr>
|
121 |
-
<th scope="row"><?php esc_html_e( 'License Key', 'meta-box
|
122 |
-
<td
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
123 |
</tr>
|
124 |
</table>
|
125 |
|
126 |
-
<?php submit_button( __( 'Save Changes', 'meta-box
|
127 |
</form>
|
128 |
</div>
|
129 |
<?php
|
@@ -133,79 +133,44 @@ class RWMB_Update_Settings {
|
|
133 |
* Save update settings.
|
134 |
*/
|
135 |
public function save() {
|
136 |
-
static $message_shown = false;
|
137 |
-
|
138 |
if ( empty( $_POST['submit'] ) ) {
|
139 |
return;
|
140 |
}
|
141 |
-
check_admin_referer( 'meta-box
|
142 |
|
143 |
// @codingStandardsIgnoreLine
|
144 |
-
$option = isset( $_POST[
|
145 |
$option = (array) $option;
|
146 |
-
$option['status'] = '
|
147 |
|
148 |
$args = $option;
|
149 |
$args['action'] = 'check_license';
|
150 |
-
$
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
155 |
} else {
|
156 |
-
|
157 |
-
|
|
|
158 |
|
159 |
-
|
160 |
-
if ( is_multisite() ) {
|
161 |
-
add_action( 'network_admin_notices', array( $this, 'show_update_message' ) );
|
162 |
}
|
163 |
|
164 |
-
|
165 |
-
update_site_option( $this->option, $option );
|
166 |
-
} else {
|
167 |
-
update_option( $this->option, $option );
|
168 |
-
}
|
169 |
-
}
|
170 |
|
171 |
-
|
172 |
-
|
173 |
-
*/
|
174 |
-
public function show_update_message() {
|
175 |
-
settings_errors();
|
176 |
-
}
|
177 |
-
|
178 |
-
/**
|
179 |
-
* Notify users to enter license key.
|
180 |
-
*/
|
181 |
-
public function notify() {
|
182 |
-
if ( ! $this->checker->has_extensions() ) {
|
183 |
-
return;
|
184 |
-
}
|
185 |
-
$messages = array(
|
186 |
-
// Translators: %1$s - URL to Meta Box Updater settings page, %2$s - URL to MetaBox.io website.
|
187 |
-
'no_key' => __( '<b>Warning!</b> You have not set your Meta Box license key yet, which means you are missing out on automatic updates and support! <a href="%1$s">Enter your license key</a> or <a href="%2$s" target="_blank">get one here</a>.', 'meta-box-updater' ),
|
188 |
-
// Translators: %1$s - URL to Meta Box Updater settings page, %2$s - URL to MetaBox.io website.
|
189 |
-
'invalid' => __( '<b>Warning!</b> Your license key for Meta Box is invalid or expired. Please <a href="%1$s">fix it</a> or <a href="%2$s" target="_blank">renew</a> to receive automatic updates and premium support.', 'meta-box-updater' ),
|
190 |
-
);
|
191 |
-
$status = $this->get_license_status();
|
192 |
-
$admin_url = is_multisite() ? network_admin_url( "settings.php?page={$this->page_id}" ) : admin_url( "admin.php?page={$this->page_id}" );
|
193 |
-
if ( isset( $messages[ $status ] ) ) {
|
194 |
-
echo '<div class="notice notice-warning"><p>', wp_kses_post( sprintf( $messages[ $status ], $admin_url, 'https://metabox.io/pricing/' ) ), '</p></div>';
|
195 |
-
}
|
196 |
-
}
|
197 |
|
198 |
-
|
199 |
-
* Get license status.
|
200 |
-
*/
|
201 |
-
public function get_license_status() {
|
202 |
-
$option = is_multisite() ? get_site_option( $this->option ) : get_option( $this->option );
|
203 |
-
if ( empty( $option['api_key'] ) ) {
|
204 |
-
return 'no_key';
|
205 |
-
}
|
206 |
-
if ( isset( $option['status'] ) && 'success' !== $option['status'] ) {
|
207 |
-
return 'invalid';
|
208 |
-
}
|
209 |
-
return 'valid';
|
210 |
}
|
211 |
}
|
12 |
*/
|
13 |
class RWMB_Update_Settings {
|
14 |
/**
|
15 |
+
* The update option object.
|
16 |
*
|
17 |
+
* @var object
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
*/
|
19 |
+
private $option;
|
20 |
|
21 |
/**
|
22 |
* The update checker object
|
29 |
* Constructor.
|
30 |
*
|
31 |
* @param object $checker Update checker object.
|
32 |
+
* @param object $option Update option object.
|
33 |
*/
|
34 |
+
public function __construct( $checker, $option ) {
|
35 |
$this->checker = $checker;
|
36 |
+
$this->option = $option;
|
37 |
}
|
38 |
|
39 |
/**
|
40 |
+
* Add hooks to create the settings page.
|
41 |
*/
|
42 |
public function init() {
|
43 |
// Whether to enable Meta Box menu. Priority 1 makes sure it runs before adding Meta Box menu.
|
44 |
add_action( 'admin_menu', array( $this, 'enable_menu' ), 1 );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
}
|
46 |
|
47 |
/**
|
48 |
+
* Enable Meta Box menu when a premium extension is installed.
|
49 |
*/
|
50 |
public function enable_menu() {
|
51 |
+
if ( ! $this->checker->has_extensions() ) {
|
52 |
+
return;
|
53 |
}
|
54 |
+
|
55 |
+
// Enable Meta Box menu.
|
56 |
+
add_filter( 'rwmb_admin_menu', '__return_true' );
|
57 |
+
|
58 |
+
// Add submenu. Priority 90 makes it the last sub-menu item.
|
59 |
+
$admin_menu_hook = is_multisite() ? 'network_admin_menu' : 'admin_menu';
|
60 |
+
add_action( $admin_menu_hook, array( $this, 'add_settings_page' ), 90 );
|
61 |
}
|
62 |
|
63 |
/**
|
64 |
* Add settings page.
|
65 |
*/
|
66 |
public function add_settings_page() {
|
67 |
+
$parent = is_multisite() ? 'settings.php' : 'meta-box';
|
68 |
+
$capability = is_multisite() ? 'manage_network_options' : 'manage_options';
|
69 |
+
$title = is_multisite() ? esc_html__( 'Meta Box License', 'meta-box' ) : esc_html__( 'License', 'meta-box' );
|
70 |
+
$page_hook = add_submenu_page(
|
71 |
$parent,
|
72 |
$title,
|
73 |
$title,
|
74 |
$capability,
|
75 |
+
'meta-box-updater',
|
76 |
array( $this, 'render' )
|
77 |
);
|
78 |
+
add_action( "load-{$page_hook}", array( $this, 'save' ) );
|
79 |
}
|
80 |
|
81 |
/**
|
84 |
public function render() {
|
85 |
?>
|
86 |
<div class="wrap">
|
87 |
+
<h1><?php esc_html_e( 'Meta Box License', 'meta-box' ); ?></h1>
|
88 |
+
<p><?php esc_html_e( 'Please enter your license key to enable automatic updates for Meta Box extensions.', 'meta-box' ); ?></p>
|
89 |
<p>
|
90 |
<?php
|
91 |
printf(
|
92 |
+
// Translators: %1$s - URL to the My Account page, %2$s - URL to the pricing page.
|
93 |
+
wp_kses_post( __( 'To get the license key, visit the <a href="%1$s" target="_blank">My Account</a> page on metabox.io website. If you have not purchased any extension yet, please <a href="%2$s" target="_blank">get a new license here</a>.', 'meta-box' ) ),
|
94 |
+
'https://metabox.io/my-account/',
|
95 |
+
'https://metabox.io/pricing/'
|
96 |
);
|
97 |
?>
|
98 |
</p>
|
99 |
|
100 |
<form action="" method="post">
|
101 |
+
<?php wp_nonce_field( 'meta-box' ); ?>
|
|
|
|
|
|
|
|
|
|
|
102 |
|
103 |
<table class="form-table">
|
104 |
<tr>
|
105 |
+
<th scope="row"><?php esc_html_e( 'License Key', 'meta-box' ); ?></th>
|
106 |
+
<td>
|
107 |
+
<input required class="regular-text" name="meta_box_updater[api_key]" value="<?php echo esc_attr( $this->option->get( 'api_key' ) ); ?>" type="password">
|
108 |
+
<?php
|
109 |
+
$messages = array(
|
110 |
+
// Translators: %1$s - URL to the pricing page.
|
111 |
+
'invalid' => __( 'Your license key is <b>invalid</b>. Please update your license key or <a href="%1$s" target="_blank">get a new one here</a>.', 'meta-box' ),
|
112 |
+
// Translators: %1$s - URL to the pricing page.
|
113 |
+
'error' => __( 'Your license key is <b>invalid</b>. Please update your license key or <a href="%1$s" target="_blank">get a new one here</a>.', 'meta-box' ),
|
114 |
+
// Translators: %2$s - URL to the My Account page.
|
115 |
+
'expired' => __( 'Your license key is <b>expired</b>. Please <a href="%2$s" target="_blank">renew your license</a>.', 'meta-box' ),
|
116 |
+
);
|
117 |
+
$status = $this->checker->get_api_key() ? $this->option->get( 'status', 'active' ) : 'no_key';
|
118 |
+
if ( isset( $messages[ $status ] ) ) {
|
119 |
+
echo '<p class="description">', wp_kses_post( sprintf( $messages[ $status ], 'https://metabox.io/pricing/', 'https://metabox.io/my-account/' ) ), '</p>';
|
120 |
+
}
|
121 |
+
?>
|
122 |
+
</td>
|
123 |
</tr>
|
124 |
</table>
|
125 |
|
126 |
+
<?php submit_button( __( 'Save Changes', 'meta-box' ) ); ?>
|
127 |
</form>
|
128 |
</div>
|
129 |
<?php
|
133 |
* Save update settings.
|
134 |
*/
|
135 |
public function save() {
|
|
|
|
|
136 |
if ( empty( $_POST['submit'] ) ) {
|
137 |
return;
|
138 |
}
|
139 |
+
check_admin_referer( 'meta-box' );
|
140 |
|
141 |
// @codingStandardsIgnoreLine
|
142 |
+
$option = isset( $_POST['meta_box_updater'] ) ? $_POST['meta_box_updater'] : array();
|
143 |
$option = (array) $option;
|
144 |
+
$option['status'] = 'active';
|
145 |
|
146 |
$args = $option;
|
147 |
$args['action'] = 'check_license';
|
148 |
+
$response = $this->checker->request( $args );
|
149 |
+
$status = isset( $response['status'] ) ? $response['status'] : 'invalid';
|
150 |
+
|
151 |
+
if ( false === $response ) {
|
152 |
+
add_settings_error( '', 'mb-error', __( 'Something wrong with the connection to metabox.io. Please try again later.', 'meta-box' ) );
|
153 |
+
} elseif ( 'active' === $status ) {
|
154 |
+
add_settings_error( '', 'mb-success', __( 'Your license is activated.', 'meta-box' ), 'updated' );
|
155 |
+
} elseif ( 'expired' === $status ) {
|
156 |
+
// Translators: %s - URL to the My Account page.
|
157 |
+
$message = __( 'License expired. Please renew on the <a href="%s" target="_blank">My Account</a> page on metabox.io website.', 'meta-box' );
|
158 |
+
$message = wp_kses_post( sprintf( $message, 'https://metabox.io/my-account/' ) );
|
159 |
+
|
160 |
+
add_settings_error( '', 'mb-expired', $message );
|
161 |
} else {
|
162 |
+
// Translators: %1$s - URL to the My Account page, %2$s - URL to the pricing page.
|
163 |
+
$message = __( 'Invalid license. Please <a href="%1$s" target="_blank">check again</a> or <a href="%2$s" target="_blank">get a new license here</a>.', 'meta-box' );
|
164 |
+
$message = wp_kses_post( sprintf( $message, 'https://metabox.io/my-account/', 'https://metabox.io/pricing/' ) );
|
165 |
|
166 |
+
add_settings_error( '', 'mb-invalid', $message );
|
|
|
|
|
167 |
}
|
168 |
|
169 |
+
$option['status'] = $status;
|
|
|
|
|
|
|
|
|
|
|
170 |
|
171 |
+
$admin_notices_hook = is_multisite() ? 'network_admin_notices' : 'admin_notices';
|
172 |
+
add_action( $admin_notices_hook, 'settings_errors' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
173 |
|
174 |
+
$this->option->update( $option );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
175 |
}
|
176 |
}
|
js/notification.js
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
( function( $, document, i18n ) {
|
2 |
+
'use strict';
|
3 |
+
|
4 |
+
function dismissNotification() {
|
5 |
+
$( '#meta-box-notification' ).on( 'click', '.notice-dismiss', function( event ) {
|
6 |
+
event.preventDefault();
|
7 |
+
|
8 |
+
$.post( ajaxurl, {
|
9 |
+
action: 'mb_dismiss_notification',
|
10 |
+
nonce: MBNotification.nonce
|
11 |
+
} );
|
12 |
+
} );
|
13 |
+
}
|
14 |
+
|
15 |
+
$( document ).on( 'ready', dismissNotification );
|
16 |
+
} )( jQuery, document, MBNotification );
|
js/wysiwyg.js
CHANGED
@@ -26,6 +26,11 @@
|
|
26 |
if ( window.tinymce ) {
|
27 |
var editor = new tinymce.Editor(id, settings.tinymce, tinymce.EditorManager);
|
28 |
editor.render();
|
|
|
|
|
|
|
|
|
|
|
29 |
}
|
30 |
|
31 |
// Quick tags
|
26 |
if ( window.tinymce ) {
|
27 |
var editor = new tinymce.Editor(id, settings.tinymce, tinymce.EditorManager);
|
28 |
editor.render();
|
29 |
+
|
30 |
+
editor.on( 'keyup change', function() {
|
31 |
+
editor.save();
|
32 |
+
$this.trigger( 'change' );
|
33 |
+
} );
|
34 |
}
|
35 |
|
36 |
// Quick tags
|
meta-box.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
* Plugin Name: Meta Box
|
4 |
* Plugin URI: https://metabox.io
|
5 |
* Description: Create custom meta boxes and custom fields in WordPress.
|
6 |
-
* Version: 5.0
|
7 |
* Author: MetaBox.io
|
8 |
* Author URI: https://metabox.io
|
9 |
* License: GPL2+
|
3 |
* Plugin Name: Meta Box
|
4 |
* Plugin URI: https://metabox.io
|
5 |
* Description: Create custom meta boxes and custom fields in WordPress.
|
6 |
+
* Version: 5.1.0
|
7 |
* Author: MetaBox.io
|
8 |
* Author URI: https://metabox.io
|
9 |
* License: GPL2+
|
readme.txt
CHANGED
@@ -5,7 +5,7 @@ Tags: meta-box, custom fields, custom field, meta, meta-boxes, admin, advanced,
|
|
5 |
Requires at least: 4.3
|
6 |
Requires PHP: 5.3
|
7 |
Tested up to: 5.2.2
|
8 |
-
Stable tag: 5.0
|
9 |
License: GPLv2 or later
|
10 |
|
11 |
Meta Box plugin is a powerful, professional developer toolkit to create custom meta boxes and custom fields for WordPress.
|
@@ -102,6 +102,7 @@ You'll have ultimate control to add whatever meta box and custom fields in WordP
|
|
102 |
|
103 |
#### Premium Extensions
|
104 |
|
|
|
105 |
- [Meta Box Builder](https://metabox.io/plugins/meta-box-builder/): Create custom meta boxes and custom fields in WordPress using a user-friendly drag-and-drop interface.
|
106 |
- [Meta Box Group](https://metabox.io/plugins/meta-box-group/): Create repeatable groups of WordPress custom fields for better appearance and structure.
|
107 |
- [MB Settings Page](https://metabox.io/plugins/mb-settings-page/): Create settings pages for themes, plugins or websites with beautiful syntax.
|
@@ -166,6 +167,22 @@ To getting started with the plugin, please read the [Quick Start Guide](https://
|
|
166 |
|
167 |
== Changelog ==
|
168 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
169 |
= 5.0.1 - 2019-07-25 =
|
170 |
|
171 |
**Fixed**
|
5 |
Requires at least: 4.3
|
6 |
Requires PHP: 5.3
|
7 |
Tested up to: 5.2.2
|
8 |
+
Stable tag: 5.1.0
|
9 |
License: GPLv2 or later
|
10 |
|
11 |
Meta Box plugin is a powerful, professional developer toolkit to create custom meta boxes and custom fields for WordPress.
|
102 |
|
103 |
#### Premium Extensions
|
104 |
|
105 |
+
- [MB Blocks](https://metabox.io/plugins/mb-blocks/): Create custom Gutenberg blocks with PHP, using the same syntax in Meta Box.
|
106 |
- [Meta Box Builder](https://metabox.io/plugins/meta-box-builder/): Create custom meta boxes and custom fields in WordPress using a user-friendly drag-and-drop interface.
|
107 |
- [Meta Box Group](https://metabox.io/plugins/meta-box-group/): Create repeatable groups of WordPress custom fields for better appearance and structure.
|
108 |
- [MB Settings Page](https://metabox.io/plugins/mb-settings-page/): Create settings pages for themes, plugins or websites with beautiful syntax.
|
167 |
|
168 |
== Changelog ==
|
169 |
|
170 |
+
= 5.1.0 - 2019-08-19 =
|
171 |
+
|
172 |
+
**Fixed**
|
173 |
+
|
174 |
+
- Fatal error with `RWMB_About::redirect()`
|
175 |
+
- Ensure change event fires when editors change
|
176 |
+
- Fix `rwmb_{$field_id}_choice_label` not working for cloneable fields
|
177 |
+
- Fix missing dependency (underscore) for datepicker JS
|
178 |
+
- Fix unindex notice for key_value field
|
179 |
+
- Fix alignment for video field
|
180 |
+
|
181 |
+
**Changed**
|
182 |
+
|
183 |
+
- Update notification sytem
|
184 |
+
- Improve sanitization for fields. See [documentation](https://docs.metabox.io/sanitization/) for details.
|
185 |
+
|
186 |
= 5.0.1 - 2019-07-25 =
|
187 |
|
188 |
**Fixed**
|