diff --git a/src/applications/conpherence/controller/ConpherenceController.php b/src/applications/conpherence/controller/ConpherenceController.php index c5c6f0e5ec..6c537f0006 100644 --- a/src/applications/conpherence/controller/ConpherenceController.php +++ b/src/applications/conpherence/controller/ConpherenceController.php @@ -1,225 +1,223 @@ unreadConpherences = $conpherences; return $this; } public function getUnreadConpherences() { return $this->unreadConpherences; } public function setReadConpherences(array $conpherences) { assert_instances_of($conpherences, 'ConpherenceThread'); $this->readConpherences = $conpherences; return $this; } public function getReadConpherences() { return $this->readConpherences; } public function setSelectedConpherencePHID($phid) { $this->selectedConpherencePHID = $phid; return $this; } public function getSelectedConpherencePHID() { return $this->selectedConpherencePHID; } /** * Try for a full set of unread conpherences, and if we fail * load read conpherences. Additional conpherences in either category * are loaded asynchronously. */ public function loadStartingConpherences($current_selection_epoch = null) { $user = $this->getRequest()->getUser(); $read_participant_query = id(new ConpherenceParticipantQuery()) ->withParticipantPHIDs(array($user->getPHID())); $read_status = ConpherenceParticipationStatus::UP_TO_DATE; if ($current_selection_epoch) { $read_one = $read_participant_query ->withParticipationStatus($read_status) ->withDateTouched($current_selection_epoch, '>') ->execute(); $read_two = $read_participant_query ->withDateTouched($current_selection_epoch, '<=') ->execute(); $read = array_merge($read_one, $read_two); } else { $read = $read_participant_query ->withParticipationStatus($read_status) ->execute(); } $unread_status = ConpherenceParticipationStatus::BEHIND; $unread_participant_query = id(new ConpherenceParticipantQuery()) ->withParticipantPHIDs(array($user->getPHID())); $unread = $unread_participant_query ->withParticipationStatus($unread_status) ->execute(); $all_participation = $unread + $read; $all_conpherence_phids = array_keys($all_participation); $all_conpherences = id(new ConpherenceThreadQuery()) ->setViewer($user) ->withPHIDs($all_conpherence_phids) ->execute(); $unread_conpherences = array_select_keys( $all_conpherences, array_keys($unread) ); $this->setUnreadConpherences($unread_conpherences); $read_conpherences = array_select_keys( $all_conpherences, array_keys($read) ); $this->setReadConpherences($read_conpherences); if (!$this->getSelectedConpherencePHID()) { $this->setSelectedConpherencePHID(reset($all_conpherence_phids)); } return $this; } public function buildSideNavView($filter = null) { require_celerity_resource('conpherence-menu-css'); $unread_conpherences = $this->getUnreadConpherences(); $read_conpherences = $this->getReadConpherences(); $user = $this->getRequest()->getUser(); $menu = new PhabricatorMenuView(); $nav = AphrontSideNavFilterView::newFromMenu($menu); $nav->addClass('conpherence-menu'); $nav->setMenuID('conpherence-menu'); $nav->addFilter( 'new', pht('New Conpherence'), $this->getApplicationURI('new/') ); $nav->addLabel(pht('Unread')); $nav = $this->addConpherencesToNav($unread_conpherences, $nav); $nav->addLabel(pht('Read')); $nav = $this->addConpherencesToNav($read_conpherences, $nav, true); $nav->selectFilter($filter); return $nav; } private function addConpherencesToNav( array $conpherences, AphrontSideNavFilterView $nav, $read = false) { $user = $this->getRequest()->getUser(); foreach ($conpherences as $conpherence) { $uri = $this->getApplicationURI('view/'.$conpherence->getID().'/'); $data = $conpherence->getDisplayData($user); $title = $data['title']; $subtitle = $data['subtitle']; $unread_count = $data['unread_count']; $epoch = $data['epoch']; $image = $data['image']; $snippet = $data['snippet']; $item = id(new ConpherenceMenuItemView()) ->setUser($user) ->setTitle($title) ->setSubtitle($subtitle) ->setHref($uri) ->setEpoch($epoch) ->setImageURI($image) ->setMessageText($snippet) ->setUnreadCount($unread_count) ->setID($conpherence->getPHID()) ->addSigil('conpherence-menu-click') ->setMetadata(array('id' => $conpherence->getID())); if ($this->getSelectedConpherencePHID() == $conpherence->getPHID()) { $item->addClass('conpherence-selected'); $item->addClass('hide-unread-count'); } $nav->addCustomBlock($item->render()); } if (empty($conpherences) || $read) { $nav->addCustomBlock($this->getNoConpherencesBlock()); } return $nav; } private function getNoConpherencesBlock() { - - return phutil_render_tag( + return phutil_tag( 'div', array( 'class' => 'no-conpherences-menu-item' ), - pht('No more conpherences.') - ); + pht('No more conpherences.')); } public function buildApplicationMenu() { return $this->buildSideNavView()->getMenu(); } public function buildApplicationCrumbs() { $crumbs = parent::buildApplicationCrumbs(); $crumbs ->addAction( id(new PhabricatorMenuItemView()) ->setName(pht('New Conpherence')) ->setHref($this->getApplicationURI('new/')) ->setIcon('create') ) ->addCrumb( id(new PhabricatorCrumbView()) ->setName(pht('Conpherence')) ); return $crumbs; } protected function initJavelinBehaviors() { Javelin::initBehavior('conpherence-menu', array( 'base_uri' => $this->getApplicationURI(''), 'header' => 'conpherence-header-pane', 'messages' => 'conpherence-messages', 'widgets_pane' => 'conpherence-widget-pane', 'form_pane' => 'conpherence-form', 'fancy_ajax' => (bool) $this->getSelectedConpherencePHID() ) ); Javelin::initBehavior('conpherence-init', array( 'selected_conpherence_id' => $this->getSelectedConpherencePHID(), 'menu_pane' => 'conpherence-menu', 'messages_pane' => 'conpherence-message-pane', 'messages' => 'conpherence-messages', 'widgets_pane' => 'conpherence-widget-pane', 'form_pane' => 'conpherence-form' ) ); } } diff --git a/src/applications/conpherence/controller/ConpherenceListController.php b/src/applications/conpherence/controller/ConpherenceListController.php index 80ef89d66a..73f845c94c 100644 --- a/src/applications/conpherence/controller/ConpherenceListController.php +++ b/src/applications/conpherence/controller/ConpherenceListController.php @@ -1,119 +1,117 @@ conpherenceID = $conpherence_id; return $this; } public function getConpherenceID() { return $this->conpherenceID; } public function willProcessRequest(array $data) { $this->setConpherenceID(idx($data, 'id')); } public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); $title = pht('Conpherence'); $conpherence_id = $this->getConpherenceID(); $current_selection_epoch = null; if ($conpherence_id) { $conpherence = id(new ConpherenceThreadQuery()) ->setViewer($user) ->withIDs(array($conpherence_id)) ->executeOne(); if (!$conpherence) { return new Aphront404Response(); } if ($conpherence->getTitle()) { $title = $conpherence->getTitle(); } $this->setSelectedConpherencePHID($conpherence->getPHID()); $read_status = ConpherenceParticipationStatus::UP_TO_DATE; $participant = $conpherence->getParticipant($user->getPHID()); $write_guard = AphrontWriteGuard::beginScopedUnguardedWrites(); $participant->markUpToDate(); unset($write_guard); $current_selection_epoch = $participant->getDateTouched(); } $this->loadStartingConpherences($current_selection_epoch); $nav = $this->buildSideNavView(); $main_pane = $this->renderEmptyMainPane(); $nav->appendChild( array( $main_pane, )); return $this->buildApplicationPage( $nav, array( 'title' => $title, 'device' => true, ) ); } private function renderEmptyMainPane() { $this->initJavelinBehaviors(); - return phutil_render_tag( + return phutil_tag( 'div', array( 'id' => 'conpherence-main-pane' ), - phutil_render_tag( - 'div', - array( - 'class' => 'conpherence-header-pane', - 'id' => 'conpherence-header-pane', - ), - '' - ). - phutil_render_tag( - 'div', - array( - 'class' => 'conpherence-widget-pane', - 'id' => 'conpherence-widget-pane' - ), - '' - ). - javelin_render_tag( - 'div', - array( - 'class' => 'conpherence-message-pane', - 'id' => 'conpherence-message-pane' - ), - phutil_render_tag( + array( + phutil_tag( 'div', array( - 'class' => 'conpherence-messages', - 'id' => 'conpherence-messages' + 'class' => 'conpherence-header-pane', + 'id' => 'conpherence-header-pane', ), - '' - ). - phutil_render_tag( + ''), + phutil_tag( 'div', array( - 'id' => 'conpherence-form' + 'class' => 'conpherence-widget-pane', + 'id' => 'conpherence-widget-pane' ), - '' - ) - ) - ); + ''), + phutil_tag( + 'div', + array( + 'class' => 'conpherence-message-pane', + 'id' => 'conpherence-message-pane' + ), + array( + phutil_tag( + 'div', + array( + 'class' => 'conpherence-messages', + 'id' => 'conpherence-messages' + ), + ''), + phutil_tag( + 'div', + array( + 'id' => 'conpherence-form' + ), + ''), + )), + )); } } diff --git a/src/applications/conpherence/controller/ConpherenceNewController.php b/src/applications/conpherence/controller/ConpherenceNewController.php index 1d0f082099..a167304e63 100644 --- a/src/applications/conpherence/controller/ConpherenceNewController.php +++ b/src/applications/conpherence/controller/ConpherenceNewController.php @@ -1,201 +1,201 @@ getRequest(); $user = $request->getUser(); $conpherence = id(new ConpherenceThread()) ->attachParticipants(array()) ->attachFilePHIDs(array()); $title = pht('New Conpherence'); $participants = array(); $message = ''; $files = array(); $errors = array(); $e_participants = null; $e_message = null; // this comes from ajax requests from all over. should be a single phid. $participant_prefill = $request->getStr('participant'); if ($participant_prefill) { $participants[] = $participant_prefill; } if ($request->isFormPost()) { $participants = $request->getArr('participants'); if (empty($participants)) { $e_participants = true; $errors[] = pht('You must specify participants.'); } else { $participants[] = $user->getPHID(); $participants = array_unique($participants); } $message = $request->getStr('message'); if (empty($message)) { $e_message = true; $errors[] = pht('You must write a message.'); } $file_phids = PhabricatorMarkupEngine::extractFilePHIDsFromEmbeddedFiles( array($message) ); if ($file_phids) { $files = id(new PhabricatorFileQuery()) ->setViewer($user) ->withPHIDs($file_phids) ->execute(); } if (!$errors) { $conpherence->openTransaction(); $conpherence->save(); $xactions = array(); $xactions[] = id(new ConpherenceTransaction()) ->setTransactionType(ConpherenceTransactionType::TYPE_PARTICIPANTS) ->setNewValue(array('+' => $participants)); $xactions[] = id(new ConpherenceTransaction()) ->setTransactionType(PhabricatorTransactions::TYPE_COMMENT) ->attachComment( id(new ConpherenceTransactionComment()) ->setContent($message) ->setConpherencePHID($conpherence->getPHID()) ); if ($files) { $xactions[] = id(new ConpherenceTransaction()) ->setTransactionType(ConpherenceTransactionType::TYPE_FILES) ->setNewValue(array('+' => mpull($files, 'getPHID'))); } $content_source = PhabricatorContentSource::newForSource( PhabricatorContentSource::SOURCE_WEB, array( 'ip' => $request->getRemoteAddr() ) ); id(new ConpherenceEditor()) ->setContentSource($content_source) ->setContinueOnNoEffect(true) ->setActor($user) ->applyTransactions($conpherence, $xactions); $conpherence->saveTransaction(); if ($request->isAjax()) { $dialog = id(new AphrontDialogView()) ->setUser($user) ->setTitle('Success') ->addCancelButton('#', 'Okay') ->appendChild( - phutil_render_tag('p', - array(), - pht('Message sent successfully.') - ) + phutil_tag( + 'p', + array(), + pht('Message sent successfully.')) ); $response = id(new AphrontDialogResponse()) ->setDialog($dialog); } else { $uri = $this->getApplicationURI($conpherence->getID()); $response = id(new AphrontRedirectResponse()) ->setURI($uri); } return $response; } } $error_view = null; if ($errors) { $error_view = id(new AphrontErrorView()) ->setTitle(pht('Conpherence Errors')) ->setErrors($errors); } $participant_handles = array(); if ($participants) { $handles = id(new PhabricatorObjectHandleData($participants)) ->setViewer($user) ->loadHandles(); $participant_handles = mpull($handles, 'getFullName', 'getPHID'); } $submit_uri = $this->getApplicationURI('new/'); $cancel_uri = $this->getApplicationURI(); if ($request->isAjax()) { // TODO - we can get a better cancel_uri once we get better at crazy // ajax jonx T2086 if ($participant_prefill) { $handle = $handles[$participant_prefill]; $cancel_uri = $handle->getURI(); } $form = id(new AphrontDialogView()) ->setSubmitURI($submit_uri) ->addSubmitButton() ->setWidth(AphrontDialogView::WIDTH_FORM) ->addCancelButton($cancel_uri); } else { $form = id(new AphrontFormView()) ->setID('conpherence-message-pane') ->setAction($submit_uri); } $form ->setUser($user) ->appendChild( id(new AphrontFormTokenizerControl()) ->setName('participants') ->setValue($participant_handles) ->setUser($user) ->setDatasource('/typeahead/common/users/') ->setLabel(pht('To')) ->setError($e_participants) ) ->appendChild( id(new PhabricatorRemarkupControl()) ->setName('message') ->setValue($message) ->setLabel(pht('Message')) ->setPlaceHolder(pht('Drag and drop to include files...')) ->setError($e_message) ); if ($request->isAjax()) { $form->setTitle($title); return id(new AphrontDialogResponse()) ->setDialog($form); } $form ->appendChild( id(new AphrontFormSubmitControl()) ->setValue(pht('Submit')) ->addCancelButton($cancel_uri) ); $this->loadStartingConpherences(); $this->setSelectedConpherencePHID(null); $this->initJavelinBehaviors(); $nav = $this->buildSideNavView('new'); $header = id(new PhabricatorHeaderView()) ->setHeader($title); $nav->appendChild( array( $header, $error_view, $form, )); return $this->buildApplicationPage( $nav, array( 'title' => $title, 'device' => true, ) ); } } diff --git a/src/applications/conpherence/controller/ConpherenceUpdateController.php b/src/applications/conpherence/controller/ConpherenceUpdateController.php index 51f1e66bc4..baa2fc92ef 100644 --- a/src/applications/conpherence/controller/ConpherenceUpdateController.php +++ b/src/applications/conpherence/controller/ConpherenceUpdateController.php @@ -1,218 +1,218 @@ conpherenceID = $conpherence_id; return $this; } public function getConpherenceID() { return $this->conpherenceID; } public function willProcessRequest(array $data) { $this->setConpherenceID(idx($data, 'id')); } public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); $conpherence_id = $this->getConpherenceID(); if (!$conpherence_id) { return new Aphront404Response(); } $conpherence = id(new ConpherenceThreadQuery()) ->setViewer($user) ->withIDs(array($conpherence_id)) ->executeOne(); $supported_formats = PhabricatorFile::getTransformableImageFormats(); $updated = false; $error_view = null; $e_image = null; $errors = array(); if ($request->isFormPost()) { $content_source = PhabricatorContentSource::newForSource( PhabricatorContentSource::SOURCE_WEB, array( 'ip' => $request->getRemoteAddr() )); $action = $request->getStr('action'); switch ($action) { case 'message': $message = $request->getStr('text'); $files = array(); $file_phids = PhabricatorMarkupEngine::extractFilePHIDsFromEmbeddedFiles( array($message) ); if ($file_phids) { $files = id(new PhabricatorFileQuery()) ->setViewer($user) ->withPHIDs($file_phids) ->execute(); } $xactions = array(); if ($files) { $xactions[] = id(new ConpherenceTransaction()) ->setTransactionType(ConpherenceTransactionType::TYPE_FILES) ->setNewValue(array('+' => mpull($files, 'getPHID'))); } $xactions[] = id(new ConpherenceTransaction()) ->setTransactionType(PhabricatorTransactions::TYPE_COMMENT) ->attachComment( id(new ConpherenceTransactionComment()) ->setContent($message) ->setConpherencePHID($conpherence->getPHID()) ); $time = time(); $conpherence->openTransaction(); $xactions = id(new ConpherenceEditor()) ->setContentSource($content_source) ->setActor($user) ->applyTransactions($conpherence, $xactions); $last_xaction = end($xactions); $xaction_phid = $last_xaction->getPHID(); $behind = ConpherenceParticipationStatus::BEHIND; $up_to_date = ConpherenceParticipationStatus::UP_TO_DATE; $participants = $conpherence->getParticipants(); foreach ($participants as $phid => $participant) { if ($phid != $user->getPHID()) { if ($participant->getParticipationStatus() != $behind) { $participant->setBehindTransactionPHID($xaction_phid); } $participant->setParticipationStatus($behind); $participant->setDateTouched($time); } else { $participant->setParticipationStatus($up_to_date); $participant->setDateTouched($time); } $participant->save(); } $updated = $conpherence->saveTransaction(); break; case 'metadata': $xactions = array(); $default_image = $request->getExists('default_image'); if ($default_image) { $image_phid = null; $xactions[] = id(new ConpherenceTransaction()) ->setTransactionType(ConpherenceTransactionType::TYPE_PICTURE) ->setNewValue($image_phid); } else if (!empty($_FILES['image'])) { $err = idx($_FILES['image'], 'error'); if ($err != UPLOAD_ERR_NO_FILE) { $file = PhabricatorFile::newFromPHPUpload( $_FILES['image'], array( 'authorPHID' => $user->getPHID(), )); $okay = $file->isTransformableImage(); if ($okay) { $xformer = new PhabricatorImageTransformer(); $xformed = $xformer->executeThumbTransform( $file, $x = 50, $y = 50); $image_phid = $xformed->getPHID(); $xactions[] = id(new ConpherenceTransaction()) ->setTransactionType(ConpherenceTransactionType::TYPE_PICTURE) ->setNewValue($image_phid); } else { $e_image = pht('Not Supported'); $errors[] = pht('This server only supports these image formats: %s.', implode(', ', $supported_formats)); } } } $title = $request->getStr('title'); if ($title != $conpherence->getTitle()) { $xactions[] = id(new ConpherenceTransaction()) ->setTransactionType(ConpherenceTransactionType::TYPE_TITLE) ->setNewValue($title); } if ($xactions) { $conpherence->openTransaction(); $xactions = id(new ConpherenceEditor()) ->setContentSource($content_source) ->setActor($user) ->setContinueOnNoEffect(true) ->applyTransactions($conpherence, $xactions); $updated = $conpherence->saveTransaction(); } else if (empty($errors)) { $errors[] = pht( 'That was a non-update. Try cancel.' ); } break; default: throw new Exception('Unknown action: '.$action); break; } } if ($updated) { return id(new AphrontRedirectResponse())->setURI( $this->getApplicationURI($conpherence_id.'/') ); } if ($errors) { $error_view = id(new AphrontErrorView()) ->setTitle(pht('Errors editing conpherence.')) ->setErrors($errors); } $form = id(new AphrontFormLayoutView()) ->appendChild( id(new AphrontFormTextControl()) ->setLabel(pht('Title')) ->setName('title') ->setValue($conpherence->getTitle()) ) ->appendChild( id(new AphrontFormMarkupControl()) ->setLabel(pht('Image')) - ->setValue(phutil_render_tag( + ->setValue(phutil_tag( 'img', array( 'src' => $conpherence->loadImageURI(), )) ) ) ->appendChild( id(new AphrontFormImageControl()) ->setLabel(pht('Change Image')) ->setName('image') ->setCaption('Supported formats: '.implode(', ', $supported_formats)) ->setError($e_image) ); // TODO -- fix javelin so we can upload files from a workflow require_celerity_resource('conpherence-update-css'); return $this->buildStandardPageResponse( array( $error_view, id(new AphrontDialogView()) ->setUser($user) ->setTitle(pht('Update Conpherence')) ->setWidth(AphrontDialogView::WIDTH_FORM) ->setSubmitURI($this->getApplicationURI('update/'.$conpherence_id.'/')) ->addHiddenInput('action', 'metadata') ->appendChild($form) ->addSubmitButton() ->addCancelButton($this->getApplicationURI($conpherence->getID().'/')), ), array() ); } } diff --git a/src/applications/conpherence/view/ConpherenceMenuItemView.php b/src/applications/conpherence/view/ConpherenceMenuItemView.php index b2e7cbccd0..44ec161179 100644 --- a/src/applications/conpherence/view/ConpherenceMenuItemView.php +++ b/src/applications/conpherence/view/ConpherenceMenuItemView.php @@ -1,144 +1,144 @@ unreadCount = $unread_count; return $this; } public function getUnreadCount() { return $this->unreadCount; } public function setMessageText($message_text) { $this->messageText = $message_text; return $this; } public function getMessageText() { return $this->messageText; } public function setEpoch($epoch) { $this->epoch = $epoch; return $this; } public function getEpoch() { return $this->epoch; } public function setHref($href) { $this->href = $href; return $this; } public function getHref() { return $this->href; } public function setImageURI($image_uri) { $this->imageURI = $image_uri; return $this; } public function getImageURI() { return $this->imageURI; } public function setSubtitle($subtitle) { $this->subtitle = $subtitle; return $this; } public function getSubtitle() { return $this->subtitle; } public function setTitle($title) { $this->title = $title; return $this; } public function getTitle() { return $this->title; } protected function getTagName() { return 'a'; } protected function getTagAttributes() { $classes = array('conpherence-menu-item-view'); return array( 'class' => $classes, 'href' => $this->href, ); } protected function getTagContent() { $image = null; if ($this->imageURI) { - $image = phutil_render_tag( + $image = phutil_tag( 'span', array( 'class' => 'conpherence-menu-item-image', 'style' => 'background-image: url('.$this->imageURI.');' ), ''); } $title = null; if ($this->title) { - $title = phutil_render_tag( + $title = phutil_tag( 'span', array( 'class' => 'conpherence-menu-item-title', ), - phutil_escape_html($this->title)); + $this->title); } $subtitle = null; if ($this->subtitle) { - $subtitle = phutil_render_tag( + $subtitle = phutil_tag( 'span', array( 'class' => 'conpherence-menu-item-subtitle', ), - phutil_escape_html($this->subtitle)); + $this->subtitle); } $message = null; if ($this->messageText) { - $message = phutil_render_tag( + $message = phutil_tag( 'span', array( 'class' => 'conpherence-menu-item-message-text' ), - phutil_escape_html($this->messageText)); + $this->messageText); } $epoch = null; if ($this->epoch) { - $epoch = phutil_render_tag( + $epoch = phutil_tag( 'span', array( 'class' => 'conpherence-menu-item-date', ), phabricator_relative_date($this->epoch, $this->user)); } $unread_count = null; if ($this->unreadCount) { - $unread_count = phutil_render_tag( + $unread_count = phutil_tag( 'span', array( 'class' => 'conpherence-menu-item-unread-count' ), - $this->unreadCount); + (int)$this->unreadCount); } return $image.$title.$subtitle.$message.$epoch.$unread_count; } } diff --git a/src/applications/conpherence/view/ConpherenceTransactionView.php b/src/applications/conpherence/view/ConpherenceTransactionView.php index d60f648414..c44b80faa5 100644 --- a/src/applications/conpherence/view/ConpherenceTransactionView.php +++ b/src/applications/conpherence/view/ConpherenceTransactionView.php @@ -1,98 +1,97 @@ handles = $handles; return $this; } public function getHandles() { return $this->handles; } public function setConpherenceTransaction(ConpherenceTransaction $tx) { $this->conpherenceTransaction = $tx; return $this; } private function getConpherenceTransaction() { return $this->conpherenceTransaction; } public function render() { $transaction = $this->getConpherenceTransaction(); $handles = $this->getHandles(); $transaction->setHandles($handles); $author = $handles[$transaction->getAuthorPHID()]; $transaction_view = id(new PhabricatorTransactionView()) ->setUser($this->getUser()) ->setEpoch($transaction->getDateCreated()) ->setContentSource($transaction->getContentSource()); $content_class = null; switch ($transaction->getTransactionType()) { case ConpherenceTransactionType::TYPE_TITLE: $content = $transaction->getTitle(); $transaction_view->addClass('conpherence-edited'); break; case ConpherenceTransactionType::TYPE_FILES: $content = $transaction->getTitle(); break; case ConpherenceTransactionType::TYPE_PICTURE: $img = $transaction->getHandle($transaction->getNewValue()); $content = $transaction->getTitle() . - phutil_render_tag( + phutil_tag( 'img', array( 'src' => $img->getImageURI() - ) - ); + )); $transaction_view->addClass('conpherence-edited'); break; case ConpherenceTransactionType::TYPE_PARTICIPANTS: $content = $transaction->getTitle(); $transaction_view->addClass('conpherence-edited'); break; case PhabricatorTransactions::TYPE_COMMENT: $comment = $transaction->getComment(); $file_ids = PhabricatorMarkupEngine::extractFilePHIDsFromEmbeddedFiles( array($comment->getContent()) ); $markup_field = ConpherenceTransactionComment::MARKUP_FIELD_COMMENT; $engine = id(new PhabricatorMarkupEngine()) ->setViewer($this->getUser()); $engine->addObject( $comment, $markup_field ); $engine->process(); $content = $engine->getOutput( $comment, $markup_field ); $content_class = 'conpherence-message phabricator-remarkup'; $transaction_view ->setImageURI($author->getImageURI()) ->setActions(array($author->renderLink())); break; } $transaction_view ->appendChild(phutil_render_tag( 'div', array( 'class' => $content_class ), $content) ); return $transaction_view->render(); } } diff --git a/src/applications/countdown/controller/PhabricatorCountdownViewController.php b/src/applications/countdown/controller/PhabricatorCountdownViewController.php index 48a51ed1c0..494f918308 100644 --- a/src/applications/countdown/controller/PhabricatorCountdownViewController.php +++ b/src/applications/countdown/controller/PhabricatorCountdownViewController.php @@ -1,79 +1,79 @@ id = $data['id']; } public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); $timer = id(new PhabricatorTimer())->load($this->id); if (!$timer) { return new Aphront404Response(); } require_celerity_resource('phabricator-countdown-css'); $chrome_visible = $request->getBool('chrome', true); $chrome_new = $chrome_visible ? false : null; - $chrome_link = phutil_render_tag( + $chrome_link = phutil_tag( 'a', array( 'href' => $request->getRequestURI()->alter('chrome', $chrome_new), 'class' => 'phabricator-timer-chrome-link', ), - $chrome_visible ? 'Disable Chrome' : 'Enable Chrome'); + $chrome_visible ? pht('Disable Chrome') : pht('Enable Chrome')); $container = celerity_generate_unique_node_id(); $content = '

'. phutil_escape_html($timer->getTitle()).' · '. phabricator_datetime($timer->getDatePoint(), $user). '

'. javelin_render_tag('td', array('sigil' => 'phabricator-timer-days'), ''). javelin_render_tag('td', array('sigil' => 'phabricator-timer-hours'), ''). javelin_render_tag('td', array('sigil' => 'phabricator-timer-minutes'), ''). javelin_render_tag('td', array('sigil' => 'phabricator-timer-seconds'), ''). '
Days Hours Minutes Seconds
'. $chrome_link. '
'; Javelin::initBehavior('countdown-timer', array( 'timestamp' => $timer->getDatepoint(), 'container' => $container, )); $panel = $content; return $this->buildStandardPageResponse( $panel, array( 'title' => 'Countdown: '.$timer->getTitle(), 'chrome' => $chrome_visible )); } } diff --git a/src/applications/meta/view/PhabricatorApplicationLaunchView.php b/src/applications/meta/view/PhabricatorApplicationLaunchView.php index e3997c0c0b..566783c5e2 100644 --- a/src/applications/meta/view/PhabricatorApplicationLaunchView.php +++ b/src/applications/meta/view/PhabricatorApplicationLaunchView.php @@ -1,135 +1,135 @@ fullWidth = $full_width; return $this; } public function setApplication(PhabricatorApplication $application) { $this->application = $application; return $this; } public function setApplicationStatus(array $status) { $this->status = $status; return $this; } public function render() { $application = $this->application; require_celerity_resource('phabricator-application-launch-view-css'); require_celerity_resource('sprite-apps-large-css'); $content = array(); $icon = null; $create_button = null; if ($application) { $content[] = phutil_tag( 'span', array( 'class' => 'phabricator-application-launch-name', ), $application->getName()); if ($application->isBeta()) { - $content[] = phutil_render_tag( + $content[] = phutil_tag( 'span', array( 'class' => 'phabricator-application-beta', ), "\xCE\xB2"); } if ($this->fullWidth) { $content[] = phutil_tag( 'span', array( 'class' => 'phabricator-application-launch-description', ), $application->getShortDescription()); } $count = 0; if ($this->status) { foreach ($this->status as $status) { $count += $status->getCount(); } } if ($count) { $content[] = phutil_tag( 'span', array( 'class' => 'phabricator-application-launch-attention', ), $count); } $classes = array(); $classes[] = 'phabricator-application-launch-icon'; $styles = array(); if ($application->getIconURI()) { $styles[] = 'background-image: url('.$application->getIconURI().')'; } else { $icon = $application->getIconName(); $classes[] = 'sprite-apps-large'; $classes[] = 'app-'.$icon.'-light-large'; } $icon = phutil_tag( 'span', array( 'class' => implode(' ', $classes), 'style' => nonempty(implode('; ', $styles), null), ), ''); $classes = array(); if ($application->getQuickCreateURI()) { $classes[] = 'phabricator-application-create-icon'; $classes[] = 'sprite-icon'; $classes[] = 'action-new-grey'; - $plus_icon = phutil_render_tag( + $plus_icon = phutil_tag( 'span', array( 'class' => implode(' ', $classes), )); - $create_button = phutil_render_tag( + $create_button = phutil_tag( 'a', array( 'href' => $application->getQuickCreateURI(), 'class' => 'phabricator-application-launch-create', ), $plus_icon); $classes = array(); $classes[] = 'application-tile-create'; } } $classes[] = 'phabricator-application-launch-container'; if ($this->fullWidth) { $classes[] = 'application-tile-full'; } $app_button = phutil_render_tag( $application ? 'a' : 'div', array( 'class' => implode(' ', $classes), 'href' => $application ? $application->getBaseURI() : null, 'title' => $application ? $application->getShortDescription() : null, ), $icon. $this->renderSingleView($content)); return $app_button.$create_button; } } diff --git a/src/applications/pholio/view/PholioMockImagesView.php b/src/applications/pholio/view/PholioMockImagesView.php index 47383f5918..5658fded90 100644 --- a/src/applications/pholio/view/PholioMockImagesView.php +++ b/src/applications/pholio/view/PholioMockImagesView.php @@ -1,40 +1,40 @@ mock = $mock; } public function render() { if (!$this->mock) { throw new Exception("Call setMock() before render()!"); } $image = id(new PholioImage())->loadOneWhere( "mockid=%d", $this->mock->getID()); $file = id(new PhabricatorFile())->loadOneWhere( "phid=%s", $image->getFilePHID()); - $image_tag = phutil_render_tag( + $image_tag = phutil_tag( 'img', array( 'src' => $file->getBestURI(), 'class' => 'pholio-mock-image', ), ''); - return phutil_render_tag( + return phutil_tag( 'div', array( 'class' => 'pholio-mock-image-container', ), $image_tag); } } diff --git a/src/applications/repository/controller/PhabricatorRepositoryDeleteController.php b/src/applications/repository/controller/PhabricatorRepositoryDeleteController.php index 4ab58929c9..da47f4304d 100644 --- a/src/applications/repository/controller/PhabricatorRepositoryDeleteController.php +++ b/src/applications/repository/controller/PhabricatorRepositoryDeleteController.php @@ -1,46 +1,52 @@ id = $data['id']; } public function processRequest() { $repository = id(new PhabricatorRepository())->load($this->id); if (!$repository) { return new Aphront404Response(); } $request = $this->getRequest(); if ($request->isDialogFormPost()) { return id(new AphrontRedirectResponse())->setURI('/repository/'); } $dialog = new AphrontDialogView(); $text_1 = pht('If you really want to delete the repository, you must run:'); $command = 'bin/repository delete '. phutil_escape_html($repository->getCallsign()); $text_2 = pht('Repositories touch many objects and as such deletes are '. 'prohibitively expensive to run from the web UI.'); - $body = phutil_render_tag( + $body = phutil_tag( 'div', array( 'class' => 'phabricator-remarkup', ), - '

'.$text_1.'

'.$command.'

'.$text_2.'

'); + array( + phutil_tag('p', array(), $text_1), + phutil_tag('p', array(), + phutil_tag('tt', array(), $command)), + phutil_tag('p', array(), $text_2), + )); + $dialog ->setUser($request->getUser()) ->setTitle(pht('Really want to delete the repository?')) ->appendChild($body) ->setSubmitURI('/repository/delete/'.$this->id.'/') ->addSubmitButton(pht('Okay')); return id(new AphrontDialogResponse())->setDialog($dialog); } } diff --git a/src/infrastructure/diff/view/PhabricatorInlineSummaryView.php b/src/infrastructure/diff/view/PhabricatorInlineSummaryView.php index f3aca0dc9f..2fa90c9f01 100644 --- a/src/infrastructure/diff/view/PhabricatorInlineSummaryView.php +++ b/src/infrastructure/diff/view/PhabricatorInlineSummaryView.php @@ -1,111 +1,113 @@ groups[$name])) { $this->groups[$name] = $items; } else { $this->groups[$name] = array_merge($this->groups[$name], $items); } return $this; } public function render() { require_celerity_resource('inline-comment-summary-css'); return $this->renderHeader().$this->renderTable(); } private function renderHeader() { return phutil_tag( 'div', array( 'class' => 'phabricator-inline-summary', ), 'Inline Comments'); } private function renderTable() { $rows = array(); foreach ($this->groups as $group => $items) { $has_where = false; foreach ($items as $item) { if (!empty($item['where'])) { $has_where = true; break; } } $rows[] = ''. ''. phutil_escape_html($group). ''. ''; foreach ($items as $item) { $items = isort($items, 'line'); $line = $item['line']; $length = $item['length']; if ($length) { $lines = $line."\xE2\x80\x93".($line + $length); } else { $lines = $line; } if (isset($item['href'])) { $href = $item['href']; $target = '_blank'; $tail = " \xE2\x86\x97"; } else { $href = '#inline-'.$item['id']; $target = null; $tail = null; } - $lines = phutil_escape_html($lines); if ($href) { - $lines = phutil_render_tag( + $lines = phutil_tag( 'a', array( 'href' => $href, 'target' => $target, 'class' => 'num', ), - $lines.$tail); + array( + $lines, + $tail, + )); } $where = idx($item, 'where'); $colspan = ($has_where ? '' : ' colspan="2"'); $rows[] = ''. ''.$lines.''. ($has_where ? ''. phutil_escape_html($where). '' : null). ''. '
'. $item['content']. '
'. ''. ''; } } return phutil_tag( 'table', array( 'class' => 'phabricator-inline-summary-table', ), new PhutilSafeHTML(implode("\n", $rows))); } } diff --git a/src/infrastructure/markup/rule/PhabricatorRemarkupRuleMeme.php b/src/infrastructure/markup/rule/PhabricatorRemarkupRuleMeme.php index 5b5135bc11..1254d044ad 100644 --- a/src/infrastructure/markup/rule/PhabricatorRemarkupRuleMeme.php +++ b/src/infrastructure/markup/rule/PhabricatorRemarkupRuleMeme.php @@ -1,42 +1,42 @@ null, 'above' => null, 'below' => null, ); $parser = new PhutilSimpleOptions(); $options = $parser->parse($matches[1]) + $options; $uri = id(new PhutilURI('/macro/meme/')) ->alter('macro', $options['src']) ->alter('uppertext', $options['above']) ->alter('lowertext', $options['below']); - $img = phutil_render_tag( + $img = phutil_tag( 'img', array( 'src' => (string)$uri, )); return $this->getEngine()->storeText($img); } } diff --git a/src/view/control/AphrontTableView.php b/src/view/control/AphrontTableView.php index 92be011692..ace3c7b9d1 100644 --- a/src/view/control/AphrontTableView.php +++ b/src/view/control/AphrontTableView.php @@ -1,320 +1,324 @@ data = $data; } public function setHeaders(array $headers) { $this->headers = $headers; return $this; } public function setColumnClasses(array $column_classes) { $this->columnClasses = $column_classes; return $this; } public function setRowClasses(array $row_classes) { $this->rowClasses = $row_classes; return $this; } public function setCellClasses(array $cell_classes) { $this->cellClasses = $cell_classes; return $this; } public function setNoDataString($no_data_string) { $this->noDataString = $no_data_string; return $this; } public function setClassName($class_name) { $this->className = $class_name; return $this; } public function setZebraStripes($zebra_stripes) { $this->zebraStripes = $zebra_stripes; return $this; } public function setColumnVisibility(array $visibility) { $this->columnVisibility = $visibility; return $this; } public function setDeviceVisibility(array $device_visibility) { $this->deviceVisibility = $device_visibility; return $this; } public function setDeviceReadyTable($ready) { $this->deviceReadyTable = $ready; return $this; } public function setShortHeaders(array $short_headers) { $this->shortHeaders = $short_headers; return $this; } /** * Parse a sorting parameter: * * list($sort, $reverse) = AphrontTableView::parseSortParam($sort_param); * * @param string Sort request parameter. * @return pair Sort value, sort direction. */ public static function parseSort($sort) { return array(ltrim($sort, '-'), preg_match('/^-/', $sort)); } public function makeSortable( PhutilURI $base_uri, $param, $selected, $reverse, array $sort_values) { $this->sortURI = $base_uri; $this->sortParam = $param; $this->sortSelected = $selected; $this->sortReverse = $reverse; $this->sortValues = array_values($sort_values); return $this; } public function render() { require_celerity_resource('aphront-table-view-css'); $table_class = $this->className; if ($this->deviceReadyTable) { $table_class .= ' aphront-table-view-device-ready'; } if ($table_class !== null) { $table_class = ' class="aphront-table-view '.$table_class.'"'; } else { $table_class = ' class="aphront-table-view"'; } $table = array(''); $col_classes = array(); foreach ($this->columnClasses as $key => $class) { if (strlen($class)) { $col_classes[] = $class; } else { $col_classes[] = null; } } $visibility = array_values($this->columnVisibility); $device_visibility = array_values($this->deviceVisibility); $headers = $this->headers; $short_headers = $this->shortHeaders; $sort_values = $this->sortValues; if ($headers) { while (count($headers) > count($visibility)) { $visibility[] = true; } while (count($headers) > count($device_visibility)) { $device_visibility[] = true; } while (count($headers) > count($short_headers)) { $short_headers[] = null; } while (count($headers) > count($sort_values)) { $sort_values[] = null; } $table[] = ''; foreach ($headers as $col_num => $header) { if (!$visibility[$col_num]) { continue; } $classes = array(); if (!empty($col_classes[$col_num])) { $classes[] = $col_classes[$col_num]; } if (empty($device_visiblity[$col_num])) { $classes[] = 'aphront-table-nodevice'; } if ($sort_values[$col_num] !== null) { $classes[] = 'aphront-table-view-sortable'; $sort_value = $sort_values[$col_num]; $sort_glyph_class = 'aphront-table-down-sort'; if ($sort_value == $this->sortSelected) { if ($this->sortReverse) { $sort_glyph_class = 'aphront-table-up-sort'; } else if (!$this->sortReverse) { $sort_value = '-'.$sort_value; } $classes[] = 'aphront-table-view-sortable-selected'; } $sort_glyph = phutil_tag( 'span', array( 'class' => $sort_glyph_class, ), ''); - $header = phutil_render_tag( + $header = phutil_tag( 'a', array( 'href' => $this->sortURI->alter($this->sortParam, $sort_value), 'class' => 'aphront-table-view-sort-link', ), - $header.' '.$sort_glyph); + array( + $header, + ' ', + $sort_glyph, + )); } if ($classes) { $class = ' class="'.implode(' ', $classes).'"'; } else { $class = null; } if ($short_headers[$col_num] !== null) { - $header_nodevice = phutil_render_tag( + $header_nodevice = phutil_tag( 'span', array( 'class' => 'aphront-table-view-nodevice', ), $header); $header_device = phutil_tag( 'span', array( 'class' => 'aphront-table-view-device', ), $short_headers[$col_num]); $header = $header_nodevice.$header_device; } $table[] = ''.$header.''; } $table[] = ''; } foreach ($col_classes as $key => $value) { if (($sort_values[$key] !== null) && ($sort_values[$key] == $this->sortSelected)) { $value = trim($value.' sorted-column'); } if ($value !== null) { $col_classes[$key] = $value; } } $data = $this->data; if ($data) { $row_num = 0; foreach ($data as $row) { while (count($row) > count($col_classes)) { $col_classes[] = null; } while (count($row) > count($visibility)) { $visibility[] = true; } $class = idx($this->rowClasses, $row_num); if ($this->zebraStripes && ($row_num % 2)) { if ($class !== null) { $class = 'alt alt-'.$class; } else { $class = 'alt'; } } if ($class !== null) { $class = ' class="'.$class.'"'; } $table[] = ''; // NOTE: Use of a separate column counter is to allow this to work // correctly if the row data has string or non-sequential keys. $col_num = 0; foreach ($row as $value) { if (!$visibility[$col_num]) { ++$col_num; continue; } $class = $col_classes[$col_num]; if (!empty($this->cellClasses[$row_num][$col_num])) { $class = trim($class.' '.$this->cellClasses[$row_num][$col_num]); } if ($class !== null) { $table[] = ''; } else { $table[] = ''; } $table[] = $value.''; ++$col_num; } ++$row_num; } } else { $colspan = max(count(array_filter($visibility)), 1); $table[] = ''. coalesce($this->noDataString, 'No data available.'). ''; } $table[] = ''; $html = implode('', $table); return '
'.$html.'
'; } public static function renderSingleDisplayLine($line) { // TODO: Is there a cleaner way to do this? We use a relative div with // overflow hidden to provide the bounds, and an absolute span with // white-space: pre to prevent wrapping. We need to append a character // (  -- nonbreaking space) afterward to give the bounds div height // (alternatively, we could hard-code the line height). This is gross but // it's not clear that there's a better appraoch. return phutil_tag( 'div', array( 'class' => 'single-display-line-bounds', ), phutil_render_tag( 'span', array( 'class' => 'single-display-line-content', ), $line).' '); } } diff --git a/src/view/control/PhabricatorObjectSelectorDialog.php b/src/view/control/PhabricatorObjectSelectorDialog.php index 8361642f67..db60a6ba7c 100644 --- a/src/view/control/PhabricatorObjectSelectorDialog.php +++ b/src/view/control/PhabricatorObjectSelectorDialog.php @@ -1,191 +1,191 @@ user = $user; return $this; } public function setFilters(array $filters) { $this->filters = $filters; return $this; } public function setSelectedFilter($selected_filter) { $this->selectedFilter = $selected_filter; return $this; } public function setExcluded($excluded_phid) { $this->excluded = $excluded_phid; return $this; } public function setHandles(array $handles) { assert_instances_of($handles, 'PhabricatorObjectHandle'); $this->handles = $handles; return $this; } public function setCancelURI($cancel_uri) { $this->cancelURI = $cancel_uri; return $this; } public function setSubmitURI($submit_uri) { $this->submitURI = $submit_uri; return $this; } public function setSearchURI($search_uri) { $this->searchURI = $search_uri; return $this; } public function setTitle($title) { $this->title = $title; return $this; } public function setHeader($header) { $this->header = $header; return $this; } public function setButtonText($button_text) { $this->buttonText = $button_text; return $this; } public function setInstructions($instructions) { $this->instructions = $instructions; return $this; } public function buildDialog() { $user = $this->user; $filter_id = celerity_generate_unique_node_id(); $query_id = celerity_generate_unique_node_id(); $results_id = celerity_generate_unique_node_id(); $current_id = celerity_generate_unique_node_id(); $search_id = celerity_generate_unique_node_id(); $form_id = celerity_generate_unique_node_id(); require_celerity_resource('phabricator-object-selector-css'); $options = array(); foreach ($this->filters as $key => $label) { - $options[] = phutil_render_tag( + $options[] = phutil_tag( 'option', array( 'value' => $key, 'selected' => ($key == $this->selectedFilter) ? 'selected' : null, ), $label); } $options = implode("\n", $options); $instructions = null; if ($this->instructions) { $instructions = '

'. $this->instructions. '

'; } $search_box = phabricator_render_form( $user, array( 'method' => 'POST', 'action' => $this->submitURI, 'id' => $search_id, ), ''); $result_box = '
'. '
'; $attached_box = '
'. '
'. '
'. phutil_escape_html($this->header). '
'. '
'. '
'. $instructions. '
'. '
'; $dialog = new AphrontDialogView(); $dialog ->setUser($this->user) ->setTitle($this->title) ->setClass('phabricator-object-selector-dialog') ->appendChild($search_box) ->appendChild($result_box) ->appendChild($attached_box) ->setRenderDialogAsDiv() ->setFormID($form_id) ->addSubmitButton($this->buttonText); if ($this->cancelURI) { $dialog->addCancelButton($this->cancelURI); } $handle_views = array(); foreach ($this->handles as $handle) { $phid = $handle->getPHID(); $view = new PhabricatorHandleObjectSelectorDataView($handle); $handle_views[$phid] = $view->renderData(); } $dialog->addHiddenInput('phids', implode(';', array_keys($this->handles))); Javelin::initBehavior( 'phabricator-object-selector', array( 'filter' => $filter_id, 'query' => $query_id, 'search' => $search_id, 'results' => $results_id, 'current' => $current_id, 'form' => $form_id, 'exclude' => $this->excluded, 'uri' => $this->searchURI, 'handles' => $handle_views, )); return $dialog; } } diff --git a/src/view/page/PhabricatorStandardPageView.php b/src/view/page/PhabricatorStandardPageView.php index 02883bb2ac..b1ce431b13 100644 --- a/src/view/page/PhabricatorStandardPageView.php +++ b/src/view/page/PhabricatorStandardPageView.php @@ -1,362 +1,362 @@ applicationMenu = $application_menu; return $this; } public function getApplicationMenu() { return $this->applicationMenu; } public function setApplicationName($application_name) { $this->applicationName = $application_name; return $this; } public function setDisableConsole($disable) { $this->disableConsole = $disable; return $this; } public function getApplicationName() { return $this->applicationName; } public function setBaseURI($base_uri) { $this->baseURI = $base_uri; return $this; } public function getBaseURI() { return $this->baseURI; } public function setShowChrome($show_chrome) { $this->showChrome = $show_chrome; return $this; } public function getShowChrome() { return $this->showChrome; } public function setSearchDefaultScope($search_default_scope) { $this->searchDefaultScope = $search_default_scope; return $this; } public function getSearchDefaultScope() { return $this->searchDefaultScope; } public function appendPageObjects(array $objs) { foreach ($objs as $obj) { $this->pageObjects[] = $obj; } } public function getTitle() { $use_glyph = true; $request = $this->getRequest(); if ($request) { $user = $request->getUser(); if ($user && $user->loadPreferences()->getPreference( PhabricatorUserPreferences::PREFERENCE_TITLES) !== 'glyph') { $use_glyph = false; } } return ($use_glyph ? $this->getGlyph() : '['.$this->getApplicationName().']'). ' '.parent::getTitle(); } protected function willRenderPage() { parent::willRenderPage(); if (!$this->getRequest()) { throw new Exception( "You must set the Request to render a PhabricatorStandardPageView."); } $console = $this->getConsole(); require_celerity_resource('phabricator-core-css'); require_celerity_resource('phabricator-zindex-css'); require_celerity_resource('phabricator-core-buttons-css'); require_celerity_resource('sprite-gradient-css'); require_celerity_resource('phabricator-standard-page-view'); Javelin::initBehavior('workflow', array()); $current_token = null; $request = $this->getRequest(); if ($request) { $user = $request->getUser(); if ($user) { $current_token = $user->getCSRFToken(); $download_form = phabricator_render_form_magic($user); $default_img_uri = PhabricatorEnv::getCDNURI( '/rsrc/image/icon/fatcow/document_black.png' ); Javelin::initBehavior( 'lightbox-attachments', array( 'defaultImageUri' => $default_img_uri, 'downloadForm' => $download_form, )); } } Javelin::initBehavior('toggle-class', array()); Javelin::initBehavior('konami', array()); Javelin::initBehavior( 'refresh-csrf', array( 'tokenName' => AphrontRequest::getCSRFTokenName(), 'header' => AphrontRequest::getCSRFHeaderName(), 'current' => $current_token, )); Javelin::initBehavior('device'); if ($console) { require_celerity_resource('aphront-dark-console-css'); Javelin::initBehavior( 'dark-console', array( 'uri' => '/~/', 'request_uri' => $request ? (string) $request->getRequestURI() : '/', )); // Change this to initBehavior when there is some behavior to initialize require_celerity_resource('javelin-behavior-error-log'); } $menu = id(new PhabricatorMainMenuView()) ->setUser($request->getUser()) ->setDefaultSearchScope($this->getSearchDefaultScope()); if ($this->getController()) { $menu->setController($this->getController()); } if ($this->getApplicationMenu()) { $menu->setApplicationMenu($this->getApplicationMenu()); } $this->menuContent = $menu->render(); } protected function getHead() { $monospaced = PhabricatorEnv::getEnvConfig('style.monospace'); $request = $this->getRequest(); if ($request) { $user = $request->getUser(); if ($user) { $monospaced = nonempty( $user->loadPreferences()->getPreference( PhabricatorUserPreferences::PREFERENCE_MONOSPACED), $monospaced); } } $response = CelerityAPI::getStaticResourceResponse(); $head = array( parent::getHead(), '', $response->renderSingleResource('javelin-magical-init'), ); return implode("\n", $head); } public function setGlyph($glyph) { $this->glyph = $glyph; return $this; } public function getGlyph() { return $this->glyph; } protected function willSendResponse($response) { $response = parent::willSendResponse($response); $console = $this->getRequest()->getApplicationConfiguration()->getConsole(); if ($console) { $response = str_replace( '', $console->render($this->getRequest()), $response); } return $response; } protected function getBody() { $console = $this->getConsole(); $user = null; $request = $this->getRequest(); if ($request) { $user = $request->getUser(); } $header_chrome = null; if ($this->getShowChrome()) { $header_chrome = $this->menuContent; } $developer_warning = null; if (PhabricatorEnv::getEnvConfig('phabricator.show-error-callout') && DarkConsoleErrorLogPluginAPI::getErrors()) { $developer_warning = '
'. pht( 'This page raised PHP errors. Find them in DarkConsole '. 'or the error log.'). '
'; } // Render the "you have unresolved setup issues..." warning. $setup_warning = null; if ($user && $user->getIsAdmin()) { $open = PhabricatorSetupCheck::getOpenSetupIssueCount(); if ($open) { - $setup_warning = phutil_render_tag( + $setup_warning = phutil_tag( 'div', array( 'class' => 'setup-warning-callout', ), - phutil_render_tag( + phutil_tag( 'a', array( 'href' => '/config/issue/', ), pht('You have %d unresolved setup issue(s)...', $open))); } } return phutil_render_tag( 'div', array( 'id' => 'base-page', 'class' => 'phabricator-standard-page', ), $developer_warning. $setup_warning. $header_chrome. '
'. ($console ? '' : null). parent::getBody(). '
'. '
'); } protected function getTail() { $request = $this->getRequest(); $user = $request->getUser(); $container = null; if ($user->isLoggedIn()) { $aphlict_object_id = celerity_generate_unique_node_id(); $aphlict_container_id = celerity_generate_unique_node_id(); $client_uri = PhabricatorEnv::getEnvConfig('notification.client-uri'); $client_uri = new PhutilURI($client_uri); if ($client_uri->getDomain() == 'localhost') { $this_host = $this->getRequest()->getHost(); $this_host = new PhutilURI('http://'.$this_host.'/'); $client_uri->setDomain($this_host->getDomain()); } $enable_debug = PhabricatorEnv::getEnvConfig('notification.debug'); Javelin::initBehavior( 'aphlict-listen', array( 'id' => $aphlict_object_id, 'containerID' => $aphlict_container_id, 'server' => $client_uri->getDomain(), 'port' => $client_uri->getPort(), 'debug' => $enable_debug, 'pageObjects' => array_fill_keys($this->pageObjects, true), )); $container = phutil_tag( 'div', array( 'id' => $aphlict_container_id, 'style' => 'position: absolute; width: 0; height: 0;', ), ''); } $response = CelerityAPI::getStaticResourceResponse(); $tail = array( parent::getTail(), $container, $response->renderHTMLFooter(), ); return implode("\n", $tail); } protected function getBodyClasses() { $classes = array(); if (!$this->getShowChrome()) { $classes[] = 'phabricator-chromeless-page'; } $agent = idx($_SERVER, 'HTTP_USER_AGENT'); // Try to guess the device resolution based on UA strings to avoid a flash // of incorrectly-styled content. $device_guess = 'device-desktop'; if (preg_match('@iPhone|iPod|(Android.*Chrome/[.0-9]* Mobile)@', $agent)) { $device_guess = 'device-phone device'; } else if (preg_match('@iPad|(Android.*Chrome/)@', $agent)) { $device_guess = 'device-tablet device'; } $classes[] = $device_guess; return implode(' ', $classes); } private function getConsole() { if ($this->disableConsole) { return null; } return $this->getRequest()->getApplicationConfiguration()->getConsole(); } }