Skip to content
Open
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
5 changes: 5 additions & 0 deletions config/install/helfi_hakuvahti.settings.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
langcode: en
hakuvahti_tos_checkbox_label: 'I consent to the processing of my personal data'
hakuvahti_tos_link_text: 'Read our privacy policy (pdf).'
hakuvahti_tos_link_url: ''
hakuvahti_instructions_link_url: ''
18 changes: 18 additions & 0 deletions config/schema/helfi_hakuvahti.schema.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,21 @@ helfi_hakuvahti.settings:
type: string
base_url:
type: string

hakuvahti_tos_checkbox_label:
type: label
label: 'Hakuvahti terms of service checkbox label'
translatable: true
hakuvahti_tos_link_text:
type: label
label: 'Hakuvahti terms of service link text'
translatable: true
hakuvahti_tos_link_url:
type: label
label: 'Hakuvahti terms of service URL'
translatable: true
hakuvahti_instructions_link_url:
type: label
label: 'Hakuvahti detailed instructions link URL'
translatable: true

5 changes: 5 additions & 0 deletions helfi_hakuvahti.config_translation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
helfi_hakuvahti.settings:
title: 'Hakuvahti settings'
base_route_name: helfi_hakuvahti.settings
names:
- helfi_hakuvahti.settings
23 changes: 23 additions & 0 deletions helfi_hakuvahti.install
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

/**
* @file
* Helfi_hakuvahti.
*
* Helfi_hakuvahti.module.
*/

declare(strict_types=1);

/**
* UHF-12723: Move configuration from rekry to hakuvahti module.
*/
function helfi_hakuvahti_update_11001(): void {
\Drupal::configFactory()->getEditable('helfi_hakuvahti.settings')
->set('hakuvahti_tos_checkbox_label', 'I consent to the processing of my personal data')
->set('hakuvahti_tos_link_text', 'Read our privacy policy (pdf).')
->set('hakuvahti_tos_link_url', '')
->set('hakuvahti_instructions_link_url', '')
->set('langcode', 'en')
->save();
}
5 changes: 5 additions & 0 deletions helfi_hakuvahti.links.menu.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
helfi_hakuvahti.settings:
title: 'Hakuvahti settings'
route_name: helfi_hakuvahti.settings
parent: hdbt_admin_tools.site_information
weight: 90
4 changes: 4 additions & 0 deletions helfi_hakuvahti.links.task.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
helfi_hakuvahti.settings:
route_name: helfi_hakuvahti.settings
title: 'Hakuvahti settings'
base_route: helfi_hakuvahti.settings
10 changes: 10 additions & 0 deletions helfi_hakuvahti.routing.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
helfi_hakuvahti.settings:
path: '/admin/tools/hakuvahti'
defaults:
_form: '\Drupal\helfi_hakuvahti\Form\SettingsForm'
_title: 'Hakuvahti settings'
requirements:
_permission: 'administer site configuration'
options:
_admin_route: TRUE

helfi_hakuvahti.subscribe:
path: '/hakuvahti/subscribe'
defaults:
Expand Down
2 changes: 2 additions & 0 deletions helfi_hakuvahti.services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ services:

Drupal\helfi_hakuvahti\HakuvahtiInterface:
class: Drupal\helfi_hakuvahti\Hakuvahti

Drupal\helfi_hakuvahti\DrupalSettings: ~
8 changes: 7 additions & 1 deletion src/Controller/HakuvahtiSubscribeController.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,13 @@ public function post(Request $request): JsonResponse {
}

// Use site_id from configuration entity.
$requestData['site_id'] = $config->getSiteId();
$requestData['siteId'] = $config->getSiteId();

// The frontend gets api url from the DrupalSettings service. The
// service sets language prefixed subscribe urls, so the frontend
// does not need to keep track of the current language, we know it
// from the request context.
$requestData['lang'] = $this->languageManager()->getCurrentLanguage()->getId();

$requestObject = new HakuvahtiRequest($requestData);
}
Expand Down
75 changes: 75 additions & 0 deletions src/DrupalSettings.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

namespace Drupal\helfi_hakuvahti;

use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Url;

/**
* Get Hakuvahti settings for frontend.
*/
readonly class DrupalSettings {

/**
* Settings that are exposed to JavaScript.
*/
public const array EXPOSED_SETTINGS = [
'hakuvahti_tos_checkbox_label',
'hakuvahti_tos_link_text',
'hakuvahti_tos_link_url',
'hakuvahti_instructions_link_url',
];

public function __construct(
private ConfigFactoryInterface $configFactory,
private LanguageManagerInterface $languageManager,
) {
}

/**
* Get settings as they should be exposed to JavaScript.
*/
public function applyTo(array &$build): void {
$langcode = $this->languageManager
->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)
->getId();

// Attempt to get the translated configuration.
// @todo Why is this needed?
$language = $this->languageManager->getLanguage($langcode);
$originalLanguage = $this->languageManager->getConfigOverrideLanguage();
$this->languageManager->setConfigOverrideLanguage($language);

try {
$cache = new CacheableMetadata();

$settings = $this->configFactory->get('helfi_hakuvahti.settings');

// Do not expose settings if base_url is not configured.
if (empty($settings->get('base_url'))) {
return;
}

$drupalSettings = [];
foreach (self::EXPOSED_SETTINGS as $exposed_setting) {
$drupalSettings['texts'][$exposed_setting] = $settings->get($exposed_setting) ?: NULL;
}

$drupalSettings['apiUrl'] = Url::fromRoute('helfi_hakuvahti.subscribe')->toString();

$build['#attached']['drupalSettings']['hakuvahti'] = $drupalSettings;

$cache->addCacheableDependency($settings);
$cache->addCacheContexts(['languages:language_content']);
$cache->applyTo($build);
}
finally {
// Set the config back to the original language.
$this->languageManager->setConfigOverrideLanguage($originalLanguage);
}
}

}
24 changes: 9 additions & 15 deletions src/Entity/HakuvahtiConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,19 @@
namespace Drupal\helfi_hakuvahti\Entity;

use Drupal\Core\Config\Entity\ConfigEntityBase;
use Drupal\Core\Entity\Attribute\ConfigEntityType;
use Drupal\Core\StringTranslation\TranslatableMarkup;

/**
* Defines the Hakuvahti configuration entity.
*
* @ConfigEntityType(
* id = "hakuvahti_config",
* label = @Translation("Hakuvahti Configuration"),
* config_prefix = "config",
* entity_keys = {
* "id" = "id",
* "label" = "label"
* },
* config_export = {
* "id",
* "label",
* "site_id"
* }
* )
*/
#[ConfigEntityType(
id: 'hakuvahti_config',
label: new TranslatableMarkup('Hakuvahti Configuration'),
config_prefix: 'config',
entity_keys: ['id' => 'id', 'label' => 'label'],
config_export: ['id', 'label', 'site_id'],
)]
class HakuvahtiConfig extends ConfigEntityBase {

/**
Expand Down
62 changes: 62 additions & 0 deletions src/Form/SettingsForm.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

declare(strict_types=1);

namespace Drupal\helfi_hakuvahti\Form;

use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;

/**
* Hakuvahti settings form.
*/
class SettingsForm extends ConfigFormBase {

/**
* {@inheritdoc}
*/
public function getFormId() : string {
return 'helfi_hakuvahti.settings_form';
}

/**
* {@inheritdoc}
*/
protected function getEditableConfigNames() : array {
return ['helfi_hakuvahti.settings'];
}

/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state): array {
$form['settings']['hakuvahti_tos_checkbox_label'] = [
'#type' => 'textfield',
'#config_target' => 'helfi_hakuvahti.settings:hakuvahti_tos_checkbox_label',
'#title' => $this->t('Hakuvahti terms of service checkbox label'),
'#description' => $this->t('Label for the terms of service checkbox.'),
];

$form['settings']['hakuvahti_tos_link_text'] = [
'#type' => 'textfield',
'#config_target' => 'helfi_hakuvahti.settings:hakuvahti_tos_link_text',
'#title' => $this->t('Hakuvahti terms of service link text'),
];

$form['settings']['hakuvahti_tos_link_url'] = [
'#type' => 'textfield',
'#title' => $this->t('Hakuvahti terms of service URL'),
'#config_target' => 'helfi_hakuvahti.settings:hakuvahti_tos_link_url',
'#description' => $this->t('URL for the webpage or pdf to the Hakuvahti terms of service.'),
];

$form['settings']['hakuvahti_instructions_link_url'] = [
'#type' => 'textfield',
'#title' => $this->t('More detailed instructions on how to use saved searches'),
'#config_target' => 'helfi_hakuvahti.settings:hakuvahti_instructions_link_url',
];

return parent::buildForm($form, $form_state);
}

}
55 changes: 37 additions & 18 deletions src/HakuvahtiRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,24 @@
*/
final readonly class HakuvahtiRequest {

private const MAX_SEARCH_DESCRIPTION_LENGTH = 999;
private const int MAX_SEARCH_DESCRIPTION_LENGTH = 999;
private const array REQUIRED_FIELDS = [
'lang',
'siteId',
'query',
'elasticQuery',
'searchDescription',
];

/**
* The email address.
*/
public string $email;
public ?string $email;

/**
* User phone number.
*/
public ?string $sms;

/**
* Language id.
Expand All @@ -29,7 +41,7 @@
public string $siteId;

/**
* The request parameters from the request uli.
* The request parameters from the request uri.
*/
public string $query;

Expand All @@ -40,6 +52,13 @@
*/
public string $elasticQuery;

/**
* If true, the elastic query is stored in ATV.
*
* Use this if the query can contain user data.
*/
public bool $elasticQueryAtv;

/**
* The search description.
*
Expand All @@ -50,43 +69,43 @@
public string $searchDescription;

public function __construct(array $requestData) {
$requiredFields = ['email', 'lang', 'site_id', 'query', 'elastic_query', 'search_description'];

foreach ($requiredFields as $fieldName) {
foreach (self::REQUIRED_FIELDS as $fieldName) {
if (!isset($requestData[$fieldName])) {
throw new \InvalidArgumentException("Request is missing field: $fieldName");
}
}

if (!filter_var($requestData['email'], FILTER_VALIDATE_EMAIL)) {
$this->lang = $requestData['lang'];
$this->siteId = $requestData['siteId'];
$this->query = $requestData['query'];
$this->elasticQuery = $requestData['elasticQuery'];
$this->elasticQueryAtv = $requestData['elasticQueryAtv'] ?? FALSE;
$this->searchDescription = $requestData['searchDescription'];
$this->email = $requestData['email'] ?? NULL;
$this->sms = $requestData['sms'] ?? NULL;

// User chooses which notification type they get. Either field can be NULL.
if ($this->email && !filter_var($this->email, FILTER_VALIDATE_EMAIL)) {
throw new \InvalidArgumentException("Email must be a valid email address");
}

if (strlen($requestData['search_description']) > self::MAX_SEARCH_DESCRIPTION_LENGTH) {
if (strlen($this->searchDescription) > self::MAX_SEARCH_DESCRIPTION_LENGTH) {
throw new \InvalidArgumentException("Search description is too long.");
}

$this->email = $requestData['email'];
$this->lang = $requestData['lang'];
$this->siteId = $requestData['site_id'];
$this->query = $requestData['query'];
$this->elasticQuery = $requestData['elastic_query'];
$this->searchDescription = $requestData['search_description'];
}

/**
* Return the data to be sent for hakuvahti services subscription endpoint.
*
* @return array
* The data for hakuvahti subscription request.
*/
public function getServiceRequestData(): array {
return [
'email' => $this->email,
'sms' => $this->sms,
'lang' => $this->lang,
'site_id' => $this->siteId,
'query' => $this->query,
'elastic_query' => $this->elasticQuery,
'elastic_query_atv' => $this->elasticQueryAtv,
'search_description' => $this->searchDescription,
];
}
Expand Down
Loading