<?php
/**
* @version	$Id: addresses_event_handler.php 13558 2010-05-12 09:17:46Z alex $
* @package	In-Commerce
* @copyright	Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license	Commercial License
* This software is protected by copyright law and international treaties.
* Unauthorized reproduction or unlicensed usage of the code of this program,
* or any portion of it may result in severe civil and criminal penalties,
* and will be prosecuted to the maximum extent possible under the law
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
	defined('FULL_PATH') or die('restricted access!');

	class AddressesEventHandler extends kDBEventHandler {

		function mapPermissions()
		{
			parent::mapPermissions();
			$permissions = Array(
				// user can view any form on front-end
				'OnItemBuild'	=>	Array('subitem' => true),
				'OnUpdate'	=>	Array('subitem' => true),
				'OnCreate'	=>	Array('subitem' => true),
				'OnDelete'	=>	Array('subitem' => true),
			);

			$this->permMapping = array_merge($this->permMapping, $permissions);
		}

		/**
		 * Get's special of main item for linking with subitem
		 *
		 * @param kEvent $event
		 * @return string
		 */
		function getMainSpecial(&$event)
		{
			return '';
		}

		/**
		 * Enter description here...
		 *
		 * @param kEvent $event
		 */
		function SetCustomQuery(&$event)
		{
			if ($this->Application->isAdminUser) {
				return ;
			}

			$object =& $event->getObject();
			$user_id = $this->Application->RecallVar('user_id');
			$object->addFilter('myitems_user','%1$s.PortalUserId = '.$user_id);
		}

		/**
		 * Makes "use as $type" mark unique among user addresses
		 *
		 * @param kDBItem $object
		 * @param string $type
		 */
		function processLastUsed(&$object, $type)
		{
			$is_last = $object->GetDBField('LastUsedAs'.$type);
			if ($is_last) {
				$fields_hash = Array (
					'LastUsedAs'.$type => 0,
				);
				$this->Conn->doUpdate($fields_hash, $object->TableName, 'PortalUserId = '.$object->GetDBField('PortalUserId'));
			}
		}

		/**
		 * Ensures, that user have only one "use as billing" / "use as shipping" address
		 *
		 * @param kEvent $event
		 */
		function OnBeforeItemUpdate(&$event)
		{
			$object =& $event->getObject();
			/* @var $object kDBItem */

			if (!$object->isLoaded() || !$this->checkItemStatus($event)) {
				// not trivially loaded object OR not current user address
				$event->status = erPERM_FAIL;
				return ;
			}

			$cs_helper =& $this->Application->recallObject('CountryStatesHelper');
			/* @var $cs_helper kCountryStatesHelper */

			$cs_helper->CheckStateField($event, 'State', 'Country');
			$cs_helper->PopulateStates($event, 'State', 'Country');

			$this->processLastUsed($object, 'Shipping');
			$this->processLastUsed($object, 'Billing');
		}

		function OnUpdate(&$event)
		{
			parent::OnUpdate($event);

			$this->setNextTemplate($event);
		}

		/**
		 * Creates new user
		 *
		 * @param kEvent $event
		 */
		function OnCreate(&$event)
		{
			parent::OnCreate($event);

			$this->setNextTemplate($event);
		}

		/**
		 * Enter description here...
		 *
		 * @param kEvent $event
		 */
		function setNextTemplate(&$event)
		{
			if ($this->Application->isAdminUser) {
				return ;
			}

			$event->SetRedirectParam('opener', 's');
			$next_template = $this->Application->GetVar('next_template');
			if ($next_template) {
				$event->redirect = $next_template;
			}
		}

		/**
		 * Fills states for object country
		 *
		 * @param kEvent $event
		 */
		function OnAfterItemLoad(&$event)
		{
			parent::OnAfterItemLoad($event);

			$cs_helper =& $this->Application->recallObject('CountryStatesHelper');
			/* @var $cs_helper kCountryStatesHelper */

			$cs_helper->PopulateStates($event, 'State', 'Country');
		}

		/**
		 * [HOOK] Update PortalUser table when address marked as ProfileAddress is changed via addr prefix object
		 *
		 * @param kEvent $event
		 */
		function OnUpdateProfileAddress(&$event)
		{
			$user =& $this->Application->recallObject('u.current');

			if ($this->Application->GetVar('billing_address_id') > 0) {
				$address_id = $this->Application->GetVar('billing_address_id');
			}
			elseif ($this->Application->GetVar('shipping_address_id') > 0) {
				$address_id = $this->Application->GetVar('shipping_address_id');
			}
			else {
				$address_id = false;
			}

			if (!$address_id) {
				return true;
			}

			$address =& $event->getObject(Array('skip_autoload' => true));
			$address->Load($address_id);
			if (!$address->GetDBField('IsProfileAddress')) {
				return true;
			}

			$field_map = Array(	'Company'		=>	1,
								'Phone'			=>	1,
								'Fax'			=>	1,
								'Email'			=>	1,
								'Address1'		=>	'Street',
								'Address2'		=>	'Street2',
								'City'			=>	1,
								'State'			=>	1,
								'Zip'			=>	1,
								'Country'		=>	1,
						);

			$user->setName( $address->GetDBField('To') );

			foreach ($field_map as $src_field => $dst_field) {
				if ($dst_field == 1) $dst_field = $src_field;
				$user->SetDBField($dst_field, $address->GetDBField($src_field));
			}

			return $user->Update();
		}

		/**
		 * [HOOK] Create user profile address based on PortalUser table data
		 *
		 * @param kEvent $event
		 */
		function OnUpdateUserProfile(&$event)
		{
			$user =& $event->MasterEvent->getObject();

			$load_keys = Array('PortalUserId' => $user->GetID(), 'IsProfileAddress' => 1);

			$address =& $this->Application->recallObject($event->Prefix.'.-item', null, Array('skip_autoload' => true));
			$address->Load($load_keys);

			$field_map = Array(	'PortalUserId'	=>	1,
								'Company'		=>	1,
								'Phone'			=>	1,
								'Fax'			=>	1,
								'Email'			=>	1,
								'Address1'		=>	'Street',
								'Address2'		=>	'Street2',
								'City'			=>	1,
								'State'			=>	1,
								'Zip'			=>	1,
								'Country'		=>	1,
						);

			$full_name = trim($user->GetDBField('FirstName').' '.$user->GetDBField('LastName'));
			$address->SetDBField('To', $full_name);
			$address->SetDBField('IsProfileAddress', 1);

			foreach ($field_map as $dst_field => $src_field) {
				if ($src_field == 1) $src_field = $dst_field;
				$address->SetDBField($dst_field, $user->GetDBField($src_field));
			}

			$sql = 'SELECT SUM(IF(LastUsedAsBilling = 1, 1, 0 )) AS HasBilling, SUM(IF(LastUsedAsShipping = 1, 1, 0)) AS HasShipping
					FROM '.$address->TableName.'
					WHERE PortalUserId = '.$user->GetID();
			$address_status = $this->Conn->GetRow($sql);

			if (!$address_status['HasBilling']) {
				$address->SetDBField('LastUsedAsBilling', 1);
			}

			if (!$address_status['HasShipping']) {
				$address->SetDBField('LastUsedAsShipping', 1);
			}

			return $address->isLoaded() ? $address->Update() : $address->Create();
		}

		/**
		 * Checks if user trying to manipulate address that he Owns (exception for Admins)
		 * (non permission-based)
		 *
		 * @param kEvent $event
		 * @return bool
		 */
		function checkItemStatus(&$event)
		{
			if ($this->Application->isAdminUser) {
				return true;
			}

			if (!$this->Application->LoggedIn()) {
				return false;
			}

			$object =& $event->getObject();
			if (!$object->isLoaded()) {
				return true;
			}

			return $object->GetDBField('PortalUserId') == $this->Application->RecallVar('user_id');

		}

		/**
		 * Ensures, that user have only one "use as billing" / "use as shipping" address
		 * Disables Guest ability to create addresses
		 *
		 * @param kEvent $event
		 */
		function OnBeforeItemCreate(&$event)
		{
			if (!$this->Application->LoggedIn()) {
				$event->status = erPERM_FAIL;
				return ;
			}

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

			$object->SetDBField('PortalUserId', $this->Application->RecallVar('user_id'));

			$cs_helper =& $this->Application->recallObject('CountryStatesHelper');
			/* @var $cs_helper kCountryStatesHelper */

			$cs_helper->CheckStateField($event, 'State', 'Country');
			$cs_helper->PopulateStates($event, 'State', 'Country');

			$this->processLastUsed($object, 'Shipping');
			$this->processLastUsed($object, 'Billing');
		}

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

			if (!$object->isLoaded() || !$this->checkItemStatus($event)) {
				// not trivially loaded object OR not current user address
				$event->status = erPERM_FAIL;
				return ;
			}
		}

		/**
		 * Sets default country for new addresses to Latvia
		 *
		 * @param kEvent $event
		 */
		function OnAfterConfigRead(&$event)
		{
			parent::OnAfterConfigRead($event);

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

			$fields = $this->Application->getUnitOption($event->Prefix, 'Fields');
			$fields['Country']['default'] = $site_helper->getDefaultCountry('Shipping');
			$this->Application->setUnitOption($event->Prefix, 'Fields', $fields);
		}
	}