Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/maniphest/relationship/ManiphestTaskCloseAsDuplicateRelationship.php b/src/applications/maniphest/relationship/ManiphestTaskCloseAsDuplicateRelationship.php
index 696ceb615e..6428c79b55 100644
--- a/src/applications/maniphest/relationship/ManiphestTaskCloseAsDuplicateRelationship.php
+++ b/src/applications/maniphest/relationship/ManiphestTaskCloseAsDuplicateRelationship.php
@@ -1,84 +1,85 @@
<?php
final class ManiphestTaskCloseAsDuplicateRelationship
extends ManiphestTaskRelationship {
const RELATIONSHIPKEY = 'task.close-as-duplicate';
public function getEdgeConstant() {
return ManiphestTaskIsDuplicateOfTaskEdgeType::EDGECONST;
}
protected function getActionName() {
return pht('Close As Duplicate');
}
protected function getActionIcon() {
return 'fa-times';
}
public function canRelateObjects($src, $dst) {
return ($dst instanceof ManiphestTask);
}
public function shouldAppearInActionMenu() {
return false;
}
public function getDialogTitleText() {
return pht('Close As Duplicate');
}
public function getDialogHeaderText() {
return pht('Close This Task As a Duplicate Of');
}
public function getDialogButtonText() {
return pht('Merge Into Selected Task');
}
protected function newRelationshipSource() {
- return new ManiphestTaskRelationshipSource();
+ return id(new ManiphestTaskRelationshipSource())
+ ->setSelectedFilter('open');
}
public function getRequiredRelationshipCapabilities() {
return array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
);
}
public function canUndoRelationship() {
return false;
}
public function willUpdateRelationships($object, array $add, array $rem) {
// TODO: Communicate this in the UI before users hit this error.
if (count($add) > 1) {
throw new Exception(
pht(
'A task can only be closed as a duplicate of exactly one other '.
'task.'));
}
$task = head($add);
return $this->newMergeIntoTransactions($task);
}
public function didUpdateRelationships($object, array $add, array $rem) {
$viewer = $this->getViewer();
$content_source = $this->getContentSource();
$task = head($add);
$xactions = $this->newMergeFromTransactions(array($object));
$task->getApplicationTransactionEditor()
->setActor($viewer)
->setContentSource($content_source)
->setContinueOnMissingFields(true)
->setContinueOnNoEffect(true)
->applyTransactions($task, $xactions);
}
}
diff --git a/src/applications/maniphest/relationship/ManiphestTaskHasParentRelationship.php b/src/applications/maniphest/relationship/ManiphestTaskHasParentRelationship.php
index 6210e3c4d4..6cfd11ff09 100644
--- a/src/applications/maniphest/relationship/ManiphestTaskHasParentRelationship.php
+++ b/src/applications/maniphest/relationship/ManiphestTaskHasParentRelationship.php
@@ -1,44 +1,45 @@
<?php
final class ManiphestTaskHasParentRelationship
extends ManiphestTaskRelationship {
const RELATIONSHIPKEY = 'task.has-parent';
public function getEdgeConstant() {
return ManiphestTaskDependedOnByTaskEdgeType::EDGECONST;
}
protected function getActionName() {
return pht('Edit Parent Tasks');
}
protected function getActionIcon() {
return 'fa-chevron-circle-up';
}
public function canRelateObjects($src, $dst) {
return ($dst instanceof ManiphestTask);
}
public function shouldAppearInActionMenu() {
return false;
}
public function getDialogTitleText() {
return pht('Edit Parent Tasks');
}
public function getDialogHeaderText() {
return pht('Current Parent Tasks');
}
public function getDialogButtonText() {
return pht('Save Parent Tasks');
}
protected function newRelationshipSource() {
- return new ManiphestTaskRelationshipSource();
+ return id(new ManiphestTaskRelationshipSource())
+ ->setSelectedFilter('open');
}
}
diff --git a/src/applications/maniphest/relationship/ManiphestTaskHasSubtaskRelationship.php b/src/applications/maniphest/relationship/ManiphestTaskHasSubtaskRelationship.php
index 335ac03d42..2fb69e90fb 100644
--- a/src/applications/maniphest/relationship/ManiphestTaskHasSubtaskRelationship.php
+++ b/src/applications/maniphest/relationship/ManiphestTaskHasSubtaskRelationship.php
@@ -1,44 +1,45 @@
<?php
final class ManiphestTaskHasSubtaskRelationship
extends ManiphestTaskRelationship {
const RELATIONSHIPKEY = 'task.has-subtask';
public function getEdgeConstant() {
return ManiphestTaskDependsOnTaskEdgeType::EDGECONST;
}
protected function getActionName() {
return pht('Edit Subtasks');
}
protected function getActionIcon() {
return 'fa-chevron-circle-down';
}
public function canRelateObjects($src, $dst) {
return ($dst instanceof ManiphestTask);
}
public function shouldAppearInActionMenu() {
return false;
}
public function getDialogTitleText() {
return pht('Edit Subtasks');
}
public function getDialogHeaderText() {
return pht('Current Subtasks');
}
public function getDialogButtonText() {
return pht('Save Subtasks');
}
protected function newRelationshipSource() {
- return new ManiphestTaskRelationshipSource();
+ return id(new ManiphestTaskRelationshipSource())
+ ->setSelectedFilter('open');
}
}
diff --git a/src/applications/maniphest/relationship/ManiphestTaskMergeInRelationship.php b/src/applications/maniphest/relationship/ManiphestTaskMergeInRelationship.php
index 5bf45b7911..c8442c428f 100644
--- a/src/applications/maniphest/relationship/ManiphestTaskMergeInRelationship.php
+++ b/src/applications/maniphest/relationship/ManiphestTaskMergeInRelationship.php
@@ -1,75 +1,76 @@
<?php
final class ManiphestTaskMergeInRelationship
extends ManiphestTaskRelationship {
const RELATIONSHIPKEY = 'task.merge-in';
public function getEdgeConstant() {
return ManiphestTaskHasDuplicateTaskEdgeType::EDGECONST;
}
protected function getActionName() {
return pht('Merge Duplicates In');
}
protected function getActionIcon() {
return 'fa-compress';
}
public function canRelateObjects($src, $dst) {
return ($dst instanceof ManiphestTask);
}
public function shouldAppearInActionMenu() {
return false;
}
public function getDialogTitleText() {
return pht('Merge Duplicates Into This Task');
}
public function getDialogHeaderText() {
return pht('Tasks to Close and Merge');
}
public function getDialogButtonText() {
return pht('Close and Merge Selected Tasks');
}
protected function newRelationshipSource() {
- return new ManiphestTaskRelationshipSource();
+ return id(new ManiphestTaskRelationshipSource())
+ ->setSelectedFilter('open');
}
public function getRequiredRelationshipCapabilities() {
return array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
);
}
public function canUndoRelationship() {
return false;
}
public function willUpdateRelationships($object, array $add, array $rem) {
return $this->newMergeFromTransactions($add);
}
public function didUpdateRelationships($object, array $add, array $rem) {
$viewer = $this->getViewer();
$content_source = $this->getContentSource();
foreach ($add as $task) {
$xactions = $this->newMergeIntoTransactions($object);
$task->getApplicationTransactionEditor()
->setActor($viewer)
->setContentSource($content_source)
->setContinueOnMissingFields(true)
->setContinueOnNoEffect(true)
->applyTransactions($task, $xactions);
}
}
}
diff --git a/src/applications/search/controller/PhabricatorSearchRelationshipController.php b/src/applications/search/controller/PhabricatorSearchRelationshipController.php
index 767c756813..14c705ac62 100644
--- a/src/applications/search/controller/PhabricatorSearchRelationshipController.php
+++ b/src/applications/search/controller/PhabricatorSearchRelationshipController.php
@@ -1,219 +1,216 @@
<?php
final class PhabricatorSearchRelationshipController
extends PhabricatorSearchBaseController {
public function handleRequest(AphrontRequest $request) {
$viewer = $this->getViewer();
$object = $this->loadRelationshipObject();
if (!$object) {
return new Aphront404Response();
}
$relationship = $this->loadRelationship($object);
if (!$relationship) {
return new Aphront404Response();
}
$src_phid = $object->getPHID();
$edge_type = $relationship->getEdgeConstant();
// If this is a normal relationship, users can remove related objects. If
// it's a special relationship like a merge, we can't undo it, so we won't
// prefill the current related objects.
if ($relationship->canUndoRelationship()) {
$dst_phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
$src_phid,
$edge_type);
} else {
$dst_phids = array();
}
$all_phids = $dst_phids;
$all_phids[] = $src_phid;
$handles = $viewer->loadHandles($all_phids);
$src_handle = $handles[$src_phid];
$done_uri = $src_handle->getURI();
$initial_phids = $dst_phids;
if ($request->isFormPost()) {
$phids = explode(';', $request->getStr('phids'));
$phids = array_filter($phids);
$phids = array_values($phids);
$initial_phids = $request->getStrList('initialPHIDs');
// Apply the changes as adds and removes relative to the original state
// of the object when the dialog was rendered so that two users adding
// relationships at the same time don't race and overwrite one another.
$add_phids = array_diff($phids, $initial_phids);
$rem_phids = array_diff($initial_phids, $phids);
$all_phids = array_merge($add_phids, $rem_phids);
$capabilities = $relationship->getRequiredRelationshipCapabilities();
if ($all_phids) {
$dst_objects = id(new PhabricatorObjectQuery())
->setViewer($viewer)
->withPHIDs($all_phids)
->setRaisePolicyExceptions(true)
->requireCapabilities($capabilities)
->execute();
$dst_objects = mpull($dst_objects, null, 'getPHID');
} else {
$dst_objects = array();
}
try {
foreach ($add_phids as $add_phid) {
$dst_object = idx($dst_objects, $add_phid);
if (!$dst_object) {
throw new Exception(
pht(
'You can not create a relationship to object "%s" because '.
'the object does not exist or could not be loaded.',
$add_phid));
}
if ($add_phid == $src_phid) {
throw new Exception(
pht(
'You can not create a relationship to object "%s" because '.
'objects can not be related to themselves.',
$add_phid));
}
if (!$relationship->canRelateObjects($object, $dst_object)) {
throw new Exception(
pht(
'You can not create a relationship (of type "%s") to object '.
'"%s" because it is not the right type of object for this '.
'relationship.',
$relationship->getRelationshipConstant(),
$add_phid));
}
}
} catch (Exception $ex) {
return $this->newUnrelatableObjectResponse($ex, $done_uri);
}
$content_source = PhabricatorContentSource::newFromRequest($request);
$relationship->setContentSource($content_source);
$editor = $object->getApplicationTransactionEditor()
->setActor($viewer)
->setContentSource($content_source)
->setContinueOnMissingFields(true)
->setContinueOnNoEffect(true);
$xactions = array();
$xactions[] = $object->getApplicationTransactionTemplate()
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
->setMetadataValue('edge:type', $edge_type)
->setNewValue(array(
'+' => array_fuse($add_phids),
'-' => array_fuse($rem_phids),
));
$add_objects = array_select_keys($dst_objects, $add_phids);
$rem_objects = array_select_keys($dst_objects, $rem_phids);
if ($add_objects || $rem_objects) {
$more_xactions = $relationship->willUpdateRelationships(
$object,
$add_objects,
$rem_objects);
foreach ($more_xactions as $xaction) {
$xactions[] = $xaction;
}
}
try {
$editor->applyTransactions($object, $xactions);
if ($add_objects || $rem_objects) {
$relationship->didUpdateRelationships(
$object,
$add_objects,
$rem_objects);
}
return id(new AphrontRedirectResponse())->setURI($done_uri);
} catch (PhabricatorEdgeCycleException $ex) {
return $this->newGraphCycleResponse($ex, $done_uri);
}
}
$handles = iterator_to_array($handles);
$handles = array_select_keys($handles, $dst_phids);
- // TODO: These are hard-coded for now.
- $filters = array(
- 'assigned' => pht('Assigned to Me'),
- 'created' => pht('Created By Me'),
- 'open' => pht('All Open Objects'),
- 'all' => pht('All Objects'),
- );
-
$dialog_title = $relationship->getDialogTitleText();
$dialog_header = $relationship->getDialogHeaderText();
$dialog_button = $relationship->getDialogButtonText();
$dialog_instructions = $relationship->getDialogInstructionsText();
$source_uri = $relationship->getSourceURI($object);
+ $source = $relationship->newSource();
+
+ $filters = $source->getFilters();
+ $selected_filter = $source->getSelectedFilter();
+
return id(new PhabricatorObjectSelectorDialog())
->setUser($viewer)
->setInitialPHIDs($initial_phids)
->setHandles($handles)
->setFilters($filters)
- ->setSelectedFilter('created')
+ ->setSelectedFilter($selected_filter)
->setExcluded($src_phid)
->setCancelURI($done_uri)
->setSearchURI($source_uri)
->setTitle($dialog_title)
->setHeader($dialog_header)
->setButtonText($dialog_button)
->setInstructions($dialog_instructions)
->buildDialog();
}
private function newGraphCycleResponse(
PhabricatorEdgeCycleException $ex,
$done_uri) {
$viewer = $this->getViewer();
$cycle = $ex->getCycle();
$handles = $this->loadViewerHandles($cycle);
$names = array();
foreach ($cycle as $cycle_phid) {
$names[] = $handles[$cycle_phid]->getFullName();
}
$message = pht(
'You can not create that relationship because it would create a '.
'circular dependency:');
$list = implode(" \xE2\x86\x92 ", $names);
return $this->newDialog()
->setTitle(pht('Circular Dependency'))
->appendParagraph($message)
->appendParagraph($list)
->addCancelButton($done_uri);
}
private function newUnrelatableObjectResponse(Exception $ex, $done_uri) {
$message = $ex->getMessage();
return $this->newDialog()
->setTitle(pht('Invalid Relationship'))
->appendParagraph($message)
->addCancelButton($done_uri);
}
}
diff --git a/src/applications/search/relationship/DiffusionCommitRelationshipSource.php b/src/applications/search/relationship/DiffusionCommitRelationshipSource.php
index 31fc918011..25c799caf4 100644
--- a/src/applications/search/relationship/DiffusionCommitRelationshipSource.php
+++ b/src/applications/search/relationship/DiffusionCommitRelationshipSource.php
@@ -1,20 +1,26 @@
<?php
final class DiffusionCommitRelationshipSource
extends PhabricatorObjectRelationshipSource {
public function isEnabledForObject($object) {
$viewer = $this->getViewer();
return PhabricatorApplication::isClassInstalledForViewer(
'PhabricatorDiffusionApplication',
$viewer);
}
public function getResultPHIDTypes() {
return array(
PhabricatorRepositoryCommitPHIDType::TYPECONST,
);
}
+ public function getFilters() {
+ $filters = parent::getFilters();
+ unset($filters['assigned']);
+ return $filters;
+ }
+
}
diff --git a/src/applications/search/relationship/PhabricatorObjectRelationshipSource.php b/src/applications/search/relationship/PhabricatorObjectRelationshipSource.php
index a1fc9a6370..9990740b4f 100644
--- a/src/applications/search/relationship/PhabricatorObjectRelationshipSource.php
+++ b/src/applications/search/relationship/PhabricatorObjectRelationshipSource.php
@@ -1,19 +1,48 @@
<?php
abstract class PhabricatorObjectRelationshipSource extends Phobject {
private $viewer;
+ private $selectedFilter;
final public function setViewer(PhabricatorUser $viewer) {
$this->viewer = $viewer;
return $this;
}
final public function getViewer() {
return $this->viewer;
}
abstract public function isEnabledForObject($object);
abstract public function getResultPHIDTypes();
+ protected function getDefaultFilter() {
+ return 'created';
+ }
+
+ final public function setSelectedFilter($selected_filter) {
+ $this->selectedFilter = $selected_filter;
+ return $this;
+ }
+
+ final public function getSelectedFilter() {
+ if ($this->selectedFilter === null) {
+ return $this->getDefaultFilter();
+ }
+
+ return $this->selectedFilter;
+ }
+
+ public function getFilters() {
+ // TODO: These are hard-coded for now, and all of this will probably be
+ // rewritten when we move to ApplicationSearch.
+ return array(
+ 'assigned' => pht('Assigned to Me'),
+ 'created' => pht('Created By Me'),
+ 'open' => pht('All Open Objects'),
+ 'all' => pht('All Objects'),
+ );
+ }
+
}
diff --git a/src/applications/search/relationship/PholioMockRelationshipSource.php b/src/applications/search/relationship/PholioMockRelationshipSource.php
index b378f8ef41..b21fd6624b 100644
--- a/src/applications/search/relationship/PholioMockRelationshipSource.php
+++ b/src/applications/search/relationship/PholioMockRelationshipSource.php
@@ -1,20 +1,26 @@
<?php
final class PholioMockRelationshipSource
extends PhabricatorObjectRelationshipSource {
public function isEnabledForObject($object) {
$viewer = $this->getViewer();
return PhabricatorApplication::isClassInstalledForViewer(
'PhabricatorPholioApplication',
$viewer);
}
public function getResultPHIDTypes() {
return array(
PholioMockPHIDType::TYPECONST,
);
}
+ public function getFilters() {
+ $filters = parent::getFilters();
+ unset($filters['assigned']);
+ return $filters;
+ }
+
}
diff --git a/src/applications/search/storage/document/PhabricatorSearchDocument.php b/src/applications/search/storage/document/PhabricatorSearchDocument.php
index 161e791316..3e177c9813 100644
--- a/src/applications/search/storage/document/PhabricatorSearchDocument.php
+++ b/src/applications/search/storage/document/PhabricatorSearchDocument.php
@@ -1,37 +1,40 @@
<?php
final class PhabricatorSearchDocument extends PhabricatorSearchDAO {
protected $documentType;
protected $documentTitle;
protected $documentCreated;
protected $documentModified;
protected function getConfiguration() {
return array(
self::CONFIG_TIMESTAMPS => false,
self::CONFIG_IDS => self::IDS_MANUAL,
self::CONFIG_COLUMN_SCHEMA => array(
'documentType' => 'text4',
'documentTitle' => 'text255',
'documentCreated' => 'epoch',
'documentModified' => 'epoch',
),
self::CONFIG_KEY_SCHEMA => array(
'key_phid' => null,
'PRIMARY' => array(
'columns' => array('phid'),
'unique' => true,
),
'documentCreated' => array(
'columns' => array('documentCreated'),
),
+ 'key_type' => array(
+ 'columns' => array('documentType', 'documentCreated'),
+ ),
),
) + parent::getConfiguration();
}
public function getIDKey() {
return 'phid';
}
}

File Metadata

Mime Type
text/x-diff
Expires
Fri, Mar 14, 6:19 AM (2 h, 38 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
71632
Default Alt Text
(20 KB)

Event Timeline