forked from symfony/ux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Map] Enhance
ux_map()
+ Add <twig:ux:map/>
TwigComponent
* add an MapFactory (internal) * allow ux_map Twig function to render map from an array * add basic TwigComponent
- Loading branch information
Showing
14 changed files
with
692 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,7 @@ | |
use Symfony\UX\Map\Renderer\Renderer; | ||
use Symfony\UX\Map\Renderer\Renderers; | ||
use Symfony\UX\Map\Twig\MapExtension; | ||
use Symfony\UX\Map\Twig\MapRuntime; | ||
|
||
/* | ||
* @author Hugo Alliaume <[email protected]> | ||
|
@@ -26,7 +27,6 @@ | |
->args([ | ||
abstract_arg('renderers configuration'), | ||
]) | ||
->tag('twig.runtime') | ||
|
||
->set('ux_map.renderer_factory.abstract', AbstractRendererFactory::class) | ||
->abstract() | ||
|
@@ -41,5 +41,11 @@ | |
|
||
->set('ux_map.twig_extension', MapExtension::class) | ||
->tag('twig.extension') | ||
|
||
->set('ux_map.twig_runtime', MapRuntime::class) | ||
->args([ | ||
service('ux_map.renderers'), | ||
]) | ||
->tag('twig.runtime') | ||
; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Component\DependencyInjection\Loader\Configurator; | ||
|
||
use Symfony\UX\Map\Twig\UXMapComponent; | ||
use Symfony\UX\Map\Twig\UXMapComponentListener; | ||
use Symfony\UX\TwigComponent\Event\PreCreateForRenderEvent; | ||
|
||
return static function (ContainerConfigurator $container): void { | ||
$container->services() | ||
->set('.ux_map.twig_component_listener', UXMapComponentListener::class) | ||
->args([ | ||
service('ux_map.renderers'), | ||
]) | ||
->tag('kernel.event_listener', [ | ||
'event' => PreCreateForRenderEvent::class, | ||
'method' => 'onPreCreateForRender', | ||
]) | ||
|
||
->set('.ux_map.twig_component.map', UXMapComponent::class) | ||
->tag('twig.component', ['key' => 'UX:Map']) | ||
; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\UX\Map; | ||
|
||
/** | ||
* @author Simon André <[email protected]> | ||
* | ||
* @internal | ||
*/ | ||
final class MapFactory | ||
{ | ||
/** | ||
* @param array{ | ||
* center?: array{lat: float, lng: float}, | ||
* zoom?: float, | ||
* markers?: list<array{ | ||
* position: array{lat: float, lng: float}, | ||
* title?: string, | ||
* infoWindow?: array{ | ||
* content?: string, | ||
* headerContent?: string, | ||
* }, | ||
* }>, | ||
* } $array The array representation of the map | ||
*/ | ||
public static function fromArray(array $array): Map | ||
{ | ||
$map = new Map(); | ||
|
||
$map->fitBoundsToMarkers(); | ||
|
||
if (isset($array['center'])) { | ||
if (!\is_array($array['center'])) { | ||
throw new \InvalidArgumentException('The "center" parameter must be an array.'); | ||
} | ||
|
||
$map->center(self::createPoint($array['center'])); | ||
$map->fitBoundsToMarkers(false); | ||
unset($array['center']); | ||
} | ||
|
||
if (isset($array['zoom'])) { | ||
if (!is_numeric($array['zoom'])) { | ||
throw new \InvalidArgumentException('The "zoom" parameter must be numeric.'); | ||
} | ||
|
||
$map->zoom((float) $array['zoom']); | ||
$map->fitBoundsToMarkers(false); | ||
unset($array['zoom']); | ||
} | ||
|
||
if (isset($array['markers'])) { | ||
if (!\is_array($array['markers'])) { | ||
throw new \InvalidArgumentException('The "markers" parameter must be an array.'); | ||
} | ||
foreach ($array['markers'] as $marker) { | ||
if (!\is_array($marker)) { | ||
throw new \InvalidArgumentException('The "markers" parameter must be an array of arrays.'); | ||
} | ||
$marker = self::createMarker($marker); | ||
$map = $map->addMarker($marker); | ||
} | ||
unset($array['markers']); | ||
} | ||
|
||
if (\count($array) > 0) { | ||
throw new \InvalidArgumentException(\sprintf('Unknown map parameters: "%s"', implode(', ', array_keys($array)))); | ||
} | ||
|
||
return $map; | ||
} | ||
|
||
private static function createMarker(array $marker): Marker | ||
{ | ||
if (!\array_key_exists('position', $marker)) { | ||
throw new \InvalidArgumentException('The "position" parameter is required.'); | ||
} | ||
if (!\is_array($marker['position'])) { | ||
throw new \InvalidArgumentException(\sprintf('The "position" parameter must be an array, "%s" given.', get_debug_type($marker['position']))); | ||
} | ||
$point = self::createPoint($marker['position']); | ||
unset($marker['position']); | ||
|
||
$infoWindow = null; | ||
if (\array_key_exists('infoWindow', $marker)) { | ||
if (!\is_array($marker['infoWindow'])) { | ||
throw new \InvalidArgumentException(\sprintf('The "infoWindow" parameter must be an array, "%s" given.', get_debug_type($marker['infoWindow']))); | ||
} | ||
|
||
$infoWindow = self::createInfoWindow($marker['infoWindow']); | ||
unset($marker['infoWindow']); | ||
} | ||
|
||
$title = null; | ||
if (\array_key_exists('title', $marker)) { | ||
if (!\is_string($marker['title'])) { | ||
throw new \InvalidArgumentException(\sprintf('The "title" parameter must be a string, "%s" given.', get_debug_type($marker['title']))); | ||
} | ||
$title = $marker['title']; | ||
unset($marker['title']); | ||
} | ||
|
||
$extra = []; | ||
if (\array_key_exists('extra', $marker)) { | ||
if (!\is_array($marker['extra'])) { | ||
throw new \InvalidArgumentException(\sprintf('The "extra" parameter must be an array, "%s" given.', get_debug_type($marker['extra']))); | ||
} | ||
$extra = $marker['extra']; | ||
unset($marker['extra']); | ||
} | ||
|
||
if (\count($marker) > 0) { | ||
throw new \InvalidArgumentException(\sprintf('Unknown marker parameters: "%s".', implode('", "', array_keys($marker)))); | ||
} | ||
|
||
return new Marker($point, $title, $infoWindow, $extra); | ||
} | ||
|
||
/** | ||
* @param array{content?: string, headerContent?: string} $infoWindow | ||
*/ | ||
private static function createInfoWindow(array $infoWindow): InfoWindow | ||
{ | ||
$headerContent = null; | ||
if (\array_key_exists('headerContent', $infoWindow)) { | ||
if (!\is_string($infoWindow['headerContent'])) { | ||
throw new \InvalidArgumentException(\sprintf('The "header" parameter must be a string, "%s" given.', get_debug_type($infoWindow['headerContent']))); | ||
} | ||
|
||
$headerContent = $infoWindow['headerContent']; | ||
unset($infoWindow['headerContent']); | ||
} | ||
|
||
$content = null; | ||
if (\array_key_exists('content', $infoWindow)) { | ||
if (!\is_string($infoWindow['content'])) { | ||
throw new \InvalidArgumentException(\sprintf('The "content" parameter must be a string, "%s" given.', get_debug_type($infoWindow['content']))); | ||
} | ||
|
||
$content = $infoWindow['content']; | ||
unset($infoWindow['content']); | ||
} | ||
|
||
if (\count($infoWindow) > 0) { | ||
throw new \InvalidArgumentException(\sprintf('Unknown "infoWindow" parameters: "%s".', implode('", "', array_keys($infoWindow)))); | ||
} | ||
|
||
if (!$headerContent && !$content) { | ||
throw new \InvalidArgumentException('The "infoWindow" parameter must have at least one of "header" or "content" values.'); | ||
} | ||
|
||
return new InfoWindow($headerContent, $content); | ||
} | ||
|
||
/** | ||
* @param array{lat?: float, lng?: float} $point | ||
*/ | ||
private static function createPoint(array $point): Point | ||
{ | ||
if (!isset($point['lat']) || !isset($point['lng'])) { | ||
throw new \InvalidArgumentException('The Point parameter must be an array with "lat" and "lng" keys.'); | ||
} | ||
if (!is_numeric($point['lat']) || !is_numeric($point['lng'])) { | ||
throw new \InvalidArgumentException('The "lat" and "lng" values must be numeric.'); | ||
} | ||
|
||
$lat = (float) $point['lat']; | ||
$lng = (float) $point['lng']; | ||
unset($point['lat'], $point['lng']); | ||
|
||
if (\count($point) > 2) { | ||
throw new \InvalidArgumentException(\sprintf('Unknown Point parameters: "%s".', implode('", "', array_keys($point)))); | ||
} | ||
|
||
return new Point($lat, $lng); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\UX\Map\Twig; | ||
|
||
use Symfony\UX\Map\Map; | ||
use Symfony\UX\Map\MapFactory; | ||
use Symfony\UX\Map\Renderer\RendererInterface; | ||
use Twig\Extension\RuntimeExtensionInterface; | ||
|
||
/** | ||
* @author Simon André <[email protected]> | ||
* | ||
* @internal | ||
*/ | ||
final class MapRuntime implements RuntimeExtensionInterface | ||
{ | ||
public function __construct( | ||
private readonly RendererInterface $renderer, | ||
) { | ||
} | ||
|
||
/** | ||
* @param Map|array<string, mixed> $map | ||
* @param array<string, mixed> $attributes | ||
*/ | ||
public function renderMap(Map|array $map, array $attributes = []): string | ||
{ | ||
if (\is_array($map)) { | ||
if (isset($map['attr'])) { | ||
if (!\is_array($map['attr'])) { | ||
throw new \InvalidArgumentException(\sprintf('The "attr" parameter must be an array, "%s" given.', get_debug_type($map['attr']))); | ||
} | ||
$attributes = [...$map['attr'], ...$attributes]; | ||
unset($map['attr']); | ||
} | ||
$map = MapFactory::fromArray($map); | ||
} | ||
|
||
return $this->renderer->renderMap($map, $attributes); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\UX\Map\Twig; | ||
|
||
use Symfony\UX\Map\Marker; | ||
use Symfony\UX\Map\Point; | ||
|
||
/** | ||
* @author Simon André <[email protected]> | ||
* | ||
* @internal | ||
*/ | ||
final class UXMapComponent | ||
{ | ||
public ?float $zoom; | ||
|
||
public ?Point $center; | ||
|
||
/** | ||
* @var Marker[] | ||
*/ | ||
public array $markers; | ||
} |
Oops, something went wrong.