Meta Box - Version 4.12.1

Version Description

  • 2017-07-05 = #### Fixed
  • Helper function doesn't work. #1144.
Download this release

Release Info

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

Code changes from version 4.11.2 to 4.12.1

css/image-advanced.css CHANGED
@@ -1,36 +1,27 @@
 
 
 
 
 
1
  /* Image */
2
- .rwmb-image-item {
3
- position: relative;
4
- float: left;
5
- padding: 0;
6
- margin: 0 5px 5px 0;
7
- box-sizing: border-box;
8
- }
9
- .rwmb-image-item.thumbnail .rwmb-media-preview,
10
- .rwmb-image-item.thumbnail{
11
  width: 150px;
12
  }
13
- .rwmb-image-item.medium .rwmb-media-preview,
14
  .rwmb-image-item.medium {
15
  width: 300px;
16
  }
17
- .rwmb-image-item.large .rwmb-media-preview,
18
  .rwmb-image-item.large {
19
  width: 1024px;
20
  }
21
 
22
- .rwmb-image-item .dashicons {
23
- font-size: 20px;
24
- width: 20px;
25
- height: 20px;
26
- }
27
  .rwmb-media-bar {
28
  position: absolute;
29
  z-index: 10;
30
- display: none;
31
- right: 5px;
32
- top: 5px;
33
  color: #fff;
 
 
34
  }
35
  .rwmb-media-bar a {
36
  text-decoration: none;
@@ -38,15 +29,17 @@
38
  }
39
  .rwmb-overlay {
40
  position: absolute;
41
- top: 0;
42
- bottom: 0;
43
- left: 0;
44
- right: 0;
45
- background: rgba(0, 0, 0, .6);
46
- display: none;
47
- }
48
- .rwmb-image-item:hover .rwmb-media-bar,
 
 
 
49
  .rwmb-image-item:hover .rwmb-overlay {
50
- display: block;
51
- cursor: move;
52
  }
1
+ .rwmb-image-item .rwmb-media-preview {
2
+ width: auto;
3
+ float: none;
4
+ }
5
+
6
  /* Image */
7
+ .rwmb-image-item.thumbnail {
 
 
 
 
 
 
 
 
8
  width: 150px;
9
  }
 
10
  .rwmb-image-item.medium {
11
  width: 300px;
12
  }
 
13
  .rwmb-image-item.large {
14
  width: 1024px;
15
  }
16
 
 
 
 
 
 
17
  .rwmb-media-bar {
18
  position: absolute;
19
  z-index: 10;
20
+ right: 12px;
21
+ top: 12px;
 
22
  color: #fff;
23
+ opacity: 0;
24
+ transition: opacity .2s;
25
  }
26
  .rwmb-media-bar a {
27
  text-decoration: none;
29
  }
30
  .rwmb-overlay {
31
  position: absolute;
32
+ top: 8px;
33
+ bottom: 8px;
34
+ left: 8px;
35
+ right: 8px;
36
+ background: #000;
37
+ opacity: 0;
38
+ transition: opacity .2s;
39
+ }
40
+ .rwmb-image-item:hover .rwmb-media-bar {
41
+ opacity: 1;
42
+ }
43
  .rwmb-image-item:hover .rwmb-overlay {
44
+ opacity: .6;
 
45
  }
css/media.css CHANGED
@@ -1,47 +1,18 @@
1
  .rwmb-media-list {
2
- margin: 0 0 5px;
3
  overflow: hidden;
4
  }
5
- .rwmb-media-item {
 
 
 
6
  overflow: hidden;
7
- margin-bottom: 10px;
8
  }
9
  .rwmb-media-preview {
10
  width: 60px;
11
  float: left;
12
  position: relative;
13
  }
14
- .rwmb-media-preview:before {
15
- content: '';
16
- display: block;
17
- padding-top: 100%;
18
- }
19
- .rwmb-media-content {
20
- position: absolute;
21
- overflow: hidden;
22
- top: 0;
23
- left: 0;
24
- bottom: 0;
25
- right: 0;
26
- }
27
- .rwmb-media-content .centered {
28
- position: absolute;
29
- top: 0;
30
- left: 0;
31
- width: 100%;
32
- height: 100%;
33
- -webkit-transform: translate(50%, 50%);
34
- -ms-transform: translate(50%, 50%);
35
- transform: translate(50%, 50%);
36
- }
37
- .rwmb-media-content img {
38
- -webkit-transform: translate(-50%, -50%);
39
- -ms-transform: translate(-50%, -50%);
40
- transform: translate(-50%, -50%);
41
- max-height: 100%;
42
- max-width: 100%;
43
- border-radius: 3px;
44
- }
45
  .rwmb-media-info {
46
  margin-left: 65px;
47
  }
@@ -57,8 +28,7 @@
57
  font-size: 11px;
58
  color: inherit;
59
  }
60
- .rwmb-edit-media .dashicons,
61
- .rwmb-remove-media .dashicons {
62
  font-size: 12px;
63
  width: 12px;
64
  height: 12px;
1
  .rwmb-media-list {
2
+ margin: -8px 0 0 -8px;
3
  overflow: hidden;
4
  }
5
+ .rwmb-media-item.attachment {
6
+ float: none;
7
+ text-align: left;
8
+ width: auto;
9
  overflow: hidden;
 
10
  }
11
  .rwmb-media-preview {
12
  width: 60px;
13
  float: left;
14
  position: relative;
15
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  .rwmb-media-info {
17
  margin-left: 65px;
18
  }
28
  font-size: 11px;
29
  color: inherit;
30
  }
31
+ .rwmb-media-info .dashicons {
 
32
  font-size: 12px;
33
  width: 12px;
34
  height: 12px;
img/loader.gif DELETED
Binary file
inc/clone.php CHANGED
@@ -33,7 +33,12 @@ class RWMB_Clone {
33
  $sub_field['address_field'] = $field['address_field'] . "_{$index}";
34
  }
35
  $sub_field['id'] = $field['id'] . "_{$index}";
 
 
 
 
36
  }
 
37
  if ( $field['multiple'] ) {
38
  $sub_field['field_name'] .= '[]';
39
  }
@@ -56,7 +61,7 @@ class RWMB_Clone {
56
  $input_html .= '</div>';
57
 
58
  $field_html .= $input_html;
59
- }
60
 
61
  return $field_html;
62
  }
@@ -94,7 +99,7 @@ class RWMB_Clone {
94
  if ( ! $field['clone'] ) {
95
  return '';
96
  }
97
- $text = RWMB_Field::filter( 'add_clone_button_text', $field['add_button'] );
98
  return '<a href="#" class="rwmb-button button-primary add-clone">' . esc_html( $text ) . '</a>';
99
  }
100
 
33
  $sub_field['address_field'] = $field['address_field'] . "_{$index}";
34
  }
35
  $sub_field['id'] = $field['id'] . "_{$index}";
36
+
37
+ if ( ! empty( $sub_field['attributes']['id'] ) ) {
38
+ $sub_field['attributes']['id'] = $sub_field['attributes']['id'] . "_{$index}";
39
+ }
40
  }
41
+
42
  if ( $field['multiple'] ) {
43
  $sub_field['field_name'] .= '[]';
44
  }
61
  $input_html .= '</div>';
62
 
63
  $field_html .= $input_html;
64
+ } // End foreach().
65
 
66
  return $field_html;
67
  }
99
  if ( ! $field['clone'] ) {
100
  return '';
101
  }
102
+ $text = RWMB_Field::filter( 'add_clone_button_text', $field['add_button'], $field );
103
  return '<a href="#" class="rwmb-button button-primary add-clone">' . esc_html( $text ) . '</a>';
104
  }
105
 
inc/field.php CHANGED
@@ -184,8 +184,13 @@ abstract class RWMB_Field {
184
  return '';
185
  }
186
 
187
- $object_type = ! empty( $args['object_type'] ) ? $args['object_type'] : 'post';
188
- $storage = rwmb_get_storage( $object_type );
 
 
 
 
 
189
 
190
  if ( ! isset( $args['single'] ) ) {
191
  $args['single'] = $field['clone'] || ! $field['multiple'];
@@ -282,10 +287,11 @@ abstract class RWMB_Field {
282
  */
283
  public static function save( $new, $old, $post_id, $field ) {
284
  $name = $field['id'];
 
285
 
286
  // Remove post meta if it's empty.
287
  if ( '' === $new || array() === $new ) {
288
- delete_post_meta( $post_id, $name );
289
  return;
290
  }
291
 
@@ -300,7 +306,7 @@ abstract class RWMB_Field {
300
  }
301
  // Reset indexes.
302
  $new = array_values( $new );
303
- update_post_meta( $post_id, $name, $new );
304
  return;
305
  }
306
 
@@ -310,17 +316,17 @@ abstract class RWMB_Field {
310
  $new = (array) $new;
311
  $new_values = array_diff( $new, $old );
312
  foreach ( $new_values as $new_value ) {
313
- add_post_meta( $post_id, $name, $new_value, false );
314
  }
315
  $old_values = array_diff( $old, $new );
316
  foreach ( $old_values as $old_value ) {
317
- delete_post_meta( $post_id, $name, $old_value );
318
  }
319
  return;
320
  }
321
 
322
  // Default: just update post meta.
323
- update_post_meta( $post_id, $name, $new );
324
  }
325
 
326
  /**
@@ -352,6 +358,7 @@ abstract class RWMB_Field {
352
  'class' => '',
353
  'disabled' => false,
354
  'required' => false,
 
355
  'attributes' => array(),
356
  ) );
357
 
@@ -368,11 +375,12 @@ abstract class RWMB_Field {
368
  */
369
  public static function get_attributes( $field, $value = null ) {
370
  $attributes = wp_parse_args( $field['attributes'], array(
371
- 'disabled' => $field['disabled'],
372
- 'required' => $field['required'],
373
- 'id' => $field['id'],
374
- 'class' => '',
375
- 'name' => $field['field_name'],
 
376
  ) );
377
 
378
  $attributes['class'] = implode( ' ', array_merge( array( "rwmb-{$field['type']}" ), (array) $attributes['class'] ) );
184
  return '';
185
  }
186
 
187
+ if ( isset( $args['object_type'] ) ) {
188
+ $storage = rwmb_get_storage( $args['object_type'] );
189
+ } elseif ( isset( $field['storage'] ) ) {
190
+ $storage = $field['storage'];
191
+ } else {
192
+ $storage = rwmb_get_storage( 'post' );
193
+ }
194
 
195
  if ( ! isset( $args['single'] ) ) {
196
  $args['single'] = $field['clone'] || ! $field['multiple'];
287
  */
288
  public static function save( $new, $old, $post_id, $field ) {
289
  $name = $field['id'];
290
+ $storage = $field['storage'];
291
 
292
  // Remove post meta if it's empty.
293
  if ( '' === $new || array() === $new ) {
294
+ $storage->delete( $post_id, $name );
295
  return;
296
  }
297
 
306
  }
307
  // Reset indexes.
308
  $new = array_values( $new );
309
+ $storage->update( $post_id, $name, $new );
310
  return;
311
  }
312
 
316
  $new = (array) $new;
317
  $new_values = array_diff( $new, $old );
318
  foreach ( $new_values as $new_value ) {
319
+ $storage->add( $post_id, $name, $new_value, false );
320
  }
321
  $old_values = array_diff( $old, $new );
322
  foreach ( $old_values as $old_value ) {
323
+ $storage->delete( $post_id, $name, $old_value );
324
  }
325
  return;
326
  }
327
 
328
  // Default: just update post meta.
329
+ $storage->update( $post_id, $name, $new );
330
  }
331
 
332
  /**
358
  'class' => '',
359
  'disabled' => false,
360
  'required' => false,
361
+ 'autofocus' => false,
362
  'attributes' => array(),
363
  ) );
364
 
375
  */
376
  public static function get_attributes( $field, $value = null ) {
377
  $attributes = wp_parse_args( $field['attributes'], array(
378
+ 'disabled' => $field['disabled'],
379
+ 'autofocus' => $field['autofocus'],
380
+ 'required' => $field['required'],
381
+ 'id' => $field['id'],
382
+ 'class' => '',
383
+ 'name' => $field['field_name'],
384
  ) );
385
 
386
  $attributes['class'] = implode( ' ', array_merge( array( "rwmb-{$field['type']}" ), (array) $attributes['class'] ) );
inc/fields/color.php CHANGED
@@ -14,7 +14,8 @@ class RWMB_Color_Field extends RWMB_Text_Field {
14
  */
15
  public static function admin_enqueue_scripts() {
16
  wp_enqueue_style( 'rwmb-color', RWMB_CSS_URL . 'color.css', array( 'wp-color-picker' ), RWMB_VER );
17
- wp_enqueue_script( 'rwmb-color', RWMB_JS_URL . 'color.js', array( 'wp-color-picker' ), RWMB_VER, true );
 
18
  }
19
 
20
  /**
@@ -27,7 +28,8 @@ class RWMB_Color_Field extends RWMB_Text_Field {
27
  $field = wp_parse_args( $field, array(
28
  'size' => 7,
29
  'maxlength' => 7,
30
- 'pattern' => '^#+([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$',
 
31
  'js_options' => array(),
32
  ) );
33
 
@@ -56,6 +58,10 @@ class RWMB_Color_Field extends RWMB_Text_Field {
56
  ) );
57
  $attributes['type'] = 'text';
58
 
 
 
 
 
59
  return $attributes;
60
  }
61
 
14
  */
15
  public static function admin_enqueue_scripts() {
16
  wp_enqueue_style( 'rwmb-color', RWMB_CSS_URL . 'color.css', array( 'wp-color-picker' ), RWMB_VER );
17
+ wp_enqueue_script( 'wp-color-picker-alpha', RWMB_JS_URL . 'wp-color-picker-alpha/wp-color-picker-alpha.min.js', array( 'wp-color-picker' ), RWMB_VER, true );
18
+ wp_enqueue_script( 'rwmb-color', RWMB_JS_URL . 'color.js', array( 'wp-color-picker', 'wp-color-picker-alpha' ), RWMB_VER, true );
19
  }
20
 
21
  /**
28
  $field = wp_parse_args( $field, array(
29
  'size' => 7,
30
  'maxlength' => 7,
31
+ 'alpha_channel' => false,
32
+ // 'pattern' => '^#+([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$',
33
  'js_options' => array(),
34
  ) );
35
 
58
  ) );
59
  $attributes['type'] = 'text';
60
 
61
+ if ( $field['alpha_channel'] ) {
62
+ $attributes['data-alpha'] = 'true';
63
+ }
64
+
65
  return $attributes;
66
  }
67
 
inc/fields/file.php CHANGED
@@ -47,12 +47,14 @@ class RWMB_File_Field extends RWMB_Field {
47
  $post_id = (int) filter_input( INPUT_POST, 'post_id', FILTER_SANITIZE_NUMBER_INT );
48
  $field_id = (string) filter_input( INPUT_POST, 'field_id' );
49
  $order = (string) filter_input( INPUT_POST, 'order' );
 
 
50
 
51
  check_ajax_referer( "rwmb-reorder-files_{$field_id}" );
52
  parse_str( $order, $items );
53
- delete_post_meta( $post_id, $field_id );
54
  foreach ( $items['item'] as $item ) {
55
- add_post_meta( $post_id, $field_id, $item, false );
56
  }
57
  wp_send_json_success();
58
  }
@@ -68,9 +70,11 @@ class RWMB_File_Field extends RWMB_Field {
68
  $field_id = (string) filter_input( INPUT_POST, 'field_id' );
69
  $attachment_id = (int) filter_input( INPUT_POST, 'attachment_id', FILTER_SANITIZE_NUMBER_INT );
70
  $force_delete = (int) filter_input( INPUT_POST, 'force_delete', FILTER_SANITIZE_NUMBER_INT );
 
 
71
 
72
  check_ajax_referer( "rwmb-delete-file_{$field_id}" );
73
- delete_post_meta( $post_id, $field_id, $attachment_id );
74
  $success = $force_delete ? wp_delete_attachment( $attachment_id ) : true;
75
 
76
  if ( $success ) {
47
  $post_id = (int) filter_input( INPUT_POST, 'post_id', FILTER_SANITIZE_NUMBER_INT );
48
  $field_id = (string) filter_input( INPUT_POST, 'field_id' );
49
  $order = (string) filter_input( INPUT_POST, 'order' );
50
+ $object_type = (string) filter_input( INPUT_POST, 'object_type' );
51
+ $storage = rwmb_get_storage( $object_type );
52
 
53
  check_ajax_referer( "rwmb-reorder-files_{$field_id}" );
54
  parse_str( $order, $items );
55
+ $storage->delete( $post_id, $field_id );
56
  foreach ( $items['item'] as $item ) {
57
+ $storage->add( $post_id, $field_id, $item, false );
58
  }
59
  wp_send_json_success();
60
  }
70
  $field_id = (string) filter_input( INPUT_POST, 'field_id' );
71
  $attachment_id = (int) filter_input( INPUT_POST, 'attachment_id', FILTER_SANITIZE_NUMBER_INT );
72
  $force_delete = (int) filter_input( INPUT_POST, 'force_delete', FILTER_SANITIZE_NUMBER_INT );
73
+ $object_type = (string) filter_input( INPUT_POST, 'object_type' );
74
+ $storage = rwmb_get_storage( $object_type );
75
 
76
  check_ajax_referer( "rwmb-delete-file_{$field_id}" );
77
+ $storage->delete( $post_id, $field_id, $attachment_id );
78
  $success = $force_delete ? wp_delete_attachment( $attachment_id ) : true;
79
 
80
  if ( $success ) {
inc/fields/input.php CHANGED
@@ -30,9 +30,10 @@ abstract class RWMB_Input_Field extends RWMB_Field {
30
  public static function normalize( $field ) {
31
  $field = parent::normalize( $field );
32
  $field = wp_parse_args( $field, array(
33
- 'size' => 30,
34
- 'datalist' => false,
35
- 'readonly' => false,
 
36
  ) );
37
  if ( $field['datalist'] ) {
38
  $field['datalist'] = wp_parse_args( $field['datalist'], array(
@@ -53,12 +54,13 @@ abstract class RWMB_Input_Field extends RWMB_Field {
53
  public static function get_attributes( $field, $value = null ) {
54
  $attributes = parent::get_attributes( $field, $value );
55
  $attributes = wp_parse_args( $attributes, array(
56
- 'list' => $field['datalist'] ? $field['datalist']['id'] : false,
57
- 'readonly' => $field['readonly'],
58
- 'value' => $value,
59
- 'placeholder' => $field['placeholder'],
60
- 'type' => $field['type'],
61
- 'size' => $field['size'],
 
62
  ) );
63
 
64
  return $attributes;
30
  public static function normalize( $field ) {
31
  $field = parent::normalize( $field );
32
  $field = wp_parse_args( $field, array(
33
+ 'autocomplete' => false,
34
+ 'size' => 30,
35
+ 'datalist' => false,
36
+ 'readonly' => false,
37
  ) );
38
  if ( $field['datalist'] ) {
39
  $field['datalist'] = wp_parse_args( $field['datalist'], array(
54
  public static function get_attributes( $field, $value = null ) {
55
  $attributes = parent::get_attributes( $field, $value );
56
  $attributes = wp_parse_args( $attributes, array(
57
+ 'autocomplete' => $field['autocomplete'],
58
+ 'list' => $field['datalist'] ? $field['datalist']['id'] : false,
59
+ 'readonly' => $field['readonly'],
60
+ 'value' => $value,
61
+ 'placeholder' => $field['placeholder'],
62
+ 'type' => $field['type'],
63
+ 'size' => $field['size'],
64
  ) );
65
 
66
  return $attributes;
inc/fields/media.php CHANGED
@@ -28,7 +28,7 @@ class RWMB_Media_Field extends RWMB_File_Field {
28
  'edit' => apply_filters( 'rwmb_media_edit_string', _x( 'Edit', 'media', 'meta-box' ) ),
29
  'view' => apply_filters( 'rwmb_media_view_string', _x( 'View', 'media', 'meta-box' ) ),
30
  'noTitle' => _x( 'No Title', 'media', 'meta-box' ),
31
- 'loadingUrl' => RWMB_URL . 'img/loader.gif',
32
  'extensions' => self::get_mime_extensions(),
33
  'select' => apply_filters( 'rwmb_media_select_string', _x( 'Select Files', 'media', 'meta-box' ) ),
34
  'or' => apply_filters( 'rwmb_media_or_string', _x( 'or', 'media', 'meta-box' ) ),
@@ -164,7 +164,8 @@ class RWMB_Media_Field extends RWMB_File_Field {
164
  * @param array $field The field parameters.
165
  */
166
  public static function save( $new, $old, $post_id, $field ) {
167
- delete_post_meta( $post_id, $field['id'] );
 
168
  parent::save( $new, array(), $post_id, $field );
169
  }
170
 
28
  'edit' => apply_filters( 'rwmb_media_edit_string', _x( 'Edit', 'media', 'meta-box' ) ),
29
  'view' => apply_filters( 'rwmb_media_view_string', _x( 'View', 'media', 'meta-box' ) ),
30
  'noTitle' => _x( 'No Title', 'media', 'meta-box' ),
31
+ 'loadingUrl' => admin_url( 'images/spinner.gif' ),
32
  'extensions' => self::get_mime_extensions(),
33
  'select' => apply_filters( 'rwmb_media_select_string', _x( 'Select Files', 'media', 'meta-box' ) ),
34
  'or' => apply_filters( 'rwmb_media_or_string', _x( 'or', 'media', 'meta-box' ) ),
164
  * @param array $field The field parameters.
165
  */
166
  public static function save( $new, $old, $post_id, $field ) {
167
+ $storage = $field['storage'];
168
+ $storage->delete( $post_id, $field['id'] );
169
  parent::save( $new, array(), $post_id, $field );
170
  }
171
 
inc/fields/oembed.php CHANGED
@@ -14,7 +14,7 @@ class RWMB_OEmbed_Field extends RWMB_Text_Field {
14
  */
15
  public static function admin_enqueue_scripts() {
16
  wp_enqueue_style( 'rwmb-oembed', RWMB_CSS_URL . 'oembed.css' );
17
- wp_enqueue_script( 'rwmb-oembed', RWMB_JS_URL . 'oembed.js', array(), RWMB_VER, true );
18
  }
19
 
20
  /**
@@ -73,10 +73,8 @@ class RWMB_OEmbed_Field extends RWMB_Text_Field {
73
  */
74
  public static function html( $meta, $field ) {
75
  return parent::html( $meta, $field ) . sprintf(
76
- '<a href="#" class="rwmb-embed-show button">%s</a>
77
- <span class="spinner"></span>
78
  <div class="rwmb-embed-media">%s</div>',
79
- esc_html__( 'Preview', 'meta-box' ),
80
  $meta ? self::get_embed( $meta ) : ''
81
  );
82
  }
14
  */
15
  public static function admin_enqueue_scripts() {
16
  wp_enqueue_style( 'rwmb-oembed', RWMB_CSS_URL . 'oembed.css' );
17
+ wp_enqueue_script( 'rwmb-oembed', RWMB_JS_URL . 'oembed.js', array( 'jquery', 'underscore' ), RWMB_VER, true );
18
  }
19
 
20
  /**
73
  */
74
  public static function html( $meta, $field ) {
75
  return parent::html( $meta, $field ) . sprintf(
76
+ '<span class="spinner"></span>
 
77
  <div class="rwmb-embed-media">%s</div>',
 
78
  $meta ? self::get_embed( $meta ) : ''
79
  );
80
  }
inc/fields/taxonomy-advanced.php CHANGED
@@ -52,10 +52,12 @@ class RWMB_Taxonomy_Advanced_Field extends RWMB_Taxonomy_Field {
52
  * @param array $field The field parameters.
53
  */
54
  public static function save( $new, $old, $post_id, $field ) {
 
 
55
  if ( $new ) {
56
- update_post_meta( $post_id, $field['id'], $new );
57
  } else {
58
- delete_post_meta( $post_id, $field['id'] );
59
  }
60
  }
61
 
52
  * @param array $field The field parameters.
53
  */
54
  public static function save( $new, $old, $post_id, $field ) {
55
+ $storage = $field['storage'];
56
+
57
  if ( $new ) {
58
+ $storage->update( $post_id, $field['id'], $new );
59
  } else {
60
+ $storage->delete( $post_id, $field['id'] );
61
  }
62
  }
63
 
inc/fields/text-list.php CHANGED
@@ -86,7 +86,8 @@ class RWMB_Text_List_Field extends RWMB_Multiple_Values_Field {
86
  * @param array $field The field parameters.
87
  */
88
  public static function save( $new, $old, $post_id, $field ) {
89
- delete_post_meta( $post_id, $field['id'] );
 
90
  parent::save( $new, array(), $post_id, $field );
91
  }
92
  }
86
  * @param array $field The field parameters.
87
  */
88
  public static function save( $new, $old, $post_id, $field ) {
89
+ $storage = $field['storage'];
90
+ $storage->delete( $post_id, $field['id'] );
91
  parent::save( $new, array(), $post_id, $field );
92
  }
93
  }
inc/fields/textarea.php CHANGED
@@ -45,11 +45,12 @@ class RWMB_Textarea_Field extends RWMB_Field {
45
  public static function normalize( $field ) {
46
  $field = parent::normalize( $field );
47
  $field = wp_parse_args( $field, array(
48
- 'cols' => 60,
49
- 'rows' => 3,
50
- 'maxlength' => false,
51
- 'wrap' => false,
52
- 'readonly' => false,
 
53
  ) );
54
 
55
  return $field;
@@ -66,12 +67,13 @@ class RWMB_Textarea_Field extends RWMB_Field {
66
  public static function get_attributes( $field, $value = null ) {
67
  $attributes = parent::get_attributes( $field, $value );
68
  $attributes = wp_parse_args( $attributes, array(
69
- 'cols' => $field['cols'],
70
- 'rows' => $field['rows'],
71
- 'maxlength' => $field['maxlength'],
72
- 'wrap' => $field['wrap'],
73
- 'readonly' => $field['readonly'],
74
- 'placeholder' => $field['placeholder'],
 
75
  ) );
76
  $attributes['class'] .= ' large-text';
77
 
45
  public static function normalize( $field ) {
46
  $field = parent::normalize( $field );
47
  $field = wp_parse_args( $field, array(
48
+ 'autocomplete' => false,
49
+ 'cols' => 60,
50
+ 'rows' => 3,
51
+ 'maxlength' => false,
52
+ 'wrap' => false,
53
+ 'readonly' => false,
54
  ) );
55
 
56
  return $field;
67
  public static function get_attributes( $field, $value = null ) {
68
  $attributes = parent::get_attributes( $field, $value );
69
  $attributes = wp_parse_args( $attributes, array(
70
+ 'autocomplete' => $field['autocomplete'],
71
+ 'cols' => $field['cols'],
72
+ 'rows' => $field['rows'],
73
+ 'maxlength' => $field['maxlength'],
74
+ 'wrap' => $field['wrap'],
75
+ 'readonly' => $field['readonly'],
76
+ 'placeholder' => $field['placeholder'],
77
  ) );
78
  $attributes['class'] .= ' large-text';
79
 
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.11.2' );
22
 
23
  list( $path, $url ) = self::get_path( dirname( dirname( __FILE__ ) ) );
24
 
18
  */
19
  protected function constants() {
20
  // Script version, used to add version for scripts and styles.
21
+ define( 'RWMB_VER', '4.12.1' );
22
 
23
  list( $path, $url ) = self::get_path( dirname( dirname( __FILE__ ) ) );
24
 
inc/meta-box.php CHANGED
@@ -34,7 +34,14 @@ class RW_Meta_Box {
34
  *
35
  * @var int
36
  */
37
- private $object_id = null;
 
 
 
 
 
 
 
38
 
39
  /**
40
  * Create meta box based on given data.
@@ -42,8 +49,13 @@ class RW_Meta_Box {
42
  * @param array $meta_box Meta box definition.
43
  */
44
  public function __construct( $meta_box ) {
 
 
 
 
 
45
  $meta_box = self::normalize( $meta_box );
46
- $meta_box['fields'] = self::normalize_fields( $meta_box['fields'] );
47
 
48
  $this->meta_box = $meta_box;
49
 
@@ -184,8 +196,9 @@ class RW_Meta_Box {
184
 
185
  // Container.
186
  printf(
187
- '<div class="rwmb-meta-box" data-autosave="%s">',
188
- $this->autosave ? 'true' : 'false'
 
189
  );
190
 
191
  wp_nonce_field( "rwmb-save-{$this->id}", "nonce_{$this->id}" );
@@ -231,7 +244,21 @@ class RW_Meta_Box {
231
  do_action( 'rwmb_before_save_post', $post_id );
232
  do_action( "rwmb_{$this->id}_before_save_post", $post_id );
233
 
234
- foreach ( $this->fields as $field ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235
  $single = $field['clone'] || ! $field['multiple'];
236
  $old = RWMB_Field::call( $field, 'raw_meta', $post_id );
237
  // @codingStandardsIgnoreLine
@@ -249,10 +276,6 @@ class RW_Meta_Box {
249
  // Call defined method to save meta value, if there's no methods, call common one.
250
  RWMB_Field::call( $field, 'save', $new, $old, $post_id );
251
  }
252
-
253
- // After save action.
254
- do_action( 'rwmb_after_save_post', $post_id );
255
- do_action( "rwmb_{$this->id}_after_save_post", $post_id );
256
  }
257
 
258
  /**
@@ -308,11 +331,12 @@ class RW_Meta_Box {
308
  /**
309
  * Normalize an array of fields
310
  *
311
- * @param array $fields Array of fields.
 
312
  *
313
  * @return array $fields Normalized fields.
314
  */
315
- public static function normalize_fields( $fields ) {
316
  foreach ( $fields as $k => $field ) {
317
  $field = RWMB_Field::call( 'normalize', $field );
318
 
@@ -321,6 +345,11 @@ class RW_Meta_Box {
321
  $field = apply_filters( "rwmb_normalize_{$field['type']}_field", $field );
322
  $field = apply_filters( "rwmb_normalize_{$field['id']}_field", $field );
323
 
 
 
 
 
 
324
  $fields[ $k ] = $field;
325
  }
326
 
@@ -386,4 +415,22 @@ class RW_Meta_Box {
386
  $this->object_id = null === $id ? get_the_ID() : $id;
387
  }
388
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
389
  }
34
  *
35
  * @var int
36
  */
37
+ protected $object_id = null;
38
+
39
+ /**
40
+ * The object type.
41
+ *
42
+ * @var string
43
+ */
44
+ protected $object_type = 'post';
45
 
46
  /**
47
  * Create meta box based on given data.
49
  * @param array $meta_box Meta box definition.
50
  */
51
  public function __construct( $meta_box ) {
52
+ $storage = $this->get_storage();
53
+ if ( ! $storage ) {
54
+ return;
55
+ }
56
+
57
  $meta_box = self::normalize( $meta_box );
58
+ $meta_box['fields'] = self::normalize_fields( $meta_box['fields'], $storage );
59
 
60
  $this->meta_box = $meta_box;
61
 
196
 
197
  // Container.
198
  printf(
199
+ '<div class="rwmb-meta-box" data-autosave="%s" data-object-type="%s">',
200
+ esc_attr( $this->autosave ? 'true' : 'false' ),
201
+ esc_attr( $this->object_type )
202
  );
203
 
204
  wp_nonce_field( "rwmb-save-{$this->id}", "nonce_{$this->id}" );
244
  do_action( 'rwmb_before_save_post', $post_id );
245
  do_action( "rwmb_{$this->id}_before_save_post", $post_id );
246
 
247
+ $this->save_fields( $post_id, $this->fields );
248
+
249
+ // After save action.
250
+ do_action( 'rwmb_after_save_post', $post_id );
251
+ do_action( "rwmb_{$this->id}_after_save_post", $post_id );
252
+ }
253
+
254
+ /**
255
+ * Save fields data.
256
+ *
257
+ * @param int $post_id Post id.
258
+ * @param array $fields Fields data.
259
+ */
260
+ public function save_fields( $post_id, $fields ) {
261
+ foreach ( $fields as $field ) {
262
  $single = $field['clone'] || ! $field['multiple'];
263
  $old = RWMB_Field::call( $field, 'raw_meta', $post_id );
264
  // @codingStandardsIgnoreLine
276
  // Call defined method to save meta value, if there's no methods, call common one.
277
  RWMB_Field::call( $field, 'save', $new, $old, $post_id );
278
  }
 
 
 
 
279
  }
280
 
281
  /**
331
  /**
332
  * Normalize an array of fields
333
  *
334
+ * @param array $fields Array of fields.
335
+ * @param RWMB_Storage_Interface $storage Storage object. Optional.
336
  *
337
  * @return array $fields Normalized fields.
338
  */
339
+ public static function normalize_fields( $fields, $storage = null ) {
340
  foreach ( $fields as $k => $field ) {
341
  $field = RWMB_Field::call( 'normalize', $field );
342
 
345
  $field = apply_filters( "rwmb_normalize_{$field['type']}_field", $field );
346
  $field = apply_filters( "rwmb_normalize_{$field['id']}_field", $field );
347
 
348
+ // Add storage object to field.
349
+ if ( $storage ) {
350
+ $field['storage'] = $storage;
351
+ }
352
+
353
  $fields[ $k ] = $field;
354
  }
355
 
415
  $this->object_id = null === $id ? get_the_ID() : $id;
416
  }
417
  }
418
+
419
+ /**
420
+ * Get object type.
421
+ *
422
+ * @return string
423
+ */
424
+ public function get_object_type() {
425
+ return $this->object_type;
426
+ }
427
+
428
+ /**
429
+ * Get storage object.
430
+ *
431
+ * @return RWMB_Storage_Interface
432
+ */
433
+ protected function get_storage() {
434
+ return rwmb_get_storage( $this->object_type );
435
+ }
436
  }
inc/storage-registry.php CHANGED
@@ -25,6 +25,10 @@ class RWMB_Storage_Registry {
25
  */
26
  public function get( $class_name ) {
27
  if ( empty( $this->storages[ $class_name ] ) ) {
 
 
 
 
28
  $this->storages[ $class_name ] = new $class_name();
29
  }
30
 
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
 
inc/storages/base.php ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Base storage
4
+ *
5
+ * @package Meta Box
6
+ */
7
+
8
+ /**
9
+ * Class RWMB_Base_Storage
10
+ */
11
+ class RWMB_Base_Storage implements RWMB_Storage_Interface {
12
+
13
+ /**
14
+ * Object type.
15
+ *
16
+ * @var string
17
+ */
18
+ protected $object_type;
19
+
20
+ /**
21
+ * Retrieve metadata for the specified object.
22
+ *
23
+ * @param int $object_id ID of the object metadata is for.
24
+ * @param string $meta_key Optional. Metadata key. If not specified, retrieve all metadata for
25
+ * the specified object.
26
+ * @param bool|array $args Optional, default is false.
27
+ * If true, return only the first value of the specified meta_key.
28
+ * If is array, use the `single` element.
29
+ * This parameter has no effect if meta_key is not specified.
30
+ * @return mixed Single metadata value, or array of values.
31
+ *
32
+ * @see get_metadata()
33
+ */
34
+ public function get( $object_id, $meta_key, $args = false ) {
35
+ if ( is_array( $args ) ) {
36
+ $single = ! empty( $args['single'] );
37
+ } else {
38
+ $single = (bool) $args;
39
+ }
40
+
41
+ return get_metadata( $this->object_type, $object_id, $meta_key, $single );
42
+ }
43
+
44
+ /**
45
+ * Add metadata
46
+ *
47
+ * @param int $object_id ID of the object metadata is for.
48
+ * @param string $meta_key Metadata key.
49
+ * @param mixed $meta_value Metadata value. Must be serializable if non-scalar.
50
+ * @param bool $unique Optional, default is false.
51
+ * Whether the specified metadata key should be unique for the object.
52
+ * If true, and the object already has a value for the specified metadata key,
53
+ * no change will be made.
54
+ * @return int|false The meta ID on success, false on failure.
55
+ *
56
+ * @see add_metadata()
57
+ */
58
+ public function add( $object_id, $meta_key, $meta_value, $unique = false ) {
59
+ return add_metadata( $this->object_type, $object_id, $meta_key, $meta_value, $unique );
60
+ }
61
+
62
+ /**
63
+ * Update metadata.
64
+ *
65
+ * @param int $object_id ID of the object metadata is for.
66
+ * @param string $meta_key Metadata key.
67
+ * @param mixed $meta_value Metadata value. Must be serializable if non-scalar.
68
+ * @param mixed $prev_value Optional. If specified, only update existing metadata entries with
69
+ * the specified value. Otherwise, update all entries.
70
+ * @return int|bool Meta ID if the key didn't exist, true on successful update, false on failure.
71
+ *
72
+ * @see update_metadata()
73
+ */
74
+ public function update( $object_id, $meta_key, $meta_value, $prev_value = '' ) {
75
+ return update_metadata( $this->object_type, $object_id, $meta_key, $meta_value, $prev_value );
76
+ }
77
+
78
+ /**
79
+ * Delete metadata.
80
+ *
81
+ * @param int $object_id ID of the object metadata is for.
82
+ * @param string $meta_key Metadata key.
83
+ * @param mixed $meta_value Optional. Metadata value. Must be serializable if non-scalar. If specified, only delete
84
+ * metadata entries with this value. Otherwise, delete all entries with the specified meta_key.
85
+ * Pass `null, `false`, or an empty string to skip this check. (For backward compatibility,
86
+ * it is not possible to pass an empty string to delete those entries with an empty string
87
+ * for a value).
88
+ * @param bool $delete_all Optional, default is false. If true, delete matching metadata entries for all objects,
89
+ * ignoring the specified object_id. Otherwise, only delete matching metadata entries for
90
+ * the specified object_id.
91
+ * @return bool True on successful delete, false on failure.
92
+ *
93
+ * @see delete_metadata()
94
+ */
95
+ public function delete( $object_id, $meta_key, $meta_value = '', $delete_all = false ) {
96
+ return delete_metadata( $this->object_type, $object_id, $meta_key, $meta_value, $delete_all );
97
+ }
98
+ }
inc/storages/post.php CHANGED
@@ -8,18 +8,12 @@
8
  /**
9
  * Class RWMB_Post_Storage
10
  */
11
- class RWMB_Post_Storage implements RWMB_Storage_Interface {
12
 
13
  /**
14
- * Get value from storage.
15
  *
16
- * @param int $object_id Object id.
17
- * @param string $name Field name.
18
- * @param array $args Custom arguments.
19
- * @return mixed
20
  */
21
- public function get( $object_id, $name, $args = array() ) {
22
- $single = ! empty( $args['single'] );
23
- return get_post_meta( $object_id, $name, $single );
24
- }
25
  }
8
  /**
9
  * Class RWMB_Post_Storage
10
  */
11
+ class RWMB_Post_Storage extends RWMB_Base_Storage {
12
 
13
  /**
14
+ * Object type.
15
  *
16
+ * @var string
 
 
 
17
  */
18
+ protected $object_type = 'post';
 
 
 
19
  }
inc/templates/image-advanced.php CHANGED
@@ -1,7 +1,7 @@
1
  <script id="tmpl-rwmb-image-item" type="text/html">
2
  <input type="hidden" name="{{{ data.controller.fieldName }}}" value="{{{ data.id }}}" class="rwmb-media-input">
3
- <div class="rwmb-media-preview">
4
- <div class="rwmb-media-content">
5
  <div class="centered">
6
  <# if ( 'image' === data.type && data.sizes ) { #>
7
  <# if ( data.sizes[data.controller.imageSize] ) { #>
1
  <script id="tmpl-rwmb-image-item" type="text/html">
2
  <input type="hidden" name="{{{ data.controller.fieldName }}}" value="{{{ data.id }}}" class="rwmb-media-input">
3
+ <div class="rwmb-media-preview attachment-preview">
4
+ <div class="rwmb-media-content thumbnail">
5
  <div class="centered">
6
  <# if ( 'image' === data.type && data.sizes ) { #>
7
  <# if ( data.sizes[data.controller.imageSize] ) { #>
inc/templates/media.php CHANGED
@@ -1,7 +1,7 @@
1
  <script id="tmpl-rwmb-media-item" type="text/html">
2
  <input type="hidden" name="{{{ data.controller.fieldName }}}" value="{{{ data.id }}}" class="rwmb-media-input">
3
- <div class="rwmb-media-preview">
4
- <div class="rwmb-media-content">
5
  <div class="centered">
6
  <# if ( 'image' === data.type && data.sizes ) { #>
7
  <# if ( data.sizes.thumbnail ) { #>
1
  <script id="tmpl-rwmb-media-item" type="text/html">
2
  <input type="hidden" name="{{{ data.controller.fieldName }}}" value="{{{ data.id }}}" class="rwmb-media-input">
3
+ <div class="rwmb-media-preview attachment-preview">
4
+ <div class="rwmb-media-content thumbnail">
5
  <div class="centered">
6
  <# if ( 'image' === data.type && data.sizes ) { #>
7
  <# if ( data.sizes.thumbnail ) { #>
js/clone.js CHANGED
@@ -22,8 +22,10 @@ jQuery( function ( $ ) {
22
  // ID attribute
23
  var id = this.id;
24
  if ( id ) {
25
- $field.attr( 'id', cloneIndex.replace( index, id, '_' ) );
26
  }
 
 
27
  } );
28
 
29
  // Address button's value attribute
@@ -43,12 +45,17 @@ jQuery( function ( $ ) {
43
  * @param alternative Check if attribute does not contain any integer, will reset the attribute?
44
  * @return string
45
  */
46
- replace: function ( index, value, before, after, alternative ) {
47
  before = before || '';
48
  after = after || '';
49
- alternative = alternative || true;
50
 
51
- var regex = new RegExp( cloneIndex.escapeRegex( before ) + '(\\d+)' + cloneIndex.escapeRegex( after ) + '$' ),
 
 
 
 
 
 
52
  newValue = before + index + after;
53
 
54
  return regex.test( value ) ? value.replace( regex, newValue ) : (alternative ? value + newValue : value );
22
  // ID attribute
23
  var id = this.id;
24
  if ( id ) {
25
+ $field.attr( 'id', cloneIndex.replace( index, id, '_', '', true, true ) );
26
  }
27
+
28
+ $field.trigger( 'update_index', index );
29
  } );
30
 
31
  // Address button's value attribute
45
  * @param alternative Check if attribute does not contain any integer, will reset the attribute?
46
  * @return string
47
  */
48
+ replace: function ( index, value, before, after, alternative, isEnd ) {
49
  before = before || '';
50
  after = after || '';
 
51
 
52
+ if ( typeof alternative === 'undefined' ) {
53
+ alternative = true;
54
+ }
55
+
56
+ var end = isEnd ? '$' : '';
57
+
58
+ var regex = new RegExp( cloneIndex.escapeRegex( before ) + '(\\d+)' + cloneIndex.escapeRegex( after ) + end ),
59
  newValue = before + index + after;
60
 
61
  return regex.test( value ) ? value.replace( regex, newValue ) : (alternative ? value + newValue : value );
js/file-upload.js CHANGED
@@ -49,7 +49,9 @@ jQuery( function ( $ ) {
49
  extensions = this.getExtensions().join( ',' ),
50
  max_file_size;
51
  this.plupload = $.extend( true, {
52
- multipart_params: {},
 
 
53
  multipart: true,
54
  urlstream_upload: true,
55
  drop_element: this.dropzone,
@@ -72,14 +74,6 @@ jQuery( function ( $ ) {
72
  this.plupload.required_features.send_binary_string = true;
73
  }
74
 
75
- if ( $('#post_ID').length && $('#post_ID').val() ) {
76
- if ( -1 === this.plupload.url.indexOf('?') ) {
77
- this.plupload.url += "?post_id=" + $('#post_ID').val();
78
- } else {
79
- this.plupload.url += "&post_id=" + $('#post_ID').val();
80
- }
81
- }
82
-
83
  // Initialize the plupload instance.
84
  this.uploader = new plupload.Uploader( this.plupload );
85
  this.uploader.init();
49
  extensions = this.getExtensions().join( ',' ),
50
  max_file_size;
51
  this.plupload = $.extend( true, {
52
+ multipart_params: {
53
+ post_id : $( '#post_ID' ).val()
54
+ },
55
  multipart: true,
56
  urlstream_upload: true,
57
  drop_element: this.dropzone,
74
  this.plupload.required_features.send_binary_string = true;
75
  }
76
 
 
 
 
 
 
 
 
 
77
  // Initialize the plupload instance.
78
  this.uploader = new plupload.Uploader( this.plupload );
79
  this.uploader.init();
js/file.js CHANGED
@@ -37,6 +37,7 @@
37
  _ajax_nonce: $uploaded.data( 'delete_nonce' ),
38
  post_id: $( '#post_ID' ).val(),
39
  field_id: $uploaded.data( 'field_id' ),
 
40
  attachment_id: $this.data( 'attachment_id' ),
41
  force_delete: $uploaded.data( 'force_delete' )
42
  };
@@ -61,7 +62,8 @@
61
  action: 'rwmb_reorder_files',
62
  _ajax_nonce: $this.data( 'reorder_nonce' ),
63
  post_id: $( '#post_ID' ).val(),
64
- field_id: $this.data( 'field_id' )
 
65
  };
66
  $this.sortable( {
67
  placeholder: 'ui-state-highlight',
37
  _ajax_nonce: $uploaded.data( 'delete_nonce' ),
38
  post_id: $( '#post_ID' ).val(),
39
  field_id: $uploaded.data( 'field_id' ),
40
+ object_type: $this.closest('.rwmb-meta-box').attr('data-object-type'),
41
  attachment_id: $this.data( 'attachment_id' ),
42
  force_delete: $uploaded.data( 'force_delete' )
43
  };
62
  action: 'rwmb_reorder_files',
63
  _ajax_nonce: $this.data( 'reorder_nonce' ),
64
  post_id: $( '#post_ID' ).val(),
65
+ field_id: $this.data( 'field_id' ),
66
+ object_type: $this.closest('.rwmb-meta-box').attr('data-object-type')
67
  };
68
  $this.sortable( {
69
  placeholder: 'ui-state-highlight',
js/image-advanced.js CHANGED
@@ -14,7 +14,7 @@ jQuery( function ( $ ) {
14
  this.list = new MediaList( {
15
  controller: this.controller,
16
  itemView: MediaItem.extend( {
17
- className: 'rwmb-image-item',
18
  template: wp.template( 'rwmb-image-item' ),
19
  initialize: function( models, options ) {
20
  MediaItem.prototype.initialize.call( this, models, options );
14
  this.list = new MediaList( {
15
  controller: this.controller,
16
  itemView: MediaItem.extend( {
17
+ className: 'rwmb-image-item attachment',
18
  template: wp.template( 'rwmb-image-item' ),
19
  initialize: function( models, options ) {
20
  MediaItem.prototype.initialize.call( this, models, options );
js/map-frontend.js CHANGED
@@ -34,6 +34,11 @@ jQuery( function ( $ ) {
34
 
35
  // Typcast zoom to a number
36
  mapOptions.zoom *= 1;
 
 
 
 
 
37
  map = new google.maps.Map( this, mapOptions );
38
 
39
  // Set marker
34
 
35
  // Typcast zoom to a number
36
  mapOptions.zoom *= 1;
37
+
38
+ if ( typeof mapOptions.styles === 'string' ) {
39
+ mapOptions.styles = JSON.parse(mapOptions.styles);
40
+ }
41
+
42
  map = new google.maps.Map( this, mapOptions );
43
 
44
  // Set marker
js/media.js CHANGED
@@ -7,9 +7,12 @@ jQuery( function ( $ ) {
7
 
8
  var views = rwmb.views = rwmb.views || {},
9
  models = rwmb.models = rwmb.models || {},
10
- MediaCollection, Controller, MediaField, MediaList, MediaItem, MediaButton, MediaStatus, EditMedia, MediaDetails;
 
 
 
11
 
12
- MediaCollection = models.MediaCollection = wp.media.model.Attachments.extend( {
13
  initialize: function ( models, options ) {
14
  this.controller = options.controller || new models.Controller;
15
  this.on( 'add remove reset', function () {
@@ -18,7 +21,7 @@ jQuery( function ( $ ) {
18
  this.controller.set( 'full', max > 0 && this.length >= max );
19
  } );
20
 
21
- wp.media.model.Attachments.prototype.initialize.call( this, models, options );
22
  },
23
 
24
  add: function ( models, options ) {
@@ -31,8 +34,7 @@ jQuery( function ( $ ) {
31
 
32
  if ( ! models.hasOwnProperty( 'length' ) ) {
33
  models = [models];
34
- }
35
- else if ( models instanceof wp.media.model.Attachments ) {
36
  models = models.models;
37
  }
38
 
@@ -41,11 +43,11 @@ jQuery( function ( $ ) {
41
  models = _.first( models, left );
42
  }
43
 
44
- return wp.media.model.Attachments.prototype.add.call( this, models, options );
45
  },
46
 
47
  remove: function ( models, options ) {
48
- models = wp.media.model.Attachments.prototype.remove.call( this, models, options );
49
  if ( this.controller.get( 'forceDelete' ) === true ) {
50
  models = ! _.isArray( models ) ? [models] : models;
51
  _.each( models, function ( model ) {
@@ -144,7 +146,7 @@ jQuery( function ( $ ) {
144
  } );
145
 
146
  this.controller.get( 'items' ).on( 'add remove reset', _.debounce( function () {
147
- that.$input.trigger( 'change' );
148
  }, 500 ) );
149
 
150
  this.controller.get( 'items' ).on( 'remove', _.debounce( function () {
@@ -242,27 +244,29 @@ jQuery( function ( $ ) {
242
  this.collection.remove( item );
243
  },
244
 
245
- switchItem: function () {
246
  if ( this._switchFrame ) {
247
  //this.stopListening( this._frame );
248
  this._switchFrame.dispose();
249
  }
250
- this._switchFrame = wp.media( {
251
  className: 'media-frame rwmb-media-frame',
252
  multiple: false,
253
  title: i18nRwmbMedia.select,
254
  editing: true,
255
  library: {
256
  type: this.controller.get( 'mimeType' )
257
- }
 
258
  } );
259
 
260
  this._switchFrame.on( 'select', function () {
261
  var selection = this._switchFrame.state().get( 'selection' ),
262
  collection = this.collection,
263
- index = collection.indexOf( this.model );
 
264
  if ( ! _.isEmpty( selection ) ) {
265
- collection.remove( this.model );
266
  collection.add( selection, {at: index} );
267
  }
268
  }, this );
@@ -309,6 +313,13 @@ jQuery( function ( $ ) {
309
  ui.item.data( 'sortableIndexStart', ui.item.index() );
310
  },
311
 
 
 
 
 
 
 
 
312
  // Update the model's index in the collection.
313
  // Do so silently, as the view is already accurate.
314
  update: function ( event, ui ) {
@@ -376,15 +387,16 @@ jQuery( function ( $ ) {
376
  //this.stopListening( this._frame );
377
  this._frame.dispose();
378
  }
379
- var maxFiles = this.controller.get( 'maxFiles');
380
- this._frame = wp.media( {
381
  className: 'media-frame rwmb-media-frame',
382
  multiple: maxFiles > 1 || maxFiles <= 0 ? 'add' : false,
383
  title: i18nRwmbMedia.select,
384
  editing: true,
385
  library: {
386
  type: this.controller.get( 'mimeType' )
387
- }
 
388
  } );
389
 
390
  this._frame.on( 'select', function () {
@@ -419,7 +431,7 @@ jQuery( function ( $ ) {
419
  */
420
  MediaItem = views.MediaItem = Backbone.View.extend( {
421
  tagName: 'li',
422
- className: 'rwmb-media-item',
423
  template: wp.template( 'rwmb-media-item' ),
424
  initialize: function ( options ) {
425
  this.controller = options.controller;
@@ -433,7 +445,7 @@ jQuery( function ( $ ) {
433
 
434
 
435
  events: {
436
- 'click .rwmb-switch': function () {
437
  this.trigger( 'click:switch', this.model );
438
  return false;
439
  },
@@ -466,26 +478,91 @@ jQuery( function ( $ ) {
466
  * MediaDetails
467
  * Custom version of TwoColumn view to prevent all video and audio from being unset
468
  */
469
- MediaDetails = views.MediaDetails = wp.media.view.Attachment.Details.TwoColumn.extend( {
470
  render: function () {
471
  var that = this;
472
- wp.media.view.Attachment.Details.prototype.render.apply( this, arguments );
473
  this.players = this.players || [];
474
 
475
- wp.media.mixin.unsetPlayers.call( this );
476
 
477
  this.$( 'audio, video' ).each( function ( i, elem ) {
478
- var el = wp.media.view.MediaDetails.prepareSrc( elem );
479
- that.players.push( new window.MediaElementPlayer( el, wp.media.mixin.mejsSettings ) );
480
  } );
481
  }
482
  } );
483
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
484
  /***
485
  * EditMedia
486
  * Custom version of EditAttachments frame to prevent all video and audio from being unset
487
  */
488
- EditMedia = views.EditMedia = wp.media.view.MediaFrame.EditAttachments.extend( {
489
  /**
490
  * Content region rendering callback for the `edit-metadata` mode.
491
  *
@@ -502,7 +579,7 @@ jQuery( function ( $ ) {
502
  * Attach a subview to display fields added via the
503
  * `attachment_fields_to_edit` filter.
504
  */
505
- contentRegion.view.views.set( '.attachment-compat', new wp.media.view.AttachmentCompat( {
506
  controller: this,
507
  model: this.model
508
  } ) );
@@ -517,7 +594,6 @@ jQuery( function ( $ ) {
517
  new MediaField( {input: this, el: $( this ).siblings( 'div.rwmb-media-view' )} );
518
  }
519
 
520
- $( ':input.rwmb-file_advanced' ).each( initMediaField );
521
- $( '.rwmb-input' )
522
- .on( 'clone', ':input.rwmb-file_advanced', initMediaField );
523
  } );
7
 
8
  var views = rwmb.views = rwmb.views || {},
9
  models = rwmb.models = rwmb.models || {},
10
+ media = wp.media,
11
+ MediaFrame = media.view.MediaFrame,
12
+ MediaCollection, Controller, MediaField, MediaList, MediaItem, MediaButton, MediaStatus, EditMedia,
13
+ MediaDetails, MediaLibrary, MediaSelect;
14
 
15
+ MediaCollection = models.MediaCollection = media.model.Attachments.extend( {
16
  initialize: function ( models, options ) {
17
  this.controller = options.controller || new models.Controller;
18
  this.on( 'add remove reset', function () {
21
  this.controller.set( 'full', max > 0 && this.length >= max );
22
  } );
23
 
24
+ media.model.Attachments.prototype.initialize.call( this, models, options );
25
  },
26
 
27
  add: function ( models, options ) {
34
 
35
  if ( ! models.hasOwnProperty( 'length' ) ) {
36
  models = [models];
37
+ } else if ( models instanceof media.model.Attachments ) {
 
38
  models = models.models;
39
  }
40
 
43
  models = _.first( models, left );
44
  }
45
 
46
+ return media.model.Attachments.prototype.add.call( this, models, options );
47
  },
48
 
49
  remove: function ( models, options ) {
50
+ models = media.model.Attachments.prototype.remove.call( this, models, options );
51
  if ( this.controller.get( 'forceDelete' ) === true ) {
52
  models = ! _.isArray( models ) ? [models] : models;
53
  _.each( models, function ( model ) {
146
  } );
147
 
148
  this.controller.get( 'items' ).on( 'add remove reset', _.debounce( function () {
149
+ that.$input.trigger( 'change', [that.$( '.rwmb-media-input' )] );
150
  }, 500 ) );
151
 
152
  this.controller.get( 'items' ).on( 'remove', _.debounce( function () {
244
  this.collection.remove( item );
245
  },
246
 
247
+ switchItem: function ( item ) {
248
  if ( this._switchFrame ) {
249
  //this.stopListening( this._frame );
250
  this._switchFrame.dispose();
251
  }
252
+ this._switchFrame = new MediaSelect( {
253
  className: 'media-frame rwmb-media-frame',
254
  multiple: false,
255
  title: i18nRwmbMedia.select,
256
  editing: true,
257
  library: {
258
  type: this.controller.get( 'mimeType' )
259
+ },
260
+ edit: this.controller.get( 'items' )
261
  } );
262
 
263
  this._switchFrame.on( 'select', function () {
264
  var selection = this._switchFrame.state().get( 'selection' ),
265
  collection = this.collection,
266
+ index = collection.indexOf( item );
267
+
268
  if ( ! _.isEmpty( selection ) ) {
269
+ collection.remove( item );
270
  collection.add( selection, {at: index} );
271
  }
272
  }, this );
313
  ui.item.data( 'sortableIndexStart', ui.item.index() );
314
  },
315
 
316
+ // Stop trigger 'click' on item. 'click' means reselect.
317
+ stop: function ( event ) {
318
+ $( event.originalEvent.target ).one( 'click', function ( e ) {
319
+ e.stopImmediatePropagation();
320
+ } );
321
+ },
322
+
323
  // Update the model's index in the collection.
324
  // Do so silently, as the view is already accurate.
325
  update: function ( event, ui ) {
387
  //this.stopListening( this._frame );
388
  this._frame.dispose();
389
  }
390
+ var maxFiles = this.controller.get( 'maxFiles' );
391
+ this._frame = new MediaSelect( {
392
  className: 'media-frame rwmb-media-frame',
393
  multiple: maxFiles > 1 || maxFiles <= 0 ? 'add' : false,
394
  title: i18nRwmbMedia.select,
395
  editing: true,
396
  library: {
397
  type: this.controller.get( 'mimeType' )
398
+ },
399
+ edit: this.controller.get( 'items' )
400
  } );
401
 
402
  this._frame.on( 'select', function () {
431
  */
432
  MediaItem = views.MediaItem = Backbone.View.extend( {
433
  tagName: 'li',
434
+ className: 'rwmb-media-item attachment',
435
  template: wp.template( 'rwmb-media-item' ),
436
  initialize: function ( options ) {
437
  this.controller = options.controller;
445
 
446
 
447
  events: {
448
+ 'click .rwmb-overlay': function () {
449
  this.trigger( 'click:switch', this.model );
450
  return false;
451
  },
478
  * MediaDetails
479
  * Custom version of TwoColumn view to prevent all video and audio from being unset
480
  */
481
+ MediaDetails = views.MediaDetails = media.view.Attachment.Details.TwoColumn.extend( {
482
  render: function () {
483
  var that = this;
484
+ media.view.Attachment.Details.prototype.render.apply( this, arguments );
485
  this.players = this.players || [];
486
 
487
+ media.mixin.unsetPlayers.call( this );
488
 
489
  this.$( 'audio, video' ).each( function ( i, elem ) {
490
+ var el = media.view.MediaDetails.prepareSrc( elem );
491
+ that.players.push( new window.MediaElementPlayer( el, media.mixin.mejsSettings ) );
492
  } );
493
  }
494
  } );
495
 
496
+ /**
497
+ * MediaLibrary
498
+ * Custom version of Library to exclude already selected media in a media frame
499
+ */
500
+ MediaLibrary = media.controller.Library.extend( {
501
+ defaults: _.defaults( {
502
+ multiple: 'add',
503
+ filterable: 'uploaded',
504
+ priority: 100,
505
+ syncSelection: false
506
+ }, media.controller.Library.prototype.defaults ),
507
+
508
+ activate: function () {
509
+ var library = this.get( 'library' ),
510
+ edit = this.frame.options.edit;
511
+
512
+ if ( this.editLibrary && this.editLibrary !== edit ) {
513
+ library.unobserve( this.editLibrary );
514
+ }
515
+
516
+ // Accepts attachments that exist in the original library and
517
+ // that do not exist in gallery's library.
518
+ library.validator = function ( attachment ) {
519
+ return ! ! this.mirroring.get( attachment.cid ) && ! edit.get( attachment.cid ) && media.model.Selection.prototype.validator.apply( this, arguments );
520
+ };
521
+
522
+ // Reset the library to ensure that all attachments are re-added
523
+ // to the collection. Do so silently, as calling `observe` will
524
+ // trigger the `reset` event.
525
+ library.reset( library.mirroring.models, {silent: true} );
526
+ library.observe( edit );
527
+ this.editLibrary = edit;
528
+
529
+ media.controller.Library.prototype.activate.apply( this, arguments );
530
+ }
531
+ } );
532
+
533
+ /**
534
+ * MediaSelect
535
+ * Custom version of Select media frame that uses MediaLibrary
536
+ */
537
+ MediaSelect = views.MediaSelect = MediaFrame.Select.extend( {
538
+ /**
539
+ * Create the default states on the frame.
540
+ */
541
+ createStates: function () {
542
+ var options = this.options;
543
+
544
+ if ( this.options.states ) {
545
+ return;
546
+ }
547
+
548
+ // Add the default states.
549
+ this.states.add( [
550
+ // Main states.
551
+ new MediaLibrary( {
552
+ library: media.query( options.library ),
553
+ multiple: options.multiple,
554
+ title: options.title,
555
+ priority: 20
556
+ } )
557
+ ] );
558
+ }
559
+ } );
560
+
561
  /***
562
  * EditMedia
563
  * Custom version of EditAttachments frame to prevent all video and audio from being unset
564
  */
565
+ EditMedia = views.EditMedia = MediaFrame.EditAttachments.extend( {
566
  /**
567
  * Content region rendering callback for the `edit-metadata` mode.
568
  *
579
  * Attach a subview to display fields added via the
580
  * `attachment_fields_to_edit` filter.
581
  */
582
+ contentRegion.view.views.set( '.attachment-compat', new media.view.AttachmentCompat( {
583
  controller: this,
584
  model: this.model
585
  } ) );
594
  new MediaField( {input: this, el: $( this ).siblings( 'div.rwmb-media-view' )} );
595
  }
596
 
597
+ $( '.rwmb-file_advanced' ).each( initMediaField );
598
+ $( document ).on( 'clone', '.rwmb-file_advanced', initMediaField );
 
599
  } );
js/oembed.js CHANGED
@@ -11,13 +11,13 @@ jQuery( function ( $ ) {
11
  $spinner = $this.siblings( '.spinner' ),
12
  data = {
13
  action: 'rwmb_get_embed',
14
- url: $this.siblings( 'input' ).val()
15
  };
16
 
17
  $spinner.css( 'visibility', 'visible' );
18
- $.post( ajaxurl, data, function ( r ) {
19
  $spinner.css( 'visibility', 'hidden' );
20
- $this.siblings( '.rwmb-embed-media' ).html( r.data );
21
  }, 'json' );
22
  }
23
 
@@ -28,9 +28,7 @@ jQuery( function ( $ ) {
28
  $( this ).siblings( '.rwmb-embed-media' ).html( '' );
29
  }
30
 
31
- // Show oembeded media when clicking "Preview" button
32
- $( 'body' ).on( 'click', '.rwmb-embed-show', showPreview );
33
-
34
- // Remove oembed preview when cloning
35
- $( '.rwmb-input' ).on( 'clone', '.rwmb-oembed', removePreview );
36
  } );
11
  $spinner = $this.siblings( '.spinner' ),
12
  data = {
13
  action: 'rwmb_get_embed',
14
+ url: $this.val()
15
  };
16
 
17
  $spinner.css( 'visibility', 'visible' );
18
+ $.post( ajaxurl, data, function ( response ) {
19
  $spinner.css( 'visibility', 'hidden' );
20
+ $this.siblings( '.rwmb-embed-media' ).html( response.data );
21
  }, 'json' );
22
  }
23
 
28
  $( this ).siblings( '.rwmb-embed-media' ).html( '' );
29
  }
30
 
31
+ $( document )
32
+ .on( 'change', '.rwmb-oembed', _.debounce( showPreview, 250 ) )
33
+ .on( 'clone', '.rwmb-oembed', removePreview );
 
 
34
  } );
js/wp-color-picker-alpha/wp-color-picker-alpha.min.js ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**!
2
+ * wp-color-picker-alpha
3
+ *
4
+ * Overwrite Automattic Iris for enabled Alpha Channel in wpColorPicker
5
+ * Only run in input and is defined data alpha in true
6
+ *
7
+ * Version: 1.2.2
8
+ * https://github.com/23r9i0/wp-color-picker-alpha
9
+ * Copyright (c) 2015 Sergio P.A. (23r9i0).
10
+ * Licensed under the GPLv2 license.
11
+ */
12
+ !function(t){var o="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAAHnlligAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAHJJREFUeNpi+P///4EDBxiAGMgCCCAGFB5AADGCRBgYDh48CCRZIJS9vT2QBAggFBkmBiSAogxFBiCAoHogAKIKAlBUYTELAiAmEtABEECk20G6BOmuIl0CIMBQ/IEMkO0myiSSraaaBhZcbkUOs0HuBwDplz5uFJ3Z4gAAAABJRU5ErkJggg==",i='<a tabindex="0" class="wp-color-result" />',e='<div class="wp-picker-holder" />',r='<div class="wp-picker-container" />',a='<input type="button" class="button button-small hidden" />';Color.fn.toString=function(){if(this._alpha<1)return this.toCSS("rgba",this._alpha).replace(/\s+/g,"");var t=parseInt(this._color,10).toString(16);return this.error?"":(t.length<6&&(t=("00000"+t).substr(-6)),"#"+t)},t.widget("wp.wpColorPicker",t.wp.wpColorPicker,{_create:function(){if(t.support.iris){var n=this,s=n.element;t.extend(n.options,s.data()),n.close=t.proxy(n.close,n),n.initialValue=s.val(),s.addClass("wp-color-picker").hide().wrap(r),n.wrap=s.parent(),n.toggler=t(i).insertBefore(s).css({backgroundColor:n.initialValue}).attr("title",wpColorPickerL10n.pick).attr("data-current",wpColorPickerL10n.current),n.pickerContainer=t(e).insertAfter(s),n.button=t(a),n.options.defaultColor?n.button.addClass("wp-picker-default").val(wpColorPickerL10n.defaultString):n.button.addClass("wp-picker-clear").val(wpColorPickerL10n.clear),s.wrap('<span class="wp-picker-input-wrap" />').after(n.button),s.iris({target:n.pickerContainer,hide:n.options.hide,width:n.options.width,mode:n.options.mode,palettes:n.options.palettes,change:function(i,e){n.options.alpha?(n.toggler.css({"background-image":"url("+o+")"}).html("<span />"),n.toggler.find("span").css({width:"100%",height:"100%",position:"absolute",top:0,left:0,"border-top-left-radius":"3px","border-bottom-left-radius":"3px",background:e.color.toString()})):n.toggler.css({backgroundColor:e.color.toString()}),t.isFunction(n.options.change)&&n.options.change.call(this,i,e)}}),s.val(n.initialValue),n._addListeners(),n.options.hide||n.toggler.click()}},_addListeners:function(){var o=this;o.wrap.on("click.wpcolorpicker",function(t){t.stopPropagation()}),o.toggler.on("click",function(){o.toggler.hasClass("wp-picker-open")?o.close():o.open()}),o.element.on("change",function(i){(""===t(this).val()||o.element.hasClass("iris-error"))&&(o.options.alpha?(o.toggler.removeAttr("style"),o.toggler.find("span").css("backgroundColor","")):o.toggler.css("backgroundColor",""),t.isFunction(o.options.clear)&&o.options.clear.call(this,i))}),o.toggler.on("keyup",function(t){13!==t.keyCode&&32!==t.keyCode||(t.preventDefault(),o.toggler.trigger("click").next().focus())}),o.button.on("click",function(i){t(this).hasClass("wp-picker-clear")?(o.element.val(""),o.options.alpha?(o.toggler.removeAttr("style"),o.toggler.find("span").css("backgroundColor","")):o.toggler.css("backgroundColor",""),t.isFunction(o.options.clear)&&o.options.clear.call(this,i)):t(this).hasClass("wp-picker-default")&&o.element.val(o.options.defaultColor).change()})}}),t.widget("a8c.iris",t.a8c.iris,{_create:function(){if(this._super(),this.options.alpha=this.element.data("alpha")||!1,this.element.is(":input")||(this.options.alpha=!1),"undefined"!=typeof this.options.alpha&&this.options.alpha){var o=this,i=o.element,e='<div class="iris-strip iris-slider iris-alpha-slider"><div class="iris-slider-offset iris-slider-offset-alpha"></div></div>',r=t(e).appendTo(o.picker.find(".iris-picker-inner")),a=r.find(".iris-slider-offset-alpha"),n={aContainer:r,aSlider:a};"undefined"!=typeof i.data("custom-width")?o.options.customWidth=parseInt(i.data("custom-width"))||0:o.options.customWidth=100,o.options.defaultWidth=i.width(),(o._color._alpha<1||-1!=o._color.toString().indexOf("rgb"))&&i.width(parseInt(o.options.defaultWidth+o.options.customWidth)),t.each(n,function(t,i){o.controls[t]=i}),o.controls.square.css({"margin-right":"0"});var s=o.picker.width()-o.controls.square.width()-20,l=s/6,c=s/2-l;t.each(["aContainer","strip"],function(t,i){o.controls[i].width(c).css({"margin-left":l+"px"})}),o._initControls(),o._change()}},_initControls:function(){if(this._super(),this.options.alpha){var t=this,o=t.controls;o.aSlider.slider({orientation:"vertical",min:0,max:100,step:1,value:parseInt(100*t._color._alpha),slide:function(o,i){t._color._alpha=parseFloat(i.value/100),t._change.apply(t,arguments)}})}},_change:function(){this._super();var t=this,i=t.element;if(this.options.alpha){var e=t.controls,r=parseInt(100*t._color._alpha),a=t._color.toRgb(),n=["rgb("+a.r+","+a.g+","+a.b+") 0%","rgba("+a.r+","+a.g+","+a.b+", 0) 100%"],s=t.options.defaultWidth,l=t.options.customWidth,c=t.picker.closest(".wp-picker-container").find(".wp-color-result");e.aContainer.css({background:"linear-gradient(to bottom, "+n.join(", ")+"), url("+o+")"}),c.hasClass("wp-picker-open")&&(e.aSlider.slider("value",r),t._color._alpha<1?(e.strip.attr("style",e.strip.attr("style").replace(/rgba\(([0-9]+,)(\s+)?([0-9]+,)(\s+)?([0-9]+)(,(\s+)?[0-9\.]+)\)/g,"rgb($1$3$5)")),i.width(parseInt(s+l))):i.width(s))}var p=i.data("reset-alpha")||!1;p&&t.picker.find(".iris-palette-container").on("click.palette",".iris-palette",function(){t._color._alpha=1,t.active="external",t._change()})},_addInputListeners:function(t){var o=this,i=100,e=function(i){var e=new Color(t.val()),r=t.val();t.removeClass("iris-error"),e.error?""!==r&&t.addClass("iris-error"):e.toString()!==o._color.toString()&&("keyup"===i.type&&r.match(/^[0-9a-fA-F]{3}$/)||o._setOption("color",e.toString()))};t.on("change",e).on("keyup",o._debounce(e,i)),o.options.hide&&t.on("focus",function(){o.show()})}})}(jQuery),jQuery(document).ready(function(t){t(".color-picker").wpColorPicker()});
js/wysiwyg.js CHANGED
@@ -29,9 +29,9 @@ jQuery( function ( $ ) {
29
 
30
  // TinyMCE
31
  if ( tinyMCEPreInit.mceInit.hasOwnProperty( originalId ) ) {
32
- var settings = tinyMCEPreInit.mceInit[originalId];
33
- settings.selector = '#' + id;
34
- tinymce.init( settings );
35
  }
36
 
37
  // Quick tags
@@ -49,19 +49,17 @@ jQuery( function ( $ ) {
49
  * @param $el Current cloned textarea
50
  */
51
  function getOriginalId( $el ) {
52
- var $clones = $el.closest( '.rwmb-clone' ).siblings( '.rwmb-clone' ),
53
- id = '';
54
- $clones.each( function () {
55
- var currentId = $( this ).find( '.rwmb-wysiwyg' ).attr( 'id' );
56
- if ( /_\d+$/.test( currentId ) ) {
57
- currentId = currentId.replace( /_\d+$/, '' );
58
- }
59
- if ( tinyMCEPreInit.mceInit.hasOwnProperty( currentId ) || tinyMCEPreInit.qtInit.hasOwnProperty( currentId ) ) {
60
- id = currentId;
61
- return false; // Immediately stop the .each() loop
62
- }
63
- } );
64
- return id;
65
  }
66
 
67
  /**
29
 
30
  // TinyMCE
31
  if ( tinyMCEPreInit.mceInit.hasOwnProperty( originalId ) ) {
32
+ var settings = tinyMCEPreInit.mceInit[originalId],
33
+ editor = new tinymce.Editor(id, settings, tinymce.EditorManager);
34
+ editor.render();
35
  }
36
 
37
  // Quick tags
49
  * @param $el Current cloned textarea
50
  */
51
  function getOriginalId( $el ) {
52
+ var $clone = $el.closest( '.rwmb-clone' ),
53
+ currentId = $clone.find( '.rwmb-wysiwyg' ).attr( 'id' );
54
+
55
+ if ( /_\d+$/.test( currentId ) ) {
56
+ currentId = currentId.replace( /_\d+$/, '' );
57
+ }
58
+ if ( tinyMCEPreInit.mceInit.hasOwnProperty( currentId ) || tinyMCEPreInit.qtInit.hasOwnProperty( currentId ) ) {
59
+ return currentId;
60
+ }
61
+
62
+ return '';
 
 
63
  }
64
 
65
  /**
meta-box.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Meta Box
4
  * Plugin URI: https://metabox.io
5
  * Description: Create custom meta boxes and custom fields in WordPress.
6
- * Version: 4.11.2
7
  * Author: MetaBox.io
8
  * Author URI: https://metabox.io
9
  * License: GPL2+
3
  * Plugin Name: Meta Box
4
  * Plugin URI: https://metabox.io
5
  * Description: Create custom meta boxes and custom fields in WordPress.
6
+ * Version: 4.12.1
7
  * Author: MetaBox.io
8
  * Author URI: https://metabox.io
9
  * License: GPL2+
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: metabox, rilwis, fitwp, f-j-kaiser, funkatronic, PerWiklander, rua
3
  Donate link: http://paypal.me/anhtnt
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.7.5
7
- Stable tag: 4.11.2
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.
@@ -128,665 +128,26 @@ To getting started with the plugin, please read [this tutorial](https://metabox.
128
 
129
  == Changelog ==
130
 
131
- = 4.11.2 =
132
-
133
- * Introducing storage interface, which now can be extended for term/user/settings page under the same codebase. With this improvement, helper functions now works for term/user/settings page (require premium extensions).
134
- * Fixed cloning wysiwyg field when tinyMCE mode is turned off (only show quick tags).
135
- * Fixed image_upload & file_upload field doesn't add attachment to post
136
- * Fixed text_list fields not saving correctly when edit not last field.
137
-
138
- = 4.11.1 =
139
-
140
- * Added button for "Check/Uncheck all options" in input list field when type is `checkbox_list`. Props @mrbrazzi.
141
- * Select multiple images now does not require to press "Shift".
142
- * Change button field to actual button element.
143
- * Fix scripts and styles dependencies
144
- * Fix bug for select tree when parent not set
145
- * Add sanitize post type in case users use CamelCase in post type name
146
- * Increase z-index of datepicker to prevent overlap with top menu bar
147
- * Make compatible with MB Admin Columns and MB Frontend Submission extensions
148
- * Update Persian translation. Credit Morteza Gholami
149
-
150
- = 4.11 =
151
-
152
- * Code architecture update:
153
- * Add `object_id` property to the meta box object. Used to connect the meta box to the post object. Not heavily used yet.
154
- * Add RWMB_Meta_Box_Registry and RWMB_Field_Registry to store all registered meta boxes and fields. Used to future access these objects. Use internally only. 3rd-party code should not use it as it's still experimental and can change in the future.
155
- * Deprecated RWMB_Core::get_meta_boxes() due to the meta box registry above. This function was made for internally use only. 3rd-party code should not rely on it.
156
- * Add magic method __get to the meta box object to quick access to meta box configuration.
157
- * UI update:
158
- * Make the field label bold (similar to WordPress settings page).
159
- * Increase margin between fields and change color for remove clone button (also reduce minus size)
160
- * Remove style for checkbox (default is good).
161
- * Improve styles for checkbox/radio list
162
- * A little smaller padding for select box. Also remove default size for select[multiple]
163
- * Add a little space between the map canvas and the "Find Address" button
164
- * Media fields:
165
- * Media field update: Hidden field for media fields now no longer disabled. If media field js not loaded properly, code will default to hidden field and process
166
- accordingly. Issue #1088.
167
- * Better and simpler way to handle HTML file upload using `media_handle_upload` function.
168
- * Rewrite JS for "file", simpler and modular. Also fix bug when add/remove items that doesn't toggle the Add more link correctly.
169
- * Improve JS code for media field, using MediaList instead of item views (Backbone JS code).
170
- * Add support for image sizes in image_advanced and image_upload. Default is thumbnail. Fixes #425.
171
- * Clone:
172
- * Add new parameter `add_button` for the add new clone button text. Better than use filter.
173
- * Fix position for remove clone button in RTL languages
174
- * Update margin between clones and set clone placeholder = outer height of the cloned element.
175
- * Scripts and styles:
176
- * Check condition for enqueueing scripts & styles only in the admin.
177
- * Update the time picker library to the latest version (1.6.3) to supports "select" control for time picker. [See demo](http://trentrichardson.com/examples/timepicker/#slider_examples).
178
- * Better dependencies for date picker CSS, autocomplete field.
179
- * Other improvements:
180
- * Remove the static helper class because of a bad OOP code.
181
- * Fix get plugin URL symlink when plugin is put in a theme and symlinked. Props @tutv95.
182
- * Add support for "region" in the map field to limit autocomplete from wrong entries (to help preventing from entering wrong address or country). See https://developers.google.com/maps/documentation/geocoding/intro#RegionCodes
183
-
184
- = 4.10.4 =
185
- * Improvement: Add support for validate user edit and term edit forms (requires MB Term Meta or MB User Meta extension).
186
- * Improvement: Add new parameter `label_description` for fields to display a description below field label (name).
187
- * Improvement: Add support for edit custom fields in the media modal. Requires `post_type` set to `attachment` and `media_modal` set to true. [See demo](https://github.com/rilwis/meta-box/blob/master/demo/media-modal.php).
188
- * Improvement: For WPML users: Add support to hide fields in "Do not translate" mode and disable editing fields in "Copy" mode.
189
- * Fix: Users can't select same images for 2 different `image_advanced` fields.
190
- * Fix: `max_status` doesn't work.
191
-
192
- = 4.10.3 =
193
- * Fix: `force_delete` causes files to be deleted even when set to `false`.
194
- * Fix: `max_file_uploads` not working.
195
-
196
- = 4.10.2 =
197
- * Improvement: Add `max_file_size` to upload fields (`File_Upload`, `Image_Upload`, `Plupload_Image`).
198
- * Improvement: Add support for attributes for file input.
199
- * Improvement: Update Polish translation.
200
- * Improvement: Add translation support for Key and Value strings (@prop saqibsarwar).
201
- * Fix: Shorter width of email field vs. other fields (@prop saqibsarwar).
202
- * Fix: Fix cloneable datetime field with timestamp=true.
203
- * Fix: Remove margin bottom in select_advanced options.
204
- * Fix: Showing the correct selected value for select_advanced field when the option value contains '&' character.
205
- * Fix: Fix default values not working with taxonomy and taxonomy_advanced fields.
206
-
207
- = 4.10.1 =
208
- * Fix: Fix `image_upload` and `plupload_image` field when select images to upload.
209
-
210
- = 4.10 =
211
- * Improvement: Add `video` field type which allows users to upload or select video from the Media Library. See [demo](https://github.com/rilwis/meta-box/blob/master/demo/video.php).
212
- * Improvement: Update Turkish. Prop Emre Tuna <tunaemre@windowslive.com>.
213
- * Improvement: Use WP 4.6 date picker localization instead of JS localized file to reduce plugin size.
214
- * Improvement: Refactor the media fields for better performance. Add `change` event for item list when add, remove or reset.
215
- * Fix: `taxonomy_advanced` field now can be cloned.
216
- * Fix: Make localize_script works with WP 4.1.
217
-
218
- = 4.9.8 =
219
- * Fix: Quick fix for enqueueing validation script
220
-
221
- = 4.9.7 =
222
- * Improvement: Re-add change event on media fields to make Conditional Logic extension works with media fields.
223
- * Improvement: Add `rwmb_choice_label`, `rwmv_{$field_type}_choice_label` and `rwmb_{field_id}_choice_label` filters for post, user, taxonomy fields, allowing users to customize the labels of choice fields.
224
- * Improvement: Change coding styles to follow WordPress Coding Standards.
225
- * Various improvements to reduce duplicated code.
226
- * Fix: Map field now works in the frontend.
227
- * Fix: `std` now works for taxonomy fields.
228
-
229
- = 4.9.6 =
230
- * Fix: Wrong CSS selector when cloning wysiwyg field
231
- * Fix: Remove preview for oembed field when cloning
232
- * Fix: 'std' for taxonomy field now works
233
-
234
- = 4.9.5 =
235
- * Fix: Quick fix for wrong field wrapper class which causes color field to render incorrectly
236
-
237
- = 4.9.4 =
238
- * Fix: Quick fix for cloning bug
239
-
240
- = 4.9.3 =
241
- * Fix: Quick fix saving datetime field
242
-
243
- = 4.9.2 =
244
- * Fix: Quick fix validation
245
-
246
- = 4.9.1 =
247
- * Fix: Quick fix for `rwmb_meta()` to be better backward compatible
248
-
249
- = 4.9 =
250
- * Improvement: Update Chinese language. Add Chinese Taiwan.
251
- * Improvement: Add support for Google Maps API key. Default API key is added, however users should replace it with their own key.
252
- * Improvement: Add additional methods for jQuery validation module which makes it understand HTML5 "pattern" attribute.
253
- * Improvement: Fully WPML compatibility (supported by WPML team)
254
- * Improvement: Add placeholders for `key_value` field
255
- * Fix: Toggle remove clone buttons for nested groups.
256
- * Fix: Error on date field, not save
257
- * Fix: Add fix for date/datetime when both inline and timestamp used
258
- * Fix: Set default language for date/time picker.
259
- * Fix: rwmb_meta for images returns incorrect width/height
260
- * Fix: PHP warning when uploading files in Settings Pages extension.
261
- * Fix: Blank space in the footer when using plupload_image.
262
- * Fix: Cloning wysiwyg when deleting the 1st clone
263
-
264
- = 4.8.7 =
265
- * Improvement: Refactor the code to reduce the complexity in the fields' inheritance
266
- * Improvement: All HTML 5 input types (week, month, etc.) are supported
267
- * Improvement: Optimize the_value function, use recursive call to reduce nested loop. Sub-fields need to define format_single_value only.
268
- * Improvement: Use 1 single localization file for jQuery date picker for simplicity
269
- * Improvement: Add support for custom marker for map field (param `marker_icon`) in rwmb_meta function
270
- * Improvement: Add `limit` option for media fields in `rwmb_meta` function when retrieving meta value.
271
- * Improvement: Add `rwmb_option_label` filter for choice fields (user, post, taxonomy) so users can choose which object field is used as label
272
- * Improvement: Use `WP_User_Query` for user field which supports more options for querying
273
- * Improvement: Optimize code for oembed, also use esc_html__ for better security
274
- * Improvement: Compatibility with Meta Box Geolocation
275
- * Fix: Fix first option is auto selected in select_advanced field.
276
- * Fix: Fix clone issue for color in Meta Box Group extension.
277
- * Fix: Fix clone issue for image advanced in Meta Box Group extension.
278
- * Fix: Fix not parsing $args to array in helper functions.
279
-
280
- = 4.8.6 =
281
- * Improvement: Edit link on media items now opens edit modal
282
- * Improvement: Refresh map when sorting meta boxes.
283
- * Improvement: Wrap checkbox's description into a <label> to make it clickable to activate/deactivate the checkbox.
284
- * Improvement: Remove Spanish language (ES) as it's already translated on translate.wordpress.org
285
- * Improvement: Add support for saving zoom in map
286
- * Improvement: Prevent output localized strings twice.
287
- * Improvement: Add fallback for autoload in PHP 5.2 in case it's disabled.
288
- * Improvement: No need to json_encode for custom attributes. User can pass an array to custom attribute
289
- * Improvement: Add style for `select2` library to match WordPress admin style
290
- * Improvement: Adds min width to select. @prop ahmadawais
291
- * Improvement: Added `max_status` option for media type fields. `true` to show status, `false` to hide
292
- * Improvement: Add attachment meta data to file info
293
- * Fix: Validation for non-Meta Box fields
294
- * Fix: advanced_image field after reload page F5 in Firefox
295
- * Fix: Cannot read property 'getFullYear' of null
296
- * Fix: Empty date converting to 0
297
- * Fix: Add missing class for image_select field which prevents setting input's name when cloning.
298
- * Fix: Fix bug with blank maps on the front end
299
- * Fix: Fix bug with cloning media fields
300
- * Fix: Remove empty values in clones and reset index.
301
- * Fix: Reset of cloned select fields
302
- * Fix: select_advanced with multiple=true adds empty selected option
303
- * Fix: No empty option for simple select field
304
- * Fix: Empty datetime field with timestamp => true returns January 1, 1970
305
- * Fix: For color picker when using with Columns extension
306
- * Fix: Fix bug with taxonomy advanced returns all taxonomy items for posts with no meta saved
307
- * Fix: Fix bug with taxonomy advanced not saving value when field isn't multiple
308
- * Fix: Make radio inline again
309
- * Fix: Wrong meta value when using helper function outside the loop
310
- * Fix: Validation now works for hidden elements in tabs
311
-
312
- = 4.8.5 =
313
- * Improvement: Add localization for Select2 library
314
- * Improvement: Range preview output added
315
- * Improvement: Add Persian translation and nag fix
316
- * Fix: Map has no refresh in collapsed meta boxes
317
- * Fix: Fix incorrect URL if the plugin is symlinked.
318
- * Fix: Added fix for saved order in object-choice
319
-
320
- = 4.8.4 =
321
- * Improvement: Refactor code for plupload_image. Introduces file_upload and image_upload field which acts the same as plupload_image but for files and images.
322
- * Improvement: Do not show "Embed is not available" if fields don't have any value
323
- * Improvement: Refactor date/time related fields. 'timestamp' now works for date field as well.
324
- * Improvement: Add 'inline' mode for date/datetime fields.
325
- * Improvement: Add option 'select_all_none' for select/select2 with default = false
326
- * Fix: users now can register 2 meta boxes with same field IDs for different post types.
327
- * Fix: width of embeded video if $content_width is too large.
328
- * Fix: autoloader now works more safely.
329
- * Fix: post field doesn't show correct post link
330
- * Fix: select field must call field's get_value to get field's value as 'select' is used in many non-inherited classes
331
- * Fix: Allows old syntax for `query_args.post_types` for post/user/taxonomy fields
332
- * Fix: Do not reset value for hidden field when clone
333
- * Fix: Missing Insert into Post button for thickbox_image field
334
- * Fix: Date picker cut off by TinyMCE
335
- * Fix: CSS for multi months in date picker
336
-
337
- = 4.8.3 =
338
- * Improvement: WYSIWYG field now can be cloned. Sorting clone hasn't worked yet.
339
- * Fix: 'std' value not working if there is 'divider' or 'heading' field withough 'id'
340
- * Fix: helper function not working in AJAX or admin.
341
- * Fix: getting plugin's path on Windows system.
342
- * Fix: warning get_value of taxonomy field
343
- * Fix: guarantee file ids are in an array
344
-
345
- = 4.8.2 =
346
- * Fix: re-add code for backward compatibility for helper function
347
- * Fix: undefined 'class' attribute for button
348
- * Improvement: speedup the helper function
349
-
350
- = 4.8.1 =
351
-
352
- * Fix: select multiple value with post, user and taxonomy
353
- * Fix: bug in oembed field
354
- * Fix: fix JS/CSS compatibility with WooCommerce
355
- * Fix: do not force field ID to lowercase, which can potentially breaks existing fields or fields with ID of CAPS characters.
356
-
357
- = 4.8.0 =
358
-
359
- * Improvement: rewrite the way the plugin loads file, which allows developers to include the plugin into themes/plugins simply by include the main file. The new loading mechanism also uses autoloading feature which prevents loading files twice and saves memory.
360
- * Improvement: rewrite `user`, `post`, `taxonomy` fields using the same codebase as they're native WordPress objects and sharing similar options. Also changes the syntax of query parameters for these fields (old syntax still works). Please see docs for details.
361
- * Improvement: add `srcset` in the returned value of helper function for image fields
362
- * Improvement: better sanitize value for `url` field
363
- * Improvement: prevent issues with dashes in field types
364
- * Improvement: remove redundant value in checkbox
365
- * Improvement: update CSS for date, time fields
366
- * Improvement: select2 now updated to 4.0.1
367
- * Improvement: optimize code for `file_advanced` and `image_advanced` fields which now submit array of values when saving instead of single CSV value
368
- * Improvement: add `collapse` option to `checkbox_list` and `checkbox_tree` in `user`, `taxonomy`, `post` fields which prevents plugin save parent values.
369
- * Improvement: secure password field so it is no longer saved in plain text. To check if a password matches the hash, please use `wp_check_password`.
370
- * Improvement: change the output of `color` field in the helper function. Now it shows the color instead of hex value.
371
- * Improvement: add `color:change` and `color:clear` JavaScript event for detecting changes in `color` field.
372
- * Improvement: refactor code for better structure and security
373
- * Fix: rewrite the JavaScript for cloning which causes bugs for date field.
374
- * Fix: fix missing attributes if value is '0' or 0.
375
- * Fix: add missing `class` attribute for fields
376
- * Fix: do not auto populate color field with '#'
377
- * Fix: wrong callback for fix page template
378
-
379
-
380
- = 4.7.3 =
381
-
382
- * Improvement: add `change` event for `file_advanced` and `image_advanced` fields.
383
- * Improvement: add support for boolean attributes.
384
- * Improvement: add support for boolean attributes.
385
- * Improvement: add Russian language.
386
- * Improvement: changed `wp_get_post_terms` to `get_the_terms` to use WordPress cache.
387
- * Improvement: refactored code to make textarea, select use attributes.
388
- * Improvement: `fieldset_text` now cloneable. Also removed `rows` option for this field.
389
- * Improvement: refactored `has_been_saved()` function.
390
-
391
- = 4.7.2 =
392
-
393
- * Fix: notice undefined index in date, time fields.
394
-
395
- = 4.7.1 =
396
-
397
- * Fix: remove default `maxlength = 30` for text fields.
398
-
399
- = 4.7 =
400
-
401
- * Improvement: add `attributes` for all input fields (text, number, email, ...) so users can add any custom attributes for them. Also added default attributes `required`, `disabled`, `readonly`, `maxlength` and `pattern` for those fields as well. These attributes will be merged into the `attributes`.
402
- * Improvement: add `js_options` for color field which allows users to define custom color palettes and other attributes for color picker. See the options in [Iris page](http://automattic.github.io/Iris/).
403
- * Fix: fix for file and image uploaded via `file_advanced` and `image_advanced` not showing up.
404
-
405
- = 4.6 =
406
-
407
- * Improvement: the plugin translation is now handled in translate.wordpress.org. While the plugin keeps old translation as backward compatibility, it's recommended to translate everything in translate.wordpress.org. Language packs will be automatically updated by WordPress.
408
- * Improvement: rewrite code for `file_advanced` and `image_advanced`, which share the same code base. These fields are now clonable and not autosave (you have to save post to save files)! Props @funkatronic.
409
- * Improvement: restyle clone icon, sort clone icon and add clone button for better UI. The new UI now is compatible with `color` and `date` fields
410
- * Improvement: separate validation module into 1 class, for better code structure
411
- * Improvement: add `pattern` attribute for `url` field
412
- * Improvement: improve code quality
413
- * Fix: missing "checked" when clone radio
414
- * Fix: language file name for Dutch
415
- * Fix: oembed not render preview if provider is added via `wp_embed_register_handler`
416
-
417
- = 4.5.7 =
418
- * Fix: Always set std as value for hidden field
419
- * Fix: `rwmb_meta` now can display rich content from `oembed` field
420
- * Fix: Wrong format for `datetime` field
421
- * Fix: Check and reset clone index when add/remove/sort clones
422
- * Improvement: Optionally display ID attribute for heading and divider
423
- * Improvement: Adding new style to date field to match WordPress style
424
- * Improvement: Change saving hooks to specific post types to prevent saving images to wrong post
425
-
426
- = 4.5.6 =
427
- * Fix: Warning for timestamp for datetime field.
428
- * Fix: z-index for color picker.
429
- * Fix: Marker title in map
430
-
431
- = 4.5.5 =
432
- * Fix: CSS alignment for sort clone icon for field type `group` (require Meta Box Group extension)
433
- * Fix: rwmbSelect is not defined
434
-
435
- = 4.5.4 =
436
- * Improvement: Add "Select All|None" for `select`, `select_advanced`, `post` fields
437
- * Improvement: Add `max_clone` parameter which limits number of clones
438
- * Improvement: Add `sort_clone` parameter which allows users to sort (drag and drop) cloned inputs
439
- * Improvement: Add Polish language. Thank Michael
440
- * Fix: Prevent warning when post type doesn't exist (`post` field)
441
-
442
- = 4.5.3 =
443
- * Improvement: Use `wp_json_encode` instead of `json_encode`. Thank Sam Ford.
444
- * Fix: Escape value for cloneable fields
445
- * Fix: Notice for missing parameters for `rwmb_meta` field for `map`
446
-
447
-
448
- = 4.5.2 =
449
- * Improvement: Add Persian (Farsi) language. Thank Ahmad Azimi.
450
- * Improvement: Update Spanish translation. Thank David Perez.
451
- * Fix: Cloning text fields
452
- * Fix: rwmb_meta works incorrectly for image fields if multiple=false
453
-
454
- = 4.5.1 =
455
- * Improvement: Add ability to use multiple post types for `post` field
456
- * Fix: Duplicated description for `checkbox` field
457
- * Fix: Blank gallery for image fields
458
-
459
- = 4.5 =
460
- * Improvement: Separate `esc_meta` method
461
- * Improvement: Add ability to use URL to retrieve options for autocomplete field
462
- * Improvement: Add `rwmb_get_field` and `rwmb_the_field` functions to get and display field values in the frontend
463
- * Improvement: Add field type `custom_html` to display any HTML in the meta box
464
- * Improvement: Add field type `key_value` which allows users to add any number of key-value pairs
465
- * Improvement: Use single JS file to display Google Maps in the frontend. No more inline Javascript.
466
- * Improvement: Code refactor
467
-
468
- = 4.4.3 =
469
- * Fix: Incorrect path to loader image for `plupload_image`
470
- * Fix: Missing placeholder for `post` field when `field_type` = `select`
471
- * Improvement: No errors showing if invalid value is returned from `rwmb_meta_boxes` filter
472
- * Improvement: Add filter for add/remove clone buttons text
473
- * Improvement: Add French translation
474
-
475
- = 4.4.2 =
476
- * Fix: Values of text_list field not showing correctly
477
- * Fix: Time picker field cannot select hour > 22, time > 58
478
- * Fix: Notice error when showing fields which don't have ID
479
- * Fix: Don't return non-existing files or images via rwmb_meta function
480
- * Fix: CSS alignment for taxonomy tree
481
- * Fix: Placeholder not working for "select" taxonomy
482
- * Improvement: Update timepicker to latest version
483
- * Improvement: Improve output markup for checkbox field
484
-
485
- = 4.4.1 =
486
- * Fix: wrong text domain
487
- * Fix: `select_advanced` field not cloning
488
- * Fix: cloned emails are not saved
489
- * Improvement: Use `post_types` instead of `pages`, accept string for single post type as well. Fallback to `pages` for previous versions.
490
-
491
- = 4.4.0 =
492
- * New: 'autocomplete' field.
493
- * Improvement: field id is now optional (heading, divider)
494
- * Improvement: heading now supports 'description'
495
- * Improvement: update select2 library to version 3.5.2
496
- * Improvement: coding standards
497
-
498
- = 4.3.11 =
499
- * Bug fix: use field id instead of field_name for wysiwyg field
500
- * Improvement: allow to sort files
501
- * Improvement: use 'meta-box' text domain instead of 'rwmb'
502
- * Improvement: coding standards
503
-
504
- = 4.3.10 =
505
- * Bug fix: upload & reorder for image fields
506
- * Bug fix: not saving meta caused by page template issue
507
- * Bug fix: filter names for helper and shortcode callback functions
508
- * Bug fix: loads correct locale JS files for jQueryUI date/time picker
509
-
510
- = 4.3.9 =
511
- * Bug fix: `text-list` field type
512
- * Improvement: better coding styles
513
- * Improvement: wysiwyg field is now clonable
514
- * Improvement: launch geolocation autocomplete when address field is cloned
515
- * Improvement: better cloning for radio, checkbox
516
- * Improvement: add more hooks
517
- * Improvement: allow child fields to add their own add/remove clone buttons.
518
- * Improvement: remove 'clone-group'. Too complicated and not user-friendly.
519
-
520
- = 4.3.8 =
521
- * Bug fix: compatibility with PHP 5.2
522
-
523
- = 4.3.7 =
524
- * Bug fix: use WP_Query instead of `query_posts` to be compatible with WPML
525
- * Bug fix: `get_called_class` function in PHP < 5.3
526
- * Bug fix: clone now works for `slider` field
527
- * Bug fix: fix cloning URL field
528
- * Bug fix: hidden drop area if no max_file_uploads defined
529
- * Improvement: added composer.json
530
- * Improvement: add Chinese language
531
- * Improvement: better check for duplication when save post
532
- * Improvement: new `image_select` file, which is "radio image", e.g. select a radio value by selecting image
533
- * Improvement: new `file_input` field, which allows to upload files or enter file URL
534
- * Improvement: separate core code for meta box and fields
535
- * Improvement: allow to add more map options in helper function
536
- * Improvement: allow to pass more arguments to "get_terms" function when getting meta value with "rwmb_meta"
537
-
538
- = 4.3.6 =
539
- * Bug fix: fatal error in PHP 5.2 (continue)
540
- * Improvement: allow register meta boxes via filter
541
-
542
- = 4.3.5 =
543
- * Bug fix: fatal error in PHP 5.2
544
- * Bug fix: save empty values of clonable fields
545
-
546
- = 4.3.4 =
547
- * Bug fix: not show upload button after delete image when reach max_file_upload. #347
548
- * Bug fix: autocomplete for map which conflicts with tags (terms) autocomplete
549
- * Bug fix: random image order when reorder
550
- * Bug fix: undefined index, notices in WordPress 3.6, notice error for oembed field
551
- * Improvement: add default location for map field (via `std` param as usual)
552
- * Improvement: add `placeholder` for text fields (url, email, etc.)
553
- * Improvement: add `multiple` param for helper function to get value of multiple fields
554
- * Improvement: `width` & `height` for map in helper function now requires units (allow to set %)
555
- * Drop support for WordPress 3.3 (wysiwyg) and < 3.5 (for file & image field which uses new json functions)
556
-
557
- = 4.3.3 =
558
- * Bug fix: cannot clear all terms in taxonomy field
559
- * Bug fix: potential problem with autosave
560
- * Bug fix: cannot save zero string value "0"
561
- * Improvement: add Turkish language
562
- * Improvement: add taxonomy_advanced field, which saves term IDs as comma separated value in custom field
563
-
564
- = 4.3.2 =
565
- * Bug fix: allow to have more than 1 map on a page
566
- * Bug fix: use HTTPS for Google Maps to work both in HTTP & HTTPS
567
- * Bug fix: allow to clear all terms in taxonomy field
568
- * Bug fix: "std" value for select fields is no longer "placeholder"
569
- * Improvement: add "placeholder" param for select fields
570
- * Improvement: add to helper function ability to show Google Maps in the front end. Check documentation for usage.
571
- * Improvement: add spaces between radio inputs
572
- * Improvement: add more params to "rwmb_meta" filter
573
- * Improvement: using CSS animation for delete image
574
-
575
- = 4.3.1 =
576
- * Bug fix: fatal error if ASP open tag is allowed in php.ini
577
-
578
- = 4.3 =
579
- * Bug fix: show full size image after upload if thumbnail is not available
580
- * Bug fix: new added file not shown
581
- * Bug fix: issue with color field disappearing
582
- * Bug fix: `max_file_upload` now works for normal `file` & `image` as well
583
- * Bug fix: problem with uploading with the advanced fields
584
- * Bug fix: file & image advanced not saving
585
- * Bug fix: `select_advanced` cloning issue
586
- * Bug fix: `plupload_image` ordering
587
- * Improvement: add `divider`, `heading`, `button`, `range`, `oembed`, `email`, `post` fields
588
- * Improvement: translation for file & image fields
589
- * Improvement: add option `default_hidden` to hide meta box by default
590
- * Improvement: allow to have multiple maps on the same page
591
- * Improvement: file and image advanced now use Underscore.js
592
- * Improvement: `slider` filed now has `prefix` and `suffix` for text labels and `js_options` for more JS options
593
- * Improvement: WYSIWYS can bypass the `wpautop` using `raw` parameter
594
- * Improvement: `color` field now supports new color picker in WP 3.5
595
- * Improvement: add `ID` to results returned by `rwmb_meta` when getting meta value of file & image
596
- * Improvement: auto use localized version for date & time fields
597
- * Improvement: add `timestamp` option to save the datetime as unix timestamp internally
598
- * Improvement: add `autosave` option for meta box
599
- * Improvement: add `force_delete` option for file and image field
600
- * And lots of changes and improvements
601
-
602
-
603
- = 4.2.4 =
604
- * Bug fix: path to Select2 JS and CSS. [Link](http://wordpress.org/support/topic/missing-files-5)
605
- * Bug fix: `taxonomy.js` loading
606
- * Bug fix: saving in quick mode edit
607
- * Improvement: add `before` and `after` attributes to fields that can be used to display custom text
608
- * Improvement: add Arabic and Spanish languages
609
- * Improvement: add `rwmb*_before_save_post` and `rwmb*_before_save_post` actions before and after save post
610
- * Improvement: add autocomplete for geo location in `map` field, add fancy animation to drop marker
611
- * Improvemnet: add `url` field
612
-
613
-
614
- = 4.2.3 =
615
- * Bug fix: clone date field. [Link](http://www.deluxeblogtips.com/forums/viewtopic.php?id=299)
616
-
617
- = 4.2.2 =
618
- * Bug fix: `time` field doesn't work. [Link](http://wordpress.org/support/topic/time-field-js-wont-run-without-datetime)
619
- * Bug fix: wrong JS call for `datetime`. [Link](http://wordpress.org/support/topic/421-datetime)
620
- * Improvement: file and images now not deleted from library, *unless* use `force_delete` option
621
- * Improvement: add `select_advanced` field, which uses [select2](http://ivaynberg.github.com/select2/) for better UX. Thanks @funkedgeek
622
-
623
- = 4.2.1 =
624
- * Bug fix: not save wysiwyg field in full screen mode. [Link](http://www.deluxeblogtips.com/forums/viewtopic.php?id=161)
625
- * Bug fix: default value for select/checkbox_list. [Link](http://www.deluxeblogtips.com/forums/viewtopic.php?id=174)
626
- * Bug fix: duplicated append test to `date` picker
627
- * Bug fix: incorrect enqueue styles, issue #166
628
- * Improvement: initial new field type `map`
629
-
630
- = 4.2 =
631
- * Bug fix: save only last element of `select` field with `multiple` values. [Link](http://wordpress.org/support/topic/plugin-meta-box-multiple-declaration-for-select-fields-no-longer-working?replies=5#post-3254534)
632
- * Improvement: add `js_options` attribute for `date`, `datetime`, `time` fields to adjust jQuery date/datetime picker options. See `demo/demo.php` for usage
633
- * Improvement: add `options` attribute for `wysiwyg`. You now can pass arguments same as for `wp_editor` function
634
- * Improvement: clone feature now works with `checkbox_list` and `select` with `multiple` values
635
- * Improvement: add `rwmb-{$field_type}-wrapper` class to field markup
636
- * Improvement: Add [rwmb_meta meta_key="..."] shortcode. Attributes are the same as `rwmb_meta` function.
637
- * Code refactored
638
-
639
- = 4.1.11 =
640
- * Bug fix: helper function for getting `taxonomy` field type
641
- * Bug fix: `multiple` attribute for `select` field type
642
-
643
- = 4.1.10 =
644
- * Allow helper functions can be used in admin area
645
- * Allow cloned fields to have a uniquely indexed `name` attribute
646
- * Add Swedish translation
647
- * Allow hidden field has its own value
648
- * Taxonomy field now supported by `rwmb_meta` function
649
- * Improvement in code format and field normalizing
650
-
651
- = 4.1.9 =
652
- * Add helper function to retrieve meta values
653
- * Add basic validation (JS based)
654
- * Fix image reorder bug
655
- * Fix `select_tree` option for taxonomy field
656
- * Fix not showing loading image for 1st image using plupload
657
-
658
- = 4.1.8 =
659
- * Add missed JS file for thickbox image
660
-
661
- = 4.1.7 =
662
- * Quick fix for thickbox image
663
-
664
- = 4.1.6 =
665
- * Quick fix for checkbox list and multiple/clonable fields
666
-
667
- = 4.1.5 =
668
- * Taxonomy field is now in core
669
- * Add demo for including meta boxes for specific posts based on IDs or page templates
670
- * Meta box ID is now optional
671
- * Add `thickbox_image` field for uploading image with WP style
672
- * Fix `guid` for uploaded images
673
-
674
- = 4.1.4 =
675
- * Fix taxonomy field
676
-
677
- = 4.1.3 =
678
- * Support max_file_uploads for plupload_image
679
- * Better enqueue styles & scripts
680
- * Store images in correct order after re-order
681
- * Fix cloning color, date, time, datetime fields
682
-
683
- = 4.1.2 =
684
- * Improve taxonomy field
685
- * Add filter to wp_editor
686
- * Add more options for time field
687
- * Improve plupload_image field
688
- * Fix translation, use string for textdomain
689
-
690
- = 4.1.1 =
691
- * Fix translation
692
- * Change jQueryUI theme to 'smoothness'
693
- * Add more demos in the `demo` folder
694
-
695
- = 4.1 =
696
- * Added jQuery UI slider field
697
- * Added new Plupload file uploader
698
- * Added new checkbox list
699
- * Fix empty jQuery UI div seen in FF in admin footer area
700
- * Fix style for 'side' meta box
701
-
702
- = 4.0.2 =
703
- * Reformat code to make more readable
704
- * Fix bugs of checkbox field and date field
705
-
706
- = 4.0.1 =
707
- * Change format_response() to ajax_response() and use WP_Ajax_Response class to control the ajax response
708
- * Use wp_editor() built-in with WP 3.3 (with fallback)
709
-
710
- = 4.0 =
711
- * strongly refactor code
712
- * create/check better nonce for each meta box
713
- * use local JS/CSS libs instead of remote files for better control if conflict occurs
714
- * separate field functions (enqueue scripts and styles, add actions, show, save) into separated classes
715
- * use filters to let user change HTML of fields
716
- * use filters to validate/change field values instead of validation class
717
- * don't use Ajax on image upload as it's buggy and complicated. Revert to default upload
718
-
719
- = 3.2.2 =
720
- * fix WYSIWYG field for custom post type without 'editor' support. Thanks Jamie, Eugene and Selin Online. (http =//disq.us/2hzgsk)
721
- * change some helper function to static as they're shared between objects
722
-
723
- = 3.2.1 =
724
- * fix code for getting script's url in Windows
725
- * make meta box id is optional
726
-
727
- = 3.2 =
728
- * move js and css codes to separated files (rewrite js code for fields, too)
729
- * allow to add multiple images to image meta field with selection, modified from "Fast Insert Image" plugin
730
- * remove 'style' attibutes for fields as all CSS rules now can be put in the 'meta=box.css' file. All fields now has the class 'rw=$type', and table cells have class 'rwmb=label' and 'rwmb=field'
731
- * allow to use file uploader for images as well, regarding http =//disq.us/1k2lwf
732
- * when delete uploaded images, they're not deleted from the server (in case you insert them from the media, not the uploader). Also remove hook to delete all attachments when delete post. Regarding http =//disq.us/1nppyi
733
- * change hook for adding meta box to 'add_meta_boxes', according Codex. Required WP 3.0+
734
- * fix image uploading when custom post type doesn't support "editor"
735
- * fix show many alerts when delete files, regarding http =//disq.us/1lolgb
736
- * fix js comma missing bug when implement multiple fields with same type
737
- * fix order of uploaded images, thank Onur
738
- * fix deleting new uploaded image
739
- * fix bug when save meta value = zero (0), regarding http =//disq.us/1tg008
740
- * some minor changes such as = add 'id' attribute to fields, show uploaded images as thumbnail, add script to header of post.php and post=new.php only
741
-
742
- = 3.1 =
743
- * use thickbox for image uploading, allow user edit title, caption or crop, rotate image (credit to Stewart Duffy, idea from Jaace http =//disq.us/1bu64d)
744
- * allow to reorder uploaded images (credit to Kai)
745
- * save attach ID instead of url (credit to Stewart Duffy)
746
- * escape fields value (credit to Stewart Duffy)
747
- * add 'style' attribute to fields, allow user quick style fields (like height, width, etc.) (credit to Anders Larsson http =//disq.us/1eg4kp)
748
- * wrap ajax callbacks into the class
749
- * fix jquery UI conflict (for time picker, color picker, contextual help)
750
- * fix notice error for checking post type
751
-
752
- = 3.0.1 =
753
- * save uploaded images and files' urls in meta fields
754
- * fix date picker bug to not show saved value (http =//disq.us/1cg6mx)
755
- * fix check_admin_referer for non=supported post types (http =//goo.gl/B6cah)
756
- * refactor code for showing fields
757
-
758
- = 3.0 =
759
- * separate functions for checking, displaying and saving each type of field; allow developers easily extend the class
760
- * add 'checkbox_list' (credit to Jan Fabry http =//goo.gl/9sDAx), 'color', 'date', 'time' types. The 'taxonomy' type is added as an example of extending class (credit to Manny Fresh http =//goo.gl/goGfm)
761
- * show uploaded files as well as allow to add/delete attached files
762
- * delete attached files when post is deleted (credit to Kai http =//goo.gl/9gfvd)
763
- * validation function MUST return the value instead of true, false
764
- * change the way of definition 'radio', 'select' field type to make it more simpler, allow multiple selection of select box
765
- * improved some codes, fix code to not show warnings when in debugging mode
766
-
767
- = 2.4.1 =
768
- * fix bug of not receiving value for select box
769
-
770
- = 2.4 =
771
- * (image upload features are credit to Kai http =//twitter.com/ungestaltbar)
772
- * change image upload using meta fields to using default WP gallery
773
- * add delete button for images, using ajax
774
- * allow to upload multiple images
775
- * add validation for meta fields
776
-
777
- = 2.3 =
778
- * add wysiwyg editor type, improve check for upload fields, change context and priority attributes to optional
779
-
780
- = 2.2 =
781
- * add enctype to post form (fix upload bug), thanks to http =//goo.gl/PWWNf
782
-
783
- = 2.1 =
784
- * add file upload, image upload support
785
-
786
- = 2.0 =
787
- * oop code, support multiple post types, multiple meta boxes
788
-
789
- = 1.0 =
790
- * procedural code
791
 
792
  == Upgrade Notice ==
3
  Donate link: http://paypal.me/anhtnt
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.8
7
+ Stable tag: 4.12.1
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.
128
 
129
  == Changelog ==
130
 
131
+ = 4.12.1 - 2017-07-05 =
132
+ #### Fixed
133
+ - Helper function doesn't work. #1144.
134
+
135
+ = 4.12 - 2017-07-04 =
136
+ #### Added
137
+ - Completed the storage abstraction. All the actions add/get/update/delete post meta now use the storage methods. Make it easy to extend for other extensions for term/user meta and settings pages.
138
+ - Added `autofocus`, `autocomplete` HTML5 attribute to inputs.
139
+ - Added `alpha_channel` to `color` field. Set it to `true` to allow picking colors with opacity.
140
+ - Click on the image will open a popup for re-select image. Works for `image_advanced` and `image_upload` (`plupload_image`) fields.
141
+
142
+ #### Changed
143
+ - Auto display oembed media when pasting the URL, without click "Preview" button (and it's removed).
144
+ - Better styles for media fields. Use the loading icon from WordPress.
145
+
146
+ #### Fixed
147
+ - Fix cloning an editor inside a group in WordPress 4.8. Caused by updated version of TinyMCE using Promise.
148
+ - Modals created by media fields now exclude already selected media. This was a previous feature, but it had caused problems with uploading.
149
+ - Fixed Google map doesn't use custom style
150
+
151
+ [See changelog for all versions](https://github.com/rilwis/meta-box/blob/master/CHANGELOG.md).
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
 
153
  == Upgrade Notice ==