diff --git a/ami.services.yml b/ami.services.yml
index 1dd7925..1b55397 100644
--- a/ami.services.yml
+++ b/ami.services.yml
@@ -13,3 +13,7 @@ services:
arguments: [ '@file_system', '@file.usage', '@entity_type.manager', '@stream_wrapper_manager', '@plugin.manager.archiver', '@config.factory', '@current_user', '@language_manager', '@transliteration', '@module_handler', '@logger.factory', '@strawberryfield.utility', '@http_client', '@keyvalue']
tags:
- { name: backend_overridable }
+ ami.twig.TwigExtension:
+ class: Drupal\ami\TwigExtension
+ tags:
+ - { name: twig.extension }
\ No newline at end of file
diff --git a/src/AmiUtilityService.php b/src/AmiUtilityService.php
index ba39f42..867b780 100644
--- a/src/AmiUtilityService.php
+++ b/src/AmiUtilityService.php
@@ -1011,7 +1011,7 @@ public function csv_read(File $file, int $offset = 0, int $count = 0, bool $alwa
$highestRow = count($data);
if ($always_include_header) {
- $rowHeaders = $data[0];
+ $rowHeaders = $data[0] ?? [];
$rowHeaders_utf8 = array_map('stripslashes', $rowHeaders);
$rowHeaders_utf8 = array_map('utf8_encode', $rowHeaders_utf8);
$rowHeaders_utf8 = array_map('strtolower', $rowHeaders_utf8);
diff --git a/src/Controller/AmiRowAutocompleteHandler.php b/src/Controller/AmiRowAutocompleteHandler.php
index 3cc205b..e6bc02d 100644
--- a/src/Controller/AmiRowAutocompleteHandler.php
+++ b/src/Controller/AmiRowAutocompleteHandler.php
@@ -138,10 +138,15 @@ public static function ajaxPreviewAmiSet($form, FormStateInterface $form_state)
/** @var \Drupal\format_strawberryfield\MetadataDisplayInterface $entity */
$entity = $form_state->getFormObject()->getEntity();
+
// Attach the library necessary for using the OpenOffCanvasDialogCommand and
// set the attachments for this Ajax response.
$form['#attached']['library'][] = 'core/drupal.dialog.off_canvas';
$form['#attached']['library'][] = 'codemirror_editor/editor';
+ $form['#attached']['library'][] = 'core/jquery';
+ $form['#attached']['library'][] = 'core/jquery.form';
+ $form['#attached']['library'][] = 'core/drupal.dialog.ajax';
+ $form['#attached']['library'][] = 'core/drupal.ajax';
$response->setAttachments($form['#attached']);
$row = $form_state->getValues()['ado_amiset_row_context_preview'] ?? 1;
$row = (int) $row;
@@ -159,159 +164,227 @@ public static function ajaxPreviewAmiSet($form, FormStateInterface $form_state)
}
// Now get the row, if not passed we will get the first because we are
// weird.
- error_log(PHP_VERSION_ID);
$csv_file_reference = $preview_ami_set->get('source_data')->getValue();
if (isset($csv_file_reference[0]['target_id'])) {
/** @var \Drupal\file\Entity\File $file */
$file = \Drupal::entityTypeManager()->getStorage('file')->load(
$csv_file_reference[0]['target_id']
);
- if (PHP_VERSION_ID < 80000) {
+ if (PHP_VERSION_ID < 81000) {
//@TODO fgetcsv has a bug when called after a seek, offsets on 1 always.
// We are trying to skip the header too (but get it)
- $row = $row - 2;
+ // Tested on 80016 and error is still in place.
+ $row = $row - 2;
+ }
+ $file_data_all = NULL;
+ if ($file) {
+ $file_data_all = \Drupal::service('ami.utility')
+ ->csv_read($file, $row, 1, TRUE);
}
- $file_data_all = \Drupal::service('ami.utility')
- ->csv_read($file, $row, 1, TRUE);
- $jsondata = array_combine($file_data_all['headers'], reset($file_data_all['data']));
- $jsondata = \Drupal::service('ami.utility')->expandJson($jsondata);
- // Check if render native is requested and get mimetype
- $mimetype = $form_state->getValue('mimetype');
- $mimetype = !empty($mimetype) ? $mimetype[0]['value'] : 'text/html';
- $show_render_native = $form_state->getValue('render_native');
+ if ($file_data_all !== NULL && !empty($file_data_all['data']) && is_array($file_data_all['data'])) {
- // Set initial context.
- $context = [
- 'node' => NULL,
- 'iiif_server' => \Drupal::service('config.factory')
- ->get('format_strawberryfield.iiif_settings')
- ->get('pub_server_url'),
- ];
+ $jsondata = array_combine($file_data_all['headers'],
+ reset($file_data_all['data']));
+ $jsondata = \Drupal::service('ami.utility')->expandJson($jsondata);
+ // Check if render native is requested and get mimetype
+ $mimetype = $form_state->getValue('mimetype');
+ $mimetype = !empty($mimetype) ? $mimetype[0]['value'] : 'text/html';
+ $show_render_native = $form_state->getValue('render_native');
- $context['data'] = $jsondata;
+ $context_lod = [];
+ $lod_mappings = \Drupal::service('ami.lod')
+ ->getKeyValueMappingsPerAmiSet($id);
+ if ($lod_mappings) {
+ foreach ($lod_mappings as $source_column => $destination) {
+ if (is_array($destination)) {
+ foreach ($destination as $pos_approach) {
+ $context_lod[$source_column][$pos_approach] = $context_lod[$source_column][$pos_approach] ?? [];
+ }
+ }
- $output = [];
- $output['json'] = [
- '#type' => 'details',
- '#title' => t('JSON Data'),
- '#open' => FALSE,
- ];
- $output['json']['data'] = [
- '#type' => 'codemirror',
- '#rows' => 60,
- '#value' => json_encode($context['data'], JSON_PRETTY_PRINT),
- '#codemirror' => [
- 'lineNumbers' => FALSE,
- 'toolbar' => FALSE,
- 'readOnly' => TRUE,
- 'mode' => 'application/json',
- ],
- ];
+ if (isset($jsondata[$source_column])) {
+ // sad here. Ok, this is a work around for our normally
+ // Strange CSV data structure
+ $data_to_clean['data'][0] = [$jsondata[$source_column]];
+ $labels = \Drupal::service('ami.utility')
+ ->getDifferentValuesfromColumnSplit($data_to_clean,
+ 0);
- // Try to Ensure we're using the twig from user's input instead of the entity's
- // default.
- try {
- $input = $form_state->getUserInput();
- $entity->set('twig', $input['twig'][0], FALSE);
- $render = $entity->renderNative($context);
- if ($show_render_native) {
- $message = '';
- switch ($mimetype) {
- case 'application/ld+json':
- case 'application/json':
- json_decode((string) $render);
- if (JSON_ERROR_NONE !== json_last_error()) {
- throw new \Exception(
- 'Error parsing JSON: ' . json_last_error_msg(),
- 0,
- NULL
- );
+ foreach ($labels as $label) {
+ $lod_for_label = \Drupal::service('ami.lod')
+ ->getKeyValuePerAmiSet($label, $id);
+ if (is_array($lod_for_label) && count($lod_for_label) > 0) {
+ foreach ($lod_for_label as $approach => $lod) {
+ if (isset($lod['lod'])) {
+ $context_lod[$source_column][$approach] = array_merge($context_lod[$source_column][$approach] ?? [],
+ $lod['lod']);
+ }
+ }
+ }
}
- break;
- case 'text/html':
- libxml_use_internal_errors(TRUE);
- $dom = new \DOMDocument('1.0', 'UTF-8');
- if ($dom->loadHTML((string) $render)) {
- if ($error = libxml_get_last_error()) {
- libxml_clear_errors();
- $message = $error->message;
+ }
+ }
+ }
+
+
+ // Set initial context.
+ $context = [
+ 'node' => NULL,
+ 'iiif_server' => \Drupal::service('config.factory')
+ ->get('format_strawberryfield.iiif_settings')
+ ->get('pub_server_url'),
+ ];
+
+ $context['data'] = $jsondata;
+ $context['data_lod'] = $context_lod;
+ $output = [];
+ $output['json'] = [
+ '#type' => 'details',
+ '#title' => t('JSON Data'),
+ '#open' => FALSE,
+ ];
+ $output['json']['data'] = [
+ '#title' => t('Your row data. e.g {{ data.keyname }} :'),
+ '#type' => 'codemirror',
+ '#rows' => 60,
+ '#value' => json_encode($context['data'], JSON_PRETTY_PRINT),
+ '#codemirror' => [
+ 'lineNumbers' => FALSE,
+ 'toolbar' => FALSE,
+ 'readOnly' => TRUE,
+ 'mode' => 'application/json',
+ ],
+ ];
+ $output['json']['data_lod'] = [
+ '#type' => 'codemirror',
+ '#title' => t('Reconciliated LoD for this row {{ data_lod.keyname.lod_endpoint_type }} :'),
+ '#rows' => 60,
+ '#value' => json_encode($context['data_lod'], JSON_PRETTY_PRINT),
+ '#codemirror' => [
+ 'lineNumbers' => FALSE,
+ 'toolbar' => FALSE,
+ 'readOnly' => TRUE,
+ 'mode' => 'application/json',
+ ],
+ ];
+
+ // Try to Ensure we're using the twig from user's input instead of the entity's
+ // default.
+ try {
+ $input = $form_state->getUserInput();
+ $entity->set('twig', $input['twig'][0], FALSE);
+ $render = $entity->renderNative($context);
+ if ($show_render_native) {
+ $message = '';
+ switch ($mimetype) {
+ case 'application/ld+json':
+ case 'application/json':
+ json_decode((string) $render);
+ if (JSON_ERROR_NONE !== json_last_error()) {
+ throw new \Exception(
+ 'Error parsing JSON: ' . json_last_error_msg(),
+ 0,
+ NULL
+ );
}
break;
- }
- else {
- throw new \Exception(
- 'Error parsing HTML',
- 0,
- NULL
- );
- }
- case 'application/xml':
- libxml_use_internal_errors(TRUE);
- try {
- libxml_clear_errors();
- $dom = new \SimpleXMLElement((string) $render);
- if ($error = libxml_get_last_error()) {
- $message = $error->message;
+ case 'text/html':
+ libxml_use_internal_errors(TRUE);
+ $dom = new \DOMDocument('1.0', 'UTF-8');
+ if ($dom->loadHTML((string) $render)) {
+ if ($error = libxml_get_last_error()) {
+ libxml_clear_errors();
+ $message = $error->message;
+ }
+ break;
}
- } catch (\Exception $e) {
- throw new \Exception(
- "Error parsing XML: {$e->getMessage()}",
- 0,
- NULL
- );
- }
- break;
+ else {
+ throw new \Exception(
+ 'Error parsing HTML',
+ 0,
+ NULL
+ );
+ }
+ case 'application/xml':
+ libxml_use_internal_errors(TRUE);
+ try {
+ libxml_clear_errors();
+ $dom = new \SimpleXMLElement((string) $render);
+ if ($error = libxml_get_last_error()) {
+ $message = $error->message;
+ }
+ } catch (\Exception $e) {
+ throw new \Exception(
+ "Error parsing XML: {$e->getMessage()}",
+ 0,
+ NULL
+ );
+ }
+ break;
+ }
+ }
+ if (!$show_render_native || ($show_render_native && $mimetype != 'text/html')) {
+ $output['preview'] = [
+ '#type' => 'codemirror',
+ '#title' => t('Processed Output:'),
+ '#rows' => 60,
+ '#value' => $render,
+ '#codemirror' => [
+ 'lineNumbers' => FALSE,
+ 'toolbar' => FALSE,
+ 'readOnly' => TRUE,
+ 'mode' => $mimetype,
+ ],
+ ];
+ }
+ else {
+ $output['preview'] = [
+ '#type' => 'details',
+ '#open' => TRUE,
+ '#title' => 'HTML Output',
+ 'messages' => [
+ '#markup' => $message,
+ '#attributes' => [
+ 'class' => ['error'],
+ ],
+ ],
+ 'render' => [
+ '#markup' => $render,
+ ],
+ ];
+ }
+ } catch (\Exception $exception) {
+ // Make the Message easier to read for the end user
+ if ($exception instanceof TwigError) {
+ $message = $exception->getRawMessage() . ' at line ' . $exception->getTemplateLine();
+ }
+ else {
+ $message = $exception->getMessage();
}
- }
- if (!$show_render_native || ($show_render_native && $mimetype != 'text/html')) {
- $output['preview'] = [
- '#type' => 'codemirror',
- '#rows' => 60,
- '#value' => $render,
- '#codemirror' => [
- 'lineNumbers' => FALSE,
- 'toolbar' => FALSE,
- 'readOnly' => TRUE,
- 'mode' => $mimetype,
- ],
- ];
- }
- else {
$output['preview'] = [
'#type' => 'details',
'#open' => TRUE,
- '#title' => 'HTML Output',
- 'messages' => [
+ '#title' => t('Syntax error'),
+ 'error' => [
'#markup' => $message,
- '#attributes' => [
- 'class' => ['error'],
- ],
- ],
- 'render' => [
- '#markup' => $render,
- ],
+ ]
];
}
- } catch (\Exception $exception) {
- // Make the Message easier to read for the end user
- if ($exception instanceof TwigError) {
- $message = $exception->getRawMessage() . ' at line ' . $exception->getTemplateLine();
- }
- else {
- $message = $exception->getMessage();
- }
-
+ $response->addCommand(new OpenOffCanvasDialogCommand(t('Preview'),
+ $output, ['width' => '50%']));
+ }
+ else {
$output['preview'] = [
'#type' => 'details',
'#open' => TRUE,
- '#title' => t('Syntax error'),
+ '#title' => !$file ? t('AMI Set has no CSV File'): t('AMI Set has no data for chosen row.'),
'error' => [
'#markup' => $message,
]
];
+ $response->addCommand(new OpenOffCanvasDialogCommand(t('Preview'),
+ $output, ['width' => '50%']));
}
- $response->addCommand(new OpenOffCanvasDialogCommand(t('Preview'),
- $output, ['width' => '50%']));
}
}
// Always refresh the Preview Element too.
@@ -338,8 +411,6 @@ public static function rowAjaxCallback($form, FormStateInterface $form_state) {
if ($id) {
$form['preview']['ado_amiset_row_context_preview']['#autocomplete_route_parameters'] = ['ami_set_entity' => $id];
}
- //$form_state->getUserInput()['ado_amiset_preview'] == name (id)
- //$form_state->getValues()['ado_amiset_preview'] == id
\Drupal::messenger()->deleteByType(MessengerInterface::TYPE_STATUS);
$response->addCommand(new ReplaceCommand('#metadata-preview-container', $form['preview']));
return $response;
diff --git a/src/TwigExtension.php b/src/TwigExtension.php
new file mode 100644
index 0000000..02ab95c
--- /dev/null
+++ b/src/TwigExtension.php
@@ -0,0 +1,82 @@
+ 'LoC subjects(LCSH)',
+ 'loc;names;athing' => 'LoC Name Authority File (LCNAF)',
+ 'loc;genreForms;thing' => 'LoC Genre/Form Terms (LCGFT)',
+ 'loc;graphicMaterials;thing' => 'LoC Thesaurus of Graphic Materials (TGN)',
+ 'loc;geographicAreas;thing' => 'LoC MARC List for Geographic Areas',
+ 'loc;relators;thing' => 'LoC Relators Vocabulary (Roles)',
+ 'loc;rdftype;CorporateName' => 'LoC MADS RDF by type: Corporate Name',
+ 'loc;rdftype;PersonalName' => 'LoC MADS RDF by type: Personal Name',
+ 'loc;rdftype;FmilyName' => 'LoC MADS RDF by type: Family Name',
+ 'loc;rdftype;Topic' => 'LoC MADS RDF by type: Topic',
+ 'loc;rdftype;GenreForm' => 'LoC MADS RDF by type: Genre Form',
+ 'loc;rdftype;Geographic' => 'LoC MADS RDF by type: Geographic',
+ 'loc;rdftype;Temporal' => 'LoC MADS RDF by type: Temporal',
+ 'loc;rdftype;ExtraterrestrialArea' => 'LoC MADS RDF by type: Extraterrestrial Area',
+ 'viaf;subjects;thing' => 'Viaf',
+ 'getty;aat;fuzzy' => 'Getty aat Fuzzy',
+ 'getty;aat;terms' => 'Getty aat Terms',
+ 'getty;aat;exact' => 'Getty aat Exact Label Match',
+ 'wikidata;subjects;thing' => 'Wikidata Q Items'
+ ];
+ $label = trim($label);
+ try {
+ $domain = \Drupal::service('request_stack')->getCurrentRequest()->getSchemeAndHttpHost();
+ $lod_route_argument_list = explode(";", $vocab);
+ $lod = \Drupal::service('ami.lod')->invokeLoDRoute($domain,
+ $label, $lod_route_argument_list[0],
+ $lod_route_argument_list[1], $lod_route_argument_list[2], $len ?? 'en', 1);
+ }
+ catch (\Exception $exception) {
+ $message = t('@exception_type thrown in @file:@line while querying for @entity_type entity ids matching "@label". Message: @response',
+ [
+ '@exception_type' => get_class($exception),
+ '@file' => $exception->getFile(),
+ '@line' => $exception->getLine(),
+ '@label' => $label,
+ '@response' => $exception->getMessage(),
+ ]);
+ \Drupal::logger('ami')->warning($message);
+ return NULL;
+ }
+
+ if (!empty($lod)) {
+ return $lod;
+ }
+ return NULL;
+ }
+}