Exemplo n.º 1
0
 /**
  * Saves the current object to the database. Determines, whether the current object has to be inserted
  * or updated to the database.
  * In case of an update, the objects' updateStateToDb() method is being called (as required by class_model).
  * In the case of a new object, a blank record is being created. Therefore, all tables returned by class' doc comment
  * will be filled with a new record (using the same new systemid as the primary key).
  * The newly created systemid is being set as the current objects' one and can be used in the afterwards
  * called updateStateToDb() method to reference the correct rows.
  *
  * @param string|bool $strPrevId The prev-id of the records, either to be used for the insert or to be used during the update of the record
  * @return bool
  * @since 3.3.0
  * @throws class_exception
  * @see interface_model
  *
  * @todo move to class_orm_objectupdate completely
  */
 public function updateObjectToDb($strPrevId = false)
 {
     $bitCommit = true;
     /** @var $this class_root|interface_model */
     if (!$this instanceof interface_model) {
         throw new class_exception("current object must implemented interface_model", class_exception::$level_FATALERROR);
     }
     if (!$this->getLockManager()->isAccessibleForCurrentUser()) {
         $objUser = new class_module_user_user($this->getLockManager()->getLockId());
         throw new class_exception("current object is locked by user " . $objUser->getStrDisplayName(), class_exception::$level_ERROR);
     }
     if (is_object($strPrevId) && $strPrevId instanceof class_root) {
         $strPrevId = $strPrevId->getSystemid();
     }
     $this->objDB->transactionBegin();
     //current systemid given? if not, create a new record.
     $bitRecordCreated = false;
     if (!validateSystemid($this->getSystemid())) {
         $bitRecordCreated = true;
         if ($strPrevId === false || $strPrevId === "" || $strPrevId === null) {
             //try to find the current modules-one
             if (isset($this->arrModule["modul"])) {
                 $strPrevId = class_module_system_module::getModuleByName($this->getArrModule("modul"), true)->getSystemid();
                 if (!validateSystemid($strPrevId)) {
                     throw new class_exception("automatic determination of module-id failed ", class_exception::$level_FATALERROR);
                 }
             } else {
                 throw new class_exception("insert with no previd ", class_exception::$level_FATALERROR);
             }
         }
         if (!validateSystemid($strPrevId) && $strPrevId !== "0") {
             throw new class_exception("insert with erroneous prev-id ", class_exception::$level_FATALERROR);
         }
         //create the new systemrecord
         //store date-bit temporary
         $bitDates = $this->bitDatesChanges;
         $this->createSystemRecord($strPrevId, $this->getStrDisplayName());
         $this->bitDatesChanges = $bitDates;
         if (validateSystemid($this->getStrSystemid())) {
             //Create the foreign records
             $objAnnotations = new class_reflection($this);
             $arrTargetTables = $objAnnotations->getAnnotationValuesFromClass("@targetTable");
             if (count($arrTargetTables) > 0) {
                 foreach ($arrTargetTables as $strOneConfig) {
                     $arrSingleTable = explode(".", $strOneConfig);
                     $strQuery = "INSERT INTO " . $this->objDB->encloseTableName(_dbprefix_ . $arrSingleTable[0]) . "\n                                                (" . $this->objDB->encloseColumnName($arrSingleTable[1]) . ") VALUES\n                                                (?) ";
                     if (!$this->objDB->_pQuery($strQuery, array($this->getStrSystemid()))) {
                         $bitCommit = false;
                     }
                 }
             }
             if (!$this->onInsertToDb()) {
                 $bitCommit = false;
             }
         } else {
             throw new class_exception("creation of systemrecord failed", class_exception::$level_FATALERROR);
         }
         //all updates are done, start the "real" update
         class_carrier::getInstance()->flushCache(class_carrier::INT_CACHE_TYPE_DBQUERIES);
     }
     //new prev-id?
     if ($strPrevId !== false && $this->getSystemid() != $strPrevId && (validateSystemid($strPrevId) || $strPrevId == "0")) {
         //validate the new prev id - it is not allowed to set a parent-node as a sub-node of its own child
         if (!$this->isSystemidChildNode($this->getSystemid(), $strPrevId)) {
             $this->setStrPrevId($strPrevId);
         }
     }
     //new comment?
     $this->setStrRecordComment($this->getStrDisplayName());
     //Keep old and new status here, status changed event is being fired after record is completely updated (so after updateStateToDb())
     $intOldStatus = $this->intOldRecordStatus;
     $intNewStatus = $this->intRecordStatus;
     //save back to the database
     $bitCommit = $bitCommit && $this->updateSystemrecord();
     //update ourselves to the database
     if ($bitCommit && !$this->updateStateToDb()) {
         $bitCommit = false;
     }
     //now fire the status changed event
     if ($intOldStatus != $intNewStatus && $intOldStatus != -1) {
         class_core_eventdispatcher::getInstance()->notifyGenericListeners(class_system_eventidentifier::EVENT_SYSTEM_STATUSCHANGED, array($this->getSystemid(), $this, $intOldStatus, $intNewStatus));
     }
     if ($bitCommit) {
         $this->objDB->transactionCommit();
         //unlock the record
         $this->getLockManager()->unlockRecord();
         class_logger::getInstance()->addLogRow("updateObjectToDb() succeeded for systemid " . $this->getSystemid() . " (" . $this->getRecordComment() . ")", class_logger::$levelInfo);
     } else {
         $this->objDB->transactionRollback();
         class_logger::getInstance()->addLogRow("updateObjectToDb() failed for systemid " . $this->getSystemid() . " (" . $this->getRecordComment() . ")", class_logger::$levelWarning);
     }
     //call the recordUpdated-Listeners
     class_core_eventdispatcher::getInstance()->notifyGenericListeners(class_system_eventidentifier::EVENT_SYSTEM_RECORDUPDATED, array($this, $bitRecordCreated));
     class_carrier::getInstance()->flushCache(class_carrier::INT_CACHE_TYPE_DBQUERIES);
     return $bitCommit;
 }