1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-23 14:00:56 +01:00

Allow contact numbers to be enabled and disabled

Summary: Depends on D20008. Ref T920. Continue fleshing out contact number behaviors.

Test Plan:
  - Enabled and disabled a contact number.
  - Saw list, detail views reflect change.
  - Added number X, disabled it, added it again (allowed), enabled the disabled one ("already in use" exception).

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T920

Differential Revision: https://secure.phabricator.com/D20010
This commit is contained in:
epriestley 2019-01-21 12:30:10 -08:00
parent c4244aa177
commit 12203762b7
6 changed files with 197 additions and 1 deletions

View file

@ -2201,12 +2201,14 @@ phutil_register_library_map(array(
'PhabricatorAuthConfirmLinkController' => 'applications/auth/controller/PhabricatorAuthConfirmLinkController.php',
'PhabricatorAuthContactNumber' => 'applications/auth/storage/PhabricatorAuthContactNumber.php',
'PhabricatorAuthContactNumberController' => 'applications/auth/controller/contact/PhabricatorAuthContactNumberController.php',
'PhabricatorAuthContactNumberDisableController' => 'applications/auth/controller/contact/PhabricatorAuthContactNumberDisableController.php',
'PhabricatorAuthContactNumberEditController' => 'applications/auth/controller/contact/PhabricatorAuthContactNumberEditController.php',
'PhabricatorAuthContactNumberEditEngine' => 'applications/auth/editor/PhabricatorAuthContactNumberEditEngine.php',
'PhabricatorAuthContactNumberEditor' => 'applications/auth/editor/PhabricatorAuthContactNumberEditor.php',
'PhabricatorAuthContactNumberNumberTransaction' => 'applications/auth/xaction/PhabricatorAuthContactNumberNumberTransaction.php',
'PhabricatorAuthContactNumberPHIDType' => 'applications/auth/phid/PhabricatorAuthContactNumberPHIDType.php',
'PhabricatorAuthContactNumberQuery' => 'applications/auth/query/PhabricatorAuthContactNumberQuery.php',
'PhabricatorAuthContactNumberStatusTransaction' => 'applications/auth/xaction/PhabricatorAuthContactNumberStatusTransaction.php',
'PhabricatorAuthContactNumberTransaction' => 'applications/auth/storage/PhabricatorAuthContactNumberTransaction.php',
'PhabricatorAuthContactNumberTransactionQuery' => 'applications/auth/query/PhabricatorAuthContactNumberTransactionQuery.php',
'PhabricatorAuthContactNumberTransactionType' => 'applications/auth/xaction/PhabricatorAuthContactNumberTransactionType.php',
@ -7904,12 +7906,14 @@ phutil_register_library_map(array(
'PhabricatorDestructibleInterface',
),
'PhabricatorAuthContactNumberController' => 'PhabricatorAuthController',
'PhabricatorAuthContactNumberDisableController' => 'PhabricatorAuthContactNumberController',
'PhabricatorAuthContactNumberEditController' => 'PhabricatorAuthContactNumberController',
'PhabricatorAuthContactNumberEditEngine' => 'PhabricatorEditEngine',
'PhabricatorAuthContactNumberEditor' => 'PhabricatorApplicationTransactionEditor',
'PhabricatorAuthContactNumberNumberTransaction' => 'PhabricatorAuthContactNumberTransactionType',
'PhabricatorAuthContactNumberPHIDType' => 'PhabricatorPHIDType',
'PhabricatorAuthContactNumberQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorAuthContactNumberStatusTransaction' => 'PhabricatorAuthContactNumberTransactionType',
'PhabricatorAuthContactNumberTransaction' => 'PhabricatorModularTransaction',
'PhabricatorAuthContactNumberTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhabricatorAuthContactNumberTransactionType' => 'PhabricatorModularTransactionType',

View file

@ -111,6 +111,8 @@ final class PhabricatorAuthApplication extends PhabricatorApplication {
'PhabricatorAuthContactNumberEditController',
'(?P<id>[1-9]\d*)/' =>
'PhabricatorAuthContactNumberViewController',
'(?P<action>disable|enable)/(?P<id>[1-9]\d*)/' =>
'PhabricatorAuthContactNumberDisableController',
),
),

View file

@ -0,0 +1,87 @@
<?php
final class PhabricatorAuthContactNumberDisableController
extends PhabricatorAuthContactNumberController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$id = $request->getURIData('id');
$number = id(new PhabricatorAuthContactNumberQuery())
->setViewer($viewer)
->withIDs(array($id))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$number) {
return new Aphront404Response();
}
$is_disable = ($request->getURIData('action') == 'disable');
$id = $number->getID();
$cancel_uri = $number->getURI();
if ($request->isFormPost()) {
$xactions = array();
if ($is_disable) {
$new_status = PhabricatorAuthContactNumber::STATUS_DISABLED;
} else {
$new_status = PhabricatorAuthContactNumber::STATUS_ACTIVE;
}
$xactions[] = id(new PhabricatorAuthContactNumberTransaction())
->setTransactionType(
PhabricatorAuthContactNumberStatusTransaction::TRANSACTIONTYPE)
->setNewValue($new_status);
$editor = id(new PhabricatorAuthContactNumberEditor())
->setActor($viewer)
->setContentSourceFromRequest($request)
->setContinueOnNoEffect(true)
->setContinueOnMissingFields(true);
try {
$editor->applyTransactions($number, $xactions);
} catch (PhabricatorApplicationTransactionValidationException $ex) {
// This happens when you enable a number which collides with another
// number.
return $this->newDialog()
->setTitle(pht('Changing Status Failed'))
->setValidationException($ex)
->addCancelButton($cancel_uri);
}
return id(new AphrontRedirectResponse())->setURI($cancel_uri);
}
$number_display = phutil_tag(
'strong',
array(),
$number->getDisplayName());
if ($is_disable) {
$title = pht('Disable Contact Number');
$body = pht(
'Disable the contact number %s?',
$number_display);
$button = pht('Disable Number');
} else {
$title = pht('Enable Contact Number');
$body = pht(
'Enable the contact number %s?',
$number_display);
$button = pht('Enable Number');
}
return $this->newDialog()
->setTitle($title)
->appendParagraph($body)
->addSubmitButton($button)
->addCancelButton($cancel_uri);
}
}

View file

@ -54,6 +54,10 @@ final class PhabricatorAuthContactNumberViewController
->setHeader($number->getObjectName())
->setPolicyObject($number);
if ($number->isDisabled()) {
$view->setStatus('fa-ban', 'red', pht('Disabled'));
}
return $view;
}
@ -92,6 +96,24 @@ final class PhabricatorAuthContactNumberViewController
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit));
if ($number->isDisabled()) {
$disable_uri = $this->getApplicationURI("contact/enable/{$id}/");
$disable_name = pht('Enable Contact Number');
$disable_icon = 'fa-check';
} else {
$disable_uri = $this->getApplicationURI("contact/disable/{$id}/");
$disable_name = pht('Disable Contact Number');
$disable_icon = 'fa-ban';
}
$curtain->addAction(
id(new PhabricatorActionView())
->setName($disable_name)
->setIcon($disable_icon)
->setHref($disable_uri)
->setWorkflow(true));
return $curtain;
}

View file

@ -93,10 +93,32 @@ final class PhabricatorAuthContactNumber
}
public function save() {
$this->uniqueKey = $this->newUniqueKey();
// We require that active contact numbers be unique, but it's okay to
// disable a number and then reuse it somewhere else.
if ($this->isDisabled()) {
$this->uniqueKey = null;
} else {
$this->uniqueKey = $this->newUniqueKey();
}
return parent::save();
}
public static function getStatusNameMap() {
return ipull(self::getStatusPropertyMap(), 'name');
}
private static function getStatusPropertyMap() {
return array(
self::STATUS_ACTIVE => array(
'name' => pht('Active'),
),
self::STATUS_DISABLED => array(
'name' => pht('Disabled'),
),
);
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */

View file

@ -0,0 +1,59 @@
<?php
final class PhabricatorAuthContactNumberStatusTransaction
extends PhabricatorAuthContactNumberTransactionType {
const TRANSACTIONTYPE = 'status';
public function generateOldValue($object) {
return $object->getStatus();
}
public function applyInternalEffects($object, $value) {
$object->setStatus($value);
}
public function getTitle() {
$new = $this->getNewValue();
if ($new === PhabricatorAuthContactNumber::STATUS_DISABLED) {
return pht(
'%s disabled this contact number.',
$this->renderAuthor());
} else {
return pht(
'%s enabled this contact number.',
$this->renderAuthor());
}
}
public function validateTransactions($object, array $xactions) {
$errors = array();
$map = PhabricatorAuthContactNumber::getStatusNameMap();
foreach ($xactions as $xaction) {
$new_value = $xaction->getNewValue();
if (!isset($map[$new_value])) {
$errors[] = $this->newInvalidError(
pht(
'Status ("%s") is not a valid contact number status. Valid '.
'status constants are: %s.',
$new_value,
implode(', ', array_keys($map))),
$xaction);
continue;
}
// NOTE: Enabling a contact number may cause us to collide with another
// active contact number. However, there might also be a transaction in
// this group that changes the number itself. Since we can't easily
// predict if we'll collide or not, just let the duplicate key logic
// handle it when we do.
}
return $errors;
}
}