Skip to content

Commit 0e8bad4

Browse files
committed
fix: removed benchmark test, added possible DI for strategy registry
1 parent e130d09 commit 0e8bad4

File tree

3 files changed

+139
-61
lines changed

3 files changed

+139
-61
lines changed

phpmyfaq/src/phpMyFAQ/Link.php

Lines changed: 73 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
use phpMyFAQ\Link\Strategy\SearchStrategy;
3030
use phpMyFAQ\Link\Strategy\ShowStrategy;
3131
use phpMyFAQ\Link\Strategy\SitemapStrategy;
32+
use phpMyFAQ\Link\Strategy\StrategyInterface;
3233
use phpMyFAQ\Link\Strategy\StrategyRegistry;
3334
use phpMyFAQ\Link\Util\LinkQueryParser;
3435
use phpMyFAQ\Link\Util\TitleSlugifier;
@@ -237,26 +238,33 @@ class Link
237238
public function __construct(
238239
public string $url,
239240
private readonly Configuration $configuration,
241+
?StrategyRegistry $strategyRegistry = null,
240242
) {
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;
260268
}
261269

262270
/**
@@ -598,4 +606,50 @@ private function appendSessionId(string $url, int $sids): string
598606

599607
return $url . $separator . self::LINK_GET_SIDS . self::LINK_EQUAL . $sids;
600608
}
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+
}
601655
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace phpMyFAQ\Link;
6+
7+
use phpMyFAQ\Configuration;
8+
use phpMyFAQ\Database\Sqlite3;
9+
use phpMyFAQ\Link;
10+
use phpMyFAQ\Link\Strategy\StrategyInterface;
11+
use phpMyFAQ\Link\Strategy\StrategyRegistry;
12+
use phpMyFAQ\Strings;
13+
use PHPUnit\Framework\TestCase;
14+
15+
final class LinkStrategyRegistryDiTest extends TestCase
16+
{
17+
private Configuration $configuration;
18+
19+
protected function setUp(): void
20+
{
21+
Strings::init();
22+
$dbHandle = new Sqlite3();
23+
$dbHandle->connect(PMF_TEST_DIR . '/test.db', '', '');
24+
$this->configuration = new Configuration($dbHandle);
25+
}
26+
27+
public function testInjectEmptyRegistryMergesDefaults(): void
28+
{
29+
$registry = new StrategyRegistry();
30+
$link = new Link('https://example.com/index.php?action=show', $this->configuration, $registry);
31+
32+
// Defaults should be merged in
33+
$this->assertTrue($link->getStrategyRegistry()->has(Link::LINK_GET_ACTION_SHOW));
34+
35+
$showStrategy = $link->getStrategyRegistry()->get(Link::LINK_GET_ACTION_SHOW);
36+
$this->assertNotNull($showStrategy);
37+
38+
$urlPart = $showStrategy->build([Link::LINK_GET_CATEGORY => '0'], $link);
39+
$this->assertSame(Link::LINK_HTML_SHOW_CATEGORIES, $urlPart);
40+
}
41+
42+
public function testOverrideExistingStrategy(): void
43+
{
44+
$custom = new class implements StrategyInterface {
45+
public function build(array $params, Link $link): string
46+
{
47+
return 'overridden.html';
48+
}
49+
};
50+
51+
$registry = new StrategyRegistry([
52+
Link::LINK_GET_ACTION_SHOW => $custom,
53+
]);
54+
$link = new Link('https://example.com/index.php?action=show', $this->configuration, $registry);
55+
56+
// ensure our custom strategy is still in place (not overridden by defaults)
57+
$this->assertTrue($link->getStrategyRegistry()->has(Link::LINK_GET_ACTION_SHOW));
58+
$strategy = $link->getStrategyRegistry()->get(Link::LINK_GET_ACTION_SHOW);
59+
$this->assertSame('overridden.html', $strategy->build([], $link));
60+
61+
// Also verify runtime registration API
62+
$link->registerStrategy('custom', $custom);
63+
$this->assertTrue($link->getStrategyRegistry()->has('custom'));
64+
}
65+
}
66+

tests/phpMyFAQ/Link/Util/TitleSlugifierBenchTest.php

Lines changed: 0 additions & 42 deletions
This file was deleted.

0 commit comments

Comments
 (0)