<?php
/*------------------------------------------------------------------------
  Solidres - Hotel booking extension for Joomla
  ------------------------------------------------------------------------
  @Author    Solidres Team
  @Website   http://www.solidres.com
  @Copyright Copyright (C) 2013 - 2017 Solidres. All Rights Reserved.
  @License   GNU General Public License version 3, or later
------------------------------------------------------------------------*/

defined('_JEXEC') or die;

class PlgSolidresACL extends SRPlugin
{
	/**
	 * @var $db JDatabaseDriver
	 * @since 0.1.0
	 */
	protected $db;

	public function __construct($subject, array $config = array())
	{
		parent::__construct($subject, $config);

		if (!defined('SR_STREAM_ACCESSED'))
		{
			define('SR_STREAM_ACCESSED', $this->authorise('core.system.manage'));
		}
	}

	protected function authorise($action, $assetName = 'com_solidres')
	{
		$user = JFactory::getUser();

		return $user->authorise($action, $assetName);
	}

	public function onSolidresSideNavPrepare(&$menuStructure, &$iconMap)
	{
		if (!$this->authorise('core.reservation.manage'))
		{
			unset($menuStructure['SR_SUBMENU_RESERVATION']);
		}

		if (!$this->authorise('core.reservation_asset.manage'))
		{
			$this->removeSubMenuByTitle($menuStructure['SR_SUBMENU_ASSET'], 'SR_SUBMENU_ASSETS_CATEGORY');
			$this->removeSubMenuByTitle($menuStructure['SR_SUBMENU_ASSET'], 'SR_SUBMENU_ASSETS_LIST');
		}

		if (!$this->authorise('core.customer.manage'))
		{
			if (!$this->authorise('core.customer_customfield.manage'))
			{
				unset($menuStructure['SR_SUBMENU_CUSTOMER']);
			}
			else
			{
				$this->removeSubMenuByTitle($menuStructure['SR_SUBMENU_CUSTOMER'], 'SR_SUBMENU_CUSTOMERS_LIST');
				$this->removeSubMenuByTitle($menuStructure['SR_SUBMENU_CUSTOMER'], 'SR_SUBMENU_CUSTOMERGROUPS_LIST');
			}
		}

		if (!$this->authorise('core.room_type.manage'))
		{
			$this->removeSubMenuByTitle($menuStructure['SR_SUBMENU_ASSET'], 'SR_SUBMENU_ROOM_TYPE_LIST');
		}

		if (!$this->authorise('core.admin', 'com_solidres'))
		{
			unset($menuStructure['SR_SUBMENU_SYSTEM']['8.5']);
		}

		if (!$this->authorise('core.coupon_extra.manage'))
		{
			unset($menuStructure['SR_SUBMENU_COUPON_EXTRA']);
		}

		if (!$this->authorise('core.feedback.manage'))
		{
			unset($menuStructure['SR_SUBMENU_CUSTOMER_FEEDBACK']);
		}

		if (!$this->authorise('core.subscription.manage'))
		{
			unset($menuStructure['SR_SUBMENU_SUBSCRIPTIONS']);
		}

		if (!$this->authorise('core.system.manage'))
		{
			unset($menuStructure['SR_SUBMENU_SYSTEM']);
		}

		if (!$this->authorise('core.experience.manage'))
		{
			unset($menuStructure['SR_SUBMENU_EXPERIENCES']);
		}

		if (!$this->authorise('core.limitbooking.manage'))
		{
			unset($menuStructure['SR_SUBMENU_RESERVATION']['2.0']);
		}

		if (!$this->authorise('core.housekeeping.manage'))
		{
			unset($menuStructure['SR_SUBMENU_ASSET']['3.0']);
		}

		foreach ($menuStructure as $key => $array)
		{
			if (empty($array))
			{
				unset($menuStructure[$key]);
			}
		}
	}

	protected function removeSubMenuByTitle(&$items, $title)
	{
		foreach ($items as $key => $item)
		{
			if (strcasecmp($item[0], $title) === 0)
			{
				unset($items[$key]);
				break;
			}
		}
	}

	protected function getCompileTask()
	{
		static $task = null;

		if (null === $task)
		{
			$view = strtolower($this->app->input->getCmd('view'));
			$task = strtolower($this->app->input->getCmd('task', 'display'));

			if (strpos($task, '.') !== false)
			{
				$task = explode('.', $task, 2);
			}
			elseif ($task == 'display')
			{
				$task = $view;
			}

			if (!is_array($task))
			{
				$task = array($task, '');
			}
		}

		return $task;
	}

	protected function backendAuthentication()
	{
		if ($this->app->getName() == 'site')
		{
			return true;
		}

		list($ctrl, $method) = $this->getCompileTask();

		switch ($ctrl)
		{
			case 'reservations':
			case 'reservationbase':
			case 'reservationnote':
			case 'discounts':
			case 'discount':
				$access = $this->authorise('core.reservation.manage');
				break;

			case 'invoices':
			case 'invoice':
				$access = $this->authorise('core.invoice.manage');
				break;

			case 'reservationassets':
			case 'reservationasset':
				$access = $this->authorise('core.reservation_asset.manage');
				break;

			case 'customers':
			case 'customer':
			case 'customergroups':
			case 'customergroup':
				$access = $this->authorise('core.customer.manage');
				break;

			case 'roomtypes':
			case 'roomtype':
				$access = $this->authorise('core.room_type.manage');
				break;

			case 'coupons':
			case 'coupon':
			case 'extras':
			case 'extra':
				$access = $this->authorise('core.coupon_extra.manage');
				break;

			case 'feedbacks':
			case 'feedback':
			case 'feedbackconditions':
			case 'feedbackcondition':
			case 'feedbacktypes':
			case 'feedbacktype':
			case 'feedbacktypevalues':
			case 'feedbacktypevalue':
				$access = $this->authorise('core.feedback.manage');
				break;

			case 'subscriptionlevels':
			case 'subscriptionlevel':
			case 'subscriptioncoupons':
			case 'subscriptioncoupon':
			case 'subscriptionupgrades':
			case 'subscriptionupgrade':
			case 'subdcriptions':
			case 'subdcription':
			case 'subdcriptionemails':
			case 'subdcriptionemail':
			case 'commissionrates':
			case 'commissionrate':
			case 'commissions':
			case 'commission':
				$access = $this->authorise('core.subscription.manage');
				break;

			case 'currencies':
			case 'currency':
			case 'system':
			case 'countries':
			case 'country':
			case 'states':
			case 'state':
			case 'taxes':
			case 'tax':
			case 'facilities':
			case 'facility':
			case 'themes':
			case 'theme':
			case 'stream':
				$access = $this->authorise('core.system.manage');
				break;

			case 'customfields':
			case 'customfield':

				$context = strtolower($this->app->input->getCmd('context'));

				if ($context == 'com_solidres.customer')
				{
					$access = $this->authorise('core.customer_customfield.manage');
				}
				elseif ($context == 'com_solidres.experience.customer')
				{
					$access = $this->authorise('core.experience.manage');
				}
				else
				{
					$access = $this->authorise('core.admin');
				}

				break;

			case 'acl':
				$access = $this->authorise('core.admin');
				break;

			case 'experiences':
			case 'experience':
			case 'transportations':
			case 'transportation':
			case 'expcategories':
			case 'expcategory':
			case 'expreservations':
			case 'expreservation':
			case 'expinvoices':
			case 'expinvoice':
			case 'expextras':
			case 'expextra':
			case 'expdashboard':
				$access = $this->authorise('core.experience.manage');
				break;

			case 'limitbookings':
			case 'limitbooking':
				$access = $this->authorise('core.limitbooking.manage');
				break;

			case 'housekeeping':
				$access = $this->authorise('core.housekeeping.manage');
				break;

			default:
				$access = true;
				break;
		}

		return (bool) $access;
	}

	protected function frontendAuthentication()
	{
		if ($this->app->input->getCmd('option') != 'com_solidres'
			|| $this->app->getName() == 'administrator'
			|| !JPluginHelper::isEnabled('solidres', 'hub')
		)
		{
			return true;
		}

		list($ctrl, $method) = $this->getCompileTask();

		switch ($ctrl)
		{
			case 'reservations':
			case 'reservationform':
			case 'discounts':
			case 'discountform':
				$access = $this->authorise('core.reservation.manage');
				break;

			case 'invoices':
				$access = $this->authorise('core.invoice.manage');
				break;

			case 'reservationassets':
			case 'reservationassetform':
				$access = $this->authorise('core.reservation_asset.manage');
				break;

			case 'roomtypes':
			case 'roomtypeform':
				$access = $this->authorise('core.room_type.manage');
				break;

			case 'coupons':
			case 'couponform':
			case 'extras':
			case 'extraform':
				$access = $this->authorise('core.coupon_extra.manage');
				break;

			case 'feedbacks':
			case 'feedback':

				if ($this->app->input->get('view') === 'dashboard')
				{
					$access = (bool) $this->authorise('core.feedback.manage');
				}
				else
				{
					$access = true;
				}

				break;

			case 'experiences':
			case 'experience':
			case 'expreservations':
			case 'expreservation':
			case 'expinvoices':
			case 'expinvoice':
			case 'expextras':
			case 'expextra':
			case 'expdashboard':

				if (in_array($ctrl, array('experiences', 'experience')))
				{
					if ($this->app->input->get('ctrl') == 'hub')
					{
						$access = $this->authorise('core.experience.manage');
					}
					else
					{
						$access = true;
					}
				}
				elseif (($ctrl == 'expreservations' && $this->app->input->get('_viewAlias') == 'myexperiences')
					|| ($ctrl == 'expreservation' && $method == 'quickview')
				)
				{
					$access = true;
				}
				else
				{
					$access = $this->authorise('core.experience.manage');
				}

				break;

			case 'limitbookings':
			case 'limitbookingform':
				$access = $this->authorise('core.limitbooking.manage');
				break;

			default:
				$access = true;
				break;
		}

		return (bool) $access;
	}

	public function onSolidresAuthentication()
	{
		return $this->backendAuthentication();
	}

	public function onSolidresPluginRegister()
	{
		parent::onSolidresPluginRegister();
		$option    = strtolower($this->app->input->getCmd('option'));
		$extension = strtolower($this->app->input->getCmd('extension'));

		if (($option == 'com_categories'
				&& $extension == 'com_solidres'
				&& !$this->authorise('core.reservation_asset.manage'))
			|| !$this->frontendAuthentication()
		)
		{
			throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403);
		}
	}
}
