/** * Static factory to parse the @objectList annotation of a single property * @param $objObject * @param $strProperty * * @return class_orm_assignment_config * @throws class_orm_exception */ public static function getConfigForProperty($objObject, $strProperty) { $objReflection = new class_reflection($objObject); $arrPropertyParams = $objReflection->getAnnotationValueForProperty($strProperty, class_orm_base::STR_ANNOTATION_OBJECTLIST, class_reflection_enum::PARAMS()); $strTable = $objReflection->getAnnotationValueForProperty($strProperty, class_orm_base::STR_ANNOTATION_OBJECTLIST, class_reflection_enum::VALUES()); $arrTypeFilter = isset($arrPropertyParams["type"]) ? $arrPropertyParams["type"] : null; if (!isset($arrPropertyParams["source"]) || !isset($arrPropertyParams["target"]) || empty($strTable)) { throw new class_orm_exception("@objectList annoation for " . $strProperty . "@" . get_class($objObject) . " is malformed", class_orm_exception::$level_FATALERROR); } return new class_orm_assignment_config($strTable, $arrPropertyParams["source"], $arrPropertyParams["target"], $arrTypeFilter); }
/** * Clears the assignments of the current object, if given * * @return bool */ private function deleteAssignments() { $bitReturn = true; $objReflection = new class_reflection($this->getObjObject()); $objDB = class_carrier::getInstance()->getObjDB(); //get the mapped properties $arrProperties = $objReflection->getPropertiesWithAnnotation(class_orm_base::STR_ANNOTATION_OBJECTLIST, class_reflection_enum::PARAMS()); foreach ($arrProperties as $strPropertyName => $arrValues) { $objCfg = class_orm_assignment_config::getConfigForProperty($this->getObjObject(), $strPropertyName); $bitReturn = $bitReturn && $objDB->_pQuery("DELETE FROM " . $objDB->encloseTableName(_dbprefix_ . $objCfg->getStrTableName()) . " WHERE " . $objDB->encloseColumnName($objCfg->getStrSourceColumn()) . " = ? ", array($this->getObjObject()->getSystemid())); } return $bitReturn; }
/** * Injects the lazy loading objects for assignment properties into the current object * @return void */ private function initAssignmentProperties() { $objReflection = new class_reflection($this->getObjObject()); //get the mapped properties $arrProperties = $objReflection->getPropertiesWithAnnotation(class_orm_base::STR_ANNOTATION_OBJECTLIST, class_reflection_enum::PARAMS()); foreach ($arrProperties as $strPropertyName => $arrValues) { $objPropertyLazyLoader = new class_orm_assignment_array($this->getObjObject(), $strPropertyName, $this->getIntCombinedLogicalDeletionConfig()); $strSetter = $objReflection->getSetter($strPropertyName); if ($strSetter !== null) { call_user_func(array($this->getObjObject(), $strSetter), $objPropertyLazyLoader); } } }
/** * Searches a given annotation for a specified property. If given, the value is returned, otherwise (when not found) null is returned. * * @param string $strProperty * @param string $strAnnotation * @param class_reflection_enum $objEnum - whether to return annotation values or parameters, default is values * * @return null|string */ public function getAnnotationValueForProperty($strProperty, $strAnnotation, class_reflection_enum $objEnum = null) { if ($objEnum == null) { $objEnum = class_reflection_enum::VALUES(); } $arrProperties = $this->objReflectionClass->getProperties(); foreach ($arrProperties as $objOneProperty) { if ($objOneProperty->getName() == $strProperty) { $strFirstAnnotation = $this->searchFirstAnnotationInDoc($objOneProperty->getDocComment(), $strAnnotation); if ($objEnum->equals(class_reflection_enum::VALUES())) { $strFirstAnnotation = $strFirstAnnotation["values"][0]; } else { if ($objEnum->equals(class_reflection_enum::PARAMS())) { $strFirstAnnotation = $strFirstAnnotation["params"][0]; } } if ($strFirstAnnotation !== false) { return $strFirstAnnotation; } } } //check if there's a base-class -> inheritance $objBaseClass = $this->objReflectionClass->getParentClass(); if ($objBaseClass !== false) { $objBaseAnnotations = new class_reflection($objBaseClass->getName()); return $objBaseAnnotations->getAnnotationValueForProperty($strProperty, $strAnnotation, $objEnum); } return null; }
/** * @dataProvider additionProvider */ public function testGetAnnotationValueForPropertyParameter($a) { $objAnnotations = new class_reflection(new C()); $arrParams = $objAnnotations->getAnnotationValueForProperty("propertyB1", "@propertyTest", class_reflection_enum::PARAMS()); $this->assertCount(0, $arrParams); $arrParams = $objAnnotations->getAnnotationValueForProperty("propertyB1", "@propertyParamTest1", class_reflection_enum::PARAMS()); $this->assertCount(1, $arrParams); $this->assertArrayHasKey("param1", $arrParams); $arrParams = $objAnnotations->getAnnotationValueForProperty("propertyB1", "@propertyParamTest2", class_reflection_enum::PARAMS()); $this->assertCount(0, $arrParams); $arrParams = $objAnnotations->getAnnotationValueForProperty("propertyB1", "@propertyParamTest3", class_reflection_enum::PARAMS()); $this->assertCount(1, $arrParams); $this->assertArrayHasKey("param1", $arrParams); $arrParams = $objAnnotations->getAnnotationValueForProperty("propertyB1", "@propertyParamTest4", class_reflection_enum::PARAMS()); $this->assertCount(0, $arrParams); }
/** * Triggers the update sequence for assignment properties * @return bool */ private function updateAssignments() { $bitReturn = true; $objReflection = new class_reflection($this->getObjObject()); //get the mapped properties $arrProperties = $objReflection->getPropertiesWithAnnotation(class_orm_base::STR_ANNOTATION_OBJECTLIST, class_reflection_enum::PARAMS()); foreach ($arrProperties as $strPropertyName => $arrValues) { $objCfg = class_orm_assignment_config::getConfigForProperty($this->getObjObject(), $strPropertyName); //try to load the orm config of the arrayObject - if given $strGetter = $objReflection->getGetter($strPropertyName); $arrValues = null; if ($strGetter !== null) { $arrValues = call_user_func(array($this->getObjObject(), $strGetter)); } $objAssignmentDeleteHandling = $this->getIntCombinedLogicalDeletionConfig(); if ($arrValues != null && $arrValues instanceof class_orm_assignment_array) { $objAssignmentDeleteHandling = $arrValues->getObjDeletedHandling(); } //try to restore the object-set from the database using the same config as when initializing the object $objOldHandling = $this->getIntCombinedLogicalDeletionConfig(); $this->setObjHandleLogicalDeleted($objAssignmentDeleteHandling); $arrAssignmentsFromObject = $this->getAssignmentValuesFromObject($strPropertyName, $objCfg->getArrTypeFilter()); $arrAssignmentsFromDatabase = $this->getAssignmentsFromDatabase($strPropertyName); $this->setObjHandleLogicalDeleted($objOldHandling); //if the delete handling was set to excluded when loading the assignment, the logically deleted nodes should be merged with the values from db if ($objAssignmentDeleteHandling->equals(class_orm_deletedhandling_enum::EXCLUDED())) { $this->setObjHandleLogicalDeleted(class_orm_deletedhandling_enum::EXCLUSIVE()); $arrDeletedIds = $this->getAssignmentsFromDatabase($strPropertyName); $this->setObjHandleLogicalDeleted($objOldHandling); foreach ($arrDeletedIds as $strOneId) { if (!in_array($strOneId, $arrAssignmentsFromDatabase)) { $arrAssignmentsFromDatabase[] = $strOneId; } if (!in_array($strOneId, $arrAssignmentsFromObject)) { $arrAssignmentsFromObject[] = $strOneId; } } } sort($arrAssignmentsFromObject); sort($arrAssignmentsFromDatabase); //only do s.th. if the array differs $arrNewAssignments = array_diff($arrAssignmentsFromObject, $arrAssignmentsFromDatabase); $arrDeletedAssignments = array_diff($arrAssignmentsFromDatabase, $arrAssignmentsFromObject); //skip in case there's nothing to do if (count($arrNewAssignments) == 0 && count($arrDeletedAssignments) == 0) { continue; } $objDB = class_carrier::getInstance()->getObjDB(); $arrInserts = array(); foreach ($arrAssignmentsFromObject as $strOneTargetId) { $arrInserts[] = array($this->getObjObject()->getSystemid(), $strOneTargetId); } $bitReturn = $bitReturn && $objDB->_pQuery("DELETE FROM " . $objDB->encloseTableName(_dbprefix_ . $objCfg->getStrTableName()) . " WHERE " . $objDB->encloseColumnName($objCfg->getStrSourceColumn()) . " = ?", array($this->getObjObject()->getSystemid())); $bitReturn = $bitReturn && $objDB->multiInsert($objCfg->getStrTableName(), array($objCfg->getStrSourceColumn(), $objCfg->getStrTargetColumn()), $arrInserts); $bitReturn = $bitReturn && class_core_eventdispatcher::getInstance()->notifyGenericListeners(class_system_eventidentifier::EVENT_SYSTEM_OBJECTASSIGNMENTSUPDATED, array(array_values($arrNewAssignments), array_values($arrDeletedAssignments), array_values($arrAssignmentsFromObject), $this->getObjObject(), $strPropertyName)); if ($objReflection->hasPropertyAnnotation($strPropertyName, class_module_system_changelog::ANNOTATION_PROPERTY_VERSIONABLE)) { $objChanges = new class_module_system_changelog(); $objChanges->setOldValueForSystemidAndProperty($this->getObjObject()->getSystemid(), $strPropertyName, implode(",", $arrAssignmentsFromDatabase)); } } return $bitReturn; }
/** * Processes all object assignments in order to generate the relevant tables * * @param $strClass * * @return array */ private function collectAssignmentDefinitions($strClass) { $arrAssignmentTables = array(); $objReflection = new class_reflection($strClass); //get the mapped properties $arrProperties = $objReflection->getPropertiesWithAnnotation(class_orm_base::STR_ANNOTATION_OBJECTLIST, class_reflection_enum::PARAMS()); foreach ($arrProperties as $strPropertyName => $arrValues) { $strTableName = $objReflection->getAnnotationValueForProperty($strPropertyName, class_orm_base::STR_ANNOTATION_OBJECTLIST); if (!isset($arrValues["source"]) || !isset($arrValues["target"]) || empty($strTableName)) { continue; } $objTable = new class_orm_schemamanager_table($strTableName); $objTable->addRow(new class_orm_schemamanager_row($arrValues["source"], class_db_datatypes::STR_TYPE_CHAR20, false, true)); $objTable->addRow(new class_orm_schemamanager_row($arrValues["target"], class_db_datatypes::STR_TYPE_CHAR20, false, true)); $arrAssignmentTables[] = $objTable; } return $arrAssignmentTables; }