diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index ecdad37ef0..3015bb58ad 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -5,36 +5,6 @@ parameters: count: 1 path: src/bundle/Core/ApiLoader/CacheFactory.php - - - message: "#^Method Ibexa\\\\Bundle\\\\Core\\\\ApiLoader\\\\RepositoryConfigurationProvider\\:\\:__construct\\(\\) has parameter \\$repositories with no value type specified in iterable type array\\.$#" - count: 1 - path: src/bundle/Core/ApiLoader/RepositoryConfigurationProvider.php - - - - message: "#^Method Ibexa\\\\Bundle\\\\Core\\\\ApiLoader\\\\RepositoryConfigurationProvider\\:\\:getDefaultRepositoryAlias\\(\\) should return string\\|null but returns int\\|string\\|null\\.$#" - count: 1 - path: src/bundle/Core/ApiLoader/RepositoryConfigurationProvider.php - - - - message: "#^Method Ibexa\\\\Bundle\\\\Core\\\\ApiLoader\\\\RepositoryConfigurationProvider\\:\\:getRepositoryConfig\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/bundle/Core/ApiLoader/RepositoryConfigurationProvider.php - - - - message: "#^Property Ibexa\\\\Bundle\\\\Core\\\\ApiLoader\\\\RepositoryConfigurationProvider\\:\\:\\$repositories type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/bundle/Core/ApiLoader/RepositoryConfigurationProvider.php - - - - message: "#^Cannot call method get\\(\\) on Symfony\\\\Component\\\\DependencyInjection\\\\ContainerInterface\\|null\\.$#" - count: 1 - path: src/bundle/Core/ApiLoader/RepositoryFactory.php - - - - message: "#^Cannot call method getRepositoryConfig\\(\\) on object\\|null\\.$#" - count: 1 - path: src/bundle/Core/ApiLoader/RepositoryFactory.php - - message: "#^Method Ibexa\\\\Bundle\\\\Core\\\\ApiLoader\\\\RepositoryFactory\\:\\:__construct\\(\\) has parameter \\$policyMap with no value type specified in iterable type array\\.$#" count: 1 @@ -65,36 +35,6 @@ parameters: count: 1 path: src/bundle/Core/ApiLoader/SearchEngineIndexerFactory.php - - - message: "#^Cannot call method get\\(\\) on Symfony\\\\Component\\\\DependencyInjection\\\\ContainerInterface\\|null\\.$#" - count: 1 - path: src/bundle/Core/ApiLoader/StorageConnectionFactory.php - - - - message: "#^Cannot call method getParameter\\(\\) on Symfony\\\\Component\\\\DependencyInjection\\\\ContainerInterface\\|null\\.$#" - count: 1 - path: src/bundle/Core/ApiLoader/StorageConnectionFactory.php - - - - message: "#^Cannot call method has\\(\\) on Symfony\\\\Component\\\\DependencyInjection\\\\ContainerInterface\\|null\\.$#" - count: 1 - path: src/bundle/Core/ApiLoader/StorageConnectionFactory.php - - - - message: "#^Method Ibexa\\\\Bundle\\\\Core\\\\ApiLoader\\\\StorageConnectionFactory\\:\\:getConnection\\(\\) should return Doctrine\\\\DBAL\\\\Connection but returns object\\|null\\.$#" - count: 1 - path: src/bundle/Core/ApiLoader/StorageConnectionFactory.php - - - - message: "#^Parameter \\#1 \\$array of function array_keys expects array, array\\|bool\\|float\\|int\\|string\\|null given\\.$#" - count: 1 - path: src/bundle/Core/ApiLoader/StorageConnectionFactory.php - - - - message: "#^Method Ibexa\\\\Bundle\\\\Core\\\\ApiLoader\\\\StorageEngineFactory\\:\\:registerStorageEngine\\(\\) has no return type specified\\.$#" - count: 1 - path: src/bundle/Core/ApiLoader/StorageEngineFactory.php - - message: "#^Method Ibexa\\\\Bundle\\\\Core\\\\Cache\\\\Warmer\\\\ProxyCacheWarmer\\:\\:warmUp\\(\\) has parameter \\$cacheDir with no type specified\\.$#" count: 1 @@ -110,11 +50,6 @@ parameters: count: 1 path: src/bundle/Core/Command/CheckURLsCommand.php - - - message: "#^Call to an undefined method Doctrine\\\\DBAL\\\\Driver\\\\Connection\\:\\:createQueryBuilder\\(\\)\\.$#" - count: 1 - path: src/bundle/Core/Command/CleanupVersionsCommand.php - - message: "#^Method Ibexa\\\\Bundle\\\\Core\\\\Command\\\\CleanupVersionsCommand\\:\\:configure\\(\\) has no return type specified\\.$#" count: 1 @@ -10840,11 +10775,6 @@ parameters: count: 1 path: src/lib/Helper/FieldsGroups/FieldsGroupsList.php - - - message: "#^Method Ibexa\\\\Core\\\\Helper\\\\FieldsGroups\\\\RepositoryConfigFieldsGroupsListFactory\\:\\:build\\(\\) has no return type specified\\.$#" - count: 1 - path: src/lib/Helper/FieldsGroups/RepositoryConfigFieldsGroupsListFactory.php - - message: "#^Method Ibexa\\\\Core\\\\Helper\\\\TranslationHelper\\:\\:__construct\\(\\) has parameter \\$siteAccessesByLanguage with no value type specified in iterable type array\\.$#" count: 1 @@ -19721,7 +19651,7 @@ parameters: path: src/lib/Persistence/Utf8Converter.php - - message: "#^Method Ibexa\\\\Core\\\\Persistence\\\\Utf8Converter\\:\\:toUnicodeCodepoint\\(\\) should return int but returns int\\<0, max\\>\\|false\\.$#" + message: "#^Method Ibexa\\\\Core\\\\Persistence\\\\Utf8Converter\\:\\:toUnicodeCodepoint\\(\\) should return int but returns int\\<0, 2147483647\\>\\|false\\.$#" count: 1 path: src/lib/Persistence/Utf8Converter.php @@ -23200,96 +23130,6 @@ parameters: count: 1 path: tests/bundle/Core/ApiLoader/CacheFactoryTest.php - - - message: "#^Method Ibexa\\\\Tests\\\\Bundle\\\\Core\\\\ApiLoader\\\\RepositoryConfigurationProviderTest\\:\\:providerForRepositories\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: tests/bundle/Core/ApiLoader/RepositoryConfigurationProviderTest.php - - - - message: "#^Method Ibexa\\\\Tests\\\\Bundle\\\\Core\\\\ApiLoader\\\\RepositoryConfigurationProviderTest\\:\\:testGetCurrentRepositoryAlias\\(\\) has parameter \\$repositories with no value type specified in iterable type array\\.$#" - count: 1 - path: tests/bundle/Core/ApiLoader/RepositoryConfigurationProviderTest.php - - - - message: "#^Method Ibexa\\\\Tests\\\\Bundle\\\\Core\\\\ApiLoader\\\\RepositoryConfigurationProviderTest\\:\\:testGetDefaultRepositoryAlias\\(\\) has parameter \\$repositories with no value type specified in iterable type array\\.$#" - count: 1 - path: tests/bundle/Core/ApiLoader/RepositoryConfigurationProviderTest.php - - - - message: "#^Method Ibexa\\\\Tests\\\\Bundle\\\\Core\\\\ApiLoader\\\\RepositoryConfigurationProviderTest\\:\\:testGetRepositoryConfigNotSpecifiedRepository\\(\\) has no return type specified\\.$#" - count: 1 - path: tests/bundle/Core/ApiLoader/RepositoryConfigurationProviderTest.php - - - - message: "#^Method Ibexa\\\\Tests\\\\Bundle\\\\Core\\\\ApiLoader\\\\RepositoryConfigurationProviderTest\\:\\:testGetRepositoryConfigSpecifiedRepository\\(\\) has no return type specified\\.$#" - count: 1 - path: tests/bundle/Core/ApiLoader/RepositoryConfigurationProviderTest.php - - - - message: "#^Method Ibexa\\\\Tests\\\\Bundle\\\\Core\\\\ApiLoader\\\\RepositoryConfigurationProviderTest\\:\\:testGetRepositoryConfigUndefinedRepository\\(\\) has parameter \\$repositories with no value type specified in iterable type array\\.$#" - count: 1 - path: tests/bundle/Core/ApiLoader/RepositoryConfigurationProviderTest.php - - - - message: "#^Method Ibexa\\\\Tests\\\\Bundle\\\\Core\\\\ApiLoader\\\\StorageConnectionFactoryTest\\:\\:getConfigResolverMock\\(\\) has no return type specified\\.$#" - count: 1 - path: tests/bundle/Core/ApiLoader/StorageConnectionFactoryTest.php - - - - message: "#^Method Ibexa\\\\Tests\\\\Bundle\\\\Core\\\\ApiLoader\\\\StorageConnectionFactoryTest\\:\\:getConnectionProvider\\(\\) has no return type specified\\.$#" - count: 1 - path: tests/bundle/Core/ApiLoader/StorageConnectionFactoryTest.php - - - - message: "#^Method Ibexa\\\\Tests\\\\Bundle\\\\Core\\\\ApiLoader\\\\StorageConnectionFactoryTest\\:\\:getContainerMock\\(\\) has no return type specified\\.$#" - count: 1 - path: tests/bundle/Core/ApiLoader/StorageConnectionFactoryTest.php - - - - message: "#^Method Ibexa\\\\Tests\\\\Bundle\\\\Core\\\\ApiLoader\\\\StorageConnectionFactoryTest\\:\\:testGetConnection\\(\\) has no return type specified\\.$#" - count: 1 - path: tests/bundle/Core/ApiLoader/StorageConnectionFactoryTest.php - - - - message: "#^Method Ibexa\\\\Tests\\\\Bundle\\\\Core\\\\ApiLoader\\\\StorageConnectionFactoryTest\\:\\:testGetConnection\\(\\) has parameter \\$doctrineConnection with no type specified\\.$#" - count: 1 - path: tests/bundle/Core/ApiLoader/StorageConnectionFactoryTest.php - - - - message: "#^Method Ibexa\\\\Tests\\\\Bundle\\\\Core\\\\ApiLoader\\\\StorageConnectionFactoryTest\\:\\:testGetConnection\\(\\) has parameter \\$repositoryAlias with no type specified\\.$#" - count: 1 - path: tests/bundle/Core/ApiLoader/StorageConnectionFactoryTest.php - - - - message: "#^Method Ibexa\\\\Tests\\\\Bundle\\\\Core\\\\ApiLoader\\\\StorageConnectionFactoryTest\\:\\:testGetConnectionInvalidConnection\\(\\) has no return type specified\\.$#" - count: 1 - path: tests/bundle/Core/ApiLoader/StorageConnectionFactoryTest.php - - - - message: "#^Method Ibexa\\\\Tests\\\\Bundle\\\\Core\\\\ApiLoader\\\\StorageConnectionFactoryTest\\:\\:testGetConnectionInvalidRepository\\(\\) has no return type specified\\.$#" - count: 1 - path: tests/bundle/Core/ApiLoader/StorageConnectionFactoryTest.php - - - - message: "#^Method Ibexa\\\\Tests\\\\Bundle\\\\Core\\\\ApiLoader\\\\StorageEngineFactoryTest\\:\\:getPersistenceHandlerMock\\(\\) has no return type specified\\.$#" - count: 1 - path: tests/bundle/Core/ApiLoader/StorageEngineFactoryTest.php - - - - message: "#^Method Ibexa\\\\Tests\\\\Bundle\\\\Core\\\\ApiLoader\\\\StorageEngineFactoryTest\\:\\:testBuildInvalidStorageEngine\\(\\) has no return type specified\\.$#" - count: 1 - path: tests/bundle/Core/ApiLoader/StorageEngineFactoryTest.php - - - - message: "#^Method Ibexa\\\\Tests\\\\Bundle\\\\Core\\\\ApiLoader\\\\StorageEngineFactoryTest\\:\\:testBuildStorageEngine\\(\\) has no return type specified\\.$#" - count: 1 - path: tests/bundle/Core/ApiLoader/StorageEngineFactoryTest.php - - - - message: "#^Method Ibexa\\\\Tests\\\\Bundle\\\\Core\\\\ApiLoader\\\\StorageEngineFactoryTest\\:\\:testRegisterStorageEngine\\(\\) has no return type specified\\.$#" - count: 1 - path: tests/bundle/Core/ApiLoader/StorageEngineFactoryTest.php - - message: "#^Method Ibexa\\\\Tests\\\\Bundle\\\\Core\\\\ChainConfigResolverTest\\:\\:buildMock\\(\\) has no return type specified\\.$#" count: 1 @@ -24720,11 +24560,6 @@ parameters: count: 1 path: tests/bundle/Core/DependencyInjection/Stub/StubYamlPolicyProvider.php - - - message: "#^Call to an undefined method Ibexa\\\\Bundle\\\\Core\\\\ApiLoader\\\\RepositoryConfigurationProvider\\:\\:method\\(\\)\\.$#" - count: 3 - path: tests/bundle/Core/Entity/EntityManagerFactoryTest.php - - message: "#^Property Ibexa\\\\Tests\\\\Bundle\\\\Core\\\\Entity\\\\EntityManagerFactoryTest\\:\\:\\$serviceLocator is never read, only written\\.$#" count: 1 @@ -44595,21 +44430,6 @@ parameters: count: 1 path: tests/lib/Helper/FieldsGroups/ArrayTranslatorFieldsGroupsListTest.php - - - message: "#^Method Ibexa\\\\Tests\\\\Core\\\\Helper\\\\FieldsGroups\\\\RepositoryConfigFieldsGroupsListFactoryTest\\:\\:testBuild\\(\\) has no return type specified\\.$#" - count: 1 - path: tests/lib/Helper/FieldsGroups/RepositoryConfigFieldsGroupsListFactoryTest.php - - - - message: "#^Property Ibexa\\\\Tests\\\\Core\\\\Helper\\\\FieldsGroups\\\\RepositoryConfigFieldsGroupsListFactoryTest\\:\\:\\$repositoryConfigMock has no type specified\\.$#" - count: 1 - path: tests/lib/Helper/FieldsGroups/RepositoryConfigFieldsGroupsListFactoryTest.php - - - - message: "#^Property Ibexa\\\\Tests\\\\Core\\\\Helper\\\\FieldsGroups\\\\RepositoryConfigFieldsGroupsListFactoryTest\\:\\:\\$translatorMock has no type specified\\.$#" - count: 1 - path: tests/lib/Helper/FieldsGroups/RepositoryConfigFieldsGroupsListFactoryTest.php - - message: "#^Method Ibexa\\\\Tests\\\\Core\\\\Helper\\\\PreviewLocationProviderTest\\:\\:testGetPreviewLocation\\(\\) has no return type specified\\.$#" count: 1 diff --git a/src/bundle/Core/ApiLoader/Exception/InvalidRepositoryException.php b/src/bundle/Core/ApiLoader/Exception/InvalidRepositoryException.php index 0c3fe878f6..57cd9cb36f 100644 --- a/src/bundle/Core/ApiLoader/Exception/InvalidRepositoryException.php +++ b/src/bundle/Core/ApiLoader/Exception/InvalidRepositoryException.php @@ -4,11 +4,12 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ +declare(strict_types=1); namespace Ibexa\Bundle\Core\ApiLoader\Exception; -use InvalidArgumentException; +use Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException; -class InvalidRepositoryException extends InvalidArgumentException +final class InvalidRepositoryException extends InvalidArgumentException { } diff --git a/src/bundle/Core/ApiLoader/Exception/InvalidSearchEngine.php b/src/bundle/Core/ApiLoader/Exception/InvalidSearchEngine.php index 1ddb12ba6b..322af57e17 100644 --- a/src/bundle/Core/ApiLoader/Exception/InvalidSearchEngine.php +++ b/src/bundle/Core/ApiLoader/Exception/InvalidSearchEngine.php @@ -4,11 +4,12 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ +declare(strict_types=1); namespace Ibexa\Bundle\Core\ApiLoader\Exception; -use InvalidArgumentException; +use Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException; -class InvalidSearchEngine extends InvalidArgumentException +final class InvalidSearchEngine extends InvalidArgumentException { } diff --git a/src/bundle/Core/ApiLoader/Exception/InvalidSearchEngineIndexer.php b/src/bundle/Core/ApiLoader/Exception/InvalidSearchEngineIndexer.php index beef3cd514..4b70072c2f 100644 --- a/src/bundle/Core/ApiLoader/Exception/InvalidSearchEngineIndexer.php +++ b/src/bundle/Core/ApiLoader/Exception/InvalidSearchEngineIndexer.php @@ -4,11 +4,12 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ +declare(strict_types=1); namespace Ibexa\Bundle\Core\ApiLoader\Exception; -use InvalidArgumentException; +use Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException; -class InvalidSearchEngineIndexer extends InvalidArgumentException +final class InvalidSearchEngineIndexer extends InvalidArgumentException { } diff --git a/src/bundle/Core/ApiLoader/Exception/InvalidStorageEngine.php b/src/bundle/Core/ApiLoader/Exception/InvalidStorageEngine.php index fde4dfddd8..2b00562c2c 100644 --- a/src/bundle/Core/ApiLoader/Exception/InvalidStorageEngine.php +++ b/src/bundle/Core/ApiLoader/Exception/InvalidStorageEngine.php @@ -4,11 +4,12 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ +declare(strict_types=1); namespace Ibexa\Bundle\Core\ApiLoader\Exception; -use InvalidArgumentException; +use Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException; -class InvalidStorageEngine extends InvalidArgumentException +final class InvalidStorageEngine extends InvalidArgumentException { } diff --git a/src/bundle/Core/ApiLoader/RepositoryConfigurationProvider.php b/src/bundle/Core/ApiLoader/RepositoryConfigurationProvider.php index eaab7d983d..3ebc747dd7 100644 --- a/src/bundle/Core/ApiLoader/RepositoryConfigurationProvider.php +++ b/src/bundle/Core/ApiLoader/RepositoryConfigurationProvider.php @@ -4,72 +4,39 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ +declare(strict_types=1); namespace Ibexa\Bundle\Core\ApiLoader; -use Ibexa\Bundle\Core\ApiLoader\Exception\InvalidRepositoryException; -use Ibexa\Contracts\Core\SiteAccess\ConfigResolverInterface; +use Ibexa\Contracts\Core\Container\ApiLoader\RepositoryConfigurationProviderInterface; /** - * The repository configuration provider. + * @deprecated 5.0.0 The "\Ibexa\Bundle\Core\ApiLoader\RepositoryConfigurationProvider" class is deprecated, will be removed in 6.0.0. + * Inject {@see \Ibexa\Contracts\Core\Container\ApiLoader\RepositoryConfigurationProviderInterface} from Dependency Injection Container instead. */ -class RepositoryConfigurationProvider +final readonly class RepositoryConfigurationProvider implements RepositoryConfigurationProviderInterface { - private const REPOSITORY_STORAGE = 'storage'; - private const REPOSITORY_CONNECTION = 'connection'; - private const DEFAULT_CONNECTION_NAME = 'default'; - - /** @var \Ibexa\Contracts\Core\SiteAccess\ConfigResolverInterface */ - private $configResolver; - - /** @var array */ - private $repositories; - - public function __construct(ConfigResolverInterface $configResolver, array $repositories) + public function __construct(private RepositoryConfigurationProviderInterface $configurationProvider) { - $this->configResolver = $configResolver; - $this->repositories = $repositories; } - /** - * @return array - * - * @throws \Ibexa\Bundle\Core\ApiLoader\Exception\InvalidRepositoryException - */ - public function getRepositoryConfig() + public function getRepositoryConfig(): array { - // Takes configured repository as the reference, if it exists. - // If not, the first configured repository is considered instead. - $repositoryAlias = $this->configResolver->getParameter('repository'); - $repositoryAlias = $repositoryAlias ?: $this->getDefaultRepositoryAlias(); - - if (empty($repositoryAlias) || !isset($this->repositories[$repositoryAlias])) { - throw new InvalidRepositoryException( - "Undefined Repository '$repositoryAlias'. Check if the Repository is configured in your project's ibexa.yaml." - ); - } - - return ['alias' => $repositoryAlias] + $this->repositories[$repositoryAlias]; + return $this->configurationProvider->getRepositoryConfig(); } public function getCurrentRepositoryAlias(): string { - return $this->getRepositoryConfig()['alias']; + return $this->configurationProvider->getCurrentRepositoryAlias(); } public function getDefaultRepositoryAlias(): ?string { - $aliases = array_keys($this->repositories); - - return array_shift($aliases); + return $this->configurationProvider->getDefaultRepositoryAlias(); } public function getStorageConnectionName(): string { - $repositoryConfig = $this->getRepositoryConfig(); - - return $repositoryConfig[self::REPOSITORY_STORAGE][self::REPOSITORY_CONNECTION] - ? $repositoryConfig[self::REPOSITORY_STORAGE][self::REPOSITORY_CONNECTION] - : self::DEFAULT_CONNECTION_NAME; + return $this->configurationProvider->getStorageConnectionName(); } } diff --git a/src/bundle/Core/ApiLoader/RepositoryFactory.php b/src/bundle/Core/ApiLoader/RepositoryFactory.php index 676131f33d..c47ddcc3f7 100644 --- a/src/bundle/Core/ApiLoader/RepositoryFactory.php +++ b/src/bundle/Core/ApiLoader/RepositoryFactory.php @@ -7,6 +7,7 @@ namespace Ibexa\Bundle\Core\ApiLoader; +use Ibexa\Contracts\Core\Container\ApiLoader\RepositoryConfigurationProviderInterface; use Ibexa\Contracts\Core\Persistence\Filter\Content\Handler as ContentFilteringHandler; use Ibexa\Contracts\Core\Persistence\Filter\Location\Handler as LocationFilteringHandler; use Ibexa\Contracts\Core\Persistence\Handler as PersistenceHandler; @@ -59,6 +60,7 @@ public function __construct( $repositoryClass, array $policyMap, LanguageResolver $languageResolver, + private readonly RepositoryConfigurationProviderInterface $repositoryConfigurationProvider, LoggerInterface $logger = null ) { $this->configResolver = $configResolver; @@ -94,9 +96,9 @@ public function buildRepository( LocationFilteringHandler $locationFilteringHandler, PasswordValidatorInterface $passwordValidator, ConfigResolverInterface $configResolver, - NameSchemaServiceInterface $nameSchemaService + NameSchemaServiceInterface $nameSchemaService, ): Repository { - $config = $this->container->get(RepositoryConfigurationProvider::class)->getRepositoryConfig(); + $config = $this->repositoryConfigurationProvider->getRepositoryConfig(); return new $this->repositoryClass( $persistenceHandler, diff --git a/src/bundle/Core/ApiLoader/SearchEngineFactory.php b/src/bundle/Core/ApiLoader/SearchEngineFactory.php index 2fb9b26ab9..85debbdbb1 100644 --- a/src/bundle/Core/ApiLoader/SearchEngineFactory.php +++ b/src/bundle/Core/ApiLoader/SearchEngineFactory.php @@ -8,6 +8,7 @@ namespace Ibexa\Bundle\Core\ApiLoader; use Ibexa\Bundle\Core\ApiLoader\Exception\InvalidSearchEngine; +use Ibexa\Contracts\Core\Container\ApiLoader\RepositoryConfigurationProviderInterface; use Ibexa\Contracts\Core\Search\Handler as SearchHandler; /** @@ -15,9 +16,6 @@ */ class SearchEngineFactory { - /** @var \Ibexa\Bundle\Core\ApiLoader\RepositoryConfigurationProvider */ - private $repositoryConfigurationProvider; - /** * Hash of registered search engines. * Key is the search engine identifier, value search handler itself. @@ -26,9 +24,9 @@ class SearchEngineFactory */ protected $searchEngines = []; - public function __construct(RepositoryConfigurationProvider $repositoryConfigurationProvider) - { - $this->repositoryConfigurationProvider = $repositoryConfigurationProvider; + public function __construct( + private readonly RepositoryConfigurationProviderInterface $repositoryConfigurationProvider, + ) { } /** diff --git a/src/bundle/Core/ApiLoader/SearchEngineIndexerFactory.php b/src/bundle/Core/ApiLoader/SearchEngineIndexerFactory.php index 231e4637ac..3f879135c3 100644 --- a/src/bundle/Core/ApiLoader/SearchEngineIndexerFactory.php +++ b/src/bundle/Core/ApiLoader/SearchEngineIndexerFactory.php @@ -9,6 +9,7 @@ use Ibexa\Bundle\Core\ApiLoader\Exception\InvalidSearchEngine; use Ibexa\Bundle\Core\ApiLoader\Exception\InvalidSearchEngineIndexer; +use Ibexa\Contracts\Core\Container\ApiLoader\RepositoryConfigurationProviderInterface; use Ibexa\Core\Search\Common\Indexer as SearchEngineIndexer; /** @@ -16,9 +17,6 @@ */ class SearchEngineIndexerFactory { - /** @var \Ibexa\Bundle\Core\ApiLoader\RepositoryConfigurationProvider */ - private $repositoryConfigurationProvider; - /** * Hash of registered search engine indexers. * Key is the search engine identifier, value indexer itself. @@ -27,9 +25,9 @@ class SearchEngineIndexerFactory */ protected $searchEngineIndexers = []; - public function __construct(RepositoryConfigurationProvider $repositoryConfigurationProvider) - { - $this->repositoryConfigurationProvider = $repositoryConfigurationProvider; + public function __construct( + private readonly RepositoryConfigurationProviderInterface $repositoryConfigurationProvider, + ) { } /** diff --git a/src/bundle/Core/ApiLoader/StorageConnectionFactory.php b/src/bundle/Core/ApiLoader/StorageConnectionFactory.php index ce9b0d9cc7..a7a83db22b 100644 --- a/src/bundle/Core/ApiLoader/StorageConnectionFactory.php +++ b/src/bundle/Core/ApiLoader/StorageConnectionFactory.php @@ -7,49 +7,44 @@ namespace Ibexa\Bundle\Core\ApiLoader; +use Doctrine\DBAL\Connection; +use Ibexa\Contracts\Core\Container\ApiLoader\RepositoryConfigurationProviderInterface; use InvalidArgumentException; -use Symfony\Component\DependencyInjection\ContainerAwareInterface; -use Symfony\Component\DependencyInjection\ContainerAwareTrait; +use Symfony\Contracts\Service\ServiceProviderInterface; -class StorageConnectionFactory implements ContainerAwareInterface +/** + * @internal + */ +final readonly class StorageConnectionFactory { - use ContainerAwareTrait; - - /** @var \Ibexa\Bundle\Core\ApiLoader\RepositoryConfigurationProvider */ - protected $repositoryConfigurationProvider; - - public function __construct(RepositoryConfigurationProvider $repositoryConfigurationProvider) - { - $this->repositoryConfigurationProvider = $repositoryConfigurationProvider; + public function __construct( + private RepositoryConfigurationProviderInterface $repositoryConfigurationProvider, + private ServiceProviderInterface $serviceLocator, + ) { } /** * Returns database connection used by database handler. * * @throws \InvalidArgumentException - * - * @return \Doctrine\DBAL\Connection + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException + * @throws \Psr\Container\ContainerExceptionInterface + * @throws \Psr\Container\NotFoundExceptionInterface */ - public function getConnection() + public function getConnection(): Connection { $repositoryConfig = $this->repositoryConfigurationProvider->getRepositoryConfig(); // Taking provided connection name if any. // Otherwise, just fallback to the default connection. - if (isset($repositoryConfig['storage']['connection'])) { - $doctrineConnectionId = sprintf('doctrine.dbal.%s_connection', $repositoryConfig['storage']['connection']); - } else { - // "database_connection" is an alias to the default connection, set up by DoctrineBundle. - $doctrineConnectionId = 'database_connection'; - } - - if (!$this->container->has($doctrineConnectionId)) { + $connectionName = $repositoryConfig['storage']['connection'] ?? 'default'; + if (!$this->serviceLocator->has($connectionName)) { throw new InvalidArgumentException( - "Invalid Doctrine connection '{$repositoryConfig['storage']['connection']}' for Repository '{$repositoryConfig['alias']}'." . - 'Valid connections are: ' . implode(', ', array_keys($this->container->getParameter('doctrine.connections'))) + "Invalid Doctrine connection '$connectionName' for Repository '{$repositoryConfig['alias']}'. " . + 'Valid connections are: ' . implode(', ', array_keys($this->serviceLocator->getProvidedServices())) ); } - return $this->container->get($doctrineConnectionId); + return $this->serviceLocator->get($connectionName); } } diff --git a/src/bundle/Core/ApiLoader/StorageEngineFactory.php b/src/bundle/Core/ApiLoader/StorageEngineFactory.php index 8040dfa5ce..836f83783a 100644 --- a/src/bundle/Core/ApiLoader/StorageEngineFactory.php +++ b/src/bundle/Core/ApiLoader/StorageEngineFactory.php @@ -8,6 +8,7 @@ namespace Ibexa\Bundle\Core\ApiLoader; use Ibexa\Bundle\Core\ApiLoader\Exception\InvalidStorageEngine; +use Ibexa\Contracts\Core\Container\ApiLoader\RepositoryConfigurationProviderInterface; use Ibexa\Contracts\Core\Persistence\Handler as PersistenceHandler; /** @@ -15,31 +16,25 @@ */ class StorageEngineFactory { - /** @var \Ibexa\Bundle\Core\ApiLoader\RepositoryConfigurationProvider */ - private $repositoryConfigurationProvider; - /** * Hash of registered storage engines. * Key is the storage engine identifier, value persistence handler itself. * * @var \Ibexa\Contracts\Core\Persistence\Handler[] */ - protected $storageEngines = []; + protected array $storageEngines = []; - public function __construct(RepositoryConfigurationProvider $repositoryConfigurationProvider) - { - $this->repositoryConfigurationProvider = $repositoryConfigurationProvider; + public function __construct( + private readonly RepositoryConfigurationProviderInterface $repositoryConfigurationProvider, + ) { } /** * Registers $persistenceHandler as a valid storage engine, with identifier $storageEngineIdentifier. * * Note: It is strongly recommenced to register a lazy persistent handler. - * - * @param \Ibexa\Contracts\Core\Persistence\Handler $persistenceHandler - * @param string $storageEngineIdentifier */ - public function registerStorageEngine(PersistenceHandler $persistenceHandler, $storageEngineIdentifier) + public function registerStorageEngine(PersistenceHandler $persistenceHandler, string $storageEngineIdentifier): void { $this->storageEngines[$storageEngineIdentifier] = $persistenceHandler; } @@ -47,7 +42,7 @@ public function registerStorageEngine(PersistenceHandler $persistenceHandler, $s /** * @return \Ibexa\Contracts\Core\Persistence\Handler[] */ - public function getStorageEngines() + public function getStorageEngines(): array { return $this->storageEngines; } @@ -55,7 +50,7 @@ public function getStorageEngines() /** * Builds storage engine identified by $storageEngineIdentifier (the "alias" attribute in the service tag). * - * @throws \Ibexa\Bundle\Core\ApiLoader\Exception\InvalidStorageEngine + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException */ public function buildStorageEngine(): PersistenceHandler { @@ -73,9 +68,9 @@ public function buildStorageEngine(): PersistenceHandler if (!isset($this->storageEngines[$storageEngineAlias])) { throw new InvalidStorageEngine( - "Invalid storage engine '{$storageEngineAlias}'. " . + "Invalid storage engine '$storageEngineAlias'. " . 'Could not find any service tagged with ibexa.storage ' . - "with alias {$storageEngineAlias}." + "with alias $storageEngineAlias." ); } diff --git a/src/bundle/Core/Command/CleanupVersionsCommand.php b/src/bundle/Core/Command/CleanupVersionsCommand.php index cec0bffd7b..3168db825d 100644 --- a/src/bundle/Core/Command/CleanupVersionsCommand.php +++ b/src/bundle/Core/Command/CleanupVersionsCommand.php @@ -9,11 +9,10 @@ use Doctrine\DBAL\Connection; use Exception; -use Ibexa\Bundle\Core\ApiLoader\RepositoryConfigurationProvider; +use Ibexa\Contracts\Core\Container\ApiLoader\RepositoryConfigurationProviderInterface; use Ibexa\Contracts\Core\Repository\Repository; use Ibexa\Contracts\Core\Repository\Values\Content\VersionInfo; use Ibexa\Core\Base\Exceptions\InvalidArgumentException; -use PDO; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Helper\ProgressBar; use Symfony\Component\Console\Input\InputInterface; @@ -44,18 +43,15 @@ class CleanupVersionsCommand extends Command implements BackwardCompatibleComman self::VERSION_PUBLISHED => VersionInfo::STATUS_PUBLISHED, ]; - /** @var \Ibexa\Contracts\Core\Repository\Repository */ - private $repository; + private readonly Repository $repository; - /** @var \Ibexa\Bundle\Core\ApiLoader\RepositoryConfigurationProvider */ - private $repositoryConfigurationProvider; + private readonly RepositoryConfigurationProviderInterface $repositoryConfigurationProvider; - /** @var \Doctrine\DBAL\Driver\Connection */ - private $connection; + private readonly Connection $connection; public function __construct( Repository $repository, - RepositoryConfigurationProvider $repositoryConfigurationProvider, + RepositoryConfigurationProviderInterface $repositoryConfigurationProvider, Connection $connection ) { $this->repository = $repository; @@ -275,9 +271,10 @@ protected function getObjectsIds($keep, $status, $excludedContentTypes = []) )->setParameter(':contentTypes', $excludedContentTypes, Connection::PARAM_STR_ARRAY); } + /** @var \Doctrine\DBAL\ForwardCompatibility\Result $stmt */ $stmt = $query->execute(); - return $stmt->fetchAll(PDO::FETCH_COLUMN); + return $stmt->fetchFirstColumn(); } /** diff --git a/src/bundle/Core/DependencyInjection/Compiler/StorageConnectionFactoryPass.php b/src/bundle/Core/DependencyInjection/Compiler/StorageConnectionFactoryPass.php new file mode 100644 index 0000000000..9647c2d556 --- /dev/null +++ b/src/bundle/Core/DependencyInjection/Compiler/StorageConnectionFactoryPass.php @@ -0,0 +1,40 @@ +has(StorageConnectionFactory::class) || !$container->hasParameter('doctrine.connections')) { + return; + } + + /** @var array $doctrineConnections a map of [ connection_name => connection_service_id ] */ + $doctrineConnections = $container->getParameter('doctrine.connections'); + $doctrineConnectionServices = array_map( + static fn (string $serviceId): Reference => new Reference($serviceId), + $doctrineConnections + ); + $storageConnectionFactory = $container->findDefinition(StorageConnectionFactory::class); + $storageConnectionFactory->replaceArgument( + '$serviceLocator', + ServiceLocatorTagPass::register($container, $doctrineConnectionServices) + ); + } +} diff --git a/src/bundle/Core/Entity/EntityManagerFactory.php b/src/bundle/Core/Entity/EntityManagerFactory.php index a9730fb14e..205cd9c895 100644 --- a/src/bundle/Core/Entity/EntityManagerFactory.php +++ b/src/bundle/Core/Entity/EntityManagerFactory.php @@ -9,7 +9,7 @@ namespace Ibexa\Bundle\Core\Entity; use Doctrine\ORM\EntityManagerInterface; -use Ibexa\Bundle\Core\ApiLoader\RepositoryConfigurationProvider; +use Ibexa\Contracts\Core\Container\ApiLoader\RepositoryConfigurationProviderInterface; use Symfony\Component\DependencyInjection\ServiceLocator; /** @@ -17,9 +17,6 @@ */ class EntityManagerFactory { - /** @var \Ibexa\Bundle\Core\ApiLoader\RepositoryConfigurationProvider */ - private $repositoryConfigurationProvider; - /** @var \Symfony\Component\DependencyInjection\ServiceLocator */ private $serviceLocator; @@ -30,12 +27,11 @@ class EntityManagerFactory private $entityManagers; public function __construct( - RepositoryConfigurationProvider $repositoryConfigurationProvider, + private readonly RepositoryConfigurationProviderInterface $repositoryConfigurationProvider, ServiceLocator $serviceLocator, string $defaultConnection, array $entityManagers ) { - $this->repositoryConfigurationProvider = $repositoryConfigurationProvider; $this->serviceLocator = $serviceLocator; $this->defaultConnection = $defaultConnection; $this->entityManagers = $entityManagers; diff --git a/src/bundle/Core/IbexaCoreBundle.php b/src/bundle/Core/IbexaCoreBundle.php index 505370aec6..cfe4ccd655 100644 --- a/src/bundle/Core/IbexaCoreBundle.php +++ b/src/bundle/Core/IbexaCoreBundle.php @@ -30,6 +30,7 @@ use Ibexa\Bundle\Core\DependencyInjection\Compiler\SessionConfigurationPass; use Ibexa\Bundle\Core\DependencyInjection\Compiler\SiteAccessMatcherRegistryPass; use Ibexa\Bundle\Core\DependencyInjection\Compiler\SlugConverterConfigurationPass; +use Ibexa\Bundle\Core\DependencyInjection\Compiler\StorageConnectionFactoryPass; use Ibexa\Bundle\Core\DependencyInjection\Compiler\StorageConnectionPass; use Ibexa\Bundle\Core\DependencyInjection\Compiler\TranslationCollectorPass; use Ibexa\Bundle\Core\DependencyInjection\Compiler\URLHandlerPass; @@ -88,6 +89,7 @@ public function build(ContainerBuilder $container): void // Storage passes $container->addCompilerPass(new ExternalStorageRegistryPass()); + $container->addCompilerPass(new StorageConnectionFactoryPass()); // Legacy Storage passes $container->addCompilerPass(new FieldValueConverterRegistryPass()); $container->addCompilerPass(new RoleLimitationConverterPass()); diff --git a/src/bundle/Core/Resources/config/papi.yml b/src/bundle/Core/Resources/config/papi.yml index 2669a3f1bd..efee2a8a24 100644 --- a/src/bundle/Core/Resources/config/papi.yml +++ b/src/bundle/Core/Resources/config/papi.yml @@ -16,33 +16,30 @@ services: - Ibexa\Core\Repository\Repository - '%ibexa.api.role.policy_map%' - '@Ibexa\Contracts\Core\Repository\LanguageResolver' + - '@Ibexa\Contracts\Core\Container\ApiLoader\RepositoryConfigurationProviderInterface' - "@?logger" calls: - [setContainer, ["@service_container"]] Ibexa\Bundle\Core\ApiLoader\StorageEngineFactory: - class: Ibexa\Bundle\Core\ApiLoader\StorageEngineFactory arguments: - - '@Ibexa\Bundle\Core\ApiLoader\RepositoryConfigurationProvider' + $repositoryConfigurationProvider: '@Ibexa\Contracts\Core\Container\ApiLoader\RepositoryConfigurationProviderInterface' ibexa.api.persistence_handler: #To disable cache, switch alias to Ibexa\Contracts\Core\Persistence\Handler alias: Ibexa\Core\Persistence\Cache\Handler Ibexa\Contracts\Core\Persistence\Handler: - class: Ibexa\Contracts\Core\Persistence\Handler factory: ['@Ibexa\Bundle\Core\ApiLoader\StorageEngineFactory', buildStorageEngine] public: false Ibexa\Bundle\Core\ApiLoader\SearchEngineFactory: - class: Ibexa\Bundle\Core\ApiLoader\SearchEngineFactory arguments: - - '@Ibexa\Bundle\Core\ApiLoader\RepositoryConfigurationProvider' + $repositoryConfigurationProvider: '@Ibexa\Contracts\Core\Container\ApiLoader\RepositoryConfigurationProviderInterface' Ibexa\Bundle\Core\ApiLoader\SearchEngineIndexerFactory: - class: Ibexa\Bundle\Core\ApiLoader\SearchEngineIndexerFactory arguments: - - '@Ibexa\Bundle\Core\ApiLoader\RepositoryConfigurationProvider' + $repositoryConfigurationProvider: '@Ibexa\Contracts\Core\Container\ApiLoader\RepositoryConfigurationProviderInterface' ibexa.spi.search: alias: Ibexa\Contracts\Core\Search\VersatileHandler diff --git a/src/bundle/Core/Resources/config/services.yml b/src/bundle/Core/Resources/config/services.yml index 0af04b30a3..a8a954686b 100644 --- a/src/bundle/Core/Resources/config/services.yml +++ b/src/bundle/Core/Resources/config/services.yml @@ -232,9 +232,8 @@ services: - "@translator" Ibexa\Core\Helper\FieldsGroups\RepositoryConfigFieldsGroupsListFactory: - class: Ibexa\Core\Helper\FieldsGroups\RepositoryConfigFieldsGroupsListFactory arguments: - - '@Ibexa\Bundle\Core\ApiLoader\RepositoryConfigurationProvider' + $configProvider: '@Ibexa\Contracts\Core\Container\ApiLoader\RepositoryConfigurationProviderInterface' Ibexa\Core\QueryType\QueryParameterContentViewQueryTypeMapper: class: Ibexa\Core\QueryType\QueryParameterContentViewQueryTypeMapper @@ -316,11 +315,10 @@ services: - { name: console.command } Ibexa\Bundle\Core\Command\CleanupVersionsCommand: - class: Ibexa\Bundle\Core\Command\CleanupVersionsCommand arguments: - - '@Ibexa\Core\Event\Repository' - - '@Ibexa\Bundle\Core\ApiLoader\RepositoryConfigurationProvider' - - '@ibexa.persistence.connection' + $repository: '@Ibexa\Core\Event\Repository' + $repositoryConfigurationProvider: '@Ibexa\Contracts\Core\Container\ApiLoader\RepositoryConfigurationProviderInterface' + $connection: '@ibexa.persistence.connection' tags: - { name: console.command } @@ -365,7 +363,7 @@ services: ibexa.doctrine.orm.entity_manager_factory: class: Ibexa\Bundle\Core\Entity\EntityManagerFactory arguments: - $repositoryConfigurationProvider: '@Ibexa\Bundle\Core\ApiLoader\RepositoryConfigurationProvider' + $repositoryConfigurationProvider: '@Ibexa\Contracts\Core\Container\ApiLoader\RepositoryConfigurationProviderInterface' $defaultConnection: '%doctrine.default_connection%' $entityManagers: '%doctrine.entity_managers%' diff --git a/src/bundle/Core/Resources/config/storage_engines.yml b/src/bundle/Core/Resources/config/storage_engines.yml index ad6c90bd16..617386c6a7 100644 --- a/src/bundle/Core/Resources/config/storage_engines.yml +++ b/src/bundle/Core/Resources/config/storage_engines.yml @@ -1,17 +1,25 @@ services: + Ibexa\Contracts\Core\Container\ApiLoader\RepositoryConfigurationProviderInterface: + alias: Ibexa\Core\Base\Container\ApiLoader\RepositoryConfigurationProvider + + Ibexa\Core\Base\Container\ApiLoader\RepositoryConfigurationProvider: + arguments: + $configResolver: '@Ibexa\Contracts\Core\SiteAccess\ConfigResolverInterface' + $repositories: '%ibexa.repositories%' + Ibexa\Bundle\Core\ApiLoader\RepositoryConfigurationProvider: - public: true # @todo should be private - class: Ibexa\Bundle\Core\ApiLoader\RepositoryConfigurationProvider + deprecated: + package: 'ibexa/core' + version: '5.0' + message: 'Since ibexa/core 5.0: The "%service_id%" service is deprecated and will be removed in 6.0. Use Ibexa\Contracts\Core\Container\ApiLoader\RepositoryConfigurationProviderInterface instead' arguments: - - '@ibexa.config.resolver' - - '%ibexa.repositories%' + $configurationProvider: '@Ibexa\Contracts\Core\Container\ApiLoader\RepositoryConfigurationProviderInterface' Ibexa\Bundle\Core\ApiLoader\StorageConnectionFactory: - class: Ibexa\Bundle\Core\ApiLoader\StorageConnectionFactory + autowire: true + autoconfigure: true arguments: - - '@Ibexa\Bundle\Core\ApiLoader\RepositoryConfigurationProvider' - calls: - - [setContainer, ["@service_container"]] + $serviceLocator: ~ ibexa.persistence.connection: public: true # @todo should be private diff --git a/src/bundle/LegacySearchEngine/ApiLoader/ConnectionFactory.php b/src/bundle/LegacySearchEngine/ApiLoader/ConnectionFactory.php index bca14ec78a..9686a8505c 100644 --- a/src/bundle/LegacySearchEngine/ApiLoader/ConnectionFactory.php +++ b/src/bundle/LegacySearchEngine/ApiLoader/ConnectionFactory.php @@ -7,7 +7,7 @@ namespace Ibexa\Bundle\LegacySearchEngine\ApiLoader; -use Ibexa\Bundle\Core\ApiLoader\RepositoryConfigurationProvider; +use Ibexa\Contracts\Core\Container\ApiLoader\RepositoryConfigurationProviderInterface; use InvalidArgumentException; use Symfony\Component\DependencyInjection\ContainerAwareInterface; use Symfony\Component\DependencyInjection\ContainerAwareTrait; @@ -16,10 +16,9 @@ class ConnectionFactory implements ContainerAwareInterface { use ContainerAwareTrait; - /** @var \Ibexa\Bundle\Core\ApiLoader\RepositoryConfigurationProvider */ - protected $repositoryConfigurationProvider; + protected RepositoryConfigurationProviderInterface $repositoryConfigurationProvider; - public function __construct(RepositoryConfigurationProvider $repositoryConfigurationProvider) + public function __construct(RepositoryConfigurationProviderInterface $repositoryConfigurationProvider) { $this->repositoryConfigurationProvider = $repositoryConfigurationProvider; } diff --git a/src/bundle/LegacySearchEngine/Resources/config/services.yml b/src/bundle/LegacySearchEngine/Resources/config/services.yml index 84eb05d611..832acb6156 100644 --- a/src/bundle/LegacySearchEngine/Resources/config/services.yml +++ b/src/bundle/LegacySearchEngine/Resources/config/services.yml @@ -1,10 +1,9 @@ services: Ibexa\Bundle\LegacySearchEngine\ApiLoader\ConnectionFactory: - class: Ibexa\Bundle\LegacySearchEngine\ApiLoader\ConnectionFactory arguments: - - '@Ibexa\Bundle\Core\ApiLoader\RepositoryConfigurationProvider' + $repositoryConfigurationProvider: '@Ibexa\Contracts\Core\Container\ApiLoader\RepositoryConfigurationProviderInterface' calls: - - [setContainer, ["@service_container"]] + - [setContainer, ['@service_container']] ibexa.api.search_engine.legacy.connection: class: Doctrine\DBAL\Connection diff --git a/src/bundle/RepositoryInstaller/Command/InstallPlatformCommand.php b/src/bundle/RepositoryInstaller/Command/InstallPlatformCommand.php index f55c2ec35f..a1d6a5a98a 100644 --- a/src/bundle/RepositoryInstaller/Command/InstallPlatformCommand.php +++ b/src/bundle/RepositoryInstaller/Command/InstallPlatformCommand.php @@ -8,8 +8,8 @@ namespace Ibexa\Bundle\RepositoryInstaller\Command; use Doctrine\DBAL\Connection; -use Ibexa\Bundle\Core\ApiLoader\RepositoryConfigurationProvider; use Ibexa\Bundle\Core\Command\BackwardCompatibleCommand; +use Ibexa\Contracts\Core\Container\ApiLoader\RepositoryConfigurationProviderInterface; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; @@ -38,8 +38,7 @@ final class InstallPlatformCommand extends Command implements BackwardCompatible /** @var \Ibexa\Bundle\RepositoryInstaller\Installer\Installer[] */ private $installers = []; - /** @var \Ibexa\Bundle\Core\ApiLoader\RepositoryConfigurationProvider */ - private $repositoryConfigurationProvider; + private RepositoryConfigurationProviderInterface $repositoryConfigurationProvider; public const EXIT_GENERAL_DATABASE_ERROR = 4; public const EXIT_PARAMETERS_NOT_FOUND = 5; @@ -51,7 +50,7 @@ public function __construct( array $installers, CacheItemPoolInterface $cachePool, string $environment, - RepositoryConfigurationProvider $repositoryConfigurationProvider + RepositoryConfigurationProviderInterface $repositoryConfigurationProvider ) { $this->connection = $connection; $this->installers = $installers; diff --git a/src/bundle/RepositoryInstaller/Resources/config/services.yml b/src/bundle/RepositoryInstaller/Resources/config/services.yml index 965404750b..6fad69a446 100644 --- a/src/bundle/RepositoryInstaller/Resources/config/services.yml +++ b/src/bundle/RepositoryInstaller/Resources/config/services.yml @@ -22,7 +22,7 @@ services: $installers: [] $cachePool: '@ibexa.cache_pool' $environment: "%kernel.environment%" - $repositoryConfigurationProvider: '@Ibexa\Bundle\Core\ApiLoader\RepositoryConfigurationProvider' + $repositoryConfigurationProvider: '@Ibexa\Contracts\Core\Container\ApiLoader\RepositoryConfigurationProviderInterface' tags: - { name: console.command } diff --git a/src/contracts/Container/ApiLoader/RepositoryConfigurationProviderInterface.php b/src/contracts/Container/ApiLoader/RepositoryConfigurationProviderInterface.php new file mode 100644 index 0000000000..df54301c35 --- /dev/null +++ b/src/contracts/Container/ApiLoader/RepositoryConfigurationProviderInterface.php @@ -0,0 +1,42 @@ +} + * @phpstan-type TRepositorySearchConfiguration array{engine: string, connection: string} + * @phpstan-type TRepositoryConfiguration array{ + * alias: string, + * storage: TRepositoryStorageConfiguration, + * search: TRepositorySearchConfiguration, + * fields_groups: array{default: string, list: string[]}, + * options: array + * } + */ +interface RepositoryConfigurationProviderInterface +{ + /** + * @phpstan-return TRepositoryConfiguration + * + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException + */ + public function getRepositoryConfig(): array; + + /** + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException + */ + public function getCurrentRepositoryAlias(): string; + + public function getDefaultRepositoryAlias(): ?string; + + /** + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException + */ + public function getStorageConnectionName(): string; +} diff --git a/src/lib/Base/Container/ApiLoader/RepositoryConfigurationProvider.php b/src/lib/Base/Container/ApiLoader/RepositoryConfigurationProvider.php new file mode 100644 index 0000000000..2cf01ea22f --- /dev/null +++ b/src/lib/Base/Container/ApiLoader/RepositoryConfigurationProvider.php @@ -0,0 +1,78 @@ + + * } + * @phpstan-type TRepositoryListConfiguration array + */ +final readonly class RepositoryConfigurationProvider implements RepositoryConfigurationProviderInterface +{ + private const string REPOSITORY_STORAGE = 'storage'; + private const string REPOSITORY_CONNECTION = 'connection'; + private const string DEFAULT_CONNECTION_NAME = 'default'; + + /** + * @phpstan-param TRepositoryListConfiguration $repositories + */ + public function __construct( + private ConfigResolverInterface $configResolver, + private array $repositories, + ) { + } + + public function getRepositoryConfig(): array + { + // Takes configured repository as the reference, if it exists. + // If not, the first configured repository is considered instead. + /** @var string|null $repositoryAlias */ + $repositoryAlias = $this->configResolver->getParameter('repository'); + $repositoryAlias = $repositoryAlias ?? $this->getDefaultRepositoryAlias(); + + if (empty($repositoryAlias) || !isset($this->repositories[$repositoryAlias])) { + throw new InvalidRepositoryException( + "Undefined Repository '$repositoryAlias'. Check if the Repository is configured in your project's ibexa.yaml." + ); + } + + return ['alias' => $repositoryAlias] + $this->repositories[$repositoryAlias]; + } + + public function getCurrentRepositoryAlias(): string + { + return $this->getRepositoryConfig()['alias']; + } + + public function getDefaultRepositoryAlias(): ?string + { + $aliases = array_keys($this->repositories); + + return array_shift($aliases); + } + + public function getStorageConnectionName(): string + { + $repositoryConfig = $this->getRepositoryConfig(); + + return $repositoryConfig[self::REPOSITORY_STORAGE][self::REPOSITORY_CONNECTION] ?? self::DEFAULT_CONNECTION_NAME; + } +} diff --git a/src/lib/Helper/FieldsGroups/RepositoryConfigFieldsGroupsListFactory.php b/src/lib/Helper/FieldsGroups/RepositoryConfigFieldsGroupsListFactory.php index 9c44ca199e..4d1be2ac68 100644 --- a/src/lib/Helper/FieldsGroups/RepositoryConfigFieldsGroupsListFactory.php +++ b/src/lib/Helper/FieldsGroups/RepositoryConfigFieldsGroupsListFactory.php @@ -7,23 +7,25 @@ namespace Ibexa\Core\Helper\FieldsGroups; -use Ibexa\Bundle\Core\ApiLoader\RepositoryConfigurationProvider; +use Ibexa\Contracts\Core\Container\ApiLoader\RepositoryConfigurationProviderInterface; use Symfony\Contracts\Translation\TranslatorInterface; /** * Builds a SettingsFieldGroupsList. */ -final class RepositoryConfigFieldsGroupsListFactory +final readonly class RepositoryConfigFieldsGroupsListFactory { - /** @var \Ibexa\Bundle\Core\ApiLoader\RepositoryConfigurationProvider */ - private $configProvider; + private RepositoryConfigurationProviderInterface $configProvider; - public function __construct(RepositoryConfigurationProvider $configProvider) + public function __construct(RepositoryConfigurationProviderInterface $configProvider) { $this->configProvider = $configProvider; } - public function build(TranslatorInterface $translator) + /** + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException + */ + public function build(TranslatorInterface $translator): FieldsGroupsList { $repositoryConfig = $this->configProvider->getRepositoryConfig(); diff --git a/tests/bundle/Core/ApiLoader/BaseRepositoryConfigurationProviderTestCase.php b/tests/bundle/Core/ApiLoader/BaseRepositoryConfigurationProviderTestCase.php new file mode 100644 index 0000000000..cf23826e4f --- /dev/null +++ b/tests/bundle/Core/ApiLoader/BaseRepositoryConfigurationProviderTestCase.php @@ -0,0 +1,49 @@ + ['engine' => 'foo', 'connection' => 'some_connection'], + 'search' => ['engine' => 'foo_search', 'connection' => 'some_connection'], + 'fields_groups' => ['default' => 'meta', 'list' => ['content', 'meta']], + 'options' => [], + ]; + protected const array REPOSITORIES_CONFIG = [ + self::MAIN_REPOSITORY_ALIAS => self::MAIN_REPOSITORY_CONFIG, + 'another' => [ + 'storage' => ['engine' => 'bar', 'connection' => 'bar_connection'], + 'search' => ['engine' => 'bar_search', 'connection' => 'bar_search_connection'], + 'fields_groups' => ['default' => 'content', 'list' => ['meta', 'content']], + 'options' => [], + ], + ]; + + /** + * @phpstan-return TRepositoryListItemConfiguration + */ + protected function buildNormalizedSingleRepositoryConfig( + string $storageEngine, + string $storageConnection = 'default_connection' + ): array { + return [ + 'storage' => [ + 'engine' => $storageEngine, + 'connection' => $storageConnection, + ], + ] + self::MAIN_REPOSITORY_CONFIG; + } +} diff --git a/tests/bundle/Core/ApiLoader/RepositoryConfigurationProviderTest.php b/tests/bundle/Core/ApiLoader/RepositoryConfigurationProviderTest.php index 4df30aabd6..29377eea48 100644 --- a/tests/bundle/Core/ApiLoader/RepositoryConfigurationProviderTest.php +++ b/tests/bundle/Core/ApiLoader/RepositoryConfigurationProviderTest.php @@ -4,74 +4,68 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ +declare(strict_types=1); namespace Ibexa\Tests\Bundle\Core\ApiLoader; use Ibexa\Bundle\Core\ApiLoader\Exception\InvalidRepositoryException; -use Ibexa\Bundle\Core\ApiLoader\RepositoryConfigurationProvider; use Ibexa\Contracts\Core\SiteAccess\ConfigResolverInterface; -use PHPUnit\Framework\TestCase; +use Ibexa\Core\Base\Container\ApiLoader\RepositoryConfigurationProvider; +use PHPUnit\Framework\MockObject\MockObject; -class RepositoryConfigurationProviderTest extends TestCase +/** + * @covers \Ibexa\Core\Base\Container\ApiLoader\RepositoryConfigurationProvider + * + * @phpstan-import-type TRepositoryListConfiguration from \Ibexa\Core\Base\Container\ApiLoader\RepositoryConfigurationProvider + */ +final class RepositoryConfigurationProviderTest extends BaseRepositoryConfigurationProviderTestCase { - public function testGetRepositoryConfigSpecifiedRepository() + /** + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException + */ + public function testGetRepositoryConfigSpecifiedRepository(): void { $configResolver = $this->getConfigResolverMock(); - $repositoryAlias = 'main'; - $repositoryConfig = [ - 'engine' => 'foo', - 'connection' => 'some_connection', - ]; - $repositories = [ - $repositoryAlias => $repositoryConfig, - 'another' => [ - 'engine' => 'bar', - ], - ]; - $provider = new RepositoryConfigurationProvider($configResolver, $repositories); + // providing normalized configuration, expected at this point + // see \Ibexa\Bundle\Core\DependencyInjection\Configuration::addRepositoriesSection for more details + $provider = new RepositoryConfigurationProvider($configResolver, self::REPOSITORIES_CONFIG); $configResolver - ->expects(self::once()) ->method('getParameter') ->with('repository') - ->will(self::returnValue($repositoryAlias)); + ->willReturn(self::MAIN_REPOSITORY_ALIAS); self::assertSame( - ['alias' => $repositoryAlias] + $repositoryConfig, + ['alias' => self::MAIN_REPOSITORY_ALIAS] + self::MAIN_REPOSITORY_CONFIG, $provider->getRepositoryConfig() ); } - public function testGetRepositoryConfigNotSpecifiedRepository() + /** + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException + */ + public function testGetRepositoryConfigNotSpecifiedRepository(): void { $configResolver = $this->getConfigResolverMock(); - $repositoryAlias = 'main'; - $repositoryConfig = [ - 'engine' => 'foo', - 'connection' => 'some_connection', - ]; - $repositories = [ - $repositoryAlias => $repositoryConfig, - 'another' => [ - 'engine' => 'bar', - ], - ]; - $provider = new RepositoryConfigurationProvider($configResolver, $repositories); + $provider = new RepositoryConfigurationProvider($configResolver, self::REPOSITORIES_CONFIG); $configResolver - ->expects(self::once()) ->method('getParameter') ->with('repository') - ->will(self::returnValue(null)); + ->willReturn(null); self::assertSame( - ['alias' => $repositoryAlias] + $repositoryConfig, + ['alias' => self::MAIN_REPOSITORY_ALIAS] + self::MAIN_REPOSITORY_CONFIG, $provider->getRepositoryConfig() ); } /** * @dataProvider providerForRepositories + * + * @phpstan-param TRepositoryListConfiguration $repositories + * + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException */ public function testGetRepositoryConfigUndefinedRepository(array $repositories): void { @@ -80,17 +74,20 @@ public function testGetRepositoryConfigUndefinedRepository(array $repositories): $configResolver = $this->getConfigResolverMock(); $configResolver - ->expects(self::once()) ->method('getParameter') ->with('repository') - ->will(self::returnValue('undefined_repository')); + ->willReturn('undefined_repository'); $provider = new RepositoryConfigurationProvider($configResolver, $repositories); - $provider->getRepositoryConfig(); + self::assertSame([], $provider->getRepositoryConfig()); } /** * @dataProvider providerForRepositories + * + * @phpstan-param TRepositoryListConfiguration $repositories + * + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException */ public function testGetDefaultRepositoryAlias(array $repositories): void { @@ -99,11 +96,13 @@ public function testGetDefaultRepositoryAlias(array $repositories): void $provider = new RepositoryConfigurationProvider($configResolver, $repositories); $provider->getRepositoryConfig(); - self::assertSame('first', $provider->getDefaultRepositoryAlias()); + self::assertSame(self::MAIN_REPOSITORY_ALIAS, $provider->getDefaultRepositoryAlias()); } /** * @dataProvider providerForRepositories + * + * @phpstan-param TRepositoryListConfiguration $repositories */ public function testGetCurrentRepositoryAlias(array $repositories): void { @@ -112,29 +111,20 @@ public function testGetCurrentRepositoryAlias(array $repositories): void $provider = new RepositoryConfigurationProvider($configResolver, $repositories); $provider->getRepositoryConfig(); - self::assertSame('first', $provider->getCurrentRepositoryAlias()); + self::assertSame(self::MAIN_REPOSITORY_ALIAS, $provider->getCurrentRepositoryAlias()); } + /** + * @phpstan-return list> $repositories + */ public function providerForRepositories(): array { return [ - [ - [ - 'first' => [ - 'engine' => 'foo', - ], - 'second' => [ - 'engine' => 'bar', - ], - ], - ], + [self::REPOSITORIES_CONFIG], ]; } - /** - * @return \PHPUnit\Framework\MockObject\MockObject|\Ibexa\Contracts\Core\SiteAccess\ConfigResolverInterface - */ - protected function getConfigResolverMock() + protected function getConfigResolverMock(): ConfigResolverInterface & MockObject { return $this->createMock(ConfigResolverInterface::class); } diff --git a/tests/bundle/Core/ApiLoader/StorageConnectionFactoryTest.php b/tests/bundle/Core/ApiLoader/StorageConnectionFactoryTest.php index 3fb7cc5de1..b3b14a61a3 100644 --- a/tests/bundle/Core/ApiLoader/StorageConnectionFactoryTest.php +++ b/tests/bundle/Core/ApiLoader/StorageConnectionFactoryTest.php @@ -4,30 +4,29 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ +declare(strict_types=1); namespace Ibexa\Tests\Bundle\Core\ApiLoader; +use Doctrine\DBAL\Connection; use Ibexa\Bundle\Core\ApiLoader\Exception\InvalidRepositoryException; -use Ibexa\Bundle\Core\ApiLoader\RepositoryConfigurationProvider; use Ibexa\Bundle\Core\ApiLoader\StorageConnectionFactory; +use Ibexa\Contracts\Core\Container\ApiLoader\RepositoryConfigurationProviderInterface; use Ibexa\Contracts\Core\SiteAccess\ConfigResolverInterface; -use PHPUnit\Framework\TestCase; +use Ibexa\Core\Base\Container\ApiLoader\RepositoryConfigurationProvider; +use PHPUnit\Framework\MockObject\MockObject; use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\ServiceLocator; -class StorageConnectionFactoryTest extends TestCase +final class StorageConnectionFactoryTest extends BaseRepositoryConfigurationProviderTestCase { /** * @dataProvider getConnectionProvider */ - public function testGetConnection($repositoryAlias, $doctrineConnection) + public function testGetConnection(string $repositoryAlias, string $doctrineConnection): void { $repositories = [ - $repositoryAlias => [ - 'storage' => [ - 'engine' => 'legacy', - 'connection' => $doctrineConnection, - ], - ], + $repositoryAlias => $this->buildNormalizedSingleRepositoryConfig('legacy', $doctrineConnection), ]; $configResolver = $this->getConfigResolverMock(); @@ -35,31 +34,23 @@ public function testGetConnection($repositoryAlias, $doctrineConnection) ->expects(self::once()) ->method('getParameter') ->with('repository') - ->will(self::returnValue($repositoryAlias)); - - $container = $this->getContainerMock(); - $container - ->expects(self::once()) - ->method('has') - ->with("doctrine.dbal.{$doctrineConnection}_connection") - ->will(self::returnValue(true)); - $container - ->expects(self::once()) - ->method('get') - ->with("doctrine.dbal.{$doctrineConnection}_connection") - ->will(self::returnValue($this->getMockBuilder('Doctrine\DBAL\Connection')->disableOriginalConstructor()->getMock())); + ->willReturn($repositoryAlias) + ; $repositoryConfigurationProvider = new RepositoryConfigurationProvider($configResolver, $repositories); - $factory = new StorageConnectionFactory($repositoryConfigurationProvider); - $factory->setContainer($container); - $connection = $factory->getConnection(); - self::assertInstanceOf( - 'Doctrine\DBAL\Connection', - $connection + $factory = $this->buildStorageConnectionFactory( + $repositoryConfigurationProvider, + $doctrineConnection, + [$doctrineConnection => "doctrine.dbal.{$doctrineConnection}_connection"] ); + $connection = $factory->getConnection(); + self::assertInstanceOf(Connection::class, $connection); } - public function getConnectionProvider() + /** + * @return list + */ + public static function getConnectionProvider(): array { return [ ['my_repository', 'my_doctrine_connection'], @@ -68,17 +59,15 @@ public function getConnectionProvider() ]; } - public function testGetConnectionInvalidRepository() + /** + * @throws \Psr\Container\ContainerExceptionInterface + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException + * @throws \Psr\Container\NotFoundExceptionInterface + */ + public function testGetConnectionInvalidRepository(): void { - $this->expectException(InvalidRepositoryException::class); - $repositories = [ - 'foo' => [ - 'storage' => [ - 'engine' => 'legacy', - 'connection' => 'my_doctrine_connection', - ], - ], + 'foo' => $this->buildNormalizedSingleRepositoryConfig('legacy', 'my_doctrine_connection'), ]; $configResolver = $this->getConfigResolverMock(); @@ -86,19 +75,19 @@ public function testGetConnectionInvalidRepository() ->expects(self::once()) ->method('getParameter') ->with('repository') - ->will(self::returnValue('inexistent_repository')); + ->willReturn('nonexistent_repository') + ; $repositoryConfigurationProvider = new RepositoryConfigurationProvider($configResolver, $repositories); - $factory = new StorageConnectionFactory($repositoryConfigurationProvider); - $factory->setContainer($this->getContainerMock()); + $factory = $this->buildStorageConnectionFactory($repositoryConfigurationProvider); + + $this->expectException(InvalidRepositoryException::class); $factory->getConnection(); } - public function testGetConnectionInvalidConnection() + public function testGetConnectionInvalidConnection(): void { - $this->expectException(\InvalidArgumentException::class); - - $repositoryConfigurationProviderMock = $this->createMock(RepositoryConfigurationProvider::class); + $repositoryConfigurationProviderMock = $this->createMock(RepositoryConfigurationProviderInterface::class); $repositoryConfig = [ 'alias' => 'foo', 'storage' => [ @@ -109,31 +98,59 @@ public function testGetConnectionInvalidConnection() $repositoryConfigurationProviderMock ->expects(self::once()) ->method('getRepositoryConfig') - ->will(self::returnValue($repositoryConfig)); + ->willReturn($repositoryConfig) + ; + + $factory = $this->buildStorageConnectionFactory( + $repositoryConfigurationProviderMock, + 'my_doctrine_connection', + [ + 'default' => 'doctrine.dbal.default_connection', + 'foo' => 'doctrine.dbal.foo_connection', + ] + ); - $container = $this->getContainerMock(); - $container - ->expects(self::once()) - ->method('has') - ->with('doctrine.dbal.my_doctrine_connection_connection') - ->will(self::returnValue(false)); - $container - ->expects(self::once()) - ->method('getParameter') - ->with('doctrine.connections') - ->will(self::returnValue([])); - $factory = new StorageConnectionFactory($repositoryConfigurationProviderMock); - $factory->setContainer($container); + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage( + 'Invalid Doctrine connection \'my_doctrine_connection\' for Repository \'foo\'. Valid connections are: default, foo' + ); $factory->getConnection(); } - protected function getConfigResolverMock() + protected function getConfigResolverMock(): ConfigResolverInterface & MockObject { return $this->createMock(ConfigResolverInterface::class); } - protected function getContainerMock() + protected function getContainerMock(): ContainerInterface & MockObject { return $this->createMock(ContainerInterface::class); } + + /** + * @param array $doctrineConnections + */ + private function buildStorageConnectionFactory( + RepositoryConfigurationProviderInterface $repositoryConfigurationProvider, + string $connectionName = 'default', + array $doctrineConnections = ['default' => 'doctrine.dbal.default_connection'] + ): StorageConnectionFactory { + $serviceLocatorMock = $this->createMock(ServiceLocator::class); + $serviceLocatorMock + ->method('has') + ->with($connectionName) + ->willReturn(isset($doctrineConnections[$connectionName])) + ; + $serviceLocatorMock->method('getProvidedServices')->willReturn($doctrineConnections); + if (isset($doctrineConnections[$connectionName])) { + $serviceLocatorMock->method('get')->with($connectionName)->willReturn($this->createMock(Connection::class)); + } else { + $serviceLocatorMock->expects(self::never())->method('get'); + } + + return new StorageConnectionFactory( + $repositoryConfigurationProvider, + $serviceLocatorMock + ); + } } diff --git a/tests/bundle/Core/ApiLoader/StorageEngineFactoryTest.php b/tests/bundle/Core/ApiLoader/StorageEngineFactoryTest.php index 77dff32931..cdc606e79a 100644 --- a/tests/bundle/Core/ApiLoader/StorageEngineFactoryTest.php +++ b/tests/bundle/Core/ApiLoader/StorageEngineFactoryTest.php @@ -8,18 +8,18 @@ namespace Ibexa\Tests\Bundle\Core\ApiLoader; use Ibexa\Bundle\Core\ApiLoader\Exception\InvalidStorageEngine; -use Ibexa\Bundle\Core\ApiLoader\RepositoryConfigurationProvider; use Ibexa\Bundle\Core\ApiLoader\StorageEngineFactory; +use Ibexa\Contracts\Core\Container\ApiLoader\RepositoryConfigurationProviderInterface; use Ibexa\Contracts\Core\Persistence\Handler; use Ibexa\Contracts\Core\SiteAccess\ConfigResolverInterface; -use PHPUnit\Framework\TestCase; +use Ibexa\Core\Base\Container\ApiLoader\RepositoryConfigurationProvider; +use PHPUnit\Framework\MockObject\MockObject; -class StorageEngineFactoryTest extends TestCase +final class StorageEngineFactoryTest extends BaseRepositoryConfigurationProviderTestCase { - public function testRegisterStorageEngine() + public function testRegisterStorageEngine(): void { - /** @var \Ibexa\Bundle\Core\ApiLoader\RepositoryConfigurationProvider $repositoryConfigurationProvider */ - $repositoryConfigurationProvider = $this->createMock(RepositoryConfigurationProvider::class); + $repositoryConfigurationProvider = $this->createMock(RepositoryConfigurationProviderInterface::class); $factory = new StorageEngineFactory($repositoryConfigurationProvider); $storageEngines = [ @@ -35,21 +35,13 @@ public function testRegisterStorageEngine() self::assertSame($storageEngines, $factory->getStorageEngines()); } - public function testBuildStorageEngine() + public function testBuildStorageEngine(): void { $configResolver = $this->getConfigResolverMock(); $repositoryAlias = 'main'; $repositories = [ - $repositoryAlias => [ - 'storage' => [ - 'engine' => 'foo', - ], - ], - 'another' => [ - 'storage' => [ - 'engine' => 'bar', - ], - ], + $repositoryAlias => $this->buildNormalizedSingleRepositoryConfig('foo'), + 'another' => $this->buildNormalizedSingleRepositoryConfig('bar'), ]; $expectedStorageEngine = $this->getPersistenceHandlerMock(); $storageEngines = [ @@ -67,28 +59,21 @@ public function testBuildStorageEngine() ->expects(self::once()) ->method('getParameter') ->with('repository') - ->will(self::returnValue($repositoryAlias)); + ->willReturn($repositoryAlias) + ; self::assertSame($expectedStorageEngine, $factory->buildStorageEngine()); } - public function testBuildInvalidStorageEngine() + public function testBuildInvalidStorageEngine(): void { $this->expectException(InvalidStorageEngine::class); $configResolver = $this->getConfigResolverMock(); $repositoryAlias = 'main'; $repositories = [ - $repositoryAlias => [ - 'storage' => [ - 'engine' => 'undefined_storage_engine', - ], - ], - 'another' => [ - 'storage' => [ - 'engine' => 'bar', - ], - ], + $repositoryAlias => $this->buildNormalizedSingleRepositoryConfig('undefined_storage_engine'), + 'another' => $this->buildNormalizedSingleRepositoryConfig('bar'), ]; $storageEngines = [ @@ -107,20 +92,18 @@ public function testBuildInvalidStorageEngine() ->expects(self::once()) ->method('getParameter') ->with('repository') - ->will(self::returnValue($repositoryAlias)); + ->willReturn($repositoryAlias) + ; self::assertSame($this->getPersistenceHandlerMock(), $factory->buildStorageEngine()); } - /** - * @return \PHPUnit\Framework\MockObject\MockObject|\Ibexa\Contracts\Core\SiteAccess\ConfigResolverInterface - */ - protected function getConfigResolverMock() + protected function getConfigResolverMock(): ConfigResolverInterface & MockObject { return $this->createMock(ConfigResolverInterface::class); } - protected function getPersistenceHandlerMock() + protected function getPersistenceHandlerMock(): Handler & MockObject { return $this->createMock(Handler::class); } diff --git a/tests/bundle/Core/DependencyInjection/Compiler/EntityManagerFactoryServiceLocatorPassTest.php b/tests/bundle/Core/DependencyInjection/Compiler/EntityManagerFactoryServiceLocatorPassTest.php index 171796b2fd..ed804bd17a 100644 --- a/tests/bundle/Core/DependencyInjection/Compiler/EntityManagerFactoryServiceLocatorPassTest.php +++ b/tests/bundle/Core/DependencyInjection/Compiler/EntityManagerFactoryServiceLocatorPassTest.php @@ -8,8 +8,8 @@ namespace Ibexa\Tests\Bundle\Core\DependencyInjection\Compiler; -use Ibexa\Bundle\Core\ApiLoader\RepositoryConfigurationProvider; use Ibexa\Bundle\Core\DependencyInjection\Compiler\EntityManagerFactoryServiceLocatorPass; +use Ibexa\Contracts\Core\Container\ApiLoader\RepositoryConfigurationProviderInterface; use Matthias\SymfonyDependencyInjectionTest\PhpUnit\AbstractCompilerPassTestCase; use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -25,7 +25,7 @@ protected function setUp(): void $this->setDefinition( 'ibexa.doctrine.orm.entity_manager_factory', new Definition(null, [ - '$repositoryConfigurationProvider' => new Reference(RepositoryConfigurationProvider::class), + '$repositoryConfigurationProvider' => new Reference(RepositoryConfigurationProviderInterface::class), '$defaultConnection' => '%doctrine.default_connection%', '$entityManagers' => '%doctrine.entity_managers%', ]) diff --git a/tests/bundle/Core/DependencyInjection/Compiler/StorageConnectionFactoryPassTest.php b/tests/bundle/Core/DependencyInjection/Compiler/StorageConnectionFactoryPassTest.php new file mode 100644 index 0000000000..1d06c290ba --- /dev/null +++ b/tests/bundle/Core/DependencyInjection/Compiler/StorageConnectionFactoryPassTest.php @@ -0,0 +1,59 @@ + 'doctrine.dbal.default_connection']; + + $this->container->setParameter('doctrine.connections', $doctrineConnections); + $this->setDefinition( + StorageConnectionFactory::class, + new Definition( + StorageConnectionFactory::class, + [ + '$doctrineConnections' => $doctrineConnections, + '$serviceLocator' => null, + ] + ) + ); + } + + protected function registerCompilerPass(ContainerBuilder $container): void + { + $container->addCompilerPass(new StorageConnectionFactoryPass()); + } + + public function testProcess(): void + { + $this->compile(); + + $this->assertContainerBuilderHasServiceDefinitionWithServiceLocatorArgument( + StorageConnectionFactory::class, + '$serviceLocator', + [ + 'default' => new Reference('doctrine.dbal.default_connection'), + ] + ); + } +} diff --git a/tests/bundle/Core/Entity/EntityManagerFactoryTest.php b/tests/bundle/Core/Entity/EntityManagerFactoryTest.php index c98e0952b4..aa0c446e74 100644 --- a/tests/bundle/Core/Entity/EntityManagerFactoryTest.php +++ b/tests/bundle/Core/Entity/EntityManagerFactoryTest.php @@ -9,9 +9,10 @@ namespace Ibexa\Tests\Bundle\Core\Entity; use Doctrine\ORM\EntityManagerInterface; -use Ibexa\Bundle\Core\ApiLoader\RepositoryConfigurationProvider; use Ibexa\Bundle\Core\Entity\EntityManagerFactory; +use Ibexa\Contracts\Core\Container\ApiLoader\RepositoryConfigurationProviderInterface; use InvalidArgumentException; +use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Symfony\Component\DependencyInjection\ServiceLocator; @@ -25,8 +26,7 @@ class EntityManagerFactoryTest extends TestCase 'ibexa_invalid' => self::INVALID_ENTITY_MANAGER, ]; - /** @var \Ibexa\Bundle\Core\ApiLoader\RepositoryConfigurationProvider */ - private $repositoryConfigurationProvider; + private RepositoryConfigurationProviderInterface & MockObject $repositoryConfigurationProvider; /** @var \Doctrine\ORM\EntityManagerInterface */ private $entityManager; @@ -132,12 +132,9 @@ public function testGetEntityManagerInvalid(): void $entityManagerFactory->getEntityManager(); } - /** - * @return \Ibexa\Bundle\Core\ApiLoader\RepositoryConfigurationProvider|\PHPUnit\Framework\MockObject\MockObject - */ - protected function getRepositoryConfigurationProvider(): RepositoryConfigurationProvider + protected function getRepositoryConfigurationProvider(): RepositoryConfigurationProviderInterface & MockObject { - return $this->createMock(RepositoryConfigurationProvider::class); + return $this->createMock(RepositoryConfigurationProviderInterface::class); } /** diff --git a/tests/lib/Helper/FieldsGroups/RepositoryConfigFieldsGroupsListFactoryTest.php b/tests/lib/Helper/FieldsGroups/RepositoryConfigFieldsGroupsListFactoryTest.php index 2d6928f36e..3c9c7e8f56 100644 --- a/tests/lib/Helper/FieldsGroups/RepositoryConfigFieldsGroupsListFactoryTest.php +++ b/tests/lib/Helper/FieldsGroups/RepositoryConfigFieldsGroupsListFactoryTest.php @@ -7,18 +7,19 @@ namespace Ibexa\Tests\Core\Helper\FieldsGroups; -use Ibexa\Bundle\Core\ApiLoader\RepositoryConfigurationProvider; +use Ibexa\Contracts\Core\Container\ApiLoader\RepositoryConfigurationProviderInterface; use Ibexa\Core\Helper\FieldsGroups\RepositoryConfigFieldsGroupsListFactory; +use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Symfony\Contracts\Translation\TranslatorInterface; class RepositoryConfigFieldsGroupsListFactoryTest extends TestCase { - private $repositoryConfigMock; + private RepositoryConfigurationProviderInterface & MockObject $repositoryConfigMock; - private $translatorMock; + private TranslatorInterface & MockObject $translatorMock; - public function testBuild() + public function testBuild(): void { $this->getRepositoryConfigMock() ->expects(self::once()) @@ -26,9 +27,8 @@ public function testBuild() ->willReturn(['fields_groups' => ['list' => ['group_a', 'group_b'], 'default' => 'group_a']]); $this->getTranslatorMock() - ->expects(self::any()) ->method('trans') - ->will(self::returnArgument(0)); + ->willReturnArgument(0); $factory = new RepositoryConfigFieldsGroupsListFactory($this->getRepositoryConfigMock()); $list = $factory->build($this->getTranslatorMock()); @@ -37,22 +37,16 @@ public function testBuild() self::assertEquals('group_a', $list->getDefaultGroup()); } - /** - * @return \PHPUnit\Framework\MockObject\MockObject|\Ibexa\Bundle\Core\ApiLoader\RepositoryConfigurationProvider - */ - protected function getRepositoryConfigMock() + protected function getRepositoryConfigMock(): RepositoryConfigurationProviderInterface & MockObject { if (!isset($this->repositoryConfigMock)) { - $this->repositoryConfigMock = $this->createMock(RepositoryConfigurationProvider::class); + $this->repositoryConfigMock = $this->createMock(RepositoryConfigurationProviderInterface::class); } return $this->repositoryConfigMock; } - /** - * @return \PHPUnit\Framework\MockObject\MockObject|\Symfony\Contracts\Translation\TranslatorInterface - */ - protected function getTranslatorMock() + protected function getTranslatorMock(): TranslatorInterface & MockObject { if (!isset($this->translatorMock)) { $this->translatorMock = $this->createMock(TranslatorInterface::class);