View source
<?php
namespace Drupal\metatag_import_export_csv;
use Drupal\file\FileInterface;
use Drupal\Core\Url;
class MetatagImport {
public static function validateCsvHeader(FileInterface $file) {
$url = $file
->getFileUri();
$filepath = file_create_url($url);
$handle = fopen($filepath, 'r');
$headers = fgetcsv($handle);
fclose($handle);
$errors = [];
if (!in_array('path_alias', $headers)) {
if (!in_array('entity_type', $headers)) {
$errors[] = t("The CSV must have an 'entity_type' column if it does not have a 'path_alias' column.");
}
if (!in_array('entity_id', $headers)) {
$errors[] = t("The CSV must have an 'entity_id' column if it does not have a 'path_alias' column.");
}
}
return $errors;
}
public static function importCsvBatchOperation($headers, $filepath, &$context = []) {
if (empty($context['sandbox'])) {
$context['sandbox']['handle'] = NULL;
$context['sandbox']['pointer_position'] = 0;
$context['sandbox']['csv_line'] = 0;
$context['results']['success'] = [];
$context['results']['error'] = [];
}
if (!is_resource($context['sandbox']['handle'])) {
$context['sandbox']['handle'] = fopen($filepath, 'r');
}
if (feof($context['sandbox']['handle'])) {
$context['finished'] = 1;
return;
}
if ($context['sandbox']['pointer_position'] == 0) {
fgetcsv($context['sandbox']['handle']);
$context['sandbox']['csv_line']++;
}
else {
fseek($context['sandbox']['handle'], $context['sandbox']['pointer_position']);
}
$data = fgetcsv($context['sandbox']['handle']);
$context['sandbox']['csv_line']++;
$context['sandbox']['pointer_position'] = ftell($context['sandbox']['handle']);
try {
$entity = static::importCsvRow($headers, $data);
$context['results']['success'][$entity
->getEntityTypeId()][] = $entity
->id();
} catch (\Exception $e) {
$context['results']['error'][] = t("Unable to import line @line of the CSV. Error was: '@message'.", [
'@line' => $context['sandbox']['csv_line'],
'@message' => $e
->getMessage(),
]);
}
$context['finished'] = 0;
}
public static function importCsvRow($headers, $data) {
$entity_type_index = array_search('entity_type', $headers);
$entity_id_index = array_search('entity_id', $headers);
$language_index = array_search('language', $headers);
$path_alias_index = array_search('path_alias', $headers);
$entity = [];
if ($entity_type_index !== FALSE && $entity_id_index !== FALSE) {
$entity_type = trim($data[$entity_type_index]);
$entity_id = trim($data[$entity_id_index]);
}
if ($path_alias_index !== FALSE) {
$path_alias = trim($data[$path_alias_index]);
}
if (!(!empty($entity_type) && !empty($entity_id) || !empty($path_alias))) {
throw new \Exception(t("Either both of entity_id and entity_type or path_alias must be specified."));
}
if ($language_index !== FALSE) {
$langcode = trim($data[$language_index]);
}
if (!empty($path_alias)) {
$path = \Drupal::service('path_alias.manager')
->getPathByAlias($path_alias, $langcode ?? NULL);
$route_parameters = Url::fromUri("internal:" . $path)
->getRouteParameters();
$entity_type = key($route_parameters);
if (!\Drupal::service('entity_type.manager')
->hasDefinition($entity_type)) {
throw new \Exception(t("The path alias '@alias' does not correspond to an entity route.", [
'@alias' => $path_alias,
]));
}
$entity_id = $route_parameters[$entity_type];
}
if (!\Drupal::service('entity_type.manager')
->hasDefinition($entity_type)) {
throw new \Exception(t("The '@entity-type' entity type does not exist.", [
'@entity-type' => $entity_type,
]));
}
$entity = \Drupal::service('entity_type.manager')
->getStorage($entity_type)
->load($entity_id);
if (!$entity) {
throw new \Exception(t("No @entity-type with ID @entity-id was found.", [
'@entity-type' => $entity_type,
'@entity-id' => $entity_id,
]));
}
if (!empty($langcode)) {
if (!$entity
->hasTranslation($langcode)) {
throw new \Exception(t("The @entity-type with ID @entity-id has no @language translation.", [
'@entity-type' => $entity_type,
'@entity-id' => $entity_id,
'@language' => $langcode,
]));
}
$entity = $entity
->getTranslation($langcode);
}
$tags = [];
foreach ($headers as $keys => $values) {
if (trim($data[$keys]) == '_blank') {
$tags[$values] = "";
}
else {
$tags[$values] = $data[$keys];
}
}
$metatag_machine_name = $tags['field_machine_name'];
unset($tags['entity_id'], $tags['entity_title'], $tags['entity_type'], $tags['alias'], $tags['field_machine_name']);
try {
$entity
->set($metatag_machine_name, serialize($tags));
$entity
->save();
} catch (\Exception $e) {
throw new \Exception(t("Error saving entity @entity-type @entity-id: '@message'.", [
'@entity-type' => $entity_type,
'@entity-id' => $entity_id,
'@message' => $e
->getMessage(),
]));
}
return $entity;
}
public static function importFinish($success, $results, $operations) {
$messenger = \Drupal::messenger();
if ($success) {
$message_entity_summary = [];
foreach ($results['success'] as $entity_type => $entity_ids) {
$entity_type_definition = \Drupal::service('entity_type.manager')
->getDefinition($entity_type);
$message_entity_summary[] = \Drupal::service('string_translation')
->formatPlural(count($entity_ids), '1 ' . $entity_type_definition
->getSingularLabel(), '@count ' . $entity_type_definition
->getPluralLabel());
}
if ($message_entity_summary) {
$messenger
->addMessage(t('Successfully updated entities: @summary.', [
'@summary' => implode(', ', $message_entity_summary),
]));
}
foreach ($results['error'] as $error_message) {
$messenger
->addError($error_message);
}
}
else {
$error_operation = reset($operations);
$messenger
->addMessage(t('An error occurred while processing @operation with arguments : @args', [
'@operation' => $error_operation[0],
'@args' => print_r($error_operation[0], TRUE),
]), 'error');
}
}
}