mirror of
https://we.phorge.it/source/phorge.git
synced 2024-09-20 09:18:48 +02:00
When an object which supports subtypes is created, set its subtype to the creating form's subtype
Summary: Ref T12314. If you set a form to have the "plant" subtype, then create a task with it, save "plant" as the task subtype. For Conduit, the default subtype is used by default, but a new "subtype" transaction is exposed. You can apply this transaction at create time to create an object of a certain subtype, or at any later time to change the subtype of an object. This still doesn't do anything particularly useful or interesting. Test Plan: - Created a non-subtyped object (a Paste). - Created "task" and "plant" tasks via different forms. - Created "default" and "plant" tasks via Conduit. - Changed the subtype of a task via Conduit. - Tried to set a bad subtype. {F3492061} {F3492066} Reviewers: chad Reviewed By: chad Maniphest Tasks: T12314 Differential Revision: https://secure.phabricator.com/D17443
This commit is contained in:
parent
b9d60d2653
commit
4a061b1def
8 changed files with 138 additions and 2 deletions
|
@ -3941,6 +3941,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorSubscriptionsTransactionController' => 'applications/subscriptions/controller/PhabricatorSubscriptionsTransactionController.php',
|
'PhabricatorSubscriptionsTransactionController' => 'applications/subscriptions/controller/PhabricatorSubscriptionsTransactionController.php',
|
||||||
'PhabricatorSubscriptionsUIEventListener' => 'applications/subscriptions/events/PhabricatorSubscriptionsUIEventListener.php',
|
'PhabricatorSubscriptionsUIEventListener' => 'applications/subscriptions/events/PhabricatorSubscriptionsUIEventListener.php',
|
||||||
'PhabricatorSubscriptionsUnsubscribeEmailCommand' => 'applications/subscriptions/command/PhabricatorSubscriptionsUnsubscribeEmailCommand.php',
|
'PhabricatorSubscriptionsUnsubscribeEmailCommand' => 'applications/subscriptions/command/PhabricatorSubscriptionsUnsubscribeEmailCommand.php',
|
||||||
|
'PhabricatorSubtypeEditEngineExtension' => 'applications/transactions/engineextension/PhabricatorSubtypeEditEngineExtension.php',
|
||||||
'PhabricatorSupportApplication' => 'applications/support/application/PhabricatorSupportApplication.php',
|
'PhabricatorSupportApplication' => 'applications/support/application/PhabricatorSupportApplication.php',
|
||||||
'PhabricatorSyntaxHighlighter' => 'infrastructure/markup/PhabricatorSyntaxHighlighter.php',
|
'PhabricatorSyntaxHighlighter' => 'infrastructure/markup/PhabricatorSyntaxHighlighter.php',
|
||||||
'PhabricatorSyntaxHighlightingConfigOptions' => 'applications/config/option/PhabricatorSyntaxHighlightingConfigOptions.php',
|
'PhabricatorSyntaxHighlightingConfigOptions' => 'applications/config/option/PhabricatorSyntaxHighlightingConfigOptions.php',
|
||||||
|
@ -9241,6 +9242,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorSubscriptionsTransactionController' => 'PhabricatorController',
|
'PhabricatorSubscriptionsTransactionController' => 'PhabricatorController',
|
||||||
'PhabricatorSubscriptionsUIEventListener' => 'PhabricatorEventListener',
|
'PhabricatorSubscriptionsUIEventListener' => 'PhabricatorEventListener',
|
||||||
'PhabricatorSubscriptionsUnsubscribeEmailCommand' => 'MetaMTAEmailTransactionCommand',
|
'PhabricatorSubscriptionsUnsubscribeEmailCommand' => 'MetaMTAEmailTransactionCommand',
|
||||||
|
'PhabricatorSubtypeEditEngineExtension' => 'PhabricatorEditEngineExtension',
|
||||||
'PhabricatorSupportApplication' => 'PhabricatorApplication',
|
'PhabricatorSupportApplication' => 'PhabricatorApplication',
|
||||||
'PhabricatorSyntaxHighlighter' => 'Phobject',
|
'PhabricatorSyntaxHighlighter' => 'Phobject',
|
||||||
'PhabricatorSyntaxHighlightingConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
'PhabricatorSyntaxHighlightingConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
||||||
|
|
|
@ -404,7 +404,12 @@ final class ManiphestTransaction
|
||||||
return pht(
|
return pht(
|
||||||
'%s created this task.',
|
'%s created this task.',
|
||||||
$this->renderHandleLink($author_phid));
|
$this->renderHandleLink($author_phid));
|
||||||
|
case PhabricatorTransactions::TYPE_SUBTYPE:
|
||||||
|
return pht(
|
||||||
|
'%s changed the subtype of this task from "%s" to "%s".',
|
||||||
|
$this->renderHandleLink($author_phid),
|
||||||
|
$this->renderSubtypeName($old),
|
||||||
|
$this->renderSubtypeName($new));
|
||||||
case self::TYPE_TITLE:
|
case self::TYPE_TITLE:
|
||||||
if ($old === null) {
|
if ($old === null) {
|
||||||
return pht(
|
return pht(
|
||||||
|
@ -876,11 +881,28 @@ final class ManiphestTransaction
|
||||||
$this->renderHandleList($new),
|
$this->renderHandleList($new),
|
||||||
$this->renderHandleLink($object_phid));
|
$this->renderHandleLink($object_phid));
|
||||||
|
|
||||||
|
case PhabricatorTransactions::TYPE_SUBTYPE:
|
||||||
|
return pht(
|
||||||
|
'%s changed the subtype of %s from "%s" to "%s".',
|
||||||
|
$this->renderHandleLink($author_phid),
|
||||||
|
$this->renderHandleLink($object_phid),
|
||||||
|
$this->renderSubtypeName($old),
|
||||||
|
$this->renderSubtypeName($new));
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent::getTitleForFeed();
|
return parent::getTitleForFeed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function renderSubtypeName($value) {
|
||||||
|
$object = $this->getObject();
|
||||||
|
$map = $object->newEditEngineSubtypeMap();
|
||||||
|
if (!isset($map[$value])) {
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $map[$value]->getName();
|
||||||
|
}
|
||||||
|
|
||||||
public function hasChangeDetails() {
|
public function hasChangeDetails() {
|
||||||
switch ($this->getTransactionType()) {
|
switch ($this->getTransactionType()) {
|
||||||
case self::TYPE_DESCRIPTION:
|
case self::TYPE_DESCRIPTION:
|
||||||
|
|
|
@ -15,6 +15,7 @@ final class PhabricatorTransactions extends Phobject {
|
||||||
const TYPE_SPACE = 'core:space';
|
const TYPE_SPACE = 'core:space';
|
||||||
const TYPE_CREATE = 'core:create';
|
const TYPE_CREATE = 'core:create';
|
||||||
const TYPE_COLUMNS = 'core:columns';
|
const TYPE_COLUMNS = 'core:columns';
|
||||||
|
const TYPE_SUBTYPE = 'core:subtype';
|
||||||
|
|
||||||
const COLOR_RED = 'red';
|
const COLOR_RED = 'red';
|
||||||
const COLOR_ORANGE = 'orange';
|
const COLOR_ORANGE = 'orange';
|
||||||
|
|
|
@ -976,6 +976,9 @@ abstract class PhabricatorEditEngine
|
||||||
$fields = $this->buildEditFields($object);
|
$fields = $this->buildEditFields($object);
|
||||||
$template = $object->getApplicationTransactionTemplate();
|
$template = $object->getApplicationTransactionTemplate();
|
||||||
|
|
||||||
|
$config = $this->getEditEngineConfiguration()
|
||||||
|
->attachEngine($this);
|
||||||
|
|
||||||
$validation_exception = null;
|
$validation_exception = null;
|
||||||
if ($request->isFormPost() && $request->getBool('editEngine')) {
|
if ($request->isFormPost() && $request->getBool('editEngine')) {
|
||||||
$submit_fields = $fields;
|
$submit_fields = $fields;
|
||||||
|
@ -1010,6 +1013,12 @@ abstract class PhabricatorEditEngine
|
||||||
if ($this->getIsCreate()) {
|
if ($this->getIsCreate()) {
|
||||||
$xactions[] = id(clone $template)
|
$xactions[] = id(clone $template)
|
||||||
->setTransactionType(PhabricatorTransactions::TYPE_CREATE);
|
->setTransactionType(PhabricatorTransactions::TYPE_CREATE);
|
||||||
|
|
||||||
|
if ($this->supportsSubtypes()) {
|
||||||
|
$xactions[] = id(clone $template)
|
||||||
|
->setTransactionType(PhabricatorTransactions::TYPE_SUBTYPE)
|
||||||
|
->setNewValue($config->getSubtype());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($submit_fields as $key => $field) {
|
foreach ($submit_fields as $key => $field) {
|
||||||
|
|
|
@ -261,6 +261,10 @@ abstract class PhabricatorApplicationTransactionEditor
|
||||||
|
|
||||||
$types[] = PhabricatorTransactions::TYPE_CREATE;
|
$types[] = PhabricatorTransactions::TYPE_CREATE;
|
||||||
|
|
||||||
|
if ($this->object instanceof PhabricatorEditEngineSubtypeInterface) {
|
||||||
|
$types[] = PhabricatorTransactions::TYPE_SUBTYPE;
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->object instanceof PhabricatorSubscribableInterface) {
|
if ($this->object instanceof PhabricatorSubscribableInterface) {
|
||||||
$types[] = PhabricatorTransactions::TYPE_SUBSCRIBERS;
|
$types[] = PhabricatorTransactions::TYPE_SUBSCRIBERS;
|
||||||
}
|
}
|
||||||
|
@ -324,6 +328,8 @@ abstract class PhabricatorApplicationTransactionEditor
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
case PhabricatorTransactions::TYPE_CREATE:
|
case PhabricatorTransactions::TYPE_CREATE:
|
||||||
return null;
|
return null;
|
||||||
|
case PhabricatorTransactions::TYPE_SUBTYPE:
|
||||||
|
return $object->getEditEngineSubtype();
|
||||||
case PhabricatorTransactions::TYPE_SUBSCRIBERS:
|
case PhabricatorTransactions::TYPE_SUBSCRIBERS:
|
||||||
return array_values($this->subscribers);
|
return array_values($this->subscribers);
|
||||||
case PhabricatorTransactions::TYPE_VIEW_POLICY:
|
case PhabricatorTransactions::TYPE_VIEW_POLICY:
|
||||||
|
@ -410,6 +416,7 @@ abstract class PhabricatorApplicationTransactionEditor
|
||||||
case PhabricatorTransactions::TYPE_BUILDABLE:
|
case PhabricatorTransactions::TYPE_BUILDABLE:
|
||||||
case PhabricatorTransactions::TYPE_TOKEN:
|
case PhabricatorTransactions::TYPE_TOKEN:
|
||||||
case PhabricatorTransactions::TYPE_INLINESTATE:
|
case PhabricatorTransactions::TYPE_INLINESTATE:
|
||||||
|
case PhabricatorTransactions::TYPE_SUBTYPE:
|
||||||
return $xaction->getNewValue();
|
return $xaction->getNewValue();
|
||||||
case PhabricatorTransactions::TYPE_SPACE:
|
case PhabricatorTransactions::TYPE_SPACE:
|
||||||
$space_phid = $xaction->getNewValue();
|
$space_phid = $xaction->getNewValue();
|
||||||
|
@ -542,6 +549,7 @@ abstract class PhabricatorApplicationTransactionEditor
|
||||||
$field = $this->getCustomFieldForTransaction($object, $xaction);
|
$field = $this->getCustomFieldForTransaction($object, $xaction);
|
||||||
return $field->applyApplicationTransactionInternalEffects($xaction);
|
return $field->applyApplicationTransactionInternalEffects($xaction);
|
||||||
case PhabricatorTransactions::TYPE_CREATE:
|
case PhabricatorTransactions::TYPE_CREATE:
|
||||||
|
case PhabricatorTransactions::TYPE_SUBTYPE:
|
||||||
case PhabricatorTransactions::TYPE_BUILDABLE:
|
case PhabricatorTransactions::TYPE_BUILDABLE:
|
||||||
case PhabricatorTransactions::TYPE_TOKEN:
|
case PhabricatorTransactions::TYPE_TOKEN:
|
||||||
case PhabricatorTransactions::TYPE_VIEW_POLICY:
|
case PhabricatorTransactions::TYPE_VIEW_POLICY:
|
||||||
|
@ -601,6 +609,7 @@ abstract class PhabricatorApplicationTransactionEditor
|
||||||
$field = $this->getCustomFieldForTransaction($object, $xaction);
|
$field = $this->getCustomFieldForTransaction($object, $xaction);
|
||||||
return $field->applyApplicationTransactionExternalEffects($xaction);
|
return $field->applyApplicationTransactionExternalEffects($xaction);
|
||||||
case PhabricatorTransactions::TYPE_CREATE:
|
case PhabricatorTransactions::TYPE_CREATE:
|
||||||
|
case PhabricatorTransactions::TYPE_SUBTYPE:
|
||||||
case PhabricatorTransactions::TYPE_EDGE:
|
case PhabricatorTransactions::TYPE_EDGE:
|
||||||
case PhabricatorTransactions::TYPE_BUILDABLE:
|
case PhabricatorTransactions::TYPE_BUILDABLE:
|
||||||
case PhabricatorTransactions::TYPE_TOKEN:
|
case PhabricatorTransactions::TYPE_TOKEN:
|
||||||
|
@ -664,6 +673,9 @@ abstract class PhabricatorApplicationTransactionEditor
|
||||||
case PhabricatorTransactions::TYPE_SPACE:
|
case PhabricatorTransactions::TYPE_SPACE:
|
||||||
$object->setSpacePHID($xaction->getNewValue());
|
$object->setSpacePHID($xaction->getNewValue());
|
||||||
break;
|
break;
|
||||||
|
case PhabricatorTransactions::TYPE_SUBTYPE:
|
||||||
|
$object->setEditEngineSubtype($xaction->getNewValue());
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2103,6 +2115,12 @@ abstract class PhabricatorApplicationTransactionEditor
|
||||||
$xactions,
|
$xactions,
|
||||||
$type);
|
$type);
|
||||||
break;
|
break;
|
||||||
|
case PhabricatorTransactions::TYPE_SUBTYPE:
|
||||||
|
$errors[] = $this->validateSubtypeTransactions(
|
||||||
|
$object,
|
||||||
|
$xactions,
|
||||||
|
$type);
|
||||||
|
break;
|
||||||
case PhabricatorTransactions::TYPE_CUSTOMFIELD:
|
case PhabricatorTransactions::TYPE_CUSTOMFIELD:
|
||||||
$groups = array();
|
$groups = array();
|
||||||
foreach ($xactions as $xaction) {
|
foreach ($xactions as $xaction) {
|
||||||
|
@ -2254,6 +2272,35 @@ abstract class PhabricatorApplicationTransactionEditor
|
||||||
return $errors;
|
return $errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function validateSubtypeTransactions(
|
||||||
|
PhabricatorLiskDAO $object,
|
||||||
|
array $xactions,
|
||||||
|
$transaction_type) {
|
||||||
|
$errors = array();
|
||||||
|
|
||||||
|
$map = $object->newEditEngineSubtypeMap();
|
||||||
|
$old = $object->getEditEngineSubtype();
|
||||||
|
foreach ($xactions as $xaction) {
|
||||||
|
$new = $xaction->getNewValue();
|
||||||
|
|
||||||
|
if ($old == $new) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($map[$new])) {
|
||||||
|
$errors[] = new PhabricatorApplicationTransactionValidationError(
|
||||||
|
$transaction_type,
|
||||||
|
pht('Invalid'),
|
||||||
|
pht(
|
||||||
|
'The subtype "%s" is not a valid subtype.',
|
||||||
|
$new),
|
||||||
|
$xaction);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $errors;
|
||||||
|
}
|
||||||
|
|
||||||
protected function adjustObjectForPolicyChecks(
|
protected function adjustObjectForPolicyChecks(
|
||||||
PhabricatorLiskDAO $object,
|
PhabricatorLiskDAO $object,
|
||||||
|
|
|
@ -57,7 +57,9 @@ final class PhabricatorEditEngineConfigurationEditor
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PhabricatorEditEngineConfigurationTransaction::TYPE_SUBTYPE:
|
case PhabricatorEditEngineConfigurationTransaction::TYPE_SUBTYPE:
|
||||||
$map = $object->getEngine()->newSubtypeMap();
|
$map = $object->getEngine()
|
||||||
|
->setViewer($this->getActor())
|
||||||
|
->newSubtypeMap();
|
||||||
foreach ($xactions as $xaction) {
|
foreach ($xactions as $xaction) {
|
||||||
$new = $xaction->getNewValue();
|
$new = $xaction->getNewValue();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorSubtypeEditEngineExtension
|
||||||
|
extends PhabricatorEditEngineExtension {
|
||||||
|
|
||||||
|
const EXTENSIONKEY = 'editengine.subtype';
|
||||||
|
const EDITKEY = 'subtype';
|
||||||
|
|
||||||
|
public function getExtensionPriority() {
|
||||||
|
return 8000;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isExtensionEnabled() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getExtensionName() {
|
||||||
|
return pht('Subtypes');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function supportsObject(
|
||||||
|
PhabricatorEditEngine $engine,
|
||||||
|
PhabricatorApplicationTransactionInterface $object) {
|
||||||
|
return $engine->supportsSubtypes();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildCustomEditFields(
|
||||||
|
PhabricatorEditEngine $engine,
|
||||||
|
PhabricatorApplicationTransactionInterface $object) {
|
||||||
|
|
||||||
|
$subtype_type = PhabricatorTransactions::TYPE_SUBTYPE;
|
||||||
|
|
||||||
|
$subtype_field = id(new PhabricatorSelectEditField())
|
||||||
|
->setKey(self::EDITKEY)
|
||||||
|
->setLabel(pht('Subtype'))
|
||||||
|
->setIsConduitOnly(true)
|
||||||
|
->setIsHidden(true)
|
||||||
|
->setIsReorderable(false)
|
||||||
|
->setIsDefaultable(false)
|
||||||
|
->setIsLockable(false)
|
||||||
|
->setTransactionType($subtype_type)
|
||||||
|
->setConduitDescription(pht('Change the object subtype.'))
|
||||||
|
->setConduitTypeDescription(pht('New object subtype key.'))
|
||||||
|
->setValue($object->getEditEngineSubtype());
|
||||||
|
|
||||||
|
return array(
|
||||||
|
$subtype_field,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -546,6 +546,8 @@ abstract class PhabricatorApplicationTransaction
|
||||||
case PhabricatorTransactions::TYPE_JOIN_POLICY:
|
case PhabricatorTransactions::TYPE_JOIN_POLICY:
|
||||||
case PhabricatorTransactions::TYPE_SPACE:
|
case PhabricatorTransactions::TYPE_SPACE:
|
||||||
break;
|
break;
|
||||||
|
case PhabricatorTransactions::TYPE_SUBTYPE:
|
||||||
|
return true;
|
||||||
default:
|
default:
|
||||||
$old = $this->getOldValue();
|
$old = $this->getOldValue();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue