From c392124ef312952ad489c488fb9fd9ad352b87e0 Mon Sep 17 00:00:00 2001 From: tuutti Date: Thu, 10 Dec 2020 14:01:36 +0200 Subject: [PATCH] UHF-27: Map integration --- .../migrate_plus.migration.tpr_unit.yml | 1 + src/Entity/Unit.php | 6 + .../FieldFormatter/ServiceMapFormatter.php | 125 ++++++++++++++++++ tests/src/Unit/ServiceMapFormatterTest.php | 102 ++++++++++++++ 4 files changed, 234 insertions(+) create mode 100644 src/Plugin/Field/FieldFormatter/ServiceMapFormatter.php create mode 100644 tests/src/Unit/ServiceMapFormatterTest.php diff --git a/config/install/migrate_plus.migration.tpr_unit.yml b/config/install/migrate_plus.migration.tpr_unit.yml index 1e6aaaa4..387b2d94 100644 --- a/config/install/migrate_plus.migration.tpr_unit.yml +++ b/config/install/migrate_plus.migration.tpr_unit.yml @@ -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 diff --git a/src/Entity/Unit.php b/src/Entity/Unit.php index d2d97ba3..aaa02466 100644 --- a/src/Entity/Unit.php +++ b/src/Entity/Unit.php @@ -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') diff --git a/src/Plugin/Field/FieldFormatter/ServiceMapFormatter.php b/src/Plugin/Field/FieldFormatter/ServiceMapFormatter.php new file mode 100644 index 00000000..f4f2cd4d --- /dev/null +++ b/src/Plugin/Field/FieldFormatter/ServiceMapFormatter.php @@ -0,0 +1,125 @@ + '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; + } + +} diff --git a/tests/src/Unit/ServiceMapFormatterTest.php b/tests/src/Unit/ServiceMapFormatterTest.php new file mode 100644 index 00000000..da8a595d --- /dev/null +++ b/tests/src/Unit/ServiceMapFormatterTest.php @@ -0,0 +1,102 @@ +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']); + } + +}