-Subproject commit 8460f552fbf8ee468734225fa6a890cde4beb964
+Subproject commit 10acc20198442f3c04bc1abbf9ad540a3afbab40
use OCP\ISession;
use OCP\IURLGenerator;
use OCP\IUserSession;
+use Psr\Container\ContainerInterface;
+/**
+ * @deprecated 20.0.0
+ */
class DIContainer extends SimpleContainer implements IAppContainer {
/**
return $this->getServer()->getUserFolder();
});
- $this->registerService(IAppData::class, function (SimpleContainer $c) {
- return $this->getServer()->getAppDataDir($c->query('AppName'));
+ $this->registerService(IAppData::class, function (ContainerInterface $c) {
+ return $this->getServer()->getAppDataDir($c->get('AppName'));
});
- $this->registerService(IL10N::class, function ($c) {
- return $this->getServer()->getL10N($c->query('AppName'));
+ $this->registerService(IL10N::class, function (ContainerInterface $c) {
+ return $this->getServer()->getL10N($c->get('AppName'));
});
// Log wrapper
- $this->registerService(ILogger::class, function ($c) {
- return new OC\AppFramework\Logger($this->server->query(ILogger::class), $c->query('AppName'));
+ $this->registerService(ILogger::class, function (ContainerInterface $c) {
+ return new OC\AppFramework\Logger($this->server->query(ILogger::class), $c->get('AppName'));
});
$this->registerService(IServerContainer::class, function () {
});
$this->registerAlias('ServerContainer', IServerContainer::class);
- $this->registerService(\OCP\WorkflowEngine\IManager::class, function ($c) {
- return $c->query(Manager::class);
+ $this->registerService(\OCP\WorkflowEngine\IManager::class, function (ContainerInterface $c) {
+ return $c->get(Manager::class);
});
- $this->registerService(\OCP\AppFramework\IAppContainer::class, function ($c) {
+ $this->registerService(ContainerInterface::class, function (ContainerInterface $c) {
return $c;
});
+ $this->registerAlias(IAppContainer::class, ContainerInterface::class);
// commonly used attributes
- $this->registerService('UserId', function ($c) {
- return $c->query(IUserSession::class)->getSession()->get('user_id');
+ $this->registerService('UserId', function (ContainerInterface $c) {
+ return $c->get(IUserSession::class)->getSession()->get('user_id');
});
- $this->registerService('WebRoot', function ($c) {
- return $c->query('ServerContainer')->getWebRoot();
+ $this->registerService('WebRoot', function (ContainerInterface $c) {
+ return $c->get(IServerContainer::class)->getWebRoot();
});
- $this->registerService('OC_Defaults', function ($c) {
- return $c->getServer()->getThemingDefaults();
+ $this->registerService('OC_Defaults', function (ContainerInterface $c) {
+ return $c->get(IServerContainer::class)->getThemingDefaults();
});
- $this->registerService('Protocol', function ($c) {
+ $this->registerService('Protocol', function (ContainerInterface $c) {
/** @var \OC\Server $server */
- $server = $c->query('ServerContainer');
+ $server = $c->get(IServerContainer::class);
$protocol = $server->getRequest()->getHttpProtocol();
return new Http($_SERVER, $protocol);
});
- $this->registerService('Dispatcher', function ($c) {
+ $this->registerService('Dispatcher', function (ContainerInterface $c) {
return new Dispatcher(
- $c['Protocol'],
- $c['MiddlewareDispatcher'],
- $c->query(IControllerMethodReflector::class),
- $c['Request']
+ $c->get('Protocol'),
+ $c->get(MiddlewareDispatcher::class),
+ $c->get(IControllerMethodReflector::class),
+ $c->get(IRequest::class)
);
});
/**
* Middleware
*/
- $this->registerService('MiddlewareDispatcher', function (SimpleContainer $c) {
- $server = $this->getServer();
+ $this->registerAlias('MiddlewareDispatcher', MiddlewareDispatcher::class);
+ $this->registerService(MiddlewareDispatcher::class, function (ContainerInterface $c) {
+ $server = $this->getServer();
$dispatcher = new MiddlewareDispatcher();
$dispatcher->registerMiddleware(
- $c->query(OC\AppFramework\Middleware\CompressionMiddleware::class)
+ $c->get(OC\AppFramework\Middleware\CompressionMiddleware::class)
);
- $dispatcher->registerMiddleware($c->query(OC\AppFramework\Middleware\NotModifiedMiddleware::class));
+ $dispatcher->registerMiddleware($c->get(OC\AppFramework\Middleware\NotModifiedMiddleware::class));
$dispatcher->registerMiddleware(
- $c->query(OC\AppFramework\Middleware\Security\ReloadExecutionMiddleware::class)
+ $c->get(OC\AppFramework\Middleware\Security\ReloadExecutionMiddleware::class)
);
$dispatcher->registerMiddleware(
new OC\AppFramework\Middleware\Security\SameSiteCookieMiddleware(
- $c->query(IRequest::class),
- $c->query(IControllerMethodReflector::class)
+ $c->get(IRequest::class),
+ $c->get(IControllerMethodReflector::class)
)
);
$dispatcher->registerMiddleware(
new CORSMiddleware(
- $c->query(IRequest::class),
- $c->query(IControllerMethodReflector::class),
- $c->query(IUserSession::class),
- $c->query(OC\Security\Bruteforce\Throttler::class)
+ $c->get(IRequest::class),
+ $c->get(IControllerMethodReflector::class),
+ $c->get(IUserSession::class),
+ $c->get(OC\Security\Bruteforce\Throttler::class)
)
);
$dispatcher->registerMiddleware(
new OCSMiddleware(
- $c->query(IRequest::class)
+ $c->get(IRequest::class)
)
);
$securityMiddleware = new SecurityMiddleware(
- $c->query(IRequest::class),
- $c->query(IControllerMethodReflector::class),
- $c->query(INavigationManager::class),
- $c->query(IURLGenerator::class),
- $server->getLogger(),
- $c['AppName'],
+ $c->get(IRequest::class),
+ $c->get(IControllerMethodReflector::class),
+ $c->get(INavigationManager::class),
+ $c->get(IURLGenerator::class),
+ $server->query(ILogger::class),
+ $c->get('AppName'),
$server->getUserSession()->isLoggedIn(),
$server->getGroupManager()->isAdmin($this->getUserId()),
$server->getUserSession()->getUser() !== null && $server->query(ISubAdmin::class)->isSubAdmin($server->getUserSession()->getUser()),
);
$dispatcher->registerMiddleware(
new OC\AppFramework\Middleware\Security\PasswordConfirmationMiddleware(
- $c->query(IControllerMethodReflector::class),
- $c->query(ISession::class),
- $c->query(IUserSession::class),
- $c->query(ITimeFactory::class)
+ $c->get(IControllerMethodReflector::class),
+ $c->get(ISession::class),
+ $c->get(IUserSession::class),
+ $c->get(ITimeFactory::class)
)
);
$dispatcher->registerMiddleware(
new TwoFactorMiddleware(
- $c->query(OC\Authentication\TwoFactorAuth\Manager::class),
- $c->query(IUserSession::class),
- $c->query(ISession::class),
- $c->query(IURLGenerator::class),
- $c->query(IControllerMethodReflector::class),
- $c->query(IRequest::class)
+ $c->get(OC\Authentication\TwoFactorAuth\Manager::class),
+ $c->get(IUserSession::class),
+ $c->get(ISession::class),
+ $c->get(IURLGenerator::class),
+ $c->get(IControllerMethodReflector::class),
+ $c->get(IRequest::class)
)
);
$dispatcher->registerMiddleware(
new OC\AppFramework\Middleware\Security\BruteForceMiddleware(
- $c->query(IControllerMethodReflector::class),
- $c->query(OC\Security\Bruteforce\Throttler::class),
- $c->query(IRequest::class)
+ $c->get(IControllerMethodReflector::class),
+ $c->get(OC\Security\Bruteforce\Throttler::class),
+ $c->get(IRequest::class)
)
);
$dispatcher->registerMiddleware(
new RateLimitingMiddleware(
- $c->query(IRequest::class),
- $c->query(IUserSession::class),
- $c->query(IControllerMethodReflector::class),
- $c->query(OC\Security\RateLimiting\Limiter::class)
+ $c->get(IRequest::class),
+ $c->get(IUserSession::class),
+ $c->get(IControllerMethodReflector::class),
+ $c->get(OC\Security\RateLimiting\Limiter::class)
)
);
$dispatcher->registerMiddleware(
new OC\AppFramework\Middleware\PublicShare\PublicShareMiddleware(
- $c->query(IRequest::class),
- $c->query(ISession::class),
- $c->query(\OCP\IConfig::class)
+ $c->get(IRequest::class),
+ $c->get(ISession::class),
+ $c->get(\OCP\IConfig::class)
)
);
$dispatcher->registerMiddleware(
- $c->query(\OC\AppFramework\Middleware\AdditionalScriptsMiddleware::class)
+ $c->get(\OC\AppFramework\Middleware\AdditionalScriptsMiddleware::class)
);
foreach ($this->middleWares as $middleWare) {
- $dispatcher->registerMiddleware($c->query($middleWare));
+ $dispatcher->registerMiddleware($c->get($middleWare));
}
$dispatcher->registerMiddleware(
new SessionMiddleware(
- $c->query(IControllerMethodReflector::class),
- $c->query(ISession::class)
+ $c->get(IControllerMethodReflector::class),
+ $c->get(ISession::class)
)
);
return $dispatcher;
});
- $this->registerService(IAppConfig::class, function (SimpleContainer $c) {
+ $this->registerService(IAppConfig::class, function (ContainerInterface $c) {
return new OC\AppFramework\Services\AppConfig(
- $c->query(IConfig::class),
- $c->query('AppName')
+ $c->get(IConfig::class),
+ $c->get('AppName')
);
});
- $this->registerService(IInitialState::class, function (SimpleContainer $c) {
+ $this->registerService(IInitialState::class, function (ContainerInterface $c) {
return new OC\AppFramework\Services\InitialState(
- $c->query(IInitialStateService::class),
- $c->query('AppName')
+ $c->get(IInitialStateService::class),
+ $c->get('AppName')
);
});
}
});
}
+ public function has($id): bool {
+ if (parent::has($id)) {
+ return true;
+ }
+
+ if ($this->server->has($id, true)) {
+ return true;
+ }
+
+ return false;
+ }
+
public function query(string $name, bool $autoload = true) {
try {
return $this->queryNoFallback($name);
if ($this->offsetExists($name)) {
return parent::query($name);
- } else {
- if ($this['AppName'] === 'settings' && strpos($name, 'OC\\Settings\\') === 0) {
- return parent::query($name);
- } elseif ($this['AppName'] === 'core' && strpos($name, 'OC\\Core\\') === 0) {
- return parent::query($name);
- } elseif (strpos($name, \OC\AppFramework\App::buildAppNamespace($this['AppName']) . '\\') === 0) {
- return parent::query($name);
- }
+ } elseif ($this['AppName'] === 'settings' && strpos($name, 'OC\\Settings\\') === 0) {
+ return parent::query($name);
+ } elseif ($this['AppName'] === 'core' && strpos($name, 'OC\\Core\\') === 0) {
+ return parent::query($name);
+ } elseif (strpos($name, \OC\AppFramework\App::buildAppNamespace($this['AppName']) . '\\') === 0) {
+ return parent::query($name);
}
throw new QueryException('Could not resolve ' . $name . '!' .
namespace OC\AppFramework\Utility;
+use ArrayAccess;
use Closure;
use OCP\AppFramework\QueryException;
use OCP\IContainer;
use Pimple\Container;
+use Psr\Container\ContainerInterface;
use ReflectionClass;
use ReflectionException;
+use ReflectionParameter;
+use function class_exists;
/**
- * Class SimpleContainer
- *
- * SimpleContainer is a simple implementation of IContainer on basis of Pimple
+ * SimpleContainer is a simple implementation of a container on basis of Pimple
*/
-class SimpleContainer extends Container implements IContainer {
+class SimpleContainer implements ArrayAccess, ContainerInterface, IContainer {
+
+ /** @var Container */
+ private $container;
+
+ public function __construct() {
+ $this->container = new Container();
+ }
+
+ public function get($id) {
+ return $this->query($id);
+ }
+ public function has($id): bool {
+ // If a service is no registered but is an existing class, we can probably load it
+ return isset($this->container[$id]) || class_exists($id);
+ }
/**
* @param ReflectionClass $class the class to instantiate
$constructor = $class->getConstructor();
if ($constructor === null) {
return $class->newInstance();
- } else {
- $parameters = [];
- foreach ($constructor->getParameters() as $parameter) {
- $parameterClass = $parameter->getClass();
+ }
- // try to find out if it is a class or a simple parameter
- if ($parameterClass === null) {
- $resolveName = $parameter->getName();
- } else {
- $resolveName = $parameterClass->name;
+ return $class->newInstanceArgs(array_map(function (ReflectionParameter $parameter) {
+ $parameterClass = $parameter->getClass();
+
+ // try to find out if it is a class or a simple parameter
+ if ($parameterClass === null) {
+ $resolveName = $parameter->getName();
+ } else {
+ $resolveName = $parameterClass->name;
+ }
+
+ try {
+ $builtIn = $parameter->hasType() && $parameter->getType()->isBuiltin();
+ return $this->query($resolveName, !$builtIn);
+ } catch (QueryException $e) {
+ // Service not found, use the default value when available
+ if ($parameter->isDefaultValueAvailable()) {
+ return $parameter->getDefaultValue();
}
- try {
- $builtIn = $parameter->hasType() && $parameter->getType()->isBuiltin();
- $parameters[] = $this->query($resolveName, !$builtIn);
- } catch (QueryException $e) {
- // Service not found, use the default value when available
- if ($parameter->isDefaultValueAvailable()) {
- $parameters[] = $parameter->getDefaultValue();
- } elseif ($parameterClass !== null) {
- $resolveName = $parameter->getName();
- $parameters[] = $this->query($resolveName);
- } else {
- throw $e;
- }
+ if ($parameterClass !== null) {
+ $resolveName = $parameter->getName();
+ return $this->query($resolveName);
}
+
+ throw $e;
}
- return $class->newInstanceArgs($parameters);
- }
+ }, $constructor->getParameters()));
}
-
- /**
- * If a parameter is not registered in the container try to instantiate it
- * by using reflection to find out how to build the class
- * @param string $name the class name to resolve
- * @return \stdClass
- * @throws QueryException if the class could not be found or instantiated
- */
public function resolve($name) {
$baseMsg = 'Could not resolve ' . $name . '!';
try {
public function query(string $name, bool $autoload = true) {
$name = $this->sanitizeName($name);
- if ($this->offsetExists($name)) {
- return $this->offsetGet($name);
- } elseif ($autoload) {
+ if (isset($this->container[$name])) {
+ return $this->container[$name];
+ }
+
+ if ($autoload) {
$object = $this->resolve($name);
$this->registerService($name, function () use ($object) {
return $object;
});
return $object;
}
+
throw new QueryException('Could not resolve ' . $name . '!');
}
* @param bool $shared
*/
public function registerService($name, Closure $closure, $shared = true) {
+ $wrapped = function () use ($closure) {
+ return $closure($this);
+ };
$name = $this->sanitizeName($name);
if (isset($this[$name])) {
unset($this[$name]);
}
if ($shared) {
- $this[$name] = $closure;
+ $this[$name] = $wrapped;
} else {
- $this[$name] = parent::factory($closure);
+ $this[$name] = $this->container->factory($wrapped);
}
}
* @param string $target the target that should be resolved instead
*/
public function registerAlias($alias, $target) {
- $this->registerService($alias, function (IContainer $container) use ($target) {
- return $container->query($target);
+ $this->registerService($alias, function (ContainerInterface $container) use ($target) {
+ return $container->get($target);
}, false);
}
}
return $name;
}
+
+ /**
+ * @deprecated 20.0.0 use \Psr\Container\ContainerInterface::has
+ */
+ public function offsetExists($id) {
+ return $this->container->offsetExists($id);
+ }
+
+ /**
+ * @deprecated 20.0.0 use \Psr\Container\ContainerInterface::get
+ */
+ public function offsetGet($id) {
+ return $this->container->offsetGet($id);
+ }
+
+ /**
+ * @deprecated 20.0.0 use \OCP\IContainer::registerService
+ */
+ public function offsetSet($id, $service) {
+ $this->container->offsetSet($id, $service);
+ }
+
+ /**
+ * @deprecated 20.0.0
+ */
+ public function offsetUnset($offset) {
+ $this->container->offsetUnset($offset);
+ }
}
use OCA\Theming\Util;
use OCP\Accounts\IAccountManager;
use OCP\App\IAppManager;
-use OCP\AppFramework\QueryException;
use OCP\Authentication\LoginCredentials\IStore;
use OCP\BackgroundJob\IJobList;
use OCP\Collaboration\AutoComplete\IManager;
use OCP\IAvatarManager;
use OCP\ICache;
use OCP\ICacheFactory;
-use OCP\IContainer;
use OCP\IDateTimeFormatter;
use OCP\IDateTimeZone;
use OCP\IDBConnection;
use OCP\User\Events\UserLoggedInEvent;
use OCP\User\Events\UserLoggedInWithCookieEvent;
use OCP\User\Events\UserLoggedOutEvent;
+use Psr\Container\ContainerExceptionInterface;
+use Psr\Container\ContainerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\GenericEvent;
* TODO: hookup all manager classes
*/
class Server extends ServerContainer implements IServerContainer {
+
/** @var string */
private $webRoot;
// To find out if we are running from CLI or not
$this->registerParameter('isCLI', \OC::$CLI);
- $this->registerService(\OCP\IServerContainer::class, function (IServerContainer $c) {
+ $this->registerService(ContainerInterface::class, function (ContainerInterface $c) {
+ return $c;
+ });
+ $this->registerService(\OCP\IServerContainer::class, function (ContainerInterface $c) {
return $c;
});
}
private function registerDeprecatedAlias(string $alias, string $target) {
- $this->registerService($alias, function (IContainer $container) use ($target, $alias) {
+ $this->registerService($alias, function (ContainerInterface $container) use ($target, $alias) {
try {
/** @var ILogger $logger */
- $logger = $container->query(ILogger::class);
+ $logger = $container->get(ILogger::class);
$logger->debug('The requested alias "' . $alias . '" is depreacted. Please request "' . $target . '" directly. This alias will be removed in a future Nextcloud version.', ['app' => 'serverDI']);
- } catch (QueryException $e) {
+ } catch (ContainerExceptionInterface $e) {
// Could not get logger. Continue
}
- return $container->query($target);
+ return $container->get($target);
}, false);
}
}
use OC\AppFramework\DependencyInjection\DIContainer;
use OC\AppFramework\Utility\SimpleContainer;
use OCP\AppFramework\QueryException;
+use function explode;
+use function strtolower;
/**
* Class ServerContainer
throw new QueryException();
}
+ public function has($id, bool $noRecursion = false): bool {
+ if (!$noRecursion && ($appContainer = $this->getAppContainerForService($id)) !== null) {
+ return $appContainer->has($id);
+ }
+
+ return parent::has($id);
+ }
+
public function query(string $name, bool $autoload = true) {
$name = $this->sanitizeName($name);
- if (isset($this[$name])) {
- return $this[$name];
- }
-
// In case the service starts with OCA\ we try to find the service in
// the apps container first.
- if (strpos($name, 'OCA\\') === 0 && substr_count($name, '\\') >= 2) {
- $segments = explode('\\', $name);
+ if (($appContainer = $this->getAppContainerForService($name)) !== null) {
try {
- $appContainer = $this->getAppContainer(strtolower($segments[1]), $segments[1]);
return $appContainer->queryNoFallback($name);
} catch (QueryException $e) {
// Didn't find the service or the respective app container,
return parent::query($name, $autoload);
}
+
+ private function getAppContainerForService(string $id): ?DIContainer {
+ if (strpos($id, 'OCA\\') !== 0 || substr_count($id, '\\') < 2) {
+ return null;
+ }
+
+ try {
+ [,$namespace,] = explode('\\', $id);
+ return $this->getAppContainer(strtolower($namespace), $namespace);
+ } catch (QueryException $e) {
+ return null;
+ }
+ }
}
namespace OCP\AppFramework\Bootstrap;
use OCP\AppFramework\IAppContainer;
-use OCP\AppFramework\QueryException;
use OCP\IServerContainer;
+use Psr\Container\ContainerExceptionInterface;
+use Psr\Container\ContainerInterface;
use Throwable;
/**
*
* Useful to register and query app-specific services
*
- * @return IAppContainer
+ * @return IAppContainer|ContainerInterface
* @since 20.0.0
*/
public function getAppContainer(): IAppContainer;
* Note: the app container will be queried
*
* @param callable $fn
- * @throws QueryException if at least one of the parameter can't be resolved
+ * @throws ContainerExceptionInterface if at least one of the parameter can't be resolved
* @throws Throwable any error the function invocation might cause
* @return mixed|null the return value of the invoked function, if any
* @since 20.0.0
*
* This container interface provides short cuts for app developers to access predefined app service.
* @since 6.0.0
+ * @deprecated 20.0.0 use \Psr\Container\ContainerInterface
*/
interface IAppContainer extends IContainer {
* used to return the appname of the set application
* @return string the name of your application
* @since 6.0.0
+ * @deprecated 20.0.0
*/
public function getAppName();
/**
* @return \OCP\IServerContainer
* @since 6.0.0
+ * @deprecated 20.0.0
*/
public function getServer();
* @param string $middleWare
* @return boolean
* @since 6.0.0
+ * @deprecated 20.0.0 use \OCP\AppFramework\Bootstrap\IRegistrationContext::registerMiddleware
*/
public function registerMiddleWare($middleWare);
*
* @param string $serviceName e.g. 'OCA\Files\Capabilities'
* @since 8.2.0
+ * @deprecated 20.0.0 use \OCP\AppFramework\Bootstrap\IRegistrationContext::registerCapability
*/
public function registerCapability($serviceName);
}
<?php
+
+declare(strict_types=1);
+
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
namespace OCP\AppFramework;
use Exception;
+use Psr\Container\ContainerExceptionInterface;
/**
* Class QueryException
*
+ * The class extends `NotFoundExceptionInterface` since 20.0.0
+ *
* @package OCP\AppFramework
* @since 8.1.0
+ * @deprecated 20.0.0 catch \Psr\Container\ContainerExceptionInterface
*/
-class QueryException extends Exception {
+class QueryException extends Exception implements ContainerExceptionInterface {
}
use Closure;
use OCP\AppFramework\QueryException;
+use Psr\Container\ContainerExceptionInterface;
+use Psr\Container\ContainerInterface;
/**
* Class IContainer
*
* @package OCP
* @since 6.0.0
+ * @deprecated 20.0.0 use \Psr\Container\ContainerInterface
*/
-interface IContainer {
+interface IContainer extends ContainerInterface {
/**
* If a parameter is not registered in the container try to instantiate it
* @param string $name the class name to resolve
* @return \stdClass
* @since 8.2.0
+ * @deprecated 20.0.0 use \Psr\Container\ContainerInterface::get
+ * @throws ContainerExceptionInterface if the class could not be found or instantiated
* @throws QueryException if the class could not be found or instantiated
*/
public function resolve($name);
* @param string $name
* @param bool $autoload Should we try to autoload the service. If we are trying to resolve built in types this makes no sense for example
* @return mixed
+ * @throws ContainerExceptionInterface if the query could not be resolved
* @throws QueryException if the query could not be resolved
* @since 6.0.0
+ * @deprecated 20.0.0 use \Psr\Container\ContainerInterface::get
*/
public function query(string $name, bool $autoload = true);
* @param mixed $value
* @return void
* @since 6.0.0
+ * @deprecated 20.0.0 use \OCP\AppFramework\Bootstrap\IRegistrationContext::registerParameter
*/
public function registerParameter($name, $value);
* @param bool $shared
* @return void
* @since 6.0.0
+ * @deprecated 20.0.0 use \OCP\AppFramework\Bootstrap\IRegistrationContext::registerService
*/
public function registerService($name, Closure $closure, $shared = true);
* @param string $alias the alias that should be registered
* @param string $target the target that should be resolved instead
* @since 8.2.0
+ * @deprecated 20.0.0 use \OCP\AppFramework\Bootstrap\IRegistrationContext::registerServiceAlias
*/
public function registerAlias($alias, $target);
}
*
* This container holds all ownCloud services
* @since 6.0.0
+ * @deprecated 20.0.0 use \Psr\Container\ContainerInterface
*/
interface IServerContainer extends IContainer {