mirror of
https://we.phorge.it/source/phorge.git
synced 2025-02-16 08:48:38 +01:00
Summary: WMF ran into this after their update. Here's the setup: - When you enable Spaces, we leave all existing objects set to `null`, which means "these belong to the default space". This is so we don't have to go update a trillion objects. - New objects get set to the default space explicitly (`PHID-SPCE-...`) but older ones stay with `null`. - If you edit an older object (like a task) from the time before Spaces, //and// the form doesn't have a Visbility/Spaces control, we would incorrectly poplate the value with `null` when the effective value should be the default space PHID. - This caused a "You must choose a space." error in the UI. Instead, populate the control with the effective value instead of the literal database value. This makes the edit go through cleanly. Also add a note about this for future-me. Test Plan: - Disabled "Visibility" control in task edit form. - Edited an old task which had `null` as a `spacePHID` in the database. - Before patch: UI error about selecting a Space. - After patch: edit goes through cleanly. Reviewers: chad, 20after4 Reviewed By: chad, 20after4 Subscribers: 20after4, aklapper Differential Revision: https://secure.phabricator.com/D15306
133 lines
4.3 KiB
PHP
133 lines
4.3 KiB
PHP
<?php
|
|
|
|
final class PhabricatorPolicyEditEngineExtension
|
|
extends PhabricatorEditEngineExtension {
|
|
|
|
const EXTENSIONKEY = 'policy.policy';
|
|
|
|
public function getExtensionPriority() {
|
|
return 250;
|
|
}
|
|
|
|
public function isExtensionEnabled() {
|
|
return true;
|
|
}
|
|
|
|
public function getExtensionName() {
|
|
return pht('Policies');
|
|
}
|
|
|
|
public function supportsObject(
|
|
PhabricatorEditEngine $engine,
|
|
PhabricatorApplicationTransactionInterface $object) {
|
|
return ($object instanceof PhabricatorPolicyInterface);
|
|
}
|
|
|
|
public function buildCustomEditFields(
|
|
PhabricatorEditEngine $engine,
|
|
PhabricatorApplicationTransactionInterface $object) {
|
|
|
|
$viewer = $engine->getViewer();
|
|
|
|
$editor = $object->getApplicationTransactionEditor();
|
|
$types = $editor->getTransactionTypesForObject($object);
|
|
$types = array_fuse($types);
|
|
|
|
$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,
|
|
'label' => pht('View Policy'),
|
|
'description' => pht('Controls who can view the object.'),
|
|
'description.conduit' => pht('Change the view policy of the object.'),
|
|
'edit' => 'view',
|
|
),
|
|
PhabricatorTransactions::TYPE_EDIT_POLICY => array(
|
|
'key' => 'policy.edit',
|
|
'aliases' => array('edit'),
|
|
'capability' => PhabricatorPolicyCapability::CAN_EDIT,
|
|
'label' => pht('Edit Policy'),
|
|
'description' => pht('Controls who can edit the object.'),
|
|
'description.conduit' => pht('Change the edit policy of the object.'),
|
|
'edit' => 'edit',
|
|
),
|
|
PhabricatorTransactions::TYPE_JOIN_POLICY => array(
|
|
'key' => 'policy.join',
|
|
'aliases' => array('join'),
|
|
'capability' => PhabricatorPolicyCapability::CAN_JOIN,
|
|
'label' => pht('Join Policy'),
|
|
'description' => pht('Controls who can join the object.'),
|
|
'description.conduit' => pht('Change the join policy of the object.'),
|
|
'edit' => 'join',
|
|
),
|
|
);
|
|
|
|
$fields = array();
|
|
foreach ($map as $type => $spec) {
|
|
if (empty($types[$type])) {
|
|
continue;
|
|
}
|
|
|
|
$capability = $spec['capability'];
|
|
$key = $spec['key'];
|
|
$aliases = $spec['aliases'];
|
|
$label = $spec['label'];
|
|
$description = $spec['description'];
|
|
$conduit_description = $spec['description.conduit'];
|
|
$edit = $spec['edit'];
|
|
|
|
$policy_field = id(new PhabricatorPolicyEditField())
|
|
->setKey($key)
|
|
->setLabel($label)
|
|
->setAliases($aliases)
|
|
->setIsCopyable(true)
|
|
->setCapability($capability)
|
|
->setPolicies($policies)
|
|
->setTransactionType($type)
|
|
->setEditTypeKey($edit)
|
|
->setDescription($description)
|
|
->setConduitDescription($conduit_description)
|
|
->setConduitTypeDescription(pht('New policy PHID or constant.'))
|
|
->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_phid = PhabricatorSpacesNamespaceQuery::getObjectSpacePHID(
|
|
$object);
|
|
|
|
$space_field = id(new PhabricatorSpaceEditField())
|
|
->setKey('spacePHID')
|
|
->setLabel(pht('Space'))
|
|
->setEditTypeKey('space')
|
|
->setIsCopyable(true)
|
|
->setIsLockable(false)
|
|
->setIsReorderable(false)
|
|
->setAliases(array('space', 'policy.space'))
|
|
->setTransactionType($type_space)
|
|
->setDescription(pht('Select a space for the object.'))
|
|
->setConduitDescription(
|
|
pht('Shift the object between spaces.'))
|
|
->setConduitTypeDescription(pht('New space PHID.'))
|
|
->setValue($space_phid);
|
|
$fields[] = $space_field;
|
|
|
|
$space_field->setPolicyField($policy_field);
|
|
$policy_field->setSpaceField($space_field);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return $fields;
|
|
}
|
|
|
|
}
|