private function checkAuditReasons(PhabricatorRepositoryCommit $commit, PhabricatorOwnersPackage $package)
 {
     $data = id(new PhabricatorRepositoryCommitData())->loadOneWhere('commitID = %d', $commit->getID());
     $reasons = array();
     if ($data->getCommitDetail('vsDiff')) {
         $reasons[] = pht('Changed After Revision Was Accepted');
     }
     $commit_author_phid = $data->getCommitDetail('authorPHID');
     if (!$commit_author_phid) {
         $reasons[] = pht('Commit Author Not Recognized');
     }
     $revision_id = $data->getCommitDetail('differential.revisionID');
     $revision_author_phid = null;
     $commit_reviewedby_phid = null;
     if ($revision_id) {
         $revision = id(new DifferentialRevisionQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withIDs(array($revision_id))->executeOne();
         if ($revision) {
             $revision_author_phid = $revision->getAuthorPHID();
             $commit_reviewedby_phid = $data->getCommitDetail('reviewerPHID');
             if ($revision_author_phid !== $commit_author_phid) {
                 $reasons[] = pht('Author Not Matching with Revision');
             }
         } else {
             $reasons[] = pht('Revision Not Found');
         }
     } else {
         $reasons[] = pht('No Revision Specified');
     }
     $owners_phids = PhabricatorOwnersOwner::loadAffiliatedUserPHIDs(array($package->getID()));
     if (!($commit_author_phid && in_array($commit_author_phid, $owners_phids) || $commit_reviewedby_phid && in_array($commit_reviewedby_phid, $owners_phids))) {
         $reasons[] = pht('Owners Not Involved');
     }
     return $reasons;
 }
 public function getHeraldFieldValue($object)
 {
     $packages = $this->getAdapter()->loadAffectedPackages();
     if (!$packages) {
         return array();
     }
     $owners = PhabricatorOwnersOwner::loadAllForPackages($packages);
     return mpull($owners, 'getUserPHID');
 }
 public function willPublishStory($commit)
 {
     $requests = id(new DiffusionCommitQuery())->setViewer($this->getViewer())->withPHIDs(array($commit->getPHID()))->needAuditRequests(true)->executeOne()->getAudits();
     // TODO: This is messy and should be generalized, but we don't have a good
     // query for it yet. Since we run in the daemons, just do the easiest thing
     // we can for the moment. Figure out who all of the "active" (need to
     // audit) and "passive" (no action necessary) users are.
     $auditor_phids = mpull($requests, 'getAuditorPHID');
     $objects = id(new PhabricatorObjectQuery())->setViewer($this->getViewer())->withPHIDs($auditor_phids)->execute();
     $active = array();
     $passive = array();
     foreach ($requests as $request) {
         $status = $request->getAuditStatus();
         $object = idx($objects, $request->getAuditorPHID());
         if (!$object) {
             continue;
         }
         $request_phids = array();
         if ($object instanceof PhabricatorUser) {
             $request_phids = array($object->getPHID());
         } else {
             if ($object instanceof PhabricatorOwnersPackage) {
                 $request_phids = PhabricatorOwnersOwner::loadAffiliatedUserPHIDs(array($object->getID()));
             } else {
                 if ($object instanceof PhabricatorProject) {
                     $project = id(new PhabricatorProjectQuery())->setViewer($this->getViewer())->withIDs(array($object->getID()))->needMembers(true)->executeOne();
                     $request_phids = $project->getMemberPHIDs();
                 } else {
                     // Dunno what this is.
                     $request_phids = array();
                 }
             }
         }
         switch ($status) {
             case PhabricatorAuditStatusConstants::AUDIT_REQUIRED:
             case PhabricatorAuditStatusConstants::AUDIT_REQUESTED:
             case PhabricatorAuditStatusConstants::CONCERNED:
                 $active += array_fuse($request_phids);
                 break;
             default:
                 $passive += array_fuse($request_phids);
                 break;
         }
     }
     // Remove "Active" users from the "Passive" list.
     $passive = array_diff_key($passive, $active);
     $this->activePHIDs = $active;
     $this->passivePHIDs = $passive;
     $this->auditRequests = $requests;
     return $commit;
 }
 protected static function queryByAffiliatedUser($owner)
 {
     $is_valid_phid = phid_get_type($owner) == PhabricatorPHIDConstants::PHID_TYPE_USER;
     if (!$is_valid_phid) {
         throw id(new ConduitException('ERR-INVALID-PARAMETER'))->setErrorDescription('Expected user PHID for affiliation, got ' . $owner);
     }
     $owners = PhabricatorOwnersOwner::loadAffiliatedPackages($owner);
     $package_ids = mpull($owners, 'getPackageID');
     $packages = array();
     foreach ($package_ids as $id) {
         $packages[] = id(new PhabricatorOwnersPackage())->load($id);
     }
     return $packages;
 }
 private function checkAuditReasons(PhabricatorRepositoryCommit $commit, PhabricatorOwnersPackage $package, $author_phid, $revision)
 {
     $owner_phids = PhabricatorOwnersOwner::loadAffiliatedUserPHIDs(array($package->getID()));
     $owner_phids = array_fuse($owner_phids);
     $reasons = array();
     if (!$author_phid) {
         $reasons[] = pht('Commit Author Not Recognized');
     } else {
         if (isset($owner_phids[$author_phid])) {
             return $reasons;
         }
     }
     if (!$revision) {
         $reasons[] = pht('No Revision Specified');
         return $reasons;
     }
     $accepted_statuses = array(DifferentialReviewerStatus::STATUS_ACCEPTED, DifferentialReviewerStatus::STATUS_ACCEPTED_OLDER);
     $accepted_statuses = array_fuse($accepted_statuses);
     $found_accept = false;
     foreach ($revision->getReviewerStatus() as $reviewer) {
         $reviewer_phid = $reviewer->getReviewerPHID();
         // If this reviewer isn't a package owner, just ignore them.
         if (empty($owner_phids[$reviewer_phid])) {
             continue;
         }
         // If this reviewer accepted the revision and owns the package, we're
         // all clear and do not need to trigger an audit.
         if (isset($accepted_statuses[$reviewer->getStatus()])) {
             $found_accept = true;
             break;
         }
     }
     if (!$found_accept) {
         $reasons[] = pht('Owners Not Involved');
     }
     return $reasons;
 }
 private function checkAuditReasons(PhabricatorRepositoryCommit $commit, PhabricatorOwnersPackage $package)
 {
     $data = id(new PhabricatorRepositoryCommitData())->loadOneWhere('commitID = %d', $commit->getID());
     $reasons = array();
     if ($data->getCommitDetail('vsDiff')) {
         $reasons[] = 'Changed After Revision Was Accepted';
     }
     $commit_author_phid = $data->getCommitDetail('authorPHID');
     if (!$commit_author_phid) {
         $reasons[] = 'Commit Author Not Recognized';
     }
     $revision_id = $data->getCommitDetail('differential.revisionID');
     $revision_author_phid = null;
     $commit_reviewedby_phid = null;
     if ($revision_id) {
         // TODO: (T603) This is probably safe to use an omnipotent user on,
         // but check things more closely.
         $revision = id(new DifferentialRevision())->load($revision_id);
         if ($revision) {
             $revision_author_phid = $revision->getAuthorPHID();
             $commit_reviewedby_phid = $data->getCommitDetail('reviewerPHID');
             if ($revision_author_phid !== $commit_author_phid) {
                 $reasons[] = 'Author Not Matching with Revision';
             }
         } else {
             $reasons[] = 'Revision Not Found';
         }
     } else {
         $reasons[] = 'No Revision Specified';
     }
     $owners_phids = PhabricatorOwnersOwner::loadAffiliatedUserPHIDs(array($package->getID()));
     if (!($commit_author_phid && in_array($commit_author_phid, $owners_phids) || $commit_reviewedby_phid && in_array($commit_reviewedby_phid, $owners_phids))) {
         $reasons[] = 'Owners Not Involved';
     }
     return $reasons;
 }
 public function getHeraldField($field)
 {
     switch ($field) {
         case self::FIELD_TITLE:
             return $this->revision->getTitle();
             break;
         case self::FIELD_BODY:
             return $this->revision->getSummary() . "\n" . $this->revision->getTestPlan();
             break;
         case self::FIELD_AUTHOR:
             return $this->revision->getAuthorPHID();
             break;
         case self::FIELD_AUTHOR_PROJECTS:
             $author_phid = $this->revision->getAuthorPHID();
             if (!$author_phid) {
                 return array();
             }
             $projects = id(new PhabricatorProjectQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withMemberPHIDs(array($author_phid))->execute();
             return mpull($projects, 'getPHID');
         case self::FIELD_DIFF_FILE:
             return $this->loadAffectedPaths();
         case self::FIELD_REVIEWERS:
             if (isset($this->explicitReviewers)) {
                 return array_keys($this->explicitReviewers);
             } else {
                 return $this->revision->getReviewers();
             }
         case self::FIELD_REPOSITORY:
             $repository = $this->loadRepository();
             if (!$repository) {
                 return null;
             }
             return $repository->getPHID();
         case self::FIELD_REPOSITORY_PROJECTS:
             $repository = $this->loadRepository();
             if (!$repository) {
                 return array();
             }
             return $repository->getProjectPHIDs();
         case self::FIELD_DIFF_CONTENT:
             return $this->loadContentDictionary();
         case self::FIELD_DIFF_ADDED_CONTENT:
             return $this->loadAddedContentDictionary();
         case self::FIELD_DIFF_REMOVED_CONTENT:
             return $this->loadRemovedContentDictionary();
         case self::FIELD_AFFECTED_PACKAGE:
             $packages = $this->loadAffectedPackages();
             return mpull($packages, 'getPHID');
         case self::FIELD_AFFECTED_PACKAGE_OWNER:
             $packages = $this->loadAffectedPackages();
             return PhabricatorOwnersOwner::loadAffiliatedUserPHIDs(mpull($packages, 'getID'));
     }
     return parent::getHeraldField($field);
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $views = array('owned' => 'Owned Packages', 'all' => 'All Packages', 'search' => 'Search Results');
     if (empty($views[$this->view])) {
         reset($views);
         $this->view = key($views);
     }
     if ($this->view != 'search') {
         unset($views['search']);
     }
     $nav = new AphrontSideNavView();
     foreach ($views as $key => $name) {
         $nav->addNavItem(phutil_render_tag('a', array('href' => '/owners/view/' . $key . '/', 'class' => $this->view == $key ? 'aphront-side-nav-selected' : null), phutil_escape_html($name)));
     }
     $package = new PhabricatorOwnersPackage();
     $owner = new PhabricatorOwnersOwner();
     $path = new PhabricatorOwnersPath();
     switch ($this->view) {
         case 'search':
             $packages = array();
             $conn_r = $package->establishConnection('r');
             $where = array('1 = 1');
             $join = array();
             if ($request->getStr('name')) {
                 $where[] = qsprintf($conn_r, 'p.name LIKE %~', $request->getStr('name'));
             }
             if ($request->getStr('path')) {
                 $join[] = qsprintf($conn_r, 'JOIN %T path ON path.packageID = p.id', $path->getTableName());
                 $where[] = qsprintf($conn_r, 'path.path LIKE %~', $request->getStr('path'));
             }
             if ($request->getArr('owner')) {
                 $join[] = qsprintf($conn_r, 'JOIN %T o ON o.packageID = p.id', $owner->getTableName());
                 $where[] = qsprintf($conn_r, 'o.userPHID IN (%Ls)', $request->getArr('owner'));
             }
             $data = queryfx_all($conn_r, 'SELECT p.* FROM %T p %Q WHERE %Q GROUP BY p.id', $package->getTableName(), implode(' ', $join), '(' . implode(') AND (', $where) . ')');
             $packages = $package->loadAllFromArray($data);
             $header = 'Search Results';
             $nodata = 'No packages match your query.';
             break;
         case 'owned':
             $data = queryfx_all($package->establishConnection('r'), 'SELECT p.* FROM %T p JOIN %T o ON p.id = o.packageID
         WHERE o.userPHID = %s GROUP BY p.id', $package->getTableName(), $owner->getTableName(), $user->getPHID());
             $packages = $package->loadAllFromArray($data);
             $header = 'Owned Packages';
             $nodata = 'No owned packages';
             break;
         case 'all':
             $packages = $package->loadAll();
             $header = 'All Packages';
             $nodata = 'There are no defined packages.';
             break;
     }
     $content = $this->renderPackageTable($packages, $header, $nodata);
     $filter = new AphrontListFilterView();
     $filter->addButton(phutil_render_tag('a', array('href' => '/owners/new/', 'class' => 'green button'), 'Create New Package'));
     $owners_search_value = array();
     if ($request->getArr('owner')) {
         $phids = $request->getArr('owner');
         $phid = reset($phids);
         $handles = id(new PhabricatorObjectHandleData(array($phid)))->loadHandles();
         $owners_search_value = array($phid => $handles[$phid]->getFullName());
     }
     $form = id(new AphrontFormView())->setUser($user)->setAction('/owners/view/search/')->appendChild(id(new AphrontFormTextControl())->setName('name')->setLabel('Name')->setValue($request->getStr('name')))->appendChild(id(new AphrontFormTokenizerControl())->setDatasource('/typeahead/common/users/')->setLimit(1)->setName('owner')->setLabel('Owner')->setValue($owners_search_value))->appendChild(id(new AphrontFormTextControl())->setName('path')->setLabel('Path')->setValue($request->getStr('path')))->appendChild(id(new AphrontFormSubmitControl())->setValue('Search for Packages'));
     $filter->appendChild($form);
     $nav->appendChild($filter);
     $nav->appendChild($content);
     return $this->buildStandardPageResponse($nav, array('title' => 'Package Index', 'tab' => 'index'));
 }
 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 getHeraldField($field)
 {
     switch ($field) {
         case HeraldFieldConfig::FIELD_TITLE:
             return $this->revision->getTitle();
             break;
         case HeraldFieldConfig::FIELD_BODY:
             return $this->revision->getSummary() . "\n" . $this->revision->getTestPlan();
             break;
         case HeraldFieldConfig::FIELD_AUTHOR:
             return $this->revision->getAuthorPHID();
             break;
         case HeraldFieldConfig::FIELD_DIFF_FILE:
             return $this->loadAffectedPaths();
         case HeraldFieldConfig::FIELD_CC:
             if (isset($this->explicitCCs)) {
                 return array_keys($this->explicitCCs);
             } else {
                 return $this->revision->getCCPHIDs();
             }
         case HeraldFieldConfig::FIELD_REVIEWERS:
             if (isset($this->explicitReviewers)) {
                 return array_keys($this->explicitReviewers);
             } else {
                 return $this->revision->getReviewers();
             }
         case HeraldFieldConfig::FIELD_REPOSITORY:
             $repository = $this->loadRepository();
             if (!$repository) {
                 return null;
             }
             return $repository->getPHID();
         case HeraldFieldConfig::FIELD_DIFF_CONTENT:
             return $this->loadContentDictionary();
         case HeraldFieldConfig::FIELD_AFFECTED_PACKAGE:
             $packages = $this->loadAffectedPackages();
             return mpull($packages, 'getPHID');
         case HeraldFieldConfig::FIELD_AFFECTED_PACKAGE_OWNER:
             $packages = $this->loadAffectedPackages();
             return PhabricatorOwnersOwner::loadAffiliatedUserPHIDs(mpull($packages, 'getID'));
         default:
             throw new Exception("Invalid field '{$field}'.");
     }
 }
 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;
 }
 private function checkAuditReasons(PhabricatorRepositoryCommit $commit, PhabricatorOwnersPackage $package)
 {
     $data = id(new PhabricatorRepositoryCommitData())->loadOneWhere('commitID = %d', $commit->getID());
     $reasons = array();
     if ($data->getCommitDetail('vsDiff')) {
         $reasons[] = "Changed After Revision Was Accepted";
     }
     $commit_author_phid = $data->getCommitDetail('authorPHID');
     if (!$commit_author_phid) {
         $reasons[] = "Commit Author Not Recognized";
     }
     $revision_id = $data->getCommitDetail('differential.revisionID');
     $revision_author_phid = null;
     $commit_reviewedby_phid = null;
     $commit_author_phid = null;
     if ($revision_id) {
         $revision = id(new DifferentialRevision())->load($revision_id);
         if ($revision) {
             $revision->loadRelationships();
             $revision_author_phid = $revision->getAuthorPHID();
             $revision_reviewedby_phid = $revision->loadReviewedBy();
             $commit_reviewedby_phid = $data->getCommitDetail('reviewerPHID');
             $commit_author_phid = $data->getCommitDetail('authorPHID');
             if ($revision_author_phid !== $commit_author_phid) {
                 $reasons[] = "Author Not Matching with Revision";
             }
             if ($revision_reviewedby_phid !== $commit_reviewedby_phid) {
                 $reasons[] = "ReviewedBy Not Matching with Revision";
             }
         } else {
             $reasons[] = "Revision Not Found";
         }
     } else {
         $reasons[] = "No Revision Specified";
     }
     $owners_phids = PhabricatorOwnersOwner::loadAffiliatedUserPHIDs(array($package->getID()));
     if (!($commit_author_phid && in_array($commit_author_phid, $owners_phids) || $commit_reviewedby_phid && in_array($commit_reviewedby_phid, $owners_phids))) {
         $reasons[] = "Owners Not Involved";
     }
     return $reasons;
 }
 public function getHeraldField($field)
 {
     $data = $this->commitData;
     switch ($field) {
         case HeraldFieldConfig::FIELD_BODY:
             return $data->getCommitMessage();
         case HeraldFieldConfig::FIELD_AUTHOR:
             return $data->getCommitDetail('authorPHID');
         case HeraldFieldConfig::FIELD_REVIEWER:
             return $data->getCommitDetail('reviewerPHID');
         case HeraldFieldConfig::FIELD_DIFF_FILE:
             return $this->loadAffectedPaths();
         case HeraldFieldConfig::FIELD_REPOSITORY:
             return $this->repository->getPHID();
         case HeraldFieldConfig::FIELD_DIFF_CONTENT:
             // TODO!
             return null;
             /*
                     try {
                       $diff = $this->loadDiff();
                     } catch (Exception $ex) {
                       // See rE280053 for an example.
                       return array(
                         '<<< Failed to load diff, this usually means the change committed '.
                         'a binary file as text. >>>',
                       );
                     }
                     $dict = array();
                     $changes = $diff->getChangesets();
                     $lines = array();
                     foreach ($changes as $change) {
                       $lines = array();
                       foreach ($change->getHunks() as $hunk) {
                         $lines[] = $hunk->makeChanges();
                       }
                       $dict[$change->getTrueFilename()] = implode("\n", $lines);
                     }
                     return $dict;
             */
         /*
                 try {
                   $diff = $this->loadDiff();
                 } catch (Exception $ex) {
                   // See rE280053 for an example.
                   return array(
                     '<<< Failed to load diff, this usually means the change committed '.
                     'a binary file as text. >>>',
                   );
                 }
                 $dict = array();
                 $changes = $diff->getChangesets();
                 $lines = array();
                 foreach ($changes as $change) {
                   $lines = array();
                   foreach ($change->getHunks() as $hunk) {
                     $lines[] = $hunk->makeChanges();
                   }
                   $dict[$change->getTrueFilename()] = implode("\n", $lines);
                 }
                 return $dict;
         */
         case HeraldFieldConfig::FIELD_AFFECTED_PACKAGE:
             $packages = $this->loadAffectedPackages();
             return mpull($packages, 'getPHID');
         case HeraldFieldConfig::FIELD_AFFECTED_PACKAGE_OWNER:
             $packages = $this->loadAffectedPackages();
             $owners = PhabricatorOwnersOwner::loadAllForPackages($packages);
             return mpull($owners, 'getUserPHID');
         case HeraldFieldConfig::FIELD_NEED_AUDIT_FOR_PACKAGE:
             return $this->loadAuditNeededPackage();
         case HeraldFieldConfig::FIELD_DIFFERENTIAL_REVISION:
             $revision = $this->loadDifferentialRevision();
             if (!$revision) {
                 return null;
             }
             return $revision->getID();
         case HeraldFieldConfig::FIELD_DIFFERENTIAL_REVIEWERS:
             $revision = $this->loadDifferentialRevision();
             if (!$revision) {
                 return null;
             }
             return $revision->getReviewers();
         case HeraldFieldConfig::FIELD_DIFFERENTIAL_CCS:
             $revision = $this->loadDifferentialRevision();
             if (!$revision) {
                 return null;
             }
             return $revision->getCCPHIDs();
         default:
             throw new Exception("Invalid field '{$field}'.");
     }
 }
 /**
  * Load the PHIDs for all objects the user has the authority to act as an
  * audit for. This includes themselves, and any packages they are an owner
  * of.
  */
 public static function loadAuditPHIDsForUser(PhabricatorUser $user)
 {
     $phids = array();
     // The user can audit on their own behalf.
     $phids[$user->getPHID()] = true;
     // The user can audit on behalf of all packages they own.
     $owned_packages = PhabricatorOwnersOwner::loadAffiliatedPackages($user->getPHID());
     if ($owned_packages) {
         $packages = id(new PhabricatorOwnersPackage())->loadAllWhere('id IN (%Ld)', mpull($owned_packages, 'getPackageID'));
         foreach (mpull($packages, 'getPHID') as $phid) {
             $phids[$phid] = true;
         }
     }
     // The user can audit on behalf of all projects they are a member of.
     $query = new PhabricatorProjectQuery();
     $query->setMembers(array($user->getPHID()));
     $projects = $query->execute();
     foreach ($projects as $project) {
         $phids[$project->getPHID()] = true;
     }
     return array_keys($phids);
 }
 public function getHeraldField($field)
 {
     $data = $this->commitData;
     switch ($field) {
         case self::FIELD_BODY:
             return $data->getCommitMessage();
         case self::FIELD_AUTHOR:
             return $data->getCommitDetail('authorPHID');
         case self::FIELD_COMMITTER:
             return $data->getCommitDetail('committerPHID');
         case self::FIELD_REVIEWER:
             return $data->getCommitDetail('reviewerPHID');
         case self::FIELD_DIFF_FILE:
             return $this->loadAffectedPaths();
         case self::FIELD_REPOSITORY:
             return $this->repository->getPHID();
         case self::FIELD_REPOSITORY_PROJECTS:
             return $this->repository->getProjectPHIDs();
         case self::FIELD_DIFF_CONTENT:
             return $this->getDiffContent('*');
         case self::FIELD_DIFF_ADDED_CONTENT:
             return $this->getDiffContent('+');
         case self::FIELD_DIFF_REMOVED_CONTENT:
             return $this->getDiffContent('-');
         case self::FIELD_DIFF_ENORMOUS:
             $this->getDiffContent('*');
             return $this->commitDiff instanceof Exception;
         case self::FIELD_AFFECTED_PACKAGE:
             $packages = $this->loadAffectedPackages();
             return mpull($packages, 'getPHID');
         case self::FIELD_AFFECTED_PACKAGE_OWNER:
             $packages = $this->loadAffectedPackages();
             $owners = PhabricatorOwnersOwner::loadAllForPackages($packages);
             return mpull($owners, 'getUserPHID');
         case self::FIELD_NEED_AUDIT_FOR_PACKAGE:
             return $this->loadAuditNeededPackage();
         case self::FIELD_DIFFERENTIAL_REVISION:
             $revision = $this->loadDifferentialRevision();
             if (!$revision) {
                 return null;
             }
             return $revision->getID();
         case self::FIELD_DIFFERENTIAL_ACCEPTED:
             $revision = $this->loadDifferentialRevision();
             if (!$revision) {
                 return null;
             }
             $status = $data->getCommitDetail('precommitRevisionStatus', $revision->getStatus());
             switch ($status) {
                 case ArcanistDifferentialRevisionStatus::ACCEPTED:
                 case ArcanistDifferentialRevisionStatus::CLOSED:
                     return $revision->getPHID();
             }
             return null;
         case self::FIELD_DIFFERENTIAL_REVIEWERS:
             $revision = $this->loadDifferentialRevision();
             if (!$revision) {
                 return array();
             }
             return $revision->getReviewers();
         case self::FIELD_DIFFERENTIAL_CCS:
             $revision = $this->loadDifferentialRevision();
             if (!$revision) {
                 return array();
             }
             return $revision->getCCPHIDs();
         case self::FIELD_BRANCHES:
             $params = array('callsign' => $this->repository->getCallsign(), 'contains' => $this->commit->getCommitIdentifier());
             $result = id(new ConduitCall('diffusion.branchquery', $params))->setUser(PhabricatorUser::getOmnipotentUser())->execute();
             $refs = DiffusionRepositoryRef::loadAllFromDictionaries($result);
             return mpull($refs, 'getShortName');
         case self::FIELD_REPOSITORY_AUTOCLOSE_BRANCH:
             return $this->repository->shouldAutocloseCommit($this->commit);
     }
     return parent::getHeraldField($field);
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $package = new PhabricatorOwnersPackage();
     $owner = new PhabricatorOwnersOwner();
     $path = new PhabricatorOwnersPath();
     $repository_phid = '';
     if ($request->getStr('repository') != '') {
         $repository_phid = id(new PhabricatorRepositoryQuery())->setViewer($user)->withCallsigns(array($request->getStr('repository')))->executeOne()->getPHID();
     }
     switch ($this->view) {
         case 'search':
             $packages = array();
             $conn_r = $package->establishConnection('r');
             $where = array('1 = 1');
             $join = array();
             $having = '';
             if ($request->getStr('name')) {
                 $where[] = qsprintf($conn_r, 'p.name LIKE %~', $request->getStr('name'));
             }
             if ($repository_phid || $request->getStr('path')) {
                 $join[] = qsprintf($conn_r, 'JOIN %T path ON path.packageID = p.id', $path->getTableName());
                 if ($repository_phid) {
                     $where[] = qsprintf($conn_r, 'path.repositoryPHID = %s', $repository_phid);
                 }
                 if ($request->getStr('path')) {
                     $where[] = qsprintf($conn_r, '(path.path LIKE %~ AND NOT path.excluded) OR
             %s LIKE CONCAT(REPLACE(path.path, %s, %s), %s)', $request->getStr('path'), $request->getStr('path'), '_', '\\_', '%');
                     $having = 'HAVING MAX(path.excluded) = 0';
                 }
             }
             if ($request->getArr('owner')) {
                 $join[] = qsprintf($conn_r, 'JOIN %T o ON o.packageID = p.id', $owner->getTableName());
                 $where[] = qsprintf($conn_r, 'o.userPHID IN (%Ls)', $request->getArr('owner'));
             }
             $data = queryfx_all($conn_r, 'SELECT p.* FROM %T p %Q WHERE %Q GROUP BY p.id %Q', $package->getTableName(), implode(' ', $join), '(' . implode(') AND (', $where) . ')', $having);
             $packages = $package->loadAllFromArray($data);
             $header = pht('Search Results');
             $nodata = pht('No packages match your query.');
             break;
         case 'owned':
             $data = queryfx_all($package->establishConnection('r'), 'SELECT p.* FROM %T p JOIN %T o ON p.id = o.packageID
         WHERE o.userPHID = %s GROUP BY p.id', $package->getTableName(), $owner->getTableName(), $user->getPHID());
             $packages = $package->loadAllFromArray($data);
             $header = pht('Owned Packages');
             $nodata = pht('No owned packages');
             break;
         case 'projects':
             $projects = id(new PhabricatorProjectQuery())->setViewer($user)->withMemberPHIDs(array($user->getPHID()))->withStatus(PhabricatorProjectQuery::STATUS_ANY)->execute();
             $owner_phids = mpull($projects, 'getPHID');
             if ($owner_phids) {
                 $data = queryfx_all($package->establishConnection('r'), 'SELECT p.* FROM %T p JOIN %T o ON p.id = o.packageID
           WHERE o.userPHID IN (%Ls) GROUP BY p.id', $package->getTableName(), $owner->getTableName(), $owner_phids);
             } else {
                 $data = array();
             }
             $packages = $package->loadAllFromArray($data);
             $header = pht('Owned Packages');
             $nodata = pht('No owned packages');
             break;
         case 'all':
             $packages = $package->loadAll();
             $header = pht('All Packages');
             $nodata = pht('There are no defined packages.');
             break;
     }
     $content = $this->renderPackageTable($packages, $header, $nodata);
     $filter = new AphrontListFilterView();
     $owners_search_value = array();
     if ($request->getArr('owner')) {
         $phids = $request->getArr('owner');
         $phid = reset($phids);
         $handles = $this->loadViewerHandles(array($phid));
         $owners_search_value = array($handles[$phid]);
     }
     $callsigns = array('' => pht('(Any Repository)'));
     $repositories = id(new PhabricatorRepositoryQuery())->setViewer($user)->setOrder(PhabricatorRepositoryQuery::ORDER_CALLSIGN)->execute();
     foreach ($repositories as $repository) {
         $callsigns[$repository->getCallsign()] = $repository->getCallsign() . ': ' . $repository->getName();
     }
     $form = id(new AphrontFormView())->setUser($user)->setAction('/owners/view/search/')->setMethod('GET')->appendChild(id(new AphrontFormTextControl())->setName('name')->setLabel(pht('Name'))->setValue($request->getStr('name')))->appendChild(id(new AphrontFormTokenizerControl())->setDatasource(new PhabricatorProjectOrUserDatasource())->setLimit(1)->setName('owner')->setLabel(pht('Owner'))->setValue($owners_search_value))->appendChild(id(new AphrontFormSelectControl())->setName('repository')->setLabel(pht('Repository'))->setOptions($callsigns)->setValue($request->getStr('repository')))->appendChild(id(new AphrontFormTextControl())->setName('path')->setLabel(pht('Path'))->setValue($request->getStr('path')))->appendChild(id(new AphrontFormSubmitControl())->setValue(pht('Search for Packages')));
     $filter->appendChild($form);
     $nav = $this->buildSideNavView();
     $nav->appendChild($filter);
     $nav->appendChild($content);
     return $this->buildApplicationPage(array($nav), array('title' => pht('Package Index')));
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $package = new PhabricatorOwnersPackage();
     $owner = new PhabricatorOwnersOwner();
     $path = new PhabricatorOwnersPath();
     $repository_phid = '';
     if ($request->getStr('repository') != '') {
         $repository_phid = id(new PhabricatorRepository())->loadOneWhere('callsign = %s', $request->getStr('repository'))->getPHID();
     }
     switch ($this->view) {
         case 'search':
             $packages = array();
             $conn_r = $package->establishConnection('r');
             $where = array('1 = 1');
             $join = array();
             if ($request->getStr('name')) {
                 $where[] = qsprintf($conn_r, 'p.name LIKE %~', $request->getStr('name'));
             }
             if ($repository_phid || $request->getStr('path')) {
                 $join[] = qsprintf($conn_r, 'JOIN %T path ON path.packageID = p.id', $path->getTableName());
                 if ($repository_phid) {
                     $where[] = qsprintf($conn_r, 'path.repositoryPHID = %s', $repository_phid);
                 }
                 if ($request->getStr('path')) {
                     $where[] = qsprintf($conn_r, 'path.path LIKE %~ OR %s LIKE CONCAT(path.path, %s)', $request->getStr('path'), $request->getStr('path'), '%');
                 }
             }
             if ($request->getArr('owner')) {
                 $join[] = qsprintf($conn_r, 'JOIN %T o ON o.packageID = p.id', $owner->getTableName());
                 $where[] = qsprintf($conn_r, 'o.userPHID IN (%Ls)', $request->getArr('owner'));
             }
             $data = queryfx_all($conn_r, 'SELECT p.* FROM %T p %Q WHERE %Q GROUP BY p.id', $package->getTableName(), implode(' ', $join), '(' . implode(') AND (', $where) . ')');
             $packages = $package->loadAllFromArray($data);
             $header = 'Search Results';
             $nodata = 'No packages match your query.';
             break;
         case 'owned':
             $data = queryfx_all($package->establishConnection('r'), 'SELECT p.* FROM %T p JOIN %T o ON p.id = o.packageID
         WHERE o.userPHID = %s GROUP BY p.id', $package->getTableName(), $owner->getTableName(), $user->getPHID());
             $packages = $package->loadAllFromArray($data);
             $header = 'Owned Packages';
             $nodata = 'No owned packages';
             break;
         case 'all':
             $packages = $package->loadAll();
             $header = 'All Packages';
             $nodata = 'There are no defined packages.';
             break;
     }
     $content = $this->renderPackageTable($packages, $header, $nodata);
     $filter = new AphrontListFilterView();
     $filter->addButton(phutil_render_tag('a', array('href' => '/owners/new/', 'class' => 'green button'), 'Create New Package'));
     $owners_search_value = array();
     if ($request->getArr('owner')) {
         $phids = $request->getArr('owner');
         $phid = reset($phids);
         $handles = id(new PhabricatorObjectHandleData(array($phid)))->loadHandles();
         $owners_search_value = array($phid => $handles[$phid]->getFullName());
     }
     $callsigns = array('' => '(Any Repository)');
     $repositories = id(new PhabricatorRepository())->loadAllWhere('1 = 1 ORDER BY callsign');
     foreach ($repositories as $repository) {
         $callsigns[$repository->getCallsign()] = $repository->getCallsign() . ': ' . $repository->getName();
     }
     $form = id(new AphrontFormView())->setUser($user)->setAction('/owners/view/search/')->setMethod('GET')->appendChild(id(new AphrontFormTextControl())->setName('name')->setLabel('Name')->setValue($request->getStr('name')))->appendChild(id(new AphrontFormTokenizerControl())->setDatasource('/typeahead/common/usersorprojects/')->setLimit(1)->setName('owner')->setLabel('Owner')->setValue($owners_search_value))->appendChild(id(new AphrontFormSelectControl())->setName('repository')->setLabel('Repository')->setOptions($callsigns)->setValue($request->getStr('repository')))->appendChild(id(new AphrontFormTextControl())->setName('path')->setLabel('Path')->setValue($request->getStr('path')))->appendChild(id(new AphrontFormSubmitControl())->setValue('Search for Packages'));
     $filter->appendChild($form);
     return $this->buildStandardPageResponse(array($filter, $content), array('title' => 'Package Index'));
 }