protected function execute(ConduitAPIRequest $request)
 {
     $viewer = $request->getUser();
     $diff = id(new DifferentialDiffQuery())->setViewer($viewer)->withIDs(array($request->getValue('diffid')))->executeOne();
     if (!$diff) {
         throw new ConduitException('ERR_BAD_DIFF');
     }
     $revision = DifferentialRevision::initializeNewRevision($viewer);
     $revision->attachReviewerStatus(array());
     $this->applyFieldEdit($request, $revision, $diff, $request->getValue('fields', array()), $message = null);
     return array('revisionid' => $revision->getID(), 'uri' => PhabricatorEnv::getURI('/D' . $revision->getID()));
 }
 public function generateObject()
 {
     $author = $this->loadPhabrictorUser();
     $revision = DifferentialRevision::initializeNewRevision($author);
     $revision->attachReviewerStatus(array());
     $revision->attachActiveDiff(null);
     // This could be a bit richer and more formal than it is.
     $revision->setTitle($this->generateTitle());
     $revision->setSummary($this->generateDescription());
     $revision->setTestPlan($this->generateDescription());
     $diff = $this->generateDiff($author);
     $xactions = array();
     $xactions[] = id(new DifferentialTransaction())->setTransactionType(DifferentialTransaction::TYPE_UPDATE)->setNewValue($diff->getPHID());
     id(new DifferentialTransactionEditor())->setActor($author)->setContentSource($this->getLipsumContentSource())->applyTransactions($revision, $xactions);
     return $revision;
 }
 public function handleRequest(AphrontRequest $request)
 {
     $viewer = $this->getViewer();
     $id = $request->getURIData('id');
     if (!$id) {
         $id = $request->getInt('revisionID');
     }
     if ($id) {
         $revision = id(new DifferentialRevisionQuery())->setViewer($viewer)->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) {
             $header_icon = 'fa-upload';
             $title = pht('Update Revision');
             $crumbs->addTextCrumb('D' . $revision->getID(), '/differential/diff/' . $diff->getID() . '/');
         } else {
             $header_icon = 'fa-pencil';
             $title = pht('Edit Revision: %s', $revision->getTitle());
             $crumbs->addTextCrumb('D' . $revision->getID(), '/D' . $revision->getID());
         }
     } else {
         $header_icon = 'fa-plus-square';
         $title = pht('Create New Differential Revision');
     }
     $form_box = id(new PHUIObjectBoxView())->setHeaderText('Revision')->setValidationException($validation_exception)->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)->setForm($form);
     $crumbs->addTextCrumb($title);
     $crumbs->setBorder(true);
     $header = id(new PHUIHeaderView())->setHeader($title)->setHeaderIcon($header_icon);
     $view = id(new PHUITwoColumnView())->setHeader($header)->setFooter($form_box);
     return $this->newPage()->setTitle($title)->setCrumbs($crumbs)->appendChild($view);
 }
 protected function execute(ConduitAPIRequest $request)
 {
     $id = $request->getValue('revision_id');
     $viewer = $request->getUser();
     if ($id) {
         $revision = id(new DifferentialRevisionQuery())->withIDs(array($id))->setViewer($viewer)->needReviewerStatus(true)->needActiveDiffs(true)->executeOne();
         if (!$revision) {
             throw new ConduitException('ERR_NOT_FOUND');
         }
     } else {
         $revision = DifferentialRevision::initializeNewRevision($viewer);
         $revision->attachReviewerStatus(array());
         $revision->attachActiveDiff(null);
     }
     $is_edit = $request->getValue('edit');
     $is_create = $is_edit == 'create';
     $field_list = PhabricatorCustomField::getObjectFields($revision, $is_edit ? DifferentialCustomField::ROLE_COMMITMESSAGEEDIT : DifferentialCustomField::ROLE_COMMITMESSAGE);
     $field_list->setViewer($viewer)->readFieldsFromStorage($revision);
     $field_map = mpull($field_list->getFields(), null, 'getFieldKeyForConduit');
     if ($is_edit) {
         $fields = $request->getValue('fields', array());
         foreach ($fields as $field => $value) {
             $custom_field = idx($field_map, $field);
             if (!$custom_field) {
                 // Just ignore this, these workflows don't make strong distictions
                 // about field editability on the client side.
                 continue;
             }
             if ($is_create || $custom_field->shouldOverwriteWhenCommitMessageIsEdited()) {
                 $custom_field->readValueFromCommitMessage($value);
             }
         }
     }
     $phids = array();
     foreach ($field_list->getFields() as $key => $field) {
         $field_phids = $field->getRequiredHandlePHIDsForCommitMessage();
         if (!is_array($field_phids)) {
             throw new Exception(pht('Custom field "%s" was expected to return an array of handle ' . 'PHIDs required for commit message rendering, but returned "%s" ' . 'instead.', $field->getFieldKey(), gettype($field_phids)));
         }
         $phids[$key] = $field_phids;
     }
     $all_phids = array_mergev($phids);
     if ($all_phids) {
         $all_handles = id(new PhabricatorHandleQuery())->setViewer($viewer)->withPHIDs($all_phids)->execute();
     } else {
         $all_handles = array();
     }
     $key_title = id(new DifferentialTitleField())->getFieldKey();
     $default_title = DifferentialTitleField::getDefaultTitle();
     $commit_message = array();
     foreach ($field_list->getFields() as $key => $field) {
         $handles = array_select_keys($all_handles, $phids[$key]);
         $label = $field->renderCommitMessageLabel();
         $value = $field->renderCommitMessageValue($handles);
         if (!is_string($value) && !is_null($value)) {
             throw new Exception(pht('Custom field "%s" was expected to render a string or null value, ' . 'but rendered a "%s" instead.', $field->getFieldKey(), gettype($value)));
         }
         $is_title = $key == $key_title;
         if (!strlen($value)) {
             if ($is_title) {
                 $commit_message[] = $default_title;
             } else {
                 if ($is_edit && $field->shouldAppearInCommitMessageTemplate()) {
                     $commit_message[] = $label . ': ';
                 }
             }
         } else {
             if ($is_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) {
         $tip = $this->getProTip($field_list);
         if ($tip !== null) {
             $commit_message[] = "\n" . $tip;
         }
     }
     $commit_message = implode("\n\n", $commit_message);
     return $commit_message;
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $viewer = $request->getUser();
     if (!$this->id) {
         $this->id = $request->getInt('revisionID');
     }
     if ($this->id) {
         $revision = id(new DifferentialRevisionQuery())->setViewer($viewer)->withIDs(array($this->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('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);
     $validation_exception = null;
     if ($request->isFormPost() && !$request->getStr('viaDiffView')) {
         $xactions = $field_list->buildFieldTransactionsFromRequest(new DifferentialTransaction(), $request);
         if ($diff) {
             $xactions[] = id(new DifferentialTransaction())->setTransactionType(DifferentialTransaction::TYPE_UPDATE)->setNewValue($diff->getPHID());
         }
         $comments = $request->getStr('comments');
         if (strlen($comments)) {
             $xactions[] = id(new DifferentialTransaction())->setTransactionType(PhabricatorTransactions::TYPE_COMMENT)->attachComment(id(new DifferentialTransactionComment())->setContent($comments));
         }
         $editor = id(new DifferentialTransactionEditor())->setActor($viewer)->setContentSourceFromRequest($request)->setContinueOnNoEffect(true);
         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));
 }