Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>tags/v22.0.0beta1
@@ -44,6 +44,7 @@ use OCP\EventDispatcher\IEventDispatcher; | |||
use OCP\Files\Template\ICustomTemplateProvider; | |||
use OCP\Http\WellKnown\IHandler; | |||
use OCP\ILogger; | |||
use OCP\Notification\INotifier; | |||
use OCP\Search\IProvider; | |||
use OCP\Support\CrashReport\IReporter; | |||
use Throwable; | |||
@@ -90,6 +91,9 @@ class RegistrationContext { | |||
/** @var ServiceRegistration<ICustomTemplateProvider>[] */ | |||
private $templateProviders = []; | |||
/** @var ServiceRegistration<INotifier>[] */ | |||
private $notifierServices; | |||
/** @var ILogger */ | |||
private $logger; | |||
@@ -206,6 +210,13 @@ class RegistrationContext { | |||
$providerClass | |||
); | |||
} | |||
public function registerNotifierService(string $notifierClass): void { | |||
$this->context->registerNotifierService( | |||
$this->appId, | |||
$notifierClass | |||
); | |||
} | |||
}; | |||
} | |||
@@ -273,6 +284,10 @@ class RegistrationContext { | |||
$this->templateProviders[] = new ServiceRegistration($appId, $class); | |||
} | |||
public function registerNotifierService(string $appId, string $class): void { | |||
$this->notifierServices[] = new ServiceRegistration($appId, $class); | |||
} | |||
/** | |||
* @param App[] $apps | |||
*/ | |||
@@ -457,4 +472,11 @@ class RegistrationContext { | |||
public function getTemplateProviders(): array { | |||
return $this->templateProviders; | |||
} | |||
/** | |||
* @return ServiceRegistration<INotifier>[] | |||
*/ | |||
public function getNotifierServices(): array { | |||
return $this->notifierServices; | |||
} | |||
} |
@@ -27,6 +27,7 @@ declare(strict_types=1); | |||
namespace OC\Notification; | |||
use OC\AppFramework\Bootstrap\Coordinator; | |||
use OCP\AppFramework\QueryException; | |||
use OCP\ILogger; | |||
use OCP\Notification\AlreadyProcessedException; | |||
@@ -43,6 +44,8 @@ class Manager implements IManager { | |||
protected $validator; | |||
/** @var ILogger */ | |||
protected $logger; | |||
/** @var Coordinator */ | |||
private $coordinator; | |||
/** @var IApp[] */ | |||
protected $apps; | |||
@@ -58,17 +61,23 @@ class Manager implements IManager { | |||
protected $preparingPushNotification; | |||
/** @var bool */ | |||
protected $deferPushing; | |||
/** @var bool */ | |||
private $parsedRegistrationContext; | |||
public function __construct(IValidator $validator, | |||
ILogger $logger) { | |||
ILogger $logger, | |||
Coordinator $coordinator) { | |||
$this->validator = $validator; | |||
$this->logger = $logger; | |||
$this->coordinator = $coordinator; | |||
$this->apps = []; | |||
$this->notifiers = []; | |||
$this->appClasses = []; | |||
$this->notifierClasses = []; | |||
$this->preparingPushNotification = false; | |||
$this->deferPushing = false; | |||
$this->parsedRegistrationContext = false; | |||
} | |||
/** | |||
* @param string $appClass The service must implement IApp, otherwise a | |||
@@ -141,6 +150,32 @@ class Manager implements IManager { | |||
* @return INotifier[] | |||
*/ | |||
public function getNotifiers(): array { | |||
if (!$this->parsedRegistrationContext) { | |||
$notifierServices = $this->coordinator->getRegistrationContext()->getNotifierServices(); | |||
foreach ($notifierServices as $notifierService) { | |||
try { | |||
$notifier = \OC::$server->query($notifierService->getService()); | |||
} catch (QueryException $e) { | |||
$this->logger->logException($e, [ | |||
'message' => 'Failed to load notification notifier class: ' . $notifierService->getService(), | |||
'app' => 'notifications', | |||
]); | |||
continue; | |||
} | |||
if (!($notifier instanceof INotifier)) { | |||
$this->logger->error('Notification notifier class ' . $notifierService->getService() . ' is not implementing ' . INotifier::class, [ | |||
'app' => 'notifications', | |||
]); | |||
continue; | |||
} | |||
$this->notifiers[] = $notifier; | |||
} | |||
$this->parsedRegistrationContext = true; | |||
} | |||
if (empty($this->notifierClasses)) { | |||
return $this->notifiers; | |||
} |
@@ -34,6 +34,7 @@ use OCP\Capabilities\ICapability; | |||
use OCP\EventDispatcher\IEventDispatcher; | |||
use OCP\Files\Template\ICustomTemplateProvider; | |||
use OCP\IContainer; | |||
use OCP\Notification\INotifier; | |||
/** | |||
* The context object passed to IBootstrap::register | |||
@@ -209,4 +210,13 @@ interface IRegistrationContext { | |||
* @since 21.0.0 | |||
*/ | |||
public function registerTemplateProvider(string $providerClass): void; | |||
/** | |||
* Register an INotifier class | |||
* | |||
* @param string $notifierClass | |||
* @psalm-param class-string<INotifier> $notifierClass | |||
* @since 22.0.0 | |||
*/ | |||
public function registerNotifierService(string $notifierClass): void; | |||
} |
@@ -21,6 +21,9 @@ | |||
namespace Test\Notification; | |||
use OC\AppFramework\Bootstrap\Coordinator; | |||
use OC\AppFramework\Bootstrap\RegistrationContext; | |||
use OC\AppFramework\Bootstrap\ServiceRegistration; | |||
use OC\Notification\Manager; | |||
use OCP\ILogger; | |||
use OCP\Notification\IManager; | |||
@@ -37,12 +40,23 @@ class ManagerTest extends TestCase { | |||
protected $validator; | |||
/** @var ILogger|MockObject */ | |||
protected $logger; | |||
/** @var Coordinator|MockObject */ | |||
protected $coordinator; | |||
/** @var RegistrationContext|MockObject */ | |||
protected $registrationContext; | |||
protected function setUp(): void { | |||
parent::setUp(); | |||
$this->validator = $this->createMock(IValidator::class); | |||
$this->logger = $this->createMock(ILogger::class); | |||
$this->manager = new Manager($this->validator, $this->logger); | |||
$this->registrationContext = $this->createMock(RegistrationContext::class); | |||
$this->coordinator = $this->createMock(Coordinator::class); | |||
$this->coordinator->method('getRegistrationContext') | |||
->willReturn($this->registrationContext); | |||
$this->manager = new Manager($this->validator, $this->logger, $this->coordinator); | |||
} | |||
public function testRegisterApp() { | |||
@@ -79,6 +93,16 @@ class ManagerTest extends TestCase { | |||
$this->assertCount(2, self::invokePrivate($this->manager, 'getNotifiers')); | |||
} | |||
public function testRegisterNotifierBootstrap() { | |||
$this->registrationContext->method('getNotifierServices') | |||
->willReturn([ | |||
new ServiceRegistration('app', DummyNotifier::class), | |||
]); | |||
$this->assertCount(1, self::invokePrivate($this->manager, 'getNotifiers')); | |||
$this->assertCount(1, self::invokePrivate($this->manager, 'getNotifiers')); | |||
} | |||
public function testRegisterNotifierInvalid() { | |||
$this->manager->registerNotifierService(DummyApp::class); | |||
@@ -105,6 +129,7 @@ class ManagerTest extends TestCase { | |||
->setConstructorArgs([ | |||
$this->validator, | |||
$this->logger, | |||
$this->coordinator, | |||
]) | |||
->setMethods(['getApps']) | |||
->getMock(); | |||
@@ -132,6 +157,7 @@ class ManagerTest extends TestCase { | |||
->setConstructorArgs([ | |||
$this->validator, | |||
$this->logger, | |||
$this->coordinator, | |||
]) | |||
->setMethods(['getApps']) | |||
->getMock(); | |||
@@ -152,6 +178,7 @@ class ManagerTest extends TestCase { | |||
->setConstructorArgs([ | |||
$this->validator, | |||
$this->logger, | |||
$this->coordinator, | |||
]) | |||
->setMethods(['getApps']) | |||
->getMock(); | |||
@@ -173,6 +200,7 @@ class ManagerTest extends TestCase { | |||
->setConstructorArgs([ | |||
$this->validator, | |||
$this->logger, | |||
$this->coordinator, | |||
]) | |||
->setMethods(['getApps']) | |||
->getMock(); |