1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-30 18:52:42 +01:00
phorge-phorge/src/view/phui/PHUIListView.php
epriestley c39b64d963 Improve handle loading semantics for tokenizers
Summary:
Ref T7689. Fixes T7688. When there are a bunch of tokenizers with different values of the same object type (e.g. 5 tokenizers with users a, b, c, d, e) we currently issue 5 separate queries to load their handles.

Improve this behavior in the common case so we can usually batch these loads.

Test Plan:
  - In Maniphest, set the various search fields to different values.
  - Used DarkConsole to examine query plan.
  - Saw fewer queries after patch than before.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T7688, T7689

Differential Revision: https://secure.phabricator.com/D12261
2015-04-02 13:42:01 -07:00

193 lines
4.1 KiB
PHP

<?php
final class PHUIListView extends AphrontTagView {
const NAVBAR_LIST = 'phui-list-navbar';
const SIDENAV_LIST = 'phui-list-sidenav';
const TABBAR_LIST = 'phui-list-tabbar';
private $items = array();
private $type;
protected function canAppendChild() {
return false;
}
public function newLabel($name, $key = null) {
$item = id(new PHUIListItemView())
->setType(PHUIListItemView::TYPE_LABEL)
->setName($name);
if ($key !== null) {
$item->setKey($key);
}
$this->addMenuItem($item);
return $item;
}
public function newLink($name, $href, $key = null) {
$item = id(new PHUIListItemView())
->setType(PHUIListItemView::TYPE_LINK)
->setName($name)
->setHref($href);
if ($key !== null) {
$item->setKey($key);
}
$this->addMenuItem($item);
return $item;
}
public function newButton($name, $href) {
$item = id(new PHUIListItemView())
->setType(PHUIListItemView::TYPE_BUTTON)
->setName($name)
->setHref($href);
$this->addMenuItem($item);
return $item;
}
public function addMenuItem(PHUIListItemView $item) {
return $this->addMenuItemAfter(null, $item);
}
public function addMenuItemAfter($key, PHUIListItemView $item) {
if ($key === null) {
$this->items[] = $item;
return $this;
}
if (!$this->getItem($key)) {
throw new Exception(pht("No such key '%s' to add menu item after!",
$key));
}
$result = array();
foreach ($this->items as $other) {
$result[] = $other;
if ($other->getKey() == $key) {
$result[] = $item;
}
}
$this->items = $result;
return $this;
}
public function addMenuItemBefore($key, PHUIListItemView $item) {
if ($key === null) {
array_unshift($this->items, $item);
return $this;
}
$this->requireKey($key);
$result = array();
foreach ($this->items as $other) {
if ($other->getKey() == $key) {
$result[] = $item;
}
$result[] = $other;
}
$this->items = $result;
return $this;
}
public function addMenuItemToLabel($key, PHUIListItemView $item) {
$this->requireKey($key);
$other = $this->getItem($key);
if ($other->getType() != PHUIListItemView::TYPE_LABEL) {
throw new Exception(pht("Menu item '%s' is not a label!", $key));
}
$seen = false;
$after = null;
foreach ($this->items as $other) {
if (!$seen) {
if ($other->getKey() == $key) {
$seen = true;
}
} else {
if ($other->getType() == PHUIListItemView::TYPE_LABEL) {
break;
}
}
$after = $other->getKey();
}
return $this->addMenuItemAfter($after, $item);
}
private function requireKey($key) {
if (!$this->getItem($key)) {
throw new Exception(pht("No menu item with key '%s' exists!", $key));
}
}
public function getItem($key) {
$key = (string)$key;
// NOTE: We could optimize this, but need to update any map when items have
// their keys change. Since that's moderately complex, wait for a profile
// or use case.
foreach ($this->items as $item) {
if ($item->getKey() == $key) {
return $item;
}
}
return null;
}
public function getItems() {
return $this->items;
}
public function willRender() {
$key_map = array();
foreach ($this->items as $item) {
$key = $item->getKey();
if ($key !== null) {
if (isset($key_map[$key])) {
throw new Exception(
pht("Menu contains duplicate items with key '%s'!", $key));
}
$key_map[$key] = $item;
}
}
}
protected function getTagName() {
return 'ul';
}
public function setType($type) {
$this->type = $type;
return $this;
}
protected function getTagAttributes() {
require_celerity_resource('phui-list-view-css');
$classes = array();
$classes[] = 'phui-list-view';
if ($this->type) {
$classes[] = $this->type;
}
return array(
'class' => implode(' ', $classes),
);
}
protected function getTagContent() {
return $this->items;
}
}