1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-10 00:42:41 +01:00

Group Maniphest transactions.

Summary:

Test Plan:

Reviewers:

CC:
This commit is contained in:
epriestley 2011-02-09 12:47:24 -08:00
parent b500105a56
commit 539b245055
9 changed files with 206 additions and 89 deletions

View file

@ -33,34 +33,61 @@ class ManiphestTaskCreateController extends ManiphestController {
if ($request->isFormPost()) { if ($request->isFormPost()) {
$task->setTitle($request->getStr('title')); $task->setTitle($request->getStr('title'));
$task->setAuthorPHID($user->getPHID()); $task->setAuthorPHID($user->getPHID());
$owner_tokenizer = $request->getArr('assigned_to');
$task->setOwnerPHID(reset($owner_tokenizer));
$task->setCCPHIDs($request->getArr('cc'));
$task->setPriority($request->getInt('priority'));
$task->setDescription($request->getStr('description')); $task->setDescription($request->getStr('description'));
$owner_tokenizer = $request->getArr('assigned_to');
$owner_phid = reset($owner_tokenizer);
if (!strlen($task->getTitle())) { if (!strlen($task->getTitle())) {
$e_title = 'Required'; $e_title = 'Required';
$errors[] = 'Title is required.'; $errors[] = 'Title is required.';
} }
if (!$errors) { if (!$errors) {
$transaction = new ManiphestTransaction(); $changes = array();
$transaction->setAuthorPHID($user->getPHID());
$transaction->setTransactionType(ManiphestTransactionType::TYPE_STATUS); $changes[ManiphestTransactionType::TYPE_STATUS] =
$transaction->setNewValue(ManiphestTaskStatus::STATUS_OPEN); ManiphestTaskStatus::STATUS_OPEN;
if ($request->getInt('priority') != $task->getPriority()) {
$changes[ManiphestTransactionType::TYPE_PRIORITY] =
$request->getInt('priority');
}
if ($owner_phid) {
$changes[ManiphestTransactionType::TYPE_OWNER] = $owner_phid;
}
if ($request->getArr('cc')) {
$changes[ManiphestTransactionType::TYPE_CCS] = $request->getArr('cc');
}
$template = new ManiphestTransaction();
$template->setAuthorPHID($user->getPHID());
$transactions = array();
foreach ($changes as $type => $value) {
$transaction = clone $template;
$transaction->setTransactionType($type);
$transaction->setNewValue($value);
$transactions[] = $transaction;
}
$editor = new ManiphestTransactionEditor(); $editor = new ManiphestTransactionEditor();
$editor->applyTransaction($task, $transaction); $editor->applyTransactions($task, $transactions);
return id(new AphrontRedirectResponse()) return id(new AphrontRedirectResponse())
->setURI('/T'.$task->getID()); ->setURI('/T'.$task->getID());
} }
} else {
$task->setCCPHIDs(array(
$user->getPHID(),
));
} }
$phids = array_merge( $phids = array_merge(
array($task->getOwnerPHID()), array($task->getOwnerPHID()),
nonempty($task->getCCPHIDs(), array())); $task->getCCPHIDs());
$phids = array_filter($phids); $phids = array_filter($phids);
$phids = array_unique($phids); $phids = array_unique($phids);

View file

@ -48,6 +48,8 @@ class ManiphestTransactionSaveController extends ManiphestController {
break; break;
case ManiphestTransactionType::TYPE_CCS: case ManiphestTransactionType::TYPE_CCS:
$ccs = $request->getArr('ccs'); $ccs = $request->getArr('ccs');
$ccs = array_merge($ccs, $task->getCCPHIDs());
$ccs = array_unique($ccs);
$transaction->setNewValue($ccs); $transaction->setNewValue($ccs);
break; break;
case ManiphestTransactionType::TYPE_PRIORITY: case ManiphestTransactionType::TYPE_PRIORITY:
@ -58,7 +60,7 @@ class ManiphestTransactionSaveController extends ManiphestController {
} }
$editor = new ManiphestTransactionEditor(); $editor = new ManiphestTransactionEditor();
$editor->applyTransaction($task, $transaction); $editor->applyTransactions($task, array($transaction));
return id(new AphrontRedirectResponse()) return id(new AphrontRedirectResponse())
->setURI('/T'.$task->getID()); ->setURI('/T'.$task->getID());

View file

@ -18,83 +18,86 @@
class ManiphestTransactionEditor { class ManiphestTransactionEditor {
public function applyTransaction($task, $transaction) { public function applyTransactions($task, array $transactions) {
$type = $transaction->getTransactionType();
$new = $transaction->getNewValue();
$email_cc = $task->getCCPHIDs(); $email_cc = $task->getCCPHIDs();
$email_to = array(); $email_to = array();
$email_to[] = $task->getOwnerPHID(); $email_to[] = $task->getOwnerPHID();
$email_to[] = $transaction->getAuthorPHID();
switch ($type) { foreach ($transactions as $transaction) {
case ManiphestTransactionType::TYPE_NONE: $type = $transaction->getTransactionType();
$old = null; $new = $transaction->getNewValue();
break; $email_to[] = $transaction->getAuthorPHID();
case ManiphestTransactionType::TYPE_STATUS:
$old = $task->getStatus();
break;
case ManiphestTransactionType::TYPE_OWNER:
$old = $task->getOwnerPHID();
break;
case ManiphestTransactionType::TYPE_CCS:
$old = $task->getCCPHIDs();
$new = array_unique(array_merge($old, $new));
break;
case ManiphestTransactionType::TYPE_PRIORITY:
$old = $task->getPriority();
break;
default:
throw new Exception('Unknown action type.');
}
if (($old !== null) && ($old == $new)) {
$transaction->setOldValue(null);
$transaction->setNewValue(null);
$transaction->setTransactionType(ManiphestTransactionType::TYPE_NONE);
} else {
switch ($type) { switch ($type) {
case ManiphestTransactionType::TYPE_NONE: case ManiphestTransactionType::TYPE_NONE:
$old = null;
break; break;
case ManiphestTransactionType::TYPE_STATUS: case ManiphestTransactionType::TYPE_STATUS:
$task->setStatus($new); $old = $task->getStatus();
break; break;
case ManiphestTransactionType::TYPE_OWNER: case ManiphestTransactionType::TYPE_OWNER:
$task->setOwnerPHID($new); $old = $task->getOwnerPHID();
break; break;
case ManiphestTransactionType::TYPE_CCS: case ManiphestTransactionType::TYPE_CCS:
$task->setCCPHIDs($new); $old = $task->getCCPHIDs();
break; break;
case ManiphestTransactionType::TYPE_PRIORITY: case ManiphestTransactionType::TYPE_PRIORITY:
$task->setPriority($new); $old = $task->getPriority();
break; break;
default: default:
throw new Exception('Unknown action type.'); throw new Exception('Unknown action type.');
} }
$transaction->setOldValue($old); if (($old !== null) && ($old == $new)) {
$transaction->setNewValue($new); $transaction->setOldValue(null);
$transaction->setNewValue(null);
$transaction->setTransactionType(ManiphestTransactionType::TYPE_NONE);
} else {
switch ($type) {
case ManiphestTransactionType::TYPE_NONE:
break;
case ManiphestTransactionType::TYPE_STATUS:
$task->setStatus($new);
break;
case ManiphestTransactionType::TYPE_OWNER:
$task->setOwnerPHID($new);
break;
case ManiphestTransactionType::TYPE_CCS:
$task->setCCPHIDs($new);
break;
case ManiphestTransactionType::TYPE_PRIORITY:
$task->setPriority($new);
break;
default:
throw new Exception('Unknown action type.');
}
$transaction->setOldValue($old);
$transaction->setNewValue($new);
}
} }
$task->save(); $task->save();
$transaction->setTaskID($task->getID()); foreach ($transactions as $transaction) {
$transaction->save(); $transaction->setTaskID($task->getID());
$transaction->save();
}
$email_to[] = $task->getOwnerPHID(); $email_to[] = $task->getOwnerPHID();
$email_cc = array_merge($email_cc, $task->getCCPHIDs()); $email_cc = array_merge(
$email_cc,
$task->getCCPHIDs());
$this->sendEmail($task, $transaction, $email_to, $email_cc); $this->sendEmail($task, $transactions, $email_to, $email_cc);
} }
private function sendEmail($task, $transaction, $email_to, $email_cc) { private function sendEmail($task, $transactions, $email_to, $email_cc) {
$email_to = array_filter(array_unique($email_to)); $email_to = array_filter(array_unique($email_to));
$email_cc = array_filter(array_unique($email_cc)); $email_cc = array_filter(array_unique($email_cc));
$transactions = array($transaction);
$phids = array(); $phids = array();
foreach ($transactions as $transaction) { foreach ($transactions as $transaction) {
foreach ($transaction->extractPHIDs() as $phid) { foreach ($transaction->extractPHIDs() as $phid) {
@ -108,13 +111,29 @@ class ManiphestTransactionEditor {
$view = new ManiphestTransactionDetailView(); $view = new ManiphestTransactionDetailView();
$view->setTransaction($transaction); $view->setTransactionGroup($transactions);
$view->setHandles($handles); $view->setHandles($handles);
list($action, $body) = $view->renderForEmail($with_date = false); list($action, $body) = $view->renderForEmail($with_date = false);
$is_create = false;
foreach ($transactions as $transaction) {
$type = $transaction->getTransactionType();
if (($type == ManiphestTransactionType::TYPE_STATUS) &&
($transaction->getOldValue() === null) &&
($transaction->getNewValue() == ManiphestTaskStatus::STATUS_OPEN)) {
$is_create = true;
}
}
$task_uri = PhabricatorEnv::getURI('/T'.$task->getID()); $task_uri = PhabricatorEnv::getURI('/T'.$task->getID());
if ($is_create) {
$body .=
"\n\n".
"TASK DESCRIPTION\n".
" ".$task->getDescription();
}
$body .= $body .=
"\n\n". "\n\n".
"TASK DETAIL\n". "TASK DETAIL\n".

View file

@ -6,6 +6,7 @@
phutil_require_module('phabricator', 'applications/maniphest/constants/status');
phutil_require_module('phabricator', 'applications/maniphest/constants/transactiontype'); phutil_require_module('phabricator', 'applications/maniphest/constants/transactiontype');
phutil_require_module('phabricator', 'applications/maniphest/view/transactiondetail'); phutil_require_module('phabricator', 'applications/maniphest/view/transactiondetail');
phutil_require_module('phabricator', 'applications/metamta/storage/mail'); phutil_require_module('phabricator', 'applications/metamta/storage/mail');

View file

@ -45,4 +45,8 @@ class ManiphestTask extends ManiphestDAO {
return PhabricatorPHID::generateNewPHID('TASK'); return PhabricatorPHID::generateNewPHID('TASK');
} }
public function getCCPHIDs() {
return nonempty($this->ccPHIDs, array());
}
} }

View file

@ -9,5 +9,7 @@
phutil_require_module('phabricator', 'applications/maniphest/storage/base'); phutil_require_module('phabricator', 'applications/maniphest/storage/base');
phutil_require_module('phabricator', 'applications/phid/storage/phid'); phutil_require_module('phabricator', 'applications/phid/storage/phid');
phutil_require_module('phutil', 'utils');
phutil_require_source('ManiphestTask.php'); phutil_require_source('ManiphestTask.php');

View file

@ -58,4 +58,29 @@ class ManiphestTransaction extends ManiphestDAO {
return $phids; return $phids;
} }
public function canGroupWith($target) {
if ($target->getAuthorPHID() != $this->getAuthorPHID()) {
return false;
}
if ($target->hasComments() && $this->hasComments()) {
return false;
}
$ttime = $target->getDateCreated();
$stime = $target->getDateCreated();
if (abs($stime - $ttime) > 60) {
return false;
}
if ($target->getTransactionType() == $this->getTransactionType()) {
return false;
}
return true;
}
public function hasComments() {
return (bool)strlen(trim($this->getComments()));
}
} }

View file

@ -18,13 +18,13 @@
class ManiphestTransactionDetailView extends AphrontView { class ManiphestTransactionDetailView extends AphrontView {
private $transaction; private $transactions;
private $handles; private $handles;
private $markupEngine; private $markupEngine;
private $forEmail; private $forEmail;
public function setTransaction(ManiphestTransaction $transaction) { public function setTransactionGroup(array $transactions) {
$this->transaction = $transaction; $this->transactions = $transactions;
return $this; return $this;
} }
@ -40,34 +40,50 @@ class ManiphestTransactionDetailView extends AphrontView {
public function renderForEmail($with_date) { public function renderForEmail($with_date) {
$this->forEmail = true; $this->forEmail = true;
list ($verb, $desc, $classes) = $this->describeAction();
$transaction = $this->transaction; $transaction = reset($this->transactions);
$author = $this->renderHandles(array($transaction->getAuthorPHID())); $author = $this->renderHandles(array($transaction->getAuthorPHID()));
$desc = $author.' '.$desc; $action = null;
if ($with_date) { $descs = array();
$desc = 'On '.date('M jS \a\t g:i A', $transaction->getDateCreated()). $comments = null;
', '.$desc; foreach ($this->transactions as $transaction) {
list($verb, $desc, $classes) = $this->describeAction($transaction);
if ($action === null) {
$action = $verb;
}
$desc = $author.' '.$desc.'.';
if ($with_date) {
$desc = 'On '.date('M jS \a\t g:i A', $transaction->getDateCreated()).
', '.$desc;
}
$descs[] = $desc;
if ($transaction->hasComments()) {
$comments = $transaction->getComments();
}
} }
$comments = $transaction->getComments(); $descs = implode("\n", $descs);
if (strlen(trim($comments))) { if ($comments) {
$desc = $desc.":\n".$comments; $descs .= "\n".$comments;
} else {
$desc = $desc.".";
} }
$this->forEmail = false; $this->forEmail = false;
return array($verb, $desc); return array($action, $descs);
} }
public function render() { public function render() {
$transaction = $this->transaction;
$handles = $this->handles; $handles = $this->handles;
$transactions = $this->transactions;
require_celerity_resource('maniphest-transaction-detail-css'); require_celerity_resource('maniphest-transaction-detail-css');
foreach ($this->transactions as $transaction) {
if ($transaction->hasComments()) {
break;
}
}
$author = $this->handles[$transaction->getAuthorPHID()]; $author = $this->handles[$transaction->getAuthorPHID()];
$comments = $transaction->getCache(); $comments = $transaction->getCache();
@ -80,18 +96,18 @@ class ManiphestTransactionDetailView extends AphrontView {
} }
} }
list($verb, $desc, $classes) = $this->describeAction( $more_classes = array();
$transaction->getComments()); $descs = array();
foreach ($transactions as $transaction) {
list($verb, $desc, $classes) = $this->describeAction($transaction);
$more_classes = array_merge($more_classes, $classes);
$descs[] = $author->renderLink().' '.$desc.'.';
}
$descs = implode('<br />', $descs);
$more_classes = implode(' ', $classes); $more_classes = implode(' ', $classes);
if (strlen(trim($transaction->getComments()))) { if ($transaction->hasComments()) {
$punc = ':';
} else {
$punc = '.';
}
if (strlen(trim($transaction->getComments()))) {
$comment_block = $comment_block =
'<div class="maniphest-transaction-comments phabricator-remarkup">'. '<div class="maniphest-transaction-comments phabricator-remarkup">'.
$comments. $comments.
@ -112,24 +128,20 @@ class ManiphestTransactionDetailView extends AphrontView {
phabricator_format_timestamp($transaction->getDateCreated()). phabricator_format_timestamp($transaction->getDateCreated()).
'</div>'. '</div>'.
'<strong>'. '<strong>'.
$author->renderLink(). $descs.
' '.
$desc.
$punc.
'</strong>'. '</strong>'.
'</div>'. '</div>'.
$comment_block. $comment_block.
'</div>'); '</div>');
} }
private function describeAction() { private function describeAction($transaction) {
$verb = null; $verb = null;
$desc = null; $desc = null;
$classes = array(); $classes = array();
$handles = $this->handles; $handles = $this->handles;
$transaction = $this->transaction;
$type = $transaction->getTransactionType(); $type = $transaction->getTransactionType();
$author_phid = $transaction->getAuthorPHID(); $author_phid = $transaction->getAuthorPHID();
$new = $transaction->getNewValue(); $new = $transaction->getNewValue();

View file

@ -46,9 +46,34 @@ class ManiphestTransactionListView extends AphrontView {
public function render() { public function render() {
$views = array(); $views = array();
$last = null;
$group = array();
$groups = array();
foreach ($this->transactions as $transaction) { foreach ($this->transactions as $transaction) {
if ($last === null) {
$last = $transaction;
$group[] = $transaction;
continue;
} else if ($last->canGroupWith($transaction)) {
$group[] = $transaction;
if ($transaction->hasComments()) {
$last = $transaction;
}
} else {
$groups[] = $group;
$last = $transaction;
$group = array($transaction);
}
}
if ($group) {
$groups[] = $group;
}
foreach ($groups as $group) {
$view = new ManiphestTransactionDetailView($transaction); $view = new ManiphestTransactionDetailView($transaction);
$view->setTransaction($transaction); $view->setTransactionGroup($group);
$view->setHandles($this->handles); $view->setHandles($this->handles);
$view->setMarkupEngine($this->markupEngine); $view->setMarkupEngine($this->markupEngine);
$views[] = $view->render(); $views[] = $view->render();