Meta Box - Version 4.17.0

Version Description

  • 2019-03-18 =

Added

  • Added range support for slider field for storing 2 values.
  • Added attribute to [rwmb_meta] shortcode to get only one attribute from the value (such as URL of the image or term slug).
  • Added prepend and append attributes for inputs like Bootstrap's input group.

Changed

  • Refactored the code.
  • Changed shortcode attributes to use id (instead of meta_key), object_id (instead of post_id).

Fixed

  • Fixed empty date field with save_format causes error.
  • Fixed wrong position of the asterisk when the field is required and has label description.
  • Fixed indirect modification of meta_box->$fields.
  • Fixed required attribute not working for file, image fields.
  • Fixed warning in the about page.
  • Fixed box-sizing issue for settings page.

See full changelog here.

=

Download this release

Release Info

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

Code changes from version 4.16.3 to 4.17.0

css/button-group.css CHANGED
@@ -1,3 +1,6 @@
 
 
 
1
  .rwmb-button-input-list li {
2
  margin-bottom: 0;
3
  list-style: none;
1
+ .rwmb-button-input-list {
2
+ margin: 0;
3
+ }
4
  .rwmb-button-input-list li {
5
  margin-bottom: 0;
6
  list-style: none;
css/input.css ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .rwmb-input-group {
2
+ display: flex;
3
+ align-items: stretch;
4
+ }
5
+ .rwmb-input-group-append,
6
+ .rwmb-input-group-prepend {
7
+ display: flex;
8
+ align-items: center;
9
+ padding: 0 8px;
10
+ background: #ddd;
11
+ }
12
+ .rwmb-input-group input {
13
+ margin: 0;
14
+ }
css/style.css CHANGED
@@ -2,23 +2,19 @@
2
  -------------------------------------------------------------- */
3
 
4
  /* Clearfix for field */
5
- .rwmb-field:before,
6
  .rwmb-field:after {
7
  content: " ";
8
  display: table;
9
- }
10
- .rwmb-field:after {
11
  clear: both;
12
  }
13
  .rwmb-field:not(:last-of-type) {
14
- *zoom: 1;
15
-
16
  margin: 0 0 12px;
17
  }
18
  .rwmb-label,
19
  .rwmb-input {
20
  vertical-align: top;
21
  float: left;
 
22
  }
23
  .rwmb-label {
24
  width: 25%;
2
  -------------------------------------------------------------- */
3
 
4
  /* Clearfix for field */
 
5
  .rwmb-field:after {
6
  content: " ";
7
  display: table;
 
 
8
  clear: both;
9
  }
10
  .rwmb-field:not(:last-of-type) {
 
 
11
  margin: 0 0 12px;
12
  }
13
  .rwmb-label,
14
  .rwmb-input {
15
  vertical-align: top;
16
  float: left;
17
+ box-sizing: border-box;
18
  }
19
  .rwmb-label {
20
  width: 25%;
inc/about/about.php CHANGED
@@ -193,7 +193,7 @@ class RWMB_About {
193
  protected function is_bundled() {
194
  // @codingStandardsIgnoreLine
195
  foreach ( $_REQUEST as $key => $value ) {
196
- if ( false !== strpos( $key, 'tgmpa' ) || false !== strpos( $value, 'tgmpa' ) ) {
197
  return true;
198
  }
199
  }
193
  protected function is_bundled() {
194
  // @codingStandardsIgnoreLine
195
  foreach ( $_REQUEST as $key => $value ) {
196
+ if ( false !== strpos( $key, 'tgmpa' ) || ( ! is_array( $value ) && false !== strpos( $value, 'tgmpa' ) ) ) {
197
  return true;
198
  }
199
  }
inc/field.php CHANGED
@@ -23,25 +23,6 @@ abstract class RWMB_Field {
23
  public static function admin_enqueue_scripts() {
24
  }
25
 
26
- /**
27
- * Localize scripts with prevention of loading localized data twice.
28
- *
29
- * @link https://github.com/rilwis/meta-box/issues/850
30
- *
31
- * @param string $handle Script handle.
32
- * @param string $name Object name.
33
- * @param mixed $data Localized data.
34
- */
35
- public static function localize_script( $handle, $name, $data ) {
36
- /*
37
- * Check with function_exists to make it work in WordPress 4.1.
38
- * @link https://github.com/rilwis/meta-box/issues/1009
39
- */
40
- if ( ! function_exists( 'wp_scripts' ) || ! wp_scripts()->get_data( $handle, 'data' ) ) {
41
- wp_localize_script( $handle, $name, $data );
42
- }
43
- }
44
-
45
  /**
46
  * Show field HTML
47
  * Filters are put inside this method, not inside methods such as "meta", "html", "begin_html", etc.
@@ -229,13 +210,11 @@ abstract class RWMB_Field {
229
 
230
  // Ensure multiple fields are arrays.
231
  if ( $field['multiple'] ) {
 
232
  if ( $field['clone'] ) {
233
- $meta = (array) $meta;
234
  foreach ( $meta as $key => $m ) {
235
  $meta[ $key ] = (array) $m;
236
  }
237
- } else {
238
- $meta = (array) $meta;
239
  }
240
  }
241
  // Escape attributes.
@@ -275,7 +254,7 @@ abstract class RWMB_Field {
275
  * @param int $post_id The post ID.
276
  * @param array $field The field parameters.
277
  *
278
- * @return int
279
  */
280
  public static function value( $new, $old, $post_id, $field ) {
281
  return $new;
@@ -585,41 +564,7 @@ abstract class RWMB_Field {
585
  }
586
  }
587
 
588
- return call_user_func_array( array( self::get_class_name( $field ), $method ), $args );
589
- }
590
-
591
- /**
592
- * Map field types.
593
- *
594
- * @param array $field Field parameters.
595
- * @return string Field mapped type.
596
- */
597
- public static function map_types( $field ) {
598
- $type = isset( $field['type'] ) ? $field['type'] : 'input';
599
- $type_map = apply_filters(
600
- 'rwmb_type_map',
601
- array(
602
- 'file_advanced' => 'media',
603
- 'plupload_image' => 'image_upload',
604
- 'url' => 'text',
605
- )
606
- );
607
-
608
- return isset( $type_map[ $type ] ) ? $type_map[ $type ] : $type;
609
- }
610
-
611
- /**
612
- * Get field class name.
613
- *
614
- * @param array $field Field parameters.
615
- * @return string Field class name.
616
- */
617
- public static function get_class_name( $field ) {
618
- $type = self::map_types( $field );
619
- $type = str_replace( array( '-', '_' ), ' ', $type );
620
- $class = 'RWMB_' . ucwords( $type ) . '_Field';
621
- $class = str_replace( ' ', '_', $class );
622
- return class_exists( $class ) ? $class : 'RWMB_Input_Field';
623
  }
624
 
625
  /**
23
  public static function admin_enqueue_scripts() {
24
  }
25
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  /**
27
  * Show field HTML
28
  * Filters are put inside this method, not inside methods such as "meta", "html", "begin_html", etc.
210
 
211
  // Ensure multiple fields are arrays.
212
  if ( $field['multiple'] ) {
213
+ $meta = (array) $meta;
214
  if ( $field['clone'] ) {
 
215
  foreach ( $meta as $key => $m ) {
216
  $meta[ $key ] = (array) $m;
217
  }
 
 
218
  }
219
  }
220
  // Escape attributes.
254
  * @param int $post_id The post ID.
255
  * @param array $field The field parameters.
256
  *
257
+ * @return mixed
258
  */
259
  public static function value( $new, $old, $post_id, $field ) {
260
  return $new;
564
  }
565
  }
566
 
567
+ return call_user_func_array( array( RWMB_Helpers_Field::get_class( $field ), $method ), $args );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
568
  }
569
 
570
  /**
inc/fields/autocomplete.php CHANGED
@@ -16,7 +16,7 @@ class RWMB_Autocomplete_Field extends RWMB_Multiple_Values_Field {
16
  wp_enqueue_style( 'rwmb-autocomplete', RWMB_CSS_URL . 'autocomplete.css', '', RWMB_VER );
17
  wp_enqueue_script( 'rwmb-autocomplete', RWMB_JS_URL . 'autocomplete.js', array( 'jquery-ui-autocomplete' ), RWMB_VER, true );
18
 
19
- self::localize_script(
20
  'rwmb-autocomplete',
21
  'RWMB_Autocomplete',
22
  array(
16
  wp_enqueue_style( 'rwmb-autocomplete', RWMB_CSS_URL . 'autocomplete.css', '', RWMB_VER );
17
  wp_enqueue_script( 'rwmb-autocomplete', RWMB_JS_URL . 'autocomplete.js', array( 'jquery-ui-autocomplete' ), RWMB_VER, true );
18
 
19
+ RWMB_Helpers_Field::localize_script_once(
20
  'rwmb-autocomplete',
21
  'RWMB_Autocomplete',
22
  array(
inc/fields/background.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * The background field.
4
  *
5
- * @package Meta Box.
6
  */
7
 
8
  /**
2
  /**
3
  * The background field.
4
  *
5
+ * @package Meta Box
6
  */
7
 
8
  /**
inc/fields/datetime.php CHANGED
@@ -79,7 +79,7 @@ class RWMB_Datetime_Field extends RWMB_Text_Field {
79
  'localeShort' => $locale_short,
80
  );
81
  foreach ( $handles as $handle ) {
82
- self::localize_script( "rwmb-$handle", 'RWMB_' . ucfirst( $handle ), $data );
83
  }
84
  }
85
 
@@ -145,7 +145,7 @@ class RWMB_Datetime_Field extends RWMB_Text_Field {
145
 
146
  if ( $field['save_format'] ) {
147
  $date = DateTime::createFromFormat( self::call( 'translate_format', $field ), $new );
148
- $new = $date->format( $field['save_format'] );
149
  }
150
 
151
  return $new;
@@ -173,7 +173,7 @@ class RWMB_Datetime_Field extends RWMB_Text_Field {
173
  }
174
 
175
  $date = DateTime::createFromFormat( $field['save_format'], $meta );
176
- $meta = $date->format( self::call( 'translate_format', $field ) );
177
 
178
  return $meta;
179
  }
79
  'localeShort' => $locale_short,
80
  );
81
  foreach ( $handles as $handle ) {
82
+ RWMB_Helpers_Field::localize_script_once( "rwmb-$handle", 'RWMB_' . ucfirst( $handle ), $data );
83
  }
84
  }
85
 
145
 
146
  if ( $field['save_format'] ) {
147
  $date = DateTime::createFromFormat( self::call( 'translate_format', $field ), $new );
148
+ $new = false === $date ? $new : $date->format( $field['save_format'] );
149
  }
150
 
151
  return $new;
173
  }
174
 
175
  $date = DateTime::createFromFormat( $field['save_format'], $meta );
176
+ $meta = false === $date ? $meta : $date->format( self::call( 'translate_format', $field ) );
177
 
178
  return $meta;
179
  }
inc/fields/file-input.php CHANGED
@@ -16,7 +16,7 @@ class RWMB_File_Input_Field extends RWMB_Input_Field {
16
  wp_enqueue_media();
17
  wp_enqueue_style( 'rwmb-file-input', RWMB_CSS_URL . 'file-input.css', array(), RWMB_VER );
18
  wp_enqueue_script( 'rwmb-file-input', RWMB_JS_URL . 'file-input.js', array( 'jquery' ), RWMB_VER, true );
19
- self::localize_script(
20
  'rwmb-file-input',
21
  'rwmbFileInput',
22
  array(
16
  wp_enqueue_media();
17
  wp_enqueue_style( 'rwmb-file-input', RWMB_CSS_URL . 'file-input.css', array(), RWMB_VER );
18
  wp_enqueue_script( 'rwmb-file-input', RWMB_JS_URL . 'file-input.js', array( 'jquery' ), RWMB_VER, true );
19
+ RWMB_Helpers_Field::localize_script_once(
20
  'rwmb-file-input',
21
  'rwmbFileInput',
22
  array(
inc/fields/file.php CHANGED
@@ -16,7 +16,7 @@ class RWMB_File_Field extends RWMB_Field {
16
  wp_enqueue_style( 'rwmb-file', RWMB_CSS_URL . 'file.css', array(), RWMB_VER );
17
  wp_enqueue_script( 'rwmb-file', RWMB_JS_URL . 'file.js', array( 'jquery-ui-sortable' ), RWMB_VER, true );
18
 
19
- self::localize_script(
20
  'rwmb-file',
21
  'rwmbFile',
22
  array(
@@ -89,12 +89,17 @@ class RWMB_File_Field extends RWMB_Field {
89
  $html = self::get_uploaded_files( $meta, $field );
90
 
91
  // Show form upload.
 
 
 
 
 
92
  $html .= sprintf(
93
  '<div class="rwmb-file-new">
94
- <input type="file" name="%s[]" class="rwmb-file-input">
95
  <a class="rwmb-file-add" href="#"><strong>%s</strong></a>
96
  </div>',
97
- $field['file_input_name'],
98
  $i18n_more
99
  );
100
 
@@ -271,7 +276,7 @@ class RWMB_File_Field extends RWMB_Field {
271
  * @return \WP_Error|int|string WP_Error if has error, attachment ID if upload in Media Library, URL to file if upload to custom folder.
272
  */
273
  protected static function handle_upload( $file_id, $post_id, $field ) {
274
- return $field['upload_dir'] ? self::handle_upload_custom_dir( $file_id, $post_id, $field ) : media_handle_upload( $file_id, $post_id );
275
  }
276
 
277
  /**
@@ -446,12 +451,11 @@ class RWMB_File_Field extends RWMB_Field {
446
  * Handle upload for files in custom directory.
447
  *
448
  * @param string $file_id File ID in $_FILES when uploading.
449
- * @param int $post_id Post ID.
450
  * @param array $field Field settings.
451
  *
452
  * @return string URL to uploaded file.
453
  */
454
- public static function handle_upload_custom_dir( $file_id, $post_id, $field ) {
455
  // @codingStandardsIgnoreStart
456
  if ( empty( $_FILES[ $file_id ] ) ) {
457
  return;
16
  wp_enqueue_style( 'rwmb-file', RWMB_CSS_URL . 'file.css', array(), RWMB_VER );
17
  wp_enqueue_script( 'rwmb-file', RWMB_JS_URL . 'file.js', array( 'jquery-ui-sortable' ), RWMB_VER, true );
18
 
19
+ RWMB_Helpers_Field::localize_script_once(
20
  'rwmb-file',
21
  'rwmbFile',
22
  array(
89
  $html = self::get_uploaded_files( $meta, $field );
90
 
91
  // Show form upload.
92
+ $attributes = self::get_attributes( $field, $meta );
93
+ $attributes['type'] = 'file';
94
+ $attributes['name'] = "{$field['file_input_name']}[]";
95
+ $attributes['class'] = 'rwmb-file-input';
96
+
97
  $html .= sprintf(
98
  '<div class="rwmb-file-new">
99
+ <input %s>
100
  <a class="rwmb-file-add" href="#"><strong>%s</strong></a>
101
  </div>',
102
+ self::render_attributes( $attributes ),
103
  $i18n_more
104
  );
105
 
276
  * @return \WP_Error|int|string WP_Error if has error, attachment ID if upload in Media Library, URL to file if upload to custom folder.
277
  */
278
  protected static function handle_upload( $file_id, $post_id, $field ) {
279
+ return $field['upload_dir'] ? self::handle_upload_custom_dir( $file_id, $field ) : media_handle_upload( $file_id, $post_id );
280
  }
281
 
282
  /**
451
  * Handle upload for files in custom directory.
452
  *
453
  * @param string $file_id File ID in $_FILES when uploading.
 
454
  * @param array $field Field settings.
455
  *
456
  * @return string URL to uploaded file.
457
  */
458
+ public static function handle_upload_custom_dir( $file_id, $field ) {
459
  // @codingStandardsIgnoreStart
460
  if ( empty( $_FILES[ $file_id ] ) ) {
461
  return;
inc/fields/input.php CHANGED
@@ -9,6 +9,13 @@
9
  * Abstract input field class.
10
  */
11
  abstract class RWMB_Input_Field extends RWMB_Field {
 
 
 
 
 
 
 
12
  /**
13
  * Get field HTML.
14
  *
@@ -17,8 +24,28 @@ abstract class RWMB_Input_Field extends RWMB_Field {
17
  * @return string
18
  */
19
  public static function html( $meta, $field ) {
 
 
 
 
 
 
 
 
 
 
20
  $attributes = self::call( 'get_attributes', $field, $meta );
21
- return sprintf( '<input %s>%s', self::render_attributes( $attributes ), self::datalist( $field ) );
 
 
 
 
 
 
 
 
 
 
22
  }
23
 
24
  /**
@@ -36,6 +63,8 @@ abstract class RWMB_Input_Field extends RWMB_Field {
36
  'size' => 30,
37
  'datalist' => false,
38
  'readonly' => false,
 
 
39
  )
40
  );
41
  if ( $field['datalist'] ) {
9
  * Abstract input field class.
10
  */
11
  abstract class RWMB_Input_Field extends RWMB_Field {
12
+ /**
13
+ * Enqueue scripts and styles.
14
+ */
15
+ public static function admin_enqueue_scripts() {
16
+ wp_enqueue_style( 'rwmb-input', RWMB_CSS_URL . 'input.css', '', RWMB_VER );
17
+ }
18
+
19
  /**
20
  * Get field HTML.
21
  *
24
  * @return string
25
  */
26
  public static function html( $meta, $field ) {
27
+ $output = '';
28
+
29
+ if ( $field['prepend'] || $field['append'] ) {
30
+ $output = '<div class="rwmb-input-group">';
31
+ }
32
+
33
+ if ( $field['prepend'] ) {
34
+ $output .= '<span class="rwmb-input-group-prepend">' . esc_html( $field['prepend'] ) . '</span>';
35
+ }
36
+
37
  $attributes = self::call( 'get_attributes', $field, $meta );
38
+ $output .= sprintf( '<input %s>%s', self::render_attributes( $attributes ), self::datalist( $field ) );
39
+
40
+ if ( $field['append'] ) {
41
+ $output .= '<span class="rwmb-input-group-append">' . esc_html( $field['append'] ) . '</span>';
42
+ }
43
+
44
+ if ( $field['prepend'] || $field['append'] ) {
45
+ $output .= '</div>';
46
+ }
47
+
48
+ return $output;
49
  }
50
 
51
  /**
63
  'size' => 30,
64
  'datalist' => false,
65
  'readonly' => false,
66
+ 'prepend' => '',
67
+ 'append' => '',
68
  )
69
  );
70
  if ( $field['datalist'] ) {
inc/fields/map.php CHANGED
@@ -48,7 +48,7 @@ class RWMB_Map_Field extends RWMB_Field {
48
  RWMB_VER,
49
  true
50
  );
51
- self::localize_script(
52
  'rwmb-map',
53
  'RWMB_Map',
54
  array(
48
  RWMB_VER,
49
  true
50
  );
51
+ RWMB_Helpers_Field::localize_script_once(
52
  'rwmb-map',
53
  'RWMB_Map',
54
  array(
inc/fields/media.php CHANGED
@@ -20,7 +20,7 @@ class RWMB_Media_Field extends RWMB_File_Field {
20
  wp_enqueue_style( 'rwmb-media', RWMB_CSS_URL . 'media.css', array(), RWMB_VER );
21
  wp_enqueue_script( 'rwmb-media', RWMB_JS_URL . 'media.js', array( 'jquery-ui-sortable', 'underscore', 'backbone', 'media-grid' ), RWMB_VER, true );
22
 
23
- self::localize_script(
24
  'rwmb-media',
25
  'i18nRwmbMedia',
26
  array(
@@ -46,7 +46,7 @@ class RWMB_Media_Field extends RWMB_File_Field {
46
  public static function add_actions() {
47
  $args = func_get_args();
48
  $field = reset( $args );
49
- add_action( 'print_media_templates', array( self::get_class_name( $field ), 'print_templates' ) );
50
  }
51
 
52
  /**
@@ -159,9 +159,8 @@ class RWMB_Media_Field extends RWMB_File_Field {
159
  * @return array|mixed
160
  */
161
  public static function value( $new, $old, $post_id, $field ) {
162
- $new = rwmb_csv_to_array( $new );
163
- array_walk( $new, 'absint' );
164
- return array_filter( array_unique( $new ) );
165
  }
166
 
167
  /**
20
  wp_enqueue_style( 'rwmb-media', RWMB_CSS_URL . 'media.css', array(), RWMB_VER );
21
  wp_enqueue_script( 'rwmb-media', RWMB_JS_URL . 'media.js', array( 'jquery-ui-sortable', 'underscore', 'backbone', 'media-grid' ), RWMB_VER, true );
22
 
23
+ RWMB_Helpers_Field::localize_script_once(
24
  'rwmb-media',
25
  'i18nRwmbMedia',
26
  array(
46
  public static function add_actions() {
47
  $args = func_get_args();
48
  $field = reset( $args );
49
+ add_action( 'print_media_templates', array( RWMB_Helpers_Field::get_class( $field ), 'print_templates' ) );
50
  }
51
 
52
  /**
159
  * @return array|mixed
160
  */
161
  public static function value( $new, $old, $post_id, $field ) {
162
+ $new = RWMB_Helpers_Array::from_csv( $new );
163
+ return array_filter( array_unique( array_map( 'absint', $new ) ) );
 
164
  }
165
 
166
  /**
inc/fields/object-choice.php CHANGED
@@ -115,7 +115,7 @@ abstract class RWMB_Object_Choice_Field extends RWMB_Choice_Field {
115
  if ( in_array( $field['field_type'], array( 'checkbox_list', 'radio_list' ), true ) ) {
116
  return 'RWMB_Input_List_Field';
117
  }
118
- return self::get_class_name(
119
  array(
120
  'type' => $field['field_type'],
121
  )
115
  if ( in_array( $field['field_type'], array( 'checkbox_list', 'radio_list' ), true ) ) {
116
  return 'RWMB_Input_List_Field';
117
  }
118
+ return RWMB_Helpers_Field::get_class(
119
  array(
120
  'type' => $field['field_type'],
121
  )
inc/fields/osm.php CHANGED
@@ -20,7 +20,7 @@ class RWMB_OSM_Field extends RWMB_Field {
20
 
21
  wp_enqueue_style( 'rwmb-osm', RWMB_CSS_URL . 'osm.css', array( 'leaflet' ), RWMB_VER );
22
  wp_enqueue_script( 'rwmb-osm', RWMB_JS_URL . 'osm.js', array( 'jquery', 'leaflet' ), RWMB_VER, true );
23
- self::localize_script(
24
  'rwmb-osm',
25
  'RWMB_Osm',
26
  array(
20
 
21
  wp_enqueue_style( 'rwmb-osm', RWMB_CSS_URL . 'osm.css', array( 'leaflet' ), RWMB_VER );
22
  wp_enqueue_script( 'rwmb-osm', RWMB_JS_URL . 'osm.js', array( 'jquery', 'leaflet' ), RWMB_VER, true );
23
+ RWMB_Helpers_Field::localize_script_once(
24
  'rwmb-osm',
25
  'RWMB_Osm',
26
  array(
inc/fields/slider.php CHANGED
@@ -40,10 +40,10 @@ class RWMB_Slider_Field extends RWMB_Field {
40
  $field['id'],
41
  esc_attr( wp_json_encode( $field['js_options'] ) ),
42
  $field['prefix'],
43
- ( $meta >= 0 ) ? $meta : $field['std'],
44
  $field['suffix'],
45
  $field['field_name'],
46
- ( $meta >= 0 ) ? $meta : $field['std']
47
  );
48
  }
49
 
40
  $field['id'],
41
  esc_attr( wp_json_encode( $field['js_options'] ) ),
42
  $field['prefix'],
43
+ $meta,
44
  $field['suffix'],
45
  $field['field_name'],
46
+ $meta
47
  );
48
  }
49
 
inc/fields/video.php CHANGED
@@ -17,7 +17,7 @@ class RWMB_Video_Field extends RWMB_Media_Field {
17
  parent::admin_enqueue_scripts();
18
  wp_enqueue_style( 'rwmb-video', RWMB_CSS_URL . 'video.css', array( 'rwmb-media' ), RWMB_VER );
19
  wp_enqueue_script( 'rwmb-video', RWMB_JS_URL . 'video.js', array( 'rwmb-media' ), RWMB_VER, true );
20
- self::localize_script(
21
  'rwmb-video',
22
  'i18nRwmbVideo',
23
  array(
17
  parent::admin_enqueue_scripts();
18
  wp_enqueue_style( 'rwmb-video', RWMB_CSS_URL . 'video.css', array( 'rwmb-media' ), RWMB_VER );
19
  wp_enqueue_script( 'rwmb-video', RWMB_JS_URL . 'video.js', array( 'rwmb-media' ), RWMB_VER, true );
20
+ RWMB_Helpers_Field::localize_script_once(
21
  'rwmb-video',
22
  'i18nRwmbVideo',
23
  array(
inc/functions.php CHANGED
@@ -254,18 +254,41 @@ if ( ! function_exists( 'rwmb_meta_shortcode' ) ) {
254
  $atts = wp_parse_args(
255
  $atts,
256
  array(
257
- 'post_id' => get_the_ID(),
 
 
258
  )
259
  );
260
- if ( empty( $atts['meta_key'] ) ) {
 
 
 
261
  return '';
262
  }
263
 
264
- $field_id = $atts['meta_key'];
265
- $post_id = $atts['post_id'];
266
- unset( $atts['meta_key'], $atts['post_id'] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
267
 
268
- return rwmb_the_value( $field_id, $atts, $post_id, false );
269
  }
270
 
271
  add_shortcode( 'rwmb_meta', 'rwmb_meta_shortcode' );
@@ -283,9 +306,7 @@ if ( ! function_exists( 'rwmb_get_registry' ) ) {
283
  function rwmb_get_registry( $type ) {
284
  static $data = array();
285
 
286
- $type = str_replace( array( '-', '_' ), ' ', $type );
287
- $class = 'RWMB_' . ucwords( $type ) . '_Registry';
288
- $class = str_replace( ' ', '_', $class );
289
  if ( ! isset( $data[ $type ] ) ) {
290
  $data[ $type ] = new $class();
291
  }
@@ -294,27 +315,6 @@ if ( ! function_exists( 'rwmb_get_registry' ) ) {
294
  }
295
  }
296
 
297
- if ( ! function_exists( 'rwmb_get_storage_class_name' ) ) {
298
- /**
299
- * Get storage class name.
300
- *
301
- * @param string $object_type Object type. Use post or term.
302
- * @return string
303
- */
304
- function rwmb_get_storage_class_name( $object_type ) {
305
- $object_type = str_replace( array( '-', '_' ), ' ', $object_type );
306
- $object_type = ucwords( $object_type );
307
- $object_type = str_replace( ' ', '_', $object_type );
308
- $class_name = 'RWMB_' . $object_type . '_Storage';
309
-
310
- if ( ! class_exists( $class_name ) ) {
311
- $class_name = 'RWMB_Post_Storage';
312
- }
313
-
314
- return apply_filters( 'rwmb_storage_class_name', $class_name, $object_type );
315
- }
316
- }
317
-
318
  if ( ! function_exists( 'rwmb_get_storage' ) ) {
319
  /**
320
  * Get storage instance.
@@ -324,8 +324,9 @@ if ( ! function_exists( 'rwmb_get_storage' ) ) {
324
  * @return RWMB_Storage_Interface
325
  */
326
  function rwmb_get_storage( $object_type, $meta_box = null ) {
327
- $class_name = rwmb_get_storage_class_name( $object_type );
328
- $storage = rwmb_get_registry( 'storage' )->get( $class_name );
 
329
 
330
  return apply_filters( 'rwmb_get_storage', $storage, $object_type, $meta_box );
331
  }
@@ -351,35 +352,3 @@ if ( ! function_exists( 'rwmb_get_meta_box' ) ) {
351
  }
352
  }
353
 
354
- /**
355
- * Helper functions
356
- */
357
-
358
- if ( ! function_exists( 'rwmb_change_array_key' ) ) {
359
- /**
360
- * Change array key.
361
- *
362
- * @param array $array Input array.
363
- * @param string $from From key.
364
- * @param string $to To key.
365
- */
366
- function rwmb_change_array_key( &$array, $from, $to ) {
367
- if ( isset( $array[ $from ] ) ) {
368
- $array[ $to ] = $array[ $from ];
369
- }
370
- unset( $array[ $from ] );
371
- }
372
- }
373
-
374
- if ( ! function_exists( 'rwmb_csv_to_array' ) ) {
375
- /**
376
- * Convert a comma separated string to array.
377
- *
378
- * @param string $string Comma separated string.
379
- *
380
- * @return array
381
- */
382
- function rwmb_csv_to_array( $string ) {
383
- return is_array( $string ) ? $string : array_filter( array_map( 'trim', explode( ',', $string . ',' ) ) );
384
- }
385
- }
254
  $atts = wp_parse_args(
255
  $atts,
256
  array(
257
+ 'id' => '',
258
+ 'object_id' => get_queried_object_id(),
259
+ 'attribute' => '',
260
  )
261
  );
262
+ RWMB_Helpers_Array::change_key( $atts, 'post_id', 'object_id' );
263
+ RWMB_Helpers_Array::change_key( $atts, 'meta_key', 'id' );
264
+
265
+ if ( empty( $atts['id'] ) ) {
266
  return '';
267
  }
268
 
269
+ $field_id = $atts['id'];
270
+ $object_id = $atts['object_id'];
271
+ unset( $atts['id'], $atts['object_id'] );
272
+
273
+ $attribute = $atts['attribute'];
274
+ if ( ! $attribute ) {
275
+ return rwmb_the_value( $field_id, $atts, $object_id, false );
276
+ }
277
+
278
+ $value = rwmb_get_value( $field_id, $atts, $object_id );
279
+
280
+ if ( ! is_array( $value ) && ! is_object( $value ) ) {
281
+ return $value;
282
+ }
283
+
284
+ if ( is_object( $value ) ) {
285
+ return $value->$attribute;
286
+ }
287
+
288
+ $value = wp_list_pluck( $value, $attribute );
289
+ $value = implode( ',', $value );
290
 
291
+ return $value;
292
  }
293
 
294
  add_shortcode( 'rwmb_meta', 'rwmb_meta_shortcode' );
306
  function rwmb_get_registry( $type ) {
307
  static $data = array();
308
 
309
+ $class = 'RWMB_' . RWMB_Helpers_String::title_case( $type ) . '_Registry';
 
 
310
  if ( ! isset( $data[ $type ] ) ) {
311
  $data[ $type ] = new $class();
312
  }
315
  }
316
  }
317
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
318
  if ( ! function_exists( 'rwmb_get_storage' ) ) {
319
  /**
320
  * Get storage instance.
324
  * @return RWMB_Storage_Interface
325
  */
326
  function rwmb_get_storage( $object_type, $meta_box = null ) {
327
+ $class = 'RWMB_' . RWMB_Helpers_String::title_case( $object_type ) . '_Storage';
328
+ $class = class_exists( $class ) ? $class : 'RWMB_Post_Storage';
329
+ $storage = rwmb_get_registry( 'storage' )->get( $class );
330
 
331
  return apply_filters( 'rwmb_get_storage', $storage, $object_type, $meta_box );
332
  }
352
  }
353
  }
354
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/helpers/array.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Array helper functions.
4
+ *
5
+ * @package Meta Box
6
+ */
7
+
8
+ /**
9
+ * Array helper class.
10
+ *
11
+ * @package Meta Box
12
+ */
13
+ class RWMB_Helpers_Array {
14
+ /**
15
+ * Convert a comma separated string to array.
16
+ *
17
+ * @param string $csv Comma separated string.
18
+ * @return array
19
+ */
20
+ public static function from_csv( $csv ) {
21
+ return is_array( $csv ) ? $csv : array_filter( array_map( 'trim', explode( ',', $csv . ',' ) ) );
22
+ }
23
+
24
+ /**
25
+ * Change array key.
26
+ *
27
+ * @param array $array Input array.
28
+ * @param string $from From key.
29
+ * @param string $to To key.
30
+ */
31
+ public static function change_key( &$array, $from, $to ) {
32
+ if ( isset( $array[ $from ] ) ) {
33
+ $array[ $to ] = $array[ $from ];
34
+ }
35
+ unset( $array[ $from ] );
36
+ }
37
+ }
inc/helpers/field.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Field helper functions.
4
+ *
5
+ * @package Meta Box
6
+ */
7
+
8
+ /**
9
+ * Field helper class.
10
+ *
11
+ * @package Meta Box
12
+ */
13
+ class RWMB_Helpers_Field {
14
+ /**
15
+ * Localize a script only once.
16
+ *
17
+ * @link https://github.com/rilwis/meta-box/issues/850
18
+ *
19
+ * @param string $handle Script handle.
20
+ * @param string $name Object name.
21
+ * @param array $data Localized data.
22
+ */
23
+ public static function localize_script_once( $handle, $name, $data ) {
24
+ if ( ! wp_scripts()->get_data( $handle, 'data' ) ) {
25
+ wp_localize_script( $handle, $name, $data );
26
+ }
27
+ }
28
+
29
+ /**
30
+ * Get field class name.
31
+ *
32
+ * @param array $field Field settings.
33
+ * @return string
34
+ */
35
+ public static function get_class( $field ) {
36
+ $type = self::get_type( $field );
37
+ $class = 'RWMB_' . RWMB_Helpers_String::title_case( $type ) . '_Field';
38
+ return class_exists( $class ) ? $class : 'RWMB_Input_Field';
39
+ }
40
+
41
+ /**
42
+ * Get field type.
43
+ *
44
+ * @param array $field Field settings.
45
+ * @return string
46
+ */
47
+ private static function get_type( $field ) {
48
+ $type = isset( $field['type'] ) ? $field['type'] : 'input';
49
+ $map = array(
50
+ 'file_advanced' => 'media',
51
+ 'plupload_image' => 'image_upload',
52
+ 'url' => 'text',
53
+ );
54
+
55
+ return isset( $map[ $type ] ) ? $map[ $type ] : $type;
56
+ }
57
+ }
inc/helpers/string.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * String helper functions.
4
+ *
5
+ * @package Meta Box
6
+ */
7
+
8
+ /**
9
+ * String helper class.
10
+ *
11
+ * @package Meta Box
12
+ */
13
+ class RWMB_Helpers_String {
14
+ /**
15
+ * Convert text to Title_Case.
16
+ *
17
+ * @param string $text Input text.
18
+ * @return string
19
+ */
20
+ public static function title_case( $text ) {
21
+ $text = str_replace( array( '-', '_' ), ' ', $text );
22
+ $text = ucwords( $text );
23
+ $text = str_replace( ' ', '_', $text );
24
+
25
+ return $text;
26
+ }
27
+ }
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', '4.16.3' );
22
 
23
  list( $path, $url ) = self::get_path( dirname( dirname( __FILE__ ) ) );
24
 
@@ -80,6 +80,7 @@ class RWMB_Loader {
80
  $autoloader->add( RWMB_INC_DIR . 'walkers', 'RWMB_Walker_' );
81
  $autoloader->add( RWMB_INC_DIR . 'interfaces', 'RWMB_', '_Interface' );
82
  $autoloader->add( RWMB_INC_DIR . 'storages', 'RWMB_', '_Storage' );
 
83
  $autoloader->register();
84
 
85
  // Plugin core.
18
  */
19
  protected function constants() {
20
  // Script version, used to add version for scripts and styles.
21
+ define( 'RWMB_VER', '4.17.0' );
22
 
23
  list( $path, $url ) = self::get_path( dirname( dirname( __FILE__ ) ) );
24
 
80
  $autoloader->add( RWMB_INC_DIR . 'walkers', 'RWMB_Walker_' );
81
  $autoloader->add( RWMB_INC_DIR . 'interfaces', 'RWMB_', '_Interface' );
82
  $autoloader->add( RWMB_INC_DIR . 'storages', 'RWMB_', '_Storage' );
83
+ $autoloader->add( RWMB_INC_DIR . 'helpers', 'RWMB_Helpers_' );
84
  $autoloader->register();
85
 
86
  // Plugin core.
inc/meta-box.php CHANGED
@@ -11,6 +11,18 @@
11
  /**
12
  * The main meta box class.
13
  *
 
 
 
 
 
 
 
 
 
 
 
 
14
  * @package Meta Box
15
  */
16
  class RW_Meta_Box {
@@ -52,12 +64,7 @@ class RW_Meta_Box {
52
  $meta_box = self::normalize( $meta_box );
53
  $this->meta_box = $meta_box;
54
 
55
- $storage = $this->get_storage();
56
- if ( ! $storage ) {
57
- return;
58
- }
59
-
60
- $this->meta_box['fields'] = self::normalize_fields( $meta_box['fields'], $storage );
61
 
62
  $this->meta_box = apply_filters( 'rwmb_meta_box_settings', $this->meta_box );
63
 
@@ -196,12 +203,10 @@ class RW_Meta_Box {
196
  * @return array
197
  */
198
  public function postbox_classes( $classes ) {
199
- if ( $this->closed && ! in_array( 'closed', $classes ) ) {
200
  $classes[] = 'closed';
201
  }
202
- if ( 'seamless' === $this->style ) {
203
- $classes[] = 'rwmb-seamless';
204
- }
205
 
206
  return $classes;
207
  }
@@ -264,63 +269,55 @@ class RW_Meta_Box {
264
  /**
265
  * Save data from meta box
266
  *
267
- * @param int $post_id Post ID.
268
  */
269
- public function save_post( $post_id ) {
270
  if ( ! $this->validate() ) {
271
  return;
272
  }
273
  $this->saved = true;
274
 
275
- // Make sure meta is added to the post, not a revision.
276
- if ( 'post' === $this->object_type ) {
277
- $the_post = wp_is_post_revision( $post_id );
278
- if ( $the_post ) {
279
- $post_id = $the_post;
280
- }
281
- }
282
 
283
  // Before save action.
284
- do_action( 'rwmb_before_save_post', $post_id );
285
- do_action( "rwmb_{$this->id}_before_save_post", $post_id );
286
 
287
- $this->save_fields( $post_id, $this->fields );
288
 
289
  // After save action.
290
- do_action( 'rwmb_after_save_post', $post_id );
291
- do_action( "rwmb_{$this->id}_after_save_post", $post_id );
292
  }
293
 
294
  /**
295
- * Save fields data.
296
  *
297
- * @param int $post_id Post id.
298
- * @param array $fields Fields data.
299
  */
300
- public function save_fields( $post_id, $fields ) {
301
- foreach ( $fields as $field ) {
302
- $single = $field['clone'] || ! $field['multiple'];
303
- $old = RWMB_Field::call( $field, 'raw_meta', $post_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, $post_id, $field );
310
- } else {
311
- $new = RWMB_Field::call( $field, 'value', $new, $old, $post_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 );
318
 
319
- // Call defined method to save meta value, if there's no methods, call common one.
320
- RWMB_Field::call( $field, 'save', $new, $old, $post_id );
321
 
322
- RWMB_Field::filter( 'after_save_field', null, $field, $new, $old, $post_id, $field );
323
- }
324
  }
325
 
326
  /**
@@ -366,10 +363,10 @@ class RW_Meta_Box {
366
  *
367
  * @since 4.4.1
368
  */
369
- rwmb_change_array_key( $meta_box, 'pages', 'post_types' );
370
 
371
  // Make sure the post type is an array and is sanitized.
372
- $meta_box['post_types'] = array_map( 'sanitize_key', rwmb_csv_to_array( $meta_box['post_types'] ) );
373
 
374
  return $meta_box;
375
  }
@@ -391,10 +388,7 @@ class RW_Meta_Box {
391
  $field = apply_filters( "rwmb_normalize_{$field['type']}_field", $field );
392
  $field = apply_filters( "rwmb_normalize_{$field['id']}_field", $field );
393
 
394
- // Add storage object to field.
395
- if ( $storage ) {
396
- $field['storage'] = $storage;
397
- }
398
 
399
  $fields[ $k ] = $field;
400
  }
@@ -485,9 +479,25 @@ class RW_Meta_Box {
485
  /**
486
  * Get current object id.
487
  *
488
- * @return int|string
489
  */
490
  protected function get_current_object_id() {
491
  return get_the_ID();
492
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
493
  }
11
  /**
12
  * The main meta box class.
13
  *
14
+ * @property string $id Meta Box ID.
15
+ * @property string $title Meta Box title.
16
+ * @property array $fields List of fields.
17
+ * @property array $post_types List of post types that the meta box is created for.
18
+ * @property string $style Meta Box style.
19
+ * @property bool $closed Whether to collapse the meta box when page loads.
20
+ * @property string $priority The meta box priority.
21
+ * @property string $context Where the meta box is displayed.
22
+ * @property bool $default_hidden Whether the meta box is hidden by default.
23
+ * @property bool $autosave Whether the meta box auto saves.
24
+ * @property bool $media_modal Add custom fields to media modal when viewing/editing an attachment.
25
+ *
26
  * @package Meta Box
27
  */
28
  class RW_Meta_Box {
64
  $meta_box = self::normalize( $meta_box );
65
  $this->meta_box = $meta_box;
66
 
67
+ $this->meta_box['fields'] = self::normalize_fields( $meta_box['fields'], $this->get_storage() );
 
 
 
 
 
68
 
69
  $this->meta_box = apply_filters( 'rwmb_meta_box_settings', $this->meta_box );
70
 
203
  * @return array
204
  */
205
  public function postbox_classes( $classes ) {
206
+ if ( $this->closed ) {
207
  $classes[] = 'closed';
208
  }
209
+ $classes[] = "rwmb-{$this->style}";
 
 
210
 
211
  return $classes;
212
  }
269
  /**
270
  * Save data from meta box
271
  *
272
+ * @param int $object_id Object ID.
273
  */
274
+ public function save_post( $object_id ) {
275
  if ( ! $this->validate() ) {
276
  return;
277
  }
278
  $this->saved = true;
279
 
280
+ $object_id = $this->get_real_object_id( $object_id );
281
+ $this->set_object_id( $object_id );
 
 
 
 
 
282
 
283
  // Before save action.
284
+ do_action( 'rwmb_before_save_post', $object_id );
285
+ do_action( "rwmb_{$this->id}_before_save_post", $object_id );
286
 
287
+ array_map( array( $this, 'save_field' ), $this->fields );
288
 
289
  // After save action.
290
+ do_action( 'rwmb_after_save_post', $object_id );
291
+ do_action( "rwmb_{$this->id}_after_save_post", $object_id );
292
  }
293
 
294
  /**
295
+ * Save field.
296
  *
297
+ * @param array $field Field settings.
 
298
  */
299
+ public function save_field( $field ) {
300
+ $single = $field['clone'] || ! $field['multiple'];
301
+ $old = RWMB_Field::call( $field, 'raw_meta', $this->object_id );
302
+ // @codingStandardsIgnoreLine
303
+ $new = isset( $_POST[ $field['id'] ] ) ? $_POST[ $field['id'] ] : ( $single ? '' : array() );
304
+
305
+ // Allow field class change the value.
306
+ if ( $field['clone'] ) {
307
+ $new = RWMB_Clone::value( $new, $old, $this->object_id, $field );
308
+ } else {
309
+ $new = RWMB_Field::call( $field, 'value', $new, $old, $this->object_id );
310
+ $new = RWMB_Field::filter( 'sanitize', $new, $field );
311
+ }
312
+ $new = RWMB_Field::filter( 'value', $new, $field, $old );
 
313
 
314
+ // Filter to allow the field to be modified.
315
+ $field = RWMB_Field::filter( 'field', $field, $field, $new, $old );
316
 
317
+ // Call defined method to save meta value, if there's no methods, call common one.
318
+ RWMB_Field::call( $field, 'save', $new, $old, $this->object_id );
319
 
320
+ RWMB_Field::filter( 'after_save_field', null, $field, $new, $old, $this->object_id, $field );
 
321
  }
322
 
323
  /**
363
  *
364
  * @since 4.4.1
365
  */
366
+ RWMB_Helpers_Array::change_key( $meta_box, 'pages', 'post_types' );
367
 
368
  // Make sure the post type is an array and is sanitized.
369
+ $meta_box['post_types'] = array_map( 'sanitize_key', RWMB_Helpers_Array::from_csv( $meta_box['post_types'] ) );
370
 
371
  return $meta_box;
372
  }
388
  $field = apply_filters( "rwmb_normalize_{$field['type']}_field", $field );
389
  $field = apply_filters( "rwmb_normalize_{$field['id']}_field", $field );
390
 
391
+ $field['storage'] = $storage;
 
 
 
392
 
393
  $fields[ $k ] = $field;
394
  }
479
  /**
480
  * Get current object id.
481
  *
482
+ * @return int
483
  */
484
  protected function get_current_object_id() {
485
  return get_the_ID();
486
  }
487
+
488
+ /**
489
+ * Get real object ID when submitting.
490
+ *
491
+ * @param int $object_id Object ID.
492
+ * @return int
493
+ */
494
+ protected function get_real_object_id( $object_id ) {
495
+ // Make sure meta is added to the post, not a revision.
496
+ if ( 'post' !== $this->object_type ) {
497
+ return $object_id;
498
+ }
499
+ $parent = wp_is_post_revision( $object_id );
500
+
501
+ return $parent ? $parent : $object_id;
502
+ }
503
  }
inc/storage-registry.php CHANGED
@@ -25,10 +25,6 @@ class RWMB_Storage_Registry {
25
  */
26
  public function get( $class_name ) {
27
  if ( empty( $this->storages[ $class_name ] ) ) {
28
- if ( ! class_exists( $class_name ) ) {
29
- return null;
30
- }
31
-
32
  $this->storages[ $class_name ] = new $class_name();
33
  }
34
 
25
  */
26
  public function get( $class_name ) {
27
  if ( empty( $this->storages[ $class_name ] ) ) {
 
 
 
 
28
  $this->storages[ $class_name ] = new $class_name();
29
  }
30
 
inc/validation.php CHANGED
@@ -43,7 +43,7 @@ class RWMB_Validation {
43
  wp_enqueue_script( 'jquery-validation-additional-methods', RWMB_JS_URL . 'jquery-validation/additional-methods.min.js', array( 'jquery-validation' ), '1.15.0', true );
44
  wp_enqueue_script( 'rwmb-validate', RWMB_JS_URL . 'validate.js', array( 'jquery-validation', 'jquery-validation-additional-methods' ), RWMB_VER, true );
45
 
46
- RWMB_Field::localize_script(
47
  'rwmb-validate',
48
  'rwmbValidate',
49
  array(
43
  wp_enqueue_script( 'jquery-validation-additional-methods', RWMB_JS_URL . 'jquery-validation/additional-methods.min.js', array( 'jquery-validation' ), '1.15.0', true );
44
  wp_enqueue_script( 'rwmb-validate', RWMB_JS_URL . 'validate.js', array( 'jquery-validation', 'jquery-validation-additional-methods' ), RWMB_VER, true );
45
 
46
+ RWMB_Helpers_Field::localize_script_once(
47
  'rwmb-validate',
48
  'rwmbValidate',
49
  array(
inc/walkers/select.php CHANGED
@@ -21,13 +21,12 @@ class RWMB_Walker_Select extends RWMB_Walker_Base {
21
  * @param int $current_object_id ID of the current item.
22
  */
23
  public function start_el( &$output, $object, $depth = 0, $args = array(), $current_object_id = 0 ) {
24
- $meta = $this->meta;
25
  $indent = str_repeat( '&nbsp;', $depth * 4 );
26
 
27
  $output .= sprintf(
28
  '<option value="%s" %s>%s%s</option>',
29
  esc_attr( $object->value ),
30
- selected( in_array( $object->value, $meta ), true, false ),
31
  $indent,
32
  esc_html( RWMB_Field::filter( 'choice_label', $object->label, $this->field, $object ) )
33
  );
21
  * @param int $current_object_id ID of the current item.
22
  */
23
  public function start_el( &$output, $object, $depth = 0, $args = array(), $current_object_id = 0 ) {
 
24
  $indent = str_repeat( '&nbsp;', $depth * 4 );
25
 
26
  $output .= sprintf(
27
  '<option value="%s" %s>%s%s</option>',
28
  esc_attr( $object->value ),
29
+ selected( in_array( $object->value, $this->meta ), true, false ),
30
  $indent,
31
  esc_html( RWMB_Field::filter( 'choice_label', $object->label, $this->field, $object ) )
32
  );
js/slider.js CHANGED
@@ -2,29 +2,31 @@ jQuery( function ( $ ) {
2
  'use strict';
3
 
4
  function rwmb_update_slider() {
5
- var $input = $( this ),
6
- $slider = $input.siblings( '.rwmb-slider' ),
7
  $valueLabel = $slider.siblings( '.rwmb-slider-value-label' ).find( 'span' ),
8
- value = $input.val(),
9
- options = $slider.data( 'options' );
10
-
11
 
12
  $slider.html( '' );
13
 
14
  if ( ! value ) {
15
  value = 0;
16
- $input.val( 0 );
17
- $valueLabel.text( '0' );
18
- }
19
- else {
20
- $valueLabel.text( value );
21
  }
 
 
 
 
 
22
 
23
- // Assign field value and callback function when slide
24
- options.value = value;
25
  options.slide = function ( event, ui ) {
26
- $input.val( ui.value );
27
- $valueLabel.text( ui.value );
 
 
 
 
 
28
  };
29
 
30
  $slider.slider( options );
2
  'use strict';
3
 
4
  function rwmb_update_slider() {
5
+ var $input = $( this ),
6
+ $slider = $input.siblings( '.rwmb-slider' ),
7
  $valueLabel = $slider.siblings( '.rwmb-slider-value-label' ).find( 'span' ),
8
+ value = $input.val(),
9
+ options = $slider.data( 'options' );
 
10
 
11
  $slider.html( '' );
12
 
13
  if ( ! value ) {
14
  value = 0;
 
 
 
 
 
15
  }
16
+ $input.val( value );
17
+ $valueLabel.text( value );
18
+
19
+ value = options.range ? value.split( '|' ) : value;
20
+ options.values = value;
21
 
 
 
22
  options.slide = function ( event, ui ) {
23
+ if ( options.range == true ) {
24
+ $input.val( ui.values[ 0 ] + '|' + ui.values[ 1 ] );
25
+ $valueLabel.html( ui.values[ 0 ] + '|' + ui.values[ 1 ] );
26
+ } else {
27
+ $input.val( ui.value );
28
+ $valueLabel.html( ui.value );
29
+ }
30
  };
31
 
32
  $slider.slider( options );
js/validate.js CHANGED
@@ -35,7 +35,7 @@ jQuery( function ( $ ) {
35
  var subRules = $( this ).data( 'rules' );
36
  $.extend( true, rules, subRules );
37
 
38
- // Required field styling
39
  $.each( subRules.rules, function ( k, v ) {
40
  if ( ! v['required'] ) {
41
  return;
@@ -44,7 +44,7 @@ jQuery( function ( $ ) {
44
  if ( ! $el.length ) {
45
  return;
46
  }
47
- $el.closest( '.rwmb-input' ).siblings( '.rwmb-label' ).append( '<span class="rwmb-required">*</span>' );
48
  } );
49
  } );
50
 
35
  var subRules = $( this ).data( 'rules' );
36
  $.extend( true, rules, subRules );
37
 
38
+ // Required field styling.
39
  $.each( subRules.rules, function ( k, v ) {
40
  if ( ! v['required'] ) {
41
  return;
44
  if ( ! $el.length ) {
45
  return;
46
  }
47
+ $el.closest( '.rwmb-input' ).siblings( '.rwmb-label' ).find( 'label' ).append( '<span class="rwmb-required">*</span>' );
48
  } );
49
  } );
50
 
meta-box.php CHANGED
@@ -1,12 +1,12 @@
1
  <?php
2
  /**
3
  * Plugin Name: Meta Box
4
- * Plugin URI: https://metabox.io
5
  * Description: Create custom meta boxes and custom fields in WordPress.
6
- * Version: 4.16.3
7
- * Author: MetaBox.io
8
- * Author URI: https://metabox.io
9
- * License: GPL2+
10
  * Text Domain: meta-box
11
  * Domain Path: /languages/
12
  *
1
  <?php
2
  /**
3
  * Plugin Name: Meta Box
4
+ * Plugin URI: https://metabox.io
5
  * Description: Create custom meta boxes and custom fields in WordPress.
6
+ * Version: 4.17.0
7
+ * Author: MetaBox.io
8
+ * Author URI: https://metabox.io
9
+ * License: GPL2+
10
  * Text Domain: meta-box
11
  * Domain Path: /languages/
12
  *
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: metabox, rilwis, fitwp, f-j-kaiser, funkatronic, PerWiklander, rua
3
  Donate link: https://metabox.io/pricing/
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.3
6
- Tested up to: 5.0.3
7
- Stable tag: 4.16.3
8
  License: GPLv2 or later
9
 
10
  Meta Box plugin is a powerful, professional developer toolkit to create custom meta boxes and custom fields for WordPress.
@@ -165,6 +165,28 @@ To getting started with the plugin, please read the [Quick Start Guide](https://
165
 
166
  == Changelog ==
167
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
168
  [See full changelog here](https://github.com/wpmetabox/meta-box/blob/master/CHANGELOG.md).
169
 
170
  == Upgrade Notice ==
3
  Donate link: https://metabox.io/pricing/
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.3
6
+ Tested up to: 5.1
7
+ Stable tag: 4.17.0
8
  License: GPLv2 or later
9
 
10
  Meta Box plugin is a powerful, professional developer toolkit to create custom meta boxes and custom fields for WordPress.
165
 
166
  == Changelog ==
167
 
168
+ = 4.17.0 - 2019-03-18 =
169
+
170
+ **Added**
171
+
172
+ - Added `range` support for `slider` field for storing 2 values.
173
+ - Added `attribute` to `[rwmb_meta]` shortcode to get only one attribute from the value (such as URL of the image or term slug).
174
+ - Added `prepend` and `append` attributes for inputs like Bootstrap's input group.
175
+
176
+ **Changed**
177
+
178
+ - Refactored the code.
179
+ - Changed shortcode attributes to use `id` (instead of `meta_key`), `object_id` (instead of `post_id`).
180
+
181
+ **Fixed**
182
+
183
+ - Fixed empty date field with save_format causes error.
184
+ - Fixed wrong position of the asterisk when the field is required and has label description.
185
+ - Fixed indirect modification of `meta_box->$fields`.
186
+ - Fixed `required` attribute not working for `file`, `image` fields.
187
+ - Fixed warning in the about page.
188
+ - Fixed box-sizing issue for settings page.
189
+
190
  [See full changelog here](https://github.com/wpmetabox/meta-box/blob/master/CHANGELOG.md).
191
 
192
  == Upgrade Notice ==