diff --git a/README.md b/README.md index d3f7e7b..0531972 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,20 @@ # Webform Strawberry Field -A module that provides Drupal 8 Webform ( == awesome piece of code) integrations for StrawberryField so you can really have control over your Metadata ingests. This is part of the Archipelago Commons Project. +A module that provides Drupal 8/9 Webform ( == awesome piece of code) integrations for StrawberryField so you can really have control over your Metadata ingests. This is part of the Archipelago Commons Project. -# Disclaimer -This is an experimental module, use at your own risk +# Setup + +This module provides many LoD Autocomplete suggester Webform Elements, but only *The Europeana Entity Suggester* for now requires you to provide an `APIKEY`. +To be able to use the Europeana Suggester edit your Drupal `settings.php` file (located normally in `web/sites/default/settings.php`) and add the following line: + +```PHP +$settings['webform_strawberryfield.europeana_entity_apikey'] = 'thekey'; +``` + +Save and clear caches. + +In its current state the Europeana Entity API (Alpha 0.5) uses a static APIKEY (not the same as other APIs) and can be found at https://pro.europeana.eu/page/entity#suggest + +If using https://github.com/esmero/archipelago-deployment this is not needed and will be provided by the deployment. ## Help @@ -18,6 +30,7 @@ Having issues with this module? Check out the Archipelago Commons google groups * [Diego Pino](https://github.com/DiegoPino) * [Giancarlo Birello](https://github.com/giancarlobi) +* [Allison Lund](https://github.com/alliomeria) ## Acknowledgments diff --git a/config/schema/webform_strawberryfield.schema.yml b/config/schema/webform_strawberryfield.schema.yml index ba31266..9a14df8 100644 --- a/config/schema/webform_strawberryfield.schema.yml +++ b/config/schema/webform_strawberryfield.schema.yml @@ -1,3 +1,9 @@ +webform_strawberryfield.settings: + type: config_object + mapping: + europeana_entity_apikey: + type: string + label: 'Europeana Entity API Secret key' field.widget.settings.strawberryfield_webform_inline_widget: type: config_object label: 'Webform Inline Widget Schema' diff --git a/js/hidenodeaction-webform_strawberryfield.js b/js/hidenodeaction-webform_strawberryfield.js index 5fd53a0..0aef16f 100644 --- a/js/hidenodeaction-webform_strawberryfield.js +++ b/js/hidenodeaction-webform_strawberryfield.js @@ -18,28 +18,27 @@ Drupal.behaviors.webformstrawberryHideNodeActions = { attach: function (context, settings) { // Only react if the document contains a strawberry webform widget - if ($('.path-node fieldset[data-strawberryfield-selector="strawberry-webform-widget"]').length) { + if ($('.node-form fieldset[data-strawberryfield-selector="strawberry-webform-widget"]').length) { if ($('.webform-confirmation',context).length) { // Exclude webform own edit-actions containter /* And hide, if present the close button but only show save if all are ready. @TODO we need to figure out what if there are many webforms open at different states in the same Entity Form. */ - $('.path-node .node-form div[data-drupal-selector="edit-actions"]').not('.webform-actions').show(); - $('.path-node .node-form div[data-drupal-selector="edit-footer"]').not('.webform-actions').show(); + $('.node-form div[data-drupal-selector="edit-actions"]').not('.webform-actions').show(); + $('.node-form div[data-drupal-selector="edit-footer"]').not('.webform-actions').show(); $('.webform-confirmation').closest('[data-strawberryfield-selector="strawberry-webform-widget"]').each(function() { var $id = $(this).attr('id') + '-strawberry-webform-close-modal'; $('#' + $id).toggleClass('js-hide'); }) - } else if ( $('div.field--widget-strawberryfield-webform-inline-widget .webform-submission-form').length || $('div.field--widget-strawberryfield-webform-widget .webform-submission-form').length ) { - $('.path-node .node-form div[data-drupal-selector="edit-actions"]').not('.webform-actions').hide(); - $('.path-node .node-form div[data-drupal-selector="edit-footer"]').not('.webform-actions').hide(); + $('.node-form div[data-drupal-selector="edit-actions"]').not('.webform-actions').hide(); + $('.node-form div[data-drupal-selector="edit-footer"]').not('.webform-actions').hide(); } var $moderationstate = $('select[data-drupal-selector="edit-moderation-state-0-state"]', context).once('show-hide-actions'); if ($moderationstate.length) { @@ -52,8 +51,7 @@ var $nodetitle = $('input[data-drupal-selector="edit-title-0-value"]', context).once('show-hide-actions'); if ($nodetitle.length) { var $select = $nodetitle.on('input', function () { - $('.path-node .node-form div[data-drupal-selector="edit-actions"]').not('.webform-actions').show(); - + $('.node-form div[data-drupal-selector="edit-actions"]').not('.webform-actions').show(); }); } } diff --git a/src/Controller/AuthAutocompleteController.php b/src/Controller/AuthAutocompleteController.php index d6cc38b..1ae2db3 100644 --- a/src/Controller/AuthAutocompleteController.php +++ b/src/Controller/AuthAutocompleteController.php @@ -2,8 +2,14 @@ namespace Drupal\webform_strawberryfield\Controller; +use Drupal\Core\Cache\Cache; +use Drupal\Core\Cache\CacheBackendInterface; +use Drupal\Core\Cache\UseCacheBackendTrait; +use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Controller\ControllerBase; use Drupal\Core\DependencyInjection\ContainerInjectionInterface; +use Drupal\Core\Session\AccountInterface; +use Drupal\Core\Site\Settings; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; @@ -12,6 +18,7 @@ use GuzzleHttp\Exception\ServerException; use Drupal\Component\Utility\UrlHelper; use Drupal\Core\Url; +use Drupal\Component\Datetime\TimeInterface; /** * Defines a route controller for Authority autocomplete form elements. @@ -20,6 +27,19 @@ */ class AuthAutocompleteController extends ControllerBase implements ContainerInjectionInterface { + use UseCacheBackendTrait; + + /** + * Mark a 401 so we can cache the fact that a certain URL will simply fail. + * + * @var bool + */ + public $notAllowed = FALSE; + + /** + * Max time to live the Results cache + */ + const MAX_CACHE_AGE = 604800; /** * English Stop words. @@ -67,14 +87,37 @@ class AuthAutocompleteController extends ControllerBase implements ContainerInje */ protected $httpClient; + /** + * The Time Service. + * + * @var \Drupal\Component\Datetime\TimeInterface + */ + protected $time; + + + /** + * The Current User. + * + * @var \Drupal\Core\Session\AccountInterface + */ + protected $currentUser; /** * AuthAutocompleteController constructor. * * @param \GuzzleHttp\Client $httpClient + * @param \Drupal\Component\Datetime\TimeInterface $time + * The time service. + * @param \Drupal\Core\Session\AccountInterface $current_user + * @param \Drupal\Core\Cache\CacheBackendInterface $cacheBackend + * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory */ - public function __construct(Client $httpClient) { + public function __construct(Client $httpClient, TimeInterface $time, AccountInterface $current_user, CacheBackendInterface $cacheBackend, ConfigFactoryInterface $configFactory) { $this->httpClient = $httpClient; + $this->time = $time; + $this->currentUser = $current_user; + $this->cacheBackend = $cacheBackend; + $this->configFactory = $configFactory; } /** @@ -84,8 +127,11 @@ public function __construct(Client $httpClient) { */ public static function create(ContainerInterface $container) { return new static( - $container->get('http_client') - + $container->get('http_client'), + $container->get('datetime.time'), + $container->get('current_user'), + $container->get('cache.data'), + $container->get('config.factory') ); } @@ -106,7 +152,25 @@ public function handleAutocomplete(Request $request, $auth_type, $vocab = 'subje //@TODO maybe refactor into plugins so others can write any other reconciliators //@TODO if so, we can query the plugins and show in the webform builder options // Get the typed string from the URL, if it exists. - if ($input = $request->query->get('q')) { + + $apikey = Settings::get('webform_strawberryfield.europeana_entity_apikey'); + $input = $request->query->get('q'); + if ($this->currentUser->isAnonymous()) { + sleep(5); + } + + + if ($input) { + $rdftype_str = $rdftype ?? 'null'; + $apikey_hash = $apikey ?? 'null'; + $count = $count ?? 10; + $cache_var = md5($auth_type.$input.$vocab.$rdftype_str.$count.$apikey_hash); + $cache_id = 'webform_strawberry:auth_lod:' . $cache_var; + $cached = $this->cacheGet($cache_id); + if ($cached) { + return new JsonResponse($cached->data); + } + switch ($auth_type) { case 'loc': $results = $this->loc($input, $vocab, $rdftype); @@ -124,9 +188,26 @@ public function handleAutocomplete(Request $request, $auth_type, $vocab = 'subje case 'viaf': $results = $this->viaf($input); break; + case 'europeana': + if ($apikey) { + $results = $this->europeana($input, $vocab, $apikey); + } + else { + $this->messenger()->addError( + $this->t("Can't query Europeana.Your Entity API key is not set. Please add it to your settings.php as \$settings['webform_strawberryfield.europeana_entity_apikey'] = 'yourapikey'" + ) + ); + } } } - + // DO not cache NULL or FALSE. Those will be 401/403/500; + if ($results) { + //setting cache for + $this->cacheSet($cache_id, $results, + ($this->time->getRequestTime() + static::MAX_CACHE_AGE), + ['user:'.$this->currentUser->id()]); + } + $results = $results ?? []; return new JsonResponse($results); } @@ -423,7 +504,6 @@ protected function getty($input, $vocab = 'aat', $mode = 'fuzzy') { $baseurl = 'http://vocab.getty.edu/sparql.json'; // I leave this as an array in case we want to combine modes in the future. foreach($queries as $query) { - error_log($query); $options = ['query' => ['query' => $query]]; $url = Url::fromUri($baseurl, $options); $remoteUrl = $url->toString() . '&_implicit=false&implicit=true&_equivalent=false&_form=%2Fsparql'; @@ -455,8 +535,6 @@ protected function getty($input, $vocab = 'aat', $mode = 'fuzzy') { } */ - - $jsonfail = FALSE; foreach($bodies as $body) { $jsondata = json_decode($body, TRUE); @@ -555,18 +633,131 @@ protected function viaf($input) { return []; } + /** + * @param $input + * The query + * @param $vocab + * Europeana Entity Type requested + * + * @param $apikey + * + * @return array + */ + protected function europeana($input, $vocab, string $apikey) { + //@TODO make the following allowed list a constant since we use it in + // \Drupal\webform_strawberryfield\Plugin\WebformElement\WebformLoC + if (!in_array($vocab, [ + 'agent', + 'concept', + 'place', + ])) { + // Drop before trying to hit non existing vocab + $this->messenger()->addError( + $this->t('@vocab for Europeana Entity Suggest autocomplete is not in in our allowed list.', + [ + '@vocab' => $vocab, + ] + ) + ); + $results[] = [ + 'value' => NULL, + 'label' => "Wrong Vocabulary {$vocab} in Europeana Entity Query", + ]; + return $results; + } + + $input = urlencode($input); + + $urlindex = "/suggest?text=" . $input . "&type=" . $vocab ."&wskey=". $apikey ; + + $baseurl = 'https://www.europeana.eu/api/entities'; + $remoteUrl = $baseurl . $urlindex; + $options['headers'] = ['Accept' => 'application/ld+json']; + $body = $this->getRemoteJsonData($remoteUrl, $options); + $results = []; + $jsondata = json_decode($body, TRUE); + $json_error = json_last_error(); + if ($json_error == JSON_ERROR_NONE) { + /* + { + "@context": [ + "https://www.w3.org/ns/ldp.jsonld", + "http://www.europeana.eu/schemas/context/entity.jsonld", + { + "@language": "en" + } + ], + "total": 10, + "type": "BasicContainer", + "contains": [ + { + "type": "Agent" + "id": "http://data.europeana.eu/agent/base/147466", + "prefLabel": { + "en": "Arturo Toscanini" + }, + "dateOfBirth": "1867-03-25", + "dateOfDeath": "1957-01-16", + }, + { .. } + ] + } + */ + // @NOTE!: This is API V 0.5 Already ill documented and its changing. So review the API every 2-3 months + if (isset($jsondata['total']) && $jsondata['total'] >= 1 && isset($jsondata['items']) && is_array($jsondata['items'])) { + foreach ($jsondata['items'] as $key => $result) { + $desc = NULL; + if (($vocab == 'place') && isset($result['isPartOf']) && is_array($result['isPartOf'])) { + foreach( $result['isPartOf'] as $partof) { + $desc[] = reset($partof['prefLabel']); + } + } + + if (($vocab == 'agent') && isset($result['dateOfBirth'])) { + $desc[] = $result['dateOfBirth'] . '/' . $result['dateOfDeath'] ?? '?'; + } + + $desc = !empty($desc) ? ' (' . implode(', ', $desc) . ')' : NULL; + $label = $result['prefLabel']['en'] ?? (reset($result['prefLabel']) ?? 'No Label'); + $label = empty($desc) ? $label : $label . $desc; + $results[] = [ + 'value' => $result['id'], + 'label' => $label, + 'desc' => $desc, + ]; + } + } + else { + $results[] = [ + 'value' => NULL, + 'label' => "Sorry no match from Europeana {$vocab}", + ]; + } + return $results; + } + $this->messenger()->addError( + $this->t('Looks like data fetched from @url is not in JSON format.
JSON says: @jsonerror
Please check your URL!', + [ + '@url' => $remoteUrl, + '@jsonerror' => $json_error, + ] + ) + ); + return []; + } /** * @param $remoteUrl * @param $options * - * @return array|string + * @return string + * A string that may be JSON (hopefully) */ protected function getRemoteJsonData($remoteUrl, $options) { // This is expensive, reason why we process and store in cache if (empty($remoteUrl)) { // No need to alarm. all good. If not URL just return. - return []; + return NULL; } if (!UrlHelper::isValid($remoteUrl, $absolute = TRUE)) { $this->messenger()->addError( @@ -574,13 +765,28 @@ protected function getRemoteJsonData($remoteUrl, $options) { ['@$remoteUrl' => $remoteUrl] ) ); - return []; + return NULL; } - - try { $request = $this->httpClient->get($remoteUrl, $options); - } catch (ClientException $exception) { + // Do not cache if things go bad. + if ($request->getStatusCode() == '401') { + $this->setNotAllowed(TRUE); + $this->useCaches = FALSE; + return NULL; + // Means we got a server Access Denied, we reply to whoever made the call. + } + if ($request->getStatusCode() == '404') { + $this->useCaches = FALSE; + return NULL; + } + if ($request->getStatusCode() == '500') { + $this->useCaches = FALSE; + return NULL; + } + } + catch (ClientException $exception) { + $this->useCaches = FALSE; $responseMessage = $exception->getMessage(); $this->messenger()->addError( $this->t('We tried to contact @url but we could not.
The WEB says: @response.
Check that URL!', @@ -590,8 +796,10 @@ protected function getRemoteJsonData($remoteUrl, $options) { ] ) ); - return []; - } catch (ServerException $exception) { + return NULL; + } + catch (ServerException $exception) { + $this->useCaches = FALSE; $responseMessage = $exception->getMessage(); $this->loggerFactory->get('webform_strawberryfield') ->error('We tried to contact @url but we could not.
The Remote server says: @response.
Check your query', @@ -600,10 +808,25 @@ protected function getRemoteJsonData($remoteUrl, $options) { '@response' => $responseMessage, ] ); - return []; + return NULL; } + $body = $request->getBody()->getContents(); return $body; } + /** + * @return bool + */ + public function isNotAllowed(): bool { + return $this->notAllowed; + } + + /** + * @param bool $notAllowed + */ + public function setNotAllowed(bool $notAllowed): void { + $this->notAllowed = $notAllowed; + } + } diff --git a/src/Controller/StrawberryRunnerModalController.php b/src/Controller/StrawberryRunnerModalController.php index 15eb92a..8feb4dd 100644 --- a/src/Controller/StrawberryRunnerModalController.php +++ b/src/Controller/StrawberryRunnerModalController.php @@ -34,8 +34,7 @@ class StrawberryRunnerModalController extends ControllerBase * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException * Thrown when not be accessible. */ - public function openModalForm(WebformInterface $webform = NULL, Request $request) - { + public function openModalForm(WebformInterface $webform = NULL, Request $request) { // @see \Drupal\archipel\Plugin\Field\FieldWidget\StrawberryFieldWebFormWidget::formElement // Request Arguments we are expecting: @@ -70,6 +69,8 @@ public function openModalForm(WebformInterface $webform = NULL, Request $request // throw new \InvalidArgumentException('Data type must be in the form of // "entityUUID:FIELD_NAME:DELTA:someSHA1hashthatidentifiesthegtriggeringwidget"'); + /* @var $source_entity \Drupal\Core\Entity\FieldableEntityInterface */ + $source_entity = NULL; // If uuid does not exist then it may be a new ADO. That is Ok. if ($source_uuid && Uuid::isValid($source_uuid)) { try { @@ -100,8 +101,6 @@ public function openModalForm(WebformInterface $webform = NULL, Request $request $notfound, ['width' => '90%'])); return $response; } - //@var $source_entity \Drupal\Core\Entity\FieldableEntityInterface */ - $source_entity = NULL; foreach ($entities as $entity) { // Means there was an entity stored! hu! diff --git a/src/Element/WebformEuropeana.php b/src/Element/WebformEuropeana.php new file mode 100644 index 0000000..2d7f127 --- /dev/null +++ b/src/Element/WebformEuropeana.php @@ -0,0 +1,109 @@ + 'agent', + '#rdftype' => 'thing' + ]; + return $info; + } + + /** + * {@inheritdoc} + */ + public static function getCompositeElements(array $element) { + + $elements = []; + $vocab = 'agent'; + $rdftype = 'thing'; + if (isset($element['#vocab'])) { + $vocab = $element['#vocab']; + } + + $class = '\Drupal\webform_strawberryfield\Element\WebformEuropeana'; + $elements['label'] = [ + '#type' => 'textfield', + '#title' => t('Label'), + '#autocomplete_route_name' => 'webform_strawberryfield.auth_autocomplete', + '#autocomplete_route_parameters' => ['auth_type' => 'europeana', 'vocab' => $vocab, 'rdftype'=> $rdftype ,'count' => 10], + '#attributes' => [ + 'data-source-strawberry-autocomplete-key' => 'label', + 'data-target-strawberry-autocomplete-key' => 'uri' + ], + + ]; + $elements['uri'] = [ + '#type' => 'url', + '#title' => t('Subject URL'), + '#attributes' => ['data-strawberry-autocomplete-value' => TRUE] + ]; + $elements['label']['#process'][] = [$class, 'processAutocomplete']; + return $elements; + } + + + + /** + * {@inheritdoc} + */ + public static function processWebformComposite(&$element, FormStateInterface $form_state, &$complete_form) { + // @Disclaimer: This function is the worst and deceiving. Keeping it here + // So i never make this error again. Because of + // \Drupal\webform\Plugin\WebformElement\WebformCompositeBase::prepareMultipleWrapper + // Basically, in case of having multiple elements :: processWebformComposite + // is *never* called because it actually converts the 'WebformComposite' element into a + // \Drupal\webform\Element\WebformMultiple calling ::processWebformMultiple element + // So basically whatever i do here gets skipped if multiple elements are allowed. + // Solution is acting here instead: + // \Drupal\webform_strawberryfield\Plugin\WebformElement\WebformLoC::prepareMultipleWrapper + $vocab = 'agent'; + $rdftype = 'thing'; + + $element = parent::processWebformComposite($element, $form_state, $complete_form); + if (isset($element['#vocab'])) { + $vocab = $element['#vocab']; + } + + $element['label']["#autocomplete_route_parameters"] = + ['auth_type' => 'europeana', 'vocab' => $vocab, 'rdftype'=> $rdftype ,'count' => 10]; + + return $element; + } + + /** + * @param array $element + * @param \Drupal\Core\Form\FormStateInterface $form_state + * @param array $complete_form + * + * @return array + */ + public static function processAutocomplete(&$element, FormStateInterface $form_state, &$complete_form) { + $element = parent::processAutocomplete($element, $form_state, $complete_form); + $element['#attached']['library'][] = 'webform_strawberryfield/webform_strawberryfield.metadataauth.autocomplete'; + $element['#attached']['drupalSettings'] = [ + 'webform_strawberryfield_autocomplete' => [], + ]; + + $element['#attributes']['data-strawberry-autocomplete'] = 'europeana'; + return $element; + } + + +} diff --git a/src/Element/WebformNominatim.php b/src/Element/WebformNominatim.php index 592f12c..72e8488 100644 --- a/src/Element/WebformNominatim.php +++ b/src/Element/WebformNominatim.php @@ -261,7 +261,7 @@ public static function nominatimSelectCallBack( } /** - * Submit Hanlder for the Nominatim reconciliation call. + * Submit Handler for the Nominatim reconciliation call. * * @param array $form * @param \Drupal\Core\Form\FormStateInterface $form_state @@ -306,7 +306,6 @@ public static function nominatimFetchSubmit( 'search', 5, $current_laguage - ); $nomitanim_response_encoded = $json_response->isSuccessful() ? $json_response->getContent() : []; diff --git a/src/Plugin/Field/FieldWidget/StrawberryFieldWebFormInlineWidget.php b/src/Plugin/Field/FieldWidget/StrawberryFieldWebFormInlineWidget.php index 9adf601..6f4bac7 100644 --- a/src/Plugin/Field/FieldWidget/StrawberryFieldWebFormInlineWidget.php +++ b/src/Plugin/Field/FieldWidget/StrawberryFieldWebFormInlineWidget.php @@ -575,7 +575,7 @@ public function massageFormValues(array $values, array $form, FormStateInterface // Who do we ask? $jsonarray["as:generator"] = $this->addActivityStream($form_state); - $jsonvalue = json_encode($jsonarray, JSON_PRETTY_PRINT); + $jsonvalue = json_encode($jsonarray); $values2[0]['value'] = $jsonvalue; // @TODO this no longer is part of wild strawberry field defintion. We already have other // ways of keeping track. Remove or deprecate. diff --git a/src/Plugin/Field/FieldWidget/StrawberryFieldWebFormWidget.php b/src/Plugin/Field/FieldWidget/StrawberryFieldWebFormWidget.php index 45c26a2..d6e405c 100644 --- a/src/Plugin/Field/FieldWidget/StrawberryFieldWebFormWidget.php +++ b/src/Plugin/Field/FieldWidget/StrawberryFieldWebFormWidget.php @@ -416,7 +416,7 @@ public function massageFormValues(array $values, array $form, FormStateInterface // Who do we ask? $jsonarray["as:generator"] = $this->addActivityStream($form_state); - $jsonvalue = json_encode($jsonarray, JSON_PRETTY_PRINT); + $jsonvalue = json_encode($jsonarray); $values2[0]['value'] = $jsonvalue; // @TODO this no longer is part of wild strawberry field definition. We already have other // ways of keeping track. Remove or deprecate. diff --git a/src/Plugin/WebformElement/WebformEuropeana.php b/src/Plugin/WebformElement/WebformEuropeana.php new file mode 100644 index 0000000..b8cd514 --- /dev/null +++ b/src/Plugin/WebformElement/WebformEuropeana.php @@ -0,0 +1,158 @@ + 'agent', + 'rdftype' => 'thing', + ]; + } + + public function getDefaultProperties() { + $properties = parent::getDefaultProperties() + [ + 'vocab' => 'agent', + 'rdftype' => 'thing', + ] + parent::defineDefaultProperties() + + $this->defineDefaultBaseProperties(); + + return $properties; + } + + + + public function prepare( + array &$element, + WebformSubmissionInterface $webform_submission = NULL + ) { + + // @TODO explore this method to act on submitted data v/s element behavior + } + + /** + * Set multiple element wrapper. + * + * @param array $element + * An element. + */ + protected function prepareMultipleWrapper(array &$element) { + + parent::prepareMultipleWrapper($element); + + // Finally! + // This is the last chance we have to affect the render array + // This is where the original element type is also + // swapped by webform_multiple + // breaking all our #process callbacks. + $vocab = 'agent'; + $rdftype = 'thing'; + $vocab = $this->getElementProperty($element, 'vocab'); + $vocab = $vocab ?: $this->getDefaultProperty($vocab); + if (isset($element['#element']['#webform_composite_elements']['label'])) { + $element['#element']['#webform_composite_elements']['label']["#autocomplete_route_parameters"] = + [ + 'auth_type' => 'europeana', + 'vocab' => $vocab, + 'rdftype' => $rdftype, + 'count' => 10 + ]; + } + // For some reason i can not understand, when multiples are using + // Tables, the #webform_composite_elements -> 'label' is not used... + if (isset($element["#multiple__header"]) && $element["#multiple__header"] == true) { + $element['#element']['label']["#autocomplete_route_parameters"] = + [ + 'auth_type' => 'europeana', + 'vocab' => $vocab, + 'rdftype' => $rdftype, + 'count' => 10 + ]; + } + } + + + /** + * {@inheritdoc} + */ + public function getPluginLabel() { + return $this->elementManager->isExcluded('webform_metadata_europeana') ? $this->t('Europeana Entity') : parent::getPluginLabel(); + } + + /** + * {@inheritdoc} + */ + protected function formatHtmlItemValue(array $element, WebformSubmissionInterface $webform_submission, array $options = []) { + return $this->formatTextItemValue($element, $webform_submission, $options); + } + + /** + * {@inheritdoc} + */ + protected function formatTextItemValue(array $element, WebformSubmissionInterface $webform_submission, array $options = []) { + $value = $this->getValue($element, $webform_submission, $options); + + $lines = []; + if (!empty($value['uri'])) { + $lines[] = $value['uri']; + } + + if (!empty($value['label'])) { + $lines[] = $value['label']; + } + return $lines; + } + + /** + * {@inheritdoc} + */ + public function form(array $form, FormStateInterface $form_state) { + $form = parent::form($form, $form_state); + $apikey = Settings::get('webform_strawberryfield.europeana_entity_apikey'); + if ($apikey) { + $description = $this->t('See Europeana Entity API. Good! We found your Europeana Entity API key.'); + } else { + $description = $this->t('See Europeana Entity API. Warning: This API requires an apikey. Please ask your Drupal admin to set it for you in settings.php'); + } + + $form['composite']['vocab'] = [ + '#type' => 'select', + '#options' => [ + 'agent' => 'Europeana Agents', + 'concept' => 'Europeana Concepts', + 'place' => 'Europeana Places', + ], + '#title' => $this->t("What Europeana Autocomplete Entity Type to use."), + '#description' => $description, + ]; + return $form; + } + +}