Passed
Push — 2.x ( c00759...e3c99f )
by Quentin
07:55
created

MediaLibraryController   A

Complexity

Total Complexity 27

Size/Duplication

Total Lines 301
Duplicated Lines 0 %

Test Coverage

Coverage 73.58%

Importance

Changes 0
Metric Value
eloc 114
dl 0
loc 301
ccs 78
cts 106
cp 0.7358
rs 10
c 0
b 0
f 0
wmc 27

14 Methods

Rating   Name   Duplication   Size   Complexity  
A uploadIsSigned() 0 5 2
A storeReference() 0 10 1
A signAzureUpload() 0 3 1
A getExtraMetadatas() 0 10 4
A getIndexData() 0 12 1
A uploadIsNotValid() 0 3 1
A store() 0 10 2
A bulkUpdate() 0 33 3
A index() 0 7 2
A signS3Upload() 0 3 1
A storeFile() 0 32 2
A __construct() 0 14 1
A getRequestFilters() 0 15 5
A singleUpdate() 0 14 1
1
<?php
2
3
namespace A17\Twill\Http\Controllers\Admin;
4
5
use A17\Twill\Http\Requests\Admin\MediaRequest;
6
use A17\Twill\Models\Media;
7
use A17\Twill\Services\Uploader\SignAzureUpload;
8
use A17\Twill\Services\Uploader\SignS3Upload;
9
use A17\Twill\Services\Uploader\SignUploadListener;
10
use Illuminate\Config\Repository as Config;
11
use Illuminate\Contracts\Foundation\Application;
12
use Illuminate\Http\JsonResponse;
13
use Illuminate\Http\Request;
14
use Illuminate\Routing\ResponseFactory;
15
use Illuminate\Support\Arr;
16
use Illuminate\Support\Collection;
17
use Illuminate\Support\Facades\Storage;
18
19
class MediaLibraryController extends ModuleController implements SignUploadListener
20
{
21
    /**
22
     * @var string
23
     */
24
    protected $moduleName = 'medias';
25
26
    /**
27
     * @var string
28
     */
29
    protected $namespace = 'A17\Twill';
30
31
    /**
32
     * @var array
33
     */
34
    protected $defaultOrders = [
35
        'id' => 'desc',
36
    ];
37
38
    /**
39
     * @var array
40
     */
41
    protected $defaultFilters = [
42
        'search' => 'search',
43
        'tag' => 'tag_id',
44
        'unused' => 'unused'
45
    ];
46
47
    /**
48
     * @var int
49
     */
50
    protected $perPage = 40;
51
52
    /**
53
     * @var string
54
     */
55
    protected $endpointType;
56
57
    /**
58
     * @var array
59
     */
60
    protected $customFields;
61
62
    /**
63
     * @var Illuminate\Routing\ResponseFactory
0 ignored issues
show
Bug introduced by
The type A17\Twill\Http\Controlle...Routing\ResponseFactory was not found. Did you mean Illuminate\Routing\ResponseFactory? If so, make sure to prefix the type with \.
Loading history...
64
     */
65
    protected $responseFactory;
66
67
    /**
68
     * @var Illuminate\Config\Repository
0 ignored issues
show
Bug introduced by
The type A17\Twill\Http\Controlle...inate\Config\Repository was not found. Did you mean Illuminate\Config\Repository? If so, make sure to prefix the type with \.
Loading history...
69
     */
70
    protected $config;
71
72 4
    public function __construct(
73
        Application $app,
74
        Config $config,
75
        Request $request,
76
        ResponseFactory $responseFactory
77
    ) {
78 4
        parent::__construct($app, $request);
79 4
        $this->responseFactory = $responseFactory;
0 ignored issues
show
Documentation Bug introduced by
It seems like $responseFactory of type Illuminate\Routing\ResponseFactory is incompatible with the declared type A17\Twill\Http\Controlle...Routing\ResponseFactory of property $responseFactory.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
80 4
        $this->config = $config;
0 ignored issues
show
Documentation Bug introduced by
It seems like $config of type Illuminate\Config\Repository is incompatible with the declared type A17\Twill\Http\Controlle...inate\Config\Repository of property $config.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
81
82 4
        $this->removeMiddleware('can:edit');
83 4
        $this->middleware('can:edit', ['only' => ['signS3Upload', 'signAzureUpload', 'tags', 'store', 'singleUpdate', 'bulkUpdate']]);
84 4
        $this->endpointType = $this->config->get('twill.media_library.endpoint_type');
85 4
        $this->customFields = $this->config->get('twill.media_library.extra_metadatas_fields');
86 4
    }
87
88
    /**
89
     * @param int|null $parentModuleId
90
     * @return array
91
     */
92 1
    public function index($parentModuleId = null)
93
    {
94 1
        if ($this->request->has('except')) {
95 1
            $prependScope['exceptIds'] = $this->request->get('except');
0 ignored issues
show
Comprehensibility Best Practice introduced by
$prependScope was never initialized. Although not strictly required by PHP, it is generally a good practice to add $prependScope = array(); before regardless.
Loading history...
96
        }
97
98 1
        return $this->getIndexData($prependScope ?? []);
99
    }
100
101
    /**
102
     * @param array $prependScope
103
     * @return array
104
     */
105 1
    public function getIndexData($prependScope = [])
106
    {
107 1
        $scopes = $this->filterScope($prependScope);
108 1
        $items = $this->getIndexItems($scopes);
109
110
        return [
111
            'items' => $items->map(function ($item) {
112
                return $item->toCmsArray();
113 1
            })->toArray(),
114 1
            'maxPage' => $items->lastPage(),
115 1
            'total' => $items->total(),
116 1
            'tags' => $this->repository->getTagsList(),
0 ignored issues
show
Bug introduced by
The method getTagsList() does not exist on A17\Twill\Repositories\ModuleRepository. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

116
            'tags' => $this->repository->/** @scrutinizer ignore-call */ getTagsList(),
Loading history...
117
        ];
118
    }
119
120
    /**
121
     * @return array
122
     */
123 2
    protected function getRequestFilters()
124
    {
125 2
        if ($this->request->has('search')) {
126 1
            $requestFilters['search'] = $this->request->get('search');
0 ignored issues
show
Comprehensibility Best Practice introduced by
$requestFilters was never initialized. Although not strictly required by PHP, it is generally a good practice to add $requestFilters = array(); before regardless.
Loading history...
127
        }
128
129 2
        if ($this->request->has('tag')) {
130 1
            $requestFilters['tag'] = $this->request->get('tag');
131
        }
132
133 2
        if ($this->request->has('unused') && (int) $this->request->unused === 1) {
134
            $requestFilters['unused'] = $this->request->get('unused');
135
        }
136
137 2
        return $requestFilters ?? [];
138
    }
139
140
    /**
141
     * @param int|null $parentModuleId
142
     * @return
143
     */
144 3
    public function store($parentModuleId = null)
145
    {
146 3
        $request = $this->app->make(MediaRequest::class);
147 3
        if ($this->endpointType === 'local') {
148 3
            $media = $this->storeFile($request);
149
        } else {
150
            $media = $this->storeReference($request);
151
        }
152
153 3
        return $this->responseFactory->json(['media' => $media->toCmsArray(), 'success' => true], 200);
154
    }
155
156
    /**
157
     * @param Request $request
158
     * @return Media
159
     */
160 3
    public function storeFile($request)
161
    {
162 3
        $originalFilename = $request->input('qqfilename');
163
164 3
        $filename = sanitizeFilename($originalFilename);
165
166 3
        $fileDirectory = $request->input('unique_folder_name');
167
168 3
        $uuid = $request->input('unique_folder_name') . '/' . $filename;
169
170 3
        if ($this->config->get('twill.media_library.prefix_uuid_with_local_path', false)) {
171
            $prefix = trim($this->config->get('twill.media_library.local_path'), '/ ') . '/';
172
            $fileDirectory = $prefix . $fileDirectory;
173
            $uuid = $prefix . $uuid;
174
        }
175
176 3
        $disk = $this->config->get('twill.media_library.disk');
177
178 3
        $request->file('qqfile')->storeAs($fileDirectory, $filename, $disk);
179
180 3
        $filePath = Storage::disk($disk)->path($fileDirectory . '/' . $filename);
181
182 3
        list($w, $h) = getimagesize($filePath);
183
184
        $fields = [
185 3
            'uuid' => $uuid,
186 3
            'filename' => $originalFilename,
187 3
            'width' => $w,
188 3
            'height' => $h,
189
        ];
190
191 3
        return $this->repository->create($fields);
192
    }
193
194
    /**
195
     * @param Request $request
196
     * @return Media
197
     */
198
    public function storeReference($request)
199
    {
200
        $fields = [
201
            'uuid' => $request->input('key') ?? $request->input('blob'),
202
            'filename' => $request->input('name'),
203
            'width' => $request->input('width'),
204
            'height' => $request->input('height'),
205
        ];
206
207
        return $this->repository->create($fields);
208
    }
209
210
    /**
211
     * @return JsonResponse
212
     */
213 1
    public function singleUpdate()
214
    {
215 1
        $this->repository->update(
216 1
            $this->request->input('id'),
217 1
            array_merge([
218 1
                'alt_text' => $this->request->get('alt_text', null),
219 1
                'caption' => $this->request->get('caption', null),
220 1
                'tags' => $this->request->get('tags', null),
221 1
            ], $this->getExtraMetadatas()->toArray())
222
        );
223
224 1
        return $this->responseFactory->json([
225 1
            'tags' => $this->repository->getTagsList(),
226 1
        ], 200);
227
    }
228
229
    /**
230
     * @return JsonResponse
231
     */
232 1
    public function bulkUpdate()
233
    {
234 1
        $ids = explode(',', $this->request->input('ids'));
235
236
        $metadatasFromRequest = $this->getExtraMetadatas()->reject(function ($meta) {
237
            return is_null($meta);
238 1
        })->toArray();
239
240 1
        $extraMetadatas = array_diff_key($metadatasFromRequest, array_flip((array) $this->request->get('fieldsRemovedFromBulkEditing', [])));
241
242 1
        if (in_array('tags', $this->request->get('fieldsRemovedFromBulkEditing', []))) {
243
            $this->repository->addIgnoreFieldsBeforeSave('bulk_tags');
0 ignored issues
show
Bug introduced by
'bulk_tags' of type string is incompatible with the type array expected by parameter $ignore of A17\Twill\Repositories\M...gnoreFieldsBeforeSave(). ( Ignorable by Annotation )

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

243
            $this->repository->addIgnoreFieldsBeforeSave(/** @scrutinizer ignore-type */ 'bulk_tags');
Loading history...
244
        } else {
245 1
            $previousCommonTags = $this->repository->getTags(null, $ids);
0 ignored issues
show
Bug introduced by
The method getTags() does not exist on A17\Twill\Repositories\ModuleRepository. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

245
            /** @scrutinizer ignore-call */ 
246
            $previousCommonTags = $this->repository->getTags(null, $ids);
Loading history...
246 1
            $newTags = array_filter(explode(',', $this->request->input('tags')));
247
        }
248
249 1
        foreach ($ids as $id) {
250 1
            $this->repository->update($id, [
251 1
                'bulk_tags' => $newTags ?? [],
252 1
                'previous_common_tags' => $previousCommonTags ?? [],
253 1
            ] + $extraMetadatas);
254
        }
255
256 1
        $scopes = $this->filterScope(['id' => $ids]);
257 1
        $items = $this->getIndexItems($scopes);
258
259 1
        return $this->responseFactory->json([
260
            'items' => $items->map(function ($item) {
261 1
                return $item->toCmsArray();
262 1
            })->toArray(),
263 1
            'tags' => $this->repository->getTagsList(),
264 1
        ], 200);
265
    }
266
267
    /**
268
     * @param Request $request
269
     * @param SignS3Upload $signS3Upload
270
     * @return mixed
271
     */
272
    public function signS3Upload(Request $request, SignS3Upload $signS3Upload)
273
    {
274
        return $signS3Upload->fromPolicy($request->getContent(), $this, $this->config->get('twill.media_library.disk'));
275
    }
276
277
    /**
278
     * @param Request $request
279
     * @param SignAzureUpload $signAzureUpload
280
     * @return mixed
281
     */
282
    public function signAzureUpload(Request $request, SignAzureUpload $signAzureUpload)
283
    {
284
        return $signAzureUpload->getSasUrl($request, $this, $this->config->get('twill.media_library.disk'));
285
    }
286
287
    /**
288
     * @param $signature
289
     * @param bool $isJsonResponse
290
     * @return mixed
291
     */
292
    public function uploadIsSigned($signature, $isJsonResponse = true)
293
    {
294
        return $isJsonResponse
295
        ? $this->responseFactory->json($signature, 200)
296
        : $this->responseFactory->make($signature, 200, ['Content-Type' => 'text/plain']);
297
    }
298
299
    /**
300
     * @return JsonResponse
301
     */
302
    public function uploadIsNotValid()
303
    {
304
        return $this->responseFactory->json(["invalid" => true], 500);
305
    }
306
307
    /**
308
     * @return Collection
309
     */
310 2
    private function getExtraMetadatas()
311
    {
312
        return Collection::make($this->customFields)->mapWithKeys(function ($field) {
313
            $fieldInRequest = $this->request->get($field['name']);
314
315
            if (isset($field['type']) && $field['type'] === 'checkbox') {
316
                return [$field['name'] => $fieldInRequest ? Arr::first($fieldInRequest) : false];
317
            }
318
319
            return [$field['name'] => $fieldInRequest];
320 2
        });
321
    }
322
}
323