[ 'type' => 'image', 'extension' => 'jpeg', ], 'image/jpg' => [ 'type' => 'image', 'extension' => 'jpg', ], 'image/png' => [ 'type' => 'image', 'extension' => 'png', ], /* 'image/svg+xml' => [ 'type' => 'image', 'extension' => 'svg' ], */ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => [ 'type' => 'document', 'extension' => 'xlsx' ], 'application/vnd.ms-excel' => [ 'type' => 'document', 'extension' => 'xls' ], 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => [ 'type' => 'document', 'extension' => 'docx' ], 'application/msword' => [ 'type' => 'document', 'extension' => 'doc' ], 'application/pdf' => [ 'type' => 'document', 'extension' => 'pdf' ], 'application/vnd.openxmlformats-officedocument.presentationml.presentation' => [ 'type' => 'document', 'extension' => 'pptx' ] ]; protected Client $client; protected Asset $model; public function __construct(Client $client, Asset $model) { $this->client = $client; $this->model = $model; } public function store(Request $request): JsonResponse { if ($request->isJson()) { $asset = $this->uploadFromUrl([ 'url' => $request->get('url'), 'user' => $request->user(), ]); } elseif ($request->hasFile('file')) { $file = $request->file('file')->getRealPath(); $asset = $this->uploadFromDirectFile([ 'mime' => $request->file('file')->getMimeType(), 'name' => $request->get('name') ?? $request->file('file')->getClientOriginalName(), 'filename' => $request->file('file')->getClientOriginalName(), 'extension' => $request->file('file')->getClientOriginalExtension(), 'content' => file_get_contents($file), 'Content-Length' => $request->header('Content-Length'), 'user' => $request->user(), 'latitude' => $request->get('latitude'), 'longitude' => $request->get('longitude'), 'accuracy' => $request->get('accuracy') ]); } else { $body = !(base64_decode($request->getContent())) ? $request->getContent() : base64_decode($request->getContent()); $asset = $this->uploadFromDirectFile([ 'mime' => $request->header('Content-Type'), 'content' => $body, 'Content-Length' => $request->header('Content-Length'), 'user' => $request->user(), 'latitude' => $request->get('latitude'), 'longitude' => $request->get('longitude') ]); } event(new AssetWasCreated($asset)); return fractal($asset, new AssetTransformer())->respond(201); } protected function uploadFromDirectFile($attributes = []) { $this->validateMime($attributes['mime']); $this->validateBodySize($attributes['Content-Length'], $attributes['content']); $path = $this->storeInFileSystem($attributes); return $this->storeInDatabase($attributes, $path); } protected function uploadFromUrl($attributes = []) { $response = $this->callFileUrl($attributes['url']); $attributes['mime'] = $response->getHeader('content-type')[0]; $attributes['filename'] = pathinfo($attributes['url'], PATHINFO_BASENAME); $attributes['extension'] = pathinfo($attributes['url'], PATHINFO_EXTENSION); $this->validateMime($attributes['mime']); $attributes['content'] = $response->getBody(); $path = $this->storeInFileSystem($attributes); return $this->storeInDatabase($attributes, $path); } protected function storeInDatabase(array $attributes, $path) { $file = $this->model->create([ 'type' => $this->validMimes[$attributes['mime']]['type'], 'path' => $path, 'mime' => $attributes['mime'], 'name' => $attributes['name'] ?? null, 'filename' => $attributes['filename'] ?? null, 'extension' => $attributes['extension'] ?? null, 'user_id' => ! empty($attributes['user']) ? $attributes['user']->id : null, 'latitude' => $attributes['latitude'], 'longitude' => $attributes['longitude'], 'accuracy' => $attributes['accuracy'] ]); return $file; } protected function storeInFileSystem(array $attributes): string { $filename = md5(Str::random(16).date('U')); $path = "public/upload/{$filename[0]}/$filename.{$this->validMimes[$attributes['mime']]['extension']}"; Storage::put($path, $attributes['content']); return $path; } protected function callFileUrl($url): ResponseInterface { try { return $this->client->get($url); } catch (TransferException $e) { throw new StoreResourceFailedException('Validation Error', [ 'url' => 'The url seems to be unreachable: '.$e->getCode(), ]); } } protected function validateMime($mime) { if (!array_key_exists($mime, $this->validMimes)) { throw new StoreResourceFailedException('Validation Error', [ 'Content-Type' => 'The Content Type sent is not valid', 'mime' => $mime ]); } } protected function validateBodySize($contentLength, $content) { if ($contentLength > config('files.maxsize', 1000000) || mb_strlen($content) > config('files.maxsize', 1000000)) { throw new BodyTooLargeException(); } } }