1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-28 17:52:43 +01:00
phorge-phorge/src/applications/subscriptions/controller/PhabricatorSubscriptionsEditController.php

140 lines
3.9 KiB
PHP
Raw Normal View History

<?php
final class PhabricatorSubscriptionsEditController
extends PhabricatorController {
private $phid;
private $action;
public function willProcessRequest(array $data) {
$this->phid = idx($data, 'phid');
$this->action = idx($data, 'action');
}
public function processRequest() {
$request = $this->getRequest();
if (!$request->isFormPost()) {
return new Aphront400Response();
}
switch ($this->action) {
case 'add':
$is_add = true;
break;
case 'delete':
$is_add = false;
break;
default:
return new Aphront400Response();
}
$user = $request->getUser();
$phid = $this->phid;
$handle = id(new PhabricatorHandleQuery())
->setViewer($user)
->withPHIDs(array($phid))
->executeOne();
if (phid_get_type($phid) == PhabricatorProjectPHIDTypeProject::TYPECONST) {
// TODO: This is a big hack, but a weak argument for adding some kind
// of "load for role" feature to ObjectQuery, and also not a really great
// argument for adding some kind of "load extra stuff" feature to
// SubscriberInterface. Do this for now and wait for the best way forward
// to become more clear?
$object = id(new PhabricatorProjectQuery())
->setViewer($user)
->withPHIDs(array($phid))
->needWatchers(true)
->executeOne();
} else {
$object = id(new PhabricatorObjectQuery())
->setViewer($user)
->withPHIDs(array($phid))
->executeOne();
}
if (!($object instanceof PhabricatorSubscribableInterface)) {
return $this->buildErrorResponse(
pht('Bad Object'),
pht('This object is not subscribable.'),
$handle->getURI());
}
if ($object->isAutomaticallySubscribed($user->getPHID())) {
return $this->buildErrorResponse(
pht('Automatically Subscribed'),
pht('You are automatically subscribed to this object.'),
$handle->getURI());
}
Make Projects a PhabricatorSubscribableInterface, but with restricted defaults Summary: Ref T4379. I want project subscriptions to work like this (yell if this seems whacky, since it makes subscriptions mean somethign a little different for projects than they do for other objects): - You can only subscribe to a project if you're a project member. - When you're added as a member, you're added as a subscriber. - When you're removed as a member, you're removed as a subscriber. - While you're a member, you can optionally unsubscribe. From a UI perspective: - We don't show the subscriber list, since it's going to be some uninteresting subset of the member list. - We don't show CC transactions in history, since they're an uninteresting near-approximation of the membership transactions. - You only see the subscription controls if you're a member. To do this, I've augmented `PhabricatorSubscribableInterface` with two new methods. It would be nice if we were on PHP 5.4+ and could just use traits for this, but we should get data about version usage before we think about this. For now, copy/paste the default implementations into every implementing class. Then, I implemented the interface in `PhabricatorProject` but with alternate defaults. Test Plan: - Used the normal interaction on existing objects. - This has no actual effect on projects, verified no subscription stuff mysteriously appeared. - Hit the new error case by fiddling with the UI. Reviewers: btrahan Reviewed By: btrahan CC: chad, aran Maniphest Tasks: T4379 Differential Revision: https://secure.phabricator.com/D8165
2014-02-10 23:29:17 +01:00
if (!$object->shouldAllowSubscription($user->getPHID())) {
return $this->buildErrorResponse(
pht('You Can Not Subscribe'),
pht('You can not subscribe to this object.'),
$handle->getURI());
}
if ($object instanceof PhabricatorApplicationTransactionInterface) {
if ($is_add) {
$xaction_value = array(
'+' => array($user->getPHID()),
);
} else {
$xaction_value = array(
'-' => array($user->getPHID()),
);
}
$xaction = id($object->getApplicationTransactionTemplate())
->setTransactionType(PhabricatorTransactions::TYPE_SUBSCRIBERS)
->setNewValue($xaction_value);
$editor = id($object->getApplicationTransactionEditor())
->setActor($user)
->setContinueOnNoEffect(true)
->setContentSourceFromRequest($request);
$editor->applyTransactions(
$object->getApplicationTransactionObject(),
array($xaction));
} else {
// TODO: Eventually, get rid of this once everything implements
// PhabriatorApplicationTransactionInterface.
$editor = id(new PhabricatorSubscriptionsEditor())
->setActor($user)
->setObject($object);
if ($is_add) {
$editor->subscribeExplicit(array($user->getPHID()), $explicit = true);
} else {
$editor->unsubscribe(array($user->getPHID()));
}
$editor->save();
}
// TODO: We should just render the "Unsubscribe" action and swap it out
// in the document for Ajax requests.
return id(new AphrontReloadResponse())->setURI($handle->getURI());
}
private function buildErrorResponse($title, $message, $uri) {
$request = $this->getRequest();
$user = $request->getUser();
$dialog = id(new AphrontDialogView())
->setUser($user)
->setTitle($title)
->appendChild($message)
->addCancelButton($uri);
return id(new AphrontDialogResponse())->setDialog($dialog);
}
}