Page MenuHomePhabricator

D8364.diff
No OneTemporary

D8364.diff

Index: src/applications/differential/customfield/DifferentialJIRAIssuesField.php
===================================================================
--- src/applications/differential/customfield/DifferentialJIRAIssuesField.php
+++ src/applications/differential/customfield/DifferentialJIRAIssuesField.php
@@ -3,6 +3,8 @@
final class DifferentialJIRAIssuesField
extends DifferentialStoredCustomField {
+ private $error;
+
public function getFieldKey() {
return 'phabricator:jira-issues';
}
@@ -12,7 +14,7 @@
}
public function setValueFromStorage($value) {
- $this->setValue(json_decode($value, true));
+ $this->setValue(phutil_json_decode($value));
return $this;
}
@@ -33,7 +35,7 @@
}
public function renderPropertyViewValue(array $handles) {
- $xobjs = $this->loadDoorkeeperExternalObjects();
+ $xobjs = $this->loadDoorkeeperExternalObjects($this->getValue());
if (!$xobjs) {
return null;
}
@@ -47,12 +49,12 @@
return phutil_implode_html(phutil_tag('br'), $links);
}
- private function buildDoorkeeperRefs() {
+ private function buildDoorkeeperRefs($value) {
$provider = PhabricatorAuthProviderOAuth1JIRA::getJIRAProvider();
$refs = array();
- if ($this->getValue()) {
- foreach ($this->getValue() as $jira_key) {
+ if ($value) {
+ foreach ($value as $jira_key) {
$refs[] = id(new DoorkeeperObjectRef())
->setApplicationType(DoorkeeperBridgeJIRA::APPTYPE_JIRA)
->setApplicationDomain($provider->getProviderDomain())
@@ -64,8 +66,8 @@
return $refs;
}
- private function loadDoorkeeperExternalObjects() {
- $refs = $this->buildDoorkeeperRefs();
+ private function loadDoorkeeperExternalObjects($value) {
+ $refs = $this->buildDoorkeeperRefs($value);
if (!$refs) {
return array();
}
@@ -78,6 +80,156 @@
return $xobjs;
}
- // TODO: Implement edit; this field is readonly for now.
+ public function shouldAppearInEditView() {
+ return PhabricatorAuthProviderOAuth1JIRA::getJIRAProvider();
+ }
+
+ public function shouldAppearInApplicationTransactions() {
+ return PhabricatorAuthProviderOAuth1JIRA::getJIRAProvider();
+ }
+
+ public function readValueFromRequest(AphrontRequest $request) {
+ $this->setValue($request->getStrList($this->getFieldKey()));
+ return $this;
+ }
+
+ public function renderEditControl(array $handles) {
+ return id(new AphrontFormTextControl())
+ ->setLabel(pht('JIRA Issues'))
+ ->setCaption(
+ pht('Example: %s', phutil_tag('tt', array(), 'JIS-3, JIS-9')))
+ ->setName($this->getFieldKey())
+ ->setValue(implode(', ', nonempty($this->getValue(), array())))
+ ->setError($this->error);
+ }
+
+ public function getOldValueForApplicationTransactions() {
+ return nonempty($this->getValue(), array());
+ }
+
+ public function getNewValueForApplicationTransactions() {
+ return nonempty($this->getValue(), array());
+ }
+
+ public function validateApplicationTransactions(
+ PhabricatorApplicationTransactionEditor $editor,
+ $type,
+ array $xactions) {
+
+ $this->error = null;
+
+ $errors = parent::validateApplicationTransactions(
+ $editor,
+ $type,
+ $xactions);
+
+ $transaction = null;
+ foreach ($xactions as $xaction) {
+ $value = $xaction->getNewValue();
+
+ $refs = id(new DoorkeeperImportEngine())
+ ->setViewer($this->getViewer())
+ ->setRefs($this->buildDoorkeeperRefs($value))
+ ->execute();
+
+ $bad = array();
+ foreach ($refs as $ref) {
+ if (!$ref->getIsVisible()) {
+ $bad[] = $ref->getObjectID();
+ }
+ }
+
+ if ($bad) {
+ $bad = implode(', ', $bad);
+ $this->error = pht('Invalid');
+
+ $error = new PhabricatorApplicationTransactionValidationError(
+ $type,
+ pht('Invalid'),
+ pht(
+ "Some JIRA issues could not be loaded. They may not exist, or ".
+ "you may not have permission to view them: %s",
+ $bad),
+ $xaction);
+ $errors[] = $error;
+ }
+ }
+
+ return $errors;
+ }
+
+ public function getApplicationTransactionTitle(
+ PhabricatorApplicationTransaction $xaction) {
+
+ $old = $xaction->getOldValue();
+ if (!is_array($old)) {
+ $old = array();
+ }
+
+ $new = $xaction->getNewValue();
+ if (!is_array($new)) {
+ $new = array();
+ }
+
+ $add = array_diff($new, $old);
+ $rem = array_diff($old, $new);
+
+ $author_phid = $xaction->getAuthorPHID();
+ if ($add && $rem) {
+ return pht(
+ '%s updated JIRA issue(s): added %d %s; removed %d %s.',
+ $xaction->renderHandleLink($author_phid),
+ new PhutilNumber(count($add)),
+ implode(', ', $add),
+ new PhutilNumber(count($rem)),
+ implode(', ', $rem));
+ } else if ($add) {
+ return pht(
+ '%s added %d JIRA issue(s): %s.',
+ $xaction->renderHandleLink($author_phid),
+ new PhutilNumber(count($add)),
+ implode(', ', $add));
+ } else if ($rem) {
+ return pht(
+ '%s removed %d JIRA issue(s): %s.',
+ $xaction->renderHandleLink($author_phid),
+ new PhutilNumber(count($rem)),
+ implode(', ', $rem));
+ }
+
+ return parent::getApplicationTransactionTitle($xaction);
+ }
+
+ public function applyApplicationTransactionExternalEffects(
+ PhabricatorApplicationTransaction $xaction) {
+
+ // Update the CustomField storage.
+ parent::applyApplicationTransactionExternalEffects($xaction);
+
+ // Now, synchronize the Doorkeeper edges.
+ $revision = $this->getObject();
+ $revision_phid = $revision->getPHID();
+
+ $edge_type = PhabricatorEdgeConfig::TYPE_PHOB_HAS_JIRAISSUE;
+ $xobjs = $this->loadDoorkeeperExternalObjects($xaction->getNewValue());
+ $edge_dsts = mpull($xobjs, 'getPHID');
+
+ $edges = PhabricatorEdgeQuery::loadDestinationPHIDs(
+ $revision_phid,
+ $edge_type);
+
+ $editor = id(new PhabricatorEdgeEditor())
+ ->setActor($this->getViewer());
+
+ foreach (array_diff($edges, $edge_dsts) as $rem_edge) {
+ $editor->removeEdge($revision_phid, $edge_type, $rem_edge);
+ }
+
+ foreach (array_diff($edge_dsts, $edges) as $add_edge) {
+ $editor->addEdge($revision_phid, $edge_type, $add_edge);
+ }
+
+ $editor->save();
+ }
}
Index: src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
===================================================================
--- src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
+++ src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
@@ -1806,6 +1806,8 @@
"integration for ApplicationTransactions.");
}
+ $field->setViewer($this->getActor());
+
return $field;
}

File Metadata

Mime Type
text/plain
Expires
Wed, Nov 20, 12:51 PM (10 h, 11 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6733456
Default Alt Text
D8364.diff (6 KB)

Event Timeline