From 2c0c87339ef72c0af7af24d892bacdd8c872869d Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 14 Mar 2025 10:12:56 +0000 Subject: [PATCH] add events for storage_config and storage_instance hooks --- src/Core/Hooks/HookEventBridge.php | 4 + .../Storage/Repository/StorageManager.php | 18 ++- src/Event/ArrayFilterEvent.php | 4 + tests/Unit/Core/Hooks/HookEventBridgeTest.php | 4 + tests/Unit/Event/ArrayFilterEventTest.php | 2 + tests/Util/FakeEventDispatcher.php | 31 ++++++ .../Storage/Repository/StorageManagerTest.php | 103 +++++++++++++++--- 7 files changed, 149 insertions(+), 17 deletions(-) create mode 100644 tests/Util/FakeEventDispatcher.php diff --git a/src/Core/Hooks/HookEventBridge.php b/src/Core/Hooks/HookEventBridge.php index 18a41a1730..6dc9d01e20 100644 --- a/src/Core/Hooks/HookEventBridge.php +++ b/src/Core/Hooks/HookEventBridge.php @@ -68,6 +68,8 @@ final class HookEventBridge ArrayFilterEvent::BLOCK_CONTACT => 'block', ArrayFilterEvent::UNBLOCK_CONTACT => 'unblock', ArrayFilterEvent::ADD_WORKER_TASK => 'proc_run', + ArrayFilterEvent::STORAGE_CONFIG => 'storage_config', + ArrayFilterEvent::STORAGE_INSTANCE => 'storage_instance', HtmlFilterEvent::HEAD => 'head', HtmlFilterEvent::FOOTER => 'footer', HtmlFilterEvent::PAGE_HEADER => 'page_header', @@ -116,6 +118,8 @@ final class HookEventBridge ArrayFilterEvent::BLOCK_CONTACT => 'onArrayFilterEvent', ArrayFilterEvent::UNBLOCK_CONTACT => 'onArrayFilterEvent', ArrayFilterEvent::ADD_WORKER_TASK => 'onArrayFilterEvent', + ArrayFilterEvent::STORAGE_CONFIG => 'onArrayFilterEvent', + ArrayFilterEvent::STORAGE_INSTANCE => 'onArrayFilterEvent', HtmlFilterEvent::HEAD => 'onHtmlFilterEvent', HtmlFilterEvent::FOOTER => 'onHtmlFilterEvent', HtmlFilterEvent::PAGE_HEADER => 'onHtmlFilterEvent', diff --git a/src/Core/Storage/Repository/StorageManager.php b/src/Core/Storage/Repository/StorageManager.php index bbd9e13f14..1de89dbddc 100644 --- a/src/Core/Storage/Repository/StorageManager.php +++ b/src/Core/Storage/Repository/StorageManager.php @@ -20,7 +20,9 @@ use Friendica\Core\Storage\Capability\ICanWriteToStorage; use Friendica\Database\Database; use Friendica\Core\Storage\Type; use Friendica\DI; +use Friendica\Event\ArrayFilterEvent; use Friendica\Network\HTTPException\InternalServerErrorException; +use Psr\EventDispatcher\EventDispatcherInterface; use Psr\Log\LoggerInterface; /** @@ -55,6 +57,7 @@ class StorageManager private $config; /** @var LoggerInterface */ private $logger; + private EventDispatcherInterface $eventDispatcher; /** @var L10n */ private $l10n; @@ -71,11 +74,12 @@ class StorageManager * @throws InvalidClassStorageException in case the active backend class is invalid * @throws StorageException in case of unexpected errors during the active backend class loading */ - public function __construct(Database $dba, IManageConfigValues $config, LoggerInterface $logger, L10n $l10n, bool $includeAddon = true) + public function __construct(Database $dba, IManageConfigValues $config, LoggerInterface $logger, EventDispatcherInterface $eventDispatcher, L10n $l10n, bool $includeAddon = true) { $this->dba = $dba; $this->config = $config; $this->logger = $logger; + $this->eventDispatcher = $eventDispatcher; $this->l10n = $l10n; $this->validBackends = $config->get('storage', 'backends', self::DEFAULT_BACKENDS); @@ -146,8 +150,12 @@ class StorageManager 'name' => $name, 'storage_config' => null, ]; + try { - Hook::callAll('storage_config', $data); + $data = $this->eventDispatcher->dispatch( + new ArrayFilterEvent(ArrayFilterEvent::STORAGE_CONFIG, $data), + )->getArray(); + if (!($data['storage_config'] ?? null) instanceof ICanConfigureStorage) { throw new InvalidClassStorageException(sprintf('Configuration for backend %s was not found', $name)); } @@ -201,8 +209,12 @@ class StorageManager 'name' => $name, 'storage' => null, ]; + try { - Hook::callAll('storage_instance', $data); + $data = $this->eventDispatcher->dispatch( + new ArrayFilterEvent(ArrayFilterEvent::STORAGE_INSTANCE, $data), + )->getArray(); + if (!($data['storage'] ?? null) instanceof ICanReadFromStorage) { throw new InvalidClassStorageException(sprintf('Backend %s was not found', $name)); } diff --git a/src/Event/ArrayFilterEvent.php b/src/Event/ArrayFilterEvent.php index 6967524f86..4a08ba4fa3 100644 --- a/src/Event/ArrayFilterEvent.php +++ b/src/Event/ArrayFilterEvent.php @@ -74,6 +74,10 @@ final class ArrayFilterEvent extends Event public const ADD_WORKER_TASK = 'friendica.data.add_worker_task'; + public const STORAGE_CONFIG = 'friendica.data.storage_config'; + + public const STORAGE_INSTANCE = 'friendica.data.storage_instance'; + private array $array; public function __construct(string $name, array $array) diff --git a/tests/Unit/Core/Hooks/HookEventBridgeTest.php b/tests/Unit/Core/Hooks/HookEventBridgeTest.php index d7df82e4d1..8ae803bdab 100644 --- a/tests/Unit/Core/Hooks/HookEventBridgeTest.php +++ b/tests/Unit/Core/Hooks/HookEventBridgeTest.php @@ -57,6 +57,8 @@ class HookEventBridgeTest extends TestCase ArrayFilterEvent::BLOCK_CONTACT => 'onArrayFilterEvent', ArrayFilterEvent::UNBLOCK_CONTACT => 'onArrayFilterEvent', ArrayFilterEvent::ADD_WORKER_TASK => 'onArrayFilterEvent', + ArrayFilterEvent::STORAGE_CONFIG => 'onArrayFilterEvent', + ArrayFilterEvent::STORAGE_INSTANCE => 'onArrayFilterEvent', HtmlFilterEvent::HEAD => 'onHtmlFilterEvent', HtmlFilterEvent::FOOTER => 'onHtmlFilterEvent', HtmlFilterEvent::PAGE_HEADER => 'onHtmlFilterEvent', @@ -290,6 +292,8 @@ class HookEventBridgeTest extends TestCase [ArrayFilterEvent::BLOCK_CONTACT, 'block'], [ArrayFilterEvent::UNBLOCK_CONTACT, 'unblock'], [ArrayFilterEvent::ADD_WORKER_TASK, 'proc_run'], + [ArrayFilterEvent::STORAGE_CONFIG, 'storage_config'], + [ArrayFilterEvent::STORAGE_INSTANCE, 'storage_instance'], ]; } diff --git a/tests/Unit/Event/ArrayFilterEventTest.php b/tests/Unit/Event/ArrayFilterEventTest.php index 2afebba496..c57b45ceb1 100644 --- a/tests/Unit/Event/ArrayFilterEventTest.php +++ b/tests/Unit/Event/ArrayFilterEventTest.php @@ -53,6 +53,8 @@ class ArrayFilterEventTest extends TestCase [ArrayFilterEvent::BLOCK_CONTACT, 'friendica.data.block_contact'], [ArrayFilterEvent::UNBLOCK_CONTACT, 'friendica.data.unblock_contact'], [ArrayFilterEvent::ADD_WORKER_TASK, 'friendica.data.add_worker_task'], + [ArrayFilterEvent::STORAGE_CONFIG, 'friendica.data.storage_config'], + [ArrayFilterEvent::STORAGE_INSTANCE, 'friendica.data.storage_instance'], ]; } diff --git a/tests/Util/FakeEventDispatcher.php b/tests/Util/FakeEventDispatcher.php new file mode 100644 index 0000000000..070e8e77d9 --- /dev/null +++ b/tests/Util/FakeEventDispatcher.php @@ -0,0 +1,31 @@ +at($this->root); - $this->logger = new NullLogger(); $this->database = $this->getDbInstance(); $configFactory = new Config(); @@ -87,7 +85,14 @@ class StorageManagerTest extends DatabaseTestCase */ public function testInstance() { - $storageManager = new StorageManager($this->database, $this->config, $this->logger, $this->l10n, false); + $storageManager = new StorageManager( + $this->database, + $this->config, + new NullLogger(), + new FakeEventDispatcher(), + $this->l10n, + false + ); self::assertInstanceOf(StorageManager::class, $storageManager); } @@ -149,7 +154,14 @@ class StorageManagerTest extends DatabaseTestCase $this->config->set('storage', 'name', $name); } - $storageManager = new StorageManager($this->database, $this->config, $this->logger, $this->l10n, false); + $storageManager = new StorageManager( + $this->database, + $this->config, + new NullLogger(), + new FakeEventDispatcher(), + $this->l10n, + false + ); if ($interface === ICanWriteToStorage::class) { $storage = $storageManager->getWritableStorageByName($name); @@ -169,7 +181,14 @@ class StorageManagerTest extends DatabaseTestCase */ public function testIsValidBackend($name, $valid, $interface, $assert, $assertName) { - $storageManager = new StorageManager($this->database, $this->config, $this->logger, $this->l10n, false); + $storageManager = new StorageManager( + $this->database, + $this->config, + new NullLogger(), + new FakeEventDispatcher(), + $this->l10n, + false + ); // true in every of the backends self::assertEquals(!empty($assertName), $storageManager->isValidBackend($name)); @@ -183,7 +202,14 @@ class StorageManagerTest extends DatabaseTestCase */ public function testListBackends() { - $storageManager = new StorageManager($this->database, $this->config, $this->logger, $this->l10n, false); + $storageManager = new StorageManager( + $this->database, + $this->config, + new NullLogger(), + new FakeEventDispatcher(), + $this->l10n, + false + ); self::assertEquals(StorageManager::DEFAULT_BACKENDS, $storageManager->listBackends()); } @@ -199,7 +225,14 @@ class StorageManagerTest extends DatabaseTestCase static::markTestSkipped('only works for ICanWriteToStorage'); } - $storageManager = new StorageManager($this->database, $this->config, $this->logger, $this->l10n, false); + $storageManager = new StorageManager( + $this->database, + $this->config, + new NullLogger(), + new FakeEventDispatcher(), + $this->l10n, + false + ); $selBackend = $storageManager->getWritableStorageByName($name); $storageManager->setBackend($selBackend); @@ -219,7 +252,14 @@ class StorageManagerTest extends DatabaseTestCase $this->expectException(InvalidClassStorageException::class); } - $storageManager = new StorageManager($this->database, $this->config, $this->logger, $this->l10n, false); + $storageManager = new StorageManager( + $this->database, + $this->config, + new NullLogger(), + new FakeEventDispatcher(), + $this->l10n, + false + ); self::assertInstanceOf($assert, $storageManager->getBackend()); } @@ -240,7 +280,14 @@ class StorageManagerTest extends DatabaseTestCase ->addRule(IHandleSessions::class, ['instanceOf' => Memory::class, 'shared' => true, 'call' => null]); DI::init($dice); - $storageManager = new StorageManager($this->database, $this->config, $this->logger, $this->l10n, false); + $storageManager = new StorageManager( + $this->database, + $this->config, + new NullLogger(), + new FakeEventDispatcher(), + $this->l10n, + false + ); self::assertTrue($storageManager->register(SampleStorageBackend::class)); @@ -268,7 +315,21 @@ class StorageManagerTest extends DatabaseTestCase ->addRule(IHandleSessions::class, ['instanceOf' => Memory::class, 'shared' => true, 'call' => null]); DI::init($dice); - $storageManager = new StorageManager($this->database, $this->config, $this->logger, $this->l10n, false); + /** @var \Friendica\Event\EventDispatcher */ + $eventDispatcher = DI::eventDispatcher(); + + foreach (HookEventBridge::getStaticSubscribedEvents() as $eventName => $methodName) { + $eventDispatcher->addListener($eventName, [HookEventBridge::class, $methodName]); + } + + $storageManager = new StorageManager( + $this->database, + $this->config, + new NullLogger(), + $eventDispatcher, + $this->l10n, + false + ); self::assertTrue($storageManager->register(SampleStorageBackend::class)); @@ -307,7 +368,14 @@ class StorageManagerTest extends DatabaseTestCase $this->loadFixture(__DIR__ . '/../../../../datasets/storage/database.fixture.php', $this->database); - $storageManager = new StorageManager($this->database, $this->config, $this->logger, $this->l10n, false); + $storageManager = new StorageManager( + $this->database, + $this->config, + new NullLogger(), + new FakeEventDispatcher(), + $this->l10n, + false + ); $storage = $storageManager->getWritableStorageByName($name); $storageManager->move($storage); @@ -331,7 +399,14 @@ class StorageManagerTest extends DatabaseTestCase $this->expectException(InvalidClassStorageException::class); $this->expectExceptionMessage('Backend SystemResource is not valid'); - $storageManager = new StorageManager($this->database, $this->config, $this->logger, $this->l10n, false); + $storageManager = new StorageManager( + $this->database, + $this->config, + new NullLogger(), + new FakeEventDispatcher(), + $this->l10n, + false + ); $storage = $storageManager->getWritableStorageByName(SystemResource::getName()); $storageManager->move($storage); }