diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index ca4d9978c4..cb2cfa36b5 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -2610,6 +2610,7 @@ phutil_register_library_map(array( 'PhabricatorEditEngineConfigurationSaveController' => 'applications/transactions/controller/PhabricatorEditEngineConfigurationSaveController.php', 'PhabricatorEditEngineConfigurationSearchEngine' => 'applications/transactions/query/PhabricatorEditEngineConfigurationSearchEngine.php', 'PhabricatorEditEngineConfigurationSortController' => 'applications/transactions/controller/PhabricatorEditEngineConfigurationSortController.php', + 'PhabricatorEditEngineConfigurationSubtypeController' => 'applications/transactions/controller/PhabricatorEditEngineConfigurationSubtypeController.php', 'PhabricatorEditEngineConfigurationTransaction' => 'applications/transactions/storage/PhabricatorEditEngineConfigurationTransaction.php', 'PhabricatorEditEngineConfigurationTransactionQuery' => 'applications/transactions/query/PhabricatorEditEngineConfigurationTransactionQuery.php', 'PhabricatorEditEngineConfigurationViewController' => 'applications/transactions/controller/PhabricatorEditEngineConfigurationViewController.php', @@ -7669,6 +7670,7 @@ phutil_register_library_map(array( 'PhabricatorEditEngineConfigurationSaveController' => 'PhabricatorEditEngineController', 'PhabricatorEditEngineConfigurationSearchEngine' => 'PhabricatorApplicationSearchEngine', 'PhabricatorEditEngineConfigurationSortController' => 'PhabricatorEditEngineController', + 'PhabricatorEditEngineConfigurationSubtypeController' => 'PhabricatorEditEngineController', 'PhabricatorEditEngineConfigurationTransaction' => 'PhabricatorApplicationTransaction', 'PhabricatorEditEngineConfigurationTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'PhabricatorEditEngineConfigurationViewController' => 'PhabricatorEditEngineController', diff --git a/src/applications/maniphest/storage/ManiphestTask.php b/src/applications/maniphest/storage/ManiphestTask.php index aa59378e20..be540b9056 100644 --- a/src/applications/maniphest/storage/ManiphestTask.php +++ b/src/applications/maniphest/storage/ManiphestTask.php @@ -557,4 +557,9 @@ final class ManiphestTask extends ManiphestDAO return $this->setSubtype($value); } + public function newEditEngineSubtypeMap() { + $config = PhabricatorEnv::getEnvConfig('maniphest.subtypes'); + return PhabricatorEditEngineSubtype::newSubtypeMap($config); + } + } diff --git a/src/applications/transactions/application/PhabricatorTransactionsApplication.php b/src/applications/transactions/application/PhabricatorTransactionsApplication.php index 51c88e990d..f5e40671fe 100644 --- a/src/applications/transactions/application/PhabricatorTransactionsApplication.php +++ b/src/applications/transactions/application/PhabricatorTransactionsApplication.php @@ -55,6 +55,8 @@ final class PhabricatorTransactionsApplication extends PhabricatorApplication { 'PhabricatorEditEngineConfigurationDefaultsController', 'lock/(?P[^/]+)/' => 'PhabricatorEditEngineConfigurationLockController', + 'subtype/(?P[^/]+)/' => + 'PhabricatorEditEngineConfigurationSubtypeController', 'defaultcreate/(?P[^/]+)/' => 'PhabricatorEditEngineConfigurationDefaultCreateController', 'defaultedit/(?P[^/]+)/' => diff --git a/src/applications/transactions/controller/PhabricatorEditEngineConfigurationSubtypeController.php b/src/applications/transactions/controller/PhabricatorEditEngineConfigurationSubtypeController.php new file mode 100644 index 0000000000..92bc34c72b --- /dev/null +++ b/src/applications/transactions/controller/PhabricatorEditEngineConfigurationSubtypeController.php @@ -0,0 +1,85 @@ +getURIData('engineKey'); + $this->setEngineKey($engine_key); + + $key = $request->getURIData('key'); + $viewer = $this->getViewer(); + + $config = id(new PhabricatorEditEngineConfigurationQuery()) + ->setViewer($viewer) + ->withEngineKeys(array($engine_key)) + ->withIdentifiers(array($key)) + ->requireCapabilities( + array( + PhabricatorPolicyCapability::CAN_VIEW, + PhabricatorPolicyCapability::CAN_EDIT, + )) + ->executeOne(); + if (!$config) { + return new Aphront404Response(); + } + + $cancel_uri = "/transactions/editengine/{$engine_key}/view/{$key}/"; + + $engine = $config->getEngine(); + if (!$engine->supportsSubtypes()) { + return new Aphront404Response(); + } + + if ($request->isFormPost()) { + $xactions = array(); + + $subtype = $request->getStr('subtype'); + $type_subtype = + PhabricatorEditEngineConfigurationTransaction::TYPE_SUBTYPE; + + $xactions[] = id(new PhabricatorEditEngineConfigurationTransaction()) + ->setTransactionType($type_subtype) + ->setNewValue($subtype); + + $editor = id(new PhabricatorEditEngineConfigurationEditor()) + ->setActor($viewer) + ->setContentSourceFromRequest($request) + ->setContinueOnMissingFields(true) + ->setContinueOnNoEffect(true); + + $editor->applyTransactions($config, $xactions); + + return id(new AphrontRedirectResponse()) + ->setURI($cancel_uri); + } + + $fields = $engine->getFieldsForConfig($config); + + $help = pht(<<newSubtypeMap(); + $map = mpull($map, 'getName'); + + $form = id(new AphrontFormView()) + ->setUser($viewer) + ->appendRemarkupInstructions($help) + ->appendControl( + id(new AphrontFormSelectControl()) + ->setName('subtype') + ->setLabel(pht('Subtype')) + ->setValue($config->getSubtype()) + ->setOptions($map)); + + return $this->newDialog() + ->setTitle(pht('Change Form Subtype')) + ->setWidth(AphrontDialogView::WIDTH_FORM) + ->appendForm($form) + ->addSubmitButton(pht('Save Changes')) + ->addCancelButton($cancel_uri); + } + +} diff --git a/src/applications/transactions/controller/PhabricatorEditEngineConfigurationViewController.php b/src/applications/transactions/controller/PhabricatorEditEngineConfigurationViewController.php index 23ccedd04d..c07b2d5f3d 100644 --- a/src/applications/transactions/controller/PhabricatorEditEngineConfigurationViewController.php +++ b/src/applications/transactions/controller/PhabricatorEditEngineConfigurationViewController.php @@ -151,6 +151,27 @@ final class PhabricatorEditEngineConfigurationViewController ->setWorkflow(true) ->setDisabled(!$can_edit)); + if ($engine->supportsSubtypes()) { + $subtype_uri = "{$base_uri}/subtype/{$form_key}/"; + + $curtain->addAction( + id(new PhabricatorActionView()) + ->setName(pht('Change Form Subtype')) + ->setIcon('fa-drivers-license-o') + ->setHref($subtype_uri) + ->setWorkflow(true) + ->setDisabled(!$can_edit)); + } + + $curtain->addAction( + id(new PhabricatorActionView()) + ->setName(pht('Change Default Values')) + ->setIcon('fa-paint-brush') + ->setHref($defaults_uri) + ->setWorkflow(!$can_edit) + ->setDisabled(!$can_edit)); + + $disable_uri = "{$base_uri}/disable/{$form_key}/"; if ($config->getIsDisabled()) { diff --git a/src/applications/transactions/editengine/PhabricatorEditEngine.php b/src/applications/transactions/editengine/PhabricatorEditEngine.php index 44b794bceb..88604e99bc 100644 --- a/src/applications/transactions/editengine/PhabricatorEditEngine.php +++ b/src/applications/transactions/editengine/PhabricatorEditEngine.php @@ -213,6 +213,20 @@ abstract class PhabricatorEditEngine return $fields; } + final public function supportsSubtypes() { + try { + $object = $this->newEditableObject(); + } catch (Exception $ex) { + return false; + } + + return ($object instanceof PhabricatorEditEngineSubtypeInterface); + } + + final public function newSubtypeMap() { + return $this->newEditableObject()->newEditEngineSubtypeMap(); + } + /* -( Display Text )------------------------------------------------------- */ diff --git a/src/applications/transactions/editengine/PhabricatorEditEngineSubtype.php b/src/applications/transactions/editengine/PhabricatorEditEngineSubtype.php index 038267834c..6c03e17ee4 100644 --- a/src/applications/transactions/editengine/PhabricatorEditEngineSubtype.php +++ b/src/applications/transactions/editengine/PhabricatorEditEngineSubtype.php @@ -6,6 +6,27 @@ final class PhabricatorEditEngineSubtype const SUBTYPE_DEFAULT = 'default'; + private $key; + private $name; + + public function setKey($key) { + $this->key = $key; + return $this; + } + + public function getKey() { + return $this->key; + } + + public function setName($name) { + $this->name = $name; + return $this; + } + + public function getName() { + return $this->name; + } + public static function validateSubtypeKey($subtype) { if (strlen($subtype) > 64) { throw new Exception( @@ -81,4 +102,19 @@ final class PhabricatorEditEngineSubtype } } + public static function newSubtypeMap(array $config) { + $map = array(); + + foreach ($config as $entry) { + $key = $entry['key']; + $name = $entry['name']; + + $map[$key] = id(new self()) + ->setKey($key) + ->setName($name); + } + + return $map; + } + } diff --git a/src/applications/transactions/editengine/PhabricatorEditEngineSubtypeInterface.php b/src/applications/transactions/editengine/PhabricatorEditEngineSubtypeInterface.php index 9c15232b7e..8058e0702c 100644 --- a/src/applications/transactions/editengine/PhabricatorEditEngineSubtypeInterface.php +++ b/src/applications/transactions/editengine/PhabricatorEditEngineSubtypeInterface.php @@ -4,5 +4,6 @@ interface PhabricatorEditEngineSubtypeInterface { public function getEditEngineSubtype(); public function setEditEngineSubtype($subtype); + public function newEditEngineSubtypeMap(); } diff --git a/src/applications/transactions/editor/PhabricatorEditEngineConfigurationEditor.php b/src/applications/transactions/editor/PhabricatorEditEngineConfigurationEditor.php index b8e9d908a4..fb07d251be 100644 --- a/src/applications/transactions/editor/PhabricatorEditEngineConfigurationEditor.php +++ b/src/applications/transactions/editor/PhabricatorEditEngineConfigurationEditor.php @@ -21,6 +21,7 @@ final class PhabricatorEditEngineConfigurationEditor $types[] = PhabricatorEditEngineConfigurationTransaction::TYPE_ORDER; $types[] = PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULT; $types[] = PhabricatorEditEngineConfigurationTransaction::TYPE_LOCKS; + $types[] = PhabricatorEditEngineConfigurationTransaction::TYPE_SUBTYPE; $types[] = PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULTCREATE; $types[] = PhabricatorEditEngineConfigurationTransaction::TYPE_ISEDIT; @@ -55,6 +56,22 @@ final class PhabricatorEditEngineConfigurationEditor $errors[] = $error; } break; + case PhabricatorEditEngineConfigurationTransaction::TYPE_SUBTYPE: + $map = $object->getEngine()->newSubtypeMap(); + foreach ($xactions as $xaction) { + $new = $xaction->getNewValue(); + + if (isset($map[$new])) { + continue; + } + + $errors[] = new PhabricatorApplicationTransactionValidationError( + $type, + pht('Invalid'), + pht('Subtype "%s" is not a valid subtype.', $new), + $xaction); + } + break; } return $errors; @@ -76,6 +93,8 @@ final class PhabricatorEditEngineConfigurationEditor return $object->getFieldDefault($field_key); case PhabricatorEditEngineConfigurationTransaction::TYPE_LOCKS: return $object->getFieldLocks(); + case PhabricatorEditEngineConfigurationTransaction::TYPE_SUBTYPE: + return $object->getSubtype(); case PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULTCREATE: return (int)$object->getIsDefault(); case PhabricatorEditEngineConfigurationTransaction::TYPE_ISEDIT: @@ -86,6 +105,7 @@ final class PhabricatorEditEngineConfigurationEditor return (int)$object->getCreateOrder(); case PhabricatorEditEngineConfigurationTransaction::TYPE_EDITORDER: return (int)$object->getEditOrder(); + } } @@ -99,6 +119,7 @@ final class PhabricatorEditEngineConfigurationEditor case PhabricatorEditEngineConfigurationTransaction::TYPE_ORDER: case PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULT: case PhabricatorEditEngineConfigurationTransaction::TYPE_LOCKS: + case PhabricatorEditEngineConfigurationTransaction::TYPE_SUBTYPE: return $xaction->getNewValue(); case PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULTCREATE: case PhabricatorEditEngineConfigurationTransaction::TYPE_ISEDIT: @@ -130,6 +151,9 @@ final class PhabricatorEditEngineConfigurationEditor case PhabricatorEditEngineConfigurationTransaction::TYPE_LOCKS: $object->setFieldLocks($xaction->getNewValue()); return; + case PhabricatorEditEngineConfigurationTransaction::TYPE_SUBTYPE: + $object->setSubtype($xaction->getNewValue()); + return; case PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULTCREATE: $object->setIsDefault($xaction->getNewValue()); return; @@ -161,6 +185,7 @@ final class PhabricatorEditEngineConfigurationEditor case PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULT: case PhabricatorEditEngineConfigurationTransaction::TYPE_ISEDIT: case PhabricatorEditEngineConfigurationTransaction::TYPE_LOCKS: + case PhabricatorEditEngineConfigurationTransaction::TYPE_SUBTYPE: case PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULTCREATE: case PhabricatorEditEngineConfigurationTransaction::TYPE_DISABLE: case PhabricatorEditEngineConfigurationTransaction::TYPE_CREATEORDER: diff --git a/src/applications/transactions/storage/PhabricatorEditEngineConfigurationTransaction.php b/src/applications/transactions/storage/PhabricatorEditEngineConfigurationTransaction.php index 4bae34e5eb..a1c44cc003 100644 --- a/src/applications/transactions/storage/PhabricatorEditEngineConfigurationTransaction.php +++ b/src/applications/transactions/storage/PhabricatorEditEngineConfigurationTransaction.php @@ -13,6 +13,7 @@ final class PhabricatorEditEngineConfigurationTransaction const TYPE_DISABLE = 'editengine.config.disable'; const TYPE_CREATEORDER = 'editengine.order.create'; const TYPE_EDITORDER = 'editengine.order.edit'; + const TYPE_SUBTYPE = 'editengine.config.subtype'; public function getApplicationName() { return 'search'; @@ -99,6 +100,12 @@ final class PhabricatorEditEngineConfigurationTransaction '%s enabled this form.', $this->renderHandleLink($author_phid)); } + case self::TYPE_SUBTYPE: + return pht( + '%s changed the subtype of this form from "%s" to "%s".', + $this->renderHandleLink($author_phid), + $old, + $new); } return parent::getTitle();