Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/differential/controller/DifferentialCommentPreviewController.php b/src/applications/differential/controller/DifferentialCommentPreviewController.php
index 66d1cc9338..706c2dcaf2 100644
--- a/src/applications/differential/controller/DifferentialCommentPreviewController.php
+++ b/src/applications/differential/controller/DifferentialCommentPreviewController.php
@@ -1,145 +1,139 @@
<?php
final class DifferentialCommentPreviewController
extends DifferentialController {
- private $id;
-
- public function willProcessRequest(array $data) {
- $this->id = $data['id'];
- }
-
- public function processRequest() {
- $request = $this->getRequest();
- $viewer = $request->getUser();
+ public function handleRequest(AphrontRequest $request) {
+ $viewer = $this->getViewer();
+ $id = $request->getURIData('id');
$revision = id(new DifferentialRevisionQuery())
->setViewer($viewer)
- ->withIDs(array($this->id))
+ ->withIDs(array($id))
->executeOne();
if (!$revision) {
return new Aphront404Response();
}
$type_comment = PhabricatorTransactions::TYPE_COMMENT;
$type_action = DifferentialTransaction::TYPE_ACTION;
$type_edge = PhabricatorTransactions::TYPE_EDGE;
$type_subscribers = PhabricatorTransactions::TYPE_SUBSCRIBERS;
$xactions = array();
$action = $request->getStr('action');
switch ($action) {
case DifferentialAction::ACTION_COMMENT:
case DifferentialAction::ACTION_ADDREVIEWERS:
case DifferentialAction::ACTION_ADDCCS:
break;
default:
$xactions[] = id(new DifferentialTransaction())
->setTransactionType($type_action)
->setNewValue($action);
break;
}
$edge_reviewer = DifferentialRevisionHasReviewerEdgeType::EDGECONST;
$reviewers = $request->getStrList('reviewers');
if (DifferentialAction::allowReviewers($action) && $reviewers) {
$faux_edges = array();
foreach ($reviewers as $phid) {
$faux_edges[$phid] = array(
'src' => $revision->getPHID(),
'type' => $edge_reviewer,
'dst' => $phid,
);
}
$xactions[] = id(new DifferentialTransaction())
->setTransactionType($type_edge)
->setMetadataValue('edge:type', $edge_reviewer)
->setOldValue(array())
->setNewValue($faux_edges);
}
$ccs = $request->getStrList('ccs');
if ($ccs) {
$xactions[] = id(new DifferentialTransaction())
->setTransactionType($type_subscribers)
->setOldValue(array())
->setNewValue(array_fuse($ccs));
}
// Add a comment transaction if there's nothing, so we'll generate a
// nonempty result.
if (strlen($request->getStr('content')) || !$xactions) {
$xactions[] = id(new DifferentialTransaction())
->setTransactionType($type_comment)
->attachComment(
id(new ManiphestTransactionComment())
->setContent($request->getStr('content')));
}
foreach ($xactions as $xaction) {
$xaction->setAuthorPHID($viewer->getPHID());
}
$engine = new PhabricatorMarkupEngine();
$engine->setViewer($request->getUser());
foreach ($xactions as $xaction) {
if ($xaction->hasComment()) {
$engine->addObject(
$xaction->getComment(),
PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT);
}
}
$engine->process();
$phids = mpull($xactions, 'getRequiredHandlePHIDs');
$phids = array_mergev($phids);
$handles = id(new PhabricatorHandleQuery())
->setViewer($viewer)
->withPHIDs($phids)
->execute();
foreach ($xactions as $xaction) {
$xaction->setHandles($handles);
}
$view = id(new DifferentialTransactionView())
->setUser($viewer)
->setTransactions($xactions)
->setIsPreview(true);
$metadata = array(
'reviewers' => $reviewers,
'ccs' => $ccs,
);
if ($action != DifferentialAction::ACTION_COMMENT) {
$metadata['action'] = $action;
}
- $draft_key = 'differential-comment-'.$this->id;
+ $draft_key = 'differential-comment-'.$id;
$draft = id(new PhabricatorDraft())
->setAuthorPHID($viewer->getPHID())
->setDraftKey($draft_key)
->setDraft($request->getStr('content'))
->setMetadata($metadata)
->replaceOrDelete();
if ($draft->isDeleted()) {
DifferentialDraft::deleteHasDraft(
$viewer->getPHID(),
$revision->getPHID(),
$draft_key);
} else {
DifferentialDraft::markHasDraft(
$viewer->getPHID(),
$revision->getPHID(),
$draft_key);
}
return id(new AphrontAjaxResponse())
->setContent((string)phutil_implode_html('', $view->buildEvents()));
}
}
diff --git a/src/applications/differential/controller/DifferentialCommentSaveController.php b/src/applications/differential/controller/DifferentialCommentSaveController.php
index 7d918a792c..831d7c90c8 100644
--- a/src/applications/differential/controller/DifferentialCommentSaveController.php
+++ b/src/applications/differential/controller/DifferentialCommentSaveController.php
@@ -1,149 +1,143 @@
<?php
final class DifferentialCommentSaveController
extends DifferentialController {
- private $id;
-
- public function willProcessRequest(array $data) {
- $this->id = $data['id'];
- }
-
- public function processRequest() {
- $request = $this->getRequest();
- $viewer = $request->getUser();
+ public function handleRequest(AphrontRequest $request) {
+ $viewer = $this->getViewer();
+ $id = $request->getURIData('id');
if (!$request->isFormPost()) {
return new Aphront400Response();
}
$revision = id(new DifferentialRevisionQuery())
->setViewer($viewer)
- ->withIDs(array($this->id))
+ ->withIDs(array($id))
->needReviewerStatus(true)
->needReviewerAuthority(true)
->executeOne();
if (!$revision) {
return new Aphront404Response();
}
$type_action = DifferentialTransaction::TYPE_ACTION;
$type_subscribers = PhabricatorTransactions::TYPE_SUBSCRIBERS;
$type_edge = PhabricatorTransactions::TYPE_EDGE;
$type_comment = PhabricatorTransactions::TYPE_COMMENT;
$type_inline = DifferentialTransaction::TYPE_INLINE;
$edge_reviewer = DifferentialRevisionHasReviewerEdgeType::EDGECONST;
$xactions = array();
$action = $request->getStr('action');
switch ($action) {
case DifferentialAction::ACTION_COMMENT:
case DifferentialAction::ACTION_ADDREVIEWERS:
case DifferentialAction::ACTION_ADDCCS:
// These transaction types have no direct effect, they just
// accompany other transaction types which can have an effect.
break;
default:
$xactions[] = id(new DifferentialTransaction())
->setTransactionType($type_action)
->setNewValue($request->getStr('action'));
break;
}
$ccs = $request->getArr('ccs');
if ($ccs) {
$xactions[] = id(new DifferentialTransaction())
->setTransactionType($type_subscribers)
->setNewValue(array('+' => $ccs));
}
$current_reviewers = mpull(
$revision->getReviewerStatus(),
null,
'getReviewerPHID');
$reviewer_edges = array();
$add_reviewers = $request->getArr('reviewers');
foreach ($add_reviewers as $reviewer_phid) {
if (isset($current_reviewers[$reviewer_phid])) {
continue;
}
$reviewer = new DifferentialReviewer(
$reviewer_phid,
array(
'status' => DifferentialReviewerStatus::STATUS_ADDED,
));
$reviewer_edges[$reviewer_phid] = array(
'data' => $reviewer->getEdgeData(),
);
}
if ($add_reviewers) {
$xactions[] = id(new DifferentialTransaction())
->setTransactionType($type_edge)
->setMetadataValue('edge:type', $edge_reviewer)
->setNewValue(array('+' => $reviewer_edges));
}
$inlines = DifferentialTransactionQuery::loadUnsubmittedInlineComments(
$viewer,
$revision);
foreach ($inlines as $inline) {
$xactions[] = id(new DifferentialTransaction())
->setTransactionType($type_inline)
->attachComment($inline);
}
// NOTE: If there are no other transactions, add an empty comment
// transaction so that we'll raise a more user-friendly error message,
// to the effect of "you can not post an empty comment".
$no_xactions = !$xactions;
$comment = $request->getStr('comment');
if (strlen($comment) || $no_xactions) {
$xactions[] = id(new DifferentialTransaction())
->setTransactionType($type_comment)
->attachComment(
id(new DifferentialTransactionComment())
->setRevisionPHID($revision->getPHID())
->setContent($comment));
}
$editor = id(new DifferentialTransactionEditor())
->setActor($viewer)
->setContentSourceFromRequest($request)
->setContinueOnMissingFields(true)
->setContinueOnNoEffect($request->isContinueRequest());
$revision_uri = '/D'.$revision->getID();
try {
$editor->applyTransactions($revision, $xactions);
} catch (PhabricatorApplicationTransactionNoEffectException $ex) {
return id(new PhabricatorApplicationTransactionNoEffectResponse())
->setCancelURI($revision_uri)
->setException($ex);
} catch (PhabricatorApplicationTransactionValidationException $ex) {
return id(new PhabricatorApplicationTransactionValidationResponse())
->setCancelURI($revision_uri)
->setException($ex);
}
$user = $request->getUser();
$draft = id(new PhabricatorDraft())->loadOneWhere(
'authorPHID = %s AND draftKey = %s',
$user->getPHID(),
'differential-comment-'.$revision->getID());
if ($draft) {
$draft->delete();
}
DifferentialDraft::deleteAllDrafts($user->getPHID(), $revision->getPHID());
return id(new AphrontRedirectResponse())
->setURI('/D'.$revision->getID());
}
}
diff --git a/src/applications/differential/controller/DifferentialDiffViewController.php b/src/applications/differential/controller/DifferentialDiffViewController.php
index 6ffd57396c..716a183b5b 100644
--- a/src/applications/differential/controller/DifferentialDiffViewController.php
+++ b/src/applications/differential/controller/DifferentialDiffViewController.php
@@ -1,199 +1,193 @@
<?php
final class DifferentialDiffViewController extends DifferentialController {
- private $id;
-
public function shouldAllowPublic() {
return true;
}
- public function willProcessRequest(array $data) {
- $this->id = $data['id'];
- }
-
- public function processRequest() {
- $request = $this->getRequest();
- $viewer = $request->getUser();
+ public function handleRequest(AphrontRequest $request) {
+ $viewer = $this->getViewer();
+ $id = $request->getURIData('id');
$diff = id(new DifferentialDiffQuery())
->setViewer($viewer)
- ->withIDs(array($this->id))
+ ->withIDs(array($id))
->executeOne();
if (!$diff) {
return new Aphront404Response();
}
if ($diff->getRevisionID()) {
return id(new AphrontRedirectResponse())
->setURI('/D'.$diff->getRevisionID().'?id='.$diff->getID());
}
$diff_phid = $diff->getPHID();
$buildables = id(new HarbormasterBuildableQuery())
->setViewer($viewer)
->withBuildablePHIDs(array($diff_phid))
->withManualBuildables(false)
->needBuilds(true)
->needTargets(true)
->execute();
$buildables = mpull($buildables, null, 'getBuildablePHID');
$diff->attachBuildable(idx($buildables, $diff_phid));
// TODO: implement optgroup support in AphrontFormSelectControl?
$select = array();
$select[] = hsprintf('<optgroup label="%s">', pht('Create New Revision'));
$select[] = phutil_tag(
'option',
array('value' => ''),
pht('Create a new Revision...'));
$select[] = hsprintf('</optgroup>');
$selected_id = $request->getInt('revisionID');
$revisions = $this->loadSelectableRevisions($viewer, $selected_id);
if ($revisions) {
$select[] = hsprintf(
'<optgroup label="%s">',
pht('Update Existing Revision'));
foreach ($revisions as $revision) {
if ($selected_id == $revision->getID()) {
$selected = 'selected';
} else {
$selected = null;
}
$select[] = phutil_tag(
'option',
array(
'value' => $revision->getID(),
'selected' => $selected,
),
id(new PhutilUTF8StringTruncator())
->setMaximumGlyphs(128)
->truncateString(
'D'.$revision->getID().' '.$revision->getTitle()));
}
$select[] = hsprintf('</optgroup>');
}
$select = phutil_tag(
'select',
array('name' => 'revisionID'),
$select);
$form = id(new AphrontFormView())
->setUser($request->getUser())
->setAction('/differential/revision/edit/')
->addHiddenInput('diffID', $diff->getID())
->addHiddenInput('viaDiffView', 1)
->addHiddenInput(
id(new DifferentialRepositoryField())->getFieldKey(),
$diff->getRepositoryPHID())
->appendRemarkupInstructions(
pht(
'Review the diff for correctness. When you are satisfied, either '.
'**create a new revision** or **update an existing revision**.'))
->appendChild(
id(new AphrontFormMarkupControl())
->setLabel(pht('Attach To'))
->setValue($select))
->appendChild(
id(new AphrontFormSubmitControl())
->setValue(pht('Continue')));
$props = id(new DifferentialDiffProperty())->loadAllWhere(
'diffID = %d',
$diff->getID());
$props = mpull($props, 'getData', 'getName');
$property_head = id(new PHUIHeaderView())
->setHeader(pht('Properties'));
$property_view = new PHUIPropertyListView();
$changesets = $diff->loadChangesets();
$changesets = msort($changesets, 'getSortKey');
$table_of_contents = $this->buildTableOfContents(
$changesets,
$changesets,
$diff->loadCoverageMap($viewer));
$refs = array();
foreach ($changesets as $changeset) {
$refs[$changeset->getID()] = $changeset->getID();
}
$details = id(new DifferentialChangesetListView())
->setChangesets($changesets)
->setVisibleChangesets($changesets)
->setRenderingReferences($refs)
->setStandaloneURI('/differential/changeset/')
->setDiff($diff)
->setTitle(pht('Diff %d', $diff->getID()))
->setUser($request->getUser());
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Diff %d', $diff->getID()));
$prop_box = id(new PHUIObjectBoxView())
->setHeader($property_head)
->addPropertyList($property_view)
->setForm($form);
return $this->buildApplicationPage(
array(
$crumbs,
$prop_box,
$table_of_contents,
$details,
),
array(
'title' => pht('Diff View'),
));
}
private function loadSelectableRevisions(
PhabricatorUser $viewer,
$selected_id) {
$revisions = id(new DifferentialRevisionQuery())
->setViewer($viewer)
->withAuthors(array($viewer->getPHID()))
->withStatus(DifferentialRevisionQuery::STATUS_OPEN)
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->execute();
$revisions = mpull($revisions, null, 'getID');
// If a specific revision is selected (for example, because the user is
// following the "Update Diff" workflow), but not present in the dropdown,
// try to add it to the dropdown even if it is closed. This allows the
// workflow to be used to update abandoned revisions.
if ($selected_id) {
if (empty($revisions[$selected_id])) {
$selected = id(new DifferentialRevisionQuery())
->setViewer($viewer)
->withAuthors(array($viewer->getPHID()))
->withIDs(array($selected_id))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->execute();
$revisions = mpull($selected, null, 'getID') + $revisions;
}
}
return $revisions;
}
}
diff --git a/src/applications/differential/controller/DifferentialRevisionCloseDetailsController.php b/src/applications/differential/controller/DifferentialRevisionCloseDetailsController.php
index 25051bcbb5..d5a7d897a8 100644
--- a/src/applications/differential/controller/DifferentialRevisionCloseDetailsController.php
+++ b/src/applications/differential/controller/DifferentialRevisionCloseDetailsController.php
@@ -1,117 +1,108 @@
<?php
final class DifferentialRevisionCloseDetailsController
extends DifferentialController {
- private $phid;
-
- public function willProcessRequest(array $data) {
- $this->phid = idx($data, 'phid');
- }
-
- public function processRequest() {
- $request = $this->getRequest();
-
- $viewer = $request->getUser();
- $xaction_phid = $this->phid;
+ public function handleRequest(AphrontRequest $request) {
+ $viewer = $this->getViewer();
$xaction = id(new PhabricatorObjectQuery())
- ->withPHIDs(array($xaction_phid))
+ ->withPHIDs(array($request->getURIData('phid')))
->setViewer($viewer)
->executeOne();
if (!$xaction) {
return new Aphront404Response();
}
$obj_phid = $xaction->getObjectPHID();
$obj_handle = id(new PhabricatorHandleQuery())
->setViewer($viewer)
->withPHIDs(array($obj_phid))
->executeOne();
$body = $this->getRevisionMatchExplanation(
$xaction->getMetadataValue('revisionMatchData'),
$obj_handle);
$dialog = id(new AphrontDialogView())
->setUser($viewer)
->setTitle(pht('Commit Close Explanation'))
->appendParagraph($body)
->addCancelButton($obj_handle->getURI());
return id(new AphrontDialogResponse())->setDialog($dialog);
}
private function getRevisionMatchExplanation(
$revision_match_data,
PhabricatorObjectHandle $obj_handle) {
if (!$revision_match_data) {
return pht(
'This commit was made before this feature was built and thus this '.
'information is unavailable.');
}
$body_why = array();
if ($revision_match_data['usedURI']) {
return pht(
'We found a "%s" field with value "%s" in the commit message, '.
'and the domain on the URI matches this install, so '.
'we linked this commit to %s.',
'Differential Revision',
$revision_match_data['foundURI'],
phutil_tag(
'a',
array(
'href' => $obj_handle->getURI(),
),
$obj_handle->getName()));
} else if ($revision_match_data['foundURI']) {
$body_why[] = pht(
'We found a "%s" field with value "%s" in the commit message, '.
'but the domain on this URI did not match the configured '.
'domain for this install, "%s", so we ignored it under '.
'the assumption that it refers to some third-party revision.',
'Differential Revision',
$revision_match_data['foundURI'],
$revision_match_data['validDomain']);
} else {
$body_why[] = pht(
'We didn\'t find a "%s" field in the commit message.',
'Differential Revision');
}
switch ($revision_match_data['matchHashType']) {
case ArcanistDifferentialRevisionHash::HASH_GIT_TREE:
$hash_info = true;
$hash_type = 'tree';
break;
case ArcanistDifferentialRevisionHash::HASH_GIT_COMMIT:
case ArcanistDifferentialRevisionHash::HASH_MERCURIAL_COMMIT:
$hash_info = true;
$hash_type = 'commit';
break;
default:
$hash_info = false;
break;
}
if ($hash_info) {
$diff_link = phutil_tag(
'a',
array(
'href' => $obj_handle->getURI(),
),
$obj_handle->getName());
$body_why = pht(
'This commit and the active diff of %s had the same %s hash '.
'(%s) so we linked this commit to %s.',
$diff_link,
$hash_type,
$revision_match_data['matchHashValue'],
$diff_link);
}
return phutil_implode_html("\n", $body_why);
}
}
diff --git a/src/applications/differential/controller/DifferentialRevisionEditController.php b/src/applications/differential/controller/DifferentialRevisionEditController.php
index 1c664f07d2..a52538ca55 100644
--- a/src/applications/differential/controller/DifferentialRevisionEditController.php
+++ b/src/applications/differential/controller/DifferentialRevisionEditController.php
@@ -1,211 +1,205 @@
<?php
final class DifferentialRevisionEditController
extends DifferentialController {
- private $id;
+ public function handleRequest(AphrontRequest $request) {
+ $viewer = $this->getViewer();
+ $id = $request->getURIData('id');
- public function willProcessRequest(array $data) {
- $this->id = idx($data, 'id');
- }
-
- public function processRequest() {
- $request = $this->getRequest();
- $viewer = $request->getUser();
-
- if (!$this->id) {
- $this->id = $request->getInt('revisionID');
+ if (!$id) {
+ $id = $request->getInt('revisionID');
}
- if ($this->id) {
+ if ($id) {
$revision = id(new DifferentialRevisionQuery())
->setViewer($viewer)
- ->withIDs(array($this->id))
+ ->withIDs(array($id))
->needRelationships(true)
->needReviewerStatus(true)
->needActiveDiffs(true)
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$revision) {
return new Aphront404Response();
}
} else {
$revision = DifferentialRevision::initializeNewRevision($viewer);
$revision->attachReviewerStatus(array());
}
$diff_id = $request->getInt('diffID');
if ($diff_id) {
$diff = id(new DifferentialDiffQuery())
->setViewer($viewer)
->withIDs(array($diff_id))
->executeOne();
if (!$diff) {
return new Aphront404Response();
}
if ($diff->getRevisionID()) {
// TODO: Redirect?
throw new Exception(
pht('This diff is already attached to a revision!'));
}
} else {
$diff = null;
}
if (!$diff) {
if (!$revision->getID()) {
throw new Exception(
pht('You can not create a new revision without a diff!'));
}
} else {
// TODO: It would be nice to show the diff being attached in the UI.
}
$field_list = PhabricatorCustomField::getObjectFields(
$revision,
PhabricatorCustomField::ROLE_EDIT);
$field_list
->setViewer($viewer)
->readFieldsFromStorage($revision);
if ($request->getStr('viaDiffView') && $diff) {
$repo_key = id(new DifferentialRepositoryField())->getFieldKey();
$repository_field = idx(
$field_list->getFields(),
$repo_key);
if ($repository_field) {
$repository_field->setValue($request->getStr($repo_key));
}
$view_policy_key = id(new DifferentialViewPolicyField())->getFieldKey();
$view_policy_field = idx(
$field_list->getFields(),
$view_policy_key);
if ($view_policy_field) {
$view_policy_field->setValue($diff->getViewPolicy());
}
}
$validation_exception = null;
if ($request->isFormPost() && !$request->getStr('viaDiffView')) {
$editor = id(new DifferentialTransactionEditor())
->setActor($viewer)
->setContentSourceFromRequest($request)
->setContinueOnNoEffect(true);
$xactions = $field_list->buildFieldTransactionsFromRequest(
new DifferentialTransaction(),
$request);
if ($diff) {
$repository_phid = null;
$repository_tokenizer = $request->getArr(
id(new DifferentialRepositoryField())->getFieldKey());
if ($repository_tokenizer) {
$repository_phid = reset($repository_tokenizer);
}
$xactions[] = id(new DifferentialTransaction())
->setTransactionType(DifferentialTransaction::TYPE_UPDATE)
->setNewValue($diff->getPHID());
$editor->setRepositoryPHIDOverride($repository_phid);
}
$comments = $request->getStr('comments');
if (strlen($comments)) {
$xactions[] = id(new DifferentialTransaction())
->setTransactionType(PhabricatorTransactions::TYPE_COMMENT)
->attachComment(
id(new DifferentialTransactionComment())
->setContent($comments));
}
try {
$editor->applyTransactions($revision, $xactions);
$revision_uri = '/D'.$revision->getID();
return id(new AphrontRedirectResponse())->setURI($revision_uri);
} catch (PhabricatorApplicationTransactionValidationException $ex) {
$validation_exception = $ex;
}
}
$form = new AphrontFormView();
$form->setUser($request->getUser());
if ($diff) {
$form->addHiddenInput('diffID', $diff->getID());
}
if ($revision->getID()) {
$form->setAction('/differential/revision/edit/'.$revision->getID().'/');
} else {
$form->setAction('/differential/revision/edit/');
}
if ($diff && $revision->getID()) {
$form
->appendChild(
id(new AphrontFormTextAreaControl())
->setLabel(pht('Comments'))
->setName('comments')
->setCaption(pht("Explain what's new in this diff."))
->setValue($request->getStr('comments')))
->appendChild(
id(new AphrontFormSubmitControl())
->setValue(pht('Save')))
->appendChild(
id(new AphrontFormDividerControl()));
}
$field_list->appendFieldsToForm($form);
$submit = id(new AphrontFormSubmitControl())
->setValue('Save');
if ($diff) {
$submit->addCancelButton('/differential/diff/'.$diff->getID().'/');
} else {
$submit->addCancelButton('/D'.$revision->getID());
}
$form->appendChild($submit);
$crumbs = $this->buildApplicationCrumbs();
if ($revision->getID()) {
if ($diff) {
$title = pht('Update Differential Revision');
$crumbs->addTextCrumb(
'D'.$revision->getID(),
'/differential/diff/'.$diff->getID().'/');
} else {
$title = pht('Edit Differential Revision');
$crumbs->addTextCrumb(
'D'.$revision->getID(),
'/D'.$revision->getID());
}
} else {
$title = pht('Create New Differential Revision');
}
$form_box = id(new PHUIObjectBoxView())
->setHeaderText($title)
->setValidationException($validation_exception)
->setForm($form);
$crumbs->addTextCrumb($title);
return $this->buildApplicationPage(
array(
$crumbs,
$form_box,
),
array(
'title' => $title,
));
}
}
diff --git a/src/applications/differential/controller/DifferentialRevisionLandController.php b/src/applications/differential/controller/DifferentialRevisionLandController.php
index e19762b44d..4f8787956f 100644
--- a/src/applications/differential/controller/DifferentialRevisionLandController.php
+++ b/src/applications/differential/controller/DifferentialRevisionLandController.php
@@ -1,165 +1,164 @@
<?php
final class DifferentialRevisionLandController extends DifferentialController {
private $revisionID;
private $strategyClass;
private $pushStrategy;
public function willProcessRequest(array $data) {
$this->revisionID = $data['id'];
$this->strategyClass = $data['strategy'];
}
- public function processRequest() {
- $request = $this->getRequest();
- $viewer = $request->getUser();
+ public function handleRequest(AphrontRequest $request) {
+ $viewer = $this->getViewer();
$revision_id = $this->revisionID;
$revision = id(new DifferentialRevisionQuery())
->withIDs(array($revision_id))
->setViewer($viewer)
->executeOne();
if (!$revision) {
return new Aphront404Response();
}
if (is_subclass_of($this->strategyClass, 'DifferentialLandingStrategy')) {
$this->pushStrategy = newv($this->strategyClass, array());
} else {
throw new Exception(
pht(
"Strategy type must be a valid class name and must subclass ".
"%s. '%s' is not a subclass of %s",
'DifferentialLandingStrategy',
$this->strategyClass,
'DifferentialLandingStrategy'));
}
if ($request->isDialogFormPost()) {
$response = null;
$text = '';
try {
$response = $this->attemptLand($revision, $request);
$title = pht('Success!');
$text = pht('Revision was successfully landed.');
} catch (Exception $ex) {
$title = pht('Failed to land revision');
if ($ex instanceof PhutilProxyException) {
$text = hsprintf(
'%s:<br><pre>%s</pre>',
$ex->getMessage(),
$ex->getPreviousException()->getMessage());
} else {
$text = phutil_tag('pre', array(), $ex->getMessage());
}
$text = id(new PHUIInfoView())
->appendChild($text);
}
if ($response instanceof AphrontDialogView) {
$dialog = $response;
} else {
$dialog = id(new AphrontDialogView())
->setUser($viewer)
->setTitle($title)
->appendChild(phutil_tag('p', array(), $text))
->addCancelButton('/D'.$revision_id, pht('Done'));
}
return id(new AphrontDialogResponse())->setDialog($dialog);
}
$is_disabled = $this->pushStrategy->isActionDisabled(
$viewer,
$revision,
$revision->getRepository());
if ($is_disabled) {
if (is_string($is_disabled)) {
$explain = $is_disabled;
} else {
$explain = pht('This action is not currently enabled.');
}
$dialog = id(new AphrontDialogView())
->setUser($viewer)
->setTitle(pht("Can't land revision"))
->appendChild($explain)
->addCancelButton('/D'.$revision_id);
return id(new AphrontDialogResponse())->setDialog($dialog);
}
$prompt = hsprintf('%s<br><br>%s',
pht(
'This will squash and rebase revision %s, and push it to '.
'the default / master branch.',
$revision_id),
pht('It is an experimental feature and may not work.'));
$dialog = id(new AphrontDialogView())
->setUser($viewer)
->setTitle(pht('Land Revision %s?', $revision_id))
->appendChild($prompt)
->setSubmitURI($request->getRequestURI())
->addSubmitButton(pht('Land it!'))
->addCancelButton('/D'.$revision_id);
return id(new AphrontDialogResponse())->setDialog($dialog);
}
private function attemptLand($revision, $request) {
$status = $revision->getStatus();
if ($status != ArcanistDifferentialRevisionStatus::ACCEPTED) {
throw new Exception(pht('Only Accepted revisions can be landed.'));
}
$repository = $revision->getRepository();
if ($repository === null) {
throw new Exception(pht('Revision is not attached to a repository.'));
}
$can_push = PhabricatorPolicyFilter::hasCapability(
$request->getUser(),
$repository,
DiffusionPushCapability::CAPABILITY);
if (!$can_push) {
throw new Exception(
pht('You do not have permission to push to this repository.'));
}
$lock = $this->lockRepository($repository);
try {
$response = $this->pushStrategy->processLandRequest(
$request,
$revision,
$repository);
} catch (Exception $e) {
$lock->unlock();
throw $e;
}
$lock->unlock();
$looksoon = new ConduitCall(
'diffusion.looksoon',
array(
'callsigns' => array($repository->getCallsign()),
));
$looksoon->setUser($request->getUser());
$looksoon->execute();
return $response;
}
private function lockRepository($repository) {
$lock_name = __CLASS__.':'.($repository->getCallsign());
$lock = PhabricatorGlobalLock::newLock($lock_name);
$lock->lock();
return $lock;
}
}
diff --git a/src/applications/differential/controller/DifferentialRevisionListController.php b/src/applications/differential/controller/DifferentialRevisionListController.php
index e48b088e6b..29567a53bf 100644
--- a/src/applications/differential/controller/DifferentialRevisionListController.php
+++ b/src/applications/differential/controller/DifferentialRevisionListController.php
@@ -1,36 +1,30 @@
<?php
final class DifferentialRevisionListController extends DifferentialController {
- private $queryKey;
-
public function shouldAllowPublic() {
return true;
}
- public function willProcessRequest(array $data) {
- $this->queryKey = idx($data, 'queryKey');
- }
-
- public function processRequest() {
+ public function handleRequest(AphrontRequest $request) {
$controller = id(new PhabricatorApplicationSearchController())
- ->setQueryKey($this->queryKey)
+ ->setQueryKey($request->getURIData('queryKey'))
->setSearchEngine(new DifferentialRevisionSearchEngine())
->setNavigation($this->buildSideNavView());
return $this->delegateToController($controller);
}
protected function buildApplicationCrumbs() {
$crumbs = parent::buildApplicationCrumbs();
$crumbs->addAction(
id(new PHUIListItemView())
->setHref($this->getApplicationURI('/diff/create/'))
->setName(pht('Create Diff'))
->setIcon('fa-plus-square'));
return $crumbs;
}
}
diff --git a/src/applications/differential/controller/DifferentialRevisionViewController.php b/src/applications/differential/controller/DifferentialRevisionViewController.php
index 4af487252c..f748b8d9d5 100644
--- a/src/applications/differential/controller/DifferentialRevisionViewController.php
+++ b/src/applications/differential/controller/DifferentialRevisionViewController.php
@@ -1,1039 +1,1035 @@
<?php
final class DifferentialRevisionViewController extends DifferentialController {
private $revisionID;
public function shouldAllowPublic() {
return true;
}
- public function willProcessRequest(array $data) {
- $this->revisionID = $data['id'];
- }
-
- public function processRequest() {
+ public function handleRequest(AphrontRequest $request) {
+ $viewer = $this->getViewer();
+ $this->revisionID = $request->getURIData('id');
- $request = $this->getRequest();
- $user = $request->getUser();
- $viewer_is_anonymous = !$user->isLoggedIn();
+ $viewer_is_anonymous = !$viewer->isLoggedIn();
$revision = id(new DifferentialRevisionQuery())
->withIDs(array($this->revisionID))
->setViewer($request->getUser())
->needRelationships(true)
->needReviewerStatus(true)
->needReviewerAuthority(true)
->executeOne();
if (!$revision) {
return new Aphront404Response();
}
$diffs = id(new DifferentialDiffQuery())
->setViewer($request->getUser())
->withRevisionIDs(array($this->revisionID))
->execute();
$diffs = array_reverse($diffs, $preserve_keys = true);
if (!$diffs) {
throw new Exception(
pht('This revision has no diffs. Something has gone quite wrong.'));
}
$revision->attachActiveDiff(last($diffs));
$diff_vs = $request->getInt('vs');
$target_id = $request->getInt('id');
$target = idx($diffs, $target_id, end($diffs));
$target_manual = $target;
if (!$target_id) {
foreach ($diffs as $diff) {
if ($diff->getCreationMethod() != 'commit') {
$target_manual = $diff;
}
}
}
if (empty($diffs[$diff_vs])) {
$diff_vs = null;
}
$repository = null;
$repository_phid = $target->getRepositoryPHID();
if ($repository_phid) {
if ($repository_phid == $revision->getRepositoryPHID()) {
$repository = $revision->getRepository();
} else {
$repository = id(new PhabricatorRepositoryQuery())
- ->setViewer($user)
+ ->setViewer($viewer)
->withPHIDs(array($repository_phid))
->executeOne();
}
}
list($changesets, $vs_map, $vs_changesets, $rendering_references) =
$this->loadChangesetsAndVsMap(
$target,
idx($diffs, $diff_vs),
$repository);
if ($request->getExists('download')) {
return $this->buildRawDiffResponse(
$revision,
$changesets,
$vs_changesets,
$vs_map,
$repository);
}
$map = $vs_map;
if (!$map) {
$map = array_fill_keys(array_keys($changesets), 0);
}
$old_ids = array();
$new_ids = array();
foreach ($map as $id => $vs) {
if ($vs <= 0) {
$old_ids[] = $id;
$new_ids[] = $id;
} else {
$new_ids[] = $id;
$new_ids[] = $vs;
}
}
$props = id(new DifferentialDiffProperty())->loadAllWhere(
'diffID = %d',
$target_manual->getID());
$props = mpull($props, 'getData', 'getName');
$object_phids = array_merge(
$revision->getReviewers(),
$revision->getCCPHIDs(),
$revision->loadCommitPHIDs(),
array(
$revision->getAuthorPHID(),
- $user->getPHID(),
+ $viewer->getPHID(),
));
foreach ($revision->getAttached() as $type => $phids) {
foreach ($phids as $phid => $info) {
$object_phids[] = $phid;
}
}
$field_list = PhabricatorCustomField::getObjectFields(
$revision,
PhabricatorCustomField::ROLE_VIEW);
- $field_list->setViewer($user);
+ $field_list->setViewer($viewer);
$field_list->readFieldsFromStorage($revision);
$warning_handle_map = array();
foreach ($field_list->getFields() as $key => $field) {
$req = $field->getRequiredHandlePHIDsForRevisionHeaderWarnings();
foreach ($req as $phid) {
$warning_handle_map[$key][] = $phid;
$object_phids[] = $phid;
}
}
$handles = $this->loadViewerHandles($object_phids);
$request_uri = $request->getRequestURI();
$limit = 100;
$large = $request->getStr('large');
if (count($changesets) > $limit && !$large) {
$count = count($changesets);
$warning = new PHUIInfoView();
$warning->setTitle(pht('Very Large Diff'));
$warning->setSeverity(PHUIInfoView::SEVERITY_WARNING);
$warning->appendChild(hsprintf(
'%s <strong>%s</strong>',
pht(
'This diff is very large and affects %s files. '.
'You may load each file individually or ',
new PhutilNumber($count)),
phutil_tag(
'a',
array(
'class' => 'button grey',
'href' => $request_uri
->alter('large', 'true')
->setFragment('toc'),
),
pht('Show All Files Inline'))));
$warning = $warning->render();
$old = array_select_keys($changesets, $old_ids);
$new = array_select_keys($changesets, $new_ids);
$query = id(new DifferentialInlineCommentQuery())
- ->setViewer($user)
+ ->setViewer($viewer)
->needHidden(true)
->withRevisionPHIDs(array($revision->getPHID()));
$inlines = $query->execute();
$inlines = $query->adjustInlinesForChangesets(
$inlines,
$old,
$new,
$revision);
$visible_changesets = array();
foreach ($inlines as $inline) {
$changeset_id = $inline->getChangesetID();
if (isset($changesets[$changeset_id])) {
$visible_changesets[$changeset_id] = $changesets[$changeset_id];
}
}
} else {
$warning = null;
$visible_changesets = $changesets;
}
$commit_hashes = mpull($diffs, 'getSourceControlBaseRevision');
$local_commits = idx($props, 'local:commits', array());
foreach ($local_commits as $local_commit) {
$commit_hashes[] = idx($local_commit, 'tree');
$commit_hashes[] = idx($local_commit, 'local');
}
$commit_hashes = array_unique(array_filter($commit_hashes));
if ($commit_hashes) {
$commits_for_links = id(new DiffusionCommitQuery())
- ->setViewer($user)
+ ->setViewer($viewer)
->withIdentifiers($commit_hashes)
->execute();
$commits_for_links = mpull(
$commits_for_links,
null,
'getCommitIdentifier');
} else {
$commits_for_links = array();
}
$revision_detail = id(new DifferentialRevisionDetailView())
- ->setUser($user)
+ ->setUser($viewer)
->setRevision($revision)
->setDiff(end($diffs))
->setCustomFields($field_list)
->setURI($request->getRequestURI());
$actions = $this->getRevisionActions($revision);
$whitespace = $request->getStr(
'whitespace',
DifferentialChangesetParser::WHITESPACE_IGNORE_MOST);
$repository = $revision->getRepository();
if ($repository) {
$symbol_indexes = $this->buildSymbolIndexes(
$repository,
$visible_changesets);
} else {
$symbol_indexes = array();
}
$revision_detail->setActions($actions);
- $revision_detail->setUser($user);
+ $revision_detail->setUser($viewer);
$revision_detail_box = $revision_detail->render();
$revision_warnings = $this->buildRevisionWarnings(
$revision,
$field_list,
$warning_handle_map,
$handles);
if ($revision_warnings) {
$revision_warnings = id(new PHUIInfoView())
->setSeverity(PHUIInfoView::SEVERITY_WARNING)
->setErrors($revision_warnings);
$revision_detail_box->setInfoView($revision_warnings);
}
$detail_diffs = array_select_keys(
$diffs,
array($diff_vs, $target->getID()));
$detail_diffs = mpull($detail_diffs, null, 'getPHID');
$buildables = id(new HarbormasterBuildableQuery())
- ->setViewer($user)
+ ->setViewer($viewer)
->withBuildablePHIDs(array_keys($detail_diffs))
->withManualBuildables(false)
->needBuilds(true)
->needTargets(true)
->execute();
$buildables = mpull($buildables, null, 'getBuildablePHID');
foreach ($detail_diffs as $diff_phid => $detail_diff) {
$detail_diff->attachBuildable(idx($buildables, $diff_phid));
}
$diff_detail_box = $this->buildDiffDetailView(
$detail_diffs,
$revision,
$field_list);
$comment_view = $this->buildTransactions(
$revision,
$diff_vs ? $diffs[$diff_vs] : $target,
$target,
$old_ids,
$new_ids);
if (!$viewer_is_anonymous) {
$comment_view->setQuoteRef('D'.$revision->getID());
$comment_view->setQuoteTargetID('comment-content');
}
$wrap_id = celerity_generate_unique_node_id();
$comment_view = phutil_tag(
'div',
array(
'id' => $wrap_id,
),
$comment_view);
$changeset_view = new DifferentialChangesetListView();
$changeset_view->setChangesets($changesets);
$changeset_view->setVisibleChangesets($visible_changesets);
if (!$viewer_is_anonymous) {
$changeset_view->setInlineCommentControllerURI(
'/differential/comment/inline/edit/'.$revision->getID().'/');
}
$changeset_view->setStandaloneURI('/differential/changeset/');
$changeset_view->setRawFileURIs(
'/differential/changeset/?view=old',
'/differential/changeset/?view=new');
- $changeset_view->setUser($user);
+ $changeset_view->setUser($viewer);
$changeset_view->setDiff($target);
$changeset_view->setRenderingReferences($rendering_references);
$changeset_view->setVsMap($vs_map);
$changeset_view->setWhitespace($whitespace);
if ($repository) {
$changeset_view->setRepository($repository);
}
$changeset_view->setSymbolIndexes($symbol_indexes);
$changeset_view->setTitle(pht('Diff %s', $target->getID()));
$diff_history = id(new DifferentialRevisionUpdateHistoryView())
- ->setUser($user)
+ ->setUser($viewer)
->setDiffs($diffs)
->setSelectedVersusDiffID($diff_vs)
->setSelectedDiffID($target->getID())
->setSelectedWhitespace($whitespace)
->setCommitsForLinks($commits_for_links);
$local_view = id(new DifferentialLocalCommitsView())
- ->setUser($user)
+ ->setUser($viewer)
->setLocalCommits(idx($props, 'local:commits'))
->setCommitsForLinks($commits_for_links);
if ($repository) {
$other_revisions = $this->loadOtherRevisions(
$changesets,
$target,
$repository);
} else {
$other_revisions = array();
}
$other_view = null;
if ($other_revisions) {
$other_view = $this->renderOtherRevisions($other_revisions);
}
$toc_view = $this->buildTableOfContents(
$changesets,
$visible_changesets,
- $target->loadCoverageMap($user));
+ $target->loadCoverageMap($viewer));
$comment_form = null;
if (!$viewer_is_anonymous) {
$draft = id(new PhabricatorDraft())->loadOneWhere(
'authorPHID = %s AND draftKey = %s',
- $user->getPHID(),
+ $viewer->getPHID(),
'differential-comment-'.$revision->getID());
$reviewers = array();
$ccs = array();
if ($draft) {
$reviewers = idx($draft->getMetadata(), 'reviewers', array());
$ccs = idx($draft->getMetadata(), 'ccs', array());
if ($reviewers || $ccs) {
$handles = $this->loadViewerHandles(array_merge($reviewers, $ccs));
$reviewers = array_select_keys($handles, $reviewers);
$ccs = array_select_keys($handles, $ccs);
}
}
$comment_form = new DifferentialAddCommentView();
$comment_form->setRevision($revision);
$review_warnings = array();
foreach ($field_list->getFields() as $field) {
$review_warnings[] = $field->getWarningsForDetailView();
}
$review_warnings = array_mergev($review_warnings);
if ($review_warnings) {
$review_warnings_panel = id(new PHUIInfoView())
->setSeverity(PHUIInfoView::SEVERITY_WARNING)
->setErrors($review_warnings);
$comment_form->setInfoView($review_warnings_panel);
}
$comment_form->setActions($this->getRevisionCommentActions($revision));
$action_uri = $this->getApplicationURI(
'comment/save/'.$revision->getID().'/');
$comment_form->setActionURI($action_uri);
- $comment_form->setUser($user);
+ $comment_form->setUser($viewer);
$comment_form->setDraft($draft);
$comment_form->setReviewers(mpull($reviewers, 'getFullName', 'getPHID'));
$comment_form->setCCs(mpull($ccs, 'getFullName', 'getPHID'));
// TODO: This just makes the "Z" key work. Generalize this and remove
// it at some point.
$comment_form = phutil_tag(
'div',
array(
'class' => 'differential-add-comment-panel',
),
$comment_form);
}
$pane_id = celerity_generate_unique_node_id();
Javelin::initBehavior(
'differential-keyboard-navigation',
array(
'haunt' => $pane_id,
));
Javelin::initBehavior('differential-user-select');
$page_pane = id(new DifferentialPrimaryPaneView())
->setID($pane_id)
->appendChild($comment_view);
$signatures = DifferentialRequiredSignaturesField::loadForRevision(
$revision);
$missing_signatures = false;
foreach ($signatures as $phid => $signed) {
if (!$signed) {
$missing_signatures = true;
}
}
if ($missing_signatures) {
$signature_message = id(new PHUIInfoView())
->setErrors(
array(
array(
phutil_tag('strong', array(), pht('Content Hidden:')),
' ',
pht(
'The content of this revision is hidden until the author has '.
'signed all of the required legal agreements.'),
),
));
$page_pane->appendChild($signature_message);
} else {
$page_pane->appendChild(
array(
$diff_history,
$warning,
$local_view,
$toc_view,
$other_view,
$changeset_view,
));
}
if ($comment_form) {
$page_pane->appendChild($comment_form);
} else {
// TODO: For now, just use this to get "Login to Comment".
$page_pane->appendChild(
id(new PhabricatorApplicationTransactionCommentView())
- ->setUser($user)
+ ->setUser($viewer)
->setRequestURI($request->getRequestURI()));
}
$object_id = 'D'.$revision->getID();
$content = array(
$revision_detail_box,
$diff_detail_box,
$page_pane,
);
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb($object_id, '/'.$object_id);
- $prefs = $user->loadPreferences();
+ $prefs = $viewer->loadPreferences();
$pref_filetree = PhabricatorUserPreferences::PREFERENCE_DIFF_FILETREE;
if ($prefs->getPreference($pref_filetree)) {
$collapsed = $prefs->getPreference(
PhabricatorUserPreferences::PREFERENCE_NAV_COLLAPSED,
false);
$nav = id(new DifferentialChangesetFileTreeSideNavBuilder())
->setTitle('D'.$revision->getID())
->setBaseURI(new PhutilURI('/D'.$revision->getID()))
->setCollapsed((bool)$collapsed)
->build($changesets);
$nav->appendChild($content);
$nav->setCrumbs($crumbs);
$content = $nav;
} else {
array_unshift($content, $crumbs);
}
return $this->buildApplicationPage(
$content,
array(
'title' => $object_id.' '.$revision->getTitle(),
'pageObjects' => array($revision->getPHID()),
));
}
private function getRevisionActions(DifferentialRevision $revision) {
$viewer = $this->getRequest()->getUser();
$revision_id = $revision->getID();
$revision_phid = $revision->getPHID();
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$revision,
PhabricatorPolicyCapability::CAN_EDIT);
$actions = array();
$actions[] = id(new PhabricatorActionView())
->setIcon('fa-pencil')
->setHref("/differential/revision/edit/{$revision_id}/")
->setName(pht('Edit Revision'))
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit);
$actions[] = id(new PhabricatorActionView())
->setIcon('fa-upload')
->setHref("/differential/revision/update/{$revision_id}/")
->setName(pht('Update Diff'))
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit);
$this->requireResource('phabricator-object-selector-css');
$this->requireResource('javelin-behavior-phabricator-object-selector');
$actions[] = id(new PhabricatorActionView())
->setIcon('fa-link')
->setName(pht('Edit Dependencies'))
->setHref("/search/attach/{$revision_phid}/DREV/dependencies/")
->setWorkflow(true)
->setDisabled(!$can_edit);
$maniphest = 'PhabricatorManiphestApplication';
if (PhabricatorApplication::isClassInstalled($maniphest)) {
$actions[] = id(new PhabricatorActionView())
->setIcon('fa-anchor')
->setName(pht('Edit Maniphest Tasks'))
->setHref("/search/attach/{$revision_phid}/TASK/")
->setWorkflow(true)
->setDisabled(!$can_edit);
}
$request_uri = $this->getRequest()->getRequestURI();
$actions[] = id(new PhabricatorActionView())
->setIcon('fa-download')
->setName(pht('Download Raw Diff'))
->setHref($request_uri->alter('download', 'true'));
return $actions;
}
private function getRevisionCommentActions(DifferentialRevision $revision) {
$actions = array(
DifferentialAction::ACTION_COMMENT => true,
);
$viewer = $this->getRequest()->getUser();
$viewer_phid = $viewer->getPHID();
$viewer_is_owner = ($viewer_phid == $revision->getAuthorPHID());
$viewer_is_reviewer = in_array($viewer_phid, $revision->getReviewers());
$status = $revision->getStatus();
$viewer_has_accepted = false;
$viewer_has_rejected = false;
$status_accepted = DifferentialReviewerStatus::STATUS_ACCEPTED;
$status_rejected = DifferentialReviewerStatus::STATUS_REJECTED;
foreach ($revision->getReviewerStatus() as $reviewer) {
if ($reviewer->getReviewerPHID() == $viewer_phid) {
if ($reviewer->getStatus() == $status_accepted) {
$viewer_has_accepted = true;
}
if ($reviewer->getStatus() == $status_rejected) {
$viewer_has_rejected = true;
}
break;
}
}
$allow_self_accept = PhabricatorEnv::getEnvConfig(
'differential.allow-self-accept');
$always_allow_abandon = PhabricatorEnv::getEnvConfig(
'differential.always-allow-abandon');
$always_allow_close = PhabricatorEnv::getEnvConfig(
'differential.always-allow-close');
$allow_reopen = PhabricatorEnv::getEnvConfig(
'differential.allow-reopen');
if ($viewer_is_owner) {
switch ($status) {
case ArcanistDifferentialRevisionStatus::NEEDS_REVIEW:
$actions[DifferentialAction::ACTION_ACCEPT] = $allow_self_accept;
$actions[DifferentialAction::ACTION_ABANDON] = true;
$actions[DifferentialAction::ACTION_RETHINK] = true;
break;
case ArcanistDifferentialRevisionStatus::NEEDS_REVISION:
case ArcanistDifferentialRevisionStatus::CHANGES_PLANNED:
$actions[DifferentialAction::ACTION_ACCEPT] = $allow_self_accept;
$actions[DifferentialAction::ACTION_ABANDON] = true;
$actions[DifferentialAction::ACTION_REQUEST] = true;
break;
case ArcanistDifferentialRevisionStatus::ACCEPTED:
$actions[DifferentialAction::ACTION_ABANDON] = true;
$actions[DifferentialAction::ACTION_REQUEST] = true;
$actions[DifferentialAction::ACTION_RETHINK] = true;
$actions[DifferentialAction::ACTION_CLOSE] = true;
break;
case ArcanistDifferentialRevisionStatus::CLOSED:
break;
case ArcanistDifferentialRevisionStatus::ABANDONED:
$actions[DifferentialAction::ACTION_RECLAIM] = true;
break;
}
} else {
switch ($status) {
case ArcanistDifferentialRevisionStatus::NEEDS_REVIEW:
$actions[DifferentialAction::ACTION_ABANDON] = $always_allow_abandon;
$actions[DifferentialAction::ACTION_ACCEPT] = true;
$actions[DifferentialAction::ACTION_REJECT] = true;
$actions[DifferentialAction::ACTION_RESIGN] = $viewer_is_reviewer;
break;
case ArcanistDifferentialRevisionStatus::NEEDS_REVISION:
case ArcanistDifferentialRevisionStatus::CHANGES_PLANNED:
$actions[DifferentialAction::ACTION_ABANDON] = $always_allow_abandon;
$actions[DifferentialAction::ACTION_ACCEPT] = true;
$actions[DifferentialAction::ACTION_REJECT] = !$viewer_has_rejected;
$actions[DifferentialAction::ACTION_RESIGN] = $viewer_is_reviewer;
break;
case ArcanistDifferentialRevisionStatus::ACCEPTED:
$actions[DifferentialAction::ACTION_ABANDON] = $always_allow_abandon;
$actions[DifferentialAction::ACTION_ACCEPT] = !$viewer_has_accepted;
$actions[DifferentialAction::ACTION_REJECT] = true;
$actions[DifferentialAction::ACTION_RESIGN] = $viewer_is_reviewer;
break;
case ArcanistDifferentialRevisionStatus::CLOSED:
case ArcanistDifferentialRevisionStatus::ABANDONED:
break;
}
if ($status != ArcanistDifferentialRevisionStatus::CLOSED) {
$actions[DifferentialAction::ACTION_CLAIM] = true;
$actions[DifferentialAction::ACTION_CLOSE] = $always_allow_close;
}
}
$actions[DifferentialAction::ACTION_ADDREVIEWERS] = true;
$actions[DifferentialAction::ACTION_ADDCCS] = true;
$actions[DifferentialAction::ACTION_REOPEN] = $allow_reopen &&
($status == ArcanistDifferentialRevisionStatus::CLOSED);
$actions = array_keys(array_filter($actions));
$actions_dict = array();
foreach ($actions as $action) {
$actions_dict[$action] = DifferentialAction::getActionVerb($action);
}
return $actions_dict;
}
private function loadChangesetsAndVsMap(
DifferentialDiff $target,
DifferentialDiff $diff_vs = null,
PhabricatorRepository $repository = null) {
$load_diffs = array($target);
if ($diff_vs) {
$load_diffs[] = $diff_vs;
}
$raw_changesets = id(new DifferentialChangesetQuery())
->setViewer($this->getRequest()->getUser())
->withDiffs($load_diffs)
->execute();
$changeset_groups = mgroup($raw_changesets, 'getDiffID');
$changesets = idx($changeset_groups, $target->getID(), array());
$changesets = mpull($changesets, null, 'getID');
$refs = array();
$vs_map = array();
$vs_changesets = array();
if ($diff_vs) {
$vs_id = $diff_vs->getID();
$vs_changesets_path_map = array();
foreach (idx($changeset_groups, $vs_id, array()) as $changeset) {
$path = $changeset->getAbsoluteRepositoryPath($repository, $diff_vs);
$vs_changesets_path_map[$path] = $changeset;
$vs_changesets[$changeset->getID()] = $changeset;
}
foreach ($changesets as $key => $changeset) {
$path = $changeset->getAbsoluteRepositoryPath($repository, $target);
if (isset($vs_changesets_path_map[$path])) {
$vs_map[$changeset->getID()] =
$vs_changesets_path_map[$path]->getID();
$refs[$changeset->getID()] =
$changeset->getID().'/'.$vs_changesets_path_map[$path]->getID();
unset($vs_changesets_path_map[$path]);
} else {
$refs[$changeset->getID()] = $changeset->getID();
}
}
foreach ($vs_changesets_path_map as $path => $changeset) {
$changesets[$changeset->getID()] = $changeset;
$vs_map[$changeset->getID()] = -1;
$refs[$changeset->getID()] = $changeset->getID().'/-1';
}
} else {
foreach ($changesets as $changeset) {
$refs[$changeset->getID()] = $changeset->getID();
}
}
$changesets = msort($changesets, 'getSortKey');
return array($changesets, $vs_map, $vs_changesets, $refs);
}
private function buildSymbolIndexes(
PhabricatorRepository $repository,
array $visible_changesets) {
assert_instances_of($visible_changesets, 'DifferentialChangeset');
$engine = PhabricatorSyntaxHighlighter::newEngine();
$langs = $repository->getSymbolLanguages();
$langs = nonempty($langs, array());
$sources = $repository->getSymbolSources();
$sources = nonempty($sources, array());
$symbol_indexes = array();
if ($langs && $sources) {
$have_symbols = id(new DiffusionSymbolQuery())
->existsSymbolsInRepository($repository->getPHID());
if (!$have_symbols) {
return $symbol_indexes;
}
}
$repository_phids = array_merge(
array($repository->getPHID()),
$sources);
$indexed_langs = array_fill_keys($langs, true);
foreach ($visible_changesets as $key => $changeset) {
$lang = $engine->getLanguageFromFilename($changeset->getFilename());
if (empty($indexed_langs) || isset($indexed_langs[$lang])) {
$symbol_indexes[$key] = array(
'lang' => $lang,
'repositories' => $repository_phids,
);
}
}
return $symbol_indexes;
}
private function loadOtherRevisions(
array $changesets,
DifferentialDiff $target,
PhabricatorRepository $repository) {
assert_instances_of($changesets, 'DifferentialChangeset');
$paths = array();
foreach ($changesets as $changeset) {
$paths[] = $changeset->getAbsoluteRepositoryPath(
$repository,
$target);
}
if (!$paths) {
return array();
}
$path_map = id(new DiffusionPathIDQuery($paths))->loadPathIDs();
if (!$path_map) {
return array();
}
$recent = (PhabricatorTime::getNow() - phutil_units('30 days in seconds'));
$query = id(new DifferentialRevisionQuery())
->setViewer($this->getRequest()->getUser())
->withStatus(DifferentialRevisionQuery::STATUS_OPEN)
->withUpdatedEpochBetween($recent, null)
->setOrder(DifferentialRevisionQuery::ORDER_MODIFIED)
->setLimit(10)
->needFlags(true)
->needDrafts(true)
->needRelationships(true);
foreach ($path_map as $path => $path_id) {
$query->withPath($repository->getID(), $path_id);
}
$results = $query->execute();
// Strip out *this* revision.
foreach ($results as $key => $result) {
if ($result->getID() == $this->revisionID) {
unset($results[$key]);
}
}
return $results;
}
private function renderOtherRevisions(array $revisions) {
assert_instances_of($revisions, 'DifferentialRevision');
$viewer = $this->getViewer();
$header = id(new PHUIHeaderView())
->setHeader(pht('Recent Similar Open Revisions'));
$view = id(new DifferentialRevisionListView())
->setHeader($header)
->setRevisions($revisions)
->setUser($viewer);
$phids = $view->getRequiredHandlePHIDs();
$handles = $this->loadViewerHandles($phids);
$view->setHandles($handles);
return $view;
}
/**
* Note this code is somewhat similar to the buildPatch method in
* @{class:DifferentialReviewRequestMail}.
*
* @return @{class:AphrontRedirectResponse}
*/
private function buildRawDiffResponse(
DifferentialRevision $revision,
array $changesets,
array $vs_changesets,
array $vs_map,
PhabricatorRepository $repository = null) {
assert_instances_of($changesets, 'DifferentialChangeset');
assert_instances_of($vs_changesets, 'DifferentialChangeset');
$viewer = $this->getRequest()->getUser();
id(new DifferentialHunkQuery())
->setViewer($viewer)
->withChangesets($changesets)
->needAttachToChangesets(true)
->execute();
$diff = new DifferentialDiff();
$diff->attachChangesets($changesets);
$raw_changes = $diff->buildChangesList();
$changes = array();
foreach ($raw_changes as $changedict) {
$changes[] = ArcanistDiffChange::newFromDictionary($changedict);
}
$loader = id(new PhabricatorFileBundleLoader())
->setViewer($viewer);
$bundle = ArcanistBundle::newFromChanges($changes);
$bundle->setLoadFileDataCallback(array($loader, 'loadFileData'));
$vcs = $repository ? $repository->getVersionControlSystem() : null;
switch ($vcs) {
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
$raw_diff = $bundle->toGitPatch();
break;
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
default:
$raw_diff = $bundle->toUnifiedDiff();
break;
}
$request_uri = $this->getRequest()->getRequestURI();
// this ends up being something like
// D123.diff
// or the verbose
// D123.vs123.id123.whitespaceignore-all.diff
// lame but nice to include these options
$file_name = ltrim($request_uri->getPath(), '/').'.';
foreach ($request_uri->getQueryParams() as $key => $value) {
if ($key == 'download') {
continue;
}
$file_name .= $key.$value.'.';
}
$file_name .= 'diff';
$file = PhabricatorFile::buildFromFileDataOrHash(
$raw_diff,
array(
'name' => $file_name,
'ttl' => (60 * 60 * 24),
'viewPolicy' => PhabricatorPolicies::POLICY_NOONE,
));
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
$file->attachToObject($revision->getPHID());
unset($unguarded);
return $file->getRedirectResponse();
}
private function buildTransactions(
DifferentialRevision $revision,
DifferentialDiff $left_diff,
DifferentialDiff $right_diff,
array $old_ids,
array $new_ids) {
$timeline = $this->buildTransactionTimeline(
$revision,
new DifferentialTransactionQuery(),
$engine = null,
array(
'left' => $left_diff->getID(),
'right' => $right_diff->getID(),
'old' => implode(',', $old_ids),
'new' => implode(',', $new_ids),
));
return $timeline;
}
private function buildRevisionWarnings(
DifferentialRevision $revision,
PhabricatorCustomFieldList $field_list,
array $warning_handle_map,
array $handles) {
$warnings = array();
foreach ($field_list->getFields() as $key => $field) {
$phids = idx($warning_handle_map, $key, array());
$field_handles = array_select_keys($handles, $phids);
$field_warnings = $field->getWarningsForRevisionHeader($field_handles);
foreach ($field_warnings as $warning) {
$warnings[] = $warning;
}
}
return $warnings;
}
private function buildDiffDetailView(
array $diffs,
DifferentialRevision $revision,
PhabricatorCustomFieldList $field_list) {
$viewer = $this->getViewer();
$fields = array();
foreach ($field_list->getFields() as $field) {
if ($field->shouldAppearInDiffPropertyView()) {
$fields[] = $field;
}
}
if (!$fields) {
return null;
}
// Make sure we're only going to render unique diffs.
$diffs = mpull($diffs, null, 'getID');
$labels = array(pht('Left'), pht('Right'));
$property_lists = array();
foreach ($diffs as $diff) {
if (count($diffs) == 2) {
$label = array_shift($labels);
$label = pht('%s (Diff %d)', $label, $diff->getID());
} else {
$label = pht('Diff %d', $diff->getID());
}
$property_lists[] = array(
$label,
$this->buildDiffPropertyList($diff, $revision, $fields),
);
}
$box = id(new PHUIObjectBoxView())
->setHeaderText(pht('Diff Detail'))
->setUser($viewer);
$last_tab = null;
foreach ($property_lists as $key => $property_list) {
list($tab_name, $list_view) = $property_list;
$tab = id(new PHUIListItemView())
->setKey($key)
->setName($tab_name);
$box->addPropertyList($list_view, $tab);
$last_tab = $tab;
}
if ($last_tab) {
$last_tab->setSelected(true);
}
return $box;
}
private function buildDiffPropertyList(
DifferentialDiff $diff,
DifferentialRevision $revision,
array $fields) {
$viewer = $this->getViewer();
$view = id(new PHUIPropertyListView())
->setUser($viewer)
->setObject($diff);
foreach ($fields as $field) {
$label = $field->renderDiffPropertyViewLabel($diff);
$value = $field->renderDiffPropertyViewValue($diff);
if ($value !== null) {
$view->addProperty($label, $value);
}
}
return $view;
}
}

File Metadata

Mime Type
text/x-diff
Expires
Tue, Jul 1, 2:56 PM (13 h, 40 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
164398
Default Alt Text
(67 KB)

Event Timeline