*/ class Mooses_AbstractMongo extends Mooses_Mongodb_Mongo_Document { const ASC = "ASC"; protected static $_db; protected static $_collection; protected static $_instance; protected $calledClass; protected $_classMethods = array(); protected static $_order = array(); protected $_queryConditions = array(); protected $_fields = array(); protected $_sorterArray = array(); protected $_sorterAttribute = ""; protected $_sorterDate = false; protected $_sorterOrder = self::ASC; protected $_forceNoCachePaginatedCollection = false; public $loadKey = array(); protected $_dataUpdate = array(); public function __construct($_data = []) { $this->_setCollectionAndDatabase(); parent::__construct($_data, array()); $this->calledClass = get_called_class(); self::$_instance = $this; return $this; } private function _setCollectionAndDatabase(){ $_mongoInformations = $this->_retrieveTableName(); self::$_db = $_mongoInformations['db']; static::$_db = $_mongoInformations['db']; self::$_collection = $_mongoInformations['collection']; static::$_collection = $_mongoInformations['collection']; $this->_classMethods = get_class_methods($this); } public static function getInstance() { if (self::$_instance === NULL || self::$_instance->calledClass !== get_called_class()) { $_className = get_called_class(); self::$_instance = new $_className(); } return self::$_instance; } protected function _retrieveTableName() { $_return = array(); $annotations = new ReflectionClass($this); $_tableSuffix = NULL; $_tablePrefix = "re_"; $_databaseAnnotated = $this->_parseDocComment($annotations->getDocComment(), "@Db"); $_collectionAnnotated = $this->_parseDocComment($annotations->getDocComment(), "@Collection"); $_return['collection'] = (stristr($_collectionAnnotated, $_tableSuffix)) ? $_collectionAnnotated : $_tablePrefix . $_collectionAnnotated . $_tableSuffix; $_return['db'] = $_databaseAnnotated; return $_return; } private function _parseDocComment($str, $tag = '') { if (empty($tag)) { return $str; } $matches = array(); preg_match("/" . $tag . ":(.*)(\\r\\n|\\r|\\n)/U", $str, $matches); if (isset($matches[1])) { return trim($matches[1]); } return ''; } protected function _convertMongoCursor($_mongoCursor, $_forceArray = false, $_order = false){ $_calledClass = $_mongoCursor->getDocumentClass(); if($_mongoCursor->count() == 0){ return (($_forceArray) ? array() : false); } elseif($_mongoCursor->count() == 1){ $_object = (($_forceArray) ? array(new $_calledClass($_mongoCursor->next())) : new $_calledClass($_mongoCursor->next())); $_object->loadKey = $this->loadKey; return $_object; } else { $_arrayResults = array(); while($_result = $_mongoCursor->next()){ $_object = new $_calledClass($_result); $_object->loadKey = $this->_loadKey; array_push($_arrayResults, $_object); } if($_order !== false && is_array($_order)){ $this->_sorterAttribute = $_order[0]; $this->_sorterOrder = $_order[1]; $this->_sorterDate = (($_order[2] === true) ? true : false); $_orderer = function($a, $b){ if($this->_sorterDate === false) { if (strcasecmp((string)$a->getData($this->_sorterAttribute), (string)$b->getData($this->_sorterAttribute)) > 0) { return (($this->_sorterOrder == self::ASC) ? 1 : -1); } else { return (($this->_sorterOrder == self::ASC) ? -1 : 1); } } else { if(is_a($a, "Default_Model_Mapper_Utenti")) { $_datiA = $a->getAllData(); } else { $_datiA = $a->getData(); } if(is_array($_datiA[$this->_sorterAttribute]) && isset($_datiA[$this->_sorterAttribute]['date'])) { $_dataA = DateTime::createFromFormat("Y-m-d H:i:s", substr($_datiA[$this->_sorterAttribute]['date'], 0, 19)); } else { $_dataA = DateTime::createFromFormat("Y-m-d H:i:s", substr($_datiA[$this->_sorterAttribute], 0, 19)); } if(is_a($b, "Default_Model_Mapper_Utenti")) { $_datiB = $b->getAllData(); } else { $_datiB = $b->getData(); } if(is_array($_datiB[$this->_sorterAttribute]) && isset($_datiB[$this->_sorterAttribute]['date'])) { $_dataB = DateTime::createFromFormat("Y-m-d H:i:s", substr($_datiB[$this->_sorterAttribute]['date'], 0, 19)); } else { $_dataB = DateTime::createFromFormat("Y-m-d H:i:s", substr($_datiB[$this->_sorterAttribute], 0, 19)); } if($_dataA > $_dataB){ return (($this->_sorterOrder == self::ASC) ? 1 : -1); } else { return (($this->_sorterOrder == self::ASC) ? -1 : 1); } } }; usort($_arrayResults, $_orderer); } return $_arrayResults; } } public function __callStatic($name, $arguments) { if(get_called_class() != get_class(self::$_instance)){ $_mongoInformations = $this->_retrieveTableName(); self::$_db = $_mongoInformations['db']; static::$_db = $_mongoInformations['db']; self::$_collection = $_mongoInformations['collection']; static::$_collection = $_mongoInformations['collection']; } } public function __call($methodName, $params = null) { if(get_called_class() != get_class(self::$_instance)){ $this->_setCollectionAndDatabase(); } $_methodsAllowed = array("setData", "setProperty", "getData", "getProperty"); $methodPrefix = substr($methodName, 0, 3); $key = strtolower(substr($methodName, 3)); $_isUppercase = ctype_upper(substr($methodName, 3, 1)); if (in_array("___".$methodName, $_methodsAllowed) || in_array("___".$methodName, $this->_classMethods)) { return call_user_func_array(array($this, "___".$methodName), $params); } elseif ($methodPrefix == 'set' && count($params) == 1 && $_isUppercase) { $value = htmlspecialchars($params[0],ENT_QUOTES,"UTF-8"); return parent::setProperty($key, $value); } elseif ($methodPrefix == 'get') { return htmlspecialchars(parent::getProperty($key),ENT_QUOTES); } elseif (!in_array($methodName, array_flip(get_class_methods($this)))) { throw new Exception("Method \"" . $methodName . "\" doesn't exist in " . get_called_class(), 500); } } public static function addMongoRegexp(&$_value){ if(!is_array($_value) && stristr($_value, "/") != FALSE){ $_value = new MongoRegex($_value); } } protected function ___getCollection(){ $this->_queryConditions = array(); return $this; } protected function ___addFieldToFilter($_attributeName, $_value){ if(!is_array($_value) && stristr($_value, "/") != FALSE){ $_value = new MongoRegex($_value); } if(is_array($_value)){ array_walk_recursive($_value, array(get_called_class(), "addMongoRegexp")); $_condition = array(); foreach ($_value as $_operators => $_realValue) { $_condition[$_operators] = $_realValue; } } else { $_condition = $_value; } if(isset($this->_queryConditions[$_attributeName])){ $_alreadyExistingConditions = $this->_queryConditions[$_attributeName]; $_condition = array_merge($_alreadyExistingConditions, $_condition); } $this->_queryConditions[$_attributeName] = $_condition; return $this; } protected function ___setFieldToSelect($_fields = array()){ $_truesFiller = function(&$_value){$_value = true;}; $_keysFields = array_flip($_fields); array_walk_recursive($_keysFields, $_truesFiller); $this->_fields = $_keysFields; return $this; } protected function ___getCollectionData($_forceArray = true){ $_result = $this->fetchAll($this->_queryConditions, $this->_fields); if (count($this->_sorterArray) == 0) { return $this->_convertMongoCursor($_result, $_forceArray); } else { return $this->_convertMongoCursor($_result, $_forceArray, $this->_sorterArray); } } protected function ___getPaginatedCollectionData($_page = 1, $_itemsPerPage = 15){ return $this->___getCollectionData(true); // $_cacher = Mooses_Cacher::getInstance(strtolower("p_".str_replace("Default_Model_Mapper", "", get_called_class())), 3600); // $_idCache = preg_replace("/[^a-zA-Z0-9_]+/", "", "query_" . json_encode($this->_queryConditions)); // if($this->_forceNoCachePaginatedCollection === true || !$_arrayResults = $_cacher->load($_idCache)) { // $_result = $this->fetchAll($this->_queryConditions, $this->_fields); // if (count($this->_sorterArray) == 0) { // $_arrayResults = $this->_convertMongoCursor($_result, true); // } else { // $_arrayResults = $this->_convertMongoCursor($_result, true, $this->_sorterArray); // } // $_cacher->save($_arrayResults, $_idCache); // } // if(count($_arrayResults) > 0) { // $_paginatorAdapter = new Zend_Paginator_Adapter_Array($_arrayResults); // $_paginator = new Zend_Paginator($_paginatorAdapter); // $_paginator->setItemCountPerPage($_itemsPerPage)->setCurrentPageNumber($_page); // return $_paginator; // } else { // return false; // } } protected function ___setCollectionOrder($_sorterArray){ $this->_sorterArray = $_sorterArray; return $this; } protected function ___useCache($_useCache = true){ $this->_forceNoCachePaginatedCollection = !$_useCache; return $this; } protected function ___getData($_key = NULL, $_default = NULL, $_forceDateExtendedFormat = false){ if(is_null($_key)) { return parent::getAllData(); } else { if(parent::hasProperty($_key)) { $_value = parent::getProperty($_key); if (is_object($_value)) { if(isset($_value->date)) { $_valueDatetime = DateTime::createFromFormat("Y-m-d H:i:s", $_value->date); if(is_object($_valueDatetime) && $_forceDateExtendedFormat){ $_value = $_valueDatetime->format("d/m/Y H:i:s"); } elseif(is_object($_valueDatetime)) { $_value = $_valueDatetime->format("d/m/Y"); } else { $_value = $_value->date; } } else { $_value = $_value->getAllData(); } } return $_value; } else { return (($_default != NULL) ? $_default : NULL); } } } protected function ___setData($_key, $_value = NULL, $_forceCleanData = false){ if(is_array($_key)){ foreach($_key as $_chiave => $_value){ parent::setProperty($_chiave, $_value); $this->_dataUpdate[$_chiave] = $_value; } } else { if($_key == "birthdate" || is_a($_value, "DateTime")){ $_oldValue = $_value; $_value = new stdClass(); $_value->date = $_oldValue->format("Y-m-d H:i:s"); $_value->timezone_type = 3; $_value->timezone = "Europe/Rome"; } parent::setProperty($_key, $_value, $_forceCleanData); } $this->_dataUpdate[$_key] = $_value; return $this; } protected function ___load($_value, $_attributeName = NULL){ if(is_null($_attributeName)){ return parent::find($_value); } else { return parent::fetchOne(array($_attributeName => $_value)); } } protected function ___loadByAttribute($_attributeName = "", $_value = "", $_forceArray = false){ if(stristr($_value, "/") !== FALSE){ $_value = new MongoRegex($_value); } $this->loadKey = array($_attributeName => $_value); $_results = parent::fetchAll($this->loadKey); return $this->_convertMongoCursor($_results, $_forceArray); } public function ___save($entierDocument = false, $safe = true){ return parent::save($entierDocument, $safe); } public function deleteData($_safe = true, $onlyOne = true){ $mongoCollection = $this->_getMongoCollection(true); $this->preDelete(); if (!$this->isRootDocument()) { $result = $mongoCollection->update($this->loadKey, array('$unset' => array($this->getPathToDocument() => 1)), array('safe' => $_safe)); } else { $result = $mongoCollection->remove($this->loadKey, array('justOne' => $onlyOne, 'safe' => $_safe)); } return $result; } public function updateData(){ $_return = $this->update($this->loadKey, array('$set' => $this->_dataUpdate)); return $_return; } public function setUpdateCriteria($_array){ $this->loadKey = $_array; return $this; } public function flatten($array, $prefix = '') { $result = array(); foreach($array as $key=>$value) { if(is_array($value)) { $result = $result + $this->flatten($value, strtolower($prefix . $key . '_')); } else { $result[strtolower($prefix . $key)] = $value; } } return $result; } }