<?
########## Confixx(R) 3.0 Professional ############
####### Copyright SWsoft, Inc. 2004-2005 ##########
#### http://www.sw-soft.com - info@sw-soft.com ####

include_once('class.CrontabEntry.php');

/****************************
* Crontab storage/import/export class
*/
class Crontab
{
	var $_ctelist = array();
	var $_file;
	var $_error = false;

	/**********************
	* Crontab - constructor
	*
	* @param $sysuser  - sysuser name
	*
	* @return true if all ok
	*
	*/
	function Crontab($file)
	{
		// check client

		$this->_file = $file;
		
		$this->import();

		return true;
	}

	/**********************
	* import - import crontab from system
	*
	* @return true if all ok
	*/
	function import()
	{
		$this->resetError_();


		//init arrays

		$this->_ctelist = array();
		$this->_vars = array();

		$out = $this->_file;
		$sub = array();


//		$param = array('-u', $sysuser, '-l');
//		$ret = exec(UTILS_DIR . '/crontab '.join($param, ' '), $out);
		if ( !is_array($out) ) {
			$out = array();
//			global $plesk_errormsg;
//			$this->setError_($plesk_errormsg);
//			return false;
		}

		$skip = true;

		$re = '^#( |\n).*$';
		foreach ($out AS $line_no => $line)	{
			if ($skip){ // skip top comments
				if (!ereg($re, $line))
					$skip = false;
				else
					continue;
			}
			if (trim($line)=='')
				continue;
			$cte = new CrontabEntry(trim($line));
			if ($cte->error())
			{
				$this->setError_($cte->error());
				return false;
			}
			array_push($this->_ctelist, $cte);
		}
		return true;
	}

	/***************************
	* export() - export class to crontab table
	*
	* @return true if all ok
	* @public
	*/
	function export()
	{
		$this->resetError_();

		$ctelist = array();
		$out = array();

		foreach ($this->_ctelist AS $cte_no => $cte)
		{
			if ($cte->isRemoved())
				continue;
			if ($cte->getType() == CTE_TYPE_V){
				array_unshift($out, $cte->getString());
			} else {
				array_push($out, $cte->getString());
			}
			$cte->setValue('src', $cte->getString());
			array_push($ctelist, $cte);
		}
		
		/*

		$temp_file = tempnam('/tmp/', 'crontab');	// Temporary file for write crontab
		if (!$temp_file) {
			$this->setError_($php_errormsg);
			return false;
		}

		if (!($fp = fopen($temp_file, 'w'))) {
			$this->setError_($php_errormsg);
			return false;
		}

		if (!chmod($temp_file, 0600)) {
			$this->setError_($php_errormsg);
			fclose($fp);
			return false;
		}

		if (sizeof($out)>0){
			if (!fwrite($fp, join($out, "\n"))) {
				$this->setError_($php_errormsg);
				fclose($fp);
				return false;
			}
			if (!fwrite($fp, "\n")) {
				$this->setError_($php_errormsg);
				fclose($fp);
				return false;
			}
		}

		fclose($fp);
		*/
		
		$out = join($out, "\n");
		$out .= "\n";

		$this->_ctelist = $ctelist;
		return $out;
	}
	
	function count_jobs()
	{
		$this->resetError_();
		if (!isset($this->_ctelist) || !is_array($this->_ctelist)){
			$this->setError_('__bad_ctelist');
			return false;
		}
		$c = 0;
		foreach ($this->_ctelist as $cte)
		{
			if( in_array($cte->getType(), array(CTE_TYPE_P)) )
			{
				$c++;	
			}
		}
		//return sizeof($this->_ctelist);			
		return $c;
	}	

	function allow()
	{
		/*
		$param = array('allow', $sysuser = $this->_sysuser);
		$ret = smart_exec('crontabmng', $param);
		if (!$ret) {
			global $plesk_errormsg;
			$this->setError_($plesk_errormsg);
			return false;
		}
		*/
		return true;
	}

	function deny()
	{
		/*
		$param = array('deny', $sysuser = $this->_sysuser);
		$ret = smart_exec('crontabmng', $param);
		if (!$ret) {
			global $plesk_errormsg;
			$this->setError_($plesk_errormsg);
			return false;
		}
		*/

		return true;
	}

	/*******************
	* getEntryList - returns CrontabEntry array
	*
	* @return array of CrontabEntry objects or false if fail
	*/
	function &getEntryList()
	{
		if (!isset($this->_ctelist) || !is_array($this->_ctelist)){
			$this->setError_('__bad_ctelist');
			return false;
		}

		return $this->_ctelist;
	}

	/****************************
	* return length of crontab
	*/
	function length()
	{
		$this->resetError_();
		if (!isset($this->_ctelist) || !is_array($this->_ctelist)){
			$this->setError_('__bad_ctelist');
			return false;
		}
		return sizeof($this->_ctelist);
	}

	/**************************
	* getSysUser
	*/
	function getSysUser()
	{
		/*
		if (!isset($this->_sysuser)){
			psaerror('Sysuser not set', __FILE_, __LINE__);
			return false;
		}

		return $this->_sysuser;
		*/
		return true;
	}

	/*******************
	* getEntry - returns CrontabEntry object by source string
	*
	* @param $str - cource crontab string
	* @param $ident - type of identify (bit or str)
	*
	* @return array of CrontabEntry objects if exists or false if not exists
	*/
	function &getEntry($str, $ident = 'bit')
	{
		$this->resetError_();
		if (!in_array($ident, array('str', 'bit'))){
			$this->setError_('Bad crontab ident type');
		}

		foreach ($this->_ctelist AS $no => $ctentry){
			if ($ident=='str' && $ctentry->identifyStr($str))
				return $this->_ctelist[$no];
			if ($ident=='bit' && $ctentry->identifyBit($str))
				return $this->_ctelist[$no];
		}

		return false;
	}

	/*************************
	* entryExists - check entry exists in crontab
	*/
	function existsEntry($src){
		$ctentry = & $this->getEntry($src);

		if (!$ctentry)
			return false;
		return true;
	}

	/***********************
	* setEntryByStr - change entry by srt
	*/
	function setEntry($str, $ctentry, $ident='bit')
	{
		$this->resetError_();
		if (!in_array($ident, array('str', 'bit'))){
			$this->setError_('Bad crontab ident type');
			return false;
		}

		foreach ($this->_ctelist AS $no => $ctentry1){
			if ($ident=='bit' && $ctentry1->identifyBit($str)){
				$this->_ctelist[$no] = $ctentry;
				return true;
			} elseif ($ident=='str' && $ctentry1->identifyStr($str)){
				$this->_ctelist[$no] = $ctentry;
				return true;
			}
		}

		$this->setError_(lmsg('__crontab_entry_not_exists'));
		return false;
	}

	/*******************************
	* addEntry
	*/
	function &addEntry($psaenabled, $enabled, $minute, $hour, $dom, $month, $dow, $cmd)
	{
		$this->resetError_();

		$ret = true;

		$ctentry = new CrontabEntry();
		if ($ctentry->error()){
			$this->setError_ ('Can\'t create crontab entry class');
			return false;
		}

		// apply params to entry
		foreach (array('psaenabled', 'enabled', 'minute', 'hour', 'dom', 'month', 'dow', 'cmd') AS $key){
			$ctentry->setValue($key, ${$key});
			if ($ctentry->getBadValues()){
				$ret = false;
			}
		}
		if (!$ret){
			$this->setError_(lmsg('__invalid_values_found'));
			return $ctentry;
		}
		$ctentry->setType(CTE_TYPE_P);
		$src = $ctentry->getString();
		if ($this->existsEntry($src)){
			$this->setError_(lmsg('__crontab_entry_exists'));
			return $ctentry;
		}

		$ctentry->setType(CTE_TYPE_P);
		if ($ctentry->error()){
			$this->setError_('Can\'t set CrontabEntry type: '.$ctentry->error());
			return false;
		}


		$this->_ctelist[] = &$ctentry;

		return $ctentry;
	}

	/***************************
	* changeEntry
	*/
	function &changeEntry($src, $enabled, $minute, $hour, $dom, $month, $dow, $cmd)
	{
		$this->resetError_();
		$ret = true;

		$ctentry = & $this->getEntry($src);
		if (!$ctentry){
			$this->setError_(lmsg('__crontab_entry_not_exists'));
			return false;
		}

		foreach (array('enabled', 'minute', 'hour', 'dom', 'month', 'dow', 'cmd') AS $key){
			$ctentry->setValue($key, ${$key});
		}

		if ($ctentry->getBadValues()){
			$this->setError_(lmsg('__invalid_values_found'));
			return $ctentry;
		}

//		if (!$this->setEntry($src, $ctentry)){
//			psaerror('Can\'t change CrontabEntry', __FILE__, __LINE__);
//		}

		return $ctentry;
	}

	/***************************
	* removeEntry()
	*/
	function removeEntry($src){
		$this->resetError_();

		$ctentry = & $this->getEntry($src);
		if (!$ctentry){
			$this->setError_(lmsg('__crontab_entry_not_exists'));
			return false;
		}
		return $ctentry->Remove();
	}

	/*********************
	* getVar
	*/
	function &getVar($name)
	{
		foreach ($this->_ctelist AS $no => $ctentry){
			if ($ctentry->getType() == CTE_TYPE_V && strcasecmp($ctentry->getValue('name'), $name)==0){
				return $this->_ctelist[$no];
			}
		}

		return false;
	}

	/*********************
	* existsVar
	*/
	function existsVar($name)
	{
		$ctentry = & $this->getVar($name);
		if (!$ctentry)
			return false;
		return true;
	}

	/*************************
	* setVar
	*/
	function setVar($name, $ctentry){
		$this->resetError_();

		foreach ($this->_ctelist AS $no => $ctentry1){
			if ($ctentry1->getType() != CTE_TYPE_V)
				continue;
			if ($ctentry1->getValue('name')==$name){
				$this->_ctelist[$no] = $ctentry;
				return true;
			}
		}

		$this->setError_(lmsg('__crontab_entry_not_exists'));
		return false;
	}

	/*********************
	* addVar
	*/
	function addVar($enabled, $name, $value)
	{
		$this->resetError_();

		$ctentry = & $this->getVar($name);
		if ($ctentry){
			$this->setError_(lmsg('__crontab_entry_exists'));
			return false;
		}

		$ctentry = new CrontabEntry();
		if ($ctentry->error()){
			$this->setError_('Can\'t create CrontabEntry: '.$ctentry->error());
			return false;
		}

		// set type to var
		$ctentry->setType(CTE_TYPE_V);
		if ($ctentry->error()){
			$this->setError_('Can\'t set CrontabEntry type: '.$ctentry->error());
			return false;
		}
		// set enabled
		$ctentry->setValue('enabled', true);
		// set name
		$ctentry->setValue('name', $name);
		//set value
		$ctentry->setValue('value', $value);

		if ($ctentry->getBadValues()){
			$this->setError_(lmsg('__invalid_values_found'));
			return false;
		}

		$this->_ctelist[] = $ctentry;

		return true;
	}

	/*********************
	* changeVar
	*/
	function changeVar($name, $enabled, $value)
	{
		$this->resetError_();

		$ctentry = & $this->getVar($name);
		if (!$ctentry){
			$this->setError_(lmsg('__crontab_entry_not_exists'));
			return false;
		}

		$ctentry->setValue('enabled', $enabled);
		$ctentry->setValue('value', $value);

		if ($ctentry->getBadValues()){
			$this->setError_(lmsg('__invalid_values_found'));
			return false;
		}

//		if (!$this->setVar($name, $ctentry)){
//			psaerror('Can\'t change CrontabEntry', __FILE__, __LINE__);
//		}

		return true;
	}

	/*************************
	* removeValue() - remove value from crontab
	*/
	function removeVar($name){
		$ctentry = & $this->getVar($name);
		if (!$ctentry)
			return true;

		return $ctentry->Remove();
	}

	/***************************
	* isChanged() - check that crontab is changed
	*/
	function isChanged(){
		foreach ($this->_ctelist AS $no => $ctentry){
			if ($ctentry->isChanged())
				return true;
		}

		return false;
	}

	/***********************
	* remove  - remove crontab entries
	*/
	function remove($del)
	{
		foreach($del AS $str){
			foreach ($this->_ctelist AS $no => $ctentry){
				if ($ctentry->identifyBit($str)){
					$ctentry->Remove();
					$this->_ctelist[$no] = $ctentry;
				}
			}
		}
	}
	
	function resetError_()
	{
		$this->_error = false;
	}
	
	function setError_($e)
	{
		$this->_error = $e;
	}


}
?>
