2013-03-15 12:28:43 +01:00
|
|
|
<?php
|
|
|
|
|
2014-04-14 21:06:56 +02:00
|
|
|
final class ReleephRequestEditController extends ReleephBranchController {
|
2013-03-15 12:28:43 +01:00
|
|
|
|
2014-04-14 21:06:56 +02:00
|
|
|
private $requestID;
|
|
|
|
private $branchID;
|
2013-03-15 12:28:43 +01:00
|
|
|
|
2013-04-08 17:34:21 +02:00
|
|
|
public function willProcessRequest(array $data) {
|
2014-04-14 21:06:56 +02:00
|
|
|
$this->requestID = idx($data, 'requestID');
|
|
|
|
$this->branchID = idx($data, 'branchID');
|
2013-04-08 17:34:21 +02:00
|
|
|
}
|
2013-03-15 12:28:43 +01:00
|
|
|
|
2013-04-08 17:34:21 +02:00
|
|
|
public function processRequest() {
|
|
|
|
$request = $this->getRequest();
|
2014-04-14 21:06:56 +02:00
|
|
|
$viewer = $request->getUser();
|
2013-03-15 12:28:43 +01:00
|
|
|
|
2014-04-14 21:06:56 +02:00
|
|
|
if ($this->requestID) {
|
|
|
|
$pull = id(new ReleephRequestQuery())
|
|
|
|
->setViewer($viewer)
|
|
|
|
->withIDs(array($this->requestID))
|
2013-07-30 21:38:32 +02:00
|
|
|
->requireCapabilities(
|
|
|
|
array(
|
|
|
|
PhabricatorPolicyCapability::CAN_VIEW,
|
|
|
|
PhabricatorPolicyCapability::CAN_EDIT,
|
|
|
|
))
|
|
|
|
->executeOne();
|
2014-04-14 21:06:56 +02:00
|
|
|
if (!$pull) {
|
|
|
|
return new Aphront404Response();
|
|
|
|
}
|
|
|
|
|
|
|
|
$branch = $pull->getBranch();
|
|
|
|
|
2013-04-08 17:34:21 +02:00
|
|
|
$is_edit = true;
|
|
|
|
} else {
|
2014-04-14 21:06:56 +02:00
|
|
|
$branch = id(new ReleephBranchQuery())
|
|
|
|
->setViewer($viewer)
|
|
|
|
->withIDs(array($this->branchID))
|
|
|
|
->executeOne();
|
|
|
|
if (!$branch) {
|
|
|
|
return new Aphront404Response();
|
|
|
|
}
|
|
|
|
|
|
|
|
$pull = id(new ReleephRequest())
|
|
|
|
->setRequestUserPHID($viewer->getPHID())
|
|
|
|
->setBranchID($branch->getID())
|
2013-04-08 17:34:21 +02:00
|
|
|
->setInBranch(0);
|
2014-04-14 21:06:56 +02:00
|
|
|
|
|
|
|
$is_edit = false;
|
2013-04-08 17:34:21 +02:00
|
|
|
}
|
2014-04-14 21:06:56 +02:00
|
|
|
$this->setBranch($branch);
|
|
|
|
|
|
|
|
$product = $branch->getProduct();
|
|
|
|
|
|
|
|
$request_identifier = $request->getStr('requestIdentifierRaw');
|
|
|
|
$e_request_identifier = true;
|
2013-03-15 12:28:43 +01:00
|
|
|
|
2013-04-08 17:34:21 +02:00
|
|
|
// Load all the ReleephFieldSpecifications
|
2014-04-14 21:06:56 +02:00
|
|
|
$selector = $branch->getProduct()->getReleephFieldSelector();
|
2013-04-08 17:34:21 +02:00
|
|
|
$fields = $selector->getFieldSpecifications();
|
|
|
|
foreach ($fields as $field) {
|
|
|
|
$field
|
2014-04-14 21:06:56 +02:00
|
|
|
->setReleephProject($product)
|
|
|
|
->setReleephBranch($branch)
|
|
|
|
->setReleephRequest($pull);
|
2013-03-15 12:28:43 +01:00
|
|
|
}
|
|
|
|
|
2013-08-15 00:36:13 +02:00
|
|
|
$field_list = PhabricatorCustomField::getObjectFields(
|
2014-04-14 21:06:56 +02:00
|
|
|
$pull,
|
2013-08-15 00:36:13 +02:00
|
|
|
PhabricatorCustomField::ROLE_EDIT);
|
|
|
|
foreach ($field_list->getFields() as $field) {
|
|
|
|
$field
|
2014-04-14 21:06:56 +02:00
|
|
|
->setReleephProject($product)
|
|
|
|
->setReleephBranch($branch)
|
|
|
|
->setReleephRequest($pull);
|
2013-08-15 00:36:13 +02:00
|
|
|
}
|
2014-04-14 21:06:56 +02:00
|
|
|
$field_list->readFieldsFromStorage($pull);
|
|
|
|
|
|
|
|
|
|
|
|
if ($this->branchID) {
|
|
|
|
$cancel_uri = $this->getApplicationURI('branch/'.$this->branchID.'/');
|
|
|
|
} else {
|
|
|
|
$cancel_uri = '/'.$pull->getMonogram();
|
2013-03-15 12:28:43 +01:00
|
|
|
}
|
|
|
|
|
2013-04-08 17:34:21 +02:00
|
|
|
// Make edits
|
2013-03-15 12:28:43 +01:00
|
|
|
$errors = array();
|
2013-04-08 17:34:21 +02:00
|
|
|
if ($request->isFormPost()) {
|
|
|
|
$xactions = array();
|
2013-03-15 12:28:43 +01:00
|
|
|
|
2013-04-08 17:34:21 +02:00
|
|
|
// The commit-identifier being requested...
|
|
|
|
if (!$is_edit) {
|
|
|
|
if ($request_identifier ===
|
|
|
|
ReleephRequestTypeaheadControl::PLACEHOLDER) {
|
2013-03-15 12:28:43 +01:00
|
|
|
|
2013-04-08 17:34:21 +02:00
|
|
|
$errors[] = "No commit ID was provided.";
|
|
|
|
$e_request_identifier = 'Required';
|
|
|
|
} else {
|
|
|
|
$pr_commit = null;
|
|
|
|
$finder = id(new ReleephCommitFinder())
|
2014-04-14 21:06:56 +02:00
|
|
|
->setUser($viewer)
|
|
|
|
->setReleephProject($product);
|
2013-03-15 12:28:43 +01:00
|
|
|
try {
|
2013-04-08 17:34:21 +02:00
|
|
|
$pr_commit = $finder->fromPartial($request_identifier);
|
|
|
|
} catch (Exception $e) {
|
|
|
|
$e_request_identifier = 'Invalid';
|
|
|
|
$errors[] =
|
|
|
|
"Request {$request_identifier} is probably not a valid commit";
|
|
|
|
$errors[] = $e->getMessage();
|
|
|
|
}
|
|
|
|
|
|
|
|
$pr_commit_data = null;
|
|
|
|
if (!$errors) {
|
|
|
|
$pr_commit_data = $pr_commit->loadCommitData();
|
|
|
|
if (!$pr_commit_data) {
|
|
|
|
$e_request_identifier = 'Not parsed yet';
|
|
|
|
$errors[] = "The requested commit hasn't been parsed yet.";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!$errors) {
|
|
|
|
$existing = id(new ReleephRequest())
|
|
|
|
->loadOneWhere('requestCommitPHID = %s AND branchID = %d',
|
2014-04-14 21:06:56 +02:00
|
|
|
$pr_commit->getPHID(), $branch->getID());
|
2013-04-08 17:34:21 +02:00
|
|
|
if ($existing) {
|
|
|
|
return id(new AphrontRedirectResponse())
|
|
|
|
->setURI('/releeph/request/edit/'.$existing->getID().
|
|
|
|
'?existing=1');
|
|
|
|
}
|
|
|
|
|
|
|
|
$xactions[] = id(new ReleephRequestTransaction())
|
|
|
|
->setTransactionType(ReleephRequestTransaction::TYPE_REQUEST)
|
|
|
|
->setNewValue($pr_commit->getPHID());
|
|
|
|
|
|
|
|
$xactions[] = id(new ReleephRequestTransaction())
|
|
|
|
->setTransactionType(ReleephRequestTransaction::TYPE_USER_INTENT)
|
|
|
|
// To help hide these implicit intents...
|
|
|
|
->setMetadataValue('isRQCreate', true)
|
2014-04-14 21:06:56 +02:00
|
|
|
->setMetadataValue('userPHID', $viewer->getPHID())
|
2013-04-08 17:34:21 +02:00
|
|
|
->setMetadataValue(
|
|
|
|
'isAuthoritative',
|
2014-04-14 21:06:56 +02:00
|
|
|
$product->isAuthoritative($viewer))
|
2013-04-08 17:34:21 +02:00
|
|
|
->setNewValue(ReleephRequest::INTENT_WANT);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-15 00:36:13 +02:00
|
|
|
// TODO: This should happen implicitly while building transactions
|
|
|
|
// instead.
|
|
|
|
foreach ($field_list->getFields() as $field) {
|
|
|
|
$field->readValueFromRequest($request);
|
|
|
|
}
|
|
|
|
|
2013-04-08 17:34:21 +02:00
|
|
|
if (!$errors) {
|
|
|
|
foreach ($fields as $field) {
|
|
|
|
if ($field->isEditable()) {
|
|
|
|
try {
|
|
|
|
$data = $request->getRequestData();
|
|
|
|
$value = idx($data, $field->getRequiredStorageKey());
|
|
|
|
$field->validate($value);
|
|
|
|
$xactions[] = id(new ReleephRequestTransaction())
|
|
|
|
->setTransactionType(ReleephRequestTransaction::TYPE_EDIT_FIELD)
|
|
|
|
->setMetadataValue('fieldClass', get_class($field))
|
|
|
|
->setNewValue($value);
|
|
|
|
} catch (ReleephFieldParseException $ex) {
|
|
|
|
$errors[] = $ex->getMessage();
|
|
|
|
}
|
2013-03-15 12:28:43 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!$errors) {
|
2013-04-08 17:34:21 +02:00
|
|
|
$editor = id(new ReleephRequestTransactionalEditor())
|
2014-04-14 21:06:56 +02:00
|
|
|
->setActor($viewer)
|
2013-04-08 17:34:21 +02:00
|
|
|
->setContinueOnNoEffect(true)
|
2013-05-24 19:48:34 +02:00
|
|
|
->setContentSourceFromRequest($request);
|
2014-04-14 21:06:56 +02:00
|
|
|
$editor->applyTransactions($pull, $xactions);
|
|
|
|
return id(new AphrontRedirectResponse())->setURI($cancel_uri);
|
2013-03-15 12:28:43 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-20 20:54:50 +02:00
|
|
|
$handle_phids = array(
|
|
|
|
$pull->getRequestUserPHID(),
|
|
|
|
$pull->getRequestCommitPHID(),
|
|
|
|
);
|
|
|
|
$handle_phids = array_filter($handle_phids);
|
|
|
|
if ($handle_phids) {
|
|
|
|
$handles = id(new PhabricatorHandleQuery())
|
|
|
|
->setViewer($viewer)
|
|
|
|
->withPHIDs($handle_phids)
|
|
|
|
->execute();
|
|
|
|
} else {
|
|
|
|
$handles = array();
|
|
|
|
}
|
2013-04-08 17:34:21 +02:00
|
|
|
|
|
|
|
$age_string = '';
|
|
|
|
if ($is_edit) {
|
|
|
|
$age_string = phabricator_format_relative_time(
|
2014-04-14 21:06:56 +02:00
|
|
|
time() - $pull->getDateCreated()) . ' ago';
|
2013-04-08 17:34:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Warn the user if we've been redirected here because we tried to
|
|
|
|
// re-request something.
|
|
|
|
$notice_view = null;
|
|
|
|
if ($request->getInt('existing')) {
|
|
|
|
$notice_messages = array(
|
|
|
|
'You are editing an existing pick request!',
|
|
|
|
hsprintf(
|
|
|
|
"Requested %s by %s",
|
|
|
|
$age_string,
|
2014-04-14 21:06:56 +02:00
|
|
|
$handles[$pull->getRequestUserPHID()]->renderLink())
|
2013-04-08 17:34:21 +02:00
|
|
|
);
|
|
|
|
$notice_view = id(new AphrontErrorView())
|
|
|
|
->setSeverity(AphrontErrorView::SEVERITY_NOTICE)
|
|
|
|
->setErrors($notice_messages);
|
|
|
|
}
|
|
|
|
|
2013-03-15 12:28:43 +01:00
|
|
|
$form = id(new AphrontFormView())
|
2014-04-14 21:06:56 +02:00
|
|
|
->setUser($viewer);
|
2013-04-08 17:34:21 +02:00
|
|
|
|
|
|
|
if ($is_edit) {
|
|
|
|
$form
|
|
|
|
->appendChild(
|
|
|
|
id(new AphrontFormMarkupControl())
|
|
|
|
->setLabel('Original Commit')
|
|
|
|
->setValue(
|
2014-04-14 21:06:56 +02:00
|
|
|
$handles[$pull->getRequestCommitPHID()]->renderLink()))
|
2013-04-08 17:34:21 +02:00
|
|
|
->appendChild(
|
|
|
|
id(new AphrontFormMarkupControl())
|
|
|
|
->setLabel('Requestor')
|
|
|
|
->setValue(hsprintf(
|
|
|
|
'%s %s',
|
2014-04-14 21:06:56 +02:00
|
|
|
$handles[$pull->getRequestUserPHID()]->renderLink(),
|
2013-04-08 17:34:21 +02:00
|
|
|
$age_string)));
|
|
|
|
} else {
|
|
|
|
$origin = null;
|
|
|
|
$diff_rev_id = $request->getStr('D');
|
|
|
|
if ($diff_rev_id) {
|
2013-09-26 21:37:19 +02:00
|
|
|
$diff_rev = id(new DifferentialRevisionQuery())
|
2014-04-14 21:06:56 +02:00
|
|
|
->setViewer($viewer)
|
2013-09-26 21:37:19 +02:00
|
|
|
->withIDs(array($diff_rev_id))
|
|
|
|
->executeOne();
|
2013-04-08 17:34:21 +02:00
|
|
|
$origin = '/D'.$diff_rev->getID();
|
|
|
|
$title = sprintf(
|
|
|
|
'D%d: %s',
|
|
|
|
$diff_rev_id,
|
|
|
|
$diff_rev->getTitle());
|
|
|
|
$form
|
|
|
|
->addHiddenInput('requestIdentifierRaw', 'D'.$diff_rev_id)
|
|
|
|
->appendChild(
|
|
|
|
id(new AphrontFormStaticControl())
|
|
|
|
->setLabel('Diff')
|
|
|
|
->setValue($title));
|
|
|
|
} else {
|
2014-04-14 21:06:56 +02:00
|
|
|
$origin = $branch->getURI();
|
2014-04-20 20:55:09 +02:00
|
|
|
$repo = $product->getRepository();
|
2013-04-08 17:34:21 +02:00
|
|
|
$branch_cut_point = id(new PhabricatorRepositoryCommit())
|
|
|
|
->loadOneWhere(
|
|
|
|
'phid = %s',
|
2014-04-14 21:06:56 +02:00
|
|
|
$branch->getCutPointCommitPHID());
|
2013-04-08 17:34:21 +02:00
|
|
|
$form->appendChild(
|
|
|
|
id(new ReleephRequestTypeaheadControl())
|
|
|
|
->setName('requestIdentifierRaw')
|
|
|
|
->setLabel('Commit ID')
|
|
|
|
->setRepo($repo)
|
|
|
|
->setValue($request_identifier)
|
|
|
|
->setError($e_request_identifier)
|
|
|
|
->setStartTime($branch_cut_point->getEpoch())
|
|
|
|
->setCaption(
|
|
|
|
'Start typing to autocomplete on commit title, '.
|
|
|
|
'or give a Phabricator commit identifier like rFOO1234'));
|
|
|
|
}
|
|
|
|
}
|
2013-03-15 12:28:43 +01:00
|
|
|
|
2013-08-15 00:36:13 +02:00
|
|
|
$field_list->appendFieldsToForm($form);
|
2013-03-15 12:28:43 +01:00
|
|
|
|
2013-07-30 21:38:32 +02:00
|
|
|
$crumbs = $this->buildApplicationCrumbs();
|
|
|
|
|
2013-04-08 17:34:21 +02:00
|
|
|
if ($is_edit) {
|
2014-04-14 21:06:56 +02:00
|
|
|
$title = pht('Edit Pull Request');
|
2013-04-08 17:34:21 +02:00
|
|
|
$submit_name = pht('Save');
|
2013-07-30 21:38:32 +02:00
|
|
|
|
2014-04-14 21:06:56 +02:00
|
|
|
$crumbs->addTextCrumb($pull->getMonogram(), '/'.$pull->getMonogram());
|
2013-12-19 02:47:34 +01:00
|
|
|
$crumbs->addTextCrumb(pht('Edit'));
|
2013-04-08 17:34:21 +02:00
|
|
|
} else {
|
2014-04-14 21:06:56 +02:00
|
|
|
$title = pht('Create Pull Request');
|
|
|
|
$submit_name = pht('Create Pull Request');
|
|
|
|
|
|
|
|
$crumbs->addTextCrumb(pht('New Pull Request'));
|
2013-04-08 17:34:21 +02:00
|
|
|
}
|
|
|
|
|
2013-07-30 21:38:32 +02:00
|
|
|
$form->appendChild(
|
|
|
|
id(new AphrontFormSubmitControl())
|
2014-04-14 21:06:56 +02:00
|
|
|
->addCancelButton($cancel_uri, 'Cancel')
|
2013-07-30 21:38:32 +02:00
|
|
|
->setValue($submit_name));
|
2013-03-15 12:28:43 +01:00
|
|
|
|
2014-04-14 21:06:56 +02:00
|
|
|
$box = id(new PHUIObjectBoxView())
|
|
|
|
->setHeaderText($title)
|
|
|
|
->setFormErrors($errors)
|
|
|
|
->appendChild($form);
|
|
|
|
|
2013-07-30 21:38:32 +02:00
|
|
|
return $this->buildApplicationPage(
|
|
|
|
array(
|
|
|
|
$crumbs,
|
|
|
|
$notice_view,
|
2014-04-14 21:06:56 +02:00
|
|
|
$box,
|
2013-07-30 21:38:32 +02:00
|
|
|
),
|
|
|
|
array(
|
|
|
|
'title' => $title,
|
2014-04-14 21:06:56 +02:00
|
|
|
'device' => true,
|
2013-07-30 21:38:32 +02:00
|
|
|
));
|
2013-03-15 12:28:43 +01:00
|
|
|
}
|
|
|
|
}
|