public function save() { // TODO: Transactions! $ret = parent::save(); if ($this->unsavedOwners) { $new_owners = array_fill_keys($this->unsavedOwners, true); $cur_owners = array(); foreach ($this->loadOwners() as $owner) { if (empty($new_owners[$owner->getUserPHID()])) { $owner->delete(); continue; } $cur_owners[$owner->getUserPHID()] = true; } $add_owners = array_diff_key($new_owners, $cur_owners); foreach ($add_owners as $phid => $ignored) { $owner = new PhabricatorOwnersOwner(); $owner->setPackageID($this->getID()); $owner->setUserPHID($phid); $owner->save(); } unset($this->unsavedOwners); } if ($this->unsavedPaths) { $new_paths = igroup($this->unsavedPaths, 'repositoryPHID', 'path'); $cur_paths = $this->loadPaths(); foreach ($cur_paths as $key => $path) { if (empty($new_paths[$path->getRepositoryPHID()][$path->getPath()])) { $path->delete(); unset($cur_paths[$key]); } } $cur_paths = mgroup($cur_paths, 'getRepositoryPHID', 'getPath'); foreach ($new_paths as $repository_phid => $paths) { foreach ($paths as $path => $ignored) { if (empty($cur_paths[$repository_phid][$path])) { $obj = new PhabricatorOwnersPath(); $obj->setPackageID($this->getID()); $obj->setRepositoryPHID($repository_phid); $obj->setPath($path); $obj->save(); } } } unset($this->unsavedPaths); } return $ret; }
public function save() { if ($this->getID()) { $is_new = false; } else { $is_new = true; } $this->openTransaction(); $ret = parent::save(); $add_owners = array(); $remove_owners = array(); $all_owners = array(); if ($this->unsavedOwners) { $new_owners = array_fill_keys($this->unsavedOwners, true); $cur_owners = array(); foreach ($this->loadOwners() as $owner) { if (empty($new_owners[$owner->getUserPHID()])) { $remove_owners[$owner->getUserPHID()] = true; $owner->delete(); continue; } $cur_owners[$owner->getUserPHID()] = true; } $add_owners = array_diff_key($new_owners, $cur_owners); $all_owners = array_merge(array($this->getPrimaryOwnerPHID() => true), $new_owners, $remove_owners); foreach ($add_owners as $phid => $ignored) { $owner = new PhabricatorOwnersOwner(); $owner->setPackageID($this->getID()); $owner->setUserPHID($phid); $owner->save(); } unset($this->unsavedOwners); } $add_paths = array(); $remove_paths = array(); $touched_repos = array(); if ($this->unsavedPaths) { $new_paths = igroup($this->unsavedPaths, 'repositoryPHID', 'path'); $cur_paths = $this->loadPaths(); foreach ($cur_paths as $key => $path) { if (empty($new_paths[$path->getRepositoryPHID()][$path->getPath()])) { $touched_repos[$path->getRepositoryPHID()] = true; $remove_paths[$path->getRepositoryPHID()][$path->getPath()] = true; $path->delete(); unset($cur_paths[$key]); } } $cur_paths = mgroup($cur_paths, 'getRepositoryPHID', 'getPath'); foreach ($new_paths as $repository_phid => $paths) { // get repository object for path validation $repository = id(new PhabricatorRepository())->loadOneWhere('phid = %s', $repository_phid); if (!$repository) { continue; } foreach ($paths as $path => $ignored) { $path = ltrim($path, '/'); // build query to validate path $drequest = DiffusionRequest::newFromDictionary(array('repository' => $repository, 'path' => $path)); $query = DiffusionBrowseQuery::newFromDiffusionRequest($drequest); $query->needValidityOnly(true); $valid = $query->loadPaths(); $is_directory = true; if (!$valid) { switch ($query->getReasonForEmptyResultSet()) { case DiffusionBrowseQuery::REASON_IS_FILE: $valid = true; $is_directory = false; break; case DiffusionBrowseQuery::REASON_IS_EMPTY: $valid = true; break; } } if ($is_directory && substr($path, -1) != '/') { $path .= '/'; } if (substr($path, 0, 1) != '/') { $path = '/' . $path; } if (empty($cur_paths[$repository_phid][$path]) && $valid) { $touched_repos[$repository_phid] = true; $add_paths[$repository_phid][$path] = true; $obj = new PhabricatorOwnersPath(); $obj->setPackageID($this->getID()); $obj->setRepositoryPHID($repository_phid); $obj->setPath($path); $obj->save(); } } } unset($this->unsavedPaths); } $this->saveTransaction(); if ($is_new) { $mail = new PackageCreateMail($this); } else { $mail = new PackageModifyMail($this, array_keys($add_owners), array_keys($remove_owners), array_keys($all_owners), array_keys($touched_repos), $add_paths, $remove_paths); } $mail->send(); return $ret; }