$minWith ?? $this->minWith, 'minHeight' => $minHeight ?? $this->minHeight, 'maxWith' => $maxWith ?? $this->maxWith, 'maxHeight' => $maxHeight ?? $this->maxHeight ]; return [ $name => [ $required ? 'required' : 'nullable', function (string $attribute, $value, callable $fail) use ($sizes) { return $this->validatePicture($attribute, $value, $fail, $sizes); } ] ]; } /** * Images rules * * @param string $name * @param boolean $required * @param integer|null $limitMin * @param integer|null $limitMax * @param integer|null $minWith * @param integer|null $minHeight * @param integer|null $maxWith * @param integer|null $maxHeight * @return array */ public function picturesRules( string $name = 'pictures', ?bool $required = null, ?int $limitMin = null, ?int $limitMax = null, ?int $minWith = null, ?int $minHeight = null, ?int $maxWith = null, ?int $maxHeight = null ): array { $sizes = (object)[ 'required' => $required ?? $this->required, 'limitMin' => $limitMin ?? $this->limitMin, 'limitMax' => $limitMax ?? $this->limitMax, 'minWith' => $minWith ?? $this->minWith, 'minHeight' => $minHeight ?? $this->minHeight, 'maxWith' => $maxWith ?? $this->maxWith, 'maxHeight' => $maxHeight ?? $this->maxHeight ]; return [ "{$name}" => ($required ? 'required' : 'nullable') . "|array|between:$limitMin,$limitMax", "{$name}.*" => [ ($required ? 'required' : 'nullable'), function (string $attribute, $value, callable $fail) use ($sizes) { return $this->validatePicture($attribute, $value, $fail, $sizes); } ] ]; } /** * Validate picture. * * @param string $attribute * @param mixed $value * @param callback $fail * @param object $sizes * @return void * @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed */ private function validatePicture(string $attribute, mixed $value, callable $fail, object $sizes) { if (!($useStorage = Storage::exists($value)) and !File::exists($value)) { $fail(trans(":attribute n'existe pas dans le système de fichier")); return; } /** @var string */ $fileFullPath = $this->getUploadedFileFullPath($value, $useStorage); if ( !\in_array($this->getUploadedFileMimeType($value, $useStorage), [ 'image/jpeg', 'image/jpg', 'image/png', 'image/gif' ]) ) { $fail(trans(":attribute doit être une image de type 'image/jpeg,image/jpg,image/png,image/gif'")); } $filesize = \filesize($fileFullPath); $maxSize = 6 * 1024 * 1024; if ($filesize === false || $filesize > $maxSize) { $fail(trans(':attribute doit être inférieur à :size Mo', ['size' => $maxSize / (1024 * 1024)])); } if (!($dimensions = \getimagesize($fileFullPath)) or !isset($dimensions[0]) or !isset($dimensions[1])) { $fail(trans(":attribute impossible de valider les dimensions")); } else { $width = intval($dimensions[0]); $height = intval($dimensions[1]); $xMessage = trans( ":attribute la largeur doit être comprise entre {$sizes->minWith}px et {$sizes->maxWith}px" ); if ($sizes->minWith === $sizes->maxWith) { $xMessage = trans(":attribute la largeur doit être de {$sizes->minWith}px"); } $yMessage = trans( ":attribute la hauteur doit être comprise entre {$sizes->minWith}px et {$sizes->maxWith}px" ); if ($sizes->minHeight === $sizes->maxHeight) { $yMessage = trans(":attribute la hauteur doit être de {$sizes->minWith}px"); } if (($width < $sizes->minWith) or ($width > $sizes->maxWith)) { $fail($xMessage); } if (($height < $sizes->minHeight) or ($height > $sizes->maxHeight)) { $fail($yMessage); } } //end if } /** * Merges picture field with request data. * * @param string $name * @return void */ protected function mergePicture(string $name = 'picture'): void { $picturePath = $this->{$name}; if (is_string($picturePath)) { $this->merge(["{$name}Validate" => []]); // ! Empty picture. if ($picturePath === 'false') { // * Empty picture and exit $this->merge([$name => []]); return; } $decodedPath = \urldecode($picturePath); $this->merge([ "{$name}Validate" => array_merge( $this->{"{$name}Validate"}, [\public_path(ltrim($decodedPath, '/'))] ) ]); $changedPicture = ltrim($decodedPath, '/'); $this->merge([ $name => $changedPicture ]); } //end if } /** * Merges pictures fields with request data. * * @param string $name * @return void */ protected function mergePictures(string $name = 'pictures'): void { $pictures = $this->{$name}; if (is_array($pictures)) { $this->merge(["{$name}Validate" => []]); foreach ($pictures as $key => $picturePath) { // ! Empty picture. if ($picturePath === 'false') { // * Empty picture and exit $this->merge([$name => []]); return; } $decodedPath = \urldecode($picturePath); $this->merge([ "{$name}Validate" => array_merge( $this->{"{$name}Validate"}, [\public_path(ltrim($decodedPath, '/'))] ) ]); $changedPicture = $this->{$name}; $changedPicture[$key] = ltrim($decodedPath, '/'); $this->merge([ $name => $changedPicture ]); } } //end if } /** * Get the file full path. * * @param string $value * @param boolean $useStorage * @return string */ private function getUploadedFileFullPath(string $value, bool $useStorage): string { return !$useStorage ? (realpath($value) ?: $value) : Storage::path($value); } /** * Get the file mimetype. * * @param string $value * @param boolean $useStorage * @return string|false */ private function getUploadedFileMimeType(string $value, bool $useStorage) { return !$useStorage ? File::mimeType($value) : Storage::mimeType($value); } }