diff --git a/CHANGELOG.md b/CHANGELOG.md index 0fec7611..2d9a632e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,8 @@ * fix [Flasher] Fix NotificationStorageMethods::resolveResourceName() return type from ?string to string (never returns null) * fix [Flasher] Fix parameter name inconsistency in NotificationBuilderInterface::options() - changed $merge to $append to match implementation * fix [Flasher] Add type validation for callable presenter return values in ResponseManager with descriptive error messages +* fix [Flasher] Fix FlasherPlugin::normalizePlugins() losing scripts/styles when both top-level and plugin-level configs are provided - replaced array union operator with array_merge +* fix [Flasher] Simplify FlasherPlugin::normalizeFlashBag() by replacing redundant array union with direct array_merge ## [v2.1.3](https://github.com/php-flasher/php-flasher/compare/v2.1.2...v2.1.3) - 2025-01-25 diff --git a/src/Prime/Plugin/FlasherPlugin.php b/src/Prime/Plugin/FlasherPlugin.php index f0a56d49..d4278658 100644 --- a/src/Prime/Plugin/FlasherPlugin.php +++ b/src/Prime/Plugin/FlasherPlugin.php @@ -127,18 +127,24 @@ final class FlasherPlugin extends Plugin } if (!empty($config['scripts'])) { - $config['plugins']['flasher']['scripts'] ??= []; - $config['plugins']['flasher']['scripts'] += $config['scripts']; + $config['plugins']['flasher']['scripts'] = array_merge( + $config['plugins']['flasher']['scripts'] ?? [], + $config['scripts'] + ); } if (!empty($config['styles'])) { - $config['plugins']['flasher']['styles'] ??= []; - $config['plugins']['flasher']['styles'] += $config['styles']; + $config['plugins']['flasher']['styles'] = array_merge( + $config['plugins']['flasher']['styles'] ?? [], + $config['styles'] + ); } if (!empty($config['options'])) { - $config['plugins']['flasher']['options'] ??= []; - $config['plugins']['flasher']['options'] += $config['options']; + $config['plugins']['flasher']['options'] = array_merge( + $config['options'], + $config['plugins']['flasher']['options'] ?? [] + ); } foreach ($config['plugins'] as $name => $options) { @@ -345,7 +351,7 @@ final class FlasherPlugin extends Plugin return $config; } - $config['flash_bag'] += array_merge($mapping, $config['flash_bag']); + $config['flash_bag'] = array_merge($mapping, $config['flash_bag']); return $config; } diff --git a/tests/Prime/Plugin/FlasherPluginTest.php b/tests/Prime/Plugin/FlasherPluginTest.php index f9daeb13..b07ba4c8 100644 --- a/tests/Prime/Plugin/FlasherPluginTest.php +++ b/tests/Prime/Plugin/FlasherPluginTest.php @@ -406,4 +406,57 @@ final class FlasherPluginTest extends TestCase $plugin = new FlasherPlugin(); $this->assertSame([], $plugin->getOptions()); } + + public function testNormalizeConfigMergesTopLevelAndPluginLevelScripts(): void + { + $plugin = new FlasherPlugin(); + $config = $plugin->normalizeConfig([ + 'scripts' => ['/top-level.js'], + 'plugins' => [ + 'flasher' => [ + 'scripts' => ['/plugin-level.js'], + ], + ], + ]); + + // Both scripts should be present - plugin-level first, then top-level + $this->assertCount(2, $config['plugins']['flasher']['scripts']); + $this->assertContains('/plugin-level.js', $config['plugins']['flasher']['scripts']); + $this->assertContains('/top-level.js', $config['plugins']['flasher']['scripts']); + } + + public function testNormalizeConfigMergesTopLevelAndPluginLevelStyles(): void + { + $plugin = new FlasherPlugin(); + $config = $plugin->normalizeConfig([ + 'styles' => ['/top-level.css'], + 'plugins' => [ + 'flasher' => [ + 'styles' => ['/plugin-level.css'], + ], + ], + ]); + + // Both styles should be present + $this->assertContains('/plugin-level.css', $config['plugins']['flasher']['styles']); + $this->assertContains('/top-level.css', $config['plugins']['flasher']['styles']); + } + + public function testNormalizeConfigMergesOptionsWithPluginLevelOverride(): void + { + $plugin = new FlasherPlugin(); + $config = $plugin->normalizeConfig([ + 'options' => ['timeout' => 5000, 'position' => 'top-right'], + 'plugins' => [ + 'flasher' => [ + 'options' => ['timeout' => 3000], + ], + ], + ]); + + // Plugin-level timeout should override top-level + $this->assertSame(3000, $config['plugins']['flasher']['options']['timeout']); + // Top-level position should be preserved as default + $this->assertSame('top-right', $config['plugins']['flasher']['options']['position']); + } }