Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ISSUE-127 and ISSUE-128: adds snac + better draft session management when editing/cloning #129

Merged
merged 6 commits into from
Aug 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@
src/Tools/Iiif/IiifHelper.php
.idea/webform_strawberryfield.iml
src/.DS_Store
.idea/runConfigurations/archipelago.xml
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
],
"require": {
"php": ">=7.2",
"ext-json": "*",
"ml/json-ld": "^1.2",
"mtdowling/jmespath.php":"^2.5",
"strawberryfield/strawberryfield":"dev-1.0.0-RC3",
Expand Down
221 changes: 208 additions & 13 deletions src/Controller/AuthAutocompleteController.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\ServerException;
use GuzzleHttp\RequestOptions;
use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Url;
use Drupal\Component\Datetime\TimeInterface;
Expand Down Expand Up @@ -163,6 +164,9 @@ public function handleAutocomplete(Request $request, $auth_type, $vocab = 'subje
if (is_string($csrf_token)) {
$request_base = $request->getSchemeAndHttpHost().':'.$request->getPort();
$is_internal = $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['SERVER_ADDR'].':'.$_SERVER['SERVER_PORT'] == $request_base;
if (!$is_internal) {
$is_internal = $_SERVER['HTTP_HOST'] == $_SERVER['SERVER_NAME'];
}
}

if ($input) {
Expand All @@ -173,10 +177,9 @@ public function handleAutocomplete(Request $request, $auth_type, $vocab = 'subje
$cache_id = 'webform_strawberry:auth_lod:' . $cache_var;
$cached = $this->cacheGet($cache_id);
if ($cached) {
error_log('cached');
return new JsonResponse($cached->data);
}
if ($this->currentUser->isAnonymous() && !$is_internal) {
if ($this->currentUser->isAnonymous() && !$is_internal) {
sleep(1);
}

Expand All @@ -197,9 +200,15 @@ public function handleAutocomplete(Request $request, $auth_type, $vocab = 'subje
case 'viaf':
$results = $this->viaf($input);
break;
case 'mesh':
$results = $this->mesh($input, $vocab, $rdftype);
break;
case 'snac':
$results = $this->snac($input, $vocab, $rdftype);
break;
case 'europeana':
if ($apikey) {
$results = $this->europeana($input, $vocab, $apikey);
$results = $this->europeana($input, $vocab, $apikey);
}
else {
$this->messenger()->addError(
Expand Down Expand Up @@ -273,7 +282,7 @@ protected function loc($input, $vocab, $rdftype) {
];
$path = $endpoint[$vocab];

$input = urlencode($input);
$input = rawurlencode($input);

if ($vocab == 'rdftype') {
$urlindex = "/suggest/?q=" . $input . "&rdftype=" . $rdftype;
Expand Down Expand Up @@ -327,7 +336,7 @@ protected function loc($input, $vocab, $rdftype) {
* @return array
*/
protected function wikidata($input) {
$input = urlencode($input);
$input = rawurlencode($input);
$urlindex = '&language=en&format=json&search=' . $input;
$baseurl = 'https://www.wikidata.org/w/api.php?action=wbsearchentities';
$remoteUrl = $baseurl . $urlindex;
Expand Down Expand Up @@ -602,7 +611,7 @@ protected function getty($input, $vocab = 'aat', $mode = 'fuzzy') {
* @return array
*/
protected function viaf($input) {
$input = urlencode($input);
$input = rawurlencode($input);
$urlindex = '&query=' . $input;
$baseurl = 'https://viaf.org/viaf/AutoSuggest?';
$remoteUrl = $baseurl . $urlindex;
Expand All @@ -612,12 +621,12 @@ protected function viaf($input) {

$jsondata = [];
$results = [];
$jsondata = json_decode($body, TRUE);
$jsondata = json_decode($body, TRUE) ?? [];
$json_error = json_last_error();
if ($json_error == JSON_ERROR_NONE) {
//WIKIdata will give is an success key will always return at least one, the query string
if (count($jsondata) > 1) {
if (count($jsondata['result']) >= 1) {
if (isset($jsondata['result']) && is_array($jsondata['result']) && count($jsondata['result']) >= 1) {
foreach ($jsondata['result'] as $key => $item) {
$desc = (isset($item['nametype'])) ? '(' . $item['nametype'] . ')' : NULL;
$results[] = [
Expand Down Expand Up @@ -681,7 +690,7 @@ protected function europeana($input, $vocab, string $apikey) {
return $results;
}

$input = urlencode($input);
$input = rawurlencode($input);

$urlindex = "/suggest?text=" . $input . "&type=" . $vocab ."&wskey=". $apikey ;

Expand Down Expand Up @@ -729,7 +738,7 @@ protected function europeana($input, $vocab, string $apikey) {
}

if (($vocab == 'agent') && isset($result['dateOfBirth'])) {
$desc[] = $result['dateOfBirth'] . '/' . $result['dateOfDeath'] ?? '?';
$desc[] = $result['dateOfBirth'] . '/' . $result['dateOfDeath'] ?? '?';
}

$desc = !empty($desc) ? ' (' . implode(', ', $desc) . ')' : NULL;
Expand Down Expand Up @@ -761,14 +770,189 @@ protected function europeana($input, $vocab, string $apikey) {
return [];
}

/**
* @param $input
* The query
* @param $vocab
* The 'suggest' enabled endpoint at LoC
*
* @return array
*/
protected function snac($input, $vocab, $rdftype) {
//@TODO make the following allowed list a constant since we use it in
// \Drupal\webform_strawberryfield\Plugin\WebformElement\WebformLoC
if (!in_array($vocab, [
'Constellation',
'rdftype',
])) {
// Drop before tryin to hit non existing vocab
$this->messenger()->addError(
$this->t('@vocab for SNAC autocomplete is not in in our allowed list.',
[
'@vocab' => $vocab,
]
)
);
$results[] = [
'value' => NULL,
'label' => "Wrong Vocabulary {$vocab} in SNAC Query",
];
return $results;
}


$input = urlencode($input);


$remoteUrl = "https://api.snaccooperative.org";
$options = [
'body' => json_encode([
"command" => "search",
"term" => $input,
"entity_type" => $rdftype != "thing" ? $rdftype : NULL,
"start" => 0,
"count" => 10,
"search_type" => "autocomplete",
]),
RequestOptions::HEADERS => [
'Content-Type' => 'application/json'
]
];
$body = $this->getRemoteJsonData($remoteUrl, $options, 'PUT');

$jsondata = [];
$results = [];
$jsondata = json_decode($body, TRUE);
$json_error = json_last_error();
if ($json_error == JSON_ERROR_NONE) {
if (!empty($jsondata['results']) && ($jsondata['total'] ?? 0) >= 1) {
foreach ($jsondata['results'] as $key => $entry) {
$nameEntry = reset($entry['nameEntries']);
$results[] = [
'value' => $entry['ark'] ?? $entry['entityType']['uri'],
'label' => $nameEntry['original'],
];
}
}
else {
$results[] = [
'value' => NULL,
'label' => "Sorry no match from SNAC {$vocab}",
];
}
return $results;
}
$this->messenger()->addError(
$this->t('Looks like data fetched from @url is not in JSON format.<br> JSON says: @jsonerror <br>Please check your URL!',
[
'@url' => $remoteUrl,
'@jsonerror' => $json_error,
]
)
);
return [];
}



/**
* @param $input
* The query
* @param $vocab
* The 'suggest' enabled endpoint at LoC
*
* @return array
*/
protected function mesh($input, $vocab, $rdftype) {

//@TODO make the following allowed list a constant since we use it in
// \Drupal\webform_strawberryfield\Plugin\WebformElement\WebformMesh
if (!in_array($vocab, [
'descriptor',
'term',
])) {
// Drop before tryin to hit non existing vocab
$this->messenger()->addError(
$this->t('@vocab for MeSH autocomplete is not in in our allowed list.',
[
'@vocab' => $vocab,
]
)
);
$results[] = [
'value' => NULL,
'label' => "Wrong Vocabulary {$vocab} in MeSH API Query",
];
return $results;
}

// Here $rdftype acts as match
if (!in_array($rdftype, [
'startswith',
'contains',
'exact',
])) {
// Drop before tryin to hit non existing vocab
$this->messenger()->addError(
$this->t('@rdftype Match type for MeSH autocomplete is not valid. It may be "exact","startswith" or "contains"',
[
'@rdftype' => $rdftype,
]
)
);
$results[] = [
'value' => NULL,
'label' => "Wrong Match type for {$vocab} in MeSH API Query",
];
return $results;
}

$input = rawurlencode($input);
$urlindex = "/mesh/lookup/{$vocab}?label=" . $input .'&limit=10&match=' . $rdftype;
$baseurl = 'https://id.nlm.nih.gov';
$remoteUrl = $baseurl . $urlindex;
$options['headers'] = ['Accept' => 'application/json'];
$body = $this->getRemoteJsonData($remoteUrl, $options);

$results = [];
$jsondata = json_decode($body, TRUE);
$json_error = json_last_error();
if ($json_error == JSON_ERROR_NONE) {
if (count($jsondata) > 1) {
foreach ($jsondata as $entry) {
$results[] = [
'value' => $entry['resource'],
'label' => $entry['label'],
];
}
}
else {
$results[] = [
'value' => NULL,
'label' => "Sorry no match from MeSH for {$vocab}",
];
}
return $results;
}
$this->messenger()->addError(
$this->t('Looks like data fetched from @url is not in JSON format.<br> JSON says: @jsonerror <br>Please check your URL!',
[
'@url' => $remoteUrl,
'@jsonerror' => $json_error,
]
)
);
return [];
}

/**
* @param $remoteUrl
* @param $options
*
* @return string
* A string that may be JSON (hopefully)
*/
protected function getRemoteJsonData($remoteUrl, $options) {
protected function getRemoteJsonData($remoteUrl, $options, $method = 'GET') {
// 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.
Expand All @@ -783,7 +967,18 @@ protected function getRemoteJsonData($remoteUrl, $options) {
return NULL;
}
try {
$request = $this->httpClient->get($remoteUrl, $options);
if ($method == 'GET') {
$request = $this->httpClient->get($remoteUrl, $options);
}
elseif ($method == 'POST') {
$request = $this->httpClient->post($remoteUrl, $options);
}
elseif ($method == 'PUT') {
$request = $this->httpClient->put($remoteUrl, $options);
}
else {
return NULL;
}
// Do not cache if things go bad.
if ($request->getStatusCode() == '401') {
$this->setNotAllowed(TRUE);
Expand Down Expand Up @@ -816,7 +1011,7 @@ protected function getRemoteJsonData($remoteUrl, $options) {
catch (ServerException $exception) {
$this->useCaches = FALSE;
$responseMessage = $exception->getMessage();
$this->loggerFactory->get('webform_strawberryfield')
$this->getLogger('webform_strawberryfield')
->error('We tried to contact @url but we could not. <br> The Remote server says: @response. <br> Check your query',
[
'@url' => $remoteUrl,
Expand Down
7 changes: 4 additions & 3 deletions src/Controller/StrawberryRunnerModalController.php
Original file line number Diff line number Diff line change
Expand Up @@ -138,17 +138,18 @@ public function openModalForm(WebformInterface $webform = NULL, Request $request
// In case we are editing an existing entity, this one gets the
// Strawberryfield value
$alldata = $source_entity->get($field_name)->getValue();
$fielddata['value'] = !empty($alldata) ? $alldata[$delta]['value']: "{}";
$fielddata['value'] = $alldata[$delta]['value'] ?? "{}";
$entityid = $source_entity->id();
}

$stored_value = (isset($fielddata['value']) && !empty($fielddata['value'])) ? $fielddata['value'] : "{}";
$stored_value = $fielddata['value'] ?? "{}";

$data_defaults = [
'strawberry_field_widget_state_id' => $widgetid,
// Can't remember why, but seems useful to pass around
'strawberry_field_widget_source_entity_uuid' => $source_uuid,
'strawberry_field_widget_source_entity_id' => $entityid,
'strawberry_field_widget_autosave' => $entityid ? FALSE : TRUE,
'strawberry_field_stored_values' => json_decode($stored_value,true)
];

Expand Down Expand Up @@ -247,7 +248,7 @@ public function openModalForm(WebformInterface $webform = NULL, Request $request
// We delete both, the session and the accumulated errors.
/** @var \Drupal\Core\TempStore\PrivateTempStore $tempstore */
$tempstore = \Drupal::service('tempstore.private')->get('archipel');
$tempstore->delete($clear_saved);
$tempstore->delete($clear_saved.'-draft');
$tempstore->delete($clear_saved.'-errors');
// Selector us built using the field name and the delta.
$response->addCommand(new \Drupal\Core\Ajax\HtmlCommand('#' . $selector .' > .fieldset-wrapper',
Expand Down
Loading