From 4508a9fe035581eb880ccbf47c5d7b60d85427c5 Mon Sep 17 00:00:00 2001 From: Alexander Schranz Date: Thu, 11 Mar 2021 15:47:14 +0100 Subject: [PATCH 1/7] Add basic configuration for content bundle storage --- .github/workflows/test-application.yaml | 2 - Article/Domain/Model/Article.php | 39 ++++ Article/Domain/Model/ArticleInterface.php | 25 +++ DependencyInjection/Configuration.php | 26 ++- DependencyInjection/SuluArticleExtension.php | 167 +++++++++++++++--- .../config/doctrine/Article/Article.orm.xml | 14 ++ Resources/config/services.xml | 6 + Resources/doc/installation.md | 1 + SuluArticleBundle.php | 38 +++- Tests/Application/Kernel.php | 17 ++ Tests/Application/config/config.yml | 42 ----- .../config/config_experimental.yml | 4 + Tests/Application/config/config_phpcr.yml | 27 +++ .../Unit/Article/Domain/Model/ArticleTest.php | 40 +++++ UPGRADE.md | 11 ++ composer.json | 14 +- 16 files changed, 397 insertions(+), 76 deletions(-) create mode 100644 Article/Domain/Model/Article.php create mode 100644 Article/Domain/Model/ArticleInterface.php create mode 100644 Resources/config/doctrine/Article/Article.orm.xml create mode 100644 Tests/Application/config/config_experimental.yml create mode 100644 Tests/Application/config/config_phpcr.yml create mode 100644 Tests/Unit/Article/Domain/Model/ArticleTest.php diff --git a/.github/workflows/test-application.yaml b/.github/workflows/test-application.yaml index 6bed923d6..02871301e 100644 --- a/.github/workflows/test-application.yaml +++ b/.github/workflows/test-application.yaml @@ -41,7 +41,6 @@ jobs: dependency-versions: 'highest' php-extensions: 'ctype, iconv, mysql, imagick' tools: 'composer:v2' - phpstan: true lint: true env: SYMFONY_DEPRECATIONS_HELPER: weak @@ -54,7 +53,6 @@ jobs: dependency-versions: 'highest' php-extensions: 'ctype, iconv, mysql, imagick' tools: 'composer:v2' - phpstan: false lint: false env: SYMFONY_DEPRECATIONS_HELPER: weak diff --git a/Article/Domain/Model/Article.php b/Article/Domain/Model/Article.php new file mode 100644 index 000000000..afd7a2b4f --- /dev/null +++ b/Article/Domain/Model/Article.php @@ -0,0 +1,39 @@ +id = $id ?: Uuid::uuid4()->toString(); + } + + public function getId(): string + { + return $this->id; + } +} diff --git a/Article/Domain/Model/ArticleInterface.php b/Article/Domain/Model/ArticleInterface.php new file mode 100644 index 000000000..d626e41ef --- /dev/null +++ b/Article/Domain/Model/ArticleInterface.php @@ -0,0 +1,25 @@ +children() - ->scalarNode('index_name')->isRequired()->end() + ->arrayNode('article') + ->addDefaultsIfNotSet() + ->children() + ->enumNode('storage') + ->values([self::ARTICLE_STORAGE_PHPCR, self::ARTICLE_STORAGE_EXPERIMENTAL]) + ->defaultValue(self::ARTICLE_STORAGE_PHPCR) + ->end() + ->arrayNode('objects') + ->addDefaultsIfNotSet() + ->children() + ->arrayNode('article') + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('model')->defaultValue(Article::class)->end() + ->end() + ->end() + ->end() + ->end() + ->end() + ->end() + ->scalarNode('index_name')->end() ->arrayNode('hosts') ->prototype('scalar')->end() ->end() diff --git a/DependencyInjection/SuluArticleExtension.php b/DependencyInjection/SuluArticleExtension.php index 0d0418fd9..5b0a7774e 100644 --- a/DependencyInjection/SuluArticleExtension.php +++ b/DependencyInjection/SuluArticleExtension.php @@ -11,6 +11,7 @@ namespace Sulu\Bundle\ArticleBundle\DependencyInjection; +use Sulu\Bundle\ArticleBundle\Article\Domain\Model\ArticleInterface; use Sulu\Bundle\ArticleBundle\Document\ArticleDocument; use Sulu\Bundle\ArticleBundle\Document\ArticlePageDocument; use Sulu\Bundle\ArticleBundle\Document\Form\ArticleDocumentType; @@ -19,6 +20,7 @@ use Sulu\Bundle\ArticleBundle\Document\Structure\ArticlePageBridge; use Sulu\Bundle\ArticleBundle\Exception\ArticlePageNotFoundException; use Sulu\Bundle\ArticleBundle\Exception\ParameterNotAllowedException; +use Sulu\Bundle\PersistenceBundle\DependencyInjection\PersistenceExtensionTrait; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface; @@ -30,12 +32,65 @@ */ class SuluArticleExtension extends Extension implements PrependExtensionInterface { + use PersistenceExtensionTrait; + /** * {@inheritdoc} */ public function prepend(ContainerBuilder $container) { - if ($container->hasExtension('sulu_core')) { + $configs = $container->getExtensionConfig($this->getAlias()); + $resolvingBag = $container->getParameterBag(); + $configs = $resolvingBag->resolveValue($configs); + $config = $this->processConfiguration(new Configuration(), $configs); + + $storage = $config['article']['storage']; + $isPHPCRStorage = Configuration::ARTICLE_STORAGE_PHPCR === $storage; + $isExperimentalStorage = Configuration::ARTICLE_STORAGE_EXPERIMENTAL === $storage; + + if ($isExperimentalStorage && $container->hasExtension('doctrine')) { + $container->prependExtensionConfig( + 'doctrine', + [ + 'orm' => [ + 'mappings' => [ + 'SuluBundleArticle' => [ + 'type' => 'xml', + 'prefix' => 'Sulu\Bundle\ArticleBundle\Article\Domain\Model', + 'dir' => \dirname(__DIR__) . '/Resources/config/doctrine/Article', + 'alias' => 'SuluArticleBundle', + 'is_bundle' => false, + 'mapping' => true, + ], + ], + ], + ] + ); + } + + if ($isExperimentalStorage && $container->hasExtension('sulu_core')) { + $container->prependExtensionConfig( + 'sulu_core', + [ + 'content' => [ + 'structure' => [ + 'paths' => [ + ArticleInterface::TEMPLATE_TYPE => [ + 'path' => '%kernel.project_dir%/config/templates/articles', + 'type' => 'article', + ], + ], + 'default_type' => [ + ArticleInterface::TEMPLATE_TYPE => 'default', + ], + ], + ], + ] + ); + } + + if ($isPHPCRStorage && $container->hasExtension('sulu_core')) { + // can be removed when phpcr storage is removed $container->prependExtensionConfig( 'sulu_core', [ @@ -61,7 +116,8 @@ public function prepend(ContainerBuilder $container) ); } - if ($container->hasExtension('sulu_route')) { + if ($isPHPCRStorage && $container->hasExtension('sulu_route')) { + // can be removed when phpcr storage is removed $container->prependExtensionConfig( 'sulu_route', [ @@ -77,6 +133,23 @@ public function prepend(ContainerBuilder $container) ); } + if ($isExperimentalStorage && $container->hasExtension('sulu_route')) { + $container->prependExtensionConfig( + 'sulu_route', + [ + 'mappings' => [ + ArticleInterface::class => [ + 'generator' => 'schema', + 'options' => [ + 'route_schema' => '/{object["title"]}', + ], + 'resource_key' => ArticleInterface::RESOURCE_KEY, + ], + ], + ] + ); + } + if ($container->hasExtension('jms_serializer')) { $container->prependExtensionConfig( 'jms_serializer', @@ -93,7 +166,8 @@ public function prepend(ContainerBuilder $container) ); } - if ($container->hasExtension('sulu_search')) { + if ($isPHPCRStorage && $container->hasExtension('sulu_search')) { + // can be removed when phpcr storage is removed $container->prependExtensionConfig( 'sulu_page', [ @@ -107,7 +181,27 @@ public function prepend(ContainerBuilder $container) ); } - if ($container->hasExtension('sulu_document_manager')) { + if ($isExperimentalStorage && $container->hasExtension('sulu_search')) { + $suluSearchConfigs = $container->getExtensionConfig('sulu_search'); + + foreach ($suluSearchConfigs as $suluSearchConfig) { + if (isset($suluSearchConfig['website']['indexes'])) { + $container->prependExtensionConfig( + 'sulu_search', + [ + 'website' => [ + 'indexes' => [ + ArticleInterface::RESOURCE_KEY => ArticleInterface::RESOURCE_KEY . '_published', + ], + ], + ] + ); + } + } + } + + if ($isPHPCRStorage && $container->hasExtension('sulu_document_manager')) { + // can be removed when phpcr storage is removed $container->prependExtensionConfig( 'sulu_document_manager', [ @@ -130,7 +224,8 @@ public function prepend(ContainerBuilder $container) ); } - if ($container->hasExtension('fos_js_routing')) { + if ($isPHPCRStorage && $container->hasExtension('fos_js_routing')) { + // can be removed when phpcr storage is removed $container->prependExtensionConfig( 'fos_js_routing', [ @@ -141,7 +236,8 @@ public function prepend(ContainerBuilder $container) ); } - if ($container->hasExtension('fos_rest')) { + if ($isPHPCRStorage && $container->hasExtension('fos_rest')) { + // can be removed when phpcr storage is removed $container->prependExtensionConfig( 'fos_rest', [ @@ -155,7 +251,8 @@ public function prepend(ContainerBuilder $container) ); } - if ($container->hasExtension('massive_build')) { + if ($isPHPCRStorage && $container->hasExtension('massive_build')) { + // can be removed when phpcr storage is removed $container->prependExtensionConfig( 'massive_build', [ @@ -246,7 +343,8 @@ public function prepend(ContainerBuilder $container) ); } - if ($container->hasExtension('ongr_elasticsearch')) { + if ($isPHPCRStorage && $container->hasExtension('ongr_elasticsearch')) { + // can be removed when phpcr storage is removed $configs = $container->getExtensionConfig($this->getAlias()); $config = $this->processConfiguration(new Configuration(), $configs); @@ -289,41 +387,62 @@ public function load(array $configs, ContainerBuilder $container) { $configuration = new Configuration(); $config = $this->processConfiguration($configuration, $configs); + + $storage = $config['article']['storage']; + $container->setParameter('sulu_article.article_storage', $storage); + $isPHPCRStorage = Configuration::ARTICLE_STORAGE_PHPCR === $storage; + $isExperimentalStorage = Configuration::ARTICLE_STORAGE_EXPERIMENTAL === $storage; + $container->setParameter('sulu_article.default_main_webspace', $config['default_main_webspace']); $container->setParameter('sulu_article.default_additional_webspaces', $config['default_additional_webspaces']); $container->setParameter('sulu_article.types', $config['types']); - $container->setParameter('sulu_article.documents', $config['documents']); - $container->setParameter('sulu_article.view_document.article.class', $config['documents']['article']['view']); $container->setParameter('sulu_article.display_tab_all', $config['display_tab_all']); $container->setParameter('sulu_article.smart_content.default_limit', $config['smart_content']['default_limit']); $container->setParameter('sulu_article.search_fields', $config['search_fields']); + if ($isPHPCRStorage) { + // can be removed when phpcr storage is removed + $container->setParameter('sulu_article.documents', $config['documents']); + $container->setParameter('sulu_article.view_document.article.class', $config['documents']['article']['view']); + } + $loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); - $loader->load('services.xml'); + + if ($isPHPCRStorage) { + // can be removed when phpcr storage is removed + $loader->load('services.xml'); + } + + if ($isExperimentalStorage) { + $this->configurePersistence($config['article']['objects'], $container); + } $bundles = $container->getParameter('kernel.bundles'); if (array_key_exists('SuluAutomationBundle', $bundles)) { $loader->load('automation.xml'); } - $this->appendDefaultAuthor($config, $container); - $this->appendArticlePageConfig($container); + if ($isPHPCRStorage) { + // can be removed when phpcr storage is removed + $this->appendDefaultAuthor($config, $container); + $this->appendArticlePageConfig($container); - $articleDocument = ArticleDocument::class; - $articlePageDocument = ArticlePageDocument::class; + $articleDocument = ArticleDocument::class; + $articlePageDocument = ArticlePageDocument::class; - foreach ($container->getParameter('sulu_document_manager.mapping') as $mapping) { - if ('article' == $mapping['alias']) { - $articleDocument = $mapping['class']; - } + foreach ($container->getParameter('sulu_document_manager.mapping') as $mapping) { + if ('article' == $mapping['alias']) { + $articleDocument = $mapping['class']; + } - if ('article_page' == $mapping['alias']) { - $articlePageDocument = $mapping['class']; + if ('article_page' == $mapping['alias']) { + $articlePageDocument = $mapping['class']; + } } - } - $container->setParameter('sulu_article.article_document.class', $articleDocument); - $container->setParameter('sulu_article.article_page_document.class', $articlePageDocument); + $container->setParameter('sulu_article.article_document.class', $articleDocument); + $container->setParameter('sulu_article.article_page_document.class', $articlePageDocument); + } } /** diff --git a/Resources/config/doctrine/Article/Article.orm.xml b/Resources/config/doctrine/Article/Article.orm.xml new file mode 100644 index 000000000..2ad383d86 --- /dev/null +++ b/Resources/config/doctrine/Article/Article.orm.xml @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/Resources/config/services.xml b/Resources/config/services.xml index 8a578e64c..d55c26c6e 100644 --- a/Resources/config/services.xml +++ b/Resources/config/services.xml @@ -2,6 +2,12 @@ + + @SuluArticle/Export/Article/1.2.xliff.twig diff --git a/Resources/doc/installation.md b/Resources/doc/installation.md index 5d8532b68..18180acb6 100644 --- a/Resources/doc/installation.md +++ b/Resources/doc/installation.md @@ -8,6 +8,7 @@ The SuluArticleBundle requires a running elasticsearch `^5.0`, `^6.0` or `^7.0`. ```bash composer require "elasticsearch/elasticsearch:7.9.*" # should match version of your elasticsearch installation +composer require "handcraftedinthealps/elasticsearch-bundle:^5.2" composer require sulu/article-bundle ``` diff --git a/SuluArticleBundle.php b/SuluArticleBundle.php index 60e0e5a61..240d7a42b 100644 --- a/SuluArticleBundle.php +++ b/SuluArticleBundle.php @@ -11,9 +11,14 @@ namespace Sulu\Bundle\ArticleBundle; +use Sulu\Bundle\ArticleBundle\Article\Domain\Model\ArticleInterface; +use Sulu\Bundle\ArticleBundle\DependencyInjection\Configuration; use Sulu\Bundle\ArticleBundle\DependencyInjection\ConverterCompilerPass; use Sulu\Bundle\ArticleBundle\DependencyInjection\RouteEnhancerCompilerPass; use Sulu\Bundle\ArticleBundle\DependencyInjection\StructureValidatorCompilerPass; +use Sulu\Bundle\PersistenceBundle\DependencyInjection\Compiler\ResolveTargetEntitiesPass; +use Sulu\Bundle\PersistenceBundle\PersistenceBundleTrait; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\Compiler\PassConfig; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Bundle\Bundle; @@ -21,15 +26,42 @@ /** * Entry-point for article-bundle. */ -class SuluArticleBundle extends Bundle +class SuluArticleBundle extends Bundle implements CompilerPassInterface { + use PersistenceBundleTrait; + /** * {@inheritdoc} */ public function build(ContainerBuilder $container) { - $container->addCompilerPass(new ConverterCompilerPass()); + $container->addCompilerPass($this); $container->addCompilerPass(new StructureValidatorCompilerPass(), PassConfig::TYPE_AFTER_REMOVING); - $container->addCompilerPass(new RouteEnhancerCompilerPass()); + } + + public function process(ContainerBuilder $container): void + { + $interfaces = []; + + if (Configuration::ARTICLE_STORAGE_EXPERIMENTAL === $container->getParameter('sulu_article.article_storage')) { + $interfaces = \array_merge($interfaces, [ + ArticleInterface::class => 'sulu.model.article.class', + ]); + } + + $compilerPasses = []; + if (0 < \count($interfaces)) { + $compilerPasses[] = new ResolveTargetEntitiesPass($interfaces); + } + + if (Configuration::ARTICLE_STORAGE_PHPCR === $container->getParameter('sulu_article.article_storage')) { + // can be removed when phpcr storage is removed + $compilerPasses[] = new RouteEnhancerCompilerPass(); + $compilerPasses[] = new ConverterCompilerPass(); + } + + foreach ($compilerPasses as $compilerPass) { + $compilerPass->process($container); + } } } diff --git a/Tests/Application/Kernel.php b/Tests/Application/Kernel.php index 2cec8f994..9d70ea002 100644 --- a/Tests/Application/Kernel.php +++ b/Tests/Application/Kernel.php @@ -16,6 +16,7 @@ use Sulu\Bundle\ArticleBundle\Tests\Application\Testing\ArticleBundleKernelBrowser; use Sulu\Bundle\ArticleBundle\Tests\TestExtendBundle\TestExtendBundle; use Sulu\Bundle\TestBundle\Kernel\SuluTestKernel; +use Sulu\Component\HttpKernel\SuluKernel; use Symfony\Component\Config\Loader\LoaderInterface; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -25,6 +26,20 @@ */ class Kernel extends SuluTestKernel implements CompilerPassInterface { + /** + * @var string|null + */ + private $config = 'phpcr'; + + public function __construct(string $environment, bool $debug, string $suluContext = SuluKernel::CONTEXT_ADMIN) + { + $environmentParts = explode('_', $environment, 2); + $environment = $environmentParts[0]; + $this->config = $environmentParts[1] ?? $this->config; + + parent::__construct($environment, $debug, $suluContext); + } + /** * {@inheritdoc} */ @@ -53,6 +68,8 @@ public function registerContainerConfiguration(LoaderInterface $loader) } $loader->load(__DIR__ . '/config/config.yml'); + $loader->load(__DIR__ . '/config/config_' . $this->config . '.yml'); + $type = 'default'; if (getenv('ARTICLE_TEST_CASE')) { $type = getenv('ARTICLE_TEST_CASE'); diff --git a/Tests/Application/config/config.yml b/Tests/Application/config/config.yml index 684f6ef6b..cd3e3c3bc 100644 --- a/Tests/Application/config/config.yml +++ b/Tests/Application/config/config.yml @@ -1,20 +1,5 @@ # Doctrine Configuration doctrine: - dbal: - driver: pdo_mysql - host: 127.0.0.1 - port: 3306 - dbname: su_articles_test - user: root - password: - server_version: '5.7' - url: '%env(DATABASE_URL)%' - - charset: '%env(DATABASE_CHARSET)%' - default_table_options: - charset: '%env(DATABASE_CHARSET)%' - collate: '%env(DATABASE_COLLATE)%' - orm: mappings: gedmo_tree: @@ -23,30 +8,3 @@ doctrine: dir: "%gedmo_directory%/Tree/Entity" alias: GedmoTree is_bundle: false - -# Sulu Routing -sulu_route: - mappings: - Sulu\Bundle\ArticleBundle\Document\ArticleDocument: - generator: "schema" - options: - route_schema: "/articles/{object.getTitle()}" - Sulu\Bundle\ArticleBundle\Document\ArticlePageDocument: - generator: "article_page" - options: - route_schema: "/{translator.trans(\"page\")}-{object.getPageNumber()}" - parent: "{object.getParent().getRoutePath()}" - -sulu_article: - index_name: "su_articles_tests" - hosts: ["%env(ELASTICSEARCH_HOST)%"] - default_main_webspace: 'sulu_io' - -ongr_elasticsearch: - analysis: - tokenizer: - pathTokenizer: - type: path_hierarchy - analyzer: - pathAnalyzer: - tokenizer: pathTokenizer diff --git a/Tests/Application/config/config_experimental.yml b/Tests/Application/config/config_experimental.yml new file mode 100644 index 000000000..fbc84c7d4 --- /dev/null +++ b/Tests/Application/config/config_experimental.yml @@ -0,0 +1,4 @@ +sulu_article: + article: + storage: 'experimental' + default_main_webspace: 'sulu_io' diff --git a/Tests/Application/config/config_phpcr.yml b/Tests/Application/config/config_phpcr.yml new file mode 100644 index 000000000..72b470ecf --- /dev/null +++ b/Tests/Application/config/config_phpcr.yml @@ -0,0 +1,27 @@ +sulu_route: + mappings: + Sulu\Bundle\ArticleBundle\Document\ArticleDocument: + generator: "schema" + options: + route_schema: "/articles/{object.getTitle()}" + Sulu\Bundle\ArticleBundle\Document\ArticlePageDocument: + generator: "article_page" + options: + route_schema: "/{translator.trans(\"page\")}-{object.getPageNumber()}" + parent: "{object.getParent().getRoutePath()}" + +sulu_article: + article: + storage: 'phpcr' + index_name: "su_articles_tests" + hosts: ["%env(ELASTICSEARCH_HOST)%"] + default_main_webspace: 'sulu_io' + +ongr_elasticsearch: + analysis: + tokenizer: + pathTokenizer: + type: path_hierarchy + analyzer: + pathAnalyzer: + tokenizer: pathTokenizer diff --git a/Tests/Unit/Article/Domain/Model/ArticleTest.php b/Tests/Unit/Article/Domain/Model/ArticleTest.php new file mode 100644 index 000000000..9aaa6292b --- /dev/null +++ b/Tests/Unit/Article/Domain/Model/ArticleTest.php @@ -0,0 +1,40 @@ +createArticle(); + + $this->assertNotNull($article->getId()); + } + + public function testGetIdCustom() + { + $article = $this->createArticle(['id' => '9dd3f8c6-f000-4a37-a780-fe8c3128526d']); + + $this->assertSame('9dd3f8c6-f000-4a37-a780-fe8c3128526d', $article->getId()); + } + + private function createArticle(array $data = []): ArticleInterface + { + return new Article( + $data['id'] ?? null + ); + } +} diff --git a/UPGRADE.md b/UPGRADE.md index cbf07a792..92c4150af 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -1,5 +1,16 @@ # Upgrade +## 2.x + +### Elasticsearch Bundle need to be required + +The SuluArticleBundle defines not longer its dependency to `handcraftedinthealps/elasticsearch-bundle` because +of the new `experimental` storage. If you update you need to require the bundle in your `composer.json`. + +```bash +composer require "handcraftedinthealps/elasticsearch-bundle:^5.2" +``` + ## 2.2.0 ### Index mapping changed diff --git a/composer.json b/composer.json index e89318b1a..6dd126c3b 100644 --- a/composer.json +++ b/composer.json @@ -20,11 +20,13 @@ "require": { "php": "^7.2 || ^8.0", "ext-json": "*", - "elasticsearch/elasticsearch": "^5.0 || ^6.0 || ^7.0", - "handcraftedinthealps/elasticsearch-bundle": "^5.2.6.4", - "handcraftedinthealps/elasticsearch-dsl": "^5.0.7.1 || ^6.2.0.1 || ^7.2.0.1", + "doctrine/collections": "^1.0", + "doctrine/orm": "^2.5.3", + "doctrine/doctrine-bundle": "^1.10 || ^2.0", + "doctrine/persistence": "^1.3 || ^2.0", "jms/serializer": "^3.3", "jms/serializer-bundle": "^3.3", + "ramsey/uuid": "^3.1 || ^4.0", "sulu/sulu": "^2.0.10 || ^2.1@dev", "symfony/config": "^4.3 || ^5.0", "symfony/dependency-injection": "^4.3 || ^5.0", @@ -34,8 +36,11 @@ "twig/twig": "^1.41 || ^2.0 || ^3.0" }, "require-dev": { - "doctrine/data-fixtures": "^1.1", + "doctrine/data-fixtures": "^1.3.3", + "elasticsearch/elasticsearch": "^5.0 || ^6.0 || ^7.0", "friendsofphp/php-cs-fixer": "^2.17", + "handcraftedinthealps/elasticsearch-bundle": "^5.2.6.4", + "handcraftedinthealps/elasticsearch-dsl": "^5.0.7.1 || ^6.2.0.1 || ^7.2.0.1", "handcraftedinthealps/zendsearch": "^2.0", "jackalope/jackalope-doctrine-dbal": "^1.3.4", "jackalope/jackalope-jackrabbit": "^1.3", @@ -46,6 +51,7 @@ "phpstan/phpstan-symfony": "^0.12.3", "phpunit/phpunit": "^8.2", "sulu/automation-bundle": "^2.0@dev", + "sulu/content-bundle": "^0.6.1", "symfony/browser-kit": "^4.3 || ^5.0", "symfony/dotenv": "^4.3 || ^5.0", "symfony/monolog-bundle": "^3.1", From 35fde555c47b7b65c3935966cd1022a0f26445f1 Mon Sep 17 00:00:00 2001 From: Alexander Schranz Date: Thu, 11 Mar 2021 16:09:36 +0100 Subject: [PATCH 2/7] Add docs about experimental storage --- DependencyInjection/SuluArticleExtension.php | 13 ++-- Resources/doc/experimental-storage.md | 70 ++++++++++++++++++++ composer.json | 7 +- 3 files changed, 82 insertions(+), 8 deletions(-) create mode 100644 Resources/doc/experimental-storage.md diff --git a/DependencyInjection/SuluArticleExtension.php b/DependencyInjection/SuluArticleExtension.php index 5b0a7774e..4f7136fe7 100644 --- a/DependencyInjection/SuluArticleExtension.php +++ b/DependencyInjection/SuluArticleExtension.php @@ -393,15 +393,14 @@ public function load(array $configs, ContainerBuilder $container) $isPHPCRStorage = Configuration::ARTICLE_STORAGE_PHPCR === $storage; $isExperimentalStorage = Configuration::ARTICLE_STORAGE_EXPERIMENTAL === $storage; - $container->setParameter('sulu_article.default_main_webspace', $config['default_main_webspace']); - $container->setParameter('sulu_article.default_additional_webspaces', $config['default_additional_webspaces']); - $container->setParameter('sulu_article.types', $config['types']); - $container->setParameter('sulu_article.display_tab_all', $config['display_tab_all']); - $container->setParameter('sulu_article.smart_content.default_limit', $config['smart_content']['default_limit']); - $container->setParameter('sulu_article.search_fields', $config['search_fields']); - if ($isPHPCRStorage) { // can be removed when phpcr storage is removed + $container->setParameter('sulu_article.default_main_webspace', $config['default_main_webspace']); + $container->setParameter('sulu_article.default_additional_webspaces', $config['default_additional_webspaces']); + $container->setParameter('sulu_article.types', $config['types']); + $container->setParameter('sulu_article.display_tab_all', $config['display_tab_all']); + $container->setParameter('sulu_article.smart_content.default_limit', $config['smart_content']['default_limit']); + $container->setParameter('sulu_article.search_fields', $config['search_fields']); $container->setParameter('sulu_article.documents', $config['documents']); $container->setParameter('sulu_article.view_document.article.class', $config['documents']['article']['view']); } diff --git a/Resources/doc/experimental-storage.md b/Resources/doc/experimental-storage.md new file mode 100644 index 000000000..11c21313f --- /dev/null +++ b/Resources/doc/experimental-storage.md @@ -0,0 +1,70 @@ +# Experimental Content Bundle Storage + +For the **experimental** storage the articles are stored using the [SuluContentBundle](https://github.com/sulu/sulucontentbundle). + +## Installation + +To use the experimental storage you need to have the [SuluContentBundle](https://github.com/sulu/sulucontentbundle) installed. + +```bash +composer require sulu/content-bundle +``` + +Then you can configure it: + +```yaml +sulu_article: + article: + storage: experimental +``` + +## Configuration + +The following is showing the full configuration of the **experimental** article module: + +```yaml +sulu_product: + article: + storage: experimental + + # optional + objects: + article: + model: 'Sulu\Bundle\ArticleBundle\Article\Domain\Model\Article' +``` + +## Override Entities + +### Override Article Entity + +```php +=8.0", + "handcraftedinthealps/elasticsearch-bundle": "<5.2.6.4 >= 6.0", + "handcraftedinthealps/elasticsearch-dsl": "<5.0.7.1 || <6.2.0.1 || <7.2.0.1 >=8.0" + }, "suggest": { "sulu/automation-bundle": "Allows to outsource long-running route update processes." }, From a3aa3e4e4fc00f2594959ab9e14b3fd22580d0cb Mon Sep 17 00:00:00 2001 From: Alexander Schranz Date: Thu, 11 Mar 2021 17:02:53 +0100 Subject: [PATCH 3/7] Fix article bundle conflicts --- composer.json | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index c5e2eec72..571ade127 100644 --- a/composer.json +++ b/composer.json @@ -40,7 +40,7 @@ "elasticsearch/elasticsearch": "^5.0 || ^6.0 || ^7.0", "friendsofphp/php-cs-fixer": "^2.17", "handcraftedinthealps/elasticsearch-bundle": "^5.2.6.4", - "handcraftedinthealps/elasticsearch-dsl": "^6.2.0.1", + "handcraftedinthealps/elasticsearch-dsl": "^5.0.7.1 || ^6.2.0.1 || ^7.2.0.1", "handcraftedinthealps/zendsearch": "^2.0", "jackalope/jackalope-doctrine-dbal": "^1.3.4", "jackalope/jackalope-jackrabbit": "^1.3", @@ -59,12 +59,15 @@ "thecodingmachine/phpstan-strict-rules": "^0.12.0" }, "conflict": { - "elasticsearch/elasticsearch": "<5.0 >=8.0", - "handcraftedinthealps/elasticsearch-bundle": "<5.2.6.4 >= 6.0", - "handcraftedinthealps/elasticsearch-dsl": "<5.0.7.1 || <6.2.0.1 || <7.2.0.1 >=8.0" + "elasticsearch/elasticsearch": "<5.0 || >=8.0", + "handcraftedinthealps/elasticsearch-bundle": "<5.2.6.4 || >=6.0", + "handcraftedinthealps/elasticsearch-dsl": "<5.0.7.1 || 6.0 - 6.2.0 || 7.0 - 7.2.0 || >=8.0" }, "suggest": { - "sulu/automation-bundle": "Allows to outsource long-running route update processes." + "elasticsearch/elasticsearch": "Required for the default article phpcr storage.", + "handcraftedinthealps/elasticsearch-bundle": "Required for the default article phpcr storage.", + "sulu/automation-bundle": "Allows publish automation and outsource long-running route update processes.", + "sulu/content-bundle": "Allows to use the experimental article storage." }, "autoload": { "psr-4": { From ce6d9b8ac2edc3a5d3de12f0d8526823a0177b87 Mon Sep 17 00:00:00 2001 From: Alexander Schranz Date: Thu, 11 Mar 2021 17:35:31 +0100 Subject: [PATCH 4/7] Fix prefer lowest tests --- Tests/Application/Kernel.php | 5 ++++- composer.json | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Tests/Application/Kernel.php b/Tests/Application/Kernel.php index 9d70ea002..a0b482c55 100644 --- a/Tests/Application/Kernel.php +++ b/Tests/Application/Kernel.php @@ -47,7 +47,10 @@ public function registerBundles() { $bundles = parent::registerBundles(); $bundles[] = new SuluArticleBundle(); - $bundles[] = new ONGRElasticsearchBundle(); + + if ('phpcr' === $this->config) { + $bundles[] = new ONGRElasticsearchBundle(); + } if ('extend' === getenv('ARTICLE_TEST_CASE')) { $bundles[] = new TestExtendBundle(); diff --git a/composer.json b/composer.json index 571ade127..aae97c383 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,7 @@ "jms/serializer": "^3.3", "jms/serializer-bundle": "^3.3", "ramsey/uuid": "^3.1 || ^4.0", - "sulu/sulu": "^2.0.10 || ^2.1@dev", + "sulu/sulu": "^2.1 || ^2.3@dev", "symfony/config": "^4.3 || ^5.0", "symfony/dependency-injection": "^4.3 || ^5.0", "symfony/http-foundation": "^4.3 || ^5.0", From 7a0eca4cee028862dd3b0858432ccf4a950cbd4a Mon Sep 17 00:00:00 2001 From: Alexander Schranz Date: Thu, 11 Mar 2021 17:50:15 +0100 Subject: [PATCH 5/7] Add prefer stable to lowest dependencies --- .github/workflows/test-application.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test-application.yaml b/.github/workflows/test-application.yaml index 02871301e..6c46555f9 100644 --- a/.github/workflows/test-application.yaml +++ b/.github/workflows/test-application.yaml @@ -25,6 +25,7 @@ jobs: elasticsearch-package-constraint: '~5.5' phpcr-transport: doctrinedbal dependency-versions: 'lowest' + composer-options: "--prefer-stable" php-extensions: 'ctype, iconv, mysql, gd' tools: 'composer:v1' lint: false From 6303972338f4dde9307fc281450098449bc5311e Mon Sep 17 00:00:00 2001 From: Alexander Schranz Date: Thu, 11 Mar 2021 18:03:02 +0100 Subject: [PATCH 6/7] Fix min requirement for sulu/sulu --- .github/workflows/test-application.yaml | 1 - composer.json | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/test-application.yaml b/.github/workflows/test-application.yaml index 6c46555f9..02871301e 100644 --- a/.github/workflows/test-application.yaml +++ b/.github/workflows/test-application.yaml @@ -25,7 +25,6 @@ jobs: elasticsearch-package-constraint: '~5.5' phpcr-transport: doctrinedbal dependency-versions: 'lowest' - composer-options: "--prefer-stable" php-extensions: 'ctype, iconv, mysql, gd' tools: 'composer:v1' lint: false diff --git a/composer.json b/composer.json index aae97c383..686a6ff56 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,7 @@ "jms/serializer": "^3.3", "jms/serializer-bundle": "^3.3", "ramsey/uuid": "^3.1 || ^4.0", - "sulu/sulu": "^2.1 || ^2.3@dev", + "sulu/sulu": "^2.1.1 || ^2.3@dev", "symfony/config": "^4.3 || ^5.0", "symfony/dependency-injection": "^4.3 || ^5.0", "symfony/http-foundation": "^4.3 || ^5.0", From 3fcc381b8db419439ebb11ca802c11319fa4af92 Mon Sep 17 00:00:00 2001 From: Alexander Schranz Date: Fri, 12 Mar 2021 12:03:09 +0100 Subject: [PATCH 7/7] Improve code readability --- DependencyInjection/SuluArticleExtension.php | 408 +++++++++--------- SuluArticleBundle.php | 44 +- Tests/Application/Kernel.php | 4 +- ...al.yml => config_experimental_storage.yml} | 0 ...fig_phpcr.yml => config_phpcr_storage.yml} | 0 5 files changed, 245 insertions(+), 211 deletions(-) rename Tests/Application/config/{config_experimental.yml => config_experimental_storage.yml} (100%) rename Tests/Application/config/{config_phpcr.yml => config_phpcr_storage.yml} (100%) diff --git a/DependencyInjection/SuluArticleExtension.php b/DependencyInjection/SuluArticleExtension.php index 4f7136fe7..9a234ce9f 100644 --- a/DependencyInjection/SuluArticleExtension.php +++ b/DependencyInjection/SuluArticleExtension.php @@ -28,7 +28,9 @@ use Symfony\Component\HttpKernel\DependencyInjection\Extension; /** - * This is the class that loads and manages article bundle configuration. + * @internal + * + * This is the class that loads and manages article bundle configuration */ class SuluArticleExtension extends Extension implements PrependExtensionInterface { @@ -45,22 +47,16 @@ public function prepend(ContainerBuilder $container) $config = $this->processConfiguration(new Configuration(), $configs); $storage = $config['article']['storage']; - $isPHPCRStorage = Configuration::ARTICLE_STORAGE_PHPCR === $storage; - $isExperimentalStorage = Configuration::ARTICLE_STORAGE_EXPERIMENTAL === $storage; - if ($isExperimentalStorage && $container->hasExtension('doctrine')) { + if ($container->hasExtension('jms_serializer')) { $container->prependExtensionConfig( - 'doctrine', + 'jms_serializer', [ - 'orm' => [ - 'mappings' => [ - 'SuluBundleArticle' => [ - 'type' => 'xml', - 'prefix' => 'Sulu\Bundle\ArticleBundle\Article\Domain\Model', - 'dir' => \dirname(__DIR__) . '/Resources/config/doctrine/Article', - 'alias' => 'SuluArticleBundle', - 'is_bundle' => false, - 'mapping' => true, + 'metadata' => [ + 'directories' => [ + 'sulu_article' => [ + 'path' => __DIR__ . '/../Resources/config/serializer', + 'namespace_prefix' => 'Sulu\Bundle\ArticleBundle', ], ], ], @@ -68,20 +64,65 @@ public function prepend(ContainerBuilder $container) ); } - if ($isExperimentalStorage && $container->hasExtension('sulu_core')) { + if ($container->hasExtension('sulu_admin')) { $container->prependExtensionConfig( - 'sulu_core', + 'sulu_admin', [ - 'content' => [ - 'structure' => [ - 'paths' => [ - ArticleInterface::TEMPLATE_TYPE => [ - 'path' => '%kernel.project_dir%/config/templates/articles', - 'type' => 'article', + 'lists' => [ + 'directories' => [ + __DIR__ . '/../Resources/config/lists', + ], + ], + 'forms' => [ + 'directories' => [ + __DIR__ . '/../Resources/config/forms', + ], + ], + 'resources' => [ + 'articles' => [ + 'routes' => [ + 'list' => 'sulu_article.get_articles', + 'detail' => 'sulu_article.get_article', + ], + ], + 'article_versions' => [ + 'routes' => [ + 'list' => 'sulu_article.get_article_versions', + 'detail' => 'sulu_article.post_article_version_trigger', + ], + ], + ], + 'field_type_options' => [ + 'selection' => [ + 'article_selection' => [ + 'default_type' => 'list_overlay', + 'resource_key' => 'articles', + 'types' => [ + 'list_overlay' => [ + 'adapter' => 'table', + 'list_key' => 'articles', + 'display_properties' => ['title', 'routePath'], + 'icon' => 'su-newspaper', + 'label' => 'sulu_article.selection_label', + 'overlay_title' => 'sulu_article.selection_overlay_title', + ], ], ], - 'default_type' => [ - ArticleInterface::TEMPLATE_TYPE => 'default', + ], + 'single_selection' => [ + 'single_article_selection' => [ + 'default_type' => 'list_overlay', + 'resource_key' => 'articles', + 'types' => [ + 'list_overlay' => [ + 'adapter' => 'table', + 'list_key' => 'articles', + 'display_properties' => ['title'], + 'empty_text' => 'sulu_article.no_article_selected', + 'icon' => 'su-newspaper', + 'overlay_title' => 'sulu_article.single_selection_overlay_title', + ], + ], ], ], ], @@ -89,7 +130,19 @@ public function prepend(ContainerBuilder $container) ); } - if ($isPHPCRStorage && $container->hasExtension('sulu_core')) { + if (Configuration::ARTICLE_STORAGE_PHPCR === $storage) { + $this->prependPHPCRStorage($container); + } elseif (Configuration::ARTICLE_STORAGE_EXPERIMENTAL === $storage) { + $this->prependExperimentalStorage($container); + } + } + + /** + * Can be removed when phpcr storage is removed. + */ + private function prependPHPCRStorage(ContainerBuilder $container): void + { + if ($container->hasExtension('sulu_core')) { // can be removed when phpcr storage is removed $container->prependExtensionConfig( 'sulu_core', @@ -116,7 +169,7 @@ public function prepend(ContainerBuilder $container) ); } - if ($isPHPCRStorage && $container->hasExtension('sulu_route')) { + if ($container->hasExtension('sulu_route')) { // can be removed when phpcr storage is removed $container->prependExtensionConfig( 'sulu_route', @@ -133,40 +186,7 @@ public function prepend(ContainerBuilder $container) ); } - if ($isExperimentalStorage && $container->hasExtension('sulu_route')) { - $container->prependExtensionConfig( - 'sulu_route', - [ - 'mappings' => [ - ArticleInterface::class => [ - 'generator' => 'schema', - 'options' => [ - 'route_schema' => '/{object["title"]}', - ], - 'resource_key' => ArticleInterface::RESOURCE_KEY, - ], - ], - ] - ); - } - - if ($container->hasExtension('jms_serializer')) { - $container->prependExtensionConfig( - 'jms_serializer', - [ - 'metadata' => [ - 'directories' => [ - 'sulu_article' => [ - 'path' => __DIR__ . '/../Resources/config/serializer', - 'namespace_prefix' => 'Sulu\Bundle\ArticleBundle', - ], - ], - ], - ] - ); - } - - if ($isPHPCRStorage && $container->hasExtension('sulu_search')) { + if ($container->hasExtension('sulu_search')) { // can be removed when phpcr storage is removed $container->prependExtensionConfig( 'sulu_page', @@ -181,26 +201,7 @@ public function prepend(ContainerBuilder $container) ); } - if ($isExperimentalStorage && $container->hasExtension('sulu_search')) { - $suluSearchConfigs = $container->getExtensionConfig('sulu_search'); - - foreach ($suluSearchConfigs as $suluSearchConfig) { - if (isset($suluSearchConfig['website']['indexes'])) { - $container->prependExtensionConfig( - 'sulu_search', - [ - 'website' => [ - 'indexes' => [ - ArticleInterface::RESOURCE_KEY => ArticleInterface::RESOURCE_KEY . '_published', - ], - ], - ] - ); - } - } - } - - if ($isPHPCRStorage && $container->hasExtension('sulu_document_manager')) { + if ($container->hasExtension('sulu_document_manager')) { // can be removed when phpcr storage is removed $container->prependExtensionConfig( 'sulu_document_manager', @@ -224,7 +225,7 @@ public function prepend(ContainerBuilder $container) ); } - if ($isPHPCRStorage && $container->hasExtension('fos_js_routing')) { + if ($container->hasExtension('fos_js_routing')) { // can be removed when phpcr storage is removed $container->prependExtensionConfig( 'fos_js_routing', @@ -236,7 +237,7 @@ public function prepend(ContainerBuilder $container) ); } - if ($isPHPCRStorage && $container->hasExtension('fos_rest')) { + if ($container->hasExtension('fos_rest')) { // can be removed when phpcr storage is removed $container->prependExtensionConfig( 'fos_rest', @@ -251,7 +252,7 @@ public function prepend(ContainerBuilder $container) ); } - if ($isPHPCRStorage && $container->hasExtension('massive_build')) { + if ($container->hasExtension('massive_build')) { // can be removed when phpcr storage is removed $container->prependExtensionConfig( 'massive_build', @@ -277,73 +278,7 @@ public function prepend(ContainerBuilder $container) ); } - if ($container->hasExtension('sulu_admin')) { - $container->prependExtensionConfig( - 'sulu_admin', - [ - 'lists' => [ - 'directories' => [ - __DIR__ . '/../Resources/config/lists', - ], - ], - 'forms' => [ - 'directories' => [ - __DIR__ . '/../Resources/config/forms', - ], - ], - 'resources' => [ - 'articles' => [ - 'routes' => [ - 'list' => 'sulu_article.get_articles', - 'detail' => 'sulu_article.get_article', - ], - ], - 'article_versions' => [ - 'routes' => [ - 'list' => 'sulu_article.get_article_versions', - 'detail' => 'sulu_article.post_article_version_trigger', - ], - ], - ], - 'field_type_options' => [ - 'selection' => [ - 'article_selection' => [ - 'default_type' => 'list_overlay', - 'resource_key' => 'articles', - 'types' => [ - 'list_overlay' => [ - 'adapter' => 'table', - 'list_key' => 'articles', - 'display_properties' => ['title', 'routePath'], - 'icon' => 'su-newspaper', - 'label' => 'sulu_article.selection_label', - 'overlay_title' => 'sulu_article.selection_overlay_title', - ], - ], - ], - ], - 'single_selection' => [ - 'single_article_selection' => [ - 'default_type' => 'list_overlay', - 'resource_key' => 'articles', - 'types' => [ - 'list_overlay' => [ - 'adapter' => 'table', - 'list_key' => 'articles', - 'display_properties' => ['title'], - 'empty_text' => 'sulu_article.no_article_selected', - 'icon' => 'su-newspaper', - 'overlay_title' => 'sulu_article.single_selection_overlay_title', - ], - ], - ], - ], - ], - ] - ); - } - - if ($isPHPCRStorage && $container->hasExtension('ongr_elasticsearch')) { + if ($container->hasExtension('ongr_elasticsearch')) { // can be removed when phpcr storage is removed $configs = $container->getExtensionConfig($this->getAlias()); $config = $this->processConfiguration(new Configuration(), $configs); @@ -380,6 +315,86 @@ public function prepend(ContainerBuilder $container) } } + private function prependExperimentalStorage(ContainerBuilder $container): void + { + if ($container->hasExtension('doctrine')) { + $container->prependExtensionConfig( + 'doctrine', + [ + 'orm' => [ + 'mappings' => [ + 'SuluBundleArticle' => [ + 'type' => 'xml', + 'prefix' => 'Sulu\Bundle\ArticleBundle\Article\Domain\Model', + 'dir' => \dirname(__DIR__) . '/Resources/config/doctrine/Article', + 'alias' => 'SuluArticleBundle', + 'is_bundle' => false, + 'mapping' => true, + ], + ], + ], + ] + ); + } + + if ($container->hasExtension('sulu_core')) { + $container->prependExtensionConfig( + 'sulu_core', + [ + 'content' => [ + 'structure' => [ + 'paths' => [ + ArticleInterface::TEMPLATE_TYPE => [ + 'path' => '%kernel.project_dir%/config/templates/articles', + 'type' => 'article', + ], + ], + 'default_type' => [ + ArticleInterface::TEMPLATE_TYPE => 'default', + ], + ], + ], + ] + ); + } + + if ($container->hasExtension('sulu_route')) { + $container->prependExtensionConfig( + 'sulu_route', + [ + 'mappings' => [ + ArticleInterface::class => [ + 'generator' => 'schema', + 'options' => [ + 'route_schema' => '/{implode("-", object)}', + ], + 'resource_key' => ArticleInterface::RESOURCE_KEY, + ], + ], + ] + ); + } + + if ($container->hasExtension('sulu_search')) { + $suluSearchConfigs = $container->getExtensionConfig('sulu_search'); + + foreach ($suluSearchConfigs as $suluSearchConfig) { + if (isset($suluSearchConfig['website']['indexes'])) { + $container->prependExtensionConfig( + 'sulu_search', + [ + 'website' => [ + 'indexes' => [ + ArticleInterface::RESOURCE_KEY => ArticleInterface::RESOURCE_KEY . '_published', + ], + ], + ] + ); + } + } + } + } + /** * {@inheritdoc} */ @@ -388,64 +403,63 @@ public function load(array $configs, ContainerBuilder $container) $configuration = new Configuration(); $config = $this->processConfiguration($configuration, $configs); - $storage = $config['article']['storage']; - $container->setParameter('sulu_article.article_storage', $storage); - $isPHPCRStorage = Configuration::ARTICLE_STORAGE_PHPCR === $storage; - $isExperimentalStorage = Configuration::ARTICLE_STORAGE_EXPERIMENTAL === $storage; - - if ($isPHPCRStorage) { - // can be removed when phpcr storage is removed - $container->setParameter('sulu_article.default_main_webspace', $config['default_main_webspace']); - $container->setParameter('sulu_article.default_additional_webspaces', $config['default_additional_webspaces']); - $container->setParameter('sulu_article.types', $config['types']); - $container->setParameter('sulu_article.display_tab_all', $config['display_tab_all']); - $container->setParameter('sulu_article.smart_content.default_limit', $config['smart_content']['default_limit']); - $container->setParameter('sulu_article.search_fields', $config['search_fields']); - $container->setParameter('sulu_article.documents', $config['documents']); - $container->setParameter('sulu_article.view_document.article.class', $config['documents']['article']['view']); - } - $loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); - if ($isPHPCRStorage) { - // can be removed when phpcr storage is removed - $loader->load('services.xml'); - } - - if ($isExperimentalStorage) { - $this->configurePersistence($config['article']['objects'], $container); - } + $storage = $config['article']['storage']; + $container->setParameter('sulu_article.article_storage', $storage); - $bundles = $container->getParameter('kernel.bundles'); - if (array_key_exists('SuluAutomationBundle', $bundles)) { - $loader->load('automation.xml'); + if (Configuration::ARTICLE_STORAGE_PHPCR === $storage) { + $this->loadPHPCRStorage($config, $container, $loader); + } elseif (Configuration::ARTICLE_STORAGE_EXPERIMENTAL === $storage) { + $this->loadExperimentalStorage($config, $container, $loader); } + } - if ($isPHPCRStorage) { - // can be removed when phpcr storage is removed - $this->appendDefaultAuthor($config, $container); - $this->appendArticlePageConfig($container); - - $articleDocument = ArticleDocument::class; - $articlePageDocument = ArticlePageDocument::class; - - foreach ($container->getParameter('sulu_document_manager.mapping') as $mapping) { - if ('article' == $mapping['alias']) { - $articleDocument = $mapping['class']; - } + private function loadExperimentalStorage(array $config, ContainerBuilder $container, Loader\XmlFileLoader $loader): void + { + $this->configurePersistence($config['article']['objects'], $container); + } - if ('article_page' == $mapping['alias']) { - $articlePageDocument = $mapping['class']; - } + /** + * Can be removed when phpcr storage is removed. + */ + private function loadPHPCRStorage(array $config, ContainerBuilder $container, Loader\XmlFileLoader $loader): void + { + $container->setParameter('sulu_article.default_main_webspace', $config['default_main_webspace']); + $container->setParameter('sulu_article.default_additional_webspaces', $config['default_additional_webspaces']); + $container->setParameter('sulu_article.types', $config['types']); + $container->setParameter('sulu_article.display_tab_all', $config['display_tab_all']); + $container->setParameter('sulu_article.smart_content.default_limit', $config['smart_content']['default_limit']); + $container->setParameter('sulu_article.search_fields', $config['search_fields']); + $container->setParameter('sulu_article.documents', $config['documents']); + $container->setParameter('sulu_article.view_document.article.class', $config['documents']['article']['view']); + + $loader->load('services.xml'); + + $this->appendDefaultAuthor($config, $container); + $this->appendArticlePageConfig($container); + + $articleDocument = ArticleDocument::class; + $articlePageDocument = ArticlePageDocument::class; + + foreach ($container->getParameter('sulu_document_manager.mapping') as $mapping) { + if ('article' == $mapping['alias']) { + $articleDocument = $mapping['class']; } - $container->setParameter('sulu_article.article_document.class', $articleDocument); - $container->setParameter('sulu_article.article_page_document.class', $articlePageDocument); + if ('article_page' == $mapping['alias']) { + $articlePageDocument = $mapping['class']; + } } + + $container->setParameter('sulu_article.article_document.class', $articleDocument); + $container->setParameter('sulu_article.article_page_document.class', $articlePageDocument); } /** * Append configuration for article "set_default_author". + * + * Can be removed when phpcr storage is removed. */ private function appendDefaultAuthor(array $config, ContainerBuilder $container): void { @@ -462,6 +476,8 @@ private function appendDefaultAuthor(array $config, ContainerBuilder $container) /** * Append configuration for article-page (cloned from article). + * + * Can be removed when phpcr storage is removed. */ private function appendArticlePageConfig(ContainerBuilder $container): void { @@ -478,6 +494,8 @@ private function appendArticlePageConfig(ContainerBuilder $container): void /** * Clone given path configuration and use given type. + * + * Can be removed when phpcr storage is removed. */ private function cloneArticleConfig(array $config, string $type): array { diff --git a/SuluArticleBundle.php b/SuluArticleBundle.php index 240d7a42b..9d85b557f 100644 --- a/SuluArticleBundle.php +++ b/SuluArticleBundle.php @@ -41,27 +41,43 @@ public function build(ContainerBuilder $container) public function process(ContainerBuilder $container): void { - $interfaces = []; - - if (Configuration::ARTICLE_STORAGE_EXPERIMENTAL === $container->getParameter('sulu_article.article_storage')) { - $interfaces = \array_merge($interfaces, [ - ArticleInterface::class => 'sulu.model.article.class', - ]); - } + $storage = $container->getParameter('sulu_article.article_storage'); $compilerPasses = []; - if (0 < \count($interfaces)) { - $compilerPasses[] = new ResolveTargetEntitiesPass($interfaces); - } - if (Configuration::ARTICLE_STORAGE_PHPCR === $container->getParameter('sulu_article.article_storage')) { - // can be removed when phpcr storage is removed - $compilerPasses[] = new RouteEnhancerCompilerPass(); - $compilerPasses[] = new ConverterCompilerPass(); + if (Configuration::ARTICLE_STORAGE_PHPCR === $storage) { + $compilerPasses = $this->getPHPCRStorageCompilerPasses($container); + } elseif (Configuration::ARTICLE_STORAGE_EXPERIMENTAL === $storage) { + $compilerPasses = $this->getExperimentalStorageCompilerPasses($container); } foreach ($compilerPasses as $compilerPass) { $compilerPass->process($container); } } + + /** + * @return CompilerPassInterface[] + */ + private function getExperimentalStorageCompilerPasses(ContainerBuilder $container): array + { + return [ + new ResolveTargetEntitiesPass([ + ArticleInterface::class => 'sulu.model.article.class', + ]), + ]; + } + + /** + * @return compilerPassInterface[] + * + * Can be removed when phpcr storage is removed + */ + private function getPHPCRStorageCompilerPasses(ContainerBuilder $container): array + { + return [ + new RouteEnhancerCompilerPass(), + new ConverterCompilerPass(), + ]; + } } diff --git a/Tests/Application/Kernel.php b/Tests/Application/Kernel.php index a0b482c55..4e1d3efcb 100644 --- a/Tests/Application/Kernel.php +++ b/Tests/Application/Kernel.php @@ -29,7 +29,7 @@ class Kernel extends SuluTestKernel implements CompilerPassInterface /** * @var string|null */ - private $config = 'phpcr'; + private $config = 'phpcr_storage'; public function __construct(string $environment, bool $debug, string $suluContext = SuluKernel::CONTEXT_ADMIN) { @@ -48,7 +48,7 @@ public function registerBundles() $bundles = parent::registerBundles(); $bundles[] = new SuluArticleBundle(); - if ('phpcr' === $this->config) { + if ('phpcr_storage' === $this->config) { $bundles[] = new ONGRElasticsearchBundle(); } diff --git a/Tests/Application/config/config_experimental.yml b/Tests/Application/config/config_experimental_storage.yml similarity index 100% rename from Tests/Application/config/config_experimental.yml rename to Tests/Application/config/config_experimental_storage.yml diff --git a/Tests/Application/config/config_phpcr.yml b/Tests/Application/config/config_phpcr_storage.yml similarity index 100% rename from Tests/Application/config/config_phpcr.yml rename to Tests/Application/config/config_phpcr_storage.yml