<?php

require_once( BX_DIRECTORY_PATH_CLASSES . 'BxDolProfileFields.php' );
require_once( BX_DIRECTORY_PATH_CLASSES . 'BxDolEmailTemplates.php' );

class BxDolProfilesController {

	var $oPF;
	var $aItems;
	var $oEmailTemplate;

	function BxDolProfilesController() {
		$this -> oEmailTemplate = new BxDolEmailTemplates();
	}
	
	function createProfile( $aData, $bSendMails = true, $iMainMemberID = 0 ) {
		
		if( !$aData or !is_array($aData) or empty($aData) )
			return false;
		
		unset( $aData['Couple'] );
		unset( $aData['Captcha'] );
		unset( $aData['TermsOfUse'] );
		unset( $aData['ProfilePhoto'] );
		
		/* @var $this->oPF BxDolProfileFields */
		$this -> oPF = new BxDolProfileFields(100);
		
		if( !$this -> oPF -> aArea ) {
			echo 'Profile Fields cache not loaded. Cannot continue.';
			return false;
		}
		
		$this -> aItems = $this -> oPF -> aArea[0]['Items'];
		
		if( $iMainMemberID )
			$aMainMember = $this -> getProfileInfo( $iMainMemberID );
		else
			$aMainMember = false;
		
		// begin profile info collecting
		$aNewProfile = array();
		
		foreach( $this -> aItems as $aItem ) {
			$sItemName = $aItem['Name'];
			
			if( array_key_exists( $sItemName, $aData ) ) {
				$aNewProfile[$sItemName] = $aData[$sItemName];
			} elseif( $aMainMember and array_key_exists( $sItemName, $aMainMember ) and $aItem['Type'] != 'system' ) {
				if( $aItem['Unique'] )
					$aNewProfile[$sItemName] = $this -> genUniqueValue( $sItemName, $aMainMember[$sItemName] );
				else
					$aNewProfile[$sItemName] = $aMainMember[$sItemName];
			} else {
				switch( $aItem['Type'] ) {
					case 'pass':
						$aNewProfile[$sItemName] = $this -> genRandomPassword();
					break;
					
					case 'num':
						$aNewProfile[$sItemName] = (int)$aItem['Default'];
					break;
					
					case 'bool':
						$aNewProfile[$sItemName] = (bool)$aItem['Default'];
					break;
					
					case 'system':
						switch( $sItemName ) {
							case 'ID': //set automatically
							case 'Captcha': //not been inserted
							case 'Location': //not been inserted
							case 'Keyword': //not been inserted
							case 'TermsOfUse': //not been inserted
								//pass
							break;
							
							case 'DateReg':
								$aNewProfile[$sItemName] = date( 'Y-m-d H:i:s' ); // set current date
							break;
							
							case 'DateLastEdit':
							case 'DateLastLogin':
								$aNewProfile[$sItemName] = '0000-00-00';
							break;
							
							case 'Couple':
								$aNewProfile[$sItemName] = $aMainMember ? $iMainMemberID : 0; //if main member exists, set him as a couple link
							break;
							
							case 'Featured':
								$aNewProfile[$sItemName] = false;
							break;
							
							case 'Status':
								if ( getParam('autoApproval_ifNoConfEmail') == 'on' ) {
									if ( getParam('autoApproval_ifJoin') == 'on' )
										$aNewProfile[$sItemName] = 'Active';
									else
										$aNewProfile[$sItemName] = 'Approval';
								} else
									$aNewProfile[$sItemName] = 'Unconfirmed';
							break;
						}
					break;
					
					default:
						$aNewProfile[$sItemName] = $aItem['Default'];
				}
			}
		} //we completed collecting
		
		$sSet = $this -> collectSetString( $aNewProfile );
		$sQuery = "INSERT INTO `Profiles` SET \n$sSet";
        
		$rRes = db_res( $sQuery );
        
        if( $rRes ) {
			$iNewID = db_last_id();
			
			$this -> createProfileCache( $iNewID );
			
			if( $aMainMember )
				$this -> updateProfile( $iMainMemberID, array('Couple' => $iNewID ) ); //set main member's couple. they will be linked each other
			
			//collect status text
			if( $bSendMails and !$aMainMember ) { //send mail only to main member, not to couple
				if( getParam('autoApproval_ifNoConfEmail') == 'on' ) {
					if ( getParam('autoApproval_ifJoin') == 'on' ) {
						$sStatusText = 'Active';
						$this -> sendActivationMail( $iNewID );
					} else {
						$sStatusText = 'Approval';
						$this -> sendApprovalMail( $iNewID );
					}
				} else {
					if( $this -> sendConfMail( $iNewID ) )
						$sStatusText = 'Unconfirmed';
					else
						$sStatusText = 'NotSent';
				}
			} else
				$sStatusText = 'OK';
			
			//set crypted password
            $sSalt = genRndSalt();
			$this -> updateProfile($iNewID, array(
                'Password' => encryptUserPwd($aNewProfile['Password'], $sSalt),
                'Salt' => $sSalt
            ));
			
			return array( $iNewID, $sStatusText );
		} else
			return array( false, 'Failed' );
	}
	
	function createProfileCache( $iMemID ) {
		createUserDataFile( $iMemID );
	}
	
	function sendConfMail( $iMemID ) {
		global $site;
		
		$iMemID = (int)$iMemID;
		$aMember = $this -> getProfileInfo( $iMemID );
		if( !$aMember )
			return false;
		
		$sEmail    = $aMember['Email'];
		
		$sConfCode = base64_encode( base64_encode( crypt( $sEmail, CRYPT_EXT_DES ? 'secret_ph' : 'se' ) ) );
		$sConfLink = "{$site['url']}profile_activate.php?ConfID={$iMemID}&ConfCode=" . urlencode( $sConfCode );
		
		$aPlus = array( 'ConfCode' => $sConfCode, 'ConfirmationLink' => $sConfLink );
		
		$aTemplate = $this -> oEmailTemplate -> getTemplate( 't_Confirmation' ) ;
		return sendMail( $sEmail, $aTemplate['Subject'], $aTemplate['Body'], $iMemID, $aPlus );
	}

	// sent when user status changed to active
	function sendActivationMail( $iMemID ) {

		$iMemID = (int)$iMemID;
		$aMember  = $this -> getProfileInfo( $iMemID );
		if( !$aMember )
			return false;

		$sEmail    = $aMember['Email'];
		$aTemplate = $this -> oEmailTemplate -> getTemplate( 't_Activation' ) ;

       	return sendMail( $sEmail, $aTemplate['Subject'], $aTemplate['Body'], $iMemID );
	}

	//sent if member in approval status
	function sendApprovalMail( $iMemId ) {
		
	}
	
	// sent to admin
	function sendNewUserNotify( $iMemID ) {
		global $site;
		
		$iMemID = (int)$iMemID;
		$aMember = $this -> getProfileInfo( $iMemID );
		if( !$aMember )
			return false;

		$oEmailTemplates = new BxDolEmailTemplates();
		$aTemplate = $oEmailTemplates->getTemplate('t_UserJoined');

		return sendMail($site['email_notify'], $aTemplate['Subject'], $aTemplate['Body'], $iMemID);
	}
	
	function updateProfile( $iMemberID, $aData ) {
		if( !$aData or !is_array($aData) or empty($aData) )
			return false;
		
        $this -> _checkUpdateMatchFields($aData);
        
		$sSet = $this -> collectSetString( $aData );
		$sQuery = "UPDATE `Profiles` SET {$sSet} WHERE `ID` = " . (int)$iMemberID;
		//echo $sQuery ;
		db_res($sQuery);
		$this -> createProfileCache( $iMemberID );
		return (bool)db_affected_rows();
	}
	
    /**
    * Check if we need to update profile matching
    */
    function _checkUpdateMatchFields(&$aData) {
        // list of all matchable fields
        $aAllMatchFields = array();
        
        // temporary flag of member
        $aData['UpdateMatch'] = false;
        
        // get array of matching fields
        $oMatchFields = new BxDolProfileFields(101);
        $aMatchFields = $oMatchFields -> aArea[0]['Items'];
        
        // get array of all fields
        $oAllFields = new BxDolProfileFields(100);
        $aAllFields = $oAllFields -> aArea[0]['Items'];
        
        // find all matchable fields
        foreach ($aMatchFields as $iFieldID => $aField) {
            // put it to the list
            $aAllMatchFields[$iFieldID] = $aField['Name'];
            
            // get matched field too
            $iNewFieldID = $aField['MatchField'];
            $aNewField   = $aAllFields[$iNewFieldID];
            
            // and put it to the list too
            $aAllMatchFields[$iNewFieldID] = $aNewField['Name'];
        }
        
        // also need to re-match if Status is changed
        $aAllMatchFields[7] = 'Status';
        
        //echoDbg($aAllMatchFields);
        
        // check if one of updated fields is matchable
        foreach ($aData as $sName => $sValue) {
            //echo $sName . "\n";
            if (in_array($sName, $aAllMatchFields)) {
                $aData['UpdateMatch'] = true;
                break; // if at least one of the fields is matchable then true
            }
        }
        
        //echoDbg($aData);
    }
    
	function collectSetString( $aData ) {
		$sRequestSet = '';
		
		foreach( $aData as $sField => $mValue ) {
			if( is_string($mValue) )
				$sValue = "'" . addslashes( $mValue ) . "'";
			elseif( is_bool($mValue) )
				$sValue = (int)$mValue;
			elseif( is_array($mValue) ) {
				$sValue = '';
				foreach( $mValue as $sStr )
					$sValue .= addslashes( str_replace( ',', '', $sStr ) ) . ',';
					
				$sValue = "'" . substr($sValue,0,-1) . "'";
			} elseif( is_int($mValue) ) {
				$sValue = $mValue;
			} else
				continue;
			
			$sRequestSet .= "`$sField` = $sValue,\n";
		}
		
		$sRequestSet = substr( $sRequestSet,0, -2 );// remove ,\n
		
		return $sRequestSet;
	}
	
	function deleteProfile( $iMemberID ) {
		
	}
	
	function genRandomPassword() {
		return 'aaaaaa';
	}
	
	function getProfileInfo( $iMemberID ) {
		return db_assoc_arr( "SELECT * FROM `Profiles` WHERE `ID` = " . (int)$iMemberID );
	}
	
	function genUniqueValue( $sFieldName, $sValue, $bRandMore = false ) {
		if( $bRandMore )
			$sRand = '(' . rand(1000, 9999) . ')';
		else
			$sRand = '(2)';
			
		$sNewValue = $sValue . $sRand;
		
		$iCount = (int)db_value( "SELECT COUNT(*) FROM `Profiles` WHERE `$sFieldName` = '" . addslashes($sNewValue) . "'" );
		if( $iCount )
			return genUniqueValue( $sFieldName, $sValue, true );
		else
			return $sNewValue;
	}
}