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

UHF-10774: news location #843

Merged
merged 4 commits into from
Nov 14, 2024
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
13 changes: 13 additions & 0 deletions config/schema/helfi_platform_config.schema.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,16 @@ block.settings.telia_ace_widget:
chat_title:
type: text
label: 'Chat button label'


# Default value.
field.value.location:
type: mapping
label: Default value
mapping:
latitude:
type: float
label: Latitude
longitude:
type: float
label: longitude
4 changes: 4 additions & 0 deletions helfi_platform_config.services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ services:
class: Drupal\helfi_platform_config\EventSubscriber\RouteSubscriber
arguments: ['@current_route_match']

Drupal\helfi_platform_config\EventSubscriber\SearchApiSubscriber:
class: Drupal\helfi_platform_config\EventSubscriber\SearchApiSubscriber
arguments: []

Drupal\helfi_platform_config\EntityVersionMatcher: '@helfi_platform_config.entity_version_matcher'
helfi_platform_config.entity_version_matcher:
class: Drupal\helfi_platform_config\EntityVersionMatcher
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
uuid: 77736144-e2d4-4f43-9bf4-d6a5700454e9
langcode: en
status: true
dependencies:
config:
- field.storage.taxonomy_term.field_location
- taxonomy.vocabulary.news_neighbourhoods
module:
- helfi_platform_config
id: taxonomy_term.news_neighbourhoods.field_location
field_name: field_location
entity_type: taxonomy_term
bundle: news_neighbourhoods
label: Location
description: 'Neighbourhood location. Used to search nearby content.'
required: true
translatable: false
default_value: { }
default_value_callback: ''
settings: { }
field_type: location
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
uuid: 44d5b217-5ef0-4178-8a1a-6190babb12e2
langcode: en
status: true
dependencies:
module:
- helfi_platform_config
- taxonomy
id: taxonomy_term.field_location
field_name: field_location
entity_type: taxonomy_term
type: location
settings: { }
module: helfi_platform_config
locked: false
cardinality: 1
translatable: true
indexes: { }
persist_with_no_fields: false
custom_storage: false
1 change: 1 addition & 0 deletions modules/helfi_node_news_item/helfi_node_news_item.info.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ dependencies:
- field_group:field_group
- drupal:menu_ui
- drupal:taxonomy
- helfi_platform_config:helfi_platform_config
- helfi_base_content:helfi_base_content
- helfi_image_styles:helfi_image_styles
- helfi_media:helfi_media
Expand Down
8 changes: 8 additions & 0 deletions modules/helfi_node_news_item/helfi_node_news_item.install
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,11 @@ function helfi_node_news_item_update_9003(): void {
\Drupal::service('helfi_platform_config.config_update_helper')
->update('helfi_node_news_item');
}

/**
* Add field.field.taxonomy_term.news_neighbourhoods.field_location.
*/
function helfi_node_news_item_update_9004(): void {
\Drupal::service('helfi_platform_config.config_update_helper')
->update('helfi_node_news_item');
}
38 changes: 38 additions & 0 deletions src/EventSubscriber/SearchApiSubscriber.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

declare(strict_types=1);

namespace Drupal\helfi_platform_config\EventSubscriber;

use Drupal\search_api\Event\MappingFieldTypesEvent;
use Drupal\search_api\Event\SearchApiEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
* Search api event subscriber.
*/
final class SearchApiSubscriber implements EventSubscriberInterface {

/**
* {@inheritdoc}
*/
public static function getSubscribedEvents(): array {
// Bail if search_api is not installed.
if (!class_exists(SearchApiEvents::class)) {
return [];
}

return [
SearchApiEvents::MAPPING_FIELD_TYPES => 'mapFieldTypes',
];
}

/**
* Map custom field types.
*/
public function mapFieldTypes(MappingFieldTypesEvent $event): void {
$mapping = &$event->getFieldTypeMapping();
$mapping['location'] = 'location';
}

}
40 changes: 40 additions & 0 deletions src/Plugin/DataType/Location.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

declare(strict_types=1);

namespace Drupal\helfi_platform_config\Plugin\DataType;

use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\TypedData\Attribute\DataType;
use Drupal\Core\TypedData\TypedData;

/**
* Location data type.
*
* This converts LocationItem FieldType to a format that elasticsearch
* understands. For more details, see:
* https://www.elastic.co/guide/en/elasticsearch/reference/current/geo-point.html.
*/
#[DataType(
id: 'computed_location',
label: new TranslatableMarkup('Location'),
)]
class Location extends TypedData {

/**
* {@inheritdoc}
*/
public function getValue() {
$item = $this->getParent();

if (isset($item->latitude, $item->longitude)) {
return (object) [
'lat' => (float) $item->latitude,
'lon' => (float) $item->longitude,
];
}

return NULL;
}

}
67 changes: 67 additions & 0 deletions src/Plugin/Field/FieldType/LocationItem.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

declare(strict_types=1);

namespace Drupal\helfi_platform_config\Plugin\Field\FieldType;

use Drupal\Core\Field\Attribute\FieldType;
use Drupal\Core\Field\FieldItemBase;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\TypedData\DataDefinition;

/**
* Defines the 'location' field type.
*/
#[FieldType(
id: "location",
label: new TranslatableMarkup("Location"),
description: new TranslatableMarkup("WGS84 coordinates."),
default_widget: "location",
)]
final class LocationItem extends FieldItemBase {

/**
* {@inheritdoc}
*/
public function isEmpty(): bool {
return empty($this->get('latitude')->getValue()) || empty($this->get('longitude')->getValue());
}

/**
* {@inheritdoc}
*/
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition): array {
$properties['latitude'] = DataDefinition::create('float')
->setLabel(new TranslatableMarkup('Latitude'));

$properties['longitude'] = DataDefinition::create('float')
->setLabel(new TranslatableMarkup('Longitude'));

$properties['value'] = DataDefinition::create('computed_location')
->setLabel(new TranslatableMarkup('Coordinates'))
->setComputed(TRUE)
->setReadOnly(TRUE);

return $properties;
}

/**
* {@inheritdoc}
*/
public static function schema(FieldStorageDefinitionInterface $field_definition): array {
return [
'columns' => [
'latitude' => [
'type' => 'float',
'size' => 'normal',
],
'longitude' => [
'type' => 'float',
'size' => 'normal',
],
],
];
}

}
71 changes: 71 additions & 0 deletions src/Plugin/Field/FieldWidget/LocationWidget.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

declare(strict_types=1);

namespace Drupal\helfi_platform_config\Plugin\Field\FieldWidget;

use Drupal\Core\Field\Attribute\FieldWidget;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Symfony\Component\Validator\ConstraintViolationInterface;

/**
* Defines the 'location' field widget.
*/
#[FieldWidget(
id: "location",
label: new TranslatableMarkup('Location'),
field_types: ['location']
)]
final class LocationWidget extends WidgetBase {

/**
* {@inheritdoc}
*/
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state): array {
$element['latitude'] = [
'#type' => 'number',
'#default_value' => $items[$delta]->latitude ?? NULL,
'#step' => 'any',
];

$element['longitude'] = [
'#type' => 'number',
'#default_value' => $items[$delta]->longitude ?? NULL,
'#step' => 'any',
];

$element['#theme_wrappers'] = ['container', 'form_element'];
$element['#attributes']['class'][] = 'location-elements';

return $element;
}

/**
* {@inheritdoc}
*/
public function errorElement(array $element, ConstraintViolationInterface $error, array $form, FormStateInterface $form_state): array|bool {
$element = parent::errorElement($element, $error, $form, $form_state);
if ($element === FALSE) {
return FALSE;
}
$error_property = explode('.', $error->getPropertyPath())[1];
return $element[$error_property];
}

/**
* {@inheritdoc}
*/
public function massageFormValues(array $values, array $form, FormStateInterface $form_state): array {
foreach ($values as $delta => $value) {
if ($value['latitude'] === '' || $value['longitude'] === '') {
$values[$delta]['latitude'] = NULL;
$values[$delta]['longitude'] = NULL;
}
}
return $values;
}

}
2 changes: 2 additions & 0 deletions src/Plugin/search_api/data_type/LocationDataType.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

declare(strict_types=1);

namespace Drupal\helfi_platform_config\Plugin\search_api\data_type;

use Drupal\search_api\DataType\DataTypePluginBase;
Expand Down