Diff: STRATO-apps/wordpress_03/app/wp-content/plugins/fluentformpro/src/Uploader.php
Keine Baseline-Datei – Diff nur gegen leer.
1
-
1
+
<?php
2
+
3
+
namespace FluentFormPro;
4
+
5
+
use FluentForm\App\Modules\Form\FormHandler;
6
+
use FluentForm\App\Modules\Form\FormFieldsParser;
7
+
use FluentForm\Framework\Helpers\ArrayHelper;
8
+
9
+
class Uploader extends FormHandler
10
+
{
11
+
/**
12
+
* Uploads files to the server.
13
+
*/
14
+
public function upload()
15
+
{
16
+
$formId = intval($this->request->get('formId'));
17
+
18
+
$attributes = $this->request->all();
19
+
20
+
$sanitizeMap = [
21
+
'formId' => 'intval',
22
+
];
23
+
$attributes = fluentform_backend_sanitizer($attributes, $sanitizeMap);
24
+
25
+
$this->formData = $attributes;
26
+
27
+
if ($formId) {
28
+
$this->setForm($formId);
29
+
30
+
$this->validateNonce();
31
+
32
+
if ($this->form) {
33
+
// Get the HTTP files. It'll be an array with always one item.
34
+
$files = $this->request->files();
35
+
36
+
do_action_deprecated(
37
+
'fluentform_starting_file_upload',
38
+
[
39
+
$files,
40
+
$this->form
41
+
],
42
+
FLUENTFORM_FRAMEWORK_UPGRADE,
43
+
'fluentform/starting_file_upload',
44
+
'Use fluentform/starting_file_upload instead of fluentform_starting_file_upload.'
45
+
);
46
+
47
+
do_action('fluentform/starting_file_upload', $files, $this->form);
48
+
49
+
// Get the form attribute name then.
50
+
$arrayKeys = array_keys($files);
51
+
$attribute = array_pop($arrayKeys);
52
+
53
+
// Get the specific form field by using the element type and it's attribute name.
54
+
$field = FormFieldsParser::getField(
55
+
$this->form,
56
+
['input_file', 'input_image', 'featured_image'],
57
+
$attribute,
58
+
['rules', 'settings']
59
+
);
60
+
61
+
if ($field) {
62
+
// Extract the validation rules & messages for file upload element.
63
+
list($rules, $messages) = FormFieldsParser::getValidations(
64
+
$this->form,
65
+
$files,
66
+
$field
67
+
);
68
+
/**
69
+
* Delegate 'max_file_size', 'allowed_file_types' rules & messages to
70
+
* 'max', 'mimes' since the validation library doesn't recognise those
71
+
*/
72
+
list($rules, $messages) = $this->delegateValidations($rules, $messages);
73
+
$delegateValidations = apply_filters_deprecated(
74
+
'fluentform_file_upload_validations',
75
+
[
76
+
[$rules, $messages],
77
+
$this->form
78
+
],
79
+
FLUENTFORM_FRAMEWORK_UPGRADE,
80
+
'fluentform/file_upload_validations',
81
+
'Use fluentform/file_upload_validations instead of fluentform_file_upload_validations.'
82
+
);
83
+
84
+
// Fire an event so that one can hook into it to work with the rules & messages.
85
+
$validations = $this->app->applyFilters(
86
+
'fluentform/file_upload_validations',
87
+
$delegateValidations,
88
+
$this->form
89
+
);
90
+
91
+
$validator = fluentValidator(
92
+
$files,
93
+
$validations[0],
94
+
$validations[1]
95
+
);
96
+
97
+
if ($validator->validate()->fails()) {
98
+
$errors = $validator->errors();
99
+
$errors = apply_filters_deprecated(
100
+
'fluentform_file_upload_validation_error',
101
+
[
102
+
$errors,
103
+
$this->form
104
+
],
105
+
FLUENTFORM_FRAMEWORK_UPGRADE,
106
+
'fluentform/file_upload_validation_error',
107
+
'Use fluentform/file_upload_validation_error instead of fluentform_file_upload_validation_error.'
108
+
);
109
+
// Fire an event so that one can hook into it to work with the errors.
110
+
$errors = $this->app->applyFilters(
111
+
'fluentform/file_upload_validation_error',
112
+
$errors,
113
+
$this->form
114
+
);
115
+
116
+
wp_send_json([
117
+
'errors' => $errors
118
+
], 422);
119
+
}
120
+
121
+
// let's upload to a temp location
122
+
$field = current($field);
123
+
124
+
//add default upload location for old inputs
125
+
if (!$uploadLocation = ArrayHelper::get($field, 'settings.upload_file_location')) {
126
+
$uploadLocation = 'default';
127
+
}
128
+
129
+
$uploadedFiles = [];
130
+
if (!empty($uploadLocation)) {
131
+
$this->overrideUploadDir();
132
+
$uploadedFiles = $this->uploadToTemp($files, $field);
133
+
}
134
+
135
+
wp_send_json_success([
136
+
'files' => $uploadedFiles
137
+
], 200);
138
+
}
139
+
}
140
+
}
141
+
}
142
+
143
+
/**
144
+
* Uploads files to its target locations
145
+
* @return void
146
+
*/
147
+
public function processFiles()
148
+
{
149
+
$fileTypes = ['input_file', 'input_image', 'featured_image'];
150
+
151
+
foreach ($fileTypes as $fileType) {
152
+
add_filter('fluentform/input_data_' . $fileType, function ($files, $field, $formData, $form) {
153
+
if (!$this->form) {
154
+
$this->setForm($form->id);
155
+
}
156
+
$uploadLocation = $this->getUploadLocation($field);
157
+
$files = is_array($files) ? $files : [$files];
158
+
159
+
$isSkip = apply_filters('fluentform/skip_cloud_file_decryption', false);
160
+
161
+
if (!$isSkip) {
162
+
$files = $this->maybeDecrypt($files);
163
+
}
164
+
165
+
do_action_deprecated(
166
+
'fluentform_starting_file_processing',
167
+
[
168
+
$files,
169
+
$uploadLocation,
170
+
$formData,
171
+
$form
172
+
],
173
+
FLUENTFORM_FRAMEWORK_UPGRADE,
174
+
'fluentform/starting_file_processing',
175
+
'Use fluentform/starting_file_processing instead of fluentform_starting_file_processing.'
176
+
);
177
+
do_action('fluentform/starting_file_processing', $files, $uploadLocation, $formData, $form);
178
+
$this->initUploads($files, $uploadLocation, $formData);
179
+
$formattedFiles = [];
180
+
foreach ($files as $file) {
181
+
$formattedFiles[] = $this->getProcessedUrl($file, $uploadLocation);
182
+
}
183
+
return $formattedFiles;
184
+
}, 10, 4);
185
+
}
186
+
}
187
+
188
+
/**
189
+
* Register filters for custom upload dir
190
+
*/
191
+
public function overrideUploadDir()
192
+
{
193
+
add_filter('wp_handle_upload_prefilter', function ($file) {
194
+
add_filter('upload_dir', [$this, 'setCustomUploadDir']);
195
+
196
+
add_filter('wp_handle_upload', function ($fileinfo) {
197
+
remove_filter('upload_dir', [$this, 'setCustomUploadDir']);
198
+
$fileinfo['file'] = basename($fileinfo['file']);
199
+
return $fileinfo;
200
+
});
201
+
202
+
return $this->renameFileName($file);
203
+
});
204
+
}
205
+
206
+
/**
207
+
* Set plugin's custom upload dir
208
+
* @param array $param
209
+
* @return array $param
210
+
*/
211
+
public function setCustomUploadDir($param)
212
+
{
213
+
$param['url'] = $param['baseurl'] . FLUENTFORM_UPLOAD_DIR . '/temp';
214
+
$param['path'] = $param['basedir'] . FLUENTFORM_UPLOAD_DIR . '/temp';
215
+
216
+
$param = apply_filters_deprecated(
217
+
'fluentform_file_upload_params',
218
+
[
219
+
$param,
220
+
$this->formData,
221
+
$this->form
222
+
],
223
+
FLUENTFORM_FRAMEWORK_UPGRADE,
224
+
'fluentform/file_upload_params',
225
+
'Use fluentform/file_upload_params instead of fluentform_file_upload_params.'
226
+
);
227
+
228
+
$param = apply_filters('fluentform/file_upload_params', $param, $this->formData, $this->form);
229
+
230
+
$this->secureDirectory($param['path']);
231
+
232
+
return $param;
233
+
}
234
+
235
+
/**
236
+
* Rename the uploaded file name before saving
237
+
* @param array $file
238
+
* @return array $file
239
+
*/
240
+
public function renameFileName($file)
241
+
{
242
+
$originalFileArray = $file;
243
+
$prefix = 'ff-' . md5(uniqid(rand())) . '-ff-';
244
+
245
+
$file['name'] = $prefix . $file['name'];
246
+
247
+
$file = apply_filters_deprecated(
248
+
'fluentform_uploaded_file_name',
249
+
[
250
+
$file,
251
+
$originalFileArray,
252
+
$this->formData,
253
+
$this->form
254
+
],
255
+
FLUENTFORM_FRAMEWORK_UPGRADE,
256
+
'fluentform/uploaded_file_name',
257
+
'Use fluentform/uploaded_file_name instead of fluentform_uploaded_file_name.'
258
+
);
259
+
260
+
return apply_filters('fluentform/uploaded_file_name', $file, $originalFileArray, $this->formData, $this->form);
261
+
}
262
+
263
+
/**
264
+
* Prepare the validation rules & messages specific to
265
+
* file type inputs when actual form is submitted.
266
+
*
267
+
* @param $validations
268
+
* @param $form \stdClass
269
+
* @return array
270
+
*/
271
+
public function prepareValidations($validations, $form)
272
+
{
273
+
$element = FormFieldsParser::getElement($form, ['input_file', 'input_image']);
274
+
275
+
if (count($element)) {
276
+
// Delegate the `max_file_count` validation to `max`
277
+
$validations = $this->delegateValidations(
278
+
$validations[0],
279
+
$validations[1],
280
+
['max_file_count'],
281
+
['max']
282
+
);
283
+
}
284
+
285
+
return $validations;
286
+
}
287
+
288
+
/**
289
+
* Process uploads from temp directory location to its final location
290
+
*
291
+
* @param $formData
292
+
* @param $form
293
+
* @return void
294
+
*/
295
+
public function initUploads($files, $uploadLocation, $formData)
296
+
{
297
+
if (empty($files)) {
298
+
return;
299
+
}
300
+
if ($uploadLocation == 'wp_media') {
301
+
$this->copyToWpMedia($files);
302
+
} elseif ($uploadLocation == 'default') {
303
+
$this->copyToDefault($files);
304
+
} elseif ($uploadLocation == 'cloud_storage') {
305
+
//for file upload addons
306
+
do_action('fluentform/upload_to_cloud', $files, $uploadLocation, $formData, $this->form);
307
+
}
308
+
}
309
+
310
+
/**
311
+
* Copy files to default location
312
+
*
313
+
* @param array $files
314
+
*/
315
+
protected function copyToDefault($files)
316
+
{
317
+
$uploadedFiles = [];
318
+
$wpUploadDir = wp_upload_dir();
319
+
320
+
foreach ($files as $file) {
321
+
$fileInfo = pathinfo($file);
322
+
$filename = $fileInfo['basename'];
323
+
324
+
$filePath = $wpUploadDir['basedir'] . FLUENTFORM_UPLOAD_DIR;
325
+
$tempFilePath = $filePath . '/temp/' . $filename;
326
+
$filePath = apply_filters_deprecated(
327
+
'fluentform_default_upload_path',
328
+
[
329
+
$filePath,
330
+
$this->form
331
+
],
332
+
FLUENTFORM_FRAMEWORK_UPGRADE,
333
+
'fluentform/default_upload_path',
334
+
'Use fluentform/default_upload_path instead of fluentform_default_upload_path.'
335
+
);
336
+
$destinationFilePath = apply_filters('fluentform/default_upload_path', $filePath, $this->form);
337
+
$this->secureDirectory($filePath);
338
+
339
+
$destinationFilePath = trailingslashit($destinationFilePath) . $filename;
340
+
341
+
self::copyFile($tempFilePath, $destinationFilePath);
342
+
}
343
+
return $uploadedFiles;
344
+
}
345
+
346
+
347
+
/**
348
+
* Copy files to WordPress Media
349
+
*
350
+
* @param $files
351
+
* @return void
352
+
*/
353
+
public function copyToWpMedia($files)
354
+
{
355
+
$uploadedFiles = [];
356
+
$wpUploadDir = wp_upload_dir();
357
+
358
+
foreach ($files as $file) {
359
+
$fileInfo = pathinfo($file);
360
+
$filename = $fileInfo['basename'];
361
+
$tempFilePath = $wpUploadDir['basedir'] . FLUENTFORM_UPLOAD_DIR . '/temp/' . $filename;
362
+
$destinationFilePath = $wpUploadDir['path'] . '/' . $filename;
363
+
364
+
$mimeType = wp_check_filetype($tempFilePath);
365
+
//Copy this file into the wp uploads dir
366
+
$move = self::copyFile($tempFilePath, $destinationFilePath);
367
+
if (!$move) {
368
+
continue;
369
+
}
370
+
$destinationFileFileUrl = $wpUploadDir['url'] . '/' . $filename;
371
+
$uploadId = wp_insert_attachment(
372
+
[
373
+
'guid' => $destinationFileFileUrl,
374
+
'post_mime_type' => $mimeType['type'],
375
+
'post_title' => preg_replace('/\.[^.]+$/', '', $filename),
376
+
'post_content' => '',
377
+
'post_status' => 'inherit',
378
+
],
379
+
$destinationFilePath
380
+
);
381
+
382
+
// wp_generate_attachment_metadata() needs this file.
383
+
require_once ABSPATH . 'wp-admin/includes/image.php';
384
+
if (!is_wp_error($uploadId)) {
385
+
wp_update_attachment_metadata(
386
+
$uploadId,
387
+
wp_generate_attachment_metadata($uploadId, $destinationFilePath)
388
+
);
389
+
}
390
+
}
391
+
}
392
+
393
+
/**
394
+
* Upload files to temp directory
395
+
*
396
+
* @param array $files
397
+
* @param array $field
398
+
* @return array
399
+
*/
400
+
private function uploadToTemp($files, $field)
401
+
{
402
+
$uploadedFiles = [];
403
+
foreach ($files as $file) {
404
+
/**
405
+
* @var $file \FluentForm\Framework\Request\File
406
+
*/
407
+
$filesArray = $file->toArray();
408
+
409
+
$args = [
410
+
'test_form' => false
411
+
];
412
+
$args = apply_filters_deprecated(
413
+
'fluentform_uploader_args',
414
+
[
415
+
$args,
416
+
$filesArray,
417
+
$this->form
418
+
],
419
+
FLUENTFORM_FRAMEWORK_UPGRADE,
420
+
'fluentform/uploader_args',
421
+
'Use fluentform/uploader_args instead of fluentform_uploader_args.'
422
+
);
423
+
424
+
$uploaderArgs = apply_filters('fluentform/uploader_args', $args, $filesArray, $this->form);
425
+
426
+
$uploadFile = wp_handle_upload(
427
+
$filesArray,
428
+
$uploaderArgs
429
+
);
430
+
431
+
if ($error = ArrayHelper::get($uploadFile, 'error')) {
432
+
wp_send_json([
433
+
'errors' => [
434
+
'error' => $error
435
+
]
436
+
], 422);
437
+
}
438
+
439
+
$file = ArrayHelper::get($uploadFile, 'file');
440
+
441
+
if ($file) {
442
+
$uploadFile['file'] = \FluentForm\App\Helpers\Protector::encrypt($file);
443
+
$uploadFile['url'] = str_replace($file, $uploadFile['file'], $uploadFile['url']);
444
+
445
+
$uploadFile = apply_filters_deprecated(
446
+
'fluent_file_uploaded',
447
+
[
448
+
$uploadFile,
449
+
$this->formData,
450
+
$this->form
451
+
],
452
+
FLUENTFORM_FRAMEWORK_UPGRADE,
453
+
'fluentform/file_uploaded',
454
+
'Use fluentform/file_uploaded instead of fluent_file_uploaded.'
455
+
);
456
+
457
+
$uploadedFiles[] = apply_filters('fluentform/file_uploaded', $uploadFile, $this->formData, $this->form);
458
+
}
459
+
}
460
+
return $uploadedFiles;
461
+
}
462
+
463
+
private static function copyFile($fromPath = null, $toPath = null)
464
+
{
465
+
$status = false;
466
+
467
+
if (!empty($fromPath) && is_file($fromPath)) {
468
+
//if destination dir exists if not make it
469
+
if (!file_exists(dirname($toPath))) {
470
+
mkdir(dirname($toPath));
471
+
}
472
+
if (file_exists(dirname($toPath))) {
473
+
//Move file into dir
474
+
if (copy($fromPath, $toPath)) {
475
+
if (file_exists($toPath)) {
476
+
$status = true;
477
+
}
478
+
}
479
+
}
480
+
}
481
+
482
+
return $status;
483
+
}
484
+
485
+
486
+
/**
487
+
* Get File url after processing uploads
488
+
*
489
+
* @param $file
490
+
* @param $uploadLocations
491
+
* @return string|void
492
+
*/
493
+
public function getProcessedUrl($file, $location)
494
+
{
495
+
$wpUploadDir = wp_upload_dir();
496
+
$fileInfo = pathinfo($file);
497
+
$filename = $fileInfo['basename'];
498
+
$filePath = $wpUploadDir['baseurl'] . FLUENTFORM_UPLOAD_DIR;
499
+
if ($location == 'wp_media') {
500
+
$fileUrl = $wpUploadDir['url'] . '/' . $filename;
501
+
} elseif ($location == 'default') {
502
+
$filePath = apply_filters_deprecated(
503
+
'fluentform_default_file_upload_url',
504
+
[
505
+
$filePath,
506
+
$this->form
507
+
],
508
+
FLUENTFORM_FRAMEWORK_UPGRADE,
509
+
'fluentform/default_file_upload_url',
510
+
'Use fluentform/default_file_upload_url instead of fluentform_default_file_upload_url.'
511
+
);
512
+
$fileUrl = apply_filters('fluentform/default_file_upload_url', $filePath, $this->form);
513
+
$fileUrl = trailingslashit($fileUrl) .$filename;
514
+
} else if ($location == 'cloud_storage') {
515
+
return $file;
516
+
} else {
517
+
//if not location found store temp file url for other file uploader
518
+
$fileUrl = $filePath . '/temp/' . $filename;
519
+
}
520
+
return $fileUrl;
521
+
}
522
+
523
+
/**
524
+
* Cleanup temp Directory
525
+
*
526
+
* @return void
527
+
*/
528
+
public static function removeOldTempFiles()
529
+
{
530
+
$maxFileAge = apply_filters('fluentform/temp_file_delete_time', 2 * 3600);
531
+
$wpUploadDir = wp_upload_dir();
532
+
$tempDir = $wpUploadDir['basedir'] . FLUENTFORM_UPLOAD_DIR . '/temp/';
533
+
534
+
// Remove old temp files
535
+
if (is_dir($tempDir) && ($dir = opendir($tempDir))) {
536
+
$deletedCount = 0;
537
+
$maxDeletions = apply_filters('fluentform/temp_file_cleanup_batch_size', 50);
538
+
539
+
while (($file = readdir($dir)) !== false) {
540
+
if ($file === '.' || $file === '..') {
541
+
continue;
542
+
}
543
+
544
+
$tempFilePath = $tempDir . $file;
545
+
if (is_file($tempFilePath) && (filemtime($tempFilePath) < time() - $maxFileAge)) {
546
+
if (@unlink($tempFilePath)) {
547
+
$deletedCount++;
548
+
}
549
+
550
+
// Limit batch size to prevent timeouts
551
+
if ($deletedCount >= $maxDeletions) {
552
+
break;
553
+
}
554
+
}
555
+
}
556
+
closedir($dir);
557
+
558
+
do_action('fluentform/temp_files_cleaned', $tempDir, $deletedCount, $maxFileAge, $maxDeletions);
559
+
}
560
+
}
561
+
562
+
/**
563
+
* Adds htaccess file to directory
564
+
* @param $path
565
+
* @return void
566
+
*/
567
+
private function secureDirectory($path)
568
+
{
569
+
if (!is_dir($path)) {
570
+
mkdir($path, 0755);
571
+
file_put_contents(
572
+
$path . '/.htaccess',
573
+
file_get_contents(__DIR__ . '/Stubs/htaccess.stub')
574
+
);
575
+
576
+
file_put_contents(
577
+
$path . '/index.php',
578
+
file_get_contents(__DIR__ . '/Stubs/index.stub')
579
+
);
580
+
}
581
+
582
+
/*
583
+
* @todo: Rempve this block after November 2023
584
+
*/
585
+
586
+
if(!file_exists($path . '/index.php')) {
587
+
file_put_contents(
588
+
$path . '/index.php',
589
+
file_get_contents(__DIR__ . '/Stubs/index.stub')
590
+
);
591
+
}
592
+
}
593
+
594
+
595
+
/**
596
+
* Maybe Decrypt file names
597
+
*
598
+
* @param $files
599
+
* @return array
600
+
*/
601
+
private function maybeDecrypt($files)
602
+
{
603
+
$decrypted = [];
604
+
foreach ($files as $file) {
605
+
$decrypted[] = \FluentForm\App\Helpers\Helper::maybeDecryptUrl($file);
606
+
}
607
+
return $decrypted;
608
+
}
609
+
610
+
public function deleteFile()
611
+
{
612
+
if (!empty($file_name = $this->request->get('path'))) {
613
+
if (!empty($this->request->get('attachment_id')) && wp_delete_attachment(
614
+
$this->request->get('attachment_id')
615
+
)) {
616
+
wp_die();
617
+
} else {
618
+
$file_name = \FluentForm\App\Helpers\Protector::decrypt($file_name);
619
+
wp_die(@unlink(wp_upload_dir()['basedir'] . FLUENTFORM_UPLOAD_DIR . '/temp/' . $file_name));
620
+
}
621
+
}
622
+
}
623
+
624
+
/**
625
+
* @param $upload_file_location
626
+
* @return mixed
627
+
*/
628
+
public function getUploadLocation($field)
629
+
{
630
+
if (!$locationType = ArrayHelper::get($field, 'raw.settings.file_location_type')) {
631
+
$locationType = 'follow_global_settings';
632
+
}
633
+
if ($locationType == 'follow_global_settings') {
634
+
$settings = get_option('_fluentform_global_form_settings', false);
635
+
$location = ArrayHelper::get($settings, 'misc.file_upload_locations');
636
+
} else {
637
+
$location = ArrayHelper::get($field, 'raw.settings.upload_file_location');
638
+
}
639
+
640
+
if (empty($location)) {
641
+
$location = 'default';
642
+
}
643
+
644
+
$location = apply_filters('fluentform/change_file_upload_location', $location);
645
+
return $location;
646
+
}
647
+
}
648
+