/** * @param Object\Concrete $object * @return void */ public function save(Object\Concrete $object) { // HACK: set the pimcore admin mode to false to get the inherited values from parent if this source one is empty $inheritedValues = Object\AbstractObject::doGetInheritedValues(); $storetable = $this->model->getDefinition()->getTableName($object->getClass(), false); $querytable = $this->model->getDefinition()->getTableName($object->getClass(), true); $this->inheritanceHelper = new Object\Concrete\Resource\InheritanceHelper($object->getClassId(), "o_id", $storetable, $querytable); Object\AbstractObject::setGetInheritedValues(false); $fd = $this->model->getDefinition()->getFieldDefinitions(); $data = array(); $data["o_id"] = $object->getId(); $data["fieldname"] = $this->model->getFieldname(); // remove all relations try { $this->db->delete("object_relations_" . $object->getClassId(), "src_id = " . $object->getId() . " AND ownertype = 'objectbrick' AND ownername = '" . $this->model->getFieldname() . "' AND (position = '" . $this->model->getType() . "' OR position IS NULL OR position = '')"); } catch (\Exception $e) { \Logger::warning("Error during removing old relations: " . $e); } foreach ($fd as $key => $value) { $getter = "get" . ucfirst($value->getName()); if (method_exists($value, "save")) { // for fieldtypes which have their own save algorithm eg. objects, multihref, ... $value->save($this->model); } else { if ($value->getColumnType()) { if (is_array($value->getColumnType())) { $insertDataArray = $value->getDataForResource($this->model->{$getter}(), $object); $data = array_merge($data, $insertDataArray); } else { $insertData = $value->getDataForResource($this->model->{$getter}(), $object); $data[$key] = $insertData; } } } } $this->db->insertOrUpdate($storetable, $data); // get data for query table // $tableName = $this->model->getDefinition()->getTableName($object->getClass(), true); // this is special because we have to call each getter to get the inherited values from a possible parent object $objectVars = get_object_vars($this->model); $data = array(); $data["o_id"] = $object->getId(); $data["fieldname"] = $this->model->getFieldname(); $this->inheritanceHelper->resetFieldsToCheck(); $oldData = $this->db->fetchRow("SELECT * FROM " . $querytable . " WHERE o_id = ?", $object->getId()); $inheritanceEnabled = $object->getClass()->getAllowInherit(); $parentData = null; if ($inheritanceEnabled) { // get the next suitable parent for inheritance $parentForInheritance = $object->getNextParentForInheritance(); if ($parentForInheritance) { // we don't use the getter (built in functionality to get inherited values) because we need to avoid race conditions // we cannot Object\AbstractObject::setGetInheritedValues(true); and then $this->model->$method(); // so we select the data from the parent object using FOR UPDATE, which causes a lock on this row // so the data of the parent cannot be changed while this transaction is on progress $parentData = $this->db->fetchRow("SELECT * FROM " . $querytable . " WHERE o_id = ? FOR UPDATE", $parentForInheritance->getId()); } } foreach ($objectVars as $key => $value) { $fd = $this->model->getDefinition()->getFieldDefinition($key); if ($fd) { if ($fd->getQueryColumnType()) { //exclude untouchables if value is not an array - this means data has not been loaded $method = "get" . $key; $fieldValue = $this->model->{$method}(); $insertData = $fd->getDataForQueryResource($fieldValue, $object); $isEmpty = $fd->isEmpty($fieldValue); if (is_array($insertData)) { $columnNames = array_keys($insertData); $data = array_merge($data, $insertData); } else { $columnNames = [$key]; $data[$key] = $insertData; } // if the current value is empty and we have data from the parent, we just use it if ($isEmpty && $parentData) { foreach ($columnNames as $columnName) { if (array_key_exists($columnName, $parentData)) { $data[$columnName] = $parentData[$columnName]; } } } if ($inheritanceEnabled) { //get changed fields for inheritance if ($fd->isRelationType()) { if (is_array($insertData)) { $doInsert = false; foreach ($insertData as $insertDataKey => $insertDataValue) { if ($isEmpty && $oldData[$insertDataKey] == $parentData[$insertDataKey]) { // do nothing, ... value is still empty and parent data is equal to current data in query table } else { if ($oldData[$insertDataKey] != $insertDataValue) { $doInsert = true; break; } } } if ($doInsert) { $this->inheritanceHelper->addRelationToCheck($key, $fd, array_keys($insertData)); } } else { if ($isEmpty && $oldData[$key] == $parentData[$key]) { // do nothing, ... value is still empty and parent data is equal to current data in query table } else { if ($oldData[$key] != $insertData) { $this->inheritanceHelper->addRelationToCheck($key, $fd); } } } } else { if (is_array($insertData)) { foreach ($insertData as $insertDataKey => $insertDataValue) { if ($isEmpty && $oldData[$insertDataKey] == $parentData[$insertDataKey]) { // do nothing, ... value is still empty and parent data is equal to current data in query table } else { if ($oldData[$insertDataKey] != $insertDataValue) { $this->inheritanceHelper->addFieldToCheck($insertDataKey, $fd); } } } } else { if ($isEmpty && $oldData[$key] == $parentData[$key]) { // do nothing, ... value is still empty and parent data is equal to current data in query table } else { if ($oldData[$key] != $insertData) { // data changed, do check and update $this->inheritanceHelper->addFieldToCheck($key, $fd); } } } } } } } } $this->db->insertOrUpdate($querytable, $data); $this->inheritanceHelper->doUpdate($object->getId(), true); $this->inheritanceHelper->resetFieldsToCheck(); // HACK: see a few lines above! Object\AbstractObject::setGetInheritedValues($inheritedValues); }
/** * */ public function saveChilds() { $this->inheritanceHelper->doUpdate($this->model->getId()); $this->inheritanceHelper->resetFieldsToCheck(); }
/** * @param Object\Concrete $object * @return void */ public function save(Object\Concrete $object) { // HACK: set the pimcore admin mode to false to get the inherited values from parent if this source one is empty $inheritedValues = Object\AbstractObject::doGetInheritedValues(); $storetable = $this->model->getDefinition()->getTableName($object->getClass(), false); $querytable = $this->model->getDefinition()->getTableName($object->getClass(), true); $this->inheritanceHelper = new Object\Concrete\Resource\InheritanceHelper($object->getClassId(), "o_id", $storetable, $querytable); Object\AbstractObject::setGetInheritedValues(false); $fd = $this->model->getDefinition()->getFieldDefinitions(); $data = array(); $data["o_id"] = $object->getId(); $data["fieldname"] = $this->model->getFieldname(); // remove all relations try { $this->db->delete("object_relations_" . $object->getClassId(), "src_id = " . $object->getId() . " AND ownertype = 'objectbrick' AND ownername = '" . $this->model->getFieldname() . "' AND (position = '" . $this->model->getType() . "' OR position IS NULL OR position = '')"); } catch (\Exception $e) { \Logger::warning("Error during removing old relations: " . $e); } foreach ($fd as $key => $value) { $getter = "get" . ucfirst($value->getName()); if (method_exists($value, "save")) { // for fieldtypes which have their own save algorithm eg. objects, multihref, ... $value->save($this->model); } else { if ($value->getColumnType()) { if (is_array($value->getColumnType())) { $insertDataArray = $value->getDataForResource($this->model->{$getter}(), $object); $data = array_merge($data, $insertDataArray); } else { $insertData = $value->getDataForResource($this->model->{$getter}(), $object); $data[$key] = $insertData; } } } } $this->db->insertOrUpdate($storetable, $data); // get data for query table // $tableName = $this->model->getDefinition()->getTableName($object->getClass(), true); // this is special because we have to call each getter to get the inherited values from a possible parent object Object\AbstractObject::setGetInheritedValues(true); $objectVars = get_object_vars($this->model); $data = array(); $data["o_id"] = $object->getId(); $data["fieldname"] = $this->model->getFieldname(); $this->inheritanceHelper->resetFieldsToCheck(); $oldData = $this->db->fetchRow("SELECT * FROM " . $querytable . " WHERE o_id = ?", $object->getId()); foreach ($objectVars as $key => $value) { $fd = $this->model->getDefinition()->getFieldDefinition($key); if ($fd) { if ($fd->getQueryColumnType()) { //exclude untouchables if value is not an array - this means data has not been loaded $method = "get" . $key; $insertData = $fd->getDataForQueryResource($this->model->{$method}(), $object); if (is_array($insertData)) { $data = array_merge($data, $insertData); } else { $data[$key] = $insertData; } //get changed fields for inheritance if ($fd->isRelationType()) { if (is_array($insertData)) { $doInsert = false; foreach ($insertData as $insertDataKey => $insertDataValue) { if ($oldData[$insertDataKey] != $insertDataValue) { $doInsert = true; } } if ($doInsert) { $this->inheritanceHelper->addRelationToCheck($key, $fd, array_keys($insertData)); } } else { if ($oldData[$key] != $insertData) { $this->inheritanceHelper->addRelationToCheck($key, $fd); } } } else { if (is_array($insertData)) { foreach ($insertData as $insertDataKey => $insertDataValue) { if ($oldData[$insertDataKey] != $insertDataValue) { $this->inheritanceHelper->addFieldToCheck($insertDataKey, $fd); } } } else { if ($oldData[$key] != $insertData) { $this->inheritanceHelper->addFieldToCheck($key, $fd); } } } } } } $this->db->insertOrUpdate($querytable, $data); $this->inheritanceHelper->doUpdate($object->getId(), true); $this->inheritanceHelper->resetFieldsToCheck(); // HACK: see a few lines above! Object\AbstractObject::setGetInheritedValues($inheritedValues); }