<?php
require_once 'Zend/Exception.php';
require_once 'lib/class.zend.eps_dtexec.inc';
/**
* SQL Server Integration Services (SSIS) event handler.
* NOTE: Self-instantiating class.
*
* The idea is that this class is executed every few minutes via the cron or
* scheduled tasks. This allows FROM files to be sent between servers via FTP
* or other copying mechanisms. The event handler would then process them in a
* timely manner and prevent multiple instances of the same data file being processed
* since the oldest file is moved from the FROM directory to the TO directory.
* Server variables are employed to keep file locations dynamic and flexible.
*
* @package bin
* @author DPassey
* @copyright 2011, Everett Public Schools
* @version 1.2, 02.23.2012
* @since 1.1, 02.17.2012 Changed the order of the isset() functionality in exec();
* removed the echo statement in exec(). [DPassey]
* @since 1.0, 03.14.2011 Added realpath to exec();
* updated directions at bottom for various config files;
* replaced $_ENV variables to $_SERVER;
* added try/catch block to setUploadDir() and setDownloadDir();
* added extType flag to __construct() and reworked code;
* added filename class property;
* added reporting options functionality. [DPassey]
* @requires Zend/Exception.php;
* @requires lib/class.zend_eps_ssis_dtexec.inc;
* @uses SSIS_HOME
* @uses SFTP_HOME
* @uses DTEXEC_CONFIG
*/
class ZEND_EPS_SSIS_EVENTHANDLER
{
/**
* The directory where SSIS data files are sent to for processing.
* Relative to the SSIS_HOME server variable.
*
* @var String
*/
private $ssisToDir = 'data';
/**
* The directory where SSIS data files come from for processing.
*
* @var String
*/
private $ssisFromDir;
/**
* The SSIS qualifying file extension.
* The is set when the class is instantiated.
*
* @var String
*/
private $ssisExt;
/**
* The name of the package to be executed.
*
* @var String
*/
public $package;
/**
* The FTP download directory, relative the FTP home server variable.
*
* @var String
*/
private $ftpDownloadDir = 'download';
/**
* The FTP upload directory, relative the FTP home server variable.
*
* @var String
*/
private $ftpUploadDir = 'upload';
/**
* The original name of the file.
*
* @var String
*/
private $filename;
/**
* An array of desired reporting options.
* Defaults to none if not used.
*
* @var Array
* @see ZEND_EPS_DTEXEC::setReportOptions()
*/
private $reportOptions = array();
/**
* Constructor.
* The file qualifier string is required. If the extention type flag is 'P', then the data files that begin with the qualifier string
* are handled. The default value is the qualifier as a Suffix. The data TO and FROM directories are pulled from server variables if they are not
* otherwise provided. Reads the data FROM directory for applicable data files (those with the proper file extension)
* and puts those files into an array. The array is then sorted by the mod UNIX timestamp and the oldest file becomes
* the package to be executed. This package file is copied to the data TO directory and then deleted from the FROM directory.
*
* @param String $ext
* @param String $extType
* @param String $dataToDir
* @param String $dataFromDir
* @throws Zend_Exception
* @uses setDataDirs()
*/
public function __construct($ext = NULL, $extType = 'S', $dataToDir = NULL, $dataFromDir = NULL)
{
try
{
$arr = array();
$extType = trim(strtoupper($extType));
if (!empty($ext))
{
$this->ssisExt = ($extType == 'P') ? str_replace('.','',trim($ext)) . '.' : '.' . str_replace('.','',trim($ext));
$dirObj = self::setDataDirs(trim($dataToDir), trim($dataFromDir));
if (is_object($dirObj))
{
while (($file = $dirObj->read()) !== false)
{
$str = '';
$path = realpath(sprintf("%s/%s",$this->ssisFromDir,$file));
if (is_file($path))
{
if ($extType == 'P')
{
if (strncasecmp($this->ssisExt, $file, strlen($this->ssisExt)) == 0) $str = str_replace($this->ssisExt,'',$file);
}
elseif (strncasecmp(strrev($this->ssisExt), strrev($file), strlen($this->ssisExt)) == 0) $str = str_replace($this->ssisExt,'',$file);
if (!empty($str))
{
$z = filemtime($path);
$arr[$z] = $str;
$this->filename = $file;
}
}
}
$dirObj->close();
}
else throw new Zend_Exception(__FUNCTION__ . '::Cannot read directory ' . $this->ssisFromDir);
ksort($arr,SORT_NUMERIC);
$this->package = array_shift($arr);
}
else throw new Zend_Exception(__CLASS__ . '::SSIS file extension is missing.');
}
catch (Zend_Exception $e)
{
exit($e->getMessage());
}
}
/**
* Destructor.
*/
public function __destruct()
{
exit(0);
}
/**
* Sets the FTP upload directory.
* Set this if data files are being passed via FTP and the upload directory is not the class default.
*
* @param String $dir
* @throws Zend_Exception
*/
public function setUploadDir($dir = NULL)
{
try
{
$dir = trim($dir);
if (!file_exists($dir)) throw new Zend_Exception(__FUNCTION__ . '::Directory does not exist.');
}
catch (Zend_Exception $e)
{
exit($e->getMessage());
}
$this->ftpUploadDir = $dir;
}
/**
* Sets the FTP download directory.
* Set this if data files are being passed via FTP and the download directory is not the class default.
*
* @param String $dir
* @throws Zend_Exception
*/
public function setDownloadDir($dir = NULL)
{
try
{
$dir = trim($dir);
if (!file_exists($dir)) throw new Zend_Exception(__FUNCTION__ . '::Directory does not exist.');
}
catch (Zend_Exception $e)
{
exit($e->getMessage());
}
$this->ftpDownloadDir = $dir;
}
/**
* Executes the package.
* Reads the dtexec config file passed in to find the package configurables. If no package data
* has been set, the class ends.
*
* @param String $configFile
* @param String $parentNode
* @throws Zend_Exception
* @uses __destruct()
* @uses ZEND_EPS_DTEXEC()
*/
public function exec($configFile = NULL, $parentNode = NULL)
{
try
{
if (!isset($this->package)) self::__destruct();
else
{
self::setPackage();
$configFile = realpath($configFile);
if (!empty($configFile))
{
if (file_exists($configFile))
{
$dts = new ZEND_EPS_DTEXEC($configFile, $parentNode);
$dts->setPackage($this->package);
$dts->setReportOptions($this->reportOptions);
$dts->exec();
}
else throw new Zend_Exception(__METHOD__ . '::DTExec config file does not exist.');
}
else throw new Zend_Exception(__METHOD__ . '::DTExec config file is missing.');
}
}
catch (Zend_Exception $e)
{
exit($e->getMessage());
}
}
public function setReportOptions($optionsArray = array())
{
try
{
if (is_array($optionsArray)) $this->reportOptions = $optionsArray;
}
catch (Zend_Exception $e)
{
exit($e->getMessage());
}
}
/**
* Private methods
*/
/**
* Sets the data file directories.
* Assumes the use of SSIS_HOME and SFTP_HOME environment variables in use.
*
* @param String $toDir
* @param String $fromDir
* @throws Zend_Exception
* @return Object
*/
private function setDataDirs($toDir, $fromDir)
{
try
{
$this->ssisToDir = (empty($toDir)) ? realpath(sprintf("%s/%s",$_SERVER['SSIS_HOME'], $this->ssisToDir)) : $toDir;
$this->ssisFromDir = (empty($fromDir)) ? realpath(sprintf("%s/%s",$_SERVER['SFTP_HOME'],$this->ftpUploadDir)) : $fromDir;
if (empty($this->ssisFromDir)) throw new Zend_Exception(__FUNCTION__ . '::SSIS data FROM directory not set.');
if (empty($this->ssisToDir)) throw new Zend_Exception(__FUNCTION__ . '::SSIS data TO directory not set.');
return dir($this->ssisFromDir);
}
catch (Zend_Exception $e)
{
exit($e->getMessage());
}
}
/**
* Sets the package.
* Copies the package file from the old directory to the new directory and then deleting the old file.
*
* @throws Zend_Exception
*/
private function setPackage()
{
try
{
$oldName = sprintf("%s/%s",$this->ssisFromDir,$this->filename);
$newName = sprintf("%s/%s",$this->ssisToDir,$this->package);
if (@copy($oldName,$newName))
{
if (!@unlink($oldName)) throw new Zend_Exception(__FUNCTION__ . '::Cannot delete package file.');
}
else throw new Zend_Exception(__FUNCTION__ . '::Cannot copy package file.');
}
catch (Zend_Exception $e)
{
exit($e->getMessage());
}
}
}
/** NOTE: Edit these lines below as necessary to execute the class. **/
/**
* Instantiate the event handler class by passing in the SSIS file qualifier to identify SSIS data files and optional flag.
* The event handler creates and executes the dtexec application via the class.
* Use $_SERVER variables to keep the configuration file location dynamic across environments.
* Class takes 4 arguments:
* [required] SSIS data qualifier string, which tells the class which files to process.
* [optional] Flag to indicate if the qualifier string is a Prefix or a Suffix (default).
* [optional] Directory where the data file is going TO. Preconfigure using the environment variable SSIS_HOME.
* [optional] Directory where the data files is coming from. Usually a FTP upload directory. Preconfigure using the environment variable SFTP_HOME.
* Special note for SFTP_HOME: Assumes that the data will be coming from an FTP upload directory ('upload') so if this is NOT the case, then change the directory by calling setUploadDir() first.
* Set reporting options as desired, but they must be passed in as an array.
* Exec method requires the location of the config XML file and the name of the parent node for the package config section.
*/
$evt = new ZEND_EPS_SSIS_EVENTHANDLER('ssis','P');
$evt->setReportOptions(array('V'));
$evt->exec($_SERVER['DTEXEC_CONFIG'],'dtexec');
?> |