Meta Box - Version 4.14.10

Version Description

Download this release

Release Info

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

Code changes from version 4.15.5 to 4.14.10

css/button-group.css CHANGED
@@ -21,48 +21,48 @@
21
  }
22
  /* Layout not inline
23
  -------------------------------------------------*/
24
- .rwmb-button-input-list:not(.rwmb-inline) li label {
25
  border-top-width: 0;
26
  }
27
- .rwmb-button-input-list:not(.rwmb-inline) li:first-child label {
28
  border-top-width: 1px;
29
  }
30
- .rwmb-button-input-list:not(.rwmb-inline) li label.selected {
31
  border-bottom: 1px solid #fff;
32
  }
33
- .rwmb-button-input-list:not(.rwmb-inline) li:last-child label.selected {
34
  border-bottom-color: #0073aa;
35
  }
36
- .rwmb-button-input-list:not(.rwmb-inline) > li:first-child:not(:last-child) label {
37
  border-top-left-radius: 3px;
38
  border-top-right-radius: 3px;
39
  }
40
- .rwmb-button-input-list:not(.rwmb-inline) > li:last-child:not(:first-child) label {
41
  border-bottom-right-radius: 3px;
42
  border-bottom-left-radius: 3px;
43
  }
44
  /* Layout inline
45
  ---------------------------------------------*/
46
- .rwmb-button-input-list.rwmb-inline li {
47
  display: inline-block;
48
  }
49
- .rwmb-button-input-list.rwmb-inline li label {
50
  border-left-width: 0;
51
  }
52
- .rwmb-button-input-list.rwmb-inline li:first-child label {
53
  border-left-width: 1px;
54
  }
55
- .rwmb-button-input-list.rwmb-inline li label.selected {
56
  border-right-color: rgb(255, 255, 255);
57
  }
58
- .rwmb-button-input-list.rwmb-inline li:last-child label.selected {
59
  border-right-color: #0073aa;
60
  }
61
- .rwmb-button-input-list.rwmb-inline > li:first-child:not(:last-child) label {
62
  border-top-left-radius: 3px;
63
  border-bottom-left-radius: 3px;
64
  }
65
- .rwmb-button-input-list.rwmb-inline > li:last-child:not(:first-child) label {
66
  border-top-right-radius: 3px;
67
  border-bottom-right-radius: 3px;
68
  }
21
  }
22
  /* Layout not inline
23
  -------------------------------------------------*/
24
+ .rwmb-button-input-list:not(.inline) li label {
25
  border-top-width: 0;
26
  }
27
+ .rwmb-button-input-list:not(.inline) li:first-child label {
28
  border-top-width: 1px;
29
  }
30
+ .rwmb-button-input-list:not(.inline) li label.selected {
31
  border-bottom: 1px solid #fff;
32
  }
33
+ .rwmb-button-input-list:not(.inline) li:last-child label.selected {
34
  border-bottom-color: #0073aa;
35
  }
36
+ .rwmb-button-input-list:not(.inline) > li:first-child:not(:last-child) label {
37
  border-top-left-radius: 3px;
38
  border-top-right-radius: 3px;
39
  }
40
+ .rwmb-button-input-list:not(.inline) > li:last-child:not(:first-child) label {
41
  border-bottom-right-radius: 3px;
42
  border-bottom-left-radius: 3px;
43
  }
44
  /* Layout inline
45
  ---------------------------------------------*/
46
+ .rwmb-button-input-list.inline li {
47
  display: inline-block;
48
  }
49
+ .rwmb-button-input-list.inline li label {
50
  border-left-width: 0;
51
  }
52
+ .rwmb-button-input-list.inline li:first-child label {
53
  border-left-width: 1px;
54
  }
55
+ .rwmb-button-input-list.inline li label.selected {
56
  border-right-color: rgb(255, 255, 255);
57
  }
58
+ .rwmb-button-input-list.inline li:last-child label.selected {
59
  border-right-color: #0073aa;
60
  }
61
+ .rwmb-button-input-list.inline > li:first-child:not(:last-child) label {
62
  border-top-left-radius: 3px;
63
  border-bottom-left-radius: 3px;
64
  }
65
+ .rwmb-button-input-list.inline > li:last-child:not(:first-child) label {
66
  border-top-right-radius: 3px;
67
  border-bottom-right-radius: 3px;
68
  }
css/color.css CHANGED
@@ -3,6 +3,6 @@
3
  }
4
  .rwmb-color-wrapper .wp-picker-holder {
5
  position: absolute;
6
- z-index: 99;
7
  min-width: 255px;
8
  }
3
  }
4
  .rwmb-color-wrapper .wp-picker-holder {
5
  position: absolute;
6
+ z-index: 9;
7
  min-width: 255px;
8
  }
css/input-list.css CHANGED
@@ -9,12 +9,12 @@
9
  list-style: none;
10
  margin-bottom: 0;
11
  }
12
- .rwmb-input-list.rwmb-inline {
13
  line-height: inherit;
14
  }
15
- .rwmb-input-list.rwmb-inline li {
16
  display: inline-block;
17
  }
18
- .rwmb-input-list.rwmb-inline li:not(:last-child) {
19
  margin-right: 20px;
20
  }
9
  list-style: none;
10
  margin-bottom: 0;
11
  }
12
+ .rwmb-input-list.inline {
13
  line-height: inherit;
14
  }
15
+ .rwmb-input-list.inline li {
16
  display: inline-block;
17
  }
18
+ .rwmb-input-list.inline li:not(:last-child) {
19
  margin-right: 20px;
20
  }
css/map.css CHANGED
@@ -3,47 +3,3 @@
3
  height: 400px;
4
  margin-bottom: 10px;
5
  }
6
-
7
- /* Autocomplete style, copy from WordPress's common.css and forms.css */
8
-
9
- input.ui-autocomplete-input.open {
10
- border-bottom-color: transparent;
11
- }
12
-
13
- .ui-autocomplete {
14
- padding: 0;
15
- margin: 0;
16
- list-style: none;
17
- position: absolute;
18
- z-index: 10000;
19
- border: 1px solid #5b9dd9;
20
- box-shadow: 0 1px 2px rgba( 30, 140, 190, 0.8 );
21
- background-color: #fff;
22
- }
23
-
24
- .ui-autocomplete li {
25
- margin-bottom: 0;
26
- padding: 4px 10px;
27
- white-space: nowrap;
28
- text-align: left;
29
- cursor: pointer;
30
- }
31
-
32
- /* Colors for the wplink toolbar autocomplete. */
33
- .ui-autocomplete .ui-state-focus {
34
- background-color: #ddd;
35
- }
36
-
37
- .ui-helper-hidden-accessible {
38
- border: 0;
39
- clip: rect(1px, 1px, 1px, 1px);
40
- -webkit-clip-path: inset(50%);
41
- clip-path: inset(50%);
42
- height: 1px;
43
- margin: -1px;
44
- overflow: hidden;
45
- padding: 0;
46
- position: absolute;
47
- width: 1px;
48
- word-wrap: normal !important; /* many screen reader and browser combinations announce broken words as they would appear visually */
49
- }
3
  height: 400px;
4
  margin-bottom: 10px;
5
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
css/osm.css DELETED
@@ -1,49 +0,0 @@
1
- .rwmb-osm-canvas {
2
- width: 100%;
3
- height: 400px;
4
- margin-bottom: 10px;
5
- }
6
-
7
- /* Autocomplete style, copy from WordPress's common.css and forms.css */
8
-
9
- input.ui-autocomplete-input.open {
10
- border-bottom-color: transparent;
11
- }
12
-
13
- .ui-autocomplete {
14
- padding: 0;
15
- margin: 0;
16
- list-style: none;
17
- position: absolute;
18
- z-index: 10000;
19
- border: 1px solid #5b9dd9;
20
- box-shadow: 0 1px 2px rgba( 30, 140, 190, 0.8 );
21
- background-color: #fff;
22
- }
23
-
24
- .ui-autocomplete li {
25
- margin-bottom: 0;
26
- padding: 4px 10px;
27
- white-space: nowrap;
28
- text-align: left;
29
- cursor: pointer;
30
- }
31
-
32
- /* Colors for the wplink toolbar autocomplete. */
33
- .ui-autocomplete .ui-state-focus {
34
- background-color: #ddd;
35
- }
36
-
37
- .ui-helper-hidden-accessible {
38
- border: 0;
39
- clip: rect(1px, 1px, 1px, 1px);
40
- -webkit-clip-path: inset(50%);
41
- clip-path: inset(50%);
42
- height: 1px;
43
- margin: -1px;
44
- overflow: hidden;
45
- padding: 0;
46
- position: absolute;
47
- width: 1px;
48
- word-wrap: normal !important; /* many screen reader and browser combinations announce broken words as they would appear visually */
49
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/about/about.php CHANGED
@@ -137,8 +137,8 @@ class RWMB_About {
137
  * Enqueue CSS and JS.
138
  */
139
  public function enqueue() {
140
- wp_enqueue_style( 'meta-box-about', RWMB_URL . 'inc/about/css/about.css', array(), RWMB_VER );
141
- wp_enqueue_script( 'meta-box-about', RWMB_URL . 'inc/about/js/about.js', array( 'jquery' ), RWMB_VER, true );
142
  }
143
 
144
  /**
@@ -165,7 +165,7 @@ class RWMB_About {
165
  * or just the current site. Multisite only. Default is false.
166
  */
167
  public function redirect( $plugin, $network_wide ) {
168
- if ( 'cli' !== php_sapi_name() && ! $network_wide && 'meta-box/meta-box.php' === $plugin && ! $this->is_bundled() ) {
169
  wp_safe_redirect( $this->get_menu_link() );
170
  die;
171
  }
137
  * Enqueue CSS and JS.
138
  */
139
  public function enqueue() {
140
+ wp_enqueue_style( 'meta-box-about', RWMB_URL . 'inc/about/css/about.css' );
141
+ wp_enqueue_script( 'meta-box-about', RWMB_URL . 'inc/about/js/about.js', array( 'jquery' ), '', true );
142
  }
143
 
144
  /**
165
  * or just the current site. Multisite only. Default is false.
166
  */
167
  public function redirect( $plugin, $network_wide ) {
168
+ if ( ! $network_wide && 'meta-box/meta-box.php' === $plugin && ! $this->is_bundled() ) {
169
  wp_safe_redirect( $this->get_menu_link() );
170
  die;
171
  }
inc/about/sections/tabs.php CHANGED
@@ -8,7 +8,7 @@
8
  ?>
9
  <h2 class="nav-tab-wrapper">
10
  <a href="#getting-started" class="nav-tab nav-tab-active"><?php esc_html_e( 'Getting Started', 'meta-box' ); ?></a>
11
- <?php do_action( 'rwmb_about_tabs' ); ?>
12
  <a href="#extensions" class="nav-tab"><?php esc_html_e( 'Extensions', 'meta-box' ); ?></a>
13
  <a href="#support" class="nav-tab"><?php esc_html_e( 'Support', 'meta-box' ); ?></a>
14
  </h2>
8
  ?>
9
  <h2 class="nav-tab-wrapper">
10
  <a href="#getting-started" class="nav-tab nav-tab-active"><?php esc_html_e( 'Getting Started', 'meta-box' ); ?></a>
11
+ <?php do_action( 'rwmb_about_tabs' ); ?>
12
  <a href="#extensions" class="nav-tab"><?php esc_html_e( 'Extensions', 'meta-box' ); ?></a>
13
  <a href="#support" class="nav-tab"><?php esc_html_e( 'Support', 'meta-box' ); ?></a>
14
  </h2>
inc/field.php CHANGED
@@ -290,7 +290,7 @@ abstract class RWMB_Field {
290
  * @param array $field The field parameters.
291
  */
292
  public static function save( $new, $old, $post_id, $field ) {
293
- if ( empty( $field['id'] ) || ! $field['save_field'] ) {
294
  return;
295
  }
296
  $name = $field['id'];
@@ -388,7 +388,6 @@ abstract class RWMB_Field {
388
  'after' => '',
389
  'field_name' => isset( $field['id'] ) ? $field['id'] : '',
390
  'placeholder' => '',
391
- 'save_field' => true,
392
 
393
  'clone' => false,
394
  'max_clone' => 0,
290
  * @param array $field The field parameters.
291
  */
292
  public static function save( $new, $old, $post_id, $field ) {
293
+ if ( empty( $field['id'] ) ) {
294
  return;
295
  }
296
  $name = $field['id'];
388
  'after' => '',
389
  'field_name' => isset( $field['id'] ) ? $field['id'] : '',
390
  'placeholder' => '',
 
391
 
392
  'clone' => false,
393
  'max_clone' => 0,
inc/fields/background.php CHANGED
@@ -144,7 +144,7 @@ class RWMB_Background_Field extends RWMB_Field {
144
  $output = '';
145
  $value = array_filter( $value );
146
  foreach ( $value as $key => $subvalue ) {
147
- $subvalue = 'image' === $key ? 'url(' . esc_url( $subvalue ) . ')' : $subvalue;
148
  $output .= 'background-' . $key . ': ' . $subvalue . ';';
149
  }
150
  return $output;
144
  $output = '';
145
  $value = array_filter( $value );
146
  foreach ( $value as $key => $subvalue ) {
147
+ $subvalue = 'image' === $key ? 'url( "' . esc_url( $subvalue ) . '")' : $subvalue;
148
  $output .= 'background-' . $key . ': ' . $subvalue . ';';
149
  }
150
  return $output;
inc/fields/button-group.php CHANGED
@@ -18,20 +18,22 @@ class RWMB_Button_Group_Field extends RWMB_Choice_Field {
18
  }
19
 
20
  /**
21
- * Get field HTML.
 
 
 
 
 
22
  *
23
- * @param mixed $meta Meta value.
24
- * @param array $field Field parameters.
25
  * @return string
26
  */
27
- public static function html( $meta, $field ) {
28
- $options = self::transform_options( $field['options'] );
29
- $walker = new RWMB_Walker_Input_List( $field, $meta );
30
 
31
  $output = sprintf( '<ul class="rwmb-button-input-list %s">',
32
- $field['inline'] ? ' rwmb-inline' : ''
33
  );
34
- $output .= $walker->walk( $options, -1 );
35
  $output .= '</ul>';
36
 
37
  return $output;
18
  }
19
 
20
  /**
21
+ * Walk options.
22
+ *
23
+ * @param array $field Field parameters.
24
+ * @param mixed $options Select options.
25
+ * @param mixed $db_fields Database fields to use in the output.
26
+ * @param mixed $meta Meta value.
27
  *
 
 
28
  * @return string
29
  */
30
+ public static function walk( $field, $options, $db_fields, $meta ) {
31
+ $walker = new RWMB_Walker_Input_List( $db_fields, $field, $meta );
 
32
 
33
  $output = sprintf( '<ul class="rwmb-button-input-list %s">',
34
+ $field['inline'] ? 'inline' : ''
35
  );
36
+ $output .= $walker->walk( $options, - 1 );
37
  $output .= '</ul>';
38
 
39
  return $output;
inc/fields/choice.php CHANGED
@@ -9,6 +9,19 @@
9
  * Abstract class for any kind of choice field.
10
  */
11
  abstract class RWMB_Choice_Field extends RWMB_Field {
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  /**
13
  * Get field HTML.
14
  *
@@ -17,7 +30,11 @@ abstract class RWMB_Choice_Field extends RWMB_Field {
17
  * @return string
18
  */
19
  public static function html( $meta, $field ) {
20
- return '';
 
 
 
 
21
  }
22
 
23
  /**
@@ -37,25 +54,55 @@ abstract class RWMB_Choice_Field extends RWMB_Field {
37
  }
38
 
39
  /**
40
- * Transform field options into the verbose format.
41
  *
42
- * @param array $options Field options.
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  *
44
  * @return array
45
  */
46
- public static function transform_options( $options ) {
47
- $transformed = array();
48
- $options = (array) $options;
49
- foreach ( $options as $value => $label ) {
50
  $option = is_array( $label ) ? $label : array(
51
  'label' => (string) $label,
52
  'value' => (string) $value,
53
  );
54
  if ( isset( $option['label'] ) && isset( $option['value'] ) ) {
55
- $transformed[ $option['value'] ] = (object) $option;
56
  }
57
  }
58
- return $transformed;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  }
60
 
61
  /**
@@ -69,7 +116,19 @@ abstract class RWMB_Choice_Field extends RWMB_Field {
69
  * @return string
70
  */
71
  public static function format_single_value( $field, $value, $args, $post_id ) {
72
- $options = self::transform_options( $field['options'] );
 
 
 
 
 
 
 
 
 
 
 
 
73
  return isset( $options[ $value ] ) ? $options[ $value ]->label : '';
74
  }
75
  }
9
  * Abstract class for any kind of choice field.
10
  */
11
  abstract class RWMB_Choice_Field extends RWMB_Field {
12
+ /**
13
+ * Walk options.
14
+ *
15
+ * @param array $field Field parameters.
16
+ * @param mixed $options Select options.
17
+ * @param mixed $db_fields Database fields to use in the output.
18
+ * @param mixed $meta Meta value.
19
+ * @return string
20
+ */
21
+ public static function walk( $field, $options, $db_fields, $meta ) {
22
+ return '';
23
+ }
24
+
25
  /**
26
  * Get field HTML.
27
  *
30
  * @return string
31
  */
32
  public static function html( $meta, $field ) {
33
+ $meta = (array) $meta;
34
+ $options = self::call( 'get_options', $field );
35
+ $options = self::call( 'filter_options', $field, $options );
36
+ $db_fields = self::call( 'get_db_fields', $field );
37
+ return ! empty( $options ) ? self::call( 'walk', $field, $options, $db_fields, $meta ) : null;
38
  }
39
 
40
  /**
54
  }
55
 
56
  /**
57
+ * Get field names of object to be used by walker.
58
  *
59
+ * @return array
60
+ */
61
+ public static function get_db_fields() {
62
+ return array(
63
+ 'parent' => 'parent',
64
+ 'id' => 'value',
65
+ 'label' => 'label',
66
+ );
67
+ }
68
+
69
+ /**
70
+ * Get options for walker.
71
+ *
72
+ * @param array $field Field parameters.
73
  *
74
  * @return array
75
  */
76
+ public static function get_options( $field ) {
77
+ $options = array();
78
+ foreach ( (array) $field['options'] as $value => $label ) {
 
79
  $option = is_array( $label ) ? $label : array(
80
  'label' => (string) $label,
81
  'value' => (string) $value,
82
  );
83
  if ( isset( $option['label'] ) && isset( $option['value'] ) ) {
84
+ $options[ $option['value'] ] = (object) $option;
85
  }
86
  }
87
+ return $options;
88
+ }
89
+
90
+ /**
91
+ * Filter options for walker.
92
+ *
93
+ * @param array $field Field parameters.
94
+ * @param array $options Array of choice options.
95
+ *
96
+ * @return array
97
+ */
98
+ public static function filter_options( $field, $options ) {
99
+ $db_fields = self::call( 'get_db_fields', $field );
100
+ $label = $db_fields['label'];
101
+ foreach ( $options as &$option ) {
102
+ $option = apply_filters( 'rwmb_option', $option, $field );
103
+ $option->$label = apply_filters( 'rwmb_option_label', $option->$label, $option, $field );
104
+ }
105
+ return $options;
106
  }
107
 
108
  /**
116
  * @return string
117
  */
118
  public static function format_single_value( $field, $value, $args, $post_id ) {
119
+ return self::call( 'get_option_label', $field, $value );
120
+ }
121
+
122
+ /**
123
+ * Get option label.
124
+ *
125
+ * @param array $field Field parameters.
126
+ * @param string $value Option value.
127
+ *
128
+ * @return string
129
+ */
130
+ public static function get_option_label( $field, $value ) {
131
+ $options = self::call( 'get_options', $field );
132
  return isset( $options[ $value ] ) ? $options[ $value ]->label : '';
133
  }
134
  }
inc/fields/datetime.php CHANGED
@@ -252,7 +252,7 @@ class RWMB_Datetime_Field extends RWMB_Text_Field {
252
  * @return string
253
  */
254
  public static function format_single_value( $field, $value, $args, $post_id ) {
255
- if ( empty( $args['format'] ) ) {
256
  return $value;
257
  }
258
  if ( ! $field['timestamp'] ) {
252
  * @return string
253
  */
254
  public static function format_single_value( $field, $value, $args, $post_id ) {
255
+ if ( ! isset( $args['format'] ) ) {
256
  return $value;
257
  }
258
  if ( ! $field['timestamp'] ) {
inc/fields/file-input.php CHANGED
@@ -14,7 +14,7 @@ class RWMB_File_Input_Field extends RWMB_Input_Field {
14
  */
15
  public static function admin_enqueue_scripts() {
16
  wp_enqueue_media();
17
- wp_enqueue_style( 'rwmb-file-input', RWMB_CSS_URL . 'file-input.css', array(), RWMB_VER );
18
  wp_enqueue_script( 'rwmb-file-input', RWMB_JS_URL . 'file-input.js', array( 'jquery' ), RWMB_VER, true );
19
  self::localize_script('rwmb-file-input', 'rwmbFileInput', array(
20
  'frameTitle' => esc_html__( 'Select File', 'meta-box' ),
14
  */
15
  public static function admin_enqueue_scripts() {
16
  wp_enqueue_media();
17
+ wp_enqueue_style( 'rwmb-file-input', RWMB_CSS_URL . 'file-input.css' );
18
  wp_enqueue_script( 'rwmb-file-input', RWMB_JS_URL . 'file-input.js', array( 'jquery' ), RWMB_VER, true );
19
  self::localize_script('rwmb-file-input', 'rwmbFileInput', array(
20
  'frameTitle' => esc_html__( 'Select File', 'meta-box' ),
inc/fields/input-list.php CHANGED
@@ -18,21 +18,23 @@ class RWMB_Input_List_Field extends RWMB_Choice_Field {
18
  }
19
 
20
  /**
21
- * Get field HTML.
 
 
 
 
 
22
  *
23
- * @param mixed $meta Meta value.
24
- * @param array $field Field parameters.
25
  * @return string
26
  */
27
- public static function html( $meta, $field ) {
28
- $options = self::transform_options( $field['options'] );
29
- $walker = new RWMB_Walker_Input_List( $field, $meta );
30
  $output = self::get_select_all_html( $field );
31
- $output .= sprintf( '<ul class="rwmb-input-list%s%s">',
32
- $field['collapse'] ? ' rwmb-collapse' : '',
33
- $field['inline'] ? ' rwmb-inline' : ''
34
  );
35
- $output .= $walker->walk( $options, $field['flatten'] ? -1 : 0 );
36
  $output .= '</ul>';
37
 
38
  return $output;
18
  }
19
 
20
  /**
21
+ * Walk options.
22
+ *
23
+ * @param array $field Field parameters.
24
+ * @param mixed $options Select options.
25
+ * @param mixed $db_fields Database fields to use in the output.
26
+ * @param mixed $meta Meta value.
27
  *
 
 
28
  * @return string
29
  */
30
+ public static function walk( $field, $options, $db_fields, $meta ) {
31
+ $walker = new RWMB_Walker_Input_List( $db_fields, $field, $meta );
 
32
  $output = self::get_select_all_html( $field );
33
+ $output .= sprintf( '<ul class="rwmb-input-list %s %s">',
34
+ $field['collapse'] ? 'collapse' : '',
35
+ $field['inline'] ? 'inline' : ''
36
  );
37
+ $output .= $walker->walk( $options, $field['flatten'] ? - 1 : 0 );
38
  $output .= '</ul>';
39
 
40
  return $output;
inc/fields/map.php CHANGED
@@ -13,7 +13,7 @@ class RWMB_Map_Field extends RWMB_Field {
13
  * Enqueue scripts and styles.
14
  */
15
  public static function admin_enqueue_scripts() {
16
- wp_enqueue_style( 'rwmb-map', RWMB_CSS_URL . 'map.css', array(), RWMB_VER );
17
 
18
  /**
19
  * Since June 2016, Google Maps requires a valid API key.
@@ -37,14 +37,11 @@ class RWMB_Map_Field extends RWMB_Field {
37
  * @link https://developers.google.com/maps/documentation/javascript/libraries
38
  */
39
  $google_maps_url = apply_filters( 'rwmb_google_maps_url', $google_maps_url );
40
- wp_register_script( 'google-maps', esc_url_raw( $google_maps_url ), array(), RWMB_VER, true );
41
  wp_enqueue_script( 'rwmb-map', RWMB_JS_URL . 'map.js', array(
42
  'jquery-ui-autocomplete',
43
  'google-maps',
44
  ), RWMB_VER, true );
45
- self::localize_script( 'rwmb-map', 'RWMB_Map', array(
46
- 'no_results_string' => __( 'No results found', 'meta-box' ),
47
- ) );
48
  }
49
 
50
  /**
13
  * Enqueue scripts and styles.
14
  */
15
  public static function admin_enqueue_scripts() {
16
+ wp_enqueue_style( 'rwmb-map', RWMB_CSS_URL . 'map.css', array( 'common', 'forms' ), RWMB_VER );
17
 
18
  /**
19
  * Since June 2016, Google Maps requires a valid API key.
37
  * @link https://developers.google.com/maps/documentation/javascript/libraries
38
  */
39
  $google_maps_url = apply_filters( 'rwmb_google_maps_url', $google_maps_url );
40
+ wp_register_script( 'google-maps', esc_url_raw( $google_maps_url ), array(), '', true );
41
  wp_enqueue_script( 'rwmb-map', RWMB_JS_URL . 'map.js', array(
42
  'jquery-ui-autocomplete',
43
  'google-maps',
44
  ), RWMB_VER, true );
 
 
 
45
  }
46
 
47
  /**
inc/fields/media.php CHANGED
@@ -15,7 +15,7 @@ class RWMB_Media_Field extends RWMB_File_Field {
15
  public static function admin_enqueue_scripts() {
16
  wp_enqueue_media();
17
  if ( ! is_admin() ) {
18
- wp_register_script( 'media-grid', includes_url( 'js/media-grid.min.js' ), array( 'media-editor' ), '4.9.7', true );
19
  }
20
  wp_enqueue_style( 'rwmb-media', RWMB_CSS_URL . 'media.css', array(), RWMB_VER );
21
  wp_enqueue_script( 'rwmb-media', RWMB_JS_URL . 'media.js', array( 'jquery-ui-sortable', 'underscore', 'backbone', 'media-grid' ), RWMB_VER, true );
@@ -149,7 +149,7 @@ class RWMB_Media_Field extends RWMB_File_Field {
149
  * @return array|mixed
150
  */
151
  public static function value( $new, $old, $post_id, $field ) {
152
- $new = rwmb_csv_to_array( $new );
153
  array_walk( $new, 'absint' );
154
  return array_filter( array_unique( $new ) );
155
  }
@@ -163,9 +163,6 @@ class RWMB_Media_Field extends RWMB_File_Field {
163
  * @param array $field The field parameters.
164
  */
165
  public static function save( $new, $old, $post_id, $field ) {
166
- if ( empty( $field['id'] ) || ! $field['save_field'] ) {
167
- return;
168
- }
169
  $storage = $field['storage'];
170
  $storage->delete( $post_id, $field['id'] );
171
  parent::save( $new, array(), $post_id, $field );
15
  public static function admin_enqueue_scripts() {
16
  wp_enqueue_media();
17
  if ( ! is_admin() ) {
18
+ wp_register_script( 'media-grid', includes_url( 'js/media-grid.min.js' ), array( 'media-editor' ), '', true );
19
  }
20
  wp_enqueue_style( 'rwmb-media', RWMB_CSS_URL . 'media.css', array(), RWMB_VER );
21
  wp_enqueue_script( 'rwmb-media', RWMB_JS_URL . 'media.js', array( 'jquery-ui-sortable', 'underscore', 'backbone', 'media-grid' ), RWMB_VER, true );
149
  * @return array|mixed
150
  */
151
  public static function value( $new, $old, $post_id, $field ) {
152
+ $new = ! is_array( $new ) && is_string( $new ) ? explode( ',', $new ) : $new;
153
  array_walk( $new, 'absint' );
154
  return array_filter( array_unique( $new ) );
155
  }
163
  * @param array $field The field parameters.
164
  */
165
  public static function save( $new, $old, $post_id, $field ) {
 
 
 
166
  $storage = $field['storage'];
167
  $storage->delete( $post_id, $field['id'] );
168
  parent::save( $new, array(), $post_id, $field );
inc/fields/object-choice.php CHANGED
@@ -10,40 +10,16 @@
10
  */
11
  abstract class RWMB_Object_Choice_Field extends RWMB_Choice_Field {
12
  /**
13
- * Show field HTML.
14
- * Populate field options before showing to make sure query is made only once.
15
  *
16
- * @param array $field Field parameters.
17
- * @param bool $saved Whether the meta box is saved at least once.
18
- * @param int $post_id Post ID.
19
- */
20
- public static function show( $field, $saved, $post_id = 0 ) {
21
- $field['options'] = self::call( $field, 'query' );
22
-
23
- parent::show( $field, $saved, $post_id );
24
- }
25
-
26
- /**
27
- * Get field HTML.
28
- *
29
- * @param mixed $meta Meta value.
30
- * @param array $field Field parameters.
31
  * @return string
32
  */
33
- public static function html( $meta, $field ) {
34
- $html = call_user_func( array( self::get_type_class( $field ), 'html' ), $meta, $field );
35
- $html .= self::call( 'add_new_form', $field );
36
- return $html;
37
- }
38
-
39
- /**
40
- * Render "Add New" form
41
- *
42
- * @param array $field Field settings.
43
- * @return string
44
- */
45
- public static function add_new_form( $field ) {
46
- return '';
47
  }
48
 
49
  /**
@@ -92,6 +68,19 @@ abstract class RWMB_Object_Choice_Field extends RWMB_Choice_Field {
92
  return $attributes;
93
  }
94
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  /**
96
  * Enqueue scripts and styles.
97
  */
10
  */
11
  abstract class RWMB_Object_Choice_Field extends RWMB_Choice_Field {
12
  /**
13
+ * Get field HTML
 
14
  *
15
+ * @param array $field Field parameters.
16
+ * @param mixed $options Select options.
17
+ * @param mixed $db_fields Database fields to use in the output.
18
+ * @param mixed $meta Meta value.
 
 
 
 
 
 
 
 
 
 
 
19
  * @return string
20
  */
21
+ public static function walk( $field, $options, $db_fields, $meta ) {
22
+ return call_user_func( array( self::get_type_class( $field ), 'walk' ), $field, $options, $db_fields, $meta );
 
 
 
 
 
 
 
 
 
 
 
 
23
  }
24
 
25
  /**
68
  return $attributes;
69
  }
70
 
71
+ /**
72
+ * Get field names of object to be used by walker.
73
+ *
74
+ * @return array
75
+ */
76
+ public static function get_db_fields() {
77
+ return array(
78
+ 'parent' => '',
79
+ 'id' => '',
80
+ 'label' => '',
81
+ );
82
+ }
83
+
84
  /**
85
  * Enqueue scripts and styles.
86
  */
inc/fields/oembed.php CHANGED
@@ -9,30 +9,11 @@
9
  * OEmbed field class.
10
  */
11
  class RWMB_OEmbed_Field extends RWMB_Text_Field {
12
- /**
13
- * Normalize parameters for field.
14
- *
15
- * @param array $field Field parameters.
16
- * @return array
17
- */
18
- public static function normalize( $field ) {
19
- $field = parent::normalize( $field );
20
-
21
- $field = wp_parse_args( $field, array(
22
- 'not_available_string' => __( 'Embed HTML not available.', 'meta-box' ),
23
- ) );
24
- $field['attributes'] = wp_parse_args( $field['attributes'], array(
25
- 'data-not-available' => $field['not_available_string'],
26
- ) );
27
-
28
- return $field;
29
- }
30
-
31
  /**
32
  * Enqueue scripts and styles.
33
  */
34
  public static function admin_enqueue_scripts() {
35
- wp_enqueue_style( 'rwmb-oembed', RWMB_CSS_URL . 'oembed.css', '', RWMB_VER );
36
  wp_enqueue_script( 'rwmb-oembed', RWMB_JS_URL . 'oembed.js', array( 'jquery', 'underscore' ), RWMB_VER, true );
37
  }
38
 
@@ -48,18 +29,16 @@ class RWMB_OEmbed_Field extends RWMB_Text_Field {
48
  */
49
  public static function wp_ajax_get_embed() {
50
  $url = (string) filter_input( INPUT_POST, 'url', FILTER_SANITIZE_URL );
51
- $not_available = (string) filter_input( INPUT_POST, 'not_available' );
52
- wp_send_json_success( self::get_embed( $url, $not_available ) );
53
  }
54
 
55
  /**
56
  * Get embed html from url.
57
  *
58
- * @param string $url URL.
59
- * @param string $not_available Not available string displayed to users.
60
  * @return string
61
  */
62
- public static function get_embed( $url, $not_available = '' ) {
63
  /**
64
  * Set arguments for getting embeded HTML.
65
  * Without arguments, default width will be taken from global $content_width, which can break UI in the admin.
@@ -79,19 +58,10 @@ class RWMB_OEmbed_Field extends RWMB_Text_Field {
79
 
80
  // If no oembed provides found, try WordPress auto embed.
81
  if ( ! $embed ) {
82
- global $wp_embed;
83
- $temp = $wp_embed->return_false_on_fail;
84
- $wp_embed->return_false_on_fail = true; // Do not fallback to make a link.
85
- $embed = $wp_embed->shortcode( $args, $url );
86
- $wp_embed->return_false_on_fail = $temp;
87
- }
88
-
89
- if ( $not_available ) {
90
- $not_available = '<div class="rwmb-oembed-not-available">' . wp_kses_post( $not_available ) . '</div>';
91
  }
92
- $not_available = apply_filters( 'rwmb_oembed_not_available_string', $not_available );
93
 
94
- return $embed ? $embed : $not_available;
95
  }
96
 
97
  /**
@@ -105,7 +75,7 @@ class RWMB_OEmbed_Field extends RWMB_Text_Field {
105
  return parent::html( $meta, $field ) . sprintf(
106
  '<span class="spinner"></span>
107
  <div class="rwmb-embed-media">%s</div>',
108
- $meta ? self::get_embed( $meta, $field['not_available_string'] ) : ''
109
  );
110
  }
111
 
@@ -134,6 +104,6 @@ class RWMB_OEmbed_Field extends RWMB_Text_Field {
134
  * @return string
135
  */
136
  public static function format_single_value( $field, $value, $args, $post_id ) {
137
- return self::get_embed( $value, $field['not_available_string'] );
138
  }
139
  }
9
  * OEmbed field class.
10
  */
11
  class RWMB_OEmbed_Field extends RWMB_Text_Field {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  /**
13
  * Enqueue scripts and styles.
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
 
29
  */
30
  public static function wp_ajax_get_embed() {
31
  $url = (string) filter_input( INPUT_POST, 'url', FILTER_SANITIZE_URL );
32
+ wp_send_json_success( self::get_embed( $url ) );
 
33
  }
34
 
35
  /**
36
  * Get embed html from url.
37
  *
38
+ * @param string $url URL.
 
39
  * @return string
40
  */
41
+ public static function get_embed( $url ) {
42
  /**
43
  * Set arguments for getting embeded HTML.
44
  * Without arguments, default width will be taken from global $content_width, which can break UI in the admin.
58
 
59
  // If no oembed provides found, try WordPress auto embed.
60
  if ( ! $embed ) {
61
+ $embed = $GLOBALS['wp_embed']->shortcode( $args, $url );
 
 
 
 
 
 
 
 
62
  }
 
63
 
64
+ return $embed ? $embed : __( 'Embed HTML not available.', 'meta-box' );
65
  }
66
 
67
  /**
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
  }
81
 
104
  * @return string
105
  */
106
  public static function format_single_value( $field, $value, $args, $post_id ) {
107
+ return self::get_embed( $value );
108
  }
109
  }
inc/fields/osm.php DELETED
@@ -1,162 +0,0 @@
1
- <?php
2
- /**
3
- * The Open Street Map field.
4
- *
5
- * @package Meta Box
6
- * @since 4.15.0
7
- */
8
-
9
- /**
10
- * Open Street Map field class.
11
- */
12
- class RWMB_OSM_Field extends RWMB_Field {
13
- /**
14
- * Enqueue scripts and styles.
15
- */
16
- public static function admin_enqueue_scripts() {
17
- // Because map is a hosted service, it's ok to use hosted Leaflet scripts.
18
- wp_enqueue_style( 'leaflet', 'https://unpkg.com/leaflet@1.3.1/dist/leaflet.css', array(), '1.3.1' );
19
- wp_enqueue_script( 'leaflet', 'https://unpkg.com/leaflet@1.3.1/dist/leaflet.js', array(), '1.3.1', true );
20
-
21
- wp_enqueue_style( 'rwmb-osm', RWMB_CSS_URL . 'osm.css', array( 'leaflet' ), RWMB_VER );
22
- wp_enqueue_script( 'rwmb-osm', RWMB_JS_URL . 'osm.js', array( 'jquery', 'leaflet' ), RWMB_VER, true );
23
- self::localize_script( 'rwmb-osm', 'RWMB_Osm', array(
24
- 'no_results_string' => __( 'No results found', 'meta-box' ),
25
- ) );
26
- }
27
-
28
- /**
29
- * Get field HTML.
30
- *
31
- * @param mixed $meta Meta value.
32
- * @param array $field Field parameters.
33
- *
34
- * @return string
35
- */
36
- public static function html( $meta, $field ) {
37
- $address = is_array( $field['address_field'] ) ? implode( ',', $field['address_field'] ) : $field['address_field'];
38
- $html = sprintf(
39
- '<div class="rwmb-osm-field" data-address-field="%s">',
40
- esc_attr( $address )
41
- );
42
-
43
- $html .= sprintf(
44
- '<div class="rwmb-osm-canvas" data-default-loc="%s" data-region="%s" data-language="%s"></div>
45
- <input type="hidden" name="%s" class="rwmb-osm-coordinate" value="%s">',
46
- esc_attr( $field['std'] ),
47
- esc_attr( $field['region'] ),
48
- esc_attr( $field['language'] ),
49
- esc_attr( $field['field_name'] ),
50
- esc_attr( $meta )
51
- );
52
-
53
- if ( $field['address_field'] ) {
54
- $html .= sprintf(
55
- '<button class="button rwmb-osm-goto-address-button">%s</button>',
56
- esc_html__( 'Find Address', 'meta-box' )
57
- );
58
- }
59
-
60
- $html .= '</div>';
61
-
62
- return $html;
63
- }
64
-
65
- /**
66
- * Normalize parameters for field.
67
- *
68
- * @param array $field Field parameters.
69
- *
70
- * @return array
71
- */
72
- public static function normalize( $field ) {
73
- $field = parent::normalize( $field );
74
- $field = wp_parse_args( $field, array(
75
- 'std' => '',
76
- 'address_field' => '',
77
- 'language' => '',
78
- 'region' => '',
79
- ) );
80
-
81
- return $field;
82
- }
83
-
84
- /**
85
- * Get the field value.
86
- * The difference between this function and 'meta' function is 'meta' function always returns the escaped value
87
- * of the field saved in the database, while this function returns more meaningful value of the field.
88
- *
89
- * @param array $field Field parameters.
90
- * @param array $args Not used for this field.
91
- * @param int|null $post_id Post ID. null for current post. Optional.
92
- *
93
- * @return mixed Array(latitude, longitude, zoom)
94
- */
95
- public static function get_value( $field, $args = array(), $post_id = null ) {
96
- $value = parent::get_value( $field, $args, $post_id );
97
- list( $latitude, $longitude, $zoom ) = explode( ',', $value . ',,' );
98
- return compact( 'latitude', 'longitude', 'zoom' );
99
- }
100
-
101
- /**
102
- * Output the field value.
103
- * Display Google maps.
104
- *
105
- * @param array $field Field parameters.
106
- * @param array $args Additional arguments for the map.
107
- * @param int|null $post_id Post ID. null for current post. Optional.
108
- *
109
- * @return string HTML output of the field
110
- */
111
- public static function the_value( $field, $args = array(), $post_id = null ) {
112
- $value = parent::get_value( $field, $args, $post_id );
113
- return self::render_map( $value, $args );
114
- }
115
-
116
- /**
117
- * Render a map in the frontend.
118
- *
119
- * @param array $location The [latitude, longitude[, zoom]] location.
120
- * @param array $args Additional arguments for the map.
121
- *
122
- * @return string
123
- */
124
- public static function render_map( $location, $args = array() ) {
125
- list( $latitude, $longitude, $zoom ) = explode( ',', $location . ',,' );
126
- if ( ! $latitude || ! $longitude ) {
127
- return '';
128
- }
129
-
130
- $args = wp_parse_args( $args, array(
131
- 'latitude' => $latitude,
132
- 'longitude' => $longitude,
133
- 'width' => '100%',
134
- 'height' => '480px',
135
- 'marker' => true, // Display marker?
136
- 'marker_title' => '', // Marker title, when hover.
137
- 'info_window' => '', // Content of info window (when click on marker). HTML allowed.
138
- 'js_options' => array(),
139
- ) );
140
-
141
- wp_enqueue_style( 'leaflet', 'https://unpkg.com/leaflet@1.3.1/dist/leaflet.css', array(), '1.3.1' );
142
- wp_enqueue_script( 'leaflet', 'https://unpkg.com/leaflet@1.3.1/dist/leaflet.js', array(), '1.3.1', true );
143
- wp_enqueue_script( 'rwmb-osm-frontend', RWMB_JS_URL . 'osm-frontend.js', array( 'jquery', 'leaflet' ), RWMB_VER, true );
144
-
145
- /*
146
- * More Open Street Map options
147
- * @link https://leafletjs.com/reference-1.3.0.html#map-option
148
- */
149
- $args['js_options'] = wp_parse_args( $args['js_options'], array(
150
- // Default to 'zoom' level set in admin, but can be overwritten.
151
- 'zoom' => $zoom,
152
- ) );
153
-
154
- $output = sprintf(
155
- '<div class="rwmb-osm-canvas" data-osm_options="%s" style="width:%s;height:%s"></div>',
156
- esc_attr( wp_json_encode( $args ) ),
157
- esc_attr( $args['width'] ),
158
- esc_attr( $args['height'] )
159
- );
160
- return $output;
161
- }
162
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/fields/post.php CHANGED
@@ -16,10 +16,10 @@ class RWMB_Post_Field extends RWMB_Object_Choice_Field {
16
  * @return array
17
  */
18
  public static function normalize( $field ) {
 
19
  $field = wp_parse_args( $field, array(
20
- 'post_type' => 'post',
21
- 'parent' => false,
22
- 'query_args' => array(),
23
  ) );
24
 
25
  $field['post_type'] = (array) $field['post_type'];
@@ -41,6 +41,11 @@ class RWMB_Post_Field extends RWMB_Object_Choice_Field {
41
  $field = wp_parse_args( $field, array(
42
  'placeholder' => $placeholder,
43
  ) );
 
 
 
 
 
44
 
45
  // Set parent option, which will change field name to `parent_id` to save as post parent.
46
  if ( $field['parent'] ) {
@@ -48,36 +53,26 @@ class RWMB_Post_Field extends RWMB_Object_Choice_Field {
48
  $field['field_name'] = 'parent_id';
49
  }
50
 
51
- $field = parent::normalize( $field );
 
 
 
 
52
 
53
  return $field;
54
  }
55
 
56
  /**
57
- * Query posts for field options.
58
  *
59
- * @param array $field Field settings.
60
- * @return array Field options array.
61
  */
62
- public static function query( $field ) {
63
- $args = wp_parse_args( $field['query_args'], array(
64
- 'post_type' => $field['post_type'],
65
- 'post_status' => 'publish',
66
- 'posts_per_page' => -1,
67
- 'no_found_rows' => true,
68
- 'update_post_meta_cache' => false,
69
- 'update_post_term_cache' => false,
70
- ) );
71
- $query = new WP_Query( $args );
72
- $options = array();
73
- foreach ( $query->posts as $post ) {
74
- $options[ $post->ID ] = array(
75
- 'value' => $post->ID,
76
- 'label' => $post->post_title,
77
- 'parent' => $post->post_parent,
78
- );
79
- }
80
- return $options;
81
  }
82
 
83
  /**
@@ -98,17 +93,26 @@ class RWMB_Post_Field extends RWMB_Object_Choice_Field {
98
  }
99
 
100
  /**
101
- * Format a single value for the helper functions. Sub-fields should overwrite this method if necessary.
 
 
 
 
 
 
 
 
 
 
 
102
  *
103
- * @param array $field Field parameters.
104
- * @param string $value The value.
105
- * @param array $args Additional arguments. Rarely used. See specific fields for details.
106
- * @param int|null $post_id Post ID. null for current post. Optional.
107
  *
108
  * @return string
109
  */
110
- public static function format_single_value( $field, $value, $args, $post_id ) {
111
- return ! $value ? '' : sprintf(
112
  '<a href="%s" title="%s">%s</a>',
113
  esc_url( get_permalink( $value ) ),
114
  the_title_attribute( array(
16
  * @return array
17
  */
18
  public static function normalize( $field ) {
19
+ // Set default field args.
20
  $field = wp_parse_args( $field, array(
21
+ 'post_type' => 'post',
22
+ 'parent' => false,
 
23
  ) );
24
 
25
  $field['post_type'] = (array) $field['post_type'];
41
  $field = wp_parse_args( $field, array(
42
  'placeholder' => $placeholder,
43
  ) );
44
+ $field = parent::normalize( $field );
45
+
46
+ if ( ! isset( $field['query_args']['post_type'] ) ) {
47
+ $field['query_args']['post_type'] = $field['post_type'];
48
+ }
49
 
50
  // Set parent option, which will change field name to `parent_id` to save as post parent.
51
  if ( $field['parent'] ) {
53
  $field['field_name'] = 'parent_id';
54
  }
55
 
56
+ // Set default query args.
57
+ $field['query_args'] = wp_parse_args( $field['query_args'], array(
58
+ 'post_status' => 'publish',
59
+ 'posts_per_page' => - 1,
60
+ ) );
61
 
62
  return $field;
63
  }
64
 
65
  /**
66
+ * Get field names of object to be used by walker.
67
  *
68
+ * @return array
 
69
  */
70
+ public static function get_db_fields() {
71
+ return array(
72
+ 'parent' => 'post_parent',
73
+ 'id' => 'ID',
74
+ 'label' => 'post_title',
75
+ );
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  }
77
 
78
  /**
93
  }
94
 
95
  /**
96
+ * Get options for walker.
97
+ *
98
+ * @param array $field Field parameters.
99
+ * @return array
100
+ */
101
+ public static function get_options( $field ) {
102
+ $query = new WP_Query( $field['query_args'] );
103
+ return $query->have_posts() ? $query->posts : array();
104
+ }
105
+
106
+ /**
107
+ * Get option label.
108
  *
109
+ * @param array $field Field parameters.
110
+ * @param string $value Option value.
 
 
111
  *
112
  * @return string
113
  */
114
+ public static function get_option_label( $field, $value ) {
115
+ return sprintf(
116
  '<a href="%s" title="%s">%s</a>',
117
  esc_url( get_permalink( $value ) ),
118
  the_title_attribute( array(
inc/fields/select-tree.php CHANGED
@@ -10,16 +10,18 @@
10
  */
11
  class RWMB_Select_Tree_Field extends RWMB_Select_Field {
12
  /**
13
- * Get field HTML.
 
 
 
 
 
14
  *
15
- * @param mixed $meta Meta value.
16
- * @param array $field Field parameters.
17
  * @return string
18
  */
19
- public static function html( $meta, $field ) {
20
- $options = self::transform_options( $field['options'] );
21
- $walker = new RWMB_Walker_Select_Tree( $field, $meta );
22
- return $options ? $walker->walk( $options ) : '';
23
  }
24
 
25
  /**
10
  */
11
  class RWMB_Select_Tree_Field extends RWMB_Select_Field {
12
  /**
13
+ * Walk options.
14
+ *
15
+ * @param array $field Field parameters.
16
+ * @param mixed $options Select options.
17
+ * @param mixed $db_fields Database fields to use in the output.
18
+ * @param mixed $meta Meta value.
19
  *
 
 
20
  * @return string
21
  */
22
+ public static function walk( $field, $options, $db_fields, $meta ) {
23
+ $walker = new RWMB_Walker_Select_Tree( $db_fields, $field, $meta );
24
+ return $walker->walk( $options );
 
25
  }
26
 
27
  /**
inc/fields/select.php CHANGED
@@ -18,25 +18,27 @@ class RWMB_Select_Field extends RWMB_Choice_Field {
18
  }
19
 
20
  /**
21
- * Get field HTML.
 
 
 
 
 
22
  *
23
- * @param mixed $meta Meta value.
24
- * @param array $field Field parameters.
25
  * @return string
26
  */
27
- public static function html( $meta, $field ) {
28
- $options = self::transform_options( $field['options'] );
29
  $attributes = self::call( 'get_attributes', $field, $meta );
30
  $attributes['data-selected'] = $meta;
31
- $walker = new RWMB_Walker_Select( $field, $meta );
32
  $output = sprintf(
33
  '<select %s>',
34
  self::render_attributes( $attributes )
35
  );
36
- if ( ! $field['multiple'] && $field['placeholder'] ) {
37
- $output .= '<option value="">' . esc_html( $field['placeholder'] ) . '</option>';
38
  }
39
- $output .= $walker->walk( $options, $field['flatten'] ? -1 : 0 );
40
  $output .= '</select>';
41
  $output .= self::get_select_all_html( $field );
42
  return $output;
18
  }
19
 
20
  /**
21
+ * Walk options.
22
+ *
23
+ * @param array $field Field parameters.
24
+ * @param mixed $options Select options.
25
+ * @param mixed $db_fields Database fields to use in the output.
26
+ * @param mixed $meta Meta value.
27
  *
 
 
28
  * @return string
29
  */
30
+ public static function walk( $field, $options, $db_fields, $meta ) {
 
31
  $attributes = self::call( 'get_attributes', $field, $meta );
32
  $attributes['data-selected'] = $meta;
33
+ $walker = new RWMB_Walker_Select( $db_fields, $field, $meta );
34
  $output = sprintf(
35
  '<select %s>',
36
  self::render_attributes( $attributes )
37
  );
38
+ if ( false === $field['multiple'] ) {
39
+ $output .= $field['placeholder'] ? '<option value="">' . esc_html( $field['placeholder'] ) . '</option>' : '';
40
  }
41
+ $output .= $walker->walk( $options, $field['flatten'] ? - 1 : 0 );
42
  $output .= '</select>';
43
  $output .= self::get_select_all_html( $field );
44
  return $output;
inc/fields/sidebar.php CHANGED
@@ -17,44 +17,59 @@ class RWMB_Sidebar_Field extends RWMB_Object_Choice_Field {
17
  * @return array
18
  */
19
  public static function normalize( $field ) {
20
- $field = wp_parse_args( $field, array(
21
- 'placeholder' => __( 'Select a sidebar', 'meta-box' ),
22
- ) );
23
-
24
  $field = parent::normalize( $field );
25
 
 
 
 
 
 
 
 
 
 
26
  return $field;
27
  }
28
 
29
  /**
30
- * Get sidebars for field options.
31
  *
32
- * @param array $field Field settings.
33
- * @return array Field options array.
 
34
  */
35
- public static function query( $field ) {
36
  global $wp_registered_sidebars;
37
  $options = array();
38
  foreach ( $wp_registered_sidebars as $sidebar ) {
39
- $options[ $sidebar['id'] ] = array(
40
- 'value' => $sidebar['id'],
41
- 'label' => $sidebar['name'],
42
- );
43
  }
44
  return $options;
45
  }
46
 
47
  /**
48
- * Format a single value for the helper functions. Sub-fields should overwrite this method if necessary.
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  *
50
- * @param array $field Field parameters.
51
- * @param string $value The value.
52
- * @param array $args Additional arguments. Rarely used. See specific fields for details.
53
- * @param int|null $post_id Post ID. null for current post. Optional.
54
  *
55
  * @return string
56
  */
57
- public static function format_single_value( $field, $value, $args, $post_id ) {
58
  if ( ! is_active_sidebar( $value ) ) {
59
  return '';
60
  }
17
  * @return array
18
  */
19
  public static function normalize( $field ) {
20
+ // Set default field args.
 
 
 
21
  $field = parent::normalize( $field );
22
 
23
+ // Prevent select tree for user since it's not hierarchical.
24
+ $field['field_type'] = 'select_tree' === $field['field_type'] ? 'select' : $field['field_type'];
25
+
26
+ // Set to always flat.
27
+ $field['flatten'] = true;
28
+
29
+ // Set default placeholder.
30
+ $field['placeholder'] = empty( $field['placeholder'] ) ? __( 'Select a sidebar', 'meta-box' ) : $field['placeholder'];
31
+
32
  return $field;
33
  }
34
 
35
  /**
36
+ * Get users.
37
  *
38
+ * @param array $field Field parameters.
39
+ *
40
+ * @return array
41
  */
42
+ public static function get_options( $field ) {
43
  global $wp_registered_sidebars;
44
  $options = array();
45
  foreach ( $wp_registered_sidebars as $sidebar ) {
46
+ $options[] = (object) $sidebar;
 
 
 
47
  }
48
  return $options;
49
  }
50
 
51
  /**
52
+ * Get field names of object to be used by walker.
53
+ *
54
+ * @return array
55
+ */
56
+ public static function get_db_fields() {
57
+ return array(
58
+ 'parent' => 'parent',
59
+ 'id' => 'id',
60
+ 'label' => 'name',
61
+ );
62
+ }
63
+
64
+ /**
65
+ * Get option label.
66
  *
67
+ * @param array $field Field parameters.
68
+ * @param string $value Option value.
 
 
69
  *
70
  * @return string
71
  */
72
+ public static function get_option_label( $field, $value ) {
73
  if ( ! is_active_sidebar( $value ) ) {
74
  return '';
75
  }
inc/fields/slider.php CHANGED
@@ -17,7 +17,7 @@ class RWMB_Slider_Field extends RWMB_Field {
17
  wp_enqueue_style( 'jquery-ui-core', "{$url}/jquery.ui.core.css", array(), '1.8.17' );
18
  wp_enqueue_style( 'jquery-ui-theme', "{$url}/jquery.ui.theme.css", array(), '1.8.17' );
19
  wp_enqueue_style( 'jquery-ui-slider', "{$url}/jquery.ui.slider.css", array(), '1.8.17' );
20
- wp_enqueue_style( 'rwmb-slider', RWMB_CSS_URL . 'slider.css', array(), RWMB_VER );
21
 
22
  wp_enqueue_script( 'rwmb-slider', RWMB_JS_URL . 'slider.js', array( 'jquery-ui-slider', 'jquery-ui-widget', 'jquery-ui-mouse', 'jquery-ui-core' ), RWMB_VER, true );
23
  }
17
  wp_enqueue_style( 'jquery-ui-core', "{$url}/jquery.ui.core.css", array(), '1.8.17' );
18
  wp_enqueue_style( 'jquery-ui-theme', "{$url}/jquery.ui.theme.css", array(), '1.8.17' );
19
  wp_enqueue_style( 'jquery-ui-slider', "{$url}/jquery.ui.slider.css", array(), '1.8.17' );
20
+ wp_enqueue_style( 'rwmb-slider', RWMB_CSS_URL . 'slider.css' );
21
 
22
  wp_enqueue_script( 'rwmb-slider', RWMB_JS_URL . 'slider.js', array( 'jquery-ui-slider', 'jquery-ui-widget', 'jquery-ui-mouse', 'jquery-ui-core' ), RWMB_VER, true );
23
  }
inc/fields/taxonomy-advanced.php CHANGED
@@ -52,9 +52,6 @@ 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 ( empty( $field['id'] ) || ! $field['save_field'] ) {
56
- return;
57
- }
58
  $storage = $field['storage'];
59
 
60
  if ( $new ) {
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 ) {
inc/fields/taxonomy.php CHANGED
@@ -29,8 +29,7 @@ class RWMB_Taxonomy_Field extends RWMB_Object_Choice_Field {
29
 
30
  // Set default field args.
31
  $field = wp_parse_args( $field, array(
32
- 'taxonomy' => 'category',
33
- 'query_args' => array(),
34
  ) );
35
 
36
  // Force taxonomy to be an array.
@@ -53,6 +52,7 @@ class RWMB_Taxonomy_Field extends RWMB_Object_Choice_Field {
53
  $field = wp_parse_args( $field, array(
54
  'placeholder' => $placeholder,
55
  ) );
 
56
 
57
  // Set default query args.
58
  $field['query_args'] = wp_parse_args( $field['query_args'], array(
@@ -62,36 +62,31 @@ class RWMB_Taxonomy_Field extends RWMB_Object_Choice_Field {
62
  // Prevent cloning for taxonomy field.
63
  $field['clone'] = false;
64
 
65
- $field = parent::normalize( $field );
66
-
67
  return $field;
68
  }
69
 
70
  /**
71
- * Query terms for field options.
72
  *
73
- * @param array $field Field settings.
74
- * @return array Field options array.
75
  */
76
- public static function query( $field ) {
77
- $args = wp_parse_args( $field['query_args'], array(
78
- 'taxonomy' => $field['taxonomy'],
79
- 'hide_empty' => false,
80
- 'count' => false,
81
- 'update_term_meta_cache' => false,
82
- ) );
83
- $terms = get_terms( $args );
84
- if ( ! is_array( $terms ) ) {
85
- return array();
86
- }
87
- $options = array();
88
- foreach ( $terms as $term ) {
89
- $options[ $term->term_id ] = array(
90
- 'value' => $term->term_id,
91
- 'label' => $term->name,
92
- 'parent' => $term->parent,
93
- );
94
- }
95
  return $options;
96
  }
97
 
@@ -104,9 +99,6 @@ class RWMB_Taxonomy_Field extends RWMB_Object_Choice_Field {
104
  * @param array $field The field parameters.
105
  */
106
  public static function save( $new, $old, $post_id, $field ) {
107
- if ( empty( $field['id'] ) || ! $field['save_field'] ) {
108
- return;
109
- }
110
  $new = array_unique( array_map( 'intval', (array) $new ) );
111
  $new = empty( $new ) ? null : $new;
112
 
@@ -132,9 +124,6 @@ class RWMB_Taxonomy_Field extends RWMB_Object_Choice_Field {
132
  $meta = wp_get_object_terms( $object_id, $field['taxonomy'], array(
133
  'orderby' => 'term_order',
134
  ) );
135
- if ( is_wp_error( $meta ) ) {
136
- return '';
137
- }
138
  $meta = wp_list_pluck( $meta, 'term_id' );
139
 
140
  return $field['multiple'] ? $meta : reset( $meta );
@@ -166,22 +155,20 @@ class RWMB_Taxonomy_Field extends RWMB_Object_Choice_Field {
166
  }
167
 
168
  /**
169
- * Format a single value for the helper functions. Sub-fields should overwrite this method if necessary.
170
  *
171
- * @param array $field Field parameters.
172
- * @param string $value The value.
173
- * @param array $args Additional arguments. Rarely used. See specific fields for details.
174
- * @param int|null $post_id Post ID. null for current post. Optional.
175
  *
176
  * @return string
177
  */
178
- public static function format_single_value( $field, $value, $args, $post_id ) {
179
  return sprintf(
180
  '<a href="%s" title="%s">%s</a>',
181
  // @codingStandardsIgnoreLine
182
  esc_url( get_term_link( $value ) ),
183
  esc_attr( $value->name ),
184
- esc_html( $value->name )
185
  );
186
  }
187
  }
29
 
30
  // Set default field args.
31
  $field = wp_parse_args( $field, array(
32
+ 'taxonomy' => 'category',
 
33
  ) );
34
 
35
  // Force taxonomy to be an array.
52
  $field = wp_parse_args( $field, array(
53
  'placeholder' => $placeholder,
54
  ) );
55
+ $field = parent::normalize( $field );
56
 
57
  // Set default query args.
58
  $field['query_args'] = wp_parse_args( $field['query_args'], array(
62
  // Prevent cloning for taxonomy field.
63
  $field['clone'] = false;
64
 
 
 
65
  return $field;
66
  }
67
 
68
  /**
69
+ * Get field names of object to be used by walker.
70
  *
71
+ * @return array
 
72
  */
73
+ public static function get_db_fields() {
74
+ return array(
75
+ 'parent' => 'parent',
76
+ 'id' => 'term_id',
77
+ 'label' => 'name',
78
+ );
79
+ }
80
+
81
+ /**
82
+ * Get options for selects, checkbox list, etc via the terms.
83
+ *
84
+ * @param array $field Field parameters.
85
+ *
86
+ * @return array
87
+ */
88
+ public static function get_options( $field ) {
89
+ $options = get_terms( $field['taxonomy'], $field['query_args'] );
 
 
90
  return $options;
91
  }
92
 
99
  * @param array $field The field parameters.
100
  */
101
  public static function save( $new, $old, $post_id, $field ) {
 
 
 
102
  $new = array_unique( array_map( 'intval', (array) $new ) );
103
  $new = empty( $new ) ? null : $new;
104
 
124
  $meta = wp_get_object_terms( $object_id, $field['taxonomy'], array(
125
  'orderby' => 'term_order',
126
  ) );
 
 
 
127
  $meta = wp_list_pluck( $meta, 'term_id' );
128
 
129
  return $field['multiple'] ? $meta : reset( $meta );
155
  }
156
 
157
  /**
158
+ * Get option label.
159
  *
160
+ * @param array $field Field parameters.
161
+ * @param object $value The term object.
 
 
162
  *
163
  * @return string
164
  */
165
+ public static function get_option_label( $field, $value ) {
166
  return sprintf(
167
  '<a href="%s" title="%s">%s</a>',
168
  // @codingStandardsIgnoreLine
169
  esc_url( get_term_link( $value ) ),
170
  esc_attr( $value->name ),
171
+ $value->name
172
  );
173
  }
174
  }
inc/fields/text-list.php CHANGED
@@ -117,9 +117,6 @@ class RWMB_Text_List_Field extends RWMB_Multiple_Values_Field {
117
  * @param array $field The field parameters.
118
  */
119
  public static function save( $new, $old, $post_id, $field ) {
120
- if ( empty( $field['id'] ) || ! $field['save_field'] ) {
121
- return;
122
- }
123
  $storage = $field['storage'];
124
  $storage->delete( $post_id, $field['id'] );
125
  parent::save( $new, array(), $post_id, $field );
117
  * @param array $field The field parameters.
118
  */
119
  public static function save( $new, $old, $post_id, $field ) {
 
 
 
120
  $storage = $field['storage'];
121
  $storage->delete( $post_id, $field['id'] );
122
  parent::save( $new, array(), $post_id, $field );
inc/fields/user.php CHANGED
@@ -19,53 +19,62 @@ class RWMB_User_Field extends RWMB_Object_Choice_Field {
19
  public static function normalize( $field ) {
20
  // Set default field args.
21
  $field = wp_parse_args( $field, array(
22
- 'placeholder' => __( 'Select an user', 'meta-box' ),
23
- 'query_args' => array(),
24
- 'display_field' => 'display_name',
25
  ) );
26
-
27
  $field = parent::normalize( $field );
28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  return $field;
30
  }
31
 
32
  /**
33
- * Query users for field options.
 
 
34
  *
35
- * @param array $field Field settings.
36
- * @return array Field options array.
37
  */
38
- public static function query( $field ) {
39
- $display_field = $field['display_field'];
40
- $args = wp_parse_args( $field['query_args'], array(
41
- 'orderby' => $display_field,
42
- 'order' => 'asc',
43
- 'fields' => array( 'ID', $display_field ),
44
- ) );
45
- $users = get_users( $args );
46
- $options = array();
47
- foreach ( $users as $user ) {
48
- $options[ $user->ID ] = array(
49
- 'value' => $user->ID,
50
- 'label' => $user->$display_field,
51
- );
52
- }
53
- return $options;
54
  }
55
 
56
  /**
57
- * Format a single value for the helper functions. Sub-fields should overwrite this method if necessary.
58
  *
59
- * @param array $field Field parameters.
60
- * @param string $value The value.
61
- * @param array $args Additional arguments. Rarely used. See specific fields for details.
62
- * @param int|null $post_id Post ID. null for current post. Optional.
63
  *
64
  * @return string
65
  */
66
- public static function format_single_value( $field, $value, $args, $post_id ) {
67
- $display_field = $field['display_field'];
68
- $user = get_userdata( $value );
69
- return '<a href="' . esc_url( get_author_posts_url( $value ) ) . '">' . esc_html( $user->$display_field ) . '</a>';
70
  }
71
  }
19
  public static function normalize( $field ) {
20
  // Set default field args.
21
  $field = wp_parse_args( $field, array(
22
+ 'placeholder' => __( 'Select an user', 'meta-box' ),
 
 
23
  ) );
 
24
  $field = parent::normalize( $field );
25
 
26
+ // Prevent select tree for user since it's not hierarchical.
27
+ $field['field_type'] = 'select_tree' === $field['field_type'] ? 'select' : $field['field_type'];
28
+
29
+ // Set to always flat.
30
+ $field['flatten'] = true;
31
+
32
+ // Set default query args.
33
+ $field['query_args'] = wp_parse_args( $field['query_args'], array(
34
+ 'orderby' => 'display_name',
35
+ 'order' => 'asc',
36
+ 'role' => '',
37
+ 'fields' => 'all',
38
+ ) );
39
+
40
  return $field;
41
  }
42
 
43
  /**
44
+ * Get users.
45
+ *
46
+ * @param array $field Field parameters.
47
  *
48
+ * @return array
 
49
  */
50
+ public static function get_options( $field ) {
51
+ $query = new WP_User_Query( $field['query_args'] );
52
+ return $query->get_results();
53
+ }
54
+
55
+ /**
56
+ * Get field names of object to be used by walker.
57
+ *
58
+ * @return array
59
+ */
60
+ public static function get_db_fields() {
61
+ return array(
62
+ 'parent' => 'parent',
63
+ 'id' => 'ID',
64
+ 'label' => 'display_name',
65
+ );
66
  }
67
 
68
  /**
69
+ * Get option label.
70
  *
71
+ * @param array $field Field parameters.
72
+ * @param string $value Option value.
 
 
73
  *
74
  * @return string
75
  */
76
+ public static function get_option_label( $field, $value ) {
77
+ $user = get_userdata( $value );
78
+ return '<a href="' . get_author_posts_url( $value ) . '">' . $user->display_name . '</a>';
 
79
  }
80
  }
inc/functions.php CHANGED
@@ -26,7 +26,7 @@ if ( ! function_exists( 'rwmb_meta' ) ) {
26
  if ( false === $field ) {
27
  return apply_filters( 'rwmb_meta', rwmb_meta_legacy( $key, $args, $post_id ) );
28
  }
29
- $meta = in_array( $field['type'], array( 'oembed', 'map', 'osm' ), true ) ?
30
  rwmb_the_value( $key, $args, $post_id, false ) :
31
  rwmb_get_value( $key, $args, $post_id );
32
  return apply_filters( 'rwmb_meta', $meta, $key, $args, $post_id );
@@ -47,6 +47,7 @@ if ( ! function_exists( 'rwmb_get_field_settings' ) ) {
47
  $args = wp_parse_args( $args, array(
48
  'object_type' => 'post',
49
  ) );
 
50
 
51
  /**
52
  * Filter meta type from object type and object id.
@@ -55,10 +56,7 @@ if ( ! function_exists( 'rwmb_get_field_settings' ) ) {
55
  * @var string Object type.
56
  * @var string|int Object id.
57
  */
58
- $type = apply_filters( 'rwmb_meta_type', '', $args['object_type'], $object_id );
59
- if ( ! $type ) {
60
- $type = get_post_type( $object_id );
61
- }
62
 
63
  return rwmb_get_registry( 'field' )->get( $key, $type, $args['object_type'] );
64
  }
@@ -94,7 +92,6 @@ if ( ! function_exists( 'rwmb_meta_legacy' ) ) {
94
  $field['taxonomy'] = $args['taxonomy'];
95
  break;
96
  case 'map':
97
- case 'osm':
98
  case 'oembed':
99
  $method = 'the_value';
100
  break;
@@ -283,36 +280,3 @@ if ( ! function_exists( 'rwmb_get_meta_box' ) ) {
283
  return new $class_name( $meta_box );
284
  }
285
  }
286
-
287
- /**
288
- * Helper functions
289
- */
290
-
291
- if ( ! function_exists( 'rwmb_change_array_key' ) ) {
292
- /**
293
- * Change array key.
294
- *
295
- * @param array $array Input array.
296
- * @param string $from From key.
297
- * @param string $to To key.
298
- */
299
- function rwmb_change_array_key( &$array, $from, $to ) {
300
- if ( isset( $array[ $from ] ) ) {
301
- $array[ $to ] = $array[ $from ];
302
- }
303
- unset( $array[ $from ] );
304
- }
305
- }
306
-
307
- if ( ! function_exists( 'rwmb_csv_to_array' ) ) {
308
- /**
309
- * Convert a comma separated string to array.
310
- *
311
- * @param string $string Comma separated string.
312
- *
313
- * @return array
314
- */
315
- function rwmb_csv_to_array( $string ) {
316
- return is_array( $string ) ? $string : array_filter( array_map( 'trim', explode( ',', $string . ',' ) ) );
317
- }
318
- }
26
  if ( false === $field ) {
27
  return apply_filters( 'rwmb_meta', rwmb_meta_legacy( $key, $args, $post_id ) );
28
  }
29
+ $meta = in_array( $field['type'], array( 'oembed', 'map' ), true ) ?
30
  rwmb_the_value( $key, $args, $post_id, false ) :
31
  rwmb_get_value( $key, $args, $post_id );
32
  return apply_filters( 'rwmb_meta', $meta, $key, $args, $post_id );
47
  $args = wp_parse_args( $args, array(
48
  'object_type' => 'post',
49
  ) );
50
+ $type = get_post_type( $object_id );
51
 
52
  /**
53
  * Filter meta type from object type and object id.
56
  * @var string Object type.
57
  * @var string|int Object id.
58
  */
59
+ $type = apply_filters( 'rwmb_meta_type', $type, $args['object_type'], $object_id );
 
 
 
60
 
61
  return rwmb_get_registry( 'field' )->get( $key, $type, $args['object_type'] );
62
  }
92
  $field['taxonomy'] = $args['taxonomy'];
93
  break;
94
  case 'map':
 
95
  case 'oembed':
96
  $method = 'the_value';
97
  break;
280
  return new $class_name( $meta_box );
281
  }
282
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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.15.5' );
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.14.10' );
22
 
23
  list( $path, $url ) = self::get_path( dirname( dirname( __FILE__ ) ) );
24
 
inc/meta-box.php CHANGED
@@ -88,7 +88,7 @@ class RW_Meta_Box {
88
  *
89
  * @return bool
90
  */
91
- public function is_shown() {
92
  $show = apply_filters( 'rwmb_show', true, $this->meta_box );
93
 
94
  return apply_filters( "rwmb_show_{$this->id}", $show, $this->meta_box );
@@ -144,6 +144,10 @@ class RW_Meta_Box {
144
  wp_enqueue_style( 'rwmb-rtl', RWMB_CSS_URL . 'style-rtl.css', array(), RWMB_VER );
145
  }
146
 
 
 
 
 
147
  // Load clone script conditionally.
148
  foreach ( $this->fields as $field ) {
149
  if ( $field['clone'] ) {
@@ -174,9 +178,6 @@ class RW_Meta_Box {
174
  * Add meta box for multiple post types
175
  */
176
  public function add_meta_boxes() {
177
- $screen = get_current_screen();
178
- add_filter( "postbox_classes_{$screen->id}_{$this->id}", array( $this, 'postbox_classes' ) );
179
-
180
  foreach ( $this->post_types as $post_type ) {
181
  add_meta_box(
182
  $this->id,
@@ -189,23 +190,6 @@ class RW_Meta_Box {
189
  }
190
  }
191
 
192
- /**
193
- * Modify meta box postbox classes.
194
- *
195
- * @param array $classes Array of classes.
196
- * @return array
197
- */
198
- public function postbox_classes( $classes ) {
199
- if ( $this->closed && ! in_array( 'closed', $classes ) ) {
200
- $classes[] = 'closed';
201
- }
202
- if ( 'seamless' === $this->style ) {
203
- $classes[] = 'rwmb-seamless';
204
- }
205
-
206
- return $classes;
207
- }
208
-
209
  /**
210
  * Hide meta box if it's set 'default_hidden'
211
  *
@@ -233,7 +217,8 @@ class RW_Meta_Box {
233
 
234
  // Container.
235
  printf(
236
- '<div class="rwmb-meta-box" data-autosave="%s" data-object-type="%s">',
 
237
  esc_attr( $this->autosave ? 'true' : 'false' ),
238
  esc_attr( $this->object_type )
239
  );
@@ -362,10 +347,12 @@ class RW_Meta_Box {
362
  *
363
  * @since 4.4.1
364
  */
365
- rwmb_change_array_key( $meta_box, 'pages', 'post_types' );
 
 
366
 
367
  // Make sure the post type is an array and is sanitized.
368
- $meta_box['post_types'] = array_map( 'sanitize_key', rwmb_csv_to_array( $meta_box['post_types'] ) );
369
 
370
  return $meta_box;
371
  }
@@ -415,7 +402,7 @@ class RW_Meta_Box {
415
  }
416
  if (
417
  ( ! $field['multiple'] && '' !== $value )
418
- || ( $field['multiple'] && is_array( $value ) && array() !== $value )
419
  ) {
420
  return true;
421
  }
88
  *
89
  * @return bool
90
  */
91
+ protected function is_shown() {
92
  $show = apply_filters( 'rwmb_show', true, $this->meta_box );
93
 
94
  return apply_filters( "rwmb_show_{$this->id}", $show, $this->meta_box );
144
  wp_enqueue_style( 'rwmb-rtl', RWMB_CSS_URL . 'style-rtl.css', array(), RWMB_VER );
145
  }
146
 
147
+ if ( 'seamless' === $this->style ) {
148
+ wp_enqueue_script( 'rwmb', RWMB_JS_URL . 'script.js', array( 'jquery' ), RWMB_VER, true );
149
+ }
150
+
151
  // Load clone script conditionally.
152
  foreach ( $this->fields as $field ) {
153
  if ( $field['clone'] ) {
178
  * Add meta box for multiple post types
179
  */
180
  public function add_meta_boxes() {
 
 
 
181
  foreach ( $this->post_types as $post_type ) {
182
  add_meta_box(
183
  $this->id,
190
  }
191
  }
192
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
193
  /**
194
  * Hide meta box if it's set 'default_hidden'
195
  *
217
 
218
  // Container.
219
  printf(
220
+ '<div class="rwmb-meta-box%s" data-autosave="%s" data-object-type="%s">',
221
+ esc_attr( 'seamless' === $this->style ? ' rwmb-meta-box--seamless' : '' ),
222
  esc_attr( $this->autosave ? 'true' : 'false' ),
223
  esc_attr( $this->object_type )
224
  );
347
  *
348
  * @since 4.4.1
349
  */
350
+ if ( ! empty( $meta_box['pages'] ) ) {
351
+ $meta_box['post_types'] = $meta_box['pages'];
352
+ }
353
 
354
  // Make sure the post type is an array and is sanitized.
355
+ $meta_box['post_types'] = array_map( 'sanitize_key', (array) $meta_box['post_types'] );
356
 
357
  return $meta_box;
358
  }
402
  }
403
  if (
404
  ( ! $field['multiple'] && '' !== $value )
405
+ || ( $field['multiple'] && array() !== $value )
406
  ) {
407
  return true;
408
  }
inc/sanitizer.php CHANGED
@@ -32,10 +32,9 @@ class RWMB_Sanitizer {
32
  }
33
 
34
  // Custom callback.
35
- $methods = array_diff( get_class_methods( __CLASS__ ), array( 'init' ) );
36
- foreach ( $methods as $method ) {
37
- $type = substr( $method, 9 );
38
- add_filter( "rwmb_{$type}_sanitize", array( $this, $method ) );
39
  }
40
  }
41
 
@@ -47,18 +46,7 @@ class RWMB_Sanitizer {
47
  * @param string $value Checkbox value.
48
  * @return int
49
  */
50
- public function sanitize_checkbox( $value ) {
51
- return (int) ! empty( $value );
52
- }
53
-
54
- /**
55
- * Set the value of switch to 1 or 0 instead of 'checked' and empty string.
56
- * This prevents using default value once the switch has been unchecked.
57
- *
58
- * @param string $value Switch value.
59
- * @return int
60
- */
61
- public function sanitize_switch( $value ) {
62
  return (int) ! empty( $value );
63
  }
64
  }
32
  }
33
 
34
  // Custom callback.
35
+ $types = array_diff( get_class_methods( __CLASS__ ), array( 'init' ) );
36
+ foreach ( $types as $type ) {
37
+ add_filter( "rwmb_{$type}_sanitize", array( $this, $type ) );
 
38
  }
39
  }
40
 
46
  * @param string $value Checkbox value.
47
  * @return int
48
  */
49
+ public function checkbox( $value ) {
 
 
 
 
 
 
 
 
 
 
 
50
  return (int) ! empty( $value );
51
  }
52
  }
inc/walkers/base.php CHANGED
@@ -11,32 +11,35 @@
11
  */
12
  abstract class RWMB_Walker_Base extends Walker {
13
  /**
14
- * Field settings.
15
  *
 
16
  * @var array
17
  */
18
  public $field;
19
 
20
  /**
21
- * Field meta data.
22
  *
 
23
  * @var array
24
  */
25
- public $meta;
26
 
27
  /**
28
  * Constructor.
29
  *
30
- * @param array $field Field parameters.
31
- * @param mixed $meta Meta value.
 
32
  */
33
- public function __construct( $field, $meta ) {
34
- $this->db_fields = array(
35
- 'id' => 'value',
36
- 'parent' => 'parent',
37
- );
38
-
39
- $this->field = $field;
40
- $this->meta = (array) $meta;
41
  }
42
  }
11
  */
12
  abstract class RWMB_Walker_Base extends Walker {
13
  /**
14
+ * Field data.
15
  *
16
+ * @access public
17
  * @var array
18
  */
19
  public $field;
20
 
21
  /**
22
+ * Meta data.
23
  *
24
+ * @access public
25
  * @var array
26
  */
27
+ public $meta = array();
28
 
29
  /**
30
  * Constructor.
31
  *
32
+ * @param array $db_fields Database fields.
33
+ * @param array $field Field parameters.
34
+ * @param mixed $meta Meta value.
35
  */
36
+ public function __construct( $db_fields, $field, $meta ) {
37
+ $this->db_fields = wp_parse_args( (array) $db_fields, array(
38
+ 'parent' => '',
39
+ 'id' => '',
40
+ 'label' => '',
41
+ ) );
42
+ $this->field = $field;
43
+ $this->meta = (array) $meta;
44
  }
45
  }
inc/walkers/input-list.php CHANGED
@@ -41,13 +41,15 @@ class RWMB_Walker_Input_List extends RWMB_Walker_Base {
41
  * @param int $current_object_id ID of the current item.
42
  */
43
  public function start_el( &$output, $object, $depth = 0, $args = array(), $current_object_id = 0 ) {
44
- $attributes = RWMB_Field::call( 'get_attributes', $this->field, $object->value );
 
 
45
 
46
  $output .= sprintf(
47
  '<li><label><input %s %s>%s</label>',
48
  RWMB_Field::render_attributes( $attributes ),
49
- checked( in_array( $object->value, $this->meta ), true, false ),
50
- $object->label
51
  );
52
  }
53
 
41
  * @param int $current_object_id ID of the current item.
42
  */
43
  public function start_el( &$output, $object, $depth = 0, $args = array(), $current_object_id = 0 ) {
44
+ $label = $this->db_fields['label'];
45
+ $id = $this->db_fields['id'];
46
+ $attributes = RWMB_Field::call( 'get_attributes', $this->field, $object->$id );
47
 
48
  $output .= sprintf(
49
  '<li><label><input %s %s>%s</label>',
50
  RWMB_Field::render_attributes( $attributes ),
51
+ checked( in_array( $object->$id, $this->meta ), 1, false ),
52
+ RWMB_Field::filter( 'choice_label', $object->$label, $this->field, $object )
53
  );
54
  }
55
 
inc/walkers/select-tree.php CHANGED
@@ -10,7 +10,7 @@
10
  */
11
  class RWMB_Walker_Select_Tree {
12
  /**
13
- * Field settings.
14
  *
15
  * @var string
16
  */
@@ -21,17 +21,23 @@ class RWMB_Walker_Select_Tree {
21
  *
22
  * @var array
23
  */
24
- public $meta;
25
 
26
  /**
27
  * Constructor.
28
  *
29
- * @param array $field Field parameters.
30
- * @param mixed $meta Meta value.
 
31
  */
32
- public function __construct( $field, $meta ) {
33
- $this->field = $field;
34
- $this->meta = (array) $meta;
 
 
 
 
 
35
  }
36
 
37
  /**
@@ -42,14 +48,15 @@ class RWMB_Walker_Select_Tree {
42
  * @return string
43
  */
44
  public function walk( $options ) {
 
45
  $children = array();
46
 
47
  foreach ( $options as $option ) {
48
- $parent = isset( $option->parent ) ? $option->parent : 0;
49
- $children[ $parent ][] = $option;
50
  }
51
 
52
- $top_level = isset( $children[0] ) ? 0 : $options[0]->parent;
53
  return $this->display_level( $children, $top_level, true );
54
  }
55
 
@@ -63,24 +70,25 @@ class RWMB_Walker_Select_Tree {
63
  * @return string
64
  */
65
  public function display_level( $options, $parent_id = 0, $active = false ) {
 
66
  $field = $this->field;
67
- $walker = new RWMB_Walker_Select( $field, $this->meta );
68
  $attributes = RWMB_Field::call( 'get_attributes', $field, $this->meta );
69
 
70
  $children = $options[ $parent_id ];
71
  $output = sprintf(
72
  '<div class="rwmb-select-tree %s" data-parent-id="%s"><select %s>',
73
  $active ? '' : 'hidden',
74
- esc_attr( $parent_id ),
75
  RWMB_Field::render_attributes( $attributes )
76
  );
77
- $output .= $field['placeholder'] ? "<option value=''>{$field['placeholder']}</option>" : '<option></option>';
78
  $output .= $walker->walk( $children, - 1 );
79
  $output .= '</select>';
80
 
81
- foreach ( $children as $child ) {
82
- if ( isset( $options[ $child->value ] ) ) {
83
- $output .= $this->display_level( $options, $child->value, in_array( $child->value, $this->meta ) && $active );
84
  }
85
  }
86
 
10
  */
11
  class RWMB_Walker_Select_Tree {
12
  /**
13
+ * Field data.
14
  *
15
  * @var string
16
  */
21
  *
22
  * @var array
23
  */
24
+ public $meta = array();
25
 
26
  /**
27
  * Constructor.
28
  *
29
+ * @param array $db_fields Database fields.
30
+ * @param array $field Field parameters.
31
+ * @param mixed $meta Meta value.
32
  */
33
+ public function __construct( $db_fields, $field, $meta ) {
34
+ $this->db_fields = wp_parse_args( (array) $db_fields, array(
35
+ 'parent' => '',
36
+ 'id' => '',
37
+ 'label' => '',
38
+ ) );
39
+ $this->field = $field;
40
+ $this->meta = (array) $meta;
41
  }
42
 
43
  /**
48
  * @return string
49
  */
50
  public function walk( $options ) {
51
+ $parent = $this->db_fields['parent'];
52
  $children = array();
53
 
54
  foreach ( $options as $option ) {
55
+ $index = isset( $option->$parent ) ? $option->$parent : 0;
56
+ $children[ $index ][] = $option;
57
  }
58
 
59
+ $top_level = isset( $children[0] ) ? 0 : $options[0]->$parent;
60
  return $this->display_level( $children, $top_level, true );
61
  }
62
 
70
  * @return string
71
  */
72
  public function display_level( $options, $parent_id = 0, $active = false ) {
73
+ $id = $this->db_fields['id'];
74
  $field = $this->field;
75
+ $walker = new RWMB_Walker_Select( $this->db_fields, $field, $this->meta );
76
  $attributes = RWMB_Field::call( 'get_attributes', $field, $this->meta );
77
 
78
  $children = $options[ $parent_id ];
79
  $output = sprintf(
80
  '<div class="rwmb-select-tree %s" data-parent-id="%s"><select %s>',
81
  $active ? '' : 'hidden',
82
+ $parent_id,
83
  RWMB_Field::render_attributes( $attributes )
84
  );
85
+ $output .= isset( $field['placeholder'] ) ? "<option value=''>{$field['placeholder']}</option>" : '<option></option>';
86
  $output .= $walker->walk( $children, - 1 );
87
  $output .= '</select>';
88
 
89
+ foreach ( $children as $c ) {
90
+ if ( isset( $options[ $c->$id ] ) ) {
91
+ $output .= $this->display_level( $options, $c->$id, in_array( $c->$id, $this->meta ) && $active );
92
  }
93
  }
94
 
inc/walkers/select.php CHANGED
@@ -21,15 +21,17 @@ class RWMB_Walker_Select extends RWMB_Walker_Base {
21
  * @param int $current_object_id ID of the current item.
22
  */
23
  public function start_el( &$output, $object, $depth = 0, $args = array(), $current_object_id = 0 ) {
 
 
24
  $meta = $this->meta;
25
  $indent = str_repeat( '&nbsp;', $depth * 4 );
26
 
27
  $output .= sprintf(
28
  '<option value="%s" %s>%s%s</option>',
29
- esc_attr( $object->value ),
30
- selected( in_array( $object->value, $meta ), true, false ),
31
  $indent,
32
- esc_html( $object->label )
33
  );
34
  }
35
  }
21
  * @param int $current_object_id ID of the current item.
22
  */
23
  public function start_el( &$output, $object, $depth = 0, $args = array(), $current_object_id = 0 ) {
24
+ $label = $this->db_fields['label'];
25
+ $id = $this->db_fields['id'];
26
  $meta = $this->meta;
27
  $indent = str_repeat( '&nbsp;', $depth * 4 );
28
 
29
  $output .= sprintf(
30
  '<option value="%s" %s>%s%s</option>',
31
+ esc_attr( $object->$id ),
32
+ selected( in_array( $object->$id, $meta ), true, false ),
33
  $indent,
34
+ esc_html( RWMB_Field::filter( 'choice_label', $object->$label, $this->field, $object ) )
35
  );
36
  }
37
  }
js/autosave.js CHANGED
@@ -2,7 +2,7 @@
2
  'use strict';
3
 
4
  $( document ).ajaxSend( function ( event, xhr, settings ) {
5
- if ( ! Array.isArray( settings.data ) || -1 === settings.data.indexOf( 'wp_autosave' ) ) {
6
  return;
7
  }
8
  var inputSelectors = 'input[class*="rwmb"], textarea[class*="rwmb"], select[class*="rwmb"], button[class*="rwmb"], input[name^="nonce_"]';
2
  'use strict';
3
 
4
  $( document ).ajaxSend( function ( event, xhr, settings ) {
5
+ if ( typeof settings.data === 'undefined' || -1 === settings.data.indexOf( 'wp_autosave' ) ) {
6
  return;
7
  }
8
  var inputSelectors = 'input[class*="rwmb"], textarea[class*="rwmb"], select[class*="rwmb"], button[class*="rwmb"], input[name^="nonce_"]';
js/input-list.js CHANGED
@@ -14,16 +14,16 @@ jQuery( function ( $ ) {
14
  }
15
 
16
  $( '.rwmb-input' )
17
- .on( 'change', '.rwmb-input-list.rwmb-collapse input[type="checkbox"]', update )
18
- .on( 'clone', '.rwmb-input-list.rwmb-collapse input[type="checkbox"]', update );
19
- $( '.rwmb-input-list.rwmb-collapse input[type="checkbox"]' ).each( update );
20
 
21
  $( '.rwmb-input-list-select-all-none' ).toggle(
22
  function () {
23
- $( this ).parent().siblings( '.rwmb-input-list' ).find( 'input' ).prop( 'checked', true );
24
  },
25
  function () {
26
- $( this ).parent().siblings( '.rwmb-input-list' ).find( 'input' ).prop( 'checked', false );
27
  }
28
  );
29
  } );
14
  }
15
 
16
  $( '.rwmb-input' )
17
+ .on( 'change', '.rwmb-input-list.collapse :checkbox', update )
18
+ .on( 'clone', '.rwmb-input-list.collapse :checkbox', update );
19
+ $( '.rwmb-input-list.collapse :checkbox' ).each( update );
20
 
21
  $( '.rwmb-input-list-select-all-none' ).toggle(
22
  function () {
23
+ $('input[name="' + $(this).data('name') + '[]"]').prop('checked', true);
24
  },
25
  function () {
26
+ $('input[name="' + $(this).data('name') + '[]"]').prop('checked', false);
27
  }
28
  );
29
  } );
js/map.js CHANGED
@@ -63,7 +63,8 @@
63
 
64
  this.map.setCenter( this.marker.position );
65
  this.map.setZoom( zoom );
66
- } else if ( this.addressField ) {
 
67
  this.geocodeAddress();
68
  }
69
  },
@@ -91,7 +92,7 @@
91
 
92
  /**
93
  * Add a custom event that allows other scripts to refresh the maps when needed
94
- * For example: when maps is in tabs or hidden div.
95
  *
96
  * @see https://developers.google.com/maps/documentation/javascript/reference ('resize' Event)
97
  */
@@ -114,20 +115,28 @@
114
  center = this.map.getCenter();
115
 
116
  if ( this.map ) {
 
117
  this.map.setZoom( zoom );
118
- this.map.panTo( center );
119
  }
120
  },
121
 
122
  // Autocomplete address
123
  autocomplete: function () {
124
- var that = this,
125
- $address = this.getAddressField();
126
 
127
- if ( null === $address ) {
 
128
  return;
129
  }
130
 
 
 
 
 
 
 
 
131
  // If Meta Box Geo Location installed. Do not run auto complete.
132
  if ( $( '.rwmb-geo-binding' ).length ) {
133
  $address.on( 'selected_address', function () {
@@ -144,14 +153,7 @@
144
  'region': that.$canvas.data( 'region' )
145
  };
146
  geocoder.geocode( options, function ( results ) {
147
- if ( ! results.length ) {
148
- response( [ {
149
- value: '',
150
- label: RWMB_Map.no_results_string
151
- } ] );
152
- return;
153
- }
154
- response( results.map( function ( item ) {
155
  return {
156
  label: item.formatted_address,
157
  value: item.formatted_address,
@@ -163,6 +165,7 @@
163
  },
164
  select: function ( event, ui ) {
165
  var latLng = new google.maps.LatLng( ui.item.latitude, ui.item.longitude );
 
166
  that.map.setCenter( latLng );
167
  that.marker.setPosition( latLng );
168
  that.updateCoordinate( latLng );
@@ -178,8 +181,18 @@
178
 
179
  // Find coordinates by address
180
  geocodeAddress: function () {
181
- var address = this.getAddress(),
 
 
 
182
  that = this;
 
 
 
 
 
 
 
183
  if ( ! address ) {
184
  return;
185
  }
@@ -192,50 +205,6 @@
192
  that.marker.setPosition( results[0].geometry.location );
193
  that.updateCoordinate( results[0].geometry.location );
194
  } );
195
- },
196
-
197
- // Get the address field.
198
- getAddressField: function() {
199
- // No address field or more than 1 address fields, ignore
200
- if ( ! this.addressField || this.addressField.split( ',' ).length > 1 ) {
201
- return null;
202
- }
203
- return this.findAddressField( this.addressField );
204
- },
205
-
206
- // Get the address value for geocoding.
207
- getAddress: function() {
208
- var that = this;
209
-
210
- return this.addressField.split( ',' )
211
- .map( function( part ) {
212
- part = that.findAddressField( part );
213
- return null === part ? '' : part.val();
214
- } )
215
- .join( ',' ).replace( /\n/g, ',' ).replace( /,,/g, ',' );
216
- },
217
-
218
- // Find address field based on its name attribute. Auto search inside groups when needed.
219
- findAddressField: function( fieldName ) {
220
- // Not in a group.
221
- var $address = $( 'input[name="' + fieldName + '"]');
222
- if ( $address.length ) {
223
- return $address;
224
- }
225
-
226
- // If map and address is inside a cloneable group.
227
- $address = this.$container.closest( '.rwmb-group-clone' ).find( 'input[name*="[' + fieldName + ']"]' );
228
- if ( $address.length ) {
229
- return $address;
230
- }
231
-
232
- // If map and address is inside a non-cloneable group.
233
- $address = this.$container.closest( '.rwmb-group-wrapper' ).find( 'input[name*="[' + fieldName + ']"]' );
234
- if ( $address.length ) {
235
- return $address;
236
- }
237
-
238
- return null;
239
  }
240
  };
241
 
@@ -247,7 +216,7 @@
247
  return;
248
  }
249
 
250
- controller = new MapField( $this );
251
  controller.init();
252
  $this.data( 'mapController', controller );
253
  } );
63
 
64
  this.map.setCenter( this.marker.position );
65
  this.map.setZoom( zoom );
66
+ }
67
+ else if ( this.addressField ) {
68
  this.geocodeAddress();
69
  }
70
  },
92
 
93
  /**
94
  * Add a custom event that allows other scripts to refresh the maps when needed
95
+ * For example: when maps is in tabs or hidden div (this is known issue of Google Maps)
96
  *
97
  * @see https://developers.google.com/maps/documentation/javascript/reference ('resize' Event)
98
  */
115
  center = this.map.getCenter();
116
 
117
  if ( this.map ) {
118
+ google.maps.event.trigger( this.map, 'resize' );
119
  this.map.setZoom( zoom );
120
+ this.map.setCenter( center );
121
  }
122
  },
123
 
124
  // Autocomplete address
125
  autocomplete: function () {
126
+ var that = this;
 
127
 
128
+ // No address field or more than 1 address fields, ignore
129
+ if ( ! this.addressField || this.addressField.split( ',' ).length > 1 ) {
130
  return;
131
  }
132
 
133
+ var $address = $( 'input[name="' + this.addressField + '"]');
134
+
135
+ // If map and address is inside a group, the input name of address field is changed.
136
+ if ( 0 === $address.length ) {
137
+ $address = this.$container.closest( '.rwmb-group-wrapper' ).find( 'input[name*="[' + this.addressField + ']"]' );
138
+ }
139
+
140
  // If Meta Box Geo Location installed. Do not run auto complete.
141
  if ( $( '.rwmb-geo-binding' ).length ) {
142
  $address.on( 'selected_address', function () {
153
  'region': that.$canvas.data( 'region' )
154
  };
155
  geocoder.geocode( options, function ( results ) {
156
+ response( $.map( results, function ( item ) {
 
 
 
 
 
 
 
157
  return {
158
  label: item.formatted_address,
159
  value: item.formatted_address,
165
  },
166
  select: function ( event, ui ) {
167
  var latLng = new google.maps.LatLng( ui.item.latitude, ui.item.longitude );
168
+
169
  that.map.setCenter( latLng );
170
  that.marker.setPosition( latLng );
171
  that.updateCoordinate( latLng );
181
 
182
  // Find coordinates by address
183
  geocodeAddress: function () {
184
+ var address,
185
+ addressList = [],
186
+ fieldList = this.addressField.split( ',' ),
187
+ loop,
188
  that = this;
189
+
190
+ for ( loop = 0; loop < fieldList.length; loop ++ ) {
191
+ addressList[loop] = $( '#' + fieldList[loop] ).val();
192
+ }
193
+
194
+ address = addressList.join( ',' ).replace( /\n/g, ',' ).replace( /,,/g, ',' );
195
+
196
  if ( ! address ) {
197
  return;
198
  }
205
  that.marker.setPosition( results[0].geometry.location );
206
  that.updateCoordinate( results[0].geometry.location );
207
  } );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
208
  }
209
  };
210
 
216
  return;
217
  }
218
 
219
+ controller = new MapField( $( this ) );
220
  controller.init();
221
  $this.data( 'mapController', controller );
222
  } );
js/media.js CHANGED
@@ -256,9 +256,9 @@ jQuery( function ( $ ) {
256
  this.collection.remove( item );
257
  },
258
 
259
- resetItemViews: function( items ){
260
  var that = this;
261
- _.each( that.models, function( item ){
262
  that.removeItemView( item );
263
  } );
264
  items.each( function( item ) {
256
  this.collection.remove( item );
257
  },
258
 
259
+ resetItemViews: function( items, options ){
260
  var that = this;
261
+ _.each( options.previousModels, function( item ){
262
  that.removeItemView( item );
263
  } );
264
  items.each( function( item ) {
js/oembed.js CHANGED
@@ -11,8 +11,7 @@ jQuery( function ( $ ) {
11
  $spinner = $this.siblings( '.spinner' ),
12
  data = {
13
  action: 'rwmb_get_embed',
14
- url: this.value,
15
- not_available: $this.data( 'not-available' ),
16
  };
17
 
18
  $spinner.css( 'visibility', 'visible' );
11
  $spinner = $this.siblings( '.spinner' ),
12
  data = {
13
  action: 'rwmb_get_embed',
14
+ url: $this.val()
 
15
  };
16
 
17
  $spinner.css( 'visibility', 'visible' );
js/osm-frontend.js DELETED
@@ -1,50 +0,0 @@
1
- jQuery( function( $ ) {
2
- 'use strict';
3
-
4
- var osmTileLayer = L.tileLayer( 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
5
- attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
6
- } );
7
-
8
- /**
9
- * Display Open Street Map
10
- */
11
- function displayMap() {
12
- var options = $( this ).data( 'osm_options' ),
13
- mapOptions = options.js_options,
14
- center = L.latLng( options.latitude, options.longitude ),
15
- map;
16
-
17
- mapOptions.center = center;
18
-
19
- // Typcast zoom to a number
20
- mapOptions.zoom *= 1;
21
-
22
- map = L.map( this, mapOptions );
23
- map.addLayer( osmTileLayer );
24
-
25
- // Set marker
26
- if ( options.marker ) {
27
- var markerOptions = {};
28
-
29
- // Set marker title
30
- if ( options.marker_title ) {
31
- markerOptions.title = options.marker_title;
32
- }
33
-
34
- // Set marker icon
35
- if ( options.marker_icon ) {
36
- markerOptions.icon = L.icon( options.marker_icon );
37
- }
38
-
39
- var marker = L.marker( center, markerOptions ).addTo( map )
40
- }
41
-
42
- // Set info window
43
- if ( options.info_window ) {
44
- marker.bindPopup( options.info_window ).openPopup();
45
- }
46
- }
47
-
48
- // Loop through all map instances and display them
49
- $( '.rwmb-osm-canvas' ).each( displayMap );
50
- } );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/osm.js DELETED
@@ -1,264 +0,0 @@
1
- ( function( $, L ) {
2
- 'use strict';
3
-
4
- var osmTileLayer = L.tileLayer( 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
5
- attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
6
- } );
7
-
8
- // Use function construction to store map & DOM elements separately for each instance
9
- var OsmField = function ( $container ) {
10
- this.$container = $container;
11
- };
12
-
13
- // Use prototype for better performance
14
- OsmField.prototype = {
15
- // Initialize everything
16
- init: function () {
17
- this.initDomElements();
18
- this.initMapElements();
19
-
20
- this.initMarkerPosition();
21
- this.addListeners();
22
- this.autocomplete();
23
- },
24
-
25
- // Initialize DOM elements
26
- initDomElements: function () {
27
- this.$canvas = this.$container.find( '.rwmb-osm-canvas' );
28
- this.canvas = this.$canvas[0];
29
- this.$coordinate = this.$container.find( '.rwmb-osm-coordinate' );
30
- this.$findButton = this.$container.find( '.rwmb-osm-goto-address-button' );
31
- this.addressField = this.$container.data( 'address-field' );
32
- },
33
-
34
- // Initialize map elements
35
- initMapElements: function () {
36
- var defaultLoc = this.$canvas.data( 'default-loc' ),
37
- latLng;
38
-
39
- defaultLoc = defaultLoc ? defaultLoc.split( ',' ) : [53.346881, -6.258860];
40
- latLng = L.latLng( defaultLoc[0], defaultLoc[1] ); // Initial position for map.
41
-
42
- this.map = L.map( this.canvas, {
43
- center: latLng,
44
- zoom: 14
45
- } );
46
- this.map.addLayer( osmTileLayer );
47
- this.marker = L.marker( latLng, {
48
- draggable: true
49
- } ).addTo( this.map );
50
- },
51
-
52
- // Initialize marker position
53
- initMarkerPosition: function () {
54
- var coordinate = this.$coordinate.val(),
55
- location,
56
- zoom;
57
-
58
- if ( coordinate ) {
59
- location = coordinate.split( ',' );
60
- var latLng = L.latLng( location[0], location[1] );
61
- this.marker.setLatLng( latLng );
62
-
63
- zoom = location.length > 2 ? parseInt( location[2], 10 ) : 14;
64
-
65
- this.map.panTo( latLng );
66
- this.map.setZoom( zoom );
67
- } else if ( this.addressField ) {
68
- this.geocodeAddress();
69
- }
70
- },
71
-
72
- // Add event listeners for 'click' & 'drag'
73
- addListeners: function () {
74
- var that = this;
75
- this.map.on( 'click', function ( event ) {
76
- that.marker.setLatLng( event.latlng );
77
- that.updateCoordinate( event.latlng );
78
- } );
79
-
80
- this.map.on( 'zoom', function () {
81
- that.updateCoordinate( that.marker.getLatLng() );
82
- } );
83
-
84
- this.marker.on( 'drag', function () {
85
- that.updateCoordinate( that.marker.getLatLng() );
86
- } );
87
-
88
- this.$findButton.on( 'click', function ( e ) {
89
- e.preventDefault();
90
- that.geocodeAddress();
91
- } );
92
-
93
- /**
94
- * Add a custom event that allows other scripts to refresh the maps when needed
95
- * For example: when maps is in tabs or hidden div (this is known issue of Google Maps)
96
- *
97
- * @see https://developers.google.com/maps/documentation/javascript/reference ('resize' Event)
98
- */
99
- $( window ).on( 'rwmb_map_refresh', function () {
100
- that.refresh();
101
- } );
102
-
103
- // Refresh on meta box hide and show
104
- $( document ).on( 'postbox-toggled', function () {
105
- that.refresh();
106
- } );
107
- // Refresh on sorting meta boxes
108
- $( '.meta-box-sortables' ).on( 'sortstop', function () {
109
- that.refresh();
110
- } );
111
- },
112
-
113
- refresh: function () {
114
- if ( this.map ) {
115
- this.map.panTo( this.map.getCenter() );
116
- }
117
- },
118
-
119
- // Autocomplete address
120
- autocomplete: function () {
121
- var that = this,
122
- $address = this.getAddressField();
123
-
124
- if ( null === $address ) {
125
- return;
126
- }
127
-
128
- // If Meta Box Geo Location installed. Do not run auto complete.
129
- if ( $( '.rwmb-geo-binding' ).length ) {
130
- $address.on( 'selected_address', that.geocodeAddress );
131
- return;
132
- }
133
-
134
- $address.autocomplete( {
135
- source: function ( request, response ) {
136
- $.get( 'https://nominatim.openstreetmap.org/search', {
137
- format: 'json',
138
- q: request.term,
139
- countrycodes: that.$canvas.data( 'region' ),
140
- "accept-language": that.$canvas.data( 'language' )
141
- }, function( results ) {
142
- if ( ! results.length ) {
143
- response( [ {
144
- value: '',
145
- label: RWMB_Osm.no_results_string
146
- } ] );
147
- return;
148
- }
149
- response( results.map( function ( item ) {
150
- return {
151
- label: item.display_name,
152
- value: item.display_name,
153
- latitude: item.lat,
154
- longitude: item.lon
155
- };
156
- } ) );
157
- }, 'json' );
158
- },
159
- select: function ( event, ui ) {
160
- var latLng = L.latLng( ui.item.latitude, ui.item.longitude );
161
-
162
- that.map.panTo( latLng );
163
- that.marker.setLatLng( latLng );
164
- that.updateCoordinate( latLng );
165
- }
166
- } );
167
- },
168
-
169
- // Update coordinate to input field
170
- updateCoordinate: function ( latLng ) {
171
- var zoom = this.map.getZoom();
172
- this.$coordinate.val( latLng.lat + ',' + latLng.lng + ',' + zoom );
173
- },
174
-
175
- // Find coordinates by address
176
- geocodeAddress: function () {
177
- var address = this.getAddress(),
178
- that = this;
179
- if ( ! address ) {
180
- return;
181
- }
182
-
183
- $.get( 'https://nominatim.openstreetmap.org/search', {
184
- format: 'json',
185
- q: address,
186
- limit: 1,
187
- countrycodes: that.$canvas.data( 'region' ),
188
- "accept-language": that.$canvas.data( 'language' )
189
- }, function( result ) {
190
- if ( result.length !== 1 ) {
191
- return;
192
- }
193
- var latLng = L.latLng( result[0].lat, result[0].lon );
194
- that.map.panTo( latLng );
195
- that.marker.setLatLng( latLng );
196
- that.updateCoordinate( latLng );
197
- }, 'json' );
198
- },
199
-
200
- // Get the address field.
201
- getAddressField: function() {
202
- // No address field or more than 1 address fields, ignore
203
- if ( ! this.addressField || this.addressField.split( ',' ).length > 1 ) {
204
- return null;
205
- }
206
- return this.findAddressField( this.addressField );
207
- },
208
-
209
- // Get the address value for geocoding.
210
- getAddress: function() {
211
- var that = this;
212
-
213
- return this.addressField.split( ',' )
214
- .map( function( part ) {
215
- part = that.findAddressField( part );
216
- return null === part ? '' : part.val();
217
- } )
218
- .join( ',' ).replace( /\n/g, ',' ).replace( /,,/g, ',' );
219
- },
220
-
221
- // Find address field based on its name attribute. Auto search inside groups when needed.
222
- findAddressField: function( fieldName ) {
223
- // Not in a group.
224
- var $address = $( 'input[name="' + fieldName + '"]');
225
- if ( $address.length ) {
226
- return $address;
227
- }
228
-
229
- // If map and address is inside a cloneable group.
230
- $address = this.$container.closest( '.rwmb-group-clone' ).find( 'input[name*="[' + fieldName + ']"]' );
231
- if ( $address.length ) {
232
- return $address;
233
- }
234
-
235
- // If map and address is inside a non-cloneable group.
236
- $address = this.$container.closest( '.rwmb-group-wrapper' ).find( 'input[name*="[' + fieldName + ']"]' );
237
- if ( $address.length ) {
238
- return $address;
239
- }
240
-
241
- return null;
242
- }
243
- };
244
-
245
- function update() {
246
- $( '.rwmb-osm-field' ).each( function () {
247
- var $this = $( this ),
248
- controller = $this.data( 'osmController' );
249
- if ( controller ) {
250
- return;
251
- }
252
-
253
- controller = new OsmField( $this );
254
- controller.init();
255
- $this.data( 'osmController', controller );
256
- } );
257
- }
258
-
259
- $( function () {
260
- update();
261
- $( '.rwmb-input' ).on( 'clone', update );
262
- } );
263
-
264
- } )( jQuery, L );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/script.js ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ jQuery( function ( $ ) {
2
+ // Add class for seamless meta boxes.
3
+ $( '.rwmb-meta-box--seamless' ).closest( '.postbox' ).addClass( 'rwmb-seamless' );
4
+ } );
js/validate.js CHANGED
@@ -37,14 +37,9 @@ jQuery( function ( $ ) {
37
 
38
  // Required field styling
39
  $.each( subRules.rules, function ( k, v ) {
40
- if ( ! v['required'] ) {
41
- return;
42
  }
43
- var $el = $( '[name="' + k + '"]' );
44
- if ( ! $el.length ) {
45
- return;
46
- }
47
- $el.closest( '.rwmb-input' ).siblings( '.rwmb-label' ).append( '<span class="rwmb-required">*</span>' );
48
  } );
49
  } );
50
 
37
 
38
  // Required field styling
39
  $.each( subRules.rules, function ( k, v ) {
40
+ if ( v['required'] ) {
41
+ $( '#' + k ).parent().siblings( '.rwmb-label' ).append( '<span class="rwmb-required">*</span>' );
42
  }
 
 
 
 
 
43
  } );
44
  } );
45
 
js/wysiwyg.js CHANGED
@@ -70,7 +70,7 @@ jQuery( function ( $ ) {
70
  function updateDom( $wrapper, id ) {
71
  // Wrapper div and media buttons
72
  $wrapper.attr( 'id', 'wp-' + id + '-wrap' )
73
- .removeClass( 'html-active' ).addClass( 'tmce-active' ) // Active the visual mode by default
74
  .find( '.mce-container' ).remove().end() // Remove rendered tinyMCE editor
75
  .find( '.wp-editor-tools' ).attr( 'id', 'wp-' + id + '-editor-tools' )
76
  .find( '.wp-media-buttons' ).attr( 'id', 'wp-' + id + '-media-buttons' )
70
  function updateDom( $wrapper, id ) {
71
  // Wrapper div and media buttons
72
  $wrapper.attr( 'id', 'wp-' + id + '-wrap' )
73
+ .removeClass( 'html-active' ).addClass( 'mce-active' ) // Active the visual mode by default
74
  .find( '.mce-container' ).remove().end() // Remove rendered tinyMCE editor
75
  .find( '.wp-editor-tools' ).attr( 'id', 'wp-' + id + '-editor-tools' )
76
  .find( '.wp-media-buttons' ).attr( 'id', 'wp-' + id + '-media-buttons' )
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.15.5
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.14.10
7
  * Author: MetaBox.io
8
  * Author URI: https://metabox.io
9
  * License: GPL2+
readme.txt CHANGED
@@ -3,138 +3,106 @@ Contributors: metabox, rilwis, fitwp, f-j-kaiser, funkatronic, PerWiklander, rua
3
  Donate link: https://metabox.io/pricing/
4
  Tags: meta-box, custom fields, custom field, meta, meta-boxes, admin, advanced, custom, edit, field, file, image, magic fields, matrix, more fields, Post, repeater, simple fields, text, textarea, type, cms, fields post
5
  Requires at least: 4.3
6
- Tested up to: 4.9.8
7
- Stable tag: 4.15.5
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.
11
 
12
  == Description ==
13
 
14
- **Meta Box is a powerful, professional, and lightweight toolkit for developers to create unlimited custom meta boxes and WordPress custom fields.**
15
 
16
- Meta Box helps you add [custom fields](https://metabox.io) and details on your website such as pages, posts, forms and anywhere you want using over 40 different field types such as text, images, file upload, checkboxes, and more.
17
 
18
- On top of that, each WordPress custom field type has extensive internal options for unlimited content possibilities. Complete customization and control is just a few clicks away.
19
 
20
- Adding WordPress custom fields and custom meta boxes is quick and painless: Select the field types you want in the user-friendly [Online Generator](https://metabox.io/online-generator/), then copy and paste the code into your child theme's `functions.php` file.
21
-
22
- **Boom! All the power with none of the bloat.**
23
-
24
- There are also free and premium extensions available to add enhanced capabilities. You can manage the display and organization of your WordPress custom fields, the conditions upon which they appear, and become the ultimate WordPress data wizard.
25
-
26
- You can also check out the [full list of extensions](https://metabox.io/plugins/) and [MetaBox.io](https://metabox.io) for details.
27
 
28
  ### Features
29
 
30
- #### Create any type of metadata or custom fields in WordPress
31
-
32
- That's right – any type. No matter where you need to insert custom data and features, Meta Box's WordPress custom fields have your back, and with infinite options to boot.
33
 
34
- **Here are just a few of the data types you can customize:**
 
 
 
35
 
36
- - Posts
37
- - Pages
38
- - Custom post types
39
- - [Taxonomies](https://metabox.io/plugins/mb-term-meta/)
40
- - [Settings pages](https://metabox.io/plugins/mb-settings-page/)
41
- - [Theme option pages](https://metabox.io/plugins/mb-settings-page/)
42
- - [User profile pages](https://metabox.io/plugins/mb-user-profile/)
43
- - [Post comments](https://metabox.io/plugins/mb-comment-meta/)
44
- - [And even more data types](https://docs.metabox.io/field-settings/) than Batman has tools on his utility belt.
45
 
46
- #### A wide-range of field types and options
 
 
47
 
48
- Take your standard WordPress custom field and imagine it infinitely expanded. That's how many options Meta Box gives you:
49
 
50
- - Meta Box supports [40+ built-in WordPress custom field types](https://docs.metabox.io/field-settings/) for all your needs including text, textarea, WYSIWYG editor, image, file, post, select, checkbox, radio buttons, date/time picker, taxonomy, user, oembed and more to come.
51
- - Not enough? You can also [effortlessly create your own field type](https://docs.metabox.io/custom-field-type/).
52
- - Meta Box supports cloning fields for most field types including the WYSIWYG editor field. It also supports [repeatable field groups](https://metabox.io/plugins/meta-box-group/).
53
- - Utilize WordPress' powerful [action](https://docs.metabox.io/actions/) and [filter](https://docs.metabox.io/filters/) system so you can build or change a site's appearance and behavior in the plugin.
54
 
55
- #### It's developer-friendly
 
 
56
 
57
- As a developer, you have enough on your plate. You shouldn't have to create an entirely new system for each project. Use Meta Box to your full advantage.
58
 
59
- You can use Meta Box and its custom fields in WordPress on as many websites as you want so you can use it on client projects as well.
60
 
61
- - Has an ultra-lightweight, yet powerful API that won't overload your site.
62
- - Add only what you need instead of getting stuck with a bundle of features you don't even want that bloat your site.
63
- - Meta Box [easily integrates with any theme and plugin](https://docs.metabox.io/integration/), and also [works with the Composer package dependency manager](https://docs.metabox.io/composer/).
64
- - We use the [native WordPress meta data storage](https://docs.metabox.io/database/) and functions for ease of use and lightning-fast processing.
65
- - It's compatible with WPML multilingual plugin, and is officially supported by the WPML team.
66
 
67
- #### Don't love coding? You're in luck!
68
 
69
- Meta Box is built mostly for developers since you need to copy and paste some code, but if you prefer a more visual system to create custom fields in WordPress, you can choose one or all of the extensions below:
70
 
71
- - [MB Custom Post Type](https://wordpress.org/plugins/mb-custom-post-type/)
72
- - [Meta Box – Beaver Themer Integrator](https://metabox.io/plugins/meta-box-beaver-themer-integrator/)
73
- - [Meta Box Builder](https://metabox.io/plugins/meta-box-builder/)
74
-
75
- The [Meta Box Builder extension](https://metabox.io/plugins/meta-box-builder/) has a ton of features to make quick work of any project:
76
 
77
- - All the power of Meta Box without touching a single line of code.
78
- - It's designer-friendly, lightweight and works at top-notch speeds.
79
- - Create an unlimited amount of WordPress custom fields at lightning speeds and with a user-friendly drag-and-drop interface.
80
- - Over 40 custom field types available that you can drag and drop to where you need ‘em.
81
- - Export your custom fields and settings to PHP. Then, add it to a new site without needing to install this extension for an incredibly lightweight option.
82
- - It has the goods with conditional logic, priority and context options ready and waiting.
83
 
84
  ### Extensions
85
 
86
- Speaking of extensions, there are a ton of free and premium ones available to further extend the already powerful core Meta Box plugin so you can supercharge your custom fields in WordPress.
87
-
88
- You'll have ultimate control to add whatever meta box and custom fields in WordPress you could ever want. Then, you can tailor it all to fit your exact specifications.
89
-
90
  #### Free Extensions
91
 
92
- - [MB Custom Post Type](https://wordpress.org/plugins/mb-custom-post-type/): Create and manage custom post types and taxonomies quickly with an easy-to-use interface.
93
- - [MB Relationships](https://wordpress.org/plugins/mb-relationships/): Create as many connections as you want from post-to-post or page-to-page.
94
- - [Meta Box Yoast SEO](https://wordpress.org/plugins/meta-box-yoast-seo/): Add WordPress custom fields to Yoast SEO Content Analysis to generate more accurate SEO scores.
95
- - [MB Rest API](https://metabox.io/plugins/mb-rest-api/): Pull all meta values from posts and terms into the WP REST API responses.
96
- - [MB Comment Meta](https://wordpress.org/plugins/mb-comment-meta/): Add WordPress custom fields to comments in WordPress. It supports all field types and options.
97
- - [MB Custom Taxonomy](https://metabox.io/plugins/custom-taxonomy/): Create and manage custom taxonomies in WordPress with a user-friendly interface.
98
  - [Meta Box Text Limiter](https://wordpress.org/plugins/meta-box-text-limiter/): Limit the number of characters or words entered for text and textarea fields.
99
- - [Meta Box – FacetWP Integrator](https://metabox.io/plugins/meta-box-facetwp-integrator/): Integrates Meta Box, and FacetWP to make WordPress custom fields searchable and filterable in the frontend.
100
- - [Meta Box – Beaver Themer Integrator](https://metabox.io/plugins/meta-box-beaver-themer-integrator/): Integrates Meta Box, and Beaver Themer to show WordPress custom fields easier in the frontend.
101
 
102
  #### Premium Extensions
103
 
104
- - [Meta Box Builder](https://metabox.io/plugins/meta-box-builder/): Create custom meta boxes and custom fields in WordPress using a user-friendly drag-and-drop interface.
105
- - [Meta Box Group](https://metabox.io/plugins/meta-box-group/): Create repeatable groups of WordPress custom fields for better appearance and structure.
106
  - [MB Settings Page](https://metabox.io/plugins/mb-settings-page/): Create settings pages for themes, plugins or websites with beautiful syntax.
107
  - [MB Term Meta](https://metabox.io/plugins/mb-term-meta/): Add meta data to categories, tags or any custom taxonomy with simple syntax.
108
  - [Meta Box Conditional Logic](https://metabox.io/plugins/meta-box-conditional-logic/): Add visibility dependency for custom meta boxes and custom fields in WordPress.
109
- - [Meta Box Include Exclude](https://metabox.io/plugins/meta-box-include-exclude/): Show or hide meta boxes by ID, page template, taxonomy, or custom function.
110
- - [MB Frontend Submission](https://metabox.io/plugins/mb-frontend-submission/): Create frontend forms for users to submit custom content and embed them anywhere with a shortcode.
111
- - [Meta Box Columns](https://metabox.io/plugins/meta-box-columns/): Display eye-catching custom fields in WordPress by putting them into 12-column grids.
112
- - [Meta Box Tabs](https://metabox.io/plugins/meta-box-tabs/): Painlessly create tabs for meta boxes. There are 3 supported WordPress-native tab styles and icons.
113
- - [MB Admin Columns](https://metabox.io/plugins/mb-admin-columns/): Display WordPress custom fields in table columns on admin screens for all post types.
114
- - [MB Custom Table](https://metabox.io/plugins/mb-custom-table/): Save custom field data to custom tables instead of the default meta tables to reduce your database's size and increase its performance.
115
- - [MB Revision](https://metabox.io/plugins/mb-revision/): Track changes to custom fields in WordPress with revisions. You can save, compare and restore the changes smoothly.
116
- - [MB User Meta](https://metabox.io/plugins/mb-user-meta/): Quickly add WordPress custom fields to user profiles in the wp_usermeta table with simple syntax.
117
- - [Meta Box Geolocation](https://metabox.io/plugins/meta-box-geolocation/): Automatically and instantly populate location data with the power of the Google Maps Geolocation API.
118
- - [Meta Box Template](https://metabox.io/plugins/meta-box-template/): Make defining custom meta boxes and WordPress custom fields way easier with templates.
119
- - [Meta Box Tooltip](https://metabox.io/plugins/meta-box-tooltip/): Display help information for custom fields in WordPress using beautiful tooltips.
120
- - [Meta Box Show Hide](https://metabox.io/plugins/meta-box-show-hide-javascript/): Toggle meta boxes by page template, post format, taxonomy and category via JavaScript.
121
-
122
- See all the available [extensions on the Meta Box website](https://metabox.io/plugins/).
123
-
124
- ### Detailed Documentation
125
-
126
- We won't leave you high and dry.
127
-
128
- We provide regularly updated, and extensive documentation as well as tutorials on how to use MetaBox and custom fields in WordPress to your advantage as well as in the most efficient way possible.
129
-
130
- Here are a few guides to quickly get you started with Meta Box and creating your own WordPress custom fields:
131
-
132
- - [Quick Start Guide](https://docs.metabox.io/quick-start/)
133
- - [Creating Meta Boxes](https://docs.metabox.io/creating-meta-boxes/)
134
- - [Field Settings](https://docs.metabox.io/field-settings/)
135
- - [Displaying Fields](https://docs.metabox.io/displaying-fields/)
136
-
137
- Check out more on the [Meta Box Documentation](https://docs.metabox.io/) page.
138
 
139
  == Installation ==
140
 
@@ -151,7 +119,7 @@ Manually
151
  1. Upload `meta-box` to the `/wp-content/plugins/` directory
152
  1. Activate the plugin through the 'Plugins' menu in WordPress
153
 
154
- To getting started with the plugin, please read the [Quick Start Guide](https://docs.metabox.io/quick-start/).
155
 
156
  == Frequently Asked Questions ==
157
 
3
  Donate link: https://metabox.io/pricing/
4
  Tags: meta-box, custom fields, custom field, meta, meta-boxes, admin, advanced, custom, edit, field, file, image, magic fields, matrix, more fields, Post, repeater, simple fields, text, textarea, type, cms, fields post
5
  Requires at least: 4.3
6
+ Tested up to: 4.9.6
7
+ Stable tag: 4.14.10
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.
11
 
12
  == Description ==
13
 
14
+ **Meta Box plugin is a powerful, professional toolkit for developers to create and handle everything related to custom meta boxes and custom fields for WordPress.**
15
 
16
+ The plugin provides a **wide range of field types** and **a lot of options to for each field type**, which gives you unlimited possibility to control and customize the custom fields.
17
 
18
+ With the extensions, you can easily build meta boxes not only for custom post types (default), but also for **settings page, user meta, term meta**. You can also display the fields the way you want with columns, tabs or groups.
19
 
20
+ The plugin requires a little coding, but if you're not familiar with coding or prefer GUI for faster creating custom post types, meta boxes and custom fields, you can use our [Online Generator](https://metabox.io/online-generator/) or use the extensions [MB Custom Post Type](https://wordpress.org/plugins/mb-custom-post-type/) or [Meta Box Builder](https://metabox.io/plugins/meta-box-builder/).
 
 
 
 
 
 
21
 
22
  ### Features
23
 
24
+ #### Create any type of meta data
 
 
25
 
26
+ * Create custom meta boxes for posts, pages or any custom post type.
27
+ * Create custom [settings pages or theme option page](https://metabox.io/plugins/mb-settings-page/).
28
+ * Create custom meta boxes for [user profile pages](https://metabox.io/plugins/mb-user-meta/).
29
+ * Create custom meta boxes for [taxonomy terms](https://metabox.io/plugins/mb-term-meta/).
30
 
31
+ #### Wide-range of field types and options
 
 
 
 
 
 
 
 
32
 
33
+ * Supports 40+ built-in [field types](https://docs.metabox.io/field-settings/) for all your needs (text, textarea, wysiwyg/editor, image, file, post, select, checkbox, radio buttons, date time picker, taxonomy, user, oembed and more to come!). You can also [create your own field type](https://docs.metabox.io/custom-field-type/) easily.
34
+ * Support cloning (repeatable) fields for most field types, including WYSIWYG/editor field. Also support [repeatable field groups](https://metabox.io/plugins/meta-box-group/).
35
+ * Powerful [actions](https://docs.metabox.io/actions/) and [filters](https://docs.metabox.io/filters/) that developers can build or change the appearance and behavior in the plugin.
36
 
37
+ #### Create meta boxes and custom fields with UI
38
 
39
+ The plugin is built mostly for developers with a little coding, but if you prefer GUI for faster creating custom post types, meta boxes and custom fields, the plugin has extensions for that:
 
 
 
40
 
41
+ - [Online Generator](https://metabox.io/online-generator/)
42
+ - [MB Custom Post Type](https://wordpress.org/plugins/mb-custom-post-type/)
43
+ - [Meta Box Builder](https://metabox.io/plugins/meta-box-builder/)
44
 
45
+ <blockquote>To make it easy for all users to create custom meta boxes and custom fields, we have created an <a href="https://metabox.io/online-generator/">Online Generator</a> tool. It has an user-friendly interface with drag and drop features. No custom code anymore!</blockquote>
46
 
47
+ #### Developer-friendly
48
 
49
+ * Uses the [native WordPress meta data storage](https://docs.metabox.io/database/) and functions for ease of use and fast processing.
50
+ * [Easily integrate with themes and plugins](https://docs.metabox.io/integration/).
51
+ * [Works with Composer](https://docs.metabox.io/composer/) if you want to include the plugin in your project.
52
+ * Compatible with WPML multilingual plugin (officially supported by WPML team).
 
53
 
54
+ #### Detailed Documentation
55
 
56
+ We provide regular updated and extensive documentation. Not only technical things, but also tutorials on how to use the plugin better.
57
 
58
+ - [Quick Start Guide](https://docs.metabox.io/quick-start/)
59
+ - [Creating Meta Boxes](https://docs.metabox.io/creating-meta-boxes/)
60
+ - [Field Settings](https://docs.metabox.io/field-settings/)
61
+ - [Displaying Fields](https://docs.metabox.io/displaying-fields/)
 
62
 
63
+ See more documentation [here](https://docs.metabox.io).
 
 
 
 
 
64
 
65
  ### Extensions
66
 
 
 
 
 
67
  #### Free Extensions
68
 
69
+ - [MB Custom Post Type](https://wordpress.org/plugins/mb-custom-post-type/): Create and manage custom post types and taxonomies easily in WordPress with an easy-to-use interface.
70
+ - [MB Relationships](https://wordpress.org/plugins/mb-relationships/): Create many-to-many relationships from posts to posts.
71
+ - [Meta Box Yoast SEO](https://wordpress.org/plugins/meta-box-yoast-seo/): Add content of custom fields to Yoast SEO Content Analysis to have better/correct SEO score.
72
+ - [MB Rest API](https://metabox.io/plugins/mb-rest-api/): Pull all meta value from posts, terms into the WP REST API responses.
73
+ - [MB Comment Meta](https://wordpress.org/plugins/mb-comment-meta/): Add custom fields to comments in WordPress. Support all field types and options.
74
+ - [MB Custom Taxonomy](https://metabox.io/plugins/custom-taxonomy/): Create and manage custom taxonomies with an easy-to-use interface in WordPress.
75
  - [Meta Box Text Limiter](https://wordpress.org/plugins/meta-box-text-limiter/): Limit the number of characters or words entered for text and textarea fields.
76
+ - [Meta Box – FacetWP Integrator](https://metabox.io/plugins/meta-box-facetwp-integrator/): Integrates Meta Box and FacetWP, makes custom fields searchable and filterable in the frontend.
 
77
 
78
  #### Premium Extensions
79
 
80
+ - [Meta Box Builder](https://metabox.io/plugins/meta-box-builder/): Create custom meta boxes and custom fields in WordPress using the drag-and-drop interface.
81
+ - [Meta Box Group](https://metabox.io/plugins/meta-box-group/): Create repeatable groups of custom fields for better appearance and structure.
82
  - [MB Settings Page](https://metabox.io/plugins/mb-settings-page/): Create settings pages for themes, plugins or websites with beautiful syntax.
83
  - [MB Term Meta](https://metabox.io/plugins/mb-term-meta/): Add meta data to categories, tags or any custom taxonomy with simple syntax.
84
  - [Meta Box Conditional Logic](https://metabox.io/plugins/meta-box-conditional-logic/): Add visibility dependency for custom meta boxes and custom fields in WordPress.
85
+ - [Meta Box Include Exclude](https://metabox.io/plugins/meta-box-include-exclude/): Show/hide meta boxes by ID, page template, taxonomy or custom function.
86
+ - [MB Frontend Submission](https://metabox.io/plugins/mb-frontend-submission/): Create frontend forms for users to submit custom content. Embed everywhere with shortcode.
87
+ - [Meta Box Columns](https://metabox.io/plugins/meta-box-columns/): Display fields more beautiful by putting them into 12-columns grid.
88
+ - [Meta Box Tabs](https://metabox.io/plugins/meta-box-tabs/): Create tabs for meta boxes easily. Support 3 WordPress-native tab styles and tab icon.
89
+ - [MB Admin Columns](https://metabox.io/plugins/mb-admin-columns/): Display custom fields in table columns in admin screens for All Posts (types).
90
+ - [MB Custom Table](https://metabox.io/plugins/mb-custom-table/): Save custom fields data to custom table instead of the default meta tables. Reduce database size and increase performance.
91
+ - [MB Revision](https://metabox.io/plugins/mb-revision/): Track changes of custom fields with WordPress revision. Save, compare, restore the changes easily.
92
+ - [MB User Meta](https://metabox.io/plugins/mb-user-meta/): Add custom fields to user profile (user meta) quickly with simple syntax.
93
+ - [Meta Box Geolocation](https://metabox.io/plugins/meta-box-geolocation/): Automatically and instantly populate location data with the power of Google Maps Geolocation API.
94
+ - [Meta Box Template](https://metabox.io/plugins/meta-box-template/): Define custom meta boxes and custom fields easier with templates.
95
+ - [Meta Box Tooltip](https://metabox.io/plugins/meta-box-tooltip/): Display help information for fields using beautiful tooltips.
96
+ - [Meta Box Show Hide](https://metabox.io/plugins/meta-box-show-hide-javascript/): Toggle meta boxes by page template, post format, taxonomy (including category) via Javascript.
97
+
98
+ See all extensions [here](https://metabox.io/plugins/).
99
+
100
+ ### Plugin Links
101
+
102
+ - [Project Page](https://metabox.io)
103
+ - [Documentation](https://docs.metabox.io)
104
+ - [Report Bugs/Issues](https://github.com/wpmetabox/meta-box/issues)
105
+ - [Premium Extensions](https://metabox.io/plugins/)
 
 
 
 
 
 
 
 
106
 
107
  == Installation ==
108
 
119
  1. Upload `meta-box` to the `/wp-content/plugins/` directory
120
  1. Activate the plugin through the 'Plugins' menu in WordPress
121
 
122
+ To getting started with the plugin, please read [this tutorial](https://docs.metabox.io/quick-start/).
123
 
124
  == Frequently Asked Questions ==
125