diff --git a/.tugboat/config.yml b/.tugboat/config.yml index 443bbca6d83e12acb83a0dfe5686f561435db922..935f9c00a3232aa2b1b9a4128171d45d930a316f 100644 --- a/.tugboat/config.yml +++ b/.tugboat/config.yml @@ -50,6 +50,7 @@ services: # Enable the module. vendor/bin/drush --yes pm:install \ experience_builder \ + xb_dev_standard \ media_library \ components diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6a2b2aa04c68cd78c217e92e4b3a5ff4f1f7169b..f583bdee66043b8912137d22f5ad96baebafd5e1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,7 +2,7 @@ 1. Drupal 11 (preferably a clone for Git archeology: `git clone https://git.drupalcode.org/project/drupal.git` — 10.3 will work too). 2. `composer require drush/drush` 3. `drush si standard` -4. `drush pm:install experience_builder` +4. `drush pm:install experience_builder xb_dev_standard` 5. Build the front end: `cd modules/contrib/experience_builder/ui` and then either * With Node.js available: `npm install && npm run build` * With Docker available: `docker build --output dist .` diff --git a/experience_builder.install b/experience_builder.install index 0aeea5106e309900c97fe750578f8ff7fd53ac79..65a3d479def7aa91e5ad4de1b0647420498ab00f 100644 --- a/experience_builder.install +++ b/experience_builder.install @@ -2,7 +2,6 @@ declare(strict_types=1); -use Drupal\node\Entity\NodeType; use Drupal\Core\Extension\ThemeInstallerInterface; /** @@ -14,23 +13,6 @@ function experience_builder_install(): void { // @see \Drupal\Core\Theme\ThemeNegotiator::determineActiveTheme() \Drupal::service(ThemeInstallerInterface::class)->install(['xb_stark']); - // Automatically set up the Standard install profile's "article" content type - // to demo/test Experience Builder. - if (!\Drupal::moduleHandler()->moduleExists('node')) { - return; - } - if (NodeType::load('article')) { - \Drupal::service('entity_display.repository') - ->getViewDisplay('node', 'article') - ->setComponent('field_xb_demo', [ - 'label' => 'hidden', - 'type' => 'experience_builder_naive_render_sdc_tree', - // The image field has weight -1 by default. - 'weight' => -2, - ]) - ->save(); - } - // Cache flush ensures the contextual form works. drupal_flush_all_caches(); } diff --git a/experience_builder.module b/experience_builder.module index 9a1d96663a0e1e8c5bb9f8797510baef6fa55b09..1fda346ad64aac3c36e0508be5c2beb26ca1e948 100644 --- a/experience_builder.module +++ b/experience_builder.module @@ -15,11 +15,9 @@ use Drupal\Core\Entity\TypedData\EntityDataDefinition; use Drupal\Core\EventSubscriber\AjaxResponseSubscriber; use Drupal\Core\Field\BaseFieldDefinition; use Drupal\Core\Form\FormStateInterface; -use Drupal\Core\Url; use Drupal\datetime\Plugin\Field\FieldType\DateTimeItem; use Drupal\experience_builder\Entity\Component; use Drupal\experience_builder\Form\FormIdPreRender; -use Drupal\experience_builder\InternalXbFieldNameResolver; use Drupal\experience_builder\Entity\PageTemplate; use Drupal\experience_builder\Plugin\ComponentPluginManager; use Drupal\Core\Validation\Plugin\Validation\Constraint\FullyValidatableConstraint; @@ -42,52 +40,6 @@ require_once __DIR__ . '/experience_builder.shape_matching.inc'; require_once __DIR__ . '/experience_builder.force_render_with_twig.inc'; -/** - * Implements hook_toolbar(). - */ -function experience_builder_toolbar(): array { - $user = \Drupal::currentUser(); - - $items = []; - $items['experience_builder'] = [ - '#cache' => [ - 'contexts' => [ - 'user.permissions', - 'url', - ], - ], - ]; - - // @see experience_builder.routing.yml - // ⚠️ This is HORRIBLY HACKY way to provide a XB link for articles using `field_xb_demo` and will go away! ☺️ - if ($user->hasPermission('access administration pages')) { - $node = \Drupal::routeMatch()->getParameter('node'); - if ($node) { - try { - InternalXbFieldNameResolver::getXbFieldName($node); - } - catch (\LogicException) { - return $items; - } - $items['experience_builder'] += [ - '#type' => 'toolbar_item', - 'tab' => [ - '#type' => 'link', - '#title' => t('Experience Builder: %title', ['%title' => $node->label()]), - '#url' => Url::fromRoute('experience_builder.experience_builder', ['entity_type' => 'node', 'entity' => $node->id()]), - '#attributes' => [ - 'title' => t('Experience Builder'), - 'class' => ['toolbar-icon', 'toolbar-icon-edit'], - ], - ], - '#weight' => 1000, - ]; - } - } - - return $items; -} - /** * Implements hook_form_alter(). */ diff --git a/config/optional/field.field.node.article.field_xb_demo.yml b/tests/modules/xb_dev_standard/config/optional/field.field.node.article.field_xb_demo.yml similarity index 100% rename from config/optional/field.field.node.article.field_xb_demo.yml rename to tests/modules/xb_dev_standard/config/optional/field.field.node.article.field_xb_demo.yml diff --git a/config/optional/field.storage.node.field_xb_demo.yml b/tests/modules/xb_dev_standard/config/optional/field.storage.node.field_xb_demo.yml similarity index 100% rename from config/optional/field.storage.node.field_xb_demo.yml rename to tests/modules/xb_dev_standard/config/optional/field.storage.node.field_xb_demo.yml diff --git a/tests/modules/xb_dev_standard/xb_dev_standard.info.yml b/tests/modules/xb_dev_standard/xb_dev_standard.info.yml new file mode 100644 index 0000000000000000000000000000000000000000..16f804414bcb8c1936f885c68a65ebd0eea36248 --- /dev/null +++ b/tests/modules/xb_dev_standard/xb_dev_standard.info.yml @@ -0,0 +1,6 @@ +name: 'Develop XB on top of the Standard install profile' +type: module +dependencies: + - experience_builder:experience_builder + - drupal:node +package: Testing diff --git a/tests/modules/xb_dev_standard/xb_dev_standard.install b/tests/modules/xb_dev_standard/xb_dev_standard.install new file mode 100644 index 0000000000000000000000000000000000000000..9161762ccd1bb0dac2a3d65f95a9bd93d00b97c9 --- /dev/null +++ b/tests/modules/xb_dev_standard/xb_dev_standard.install @@ -0,0 +1,22 @@ +<?php + +declare(strict_types=1); + +use Drupal\node\Entity\NodeType; + +/** + * Implements hook_install(). + */ +function xb_dev_standard_install(): void { + if (NodeType::load('article')) { + \Drupal::service('entity_display.repository') + ->getViewDisplay('node', 'article') + ->setComponent('field_xb_demo', [ + 'label' => 'hidden', + 'type' => 'experience_builder_naive_render_sdc_tree', + // The image field has weight -1 by default. + 'weight' => -2, + ]) + ->save(); + } +} diff --git a/tests/modules/xb_dev_standard/xb_dev_standard.module b/tests/modules/xb_dev_standard/xb_dev_standard.module new file mode 100644 index 0000000000000000000000000000000000000000..e5cd2404c20ec96dd2701c2c3b3dc363eb7cdcec --- /dev/null +++ b/tests/modules/xb_dev_standard/xb_dev_standard.module @@ -0,0 +1,52 @@ +<?php + +declare(strict_types=1); + +use Drupal\Core\Url; +use Drupal\experience_builder\InternalXbFieldNameResolver; + +/** + * Implements hook_toolbar(). + */ +function xb_dev_standard_toolbar(): array { + $user = \Drupal::currentUser(); + + $items = []; + $items['experience_builder'] = [ + '#cache' => [ + 'contexts' => [ + 'user.permissions', + 'url', + ], + ], + ]; + + // @see experience_builder.routing.yml + // ⚠️ This is HORRIBLY HACKY way to provide a XB link for articles using `field_xb_demo` and will go away! ☺️ + if ($user->hasPermission('access administration pages')) { + $node = \Drupal::routeMatch()->getParameter('node'); + if ($node) { + try { + InternalXbFieldNameResolver::getXbFieldName($node); + } + catch (\LogicException) { + return $items; + } + $items['experience_builder'] += [ + '#type' => 'toolbar_item', + 'tab' => [ + '#type' => 'link', + '#title' => t('Experience Builder: %title', ['%title' => $node->label()]), + '#url' => Url::fromRoute('experience_builder.experience_builder', ['entity_type' => 'node', 'entity' => $node->id()]), + '#attributes' => [ + 'title' => t('Experience Builder'), + 'class' => ['toolbar-icon', 'toolbar-icon-edit'], + ], + ], + '#weight' => 1000, + ]; + } + } + + return $items; +} diff --git a/tests/src/Functional/ApiContentUpdateForDemoControllerTest.php b/tests/src/Functional/ApiContentUpdateForDemoControllerTest.php index 0917a8a0326d04aa95d62dc3ac90e87621762e39..43d007ebe23b5f9dab87425be67a83961dc67f89 100644 --- a/tests/src/Functional/ApiContentUpdateForDemoControllerTest.php +++ b/tests/src/Functional/ApiContentUpdateForDemoControllerTest.php @@ -20,7 +20,7 @@ final class ApiContentUpdateForDemoControllerTest extends FunctionalTestBase { /** * {@inheritdoc} */ - protected static $modules = ['experience_builder']; + protected static $modules = ['experience_builder', 'xb_dev_standard']; /** * {@inheritdoc} diff --git a/tests/src/Kernel/FieldTypeUninstallValidatorTest.php b/tests/src/Kernel/FieldTypeUninstallValidatorTest.php index 01c5108d4dfb659bea3749fc207ce8056d1be2a5..f7f517629e4c8f275889d3a128c79b529e8af37c 100644 --- a/tests/src/Kernel/FieldTypeUninstallValidatorTest.php +++ b/tests/src/Kernel/FieldTypeUninstallValidatorTest.php @@ -31,8 +31,6 @@ final class FieldTypeUninstallValidatorTest extends KernelTestBase { use NodeCreationTrait; use TestDataUtilitiesTrait; - private const XB_FIELD_UNINSTALL_ERROR = 'The <em class="placeholder">Experience Builder</em> field type is used in the following fields: node.field_xb_demo, node.field_xb_test'; - protected function setUp(): void { parent::setUp(); // Clone the current connection and replace the current prefix. @@ -87,7 +85,7 @@ final class FieldTypeUninstallValidatorTest extends KernelTestBase { // is dependency for 'experience_builder' we should get an error because // of the XB fields. $this->assertUninstallFailureReasons( - [self::XB_FIELD_UNINSTALL_ERROR], + ['The <em class="placeholder">Experience Builder</em> field type is used in the following field: node.field_xb_test'], // Ensure 'link' is not in the error message. 'link' ); @@ -153,7 +151,7 @@ final class FieldTypeUninstallValidatorTest extends KernelTestBase { // is dependency for 'experience_builder' we should get an error because // of the XB fields. $this->assertUninstallFailureReasons( - [self::XB_FIELD_UNINSTALL_ERROR], + ['The <em class="placeholder">Experience Builder</em> field type is used in the following fields: node.field_xb_test, taxonomy_term.field_tag_test'], // Ensure 'link' is not in the error message. 'link' ); @@ -174,9 +172,9 @@ final class FieldTypeUninstallValidatorTest extends KernelTestBase { catch (ModuleUninstallValidatorException $exception) { if ($reasons) { $this->assertSame($reasons, array_unique($reasons)); - $this->assertStringContainsString( + $this->assertSame( 'The following reasons prevent the modules from being uninstalled: ' . implode(', ', $reasons), - $exception->getMessage() + strtok($exception->getMessage(), ';'), ); } if ($not_contains) { diff --git a/tests/src/TestSite/XBTestSetup.php b/tests/src/TestSite/XBTestSetup.php index 63badad17b8ba4ec941bfa63c415472dfc13e150..d2a8dc815c269dda9189c57cc3a72bb5aee54675 100644 --- a/tests/src/TestSite/XBTestSetup.php +++ b/tests/src/TestSite/XBTestSetup.php @@ -93,6 +93,7 @@ class XBTestSetup implements TestSetupInterface { ])->save(); $module_installer->install([ 'experience_builder', + 'xb_dev_standard', 'xb_e2e_support', ]);