Meta Box - Version 4.3.9

Version Description

  • Bug fix: text-list field type
  • Improvement: better coding styles
  • Improvement: wysiwyg field is now clonable
  • Improvement: launch geolocation autocomplete when address field is cloned
  • Improvement: better cloning for radio, checkbox
  • Improvement: add more hooks
  • Improvement: allow child fields to add their own add/remove clone buttons.
  • Improvement: remove 'clone-group'. Too complicated and not user-friendly.
Download this release

Release Info

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

Code changes from version 4.3.8 to 4.3.9

css/image.css CHANGED
@@ -63,4 +63,7 @@ li:hover .rwmb-image-bar{
63
  z-index: 2;
64
  opacity: .4;
65
  background-color: #f00;
66
- }
 
 
 
63
  z-index: 2;
64
  opacity: .4;
65
  background-color: #f00;
66
+ }
67
+ .rwmb-images li.ui-state-highlight{
68
+ background: #DDDDDD;
69
+ }
css/select2/select2.css CHANGED
@@ -407,7 +407,7 @@ disabled look for already selected choices in the results dropdown
407
  background: transparent !important;
408
  font-family: sans-serif;
409
  font-size: 100%;
410
- height: 15px;
411
  padding: 5px;
412
  margin: 1px 0;
413
  outline: 0;
407
  background: transparent !important;
408
  font-family: sans-serif;
409
  font-size: 100%;
410
+ height: auto;
411
  padding: 5px;
412
  margin: 1px 0;
413
  outline: 0;
css/style.css CHANGED
@@ -2,7 +2,7 @@
2
  -------------------------------------------------------------- */
3
 
4
  .rwmb-field {
5
- margin: 10px 0;
6
  }
7
  .rwmb-label,
8
  .rwmb-input {
2
  -------------------------------------------------------------- */
3
 
4
  .rwmb-field {
5
+ margin: 0 0 10px;
6
  }
7
  .rwmb-label,
8
  .rwmb-input {
inc/common.php CHANGED
@@ -2,7 +2,7 @@
2
  // Prevent loading this file directly
3
  defined( 'ABSPATH' ) || exit;
4
 
5
- if ( !class_exists( 'RWMB_Common' ) )
6
  {
7
  /**
8
  * Common functions for the plugin
2
  // Prevent loading this file directly
3
  defined( 'ABSPATH' ) || exit;
4
 
5
+ if ( ! class_exists( 'RWMB_Common' ) )
6
  {
7
  /**
8
  * Common functions for the plugin
inc/field.php CHANGED
@@ -1,5 +1,5 @@
1
  <?php
2
- if ( !class_exists( 'RWMB_Field ' ) )
3
  {
4
  class RWMB_Field
5
  {
@@ -19,6 +19,9 @@ if ( !class_exists( 'RWMB_Field ' ) )
19
 
20
  /**
21
  * Show field HTML
 
 
 
22
  *
23
  * @param array $field
24
  * @param bool $saved
@@ -32,7 +35,14 @@ if ( !class_exists( 'RWMB_Field ' ) )
32
  $field_class = RW_Meta_Box::get_class_name( $field );
33
  $meta = call_user_func( array( $field_class, 'meta' ), $post->ID, $saved, $field );
34
 
35
- $group = ''; // Empty the clone-group field
 
 
 
 
 
 
 
36
  $type = $field['type'];
37
  $id = $field['id'];
38
 
@@ -51,9 +61,6 @@ if ( !class_exists( 'RWMB_Field ' ) )
51
  // Cloneable fields
52
  if ( $field['clone'] )
53
  {
54
- if ( isset( $field['clone-group'] ) )
55
- $group = " clone-group='{$field['clone-group']}'";
56
-
57
  $meta = (array) $meta;
58
 
59
  $field_html = '';
@@ -62,6 +69,12 @@ if ( !class_exists( 'RWMB_Field ' ) )
62
  {
63
  $sub_field = $field;
64
  $sub_field['field_name'] = $field['field_name'] . "[{$index}]";
 
 
 
 
 
 
65
  if ( $field['multiple'] )
66
  $sub_field['field_name'] .= '[]';
67
 
@@ -77,8 +90,8 @@ if ( !class_exists( 'RWMB_Field ' ) )
77
  $input_html = apply_filters( "rwmb_{$type}_html", $input_html, $field, $sub_meta );
78
  $input_html = apply_filters( "rwmb_{$id}_html", $input_html, $field, $sub_meta );
79
 
80
- // Add clone button
81
- $input_html .= self::clone_button();
82
 
83
  $input_html .= '</div>';
84
 
@@ -110,26 +123,37 @@ if ( !class_exists( 'RWMB_Field ' ) )
110
 
111
  // Apply filter to field wrapper
112
  // This allow users to change whole HTML markup of the field wrapper (i.e. table row)
 
113
  // 1st filter applies to all fields with the same type
114
  // 2nd filter applies to current field only
115
- $html = apply_filters( "rwmb_{$type}_wrapper_html", "{$begin}{$field_html}{$end}", $field, $meta );
 
116
  $html = apply_filters( "rwmb_{$id}_wrapper_html", $html, $field, $meta );
117
 
118
  // Display label and input in DIV and allow user-defined classes to be appended
119
  $classes = array( 'rwmb-field', "rwmb-{$type}-wrapper" );
120
  if ( 'hidden' === $field['type'] )
121
  $classes[] = 'hidden';
122
- if ( !empty( $field['required'] ) )
123
  $classes[] = 'required';
124
- if ( !empty( $field['class'] ) )
125
  $classes[] = $field['class'];
126
 
127
- printf(
128
- $field['before'] . '<div class="%s"%s>%s</div>' . $field['after'],
129
  implode( ' ', $classes ),
130
- $group,
131
  $html
132
  );
 
 
 
 
 
 
 
 
 
 
133
  }
134
 
135
  /**
@@ -178,13 +202,8 @@ if ( !class_exists( 'RWMB_Field ' ) )
178
  */
179
  static function end_html( $meta, $field )
180
  {
181
- $id = $field['id'];
182
-
183
- $button = '';
184
- if ( $field['clone'] )
185
- $button = '<a href="#" class="rwmb-button button-primary add-clone">' . __( '+', 'rwmb' ) . '</a>';
186
-
187
- $desc = !empty( $field['desc'] ) ? "<p id='{$id}_description' class='description'>{$field['desc']}</p>" : '';
188
 
189
  // Closes the container
190
  $html = "{$button}{$desc}</div>";
@@ -197,7 +216,17 @@ if ( !class_exists( 'RWMB_Field ' ) )
197
  *
198
  * @return string $html
199
  */
200
- static function clone_button()
 
 
 
 
 
 
 
 
 
 
201
  {
202
  return '<a href="#" class="rwmb-button button remove-clone">' . __( '&#8211;', 'rwmb' ) . '</a>';
203
  }
@@ -213,18 +242,15 @@ if ( !class_exists( 'RWMB_Field ' ) )
213
  */
214
  static function meta( $post_id, $saved, $field )
215
  {
216
- $meta = get_post_meta( $post_id, $field['id'], !$field['multiple'] );
217
 
218
  // Use $field['std'] only when the meta box hasn't been saved (i.e. the first time we run)
219
- $meta = ( !$saved && '' === $meta || array() === $meta ) ? $field['std'] : $meta;
220
 
221
  // Escape attributes for non-wysiwyg fields
222
  if ( 'wysiwyg' !== $field['type'] )
223
  $meta = is_array( $meta ) ? array_map( 'esc_attr', $meta ) : esc_attr( $meta );
224
 
225
- $meta = apply_filters( "rwmb_{$field['type']}_meta", $meta );
226
- $meta = apply_filters( "rwmb_{$field['id']}_meta", $meta );
227
-
228
  return $meta;
229
  }
230
 
@@ -265,12 +291,12 @@ if ( !class_exists( 'RWMB_Field ' ) )
265
  {
266
  foreach ( $new as $new_value )
267
  {
268
- if ( !in_array( $new_value, $old ) )
269
  add_post_meta( $post_id, $name, $new_value, false );
270
  }
271
  foreach ( $old as $old_value )
272
  {
273
- if ( !in_array( $old_value, $new ) )
274
  delete_post_meta( $post_id, $name, $old_value );
275
  }
276
  }
1
  <?php
2
+ if ( ! class_exists( 'RWMB_Field ' ) )
3
  {
4
  class RWMB_Field
5
  {
19
 
20
  /**
21
  * Show field HTML
22
+ * Filters are put inside this method, not inside methods such as "meta", "html", "begin_html", etc.
23
+ * That ensures the returned value are always been applied filters
24
+ * This method is not meant to be overwritten in specific fields
25
  *
26
  * @param array $field
27
  * @param bool $saved
35
  $field_class = RW_Meta_Box::get_class_name( $field );
36
  $meta = call_user_func( array( $field_class, 'meta' ), $post->ID, $saved, $field );
37
 
38
+ // Apply filter to field meta value
39
+ // 1st filter applies to all fields
40
+ // 2nd filter applies to all fields with the same type
41
+ // 3rd filter applies to current field only
42
+ $meta = apply_filters( 'rwmb_field_meta', $meta, $field, $saved );
43
+ $meta = apply_filters( "rwmb_{$field['type']}_meta", $meta, $field, $saved );
44
+ $meta = apply_filters( "rwmb_{$field['id']}_meta", $meta, $field, $saved );
45
+
46
  $type = $field['type'];
47
  $id = $field['id'];
48
 
61
  // Cloneable fields
62
  if ( $field['clone'] )
63
  {
 
 
 
64
  $meta = (array) $meta;
65
 
66
  $field_html = '';
69
  {
70
  $sub_field = $field;
71
  $sub_field['field_name'] = $field['field_name'] . "[{$index}]";
72
+ if ( $index > 0 )
73
+ {
74
+ if ( isset( $sub_field['address_field'] ) )
75
+ $sub_field['address_field'] = $field['address_field'] . "_{$index}";
76
+ $sub_field['id'] = $field['id'] . "_{$index}";
77
+ }
78
  if ( $field['multiple'] )
79
  $sub_field['field_name'] .= '[]';
80
 
90
  $input_html = apply_filters( "rwmb_{$type}_html", $input_html, $field, $sub_meta );
91
  $input_html = apply_filters( "rwmb_{$id}_html", $input_html, $field, $sub_meta );
92
 
93
+ // Remove clone button
94
+ $input_html .= call_user_func( array( $field_class, 'remove_clone_button' ), $sub_meta, $sub_field );
95
 
96
  $input_html .= '</div>';
97
 
123
 
124
  // Apply filter to field wrapper
125
  // This allow users to change whole HTML markup of the field wrapper (i.e. table row)
126
+ // 1st filter applies to all fields
127
  // 1st filter applies to all fields with the same type
128
  // 2nd filter applies to current field only
129
+ $html = apply_filters( 'rwmb_wrapper_html', "{$begin}{$field_html}{$end}", $field, $meta );
130
+ $html = apply_filters( "rwmb_{$type}_wrapper_html", $html, $field, $meta );
131
  $html = apply_filters( "rwmb_{$id}_wrapper_html", $html, $field, $meta );
132
 
133
  // Display label and input in DIV and allow user-defined classes to be appended
134
  $classes = array( 'rwmb-field', "rwmb-{$type}-wrapper" );
135
  if ( 'hidden' === $field['type'] )
136
  $classes[] = 'hidden';
137
+ if ( ! empty( $field['required'] ) )
138
  $classes[] = 'required';
139
+ if ( ! empty( $field['class'] ) )
140
  $classes[] = $field['class'];
141
 
142
+ $outer_html = sprintf(
143
+ $field['before'] . '<div class="%s">%s</div>' . $field['after'],
144
  implode( ' ', $classes ),
 
145
  $html
146
  );
147
+
148
+ // Allow to change output of outer div
149
+ // 1st filter applies to all fields
150
+ // 1st filter applies to all fields with the same type
151
+ // 2nd filter applies to current field only
152
+ $outer_html = apply_filters( 'rwmb_outer_html', $outer_html, $field, $meta );
153
+ $outer_html = apply_filters( "rwmb_{$type}_outer_html", $outer_html, $field, $meta );
154
+ $outer_html = apply_filters( "rwmb_{$id}_outer_html", $outer_html, $field, $meta );
155
+
156
+ echo $outer_html;
157
  }
158
 
159
  /**
202
  */
203
  static function end_html( $meta, $field )
204
  {
205
+ $button = $field['clone'] ? call_user_func( array( RW_Meta_Box::get_class_name( $field ), 'add_clone_button' ) ) : '';
206
+ $desc = $field['desc'] ? "<p id='{$field['id']}_description' class='description'>{$field['desc']}</p>" : '';
 
 
 
 
 
207
 
208
  // Closes the container
209
  $html = "{$button}{$desc}</div>";
216
  *
217
  * @return string $html
218
  */
219
+ static function add_clone_button()
220
+ {
221
+ return '<a href="#" class="rwmb-button button-primary add-clone">' . __( '+', 'rwmb' ) . '</a>';
222
+ }
223
+
224
+ /**
225
+ * Remove clone button
226
+ *
227
+ * @return string $html
228
+ */
229
+ static function remove_clone_button()
230
  {
231
  return '<a href="#" class="rwmb-button button remove-clone">' . __( '&#8211;', 'rwmb' ) . '</a>';
232
  }
242
  */
243
  static function meta( $post_id, $saved, $field )
244
  {
245
+ $meta = get_post_meta( $post_id, $field['id'], ! $field['multiple'] );
246
 
247
  // Use $field['std'] only when the meta box hasn't been saved (i.e. the first time we run)
248
+ $meta = ( ! $saved && '' === $meta || array() === $meta ) ? $field['std'] : $meta;
249
 
250
  // Escape attributes for non-wysiwyg fields
251
  if ( 'wysiwyg' !== $field['type'] )
252
  $meta = is_array( $meta ) ? array_map( 'esc_attr', $meta ) : esc_attr( $meta );
253
 
 
 
 
254
  return $meta;
255
  }
256
 
291
  {
292
  foreach ( $new as $new_value )
293
  {
294
+ if ( ! in_array( $new_value, $old ) )
295
  add_post_meta( $post_id, $name, $new_value, false );
296
  }
297
  foreach ( $old as $old_value )
298
  {
299
+ if ( ! in_array( $old_value, $new ) )
300
  delete_post_meta( $post_id, $name, $old_value );
301
  }
302
  }
inc/fields/checkbox-list.php CHANGED
@@ -51,7 +51,7 @@ if ( ! class_exists( 'RWMB_Checkbox_List_Field' ) )
51
  static function meta( $post_id, $saved, $field )
52
  {
53
  $meta = get_post_meta( $post_id, $field['id'], $field['clone'] );
54
- $meta = ( !$saved && '' === $meta || array() === $meta ) ? $field['std'] : $meta;
55
  $meta = array_map( 'esc_attr', (array) $meta );
56
 
57
  return $meta;
@@ -71,9 +71,10 @@ if ( ! class_exists( 'RWMB_Checkbox_List_Field' ) )
71
  */
72
  static function save( $new, $old, $post_id, $field )
73
  {
74
- if ( !$field['clone'] )
75
  {
76
  parent::save( $new, $old, $post_id, $field );
 
77
  return;
78
  }
79
 
@@ -94,8 +95,9 @@ if ( ! class_exists( 'RWMB_Checkbox_List_Field' ) )
94
  {
95
  $field['multiple'] = true;
96
  $field['field_name'] = $field['id'];
97
- if ( !$field['clone'] )
98
  $field['field_name'] .= '[]';
 
99
  return $field;
100
  }
101
  }
51
  static function meta( $post_id, $saved, $field )
52
  {
53
  $meta = get_post_meta( $post_id, $field['id'], $field['clone'] );
54
+ $meta = ( ! $saved && '' === $meta || array() === $meta ) ? $field['std'] : $meta;
55
  $meta = array_map( 'esc_attr', (array) $meta );
56
 
57
  return $meta;
71
  */
72
  static function save( $new, $old, $post_id, $field )
73
  {
74
+ if ( ! $field['clone'] )
75
  {
76
  parent::save( $new, $old, $post_id, $field );
77
+
78
  return;
79
  }
80
 
95
  {
96
  $field['multiple'] = true;
97
  $field['field_name'] = $field['id'];
98
+ if ( ! $field['clone'] )
99
  $field['field_name'] .= '[]';
100
+
101
  return $field;
102
  }
103
  }
inc/fields/checkbox.php CHANGED
@@ -17,10 +17,10 @@ if ( ! class_exists( 'RWMB_Checkbox_Field' ) )
17
  static function html( $meta, $field )
18
  {
19
  return sprintf(
20
- '<input type="checkbox" class="rwmb-checkbox" name="%s" id="%s" value="1" %s />',
21
  $field['field_name'],
22
  $field['id'],
23
- checked( !empty( $meta ), 1, false )
24
  );
25
  }
26
 
17
  static function html( $meta, $field )
18
  {
19
  return sprintf(
20
+ '<input type="checkbox" class="rwmb-checkbox" name="%s" id="%s" value="1" %s>',
21
  $field['field_name'],
22
  $field['id'],
23
+ checked( ! empty( $meta ), 1, false )
24
  );
25
  }
26
 
inc/fields/color.php CHANGED
@@ -13,8 +13,8 @@ if ( ! class_exists( 'RWMB_Color_Field' ) )
13
  */
14
  static function admin_enqueue_scripts()
15
  {
16
- wp_enqueue_style( 'rwmb-color', RWMB_CSS_URL . 'color.css', array( 'farbtastic', 'wp-color-picker' ), RWMB_VER );
17
- wp_enqueue_script( 'rwmb-color', RWMB_JS_URL . 'color.js', array( 'farbtastic', 'wp-color-picker' ), RWMB_VER, true );
18
  }
19
 
20
  /**
13
  */
14
  static function admin_enqueue_scripts()
15
  {
16
+ wp_enqueue_style( 'rwmb-color', RWMB_CSS_URL . 'color.css', array( 'wp-color-picker' ), RWMB_VER );
17
+ wp_enqueue_script( 'rwmb-color', RWMB_JS_URL . 'color.js', array( 'wp-color-picker' ), RWMB_VER, true );
18
  }
19
 
20
  /**
inc/fields/date.php CHANGED
@@ -2,7 +2,7 @@
2
  // Prevent loading this file directly
3
  defined( 'ABSPATH' ) || exit;
4
 
5
- if ( !class_exists( 'RWMB_Date_Field' ) )
6
  {
7
  class RWMB_Date_Field extends RWMB_Field
8
  {
2
  // Prevent loading this file directly
3
  defined( 'ABSPATH' ) || exit;
4
 
5
+ if ( ! class_exists( 'RWMB_Date_Field' ) )
6
  {
7
  class RWMB_Date_Field extends RWMB_Field
8
  {
inc/fields/datetime.php CHANGED
@@ -2,7 +2,7 @@
2
  // Prevent loading this file directly
3
  defined( 'ABSPATH' ) || exit;
4
 
5
- if ( !class_exists( 'RWMB_Datetime_Field' ) )
6
  {
7
  class RWMB_Datetime_Field extends RWMB_Field
8
  {
@@ -75,10 +75,11 @@ if ( !class_exists( 'RWMB_Datetime_Field' ) )
75
  */
76
  static function value( $new, $old, $post_id, $field )
77
  {
78
- if ( !$field['timestamp'] )
79
  return $new;
80
 
81
  $d = DateTime::createFromFormat( self::translate_format( $field ), $new );
 
82
  return $d ? $d->getTimestamp() : 0;
83
  }
84
 
@@ -112,13 +113,13 @@ if ( !class_exists( 'RWMB_Datetime_Field' ) )
112
  // Missing: 't' => '', T' => '', 'm' => '', 's' => ''
113
  static $time_format_translation = array(
114
  'H' => 'H', 'HH' => 'H', 'h' => 'H', 'hh' => 'H',
115
- 'mm' => 'i', 'ss' => 's', 'l' => 'u', 'tt' => 'a', 'TT' => 'A'
116
  );
117
 
118
  // Missing: 'o' => '', '!' => '', 'oo' => '', '@' => '', "''" => "'"
119
  static $date_format_translation = array(
120
  'd' => 'j', 'dd' => 'd', 'oo' => 'z', 'D' => 'D', 'DD' => 'l',
121
- 'm' => 'n', 'mm' => 'm', 'M' => 'M', 'MM' => 'F', 'y' => 'y', 'yy' => 'Y'
122
  );
123
 
124
  /**
2
  // Prevent loading this file directly
3
  defined( 'ABSPATH' ) || exit;
4
 
5
+ if ( ! class_exists( 'RWMB_Datetime_Field' ) )
6
  {
7
  class RWMB_Datetime_Field extends RWMB_Field
8
  {
75
  */
76
  static function value( $new, $old, $post_id, $field )
77
  {
78
+ if ( ! $field['timestamp'] )
79
  return $new;
80
 
81
  $d = DateTime::createFromFormat( self::translate_format( $field ), $new );
82
+
83
  return $d ? $d->getTimestamp() : 0;
84
  }
85
 
113
  // Missing: 't' => '', T' => '', 'm' => '', 's' => ''
114
  static $time_format_translation = array(
115
  'H' => 'H', 'HH' => 'H', 'h' => 'H', 'hh' => 'H',
116
+ 'mm' => 'i', 'ss' => 's', 'l' => 'u', 'tt' => 'a', 'TT' => 'A',
117
  );
118
 
119
  // Missing: 'o' => '', '!' => '', 'oo' => '', '@' => '', "''" => "'"
120
  static $date_format_translation = array(
121
  'd' => 'j', 'dd' => 'd', 'oo' => 'z', 'D' => 'D', 'DD' => 'l',
122
+ 'm' => 'n', 'mm' => 'm', 'M' => 'M', 'MM' => 'F', 'y' => 'y', 'yy' => 'Y',
123
  );
124
 
125
  /**
inc/fields/email.php CHANGED
@@ -5,7 +5,7 @@ defined( 'ABSPATH' ) || exit;
5
  // Make sure "text" field is loaded
6
  require_once RWMB_FIELDS_DIR . 'text.php';
7
 
8
- if ( !class_exists( 'RWMB_Email_Field' ) )
9
  {
10
  class RWMB_Email_Field extends RWMB_Text_Field
11
  {
5
  // Make sure "text" field is loaded
6
  require_once RWMB_FIELDS_DIR . 'text.php';
7
 
8
+ if ( ! class_exists( 'RWMB_Email_Field' ) )
9
  {
10
  class RWMB_Email_Field extends RWMB_Text_Field
11
  {
inc/fields/fieldset-text.php CHANGED
@@ -2,7 +2,7 @@
2
  // Prevent loading this file directly
3
  defined( 'ABSPATH' ) || exit;
4
 
5
- if ( !class_exists( 'RWMB_Fieldset_Text_Field' ) )
6
  {
7
  class RWMB_Fieldset_Text_Field extends RWMB_Field
8
  {
@@ -30,7 +30,7 @@ if ( !class_exists( 'RWMB_Fieldset_Text_Field' ) )
30
  foreach ( $field['options'] as $k => $v )
31
  {
32
  $fid = $field['id'];
33
- if ( is_array( $meta ) && !empty( $meta ) )
34
  $html[] = sprintf( $tpl, $k, $fid, $v, $n, $k, $meta[$v][$n] );
35
  else
36
  $html[] = sprintf( $tpl, $k, $fid, $v, $n, $k, '' );
@@ -55,7 +55,7 @@ if ( !class_exists( 'RWMB_Fieldset_Text_Field' ) )
55
  {
56
  $meta = get_post_meta( $post_id, $field['id'] );
57
 
58
- if ( is_array( $meta ) && !empty( $meta ) )
59
  $meta = $meta[0];
60
 
61
  return $meta;
2
  // Prevent loading this file directly
3
  defined( 'ABSPATH' ) || exit;
4
 
5
+ if ( ! class_exists( 'RWMB_Fieldset_Text_Field' ) )
6
  {
7
  class RWMB_Fieldset_Text_Field extends RWMB_Field
8
  {
30
  foreach ( $field['options'] as $k => $v )
31
  {
32
  $fid = $field['id'];
33
+ if ( is_array( $meta ) && ! empty( $meta ) )
34
  $html[] = sprintf( $tpl, $k, $fid, $v, $n, $k, $meta[$v][$n] );
35
  else
36
  $html[] = sprintf( $tpl, $k, $fid, $v, $n, $k, '' );
55
  {
56
  $meta = get_post_meta( $post_id, $field['id'] );
57
 
58
+ if ( is_array( $meta ) && ! empty( $meta ) )
59
  $meta = $meta[0];
60
 
61
  return $meta;
inc/fields/file-advanced.php CHANGED
@@ -40,13 +40,15 @@ if ( ! class_exists( 'RWMB_File_Advanced_Field' ) )
40
 
41
  static function wp_ajax_attach_file()
42
  {
43
- $post_id = is_numeric( $_REQUEST['post_id'] ) ? $_REQUEST['post_id'] : 0;
44
- $field_id = isset( $_POST['field_id'] ) ? $_POST['field_id'] : 0;
45
- $attachment_ids = isset( $_POST['attachment_ids'] ) ? $_POST['attachment_ids'] : array();
46
 
47
  check_ajax_referer( "rwmb-attach-file_{$field_id}" );
48
  foreach( $attachment_ids as $attachment_id )
 
49
  add_post_meta( $post_id, $field_id, $attachment_id, false );
 
50
 
51
  wp_send_json_success();
52
  }
@@ -100,20 +102,20 @@ if ( ! class_exists( 'RWMB_File_Advanced_Field' ) )
100
  $i18n_delete = apply_filters( 'rwmb_file_delete_string', _x( 'Delete', 'file upload', 'rwmb' ) );
101
  $i18n_edit = apply_filters( 'rwmb_file_edit_string', _x( 'Edit', 'file upload', 'rwmb' ) );
102
  ?>
103
- <script id="tmpl-rwmb-file-advanced" type="text/html">
104
  <# _.each( attachments, function( attachment ) { #>
105
  <li>
106
  <div class="rwmb-icon"><img src="<# if ( attachment.type == 'image' ){ #>{{{ attachment.sizes.thumbnail.url }}}<# } else { #>{{{ attachment.icon }}}<# } #>"></div>
107
  <div class="rwmb-info">
108
  <a href="{{{ attachment.url }}}" target="_blank">{{{ attachment.title }}}</a>
109
  <p>{{{ attachment.mime }}}</p>
110
- <a title="<?php echo $i18n_edit; ?>" href="{{{ attachment.editLink }}}" target="_blank"><?php echo $i18n_edit; ?></a> |
111
- <a title="<?php echo $i18n_delete; ?>" class="rwmb-delete-file" href="#" data-attachment_id="{{{ attachment.id }}}"><?php echo $i18n_delete; ?></a>
112
  </div>
113
  </li>
114
  <# } ); #>
115
  </script>
116
- <?php
117
  }
118
  }
119
  }
40
 
41
  static function wp_ajax_attach_file()
42
  {
43
+ $post_id = isset( $_REQUEST['post_id'] ) ? intval( $_REQUEST['post_id'] ) : 0;
44
+ $field_id = isset( $_POST['field_id'] ) ? sanitize_key( $_POST['field_id'] ) : 0;
45
+ $attachment_ids = isset( $_POST['attachment_ids'] ) ? (array) $_POST['attachment_ids'] : array();
46
 
47
  check_ajax_referer( "rwmb-attach-file_{$field_id}" );
48
  foreach( $attachment_ids as $attachment_id )
49
+ {
50
  add_post_meta( $post_id, $field_id, $attachment_id, false );
51
+ }
52
 
53
  wp_send_json_success();
54
  }
102
  $i18n_delete = apply_filters( 'rwmb_file_delete_string', _x( 'Delete', 'file upload', 'rwmb' ) );
103
  $i18n_edit = apply_filters( 'rwmb_file_edit_string', _x( 'Edit', 'file upload', 'rwmb' ) );
104
  ?>
105
+ <script id="tmpl-rwmb-file-advanced" type="text/html">
106
  <# _.each( attachments, function( attachment ) { #>
107
  <li>
108
  <div class="rwmb-icon"><img src="<# if ( attachment.type == 'image' ){ #>{{{ attachment.sizes.thumbnail.url }}}<# } else { #>{{{ attachment.icon }}}<# } #>"></div>
109
  <div class="rwmb-info">
110
  <a href="{{{ attachment.url }}}" target="_blank">{{{ attachment.title }}}</a>
111
  <p>{{{ attachment.mime }}}</p>
112
+ <a title="<?php echo esc_attr( $i18n_edit ); ?>" href="{{{ attachment.editLink }}}" target="_blank"><?php echo esc_html( $i18n_edit ); ?></a> |
113
+ <a title="<?php echo esc_attr( $i18n_delete ); ?>" class="rwmb-delete-file" href="#" data-attachment_id="{{{ attachment.id }}}"><?php echo esc_html( $i18n_delete ); ?></a>
114
  </div>
115
  </li>
116
  <# } ); #>
117
  </script>
118
+ <?php
119
  }
120
  }
121
  }
inc/fields/file-input.php CHANGED
@@ -1,5 +1,5 @@
1
  <?php
2
- if ( !class_exists( 'RWMB_File_Input_Field' ) )
3
  {
4
  class RWMB_File_Input_Field extends RWMB_Field
5
  {
1
  <?php
2
+ if ( ! class_exists( 'RWMB_File_Input_Field' ) )
3
  {
4
  class RWMB_File_Input_Field extends RWMB_Field
5
  {
inc/fields/file.php CHANGED
@@ -55,7 +55,7 @@ if ( ! class_exists( 'RWMB_File_Field' ) )
55
  static function wp_ajax_delete_file()
56
  {
57
  $post_id = isset( $_POST['post_id'] ) ? intval( $_POST['post_id'] ) : 0;
58
- $field_id = isset( $_POST['field_id'] ) ? $_POST['field_id'] : 0;
59
  $attachment_id = isset( $_POST['attachment_id'] ) ? intval( $_POST['attachment_id'] ) : 0;
60
  $force_delete = isset( $_POST['force_delete'] ) ? intval( $_POST['force_delete'] ) : 0;
61
 
@@ -86,7 +86,7 @@ if ( ! class_exists( 'RWMB_File_Field' ) )
86
  // Uploaded files
87
  $html = self::get_uploaded_files( $meta, $field );
88
  $new_file_classes = array( 'new-files' );
89
- if ( !empty( $field['max_file_uploads'] ) && count( $meta ) >= (int) $field['max_file_uploads'] )
90
  $new_file_classes[] = 'hidden';
91
 
92
  // Show form upload
@@ -150,8 +150,8 @@ if ( ! class_exists( 'RWMB_File_Field' ) )
150
  $mime_type = get_post_mime_type( $attachment_id );
151
  return sprintf(
152
  $li,
153
- wp_get_attachment_image( $attachment_id, array(60,60), true ),
154
- wp_get_attachment_url($attachment_id),
155
  get_the_title( $attachment_id ),
156
  $mime_type,
157
  $i18n_edit,
55
  static function wp_ajax_delete_file()
56
  {
57
  $post_id = isset( $_POST['post_id'] ) ? intval( $_POST['post_id'] ) : 0;
58
+ $field_id = isset( $_POST['field_id'] ) ? sanitize_key( $_POST['field_id'] ) : 0;
59
  $attachment_id = isset( $_POST['attachment_id'] ) ? intval( $_POST['attachment_id'] ) : 0;
60
  $force_delete = isset( $_POST['force_delete'] ) ? intval( $_POST['force_delete'] ) : 0;
61
 
86
  // Uploaded files
87
  $html = self::get_uploaded_files( $meta, $field );
88
  $new_file_classes = array( 'new-files' );
89
+ if ( ! empty( $field['max_file_uploads'] ) && count( $meta ) >= (int) $field['max_file_uploads'] )
90
  $new_file_classes[] = 'hidden';
91
 
92
  // Show form upload
150
  $mime_type = get_post_mime_type( $attachment_id );
151
  return sprintf(
152
  $li,
153
+ wp_get_attachment_image( $attachment_id, array( 60, 60 ), true ),
154
+ wp_get_attachment_url( $attachment_id ),
155
  get_the_title( $attachment_id ),
156
  $mime_type,
157
  $i18n_edit,
inc/fields/image-advanced.php CHANGED
@@ -45,9 +45,9 @@ if ( ! class_exists( 'RWMB_Image_Advanced_Field' ) )
45
  */
46
  static function wp_ajax_attach_media()
47
  {
48
- $post_id = is_numeric( $_REQUEST['post_id'] ) ? $_REQUEST['post_id'] : 0;
49
- $field_id = isset( $_POST['field_id'] ) ? $_POST['field_id'] : 0;
50
- $attachment_ids = isset( $_POST['attachment_ids'] ) ? $_POST['attachment_ids'] : array();
51
 
52
  check_ajax_referer( "rwmb-attach-media_{$field_id}" );
53
  foreach ( $attachment_ids as $attachment_id )
@@ -106,7 +106,7 @@ if ( ! class_exists( 'RWMB_Image_Advanced_Field' ) )
106
  $i18n_delete = apply_filters( 'rwmb_image_delete_string', _x( 'Delete', 'image upload', 'rwmb' ) );
107
  $i18n_edit = apply_filters( 'rwmb_image_edit_string', _x( 'Edit', 'image upload', 'rwmb' ) );
108
  ?>
109
- <script id="tmpl-rwmb-image-advanced" type="text/html">
110
  <# _.each( attachments, function( attachment ) { #>
111
  <li id="item_{{{ attachment.id }}}">
112
  <# if ( attachment.sizes.hasOwnProperty( 'thumbnail' ) ) { #>
@@ -115,13 +115,13 @@ if ( ! class_exists( 'RWMB_Image_Advanced_Field' ) )
115
  <img src="{{{ attachment.sizes.full.url }}}">
116
  <# } #>
117
  <div class="rwmb-image-bar">
118
- <a title="<?php echo $i18n_edit; ?>" class="rwmb-edit-file" href="{{{ attachment.editLink }}}" target="_blank"><?php echo $i18n_edit; ?></a> |
119
- <a title="<?php echo $i18n_delete; ?>" class="rwmb-delete-file" href="#" data-attachment_id="{{{ attachment.id }}}">×</a>
120
  </div>
121
  </li>
122
  <# } ); #>
123
  </script>
124
- <?php
125
  }
126
 
127
  }
45
  */
46
  static function wp_ajax_attach_media()
47
  {
48
+ $post_id = isset( $_REQUEST['post_id'] ) ? intval( $_REQUEST['post_id'] ) : 0;
49
+ $field_id = isset( $_POST['field_id'] ) ? sanitize_key( $_POST['field_id'] ) : 0;
50
+ $attachment_ids = isset( $_POST['attachment_ids'] ) ? (array) $_POST['attachment_ids'] : array();
51
 
52
  check_ajax_referer( "rwmb-attach-media_{$field_id}" );
53
  foreach ( $attachment_ids as $attachment_id )
106
  $i18n_delete = apply_filters( 'rwmb_image_delete_string', _x( 'Delete', 'image upload', 'rwmb' ) );
107
  $i18n_edit = apply_filters( 'rwmb_image_edit_string', _x( 'Edit', 'image upload', 'rwmb' ) );
108
  ?>
109
+ <script id="tmpl-rwmb-image-advanced" type="text/html">
110
  <# _.each( attachments, function( attachment ) { #>
111
  <li id="item_{{{ attachment.id }}}">
112
  <# if ( attachment.sizes.hasOwnProperty( 'thumbnail' ) ) { #>
115
  <img src="{{{ attachment.sizes.full.url }}}">
116
  <# } #>
117
  <div class="rwmb-image-bar">
118
+ <a title="<?php echo esc_attr( $i18n_edit ); ?>" class="rwmb-edit-file" href="{{{ attachment.editLink }}}" target="_blank"><?php echo esc_html( $i18n_edit ); ?></a> |
119
+ <a title="<?php echo esc_attr( $i18n_delete ); ?>" class="rwmb-delete-file" href="#" data-attachment_id="{{{ attachment.id }}}">&times;</a>
120
  </div>
121
  </li>
122
  <# } ); #>
123
  </script>
124
+ <?php
125
  }
126
 
127
  }
inc/fields/image.php CHANGED
@@ -41,9 +41,9 @@ if ( ! class_exists( 'RWMB_Image_Field' ) )
41
  */
42
  static function wp_ajax_reorder_images()
43
  {
44
- $field_id = isset( $_POST['field_id'] ) ? $_POST['field_id'] : 0;
45
  $order = isset( $_POST['order'] ) ? $_POST['order'] : 0;
46
- $post_id = isset( $_POST['post_id'] ) ? (int) $_POST['post_id'] : 0;
47
 
48
  check_ajax_referer( "rwmb-reorder-images_{$field_id}" );
49
 
@@ -140,7 +140,7 @@ if ( ! class_exists( 'RWMB_Image_Field' ) )
140
  <img src="%s" />
141
  <div class="rwmb-image-bar">
142
  <a title="%s" class="rwmb-edit-file" href="%s" target="_blank">%s</a> |
143
- <a title="%s" class="rwmb-delete-file" href="#" data-attachment_id="%s">×</a>
144
  </div>
145
  </li>
146
  ';
@@ -158,26 +158,5 @@ if ( ! class_exists( 'RWMB_Image_Field' ) )
158
  );
159
  }
160
 
161
- /**
162
- * Standard meta retrieval
163
- *
164
- * @param int $post_id
165
- * @param array $field
166
- * @param bool $saved
167
- *
168
- * @return mixed
169
- */
170
- static function meta( $post_id, $saved, $field )
171
- {
172
- global $wpdb;
173
-
174
- $meta = $wpdb->get_col( $wpdb->prepare( "
175
- SELECT meta_value FROM $wpdb->postmeta
176
- WHERE post_id = %d AND meta_key = '%s'
177
- ORDER BY meta_id ASC
178
- ", $post_id, $field['id'] ) );
179
-
180
- return empty( $meta ) ? array() : $meta;
181
- }
182
  }
183
  }
41
  */
42
  static function wp_ajax_reorder_images()
43
  {
44
+ $field_id = isset( $_POST['field_id'] ) ? intval( $_POST['field_id'] ) : 0;
45
  $order = isset( $_POST['order'] ) ? $_POST['order'] : 0;
46
+ $post_id = isset( $_POST['post_id'] ) ? intval( $_POST['post_id'] ) : 0;
47
 
48
  check_ajax_referer( "rwmb-reorder-images_{$field_id}" );
49
 
140
  <img src="%s" />
141
  <div class="rwmb-image-bar">
142
  <a title="%s" class="rwmb-edit-file" href="%s" target="_blank">%s</a> |
143
+ <a title="%s" class="rwmb-delete-file" href="#" data-attachment_id="%s">&times;</a>
144
  </div>
145
  </li>
146
  ';
158
  );
159
  }
160
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
  }
162
  }
inc/fields/map.php CHANGED
@@ -2,7 +2,7 @@
2
  // Prevent loading this file directly
3
  defined( 'ABSPATH' ) || exit;
4
 
5
- if ( !class_exists( 'RWMB_Map_Field' ) )
6
  {
7
  class RWMB_Map_Field extends RWMB_Field
8
  {
2
  // Prevent loading this file directly
3
  defined( 'ABSPATH' ) || exit;
4
 
5
+ if ( ! class_exists( 'RWMB_Map_Field' ) )
6
  {
7
  class RWMB_Map_Field extends RWMB_Field
8
  {
inc/fields/number.php CHANGED
@@ -2,7 +2,7 @@
2
  // Prevent loading this file directly
3
  defined( 'ABSPATH' ) || exit;
4
 
5
- if ( !class_exists( 'RWMB_Number_Field' ) )
6
  {
7
  class RWMB_Number_Field extends RWMB_Field
8
  {
2
  // Prevent loading this file directly
3
  defined( 'ABSPATH' ) || exit;
4
 
5
+ if ( ! class_exists( 'RWMB_Number_Field' ) )
6
  {
7
  class RWMB_Number_Field extends RWMB_Field
8
  {
inc/fields/plupload-image.php CHANGED
@@ -26,8 +26,8 @@ if ( ! class_exists( 'RWMB_Plupload_Image_Field' ) )
26
  static function handle_upload()
27
  {
28
  global $wpdb;
29
- $post_id = is_numeric( $_REQUEST['post_id'] ) ? $_REQUEST['post_id'] : 0;
30
- $field_id = isset( $_REQUEST['field_id'] ) ? $_REQUEST['field_id'] : '';
31
 
32
  check_ajax_referer( "rwmb-upload-images_{$field_id}" );
33
 
@@ -36,25 +36,28 @@ if ( ! class_exists( 'RWMB_Plupload_Image_Field' ) )
36
  $file_attr = wp_handle_upload( $file, array( 'test_form' => false ) );
37
  //Get next menu_order
38
  $meta = get_post_meta( $post_id, $field_id, false );
39
- if( empty( $meta ) ){
 
40
  $next = 0;
41
- } else {
42
- $meta = implode( ',' , (array) $meta );
43
- $max = $wpdb->get_var( "
 
 
44
  SELECT MAX(menu_order) FROM {$wpdb->posts}
45
  WHERE post_type = 'attachment'
46
  AND ID in ({$meta})
47
  " );
48
- $next = is_numeric($max) ? (int) $max + 1: 0;
49
  }
50
 
51
  $attachment = array(
52
- 'guid' => $file_attr['url'],
53
- 'post_mime_type' => $file_attr['type'],
54
- 'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $file['name'] ) ),
55
- 'post_content' => '',
56
- 'post_status' => 'inherit',
57
- 'menu_order' => $next
58
  );
59
 
60
  // Adds file as attachment to WordPress
26
  static function handle_upload()
27
  {
28
  global $wpdb;
29
+ $post_id = isset( $_REQUEST['post_id'] ) ? intval( $_REQUEST['post_id'] ) : 0;
30
+ $field_id = isset( $_REQUEST['field_id'] ) ? sanitize_key( $_REQUEST['field_id'] ) : '';
31
 
32
  check_ajax_referer( "rwmb-upload-images_{$field_id}" );
33
 
36
  $file_attr = wp_handle_upload( $file, array( 'test_form' => false ) );
37
  //Get next menu_order
38
  $meta = get_post_meta( $post_id, $field_id, false );
39
+ if ( empty( $meta ) )
40
+ {
41
  $next = 0;
42
+ }
43
+ else
44
+ {
45
+ $meta = implode( ',', (array) $meta );
46
+ $max = $wpdb->get_var( "
47
  SELECT MAX(menu_order) FROM {$wpdb->posts}
48
  WHERE post_type = 'attachment'
49
  AND ID in ({$meta})
50
  " );
51
+ $next = is_numeric( $max ) ? (int) $max + 1 : 0;
52
  }
53
 
54
  $attachment = array(
55
+ 'guid' => $file_attr['url'],
56
+ 'post_mime_type' => $file_attr['type'],
57
+ 'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $file['name'] ) ),
58
+ 'post_content' => '',
59
+ 'post_status' => 'inherit',
60
+ 'menu_order' => $next,
61
  );
62
 
63
  // Adds file as attachment to WordPress
inc/fields/post.php CHANGED
@@ -5,7 +5,7 @@ defined( 'ABSPATH' ) || exit;
5
  // Make sure "select" field is loaded
6
  require_once RWMB_FIELDS_DIR . 'select-advanced.php';
7
 
8
- if ( !class_exists( 'RWMB_Post_Field' ) )
9
  {
10
  class RWMB_Post_Field extends RWMB_Field
11
  {
@@ -60,7 +60,7 @@ if ( !class_exists( 'RWMB_Post_Field' ) )
60
  'post_type' => 'post',
61
  'field_type' => 'select_advanced',
62
  'parent' => false,
63
- 'query_args' => array()
64
  ) );
65
 
66
  $field['std'] = empty( $field['std'] ) ? sprintf( __( 'Select a %s', 'rwmb' ), $default_post_type ) : $field['std'];
@@ -74,7 +74,7 @@ if ( !class_exists( 'RWMB_Post_Field' ) )
74
  $field['query_args'] = wp_parse_args( $field['query_args'], array(
75
  'post_type' => $field['post_type'],
76
  'post_status' => 'publish',
77
- 'posts_per_page' => '-1'
78
  ) );
79
 
80
  switch ( $field['field_type'] )
5
  // Make sure "select" field is loaded
6
  require_once RWMB_FIELDS_DIR . 'select-advanced.php';
7
 
8
+ if ( ! class_exists( 'RWMB_Post_Field' ) )
9
  {
10
  class RWMB_Post_Field extends RWMB_Field
11
  {
60
  'post_type' => 'post',
61
  'field_type' => 'select_advanced',
62
  'parent' => false,
63
+ 'query_args' => array(),
64
  ) );
65
 
66
  $field['std'] = empty( $field['std'] ) ? sprintf( __( 'Select a %s', 'rwmb' ), $default_post_type ) : $field['std'];
74
  $field['query_args'] = wp_parse_args( $field['query_args'], array(
75
  'post_type' => $field['post_type'],
76
  'post_status' => 'publish',
77
+ 'posts_per_page' => -1,
78
  ) );
79
 
80
  switch ( $field['field_type'] )
inc/fields/range.php CHANGED
@@ -2,7 +2,7 @@
2
  // Prevent loading this file directly
3
  defined( 'ABSPATH' ) || exit;
4
 
5
- if ( !class_exists( 'RWMB_Range_Field' ) )
6
  {
7
  class RWMB_Range_Field extends RWMB_Field
8
  {
@@ -49,7 +49,7 @@ if ( !class_exists( 'RWMB_Range_Field' ) )
49
  $field = wp_parse_args( $field, array(
50
  'min' => 0,
51
  'max' => 10,
52
- 'step' => 1
53
  ) );
54
  return $field;
55
  }
@@ -66,14 +66,16 @@ if ( !class_exists( 'RWMB_Range_Field' ) )
66
  */
67
  static function value( $new, $old, $post_id, $field )
68
  {
69
- $new = intval($new);
70
- $min = intval($field['min']);
71
- $max = intval($field['max']);
72
 
73
- if ($new < $min) {
 
74
  return $min;
75
  }
76
- else if ($new > $max) {
 
77
  return $max;
78
  }
79
 
2
  // Prevent loading this file directly
3
  defined( 'ABSPATH' ) || exit;
4
 
5
+ if ( ! class_exists( 'RWMB_Range_Field' ) )
6
  {
7
  class RWMB_Range_Field extends RWMB_Field
8
  {
49
  $field = wp_parse_args( $field, array(
50
  'min' => 0,
51
  'max' => 10,
52
+ 'step' => 1,
53
  ) );
54
  return $field;
55
  }
66
  */
67
  static function value( $new, $old, $post_id, $field )
68
  {
69
+ $new = intval( $new );
70
+ $min = intval( $field['min'] );
71
+ $max = intval( $field['max'] );
72
 
73
+ if ( $new < $min )
74
+ {
75
  return $min;
76
  }
77
+ elseif ( $new > $max )
78
+ {
79
  return $max;
80
  }
81
 
inc/fields/select-advanced.php CHANGED
@@ -5,7 +5,7 @@ defined( 'ABSPATH' ) || exit;
5
  // Make sure "select" field is loaded
6
  require_once RWMB_FIELDS_DIR . 'select.php';
7
 
8
- if ( !class_exists( 'RWMB_Select_Advanced_Field' ) )
9
  {
10
  class RWMB_Select_Advanced_Field extends RWMB_Select_Field
11
  {
5
  // Make sure "select" field is loaded
6
  require_once RWMB_FIELDS_DIR . 'select.php';
7
 
8
+ if ( ! class_exists( 'RWMB_Select_Advanced_Field' ) )
9
  {
10
  class RWMB_Select_Advanced_Field extends RWMB_Select_Field
11
  {
inc/fields/select.php CHANGED
@@ -2,7 +2,7 @@
2
  // Prevent loading this file directly
3
  defined( 'ABSPATH' ) || exit;
4
 
5
- if ( !class_exists( 'RWMB_Select_Field' ) )
6
  {
7
  class RWMB_Select_Field extends RWMB_Field
8
  {
@@ -58,9 +58,9 @@ if ( !class_exists( 'RWMB_Select_Field' ) )
58
  */
59
  static function meta( $post_id, $saved, $field )
60
  {
61
- $single = $field['clone'] || !$field['multiple'];
62
- $meta = get_post_meta( $post_id, $field['id'], $single );
63
- $meta = ( !$saved && '' === $meta || array() === $meta ) ? $field['std'] : $meta;
64
 
65
  $meta = array_map( 'esc_attr', (array) $meta );
66
 
@@ -81,9 +81,10 @@ if ( !class_exists( 'RWMB_Select_Field' ) )
81
  */
82
  static function save( $new, $old, $post_id, $field )
83
  {
84
- if ( !$field['clone'] )
85
  {
86
  parent::save( $new, $old, $post_id, $field );
 
87
  return;
88
  }
89
 
@@ -108,8 +109,9 @@ if ( !class_exists( 'RWMB_Select_Field' ) )
108
  'size' => $field['multiple'] ? 5 : 0,
109
  'placeholder' => '',
110
  ) );
111
- if ( !$field['clone'] && $field['multiple'] )
112
  $field['field_name'] .= '[]';
 
113
  return $field;
114
  }
115
 
2
  // Prevent loading this file directly
3
  defined( 'ABSPATH' ) || exit;
4
 
5
+ if ( ! class_exists( 'RWMB_Select_Field' ) )
6
  {
7
  class RWMB_Select_Field extends RWMB_Field
8
  {
58
  */
59
  static function meta( $post_id, $saved, $field )
60
  {
61
+ $single = $field['clone'] || ! $field['multiple'];
62
+ $meta = get_post_meta( $post_id, $field['id'], $single );
63
+ $meta = ( ! $saved && '' === $meta || array() === $meta ) ? $field['std'] : $meta;
64
 
65
  $meta = array_map( 'esc_attr', (array) $meta );
66
 
81
  */
82
  static function save( $new, $old, $post_id, $field )
83
  {
84
+ if ( ! $field['clone'] )
85
  {
86
  parent::save( $new, $old, $post_id, $field );
87
+
88
  return;
89
  }
90
 
109
  'size' => $field['multiple'] ? 5 : 0,
110
  'placeholder' => '',
111
  ) );
112
+ if ( ! $field['clone'] && $field['multiple'] )
113
  $field['field_name'] .= '[]';
114
+
115
  return $field;
116
  }
117
 
inc/fields/slider.php CHANGED
@@ -2,7 +2,7 @@
2
  // Prevent loading this file directly
3
  defined( 'ABSPATH' ) || exit;
4
 
5
- if ( !class_exists( 'RWMB_Slider_Field' ) )
6
  {
7
  class RWMB_Slider_Field extends RWMB_Field
8
  {
2
  // Prevent loading this file directly
3
  defined( 'ABSPATH' ) || exit;
4
 
5
+ if ( ! class_exists( 'RWMB_Slider_Field' ) )
6
  {
7
  class RWMB_Slider_Field extends RWMB_Field
8
  {
inc/fields/text-list.php CHANGED
@@ -2,7 +2,7 @@
2
  // Prevent loading this file directly
3
  defined( 'ABSPATH' ) || exit;
4
 
5
- if ( !class_exists( 'RWMB_Text_List_Field' ) )
6
  {
7
  class RWMB_Text_List_Field extends RWMB_Field
8
  {
@@ -16,21 +16,23 @@ if ( !class_exists( 'RWMB_Text_List_Field' ) )
16
  */
17
  static function html( $meta, $field )
18
  {
19
- $html = array();
20
- $tpl = '<label><input type="text" class="rwmb-text-list" name="%s" id="%s" value="%s" placeholder="%s"/> %s</label>';
21
 
 
22
  foreach ( $field['options'] as $value => $label )
23
- {
24
- $html[] = sprintf(
25
- $tpl,
26
  $field['field_name'],
27
  $field['id'],
 
28
  $value,
29
- $field['placeholder'],
30
  $label
31
  );
 
32
  }
33
- return implode( ' ', $html );
34
  }
35
 
36
  /**
@@ -50,8 +52,10 @@ if ( !class_exists( 'RWMB_Text_List_Field' ) )
50
  */
51
  static function meta( $post_id, $saved, $field )
52
  {
53
- $meta = get_post_meta( $post_id, $field['id'], $field['clone'] );
54
- $meta = ( !$saved && '' === $meta || array() === $meta ) ? $field['std'] : $meta;
 
 
55
  $meta = array_map( 'esc_attr', (array) $meta );
56
 
57
  return $meta;
@@ -71,9 +75,10 @@ if ( !class_exists( 'RWMB_Text_List_Field' ) )
71
  */
72
  static function save( $new, $old, $post_id, $field )
73
  {
74
- if ( !$field['clone'] )
75
  {
76
  parent::save( $new, $old, $post_id, $field );
 
77
  return;
78
  }
79
 
@@ -92,10 +97,11 @@ if ( !class_exists( 'RWMB_Text_List_Field' ) )
92
  */
93
  static function normalize_field( $field )
94
  {
95
- $field['multiple'] = true;
96
  $field['field_name'] = $field['id'];
97
- if ( !$field['clone'] )
98
  $field['field_name'] .= '[]';
 
99
  return $field;
100
  }
101
  }
2
  // Prevent loading this file directly
3
  defined( 'ABSPATH' ) || exit;
4
 
5
+ if ( ! class_exists( 'RWMB_Text_List_Field' ) )
6
  {
7
  class RWMB_Text_List_Field extends RWMB_Field
8
  {
16
  */
17
  static function html( $meta, $field )
18
  {
19
+ $html = '';
20
+ $input = '<label><input type="text" class="rwmb-text-list" name="%s" id="%s" value="%s" placeholder="%s" /> %s</label>';
21
 
22
+ $i = 0;
23
  foreach ( $field['options'] as $value => $label )
24
+ {
25
+ $html .= sprintf(
26
+ $input,
27
  $field['field_name'],
28
  $field['id'],
29
+ $meta[$i],
30
  $value,
 
31
  $label
32
  );
33
+ $i++;
34
  }
35
+ return $html;
36
  }
37
 
38
  /**
52
  */
53
  static function meta( $post_id, $saved, $field )
54
  {
55
+ $single = $field['clone'] || ! $field['multiple'];
56
+ $meta = get_post_meta( $post_id, $field['id'], $single );
57
+ $meta = ( ! $saved && '' === $meta || array() === $meta ) ? $field['std'] : $meta;
58
+
59
  $meta = array_map( 'esc_attr', (array) $meta );
60
 
61
  return $meta;
75
  */
76
  static function save( $new, $old, $post_id, $field )
77
  {
78
+ if ( ! $field['clone'] )
79
  {
80
  parent::save( $new, $old, $post_id, $field );
81
+
82
  return;
83
  }
84
 
97
  */
98
  static function normalize_field( $field )
99
  {
100
+ $field['multiple'] = true;
101
  $field['field_name'] = $field['id'];
102
+ if ( ! $field['clone'] )
103
  $field['field_name'] .= '[]';
104
+
105
  return $field;
106
  }
107
  }
inc/fields/text.php CHANGED
@@ -9,8 +9,8 @@ if ( ! class_exists( 'RWMB_Text_Field' ) )
9
  /**
10
  * Get field HTML
11
  *
12
- * @param mixed $meta
13
- * @param array $field
14
  *
15
  * @return string
16
  */
@@ -23,8 +23,8 @@ if ( ! class_exists( 'RWMB_Text_Field' ) )
23
  $meta,
24
  $field['placeholder'],
25
  $field['size'],
26
- !$field['datalist'] ? '' : "list='{$field['datalist']['id']}'",
27
- self::datalist_html($field)
28
  );
29
  }
30
 
@@ -42,6 +42,7 @@ if ( ! class_exists( 'RWMB_Text_Field' ) )
42
  'datalist' => false,
43
  'placeholder' => '',
44
  ) );
 
45
  return $field;
46
  }
47
 
@@ -54,16 +55,18 @@ if ( ! class_exists( 'RWMB_Text_Field' ) )
54
  */
55
  static function datalist_html( $field )
56
  {
57
- if( !$field['datalist'] )
58
  return '';
 
59
  $datalist = $field['datalist'];
60
- $html = sprintf(
61
  '<datalist id="%s">',
62
  $datalist['id']
63
  );
64
 
65
- foreach( $datalist['options'] as $option ) {
66
- $html.= sprintf('<option value="%s"></option>', $option);
 
67
  }
68
 
69
  $html .= '</datalist>';
9
  /**
10
  * Get field HTML
11
  *
12
+ * @param mixed $meta
13
+ * @param array $field
14
  *
15
  * @return string
16
  */
23
  $meta,
24
  $field['placeholder'],
25
  $field['size'],
26
+ $field['datalist'] ? "list='{$field['datalist']['id']}'" : '',
27
+ self::datalist_html( $field )
28
  );
29
  }
30
 
42
  'datalist' => false,
43
  'placeholder' => '',
44
  ) );
45
+
46
  return $field;
47
  }
48
 
55
  */
56
  static function datalist_html( $field )
57
  {
58
+ if ( ! $field['datalist'] )
59
  return '';
60
+
61
  $datalist = $field['datalist'];
62
+ $html = sprintf(
63
  '<datalist id="%s">',
64
  $datalist['id']
65
  );
66
 
67
+ foreach ( $datalist['options'] as $option )
68
+ {
69
+ $html .= sprintf( '<option value="%s"></option>', $option );
70
  }
71
 
72
  $html .= '</datalist>';
inc/fields/url.php CHANGED
@@ -39,7 +39,7 @@ if ( ! class_exists( 'RWMB_URL_Field' ) )
39
  *
40
  * @return string
41
  */
42
- static function value( $new, $old, $post_id, $field)
43
  {
44
  return is_array( $new ) ? array_map( 'esc_url', $new ) : esc_url( $new );
45
  }
39
  *
40
  * @return string
41
  */
42
+ static function value( $new, $old, $post_id, $field )
43
  {
44
  return is_array( $new ) ? array_map( 'esc_url', $new ) : esc_url( $new );
45
  }
inc/fields/user.php ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Prevent loading this file directly
3
+ defined( 'ABSPATH' ) || exit;
4
+
5
+ // Make sure "select" field is loaded
6
+ require_once RWMB_FIELDS_DIR . 'select-advanced.php';
7
+
8
+ if ( ! class_exists( 'RWMB_User_Field' ) )
9
+ {
10
+ class RWMB_User_Field extends RWMB_Field
11
+ {
12
+ /**
13
+ * Enqueue scripts and styles
14
+ *
15
+ * @return void
16
+ */
17
+ static function admin_enqueue_scripts()
18
+ {
19
+ RWMB_Select_Advanced_Field::admin_enqueue_scripts();
20
+ }
21
+
22
+ /**
23
+ * Get field HTML
24
+ *
25
+ * @param mixed $meta
26
+ * @param array $field
27
+ *
28
+ * @return string
29
+ */
30
+ static function html( $meta, $field )
31
+ {
32
+ $field['options'] = self::get_options( $field );
33
+ switch ( $field['field_type'] )
34
+ {
35
+ case 'select':
36
+ return RWMB_Select_Field::html( $meta, $field );
37
+ break;
38
+ case 'select_advanced':
39
+ default:
40
+ return RWMB_Select_Advanced_Field::html( $meta, $field );
41
+ }
42
+ }
43
+
44
+ /**
45
+ * Normalize parameters for field
46
+ *
47
+ * @param array $field
48
+ *
49
+ * @return array
50
+ */
51
+ static function normalize_field( $field )
52
+ {
53
+
54
+ $default_post_type = __( 'User', 'rwmb' );
55
+
56
+ $field = wp_parse_args( $field, array(
57
+ 'field_type' => 'select_advanced',
58
+ 'parent' => false,
59
+ 'query_args' => array(),
60
+ ) );
61
+
62
+ $field['std'] = empty( $field['std'] ) ? sprintf( __( 'Select a %s', 'rwmb' ), $default_post_type ) : $field['std'];
63
+
64
+ $field['query_args'] = wp_parse_args( $field['query_args'], array(
65
+ 'orderby' => 'display_name',
66
+ 'order' => 'asc',
67
+ 'role' => '',
68
+ 'fields' => 'all',
69
+ ) );
70
+
71
+ switch ( $field['field_type'] )
72
+ {
73
+ case 'select':
74
+ return RWMB_Select_Field::normalize_field( $field );
75
+ break;
76
+ case 'select_advanced':
77
+ default:
78
+ return RWMB_Select_Advanced_Field::normalize_field( $field );
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Get meta value
84
+ * If field is cloneable, value is saved as a single entry in DB
85
+ * Otherwise value is saved as multiple entries (for backward compatibility)
86
+ *
87
+ * @see "save" method for better understanding
88
+ *
89
+ * @param $post_id
90
+ * @param $saved
91
+ * @param $field
92
+ *
93
+ * @return array
94
+ */
95
+ static function meta( $post_id, $saved, $field )
96
+ {
97
+ if ( isset( $field['parent'] ) && $field['parent'] )
98
+ {
99
+ $post = get_post( $post_id );
100
+ return $post->post_parent;
101
+ }
102
+ return RWMB_Select_Field::meta( $post_id, $saved, $field );
103
+ }
104
+
105
+ /**
106
+ * Save meta value
107
+ * If field is cloneable, value is saved as a single entry in DB
108
+ * Otherwise value is saved as multiple entries (for backward compatibility)
109
+ *
110
+ * TODO: A good way to ALWAYS save values in single entry in DB, while maintaining backward compatibility
111
+ *
112
+ * @param $new
113
+ * @param $old
114
+ * @param $post_id
115
+ * @param $field
116
+ */
117
+ static function save( $new, $old, $post_id, $field )
118
+ {
119
+ return RWMB_Select_Field::save( $new, $old, $post_id, $field );
120
+ }
121
+
122
+ /**
123
+ * Get users
124
+ *
125
+ * @param array $field
126
+ *
127
+ * @return array
128
+ */
129
+ static function get_options( $field )
130
+ {
131
+ $results = get_users( $field['query_args'] );
132
+ $options = array();
133
+ foreach ( $results as $result )
134
+ {
135
+ $options[$result->ID] = $result->display_name ;
136
+ }
137
+ return $options;
138
+ }
139
+ }
140
+ }
inc/fields/wysiwyg.php CHANGED
@@ -2,10 +2,12 @@
2
  // Prevent loading this file directly
3
  defined( 'ABSPATH' ) || exit;
4
 
5
- if ( !class_exists( 'RWMB_Wysiwyg_Field' ) )
6
  {
7
  class RWMB_Wysiwyg_Field extends RWMB_Field
8
  {
 
 
9
  /**
10
  * Enqueue scripts and styles
11
  *
@@ -28,7 +30,20 @@ if ( !class_exists( 'RWMB_Wysiwyg_Field' ) )
28
  */
29
  static function value( $new, $old, $post_id, $field )
30
  {
31
- return ( $field['raw'] ? $new : wpautop( $new ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  }
33
 
34
  /**
@@ -47,9 +62,16 @@ if ( !class_exists( 'RWMB_Wysiwyg_Field' ) )
47
  $field['options']['textarea_name'] = $field['field_name'];
48
 
49
  // Use new wp_editor() since WP 3.3
50
- wp_editor( $meta, $field['id'], $field['options'] );
 
 
 
 
 
 
 
51
 
52
- return ob_get_clean();
53
  }
54
 
55
  /**
@@ -76,5 +98,9 @@ if ( !class_exists( 'RWMB_Wysiwyg_Field' ) )
76
 
77
  return $field;
78
  }
 
 
 
 
79
  }
80
- }
2
  // Prevent loading this file directly
3
  defined( 'ABSPATH' ) || exit;
4
 
5
+ if ( ! class_exists( 'RWMB_Wysiwyg_Field' ) )
6
  {
7
  class RWMB_Wysiwyg_Field extends RWMB_Field
8
  {
9
+
10
+ static $cloneable_editors = array();
11
  /**
12
  * Enqueue scripts and styles
13
  *
30
  */
31
  static function value( $new, $old, $post_id, $field )
32
  {
33
+ if ( $field['raw'] )
34
+ {
35
+ $meta = $new;
36
+ }
37
+ else if ( $field['clone'] )
38
+ {
39
+ $meta = array_map( 'wpautop', $new );
40
+ }
41
+ else
42
+ {
43
+ $meta = wpautop( $new );
44
+ }
45
+
46
+ return $meta;
47
  }
48
 
49
  /**
62
  $field['options']['textarea_name'] = $field['field_name'];
63
 
64
  // Use new wp_editor() since WP 3.3
65
+ wp_editor( $meta, $field['field_name'], $field['options'] );
66
+
67
+ $editor = ob_get_clean();
68
+ if ( $field['clone'] )
69
+ {
70
+ self::$cloneable_editors[$field['id']] = $editor;
71
+ add_action( 'admin_print_footer_scripts', array( __CLASS__, 'footer_scripts' ), 51 );
72
+ }
73
 
74
+ return $editor;
75
  }
76
 
77
  /**
98
 
99
  return $field;
100
  }
101
+
102
+ static function footer_scripts() {
103
+ echo '<script> var rwmb_cloneable_editors = ' . json_encode( self::$cloneable_editors ) . ';</script>';
104
+ }
105
  }
106
+ }
inc/helpers.php CHANGED
@@ -134,19 +134,20 @@ if ( ! class_exists( 'RWMB_Helper' ) )
134
  $post_id = empty( $post_id ) ? get_the_ID() : $post_id;
135
 
136
  $args = wp_parse_args( $args, array(
137
- 'type' => 'text',
138
- ) );
 
139
 
140
  // Set 'multiple' for fields based on 'type'
141
- if ( !isset( $args['multiple'] ) )
142
  $args['multiple'] = in_array( $args['type'], array( 'checkbox_list', 'file', 'file_advanced', 'image', 'image_advanced', 'plupload_image', 'thickbox_image' ) );
143
 
144
- $meta = get_post_meta( $post_id, $key, !$args['multiple'] );
145
 
146
  // Get uploaded files info
147
  if ( in_array( $args['type'], array( 'file', 'file_advanced' ) ) )
148
  {
149
- if ( is_array( $meta ) && !empty( $meta ) )
150
  {
151
  $files = array();
152
  foreach ( $meta as $id )
@@ -168,7 +169,7 @@ if ( ! class_exists( 'RWMB_Helper' ) )
168
  ORDER BY meta_id ASC
169
  ", $post_id, $key ) );
170
 
171
- if ( is_array( $meta ) && !empty( $meta ) )
172
  {
173
  $images = array();
174
  foreach ( $meta as $id )
@@ -182,7 +183,7 @@ if ( ! class_exists( 'RWMB_Helper' ) )
182
  // Get terms
183
  elseif ( 'taxonomy_advanced' == $args['type'] )
184
  {
185
- if ( !empty( $args['taxonomy'] ) )
186
  {
187
  $term_ids = array_map( 'intval', array_filter( explode( ',', $meta . ',' ) ) );
188
 
@@ -281,8 +282,8 @@ if ( ! class_exists( 'RWMB_Helper' ) )
281
  static function map( $key, $args = array(), $post_id = null )
282
  {
283
  $post_id = empty( $post_id ) ? get_the_ID() : $post_id;
284
- $loc = get_post_meta( $post_id, $key, true );
285
- if ( !$loc )
286
  return '';
287
 
288
  $parts = array_map( 'trim', explode( ',', $loc ) );
@@ -295,9 +296,9 @@ if ( ! class_exists( 'RWMB_Helper' ) )
295
  $args = wp_parse_args( $args, array(
296
  'width' => '640px',
297
  'height' => '480px',
298
- 'marker' => true, // Display marker?
299
- 'marker_title' => '', // Marker title, when hover
300
- 'info_window' => '', // Content of info window (when click on marker). HTML allowed
301
  'js_options' => array(),
302
  ) );
303
  $args['js_options'] = wp_parse_args( $args['js_options'], array(
134
  $post_id = empty( $post_id ) ? get_the_ID() : $post_id;
135
 
136
  $args = wp_parse_args( $args, array(
137
+ 'type' => 'text',
138
+ )
139
+ );
140
 
141
  // Set 'multiple' for fields based on 'type'
142
+ if ( ! isset( $args['multiple'] ) )
143
  $args['multiple'] = in_array( $args['type'], array( 'checkbox_list', 'file', 'file_advanced', 'image', 'image_advanced', 'plupload_image', 'thickbox_image' ) );
144
 
145
+ $meta = get_post_meta( $post_id, $key, ! $args['multiple'] );
146
 
147
  // Get uploaded files info
148
  if ( in_array( $args['type'], array( 'file', 'file_advanced' ) ) )
149
  {
150
+ if ( is_array( $meta ) && ! empty( $meta ) )
151
  {
152
  $files = array();
153
  foreach ( $meta as $id )
169
  ORDER BY meta_id ASC
170
  ", $post_id, $key ) );
171
 
172
+ if ( is_array( $meta ) && ! empty( $meta ) )
173
  {
174
  $images = array();
175
  foreach ( $meta as $id )
183
  // Get terms
184
  elseif ( 'taxonomy_advanced' == $args['type'] )
185
  {
186
+ if ( ! empty( $args['taxonomy'] ) )
187
  {
188
  $term_ids = array_map( 'intval', array_filter( explode( ',', $meta . ',' ) ) );
189
 
282
  static function map( $key, $args = array(), $post_id = null )
283
  {
284
  $post_id = empty( $post_id ) ? get_the_ID() : $post_id;
285
+ $loc = get_post_meta( $post_id, $key, true );
286
+ if ( ! $loc )
287
  return '';
288
 
289
  $parts = array_map( 'trim', explode( ',', $loc ) );
296
  $args = wp_parse_args( $args, array(
297
  'width' => '640px',
298
  'height' => '480px',
299
+ 'marker' => true, // Display marker?
300
+ 'marker_title' => '', // Marker title, when hover
301
+ 'info_window' => '', // Content of info window (when click on marker). HTML allowed
302
  'js_options' => array(),
303
  ) );
304
  $args['js_options'] = wp_parse_args( $args['js_options'], array(
inc/meta-box.php CHANGED
@@ -36,6 +36,9 @@ if ( ! class_exists( 'RW_Meta_Box' ) )
36
  */
37
  public $validation;
38
 
 
 
 
39
  public $saved = false;
40
 
41
  /**
@@ -64,7 +67,7 @@ if ( ! class_exists( 'RW_Meta_Box' ) )
64
  $show = true;
65
  $show = apply_filters( 'rwmb_show', $show, $this->meta_box );
66
  $show = apply_filters( "rwmb_show_{$this->meta_box['id']}", $show, $this->meta_box );
67
- if ( !$show )
68
  return;
69
 
70
  // Enqueue common styles and scripts
@@ -221,8 +224,8 @@ if ( ! class_exists( 'RW_Meta_Box' ) )
221
  // Allow users to add custom code before meta box content
222
  // 1st action applies to all meta boxes
223
  // 2nd action applies to only current meta box
224
- do_action( 'rwmb_before' );
225
- do_action( "rwmb_before_{$this->meta_box['id']}" );
226
 
227
  foreach ( $this->fields as $field )
228
  {
@@ -238,14 +241,14 @@ if ( ! class_exists( 'RW_Meta_Box' ) )
238
  {
239
  var rwmb = {
240
  validationOptions : jQuery.parseJSON( \'' . json_encode( $this->validation ) . '\' ),
241
- summaryMessage : "' . __( 'Please correct the errors highlighted below and try again.', 'rwmb' ) . '"
242
  };
243
  }
244
  else
245
  {
246
  var tempOptions = jQuery.parseJSON( \'' . json_encode( $this->validation ) . '\' );
247
  jQuery.extend( true, rwmb.validationOptions, tempOptions );
248
- };
249
  </script>
250
  ';
251
  }
@@ -253,8 +256,8 @@ if ( ! class_exists( 'RW_Meta_Box' ) )
253
  // Allow users to add custom code after meta box content
254
  // 1st action applies to all meta boxes
255
  // 2nd action applies to only current meta box
256
- do_action( 'rwmb_after' );
257
- do_action( "rwmb_after_{$this->meta_box['id']}" );
258
 
259
  // End container
260
  echo '</div>';
@@ -280,11 +283,12 @@ if ( ! class_exists( 'RW_Meta_Box' ) )
280
 
281
  // Check whether form is submitted properly
282
  $id = $this->meta_box['id'];
283
- if ( empty( $_POST["nonce_{$id}"] ) || !wp_verify_nonce( $_POST["nonce_{$id}"], "rwmb-save-{$id}" ) )
 
284
  return;
285
 
286
  // Autosave
287
- if ( defined( 'DOING_AUTOSAVE' ) && !$this->meta_box['autosave'] )
288
  return;
289
 
290
  // Make sure meta is added to the post, not a revision
@@ -298,7 +302,7 @@ if ( ! class_exists( 'RW_Meta_Box' ) )
298
  foreach ( $this->fields as $field )
299
  {
300
  $name = $field['id'];
301
- $old = get_post_meta( $post_id, $name, !$field['multiple'] );
302
  $new = isset( $_POST[$name] ) ? $_POST[$name] : ( $field['multiple'] ? array() : '' );
303
 
304
  // Allow field class change the value
@@ -317,9 +321,6 @@ if ( ! class_exists( 'RW_Meta_Box' ) )
317
  // After save action
318
  do_action( 'rwmb_after_save_post', $post_id );
319
  do_action( "rwmb_{$this->meta_box['id']}_after_save_post", $post_id );
320
-
321
- // Done saving post meta
322
- $called = false;
323
  }
324
 
325
  /**************************************************
@@ -348,6 +349,10 @@ if ( ! class_exists( 'RW_Meta_Box' ) )
348
  // Set default values for fields
349
  $meta_box['fields'] = self::normalize_fields( $meta_box['fields'] );
350
 
 
 
 
 
351
  return $meta_box;
352
  }
353
 
@@ -372,14 +377,27 @@ if ( ! class_exists( 'RW_Meta_Box' ) )
372
  'after' => '',
373
  'field_name' => isset( $field['id'] ) ? $field['id'] : '',
374
  'required' => false,
375
- 'placeholder' => ''
376
  ) );
377
 
 
 
 
 
378
  // Allow field class add/change default field values
379
  $field = call_user_func( array( self::get_class_name( $field ), 'normalize_field' ), $field );
380
 
381
  if ( isset( $field['fields'] ) )
382
  $field['fields'] = self::normalize_fields( $field['fields'] );
 
 
 
 
 
 
 
 
 
383
  }
384
 
385
  return $fields;
@@ -418,9 +436,9 @@ if ( ! class_exists( 'RW_Meta_Box' ) )
418
  {
419
  foreach ( $fields as $field )
420
  {
421
- $value = get_post_meta( $post_id, $field['id'], !$field['multiple'] );
422
  if (
423
- ( !$field['multiple'] && '' !== $value )
424
  || ( $field['multiple'] && array() !== $value )
425
  )
426
  {
36
  */
37
  public $validation;
38
 
39
+ /**
40
+ * @var bool Used to prevent duplicated calls like revisions, manual hook to wp_insert_post, etc.
41
+ */
42
  public $saved = false;
43
 
44
  /**
67
  $show = true;
68
  $show = apply_filters( 'rwmb_show', $show, $this->meta_box );
69
  $show = apply_filters( "rwmb_show_{$this->meta_box['id']}", $show, $this->meta_box );
70
+ if ( ! $show )
71
  return;
72
 
73
  // Enqueue common styles and scripts
224
  // Allow users to add custom code before meta box content
225
  // 1st action applies to all meta boxes
226
  // 2nd action applies to only current meta box
227
+ do_action( 'rwmb_before', $this );
228
+ do_action( "rwmb_before_{$this->meta_box['id']}", $this );
229
 
230
  foreach ( $this->fields as $field )
231
  {
241
  {
242
  var rwmb = {
243
  validationOptions : jQuery.parseJSON( \'' . json_encode( $this->validation ) . '\' ),
244
+ summaryMessage : "' . esc_js( __( 'Please correct the errors highlighted below and try again.', 'rwmb' ) ) . '"
245
  };
246
  }
247
  else
248
  {
249
  var tempOptions = jQuery.parseJSON( \'' . json_encode( $this->validation ) . '\' );
250
  jQuery.extend( true, rwmb.validationOptions, tempOptions );
251
+ }
252
  </script>
253
  ';
254
  }
256
  // Allow users to add custom code after meta box content
257
  // 1st action applies to all meta boxes
258
  // 2nd action applies to only current meta box
259
+ do_action( 'rwmb_after', $this );
260
+ do_action( "rwmb_after_{$this->meta_box['id']}", $this );
261
 
262
  // End container
263
  echo '</div>';
283
 
284
  // Check whether form is submitted properly
285
  $id = $this->meta_box['id'];
286
+ $nonce = isset( $_POST["nonce_{$id}"] ) ? sanitize_key( $_POST["nonce_{$id}"] ) : '';
287
+ if ( empty( $_POST["nonce_{$id}"] ) || ! wp_verify_nonce( $nonce, "rwmb-save-{$id}" ) )
288
  return;
289
 
290
  // Autosave
291
+ if ( defined( 'DOING_AUTOSAVE' ) && ! $this->meta_box['autosave'] )
292
  return;
293
 
294
  // Make sure meta is added to the post, not a revision
302
  foreach ( $this->fields as $field )
303
  {
304
  $name = $field['id'];
305
+ $old = get_post_meta( $post_id, $name, ! $field['multiple'] );
306
  $new = isset( $_POST[$name] ) ? $_POST[$name] : ( $field['multiple'] ? array() : '' );
307
 
308
  // Allow field class change the value
321
  // After save action
322
  do_action( 'rwmb_after_save_post', $post_id );
323
  do_action( "rwmb_{$this->meta_box['id']}_after_save_post", $post_id );
 
 
 
324
  }
325
 
326
  /**************************************************
349
  // Set default values for fields
350
  $meta_box['fields'] = self::normalize_fields( $meta_box['fields'] );
351
 
352
+ // Allow to add default values for meta box
353
+ $meta_box = apply_filters( 'rwmb_normalize_meta_box', $meta_box );
354
+ $meta_box = apply_filters( "rwmb_normalize_{$meta_box['id']}_meta_box", $meta_box );
355
+
356
  return $meta_box;
357
  }
358
 
377
  'after' => '',
378
  'field_name' => isset( $field['id'] ) ? $field['id'] : '',
379
  'required' => false,
380
+ 'placeholder' => '',
381
  ) );
382
 
383
+ do_action( 'rwmb_before_normalize_field', $field );
384
+ do_action( "rwmb_before_normalize_{$field['type']}_field", $field );
385
+ do_action( "rwmb_before_normalize_{$field['id']}_field", $field );
386
+
387
  // Allow field class add/change default field values
388
  $field = call_user_func( array( self::get_class_name( $field ), 'normalize_field' ), $field );
389
 
390
  if ( isset( $field['fields'] ) )
391
  $field['fields'] = self::normalize_fields( $field['fields'] );
392
+
393
+ // Allow to add default values for fields
394
+ $field = apply_filters( 'rwmb_normalize_field', $field );
395
+ $field = apply_filters( "rwmb_normalize_{$field['type']}_field", $field );
396
+ $field = apply_filters( "rwmb_normalize_{$field['id']}_field", $field );
397
+
398
+ do_action( 'rwmb_after_normalize_field', $field );
399
+ do_action( "rwmb_after_normalize_{$field['type']}_field", $field );
400
+ do_action( "rwmb_after_normalize_{$field['id']}_field", $field );
401
  }
402
 
403
  return $fields;
436
  {
437
  foreach ( $fields as $field )
438
  {
439
+ $value = get_post_meta( $post_id, $field['id'], ! $field['multiple'] );
440
  if (
441
+ ( ! $field['multiple'] && '' !== $value )
442
  || ( $field['multiple'] && array() !== $value )
443
  )
444
  {
js/clone.js CHANGED
@@ -1,103 +1,225 @@
1
- jQuery( document ).ready( function( $ )
2
  {
3
- toggle_remove_buttons();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
 
5
- function add_cloned_fields( $input )
 
 
 
 
6
  {
7
- var $clone_last = $input.find( '.rwmb-clone:last' ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  $clone = $clone_last.clone(),
9
- $input, name;
10
-
11
  $clone.insertAfter( $clone_last );
12
  $input = $clone.find( ':input[class|="rwmb"]' );
13
 
14
- // Reset value
15
- $input.val( '' );
16
-
17
- // Get the field name, and increment
18
- name = $input.attr( 'name' ).replace( /\[(\d+)\]/, function( match, p1 )
19
  {
20
- return '[' + ( parseInt( p1 ) + 1 ) + ']';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  } );
22
 
23
- // Update the "name" attribute
24
- $input.attr( 'name', name );
25
-
26
  // Toggle remove buttons
27
- toggle_remove_buttons( $input );
28
-
29
- //Trigger custom clone event
30
  $input.trigger( 'clone' );
31
  }
32
 
33
- // Add more clones
34
- $( '.add-clone' ).on( 'click', function( e )
 
 
 
 
35
  {
36
- e.stopPropagation();
37
- var $input = $( this ).parents( '.rwmb-input' ),
38
- $clone_group = $( this ).parents( '.rwmb-field' ).attr( "clone-group" );
 
 
 
 
 
 
 
 
 
 
39
 
40
- // If the field is part of a clone group, get all fields in that
41
- // group and itterate over them
42
- if ( $clone_group )
43
  {
44
- // Get the parent metabox and then find the matching
45
- // clone-group elements inside
46
- var $metabox = $( this ).parents( '.inside' );
47
- var $clone_group_list = $metabox.find( 'div[clone-group="' + $clone_group + '"]' );
48
 
49
- $.each( $clone_group_list.find( '.rwmb-input' ),
50
- function( key, value )
51
- {
52
- add_cloned_fields( $( value ) );
53
- } );
54
- }
55
- else
56
- add_cloned_fields( $input );
57
 
58
- toggle_remove_buttons( $input );
 
59
 
60
- return false;
61
- } );
62
 
63
- // Remove clones
64
- $( '.rwmb-input' ).on( 'click', '.remove-clone', function()
65
- {
66
- var $this = $( this ),
67
- $input = $this.parents( '.rwmb-input' ),
68
- $clone_group = $( this ).parents( '.rwmb-field' ).attr( 'clone-group' );
69
 
70
- // Remove clone only if there're 2 or more of them
71
- if ( $input.find( '.rwmb-clone' ).length <= 1 )
72
- return false;
 
 
 
73
 
74
- if ( $clone_group )
75
- {
76
- // Get the parent metabox and then find the matching
77
- // clone-group elements inside
78
- var $metabox = $( this ).parents( '.inside' );
79
- var $clone_group_list = $metabox.find( 'div[clone-group="' + $clone_group + '"]' );
80
- var $index = $this.parent().index();
81
-
82
- $.each( $clone_group_list.find( '.rwmb-input' ),
83
- function( key, value )
84
- {
85
- $( value ).children( '.rwmb-clone' ).eq( $index ).remove();
86
 
87
- // Toggle remove buttons
88
- toggle_remove_buttons( $( value ) );
89
- } );
90
- }
91
- else
92
- {
93
- $this.parent().remove();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
 
95
  // Toggle remove buttons
96
- toggle_remove_buttons( $input );
 
 
 
97
  }
98
 
99
- return false;
100
- } );
101
 
102
  /**
103
  * Hide remove buttons when there's only 1 of them
@@ -106,15 +228,14 @@ jQuery( document ).ready( function( $ )
106
  *
107
  * @return void
108
  */
109
- function toggle_remove_buttons( $el )
110
  {
111
  var $button;
112
- if ( !$el )
113
- $el = $( '.rwmb-field' );
114
- $el.each( function()
115
  {
116
  $button = $( this ).find( '.remove-clone' );
117
  $button.length < 2 ? $button.hide() : $button.show();
118
  } );
119
  }
120
- } );
1
+ jQuery( function ( $ )
2
  {
3
+ // Add more clones
4
+ $( '.add-clone' ).on( 'click', function ( e )
5
+ {
6
+ e.preventDefault();
7
+
8
+ var $input = $( this ).parents( '.rwmb-input' );
9
+
10
+ if ( $( this ).parents( '.rwmb-field' ).hasClass( 'rwmb-wysiwyg-wrapper' ) )
11
+ {
12
+ cloneWYSIWYG( $input );
13
+ }
14
+ else
15
+ {
16
+ clone( $input );
17
+ }
18
 
19
+ toggleRemoveButtons( $input );
20
+ } );
21
+
22
+ // Remove clones
23
+ $( '.rwmb-input' ).on( 'click', '.remove-clone', function ( e )
24
  {
25
+ e.preventDefault();
26
+
27
+ var $this = $( this ),
28
+ $input = $this.parents( '.rwmb-input' );
29
+
30
+ // Remove clone only if there're 2 or more of them
31
+ if ( $input.find( '.rwmb-clone' ).length <= 1 )
32
+ return;
33
+
34
+ $this.parent().remove();
35
+
36
+ // Toggle remove buttons
37
+ toggleRemoveButtons( $input );
38
+ } );
39
+
40
+ toggleRemoveButtons();
41
+
42
+ /**
43
+ * Clone fields
44
+ * @param $container A div container which has all fields
45
+ * @return void
46
+ */
47
+ function clone( $container )
48
+ {
49
+ var $clone_last = $container.find( '.rwmb-clone:last' ),
50
  $clone = $clone_last.clone(),
51
+ $input;
52
+
53
  $clone.insertAfter( $clone_last );
54
  $input = $clone.find( ':input[class|="rwmb"]' );
55
 
56
+ // Increment each field type
57
+ $input.each( function ()
 
 
 
58
  {
59
+ var $this = $( this );
60
+
61
+ if ( $this.attr( 'type' ) == 'radio' || $this.attr( 'type' ) == 'checkbox' )
62
+ {
63
+ // Reset 'checked' attribute
64
+ $this.removeAttr( 'checked' );
65
+ }
66
+ else
67
+ {
68
+ // Reset value
69
+ $this.val( '' );
70
+ }
71
+
72
+ // Get the field name, and increment
73
+ var name = $this.attr( 'name' ).replace( /\[(\d+)\]/, function ( match, p1 )
74
+ {
75
+ return '[' + ( parseInt( p1 ) + 1 ) + ']';
76
+ } );
77
+
78
+ // Update the "name" attribute
79
+ $this.attr( 'name', name );
80
+
81
+ // Get the field id, and increment
82
+ // Not all fields require id, such as 'radio', 'checkbox_list'
83
+ var id = $this.attr( 'id' );
84
+ if ( id )
85
+ {
86
+ if ( /_(\d+)/.test( id ) )
87
+ {
88
+ id = id.replace( /_(\d+)/, function ( match, p1 )
89
+ {
90
+ return '_' + ( parseInt( p1 ) + 1 );
91
+ } );
92
+ }
93
+ else
94
+ {
95
+ id += '_1';
96
+ }
97
+
98
+ // Update the "id" attribute
99
+ $this.attr( 'id', id );
100
+ }
101
+
102
+ // Update the address_button "value" attribute
103
+ var $address_button = $clone.find( '.rwmb-map-goto-address-button' );
104
+ if ( $address_button )
105
+ {
106
+ var value = $address_button.attr( 'value' );
107
+ if ( /_(\d+)/.test( value ) )
108
+ {
109
+ value = value.replace( /_(\d+)/, function ( match, p1 )
110
+ {
111
+ return '_' + ( parseInt( p1 ) + 1 );
112
+ } );
113
+ }
114
+ else
115
+ {
116
+ value += '_1';
117
+ }
118
+ $address_button.attr( 'value', value );
119
+ }
120
  } );
121
 
 
 
 
122
  // Toggle remove buttons
123
+ toggleRemoveButtons( $input );
124
+
125
+ // Trigger custom clone event
126
  $input.trigger( 'clone' );
127
  }
128
 
129
+ /**
130
+ * Clone WYSIWYG field
131
+ * @param $container
132
+ * @return void
133
+ */
134
+ function cloneWYSIWYG( $container )
135
  {
136
+ var $clone_first = $container.find( '.rwmb-clone:first' ),
137
+ $clone_last = $container.find( '.rwmb-clone:last' ),
138
+ $clone = $( '<div />' ).addClass( 'rwmb-clone' ),
139
+ field_name = $clone_last.find( 'textarea.wp-editor-area' ).attr( 'name' ),
140
+ field_id = field_name.replace( /\[(\d+)\]/, '' );
141
+
142
+ //Create some global vars
143
+ var new_index = 0;
144
+ var new_name = field_name.replace( /\[(\d+)\]/, function ( match, p1 )
145
+ {
146
+ new_index = ( parseInt( p1 ) + 1 );
147
+ return '[' + new_index + ']';
148
+ } );
149
 
150
+ if ( typeof rwmb_cloneable_editors !== 'undefined' && typeof rwmb_cloneable_editors[field_id] !== 'undefined' )
 
 
151
  {
152
+ //Get HTML of editor from global object
153
+ var cloned_editor = $( rwmb_cloneable_editors[field_id] );
 
 
154
 
155
+ //Fill new clone with html form global object
156
+ $clone.append( cloned_editor );
 
 
 
 
 
 
157
 
158
+ //Add remove button to clone
159
+ $clone.append( $clone_last.find( '.remove-clone' ).clone() );
160
 
161
+ //Add new clone after the last clone
162
+ $clone.insertAfter( $clone_last );
163
 
164
+ //Replace ID of field with new ID
165
+ var new_id = cloned_editor.attr( 'id' ).replace( /\[(\d+)\]/, '[' + new_index + ']' );
166
+ cloned_editor.attr( 'id', new_id );
 
 
 
167
 
168
+ //Replace all IDs within cloned field
169
+ cloned_editor.find( '[id*="' + field_id + '"]' ).each( function ()
170
+ {
171
+ var id = $( this ).attr( 'id' ).replace( /\[(\d+)\]/, '[' + new_index + ']' );
172
+ $( this ).attr( 'id', id );
173
+ } );
174
 
175
+ //Get the new textarea element
176
+ var textarea = $( cloned_editor ).find( 'textarea.wp-editor-area' );
177
+
178
+ // Update the "name" attribute
179
+ textarea.attr( 'name', new_name );
180
+
181
+ //Empty the textarea
182
+ textarea.html( '' );
183
+
184
+ //Update editor link, so we can add media to the new editor
185
+ cloned_editor.find( '#insert-media-button' ).data( 'editor', new_name );
 
186
 
187
+
188
+ //Get TinyMCE setting for our fields
189
+ var tmceinit = tinyMCEPreInit.mceInit[ $clone_first.find( 'textarea.wp-editor-area' ).attr( 'name' ) ];
190
+ var tmceqtinit = tinyMCEPreInit.qtInit[ $clone_first.find( 'textarea.wp-editor-area' ).attr( 'name' ) ];
191
+
192
+ //Replace id & elements with new created field names
193
+ tmceinit.elements = new_name;
194
+ tmceqtinit.id = new_name;
195
+
196
+ //Initialize TinyMCE
197
+ try
198
+ {
199
+ tinymce.init( tmceinit );
200
+ }
201
+ catch (e)
202
+ {
203
+ }
204
+ if ( typeof(QTags) == 'function' )
205
+ {
206
+ try
207
+ {
208
+ quicktags( tmceqtinit );
209
+ }
210
+ catch (e)
211
+ {
212
+ }
213
+ }
214
 
215
  // Toggle remove buttons
216
+ toggleRemoveButtons( $clone );
217
+
218
+ //Trigger custom clone event
219
+ textarea.trigger( 'clone' );
220
  }
221
 
222
+ }
 
223
 
224
  /**
225
  * Hide remove buttons when there's only 1 of them
228
  *
229
  * @return void
230
  */
231
+ function toggleRemoveButtons( $el )
232
  {
233
  var $button;
234
+ $el = $el || $( '.rwmb-field' );
235
+ $el.each( function ()
 
236
  {
237
  $button = $( this ).find( '.remove-clone' );
238
  $button.length < 2 ? $button.hide() : $button.show();
239
  } );
240
  }
241
+ } );
js/jqueryui/timepicker-i18n/jquery-ui-timepicker-af.js CHANGED
@@ -1,20 +1,20 @@
1
- /* Afrikaans translation for the jQuery Timepicker Addon */
2
- /* Written by Deon Heyns */
3
- (function($) {
4
- $.timepicker.regional['af'] = {
5
- timeOnlyTitle: 'Kies Tyd',
6
- timeText: 'Tyd ',
7
- hourText: 'Ure ',
8
- minuteText: 'Minute',
9
- secondText: 'Sekondes',
10
- millisecText: 'Millisekondes',
11
- timezoneText: 'Tydsone',
12
- currentText: 'Huidige Tyd',
13
- closeText: 'Klaar',
14
- timeFormat: 'HH:mm',
15
- amNames: ['AM', 'A'],
16
- pmNames: ['PM', 'P'],
17
- isRTL: false
18
- };
19
- $.timepicker.setDefaults($.timepicker.regional['af']);
20
- })(jQuery);
1
+ /* Afrikaans translation for the jQuery Timepicker Addon */
2
+ /* Written by Deon Heyns */
3
+ (function($) {
4
+ $.timepicker.regional['af'] = {
5
+ timeOnlyTitle: 'Kies Tyd',
6
+ timeText: 'Tyd ',
7
+ hourText: 'Ure ',
8
+ minuteText: 'Minute',
9
+ secondText: 'Sekondes',
10
+ millisecText: 'Millisekondes',
11
+ timezoneText: 'Tydsone',
12
+ currentText: 'Huidige Tyd',
13
+ closeText: 'Klaar',
14
+ timeFormat: 'HH:mm',
15
+ amNames: ['AM', 'A'],
16
+ pmNames: ['PM', 'P'],
17
+ isRTL: false
18
+ };
19
+ $.timepicker.setDefaults($.timepicker.regional['af']);
20
+ })(jQuery);
js/map.js CHANGED
@@ -1,9 +1,9 @@
1
- ( function( $ )
2
  {
3
  'use strict';
4
 
5
  // Use function construction to store map & DOM elements separately for each instance
6
- var mapField = function( $container )
7
  {
8
  this.$container = $container;
9
  };
@@ -11,7 +11,7 @@
11
  // Use prototype for better performance
12
  mapField.prototype = {
13
  // Initialize everything
14
- init: function()
15
  {
16
  this.initDomElements();
17
  this.initMapElements();
@@ -22,7 +22,7 @@
22
  },
23
 
24
  // Initialize DOM elements
25
- initDomElements: function()
26
  {
27
  this.canvas = this.$container.find( '.rwmb-map-canvas' )[0];
28
  this.$coordinate = this.$container.find( '.rwmb-map-coordinate' );
@@ -31,31 +31,26 @@
31
  },
32
 
33
  // Initialize map elements
34
- initMapElements: function()
35
  {
36
- var defaultLoc = $(this.canvas).data('default-loc'),
37
  latLng;
38
 
39
- if (defaultLoc) {
40
- defaultLoc = defaultLoc.split(',');
41
- } else {
42
- defaultLoc = [53.346881, -6.258860];
43
- }
44
-
45
  latLng = new google.maps.LatLng( defaultLoc[0], defaultLoc[1] ); // Initial position for map
46
 
47
- this.map = new google.maps.Map( this.canvas, {
48
- center: latLng,
49
- zoom: 14,
50
  streetViewControl: 0,
51
- mapTypeId: google.maps.MapTypeId.ROADMAP
52
  } );
53
  this.marker = new google.maps.Marker( {position: latLng, map: this.map, draggable: true} );
54
  this.geocoder = new google.maps.Geocoder();
55
  },
56
 
57
  // Initialize marker position
58
- initMarkerPosition: function()
59
  {
60
  var coord = this.$coordinate.val(),
61
  l,
@@ -78,7 +73,7 @@
78
  },
79
 
80
  // Add event listeners for 'click' & 'drag'
81
- addListeners: function()
82
  {
83
  var that = this;
84
  google.maps.event.addListener( this.map, 'click', function ( event )
@@ -91,7 +86,7 @@
91
  that.updateCoordinate( event.latLng );
92
  } );
93
 
94
- this.$findButton.on( 'click', function()
95
  {
96
  that.geocodeAddress();
97
  return false;
@@ -99,7 +94,7 @@
99
  },
100
 
101
  // Autocomplete address
102
- autocomplete: function()
103
  {
104
  var that = this;
105
 
@@ -108,25 +103,25 @@
108
  return;
109
 
110
  $( '#' + this.addressField ).autocomplete( {
111
- source: function( request, response )
112
  {
113
  // TODO: add 'region' option, to help bias geocoder.
114
  that.geocoder.geocode( {
115
  'address': request.term
116
- }, function( results )
117
  {
118
- response( $.map( results, function( item )
119
  {
120
  return {
121
- label: item.formatted_address,
122
- value: item.formatted_address,
123
- latitude: item.geometry.location.lat(),
124
  longitude: item.geometry.location.lng()
125
  };
126
- } ) );
127
  } );
128
  },
129
- select: function( event, ui )
130
  {
131
  var latLng = new google.maps.LatLng( ui.item.latitude, ui.item.longitude );
132
 
@@ -138,29 +133,31 @@
138
  },
139
 
140
  // Update coordinate to input field
141
- updateCoordinate: function( latLng )
142
  {
143
  this.$coordinate.val( latLng.lat() + ',' + latLng.lng() );
144
  },
145
 
146
  // Find coordinates by address
147
  // Find coordinates by address
148
- geocodeAddress: function()
149
  {
150
- var address = '',
151
- addressList = new Array(),
152
  fieldList = this.addressField.split( ',' ),
153
  loop,
154
  that = this;
155
 
156
  for ( loop = 0; loop < fieldList.length; loop++ )
157
- addressList[loop]=jQuery( '#' + fieldList[loop] ).val();
158
-
159
- address = addressList.join(",").replace( /\n/g, ',' ).replace( /,,/g, ',' );
 
 
160
 
161
- if (address)
162
  {
163
- this.geocoder.geocode( {'address': address}, function( results, status )
164
  {
165
  if ( status === google.maps.GeocoderStatus.OK )
166
  {
@@ -170,18 +167,29 @@
170
  }
171
  } );
172
  }
173
- },
174
  };
175
 
176
- $( function()
177
  {
178
- $( '.rwmb-map-field' ).each( function()
179
  {
180
  var field = new mapField( $( this ) );
181
  field.init();
182
 
183
- $( this ).data('mapController', field);
 
 
 
 
 
 
 
 
 
 
 
184
  } );
185
  } );
186
 
187
- } )( jQuery );
1
+ (function ( $ )
2
  {
3
  'use strict';
4
 
5
  // Use function construction to store map & DOM elements separately for each instance
6
+ var mapField = function ( $container )
7
  {
8
  this.$container = $container;
9
  };
11
  // Use prototype for better performance
12
  mapField.prototype = {
13
  // Initialize everything
14
+ init : function ()
15
  {
16
  this.initDomElements();
17
  this.initMapElements();
22
  },
23
 
24
  // Initialize DOM elements
25
+ initDomElements : function ()
26
  {
27
  this.canvas = this.$container.find( '.rwmb-map-canvas' )[0];
28
  this.$coordinate = this.$container.find( '.rwmb-map-coordinate' );
31
  },
32
 
33
  // Initialize map elements
34
+ initMapElements : function ()
35
  {
36
+ var defaultLoc = $( this.canvas ).data( 'default-loc' ),
37
  latLng;
38
 
39
+ defaultLoc = defaultLoc ? defaultLoc.split( ',' ) : [53.346881, -6.258860];
 
 
 
 
 
40
  latLng = new google.maps.LatLng( defaultLoc[0], defaultLoc[1] ); // Initial position for map
41
 
42
+ this.map = new google.maps.Map( this.canvas, {
43
+ center : latLng,
44
+ zoom : 14,
45
  streetViewControl: 0,
46
+ mapTypeId : google.maps.MapTypeId.ROADMAP
47
  } );
48
  this.marker = new google.maps.Marker( {position: latLng, map: this.map, draggable: true} );
49
  this.geocoder = new google.maps.Geocoder();
50
  },
51
 
52
  // Initialize marker position
53
+ initMarkerPosition: function ()
54
  {
55
  var coord = this.$coordinate.val(),
56
  l,
73
  },
74
 
75
  // Add event listeners for 'click' & 'drag'
76
+ addListeners : function ()
77
  {
78
  var that = this;
79
  google.maps.event.addListener( this.map, 'click', function ( event )
86
  that.updateCoordinate( event.latLng );
87
  } );
88
 
89
+ this.$findButton.on( 'click', function ()
90
  {
91
  that.geocodeAddress();
92
  return false;
94
  },
95
 
96
  // Autocomplete address
97
+ autocomplete : function ()
98
  {
99
  var that = this;
100
 
103
  return;
104
 
105
  $( '#' + this.addressField ).autocomplete( {
106
+ source: function ( request, response )
107
  {
108
  // TODO: add 'region' option, to help bias geocoder.
109
  that.geocoder.geocode( {
110
  'address': request.term
111
+ }, function ( results )
112
  {
113
+ response( $.map( results, function ( item )
114
  {
115
  return {
116
+ label : item.formatted_address,
117
+ value : item.formatted_address,
118
+ latitude : item.geometry.location.lat(),
119
  longitude: item.geometry.location.lng()
120
  };
121
+ } ) );
122
  } );
123
  },
124
+ select: function ( event, ui )
125
  {
126
  var latLng = new google.maps.LatLng( ui.item.latitude, ui.item.longitude );
127
 
133
  },
134
 
135
  // Update coordinate to input field
136
+ updateCoordinate : function ( latLng )
137
  {
138
  this.$coordinate.val( latLng.lat() + ',' + latLng.lng() );
139
  },
140
 
141
  // Find coordinates by address
142
  // Find coordinates by address
143
+ geocodeAddress : function ()
144
  {
145
+ var address,
146
+ addressList = [],
147
  fieldList = this.addressField.split( ',' ),
148
  loop,
149
  that = this;
150
 
151
  for ( loop = 0; loop < fieldList.length; loop++ )
152
+ {
153
+ addressList[loop] = jQuery( '#' + fieldList[loop] ).val();
154
+ }
155
+
156
+ address = addressList.join( "," ).replace( /\n/g, ',' ).replace( /,,/g, ',' );
157
 
158
+ if ( address )
159
  {
160
+ this.geocoder.geocode( {'address': address}, function ( results, status )
161
  {
162
  if ( status === google.maps.GeocoderStatus.OK )
163
  {
167
  }
168
  } );
169
  }
170
+ }
171
  };
172
 
173
+ $( function ()
174
  {
175
+ $( '.rwmb-map-field' ).each( function ()
176
  {
177
  var field = new mapField( $( this ) );
178
  field.init();
179
 
180
+ $( this ).data( 'mapController', field );
181
+ } );
182
+
183
+ $( '.rwmb-input' ).on( 'clone', function ( params )
184
+ {
185
+ $( '.rwmb-map-field' ).each( function ()
186
+ {
187
+ var field = new mapField( $( this ) );
188
+ field.init();
189
+
190
+ $( this ).data( 'mapController', field );
191
+ } );
192
  } );
193
  } );
194
 
195
+ })( jQuery );
meta-box.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Meta Box
4
  Plugin URI: http://www.deluxeblogtips.com/meta-box
5
  Description: Create meta box for editing pages in WordPress. Compatible with custom post types since WP 3.0
6
- Version: 4.3.8
7
  Author: Rilwis
8
  Author URI: http://www.deluxeblogtips.com
9
  License: GPL2+
@@ -13,7 +13,7 @@ License: GPL2+
13
  defined( 'ABSPATH' ) || exit;
14
 
15
  // Script version, used to add version for scripts and styles
16
- define( 'RWMB_VER', '4.3.8' );
17
 
18
  // Define plugin URLs, for fast enqueuing scripts and styles
19
  if ( ! defined( 'RWMB_URL' ) )
3
  Plugin Name: Meta Box
4
  Plugin URI: http://www.deluxeblogtips.com/meta-box
5
  Description: Create meta box for editing pages in WordPress. Compatible with custom post types since WP 3.0
6
+ Version: 4.3.9
7
  Author: Rilwis
8
  Author URI: http://www.deluxeblogtips.com
9
  License: GPL2+
13
  defined( 'ABSPATH' ) || exit;
14
 
15
  // Script version, used to add version for scripts and styles
16
+ define( 'RWMB_VER', '4.3.9' );
17
 
18
  // Define plugin URLs, for fast enqueuing scripts and styles
19
  if ( ! defined( 'RWMB_URL' ) )
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: rilwis, franz-josef-kaiser, Omnicia, funkedgeek, PerWiklander, rua
3
  Donate link: http://www.deluxeblogtips.com/donate
4
  Tags: meta-box, custom-fields, custom-field, meta, meta-boxes
5
  Requires at least: 3.5
6
- Tested up to: 3.8
7
- Stable tag: 4.3.8
8
 
9
  Meta Box plugin helps you easily implement multiple meta boxes in editing pages in WordPress. Works with custom post types and various field types.
10
 
@@ -18,6 +18,8 @@ Meta Box plugin provides an API to easily implement custom meta boxes in editing
18
  * Has built-in hooks which allow you to change the appearance and behavior of meta boxes
19
  * Easily integrated with themes
20
 
 
 
21
  **Supported fields**
22
 
23
  - button
@@ -40,7 +42,12 @@ Meta Box plugin provides an API to easily implement custom meta boxes in editing
40
  - textarea
41
  - wysiwyg
42
 
43
- [Project Page](http://www.deluxeblogtips.com/meta-box/) | [Getting Started](http://www.deluxeblogtips.com/meta-box/getting-started/) | [Support Forums](http://www.deluxeblogtips.com/forums/) | [Donate](http://www.deluxeblogtips.com/donate/)
 
 
 
 
 
44
 
45
  == Installation ==
46
 
@@ -58,6 +65,16 @@ To getting started with the plugin API, please read [this tutorial](http://www.d
58
 
59
  == Changelog ==
60
 
 
 
 
 
 
 
 
 
 
 
61
  = 4.3.8 =
62
  * Bug fix: compatibility with PHP 5.2
63
 
3
  Donate link: http://www.deluxeblogtips.com/donate
4
  Tags: meta-box, custom-fields, custom-field, meta, meta-boxes
5
  Requires at least: 3.5
6
+ Tested up to: 3.9.1
7
+ Stable tag: 4.3.9
8
 
9
  Meta Box plugin helps you easily implement multiple meta boxes in editing pages in WordPress. Works with custom post types and various field types.
10
 
18
  * Has built-in hooks which allow you to change the appearance and behavior of meta boxes
19
  * Easily integrated with themes
20
 
21
+ **You can also add more features to meta box via [premium extensions](http://premium.deluxeblogtips.com)**.
22
+
23
  **Supported fields**
24
 
25
  - button
42
  - textarea
43
  - wysiwyg
44
 
45
+ **Plugin Links**
46
+
47
+ - [Project Page](http://www.deluxeblogtips.com/meta-box/)
48
+ - [Documentation](http://www.deluxeblogtips.com/meta-box/getting-started/)
49
+ - [Report Bugs/Issues](https://github.com/rilwis/meta-box/issues)
50
+ - [Premium Extensions](http://premium.deluxeblogtips.com)
51
 
52
  == Installation ==
53
 
65
 
66
  == Changelog ==
67
 
68
+ = 4.3.9 =
69
+ * Bug fix: `text-list` field type
70
+ * Improvement: better coding styles
71
+ * Improvement: wysiwyg field is now clonable
72
+ * Improvement: launch geolocation autocomplete when address field is cloned
73
+ * Improvement: better cloning for radio, checkbox
74
+ * Improvement: add more hooks
75
+ * Improvement: allow child fields to add their own add/remove clone buttons.
76
+ * Improvement: remove 'clone-group'. Too complicated and not user-friendly.
77
+
78
  = 4.3.8 =
79
  * Bug fix: compatibility with PHP 5.2
80