<?php
class Admin_DashboardController extends Atmail_Controller_Action 
{
	var $eximQueueItem;
	
	public function init()
	{
	    $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->moduleBaseUrl = $this->view->appBaseUrl . ($this->request->module == 'default'?'':DIRECTORY_SEPARATOR . $this->request->module);
		$this->view->siteBaseUrl = Zend_Registry::get('siteBaseUrl');
		$this->view->global = Zend_Registry::get('config')->global;
		
		require_once 'library/jQuery/jQuery.php';
		require_once 'application/models/admin.php';
		$this->admin = new admin();

		
	}
	
	public function preDispatch() 
	{
		
		// Check the session is active, otherwise redirect to the login page
		$this->view->userData = $this->admin->getCurrentAdminData();
		
		if( $this->view->userData == null || empty($this->view->userData) ) 
		{

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

		}
		
		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();
		
		try 
		{
		
			$this->view->allLicensesExpired = Zend_Registry::get('w4m70Yt0hYNduM2r2lrrIuY0zgKG4A3vvftl4UbbCWfW');
			
		}
		catch( Exception $e )
		{
			
			$this->view->allLicensesExpired = false;
			
		}
		
		

		
	}
	
	public function indexAction() 
	{

	}
	
	public function graphsAction() 
	{

	}

	public function loginAction() 
	{
		
		$this->view->dlid = Zend_Registry::get('config')->reg['downloadId'];	
		$this->view->userData = $this->admin->getCurrentAdminData();
		
		
		// Select day, month, year
		if(empty($this->request->view))
		{
			
			$this->view->view = "day";
			
		}
		else
		{
			
			$this->view->view = $this->request->view;
			
		}
		
	}
	
	public function recvAction() 
	{
		
		// Select day, month, year
		if(empty($this->request->view))
		{
			
			$this->view->view = "day";
			
		}
		else
		{
			
			$this->view->view = $this->request->view;
			
		}
		
	}

	public function sentAction() 
	{
		
		// Select day, month, year
		if(empty($this->request->view))
		{
			
			$this->view->view = "day";
			
		}
		else
		{
			
			$this->view->view = $this->request->view;
			
		}
		
	}

	public function spamAction() 
	{
		
		// Select day, month, year
		if(empty($this->request->view))
		{
			
			$this->view->view = "day";
			
		}
		else
		{
			
			$this->view->view = $this->request->view;
			
		}

	}

	public function virusAction() 
	{
	
		
		// Select day, month, year
		if( empty($this->request->view) )
		{
			
			$this->view->view = "day";
			
		}
		else
		{
			
			$this->view->view = $this->request->view;
			
		}

	}
	
	public function subadminAction()
	{
		
		// Check the user account quota is not exceeded
		$this->view->activeUsers = count( $this->admin->getDomainAndGroupUsers() );
		$this->view->availUsers = $this->view->userData['NumUsers'] - $this->view->activeUsers;
		if( $this->view->availUsers < 0 )
		{
			
			$this->view->availUsers = 0;
			
		}
        if($this->view->userData['NumUsers'] == 0)
        {
            // no users allocated
            $this->view->availUserPercentage = 0;
        }
        else
        {
            $this->view->availUserPercentage = round( ($this->view->availUsers / $this->view->userData['NumUsers']) * 100, 1 );
        }
		$this->view->usedUserPercentage = round( 100 - $this->view->availUserPercentage, 1 );
        if( $this->view->usedUserPercentage > 100 )
		{
			
			$this->view->usedUserPercentage = '100';
			
		}
		
		$this->view->currentQuota = $this->admin->getUsedQuota(); //allocated to users (MB)
		if($this->view->currentQuota == '') $this->view->currentQuota = 0;
		$this->view->availQuota = round($this->view->userData['NumQuota'] - $this->view->currentQuota, 1);
		if( $this->view->availQuota < 0 )
		{
			
			$this->view->availQuota = 0;
			
		}	
		if( $this->view->userData['NumQuota'] > 0 ) 
		{
		
			$this->view->availDiskPercentage = round( ($this->view->availQuota / $this->view->userData['NumQuota']) * 100, 1);
			$this->view->usedDiskPercentage = round(100 - $this->view->availDiskPercentage, 1);
			
			if( $this->view->usedDiskPercentage > 100 )
			{
				
				$this->view->usedDiskPercentage = '100';
				
			}
		
		}

		$this->render('subadmin');
		
	}
	
	public function versionAction() 
	{

		require_once("Atmail/General.php");
		try 
		{

			$res = fetchLatestVersion();

		} 
		catch (Exception $e) 
		{

			if( $e->getMessage() == 'cache_dir is not writable' ) 
			{

				Zend_Registry::get('log')->debug($e->getMessage() . ' : Cache disabled.');
				jQuery::addError('Unable to activate cache. Make sure tmp folder is owned by the web server user and has sufficient permissions: ' . APP_ROOT . 'tmp/' );

			}
			else 
			{
			
				throw $e;
			
			}
			
		}
		// Check the response
		if( $res )
		{
			$res = trim($res);
			$versions = explode("\n", $res);
			
			$latestVersion = '0.0';
			$priority = 0;
			$majorUpdate = false;
			if(count($versions) == 1)
			{
				$test = explode("|", $versions[0]);
				if(count($test) == 3)
				{
					$majorUpdate = true;
					$message = "<br>";	
				}
			}
			if(!$majorUpdate)
			{
				sort($versions, SORT_NUMERIC);
				$patches_available = false;

				foreach($versions as $version)
				{
					$versionArray = explode('|', $version);
					$versionTestNumber = $versionArray[0];
					$versionTestMessage = $versionArray[1];
					$versionTestExpiryDate = $versionArray[2];
					$versionPriority = 1;	// always crit unless specified
					if( isset($versionArray[3]))
					{
						$patches_available = true;
						$versionPriority = $versionArray[3];
					}
					if($patches_available)
					{
						if($versionPriority == 1)
						{
							$type = "Critical";	
						}
						else
						{
							$type = "Minor";	
						}
						$message .= $versionTestNumber . " : " . $type . " - " . $versionTestMessage . "<br>";
					}
					else
					{
						$message = $versionTestMessage;	
					}
					
					if(version_compare($latestVersion, $versionTestNumber)==-1)
					{
						$latestVersion = $versionTestNumber;
						$expiryDate = $versionTestExpiryDate;
					}				
		
					if($versionPriority > $priority)
					{
						$priority = $versionPriority;
					}
				}
			}
			else
			{
				list($latestVersion, $message, $expiryDate) = explode("|", $versions[0]);
			}
			$expiryDate = Zend_Registry::get('config')->reg['expiry'];
			// Update the expiry date
			/*
			if( empty($expiry) || strtotime($expiryDate) != strtotime($expiry) )
			{
				$arr = array('expiry' => $expiryDate);
				require_once 'application/models/config.php';
				config::save('reg', $arr);
			}
			*/
			
			$showDownload = false;
			$showDiv = 0;
			// Load version string from webmail root
			$myVersion = trim(file_get_contents('.VERSION'));
			$storeUrl = "http://atmail.com/store/index.php?Type=" . (Zend_Registry::get('config')->global['install_type']=='server'?'Server':'Webmail');
			
			if (version_compare($latestVersion, $myVersion) == 1) 
			{
				
				if(!$patches_available)
				{
				
					$message = 'Your Atmail version is out of date. Atmail ' . $latestVersion . ' is now available. ' . $message;
				
				}
				else
				{
				
					$showDownload=true;
					// patches available
					if($priority == 1)
					{
				
						//critical
						$message = 'Your Atmail version is out of date. A critical patch ' . $latestVersion . ' is now available. It is HIGHLY recommend that you apply this version.<br><br>' . $message . "<br>";
				
					}
					else
					{
				
						$message = 'Your Atmail version is out of date. A minor patch ' . $latestVersion . ' is now available. It is optional that you apply this version.<br><br>' . $message . "<br>";
				
					}	
				
				}
				$showDiv = 1;
			
			}
			elseif( !(time() > strtotime($expiryDate)) && (time() > (strtotime($expiryDate) - (30 * 24 * 60 * 60))))
			{
				$message = $this->admin->getLicenseStatusApproachingExpired();
				$showDiv = 1;

			}
			elseif( time() > strtotime($expiryDate) ) 
			{
				
				$message = $this->admin->getLicenseStatusExpired();
				$showDiv = 1;

			}
			elseif( $this->view->allLicensesExpired == true )
			{
			    $message = "License(s) expired. Purchase a license via the <a href=\"" . $storeUrl . "\" target=\"_blank\">Atmail store</a>.";
				$showDiv = 1;
			}

			if( !(( !(time() > strtotime($expiryDate)) && (time() > (strtotime($expiryDate) - (30 * 24 * 60 * 60))))) && version_compare($latestVersion, Zend_Registry::get('config')->global['version']) == -1 )
			{
				$showDiv = 0;	
			}
			
			if( !empty($showDiv) )
			{
				if($priority == 1)
				{
					// critical Update
					jQuery::evalscript("$('.versionDiv').addClass('critical');");	
				} 
				if($showDownload)
				{
					$dlid = Zend_Registry::get("config")->reg['downloadId'];
					$message .= '<strong><a target="_blank" href="http://atmail.com/portal/?DownloadID=' . $dlid . '">Download Now</a></strong><br><br>';
				}
				if($patches_available)
				{
					jQuery::evalscript("$('.versionDiv').addClass('licence-expanded');$('.versionDiv SPAN:first').addClass('licence-expanded');");	
				}
			    jQuery::evalscript("$('.versionDiv SPAN:first').html('$message')");
				jQuery::evalscript("$('.versionDiv').show()");

			}

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

	}

	// Verbose log view
	public function logAction()
	{
		
		$this->view->filter = $this->requestParams['filter'];		
		$this->view->log = $this->requestParams['log'];
		$this->view->type = $this->requestParams['type'];
		$this->view->view = $this->requestParams['view'];
		$this->view->index = $this->requestParams['index'];
		
		// Defaults
		if( empty($this->view->log) )
			$this->view->log = 'Log_Login';

		if( empty($this->view->view) )
			$this->view->view = 'week';
		
			
	}

	/**
	 * Figure out if the queue data in the db is new enough
	 * @return Boolean Is the data new enough?
	 */
	public function queueage()
	{
		//get existing db records.
		$dbConfig = Zend_Registry::get('dbConfig');
		$dbAdapter = Zend_Registry::get('dbAdapter');
    
		$sql = 'SELECT TIMESTAMPDIFF(SECOND,logDate,NOW()) AS seconds FROM eximqueue ORDER BY logDate LIMIT 1';
		$result = $dbAdapter->query($sql);

		$rows = $result->fetchAll();
		
		$seconds = $rows[0]['seconds'];

		return $seconds;
	}
	
	/**
	 * Figure out if the queue data in the db is new enough
	 * @return Boolean Is the data new enough?
	 */
	public function isQueueToOld($seconds = null)
	{
		if(is_null($seconds))
		{
			$seconds = $this->queueage();
		}
		
		if ($seconds > 120) {
			return false;
		}
		
		return true;
			
	}
	
	// manage the EXIM queue
	public function queueAction()
	{
		// check if the queue needs to be refreshed
		// 
		
		/**
		 * How old is the cache of the exim queue in the database
		 * @var Integer
		 */
		$seconds = $this->queueage();

		/**
		 * If the queue info in the db is to old then reload it
		 */
		if($this->isQueueToOld($seconds) == false) {
			$this->queueload();
		}
		
		/*
		$this->view->filter = $this->requestParams['filter'];		
		$this->view->log = $this->requestParams['log'];
		$this->view->type = $this->requestParams['type'];
		$this->view->view = $this->requestParams['view'];
		$this->view->index = $this->requestParams['index'];
		
		// Defaults
		if( empty($this->view->log) )
			$this->view->log = 'Log_Login';

		if( empty($this->view->view) )
			$this->view->view = 'week';
		*/
		
			
	}
	
	/**
	 * Delete one message from the queue and the queue data in the db
	 * @return Boolean returns true if sucesssful
	 */
	public function deletemessageAction()
	{
		$this->_helper->viewRenderer->setNoRender();
		
		$messageId = $this->requestParams['currentId'];

		if($messageId == '')
		{
			continue;
		}

		//get existing db records.
		$dbConfig = Zend_Registry::get('dbConfig');
		$dbAdapter = Zend_Registry::get('dbAdapter');

		// delete the message from the exim queue
		// 
		$sys_command = '/usr/local/atmail/mailserver/bin/exim -Mrm ' . $messageId;

		system($sys_command);	
		
		// var_dump($sys_command);

		// delete the message from the eximqueue table
		$sql = "DELETE FROM eximqueue WHERE messageId = '$messageId'";
		$result = $dbAdapter->query($sql);

		//$this->APIArgs['method'] = 'queueDeleteMessage';
		//$this->restserver->handle($this->APIArgs);
	
		// $this->render('global/jsonresponse', null, true);
	}
	
	public function logsearchAction()
	{
		
		// Feature for master admin or subadmin ( if enabled ) only
		if( $this->view->userData['UMasterAdmin'] != '1' )
		{
			
		//	if( $this->view->userData['ULogs'] != '1')
		//		throw new Exception('MasterAdmin rights required.');
			
		}
				
		$this->view->filter = $this->requestParams['filter'];		
		$this->view->log = $this->requestParams['log'];
		$this->view->type = $this->requestParams['type'];
		$this->view->view = $this->requestParams['view'];
		$this->view->index = $this->requestParams['index'];
		
		$this->view->logs = $this->admin->logsearch( array('filter' => $this->requestParams['filter'], 'log' => $this->view->log, 'type' => $this->view->type, 'view' => $this->view->view, 'Range' => $this->requestParams['LogRange'], 'index' => $this->requestParams['index'] )); 
		
		// Next, build the select box
		$count = $this->view->logs[0];
		
		$pages = $count / 100;
		$arr = array();
		for($i = 0; $i < $pages; $i++)	{
			$index = $i * 100;
			$page = $i + 1;
			$arr[] = "<option value='$index'>Page $page</option>";
		}
		
		$this->view->pagination = implode("\n", $arr);	
		
	}
	
	/**
	 * takes on line from the exim queue export and parses it for inserting into the database
	 * @param  String $line
	 */
	public function eximLineToDB($line)
	{
		/*
		 * CREATE TABLE IF NOT EXISTS `eximqueue` (
		  `id` int(11) NOT NULL AUTO_INCREMENT,
		  `messageId` varchar(16) COLLATE utf8_unicode_ci NOT NULL,
		  `lineType` enum('main','recipent') COLLATE utf8_unicode_ci NOT NULL,
		  `lineStatus` enum('frozen','delivered','neutral') COLLATE utf8_unicode_ci NOT NULL DEFAULT 'neutral',
		  `recipient` varchar(128) COLLATE utf8_unicode_ci DEFAULT NULL,
		  `sender` varchar(128) COLLATE utf8_unicode_ci DEFAULT NULL,
		  `age` int(11) DEFAULT NULL,
		  `size` int(11) DEFAULT NULL,
		  `sessionId` varchar(32) COLLATE utf8_unicode_ci DEFAULT NULL,
		  `logDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
		  PRIMARY KEY (`id`),
		  KEY `messageId` (`messageId`),
		  KEY `lineType` (`lineType`,`lineStatus`)
		) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;

		 */
		
		//get existing db records.
		$dbConfig = Zend_Registry::get('dbConfig');
		$dbAdapter = Zend_Registry::get('dbAdapter');
		
		// replace the frozen from blank lines with a TAG
		// <> *** frozen ***
		$line = str_replace ( "<> *** frozen ***" , "TAG_FROZEN_FROM_BLANK" , $line );
			
		// replace the remaining empty senders with a TAG
		// <>
		$line = str_replace ( "<>" , "TAG_FROM_BLANK" , $line );
			
		// remove the brackets around the sender
		$line = str_replace ( "<" , "" , $line );
		$line = str_replace ( ">" , "" , $line );
			
		// reduce all the spacing between variables to a single space
		$line = preg_replace( '/\s+/', ' ', $line );
		
		$parts = explode(' ', trim($line));
			
		$count = count($parts);
			
					
		if($parts[0] != "")
		{
			if($count >= 3)
			{
				$this->eximQueueItem['messageId'] = $parts[2];
				
				if ($parts[3] == "TAG_FROZEN_FROM_BLANK") {
					$lineStatus = 'frozen';
				}
				else {
					$lineStatus = 'neutral';
				}
				
				// age
				$age_switch = mb_substr($parts[0],-1);
				$age_units =  mb_substr($parts[0],0,-1);
				
				switch ($age_switch) {
					case "m":
						$age_mins = $age_units;
						break;
					case "h":
						$age_mins = $age_units * 60;
						break;
					case "d":
						$age_mins = $age_units * 60 * 24;
						break;
				}

				$this->age_mins = $age_mins;
				
				// size
				$size_switch = mb_substr($parts[1],-1);
				$size_units =  mb_substr($parts[1],0,-1);
				
				switch ($size_switch) {
					case "K":
						$size_k = $size_units;
						break;
					case "M":
						$size_k = $size_units * 1024;
						break;
				}
				
				$dbAdapter->insert("eximqueue", array(
						'messageId' => $this->eximQueueItem['messageId'],
						'sender' => $parts[3],
						'lineStatus' => $lineStatus,
						'age' => $age_mins,
						'size' => round($size_k,0)
				),true);
			}
			else
			{
				if($parts[0] == "D")
				{
					$dbAdapter->insert("eximqueue", array(
							'messageId' => $this->eximQueueItem['messageId'],
							'recipient' => $parts[1],
							'lineType' => 'recipent',
							'age' => $this->age_mins,
							'lineStatus' => 'delivered'
							
					),true);
				}
				else
				{
					$dbAdapter->insert("eximqueue", array(
							'messageId' => $this->eximQueueItem['messageId'],
							'recipient' => $parts[0],
							'lineType' => 'recipent',
							'age' => $this->age_mins,
							'lineStatus' => 'neutral'
							
					),true);
				}
			}
		}
	}
	
	/**
	 * Displays the initial static queue page
	 */
	public function queuepageAction()
	{
		//get existing db records.
		$dbConfig = Zend_Registry::get('dbConfig');
		$dbAdapter = Zend_Registry::get('dbAdapter');
    
		//  check if we have a current queue in the database, if we do not then
		//  call queueload() to get an updated queue loaded
		
		$this->view->index = $this->requestParams['index'];
		
		// Defaults
		if( empty($this->view->index) ) {
			$this->view->index = 0;
		}
		
		// Number of records
		$sql = "SELECT count(id) AS idcount FROM eximqueue WHERE lineType = 'main'";
		$result = $dbAdapter->query($sql);
		$rows = $result->fetchAll();
		$msgCount = $rows[0]['idcount'];

		if($msgCount > 0)
		{
			
		$index = $this->view->index;

		$start_index = 0;
		if($index >= 100)
		{
			$start_index = $index - 100;
		}
		
		// First and last id for the sub query
		$end_index = $start_index + 100;

		if($end_index == $msgCount)
		{
			$end_index--;
		}

		if($msgCount < 100)
		{
			$end_index = $msgCount -1;
		}

		$sql = "(select id, messageId from eximqueue group by messageId order by id ASC limit $start_index,1) UNION (select id, messageId from eximqueue group by messageId order by id ASC limit $end_index,1)";

		$result = $dbAdapter->query($sql);
		$rows = $result->fetchAll();
		$firstID = $rows[0]['id'];

		if($end_index == 0)
		{
			$lastID = $rows[0]['id'];
			$lastMessageId = $rows[0]['messageId'];
		}
		else
		{
			$lastID = $rows[1]['id'];
			$lastMessageId = $rows[1]['messageId'];
		}

		// fetch all the rows for the 100 messages in our page
		$sql = "SELECT * FROM eximqueue WHERE id >= $firstID AND id <= (SELECT MAX(id) FROM eximqueue WHERE messageId = '$lastMessageId') ORDER BY age ASC, messageId";

		$result = $dbAdapter->query($sql);
		$this->view->rows = $result->fetchAll();

		$pages = $msgCount / 100;

		}
		else {
			$this->view->rows = null;
			$pages = 0;
		}

		
		
		$arr = array();
		for($i = 0; $i < $pages; $i++)	{
			$index = ($pages - $i) * 100;
			$page = $i + 1;
			$arr[] = "<option value='$index'>Page $page</option>";
		}
		
		$this->view->pagination	= implode("\n", $arr);
		$this->view->rowcount   = $msgCount;

		// var_dump($msgCount);
		
	}
	
	
	public function queueload()
	{
		
		//get existing db records.
		$dbConfig = Zend_Registry::get('dbConfig');
		$dbAdapter = Zend_Registry::get('dbAdapter');
		
		// clear out the old entries
		$dbAdapter->query("DELETE FROM eximqueue");
		
		
		system('/usr/local/atmail/mailserver/bin/exim -bp > /usr/local/atmail/webmail/log/tmpspool.txt');
		$log_file = '/usr/local/atmail/webmail/log/tmpspool.txt';
		
		// $log_file = '/usr/local/atmail/webmail/log/spool.txt';
		
		$file = new SplFileObject($log_file);
		
		$file->setFlags(SplFileObject::DROP_NEW_LINE);
		foreach ($file as $row) {
			$this->eximLineToDB($row);
		}
	}
	
	/**
	 * Wrapper to allow an ajax call to force a refresh of the queue cache
	 */
	public function queueloadAction()
	{		
		// setup the pagination
		$this->queueload();
	}
	
	public function logexportAction()
	{
		$this->_helper->viewRenderer->setNoRender();
		
		$csv = $this->admin->logsearch( array('all' => 1, 'log' => $this->requestParams['log'], 'type' => $this->requestParams['type'], 'view' => $this->requestParams['view'] )); 

		// Output the VCF file
		$this->getResponse()->setHeader('Content-Type','text/csv')
			->setHeader('Content-Disposition', "attachment; filename=atmail-" . $this->requestParams['log'] . "-" . $this->requestParams['view'] . ".csv");		
		
		// Export the header ( Account, id, etc )
		echo( $this->array_to_csv_header($csv[1][0]) );
		
		// Export each line
		foreach($csv[1] as $line)	{
			echo( $this->array_to_csv($line) );
		}
		
	}
	
	// Public functions
	public function summaryAction() {
	
		$this->view->dlid = Zend_Registry::get('config')->reg['downloadId'];	
		$this->view->userData = $this->admin->getCurrentAdminData();
		
		
		// Select day, month, year
		if(empty($this->request->view))
		{
			
			$this->view->view = "day";
			
		}
		else
		{
			
			$this->view->view = $this->request->view;
			
		}
			
	}
	
	// Private functions	
	private function array_to_csv($data, $delim = ",", $newline = "\n", $enclosure = '"') {
	        if(!is_array($data))
	                return;

	        $footer = array_values($data);

	        $output = $enclosure . implode($footer, ($enclosure . $delim . $enclosure)) . $enclosure . $newline;

	        return $output;
	}

	private function array_to_csv_header($data, $delim = ",", $newline = "\n", $enclosure = '"') {
	        if(!is_array($data))
	                return;

	        $header = array_keys($data);

	        $output = $enclosure . implode($header, ($enclosure . $delim . $enclosure)) . $enclosure . $newline;

	        return $output;
	}	

}
