diff --git a/layout_builder_asset.module b/layout_builder_asset.module index 182aee0..7b92090 100644 --- a/layout_builder_asset.module +++ b/layout_builder_asset.module @@ -5,11 +5,40 @@ * Provides hook implementations for Layout Builder Asset. */ +use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\FieldableEntityInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\layout_builder_asset\Form\OverridesContentEntityForm; use Drupal\layout_builder_asset\LayoutBuilderAssetInterface; +/** + * Implements hook_ENTITY_TYPE_delete(). + * + * Delete the assets(css, js) if a layout builder + * entity is deleted. + */ +function layout_builder_asset_node_delete(EntityInterface $entity) { + if ($entity->hasField('layout_builder__layout')) { + $layoutBuilder = $entity->get('layout_builder__layout')->getValue(); + foreach ($layoutBuilder as $section) { + $section = $section['section']; + foreach ($section->getComponents() as $component) { + $additional = $component->get('additional'); + if (isset($additional['layout_builder_asset_style'])) { + $css = \Drupal::entityTypeManager()->getStorage('layout_builder_asset_css'); + $asset = $css->load($additional['layout_builder_asset_style']['id']); + $asset && $asset->delete(); + } + if (isset($additional['layout_builder_asset_js'])) { + $js = \Drupal::entityTypeManager()->getStorage('layout_builder_asset_js'); + $asset = $js->load($additional['layout_builder_asset_js']['id']); + $asset && $asset->delete(); + } + } + } + } +} + /** * Implements hook_form_alter(). * @@ -79,8 +108,8 @@ function _layout_builder_asset_add_style_selection_form_element(array &$form, $f '#title' => t('Class'), '#description' => t('Add Unique Class for the Block to apply the css specifically to the current context or keep empty to use the default config block.'), ]; - $cssID = $component->get('additional')['layout_builder_asset_style_data']['id']; - $jsID = $component->get('additional')['layout_builder_asset_js_data']['id']; + $cssID = $component->get('additional')['layout_builder_asset_style']['id']; + $jsID = $component->get('additional')['layout_builder_asset_js']['id']; $form['css_id'] = [ '#type' => 'hidden', '#value' => $cssID, @@ -90,8 +119,8 @@ function _layout_builder_asset_add_style_selection_form_element(array &$form, $f '#value' => $jsID, ]; if ($form['#form_id'] === 'layout_builder_update_block') { - $componentAdditionalCssData = $component->get('additional')['layout_builder_asset_style_data']; - $componentAdditionalJsData = $component->get('additional')['layout_builder_asset_js_data']; + $componentAdditionalCssData = $component->get('additional')['layout_builder_asset_style']; + $componentAdditionalJsData = $component->get('additional')['layout_builder_asset_js']; $data = []; // Load the CSS data from the created asset entity // else from the tempStorage. @@ -159,19 +188,25 @@ function _layout_builder_asset_submit_block_form(array $form, FormStateInterface $config_id = $prefixed_config_id . '.block-' . str_replace([':', '_'], ['', '-'], $cid); } // For CSS. - $data['code'] = get_prefixed_css($formState->getValue('layout_builder_asset'), $config_id); - $data['label'] = ($values['settings']['label']) ? $values['settings']['label'] : $values['settings']['views_label']; - $data['class'] = $formState->getValue('block_class'); + if ($component->get('additional')['layout_builder_asset_style']) { + $data = $component->get('additional')['layout_builder_asset_style']; + $data['id'] = $formState->getValue('css_id'); + $data['code'] = get_prefixed_css($formState->getValue('layout_builder_asset'), $config_id); + $data['label'] = ($values['settings']['label']) ? $values['settings']['label'] : $values['settings']['views_label']; + $data['class'] = $formState->getValue('block_class'); - $component->set('layout_builder_asset_style_data', $data); - $component->set('layout_builder_asset_id', $formState->getValue('css_id')); + $component->set('layout_builder_asset_style', $data); + } // For JS. - $data['code'] = get_prefixed_js($formState->getValue('layout_builder_asset_js')); - $data['class'] = $formState->getValue('block_class'); - $data['label'] = ($values['settings']['label']) ? $values['settings']['label'] : $values['settings']['views_label']; + if ($component->get('additional')['layout_builder_asset_js']) { + $data = $component->get('additional')['layout_builder_asset_js']; + $data['id'] = $formState->getValue('js_id'); + $data['code'] = get_prefixed_js($formState->getValue('layout_builder_asset_js')); + $data['class'] = $formState->getValue('block_class'); + $data['label'] = ($values['settings']['label']) ? $values['settings']['label'] : $values['settings']['views_label']; - $component->set('layout_builder_asset_js_data', $data); - $component->set('layout_builder_asset_js_id', $formState->getValue('js_id')); + $component->set('layout_builder_asset_js', $data); + } } else { // Create the required data, which will create the block when @@ -192,7 +227,7 @@ function _layout_builder_asset_submit_block_form(array $form, FormStateInterface $data['getoriginalId'] = $data['id']; $data['nodeType'] = 'css'; $data['class'] = $formState->getValue('block_class'); - $component->set('layout_builder_asset_style_data', $data); + $component->set('layout_builder_asset_style', $data); } if (!empty($values['layout_builder_asset_js'])) { // ['settings']['label']; @@ -208,7 +243,7 @@ function _layout_builder_asset_submit_block_form(array $form, FormStateInterface $data['status'] = TRUE; $data['getoriginalId'] = $data['id']; $data['nodeType'] = 'js'; - $component->set('layout_builder_asset_js_data', $data); + $component->set('layout_builder_asset_js', $data); } } } diff --git a/src/EventSubscriber/BlockRendererListener.php b/src/EventSubscriber/BlockRendererListener.php index 50cbad4..7cb8b18 100644 --- a/src/EventSubscriber/BlockRendererListener.php +++ b/src/EventSubscriber/BlockRendererListener.php @@ -135,12 +135,8 @@ class BlockRendererListener implements EventSubscriberInterface if ($is_content_empty && $is_placeholder_ready) { $build['content']['#markup'] = $this->t('Placeholder for the @preview_fallback', ['@preview_fallback' => $block->getPreviewFallbackString()]); } - $css_id = $event->getComponent()->get('layout_builder_asset_id'); - $js_id = $event->getComponent()->get('layout_builder_asset_js_id'); - - $additional = $event->getComponent()->get('additional'); $class = ''; - if ($css_id) { + if ($css_id = $event->getComponent()->get('layout_builder_asset_style')['id']) { //@todo : To make the library name dynamically $layout_builder_asset = \Drupal::entityTypeManager()->getStorage('layout_builder_asset_css')->load($css_id); if ($layout_builder_asset) { @@ -148,7 +144,7 @@ class BlockRendererListener implements EventSubscriberInterface } $build['#attached']['library'][] = 'layout_builder_asset/css/' . $css_id; } - if ($js_id) { + if ($js_id = $event->getComponent()->get('layout_builder_asset_js')['id']) { //@todo : To make the library name dynamically $layout_builder_asset = \Drupal::entityTypeManager()->getStorage('layout_builder_asset_js')->load($js_id); if ($layout_builder_asset) { diff --git a/src/EventSubscriber/RouteSubscriber.php b/src/EventSubscriber/RouteSubscriber.php index 5549840..77e18e5 100644 --- a/src/EventSubscriber/RouteSubscriber.php +++ b/src/EventSubscriber/RouteSubscriber.php @@ -23,8 +23,7 @@ class RouteSubscriber extends RouteSubscriberBase { if ($addBlockRoute) { $addBlockRoute->setDefault('_form', '\Drupal\layout_builder_asset\Form\AddBlockForm'); } - $updateBlockRoute = $collection->get('layout_builder.update_block'); - if ($updateBlockRoute) { + if ($updateBlockRoute = $collection->get('layout_builder.update_block')) { $updateBlockRoute->setDefault('_form', '\Drupal\layout_builder_asset\Form\UpdateBlockForm'); } if ($removeBlockRoute = $collection->get('layout_builder.remove_block')) { @@ -33,7 +32,6 @@ class RouteSubscriber extends RouteSubscriberBase { if ($removeSectionRoute = $collection->get('layout_builder.remove_section')) { $removeSectionRoute->setDefault('_form', '\Drupal\layout_builder_asset\Form\RemoveSectionForm'); } - } } diff --git a/src/Form/OverridesContentEntityForm.php b/src/Form/OverridesContentEntityForm.php index 0bf71e3..00150b0 100644 --- a/src/Form/OverridesContentEntityForm.php +++ b/src/Form/OverridesContentEntityForm.php @@ -2,8 +2,15 @@ namespace Drupal\layout_builder_asset\Form; +use Drupal\Component\Datetime\TimeInterface; +use Drupal\Core\Entity\EntityRepositoryInterface; +use Drupal\Core\Entity\EntityTypeBundleInfoInterface; +use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\TempStore\PrivateTempStoreFactory; use Drupal\layout_builder\Form\OverridesEntityForm; +use Drupal\layout_builder\LayoutTempstoreRepositoryInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * On saving the layout, creating the asset entity. @@ -24,6 +31,49 @@ class OverridesContentEntityForm extends OverridesEntityForm { */ protected $assetCss; + /** + * The tempstore factory. + * + * @var \Drupal\Core\TempStore\PrivateTempStoreFactory + */ + protected $tempStoreFactory; + + /** + * Constructs a new OverridesEntityForm. + * + * @param \Drupal\Core\Entity\EntityRepositoryInterface $entity_repository + * The entity repository service. + * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info + * The entity type bundle service. + * @param \Drupal\Component\Datetime\TimeInterface $time + * The time service. + * @param \Drupal\layout_builder\LayoutTempstoreRepositoryInterface $layout_tempstore_repository + * The layout tempstore repository. + * @param \Drupal\Core\TempStore\PrivateTempStoreFactory $tempStoreFactory + * The tempstore factory. + * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityManager + * The Entity Manager Interface. + */ + public function __construct(EntityRepositoryInterface $entity_repository, EntityTypeBundleInfoInterface $entity_type_bundle_info, TimeInterface $time, LayoutTempstoreRepositoryInterface $layout_tempstore_repository, PrivateTempStoreFactory $tempStoreFactory, EntityTypeManagerInterface $entityManager) { + parent::__construct($entity_repository, $entity_type_bundle_info, $time, $layout_tempstore_repository); + $this->tempStoreFactory = $tempStoreFactory; + $this->entityTypeManager = $entityManager; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('entity.repository'), + $container->get('entity_type.bundle.info'), + $container->get('datetime.time'), + $container->get('layout_builder.tempstore_repository'), + $container->get('tempstore.private'), + $container->get('entity_type.manager') + ); + } + /** * {@inheritdoc} */ @@ -31,46 +81,70 @@ class OverridesContentEntityForm extends OverridesEntityForm { $layoutBuilder = $this->entity->get('layout_builder__layout')->getValue(); $this->assetCss = $this->entityTypeManager->getStorage('layout_builder_asset_css'); $this->assetJs = $this->entityTypeManager->getStorage('layout_builder_asset_js'); + // Deleting any asset if needed. + $this->deleteAsset(); foreach ($layoutBuilder as $section) { $section = $section['section']; foreach ($section->getComponents() as $component) { - if (!empty($component->get('additional')['layout_builder_asset_style_data'])) { + if (!empty($component->get('additional')['layout_builder_asset_style'])) { // Updated the CSS Asset entity. - if (isset($component->get('additional')['layout_builder_asset_id'])) { - $layoutBuilderAssetCss = $this->assetCss->load($component->get('additional')['layout_builder_asset_id']); - $layoutBuilderAssetCss->code = $component->get('additional')['layout_builder_asset_style_data']['code']; - $layoutBuilderAssetCss->label = $component->get('additional')['layout_builder_asset_style_data']['label']; - $layoutBuilderAssetCss->class = $component->get('additional')['layout_builder_asset_style_data']['class']; + if ($layoutBuilderAssetCss = $this->assetCss->load($component->get('additional')['layout_builder_asset_style']['id'])) { + $layoutBuilderAssetCss->code = $component->get('additional')['layout_builder_asset_style']['code']; + $layoutBuilderAssetCss->label = $component->get('additional')['layout_builder_asset_style']['label']; + $layoutBuilderAssetCss->class = $component->get('additional')['layout_builder_asset_style']['class']; $layoutBuilderAssetCss->save(); } // Create the CSS Asset entity. else { - $layout_builder_asset = $this->assetCss->create($component->get('additional')['layout_builder_asset_style_data']); + $layout_builder_asset = $this->assetCss->create($component->get('additional')['layout_builder_asset_style']); $layout_builder_asset->save(); - $component->set('layout_builder_asset_id', $layout_builder_asset->id); } - $component->set('layout_builder_asset_style', $component->get('additional')['layout_builder_asset_style_data']['code']); } - if (!empty($component->get('additional')['layout_builder_asset_js_data'])) { + if (!empty($component->get('additional')['layout_builder_asset_js'])) { // Updated the JS Asset entity. - if (isset($component->get('additional')['layout_builder_asset_js_id'])) { - $layoutBuilderAssetJs = $this->assetJs->load($component->get('additional')['layout_builder_asset_js_id']); - $layoutBuilderAssetJs->code = $component->get('additional')['layout_builder_asset_js_data']['code']; - $layoutBuilderAssetJs->label = $component->get('additional')['layout_builder_asset_js_data']['label']; - $layoutBuilderAssetJs->class = $component->get('additional')['layout_builder_asset_js_data']['class']; + if ($layoutBuilderAssetJs = $this->assetJs->load($component->get('additional')['layout_builder_asset_js']['id'])) { + $layoutBuilderAssetJs->code = $component->get('additional')['layout_builder_asset_js']['code']; + $layoutBuilderAssetJs->label = $component->get('additional')['layout_builder_asset_js']['label']; + $layoutBuilderAssetJs->class = $component->get('additional')['layout_builder_asset_js']['class']; $layoutBuilderAssetJs->save(); } // Create the Js Asset entity. else { - $layout_builder_asset = $this->assetJs->create($component->get('additional')['layout_builder_asset_js_data']); + $layout_builder_asset = $this->assetJs->create($component->get('additional')['layout_builder_asset_js']); $layout_builder_asset->save(); - $component->set('layout_builder_asset_js_id', $layout_builder_asset->id); } - $component->set('layout_builder_asset_js', $component->get('additional')['layout_builder_asset_js_data']['code']); } } } return parent::save($form, $form_state);; } + /** + * Delete all the Assets for the layout builder. + * + * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException + * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException + * @throws \Drupal\Core\Entity\EntityStorageException + * @throws \Drupal\Core\TempStore\TempStoreException + */ + protected function deleteAsset() { + $store = $this->tempStoreFactory->get('layout_builder_asset'); + if (!empty($store->get('deleted'))) { + + // Delete both the entity (css and js). + // Both has the same id. + $entitiesName = ['layout_builder_asset_js', 'layout_builder_asset_css']; + if ($ids = $store->get('deleted')) { + foreach ($ids as $id) { + foreach ($entitiesName as $entityName) { + $assetEntity = $this->entityTypeManager->getStorage($entityName); + $asset = $assetEntity->load($id); + $asset && $asset->delete(); + } + } + $store->delete('deleted'); + } + } + } + } diff --git a/src/Form/RemoveBlockForm.php b/src/Form/RemoveBlockForm.php index 1dd8654..f64b219 100644 --- a/src/Form/RemoveBlockForm.php +++ b/src/Form/RemoveBlockForm.php @@ -3,13 +3,42 @@ namespace Drupal\layout_builder_asset\Form; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\TempStore\PrivateTempStoreFactory; use Drupal\layout_builder\Form\RemoveBlockForm as OriginalRemoveBlockForm; +use Drupal\layout_builder\LayoutTempstoreRepositoryInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * {@inheritdoc} */ class RemoveBlockForm extends OriginalRemoveBlockForm { + /** + * The tempstore factory. + * + * @var \Drupal\Core\TempStore\PrivateTempStoreFactory + */ + protected $tempStoreFactory; + + /** + * {@inheritdoc} + */ + public function __construct(LayoutTempstoreRepositoryInterface $layout_tempstore_repository, PrivateTempStoreFactory $tempStoreFactory) { + parent::__construct($layout_tempstore_repository); + $this->tempStoreFactory = $tempStoreFactory; + + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('layout_builder.tempstore_repository'), + $container->get('tempstore.private') + ); + } + /** * {@inheritdoc} */ @@ -19,21 +48,23 @@ class RemoveBlockForm extends OriginalRemoveBlockForm { } /** - * Delete the Asset Config entity of the Block. + * Create tempStorage for deleted assets. + * + * Mark the Asset Config entity of the Block as deleted, + * so that it will be deleted while saving the layout. */ protected function handleLayoutBuilderAssetStorage() { - $selectedAssetName = str_replace(' ', '_', strtolower( - $this->sectionStorage - ->getSection($this->delta) - ->getComponent($this->uuid) - ->getPlugin() - ->label() - )); - $entitiesName = ['layout_builder_asset_js', 'layout_builder_asset_css']; - foreach ($entitiesName as $entityName) { - $assetEntity = \Drupal::entityTypeManager()->getStorage($entityName); - $asset = $assetEntity->load($selectedAssetName); - $asset->delete(); + $component = $this->sectionStorage->getSection($this->delta)->getComponent($this->uuid); + if (!empty($component->get('additional'))) { + $store = $this->tempStoreFactory->get('layout_builder_asset'); + $ids = !empty($store->get('deleted')) ? $store->get('deleted') : []; + if ($id = $component->get('layout_builder_asset_js')['id']) { + $ids = [$id]; + } + elseif ($id = $component->get('layout_builder_asset_style')['id']) { + $ids = [$id]; + } + $store->set('deleted', $ids); } } diff --git a/src/Form/RemoveSectionForm.php b/src/Form/RemoveSectionForm.php index 5140be1..1e39a4c 100644 --- a/src/Form/RemoveSectionForm.php +++ b/src/Form/RemoveSectionForm.php @@ -3,13 +3,41 @@ namespace Drupal\layout_builder_asset\Form; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\TempStore\PrivateTempStoreFactory; use Drupal\layout_builder\Form\RemoveSectionForm as OriginalRemoveSectionForm; +use Drupal\layout_builder\LayoutTempstoreRepositoryInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * {@inheritdoc} */ class RemoveSectionForm extends OriginalRemoveSectionForm { + /** + * The tempstore factory. + * + * @var \Drupal\Core\TempStore\PrivateTempStoreFactory + */ + protected $tempStoreFactory; + + /** + * {@inheritdoc} + */ + public function __construct(LayoutTempstoreRepositoryInterface $layout_tempstore_repository, PrivateTempStoreFactory $tempStoreFactory) { + parent::__construct($layout_tempstore_repository); + $this->tempStoreFactory = $tempStoreFactory; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('layout_builder.tempstore_repository'), + $container->get('tempstore.private') + ); + } + /** * {@inheritdoc} */ @@ -23,17 +51,22 @@ class RemoveSectionForm extends OriginalRemoveSectionForm { */ protected function handleLayoutBuilderAssetStorage() { $components = $this->sectionStorage->getSection($this->delta)->getComponents(); + $store = $this->tempStoreFactory->get('layout_builder_asset'); + $ids = !empty($store->get('deleted')) ? $store->get('deleted') : []; + $flag = FALSE; foreach ($components as $component) { - $selectedAssetName = str_replace(' ', '_', strtolower($component->getPlugin()->label())); - $entitiesName = ['layout_builder_asset_js', 'layout_builder_asset_css']; - if ($selectedAssetName) { - foreach ($entitiesName as $entityName) { - $assetEntity = \Drupal::entityTypeManager()->getStorage($entityName); - $asset = $assetEntity->load($selectedAssetName); - $asset && $asset->delete(); + if ($flag = !empty($component->get('additional'))) { + $id = NULL; + if ($component->get('layout_builder_asset_js')['id']) { + $id = $component->get('layout_builder_asset_js')['id']; + } + elseif ($component->get('layout_builder_asset_style')['id']) { + $id = $component->get('layout_builder_asset_style')['id']; } + $ids[] = $id; } } + $flag && $store->set('deleted', $ids); } }