<?php
class Admin_UsersController extends Zend_Controller_Action 
{

	public function init()
	{

		//$this->log = Zend_Registry::get('log');
        $this->view->addHelperPath('library/Atmail/View/Helper/', 'Atmail_View_Helper');
		$this->_helper->pluginCall('initAdminController', $this);
		 
		$this->request  = $this->getRequest();
		$this->view->baseUrl = $this->request->getBaseUrl();
		$this->view->appBaseUrl = $this->request->getBaseUrl() . (strpos($this->request->getBaseUrl(),'index.php')?'':'/index.php');
		$this->view->siteBaseUrl = Zend_Registry::get('siteBaseUrl');
		$this->view->moduleBaseUrl = $this->view->appBaseUrl . ($this->request->module == 'default'?'':DIRECTORY_SEPARATOR . $this->request->module);
		$this->view->global = Zend_Registry::get('config')->global;
		$this->dbAdapter = Zend_Registry::get('dbAdapter');
		$this->dbTables = new dbTables();
		
		require_once 'application/models/admin.php';
		$this->admin = new admin();

		// check is an XML request or not only allow index to be rendered normally (i.e. full page load)
		if ($this->request->action == 'index' )
			return;
        
		if( !isset($this->view->errors) )
			$this->view->errors = array();
        if( !isset($this->view->notices) )
			$this->view->notices = array();
        if( !isset($this->view->jsonIdsToRender) )
			$this->view->jsonIdsToRender = array();
        require_once 'library/jQuery/jQuery.php';

	    require_once('Mail/RFC822.php');

		$this->current_domain = '';
	}

	public function preDispatch() 
	{

		// Check the session is active, otherwise redirect to the login page
		$this->view->userData = $this->admin->getCurrentAdminData();

		if( empty($this->view->userData) ) 
		{

			$this->_forward( 'timeout', 'index', 'default' );
			return;

		}

		// Load a list of the admin users domain-names ( if not superuser )
		$this->view->adminDomains = $this->dbAdapter->fetchCol("select Domain from AdminGroup where Username = " . $this->dbAdapter->quote( Zend_Auth::getInstance()->getIdentity() ) );
        
		Atmail_Locale::setupLocaleAndTranslation( $this->view->userData['Language'] );

		// Setup filters
		$this->filter = Atmail_Filter_Input_Controller::filterInput($this->_request);
		// grab another copy of the parsams
		$this->requestParams = $this->getRequest()->getParams();


	}

	public function indexAction() 
	{
		$DOMAINS_PER_PAGE = $this->view->DOMAINS_PER_PAGE = 20;
		$this->view->domainsTotal = $this->admin->domainList(array('countOnly' => true));
		$this->view->domainsTotalPages = floor($this->view->domainsTotal['count'] / $DOMAINS_PER_PAGE);
		$this->view->domains = $this->admin->domainList(array('page' => 0, 'pageSize' => $DOMAINS_PER_PAGE));
		$this->view->userGroups = $this->admin->groupsListTotals('user');

		$this->view->currentDomain = '';
		$this->view->domain = '';

		//$this->view->numTotalAccounts = users::count();
		//$this->view->numTotalAccounts = count( $this->admin->getDomainAndGroupUsers() );
        //$this->view->activeUsers = count( $this->admin->getDomainAndGroupUsers() );
        $getDomainAndGroupUsersResult = $this->admin->getDomainAndGroupUsers(array('countOnly' => true));
		if( isset($getDomainAndGroupUsersResult[0]) && isset($getDomainAndGroupUsersResult[0]['count']) )
		{
			$this->view->numTotalAccounts = $getDomainAndGroupUsersResult[0]['count'];
		}
		else
		{
			$this->view->numTotalAccounts = 0;
		}
		
		$this->view->numExtAccounts = users::getNumExternalAccounts();

		$this->render('users');

	}

	// Load the contact creation page, using the existing editcontact for code re-use
	public function createAction() 
	{

		$this->view->edit = true;

		if( $this->view->global['demo'] == 1 )
			$this->view->domains = array(0 => array('DomainName' => 'demo.atmail.com'));
		else
			$this->view->domains = $this->admin->domainList();
		$this->view->groups = $this->admin->groupsList('user'); 
		$this->view->domainGroupsList = $this->admin->domainGroupsList(); 
		
		//only show domains and groups that still have seats available
		$this->view->typesAvailable = array();
		foreach( Zend_Registry::get('w4m70Yt0hYUdlM2r2lrrIuY0zgKG4A3vvftu4NbbCWfW') as $k => $v )
		{

			if( $v > 0 )
				$this->view->typesAvailable[] = $k;

		}
		$this->view->defaultLicenseType = 0;
		foreach( $this->view->domainGroupsList as $v )
		{
			
			if( $v['GroupName'] == 'default' )
				$this->view->defaultLicenseType = $v['licenseType'];
			
		}
		if( $this->view->defaultLicenseType == 0 )
			throw new Exception('No available license seats. You must install a valid license.');

		//work out domains and groups that still have licensed seats available
		$this->view->domainsAllowed = array();
		foreach( $this->view->domains as $domain )
		{
			
			//if customised group found for this domain then use its liceneType else use default
			foreach( $this->view->domainGroupsList as $v )
			{

				//if domain has customised domain specific group settings
				if( trim($domain['DomainName']) == trim($v['GroupName']) )
				{
				
					if( in_array($v['licenseType'], $this->view->typesAvailable) )
						$this->view->domainsAllowed[] = $domain['DomainName'];
					continue 2;
				}
				
			}
			if( !in_array($domain['DomainName'], $this->view->domainsAllowed) && in_array($this->view->defaultLicenseType, $this->view->typesAvailable) )
				$this->view->domainsAllowed[] = $domain['DomainName'];
			
		}
		$this->view->groupsAllowed = array();
		foreach( $this->view->domainGroupsList as $v )
		{
			
			//dont include domain specific groups
			foreach( $this->view->domains as $domain )
			{
			 	if( trim($v['GroupName']) == $domain['DomainName'] )
					continue 2;
			}
			if( in_array($v['licenseType'], $this->view->typesAvailable) )
				$this->view->groupsAllowed[] = $v['GroupName'];
			
		}
		
//Zend_Registry::get('log')->debug( "\n\n" . print_r($this->view->typesAvailable,true) . "\n" . __METHOD__ . ' #' . __LINE__ . ": \$this->view->typesAvailable: \n\n");
//Zend_Registry::get('log')->debug( "\n\n" . print_r($this->view->groupsAllowed, true) . "\n" . __METHOD__ . ' #' . __LINE__ . ": \$this->view->groupsAllowed: \n\n");
//Zend_Registry::get('log')->debug( "\n\n" . print_r($this->view->domainsAllowed,true) . "\n" . __METHOD__ . ' #' . __LINE__ . ": \$this->view->domainsAllowed: \n\n");



		if( count($this->view->domainsAllowed) == 0 && count($this->view->groupsAllowed) == 0 )
			throw new Exception('No available license seats. Please add more seats.');
		
		// Create the user record for real
		if( $this->requestParams['NewContact'] ) //saving
		{

            $passwordConfig = Zend_Registry::get('config')->password;

            if( $passwordConfig['use_password_policy'] == 1 )
            {
                //Using a password policy
                $error = "";

                // Load password policy class library
                require_once('Atmail/PasswordPolicy.php');

                // Get password from submitted data or default
                $password = ( isset($this->requestParams['Password']) ) ? $this->requestParams['Password'] : false;
                $rules = Zend_Registry::get('config')->password;

                // Create password policy object
                // Pass rule array in constructor
                $policy = new PasswordPolicy($rules);

                // Validate submitted password
                $valid = $policy->validate($password);

                if( !$valid )
                {
                    foreach( $policy->get_errors() as $k=>$invalid )
                    {
                        $error = $this->view->translate($invalid);
                    }
                    throw new Exception($error);
                }
            }
            else
            {
                if( strlen($this->requestParams['Password']) < 4 )
                {
                    throw new Exception('Password must be at least 4 characters long.');
                }
            }

			$this->requestParams['name'] = $this->requestParams['username'] . '@' . $this->requestParams['domain'];

			$result = $this->admin->userCreate($this->requestParams);

			// User could not be created
			if( $result['status'] == 'failed' ) 
			{

				jQuery::addError( addslashes($result['response']) );

			}
			else
			{

                $this->admin->prepareUserView($this);
				$domStatus = $this->admin->getDomainStatus($this->requestParams['domain']);
				$this->view->contact['DomainStatus'] = $domStatus['response'];
				list($this->view->contact['emailName'], $this->view->contact['emailDomain']) = explode('@', $this->view->contact['Account']);
				jQuery('#Users .user_row[contactid=]')->attr('contactid', $this->requestParams['name']);
				jQuery('#Users .user_row[contactid=' . $this->requestParams['name'] . '] .contactRow')->val($this->requestParams['name']);
				jQuery::evalScript("enableItem($(\"#Users .user_row[contactid='" . $this->requestParams['name'] . "'] .contactRow\"), false)");
				jQuery::evalScript("enableItem($(\"#Users .user_row[contactid='" . $this->requestParams['name'] . "'] .contact_click\"), false)");
				jQuery::evalScript("updateUserCount($('#Users li[DomainName=\'" . $this->requestParams['domain'] . "\'] .unread strong'), '1')");
				jQuery::evalScript("updateUserCount($('#Users li[DomainName=] .unread strong'), '1')");
				jQuery::evalScript('resetDroppables();resetDraggables();');

                // User was successfully created, show the user, select in the list
                jQuery::evalScript( "viewDomain('" . $this->requestParams['domain'] . "', '" . $this->view->contact['Account'] . "');" );

			}

		}
		else //launching new user creation form
		{

			// Else show the new contact screen
			$this->view->contact = array();
			$this->view->contact['NewContact'] = 1;
			$this->view->contact['password'] = $this->admin->generateUserPassword();
			$this->view->defaultUserSettings = Zend_Registry::get('config')->defaultUserSettings;
			$this->view->jsonIdsToRender['contact_info'] = 'users/newuser.phtml';
			$adminInfo = $this->admin->getCurrentAdminData();
			
			// Check the disk quota has not exceeded on editing the user
			
			if($adminInfo['NumQuota'] > 0 && $adminInfo['UMasterAdmin'] != true)
			{

				//Total allocated quota for domain
				$quotaTotal = (Integer)$adminInfo['NumQuota'];
				$quotaAllocated = $this->admin->getUsedQuota();
				$usersTotal = $adminInfo['NumUsers'];
				$usersAllocated = count($this->admin->getDomainAndGroupUsers());

				if($usersTotal-$usersAllocated > 0)
					$this->view->proposedUserNewQuota = round( ($quotaTotal-$quotaAllocated)/($usersTotal-$usersAllocated),0);
				else
					$this->view->proposedUserNewQuota = round( ($quotaTotal-$quotaAllocated) );
					
			}
			else
				$this->view->proposedUserNewQuota = $this->view->defaultUserSettings['UserQuota'];

			if( $this->view->proposedUserNewQuota < 0)
				$this->view->proposedUserNewQuota = 0;

			$this->filter->setData($this->view->contact);
			$this->view->contact = $this->filter->getEscapedData();

		}
		$this->render('global/jsonresponse', null, true);

	}

	public function excludedlinkAction()
	{
		$this->getExcludedGroupsDomains();
	}

	public function excludedAction()
	{
		$this->getExcludedGroupsDomains();
	}

	public function getExcludedGroupsDomains()
	{

		$groups = $this->admin->groupsList('all');
		$domains = $this->admin->domainList();
		$this->view->customizedDomains = array();
		$this->view->customizedGroups = array();

		if(($key = array_search('default', $groups)) !== false)
		{
			unset($groups[$key]);
		}
		foreach($groups as $group)
		{
			$found = false;
			foreach($domains as $domain)
			{
				if($domain['DomainName'] == $group)
				{
					$found = true;
					break;
				}
			}
			if(!$found)
			{
				$this->view->customizedGroups[] = array('GroupName' => $group, 'Users' => $this->admin->userList(false, array(0, 25), false, $group, array('UserFirstName', 'UserLastName')));
			}
		}
		foreach($domains as $domain)
		{
			if(in_array($domain['DomainName'], $groups))
			{
				$this->view->customizedDomains[] = $domain;
			}
		}

		if(count($this->view->customizedDomains) || count($this->view->customizedGroups))
		{
			$this->view->excluded = true;
		}
	}

	public function listAction() 
	{

		$this->view->showingAll = !isset($this->requestParams['domain']) && !isset($this->requestParams['type']) && !isset($this->requestParams['group']);
		$this->view->showingExternal = isset($this->requestParams['domain']) && $this->requestParams['domain'] == 'external';
		$this->view->pageVolume = 25;
		if (!isset($this->requestParams['page'])) 
		{
			$this->view->pageNumber = 1;
			$limit = array(0,$this->view->pageVolume);
		} 
		else
		{
			$this->view->pageNumber = $this->requestParams['page'];
			$start = ($this->view->pageNumber - 1) * $this->view->pageVolume;
			$limit = array($start,$this->view->pageVolume); 
		}
		if( $this->view->global['demo'] == 1 && $this->requestParams['domain'] == 'external' )
		        throw new Exception('Disabled in demo.');
        
		if( $this->view->global['demo'] == 1 )
		        $this->requestParams['domain'] = 'demo.atmail.com';
		
		$this->view->users = array();
		if( isset($this->requestParams['type']) && $this->requestParams['type'] == 'user' )
		{
			$this->view->users = $this->admin->userList($this->requestParams['domain'], $limit, $this->requestParams['searchQuery'], $this->requestParams['group'], array('UserFirstName', 'UserLastName'));
			$this->view->group = $this->requestParams['group'];
			$this->view->listType = $this->requestParams['type'];
		}
		else
		{
			$this->requestParams['group'] = (!isset($this->requestParams['group']) || (isset($this->requestParams['group']) && $this->requestParams['group'] == '')) ? false : true;
			$this->requestParams['domain'] = isset($this->requestParams['domain']) ? $this->requestParams['domain'] : '';
			$this->requestParams['searchQuery'] = isset($this->requestParams['searchQuery']) ? $this->requestParams['searchQuery'] : '';
			$this->view->users = $this->admin->userList($this->requestParams['domain'], $limit, $this->requestParams['searchQuery'], $this->requestParams['group'], array('UserFirstName', 'UserLastName'));
			$this->view->listType = 'domain';
			$this->view->group = $this->requestParams['domain'];
		}

		// TODO: Use the rest query to get total users - Don't use the users module!
		if( isset($this->requestParams['domain']) )
		{

			$this->current_domain = $this->requestParams['domain'];

		}

		if ($this->requestParams['domain'] == 'external') 
			$this->view->totalUsers = users::getNumExternalAccounts();
		elseif( $this->view->listType != 'user' )
		{
			if( !isset($this->requestParams['group']) )
		    	$this->requestParams['group'] = false;
			$allUsers = $this->admin->userList($this->requestParams['domain'], null, $this->requestParams['searchQuery'], $this->requestParams['group'], array('UserFirstName', 'UserLastName', 'countOnly' => true));
			$this->view->totalUsers = $allUsers[0]['count'];
		}
		else
		{

			$this->view->totalUsers = $this->admin->groupTotal($this->requestParams['group']);

		}

		$this->view->domain = $this->current_domain;
		if(isset($this->requestParams['group']))
			$this->view->group = $this->requestParams['group'];
		else
			$this->view->group = false;

		$this->view->searchQuery = $this->requestParams['searchQuery'];
        $this->filter->setData($this->view->users);
        $this->view->users = $this->filter->getEscapedData();

        $this->admin->prepareUserView($this);

        if($this->view->totalUsers == 0)
        {
            $this->view->jsonIdsToRender['address_contacts'] = 'users/listusers.phtml';
            $this->view->jsonIdsToRender['Users #contact_info'] = 'users/viewuser.phtml';
        }
        else
        {
            jQuery::evalScript('$("#Users #primary_content_inner").show()');
            $this->view->jsonIdsToRender['address_contacts'] = 'users/listusers.phtml';
            $this->view->jsonIdsToRender['Users #contact_info'] = 'users/viewuser.phtml';

        }

        $this->_helper->pluginCall('endUserListAction');
        
		$this->render('/global/jsonresponse', null, true);
	}

	public function viewAction() 
	{
		$this->admin->prepareUserView($this);
        $this->view->jsonIdsToRender['contact_info'] = 'users/viewuser.phtml';
		$this->render('/global/jsonresponse', null, true);
	}

	public function editAction() 
	{

        if( strlen($this->requestParams['domain']) > 0 )
        {
            // List type is domain or external
            $this->view->domain = $this->requestParams['domain'];
            $this->view->group = $this->requestParams['listGroup'];
        }
        else
        {
            if( strlen($this->requestParams['listGroup']) > 0 )
            {
                // List type is group
                $this->view->domain = "";
                $this->view->group = $this->requestParams['listGroup'];
            }
            else
            {
                // List type is all
                $this->view->domain = "";
                $this->view->group = "";
            }
        }

		$this->view->edit = true;
		$this->view->contact = $this->admin->userView( $this->requestParams['name'] );
        $this->view->contact['NewContact'] = 0;
		$this->view->groups = $this->admin->groupsList('user');
		
		// Decide if to expand the 'more' options div
		foreach( array('UserWorkCompany', 'UserTitle', 'UserDOB', 'UserURL', 'UserWorkTitle', 'UserWorkDept', 'UserInfo') as $field )
		{

			if( isset($this->view->contact[$field]) && !empty($this->view->contact[$field]) )
			{

				$this->view->contact['ExpandMoreOptions'] = 1;

			}

		}

		$this->filter->setData($this->view->contact);
		$this->view->contact = $this->filter->getEscapedData();

        $this->view->isExternal = users::isExternal($this->view->contact['Account']);

		$this->view->jsonIdsToRender['contact_info'] = 'users/edituser.phtml';
		$this->render('global/jsonresponse', null, true);

	}

	// Load the contact creation page, using the existing editcontact for code re-use
	public function updateAction() 
	{

		if( $this->view->global['demo'] == 1 )
		{
			throw new Exception('Disabled in online demo');
		}

		//convert fields from UI returned format into standard record format (field => value) for update
		if( isset($this->requestParams['numberFieldName']) ) 
		{
			foreach( $this->requestParams['numberFieldName'] as $k => $fieldName ) 
			{ 
				$this->requestParams[$fieldName] = $this->requestParams['numberValue'][$k];
			}
		}

        //Check fields
        // Ensure username given
        if( $this->requestParams['NewUsername'] == NULL || strlen($this->requestParams['NewUsername']) == 0 || $this->requestParams['NewUsername'] == '' )
        {
            throw new Exception('Username can not be empty.');
        }

        //Only check the password parameter if not external
        if (!$this->view->isExternal)
        {
        // Ensure password not empty and meets password policy
        $password = $this->requestParams['Password'];
        if( $this->requestParams['Password'] == NULL || strlen($this->requestParams['Password']) == 0 || $this->requestParams['Password'] == '' )
        {
            throw new Exception('Password can not be empty.');
        }
        require_once('Atmail/PasswordPolicy.php');
        $rules = Zend_Registry::get('config')->password;
        if ($rules['use_password_policy'] == 1)
        {
            //If using a password policy
            // Create password policy object
            $policy = new PasswordPolicy($rules);

            // Validate submitted password
            $valid = $policy->validate($password);

            if( !$valid )
            {
                foreach( $policy->get_errors() as $k=>$invalid )
                {
                    $error = $this->view->translate($invalid);
                }

                throw new Exception($error);
            }
        }
        elseif( strlen($password) < 6 )
        {
            //Not using a password policy and policy less than 6 characters long
            throw new Exception('Password must be at least 6 characters long');
            }
        }

        //Update user data
		$result = $this->admin->userUpdate( $this->requestParams );

		// Add a message on failure, not required for success, obvious enough with the interaction
		if( $result['status'] == 'failed' )
		{
			jQuery::addError( $result['response'] );
		}
		else if(isset($this->requestParams['NewUsername']))
		{
			$username = $this->requestParams['Account'];
			$domain = ($pos = strpos($username, '@')) !== false ? substr($username, $pos + 1) : '';		
			$username = (($domain == '') ? $this->requestParams['NewUsername'] : $this->requestParams['NewUsername'] . '@' . $domain);
			$this->_forward('view', 'users', 'admin', array_merge($this->requestParams, array('name' => $username)));
		}
		else
		{
			$this->_forward('view', 'users', 'admin', array_merge($this->requestParams, array('name' => $this->requestParams['Account'])));
		}
	}

	public function statDomains($accounts)
	{
		$domains = array();

		foreach($accounts as $acc) {
			$domain = explode('@', $acc);
			$domains[] = $domain[1];
		}

		$statDomains = array();

		foreach($domains as $domain) {
			isset($statDomains[$domain])? $statDomains[$domain] += 1 : $statDomains[$domain] = 1;
		}

		return $statDomains;
	}

	public function deleteAction() 
	{

		jQuery::evalScript( 'deleteUserFailed=false;');
		if( $this->view->global['demo'] == 1 )
			jQuery::addError('Disabled in online demo');
        
		else if(empty($this->requestParams['id'])) // Prevent empty deletion
			jQuery::addError('No users supplied to delete');
        
		else
		{
			
			$Accounts = $this->requestParams['id'];
			if( isset($this->requestParams['listType']) && $this->requestParams['listType'] == 'user' )
			{
				$groupName = $this->requestParams['listGroup'];
				$result = $this->admin->groupUsersDelete( $groupName, $Accounts );
				
				if( $result['status'] != 'failed' ) 
				{

					foreach( $Accounts as $Account )
					{
						jQuery('#Users .user_row[contactid=' . $Account . ']')->remove();
					}

					jQuery::evalScript("updateUserCount($('#Users li[groupname=\'" . $groupName . "\'] .unread strong'),'-" . count($Accounts) . "')");
				}
				else
				{
					
					jQuery::evalScript( 'deleteUserFailed=true;');
					if( $result['response']['errorCode'] == 2 )
					{
						
						$pushUsersRemaining = $result['response']['pushUsersRemaining'];
						$pushUsersRequired = $result['response']['pushUsersRequired'];
						jQuery::addError( $this->view->translate('Error removing users from this group:') . ' ' . $this->view->translate("$pushUsersRemaining Push users left, $pushUsersRequired required.") );
						
					}
					else
						jQuery::addError( $result['response']['message'] );
					
				}
				
			}
			else
			{
				$names = $this->requestParams['id'];
				$domains = $this->statDomains($names);

				foreach($names as $name)
				{
					$result = $this->admin->userDelete( $name );
					if( $result['status'] == 'failed' )
					{
						$response = $result['response'];
						jQuery::addError( ( is_array($response) ? $response['message'] : $response) );
						break;
					} 
				}

				if( $result['status'] != 'failed' ) 
				{
					jQuery('#Users .user_row[contactid=' . $name . ']')->remove();

					foreach ($domains as $domain => $count) {
						jQuery::evalScript("updateUserCount($('#Users li[DomainName=\'" . $domain . "\'] .unread strong'), '-" . $count . "')");
					}
					jQuery::evalScript("updateUserCount($('#Users li[DomainName=] .unread strong'), '-" . count($names) . "')");
				}
			}		
		}
		$this->render('/global/jsonresponse', null, true);

	}

	public function groupeditAction()
	{

		$this->view->groupType = $this->requestParams['type'];
		$this->view->groupName = $this->requestParams['groupName']; //TODO: sanitize

        if( $this->view->groupType == "domain" )
        {
            $enabledArray = $this->dbAdapter->fetchCol("select Enable from Domains where Hostname = '" . $this->view->groupName . "'");
            $this->view->domainEnabled = $enabledArray[0];
        }

		$groupGetResultDefault = $this->admin->groupGet( 'default' );
		if( $groupGetResultDefault['status'] != 'success' )
			throw new Exception('Fatal error: default group not found.');
		$this->view->groupDataDefault = $groupGetResultDefault['response']['results'];
		$this->view->defaultLicenseType = $groupGetResultDefault['response']['results']['licenseType'];
		
		$groupGetResult = $this->admin->groupGet( $this->view->groupName );
        $finalInherit = false;
		if( $groupGetResult['status'] == 'success' )
			$this->view->groupData = $groupGetResult['response']['results'];
        else if($this->view->groupType == 'domain')
		{

			//if failed then get default group (domain group does not exist)
			$this->view->groupData = $groupGetResultDefault['response']['results'];
			$this->view->groupData['GroupName'] = $this->view->groupName;
			$finalInherit = true;

		}
		else // non-domain groups are not allowed to not exist if called. only domain groups can not-exist (inherit default)
			throw new Exception( $groupGetResult['response']['message']);
	        $this->view->groupData['inherit'] = $finalInherit;
	}

	public function groupsaveAction()
	{

		if( $this->view->global['demo'] == 1 )
			throw new Exception('Disabled in online demo');

		$fields = $this->requestParams['fields'];
		if( $fields['inherit'] == '0' && $fields['currentGroupName'] == 'default')
			jQuery::addError('Fatal error: Not allowed');
		else
		{

            if( $fields['disable'] == '1' )
            {
                // Enable the group if it is currently disabled
                $result = $this->admin->domainUnlock($fields['currentGroupName']);
                if( $result['status'] == 'failed' )
                    jQuery::addError( $this->view->translate('Error enabling the domain') );
            }
            elseif( $fields['disable'] == '0' )
            {
                // Disable the group if it is currently enabled
                $result = $this->admin->domainLock($fields['currentGroupName']);
                if( $result['status'] == 'failed' )
                    jQuery::addError( $this->view->translate('Error disabling the domain') );
            }

            if( $fields['inherit'] == '1' )
            {
                //remove from database Groups
                $result = $this->admin->groupDelete($fields['currentGroupName']);

                // its ok
                $result['status'] = 'success';
            }
            else
            {
                $result = $this->admin->groupUpdate( $fields['currentGroupName'], $fields );
            }

            if( $result['status'] == 'success' )
				jQuery::addMessage( $this->view->translate('Group updated successfully') );
	        else
			{
			
			    if( $result['response']['errorCode'] == 1 )
				{                                                                                                                                 
					$pushUsersRemaining = $result['response']['pushUsersRemaining'];
					$pushUsersRequired = $result['response']['pushUsersRequired'];
					jQuery::addError( $this->view->translate('Error updating group:') . ' ' . $this->view->translate("$pushUsersRemaining Push users left, $pushUsersRequired required.") );
					jQuery('#Push')->removeAttr('checked');    
					jQuery('#Push')->trigger('change');    
				}
				else
					jQuery::addError( $this->view->translate('Error updating group:') . (is_array($result['result']) && array_key_exists('message', $result['response']) ? $result['response']['message'] : $result['response']) );
			}
			
		}
		$this->render('/global/jsonresponse', null, true);
	
	}

	public function adduserstogroupAction()
	{

		if( $this->view->global['demo'] == 1 )
			throw new Exception('Disabled in online demo');
		
		if( isset($this->requestParams['groupNameTo']) )
		{

			$result = $this->admin->groupUsersAdd( $this->requestParams['groupNameTo'], $this->requestParams['id'] );
			
			//TODO: get propper metrics to calculate how to updateCounts
			if( $result['status'] != 'failed' )
			{ 

			    //find new cound for this user group
				$userGroups = $this->admin->groupsListTotals('user');
				foreach( $userGroups as $userGroup )
					jQuery::evalScript("updateUserTotal($('#Users li[groupname=\'" . $userGroup['GroupName'] . "\'] .unread strong'), " . $userGroup['totalUsers'] . ");");
			
			}
       		else
			{
				if( $result['response']['errorCode'] == 1 )
				{

					$pushUsersRemaining = $result['response']['pushUsersRemaining'];
					$pushUsersRequired = $result['response']['pushUsersRequired'];
					jQuery::addError( $this->view->translate('Error moving users:') . ' ' . $this->view->translate("Insufficient Push seats: $pushUsersRemaining Push users left, $pushUsersRequired required.") );

				}
				else
					jQuery::addError( $result['response']['message'] );  

			}

		}
		$this->render('/global/jsonresponse', null, true);

	}

	public function addphotoAction() 
	{
		require_once 'library/Atmail/ThumbNail.php';

		if( $this->view->global['demo'] == 1 )
		{

			throw new Exception('Disabled in online demo');

		}

		$retries = 0;
		$filename = '';
		while(is_file($filename) || $filename == '' && $retries++ < 3)
		{
	        $filename = users::getTmpFolder() . uniqid() . '.' . Thumbnail::findFormat($_FILES['UserPhoto']['name']);
		}
		if( !move_uploaded_file($_FILES['UserPhoto']['tmp_name'], $filename))
		{
			echo $this->view->translate('Unable to upload photo');
		}

		if(function_exists("gd_info"))
		{
			$this->_createThumbnail($filename , $filename, 110, 110);
		}
        
		$UserPhotoBase64 = base64_encode(file_get_contents($filename));
        
		require_once('contacts.php');
		$this->_contacts = new contacts(array('admin' => true));
		$this->_contacts->uploadUserPhoto(array('id' => $this->requestParams['id'], 'GroupID' => (isset($this->requestParams['GroupID']) ? $this->requestParams['GroupID'] : GROUP_GLOBAL), 'UserPhoto' => $UserPhotoBase64));
		$this->_helper->viewRenderer->setNoRender();
        echo 'success';
	}

	private function _createThumbnail($sourcePath, $destPath, $w, $h, $q = 100) 
	{

		require_once 'library/Atmail/ThumbNail.php';

		$thumb = new Thumbnail($sourcePath);
		if($thumb->init_success)
		{
			$thumb->resize($w, $h);
			$thumb->cropFromCenter(60);
			$thumb->save($destPath, $q);
		}
	}

	public function viewphotoAction() 
	{

		require_once('contacts.php');

		// TODO: admin a quick hack/workaround to avoid error
		$contacts = new contacts(array('admin' => true));
        $photoContent = $contacts->viewUserPhoto($this->requestParams);
		
		if( $photoContent == false )
		{
			
			//if no photo then serve default
			$photoContent = file_get_contents(APP_ROOT . "images/themes/fresh/contact-photo.png");
			
		}
	
		
		// TODO: Convert all images to jpeg
		$this->getResponse()
			 ->setHeader('Content-Type','image/jpeg')
			 ->appendBody( $photoContent );

		$this->_helper->viewRenderer->setNoRender(); 

	}
	
	public function importAction()
	{
		
		$this->view->jsonIdsToRender['contact_info'] = 'users/import.phtml';
		$this->render('global/jsonresponse', null, true);
		
	}
	
	// Upload the specified file to import users - Do a sanity check of the file and prompt to the user the import status
	public function importcsvAction()
	{

		if( $this->view->global['demo'] == 1 )
		{
			throw new Exception('Disabled in online demo');
		}
		
		// Step 1, upload the user import file
		$tmpfname = tempnam(APP_ROOT . 'tmp/', "user-import");

		if( !move_uploaded_file($_FILES['csvImport']['tmp_name'], $tmpfname)) {
			$this->getResponse()
				 ->setHeader('Content-Type','text/html')
				 ->appendBody( "Unable to upload user CSV" );
				
			return $this->_helper->viewRenderer->setNoRender();
		}
		
		$row = 0;
		
		if (($handle = fopen($tmpfname, "r")) !== FALSE) {
			
		    while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
				if($row == 0 && preg_match('/(.*)@(.*)/', $data[0])) {
					$this->getResponse()
						 ->setHeader('Content-Type','text/html')
						 ->appendBody( "CSV header row missing. Please check formatting and try again. Correct format is Email, FirstName, LastName, Password" );
						
					return $this->_helper->viewRenderer->setNoRender();
				}
				
				// Sanity check the CSV file, does the first row contain an email address?
				if($row != 0 && !preg_match('/(.*)@(.*)/', $data[0])) {
					$this->getResponse()
						 ->setHeader('Content-Type','text/html')
						 ->appendBody( "Specified CSV file does not contain an email address" );
						
					return $this->_helper->viewRenderer->setNoRender();
				}
				
				// Sanity check the CSV file, does the first row contain an email address?
				if($row != 0 && (empty($data[3])) ) {
					$this->getResponse()
						 ->setHeader('Content-Type','text/html')
						 ->appendBody( "Specified CSV file does not contain a password. Correct format is Email, FirstName, LastName, Password" );
						
					return $this->_helper->viewRenderer->setNoRender();
				}
				
				$row++;
				
			}
		}
		
		$row--;
		
		// Only allow 5k maximum users to import at a time
		if($row > 5000) {
			$this->getResponse()
				 ->setHeader('Content-Type','text/html')
				 ->appendBody( "Maximum CSV user import reached. Please import users in batches of 5,000 users at a time." );
				
			return $this->_helper->viewRenderer->setNoRender();
		}
		
		$this->getResponse()
			 ->setHeader('Content-Type','text/html')
			 ->appendBody( $this->view->translate("$row users to import") . "<input type='hidden' name='tmpfname' value='" . basename($tmpfname) . "'/>" );

		$this->_helper->viewRenderer->setNoRender(); 
	}
	
	
	public function importuploadAction()
	{

		if( $this->view->global['demo'] == 1 )
		{
			throw new Exception('Disabled in online demo');
		}		
		
		$row = 0;
		$num = array();
		$update = array();
		$duplicate = 0;
		
		// Use basename to escape any nasties
		$tmpfname = APP_ROOT . 'tmp/' . basename($this->requestParams['tmpfname']);
		
		if(!file_exists($tmpfname))	{
			jQuery::addError( $this->view->translate('Upload CSV file cannot be found') );
			return $this->render('global/jsonresponse', null, true);
		}
		
		$rfc822 = new Mail_RFC822;

		if (($handle = fopen($tmpfname, "r")) !== FALSE) {
			
		    while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
		
				$userEmail = strtolower($data[0]);
				
				// Skip the CSV header row
				if($row == 0) {
					$row++;
					continue;
				}
				
				// Skip duplicate accounts
				if( !empty($num[$userEmail]) ) {
					$duplicate++;
					continue;
				}
				
				$emailObject = $rfc822->parseAddressList(stripslashes($userEmail), null, false);

				// If no valid email returned, skip importing the row
				if(gettype($emailObject) != "array")
				{
					continue;
				}
				
				if(!empty($userEmail) && !empty($data[3])) {

					// Step 2. Add the domain into the system if its not defined
					$domain = $emailObject[0]->host;
					
					$result = $this->admin->domainCheck($domain);
					
					// Step 2.5 Add the missing domain if not already in the system ( and checked in the import screen )
					if($result['status'] == 'failed' && !empty($this->requestParams['addDomain']))	{
						$this->admin->domainCreate($domain);
					}

					// Step 3. If a new user, create the account in the system
					// Optionally send the welcome email
					if(!empty($this->requestParams['sendWelcome']))
						$skipWelcome = false;
					else
						$skipWelcome = true;
					
					// Fire off the API call to create the user
					$result = $this->admin->userCreate(array('name' => $userEmail, 'UserFirstName' => $data[1], 'UserLastName' => $data[2], 'Password' => $data[3], 'skipWelcome' => $skipWelcome));

					// Count how many users are imported
					if($result['status'] != 'failed')
						$num[$userEmail]++;
						
					if(!empty($this->requestParams['updatePass']) && $result['status'] == 'failed' && $result['response'] == $userEmail . ' already exists') {
						
						// Update the users password, already exists on the system
						$result = $this->admin->userUpdate(array('Account' => $userEmail, 'Password' => $data[3]));
						
						// Count the number of password 
						$update[$userEmail]++;
						
					}
										
				}
				
		        $row++;
		    }
		    fclose($handle);
		}

		// Remove the temporary file used to upload the CSV
		unlink($tmpfname);
		
		$status = count($num) . $this->view->translate(" users(s) successfully imported. ");
		
		if(!empty($duplicate))
			$status .= $duplicate . $this->view->translate( " duplicate accounts detected in CSV file. ");
		
		if(count($update) > 0)
			$status .= count($update) . $this->view->translate(" user(s) passwords updated. ");
			
		jQuery::addMessage( $status );
		jQuery('SPAN.importStatus')->html('');
		
		$this->render('global/jsonresponse', null, true);
		
	}

}
