Path: blob/master/src/view/phui/PHUIHeaderView.php
12249 views
<?php12final class PHUIHeaderView extends AphrontTagView {34const PROPERTY_STATUS = 1;56private $header;7private $tags = array();8private $image;9private $imageURL = null;10private $imageEditURL = null;11private $subheader;12private $headerIcon;13private $noBackground;14private $bleedHeader;15private $profileHeader;16private $tall;17private $properties = array();18private $actionLinks = array();19private $buttonBar = null;20private $policyObject;21private $epoch;22private $actionItems = array();23private $href;24private $actionList;25private $actionListID;2627public function setHeader($header) {28$this->header = $header;29return $this;30}3132public function setNoBackground($nada) {33$this->noBackground = $nada;34return $this;35}3637public function setTall($tall) {38$this->tall = $tall;39return $this;40}4142public function addTag(PHUITagView $tag) {43$this->tags[] = $tag;44return $this;45}4647public function setImage($uri) {48$this->image = $uri;49return $this;50}5152public function setImageURL($url) {53$this->imageURL = $url;54return $this;55}5657public function setImageEditURL($url) {58$this->imageEditURL = $url;59return $this;60}6162public function setSubheader($subheader) {63$this->subheader = $subheader;64return $this;65}6667public function setBleedHeader($bleed) {68$this->bleedHeader = $bleed;69return $this;70}7172public function setProfileHeader($bighead) {73$this->profileHeader = $bighead;74return $this;75}7677public function setHeaderIcon($icon) {78$this->headerIcon = $icon;79return $this;80}8182public function setActionList(PhabricatorActionListView $list) {83$this->actionList = $list;84return $this;85}8687public function setActionListID($action_list_id) {88$this->actionListID = $action_list_id;89return $this;90}9192public function setPolicyObject(PhabricatorPolicyInterface $object) {93$this->policyObject = $object;94return $this;95}9697public function addProperty($property, $value) {98$this->properties[$property] = $value;99return $this;100}101102public function addActionLink(PHUIButtonView $button) {103$this->actionLinks[] = $button;104return $this;105}106107public function addActionItem($action) {108$this->actionItems[] = $action;109return $this;110}111112public function setButtonBar(PHUIButtonBarView $bb) {113$this->buttonBar = $bb;114return $this;115}116117public function setStatus($icon, $color, $name) {118119// TODO: Normalize "closed/archived" to constants.120if ($color == 'dark') {121$color = PHUITagView::COLOR_INDIGO;122}123124$tag = id(new PHUITagView())125->setName($name)126->setIcon($icon)127->setColor($color)128->setType(PHUITagView::TYPE_SHADE);129130return $this->addProperty(self::PROPERTY_STATUS, $tag);131}132133public function setEpoch($epoch) {134$age = time() - $epoch;135$age = floor($age / (60 * 60 * 24));136if ($age < 1) {137$when = pht('Today');138} else if ($age == 1) {139$when = pht('Yesterday');140} else {141$when = pht('%s Day(s) Ago', new PhutilNumber($age));142}143144$this->setStatus('fa-clock-o bluegrey', null, pht('Updated %s', $when));145return $this;146}147148public function setHref($href) {149$this->href = $href;150return $this;151}152153public function getHref() {154return $this->href;155}156157protected function getTagName() {158return 'div';159}160161protected function getTagAttributes() {162require_celerity_resource('phui-header-view-css');163164$classes = array();165$classes[] = 'phui-header-shell';166167if ($this->noBackground) {168$classes[] = 'phui-header-no-background';169}170171if ($this->bleedHeader) {172$classes[] = 'phui-bleed-header';173}174175if ($this->profileHeader) {176$classes[] = 'phui-profile-header';177}178179if ($this->properties || $this->policyObject ||180$this->subheader || $this->tall) {181$classes[] = 'phui-header-tall';182}183184return array(185'class' => $classes,186);187}188189protected function getTagContent() {190191if ($this->actionList || $this->actionListID) {192$action_button = id(new PHUIButtonView())193->setTag('a')194->setText(pht('Actions'))195->setHref('#')196->setIcon('fa-bars')197->addClass('phui-mobile-menu');198199if ($this->actionList) {200$action_button->setDropdownMenu($this->actionList);201} else if ($this->actionListID) {202$action_button->setDropdownMenuID($this->actionListID);203}204205$this->addActionLink($action_button);206}207208$image = null;209if ($this->image) {210$image_href = null;211if ($this->imageURL) {212$image_href = $this->imageURL;213} else if ($this->imageEditURL) {214$image_href = $this->imageEditURL;215}216217$image = phutil_tag(218'span',219array(220'class' => 'phui-header-image',221'style' => 'background-image: url('.$this->image.')',222));223224if ($image_href) {225$edit_view = null;226if ($this->imageEditURL) {227$edit_view = phutil_tag(228'span',229array(230'class' => 'phui-header-image-edit',231),232pht('Edit'));233}234235$image = phutil_tag(236'a',237array(238'href' => $image_href,239'class' => 'phui-header-image-href',240),241array(242$image,243$edit_view,244));245}246}247248$viewer = $this->getUser();249250$left = array();251$right = array();252253$space_header = null;254if ($viewer) {255$space_header = id(new PHUISpacesNamespaceContextView())256->setUser($viewer)257->setObject($this->policyObject);258}259260if ($this->actionLinks) {261$actions = array();262foreach ($this->actionLinks as $button) {263if (!$button->getColor()) {264$button->setColor(PHUIButtonView::GREY);265}266$button->addClass(PHUI::MARGIN_SMALL_LEFT);267$button->addClass('phui-header-action-link');268$actions[] = $button;269}270$right[] = phutil_tag(271'div',272array(273'class' => 'phui-header-action-links',274),275$actions);276}277278if ($this->buttonBar) {279$right[] = phutil_tag(280'div',281array(282'class' => 'phui-header-action-links',283),284$this->buttonBar);285}286287if ($this->actionItems) {288$action_list = array();289if ($this->actionItems) {290foreach ($this->actionItems as $item) {291$action_list[] = phutil_tag(292'li',293array(294'class' => 'phui-header-action-item',295),296$item);297}298}299$right[] = phutil_tag(300'ul',301array(302'class' => 'phui-header-action-list',303),304$action_list);305}306307$icon = null;308if ($this->headerIcon) {309if ($this->headerIcon instanceof PHUIIconView) {310$icon = id(clone $this->headerIcon)311->addClass('phui-header-icon');312} else {313$icon = id(new PHUIIconView())314->setIcon($this->headerIcon)315->addClass('phui-header-icon');316}317}318319$header_content = $this->header;320321$href = $this->getHref();322if ($href !== null) {323$header_content = phutil_tag(324'a',325array(326'href' => $href,327),328$header_content);329}330331$left[] = phutil_tag(332'span',333array(334'class' => 'phui-header-header',335),336array(337$space_header,338$icon,339$header_content,340));341342if ($this->subheader) {343$left[] = phutil_tag(344'div',345array(346'class' => 'phui-header-subheader',347),348array(349$this->subheader,350));351}352353if ($this->properties || $this->policyObject || $this->tags) {354$property_list = array();355foreach ($this->properties as $type => $property) {356switch ($type) {357case self::PROPERTY_STATUS:358$property_list[] = $property;359break;360default:361throw new Exception(pht('Incorrect Property Passed'));362break;363}364}365366if ($this->policyObject) {367$property_list[] = $this->renderPolicyProperty($this->policyObject);368}369370if ($this->tags) {371$property_list[] = $this->tags;372}373374$left[] = phutil_tag(375'div',376array(377'class' => 'phui-header-subheader',378),379$property_list);380}381382// We here at @phabricator383$header_image = null;384if ($image) {385$header_image = phutil_tag(386'div',387array(388'class' => 'phui-header-col1',389),390$image);391}392393// All really love394$header_left = phutil_tag(395'div',396array(397'class' => 'phui-header-col2',398),399$left);400401// Tables and Pokemon.402$header_right = phutil_tag(403'div',404array(405'class' => 'phui-header-col3',406),407$right);408409$header_row = phutil_tag(410'div',411array(412'class' => 'phui-header-row',413),414array(415$header_image,416$header_left,417$header_right,418));419420return phutil_tag(421'h1',422array(423'class' => 'phui-header-view',424),425$header_row);426}427428private function renderPolicyProperty(PhabricatorPolicyInterface $object) {429$viewer = $this->getUser();430431$policies = PhabricatorPolicyQuery::loadPolicies($viewer, $object);432433$view_capability = PhabricatorPolicyCapability::CAN_VIEW;434$policy = idx($policies, $view_capability);435if (!$policy) {436return null;437}438439// If an object is in a Space with a strictly stronger (more restrictive)440// policy, we show the more restrictive policy. This better aligns the441// UI hint with the actual behavior.442443// NOTE: We'll do this even if the viewer has access to only one space, and444// show them information about the existence of spaces if they click445// through.446$use_space_policy = false;447if ($object instanceof PhabricatorSpacesInterface) {448$space_phid = PhabricatorSpacesNamespaceQuery::getObjectSpacePHID(449$object);450451$spaces = PhabricatorSpacesNamespaceQuery::getViewerSpaces($viewer);452$space = idx($spaces, $space_phid);453if ($space) {454$space_policies = PhabricatorPolicyQuery::loadPolicies(455$viewer,456$space);457$space_policy = idx($space_policies, $view_capability);458if ($space_policy) {459if ($space_policy->isStrongerThan($policy)) {460$policy = $space_policy;461$use_space_policy = true;462}463}464}465}466467$container_classes = array();468$container_classes[] = 'policy-header-callout';469$phid = $object->getPHID();470471$policy_name = array($policy->getShortName());472$policy_icon = $policy->getIcon().' bluegrey';473474if ($object instanceof PhabricatorPolicyCodexInterface) {475$codex = PhabricatorPolicyCodex::newFromObject($object, $viewer);476477$codex_name = $codex->getPolicyShortName($policy, $view_capability);478if ($codex_name !== null) {479$policy_name = $codex_name;480}481482$codex_icon = $codex->getPolicyIcon($policy, $view_capability);483if ($codex_icon !== null) {484$policy_icon = $codex_icon;485}486487$codex_classes = $codex->getPolicyTagClasses($policy, $view_capability);488foreach ($codex_classes as $codex_class) {489$container_classes[] = $codex_class;490}491}492493if (!is_array($policy_name)) {494$policy_name = (array)$policy_name;495}496497$arrow = id(new PHUIIconView())498->setIcon('fa-angle-right')499->addClass('policy-tier-separator');500501$policy_name = phutil_implode_html($arrow, $policy_name);502503$icon = id(new PHUIIconView())504->setIcon($policy_icon);505506$link = javelin_tag(507'a',508array(509'class' => 'policy-link',510'href' => '/policy/explain/'.$phid.'/'.$view_capability.'/',511'sigil' => 'workflow',512),513$policy_name);514515return phutil_tag(516'span',517array(518'class' => implode(' ', $container_classes),519),520array($icon, $link));521}522523}524525526