Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 1 addition & 12 deletions apps/accessibility/lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,7 @@
use OCP\AppFramework\Bootstrap\IBootContext;
use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\AppFramework\Bootstrap\IRegistrationContext;
use OCP\AppFramework\IAppContainer;
use OCP\IConfig;
use OCP\IInitialStateService;
use OCP\IURLGenerator;
use OCP\IUserSession;
use function count;
Expand All @@ -55,11 +53,11 @@ public function __construct() {
}

public function register(IRegistrationContext $context): void {
$context->registerInitialStateProvider(JSDataService::class);
}

public function boot(IBootContext $context): void {
$context->injectFn([$this, 'injectCss']);
$context->injectFn([$this, 'registerInitialState']);
}

public function injectCss(IUserSession $userSession,
Expand All @@ -84,13 +82,4 @@ public function injectCss(IUserSession $userSession,
\OCP\Util::addHeader('link', ['rel' => 'stylesheet', 'media' => '(prefers-color-scheme: dark)', 'href' => $linkToCSS]);
}
}

public function registerInitialState(IInitialStateService $initialState,
IAppContainer $container) {
$initialState->provideLazyInitialState(self::APP_ID, 'data', function () use ($container) {
/** @var JSDataService $data */
$data = $container->query(JSDataService::class);
return $data;
});
}
}
9 changes: 7 additions & 2 deletions apps/accessibility/lib/Service/JSDataService.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@
namespace OCA\Accessibility\Service;

use OCA\Accessibility\AppInfo\Application;
use OCP\AppFramework\Services\InitialStateProvider;
use OCP\IConfig;
use OCP\IUserSession;

class JSDataService implements \JsonSerializable {
class JSDataService extends InitialStateProvider {
/** @var IUserSession */
private $userSession;
/** @var IConfig */
Expand All @@ -44,7 +45,11 @@ public function __construct(
$this->config = $config;
}

public function jsonSerialize() {
public function getKey(): string {
return 'data';
}

public function getData() {
$user = $this->userSession->getUser();

if ($user === null) {
Expand Down
1 change: 1 addition & 0 deletions lib/composer/composer/autoload_classmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
'OCP\\AppFramework\\QueryException' => $baseDir . '/lib/public/AppFramework/QueryException.php',
'OCP\\AppFramework\\Services\\IAppConfig' => $baseDir . '/lib/public/AppFramework/Services/IAppConfig.php',
'OCP\\AppFramework\\Services\\IInitialState' => $baseDir . '/lib/public/AppFramework/Services/IInitialState.php',
'OCP\\AppFramework\\Services\\InitialStateProvider' => $baseDir . '/lib/public/AppFramework/Services/InitialStateProvider.php',
'OCP\\AppFramework\\Utility\\IControllerMethodReflector' => $baseDir . '/lib/public/AppFramework/Utility/IControllerMethodReflector.php',
'OCP\\AppFramework\\Utility\\ITimeFactory' => $baseDir . '/lib/public/AppFramework/Utility/ITimeFactory.php',
'OCP\\App\\AppPathNotFoundException' => $baseDir . '/lib/public/App/AppPathNotFoundException.php',
Expand Down
1 change: 1 addition & 0 deletions lib/composer/composer/autoload_static.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OCP\\AppFramework\\QueryException' => __DIR__ . '/../../..' . '/lib/public/AppFramework/QueryException.php',
'OCP\\AppFramework\\Services\\IAppConfig' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Services/IAppConfig.php',
'OCP\\AppFramework\\Services\\IInitialState' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Services/IInitialState.php',
'OCP\\AppFramework\\Services\\InitialStateProvider' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Services/InitialStateProvider.php',
'OCP\\AppFramework\\Utility\\IControllerMethodReflector' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Utility/IControllerMethodReflector.php',
'OCP\\AppFramework\\Utility\\ITimeFactory' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Utility/ITimeFactory.php',
'OCP\\App\\AppPathNotFoundException' => __DIR__ . '/../../..' . '/lib/public/App/AppPathNotFoundException.php',
Expand Down
24 changes: 24 additions & 0 deletions lib/private/AppFramework/Bootstrap/RegistrationContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ class RegistrationContext {
/** @var array[] */
private $alternativeLogins = [];

/** @var array[] */
private $initialStates = [];

/** @var ILogger */
private $logger;

Expand Down Expand Up @@ -164,6 +167,13 @@ public function registerAlternativeLogin(string $class): void {
$class
);
}

public function registerInitialStateProvider(string $class): void {
$this->context->registerInitialState(
$this->appId,
$class
);
}
};
}

Expand Down Expand Up @@ -243,6 +253,13 @@ public function registerAlternativeLogin(string $appId, string $class): void {
];
}

public function registerInitialState(string $appId, string $class): void {
$this->initialStates[] = [
'appId' => $appId,
'class' => $class,
];
}

/**
* @param App[] $apps
*/
Expand Down Expand Up @@ -413,4 +430,11 @@ public function getSearchProviders(): array {
public function getAlternativeLogins(): array {
return $this->alternativeLogins;
}

/**
* @erturn array[]
*/
public function getInitialStates(): array {
return $this->initialStates;
}
}
51 changes: 50 additions & 1 deletion lib/private/InitialStateService.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,12 @@
namespace OC;

use Closure;
use OC\AppFramework\Bootstrap\Coordinator;
use OCP\AppFramework\QueryException;
use OCP\AppFramework\Services\InitialStateProvider;
use OCP\IInitialStateService;
use OCP\ILogger;
use OCP\IServerContainer;

class InitialStateService implements IInitialStateService {

Expand All @@ -42,8 +46,16 @@ class InitialStateService implements IInitialStateService {
/** @var Closure[][] */
private $lazyStates = [];

public function __construct(ILogger $logger) {
/** @var Coordinator */
private $bootstrapCoordinator;

/** @var IServerContainer */
private $container;

public function __construct(ILogger $logger, Coordinator $bootstrapCoordinator, IServerContainer $container) {
$this->logger = $logger;
$this->bootstrapCoordinator = $bootstrapCoordinator;
$this->container = $container;
}

public function provideInitialState(string $appName, string $key, $data): void {
Expand Down Expand Up @@ -88,8 +100,45 @@ private function invokeLazyStateCallbacks(): void {
$this->lazyStates = [];
}

/**
* Load the lazy states via the IBootstrap mechanism
*/
private function loadLazyStates(): void {
$context = $this->bootstrapCoordinator->getRegistrationContext();

if ($context === null) {
// To early, nothing to do yet
return;
}

$initialStates = $context->getInitialStates();
foreach ($initialStates as $initialState) {
try {
$provider = $this->container->query($initialState['class']);
} catch (QueryException $e) {
// Log an continue. We can be fault tolerant here.
$this->logger->logException($e, [
'message' => 'Could not load initial state provider dynamically: ' . $e->getMessage(),
'level' => ILogger::ERROR,
'app' => $initialState['appId'],
]);
continue;
}

if (!($provider instanceof InitialStateProvider)) {
// Log an continue. We can be fault tolerant here.
$this->logger->error('Initial state provider is not an InitialStateProvider instance: ' . $initialState['class'], [
'app' => $initialState['appId'],
]);
}

$this->provideInitialState($initialState['appId'], $provider->getKey(), $provider);
}
}

public function getInitialStates(): array {
$this->invokeLazyStateCallbacks();
$this->loadLazyStates();

$appStates = [];
foreach ($this->states as $app => $states) {
Expand Down
13 changes: 13 additions & 0 deletions lib/public/AppFramework/Bootstrap/IRegistrationContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -155,4 +155,17 @@ public function registerSearchProvider(string $class): void;
* @since 20.0.0
*/
public function registerAlternativeLogin(string $class): void;

/**
* Register an initialstate provider
*
* It is allowed to register more than one provider per app.
*
* @param string $class
*
* @return void
*
* @since 21.0.0
*/
public function registerInitialStateProvider(string $class): void;
}
49 changes: 49 additions & 0 deletions lib/public/AppFramework/Services/InitialStateProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

declare(strict_types=1);
/**
* @copyright Copyright (c) 2020, Roeland Jago Douma <roeland@famdouma.nl>
*
* @author Roeland Jago Douma <roeland@famdouma.nl>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

namespace OCP\AppFramework\Services;

/**
* @since 21.0.0
*/
abstract class InitialStateProvider implements \JsonSerializable {

/**
* @since 21.0.0
*/
abstract public function getKey(): string;

/**
* @since 21.0.0
*/
abstract public function getData();

/**
* @since 21.0.0
*/
final public function jsonSerialize() {
return $this->getData();
}
}
4 changes: 4 additions & 0 deletions lib/public/IInitialStateService.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ interface IInitialStateService {
* @param string $appName
* @param string $key
* @param bool|int|float|string|array|\JsonSerializable $data
*
* @deprecated 21 Use OCP\AppFramework\Services\IInitialState or OCP\AppFramework\Services\InitialStateProvider
*/
public function provideInitialState(string $appName, string $key, $data): void;

Expand All @@ -58,6 +60,8 @@ public function provideInitialState(string $appName, string $key, $data): void;
* @param string $appName
* @param string $key
* @param Closure $closure returns a primitive or an object that implements JsonSerializable
*
* @deprecated 21 Use OCP\AppFramework\Services\IInitialState or OCP\AppFramework\Services\InitialStateProvider
*/
public function provideLazyInitialState(string $appName, string $key, Closure $closure): void;
}
6 changes: 5 additions & 1 deletion tests/lib/InitialStateServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@

namespace Test;

use OC\AppFramework\Bootstrap\Coordinator;
use OCP\IServerContainer;
use function json_encode;
use JsonSerializable;
use OC\InitialStateService;
Expand All @@ -40,7 +42,9 @@ protected function setUp(): void {
parent::setUp();

$this->service = new InitialStateService(
$this->createMock(ILogger::class)
$this->createMock(ILogger::class),
$this->createMock(Coordinator::class),
$this->createMock(IServerContainer::class)
);
}

Expand Down