├── Classes
├── Backend
│ └── Preview
│ │ └── Maps2PluginPreview.php
├── Client
│ ├── AbstractClient.php
│ ├── ClientFactory.php
│ ├── ClientInterface.php
│ ├── GoogleMapsClient.php
│ ├── OpenStreetMapClient.php
│ └── Request
│ │ ├── AbstractRequest.php
│ │ ├── GoogleMaps
│ │ └── GeocodeRequest.php
│ │ ├── OpenStreetMap
│ │ └── GeocodeRequest.php
│ │ ├── RequestFactory.php
│ │ └── RequestInterface.php
├── Configuration
│ └── ExtConf.php
├── Controller
│ ├── CityMapController.php
│ ├── PoiCollectionController.php
│ └── Traits
│ │ ├── InjectExtConfTrait.php
│ │ ├── InjectGeoCodeServiceTrait.php
│ │ ├── InjectLinkHelperTrait.php
│ │ ├── InjectPoiCollectionRepositoryTrait.php
│ │ └── InjectSettingsHelperTrait.php
├── Domain
│ ├── Model
│ │ ├── Category.php
│ │ ├── PoiCollection.php
│ │ ├── Position.php
│ │ └── Search.php
│ ├── Repository
│ │ └── PoiCollectionRepository.php
│ └── Traits
│ │ ├── GetExtConfTrait.php
│ │ ├── GetMapHelperTrait.php
│ │ └── GetWebPathOfFileReferenceTrait.php
├── Event
│ ├── AllowCreationOfPoiCollectionEvent.php
│ ├── ControllerActionEventInterface.php
│ ├── ModifyQueryOfFindPoiCollectionsEvent.php
│ ├── PostProcessFluidVariablesEvent.php
│ ├── PostProcessPoiCollectionRecordEvent.php
│ ├── PreAddForeignRecordEvent.php
│ └── RenderInfoWindowContentEvent.php
├── EventListener
│ └── PreventPageCacheForMiddlewareEventListener.php
├── ExpressionLanguage
│ ├── AllowMapProviderRequestConditionProvider.php
│ └── AllowMapProviderRequestFunctionsProvider.php
├── Form
│ ├── Element
│ │ ├── GoogleMapsElement.php
│ │ ├── OpenStreetMapElement.php
│ │ └── ReadOnlyInputTextElement.php
│ ├── FieldInformation
│ │ └── InfoWindowContent.php
│ └── Resolver
│ │ └── MapProviderResolver.php
├── Helper
│ ├── AddressHelper.php
│ ├── LinkHelper.php
│ ├── MapHelper.php
│ ├── MessageHelper.php
│ ├── OverlayHelper.php
│ ├── SettingsHelper.php
│ └── StoragePidHelper.php
├── Hook
│ └── CreateMaps2RecordHook.php
├── Mapper
│ ├── GoogleMapsMapper.php
│ ├── MapperFactory.php
│ ├── MapperInterface.php
│ └── OpenStreetMapMapper.php
├── Middleware
│ ├── GetInfoWindowContentMiddleware.php
│ └── InitFeSessionMiddleware.php
├── Service
│ ├── CacheService.php
│ ├── GeoCodeService.php
│ ├── InfoWindowContentService.php
│ ├── MapProviderRequestService.php
│ ├── MapService.php
│ └── PoiCollectionService.php
├── Tca
│ ├── Maps2Registry.php
│ └── Type
│ │ └── FloatType.php
├── Traits
│ └── GetTypo3RequestTrait.php
├── Update
│ ├── MigratePluginToContentElementUpdate.php
│ ├── MigratePoiRecordsToConfigurationMapUpdate.php
│ ├── MoveOldFlexFormSettingsUpdate.php
│ └── NewGeocodeUriForOsmUpdate.php
├── Utility
│ └── DatabaseUtility.php
└── ViewHelpers
│ ├── Cache
│ ├── GetCacheViewHelper.php
│ ├── HasCacheViewHelper.php
│ └── SetCacheViewHelper.php
│ ├── ConvertToJsonViewHelper.php
│ ├── Form
│ ├── HiddenViewHelper.php
│ └── RenderHiddenFieldsForGetViewHelper.php
│ ├── GetEnvironmentViewHelper.php
│ ├── IsRequestToMapProviderAllowedViewHelper.php
│ ├── RequestUriForOverlayViewHelper.php
│ └── TrimExplodeViewHelper.php
├── Configuration
├── ContentSecurityPolicies.php
├── ExpressionLanguage.php
├── Extbase
│ └── Persistence
│ │ └── Classes.php
├── FlexForms
│ ├── CityMap.xml
│ ├── Maps2.xml
│ └── Radius.xml
├── Icons.php
├── JavaScriptModules.php
├── RequestMiddlewares.php
├── Services.yaml
├── Sets
│ ├── GoogleMaps
│ │ ├── config.yaml
│ │ ├── settings.definitions.yaml
│ │ └── setup.typoscript
│ ├── Maps2
│ │ ├── config.yaml
│ │ ├── settings.definitions.yaml
│ │ └── setup.typoscript
│ └── OpenStreetMap
│ │ ├── config.yaml
│ │ ├── settings.definitions.yaml
│ │ └── setup.typoscript
└── TCA
│ ├── Overrides
│ ├── sys_category.php
│ ├── sys_template.php
│ ├── tt_content.php
│ └── tx_maps2_domain_model_poicollection.php
│ └── tx_maps2_domain_model_poicollection.php
├── Documentation
├── AdministratorManual
│ ├── GoogleApiKeys
│ │ └── Index.rst
│ ├── Index.rst
│ ├── Routing
│ │ └── Index.rst
│ ├── Templates
│ │ ├── Index.rst
│ │ ├── Start
│ │ │ └── Index.rst
│ │ └── ViewHelpers
│ │ │ ├── Cache
│ │ │ ├── GetCacheViewHelper.rst
│ │ │ ├── HasCacheViewHelper.rst
│ │ │ └── SetCacheViewHelper.rst
│ │ │ ├── ConvertToJsonViewHelper.rst
│ │ │ ├── Index.rst
│ │ │ ├── IsRequestToMapProviderAllowedViewHelper.rst
│ │ │ ├── RequestUriForOverlayViewHelper.rst
│ │ │ └── TrimExplodeViewHelper.rst
│ └── Upgrade
│ │ └── Index.rst
├── ChangeLog
│ └── Index.rst
├── Configuration
│ ├── Extension
│ │ └── Index.rst
│ ├── Index.rst
│ ├── Plugins
│ │ └── Index.rst
│ └── TypoScript
│ │ └── Index.rst
├── DeveloperManual
│ ├── Api
│ │ └── Index.rst
│ ├── Index.rst
│ ├── Maps2Registry
│ │ └── Index.rst
│ └── Template
│ │ └── Index.rst
├── FAQ
│ └── Index.rst
├── Images
│ ├── AdministratorManual
│ │ └── maps2-include-TypoScript.png
│ ├── GoogleApiKeys
│ │ ├── WizardActivatedApis.png
│ │ ├── WizardPickProduct.png
│ │ └── WizardSelectProject.png
│ ├── Introduction
│ │ ├── maps2-type-Area.png
│ │ ├── maps2-type-Point.png
│ │ ├── maps2-type-Radius.png
│ │ └── maps2-type-Route.png
│ ├── Typo3.png
│ └── UserManual
│ │ └── BackendView.png
├── Includes.rst.txt
├── Index.rst
├── Installation
│ └── Index.rst
├── Introduction
│ └── Index.rst
├── User
│ ├── HowToStart
│ │ └── Index.rst
│ ├── Index.rst
│ └── Maps2Record
│ │ └── Index.rst
└── guides.xml
├── LICENSE.txt
├── README.md
├── Resources
├── Private
│ ├── .htaccess
│ ├── Language
│ │ ├── ExtConf.xlf
│ │ ├── FlexForms.xlf
│ │ ├── locallang.xlf
│ │ └── locallang_db.xlf
│ ├── Layouts
│ │ └── Default.html
│ ├── Partials
│ │ ├── InfoWindowContent.html
│ │ ├── LoadAssets.html
│ │ └── Maps2
│ │ │ ├── EditPoiCollection.html
│ │ │ ├── Overlay.html
│ │ │ └── PoiCollection.html
│ └── Templates
│ │ ├── CityMap
│ │ ├── Search.html
│ │ └── Show.html
│ │ ├── InfoWindowContent.html
│ │ ├── InfoWindowContentNoCache.html
│ │ ├── PluginPreview
│ │ └── Maps2.html
│ │ ├── PoiCollection
│ │ ├── ListRadius.html
│ │ ├── Overlay.html
│ │ ├── Search.html
│ │ └── Show.html
│ │ └── Tca
│ │ ├── GoogleMaps.html
│ │ └── OpenStreetMap.html
└── Public
│ ├── Css
│ ├── GoogleMapsModule.css
│ └── Leaflet
│ │ ├── Leaflet.css
│ │ └── images
│ │ ├── layers-2x.png
│ │ ├── layers.png
│ │ ├── marker-icon-2x.png
│ │ ├── marker-icon.png
│ │ └── marker-shadow.png
│ ├── Icons
│ ├── Extension.svg
│ ├── MarkerClusterer
│ │ ├── m1.png
│ │ ├── m2.png
│ │ ├── m3.png
│ │ ├── m4.png
│ │ └── m5.png
│ ├── RecordTypeArea.png
│ ├── RecordTypePoint.png
│ ├── RecordTypeRadius.png
│ ├── RecordTypeRoute.png
│ ├── TypeSelectArea.png
│ ├── TypeSelectPoint.png
│ ├── TypeSelectRadius.png
│ ├── TypeSelectRoute.png
│ ├── marker.png
│ ├── marker.svg
│ ├── plugin_wizard.svg
│ ├── relation.gif
│ └── tx_maps2_domain_model_poi.png
│ └── JavaScript
│ ├── Classes.js
│ ├── Classes.js.map
│ ├── GoogleMaps2.min.js
│ ├── GoogleMaps2.min.js.map
│ ├── GoogleMapsModule.min.js
│ ├── GoogleMapsModule.min.js.map
│ ├── MarkerClusterer.js
│ ├── OpenStreetMap2.min.js
│ ├── OpenStreetMap2.min.js.map
│ ├── OpenStreetMapModule.min.js
│ ├── OpenStreetMapModule.min.js.map
│ ├── leaflet.min.js
│ └── leaflet.min.js.map
├── composer.json
├── ext_conf_template.txt
├── ext_emconf.php
├── ext_localconf.php
└── ext_tables.sql
/Classes/Backend/Preview/Maps2PluginPreview.php:
--------------------------------------------------------------------------------
1 | getRecord();
46 | if (!$this->isValidPlugin($ttContentRecord)) {
47 | return '';
48 | }
49 |
50 | $view = $this->viewFactory->create(new ViewFactoryData(
51 | templatePathAndFilename: self::PREVIEW_TEMPLATE,
52 | ));
53 | $view->assignMultiple($ttContentRecord);
54 |
55 | $this->addPluginName($view, $ttContentRecord);
56 |
57 | // Add data from column pi_flexform
58 | $piFlexformData = $this->getPiFlexformData($ttContentRecord);
59 | if ($piFlexformData !== []) {
60 | $view->assign('pi_flexform_transformed', $piFlexformData);
61 | }
62 |
63 | if ($ttContentRecord['CType'] === 'maps2_maps2') {
64 | $this->addPoiCollection($view, $piFlexformData);
65 | }
66 |
67 | return $view->render();
68 | }
69 |
70 | protected function isValidPlugin(array $ttContentRecord): bool
71 | {
72 | if (!isset($ttContentRecord['CType'])) {
73 | return false;
74 | }
75 |
76 | return in_array($ttContentRecord['CType'], self::ALLOWED_PLUGINS, true);
77 | }
78 |
79 | protected function addPluginName(ViewInterface $view, array $ttContentRecord): void
80 | {
81 | $langKey = sprintf(
82 | 'plugin.%s.title',
83 | str_replace('maps2_', '', $ttContentRecord['CType']),
84 | );
85 |
86 | $view->assign(
87 | 'pluginName',
88 | LocalizationUtility::translate('LLL:EXT:maps2/Resources/Private/Language/locallang_db.xlf:' . $langKey),
89 | );
90 | }
91 |
92 | protected function getPiFlexformData(array $ttContentRecord): array
93 | {
94 | $data = [];
95 | if (!empty($ttContentRecord['pi_flexform'] ?? '')) {
96 | $data = $this->flexFormService->convertFlexFormContentToArray($ttContentRecord['pi_flexform']);
97 | }
98 |
99 | return $data;
100 | }
101 |
102 | protected function addPoiCollection(ViewInterface $view, array $piFlexformData): void
103 | {
104 | if (
105 | isset($piFlexformData['settings']['poiCollection'])
106 | && $piFlexformData['settings']['poiCollection'] !== '0'
107 | && MathUtility::canBeInterpretedAsInteger($piFlexformData['settings']['poiCollection'])
108 | ) {
109 | $poiCollectionRecord = $this->poiCollectionService->findByUid(
110 | (int)$piFlexformData['settings']['poiCollection'],
111 | $GLOBALS['TYPO3_REQUEST'] ?? null,
112 | );
113 | if ($poiCollectionRecord !== null) {
114 | $view->assign('poiCollectionRecord', $poiCollectionRecord);
115 | }
116 | }
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/Classes/Client/AbstractClient.php:
--------------------------------------------------------------------------------
1 | isValidRequest()) {
33 | $this->messageHelper->addFlashMessage(
34 | 'URI is empty or contains invalid chars. URI: ' . $request->getUri(),
35 | 'Invalid request URI',
36 | ContextualFeedbackSeverity::ERROR,
37 | );
38 | return [];
39 | }
40 |
41 | $processedResponse = [];
42 | $response = $this->requestFactory->request($request->getUri());
43 | if ($response->getStatusCode() === 200) {
44 | $processedResponse = \json_decode((string)$response->getBody(), true, 512, JSON_THROW_ON_ERROR);
45 | $this->checkResponseForErrors($processedResponse);
46 | } else {
47 | $this->messageHelper->addFlashMessage(
48 | 'MapProvider returns a response with a status code different than 200',
49 | 'Client Error',
50 | ContextualFeedbackSeverity::ERROR,
51 | );
52 | }
53 |
54 | if ($this->hasErrors()) {
55 | $processedResponse = [];
56 | }
57 |
58 | return $processedResponse;
59 | }
60 |
61 | public function hasErrors(): bool
62 | {
63 | return $this->messageHelper->hasErrorMessages();
64 | }
65 |
66 | /**
67 | * @return AbstractMessage[]
68 | */
69 | public function getErrors(): array
70 | {
71 | return $this->messageHelper->getErrorMessages();
72 | }
73 |
74 | abstract protected function checkResponseForErrors(?array $processedResponse): void;
75 | }
76 |
--------------------------------------------------------------------------------
/Classes/Client/ClientFactory.php:
--------------------------------------------------------------------------------
1 | GoogleMapsClient::class,
27 | 'osm' => OpenStreetMapClient::class,
28 | ];
29 |
30 | public function __construct(protected MapHelper $mapHelper) {}
31 |
32 | public function create(): ClientInterface
33 | {
34 | /** @var ClientInterface $client */
35 | $client = GeneralUtility::makeInstance(
36 | $this->mapping[$this->mapHelper->getMapProvider()],
37 | );
38 |
39 | return $client;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Classes/Client/ClientInterface.php:
--------------------------------------------------------------------------------
1 | messageHelper->addFlashMessage(
28 | 'The response of Google Maps was not a valid JSON response.',
29 | 'Invalid JSON response',
30 | ContextualFeedbackSeverity::ERROR,
31 | );
32 | } elseif ($processedResponse['status'] !== 'OK') {
33 | if ($processedResponse['status'] === 'ZERO_RESULTS') {
34 | $this->messageHelper->addFlashMessage(
35 | LocalizationUtility::translate(
36 | 'error.noPositionsFound.body',
37 | 'maps2',
38 | [
39 | 0 => $this->title,
40 | ],
41 | ),
42 | LocalizationUtility::translate(
43 | 'error.noPositionsFound.title',
44 | 'maps2',
45 | ),
46 | ContextualFeedbackSeverity::ERROR,
47 | );
48 | } else {
49 | $this->messageHelper->addFlashMessage(
50 | $processedResponse['error_message'],
51 | 'Error',
52 | ContextualFeedbackSeverity::ERROR,
53 | );
54 | }
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/Classes/Client/OpenStreetMapClient.php:
--------------------------------------------------------------------------------
1 | messageHelper->addFlashMessage(
28 | 'The response of Open Street Map was not a valid JSON response.',
29 | 'Invalid JSON response',
30 | ContextualFeedbackSeverity::ERROR,
31 | );
32 | } elseif ($processedResponse === []) {
33 | $this->messageHelper->addFlashMessage(
34 | LocalizationUtility::translate(
35 | 'error.noPositionsFound.body',
36 | 'maps2',
37 | [
38 | 0 => $this->title,
39 | ],
40 | ),
41 | LocalizationUtility::translate(
42 | 'error.noPositionsFound.title',
43 | 'maps2',
44 | ),
45 | ContextualFeedbackSeverity::ERROR,
46 | );
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/Classes/Client/Request/AbstractRequest.php:
--------------------------------------------------------------------------------
1 | uri;
31 | }
32 |
33 | public function setUri(string $uri): void
34 | {
35 | $this->uri = trim($uri);
36 | }
37 |
38 | public function getParameters(): array
39 | {
40 | return $this->parameters;
41 | }
42 |
43 | public function setParameters(array $parameters): void
44 | {
45 | $this->parameters = $parameters;
46 | }
47 |
48 | /**
49 | * @param mixed $value
50 | */
51 | public function addParameter(string $parameter, $value): void
52 | {
53 | $this->parameters[$parameter] = $value;
54 | }
55 |
56 | /**
57 | * @return mixed
58 | */
59 | public function getParameter(string $parameter)
60 | {
61 | return $this->parameters[$parameter] ?? null;
62 | }
63 |
64 | public function hasParameter(string $parameter): bool
65 | {
66 | return array_key_exists($parameter, $this->parameters);
67 | }
68 |
69 | /**
70 | * Prepare address for an uri
71 | * Further it will add some additional information like country
72 | */
73 | protected function updateAddressForUri(string $address): string
74 | {
75 | // if address can be interpreted as zip, attach the default country to prevent a worldwide search
76 | if (
77 | MathUtility::canBeInterpretedAsInteger($address)
78 | && $this->extConf->getDefaultCountry() !== ''
79 | ) {
80 | $address .= ' ' . $this->extConf->getDefaultCountry();
81 | }
82 |
83 | return rawurlencode($address);
84 | }
85 |
86 | public function isValidRequest(): bool
87 | {
88 | if ($this->getUri() === '') {
89 | return false;
90 | }
91 |
92 | return (bool)filter_var($this->getUri(), FILTER_VALIDATE_URL);
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/Classes/Client/Request/GoogleMaps/GeocodeRequest.php:
--------------------------------------------------------------------------------
1 | uri = $this->extConf->getGoogleMapsGeocodeUri();
29 | }
30 |
31 | /**
32 | * Get URI for Geocode
33 | *
34 | * @throws \Exception
35 | */
36 | public function getUri(): string
37 | {
38 | if ($this->uri === '') {
39 | return '';
40 | }
41 |
42 | if (!$this->hasParameter('address')) {
43 | return $this->uri;
44 | }
45 |
46 | return sprintf(
47 | $this->uri,
48 | $this->updateAddressForUri(
49 | (string)$this->getParameter('address'),
50 | ),
51 | $this->extConf->getGoogleMapsGeocodeApiKey(),
52 | );
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/Classes/Client/Request/OpenStreetMap/GeocodeRequest.php:
--------------------------------------------------------------------------------
1 | uri = $this->extConf->getOpenStreetMapGeocodeUri();
29 | }
30 |
31 | /**
32 | * Get URI for Geocode
33 | *
34 | * @throws \Exception
35 | */
36 | public function getUri(): string
37 | {
38 | if ($this->uri === '') {
39 | return '';
40 | }
41 |
42 | if (!$this->hasParameter('address')) {
43 | return $this->uri;
44 | }
45 |
46 | return sprintf(
47 | $this->uri,
48 | $this->updateAddressForUri(
49 | (string)$this->getParameter('address'),
50 | ),
51 | );
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/Classes/Client/Request/RequestFactory.php:
--------------------------------------------------------------------------------
1 | 'JWeiland\\Maps2\\Client\\Request\\GoogleMaps',
25 | 'osm' => 'JWeiland\\Maps2\\Client\\Request\\OpenStreetMap',
26 | ];
27 |
28 | public function __construct(protected MapHelper $mapHelper) {}
29 |
30 | /**
31 | * Create a new Request by its filename
32 | *
33 | * @throws \Exception
34 | */
35 | public function create(string $filename): RequestInterface
36 | {
37 | $className = sprintf(
38 | '%s\\%s',
39 | $this->mapping[$this->mapHelper->getMapProvider()],
40 | $this->sanitizeFilename($filename),
41 | );
42 |
43 | if (!class_exists($className)) {
44 | throw new \RuntimeException(
45 | sprintf('Class "%s" to create a new Request could not be found', $className),
46 | 1733471535,
47 | );
48 | }
49 |
50 | /** @var RequestInterface $request */
51 | $request = GeneralUtility::makeInstance($className);
52 |
53 | return $request;
54 | }
55 |
56 | protected function sanitizeFilename(string $filename): string
57 | {
58 | return ucfirst(GeneralUtility::split_fileref($filename)['filebody']);
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/Classes/Client/Request/RequestInterface.php:
--------------------------------------------------------------------------------
1 | geoCodeService = $geoCodeService;
36 | }
37 |
38 | public function initializeObject(): void
39 | {
40 | $this->settings = $this->settingsHelper->getMergedSettings();
41 | }
42 |
43 | protected function initializeView($view): void
44 | {
45 | $contentRecord = $this->request->getAttribute('currentContentObject')->data;
46 |
47 | // Remove unneeded columns from tt_content array
48 | unset(
49 | $contentRecord['pi_flexform'],
50 | $contentRecord['l18n_diffsource'],
51 | );
52 |
53 | $view->assign('data', $contentRecord);
54 | $view->assign('environment', [
55 | 'settings' => $this->settingsHelper->getPreparedSettings($this->settings),
56 | 'extConf' => ObjectAccess::getGettableProperties($this->extConf),
57 | 'id' => $this->getPageArguments()->getPageId(),
58 | 'contentRecord' => $contentRecord,
59 | ]);
60 | }
61 |
62 | public function showAction(): ResponseInterface
63 | {
64 | return $this->htmlResponse();
65 | }
66 |
67 | public function searchAction(string $street): ResponseInterface
68 | {
69 | $position = $this->geoCodeService->getFirstFoundPositionByAddress(
70 | strip_tags($street) . ' ' . $this->settings['autoAppend'],
71 | );
72 |
73 | if ($position instanceof Position) {
74 | $this->view->assign('latitude', $position->getLatitude());
75 | $this->view->assign('longitude', $position->getLongitude());
76 | $this->view->assign('address', rawurldecode($street));
77 | }
78 |
79 | return $this->htmlResponse();
80 | }
81 |
82 | protected function getPageArguments(): PageArguments
83 | {
84 | return $this->request->getAttribute('routing');
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/Classes/Controller/Traits/InjectExtConfTrait.php:
--------------------------------------------------------------------------------
1 | extConf = $extConf;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Classes/Controller/Traits/InjectGeoCodeServiceTrait.php:
--------------------------------------------------------------------------------
1 | geoCodeService = $geoCodeService;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Classes/Controller/Traits/InjectLinkHelperTrait.php:
--------------------------------------------------------------------------------
1 | linkHelper = $linkHelper;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Classes/Controller/Traits/InjectPoiCollectionRepositoryTrait.php:
--------------------------------------------------------------------------------
1 | poiCollectionRepository = $poiCollectionRepository;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Classes/Controller/Traits/InjectSettingsHelperTrait.php:
--------------------------------------------------------------------------------
1 | settingsHelper = $settingsHelper;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Classes/Domain/Model/Position.php:
--------------------------------------------------------------------------------
1 | formattedAddress;
29 | }
30 |
31 | public function setFormattedAddress(string $formattedAddress): void
32 | {
33 | $this->formattedAddress = $formattedAddress;
34 | }
35 |
36 | public function getLatitude(): float
37 | {
38 | return $this->latitude;
39 | }
40 |
41 | public function setLatitude(float $latitude): void
42 | {
43 | $this->latitude = $latitude;
44 | }
45 |
46 | public function getLongitude(): float
47 | {
48 | return $this->longitude;
49 | }
50 |
51 | public function setLongitude(float $longitude): void
52 | {
53 | $this->longitude = $longitude;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/Classes/Domain/Model/Search.php:
--------------------------------------------------------------------------------
1 | address;
27 | }
28 |
29 | public function setAddress(string $address): void
30 | {
31 | $this->address = $address;
32 | }
33 |
34 | public function getRadius(): int
35 | {
36 | return $this->radius;
37 | }
38 |
39 | public function setRadius(int $radius): void
40 | {
41 | $this->radius = $radius;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Classes/Domain/Traits/GetExtConfTrait.php:
--------------------------------------------------------------------------------
1 | getOriginalResource();
28 | }
29 |
30 | if ($coreFileReference instanceof CoreFileReference && $coreFileReference->getPublicUrl() !== null) {
31 | return GeneralUtility::locationHeaderUrl($coreFileReference->getPublicUrl());
32 | }
33 |
34 | return '';
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Classes/Event/AllowCreationOfPoiCollectionEvent.php:
--------------------------------------------------------------------------------
1 | foreignLocationRecord;
30 | }
31 |
32 | public function getForeignTableName(): string
33 | {
34 | return $this->foreignTableName;
35 | }
36 |
37 | public function getForeignColumnName(): string
38 | {
39 | return $this->foreignColumnName;
40 | }
41 |
42 | public function getOptions(): array
43 | {
44 | return $this->options;
45 | }
46 |
47 | public function isValid(): bool
48 | {
49 | return $this->isValid;
50 | }
51 |
52 | public function setIsValid(bool $isValid): void
53 | {
54 | $this->isValid = $isValid;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/Classes/Event/ControllerActionEventInterface.php:
--------------------------------------------------------------------------------
1 | queryBuilder;
31 | }
32 |
33 | public function getSettings(): array
34 | {
35 | return $this->settings;
36 | }
37 |
38 | public function getPoiCollectionUid(): int
39 | {
40 | return $this->poiCollectionUid;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Classes/Event/PostProcessFluidVariablesEvent.php:
--------------------------------------------------------------------------------
1 | request;
31 | }
32 |
33 | public function getControllerName(): string
34 | {
35 | return $this->request->getControllerName();
36 | }
37 |
38 | public function getActionName(): string
39 | {
40 | return $this->request->getControllerActionName();
41 | }
42 |
43 | public function getSettings(): array
44 | {
45 | return $this->settings;
46 | }
47 |
48 | public function getFluidVariables(): array
49 | {
50 | return $this->fluidVariables;
51 | }
52 |
53 | public function addFluidVariable(string $key, $value): void
54 | {
55 | $this->fluidVariables[$key] = $value;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/Classes/Event/PostProcessPoiCollectionRecordEvent.php:
--------------------------------------------------------------------------------
1 | poiCollectionTableName;
30 | }
31 |
32 | public function getPoiCollectionUid(): int
33 | {
34 | return $this->poiCollectionUid;
35 | }
36 |
37 | public function getForeignTableName(): string
38 | {
39 | return $this->foreignTableName;
40 | }
41 |
42 | public function getForeignLocationRecord(): array
43 | {
44 | return $this->foreignLocationRecord;
45 | }
46 |
47 | public function getOptions(): array
48 | {
49 | return $this->options;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Classes/Event/PreAddForeignRecordEvent.php:
--------------------------------------------------------------------------------
1 | foreignRecord;
28 | }
29 |
30 | public function getTableName(): string
31 | {
32 | return $this->tableName;
33 | }
34 |
35 | public function getColumnName(): string
36 | {
37 | return $this->columnName;
38 | }
39 |
40 | public function setForeignRecord(array $foreignRecord): void
41 | {
42 | $this->foreignRecord = $foreignRecord;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/Classes/Event/RenderInfoWindowContentEvent.php:
--------------------------------------------------------------------------------
1 | poiCollectionRecord;
31 | }
32 |
33 | /**
34 | * Keep in mind: This event was called by a Middleware. The request object is not fully compiled!
35 | * Attributes like ContentObjectRenderer are not defined until now.
36 | */
37 | public function getRequest(): ServerRequestInterface
38 | {
39 | return $this->request;
40 | }
41 |
42 | public function getInfoWindowContent(): string
43 | {
44 | return $this->infoWindowContent;
45 | }
46 |
47 | public function setInfoWindowContent(string $infoWindowContent): void
48 | {
49 | $this->infoWindowContent = $infoWindowContent;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Classes/EventListener/PreventPageCacheForMiddlewareEventListener.php:
--------------------------------------------------------------------------------
1 | setShouldUseCachedPageData(
31 | $event->getRequest()->getHeader('ext-maps2') !== ['infoWindowContent'],
32 | );
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/Classes/ExpressionLanguage/AllowMapProviderRequestConditionProvider.php:
--------------------------------------------------------------------------------
1 | expressionLanguageProviders = [
24 | AllowMapProviderRequestFunctionsProvider::class,
25 | ];
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Classes/ExpressionLanguage/AllowMapProviderRequestFunctionsProvider.php:
--------------------------------------------------------------------------------
1 | getIsRequestToMapProviderAllowed(),
33 | ];
34 | }
35 |
36 | protected function getIsRequestToMapProviderAllowed(): ExpressionFunction
37 | {
38 | // Need local variable for static callable
39 | $mapHelper = $this->mapHelper;
40 |
41 | return new ExpressionFunction(
42 | 'isRequestToMapProviderAllowed',
43 | static function (): void {
44 | // Not implemented, we only use the evaluator
45 | },
46 | static fn($existingVariables) => $mapHelper->isRequestToMapProviderAllowed(),
47 | );
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/Classes/Form/FieldInformation/InfoWindowContent.php:
--------------------------------------------------------------------------------
1 | initializeResultArray();
26 |
27 | $address = GeneralUtility::trimExplode(',', $this->data['databaseRow']['address']);
28 |
29 | $html = [];
30 | $html[] = '
' . $this->getLanguageService()->sL('LLL:EXT:maps2/Resources/Private/Language/locallang_db.xlf:info_window_content.preview') . '
';
31 | $html[] = '';
32 | $html[] = '
';
38 | $html[] = '
';
39 |
40 | $resultArray['html'] = implode('', $html);
41 |
42 | return $resultArray;
43 | }
44 |
45 | protected function getLanguageService(): LanguageService
46 | {
47 | return $GLOBALS['LANG'];
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/Classes/Form/Resolver/MapProviderResolver.php:
--------------------------------------------------------------------------------
1 | data = $data;
34 | }
35 |
36 | /**
37 | * Returns either a map based on Google Maps or Open Street Map
38 | *
39 | * @return string New class name
40 | */
41 | public function resolve(): string
42 | {
43 | if ($this->mapHelper->getMapProvider($this->data['databaseRow']) === 'osm') {
44 | return OpenStreetMapElement::class;
45 | }
46 |
47 | return GoogleMapsElement::class;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/Classes/Helper/LinkHelper.php:
--------------------------------------------------------------------------------
1 | siteFinder = $siteFinder;
31 | }
32 |
33 | public function buildUriToCurrentPage(array $parameters, ServerRequestInterface $request): string
34 | {
35 | $router = $this->getRouter($request);
36 | if (!$router instanceof RouterInterface) {
37 | return '';
38 | }
39 |
40 | $mergedParameters = [
41 | '_language' => $request->getAttribute('language'),
42 | ];
43 |
44 | ArrayUtility::mergeRecursiveWithOverrule($mergedParameters, $parameters);
45 |
46 | return (string)$router->generateUri(
47 | $this->getCurrentPageUid($request),
48 | $mergedParameters,
49 | RouterInterface::ABSOLUTE_URL,
50 | );
51 | }
52 |
53 | protected function getRouter(ServerRequestInterface $request): ?RouterInterface
54 | {
55 | $site = $this->getCurrentSite($request);
56 | if (!$site instanceof Site) {
57 | return null;
58 | }
59 |
60 | return $site->getRouter();
61 | }
62 |
63 | protected function getCurrentSite(ServerRequestInterface $request): ?Site
64 | {
65 | $site = $request->getAttribute('site');
66 | if ($site instanceof Site) {
67 | return $site;
68 | }
69 |
70 | return null;
71 | }
72 |
73 | protected function getCurrentPageUid(ServerRequestInterface $request): int
74 | {
75 | $pageUid = $this->getCurrentPageUidFromRequest($request);
76 | if ($pageUid === 0) {
77 | $pageUid = $this->getCurrentPageUidFromQueryParameters($request);
78 | }
79 |
80 | return $pageUid;
81 | }
82 |
83 | protected function getCurrentPageUidFromRequest(ServerRequestInterface $request): int
84 | {
85 | $routing = $request->getAttribute('routing');
86 | if ($routing instanceof PageArguments) {
87 | return $routing->getPageId();
88 | }
89 |
90 | return 0;
91 | }
92 |
93 | protected function getCurrentPageUidFromQueryParameters(ServerRequestInterface $request): int
94 | {
95 | $queryParameters = $this->getQueryParameters($request);
96 |
97 | return (int)(array_key_exists('id', $queryParameters) ? $queryParameters['id'] : 0);
98 | }
99 |
100 | protected function getQueryParameters(ServerRequestInterface $request): array
101 | {
102 | if (is_array($request->getQueryParams())) {
103 | return $request->getQueryParams();
104 | }
105 |
106 | return [];
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/Classes/Helper/SettingsHelper.php:
--------------------------------------------------------------------------------
1 | configurationManager = $configurationManager;
28 | }
29 |
30 | /**
31 | * This method will merge TypoScript and FlexForm settings of EXT:maps2 and should be called
32 | * by maps2 only.
33 | * Be careful using this method from within foreign extensions. The context may differ. It may happen
34 | * that FlexForm settings of your plugin will be merged with TypoScript settings of maps2. This can
35 | * lead to unforeseen miss-configuration.
36 | */
37 | public function getMergedSettings(): array
38 | {
39 | $typoScriptSettings = $this->configurationManager->getConfiguration(
40 | ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK,
41 | 'maps2',
42 | 'invalid', // invalid plugin name, to get fresh unmerged settings
43 | );
44 |
45 | // In context of a maps2 plugin this will return the merged (TS and FlexForm) settings
46 | $mergedSettings = $this->configurationManager->getConfiguration(
47 | ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS,
48 | );
49 |
50 | foreach ($mergedSettings as $setting => $value) {
51 | if ($value === '' && isset($typoScriptSettings['settings'][$setting])) {
52 | $mergedSettings[$setting] = $typoScriptSettings['settings'][$setting];
53 | }
54 | }
55 |
56 | return $mergedSettings;
57 | }
58 |
59 | /**
60 | * If possible you should always set $settings. In context of controllers $settings contains a merged version
61 | * of TS settings and FlexForm settings. If you don't have any settings by hand, leave empty, and we will
62 | * try to get settings from TypoScript (no FlexForm settings!!!)
63 | */
64 | public function getPreparedSettings(array $settings = []): array
65 | {
66 | $settings = $settings ?: $this->getTypoScriptSettings();
67 |
68 | $settings['forceZoom'] = (bool)($settings['forceZoom'] ?? false);
69 |
70 | // https://wiki.openstreetmap.org/wiki/Tile_servers tolds to use ${x} placeholders, but they don't work.
71 | if (!empty($settings['mapTile'])) {
72 | $settings['mapTile'] = str_replace(
73 | ['${s}', '${x}', '${y}', '${z}'],
74 | ['{s}', '{x}', '{y}', '{z}'],
75 | $settings['mapTile'],
76 | );
77 | }
78 |
79 | if (
80 | !empty($settings['markerClusterer']['enable'])
81 | && !empty($settings['markerClusterer']['imagePath'])
82 | ) {
83 | $settings['markerClusterer']['enable'] = 1;
84 | if (method_exists(PathUtility::class, 'getPublicResourceWebPath')) {
85 | $settings['markerClusterer']['imagePath'] = PathUtility::getPublicResourceWebPath($settings['markerClusterer']['imagePath']);
86 | } else {
87 | $settings['markerClusterer']['imagePath'] = PathUtility::getAbsoluteWebPath(
88 | GeneralUtility::getFileAbsFileName(
89 | $settings['markerClusterer']['imagePath'],
90 | ),
91 | );
92 | }
93 | }
94 |
95 | return $settings;
96 | }
97 |
98 | protected function getTypoScriptSettings(): array
99 | {
100 | return $this->configurationManager->getConfiguration(
101 | ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS,
102 | 'Maps2',
103 | 'Maps2',
104 | ) ?? [];
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/Classes/Mapper/GoogleMapsMapper.php:
--------------------------------------------------------------------------------
1 | attach($this->getPosition($data));
29 | }
30 |
31 | return $objectStorage;
32 | }
33 |
34 | protected function getPosition(array $data): Position
35 | {
36 | $position = GeneralUtility::makeInstance(Position::class);
37 | $position->setFormattedAddress($data['formatted_address']);
38 |
39 | try {
40 | $position->setLatitude((float)ArrayUtility::getValueByPath($data, 'geometry/location/lat'));
41 | $position->setLongitude((float)ArrayUtility::getValueByPath($data, 'geometry/location/lng'));
42 | } catch (\RuntimeException) {
43 | // Path of ArrayUtility does not exist
44 | $position->setLatitude(0.0);
45 | $position->setLongitude(0.0);
46 | }
47 |
48 | return $position;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/Classes/Mapper/MapperFactory.php:
--------------------------------------------------------------------------------
1 | GoogleMapsMapper::class,
24 | 'osm' => OpenStreetMapMapper::class,
25 | ];
26 |
27 | public function __construct(protected MapHelper $mapHelper) {}
28 |
29 | public function create(): MapperInterface
30 | {
31 | /** @var MapperInterface $client */
32 | $client = GeneralUtility::makeInstance(
33 | $this->mapping[$this->mapHelper->getMapProvider()],
34 | );
35 |
36 | return $client;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Classes/Mapper/MapperInterface.php:
--------------------------------------------------------------------------------
1 | attach($this->getPosition($data));
28 | }
29 |
30 | return $objectStorage;
31 | }
32 |
33 | protected function getPosition(array $data): Position
34 | {
35 | $position = GeneralUtility::makeInstance(Position::class);
36 | $position->setFormattedAddress($this->getFormattedAddress($data));
37 | $position->setLatitude((float)($data['lat'] ?? 0.0));
38 | $position->setLongitude((float)($data['lon'] ?? 0.0));
39 |
40 | return $position;
41 | }
42 |
43 | /**
44 | * Extract address parts from Response to build a formatted address
45 | */
46 | protected function getFormattedAddress(array $data): string
47 | {
48 | if (array_key_exists('address', $data)) {
49 | $data['address']['city'] = $this->getCityFromAddress($data['address']);
50 |
51 | $formattedAddress = sprintf(
52 | '%s %s, %s %s, %s',
53 | $data['address']['road'] ?? $data['address']['footway'] ?? '',
54 | $data['address']['house_number'] ?? '',
55 | $data['address']['postcode'] ?? '',
56 | $data['address']['city'],
57 | $data['address']['country'] ?? '',
58 | );
59 | } else {
60 | // 'display_name' can be a very long name.
61 | // We hope address key is set above to return a reduced formattedAddress
62 | $formattedAddress = $data['display_name'];
63 | }
64 |
65 | return trim((string)$formattedAddress, " ,\t\n\r\0\x0B");
66 | }
67 |
68 | /**
69 | * Open Street Map differs between small and big cities.
70 | * That's why we have to check each kind of city size to get the city name itself.
71 | */
72 | protected function getCityFromAddress(array $address): string
73 | {
74 | $sortedCityTypes = ['village', 'town', 'city'];
75 | $city = '';
76 |
77 | foreach ($sortedCityTypes as $type) {
78 | if (array_key_exists($type, $address)) {
79 | $city = $address[$type];
80 | }
81 | }
82 |
83 | return $city;
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/Classes/Middleware/GetInfoWindowContentMiddleware.php:
--------------------------------------------------------------------------------
1 | getHeader('ext-maps2') !== ['infoWindowContent']) {
35 | return $handler->handle($request);
36 | }
37 |
38 | $postData = $this->getPostData($request);
39 |
40 | if (isset($postData['error'])) {
41 | return new JsonResponse($postData);
42 | }
43 |
44 | if (!array_key_exists('poiCollection', $postData)) {
45 | return new JsonResponse([
46 | 'error' => 'No POI collection provided',
47 | ]);
48 | }
49 |
50 | $poiCollectionUid = (int)$postData['poiCollection'];
51 |
52 | if ($poiCollectionUid === 0) {
53 | return new JsonResponse([
54 | 'error' => 'POI collection UID can not be empty',
55 | ]);
56 | }
57 |
58 | $poiCollectionRecord = $this->poiCollectionService->findByUid($poiCollectionUid, $request);
59 |
60 | if ($poiCollectionRecord === null) {
61 | return new JsonResponse([
62 | 'error' => 'No POI collection record with requested UID found',
63 | ]);
64 | }
65 |
66 | return new JsonResponse([
67 | 'content' => $this->infoWindowContentService->render($poiCollectionRecord, $request),
68 | ]);
69 | }
70 |
71 | protected function getPostData(ServerRequestInterface $request): array
72 | {
73 | try {
74 | $payload = json_decode((string)$request->getBody(), true, 512, JSON_THROW_ON_ERROR);
75 | } catch (\JsonException) {
76 | $payload = [
77 | 'errors' => [
78 | 'Given post stream does not contain valid JSON string',
79 | ],
80 | ];
81 | }
82 |
83 | return is_array($payload) ? $payload : [];
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/Classes/Middleware/InitFeSessionMiddleware.php:
--------------------------------------------------------------------------------
1 | handle($request);
40 | if (
41 | $this->extConf->getExplicitAllowMapProviderRequests()
42 | && $this->mapHelper->isRequestToMapProviderAllowed()
43 | ) {
44 | $cookie = $this->createCookie($request);
45 | $response = $response->withAddedHeader('Set-Cookie', $cookie->__toString());
46 | }
47 |
48 | return $response;
49 | }
50 |
51 | protected function createCookie(ServerRequestInterface $request): Cookie
52 | {
53 | $normalizedParams = $request->getAttribute('normalizedParams');
54 |
55 | // Store consent in COOKIE
56 | $cookieSameSite = $this->sanitizeSameSiteCookieValue(
57 | strtolower($GLOBALS['TYPO3_CONF_VARS']['BE']['cookieSameSite'] ?? Cookie::SAMESITE_STRICT),
58 | );
59 |
60 | // SameSite Cookie = None needs the secure option (only allowed on HTTPS)
61 | $isSecure = $cookieSameSite === Cookie::SAMESITE_NONE || $normalizedParams->isHttps();
62 |
63 | return new Cookie(
64 | 'mapProviderRequestsAllowedForMaps2',
65 | '1',
66 | $this->getCookieExpire(),
67 | $normalizedParams->getSitePath(),
68 | null,
69 | $isSecure,
70 | false, // Should be false to allow JS based consent tools to delete this cookie
71 | false,
72 | $cookieSameSite,
73 | );
74 | }
75 |
76 | protected function getCookieExpire(): int
77 | {
78 | // If COOKIE is activated, set expire to FE sessionDataLifetime which is 1 day by default
79 | $maxSessionLifetime = $GLOBALS['TYPO3_CONF_VARS']['FE']['sessionDataLifetime'] ?? 60 * 60 * 24;
80 | $expire = GeneralUtility::makeInstance(Context::class)
81 | ->getPropertyFromAspect('date', 'timestamp') + $maxSessionLifetime;
82 |
83 | // If session only is activated, $expire = 0 will delete our created COOKIE after closing the browser
84 | if ($this->extConf->getExplicitAllowMapProviderRequestsBySessionOnly()) {
85 | $expire = 0;
86 | }
87 |
88 | return (int)$expire;
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/Classes/Service/CacheService.php:
--------------------------------------------------------------------------------
1 | isFrontendEnvironment()) {
37 | throw new \RuntimeException(
38 | 'getCacheIdentifier can only be called from FE, as we have to add the true language ID to PoiCollection',
39 | 1733471017,
40 | );
41 | }
42 |
43 | // We do not add the original sys_language_uid of PoiCollection, as it can be the same for different languages.
44 | $poiCollection['language'] = $this->getLanguageUid();
45 |
46 | return sprintf(
47 | '%s%s',
48 | $prefix,
49 | $this->hashService->hmac(
50 | \json_encode(array_diff_key($poiCollection, ['uid', 'pid', 'language', 'title', 'address'])),
51 | $prefix,
52 | ),
53 | );
54 | }
55 |
56 | /**
57 | * Add UID and PID of PoiCollection as Cache-Tags to Cache-Entry.
58 | * Please do not use "infoWindowPid" and "infoWindowUid" as Cache-Tag-Prefix in your template,
59 | * as we will override them here.
60 | */
61 | public function getCacheTags(array $poiCollection, array $cacheTags = []): array
62 | {
63 | return array_merge(
64 | $cacheTags,
65 | [
66 | 'infoWindowPid' . ($poiCollection['pid'] ?? 0),
67 | 'infoWindowUid' . ($poiCollection['uid'] ?? 0),
68 | ],
69 | );
70 | }
71 |
72 | /**
73 | * Returns the calculated (incl. fallback) sys_language_uid
74 | *
75 | * @throws \Exception
76 | */
77 | protected function getLanguageUid(): int
78 | {
79 | if (!$this->isFrontendEnvironment()) {
80 | throw new \RuntimeException(
81 | 'getLanguageId can only be called from FE, as we have to add the true language ID to PoiCollection',
82 | 1733470968,
83 | );
84 | }
85 |
86 | return (int)GeneralUtility::makeInstance(Context::class)
87 | ->getPropertyFromAspect('language', 'id');
88 | }
89 |
90 | protected function isFrontendEnvironment(): bool
91 | {
92 | return defined('TYPO3') && ApplicationType::fromRequest($GLOBALS['TYPO3_REQUEST'])->isFrontend();
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/Classes/Service/GeoCodeService.php:
--------------------------------------------------------------------------------
1 | client = $clientFactory->create();
40 | }
41 |
42 | /**
43 | * @return ObjectStorage|Position[]
44 | * @throws \Exception
45 | */
46 | public function getPositionsByAddress(string $address): ObjectStorage
47 | {
48 | $positions = new ObjectStorage();
49 |
50 | // Prevent calls to Map Providers GeoCode API, if address is empty
51 | if (trim($address) === '') {
52 | return $positions;
53 | }
54 |
55 | $geocodeRequest = $this->requestFactory->create('GeocodeRequest');
56 | $geocodeRequest->addParameter('address', $address);
57 |
58 | $response = $this->client->processRequest($geocodeRequest);
59 | if ($response !== []) {
60 | $positions = $this->mapperFactory->create()->map($response);
61 | }
62 |
63 | return $positions;
64 | }
65 |
66 | public function getFirstFoundPositionByAddress(string $address): ?Position
67 | {
68 | $position = null;
69 | $positions = $this->getPositionsByAddress($address);
70 | if ($positions->count() !== 0) {
71 | $positions->rewind();
72 | /** @var Position $position */
73 | $position = $positions->current();
74 | }
75 |
76 | return $position;
77 | }
78 |
79 | public function hasErrors(): bool
80 | {
81 | return $this->client->hasErrors();
82 | }
83 |
84 | /**
85 | * @return FlashMessage[]
86 | */
87 | public function getErrors(): array
88 | {
89 | return $this->client->getErrors();
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/Classes/Service/MapProviderRequestService.php:
--------------------------------------------------------------------------------
1 | mapHelper->isRequestToMapProviderAllowed();
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Classes/Service/PoiCollectionService.php:
--------------------------------------------------------------------------------
1 | getQueryBuilder($request);
40 |
41 | try {
42 | $poiCollectionRecord = $queryBuilder
43 | ->select('*')
44 | ->from(self::TABLE)
45 | ->where(
46 | $queryBuilder->expr()->eq(
47 | 'uid',
48 | $queryBuilder->createNamedParameter($poiCollectionUid, Connection::PARAM_INT),
49 | ),
50 | )
51 | ->executeQuery()
52 | ->fetchAssociative();
53 | } catch (Exception) {
54 | return null;
55 | }
56 |
57 | if (is_array($poiCollectionRecord)) {
58 | $this->pageRepository->versionOL(self::TABLE, $poiCollectionRecord);
59 | if (is_array($poiCollectionRecord)) {
60 | $poiCollectionRecord = $this->pageRepository->getLanguageOverlay(
61 | self::TABLE,
62 | $poiCollectionRecord,
63 | );
64 | }
65 | }
66 |
67 | return is_array($poiCollectionRecord) ? $poiCollectionRecord : null;
68 | }
69 |
70 | private function getQueryBuilder(ServerRequestInterface $request): QueryBuilder
71 | {
72 | $queryBuilder = $this->queryBuilder;
73 |
74 | if (ApplicationType::fromRequest($request)->isFrontend()) {
75 | $queryBuilder->setRestrictions(GeneralUtility::makeInstance(FrontendRestrictionContainer::class));
76 | } else {
77 | $queryBuilder
78 | ->getRestrictions()
79 | ->removeAll()
80 | ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
81 | }
82 |
83 | return $queryBuilder;
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/Classes/Tca/Type/FloatType.php:
--------------------------------------------------------------------------------
1 | 'maps2_maps2',
27 | 'maps2_overlay' => 'maps2_overlay',
28 | 'maps2_searchwithinradius' => 'maps2_searchwithinradius',
29 | 'maps2_citymap' => 'maps2_citymap',
30 | ];
31 | }
32 |
33 | public function getTitle(): string
34 | {
35 | return 'Migrate plugins to Content Elements';
36 | }
37 |
38 | public function getDescription(): string
39 | {
40 | return 'The modern way to register plugins for TYPO3 is to register them as content element types. ' .
41 | 'Running this wizard will migrate all maps2 plugins to content element (CType)';
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Classes/Update/NewGeocodeUriForOsmUpdate.php:
--------------------------------------------------------------------------------
1 | getOsmGeocodeUri() === $this->oldOsmGeocodeUri;
47 | }
48 |
49 | public function executeUpdate(): bool
50 | {
51 | if ($this->getOsmGeocodeUri() === $this->oldOsmGeocodeUri) {
52 | try {
53 | $maps2ExtensionConfiguration = $this->getExtensionConfiguration()->get('maps2');
54 | if (
55 | is_array($maps2ExtensionConfiguration)
56 | && array_key_exists('openStreetMapGeocodeUri', $maps2ExtensionConfiguration)
57 | ) {
58 | $maps2ExtensionConfiguration['openStreetMapGeocodeUri'] = $this->newOsmGeocodeUri;
59 | $this->getExtensionConfiguration()->set(
60 | 'maps2',
61 | $maps2ExtensionConfiguration,
62 | );
63 | }
64 |
65 | return true;
66 | } catch (ExtensionConfigurationExtensionNotConfiguredException | ExtensionConfigurationPathDoesNotExistException) {
67 | }
68 | }
69 |
70 | return false;
71 | }
72 |
73 | private function getOsmGeocodeUri(): string
74 | {
75 | try {
76 | return $this->getExtensionConfiguration()->get('maps2', 'openStreetMapGeocodeUri');
77 | } catch (ExtensionConfigurationExtensionNotConfiguredException | ExtensionConfigurationPathDoesNotExistException) {
78 | return '';
79 | }
80 | }
81 |
82 | private function getExtensionConfiguration(): ExtensionConfiguration
83 | {
84 | return GeneralUtility::makeInstance(ExtensionConfiguration::class);
85 | }
86 |
87 | private function getTypo3Version(): Typo3Version
88 | {
89 | return GeneralUtility::makeInstance(Typo3Version::class);
90 | }
91 |
92 | public function getPrerequisites(): array
93 | {
94 | return [];
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/Classes/Utility/DatabaseUtility.php:
--------------------------------------------------------------------------------
1 | getConnectionForTable($tableName);
32 | try {
33 | return $connection->createSchemaManager()->listTableColumns($tableName);
34 | } catch (Exception) {
35 | }
36 |
37 | return [];
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Classes/ViewHelpers/Cache/GetCacheViewHelper.php:
--------------------------------------------------------------------------------
1 | registerArgument(
36 | 'prefix',
37 | 'string',
38 | 'A prefix for the cache identifier.',
39 | false,
40 | 'infoWindow',
41 | );
42 | $this->registerArgument(
43 | 'poiCollection',
44 | 'array',
45 | 'We need the PoiCollection record to build a better language independent CacheIdentifier.',
46 | true,
47 | );
48 | }
49 |
50 | /**
51 | * Returns cache entry by given cache identifier
52 | * Info: here is no check if cache entry exists. Please use maps:cache.hasCache instead/before
53 | */
54 | public function render(): string
55 | {
56 | $poiCollectionRecord = $this->arguments['poiCollection'];
57 |
58 | try {
59 | return $this->cache->get(
60 | $this->cacheService->getCacheIdentifier(
61 | $poiCollectionRecord,
62 | $this->arguments['prefix'],
63 | ),
64 | );
65 | } catch (\Exception) {
66 | }
67 |
68 | return '';
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/Classes/ViewHelpers/Cache/HasCacheViewHelper.php:
--------------------------------------------------------------------------------
1 | registerArgument(
31 | 'prefix',
32 | 'string',
33 | 'A prefix for the cache identifier.',
34 | false,
35 | 'infoWindow',
36 | );
37 | $this->registerArgument(
38 | 'poiCollection',
39 | 'array',
40 | 'We need the PoiCollection record to build a better language independent CacheIdentifier.',
41 | true,
42 | );
43 | }
44 |
45 | /**
46 | * Checks if caching framework has the requested cache entry
47 | */
48 | public function render(): bool
49 | {
50 | $poiCollectionRecord = $this->arguments['poiCollection'];
51 |
52 | try {
53 | return $this->cache->has(
54 | $this->cacheService->getCacheIdentifier(
55 | $poiCollectionRecord,
56 | $this->arguments['prefix'],
57 | ),
58 | );
59 | } catch (\Exception) {
60 | }
61 |
62 | return false;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/Classes/ViewHelpers/Cache/SetCacheViewHelper.php:
--------------------------------------------------------------------------------
1 | registerArgument(
36 | 'prefix',
37 | 'string',
38 | 'A prefix for the cache identifier.',
39 | false,
40 | 'infoWindow',
41 | );
42 | $this->registerArgument(
43 | 'poiCollection',
44 | 'array',
45 | 'We need the PoiCollection record to build a better language independent CacheIdentifier.',
46 | true,
47 | );
48 | $this->registerArgument(
49 | 'data',
50 | 'string',
51 | 'The data to be stored',
52 | true,
53 | );
54 | $this->registerArgument(
55 | 'tags',
56 | 'array',
57 | 'Tags to associate with this cache entry',
58 | false,
59 | [],
60 | );
61 | $this->registerArgument(
62 | 'lifetime',
63 | 'int',
64 | 'Lifetime of this cache entry in seconds. If null is specified, the default lifetime is used. "0" means unlimited lifetime',
65 | );
66 | }
67 |
68 | /**
69 | * Saves data in a cache file.
70 | */
71 | public function render(): void
72 | {
73 | $poiCollectionRecord = $this->arguments['poiCollection'];
74 |
75 | try {
76 | $this->cache->set(
77 | $this->cacheService->getCacheIdentifier($poiCollectionRecord, $this->arguments['prefix']),
78 | $this->arguments['data'],
79 | $this->cacheService->getCacheTags($poiCollectionRecord, $this->arguments['tags']),
80 | ($this->arguments['lifetime'] === null ? null : (int)$this->arguments['lifetime']),
81 | );
82 | } catch (\Exception) {
83 | }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/Classes/ViewHelpers/ConvertToJsonViewHelper.php:
--------------------------------------------------------------------------------
1 | renderChildren();
43 |
44 | if ($poiCollections instanceof PoiCollection) {
45 | $poiCollections = [$poiCollections];
46 | }
47 |
48 | try {
49 | if (self::valueContainsPoiCollections($poiCollections)) {
50 | $json = self::getPoiCollectionsAsJson($poiCollections);
51 | } else {
52 | $json = json_encode($poiCollections, JSON_THROW_ON_ERROR);
53 | }
54 | } catch (\JsonException) {
55 | $json = '{}';
56 | }
57 |
58 | return htmlspecialchars($json);
59 | }
60 |
61 | /**
62 | * Convert poiCollections to array and pass them through json_encode
63 | *
64 | * @param PoiCollection[] $poiCollections
65 | */
66 | protected function getPoiCollectionsAsJson(array|QueryResultInterface|ObjectStorage $poiCollections): string
67 | {
68 | $poiCollectionsAsArray = [];
69 | foreach ($poiCollections as $poiCollection) {
70 | $poiCollectionAsArray = ObjectAccess::getGettableProperties($poiCollection);
71 | unset($poiCollectionAsArray['markerIcons']);
72 |
73 | $poiCollectionAsArray['categories'] = [];
74 | /** @var Category $category */
75 | foreach ($poiCollection->getCategories() as $category) {
76 | $categoryProperties = ObjectAccess::getGettableProperties($category);
77 | unset($categoryProperties['maps2MarkerIcons'], $categoryProperties['parent']);
78 | $poiCollectionAsArray['categories'][] = $categoryProperties;
79 | }
80 |
81 | $poiCollectionsAsArray[] = $poiCollectionAsArray;
82 | }
83 |
84 | try {
85 | return json_encode($poiCollectionsAsArray, JSON_THROW_ON_ERROR);
86 | } catch (\JsonException $e) {
87 | return '{}';
88 | }
89 | }
90 |
91 | /**
92 | * Check, if value contains entries of type PoiCollection
93 | */
94 | protected function valueContainsPoiCollections(mixed $value): bool
95 | {
96 | // With PHP 8.1 reset() and current() should not be used with objects anymore.
97 | // Extract the values as simple array to be compatible in the future.
98 | if ($value instanceof \ArrayObject) {
99 | $value = $value->getArrayCopy();
100 | }
101 |
102 | $containsPoiCollections = false;
103 | if (is_array($value)) {
104 | reset($value);
105 | $poiCollection = current($value);
106 | $containsPoiCollections = $poiCollection instanceof PoiCollection;
107 | } elseif ($value instanceof \Iterator) {
108 | $value->rewind();
109 | $poiCollection = $value->current();
110 | $containsPoiCollections = $poiCollection instanceof PoiCollection;
111 | }
112 |
113 | return $containsPoiCollections;
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/Classes/ViewHelpers/Form/HiddenViewHelper.php:
--------------------------------------------------------------------------------
1 | ` tag.
18 | * This VH is a copy of the original f:hidden VH with ONE difference:
19 | * It adds a required __identity flag for property
20 | * Many other f:form.* VHs do so, but f:hidden not. Don't know why.
21 | * Remove this VH, if this is resolved: https://forge.typo3.org/issues/90331
22 | */
23 | class HiddenViewHelper extends AbstractFormFieldViewHelper
24 | {
25 | /**
26 | * @var string
27 | */
28 | protected $tagName = 'input';
29 |
30 | public function initializeArguments(): void
31 | {
32 | parent::initializeArguments();
33 | }
34 |
35 | /**
36 | * Renders the hidden field.
37 | */
38 | public function render(): string
39 | {
40 | $name = $this->getName();
41 | $this->registerFieldNameForFormTokenGeneration($name);
42 | $this->setRespectSubmittedDataValue(true);
43 |
44 | $this->tag->addAttribute('type', 'hidden');
45 | $this->tag->addAttribute('name', $name);
46 | $this->tag->addAttribute('value', $this->getValueAttribute());
47 |
48 | // Add required __identify field
49 | $this->addAdditionalIdentityPropertiesIfNeeded();
50 |
51 | return $this->tag->render();
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/Classes/ViewHelpers/GetEnvironmentViewHelper.php:
--------------------------------------------------------------------------------
1 | renderingContext->getVariableProvider();
47 | $extbaseRequest = self::getExtbaseRequest($this->renderingContext);
48 | if (!$extbaseRequest instanceof RequestInterface) {
49 | return '';
50 | }
51 |
52 | $templateVariableContainer->add(
53 | 'environment',
54 | [
55 | 'settings' => $this->settingsHelper->getPreparedSettings(),
56 | 'extConf' => ObjectAccess::getGettableProperties($this->extConf),
57 | 'ajaxUrl' => $this->linkHelper->buildUriToCurrentPage([], $extbaseRequest),
58 | 'contentRecord' => $extbaseRequest->getAttribute('currentContentObject')->data,
59 | ],
60 | );
61 |
62 | $content = $this->renderChildren();
63 |
64 | $templateVariableContainer->remove('environment');
65 |
66 | return $content;
67 | }
68 |
69 | private function getExtbaseRequest(RenderingContextInterface $renderingContext): ?RequestInterface
70 | {
71 | if (
72 | $renderingContext instanceof RenderingContext
73 | && $renderingContext->hasAttribute(ServerRequestInterface::class)
74 | && $renderingContext->getAttribute(ServerRequestInterface::class) instanceof RequestInterface
75 | ) {
76 | return $renderingContext->getAttribute(ServerRequestInterface::class);
77 | }
78 |
79 | return null;
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/Classes/ViewHelpers/IsRequestToMapProviderAllowedViewHelper.php:
--------------------------------------------------------------------------------
1 | mapHelper->isRequestToMapProviderAllowed();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Classes/ViewHelpers/RequestUriForOverlayViewHelper.php:
--------------------------------------------------------------------------------
1 | registerArgument(
33 | 'ttContentUid',
34 | 'int',
35 | 'The tt_content UID of the record which shows the map',
36 | false,
37 | 0,
38 | );
39 | }
40 |
41 | /**
42 | * Convert all array and object types into a json string. Useful for data-Attributes
43 | */
44 | public function render(): string
45 | {
46 | $uriBuilder = $this->uriBuilder
47 | ->reset()
48 | ->setAddQueryString('untrusted')
49 | ->setArguments([
50 | 'tx_maps2_maps2' => [
51 | 'mapProviderRequestsAllowedForMaps2' => 1,
52 | ],
53 | ])
54 | ->setArgumentsToBeExcludedFromQueryString(['cHash']);
55 |
56 | if (($this->settingsHelper->getPreparedSettings()['overlay']['link']['addSection'] ?? '') === '1') {
57 | $ttContentUid = (int)($arguments['ttContentUid'] ?? 0);
58 | if ($ttContentUid) {
59 | $uriBuilder->setSection('c' . $ttContentUid);
60 | }
61 | }
62 |
63 | $request = $this->renderingContext->getAttribute(ServerRequestInterface::class);
64 | $this->uriBuilder->setRequest($request);
65 |
66 | return $uriBuilder->build();
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/Classes/ViewHelpers/TrimExplodeViewHelper.php:
--------------------------------------------------------------------------------
1 | registerArgument(
25 | 'delimiter',
26 | 'string',
27 | 'The delimiter where the string should be exploded',
28 | false,
29 | ',',
30 | );
31 | }
32 |
33 | /**
34 | * Implements a ViewHelper to trim explode comma separated strings
35 | *
36 | * @return string[]
37 | */
38 | public function render(): array
39 | {
40 | return GeneralUtility::trimExplode($this->arguments['delimiter'], $this->renderChildren());
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Configuration/ExpressionLanguage.php:
--------------------------------------------------------------------------------
1 | [
14 | AllowMapProviderRequestConditionProvider::class,
15 | ],
16 | ];
17 |
--------------------------------------------------------------------------------
/Configuration/Extbase/Persistence/Classes.php:
--------------------------------------------------------------------------------
1 | [
23 | 'tableName' => 'sys_category',
24 | 'properties' => [],
25 | ],
26 | ];
27 |
--------------------------------------------------------------------------------
/Configuration/Icons.php:
--------------------------------------------------------------------------------
1 | [
15 | 'provider' => SvgIconProvider::class,
16 | 'source' => 'EXT:maps2/Resources/Public/Icons/plugin_wizard.svg',
17 | ],
18 | 'ext-maps2-record-type-point' => [
19 | 'provider' => BitmapIconProvider::class,
20 | 'source' => 'EXT:maps2/Resources/Public/Icons/RecordTypePoint.png',
21 | ],
22 | 'ext-maps2-record-type-area' => [
23 | 'provider' => BitmapIconProvider::class,
24 | 'source' => 'EXT:maps2/Resources/Public/Icons/RecordTypeArea.png',
25 | ],
26 | 'ext-maps2-record-type-route' => [
27 | 'provider' => BitmapIconProvider::class,
28 | 'source' => 'EXT:maps2/Resources/Public/Icons/RecordTypeRoute.png',
29 | ],
30 | 'ext-maps2-record-type-radius' => [
31 | 'provider' => BitmapIconProvider::class,
32 | 'source' => 'EXT:maps2/Resources/Public/Icons/RecordTypeRadius.png',
33 | ],
34 | ];
35 |
--------------------------------------------------------------------------------
/Configuration/JavaScriptModules.php:
--------------------------------------------------------------------------------
1 | [
12 | 'backend',
13 | 'core',
14 | ],
15 | 'imports' => [
16 | '@jweiland/maps2/' => [
17 | 'path' => 'EXT:maps2/Resources/Public/JavaScript/',
18 | 'exclude' => [
19 | 'EXT:maps2/Resources/Public/JavaScript/leaflet.min.js',
20 | ],
21 | ],
22 | 'leaflet' => 'EXT:maps2/Resources/Public/JavaScript/leaflet.min.js',
23 | ],
24 | ];
25 |
--------------------------------------------------------------------------------
/Configuration/RequestMiddlewares.php:
--------------------------------------------------------------------------------
1 | [
15 | 'jweiland/maps2/initialize-fe-session' => [
16 | 'target' => InitFeSessionMiddleware::class,
17 | 'after' => [
18 | 'typo3/cms-frontend/tsfe',
19 | ],
20 | 'before' => [
21 | 'typo3/cms-frontend/prepare-tsfe-rendering',
22 | ],
23 | ],
24 | 'jweiland/maps2/info-window-content' => [
25 | 'target' => GetInfoWindowContentMiddleware::class,
26 | 'after' => [
27 | 'typo3/cms-frontend/prepare-tsfe-rendering',
28 | ],
29 | 'before' => [
30 | 'typo3/cms-frontend/output-compression',
31 | ],
32 | ],
33 | ],
34 | ];
35 |
--------------------------------------------------------------------------------
/Configuration/Services.yaml:
--------------------------------------------------------------------------------
1 | services:
2 | _defaults:
3 | autowire: true
4 | autoconfigure: true
5 | public: false
6 |
7 | JWeiland\Maps2\:
8 | resource: '../Classes/*'
9 | exclude: '../Classes/Domain/Model/*'
10 |
11 | cache.maps2CachedHtml:
12 | class: TYPO3\CMS\Core\Cache\Frontend\FrontendInterface
13 | factory: ['@TYPO3\CMS\Core\Cache\CacheManager', 'getCache']
14 | arguments: ['maps2_cachedhtml']
15 |
16 | querybuilder.tx_maps2_domain_model_poicollection:
17 | class: 'TYPO3\CMS\Core\Database\Query\QueryBuilder'
18 | factory:
19 | - '@TYPO3\CMS\Core\Database\ConnectionPool'
20 | - 'getQueryBuilderForTable'
21 | arguments:
22 | - 'tx_maps2_domain_model_poicollection'
23 |
24 | # Called by makeInstance in TYPO3's PluginPreview
25 | JWeiland\Maps2\Backend\Preview\Maps2PluginPreview:
26 | public: true
27 |
28 | # Called by makeInstance in our RequestFactory
29 | JWeiland\Maps2\Client\Request\GoogleMaps\GeocodeRequest:
30 | public: true
31 |
32 | # Called by makeInstance in our RequestFactory
33 | JWeiland\Maps2\Client\Request\OpenStreetMap\GeocodeRequest:
34 | public: true
35 |
36 | # Called by makeInstance in our ClientFactory
37 | JWeiland\Maps2\Client\GoogleMapsClient:
38 | public: true
39 |
40 | # Called by makeInstance in our ClientFactory
41 | JWeiland\Maps2\Client\OpenStreetMapClient:
42 | public: true
43 |
44 | # Called by makeInstance in various TCA files
45 | JWeiland\Maps2\Configuration\ExtConf:
46 | public: true
47 |
48 | # Called by makeInstance in TYPO3's AbstractConditionMatcher
49 | JWeiland\Maps2\ExpressionLanguage\AllowMapProviderRequestFunctionsProvider:
50 | public: true
51 |
52 | # Called by makeInstance in TYPO3's NodeRegistry
53 | JWeiland\Maps2\Form\Element\ReadOnlyInputTextElement:
54 | public: true
55 |
56 | # Called by makeInstance in TYPO3's NodeRegistry
57 | JWeiland\Maps2\Form\FieldInformation\InfoWindowContent:
58 | public: true
59 |
60 | # Called by makeInstance in TYPO3's NodeRegistry
61 | JWeiland\Maps2\Form\Resolver\MapProviderResolver:
62 | public: true
63 |
64 | # Called by makeInstance in our PoiCollection
65 | JWeiland\Maps2\Helper\MapHelper:
66 | public: true
67 |
68 | # Called by makeInstance in our GetEnvironmentViewHelper
69 | JWeiland\Maps2\Helper\SettingsHelper:
70 | public: true
71 |
72 | # Called by makeInstance in TYPO3's DataHandler
73 | JWeiland\Maps2\Hook\CreateMaps2RecordHook:
74 | public: true
75 |
76 | # Called by makeInstance in PoiCollection model to add foreign records
77 | JWeiland\Maps2\Service\MapService:
78 | public: true
79 |
80 | JWeiland\Maps2\Service\PoiCollectionService:
81 | arguments:
82 | $queryBuilder: '@querybuilder.tx_maps2_domain_model_poicollection'
83 |
84 | JWeiland\Maps2\ViewHelpers\Cache\GetCacheViewHelper:
85 | arguments:
86 | $cache: '@cache.maps2CachedHtml'
87 | JWeiland\Maps2\ViewHelpers\Cache\HasCacheViewHelper:
88 | arguments:
89 | $cache: '@cache.maps2CachedHtml'
90 | JWeiland\Maps2\ViewHelpers\Cache\SetCacheViewHelper:
91 | arguments:
92 | $cache: '@cache.maps2CachedHtml'
93 |
94 | JWeiland\Maps2\Tca\Maps2Registry:
95 | tags:
96 | - name: event.listener
97 | method: 'addMaps2DatabaseSchemasToTablesDefinition'
98 | event: TYPO3\CMS\Core\Database\Event\AlterTableDefinitionStatementsEvent
99 |
--------------------------------------------------------------------------------
/Configuration/Sets/GoogleMaps/config.yaml:
--------------------------------------------------------------------------------
1 | name: jweiland/maps2-googlemaps
2 | label: Maps2 - Google Maps
3 |
4 | dependencies:
5 | - jweiland/maps2-default
6 |
--------------------------------------------------------------------------------
/Configuration/Sets/GoogleMaps/settings.definitions.yaml:
--------------------------------------------------------------------------------
1 | categories:
2 | Maps2.googlemaps:
3 | label: 'Google Maps'
4 | parent: Maps2
5 |
6 | settings:
7 | maps2.enableMarkerClusterer:
8 | label: 'Enable Marker Clusterer'
9 | category: Maps2.googlemaps
10 | description: 'If you have a lot of POIs, some POIs will be joined to a single POI with the amount of joined POIs as label'
11 | type: bool
12 | default: false
13 | maps2.googleMapsJavaScriptApiKey:
14 | label: 'JavaScript API Key'
15 | category: Maps2.googlemaps
16 | description: 'Enter the Google Maps JavaScript API key which you can get from google cloud console'
17 | type: string
18 | default: ''
19 |
--------------------------------------------------------------------------------
/Configuration/Sets/GoogleMaps/setup.typoscript:
--------------------------------------------------------------------------------
1 | # Prevent including both static maps of map providers on one page
2 | page.includeJSFooterlibs.markerClustererForMaps2 >
3 |
4 | [isRequestToMapProviderAllowed()]
5 | page.includeJSFooterlibs {
6 | markerClustererForMaps2 = EXT:maps2/Resources/Public/JavaScript/MarkerClusterer.js
7 | markerClustererForMaps2.if.isTrue = {$maps2.enableMarkerClusterer}
8 | }
9 | [ELSE]
10 | # Requests to Google Maps are not allowed. Inform the user about cookies and request permissions for 3rd party.
11 | tt_content.maps2_maps2.20.pluginName = Overlay
12 | tt_content.maps2_searchwithinradius.20.pluginName = Overlay
13 | tt_content.maps2_citymap.20.pluginName = Overlay
14 | [END]
15 |
16 | plugin.tx_maps2 {
17 | settings {
18 | mapProvider = gm
19 | mapTypeControl = 1
20 | scaleControl = 1
21 | streetViewControl = 1
22 | fullscreenMapControl = 1
23 | googleMapsJavaScriptApiKey = {$maps2.googleMapsJavaScriptApiKey}
24 | mapTypeId = google.maps.MapTypeId.ROADMAP
25 | markerClusterer {
26 | enable = {$maps2.enableMarkerClusterer}
27 | imagePath = EXT:maps2/Resources/Public/Icons/MarkerClusterer/m
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Configuration/Sets/Maps2/config.yaml:
--------------------------------------------------------------------------------
1 | name: jweiland/maps2-default
2 | label: Maps2 - Default Set
3 |
--------------------------------------------------------------------------------
/Configuration/Sets/Maps2/settings.definitions.yaml:
--------------------------------------------------------------------------------
1 | categories:
2 | Maps2:
3 | label: 'Maps2'
4 | Maps2.templates:
5 | label: 'Templates'
6 | parent: 'Maps2'
7 | Maps2.templates.infoWindowContent:
8 | label: 'Info Window Content'
9 | parent: 'Maps2.templates'
10 | Maps2.pages:
11 | label: 'Pages'
12 | parent: 'Maps2'
13 |
14 | settings:
15 | maps2.templateRootPath:
16 | label: 'Templates'
17 | category: 'Maps2.templates'
18 | description: 'Path to template root'
19 | type: string
20 | default: 'EXT:maps2/Resources/Private/Templates/'
21 | maps2.partialRootPath:
22 | label: 'Partials'
23 | category: 'Maps2.templates'
24 | description: 'Path to partial root'
25 | type: string
26 | default: 'EXT:maps2/Resources/Private/Partials/'
27 | maps2.layoutRootPath:
28 | label: 'Layouts'
29 | category: 'Maps2.templates'
30 | description: 'Path to layout root'
31 | type: string
32 | default: 'EXT:maps2/Resources/Private/Layouts/'
33 | maps2.infoWindowContent.templatePath:
34 | label: 'Template path for info window content'
35 | category: 'Maps2.templates.infoWindowContent'
36 | description: 'If you click on a marker (POI) a little info window will appear. With this setting you can change the template to your own needs.'
37 | type: string
38 | default: 'EXT:maps2/Resources/Private/Templates/InfoWindowContent.html'
39 | maps2.infoWindowContent.imageHeight:
40 | label: 'Image Height'
41 | category: 'Maps2.templates.infoWindowContent'
42 | description: 'Define the image height for images in info window content of a POI. Values like 150c or 120m are also allowed.'
43 | type: string
44 | default: '150c'
45 | maps2.infoWindowContent.imageWidth:
46 | label: 'Image Width'
47 | category: 'Maps2.templates.infoWindowContent'
48 | description: 'Define the image width for images in info window content of a POI. Values like 150c or 120m are also allowed.'
49 | type: string
50 | default: '150c'
51 |
52 | maps2.storagePid:
53 | label: 'Default storage PID'
54 | category: 'Maps2.pages'
55 | description: 'Folder that stores all POIs'
56 | type: int
57 | default: 0
58 |
--------------------------------------------------------------------------------
/Configuration/Sets/Maps2/setup.typoscript:
--------------------------------------------------------------------------------
1 | plugin.tx_maps2 {
2 | view {
3 | templateRootPaths {
4 | 0 = {$maps2.templateRootPath}
5 | 10 =
6 | }
7 |
8 | partialRootPaths {
9 | 0 = {$maps2.partialRootPath}
10 | 10 =
11 | }
12 |
13 | layoutRootPaths {
14 | 0 = {$maps2.layoutRootPath}
15 | 10 =
16 | }
17 | }
18 |
19 | persistence {
20 | storagePid = {$maps2.storagePid}
21 | classes {
22 | JWeiland\Maps2\Domain\Model\PoiCollection {
23 | mapping.columns {
24 | distance.config {
25 | type = passthrough
26 | }
27 | }
28 | }
29 | }
30 | }
31 |
32 | settings {
33 | zoom = 10
34 | zoomControl = 1
35 | overlay {
36 | link {
37 | addSection = 1
38 | }
39 | }
40 |
41 | infoWindowContent {
42 | view {
43 | dataProcessing {
44 | 10 = files
45 | 10 {
46 | as = infoWindowImages
47 | references {
48 | fieldName = info_window_images
49 | table = tx_maps2_domain_model_poicollection
50 | }
51 | }
52 | }
53 | }
54 |
55 | image {
56 | width = {$maps2.infoWindowContent.imageWidth}
57 | height = {$maps2.infoWindowContent.imageHeight}
58 | }
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/Configuration/Sets/OpenStreetMap/config.yaml:
--------------------------------------------------------------------------------
1 | name: jweiland/maps2-openstreetmap
2 | label: Maps2 - OpenStreetMap
3 |
4 | dependencies:
5 | - jweiland/maps2-default
6 |
--------------------------------------------------------------------------------
/Configuration/Sets/OpenStreetMap/settings.definitions.yaml:
--------------------------------------------------------------------------------
1 | categories:
2 | Maps2.openstreetmap:
3 | label: 'OpenStreetMap'
4 | parent: Maps2
5 |
6 | settings:
7 | maps2.mapTile:
8 | label: 'Map Tile URL'
9 | category: Maps2.openstreetmap
10 | description: 'Define map tile: Please visit https://wiki.openstreetmap.org/wiki/Tile_servers to see all available map tiles. Be careful: If you switch a tile you may have to update the tile attribution, too'
11 | type: string
12 | default: 'https://{s}.tile.openstreetmap.org/${z}/${x}/${y}.png'
13 | maps2.mapTileAttribution:
14 | label: 'Map Tile Attribution'
15 | category: Maps2.openstreetmap
16 | description: 'Map tile attribution: OpenStreetMap license requires a correct map tile attribution. If you update map tile you may need to update this value, too'
17 | type: string
18 | default: '© OpenStreetMap contributors'
19 |
--------------------------------------------------------------------------------
/Configuration/Sets/OpenStreetMap/setup.typoscript:
--------------------------------------------------------------------------------
1 | # Prevent including both static maps of map providers on one page
2 | page.includeJSFooterlibs.markerClustererForMaps2 >
3 |
4 | [isRequestToMapProviderAllowed()]
5 | [ELSE]
6 | # Requests to OpenStreetMap are not allowed. Inform the user about cookies and request permissions for 3rd party.
7 | tt_content.maps2_maps2.20.pluginName = Overlay
8 | tt_content.maps2_searchwithinradius.20.pluginName = Overlay
9 | tt_content.maps2_citymap.20.pluginName = Overlay
10 | [END]
11 |
12 | plugin.tx_maps2 {
13 | settings {
14 | mapProvider = osm
15 | mapTile = {$maps2.mapTile}
16 | mapTileAttribution = {$maps2.mapTileAttribution}
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Configuration/TCA/Overrides/sys_category.php:
--------------------------------------------------------------------------------
1 | getMapProvider();
23 |
24 | $newSysCategoryColumn = [
25 | 'maps2_marker_icons' => [
26 | 'exclude' => 1,
27 | 'label' => $ll . 'sys_category.maps2_marker_icons.' . $mapProvider,
28 | 'description' => $ll . 'sys_category.maps2_marker_icons.' . $mapProvider . '.description',
29 | 'config' => [
30 | 'type' => 'file',
31 | 'minitems' => 0,
32 | 'maxitems' => 1,
33 | 'allowed' => 'common-image-types',
34 | ],
35 | ],
36 | 'maps2_marker_icon_width' => [
37 | 'exclude' => true,
38 | 'label' => $ll . 'sys_category.maps2_marker_icon_width.' . $mapProvider,
39 | 'description' => $ll . 'sys_category.maps2_marker_icon_width.' . $mapProvider . '.description',
40 | 'config' => [
41 | 'type' => 'number',
42 | 'format' => 'integer',
43 | ],
44 | ],
45 | 'maps2_marker_icon_height' => [
46 | 'exclude' => true,
47 | 'label' => $ll . 'sys_category.maps2_marker_icon_height.' . $mapProvider,
48 | 'description' => $ll . 'sys_category.maps2_marker_icon_height.' . $mapProvider . '.description',
49 | 'config' => [
50 | 'type' => 'number',
51 | 'format' => 'integer',
52 | ],
53 | ],
54 | 'maps2_marker_icon_anchor_pos_x' => [
55 | 'exclude' => true,
56 | 'label' => $ll . 'sys_category.maps2_marker_icon_anchor_pos_x.' . $mapProvider,
57 | 'description' => $ll . 'sys_category.maps2_marker_icon_anchor_pos_x.' . $mapProvider . '.description',
58 | 'config' => [
59 | 'type' => 'number',
60 | 'format' => 'integer',
61 | ],
62 | ],
63 | 'maps2_marker_icon_anchor_pos_y' => [
64 | 'exclude' => true,
65 | 'label' => $ll . 'sys_category.maps2_marker_icon_anchor_pos_y.' . $mapProvider,
66 | 'description' => $ll . 'sys_category.maps2_marker_icon_anchor_pos_y.' . $mapProvider . '.description',
67 | 'config' => [
68 | 'type' => 'number',
69 | 'format' => 'integer',
70 | ],
71 | ],
72 | ];
73 |
74 | ExtensionManagementUtility::addTCAcolumns('sys_category', $newSysCategoryColumn);
75 | ExtensionManagementUtility::addToAllTCAtypes(
76 | 'sys_category',
77 | '--div--;LLL:EXT:maps2/Resources/Private/Language/locallang_db.xlf:tab.maps2.' . $mapHelper->getMapProvider() . ', maps2_marker_icons, maps2_marker_icon_width, maps2_marker_icon_height, maps2_marker_icon_anchor_pos_x, maps2_marker_icon_anchor_pos_y',
78 | );
79 | });
80 |
--------------------------------------------------------------------------------
/Configuration/TCA/Overrides/sys_template.php:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jweiland-net/maps2/ba4cd77780f5e50c9070a26ad45f1e787868061e/Configuration/TCA/Overrides/sys_template.php
--------------------------------------------------------------------------------
/Configuration/TCA/Overrides/tt_content.php:
--------------------------------------------------------------------------------
1 | getMapProvider();
26 |
27 | // Set default for poi collection type
28 | $GLOBALS['TCA']['tx_maps2_domain_model_poicollection']['columns']['collection_type']['config']['default']
29 | = $extConf->getDefaultMapType();
30 |
31 | // Set latitude/longitude to float representation of extension configuration
32 | $GLOBALS['TCA']['tx_maps2_domain_model_poicollection']['columns']['latitude']['config']['default'] = number_format(
33 | $extConf->getDefaultLatitude(),
34 | 6,
35 | );
36 | $GLOBALS['TCA']['tx_maps2_domain_model_poicollection']['columns']['longitude']['config']['default'] = number_format(
37 | $extConf->getDefaultLongitude(),
38 | 6,
39 | );
40 |
41 | // If both map providers are allowed in ExtensionManager we have to add a selectbox for map provider to TCA
42 | if ($extConf->getMapProvider() === 'both') {
43 | ExtensionManagementUtility::addToAllTCAtypes(
44 | 'tx_maps2_domain_model_poicollection',
45 | 'map_provider',
46 | '',
47 | 'before:configuration_map',
48 | );
49 | }
50 | });
51 |
--------------------------------------------------------------------------------
/Documentation/AdministratorManual/Index.rst:
--------------------------------------------------------------------------------
1 | .. include:: /Includes.rst.txt
2 |
3 |
4 | .. _admin-manual:
5 |
6 | ====================
7 | Administrator manual
8 | ====================
9 |
10 | .. only:: html
11 |
12 | This chapter describes how to manage the extension from a superuser point of view.
13 |
14 | .. toctree::
15 | :maxdepth: 2
16 | :titlesonly:
17 |
18 | GoogleApiKeys/Index
19 | Routing/Index
20 | Upgrade/Index
21 | Templates/Index
22 |
--------------------------------------------------------------------------------
/Documentation/AdministratorManual/Routing/Index.rst:
--------------------------------------------------------------------------------
1 | .. include:: /Includes.rst.txt
2 |
3 |
4 | .. _routing:
5 |
6 | =======
7 | Routing
8 | =======
9 |
10 | `EXT:maps2` does not have a list and detail view, so there is no need to
11 | configure any route enhancers. But, it is possible to link to a POI
12 | from foreign extensions. That is possible by defining the PoiCollection
13 | UID as GET parameter `tx_maps2_maps2[poiCollectionUid]` in URI.
14 |
15 | For this case you can use following configuration.
16 |
17 | .. hint::
18 |
19 | As PoiCollection records do NOT have any slug column defined, we really
20 | prefer to use just the UID of the record. Please prevent the usage of
21 | any title column as that may lead to unexpected escaping problems in URI.
22 | If you really want to use a title please create a slug column on your own
23 | and reference that column in aspect yourself.
24 |
25 | Example Configuration
26 | =====================
27 |
28 | .. code-block:: yaml
29 |
30 | routeEnhancers:
31 | Maps2Plugin:
32 | type: Extbase
33 | extension: Maps2
34 | plugin: Maps2
35 | routes:
36 | -
37 | routePath: '/poi/{poiCollectionUid}'
38 | _controller: 'PoiCollection::show'
39 | defaultController: 'PoiCollection::show'
40 | aspects:
41 | poiCollectionUid:
42 | type: PersistedAliasMapper
43 | tableName: 'tx_maps2_domain_model_poicollection'
44 | routeFieldName: 'uid'
45 |
--------------------------------------------------------------------------------
/Documentation/AdministratorManual/Templates/Index.rst:
--------------------------------------------------------------------------------
1 | .. include:: /Includes.rst.txt
2 |
3 |
4 | =========
5 | Templates
6 | =========
7 |
8 | .. only:: html
9 |
10 | This chapter is all about templating EXT:maps2
11 |
12 | .. toctree::
13 | :maxdepth: 2
14 | :titlesonly:
15 |
16 | Start/Index
17 | ViewHelpers/Index
18 |
--------------------------------------------------------------------------------
/Documentation/AdministratorManual/Templates/Start/Index.rst:
--------------------------------------------------------------------------------
1 | .. include:: /Includes.rst.txt
2 |
3 |
4 | ============================
5 | Changing & editing templates
6 | ============================
7 |
8 | EXT:maps2 is using fluid as template engine. If you are know how to manage fluid
9 | templates, you can skip this section.
10 |
11 |
12 | Changing paths of the template
13 | ==============================
14 |
15 | You should never edit the original templates of an extension as those changes
16 | will vanish if you upgrade the extension. As any extbase based extension, you
17 | can find the templates in the directory ``Resources/Private/``.
18 |
19 | If you want to change a template, copy the desired files to the directory where
20 | you store the templates. This should be a directory in your SitePackage
21 | extension. Multiple fallbacks can be defined which makes it far easier to
22 | customize the templates.
23 |
24 | .. code-block:: typoscript
25 |
26 | plugin.tx_maps2 {
27 | view {
28 | templateRootPaths >
29 | templateRootPaths {
30 | 0 = EXT:maps2/Resources/Private/Templates/
31 | 1 = EXT:site_package/Resources/Private/Extensions/Maps2/Templates/
32 | }
33 | partialRootPaths >
34 | partialRootPaths {
35 | 0 = EXT:maps2/Resources/Private/Partials/
36 | 1 = EXT:site_package/Resources/Private/Extensions/Maps2/Partials/
37 | }
38 | layoutRootPaths >
39 | layoutRootPaths {
40 | 0 = EXT:maps2/Resources/Private/Layouts/
41 | 1 = EXT:site_package/Resources/Private/Extensions/Maps2/Templates/Layouts/
42 | }
43 | }
44 | }
45 |
46 | Change the templates using TypoScript constants
47 | -----------------------------------------------
48 |
49 | You can use the following TypoScript in the **constants** to change
50 | the paths
51 |
52 | .. code-block:: typoscript
53 |
54 | plugin.tx_maps2 {
55 | view {
56 | templateRootPath = EXT:site_package/Resources/Private/Extensions/Maps2/Templates/
57 | partialRootPath = EXT:site_package/Resources/Private/Extensions/Maps2/Partials/
58 | layoutRootPath = EXT:site_package/Resources/Private/Extensions/Maps2/Layouts/
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/Documentation/AdministratorManual/Templates/ViewHelpers/Cache/GetCacheViewHelper.rst:
--------------------------------------------------------------------------------
1 | .. include:: /Includes.rst.txt
2 |
3 |
4 | ==========================
5 | Cache / GetCacheViewHelper
6 | ==========================
7 |
8 | This is a ViewHelper to retrieve a cache entry.
9 |
10 | General properties
11 | ==================
12 |
13 | .. confval-menu::
14 | :name: confval-get-cache
15 | :display: table
16 | :required:
17 | :type:
18 |
19 | .. confval:: prefix
20 | :name: get-cache-prefix
21 | :required: false
22 | :type: string
23 |
24 | If you want you can define a prefix for the generated CacheIdentifier. Leave
25 | this value empty to use "infoWindow" as default value
26 |
27 | .. confval:: poiCollection
28 | :name: get-cache-poiCollection
29 | :required: true
30 | :type: PoiCollection
31 |
32 | You must assign the PoiCollection object to this ViewHelper. We extract some
33 | data from PoiCollection to build a more unique CacheIdentifier which can differ
34 | Caches in multilingual environment.
35 |
36 | Examples
37 | ========
38 |
39 | Basic example
40 | -------------
41 |
42 | .. code-block:: html
43 |
44 | {maps2:cache.getCache(poiCollection: poiCollection)}
45 |
46 |
--------------------------------------------------------------------------------
/Documentation/AdministratorManual/Templates/ViewHelpers/Cache/HasCacheViewHelper.rst:
--------------------------------------------------------------------------------
1 | .. include:: /Includes.rst.txt
2 |
3 |
4 | ==========================
5 | Cache / HasCacheViewHelper
6 | ==========================
7 |
8 | This is a ViewHelper to check, if a cache entry exists.
9 |
10 | General properties
11 | ==================
12 |
13 | .. confval-menu::
14 | :name: confval-has-cache
15 | :display: table
16 | :required:
17 | :type:
18 |
19 | .. confval:: prefix
20 | :name: has-cache-prefix
21 | :required: false
22 | :type: string
23 |
24 | If you want you can define a prefix for the generated CacheIdentifier. Leave
25 | this value empty to use "infoWindow" as default value
26 |
27 | .. confval:: poiCollection
28 | :name: has-cache-poiCollection
29 | :required: true
30 | :type: PoiCollection
31 |
32 | You must assign the PoiCollection object to this ViewHelper. We extract some
33 | data from PoiCollection to build a more unique CacheIdentifier which can differ
34 | Caches in multilingual environment.
35 |
36 | Examples
37 | ========
38 |
39 | Basic example
40 | -------------
41 |
42 | .. code-block:: html
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/Documentation/AdministratorManual/Templates/ViewHelpers/Cache/SetCacheViewHelper.rst:
--------------------------------------------------------------------------------
1 | .. include:: /Includes.rst.txt
2 |
3 |
4 | ==========================
5 | Cache / SetCacheViewHelper
6 | ==========================
7 |
8 | This is a ViewHelper to set a new cache entry.
9 |
10 | General properties
11 | ==================
12 |
13 | .. confval-menu::
14 | :name: confval-set-cache
15 | :display: table
16 | :required:
17 | :type:
18 |
19 | .. confval:: prefix
20 | :name: set-cache-prefix
21 | :required: false
22 | :type: string
23 |
24 | If you want you can define a prefix for the generated CacheIdentifier. Leave
25 | this value empty to use "infoWindow" as default value
26 |
27 | .. confval:: poiCollection
28 | :name: set-cache-poiCollection
29 | :required: true
30 | :type: PoiCollection
31 |
32 | You must assign the PoiCollection object to this ViewHelper. We extract some
33 | data from PoiCollection to build a more unique CacheIdentifier which can differ
34 | Caches in multilingual environment.
35 |
36 | .. confval:: data
37 | :name: set-cache-data
38 | :required: true
39 | :type: string
40 |
41 | The data as string which has to be stored.
42 |
43 | .. confval:: tags
44 | :name: set-cache-tags
45 | :required: false
46 | :type: array
47 |
48 | You can define some additional CacheEntryTags if you want. By default we add
49 | two additional Cache Tags named `infoWindowUid{PoiCollectionUid}` and
50 | `infoWindowPid{PoiCollectionPid}`
51 |
52 | .. confval:: lifetime
53 | :name: set-cache-lifetime
54 | :required: false
55 | :type: int
56 |
57 | How long (in seconds) the CacheEntry should be available, before it will be
58 | re-generated? Keep this value empty to use the Default Value of Storage-Backend.
59 | 0 for unlimited.
60 |
61 |
62 | Examples
63 | ========
64 |
65 | Basic example
66 | -------------
67 |
68 | .. code-block:: html
69 |
70 | {maps2:cache.setCache(poiCollection: poiCollection, data: '{content->f:format.raw()}')}
71 |
--------------------------------------------------------------------------------
/Documentation/AdministratorManual/Templates/ViewHelpers/ConvertToJsonViewHelper.rst:
--------------------------------------------------------------------------------
1 | .. include:: /Includes.rst.txt
2 |
3 |
4 | =======================
5 | ConvertToJsonViewHelper
6 | =======================
7 |
8 | This is a ViewHelper to convert an array into JSON format.
9 |
10 | Examples
11 | ========
12 |
13 | Basic example
14 | -------------
15 |
16 | .. code-block:: html
17 |
18 |
19 |
--------------------------------------------------------------------------------
/Documentation/AdministratorManual/Templates/ViewHelpers/Index.rst:
--------------------------------------------------------------------------------
1 | .. include:: /Includes.rst.txt
2 |
3 |
4 | ========================
5 | ViewHelpers of EXT:maps2
6 | ========================
7 |
8 | ViewHelpers are used to add logic inside the view.
9 | There're basic things like if/else conditions, loops and so on. The system
10 | extension fluid has the most important ViewHelpers already included.
11 |
12 | To be able to use a ViewHelper in your template, you need to follow always the
13 | same structure which is:
14 |
15 | .. code-block:: html
16 |
17 | bar
18 |
19 | This would call the ViewHelper foo of the namespace **f** which stands for
20 | fluid. If you want to use ViewHelpers from other extensions you need to add the
21 | namespace declaration at the beginning of the template. Add or update following
22 | lines in your template, partial or layout:
23 |
24 | .. code-block:: html
25 |
26 |
30 |
31 | Now you can use a ViewHelper of maps2 with a code like:
32 |
33 | .. code-block:: html
34 |
35 |
36 |
37 | If you want to know what a ViewHelper does, it is very easy to find the related
38 | PHP class by looking at the namespace and the name of the ViewHelper. Having
39 | e.g. ``JWeiland\Maps2\ViewHelpers`` and ``convertToJson`` you will find the
40 | class at ``maps2\Classes\ViewHelpers\ConvertToJsonViewHelper.php``.
41 |
42 | The most awesome thing is that you can use ViewHelpers of any extension in any
43 | other template by just adding another namespace declaration like:
44 |
45 | .. code-block:: html
46 |
47 |
52 |
53 | and call the ViewHelper like
54 |
55 | .. code-block:: html
56 |
57 |
58 |
59 | All ViewHelpers
60 | ===============
61 |
62 | .. toctree::
63 | :maxdepth: 2
64 | :titlesonly:
65 | :glob:
66 |
67 | ConvertToJsonViewHelper
68 | IsRequestToMapProviderAllowedViewHelper
69 | RequestUriForOverlayViewHelper
70 | TrimExplodeViewHelper
71 |
72 | Cache/GetCacheViewHelper
73 | Cache/HasCacheViewHelper
74 | Cache/SetCacheViewHelper
75 |
--------------------------------------------------------------------------------
/Documentation/AdministratorManual/Templates/ViewHelpers/IsRequestToMapProviderAllowedViewHelper.rst:
--------------------------------------------------------------------------------
1 | .. include:: /Includes.rst.txt
2 |
3 |
4 | =======================================
5 | IsRequestToMapProviderAllowedViewHelper
6 | =======================================
7 |
8 | Use this ViewHelper to check user consent, if requests to map providers like
9 | Google Maps or OpenStreetMap are allowed or not.
10 |
11 |
12 | Examples
13 | ========
14 |
15 | Basic example
16 | -------------
17 |
18 | .. code-block:: html
19 |
20 |
21 |
22 | ...do something to show the map or what ever you want...
23 |
24 |
25 | ...show overlay or add a message what user should do to see the map...
26 |
27 |
28 |
--------------------------------------------------------------------------------
/Documentation/AdministratorManual/Templates/ViewHelpers/RequestUriForOverlayViewHelper.rst:
--------------------------------------------------------------------------------
1 | .. include:: /Includes.rst.txt
2 |
3 |
4 | ==============================
5 | RequestUriForOverlayViewHelper
6 | ==============================
7 |
8 | This ViewHelper creates an URI with a special parameter which allows the map to
9 | be visible for the user.
10 |
11 |
12 | Examples
13 | ========
14 |
15 | Basic example
16 | -------------
17 |
18 | .. code-block:: html
19 |
20 |
21 | Link to current page. Map will be shown somewhere on that page.
22 |
23 |
24 | Scroll to content element
25 | -------------------------
26 |
27 | If you add `ttContentUid` to ViewHelper it will add a link section (#174)
28 | to the end of the URI. If all of your content elements contain an `id` attribute
29 | like `c174` the target page will scroll to this specific content element
30 | directly.
31 |
32 | .. code-block:: html
33 |
34 |
35 | Link to current page and scroll to content element with map.
36 |
37 |
--------------------------------------------------------------------------------
/Documentation/AdministratorManual/Templates/ViewHelpers/TrimExplodeViewHelper.rst:
--------------------------------------------------------------------------------
1 | .. include:: /Includes.rst.txt
2 |
3 |
4 | =====================
5 | TrimExplodeViewHelper
6 | =====================
7 |
8 | This is a ViewHelper to convert a comma separated value into an array.
9 | All values will be trimmed.
10 |
11 | General properties
12 | ==================
13 |
14 | .. t3-field-list-table::
15 | :header-rows: 1
16 |
17 | - :Name: Name:
18 | :Type: Type:
19 | :Description: Description:
20 | :Default value: Default value:
21 |
22 | - :Name:
23 | \* delimiter
24 | :Type:
25 | string
26 | :Description:
27 | Delimiter
28 | :Default value:
29 | ,
30 |
31 | Examples
32 | ========
33 |
34 | Basic example
35 | -------------
36 |
37 | .. code-block:: html
38 |
39 |
40 | ..do something with {address}
41 |
42 |
--------------------------------------------------------------------------------
/Documentation/Configuration/Index.rst:
--------------------------------------------------------------------------------
1 | .. include:: /Includes.rst.txt
2 |
3 |
4 | .. _configuration:
5 |
6 | =============
7 | Configuration
8 | =============
9 |
10 | Minimal Example
11 | ===============
12 |
13 | .. hint::
14 |
15 | If you want to work with Google Maps in TYPO3 backend you or an
16 | administrator have to configure the Google Maps API keys in
17 | :ref:`Configure extension ` to get a working environment.
18 |
19 | * Include site set `Maps2 - Default Set` in "Sets for this Site" in your site.
20 | * include one of these site sets `Maps2 - Google Maps` or
21 | `Maps2 - Open Street Map` in "Sets for this Site" in your site.
22 |
23 | Update at least `Default storage PID` and `JavaScript API Key` settings of
24 | maps2 in Site Settings.
25 |
26 | .. toctree::
27 | :maxdepth: 2
28 |
29 | Extension/Index
30 | Plugins/Index
31 | TypoScript/Index
32 |
--------------------------------------------------------------------------------
/Documentation/DeveloperManual/Index.rst:
--------------------------------------------------------------------------------
1 | .. include:: /Includes.rst.txt
2 |
3 |
4 | .. _developer-manual:
5 |
6 | ================
7 | Developer manual
8 | ================
9 |
10 | This chapter describes how to manage the extension from a developer point
11 | of view.
12 |
13 | .. toctree::
14 | :maxdepth: 2
15 | :titlesonly:
16 |
17 | Api/Index
18 | Maps2Registry/Index
19 | Template/Index
20 |
--------------------------------------------------------------------------------
/Documentation/DeveloperManual/Template/Index.rst:
--------------------------------------------------------------------------------
1 | .. include:: /Includes.rst.txt
2 |
3 |
4 | .. _developer-template:
5 |
6 | ========
7 | Template
8 | ========
9 |
10 | With EXT:maps2 version 10.0.0 we have remove PoiCollection- and
11 | EditPoiCollection ViewHelper. This part will explain how to change your
12 | template to use the new implementation.
13 |
14 | PoiCollection
15 | =============
16 |
17 | Add static TS template `Maps2 Default (maps2)` and one of
18 | the `Maps2 for Google Maps (maps2)` or `Maps2 for Open Street Map (maps2)`
19 | templates to the page where your extension/plugin belongs to, as far as not
20 | already done in root page.
21 |
22 | In case of `Maps2 for Google Maps (maps2)`please check, if following
23 | TS constant is set:
24 |
25 | .. code-block:: typoscript
26 |
27 | plugin.tx_maps2.view.googleMapsJavaScriptApiKey
28 |
29 | Add a further entry for `maps2` to `partialRootPaths` configuration of your
30 | extension, so that fluid can find our new partials:
31 |
32 | .. code-block:: typoscript
33 |
34 | plugin.tx_myext.view.partialRootPaths {
35 | 0 = EXT:my_ext/Resources/Private/Partials/
36 | 1 = EXT:maps2/Resources/Private/Partials/
37 | }
38 |
39 | Replace old `maps2:widget.poiCollection` ViewHelper in templates of your
40 | extension:
41 |
42 | .. code-block:: html
43 |
44 |
45 |
46 | with following HTML:
47 |
48 | .. code-block:: html
49 |
50 |
53 |
54 |
55 | EditPoiCollection
56 | =================
57 |
58 | Add static TS template `Maps2 Default (maps2)` and one of the
59 | `Maps2 for Google Maps (maps2)` or `Maps2 for Open Street Map (maps2)` templates
60 | to the page where your extension/plugin belongs to, as far as not already done
61 | in root page.
62 |
63 | In case of `Maps2 for Google Maps (maps2)`please check, if following
64 | TS constant is set:
65 |
66 | .. code-block:: typoscript
67 |
68 | plugin.tx_maps2.view.googleMapsJavaScriptApiKey
69 |
70 | Add a further entry for `maps2` to `partialRootPaths` configuration of your
71 | extension, so that fluid can find our new partials:
72 |
73 | .. code-block:: typoscript
74 |
75 | plugin.tx_myext.view.partialRootPaths {
76 | 0 = EXT:my_ext/Resources/Private/Partials/
77 | 1 = EXT:maps2/Resources/Private/Partials/
78 | }
79 |
80 | Replace old `maps2:widget.editPoiCollection` ViewHelper in templates of your
81 | extension:
82 |
83 | .. code-block:: html
84 |
85 |
89 |
90 | with following html:
91 |
92 | .. code-block:: html
93 |
94 |
97 |
--------------------------------------------------------------------------------
/Documentation/Images/AdministratorManual/maps2-include-TypoScript.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jweiland-net/maps2/ba4cd77780f5e50c9070a26ad45f1e787868061e/Documentation/Images/AdministratorManual/maps2-include-TypoScript.png
--------------------------------------------------------------------------------
/Documentation/Images/GoogleApiKeys/WizardActivatedApis.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jweiland-net/maps2/ba4cd77780f5e50c9070a26ad45f1e787868061e/Documentation/Images/GoogleApiKeys/WizardActivatedApis.png
--------------------------------------------------------------------------------
/Documentation/Images/GoogleApiKeys/WizardPickProduct.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jweiland-net/maps2/ba4cd77780f5e50c9070a26ad45f1e787868061e/Documentation/Images/GoogleApiKeys/WizardPickProduct.png
--------------------------------------------------------------------------------
/Documentation/Images/GoogleApiKeys/WizardSelectProject.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jweiland-net/maps2/ba4cd77780f5e50c9070a26ad45f1e787868061e/Documentation/Images/GoogleApiKeys/WizardSelectProject.png
--------------------------------------------------------------------------------
/Documentation/Images/Introduction/maps2-type-Area.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jweiland-net/maps2/ba4cd77780f5e50c9070a26ad45f1e787868061e/Documentation/Images/Introduction/maps2-type-Area.png
--------------------------------------------------------------------------------
/Documentation/Images/Introduction/maps2-type-Point.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jweiland-net/maps2/ba4cd77780f5e50c9070a26ad45f1e787868061e/Documentation/Images/Introduction/maps2-type-Point.png
--------------------------------------------------------------------------------
/Documentation/Images/Introduction/maps2-type-Radius.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jweiland-net/maps2/ba4cd77780f5e50c9070a26ad45f1e787868061e/Documentation/Images/Introduction/maps2-type-Radius.png
--------------------------------------------------------------------------------
/Documentation/Images/Introduction/maps2-type-Route.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jweiland-net/maps2/ba4cd77780f5e50c9070a26ad45f1e787868061e/Documentation/Images/Introduction/maps2-type-Route.png
--------------------------------------------------------------------------------
/Documentation/Images/Typo3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jweiland-net/maps2/ba4cd77780f5e50c9070a26ad45f1e787868061e/Documentation/Images/Typo3.png
--------------------------------------------------------------------------------
/Documentation/Images/UserManual/BackendView.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jweiland-net/maps2/ba4cd77780f5e50c9070a26ad45f1e787868061e/Documentation/Images/UserManual/BackendView.png
--------------------------------------------------------------------------------
/Documentation/Includes.rst.txt:
--------------------------------------------------------------------------------
1 | .. More information about this file:
2 | https://docs.typo3.org/m/typo3/docs-how-to-document/main/en-us/GeneralConventions/FileStructure.html#includes-rst-txt
3 |
4 | .. ----------
5 | .. text roles
6 | .. ----------
7 |
8 | .. role:: aspect(emphasis)
9 | .. role:: bash(code)
10 | .. role:: html(code)
11 | .. role:: js(code)
12 | .. role:: php(code)
13 | .. role:: rst(code)
14 | .. role:: sep(strong)
15 | .. role:: sql(code)
16 | .. role:: ts(code)
17 | :class: typoscript
18 |
19 | .. role:: tsconfig(code)
20 | :class: typoscript
21 |
22 | .. role:: typoscript(code)
23 | .. role:: xml(code)
24 | :class: html
25 |
26 | .. role:: yaml(code)
27 |
28 | .. default-role:: code
29 |
30 | .. ---------
31 | .. highlight
32 | .. ---------
33 |
34 | .. By default, code blocks use PHP syntax highlighting
35 |
36 | .. highlight:: php
37 |
--------------------------------------------------------------------------------
/Documentation/Index.rst:
--------------------------------------------------------------------------------
1 | .. include:: /Includes.rst.txt
2 |
3 | .. _start:
4 |
5 | =====
6 | Maps2
7 | =====
8 |
9 | :Language:
10 | en
11 |
12 | :Version:
13 | |release|
14 |
15 | :Description:
16 | This TYPO3 extension supports the rendering of a map based on Google Maps or
17 | OpenStreetMap. The map can be additionally enriched with markers, routes,
18 | area and radius overlays and these overlays can be grouped into categories
19 | for easy and recurring assignment.
20 |
21 | :Keywords:
22 | typo3,TYPO3 CMS,google maps,osm,open street map,openstreetmap,maps2
23 |
24 | :Copyright:
25 | 2013-2021
26 |
27 | :Author:
28 | Stefan Froemken
29 |
30 | :Email:
31 | projects@jweiland.net
32 |
33 | :License:
34 | This document is published under the Open Content License
35 | available from http://www.opencontent.org/opl.shtml
36 |
37 | :Rendered:
38 | |today|
39 |
40 |
41 | .. toctree::
42 | :titlesonly:
43 |
44 | Introduction/Index
45 | Installation/Index
46 | Configuration/Index
47 | User/Index
48 | AdministratorManual/Index
49 | DeveloperManual/Index
50 | FAQ/Index
51 | ChangeLog/Index
52 |
--------------------------------------------------------------------------------
/Documentation/Installation/Index.rst:
--------------------------------------------------------------------------------
1 | .. include:: /Includes.rst.txt
2 |
3 |
4 | .. _installation:
5 |
6 | ============
7 | Installation
8 | ============
9 |
10 | Target group: **Administrators**
11 |
12 | .. contents::
13 | :backlinks: top
14 | :class: compact-list
15 | :depth: 1
16 | :local:
17 |
18 | .. _installation_composer:
19 |
20 | Composer mode
21 | =============
22 |
23 | If your TYPO3 installation uses Composer, install the latest release of this
24 | extension through:
25 |
26 | .. code-block:: bash
27 |
28 | composer require jweiland/maps2
29 |
30 | If you are not using the latest version, you need to
31 | add a version constraint, for example:
32 |
33 | .. code-block:: bash
34 |
35 | composer require jweiland/maps2:"^9.3"
36 |
37 | Installing the extension prior to TYPO3 11.4
38 | --------------------------------------------
39 |
40 | Before TYPO3 11.4 it was still necessary to manually activate extensions
41 | installed via Composer using the Extension Manager. Activate it as follows:
42 |
43 | * Navigate to :guilabel:`Admin Tools > Extensions > Installed Extensions`
44 | * Search for `maps2`
45 | * Activate the extension by clicking on the :guilabel:`Activate` button in the
46 | :guilabel:`A/D` column
47 |
48 |
49 | .. _installation_legacy:
50 |
51 | Legacy mode
52 | ===========
53 |
54 | If you are working with a TYPO3 installation that does not use Composer, install
55 | the extension in the Extension Manager:
56 |
57 | * Navigate to :guilabel:`Admin Tools > Extensions > Get Extensions`.
58 | * Click on :guilabel:`Update now`
59 | * Search for `maps2`
60 | * Click :guilabel:`Import and install` on the side of the extension entry
61 |
62 | and activate it:
63 |
64 | * Navigate to :guilabel:`Admin Tools > Extensions > Installed Extensions`
65 | * Search for `maps2`
66 | * Activate the extension by clicking on the :guilabel:`Activate` button in the
67 | :guilabel:`A/D` column
68 |
69 | .. seealso::
70 |
71 | On page `Installing extensions `_
72 | both TYPO3 installation modes are explained in detail.
73 |
74 | **Next step**
75 |
76 | Please edit ExtensionManager configuration of maps2 to decide, if you will use
77 | Google Maps or OpenStreetMap as your default rendering service:
78 | :ref:`Configure extension `.
79 |
--------------------------------------------------------------------------------
/Documentation/Introduction/Index.rst:
--------------------------------------------------------------------------------
1 | .. include:: /Includes.rst.txt
2 |
3 |
4 | .. _introduction:
5 |
6 | ============
7 | Introduction
8 | ============
9 |
10 |
11 | .. _what-it-does:
12 |
13 | What does it do?
14 | ================
15 |
16 | maps2 is an extension for TYPO3 CMS. It can render you a map based on Google Maps and/or OpenStreetMap. If you
17 | want, you can create Markers, Routes, Area and Radius overlays. Assign these overlays to categories to
18 | build a map, with all points based on selected category.
19 |
20 |
21 | .. _screenshots:
22 |
23 | Screenshots
24 | ===========
25 |
26 | See maps2 in action.
27 |
28 | Point
29 | -----
30 |
31 | .. figure:: ../Images/Introduction/maps2-type-Point.png
32 | :width: 500px
33 | :alt: Type: Point
34 |
35 | Introduction Package just after installation (caption of the image)
36 |
37 | How the Frontend of the Introduction Package looks like just after installation (legend of the image)
38 |
39 | Radius
40 | ------
41 |
42 | .. figure:: ../Images/Introduction/maps2-type-Radius.png
43 | :width: 500px
44 | :alt: Type: Radius
45 |
46 | Introduction Package just after installation (caption of the image)
47 |
48 | How the Frontend of the Introduction Package looks like just after installation (legend of the image)
49 |
50 | Area
51 | ----
52 |
53 | .. figure:: ../Images/Introduction/maps2-type-Area.png
54 | :width: 500px
55 | :alt: Type: Area
56 |
57 | Introduction Package just after installation (caption of the image)
58 |
59 | How the Frontend of the Introduction Package looks like just after installation (legend of the image)
60 |
61 | Route
62 | -----
63 |
64 | .. figure:: ../Images/Introduction/maps2-type-Route.png
65 | :width: 500px
66 | :alt: Type: Route
67 |
68 | Introduction Package just after installation (caption of the image)
69 |
70 | How the Frontend of the Introduction Package looks like just after installation (legend of the image)
71 |
--------------------------------------------------------------------------------
/Documentation/User/HowToStart/Index.rst:
--------------------------------------------------------------------------------
1 | .. include:: /Includes.rst.txt
2 |
3 |
4 | .. _howToStart:
5 |
6 | ============
7 | How to start
8 | ============
9 |
10 | This walkthrough will help you to implement the extension maps2 at your
11 | TYPO3 site. The installation is covered :ref:`here `.
12 |
13 | .. only:: html
14 |
15 | .. contents::
16 | :local:
17 | :depth: 1
18 |
19 | .. _howToStartCreateRecords:
20 |
21 | Create the records
22 | ==================
23 |
24 | Before any maps2 record can be shown in the frontend those need to be
25 | created.
26 |
27 | #. Create a new sysfolder.
28 | (Of course you can also use an existing sysfolder).
29 |
30 | #. Switch to **List module**
31 |
32 | #. Use the icon in the topbar "Create new record" and search for "Maps2" and
33 | its record "Marking".
34 |
35 | #. Click on "Marking" to create a new maps2 record.
36 |
37 | #. Give it a title (required)
38 |
39 | #. Choose a type of record you want to create. This will reload the form to
40 | show further fields especially for this record type. Alternative you can
41 | click on one of these type images to switch the type.
42 |
43 | #. After reload you should see some more tabs now. Click on tab "Map"
44 |
45 | #. Field "Address" is required, but you can not fill it. Please use the search
46 | field at top of map to search for an address and press . If an
47 | address was found, we will automatically fill the required address field
48 | in a formatted representation of the searched address.
49 |
50 | .. _howToStartAddPlugin:
51 |
52 | Add a plugin to a page
53 | ======================
54 |
55 | A plugin is used to render a defined selection of records in the frontend.
56 | Follow this steps to add a plugin to a page:
57 |
58 | Maps2: Show map - Plugin
59 | ------------------------
60 |
61 | #. Create a new page with a title like "Location" which will be used to show
62 | a Marking record.
63 |
64 | #. Add a new content element, switch to Tab "Plugins" and select the
65 | entry "Maps2: Show map"
66 |
67 | #. Change the 1 :sup:`st` field to one of your created Marking records.
68 |
69 | #. Save the plugin.
70 |
71 | Here are some more possible configuration of the plugin:
72 |
73 | If you leave marking and category field empty we will show all POIs of
74 | configured StorageFolder
75 |
76 | If you leave marking field empty, but select some categories we will show all
77 | POIs of selected category. As long as they are available in configured
78 | StorageFolder.
79 |
80 | If marking and category field is set, marking field has precedence.
81 |
82 | If there is a PoiCollection UID in URI this POI has precedence over marking and
83 | category settings.
84 |
85 | Info: If there will be shown more than one POI on the map it is not possible to
86 | set zoom anymore. We are working with the BoundedBox feature of Google Maps
87 | and OpenStreetMap to zoom out until all POIs are visible.
88 |
89 | Maps2: Search Radius - Plugin
90 | -----------------------------
91 |
92 | #. Create a new page with a title like "Radius Search" which will be used to
93 | show a form, where a website visitor can enter an address and a range to
94 | search for Markings.
95 |
96 | #. Add a new content element of type "General Plugin"
97 |
98 | #. Switch over to tab "Plugin" and select "Maps2: Search Radius" from selectbox
99 | "Selected Plugin"
100 |
101 | #. After reload go to Tab "Plugin" again and change the 1 :sup:`st` field to a
102 | location where you want to search. Something like "germany" or a city name.
103 |
104 | #. Save the plugin.
105 |
106 | Maps2: City Map - Plugin
107 | ------------------------
108 |
109 | #. Create a new page with a title like "City Map" which will be used to show
110 | a form, where a website visitor can enter a street name.
111 |
112 | #. Add a new content element of type "General Plugin"
113 |
114 | #. Switch over to tab "Plugin" and select "Maps2: City Map" from selectbox
115 | "Selected Plugin"
116 |
117 | #. After reload go to Tab "Plugin" again and Change the 1 :sup:`st` field to
118 | location where you want to search. Type in a city name and the results will
119 | be reduced to that city.
120 |
121 | #. Save the plugin.
122 |
--------------------------------------------------------------------------------
/Documentation/User/Index.rst:
--------------------------------------------------------------------------------
1 | .. include:: /Includes.rst.txt
2 |
3 |
4 | .. _userManual:
5 |
6 | ===========
7 | User manual
8 | ===========
9 |
10 | .. only:: html
11 |
12 | This chapter describes how to use the extension from a user point of view.
13 |
14 | The section "*Maps2Record*" lists all the fields of the record and
15 | "*HowToStart*" describes all available plugins.
16 |
17 | .. toctree::
18 | :maxdepth: 2
19 | :titlesonly:
20 |
21 | HowToStart/Index
22 | Maps2Record/Index
23 |
--------------------------------------------------------------------------------
/Documentation/guides.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # TYPO3 Extension `maps2`
2 |
3 | [![Packagist][packagist-logo-stable]][extension-packagist-url]
4 | [![Latest Stable Version][extension-build-shield]][extension-ter-url]
5 | [![Total Downloads][extension-downloads-badge]][extension-packagist-url]
6 | [![Monthly Downloads][extension-monthly-downloads]][extension-packagist-url]
7 | [![TYPO3 13.4][TYPO3-shield]][TYPO3-13-url]
8 |
9 | ![Build Status][extension-ci-shield]
10 |
11 | This TYPO3 extension supports the rendering of a map based on Google Maps or
12 | OpenStreetMap. The map can be additionally enriched with markers, routes,
13 | area and radius overlays and these overlays can be grouped into categories
14 | for easy and recurring assignment.
15 |
16 | | Type | URL |
17 | |--------------|-----------------------------------------------------|
18 | | Repository: | https://github.com/jweiland-net/maps2 |
19 | | Read online: | https://docs.typo3.org/p/jweiland/maps2/main/en-us/ |
20 | | TER: | https://extensions.typo3.org/extension/maps2 |
21 |
22 | [extension-build-shield]: https://poser.pugx.org/jweiland/maps2/v/stable.svg?style=for-the-badge
23 |
24 | [extension-ci-shield]: https://github.com/jweiland-net/maps2/actions/workflows/ci.yml/badge.svg
25 |
26 | [extension-downloads-badge]: https://poser.pugx.org/jweiland/maps2/d/total.svg?style=for-the-badge
27 |
28 | [extension-monthly-downloads]: https://poser.pugx.org/jweiland/maps2/d/monthly?style=for-the-badge
29 |
30 | [extension-ter-url]: https://extensions.typo3.org/extension/maps2/
31 |
32 | [extension-packagist-url]: https://packagist.org/packages/jweiland/maps2/
33 |
34 | [packagist-logo-stable]: https://img.shields.io/badge/--grey.svg?style=for-the-badge&logo=packagist&logoColor=white
35 |
36 | [TYPO3-13-url]: https://get.typo3.org/version/13
37 |
38 | [TYPO3-shield]: https://img.shields.io/badge/TYPO3-13.4-green.svg?style=for-the-badge&logo=typo3
39 |
--------------------------------------------------------------------------------
/Resources/Private/.htaccess:
--------------------------------------------------------------------------------
1 | deny from all
--------------------------------------------------------------------------------
/Resources/Private/Language/FlexForms.xlf:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | General
8 |
9 |
10 | Map Provider
11 |
12 |
13 | Which marking should be shown? If there is a marking defined in website uri, that one has priority.
14 |
15 |
16 | Show all markings of given categories. This will only work, if there is no marking in website uri nor if a marking is selected above.
17 |
18 |
19 | Append a fixed string to search value. Maybe a cityname. That way the user has only to insert a streetname.
20 |
21 |
22 | Map width
23 |
24 |
25 | Map height
26 |
27 |
28 |
29 | Map Options
30 |
31 |
32 | Default zoom
33 |
34 |
35 | Set a fix Zoomlevel if more than one POI will be displayed. Default: automatic zoomlevel to display all POIs.
36 |
37 |
38 | Show Zoom Control
39 |
40 |
41 | Show full screen Control
42 |
43 |
44 |
45 | Google Maps
46 |
47 |
48 | Default map view
49 |
50 |
51 | Hybrid
52 |
53 |
54 | Road Map
55 |
56 |
57 | Satellite
58 |
59 |
60 | Terrain
61 |
62 |
63 | Show Map Type Control
64 |
65 |
66 | Show Scale Control
67 |
68 |
69 | Show StreetView Control
70 |
71 |
72 | Activate zoom with mouse scroll wheel
73 |
74 |
75 | Map Style. Have a look at https://snazzymaps.com to copy some cool styles for you map
76 |
77 |
78 |
79 | Open Street Map
80 |
81 |
82 | Map Tile URI: Define another external provider to show map with another layout
83 |
84 |
85 | Map Tile Attribution: Each map needs to show the author attribution. Please check which Attribution has to be used for defined map tile above
86 |
87 |
88 |
89 |
90 |
--------------------------------------------------------------------------------
/Resources/Private/Language/locallang.xlf:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Google Maps
8 |
9 |
10 | The protection of your data is important for us.
11 |
12 |
13 | Click on "Activate" to allow us requesting google servers to show Google Maps.
14 |
15 |
16 | Activate
17 |
18 |
19 | Open Street Map
20 |
21 |
22 | The protection of your data is important for us.
23 |
24 |
25 | Click on "Activate" to allow us requesting Open Street Map servers to show map.
26 |
27 |
28 | Activate
29 |
30 |
31 | Insert address to search for
32 |
33 |
34 |
35 | latitude
36 |
37 |
38 | longitude
39 |
40 |
41 | Marking
42 |
43 |
44 | Title
45 |
46 |
47 |
48 | Address
49 |
50 |
51 | Radius
52 |
53 |
54 | Search
55 |
56 |
57 |
58 | Search for street
59 |
60 |
61 |
62 | No positions found
63 |
64 |
65 | %1$s can't find any position. Please check your input and try again
66 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/Resources/Private/Layouts/Default.html:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Resources/Private/Partials/InfoWindowContent.html:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
16 |
17 |
18 |
19 |
20 |
21 | {poiCollection.title}
22 |
23 |
24 |
25 |
26 |
27 | {address}
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | {poiCollection.info_window_content -> f:transform.html()}
36 |
37 |
38 |
--------------------------------------------------------------------------------
/Resources/Private/Partials/LoadAssets.html:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | ;
12 |
17 |
22 |
23 |
24 |
25 |
29 |
34 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/Resources/Private/Partials/Maps2/EditPoiCollection.html:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 | {environment.contentRecord.uid}
11 |
12 |
14 |
16 |
17 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/Resources/Private/Partials/Maps2/Overlay.html:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
{f:translate(key: 'LLL:EXT:maps2/Resources/Private/Language/locallang.xlf:{mapProvider}.map')}
8 |
9 | {f:translate(key: 'LLL:EXT:maps2/Resources/Private/Language/locallang.xlf:{mapProvider}.protectData')}
10 | {f:translate(key: 'LLL:EXT:maps2/Resources/Private/Language/locallang.xlf:{mapProvider}.explainActivation')}
11 |
12 |
13 |
14 | {f:translate(key: 'LLL:EXT:maps2/Resources/Private/Language/locallang.xlf:{mapProvider}.activate')}
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/Resources/Private/Partials/Maps2/PoiCollection.html:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
21 |
22 |
23 | {environment.settings.mapProvider}
24 | {environment.contentRecord.uid}
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/Resources/Private/Templates/CityMap/Search.html:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
26 |
27 |
32 |
33 |
--------------------------------------------------------------------------------
/Resources/Private/Templates/CityMap/Show.html:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
19 |
21 |
22 |
--------------------------------------------------------------------------------
/Resources/Private/Templates/InfoWindowContent.html:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 | {m:cache.getCache(poiCollection: poiCollection)}
9 |
10 |
11 |
12 |
13 |
14 |
15 | {content -> f:format.raw()}
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/Resources/Private/Templates/InfoWindowContentNoCache.html:
--------------------------------------------------------------------------------
1 |
5 |
6 |
11 |
12 |
13 |
14 |
15 |
16 | {content -> f:format.raw()}
17 |
18 |
--------------------------------------------------------------------------------
/Resources/Private/Templates/PluginPreview/Maps2.html:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 | Config |
10 | Value |
11 |
12 |
13 |
14 |
15 | Plugin |
16 | {pluginName} |
17 |
18 |
19 |
20 | POI collection |
21 | {poiCollectionRecord.title} ({poiCollectionRecord.uid}) |
22 |
23 |
24 |
25 |
26 | Categories |
27 | {pi_flexform_transformed.settings.categories} |
28 |
29 |
30 |
31 |
32 | Size |
33 | {pi_flexform_transformed.settings.mapWidth} * {pi_flexform_transformed.settings.mapHeight} |
34 |
35 |
36 |
37 |
38 | Zoom |
39 | {pi_flexform_transformed.settings.zoom} |
40 |
41 |
42 |
43 |
44 | Storages |
45 | {pages} |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/Resources/Private/Templates/PoiCollection/ListRadius.html:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
18 |
19 |
20 | Sorry, there are no results within your given radius
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/Resources/Private/Templates/PoiCollection/Overlay.html:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 | {settings.mapProvider}
8 | {data.uid}
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Resources/Private/Templates/PoiCollection/Search.html:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
18 |
19 |
20 |
21 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/Resources/Private/Templates/PoiCollection/Show.html:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/Resources/Private/Templates/Tca/GoogleMaps.html:
--------------------------------------------------------------------------------
1 |
4 |
5 |
7 |
9 |
10 |
11 | Place ID
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/Resources/Private/Templates/Tca/OpenStreetMap.html:
--------------------------------------------------------------------------------
1 |
9 |
10 |
12 |
--------------------------------------------------------------------------------
/Resources/Public/Css/GoogleMapsModule.css:
--------------------------------------------------------------------------------
1 | .controls {
2 | background-color: #fff;
3 | border-radius: 2px;
4 | border: 1px solid transparent;
5 | box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
6 | box-sizing: border-box;
7 | font-family: Roboto, Verdana, sans-serif;
8 | font-size: 15px;
9 | font-weight: 300;
10 | height: 29px;
11 | margin-left: 17px;
12 | margin-top: 10px;
13 | outline: none;
14 | padding: 0 11px 0 13px;
15 | text-overflow: ellipsis;
16 | width: 400px;
17 | }
18 |
19 | .controls:focus {
20 | border-color: #4d90fe;
21 | }
22 | .title {
23 | font-weight: bold;
24 | }
25 | #infowindow-content {
26 | display: none;
27 | }
28 | #maps2ConfigurationMap #infowindow-content {
29 | display: inline;
30 | }
31 |
--------------------------------------------------------------------------------
/Resources/Public/Css/Leaflet/images/layers-2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jweiland-net/maps2/ba4cd77780f5e50c9070a26ad45f1e787868061e/Resources/Public/Css/Leaflet/images/layers-2x.png
--------------------------------------------------------------------------------
/Resources/Public/Css/Leaflet/images/layers.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jweiland-net/maps2/ba4cd77780f5e50c9070a26ad45f1e787868061e/Resources/Public/Css/Leaflet/images/layers.png
--------------------------------------------------------------------------------
/Resources/Public/Css/Leaflet/images/marker-icon-2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jweiland-net/maps2/ba4cd77780f5e50c9070a26ad45f1e787868061e/Resources/Public/Css/Leaflet/images/marker-icon-2x.png
--------------------------------------------------------------------------------
/Resources/Public/Css/Leaflet/images/marker-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jweiland-net/maps2/ba4cd77780f5e50c9070a26ad45f1e787868061e/Resources/Public/Css/Leaflet/images/marker-icon.png
--------------------------------------------------------------------------------
/Resources/Public/Css/Leaflet/images/marker-shadow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jweiland-net/maps2/ba4cd77780f5e50c9070a26ad45f1e787868061e/Resources/Public/Css/Leaflet/images/marker-shadow.png
--------------------------------------------------------------------------------
/Resources/Public/Icons/Extension.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Resources/Public/Icons/MarkerClusterer/m1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jweiland-net/maps2/ba4cd77780f5e50c9070a26ad45f1e787868061e/Resources/Public/Icons/MarkerClusterer/m1.png
--------------------------------------------------------------------------------
/Resources/Public/Icons/MarkerClusterer/m2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jweiland-net/maps2/ba4cd77780f5e50c9070a26ad45f1e787868061e/Resources/Public/Icons/MarkerClusterer/m2.png
--------------------------------------------------------------------------------
/Resources/Public/Icons/MarkerClusterer/m3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jweiland-net/maps2/ba4cd77780f5e50c9070a26ad45f1e787868061e/Resources/Public/Icons/MarkerClusterer/m3.png
--------------------------------------------------------------------------------
/Resources/Public/Icons/MarkerClusterer/m4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jweiland-net/maps2/ba4cd77780f5e50c9070a26ad45f1e787868061e/Resources/Public/Icons/MarkerClusterer/m4.png
--------------------------------------------------------------------------------
/Resources/Public/Icons/MarkerClusterer/m5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jweiland-net/maps2/ba4cd77780f5e50c9070a26ad45f1e787868061e/Resources/Public/Icons/MarkerClusterer/m5.png
--------------------------------------------------------------------------------
/Resources/Public/Icons/RecordTypeArea.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jweiland-net/maps2/ba4cd77780f5e50c9070a26ad45f1e787868061e/Resources/Public/Icons/RecordTypeArea.png
--------------------------------------------------------------------------------
/Resources/Public/Icons/RecordTypePoint.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jweiland-net/maps2/ba4cd77780f5e50c9070a26ad45f1e787868061e/Resources/Public/Icons/RecordTypePoint.png
--------------------------------------------------------------------------------
/Resources/Public/Icons/RecordTypeRadius.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jweiland-net/maps2/ba4cd77780f5e50c9070a26ad45f1e787868061e/Resources/Public/Icons/RecordTypeRadius.png
--------------------------------------------------------------------------------
/Resources/Public/Icons/RecordTypeRoute.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jweiland-net/maps2/ba4cd77780f5e50c9070a26ad45f1e787868061e/Resources/Public/Icons/RecordTypeRoute.png
--------------------------------------------------------------------------------
/Resources/Public/Icons/TypeSelectArea.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jweiland-net/maps2/ba4cd77780f5e50c9070a26ad45f1e787868061e/Resources/Public/Icons/TypeSelectArea.png
--------------------------------------------------------------------------------
/Resources/Public/Icons/TypeSelectPoint.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jweiland-net/maps2/ba4cd77780f5e50c9070a26ad45f1e787868061e/Resources/Public/Icons/TypeSelectPoint.png
--------------------------------------------------------------------------------
/Resources/Public/Icons/TypeSelectRadius.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jweiland-net/maps2/ba4cd77780f5e50c9070a26ad45f1e787868061e/Resources/Public/Icons/TypeSelectRadius.png
--------------------------------------------------------------------------------
/Resources/Public/Icons/TypeSelectRoute.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jweiland-net/maps2/ba4cd77780f5e50c9070a26ad45f1e787868061e/Resources/Public/Icons/TypeSelectRoute.png
--------------------------------------------------------------------------------
/Resources/Public/Icons/marker.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jweiland-net/maps2/ba4cd77780f5e50c9070a26ad45f1e787868061e/Resources/Public/Icons/marker.png
--------------------------------------------------------------------------------
/Resources/Public/Icons/marker.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Resources/Public/Icons/plugin_wizard.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
--------------------------------------------------------------------------------
/Resources/Public/Icons/relation.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jweiland-net/maps2/ba4cd77780f5e50c9070a26ad45f1e787868061e/Resources/Public/Icons/relation.gif
--------------------------------------------------------------------------------
/Resources/Public/Icons/tx_maps2_domain_model_poi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jweiland-net/maps2/ba4cd77780f5e50c9070a26ad45f1e787868061e/Resources/Public/Icons/tx_maps2_domain_model_poi.png
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jweiland/maps2",
3 | "description": "Create maps with Marker, Area, Routes or Radius based on Google Maps or OpenStreetMap",
4 | "license": "GPL-2.0-or-later",
5 | "type": "typo3-cms-extension",
6 | "keywords": [
7 | "typo3",
8 | "TYPO3 CMS",
9 | "google maps",
10 | "osm",
11 | "open street map",
12 | "openstreetmap",
13 | "maps2"
14 | ],
15 | "authors": [
16 | {
17 | "name": "Stefan Froemken",
18 | "email": "sfroemken@jweiland.net",
19 | "role": "Lead Developer"
20 | }
21 | ],
22 | "homepage": "https://jweiland.net/",
23 | "support": {
24 | "email": "projects@jweiland.net",
25 | "issues": "https://github.com/jweiland-net/maps2/issues",
26 | "source": "https://github.com/jweiland-net/maps2",
27 | "docs": "https://docs.typo3.org/p/jweiland/maps2/main/en-us/"
28 | },
29 | "require": {
30 | "ext-json": "*",
31 | "typo3/cms-core": "^13.4.0"
32 | },
33 | "require-dev": {
34 | "ergebnis/composer-normalize": "^2.44",
35 | "sjbr/static-info-tables": "^13.4",
36 | "typo3/coding-standards": "^0.8",
37 | "typo3/testing-framework": "^9.0.1"
38 | },
39 | "suggest": {
40 | "sjbr/static-info-tables": "Install this package, if you want to choose from contained countries instead of typing them"
41 | },
42 | "autoload": {
43 | "psr-4": {
44 | "JWeiland\\Maps2\\": "Classes"
45 | }
46 | },
47 | "autoload-dev": {
48 | "psr-4": {
49 | "JWeiland\\Maps2\\Tests\\": "Tests"
50 | }
51 | },
52 | "config": {
53 | "allow-plugins": {
54 | "ergebnis/composer-normalize": true,
55 | "typo3/class-alias-loader": true,
56 | "typo3/cms-composer-installers": true
57 | },
58 | "bin-dir": ".Build/bin",
59 | "vendor-dir": ".Build/vendor"
60 | },
61 | "extra": {
62 | "typo3/cms": {
63 | "app-dir": ".Build",
64 | "extension-key": "maps2",
65 | "web-dir": ".Build/Web"
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/ext_conf_template.txt:
--------------------------------------------------------------------------------
1 | # cat=basic; type=options[LLL:EXT:maps2/Resources/Private/Language/ExtConf.xlf:mapProvider.both=both,Google=gm,Open Street Map=osm]; label=LLL:EXT:maps2/Resources/Private/Language/ExtConf.xlf:mapProvider
2 | mapProvider = both
3 | # cat=basic; type=options[Google=gm,OpenStreetMap=osm]; label=LLL:EXT:maps2/Resources/Private/Language/ExtConf.xlf:defaultMapProvider
4 | defaultMapProvider = gm
5 | # cat=basic; type=options[Empty=Empty,Point=Point,Radius=Radius,Area=Area,Route=Route]; label=LLL:EXT:maps2/Resources/Private/Language/ExtConf.xlf:defaultMapType
6 | defaultMapType = Empty
7 | # cat=basic; type=string; label=LLL:EXT:maps2/Resources/Private/Language/ExtConf.xlf:defaultCountry
8 | defaultCountry =
9 | # cat=basic; type=string; label=LLL:EXT:maps2/Resources/Private/Language/ExtConf.xlf:defaultLatitude
10 | defaultLatitude =
11 | # cat=basic; type=string; label=LLL:EXT:maps2/Resources/Private/Language/ExtConf.xlf:defaultLongitude
12 | defaultLongitude =
13 | # cat=basic; type=int+; label=LLL:EXT:maps2/Resources/Private/Language/ExtConf.xlf:defaultRadius
14 | defaultRadius = 250
15 | # cat=basic; type=boolean; label=LLL:EXT:maps2/Resources/Private/Language/ExtConf.xlf:explicitAllowMapProviderRequests
16 | explicitAllowMapProviderRequests = 0
17 | # cat=basic; type=boolean; label=LLL:EXT:maps2/Resources/Private/Language/ExtConf.xlf:explicitAllowMapProviderRequestsBySessionOnly
18 | explicitAllowMapProviderRequestsBySessionOnly = 0
19 |
20 | # cat=gm; type=wrap; label=LLL:EXT:maps2/Resources/Private/Language/ExtConf.xlf:googleMapsLibrary
21 | googleMapsLibrary = https://maps.googleapis.com/maps/api/js?key=|&libraries=places
22 | # cat=gm; type=string; label=LLL:EXT:maps2/Resources/Private/Language/ExtConf.xlf:googleMapsGeocodeUri
23 | googleMapsGeocodeUri = https://maps.googleapis.com/maps/api/geocode/json?address=%s&key=%s
24 | # cat=gm; type=string; label=LLL:EXT:maps2/Resources/Private/Language/ExtConf.xlf:googleMapsApiKey
25 | googleMapsJavaScriptApiKey =
26 | # cat=gm; type=string; label=LLL:EXT:maps2/Resources/Private/Language/ExtConf.xlf:googleGeocodeApiKey
27 | googleMapsGeocodeApiKey =
28 |
29 | # cat=osm; type=string; label=LLL:EXT:maps2/Resources/Private/Language/ExtConf.xlf:openStreetMapGeocodeUri
30 | openStreetMapGeocodeUri = https://nominatim.openstreetmap.org/search?q=%s&format=json&addressdetails=1
31 |
32 | # cat=design/color; type=string; label=LLL:EXT:maps2/Resources/Private/Language/ExtConf.xlf:strokeColor
33 | strokeColor = #FF0000
34 | # cat=design/color; type=string; label=LLL:EXT:maps2/Resources/Private/Language/ExtConf.xlf:strokeOpacity
35 | strokeOpacity = 0.8
36 | # cat=design/color; type=int+; label=LLL:EXT:maps2/Resources/Private/Language/ExtConf.xlf:strokeWeight
37 | strokeWeight = 2
38 | # cat=design/color; type=string; label=LLL:EXT:maps2/Resources/Private/Language/ExtConf.xlf:fillColor
39 | fillColor = #FF0000
40 | # cat=design/color; type=string; label=LLL:EXT:maps2/Resources/Private/Language/ExtConf.xlf:fillOpacity
41 | fillOpacity = 0.35
42 | # cat=design; type=int+; label=LLL:EXT:maps2/Resources/Private/Language/ExtConf.xlf:markerIconWidth
43 | markerIconWidth = 25
44 | # cat=design; type=int+; label=LLL:EXT:maps2/Resources/Private/Language/ExtConf.xlf:markerIconHeight
45 | markerIconHeight = 40
46 | # cat=design; type=int+; label=LLL:EXT:maps2/Resources/Private/Language/ExtConf.xlf:markerIconAnchorPosX
47 | markerIconAnchorPosX = 13
48 | # cat=design; type=int+; label=LLL:EXT:maps2/Resources/Private/Language/ExtConf.xlf:markerIconAnchorPosY
49 | markerIconAnchorPosY = 40
50 |
--------------------------------------------------------------------------------
/ext_emconf.php:
--------------------------------------------------------------------------------
1 | 'Maps2',
12 | 'description' => 'Create maps with Marker, Area, Routes or Radius based on Google Maps or OpenStreetMap',
13 | 'version' => '12.0.8',
14 | 'category' => 'plugin',
15 | 'state' => 'stable',
16 | 'author' => 'Stefan Froemken',
17 | 'author_email' => 'projects@jweiland.net',
18 | 'author_company' => 'jweiland.net',
19 | 'constraints' => [
20 | 'depends' => [
21 | 'typo3' => '13.4.0-13.4.99',
22 | ],
23 | 'conflicts' => [
24 | ],
25 | 'suggests' => [
26 | 'static_info_tables' => '13.4.0-13.99.99',
27 | ],
28 | ],
29 | ];
30 |
--------------------------------------------------------------------------------
/ext_localconf.php:
--------------------------------------------------------------------------------
1 | 'show',
28 | ],
29 | [],
30 | ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT,
31 | );
32 |
33 | ExtensionUtility::configurePlugin(
34 | 'Maps2',
35 | 'Overlay',
36 | [
37 | PoiCollectionController::class => 'overlay',
38 | ],
39 | [
40 | PoiCollectionController::class => 'overlay',
41 | ],
42 | ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT,
43 | );
44 |
45 | ExtensionUtility::configurePlugin(
46 | 'Maps2',
47 | 'SearchWithinRadius',
48 | [
49 | PoiCollectionController::class => 'search, listRadius',
50 | ],
51 | [
52 | PoiCollectionController::class => 'listRadius',
53 | ],
54 | ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT,
55 | );
56 |
57 | ExtensionUtility::configurePlugin(
58 | 'Maps2',
59 | 'CityMap',
60 | [
61 | CityMapController::class => 'show, search',
62 | ],
63 | [
64 | CityMapController::class => 'search',
65 | ],
66 | ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT,
67 | );
68 |
69 | // Activate caching for info window content
70 | if (!isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['maps2_cachedhtml'])) {
71 | $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['maps2_cachedhtml'] = [
72 | 'groups' => ['pages', 'all'],
73 | ];
74 | }
75 |
76 | // This is a solution to build GET forms.
77 | $GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludedParameters']['maps2'] = 'tx_maps2_citymap[street]';
78 |
79 | // Create maps2 records while saving foreign records
80 | $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processDatamapClass']['createMaps2Record']
81 | = CreateMaps2RecordHook::class;
82 |
83 | $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeRegistry'][1530778687] = [
84 | 'nodeName' => 'maps2InfoWindowContent',
85 | 'priority' => 40,
86 | 'class' => InfoWindowContent::class,
87 | ];
88 | $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeRegistry'][1633612058] = [
89 | 'nodeName' => 'maps2ReadOnlyInputText',
90 | 'priority' => 40,
91 | 'class' => ReadOnlyInputTextElement::class,
92 | ];
93 | $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeResolver'][1551448205] = [
94 | 'nodeName' => 'maps2MapProvider',
95 | 'priority' => 40,
96 | 'class' => MapProviderResolver::class,
97 | ];
98 | });
99 |
--------------------------------------------------------------------------------
/ext_tables.sql:
--------------------------------------------------------------------------------
1 | #
2 | # Table structure for table 'tx_maps2_domain_model_poicollection'
3 | #
4 | CREATE TABLE tx_maps2_domain_model_poicollection
5 | (
6 | configuration_map text,
7 | latitude numeric(11, 6) DEFAULT '0.000000' NOT NULL,
8 | longitude numeric(11, 6) DEFAULT '0.000000' NOT NULL,
9 | );
10 |
--------------------------------------------------------------------------------