PluginProbe
WPBot – ChatBot Conversational Forms / 1.4.7
WPBot – ChatBot Conversational Forms v1.4.7
1.5.0 1.4.8 1.4.7 trunk 0.9.2 0.9.3 0.9.5 0.9.6 0.9.7 0.9.8 0.9.9 1.0.0 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.6 1.1.7 1.1.8 1.2.0 1.3.0 1.3.1 1.3.2 1.3.3 All 36 releases
conversational-forms / classes / files.php

files.php in WPBot – ChatBot Conversational Forms 1.4.7, at classes/files.php

430 lines 11.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Handles file uploading from file fields
5 *
6 * @package Caldera_Forms Modified by QuantumCloud
7 * @author Josh Pollock <Josh@CalderaWP.com>
8 * @license GPL-2.0+
9 * @link
10 * @copyright 2015 CalderaWP LLC
11 */
12 class Qcformbuilder_Forms_Files{
13
14 const CRON_ACTION = 'qcformbuilder_forms_delete_files';
15
16 /**
17 * Holds upload dir path for non-media library uploads
18 *
19 * @since 1.4.4
20 *
21 * @var string
22 */
23 protected static $dir;
24
25 /**
26 * Upload a file to WordPress
27 *
28 * @since 1.4.4
29 *
30 * @param array $file File
31 * @param array $args Optional. Used to place in private dir
32 *
33 * @return array
34 */
35 public static function upload( $file, array $args = array() ){
36 $args = wp_parse_args($args, array(
37 'private' => false,
38 'field_id' => null,
39 'form_id' => null,
40 'transient_id' => null,
41 ));
42 if( true == $args[ 'private' ] && ! empty( $args[ 'field_id' ] ) && ! empty( $args[ 'form_id' ] )){
43 $private = true;
44 }else{
45 $private = false;
46 }
47
48
49 self::add_upload_filter( $args[ 'field_id' ], $args[ 'form_id' ], $private, $args[ 'transient_id' ] );
50
51 $upload = wp_handle_upload($file, array( 'test_form' => false, 'foo' => 'bnar' ) );
52
53 if( $private ){
54 self::remove_upload_filter();
55 }
56
57 self::schedule_delete($args, $private, $upload);
58
59 return $upload;
60
61 }
62
63 /**
64 * Add uploaded file to media library
65 *
66 * @since 1.4.4
67 *
68 * @param array $upload Uploaded file data
69 * @param array $field Optional. Field config for file field doing upload. @since 1.5.1
70 *
71 * @return int|string|bool The ID of attachment or false if error @since 1.5.0.8
72 */
73 public static function add_to_media_library( $upload, $field ){
74 if( isset( $upload[ 'error' ] ) ){
75 return false;
76 }
77
78 require_once( ABSPATH . 'wp-admin/includes/media.php' );
79 require_once( ABSPATH . 'wp-admin/includes/image.php' );
80
81 $media_item = array(
82 'guid' => $upload['file'],
83 'post_mime_type' => $upload['type'],
84 'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $upload['file'] ) ),
85 'post_content' => '',
86 'post_status' => 'inherit'
87 );
88
89 $media_id = wp_insert_attachment( $media_item, $upload['file'] );
90
91 $media_data = wp_generate_attachment_metadata( $media_id, $upload['file'] );
92 wp_update_attachment_metadata( $media_id, $media_data );
93
94 /**
95 * Runs after file is uploaded to media library by Qcformbuilder Forms
96 *
97 * @since 1.5.1
98 *
99 * @param int|bool Attachment ID or false if upload failed
100 * @param array $field Field config
101 */
102 do_action( 'qcformbuilder_forms_file_added_to_media_library', $media_id, $field );
103 return $media_id;
104 }
105
106 /**
107 * Setup upload directory filter
108 *
109 * @since 1.4.4
110 *
111 * @param string $field_id The field ID for file field
112 * @param string $form_id The form ID
113 * @param bool $private If is private
114 * @param null|string $transient_id ID of transient for file. Optional.
115 */
116 public static function add_upload_filter( $field_id , $form_id, $private = true, $transient_id = null ){
117 if ( $private ) {
118 self::$dir = apply_filters( 'qcformbuilder_forms_private_upload_directory', self::secret_dir( $field_id, $form_id, $transient_id), $field_id, $form_id, $transient_id );
119 }else{
120 /**
121 * Filter directory for uploaded files
122 *
123 * If null, the file path will be WordPress' default
124 *
125 * @since 1.4.5
126 *
127 * @param string|null Directory
128 * @param string $field_id Field ID
129 * @param string $form_id Form ID
130 */
131 $dir = apply_filters( 'qcformbuilder_forms_upload_directory', null, $field_id, $form_id );
132 if( null != $dir ){
133 self::$dir = $dir;
134 }
135 }
136 add_filter( 'upload_dir', array( __CLASS__, 'uploads_filter' ) );
137 }
138
139 /**
140 * Remove the filter for upload directory path
141 *
142 * @since 1.4.4
143 */
144 public static function remove_upload_filter(){
145 remove_filter( 'upload_dir', array( __CLASS__, 'uploads_filter' ) );
146 }
147
148 /**
149 * Filter upload directory
150 *
151 * @uses "upload_dir" filter
152 *
153 * @since 1.4.4
154 *
155 * @param array $args
156 * @return array
157 */
158 public static function uploads_filter( $args ){
159
160 if ( self::$dir ) {
161 $newdir = '/' . self::$dir;
162
163 $args[ 'path' ] = str_replace( $args[ 'subdir' ], '', $args[ 'path' ] );
164 $args[ 'url' ] = str_replace( $args[ 'subdir' ], '', $args[ 'url' ] );
165 $args[ 'subdir' ] = $newdir;
166 $args[ 'path' ] .= $newdir;
167 $args[ 'url' ] .= $newdir;
168 if( ! file_exists( $args[ 'path' ] ) ){
169 $created = wp_mkdir_p( $args[ 'path' ] );
170 }
171 }
172
173 return $args;
174 }
175
176 /**
177 * Get a secret file fir by field ID and form ID
178 *
179 * @since 1.4.4
180 *
181 * @param string $field_id The field ID for file field
182 * @param string $form_id The form ID
183 * @param null|string $transient_id ID of transient for file. Optional.
184 *
185 * @return string
186 */
187 protected static function secret_dir( $field_id, $form_id, $transient_id = null ){
188 return md5( $field_id . $form_id . NONCE_SALT . (string) $transient_id );
189
190 }
191
192 /**
193 * Delete all files from the secret dir for a field
194 *
195 * @since 1.4.4
196 *
197 * @param string $field_id The field ID for file field
198 * @param string $form_id The form ID
199 */
200 protected static function delete_uploaded_files( $field_id, $form_id ){
201 $uploads = wp_get_upload_dir();
202 $dir = $uploads[ 'basedir' ] . '/' . self::secret_dir($field_id, $form_id);
203 if (is_dir($dir)) {
204 array_map('unlink', glob($dir . '/*'));
205 rmdir($dir);
206 }
207
208 }
209
210 /**
211 * After form submit, clear out files from secret dirs
212 *
213 * @since 1.4.4
214 *
215 * @param array $form Form config
216 * @param bool $second_run Optional. If using at mail hooks, set true to prevent recurrsion
217 */
218 public static function cleanup( $form, $second_run = false ){
219 if( false === $second_run && Qcformbuilder_Forms::should_send_mail( $form ) ) {
220 add_action( 'qcformbuilder_forms_mailer_complete', array( __CLASS__, 'delete_after_mail' ), 10, 3 );
221 add_action( 'qcformbuilder_forms_mailer_failed', array( __CLASS__, 'delete_after_mail' ), 10, 3 );
222 return;
223 }
224
225 $form_id = $form[ 'ID' ];
226 $fields = Qcformbuilder_Forms_Forms::get_fields( $form, false );
227 foreach( $fields as $id => $field ){
228 if( Qcformbuilder_Forms_Field_Util::is_file_field( $field, $form ) ){
229 self::delete_uploaded_files( $field[ 'ID' ], $form_id );
230 }
231
232 }
233
234 }
235
236 /**
237 * Do cleanup after sending email
238 *
239 * We use "qcformbuilder_forms_submit_complete" to start the clean up, but that is too soon, if using mailer.
240 *
241 * @since 1.4.4
242 *
243 * @param $mail
244 * @param $data
245 * @param $form
246 */
247 public static function delete_after_mail( $mail, $data, $form ){
248 self::cleanup( $form, true );
249 }
250
251 /**
252 * Trigger file delete via CRON
253 *
254 * This is needed because if a form never completed submission, files are not deleted at qcformbuilder_forms_submit_complete
255 *
256 * @since 1.4.4
257 *
258 * @param array $args
259 */
260 public static function cleanup_via_cron( $args ){
261 if( isset( $args[0], $args[1] ) ){
262 self::delete_uploaded_files( $args[0], $args[1] );
263 }
264
265 }
266
267 /**
268 * Check if file field's uploads are private or not
269 *
270 * @since 1.4.4
271 *
272 * @param array $field Field config
273 *
274 * @return bool
275 */
276 public static function is_private( array $field ){
277
278 return Qcformbuilder_Forms_Field_Util::is_file_field( $field ) && ! self::should_add_to_media_library($field);
279 }
280
281
282 /**
283 * Check if a file field is "persistent"
284 *
285 * If true, file should be retained on server.
286 *
287 * @since 1.8.0
288 *
289 * @param array $field Field config
290 *
291 * @return bool
292 */
293 public static function is_persistent(array $field ){
294 return self::should_add_to_media_library($field) || ! empty( $field['config']['persistent']);
295 }
296
297 /**
298 * Get max size for file field
299 *
300 * @since 1.8.0
301 *
302 * @param array $field Field config
303 *
304 * @return int
305 */
306 public static function get_max_upload_size( array $field)
307 {
308 return ! empty( $field[ 'config']['max_upload'] ) ? absint( $field[ 'config']['max_upload']) : 0;
309 }
310
311 /**
312 * Check if a file is too large to upload
313 *
314 * @since 1.8.0
315 *
316 * Returns false if no max upload size set.
317 * Returns true if max upload size option is set and file is larger than limit
318 *
319 * @param array $field Field config
320 * @param string $file File to check size against
321 *
322 * @return bool
323 */
324 public static function is_file_too_large( array $field, $file )
325 {
326
327 return 0 !== self::get_max_upload_size($field) && self::get_max_upload_size($field) < $file['size'];
328
329 }
330 /**
331 * Check if a file field should upload to media library.
332 **
333 *
334 * @since 1.8.0
335 *
336 * @param array $field Field config
337 *
338 * @return bool
339 */
340 public static function should_add_to_media_library(array $field ){
341 return isset( $field[ 'config']['media_lib'] ) && true == $field['config']['media_lib'];
342 }
343
344 /**
345 * Get the callback function for file uploads
346 *
347 * @since 1.4.4
348 *
349 * @param array $form Form config
350 * @param array $field Field config
351 *
352 * @return array|string|callable
353 */
354 public static function get_upload_handler( $form, $field ){
355
356 /**
357 * Filter the callback function for file uploads
358 *
359 * @since 1.4.4
360 *
361 * @param array|string|callable Callable
362 * @param array $form Form config
363 * @param array $field Field config
364 */
365 return apply_filters( 'qcformbuilder_forms_file_upload_handler', array( 'Qcformbuilder_Forms_Files', 'upload' ), $form, $field );
366 }
367
368 /**
369 * Check if field's files should be attached
370 *
371 * @since 1.5.0
372 *
373 * @param array $field
374 * @param array $form Form config
375 * @return bool
376 */
377 public static function should_attach( array $field, array $form ){
378
379 if( Qcformbuilder_Forms_Field_Util::is_file_field( $field, $form ) ){
380 return ! empty( $field[ 'config' ][ 'attach'] );
381 }
382
383 return false;
384
385 }
386
387 /**
388 * Get types of file fields
389 *
390 * @since 1.5.0
391 *
392 * @return array
393 */
394 public static function types(){
395 return array(
396 'advanced_file',
397 'file',
398 \qcformbuilderwp\qcformbuilderforms\cf2\Fields\FieldTypes\FileFieldType::getCf1Identifier(),
399 \qcformbuilderwp\qcformbuilderforms\cf2\Fields\FieldTypes\FileFieldType::getType()
400 );
401 }
402
403 /**
404 * Schedule file to be deleted as soon as possible
405 *
406 * @since 1.8.0
407 *
408 * @param string $field_id ID of field
409 * @param string $form_id ID of form
410 * @param string $file Path to file to delete.
411 *
412 * @return bool
413 */
414 public static function schedule_delete($field_id, $form_id, $file )
415 {
416 $form = Qcformbuilder_Forms_Forms::get_form($form_id);
417 if ( is_array($form) ) {
418 $field = Qcformbuilder_Forms_Field_Util::get_field($field_id, $form);
419 if ( is_array($field) && !self::is_persistent($field) ) {
420 qcformbuilder_forms_schedule_job(new \qcformbuilderwp\qcformbuilderforms\cf2\Jobs\DeleteFileJob($file));
421 return true;
422 }
423 }
424
425 return false;
426
427 }
428
429 }
430