RegistrationContext.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * @copyright 2020 Christoph Wurst <christoph@winzerhof-wurst.at>
  5. *
  6. * @author Christoph Wurst <christoph@winzerhof-wurst.at>
  7. * @author Joas Schilling <coding@schilljs.com>
  8. * @author Julius Härtl <jus@bitgrid.net>
  9. * @author Roeland Jago Douma <roeland@famdouma.nl>
  10. *
  11. * @license GNU AGPL version 3 or any later version
  12. *
  13. * This program is free software: you can redistribute it and/or modify
  14. * it under the terms of the GNU Affero General Public License as
  15. * published by the Free Software Foundation, either version 3 of the
  16. * License, or (at your option) any later version.
  17. *
  18. * This program is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU Affero General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU Affero General Public License
  24. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  25. *
  26. */
  27. namespace OC\AppFramework\Bootstrap;
  28. use Closure;
  29. use OCP\Calendar\Resource\IBackend as IResourceBackend;
  30. use OCP\Calendar\Room\IBackend as IRoomBackend;
  31. use OCP\Collaboration\Reference\IReferenceProvider;
  32. use OCP\Talk\ITalkBackend;
  33. use RuntimeException;
  34. use function array_shift;
  35. use OC\Support\CrashReport\Registry;
  36. use OCP\AppFramework\App;
  37. use OCP\AppFramework\Bootstrap\IRegistrationContext;
  38. use OCP\AppFramework\Middleware;
  39. use OCP\AppFramework\Services\InitialStateProvider;
  40. use OCP\Authentication\IAlternativeLogin;
  41. use OCP\Calendar\ICalendarProvider;
  42. use OCP\Capabilities\ICapability;
  43. use OCP\Dashboard\IManager;
  44. use OCP\Dashboard\IWidget;
  45. use OCP\EventDispatcher\IEventDispatcher;
  46. use OCP\Files\Template\ICustomTemplateProvider;
  47. use OCP\Http\WellKnown\IHandler;
  48. use OCP\Notification\INotifier;
  49. use OCP\Profile\ILinkAction;
  50. use OCP\Search\IProvider;
  51. use OCP\Support\CrashReport\IReporter;
  52. use OCP\UserMigration\IMigrator as IUserMigrator;
  53. use Psr\Log\LoggerInterface;
  54. use Throwable;
  55. class RegistrationContext {
  56. /** @var ServiceRegistration<ICapability>[] */
  57. private $capabilities = [];
  58. /** @var ServiceRegistration<IReporter>[] */
  59. private $crashReporters = [];
  60. /** @var ServiceRegistration<IWidget>[] */
  61. private $dashboardPanels = [];
  62. /** @var ServiceRegistration<ILinkAction>[] */
  63. private $profileLinkActions = [];
  64. /** @var null|ServiceRegistration<ITalkBackend> */
  65. private $talkBackendRegistration = null;
  66. /** @var ServiceRegistration<IResourceBackend>[] */
  67. private $calendarResourceBackendRegistrations = [];
  68. /** @var ServiceRegistration<IRoomBackend>[] */
  69. private $calendarRoomBackendRegistrations = [];
  70. /** @var ServiceRegistration<IUserMigrator>[] */
  71. private $userMigrators = [];
  72. /** @var ServiceFactoryRegistration[] */
  73. private $services = [];
  74. /** @var ServiceAliasRegistration[] */
  75. private $aliases = [];
  76. /** @var ParameterRegistration[] */
  77. private $parameters = [];
  78. /** @var EventListenerRegistration[] */
  79. private $eventListeners = [];
  80. /** @var ServiceRegistration<Middleware>[] */
  81. private $middlewares = [];
  82. /** @var ServiceRegistration<IProvider>[] */
  83. private $searchProviders = [];
  84. /** @var ServiceRegistration<IAlternativeLogin>[] */
  85. private $alternativeLogins = [];
  86. /** @var ServiceRegistration<InitialStateProvider>[] */
  87. private $initialStates = [];
  88. /** @var ServiceRegistration<IHandler>[] */
  89. private $wellKnownHandlers = [];
  90. /** @var ServiceRegistration<ICustomTemplateProvider>[] */
  91. private $templateProviders = [];
  92. /** @var ServiceRegistration<INotifier>[] */
  93. private $notifierServices = [];
  94. /** @var ServiceRegistration<\OCP\Authentication\TwoFactorAuth\IProvider>[] */
  95. private $twoFactorProviders = [];
  96. /** @var ServiceRegistration<ICalendarProvider>[] */
  97. private $calendarProviders = [];
  98. /** @var ServiceRegistration<IReferenceProvider>[] */
  99. private array $referenceProviders = [];
  100. /** @var ParameterRegistration[] */
  101. private $sensitiveMethods = [];
  102. /** @var LoggerInterface */
  103. private $logger;
  104. /** @var PreviewProviderRegistration[] */
  105. private $previewProviders = [];
  106. public function __construct(LoggerInterface $logger) {
  107. $this->logger = $logger;
  108. }
  109. public function for(string $appId): IRegistrationContext {
  110. return new class($appId, $this) implements IRegistrationContext {
  111. /** @var string */
  112. private $appId;
  113. /** @var RegistrationContext */
  114. private $context;
  115. public function __construct(string $appId, RegistrationContext $context) {
  116. $this->appId = $appId;
  117. $this->context = $context;
  118. }
  119. public function registerCapability(string $capability): void {
  120. $this->context->registerCapability(
  121. $this->appId,
  122. $capability
  123. );
  124. }
  125. public function registerCrashReporter(string $reporterClass): void {
  126. $this->context->registerCrashReporter(
  127. $this->appId,
  128. $reporterClass
  129. );
  130. }
  131. public function registerDashboardWidget(string $widgetClass): void {
  132. $this->context->registerDashboardPanel(
  133. $this->appId,
  134. $widgetClass
  135. );
  136. }
  137. public function registerService(string $name, callable $factory, bool $shared = true): void {
  138. $this->context->registerService(
  139. $this->appId,
  140. $name,
  141. $factory,
  142. $shared
  143. );
  144. }
  145. public function registerServiceAlias(string $alias, string $target): void {
  146. $this->context->registerServiceAlias(
  147. $this->appId,
  148. $alias,
  149. $target
  150. );
  151. }
  152. public function registerParameter(string $name, $value): void {
  153. $this->context->registerParameter(
  154. $this->appId,
  155. $name,
  156. $value
  157. );
  158. }
  159. public function registerEventListener(string $event, string $listener, int $priority = 0): void {
  160. $this->context->registerEventListener(
  161. $this->appId,
  162. $event,
  163. $listener,
  164. $priority
  165. );
  166. }
  167. public function registerMiddleware(string $class): void {
  168. $this->context->registerMiddleware(
  169. $this->appId,
  170. $class
  171. );
  172. }
  173. public function registerSearchProvider(string $class): void {
  174. $this->context->registerSearchProvider(
  175. $this->appId,
  176. $class
  177. );
  178. }
  179. public function registerAlternativeLogin(string $class): void {
  180. $this->context->registerAlternativeLogin(
  181. $this->appId,
  182. $class
  183. );
  184. }
  185. public function registerInitialStateProvider(string $class): void {
  186. $this->context->registerInitialState(
  187. $this->appId,
  188. $class
  189. );
  190. }
  191. public function registerWellKnownHandler(string $class): void {
  192. $this->context->registerWellKnown(
  193. $this->appId,
  194. $class
  195. );
  196. }
  197. public function registerTemplateProvider(string $providerClass): void {
  198. $this->context->registerTemplateProvider(
  199. $this->appId,
  200. $providerClass
  201. );
  202. }
  203. public function registerNotifierService(string $notifierClass): void {
  204. $this->context->registerNotifierService(
  205. $this->appId,
  206. $notifierClass
  207. );
  208. }
  209. public function registerTwoFactorProvider(string $twoFactorProviderClass): void {
  210. $this->context->registerTwoFactorProvider(
  211. $this->appId,
  212. $twoFactorProviderClass
  213. );
  214. }
  215. public function registerPreviewProvider(string $previewProviderClass, string $mimeTypeRegex): void {
  216. $this->context->registerPreviewProvider(
  217. $this->appId,
  218. $previewProviderClass,
  219. $mimeTypeRegex
  220. );
  221. }
  222. public function registerCalendarProvider(string $class): void {
  223. $this->context->registerCalendarProvider(
  224. $this->appId,
  225. $class
  226. );
  227. }
  228. public function registerReferenceProvider(string $class): void {
  229. $this->context->registerReferenceProvider(
  230. $this->appId,
  231. $class
  232. );
  233. }
  234. public function registerProfileLinkAction(string $actionClass): void {
  235. $this->context->registerProfileLinkAction(
  236. $this->appId,
  237. $actionClass
  238. );
  239. }
  240. public function registerTalkBackend(string $backend): void {
  241. $this->context->registerTalkBackend(
  242. $this->appId,
  243. $backend
  244. );
  245. }
  246. public function registerCalendarResourceBackend(string $class): void {
  247. $this->context->registerCalendarResourceBackend(
  248. $this->appId,
  249. $class
  250. );
  251. }
  252. public function registerCalendarRoomBackend(string $class): void {
  253. $this->context->registerCalendarRoomBackend(
  254. $this->appId,
  255. $class
  256. );
  257. }
  258. public function registerUserMigrator(string $migratorClass): void {
  259. $this->context->registerUserMigrator(
  260. $this->appId,
  261. $migratorClass
  262. );
  263. }
  264. public function registerSensitiveMethods(string $class, array $methods): void {
  265. $this->context->registerSensitiveMethods(
  266. $this->appId,
  267. $class,
  268. $methods
  269. );
  270. }
  271. };
  272. }
  273. /**
  274. * @psalm-param class-string<ICapability> $capability
  275. */
  276. public function registerCapability(string $appId, string $capability): void {
  277. $this->capabilities[] = new ServiceRegistration($appId, $capability);
  278. }
  279. /**
  280. * @psalm-param class-string<IReporter> $capability
  281. */
  282. public function registerCrashReporter(string $appId, string $reporterClass): void {
  283. $this->crashReporters[] = new ServiceRegistration($appId, $reporterClass);
  284. }
  285. /**
  286. * @psalm-param class-string<IWidget> $capability
  287. */
  288. public function registerDashboardPanel(string $appId, string $panelClass): void {
  289. $this->dashboardPanels[] = new ServiceRegistration($appId, $panelClass);
  290. }
  291. public function registerService(string $appId, string $name, callable $factory, bool $shared = true): void {
  292. $this->services[] = new ServiceFactoryRegistration($appId, $name, $factory, $shared);
  293. }
  294. public function registerServiceAlias(string $appId, string $alias, string $target): void {
  295. $this->aliases[] = new ServiceAliasRegistration($appId, $alias, $target);
  296. }
  297. public function registerParameter(string $appId, string $name, $value): void {
  298. $this->parameters[] = new ParameterRegistration($appId, $name, $value);
  299. }
  300. public function registerEventListener(string $appId, string $event, string $listener, int $priority = 0): void {
  301. $this->eventListeners[] = new EventListenerRegistration($appId, $event, $listener, $priority);
  302. }
  303. /**
  304. * @psalm-param class-string<Middleware> $class
  305. */
  306. public function registerMiddleware(string $appId, string $class): void {
  307. $this->middlewares[] = new ServiceRegistration($appId, $class);
  308. }
  309. public function registerSearchProvider(string $appId, string $class) {
  310. $this->searchProviders[] = new ServiceRegistration($appId, $class);
  311. }
  312. public function registerAlternativeLogin(string $appId, string $class): void {
  313. $this->alternativeLogins[] = new ServiceRegistration($appId, $class);
  314. }
  315. public function registerInitialState(string $appId, string $class): void {
  316. $this->initialStates[] = new ServiceRegistration($appId, $class);
  317. }
  318. public function registerWellKnown(string $appId, string $class): void {
  319. $this->wellKnownHandlers[] = new ServiceRegistration($appId, $class);
  320. }
  321. public function registerTemplateProvider(string $appId, string $class): void {
  322. $this->templateProviders[] = new ServiceRegistration($appId, $class);
  323. }
  324. public function registerNotifierService(string $appId, string $class): void {
  325. $this->notifierServices[] = new ServiceRegistration($appId, $class);
  326. }
  327. public function registerTwoFactorProvider(string $appId, string $class): void {
  328. $this->twoFactorProviders[] = new ServiceRegistration($appId, $class);
  329. }
  330. public function registerPreviewProvider(string $appId, string $class, string $mimeTypeRegex): void {
  331. $this->previewProviders[] = new PreviewProviderRegistration($appId, $class, $mimeTypeRegex);
  332. }
  333. public function registerCalendarProvider(string $appId, string $class): void {
  334. $this->calendarProviders[] = new ServiceRegistration($appId, $class);
  335. }
  336. public function registerReferenceProvider(string $appId, string $class): void {
  337. $this->referenceProviders[] = new ServiceRegistration($appId, $class);
  338. }
  339. /**
  340. * @psalm-param class-string<ILinkAction> $actionClass
  341. */
  342. public function registerProfileLinkAction(string $appId, string $actionClass): void {
  343. $this->profileLinkActions[] = new ServiceRegistration($appId, $actionClass);
  344. }
  345. /**
  346. * @psalm-param class-string<ITalkBackend> $backend
  347. */
  348. public function registerTalkBackend(string $appId, string $backend) {
  349. // Some safeguards for invalid registrations
  350. if ($appId !== 'spreed') {
  351. throw new RuntimeException("Only the Talk app is allowed to register a Talk backend");
  352. }
  353. if ($this->talkBackendRegistration !== null) {
  354. throw new RuntimeException("There can only be one Talk backend");
  355. }
  356. $this->talkBackendRegistration = new ServiceRegistration($appId, $backend);
  357. }
  358. public function registerCalendarResourceBackend(string $appId, string $class) {
  359. $this->calendarResourceBackendRegistrations[] = new ServiceRegistration(
  360. $appId,
  361. $class,
  362. );
  363. }
  364. public function registerCalendarRoomBackend(string $appId, string $class) {
  365. $this->calendarRoomBackendRegistrations[] = new ServiceRegistration(
  366. $appId,
  367. $class,
  368. );
  369. }
  370. /**
  371. * @psalm-param class-string<IUserMigrator> $migratorClass
  372. */
  373. public function registerUserMigrator(string $appId, string $migratorClass): void {
  374. $this->userMigrators[] = new ServiceRegistration($appId, $migratorClass);
  375. }
  376. public function registerSensitiveMethods(string $appId, string $class, array $methods): void {
  377. $methods = array_filter($methods, 'is_string');
  378. $this->sensitiveMethods[] = new ParameterRegistration($appId, $class, $methods);
  379. }
  380. /**
  381. * @param App[] $apps
  382. */
  383. public function delegateCapabilityRegistrations(array $apps): void {
  384. while (($registration = array_shift($this->capabilities)) !== null) {
  385. $appId = $registration->getAppId();
  386. if (!isset($apps[$appId])) {
  387. // If we land here something really isn't right. But at least we caught the
  388. // notice that is otherwise emitted for the undefined index
  389. $this->logger->error("App $appId not loaded for the capability registration");
  390. continue;
  391. }
  392. try {
  393. $apps[$appId]
  394. ->getContainer()
  395. ->registerCapability($registration->getService());
  396. } catch (Throwable $e) {
  397. $this->logger->error("Error during capability registration of $appId: " . $e->getMessage(), [
  398. 'exception' => $e,
  399. ]);
  400. }
  401. }
  402. }
  403. /**
  404. * @param App[] $apps
  405. */
  406. public function delegateCrashReporterRegistrations(array $apps, Registry $registry): void {
  407. while (($registration = array_shift($this->crashReporters)) !== null) {
  408. try {
  409. $registry->registerLazy($registration->getService());
  410. } catch (Throwable $e) {
  411. $appId = $registration->getAppId();
  412. $this->logger->error("Error during crash reporter registration of $appId: " . $e->getMessage(), [
  413. 'exception' => $e,
  414. ]);
  415. }
  416. }
  417. }
  418. /**
  419. * @param App[] $apps
  420. */
  421. public function delegateDashboardPanelRegistrations(IManager $dashboardManager): void {
  422. while (($panel = array_shift($this->dashboardPanels)) !== null) {
  423. try {
  424. $dashboardManager->lazyRegisterWidget($panel->getService(), $panel->getAppId());
  425. } catch (Throwable $e) {
  426. $appId = $panel->getAppId();
  427. $this->logger->error("Error during dashboard registration of $appId: " . $e->getMessage(), [
  428. 'exception' => $e,
  429. ]);
  430. }
  431. }
  432. }
  433. public function delegateEventListenerRegistrations(IEventDispatcher $eventDispatcher): void {
  434. while (($registration = array_shift($this->eventListeners)) !== null) {
  435. try {
  436. $eventDispatcher->addServiceListener(
  437. $registration->getEvent(),
  438. $registration->getService(),
  439. $registration->getPriority()
  440. );
  441. } catch (Throwable $e) {
  442. $appId = $registration->getAppId();
  443. $this->logger->error("Error during event listener registration of $appId: " . $e->getMessage(), [
  444. 'exception' => $e,
  445. ]);
  446. }
  447. }
  448. }
  449. /**
  450. * @param App[] $apps
  451. */
  452. public function delegateContainerRegistrations(array $apps): void {
  453. while (($registration = array_shift($this->services)) !== null) {
  454. $appId = $registration->getAppId();
  455. if (!isset($apps[$appId])) {
  456. // If we land here something really isn't right. But at least we caught the
  457. // notice that is otherwise emitted for the undefined index
  458. $this->logger->error("App $appId not loaded for the container service registration");
  459. continue;
  460. }
  461. try {
  462. /**
  463. * Register the service and convert the callable into a \Closure if necessary
  464. */
  465. $apps[$appId]
  466. ->getContainer()
  467. ->registerService(
  468. $registration->getName(),
  469. Closure::fromCallable($registration->getFactory()),
  470. $registration->isShared()
  471. );
  472. } catch (Throwable $e) {
  473. $this->logger->error("Error during service registration of $appId: " . $e->getMessage(), [
  474. 'exception' => $e,
  475. ]);
  476. }
  477. }
  478. while (($registration = array_shift($this->aliases)) !== null) {
  479. $appId = $registration->getAppId();
  480. if (!isset($apps[$appId])) {
  481. // If we land here something really isn't right. But at least we caught the
  482. // notice that is otherwise emitted for the undefined index
  483. $this->logger->error("App $appId not loaded for the container alias registration");
  484. continue;
  485. }
  486. try {
  487. $apps[$appId]
  488. ->getContainer()
  489. ->registerAlias(
  490. $registration->getAlias(),
  491. $registration->getTarget()
  492. );
  493. } catch (Throwable $e) {
  494. $this->logger->error("Error during service alias registration of $appId: " . $e->getMessage(), [
  495. 'exception' => $e,
  496. ]);
  497. }
  498. }
  499. while (($registration = array_shift($this->parameters)) !== null) {
  500. $appId = $registration->getAppId();
  501. if (!isset($apps[$appId])) {
  502. // If we land here something really isn't right. But at least we caught the
  503. // notice that is otherwise emitted for the undefined index
  504. $this->logger->error("App $appId not loaded for the container parameter registration");
  505. continue;
  506. }
  507. try {
  508. $apps[$appId]
  509. ->getContainer()
  510. ->registerParameter(
  511. $registration->getName(),
  512. $registration->getValue()
  513. );
  514. } catch (Throwable $e) {
  515. $this->logger->error("Error during service parameter registration of $appId: " . $e->getMessage(), [
  516. 'exception' => $e,
  517. ]);
  518. }
  519. }
  520. }
  521. /**
  522. * @param App[] $apps
  523. */
  524. public function delegateMiddlewareRegistrations(array $apps): void {
  525. while (($middleware = array_shift($this->middlewares)) !== null) {
  526. $appId = $middleware->getAppId();
  527. if (!isset($apps[$appId])) {
  528. // If we land here something really isn't right. But at least we caught the
  529. // notice that is otherwise emitted for the undefined index
  530. $this->logger->error("App $appId not loaded for the container middleware registration");
  531. continue;
  532. }
  533. try {
  534. $apps[$appId]
  535. ->getContainer()
  536. ->registerMiddleWare($middleware->getService());
  537. } catch (Throwable $e) {
  538. $this->logger->error("Error during capability registration of $appId: " . $e->getMessage(), [
  539. 'exception' => $e,
  540. ]);
  541. }
  542. }
  543. }
  544. /**
  545. * @return ServiceRegistration<IProvider>[]
  546. */
  547. public function getSearchProviders(): array {
  548. return $this->searchProviders;
  549. }
  550. /**
  551. * @return ServiceRegistration<IAlternativeLogin>[]
  552. */
  553. public function getAlternativeLogins(): array {
  554. return $this->alternativeLogins;
  555. }
  556. /**
  557. * @return ServiceRegistration<InitialStateProvider>[]
  558. */
  559. public function getInitialStates(): array {
  560. return $this->initialStates;
  561. }
  562. /**
  563. * @return ServiceRegistration<IHandler>[]
  564. */
  565. public function getWellKnownHandlers(): array {
  566. return $this->wellKnownHandlers;
  567. }
  568. /**
  569. * @return ServiceRegistration<ICustomTemplateProvider>[]
  570. */
  571. public function getTemplateProviders(): array {
  572. return $this->templateProviders;
  573. }
  574. /**
  575. * @return ServiceRegistration<INotifier>[]
  576. */
  577. public function getNotifierServices(): array {
  578. return $this->notifierServices;
  579. }
  580. /**
  581. * @return ServiceRegistration<\OCP\Authentication\TwoFactorAuth\IProvider>[]
  582. */
  583. public function getTwoFactorProviders(): array {
  584. return $this->twoFactorProviders;
  585. }
  586. /**
  587. * @return PreviewProviderRegistration[]
  588. */
  589. public function getPreviewProviders(): array {
  590. return $this->previewProviders;
  591. }
  592. /**
  593. * @return ServiceRegistration<ICalendarProvider>[]
  594. */
  595. public function getCalendarProviders(): array {
  596. return $this->calendarProviders;
  597. }
  598. /**
  599. * @return ServiceRegistration<IReferenceProvider>[]
  600. */
  601. public function getReferenceProviders(): array {
  602. return $this->referenceProviders;
  603. }
  604. /**
  605. * @return ServiceRegistration<ILinkAction>[]
  606. */
  607. public function getProfileLinkActions(): array {
  608. return $this->profileLinkActions;
  609. }
  610. /**
  611. * @return ServiceRegistration|null
  612. * @psalm-return ServiceRegistration<ITalkBackend>|null
  613. */
  614. public function getTalkBackendRegistration(): ?ServiceRegistration {
  615. return $this->talkBackendRegistration;
  616. }
  617. /**
  618. * @return ServiceRegistration[]
  619. * @psalm-return ServiceRegistration<IResourceBackend>[]
  620. */
  621. public function getCalendarResourceBackendRegistrations(): array {
  622. return $this->calendarResourceBackendRegistrations;
  623. }
  624. /**
  625. * @return ServiceRegistration[]
  626. * @psalm-return ServiceRegistration<IRoomBackend>[]
  627. */
  628. public function getCalendarRoomBackendRegistrations(): array {
  629. return $this->calendarRoomBackendRegistrations;
  630. }
  631. /**
  632. * @return ServiceRegistration<IUserMigrator>[]
  633. */
  634. public function getUserMigrators(): array {
  635. return $this->userMigrators;
  636. }
  637. /**
  638. * @return ParameterRegistration[]
  639. */
  640. public function getSensitiveMethods(): array {
  641. return $this->sensitiveMethods;
  642. }
  643. }