Passed
Push — main ( 501f40...d2df27 )
by Pranjal
13:08 queued 13s
created

StorageEngine   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 98
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 16
eloc 41
c 3
b 0
f 0
dl 0
loc 98
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A write() 0 7 2
B writeRequest() 0 27 9
A writeFile() 0 19 3
A sanitizeFilename() 0 8 1
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 League\Flysystem\FilesystemAdapter;
14
use Scrawler\Http\Request;
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 FilesystemAdapter $adapter, array $config = [])
29
    {
30
        parent::__construct($this->adapter, $config);
31
    }
32
33
    /**
34
     * Stores the files in request to  specific path.
35
     *
36
     * @param array<string,Validator>|Validator|null $validators
37
     * @param array<string,mixed>                    $options
38
     *
39
     * @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...
40
     */
41
    public function writeRequest(Request $request, string $path = '', array|Validator|null $validators = null, array $options = []): array
42
    {
43
        $uploaded = [];
44
        $files = $request->files->all();
45
        foreach ($files as $name => $file) {
46
            if (is_array($validators) && array_key_exists($name, $validators)) {
47
                $validator = $validators[$name];
48
            } elseif ($validators instanceof Validator) {
49
                $validator = $validators;
50
            } else {
51
                $validator = null;
52
            }
53
            if (\is_array($file)) {
54
                $paths = [];
55
                foreach ($file as $single) {
56
                    if ($single) {
57
                        $filepath = $this->writeFile($single, $path, $validator, $options);
58
                        $paths[] = $filepath;
59
                    }
60
                }
61
                $uploaded[$name] = $paths;
62
            } elseif ($file) {
63
                $uploaded[$name] = $this->writeFile($file, $path, $validator, $options);
64
            }
65
        }
66
67
        return $uploaded;
68
    }
69
70
    /**
71
     * Write the request's uploaded file to the storage.
72
     *
73
     * @param array<string,mixed> $options
74
     */
75
    public function writeFile(UploadedFile|File $file, string $path = '', ?Validator $validator = null, array $options = []): string
76
    {
77
        if (!$validator instanceof Validator) {
78
            $validator = new Blacklist();
79
        }
80
81
        $validator->runValidate($file);
82
        $content = $validator->getProcessedContent($file);
83
84
        $originalname = explode('.', $file->getFilename());
85
        if (array_key_exists('filename', $options)) {
86
            $filename = $this->sanitizeFilename($options['filename']).'.'.$file->guessExtension();
87
        } else {
88
            $filename = $this->sanitizeFilename($originalname[0]).'.'.$file->guessExtension();
89
        }
90
        $visibility = $options['visibility'] ?? 'public';
91
        $this->write($path.'/'.$visibility.'/'.$filename, $content, ['visibility' => $visibility]);
92
93
        return $path.'/'.$visibility.'/'.$filename;
94
    }
95
96
    /**
97
     * Write the content to the storage.
98
     *
99
     * @param array<string,mixed> $config
100
     */
101
    public function write(string $path, string $content, array $config = []): void
102
    {
103
        if (!array_key_exists('visibility', $config)) {
104
            $config['visibility'] = 'public';
105
        }
106
107
        parent::write($config['visibility'].'/'.$path, $content, $config);
108
    }
109
110
    /**
111
     * Sanitize the filename.
112
     */
113
    private function sanitizeFilename(string $filename): string
114
    {
115
        $name = \Safe\preg_replace('/[^a-z0-9-_.]/', '', subject: strtolower($filename));
116
        $name = \Safe\preg_replace('/[\. _-]+/', '-', (string) $name);
117
        $name = trim((string) $name, '-');
118
        $name = substr($name, 0, 100);
119
120
        return $name.'_'.uniqid();
121
    }
122
}
123