2016-01-12 19:27:39 +01:00
|
|
|
<?php
|
|
|
|
|
2016-01-14 14:59:25 +01:00
|
|
|
abstract class PhabricatorProfilePanelEngine extends Phobject {
|
2016-01-12 19:27:39 +01:00
|
|
|
|
|
|
|
private $viewer;
|
|
|
|
private $profileObject;
|
|
|
|
private $panels;
|
2016-01-13 00:06:43 +01:00
|
|
|
private $controller;
|
2016-01-12 19:27:39 +01:00
|
|
|
|
|
|
|
public function setViewer(PhabricatorUser $viewer) {
|
|
|
|
$this->viewer = $viewer;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getViewer() {
|
|
|
|
return $this->viewer;
|
|
|
|
}
|
|
|
|
|
2016-01-14 14:59:25 +01:00
|
|
|
public function setProfileObject($profile_object) {
|
2016-01-12 19:27:39 +01:00
|
|
|
$this->profileObject = $profile_object;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getProfileObject() {
|
|
|
|
return $this->profileObject;
|
|
|
|
}
|
|
|
|
|
2016-01-13 00:06:43 +01:00
|
|
|
public function setController(PhabricatorController $controller) {
|
|
|
|
$this->controller = $controller;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getController() {
|
|
|
|
return $this->controller;
|
|
|
|
}
|
|
|
|
|
2016-01-14 14:59:25 +01:00
|
|
|
abstract protected function getPanelURI($path);
|
|
|
|
|
2016-01-14 15:47:06 +01:00
|
|
|
protected function isPanelEngineConfigurable() {
|
|
|
|
return PhabricatorEnv::getEnvConfig('phabricator.show-prototypes');
|
|
|
|
}
|
|
|
|
|
2016-01-13 00:06:43 +01:00
|
|
|
public function buildResponse() {
|
|
|
|
$controller = $this->getController();
|
|
|
|
|
|
|
|
$viewer = $controller->getViewer();
|
|
|
|
$this->setViewer($viewer);
|
|
|
|
|
|
|
|
$request = $controller->getRequest();
|
|
|
|
|
|
|
|
$panel_action = $request->getURIData('panelAction');
|
2016-01-14 15:47:06 +01:00
|
|
|
|
|
|
|
// If the engine is not configurable, don't respond to any of the editing
|
|
|
|
// or configuration routes.
|
|
|
|
if (!$this->isPanelEngineConfigurable()) {
|
|
|
|
switch ($panel_action) {
|
|
|
|
case 'view':
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return new Aphront404Response();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-13 00:06:43 +01:00
|
|
|
$panel_id = $request->getURIData('panelID');
|
|
|
|
|
|
|
|
$panel_list = $this->loadPanels();
|
|
|
|
|
|
|
|
$selected_panel = null;
|
|
|
|
if (strlen($panel_id)) {
|
|
|
|
$panel_id_int = (int)$panel_id;
|
|
|
|
foreach ($panel_list as $panel) {
|
|
|
|
if ($panel_id_int) {
|
2016-01-13 19:40:31 +01:00
|
|
|
if ((int)$panel->getID() === $panel_id_int) {
|
2016-01-13 00:06:43 +01:00
|
|
|
$selected_panel = $panel;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$builtin_key = $panel->getBuiltinKey();
|
|
|
|
if ($builtin_key === (string)$panel_id) {
|
|
|
|
$selected_panel = $panel;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
switch ($panel_action) {
|
|
|
|
case 'view':
|
|
|
|
case 'info':
|
|
|
|
case 'hide':
|
|
|
|
case 'builtin':
|
|
|
|
if (!$selected_panel) {
|
|
|
|
return new Aphront404Response();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
$navigation = $this->buildNavigation();
|
|
|
|
$navigation->selectFilter('panel.configure');
|
|
|
|
|
|
|
|
$crumbs = $controller->buildApplicationCrumbsForEditEngine();
|
|
|
|
|
|
|
|
switch ($panel_action) {
|
|
|
|
case 'view':
|
|
|
|
$content = $this->buildPanelViewContent($selected_panel);
|
|
|
|
break;
|
|
|
|
case 'configure':
|
|
|
|
$content = $this->buildPanelConfigureContent($panel_list);
|
|
|
|
$crumbs->addTextCrumb(pht('Configure Menu'));
|
|
|
|
break;
|
2016-01-13 18:40:27 +01:00
|
|
|
case 'reorder':
|
|
|
|
$content = $this->buildPanelReorderContent($panel_list);
|
|
|
|
break;
|
2016-01-13 00:06:43 +01:00
|
|
|
case 'new':
|
|
|
|
$panel_key = $request->getURIData('panelKey');
|
|
|
|
$content = $this->buildPanelNewContent($panel_key);
|
|
|
|
break;
|
|
|
|
case 'builtin':
|
|
|
|
$content = $this->buildPanelBuiltinContent($selected_panel);
|
|
|
|
break;
|
2016-01-13 19:40:31 +01:00
|
|
|
case 'hide':
|
|
|
|
$content = $this->buildPanelHideContent($selected_panel);
|
|
|
|
break;
|
2016-01-13 00:06:43 +01:00
|
|
|
case 'edit':
|
|
|
|
$content = $this->buildPanelEditContent();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
throw new Exception(
|
|
|
|
pht(
|
|
|
|
'Unsupported panel action "%s".',
|
|
|
|
$panel_action));
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($content instanceof AphrontResponse) {
|
|
|
|
return $content;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($content instanceof AphrontResponseProducerInterface) {
|
|
|
|
return $content;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $controller->newPage()
|
|
|
|
->setTitle(pht('Profile Stuff'))
|
|
|
|
->setNavigation($navigation)
|
|
|
|
->setCrumbs($crumbs)
|
|
|
|
->appendChild($content);
|
|
|
|
}
|
|
|
|
|
2016-01-12 19:27:39 +01:00
|
|
|
public function buildNavigation() {
|
|
|
|
$nav = id(new AphrontSideNavFilterView())
|
2016-01-14 01:07:04 +01:00
|
|
|
->setIsProfileMenu(true)
|
2016-01-14 14:59:25 +01:00
|
|
|
->setBaseURI(new PhutilURI($this->getPanelURI('')));
|
2016-01-12 19:27:39 +01:00
|
|
|
|
|
|
|
$panels = $this->getPanels();
|
|
|
|
|
|
|
|
foreach ($panels as $panel) {
|
2016-01-13 19:40:31 +01:00
|
|
|
if ($panel->isDisabled()) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2016-01-12 19:27:39 +01:00
|
|
|
$items = $panel->buildNavigationMenuItems();
|
|
|
|
foreach ($items as $item) {
|
|
|
|
$this->validateNavigationMenuItem($item);
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the panel produced only a single item which does not otherwise
|
|
|
|
// have a key, try to automatically assign it a reasonable key. This
|
|
|
|
// makes selecting the correct item simpler.
|
|
|
|
|
|
|
|
if (count($items) == 1) {
|
|
|
|
$item = head($items);
|
|
|
|
if ($item->getKey() === null) {
|
|
|
|
$builtin_key = $panel->getBuiltinKey();
|
|
|
|
$panel_phid = $panel->getPHID();
|
|
|
|
if ($builtin_key !== null) {
|
|
|
|
$item->setKey($builtin_key);
|
|
|
|
} else if ($panel_phid !== null) {
|
|
|
|
$item->setKey($panel_phid);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach ($items as $item) {
|
|
|
|
$nav->addMenuItem($item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-13 00:06:43 +01:00
|
|
|
$configure_item = $this->newConfigureMenuItem();
|
|
|
|
if ($configure_item) {
|
|
|
|
$nav->addMenuItem($configure_item);
|
|
|
|
}
|
|
|
|
|
2016-01-12 19:27:39 +01:00
|
|
|
$nav->selectFilter(null);
|
|
|
|
|
|
|
|
return $nav;
|
|
|
|
}
|
|
|
|
|
|
|
|
private function getPanels() {
|
|
|
|
if ($this->panels === null) {
|
|
|
|
$this->panels = $this->loadPanels();
|
|
|
|
}
|
|
|
|
|
|
|
|
return $this->panels;
|
|
|
|
}
|
|
|
|
|
|
|
|
private function loadPanels() {
|
|
|
|
$viewer = $this->getViewer();
|
2016-01-13 00:06:43 +01:00
|
|
|
$object = $this->getProfileObject();
|
2016-01-12 19:27:39 +01:00
|
|
|
|
|
|
|
$panels = $this->loadBuiltinProfilePanels();
|
|
|
|
|
2016-01-13 00:06:43 +01:00
|
|
|
$stored_panels = id(new PhabricatorProfilePanelConfigurationQuery())
|
|
|
|
->setViewer($viewer)
|
|
|
|
->withProfilePHIDs(array($object->getPHID()))
|
|
|
|
->execute();
|
|
|
|
|
|
|
|
// Merge the stored panels into the builtin panels. If a builtin panel has
|
|
|
|
// a stored version, replace the defaults with the stored changes.
|
|
|
|
foreach ($stored_panels as $stored_panel) {
|
|
|
|
$builtin_key = $stored_panel->getBuiltinKey();
|
|
|
|
if ($builtin_key !== null) {
|
|
|
|
$panels[$builtin_key] = $stored_panel;
|
|
|
|
} else {
|
|
|
|
$panels[] = $stored_panel;
|
|
|
|
}
|
|
|
|
}
|
2016-01-12 19:27:39 +01:00
|
|
|
|
|
|
|
foreach ($panels as $panel) {
|
|
|
|
$impl = $panel->getPanel();
|
|
|
|
|
|
|
|
$impl->setViewer($viewer);
|
|
|
|
}
|
|
|
|
|
2016-01-13 18:40:27 +01:00
|
|
|
$panels = msort($panels, 'getSortKey');
|
|
|
|
|
2016-01-13 00:06:43 +01:00
|
|
|
// Normalize keys since callers shouldn't rely on this array being
|
|
|
|
// partially keyed.
|
|
|
|
$panels = array_values($panels);
|
|
|
|
|
2016-01-12 19:27:39 +01:00
|
|
|
return $panels;
|
|
|
|
}
|
|
|
|
|
|
|
|
private function loadBuiltinProfilePanels() {
|
|
|
|
$object = $this->getProfileObject();
|
2016-01-14 14:59:25 +01:00
|
|
|
$builtins = $this->getBuiltinProfilePanels($object);
|
2016-01-12 19:27:39 +01:00
|
|
|
|
|
|
|
$panels = PhabricatorProfilePanel::getAllPanels();
|
|
|
|
|
|
|
|
$order = 1;
|
|
|
|
$map = array();
|
|
|
|
foreach ($builtins as $builtin) {
|
|
|
|
$builtin_key = $builtin->getBuiltinKey();
|
|
|
|
|
|
|
|
if (!$builtin_key) {
|
|
|
|
throw new Exception(
|
|
|
|
pht(
|
|
|
|
'Object produced a builtin panel with no builtin panel key! '.
|
|
|
|
'Builtin panels must have a unique key.'));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isset($map[$builtin_key])) {
|
|
|
|
throw new Exception(
|
|
|
|
pht(
|
|
|
|
'Object produced two panels with the same builtin key ("%s"). '.
|
|
|
|
'Each panel must have a unique builtin key.',
|
|
|
|
$builtin_key));
|
|
|
|
}
|
|
|
|
|
|
|
|
$panel_key = $builtin->getPanelKey();
|
|
|
|
|
|
|
|
$panel = idx($panels, $panel_key);
|
|
|
|
if (!$panel) {
|
|
|
|
throw new Exception(
|
|
|
|
pht(
|
|
|
|
'Builtin panel ("%s") specifies a bad panel key ("%s"); there '.
|
|
|
|
'is no corresponding panel implementation available.',
|
|
|
|
$builtin_key,
|
|
|
|
$panel_key));
|
|
|
|
}
|
|
|
|
|
|
|
|
$builtin
|
2016-01-13 00:06:43 +01:00
|
|
|
->setProfilePHID($object->getPHID())
|
2016-01-12 19:27:39 +01:00
|
|
|
->attachPanel($panel)
|
|
|
|
->attachProfileObject($object)
|
|
|
|
->setPanelOrder($order);
|
|
|
|
|
|
|
|
$map[$builtin_key] = $builtin;
|
|
|
|
|
|
|
|
$order++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $map;
|
|
|
|
}
|
|
|
|
|
|
|
|
private function validateNavigationMenuItem($item) {
|
|
|
|
if (!($item instanceof PHUIListItemView)) {
|
|
|
|
throw new Exception(
|
|
|
|
pht(
|
|
|
|
'Expected buildNavigationMenuItems() to return a list of '.
|
|
|
|
'PHUIListItemView objects, but got a surprise.'));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-13 00:06:43 +01:00
|
|
|
private function newConfigureMenuItem() {
|
2016-01-14 15:47:06 +01:00
|
|
|
if (!$this->isPanelEngineConfigurable()) {
|
2016-01-13 00:06:43 +01:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
$viewer = $this->getViewer();
|
|
|
|
$object = $this->getProfileObject();
|
|
|
|
|
|
|
|
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
|
|
|
$viewer,
|
|
|
|
$object,
|
|
|
|
PhabricatorPolicyCapability::CAN_EDIT);
|
|
|
|
|
|
|
|
return id(new PHUIListItemView())
|
|
|
|
->setName('Configure Menu')
|
|
|
|
->setKey('panel.configure')
|
|
|
|
->setIcon('fa-gear')
|
|
|
|
->setHref($this->getPanelURI('configure/'))
|
|
|
|
->setDisabled(!$can_edit)
|
2016-01-14 01:07:04 +01:00
|
|
|
->setWorkflow(!$can_edit);
|
2016-01-13 00:06:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function getConfigureURI() {
|
|
|
|
return $this->getPanelURI('configure/');
|
|
|
|
}
|
|
|
|
|
2016-01-13 18:40:27 +01:00
|
|
|
private function buildPanelReorderContent(array $panels) {
|
|
|
|
$viewer = $this->getViewer();
|
|
|
|
$object = $this->getProfileObject();
|
|
|
|
|
|
|
|
PhabricatorPolicyFilter::requireCapability(
|
|
|
|
$viewer,
|
|
|
|
$object,
|
|
|
|
PhabricatorPolicyCapability::CAN_EDIT);
|
|
|
|
|
|
|
|
$controller = $this->getController();
|
|
|
|
$request = $controller->getRequest();
|
|
|
|
|
|
|
|
$request->validateCSRF();
|
|
|
|
|
|
|
|
$order = $request->getStrList('order');
|
|
|
|
|
|
|
|
$by_builtin = array();
|
|
|
|
$by_id = array();
|
|
|
|
|
|
|
|
foreach ($panels as $key => $panel) {
|
|
|
|
$id = $panel->getID();
|
|
|
|
if ($id) {
|
|
|
|
$by_id[$id] = $key;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
$builtin_key = $panel->getBuiltinKey();
|
|
|
|
if ($builtin_key) {
|
|
|
|
$by_builtin[$builtin_key] = $key;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$key_order = array();
|
|
|
|
foreach ($order as $order_item) {
|
|
|
|
if (isset($by_id[$order_item])) {
|
|
|
|
$key_order[] = $by_id[$order_item];
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (isset($by_builtin[$order_item])) {
|
|
|
|
$key_order[] = $by_builtin[$order_item];
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$panels = array_select_keys($panels, $key_order) + $panels;
|
|
|
|
|
|
|
|
$type_order =
|
|
|
|
PhabricatorProfilePanelConfigurationTransaction::TYPE_ORDER;
|
|
|
|
|
|
|
|
$order = 1;
|
|
|
|
foreach ($panels as $panel) {
|
|
|
|
$xactions = array();
|
|
|
|
|
|
|
|
$xactions[] = id(new PhabricatorProfilePanelConfigurationTransaction())
|
|
|
|
->setTransactionType($type_order)
|
|
|
|
->setNewValue($order);
|
|
|
|
|
|
|
|
$editor = id(new PhabricatorProfilePanelEditor())
|
|
|
|
->setContentSourceFromRequest($request)
|
|
|
|
->setActor($viewer)
|
|
|
|
->setContinueOnMissingFields(true)
|
|
|
|
->setContinueOnNoEffect(true)
|
|
|
|
->applyTransactions($panel, $xactions);
|
|
|
|
|
|
|
|
$order++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return id(new AphrontRedirectResponse())
|
|
|
|
->setURI($this->getConfigureURI());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-01-13 00:06:43 +01:00
|
|
|
private function buildPanelConfigureContent(array $panels) {
|
|
|
|
$viewer = $this->getViewer();
|
|
|
|
$object = $this->getProfileObject();
|
|
|
|
|
|
|
|
PhabricatorPolicyFilter::requireCapability(
|
|
|
|
$viewer,
|
|
|
|
$object,
|
|
|
|
PhabricatorPolicyCapability::CAN_EDIT);
|
|
|
|
|
2016-01-13 18:40:27 +01:00
|
|
|
$list_id = celerity_generate_unique_node_id();
|
|
|
|
|
|
|
|
Javelin::initBehavior(
|
|
|
|
'reorder-profile-menu-items',
|
|
|
|
array(
|
|
|
|
'listID' => $list_id,
|
|
|
|
'orderURI' => $this->getPanelURI('reorder/'),
|
|
|
|
));
|
|
|
|
|
|
|
|
$list = id(new PHUIObjectItemListView())
|
|
|
|
->setID($list_id);
|
|
|
|
|
2016-01-13 00:06:43 +01:00
|
|
|
foreach ($panels as $panel) {
|
|
|
|
$id = $panel->getID();
|
|
|
|
$builtin_key = $panel->getBuiltinKey();
|
|
|
|
|
|
|
|
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
|
|
|
$viewer,
|
|
|
|
$panel,
|
|
|
|
PhabricatorPolicyCapability::CAN_EDIT);
|
|
|
|
|
|
|
|
$item = id(new PHUIObjectItemView());
|
|
|
|
|
|
|
|
$name = $panel->getDisplayName();
|
|
|
|
$type = $panel->getPanelTypeName();
|
|
|
|
if (!strlen(trim($name))) {
|
|
|
|
$name = pht('Untitled "%s" Item', $type);
|
|
|
|
}
|
|
|
|
|
|
|
|
$item->setHeader($name);
|
|
|
|
$item->addAttribute($type);
|
|
|
|
|
|
|
|
if ($can_edit) {
|
2016-01-13 18:40:27 +01:00
|
|
|
$item
|
|
|
|
->setGrippable(true)
|
|
|
|
->addSigil('profile-menu-item')
|
|
|
|
->setMetadata(
|
|
|
|
array(
|
|
|
|
'key' => nonempty($id, $builtin_key),
|
|
|
|
));
|
|
|
|
|
2016-01-13 00:06:43 +01:00
|
|
|
if ($id) {
|
|
|
|
$item->setHref($this->getPanelURI("edit/{$id}/"));
|
2016-01-13 19:40:31 +01:00
|
|
|
$hide_uri = $this->getPanelURI("hide/{$id}/");
|
2016-01-13 00:06:43 +01:00
|
|
|
} else {
|
|
|
|
$item->setHref($this->getPanelURI("builtin/{$builtin_key}/"));
|
2016-01-13 19:40:31 +01:00
|
|
|
$hide_uri = $this->getPanelURI("hide/{$builtin_key}/");
|
2016-01-13 00:06:43 +01:00
|
|
|
}
|
2016-01-13 19:40:31 +01:00
|
|
|
|
|
|
|
$item->addAction(
|
|
|
|
id(new PHUIListItemView())
|
|
|
|
->setHref($hide_uri)
|
|
|
|
->setWorkflow(true)
|
|
|
|
->setIcon(pht('fa-eye')));
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($panel->isDisabled()) {
|
|
|
|
$item->setDisabled(true);
|
|
|
|
$item->addIcon('fa-times grey', pht('Disabled'));
|
2016-01-13 00:06:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
$list->addItem($item);
|
|
|
|
}
|
|
|
|
|
|
|
|
$action_view = id(new PhabricatorActionListView())
|
|
|
|
->setUser($viewer);
|
|
|
|
|
|
|
|
$panel_types = PhabricatorProfilePanel::getAllPanels();
|
|
|
|
|
|
|
|
$action_view->addAction(
|
|
|
|
id(new PhabricatorActionView())
|
|
|
|
->setLabel(true)
|
|
|
|
->setName(pht('Add New Menu Item...')));
|
|
|
|
|
|
|
|
foreach ($panel_types as $panel_type) {
|
|
|
|
if (!$panel_type->canAddToObject($object)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
$panel_key = $panel_type->getPanelKey();
|
|
|
|
|
|
|
|
$action_view->addAction(
|
|
|
|
id(new PhabricatorActionView())
|
|
|
|
->setIcon($panel_type->getPanelTypeIcon())
|
|
|
|
->setName($panel_type->getPanelTypeName())
|
|
|
|
->setHref($this->getPanelURI("new/{$panel_key}/")));
|
|
|
|
}
|
|
|
|
|
|
|
|
$action_view->addAction(
|
|
|
|
id(new PhabricatorActionView())
|
|
|
|
->setLabel(true)
|
|
|
|
->setName(pht('Documentation')));
|
|
|
|
|
|
|
|
$action_view->addAction(
|
|
|
|
id(new PhabricatorActionView())
|
|
|
|
->setIcon('fa-book')
|
|
|
|
->setName(pht('TODO: Write Documentation')));
|
|
|
|
|
|
|
|
$action_button = id(new PHUIButtonView())
|
|
|
|
->setTag('a')
|
|
|
|
->setText(pht('Configure Menu'))
|
|
|
|
->setHref('#')
|
|
|
|
->setIconFont('fa-gear')
|
|
|
|
->setDropdownMenu($action_view);
|
|
|
|
|
|
|
|
$header = id(new PHUIHeaderView())
|
|
|
|
->setHeader(pht('Profile Menu Items'))
|
|
|
|
->addActionLink($action_button);
|
|
|
|
|
|
|
|
$box = id(new PHUIObjectBoxView())
|
|
|
|
->setHeader($header)
|
|
|
|
->setObjectList($list);
|
|
|
|
|
|
|
|
return $box;
|
|
|
|
}
|
|
|
|
|
|
|
|
private function buildPanelNewContent($panel_key) {
|
|
|
|
$panel_types = PhabricatorProfilePanel::getAllPanels();
|
|
|
|
$panel_type = idx($panel_types, $panel_key);
|
|
|
|
if (!$panel_type) {
|
|
|
|
return new Aphront404Response();
|
|
|
|
}
|
|
|
|
|
|
|
|
$object = $this->getProfileObject();
|
|
|
|
if (!$panel_type->canAddToObject($object)) {
|
|
|
|
return new Aphront404Response();
|
|
|
|
}
|
|
|
|
|
|
|
|
$configuration =
|
|
|
|
PhabricatorProfilePanelConfiguration::initializeNewPanelConfiguration(
|
|
|
|
$object,
|
|
|
|
$panel_type);
|
|
|
|
|
|
|
|
$viewer = $this->getViewer();
|
|
|
|
|
|
|
|
PhabricatorPolicyFilter::requireCapability(
|
|
|
|
$viewer,
|
|
|
|
$configuration,
|
|
|
|
PhabricatorPolicyCapability::CAN_EDIT);
|
|
|
|
|
|
|
|
$controller = $this->getController();
|
|
|
|
|
|
|
|
return id(new PhabricatorProfilePanelEditEngine())
|
|
|
|
->setPanelEngine($this)
|
|
|
|
->setProfileObject($object)
|
|
|
|
->setNewPanelConfiguration($configuration)
|
|
|
|
->setController($controller)
|
|
|
|
->buildResponse();
|
|
|
|
}
|
|
|
|
|
|
|
|
private function buildPanelEditContent() {
|
|
|
|
$viewer = $this->getViewer();
|
|
|
|
$object = $this->getProfileObject();
|
|
|
|
$controller = $this->getController();
|
|
|
|
|
|
|
|
return id(new PhabricatorProfilePanelEditEngine())
|
|
|
|
->setPanelEngine($this)
|
|
|
|
->setProfileObject($object)
|
|
|
|
->setController($controller)
|
|
|
|
->buildResponse();
|
|
|
|
}
|
|
|
|
|
|
|
|
private function buildPanelBuiltinContent(
|
|
|
|
PhabricatorProfilePanelConfiguration $configuration) {
|
|
|
|
|
|
|
|
// If this builtin panel has already been persisted, redirect to the
|
|
|
|
// edit page.
|
|
|
|
$id = $configuration->getID();
|
|
|
|
if ($id) {
|
|
|
|
return id(new AphrontRedirectResponse())
|
|
|
|
->setURI($this->getPanelURI("edit/{$id}/"));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Otherwise, act like we're creating a new panel, we're just starting
|
|
|
|
// with the builtin template.
|
|
|
|
$viewer = $this->getViewer();
|
|
|
|
|
|
|
|
PhabricatorPolicyFilter::requireCapability(
|
|
|
|
$viewer,
|
|
|
|
$configuration,
|
|
|
|
PhabricatorPolicyCapability::CAN_EDIT);
|
|
|
|
|
|
|
|
$object = $this->getProfileObject();
|
|
|
|
$controller = $this->getController();
|
|
|
|
|
|
|
|
return id(new PhabricatorProfilePanelEditEngine())
|
|
|
|
->setIsBuiltin(true)
|
|
|
|
->setPanelEngine($this)
|
|
|
|
->setProfileObject($object)
|
|
|
|
->setNewPanelConfiguration($configuration)
|
|
|
|
->setController($controller)
|
|
|
|
->buildResponse();
|
|
|
|
}
|
|
|
|
|
2016-01-13 19:40:31 +01:00
|
|
|
private function buildPanelHideContent(
|
|
|
|
PhabricatorProfilePanelConfiguration $configuration) {
|
|
|
|
|
|
|
|
$controller = $this->getController();
|
|
|
|
$request = $controller->getRequest();
|
|
|
|
$viewer = $this->getViewer();
|
|
|
|
|
|
|
|
PhabricatorPolicyFilter::requireCapability(
|
|
|
|
$viewer,
|
|
|
|
$configuration,
|
|
|
|
PhabricatorPolicyCapability::CAN_EDIT);
|
|
|
|
|
|
|
|
$v_visibility = $configuration->getVisibility();
|
|
|
|
if ($request->isFormPost()) {
|
|
|
|
$v_visibility = $request->getStr('visibility');
|
|
|
|
|
|
|
|
$type_visibility =
|
|
|
|
PhabricatorProfilePanelConfigurationTransaction::TYPE_VISIBILITY;
|
|
|
|
|
|
|
|
$xactions = array();
|
|
|
|
|
|
|
|
$xactions[] = id(new PhabricatorProfilePanelConfigurationTransaction())
|
|
|
|
->setTransactionType($type_visibility)
|
|
|
|
->setNewValue($v_visibility);
|
|
|
|
|
|
|
|
$editor = id(new PhabricatorProfilePanelEditor())
|
|
|
|
->setContentSourceFromRequest($request)
|
|
|
|
->setActor($viewer)
|
|
|
|
->setContinueOnMissingFields(true)
|
|
|
|
->setContinueOnNoEffect(true)
|
|
|
|
->applyTransactions($configuration, $xactions);
|
|
|
|
|
|
|
|
return id(new AphrontRedirectResponse())
|
|
|
|
->setURI($this->getConfigureURI());
|
|
|
|
}
|
|
|
|
|
|
|
|
$map = PhabricatorProfilePanelConfiguration::getVisibilityNameMap();
|
|
|
|
|
|
|
|
$form = id(new AphrontFormView())
|
|
|
|
->setUser($viewer)
|
|
|
|
->appendControl(
|
|
|
|
id(new AphrontFormSelectControl())
|
|
|
|
->setName('visibility')
|
|
|
|
->setLabel(pht('Visibility'))
|
|
|
|
->setValue($v_visibility)
|
|
|
|
->setOptions($map));
|
|
|
|
|
|
|
|
return $controller->newDialog()
|
|
|
|
->setTitle(pht('Change Item Visibility'))
|
|
|
|
->appendForm($form)
|
|
|
|
->addCancelButton($this->getConfigureURI())
|
|
|
|
->addSubmitButton(pht('Save Changes'));
|
|
|
|
}
|
|
|
|
|
2016-01-14 14:59:25 +01:00
|
|
|
protected function newPanel() {
|
|
|
|
return PhabricatorProfilePanelConfiguration::initializeNewBuiltin();
|
|
|
|
}
|
|
|
|
|
2016-01-12 19:27:39 +01:00
|
|
|
}
|