View source
<?php
namespace Drupal\commerce_demo;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Serialization\Yaml;
use Drupal\taxonomy\TermInterface;
use Drupal\Core\Entity\EntityInterface;
class ContentImporter {
protected $entityTypeManager;
protected $fileSystem;
protected $contentPath;
protected $store;
public function __construct(EntityTypeManagerInterface $entityTypeManager, FileSystemInterface $file_system) {
$this->entityTypeManager = $entityTypeManager;
$this->fileSystem = $file_system;
$this->contentPath = realpath(__DIR__ . '/../content');
}
public function onInstall() {
$available_content = [
[
'taxonomy_term',
'brands',
],
[
'taxonomy_term',
'product_categories',
],
[
'taxonomy_term',
'special_categories',
],
[
'commerce_product_attribute_value',
'color',
],
[
'commerce_product_attribute_value',
'size',
],
[
'commerce_product',
'clothing',
],
[
'commerce_product',
'simple',
],
[
'commerce_shipping_method',
'',
],
[
'commerce_promotion',
'',
],
];
foreach ($available_content as $keys) {
$this
->importAll($keys[0], $keys[1]);
}
}
public function importAll($entity_type_id, $bundle = '') {
$filepath = $this
->buildFilepath($entity_type_id, $bundle);
if (!is_readable($filepath)) {
throw new \InvalidArgumentException(sprintf('The %s file could not be found/read.', $filepath));
}
$data = Yaml::decode(file_get_contents($filepath));
foreach ($data as $uuid => $values) {
$values['uuid'] = $uuid;
$this
->importEntity($entity_type_id, $values);
}
}
public function importEntity($entity_type_id, array $values) {
$entity_type = $this->entityTypeManager
->getDefinition($entity_type_id);
$wanted_keys = [
'bundle',
'langcode',
'uuid',
];
$wanted_keys = array_combine($wanted_keys, $wanted_keys);
$entity_keys = array_intersect_key($entity_type
->getKeys(), $wanted_keys);
$storage = $this->entityTypeManager
->getStorage($entity_type_id);
$entity = $this
->loadEntityByUuid($entity_type_id, $values['uuid']);
if (!$entity) {
$initial_values = array_intersect_key($values, array_flip($entity_keys));
$entity = $storage
->create($initial_values);
}
$values = array_diff_key($values, array_flip($entity_keys));
foreach ($entity
->getFieldDefinitions() as $field_name => $definition) {
if (!isset($values[$field_name])) {
continue;
}
$storage_definition = $definition
->getFieldStorageDefinition();
$items = $values[$field_name];
if ($storage_definition
->getCardinality() === 1) {
$items = [
$items,
];
}
foreach ($items as $delta => $item) {
if ($definition
->getType() == 'entity_reference' && is_string($item)) {
$target_entity_type_id = $storage_definition
->getSetting('target_type');
$target_entity_type = $this->entityTypeManager
->getDefinition($target_entity_type_id);
if ($target_entity_type
->entityClassImplements(ContentEntityInterface::class)) {
$target_entity = $this
->loadEntityByUuid($target_entity_type_id, $item);
if ($target_entity) {
$items[$delta] = $target_entity
->id();
}
else {
unset($items[$delta]);
}
}
}
elseif ($definition
->getType() == 'image') {
$file = $this
->ensureFile($item['filename']);
$items[$delta] = [
'target_id' => $file
->id(),
] + $item;
}
$values[$field_name] = $items;
}
}
if (substr($entity_type_id, 0, 9) == 'commerce_') {
$values = $this
->processCommerce($values, $entity);
}
if ($entity_type_id == 'commerce_product') {
$values = $this
->processReferences($values, $entity, 'variations');
}
elseif ($entity_type_id == 'commerce_promotion') {
$values = $this
->processReferences($values, $entity, 'coupons');
}
elseif ($entity_type_id == 'taxonomy_term') {
$values = $this
->processTerm($values, $entity);
}
foreach ($values as $field_name => $items) {
$entity
->set($field_name, $items);
}
$entity
->save();
return $entity;
}
protected function processCommerce(array $values, ContentEntityInterface $entity) {
$store = $this
->ensureStore();
if ($entity
->hasField('stores')) {
$values['stores'] = [
$store,
];
}
elseif ($entity
->hasField('store')) {
$values['store'] = $store;
}
return $values;
}
protected function processReferences(array $values, EntityInterface $entity, $field_name) {
$ids = [];
foreach ($values[$field_name] as $uuid => $entity_values) {
$entity_values['uuid'] = $uuid;
if ($field_name == 'variations') {
$entity_type_id = 'commerce_product_variation';
}
elseif ($field_name == 'coupons') {
$entity_type_id = 'commerce_promotion_coupon';
}
else {
return $values;
}
$imported_entity = $this
->importEntity($entity_type_id, $entity_values);
$ids[] = $imported_entity
->id();
}
$values[$field_name] = $ids;
return $values;
}
protected function processTerm(array $values, TermInterface $term) {
if (!isset($values['parent'])) {
$values['parent'] = [
0,
];
}
return $values;
}
protected function loadEntityByUuid($entity_type_id, $entity_uuid) {
$storage = $this->entityTypeManager
->getStorage($entity_type_id);
$entities = $storage
->loadByProperties([
'uuid' => $entity_uuid,
]);
return $entities ? reset($entities) : NULL;
}
protected function buildFilepath($entity_type_id, $bundle = '') {
$filepath = $this->contentPath . '/' . $entity_type_id;
if ($bundle) {
$filepath .= '.' . $bundle;
}
$filepath .= '.yml';
return $filepath;
}
protected function ensureStore() {
if (!$this->store) {
$store_storage = $this->entityTypeManager
->getStorage('commerce_store');
$store = $store_storage
->loadDefault();
if (!$store) {
$store = $store_storage
->create([
'type' => 'online',
'name' => 'US Store',
'mail' => 'admin@example.com',
'default_currency' => 'USD',
'address' => [
'country_code' => 'US',
'administrative_area' => 'SC',
'locality' => 'Greenville',
'postal_code' => '29616',
'address_line1' => '12344 24th St',
],
'prices_include_tax' => FALSE,
]);
$store
->save();
$store_storage
->markAsDefault($store);
}
$this->store = $store;
}
return $this->store;
}
protected function ensureFile($filename) {
$file_storage = $this->entityTypeManager
->getStorage('file');
$files = $file_storage
->loadByProperties([
'filename' => $filename,
]);
$file = reset($files);
if (!$file) {
$path = $this->contentPath . '/files/' . $filename;
$uri = $this->fileSystem
->copy($path, 'public://' . $filename, FileSystemInterface::EXISTS_REPLACE);
$file = $file_storage
->create([
'filename' => $filename,
'uri' => $uri,
'status' => 1,
]);
$file
->save();
}
return $file;
}
}