diff --git a/config/install/default_content_deploy.settings.yml b/config/install/default_content_deploy.settings.yml new file mode 100644 index 0000000..43cbb05 --- /dev/null +++ b/config/install/default_content_deploy.settings.yml @@ -0,0 +1,9 @@ +export_list: + block_content: block_content + file: file + media: media + menu_link_content: menu_link_content + node: node + path_alias: path_alias + taxonomy_term: taxonomy_term + user: user diff --git a/config/schema/default_content_deploy.schema.yml b/config/schema/default_content_deploy.schema.yml new file mode 100644 index 0000000..e98e39e --- /dev/null +++ b/config/schema/default_content_deploy.schema.yml @@ -0,0 +1,11 @@ + +default_content_deploy.settings: + type: config_object + label: 'Default Content Deploy Settings' + mapping: + safe: + type: sequence + label: 'Export List' + sequence: + type: string + label: 'Entity Type' diff --git a/default_content_deploy.links.menu.yml b/default_content_deploy.links.menu.yml index 3e77178..d24fffd 100644 --- a/default_content_deploy.links.menu.yml +++ b/default_content_deploy.links.menu.yml @@ -9,3 +9,11 @@ default_content_deploy.import: description: 'Perform content import (drush dcdi) via UI.' parent: default_content_deploy.settings route_name: default_content_deploy.import + weight: 1 + +default_content_deploy.export: + title: 'Export' + description: 'Perform content export (drush dcde) via UI.' + parent: default_content_deploy.settings + route_name: default_content_deploy.export + weight: 2 diff --git a/default_content_deploy.links.task.yml b/default_content_deploy.links.task.yml index 9471c82..35d1891 100644 --- a/default_content_deploy.links.task.yml +++ b/default_content_deploy.links.task.yml @@ -7,3 +7,11 @@ default_content_deploy.import: base_route: default_content_deploy.settings route_name: default_content_deploy.import title: 'Import' + +default_content_deploy.export: + base_route: default_content_deploy.settings + route_name: default_content_deploy.export + title: 'Export' + +default_content_deploy.export_entity: + deriver: 'Drupal\default_content_deploy\Plugin\Derivative\DynamicLocalTasks' diff --git a/default_content_deploy.module b/default_content_deploy.module new file mode 100644 index 0000000..7e2f5bf --- /dev/null +++ b/default_content_deploy.module @@ -0,0 +1,36 @@ + $entity_type) { + if ($entity_type instanceof ContentEntityType) { + if ($canonical = $entity_type->getLinkTemplate('canonical')) { + $entity_type->setLinkTemplate('dcd-export', $canonical . '/export'); + } + } + } +} + + +/** + * Implements hook_file_download(). + */ +function default_content_deploy_file_download($uri) { + $scheme = \Drupal::service('file_system')->uriScheme($uri); + $target = file_uri_target($uri); + if ($scheme == 'temporary' && $target == 'dcd.tar.gz') { + $request = \Drupal::request(); + $date = DateTime::createFromFormat('U', $request->server->get('REQUEST_TIME')); + $date_string = $date->format('Y-m-d-H-i'); + $hostname = str_replace('.', '-', $request->getHttpHost()); + $filename = 'dcd' . '-' . $hostname . '-' . $date_string . '.tar.gz'; + $disposition = 'attachment; filename="' . $filename . '"'; + return array( + 'Content-disposition' => $disposition, + ); + } +} diff --git a/default_content_deploy.permissions.yml b/default_content_deploy.permissions.yml index 9a60e62..68c2ccc 100644 --- a/default_content_deploy.permissions.yml +++ b/default_content_deploy.permissions.yml @@ -2,3 +2,8 @@ default content deploy import: description: 'Allows user to import exported content via UI. It will overwrite existing content.' title: 'Import content' restrict access: TRUE + +default content deploy export: + description: 'Allows user to export content via UI. It will overwrite existing content.' + title: 'Export content' + restrict access: TRUE diff --git a/default_content_deploy.routing.yml b/default_content_deploy.routing.yml index bcb78a4..58ca948 100644 --- a/default_content_deploy.routing.yml +++ b/default_content_deploy.routing.yml @@ -17,3 +17,19 @@ default_content_deploy.import: _permission: 'default content deploy import' options: _admin_route: TRUE + +default_content_deploy.export: + path: '/admin/config/development/dcd/export' + defaults: + _form: 'Drupal\default_content_deploy\Form\ExportForm' + _title: 'Default Content Deploy - Export' + requirements: + _permission: 'default content deploy export' + + +default_content_deploy.export_download: + path: '/admin/config/development/dcd/export/download' + defaults: + _controller: 'Drupal\default_content_deploy\Controller\DownloadController::downloadExport' + requirements: + _permission: 'default content deploy export' diff --git a/default_content_deploy.services.yml b/default_content_deploy.services.yml index df8073b..ddaad56 100644 --- a/default_content_deploy.services.yml +++ b/default_content_deploy.services.yml @@ -1,7 +1,7 @@ services: default_content_deploy.importer: class: Drupal\default_content_deploy\Importer - arguments: ['@serializer', '@entity_type.manager', '@hal.link_manager', '@event_dispatcher', '@default_content.scanner', '%default_content.link_domain%', '@account_switcher', '@default_content_deploy.manager', '@module_handler', '@logger.channel.default_content_deploy', '@path.alias_storage'] + arguments: ['@serializer', '@entity_type.manager', '@hal.link_manager', '@event_dispatcher', '@default_content.scanner', '%default_content.link_domain%', '@account_switcher', '@default_content_deploy.manager', '@module_handler', '@logger.channel.default_content_deploy', '@path.alias_storage', '@file_system'] default_content_deploy.exporter: class: Drupal\default_content_deploy\Exporter arguments: ['@default_content.exporter', '@database', '@default_content_deploy.manager', '@entity_type.manager', '@serializer', '@account_switcher', '@file_system'] @@ -11,3 +11,8 @@ services: logger.channel.default_content_deploy: parent: logger.channel_base arguments: ['default_content_deploy'] + default_content_deploy.route_subscriber: + class: Drupal\default_content_deploy\Routing\RouteSubscriber + arguments: ['@entity_type.manager'] + tags: + - { name: event_subscriber } diff --git a/src/Controller/DownloadController.php b/src/Controller/DownloadController.php new file mode 100644 index 0000000..c03175d --- /dev/null +++ b/src/Controller/DownloadController.php @@ -0,0 +1,49 @@ +fileDownloadController = $file_download_controller; + } + + /** + * Downloads a tarball of export. + */ + public function downloadExport() { + $request = new Request(['file' => 'dcd.tar.gz']); + return $this->fileDownloadController->download($request, 'temporary'); + } + +} diff --git a/src/Exporter.php b/src/Exporter.php index d66ec38..0956ccf 100644 --- a/src/Exporter.php +++ b/src/Exporter.php @@ -2,6 +2,7 @@ namespace Drupal\default_content_deploy; +use Drupal\Core\Archiver\ArchiveTar; use Drupal\Core\Database\Connection; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\File\FileSystemInterface; @@ -455,8 +456,8 @@ class Exporter { $entity_type_object = $this->entityTypeManager->getDefinition($entity_type); // Removed data. - unset($entity[$entity_type_object->getKey('id')]); - unset($entity[$entity_type_object->getKey('revision')]); + //unset($entity[$entity_type_object->getKey('id')]); + //unset($entity[$entity_type_object->getKey('revision')]); $data = $this->serializer->serialize($entity, 'hal_json', [ 'json_encode_options' => JSON_PRETTY_PRINT @@ -467,4 +468,33 @@ class Exporter { } } + /** + * Create a tarball. + * + * @param string $path + * Path of folder to tar. + */ + public function createArchive($folder) { + // Try to delete existing tarball. + try { + $this->fileSystem->delete($folder . '.tar.gz'); + } + catch (FileException $e) { + // Ignore failed deletes. + } + + // Create new tarball. + $archiver = new ArchiveTar($folder. '.tar.gz', 'gz'); + + // Add our export to tarball. + $archiver->addModify($folder, basename($folder), $folder); + + // Try to delete our export. + try { + $this->fileSystem->deleteRecursive($folder); + } + catch (FileException $e) { + // Ignore failed deletes. + } + } } diff --git a/src/Form/ExportEntityForm.php b/src/Form/ExportEntityForm.php new file mode 100644 index 0000000..1b8308e --- /dev/null +++ b/src/Form/ExportEntityForm.php @@ -0,0 +1,170 @@ +exporter = $exporter; + $this->messenger = $messenger; + $this->deployManager = $deploy_manager; + $this->entityTypeManager = $entity_type_manager; + $this->routeMatch = $routeMatch; + $this->fileSystem = $file_system; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('default_content_deploy.exporter'), + $container->get('messenger'), + $container->get('default_content_deploy.manager'), + $container->get('entity_type.manager'), + $container->get('current_route_match'), + $container->get('file_system') + ); + } + + /** + * {@inheritdoc} + */ + public function getFormId() { + return 'dcd_export_entity_form'; + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, FormStateInterface $form_state) { + $entity = $this->routeMatch->getParameter($this->routeMatch->getParameters()->keys()[0]); + $entity_label = $entity->label(); + + $form['references'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Export with references'), + '#description' => $this->t('Export @entity_label and referenced entities.', ['@entity_label' => $entity_label]), + '#default_value' => FALSE, + ]; + + $form['tar'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Export a tar file'), + '#description' => $this->t('Export a tar file of the current export setting.'), + '#default_value' => FALSE, + ]; + + $form['export'] = [ + '#type' => 'submit', + '#value' => $this->t('Export'), + ]; + + return $form; + } + + /** + * Form submission handler. + * + * @param array $form + * An associative array containing the structure of the form. + * @param \Drupal\Core\Form\FormStateInterface $form_state + * The current state of the form. + * + * @throws \Exception + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + $entity = $this->routeMatch->getParameter($this->routeMatch->getParameters()->keys()[0]); + $entity_ids = [$entity->id()]; + $entity_type = $entity->getEntityTypeId(); + $entity_label = $entity->label(); + + $this->exporter->setEntityTypeId($entity_type); + $this->exporter->setEntityIds($entity_ids); + + if ($form_state->getValue('references')) { + $this->exporter->setMode('reference'); + } + else { + $this->exporter->setMode('default'); + } + + if ($form_state->getValue('tar')) { + $folder = $this->fileSystem->getTempDirectory() . '/dcd'; + $this->exporter->setFolder($folder); + $this->exporter->export(); + $this->exporter->createArchive($folder); + $download_link = Link::fromTextAndUrl($this->t('Download tar file'), Url::fromRoute('default_content_deploy.export_download'))->toString(); + $download_message = Markup::create($download_link); + $this->messenger->addMessage($download_message); + } + else { + $this->exporter->export(); + } + + $message = $this->t('@entity_label has been exported.', ['@entity_label' => $entity_label]); + $this->messenger->addMessage($message); + + } + +} diff --git a/src/Form/ExportForm.php b/src/Form/ExportForm.php new file mode 100644 index 0000000..28d0ce8 --- /dev/null +++ b/src/Form/ExportForm.php @@ -0,0 +1,242 @@ +exporter = $exporter; + $this->messenger = $messenger; + $this->deployManager = $deploy_manager; + $this->entityTypeManager = $entity_type_manager; + $this->fileSystem = $file_system; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('default_content_deploy.exporter'), + $container->get('messenger'), + $container->get('default_content_deploy.manager'), + $container->get('entity_type.manager'), + $container->get('file_system') + ); + } + + /** + * {@inheritdoc} + */ + public function getFormId() { + return 'dcd_export_form'; + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, FormStateInterface $form_state) { + $form['help'] = [ + '#markup' => '

' . $this->t('Select the entity types that should be included when performing an export.') . '

', + + ]; + + // Build the tableselect of entities. + $export_list = $this->config('default_content_deploy.settings')->get('export_list'); + $options = []; + $types = $this->entityTypeManager->getDefinitions(); + foreach ($types as $type => $type_object) { + if ($type_object->getGroup() == 'content' && in_array($type, $export_list)) { + $type = $type; + $options[$type] = [ + 'name' => $type . " (" . $type_object->getLabel() . ")", + ]; + } + } + ksort($options); + + $form['entity_types'] = [ + '#type' => 'tableselect', + '#header' => [ + 'name' => 'Entity type', + ], + '#options' => $options, + + ]; + + $form['export_configuration'] = [ + '#title' => $this->t('Entity Types for Export'), + '#type' => 'details', + '#open' => FALSE, + ]; + + $type_options = []; + foreach ($types as $type => $type_object) { + if ($type_object->getGroup() == 'content') { + $type_options[$type] = $type . " (" . $type_object->getLabel() . ")"; + } + } + ksort($type_options); + + $form['export_configuration']['export_list'] = [ + '#type' => 'checkboxes', + '#title' => $this->t('Entity types available in export configuration'), + '#options' => $type_options, + '#default_value' => $export_list, + ]; + + $form['export_configuration']['export_info'] = [ + '#type' => 'item', + '#markup' => $this->t('Selecting an entity type will modify the available entity type checkboxes. Save Configuration to reload the form after changing these values.') + ]; + + $form['advanced'] = [ + '#title' => $this->t('Advanced settings'), + '#type' => 'details', + '#open' => TRUE, + ]; + + $form['advanced']['references'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Export with references'), + '#description' => $this->t('Export entity type and referenced entity types. (This can add additional entity types that are not selected in the export list.)'), + '#default_value' => FALSE, + ]; + + $form['advanced']['tar'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Export a tar file'), + '#description' => $this->t('Exports a tar file of the current export setting.'), + '#default_value' => FALSE, + ]; + + $form['actions']['#type'] = 'actions'; + $form['actions']['submit'] = [ + '#type' => 'submit', + '#value' => $this->t('Save Configuration'), + '#button_type' => 'primary', + '#name' => 'save' + ]; + $form['actions']['export'] = [ + '#type' => 'submit', + '#value' => $this->t('Export Content'), + '#name' => 'export' + ]; + + return $form; + } + + /** + * Form submission handler. + * + * @param array $form + * An associative array containing the structure of the form. + * @param \Drupal\Core\Form\FormStateInterface $form_state + * The current state of the form. + * + * @throws \Exception + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + $settings = $this->configFactory()->getEditable('default_content_deploy.settings'); + $export_list = $form_state->getValue('export_list'); + foreach ($export_list as $key => $value) { + if ($value == '0') { + unset($export_list[$key]); + } + } + $settings->set('export_list', $export_list)->save(); + $trigger = $form_state->getTriggeringElement(); + if ($trigger['#name'] == 'export') { + foreach ($form_state->getValue('entity_types') as $entity_type => $checked) { + if (\Drupal::entityQuery($entity_type)->execute() && $checked) { + $this->exporter->setEntityTypeId($entity_type); + + if ($form_state->getValue('references')) { + $this->exporter->setMode('reference'); + } + else { + $this->exporter->setMode('default'); + } + + if ($form_state->getValue('tar')) { + $folder = $this->fileSystem->getTempDirectory() . '/dcd'; + $this->exporter->setFolder($folder); + $this->exporter->export(); + $this->exporter->createArchive($folder); + $download_link = Link::fromTextAndUrl($this->t('Download tar file'), Url::fromRoute('default_content_deploy.export_download'))->toString(); + $download_message = Markup::create($download_link); + $this->messenger->addMessage($download_message); + } + else { + $this->exporter->export(); + } + + $message = $this->t('@entity_type has been exported.', ['@entity_type' => $entity_type]); + $this->messenger->addMessage($message); + + } + } + } + } + +} diff --git a/src/Form/ImportForm.php b/src/Form/ImportForm.php index 27d5e13..fef903a 100644 --- a/src/Form/ImportForm.php +++ b/src/Form/ImportForm.php @@ -2,6 +2,8 @@ namespace Drupal\default_content_deploy\Form; +use Drupal\Core\Archiver\ArchiveTar; +use Drupal\Core\File\FileSystemInterface; use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Messenger\Messenger; @@ -28,6 +30,12 @@ class ImportForm extends FormBase { */ protected $deployManager; + /** + * The file system service. + * + * @var \Drupal\Core\File\FileSystemInterface + */ + protected $fileSystem; /** * ImportForm constructor. @@ -35,11 +43,15 @@ class ImportForm extends FormBase { * @param \Drupal\default_content_deploy\Importer $importer * @param \Drupal\Core\Messenger\Messenger $messenger * @param \Drupal\default_content_deploy\DeployManager $deploy_manager + * @param \Drupal\Core\File\FileSystemInterface $file_system + * The file system service. */ - public function __construct(Importer $importer, Messenger $messenger, DeployManager $deploy_manager ) { + public function __construct(Importer $importer, Messenger $messenger, DeployManager $deploy_manager, FileSystemInterface $file_system) { $this->importer = $importer; $this->messenger = $messenger; $this->deployManager = $deploy_manager; + $this->fileSystem = $file_system; + } /** @@ -49,7 +61,8 @@ class ImportForm extends FormBase { return new static( $container->get('default_content_deploy.importer'), $container->get('messenger'), - $container->get('default_content_deploy.manager') + $container->get('default_content_deploy.manager'), + $container->get('file_system') ); } @@ -94,6 +107,18 @@ class ImportForm extends FormBase { '#default_value' => FALSE, ]; + $form['advanced_settings'] = [ + '#title' => $this->t('Advanced settings'), + '#type' => 'details', + '#open' => TRUE, + ]; + + $form['advanced_settings']['import_tarball'] = [ + '#type' => 'file', + '#title' => $this->t('Import from a tar file.'), + '#description' => $this->t('This will not update existing content in a content directory.'), + ]; + $form['import'] = [ '#type' => 'submit', '#value' => $this->t('Import content'), @@ -102,6 +127,23 @@ class ImportForm extends FormBase { return $form; } + /** + * {@inheritdoc} + */ + public function validateForm(array &$form, FormStateInterface $form_state) { + $all_files = $this->getRequest()->files->get('files', []); + if (!empty($all_files['import_tarball'])) { + $file_upload = $all_files['import_tarball']; + if ($file_upload->isValid()) { + $form_state->setValue('import_tarball', $file_upload->getRealPath()); + return; + } + else { + $form_state->setErrorByName('import_tarball', $this->t('The file could not be uploaded.')); + } + } + } + /** * Form submission handler. * @@ -117,7 +159,13 @@ class ImportForm extends FormBase { $forceUpdate = $form_state->getValue('force-update', FALSE); $forceOverride = $form_state->getValue('force-override', FALSE); $preservePassword = $form_state->getValue('preserve-password', FALSE); - $result_info = $this->importer->deployContent($folder, $forceUpdate, $forceOverride, $preservePassword, TRUE); + + if ($path = $form_state->getValue('import_tarball')) { + $result_info = $this->importer->deployArchive($path,$forceUpdate, $forceOverride, $preservePassword, TRUE); + } + else { + $result_info = $this->importer->deployContent($folder, $forceUpdate, $forceOverride, $preservePassword, TRUE); + } $message = $this->t('@count entities have been imported.', ['@count' => $result_info['processed']]); $message .= " "; diff --git a/src/Importer.php b/src/Importer.php index 63a67ec..3bdf7c3 100644 --- a/src/Importer.php +++ b/src/Importer.php @@ -3,10 +3,12 @@ namespace Drupal\default_content_deploy; use Drupal\Component\Serialization\Json; +use Drupal\Core\Archiver\ArchiveTar; use Drupal\Core\Config\Entity\ConfigEntityInterface; use Drupal\Core\Entity\Entity; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Extension\ModuleHandlerInterface; +use Drupal\Core\File\FileSystemInterface; use Drupal\Core\Path\AliasStorageInterface; use Drupal\Core\Session\AccountSwitcherInterface; use Drupal\default_content\Importer as DCImporter; @@ -68,6 +70,13 @@ class Importer extends DCImporter { */ private $pathAliasStorage; + /** + * The file system service. + * + * @var \Drupal\Core\File\FileSystemInterface + */ + protected $fileSystem; + /** * Constructs the default content deploy manager. * @@ -93,8 +102,10 @@ class Importer extends DCImporter { * Logger. * @param \Drupal\Core\Path\AliasStorageInterface $path_alias_storage * The path alias storage service. + * @param \Drupal\Core\File\FileSystemInterface $file_system + * The file system service. */ - public function __construct(Serializer $serializer, EntityTypeManagerInterface $entity_type_manager, LinkManagerInterface $link_manager, EventDispatcherInterface $event_dispatcher, ScannerInterface $scanner, $link_domain, AccountSwitcherInterface $account_switcher, DeployManager $deploy_manager, ModuleHandlerInterface $module_handler, LoggerInterface $logger, AliasStorageInterface $path_alias_storage) { + public function __construct(Serializer $serializer, EntityTypeManagerInterface $entity_type_manager, LinkManagerInterface $link_manager, EventDispatcherInterface $event_dispatcher, ScannerInterface $scanner, $link_domain, AccountSwitcherInterface $account_switcher, DeployManager $deploy_manager, ModuleHandlerInterface $module_handler, LoggerInterface $logger, AliasStorageInterface $path_alias_storage, FileSystemInterface $file_system) { parent::__construct($serializer, $entity_type_manager, $link_manager, $event_dispatcher, $scanner, $link_domain, $account_switcher); $this->deployManager = $deploy_manager; @@ -105,6 +116,7 @@ class Importer extends DCImporter { $this->moduleHandler->moduleExists('file_entity') || $this->moduleHandler->moduleExists('better_normalizers') ); + $this->fileSystem = $file_system; } /** @@ -567,4 +579,36 @@ class Importer extends DCImporter { return $entity; } + /** + * Import from an archive. + * + * @param string $path + * Path to tarball. + * @param bool $force_update + * TRUE for overwrite entities with matching ID but different UUID. + * @param bool $force_override + * TRUE for override all imported entities. Locally updated content + * will be updated to imported version. + * @param bool $preserve_password + * TRUE will preserve user password. + */ + public function deployArchive($path, $forceUpdate, $forceOverride, $preservePassword) { + try { + $archiver = new ArchiveTar($path, 'gz'); + $files = []; + foreach ($archiver->listContent() as $file) { + $files[] = $file['filename']; + } + $folder = $this->fileSystem->getTempDirectory(); + $archiver->extractList($files, $folder, '', FALSE, FALSE); + + $result_info = $this->deployContent($folder . '/dcd', $forceUpdate, $forceOverride, $preservePassword, TRUE); + $this->fileSystem->deleteRecursive($folder . '/dcd'); + } + catch (\Exception $e) { + } + $this->fileSystem->unlink($path); + return $result_info; + } + } diff --git a/src/Plugin/Derivative/DynamicLocalTasks.php b/src/Plugin/Derivative/DynamicLocalTasks.php new file mode 100644 index 0000000..09daedf --- /dev/null +++ b/src/Plugin/Derivative/DynamicLocalTasks.php @@ -0,0 +1,73 @@ +entityTypeManager = $entity_type_manager; + $this->stringTranslation = $string_translation; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, $base_plugin_id) { + return new static( $container->get('entity_type.manager'), + $container->get('string_translation') + ); + } + + /** + * {@inheritdoc} + */ + public function getDerivativeDefinitions($base_plugin_definition) { + + $this->derivatives = []; + + foreach ($this->entityTypeManager->getDefinitions() as $entity_type_id => $entity_type) { + + $has_export = $entity_type->hasLinkTemplate('dcd-export'); + + if ($has_export) { + + $this->derivatives["$entity_type_id.dcd-export"] = [ + 'route_name' => "entity.$entity_type_id.dcd-export", + 'title' => $this->t('Export'), + 'base_route' => "entity.$entity_type_id.canonical", + 'weight' => 100, + ]; + + } + } + + return $this->derivatives; + } +} diff --git a/src/Routing/RouteSubscriber.php b/src/Routing/RouteSubscriber.php new file mode 100644 index 0000000..d73fb70 --- /dev/null +++ b/src/Routing/RouteSubscriber.php @@ -0,0 +1,73 @@ +entityTypeManager = $entity_manager; + } + + /** + * {@inheritdoc} + */ + protected function alterRoutes(RouteCollection $collection) { + + foreach ($this->entityTypeManager->getDefinitions() as $entity_type_id => $entity_type) { + + if ($export = $entity_type->getLinkTemplate('dcd-export')) { + $entity_type_id = $entity_type->id(); + $route = new Route($export); + $route + ->addDefaults([ + '_form' => '\Drupal\default_content_deploy\Form\ExportEntityForm', + '_title' => 'Export', + ]) + ->addRequirements([ + '_permission' => 'export content', + ]) + ->setOption('_admin_route', TRUE) + ->setOption('parameters', [ + $entity_type_id => ['type' => 'entity:' . $entity_type_id], + ]); + + $collection->add("entity.$entity_type_id.dcd-export", $route); + } + + } + + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() { + $events = parent::getSubscribedEvents(); + $events[RoutingEvents::ALTER] = ['onAlterRoutes', 100]; + return $events; + } + +}