Commit 471bf110 authored by Sam152's avatar Sam152 Committed by benjy

Issue #2614650 by Sam152: Allow modules to declare content they are responsible for

parent d65db120
services:
default_content.manager:
class: Drupal\default_content\DefaultContentManager
arguments: ['@serializer', '@plugin.manager.rest', '@current_user', '@entity.manager', '@rest.link_manager', '@event_dispatcher']
arguments: ['@serializer', '@plugin.manager.rest', '@current_user', '@entity.manager', '@rest.link_manager', '@event_dispatcher', '@module_handler', '@info_parser']
......@@ -33,6 +33,14 @@ function default_content_drush_command() {
'aliases' => ['dcer'],
'required-arguments' => 2,
];
$items['default-content-export-module'] = [
'description' => dt('Exports all the content defined in a module info file.'),
'arguments' => [
'module' => dt('The name of the module.'),
],
'aliases' => ['dcem'],
'required-arguments' => 1,
];
return $items;
}
......@@ -73,12 +81,19 @@ function drush_default_content_export_references($entity_type_id, $entity_id) {
$folder = drush_get_option('folder', '.');
$serialized_by_type = $manager->exportContentWithReferences($entity_type_id, $entity_id);
foreach ($serialized_by_type as $entity_type => $serialized_entities) {
// Ensure that the folder per entity type exists.
$entity_type_folder = "$folder/$entity_type";
file_prepare_directory($entity_type_folder, FILE_CREATE_DIRECTORY);
foreach ($serialized_entities as $entity_id => $serialized_entity) {
file_put_contents($entity_type_folder . '/' . $entity_id . '.json', $serialized_entity);
}
}
$manager->writeDefaultContent($serialized_by_type, $folder);
}
/**
* Exports all of the content for a given module.
*
* @param string $module_name
* The module name to export.
*/
function drush_default_content_export_module($module_name) {
/** @var \Drupal\default_content\DefaultContentManagerInterface $manager */
$manager = \Drupal::service('default_content.manager');
$serialized_by_type = $manager->exportModuleContent($module_name);
$module_folder = \Drupal::moduleHandler()->getModule($module_name)->getPath() . '/content';
$manager->writeDefaultContent($serialized_by_type, $module_folder);
}
......@@ -12,13 +12,14 @@ use Drupal\Component\Utility\SafeMarkup;
use Drupal\Core\Config\Entity\ConfigEntityInterface;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityManager;
use Drupal\Core\Extension\InfoParserInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\default_content\Event\DefaultContentEvents;
use Drupal\default_content\Event\ExportEvent;
use Drupal\default_content\Event\ImportEvent;
use Drupal\rest\LinkManager\LinkManagerInterface;
use Drupal\rest\Plugin\Type\ResourcePluginManager;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Serializer\Serializer;
......@@ -58,6 +59,20 @@ class DefaultContentManager implements DefaultContentManagerInterface {
*/
protected $entityManager;
/**
* The module handler.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* The info file parser.
*
* @var \Drupal\Core\Extension\InfoParserInterface
*/
protected $infoParser;
/**
* The file system scanner.
*
......@@ -106,13 +121,21 @@ class DefaultContentManager implements DefaultContentManagerInterface {
* The entity manager service.
* @param \Drupal\rest\LinkManager\LinkManagerInterface $link_manager
* The link manager service.
* @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
* The event dispatcher.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler.
* @param \Drupal\Core\Extension\InfoParserInterface $info_parser
* The info file parser.
*/
public function __construct(Serializer $serializer, ResourcePluginManager $resource_plugin_manager, AccountInterface $current_user, EntityManager $entity_manager, LinkManagerInterface $link_manager, EventDispatcherInterface $event_dispatcher) {
public function __construct(Serializer $serializer, ResourcePluginManager $resource_plugin_manager, AccountInterface $current_user, EntityManager $entity_manager, LinkManagerInterface $link_manager, EventDispatcherInterface $event_dispatcher, ModuleHandlerInterface $module_handler, InfoParserInterface $info_parser) {
$this->serializer = $serializer;
$this->resourcePluginManager = $resource_plugin_manager;
$this->entityManager = $entity_manager;
$this->linkManager = $link_manager;
$this->eventDispatcher = $event_dispatcher;
$this->moduleHandler = $module_handler;
$this->infoParser = $info_parser;
}
/**
......@@ -246,6 +269,39 @@ class DefaultContentManager implements DefaultContentManagerInterface {
return $serialized_entities_per_type;
}
/**
* {@inheritdoc}
*/
public function exportModuleContent($module_name) {
$info_file = $this->moduleHandler->getModule($module_name)->getPathname();
$info = $this->infoParser->parse($info_file);
$exported_content = [];
if (empty($info['default_content'])) {
return $exported_content;
}
foreach ($info['default_content'] as $entity_type => $uuids) {
foreach ($uuids as $uuid) {
$entity = $this->entityManager->loadEntityByUuid($entity_type, $uuid);
$exported_content[$entity_type][$uuid] = $this->exportContent($entity_type, $entity->id());
}
}
return $exported_content;
}
/**
* {@inheritdoc{
*/
public function writeDefaultContent($serialized_by_type, $folder) {
foreach ($serialized_by_type as $entity_type => $serialized_entities) {
// Ensure that the folder per entity type exists.
$entity_type_folder = "$folder/$entity_type";
file_prepare_directory($entity_type_folder, FILE_CREATE_DIRECTORY);
foreach ($serialized_entities as $uuid => $serialized_entity) {
file_put_contents($entity_type_folder . '/' . $uuid . '.json', $serialized_entity);
}
}
}
/**
* Returns all referenced entities of an entity.
*
......
......@@ -57,4 +57,25 @@ interface DefaultContentManagerInterface {
*/
public function exportContentWithReferences($entity_type_id, $entity_id);
/**
* Exports all of the content defined in a module's info file.
*
* @param string $module_name
* The name of the module.
*
* @return string[][]
* The serialized entities keyed by entity type and UUID.
*/
public function exportModuleContent($module_name);
/**
* Writes an array of serialized entities to a given folder.
*
* @param string[][] $serialized_by_type
* An array of serialized entities keyed by entity type and UUID
* @param $folder
* The folder to write files into.
*/
public function writeDefaultContent($serialized_by_type, $folder);
}
......@@ -109,4 +109,27 @@ class DefaultContentManagerIntegrationTest extends KernelTestBase {
$this->assertEqual(reset($exported_by_entity_type['user']), $expected_user);
}
/**
* Tests exportModuleContent().
*/
public function testModuleExport() {
\Drupal::service('module_installer')->install(['node', 'default_content', 'default_content_export_test']);
\Drupal::service('router.builder')->rebuild();
$this->defaultContentManager = \Drupal::service('default_content.manager');
$test_uuid = '0e45d92f-1919-47cd-8b60-964a8a761292';
$node_type = NodeType::create(['type' => 'test']);
$node_type->save();
$node = Node::create(['type' => $node_type->id(), 'title' => 'test node']);
$node->uuid = $test_uuid;
$node->save();
$node = Node::load($node->id());
$serializer = \Drupal::service('serializer');
\Drupal::service('rest.link_manager')->setLinkDomain(DefaultContentManager::LINK_DOMAIN);
$expected_node = $serializer->serialize($node, 'hal_json', ['json_encode_options' => JSON_PRETTY_PRINT]);
$content = $this->defaultContentManager->exportModuleContent('default_content_export_test');
$this->assertEqual($content['node'][$test_uuid], $expected_node);
}
}
name: 'Default content export test'
type: module
hidden: TRUE
description: 'Used in testing to ensure modules can declare content.'
package: Web services
core: 8.x
default_content:
node:
- 0e45d92f-1919-47cd-8b60-964a8a761292
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment