PluginProbe
JetFormBuilder — Dynamic Blocks Form Builder / 1.0.2
JetFormBuilder — Dynamic Blocks Form Builder v1.0.2
3.6.5.2 3.6.5.1 3.6.5 3.6.4.2 3.6.4.1 3.6.4 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 All 130 releases
jetformbuilder / includes / file-upload.php
file-upload.php
597 lines 15.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Jet_Form_Builder;
4
5 use Jet_Form_Builder\Classes\Tools;
6
7 /**
8 * Class description
9 *
10 * @package package_name
11 * @author Cherry Team
12 * @license GPL-2.0+
13 */
14
15 // If this file is called directly, abort.
16 if ( ! defined( 'WPINC' ) ) {
17 die;
18 }
19
20 class File_Upload {
21
22 private $nonce_key = 'jet-form-builder-file-upload-nonce-key';
23 private $action = 'jet-form-builder-upload-file';
24 private $errors = array();
25
26 /**
27 * A reference to an instance of this class.
28 *
29 * @since 1.0.0
30 * @access private
31 * @var object
32 */
33 private static $instance = null;
34
35 public function __construct() {
36 add_action( 'wp_ajax_' . $this->action, array( $this, 'ajax_file_upload' ) );
37 add_action( 'wp_ajax_nopriv_' . $this->action, array( $this, 'ajax_file_upload' ) );
38 }
39
40 public function enqueue_scripts() {
41 $this->register_assets();
42 $this->enqueue_upload_script();
43 }
44
45 /**
46 * Returns data arguments for files wrapper
47 */
48 public function get_files_data_args( $args ) {
49
50 $data_args = array(
51 'max_files' => 1,
52 'insert_attachment' => false,
53 'value_format' => 'id',
54 );
55
56 foreach ( $data_args as $key => $value ) {
57 $data_args[ $key ] = ! empty( $args[ $key ] ) ? $args[ $key ] : $value;
58 }
59
60 return sprintf( ' data-args="%s"', htmlspecialchars( json_encode( $data_args ) ) );
61 }
62
63 /**
64 * Ajax callback for uploading files
65 *
66 * @return [type] [description]
67 */
68 public function ajax_file_upload() {
69
70 if ( ! is_user_logged_in() ) {
71 return;
72 }
73
74 $nonce = ! empty( $_REQUEST['nonce'] ) ? esc_attr( $_REQUEST['nonce'] ) : false;
75 $form_id = ! empty( $_REQUEST['form_id'] ) ? absint( $_REQUEST['form_id'] ) : false;
76 $field = ! empty( $_REQUEST['field'] ) ? sanitize_key( $_REQUEST['field'] ) : false;
77
78 if ( ! $nonce || ! wp_verify_nonce( $nonce, $this->nonce_key ) ) {
79 wp_send_json_error( __( 'You not allowed to do this', 'jet-form-builder' ) );
80 }
81
82 if ( ! $form_id || ! $field ) {
83 wp_send_json_error( __( 'Required parameters not found in request', 'jet-form-builder' ) );
84 }
85
86 $form_data = Plugin::instance()->form->get_only_form_fields( $form_id );
87
88 if ( ! $form_data ) {
89 wp_send_json_error( __( 'Form data not found', 'jet-form-builder' ) );
90 }
91
92 $field_data = null;
93
94 foreach ( $form_data as $item ) {
95 if ( ! empty( $item['attrs']['name'] ) && $item['attrs']['name'] === $field ) {
96 $field_data = $item['attrs'];
97 break;
98 }
99 }
100
101 if ( ! $field_data ) {
102 wp_send_json_error( __( 'Requested field not found', 'jet-form-builder' ) );
103 }
104
105 $cap = ! empty( $field_data['allowed_user_cap'] ) ? $field_data['allowed_user_cap'] : 'upload_files';
106
107 if ( 'all' !== $cap && ! current_user_can( $cap ) ) {
108 wp_send_json_error( __( 'You are not allowed to upload files', 'jet-form-builder' ) );
109 }
110
111 $settings = array(
112 'max_size' => $this->get_max_size_for_field( $field_data ),
113 );
114
115 if ( ! empty( $field_data['allowed_mimes'] ) ) {
116 $settings['mime_types'] = $field_data['allowed_mimes'];
117 }
118
119 if ( ! empty( $field_data['max_files'] ) ) {
120 $settings['max_files'] = $field_data['max_files'];
121 }
122
123 if ( ! empty( $field_data['insert_attachment'] ) ) {
124 $settings['insert_attachment'] = $field_data['insert_attachment'];
125 }
126
127 $message_builder = Plugin::instance()->form_handler->get_message_builder( $form_id );
128 $settings['messages'] = $message_builder->manager->get_messages();
129
130 $result = $this->process_upload( $_FILES, $settings );
131
132 if ( ! $result ) {
133 wp_send_json_error( __( 'Internal error. Plaese check uploaded files and try again.', 'jet-form-builder' ) );
134 }
135
136 wp_send_json_success( array(
137 'files' => $result,
138 'html' => $this->get_result_html( $field_data, $result ),
139 'value' => $this->get_result_value( $field_data, $result ),
140 'errors' => $this->get_errors_string(),
141 ) );
142
143 }
144
145 /**
146 * Process files upload
147 *
148 * @param boolean $files [description]
149 *
150 * @return [type] [description]
151 */
152 public function process_upload( $files = false, $settings = array() ) {
153
154 $settings = wp_parse_args( $settings, array(
155 'max_size' => wp_max_upload_size(),
156 'max_files' => 1,
157 'insert_attachment' => false,
158 ) );
159
160 $insert_attachment = filter_var( $settings['insert_attachment'], FILTER_VALIDATE_BOOLEAN );
161
162 $files = Tools::sanitize_files( $files );
163
164 if ( empty( $files ) || ! is_array( $files ) ) {
165 return false;
166 }
167
168 if ( count( $files ) > $settings['max_files'] ) {
169 wp_send_json_error( $settings['messages']['upload_max_files'] );
170 }
171
172 $result = array();
173 $index = 0;
174
175 foreach ( $files as $file ) {
176
177 if ( ! $file['size'] > $settings['max_size'] ) {
178 wp_send_json_error( $settings['messages']['upload_max_size'] );
179 }
180
181 if ( ! empty( $settings['mime_types'] ) && ! in_array( $file['type'], $settings['mime_types'] ) ) {
182 wp_send_json_error( $settings['messages']['upload_mime_types'] );
183 }
184
185 $result[] = $this->upload_file( $file, $insert_attachment );
186
187 }
188
189 return $result;
190
191 }
192
193 /**
194 * Upload file
195 *
196 * @return [type] [description]
197 */
198 public function upload_file( $file = array(), $insert_attachment = false ) {
199
200 $result = array();
201
202 if ( ! function_exists( 'wp_handle_upload' ) ) {
203 include_once ABSPATH . 'wp-admin/includes/file.php';
204 include_once ABSPATH . 'wp-admin/includes/media.php';
205 }
206
207 add_filter( 'upload_dir', array( $this, 'apply_upload_dir' ) );
208
209 $upload = wp_handle_upload(
210 $file,
211 array( 'test_form' => false )
212 );
213
214 if ( empty( $upload['error'] ) && $insert_attachment ) {
215
216 $filepath = $upload['file'];
217 $attachment = wp_insert_attachment(
218 array(
219 'guid' => $upload['url'],
220 'post_mime_type' => $upload['type'],
221 'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $filepath ) ),
222 'post_content' => '',
223 'post_status' => 'publish'
224 ),
225 $filepath,
226 0,
227 true
228 );
229
230 if ( ! is_wp_error( $attachment ) ) {
231 $metadata = wp_generate_attachment_metadata( $attachment, $filepath );
232 wp_update_attachment_metadata( $attachment, $metadata );
233 } else {
234 $this->errors[] = $attachment->get_error_message();
235 }
236
237 $upload['attachment'] = $attachment;
238
239 } elseif ( ! empty( $upload['error'] ) ) {
240 $this->errors[] = $upload['error'];
241 }
242
243 remove_filter( 'upload_dir', array( $this, 'apply_upload_dir' ) );
244
245 return $upload;
246
247 }
248
249 /**
250 * Try to get files array from field data
251 *
252 * @param array $field [description]
253 * @param string $format [description]
254 *
255 * @return [type] [description]
256 */
257 public function get_files_from_field( $field = array(), $format = 'url' ) {
258
259 $files = array();
260 $value = ! empty( $field['default'] ) ? $field['default'] : array();
261
262 if ( ! is_array( $value ) ) {
263 if ( 'both' !== $format ) {
264 $value = explode( ',', str_replace( ', ', ',', $value ) );
265 } else {
266 return $files;
267 }
268 }
269
270 foreach ( $value as $val ) {
271
272 switch ( $format ) {
273
274 case 'id':
275
276 $files[] = array(
277 'url' => wp_get_attachment_url( $val ),
278 'attachment' => $val,
279 );
280
281 break;
282
283 case 'url':
284
285 $files[] = array(
286 'url' => $val,
287 );
288
289 break;
290
291 case 'both':
292 if ( is_array( $val ) && isset( $val['url'] ) && isset( $val['id'] ) ) {
293 $files[] = array(
294 'url' => $val['url'],
295 'attachment' => $val['id'],
296 );
297 }
298
299 break;
300 }
301
302 }
303
304 return $files;
305 }
306
307 /**
308 * Returns formatted HTML result
309 *
310 * @return [type] [description]
311 */
312 public function get_result_html( $field = array(), $files = array() ) {
313
314 if ( ! empty( $field['insert_attachment'] ) ) {
315 $result_format = ! empty( $field['value_format'] ) ? $field['value_format'] : 'id';
316 } else {
317 $result_format = 'id';
318 }
319
320 if ( empty( $files ) ) {
321 $files = $this->get_files_from_field( $field, $result_format );
322 }
323
324 if ( empty( $files ) ) {
325 return;
326 }
327
328 $format = '<div class="jet-form-builder-file-upload__file" data-file="%1$s" data-id="%2$s" data-format="%3$s"><img src="%1$s" alt=""><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></div>';
329
330 $result = '';
331
332 foreach ( $files as $file ) {
333
334 if ( ! empty( $file['attachment'] ) && ! is_wp_error( $file['attachment'] ) ) {
335 $attachment = $file['attachment'];
336 } else {
337 $attachment = 0;
338 }
339
340 $result .= sprintf( $format, $file['url'], $attachment, $result_format );
341
342 }
343
344 return $result;
345
346 }
347
348 public function get_loader() {
349 return '<div class="jet-form-builder-file-upload__loader">' . apply_filters(
350 'jet-form-builder/file-upload/loader',
351 '<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>'
352 ) . '</div>';
353 }
354
355 /**
356 * Returns formatted result array
357 *
358 * @param array $field [description]
359 * @param array $files [description]
360 *
361 * @return [type] [description]
362 */
363 public function get_result_value( $field = array(), $files = array() ) {
364
365 if ( ! empty( $field['insert_attachment'] ) ) {
366 $format = ! empty( $field['value_format'] ) ? $field['value_format'] : 'id';
367 } else {
368 $format = 'url';
369 }
370
371 if ( empty( $files ) ) {
372 $files = $this->get_files_from_field( $field, $format );
373 }
374
375 if ( empty( $files ) ) {
376 return '';
377 }
378
379 $limit = ! empty( $field['max_files'] ) ? absint( $field['max_files'] ) : 1;
380 $limit = $limit ? $limit : 1;
381 $result = array();
382
383 foreach ( $files as $file ) {
384
385 if ( isset( $file['attachment'] ) && ! is_wp_error( $file['attachment'] ) ) {
386 $id = $file['attachment'];
387 } else {
388 $id = false;
389 }
390
391 $url = ! empty( $file['url'] ) ? $file['url'] : false;
392
393 switch ( $format ) {
394 case 'id':
395 if ( 1 < $limit ) {
396 $result[] = $id;
397 } else {
398 $result = $id;
399 }
400 break;
401
402 case 'url':
403 if ( 1 < $limit ) {
404 $result[] = $url;
405 } else {
406 $result = $url;
407 }
408 break;
409
410 case 'both':
411 if ( $url && $id ) {
412 if ( 1 < $limit ) {
413 $result[] = array(
414 'id' => $id,
415 'url' => $url,
416 );
417 } else {
418 $result = array(
419 'id' => $id,
420 'url' => $url,
421 );
422 }
423 }
424 break;
425 }
426 }
427
428 return is_array( $result ) ? array_filter( $result ) : $result;
429
430 }
431
432 /**
433 * Returns stringified uploading errors
434 *
435 * @return string
436 */
437 public function get_errors_string() {
438
439 if ( empty( $this->errors ) ) {
440 return null;
441 }
442
443 if ( 1 === count( $this->errors ) ) {
444 return $this->errors[0];
445 } else {
446
447 $result = '';
448
449 foreach ( $this->errors as $error ) {
450 $result .= '- ' . $error . '<br>';
451 }
452
453 return $result;
454
455 }
456
457 }
458
459 /**
460 * Resturns max upload size based on field arguments
461 *
462 * @param array $args [description]
463 *
464 * @return [type] [description]
465 */
466 public function get_max_size_for_field( $args = array() ) {
467
468 $max_size = wp_max_upload_size();
469 $field_max_size = $max_size;
470
471 if ( ! empty( $args['max_size'] ) ) {
472
473 $field_max_size = intval( floatval( $args['max_size'] ) * MB_IN_BYTES );
474
475 if ( $field_max_size > $max_size ) {
476 $field_max_size = $max_size;
477 }
478
479 }
480
481 return $field_max_size;
482
483 }
484
485
486 /**
487 * Returns upload subdirectory
488 *
489 * @return [type] [description]
490 */
491 public function get_upload_dir() {
492 return $this->upload_base() . '/' . get_current_user_id();
493 }
494
495 /**
496 * Returns upload base directory
497 *
498 * @return [type] [description]
499 */
500 public function upload_base() {
501 return apply_filters( 'jet-form-builder/file-upload/dir', 'jet-form-builder' );
502 }
503
504 /**
505 * Change upload directory for JetEngine uploads
506 *
507 * @param [type] $pathdata [description]
508 *
509 * @return [type] [description]
510 */
511 public function apply_upload_dir( $pathdata ) {
512
513 $dir = $this->get_upload_dir();
514
515 if ( empty( $pathdata['subdir'] ) ) {
516 $pathdata['path'] = $pathdata['path'] . '/' . $dir;
517 $pathdata['url'] = $pathdata['url'] . '/' . $dir;
518 $pathdata['subdir'] = '/' . $dir;
519 } else {
520 $new_subdir = '/' . $dir . $pathdata['subdir'];
521 $pathdata['path'] = str_replace( $pathdata['subdir'], $new_subdir, $pathdata['path'] );
522 $pathdata['url'] = str_replace( $pathdata['subdir'], $new_subdir, $pathdata['url'] );
523 $pathdata['subdir'] = $new_subdir;
524 }
525
526 return $pathdata;
527
528 }
529
530 /**
531 * Register form-specific assets
532 *
533 * @return void
534 */
535 public function register_assets() {
536
537 wp_enqueue_script(
538 'jet-form-builder-sortable',
539 Plugin::instance()->plugin_url( 'assets/lib/jquery-sortable/sortable.js' ),
540 array(),
541 Plugin::instance()->get_version(),
542 true
543 );
544
545 wp_enqueue_script(
546 'jet-form-builder-file-upload',
547 Plugin::instance()->plugin_url( 'assets/js/file-upload.js' ),
548 array( 'jet-form-builder-frontend-forms', 'jet-form-builder-sortable' ),
549 Plugin::instance()->get_version(),
550 true
551 );
552
553 }
554
555 /**
556 * Enqueue upload file JS
557 * @return void
558 */
559 public function enqueue_upload_script() {
560
561 wp_localize_script( 'jet-form-builder-file-upload', 'JetFormBuilderFileUploadConfig', array(
562 'ajaxurl' => esc_url( admin_url( 'admin-ajax.php' ) ),
563 'action' => $this->action,
564 'nonce' => wp_create_nonce( $this->nonce_key ),
565 'max_upload_size' => wp_max_upload_size(),
566 ) );
567
568 }
569
570 public function ensure_media_js( $content, $popup_data = array() ) {
571 ob_start();
572 jet_engine()->frontend->frontend_scripts();
573 $this->register_assets();
574 $this->enqueue_upload_script();
575 wp_scripts()->done[] = 'jet-form-builder-frontend-forms';
576 wp_scripts()->print_scripts( 'jet-form-builder-file-upload' );
577
578 return $content . ob_get_clean();
579 }
580
581 /**
582 * Returns the instance.
583 *
584 * @return object
585 * @since 1.0.0
586 * @access public
587 */
588 public static function instance() {
589 // If the single instance hasn't been set, set it now.
590 if ( null == self::$instance ) {
591 self::$instance = new self;
592 }
593
594 return self::$instance;
595 }
596
597 }