Version Description
Download this release
Release Info
Developer | rilwis |
Plugin | Meta Box |
Version | 4.16.0 |
Comparing to | |
See all releases |
Code changes from version 4.15.9 to 4.16.0
- css/select-advanced.css +1 -0
- css/style.css +7 -0
- inc/about/about.php +0 -12
- inc/about/sections/welcome.php +4 -2
- inc/autoloader.php +1 -1
- inc/fields/datetime.php +24 -4
- inc/fields/file.php +134 -22
- inc/fields/image-advanced.php +5 -3
- inc/fields/image.php +4 -3
- inc/fields/post.php +12 -0
- inc/fields/user.php +12 -0
- inc/fields/video.php +2 -1
- inc/loader.php +5 -3
- js/media.js +7 -36
- js/osm.js +3 -5
- js/select-tree.js +32 -6
- meta-box.php +1 -1
- readme.txt +2 -2
css/select-advanced.css
CHANGED
@@ -1,6 +1,7 @@
|
|
1 |
.rwmb-field .select2-container {
|
2 |
height: auto;
|
3 |
min-width: 200px;
|
|
|
4 |
}
|
5 |
#wpbody .rwmb-select-all {
|
6 |
display: block;
|
1 |
.rwmb-field .select2-container {
|
2 |
height: auto;
|
3 |
min-width: 200px;
|
4 |
+
max-width: 100%;
|
5 |
}
|
6 |
#wpbody .rwmb-select-all {
|
7 |
display: block;
|
css/style.css
CHANGED
@@ -31,6 +31,10 @@
|
|
31 |
font-weight: bold;
|
32 |
margin-left: 3px;
|
33 |
}
|
|
|
|
|
|
|
|
|
34 |
|
35 |
/* 75% if field has label, 100% if no label */
|
36 |
.rwmb-input {
|
@@ -122,6 +126,9 @@ select.rwmb-error {
|
|
122 |
#side-sortables .rwmb-input {
|
123 |
width: 100%;
|
124 |
}
|
|
|
|
|
|
|
125 |
|
126 |
/* Seamless style
|
127 |
--------------------------------------------------------------*/
|
31 |
font-weight: bold;
|
32 |
margin-left: 3px;
|
33 |
}
|
34 |
+
.rwmb-input input,
|
35 |
+
.rwmb-input select {
|
36 |
+
max-width: 99%;
|
37 |
+
}
|
38 |
|
39 |
/* 75% if field has label, 100% if no label */
|
40 |
.rwmb-input {
|
126 |
#side-sortables .rwmb-input {
|
127 |
width: 100%;
|
128 |
}
|
129 |
+
#side-sortables .rwmb-label {
|
130 |
+
margin-bottom: 3px;
|
131 |
+
}
|
132 |
|
133 |
/* Seamless style
|
134 |
--------------------------------------------------------------*/
|
inc/about/about.php
CHANGED
@@ -9,22 +9,10 @@
|
|
9 |
* About page class.
|
10 |
*/
|
11 |
class RWMB_About {
|
12 |
-
/**
|
13 |
-
* Plugin data.
|
14 |
-
*
|
15 |
-
* @var array
|
16 |
-
*/
|
17 |
-
protected $plugin;
|
18 |
-
|
19 |
/**
|
20 |
* Init hooks.
|
21 |
*/
|
22 |
public function init() {
|
23 |
-
if ( ! function_exists( 'get_plugin_data' ) ) {
|
24 |
-
include ABSPATH . 'wp-admin/includes/plugin.php';
|
25 |
-
}
|
26 |
-
$this->plugin = get_plugin_data( RWMB_DIR . 'meta-box.php' );
|
27 |
-
|
28 |
// Add links to about page in the plugin action links.
|
29 |
add_filter( 'plugin_action_links_meta-box/meta-box.php', array( $this, 'plugin_links' ) );
|
30 |
|
9 |
* About page class.
|
10 |
*/
|
11 |
class RWMB_About {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
/**
|
13 |
* Init hooks.
|
14 |
*/
|
15 |
public function init() {
|
|
|
|
|
|
|
|
|
|
|
16 |
// Add links to about page in the plugin action links.
|
17 |
add_filter( 'plugin_action_links_meta-box/meta-box.php', array( $this, 'plugin_links' ) );
|
18 |
|
inc/about/sections/welcome.php
CHANGED
@@ -9,12 +9,14 @@
|
|
9 |
?>
|
10 |
<h1>
|
11 |
<?php
|
|
|
|
|
12 |
// Translators: %s - Plugin name.
|
13 |
-
echo esc_html( sprintf( __( 'Welcome to %s', 'meta-box' ), $
|
14 |
?>
|
15 |
</h1>
|
16 |
<div class="about-text"><?php esc_html_e( 'Meta Box is a free Gutenberg and GDPR-compatible WordPress custom fields plugin and framework that makes quick work of customizing a website with—you guessed it—meta boxes and custom fields in WordPress. Follow the instruction below to get started!', 'meta-box' ); ?></div>
|
17 |
-
<a target="_blank" class="wp-badge" href="<?php echo esc_url( 'https://metabox.io/?utm_source=WordPress&utm_medium=link&utm_campaign=plugin' ); ?>"><?php echo esc_html( $
|
18 |
<p class="about-buttons">
|
19 |
<a target="_blank" class="button" href="<?php echo esc_url( 'https://docs.metabox.io?utm_source=WordPress&utm_medium=link&utm_campaign=plugin' ); ?>"><?php esc_html_e( 'Documentation', 'meta-box' ); ?></a>
|
20 |
<a target="_blank" class="button" href="<?php echo esc_url( 'https://metabox.io/plugins/?utm_source=WordPress&utm_medium=link&utm_campaign=plugin' ); ?>"><?php esc_html_e( 'Extensions', 'meta-box' ); ?></a>
|
9 |
?>
|
10 |
<h1>
|
11 |
<?php
|
12 |
+
$plugin = get_plugin_data( RWMB_DIR . 'meta-box.php', false, false );
|
13 |
+
|
14 |
// Translators: %s - Plugin name.
|
15 |
+
echo esc_html( sprintf( __( 'Welcome to %s', 'meta-box' ), $plugin['Name'] ) );
|
16 |
?>
|
17 |
</h1>
|
18 |
<div class="about-text"><?php esc_html_e( 'Meta Box is a free Gutenberg and GDPR-compatible WordPress custom fields plugin and framework that makes quick work of customizing a website with—you guessed it—meta boxes and custom fields in WordPress. Follow the instruction below to get started!', 'meta-box' ); ?></div>
|
19 |
+
<a target="_blank" class="wp-badge" href="<?php echo esc_url( 'https://metabox.io/?utm_source=WordPress&utm_medium=link&utm_campaign=plugin' ); ?>"><?php echo esc_html( $plugin['Name'] ); ?></a>
|
20 |
<p class="about-buttons">
|
21 |
<a target="_blank" class="button" href="<?php echo esc_url( 'https://docs.metabox.io?utm_source=WordPress&utm_medium=link&utm_campaign=plugin' ); ?>"><?php esc_html_e( 'Documentation', 'meta-box' ); ?></a>
|
22 |
<a target="_blank" class="button" href="<?php echo esc_url( 'https://metabox.io/plugins/?utm_source=WordPress&utm_medium=link&utm_campaign=plugin' ); ?>"><?php esc_html_e( 'Extensions', 'meta-box' ); ?></a>
|
inc/autoloader.php
CHANGED
@@ -57,7 +57,7 @@ class RWMB_Autoloader {
|
|
57 |
foreach ( $this->dirs as $dir ) {
|
58 |
if (
|
59 |
( $dir['prefix'] && 0 !== strpos( $class, $dir['prefix'] ) )
|
60 |
-
|
61 |
) {
|
62 |
continue;
|
63 |
}
|
57 |
foreach ( $this->dirs as $dir ) {
|
58 |
if (
|
59 |
( $dir['prefix'] && 0 !== strpos( $class, $dir['prefix'] ) )
|
60 |
+
|| ( $dir['suffix'] && substr( $class, - strlen( $dir['suffix'] ) ) !== $dir['suffix'] )
|
61 |
) {
|
62 |
continue;
|
63 |
}
|
inc/fields/datetime.php
CHANGED
@@ -139,7 +139,16 @@ class RWMB_Datetime_Field extends RWMB_Text_Field {
|
|
139 |
* @return string|int
|
140 |
*/
|
141 |
public static function value( $new, $old, $post_id, $field ) {
|
142 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
143 |
}
|
144 |
|
145 |
/**
|
@@ -153,9 +162,19 @@ class RWMB_Datetime_Field extends RWMB_Text_Field {
|
|
153 |
*/
|
154 |
public static function meta( $post_id, $saved, $field ) {
|
155 |
$meta = parent::meta( $post_id, $saved, $field );
|
|
|
156 |
if ( $field['timestamp'] ) {
|
157 |
$meta = self::prepare_meta( $meta, $field );
|
|
|
|
|
|
|
|
|
|
|
158 |
}
|
|
|
|
|
|
|
|
|
159 |
return $meta;
|
160 |
}
|
161 |
|
@@ -189,9 +208,10 @@ class RWMB_Datetime_Field extends RWMB_Text_Field {
|
|
189 |
$field = wp_parse_args(
|
190 |
$field,
|
191 |
array(
|
192 |
-
'timestamp'
|
193 |
-
'inline'
|
194 |
-
'js_options'
|
|
|
195 |
)
|
196 |
);
|
197 |
|
139 |
* @return string|int
|
140 |
*/
|
141 |
public static function value( $new, $old, $post_id, $field ) {
|
142 |
+
if ( $field['timestamp'] ) {
|
143 |
+
return $new['timestamp'];
|
144 |
+
}
|
145 |
+
|
146 |
+
if ( $field['save_format'] ) {
|
147 |
+
$date = DateTime::createFromFormat( self::call( 'translate_format', $field ), $new );
|
148 |
+
$new = $date->format( $field['save_format'] );
|
149 |
+
}
|
150 |
+
|
151 |
+
return $new;
|
152 |
}
|
153 |
|
154 |
/**
|
162 |
*/
|
163 |
public static function meta( $post_id, $saved, $field ) {
|
164 |
$meta = parent::meta( $post_id, $saved, $field );
|
165 |
+
|
166 |
if ( $field['timestamp'] ) {
|
167 |
$meta = self::prepare_meta( $meta, $field );
|
168 |
+
return $meta;
|
169 |
+
}
|
170 |
+
|
171 |
+
if ( ! $field['save_format'] || ! $meta ) {
|
172 |
+
return $meta;
|
173 |
}
|
174 |
+
|
175 |
+
$date = DateTime::createFromFormat( $field['save_format'], $meta );
|
176 |
+
$meta = $date->format( self::call( 'translate_format', $field ) );
|
177 |
+
|
178 |
return $meta;
|
179 |
}
|
180 |
|
208 |
$field = wp_parse_args(
|
209 |
$field,
|
210 |
array(
|
211 |
+
'timestamp' => false,
|
212 |
+
'inline' => false,
|
213 |
+
'js_options' => array(),
|
214 |
+
'save_format' => '',
|
215 |
)
|
216 |
);
|
217 |
|
inc/fields/file.php
CHANGED
@@ -47,11 +47,18 @@ class RWMB_File_Field extends RWMB_Field {
|
|
47 |
* Ajax callback for deleting files.
|
48 |
*/
|
49 |
public static function ajax_delete_file() {
|
50 |
-
$field_id
|
51 |
-
$attachment_id = (int) filter_input( INPUT_POST, 'attachment_id', FILTER_SANITIZE_NUMBER_INT );
|
52 |
-
|
53 |
check_ajax_referer( "rwmb-delete-file_{$field_id}" );
|
54 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
wp_send_json_success();
|
56 |
}
|
57 |
wp_send_json_error( __( 'Error: Cannot delete file', 'meta-box' ) );
|
@@ -97,10 +104,11 @@ class RWMB_File_Field extends RWMB_Field {
|
|
97 |
|
98 |
foreach ( (array) $files as $k => $file ) {
|
99 |
// Ignore deleted files (if users accidentally deleted files or uses `force_delete` without saving post).
|
100 |
-
if ( get_attached_file( $file ) ) {
|
101 |
$output .= self::call( $field, 'file_html', $file, $k );
|
102 |
}
|
103 |
}
|
|
|
104 |
return sprintf(
|
105 |
'<ul class="rwmb-uploaded" data-field_id="%s" data-delete_nonce="%s" data-reorder_nonce="%s" data-force_delete="%s" data-max_file_uploads="%s" data-mime_type="%s">%s</ul>',
|
106 |
$field['id'],
|
@@ -125,8 +133,22 @@ class RWMB_File_Field extends RWMB_Field {
|
|
125 |
$i18n_delete = apply_filters( 'rwmb_file_delete_string', _x( 'Delete', 'file upload', 'meta-box' ) );
|
126 |
$i18n_edit = apply_filters( 'rwmb_file_edit_string', _x( 'Edit', 'file upload', 'meta-box' ) );
|
127 |
$attributes = self::get_attributes( $field, $file );
|
128 |
-
|
129 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
130 |
|
131 |
return sprintf(
|
132 |
'<li class="rwmb-file">
|
@@ -135,19 +157,18 @@ class RWMB_File_Field extends RWMB_Field {
|
|
135 |
<a href="%s" target="_blank" class="rwmb-file-title">%s</a>
|
136 |
<p class="rwmb-file-name">%s</p>
|
137 |
<p class="rwmb-file-actions">
|
138 |
-
|
139 |
<a href="#" class="rwmb-file-delete" data-attachment_id="%s"><span class="dashicons dashicons-no-alt"></span>%s</a>
|
140 |
</p>
|
141 |
</div>
|
142 |
<input type="hidden" name="%s[%s]" value="%s">
|
143 |
</li>',
|
144 |
-
|
145 |
-
$icon,
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
$i18n_edit,
|
151 |
$file,
|
152 |
$i18n_delete,
|
153 |
$attributes['name'],
|
@@ -156,6 +177,28 @@ class RWMB_File_Field extends RWMB_Field {
|
|
156 |
);
|
157 |
}
|
158 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
159 |
/**
|
160 |
* Get meta values to save.
|
161 |
*
|
@@ -180,11 +223,12 @@ class RWMB_File_Field extends RWMB_Field {
|
|
180 |
if ( ! $field['clone'] ) {
|
181 |
$count = self::transform( $input );
|
182 |
for ( $i = 0; $i <= $count; $i ++ ) {
|
183 |
-
$attachment =
|
184 |
-
if ( ! is_wp_error( $attachment ) ) {
|
185 |
$new[] = $attachment;
|
186 |
}
|
187 |
}
|
|
|
188 |
return $new;
|
189 |
}
|
190 |
|
@@ -195,8 +239,8 @@ class RWMB_File_Field extends RWMB_Field {
|
|
195 |
$new[ $clone_index ] = array();
|
196 |
}
|
197 |
for ( $i = 0; $i <= $count; $i ++ ) {
|
198 |
-
$attachment =
|
199 |
-
if ( ! is_wp_error( $attachment ) ) {
|
200 |
$new[ $clone_index ][] = $attachment;
|
201 |
}
|
202 |
}
|
@@ -205,6 +249,20 @@ class RWMB_File_Field extends RWMB_Field {
|
|
205 |
return $new;
|
206 |
}
|
207 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
208 |
/**
|
209 |
* Transform $_FILES from $_FILES['field']['key']['index'] to $_FILES['field_index']['key'].
|
210 |
*
|
@@ -273,6 +331,7 @@ class RWMB_File_Field extends RWMB_Field {
|
|
273 |
'force_delete' => false,
|
274 |
'max_file_uploads' => 0,
|
275 |
'mime_type' => '',
|
|
|
276 |
)
|
277 |
);
|
278 |
$field['multiple'] = true;
|
@@ -330,12 +389,17 @@ class RWMB_File_Field extends RWMB_Field {
|
|
330 |
/**
|
331 |
* Get uploaded file information.
|
332 |
*
|
333 |
-
* @param int $file
|
334 |
-
* @param array $args
|
|
|
335 |
*
|
336 |
* @return array|bool False if file not found. Array of (id, name, path, url) on success.
|
337 |
*/
|
338 |
-
public static function file_info( $file, $args = array() ) {
|
|
|
|
|
|
|
|
|
339 |
$path = get_attached_file( $file );
|
340 |
if ( ! $path ) {
|
341 |
return false;
|
@@ -366,4 +430,52 @@ class RWMB_File_Field extends RWMB_Field {
|
|
366 |
public static function format_single_value( $field, $value, $args, $post_id ) {
|
367 |
return sprintf( '<a href="%s" target="_blank">%s</a>', esc_url( $value['url'] ), esc_html( $value['title'] ) );
|
368 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
369 |
}
|
47 |
* Ajax callback for deleting files.
|
48 |
*/
|
49 |
public static function ajax_delete_file() {
|
50 |
+
$field_id = filter_input( INPUT_POST, 'field_id', FILTER_SANITIZE_STRING );
|
|
|
|
|
51 |
check_ajax_referer( "rwmb-delete-file_{$field_id}" );
|
52 |
+
|
53 |
+
$attachment = filter_input( INPUT_POST, 'attachment_id' );
|
54 |
+
if ( is_numeric( $attachment ) ) {
|
55 |
+
$result = wp_delete_attachment( $attachment );
|
56 |
+
} else {
|
57 |
+
$path = str_replace( home_url( '/' ), ABSPATH . '/', $attachment );
|
58 |
+
$result = unlink( $path );
|
59 |
+
}
|
60 |
+
|
61 |
+
if ( $result ) {
|
62 |
wp_send_json_success();
|
63 |
}
|
64 |
wp_send_json_error( __( 'Error: Cannot delete file', 'meta-box' ) );
|
104 |
|
105 |
foreach ( (array) $files as $k => $file ) {
|
106 |
// Ignore deleted files (if users accidentally deleted files or uses `force_delete` without saving post).
|
107 |
+
if ( get_attached_file( $file ) || $field['upload_dir'] ) {
|
108 |
$output .= self::call( $field, 'file_html', $file, $k );
|
109 |
}
|
110 |
}
|
111 |
+
|
112 |
return sprintf(
|
113 |
'<ul class="rwmb-uploaded" data-field_id="%s" data-delete_nonce="%s" data-reorder_nonce="%s" data-force_delete="%s" data-max_file_uploads="%s" data-mime_type="%s">%s</ul>',
|
114 |
$field['id'],
|
133 |
$i18n_delete = apply_filters( 'rwmb_file_delete_string', _x( 'Delete', 'file upload', 'meta-box' ) );
|
134 |
$i18n_edit = apply_filters( 'rwmb_file_edit_string', _x( 'Edit', 'file upload', 'meta-box' ) );
|
135 |
$attributes = self::get_attributes( $field, $file );
|
136 |
+
|
137 |
+
if ( ! $file ) {
|
138 |
+
return;
|
139 |
+
}
|
140 |
+
|
141 |
+
if ( $field['upload_dir'] ) {
|
142 |
+
$data = self::file_info_custom_dir( $file, $field );
|
143 |
+
} else {
|
144 |
+
$data = array(
|
145 |
+
'icon' => wp_get_attachment_image( $file, array( 60, 60 ), true ),
|
146 |
+
'name' => basename( get_attached_file( $file ) ),
|
147 |
+
'url' => wp_get_attachment_url( $file ),
|
148 |
+
'title' => get_the_title( $file ),
|
149 |
+
'edit_link' => sprintf( '<a href="%s" class="rwmb-file-edit" target="_blank"><span class="dashicons dashicons-edit"></span>%s</a>', get_edit_post_link( $file ), $i18n_edit ),
|
150 |
+
);
|
151 |
+
}
|
152 |
|
153 |
return sprintf(
|
154 |
'<li class="rwmb-file">
|
157 |
<a href="%s" target="_blank" class="rwmb-file-title">%s</a>
|
158 |
<p class="rwmb-file-name">%s</p>
|
159 |
<p class="rwmb-file-actions">
|
160 |
+
%s
|
161 |
<a href="#" class="rwmb-file-delete" data-attachment_id="%s"><span class="dashicons dashicons-no-alt"></span>%s</a>
|
162 |
</p>
|
163 |
</div>
|
164 |
<input type="hidden" name="%s[%s]" value="%s">
|
165 |
</li>',
|
166 |
+
$data['url'],
|
167 |
+
$data['icon'],
|
168 |
+
$data['url'],
|
169 |
+
$data['title'],
|
170 |
+
$data['name'],
|
171 |
+
$data['edit_link'],
|
|
|
172 |
$file,
|
173 |
$i18n_delete,
|
174 |
$attributes['name'],
|
177 |
);
|
178 |
}
|
179 |
|
180 |
+
/**
|
181 |
+
* Get file data uploaded to custom directory.
|
182 |
+
*
|
183 |
+
* @param string $file URL to uploaded file.
|
184 |
+
* @param array $field Field settings.
|
185 |
+
* @return string
|
186 |
+
*/
|
187 |
+
protected static function file_info_custom_dir( $file, $field ) {
|
188 |
+
$path = wp_normalize_path( trailingslashit( $field['upload_dir'] ) . basename( $file ) );
|
189 |
+
$ext = pathinfo( $path, PATHINFO_EXTENSION );
|
190 |
+
$icon_url = wp_mime_type_icon( wp_ext2type( $ext ) );
|
191 |
+
$data = array(
|
192 |
+
'icon' => '<img width="48" height="64" src="' . esc_url( $icon_url ) . '" alt="">',
|
193 |
+
'name' => basename( $path ),
|
194 |
+
'path' => $path,
|
195 |
+
'url' => $file,
|
196 |
+
'title' => preg_replace( '/\.[^.]+$/', '', basename( $path ) ),
|
197 |
+
'edit_link' => '',
|
198 |
+
);
|
199 |
+
return $data;
|
200 |
+
}
|
201 |
+
|
202 |
/**
|
203 |
* Get meta values to save.
|
204 |
*
|
223 |
if ( ! $field['clone'] ) {
|
224 |
$count = self::transform( $input );
|
225 |
for ( $i = 0; $i <= $count; $i ++ ) {
|
226 |
+
$attachment = self::handle_upload( "{$input}_{$i}", $post_id, $field );
|
227 |
+
if ( $attachment && ! is_wp_error( $attachment ) ) {
|
228 |
$new[] = $attachment;
|
229 |
}
|
230 |
}
|
231 |
+
|
232 |
return $new;
|
233 |
}
|
234 |
|
239 |
$new[ $clone_index ] = array();
|
240 |
}
|
241 |
for ( $i = 0; $i <= $count; $i ++ ) {
|
242 |
+
$attachment = self::handle_upload( "{$input}_{$clone_index}_{$i}", $post_id, $field );
|
243 |
+
if ( $attachment && ! is_wp_error( $attachment ) ) {
|
244 |
$new[ $clone_index ][] = $attachment;
|
245 |
}
|
246 |
}
|
249 |
return $new;
|
250 |
}
|
251 |
|
252 |
+
/**
|
253 |
+
* Handle file upload.
|
254 |
+
* Consider upload to Media Library or custom folder.
|
255 |
+
*
|
256 |
+
* @param string $file_id File ID in $_FILES when uploading.
|
257 |
+
* @param int $post_id Post ID.
|
258 |
+
* @param array $field Field settings.
|
259 |
+
*
|
260 |
+
* @return \WP_Error|int|string WP_Error if has error, attachment ID if upload in Media Library, URL to file if upload to custom folder.
|
261 |
+
*/
|
262 |
+
protected static function handle_upload( $file_id, $post_id, $field ) {
|
263 |
+
return $field['upload_dir'] ? self::handle_upload_custom_dir( $file_id, $post_id, $field ) : media_handle_upload( $file_id, $post_id );
|
264 |
+
}
|
265 |
+
|
266 |
/**
|
267 |
* Transform $_FILES from $_FILES['field']['key']['index'] to $_FILES['field_index']['key'].
|
268 |
*
|
331 |
'force_delete' => false,
|
332 |
'max_file_uploads' => 0,
|
333 |
'mime_type' => '',
|
334 |
+
'upload_dir' => '',
|
335 |
)
|
336 |
);
|
337 |
$field['multiple'] = true;
|
389 |
/**
|
390 |
* Get uploaded file information.
|
391 |
*
|
392 |
+
* @param int $file Attachment file ID (post ID). Required.
|
393 |
+
* @param array $args Array of arguments (for size).
|
394 |
+
* @param array $field Field settings.
|
395 |
*
|
396 |
* @return array|bool False if file not found. Array of (id, name, path, url) on success.
|
397 |
*/
|
398 |
+
public static function file_info( $file, $args = array(), $field ) {
|
399 |
+
if ( $field['upload_dir'] ) {
|
400 |
+
return self::file_info_custom_dir( $file, $field );
|
401 |
+
}
|
402 |
+
|
403 |
$path = get_attached_file( $file );
|
404 |
if ( ! $path ) {
|
405 |
return false;
|
430 |
public static function format_single_value( $field, $value, $args, $post_id ) {
|
431 |
return sprintf( '<a href="%s" target="_blank">%s</a>', esc_url( $value['url'] ), esc_html( $value['title'] ) );
|
432 |
}
|
433 |
+
|
434 |
+
/**
|
435 |
+
* Handle upload for files in custom directory.
|
436 |
+
*
|
437 |
+
* @param string $file_id File ID in $_FILES when uploading.
|
438 |
+
* @param int $post_id Post ID.
|
439 |
+
* @param array $field Field settings.
|
440 |
+
*
|
441 |
+
* @return string URL to uploaded file.
|
442 |
+
*/
|
443 |
+
public static function handle_upload_custom_dir( $file_id, $post_id, $field ) {
|
444 |
+
// @codingStandardsIgnoreStart
|
445 |
+
if ( ! isset( $_FILES[ $file_id ] ) ) {
|
446 |
+
return;
|
447 |
+
}
|
448 |
+
$file = $_FILES[ $file_id ];
|
449 |
+
if ( UPLOAD_ERR_OK !== $file['error'] || ! $file['tmp_name'] ) {
|
450 |
+
return;
|
451 |
+
}
|
452 |
+
// @codingStandardsIgnoreEnd
|
453 |
+
|
454 |
+
if ( ! file_exists( $field['upload_dir'] ) ) {
|
455 |
+
wp_mkdir_p( $field['upload_dir'] );
|
456 |
+
}
|
457 |
+
if ( ! is_dir( $field['upload_dir'] ) || ! is_writable( $field['upload_dir'] ) ) {
|
458 |
+
return;
|
459 |
+
}
|
460 |
+
|
461 |
+
$file_name = wp_unique_filename( $field['upload_dir'], basename( $file['name'] ) );
|
462 |
+
$path = trailingslashit( $field['upload_dir'] ) . $file_name;
|
463 |
+
move_uploaded_file( $file['tmp_name'], $path );
|
464 |
+
|
465 |
+
return self::convert_path_to_url( $path );
|
466 |
+
}
|
467 |
+
|
468 |
+
/**
|
469 |
+
* Convert a path to an URL.
|
470 |
+
*
|
471 |
+
* @param string $path Full path to a file or a directory.
|
472 |
+
* @return string URL to the file or directory.
|
473 |
+
*/
|
474 |
+
public static function convert_path_to_url( $path ) {
|
475 |
+
$path = wp_normalize_path( untrailingslashit( $path ) );
|
476 |
+
$root = wp_normalize_path( untrailingslashit( ABSPATH ) );
|
477 |
+
$relative_path = str_replace( $root, '', $path );
|
478 |
+
|
479 |
+
return home_url( $relative_path );
|
480 |
+
}
|
481 |
}
|
inc/fields/image-advanced.php
CHANGED
@@ -61,11 +61,13 @@ class RWMB_Image_Advanced_Field extends RWMB_Media_Field {
|
|
61 |
/**
|
62 |
* Get uploaded file information.
|
63 |
*
|
64 |
-
* @param int $file
|
65 |
-
* @param array $args
|
|
|
|
|
66 |
* @return array|bool False if file not found. Array of image info on success.
|
67 |
*/
|
68 |
-
public static function file_info( $file, $args = array() ) {
|
69 |
return RWMB_Image_Field::file_info( $file, $args );
|
70 |
}
|
71 |
|
61 |
/**
|
62 |
* Get uploaded file information.
|
63 |
*
|
64 |
+
* @param int $file Attachment image ID (post ID). Required.
|
65 |
+
* @param array $args Array of arguments (for size).
|
66 |
+
* @param array $field Field settings.
|
67 |
+
*
|
68 |
* @return array|bool False if file not found. Array of image info on success.
|
69 |
*/
|
70 |
+
public static function file_info( $file, $args = array(), $field ) {
|
71 |
return RWMB_Image_Field::file_info( $file, $args );
|
72 |
}
|
73 |
|
inc/fields/image.php
CHANGED
@@ -99,12 +99,13 @@ class RWMB_Image_Field extends RWMB_File_Field {
|
|
99 |
/**
|
100 |
* Get uploaded file information.
|
101 |
*
|
102 |
-
* @param int $file
|
103 |
-
* @param array $args
|
|
|
104 |
*
|
105 |
* @return array|bool False if file not found. Array of image info on success.
|
106 |
*/
|
107 |
-
public static function file_info( $file, $args = array() ) {
|
108 |
$path = get_attached_file( $file );
|
109 |
if ( ! $path ) {
|
110 |
return false;
|
99 |
/**
|
100 |
* Get uploaded file information.
|
101 |
*
|
102 |
+
* @param int $file Attachment image ID (post ID). Required.
|
103 |
+
* @param array $args Array of arguments (for size).
|
104 |
+
* @param array $field Field settings.
|
105 |
*
|
106 |
* @return array|bool False if file not found. Array of image info on success.
|
107 |
*/
|
108 |
+
public static function file_info( $file, $args = array(), $field ) {
|
109 |
$path = get_attached_file( $file );
|
110 |
if ( ! $path ) {
|
111 |
return false;
|
inc/fields/post.php
CHANGED
@@ -77,6 +77,14 @@ class RWMB_Post_Field extends RWMB_Object_Choice_Field {
|
|
77 |
'update_post_term_cache' => false,
|
78 |
)
|
79 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
80 |
$query = new WP_Query( $args );
|
81 |
$options = array();
|
82 |
foreach ( $query->posts as $post ) {
|
@@ -89,6 +97,10 @@ class RWMB_Post_Field extends RWMB_Object_Choice_Field {
|
|
89 |
(array) $post
|
90 |
);
|
91 |
}
|
|
|
|
|
|
|
|
|
92 |
return $options;
|
93 |
}
|
94 |
|
77 |
'update_post_term_cache' => false,
|
78 |
)
|
79 |
);
|
80 |
+
|
81 |
+
// Get from cache to prevent same queries.
|
82 |
+
$cache_key = md5( serialize( $args ) );
|
83 |
+
$options = wp_cache_get( $cache_key, 'meta-box-post-field' );
|
84 |
+
if ( false !== $options ) {
|
85 |
+
return $options;
|
86 |
+
}
|
87 |
+
|
88 |
$query = new WP_Query( $args );
|
89 |
$options = array();
|
90 |
foreach ( $query->posts as $post ) {
|
97 |
(array) $post
|
98 |
);
|
99 |
}
|
100 |
+
|
101 |
+
// Cache the query.
|
102 |
+
wp_cache_set( $cache_key, $options, 'meta-box-post-field' );
|
103 |
+
|
104 |
return $options;
|
105 |
}
|
106 |
|
inc/fields/user.php
CHANGED
@@ -48,6 +48,14 @@ class RWMB_User_Field extends RWMB_Object_Choice_Field {
|
|
48 |
'fields' => array( 'ID', $display_field ),
|
49 |
)
|
50 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
$users = get_users( $args );
|
52 |
$options = array();
|
53 |
foreach ( $users as $user ) {
|
@@ -59,6 +67,10 @@ class RWMB_User_Field extends RWMB_Object_Choice_Field {
|
|
59 |
(array) $user
|
60 |
);
|
61 |
}
|
|
|
|
|
|
|
|
|
62 |
return $options;
|
63 |
}
|
64 |
|
48 |
'fields' => array( 'ID', $display_field ),
|
49 |
)
|
50 |
);
|
51 |
+
|
52 |
+
// Get from cache to prevent same queries.
|
53 |
+
$cache_key = md5( serialize( $args ) );
|
54 |
+
$options = wp_cache_get( $cache_key, 'meta-box-user-field' );
|
55 |
+
if ( false !== $options ) {
|
56 |
+
return $options;
|
57 |
+
}
|
58 |
+
|
59 |
$users = get_users( $args );
|
60 |
$options = array();
|
61 |
foreach ( $users as $user ) {
|
67 |
(array) $user
|
68 |
);
|
69 |
}
|
70 |
+
|
71 |
+
// Cache the query.
|
72 |
+
wp_cache_set( $cache_key, $options, 'meta-box-user-field' );
|
73 |
+
|
74 |
return $options;
|
75 |
}
|
76 |
|
inc/fields/video.php
CHANGED
@@ -45,10 +45,11 @@ class RWMB_Video_Field extends RWMB_Media_Field {
|
|
45 |
*
|
46 |
* @param int $file_id Attachment image ID (post ID). Required.
|
47 |
* @param array $args Array of arguments (for size).
|
|
|
48 |
*
|
49 |
* @return array|bool False if file not found. Array of image info on success.
|
50 |
*/
|
51 |
-
public static function file_info( $file_id, $args = array() ) {
|
52 |
if ( ! get_attached_file( $file_id ) ) {
|
53 |
return false;
|
54 |
}
|
45 |
*
|
46 |
* @param int $file_id Attachment image ID (post ID). Required.
|
47 |
* @param array $args Array of arguments (for size).
|
48 |
+
* @param array $field Field settings.
|
49 |
*
|
50 |
* @return array|bool False if file not found. Array of image info on success.
|
51 |
*/
|
52 |
+
public static function file_info( $file_id, $args = array(), $field ) {
|
53 |
if ( ! get_attached_file( $file_id ) ) {
|
54 |
return false;
|
55 |
}
|
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.
|
22 |
|
23 |
list( $path, $url ) = self::get_path( dirname( dirname( __FILE__ ) ) );
|
24 |
|
@@ -86,8 +86,10 @@ class RWMB_Loader {
|
|
86 |
$core = new RWMB_Core();
|
87 |
$core->init();
|
88 |
|
89 |
-
|
90 |
-
|
|
|
|
|
91 |
|
92 |
// Validation module.
|
93 |
new RWMB_Validation();
|
18 |
*/
|
19 |
protected function constants() {
|
20 |
// Script version, used to add version for scripts and styles.
|
21 |
+
define( 'RWMB_VER', '4.16.0' );
|
22 |
|
23 |
list( $path, $url ) = self::get_path( dirname( dirname( __FILE__ ) ) );
|
24 |
|
86 |
$core = new RWMB_Core();
|
87 |
$core->init();
|
88 |
|
89 |
+
if ( is_admin() ) {
|
90 |
+
$about = new RWMB_About();
|
91 |
+
$about->init();
|
92 |
+
}
|
93 |
|
94 |
// Validation module.
|
95 |
new RWMB_Validation();
|
js/media.js
CHANGED
@@ -215,14 +215,17 @@ jQuery( function ( $ ) {
|
|
215 |
},
|
216 |
function ( item ) {
|
217 |
return item.cid;
|
218 |
-
}
|
|
|
219 |
|
220 |
this.listenTo( this.collection, 'add', this.addItemView );
|
221 |
this.listenTo( this.collection, 'remove', this.removeItemView );
|
222 |
this.listenTo( this.collection, 'reset', this.resetItemViews );
|
223 |
|
224 |
-
// Sort
|
225 |
-
this.
|
|
|
|
|
226 |
},
|
227 |
|
228 |
listenToItemView: function ( itemView ) {
|
@@ -321,37 +324,6 @@ jQuery( function ( $ ) {
|
|
321 |
} );
|
322 |
|
323 |
this._editFrame.open();
|
324 |
-
},
|
325 |
-
|
326 |
-
initSortable: function () {
|
327 |
-
var collection = this.controller.get( 'items' );
|
328 |
-
this.$el.sortable( {
|
329 |
-
// Clone the element and the clone will be dragged. Prevent trigger click on the image, which means reselect.
|
330 |
-
helper : 'clone',
|
331 |
-
|
332 |
-
// Record the initial `index` of the dragged model.
|
333 |
-
start: function ( event, ui ) {
|
334 |
-
ui.item.data( 'sortableIndexStart', ui.item.index() );
|
335 |
-
},
|
336 |
-
|
337 |
-
// Update the model's index in the collection.
|
338 |
-
// Do so silently, as the view is already accurate.
|
339 |
-
update: function ( event, ui ) {
|
340 |
-
var model = collection.at( ui.item.data( 'sortableIndexStart' ) );
|
341 |
-
|
342 |
-
// Silently shift the model to its new index.
|
343 |
-
collection.remove( model, {
|
344 |
-
silent: true
|
345 |
-
} );
|
346 |
-
collection.add( model, {
|
347 |
-
silent: true,
|
348 |
-
at: ui.item.index()
|
349 |
-
} );
|
350 |
-
|
351 |
-
// Fire the `reset` event to ensure other collections sync.
|
352 |
-
collection.trigger( 'reset', collection );
|
353 |
-
}
|
354 |
-
} );
|
355 |
}
|
356 |
} );
|
357 |
|
@@ -458,9 +430,8 @@ jQuery( function ( $ ) {
|
|
458 |
this.$el.data( 'id', this.model.cid );
|
459 |
},
|
460 |
|
461 |
-
|
462 |
events: {
|
463 |
-
'click .rwmb-overlay': function () {
|
464 |
this.trigger( 'click:switch', this.model );
|
465 |
return false;
|
466 |
},
|
215 |
},
|
216 |
function ( item ) {
|
217 |
return item.cid;
|
218 |
+
}
|
219 |
+
);
|
220 |
|
221 |
this.listenTo( this.collection, 'add', this.addItemView );
|
222 |
this.listenTo( this.collection, 'remove', this.removeItemView );
|
223 |
this.listenTo( this.collection, 'reset', this.resetItemViews );
|
224 |
|
225 |
+
// Sort items using helper 'clone' to prevent trigger click on the image, which means reselect.
|
226 |
+
this.$el.sortable( {
|
227 |
+
helper : 'clone'
|
228 |
+
} );
|
229 |
},
|
230 |
|
231 |
listenToItemView: function ( itemView ) {
|
324 |
} );
|
325 |
|
326 |
this._editFrame.open();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
327 |
}
|
328 |
} );
|
329 |
|
430 |
this.$el.data( 'id', this.model.cid );
|
431 |
},
|
432 |
|
|
|
433 |
events: {
|
434 |
+
'click .rwmb-image-overlay': function () {
|
435 |
this.trigger( 'click:switch', this.model );
|
436 |
return false;
|
437 |
},
|
js/osm.js
CHANGED
@@ -1,10 +1,6 @@
|
|
1 |
( function( $, L ) {
|
2 |
'use strict';
|
3 |
|
4 |
-
var osmTileLayer = L.tileLayer( 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
5 |
-
attribution: '© <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;
|
@@ -43,7 +39,9 @@
|
|
43 |
center: latLng,
|
44 |
zoom: 14
|
45 |
} );
|
46 |
-
|
|
|
|
|
47 |
this.marker = L.marker( latLng, {
|
48 |
draggable: true
|
49 |
} ).addTo( this.map );
|
1 |
( function( $, L ) {
|
2 |
'use strict';
|
3 |
|
|
|
|
|
|
|
|
|
4 |
// Use function construction to store map & DOM elements separately for each instance
|
5 |
var OsmField = function ( $container ) {
|
6 |
this.$container = $container;
|
39 |
center: latLng,
|
40 |
zoom: 14
|
41 |
} );
|
42 |
+
L.tileLayer( 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
43 |
+
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
44 |
+
} ).addTo( this.map );
|
45 |
this.marker = L.marker( latLng, {
|
46 |
draggable: true
|
47 |
} ).addTo( this.map );
|
js/select-tree.js
CHANGED
@@ -1,19 +1,45 @@
|
|
1 |
jQuery( function ( $ ) {
|
2 |
'use strict';
|
3 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
function update() {
|
5 |
var $this = $( this ),
|
6 |
val = $this.val(),
|
7 |
$selected = $this.siblings( "[data-parent-id='" + val + "']" ),
|
8 |
-
$notSelected = $this.
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
|
10 |
-
$selected.removeClass( 'hidden' );
|
11 |
-
$notSelected
|
12 |
-
.addClass( 'hidden' )
|
13 |
-
.find( 'select' )
|
14 |
-
.prop( 'selectedIndex', 0 );
|
15 |
}
|
16 |
|
|
|
|
|
17 |
$( '.rwmb-input' )
|
18 |
.on( 'change', '.rwmb-select-tree select', update )
|
19 |
.on( 'clone', '.rwmb-select-tree select', update );
|
1 |
jQuery( function ( $ ) {
|
2 |
'use strict';
|
3 |
|
4 |
+
function setInitialRequiredProp() {
|
5 |
+
var $this = $( this ),
|
6 |
+
required = $this.prop( 'required' );
|
7 |
+
|
8 |
+
if ( required ) {
|
9 |
+
$this.data( 'initial-required', required );
|
10 |
+
}
|
11 |
+
}
|
12 |
+
|
13 |
+
function unsetRequiredProp() {
|
14 |
+
$( this ).prop( 'required', false );
|
15 |
+
}
|
16 |
+
|
17 |
+
function setRequiredProp() {
|
18 |
+
var $this = $( this );
|
19 |
+
|
20 |
+
if ( $this.data( 'initial-required' ) ) {
|
21 |
+
$this.prop( 'required', true );
|
22 |
+
}
|
23 |
+
}
|
24 |
+
|
25 |
function update() {
|
26 |
var $this = $( this ),
|
27 |
val = $this.val(),
|
28 |
$selected = $this.siblings( "[data-parent-id='" + val + "']" ),
|
29 |
+
$notSelected = $this.siblings().not( $selected ),
|
30 |
+
options = $this.data( 'options' );
|
31 |
+
|
32 |
+
// Turn select into beautiful select2.
|
33 |
+
$this.removeClass( 'select2-hidden-accessible' );
|
34 |
+
$this.siblings( '.select2-container' ).remove();
|
35 |
+
$this.show().select2( options );
|
36 |
|
37 |
+
$selected.removeClass( 'hidden' ).find( 'select' ).each( setRequiredProp );
|
38 |
+
$notSelected.addClass( 'hidden' ).find( 'select' ).each( unsetRequiredProp ).prop( 'selectedIndex', 0 );
|
|
|
|
|
|
|
39 |
}
|
40 |
|
41 |
+
$( '.rwmb-select-tree select' ).select2();
|
42 |
+
$( '.rwmb-select-tree select' ).each( setInitialRequiredProp );
|
43 |
$( '.rwmb-input' )
|
44 |
.on( 'change', '.rwmb-select-tree select', update )
|
45 |
.on( 'clone', '.rwmb-select-tree select', update );
|
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.
|
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.16.0
|
7 |
* Author: MetaBox.io
|
8 |
* Author URI: https://metabox.io
|
9 |
* License: GPL2+
|
readme.txt
CHANGED
@@ -3,8 +3,8 @@ Contributors: metabox, rilwis, fitwp, f-j-kaiser, funkatronic, PerWiklander, rua
|
|
3 |
Donate link: https://metabox.io/pricing/
|
4 |
Tags: meta-box, custom fields, custom field, meta, meta-boxes, admin, advanced, custom, edit, field, file, image, magic fields, matrix, more fields, Post, repeater, simple fields, text, textarea, type, cms, fields post
|
5 |
Requires at least: 4.3
|
6 |
-
Tested up to: 5.0
|
7 |
-
Stable tag: 4.
|
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.
|
3 |
Donate link: https://metabox.io/pricing/
|
4 |
Tags: meta-box, custom fields, custom field, meta, meta-boxes, admin, advanced, custom, edit, field, file, image, magic fields, matrix, more fields, Post, repeater, simple fields, text, textarea, type, cms, fields post
|
5 |
Requires at least: 4.3
|
6 |
+
Tested up to: 5.0.3
|
7 |
+
Stable tag: 4.16.0
|
8 |
License: GPLv2 or later
|
9 |
|
10 |
Meta Box plugin is a powerful, professional developer toolkit to create custom meta boxes and custom fields for WordPress.
|