<?php
/**
* @version	$Id: site_domain_eh.php 14241 2011-03-16 20:24:35Z alex $
* @package	In-Portal
* @copyright	Copyright (C) 1997 - 2010 Intechnic. All rights reserved.
* @license      GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/

	defined('FULL_PATH') or die('restricted access!');

	class SiteDomainEventHandler extends kDBEventHandler {

		/**
		 * Permission check override
		 *
		 * @param kEvent $event
		 */
		function CheckPermission(&$event)
		{
			if ($event->Name == 'OnItemBuild') {
				// check permission without using $event->getSection(),
				// so first cache rebuild won't lead to "ldefault_Name" field being used
				return true;
			}

			return parent::CheckPermission($event);
		}

		/**
		 * Returns ID of site domain, that matches current url
		 *
		 * @param kEvent $event
		 */
		function getPassedID(&$event)
		{
			if ($event->Special == 'current') {
				if ($this->Application->isAdmin) {
					$event->setEventParam('raise_warnings', 0);
				}
				else {
					if (PROTOCOL == 'https://') {
						return $this->querySiteDomain('SSLUrl', rtrim($this->Application->BaseURL(), '/'));
					}

					return $this->querySiteDomain('DomainName', $_SERVER['HTTP_HOST']);
				}
			}

			return parent::getPassedID($event);
		}

		function querySiteDomain($field, $value)
		{
			$site_helper =& $this->Application->recallObject('SiteHelper');
			/* @var $site_helper SiteHelper */

			$site_domains = $site_helper->getSiteDomains();
			$domain_by_name = $site_helper->getDomainByName($field, $value);
			$domain_by_ip = $site_helper->getDomainByIP();

			if ($domain_by_ip) {
				$site_domain = $site_domains[$domain_by_ip];
				$redirect_mode = $site_domain['RedirectOnIPMatch'];

				if (($redirect_mode == SITE_DOMAIN_REDIRECT_EXTERNAL) && ($domain_by_ip == $domain_by_name)) {
					// redirect to external url (when visiting protected domain)
					$external_url = $site_domain['ExternalUrl'];

					if (preg_match('/^http[s]{0,1}:\/\//', $external_url)) {
						$this->Application->Redirect('external:' . $external_url);
					}
					else {
						$this->Application->Redirect('external:' . PROTOCOL . $external_url . $_SERVER['REQUEST_URI']);
					}
				}
				elseif (($redirect_mode == SITE_DOMAIN_REDIRECT_CURRENT) && ($domain_by_ip != $domain_by_name)) {
					// redirect to a domain detected by IP (when not already on it)
					if ((PROTOCOL == 'https://') && !$site_domain['SSLUrlUsesRegExp'] && $site_domain['SSLUrl']) {
						// need to remove sub folder from ssl url
						$ssl_url = preg_replace('/^(https:\/\/[^\/]*)(\/.*){0,1}$/', '\\1', $site_domain['SSLUrl']);
						$this->Application->Redirect('external:' . $ssl_url . $_SERVER['REQUEST_URI']);
					}
					elseif ((PROTOCOL == 'http://') && !$site_domain['DomainNameUsesRegExp']) {
						$this->Application->Redirect('external:http://' . $site_domain['DomainName'] . $_SERVER['REQUEST_URI']);
					}
				}

				return $domain_by_ip;
			}

			return $domain_by_name;
		}

		/**
		 * Load item if id is available
		 *
		 * @param kEvent $event
		 */
		function LoadItem(&$event)
		{
			if ($this->Application->isAdmin) {
				// don't load domain data from cache
				parent::LoadItem($event);

				return ;
			}

			$object =& $event->getObject();
			/* @var $object kDBItem */

			$id = (int)$this->getPassedID($event);

			if ($object->isLoaded() && ($object->GetID() == $id)) {
				// object is already loaded by same id
				return ;
			}

			$site_helper =& $this->Application->recallObject('SiteHelper');
			/* @var $site_helper SiteHelper */

			$site_domains = $site_helper->getSiteDomains();
			$domain_data = array_key_exists($id, $site_domains) ? $site_domains[$id] : false;

			if ($object->LoadFromHash($domain_data)) {
				$actions =& $this->Application->recallObject('kActions');
				$actions->Set($event->Prefix_Special.'_id', $object->GetID() );
			}
			else {
				$object->setID($id);
			}
		}

		/**
		 * Removes In-Commerce related fields, when it's not installed
		 *
		 * @param kEvent $event
		 */
		function OnAfterConfigRead(&$event)
		{
			parent::OnAfterConfigRead($event);

			if (!$this->Application->isModuleEnabled('In-Commerce')) {
				$remove_fields = Array (
					'BillingCountry', 'ShippingCountry',
					'PrimaryCurrencyId', 'Currencies',
					'PrimaryPaymentTypeId', 'PaymentTypes'
				);

				// remove field definitions
				$fields = $this->Application->getUnitOption($event->Prefix, 'Fields');

				foreach ($remove_fields as $remove_field) {
					unset($fields[$remove_field]);
				}

				$this->Application->setUnitOption($event->Prefix, 'Fields', $fields);

				// remove grid columns
				$grids = $this->Application->getUnitOption($event->Prefix, 'Grids');

				foreach ($grids as $grid_name => $grid_info) {
					foreach ($remove_fields as $remove_field) {
						if (array_key_exists($remove_field, $grid_info['Fields'])) {
							unset($grids[$grid_name]['Fields'][$remove_field]);
						}
					}
				}

				$this->Application->setUnitOption($event->Prefix, 'Grids', $grids);
			}
		}

		/**
		 * Delete cached information about site domains
		 *
		 * @param kEvent $event
		 */
		function OnSave(&$event)
		{
			parent::OnSave($event);

			if ($event->status == erSUCCESS) {
				$this->_deleteCache();
			}
		}

		/**
		 * Deletes cached information about site domains
		 */
		function _deleteCache()
		{
			if ($this->Application->isCachingType(CACHING_TYPE_MEMORY)) {
				$this->Application->deleteCache('master:domains_parsed');
			}
			else {
				$this->Application->deleteDBCache('domains_parsed');
			}

			$sql = 'DELETE FROM ' . TABLE_PREFIX . 'CachedUrls';
			$this->Conn->Query($sql);
		}

		/**
		 * Set's required fields based on redirect mode
		 *
		 * @param kEvent $event
		 */
		function OnAfterItemLoad(&$event)
		{
			parent::OnAfterItemLoad($event);

			$this->_setRequired($event);
		}

		/**
		 * Set's required fields based on redirect mode
		 *
		 * @param kEvent $event
		 */
		function OnBeforeItemCreate(&$event)
		{
			parent::OnBeforeItemCreate($event);

			$this->_setRequired($event);
		}

		/**
		 * Set's required fields based on redirect mode
		 *
		 * @param kEvent $event
		 */
		function OnBeforeItemUpdate(&$event)
		{
			parent::OnBeforeItemUpdate($event);

			$this->_setRequired($event);
		}

		/**
		 * Set's required fields
		 *
		 * @param kEvent $event
		 */
		function _setRequired(&$event)
		{
			$object =& $event->getObject();
			/* @var $object kDBItem */

			$redirect_mode = $object->GetDBField('RedirectOnIPMatch');
			$object->setRequired('ExternalUrl', $redirect_mode == SITE_DOMAIN_REDIRECT_EXTERNAL);
			$object->setRequired('DomainIPRange', $redirect_mode > 0);
		}
	}
