PluginProbe ʕ •ᴥ•ʔ
JetFormBuilder — Dynamic Blocks Form Builder / 2.0.3
JetFormBuilder — Dynamic Blocks Form Builder v2.0.3
3.6.3.1 3.6.3 3.6.2.2 3.6.2.1 3.6.2 3.6.1.1 3.6.1 3.6.0.1 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.3.0 1.3.1 1.3.2 1.3.3 1.4.0 1.4.1 1.4.2 1.4.3 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.1.0 2.1.1 2.1.10 2.1.11 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 3.0.0 3.0.0.1 3.0.0.2 3.0.0.3 3.0.1 3.0.1.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.0.1 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.3.2 3.3.3 3.3.3.1 3.3.4 3.3.4.1 3.3.4.2 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.5.1 3.4.5.2 3.4.6 3.4.7 3.4.7.1 3.5.0 3.5.1 3.5.1.1 3.5.1.2 3.5.2 3.5.2.1 3.5.3 3.5.4 3.5.5 3.5.6 3.5.6.1 3.5.6.2 3.5.6.3 3.6.0
jetformbuilder / includes / file-upload.php
jetformbuilder / includes Last commit date
actions 4 years ago addons 4 years ago admin 4 years ago blocks 4 years ago classes 4 years ago compatibility 4 years ago db-queries 4 years ago dev-mode 4 years ago exceptions 4 years ago form-actions 4 years ago form-messages 4 years ago form-patterns 4 years ago form-response 4 years ago gateways 4 years ago generators 4 years ago integrations 4 years ago presets 4 years ago request 4 years ago rest-api 4 years ago shortcodes 4 years ago widgets 4 years ago autoloader.php 4 years ago file-upload.php 4 years ago form-break.php 4 years ago form-handler.php 4 years ago form-manager.php 4 years ago live-form.php 4 years ago plugin.php 4 years ago post-type.php 4 years ago
file-upload.php
600 lines
1 <?php
2
3 namespace Jet_Form_Builder;
4
5 use Jet_Form_Builder\Classes\Instance_Trait;
6 use Jet_Form_Builder\Classes\Tools;
7
8 // If this file is called directly, abort.
9 if ( ! defined( 'WPINC' ) ) {
10 die;
11 }
12
13 /**
14 * @method static File_Upload instance()
15 *
16 * Class description
17 *
18 * @package package_name
19 * @author Cherry Team
20 * @license GPL-2.0+
21 */
22 class File_Upload {
23
24 use Instance_Trait;
25
26 private $nonce_key = 'jet-form-builder-file-upload-nonce-key';
27 private $action = 'jet-form-builder-upload-file';
28 private $errors = array();
29 private $rendered_scripts = false;
30
31 public function __construct() {
32 add_action( 'wp_ajax_' . $this->action, array( $this, 'ajax_file_upload' ) );
33 add_action( 'wp_ajax_nopriv_' . $this->action, array( $this, 'ajax_file_upload' ) );
34 }
35
36
37 /**
38 * Returns data arguments for files wrapper
39 */
40 public function get_files_data_args( $args ) {
41
42 $data_args = array(
43 'max_files' => 1,
44 'insert_attachment' => false,
45 'value_format' => 'url',
46 );
47
48 foreach ( $data_args as $key => $value ) {
49 $data_args[ $key ] = ! empty( $args[ $key ] ) ? $args[ $key ] : $value;
50 }
51
52 return sprintf( ' data-args="%s"', htmlspecialchars( wp_json_encode( $data_args ) ) );
53 }
54
55 /**
56 * Ajax callback for uploading files
57 *
58 * @return [type] [description]
59 */
60 public function ajax_file_upload() {
61
62 $nonce = sanitize_text_field( wp_unslash( $_POST['nonce'] ?? '' ) );
63 $form_id = absint( wp_unslash( $_POST['form_id'] ?? 0 ) );
64 $field = sanitize_text_field( wp_unslash( $_POST['field'] ?? '' ) );
65
66 if ( ! $nonce || ! wp_verify_nonce( $nonce, $this->nonce_key ) ) {
67 wp_send_json_error( __( 'You not allowed to do this', 'jet-form-builder' ) );
68 }
69
70 if ( ! $form_id || ! $field ) {
71 wp_send_json_error( __( 'Required parameters not found in request', 'jet-form-builder' ) );
72 }
73
74 $form_data = Plugin::instance()->form->get_only_form_fields( $form_id );
75
76 if ( ! $form_data ) {
77 wp_send_json_error( __( 'Form data not found', 'jet-form-builder' ) );
78 }
79
80 $field_data = null;
81
82 foreach ( $form_data as $item ) {
83 if ( ! empty( $item['attrs']['name'] ) && $item['attrs']['name'] === $field ) {
84 $field_data = $item['attrs'];
85 break;
86 }
87 }
88
89 if ( ! $field_data ) {
90 wp_send_json_error( __( 'Requested field not found', 'jet-form-builder' ) );
91 }
92
93 $cap = ! empty( $field_data['allowed_user_cap'] ) ? $field_data['allowed_user_cap'] : 'upload_files';
94
95 if ( 'any_user' !== $cap && ! is_user_logged_in() ) {
96 wp_send_json_error( __( 'You are not allowed to upload files', 'jet-form-builder' ) );
97 }
98
99 if ( ! in_array( $cap, array( 'all', 'any_user' ) ) && ! current_user_can( $cap ) ) {
100 wp_send_json_error( __( 'You are not allowed to upload files', 'jet-form-builder' ) );
101 }
102
103 // Prevent non logged-in users insert attachment
104 if ( ! is_user_logged_in() ) {
105 $field_data['insert_attachment'] = false;
106 }
107
108 $settings = array(
109 'max_size' => $this->get_max_size_for_field( $field_data ),
110 );
111
112 $settings['messages'] = jet_form_builder()->msg_router->get_manager(
113 array(
114 'form_id' => $form_id,
115 )
116 );
117
118 $settings = array_merge( $field_data, $settings );
119
120 $result = $this->process_upload( $_FILES, $settings );
121
122 if ( ! $result ) {
123 wp_send_json_error( $settings['messages']['internal'] );
124 }
125
126 wp_send_json_success(
127 array(
128 'files' => $result,
129 'html' => $this->get_result_html( $settings, $result ),
130 'value' => $this->get_result_value( $settings, $result ),
131 'errors' => $this->get_errors_string(),
132 )
133 );
134 }
135
136 /**
137 * Process files upload
138 *
139 * @param boolean $files [description]
140 *
141 * @return [type] [description]
142 */
143 public function process_upload( $files = false, $settings = array() ) {
144
145 $settings = wp_parse_args(
146 $settings,
147 array(
148 'max_size' => wp_max_upload_size(),
149 'max_files' => 1,
150 'insert_attachment' => false,
151 )
152 );
153 $settings['max_files'] = $settings['max_files'] ? $settings['max_files'] : 1;
154
155 $insert_attachment = filter_var( $settings['insert_attachment'], FILTER_VALIDATE_BOOLEAN );
156
157 $files = Tools::sanitize_files( $files );
158
159 if ( empty( $files ) || ! is_array( $files ) ) {
160 return false;
161 }
162
163 if ( count( $files ) > $settings['max_files'] ) {
164 wp_send_json_error( $settings['messages']['upload_max_files'] );
165 }
166
167 $result = array();
168 $index = 0;
169
170 foreach ( $files as $file ) {
171
172 if ( ! $file['size'] > $settings['max_size'] ) {
173 wp_send_json_error( $settings['messages']['upload_max_size'] );
174 }
175
176 if ( ! empty( $settings['mime_types'] ) && ! in_array( $file['type'], $settings['mime_types'] ) ) {
177 wp_send_json_error( $settings['messages']['upload_mime_types'] );
178 }
179
180 $result[] = $this->upload_file( $file, $insert_attachment );
181
182 }
183
184 return $result;
185
186 }
187
188 /**
189 * Upload file
190 *
191 * @return [type] [description]
192 */
193 public function upload_file( $file = array(), $insert_attachment = false ) {
194
195 $result = array();
196
197 if ( ! function_exists( 'wp_handle_upload' ) ) {
198 include_once ABSPATH . 'wp-admin/includes/file.php';
199 include_once ABSPATH . 'wp-admin/includes/media.php';
200 }
201
202 add_filter( 'upload_dir', array( $this, 'apply_upload_dir' ) );
203
204 $upload = wp_handle_upload(
205 $file,
206 array( 'test_form' => false )
207 );
208
209 if ( empty( $upload['error'] ) && $insert_attachment ) {
210
211 $filepath = $upload['file'];
212 $attachment = wp_insert_attachment(
213 array(
214 'guid' => $upload['url'],
215 'post_mime_type' => $upload['type'],
216 'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $filepath ) ),
217 'post_content' => '',
218 'post_status' => 'publish',
219 ),
220 $filepath,
221 0,
222 true
223 );
224
225 if ( ! is_wp_error( $attachment ) ) {
226 $metadata = wp_generate_attachment_metadata( $attachment, $filepath );
227 wp_update_attachment_metadata( $attachment, $metadata );
228 } else {
229 $this->errors[] = $attachment->get_error_message();
230 }
231
232 $upload['attachment'] = $attachment;
233
234 } elseif ( ! empty( $upload['error'] ) ) {
235 $this->errors[] = $upload['error'];
236 }
237
238 remove_filter( 'upload_dir', array( $this, 'apply_upload_dir' ) );
239
240 return $upload;
241
242 }
243
244 /**
245 * Try to get files array from field data
246 *
247 * @param array $field [description]
248 * @param string $format [description]
249 *
250 * @return [type] [description]
251 */
252 public function get_files_from_field( $field = array(), $format = 'url' ) {
253
254 $files = array();
255 $value = ! empty( $field['default'] ) ? $field['default'] : array();
256
257 if ( ! is_array( $value ) ) {
258 if ( 'both' !== $format ) {
259 $value = explode( ',', str_replace( ', ', ',', $value ) );
260 } else {
261 if ( false !== strpos( $value, '{' ) ) {
262 $value = json_decode( wp_unslash( $value ), true );
263 } else {
264 return $files;
265 }
266 }
267 }
268
269 if ( 'both' === $format ) {
270 $value = isset( $value['id'] ) ? array( $value ) : $value;
271 }
272
273 foreach ( $value as $val ) {
274 switch ( $format ) {
275 case 'id':
276 $files[] = array(
277 'url' => wp_get_attachment_url( $val ),
278 'attachment' => $val,
279 );
280 break;
281
282 case 'url':
283 $files[] = array(
284 'url' => $val,
285 );
286 break;
287
288 case 'both':
289 if ( is_array( $val ) && isset( $val['url'] ) && isset( $val['id'] ) ) {
290 $files[] = array(
291 'url' => $val['url'],
292 'attachment' => $val['id'],
293 );
294 }
295 break;
296 }
297 }
298
299 return $files;
300 }
301
302 /**
303 * Returns formatted HTML result
304 *
305 * @return [type] [description]
306 */
307 public function get_result_html( $field = array(), $files = array() ) {
308
309 if ( ! empty( $field['insert_attachment'] ) ) {
310 $result_format = ! empty( $field['value_format'] ) ? $field['value_format'] : 'url';
311 } else {
312 $result_format = 'url';
313 }
314
315 if ( empty( $files ) ) {
316 $files = $this->get_files_from_field( $field, $result_format );
317 }
318
319 if ( empty( $files ) ) {
320 return '';
321 }
322
323 $format = '<div class="jet-form-builder-file-upload__file" data-file="%1$s" data-id="%2$s" data-format="%3$s">%4$s<div class="jet-form-builder-file-upload__file-remove"><svg width="22" height="22" viewBox="0 0 14 15" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M4.375 7H6.125V12.25H4.375V7ZM7.875 7H9.625V12.25H7.875V7ZM10.5 1.75C10.5 1.51302 10.4134 1.30794 10.2402 1.13477C10.0762 0.961589 9.87109 0.875 9.625 0.875H4.375C4.12891 0.875 3.91927 0.961589 3.74609 1.13477C3.58203 1.30794 3.5 1.51302 3.5 1.75V3.5H0V5.25H0.875V14C0.875 14.237 0.957031 14.4421 1.12109 14.6152C1.29427 14.7884 1.50391 14.875 1.75 14.875H12.25C12.4961 14.875 12.7012 14.7884 12.8652 14.6152C13.0384 14.4421 13.125 14.237 13.125 14V5.25H14V3.5H10.5V1.75ZM5.25 2.625H8.75V3.5H5.25V2.625ZM11.375 5.25V13.125H2.625V5.25H11.375Z"></path></svg></div>%5$s</div>';
324
325 $result = '';
326
327 foreach ( $files as $file ) {
328
329 if ( ! empty( $file['attachment'] ) && ! is_wp_error( $file['attachment'] ) ) {
330 $attachment = $file['attachment'];
331 } else {
332 $attachment = 0;
333 }
334
335 $img_preview = '';
336
337 $image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'svg' );
338 $img_ext_preg = '!\.(' . join( '|', $image_exts ) . ')$!i';
339
340 if ( preg_match( $img_ext_preg, $file['url'] ) ) {
341 $img_preview = sprintf( '<img src="%s" alt="">', $file['url'] );
342 }
343
344 $result .= sprintf(
345 $format,
346 ...apply_filters(
347 'jet-form-builder/file-upload/render-file-params',
348 array(
349 $file['url'],
350 $attachment,
351 $result_format,
352 $img_preview,
353 apply_filters( 'jet-form-builder/file-upload/custom-html', '', $file, $field ),
354 )
355 )
356 );
357
358 }
359
360 return $result;
361
362 }
363
364 public function get_loader() {
365 return '<div class="jet-form-builder-file-upload__loader">' . apply_filters(
366 'jet-form-builder/file-upload/loader',
367 '<svg xmlns="http://www.w3.org/2000/svg" width="38" height="38" viewBox="0 0 38 38" stroke="#fff"><g fill="none" fill-rule="evenodd"><g transform="translate(1 1)" stroke-width="2"><circle stroke-opacity=".5" cx="18" cy="18" r="18"/><path d="M36 18c0-9.94-8.06-18-18-18" transform="rotate(137.826 18 18)"><animateTransform attributeName="transform" type="rotate" from="0 18 18" to="360 18 18" dur="1s" repeatCount="indefinite"/></path></g></g></svg>'
368 ) . '</div>';
369 }
370
371 /**
372 * Returns formatted result array
373 *
374 * @param array $field [description]
375 * @param array $files [description]
376 *
377 * @return [type] [description]
378 */
379 public function get_result_value( $field = array(), $files = array() ) {
380
381 if ( ! empty( $field['insert_attachment'] ) ) {
382 $format = ! empty( $field['value_format'] ) ? $field['value_format'] : 'url';
383 } else {
384 $format = 'url';
385 }
386
387 if ( empty( $files ) ) {
388 $files = $this->get_files_from_field( $field, $format );
389 }
390
391 if ( empty( $files ) ) {
392 return '';
393 }
394
395 $limit = ! empty( $field['max_files'] ) ? absint( $field['max_files'] ) : 1;
396 $limit = $limit ? $limit : 1;
397 $result = array();
398
399 foreach ( $files as $file ) {
400
401 if ( isset( $file['attachment'] ) && ! is_wp_error( $file['attachment'] ) ) {
402 $id = $file['attachment'];
403 } else {
404 $id = false;
405 }
406
407 $url = ! empty( $file['url'] ) ? $file['url'] : false;
408
409 switch ( $format ) {
410 case 'id':
411 if ( 1 < $limit ) {
412 $result[] = $id;
413 } else {
414 $result = $id;
415 }
416 break;
417
418 case 'url':
419 if ( 1 < $limit ) {
420 $result[] = $url;
421 } else {
422 $result = $url;
423 }
424 break;
425
426 case 'both':
427 if ( $url && $id ) {
428 if ( 1 < $limit ) {
429 $result[] = array(
430 'id' => $id,
431 'url' => $url,
432 );
433 } else {
434 $result = array(
435 'id' => $id,
436 'url' => $url,
437 );
438 }
439 }
440 break;
441 }
442 }
443
444 return is_array( $result ) ? array_filter( $result ) : $result;
445
446 }
447
448 /**
449 * Returns stringified uploading errors
450 *
451 * @return string
452 */
453 public function get_errors_string() {
454
455 if ( empty( $this->errors ) ) {
456 return null;
457 }
458
459 if ( 1 === count( $this->errors ) ) {
460 return $this->errors[0];
461 } else {
462
463 $result = '';
464
465 foreach ( $this->errors as $error ) {
466 $result .= '- ' . $error . '<br>';
467 }
468
469 return $result;
470
471 }
472
473 }
474
475 /**
476 * Resturns max upload size based on field arguments
477 *
478 * @param array $args [description]
479 *
480 * @return [type] [description]
481 */
482 public function get_max_size_for_field( $args = array() ) {
483
484 $max_size = wp_max_upload_size();
485 $field_max_size = $max_size;
486
487 if ( ! empty( $args['max_size'] ) ) {
488
489 $field_max_size = intval( floatval( $args['max_size'] ) * MB_IN_BYTES );
490
491 if ( $field_max_size > $max_size ) {
492 $field_max_size = $max_size;
493 }
494 }
495
496 return $field_max_size;
497
498 }
499
500
501 /**
502 * Returns upload subdirectory
503 *
504 * @return [type] [description]
505 */
506 public function get_upload_dir() {
507
508 $user_id = get_current_user_id();
509 $user_dir_name = $user_id ? $user_id : 'guest';
510 $user_dir_name = apply_filters( 'jet-form-builder/file-upload/user-dir-name', $user_dir_name );
511
512 return $this->upload_base() . '/' . $user_dir_name;
513 }
514
515 /**
516 * Returns upload base directory
517 *
518 * @return [type] [description]
519 */
520 public function upload_base() {
521 return apply_filters( 'jet-form-builder/file-upload/dir', 'jet-form-builder' );
522 }
523
524 /**
525 * Change upload directory for JetEngine uploads
526 *
527 * @param [type] $pathdata [description]
528 *
529 * @return [type] [description]
530 */
531 public function apply_upload_dir( $pathdata ) {
532
533 $dir = $this->get_upload_dir();
534
535 if ( empty( $pathdata['subdir'] ) ) {
536 $pathdata['path'] = $pathdata['path'] . '/' . $dir;
537 $pathdata['url'] = $pathdata['url'] . '/' . $dir;
538 $pathdata['subdir'] = '/' . $dir;
539 } else {
540 $new_subdir = '/' . $dir . $pathdata['subdir'];
541 $pathdata['path'] = str_replace( $pathdata['subdir'], $new_subdir, $pathdata['path'] );
542 $pathdata['url'] = str_replace( $pathdata['subdir'], $new_subdir, $pathdata['url'] );
543 $pathdata['subdir'] = $new_subdir;
544 }
545
546 return $pathdata;
547
548 }
549
550 /**
551 * Register form-specific assets
552 *
553 * @return void
554 */
555 public function enqueue_scripts() {
556 wp_enqueue_script( 'jet-form-builder-sortable' );
557 wp_enqueue_script( 'jet-form-builder-file-upload' );
558
559 $messages = wp_json_encode( jet_form_builder()->msg_router->get_manager()->get_messages() );
560 $form_id = (int) Live_Form::instance()->form_id;
561
562 wp_localize_script(
563 'jet-form-builder-file-upload',
564 'JetFormBuilderFileUploadConfig',
565 array(
566 'ajaxurl' => esc_url_raw( admin_url( 'admin-ajax.php' ) ),
567 'action' => $this->action,
568 'nonce' => wp_create_nonce( $this->nonce_key ),
569 'max_upload_size' => wp_max_upload_size(),
570 )
571 );
572
573 wp_add_inline_script(
574 'jet-form-builder-file-upload',
575 "
576 window.JetFormBuilderFileUploadConfig = window.JetFormBuilderFileUploadConfig || {};
577 window.JetFormBuilderFileUploadConfig.errors = window.JetFormBuilderFileUploadConfig.errors || {};
578
579 window.JetFormBuilderFileUploadConfig.errors[ $form_id ] = $messages;
580 "
581 );
582 }
583
584 public function ensure_media_js( $content = '' ) {
585 if ( $this->rendered_scripts ) {
586 return $content;
587 }
588 $this->rendered_scripts = true;
589
590 ob_start();
591 jet_form_builder()->blocks->register_form_scripts();
592
593 $this->enqueue_scripts();
594 wp_scripts()->print_scripts( 'jet-form-builder-file-upload' );
595
596 return $content . ob_get_clean();
597 }
598
599 }
600