Skip to content

Commit

Permalink
Merge pull request #8 from City-of-Helsinki/UHF-27
Browse files Browse the repository at this point in the history
UHF-27: Map integration
  • Loading branch information
tuutti authored Dec 10, 2020
2 parents 5d7b520 + c392124 commit bbc1e12
Show file tree
Hide file tree
Showing 4 changed files with 234 additions and 0 deletions.
1 change: 1 addition & 0 deletions config/install/migrate_plus.migration.tpr_unit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ source:
type: string
process:
id: id
service_map_embed: id
latitude: latitude
longitude: longitude
streetview_entrance_url/uri: streetview_entrance_url
Expand Down
6 changes: 6 additions & 0 deletions src/Entity/Unit.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
$fields = parent::baseFieldDefinitions($entity_type);

$fields['name'] = static::createStringField('Name');
$fields['service_map_embed'] = static::createStringField('Service map embed')
->setDisplayOptions('view', [
'label' => 'hidden',
'type' => 'service_map_embed',
'weight' => 0,
]);
$fields['latitude'] = static::createStringField('Latitude')
->setTranslatable(FALSE);
$fields['longitude'] = static::createStringField('Longitude')
Expand Down
125 changes: 125 additions & 0 deletions src/Plugin/Field/FieldFormatter/ServiceMapFormatter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
<?php

declare(strict_types = 1);

namespace Drupal\helfi_tpr\Plugin\Field\FieldFormatter;

use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FormatterBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\helfi_tpr\Entity\Unit;

/**
* Field formatter to render service maps.
*
* @FieldFormatter(
* id = "service_map_embed",
* label = @Translation("TPR - Service map embed"),
* field_types = {
* "string"
* }
* )
*/
final class ServiceMapFormatter extends FormatterBase {

/**
* The map base url.
*
* @var string
*/
protected const BASE_URL = 'https://palvelukartta.hel.fi';

/**
* {@inheritdoc}
*/
public static function defaultSettings() {
return [
'iframe_title' => 'Service map',
'link_title' => 'View larger map',
'target' => TRUE,
] + parent::defaultSettings();
}

/**
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state) {
$elements = parent::settingsForm($form, $form_state);

$elements['iframe_title'] = [
'#type' => 'textfield',
'#title' => $this->t('Iframe title'),
'#default_value' => $this->getSetting('iframe_title'),
];

$elements['link_title'] = [
'#type' => 'textfield',
'#title' => $this->t('Link title'),
'#default_value' => $this->getSetting('link_title'),
];

$elements['target'] = [
'#type' => 'checkbox',
'#title' => $this->t('Open link in new window'),
'#return_value' => '_blank',
'#default_value' => $this->getSetting('target'),
];

return $elements;
}

/**
* Generates the service map url for given entity.
*
* @param \Drupal\helfi_tpr\Entity\Unit $entity
* The tpr unit entity.
* @param string|null $type
* The url type (embed or null).
*
* @return string
* The url.
*/
protected function generateUrl(Unit $entity, ?string $type = NULL) : string {
$type = $type ? sprintf('%s/', $type) : NULL;
return sprintf('%s/%sunit/%s', static::BASE_URL, $type, $entity->id());
}

/**
* {@inheritdoc}
*/
public function viewElements(FieldItemListInterface $items, $langcode) {
$element = [];

$entity = $items->getEntity();

if (!$entity instanceof Unit) {
throw new \InvalidArgumentException('The "service_map_embed" field can only be used with tpr_unit entities.');
}
foreach ($items as $delta => $item) {
$element[$delta] = [
'iframe' => [
'#type' => 'html_tag',
'#tag' => 'iframe',
'#value' => '',
'#attributes' => [
'src' => $this->generateUrl($entity, 'embed'),
'frameborder' => 0,
'title' => $this->getSetting('iframe_title'),
],
],
'link' => [
'#type' => 'html_tag',
'#tag' => 'a',
'#value' => $this->getSetting('link_title'),
'#attributes' => [
'href' => $this->generateUrl($entity),
'target' => $this->getSetting('target'),
],
],
];
}

return $element;
}

}
102 changes: 102 additions & 0 deletions tests/src/Unit/ServiceMapFormatterTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<?php

declare(strict_types = 1);

namespace Drupal\Tests\helfi_tpr\Unit;

use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemList;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FieldTypePluginManagerInterface;
use Drupal\Core\TypedData\TraversableTypedDataInterface;
use Drupal\helfi_api_base\Entity\RemoteEntityBase;
use Drupal\helfi_tpr\Entity\Unit;
use Drupal\helfi_tpr\Plugin\Field\FieldFormatter\ServiceMapFormatter;
use Drupal\Tests\UnitTestCase;

/**
* Tests service map formatter field formatter.
*
* @coversDefaultClass \Drupal\helfi_tpr\Plugin\Field\FieldFormatter\ServiceMapFormatter
* @group helfi_tpr
*/
class ServiceMapFormatterTest extends UnitTestCase {

/**
* The service map formatter.
*
* @var \Drupal\helfi_tpr\Plugin\Field\FieldFormatter\ServiceMapFormatter
*/
protected ServiceMapFormatter $sut;

/**
* The field definition.
*
* @var \Drupal\Core\Field\FieldDefinitionInterface|\PHPUnit\Framework\MockObject\MockObject
*/
protected FieldDefinitionInterface $fieldDefinition;

/**
* {@inheritdoc}
*/
public function setUp() : void {
parent::setUp();

// Mock the field type manager and place it in the container.
$container = new ContainerBuilder();
$container->set('plugin.manager.field.field_type', $this->prophesize(FieldTypePluginManagerInterface::class)->reveal());
\Drupal::setContainer($container);

$this->fieldDefinition = $this->createMock(FieldDefinitionInterface::class);
$this->sut = new ServiceMapFormatter('service_map_embed', [], $this->fieldDefinition, [], 'hidden', 'full', []);
}

/**
* Tests with invalid entity type.
*/
public function testInvalidEntity() : void {
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('The "service_map_embed" field can only be used with tpr_unit entities.');
$list = $this->prophesize(FieldItemListInterface::class);
$list->getEntity()->willReturn($this->prophesize(RemoteEntityBase::class)->reveal());
$this->sut->viewElements($list->reveal(), 'en');
}

/**
* Tests render array.
*/
public function testRenderArray() : void {
$entity = $this->prophesize(Unit::class);
$entity->id()->willReturn('1');
$parent = $this->prophesize(TraversableTypedDataInterface::class);
$parent->onChange('service_map_embed')->shouldBeCalled();
$parent->getValue()->willReturn($entity->reveal());
$list = FieldItemList::createInstance($this->fieldDefinition, 'service_map_embed', $parent->reveal());
$list->setValue('test');

$result = $this->sut->viewElements($list, 'en');
$this->assertCount(1, $result);

$this->assertEquals([
'src' => 'https://palvelukartta.hel.fi/embed/unit/1',
'frameborder' => 0,
'title' => 'Service map',
], $result[0]['iframe']['#attributes']);

$this->assertArrayEquals([
'href' => 'https://palvelukartta.hel.fi/unit/1',
'target' => TRUE,
], $result[0]['link']['#attributes']);

$this->sut->setSetting('iframe_title', 'Iframe title changed');
$this->sut->setSetting('link_title', 'Link title changed');
$this->sut->setSetting('target', FALSE);
$result = $this->sut->viewElements($list, 'en');

$this->assertFalse($result[0]['link']['#attributes']['target']);
$this->assertEquals('Iframe title changed', $result[0]['iframe']['#attributes']['title']);
$this->assertEquals('Link title changed', $result[0]['link']['#value']);
}

}

0 comments on commit bbc1e12

Please sign in to comment.