[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/view/page/ -> PhabricatorStandardPageView.php (source)

   1  <?php
   2  
   3  /**
   4   * This is a standard Phabricator page with menus, Javelin, DarkConsole, and
   5   * basic styles.
   6   *
   7   */
   8  final class PhabricatorStandardPageView extends PhabricatorBarePageView {
   9  
  10    private $baseURI;
  11    private $applicationName;
  12    private $glyph;
  13    private $menuContent;
  14    private $showChrome = true;
  15    private $disableConsole;
  16    private $pageObjects = array();
  17    private $applicationMenu;
  18    private $showFooter = true;
  19  
  20    public function setShowFooter($show_footer) {
  21      $this->showFooter = $show_footer;
  22      return $this;
  23    }
  24  
  25    public function getShowFooter() {
  26      return $this->showFooter;
  27    }
  28  
  29    public function setApplicationMenu(PHUIListView $application_menu) {
  30      $this->applicationMenu = $application_menu;
  31      return $this;
  32    }
  33  
  34    public function getApplicationMenu() {
  35      return $this->applicationMenu;
  36    }
  37  
  38    public function setApplicationName($application_name) {
  39      $this->applicationName = $application_name;
  40      return $this;
  41    }
  42  
  43    public function setDisableConsole($disable) {
  44      $this->disableConsole = $disable;
  45      return $this;
  46    }
  47  
  48    public function getApplicationName() {
  49      return $this->applicationName;
  50    }
  51  
  52    public function setBaseURI($base_uri) {
  53      $this->baseURI = $base_uri;
  54      return $this;
  55    }
  56  
  57    public function getBaseURI() {
  58      return $this->baseURI;
  59    }
  60  
  61    public function setShowChrome($show_chrome) {
  62      $this->showChrome = $show_chrome;
  63      return $this;
  64    }
  65  
  66    public function getShowChrome() {
  67      return $this->showChrome;
  68    }
  69  
  70    public function appendPageObjects(array $objs) {
  71      foreach ($objs as $obj) {
  72        $this->pageObjects[] = $obj;
  73      }
  74    }
  75  
  76    public function getTitle() {
  77      $use_glyph = true;
  78  
  79      $request = $this->getRequest();
  80      if ($request) {
  81        $user = $request->getUser();
  82        if ($user && $user->loadPreferences()->getPreference(
  83              PhabricatorUserPreferences::PREFERENCE_TITLES) !== 'glyph') {
  84          $use_glyph = false;
  85        }
  86      }
  87  
  88      $title = parent::getTitle();
  89  
  90      $prefix = null;
  91      if ($use_glyph) {
  92        $prefix = $this->getGlyph();
  93      } else {
  94        $application_name = $this->getApplicationName();
  95        if (strlen($application_name)) {
  96          $prefix = '['.$application_name.']';
  97        }
  98      }
  99  
 100      if (strlen($prefix)) {
 101        $title = $prefix.' '.$title;
 102      }
 103  
 104      return $title;
 105    }
 106  
 107  
 108    protected function willRenderPage() {
 109      parent::willRenderPage();
 110  
 111      if (!$this->getRequest()) {
 112        throw new Exception(
 113          pht(
 114            'You must set the Request to render a PhabricatorStandardPageView.'));
 115      }
 116  
 117      $console = $this->getConsole();
 118  
 119      require_celerity_resource('phabricator-core-css');
 120      require_celerity_resource('phabricator-zindex-css');
 121      require_celerity_resource('phui-button-css');
 122      require_celerity_resource('phui-spacing-css');
 123      require_celerity_resource('phui-form-css');
 124      require_celerity_resource('sprite-gradient-css');
 125      require_celerity_resource('phabricator-standard-page-view');
 126  
 127      Javelin::initBehavior('workflow', array());
 128  
 129      $request = $this->getRequest();
 130      $user = null;
 131      if ($request) {
 132        $user = $request->getUser();
 133      }
 134  
 135      if ($user) {
 136        $default_img_uri =
 137          celerity_get_resource_uri(
 138            'rsrc/image/icon/fatcow/document_black.png');
 139        $download_form = phabricator_form(
 140          $user,
 141          array(
 142            'action' => '#',
 143            'method' => 'POST',
 144            'class'  => 'lightbox-download-form',
 145            'sigil'  => 'download',
 146          ),
 147          phutil_tag(
 148            'button',
 149            array(),
 150            pht('Download')));
 151  
 152        Javelin::initBehavior(
 153          'lightbox-attachments',
 154          array(
 155            'defaultImageUri' => $default_img_uri,
 156            'downloadForm'    => $download_form,
 157          ));
 158      }
 159  
 160      Javelin::initBehavior('aphront-form-disable-on-submit');
 161      Javelin::initBehavior('toggle-class', array());
 162      Javelin::initBehavior('konami', array());
 163      Javelin::initBehavior('history-install');
 164      Javelin::initBehavior('phabricator-gesture');
 165  
 166      $current_token = null;
 167      if ($user) {
 168        $current_token = $user->getCSRFToken();
 169      }
 170  
 171      Javelin::initBehavior(
 172        'refresh-csrf',
 173        array(
 174          'tokenName' => AphrontRequest::getCSRFTokenName(),
 175          'header'    => AphrontRequest::getCSRFHeaderName(),
 176          'current'   => $current_token,
 177        ));
 178  
 179      Javelin::initBehavior('device');
 180  
 181      if ($user->hasSession()) {
 182        $hisec = ($user->getSession()->getHighSecurityUntil() - time());
 183        if ($hisec > 0) {
 184          $remaining_time = phutil_format_relative_time($hisec);
 185          Javelin::initBehavior(
 186            'high-security-warning',
 187            array(
 188              'uri' => '/auth/session/downgrade/',
 189              'message' => pht(
 190                'Your session is in high security mode. When you '.
 191                'finish using it, click here to leave.',
 192                $remaining_time),
 193            ));
 194        }
 195      }
 196  
 197      if ($console) {
 198        require_celerity_resource('aphront-dark-console-css');
 199  
 200        $headers = array();
 201        if (DarkConsoleXHProfPluginAPI::isProfilerStarted()) {
 202          $headers[DarkConsoleXHProfPluginAPI::getProfilerHeader()] = 'page';
 203        }
 204        if (DarkConsoleServicesPlugin::isQueryAnalyzerRequested()) {
 205          $headers[DarkConsoleServicesPlugin::getQueryAnalyzerHeader()] = true;
 206        }
 207  
 208        Javelin::initBehavior(
 209          'dark-console',
 210          array(
 211            // NOTE: We use a generic label here to prevent input reflection
 212            // and mitigate compression attacks like BREACH. See discussion in
 213            // T3684.
 214            'uri' => pht('Main Request'),
 215            'selected' => $user ? $user->getConsoleTab() : null,
 216            'visible'  => $user ? (int)$user->getConsoleVisible() : true,
 217            'headers' => $headers,
 218          ));
 219  
 220        // Change this to initBehavior when there is some behavior to initialize
 221        require_celerity_resource('javelin-behavior-error-log');
 222      }
 223  
 224      if ($user) {
 225        $viewer = $user;
 226      } else {
 227        $viewer = new PhabricatorUser();
 228      }
 229  
 230      $menu = id(new PhabricatorMainMenuView())
 231        ->setUser($viewer);
 232  
 233      if ($this->getController()) {
 234        $menu->setController($this->getController());
 235      }
 236  
 237      if ($this->getApplicationMenu()) {
 238        $menu->setApplicationMenu($this->getApplicationMenu());
 239      }
 240  
 241      $this->menuContent = $menu->render();
 242    }
 243  
 244  
 245    protected function getHead() {
 246      $monospaced = PhabricatorEnv::getEnvConfig('style.monospace');
 247      $monospaced_win = PhabricatorEnv::getEnvConfig('style.monospace.windows');
 248  
 249      $request = $this->getRequest();
 250      if ($request) {
 251        $user = $request->getUser();
 252        if ($user) {
 253          $pref = $user->loadPreferences()->getPreference(
 254              PhabricatorUserPreferences::PREFERENCE_MONOSPACED);
 255          $monospaced = nonempty($pref, $monospaced);
 256          $monospaced_win = nonempty($pref, $monospaced_win);
 257        }
 258      }
 259  
 260      $response = CelerityAPI::getStaticResourceResponse();
 261  
 262      return hsprintf(
 263        '%s<style type="text/css">'.
 264        '.PhabricatorMonospaced, '.
 265        '.phabricator-remarkup .remarkup-code-block '.
 266          '.remarkup-code { font: %s; } '.
 267        '.platform-windows .PhabricatorMonospaced, '.
 268        '.platform-windows .phabricator-remarkup '.
 269          '.remarkup-code-block .remarkup-code { font: %s; }'.
 270        '</style>%s',
 271        parent::getHead(),
 272        phutil_safe_html($monospaced),
 273        phutil_safe_html($monospaced_win),
 274        $response->renderSingleResource('javelin-magical-init', 'phabricator'));
 275    }
 276  
 277    public function setGlyph($glyph) {
 278      $this->glyph = $glyph;
 279      return $this;
 280    }
 281  
 282    public function getGlyph() {
 283      return $this->glyph;
 284    }
 285  
 286    protected function willSendResponse($response) {
 287      $request = $this->getRequest();
 288      $response = parent::willSendResponse($response);
 289  
 290      $console = $request->getApplicationConfiguration()->getConsole();
 291  
 292      if ($console) {
 293        $response = PhutilSafeHTML::applyFunction(
 294          'str_replace',
 295          hsprintf('<darkconsole />'),
 296          $console->render($request),
 297          $response);
 298      }
 299  
 300      return $response;
 301    }
 302  
 303    protected function getBody() {
 304      $console = $this->getConsole();
 305  
 306      $user = null;
 307      $request = $this->getRequest();
 308      if ($request) {
 309        $user = $request->getUser();
 310      }
 311  
 312      $header_chrome = null;
 313      if ($this->getShowChrome()) {
 314        $header_chrome = $this->menuContent;
 315      }
 316  
 317      $developer_warning = null;
 318      if (PhabricatorEnv::getEnvConfig('phabricator.developer-mode') &&
 319          DarkConsoleErrorLogPluginAPI::getErrors()) {
 320        $developer_warning = phutil_tag_div(
 321          'aphront-developer-error-callout',
 322          pht(
 323            'This page raised PHP errors. Find them in DarkConsole '.
 324            'or the error log.'));
 325      }
 326  
 327      // Render the "you have unresolved setup issues..." warning.
 328      $setup_warning = null;
 329      if ($user && $user->getIsAdmin()) {
 330        $open = PhabricatorSetupCheck::getOpenSetupIssueCount();
 331        if ($open) {
 332          $setup_warning = phutil_tag_div(
 333            'setup-warning-callout',
 334            phutil_tag(
 335              'a',
 336              array(
 337                'href' => '/config/issue/',
 338              ),
 339              pht('You have %d unresolved setup issue(s)...', $open)));
 340        }
 341      }
 342  
 343      return phutil_tag(
 344        'div',
 345        array(
 346          'id' => 'base-page',
 347          'class' => 'phabricator-standard-page',
 348        ),
 349        array(
 350          $developer_warning,
 351          $setup_warning,
 352          $header_chrome,
 353          phutil_tag_div('phabricator-standard-page-body', array(
 354            ($console ? hsprintf('<darkconsole />') : null),
 355            parent::getBody(),
 356            $this->renderFooter(),
 357          )),
 358        ));
 359    }
 360  
 361    protected function getTail() {
 362      $request = $this->getRequest();
 363      $user = $request->getUser();
 364  
 365      $tail = array(
 366        parent::getTail(),
 367      );
 368  
 369      $response = CelerityAPI::getStaticResourceResponse();
 370  
 371      if (PhabricatorEnv::getEnvConfig('notification.enabled')) {
 372        if ($user && $user->isLoggedIn()) {
 373  
 374          $aphlict_object_id = celerity_generate_unique_node_id();
 375          $aphlict_container_id = celerity_generate_unique_node_id();
 376  
 377          $client_uri = PhabricatorEnv::getEnvConfig('notification.client-uri');
 378          $client_uri = new PhutilURI($client_uri);
 379          if ($client_uri->getDomain() == 'localhost') {
 380            $this_host = $this->getRequest()->getHost();
 381            $this_host = new PhutilURI('http://'.$this_host.'/');
 382            $client_uri->setDomain($this_host->getDomain());
 383          }
 384  
 385          $map = CelerityResourceMap::getNamedInstance('phabricator');
 386          $swf_uri = $response->getURI($map, 'rsrc/swf/aphlict.swf', true);
 387  
 388          $enable_debug = PhabricatorEnv::getEnvConfig('notification.debug');
 389  
 390          $subscriptions = $this->pageObjects;
 391          if ($user) {
 392            $subscriptions[] = $user->getPHID();
 393          }
 394  
 395          Javelin::initBehavior(
 396            'aphlict-listen',
 397            array(
 398              'id'            => $aphlict_object_id,
 399              'containerID'   => $aphlict_container_id,
 400              'server'        => $client_uri->getDomain(),
 401              'port'          => $client_uri->getPort(),
 402              'debug'         => $enable_debug,
 403              'swfURI'        => $swf_uri,
 404              'pageObjects'   => array_fill_keys($this->pageObjects, true),
 405              'subscriptions' => $subscriptions,
 406            ));
 407  
 408          $tail[] = phutil_tag(
 409            'div',
 410            array(
 411              'id' => $aphlict_container_id,
 412              'style' =>
 413                'position: absolute; width: 0; height: 0; overflow: hidden;',
 414            ),
 415            '');
 416        }
 417      }
 418  
 419      $tail[] = $response->renderHTMLFooter();
 420  
 421      return $tail;
 422    }
 423  
 424    protected function getBodyClasses() {
 425      $classes = array();
 426  
 427      if (!$this->getShowChrome()) {
 428        $classes[] = 'phabricator-chromeless-page';
 429      }
 430  
 431      $agent = AphrontRequest::getHTTPHeader('User-Agent');
 432  
 433      // Try to guess the device resolution based on UA strings to avoid a flash
 434      // of incorrectly-styled content.
 435      $device_guess = 'device-desktop';
 436      if (preg_match('@iPhone|iPod|(Android.*Chrome/[.0-9]* Mobile)@', $agent)) {
 437        $device_guess = 'device-phone device';
 438      } else if (preg_match('@iPad|(Android.*Chrome/)@', $agent)) {
 439        $device_guess = 'device-tablet device';
 440      }
 441  
 442      $classes[] = $device_guess;
 443  
 444      if (preg_match('@Windows@', $agent)) {
 445        $classes[] = 'platform-windows';
 446      } else if (preg_match('@Macintosh@', $agent)) {
 447        $classes[] = 'platform-mac';
 448      } else if (preg_match('@X11@', $agent)) {
 449        $classes[] = 'platform-linux';
 450      }
 451  
 452      if ($this->getRequest()->getStr('__print__')) {
 453        $classes[] = 'printable';
 454      }
 455  
 456      if ($this->getRequest()->getStr('__aural__')) {
 457        $classes[] = 'audible';
 458      }
 459  
 460      return implode(' ', $classes);
 461    }
 462  
 463    private function getConsole() {
 464      if ($this->disableConsole) {
 465        return null;
 466      }
 467      return $this->getRequest()->getApplicationConfiguration()->getConsole();
 468    }
 469  
 470    private function renderFooter() {
 471      if (!$this->getShowChrome()) {
 472        return null;
 473      }
 474  
 475      if (!$this->getShowFooter()) {
 476        return null;
 477      }
 478  
 479      $items = PhabricatorEnv::getEnvConfig('ui.footer-items');
 480      if (!$items) {
 481        return null;
 482      }
 483  
 484      $foot = array();
 485      foreach ($items as $item) {
 486        $name = idx($item, 'name', pht('Unnamed Footer Item'));
 487  
 488        $href = idx($item, 'href');
 489        if (!PhabricatorEnv::isValidWebResource($href)) {
 490          $href = null;
 491        }
 492  
 493        if ($href !== null) {
 494          $tag = 'a';
 495        } else {
 496          $tag = 'span';
 497        }
 498  
 499        $foot[] = phutil_tag(
 500          $tag,
 501          array(
 502            'href' => $href,
 503          ),
 504          $name);
 505      }
 506      $foot = phutil_implode_html(" \xC2\xB7 ", $foot);
 507  
 508      return phutil_tag(
 509        'div',
 510        array(
 511          'class' => 'phabricator-standard-page-footer grouped',
 512        ),
 513        $foot);
 514    }
 515  
 516  }


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1