|
29 | 29 | use phpMyFAQ\Link\Strategy\SearchStrategy; |
30 | 30 | use phpMyFAQ\Link\Strategy\ShowStrategy; |
31 | 31 | use phpMyFAQ\Link\Strategy\SitemapStrategy; |
| 32 | +use phpMyFAQ\Link\Strategy\StrategyInterface; |
32 | 33 | use phpMyFAQ\Link\Strategy\StrategyRegistry; |
33 | 34 | use phpMyFAQ\Link\Util\LinkQueryParser; |
34 | 35 | use phpMyFAQ\Link\Util\TitleSlugifier; |
@@ -237,26 +238,33 @@ class Link |
237 | 238 | public function __construct( |
238 | 239 | public string $url, |
239 | 240 | private readonly Configuration $configuration, |
| 241 | + ?StrategyRegistry $strategyRegistry = null, |
240 | 242 | ) { |
241 | | - $this->strategyRegistry = new StrategyRegistry([ |
242 | | - // Complex strategies |
243 | | - self::LINK_GET_ACTION_FAQ => new FaqStrategy(), |
244 | | - self::LINK_GET_ACTION_SEARCH => new SearchStrategy(), |
245 | | - self::LINK_GET_ACTION_SITEMAP => new SitemapStrategy(), |
246 | | - self::LINK_GET_ACTION_SHOW => new ShowStrategy(), |
247 | | - self::LINK_GET_ACTION_NEWS => new NewsStrategy(), |
248 | | - // Simple path-based strategies |
249 | | - self::LINK_GET_ACTION_ADD => new GenericPathStrategy(self::LINK_HTML_ADDCONTENT), |
250 | | - self::LINK_GET_ACTION_ASK => new GenericPathStrategy(self::LINK_HTML_ASK), |
251 | | - self::LINK_GET_ACTION_CONTACT => new GenericPathStrategy(self::LINK_HTML_CONTACT), |
252 | | - self::LINK_GET_ACTION_GLOSSARY => new GenericPathStrategy(self::LINK_HTML_GLOSSARY), |
253 | | - self::LINK_GET_ACTION_HELP => new GenericPathStrategy(self::LINK_HTML_HELP), |
254 | | - self::LINK_GET_ACTION_OPEN => new GenericPathStrategy(self::LINK_HTML_OPEN), |
255 | | - self::LINK_GET_ACTION_LOGIN => new GenericPathStrategy(self::LINK_HTML_LOGIN), |
256 | | - self::LINK_GET_ACTION_PASSWORD => new GenericPathStrategy(self::LINK_HTML_FORGOT_PASSWORD), |
257 | | - self::LINK_GET_ACTION_BOOKMARKS => new GenericPathStrategy(self::LINK_HTML_BOOKMARKS), |
258 | | - self::LINK_GET_ACTION_REGISTER => new GenericPathStrategy(self::LINK_HTML_REGISTER), |
259 | | - ]); |
| 243 | + if ($strategyRegistry === null) { |
| 244 | + // default registry population (previous behavior) |
| 245 | + $strategyRegistry = new StrategyRegistry([ |
| 246 | + self::LINK_GET_ACTION_FAQ => new FaqStrategy(), |
| 247 | + self::LINK_GET_ACTION_SEARCH => new SearchStrategy(), |
| 248 | + self::LINK_GET_ACTION_SITEMAP => new SitemapStrategy(), |
| 249 | + self::LINK_GET_ACTION_SHOW => new ShowStrategy(), |
| 250 | + self::LINK_GET_ACTION_NEWS => new NewsStrategy(), |
| 251 | + // Simple path-based strategies |
| 252 | + self::LINK_GET_ACTION_ADD => new GenericPathStrategy(self::LINK_HTML_ADDCONTENT), |
| 253 | + self::LINK_GET_ACTION_ASK => new GenericPathStrategy(self::LINK_HTML_ASK), |
| 254 | + self::LINK_GET_ACTION_CONTACT => new GenericPathStrategy(self::LINK_HTML_CONTACT), |
| 255 | + self::LINK_GET_ACTION_GLOSSARY => new GenericPathStrategy(self::LINK_HTML_GLOSSARY), |
| 256 | + self::LINK_GET_ACTION_HELP => new GenericPathStrategy(self::LINK_HTML_HELP), |
| 257 | + self::LINK_GET_ACTION_OPEN => new GenericPathStrategy(self::LINK_HTML_OPEN), |
| 258 | + self::LINK_GET_ACTION_LOGIN => new GenericPathStrategy(self::LINK_HTML_LOGIN), |
| 259 | + self::LINK_GET_ACTION_PASSWORD => new GenericPathStrategy(self::LINK_HTML_FORGOT_PASSWORD), |
| 260 | + self::LINK_GET_ACTION_BOOKMARKS => new GenericPathStrategy(self::LINK_HTML_BOOKMARKS), |
| 261 | + self::LINK_GET_ACTION_REGISTER => new GenericPathStrategy(self::LINK_HTML_REGISTER), |
| 262 | + ]); |
| 263 | + } else { |
| 264 | + // Merge missing default strategies when a custom registry is injected (non-destructive) |
| 265 | + $this->ensureDefaultStrategies($strategyRegistry); |
| 266 | + } |
| 267 | + $this->strategyRegistry = $strategyRegistry; |
260 | 268 | } |
261 | 269 |
|
262 | 270 | /** |
@@ -598,4 +606,50 @@ private function appendSessionId(string $url, int $sids): string |
598 | 606 |
|
599 | 607 | return $url . $separator . self::LINK_GET_SIDS . self::LINK_EQUAL . $sids; |
600 | 608 | } |
| 609 | + |
| 610 | + /** |
| 611 | + * Returns the injected StrategyRegistry instance. |
| 612 | + */ |
| 613 | + public function getStrategyRegistry(): StrategyRegistry |
| 614 | + { |
| 615 | + return $this->strategyRegistry; |
| 616 | + } |
| 617 | + |
| 618 | + /** |
| 619 | + * Registers or overrides a strategy at runtime (plugin extension point). |
| 620 | + */ |
| 621 | + public function registerStrategy(string $action, StrategyInterface $strategy): void |
| 622 | + { |
| 623 | + $this->strategyRegistry->register($action, $strategy); |
| 624 | + } |
| 625 | + |
| 626 | + /** |
| 627 | + * Ensures that all default strategies exist in the provided registry without overriding existing entries. |
| 628 | + */ |
| 629 | + private function ensureDefaultStrategies(StrategyRegistry $registry): void |
| 630 | + { |
| 631 | + $defaults = [ |
| 632 | + self::LINK_GET_ACTION_FAQ => fn() => new FaqStrategy(), |
| 633 | + self::LINK_GET_ACTION_SEARCH => fn() => new SearchStrategy(), |
| 634 | + self::LINK_GET_ACTION_SITEMAP => fn() => new SitemapStrategy(), |
| 635 | + self::LINK_GET_ACTION_SHOW => fn() => new ShowStrategy(), |
| 636 | + self::LINK_GET_ACTION_NEWS => fn() => new NewsStrategy(), |
| 637 | + // Simple path-based strategies |
| 638 | + self::LINK_GET_ACTION_ADD => fn() => new GenericPathStrategy(self::LINK_HTML_ADDCONTENT), |
| 639 | + self::LINK_GET_ACTION_ASK => fn() => new GenericPathStrategy(self::LINK_HTML_ASK), |
| 640 | + self::LINK_GET_ACTION_CONTACT => fn() => new GenericPathStrategy(self::LINK_HTML_CONTACT), |
| 641 | + self::LINK_GET_ACTION_GLOSSARY => fn() => new GenericPathStrategy(self::LINK_HTML_GLOSSARY), |
| 642 | + self::LINK_GET_ACTION_HELP => fn() => new GenericPathStrategy(self::LINK_HTML_HELP), |
| 643 | + self::LINK_GET_ACTION_OPEN => fn() => new GenericPathStrategy(self::LINK_HTML_OPEN), |
| 644 | + self::LINK_GET_ACTION_LOGIN => fn() => new GenericPathStrategy(self::LINK_HTML_LOGIN), |
| 645 | + self::LINK_GET_ACTION_PASSWORD => fn() => new GenericPathStrategy(self::LINK_HTML_FORGOT_PASSWORD), |
| 646 | + self::LINK_GET_ACTION_BOOKMARKS => fn() => new GenericPathStrategy(self::LINK_HTML_BOOKMARKS), |
| 647 | + self::LINK_GET_ACTION_REGISTER => fn() => new GenericPathStrategy(self::LINK_HTML_REGISTER), |
| 648 | + ]; |
| 649 | + foreach ($defaults as $action => $factory) { |
| 650 | + if (!$registry->has($action)) { |
| 651 | + $registry->register($action, $factory()); |
| 652 | + } |
| 653 | + } |
| 654 | + } |
601 | 655 | } |
0 commit comments