SlideShare a Scribd company logo
1 of 50
Download to read offline
$return[‘fileLocation’]=$this->cachePath.$keyDir.’/’; $return[‘fileName’]=$return[‘keyHash’].’.cache’; return $return; } /** * Sets a value in the cache for a certain key. * @param String $key * @param Mixed $value * @param String $expireTime * @return Boolean - indicating if the key was correctly saved in the cache */ public function
set($key, $value, $expireTime=0) { // CHECK INPUTS // if key is not set if (!$key) return false; // do not store ‘null’ values if ($value===null) return false; // FILE AND DIRECTORY MANAGEMENT $params=$this->getFileDetails($key); // attempt to create the directory chain if (!Dir::create($params[‘fileLocation’])) return false; //
DETERMINE THE EXPIRE TIMESTAMP if (is_numeric($expireTime) and $expireTime>0) { $expireTimestamp=TIMESTAMP+$expireTime; } else { switch (substr($expireTime, -1)) { case ‘s’: $expireTimestamp=TIMESTAMP+$expireTime;break; case ‘m’: $expireTimestamp=TIMESTAMP+$expireTime*60;break; case ‘h’:
$expireTimestamp=TIMESTAMP+$expireTime*3600;break; case ‘d’: $expireTimestamp=TIMESTAMP+$expireTime*86400;break; default: $expireTimestamp=0; } } if (!$expireTimestamp) $expireTimestamp = TIMESTAMP + $this->defaultExpireTime; // FILE CONTENT $fileContent =$expire Timestamp .serialize($value) ; // WRITE THE
CACHE FILE return File::create($params[‘fileLocation’].$params[‘fileName’], $fileContent); } /** * Gets a value stored in the cache for a certain key. * @param String $key * @return Mixed - the stored value or null if the key was not found */ public function get($key) { // CHECK INPUTS if (!$key) return null; // CHECK THE FILE // get file
params $params=$this->getFileDetails($key); // check the file if (!file_exists($params[‘fileLocation’] .$params[‘fileName’]) or !is_readable($params [‘fileLocation’].$params[‘fileName’])) return null; // READ THE FILE$fc=File::getContents($params[‘fileLocation’].$params[‘fileName’]); // get and check expiration time $expirationTimestamp
=substr ($fc, 0, 10); if ($expirationTimestamp<TIMESTAMP) { // delete the expired cache from disk $this->delete($key); return null; } // get contents, unserialize it and return it $valueSer=substr($fc, 10); $value=@unserialize($valueSer); if ($valu e===false) return null; else return $value; } /** * Deletes the value stored in the cache
for a certain key. * @param Mixed $key - if it is an array - deletes all those keys; if it is a string - deleted only that key * @return Boolean - indicating if the key was correctly deleted in the cache */ public function delete($key) { // CHECK INPUTS if (!$key) return true; // CHECK THE FILE $return=1; // A LIST OF KEYS TO BE DELETED if
(is_array($key)) { foreach($key as $k) { // get file params $params=$this->getFileDetails($k); // check the file if (!file_exists($params[‘fileLocation’].$params[‘fileName’])) continue; // delete the file $return*=File::delete($params[‘fileLocation’].$params[‘fileName’]); } } // ONLY ONE KEY else { // get file params $params=$this-
>getFileDetails($key); // check the file if (!file_exists($params[‘fileLocation’].$params[‘fileName’])) return true; // delete the file $return=File::delete($params[‘fileLocation’].$params[‘fileName’]); } return (Bool)$return; } /** * Deletes the whole cache content. * @return Boolean - indicating if the cache was completely destroyed * @see
EngineCacheBaseInterface::flush() */ public function flush() { return Dir::delete($this->cachePath); } /** * Returns an associative array of details for a certain key: the file location, the expire timestamp * @return Array */ public function getInfo($key) { $return=array(); // associate the key $return[‘key’]=$key; // get more details
$params=$this->getFileDetails($key); $fullFileName=$params[‘fileLocation’].$params[‘fileName’]; // CHECK IF THE FILE EXISTS if (!file_exists($fullFileName) or !is_readable($fullFileName)) { $return[‘fileExists’]=false; } else { // associate some more keys $return[‘fileExists’]=true; $return[‘keyHash’]=$params[‘keyHash’];
$return[‘fileLocation’]=$params[‘fileLocation’]; $return[‘fileName’]=$params[‘fileName’]; $return[‘fileSize’]=filesize($fullFileName); // get expire time $fc=File::getContents($fullFileName); $return[‘expireTimestamp’]=substr($fc, 0, 10); $return[‘expireTimestampReadable’]=date(TIMESTAMP_FULL_FORMAT, $return[‘expireTimestamp’]); //
get the value $return [‘cachedValue’] =unserialize (substr($fc, 10)); } return $return; } } <?php namespace EnginePlugins; /** * The class is used for registering a new plugin. It is extended in a class which is automatically * executed. * @author Gabriel */ abstract class RegisterAbstract { /** * The list of observers for a registered plugin.
* @var Array - associative array of [triggerName][index][EnginePluginsObserver object] */ protected $observers=array(); /** * The constructor will register the current plugin. */ public function __construct() { $this->register(); } /** * Stores a new observer for this plugin (the method is called from the defined method register() * in the
concrete classes. * @param String $triggerName - the trigger name * @param EnginePluginsObserver $obs - the observer object * @throws Exception - if the triger name is not correct */ protected function addObserver($triggerName, EnginePluginsObserver $obs) { // check trigger name if (!$triggerName) { throw new Exception(‘The
trigger name was not set in ‘.get_called_class().’::’.__FUNCTION__.”.”); } $this->observers[$triggerName][] = $obs; } /** * The method will add new observers to the current plugin (using the addObserver() method. */ abstract protected function register(); /** * Returns the list of observers for the current * @return multitype: */ public
function getObservers() { return $this->observers; } } <?php namespace AppEntityMatch; /** * The class manages the matching of suppliers * @author Gabriel */ class Supplier extends AppEntityMatchBaseAbstract { /** * The export fields for suppliers. * @var Array */ protected $exportFields = array(‘alias’, ‘company’); /** * Extra
filters - deleted and duplicated suppliers are not allwed. * @var String */ protected $matchingFilteringSQL = ‘AND ent.deleted=0 AND ent.idRealSupplier=0’; /** * The class name which will instantiate the Entity - used for primaryKey search. * @var String */ protected $entityClassName = ‘EntitySupplier’; /** * (non-PHPdoc) * @see
AppEntityMatchBaseAbstract::setTableName() */ protected function setTableName() { global $DBTSuppliers; $this->tableName = $DBTSuppliers; } /** * Sets a search by supplier alias. * @param String $value - the supplier alias. * @param Boolean $useWildcard - uses wildcard for this search or not. */ public function setAlias($value,
$useWildcard=true) { $this->setSearchCriterion(‘alias’, $value, $useWildcard); } /** * Sets a search by supplier company name. * @param String $value - the supplier company name. * @param Boolean $useWildcard - uses wildcard for this search or not. */ public function setCompany($value, $useWildcard=true) { $this-
>setSearchCriterion(‘company’, $value, $useWildcard); } /** * Sets a search by supplier fiscal code. * @param String $value - the supplier fiscal code. */ public function setFiscalCode($value) { $this->setSearchCriterion(‘fiscalCode’, $value, false); } /** * Searches a supplier by its code. * @param String $value * @param String $codeName
- indicate the type of code (iata, tktCode, etc) */ public function setCode($value, $codeName) { // check the code name global $CFG; if (!$CFG[‘travel’][‘standardCodes’][$codeName]) { throw new Exception(“The supplier code `{$codeName}` is not valid - you can only use: “.implode(‘, ‘, array_keys($CFG[‘travel’][‘standardCodes’]))); } //
add the search criterion $this->setSearchCriterion(‘code’, $value, false, array(‘codeName’=>$codeName)); } /** * Searches a supplier by the matching manually set in the external reservations system configs. * @param String $name - the supplier name * @param Int $idExternalResSystem - the external system */ public function
setExtResSysName($name, $idExternalResSystem) { $this->setSearchCriterion(‘extResSys’, $name, false, array(‘idExtResSystem’=>$idExternalResSystem)); } /** * This method does a special search for supplier code (for the rest of the criteria, it uses the parent call. * @see AppEntityMatchBaseAbstract::searchRecords() */ protected
function dispatchSearchRecords($field, $value, $useWildcard, Array $options=array()) { switch ($field) { case ‘code’: return $this->searchRecords_code($value, $options); break; case ‘extResSys’: return $this->searchRecords_extResSys($value, $options); break; default: return parent::dispatchSearchRecords($field, $value,
$useWildcard, $options); } } /** * Searches a supplier by its code. * @param String $value - the supplier code * @param Array $options - stores the code name used */ private function searchRecords_code($value, Array $options) { global $DBTSupplierCodes; $db = DB::getInstance(); // RUN SQL $matchSupplierCodeSQL = “ SELECT
“.$this->getSelectingFieldsSQL().” FROM `$DBTSupplierCodes` AS sc, `{$this->tableName}` AS ent WHERE sc.`code`=? AND sc.`value`=? AND `ent`.`id`=`sc`.`idSupplier` {$this->matchingFilteringSQL} “; $matchSupplierCodeEx = $db->Execute($matchSupplierCodeSQL, array($options[‘codeName’], $value)); if (!$matchSupplierCodeEx)
{ writeLog(“Could not match supplier by their code.”, ‘events’, 9); throw new Exception(‘Could not match supplier by their code.’); } // STORE RESULTS $return = array(); foreach($matchSupplierCodeEx as $supp) { $return[$supp[‘id’]] = $supp; } return $return; } /** * Searches a supplier by its matching in the external reservation
systems. * @param unknown $valuem * @param array $options */ private function searchRecords_extResSys($value, Array $options) { global $DBTImportRes_suppliersAssociations; $db = DB::getInstance(); // SEARCH IN THE DB $searchSupplierSQL=”SELECT tinaSupplierId FROM `$DBTImportRes_suppliersAssociations` WHERE
systemSupplierId=? AND systemId=?”; $searchSupplierEx=$db->Execute($searchSupplierSQL, array($value, $options[‘idExtResSystem’])); if (!$searchSupplierEx) { writeLog(“Could not match supplier by the external reservation systems code.”, ‘events’, 9); throw new Exception(‘Could not match supplier by the external reservation systems
code.’); } // RETURN THE RESULT $supp=$searchSupplierEx->FetchRow(); $return = array(); if ($supp[‘tinaSupplierId’]) { $return=$this->searchRecord_primaryKey($supp[‘tinaSupplierId’]); } return $return; } } <?php namespace AppConfig; abstract class XmlBasicAbstract extends BaseAbstract { /** * Stores the configuration file
(relative to the “files/config/” dir). For config files stored * inside subdirectories, the subdirectory is included (Ex: services/servicesList.xml). * @var String */ protected $fileName=null; /** * The filename with its full path. * @var String */ protected $fileNameWithPath=null; /** * (non-PHPdoc) * @see
AppConfigBaseAbstract::constructInit() */ protected function constructInit() { // check if the file name is okay if (!$this->fileName) { throw new Exception(‘You did not set the `fileName` attribute for the class `’.get_called_class().’`.’); } // set the $this->fileNameWithPath=MODULE_REL_PATH . FILEPATH_APPCONFIGS . $this->fileName;
} /** * Sets a reference to the current data in session so it can be stored during session lifetime. * @see AppConfigBaseAbstract::constructAdmin() */ protected function constructAdmin() { global $S; $className =get_called_ class(); // if items list and changed flag are set in session - they are copied into class attributes if
(isset($S[‘admin’][‘configApp’][$className][‘itemsList’])) { $this->itemsList=$S [‘admin’] [‘configApp’] [$className ][‘itemsList’]; } if (isset($S[‘admin’][‘configApp’][$className][‘changedFlag’])) { $this->changedFlag=$S[‘admin’][‘configApp’][$className][‘changedFlag’]; } // these references will keep the data over different page loads
$S[‘admin’] [‘configApp’] [$className] [‘itemsList’] =&$this->itemsList; $S[‘admin’][‘configApp’][$className][‘changedFlag’]=&$this->changedFlag; } /** * (non-PHPdoc) * @see AppConfigBaseAbstract::getAll_rawData() */ protected function getAll_rawData() { // return the output in case the file does not exist if (!file_exists($this-
>fileNameWithPath)) return $this->getAll_rawData_fileNotExists(); // the file exists - load the content as XML (and check it) $xml=@simplexml_load_file($this->fileNameWithPath); if (!($xml instanceof SimpleXMLElement)) throw new Exception(‘The config file is not a well formed XML (class = ‘.get_called_class().’ ; file = ‘.$this-
>fileNameWithPath.’).’); // return the array from the parsed XML content return $this->getAll _rawData _extract DataFromFile($xml); } /** * Sets the default output in case the XML file is missing. * @return Array */ protected function getAll_rawData_fileNotExists() { return array(); } /** * Returns the extracted data after the XML content
is parsed. * @param SimpleXMLElement $xml - the parsed xml * @return Array - the items list or whatever output is needed. */ abstract protected function getAll_ rawData _extractData FromFile ( Simple XMLElement $xml); /** * Sets an element in the internal attribute $this->itemsList. The method can be called multiple * times and they
will overwrite the older values. * @param String $var - or the name of one key (a string); * @param Mixed $value - the value of the key; * @throws Exception - if input is bad */ public function set($var, $value) { // check constructor type if ($this->constructType!=’admin’) throw new Exception(“You can use the method `”.get _called_
class().’::’.__FUNCTION__.”` only if the constructor type is `admin`.”); // check inputs if (!is_string($var)) throw new Exception(“You did not set() a correct name for the key.”); // (re)set one key $this->itemsList[$var]=$value; // update the changed flag $this->changedFlag=true; } /** * Sets all the elements in the internal attribute $this-
>itemsList (rewrites any old data * already stored). The parameter is an associative array and the keys will be * stored one by one. * @param Array $vars - associative array of keys * @throws Exception - if input is bad */ public function setAll($vars) { // check constructor type if ($this->constructType!=’admin’) throw new Exception(“You
can use the method `”.get_c alled_class().’::’.__ FUNCTION__.”` only if the constructor type is `admin`.”); // check inputs if (!is_array($vars)) throw new Exception(“You did not setAll() a correct list of elements - the parameter is not an array.”); // (re)set a list of keys $this->itemsList=$vars; // update the changed flag $this->changed
Flag=true; } /** * (non-PHPdoc) * @see AppConfigBaseAbstract::save_write_do() */ protected function save_write_do() { // GETS THE SIMPLEXML OBJECT TO BE WRITTEN ON DISK gets the simplexml object $xmlObj=$this->save_write_do _getXml(); // checks that the object is correct (it is a valid simplexml object) if (!($xmlObj
instanceof SimpleXMLElement)) throw new Exception(‘The output of the method `’.get_ called_class() .’::save_write_do_getXml` must be a `SimpleXMLElement` object.’); // (RE)WRITE FILE ON DISK // check if the file is writeable $fileChmod=false; if (file_exists($this->fileNameWithPath)) { if (!is_writeable($this->fileNameWithPath)) $this-
>addErrorMessage(‘The config file exists but it is not writeable.’); } else { $fileChmod=true; } // (OVER)WRITE THE FILE CONTENT - if (!file_put_contents($this->fileNameWithPath, $xmlObj->asXml())) { $this->addErrorMessage(‘The config file could not be (over)written.’); } // if the file did not exist - chmod it if ($fileChmod) { if
(!chmod($this->fileNameWithPath, 0777)) { $this->addErrorMessage(‘The config file could not have its acess rights updated.’); } } } /** * Returns the SimpleXML object to be written on disk. * @return SimpleXMLElement */ abstract protected function save_write_do_getXml(); } <?php namespace EngineCache; /** * The class is used to
manage the cache stored on disk. * @author Gabriel Grosu */ class Disk implements EngineCacheBaseInterface { /** * The full location where the cache files are stored. * @var String */ protected $cachePath=’’; /** * The prefix key is used to avoid the reusing of keys if the application was updated. * @var String */ protected
$keyPrefix=’’; /** * The default expiration time limit, if no param is specified when calling set() * @var int */ protected $defaultExpireTime = 2592000; // 2592000 = one month /** * The class constructor. */ public function __construct() { global $CFG; // realpath is used because cwd may change in __destructor(s) - AppEntityCache
caches the entity object in destructors. $this->cachePath=realpath(MODULE_REL_PATH.$CFG[‘paths’][‘files’]).’/’.$CFG[‘cache’][‘disk’][‘location’]; // sets the mem cached key prefix $this->keyPrefix=$CFG[‘global’][‘application’][‘versionBuild’]; return true; } /** * Returns some associative array of data determined from the key * @param Array
$key */ private function getFileDetails($key) { $return=array(); // rewrite the key $key=$this->keyPrefix.’-’.$key; // the key hash $return[‘keyHash’]=md5($key); // the subdir for the current key $keyDir=substr($return[‘keyHash’], 0, 2); // the full file location $return[‘fileLocation’]=$this->cachePath.$keyDir.’/’;
$return[‘fileName’]=$return[‘keyHash’].’.cache’; return $return; } /** * Sets a value in the cache for a certain key. * @param String $key * @param Mixed $value * @param String $expireTime * @return Boolean - indicating if the key was correctly saved in the cache */ public function set($key, $value, $expireTime=0) { // CHECK INPUTS
// if key is not set if (!$key) return false; // do not store ‘null’ values if ($value===null) return false; // FILE AND DIRECTORY MANAGEMENT $params=$this->getFileDetails($key); // attempt to create the directory chain if (!Dir::create($params[‘fileLocation’])) return false; // DETERMINE THE EXPIRE TIMESTAMP if
(is_numeric($expireTime) and $expireTime>0) { $expireTimestamp=TIMESTAMP+$expireTime; } else { switch (substr($expireTime, -1)) { case ‘s’: $expireTimestamp=TIMESTAMP+$expireTime;break; case ‘m’: $expireTimestamp=TIMESTAMP+$expireTime*60;break; case ‘h’: $expireTimestamp=TIMESTAMP+$expireTime*3600;break; case
‘d’: $expireTimestamp=TIMESTAMP+$expireTime*86400;break; default: $expireTimestamp=0; } } if (!$expireTimestamp) $expireTimestamp = TIMESTAMP + $this->defaultExpireTime; // FILE CONTENT $fileContent =$expire Timestamp .serialize($value) ; // WRITE THE CACHE FILE return
File::create($params[‘fileLocation’].$params[‘fileName’], $fileContent); } /** * Gets a value stored in the cache for a certain key. * @param String $key * @return Mixed - the stored value or null if the key was not found */ public function get($key) { // CHECK INPUTS if (!$key) return null; // CHECK THE FILE // get file params
$params=$this->getFileDetails($key); // check the file if (!file_exists($params[‘fileLocation’] .$params[‘fileName’]) or !is_readable($params [‘fileLocation’].$params[‘fileName’])) return null; // READ THE FILE$fc=File::getContents($params[‘fileLocation’].$params[‘fileName’]); // get and check expiration time $expirationTimestamp =substr
($fc, 0, 10); if ($expirationTimestamp<TIMESTAMP) { // delete the expired cache from disk $this->delete($key); return null; } // get contents, unserialize it and return it $valueSer=substr($fc, 10); $value=@unserialize($valueSer); if ($valu e===false) return null; else return $value; } /** * Deletes the value stored in the cache for a
certain key. * @param Mixed $key - if it is an array - deletes all those keys; if it is a string - deleted only that key * @return Boolean - indicating if the key was correctly deleted in the cache */ public function delete($key) { // CHECK INPUTS if (!$key) return true; // CHECK THE FILE $return=1; // A LIST OF KEYS TO BE DELETED if
(is_array($key)) { foreach($key as $k) { // get file params $params=$this->getFileDetails($k); // check the file if (!file_exists($params[‘fileLocation’].$params[‘fileName’])) continue; // delete the file $return*=File::delete($params[‘fileLocation’].$params[‘fileName’]); } } // ONLY ONE KEY else { // get file params $params=$this-
>getFileDetails($key); // check the file if (!file_exists($params[‘fileLocation’].$params[‘fileName’])) return true; // delete the file $return=File::delete($params[‘fileLocation’].$params[‘fileName’]); } return (Bool)$return; } /** * Deletes the whole cache content. * @return Boolean - indicating if the cache was completely destroyed * @see
EngineCacheBaseInterface::flush() */ public function flush() { return Dir::delete($this->cachePath); } /** * Returns an associative array of details for a certain key: the file location, the expire timestamp * @return Array */ public function getInfo($key) { $return=array(); // associate the key $return[‘key’]=$key; // get more details
$params=$this->getFileDetails($key); $fullFileName=$params[‘fileLocation’].$params[‘fileName’]; // CHECK IF THE FILE EXISTS if (!file_exists($fullFileName) or !is_readable($fullFileName)) { $return[‘fileExists’]=false; } else { // associate some more keys $return[‘fileExists’]=true; $return[‘keyHash’]=$params[‘keyHash’];
$return[‘fileLocation’]=$params[‘fileLocation’]; $return[‘fileName’]=$params[‘fileName’]; $return[‘fileSize’]=filesize($fullFileName); // get expire time $fc=File::getContents($fullFileName); $return[‘expireTimestamp’]=substr($fc, 0, 10); $return[‘expireTimestampReadable’]=date(TIMESTAMP_FULL_FORMAT, $return[‘expireTimestamp’]); //
get the value $return [‘cachedValue’] =unserialize (substr($fc, 10)); } return $return; } } <?php namespace EnginePlugins; /** * The class is used for registering a new plugin. It is extended in a class which is automatically * executed. * @author Gabriel */ abstract class RegisterAbstract { /** * The list of observers for a registered plugin.
* @var Array - associative array of [triggerName][index][EnginePluginsObserver object] */ protected $observers=array(); /** * The constructor will register the current plugin. */ public function __construct() { $this->register(); } /** * Stores a new observer for this plugin (the method is called from the defined method register() * in the
concrete classes. * @param String $triggerName - the trigger name * @param EnginePluginsObserver $obs - the observer object * @throws Exception - if the triger name is not correct */ protected function addObserver($triggerName, EnginePluginsObserver $obs) { // check trigger name if (!$triggerName) { throw new Exception(‘The
trigger name was not set in ‘.get_called_class().’::’.__FUNCTION__.”.”); } $this->observers[$triggerName][] = $obs; } /** * The method will add new observers to the current plugin (using the addObserver() method. */ abstract protected function register(); /** * Returns the list of observers for the current * @return multitype: */ public
function getObservers() { return $this->observers; } } <?php namespace AppEntityMatch; /** * The class manages the matching of suppliers * @author Gabriel */ class Supplier extends AppEntityMatchBaseAbstract { /** * The export fields for suppliers. * @var Array */ protected $exportFields = array(‘alias’, ‘company’); /** * Extra
filters - deleted and duplicated suppliers are not allwed. * @var String */ protected $matchingFilteringSQL = ‘AND ent.deleted=0 AND ent.idRealSupplier=0’; /** * The class name which will instantiate the Entity - used for primaryKey search. * @var String */ protected $entityClassName = ‘EntitySupplier’; /** * (non-PHPdoc) * @see
AppEntityMatchBaseAbstract::setTableName() */ protected function setTableName() { global $DBTSuppliers; $this->tableName = $DBTSuppliers; } /** * Sets a search by supplier alias. * @param String $value - the supplier alias. * @param Boolean $useWildcard - uses wildcard for this search or not. */ public function setAlias($value,
$useWildcard=true) { $this->setSearchCriterion(‘alias’, $value, $useWildcard); } /** * Sets a search by supplier company name. * @param String $value - the supplier company name. * @param Boolean $useWildcard - uses wildcard for this search or not. */ public function setCompany($value, $useWildcard=true) { $this-
>setSearchCriterion(‘company’, $value, $useWildcard); } /** * Sets a search by supplier fiscal code. * @param String $value - the supplier fiscal code. */ public function setFiscalCode($value) { $this->setSearchCriterion(‘fiscalCode’, $value, false); } /** * Searches a supplier by its code. * @param String $value * @param String $codeName
- indicate the type of code (iata, tktCode, etc) */ public function setCode($value, $codeName) { // check the code name global $CFG; if (!$CFG[‘travel’][‘standardCodes’][$codeName]) { throw new Exception(“The supplier code `{$codeName}` is not valid - you can only use: “.implode(‘, ‘, array_keys($CFG[‘travel’][‘standardCodes’]))); } //
add the search criterion $this->setSearchCriterion(‘code’, $value, false, array(‘codeName’=>$codeName)); } /** * Searches a supplier by the matching manually set in the external reservations system configs. * @param String $name - the supplier name * @param Int $idExternalResSystem - the external system */ public function
setExtResSysName($name, $idExternalResSystem) { $this->setSearchCriterion(‘extResSys’, $name, false, array(‘idExtResSystem’=>$idExternalResSystem)); } /** * This method does a special search for supplier code (for the rest of the criteria, it uses the parent call. * @see AppEntityMatchBaseAbstract::searchRecords() */ protected
function dispatchSearchRecords($field, $value, $useWildcard, Array $options=array()) { switch ($field) { case ‘code’: return $this->searchRecords_code($value, $options); break; case ‘extResSys’: return $this->searchRecords_extResSys($value, $options); break; default: return parent::dispatchSearchRecords($field, $value,
$useWildcard, $options); } } /** * Searches a supplier by its code. * @param String $value - the supplier code * @param Array $options - stores the code name used */ private function searchRecords_code($value, Array $options) { global $DBTSupplierCodes; $db = DB::getInstance(); // RUN SQL $matchSupplierCodeSQL = “ SELECT
“.$this->getSelectingFieldsSQL().” FROM `$DBTSupplierCodes` AS sc, `{$this->tableName}` AS ent WHERE sc.`code`=? AND sc.`value`=? AND `ent`.`id`=`sc`.`idSupplier` {$this->matchingFilteringSQL} “; $matchSupplierCodeEx = $db->Execute($matchSupplierCodeSQL, array($options[‘codeName’], $value)); if (!$matchSupplierCodeEx)
{ writeLog(“Could not match supplier by their code.”, ‘events’, 9); throw new Exception(‘Could not match supplier by their code.’); } // STORE RESULTS $return = array(); foreach($matchSupplierCodeEx as $supp) { $return[$supp[‘id’]] = $supp; } return $return; } /** * Searches a supplier by its matching in the external reservation
systems. * @param unknown $valuem * @param array $options */ private function searchRecords_extResSys($value, Array $options) { global $DBTImportRes_suppliersAssociations; $db = DB::getInstance(); // SEARCH IN THE DB $searchSupplierSQL=”SELECT tinaSupplierId FROM `$DBTImportRes_suppliersAssociations` WHERE
systemSupplierId=? AND systemId=?”; $searchSupplierEx=$db->Execute($searchSupplierSQL, array($value, $options[‘idExtResSystem’])); if (!$searchSupplierEx) { writeLog(“Could not match supplier by the external reservation systems code.”, ‘events’, 9); throw new Exception(‘Could not match supplier by the external reservation systems
code.’); } // RETURN THE RESULT $supp=$searchSupplierEx->FetchRow(); $return = array(); if ($supp[‘tinaSupplierId’]) { $return=$this->searchRecord_primaryKey($supp[‘tinaSupplierId’]); } return $return; } } <?php namespace AppConfig; abstract class XmlBasicAbstract extends BaseAbstract { /** * Stores the configuration file
(relative to the “files/config/” dir). For config files stored * inside subdirectories, the subdirectory is included (Ex: services/servicesList.xml). * @var String */ protected $fileName=null; /** * The filename with its full path. * @var String */ protected $fileNameWithPath=null; /** * (non-PHPdoc) * @see
AppConfigBaseAbstract::constructInit() */ protected function constructInit() { // check if the file name is okay if (!$this->fileName) { throw new Exception(‘You did not set the `fileName` attribute for the class `’.get_called_class().’`.’); } // set the $this->fileNameWithPath=MODULE_REL_PATH . FILEPATH_APPCONFIGS . $this->fileName;
} /** * Sets a reference to the current data in session so it can be stored during session lifetime. * @see AppConfigBaseAbstract::constructAdmin() */ protected function constructAdmin() { global $S; $className =get_called_ class(); // if items list and changed flag are set in session - they are copied into class attributes if
$return[‘fileLocation’]=$this->cachePath.$keyDir.’/’; $return[‘fileName’]=$return[‘keyHash’].’.cache’; return $return; } /** * Sets a value in the cache for a certain key. * @param String $key * @param Mixed $value * @param String $expireTime * @return Boolean - indicating if the key was correctly saved in the cache */ public function
set($key, $value, $expireTime=0) { // CHECK INPUTS // if key is not set if (!$key) return false; // do not store ‘null’ values if ($value===null) return false; // FILE AND DIRECTORY MANAGEMENT $params=$this->getFileDetails($key); // attempt to create the directory chain if (!Dir::create($params[‘fileLocation’])) return false; //
DETERMINE THE EXPIRE TIMESTAMP if (is_numeric($expireTime) and $expireTime>0) { $expireTimestamp=TIMESTAMP+$expireTime; } else { switch (substr($expireTime, -1)) { case ‘s’: $expireTimestamp=TIMESTAMP+$expireTime;break; case ‘m’: $expireTimestamp=TIMESTAMP+$expireTime*60;break; case ‘h’:
$expireTimestamp=TIMESTAMP+$expireTime*3600;break; case ‘d’: $expireTimestamp=TIMESTAMP+$expireTime*86400;break; default: $expireTimestamp=0; } } if (!$expireTimestamp) $expireTimestamp = TIMESTAMP + $this->defaultExpireTime; // FILE CONTENT $fileContent =$expire Timestamp .serialize($value) ; // WRITE THE
CACHE FILE return File::create($params[‘fileLocation’].$params[‘fileName’], $fileContent); } /** * Gets a value stored in the cache for a certain key. * @param String $key * @return Mixed - the stored value or null if the key was not found */ public function get($key) { // CHECK INPUTS if (!$key) return null; // CHECK THE FILE // get file
params $params=$this->getFileDetails($key); // check the file if (!file_exists($params[‘fileLocation’] .$params[‘fileName’]) or !is_readable($params [‘fileLocation’].$params[‘fileName’])) return null; // READ THE FILE$fc=File::getContents($params[‘fileLocation’].$params[‘fileName’]); // get and check expiration time $expirationTimestamp
=substr ($fc, 0, 10); if ($expirationTimestamp<TIMESTAMP) { // delete the expired cache from disk $this->delete($key); return null; } // get contents, unserialize it and return it $valueSer=substr($fc, 10); $value=@unserialize($valueSer); if ($valu e===false) return null; else return $value; } /** * Deletes the value stored in the cache
for a certain key. * @param Mixed $key - if it is an array - deletes all those keys; if it is a string - deleted only that key * @return Boolean - indicating if the key was correctly deleted in the cache */ public function delete($key) { // CHECK INPUTS if (!$key) return true; // CHECK THE FILE $return=1; // A LIST OF KEYS TO BE DELETED if
(is_array($key)) { foreach($key as $k) { // get file params $params=$this->getFileDetails($k); // check the file if (!file_exists($params[‘fileLocation’].$params[‘fileName’])) continue; // delete the file $return*=File::delete($params[‘fileLocation’].$params[‘fileName’]); } } // ONLY ONE KEY else { // get file params $params=$this-
>getFileDetails($key); // check the file if (!file_exists($params[‘fileLocation’].$params[‘fileName’])) return true; // delete the file $return=File::delete($params[‘fileLocation’].$params[‘fileName’]); } return (Bool)$return; } /** * Deletes the whole cache content. * @return Boolean - indicating if the cache was completely destroyed * @see
EngineCacheBaseInterface::flush() */ public function flush() { return Dir::delete($this->cachePath); } /** * Returns an associative array of details for a certain key: the file location, the expire timestamp * @return Array */ public function getInfo($key) { $return=array(); // associate the key $return[‘key’]=$key; // get more details
$params=$this->getFileDetails($key); $fullFileName=$params[‘fileLocation’].$params[‘fileName’]; // CHECK IF THE FILE EXISTS if (!file_exists($fullFileName) or !is_readable($fullFileName)) { $return[‘fileExists’]=false; } else { // associate some more keys $return[‘fileExists’]=true; $return[‘keyHash’]=$params[‘keyHash’];
$return[‘fileLocation’]=$params[‘fileLocation’]; $return[‘fileName’]=$params[‘fileName’]; $return[‘fileSize’]=filesize($fullFileName); // get expire time $fc=File::getContents($fullFileName); $return[‘expireTimestamp’]=substr($fc, 0, 10); $return[‘expireTimestampReadable’]=date(TIMESTAMP_FULL_FORMAT, $return[‘expireTimestamp’]); //
get the value $return [‘cachedValue’] =unserialize (substr($fc, 10)); } return $return; } } <?php namespace EnginePlugins; /** * The class is used for registering a new plugin. It is extended in a class which is automatically * executed. * @author Gabriel */ abstract class RegisterAbstract { /** * The list of observers for a registered plugin.
* @var Array - associative array of [triggerName][index][EnginePluginsObserver object] */ protected $observers=array(); /** * The constructor will register the current plugin. */ public function __construct() { $this->register(); } /** * Stores a new observer for this plugin (the method is called from the defined method register() * in the
concrete classes. * @param String $triggerName - the trigger name * @param EnginePluginsObserver $obs - the observer object * @throws Exception - if the triger name is not correct */ protected function addObserver($triggerName, EnginePluginsObserver $obs) { // check trigger name if (!$triggerName) { throw new Exception(‘The
trigger name was not set in ‘.get_called_class().’::’.__FUNCTION__.”.”); } $this->observers[$triggerName][] = $obs; } /** * The method will add new observers to the current plugin (using the addObserver() method. */ abstract protected function register(); /** * Returns the list of observers for the current * @return multitype: */ public
function getObservers() { return $this->observers; } } <?php namespace AppEntityMatch; /** * The class manages the matching of suppliers * @author Gabriel */ class Supplier extends AppEntityMatchBaseAbstract { /** * The export fields for suppliers. * @var Array */ protected $exportFields = array(‘alias’, ‘company’); /** * Extra
filters - deleted and duplicated suppliers are not allwed. * @var String */ protected $matchingFilteringSQL = ‘AND ent.deleted=0 AND ent.idRealSupplier=0’; /** * The class name which will instantiate the Entity - used for primaryKey search. * @var String */ protected $entityClassName = ‘EntitySupplier’; /** * (non-PHPdoc) * @see
AppEntityMatchBaseAbstract::setTableName() */ protected function setTableName() { global $DBTSuppliers; $this->tableName = $DBTSuppliers; } /** * Sets a search by supplier alias. * @param String $value - the supplier alias. * @param Boolean $useWildcard - uses wildcard for this search or not. */ public function setAlias($value,
$useWildcard=true) { $this->setSearchCriterion(‘alias’, $value, $useWildcard); } /** * Sets a search by supplier company name. * @param String $value - the supplier company name. * @param Boolean $useWildcard - uses wildcard for this search or not. */ public function setCompany($value, $useWildcard=true) { $this-
>setSearchCriterion(‘company’, $value, $useWildcard); } /** * Sets a search by supplier fiscal code. * @param String $value - the supplier fiscal code. */ public function setFiscalCode($value) { $this->setSearchCriterion(‘fiscalCode’, $value, false); } /** * Searches a supplier by its code. * @param String $value * @param String $codeName
- indicate the type of code (iata, tktCode, etc) */ public function setCode($value, $codeName) { // check the code name global $CFG; if (!$CFG[‘travel’][‘standardCodes’][$codeName]) { throw new Exception(“The supplier code `{$codeName}` is not valid - you can only use: “.implode(‘, ‘, array_keys($CFG[‘travel’][‘standardCodes’]))); } //
add the search criterion $this->setSearchCriterion(‘code’, $value, false, array(‘codeName’=>$codeName)); } /** * Searches a supplier by the matching manually set in the external reservations system configs. * @param String $name - the supplier name * @param Int $idExternalResSystem - the external system */ public function
setExtResSysName($name, $idExternalResSystem) { $this->setSearchCriterion(‘extResSys’, $name, false, array(‘idExtResSystem’=>$idExternalResSystem)); } /** * This method does a special search for supplier code (for the rest of the criteria, it uses the parent call. * @see AppEntityMatchBaseAbstract::searchRecords() */ protected
function dispatchSearchRecords($field, $value, $useWildcard, Array $options=array()) { switch ($field) { case ‘code’: return $this->searchRecords_code($value, $options); break; case ‘extResSys’: return $this->searchRecords_extResSys($value, $options); break; default: return parent::dispatchSearchRecords($field, $value,
$useWildcard, $options); } } /** * Searches a supplier by its code. * @param String $value - the supplier code * @param Array $options - stores the code name used */ private function searchRecords_code($value, Array $options) { global $DBTSupplierCodes; $db = DB::getInstance(); // RUN SQL $matchSupplierCodeSQL = “ SELECT
“.$this->getSelectingFieldsSQL().” FROM `$DBTSupplierCodes` AS sc, `{$this->tableName}` AS ent WHERE sc.`code`=? AND sc.`value`=? AND `ent`.`id`=`sc`.`idSupplier` {$this->matchingFilteringSQL} “; $matchSupplierCodeEx = $db->Execute($matchSupplierCodeSQL, array($options[‘codeName’], $value)); if (!$matchSupplierCodeEx)
{ writeLog(“Could not match supplier by their code.”, ‘events’, 9); throw new Exception(‘Could not match supplier by their code.’); } // STORE RESULTS $return = array(); foreach($matchSupplierCodeEx as $supp) { $return[$supp[‘id’]] = $supp; } return $return; } /** * Searches a supplier by its matching in the external reservation
systems. * @param unknown $valuem * @param array $options */ private function searchRecords_extResSys($value, Array $options) { global $DBTImportRes_suppliersAssociations; $db = DB::getInstance(); // SEARCH IN THE DB $searchSupplierSQL=”SELECT tinaSupplierId FROM `$DBTImportRes_suppliersAssociations` WHERE
systemSupplierId=? AND systemId=?”; $searchSupplierEx=$db->Execute($searchSupplierSQL, array($value, $options[‘idExtResSystem’])); if (!$searchSupplierEx) { writeLog(“Could not match supplier by the external reservation systems code.”, ‘events’, 9); throw new Exception(‘Could not match supplier by the external reservation systems
code.’); } // RETURN THE RESULT $supp=$searchSupplierEx->FetchRow(); $return = array(); if ($supp[‘tinaSupplierId’]) { $return=$this->searchRecord_primaryKey($supp[‘tinaSupplierId’]); } return $return; } } <?php namespace AppConfig; abstract class XmlBasicAbstract extends BaseAbstract { /** * Stores the configuration file
(relative to the “files/config/” dir). For config files stored * inside subdirectories, the subdirectory is included (Ex: services/servicesList.xml). * @var String */ protected $fileName=null; /** * The filename with its full path. * @var String */ protected $fileNameWithPath=null; /** * (non-PHPdoc) * @see
AppConfigBaseAbstract::constructInit() */ protected function constructInit() { // check if the file name is okay if (!$this->fileName) { throw new Exception(‘You did not set the `fileName` attribute for the class `’.get_called_class().’`.’); } // set the $this->fileNameWithPath=MODULE_REL_PATH . FILEPATH_APPCONFIGS . $this->fileName;
} /** * Sets a reference to the current data in session so it can be stored during session lifetime. * @see AppConfigBaseAbstract::constructAdmin() */ protected function constructAdmin() { global $S; $className =get_called_ class(); // if items list and changed flag are set in session - they are copied into class attributes if
(isset($S[‘admin’][‘configApp’][$className][‘itemsList’])) { $this->itemsList=$S [‘admin’] [‘configApp’] [$className ][‘itemsList’]; } if (isset($S[‘admin’][‘configApp’][$className][‘changedFlag’])) { $this->changedFlag=$S[‘admin’][‘configApp’][$className][‘changedFlag’]; } // these references will keep the data over different page loads
$S[‘admin’] [‘configApp’] [$className] [‘itemsList’] =&$this->itemsList; $S[‘admin’][‘configApp’][$className][‘changedFlag’]=&$this->changedFlag; } /** * (non-PHPdoc) * @see AppConfigBaseAbstract::getAll_rawData() */ protected function getAll_rawData() { // return the output in case the file does not exist if (!file_exists($this-
>fileNameWithPath)) return $this->getAll_rawData_fileNotExists(); // the file exists - load the content as XML (and check it) $xml=@simplexml_load_file($this->fileNameWithPath); if (!($xml instanceof SimpleXMLElement)) throw new Exception(‘The config file is not a well formed XML (class = ‘.get_called_class().’ ; file = ‘.$this-
>fileNameWithPath.’).’); // return the array from the parsed XML content return $this->getAll _rawData _extract DataFromFile($xml); } /** * Sets the default output in case the XML file is missing. * @return Array */ protected function getAll_rawData_fileNotExists() { return array(); } /** * Returns the extracted data after the XML content
is parsed. * @param SimpleXMLElement $xml - the parsed xml * @return Array - the items list or whatever output is needed. */ abstract protected function getAll_ rawData _extractData FromFile ( Simple XMLElement $xml); /** * Sets an element in the internal attribute $this->itemsList. The method can be called multiple * times and they
will overwrite the older values. * @param String $var - or the name of one key (a string); * @param Mixed $value - the value of the key; * @throws Exception - if input is bad */ public function set($var, $value) { // check constructor type if ($this->constructType!=’admin’) throw new Exception(“You can use the method `”.get _called_
class().’::’.__FUNCTION__.”` only if the constructor type is `admin`.”); // check inputs if (!is_string($var)) throw new Exception(“You did not set() a correct name for the key.”); // (re)set one key $this->itemsList[$var]=$value; // update the changed flag $this->changedFlag=true; } /** * Sets all the elements in the internal attribute $this-
>itemsList (rewrites any old data * already stored). The parameter is an associative array and the keys will be * stored one by one. * @param Array $vars - associative array of keys * @throws Exception - if input is bad */ public function setAll($vars) { // check constructor type if ($this->constructType!=’admin’) throw new Exception(“You
can use the method `”.get_c alled_class().’::’.__ FUNCTION__.”` only if the constructor type is `admin`.”); // check inputs if (!is_array($vars)) throw new Exception(“You did not setAll() a correct list of elements - the parameter is not an array.”); // (re)set a list of keys $this->itemsList=$vars; // update the changed flag $this->changed
Flag=true; } /** * (non-PHPdoc) * @see AppConfigBaseAbstract::save_write_do() */ protected function save_write_do() { // GETS THE SIMPLEXML OBJECT TO BE WRITTEN ON DISK gets the simplexml object $xmlObj=$this->save_write_do _getXml(); // checks that the object is correct (it is a valid simplexml object) if (!($xmlObj
instanceof SimpleXMLElement)) throw new Exception(‘The output of the method `’.get_ called_class() .’::save_write_do_getXml` must be a `SimpleXMLElement` object.’); // (RE)WRITE FILE ON DISK // check if the file is writeable $fileChmod=false; if (file_exists($this->fileNameWithPath)) { if (!is_writeable($this->fileNameWithPath)) $this-
>addErrorMessage(‘The config file exists but it is not writeable.’); } else { $fileChmod=true; } // (OVER)WRITE THE FILE CONTENT - if (!file_put_contents($this->fileNameWithPath, $xmlObj->asXml())) { $this->addErrorMessage(‘The config file could not be (over)written.’); } // if the file did not exist - chmod it if ($fileChmod) { if
(!chmod($this->fileNameWithPath, 0777)) { $this->addErrorMessage(‘The config file could not have its acess rights updated.’); } } } /** * Returns the SimpleXML object to be written on disk. * @return SimpleXMLElement */ abstract protected function save_write_do_getXml(); } <?php namespace EngineCache; /** * The class is used to
manage the cache stored on disk. * @author Gabriel Grosu */ class Disk implements EngineCacheBaseInterface { /** * The full location where the cache files are stored. * @var String */ protected $cachePath=’’; /** * The prefix key is used to avoid the reusing of keys if the application was updated. * @var String */ protected
$keyPrefix=’’; /** * The default expiration time limit, if no param is specified when calling set() * @var int */ protected $defaultExpireTime = 2592000; // 2592000 = one month /** * The class constructor. */ public function __construct() { global $CFG; // realpath is used because cwd may change in __destructor(s) - AppEntityCache
caches the entity object in destructors. $this->cachePath=realpath(MODULE_REL_PATH.$CFG[‘paths’][‘files’]).’/’.$CFG[‘cache’][‘disk’][‘location’]; // sets the mem cached key prefix $this->keyPrefix=$CFG[‘global’][‘application’][‘versionBuild’]; return true; } /** * Returns some associative array of data determined from the key * @param Array
$key */ private function getFileDetails($key) { $return=array(); // rewrite the key $key=$this->keyPrefix.’-’.$key; // the key hash $return[‘keyHash’]=md5($key); // the subdir for the current key $keyDir=substr($return[‘keyHash’], 0, 2); // the full file location $return[‘fileLocation’]=$this->cachePath.$keyDir.’/’;
$return[‘fileName’]=$return[‘keyHash’].’.cache’; return $return; } /** * Sets a value in the cache for a certain key. * @param String $key * @param Mixed $value * @param String $expireTime * @return Boolean - indicating if the key was correctly saved in the cache */ public function set($key, $value, $expireTime=0) { // CHECK INPUTS
// if key is not set if (!$key) return false; // do not store ‘null’ values if ($value===null) return false; // FILE AND DIRECTORY MANAGEMENT $params=$this->getFileDetails($key); // attempt to create the directory chain if (!Dir::create($params[‘fileLocation’])) return false; // DETERMINE THE EXPIRE TIMESTAMP if
(is_numeric($expireTime) and $expireTime>0) { $expireTimestamp=TIMESTAMP+$expireTime; } else { switch (substr($expireTime, -1)) { case ‘s’: $expireTimestamp=TIMESTAMP+$expireTime;break; case ‘m’: $expireTimestamp=TIMESTAMP+$expireTime*60;break; case ‘h’: $expireTimestamp=TIMESTAMP+$expireTime*3600;break; case
‘d’: $expireTimestamp=TIMESTAMP+$expireTime*86400;break; default: $expireTimestamp=0; } } if (!$expireTimestamp) $expireTimestamp = TIMESTAMP + $this->defaultExpireTime; // FILE CONTENT $fileContent =$expire Timestamp .serialize($value) ; // WRITE THE CACHE FILE return
File::create($params[‘fileLocation’].$params[‘fileName’], $fileContent); } /** * Gets a value stored in the cache for a certain key. * @param String $key * @return Mixed - the stored value or null if the key was not found */ public function get($key) { // CHECK INPUTS if (!$key) return null; // CHECK THE FILE // get file params
$params=$this->getFileDetails($key); // check the file if (!file_exists($params[‘fileLocation’] .$params[‘fileName’]) or !is_readable($params [‘fileLocation’].$params[‘fileName’])) return null; // READ THE FILE$fc=File::getContents($params[‘fileLocation’].$params[‘fileName’]); // get and check expiration time $expirationTimestamp =substr
($fc, 0, 10); if ($expirationTimestamp<TIMESTAMP) { // delete the expired cache from disk $this->delete($key); return null; } // get contents, unserialize it and return it $valueSer=substr($fc, 10); $value=@unserialize($valueSer); if ($valu e===false) return null; else return $value; } /** * Deletes the value stored in the cache for a
certain key. * @param Mixed $key - if it is an array - deletes all those keys; if it is a string - deleted only that key * @return Boolean - indicating if the key was correctly deleted in the cache */ public function delete($key) { // CHECK INPUTS if (!$key) return true; // CHECK THE FILE $return=1; // A LIST OF KEYS TO BE DELETED if
(is_array($key)) { foreach($key as $k) { // get file params $params=$this->getFileDetails($k); // check the file if (!file_exists($params[‘fileLocation’].$params[‘fileN
@ @
@
@
@
@ @ @
@
@ @
@ @ @
@ @
@ @
@ @ @
@ @
@
@ @
@ @
@ @ @
@
@ @ @ @
@ @
@
@ @
@ @
@
@
@
@ @ @
@
@ @
@ @ @
@ @
@ @
@ @ @
@ @
@
@ @
@ @
@ @ @
@
@
@
@
@ @
@ @ @
@ @
@
@
@ @ @
@
@
@ @ @ @
@ @
@
@ @
@ @
@
@
@
@ @ @
@
@ @
@ @ @
@ @
@ @
@ @ @
@ @
@
@ @
@ @
@ @ @
@
@ @ @ @
@ @
@
@ @
@ @
@
@
@
@ @ @
@
@ @
@ @ @
@ @
@ @
@ @ @
@ @
@
@ @
@ @
@ @ @
@
@
@
@
@ @
@ @ @
@ @
@
@
@ @ @
@
@
@ @ @ @
@ @
@
@ @
@ @
@
@
@
@ @ @
@
@ @
@ @ @
@ @
@ @
@ @ @
@ @
@
@ @
@ @
@ @ @
@
@ @ @ @
@ @
@
@ @
@ @
@
@
@
@ @ @
@
@ @
@ @ @
@ @
@ @
@ @ @
@ @
@
@ @
@ @
@ @ @
@
@
@
@
@ @
@ @ @
@ @
@
@
@ @ @
@
@
@ @ @ @
@ @
@
@ @
@ @
@
@
@
@ @ @
@
@ @
@ @ @
@ @
@ @
@ @ @
@ @
@
@ @
@ @
@ @ @
@
@ @ @ @
@ @
@
@ @
@ @
@
@
@
@ @ @
@
@ @
@ @ @
@ @
@ @
@ @ @
@ @
@
@ @
@ @
@ @ @
@
@
@
@
@ @
@ @ @
@ @
@
@
@ @ @
@
@
@ @ @ @
@ @
@
@ @
@ @
@
@
@
@ @ @
@
@ @
@ @ @
@ @
@ @
@ @ @
@ @
@
@ @
@ @
@ @ @
@
@ @
@ @
@
@ @ @ @
@ @
@
@ @
@ @
@
@
@
@ @ @
@
@ @
@ @ @
@ @
@ @
@ @ @
@ @
@
@ @
@ @
@ @ @
@
@
@
@
@ @
@ @ @
@ @
@
@
@ @ @
@
@
@ @ @ @
@ @
@
@ @
@ @
@
@
@
@ @ @
@
@ @
@ @ @
@ @
@ @
@ @
@
@ @ @ @
@ @
@
@ @
@ @
@
@
@
@ @ @
@
@ @
@ @ @
@ @
@ @
@ @ @
@ @
@
@ @
@ @
@ @ @
@
@
@
@
@ @
@ @ @
@ @
@
@
@ @ @
@
@
@ @ @ @
@ @
@
@ @
@ @
@
@
@
@ @ @
@
@ @
@ @ @
@ @
@ @
@ @
@
@ @ @ @
@ @
@
@ @
@ @
@
@
@
@ @ @
@
@ @
@ @ @
@ @
@ @
@ @ @
@ @
@
@ @
@ @
@ @ @
@
@
@
@
@ @
@ @ @
@ @
@
@
@ @ @
@
@
@ @ @ @
@ @
@
@ @
@ @
@
@
@
@ @ @
@
@ @
@ @ @
@ @
@ @ @ @
@ @
@
@ @
@ @
@
@
@
@ @ @
@
@ @
@ @ @
@ @
@ @
@ @ @
@ @
@
@ @
@ @
@ @ @
@
@
@
@
@ @
@ @ @
@ @
@
@
@ @ @
@
@
@ @ @ @
@ @
@
@ @
@ @
@
@
@
@ @ @
@
@ @
@ @ @
@ @
@ @
@ @ @
@ @
@
@ @
@ @
@ @ @
@
@ @ @ @
@ @
@
@ @
@ @
@
@
@
@ @ @
@
@ @
@ @ @
@ @
@ @
@ @ @
@ @
@
@ @
@ @
@ @ @
@
@
@
@
@ @
@ @ @
@ @
@
@
@ @ @
@
@
@ @ @ @
@ @
@
@ @
@ @
@
@
@
@ @ @
@
@ @
@ @ @
@ @
@ @
@ @ @
@ @
@
@ @
@ @
@ @ @
@
@ @
@ @
@
@ @ @ @
@ @
@
@ @
@ @
@
@
@
@ @ @
@
@ @
@ @ @
@ @
@ @
@ @ @
@ @
@
@ @
@ @
@ @ @
@
@
@
@
@ @
@ @ @
@ @
@
@
@ @ @
@
@
@ @ @ @
@ @
@
@ @
@ @
@
@
@
@ @ @
@
@ @
@ @ @
@ @
Business critical
end-to-end solutions
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus Catalogue 2015

More Related Content

What's hot

The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of LithiumNate Abele
 
Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleHugo Hamon
 
Advanced php testing in action
Advanced php testing in actionAdvanced php testing in action
Advanced php testing in actionJace Ju
 
Adding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy ApplicationsAdding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy ApplicationsSam Hennessy
 
Dependency Injection IPC 201
Dependency Injection IPC 201Dependency Injection IPC 201
Dependency Injection IPC 201Fabien Potencier
 
Everything About PowerShell
Everything About PowerShellEverything About PowerShell
Everything About PowerShellGaetano Causio
 
購物車程式架構簡介
購物車程式架構簡介購物車程式架構簡介
購物車程式架構簡介Jace Ju
 
PHP Data Objects
PHP Data ObjectsPHP Data Objects
PHP Data ObjectsWez Furlong
 
Decouple Your Code For Reusability (International PHP Conference / IPC 2008)
Decouple Your Code For Reusability (International PHP Conference / IPC 2008)Decouple Your Code For Reusability (International PHP Conference / IPC 2008)
Decouple Your Code For Reusability (International PHP Conference / IPC 2008)Fabien Potencier
 
Extbase and Beyond
Extbase and BeyondExtbase and Beyond
Extbase and BeyondJochen Rau
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownpartsBastian Feder
 
Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2Fabien Potencier
 
Models and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsModels and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsRoss Tuck
 
PHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkPHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkG Woo
 
international PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretsinternational PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretssmueller_sandsmedia
 
Command Bus To Awesome Town
Command Bus To Awesome TownCommand Bus To Awesome Town
Command Bus To Awesome TownRoss Tuck
 
PhpUnit - The most unknown Parts
PhpUnit - The most unknown PartsPhpUnit - The most unknown Parts
PhpUnit - The most unknown PartsBastian Feder
 

What's hot (20)

The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of Lithium
 
Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et Pimple
 
Advanced php testing in action
Advanced php testing in actionAdvanced php testing in action
Advanced php testing in action
 
Adding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy ApplicationsAdding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy Applications
 
Dependency Injection IPC 201
Dependency Injection IPC 201Dependency Injection IPC 201
Dependency Injection IPC 201
 
Everything About PowerShell
Everything About PowerShellEverything About PowerShell
Everything About PowerShell
 
購物車程式架構簡介
購物車程式架構簡介購物車程式架構簡介
購物車程式架構簡介
 
zinno
zinnozinno
zinno
 
My shell
My shellMy shell
My shell
 
PHP Data Objects
PHP Data ObjectsPHP Data Objects
PHP Data Objects
 
Decouple Your Code For Reusability (International PHP Conference / IPC 2008)
Decouple Your Code For Reusability (International PHP Conference / IPC 2008)Decouple Your Code For Reusability (International PHP Conference / IPC 2008)
Decouple Your Code For Reusability (International PHP Conference / IPC 2008)
 
Oops in php
Oops in phpOops in php
Oops in php
 
Extbase and Beyond
Extbase and BeyondExtbase and Beyond
Extbase and Beyond
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
 
Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2
 
Models and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsModels and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and Hobgoblins
 
PHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkPHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php framework
 
international PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretsinternational PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secrets
 
Command Bus To Awesome Town
Command Bus To Awesome TownCommand Bus To Awesome Town
Command Bus To Awesome Town
 
PhpUnit - The most unknown Parts
PhpUnit - The most unknown PartsPhpUnit - The most unknown Parts
PhpUnit - The most unknown Parts
 

Similar to dcs plus Catalogue 2015

DRUPAL 8 STORAGES OVERVIEW
DRUPAL 8 STORAGES OVERVIEWDRUPAL 8 STORAGES OVERVIEW
DRUPAL 8 STORAGES OVERVIEWDrupalCamp Kyiv
 
vfsStream - effective filesystem mocking
vfsStream - effective filesystem mocking vfsStream - effective filesystem mocking
vfsStream - effective filesystem mocking Sebastian Marek
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Developmentjsmith92
 
Aura Project for PHP
Aura Project for PHPAura Project for PHP
Aura Project for PHPHari K T
 
PHP Traits
PHP TraitsPHP Traits
PHP Traitsmattbuzz
 
Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Jeff Carouth
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony TechniquesKris Wallsmith
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency InjectionRifat Nabi
 
Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)Fabien Potencier
 
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitinternational PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitsmueller_sandsmedia
 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologyDaniel Knell
 
laravel tricks in 50minutes
laravel tricks in 50minuteslaravel tricks in 50minutes
laravel tricks in 50minutesBarang CK
 
50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 MinutesAzim Kurt
 

Similar to dcs plus Catalogue 2015 (20)

DRUPAL 8 STORAGES OVERVIEW
DRUPAL 8 STORAGES OVERVIEWDRUPAL 8 STORAGES OVERVIEW
DRUPAL 8 STORAGES OVERVIEW
 
vfsStream - effective filesystem mocking
vfsStream - effective filesystem mocking vfsStream - effective filesystem mocking
vfsStream - effective filesystem mocking
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Development
 
Dando nome aos códigos
Dando nome aos códigosDando nome aos códigos
Dando nome aos códigos
 
Twitter codeigniter library
Twitter codeigniter libraryTwitter codeigniter library
Twitter codeigniter library
 
Aura Project for PHP
Aura Project for PHPAura Project for PHP
Aura Project for PHP
 
PHP Traits
PHP TraitsPHP Traits
PHP Traits
 
Drupal7 dbtng
Drupal7  dbtngDrupal7  dbtng
Drupal7 dbtng
 
Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony Techniques
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
 
BEAR DI
BEAR DIBEAR DI
BEAR DI
 
Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)
 
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitinternational PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technology
 
Unittests für Dummies
Unittests für DummiesUnittests für Dummies
Unittests für Dummies
 
C99
C99C99
C99
 
Migrare da symfony 1 a Symfony2
 Migrare da symfony 1 a Symfony2  Migrare da symfony 1 a Symfony2
Migrare da symfony 1 a Symfony2
 
laravel tricks in 50minutes
laravel tricks in 50minuteslaravel tricks in 50minutes
laravel tricks in 50minutes
 
50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes
 

Recently uploaded

Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Next-generation AAM aircraft unveiled by Supernal, S-A2
Next-generation AAM aircraft unveiled by Supernal, S-A2Next-generation AAM aircraft unveiled by Supernal, S-A2
Next-generation AAM aircraft unveiled by Supernal, S-A2Hyundai Motor Group
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxMaking_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxnull - The Open Security Community
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your BudgetHyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your BudgetEnjoy Anytime
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 

Recently uploaded (20)

Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Next-generation AAM aircraft unveiled by Supernal, S-A2
Next-generation AAM aircraft unveiled by Supernal, S-A2Next-generation AAM aircraft unveiled by Supernal, S-A2
Next-generation AAM aircraft unveiled by Supernal, S-A2
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxMaking_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your BudgetHyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 

dcs plus Catalogue 2015

  • 1. $return[‘fileLocation’]=$this->cachePath.$keyDir.’/’; $return[‘fileName’]=$return[‘keyHash’].’.cache’; return $return; } /** * Sets a value in the cache for a certain key. * @param String $key * @param Mixed $value * @param String $expireTime * @return Boolean - indicating if the key was correctly saved in the cache */ public function set($key, $value, $expireTime=0) { // CHECK INPUTS // if key is not set if (!$key) return false; // do not store ‘null’ values if ($value===null) return false; // FILE AND DIRECTORY MANAGEMENT $params=$this->getFileDetails($key); // attempt to create the directory chain if (!Dir::create($params[‘fileLocation’])) return false; // DETERMINE THE EXPIRE TIMESTAMP if (is_numeric($expireTime) and $expireTime>0) { $expireTimestamp=TIMESTAMP+$expireTime; } else { switch (substr($expireTime, -1)) { case ‘s’: $expireTimestamp=TIMESTAMP+$expireTime;break; case ‘m’: $expireTimestamp=TIMESTAMP+$expireTime*60;break; case ‘h’: $expireTimestamp=TIMESTAMP+$expireTime*3600;break; case ‘d’: $expireTimestamp=TIMESTAMP+$expireTime*86400;break; default: $expireTimestamp=0; } } if (!$expireTimestamp) $expireTimestamp = TIMESTAMP + $this->defaultExpireTime; // FILE CONTENT $fileContent =$expire Timestamp .serialize($value) ; // WRITE THE CACHE FILE return File::create($params[‘fileLocation’].$params[‘fileName’], $fileContent); } /** * Gets a value stored in the cache for a certain key. * @param String $key * @return Mixed - the stored value or null if the key was not found */ public function get($key) { // CHECK INPUTS if (!$key) return null; // CHECK THE FILE // get file params $params=$this->getFileDetails($key); // check the file if (!file_exists($params[‘fileLocation’] .$params[‘fileName’]) or !is_readable($params [‘fileLocation’].$params[‘fileName’])) return null; // READ THE FILE$fc=File::getContents($params[‘fileLocation’].$params[‘fileName’]); // get and check expiration time $expirationTimestamp =substr ($fc, 0, 10); if ($expirationTimestamp<TIMESTAMP) { // delete the expired cache from disk $this->delete($key); return null; } // get contents, unserialize it and return it $valueSer=substr($fc, 10); $value=@unserialize($valueSer); if ($valu e===false) return null; else return $value; } /** * Deletes the value stored in the cache for a certain key. * @param Mixed $key - if it is an array - deletes all those keys; if it is a string - deleted only that key * @return Boolean - indicating if the key was correctly deleted in the cache */ public function delete($key) { // CHECK INPUTS if (!$key) return true; // CHECK THE FILE $return=1; // A LIST OF KEYS TO BE DELETED if (is_array($key)) { foreach($key as $k) { // get file params $params=$this->getFileDetails($k); // check the file if (!file_exists($params[‘fileLocation’].$params[‘fileName’])) continue; // delete the file $return*=File::delete($params[‘fileLocation’].$params[‘fileName’]); } } // ONLY ONE KEY else { // get file params $params=$this- >getFileDetails($key); // check the file if (!file_exists($params[‘fileLocation’].$params[‘fileName’])) return true; // delete the file $return=File::delete($params[‘fileLocation’].$params[‘fileName’]); } return (Bool)$return; } /** * Deletes the whole cache content. * @return Boolean - indicating if the cache was completely destroyed * @see EngineCacheBaseInterface::flush() */ public function flush() { return Dir::delete($this->cachePath); } /** * Returns an associative array of details for a certain key: the file location, the expire timestamp * @return Array */ public function getInfo($key) { $return=array(); // associate the key $return[‘key’]=$key; // get more details $params=$this->getFileDetails($key); $fullFileName=$params[‘fileLocation’].$params[‘fileName’]; // CHECK IF THE FILE EXISTS if (!file_exists($fullFileName) or !is_readable($fullFileName)) { $return[‘fileExists’]=false; } else { // associate some more keys $return[‘fileExists’]=true; $return[‘keyHash’]=$params[‘keyHash’]; $return[‘fileLocation’]=$params[‘fileLocation’]; $return[‘fileName’]=$params[‘fileName’]; $return[‘fileSize’]=filesize($fullFileName); // get expire time $fc=File::getContents($fullFileName); $return[‘expireTimestamp’]=substr($fc, 0, 10); $return[‘expireTimestampReadable’]=date(TIMESTAMP_FULL_FORMAT, $return[‘expireTimestamp’]); // get the value $return [‘cachedValue’] =unserialize (substr($fc, 10)); } return $return; } } <?php namespace EnginePlugins; /** * The class is used for registering a new plugin. It is extended in a class which is automatically * executed. * @author Gabriel */ abstract class RegisterAbstract { /** * The list of observers for a registered plugin. * @var Array - associative array of [triggerName][index][EnginePluginsObserver object] */ protected $observers=array(); /** * The constructor will register the current plugin. */ public function __construct() { $this->register(); } /** * Stores a new observer for this plugin (the method is called from the defined method register() * in the concrete classes. * @param String $triggerName - the trigger name * @param EnginePluginsObserver $obs - the observer object * @throws Exception - if the triger name is not correct */ protected function addObserver($triggerName, EnginePluginsObserver $obs) { // check trigger name if (!$triggerName) { throw new Exception(‘The trigger name was not set in ‘.get_called_class().’::’.__FUNCTION__.”.”); } $this->observers[$triggerName][] = $obs; } /** * The method will add new observers to the current plugin (using the addObserver() method. */ abstract protected function register(); /** * Returns the list of observers for the current * @return multitype: */ public function getObservers() { return $this->observers; } } <?php namespace AppEntityMatch; /** * The class manages the matching of suppliers * @author Gabriel */ class Supplier extends AppEntityMatchBaseAbstract { /** * The export fields for suppliers. * @var Array */ protected $exportFields = array(‘alias’, ‘company’); /** * Extra filters - deleted and duplicated suppliers are not allwed. * @var String */ protected $matchingFilteringSQL = ‘AND ent.deleted=0 AND ent.idRealSupplier=0’; /** * The class name which will instantiate the Entity - used for primaryKey search. * @var String */ protected $entityClassName = ‘EntitySupplier’; /** * (non-PHPdoc) * @see AppEntityMatchBaseAbstract::setTableName() */ protected function setTableName() { global $DBTSuppliers; $this->tableName = $DBTSuppliers; } /** * Sets a search by supplier alias. * @param String $value - the supplier alias. * @param Boolean $useWildcard - uses wildcard for this search or not. */ public function setAlias($value, $useWildcard=true) { $this->setSearchCriterion(‘alias’, $value, $useWildcard); } /** * Sets a search by supplier company name. * @param String $value - the supplier company name. * @param Boolean $useWildcard - uses wildcard for this search or not. */ public function setCompany($value, $useWildcard=true) { $this- >setSearchCriterion(‘company’, $value, $useWildcard); } /** * Sets a search by supplier fiscal code. * @param String $value - the supplier fiscal code. */ public function setFiscalCode($value) { $this->setSearchCriterion(‘fiscalCode’, $value, false); } /** * Searches a supplier by its code. * @param String $value * @param String $codeName - indicate the type of code (iata, tktCode, etc) */ public function setCode($value, $codeName) { // check the code name global $CFG; if (!$CFG[‘travel’][‘standardCodes’][$codeName]) { throw new Exception(“The supplier code `{$codeName}` is not valid - you can only use: “.implode(‘, ‘, array_keys($CFG[‘travel’][‘standardCodes’]))); } // add the search criterion $this->setSearchCriterion(‘code’, $value, false, array(‘codeName’=>$codeName)); } /** * Searches a supplier by the matching manually set in the external reservations system configs. * @param String $name - the supplier name * @param Int $idExternalResSystem - the external system */ public function setExtResSysName($name, $idExternalResSystem) { $this->setSearchCriterion(‘extResSys’, $name, false, array(‘idExtResSystem’=>$idExternalResSystem)); } /** * This method does a special search for supplier code (for the rest of the criteria, it uses the parent call. * @see AppEntityMatchBaseAbstract::searchRecords() */ protected function dispatchSearchRecords($field, $value, $useWildcard, Array $options=array()) { switch ($field) { case ‘code’: return $this->searchRecords_code($value, $options); break; case ‘extResSys’: return $this->searchRecords_extResSys($value, $options); break; default: return parent::dispatchSearchRecords($field, $value, $useWildcard, $options); } } /** * Searches a supplier by its code. * @param String $value - the supplier code * @param Array $options - stores the code name used */ private function searchRecords_code($value, Array $options) { global $DBTSupplierCodes; $db = DB::getInstance(); // RUN SQL $matchSupplierCodeSQL = “ SELECT “.$this->getSelectingFieldsSQL().” FROM `$DBTSupplierCodes` AS sc, `{$this->tableName}` AS ent WHERE sc.`code`=? AND sc.`value`=? AND `ent`.`id`=`sc`.`idSupplier` {$this->matchingFilteringSQL} “; $matchSupplierCodeEx = $db->Execute($matchSupplierCodeSQL, array($options[‘codeName’], $value)); if (!$matchSupplierCodeEx) { writeLog(“Could not match supplier by their code.”, ‘events’, 9); throw new Exception(‘Could not match supplier by their code.’); } // STORE RESULTS $return = array(); foreach($matchSupplierCodeEx as $supp) { $return[$supp[‘id’]] = $supp; } return $return; } /** * Searches a supplier by its matching in the external reservation systems. * @param unknown $valuem * @param array $options */ private function searchRecords_extResSys($value, Array $options) { global $DBTImportRes_suppliersAssociations; $db = DB::getInstance(); // SEARCH IN THE DB $searchSupplierSQL=”SELECT tinaSupplierId FROM `$DBTImportRes_suppliersAssociations` WHERE systemSupplierId=? AND systemId=?”; $searchSupplierEx=$db->Execute($searchSupplierSQL, array($value, $options[‘idExtResSystem’])); if (!$searchSupplierEx) { writeLog(“Could not match supplier by the external reservation systems code.”, ‘events’, 9); throw new Exception(‘Could not match supplier by the external reservation systems code.’); } // RETURN THE RESULT $supp=$searchSupplierEx->FetchRow(); $return = array(); if ($supp[‘tinaSupplierId’]) { $return=$this->searchRecord_primaryKey($supp[‘tinaSupplierId’]); } return $return; } } <?php namespace AppConfig; abstract class XmlBasicAbstract extends BaseAbstract { /** * Stores the configuration file (relative to the “files/config/” dir). For config files stored * inside subdirectories, the subdirectory is included (Ex: services/servicesList.xml). * @var String */ protected $fileName=null; /** * The filename with its full path. * @var String */ protected $fileNameWithPath=null; /** * (non-PHPdoc) * @see AppConfigBaseAbstract::constructInit() */ protected function constructInit() { // check if the file name is okay if (!$this->fileName) { throw new Exception(‘You did not set the `fileName` attribute for the class `’.get_called_class().’`.’); } // set the $this->fileNameWithPath=MODULE_REL_PATH . FILEPATH_APPCONFIGS . $this->fileName; } /** * Sets a reference to the current data in session so it can be stored during session lifetime. * @see AppConfigBaseAbstract::constructAdmin() */ protected function constructAdmin() { global $S; $className =get_called_ class(); // if items list and changed flag are set in session - they are copied into class attributes if (isset($S[‘admin’][‘configApp’][$className][‘itemsList’])) { $this->itemsList=$S [‘admin’] [‘configApp’] [$className ][‘itemsList’]; } if (isset($S[‘admin’][‘configApp’][$className][‘changedFlag’])) { $this->changedFlag=$S[‘admin’][‘configApp’][$className][‘changedFlag’]; } // these references will keep the data over different page loads $S[‘admin’] [‘configApp’] [$className] [‘itemsList’] =&$this->itemsList; $S[‘admin’][‘configApp’][$className][‘changedFlag’]=&$this->changedFlag; } /** * (non-PHPdoc) * @see AppConfigBaseAbstract::getAll_rawData() */ protected function getAll_rawData() { // return the output in case the file does not exist if (!file_exists($this- >fileNameWithPath)) return $this->getAll_rawData_fileNotExists(); // the file exists - load the content as XML (and check it) $xml=@simplexml_load_file($this->fileNameWithPath); if (!($xml instanceof SimpleXMLElement)) throw new Exception(‘The config file is not a well formed XML (class = ‘.get_called_class().’ ; file = ‘.$this- >fileNameWithPath.’).’); // return the array from the parsed XML content return $this->getAll _rawData _extract DataFromFile($xml); } /** * Sets the default output in case the XML file is missing. * @return Array */ protected function getAll_rawData_fileNotExists() { return array(); } /** * Returns the extracted data after the XML content is parsed. * @param SimpleXMLElement $xml - the parsed xml * @return Array - the items list or whatever output is needed. */ abstract protected function getAll_ rawData _extractData FromFile ( Simple XMLElement $xml); /** * Sets an element in the internal attribute $this->itemsList. The method can be called multiple * times and they will overwrite the older values. * @param String $var - or the name of one key (a string); * @param Mixed $value - the value of the key; * @throws Exception - if input is bad */ public function set($var, $value) { // check constructor type if ($this->constructType!=’admin’) throw new Exception(“You can use the method `”.get _called_ class().’::’.__FUNCTION__.”` only if the constructor type is `admin`.”); // check inputs if (!is_string($var)) throw new Exception(“You did not set() a correct name for the key.”); // (re)set one key $this->itemsList[$var]=$value; // update the changed flag $this->changedFlag=true; } /** * Sets all the elements in the internal attribute $this- >itemsList (rewrites any old data * already stored). The parameter is an associative array and the keys will be * stored one by one. * @param Array $vars - associative array of keys * @throws Exception - if input is bad */ public function setAll($vars) { // check constructor type if ($this->constructType!=’admin’) throw new Exception(“You can use the method `”.get_c alled_class().’::’.__ FUNCTION__.”` only if the constructor type is `admin`.”); // check inputs if (!is_array($vars)) throw new Exception(“You did not setAll() a correct list of elements - the parameter is not an array.”); // (re)set a list of keys $this->itemsList=$vars; // update the changed flag $this->changed Flag=true; } /** * (non-PHPdoc) * @see AppConfigBaseAbstract::save_write_do() */ protected function save_write_do() { // GETS THE SIMPLEXML OBJECT TO BE WRITTEN ON DISK gets the simplexml object $xmlObj=$this->save_write_do _getXml(); // checks that the object is correct (it is a valid simplexml object) if (!($xmlObj instanceof SimpleXMLElement)) throw new Exception(‘The output of the method `’.get_ called_class() .’::save_write_do_getXml` must be a `SimpleXMLElement` object.’); // (RE)WRITE FILE ON DISK // check if the file is writeable $fileChmod=false; if (file_exists($this->fileNameWithPath)) { if (!is_writeable($this->fileNameWithPath)) $this- >addErrorMessage(‘The config file exists but it is not writeable.’); } else { $fileChmod=true; } // (OVER)WRITE THE FILE CONTENT - if (!file_put_contents($this->fileNameWithPath, $xmlObj->asXml())) { $this->addErrorMessage(‘The config file could not be (over)written.’); } // if the file did not exist - chmod it if ($fileChmod) { if (!chmod($this->fileNameWithPath, 0777)) { $this->addErrorMessage(‘The config file could not have its acess rights updated.’); } } } /** * Returns the SimpleXML object to be written on disk. * @return SimpleXMLElement */ abstract protected function save_write_do_getXml(); } <?php namespace EngineCache; /** * The class is used to manage the cache stored on disk. * @author Gabriel Grosu */ class Disk implements EngineCacheBaseInterface { /** * The full location where the cache files are stored. * @var String */ protected $cachePath=’’; /** * The prefix key is used to avoid the reusing of keys if the application was updated. * @var String */ protected $keyPrefix=’’; /** * The default expiration time limit, if no param is specified when calling set() * @var int */ protected $defaultExpireTime = 2592000; // 2592000 = one month /** * The class constructor. */ public function __construct() { global $CFG; // realpath is used because cwd may change in __destructor(s) - AppEntityCache caches the entity object in destructors. $this->cachePath=realpath(MODULE_REL_PATH.$CFG[‘paths’][‘files’]).’/’.$CFG[‘cache’][‘disk’][‘location’]; // sets the mem cached key prefix $this->keyPrefix=$CFG[‘global’][‘application’][‘versionBuild’]; return true; } /** * Returns some associative array of data determined from the key * @param Array $key */ private function getFileDetails($key) { $return=array(); // rewrite the key $key=$this->keyPrefix.’-’.$key; // the key hash $return[‘keyHash’]=md5($key); // the subdir for the current key $keyDir=substr($return[‘keyHash’], 0, 2); // the full file location $return[‘fileLocation’]=$this->cachePath.$keyDir.’/’; $return[‘fileName’]=$return[‘keyHash’].’.cache’; return $return; } /** * Sets a value in the cache for a certain key. * @param String $key * @param Mixed $value * @param String $expireTime * @return Boolean - indicating if the key was correctly saved in the cache */ public function set($key, $value, $expireTime=0) { // CHECK INPUTS // if key is not set if (!$key) return false; // do not store ‘null’ values if ($value===null) return false; // FILE AND DIRECTORY MANAGEMENT $params=$this->getFileDetails($key); // attempt to create the directory chain if (!Dir::create($params[‘fileLocation’])) return false; // DETERMINE THE EXPIRE TIMESTAMP if (is_numeric($expireTime) and $expireTime>0) { $expireTimestamp=TIMESTAMP+$expireTime; } else { switch (substr($expireTime, -1)) { case ‘s’: $expireTimestamp=TIMESTAMP+$expireTime;break; case ‘m’: $expireTimestamp=TIMESTAMP+$expireTime*60;break; case ‘h’: $expireTimestamp=TIMESTAMP+$expireTime*3600;break; case ‘d’: $expireTimestamp=TIMESTAMP+$expireTime*86400;break; default: $expireTimestamp=0; } } if (!$expireTimestamp) $expireTimestamp = TIMESTAMP + $this->defaultExpireTime; // FILE CONTENT $fileContent =$expire Timestamp .serialize($value) ; // WRITE THE CACHE FILE return File::create($params[‘fileLocation’].$params[‘fileName’], $fileContent); } /** * Gets a value stored in the cache for a certain key. * @param String $key * @return Mixed - the stored value or null if the key was not found */ public function get($key) { // CHECK INPUTS if (!$key) return null; // CHECK THE FILE // get file params $params=$this->getFileDetails($key); // check the file if (!file_exists($params[‘fileLocation’] .$params[‘fileName’]) or !is_readable($params [‘fileLocation’].$params[‘fileName’])) return null; // READ THE FILE$fc=File::getContents($params[‘fileLocation’].$params[‘fileName’]); // get and check expiration time $expirationTimestamp =substr ($fc, 0, 10); if ($expirationTimestamp<TIMESTAMP) { // delete the expired cache from disk $this->delete($key); return null; } // get contents, unserialize it and return it $valueSer=substr($fc, 10); $value=@unserialize($valueSer); if ($valu e===false) return null; else return $value; } /** * Deletes the value stored in the cache for a certain key. * @param Mixed $key - if it is an array - deletes all those keys; if it is a string - deleted only that key * @return Boolean - indicating if the key was correctly deleted in the cache */ public function delete($key) { // CHECK INPUTS if (!$key) return true; // CHECK THE FILE $return=1; // A LIST OF KEYS TO BE DELETED if (is_array($key)) { foreach($key as $k) { // get file params $params=$this->getFileDetails($k); // check the file if (!file_exists($params[‘fileLocation’].$params[‘fileName’])) continue; // delete the file $return*=File::delete($params[‘fileLocation’].$params[‘fileName’]); } } // ONLY ONE KEY else { // get file params $params=$this- >getFileDetails($key); // check the file if (!file_exists($params[‘fileLocation’].$params[‘fileName’])) return true; // delete the file $return=File::delete($params[‘fileLocation’].$params[‘fileName’]); } return (Bool)$return; } /** * Deletes the whole cache content. * @return Boolean - indicating if the cache was completely destroyed * @see EngineCacheBaseInterface::flush() */ public function flush() { return Dir::delete($this->cachePath); } /** * Returns an associative array of details for a certain key: the file location, the expire timestamp * @return Array */ public function getInfo($key) { $return=array(); // associate the key $return[‘key’]=$key; // get more details $params=$this->getFileDetails($key); $fullFileName=$params[‘fileLocation’].$params[‘fileName’]; // CHECK IF THE FILE EXISTS if (!file_exists($fullFileName) or !is_readable($fullFileName)) { $return[‘fileExists’]=false; } else { // associate some more keys $return[‘fileExists’]=true; $return[‘keyHash’]=$params[‘keyHash’]; $return[‘fileLocation’]=$params[‘fileLocation’]; $return[‘fileName’]=$params[‘fileName’]; $return[‘fileSize’]=filesize($fullFileName); // get expire time $fc=File::getContents($fullFileName); $return[‘expireTimestamp’]=substr($fc, 0, 10); $return[‘expireTimestampReadable’]=date(TIMESTAMP_FULL_FORMAT, $return[‘expireTimestamp’]); // get the value $return [‘cachedValue’] =unserialize (substr($fc, 10)); } return $return; } } <?php namespace EnginePlugins; /** * The class is used for registering a new plugin. It is extended in a class which is automatically * executed. * @author Gabriel */ abstract class RegisterAbstract { /** * The list of observers for a registered plugin. * @var Array - associative array of [triggerName][index][EnginePluginsObserver object] */ protected $observers=array(); /** * The constructor will register the current plugin. */ public function __construct() { $this->register(); } /** * Stores a new observer for this plugin (the method is called from the defined method register() * in the concrete classes. * @param String $triggerName - the trigger name * @param EnginePluginsObserver $obs - the observer object * @throws Exception - if the triger name is not correct */ protected function addObserver($triggerName, EnginePluginsObserver $obs) { // check trigger name if (!$triggerName) { throw new Exception(‘The trigger name was not set in ‘.get_called_class().’::’.__FUNCTION__.”.”); } $this->observers[$triggerName][] = $obs; } /** * The method will add new observers to the current plugin (using the addObserver() method. */ abstract protected function register(); /** * Returns the list of observers for the current * @return multitype: */ public function getObservers() { return $this->observers; } } <?php namespace AppEntityMatch; /** * The class manages the matching of suppliers * @author Gabriel */ class Supplier extends AppEntityMatchBaseAbstract { /** * The export fields for suppliers. * @var Array */ protected $exportFields = array(‘alias’, ‘company’); /** * Extra filters - deleted and duplicated suppliers are not allwed. * @var String */ protected $matchingFilteringSQL = ‘AND ent.deleted=0 AND ent.idRealSupplier=0’; /** * The class name which will instantiate the Entity - used for primaryKey search. * @var String */ protected $entityClassName = ‘EntitySupplier’; /** * (non-PHPdoc) * @see AppEntityMatchBaseAbstract::setTableName() */ protected function setTableName() { global $DBTSuppliers; $this->tableName = $DBTSuppliers; } /** * Sets a search by supplier alias. * @param String $value - the supplier alias. * @param Boolean $useWildcard - uses wildcard for this search or not. */ public function setAlias($value, $useWildcard=true) { $this->setSearchCriterion(‘alias’, $value, $useWildcard); } /** * Sets a search by supplier company name. * @param String $value - the supplier company name. * @param Boolean $useWildcard - uses wildcard for this search or not. */ public function setCompany($value, $useWildcard=true) { $this- >setSearchCriterion(‘company’, $value, $useWildcard); } /** * Sets a search by supplier fiscal code. * @param String $value - the supplier fiscal code. */ public function setFiscalCode($value) { $this->setSearchCriterion(‘fiscalCode’, $value, false); } /** * Searches a supplier by its code. * @param String $value * @param String $codeName - indicate the type of code (iata, tktCode, etc) */ public function setCode($value, $codeName) { // check the code name global $CFG; if (!$CFG[‘travel’][‘standardCodes’][$codeName]) { throw new Exception(“The supplier code `{$codeName}` is not valid - you can only use: “.implode(‘, ‘, array_keys($CFG[‘travel’][‘standardCodes’]))); } // add the search criterion $this->setSearchCriterion(‘code’, $value, false, array(‘codeName’=>$codeName)); } /** * Searches a supplier by the matching manually set in the external reservations system configs. * @param String $name - the supplier name * @param Int $idExternalResSystem - the external system */ public function setExtResSysName($name, $idExternalResSystem) { $this->setSearchCriterion(‘extResSys’, $name, false, array(‘idExtResSystem’=>$idExternalResSystem)); } /** * This method does a special search for supplier code (for the rest of the criteria, it uses the parent call. * @see AppEntityMatchBaseAbstract::searchRecords() */ protected function dispatchSearchRecords($field, $value, $useWildcard, Array $options=array()) { switch ($field) { case ‘code’: return $this->searchRecords_code($value, $options); break; case ‘extResSys’: return $this->searchRecords_extResSys($value, $options); break; default: return parent::dispatchSearchRecords($field, $value, $useWildcard, $options); } } /** * Searches a supplier by its code. * @param String $value - the supplier code * @param Array $options - stores the code name used */ private function searchRecords_code($value, Array $options) { global $DBTSupplierCodes; $db = DB::getInstance(); // RUN SQL $matchSupplierCodeSQL = “ SELECT “.$this->getSelectingFieldsSQL().” FROM `$DBTSupplierCodes` AS sc, `{$this->tableName}` AS ent WHERE sc.`code`=? AND sc.`value`=? AND `ent`.`id`=`sc`.`idSupplier` {$this->matchingFilteringSQL} “; $matchSupplierCodeEx = $db->Execute($matchSupplierCodeSQL, array($options[‘codeName’], $value)); if (!$matchSupplierCodeEx) { writeLog(“Could not match supplier by their code.”, ‘events’, 9); throw new Exception(‘Could not match supplier by their code.’); } // STORE RESULTS $return = array(); foreach($matchSupplierCodeEx as $supp) { $return[$supp[‘id’]] = $supp; } return $return; } /** * Searches a supplier by its matching in the external reservation systems. * @param unknown $valuem * @param array $options */ private function searchRecords_extResSys($value, Array $options) { global $DBTImportRes_suppliersAssociations; $db = DB::getInstance(); // SEARCH IN THE DB $searchSupplierSQL=”SELECT tinaSupplierId FROM `$DBTImportRes_suppliersAssociations` WHERE systemSupplierId=? AND systemId=?”; $searchSupplierEx=$db->Execute($searchSupplierSQL, array($value, $options[‘idExtResSystem’])); if (!$searchSupplierEx) { writeLog(“Could not match supplier by the external reservation systems code.”, ‘events’, 9); throw new Exception(‘Could not match supplier by the external reservation systems code.’); } // RETURN THE RESULT $supp=$searchSupplierEx->FetchRow(); $return = array(); if ($supp[‘tinaSupplierId’]) { $return=$this->searchRecord_primaryKey($supp[‘tinaSupplierId’]); } return $return; } } <?php namespace AppConfig; abstract class XmlBasicAbstract extends BaseAbstract { /** * Stores the configuration file (relative to the “files/config/” dir). For config files stored * inside subdirectories, the subdirectory is included (Ex: services/servicesList.xml). * @var String */ protected $fileName=null; /** * The filename with its full path. * @var String */ protected $fileNameWithPath=null; /** * (non-PHPdoc) * @see AppConfigBaseAbstract::constructInit() */ protected function constructInit() { // check if the file name is okay if (!$this->fileName) { throw new Exception(‘You did not set the `fileName` attribute for the class `’.get_called_class().’`.’); } // set the $this->fileNameWithPath=MODULE_REL_PATH . FILEPATH_APPCONFIGS . $this->fileName; } /** * Sets a reference to the current data in session so it can be stored during session lifetime. * @see AppConfigBaseAbstract::constructAdmin() */ protected function constructAdmin() { global $S; $className =get_called_ class(); // if items list and changed flag are set in session - they are copied into class attributes if $return[‘fileLocation’]=$this->cachePath.$keyDir.’/’; $return[‘fileName’]=$return[‘keyHash’].’.cache’; return $return; } /** * Sets a value in the cache for a certain key. * @param String $key * @param Mixed $value * @param String $expireTime * @return Boolean - indicating if the key was correctly saved in the cache */ public function set($key, $value, $expireTime=0) { // CHECK INPUTS // if key is not set if (!$key) return false; // do not store ‘null’ values if ($value===null) return false; // FILE AND DIRECTORY MANAGEMENT $params=$this->getFileDetails($key); // attempt to create the directory chain if (!Dir::create($params[‘fileLocation’])) return false; // DETERMINE THE EXPIRE TIMESTAMP if (is_numeric($expireTime) and $expireTime>0) { $expireTimestamp=TIMESTAMP+$expireTime; } else { switch (substr($expireTime, -1)) { case ‘s’: $expireTimestamp=TIMESTAMP+$expireTime;break; case ‘m’: $expireTimestamp=TIMESTAMP+$expireTime*60;break; case ‘h’: $expireTimestamp=TIMESTAMP+$expireTime*3600;break; case ‘d’: $expireTimestamp=TIMESTAMP+$expireTime*86400;break; default: $expireTimestamp=0; } } if (!$expireTimestamp) $expireTimestamp = TIMESTAMP + $this->defaultExpireTime; // FILE CONTENT $fileContent =$expire Timestamp .serialize($value) ; // WRITE THE CACHE FILE return File::create($params[‘fileLocation’].$params[‘fileName’], $fileContent); } /** * Gets a value stored in the cache for a certain key. * @param String $key * @return Mixed - the stored value or null if the key was not found */ public function get($key) { // CHECK INPUTS if (!$key) return null; // CHECK THE FILE // get file params $params=$this->getFileDetails($key); // check the file if (!file_exists($params[‘fileLocation’] .$params[‘fileName’]) or !is_readable($params [‘fileLocation’].$params[‘fileName’])) return null; // READ THE FILE$fc=File::getContents($params[‘fileLocation’].$params[‘fileName’]); // get and check expiration time $expirationTimestamp =substr ($fc, 0, 10); if ($expirationTimestamp<TIMESTAMP) { // delete the expired cache from disk $this->delete($key); return null; } // get contents, unserialize it and return it $valueSer=substr($fc, 10); $value=@unserialize($valueSer); if ($valu e===false) return null; else return $value; } /** * Deletes the value stored in the cache for a certain key. * @param Mixed $key - if it is an array - deletes all those keys; if it is a string - deleted only that key * @return Boolean - indicating if the key was correctly deleted in the cache */ public function delete($key) { // CHECK INPUTS if (!$key) return true; // CHECK THE FILE $return=1; // A LIST OF KEYS TO BE DELETED if (is_array($key)) { foreach($key as $k) { // get file params $params=$this->getFileDetails($k); // check the file if (!file_exists($params[‘fileLocation’].$params[‘fileName’])) continue; // delete the file $return*=File::delete($params[‘fileLocation’].$params[‘fileName’]); } } // ONLY ONE KEY else { // get file params $params=$this- >getFileDetails($key); // check the file if (!file_exists($params[‘fileLocation’].$params[‘fileName’])) return true; // delete the file $return=File::delete($params[‘fileLocation’].$params[‘fileName’]); } return (Bool)$return; } /** * Deletes the whole cache content. * @return Boolean - indicating if the cache was completely destroyed * @see EngineCacheBaseInterface::flush() */ public function flush() { return Dir::delete($this->cachePath); } /** * Returns an associative array of details for a certain key: the file location, the expire timestamp * @return Array */ public function getInfo($key) { $return=array(); // associate the key $return[‘key’]=$key; // get more details $params=$this->getFileDetails($key); $fullFileName=$params[‘fileLocation’].$params[‘fileName’]; // CHECK IF THE FILE EXISTS if (!file_exists($fullFileName) or !is_readable($fullFileName)) { $return[‘fileExists’]=false; } else { // associate some more keys $return[‘fileExists’]=true; $return[‘keyHash’]=$params[‘keyHash’]; $return[‘fileLocation’]=$params[‘fileLocation’]; $return[‘fileName’]=$params[‘fileName’]; $return[‘fileSize’]=filesize($fullFileName); // get expire time $fc=File::getContents($fullFileName); $return[‘expireTimestamp’]=substr($fc, 0, 10); $return[‘expireTimestampReadable’]=date(TIMESTAMP_FULL_FORMAT, $return[‘expireTimestamp’]); // get the value $return [‘cachedValue’] =unserialize (substr($fc, 10)); } return $return; } } <?php namespace EnginePlugins; /** * The class is used for registering a new plugin. It is extended in a class which is automatically * executed. * @author Gabriel */ abstract class RegisterAbstract { /** * The list of observers for a registered plugin. * @var Array - associative array of [triggerName][index][EnginePluginsObserver object] */ protected $observers=array(); /** * The constructor will register the current plugin. */ public function __construct() { $this->register(); } /** * Stores a new observer for this plugin (the method is called from the defined method register() * in the concrete classes. * @param String $triggerName - the trigger name * @param EnginePluginsObserver $obs - the observer object * @throws Exception - if the triger name is not correct */ protected function addObserver($triggerName, EnginePluginsObserver $obs) { // check trigger name if (!$triggerName) { throw new Exception(‘The trigger name was not set in ‘.get_called_class().’::’.__FUNCTION__.”.”); } $this->observers[$triggerName][] = $obs; } /** * The method will add new observers to the current plugin (using the addObserver() method. */ abstract protected function register(); /** * Returns the list of observers for the current * @return multitype: */ public function getObservers() { return $this->observers; } } <?php namespace AppEntityMatch; /** * The class manages the matching of suppliers * @author Gabriel */ class Supplier extends AppEntityMatchBaseAbstract { /** * The export fields for suppliers. * @var Array */ protected $exportFields = array(‘alias’, ‘company’); /** * Extra filters - deleted and duplicated suppliers are not allwed. * @var String */ protected $matchingFilteringSQL = ‘AND ent.deleted=0 AND ent.idRealSupplier=0’; /** * The class name which will instantiate the Entity - used for primaryKey search. * @var String */ protected $entityClassName = ‘EntitySupplier’; /** * (non-PHPdoc) * @see AppEntityMatchBaseAbstract::setTableName() */ protected function setTableName() { global $DBTSuppliers; $this->tableName = $DBTSuppliers; } /** * Sets a search by supplier alias. * @param String $value - the supplier alias. * @param Boolean $useWildcard - uses wildcard for this search or not. */ public function setAlias($value, $useWildcard=true) { $this->setSearchCriterion(‘alias’, $value, $useWildcard); } /** * Sets a search by supplier company name. * @param String $value - the supplier company name. * @param Boolean $useWildcard - uses wildcard for this search or not. */ public function setCompany($value, $useWildcard=true) { $this- >setSearchCriterion(‘company’, $value, $useWildcard); } /** * Sets a search by supplier fiscal code. * @param String $value - the supplier fiscal code. */ public function setFiscalCode($value) { $this->setSearchCriterion(‘fiscalCode’, $value, false); } /** * Searches a supplier by its code. * @param String $value * @param String $codeName - indicate the type of code (iata, tktCode, etc) */ public function setCode($value, $codeName) { // check the code name global $CFG; if (!$CFG[‘travel’][‘standardCodes’][$codeName]) { throw new Exception(“The supplier code `{$codeName}` is not valid - you can only use: “.implode(‘, ‘, array_keys($CFG[‘travel’][‘standardCodes’]))); } // add the search criterion $this->setSearchCriterion(‘code’, $value, false, array(‘codeName’=>$codeName)); } /** * Searches a supplier by the matching manually set in the external reservations system configs. * @param String $name - the supplier name * @param Int $idExternalResSystem - the external system */ public function setExtResSysName($name, $idExternalResSystem) { $this->setSearchCriterion(‘extResSys’, $name, false, array(‘idExtResSystem’=>$idExternalResSystem)); } /** * This method does a special search for supplier code (for the rest of the criteria, it uses the parent call. * @see AppEntityMatchBaseAbstract::searchRecords() */ protected function dispatchSearchRecords($field, $value, $useWildcard, Array $options=array()) { switch ($field) { case ‘code’: return $this->searchRecords_code($value, $options); break; case ‘extResSys’: return $this->searchRecords_extResSys($value, $options); break; default: return parent::dispatchSearchRecords($field, $value, $useWildcard, $options); } } /** * Searches a supplier by its code. * @param String $value - the supplier code * @param Array $options - stores the code name used */ private function searchRecords_code($value, Array $options) { global $DBTSupplierCodes; $db = DB::getInstance(); // RUN SQL $matchSupplierCodeSQL = “ SELECT “.$this->getSelectingFieldsSQL().” FROM `$DBTSupplierCodes` AS sc, `{$this->tableName}` AS ent WHERE sc.`code`=? AND sc.`value`=? AND `ent`.`id`=`sc`.`idSupplier` {$this->matchingFilteringSQL} “; $matchSupplierCodeEx = $db->Execute($matchSupplierCodeSQL, array($options[‘codeName’], $value)); if (!$matchSupplierCodeEx) { writeLog(“Could not match supplier by their code.”, ‘events’, 9); throw new Exception(‘Could not match supplier by their code.’); } // STORE RESULTS $return = array(); foreach($matchSupplierCodeEx as $supp) { $return[$supp[‘id’]] = $supp; } return $return; } /** * Searches a supplier by its matching in the external reservation systems. * @param unknown $valuem * @param array $options */ private function searchRecords_extResSys($value, Array $options) { global $DBTImportRes_suppliersAssociations; $db = DB::getInstance(); // SEARCH IN THE DB $searchSupplierSQL=”SELECT tinaSupplierId FROM `$DBTImportRes_suppliersAssociations` WHERE systemSupplierId=? AND systemId=?”; $searchSupplierEx=$db->Execute($searchSupplierSQL, array($value, $options[‘idExtResSystem’])); if (!$searchSupplierEx) { writeLog(“Could not match supplier by the external reservation systems code.”, ‘events’, 9); throw new Exception(‘Could not match supplier by the external reservation systems code.’); } // RETURN THE RESULT $supp=$searchSupplierEx->FetchRow(); $return = array(); if ($supp[‘tinaSupplierId’]) { $return=$this->searchRecord_primaryKey($supp[‘tinaSupplierId’]); } return $return; } } <?php namespace AppConfig; abstract class XmlBasicAbstract extends BaseAbstract { /** * Stores the configuration file (relative to the “files/config/” dir). For config files stored * inside subdirectories, the subdirectory is included (Ex: services/servicesList.xml). * @var String */ protected $fileName=null; /** * The filename with its full path. * @var String */ protected $fileNameWithPath=null; /** * (non-PHPdoc) * @see AppConfigBaseAbstract::constructInit() */ protected function constructInit() { // check if the file name is okay if (!$this->fileName) { throw new Exception(‘You did not set the `fileName` attribute for the class `’.get_called_class().’`.’); } // set the $this->fileNameWithPath=MODULE_REL_PATH . FILEPATH_APPCONFIGS . $this->fileName; } /** * Sets a reference to the current data in session so it can be stored during session lifetime. * @see AppConfigBaseAbstract::constructAdmin() */ protected function constructAdmin() { global $S; $className =get_called_ class(); // if items list and changed flag are set in session - they are copied into class attributes if (isset($S[‘admin’][‘configApp’][$className][‘itemsList’])) { $this->itemsList=$S [‘admin’] [‘configApp’] [$className ][‘itemsList’]; } if (isset($S[‘admin’][‘configApp’][$className][‘changedFlag’])) { $this->changedFlag=$S[‘admin’][‘configApp’][$className][‘changedFlag’]; } // these references will keep the data over different page loads $S[‘admin’] [‘configApp’] [$className] [‘itemsList’] =&$this->itemsList; $S[‘admin’][‘configApp’][$className][‘changedFlag’]=&$this->changedFlag; } /** * (non-PHPdoc) * @see AppConfigBaseAbstract::getAll_rawData() */ protected function getAll_rawData() { // return the output in case the file does not exist if (!file_exists($this- >fileNameWithPath)) return $this->getAll_rawData_fileNotExists(); // the file exists - load the content as XML (and check it) $xml=@simplexml_load_file($this->fileNameWithPath); if (!($xml instanceof SimpleXMLElement)) throw new Exception(‘The config file is not a well formed XML (class = ‘.get_called_class().’ ; file = ‘.$this- >fileNameWithPath.’).’); // return the array from the parsed XML content return $this->getAll _rawData _extract DataFromFile($xml); } /** * Sets the default output in case the XML file is missing. * @return Array */ protected function getAll_rawData_fileNotExists() { return array(); } /** * Returns the extracted data after the XML content is parsed. * @param SimpleXMLElement $xml - the parsed xml * @return Array - the items list or whatever output is needed. */ abstract protected function getAll_ rawData _extractData FromFile ( Simple XMLElement $xml); /** * Sets an element in the internal attribute $this->itemsList. The method can be called multiple * times and they will overwrite the older values. * @param String $var - or the name of one key (a string); * @param Mixed $value - the value of the key; * @throws Exception - if input is bad */ public function set($var, $value) { // check constructor type if ($this->constructType!=’admin’) throw new Exception(“You can use the method `”.get _called_ class().’::’.__FUNCTION__.”` only if the constructor type is `admin`.”); // check inputs if (!is_string($var)) throw new Exception(“You did not set() a correct name for the key.”); // (re)set one key $this->itemsList[$var]=$value; // update the changed flag $this->changedFlag=true; } /** * Sets all the elements in the internal attribute $this- >itemsList (rewrites any old data * already stored). The parameter is an associative array and the keys will be * stored one by one. * @param Array $vars - associative array of keys * @throws Exception - if input is bad */ public function setAll($vars) { // check constructor type if ($this->constructType!=’admin’) throw new Exception(“You can use the method `”.get_c alled_class().’::’.__ FUNCTION__.”` only if the constructor type is `admin`.”); // check inputs if (!is_array($vars)) throw new Exception(“You did not setAll() a correct list of elements - the parameter is not an array.”); // (re)set a list of keys $this->itemsList=$vars; // update the changed flag $this->changed Flag=true; } /** * (non-PHPdoc) * @see AppConfigBaseAbstract::save_write_do() */ protected function save_write_do() { // GETS THE SIMPLEXML OBJECT TO BE WRITTEN ON DISK gets the simplexml object $xmlObj=$this->save_write_do _getXml(); // checks that the object is correct (it is a valid simplexml object) if (!($xmlObj instanceof SimpleXMLElement)) throw new Exception(‘The output of the method `’.get_ called_class() .’::save_write_do_getXml` must be a `SimpleXMLElement` object.’); // (RE)WRITE FILE ON DISK // check if the file is writeable $fileChmod=false; if (file_exists($this->fileNameWithPath)) { if (!is_writeable($this->fileNameWithPath)) $this- >addErrorMessage(‘The config file exists but it is not writeable.’); } else { $fileChmod=true; } // (OVER)WRITE THE FILE CONTENT - if (!file_put_contents($this->fileNameWithPath, $xmlObj->asXml())) { $this->addErrorMessage(‘The config file could not be (over)written.’); } // if the file did not exist - chmod it if ($fileChmod) { if (!chmod($this->fileNameWithPath, 0777)) { $this->addErrorMessage(‘The config file could not have its acess rights updated.’); } } } /** * Returns the SimpleXML object to be written on disk. * @return SimpleXMLElement */ abstract protected function save_write_do_getXml(); } <?php namespace EngineCache; /** * The class is used to manage the cache stored on disk. * @author Gabriel Grosu */ class Disk implements EngineCacheBaseInterface { /** * The full location where the cache files are stored. * @var String */ protected $cachePath=’’; /** * The prefix key is used to avoid the reusing of keys if the application was updated. * @var String */ protected $keyPrefix=’’; /** * The default expiration time limit, if no param is specified when calling set() * @var int */ protected $defaultExpireTime = 2592000; // 2592000 = one month /** * The class constructor. */ public function __construct() { global $CFG; // realpath is used because cwd may change in __destructor(s) - AppEntityCache caches the entity object in destructors. $this->cachePath=realpath(MODULE_REL_PATH.$CFG[‘paths’][‘files’]).’/’.$CFG[‘cache’][‘disk’][‘location’]; // sets the mem cached key prefix $this->keyPrefix=$CFG[‘global’][‘application’][‘versionBuild’]; return true; } /** * Returns some associative array of data determined from the key * @param Array $key */ private function getFileDetails($key) { $return=array(); // rewrite the key $key=$this->keyPrefix.’-’.$key; // the key hash $return[‘keyHash’]=md5($key); // the subdir for the current key $keyDir=substr($return[‘keyHash’], 0, 2); // the full file location $return[‘fileLocation’]=$this->cachePath.$keyDir.’/’; $return[‘fileName’]=$return[‘keyHash’].’.cache’; return $return; } /** * Sets a value in the cache for a certain key. * @param String $key * @param Mixed $value * @param String $expireTime * @return Boolean - indicating if the key was correctly saved in the cache */ public function set($key, $value, $expireTime=0) { // CHECK INPUTS // if key is not set if (!$key) return false; // do not store ‘null’ values if ($value===null) return false; // FILE AND DIRECTORY MANAGEMENT $params=$this->getFileDetails($key); // attempt to create the directory chain if (!Dir::create($params[‘fileLocation’])) return false; // DETERMINE THE EXPIRE TIMESTAMP if (is_numeric($expireTime) and $expireTime>0) { $expireTimestamp=TIMESTAMP+$expireTime; } else { switch (substr($expireTime, -1)) { case ‘s’: $expireTimestamp=TIMESTAMP+$expireTime;break; case ‘m’: $expireTimestamp=TIMESTAMP+$expireTime*60;break; case ‘h’: $expireTimestamp=TIMESTAMP+$expireTime*3600;break; case ‘d’: $expireTimestamp=TIMESTAMP+$expireTime*86400;break; default: $expireTimestamp=0; } } if (!$expireTimestamp) $expireTimestamp = TIMESTAMP + $this->defaultExpireTime; // FILE CONTENT $fileContent =$expire Timestamp .serialize($value) ; // WRITE THE CACHE FILE return File::create($params[‘fileLocation’].$params[‘fileName’], $fileContent); } /** * Gets a value stored in the cache for a certain key. * @param String $key * @return Mixed - the stored value or null if the key was not found */ public function get($key) { // CHECK INPUTS if (!$key) return null; // CHECK THE FILE // get file params $params=$this->getFileDetails($key); // check the file if (!file_exists($params[‘fileLocation’] .$params[‘fileName’]) or !is_readable($params [‘fileLocation’].$params[‘fileName’])) return null; // READ THE FILE$fc=File::getContents($params[‘fileLocation’].$params[‘fileName’]); // get and check expiration time $expirationTimestamp =substr ($fc, 0, 10); if ($expirationTimestamp<TIMESTAMP) { // delete the expired cache from disk $this->delete($key); return null; } // get contents, unserialize it and return it $valueSer=substr($fc, 10); $value=@unserialize($valueSer); if ($valu e===false) return null; else return $value; } /** * Deletes the value stored in the cache for a certain key. * @param Mixed $key - if it is an array - deletes all those keys; if it is a string - deleted only that key * @return Boolean - indicating if the key was correctly deleted in the cache */ public function delete($key) { // CHECK INPUTS if (!$key) return true; // CHECK THE FILE $return=1; // A LIST OF KEYS TO BE DELETED if (is_array($key)) { foreach($key as $k) { // get file params $params=$this->getFileDetails($k); // check the file if (!file_exists($params[‘fileLocation’].$params[‘fileN @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ Business critical end-to-end solutions