View source
<?php
namespace Drupal\demo_umami_content;
use Drupal\Component\Utility\Html;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\File\Exception\FileException;
use Drupal\Core\File\FileSystemInterface;
use Drupal\path_alias\AliasManagerInterface;
use Drupal\Core\State\StateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
class InstallHelper implements ContainerInjectionInterface {
protected $aliasManager;
protected $entityTypeManager;
protected $moduleHandler;
protected $state;
protected $fileSystem;
protected $enabledLanguages;
protected $termIdMap;
protected $mediaImageIdMap;
protected $nodeIdMap;
public function __construct(AliasManagerInterface $aliasManager, EntityTypeManagerInterface $entityTypeManager, ModuleHandlerInterface $moduleHandler, StateInterface $state, FileSystemInterface $fileSystem) {
$this->aliasManager = $aliasManager;
$this->entityTypeManager = $entityTypeManager;
$this->moduleHandler = $moduleHandler;
$this->state = $state;
$this->fileSystem = $fileSystem;
$this->termIdMap = [];
$this->mediaImageIdMap = [];
$this->nodeIdMap = [];
$this->enabledLanguages = array_keys(\Drupal::languageManager()
->getLanguages());
}
public static function create(ContainerInterface $container) {
return new static($container
->get('path_alias.manager'), $container
->get('entity_type.manager'), $container
->get('module_handler'), $container
->get('state'), $container
->get('file_system'));
}
public function importContent() {
$this
->getModulePath()
->importEditors()
->importContentFromFile('taxonomy_term', 'tags')
->importContentFromFile('taxonomy_term', 'recipe_category')
->importContentFromFile('media', 'image')
->importContentFromFile('node', 'recipe')
->importContentFromFile('node', 'article')
->importContentFromFile('node', 'page')
->importContentFromFile('block_content', 'disclaimer_block')
->importContentFromFile('block_content', 'footer_promo_block')
->importContentFromFile('block_content', 'banner_block');
}
protected function getModulePath() {
$this->module_path = $this->moduleHandler
->getModule('demo_umami_content')
->getPath();
return $this;
}
protected function readMultilingualContent($filename) {
$default_content_path = $this->module_path . "/default_content/languages/";
$translated_languages = $this->enabledLanguages;
foreach ($translated_languages as $language) {
if (file_exists($default_content_path . "{$language}/{$filename}") && ($handle = fopen($default_content_path . "{$language}/{$filename}", 'r')) !== FALSE) {
$header = fgetcsv($handle);
$line_counter = 0;
while (($content = fgetcsv($handle)) !== FALSE) {
$keyed_content[$language][$line_counter] = array_combine($header, $content);
$line_counter++;
}
fclose($handle);
}
else {
$key = array_search($language, $translated_languages);
unset($translated_languages[$key]);
}
}
return [
$keyed_content,
$translated_languages,
];
}
protected function getTermId($vocabulary, $term_csv_id) {
if (array_key_exists($vocabulary, $this->termIdMap) && array_key_exists($term_csv_id, $this->termIdMap[$vocabulary])) {
return $this->termIdMap[$vocabulary][$term_csv_id];
}
return 0;
}
protected function saveTermId($vocabulary, $term_csv_id, $tid) {
$this->termIdMap[$vocabulary][$term_csv_id] = $tid;
}
protected function getMediaImageId($media_image_csv_id) {
if (array_key_exists($media_image_csv_id, $this->mediaImageIdMap)) {
return $this->mediaImageIdMap[$media_image_csv_id];
}
return 0;
}
protected function saveMediaImageId($media_image_csv_id, $media_image_id) {
$this->mediaImageIdMap[$media_image_csv_id] = $media_image_id;
}
protected function getNodePath($langcode, $content_type, $node_csv_id) {
if (array_key_exists($langcode, $this->nodeIdMap) && array_key_exists($content_type, $this->nodeIdMap[$langcode]) && array_key_exists($node_csv_id, $this->nodeIdMap[$langcode][$content_type])) {
return $this->nodeIdMap[$langcode][$content_type][$node_csv_id];
}
return 0;
}
protected function saveNodePath($langcode, $content_type, $node_csv_id, $node_url) {
$this->nodeIdMap[$langcode][$content_type][$node_csv_id] = $node_url;
}
protected function importEditors() {
$user_storage = $this->entityTypeManager
->getStorage('user');
$editors = [
'Margaret Hopper',
'Grace Hamilton',
];
foreach ($editors as $name) {
$user = $user_storage
->create([
'name' => $name,
'status' => 1,
'roles' => [
'editor',
],
'mail' => mb_strtolower(str_replace(' ', '.', $name)) . '@example.com',
]);
$user
->enforceIsNew();
$user
->save();
$this
->storeCreatedContentUuids([
$user
->uuid() => 'user',
]);
}
return $this;
}
protected function processTerm(array $data, $vocabulary) {
$term_name = trim($data['term']);
$values = [
'name' => $term_name,
'vid' => $vocabulary,
'path' => [
'alias' => '/' . Html::getClass($vocabulary) . '/' . Html::getClass($term_name),
],
'langcode' => 'en',
];
return $values;
}
protected function processImage(array $data) {
if (!empty($data['author'])) {
$values['uid'] = $this
->getUser($data['author']);
}
$image_path = $this->module_path . '/default_content/images/' . $data['image'];
$values = [
'name' => $data['title'],
'bundle' => 'image',
'langcode' => 'en',
'field_media_image' => [
'target_id' => $this
->createFileEntity($image_path),
'alt' => $data['alt'],
],
];
return $values;
}
protected function processPage(array $data, $langcode) {
$values = [
'type' => 'page',
'title' => $data['title'],
'moderation_state' => 'published',
'langcode' => 'en',
];
if (!empty($data['body'])) {
$values['body'] = [
[
'value' => $data['body'],
'format' => 'basic_html',
],
];
}
if (!empty($data['slug'])) {
$values['path'] = [
[
'alias' => '/' . $data['slug'],
],
];
}
$this
->saveNodePath($langcode, 'page', $data['id'], $data['slug']);
if (!empty($data['author'])) {
$values['uid'] = $this
->getUser($data['author']);
}
return $values;
}
protected function processRecipe(array $data, $langcode) {
$values = [
'type' => 'recipe',
'title' => $data['title'],
'moderation_state' => 'published',
'langcode' => 'en',
];
if (!empty($data['author'])) {
$values['uid'] = $this
->getUser($data['author']);
}
if (!empty($data['slug'])) {
$values['path'] = [
[
'alias' => '/' . $data['slug'],
],
];
}
$this
->saveNodePath($langcode, 'recipe', $data['id'], $data['slug']);
if (!empty($data['image_reference'])) {
$values['field_media_image'] = [
'target_id' => $this
->getMediaImageId($data['image_reference']),
];
}
if (!empty($data['summary'])) {
$values['field_summary'] = [
[
'value' => $data['summary'],
'format' => 'basic_html',
],
];
}
if (!empty($data['recipe_category'])) {
$values['field_recipe_category'] = [];
$tags = array_filter(explode(',', $data['recipe_category']));
foreach ($tags as $tag_id) {
if ($tid = $this
->getTermId('recipe_category', $tag_id)) {
$values['field_recipe_category'][] = [
'target_id' => $tid,
];
}
}
}
if (!empty($data['preparation_time'])) {
$values['field_preparation_time'] = [
[
'value' => $data['preparation_time'],
],
];
}
if (!empty($data['cooking_time'])) {
$values['field_cooking_time'] = [
[
'value' => $data['cooking_time'],
],
];
}
if (!empty($data['difficulty'])) {
$values['field_difficulty'] = $data['difficulty'];
}
if (!empty($data['number_of_servings'])) {
$values['field_number_of_servings'] = [
[
'value' => $data['number_of_servings'],
],
];
}
if (!empty($data['ingredients'])) {
$ingredients = explode(',', $data['ingredients']);
$values['field_ingredients'] = [];
foreach ($ingredients as $ingredient) {
$values['field_ingredients'][] = [
'value' => $ingredient,
];
}
}
if (!empty($data['recipe_instruction'])) {
$recipe_instruction_path = $this->module_path . '/default_content/languages/' . $langcode . '/recipe_instructions/' . $data['recipe_instruction'];
$recipe_instructions = file_get_contents($recipe_instruction_path);
if ($recipe_instructions !== FALSE) {
$values['field_recipe_instruction'] = [
[
'value' => $recipe_instructions,
'format' => 'basic_html',
],
];
}
}
if (!empty($data['tags'])) {
$values['field_tags'] = [];
$tags = array_filter(explode(',', $data['tags']));
foreach ($tags as $tag_id) {
if ($tid = $this
->getTermId('tags', $tag_id)) {
$values['field_tags'][] = [
'target_id' => $tid,
];
}
}
}
return $values;
}
protected function processArticle(array $data, $langcode) {
$values = [
'type' => 'article',
'title' => $data['title'],
'moderation_state' => 'published',
'langcode' => 'en',
];
if (!empty($data['body'])) {
$body_path = $this->module_path . '/default_content/languages/' . $langcode . '/article_body/' . $data['body'];
$body = file_get_contents($body_path);
if ($body !== FALSE) {
$values['body'] = [
[
'value' => $body,
'format' => 'basic_html',
],
];
}
}
if (!empty($data['slug'])) {
$values['path'] = [
[
'alias' => '/' . $data['slug'],
],
];
}
$this
->saveNodePath($langcode, 'article', $data['id'], $data['slug']);
if (!empty($data['author'])) {
$values['uid'] = $this
->getUser($data['author']);
}
if (!empty($data['image_reference'])) {
$values['field_media_image'] = [
'target_id' => $this
->getMediaImageId($data['image_reference']),
];
}
if (!empty($data['tags'])) {
$values['field_tags'] = [];
$tags = explode(',', $data['tags']);
foreach ($tags as $tag_id) {
if ($tid = $this
->getTermId('tags', $tag_id)) {
$values['field_tags'][] = [
'target_id' => $tid,
];
}
}
}
return $values;
}
protected function processBannerBlock(array $data, $langcode) {
$node_url = $this
->getNodePath($langcode, $data['content_type'], $data['node_id']);
$values = [
'uuid' => $data['uuid'],
'info' => $data['info'],
'type' => $data['type'],
'langcode' => 'en',
'field_title' => [
'value' => $data['field_title'],
],
'field_content_link' => [
'uri' => 'internal:/' . $langcode . '/' . $node_url,
'title' => $data['field_content_link_title'],
],
'field_summary' => [
'value' => $data['field_summary'],
],
'field_media_image' => [
'target_id' => $this
->getMediaImageId($data['image_reference']),
],
];
return $values;
}
protected function processDisclaimerBlock(array $data) {
$values = [
'uuid' => $data['uuid'],
'info' => $data['info'],
'type' => $data['type'],
'langcode' => 'en',
'field_disclaimer' => [
'value' => $data['field_disclaimer'],
'format' => 'basic_html',
],
'field_copyright' => [
'value' => '© ' . date("Y") . ' ' . $data['field_copyright'],
'format' => 'basic_html',
],
];
return $values;
}
protected function processFooterPromoBlock(array $data, $langcode) {
$node_url = $this
->getNodePath($langcode, $data['content_type'], $data['node_id']);
$values = [
'uuid' => $data['uuid'],
'info' => $data['info'],
'type' => $data['type'],
'langcode' => 'en',
'field_title' => [
'value' => $data['field_title'],
],
'field_content_link' => [
'uri' => 'internal:/' . $node_url,
'title' => $data['field_content_link_title'],
],
'field_summary' => [
'value' => $data['field_summary'],
],
'field_media_image' => [
'target_id' => $this
->getMediaImageId($data['image_reference']),
],
];
return $values;
}
protected function processContent($bundle_machine_name, array $content, $langcode) {
switch ($bundle_machine_name) {
case 'recipe':
$structured_content = $this
->processRecipe($content, $langcode);
break;
case 'article':
$structured_content = $this
->processArticle($content, $langcode);
break;
case 'page':
$structured_content = $this
->processPage($content, $langcode);
break;
case 'banner_block':
$structured_content = $this
->processBannerBlock($content, $langcode);
break;
case 'disclaimer_block':
$structured_content = $this
->processDisclaimerBlock($content);
break;
case 'footer_promo_block':
$structured_content = $this
->processFooterPromoBlock($content, $langcode);
break;
case 'image':
$structured_content = $this
->processImage($content);
break;
case 'recipe_category':
case 'tags':
$structured_content = $this
->processTerm($content, $bundle_machine_name);
break;
default:
break;
}
return $structured_content;
}
protected function importContentFromFile($entity_type, $bundle_machine_name) {
$filename = $entity_type . '/' . $bundle_machine_name . '.csv';
list($all_content, $translated_languages) = $this
->readMultilingualContent($filename);
$key = array_search('en', $translated_languages);
unset($translated_languages[$key]);
foreach ($all_content['en'] as $current_content) {
$structured_content = $this
->processContent($bundle_machine_name, $current_content, 'en');
$entity = $this->entityTypeManager
->getStorage($entity_type)
->create($structured_content);
$entity
->save();
$this
->storeCreatedContentUuids([
$entity
->uuid() => $entity_type,
]);
if ($entity_type == 'taxonomy_term') {
$this
->saveTermId($bundle_machine_name, $current_content['id'], $entity
->id());
}
if ($entity_type == 'media') {
$this
->saveMediaImageId($current_content['id'], $entity
->id());
}
foreach ($translated_languages as $translated_language) {
$translation_id = array_search($current_content['id'], array_column($all_content[$translated_language], 'id'));
if ($translation_id !== FALSE) {
$translated_entity = $all_content[$translated_language][$translation_id];
$structured_content = $this
->processContent($bundle_machine_name, $translated_entity, $translated_language);
$entity
->addTranslation($translated_language, $structured_content);
$entity
->save();
}
}
}
return $this;
}
public function deleteImportedContent() {
$uuids = $this->state
->get('demo_umami_content_uuids', []);
$by_entity_type = array_reduce(array_keys($uuids), function ($carry, $uuid) use ($uuids) {
$entity_type_id = $uuids[$uuid];
$carry[$entity_type_id][] = $uuid;
return $carry;
}, []);
foreach ($by_entity_type as $entity_type_id => $entity_uuids) {
$storage = $this->entityTypeManager
->getStorage($entity_type_id);
$entities = $storage
->loadByProperties([
'uuid' => $entity_uuids,
]);
$storage
->delete($entities);
}
return $this;
}
protected function getUser($name) {
$user_storage = $this->entityTypeManager
->getStorage('user');
$users = $user_storage
->loadByProperties([
'name' => $name,
]);
if (empty($users)) {
$user = $user_storage
->create([
'name' => $name,
'status' => 1,
'roles' => [
'author',
],
'mail' => mb_strtolower(str_replace(' ', '.', $name)) . '@example.com',
]);
$user
->enforceIsNew();
$user
->save();
$this
->storeCreatedContentUuids([
$user
->uuid() => 'user',
]);
return $user
->id();
}
$user = reset($users);
return $user
->id();
}
protected function createFileEntity($path) {
$filename = basename($path);
try {
$uri = $this->fileSystem
->copy($path, 'public://' . $filename, FileSystemInterface::EXISTS_REPLACE);
} catch (FileException $e) {
$uri = FALSE;
}
$file = $this->entityTypeManager
->getStorage('file')
->create([
'uri' => $uri,
'status' => 1,
]);
$file
->save();
$this
->storeCreatedContentUuids([
$file
->uuid() => 'file',
]);
return $file
->id();
}
protected function storeCreatedContentUuids(array $uuids) {
$uuids = $this->state
->get('demo_umami_content_uuids', []) + $uuids;
$this->state
->set('demo_umami_content_uuids', $uuids);
}
}