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;
+ }
+
+}