diff --git a/src/Laravel/Command/InstallCommand.php b/src/Laravel/Command/InstallCommand.php index 3ec65969..d69e4db4 100644 --- a/src/Laravel/Command/InstallCommand.php +++ b/src/Laravel/Command/InstallCommand.php @@ -119,7 +119,7 @@ final class InstallCommand extends Command $output->writeln(' ERROR An error occurred during the installation of PHPFlasher resources.'); } - $this->assetManager->createManifest(array_merge([], ...$files)); + $this->assetManager->createManifest(array_merge(...$files)); $output->writeln(''); diff --git a/src/Prime/Plugin/FlasherPlugin.php b/src/Prime/Plugin/FlasherPlugin.php index d4278658..d39c4f49 100644 --- a/src/Prime/Plugin/FlasherPlugin.php +++ b/src/Prime/Plugin/FlasherPlugin.php @@ -397,6 +397,25 @@ final class FlasherPlugin extends Plugin return $config; } + private const DEFAULT_THEME_NAMES = [ + 'amazon', + 'amber', + 'jade', + 'crystal', + 'emerald', + 'sapphire', + 'ruby', + 'onyx', + 'neon', + 'aurora', + 'minimal', + 'material', + 'google', + 'ios', + 'slack', + 'facebook', + ]; + /** * @return array [ - 'scripts' => ['/vendor/flasher/themes/amazon/amazon.min.js'], + $themes = []; + + foreach (self::DEFAULT_THEME_NAMES as $name) { + $themes[$name] = [ + 'scripts' => ["/vendor/flasher/themes/{$name}/{$name}.min.js"], 'styles' => [ '/vendor/flasher/flasher.min.css', - '/vendor/flasher/themes/amazon/amazon.min.css', + "/vendor/flasher/themes/{$name}/{$name}.min.css", ], 'options' => [], - ], - 'amber' => [ - 'scripts' => ['/vendor/flasher/themes/amber/amber.min.js'], - 'styles' => [ - '/vendor/flasher/flasher.min.css', - '/vendor/flasher/themes/amber/amber.min.css', - ], - 'options' => [], - ], - 'jade' => [ - 'scripts' => ['/vendor/flasher/themes/jade/jade.min.js'], - 'styles' => [ - '/vendor/flasher/flasher.min.css', - '/vendor/flasher/themes/jade/jade.min.css', - ], - 'options' => [], - ], - 'crystal' => [ - 'scripts' => ['/vendor/flasher/themes/crystal/crystal.min.js'], - 'styles' => [ - '/vendor/flasher/flasher.min.css', - '/vendor/flasher/themes/crystal/crystal.min.css', - ], - 'options' => [], - ], - 'emerald' => [ - 'scripts' => ['/vendor/flasher/themes/emerald/emerald.min.js'], - 'styles' => [ - '/vendor/flasher/flasher.min.css', - '/vendor/flasher/themes/emerald/emerald.min.css', - ], - 'options' => [], - ], - 'sapphire' => [ - 'scripts' => ['/vendor/flasher/themes/sapphire/sapphire.min.js'], - 'styles' => [ - '/vendor/flasher/flasher.min.css', - '/vendor/flasher/themes/sapphire/sapphire.min.css', - ], - 'options' => [], - ], - 'ruby' => [ - 'scripts' => ['/vendor/flasher/themes/ruby/ruby.min.js'], - 'styles' => [ - '/vendor/flasher/flasher.min.css', - '/vendor/flasher/themes/ruby/ruby.min.css', - ], - 'options' => [], - ], - 'onyx' => [ - 'scripts' => ['/vendor/flasher/themes/onyx/onyx.min.js'], - 'styles' => [ - '/vendor/flasher/flasher.min.css', - '/vendor/flasher/themes/onyx/onyx.min.css', - ], - 'options' => [], - ], - 'neon' => [ - 'scripts' => ['/vendor/flasher/themes/neon/neon.min.js'], - 'styles' => [ - '/vendor/flasher/flasher.min.css', - '/vendor/flasher/themes/neon/neon.min.css', - ], - 'options' => [], - ], - 'aurora' => [ - 'scripts' => ['/vendor/flasher/themes/aurora/aurora.min.js'], - 'styles' => [ - '/vendor/flasher/flasher.min.css', - '/vendor/flasher/themes/aurora/aurora.min.css', - ], - 'options' => [], - ], - 'minimal' => [ - 'scripts' => ['/vendor/flasher/themes/minimal/minimal.min.js'], - 'styles' => [ - '/vendor/flasher/flasher.min.css', - '/vendor/flasher/themes/minimal/minimal.min.css', - ], - 'options' => [], - ], - 'material' => [ - 'scripts' => ['/vendor/flasher/themes/material/material.min.js'], - 'styles' => [ - '/vendor/flasher/flasher.min.css', - '/vendor/flasher/themes/material/material.min.css', - ], - 'options' => [], - ], - 'google' => [ - 'scripts' => ['/vendor/flasher/themes/google/google.min.js'], - 'styles' => [ - '/vendor/flasher/flasher.min.css', - '/vendor/flasher/themes/google/google.min.css', - ], - 'options' => [], - ], - 'ios' => [ - 'scripts' => ['/vendor/flasher/themes/ios/ios.min.js'], - 'styles' => [ - '/vendor/flasher/flasher.min.css', - '/vendor/flasher/themes/ios/ios.min.css', - ], - 'options' => [], - ], - 'slack' => [ - 'scripts' => ['/vendor/flasher/themes/slack/slack.min.js'], - 'styles' => [ - '/vendor/flasher/flasher.min.css', - '/vendor/flasher/themes/slack/slack.min.css', - ], - 'options' => [], - ], - 'facebook' => [ - 'scripts' => ['/vendor/flasher/themes/facebook/facebook.min.js'], - 'styles' => [ - '/vendor/flasher/flasher.min.css', - '/vendor/flasher/themes/facebook/facebook.min.css', - ], - 'options' => [], - ], - ]; + ]; + } + + return $themes; } } diff --git a/src/Prime/Storage/Filter/Criteria/FilterCriteria.php b/src/Prime/Storage/Filter/Criteria/FilterCriteria.php index 9d2125bf..0558adfb 100644 --- a/src/Prime/Storage/Filter/Criteria/FilterCriteria.php +++ b/src/Prime/Storage/Filter/Criteria/FilterCriteria.php @@ -36,11 +36,23 @@ final class FilterCriteria implements CriteriaInterface * @param Envelope[] $envelopes * * @return Envelope[] + * + * @throws \InvalidArgumentException */ public function apply(array $envelopes): array { foreach ($this->callbacks as $callback) { - $envelopes = $callback($envelopes); + $result = $callback($envelopes); + + if (!\is_array($result)) { + throw new \InvalidArgumentException(\sprintf( + 'Filter callback must return an array, got "%s".', + get_debug_type($result) + )); + } + + /** @var Envelope[] $result */ + $envelopes = $result; } return $envelopes; diff --git a/src/SweetAlert/Prime/SweetAlertBuilder.php b/src/SweetAlert/Prime/SweetAlertBuilder.php index 58b905af..7f98131e 100644 --- a/src/SweetAlert/Prime/SweetAlertBuilder.php +++ b/src/SweetAlert/Prime/SweetAlertBuilder.php @@ -152,7 +152,7 @@ final class SweetAlertBuilder extends NotificationBuilder } /** - * @phpstan-param array $options + * @phpstan-param OptionsType $options */ public function question(?string $message = null, array $options = []): self { @@ -162,7 +162,7 @@ final class SweetAlertBuilder extends NotificationBuilder $this->messages($message); } - if ([] === $options) { + if ([] !== $options) { $this->options($options); } @@ -229,8 +229,9 @@ final class SweetAlertBuilder extends NotificationBuilder public function showClass(string $showClass, string $value): self { + /** @var array $option */ $option = $this->getEnvelope()->getOption('showClass', []); - $option[$showClass] = $value; // @phpstan-ignore-line + $option[$showClass] = $value; $this->option('showClass', $option); @@ -239,8 +240,9 @@ final class SweetAlertBuilder extends NotificationBuilder public function hideClass(string $hideClass, string $value): self { + /** @var array $option */ $option = $this->getEnvelope()->getOption('hideClass', []); - $option[$hideClass] = $value; // @phpstan-ignore-line + $option[$hideClass] = $value; $this->option('hideClass', $option); diff --git a/src/Symfony/Command/InstallCommand.php b/src/Symfony/Command/InstallCommand.php index 7ad392f0..849d1f25 100644 --- a/src/Symfony/Command/InstallCommand.php +++ b/src/Symfony/Command/InstallCommand.php @@ -134,7 +134,7 @@ final class InstallCommand extends Command } // Create asset manifest - $this->assetManager->createManifest(array_merge([], ...$files)); + $this->assetManager->createManifest(array_merge(...$files)); $output->writeln(''); diff --git a/tests/Prime/Storage/Filter/Criteria/FilterCriteriaTest.php b/tests/Prime/Storage/Filter/Criteria/FilterCriteriaTest.php index 0d7ecf23..1830c15f 100644 --- a/tests/Prime/Storage/Filter/Criteria/FilterCriteriaTest.php +++ b/tests/Prime/Storage/Filter/Criteria/FilterCriteriaTest.php @@ -194,4 +194,34 @@ final class FilterCriteriaTest extends TestCase $this->assertCount(1, $result); $this->assertSame('test', $result[0]->getMessage()); } + + public function testApplyThrowsExceptionWhenCallbackReturnsNonArray(): void + { + $criteria = new FilterCriteria(fn ($e) => 'not an array'); + + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('Filter callback must return an array, got "string".'); + + $criteria->apply([new Envelope(new Notification())]); + } + + public function testApplyThrowsExceptionWhenCallbackReturnsNull(): void + { + $criteria = new FilterCriteria(fn ($e) => null); + + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('Filter callback must return an array, got "null".'); + + $criteria->apply([new Envelope(new Notification())]); + } + + public function testApplyThrowsExceptionWhenCallbackReturnsObject(): void + { + $criteria = new FilterCriteria(fn ($e) => new \stdClass()); + + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('Filter callback must return an array, got "stdClass".'); + + $criteria->apply([new Envelope(new Notification())]); + } } diff --git a/tests/SweetAlert/Prime/SweetAlertBuilderTest.php b/tests/SweetAlert/Prime/SweetAlertBuilderTest.php index 238835b3..6fb4ced1 100644 --- a/tests/SweetAlert/Prime/SweetAlertBuilderTest.php +++ b/tests/SweetAlert/Prime/SweetAlertBuilderTest.php @@ -29,7 +29,7 @@ final class SweetAlertBuilderTest extends TestCase $envelope = $this->sweetAlertBuilder->getEnvelope(); $options = $envelope->getNotification()->getOptions(); - $this->assertSame(['showCancelButton' => true, 'text' => 'Are you sure?'], $options); + $this->assertSame(['showCancelButton' => true, 'text' => 'Are you sure?', 'option1' => 'value1'], $options); } public function testTitle(): void