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-03 03:58:32 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
abstract class PhabricatorEditField extends Phobject {
|
|
|
|
|
|
|
|
private $key;
|
|
|
|
private $viewer;
|
|
|
|
private $label;
|
|
|
|
private $aliases = array();
|
|
|
|
private $value;
|
|
|
|
private $hasValue = false;
|
|
|
|
private $object;
|
|
|
|
private $transactionType;
|
|
|
|
private $metadata = array();
|
2015-11-03 14:38:06 +01:00
|
|
|
private $description;
|
2015-11-03 17:45:00 +01:00
|
|
|
private $editTypeKey;
|
Allow ApplicationEditor forms to be reconfigured
Summary:
Ref T9132. This diff doesn't do anything interesting, it just lays the groundwork for more interesting future diffs.
Broadly, the idea here is to let you create multiple views of each edit form. For example, we might create several different "Create Task" forms, like:
- "New Bug Report"
- "New Feature Request"
These would be views of the "Create Task" form, but with various adjustments:
- A form might have additional instructions ("how to file a good bug report").
- A form might have prefilled values for some fields (like particular projects, subscribers, or policies).
- A form might have some fields locked (so they can not be edited) or hidden.
- A form might have a different field order.
- A form might have a limited visibility policy, so only some users can access it.
This diff adds a new storage object (`EditEngineConfiguration`) to keep track of all those customizations and represent "a form which has been configured to look and work a certain way".
This doesn't let these configurations do anything useful/interesting, and you can't access them directly yet, it's just all the boring plumbing to enable more interesting behavior in the future.
Test Plan:
ApplicationEditor forms now let you manage available forms and edit the current form:
{F959025}
There's a new (bare bones) list of all available engines:
{F959030}
And if you jump into an engine, you can see all the forms for it:
{F959038}
The actual form configurations have standard detail/edit pages. The edit pages are themselves driven by ApplicationEditor, of course, so you can edit the form for editing forms.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T9132
Differential Revision: https://secure.phabricator.com/D14453
2015-11-04 21:52:52 +01:00
|
|
|
private $isLocked;
|
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-03 03:58:32 +01:00
|
|
|
|
|
|
|
public function setKey($key) {
|
|
|
|
$this->key = $key;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getKey() {
|
|
|
|
return $this->key;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setLabel($label) {
|
|
|
|
$this->label = $label;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getLabel() {
|
|
|
|
return $this->label;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setViewer(PhabricatorUser $viewer) {
|
|
|
|
$this->viewer = $viewer;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getViewer() {
|
|
|
|
return $this->viewer;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setAliases(array $aliases) {
|
|
|
|
$this->aliases = $aliases;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getAliases() {
|
|
|
|
return $this->aliases;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setObject($object) {
|
|
|
|
$this->object = $object;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getObject() {
|
|
|
|
return $this->object;
|
|
|
|
}
|
|
|
|
|
2015-11-03 14:38:06 +01:00
|
|
|
public function setDescription($description) {
|
|
|
|
$this->description = $description;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getDescription() {
|
|
|
|
return $this->description;
|
|
|
|
}
|
|
|
|
|
Allow ApplicationEditor forms to be reconfigured
Summary:
Ref T9132. This diff doesn't do anything interesting, it just lays the groundwork for more interesting future diffs.
Broadly, the idea here is to let you create multiple views of each edit form. For example, we might create several different "Create Task" forms, like:
- "New Bug Report"
- "New Feature Request"
These would be views of the "Create Task" form, but with various adjustments:
- A form might have additional instructions ("how to file a good bug report").
- A form might have prefilled values for some fields (like particular projects, subscribers, or policies).
- A form might have some fields locked (so they can not be edited) or hidden.
- A form might have a different field order.
- A form might have a limited visibility policy, so only some users can access it.
This diff adds a new storage object (`EditEngineConfiguration`) to keep track of all those customizations and represent "a form which has been configured to look and work a certain way".
This doesn't let these configurations do anything useful/interesting, and you can't access them directly yet, it's just all the boring plumbing to enable more interesting behavior in the future.
Test Plan:
ApplicationEditor forms now let you manage available forms and edit the current form:
{F959025}
There's a new (bare bones) list of all available engines:
{F959030}
And if you jump into an engine, you can see all the forms for it:
{F959038}
The actual form configurations have standard detail/edit pages. The edit pages are themselves driven by ApplicationEditor, of course, so you can edit the form for editing forms.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T9132
Differential Revision: https://secure.phabricator.com/D14453
2015-11-04 21:52:52 +01:00
|
|
|
public function setIsLocked($is_locked) {
|
|
|
|
$this->isLocked = $is_locked;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getIsLocked() {
|
|
|
|
return $this->isLocked;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function newControl() {
|
|
|
|
throw new PhutilMethodNotImplementedException();
|
|
|
|
}
|
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-03 03:58:32 +01:00
|
|
|
|
|
|
|
protected function renderControl() {
|
|
|
|
$control = $this->newControl();
|
|
|
|
if ($control === null) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
$control
|
|
|
|
->setValue($this->getValueForControl())
|
|
|
|
->setName($this->getKey());
|
|
|
|
|
|
|
|
if (!$control->getLabel()) {
|
|
|
|
$control->setLabel($this->getLabel());
|
|
|
|
}
|
|
|
|
|
Allow ApplicationEditor forms to be reconfigured
Summary:
Ref T9132. This diff doesn't do anything interesting, it just lays the groundwork for more interesting future diffs.
Broadly, the idea here is to let you create multiple views of each edit form. For example, we might create several different "Create Task" forms, like:
- "New Bug Report"
- "New Feature Request"
These would be views of the "Create Task" form, but with various adjustments:
- A form might have additional instructions ("how to file a good bug report").
- A form might have prefilled values for some fields (like particular projects, subscribers, or policies).
- A form might have some fields locked (so they can not be edited) or hidden.
- A form might have a different field order.
- A form might have a limited visibility policy, so only some users can access it.
This diff adds a new storage object (`EditEngineConfiguration`) to keep track of all those customizations and represent "a form which has been configured to look and work a certain way".
This doesn't let these configurations do anything useful/interesting, and you can't access them directly yet, it's just all the boring plumbing to enable more interesting behavior in the future.
Test Plan:
ApplicationEditor forms now let you manage available forms and edit the current form:
{F959025}
There's a new (bare bones) list of all available engines:
{F959030}
And if you jump into an engine, you can see all the forms for it:
{F959038}
The actual form configurations have standard detail/edit pages. The edit pages are themselves driven by ApplicationEditor, of course, so you can edit the form for editing forms.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T9132
Differential Revision: https://secure.phabricator.com/D14453
2015-11-04 21:52:52 +01:00
|
|
|
if ($this->getIsLocked()) {
|
|
|
|
$control->setDisabled(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-03 03:58:32 +01:00
|
|
|
return $control;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function appendToForm(AphrontFormView $form) {
|
|
|
|
$control = $this->renderControl();
|
|
|
|
if ($control !== null) {
|
|
|
|
$form->appendControl($control);
|
|
|
|
}
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function getValueForControl() {
|
|
|
|
return $this->getValue();
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function getValue() {
|
|
|
|
return $this->value;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setValue($value) {
|
|
|
|
$this->hasValue = true;
|
|
|
|
$this->value = $value;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function generateTransaction(
|
|
|
|
PhabricatorApplicationTransaction $xaction) {
|
|
|
|
|
|
|
|
$xaction
|
|
|
|
->setTransactionType($this->getTransactionType())
|
|
|
|
->setNewValue($this->getValueForTransaction());
|
|
|
|
|
|
|
|
foreach ($this->metadata as $key => $value) {
|
|
|
|
$xaction->setMetadataValue($key, $value);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $xaction;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setMetadataValue($key, $value) {
|
|
|
|
$this->metadata[$key] = $value;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function getValueForTransaction() {
|
|
|
|
return $this->getValue();
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getTransactionType() {
|
|
|
|
if (!$this->transactionType) {
|
|
|
|
throw new PhutilInvalidStateException('setTransactionType');
|
|
|
|
}
|
|
|
|
return $this->transactionType;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setTransactionType($type) {
|
|
|
|
$this->transactionType = $type;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function readValueFromRequest(AphrontRequest $request) {
|
|
|
|
$check = array_merge(array($this->getKey()), $this->getAliases());
|
|
|
|
foreach ($check as $key) {
|
|
|
|
if (!$this->getValueExistsInRequest($request, $key)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->value = $this->getValueFromRequest($request, $key);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->readValueFromObject($this->getObject());
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function readValueFromObject($object) {
|
|
|
|
$this->value = $this->getValueFromObject($object);
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
Allow ApplicationEditor forms to be reconfigured
Summary:
Ref T9132. This diff doesn't do anything interesting, it just lays the groundwork for more interesting future diffs.
Broadly, the idea here is to let you create multiple views of each edit form. For example, we might create several different "Create Task" forms, like:
- "New Bug Report"
- "New Feature Request"
These would be views of the "Create Task" form, but with various adjustments:
- A form might have additional instructions ("how to file a good bug report").
- A form might have prefilled values for some fields (like particular projects, subscribers, or policies).
- A form might have some fields locked (so they can not be edited) or hidden.
- A form might have a different field order.
- A form might have a limited visibility policy, so only some users can access it.
This diff adds a new storage object (`EditEngineConfiguration`) to keep track of all those customizations and represent "a form which has been configured to look and work a certain way".
This doesn't let these configurations do anything useful/interesting, and you can't access them directly yet, it's just all the boring plumbing to enable more interesting behavior in the future.
Test Plan:
ApplicationEditor forms now let you manage available forms and edit the current form:
{F959025}
There's a new (bare bones) list of all available engines:
{F959030}
And if you jump into an engine, you can see all the forms for it:
{F959038}
The actual form configurations have standard detail/edit pages. The edit pages are themselves driven by ApplicationEditor, of course, so you can edit the form for editing forms.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T9132
Differential Revision: https://secure.phabricator.com/D14453
2015-11-04 21:52:52 +01:00
|
|
|
public function readDefaultValueFromConfiguration($value) {
|
|
|
|
$this->value = $this->getDefaultValueFromConfiguration($value);
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function getDefaultValueFromConfiguration($value) {
|
|
|
|
return $value;
|
|
|
|
}
|
|
|
|
|
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-03 03:58:32 +01:00
|
|
|
protected function getValueFromObject($object) {
|
|
|
|
if ($this->hasValue) {
|
|
|
|
return $this->value;
|
|
|
|
} else {
|
|
|
|
return $this->getDefaultValue();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function getValueExistsInRequest(AphrontRequest $request, $key) {
|
|
|
|
return $this->getValueExistsInSubmit($request, $key);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function getValueFromRequest(AphrontRequest $request, $key) {
|
|
|
|
return $this->getValueFromSubmit($request, $key);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function readValueFromSubmit(AphrontRequest $request) {
|
|
|
|
$key = $this->getKey();
|
|
|
|
if ($this->getValueExistsInSubmit($request, $key)) {
|
|
|
|
$value = $this->getValueFromSubmit($request, $key);
|
|
|
|
} else {
|
|
|
|
$value = $this->getDefaultValue();
|
|
|
|
}
|
|
|
|
$this->value = $value;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function getValueExistsInSubmit(AphrontRequest $request, $key) {
|
2015-11-04 14:05:10 +01:00
|
|
|
return $this->getHTTPParameterType()->getExists($request, $key);
|
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-03 03:58:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
protected function getValueFromSubmit(AphrontRequest $request, $key) {
|
2015-11-04 14:05:10 +01:00
|
|
|
return $this->getHTTPParameterType()->getValue($request, $key);
|
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-03 03:58:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
protected function getDefaultValue() {
|
2015-11-04 14:05:10 +01:00
|
|
|
return $this->getHTTPParameterType()->getDefaultValue();
|
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-03 03:58:32 +01:00
|
|
|
}
|
|
|
|
|
2015-11-04 14:05:10 +01:00
|
|
|
final public function getHTTPParameterType() {
|
|
|
|
$type = $this->newHTTPParameterType();
|
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-03 03:58:32 +01:00
|
|
|
|
2015-11-04 14:05:10 +01:00
|
|
|
if ($type) {
|
|
|
|
$type->setViewer($this->getViewer());
|
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-03 03:58:32 +01:00
|
|
|
}
|
|
|
|
|
2015-11-04 14:05:10 +01:00
|
|
|
return $type;
|
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-03 03:58:32 +01:00
|
|
|
}
|
|
|
|
|
2015-11-04 14:05:10 +01:00
|
|
|
protected function newHTTPParameterType() {
|
|
|
|
return new AphrontStringHTTPParameterType();
|
2015-11-03 14:38:06 +01:00
|
|
|
}
|
|
|
|
|
2015-11-03 17:45:00 +01:00
|
|
|
public function setEditTypeKey($edit_type_key) {
|
|
|
|
$this->editTypeKey = $edit_type_key;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getEditTypeKey() {
|
|
|
|
if ($this->editTypeKey === null) {
|
|
|
|
return $this->getKey();
|
|
|
|
}
|
|
|
|
return $this->editTypeKey;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getEditTransactionTypes() {
|
|
|
|
$transaction_type = $this->getTransactionType();
|
|
|
|
$type_key = $this->getEditTypeKey();
|
|
|
|
|
|
|
|
// TODO: This is a pretty big pile of hard-coded hacks for now.
|
|
|
|
|
|
|
|
$edge_types = array(
|
|
|
|
PhabricatorTransactions::TYPE_EDGE => array(
|
|
|
|
'+' => pht('Add projects.'),
|
|
|
|
'-' => pht('Remove projects.'),
|
|
|
|
'=' => pht('Set associated projects, overwriting current value.'),
|
|
|
|
),
|
|
|
|
PhabricatorTransactions::TYPE_SUBSCRIBERS => array(
|
|
|
|
'+' => pht('Add subscribers.'),
|
|
|
|
'-' => pht('Remove subscribers.'),
|
|
|
|
'=' => pht('Set subscribers, overwriting current value.'),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
|
|
|
|
if (isset($edge_types[$transaction_type])) {
|
|
|
|
$base = id(new PhabricatorEdgeEditType())
|
|
|
|
->setTransactionType($transaction_type)
|
|
|
|
->setMetadata($this->metadata);
|
|
|
|
|
|
|
|
$strings = $edge_types[$transaction_type];
|
|
|
|
|
|
|
|
$add = id(clone $base)
|
|
|
|
->setEditType($type_key.'.add')
|
|
|
|
->setEdgeOperation('+')
|
|
|
|
->setDescription($strings['+'])
|
|
|
|
->setValueDescription(pht('List of PHIDs to add.'));
|
|
|
|
$rem = id(clone $base)
|
|
|
|
->setEditType($type_key.'.remove')
|
|
|
|
->setEdgeOperation('-')
|
|
|
|
->setDescription($strings['-'])
|
|
|
|
->setValueDescription(pht('List of PHIDs to remove.'));
|
|
|
|
$set = id(clone $base)
|
|
|
|
->setEditType($type_key.'.set')
|
|
|
|
->setEdgeOperation('=')
|
|
|
|
->setDescription($strings['='])
|
|
|
|
->setValueDescription(pht('List of PHIDs to set.'));
|
|
|
|
|
|
|
|
return array(
|
|
|
|
$add,
|
|
|
|
$rem,
|
|
|
|
$set,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
return array(
|
|
|
|
id(new PhabricatorSimpleEditType())
|
|
|
|
->setEditType($type_key)
|
|
|
|
->setTransactionType($transaction_type)
|
2015-11-04 14:05:10 +01:00
|
|
|
->setValueType($this->getHTTPParameterType()->getTypeName())
|
2015-11-03 17:45:00 +01:00
|
|
|
->setDescription($this->getDescription())
|
|
|
|
->setMetadata($this->metadata),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
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-03 03:58:32 +01:00
|
|
|
}
|