2011-02-08 19:53:59 +01:00
|
|
|
<?php
|
|
|
|
|
2013-10-22 01:58:37 +02:00
|
|
|
final class ManiphestTransactionEditor
|
|
|
|
extends PhabricatorApplicationTransactionEditor {
|
2011-02-08 19:53:59 +01:00
|
|
|
|
2014-03-14 19:52:31 +01:00
|
|
|
private $heraldEmailPHIDs = array();
|
|
|
|
|
2013-10-22 01:58:37 +02:00
|
|
|
public function getTransactionTypes() {
|
|
|
|
$types = parent::getTransactionTypes();
|
2011-05-10 01:31:26 +02:00
|
|
|
|
2013-10-22 01:58:37 +02:00
|
|
|
$types[] = PhabricatorTransactions::TYPE_COMMENT;
|
|
|
|
$types[] = ManiphestTransaction::TYPE_PRIORITY;
|
|
|
|
$types[] = ManiphestTransaction::TYPE_STATUS;
|
|
|
|
$types[] = ManiphestTransaction::TYPE_TITLE;
|
|
|
|
$types[] = ManiphestTransaction::TYPE_DESCRIPTION;
|
|
|
|
$types[] = ManiphestTransaction::TYPE_OWNER;
|
|
|
|
$types[] = ManiphestTransaction::TYPE_CCS;
|
|
|
|
$types[] = ManiphestTransaction::TYPE_PROJECTS;
|
|
|
|
$types[] = ManiphestTransaction::TYPE_ATTACH;
|
|
|
|
$types[] = ManiphestTransaction::TYPE_EDGE;
|
2014-02-27 18:39:59 +01:00
|
|
|
$types[] = ManiphestTransaction::TYPE_SUBPRIORITY;
|
2014-03-04 00:58:00 +01:00
|
|
|
$types[] = ManiphestTransaction::TYPE_PROJECT_COLUMN;
|
2013-10-22 01:58:37 +02:00
|
|
|
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
|
|
|
|
$types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
|
|
|
|
|
|
|
|
return $types;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function getCustomTransactionOldValue(
|
|
|
|
PhabricatorLiskDAO $object,
|
|
|
|
PhabricatorApplicationTransaction $xaction) {
|
|
|
|
|
|
|
|
switch ($xaction->getTransactionType()) {
|
|
|
|
case ManiphestTransaction::TYPE_PRIORITY:
|
|
|
|
if ($this->getIsNewObject()) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return (int)$object->getPriority();
|
|
|
|
case ManiphestTransaction::TYPE_STATUS:
|
|
|
|
if ($this->getIsNewObject()) {
|
|
|
|
return null;
|
|
|
|
}
|
Use string constants, not integer constants, to represent task status internally
Summary:
Ref T1812. I think integer constants are going to be confusing and error prone for users to interact with. For example, because we use 0-5, adding a second "open" status like "needs verification" without disrupting the existing statuses would require users to define a status with, e.g., constant `6`, but order it between constants `0` and `1`. And if they later remove statuses, they need to avoid reusing existing constants.
Instead, use more manageable string constants like "open", "resolved", etc.
We must migrate three tables:
- The task table itself, to update task status.
- The transaction table, to update historic status changes.
- The saved query table, to update saved queries which specify status sets.
Test Plan:
- Saved a query with complicated status filters.
- Ran migrations.
- Looked at the query, at existing tasks, and at task transactions.
- Forced migrations to run again to verify idempotentcy/safety.
Reviewers: btrahan
Reviewed By: btrahan
Subscribers: epriestley
Maniphest Tasks: T1812
Differential Revision: https://secure.phabricator.com/D8583
2014-03-25 21:58:14 +01:00
|
|
|
return $object->getStatus();
|
2013-10-22 01:58:37 +02:00
|
|
|
case ManiphestTransaction::TYPE_TITLE:
|
|
|
|
if ($this->getIsNewObject()) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return $object->getTitle();
|
|
|
|
case ManiphestTransaction::TYPE_DESCRIPTION:
|
|
|
|
if ($this->getIsNewObject()) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return $object->getDescription();
|
|
|
|
case ManiphestTransaction::TYPE_OWNER:
|
|
|
|
return nonempty($object->getOwnerPHID(), null);
|
|
|
|
case ManiphestTransaction::TYPE_CCS:
|
|
|
|
return array_values(array_unique($object->getCCPHIDs()));
|
|
|
|
case ManiphestTransaction::TYPE_PROJECTS:
|
|
|
|
return array_values(array_unique($object->getProjectPHIDs()));
|
|
|
|
case ManiphestTransaction::TYPE_ATTACH:
|
|
|
|
return $object->getAttached();
|
|
|
|
case ManiphestTransaction::TYPE_EDGE:
|
2014-03-04 00:58:00 +01:00
|
|
|
case ManiphestTransaction::TYPE_PROJECT_COLUMN:
|
2013-10-22 01:58:37 +02:00
|
|
|
// These are pre-populated.
|
|
|
|
return $xaction->getOldValue();
|
2014-02-27 18:39:59 +01:00
|
|
|
case ManiphestTransaction::TYPE_SUBPRIORITY:
|
|
|
|
return $object->getSubpriority();
|
2013-10-22 01:58:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function getCustomTransactionNewValue(
|
|
|
|
PhabricatorLiskDAO $object,
|
|
|
|
PhabricatorApplicationTransaction $xaction) {
|
|
|
|
|
|
|
|
switch ($xaction->getTransactionType()) {
|
|
|
|
case ManiphestTransaction::TYPE_PRIORITY:
|
|
|
|
return (int)$xaction->getNewValue();
|
|
|
|
case ManiphestTransaction::TYPE_CCS:
|
|
|
|
case ManiphestTransaction::TYPE_PROJECTS:
|
|
|
|
return array_values(array_unique($xaction->getNewValue()));
|
|
|
|
case ManiphestTransaction::TYPE_OWNER:
|
|
|
|
return nonempty($xaction->getNewValue(), null);
|
Use string constants, not integer constants, to represent task status internally
Summary:
Ref T1812. I think integer constants are going to be confusing and error prone for users to interact with. For example, because we use 0-5, adding a second "open" status like "needs verification" without disrupting the existing statuses would require users to define a status with, e.g., constant `6`, but order it between constants `0` and `1`. And if they later remove statuses, they need to avoid reusing existing constants.
Instead, use more manageable string constants like "open", "resolved", etc.
We must migrate three tables:
- The task table itself, to update task status.
- The transaction table, to update historic status changes.
- The saved query table, to update saved queries which specify status sets.
Test Plan:
- Saved a query with complicated status filters.
- Ran migrations.
- Looked at the query, at existing tasks, and at task transactions.
- Forced migrations to run again to verify idempotentcy/safety.
Reviewers: btrahan
Reviewed By: btrahan
Subscribers: epriestley
Maniphest Tasks: T1812
Differential Revision: https://secure.phabricator.com/D8583
2014-03-25 21:58:14 +01:00
|
|
|
case ManiphestTransaction::TYPE_STATUS:
|
2013-10-22 01:58:37 +02:00
|
|
|
case ManiphestTransaction::TYPE_TITLE:
|
|
|
|
case ManiphestTransaction::TYPE_DESCRIPTION:
|
|
|
|
case ManiphestTransaction::TYPE_ATTACH:
|
|
|
|
case ManiphestTransaction::TYPE_EDGE:
|
2014-02-27 18:39:59 +01:00
|
|
|
case ManiphestTransaction::TYPE_SUBPRIORITY:
|
2014-03-04 00:58:00 +01:00
|
|
|
case ManiphestTransaction::TYPE_PROJECT_COLUMN:
|
2013-10-22 01:58:37 +02:00
|
|
|
return $xaction->getNewValue();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Add capabilities for editing task triage details (priority, assignee, etc)
Summary:
This is primarily a client request, and a little bit use-case specific, but policies seem to be holding up well and I'm getting more comfortable about maintaining this. Much if it can run through ApplicationTransactions.
Allow the ability to edit status, policies, priorities, assignees and projects of a task to be restricted to some subset of users. Also allow bulk edit to be locked. This affects the editor itself and the edit, view and list interfaces.
Test Plan: As a restricted user, created, edited and commented on tasks. Tried to drag them around.
Reviewers: btrahan
Reviewed By: btrahan
CC: aran
Differential Revision: https://secure.phabricator.com/D7357
2013-10-22 01:59:06 +02:00
|
|
|
|
2013-10-22 01:58:37 +02:00
|
|
|
protected function transactionHasEffect(
|
|
|
|
PhabricatorLiskDAO $object,
|
|
|
|
PhabricatorApplicationTransaction $xaction) {
|
|
|
|
|
|
|
|
$old = $xaction->getOldValue();
|
|
|
|
$new = $xaction->getNewValue();
|
|
|
|
|
|
|
|
switch ($xaction->getTransactionType()) {
|
|
|
|
case ManiphestTransaction::TYPE_PROJECTS:
|
|
|
|
case ManiphestTransaction::TYPE_CCS:
|
|
|
|
sort($old);
|
|
|
|
sort($new);
|
|
|
|
return ($old !== $new);
|
2014-03-04 00:58:00 +01:00
|
|
|
case ManiphestTransaction::TYPE_PROJECT_COLUMN:
|
|
|
|
$new_column_phids = $new['columnPHIDs'];
|
|
|
|
$old_column_phids = $old['columnPHIDs'];
|
|
|
|
sort($new_column_phids);
|
|
|
|
sort($old_column_phids);
|
|
|
|
return ($old !== $new);
|
2013-10-22 01:58:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return parent::transactionHasEffect($object, $xaction);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function applyCustomInternalTransaction(
|
|
|
|
PhabricatorLiskDAO $object,
|
|
|
|
PhabricatorApplicationTransaction $xaction) {
|
|
|
|
|
|
|
|
switch ($xaction->getTransactionType()) {
|
|
|
|
case ManiphestTransaction::TYPE_PRIORITY:
|
|
|
|
return $object->setPriority($xaction->getNewValue());
|
|
|
|
case ManiphestTransaction::TYPE_STATUS:
|
|
|
|
return $object->setStatus($xaction->getNewValue());
|
|
|
|
case ManiphestTransaction::TYPE_TITLE:
|
|
|
|
return $object->setTitle($xaction->getNewValue());
|
|
|
|
case ManiphestTransaction::TYPE_DESCRIPTION:
|
|
|
|
return $object->setDescription($xaction->getNewValue());
|
|
|
|
case ManiphestTransaction::TYPE_OWNER:
|
2013-11-19 23:10:54 +01:00
|
|
|
$phid = $xaction->getNewValue();
|
|
|
|
|
|
|
|
// Update the "ownerOrdering" column to contain the full name of the
|
|
|
|
// owner, if the task is assigned.
|
|
|
|
|
|
|
|
$handle = null;
|
|
|
|
if ($phid) {
|
|
|
|
$handle = id(new PhabricatorHandleQuery())
|
|
|
|
->setViewer($this->getActor())
|
|
|
|
->withPHIDs(array($phid))
|
|
|
|
->executeOne();
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($handle) {
|
|
|
|
$object->setOwnerOrdering($handle->getName());
|
|
|
|
} else {
|
|
|
|
$object->setOwnerOrdering(null);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $object->setOwnerPHID($phid);
|
2013-10-22 01:58:37 +02:00
|
|
|
case ManiphestTransaction::TYPE_CCS:
|
|
|
|
return $object->setCCPHIDs($xaction->getNewValue());
|
|
|
|
case ManiphestTransaction::TYPE_PROJECTS:
|
|
|
|
return $object->setProjectPHIDs($xaction->getNewValue());
|
|
|
|
case ManiphestTransaction::TYPE_ATTACH:
|
|
|
|
return $object->setAttached($xaction->getNewValue());
|
|
|
|
case ManiphestTransaction::TYPE_EDGE:
|
|
|
|
// These are a weird, funky mess and are already being applied by the
|
|
|
|
// time we reach this.
|
|
|
|
return;
|
2014-02-27 18:39:59 +01:00
|
|
|
case ManiphestTransaction::TYPE_SUBPRIORITY:
|
|
|
|
$data = $xaction->getNewValue();
|
|
|
|
$new_sub = $this->getNextSubpriority(
|
|
|
|
$data['newPriority'],
|
|
|
|
$data['newSubpriorityBase']);
|
|
|
|
$object->setSubpriority($new_sub);
|
|
|
|
return;
|
2014-03-04 00:58:00 +01:00
|
|
|
case ManiphestTransaction::TYPE_PROJECT_COLUMN:
|
|
|
|
// these do external (edge) updates
|
|
|
|
return;
|
2013-10-22 01:58:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2014-02-27 18:39:59 +01:00
|
|
|
protected function expandTransaction(
|
|
|
|
PhabricatorLiskDAO $object,
|
|
|
|
PhabricatorApplicationTransaction $xaction) {
|
|
|
|
|
|
|
|
$xactions = parent::expandTransaction($object, $xaction);
|
|
|
|
switch ($xaction->getTransactionType()) {
|
|
|
|
case ManiphestTransaction::TYPE_SUBPRIORITY:
|
|
|
|
$data = $xaction->getNewValue();
|
|
|
|
$new_pri = $data['newPriority'];
|
|
|
|
if ($new_pri != $object->getPriority()) {
|
|
|
|
$xactions[] = id(new ManiphestTransaction())
|
|
|
|
->setTransactionType(ManiphestTransaction::TYPE_PRIORITY)
|
|
|
|
->setNewValue($new_pri);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $xactions;
|
|
|
|
}
|
|
|
|
|
2013-10-22 01:58:37 +02:00
|
|
|
protected function applyCustomExternalTransaction(
|
|
|
|
PhabricatorLiskDAO $object,
|
|
|
|
PhabricatorApplicationTransaction $xaction) {
|
2014-03-04 00:58:00 +01:00
|
|
|
|
|
|
|
switch ($xaction->getTransactionType()) {
|
|
|
|
case ManiphestTransaction::TYPE_PROJECT_COLUMN:
|
|
|
|
$new = $xaction->getNewValue();
|
|
|
|
$old = $xaction->getOldValue();
|
|
|
|
$src = $object->getPHID();
|
|
|
|
$dst = head($new['columnPHIDs']);
|
|
|
|
$edges = $old['columnPHIDs'];
|
|
|
|
$edge_type = PhabricatorEdgeConfig::TYPE_OBJECT_HAS_COLUMN;
|
|
|
|
// NOTE: Normally, we expect only one edge to exist, but this works in
|
|
|
|
// a general way so it will repair any stray edges.
|
|
|
|
$remove = array();
|
|
|
|
$edge_missing = true;
|
|
|
|
foreach ($edges as $phid) {
|
|
|
|
if ($phid == $dst) {
|
|
|
|
$edge_missing = false;
|
|
|
|
} else {
|
|
|
|
$remove[] = $phid;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$add = array();
|
|
|
|
if ($edge_missing) {
|
|
|
|
$add[] = $dst;
|
|
|
|
}
|
|
|
|
|
|
|
|
// This should never happen because of the code in
|
|
|
|
// transactionHasEffect, but keep it for maximum conservativeness
|
|
|
|
if (!$add && !$remove) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
$editor = id(new PhabricatorEdgeEditor())
|
|
|
|
->setActor($this->getActor())
|
|
|
|
->setSuppressEvents(true);
|
|
|
|
|
|
|
|
foreach ($add as $phid) {
|
|
|
|
$editor->addEdge($src, $edge_type, $phid);
|
|
|
|
}
|
|
|
|
foreach ($remove as $phid) {
|
|
|
|
$editor->removeEdge($src, $edge_type, $phid);
|
|
|
|
}
|
|
|
|
$editor->save();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2013-10-22 01:58:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
protected function shouldSendMail(
|
|
|
|
PhabricatorLiskDAO $object,
|
|
|
|
array $xactions) {
|
2014-03-04 00:58:00 +01:00
|
|
|
|
2014-03-05 02:01:33 +01:00
|
|
|
$xactions = mfilter($xactions, 'shouldHide', true);
|
|
|
|
return $xactions;
|
2013-10-22 01:58:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
protected function getMailSubjectPrefix() {
|
|
|
|
return PhabricatorEnv::getEnvConfig('metamta.maniphest.subject-prefix');
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function getMailThreadID(PhabricatorLiskDAO $object) {
|
|
|
|
return 'maniphest-task-'.$object->getPHID();
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function getMailTo(PhabricatorLiskDAO $object) {
|
|
|
|
return array(
|
|
|
|
$object->getOwnerPHID(),
|
|
|
|
$this->requireActor()->getPHID(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function getMailCC(PhabricatorLiskDAO $object) {
|
2014-03-14 19:52:31 +01:00
|
|
|
$phids = array();
|
|
|
|
|
|
|
|
foreach ($object->getCCPHIDs() as $phid) {
|
|
|
|
$phids[] = $phid;
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach ($this->heraldEmailPHIDs as $phid) {
|
|
|
|
$phids[] = $phid;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $phids;
|
2013-10-22 01:58:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
protected function buildReplyHandler(PhabricatorLiskDAO $object) {
|
|
|
|
return id(new ManiphestReplyHandler())
|
|
|
|
->setMailReceiver($object);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function buildMailTemplate(PhabricatorLiskDAO $object) {
|
|
|
|
$id = $object->getID();
|
|
|
|
$title = $object->getTitle();
|
|
|
|
|
|
|
|
return id(new PhabricatorMetaMTAMail())
|
|
|
|
->setSubject("T{$id}: {$title}")
|
|
|
|
->addHeader('Thread-Topic', "T{$id}: ".$object->getOriginalTitle());
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function buildMailBody(
|
|
|
|
PhabricatorLiskDAO $object,
|
|
|
|
array $xactions) {
|
|
|
|
|
|
|
|
$body = parent::buildMailBody($object, $xactions);
|
|
|
|
|
|
|
|
if ($this->getIsNewObject()) {
|
|
|
|
$body->addTextSection(
|
|
|
|
pht('TASK DESCRIPTION'),
|
|
|
|
$object->getDescription());
|
|
|
|
}
|
|
|
|
|
|
|
|
$body->addTextSection(
|
|
|
|
pht('TASK DETAIL'),
|
|
|
|
PhabricatorEnv::getProductionURI('/T'.$object->getID()));
|
|
|
|
|
|
|
|
return $body;
|
|
|
|
}
|
|
|
|
|
2014-03-05 02:01:33 +01:00
|
|
|
protected function shouldPublishFeedStory(
|
|
|
|
PhabricatorLiskDAO $object,
|
|
|
|
array $xactions) {
|
|
|
|
return $this->shouldSendMail($object, $xactions);
|
2013-10-22 01:58:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
protected function supportsSearch() {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-03-05 21:06:59 +01:00
|
|
|
protected function shouldApplyHeraldRules(
|
|
|
|
PhabricatorLiskDAO $object,
|
|
|
|
array $xactions) {
|
2013-10-22 01:58:37 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function buildHeraldAdapter(
|
|
|
|
PhabricatorLiskDAO $object,
|
|
|
|
array $xactions) {
|
|
|
|
|
|
|
|
return id(new HeraldManiphestTaskAdapter())
|
|
|
|
->setTask($object);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function didApplyHeraldRules(
|
|
|
|
PhabricatorLiskDAO $object,
|
|
|
|
HeraldAdapter $adapter,
|
|
|
|
HeraldTranscript $transcript) {
|
|
|
|
|
2014-03-05 21:06:59 +01:00
|
|
|
// TODO: Convert these to transactions. The way Maniphest deals with these
|
|
|
|
// transactions is currently unconventional and messy.
|
|
|
|
|
2013-10-22 01:58:37 +02:00
|
|
|
$save_again = false;
|
|
|
|
$cc_phids = $adapter->getCcPHIDs();
|
|
|
|
if ($cc_phids) {
|
|
|
|
$existing_cc = $object->getCCPHIDs();
|
|
|
|
$new_cc = array_unique(array_merge($cc_phids, $existing_cc));
|
|
|
|
$object->setCCPHIDs($new_cc);
|
|
|
|
$save_again = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
$project_phids = $adapter->getProjectPHIDs();
|
|
|
|
if ($project_phids) {
|
|
|
|
$existing_projects = $object->getProjectPHIDs();
|
|
|
|
$new_projects = array_unique(
|
|
|
|
array_merge($project_phids, $existing_projects));
|
|
|
|
$object->setProjectPHIDs($new_projects);
|
|
|
|
$save_again = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($save_again) {
|
|
|
|
$object->save();
|
|
|
|
}
|
2014-03-05 21:06:59 +01:00
|
|
|
|
2014-03-14 19:52:31 +01:00
|
|
|
$this->heraldEmailPHIDs = $adapter->getEmailPHIDs();
|
|
|
|
|
2014-03-05 21:06:59 +01:00
|
|
|
$xactions = array();
|
|
|
|
|
|
|
|
$assign_phid = $adapter->getAssignPHID();
|
|
|
|
if ($assign_phid) {
|
|
|
|
$xactions[] = id(new ManiphestTransaction())
|
|
|
|
->setTransactionType(ManiphestTransaction::TYPE_OWNER)
|
|
|
|
->setNewValue($assign_phid);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $xactions;
|
2011-02-08 19:53:59 +01:00
|
|
|
}
|
2011-12-17 22:27:11 +01:00
|
|
|
|
Add capabilities for editing task triage details (priority, assignee, etc)
Summary:
This is primarily a client request, and a little bit use-case specific, but policies seem to be holding up well and I'm getting more comfortable about maintaining this. Much if it can run through ApplicationTransactions.
Allow the ability to edit status, policies, priorities, assignees and projects of a task to be restricted to some subset of users. Also allow bulk edit to be locked. This affects the editor itself and the edit, view and list interfaces.
Test Plan: As a restricted user, created, edited and commented on tasks. Tried to drag them around.
Reviewers: btrahan
Reviewed By: btrahan
CC: aran
Differential Revision: https://secure.phabricator.com/D7357
2013-10-22 01:59:06 +02:00
|
|
|
protected function requireCapabilities(
|
|
|
|
PhabricatorLiskDAO $object,
|
|
|
|
PhabricatorApplicationTransaction $xaction) {
|
|
|
|
|
|
|
|
parent::requireCapabilities($object, $xaction);
|
|
|
|
|
|
|
|
$app_capability_map = array(
|
|
|
|
ManiphestTransaction::TYPE_PRIORITY =>
|
|
|
|
ManiphestCapabilityEditPriority::CAPABILITY,
|
|
|
|
ManiphestTransaction::TYPE_STATUS =>
|
|
|
|
ManiphestCapabilityEditStatus::CAPABILITY,
|
|
|
|
ManiphestTransaction::TYPE_PROJECTS =>
|
|
|
|
ManiphestCapabilityEditProjects::CAPABILITY,
|
|
|
|
ManiphestTransaction::TYPE_OWNER =>
|
|
|
|
ManiphestCapabilityEditAssign::CAPABILITY,
|
|
|
|
PhabricatorTransactions::TYPE_EDIT_POLICY =>
|
|
|
|
ManiphestCapabilityEditPolicies::CAPABILITY,
|
|
|
|
PhabricatorTransactions::TYPE_VIEW_POLICY =>
|
|
|
|
ManiphestCapabilityEditPolicies::CAPABILITY,
|
|
|
|
);
|
|
|
|
|
|
|
|
$transaction_type = $xaction->getTransactionType();
|
|
|
|
$app_capability = idx($app_capability_map, $transaction_type);
|
|
|
|
|
|
|
|
if ($app_capability) {
|
|
|
|
$app = id(new PhabricatorApplicationQuery())
|
|
|
|
->setViewer($this->getActor())
|
|
|
|
->withClasses(array('PhabricatorApplicationManiphest'))
|
|
|
|
->executeOne();
|
|
|
|
PhabricatorPolicyFilter::requireCapability(
|
|
|
|
$this->getActor(),
|
|
|
|
$app,
|
|
|
|
$app_capability);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-13 21:50:08 +01:00
|
|
|
protected function adjustObjectForPolicyChecks(
|
|
|
|
PhabricatorLiskDAO $object,
|
|
|
|
array $xactions) {
|
|
|
|
|
|
|
|
$copy = parent::adjustObjectForPolicyChecks($object, $xactions);
|
|
|
|
foreach ($xactions as $xaction) {
|
|
|
|
switch ($xaction->getTransactionType()) {
|
|
|
|
case ManiphestTransaction::TYPE_OWNER:
|
|
|
|
$copy->setOwnerPHID($xaction->getNewValue());
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $copy;
|
|
|
|
}
|
Add capabilities for editing task triage details (priority, assignee, etc)
Summary:
This is primarily a client request, and a little bit use-case specific, but policies seem to be holding up well and I'm getting more comfortable about maintaining this. Much if it can run through ApplicationTransactions.
Allow the ability to edit status, policies, priorities, assignees and projects of a task to be restricted to some subset of users. Also allow bulk edit to be locked. This affects the editor itself and the edit, view and list interfaces.
Test Plan: As a restricted user, created, edited and commented on tasks. Tried to drag them around.
Reviewers: btrahan
Reviewed By: btrahan
CC: aran
Differential Revision: https://secure.phabricator.com/D7357
2013-10-22 01:59:06 +02:00
|
|
|
|
2014-02-27 18:39:59 +01:00
|
|
|
private function getNextSubpriority($pri, $sub) {
|
2013-09-25 22:44:14 +02:00
|
|
|
|
2012-04-02 21:12:04 +02:00
|
|
|
if ($sub === null) {
|
|
|
|
$next = id(new ManiphestTask())->loadOneWhere(
|
|
|
|
'priority = %d ORDER BY subpriority ASC LIMIT 1',
|
|
|
|
$pri);
|
|
|
|
if ($next) {
|
|
|
|
return $next->getSubpriority() - ((double)(2 << 16));
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$next = id(new ManiphestTask())->loadOneWhere(
|
|
|
|
'priority = %d AND subpriority > %s ORDER BY subpriority ASC LIMIT 1',
|
|
|
|
$pri,
|
|
|
|
$sub);
|
|
|
|
if ($next) {
|
|
|
|
return ($sub + $next->getSubpriority()) / 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return (double)(2 << 32);
|
|
|
|
}
|
|
|
|
|
2011-02-08 19:53:59 +01:00
|
|
|
}
|