diff --git a/README.md b/README.md index c22fb9e..7dfa60e 100644 --- a/README.md +++ b/README.md @@ -111,6 +111,9 @@ Exports a single entity or group of entities with no references. drush dcde node Export all nodes. + drush dcde node --folder='../content' +Export all nodes from the specified folder. + drush dcde node --bundle=page Export all nodes with bundle (content type) page. @@ -149,6 +152,9 @@ The options are identical in drush dcde. drush dcder node Export all nodes with references + drush dcder node --folder='../content' +Export all nodes with references from the specified folder + drush dcder node --bundle=page Export all nodes with references with bundle page @@ -249,6 +255,7 @@ will be reverted to the state defined in a content directory. **Examples** drush dcdi + drush dcdi --folder='../content' drush dcdi --force-update drush dcdi --verbose drush dcdi --verbose --force-update diff --git a/src/Commands/DefaultContentDeployCommands.php b/src/Commands/DefaultContentDeployCommands.php index a201cbb..a0ef07a 100644 --- a/src/Commands/DefaultContentDeployCommands.php +++ b/src/Commands/DefaultContentDeployCommands.php @@ -70,6 +70,8 @@ class DefaultContentDeployCommands extends DrushCommands { * @option skip_entities The ID of the entity to skip. * @usage drush dcde node * Export all nodes + * @usage drush dcde node --folder='../content' + * Export all nodes from the specified folder. * @usage drush dcde node --bundle=page * Export all nodes with bundle page * @usage drush dcde node --bundle=page,article --entity_id=2,3,4 @@ -88,13 +90,15 @@ class DefaultContentDeployCommands extends DrushCommands { 'entity_id' => NULL, 'bundle' => NULL, 'skip_entities' => NULL, + 'folder' => self::OPT, ]) { $entity_ids = $options['entity_id']; $entity_bundles = $options['bundle']; $skip_entities = $options['skip_entities']; + $folder = $options['folder']; try { - $count = $this->exporter->export($entityType, $entity_bundles, $entity_ids, $skip_entities); + $count = $this->exporter->export($entityType, $entity_bundles, $entity_ids, $skip_entities, $folder); $this->logger->notice(dt('Exported @count entities.', ['@count' => $count])); } catch (\InvalidArgumentException $e) { @@ -119,17 +123,19 @@ class DefaultContentDeployCommands extends DrushCommands { * @option entity_id The ID of the entity to export. * @option bundle Write out the exported bundle of entity * @option skip_entities The ID of the entity to skip. - * @usage drush dcde node + * @usage drush dcder node * Export all nodes with references - * @usage drush dcde node --bundle=page + * @usage drush dcder node --folder='../content' + * Export all nodes with references from the specified folder. + * @usage drush dcder node --bundle=page * Export all nodes with references with bundle page - * @usage drush dcde node --bundle=page,article --entity_id=2,3,4 + * @usage drush dcder node --bundle=page,article --entity_id=2,3,4 * Export all nodes with references with bundle page or article plus nodes * with entitiy id 2, 3 and 4. - * @usage drush dcde node --bundle=page,article --skip_entities=5,7 + * @usage drush dcder node --bundle=page,article --skip_entities=5,7 * Export all nodes with references with bundle page or article and skip * nodes with entity id 5 and 7. - * @usage drush dcde node --skip_entities=5,7 + * @usage drush dcder node --skip_entities=5,7 * Export all nodes and skip nodes with references with entity id 5 and 7. * @validate-module-enabled default_content * @aliases dcder,default-content-deploy-export-with-references @@ -139,13 +145,15 @@ class DefaultContentDeployCommands extends DrushCommands { 'entity_id' => NULL, 'bundle' => NULL, 'skip_entities' => NULL, + 'folder' => self::OPT, ]) { $entity_ids = $options['entity_id']; $entity_bundles = $options['bundle']; $skip_entities = $options['skip_entities']; + $folder = $options['folder']; try { - $count = $this->exporter->exportWithReferences($entityType, $entity_bundles, $entity_ids, $skip_entities); + $count = $this->exporter->exportWithReferences($entityType, $entity_bundles, $entity_ids, $skip_entities, $folder); $this->logger->notice(dt('Exported @count entities with references.', ['@count' => $count])); } catch (\InvalidArgumentException $e) { @@ -178,6 +186,8 @@ class DefaultContentDeployCommands extends DrushCommands { * Use 'drush dcd-entity-list' for list of all content entities. * @usage drush dcdes * Export complete website. + * @usage drush dcdes --folder='../content' + * Export complete website from the specified folder. * @usage drush dcdes --skip_entity_type=node,user * Export complete website but skip nodes and users. * @validate-module-enabled default_content @@ -186,14 +196,16 @@ class DefaultContentDeployCommands extends DrushCommands { public function contentDeployExportSite(array $options = [ 'add_entity_type' => NULL, 'skip_entity_type' => NULL, + 'folder' => self::OPT, ]) { + $folder = $options['folder']; // @todo Remove in beta version. if ($options['add_entity_type']) { $this->logger->notice(dt('Option add_entity_type is deprecated and will be disabled in a future. The drush dcdes command exports all content entity by default.')); } $skip_entity_type = $options['skip_entity_type']; - $count = $this->exporter->exportSite($skip_entity_type); + $count = $this->exporter->exportSite($skip_entity_type, $folder); foreach ($count as $entity => $value) { $this->logger->notice(dt('Exported @count entities of type @entity.', [ @@ -203,21 +215,27 @@ class DefaultContentDeployCommands extends DrushCommands { } // Also export path aliases. - $this->contentDeployExportAliases(); + $this->contentDeployExportAliases($folder); } /** * Exports site url aliases. * + * @param array $options + * An associative array of options. + * * @command default-content-deploy:export-aliases * * @usage drush dcdea * Export url aliases. + * @usage drush dcdea --folder='../content' + * Export url aliases from the specified folder. * @validate-module-enabled default_content * @aliases dcdea,default-content-deploy-export-aliases */ - public function contentDeployExportAliases() { - $aliases = $this->exporter->exportUrlAliases(); + public function contentDeployExportAliases(array $options = ['folder' => self::OPT]) { + $folder = $options['folder']; + $aliases = $this->exporter->exportUrlAliases($folder); $this->logger->notice(dt('Exported @count aliases.', ['@count' => $aliases])); } @@ -240,6 +258,8 @@ class DefaultContentDeployCommands extends DrushCommands { * Import content. Existing older content with matching UUID will be * updated. Newer content and existing content with different UUID will be * ignored. + * @usage drush dcdi --folder='../content' + * Import content from the specified folder. * @usage drush dcdi --force-update * Existing content with different UUID will be deleted and created again * (recommended for better content synchronization). @@ -254,12 +274,14 @@ class DefaultContentDeployCommands extends DrushCommands { public function contentDeployImport(array $options = [ 'force-update' => NULL, 'force-override' => NULL, + 'folder' => self::OPT, ]) { $force_update = $options['force-update']; $force_override = $options['force-override']; + $folder = $options['folder']; // Perform read only update. - $result_info = $this->importer->deployContent($force_update, $force_override, FALSE); + $result_info = $this->importer->deployContent($folder, $force_update, $force_override, FALSE); $this->output() ->writeln(dt('@count entities will be processed.', ['@count' => $result_info['processed']])); $this->displayImportResult($result_info); @@ -270,7 +292,7 @@ class DefaultContentDeployCommands extends DrushCommands { } if ($this->io()->confirm(dt('Do you really want to continue?'))) { // Perform update. - $result_info = $this->importer->deployContent($force_update, $force_override, TRUE); + $result_info = $this->importer->deployContent($folder, $force_update, $force_override, TRUE); $import_status = $this->importer->importUrlAliases(); // Display results. diff --git a/src/Exporter.php b/src/Exporter.php index 8cf7dc4..af4772b 100644 --- a/src/Exporter.php +++ b/src/Exporter.php @@ -22,6 +22,8 @@ class Exporter extends DefaultContentDeployBase { * Entity Bundle. * @param string $skipEntities * Entities to skip. + * @param string $folder + * The content folder. * * @return int * Number of exported entities. @@ -31,7 +33,11 @@ class Exporter extends DefaultContentDeployBase { public function export($entityType, $entityBundle = '', $entityIds = '', - $skipEntities = '') { + $skipEntities = '', + $folder = NULL) { + if (!$folder) { + $folder = $this->getContentFolder(); + } // Switch to limitless admin account. // It solves limitations during export a user entities. $this->accountSwitcher->switchTo(new UserSession(['uid' => 1])); @@ -46,7 +52,7 @@ class Exporter extends DefaultContentDeployBase { $exportedEntities[$entityType][$uuid] = $exportedEntity; } // Export all entities to folder. - $this->exporter->writeDefaultContent($exportedEntities, $this->getContentFolder()); + $this->exporter->writeDefaultContent($exportedEntities, $folder); $this->accountSwitcher->switchBack(); return count($exportedEntityIds); @@ -63,6 +69,8 @@ class Exporter extends DefaultContentDeployBase { * Entity Bundle. * @param string $skipEntities * Entities to skip. + * @param string $folder + * The content folder. * * @return int * Number of exported entities. @@ -72,7 +80,11 @@ class Exporter extends DefaultContentDeployBase { public function exportWithReferences($entityType, $entityBundle = '', $entityIds = '', - $skipEntities = '') { + $skipEntities = '', + $folder = NULL) { + if (!$folder) { + $folder = $this->getContentFolder(); + } // Switch to limitless admin account. // It solves limitations during export a user entities. $this->accountSwitcher->switchTo(new UserSession(['uid' => 1])); @@ -80,7 +92,7 @@ class Exporter extends DefaultContentDeployBase { $exportedEntityIds = $this->getEntityIdsForExport($entityType, $entityBundle, $entityIds, $skipEntities); foreach ($exportedEntityIds as $entityId) { $exportedEntityByType = $this->exporter->exportContentWithReferences($entityType, $entityId); - $this->exporter->writeDefaultContent($exportedEntityByType, $this->getContentFolder()); + $this->exporter->writeDefaultContent($exportedEntityByType, $folder); } $this->accountSwitcher->switchBack(); return count($exportedEntityIds); @@ -91,13 +103,19 @@ class Exporter extends DefaultContentDeployBase { * * @param string $skipEntityType * Add entity types what are you want to skip. + * @param string $folder + * The content folder. * * @return array * Return number of exported entities grouped by entity type. * * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException */ - public function exportSite($skipEntityType = '') { + public function exportSite($skipEntityType = '', $folder = NULL) { + if (!$folder) { + $folder = $this->getContentFolder(); + } + $count = []; $skipEntityType = explode(parent::DELIMITER, $skipEntityType); @@ -105,7 +123,7 @@ class Exporter extends DefaultContentDeployBase { $contentEntityTypes = $this->getContentEntityTypes(); // Delete files in the content directory before export. - $this->deleteDirectoryContentRecursively($this->getContentFolder(), FALSE); + $this->deleteDirectoryContentRecursively($folder, FALSE); foreach ($contentEntityTypes as $entityType => $entityDefinition) { // Skip specified entities in --skip_entity_type option. @@ -120,8 +138,14 @@ class Exporter extends DefaultContentDeployBase { /** * Export url aliases in single json file under alias folder. + * + * @param string $folder + * The content folder. */ - public function exportUrlAliases() { + public function exportUrlAliases($folder = NULL) { + if (!$folder) { + $folder = $this->getContentFolder(); + } $query = $this->database->select('url_alias', 'aliases') ->fields('aliases', []); $data = $query->execute(); @@ -136,7 +160,7 @@ class Exporter extends DefaultContentDeployBase { } $serializedAliases = JSON::encode($aliases); - $this->exporter->writeDefaultContent([parent::ALIAS_NAME => [parent::ALIAS_NAME => $serializedAliases]], $this->getContentFolder()); + $this->exporter->writeDefaultContent([parent::ALIAS_NAME => [parent::ALIAS_NAME => $serializedAliases]], $folder); return count($aliases); } diff --git a/src/Importer.php b/src/Importer.php index 71e2613..a3a61c8 100644 --- a/src/Importer.php +++ b/src/Importer.php @@ -123,6 +123,8 @@ class Importer extends DCImporter { * Injected code is marked in comment. Look for text: * "Here is start of injected code." * + * @param string $folder + * The content folder. * @param bool $force_update * TRUE for overwrite entities with matching ID but different UUID. * @param bool $force_override @@ -138,7 +140,7 @@ class Importer extends DCImporter { * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException * @throws \Drupal\Core\Entity\EntityStorageException */ - public function deployContent($force_update = FALSE, $force_override = FALSE, $writeEnable = FALSE) { + public function deployContent($folder = NULL, $force_update = FALSE, $force_override = FALSE, $writeEnable = FALSE) { $this->writeEnable = $writeEnable; $result_info = [ 'processed' => 0, @@ -147,7 +149,9 @@ class Importer extends DCImporter { 'skipped' => 0, 'file_created' => 0, ]; - $folder = $this->dcdBase->getContentFolder(); + if (!$folder) { + $folder = $this->dcdBase->getContentFolder(); + } if (file_exists($folder)) { /** @var \Drupal\user\Entity\User $root_user */