278 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			278 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| 
 | |
| /**
 | |
|  * @author          Tassos Marinos <info@tassos.gr>
 | |
|  * @link            https://www.tassos.gr
 | |
|  * @copyright       Copyright © 2024 Tassos All Rights Reserved
 | |
|  * @license         GNU GPLv3 <http://www.gnu.org/licenses/gpl.html> or later
 | |
|  */
 | |
| 
 | |
| namespace NRFramework\Widgets;
 | |
| 
 | |
| defined('_JEXEC') or die;
 | |
| 
 | |
| use Joomla\CMS\Language\Text;
 | |
| use Joomla\CMS\Uri\Uri;
 | |
| use Joomla\CMS\HTML\HTMLHelper;
 | |
| use Joomla\CMS\Router\Route;
 | |
| 
 | |
| abstract class Map extends Widget
 | |
| {
 | |
| 	/**
 | |
| 	 * Widget default options
 | |
| 	 *
 | |
| 	 * @var array
 | |
| 	 */
 | |
| 	protected $widget_options = [
 | |
| 		/**
 | |
| 		 * The value of the widget.
 | |
| 		 * Format: latitude,longitude
 | |
| 		 * 
 | |
| 		 * i.e. 36.891319,27.283480
 | |
| 		 * 
 | |
| 		 * Otherwise, set the markers property
 | |
| 		 */
 | |
| 		'value' => '',
 | |
| 
 | |
| 		// Map tile provider key (if needed) to use the provider tiles
 | |
| 		'provider_key' => null,
 | |
| 
 | |
| 		// Default map width
 | |
| 		'width' => 500,
 | |
| 
 | |
| 		// Default map height
 | |
| 		'height' => 400,
 | |
| 
 | |
| 		/**
 | |
| 		 * The Zoom Level.
 | |
| 		 * 
 | |
| 		 * - preset: Set a fixed zoom.
 | |
| 		 * - fitbounds: Allow the map provider to auto-zoom and center the map around the markers.
 | |
| 		 */
 | |
| 		'zoom_level' => 'preset',
 | |
| 
 | |
| 		// Default map zoon
 | |
| 		'zoom' => 4,
 | |
| 
 | |
| 		// Define lat,long format which will be used to center the map when zoom_level=preset is used.
 | |
| 		'map_center' => null,
 | |
| 
 | |
| 		// Map scale. Values: metric, imperial, false
 | |
| 		'scale' => false,
 | |
| 
 | |
| 		// View mode of the map.
 | |
| 		'view' => '',
 | |
| 
 | |
| 		/**
 | |
| 		 * Set whether to show or not the map marker info window.
 | |
| 		 * 
 | |
| 		 * Defaults to the map marker address (if not empty).
 | |
| 		 * If a map makrer label and/or description is set, these will be used.
 | |
| 		 */
 | |
| 		'enable_info_window' => true,
 | |
| 		
 | |
| 		/**
 | |
| 		 * Map Marker
 | |
| 		 */
 | |
| 		/**
 | |
| 		 * The markers.
 | |
| 		 * 
 | |
| 		 * An array of markers.
 | |
| 		 * 
 | |
| 		 * [
 | |
| 		 * 	  [
 | |
| 		 * 	  	  latitude: 36.891319,
 | |
| 		 * 	  	  longitude: 27.283480,
 | |
| 		 * 	  	  label: 'Marker label',
 | |
| 		 * 	  	  description: 'Marker description'
 | |
| 		 * 	  ]
 | |
| 		 * ]
 | |
| 		 */
 | |
| 		'markers' => [],
 | |
| 
 | |
| 		// Marker image relative to Joomla installation
 | |
| 		'markerImage' => '',
 | |
| 
 | |
| 		// Set whether to replace marker label/description smart tags
 | |
| 		'replaceSmartTags' => false
 | |
| 	];
 | |
| 
 | |
| 	public function __construct($options = [])
 | |
| 	{
 | |
| 		parent::__construct($options);
 | |
| 
 | |
| 		$this->prepare();
 | |
| 	}
 | |
| 
 | |
| 	private function prepare()
 | |
| 	{
 | |
| 		$this->options['markerImage'] = $this->options['markerImage'] ? Uri::root() . ltrim($this->options['markerImage'], DIRECTORY_SEPARATOR) : '';
 | |
| 
 | |
| 		// Set the marker if a single value was given
 | |
| 		if ($this->options['value'] && empty($this->options['markers']))
 | |
| 		{
 | |
| 			$coords = array_filter(array_map('trim', explode(',', $this->options['value'])));
 | |
| 			if (count($coords) === 2)
 | |
| 			{
 | |
| 				$this->options['markers'] = [
 | |
| 					[
 | |
| 						'id' => 1,
 | |
| 						'latitude' => $coords[0],
 | |
| 						'longitude' => $coords[1]
 | |
| 					]
 | |
| 				];
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		// Make markers an array if a JSON string was given
 | |
| 		if (is_string($this->options['markers']))
 | |
| 		{
 | |
| 			$this->options['markers'] = json_decode($this->options['markers'], true);
 | |
| 		}
 | |
| 
 | |
| 		// Set as value the first marker so the JS library can have an initial center of the map
 | |
| 		if (is_array($this->options['markers']))
 | |
| 		{
 | |
| 			$latitude = isset($this->options['markers'][0]['latitude']) ? $this->options['markers'][0]['latitude'] : false;
 | |
| 			$longitude = isset($this->options['markers'][0]['longitude']) ? $this->options['markers'][0]['longitude'] : false;
 | |
| 
 | |
| 			if ($latitude && $longitude)
 | |
| 			{
 | |
| 				$this->options['value'] = implode(',', [$latitude, $longitude]);
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		if ($this->options['load_css_vars'])
 | |
| 		{
 | |
| 			$this->options['custom_css'] = $this->getWidgetCSS();
 | |
| 		}
 | |
| 
 | |
| 		// Transform title/description translation strings
 | |
| 		$this->prepareMarkerText();
 | |
| 	}
 | |
| 
 | |
| 	private function prepareMarkerText()
 | |
| 	{
 | |
| 		if (!is_array($this->options['markers']) || !count($this->options['markers']))
 | |
| 		{
 | |
| 			return;
 | |
| 		}
 | |
| 
 | |
| 		$st = new \NRFramework\SmartTags();
 | |
| 
 | |
| 		foreach ($this->options['markers'] as &$marker)
 | |
| 		{
 | |
| 			if (isset($marker['label']) && $marker['label'])
 | |
| 			{
 | |
| 				$marker['label'] = Text::_($marker['label']);
 | |
| 
 | |
| 				// Replace Smart tags
 | |
| 				if ($this->options['replaceSmartTags'])
 | |
| 				{
 | |
| 					$marker['label'] = $st->replace($marker['label']);
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			if (isset($marker['description']) && $marker['description'])
 | |
| 			{
 | |
| 				$marker['description'] = Text::_($marker['description']);
 | |
| 				$marker['description'] = \Joomla\CMS\HTML\HTMLHelper::_('content.prepare', $marker['description'], null, 'tassos.widget.map');
 | |
| 
 | |
| 				// Replace Smart tags
 | |
| 				if ($this->options['replaceSmartTags'])
 | |
| 				{
 | |
| 					$marker['description'] = $st->replace($marker['description']);
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			if (empty($marker['label']) && isset($marker['address']))
 | |
| 			{
 | |
| 				$marker['label'] = $marker['address'];
 | |
| 			}
 | |
| 
 | |
| 			// Link to the item
 | |
| 			if (!empty($marker['label']) && isset($marker['item_id']) && $marker['item_id'] && isset($marker['context']) && $marker['context'] && $marker['context'] !== 'com_users.user')
 | |
| 			{
 | |
| 				$context = explode('.', $marker['context']);
 | |
| 
 | |
| 				$routerHelper = $routerMethod = null;
 | |
| 
 | |
| 				// Content
 | |
| 				if ($marker['context'] === 'com_content.article')
 | |
| 				{
 | |
| 					$routerHelper = defined('nrJ4') ? 'Joomla\Component\Content\Site\Helper\RouteHelper' : 'ContentHelperRoute';
 | |
| 					$routerMethod = 'getArticleRoute';
 | |
| 				}
 | |
| 				// Contact
 | |
| 				else
 | |
| 				{
 | |
| 					if (!defined('nrJ4'))
 | |
| 					{
 | |
| 						\JLoader::register('ContactHelperRoute', JPATH_SITE . '/components/com_contact/helpers/route.php');
 | |
| 					}
 | |
| 					$routerHelper = defined('nrJ4') ? 'Joomla\Component\Contact\Site\Helper\RouteHelper' : 'ContactHelperRoute';
 | |
| 					$routerMethod = 'getContactRoute';
 | |
| 				}
 | |
| 				
 | |
| 				$url = Route::_($routerHelper::$routerMethod($marker['item_id'], $marker['cat_id'], $marker['language']));
 | |
| 				
 | |
| 				$marker['label'] = '<a href="' . $url . '">' . $marker['label'] . '</a>';
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Returns the CSS for the widget.
 | |
| 	 * 
 | |
| 	 * @param   array  $exclude_breakpoints   Define breakpoints to exclude their CSS
 | |
| 	 * 
 | |
| 	 * @return  string
 | |
| 	 */
 | |
| 	public function getWidgetCSS($exclude_breakpoints = [])
 | |
| 	{
 | |
| 		$controls = [
 | |
| 			// CSS Variables
 | |
|             [
 | |
|                 'property' => '--width',
 | |
|                 'value' => $this->options['width'],
 | |
| 				'unit' => 'px'
 | |
| 			],
 | |
|             [
 | |
|                 'property' => '--height',
 | |
|                 'value' => $this->options['height'],
 | |
| 				'unit' => 'px'
 | |
| 			],
 | |
| 		];
 | |
| 
 | |
| 		$selector = '.nrf-widget.map-widget.' . $this->options['id'];
 | |
| 		
 | |
| 		$controlsInstance = new \NRFramework\Controls\Controls(null, $selector, $exclude_breakpoints);
 | |
|         
 | |
| 		if (!$controlsCSS = $controlsInstance->generateCSS($controls))
 | |
| 		{
 | |
| 			return;
 | |
| 		}
 | |
| 
 | |
| 		return $controlsCSS;
 | |
| 	}
 | |
| 
 | |
| 	public function render()
 | |
| 	{
 | |
| 		$this->loadMedia();
 | |
| 
 | |
| 		return parent::render();
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Loads media files
 | |
| 	 * 
 | |
| 	 * @return  void
 | |
| 	 */
 | |
| 	public function loadMedia()
 | |
| 	{
 | |
| 		if ($this->options['load_stylesheet'])
 | |
| 		{
 | |
| 			HTMLHelper::stylesheet('plg_system_nrframework/widgets/map.css', ['relative' => true, 'version' => 'auto']);
 | |
| 		}
 | |
| 	}
 | |
| } |