Skip to content

Commit

Permalink
Merge pull request #498 from City-of-Helsinki/UHF-10120
Browse files Browse the repository at this point in the history
UHF-10120: Fix search description + UHF-9289 fix backend error messages in front.
  • Loading branch information
sundflux authored Jun 13, 2024
2 parents d19e6db + ef5fbaa commit f77c820
Show file tree
Hide file tree
Showing 2 changed files with 159 additions and 18 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ jobs:

- name: Run PHPCS
run: |
vendor/bin/phpcs public/modules/custom/ --ignore="*.js,*.css" --extensions=php,module,install --standard=Drupal,DrupalPractice
vendor/bin/phpcs public/themes/custom/ --ignore="*.js,*.css" --extensions=php,theme --standard=Drupal,DrupalPractice
vendor/bin/phpcs public/modules/custom/
vendor/bin/phpcs public/themes/custom/
- name: Run phpstan
run: vendor/bin/phpstan analyze
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use GuzzleHttp\Client;
use GuzzleHttp\RequestOptions;
use Symfony\Component\DependencyInjection\ContainerInterface;
Expand All @@ -18,6 +19,8 @@
*/
final class HelfiHakuvahtiSubscribeController extends ControllerBase {

use StringTranslationTrait;

/**
* Constructor for the HelfiHakuvahtiSubscribeController class.
*
Expand All @@ -34,6 +37,108 @@ public function __construct(
protected EntityTypeManagerInterface $_entityTypeManager,
) {}

/**
* Retrieves taxonomy labels by field_external_id values in a given language.
*
* @param array $external_ids
* An array of external ID values to match.
* @param string $language
* The language code for the desired translation.
*
* @return array
* An array of taxonomy term labels in the specified language.
*/
private function getLabelsByExternalId(array $external_ids, $language) {
$labels = [];
$terms = $this->_entityTypeManager->getStorage('taxonomy_term')->loadByProperties(['field_external_id' => $external_ids]);
foreach ($terms as $term) {
$translated_term = $term->hasTranslation($language) ? $term->getTranslation($language) : $term;
$labels[] = $translated_term->label();
}
return $labels;
}

/**
* Retrieves taxonomy labels by their taxonomy term IDs in a given language.
*
* @param array $term_ids
* An array of taxonomy term IDs to load.
* @param string $language
* The language code for the desired translation.
*
* @return array
* An array of taxonomy term labels in the specified language.
*/
private function getLabelsByTermIds(array $term_ids, $language) {
$labels = [];
$terms = $this->_entityTypeManager->getStorage('taxonomy_term')->loadMultiple($term_ids);
foreach ($terms as $term) {
$translated_term = $term->hasTranslation($language) ? $term->getTranslation($language) : $term;
$labels[] = $translated_term->label();
}

return $labels;
}

/**
* Function to get translated string in a given language.
*
* phpcs:ignore is used to mute error about string literals as there
* is no other way to do this translation.
*
* @param string $string
* The string to be translated.
* @param string $language
* The language code for the desired translation.
*
* @return string
* The translated string.
*/
private function translateString($string, $language) {
$translatedString = $this->t($string, [], ['langcode' => $language]); // @phpcs:ignore
return (string) $translatedString;
}

/**
* Function to extract specific query parameters from a URL string.
*
* @param string $url
* The URL string to parse.
* @param string $parameter
* The query parameter to extract values for.
*
* @return array
* An array of values for the specified query parameter.
*/
private function extractQueryParameters($url, $parameter) {
$parsed_url = parse_url($url);
$query = $parsed_url['query'] ?? '';
$query_parameters = [];
$pairs = explode('&', $query);

foreach ($pairs as $pair) {
if (empty($pair)) {
continue;
}

// Split the key and value, using + [null, null] to ensure both are set.
[$key, $value] = explode('=', $pair, 2) + [NULL, NULL];
if ($key === NULL) {
continue;
}

$key = urldecode($key);
$value = urldecode($value);

// If the parameter is the one we're looking for, add it to the array.
if ($key === $parameter) {
$query_parameters[] = $value;
}
}

return $query_parameters;
}

/**
* Retrieves search description taxonomies from the provided object.
*
Expand All @@ -52,30 +157,67 @@ private function getSearchDescriptionTaxonomies($obj): string {

// Free text search.
$query = $elasticQueryObject->query->bool->must[1]->bool->should[1]->combined_fields->query ?? NULL;
// Task area.
$taxonomyIds = array_merge($taxonomyIds, $elasticQueryObject->query->bool->must[2]->terms->task_area_external_id ?? []);

// Ammattiala / Task area.
$externalTaxonomyIds = array_merge($taxonomyIds, $elasticQueryObject->query->bool->must[2]->terms->task_area_external_id ?? []);
if (!empty($externalTaxonomyIds)) {
$terms = $this->getLabelsByExternalId($externalTaxonomyIds, $obj->lang);
}

// Type of employment.
$taxonomyIds = array_merge($taxonomyIds, $elasticQueryObject->query->bool->must[3]->bool->should[1]->terms->employment_type_id ?? []);

if (!empty($taxonomyIds)) {
$language = $obj->lang;
$terms = array_map(function ($term) use ($language) {
if ($term->hasTranslation($language)) {
$translated_term = $term->getTranslation($language);
return $translated_term->label();
}
return $term->label();
}, $this->_entityTypeManager->getStorage('taxonomy_term')->loadMultiple($taxonomyIds));
$employmentTermLabels = $this->getLabelsByTermIds($taxonomyIds, $obj->lang);
}

// We need to send just *something* if nothing is selected in filters.
if (empty($terms) && empty($query)) {
$terms[] = '*';
// Job location:
$area_filters = $this->extractQueryParameters($obj->query, 'area_filter');
if (!empty($area_filters)) {
// Duplicated from react frondend for proper translation mapping.
$areasList = [
'eastern' => 'Eastern area',
'central' => 'Central area',
'southern' => 'Southern area',
'southeastern' => 'South-Eastern area',
'western' => 'Western area',
'northern' => 'Northern area',
'northeast' => 'North-Eastern area',
];

foreach ($area_filters as $area) {
$areaFiltersTranslated[] = $this->translateString($areasList[$area], $obj->lang);
}
}

// Build description string:
$description = '';

// Search term first.
array_unshift($terms, $query);

return implode(', ', array_filter($terms));
// All these can be printed out with , separator.
if (!empty($areaFiltersTranslated)) {
$allTerms = array_merge($terms, $areaFiltersTranslated);
}

if (!empty($allTerms)) {
$description .= implode(', ', array_filter($allTerms));
}

// Employment label should use / instead of comma.
if (!empty($employmentTermLabels)) {
if (!empty($description)) {
$description .= ', ';
}
$description .= implode(' / ', $employmentTermLabels);
}

// Backup description if no terms or keywords found, must return something.
if (empty($description)) {
'*';
}

return $description;
}

/**
Expand All @@ -88,7 +230,6 @@ public function post(): JsonResponse {
$request = $this->requestStack->getCurrentRequest();
$body = $request->getContent(FALSE);
$bodyObj = json_decode($body);
$bodyObj->lang = substr($bodyObj->query, 1, 2);
$bodyObj->search_description = $this->getSearchDescriptionTaxonomies($bodyObj);

$token = $request->headers->get('token');
Expand Down

0 comments on commit f77c820

Please sign in to comment.