Meta Box - Version 4.9

Version Description

  • Improvement: Update Chinese language. Add Chinese Taiwan.
  • Improvement: Add support for Google Maps API key. Default API key is added, however users should replace it with their own key.
  • Improvement: Add additional methods for jQuery validation module which makes it understand HTML5 "pattern" attribute.
  • Improvement: Fully WPML compatibility (supported by WPML team)
  • Improvement: Add placeholders for key_value field
  • Fix: Toggle remove clone buttons for nested groups.
  • Fix: Error on date field, not save
  • Fix: Add fix for date/datetime when both inline and timestamp used
  • Fix: Set default language for date/time picker.
  • Fix: rwmb_meta for images returns incorrect width/height
  • Fix: PHP warning when uploading files in Settings Pages extension.
  • Fix: Blank space in the footer when using plupload_image.
  • Fix: Cloning wysiwyg when deleting the 1st clone
Download this release

Release Info

Developer rilwis
Plugin Icon 128x128 Meta Box
Version 4.9
Comparing to
See all releases

Code changes from version 4.8.7 to 4.9

css/plupload-image.css DELETED
@@ -1,25 +0,0 @@
1
- div.rwmb-drag-drop {
2
- border: 4px dashed #ddd;
3
- height: 200px;
4
- }
5
-
6
- div.rwmb-image-uploading-bar {
7
- position: absolute;
8
- width: 100%;
9
- height: 0;
10
- bottom: 0;
11
- }
12
- div.rwmb-image-uploading-status {
13
- position: absolute;
14
- }
15
- li.rwmb-image-error {
16
- border: 3px solid #c00;
17
- background: #903838;
18
- }
19
- .rwmb-image-uploading-status .rwmb-loader {
20
- width: 64px;
21
- height: 64px;
22
- top: 43px;
23
- left: 43px;
24
- position: relative;
25
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
css/upload.css CHANGED
@@ -1,31 +1,32 @@
1
  .rwmb-upload-area {
2
- position: relative;
3
- padding-top: 0;
4
- margin-top: 0;
5
- height: 200px;
6
- border: 4px dashed #ddd;
 
 
 
 
7
  }
8
-
9
  .rwmb-upload-inside {
10
- text-align: center;
11
- position: absolute;
12
- left: 0;
13
- right:0;
14
- top: 50%;
15
- transform: translateY(-50%);
16
- -webkit-transform: translateY(-50%);
17
- -moz-transform: translateY(-50%);
18
- -ms-transform: translateY(-50%);
19
- margin-top: 10px;
20
  }
21
-
22
  .rwmb-upload-inside p, .rwmb-upload-inside h3 {
23
- text-align: center;
24
  }
25
-
26
  .rwmb-upload-inside h3 {
27
- font-size: 20px;
28
- line-height: 28px;
29
- font-weight: 400;
30
- margin: 0;
31
  }
1
  .rwmb-upload-area {
2
+ position: relative;
3
+ padding-top: 0;
4
+ margin-top: 0;
5
+ height: 200px;
6
+ border: 4px dashed #ddd;
7
+ }
8
+ /* Fix blank space in the footer */
9
+ .rwmb-upload-area .moxie-shim {
10
+ display: none;
11
  }
 
12
  .rwmb-upload-inside {
13
+ text-align: center;
14
+ position: absolute;
15
+ left: 0;
16
+ right: 0;
17
+ top: 50%;
18
+ transform: translateY(-50%);
19
+ -webkit-transform: translateY(-50%);
20
+ -moz-transform: translateY(-50%);
21
+ -ms-transform: translateY(-50%);
22
+ margin-top: 10px;
23
  }
 
24
  .rwmb-upload-inside p, .rwmb-upload-inside h3 {
25
+ text-align: center;
26
  }
 
27
  .rwmb-upload-inside h3 {
28
+ font-size: 20px;
29
+ line-height: 28px;
30
+ font-weight: 400;
31
+ margin: 0;
32
  }
inc/autoloader.php ADDED
@@ -0,0 +1,181 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Autoload plugin classes.
4
+ * @package Meta Box
5
+ */
6
+
7
+ /**
8
+ * Autoload class
9
+ */
10
+ class RWMB_Autoloader
11
+ {
12
+ /**
13
+ * List of directories to load classes.
14
+ * @var array
15
+ */
16
+ protected $dirs = array();
17
+
18
+ /**
19
+ * Adds a base directory for a class name prefix and/or suffix.
20
+ *
21
+ * @param string $base_dir A base directory for class files.
22
+ * @param string $prefix The class name prefix.
23
+ * @param string $suffix The class name suffix.
24
+ */
25
+ public function add( $base_dir, $prefix, $suffix = '' )
26
+ {
27
+ $this->dirs[] = array(
28
+ 'dir' => trailingslashit( $base_dir ),
29
+ 'prefix' => $prefix,
30
+ 'suffix' => $suffix,
31
+ );
32
+ }
33
+
34
+ /**
35
+ * Register autoloader for plugin classes.
36
+ * In PHP 5.3, SPL extension cannot be disabled and it's safe to use autoload.
37
+ * However, hosting providers can disable it in PHP 5.2. In that case, we provide a fallback for autoload.
38
+ * @link http://php.net/manual/en/spl.installation.php
39
+ * @link https://github.com/rilwis/meta-box/issues/810
40
+ */
41
+ public function register()
42
+ {
43
+ spl_autoload_register( array( $this, 'autoload' ) );
44
+ if ( ! class_exists( 'RWMB_Core' ) )
45
+ {
46
+ $this->fallback();
47
+ }
48
+ }
49
+
50
+ /**
51
+ * Autoload fields' classes.
52
+ * @param string $class Class name
53
+ * @return mixed Boolean false if no mapped file can be loaded, or the name of the mapped file that was loaded.
54
+ */
55
+ public function autoload( $class )
56
+ {
57
+ foreach ( $this->dirs as $dir )
58
+ {
59
+ if (
60
+ ( $dir['prefix'] && 0 !== strpos( $class, $dir['prefix'] ) )
61
+ && ( $dir['suffix'] && substr( $class, - strlen( $dir['suffix'] ) ) !== $dir['suffix'] )
62
+ )
63
+ {
64
+ continue;
65
+ }
66
+ $file = substr( $class, strlen( $dir['prefix'] ) );
67
+ if ( $dir['suffix'] && strlen( $file ) > strlen( $dir['suffix'] ) )
68
+ {
69
+ $file = substr( $file, 0, - strlen( $dir['suffix'] ) );
70
+ }
71
+ $file = strtolower( str_replace( '_', '-', $file ) ) . '.php';
72
+ $file = $dir['dir'] . $file;
73
+ if ( $this->require_file( $file ) )
74
+ {
75
+ return $file;
76
+ }
77
+ }
78
+ return false;
79
+ }
80
+
81
+ /**
82
+ * Fallback for autoload in PHP 5.2.
83
+ */
84
+ protected function fallback()
85
+ {
86
+ $files = array(
87
+ // Core
88
+ 'core',
89
+ 'clone',
90
+ 'helper',
91
+ 'meta-box',
92
+ 'validation',
93
+ 'sanitize',
94
+
95
+ // Walkers
96
+ 'walkers/walker',
97
+ 'walkers/select',
98
+ 'walkers/select-tree',
99
+ 'walkers/input-list',
100
+
101
+ // Fields
102
+ 'field',
103
+
104
+ 'fields/multiple-values',
105
+ 'fields/autocomplete',
106
+ 'fields/text-list',
107
+
108
+ 'fields/choice',
109
+
110
+ 'fields/select',
111
+ 'fields/select-advanced',
112
+ 'fields/select-tree',
113
+
114
+ 'fields/input-list',
115
+ 'fields/radio',
116
+ 'fields/checkbox-list',
117
+
118
+ 'fields/object-choice',
119
+ 'fields/post',
120
+ 'fields/taxonomy',
121
+ 'fields/taxonomy-advanced',
122
+ 'fields/user',
123
+
124
+ 'fields/input',
125
+
126
+ 'fields/checkbox',
127
+ 'fields/number',
128
+ 'fields/range',
129
+
130
+ 'fields/text',
131
+ 'fields/color',
132
+ 'fields/datetime',
133
+ 'fields/date',
134
+ 'fields/time',
135
+ 'fields/fieldset-text',
136
+ 'fields/key-value',
137
+ 'fields/oembed',
138
+ 'fields/password',
139
+
140
+ 'fields/file-input',
141
+ 'fields/file',
142
+ 'fields/image',
143
+ 'fields/image-select',
144
+ 'fields/thickbox-image',
145
+
146
+ 'fields/media',
147
+ 'fields/file-upload',
148
+ 'fields/image-advanced',
149
+ 'fields/image-upload',
150
+
151
+ 'fields/button',
152
+ 'fields/custom-html',
153
+ 'fields/divider',
154
+ 'fields/heading',
155
+ 'fields/map',
156
+ 'fields/slider',
157
+ 'fields/textarea',
158
+ 'fields/wysiwyg',
159
+ );
160
+ foreach ( $files as $file )
161
+ {
162
+ $this->require_file( RWMB_INC_DIR . "$file.php" );
163
+ }
164
+ }
165
+
166
+ /**
167
+ * If a file exists, require it from the file system.
168
+ *
169
+ * @param string $file The file to require.
170
+ * @return bool True if the file exists, false if not.
171
+ */
172
+ protected function require_file( $file )
173
+ {
174
+ if ( file_exists( $file ) )
175
+ {
176
+ require_once $file;
177
+ return true;
178
+ }
179
+ return false;
180
+ }
181
+ }
inc/clone.php ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * The Meta Box Clone class.
5
+ * @package Meta Box
6
+ */
7
+ class RWMB_Clone
8
+ {
9
+ /**
10
+ * Get clone field HTML
11
+ *
12
+ * @param mixed $meta
13
+ * @param array $field
14
+ *
15
+ * @return string
16
+ */
17
+ public static function html( $meta, $field )
18
+ {
19
+ $field_html = '';
20
+
21
+ /**
22
+ * Note: $meta must contain value so that the foreach loop runs!
23
+ * @see meta()
24
+ */
25
+ foreach ( $meta as $index => $sub_meta )
26
+ {
27
+ $sub_field = $field;
28
+ $sub_field['field_name'] = $field['field_name'] . "[{$index}]";
29
+ if ( $index > 0 )
30
+ {
31
+ if ( isset( $sub_field['address_field'] ) )
32
+ $sub_field['address_field'] = $field['address_field'] . "_{$index}";
33
+ $sub_field['id'] = $field['id'] . "_{$index}";
34
+ }
35
+ if ( $field['multiple'] )
36
+ $sub_field['field_name'] .= '[]';
37
+
38
+ // Wrap field HTML in a div with class="rwmb-clone" if needed
39
+ $class = "rwmb-clone rwmb-{$field['type']}-clone";
40
+ $sort_icon = '';
41
+ if ( $field['sort_clone'] )
42
+ {
43
+ $class .= ' rwmb-sort-clone';
44
+ $sort_icon = "<a href='javascript:;' class='rwmb-clone-icon'></a>";
45
+ }
46
+ $input_html = "<div class='$class'>" . $sort_icon;
47
+
48
+ // Call separated methods for displaying each type of field
49
+ $input_html .= RWMB_Field::call( $sub_field, 'html', $sub_meta );
50
+ $input_html = RWMB_Field::filter( 'html', $input_html, $sub_field, $sub_meta );
51
+
52
+ // Remove clone button
53
+ $input_html .= self::remove_clone_button( $sub_field );
54
+ $input_html .= '</div>';
55
+
56
+ $field_html .= $input_html;
57
+ }
58
+
59
+ return $field_html;
60
+ }
61
+
62
+ /**
63
+ * Set value of meta before saving into database
64
+ *
65
+ * @param mixed $new
66
+ * @param mixed $old
67
+ * @param int $post_id
68
+ * @param array $field
69
+ *
70
+ * @return mixed
71
+ */
72
+ public static function value( $new, $old, $post_id, $field )
73
+ {
74
+ foreach ( $new as $key => $value )
75
+ {
76
+ $old_value = isset( $old[$key] ) ? $old[$key] : null;
77
+ $value = RWMB_Field::call( $field, 'value', $value, $old_value, $post_id );
78
+ $new[$key] = RWMB_Field::filter( 'sanitize', $value, $field );
79
+ }
80
+ return $new;
81
+ }
82
+
83
+ /**
84
+ * Add clone button
85
+ * @param array $field Field parameter
86
+ * @return string $html
87
+ */
88
+ public static function add_clone_button( $field )
89
+ {
90
+ if ( ! $field['clone'] )
91
+ {
92
+ return '';
93
+ }
94
+ $text = RWMB_Field::filter( 'add_clone_button_text', __( '+ Add more', 'meta-box' ), $field );
95
+ return '<a href="#" class="rwmb-button button-primary add-clone">' . esc_html( $text ) . '</a>';
96
+ }
97
+
98
+ /**
99
+ * Remove clone button
100
+ * @param array $field Field parameter
101
+ * @return string $html
102
+ */
103
+ public static function remove_clone_button( $field )
104
+ {
105
+ $text = RWMB_Field::filter( 'remove_clone_button_text', '<i class="dashicons dashicons-minus"></i>', $field );
106
+ return '<a href="#" class="rwmb-button remove-clone">' . $text . '</a>';
107
+ }
108
+ }
inc/core.php CHANGED
@@ -24,7 +24,8 @@ class RWMB_Core
24
  $plugin = 'meta-box/meta-box.php';
25
  add_filter( "plugin_action_links_$plugin", array( $this, 'plugin_links' ) );
26
  add_action( 'plugins_loaded', array( $this, 'load_textdomain' ) );
27
- add_action( 'admin_init', array( $this, 'register_meta_boxes' ) );
 
28
  add_action( 'edit_page_form', array( $this, 'fix_page_template' ) );
29
  }
30
 
@@ -81,6 +82,25 @@ class RWMB_Core
81
  return self::$meta_boxes;
82
  }
83
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  /**
85
  * WordPress will prevent post data saving if a page template has been selected that does not exist
86
  * This is especially a problem when switching to our theme, and old page templates are in the post data
@@ -100,4 +120,13 @@ class RWMB_Core
100
  delete_post_meta( $post->ID, '_wp_page_template' );
101
  }
102
  }
103
- }
 
 
 
 
 
 
 
 
 
24
  $plugin = 'meta-box/meta-box.php';
25
  add_filter( "plugin_action_links_$plugin", array( $this, 'plugin_links' ) );
26
  add_action( 'plugins_loaded', array( $this, 'load_textdomain' ) );
27
+ add_action( 'init', array( $this, 'register_meta_boxes' ) );
28
+ add_action( 'init', array( $this, 'register_wpml_hooks' ) );
29
  add_action( 'edit_page_form', array( $this, 'fix_page_template' ) );
30
  }
31
 
82
  return self::$meta_boxes;
83
  }
84
 
85
+ /**
86
+ * Get all registered fields.
87
+ *
88
+ * @return array
89
+ */
90
+ public static function get_fields() {
91
+ $fields = array();
92
+
93
+ foreach ( self::$meta_boxes as $meta_box ) {
94
+ foreach ( $meta_box['fields'] as $field ) {
95
+ if ( ! empty( $field['id'] ) ) {
96
+ $fields[ $field['id'] ] = $field;
97
+ }
98
+ }
99
+ }
100
+
101
+ return $fields;
102
+ }
103
+
104
  /**
105
  * WordPress will prevent post data saving if a page template has been selected that does not exist
106
  * This is especially a problem when switching to our theme, and old page templates are in the post data
120
  delete_post_meta( $post->ID, '_wp_page_template' );
121
  }
122
  }
123
+
124
+ /**
125
+ * Register wpml compatibility hooks
126
+ */
127
+ public function register_wpml_hooks() {
128
+ if ( defined( 'ICL_SITEPRESS_VERSION' ) ) {
129
+ new RWMB_WPML;
130
+ }
131
+ }
132
+ }
inc/field.php CHANGED
@@ -47,46 +47,7 @@ abstract class RWMB_Field
47
  // Cloneable fields
48
  if ( $field['clone'] )
49
  {
50
- $field_html = '';
51
-
52
- /**
53
- * Note: $meta must contain value so that the foreach loop runs!
54
- * @see meta()
55
- */
56
- foreach ( $meta as $index => $sub_meta )
57
- {
58
- $sub_field = $field;
59
- $sub_field['field_name'] = $field['field_name'] . "[{$index}]";
60
- if ( $index > 0 )
61
- {
62
- if ( isset( $sub_field['address_field'] ) )
63
- $sub_field['address_field'] = $field['address_field'] . "_{$index}";
64
- $sub_field['id'] = $field['id'] . "_{$index}";
65
- }
66
- if ( $field['multiple'] )
67
- $sub_field['field_name'] .= '[]';
68
-
69
- // Wrap field HTML in a div with class="rwmb-clone" if needed
70
- $class = "rwmb-clone rwmb-{$field['type']}-clone";
71
- $sort_icon = '';
72
- if ( $field['sort_clone'] )
73
- {
74
- $class .= ' rwmb-sort-clone';
75
- $sort_icon = "<a href='javascript:;' class='rwmb-clone-icon'></a>";
76
- }
77
- $input_html = "<div class='$class'>" . $sort_icon;
78
-
79
- // Call separated methods for displaying each type of field
80
- $input_html .= self::call( $sub_field, 'html', $sub_meta );
81
- $input_html = self::filter( 'html', $input_html, $sub_field, $sub_meta );
82
-
83
- // Remove clone button
84
- $input_html .= self::call( 'remove_clone_button', $sub_field );
85
-
86
- $input_html .= '</div>';
87
-
88
- $field_html .= $input_html;
89
- }
90
  }
91
  // Non-cloneable fields
92
  else
@@ -171,40 +132,18 @@ abstract class RWMB_Field
171
  */
172
  public static function end_html( $meta, $field )
173
  {
174
- $button = $field['clone'] ? self::call( 'add_clone_button', $field ) : '';
175
- $desc = $field['desc'] ? "<p id='{$field['id']}_description' class='description'>{$field['desc']}</p>" : '';
176
-
177
- // Closes the container
178
- $html = "{$button}{$desc}</div>";
179
-
180
- return $html;
181
- }
182
-
183
- /**
184
- * Add clone button
185
- *
186
- * @param array $field Field parameter
187
- *
188
- * @return string $html
189
- */
190
- public static function add_clone_button( $field )
191
- {
192
- $text = apply_filters( 'rwmb_add_clone_button_text', __( '+ Add more', 'meta-box' ), $field );
193
- return "<a href='#' class='rwmb-button button-primary add-clone'>$text</a>";
194
  }
195
 
196
  /**
197
- * Remove clone button
198
- *
199
- * @param array $field Field parameter
200
- *
201
- * @return string $html
202
  */
203
- public static function remove_clone_button( $field )
204
  {
205
- $icon = '<i class="dashicons dashicons-minus"></i>';
206
- $text = apply_filters( 'rwmb_remove_clone_button_text', $icon, $field );
207
- return "<a href='#' class='rwmb-button remove-clone'>$text</a>";
208
  }
209
 
210
  /**
@@ -229,7 +168,7 @@ abstract class RWMB_Field
229
  $meta = get_post_meta( $post_id, $field['id'], $single );
230
 
231
  // Use $field['std'] only when the meta box hasn't been saved (i.e. the first time we run)
232
- $meta = ( ! $saved && '' === $meta || array() === $meta ) ? $field['std'] : $meta;
233
 
234
  // Escape attributes
235
  $meta = self::call( $field, 'esc_meta', $meta );
47
  // Cloneable fields
48
  if ( $field['clone'] )
49
  {
50
+ $field_html = RWMB_Clone::html( $meta, $field );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  }
52
  // Non-cloneable fields
53
  else
132
  */
133
  public static function end_html( $meta, $field )
134
  {
135
+ return RWMB_Clone::add_clone_button( $field ) . self::call( 'element_description', $field ) . '</div>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
  }
137
 
138
  /**
139
+ * Display field description.
140
+ * @param array $field
141
+ * @return string
 
 
142
  */
143
+ protected static function element_description( $field )
144
  {
145
+ $id = $field['id'] ? " id='{$field['id']}-description'" : '';
146
+ return $field['desc'] ? "<p{$id} class='description'>{$field['desc']}</p>" : '';
 
147
  }
148
 
149
  /**
168
  $meta = get_post_meta( $post_id, $field['id'], $single );
169
 
170
  // Use $field['std'] only when the meta box hasn't been saved (i.e. the first time we run)
171
+ $meta = ! $saved ? $field['std'] : $meta;
172
 
173
  // Escape attributes
174
  $meta = self::call( $field, 'esc_meta', $meta );
inc/fields/checkbox.php CHANGED
@@ -36,39 +36,13 @@ class RWMB_Checkbox_Field extends RWMB_Input_Field
36
  }
37
 
38
  /**
39
- * Show end HTML markup for fields
40
- *
41
- * @param mixed $meta
42
  * @param array $field
43
- *
44
  * @return string
45
  */
46
- public static function end_html( $meta, $field )
47
- {
48
- $button = $field['clone'] ? self::add_clone_button( $field ) : '';
49
-
50
- // Closes the container
51
- $html = "{$button}</div>";
52
-
53
- return $html;
54
- }
55
-
56
- /**
57
- * Set the value of checkbox to 1 or 0 instead of 'checked' and empty string
58
- * This prevents using default value once the checkbox has been unchecked
59
- *
60
- * @link https://github.com/rilwis/meta-box/issues/6
61
- *
62
- * @param mixed $new
63
- * @param mixed $old
64
- * @param int $post_id
65
- * @param array $field
66
- *
67
- * @return int
68
- */
69
- public static function value( $new, $old, $post_id, $field )
70
  {
71
- return empty( $new ) ? 0 : 1;
72
  }
73
 
74
  /**
36
  }
37
 
38
  /**
39
+ * Do not show field description.
 
 
40
  * @param array $field
 
41
  * @return string
42
  */
43
+ public static function element_description( $field )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  {
45
+ return '';
46
  }
47
 
48
  /**
inc/fields/choice.php CHANGED
@@ -32,7 +32,7 @@ abstract class RWMB_Choice_Field extends RWMB_Field
32
  $options = self::call( 'get_options', $field );
33
  $options = self::call( 'filter_options', $field, $options );
34
  $db_fields = self::call( 'get_db_fields', $field );
35
- return self::call( 'walk', $field, $options, $db_fields, $meta );
36
  }
37
 
38
  /**
32
  $options = self::call( 'get_options', $field );
33
  $options = self::call( 'filter_options', $field, $options );
34
  $db_fields = self::call( 'get_db_fields', $field );
35
+ return ! empty( $options ) ? self::call( 'walk', $field, $options, $db_fields, $meta ) : null;
36
  }
37
 
38
  /**
inc/fields/datetime.php CHANGED
@@ -127,26 +127,7 @@ class RWMB_Datetime_Field extends RWMB_Text_Field
127
  */
128
  public static function value( $new, $old, $post_id, $field )
129
  {
130
- if ( $field['timestamp'] )
131
- {
132
- $new = self::prepare_value( $new, $field );
133
- }
134
- return $new;
135
- }
136
-
137
- /**
138
- * Prepare value before saving if set 'timestamp'
139
- * @param array|string $value The submitted value
140
- * @param array $field Field parameter
141
- * @return array
142
- */
143
- protected static function prepare_value( $value, $field )
144
- {
145
- if ( $field['clone'] )
146
- {
147
- return array_map( __METHOD__, $value );
148
- }
149
- return isset( $value['timestamp'] ) ? $value['timestamp'] : null;
150
  }
151
 
152
  /**
@@ -216,7 +197,7 @@ class RWMB_Datetime_Field extends RWMB_Text_Field
216
  ) );
217
  }
218
 
219
- $field = RWMB_Text_Field::normalize( $field );
220
 
221
  return $field;
222
  }
127
  */
128
  public static function value( $new, $old, $post_id, $field )
129
  {
130
+ return isset( $new['timestamp'] ) ? $new['timestamp'] : $new;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
  }
132
 
133
  /**
197
  ) );
198
  }
199
 
200
+ $field = parent::normalize( $field );
201
 
202
  return $field;
203
  }
inc/fields/email.php DELETED
@@ -1,21 +0,0 @@
1
- <?php
2
- /**
3
- * Email field class.
4
- */
5
- class RWMB_Email_Field extends RWMB_Text_Field
6
- {
7
- /**
8
- * Sanitize email
9
- *
10
- * @param mixed $new
11
- * @param mixed $old
12
- * @param int $post_id
13
- * @param array $field
14
- *
15
- * @return string
16
- */
17
- public static function value( $new, $old, $post_id, $field )
18
- {
19
- return $field['clone'] ? array_map( 'sanitize_email', (array) $new ) : sanitize_email( $new );
20
- }
21
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/fields/fieldset-text.php CHANGED
@@ -31,18 +31,13 @@ class RWMB_Fieldset_Text_Field extends RWMB_Text_Field
31
  }
32
 
33
  /**
34
- * Show end HTML markup for fields
35
- * Do not show field description. Field description is shown before list of fields
36
- *
37
- * @param mixed $meta
38
  * @param array $field
39
  * @return string
40
  */
41
- static function end_html( $meta, $field )
42
  {
43
- $button = $field['clone'] ? self::add_clone_button( $field ) : '';
44
- $html = "$button</div>";
45
- return $html;
46
  }
47
 
48
  /**
31
  }
32
 
33
  /**
34
+ * Do not show field description.
 
 
 
35
  * @param array $field
36
  * @return string
37
  */
38
+ public static function element_description( $field )
39
  {
40
+ return '';
 
 
41
  }
42
 
43
  /**
inc/fields/file.php CHANGED
@@ -207,7 +207,7 @@ class RWMB_File_Field extends RWMB_Field
207
  $new[] = self::upload( $file, $post_id );
208
  }
209
 
210
- return array_unique( array_merge( $old, array_filter( $new ) ) );
211
  }
212
 
213
  /**
207
  $new[] = self::upload( $file, $post_id );
208
  }
209
 
210
+ return array_filter( array_unique( array_merge( (array) $old, $new ) ) );
211
  }
212
 
213
  /**
inc/fields/heading.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  /**
3
  * Heading field class.
4
  */
@@ -38,8 +39,6 @@ class RWMB_Heading_Field extends RWMB_Field
38
  */
39
  static function end_html( $meta, $field )
40
  {
41
- $id = $field['id'] ? " id='{$field['id']}-description'" : '';
42
-
43
- return $field['desc'] ? "<p{$id} class='description'>{$field['desc']}</p>" : '';
44
  }
45
  }
1
  <?php
2
+
3
  /**
4
  * Heading field class.
5
  */
39
  */
40
  static function end_html( $meta, $field )
41
  {
42
+ return self::element_description( $field );
 
 
43
  }
44
  }
inc/fields/image.php CHANGED
@@ -77,16 +77,16 @@ class RWMB_Image_Field extends RWMB_File_Field
77
  return false;
78
  }
79
 
80
- $args = wp_parse_args( $args, array(
81
  'size' => 'thumbnail',
82
  ) );
83
- list( $src ) = wp_get_attachment_image_src( $file, $args['size'] );
84
  $attachment = get_post( $file );
85
  $info = array(
86
  'ID' => $file,
87
  'name' => basename( $path ),
88
  'path' => $path,
89
- 'url' => $src,
90
  'full_url' => wp_get_attachment_url( $file ),
91
  'title' => $attachment->post_title,
92
  'caption' => $attachment->post_excerpt,
@@ -98,6 +98,12 @@ class RWMB_Image_Field extends RWMB_File_Field
98
  $info['srcset'] = wp_get_attachment_image_srcset( $file );
99
  }
100
 
101
- return wp_parse_args( $info, wp_get_attachment_metadata( $file ) );
 
 
 
 
 
 
102
  }
103
  }
77
  return false;
78
  }
79
 
80
+ $args = wp_parse_args( $args, array(
81
  'size' => 'thumbnail',
82
  ) );
83
+ $image = wp_get_attachment_image_src( $file, $args['size'] );
84
  $attachment = get_post( $file );
85
  $info = array(
86
  'ID' => $file,
87
  'name' => basename( $path ),
88
  'path' => $path,
89
+ 'url' => $image[0],
90
  'full_url' => wp_get_attachment_url( $file ),
91
  'title' => $attachment->post_title,
92
  'caption' => $attachment->post_excerpt,
98
  $info['srcset'] = wp_get_attachment_image_srcset( $file );
99
  }
100
 
101
+ $info = wp_parse_args( $info, wp_get_attachment_metadata( $file ) );
102
+
103
+ // Do not overwrite width and height by returned value of image meta
104
+ $info['width'] = $image[1];
105
+ $info['height'] = $image[2];
106
+
107
+ return $info;
108
  }
109
  }
inc/fields/input-list.php CHANGED
@@ -25,7 +25,7 @@ class RWMB_Input_List_Field extends RWMB_Choice_Field
25
  */
26
  public static function walk( $field, $options, $db_fields, $meta )
27
  {
28
- $walker = new RWMB_Input_List_Walker( $db_fields, $field, $meta );
29
  $output = sprintf( '<ul class="rwmb-input-list %s %s">',
30
  $field['collapse'] ? 'collapse' : '',
31
  $field['inline'] ? 'inline' : ''
25
  */
26
  public static function walk( $field, $options, $db_fields, $meta )
27
  {
28
+ $walker = new RWMB_Walker_Input_List( $db_fields, $field, $meta );
29
  $output = sprintf( '<ul class="rwmb-input-list %s %s">',
30
  $field['collapse'] ? 'collapse' : '',
31
  $field['inline'] ? 'inline' : ''
inc/fields/key-value.php CHANGED
@@ -17,13 +17,13 @@ abstract class RWMB_Key_Value_Field extends RWMB_Text_Field
17
  // Key
18
  $key = isset( $meta[0] ) ? $meta[0] : '';
19
  $attributes = self::get_attributes( $field, $key );
20
- $attributes['placeholder'] = esc_attr__( 'Key', 'meta-box' );
21
  $html = sprintf( '<input %s>', self::render_attributes( $attributes ) );
22
 
23
  // Value
24
  $val = isset( $meta[1] ) ? $meta[1] : '';
25
  $attributes = self::get_attributes( $field, $val );
26
- $attributes['placeholder'] = esc_attr__( 'Value', 'meta-box' );
27
  $html .= sprintf( '<input %s>', self::render_attributes( $attributes ) );
28
 
29
  return $html;
@@ -56,18 +56,13 @@ abstract class RWMB_Key_Value_Field extends RWMB_Text_Field
56
  }
57
 
58
  /**
59
- * Show end HTML markup for fields
60
- * Do not show field description. Field description is shown before list of fields
61
- *
62
- * @param mixed $meta
63
  * @param array $field
64
  * @return string
65
  */
66
- static function end_html( $meta, $field )
67
  {
68
- $button = $field['clone'] ? self::add_clone_button( $field ) : '';
69
- $html = "$button</div>";
70
- return $html;
71
  }
72
 
73
  /**
@@ -118,6 +113,10 @@ abstract class RWMB_Key_Value_Field extends RWMB_Text_Field
118
  $field['clone'] = true;
119
  $field['multiple'] = true;
120
  $field['attributes']['type'] = 'text';
 
 
 
 
121
  return $field;
122
  }
123
 
17
  // Key
18
  $key = isset( $meta[0] ) ? $meta[0] : '';
19
  $attributes = self::get_attributes( $field, $key );
20
+ $attributes['placeholder'] = $field['placeholder']['key'];
21
  $html = sprintf( '<input %s>', self::render_attributes( $attributes ) );
22
 
23
  // Value
24
  $val = isset( $meta[1] ) ? $meta[1] : '';
25
  $attributes = self::get_attributes( $field, $val );
26
+ $attributes['placeholder'] = $field['placeholder']['value'];
27
  $html .= sprintf( '<input %s>', self::render_attributes( $attributes ) );
28
 
29
  return $html;
56
  }
57
 
58
  /**
59
+ * Do not show field description.
 
 
 
60
  * @param array $field
61
  * @return string
62
  */
63
+ public static function element_description( $field )
64
  {
65
+ return '';
 
 
66
  }
67
 
68
  /**
113
  $field['clone'] = true;
114
  $field['multiple'] = true;
115
  $field['attributes']['type'] = 'text';
116
+ $field['placeholder'] = wp_parse_args( (array) $field['placeholder'], array(
117
+ 'key' => 'Key',
118
+ 'value' => 'Value',
119
+ ) );
120
  return $field;
121
  }
122
 
inc/fields/map.php CHANGED
@@ -11,11 +11,20 @@ class RWMB_Map_Field extends RWMB_Field
11
  */
12
  static function admin_enqueue_scripts()
13
  {
14
- /**
 
 
 
 
 
 
 
 
 
15
  * Allows developers load more libraries via a filter.
16
  * @link https://developers.google.com/maps/documentation/javascript/libraries
17
  */
18
- $google_maps_url = apply_filters( 'rwmb_google_maps_url', 'https://maps.google.com/maps/api/js?sensor=false' );
19
  wp_register_script( 'google-maps', esc_url_raw( $google_maps_url ), array(), '', true );
20
  wp_enqueue_style( 'rwmb-map', RWMB_CSS_URL . 'map.css' );
21
  wp_enqueue_script( 'rwmb-map', RWMB_JS_URL . 'map.js', array( 'jquery-ui-autocomplete', 'google-maps' ), RWMB_VER, true );
@@ -66,8 +75,12 @@ class RWMB_Map_Field extends RWMB_Field
66
  {
67
  $field = parent::normalize( $field );
68
  $field = wp_parse_args( $field, array(
69
- 'std' => '',
70
- 'address_field' => '',
 
 
 
 
71
  ) );
72
 
73
  return $field;
@@ -121,7 +134,8 @@ class RWMB_Map_Field extends RWMB_Field
121
  * Allows developers load more libraries via a filter.
122
  * @link https://developers.google.com/maps/documentation/javascript/libraries
123
  */
124
- $google_maps_url = apply_filters( 'rwmb_google_maps_url', 'https://maps.google.com/maps/api/js?sensor=false' );
 
125
  wp_register_script( 'google-maps', esc_url_raw( $google_maps_url ), array(), '', true );
126
  wp_enqueue_script( 'rwmb-map-frontend', RWMB_JS_URL . 'map-frontend.js', array( 'google-maps' ), '', true );
127
 
11
  */
12
  static function admin_enqueue_scripts()
13
  {
14
+ /**
15
+ * Since June 2016, Google Maps requires a valid API key.
16
+ * @link http://googlegeodevelopers.blogspot.com/2016/06/building-for-scale-updates-to-google.html
17
+ * @link https://developers.google.com/maps/documentation/javascript/get-api-key
18
+ */
19
+ $args = func_get_args();
20
+ $field = $args[0];
21
+ $google_maps_url = add_query_arg( 'key', $field['api_key'], 'https://maps.google.com/maps/api/js' );
22
+
23
+ /**
24
  * Allows developers load more libraries via a filter.
25
  * @link https://developers.google.com/maps/documentation/javascript/libraries
26
  */
27
+ $google_maps_url = apply_filters( 'rwmb_google_maps_url', $google_maps_url );
28
  wp_register_script( 'google-maps', esc_url_raw( $google_maps_url ), array(), '', true );
29
  wp_enqueue_style( 'rwmb-map', RWMB_CSS_URL . 'map.css' );
30
  wp_enqueue_script( 'rwmb-map', RWMB_JS_URL . 'map.js', array( 'jquery-ui-autocomplete', 'google-maps' ), RWMB_VER, true );
75
  {
76
  $field = parent::normalize( $field );
77
  $field = wp_parse_args( $field, array(
78
+ 'std' => '',
79
+ 'address_field' => '',
80
+
81
+ // Default API key, required by Google Maps since June 2016.
82
+ // Users should overwrite this key with their own key.
83
+ 'api_key' => 'AIzaSyC1mUh87SGFyf133tpZQJa-s96p0tgnraQ',
84
  ) );
85
 
86
  return $field;
134
  * Allows developers load more libraries via a filter.
135
  * @link https://developers.google.com/maps/documentation/javascript/libraries
136
  */
137
+ $google_maps_url = add_query_arg( 'key', $field['api_key'], 'https://maps.google.com/maps/api/js' );
138
+ $google_maps_url = apply_filters( 'rwmb_google_maps_url', $google_maps_url );
139
  wp_register_script( 'google-maps', esc_url_raw( $google_maps_url ), array(), '', true );
140
  wp_enqueue_script( 'rwmb-map-frontend', RWMB_JS_URL . 'map-frontend.js', array( 'google-maps' ), '', true );
141
 
inc/fields/media.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  /**
3
  * Media field class which users WordPress media popup to upload and select files.
4
  */
@@ -30,8 +31,9 @@ class RWMB_Media_Field extends RWMB_File_Field
30
  'noTitle' => _x( 'No Title', 'media', 'meta-box' ),
31
  'loadingUrl' => RWMB_URL . 'img/loader.gif',
32
  'extensions' => self::get_mime_extensions(),
33
- 'select' => _x( 'Select Files', 'media', 'meta-box' ),
34
- 'uploadInstructions' => _x( 'Drop files here to upload', 'media', 'meta-box' ),
 
35
  ) );
36
  }
37
  }
@@ -41,7 +43,7 @@ class RWMB_Media_Field extends RWMB_File_Field
41
  */
42
  public static function add_actions()
43
  {
44
- $args = func_get_args();
45
  $field = reset( $args );
46
  add_action( 'print_media_templates', array( self::get_class_name( $field ), 'print_templates' ) );
47
  }
@@ -165,15 +167,6 @@ class RWMB_Media_Field extends RWMB_File_Field
165
  */
166
  public static function value( $new, $old, $post_id, $field )
167
  {
168
- if ( $field['clone'] )
169
- {
170
- foreach ( (array) $new as $n )
171
- {
172
- if ( - 1 === intval( $n ) )
173
- return $old;
174
- }
175
- }
176
-
177
  if ( - 1 === intval( $new ) )
178
  return $old;
179
 
1
  <?php
2
+
3
  /**
4
  * Media field class which users WordPress media popup to upload and select files.
5
  */
31
  'noTitle' => _x( 'No Title', 'media', 'meta-box' ),
32
  'loadingUrl' => RWMB_URL . 'img/loader.gif',
33
  'extensions' => self::get_mime_extensions(),
34
+ 'select' => apply_filters( 'rwmb_media_select_string', _x( 'Select Files', 'media', 'meta-box' ) ),
35
+ 'or' => apply_filters( 'rwmb_media_or_string', _x( 'or', 'media', 'meta-box' ) ),
36
+ 'uploadInstructions' => apply_filters( 'rwmb_media_upload_instructions_string', _x( 'Drop files here to upload', 'media', 'meta-box' ) ),
37
  ) );
38
  }
39
  }
43
  */
44
  public static function add_actions()
45
  {
46
+ $args = func_get_args();
47
  $field = reset( $args );
48
  add_action( 'print_media_templates', array( self::get_class_name( $field ), 'print_templates' ) );
49
  }
167
  */
168
  public static function value( $new, $old, $post_id, $field )
169
  {
 
 
 
 
 
 
 
 
 
170
  if ( - 1 === intval( $new ) )
171
  return $old;
172
 
inc/fields/object-choice.php CHANGED
@@ -82,19 +82,6 @@ abstract class RWMB_Object_Choice_Field extends RWMB_Choice_Field
82
  );
83
  }
84
 
85
- /**
86
- * Save meta value
87
- *
88
- * @param $new
89
- * @param $old
90
- * @param $post_id
91
- * @param $field
92
- */
93
- static function save( $new, $old, $post_id, $field )
94
- {
95
- delete_post_meta( $post_id, $field['id'] );
96
- parent::save( $new, array(), $post_id, $field );
97
- }
98
 
99
  /**
100
  * Enqueue scripts and styles
82
  );
83
  }
84
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
 
86
  /**
87
  * Enqueue scripts and styles
inc/fields/oembed.php CHANGED
@@ -3,7 +3,7 @@
3
  /**
4
  * oEmbed field class.
5
  */
6
- class RWMB_OEmbed_Field extends RWMB_URL_Field
7
  {
8
  /**
9
  * Enqueue scripts and styles
3
  /**
4
  * oEmbed field class.
5
  */
6
+ class RWMB_OEmbed_Field extends RWMB_Text_Field
7
  {
8
  /**
9
  * Enqueue scripts and styles
inc/fields/select-tree.php CHANGED
@@ -16,7 +16,7 @@ class RWMB_Select_Tree_Field extends RWMB_Select_Field
16
  */
17
  public static function walk( $field, $options, $db_fields, $meta )
18
  {
19
- $walker = new RWMB_Select_Tree_Walker( $db_fields, $field, $meta );
20
  return $walker->walk( $options );
21
  }
22
 
16
  */
17
  public static function walk( $field, $options, $db_fields, $meta )
18
  {
19
+ $walker = new RWMB_Walker_Select_Tree( $db_fields, $field, $meta );
20
  return $walker->walk( $options );
21
  }
22
 
inc/fields/select.php CHANGED
@@ -26,7 +26,7 @@ class RWMB_Select_Field extends RWMB_Choice_Field
26
  public static function walk( $field, $options, $db_fields, $meta )
27
  {
28
  $attributes = self::call( 'get_attributes', $field, $meta );
29
- $walker = new RWMB_Select_Walker( $db_fields, $field, $meta );
30
  $output = sprintf(
31
  '<select %s>',
32
  self::render_attributes( $attributes )
26
  public static function walk( $field, $options, $db_fields, $meta )
27
  {
28
  $attributes = self::call( 'get_attributes', $field, $meta );
29
+ $walker = new RWMB_Walker_Select( $db_fields, $field, $meta );
30
  $output = sprintf(
31
  '<select %s>',
32
  self::render_attributes( $attributes )
inc/fields/thickbox-image.php CHANGED
@@ -74,6 +74,6 @@ class RWMB_Thickbox_Image_Field extends RWMB_Image_Field
74
  */
75
  public static function value( $new, $old, $post_id, $field )
76
  {
77
- return array_unique( array_merge( $old, $new ) );
78
  }
79
  }
74
  */
75
  public static function value( $new, $old, $post_id, $field )
76
  {
77
+ return array_filter( array_unique( array_merge( (array) $old, (array) $new ) ) );
78
  }
79
  }
inc/fields/url.php DELETED
@@ -1,21 +0,0 @@
1
- <?php
2
- /**
3
- * HTML5 URL field class.
4
- */
5
- class RWMB_URL_Field extends RWMB_Text_Field
6
- {
7
- /**
8
- * Sanitize url
9
- *
10
- * @param mixed $new
11
- * @param mixed $old
12
- * @param int $post_id
13
- * @param array $field
14
- *
15
- * @return string
16
- */
17
- static function value( $new, $old, $post_id, $field )
18
- {
19
- return is_array( $new ) ? array_map( 'esc_url_raw', $new ) : esc_url_raw( $new );
20
- }
21
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/fields/wysiwyg.php CHANGED
@@ -31,20 +31,7 @@ class RWMB_Wysiwyg_Field extends RWMB_Field
31
  */
32
  static function value( $new, $old, $post_id, $field )
33
  {
34
- if ( $field['raw'] )
35
- {
36
- $meta = $new;
37
- }
38
- elseif ( $field['clone'] )
39
- {
40
- $meta = array_map( 'wpautop', $new );
41
- }
42
- else
43
- {
44
- $meta = wpautop( $new );
45
- }
46
-
47
- return $meta;
48
  }
49
 
50
  /**
31
  */
32
  static function value( $new, $old, $post_id, $field )
33
  {
34
+ return $field['raw'] ? $new : wpautop( $new );
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  }
36
 
37
  /**
inc/functions.php CHANGED
@@ -22,7 +22,8 @@ if ( ! function_exists( 'rwmb_meta' ) )
22
  * This is for backward compatibility with version < 4.8.0
23
  */
24
  $field = RWMB_Helper::find_field( $key, $post_id );
25
- if ( false === $field || isset( $args['type'] ) )
 
26
  {
27
  return apply_filters( 'rwmb_meta', RWMB_Helper::meta( $key, $args, $post_id ) );
28
  }
22
  * This is for backward compatibility with version < 4.8.0
23
  */
24
  $field = RWMB_Helper::find_field( $key, $post_id );
25
+
26
+ if ( false === $field && isset( $args['type'] ) )
27
  {
28
  return apply_filters( 'rwmb_meta', RWMB_Helper::meta( $key, $args, $post_id ) );
29
  }
inc/loader.php CHANGED
@@ -12,38 +12,15 @@
12
  */
13
  class RWMB_Loader
14
  {
15
- /**
16
- * Class constructor.
17
- */
18
- public function __construct()
19
- {
20
- $this->constants();
21
-
22
- /**
23
- * Register autoloader for plugin classes.
24
- * In PHP 5.3, SPL extension cannot be disabled and it's safe to use autoload.
25
- * However, hosting providers can disable it in PHP 5.2. In that case, we provide a fallback for autoload.
26
- * @link http://php.net/manual/en/spl.installation.php
27
- * @link https://github.com/rilwis/meta-box/issues/810
28
- */
29
- spl_autoload_register( array( $this, 'autoload' ) );
30
- if ( ! class_exists( 'RWMB_Core' ) )
31
- {
32
- $this->autoload_fallback();
33
- }
34
-
35
- $this->init();
36
- }
37
-
38
  /**
39
  * Define plugin constants.
40
  */
41
- public function constants()
42
  {
43
  // Script version, used to add version for scripts and styles
44
- define( 'RWMB_VER', '4.8.7' );
45
 
46
- list( $path, $url ) = self::get_path();
47
 
48
  // Plugin URLs, for fast enqueuing scripts and styles
49
  define( 'RWMB_URL', $url );
@@ -53,20 +30,18 @@ class RWMB_Loader
53
  // Plugin paths, for including files
54
  define( 'RWMB_DIR', $path );
55
  define( 'RWMB_INC_DIR', trailingslashit( RWMB_DIR . 'inc' ) );
56
- define( 'RWMB_FIELDS_DIR', trailingslashit( RWMB_INC_DIR . 'fields' ) );
57
  }
58
 
59
  /**
60
  * Get plugin base path and URL.
61
  * The method is static and can be used in extensions.
62
  * @link http://www.deluxeblogtips.com/2013/07/get-url-of-php-file-in-wordpress.html
63
- * @param string $base Base folder path
64
  * @return array Path and URL.
65
  */
66
- public static function get_path( $base = '' )
67
  {
68
  // Plugin base path
69
- $path = $base ? $base : dirname( dirname( __FILE__ ) );
70
  $path = wp_normalize_path( untrailingslashit( $path ) );
71
  $content_dir = wp_normalize_path( untrailingslashit( WP_CONTENT_DIR ) );
72
 
@@ -91,131 +66,21 @@ class RWMB_Loader
91
  }
92
 
93
  /**
94
- * Autoload fields' classes.
95
- * @param string $class Class name
96
  */
97
- public function autoload( $class )
98
- {
99
- // Only load plugin's classes
100
- if ( 'RW_Meta_Box' != $class && 0 !== strpos( $class, 'RWMB_' ) )
101
- {
102
- return;
103
- }
104
-
105
- // Get file name
106
- $file = 'meta-box';
107
- if ( 'RW_Meta_Box' != $class )
108
- {
109
- // Remove prefix 'RWMB_'
110
- $file = substr( $class, 5 );
111
-
112
- // Optional '_Field'
113
- $file = preg_replace( '/_Field$/', '', $file );
114
- }
115
-
116
- $file = strtolower( str_replace( '_', '-', $file ) ) . '.php';
117
-
118
- $dirs = array( RWMB_INC_DIR, RWMB_FIELDS_DIR, trailingslashit( RWMB_INC_DIR . 'walkers' ) );
119
- foreach ( $dirs as $dir )
120
- {
121
- if ( file_exists( $dir . $file ) )
122
- {
123
- require $dir . $file;
124
- return;
125
- }
126
- }
127
- }
128
-
129
- /**
130
- * Fallback for autoload in PHP 5.2.
131
- */
132
- public function autoload_fallback()
133
  {
134
- $files = array(
135
- // Core
136
- 'core',
137
- 'helper',
138
- 'meta-box',
139
- 'validation',
140
-
141
- // Walkers
142
- 'walkers/walker',
143
- 'walkers/select-walker',
144
- 'walkers/select-tree-walker',
145
- 'walkers/input-list-walker',
146
-
147
- // Fields
148
- 'field',
149
-
150
- 'fields/multiple-values',
151
- 'fields/autocomplete',
152
- 'fields/text-list',
153
-
154
- 'fields/choice',
155
-
156
- 'fields/select',
157
- 'fields/select-advanced',
158
- 'fields/select-tree',
159
-
160
- 'fields/input-list',
161
- 'fields/radio',
162
- 'fields/checkbox-list',
163
-
164
- 'fields/object-choice',
165
- 'fields/post',
166
- 'fields/taxonomy',
167
- 'fields/taxonomy-advanced',
168
- 'fields/user',
169
-
170
- 'fields/input',
171
-
172
- 'fields/checkbox',
173
- 'fields/number',
174
- 'fields/range',
175
-
176
- 'fields/text',
177
- 'fields/color',
178
- 'fields/datetime',
179
- 'fields/date',
180
- 'fields/time',
181
- 'fields/email',
182
- 'fields/fieldset-text',
183
- 'fields/key-value',
184
- 'fields/url',
185
- 'fields/oembed',
186
- 'fields/password',
187
-
188
- 'fields/media',
189
- 'fields/file-upload',
190
- 'fields/image-advanced',
191
- 'fields/image-upload',
192
-
193
- 'fields/file-input',
194
- 'fields/file',
195
- 'fields/image',
196
- 'fields/image-select',
197
- 'fields/thickbox-image',
198
 
199
- 'fields/button',
200
- 'fields/custom-html',
201
- 'fields/divider',
202
- 'fields/heading',
203
- 'fields/map',
204
- 'fields/slider',
205
- 'fields/textarea',
206
- 'fields/wysiwyg',
207
- );
208
- foreach ( $files as $file )
209
- {
210
- require RWMB_INC_DIR . "$file.php";
211
- }
212
- }
213
 
214
- /**
215
- * Initialize plugin.
216
- */
217
- public function init()
218
- {
219
  // Plugin core
220
  new RWMB_Core;
221
 
@@ -223,9 +88,12 @@ class RWMB_Loader
223
  {
224
  // Validation module
225
  new RWMB_Validation;
 
 
 
226
  }
227
 
228
  // Public functions
229
- require RWMB_INC_DIR . 'functions.php';
230
  }
231
  }
12
  */
13
  class RWMB_Loader
14
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  /**
16
  * Define plugin constants.
17
  */
18
+ protected function constants()
19
  {
20
  // Script version, used to add version for scripts and styles
21
+ define( 'RWMB_VER', '4.9' );
22
 
23
+ list( $path, $url ) = self::get_path( dirname( dirname( __FILE__ ) ) );
24
 
25
  // Plugin URLs, for fast enqueuing scripts and styles
26
  define( 'RWMB_URL', $url );
30
  // Plugin paths, for including files
31
  define( 'RWMB_DIR', $path );
32
  define( 'RWMB_INC_DIR', trailingslashit( RWMB_DIR . 'inc' ) );
 
33
  }
34
 
35
  /**
36
  * Get plugin base path and URL.
37
  * The method is static and can be used in extensions.
38
  * @link http://www.deluxeblogtips.com/2013/07/get-url-of-php-file-in-wordpress.html
39
+ * @param string $path Base folder path
40
  * @return array Path and URL.
41
  */
42
+ public static function get_path( $path = '' )
43
  {
44
  // Plugin base path
 
45
  $path = wp_normalize_path( untrailingslashit( $path ) );
46
  $content_dir = wp_normalize_path( untrailingslashit( WP_CONTENT_DIR ) );
47
 
66
  }
67
 
68
  /**
69
+ * Bootstrap the plugin.
 
70
  */
71
+ public function init()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  {
73
+ $this->constants();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
 
75
+ // Register autoload for classes
76
+ require_once RWMB_INC_DIR . 'autoloader.php';
77
+ $autoloader = new RWMB_Autoloader;
78
+ $autoloader->add( RWMB_INC_DIR, 'RW_' );
79
+ $autoloader->add( RWMB_INC_DIR, 'RWMB_' );
80
+ $autoloader->add( RWMB_INC_DIR . 'fields', 'RWMB_', '_Field' );
81
+ $autoloader->add( RWMB_INC_DIR . 'walkers', 'RWMB_Walker_' );
82
+ $autoloader->register();
 
 
 
 
 
 
83
 
 
 
 
 
 
84
  // Plugin core
85
  new RWMB_Core;
86
 
88
  {
89
  // Validation module
90
  new RWMB_Validation;
91
+
92
+ $sanitize = new RWMB_Sanitizer;
93
+ $sanitize->init();
94
  }
95
 
96
  // Public functions
97
+ require_once RWMB_INC_DIR . 'functions.php';
98
  }
99
  }
inc/meta-box.php CHANGED
@@ -49,8 +49,7 @@ class RW_Meta_Box
49
  add_action( 'admin_enqueue_scripts', array( $this, 'enqueue' ) );
50
 
51
  // Add additional actions for fields
52
- $fields = self::get_fields( $this->fields );
53
- foreach ( $fields as $field )
54
  {
55
  RWMB_Field::call( $field, 'add_actions' );
56
  }
@@ -91,8 +90,7 @@ class RW_Meta_Box
91
  wp_enqueue_style( 'rwmb-rtl', RWMB_CSS_URL . 'style-rtl.css', array(), RWMB_VER );
92
 
93
  // Load clone script conditionally
94
- $fields = self::get_fields( $this->fields );
95
- foreach ( $fields as $field )
96
  {
97
  if ( $field['clone'] )
98
  {
@@ -102,7 +100,7 @@ class RW_Meta_Box
102
  }
103
 
104
  // Enqueue scripts and styles for fields
105
- foreach ( $fields as $field )
106
  {
107
  RWMB_Field::call( $field, 'admin_enqueue_scripts' );
108
  }
@@ -118,24 +116,6 @@ class RW_Meta_Box
118
  do_action( 'rwmb_enqueue_scripts', $this );
119
  }
120
 
121
- /**
122
- * Get all fields of a meta box, recursively
123
- * @param array $fields
124
- * @return array
125
- */
126
- public static function get_fields( $fields )
127
- {
128
- $all_fields = array();
129
- foreach ( $fields as $field )
130
- {
131
- $all_fields[] = $field;
132
- if ( isset( $field['fields'] ) )
133
- $all_fields = array_merge( $all_fields, self::get_fields( $field['fields'] ) );
134
- }
135
-
136
- return $all_fields;
137
- }
138
-
139
  /**
140
  * Add meta box for multiple post types
141
  */
@@ -233,7 +213,15 @@ class RW_Meta_Box
233
  $new = isset( $_POST[$field['id']] ) ? $_POST[$field['id']] : ( $single ? '' : array() );
234
 
235
  // Allow field class change the value
236
- $new = RWMB_Field::call( $field, 'value', $new, $old, $post_id );
 
 
 
 
 
 
 
 
237
  $new = RWMB_Field::filter( 'value', $new, $field, $old );
238
 
239
  // Call defined method to save meta value, if there's no methods, call common one
@@ -287,15 +275,8 @@ class RW_Meta_Box
287
  $meta_box['post_types'] = $meta_box['pages'];
288
  }
289
 
290
- // Allow to set 'post_types' param by string
291
- if ( is_string( $meta_box['post_types'] ) )
292
- {
293
- $meta_box['post_types'] = array( $meta_box['post_types'] );
294
- }
295
-
296
- // Allow to add default values for meta box
297
- $meta_box = apply_filters( 'rwmb_normalize_meta_box', $meta_box );
298
- $meta_box = apply_filters( "rwmb_normalize_{$meta_box['id']}_meta_box", $meta_box );
299
 
300
  return $meta_box;
301
  }
@@ -311,9 +292,6 @@ class RW_Meta_Box
311
  {
312
  $field = RWMB_Field::call( 'normalize', $field );
313
 
314
- if ( isset( $field['fields'] ) )
315
- $field['fields'] = self::normalize_fields( $field['fields'] );
316
-
317
  // Allow to add default values for fields
318
  $field = apply_filters( 'rwmb_normalize_field', $field );
319
  $field = apply_filters( "rwmb_normalize_{$field['type']}_field", $field );
@@ -325,16 +303,6 @@ class RW_Meta_Box
325
  return $fields;
326
  }
327
 
328
- /**
329
- * Get field class name. Only for backward compatibility.
330
- * @param array $field Field array
331
- * @return string Field class name
332
- */
333
- public static function get_class_name( $field )
334
- {
335
- return RWMB_Field::get_class_name( $field );
336
- }
337
-
338
  /**
339
  * Check if meta box is saved before.
340
  * This helps saving empty value in meta fields (text, check box, etc.) and set the correct default values.
49
  add_action( 'admin_enqueue_scripts', array( $this, 'enqueue' ) );
50
 
51
  // Add additional actions for fields
52
+ foreach ( $this->fields as $field )
 
53
  {
54
  RWMB_Field::call( $field, 'add_actions' );
55
  }
90
  wp_enqueue_style( 'rwmb-rtl', RWMB_CSS_URL . 'style-rtl.css', array(), RWMB_VER );
91
 
92
  // Load clone script conditionally
93
+ foreach ( $this->fields as $field )
 
94
  {
95
  if ( $field['clone'] )
96
  {
100
  }
101
 
102
  // Enqueue scripts and styles for fields
103
+ foreach ( $this->fields as $field )
104
  {
105
  RWMB_Field::call( $field, 'admin_enqueue_scripts' );
106
  }
116
  do_action( 'rwmb_enqueue_scripts', $this );
117
  }
118
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
  /**
120
  * Add meta box for multiple post types
121
  */
213
  $new = isset( $_POST[$field['id']] ) ? $_POST[$field['id']] : ( $single ? '' : array() );
214
 
215
  // Allow field class change the value
216
+ if ( $field['clone'] )
217
+ {
218
+ $new = RWMB_Clone::value( $new, $old, $post_id, $field );
219
+ }
220
+ else
221
+ {
222
+ $new = RWMB_Field::call( $field, 'value', $new, $old, $post_id );
223
+ $new = RWMB_Field::filter( 'sanitize', $new, $field );
224
+ }
225
  $new = RWMB_Field::filter( 'value', $new, $field, $old );
226
 
227
  // Call defined method to save meta value, if there's no methods, call common one
275
  $meta_box['post_types'] = $meta_box['pages'];
276
  }
277
 
278
+ // Make sure the post type is an array.
279
+ $meta_box['post_types'] = (array) $meta_box['post_types'];
 
 
 
 
 
 
 
280
 
281
  return $meta_box;
282
  }
292
  {
293
  $field = RWMB_Field::call( 'normalize', $field );
294
 
 
 
 
295
  // Allow to add default values for fields
296
  $field = apply_filters( 'rwmb_normalize_field', $field );
297
  $field = apply_filters( "rwmb_normalize_{$field['type']}_field", $field );
303
  return $fields;
304
  }
305
 
 
 
 
 
 
 
 
 
 
 
306
  /**
307
  * Check if meta box is saved before.
308
  * This helps saving empty value in meta fields (text, check box, etc.) and set the correct default values.
inc/sanitizer.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Sanitize field value before saving.
4
+ * @package Meta Box
5
+ */
6
+
7
+ /**
8
+ * Sanitize class.
9
+ */
10
+ class RWMB_Sanitizer
11
+ {
12
+ /**
13
+ * Built-in callbacks for some specific types.
14
+ * @var array
15
+ */
16
+ protected $callbacks = array(
17
+ 'email' => 'sanitize_email',
18
+ 'file_input' => 'esc_url_raw',
19
+ 'oembed' => 'esc_url_raw',
20
+ 'url' => 'esc_url_raw',
21
+ );
22
+
23
+ /**
24
+ * Register hook to sanitize field value.
25
+ */
26
+ public function init()
27
+ {
28
+ // Built-in callback
29
+ foreach ( $this->callbacks as $type => $callback )
30
+ {
31
+ add_filter( "rwmb_{$type}_sanitize", $callback );
32
+ }
33
+
34
+ // Custom callback
35
+ $types = array_diff( get_class_methods( __CLASS__ ), array( 'init' ) );
36
+ foreach ( $types as $type )
37
+ {
38
+ add_filter( "rwmb_{$type}_sanitize", array( $this, $type ) );
39
+ }
40
+ }
41
+
42
+ /**
43
+ * Set the value of checkbox to 1 or 0 instead of 'checked' and empty string.
44
+ * This prevents using default value once the checkbox has been unchecked.
45
+ * @link https://github.com/rilwis/meta-box/issues/6
46
+ * @param string $value
47
+ * @return int
48
+ */
49
+ public function checkbox( $value )
50
+ {
51
+ return (int) ! empty( $value );
52
+ }
53
+ }
inc/templates/upload.php CHANGED
@@ -1,7 +1,7 @@
1
  <script id="tmpl-rwmb-upload-area" type="text/html">
2
  <div class="rwmb-upload-inside">
3
- <h3>{{{ i18nRwmbMedia.uploadInstructions }}}</h3>
4
- <p> or</p>
5
- <p><a href="#" class="rwmb-browse-button button button-hero" id="{{{ _.uniqueId( 'rwmb-upload-browser-') }}}">{{{ i18nRwmbMedia.select }}}</a></p>
6
  </div>
7
  </script>
1
  <script id="tmpl-rwmb-upload-area" type="text/html">
2
  <div class="rwmb-upload-inside">
3
+ <h3>{{{ i18nRwmbMedia.uploadInstructions }}}</h3>
4
+ <p>{{{ i18nRwmbMedia.or }}}</p>
5
+ <p><a href="#" class="rwmb-browse-button button button-hero" id="{{{ _.uniqueId( 'rwmb-upload-browser-') }}}">{{{ i18nRwmbMedia.select }}}</a></p>
6
  </div>
7
  </script>
inc/validation.php CHANGED
@@ -23,7 +23,7 @@ class RWMB_Validation
23
  * The rules are outputted in [data-rules] attribute of an hidden <script> and will be converted into JSON by JS.
24
  * @param RW_Meta_Box $object Meta Box object
25
  */
26
- public function rules( RW_Meta_Box $object )
27
  {
28
  if ( ! empty( $object->meta_box['validation'] ) )
29
  {
@@ -33,10 +33,16 @@ class RWMB_Validation
33
 
34
  /**
35
  * Enqueue scripts for validation.
 
36
  */
37
- public function enqueue()
38
  {
39
- wp_enqueue_script( 'jquery-validate', RWMB_JS_URL . 'jquery.validate.min.js', array( 'jquery' ), RWMB_VER, true );
 
 
 
 
 
40
  wp_enqueue_script( 'rwmb-validate', RWMB_JS_URL . 'validate.js', array( 'jquery-validate' ), RWMB_VER, true );
41
  /**
42
  * Prevent loading localized string twice.
23
  * The rules are outputted in [data-rules] attribute of an hidden <script> and will be converted into JSON by JS.
24
  * @param RW_Meta_Box $object Meta Box object
25
  */
26
+ public function rules( $object )
27
  {
28
  if ( ! empty( $object->meta_box['validation'] ) )
29
  {
33
 
34
  /**
35
  * Enqueue scripts for validation.
36
+ * @param RW_Meta_Box $object Meta Box object
37
  */
38
+ public function enqueue( $object )
39
  {
40
+ if ( empty( $object->meta_box['validation'] ) )
41
+ {
42
+ return;
43
+ }
44
+ wp_enqueue_script( 'jquery-validation', RWMB_JS_URL . 'jquery-validation/jquery.validate.min.js', array( 'jquery' ), '1.15.0', true );
45
+ wp_enqueue_script( 'jquery-validation-additional-methods', RWMB_JS_URL . 'jquery-validation/additional-methods.min.js', array( 'jquery-validation' ), '1.15.0', true );
46
  wp_enqueue_script( 'rwmb-validate', RWMB_JS_URL . 'validate.js', array( 'jquery-validate' ), RWMB_VER, true );
47
  /**
48
  * Prevent loading localized string twice.
inc/walkers/{walker.php → base.php} RENAMED
@@ -3,7 +3,7 @@
3
  * Base Walker
4
  * Walkers must inherit this class and overwrite methods with its own.
5
  */
6
- abstract class RWMB_Walker extends Walker
7
  {
8
  /**
9
  * Field data.
3
  * Base Walker
4
  * Walkers must inherit this class and overwrite methods with its own.
5
  */
6
+ abstract class RWMB_Walker_Base extends Walker
7
  {
8
  /**
9
  * Field data.
inc/walkers/{input-list-walker.php → input-list.php} RENAMED
@@ -4,7 +4,7 @@
4
  * Input List Walker
5
  * For checkbox and radio list fields
6
  */
7
- class RWMB_Input_List_Walker extends RWMB_Walker
8
  {
9
  /**
10
  * @see Walker::start_lvl()
4
  * Input List Walker
5
  * For checkbox and radio list fields
6
  */
7
+ class RWMB_Walker_Input_List extends RWMB_Walker_Base
8
  {
9
  /**
10
  * @see Walker::start_lvl()
inc/walkers/{select-tree-walker.php → select-tree.php} RENAMED
@@ -2,9 +2,9 @@
2
 
3
  /**
4
  * Select Tree Walker for cascading select fields.
5
- * @uses RWMB_Select_Walker
6
  */
7
- class RWMB_Select_Tree_Walker
8
  {
9
  /**
10
  * Field data.
@@ -46,7 +46,7 @@ class RWMB_Select_Tree_Walker
46
  {
47
  $id = $this->db_fields['id'];
48
  $field = $this->field;
49
- $walker = new RWMB_Select_Walker( $this->db_fields, $field, $this->meta );
50
  $attributes = RWMB_Field::call( 'get_attributes', $field, $this->meta );
51
 
52
  $children = $options[$parent_id];
2
 
3
  /**
4
  * Select Tree Walker for cascading select fields.
5
+ * @uses RWMB_Walker_Select
6
  */
7
+ class RWMB_Walker_Select_Tree
8
  {
9
  /**
10
  * Field data.
46
  {
47
  $id = $this->db_fields['id'];
48
  $field = $this->field;
49
+ $walker = new RWMB_Walker_Select( $this->db_fields, $field, $this->meta );
50
  $attributes = RWMB_Field::call( 'get_attributes', $field, $this->meta );
51
 
52
  $children = $options[$parent_id];
inc/walkers/{select-walker.php → select.php} RENAMED
@@ -3,7 +3,7 @@
3
  * Select Walker
4
  * For generating Select fields
5
  */
6
- class RWMB_Select_Walker extends RWMB_Walker
7
  {
8
  /**
9
  * @see Walker::start_el()
3
  * Select Walker
4
  * For generating Select fields
5
  */
6
+ class RWMB_Walker_Select extends RWMB_Walker_Base
7
  {
8
  /**
9
  * @see Walker::start_el()
inc/wpml.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * WPML compatibility class
5
+ */
6
+ class RWMB_WPML {
7
+
8
+ /**
9
+ * Register hooks.
10
+ */
11
+ public function __construct() {
12
+ add_filter( 'wpml_duplicate_generic_string', array( $this, 'wpml_translate_values' ), 10, 3 );
13
+ }
14
+
15
+ /**
16
+ * Translating IDs stored as field values upon WPML post/page duplication.
17
+ *
18
+ * @param $value
19
+ * @param $target_language
20
+ * @param $meta_data
21
+ * @return mixed
22
+ */
23
+ public function wpml_translate_values( $value, $target_language, $meta_data ) {
24
+ $fields = RWMB_Core::get_fields();
25
+
26
+ foreach ( $fields as $field ) {
27
+ if ( in_array( $field['type'], array( 'post', 'taxonomy_advanced' ) ) && $field['id'] === $meta_data['key'] ) {
28
+ // Post type needed for WPML filter differs between fields
29
+ $post_type = $field['type'] === 'taxonomy_advanced' ? $field['taxonomy'] : $field['post_type'];
30
+
31
+ // Translating values, whether are stored as comma separated strings or not.
32
+ if ( ( strpos( $value, ',' ) === false ) ) {
33
+ $value = apply_filters( 'wpml_object_id', $value, $post_type, true, $target_language );
34
+ }
35
+ else {
36
+ // Dealing with IDs stored as comma separated strings
37
+ $translated_values = array();
38
+ $values = explode( ',', $value );
39
+
40
+ foreach ( $values as $v ) {
41
+ $translated_values[] = apply_filters( 'wpml_object_id', $v, $post_type, true, $target_language );
42
+ }
43
+
44
+ $value = implode( ',', $translated_values );
45
+ }
46
+ }
47
+ }
48
+
49
+ return $value;
50
+ }
51
+ }
js/clone.js CHANGED
@@ -140,8 +140,14 @@ jQuery( function ( $ )
140
  */
141
  function toggleRemoveButtons( $container )
142
  {
143
- var $button = $container.find( '.remove-clone' );
144
- $button.toggle( $button.length > 1 );
 
 
 
 
 
 
145
  }
146
 
147
  /**
@@ -182,7 +188,7 @@ jQuery( function ( $ )
182
  $container = $this.closest( '.rwmb-input' );
183
 
184
  // Remove clone only if there are 2 or more of them
185
- if ( $container.find( '.rwmb-clone' ).length < 2 )
186
  {
187
  return;
188
  }
140
  */
141
  function toggleRemoveButtons( $container )
142
  {
143
+ var $clones = $container.children( '.rwmb-clone' );
144
+ $clones.children( '.remove-clone' ).toggle( $clones.length > 1 );
145
+
146
+ // Recursive for nested groups.
147
+ $container.find( '.rwmb-input' ).each( function ()
148
+ {
149
+ toggleRemoveButtons( $( this ) );
150
+ } );
151
  }
152
 
153
  /**
188
  $container = $this.closest( '.rwmb-input' );
189
 
190
  // Remove clone only if there are 2 or more of them
191
+ if ( $container.children( '.rwmb-clone' ).length < 2 )
192
  {
193
  return;
194
  }
js/date.js CHANGED
@@ -12,13 +12,13 @@ jQuery( function ( $ )
12
  options = $this.data( 'options' ),
13
  $inline = $this.siblings( '.rwmb-datetime-inline' ),
14
  $timestamp = $this.siblings( '.rwmb-datetime-timestamp' ),
15
- current = $this.val();
 
16
 
17
  $this.siblings( '.ui-datepicker-append' ).remove(); // Remove appended text
18
  if ( $timestamp.length )
19
  {
20
- var $picker = $inline.length ? $inline : $this;
21
- options.onClose = function ()
22
  {
23
  $timestamp.val( getTimestamp( $picker.datepicker( 'getDate' ) ) );
24
  };
@@ -27,6 +27,13 @@ jQuery( function ( $ )
27
  if ( $inline.length )
28
  {
29
  options.altField = '#' + $this.attr( 'id' );
 
 
 
 
 
 
 
30
  $inline
31
  .removeClass( 'hasDatepicker' )
32
  .empty()
@@ -54,6 +61,7 @@ jQuery( function ( $ )
54
  return Math.floor( milliseconds / 1000 );
55
  }
56
 
 
57
  if ( $.datepicker.regional.hasOwnProperty( RWMB_Date.locale ) )
58
  {
59
  $.datepicker.setDefaults( $.datepicker.regional[RWMB_Date.locale] );
12
  options = $this.data( 'options' ),
13
  $inline = $this.siblings( '.rwmb-datetime-inline' ),
14
  $timestamp = $this.siblings( '.rwmb-datetime-timestamp' ),
15
+ current = $this.val(),
16
+ $picker = $inline.length ? $inline : $this;
17
 
18
  $this.siblings( '.ui-datepicker-append' ).remove(); // Remove appended text
19
  if ( $timestamp.length )
20
  {
21
+ options.onClose = options.onSelect = function ()
 
22
  {
23
  $timestamp.val( getTimestamp( $picker.datepicker( 'getDate' ) ) );
24
  };
27
  if ( $inline.length )
28
  {
29
  options.altField = '#' + $this.attr( 'id' );
30
+ $this.on( 'keydown', _.debounce( function(){
31
+ $picker
32
+ .datepicker( 'setDate', $this.val() )
33
+ .find(".ui-datepicker-current-day")
34
+ .trigger("click");
35
+ }, 600 ) );
36
+
37
  $inline
38
  .removeClass( 'hasDatepicker' )
39
  .empty()
61
  return Math.floor( milliseconds / 1000 );
62
  }
63
 
64
+ $.datepicker.setDefaults( $.datepicker.regional[ "" ] );
65
  if ( $.datepicker.regional.hasOwnProperty( RWMB_Date.locale ) )
66
  {
67
  $.datepicker.setDefaults( $.datepicker.regional[RWMB_Date.locale] );
js/datetime.js CHANGED
@@ -12,13 +12,13 @@ jQuery( function ( $ )
12
  options = $this.data( 'options' ),
13
  $inline = $this.siblings( '.rwmb-datetime-inline' ),
14
  $timestamp = $this.siblings( '.rwmb-datetime-timestamp' ),
15
- current = $this.val();
 
16
 
17
  $this.siblings( '.ui-datepicker-append' ).remove(); // Remove appended text
18
  if ( $timestamp.length )
19
  {
20
- var $picker = $inline.length ? $inline : $this;
21
- options.onClose = function ()
22
  {
23
  $timestamp.val( getTimestamp( $picker.datetimepicker( 'getDate' ) ) );
24
  };
@@ -27,6 +27,13 @@ jQuery( function ( $ )
27
  if ( $inline.length )
28
  {
29
  options.altField = '#' + $this.attr( 'id' );
 
 
 
 
 
 
 
30
  $inline
31
  .removeClass( 'hasDatepicker' )
32
  .empty()
@@ -55,6 +62,7 @@ jQuery( function ( $ )
55
  }
56
 
57
  // Set language if available
 
58
  if ( $.datepicker.regional.hasOwnProperty( RWMB_Datetime.locale ) )
59
  {
60
  $.datepicker.setDefaults( $.datepicker.regional[RWMB_Datetime.locale] );
@@ -63,6 +71,7 @@ jQuery( function ( $ )
63
  {
64
  $.datepicker.setDefaults( $.datepicker.regional[RWMB_Datetime.localeShort] );
65
  }
 
66
  if ( $.timepicker.regional.hasOwnProperty( RWMB_Datetime.locale ) )
67
  {
68
  $.timepicker.setDefaults( $.timepicker.regional[RWMB_Datetime.locale] );
12
  options = $this.data( 'options' ),
13
  $inline = $this.siblings( '.rwmb-datetime-inline' ),
14
  $timestamp = $this.siblings( '.rwmb-datetime-timestamp' ),
15
+ current = $this.val(),
16
+ $picker = $inline.length ? $inline : $this;
17
 
18
  $this.siblings( '.ui-datepicker-append' ).remove(); // Remove appended text
19
  if ( $timestamp.length )
20
  {
21
+ options.onClose = options.onSelect = function ()
 
22
  {
23
  $timestamp.val( getTimestamp( $picker.datetimepicker( 'getDate' ) ) );
24
  };
27
  if ( $inline.length )
28
  {
29
  options.altField = '#' + $this.attr( 'id' );
30
+ $this.on( 'keydown', _.debounce( function(){
31
+ $picker
32
+ .datepicker( 'setDate', $this.val() )
33
+ .find(".ui-datepicker-current-day")
34
+ .trigger("click");
35
+ }, 600 ) );
36
+
37
  $inline
38
  .removeClass( 'hasDatepicker' )
39
  .empty()
62
  }
63
 
64
  // Set language if available
65
+ $.datepicker.setDefaults( $.datepicker.regional[ "" ] );
66
  if ( $.datepicker.regional.hasOwnProperty( RWMB_Datetime.locale ) )
67
  {
68
  $.datepicker.setDefaults( $.datepicker.regional[RWMB_Datetime.locale] );
71
  {
72
  $.datepicker.setDefaults( $.datepicker.regional[RWMB_Datetime.localeShort] );
73
  }
74
+ $.timepicker.setDefaults( $.timepicker.regional[ "" ] );
75
  if ( $.timepicker.regional.hasOwnProperty( RWMB_Datetime.locale ) )
76
  {
77
  $.timepicker.setDefaults( $.timepicker.regional[RWMB_Datetime.locale] );
js/jquery-validation/additional-methods.min.js ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ /*! jQuery Validation Plugin - v1.15.0 - 2/24/2016
2
+ * http://jqueryvalidation.org/
3
+ * Copyright (c) 2016 Jörn Zaefferer; Licensed MIT */
4
+ !function(a){"function"==typeof define&&define.amd?define(["jquery","./jquery.validate.min"],a): "object" == typeof module && module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){!function(){function b(a){return a.replace(/<.[^<>]*?>/g," ").replace(/&nbsp;|&#160;/gi," ").replace(/[.(),;:!?%#$'\"_+=\/\-“”’]*/g,"")}a.validator.addMethod("maxWords",function(a,c,d){return this.optional(c) || b(a).match(/\b\w+\b/g).length <= d},a.validator.format("Please enter {0} words or less.")),a.validator.addMethod("minWords",function(a,c,d){return this.optional(c) || b(a).match(/\b\w+\b/g).length >= d},a.validator.format("Please enter at least {0} words.")),a.validator.addMethod("rangeWords",function(a,c,d){var e=b(a),f=/\b\w+\b/g;return this.optional(c)||e.match(f).length>=d[0]&&e.match(f).length<=d[1]},a.validator.format("Please enter between {0} and {1} words."))}(),a.validator.addMethod("accept",function(b,c,d){var e,f,g,h="string"==typeof d?d.replace(/\s/g,""):"image/*",i=this.optional(c);if(i)return i;if("file"===a(c).attr("type")&&(h=h.replace(/[\-\[\]\/\{\}\(\)\+\?\.\\\^\$\|]/g,"\\$&").replace(/,/g,"|").replace("/*","/.*"),c.files&&c.files.length))for(g=new RegExp(".?("+h+")$","i"),e=0;e<c.files.length;e++)if(f=c.files[e],!f.type.match(g))return!1;return!0},a.validator.format("Please enter a value with a valid mimetype.")),a.validator.addMethod("alphanumeric",function(a,b){return this.optional(b)||/^\w+$/i.test(a)},"Letters, numbers, and underscores only please"),a.validator.addMethod("bankaccountNL",function(a,b){if(this.optional(b))return!0;if(!/^[0-9]{9}|([0-9]{2} ){3}[0-9]{3}$/.test(a))return!1;var c,d,e,f=a.replace(/ /g,""),g=0,h=f.length;for(c=0;h>c;c++)d=h-c,e=f.substring(c,c+1),g+=d*e;return g%11===0},"Please specify a valid bank account number"),a.validator.addMethod("bankorgiroaccountNL",function(b,c){return this.optional(c)||a.validator.methods.bankaccountNL.call(this,b,c)||a.validator.methods.giroaccountNL.call(this,b,c)},"Please specify a valid bank or giro account number"),a.validator.addMethod("bic",function(a,b){return this.optional(b)||/^([A-Z]{6}[A-Z2-9][A-NP-Z1-9])(X{3}|[A-WY-Z0-9][A-Z0-9]{2})?$/.test(a.toUpperCase())},"Please specify a valid BIC code"),a.validator.addMethod("cifES",function(a){"use strict";var b,c,d,e,f,g,h=[];if(a=a.toUpperCase(),!a.match("((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)"))return!1;for(d=0;9>d;d++)h[d]=parseInt(a.charAt(d),10);for(c=h[2]+h[4]+h[6],e=1;8>e;e+=2)f=(2*h[e]).toString(),g=f.charAt(1),c+=parseInt(f.charAt(0),10)+(""===g?0:parseInt(g,10));return/^[ABCDEFGHJNPQRSUVW]{1}/.test(a)?(c+="",b=10-parseInt(c.charAt(c.length-1),10),a+=b,h[8].toString()===String.fromCharCode(64+b)||h[8].toString()===a.charAt(a.length-1)):!1},"Please specify a valid CIF number."),a.validator.addMethod("cpfBR",function(a){if(a=a.replace(/([~!@#$%^&*()_+=`{}\[\]\-|\\:;'<>,.\/? ])+/g,""),11!==a.length)return!1;var b,c,d,e,f=0;if(b=parseInt(a.substring(9,10),10),c=parseInt(a.substring(10,11),10),d=function(a,b){var c=10*a%11;return 10!==c&&11!==c||(c=0),c===b},""===a||"00000000000"===a||"11111111111"===a||"22222222222"===a||"33333333333"===a||"44444444444"===a||"55555555555"===a||"66666666666"===a||"77777777777"===a||"88888888888"===a||"99999999999"===a)return!1;for(e=1;9>=e;e++)f+=parseInt(a.substring(e-1,e),10)*(11-e);if(d(f,b)){for(f=0,e=1;10>=e;e++)f+=parseInt(a.substring(e-1,e),10)*(12-e);return d(f,c)}return!1},"Please specify a valid CPF number"),a.validator.addMethod("creditcard",function(a,b){if(this.optional(b))return"dependency-mismatch";if(/[^0-9 \-]+/.test(a))return!1;var c,d,e=0,f=0,g=!1;if(a=a.replace(/\D/g,""),a.length<13||a.length>19)return!1;for(c=a.length-1;c>=0;c--)d=a.charAt(c),f=parseInt(d,10),g&&(f*=2)>9&&(f-=9),e+=f,g=!g;return e%10===0},"Please enter a valid credit card number."),a.validator.addMethod("creditcardtypes",function(a,b,c){if(/[^0-9\-]+/.test(a))return!1;a=a.replace(/\D/g,"");var d=0;return c.mastercard&&(d|=1),c.visa&&(d|=2),c.amex&&(d|=4),c.dinersclub&&(d|=8),c.enroute&&(d|=16),c.discover&&(d|=32),c.jcb&&(d|=64),c.unknown&&(d|=128),c.all&&(d=255),1&d&&/^(5[12345])/.test(a)?16===a.length:2&d&&/^(4)/.test(a)?16===a.length:4&d&&/^(3[47])/.test(a)?15===a.length:8&d&&/^(3(0[012345]|[68]))/.test(a)?14===a.length:16&d&&/^(2(014|149))/.test(a)?15===a.length:32&d&&/^(6011)/.test(a)?16===a.length:64&d&&/^(3)/.test(a)?16===a.length:64&d&&/^(2131|1800)/.test(a)?15===a.length:!!(128&d)},"Please enter a valid credit card number."),a.validator.addMethod("currency",function(a,b,c){var d,e="string"==typeof c,f=e?c:c[0],g=e?!0:c[1];return f=f.replace(/,/g,""),f=g?f+"]":f+"]?",d="^["+f+"([1-9]{1}[0-9]{0,2}(\\,[0-9]{3})*(\\.[0-9]{0,2})?|[1-9]{1}[0-9]{0,}(\\.[0-9]{0,2})?|0(\\.[0-9]{0,2})?|(\\.[0-9]{1,2})?)$",d=new RegExp(d),this.optional(b)||d.test(a)},"Please specify a valid currency"),a.validator.addMethod("dateFA",function(a,b){return this.optional(b)||/^[1-4]\d{3}\/((0?[1-6]\/((3[0-1])|([1-2][0-9])|(0?[1-9])))|((1[0-2]|(0?[7-9]))\/(30|([1-2][0-9])|(0?[1-9]))))$/.test(a)},a.validator.messages.date),a.validator.addMethod("dateITA",function(a,b){var c,d,e,f,g,h=!1,i=/^\d{1,2}\/\d{1,2}\/\d{4}$/;return i.test(a)?(c=a.split("/"),d=parseInt(c[0],10),e=parseInt(c[1],10),f=parseInt(c[2],10),g=new Date(Date.UTC(f,e-1,d,12,0,0,0)),h=g.getUTCFullYear()===f&&g.getUTCMonth()===e-1&&g.getUTCDate()===d):h=!1,this.optional(b)||h},a.validator.messages.date),a.validator.addMethod("dateNL",function(a,b){return this.optional(b)||/^(0?[1-9]|[12]\d|3[01])[\.\/\-](0?[1-9]|1[012])[\.\/\-]([12]\d)?(\d\d)$/.test(a)},a.validator.messages.date),a.validator.addMethod("extension",function(a,b,c){return c="string"==typeof c?c.replace(/,/g,"|"):"png|jpe?g|gif",this.optional(b)||a.match(new RegExp("\\.("+c+")$","i"))},a.validator.format("Please enter a value with a valid extension.")),a.validator.addMethod("giroaccountNL",function(a,b){return this.optional(b)||/^[0-9]{1,7}$/.test(a)},"Please specify a valid giro account number"),a.validator.addMethod("iban",function(a,b){if(this.optional(b))return!0;var c,d,e,f,g,h,i,j,k,l=a.replace(/ /g,"").toUpperCase(),m="",n=!0,o="",p="";if(c=l.substring(0,2),h={AL:"\\d{8}[\\dA-Z]{16}",AD:"\\d{8}[\\dA-Z]{12}",AT:"\\d{16}",AZ:"[\\dA-Z]{4}\\d{20}",BE:"\\d{12}",BH:"[A-Z]{4}[\\dA-Z]{14}",BA:"\\d{16}",BR:"\\d{23}[A-Z][\\dA-Z]",BG:"[A-Z]{4}\\d{6}[\\dA-Z]{8}",CR:"\\d{17}",HR:"\\d{17}",CY:"\\d{8}[\\dA-Z]{16}",CZ:"\\d{20}",DK:"\\d{14}",DO:"[A-Z]{4}\\d{20}",EE:"\\d{16}",FO:"\\d{14}",FI:"\\d{14}",FR:"\\d{10}[\\dA-Z]{11}\\d{2}",GE:"[\\dA-Z]{2}\\d{16}",DE:"\\d{18}",GI:"[A-Z]{4}[\\dA-Z]{15}",GR:"\\d{7}[\\dA-Z]{16}",GL:"\\d{14}",GT:"[\\dA-Z]{4}[\\dA-Z]{20}",HU:"\\d{24}",IS:"\\d{22}",IE:"[\\dA-Z]{4}\\d{14}",IL:"\\d{19}",IT:"[A-Z]\\d{10}[\\dA-Z]{12}",KZ:"\\d{3}[\\dA-Z]{13}",KW:"[A-Z]{4}[\\dA-Z]{22}",LV:"[A-Z]{4}[\\dA-Z]{13}",LB:"\\d{4}[\\dA-Z]{20}",LI:"\\d{5}[\\dA-Z]{12}",LT:"\\d{16}",LU:"\\d{3}[\\dA-Z]{13}",MK:"\\d{3}[\\dA-Z]{10}\\d{2}",MT:"[A-Z]{4}\\d{5}[\\dA-Z]{18}",MR:"\\d{23}",MU:"[A-Z]{4}\\d{19}[A-Z]{3}",MC:"\\d{10}[\\dA-Z]{11}\\d{2}",MD:"[\\dA-Z]{2}\\d{18}",ME:"\\d{18}",NL:"[A-Z]{4}\\d{10}",NO:"\\d{11}",PK:"[\\dA-Z]{4}\\d{16}",PS:"[\\dA-Z]{4}\\d{21}",PL:"\\d{24}",PT:"\\d{21}",RO:"[A-Z]{4}[\\dA-Z]{16}",SM:"[A-Z]\\d{10}[\\dA-Z]{12}",SA:"\\d{2}[\\dA-Z]{18}",RS:"\\d{18}",SK:"\\d{20}",SI:"\\d{15}",ES:"\\d{20}",SE:"\\d{20}",CH:"\\d{5}[\\dA-Z]{12}",TN:"\\d{20}",TR:"\\d{5}[\\dA-Z]{17}",AE:"\\d{3}\\d{16}",GB:"[A-Z]{4}\\d{14}",VG:"[\\dA-Z]{4}\\d{16}"},g=h[c],"undefined"!=typeof g&&(i=new RegExp("^[A-Z]{2}\\d{2}"+g+"$",""),!i.test(l)))return!1;for(d=l.substring(4,l.length)+l.substring(0,4),j=0;j<d.length;j++)e=d.charAt(j),"0"!==e&&(n=!1),n||(m+="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".indexOf(e));for(k=0;k<m.length;k++)f=m.charAt(k),p=""+o+f,o=p%97;return 1===o},"Please specify a valid IBAN"),a.validator.addMethod("integer",function(a,b){return this.optional(b)||/^-?\d+$/.test(a)},"A positive or negative non-decimal number please"),a.validator.addMethod("ipv4",function(a,b){return this.optional(b)||/^(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)$/i.test(a)},"Please enter a valid IP v4 address."),a.validator.addMethod("ipv6",function(a,b){return this.optional(b)||/^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/i.test(a)},"Please enter a valid IP v6 address."),a.validator.addMethod("lettersonly",function(a,b){return this.optional(b)||/^[a-z]+$/i.test(a)},"Letters only please"),a.validator.addMethod("letterswithbasicpunc",function(a,b){return this.optional(b)||/^[a-z\-.,()'"\s]+$/i.test(a)},"Letters or punctuation only please"),a.validator.addMethod("mobileNL",function(a,b){return this.optional(b)||/^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)6((\s|\s?\-\s?)?[0-9]){8}$/.test(a)},"Please specify a valid mobile number"),a.validator.addMethod("mobileUK",function(a,b){return a=a.replace(/\(|\)|\s+|-/g,""),this.optional(b)||a.length>9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?|0)7(?:[1345789]\d{2}|624)\s?\d{3}\s?\d{3})$/)},"Please specify a valid mobile number"),a.validator.addMethod("nieES",function(a){"use strict";return a=a.toUpperCase(),a.match("((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)")?/^[T]{1}/.test(a)?a[8]===/^[T]{1}[A-Z0-9]{8}$/.test(a):/^[XYZ]{1}/.test(a)?a[8]==="TRWAGMYFPDXBNJZSQVHLCKE".charAt(a.replace("X","0").replace("Y","1").replace("Z","2").substring(0,8)%23):!1:!1},"Please specify a valid NIE number."),a.validator.addMethod("nifES",function(a){"use strict";return a=a.toUpperCase(),a.match("((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)")?/^[0-9]{8}[A-Z]{1}$/.test(a)?"TRWAGMYFPDXBNJZSQVHLCKE".charAt(a.substring(8,0)%23)===a.charAt(8):/^[KLM]{1}/.test(a)?a[8]===String.fromCharCode(64):!1:!1},"Please specify a valid NIF number."),jQuery.validator.addMethod("notEqualTo",function(b,c,d){return this.optional(c)||!a.validator.methods.equalTo.call(this,b,c,d)},"Please enter a different value, values must not be the same."),a.validator.addMethod("nowhitespace",function(a,b){return this.optional(b)||/^\S+$/i.test(a)},"No white space please"),a.validator.addMethod("pattern",function(a,b,c){return this.optional(b)?!0:("string"==typeof c&&(c=new RegExp("^(?:"+c+")$")),c.test(a))},"Invalid format."),a.validator.addMethod("phoneNL",function(a,b){return this.optional(b)||/^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)[1-9]((\s|\s?\-\s?)?[0-9]){8}$/.test(a)},"Please specify a valid phone number."),a.validator.addMethod("phoneUK",function(a,b){return a=a.replace(/\(|\)|\s+|-/g,""),this.optional(b)||a.length>9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?)|(?:\(?0))(?:\d{2}\)?\s?\d{4}\s?\d{4}|\d{3}\)?\s?\d{3}\s?\d{3,4}|\d{4}\)?\s?(?:\d{5}|\d{3}\s?\d{3})|\d{5}\)?\s?\d{4,5})$/)},"Please specify a valid phone number"),a.validator.addMethod("phoneUS",function(a,b){return a=a.replace(/\s+/g,""),this.optional(b)||a.length>9&&a.match(/^(\+?1-?)?(\([2-9]([02-9]\d|1[02-9])\)|[2-9]([02-9]\d|1[02-9]))-?[2-9]([02-9]\d|1[02-9])-?\d{4}$/)},"Please specify a valid phone number"),a.validator.addMethod("phonesUK",function(a,b){return a=a.replace(/\(|\)|\s+|-/g,""),this.optional(b)||a.length>9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?|0)(?:1\d{8,9}|[23]\d{9}|7(?:[1345789]\d{8}|624\d{6})))$/)},"Please specify a valid uk phone number"),a.validator.addMethod("postalCodeCA",function(a,b){return this.optional(b)||/^[ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTVWXYZ] *\d[ABCEGHJKLMNPRSTVWXYZ]\d$/i.test(a)},"Please specify a valid postal code"),a.validator.addMethod("postalcodeBR",function(a,b){return this.optional(b)||/^\d{2}.\d{3}-\d{3}?$|^\d{5}-?\d{3}?$/.test(a)},"Informe um CEP válido."),a.validator.addMethod("postalcodeIT",function(a,b){return this.optional(b)||/^\d{5}$/.test(a)},"Please specify a valid postal code"),a.validator.addMethod("postalcodeNL",function(a,b){return this.optional(b)||/^[1-9][0-9]{3}\s?[a-zA-Z]{2}$/.test(a)},"Please specify a valid postal code"),a.validator.addMethod("postcodeUK",function(a,b){return this.optional(b)||/^((([A-PR-UWYZ][0-9])|([A-PR-UWYZ][0-9][0-9])|([A-PR-UWYZ][A-HK-Y][0-9])|([A-PR-UWYZ][A-HK-Y][0-9][0-9])|([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRVWXY]))\s?([0-9][ABD-HJLNP-UW-Z]{2})|(GIR)\s?(0AA))$/i.test(a)},"Please specify a valid UK postcode"),a.validator.addMethod("require_from_group",function(b,c,d){var e=a(d[1],c.form),f=e.eq(0),g=f.data("valid_req_grp")?f.data("valid_req_grp"):a.extend({},this),h=e.filter(function(){return g.elementValue(this)}).length>=d[0];return f.data("valid_req_grp",g),a(c).data("being_validated")||(e.data("being_validated",!0),e.each(function(){g.element(this)}),e.data("being_validated",!1)),h},a.validator.format("Please fill at least {0} of these fields.")),a.validator.addMethod("skip_or_fill_minimum",function(b,c,d){var e=a(d[1],c.form),f=e.eq(0),g=f.data("valid_skip")?f.data("valid_skip"):a.extend({},this),h=e.filter(function(){return g.elementValue(this)}).length,i=0===h||h>=d[0];return f.data("valid_skip",g),a(c).data("being_validated")||(e.data("being_validated",!0),e.each(function(){g.element(this)}),e.data("being_validated",!1)),i},a.validator.format("Please either skip these fields or fill at least {0} of them.")),a.validator.addMethod("stateUS",function(a,b,c){var d,e="undefined"==typeof c,f=e||"undefined"==typeof c.caseSensitive?!1:c.caseSensitive,g=e||"undefined"==typeof c.includeTerritories?!1:c.includeTerritories,h=e||"undefined"==typeof c.includeMilitary?!1:c.includeMilitary;return d=g||h?g&&h?"^(A[AEKLPRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$":g?"^(A[KLRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$":"^(A[AEKLPRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$":"^(A[KLRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$",d=f?new RegExp(d):new RegExp(d,"i"),this.optional(b)||d.test(a)},"Please specify a valid state"),a.validator.addMethod("strippedminlength",function(b,c,d){return a(b).text().length>=d},a.validator.format("Please enter at least {0} characters")),a.validator.addMethod("time",function(a,b){return this.optional(b)||/^([01]\d|2[0-3]|[0-9])(:[0-5]\d){1,2}$/.test(a)},"Please enter a valid time, between 00:00 and 23:59"),a.validator.addMethod("time12h",function(a,b){return this.optional(b)||/^((0?[1-9]|1[012])(:[0-5]\d){1,2}(\ ?[AP]M))$/i.test(a)},"Please enter a valid time in 12-hour am/pm format"),a.validator.addMethod("url2",function(a,b){return this.optional(b)||/^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(a)},a.validator.messages.url),a.validator.addMethod("vinUS",function(a){if(17!==a.length)return!1;var b,c,d,e,f,g,h=["A","B","C","D","E","F","G","H","J","K","L","M","N","P","R","S","T","U","V","W","X","Y","Z"],i=[1,2,3,4,5,6,7,8,1,2,3,4,5,7,9,2,3,4,5,6,7,8,9],j=[8,7,6,5,4,3,2,10,0,9,8,7,6,5,4,3,2],k=0;for(b=0;17>b;b++){if(e=j[b],d=a.slice(b,b+1),8===b&&(g=d),isNaN(d)){for(c=0;c<h.length;c++)if(d.toUpperCase()===h[c]){d=i[c],d*=e,isNaN(g)&&8===c&&(g=h[c]);break}}else d*=e;k+=d}return f=k%11,10===f&&(f="X"),f===g},"The specified vehicle identification number (VIN) is invalid."),a.validator.addMethod("zipcodeUS",function(a,b){return this.optional(b)||/^\d{5}(-\d{4})?$/.test(a)},"The specified US ZIP Code is invalid"),a.validator.addMethod("ziprange",function(a,b){return this.optional(b)||/^90[2-5]\d\{2\}-\d{4}$/.test(a)},"Your ZIP-code must be in the range 902xx-xxxx to 905xx-xxxx")});
js/{jquery.validate.min.js → jquery-validation/jquery.validate.min.js} RENAMED
File without changes
js/time.js CHANGED
@@ -32,6 +32,7 @@ jQuery( function ( $ )
32
  }
33
 
34
  // Set language if available
 
35
  if ( $.timepicker.regional.hasOwnProperty( RWMB_Time.locale ) )
36
  {
37
  $.timepicker.setDefaults( $.timepicker.regional[RWMB_Time.locale] );
32
  }
33
 
34
  // Set language if available
35
+ $.timepicker.setDefaults( $.timepicker.regional[ "" ] );
36
  if ( $.timepicker.regional.hasOwnProperty( RWMB_Time.locale ) )
37
  {
38
  $.timepicker.setDefaults( $.timepicker.regional[RWMB_Time.locale] );
js/wysiwyg.js CHANGED
@@ -58,6 +58,10 @@ jQuery( function ( $ )
58
  $clones.each( function ()
59
  {
60
  var currentId = $( this ).find( '.rwmb-wysiwyg' ).attr( 'id' );
 
 
 
 
61
  if ( tinyMCEPreInit.mceInit.hasOwnProperty( currentId ) )
62
  {
63
  id = currentId;
58
  $clones.each( function ()
59
  {
60
  var currentId = $( this ).find( '.rwmb-wysiwyg' ).attr( 'id' );
61
+ if ( /_\d+$/.test( currentId ) )
62
+ {
63
+ currentId = currentId.replace( /_\d+$/, '' );
64
+ }
65
  if ( tinyMCEPreInit.mceInit.hasOwnProperty( currentId ) )
66
  {
67
  id = currentId;
lang/meta-box-zh_CN.mo CHANGED
Binary file
lang/meta-box-zh_TW.mo ADDED
Binary file
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 for any post type in WordPress.
6
- * Version: 4.8.7
7
  * Author: Rilwis
8
  * Author URI: http://www.deluxeblogtips.com
9
  * License: GPL2+
@@ -11,8 +11,9 @@
11
  * Domain Path: /lang/
12
  */
13
 
14
- if ( defined( 'ABSPATH' ) && ! class_exists( 'RWMB_Loader' ) )
15
  {
16
- require plugin_dir_path( __FILE__ ) . 'inc/loader.php';
17
- new RWMB_Loader;
 
18
  }
3
  * Plugin Name: Meta Box
4
  * Plugin URI: https://metabox.io
5
  * Description: Create custom meta boxes and custom fields for any post type in WordPress.
6
+ * Version: 4.9
7
  * Author: Rilwis
8
  * Author URI: http://www.deluxeblogtips.com
9
  * License: GPL2+
11
  * Domain Path: /lang/
12
  */
13
 
14
+ if ( defined( 'ABSPATH' ) && ! defined( 'RWMB_VER' ) )
15
  {
16
+ require_once plugin_dir_path( __FILE__ ) . 'inc/loader.php';
17
+ $loader = new RWMB_Loader;
18
+ $loader->init();
19
  }
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: metabox, rilwis, fitwp, f-j-kaiser, funkatronic, PerWiklander, rua
3
  Donate link: http://www.deluxeblogtips.com/donate
4
  Tags: meta-box, custom fields, custom field, meta, meta-boxes, admin, advanced, custom, edit, field, file, image, magic fields, matrix, more fields, Post, repeater, simple fields, text, textarea, type, cms, fields post
5
  Requires at least: 4.1
6
- Tested up to: 4.5.2
7
- Stable tag: 4.8.7
8
  License: GPLv2 or later
9
 
10
  Meta Box plugin is a powerful, professional solution to create custom meta boxes and custom fields for WordPress websites.
@@ -33,6 +33,7 @@ See more documentation [here](https://metabox.io/docs/).
33
 
34
  ### Extensions
35
 
 
36
  - [Meta Box Geolocation](https://metabox.io/plugins/meta-box-geolocation/)|Automatically and instantly populate location data with the power of Google Maps Geolocation API.
37
  - [MB Admin Columns](https://metabox.io/plugins/mb-admin-columns/): Display custom fields in table columns in admin screens for All Posts (types).
38
  - [MB Term Meta](https://metabox.io/plugins/mb-term-meta/): Add meta data to categories, tags or any custom taxonomy with simple syntax.
@@ -79,6 +80,21 @@ To getting started with the plugin API, please read [this tutorial](https://meta
79
 
80
  == Changelog ==
81
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  = 4.8.7 =
83
  * Improvement: Refactor the code to reduce the complexity in the fields' inheritance
84
  * Improvement: All HTML 5 input types (week, month, etc.) are supported
3
  Donate link: http://www.deluxeblogtips.com/donate
4
  Tags: meta-box, custom fields, custom field, meta, meta-boxes, admin, advanced, custom, edit, field, file, image, magic fields, matrix, more fields, Post, repeater, simple fields, text, textarea, type, cms, fields post
5
  Requires at least: 4.1
6
+ Tested up to: 4.6.1
7
+ Stable tag: 4.9
8
  License: GPLv2 or later
9
 
10
  Meta Box plugin is a powerful, professional solution to create custom meta boxes and custom fields for WordPress websites.
33
 
34
  ### Extensions
35
 
36
+ - [MB User Meta](https://metabox.io/plugins/mb-user-meta/)|Add custom fields to user profile (user meta) quickly with simple syntax.
37
  - [Meta Box Geolocation](https://metabox.io/plugins/meta-box-geolocation/)|Automatically and instantly populate location data with the power of Google Maps Geolocation API.
38
  - [MB Admin Columns](https://metabox.io/plugins/mb-admin-columns/): Display custom fields in table columns in admin screens for All Posts (types).
39
  - [MB Term Meta](https://metabox.io/plugins/mb-term-meta/): Add meta data to categories, tags or any custom taxonomy with simple syntax.
80
 
81
  == Changelog ==
82
 
83
+ = 4.9 =
84
+ * Improvement: Update Chinese language. Add Chinese Taiwan.
85
+ * Improvement: Add support for Google Maps API key. Default API key is added, however users should replace it with their own key.
86
+ * Improvement: Add additional methods for jQuery validation module which makes it understand HTML5 "pattern" attribute.
87
+ * Improvement: Fully WPML compatibility (supported by WPML team)
88
+ * Improvement: Add placeholders for `key_value` field
89
+ * Fix: Toggle remove clone buttons for nested groups.
90
+ * Fix: Error on date field, not save
91
+ * Fix: Add fix for date/datetime when both inline and timestamp used
92
+ * Fix: Set default language for date/time picker.
93
+ * Fix: rwmb_meta for images returns incorrect width/height
94
+ * Fix: PHP warning when uploading files in Settings Pages extension.
95
+ * Fix: Blank space in the footer when using plupload_image.
96
+ * Fix: Cloning wysiwyg when deleting the 1st clone
97
+
98
  = 4.8.7 =
99
  * Improvement: Refactor the code to reduce the complexity in the fields' inheritance
100
  * Improvement: All HTML 5 input types (week, month, etc.) are supported