Passed
Push — master ( e1ac4a...a9f297 )
by
unknown
09:26 queued 11s
created

MediaLibraryController::storeReference()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
nc 1
nop 1
dl 0
loc 10
rs 10
c 0
b 0
f 0
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\Container\BindingResolutionException;
12
use Illuminate\Contracts\Foundation\Application;
13
use Illuminate\Http\JsonResponse;
14
use Illuminate\Http\Request;
15
use Illuminate\Routing\ResponseFactory;
16
use Illuminate\Support\Arr;
17
use Illuminate\Support\Collection;
18
use Illuminate\Support\Facades\Storage;
19
20
class MediaLibraryController extends ModuleController implements SignUploadListener
21
{
22
    /**
23
     * @var string
24
     */
25
    protected $moduleName = 'medias';
26
27
    /**
28
     * @var string
29
     */
30
    protected $namespace = 'A17\Twill';
31
32
    /**
33
     * @var array
34
     */
35
    protected $defaultOrders = [
36
        'id' => 'desc',
37
    ];
38
39
    /**
40
     * @var array
41
     */
42
    protected $defaultFilters = [
43
        'search' => 'search',
44
        'tag' => 'tag_id',
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
    public function __construct(
63
        Application $app,
64
        Config $config,
65
        Request $request,
66
        ResponseFactory $responseFactory
67
    )
68
    {
69
        parent::__construct($app, $request);
70
        $this->responseFactory = $responseFactory;
0 ignored issues
show
Bug Best Practice introduced by
The property responseFactory does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
71
        $this->config = $config;
0 ignored issues
show
Bug Best Practice introduced by
The property config does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
72
73
        $this->removeMiddleware('can:edit');
74
        $this->middleware('can:edit', ['only' => ['signS3Upload', 'signAzureUpload', 'tags', 'store', 'singleUpdate', 'bulkUpdate']]);
75
        $this->endpointType = $this->config->get('twill.media_library.endpoint_type');
76
        $this->customFields = $this->config->get('twill.media_library.extra_metadatas_fields');
77
    }
78
79
    /**
80
     * @param int|null $parentModuleId
81
     * @return array
82
     */
83
    public function index($parentModuleId = null)
84
    {
85
        if ($this->request->has('except')) {
86
            $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...
87
        }
88
89
        return $this->getIndexData($prependScope ?? []);
90
    }
91
92
    /**
93
     * @param array $prependScope
94
     * @return array
95
     */
96
    public function getIndexData($prependScope = [])
97
    {
98
        $scopes = $this->filterScope($prependScope);
99
        $items = $this->getIndexItems($scopes);
100
101
        return [
102
            'items' => $items->map(function ($item) {
103
                return $item->toCmsArray();
104
            })->toArray(),
105
            'maxPage' => $items->lastPage(),
106
            'total' => $items->total(),
107
            '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

107
            'tags' => $this->repository->/** @scrutinizer ignore-call */ getTagsList(),
Loading history...
108
        ];
109
    }
110
111
    /**
112
     * @return array
113
     */
114
    protected function getRequestFilters()
115
    {
116
        if ($this->request->has('search')) {
117
            $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...
118
        }
119
120
        if ($this->request->has('tag')) {
121
            $requestFilters['tag'] = $this->request->get('tag');
122
        }
123
124
        return $requestFilters ?? [];
125
    }
126
127
    /**
128
     * @param int|null $parentModuleId
129
     * @return
130
     */
131
    public function store($parentModuleId = null)
132
    {
133
        $request = $this->app->make(MediaRequest::class);
134
        if ($this->endpointType === 'local') {
135
            $media = $this->storeFile($request);
136
        } else {
137
            $media = $this->storeReference($request);
138
        }
139
140
        return $this->responseFactory->json(['media' => $media->toCmsArray(), 'success' => true], 200);
141
    }
142
143
    /**
144
     * @param Request $request
145
     * @return Media
146
     */
147
    public function storeFile($request)
148
    {
149
        $originalFilename = $request->input('qqfilename');
150
151
        $filename = sanitizeFilename($originalFilename);
152
153
        $fileDirectory = $request->input('unique_folder_name');
154
155
        $uuid = $request->input('unique_folder_name') . '/' . $filename;
156
157
        if ($this->config->get('twill.media_library.prefix_uuid_with_local_path', false)) {
158
            $prefix = trim($this->config->get('twill.media_library.local_path'), '/ ') . '/';
159
            $fileDirectory = $prefix . $fileDirectory;
160
            $uuid = $prefix . $uuid;
161
        }
162
163
        $disk = $this->config->get('twill.media_library.disk');
164
165
        $request->file('qqfile')->storeAs($fileDirectory, $filename, $disk);
166
167
        $filePath = Storage::disk($disk)->path($fileDirectory . '/' . $filename);
168
169
        list($w, $h) = getimagesize($filePath);
170
171
        $fields = [
172
            'uuid' => $uuid,
173
            'filename' => $originalFilename,
174
            'width' => $w,
175
            'height' => $h,
176
        ];
177
178
        return $this->repository->create($fields);
179
    }
180
181
    /**
182
     * @param Request $request
183
     * @return Media
184
     */
185
    public function storeReference($request)
186
    {
187
        $fields = [
188
            'uuid' => $request->input('key') ?? $request->input('blob'),
189
            'filename' => $request->input('name'),
190
            'width' => $request->input('width'),
191
            'height' => $request->input('height'),
192
        ];
193
194
        return $this->repository->create($fields);
195
    }
196
197
    /**
198
     * @return JsonResponse
199
     */
200
    public function singleUpdate()
201
    {
202
        $this->repository->update(
203
            $this->request->input('id'),
204
            array_merge([
205
                'alt_text' => $this->request->get('alt_text', null),
206
                'caption' => $this->request->get('caption', null),
207
                'tags' => $this->request->get('tags', null),
208
            ], $this->getExtraMetadatas()->toArray())
209
        );
210
211
        return $this->responseFactory->json([
212
            'tags' => $this->repository->getTagsList(),
213
        ], 200);
214
    }
215
216
    /**
217
     * @return JsonResponse
218
     */
219
    public function bulkUpdate()
220
    {
221
        $ids = explode(',', $this->request->input('ids'));
222
223
        $metadatasFromRequest = $this->getExtraMetadatas()->reject(function ($meta) {
224
            return is_null($meta);
225
        })->toArray();
226
227
        $extraMetadatas = array_diff_key($metadatasFromRequest, array_flip((array)$this->request->get('fieldsRemovedFromBulkEditing', [])));
228
229
        if (in_array('tags', $this->request->get('fieldsRemovedFromBulkEditing', []))) {
230
            $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

230
            $this->repository->addIgnoreFieldsBeforeSave(/** @scrutinizer ignore-type */ 'bulk_tags');
Loading history...
231
        } else {
232
            $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

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