<?php
/**
* @version	$Id: spam_helper.php 15569 2012-10-10 13:29:39Z alex $
* @package	In-Portal
* @copyright	Copyright (C) 1997 - 2009 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 SpamHelper extends kHelper {

		/**
		 * Table name where spam control information is kept
		 *
		 * @var string
		 * @access protected
		 */
		protected $TableName;

		/**
		 * ResourceId field of current item
		 *
		 * @var int
		 * @access protected
		 */
		protected $ResourceId = 0;

		/**
		 * ResourceId from all items in list
		 *
		 * @var Array
		 * @access protected
		 */
		protected $ListResourceIDs = Array ();

		/**
		 * Type of information to put into spam control
		 *
		 * @var string
		 * @access protected
		 */
		protected $DataType = '';

		/**
		 * Default spam control record expiration
		 *
		 * @var int
		 * @access protected
		 */
		protected $Expiration = 0;

		/**
		 * Items expiration cache (for faster access)
		 *
		 * @var array
		 * @access protected
		 */
		protected $ExpirationCache = Array ();

		public function __construct()
		{
			parent::__construct();

			$this->TableName = TABLE_PREFIX . 'SpamControl';
		}

		/**
		 * Initializes helper for concrete item
		 *
		 * @param int $resource_id
		 * @param string $data_type
		 * @param int $expiration
		 * @param Array $list_resource_ids
		 * @access public
		 */
		public function InitHelper($resource_id, $data_type, $expiration, $list_resource_ids = Array ())
		{
			$this->DataType = $data_type;
			$this->ResourceId = $resource_id;
			$this->ListResourceIDs = $list_resource_ids ? $list_resource_ids : Array ($resource_id);

			if ( preg_match('/(.*):(.*)/', $expiration, $regs) ) {
				$delay_value = $this->Application->ConfigValue($regs[1]);
				$delay_interval = $this->Application->ConfigValue($regs[2]);
				$expiration = $delay_value * $delay_interval;
			}

			$this->Expiration = adodb_mktime() + $expiration;
		}

		/**
		 * Returns WHERE clause that identified each spam control record
		 *
		 * @param bool $as_array return result as array, not string
		 *
		 * @return string
		 * @access protected
		 */
		protected function GetKeyClause($as_array = false)
		{
			$user_id = $this->Application->RecallVar('user_id');

			if ( $user_id == 0 ) {
				$user_id = USER_GUEST;
			}

			$keys = Array (
				'IPaddress' => $this->Application->getClientIp(),
				'PortalUserId' => $user_id,
				'DataType' => $this->DataType,
			);

			if ( $as_array ) {
				$keys['ItemResourceId'] = $this->ResourceId;

				return $keys;
			}

			$ret = '';
			foreach ($keys as $field_name => $field_value) {
				$ret .= '(' . $field_name . ' = ' . $this->Conn->qstr($field_value) . ') AND ';
			}

			$ret .= '(ItemResourceId IN (' . implode(',', $this->ListResourceIDs) . '))';

			return $ret;
		}

		/**
		 * Allows to add current item in spam control
		 *
		 * @return void
		 * @access public
		 */
		public function AddToSpamControl()
		{
			$fields_hash = $this->GetKeyClause(true);

			$fields_hash['Expire'] = $this->Expiration;
			$this->Conn->doInsert($fields_hash, $this->TableName);

			// create empty expiration cache for given data type in case, when InSpamControl method wasn't called
			if ( !isset($this->ExpirationCache[$this->DataType]) ) {
				$this->ExpirationCache[$this->DataType] = Array ();
			}

			$this->ExpirationCache[$this->DataType][$this->ResourceId] = $this->Expiration;
		}

		/**
		 * Allows to check if current item is in spam control
		 *
		 * @return bool
		 * @access public
		 */
		public function InSpamControl()
		{
			if ( !array_key_exists($this->DataType, $this->ExpirationCache) ) {
				$key_clause = $this->GetKeyClause();

				$sql = 'SELECT Expire, ItemResourceId
						FROM ' . $this->TableName . '
						WHERE ' . $key_clause;
				$this->ExpirationCache[$this->DataType] = $this->Conn->GetCol($sql, 'ItemResourceId');
			}
			else {
				$key_clause = '';
			}

			$cache =& $this->ExpirationCache[$this->DataType];
			$expires = array_key_exists($this->ResourceId, $cache) ? $cache[$this->ResourceId] : false;

			if ( $expires && $expires < adodb_mktime() ) {
				// spam control record is expired
				$sql = 'DELETE FROM ' . $this->TableName . '
						WHERE ' . $key_clause;
				$this->Conn->Query($sql);
				return false;
			}

			return $expires ? true : false;
		}
	}