Esempio n. 1
0
 /**
  * @param Object\Concrete $object
  * @throws \Exception
  */
 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\Dao\InheritanceHelper($object->getClassId(), "o_id", $storetable, $querytable);
     Object\AbstractObject::setGetInheritedValues(false);
     $fieldDefinitions = $this->model->getDefinition()->getFieldDefinitions();
     $data = [];
     $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 ($fieldDefinitions as $key => $fd) {
         $getter = "get" . ucfirst($fd->getName());
         if (method_exists($fd, "save")) {
             // for fieldtypes which have their own save algorithm eg. objects, multihref, ...
             $fd->save($this->model);
         } elseif ($fd->getColumnType()) {
             if (is_array($fd->getColumnType())) {
                 $insertDataArray = $fd->getDataForResource($this->model->{$getter}(), $object, ['context' => $this->model]);
                 $data = array_merge($data, $insertDataArray);
             } else {
                 $insertData = $fd->getDataForResource($this->model->{$getter}(), $object, ['context' => $this->model]);
                 $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
     $data = [];
     $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 ($fieldDefinitions as $key => $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 (is_array($insertData)) {
                             $insertData[$columnName] = $parentData[$columnName];
                         } else {
                             $insertData = $parentData[$columnName];
                         }
                     }
                 }
             }
             if ($inheritanceEnabled) {
                 //get changed fields for inheritance
                 if ($fd instanceof Object\ClassDefinition\Data\CalculatedValue) {
                     // nothing to do, see https://github.com/pimcore/pimcore/issues/727
                     continue;
                 } elseif ($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
                             } elseif ($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
                         } elseif ($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
                             } elseif ($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
                         } elseif ($oldData[$key] != $insertData) {
                             // data changed, do check and update
                             $this->inheritanceHelper->addFieldToCheck($key, $fd);
                         }
                     }
                 }
             }
         }
     }
     $this->db->insertOrUpdate($querytable, $data);
     if ($inheritanceEnabled) {
         $this->inheritanceHelper->doUpdate($object->getId(), true);
     }
     $this->inheritanceHelper->resetFieldsToCheck();
     // HACK: see a few lines above!
     Object\AbstractObject::setGetInheritedValues($inheritedValues);
 }
Esempio n. 2
0
 /**
  *
  */
 public function saveChildData()
 {
     $this->inheritanceHelper->doUpdate($this->model->getId());
     $this->inheritanceHelper->resetFieldsToCheck();
 }