public static function indexRevision(DifferentialRevision $rev) { $doc = new PhabricatorSearchAbstractDocument(); $doc->setPHID($rev->getPHID()); $doc->setDocumentType(PhabricatorPHIDConstants::PHID_TYPE_DREV); $doc->setDocumentTitle($rev->getTitle()); $doc->setDocumentCreated($rev->getDateCreated()); $doc->setDocumentModified($rev->getDateModified()); $doc->addField(PhabricatorSearchField::FIELD_BODY, $rev->getSummary()); $doc->addField(PhabricatorSearchField::FIELD_TEST_PLAN, $rev->getTestPlan()); $doc->addRelationship(PhabricatorSearchRelationship::RELATIONSHIP_AUTHOR, $rev->getAuthorPHID(), PhabricatorPHIDConstants::PHID_TYPE_USER, $rev->getDateCreated()); if ($rev->getStatus() != ArcanistDifferentialRevisionStatus::CLOSED && $rev->getStatus() != ArcanistDifferentialRevisionStatus::ABANDONED) { $doc->addRelationship(PhabricatorSearchRelationship::RELATIONSHIP_OPEN, $rev->getPHID(), PhabricatorPHIDConstants::PHID_TYPE_DREV, time()); } $comments = id(new DifferentialComment())->loadAllWhere('revisionID = %d', $rev->getID()); $inlines = id(new DifferentialInlineComment())->loadAllWhere('revisionID = %d AND commentID IS NOT NULL', $rev->getID()); $touches = array(); foreach (array_merge($comments, $inlines) as $comment) { if (strlen($comment->getContent())) { $doc->addField(PhabricatorSearchField::FIELD_COMMENT, $comment->getContent()); } $author = $comment->getAuthorPHID(); $touches[$author] = $comment->getDateCreated(); } foreach ($touches as $touch => $time) { $doc->addRelationship(PhabricatorSearchRelationship::RELATIONSHIP_TOUCH, $touch, PhabricatorPHIDConstants::PHID_TYPE_USER, $time); } $rev->loadRelationships(); // If a revision needs review, the owners are the reviewers. Otherwise, the // owner is the author (e.g., accepted, rejected, closed). if ($rev->getStatus() == ArcanistDifferentialRevisionStatus::NEEDS_REVIEW) { foreach ($rev->getReviewers() as $phid) { $doc->addRelationship(PhabricatorSearchRelationship::RELATIONSHIP_OWNER, $phid, PhabricatorPHIDConstants::PHID_TYPE_USER, $rev->getDateModified()); // Bogus timestamp. } } else { $doc->addRelationship(PhabricatorSearchRelationship::RELATIONSHIP_OWNER, $rev->getAuthorPHID(), PhabricatorPHIDConstants::PHID_TYPE_USER, $rev->getDateCreated()); } $ccphids = $rev->getCCPHIDs(); $handles = id(new PhabricatorObjectHandleData($ccphids))->loadHandles(); foreach ($handles as $phid => $handle) { $doc->addRelationship(PhabricatorSearchRelationship::RELATIONSHIP_SUBSCRIBER, $phid, $handle->getType(), $rev->getDateModified()); // Bogus timestamp. } self::reindexAbstractDocument($doc); }
private function unsubscribeUser(DifferentialRevision $revision, PhabricatorUser $user) { $revision->loadRelationships(); DifferentialRevisionEditor::removeCCAndUpdateRevision($revision, $user->getPHID(), $user->getPHID()); }
public function __construct(DifferentialRevision $revision, DifferentialDiff $diff) { $revision->loadRelationships(); $this->revision = $revision; $this->diff = $diff; }
public function processRequest() { $request = $this->getRequest(); if (!$this->id) { $this->id = $request->getInt('revisionID'); } if ($this->id) { $revision = id(new DifferentialRevision())->load($this->id); if (!$revision) { return new Aphront404Response(); } } else { $revision = new DifferentialRevision(); } $revision->loadRelationships(); $aux_fields = $this->loadAuxiliaryFields($revision); $diff_id = $request->getInt('diffID'); if ($diff_id) { $diff = id(new DifferentialDiff())->load($diff_id); if (!$diff) { return new Aphront404Response(); } if ($diff->getRevisionID()) { // TODO: Redirect? throw new Exception("This diff is already attached to a revision!"); } } else { $diff = null; } $errors = array(); if ($request->isFormPost() && !$request->getStr('viaDiffView')) { $user_phid = $request->getUser()->getPHID(); foreach ($aux_fields as $aux_field) { $aux_field->setValueFromRequest($request); try { $aux_field->validateField(); } catch (DifferentialFieldValidationException $ex) { $errors[] = $ex->getMessage(); } } if (!$errors) { $editor = new DifferentialRevisionEditor($revision, $user_phid); if ($diff) { $editor->addDiff($diff, $request->getStr('comments')); } $editor->setAuxiliaryFields($aux_fields); $editor->save(); return id(new AphrontRedirectResponse())->setURI('/D' . $revision->getID()); } } $aux_phids = array(); foreach ($aux_fields as $key => $aux_field) { $aux_phids[$key] = $aux_field->getRequiredHandlePHIDsForRevisionEdit(); } $phids = array_mergev($aux_phids); $phids = array_unique($phids); $handles = id(new PhabricatorObjectHandleData($phids))->loadHandles(); foreach ($aux_fields as $key => $aux_field) { $aux_field->setHandles(array_select_keys($handles, $aux_phids[$key])); } $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/'); } $error_view = null; if ($errors) { $error_view = id(new AphrontErrorView())->setTitle('Form Errors')->setErrors($errors); } if ($diff && $revision->getID()) { $form->appendChild(id(new AphrontFormTextAreaControl())->setLabel('Comments')->setName('comments')->setCaption("Explain what's new in this diff.")->setValue($request->getStr('comments')))->appendChild(id(new AphrontFormSubmitControl())->setValue('Save'))->appendChild(id(new AphrontFormDividerControl())); } foreach ($aux_fields as $aux_field) { $control = $aux_field->renderEditControl(); if ($control) { $form->appendChild($control); } } $submit = id(new AphrontFormSubmitControl())->setValue('Save'); if ($diff) { $submit->addCancelButton('/differential/diff/' . $diff->getID() . '/'); } else { $submit->addCancelButton('/D' . $revision->getID()); } $form->appendChild($submit); $panel = new AphrontPanelView(); if ($revision->getID()) { if ($diff) { $panel->setHeader('Update Differential Revision'); } else { $panel->setHeader('Edit Differential Revision'); } } else { $panel->setHeader('Create New Differential Revision'); } $panel->appendChild($form); $panel->setWidth(AphrontPanelView::WIDTH_FORM); return $this->buildStandardPageResponse(array($error_view, $panel), array('title' => 'Edit Differential Revision')); }
private static function alterRelationships(DifferentialRevision $revision, array $stable_phids, array $rem_phids, array $add_phids, $reason_phid, $relation_type) { $rem_map = array_fill_keys($rem_phids, true); $add_map = array_fill_keys($add_phids, true); $seq_map = array_values($stable_phids); $seq_map = array_flip($seq_map); foreach ($rem_map as $phid => $ignored) { if (!isset($seq_map[$phid])) { $seq_map[$phid] = count($seq_map); } } foreach ($add_map as $phid => $ignored) { if (!isset($seq_map[$phid])) { $seq_map[$phid] = count($seq_map); } } $raw = $revision->getRawRelations($relation_type); $raw = ipull($raw, null, 'objectPHID'); $sequence = count($seq_map); foreach ($raw as $phid => $ignored) { if (isset($seq_map[$phid])) { $raw[$phid]['sequence'] = $seq_map[$phid]; } else { $raw[$phid]['sequence'] = $sequence++; } } $raw = isort($raw, 'sequence'); foreach ($raw as $phid => $ignored) { if (isset($rem_map[$phid])) { unset($raw[$phid]); } } foreach ($add_phids as $add) { $reason = is_array($reason_phid) ? idx($reason_phid, $add) : $reason_phid; $raw[$add] = array('objectPHID' => $add, 'sequence' => idx($seq_map, $add, $sequence++), 'reasonPHID' => $reason); } $conn_w = $revision->establishConnection('w'); $sql = array(); foreach ($raw as $relation) { $sql[] = qsprintf($conn_w, '(%d, %s, %s, %d, %s)', $revision->getID(), $relation_type, $relation['objectPHID'], $relation['sequence'], $relation['reasonPHID']); } $conn_w->openTransaction(); queryfx($conn_w, 'DELETE FROM %T WHERE revisionID = %d AND relation = %s', DifferentialRevision::RELATIONSHIP_TABLE, $revision->getID(), $relation_type); if ($sql) { queryfx($conn_w, 'INSERT INTO %T (revisionID, relation, objectPHID, sequence, reasonPHID) VALUES %Q', DifferentialRevision::RELATIONSHIP_TABLE, implode(', ', $sql)); } $conn_w->saveTransaction(); $revision->loadRelationships(); }
protected function execute(ConduitAPIRequest $request) { $id = $request->getValue('revision_id'); if ($id) { $revision = id(new DifferentialRevision())->load($id); if (!$revision) { throw new ConduitException('ERR_NOT_FOUND'); } } else { $revision = new DifferentialRevision(); } $revision->loadRelationships(); $is_edit = $request->getValue('edit'); $is_create = $is_edit == 'create'; $aux_fields = DifferentialFieldSelector::newSelector()->getFieldSpecifications(); foreach ($aux_fields as $key => $aux_field) { $aux_field->setRevision($revision); 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))->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[] = '<<Enter Revision Title>>'; } 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}"; } } } } $commit_message = implode("\n\n", $commit_message); return $commit_message; }
public function processRequest() { $request = $this->getRequest(); if (!$this->id) { $this->id = $request->getInt('revisionID'); } if ($this->id) { $revision = id(new DifferentialRevision())->load($this->id); if (!$revision) { return new Aphront404Response(); } } else { $revision = new DifferentialRevision(); } $diff_id = $request->getInt('diffID'); if ($diff_id) { $diff = id(new DifferentialDiff())->load($diff_id); if (!$diff) { return new Aphront404Response(); } if ($diff->getRevisionID()) { // TODO: Redirect? throw new Exception("This diff is already attached to a revision!"); } } else { $diff = null; } $e_title = true; $e_testplan = true; $e_reviewers = null; $errors = array(); $revision->loadRelationships(); if ($request->isFormPost() && !$request->getStr('viaDiffView')) { $revision->setTitle($request->getStr('title')); $revision->setSummary($request->getStr('summary')); $revision->setTestPlan($request->getStr('testplan')); $revision->setBlameRevision($request->getStr('blame')); $revision->setRevertPlan($request->getStr('revert')); if (!strlen(trim($revision->getTitle()))) { $errors[] = 'You must provide a title.'; $e_title = 'Required'; } else { $e_title = null; } if (!strlen(trim($revision->getTestPlan()))) { $errors[] = 'You must provide a test plan.'; $e_testplan = 'Required'; } else { $e_testplan = null; } $user_phid = $request->getUser()->getPHID(); if (in_array($user_phid, $request->getArr('reviewers'))) { $errors[] = 'You may not review your own revision.'; $e_reviewers = 'Invalid'; } if (!$errors) { $editor = new DifferentialRevisionEditor($revision, $user_phid); if ($diff) { $editor->addDiff($diff, $request->getStr('comments')); } $editor->setCCPHIDs($request->getArr('cc')); $editor->setReviewers($request->getArr('reviewers')); $editor->save(); return id(new AphrontRedirectResponse())->setURI('/D' . $revision->getID()); } $reviewer_phids = $request->getArr('reviewers'); $cc_phids = $request->getArr('cc'); } else { $reviewer_phids = $revision->getReviewers(); $cc_phids = $revision->getCCPHIDs(); } $phids = array_merge($reviewer_phids, $cc_phids); $phids = array_unique($phids); $handles = id(new PhabricatorObjectHandleData($phids))->loadHandles(); $handles = mpull($handles, 'getFullName', 'getPHID'); $reviewer_map = array_select_keys($handles, $reviewer_phids); $cc_map = array_select_keys($handles, $cc_phids); $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/'); } $error_view = null; if ($errors) { $error_view = id(new AphrontErrorView())->setTitle('Form Errors')->setErrors($errors); } if ($diff && $revision->getID()) { $form->appendChild(id(new AphrontFormTextAreaControl())->setLabel('Comments')->setName('comments')->setCaption("Explain what's new in this diff.")->setValue($request->getStr('comments')))->appendChild(id(new AphrontFormSubmitControl())->setValue('Save'))->appendChild(id(new AphrontFormDividerControl())); } $form->appendChild(id(new AphrontFormTextAreaControl())->setLabel('Title')->setName('title')->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_SHORT)->setValue($revision->getTitle())->setError($e_title))->appendChild(id(new AphrontFormTextAreaControl())->setLabel('Summary')->setName('summary')->setValue($revision->getSummary()))->appendChild(id(new AphrontFormTextAreaControl())->setLabel('Test Plan')->setName('testplan')->setValue($revision->getTestPlan())->setError($e_testplan))->appendChild(id(new AphrontFormTokenizerControl())->setLabel('Reviewers')->setName('reviewers')->setDatasource('/typeahead/common/users/')->setError($e_reviewers)->setValue($reviewer_map))->appendChild(id(new AphrontFormTokenizerControl())->setLabel('CC')->setName('cc')->setDatasource('/typeahead/common/mailable/')->setValue($cc_map))->appendChild(id(new AphrontFormTextControl())->setLabel('Blame Revision')->setName('blame')->setValue($revision->getBlameRevision())->setCaption('Revision which broke the stuff which this ' . 'change fixes.'))->appendChild(id(new AphrontFormTextAreaControl())->setLabel('Revert Plan')->setName('revert')->setValue($revision->getRevertPlan())->setCaption('Special steps required to safely revert this change.')); $submit = id(new AphrontFormSubmitControl())->setValue('Save'); if ($diff) { $submit->addCancelButton('/differential/diff/' . $diff->getID() . '/'); } else { $submit->addCancelButton('/D' . $revision->getID()); } $form->appendChild($submit); $panel = new AphrontPanelView(); if ($revision->getID()) { if ($diff) { $panel->setHeader('Update Differential Revision'); } else { $panel->setHeader('Edit Differential Revision'); } } else { $panel->setHeader('Create New Differential Revision'); } $panel->appendChild($form); $panel->setWidth(AphrontPanelView::WIDTH_FORM); return $this->buildStandardPageResponse(array($error_view, $panel), array('title' => 'Edit Differential Revision')); }