Your IP : 216.73.217.142


Current Path : /var/www/consult-e-syn/public_html/plugins/ats/geolocation/
Upload File :
Current File : /var/www/consult-e-syn/public_html/plugins/ats/geolocation/geolocation.php

<?php
/**
 * @package   ats
 * @copyright Copyright (c)2011-2022 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license   GNU General Public License version 3, or later
 */

defined('_JEXEC') or die();

use Akeeba\TicketSystem\Admin\Helper\Permissions;
use Akeeba\TicketSystem\Admin\Model\Tickets;
use FOF40\IP\IPHelper as Ip;
use Joomla\CMS\Factory;
use Joomla\CMS\Http\HttpFactory;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\Registry\Registry;

class plgAtsGeolocation extends CMSPlugin
{
	private $fieldSlug = 'geolocation';

	/**
	 * Overridden constructor. We set up basic fields when the plugin initializes.
	 *
	 * @param   object  &$subject  The object to observe
	 * @param   array    $config   An optional associative array of configuration settings.
	 *                             Recognized key values include 'name', 'group', 'params', 'language'
	 *                             (this list is not meant to be comprehensive).
	 *
	 * @since   3.0.0
	 */
	public function __construct(&$subject, array $config = [])
	{
		parent::__construct($subject, $config);

		$this->fieldSlug = trim($this->params->get('slug', 'geolocation'));
		$this->fieldSlug = empty($this->fieldSlug) ? 'geolocation' : $this->fieldSlug;
	}

	/**
	 * Renders per-category custom fields
	 *
	 * @param   array  $cache  Information about the ticket being created
	 *
	 * @return  array
	 *
	 * @throws  Exception
	 * @since   3.0.0
	 *
	 */
	public function onTicketFormRenderPerCatFields($cache)
	{
		// Only set up this field when filing a new ticket
		if (!array_key_exists('ats_ticket_id', $cache) || !empty($cache['ats_ticket_id']))
		{
			return [];
		}

		// Setup the field
		$slug = $this->fieldSlug;

		$field = [
			'id'          => $slug,
			'label'       => '',
			'elementHTML' => "<input type=\"hidden\" name=\"params[$slug]\" id=\"$slug\" />",
			'isValid'     => true,
			'public'      => false,
		];

		$maxAccuracy = (int) $this->params->get('w3c_accuracy', 7000);
		$maxAccuracy = ($maxAccuracy <= 0) ? 7000 : $maxAccuracy;
		$useW3C      = $this->params->get('use_w3c', 1);

		$js = <<< JS
var akeebatickets_{$slug}_content = {
		latitude:  0,
		longitude: 0,
		accuracy:  0
	};

akeeba.Loader.add(['akeeba.System', 'navigator.geolocation'], function() {
   akeeba.System.documentReady(function(){
       navigator.geolocation.getCurrentPosition(function(position) {
			if (position.coords.accuracy <= $maxAccuracy)
			{
			    akeebatickets_{$slug}_content.latitude  = position.coords.latitude;
			    akeebatickets_{$slug}_content.longitude = position.coords.longitude;
			    akeebatickets_{$slug}_content.accuracy  = position.coords.accuracy;
			
			    document.getElementById('$slug').value = JSON.stringify(akeebatickets_{$slug}_content);
			}
       });
   }) 
});

JS;

		if ($useW3C)
		{
			Factory::getApplication()->getDocument()->addScriptDeclaration($js);
		}

		return [$field];
	}

	/**
	 * Validate the custom fields' values. We use this to fetch GeoIP information is there was no data returned from the
	 * browser.
	 *
	 * @param   array  $data      The values for all custom fields
	 * @param   int    $category  The numeric category ID the ticket belongs to
	 *
	 * @return  array
	 *
	 * @since   3.0.0
	 */
	public function onAtsValidate(&$data, $category)
	{
		if (!isset($data[$this->fieldSlug]) || empty($data[$this->fieldSlug]))
		{
			$data[$this->fieldSlug] = '{}';
		}

		$geo = @json_decode($data[$this->fieldSlug], true);
		$geo = array_merge([
			'latitude'  => 0,
			'longitude' => 0,
			'accuracy'  => 0,
		], $geo);

		if (
			((abs($geo['latitude']) < 0.0000000001) && (abs($geo['longitude']) < 0.0000000001)) ||
			($geo['accuracy'] < 0.0000000001)
		)
		{
			$geo = $this->getGeoIP();
		}

		$data[$this->fieldSlug] = json_encode($geo);

		return [
			'valid'             => true,
			'isValid'           => true,
			'custom_validation' => [],
		];
	}

	/**
	 * Renders custom fields
	 *
	 * @param   Tickets  $ticket  The ticket we're rendering against
	 *
	 * @return  array|null  [['label' => $label, 'value' => $value], ...] or null when we can't render this field
	 *
	 * @since   3.0.0
	 */
	public function onAtsDisplayCustomFields(Tickets $ticket)
	{
		// Should I display the map at all?
		$displayFor = $this->params->get('display_map_for', 'staff');
		$isAdmin    = Permissions::isManager($ticket->catid, $ticket->created_by);
		$isOwner    = $ticket->created_by == Factory::getUser()->id;

		switch ($displayFor)
		{
			case 'staff':
			default:
				if (!$isAdmin)
				{
					return [];
				}
				break;

			case 'user':
				if (!$isAdmin && !$isOwner)
				{
					return [];
				}
				break;
		}

		foreach ($ticket->params as $slug => $value)
		{
			if ($slug != $this->fieldSlug)
			{
				continue;
			}

			$geo = @json_decode($value, true);

			if (
				((abs($geo['latitude']) < 0.0000000001) && (abs($geo['longitude']) < 0.0000000001)) ||
				($geo['accuracy'] < 0.0000000001)
			)
			{
				// No location recorded
				return [];
			}


			$this->loadLanguage('plg_ats_geolocation');
			$title = Text::_('PLG_ATS_GEOLOCATION_FIELD_LABEL');
			$html  = $this->getMapHTML($geo['latitude'], $geo['longitude']);

			return [
				[
					'label' => $title,
					'value' => $html,
				],
			];

			break;
		}

		return [];
	}

	/**
	 * Get the HTML to display an embedded map.
	 *
	 * @param   float  $lat  Latitude of pinned point on the map
	 * @param   float  $lon  Longitude of pinned point on the map
	 *
	 * @return  string
	 *
	 * @since   3.0.0
	 */
	protected function getMapHTML($lat, $lon)
	{
		$mapMethod = $this->params->get('display_map_with', 'osm');
		$googleKey = $this->params->get('google_key', '');

		$html       = '';
		$viewMapLbl = Text::_('PLG_ATS_GEOLOCATION_VIEWLARGER_LABEL');

		switch ($mapMethod)
		{
			case 'google':
				$html = <<< HTML
<iframe
  width="425"
  height="350"
  frameborder="0" style="border:0"
  scrolling="no" marginheight="0" marginwidth="0"
  src="https://www.google.com/maps/embed/v1/place?key=$googleKey&q=$lat,$lon" allowfullscreen>
</iframe>				
HTML;
				break;

			case 'bing':
				$viewMapLbl = Text::_('PLG_ATS_GEOLOCATION_VIEWLARGER_LABEL');
				$html       = <<< HTML
<iframe width="425" height="350" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="https://www.bing.com/maps/embed/viewer.aspx?v=3&cp=$lat~$lon&lvl=15&w=425&h=350&sty=r&typ=s&pp=~~$lat~$lon&ps=55&dir=0" style="border: 1px solid black"></iframe><br/><small><a href="https://www.bing.com/maps?v=2&cp=$lat~$lon&lvl=15&dir=0&sty=c&sp=point.{$lat}_{$lon}_Location" target="_blank">$viewMapLbl</a></small>

HTML;

				break;

			case 'osm':
			default:
				// Get a bounding box for the map
				$stepLat = 0.003;
				$stepLon = 0.003;
				$boxLat1 = $lat - $stepLat;
				$boxLat2 = $lat + $stepLon;
				$boxLon1 = $lon - $stepLon;
				$boxLon2 = $lon + $stepLat;


				$html = <<< HTML
<iframe width="425" height="350" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="https://www.openstreetmap.org/export/embed.html?bbox=$boxLon1%2C$boxLat1%2C$boxLon2%2C$boxLat2&amp;layer=mapnik&amp;marker=$lat%2C$lon" style="border: 1px solid black"></iframe><br/><small><a href="https://www.openstreetmap.org/?mlat=$lat&amp;mlon=$lon#map=16/$lat/$lon" target="_blank">$viewMapLbl</a></small>

HTML;

				break;
		}

		return $html;
	}

	/**
	 * Get location information from a GeoIP database
	 *
	 * @return   array  longitude, latitude, accuracy
	 *
	 * @since    3.0.0
	 */
	protected function getGeoIP()
	{
		$ip = Ip::getIp();

		return $this->getFreeGeoIP($ip);
	}

	/**
	 * Get GeoIP information using the FreeGeoIP service
	 *
	 * @param   string  $ip  The IP address to get GeoIP information for
	 *
	 * @return  array  longitude, latitude, accuracy
	 *
	 * @since   3.0.0
	 */
	private function getFreeGeoIP($ip)
	{
		$ret = [
			'latitude'  => 0,
			'longitude' => 0,
			'accuracy'  => 0,
		];

		try
		{
			$options  = new Registry();
			$http     = HttpFactory::getHttp($options);
			$url      = "https://freegeoip.net/json/" . urlencode($ip);
			$response = $http->get($url);
		}
		catch (Exception $e)
		{
			return $ret;
		}

		if ($response->code != 200)
		{
			return $ret;
		}

		$data = @json_decode($response->body, true);

		if (empty($data))
		{
			return $ret;
		}

		$ret['latitude']  = $data['latitude'];
		$ret['longitude'] = $data['longitude'];

		return $ret;
	}
}