Location: PHPKode > scripts > ZEND_EPS_DTEXEC > class.zend.eps_dtexec.inc
<?php

	require_once 'Zend/Exception.php';
	require_once 'Zend/Config/Xml.php';
	
/**
 * SQL Server Integration Services (SSIS) package execution class.  
 * Allows for the configuration and execution of SSIS packages via a PHP script or batch file.
 * 
 * @package lib
 * @author DPassey
 * @copyright 2011, Everett Public Schools
 * @version 1.0, 02.14.2011
 */
	
/**
 * Environment defined computer name.
 * Allows the class to know where it is at and process the correct configuration.
 *
 * @var Const EPS_COMPUTER
 */
	define('EPS_COMPUTER',strtolower($_ENV['COMPUTERNAME']));
	
/**
 * SSIS command line executable.
 * 
 * @var Const EXEC
 */
	define('EXEC', 'dtexec');
	
	define('DTSUCCESS','dtser_success');
	
	
	class ZEND_EPS_DTEXEC
	{
/**
 * System temp directory.
 * 
 * @var String
 */
		private $tmpDir;

/**
 * XML configuration file location.
 * Path and name of the master configuration file.
 * The config file should have this structure:
 * <?xml version="1.0" encoding="UTF-8" ?>
 * <config> [parent node named as you want]
 * <env> [required for each environment]
 * <computer> [required for each computer in that environment]
 * <name>computer_name</name> [required]
 * <package> [required for each package to define]
 * <name>package_name</name> [required]
 * <package_path>path_to_package_file</package_path> [required]
 * <config_path>path_to_package_config</config_path> [required]
 * <report_path></report_path> [optional]
 * </computer>
 * </env>
 * </config>
 * 
 * @var String
 */
		private $configFile;
		
/**
 * Package configuration file location.
 * Path and name of the package configuration file.
 * 
 * @var String
 */
		private $pkgConfigFile;
		
/**
 * Package file location.
 * Path and name of the executable package file.
 * 
 * @var String
 */
		private $package;
		
/**
 * XML config env node object.
 * Holds all configurable information for each environment (dev, production, etc.) that the package will run in.
 * 
 * @var Object
 */
		private $envObj;
		
/**
 * Report data.
 * Data returned from the exec() regardless of success status.
 * 
 * @var String
 */
		private $report;
		
/**
 * Check pointing flag.
 * Set this to true to allow checkpointing.
 * 
 * @var Boolean
 */
		private $isCheckPointing = FALSE;
		
/**
 * Validation only flag.
 * Set this to true to only validate the package.
 * 
 * @var Boolean
 */
		private $isValidateOnly = FALSE;
		
/**
 * Valid configurable reporting options.
 * Index 0 is the default.
 * 
 * @var Array
 */
		private $reportConfigArray = array('N','V','E','W','I','C','D','P');
		
/**
 * Report options array.
 * Holds the valid reporting options which will be used during exec().
 * 
 * @var Array
 */
		private $reportOptions = array();
		
/**
 * Reporting flag.
 * Set via setReporting() so report data will be captured.
 * 
 * @var Boolean
 */
		private $isReporting = FALSE;
		
/**
 * Reporting file path and name.
 * 
 * @var String
 */
		private $reportFilename;
		
/**
 * Packages object.
 * Holds all config information for each package defined in the config file.
 * 
 * @var Object
 */
		private $pkgsObject;
		
/**
 * Exec statistics array.
 * Used for indexing the statistics object.
 * 
 * @var Array
 */
		private $statsArray = array('started','finished','elapsed');
		
/**
 * Statistics object.
 * Holds the stats from the package execution.  
 * Indexed by the statsArray and a success index.
 * 
 * @var Object
 */
		public $statsObj;
	
/**
 * Class constructor.
 * Attempts to load in the configuration XML file and set configurables.
 * 
 * @param String $configFile
 * @uses setConfig()
 * @throws Zend_Exception
 */
		public function __construct($configFile = NULL) 
		{
			try 
			{
				if (empty($configFile)) throw new Zend_Exception(__FUNCTION__ . '::Config file path is missing.');
				else 
				{
					$this->tmpDir = sys_get_temp_dir();
					$this->reportFilename = sprintf("%s.%s.txt",__CLASS__, date("YmdHis"));
					$this->envObj = new Zend_Config_Xml($configFile,'env',TRUE);	
					if (is_object($this->envObj)) self::setConfig();
					else throw new Zend_Exception(__FUNCTION__ . '::Environment nodes not found.');
				}
			}
			catch (Zend_Exception $e)
			{
				exit($e->getMessage());
			}
		}

/**
 * Class destructor.
 * Writes the report file if reporting was turned on and there is report data to write.
 * 
 * @throws Zend_Exception
 */
		public function __destruct() 
		{
			try 
			{
				if ($this->isReporting && isset($this->report)) 
				{
					if (!@file_put_contents($this->reportFilename, $this->report)) throw new Zend_Exception(__FUNCTION__ . '::Failed to write report file.');
				}
			}
			catch (Zend_Exception $e)
			{
				exit($e->getMessage());
			}
		}
		
/**
 * Sets the package name to be executed.
 * Validates the package file location, package config file location, reporting file location.
 * 
 * @param String $pkg
 * @uses setReportFile()
 * @uses setConfigPath()
 * @throws Zend_Exception
 */
		public function setPackage($pkg = NULL)
		{
			try 
			{
				if (empty($pkg)) throw new Zend_Exception (__FUNCTION__ . '::Package name is missing.');
				elseif (empty($this->pkgsObject->$pkg)) throw new Zend_Exception(__FUNCTION__ . '::Package object does not exist.');
				else
				{
					$path = $this->pkgsObject->$pkg->path;
					$config = $this->pkgsObject->$pkg->config;
					$report = $this->pkgsObject->$pkg->report;
				}
				if (!file_exists($path)) throw new Zend_Exception (__FUNCTION__ . '::Package file does not exist.');
				if (empty($config)) throw new Zend_Exception(__FUNCTION__ . '::Missing "config_path" node in the config file.');
				else self::setConfigPath($config);
				if (!empty($report)) self::setReportFile($report,__FUNCTION__);
				else self::setReportFile($this->tmpDir,$this->reportFilename);
				$this->package = str_replace('//','/',str_replace('\\','/',$path));
			}
			catch (Zend_Exception $e)
			{
				exit($e->getMessage());
			}
		}
		
/**
 * Executes the DTEXEC command with all of the configured options and generates report data.
 * Throws an error if the package is not set.
 * 
 * @uses setExecStats()
 * @throws Zend_Exception
 * @return Boolean
 */
		public function exec()
		{
			try
			{
				if (isset($this->package))
				{
					if (empty($this->reportOptions)) $this->reportOptions[] = $this->reportConfigArray[0];
					else 
					{
						if (count($this->reportOptions) > 1 && (in_array($this->reportConfigArray[0], $this->reportOptions) || in_array($this->reportConfigArray[1], $this->reportOptions)))
						{
							throw new Zend_Exception(__FUNCTION__ . '::Reporting options "' . $this->reportConfigArray[0] . '" and "' . $this->reportConfigArray[1] . '" must be specified alone.');
						}
					}
					$cmd = sprintf("%s -F %s -CONFIG %s -CHECKP %s -REP %s %s", EXEC, $this->package, $this->pkgConfigFile, ($this->isCheckPointing)?'ON':'OFF', implode('',$this->reportOptions), ($this->isValidateOnly)?'-VA':'');
					$this->report = `$cmd`;
					self::setExecStats();
				}
				else throw new Zend_Exception(__FUNCTION__ . '::Package is not set.');
			}
			catch (Zend_Exception $e)
			{
				exit($e->getMessage());
			}
			return $this->statsObj->success;
		}
		
/**
 * Sets the checkpoint option.
 * 
 * @param Boolean $check
 */
		public function setCheckPoint($check = FALSE)
		{
			$this->isCheckPointing = ($check) ? TRUE: FALSE;
		}
		
/**
 * Sets the reporting options.
 * No reporting (N) and Verbose reporting (V) cannot be combined with any other options.
 * 
 * @param Array $optionsArray
 * @throws Zend_Exception
 */
		public function setReportOptions($optionsArray = array())
		{
			try 
			{
				if (is_array($optionsArray))
				{
					foreach ($optionsArray as $o) 
					{
						$o = strtoupper($o);
						if (!in_array($o, $this->reportConfigArray)) throw new Zend_Exception(__FUNCTION__ . '::' . $o . ' is not a valid reporting option.');
						elseif (!in_array($o, $this->reportOptions)) $this->reportOptions[] = $o;
						if ($o != $this->reportConfigArray[0]) $this->isReporting = TRUE;
					}
				}
				else throw new Zend_Exception(__FUNCTION__ . '::Reporting options must be in an array.');
				
				if (empty($this->reportOptions)) throw new Zend_Exception(__FUNCTION__ . '::Reporting options array is empty.');
			}
			catch (Zend_Exception $e) 
			{
				exit($e->getMessage());
			}
		}
		
/**
 * Sets the validation option so the package is not executed, but only validated.
 * 
 */
		public function setValidation()
		{
			$this->isValidateOnly = TRUE;
		}
		
/**
 * Sets the report file path and filename.
 * If $path does not a valid directory/file structure, then the default report file name is used.
 * 
 * @param String $path
 * @throws Zend_Exception
 */
		public function setReportFile($path = NULL)
		{
			try 
			{
				if (empty($path)) throw new Zend_Exception(__FUNCTION__ . '::File path is missing.');
				if (!is_dir(dirname($path))) throw new Zend_Exception(__FUNCTION__ . '::File path directory is not valid.');
				elseif (!is_writable(dirname($path))) throw new Zend_Exception(__FUNCTION__ . '::File directory is not writable.');
				elseif (!is_dir($path)) $this->reportFilename = sprintf("%s/%s", dirname($path), basename($path));
				else $this->reportFilename = sprintf("%s/%s", $path, $this->reportFilename);
			}
			catch (Zend_Exception $e)
			{
				exit($e->getMessage());
			}
			$this->reportFilename = str_replace('//','/',str_replace('\\','/',$this->reportFilename));
		}
		
/**
* Private methods
*/
		
/**
 * Sets the configurable items.
 * Creates an array from the Config object and trims it down to the base element.
 * Cycles through the array and processes configurables based upon the local computer.
 * 
 * @uses setConfigPath()
 * @uses setReportFile()
 * @throws Zend_Exception
 */
		private function setConfig()
		{
			try 
			{
				$cpuArray[] = $this->envObj->computer->toArray();
				$cpuArray = $cpuArray[0];
				foreach ($cpuArray as $arr)
				{
					if (strtolower($arr['name']) == EPS_COMPUTER) 
					{
						$this->pkgsObject = new stdClass();
						foreach ($arr['package'] as $v)
						{
							$ndx = strtolower($v['name']);
							$this->pkgsObject->$ndx = new stdClass();
							$this->pkgsObject->$ndx->path = $v['package_path'];
							$this->pkgsObject->$ndx->config = $v['config_path'];
							$this->pkgsObject->$ndx->report = $v['report_path'];
						}
					}
				}
			}
			catch (Zend_Exception $e)
			{
				exit($e->getMessage());
			}
						
		}
		
/**
 * Sets the package configuration path.
 * 
 * @param String $path
 * @throws Zend_Exception
 */
		private function setConfigPath($path)
		{
			try 
			{
				if (file_exists($path)) $this->pkgConfigFile = $path;
				else throw new Zend_Exception(__FUNCTION__ . '::Package config file does not exist.');
			}
			catch (Zend_Exception $e)
			{
				exit($e->getMessage());
			}
		}
		
/**
 * Sets the statsObject which holds indexes of success and the statsArray indexes.
 * 
 * @throws Zend_Exception
 */
		private function setExecStats()
		{
			try 
			{
				$tmp = array();
				$arr = explode("\n", $this->report);
				if (empty($arr)) throw new Zend_Exception(__FUNCTION__ . '::Report was not created.');
				else 
				{
					$arr = array_reverse($arr);
					$str = EXEC;
					foreach ($arr as $val)
					{
						if (preg_match("/^$str/i", $val) == 0) $tmp[] = $val;
						else 
						{
							$tmp[] = $val;
							$arr = array_reverse($tmp);
							break;
						}
					}
					if (!empty($tmp))
					{
						$this->statsObj = new stdClass();
						$this->statsObj->success = 0;
						foreach ($arr as $val)
						{
							$split = explode(':',$val,2);
							$ndx = trim(strtolower($split[0]));
							if (in_array($ndx,$this->statsArray) || $ndx == EXEC) $this->statsObj->$ndx = trim($split[1]);
						}
						foreach (str_split(strrev($this->statsObj->$str)) as $c)
						{
							if ($c == '0') 
							{
								$this->statsObj->success = 1;
								break;
							}
						}
					}
					else unset($tmp);	
				}	
			}
			catch (Zend_Exception $e)
			{
				exit($e->getMessage());
			}		
		}
	}

?>
Return current item: ZEND_EPS_DTEXEC