protected function _save($force = false) { if (!$this->_autoSave) { return true; } if (!$this->hasChanged()) { if (!$force) { return false; } SystemEvent::raise(SystemEvent::DEBUG, "Forced object save.", __METHOD__); } if (!Database::beginTransaction()) { return false; } // // The following is a workaround on the fact that the translation of this // serialized object to the database gets all broken, due to the fact of PHP // introducing NULL bytes around the '*' that is prepended before protected // variable members, in the serialized mode. This method replaces those // problematic NULL bytes with an identifier string '~~NULL_BYTE~~', // rendering serialization and unserialization of these specific kinds of // object safe. Credits to travis@travishegner.com on: // http://pt.php.net/manual/en/function.serialize.php#96504 // $serializedIntegrationBuilder = str_replace("", CINTIENT_NULL_BYTE_TOKEN, serialize($this->getIntegrationBuilder())); $serializedDeploymentBuilder = str_replace("", CINTIENT_NULL_BYTE_TOKEN, serialize($this->getDeploymentBuilder())); $sql = 'REPLACE INTO project' . ' (id,avatar,datecreation,' . ' description,title,visits,integrationbuilder,deploymentbuilder,status,' . ' releaselabel,statsnumbuilds,scmpassword,scmusername,workdir,' . ' scmremoterepository,scmconnectortype,scmcheckchangestimeout,' . ' datecheckedforchanges, specialtasks, optionreleasepackage,' . ' scmenvvars)' . " VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; $specialTasks = @serialize($this->getSpecialTasks()); if ($specialTasks === false) { $specialTasks = serialize(array()); } $val = array($this->getId(), $this->getAvatar(), $this->getDateCreation(), $this->getDescription(), $this->getTitle(), $this->getVisits(), $serializedIntegrationBuilder, $serializedDeploymentBuilder, $this->getStatus(), $this->getReleaseLabel(), $this->getStatsNumBuilds(), $this->getScmPassword(), $this->getScmUsername(), $this->getWorkDir(), $this->getScmRemoteRepository(), $this->getScmConnectorType(), $this->getScmCheckChangesTimeout(), $this->getDateCheckedForChanges(), $specialTasks, $this->getOptionReleasePackage(), $this->getScmEnvVars()); if ($this->_id === null) { if (!($id = Database::insert($sql, $val)) || !is_numeric($id)) { Database::rollbackTransaction(); SystemEvent::raise(SystemEvent::ERROR, "Problems saving project to db.", __METHOD__); return false; } $this->setId($id); } else { if (!Database::execute($sql, $val)) { Database::rollbackTransaction(); SystemEvent::raise(SystemEvent::ERROR, "Problems saving project to db.", __METHOD__); return false; } } // The project users Project_User::deleteByProject($this); // Reset it foreach ($this->_users as $projectUser) { if (!$projectUser->save(true)) { Database::rollbackTransaction(); SystemEvent::raise(SystemEvent::ERROR, "Problems saving project to db.", __METHOD__); return false; } } if (!Database::endTransaction()) { SystemEvent::raise(SystemEvent::ERROR, "Something occurred while finishing transaction. The project might not have been saved. [ID={$this->getId()}]", __METHOD__); return false; } #if DEBUG SystemEvent::raise(SystemEvent::DEBUG, "Saved project. [PID={$this->getId()}] [TITLE={$this->getTitle()}]", __METHOD__); #endif $this->resetSignature(); return true; }