Implement a basic version of ApplicationEditor in Paste
Summary:
Ref T9132. Ref T4768. This is a rough v0 of ApplicationEditor, which replaces the edit workflow in Paste.
This mostly looks and works like ApplicationSearch, and is heavily modeled on it.
Roughly, we define a set of editable fields and the ApplicationEditor stuff builds everything else.
This has no functional changes, except:
- I removed "Fork Paste" since I don't think it's particularly useful now that pastes are editable. We could restore it if users miss it.
- Subscribers are now editable.
- Form field order is a little goofy (this will be fixed in a future diff).
- Subscribers and projects are now race-resistant.
The race-resistance works like this: instead of submitting just the new value ("subscribers=apple, dog") and doing a set operation ("set subscribers = apple, dog"), we submit the old and new values ("original=apple" + "new=apple, dog") then apply the user's changes as an add + remove ("add=dog", "remove=<none>"). This means that two users who do "Edit Paste" at around the same time and each add or remove a couple of subscribers won't overwrite each other, unless they actually add or remove the exact same subscribers (in which case their edits legitimately conflict). Previously, the last user to save would win, and whatever was in their field would overwrite the prior state, potentially losing the first user's edits.
Test Plan:
- Created pastes.
- Created pastes via API.
- Edited pastes.
- Edited every field.
- Opened a paste in two windows and did project/subscriber edits in each, saved in arbitrary order, had edits respected.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T4768, T9132
Differential Revision: https://secure.phabricator.com/D14390
2015-11-02 18:58:32 -08:00
|
|
|
<?php
|
|
|
|
|
|
|
|
abstract class PhabricatorApplicationEditEngine extends Phobject {
|
|
|
|
|
|
|
|
private $viewer;
|
|
|
|
private $controller;
|
2015-11-03 05:38:06 -08:00
|
|
|
private $isCreate;
|
Implement a basic version of ApplicationEditor in Paste
Summary:
Ref T9132. Ref T4768. This is a rough v0 of ApplicationEditor, which replaces the edit workflow in Paste.
This mostly looks and works like ApplicationSearch, and is heavily modeled on it.
Roughly, we define a set of editable fields and the ApplicationEditor stuff builds everything else.
This has no functional changes, except:
- I removed "Fork Paste" since I don't think it's particularly useful now that pastes are editable. We could restore it if users miss it.
- Subscribers are now editable.
- Form field order is a little goofy (this will be fixed in a future diff).
- Subscribers and projects are now race-resistant.
The race-resistance works like this: instead of submitting just the new value ("subscribers=apple, dog") and doing a set operation ("set subscribers = apple, dog"), we submit the old and new values ("original=apple" + "new=apple, dog") then apply the user's changes as an add + remove ("add=dog", "remove=<none>"). This means that two users who do "Edit Paste" at around the same time and each add or remove a couple of subscribers won't overwrite each other, unless they actually add or remove the exact same subscribers (in which case their edits legitimately conflict). Previously, the last user to save would win, and whatever was in their field would overwrite the prior state, potentially losing the first user's edits.
Test Plan:
- Created pastes.
- Created pastes via API.
- Edited pastes.
- Edited every field.
- Opened a paste in two windows and did project/subscriber edits in each, saved in arbitrary order, had edits respected.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T4768, T9132
Differential Revision: https://secure.phabricator.com/D14390
2015-11-02 18:58:32 -08:00
|
|
|
|
|
|
|
final public function setViewer(PhabricatorUser $viewer) {
|
|
|
|
$this->viewer = $viewer;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
final public function getViewer() {
|
|
|
|
return $this->viewer;
|
|
|
|
}
|
|
|
|
|
|
|
|
final public function setController(PhabricatorController $controller) {
|
|
|
|
$this->controller = $controller;
|
|
|
|
$this->setViewer($controller->getViewer());
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
final public function getController() {
|
|
|
|
return $this->controller;
|
|
|
|
}
|
|
|
|
|
|
|
|
final protected function buildEditFields($object) {
|
|
|
|
$viewer = $this->getViewer();
|
|
|
|
$editor = $object->getApplicationTransactionEditor();
|
|
|
|
|
|
|
|
$types = $editor->getTransactionTypesForObject($object);
|
|
|
|
$types = array_fuse($types);
|
|
|
|
|
|
|
|
$fields = $this->buildCustomEditFields($object);
|
|
|
|
|
|
|
|
if ($object instanceof PhabricatorPolicyInterface) {
|
|
|
|
$policies = id(new PhabricatorPolicyQuery())
|
|
|
|
->setViewer($viewer)
|
|
|
|
->setObject($object)
|
|
|
|
->execute();
|
|
|
|
|
|
|
|
$map = array(
|
|
|
|
PhabricatorTransactions::TYPE_VIEW_POLICY => array(
|
|
|
|
'key' => 'policy.view',
|
|
|
|
'aliases' => array('view'),
|
|
|
|
'capability' => PhabricatorPolicyCapability::CAN_VIEW,
|
2015-11-03 05:38:06 -08:00
|
|
|
'label' => pht('View Policy'),
|
|
|
|
'description' => pht('Controls who can view the object.'),
|
Implement a basic version of ApplicationEditor in Paste
Summary:
Ref T9132. Ref T4768. This is a rough v0 of ApplicationEditor, which replaces the edit workflow in Paste.
This mostly looks and works like ApplicationSearch, and is heavily modeled on it.
Roughly, we define a set of editable fields and the ApplicationEditor stuff builds everything else.
This has no functional changes, except:
- I removed "Fork Paste" since I don't think it's particularly useful now that pastes are editable. We could restore it if users miss it.
- Subscribers are now editable.
- Form field order is a little goofy (this will be fixed in a future diff).
- Subscribers and projects are now race-resistant.
The race-resistance works like this: instead of submitting just the new value ("subscribers=apple, dog") and doing a set operation ("set subscribers = apple, dog"), we submit the old and new values ("original=apple" + "new=apple, dog") then apply the user's changes as an add + remove ("add=dog", "remove=<none>"). This means that two users who do "Edit Paste" at around the same time and each add or remove a couple of subscribers won't overwrite each other, unless they actually add or remove the exact same subscribers (in which case their edits legitimately conflict). Previously, the last user to save would win, and whatever was in their field would overwrite the prior state, potentially losing the first user's edits.
Test Plan:
- Created pastes.
- Created pastes via API.
- Edited pastes.
- Edited every field.
- Opened a paste in two windows and did project/subscriber edits in each, saved in arbitrary order, had edits respected.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T4768, T9132
Differential Revision: https://secure.phabricator.com/D14390
2015-11-02 18:58:32 -08:00
|
|
|
),
|
|
|
|
PhabricatorTransactions::TYPE_EDIT_POLICY => array(
|
|
|
|
'key' => 'policy.edit',
|
|
|
|
'aliases' => array('edit'),
|
|
|
|
'capability' => PhabricatorPolicyCapability::CAN_EDIT,
|
2015-11-03 05:38:06 -08:00
|
|
|
'label' => pht('Edit Policy'),
|
|
|
|
'description' => pht('Controls who can edit the object.'),
|
Implement a basic version of ApplicationEditor in Paste
Summary:
Ref T9132. Ref T4768. This is a rough v0 of ApplicationEditor, which replaces the edit workflow in Paste.
This mostly looks and works like ApplicationSearch, and is heavily modeled on it.
Roughly, we define a set of editable fields and the ApplicationEditor stuff builds everything else.
This has no functional changes, except:
- I removed "Fork Paste" since I don't think it's particularly useful now that pastes are editable. We could restore it if users miss it.
- Subscribers are now editable.
- Form field order is a little goofy (this will be fixed in a future diff).
- Subscribers and projects are now race-resistant.
The race-resistance works like this: instead of submitting just the new value ("subscribers=apple, dog") and doing a set operation ("set subscribers = apple, dog"), we submit the old and new values ("original=apple" + "new=apple, dog") then apply the user's changes as an add + remove ("add=dog", "remove=<none>"). This means that two users who do "Edit Paste" at around the same time and each add or remove a couple of subscribers won't overwrite each other, unless they actually add or remove the exact same subscribers (in which case their edits legitimately conflict). Previously, the last user to save would win, and whatever was in their field would overwrite the prior state, potentially losing the first user's edits.
Test Plan:
- Created pastes.
- Created pastes via API.
- Edited pastes.
- Edited every field.
- Opened a paste in two windows and did project/subscriber edits in each, saved in arbitrary order, had edits respected.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T4768, T9132
Differential Revision: https://secure.phabricator.com/D14390
2015-11-02 18:58:32 -08:00
|
|
|
),
|
|
|
|
PhabricatorTransactions::TYPE_JOIN_POLICY => array(
|
|
|
|
'key' => 'policy.join',
|
|
|
|
'aliases' => array('join'),
|
|
|
|
'capability' => PhabricatorPolicyCapability::CAN_JOIN,
|
2015-11-03 05:38:06 -08:00
|
|
|
'label' => pht('Join Policy'),
|
|
|
|
'description' => pht('Controls who can join the object.'),
|
Implement a basic version of ApplicationEditor in Paste
Summary:
Ref T9132. Ref T4768. This is a rough v0 of ApplicationEditor, which replaces the edit workflow in Paste.
This mostly looks and works like ApplicationSearch, and is heavily modeled on it.
Roughly, we define a set of editable fields and the ApplicationEditor stuff builds everything else.
This has no functional changes, except:
- I removed "Fork Paste" since I don't think it's particularly useful now that pastes are editable. We could restore it if users miss it.
- Subscribers are now editable.
- Form field order is a little goofy (this will be fixed in a future diff).
- Subscribers and projects are now race-resistant.
The race-resistance works like this: instead of submitting just the new value ("subscribers=apple, dog") and doing a set operation ("set subscribers = apple, dog"), we submit the old and new values ("original=apple" + "new=apple, dog") then apply the user's changes as an add + remove ("add=dog", "remove=<none>"). This means that two users who do "Edit Paste" at around the same time and each add or remove a couple of subscribers won't overwrite each other, unless they actually add or remove the exact same subscribers (in which case their edits legitimately conflict). Previously, the last user to save would win, and whatever was in their field would overwrite the prior state, potentially losing the first user's edits.
Test Plan:
- Created pastes.
- Created pastes via API.
- Edited pastes.
- Edited every field.
- Opened a paste in two windows and did project/subscriber edits in each, saved in arbitrary order, had edits respected.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T4768, T9132
Differential Revision: https://secure.phabricator.com/D14390
2015-11-02 18:58:32 -08:00
|
|
|
),
|
|
|
|
);
|
|
|
|
|
|
|
|
foreach ($map as $type => $spec) {
|
|
|
|
if (empty($types[$type])) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
$capability = $spec['capability'];
|
|
|
|
$key = $spec['key'];
|
|
|
|
$aliases = $spec['aliases'];
|
2015-11-03 05:38:06 -08:00
|
|
|
$label = $spec['label'];
|
|
|
|
$description = $spec['description'];
|
Implement a basic version of ApplicationEditor in Paste
Summary:
Ref T9132. Ref T4768. This is a rough v0 of ApplicationEditor, which replaces the edit workflow in Paste.
This mostly looks and works like ApplicationSearch, and is heavily modeled on it.
Roughly, we define a set of editable fields and the ApplicationEditor stuff builds everything else.
This has no functional changes, except:
- I removed "Fork Paste" since I don't think it's particularly useful now that pastes are editable. We could restore it if users miss it.
- Subscribers are now editable.
- Form field order is a little goofy (this will be fixed in a future diff).
- Subscribers and projects are now race-resistant.
The race-resistance works like this: instead of submitting just the new value ("subscribers=apple, dog") and doing a set operation ("set subscribers = apple, dog"), we submit the old and new values ("original=apple" + "new=apple, dog") then apply the user's changes as an add + remove ("add=dog", "remove=<none>"). This means that two users who do "Edit Paste" at around the same time and each add or remove a couple of subscribers won't overwrite each other, unless they actually add or remove the exact same subscribers (in which case their edits legitimately conflict). Previously, the last user to save would win, and whatever was in their field would overwrite the prior state, potentially losing the first user's edits.
Test Plan:
- Created pastes.
- Created pastes via API.
- Edited pastes.
- Edited every field.
- Opened a paste in two windows and did project/subscriber edits in each, saved in arbitrary order, had edits respected.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T4768, T9132
Differential Revision: https://secure.phabricator.com/D14390
2015-11-02 18:58:32 -08:00
|
|
|
|
|
|
|
$policy_field = id(new PhabricatorPolicyEditField())
|
|
|
|
->setKey($key)
|
2015-11-03 05:38:06 -08:00
|
|
|
->setLabel($label)
|
|
|
|
->setDescription($description)
|
Implement a basic version of ApplicationEditor in Paste
Summary:
Ref T9132. Ref T4768. This is a rough v0 of ApplicationEditor, which replaces the edit workflow in Paste.
This mostly looks and works like ApplicationSearch, and is heavily modeled on it.
Roughly, we define a set of editable fields and the ApplicationEditor stuff builds everything else.
This has no functional changes, except:
- I removed "Fork Paste" since I don't think it's particularly useful now that pastes are editable. We could restore it if users miss it.
- Subscribers are now editable.
- Form field order is a little goofy (this will be fixed in a future diff).
- Subscribers and projects are now race-resistant.
The race-resistance works like this: instead of submitting just the new value ("subscribers=apple, dog") and doing a set operation ("set subscribers = apple, dog"), we submit the old and new values ("original=apple" + "new=apple, dog") then apply the user's changes as an add + remove ("add=dog", "remove=<none>"). This means that two users who do "Edit Paste" at around the same time and each add or remove a couple of subscribers won't overwrite each other, unless they actually add or remove the exact same subscribers (in which case their edits legitimately conflict). Previously, the last user to save would win, and whatever was in their field would overwrite the prior state, potentially losing the first user's edits.
Test Plan:
- Created pastes.
- Created pastes via API.
- Edited pastes.
- Edited every field.
- Opened a paste in two windows and did project/subscriber edits in each, saved in arbitrary order, had edits respected.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T4768, T9132
Differential Revision: https://secure.phabricator.com/D14390
2015-11-02 18:58:32 -08:00
|
|
|
->setAliases($aliases)
|
|
|
|
->setCapability($capability)
|
|
|
|
->setPolicies($policies)
|
|
|
|
->setTransactionType($type)
|
|
|
|
->setValue($object->getPolicy($capability));
|
|
|
|
$fields[] = $policy_field;
|
|
|
|
|
|
|
|
if ($object instanceof PhabricatorSpacesInterface) {
|
|
|
|
if ($capability == PhabricatorPolicyCapability::CAN_VIEW) {
|
|
|
|
$type_space = PhabricatorTransactions::TYPE_SPACE;
|
|
|
|
if (isset($types[$type_space])) {
|
|
|
|
$space_field = id(new PhabricatorSpaceEditField())
|
|
|
|
->setKey('spacePHID')
|
2015-11-03 05:38:06 -08:00
|
|
|
->setLabel(pht('Space'))
|
|
|
|
->setDescription(
|
|
|
|
pht('Shifts the object in the Spaces application.'))
|
Implement a basic version of ApplicationEditor in Paste
Summary:
Ref T9132. Ref T4768. This is a rough v0 of ApplicationEditor, which replaces the edit workflow in Paste.
This mostly looks and works like ApplicationSearch, and is heavily modeled on it.
Roughly, we define a set of editable fields and the ApplicationEditor stuff builds everything else.
This has no functional changes, except:
- I removed "Fork Paste" since I don't think it's particularly useful now that pastes are editable. We could restore it if users miss it.
- Subscribers are now editable.
- Form field order is a little goofy (this will be fixed in a future diff).
- Subscribers and projects are now race-resistant.
The race-resistance works like this: instead of submitting just the new value ("subscribers=apple, dog") and doing a set operation ("set subscribers = apple, dog"), we submit the old and new values ("original=apple" + "new=apple, dog") then apply the user's changes as an add + remove ("add=dog", "remove=<none>"). This means that two users who do "Edit Paste" at around the same time and each add or remove a couple of subscribers won't overwrite each other, unless they actually add or remove the exact same subscribers (in which case their edits legitimately conflict). Previously, the last user to save would win, and whatever was in their field would overwrite the prior state, potentially losing the first user's edits.
Test Plan:
- Created pastes.
- Created pastes via API.
- Edited pastes.
- Edited every field.
- Opened a paste in two windows and did project/subscriber edits in each, saved in arbitrary order, had edits respected.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T4768, T9132
Differential Revision: https://secure.phabricator.com/D14390
2015-11-02 18:58:32 -08:00
|
|
|
->setAliases(array('space', 'policy.space'))
|
|
|
|
->setTransactionType($type_space)
|
|
|
|
->setValue($object->getSpacePHID());
|
|
|
|
$fields[] = $space_field;
|
|
|
|
|
|
|
|
$policy_field->setSpaceField($space_field);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$edge_type = PhabricatorTransactions::TYPE_EDGE;
|
|
|
|
$object_phid = $object->getPHID();
|
|
|
|
|
|
|
|
$project_edge_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
|
|
|
|
|
|
|
|
if ($object instanceof PhabricatorProjectInterface) {
|
|
|
|
if (isset($types[$edge_type])) {
|
|
|
|
if ($object_phid) {
|
|
|
|
$project_phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
|
|
|
|
$object_phid,
|
|
|
|
$project_edge_type);
|
|
|
|
$project_phids = array_reverse($project_phids);
|
|
|
|
} else {
|
|
|
|
$project_phids = array();
|
|
|
|
}
|
|
|
|
|
|
|
|
$edge_field = id(new PhabricatorDatasourceEditField())
|
|
|
|
->setKey('projectPHIDs')
|
|
|
|
->setLabel(pht('Projects'))
|
2015-11-03 05:38:06 -08:00
|
|
|
->setDescription(
|
|
|
|
pht(
|
|
|
|
'Add or remove associated projects.'))
|
Implement a basic version of ApplicationEditor in Paste
Summary:
Ref T9132. Ref T4768. This is a rough v0 of ApplicationEditor, which replaces the edit workflow in Paste.
This mostly looks and works like ApplicationSearch, and is heavily modeled on it.
Roughly, we define a set of editable fields and the ApplicationEditor stuff builds everything else.
This has no functional changes, except:
- I removed "Fork Paste" since I don't think it's particularly useful now that pastes are editable. We could restore it if users miss it.
- Subscribers are now editable.
- Form field order is a little goofy (this will be fixed in a future diff).
- Subscribers and projects are now race-resistant.
The race-resistance works like this: instead of submitting just the new value ("subscribers=apple, dog") and doing a set operation ("set subscribers = apple, dog"), we submit the old and new values ("original=apple" + "new=apple, dog") then apply the user's changes as an add + remove ("add=dog", "remove=<none>"). This means that two users who do "Edit Paste" at around the same time and each add or remove a couple of subscribers won't overwrite each other, unless they actually add or remove the exact same subscribers (in which case their edits legitimately conflict). Previously, the last user to save would win, and whatever was in their field would overwrite the prior state, potentially losing the first user's edits.
Test Plan:
- Created pastes.
- Created pastes via API.
- Edited pastes.
- Edited every field.
- Opened a paste in two windows and did project/subscriber edits in each, saved in arbitrary order, had edits respected.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T4768, T9132
Differential Revision: https://secure.phabricator.com/D14390
2015-11-02 18:58:32 -08:00
|
|
|
->setDatasource(new PhabricatorProjectDatasource())
|
|
|
|
->setAliases(array('project', 'projects'))
|
|
|
|
->setTransactionType($edge_type)
|
|
|
|
->setMetadataValue('edge:type', $project_edge_type)
|
|
|
|
->setValue($project_phids);
|
|
|
|
$fields[] = $edge_field;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$subscribers_type = PhabricatorTransactions::TYPE_SUBSCRIBERS;
|
|
|
|
|
|
|
|
if ($object instanceof PhabricatorSubscribableInterface) {
|
|
|
|
if (isset($types[$subscribers_type])) {
|
|
|
|
if ($object_phid) {
|
|
|
|
$sub_phids = PhabricatorSubscribersQuery::loadSubscribersForPHID(
|
|
|
|
$object_phid);
|
|
|
|
} else {
|
|
|
|
// TODO: Allow applications to provide default subscribers; Maniphest
|
|
|
|
// does this at a minimum.
|
|
|
|
$sub_phids = array();
|
|
|
|
}
|
|
|
|
|
|
|
|
$subscribers_field = id(new PhabricatorDatasourceEditField())
|
|
|
|
->setKey('subscriberPHIDs')
|
|
|
|
->setLabel(pht('Subscribers'))
|
2015-11-03 05:38:06 -08:00
|
|
|
->setDescription(pht('Manage subscribers.'))
|
Implement a basic version of ApplicationEditor in Paste
Summary:
Ref T9132. Ref T4768. This is a rough v0 of ApplicationEditor, which replaces the edit workflow in Paste.
This mostly looks and works like ApplicationSearch, and is heavily modeled on it.
Roughly, we define a set of editable fields and the ApplicationEditor stuff builds everything else.
This has no functional changes, except:
- I removed "Fork Paste" since I don't think it's particularly useful now that pastes are editable. We could restore it if users miss it.
- Subscribers are now editable.
- Form field order is a little goofy (this will be fixed in a future diff).
- Subscribers and projects are now race-resistant.
The race-resistance works like this: instead of submitting just the new value ("subscribers=apple, dog") and doing a set operation ("set subscribers = apple, dog"), we submit the old and new values ("original=apple" + "new=apple, dog") then apply the user's changes as an add + remove ("add=dog", "remove=<none>"). This means that two users who do "Edit Paste" at around the same time and each add or remove a couple of subscribers won't overwrite each other, unless they actually add or remove the exact same subscribers (in which case their edits legitimately conflict). Previously, the last user to save would win, and whatever was in their field would overwrite the prior state, potentially losing the first user's edits.
Test Plan:
- Created pastes.
- Created pastes via API.
- Edited pastes.
- Edited every field.
- Opened a paste in two windows and did project/subscriber edits in each, saved in arbitrary order, had edits respected.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T4768, T9132
Differential Revision: https://secure.phabricator.com/D14390
2015-11-02 18:58:32 -08:00
|
|
|
->setDatasource(new PhabricatorMetaMTAMailableDatasource())
|
|
|
|
->setAliases(array('subscriber', 'subscribers'))
|
|
|
|
->setTransactionType($subscribers_type)
|
|
|
|
->setValue($sub_phids);
|
|
|
|
$fields[] = $subscribers_field;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $fields;
|
|
|
|
}
|
|
|
|
|
|
|
|
abstract protected function newEditableObject();
|
|
|
|
abstract protected function newObjectQuery();
|
|
|
|
abstract protected function buildCustomEditFields($object);
|
|
|
|
|
|
|
|
abstract protected function getObjectCreateTitleText($object);
|
|
|
|
abstract protected function getObjectEditTitleText($object);
|
|
|
|
abstract protected function getObjectCreateShortText($object);
|
|
|
|
abstract protected function getObjectEditShortText($object);
|
|
|
|
abstract protected function getObjectViewURI($object);
|
|
|
|
|
2015-11-03 05:38:06 -08:00
|
|
|
protected function getObjectEditURI($object) {
|
|
|
|
return $this->getController()->getApplicationURI('edit/');
|
|
|
|
}
|
|
|
|
|
Implement a basic version of ApplicationEditor in Paste
Summary:
Ref T9132. Ref T4768. This is a rough v0 of ApplicationEditor, which replaces the edit workflow in Paste.
This mostly looks and works like ApplicationSearch, and is heavily modeled on it.
Roughly, we define a set of editable fields and the ApplicationEditor stuff builds everything else.
This has no functional changes, except:
- I removed "Fork Paste" since I don't think it's particularly useful now that pastes are editable. We could restore it if users miss it.
- Subscribers are now editable.
- Form field order is a little goofy (this will be fixed in a future diff).
- Subscribers and projects are now race-resistant.
The race-resistance works like this: instead of submitting just the new value ("subscribers=apple, dog") and doing a set operation ("set subscribers = apple, dog"), we submit the old and new values ("original=apple" + "new=apple, dog") then apply the user's changes as an add + remove ("add=dog", "remove=<none>"). This means that two users who do "Edit Paste" at around the same time and each add or remove a couple of subscribers won't overwrite each other, unless they actually add or remove the exact same subscribers (in which case their edits legitimately conflict). Previously, the last user to save would win, and whatever was in their field would overwrite the prior state, potentially losing the first user's edits.
Test Plan:
- Created pastes.
- Created pastes via API.
- Edited pastes.
- Edited every field.
- Opened a paste in two windows and did project/subscriber edits in each, saved in arbitrary order, had edits respected.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T4768, T9132
Differential Revision: https://secure.phabricator.com/D14390
2015-11-02 18:58:32 -08:00
|
|
|
protected function getObjectCreateCancelURI($object) {
|
|
|
|
return $this->getController()->getApplicationURI();
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function getObjectEditCancelURI($object) {
|
|
|
|
return $this->getObjectViewURI($object);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function getObjectCreateButtonText($object) {
|
|
|
|
return $this->getObjectCreateTitleText($object);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function getObjectEditButtonText($object) {
|
|
|
|
return pht('Save Changes');
|
|
|
|
}
|
|
|
|
|
2015-11-03 05:38:06 -08:00
|
|
|
protected function getEditURI($object, $path = null) {
|
|
|
|
$parts = array(
|
|
|
|
$this->getObjectEditURI($object),
|
|
|
|
);
|
|
|
|
|
|
|
|
if (!$this->getIsCreate()) {
|
|
|
|
$parts[] = $object->getID().'/';
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($path !== null) {
|
|
|
|
$parts[] = $path;
|
|
|
|
}
|
|
|
|
|
|
|
|
return implode('', $parts);
|
|
|
|
}
|
|
|
|
|
|
|
|
final protected function setIsCreate($is_create) {
|
|
|
|
$this->isCreate = $is_create;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
final protected function getIsCreate() {
|
|
|
|
return $this->isCreate;
|
|
|
|
}
|
|
|
|
|
Implement a basic version of ApplicationEditor in Paste
Summary:
Ref T9132. Ref T4768. This is a rough v0 of ApplicationEditor, which replaces the edit workflow in Paste.
This mostly looks and works like ApplicationSearch, and is heavily modeled on it.
Roughly, we define a set of editable fields and the ApplicationEditor stuff builds everything else.
This has no functional changes, except:
- I removed "Fork Paste" since I don't think it's particularly useful now that pastes are editable. We could restore it if users miss it.
- Subscribers are now editable.
- Form field order is a little goofy (this will be fixed in a future diff).
- Subscribers and projects are now race-resistant.
The race-resistance works like this: instead of submitting just the new value ("subscribers=apple, dog") and doing a set operation ("set subscribers = apple, dog"), we submit the old and new values ("original=apple" + "new=apple, dog") then apply the user's changes as an add + remove ("add=dog", "remove=<none>"). This means that two users who do "Edit Paste" at around the same time and each add or remove a couple of subscribers won't overwrite each other, unless they actually add or remove the exact same subscribers (in which case their edits legitimately conflict). Previously, the last user to save would win, and whatever was in their field would overwrite the prior state, potentially losing the first user's edits.
Test Plan:
- Created pastes.
- Created pastes via API.
- Edited pastes.
- Edited every field.
- Opened a paste in two windows and did project/subscriber edits in each, saved in arbitrary order, had edits respected.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T4768, T9132
Differential Revision: https://secure.phabricator.com/D14390
2015-11-02 18:58:32 -08:00
|
|
|
final public function buildResponse() {
|
|
|
|
$controller = $this->getController();
|
|
|
|
$viewer = $this->getViewer();
|
|
|
|
$request = $controller->getRequest();
|
|
|
|
|
|
|
|
$id = $request->getURIData('id');
|
|
|
|
if ($id) {
|
|
|
|
$object = $this->newObjectQuery()
|
|
|
|
->setViewer($viewer)
|
|
|
|
->withIDs(array($id))
|
|
|
|
->requireCapabilities(
|
|
|
|
array(
|
|
|
|
PhabricatorPolicyCapability::CAN_VIEW,
|
|
|
|
PhabricatorPolicyCapability::CAN_EDIT,
|
|
|
|
))
|
|
|
|
->executeOne();
|
|
|
|
if (!$object) {
|
|
|
|
return new Aphront404Response();
|
|
|
|
}
|
|
|
|
|
2015-11-03 05:38:06 -08:00
|
|
|
$this->setIsCreate(false);
|
Implement a basic version of ApplicationEditor in Paste
Summary:
Ref T9132. Ref T4768. This is a rough v0 of ApplicationEditor, which replaces the edit workflow in Paste.
This mostly looks and works like ApplicationSearch, and is heavily modeled on it.
Roughly, we define a set of editable fields and the ApplicationEditor stuff builds everything else.
This has no functional changes, except:
- I removed "Fork Paste" since I don't think it's particularly useful now that pastes are editable. We could restore it if users miss it.
- Subscribers are now editable.
- Form field order is a little goofy (this will be fixed in a future diff).
- Subscribers and projects are now race-resistant.
The race-resistance works like this: instead of submitting just the new value ("subscribers=apple, dog") and doing a set operation ("set subscribers = apple, dog"), we submit the old and new values ("original=apple" + "new=apple, dog") then apply the user's changes as an add + remove ("add=dog", "remove=<none>"). This means that two users who do "Edit Paste" at around the same time and each add or remove a couple of subscribers won't overwrite each other, unless they actually add or remove the exact same subscribers (in which case their edits legitimately conflict). Previously, the last user to save would win, and whatever was in their field would overwrite the prior state, potentially losing the first user's edits.
Test Plan:
- Created pastes.
- Created pastes via API.
- Edited pastes.
- Edited every field.
- Opened a paste in two windows and did project/subscriber edits in each, saved in arbitrary order, had edits respected.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T4768, T9132
Differential Revision: https://secure.phabricator.com/D14390
2015-11-02 18:58:32 -08:00
|
|
|
} else {
|
|
|
|
$object = $this->newEditableObject();
|
|
|
|
|
2015-11-03 05:38:06 -08:00
|
|
|
$this->setIsCreate(true);
|
Implement a basic version of ApplicationEditor in Paste
Summary:
Ref T9132. Ref T4768. This is a rough v0 of ApplicationEditor, which replaces the edit workflow in Paste.
This mostly looks and works like ApplicationSearch, and is heavily modeled on it.
Roughly, we define a set of editable fields and the ApplicationEditor stuff builds everything else.
This has no functional changes, except:
- I removed "Fork Paste" since I don't think it's particularly useful now that pastes are editable. We could restore it if users miss it.
- Subscribers are now editable.
- Form field order is a little goofy (this will be fixed in a future diff).
- Subscribers and projects are now race-resistant.
The race-resistance works like this: instead of submitting just the new value ("subscribers=apple, dog") and doing a set operation ("set subscribers = apple, dog"), we submit the old and new values ("original=apple" + "new=apple, dog") then apply the user's changes as an add + remove ("add=dog", "remove=<none>"). This means that two users who do "Edit Paste" at around the same time and each add or remove a couple of subscribers won't overwrite each other, unless they actually add or remove the exact same subscribers (in which case their edits legitimately conflict). Previously, the last user to save would win, and whatever was in their field would overwrite the prior state, potentially losing the first user's edits.
Test Plan:
- Created pastes.
- Created pastes via API.
- Edited pastes.
- Edited every field.
- Opened a paste in two windows and did project/subscriber edits in each, saved in arbitrary order, had edits respected.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T4768, T9132
Differential Revision: https://secure.phabricator.com/D14390
2015-11-02 18:58:32 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
$fields = $this->buildEditFields($object);
|
|
|
|
|
|
|
|
foreach ($fields as $field) {
|
|
|
|
$field
|
|
|
|
->setViewer($viewer)
|
|
|
|
->setObject($object);
|
|
|
|
}
|
|
|
|
|
2015-11-03 05:38:06 -08:00
|
|
|
$action = $request->getURIData('editAction');
|
|
|
|
switch ($action) {
|
|
|
|
case 'parameters':
|
|
|
|
return $this->buildParametersResponse($object, $fields);
|
|
|
|
}
|
|
|
|
|
Implement a basic version of ApplicationEditor in Paste
Summary:
Ref T9132. Ref T4768. This is a rough v0 of ApplicationEditor, which replaces the edit workflow in Paste.
This mostly looks and works like ApplicationSearch, and is heavily modeled on it.
Roughly, we define a set of editable fields and the ApplicationEditor stuff builds everything else.
This has no functional changes, except:
- I removed "Fork Paste" since I don't think it's particularly useful now that pastes are editable. We could restore it if users miss it.
- Subscribers are now editable.
- Form field order is a little goofy (this will be fixed in a future diff).
- Subscribers and projects are now race-resistant.
The race-resistance works like this: instead of submitting just the new value ("subscribers=apple, dog") and doing a set operation ("set subscribers = apple, dog"), we submit the old and new values ("original=apple" + "new=apple, dog") then apply the user's changes as an add + remove ("add=dog", "remove=<none>"). This means that two users who do "Edit Paste" at around the same time and each add or remove a couple of subscribers won't overwrite each other, unless they actually add or remove the exact same subscribers (in which case their edits legitimately conflict). Previously, the last user to save would win, and whatever was in their field would overwrite the prior state, potentially losing the first user's edits.
Test Plan:
- Created pastes.
- Created pastes via API.
- Edited pastes.
- Edited every field.
- Opened a paste in two windows and did project/subscriber edits in each, saved in arbitrary order, had edits respected.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T4768, T9132
Differential Revision: https://secure.phabricator.com/D14390
2015-11-02 18:58:32 -08:00
|
|
|
$validation_exception = null;
|
|
|
|
if ($request->isFormPost()) {
|
|
|
|
foreach ($fields as $field) {
|
|
|
|
$field->readValueFromSubmit($request);
|
|
|
|
}
|
|
|
|
|
|
|
|
$template = $object->getApplicationTransactionTemplate();
|
|
|
|
|
|
|
|
$xactions = array();
|
|
|
|
foreach ($fields as $field) {
|
|
|
|
$xactions[] = $field->generateTransaction(clone $template);
|
|
|
|
}
|
|
|
|
|
|
|
|
$editor = $object->getApplicationTransactionEditor()
|
|
|
|
->setActor($viewer)
|
|
|
|
->setContentSourceFromRequest($request)
|
|
|
|
->setContinueOnNoEffect(true)
|
|
|
|
->setContinueOnMissingFields(false);
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
$editor->applyTransactions($object, $xactions);
|
|
|
|
|
|
|
|
return id(new AphrontRedirectResponse())
|
|
|
|
->setURI($this->getObjectViewURI($object));
|
|
|
|
} catch (PhabricatorApplicationTransactionValidationException $ex) {
|
|
|
|
$validation_exception = $ex;
|
|
|
|
}
|
|
|
|
} else {
|
2015-11-03 05:38:06 -08:00
|
|
|
if ($this->getIsCreate()) {
|
Implement a basic version of ApplicationEditor in Paste
Summary:
Ref T9132. Ref T4768. This is a rough v0 of ApplicationEditor, which replaces the edit workflow in Paste.
This mostly looks and works like ApplicationSearch, and is heavily modeled on it.
Roughly, we define a set of editable fields and the ApplicationEditor stuff builds everything else.
This has no functional changes, except:
- I removed "Fork Paste" since I don't think it's particularly useful now that pastes are editable. We could restore it if users miss it.
- Subscribers are now editable.
- Form field order is a little goofy (this will be fixed in a future diff).
- Subscribers and projects are now race-resistant.
The race-resistance works like this: instead of submitting just the new value ("subscribers=apple, dog") and doing a set operation ("set subscribers = apple, dog"), we submit the old and new values ("original=apple" + "new=apple, dog") then apply the user's changes as an add + remove ("add=dog", "remove=<none>"). This means that two users who do "Edit Paste" at around the same time and each add or remove a couple of subscribers won't overwrite each other, unless they actually add or remove the exact same subscribers (in which case their edits legitimately conflict). Previously, the last user to save would win, and whatever was in their field would overwrite the prior state, potentially losing the first user's edits.
Test Plan:
- Created pastes.
- Created pastes via API.
- Edited pastes.
- Edited every field.
- Opened a paste in two windows and did project/subscriber edits in each, saved in arbitrary order, had edits respected.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T4768, T9132
Differential Revision: https://secure.phabricator.com/D14390
2015-11-02 18:58:32 -08:00
|
|
|
foreach ($fields as $field) {
|
|
|
|
$field->readValueFromRequest($request);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
foreach ($fields as $field) {
|
|
|
|
$field->readValueFromObject($object);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$box = id(new PHUIObjectBoxView())
|
|
|
|
->setUser($viewer);
|
|
|
|
|
2015-11-03 05:38:06 -08:00
|
|
|
$crumbs = $this->buildCrumbs($object, $final = true);
|
Implement a basic version of ApplicationEditor in Paste
Summary:
Ref T9132. Ref T4768. This is a rough v0 of ApplicationEditor, which replaces the edit workflow in Paste.
This mostly looks and works like ApplicationSearch, and is heavily modeled on it.
Roughly, we define a set of editable fields and the ApplicationEditor stuff builds everything else.
This has no functional changes, except:
- I removed "Fork Paste" since I don't think it's particularly useful now that pastes are editable. We could restore it if users miss it.
- Subscribers are now editable.
- Form field order is a little goofy (this will be fixed in a future diff).
- Subscribers and projects are now race-resistant.
The race-resistance works like this: instead of submitting just the new value ("subscribers=apple, dog") and doing a set operation ("set subscribers = apple, dog"), we submit the old and new values ("original=apple" + "new=apple, dog") then apply the user's changes as an add + remove ("add=dog", "remove=<none>"). This means that two users who do "Edit Paste" at around the same time and each add or remove a couple of subscribers won't overwrite each other, unless they actually add or remove the exact same subscribers (in which case their edits legitimately conflict). Previously, the last user to save would win, and whatever was in their field would overwrite the prior state, potentially losing the first user's edits.
Test Plan:
- Created pastes.
- Created pastes via API.
- Edited pastes.
- Edited every field.
- Opened a paste in two windows and did project/subscriber edits in each, saved in arbitrary order, had edits respected.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T4768, T9132
Differential Revision: https://secure.phabricator.com/D14390
2015-11-02 18:58:32 -08:00
|
|
|
|
2015-11-03 05:38:06 -08:00
|
|
|
if ($this->getIsCreate()) {
|
Implement a basic version of ApplicationEditor in Paste
Summary:
Ref T9132. Ref T4768. This is a rough v0 of ApplicationEditor, which replaces the edit workflow in Paste.
This mostly looks and works like ApplicationSearch, and is heavily modeled on it.
Roughly, we define a set of editable fields and the ApplicationEditor stuff builds everything else.
This has no functional changes, except:
- I removed "Fork Paste" since I don't think it's particularly useful now that pastes are editable. We could restore it if users miss it.
- Subscribers are now editable.
- Form field order is a little goofy (this will be fixed in a future diff).
- Subscribers and projects are now race-resistant.
The race-resistance works like this: instead of submitting just the new value ("subscribers=apple, dog") and doing a set operation ("set subscribers = apple, dog"), we submit the old and new values ("original=apple" + "new=apple, dog") then apply the user's changes as an add + remove ("add=dog", "remove=<none>"). This means that two users who do "Edit Paste" at around the same time and each add or remove a couple of subscribers won't overwrite each other, unless they actually add or remove the exact same subscribers (in which case their edits legitimately conflict). Previously, the last user to save would win, and whatever was in their field would overwrite the prior state, potentially losing the first user's edits.
Test Plan:
- Created pastes.
- Created pastes via API.
- Edited pastes.
- Edited every field.
- Opened a paste in two windows and did project/subscriber edits in each, saved in arbitrary order, had edits respected.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T4768, T9132
Differential Revision: https://secure.phabricator.com/D14390
2015-11-02 18:58:32 -08:00
|
|
|
$header_text = $this->getObjectCreateTitleText($object);
|
|
|
|
|
|
|
|
$cancel_uri = $this->getObjectCreateCancelURI($object);
|
|
|
|
$submit_button = $this->getObjectCreateButtonText($object);
|
|
|
|
} else {
|
|
|
|
$header_text = $this->getObjectEditTitleText($object);
|
|
|
|
|
|
|
|
$cancel_uri = $this->getObjectEditCancelURI($object);
|
|
|
|
$submit_button = $this->getObjectEditButtonText($object);
|
|
|
|
}
|
|
|
|
|
2015-11-03 05:38:06 -08:00
|
|
|
$header = id(new PHUIHeaderView())
|
|
|
|
->setHeader($header_text);
|
|
|
|
|
|
|
|
$action_button = $this->buildEditFormActionButton($object);
|
|
|
|
|
|
|
|
$header->addActionLink($action_button);
|
|
|
|
|
|
|
|
$box->setHeader($header);
|
Implement a basic version of ApplicationEditor in Paste
Summary:
Ref T9132. Ref T4768. This is a rough v0 of ApplicationEditor, which replaces the edit workflow in Paste.
This mostly looks and works like ApplicationSearch, and is heavily modeled on it.
Roughly, we define a set of editable fields and the ApplicationEditor stuff builds everything else.
This has no functional changes, except:
- I removed "Fork Paste" since I don't think it's particularly useful now that pastes are editable. We could restore it if users miss it.
- Subscribers are now editable.
- Form field order is a little goofy (this will be fixed in a future diff).
- Subscribers and projects are now race-resistant.
The race-resistance works like this: instead of submitting just the new value ("subscribers=apple, dog") and doing a set operation ("set subscribers = apple, dog"), we submit the old and new values ("original=apple" + "new=apple, dog") then apply the user's changes as an add + remove ("add=dog", "remove=<none>"). This means that two users who do "Edit Paste" at around the same time and each add or remove a couple of subscribers won't overwrite each other, unless they actually add or remove the exact same subscribers (in which case their edits legitimately conflict). Previously, the last user to save would win, and whatever was in their field would overwrite the prior state, potentially losing the first user's edits.
Test Plan:
- Created pastes.
- Created pastes via API.
- Edited pastes.
- Edited every field.
- Opened a paste in two windows and did project/subscriber edits in each, saved in arbitrary order, had edits respected.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T4768, T9132
Differential Revision: https://secure.phabricator.com/D14390
2015-11-02 18:58:32 -08:00
|
|
|
|
|
|
|
$form = id(new AphrontFormView())
|
|
|
|
->setUser($viewer);
|
|
|
|
|
|
|
|
foreach ($fields as $field) {
|
|
|
|
$field->appendToForm($form);
|
|
|
|
}
|
|
|
|
|
|
|
|
$form->appendControl(
|
|
|
|
id(new AphrontFormSubmitControl())
|
|
|
|
->addCancelButton($cancel_uri)
|
|
|
|
->setValue($submit_button));
|
|
|
|
|
|
|
|
$box->appendChild($form);
|
|
|
|
|
|
|
|
if ($validation_exception) {
|
|
|
|
$box->setValidationException($validation_exception);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $controller->newPage()
|
|
|
|
->setTitle($header_text)
|
|
|
|
->setCrumbs($crumbs)
|
|
|
|
->appendChild($box);
|
|
|
|
}
|
|
|
|
|
2015-11-03 05:38:06 -08:00
|
|
|
private function buildParametersResponse($object, array $fields) {
|
|
|
|
$controller = $this->getController();
|
|
|
|
$viewer = $this->getViewer();
|
|
|
|
$request = $controller->getRequest();
|
|
|
|
|
|
|
|
$crumbs = $this->buildCrumbs($object);
|
|
|
|
$crumbs->addTextCrumb(pht('HTTP Parameters'));
|
|
|
|
|
|
|
|
$header = id(new PHUIHeaderView())
|
|
|
|
->setHeader(
|
|
|
|
pht(
|
|
|
|
'HTTP Parameters: %s',
|
|
|
|
$this->getObjectCreateShortText($object)));
|
|
|
|
|
|
|
|
// TODO: Upgrade to DocumentViewPro.
|
|
|
|
|
|
|
|
$document = id(new PHUIDocumentView())
|
|
|
|
->setUser($viewer)
|
|
|
|
->setHeader($header);
|
|
|
|
|
|
|
|
$document->appendChild(
|
|
|
|
id(new PhabricatorApplicationEditHTTPParameterHelpView())
|
|
|
|
->setUser($viewer)
|
|
|
|
->setFields($fields));
|
|
|
|
|
|
|
|
return $controller->newPage()
|
|
|
|
->setTitle(pht('HTTP Parameters'))
|
|
|
|
->setCrumbs($crumbs)
|
|
|
|
->appendChild($document);
|
|
|
|
}
|
|
|
|
|
|
|
|
private function buildCrumbs($object, $final = false) {
|
|
|
|
$controller = $this->getcontroller();
|
|
|
|
|
|
|
|
$crumbs = $controller->buildApplicationCrumbsForEditEngine();
|
|
|
|
if ($this->getIsCreate()) {
|
|
|
|
$create_text = $this->getObjectCreateShortText($object);
|
|
|
|
if ($final) {
|
|
|
|
$crumbs->addTextCrumb($create_text);
|
|
|
|
} else {
|
|
|
|
$edit_uri = $this->getEditURI($object);
|
|
|
|
$crumbs->addTextCrumb($create_text, $edit_uri);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$crumbs->addTextCrumb(
|
|
|
|
$this->getObjectEditShortText($object),
|
|
|
|
$this->getObjectViewURI($object));
|
|
|
|
|
|
|
|
$edit_text = pht('Edit');
|
|
|
|
if ($final) {
|
|
|
|
$crumbs->addTextCrumb($edit_text);
|
|
|
|
} else {
|
|
|
|
$edit_uri = $this->getEditURI($object);
|
|
|
|
$crumbs->addTextCrumb($edit_text, $edit_uri);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $crumbs;
|
|
|
|
}
|
|
|
|
|
|
|
|
private function buildEditFormActionButton($object) {
|
|
|
|
$viewer = $this->getViewer();
|
|
|
|
|
|
|
|
$action_view = id(new PhabricatorActionListView())
|
|
|
|
->setUser($viewer);
|
|
|
|
|
|
|
|
foreach ($this->buildEditFormActions($object) as $action) {
|
|
|
|
$action_view->addAction($action);
|
|
|
|
}
|
|
|
|
|
|
|
|
$action_button = id(new PHUIButtonView())
|
|
|
|
->setTag('a')
|
|
|
|
->setText(pht('Actions'))
|
|
|
|
->setHref('#')
|
|
|
|
->setIconFont('fa-bars')
|
|
|
|
->setDropdownMenu($action_view);
|
|
|
|
|
|
|
|
return $action_button;
|
|
|
|
}
|
|
|
|
|
|
|
|
private function buildEditFormActions($object) {
|
|
|
|
$actions = array();
|
|
|
|
|
|
|
|
$actions[] = id(new PhabricatorActionView())
|
|
|
|
->setName(pht('Show HTTP Parameters'))
|
|
|
|
->setIcon('fa-crosshairs')
|
|
|
|
->setHref($this->getEditURI($object, 'parameters/'));
|
|
|
|
|
|
|
|
return $actions;
|
|
|
|
}
|
Implement a basic version of ApplicationEditor in Paste
Summary:
Ref T9132. Ref T4768. This is a rough v0 of ApplicationEditor, which replaces the edit workflow in Paste.
This mostly looks and works like ApplicationSearch, and is heavily modeled on it.
Roughly, we define a set of editable fields and the ApplicationEditor stuff builds everything else.
This has no functional changes, except:
- I removed "Fork Paste" since I don't think it's particularly useful now that pastes are editable. We could restore it if users miss it.
- Subscribers are now editable.
- Form field order is a little goofy (this will be fixed in a future diff).
- Subscribers and projects are now race-resistant.
The race-resistance works like this: instead of submitting just the new value ("subscribers=apple, dog") and doing a set operation ("set subscribers = apple, dog"), we submit the old and new values ("original=apple" + "new=apple, dog") then apply the user's changes as an add + remove ("add=dog", "remove=<none>"). This means that two users who do "Edit Paste" at around the same time and each add or remove a couple of subscribers won't overwrite each other, unless they actually add or remove the exact same subscribers (in which case their edits legitimately conflict). Previously, the last user to save would win, and whatever was in their field would overwrite the prior state, potentially losing the first user's edits.
Test Plan:
- Created pastes.
- Created pastes via API.
- Edited pastes.
- Edited every field.
- Opened a paste in two windows and did project/subscriber edits in each, saved in arbitrary order, had edits respected.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T4768, T9132
Differential Revision: https://secure.phabricator.com/D14390
2015-11-02 18:58:32 -08:00
|
|
|
|
|
|
|
}
|