Passed
Push — fix/media-validation ( 732083...34b116 )
by Ben
06:22
created

AbstractMediaFieldHandler::getFileIdsFromInput()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 7
c 0
b 0
f 0
dl 0
loc 12
rs 10
cc 4
nc 8
nop 2
1
<?php declare(strict_types=1);
2
3
namespace Thinktomorrow\Chief\Media\Application;
4
5
use Illuminate\Support\Str;
6
use Illuminate\Http\Request;
7
use Thinktomorrow\AssetLibrary\Asset;
8
use Thinktomorrow\AssetLibrary\HasAsset;
9
use Thinktomorrow\Chief\Fields\Types\MediaField;
10
use Thinktomorrow\AssetLibrary\Application\AddAsset;
11
use Thinktomorrow\Chief\Media\DuplicateAssetException;
12
use Thinktomorrow\AssetLibrary\Application\DetachAsset;
13
use Thinktomorrow\AssetLibrary\Application\ReplaceAsset;
14
use Thinktomorrow\AssetLibrary\Application\AssetUploader;
15
use Thinktomorrow\AssetLibrary\Application\SortAssets;
16
17
abstract class AbstractMediaFieldHandler
18
{
19
    /** @var ReplaceAsset */
20
    protected $replaceAsset;
21
22
    /** @var AddAsset */
23
    protected $addAsset;
24
25
    /** @var DetachAsset */
26
    protected $detachAsset;
27
28
    /** @var AssetUploader */
29
    protected $assetUploader;
30
31
    /** @var SortAssets */
32
    protected $sortAssets;
33
34
    final public function __construct(AddAsset $addAsset, ReplaceAsset $replaceAsset, DetachAsset $detachAsset, SortAssets $sortAssets, AssetUploader $assetUploader)
35
    {
36
        $this->replaceAsset = $replaceAsset;
37
        $this->addAsset = $addAsset;
38
        $this->detachAsset = $detachAsset;
39
        $this->sortAssets = $sortAssets;
40
        $this->assetUploader = $assetUploader;
41
    }
42
43
    protected function mediaRequest(array $requests, MediaField $field, Request $request): MediaRequest
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

43
    protected function mediaRequest(array $requests, MediaField $field, /** @scrutinizer ignore-unused */ Request $request): MediaRequest

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
44
    {
45
        $mediaRequest = new MediaRequest();
46
47
        foreach ($requests as $requestData) {
48
            foreach ($requestData as $locale => $filesPerLocale) {
49
                foreach ($filesPerLocale as $action => $files) {
50
51
                    if (!is_array($files) || !in_array($action, [
52
                            MediaRequest::NEW,
53
                            MediaRequest::REPLACE,
54
                            MediaRequest::DETACH,
55
                        ])) {
56
                        throw new \InvalidArgumentException('Malformed request data. Files are expected to be passed in a localized array.');
57
                    }
58
59
                    foreach ($files as $k => $file) {
60
61
                        // The null entries in the 'replace' request are passed explicitly - the replace array contains all existing assets (ids as keys, null as value)
62
                        if (is_null($file)) {
63
                            continue;
64
                        }
65
66
                        $mediaRequest->add($action, new MediaRequestInput(
67
                            $file, $locale, $field->getKey(), [
68
                                'index'          => $k,
69
                                // index key is used for replace method to indicate the current asset id
70
                                'existing_asset' => $this->refersToExistingAsset($file),
71
                            ]
72
                        ));
73
                    }
74
                }
75
            }
76
        }
77
78
        return $mediaRequest;
79
    }
80
81
    protected function refersToExistingAsset($value): bool
82
    {
83
        if (!is_string($value) && !is_int($value)) {
84
            return false;
85
        }
86
87
        // check if passed value is an ID
88
        return (bool)preg_match('/^[1-9][0-9]*$/', (string)$value);
89
    }
90
91
    /**
92
     * @param HasAsset $model
93
     * @param MediaRequestInput $mediaRequestInput
94
     * @return Asset
95
     * @throws DuplicateAssetException
96
     * @throws \Spatie\MediaLibrary\Exceptions\FileCannotBeAdded
97
     */
98
    protected function newExistingAsset(HasAsset $model, MediaRequestInput $mediaRequestInput): Asset
99
    {
100
        $existingAsset = Asset::find($mediaRequestInput->value());
101
102
        if ($model->assetRelation()->where('asset_pivots.type', $mediaRequestInput->type())->where('asset_pivots.locale', $mediaRequestInput->locale())->get()->contains($existingAsset)) {
103
            throw new DuplicateAssetException();
104
        }
105
106
        return $this->addAsset->add($model, $existingAsset, $mediaRequestInput->type(), $mediaRequestInput->locale());
107
    }
108
109
    /**
110
     * @param string $filename
111
     * @return string
112
     */
113
    protected function sluggifyFilename(string $filename): string
114
    {
115
        if (false === strpos($filename, '.')) {
116
            return $filename;
117
        }
118
119
        $extension = substr($filename, strrpos($filename, '.') + 1);
120
        $filename = substr($filename, 0, strrpos($filename, '.'));
121
122
        return Str::slug($filename) . '.' . $extension;
123
    }
124
125
    protected function sort(HasAsset $model, MediaField $field, Request $request)
126
    {
127
        if ($request->has('filesOrder')) {
128
            foreach ($request->input('filesOrder') as $locale => $fileIdInput) {
129
130
                $fileIds = $this->getFileIdsFromInput($field->getKey(), $fileIdInput);
131
132
                if (!empty($fileIds)) {
133
                    $this->sortAssets->handle($model, $fileIds, $field->getKey(), $locale);
134
                }
135
            }
136
        }
137
    }
138
139
    /**
140
     * @param string $key
141
     * @param array $fileIdInput
142
     * @return array
143
     */
144
    protected function getFileIdsFromInput(string $key, array $fileIdInput): array
145
    {
146
        $values = isset($fileIdInput[$key])
147
            ? $fileIdInput[$key]
148
            : (isset($fileIdInput['files-' . $key])
149
                ? $fileIdInput['files-' . $key]
150
                : ''
151
            );
152
153
        if(!$values) return [];
154
155
        return explode(',', $values);
156
    }
157
}
158