diff --git a/src/applications/differential/conduit/ConduitAPI_differential_close_Method.php b/src/applications/differential/conduit/ConduitAPI_differential_close_Method.php index f7bbe40d5..f59aff276 100644 --- a/src/applications/differential/conduit/ConduitAPI_differential_close_Method.php +++ b/src/applications/differential/conduit/ConduitAPI_differential_close_Method.php @@ -1,66 +1,69 @@ <?php /** * @group conduit */ final class ConduitAPI_differential_close_Method extends ConduitAPIMethod { public function getMethodDescription() { return "Close a Differential revision."; } public function defineParamTypes() { return array( 'revisionID' => 'required int', ); } public function defineReturnType() { return 'void'; } public function defineErrorTypes() { return array( 'ERR_NOT_FOUND' => 'Revision was not found.', ); } protected function execute(ConduitAPIRequest $request) { $id = $request->getValue('revisionID'); - $revision = id(new DifferentialRevision())->load($id); + $revision = id(new DifferentialRevisionQuery()) + ->withIDs(array($id)) + ->setViewer($request->getUser()) + ->needRelationships(true) + ->needReviewerStatus(true) + ->executeOne(); if (!$revision) { throw new ConduitException('ERR_NOT_FOUND'); } if ($revision->getStatus() == ArcanistDifferentialRevisionStatus::CLOSED) { // This can occur if someone runs 'close-revision' and hits a race, or // they have a remote hook installed but don't have the // 'remote_hook_installed' flag set, or similar. In any case, just treat // it as a no-op rather than adding another "X closed this revision" // message to the revision comments. return; } - $revision->loadRelationships(); - $content_source = PhabricatorContentSource::newForSource( PhabricatorContentSource::SOURCE_CONDUIT, array()); $editor = new DifferentialCommentEditor( $revision, DifferentialAction::ACTION_CLOSE); $editor->setContentSource($content_source); $editor->setActor($request->getUser()); $editor->save(); $revision->setStatus(ArcanistDifferentialRevisionStatus::CLOSED); $revision->setDateCommitted(time()); $revision->save(); return; } } diff --git a/src/applications/differential/conduit/ConduitAPI_differential_getcommitmessage_Method.php b/src/applications/differential/conduit/ConduitAPI_differential_getcommitmessage_Method.php index 7bd90f6ca..c8d000f71 100644 --- a/src/applications/differential/conduit/ConduitAPI_differential_getcommitmessage_Method.php +++ b/src/applications/differential/conduit/ConduitAPI_differential_getcommitmessage_Method.php @@ -1,156 +1,162 @@ <?php /** * @group conduit */ final class ConduitAPI_differential_getcommitmessage_Method extends ConduitAPIMethod { public function getMethodDescription() { return "Retrieve Differential commit messages or message templates."; } public function defineParamTypes() { return array( 'revision_id' => 'optional revision_id', 'fields' => 'optional dict<string, wild>', 'edit' => 'optional enum<"edit", "create">', ); } public function defineReturnType() { return 'nonempty string'; } public function defineErrorTypes() { return array( 'ERR_NOT_FOUND' => 'Revision was not found.', ); } protected function execute(ConduitAPIRequest $request) { $id = $request->getValue('revision_id'); if ($id) { - $revision = id(new DifferentialRevision())->load($id); + $revision = id(new DifferentialRevisionQuery()) + ->withIDs(array($id)) + ->setViewer($request->getUser()) + ->needRelationships(true) + ->needReviewerStatus(true) + ->executeOne(); + if (!$revision) { throw new ConduitException('ERR_NOT_FOUND'); } } else { $revision = new DifferentialRevision(); + $revision->attachRelationships(array()); } - $revision->loadRelationships(); $is_edit = $request->getValue('edit'); $is_create = ($is_edit == 'create'); $aux_fields = DifferentialFieldSelector::newSelector() ->getFieldSpecifications(); $pro_tips = array(); foreach ($aux_fields as $key => $aux_field) { $aux_field->setUser($request->getUser()); $aux_field->setRevision($revision); $pro_tips[] = $aux_field->getCommitMessageTips(); if (!$aux_field->shouldAppearOnCommitMessage()) { unset($aux_fields[$key]); } } $aux_fields = DifferentialAuxiliaryField::loadFromStorage( $revision, $aux_fields); $aux_fields = mpull($aux_fields, null, 'getCommitMessageKey'); if ($is_edit) { $fields = $request->getValue('fields'); if (!is_array($fields)) { $fields = array(); } foreach ($fields as $field => $value) { $aux_field = idx($aux_fields, $field); if (!$aux_field) { throw new Exception( "Commit message includes field '{$field}' which does not ". "correspond to any configured field."); } if ($is_create || $aux_field->shouldOverwriteWhenCommitMessageIsEdited()) { $aux_field->setValueFromParsedCommitMessage($value); } } } $aux_phids = array(); foreach ($aux_fields as $field_key => $field) { $aux_phids[$field_key] = $field->getRequiredHandlePHIDsForCommitMessage(); } $phids = array_unique(array_mergev($aux_phids)); $handles = id(new PhabricatorObjectHandleData($phids)) ->setViewer($request->getUser()) ->loadHandles(); foreach ($aux_fields as $field_key => $field) { $field->setHandles(array_select_keys($handles, $aux_phids[$field_key])); } $commit_message = array(); foreach ($aux_fields as $field_key => $field) { $value = $field->renderValueForCommitMessage($is_edit); $label = $field->renderLabelForCommitMessage(); if (!strlen($value)) { if ($field_key === 'title') { $commit_message[] = DifferentialTitleFieldSpecification::getDefaultRevisionTitle(); } else { if ($field->shouldAppearOnCommitMessageTemplate() && $is_edit) { $commit_message[] = $label.': '; } } } else { if ($field_key === 'title') { $commit_message[] = $value; } else { $value = str_replace( array("\r\n", "\r"), array("\n", "\n"), $value); if (strpos($value, "\n") !== false || substr($value, 0, 2) === ' ') { $commit_message[] = "{$label}:\n{$value}"; } else { $commit_message[] = "{$label}: {$value}"; } } } } if ($is_edit) { $pro_tips = array_mergev($pro_tips); if (!empty($pro_tips)) { shuffle($pro_tips); $pro_tip = "Tip: ".$pro_tips[0]; $pro_tip = wordwrap($pro_tip, 78, "\n", true); $lines = explode("\n", $pro_tip); foreach ($lines as $key => $line) { $lines[$key] = "# ".$line; } $pro_tip = implode("\n", $lines); $commit_message[] = $pro_tip; } } $commit_message = implode("\n\n", $commit_message); return $commit_message; } } diff --git a/src/applications/differential/conduit/ConduitAPI_differential_getrevision_Method.php b/src/applications/differential/conduit/ConduitAPI_differential_getrevision_Method.php index e2ce4aeac..ef4669aa3 100644 --- a/src/applications/differential/conduit/ConduitAPI_differential_getrevision_Method.php +++ b/src/applications/differential/conduit/ConduitAPI_differential_getrevision_Method.php @@ -1,119 +1,124 @@ <?php /** * @group conduit */ final class ConduitAPI_differential_getrevision_Method extends ConduitAPIMethod { public function getMethodStatus() { return self::METHOD_STATUS_DEPRECATED; } public function getMethodStatusDescription() { return "Replaced by 'differential.query'."; } public function getMethodDescription() { return "Load the content of a revision from Differential."; } public function defineParamTypes() { return array( 'revision_id' => 'required id', ); } public function defineReturnType() { return 'nonempty dict'; } public function defineErrorTypes() { return array( 'ERR_BAD_REVISION' => 'No such revision exists.', ); } protected function execute(ConduitAPIRequest $request) { $diff = null; $revision_id = $request->getValue('revision_id'); - $revision = id(new DifferentialRevision())->load($revision_id); + $revision = id(new DifferentialRevisionQuery()) + ->withIDs(array($revision_id)) + ->setViewer($request->getUser()) + ->needRelationships(true) + ->needReviewerStatus(true) + ->executeOne(); + if (!$revision) { throw new ConduitException('ERR_BAD_REVISION'); } - $revision->loadRelationships(); $reviewer_phids = array_values($revision->getReviewers()); $diffs = $revision->loadDiffs(); $diff_dicts = array(); foreach ($diffs as $diff) { $diff->attachChangesets($diff->loadChangesets()); // TODO: We could batch this to improve performance. foreach ($diff->getChangesets() as $changeset) { $changeset->attachHunks($changeset->loadHunks()); } $diff_dicts[] = $diff->getDiffDict(); } $commit_dicts = array(); $commit_phids = $revision->loadCommitPHIDs(); $handles = id(new PhabricatorObjectHandleData($commit_phids)) ->setViewer($request->getUser()) ->loadHandles(); foreach ($commit_phids as $commit_phid) { $commit_dicts[] = array( 'fullname' => $handles[$commit_phid]->getFullName(), 'dateCommitted' => $handles[$commit_phid]->getTimestamp(), ); } $auxiliary_fields = $this->loadAuxiliaryFields( $revision, $request->getUser()); $dict = array( 'id' => $revision->getID(), 'phid' => $revision->getPHID(), 'authorPHID' => $revision->getAuthorPHID(), 'uri' => PhabricatorEnv::getURI('/D'.$revision->getID()), 'title' => $revision->getTitle(), 'status' => $revision->getStatus(), 'statusName' => ArcanistDifferentialRevisionStatus::getNameForRevisionStatus( $revision->getStatus()), 'summary' => $revision->getSummary(), 'testPlan' => $revision->getTestPlan(), 'lineCount' => $revision->getLineCount(), 'reviewerPHIDs' => $reviewer_phids, 'diffs' => $diff_dicts, 'commits' => $commit_dicts, 'auxiliary' => $auxiliary_fields, ); return $dict; } private function loadAuxiliaryFields( DifferentialRevision $revision, PhabricatorUser $user) { $aux_fields = DifferentialFieldSelector::newSelector() ->getFieldSpecifications(); foreach ($aux_fields as $key => $aux_field) { $aux_field->setUser($user); if (!$aux_field->shouldAppearOnConduitView()) { unset($aux_fields[$key]); } } $aux_fields = DifferentialAuxiliaryField::loadFromStorage( $revision, $aux_fields); return mpull($aux_fields, 'getValueForConduit', 'getKeyForConduit'); } } diff --git a/src/applications/differential/conduit/ConduitAPI_differential_markcommitted_Method.php b/src/applications/differential/conduit/ConduitAPI_differential_markcommitted_Method.php index e0328b66a..7bba22c24 100644 --- a/src/applications/differential/conduit/ConduitAPI_differential_markcommitted_Method.php +++ b/src/applications/differential/conduit/ConduitAPI_differential_markcommitted_Method.php @@ -1,59 +1,62 @@ <?php /** * @group conduit * @deprecated */ final class ConduitAPI_differential_markcommitted_Method extends ConduitAPIMethod { public function getMethodStatus() { return self::METHOD_STATUS_DEPRECATED; } public function getMethodStatusDescription() { return "Replaced by 'differential.close'."; } public function getMethodDescription() { return "Mark a revision closed."; } public function defineParamTypes() { return array( 'revision_id' => 'required revision_id', ); } public function defineReturnType() { return 'void'; } public function defineErrorTypes() { return array( 'ERR_NOT_FOUND' => 'Revision was not found.', ); } protected function execute(ConduitAPIRequest $request) { $id = $request->getValue('revision_id'); - $revision = id(new DifferentialRevision())->load($id); + $revision = id(new DifferentialRevisionQuery()) + ->withIDs(array($id)) + ->setViewer($request->getUser()) + ->needRelationships(true) + ->needReviewerStatus(true) + ->executeOne(); if (!$revision) { throw new ConduitException('ERR_NOT_FOUND'); } if ($revision->getStatus() == ArcanistDifferentialRevisionStatus::CLOSED) { return; } - $revision->loadRelationships(); - $editor = new DifferentialCommentEditor( $revision, DifferentialAction::ACTION_CLOSE); $editor->setActor($request->getUser()); $editor->save(); } }