Passed
Push — main ( f54dcc...7cc7c7 )
by Pranjal
02:59 queued 25s
created

StorageEngine::writeRequest()   B

Complexity

Conditions 9
Paths 16

Size

Total Lines 27
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 19
dl 0
loc 27
rs 8.0555
c 1
b 0
f 0
cc 9
nc 16
nop 3
1
<?php
2
/*
3
 * This file is part of the Scrawler package.
4
 *
5
 * (c) Pranjal Pandey <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Scrawler;
12
13
use Scrawler\Http\Request;
14
use Scrawler\Interfaces\StorageInterface;
15
use Scrawler\Validator\Storage\AbstractValidator as Validator;
16
use Scrawler\Validator\Storage\Blacklist;
17
use Symfony\Component\HttpFoundation\File\File;
18
use Symfony\Component\HttpFoundation\File\UploadedFile;
19
20
/**
21
 * Scrawler filesystem storage engine.
22
 */
23
class StorageEngine extends \League\Flysystem\Filesystem
24
{
25
    /**
26
     * @param array<mixed> $config
27
     */
28
    public function __construct(protected StorageInterface $adapter, array $config = [])
29
    {
30
        parent::__construct($this->adapter, $config);
31
    }
32
33
    /**
34
     * Get the Adapter.
35
     */
36
    public function getAdapter(): StorageInterface
37
    {
38
        return $this->adapter;
39
    }
40
41
    /**
42
     * Stores the files in request to  specific path.
43
     *
44
     * @param array<string,Validator>|Validator|null $validators
45
     *
46
     * @return array<array<int<0, max>, string>|string>
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<array<int<0, max>, string>|string> at position 4 could not be parsed: Expected '>' at position 4, but found 'int'.
Loading history...
47
     */
48
    public function writeRequest(Request $request, ?string $path = '', array|Validator|null $validators = null): array
49
    {
50
        $uploaded = [];
51
        $files = $request->files->all();
52
        foreach ($files as $name => $file) {
53
            if (is_array($validators) && array_key_exists($name, $validators)) {
54
                $validator = $validators[$name];
55
            } elseif ($validators instanceof Validator) {
56
                $validator = $validators;
57
            } else {
58
                $validator = null;
59
            }
60
            if (\is_array($file)) {
61
                $paths = [];
62
                foreach ($file as $single) {
63
                    if ($single) {
64
                        $filepath = $this->writeFile($single, $path, $validator);
65
                        $paths[] = $filepath;
66
                    }
67
                }
68
                $uploaded[$name] = $paths;
69
            } elseif ($file) {
70
                $uploaded[$name] = $this->writeFile($file, $path, $validator);
71
            }
72
        }
73
74
        return $uploaded;
75
    }
76
77
    /**
78
     * Write the request's uploaded file to the storage.
79
     */
80
    public function writeFile(UploadedFile|File $file, ?string $path = '', ?Validator $validator = null, ?string $filename = null): string
81
    {
82
        if (!$validator instanceof Validator) {
83
            $validator = new Blacklist();
84
        }
85
86
        $validator->runValidate($file);
87
        $content = $validator->getProcessedContent($file);
88
89
        $originalname = explode('.', $file->getFilename());
90
        if (null == $filename) {
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $filename of type null|string against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
91
            $filename = $this->sanitizeFilename($originalname[0]).'.'.$file->guessExtension();
92
        } else {
93
            $filename = $this->sanitizeFilename($filename).'.'.$file->guessExtension();
94
        }
95
        $this->write($path.$filename, $content);
96
97
        return $path.$filename;
98
    }
99
100
    /**
101
     * Sanitize the filename.
102
     */
103
    private function sanitizeFilename(string $filename): string
104
    {
105
        $name = \Safe\preg_replace('/[^a-z0-9-_.]/', '', subject: strtolower($filename));
106
        $name = \Safe\preg_replace('/[\. _-]+/', '-', (string) $name);
107
        $name = trim((string) $name, '-');
108
        $name = substr($name, 0, 100);
109
110
        return $name.'_'.uniqid();
111
    }
112
113
    /**
114
     * Get file public Url if availabe else returns path.
115
     */
116
    public function getUrl(string $path): string
117
    {
118
        return $this->getAdapter()->getUrl($path);
119
    }
120
}
121