$max_length) { $name = substr($name, 0, $max_length - strlen($suffix)); } return $name.$suffix; } /** * Clone a project with all settings * * @param integer $src_project_id Project Id * @param array $selection Selection of optional project parts to duplicate * @param integer $owner_id Owner of the project * @param string $name Name of the project * @param boolean $private Force the project to be private * @return integer Cloned Project Id */ public function duplicate($src_project_id, $selection = array('projectPermissionModel', 'categoryModel', 'actionModel'), $owner_id = 0, $name = null, $private = null) { $this->db->startTransaction(); // Get the cloned project Id $dst_project_id = $this->copy($src_project_id, $owner_id, $name, $private); if ($dst_project_id === false) { $this->db->cancelTransaction(); return false; } // Clone Columns, Categories, Permissions and Actions foreach ($this->getPossibleSelection() as $model) { // Skip if optional part has not been selected if (in_array($model, $this->getOptionalSelection()) && ! in_array($model, $selection)) { continue; } // Skip permissions for private projects if ($private && $model === 'projectPermissionModel') { continue; } if (! $this->$model->duplicate($src_project_id, $dst_project_id)) { $this->db->cancelTransaction(); return false; } } if (! $this->makeOwnerManager($dst_project_id, $owner_id)) { $this->db->cancelTransaction(); return false; } $this->db->closeTransaction(); return (int) $dst_project_id; } /** * Create a project from another one * * @access private * @param integer $src_project_id * @param integer $owner_id * @param string $name * @param boolean $private * @return integer */ private function copy($src_project_id, $owner_id = 0, $name = null, $private = null) { $project = $this->projectModel->getById($src_project_id); $is_private = empty($project['is_private']) ? 0 : 1; $values = array( 'name' => $name ?: $this->getClonedProjectName($project['name']), 'is_active' => 1, 'last_modified' => time(), 'token' => '', 'is_public' => 0, 'is_private' => $private ? 1 : $is_private, 'owner_id' => $owner_id, ); if (! $this->db->table(ProjectModel::TABLE)->save($values)) { return false; } return $this->db->getLastId(); } /** * Make sure that the creator of the duplicated project is alsp owner * * @access private * @param integer $dst_project_id * @param integer $owner_id * @return boolean */ private function makeOwnerManager($dst_project_id, $owner_id) { if ($owner_id > 0) { $this->projectUserRoleModel->removeUser($dst_project_id, $owner_id); if (! $this->projectUserRoleModel->addUser($dst_project_id, $owner_id, Role::PROJECT_MANAGER)) { return false; } } return true; } }