<?php
/**
* @version	$Id: coupons_event_handler.php 16516 2017-01-20 14:12:22Z 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 CouponsEventHandler extends kDBEventHandler {

	/**
	 * Allows to override standard permission mapping
	 *
	 * @return void
	 * @access protected
	 * @see kEventHandler::$permMapping
	 */
	protected function mapPermissions()
	{
		parent::mapPermissions();

		$permissions = Array (
			'OnItemBuild' => Array ('self' => true),
			'OnApplyClone' => Array ('self' => 'add'),
			'OnPrepareClone' => Array ('self' => 'view'),
		);

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

	/**
	 * Prepares coupon cloning
	 *
	 * @param kEvent $event
	 */
	function OnPrepareClone($event)
	{
		$this->StoreSelectedIDs($event);

		$event->CallSubEvent('OnNew');

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

		$this->setCloningRequired($object);
		$clone_count = $this->Application->RecallVar('CoupLastCloneCount');

		if ( is_numeric($clone_count) && $clone_count > 0 ) {
			$object->SetDBField('CouponCount', $clone_count);
		}

		$expire_days = $this->Application->ConfigValue('Comm_DefaultCouponDuration');
		$default_expiration = strtotime('+' . $expire_days . ' days');

		$object->SetDBField('DefaultExpiration_date', $default_expiration);
		$object->SetDBField('DefaultExpiration_time', $default_expiration);
	}

	/**
	 * Occurs before an item has been cloned
	 * Id of newly created item is passed as event' 'id' param
	 *
	 * @param kEvent $event
	 * @return void
	 * @access protected
	 */
	protected function OnBeforeClone(kEvent $event)
	{
		parent::OnBeforeClone($event);

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

		$this->SetNewCode($object);

		$object->SetDBField('LastUsedBy', NULL);
		$object->SetDBField('LastUsedOn', NULL);
		$object->SetDBField('NumberOfUses', NULL);

		$expiration = $this->Application->GetVar('clone_coupon_expiration');
		$object->SetDBField('Expiration_date', $expiration);
		$object->SetDBField('Expiration_time', $expiration);
	}

	function OnApplyClone(kEvent $event)
	{
		if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
			$event->status = kEvent::erFAIL;
			return;
		}

		/** @var kDBItem $object */
		$object = $event->getObject( Array ('skip_autoload' => true) );

		$this->setCloningRequired($object);

		$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
		list($id, $field_values) = each($items_info);
		$object->setID($id);
		$object->SetFieldsFromHash($field_values);
		$event->setEventParam('form_data', $field_values);

		if ( !$object->Validate() ) {
			$event->status = kEvent::erFAIL;
			return ;
		}

		/** @var kTempTablesHandler $temp */
		$temp = $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');

		$original_coupon_ids = $this->getSelectedIDs($event, true);
		$clone_count = $object->GetDBField('CouponCount');
		$this->Application->StoreVar('CoupLastCloneCount', $clone_count);
		$this->Application->SetVar('clone_coupon_expiration', $object->GetDBField('DefaultExpiration'));

		for ($i = 0; $i < $clone_count; $i++) {
			$temp->CloneItems($event->Prefix, $event->Special, $original_coupon_ids);
		}

		$event->SetRedirectParam('opener', 'u');
	}

	/**
	 * Sets fields required during coupon cloning
	 *
	 * @param kDBItem $object
	 * @return void
	 * @access protected
	 */
	protected function setCloningRequired(&$object)
	{
		$this->RemoveRequiredFields($object);
		$object->setRequired('CouponCount');
		$object->setRequired('DefaultExpiration');
	}

	function SetNewCode(&$item)
	{
		do{
			$new_code = $this->RandomCouponCode();
			$exists = $this->Conn->GetOne('SELECT COUNT(*) FROM '.TABLE_PREFIX.'ProductsCoupons WHERE Code='.$this->Conn->qstr($new_code));
			if ($exists){
				$new_code = false;
			}
		} while (!$new_code);

		$item->SetDBField('Code', $new_code);
	}

	function RandomCouponCode()
	{
		$rand_code = '';

		for ($i = 0; $i < 10; $i++) {
			$is_letter = rand(0, 1);
			$rand_code .= ($is_letter ? chr(rand(65, 90)) : rand(0, 9));
		}

		return $rand_code;
	}

	/**
	 * Prepare temp tables for creating new item
	 * but does not create it. Actual create is
	 * done in OnPreSaveCreated
	 *
	 * @param kEvent $event
	 * @return void
	 * @access protected
	 */
	protected function OnPreCreate(kEvent $event)
	{
		parent::OnPreCreate($event);

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

		$exp_date = adodb_mktime();
		$default_duration = $this->Application->ConfigValue('Comm_DefaultCouponDuration');

		if ( $default_duration && $default_duration > 0 ) {
			$exp_date += (int)$default_duration * 86400;
		}

		$object->SetDBField('Expiration_date', $exp_date);
	}

	/**
	 * Occurs before updating item
	 *
	 * @param kEvent $event
	 * @return void
	 * @access protected
	 */
	protected function OnBeforeItemUpdate(kEvent $event)
	{
		parent::OnBeforeItemUpdate($event);

		$this->itemChanged($event);
	}

	/**
	 * Occurs before creating item
	 *
	 * @param kEvent $event
	 * @return void
	 * @access protected
	 */
	protected function OnBeforeItemCreate(kEvent $event)
	{
		parent::OnBeforeItemCreate($event);

		$this->itemChanged($event);
	}

	/**
	 * Occurs before item is changed
	 *
	 * @param kEvent $event
	 */
	function itemChanged($event)
	{
		/** @var kDBItem $object */
		$object = $event->getObject();

		$object->SetDBField('Amount', abs($object->GetDBField('Amount')));
	}
}
