[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/maniphest/controller/ -> ManiphestTransactionSaveController.php (source)

   1  <?php
   2  
   3  final class ManiphestTransactionSaveController extends ManiphestController {
   4  
   5    public function processRequest() {
   6      $request = $this->getRequest();
   7      $user = $request->getUser();
   8  
   9      $task = id(new ManiphestTaskQuery())
  10        ->setViewer($user)
  11        ->withIDs(array($request->getStr('taskID')))
  12        ->executeOne();
  13      if (!$task) {
  14        return new Aphront404Response();
  15      }
  16  
  17      $task_uri = '/'.$task->getMonogram();
  18  
  19      $transactions = array();
  20  
  21      $action = $request->getStr('action');
  22  
  23      // Compute new CCs added by @mentions. Several things can cause CCs to
  24      // be added as side effects: mentions, explicit CCs, users who aren't
  25      // CC'd interacting with the task, and ownership changes. We build up a
  26      // list of all the CCs and then construct a transaction for them at the
  27      // end if necessary.
  28      $added_ccs = PhabricatorMarkupEngine::extractPHIDsFromMentions(
  29        $user,
  30        array(
  31          $request->getStr('comments'),
  32        ));
  33  
  34      $cc_transaction = new ManiphestTransaction();
  35      $cc_transaction
  36        ->setTransactionType(ManiphestTransaction::TYPE_CCS);
  37  
  38      $transaction = new ManiphestTransaction();
  39      $transaction
  40        ->setTransactionType($action);
  41  
  42      switch ($action) {
  43        case ManiphestTransaction::TYPE_STATUS:
  44          $transaction->setNewValue($request->getStr('resolution'));
  45          break;
  46        case ManiphestTransaction::TYPE_OWNER:
  47          $assign_to = $request->getArr('assign_to');
  48          $assign_to = reset($assign_to);
  49          $transaction->setNewValue($assign_to);
  50          break;
  51        case ManiphestTransaction::TYPE_PROJECTS:
  52          $projects = $request->getArr('projects');
  53          $projects = array_merge($projects, $task->getProjectPHIDs());
  54          $projects = array_filter($projects);
  55          $projects = array_unique($projects);
  56  
  57          // TODO: Bleh.
  58          $project_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
  59          $transaction
  60            ->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
  61            ->setMetadataValue('edge:type', $project_type)
  62            ->setNewValue(
  63              array(
  64                '+' => array_fuse($projects),
  65              ));
  66          break;
  67        case ManiphestTransaction::TYPE_CCS:
  68          // Accumulate the new explicit CCs into the array that we'll add in
  69          // the CC transaction later.
  70          $added_ccs = array_merge($added_ccs, $request->getArr('ccs'));
  71  
  72          // Throw away the primary transaction.
  73          $transaction = null;
  74          break;
  75        case ManiphestTransaction::TYPE_PRIORITY:
  76          $transaction->setNewValue($request->getInt('priority'));
  77          break;
  78        case PhabricatorTransactions::TYPE_COMMENT:
  79          // Nuke this, we're going to create it below.
  80          $transaction = null;
  81          break;
  82        default:
  83          throw new Exception('unknown action');
  84      }
  85  
  86      if ($transaction) {
  87        $transactions[] = $transaction;
  88      }
  89  
  90  
  91      // When you interact with a task, we add you to the CC list so you get
  92      // further updates, and possibly assign the task to you if you took an
  93      // ownership action (closing it) but it's currently unowned. We also move
  94      // previous owners to CC if ownership changes. Detect all these conditions
  95      // and create side-effect transactions for them.
  96  
  97      $implicitly_claimed = false;
  98      if ($action == ManiphestTransaction::TYPE_OWNER) {
  99        if ($task->getOwnerPHID() == $transaction->getNewValue()) {
 100          // If this is actually no-op, don't generate the side effect.
 101        } else {
 102          // Otherwise, when a task is reassigned, move the previous owner to CC.
 103          $added_ccs[] = $task->getOwnerPHID();
 104        }
 105      }
 106  
 107      if ($action == ManiphestTransaction::TYPE_STATUS) {
 108        $resolution = $request->getStr('resolution');
 109        if (!$task->getOwnerPHID() &&
 110            ManiphestTaskStatus::isClosedStatus($resolution)) {
 111          // Closing an unassigned task. Assign the user as the owner of
 112          // this task.
 113          $assign = new ManiphestTransaction();
 114          $assign->setTransactionType(ManiphestTransaction::TYPE_OWNER);
 115          $assign->setNewValue($user->getPHID());
 116          $transactions[] = $assign;
 117  
 118          $implicitly_claimed = true;
 119        }
 120      }
 121  
 122      $user_owns_task = false;
 123      if ($implicitly_claimed) {
 124        $user_owns_task = true;
 125      } else {
 126        if ($action == ManiphestTransaction::TYPE_OWNER) {
 127          if ($transaction->getNewValue() == $user->getPHID()) {
 128            $user_owns_task = true;
 129          }
 130        } else if ($task->getOwnerPHID() == $user->getPHID()) {
 131          $user_owns_task = true;
 132        }
 133      }
 134  
 135      if (!$user_owns_task) {
 136        // If we aren't making the user the new task owner and they aren't the
 137        // existing task owner, add them to CC unless they're aleady CC'd.
 138        if (!in_array($user->getPHID(), $task->getCCPHIDs())) {
 139          $added_ccs[] = $user->getPHID();
 140        }
 141      }
 142  
 143      // Evade no-effect detection in the new editor stuff until we can switch
 144      // to subscriptions.
 145      $added_ccs = array_filter(array_diff($added_ccs, $task->getCCPHIDs()));
 146  
 147      if ($added_ccs) {
 148        // We've added CCs, so include a CC transaction.
 149        $all_ccs = array_merge($task->getCCPHIDs(), $added_ccs);
 150        $cc_transaction->setNewValue($all_ccs);
 151        $transactions[] = $cc_transaction;
 152      }
 153  
 154      $comments = $request->getStr('comments');
 155      if (strlen($comments) || !$transactions) {
 156        $transactions[] = id(new ManiphestTransaction())
 157          ->setTransactionType(PhabricatorTransactions::TYPE_COMMENT)
 158          ->attachComment(
 159            id(new ManiphestTransactionComment())
 160              ->setContent($comments));
 161      }
 162  
 163      $event = new PhabricatorEvent(
 164        PhabricatorEventType::TYPE_MANIPHEST_WILLEDITTASK,
 165        array(
 166          'task'          => $task,
 167          'new'           => false,
 168          'transactions'  => $transactions,
 169        ));
 170      $event->setUser($user);
 171      $event->setAphrontRequest($request);
 172      PhutilEventEngine::dispatchEvent($event);
 173  
 174      $task = $event->getValue('task');
 175      $transactions = $event->getValue('transactions');
 176  
 177      $editor = id(new ManiphestTransactionEditor())
 178        ->setActor($user)
 179        ->setContentSourceFromRequest($request)
 180        ->setContinueOnMissingFields(true)
 181        ->setContinueOnNoEffect($request->isContinueRequest());
 182  
 183      try {
 184        $editor->applyTransactions($task, $transactions);
 185      } catch (PhabricatorApplicationTransactionNoEffectException $ex) {
 186        return id(new PhabricatorApplicationTransactionNoEffectResponse())
 187          ->setCancelURI($task_uri)
 188          ->setException($ex);
 189      }
 190  
 191      $draft = id(new PhabricatorDraft())->loadOneWhere(
 192        'authorPHID = %s AND draftKey = %s',
 193        $user->getPHID(),
 194        $task->getPHID());
 195      if ($draft) {
 196        $draft->delete();
 197      }
 198  
 199      $event = new PhabricatorEvent(
 200        PhabricatorEventType::TYPE_MANIPHEST_DIDEDITTASK,
 201        array(
 202          'task'          => $task,
 203          'new'           => false,
 204          'transactions'  => $transactions,
 205        ));
 206      $event->setUser($user);
 207      $event->setAphrontRequest($request);
 208      PhutilEventEngine::dispatchEvent($event);
 209  
 210      return id(new AphrontRedirectResponse())->setURI($task_uri);
 211    }
 212  
 213  }


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1