<?php
/**
* @version	$Id: users_tag_processor.php 14364 2011-06-14 12:45:45Z 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 UsersTagProcessor extends kDBTagProcessor
	{

		function LogoutLink($params)
		{
			$pass = Array('pass' => 'all,m,u', 'u_event' => 'OnLogout', 'm_cat_id'=>0);
			$logout_template = $this->SelectParam($params, 'template,t');
			return $this->Application->HREF($logout_template, '', $pass);
		}

		function UseUsernames($params)
		{
			return $this->Application->ConfigValue('Email_As_Login') != 1;
		}

		function RegistrationEnabled($params)
		{
			return $this->Application->ConfigValue('User_Allow_New') != 2;
		}

		function SuggestRegister($params)
		{
			return !$this->Application->LoggedIn() && !$this->Application->ConfigValue('Comm_RequireLoginBeforeCheckout') && $this->RegistrationEnabled($params);
		}

		function ConfirmPasswordLink($params)
		{
			$code = $this->getCachedCode();

			$fields_hash = Array (
				'PwResetConfirm' => $code,
				'PwRequestTime' => adodb_mktime(),
			);

			$user_id = $this->Application->RecallVar('tmp_user_id');
			$this->Conn->doUpdate($fields_hash, TABLE_PREFIX.'PortalUser', 'PortalUserId = '.$user_id);

		    $params['user_key'] = $code;
		    if (!$this->SelectParam($params, 'template,t')) {
		    	$params['template'] = $this->Application->GetVar('reset_confirm_template');
		    }

		    return $this->Application->ProcessParsedTag('m', 'Link', $params);
		}

		/**
		 * Generates & caches code for password confirmation link
		 *
		 * @return string
		 */
		function getCachedCode()
		{
			static $code = null;

			if (!isset($code)) {
				$code = md5($this->GenerateCode());
			}

			return $code;
		}

		function GenerateCode()
		{
	        list($usec, $sec) = explode(" ",microtime());

	        $id_part_1 = substr($usec, 4, 4);
	        $id_part_2 = mt_rand(1,9);
	        $id_part_3 = substr($sec, 6, 4);
	        $digit_one = substr($id_part_1, 0, 1);
	        if ($digit_one == 0) {
                $digit_one = mt_rand(1,9);
                $id_part_1 = preg_replace('/^0/', '', $id_part_1);
                $id_part_1=$digit_one.$id_part_1;
	        }
	        return $id_part_1.$id_part_2.$id_part_3;
		}

		function ForgottenPassword($params)
		{
			return $this->Application->GetVar('ForgottenPassword');
		}

		function TestCodeIsValid($params)
		{
			$passed_key = trim($this->Application->GetVar('user_key'));

	     	// used for error reporting only -> rewrite code + theme (by Alex)
	     	$user_current_object =& $this->Application->recallObject('u', null, Array('skip_autoload' => true)); // TODO: change theme too
			/* @var $user_current_object UsersItem */

			$code_type = isset($params['code_type']) ? $params['code_type'] : 'forgot_password';

			$error_messages = Array (
				'forgot_password' => Array (
					'code_is_not_valid' => 'lu_code_is_not_valid',
					'code_expired' => 'lu_code_expired',
				),

				'activation' => Array (
					'code_is_not_valid' => 'lu_error_ActivationCodeNotValid',
					'code_expired' => 'lu_error_ActivationCodeExpired',
				),
			);

			if ($code_type == 'custom') {
				// custom error messages are given directly in tag
				$error_messages[$code_type] = Array (
					'code_is_not_valid' => $params['error_invalid'],
					'code_expired' => $params['error_expired'],
				);
			}

			$expiration_timeouts = Array (
				'forgot_password' => 'config:Users_AllowReset',
				'activation' => 'config:UserEmailActivationTimeout',
				'custom' => '',
			);

		    if (!$passed_key) {
		    	$user_current_object->SetError('PwResetConfirm', 'code_is_not_valid', $error_messages[$code_type]['code_is_not_valid']);

				return false;
		    }

		    $user_object =& $this->Application->recallObject('u.forgot', null, Array('skip_autoload' => true));
		    /* @var $user_object UsersItems */

		    $user_object->Load($passed_key, 'PwResetConfirm');

		    if ( !$user_object->isLoaded() ) {
		    	$user_current_object->SetError('PwResetConfirm', 'code_is_not_valid', $error_messages[$code_type]['code_is_not_valid']);

		    	return false;
		    }
		    else {
		    	$expiration_timeout = isset($params['expiration_timeout']) ? $params['expiration_timeout'] : $expiration_timeouts[$code_type];

		    	if ( preg_match('/^config:(.*)$/', $expiration_timeout, $regs) ) {
		    		$expiration_timeout = $this->Application->ConfigValue( $regs[1] );
		    	}

		    	if ( $expiration_timeout ) {
			      	if ( $user_object->GetDBField('PwRequestTime') < strtotime('-' . $expiration_timeout . ' minutes') ) {
						$user_current_object->SetError('PwResetConfirm', 'code_expired', $error_messages[$code_type]['code_expired']);

			      		return false;
			      	}
		    	}
		    }

			return true;
		}

		/**
		 * Returns sitem administrator email
		 *
		 * @param Array $params
		 * @return string
		 */
		function SiteAdminEmail($params)
		{
			return $this->Application->ConfigValue('Smtp_AdminMailFrom');
		}

		function AffiliatePaymentTypeChecked($params)
		{
			static $checked = false;

			if( $this->Application->GetVar('PaymentTypeId') )
			{
				$apt_object =& $this->Application->recallObject('apt.active');
				if( $this->Application->GetVar('PaymentTypeId') == $apt_object->GetDBField('PaymentTypeId') )
				{
					return 1;
				}
				else
				{
					return 0;
				}
			}

			if(!$checked)
			{
				$checked = true;
				return 1;
			}
			else
			{
				return 0;
			}
		}

		function HasError($params)
		{
			$res = parent::HasError($params);
			if($this->SelectParam($params,'field,fields') == 'any')
			{
				$res = $res || $this->Application->GetVar('MustAgreeToTerms'); // need to do it not put module fields into kernel ! (noticed by Alex)
				$res = $res || $this->Application->GetVar('SSNRequiredError');
			}
			return $res;
		}

		/**
		 * Returns login name of user
		 *
		 * @param Array $params
		 */
		function LoginName($params)
		{
			$object =& $this->getObject($params);
			return $object->GetID() != USER_ROOT ? $object->GetDBField('Login') : 'root';
		}

		function CookieUsername($params)
		{
			$submit_value = $this->Application->GetVar($params['submit_field']);
			if ($submit_value !== false) {
				return $submit_value;
			}

			$username = $this->Application->GetVar('save_username'); // from cookie

			if ($username == 'super-root') {
				$username = 'root';
			}
			return $username === false ? '' : $username;
		}

		/**
		 * Checks if user have one of required permissions
		 *
		 * @param Array $params
		 * @return bool
		 */
		function HasPermission($params)
		{
			$perm_helper =& $this->Application->recallObject('PermissionsHelper');
			/* @var $perm_helper kPermissionsHelper */

			return $perm_helper->TagPermissionCheck($params);
		}

		/**
		 * Returns link to user public profile
		 *
		 * @param Array $params
		 * @return string
		 */
		function ProfileLink($params)
		{
			$object =& $this->getObject($params);
			$params['user_id'] = $object->GetID();

			return $this->Application->ProcessParsedTag('m', 'Link', $params);
		}

		function ImageSrc($params)
		{
			list ($ret, $tag_processed) = $this->processAggregatedTag('ImageSrc', $params, $this->getPrefixSpecial());
			return $tag_processed ? $ret : false;
		}

		function LoggedIn($params)
		{
			static $loggedin_status = Array ();

			$object =& $this->getObject($params);
			/* @var $object kDBList */

			if (!isset($loggedin_status[$this->Special])) {
				$user_ids = $object->GetCol($object->IDField);
				$sql = 'SELECT LastAccessed, '.$object->IDField.'
						FROM '.TABLE_PREFIX.'UserSession
						WHERE (PortalUserId IN ('.implode(',', $user_ids).'))';
				$loggedin_status[$this->Special] = $this->Conn->GetCol($sql, $object->IDField);
			}

			return isset($loggedin_status[$this->Special][$object->GetID()]);
		}

		/**
		 * Prints user activation link
		 *
		 * @param Array $params
		 * @return string
		 */
		function ActivationLink($params)
		{
			$code = $this->getCachedCode();

			$fields_hash = Array (
				'PwResetConfirm' => $code,
				'PwRequestTime' => adodb_mktime(),
			);

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

			$this->Conn->doUpdate($fields_hash, $object->TableName, $object->IDField . ' = ' . $object->GetID());

		    $params['user_key'] = $code;

		    return $this->Application->ProcessParsedTag('m', 'Link', $params);
		}

		/**
		 * Activates user using given code
		 *
		 * @param Array $params
		 */
		function ActivateUser($params)
		{
			$passed_key = trim($this->Application->GetVar('user_key'));

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

		    $user =& $user_helper->getUserObject();
			$user->Load($passed_key, 'PwResetConfirm');

			if ( !$user->isLoaded() ) {
				return ;
			}

			$user->SetDBField('Status', STATUS_ACTIVE);
			$user->SetDBField('PwResetConfirm', '');
			$user->SetDBField('PwRequestTime', 0);
			$user->Update();

			if ( $user_helper->checkLoginPermission() ) {
	    		$user_helper->loginUserById( $user->GetID() );
			}
		}

	}