mirror of
https://we.phorge.it/source/phorge.git
synced 2025-04-12 12:28:36 +02:00
Summary: Basically straight from D7391. The differences are basically: - Policy stuff is all application-scope instead of global-scope. - Made a few strings a little nicer. - Deleted a bit of dead code. - Added a big "THIS DOESN'T WORK YET" warning. Test Plan: See screenshots. Reviewers: hach-que, btrahan Reviewed By: hach-que CC: aran Maniphest Tasks: T2230 Differential Revision: https://secure.phabricator.com/D7416
226 lines
6.2 KiB
PHP
226 lines
6.2 KiB
PHP
<?php
|
|
|
|
final class AphrontFormPolicyControl extends AphrontFormControl {
|
|
|
|
private $object;
|
|
private $capability;
|
|
private $policies;
|
|
|
|
public function setPolicyObject(PhabricatorPolicyInterface $object) {
|
|
$this->object = $object;
|
|
return $this;
|
|
}
|
|
|
|
public function setPolicies(array $policies) {
|
|
assert_instances_of($policies, 'PhabricatorPolicy');
|
|
$this->policies = $policies;
|
|
return $this;
|
|
}
|
|
|
|
public function setCapability($capability) {
|
|
$this->capability = $capability;
|
|
|
|
$labels = array(
|
|
PhabricatorPolicyCapability::CAN_VIEW => pht('Visible To'),
|
|
PhabricatorPolicyCapability::CAN_EDIT => pht('Editable By'),
|
|
PhabricatorPolicyCapability::CAN_JOIN => pht('Joinable By'),
|
|
);
|
|
|
|
if (isset($labels[$capability])) {
|
|
$label = $labels[$capability];
|
|
} else {
|
|
$capobj = PhabricatorPolicyCapability::getCapabilityByKey($capability);
|
|
if ($capobj) {
|
|
$label = $capobj->getCapabilityName();
|
|
} else {
|
|
$label = pht('Capability "%s"', $capability);
|
|
}
|
|
}
|
|
|
|
$this->setLabel($label);
|
|
|
|
return $this;
|
|
}
|
|
|
|
protected function getCustomControlClass() {
|
|
return 'aphront-form-control-policy';
|
|
}
|
|
|
|
protected function getOptions() {
|
|
$capability = $this->capability;
|
|
|
|
$options = array();
|
|
foreach ($this->policies as $policy) {
|
|
if ($policy->getPHID() == PhabricatorPolicies::POLICY_PUBLIC) {
|
|
// Never expose "Public" for capabilities which don't support it.
|
|
$capobj = PhabricatorPolicyCapability::getCapabilityByKey($capability);
|
|
if (!$capobj || !$capobj->shouldAllowPublicPolicySetting()) {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
$options[$policy->getType()][$policy->getPHID()] = array(
|
|
'name' => phutil_utf8_shorten($policy->getName(), 28),
|
|
'full' => $policy->getName(),
|
|
'icon' => $policy->getIcon(),
|
|
);
|
|
}
|
|
|
|
// If we were passed several custom policy options, throw away the ones
|
|
// which aren't the value for this capability. For example, an object might
|
|
// have a custom view pollicy and a custom edit policy. When we render
|
|
// the selector for "Can View", we don't want to show the "Can Edit"
|
|
// custom policy -- if we did, the menu would look like this:
|
|
//
|
|
// Custom
|
|
// Custom Policy
|
|
// Custom Policy
|
|
//
|
|
// ...where one is the "view" custom policy, and one is the "edit" custom
|
|
// policy.
|
|
|
|
$type_custom = PhabricatorPolicyType::TYPE_CUSTOM;
|
|
if (!empty($options[$type_custom])) {
|
|
$options[$type_custom] = array_select_keys(
|
|
$options[$type_custom],
|
|
array($this->getValue()));
|
|
}
|
|
|
|
// If there aren't any custom policies, add a placeholder policy so we
|
|
// render a menu item. This allows the user to switch to a custom policy.
|
|
|
|
if (empty($options[$type_custom])) {
|
|
$placeholder = new PhabricatorPolicy();
|
|
$placeholder->setName(pht('Custom Policy...'));
|
|
$options[$type_custom][$this->getCustomPolicyPlaceholder()] = array(
|
|
'name' => $placeholder->getName(),
|
|
'full' => $placeholder->getName(),
|
|
'icon' => $placeholder->getIcon(),
|
|
);
|
|
}
|
|
|
|
$options = array_select_keys(
|
|
$options,
|
|
array(
|
|
PhabricatorPolicyType::TYPE_GLOBAL,
|
|
PhabricatorPolicyType::TYPE_CUSTOM,
|
|
PhabricatorPolicyType::TYPE_PROJECT,
|
|
));
|
|
|
|
return $options;
|
|
}
|
|
|
|
protected function renderInput() {
|
|
if (!$this->object) {
|
|
throw new Exception(pht("Call setPolicyObject() before rendering!"));
|
|
}
|
|
if (!$this->capability) {
|
|
throw new Exception(pht("Call setCapability() before rendering!"));
|
|
}
|
|
|
|
$policy = $this->object->getPolicy($this->capability);
|
|
if (!$policy) {
|
|
// TODO: Make this configurable.
|
|
$policy = PhabricatorPolicies::POLICY_USER;
|
|
}
|
|
$this->setValue($policy);
|
|
|
|
|
|
$control_id = celerity_generate_unique_node_id();
|
|
$input_id = celerity_generate_unique_node_id();
|
|
|
|
$caret = phutil_tag(
|
|
'span',
|
|
array(
|
|
'class' => 'caret',
|
|
));
|
|
|
|
$input = phutil_tag(
|
|
'input',
|
|
array(
|
|
'type' => 'hidden',
|
|
'id' => $input_id,
|
|
'name' => $this->getName(),
|
|
'value' => $this->getValue(),
|
|
));
|
|
|
|
$options = $this->getOptions();
|
|
|
|
$order = array();
|
|
$labels = array();
|
|
foreach ($options as $key => $values) {
|
|
$order[$key] = array_keys($values);
|
|
$labels[$key] = PhabricatorPolicyType::getPolicyTypeName($key);
|
|
}
|
|
|
|
$flat_options = array_mergev($options);
|
|
|
|
$icons = array();
|
|
foreach (igroup($flat_options, 'icon') as $icon => $ignored) {
|
|
$icons[$icon] = id(new PHUIIconView())
|
|
->setSpriteSheet(PHUIIconView::SPRITE_STATUS)
|
|
->setSpriteIcon($icon);
|
|
}
|
|
|
|
|
|
Javelin::initBehavior(
|
|
'policy-control',
|
|
array(
|
|
'controlID' => $control_id,
|
|
'inputID' => $input_id,
|
|
'options' => $flat_options,
|
|
'groups' => array_keys($options),
|
|
'order' => $order,
|
|
'icons' => $icons,
|
|
'labels' => $labels,
|
|
'value' => $this->getValue(),
|
|
'customPlaceholder' => $this->getCustomPolicyPlaceholder(),
|
|
));
|
|
|
|
$selected = $flat_options[$this->getValue()];
|
|
|
|
return phutil_tag(
|
|
'div',
|
|
array(
|
|
),
|
|
array(
|
|
javelin_tag(
|
|
'a',
|
|
array(
|
|
'class' => 'grey button dropdown has-icon policy-control',
|
|
'href' => '#',
|
|
'mustcapture' => true,
|
|
'sigil' => 'policy-control',
|
|
'id' => $control_id,
|
|
),
|
|
array(
|
|
$caret,
|
|
javelin_tag(
|
|
'span',
|
|
array(
|
|
'sigil' => 'policy-label',
|
|
'class' => 'phui-button-text',
|
|
),
|
|
array(
|
|
$icons[$selected['icon']],
|
|
$selected['name'],
|
|
)),
|
|
)),
|
|
$input,
|
|
));
|
|
|
|
return AphrontFormSelectControl::renderSelectTag(
|
|
$this->getValue(),
|
|
$this->getOptions(),
|
|
array(
|
|
'name' => $this->getName(),
|
|
'disabled' => $this->getDisabled() ? 'disabled' : null,
|
|
'id' => $this->getID(),
|
|
));
|
|
}
|
|
|
|
private function getCustomPolicyPlaceholder() {
|
|
return 'custom:placeholder';
|
|
}
|
|
|
|
}
|