diff --git a/src/Concerns/Tool.php b/src/Concerns/Tool.php index cc70fc2..3b264eb 100644 --- a/src/Concerns/Tool.php +++ b/src/Concerns/Tool.php @@ -3,20 +3,16 @@ namespace Sowren\SvgAvatarGenerator\Concerns; use Arr; -use Sowren\SvgAvatarGenerator\Exceptions\MissingTextException; +use Sowren\SvgAvatarGenerator\Validators\ConfigValidator; trait Tool { /** * Extract initials using configured extractor. - * - * @throws MissingTextException */ protected function extractInitials(): void { - if (! $this->text) { - throw MissingTextException::create(); - } + ConfigValidator::validate('svg_text', $this->text); $initials = $this->extractor->extract($this->text); $this->setInitials($initials); diff --git a/src/Facades/Svg.php b/src/Facades/Svg.php index 8d6b13a..a36f1d3 100644 --- a/src/Facades/Svg.php +++ b/src/Facades/Svg.php @@ -3,13 +3,45 @@ namespace Sowren\SvgAvatarGenerator\Facades; use Illuminate\Support\Facades\Facade; +use Sowren\SvgAvatarGenerator\Enums\Shape; +use Sowren\SvgAvatarGenerator\Enums\FontWeight; +use Sowren\SvgAvatarGenerator\SvgAvatarGenerator; /** + * @method static SvgAvatarGenerator for(string $text) + * @method static string getInitials() + * @method static int getSize() + * @method static SvgAvatarGenerator setSize(int $size) + * @method static Shape getShape() + * @method static SvgAvatarGenerator asCircle() + * @method static SvgAvatarGenerator asRectangle() + * @method static int getCornerRadius() + * @method static SvgAvatarGenerator setCornerRadius(int $radius) + * @method static string|null getCustomFontUrl() + * @method static SvgAvatarGenerator setCustomFontUrl(?string $url = null) + * @method static string|null getFontFamily() + * @method static SvgAvatarGenerator setFontFamily(?string $name = null) + * @method static int getFontSize() + * @method static SvgAvatarGenerator setFontSize(int $fontSize) + * @method static FontWeight getFontWeight() + * @method static SvgAvatarGenerator setFontWeight(FontWeight $fontWeight) + * @method static string getForeground() + * @method static SvgAvatarGenerator setForeground(string $color) + * @method static int getGradientRotation() + * @method static SvgAvatarGenerator setGradientRotation(int $angle) + * @method static array getGradientColors() + * @method static SvgAvatarGenerator setGradientColors(string|array ...$colors) + * @method static array getGradientStops() + * @method static SvgAvatarGenerator setGradientStops(int|float ...$offsets) + * @method static array getGradientSet() + * @method static \Sowren\SvgAvatarGenerator\Svg render() + * @method static string toUrl() + * * @see \Sowren\SvgAvatarGenerator\SvgAvatarGenerator */ class Svg extends Facade { - protected static function getFacadeAccessor() + protected static function getFacadeAccessor(): string { return \Sowren\SvgAvatarGenerator\SvgAvatarGenerator::class; } diff --git a/src/Http/Controllers/SvgController.php b/src/Http/Controllers/SvgController.php index 257a5c1..b1bac79 100644 --- a/src/Http/Controllers/SvgController.php +++ b/src/Http/Controllers/SvgController.php @@ -5,13 +5,6 @@ use Illuminate\Http\Request; use Illuminate\Http\Response; use Illuminate\Routing\Controller; -use Sowren\SvgAvatarGenerator\Exceptions\InvalidCornerRadius; -use Sowren\SvgAvatarGenerator\Exceptions\InvalidFontSizeException; -use Sowren\SvgAvatarGenerator\Exceptions\InvalidGradientRotationException; -use Sowren\SvgAvatarGenerator\Exceptions\InvalidGradientStopException; -use Sowren\SvgAvatarGenerator\Exceptions\InvalidSvgSizeException; -use Sowren\SvgAvatarGenerator\Exceptions\InvalidUrlException; -use Sowren\SvgAvatarGenerator\Exceptions\MissingTextException; use Sowren\SvgAvatarGenerator\SvgAvatarGenerator; class SvgController extends Controller @@ -23,14 +16,6 @@ public function __construct() /** * Generate an SVG and send it as an HTTP response. - * - * @throws InvalidCornerRadius - * @throws InvalidUrlException - * @throws MissingTextException - * @throws InvalidSvgSizeException - * @throws InvalidFontSizeException - * @throws InvalidGradientStopException - * @throws InvalidGradientRotationException */ public function __invoke(Request $request): Response { diff --git a/src/SvgAvatarGenerator.php b/src/SvgAvatarGenerator.php index 4ebaa5e..4ce7d4c 100755 --- a/src/SvgAvatarGenerator.php +++ b/src/SvgAvatarGenerator.php @@ -6,15 +6,8 @@ use Sowren\SvgAvatarGenerator\Concerns\Tool; use Sowren\SvgAvatarGenerator\Enums\FontWeight; use Sowren\SvgAvatarGenerator\Enums\Shape; -use Sowren\SvgAvatarGenerator\Exceptions\InvalidCornerRadius; -use Sowren\SvgAvatarGenerator\Exceptions\InvalidFontSizeException; -use Sowren\SvgAvatarGenerator\Exceptions\InvalidGradientRotationException; -use Sowren\SvgAvatarGenerator\Exceptions\InvalidGradientStopException; -use Sowren\SvgAvatarGenerator\Exceptions\InvalidSvgSizeException; -use Sowren\SvgAvatarGenerator\Exceptions\InvalidUrlException; -use Sowren\SvgAvatarGenerator\Exceptions\MissingTextException; +use Sowren\SvgAvatarGenerator\Validators\ConfigValidator; use Sowren\SvgAvatarGenerator\Extractors\Extractor; -use URL; class SvgAvatarGenerator { @@ -23,7 +16,7 @@ class SvgAvatarGenerator /** * Initials to be put in SVG. */ - protected string $initials = ''; + private string $initials = ''; /** * Size of the SVG. @@ -88,21 +81,13 @@ class SvgAvatarGenerator /** * Array to hold default config. */ - private array $config; + protected array $config; /** * Instance of predefined extractor. */ - public Extractor $extractor; + protected Extractor $extractor; - /** - * @throws InvalidCornerRadius - * @throws InvalidUrlException - * @throws InvalidSvgSizeException - * @throws InvalidFontSizeException - * @throws InvalidGradientStopException - * @throws InvalidGradientRotationException - */ public function __construct(public ?string $text = null) { $this->config = config('svg-avatar'); @@ -122,8 +107,6 @@ public function for(string $text): static /** * Get generated initials. - * - * @throws MissingTextException */ public function getInitials(): string { @@ -155,14 +138,10 @@ public function getSize(): int /** * Set the SVG size between 16 and 512. The generated * SVG is square always. - * - * @throws InvalidSvgSizeException */ public function setSize(int $size): static { - if ($size < 16 || $size > 512) { - throw InvalidSvgSizeException::create($size); - } + ConfigValidator::validate('svg_size', $size); $this->size = $size; @@ -216,14 +195,10 @@ public function getCornerRadius(): int /** * Set corner radius of rectangular shape. - * - * @throws InvalidCornerRadius */ public function setCornerRadius(int $radius): static { - if ($radius < 0 || $radius > 25) { - throw InvalidCornerRadius::create($radius); - } + ConfigValidator::validate('corner_radius', $radius); $this->cornerRadius = $radius; @@ -240,14 +215,10 @@ public function getCustomFontUrl(): ?string /** * Set the custom font url. - * - * @throws InvalidUrlException */ public function setCustomFontUrl(?string $url = null): static { - if (! empty($url) && ! URL::isValidUrl($url)) { - throw InvalidUrlException::create($url); - } + ConfigValidator::validate('custom_font_url', $url); $this->customFontUrl = $url; @@ -282,14 +253,10 @@ public function getFontSize(): int /** * Set font size of the SVG between 10 and 50. - * - * @throws InvalidFontSizeException */ public function setFontSize(int $fontSize): static { - if ($fontSize < 10 || $fontSize > 50) { - throw InvalidFontSizeException::create($fontSize); - } + ConfigValidator::validate('font_size', $fontSize); $this->fontSize = $fontSize; @@ -343,14 +310,10 @@ public function getGradientRotation(): int /** * Set the angle of the color gradient rotation between 0 and 360. - * - * @throws InvalidGradientRotationException */ public function setGradientRotation(int $angle): static { - if ($angle < 0 || $angle > 360) { - throw InvalidGradientRotationException::create($angle); - } + ConfigValidator::validate('gradiant_rotation', $angle); $this->gradientRotation = $angle; @@ -396,14 +359,10 @@ public function getGradientStops(): array /** * Set stop positions of gradients. - * - * @throws InvalidGradientStopException */ public function setGradientStops(int|float ...$offsets): static { - if ((min($offsets) < 0) || max($offsets) > 1) { - throw InvalidGradientStopException::create($offsets); - } + ConfigValidator::validate('gradiant_stops', $offsets); $this->gradientStops = $offsets; @@ -435,13 +394,6 @@ protected function setGradientSet(): static /** * Set default values from config. - * - * @throws InvalidCornerRadius - * @throws InvalidFontSizeException - * @throws InvalidGradientRotationException - * @throws InvalidSvgSizeException - * @throws InvalidGradientStopException - * @throws InvalidUrlException */ protected function build(): void { @@ -461,8 +413,6 @@ protected function build(): void /** * Render the SVG. - * - * @throws MissingTextException */ public function render(): Svg { diff --git a/src/SvgAvatarGeneratorServiceProvider.php b/src/SvgAvatarGeneratorServiceProvider.php index 997fabb..9c07df5 100644 --- a/src/SvgAvatarGeneratorServiceProvider.php +++ b/src/SvgAvatarGeneratorServiceProvider.php @@ -21,13 +21,13 @@ public function configurePackage(Package $package): void ->hasRoute('web'); } - public function bootingPackage() + public function bootingPackage(): void { // We are not going to publish these views $this->loadViewsFrom(__DIR__.'/../resources/views', 'svg'); } - public function registeringPackage() + public function registeringPackage(): void { $this->app->singleton(Extractor::class, fn () => new (config('svg-avatar.extractor'))); } diff --git a/src/Validators/ConfigValidator.php b/src/Validators/ConfigValidator.php new file mode 100644 index 0000000..dcea173 --- /dev/null +++ b/src/Validators/ConfigValidator.php @@ -0,0 +1,30 @@ + ['int', 'between:0,25'], + 'font_size' => ['int', 'between:10,50'], + 'gradiant_rotation' => ['int', 'between:0,360'], + 'gradiant_stops' => ['array'], + 'gradiant_stops.*' => ['numeric', 'between:0,1'], + 'svg_size' => ['int', 'between:16,512'], + 'custom_font_url' => ['nullable', 'url'], + 'svg_text' => ['required', 'string'] + ]; + + public static function validate(string $key, mixed $value): array + { + $rules = Arr::where(static::$rules, function ($set, $property) use ($key) { + return Str::startsWith($property, $key); + }); + + return Validator::validate([$key => $value], $rules); + } +} diff --git a/tests/ExceptionTest.php b/tests/ExceptionTest.php index a492e27..52eaee4 100644 --- a/tests/ExceptionTest.php +++ b/tests/ExceptionTest.php @@ -1,59 +1,54 @@ 8]); new SvgAvatarGenerator('Rob Stark'); -})->throws(InvalidSvgSizeException::class); +})->throws(ValidationException::class, 'The svg size field must be between 16 and 512.'); it('will throw exception if svg size greater than maximum is provided', function () { config(['svg-avatar.size' => 1024]); new SvgAvatarGenerator('Jon Snow'); -})->throws(InvalidSvgSizeException::class); +})->throws(ValidationException::class, 'The svg size field must be between 16 and 512.'); it('will throw exception if font size less than minimum is provided', function () { config(['svg-avatar.font_size' => 9]); new SvgAvatarGenerator('Sansa Stark'); -})->throws(InvalidFontSizeException::class); +})->throws(ValidationException::class, 'The font size field must be between 10 and 50.'); it('will throw exception if font size greater than maximum is provided', function () { config(['svg-avatar.font_size' => 51]); new SvgAvatarGenerator('Arya Stark'); -})->throws(InvalidFontSizeException::class); +})->throws(ValidationException::class, 'The font size field must be between 10 and 50.'); it('will throw exception if gradient rotation less than minimum is provided', function () { config(['svg-avatar.gradient_rotation' => -1]); new SvgAvatarGenerator('Brandon Stark'); -})->throws(InvalidGradientRotationException::class); +})->throws(ValidationException::class, 'The gradiant rotation field must be between 0 and 360.'); it('will throw exception if gradient rotation greater than maximum is provided', function () { config(['svg-avatar.gradient_rotation' => 361]); new SvgAvatarGenerator('Rickon Stark'); -})->throws(InvalidGradientRotationException::class); +})->throws(ValidationException::class, 'The gradiant rotation field must be between 0 and 360.'); it('will throw missing text exception if text is not set', function () { $generator = new SvgAvatarGenerator(); $generator->getInitials(); -})->throws(MissingTextException::class); +})->throws(ValidationException::class, 'The svg text field is required.'); it('will throw exception if gradient stop less than minimum is provided', function () { - config(['svg-avatar.gradient_stops' => [-1, 1]]); + config(['svg-avatar.gradient_stops' => [-1, 0.5]]); new SvgAvatarGenerator('Lyanna Stark'); -})->throws(InvalidGradientStopException::class); +})->throws(ValidationException::class, 'The gradiant_stops.0 field must be between 0 and 1.'); it('will throw exception if gradient stop greater than maximum is provided', function () { - config(['svg-avatar.gradient_stops' => [0, 2]]); + config(['svg-avatar.gradient_stops' => [0.2, 2]]); new SvgAvatarGenerator('Benjen Stark'); -})->throws(InvalidGradientStopException::class); +})->throws(ValidationException::class, 'The gradiant_stops.1 field must be between 0 and 1.'); it('will throw exception if invalid font url is provided', function () { config(['svg-avatar.custom_font_url' => 'invalid_url']); new SvgAvatarGenerator('Rickard Stark'); -})->throws(InvalidUrlException::class); +})->throws(ValidationException::class, 'The custom font url field must be a valid URL.'); diff --git a/tests/UrlTest.php b/tests/UrlTest.php index 7ec2822..de665a3 100644 --- a/tests/UrlTest.php +++ b/tests/UrlTest.php @@ -1,7 +1,7 @@ throws(MissingTextException::class); +})->throws(ValidationException::class);