public function handleRequest(AphrontRequest $request) { $viewer = $request->getViewer(); $keys = $request->getStr('keys'); try { $keys = phutil_json_decode($keys); } catch (PhutilJSONParserException $ex) { return new Aphront400Response(); } // There have been at least two users asking for a keyboard shortcut to // close the dialog, so be explicit that escape works since it isn't // terribly discoverable. $keys[] = array('keys' => array('esc'), 'description' => pht('Close any dialog, including this one.')); $stroke_map = array('left' => "←", 'right' => "→", 'up' => "↑", 'down' => "↓", 'return' => "⏎", 'tab' => "⇥", 'delete' => "⌫"); $rows = array(); foreach ($keys as $shortcut) { $keystrokes = array(); foreach ($shortcut['keys'] as $stroke) { $stroke = idx($stroke_map, $stroke, $stroke); $keystrokes[] = phutil_tag('kbd', array(), $stroke); } $keystrokes = phutil_implode_html(' or ', $keystrokes); $rows[] = phutil_tag('tr', array(), array(phutil_tag('th', array(), $keystrokes), phutil_tag('td', array(), $shortcut['description']))); } $table = phutil_tag('table', array('class' => 'keyboard-shortcut-help'), $rows); return $this->newDialog()->setTitle(pht('Keyboard Shortcuts'))->appendChild($table)->addCancelButton('#', pht('Close')); }
public function processRequest() { $root = dirname(phutil_get_library_root('phabricator')); require_once $root . '/support/phame/libskin.php'; $this->cssResources = array(); $css = $this->getPath('css/'); if (Filesystem::pathExists($css)) { foreach (Filesystem::listDirectory($css) as $path) { if (!preg_match('/.css$/', $path)) { continue; } $this->cssResources[] = phutil_tag('link', array('rel' => 'stylesheet', 'type' => 'text/css', 'href' => $this->getResourceURI('css/' . $path))); } } $map = CelerityResourceMap::getNamedInstance('phabricator'); $resource_symbol = 'syntax-highlighting-css'; $resource_uri = $map->getURIForSymbol($resource_symbol); $this->cssResources[] = phutil_tag('link', array('rel' => 'stylesheet', 'type' => 'text/css', 'href' => PhabricatorEnv::getCDNURI($resource_uri))); $this->cssResources = phutil_implode_html("\n", $this->cssResources); $request = $this->getRequest(); // Render page parts in order so the templates execute in order, if we're // using templates. $header = $this->renderHeader(); $content = $this->renderContent($request); $footer = $this->renderFooter(); if (!$content) { $content = $this->render404Page(); } $content = array($header, $content, $footer); $response = new AphrontWebpageResponse(); $response->setContent(phutil_implode_html("\n", $content)); return $response; }
public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); $inlines = $this->loadInlineComments(); assert_instances_of($inlines, 'PhabricatorInlineCommentInterface'); $engine = new PhabricatorMarkupEngine(); $engine->setViewer($user); foreach ($inlines as $inline) { $engine->addObject($inline, PhabricatorInlineCommentInterface::MARKUP_FIELD_BODY); } $engine->process(); $phids = array($user->getPHID()); $handles = $this->loadViewerHandles($phids); $views = array(); foreach ($inlines as $inline) { $view = new DifferentialInlineCommentView(); $view->setInlineComment($inline); $view->setMarkupEngine($engine); $view->setHandles($handles); $view->setEditable(false); $view->setPreview(true); $views[] = $view->render(); } $views = phutil_implode_html("\n", $views); return id(new AphrontAjaxResponse())->setContent($views); }
public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); $document = id(new PhrictionDocumentQuery())->setViewer($user)->withIDs(array($this->id))->needContent(true)->requireCapabilities(array(PhabricatorPolicyCapability::CAN_EDIT, PhabricatorPolicyCapability::CAN_VIEW))->executeOne(); if (!$document) { return new Aphront404Response(); } $document_uri = PhrictionDocument::getSlugURI($document->getSlug()); $e_text = null; if ($request->isFormPost()) { $xactions = array(); $xactions[] = id(new PhrictionTransaction())->setTransactionType(PhrictionTransaction::TYPE_DELETE)->setNewValue(true); $editor = id(new PhrictionTransactionEditor())->setActor($user)->setContentSourceFromRequest($request)->setContinueOnNoEffect(true); try { $editor->applyTransactions($document, $xactions); return id(new AphrontRedirectResponse())->setURI($document_uri); } catch (PhabricatorApplicationTransactionValidationException $ex) { $e_text = phutil_implode_html("\n", $ex->getErrorMessages()); } } if ($e_text) { $dialog = id(new AphrontDialogView())->setUser($user)->setTitle(pht('Can Not Delete Document!'))->appendChild($e_text)->addCancelButton($document_uri); } else { $dialog = id(new AphrontDialogView())->setUser($user)->setTitle(pht('Delete Document?'))->appendChild(pht('Really delete this document? You can recover it later by ' . 'reverting to a previous version.'))->addSubmitButton(pht('Delete'))->addCancelButton($document_uri); } return id(new AphrontDialogResponse())->setDialog($dialog); }
public function render() { if ($this->header !== null) { $header = phutil_tag('h1', array(), $this->header); } else { $header = null; } if ($this->caption !== null) { $caption = phutil_tag_div('aphront-panel-view-caption', $this->caption); } else { $caption = null; } $buttons = null; if ($this->buttons) { $buttons = phutil_tag_div('aphront-panel-view-buttons', phutil_implode_html(' ', $this->buttons)); } $header_elements = phutil_tag_div('aphront-panel-header', array($buttons, $header, $caption)); $table = phutil_implode_html('', $this->renderChildren()); require_celerity_resource('aphront-panel-view-css'); $classes = $this->classes; $classes[] = 'aphront-panel-view'; if ($this->width) { $classes[] = 'aphront-panel-width-' . $this->width; } return phutil_tag('div', array('class' => implode(' ', $classes), 'id' => $this->id), array($header_elements, $table)); }
private function getRevisionMatchExplanation($revision_match_data, PhabricatorObjectHandle $obj_handle) { if (!$revision_match_data) { return pht('This commit was made before this feature was built and thus this ' . 'information is unavailable.'); } $body_why = array(); if ($revision_match_data['usedURI']) { return pht('We found a "%s" field with value "%s" in the commit message, ' . 'and the domain on the URI matches this install, so ' . 'we linked this commit to %s.', 'Differential Revision', $revision_match_data['foundURI'], phutil_tag('a', array('href' => $obj_handle->getURI()), $obj_handle->getName())); } else { if ($revision_match_data['foundURI']) { $body_why[] = pht('We found a "%s" field with value "%s" in the commit message, ' . 'but the domain on this URI did not match the configured ' . 'domain for this install, "%s", so we ignored it under ' . 'the assumption that it refers to some third-party revision.', 'Differential Revision', $revision_match_data['foundURI'], $revision_match_data['validDomain']); } else { $body_why[] = pht('We didn\'t find a "%s" field in the commit message.', 'Differential Revision'); } } switch ($revision_match_data['matchHashType']) { case ArcanistDifferentialRevisionHash::HASH_GIT_TREE: $hash_info = true; $hash_type = 'tree'; break; case ArcanistDifferentialRevisionHash::HASH_GIT_COMMIT: case ArcanistDifferentialRevisionHash::HASH_MERCURIAL_COMMIT: $hash_info = true; $hash_type = 'commit'; break; default: $hash_info = false; break; } if ($hash_info) { $diff_link = phutil_tag('a', array('href' => $obj_handle->getURI()), $obj_handle->getName()); $body_why = pht('This commit and the active diff of %s had the same %s hash ' . '(%s) so we linked this commit to %s.', $diff_link, $hash_type, $revision_match_data['matchHashValue'], $diff_link); } return phutil_implode_html("\n", $body_why); }
protected function getTagContent() { require_celerity_resource('ponder-view-css'); $answer = $this->answer; $viewer = $this->getUser(); $status = $answer->getStatus(); $author_phid = $answer->getAuthorPHID(); $actions = $this->buildAnswerActions(); $handle = $this->handle; $id = $answer->getID(); if ($status == PonderAnswerStatus::ANSWER_STATUS_HIDDEN) { $can_edit = PhabricatorPolicyFilter::hasCapability($viewer, $answer, PhabricatorPolicyCapability::CAN_EDIT); $message = array(); $message[] = phutil_tag('em', array(), pht('This answer has been hidden.')); if ($can_edit) { $message[] = phutil_tag('a', array('href' => "/ponder/answer/edit/{$id}/"), pht('Edit Answer')); } $message = phutil_implode_html(' ', $message); return id(new PHUIInfoView())->setSeverity(PHUIInfoView::SEVERITY_NODATA)->appendChild($message); } $action_button = id(new PHUIButtonView())->setTag('a')->setText(pht('Actions'))->setHref('#')->setIcon('fa-bars')->setDropdownMenu($actions); $header_name = phutil_tag('a', array('href' => $handle->getURI()), $handle->getName()); $header = id(new PHUIHeaderView())->setUser($viewer)->setEpoch($answer->getDateModified())->setHeader($header_name)->addActionLink($action_button)->setImage($handle->getImageURI())->setImageURL($handle->getURI()); $content = phutil_tag('div', array('class' => 'phabricator-remarkup'), PhabricatorMarkupEngine::renderOneObject($answer, $answer->getMarkupField(), $viewer)); $anchor = id(new PhabricatorAnchorView())->setAnchorName("A{$id}"); $content_id = celerity_generate_unique_node_id(); $footer = id(new PonderFooterView())->setContentID($content_id)->setCount(count($this->transactions)); $content = phutil_tag_div('ponder-answer-content', array($anchor, $content, $footer)); $answer_view = id(new PHUIObjectBoxView())->setHeader($header)->setBackground(PHUIObjectBoxView::GREY)->addClass('ponder-answer')->appendChild($content); $comment_view = id(new PhabricatorApplicationTransactionCommentView())->setUser($viewer)->setObjectPHID($answer->getPHID())->setShowPreview(false)->setHeaderText(pht('Answer Comment'))->setAction("/ponder/answer/comment/{$id}/")->setSubmitButtonName(pht('Comment')); $hidden_view = phutil_tag('div', array('id' => $content_id, 'style' => 'display: none;'), array($this->timeline, $comment_view)); return array($answer_view, $hidden_view); }
public function render() { require_celerity_resource('phabricator-source-code-view-css'); require_celerity_resource('syntax-highlighting-css'); Javelin::initBehavior('phabricator-oncopy', array()); $line_number = $this->start; $rows = array(); foreach ($this->lines as $line) { $hit_limit = $this->limit && $line_number == $this->limit && count($this->lines) != $this->limit; if ($hit_limit) { $content_number = ''; $content_line = phutil_tag('span', array('class' => 'c'), pht('...')); } else { $content_number = $line_number; $content_line = $line; } $row_attributes = array(); if (isset($this->highlights[$line_number])) { $row_attributes['class'] = 'phabricator-source-highlight'; } // TODO: Provide nice links. $th = phutil_tag('th', array('class' => 'phabricator-source-line', 'style' => 'background-color: #fff;'), $content_number); $td = phutil_tag('td', array('class' => 'phabricator-source-code'), $content_line); $rows[] = phutil_tag('tr', $row_attributes, array($th, $td)); if ($hit_limit) { break; } $line_number++; } $classes = array(); $classes[] = 'phabricator-source-code-view'; $classes[] = 'remarkup-code'; $classes[] = 'PhabricatorMonospaced'; return phutil_tag('div', array('class' => 'phabricator-source-code-container', 'style' => 'background-color: black; color: white;'), phutil_tag('table', array('class' => implode(' ', $classes), 'style' => 'background-color: black'), phutil_implode_html('', $rows))); }
public function renderPanel() { $data = $this->getData(); $sections = array('Basics' => array('Machine' => php_uname('n'))); // NOTE: This may not be present for some SAPIs, like php-fpm. if (!empty($data['Server']['SERVER_ADDR'])) { $addr = $data['Server']['SERVER_ADDR']; $sections['Basics']['Host'] = $addr; $sections['Basics']['Hostname'] = @gethostbyaddr($addr); } $sections = array_merge($sections, $data); $mask = array('HTTP_COOKIE' => true, 'HTTP_X_PHABRICATOR_CSRF' => true); $out = array(); foreach ($sections as $header => $map) { $rows = array(); foreach ($map as $key => $value) { if (isset($mask[$key])) { $rows[] = array($key, phutil_tag('em', array(), '(Masked)')); } else { $rows[] = array($key, is_array($value) ? json_encode($value) : $value); } } $table = new AphrontTableView($rows); $table->setHeaders(array($header, null)); $table->setColumnClasses(array('header', 'wide wrap')); $out[] = $table->render(); } return phutil_implode_html("\n", $out); }
public function markupNavigation(array $matches) { if (!$this->isFlatText($matches[0])) { return $matches[0]; } $elements = ltrim($matches[1], ", \n"); $elements = explode('>', $elements); $defaults = array('name' => null, 'type' => 'link', 'href' => null, 'icon' => null); $sequence = array(); $parser = new PhutilSimpleOptions(); foreach ($elements as $element) { if (strpos($element, '=') === false) { $sequence[] = array('name' => trim($element)) + $defaults; } else { $sequence[] = $parser->parse($element) + $defaults; } } if ($this->getEngine()->isTextMode()) { return implode(' > ', ipull($sequence, 'name')); } static $icon_names; if (!$icon_names) { $icon_names = array_fuse(PHUIIconView::getIcons()); } $out = array(); foreach ($sequence as $item) { $item_name = $item['name']; $item_color = PHUITagView::COLOR_GREY; if ($item['type'] == 'instructions') { $item_name = phutil_tag('em', array(), $item_name); $item_color = PHUITagView::COLOR_INDIGO; } $tag = id(new PHUITagView())->setType(PHUITagView::TYPE_SHADE)->setShade($item_color)->setName($item_name); if ($item['icon']) { $icon_name = 'fa-' . $item['icon']; if (isset($icon_names[$icon_name])) { $tag->setIcon($icon_name); } } if ($item['href'] !== null) { if (PhabricatorEnv::isValidRemoteURIForLink($item['href'])) { $tag->setHref($item['href']); $tag->setExternal(true); } } $out[] = $tag; } if ($this->getEngine()->isHTMLMailMode()) { $arrow_attr = array('style' => 'color: #92969D;'); $nav_attr = array(); } else { $arrow_attr = array('class' => 'remarkup-nav-sequence-arrow'); $nav_attr = array('class' => 'remarkup-nav-sequence'); } $joiner = phutil_tag('span', $arrow_attr, " → "); $out = phutil_implode_html($joiner, $out); $out = phutil_tag('span', $nav_attr, $out); return $this->getEngine()->storeText($out); }
public function renderThreadsHTML() { $thread_html = array(); foreach ($this->threads as $thread) { $thread_html[] = $this->renderSingleThread($thread); } return phutil_implode_html('', $thread_html); }
/** * Implodes selected handles from a pool of handles. Useful if you load handles * for various phids, but only render a few of them at a time. * * @return PhutilSafeHTML */ function implode_selected_handle_links($glue, array $handles, array $phids) { $items = array(); foreach ($phids as $phid) { $items[] = $handles[$phid]->renderLink(); } return phutil_implode_html($glue, $items); }
private function buildClusterNotificationStatus() { $viewer = $this->getViewer(); $servers = PhabricatorNotificationServerRef::newRefs(); Javelin::initBehavior('phabricator-tooltips'); $rows = array(); foreach ($servers as $server) { if ($server->isAdminServer()) { $type_icon = 'fa-database sky'; $type_tip = pht('Admin Server'); } else { $type_icon = 'fa-bell sky'; $type_tip = pht('Client Server'); } $type_icon = id(new PHUIIconView())->setIcon($type_icon)->addSigil('has-tooltip')->setMetadata(array('tip' => $type_tip)); $messages = array(); $details = array(); if ($server->isAdminServer()) { try { $details = $server->loadServerStatus(); $status_icon = 'fa-exchange green'; $status_label = pht('Version %s', idx($details, 'version')); } catch (Exception $ex) { $status_icon = 'fa-times red'; $status_label = pht('Connection Error'); $messages[] = $ex->getMessage(); } } else { try { $server->testClient(); $status_icon = 'fa-exchange green'; $status_label = pht('Connected'); } catch (Exception $ex) { $status_icon = 'fa-times red'; $status_label = pht('Connection Error'); $messages[] = $ex->getMessage(); } } if ($details) { $uptime = idx($details, 'uptime'); $uptime = $uptime / 1000; $uptime = phutil_format_relative_time_detailed($uptime); $clients = pht('%s Active / %s Total', new PhutilNumber(idx($details, 'clients.active')), new PhutilNumber(idx($details, 'clients.total'))); $stats = pht('%s In / %s Out', new PhutilNumber(idx($details, 'messages.in')), new PhutilNumber(idx($details, 'messages.out'))); } else { $uptime = null; $clients = null; $stats = null; } $status_view = array(id(new PHUIIconView())->setIcon($status_icon), ' ', $status_label); $messages = phutil_implode_html(phutil_tag('br'), $messages); $rows[] = array($type_icon, $server->getProtocol(), $server->getHost(), $server->getPort(), $status_view, $uptime, $clients, $stats, $messages); } $table = id(new AphrontTableView($rows))->setNoDataString(pht('No notification servers are configured.'))->setHeaders(array(null, pht('Proto'), pht('Host'), pht('Port'), pht('Status'), pht('Uptime'), pht('Clients'), pht('Messages'), null))->setColumnClasses(array(null, null, null, null, null, null, null, null, 'wide')); $doc_href = PhabricatorEnv::getDoclink('Cluster: Notifications'); $header = id(new PHUIHeaderView())->setHeader(pht('Cluster Notification Status'))->addActionLink(id(new PHUIButtonView())->setIcon('fa-book')->setHref($doc_href)->setTag('a')->setText(pht('Documentation'))); return id(new PHUIObjectBoxView())->setHeader($header)->setTable($table); }
public function markupText($text, $children) { $text = preg_replace('/%%%\\s*$/', '', substr($text, 3)); if ($this->getEngine()->isTextMode()) { return $text; } $text = phutil_split_lines($text, $retain_endings = true); return phutil_implode_html(phutil_tag('br', array()), $text); }
public function renderPropertyViewValue(array $handles) { $value = $this->getFieldValue(); if (!$value) { return null; } $handles = mpull($handles, 'renderLink'); $handles = phutil_implode_html(', ', $handles); return $handles; }
private function buildResources() { $css = array('application/config/config-template.css', 'application/config/setup-issue.css'); $webroot = dirname(phutil_get_library_root('phabricator')) . '/webroot/'; $resources = array(); foreach ($css as $path) { $resources[] = phutil_tag('style', array('type' => 'text/css'), phutil_safe_html(Filesystem::readFile($webroot . '/rsrc/css/' . $path))); } return phutil_implode_html("\n", $resources); }
private function buildResources() { $paths = $this->getResources(); $webroot = dirname(phutil_get_library_root('phabricator')) . '/webroot/'; $resources = array(); foreach ($paths as $path) { $resources[] = phutil_tag('style', array('type' => 'text/css'), phutil_safe_html(Filesystem::readFile($webroot . '/rsrc/' . $path))); } return phutil_implode_html("\n", $resources); }
public function markupKeystrokes(array $matches) { if (!$this->isFlatText($matches[0])) { return $matches[0]; } $keys = explode(' ', $matches[1]); foreach ($keys as $k => $v) { $v = trim($v, " \n"); $v = preg_replace('/\\\\(.)/', '\\1', $v); if (!strlen($v)) { unset($keys[$k]); continue; } $keys[$k] = $v; } $special = array(array('name' => pht('Command'), 'symbol' => "⌘", 'aliases' => array('cmd', 'command')), array('name' => pht('Option'), 'symbol' => "⌥", 'aliases' => array('opt', 'option')), array('name' => pht('Shift'), 'symbol' => "⇧", 'aliases' => array('shift')), array('name' => pht('Escape'), 'symbol' => "⎋", 'aliases' => array('esc', 'escape')), array('name' => pht('Up'), 'symbol' => "↑", 'heavy' => "⬆", 'aliases' => array('up', 'arrow-up', 'up-arrow', 'north')), array('name' => pht('Tab'), 'symbol' => "⇥", 'aliases' => array('tab')), array('name' => pht('Right'), 'symbol' => "→", 'heavy' => "➡", 'aliases' => array('right', 'right-arrow', 'arrow-right', 'east')), array('name' => pht('Left'), 'symbol' => "←", 'heavy' => "⬅", 'aliases' => array('left', 'left-arrow', 'arrow-left', 'west')), array('name' => pht('Down'), 'symbol' => "↓", 'heavy' => "⬇", 'aliases' => array('down', 'down-arrow', 'arrow-down', 'south')), array('name' => pht('Up Right'), 'symbol' => "↗", 'heavy' => "⬈", 'aliases' => array('up-right', 'upright', 'up-right-arrow', 'upright-arrow', 'arrow-up-right', 'arrow-upright', 'northeast', 'north-east')), array('name' => pht('Down Right'), 'symbol' => "↘", 'heavy' => "⬊", 'aliases' => array('down-right', 'downright', 'down-right-arrow', 'downright-arrow', 'arrow-down-right', 'arrow-downright', 'southeast', 'south-east')), array('name' => pht('Down Left'), 'symbol' => "↙", 'heavy' => "⬋", 'aliases' => array('down-left', 'downleft', 'down-left-arrow', 'downleft-arrow', 'arrow-down-left', 'arrow-downleft', 'southwest', 'south-west')), array('name' => pht('Up Left'), 'symbol' => "↖", 'heavy' => "⬉", 'aliases' => array('up-left', 'upleft', 'up-left-arrow', 'upleft-arrow', 'arrow-up-left', 'arrow-upleft', 'northwest', 'north-west'))); $map = array(); foreach ($special as $spec) { foreach ($spec['aliases'] as $alias) { $map[$alias] = $spec; } } $is_text = $this->getEngine()->isTextMode(); $is_html_mail = $this->getEngine()->isHTMLMailMode(); if ($is_html_mail) { $key_style = array('display: inline-block;', 'min-width: 1em;', 'padding: 4px 5px 5px;', 'font-weight: normal;', 'font-size: 0.8rem;', 'text-align: center;', 'text-decoration: none;', 'line-height: 0.6rem;', 'border-radius: 3px;', 'box-shadow: inset 0 -1px 0 rgba(71, 87, 120, 0.08);', 'user-select: none;', 'background: #f7f7f7;', 'border: 1px solid #C7CCD9;'); $key_style = implode(' ', $key_style); $join_style = array('padding: 0 4px;', 'color: #92969D;'); $join_style = implode(' ', $join_style); } else { $key_style = null; $join_style = null; } $parts = array(); foreach ($keys as $k => $v) { $normal = phutil_utf8_strtolower($v); if (isset($map[$normal])) { $spec = $map[$normal]; } else { $spec = array('name' => null, 'symbol' => $v); } if ($is_text) { $parts[] = '[' . $spec['symbol'] . ']'; } else { $parts[] = phutil_tag('kbd', array('title' => $spec['name'], 'style' => $key_style), $spec['symbol']); } } if ($is_text) { $parts = implode(' + ', $parts); } else { $glue = phutil_tag('span', array('class' => 'kbd-join', 'style' => $join_style), '+'); $parts = phutil_implode_html($glue, $parts); } return $this->getEngine()->storeText($parts); }
public function render() { $id = celerity_generate_unique_node_id(); $placeholder = phutil_tag('span', array('id' => $id)); require_celerity_resource($this->getCelerityResource()); $render_context = self::peekRenderContext(); self::pushRenderContext($id); Javelin::initBehavior('view-placeholder', array('id' => $id, 'view' => $this->getName(), 'params' => $this->getParameters(), 'children' => phutil_implode_html('', $this->renderChildren()), 'trigger_id' => $render_context)); self::popRenderContext(); return $placeholder; }
public function renderConditionValue(PhabricatorUser $viewer, $value) { $change_map = PhabricatorRepositoryPushLog::getHeraldChangeFlagConditionOptions(); foreach ($value as $index => $val) { $name = idx($change_map, $val); if ($name) { $value[$index] = $name; } } return phutil_implode_html(', ', $value); }
protected function executeChecks() { $master = PhabricatorDatabaseRef::getMasterDatabaseRef(); if (!$master) { // If we're implicitly in read-only mode during disaster recovery, // don't bother with these setup checks. return; } $conn_raw = $master->newManagementConnection(); try { queryfx($conn_raw, 'SELECT 1'); $database_exception = null; } catch (AphrontInvalidCredentialsQueryException $ex) { $database_exception = $ex; } catch (AphrontConnectionQueryException $ex) { $database_exception = $ex; } if ($database_exception) { $issue = PhabricatorSetupIssue::newDatabaseConnectionIssue($database_exception); $this->addIssue($issue); return; } $engines = queryfx_all($conn_raw, 'SHOW ENGINES'); $engines = ipull($engines, 'Support', 'Engine'); $innodb = idx($engines, 'InnoDB'); if ($innodb != 'YES' && $innodb != 'DEFAULT') { $message = pht("The 'InnoDB' engine is not available in MySQL. Enable InnoDB in " . "your MySQL configuration." . "\n\n" . "(If you aleady created tables, MySQL incorrectly used some other " . "engine to create them. You need to convert them or drop and " . "reinitialize them.)"); $this->newIssue('mysql.innodb')->setName(pht('MySQL InnoDB Engine Not Available'))->setMessage($message)->setIsFatal(true); return; } $namespace = PhabricatorEnv::getEnvConfig('storage.default-namespace'); $databases = queryfx_all($conn_raw, 'SHOW DATABASES'); $databases = ipull($databases, 'Database', 'Database'); if (empty($databases[$namespace . '_meta_data'])) { $message = pht("Run the storage upgrade script to setup Phabricator's database " . "schema."); $this->newIssue('storage.upgrade')->setName(pht('Setup MySQL Schema'))->setMessage($message)->setIsFatal(true)->addCommand(hsprintf('<tt>phabricator/ $</tt> ./bin/storage upgrade')); } else { $conn_meta = $master->newApplicationConnection($namespace . '_meta_data'); $applied = queryfx_all($conn_meta, 'SELECT patch FROM patch_status'); $applied = ipull($applied, 'patch', 'patch'); $all = PhabricatorSQLPatchList::buildAllPatches(); $diff = array_diff_key($all, $applied); if ($diff) { $this->newIssue('storage.patch')->setName(pht('Upgrade MySQL Schema'))->setMessage(pht("Run the storage upgrade script to upgrade Phabricator's " . "database schema. Missing patches:<br />%s<br />", phutil_implode_html(phutil_tag('br'), array_keys($diff))))->addCommand(hsprintf('<tt>phabricator/ $</tt> ./bin/storage upgrade')); } } $host = PhabricatorEnv::getEnvConfig('mysql.host'); $matches = null; if (preg_match('/^([^:]+):(\\d+)$/', $host, $matches)) { $host = $matches[1]; $port = $matches[2]; $this->newIssue('storage.mysql.hostport')->setName(pht('Deprecated mysql.host Format'))->setSummary(pht('Move port information from `%s` to `%s` in your config.', 'mysql.host', 'mysql.port'))->setMessage(pht('Your `%s` configuration contains a port number, but this usage ' . 'is deprecated. Instead, put the port number in `%s`.', 'mysql.host', 'mysql.port'))->addPhabricatorConfig('mysql.host')->addPhabricatorConfig('mysql.port')->addCommand(hsprintf('<tt>phabricator/ $</tt> ./bin/config set mysql.host %s', $host))->addCommand(hsprintf('<tt>phabricator/ $</tt> ./bin/config set mysql.port %s', $port)); } }
private function renderWeirdOrderGlyphBars() { $views = array(); $indices = array(1, 3, 7, 4, 2, 8, 9, 5, 10, 6); $max = count($indices); foreach ($indices as $index) { $views[] = id(new AphrontGlyphBarView())->setValue($index)->setMax($max)->setNumGlyphs(5)->setCaption("Lol score is {$index}/{$max}")->setGlyph(hsprintf('%s', 'LOL!'))->setBackgroundGlyph(hsprintf('%s', '____'))->render(); $views[] = hsprintf('<div style="clear:both;"></div>'); } return $this->wrap('Glyph bars in weird order', phutil_implode_html('', $views)); }
public function markupText($text) { $lines = array(); foreach (explode("\n", $text) as $line) { $lines[] = $this->applyRules(preg_replace('/^>\\s*/', '', $line)); } if ($this->getEngine()->isTextMode()) { return '> ' . implode("\n> ", $lines); } return hsprintf('<blockquote><p>%s</p></blockquote>', phutil_implode_html(phutil_tag('br'), $lines)); }
public function renderPropertyViewValue(array $handles) { $xobjs = $this->loadDoorkeeperExternalObjects($this->getValue()); if (!$xobjs) { return null; } $links = array(); foreach ($xobjs as $xobj) { $links[] = id(new DoorkeeperTagView())->setExternalObject($xobj); } return phutil_implode_html(phutil_tag('br'), $links); }
public function renderTextChange($range_start, $range_len, $rows) { $primitives = $this->buildPrimitives($range_start, $range_len); $out = array(); foreach ($primitives as $p) { $type = $p['type']; switch ($type) { case 'old': case 'new': $out[] = hsprintf('<tr>'); if ($type == 'old') { if ($p['htype']) { $class = 'left old'; } else { $class = 'left'; } $out[] = phutil_tag('th', array(), $p['line']); $out[] = phutil_tag('th', array()); $out[] = phutil_tag('td', array('class' => $class), $p['render']); } else { if ($type == 'new') { if ($p['htype']) { $class = 'right new'; $out[] = phutil_tag('th', array()); } else { $class = 'right'; $out[] = phutil_tag('th', array(), $p['oline']); } $out[] = phutil_tag('th', array(), $p['line']); $out[] = phutil_tag('td', array('class' => $class), $p['render']); } } $out[] = hsprintf('</tr>'); break; case 'inline': $out[] = hsprintf('<tr><th /><th />'); $out[] = hsprintf('<td>'); $inline = $this->buildInlineComment($p['comment'], $p['right']); $inline->setBuildScaffolding(false); $out[] = $inline->render(); $out[] = hsprintf('</td></tr>'); break; default: $out[] = hsprintf('<tr><th /><th /><td>%s</td></tr>', $type); break; } } if ($out) { return $this->wrapChangeInTable(phutil_implode_html('', $out)); } return null; }
protected function getTagContent() { $items = array(); foreach ($this->handleList as $handle) { $items[] = $handle->renderLink(); } if ($this->getAsInline()) { $items = phutil_implode_html(', ', $items); } else { $items = phutil_implode_html(phutil_tag('br'), $items); } return $items; }
private function handlePropertyEvent($event) { $user = $event->getUser(); $object = $event->getValue('object'); if (!$object || !$object->getPHID()) { // No object, or the object has no PHID yet.. return; } if (!$object instanceof PhabricatorProjectInterface) { // This object doesn't have projects. return; } $project_phids = PhabricatorEdgeQuery::loadDestinationPHIDs($object->getPHID(), PhabricatorProjectObjectHasProjectEdgeType::EDGECONST); if ($project_phids) { $project_phids = array_reverse($project_phids); $handles = id(new PhabricatorHandleQuery())->setViewer($user)->withPHIDs($project_phids)->execute(); } else { $handles = array(); } // If this object can appear on boards, build the workboard annotations. // Some day, this might be a generic interface. For now, only tasks can // appear on boards. $can_appear_on_boards = $object instanceof ManiphestTask; $annotations = array(); if ($handles && $can_appear_on_boards) { $engine = id(new PhabricatorBoardLayoutEngine())->setViewer($user)->setBoardPHIDs($project_phids)->setObjectPHIDs(array($object->getPHID()))->executeLayout(); // TDOO: Generalize this UI and move it out of Maniphest. require_celerity_resource('maniphest-task-summary-css'); foreach ($project_phids as $project_phid) { $handle = $handles[$project_phid]; $columns = $engine->getObjectColumns($project_phid, $object->getPHID()); $annotation = array(); foreach ($columns as $column) { $project_id = $column->getProject()->getID(); $column_name = pht('(%s)', $column->getDisplayName()); $column_link = phutil_tag('a', array('href' => "/project/board/{$project_id}/", 'class' => 'maniphest-board-link'), $column_name); $annotation[] = $column_link; } if ($annotation) { $annotations[$project_phid] = array(' ', phutil_implode_html(', ', $annotation)); } } } if ($handles) { $list = id(new PHUIHandleTagListView())->setHandles($handles)->setAnnotations($annotations)->setShowHovercards(true); } else { $list = phutil_tag('em', array(), pht('None')); } $view = $event->getValue('view'); $view->addProperty(pht('Projects'), $list); }
protected function executeChecks() { $conf = PhabricatorEnv::newObjectFromConfig('mysql.configuration-provider'); $conn_user = $conf->getUser(); $conn_pass = $conf->getPassword(); $conn_host = $conf->getHost(); $conn_port = $conf->getPort(); ini_set('mysql.connect_timeout', 2); $config = array('user' => $conn_user, 'pass' => $conn_pass, 'host' => $conn_host, 'port' => $conn_port, 'database' => null); $conn_raw = PhabricatorEnv::newObjectFromConfig('mysql.implementation', array($config)); try { queryfx($conn_raw, 'SELECT 1'); } catch (AphrontConnectionQueryException $ex) { $message = pht("Unable to connect to MySQL!\n\n" . "%s\n\n" . "Make sure Phabricator and MySQL are correctly configured.", $ex->getMessage()); $this->newIssue('mysql.connect')->setName(pht('Can Not Connect to MySQL'))->setMessage($message)->setIsFatal(true)->addRelatedPhabricatorConfig('mysql.host')->addRelatedPhabricatorConfig('mysql.port')->addRelatedPhabricatorConfig('mysql.user')->addRelatedPhabricatorConfig('mysql.pass'); return; } $engines = queryfx_all($conn_raw, 'SHOW ENGINES'); $engines = ipull($engines, 'Support', 'Engine'); $innodb = idx($engines, 'InnoDB'); if ($innodb != 'YES' && $innodb != 'DEFAULT') { $message = pht("The 'InnoDB' engine is not available in MySQL. Enable InnoDB in " . "your MySQL configuration." . "\n\n" . "(If you aleady created tables, MySQL incorrectly used some other " . "engine to create them. You need to convert them or drop and " . "reinitialize them.)"); $this->newIssue('mysql.innodb')->setName(pht('MySQL InnoDB Engine Not Available'))->setMessage($message)->setIsFatal(true); return; } $namespace = PhabricatorEnv::getEnvConfig('storage.default-namespace'); $databases = queryfx_all($conn_raw, 'SHOW DATABASES'); $databases = ipull($databases, 'Database', 'Database'); if (empty($databases[$namespace . '_meta_data'])) { $message = pht("Run the storage upgrade script to setup Phabricator's database " . "schema."); $this->newIssue('storage.upgrade')->setName(pht('Setup MySQL Schema'))->setMessage($message)->setIsFatal(true)->addCommand(hsprintf('<tt>phabricator/ $</tt> ./bin/storage upgrade')); } else { $config['database'] = $namespace . '_meta_data'; $conn_meta = PhabricatorEnv::newObjectFromConfig('mysql.implementation', array($config)); $applied = queryfx_all($conn_meta, 'SELECT patch FROM patch_status'); $applied = ipull($applied, 'patch', 'patch'); $all = PhabricatorSQLPatchList::buildAllPatches(); $diff = array_diff_key($all, $applied); if ($diff) { $this->newIssue('storage.patch')->setName(pht('Upgrade MySQL Schema'))->setMessage(pht("Run the storage upgrade script to upgrade Phabricator's " . "database schema. Missing patches:<br />%s<br />", phutil_implode_html(phutil_tag('br'), array_keys($diff))))->addCommand(hsprintf('<tt>phabricator/ $</tt> ./bin/storage upgrade')); } } $host = PhabricatorEnv::getEnvConfig('mysql.host'); $matches = null; if (preg_match('/^([^:]+):(\\d+)$/', $host, $matches)) { $host = $matches[1]; $port = $matches[2]; $this->newIssue('storage.mysql.hostport')->setName(pht('Deprecated mysql.host Format'))->setSummary(pht('Move port information from `%s` to `%s` in your config.', 'mysql.host', 'mysql.port'))->setMessage(pht('Your `%s` configuration contains a port number, but this usage ' . 'is deprecated. Instead, put the port number in `%s`.', 'mysql.host', 'mysql.port'))->addPhabricatorConfig('mysql.host')->addPhabricatorConfig('mysql.port')->addCommand(hsprintf('<tt>phabricator/ $</tt> ./bin/config set mysql.host %s', $host))->addCommand(hsprintf('<tt>phabricator/ $</tt> ./bin/config set mysql.port %s', $port)); } }
public function renderThreadsHTML() { $thread_html = array(); if ($this->scrollUpParticipant->getID()) { $thread_html[] = $this->getScrollMenuItem($this->scrollUpParticipant, 'up'); } foreach ($this->threads as $thread) { $thread_html[] = $this->renderSingleThread($thread); } if ($this->scrollDownParticipant->getID()) { $thread_html[] = $this->getScrollMenuItem($this->scrollDownParticipant, 'down'); } return phutil_implode_html('', $thread_html); }
public function markupText($text, $children) { $text = rtrim($text); $text = phutil_split_lines($text, $retain_endings = true); foreach ($text as $key => $line) { $line = preg_replace('/^\\s*%%%/', '', $line); $line = preg_replace('/%%%(\\s*)\\z/', '\\1', $line); $text[$key] = $line; } if ($this->getEngine()->isTextMode()) { return implode('', $text); } return phutil_tag('p', array('class' => 'remarkup-literal'), phutil_implode_html(phutil_tag('br', array()), $text)); }