public function processRequest()
 {
     $request = $this->getRequest();
     if ($request->isFormPost()) {
         $parser = new ArcanistDiffParser();
         $diff = null;
         try {
             $diff = PhabricatorFile::readUploadedFileData($_FILES['diff-file']);
         } catch (Exception $ex) {
             $diff = $request->getStr('diff');
         }
         $changes = $parser->parseDiff($diff);
         $diff = DifferentialDiff::newFromRawChanges($changes);
         $diff->setLintStatus(DifferentialLintStatus::LINT_SKIP);
         $diff->setUnitStatus(DifferentialLintStatus::LINT_SKIP);
         $diff->setAuthorPHID($request->getUser()->getPHID());
         $diff->setCreationMethod('web');
         $diff->save();
         return id(new AphrontRedirectResponse())->setURI('/differential/diff/' . $diff->getID() . '/');
     }
     $form = new AphrontFormView();
     $arcanist_href = PhabricatorEnv::getDoclink('article/Arcanist_User_Guide.html');
     $arcanist_link = phutil_render_tag('a', array('href' => $arcanist_href, 'target' => '_blank'), 'Arcanist');
     $form->setAction('/differential/diff/create/')->setEncType('multipart/form-data')->setUser($request->getUser())->appendChild('<p class="aphront-form-instructions">The best way to create a ' . "Differential diff is by using {$arcanist_link}, but you " . 'can also just paste a diff (e.g., from <tt>svn diff</tt> or ' . '<tt>git diff</tt>) into this box or upload it as a file if you ' . 'really want.</p>')->appendChild(id(new AphrontFormTextAreaControl())->setLabel('Raw Diff')->setName('diff')->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL))->appendChild(id(new AphrontFormFileControl())->setLabel('Raw Diff from file')->setName('diff-file'))->appendChild(id(new AphrontFormSubmitControl())->setValue("Create Diff »"));
     $panel = new AphrontPanelView();
     $panel->setHeader('Create New Diff');
     $panel->appendChild($form);
     $panel->setWidth(AphrontPanelView::WIDTH_FORM);
     return $this->buildStandardPageResponse($panel, array('title' => 'Create Diff', 'tab' => 'create'));
 }
 public function buildStandardPageResponse($view, array $data)
 {
     $user = $this->getRequest()->getUser();
     $page = $this->buildStandardPageView();
     $page->setApplicationName('OAuth Server');
     $page->setBaseURI('/oauthserver/');
     $page->setTitle(idx($data, 'title'));
     $nav = new AphrontSideNavFilterView();
     $nav->setBaseURI(new PhutilURI('/oauthserver/'));
     $nav->addLabel('Client Authorizations');
     $nav->addFilter('clientauthorization', 'My Authorizations');
     $nav->addSpacer();
     $nav->addLabel('Clients');
     $nav->addFilter('client/create', 'Create Client');
     foreach ($this->getExtraClientFilters() as $filter) {
         $nav->addFilter($filter['url'], $filter['label']);
     }
     $nav->addFilter('client', 'My Clients');
     $nav->selectFilter($this->getFilter(), 'clientauthorization');
     $nav->appendChild($view);
     $page->appendChild($nav);
     $doc_href = PhabricatorEnv::getDoclink('article/Using_the_Phabricator_OAuth_Server.html');
     $page->setTabs(array('help' => array('name' => 'Help', 'href' => $doc_href)), null);
     $response = new AphrontWebpageResponse();
     return $response->setContent($page->render());
 }
 private function buildPropertyView(PhabricatorApplication $application, PhabricatorActionListView $actions)
 {
     $viewer = $this->getRequest()->getUser();
     $properties = id(new PHUIPropertyListView());
     $properties->setActionList($actions);
     $properties->addProperty(pht('Description'), $application->getShortDescription());
     if ($application->getFlavorText()) {
         $properties->addProperty(null, phutil_tag('em', array(), $application->getFlavorText()));
     }
     if ($application->isPrototype()) {
         $proto_href = PhabricatorEnv::getDoclink('User Guide: Prototype Applications');
         $learn_more = phutil_tag('a', array('href' => $proto_href, 'target' => '_blank'), pht('Learn More'));
         $properties->addProperty(pht('Prototype'), pht('This application is a prototype. %s', $learn_more));
     }
     $overview = $application->getOverview();
     if (strlen($overview)) {
         $overview = new PHUIRemarkupView($viewer, $overview);
         $properties->addSectionHeader(pht('Overview'), PHUIPropertyListView::ICON_SUMMARY);
         $properties->addTextContent($overview);
     }
     $descriptions = PhabricatorPolicyQuery::renderPolicyDescriptions($viewer, $application);
     $properties->addSectionHeader(pht('Policies'), 'fa-lock');
     foreach ($application->getCapabilities() as $capability) {
         $properties->addProperty($application->getCapabilityLabel($capability), idx($descriptions, $capability));
     }
     return $properties;
 }
 public function handleRequest(AphrontRequest $request)
 {
     $viewer = $this->getViewer();
     $class = $request->getURIData('class');
     $sources = id(new PhutilClassMapQuery())->setAncestorClass('PhabricatorTypeaheadDatasource')->execute();
     if (!isset($sources[$class])) {
         return new Aphront404Response();
     }
     $source = $sources[$class];
     $application_class = $source->getDatasourceApplicationClass();
     if ($application_class) {
         $result = id(new PhabricatorApplicationQuery())->setViewer($this->getViewer())->withClasses(array($application_class))->execute();
         if (!$result) {
             return new Aphront404Response();
         }
     }
     $source->setViewer($viewer);
     $title = pht('Typeahead Function Help');
     $functions = $source->getAllDatasourceFunctions();
     ksort($functions);
     $content = array();
     $content[] = '= ' . pht('Overview');
     $content[] = pht('Typeahead functions are an advanced feature which allow you to build ' . 'more powerful queries. This document explains functions available ' . 'for the selected control.' . "\n\n" . 'For general help with search, see the [[ %s | Search User Guide ]] in ' . 'the documentation.' . "\n\n" . 'Note that different controls support //different// functions ' . '(depending on what the control is doing), so these specific functions ' . 'may not work everywhere. You can always check the help for a control ' . 'to review which functions are available for that control.', PhabricatorEnv::getDoclink('Search User Guide'));
     $table = array();
     $table_header = array(pht('Function'), pht('Token Name'), pht('Summary'));
     $table[] = '| ' . implode(' | ', $table_header) . ' |';
     $table[] = '|---|---|---|';
     foreach ($functions as $function => $spec) {
         $spec = $spec + array('summary' => null, 'arguments' => null);
         if (idx($spec, 'arguments')) {
             $signature = '**' . $function . '(**//' . $spec['arguments'] . '//**)**';
         } else {
             $signature = '**' . $function . '()**';
         }
         $name = idx($spec, 'name', '');
         $summary = idx($spec, 'summary', '');
         $table[] = '| ' . $signature . ' | ' . $name . ' | ' . $summary . ' |';
     }
     $table = implode("\n", $table);
     $content[] = '= ' . pht('Function Quick Reference');
     $content[] = pht('This table briefly describes available functions for this control. ' . 'For details on a particular function, see the corresponding section ' . 'below.');
     $content[] = $table;
     $content[] = '= ' . pht('Using Typeahead Functions');
     $content[] = pht("In addition to typing user and project names to build queries, you can " . "also type the names of special functions which give you more options " . "and the ability to express more complex queries.\n\n" . "Functions have an internal name (like `%s`) and a human-readable name, " . "like `Current Viewer`. In general, you can type either one to select " . "the function. You can also click the {nav icon=search} button on any " . "typeahead control to browse available functions and find this " . "documentation.\n\n" . "This documentation uses the internal names to make it clear where " . "tokens begin and end. Specifically, you will find queries written " . "out like this in the documentation:\n\n%s\n\n" . "When this query is actually shown in the control, it will look more " . "like this:\n\n%s", 'viewer()', '> viewer(), alincoln', '> {nav Current Viewer} {nav alincoln (Abraham Lincoln)}');
     $middot = "·";
     foreach ($functions as $function => $spec) {
         $arguments = idx($spec, 'arguments', '');
         $name = idx($spec, 'name');
         $content[] = '= ' . $function . '(' . $arguments . ') ' . $middot . ' ' . $name;
         $content[] = $spec['description'];
     }
     $content = implode("\n\n", $content);
     $content_box = new PHUIRemarkupView($viewer, $content);
     $header = id(new PHUIHeaderView())->setHeader($title);
     $document = id(new PHUIDocumentViewPro())->setHeader($header)->appendChild($content_box);
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb(pht('Function Help'));
     $crumbs->setBorder(true);
     return $this->newPage()->setTitle($title)->setCrumbs($crumbs)->appendChild($document);
 }
 public function handleRequest(AphrontRequest $request)
 {
     $admin = $request->getUser();
     id(new PhabricatorAuthSessionEngine())->requireHighSecuritySession($admin, $request, $this->getApplicationURI());
     $v_type = 'standard';
     if ($request->isFormPost()) {
         $v_type = $request->getStr('type');
         if ($v_type == 'standard' || $v_type == 'bot' || $v_type == 'list') {
             return id(new AphrontRedirectResponse())->setURI($this->getApplicationURI('new/' . $v_type . '/'));
         }
     }
     $title = pht('Create New User');
     $standard_caption = pht('Create a standard user account. These users can log in to Phabricator, ' . 'use the web interface and API, and receive email.');
     $standard_admin = pht('Administrators are limited in their ability to access or edit these ' . 'accounts after account creation.');
     $bot_caption = pht('Create a bot/script user account, to automate interactions with other ' . 'systems. These users can not use the web interface, but can use the ' . 'API.');
     $bot_admin = pht('Administrators have greater access to edit these accounts.');
     $types = array();
     $can_create = $this->hasApplicationCapability(PeopleCreateUsersCapability::CAPABILITY);
     if ($can_create) {
         $types[] = array('type' => 'standard', 'name' => pht('Create Standard User'), 'help' => pht('Create a standard user account.'));
     }
     $types[] = array('type' => 'bot', 'name' => pht('Create Bot User'), 'help' => pht('Create a new user for use with automated scripts.'));
     $types[] = array('type' => 'list', 'name' => pht('Create Mailing List User'), 'help' => pht('Create a mailing list user to represent an existing, external ' . 'mailing list like a Google Group or a Mailman list.'));
     $buttons = id(new AphrontFormRadioButtonControl())->setLabel(pht('Account Type'))->setName('type')->setValue($v_type);
     foreach ($types as $type) {
         $buttons->addButton($type['type'], $type['name'], $type['help']);
     }
     $form = id(new AphrontFormView())->setUser($admin)->appendRemarkupInstructions(pht('Choose the type of user account to create. For a detailed ' . 'explanation of user account types, see [[ %s | User Guide: ' . 'Account Roles ]].', PhabricatorEnv::getDoclink('User Guide: Account Roles')))->appendChild($buttons)->appendChild(id(new AphrontFormSubmitControl())->addCancelButton($this->getApplicationURI())->setValue(pht('Continue')));
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb($title);
     $box = id(new PHUIObjectBoxView())->setHeaderText($title)->appendChild($form);
     return $this->buildApplicationPage(array($crumbs, $box), array('title' => $title));
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $query = id(new PhabricatorNotificationQuery())->setViewer($user)->withUserPHIDs(array($user->getPHID()))->setLimit(15);
     $stories = $query->execute();
     $clear_ui_class = 'phabricator-notification-clear-all';
     $clear_uri = id(new PhutilURI('/notification/clear/'));
     if ($stories) {
         $builder = new PhabricatorNotificationBuilder($stories);
         $notifications_view = $builder->buildView();
         $content = $notifications_view->render();
         $clear_uri->setQueryParam('chronoKey', head($stories)->getChronologicalKey());
     } else {
         $content = phutil_tag_div('phabricator-notification no-notifications', pht('You have no notifications.'));
         $clear_ui_class .= ' disabled';
     }
     $clear_ui = javelin_tag('a', array('sigil' => 'workflow', 'href' => (string) $clear_uri, 'class' => $clear_ui_class), pht('Mark All Read'));
     $notifications_link = phutil_tag('a', array('href' => '/notification/'), pht('Notifications'));
     if (PhabricatorEnv::getEnvConfig('notification.enabled')) {
         $connection_status = new PhabricatorNotificationStatusView();
     } else {
         $connection_status = phutil_tag('a', array('href' => PhabricatorEnv::getDoclink('Notifications User Guide: Setup and Configuration')), pht('Notification Server not enabled.'));
     }
     $connection_ui = phutil_tag('div', array('class' => 'phabricator-notification-footer'), $connection_status);
     $header = phutil_tag('div', array('class' => 'phabricator-notification-header'), array($notifications_link, $clear_ui));
     $content = hsprintf('%s%s%s', $header, $content, $connection_ui);
     $unread_count = id(new PhabricatorFeedStoryNotification())->countUnread($user);
     $json = array('content' => $content, 'number' => (int) $unread_count);
     return id(new AphrontAjaxResponse())->setContent($json);
 }
 public function handleHosting(PhabricatorRepository $repository)
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $v_hosting = $repository->isHosted();
     $edit_uri = $this->getRepositoryControllerURI($repository, 'edit/');
     $next_uri = $this->getRepositoryControllerURI($repository, 'edit/serve/');
     if ($request->isFormPost()) {
         $v_hosting = $request->getBool('hosting');
         $xactions = array();
         $template = id(new PhabricatorRepositoryTransaction());
         $type_hosting = PhabricatorRepositoryTransaction::TYPE_HOSTING;
         $xactions[] = id(clone $template)->setTransactionType($type_hosting)->setNewValue($v_hosting);
         id(new PhabricatorRepositoryEditor())->setContinueOnNoEffect(true)->setContentSourceFromRequest($request)->setActor($user)->applyTransactions($repository, $xactions);
         return id(new AphrontRedirectResponse())->setURI($next_uri);
     }
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb(pht('Edit Hosting'));
     $title = pht('Edit Hosting (%s)', $repository->getName());
     $hosted_control = id(new AphrontFormRadioButtonControl())->setName('hosting')->setLabel(pht('Hosting'))->addButton(true, pht('Host Repository on Phabricator'), pht('Phabricator will host this repository. Users will be able to ' . 'push commits to Phabricator. Phabricator will not pull ' . 'changes from elsewhere.'))->addButton(false, pht('Host Repository Elsewhere'), pht('Phabricator will pull updates to this repository from a master ' . 'repository elsewhere (for example, on GitHub or Bitbucket). ' . 'Users will not be able to push commits to this repository.'))->setValue($v_hosting);
     $doc_href = PhabricatorEnv::getDoclink('Diffusion User Guide: Repository Hosting');
     $form = id(new AphrontFormView())->setUser($user)->appendRemarkupInstructions(pht('Phabricator can host repositories, or it can track repositories ' . 'hosted elsewhere (like on GitHub or Bitbucket). For information ' . 'on configuring hosting, see [[ %s | Diffusion User Guide: ' . 'Repository Hosting]]', $doc_href))->appendChild($hosted_control)->appendChild(id(new AphrontFormSubmitControl())->setValue(pht('Save and Continue'))->addCancelButton($edit_uri));
     $object_box = id(new PHUIObjectBoxView())->setHeaderText($title)->setForm($form);
     return $this->buildApplicationPage(array($crumbs, $object_box), array('title' => $title));
 }
Пример #8
0
 public function buildStandardPageResponse($view, array $data)
 {
     $page = $this->buildStandardPageView();
     $page->setApplicationName('Herald');
     $page->setBaseURI('/herald/');
     $page->setTitle(idx($data, 'title'));
     $page->setGlyph("☿");
     $doclink = PhabricatorEnv::getDoclink('article/Herald_User_Guide.html');
     $nav = new AphrontSideNavFilterView();
     $nav->setBaseURI(new PhutilURI('/herald/'))->addLabel('Rules')->addFilter('new', 'Create Rule');
     $rules_map = HeraldContentTypeConfig::getContentTypeMap();
     $first_filter = null;
     foreach ($rules_map as $key => $value) {
         $nav->addFilter('view/' . $key, $value);
         if (!$first_filter) {
             $first_filter = 'view/' . $key;
         }
     }
     $nav->addSpacer()->addLabel('Utilities')->addFilter('test', 'Test Console')->addFilter('transcript', 'Transcripts');
     $user = $this->getRequest()->getUser();
     if ($user->getIsAdmin()) {
         $nav->addSpacer()->addLabel('Admin');
         $view_PHID = nonempty($this->getRequest()->getStr('phid'), null);
         foreach ($rules_map as $key => $value) {
             $nav->addFilter('all/view/' . $key, $value);
         }
     }
     $nav->selectFilter($this->getFilter(), $first_filter);
     $nav->appendChild($view);
     $page->appendChild($nav);
     $tabs = array('help' => array('href' => $doclink, 'name' => 'Help'));
     $page->setTabs($tabs, null);
     $response = new AphrontWebpageResponse();
     return $response->setContent($page->render());
 }
 protected function processDiffusionRequest(AphrontRequest $request)
 {
     $viewer = $request->getUser();
     $this->requireApplicationCapability(DiffusionCreateRepositoriesCapability::CAPABILITY);
     if ($request->isFormPost()) {
         if ($request->getStr('type')) {
             switch ($request->getStr('type')) {
                 case 'create':
                     $uri = $this->getApplicationURI('create/');
                     break;
                 case 'import':
                 default:
                     $uri = $this->getApplicationURI('import/');
                     break;
             }
             return id(new AphrontRedirectResponse())->setURI($uri);
         }
     }
     $doc_href = PhabricatorEnv::getDoclink('Diffusion User Guide: Repository Hosting');
     $doc_link = phutil_tag('a', array('href' => $doc_href, 'target' => '_blank'), pht('Diffusion User Guide: Repository Hosting'));
     $form = id(new AphrontFormView())->setUser($viewer)->appendChild(id(new AphrontFormRadioButtonControl())->setName('type')->addButton('create', pht('Create a New Hosted Repository'), array(pht('Create a new, empty repository which Phabricator will host. ' . 'For instructions on configuring repository hosting, see %s.', $doc_link)))->addButton('import', pht('Import an Existing External Repository'), pht("Import a repository hosted somewhere else, like GitHub, " . "Bitbucket, or your organization's existing servers. " . "Phabricator will read changes from the repository but will " . "not host or manage it. The authoritative master version of " . "the repository will stay where it is now.")))->appendChild(id(new AphrontFormSubmitControl())->setValue(pht('Continue'))->addCancelButton($this->getApplicationURI()));
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb(pht('New Repository'));
     $form_box = id(new PHUIObjectBoxView())->setHeaderText(pht('Create or Import Repository'))->setForm($form);
     return $this->buildApplicationPage(array($crumbs, $form_box), array('title' => pht('New Repository')));
 }
 private function buildResponse($title, $body)
 {
     $nav = $this->buildSideNavView();
     $nav->selectFilter('database/');
     if (!$title) {
         $title = pht('Database Status');
     }
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->setBorder(true);
     if ($this->database) {
         $crumbs->addTextCrumb(pht('Database Status'), $this->getApplicationURI('database/'));
         if ($this->table) {
             $crumbs->addTextCrumb($this->database, $this->getApplicationURI('database/' . $this->database . '/'));
             if ($this->column || $this->key) {
                 $crumbs->addTextCrumb($this->table, $this->getApplicationURI('database/' . $this->database . '/' . $this->table . '/'));
                 if ($this->column) {
                     $crumbs->addTextCrumb($this->column);
                 } else {
                     $crumbs->addTextCrumb($this->key);
                 }
             } else {
                 $crumbs->addTextCrumb($this->table);
             }
         } else {
             $crumbs->addTextCrumb($this->database);
         }
     } else {
         $crumbs->addTextCrumb(pht('Database Status'));
     }
     $doc_link = PhabricatorEnv::getDoclink('Managing Storage Adjustments');
     $header = id(new PHUIHeaderView())->setHeader($title)->setProfileHeader(true)->addActionLink(id(new PHUIButtonView())->setTag('a')->setIcon('fa-book')->setHref($doc_link)->setText(pht('Learn More')));
     $content = id(new PhabricatorConfigPageView())->setHeader($header)->setContent($body);
     return $this->newPage()->setTitle($title)->setCrumbs($crumbs)->setNavigation($nav)->appendChild($content)->addClass('white-background');
 }
 protected function processDiffusionRequest(AphrontRequest $request)
 {
     $user = $request->getUser();
     $drequest = $this->getDiffusionRequest();
     $callsign = $drequest->getRepository()->getCallsign();
     $repository = $drequest->getRepository();
     $commit = $drequest->loadCommit();
     $data = $commit->loadCommitData();
     $page_title = pht('Edit Diffusion Commit');
     if (!$commit) {
         return new Aphront404Response();
     }
     $commit_phid = $commit->getPHID();
     $edge_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
     $current_proj_phids = PhabricatorEdgeQuery::loadDestinationPHIDs($commit_phid, $edge_type);
     if ($request->isFormPost()) {
         $xactions = array();
         $proj_phids = $request->getArr('projects');
         $xactions[] = id(new PhabricatorAuditTransaction())->setTransactionType(PhabricatorTransactions::TYPE_EDGE)->setMetadataValue('edge:type', $edge_type)->setNewValue(array('=' => array_fuse($proj_phids)));
         $editor = id(new PhabricatorAuditEditor())->setActor($user)->setContinueOnNoEffect(true)->setContentSourceFromRequest($request);
         $xactions = $editor->applyTransactions($commit, $xactions);
         return id(new AphrontRedirectResponse())->setURI('/r' . $callsign . $commit->getCommitIdentifier());
     }
     $tokenizer_id = celerity_generate_unique_node_id();
     $form = id(new AphrontFormView())->setUser($user)->setAction($request->getRequestURI()->getPath())->appendControl(id(new AphrontFormTokenizerControl())->setLabel(pht('Projects'))->setName('projects')->setValue($current_proj_phids)->setID($tokenizer_id)->setCaption(javelin_tag('a', array('href' => '/project/create/', 'mustcapture' => true, 'sigil' => 'project-create'), pht('Create New Project')))->setDatasource(new PhabricatorProjectDatasource()));
     $reason = $data->getCommitDetail('autocloseReason', false);
     $reason = PhabricatorRepository::BECAUSE_AUTOCLOSE_FORCED;
     if ($reason !== false) {
         switch ($reason) {
             case PhabricatorRepository::BECAUSE_REPOSITORY_IMPORTING:
                 $desc = pht('No, Repository Importing');
                 break;
             case PhabricatorRepository::BECAUSE_AUTOCLOSE_DISABLED:
                 $desc = pht('No, Autoclose Disabled');
                 break;
             case PhabricatorRepository::BECAUSE_NOT_ON_AUTOCLOSE_BRANCH:
                 $desc = pht('No, Not On Autoclose Branch');
                 break;
             case PhabricatorRepository::BECAUSE_AUTOCLOSE_FORCED:
                 $desc = pht('Yes, Forced Via bin/repository CLI Tool.');
                 break;
             case null:
                 $desc = pht('Yes');
                 break;
             default:
                 $desc = pht('Unknown');
                 break;
         }
         $doc_href = PhabricatorEnv::getDoclink('Diffusion User Guide: Autoclose');
         $doc_link = phutil_tag('a', array('href' => $doc_href, 'target' => '_blank'), pht('Learn More'));
         $form->appendChild(id(new AphrontFormMarkupControl())->setLabel(pht('Autoclose?'))->setValue(array($desc, " · ", $doc_link)));
     }
     Javelin::initBehavior('project-create', array('tokenizerID' => $tokenizer_id));
     $submit = id(new AphrontFormSubmitControl())->setValue(pht('Save'))->addCancelButton('/r' . $callsign . $commit->getCommitIdentifier());
     $form->appendChild($submit);
     $crumbs = $this->buildCrumbs(array('commit' => true));
     $crumbs->addTextCrumb(pht('Edit'));
     $form_box = id(new PHUIObjectBoxView())->setHeaderText($page_title)->setForm($form);
     return $this->buildApplicationPage(array($crumbs, $form_box), array('title' => $page_title));
 }
 public function getOptions()
 {
     $doc_href = PhabricatorEnv::getDoclink('Configuring a File Domain');
     $doc_name = pht('Configuration Guide: Configuring a File Domain');
     // This is all of the IANA special/reserved blocks in IPv4 space.
     $default_address_blacklist = array('0.0.0.0/8', '10.0.0.0/8', '100.64.0.0/10', '127.0.0.0/8', '169.254.0.0/16', '172.16.0.0/12', '192.0.0.0/24', '192.0.2.0/24', '192.88.99.0/24', '192.168.0.0/16', '198.18.0.0/15', '198.51.100.0/24', '203.0.113.0/24', '224.0.0.0/4', '240.0.0.0/4', '255.255.255.255/32');
     return array($this->newOption('security.alternate-file-domain', 'string', null)->setLocked(true)->setSummary(pht('Alternate domain to serve files from.'))->setDescription(pht('By default, Phabricator serves files from the same domain ' . 'the application is served from. This is convenient, but ' . 'presents a security risk.' . "\n\n" . 'You should configure a CDN or alternate file domain to mitigate ' . 'this risk. Configuring a CDN will also improve performance. See ' . '[[ %s | %s ]] for instructions.', $doc_href, $doc_name))->addExample('https://files.phabcdn.net/', pht('Valid Setting')), $this->newOption('security.hmac-key', 'string', '[D\\t~Y7eNmnQGJ;rnH6aF;m2!vJ8@v8C=Cs:aQS\\.Qw')->setHidden(true)->setSummary(pht('Key for HMAC digests.'))->setDescription(pht('Default key for HMAC digests where the key is not important ' . '(i.e., the hash itself is secret). You can change this if you ' . 'want (to any other string), but doing so will break existing ' . 'sessions and CSRF tokens.')), $this->newOption('security.require-https', 'bool', false)->setLocked(true)->setSummary(pht('Force users to connect via HTTPS instead of HTTP.'))->setDescription(pht("If the web server responds to both HTTP and HTTPS requests but " . "you want users to connect with only HTTPS, you can set this " . "to true to make Phabricator redirect HTTP requests to HTTPS.\n\n" . "Normally, you should just configure your server not to accept " . "HTTP traffic, but this setting may be useful if you originally " . "used HTTP and have now switched to HTTPS but don't want to " . "break old links, or if your webserver sits behind a load " . "balancer which terminates HTTPS connections and you can not " . "reasonably configure more granular behavior there.\n\n" . "IMPORTANT: Phabricator determines if a request is HTTPS or not " . "by examining the PHP `%s` variable. If you run " . "Apache/mod_php this will probably be set correctly for you " . "automatically, but if you run Phabricator as CGI/FCGI (e.g., " . "through nginx or lighttpd), you need to configure your web " . "server so that it passes the value correctly based on the " . "connection type.", "\$_SERVER['HTTPS']"))->setBoolOptions(array(pht('Force HTTPS'), pht('Allow HTTP'))), $this->newOption('security.require-multi-factor-auth', 'bool', false)->setLocked(true)->setSummary(pht('Require all users to configure multi-factor authentication.'))->setDescription(pht('By default, Phabricator allows users to add multi-factor ' . 'authentication to their accounts, but does not require it. ' . 'By enabling this option, you can force all users to add ' . 'at least one authentication factor before they can use their ' . 'accounts.'))->setBoolOptions(array(pht('Multi-Factor Required'), pht('Multi-Factor Optional'))), $this->newOption('phabricator.csrf-key', 'string', '0b7ec0592e0a2829d8b71df2fa269b2c6172eca3')->setHidden(true)->setSummary(pht('Hashed with other inputs to generate CSRF tokens.'))->setDescription(pht('This is hashed with other inputs to generate CSRF tokens. If ' . 'you want, you can change it to some other string which is ' . 'unique to your install. This will make your install more secure ' . 'in a vague, mostly theoretical way. But it will take you like 3 ' . 'seconds of mashing on your keyboard to set it up so you might ' . 'as well.')), $this->newOption('phabricator.mail-key', 'string', '5ce3e7e8787f6e40dfae861da315a5cdf1018f12')->setHidden(true)->setSummary(pht('Hashed with other inputs to generate mail tokens.'))->setDescription(pht("This is hashed with other inputs to generate mail tokens. If " . "you want, you can change it to some other string which is " . "unique to your install. In particular, you will want to do " . "this if you accidentally send a bunch of mail somewhere you " . "shouldn't have, to invalidate all old reply-to addresses.")), $this->newOption('uri.allowed-protocols', 'set', array('http' => true, 'https' => true, 'mailto' => true))->setSummary(pht('Determines which URI protocols are auto-linked.'))->setDescription(pht("When users write comments which have URIs, they'll be " . "automatically linked if the protocol appears in this set. This " . "whitelist is primarily to prevent security issues like " . "%s URIs.", 'javascript://'))->addExample("http\nhttps", pht('Valid Setting'))->setLocked(true), $this->newOption('uri.allowed-editor-protocols', 'set', array('http' => true, 'https' => true, 'txmt' => true, 'mvim' => true, 'vim' => true, 'subl' => true, 'emacs' => true, 'editor' => true))->setSummary(pht('Whitelists editor protocols for "Open in Editor".'))->setDescription(pht('Users can configure a URI pattern to open files in a text ' . 'editor. The URI must use a protocol on this whitelist.'))->setLocked(true), $this->newOption('celerity.resource-hash', 'string', 'd9455ea150622ee044f7931dabfa52aa')->setSummary(pht('An input to the hash function when building resource hashes.'))->setDescription(pht('This value is an input to the hash function when building ' . 'resource hashes. It has no security value, but if you ' . 'accidentally poison user caches (by pushing a bad patch or ' . 'having something go wrong with a CDN, e.g.) you can change this ' . 'to something else and rebuild the Celerity map to break user ' . 'caches. Unless you are doing Celerity development, it is ' . 'exceptionally unlikely that you need to modify this.')), $this->newOption('remarkup.enable-embedded-youtube', 'bool', false)->setBoolOptions(array(pht('Embed YouTube videos'), pht("Don't embed YouTube videos")))->setSummary(pht('Determines whether or not YouTube videos get embedded.'))->setDescription(pht("If you enable this, linked YouTube videos will be embedded " . "inline. This has mild security implications (you'll leak " . "referrers to YouTube) and is pretty silly (but sort of " . "awesome).")), $this->newOption('security.outbound-blacklist', 'list<string>', $default_address_blacklist)->setLocked(true)->setSummary(pht('Blacklist subnets to prevent user-initiated outbound ' . 'requests.'))->setDescription(pht('Phabricator users can make requests to other services from ' . 'the Phabricator host in some circumstances (for example, by ' . 'creating a repository with a remote URL or having Phabricator ' . 'fetch an image from a remote server).' . "\n\n" . 'This may represent a security vulnerability if services on ' . 'the same subnet will accept commands or reveal private ' . 'information over unauthenticated HTTP GET, based on the source ' . 'IP address. In particular, all hosts in EC2 have access to ' . 'such a service.' . "\n\n" . 'This option defines a list of netblocks which Phabricator ' . 'will decline to connect to. Generally, you should list all ' . 'private IP space here.'))->addExample(array('0.0.0.0/0'), pht('No Outbound Requests')), $this->newOption('security.strict-transport-security', 'bool', false)->setLocked(true)->setBoolOptions(array(pht('Use HSTS'), pht('Do Not Use HSTS')))->setSummary(pht('Enable HTTP Strict Transport Security (HSTS).'))->setDescription(pht('HTTP Strict Transport Security (HSTS) sends a header which ' . 'instructs browsers that the site should only be accessed ' . 'over HTTPS, never HTTP. This defuses an attack where an ' . 'adversary gains access to your network, then proxies requests ' . 'through an unsecured link.' . "\n\n" . 'Do not enable this option if you serve (or plan to ever serve) ' . 'unsecured content over plain HTTP. It is very difficult to ' . 'undo this change once users\' browsers have accepted the ' . 'setting.')));
 }
 protected function buildApplicationCrumbs()
 {
     $crumbs = parent::buildApplicationCrumbs();
     $doc_name = 'Calendar User Guide: Exporting Events';
     $doc_href = PhabricatorEnv::getDoclink($doc_name);
     $crumbs->addAction(id(new PHUIListItemView())->setName(pht('Guide: Exporting Events'))->setIcon('fa-book')->setHref($doc_href));
     return $crumbs;
 }
 public function render()
 {
     $drequest = $this->getDiffusionRequest();
     $current_branch = $drequest->getBranch();
     $repository = $drequest->getRepository();
     Javelin::initBehavior('phabricator-tooltips');
     $doc_href = PhabricatorEnv::getDoclink('Diffusion User Guide: Autoclose');
     $rows = array();
     $rowc = array();
     foreach ($this->branches as $branch) {
         $commit = idx($this->commits, $branch->getCommitIdentifier());
         if ($commit) {
             $details = $commit->getSummary();
             $datetime = phabricator_datetime($commit->getEpoch(), $this->user);
         } else {
             $datetime = null;
             $details = null;
         }
         switch ($repository->shouldSkipAutocloseBranch($branch->getShortName())) {
             case PhabricatorRepository::BECAUSE_REPOSITORY_IMPORTING:
                 $icon = 'fa-times bluegrey';
                 $tip = pht('Repository Importing');
                 break;
             case PhabricatorRepository::BECAUSE_AUTOCLOSE_DISABLED:
                 $icon = 'fa-times bluegrey';
                 $tip = pht('Repository Autoclose Disabled');
                 break;
             case PhabricatorRepository::BECAUSE_BRANCH_UNTRACKED:
                 $icon = 'fa-times bluegrey';
                 $tip = pht('Branch Untracked');
                 break;
             case PhabricatorRepository::BECAUSE_BRANCH_NOT_AUTOCLOSE:
                 $icon = 'fa-times bluegrey';
                 $tip = pht('Branch Autoclose Disabled');
                 break;
             case null:
                 $icon = 'fa-check bluegrey';
                 $tip = pht('Autoclose Enabled');
                 break;
             default:
                 $icon = 'fa-question';
                 $tip = pht('Status Unknown');
                 break;
         }
         $status_icon = id(new PHUIIconView())->setIconFont($icon)->addSigil('has-tooltip')->setHref($doc_href)->setMetadata(array('tip' => $tip, 'size' => 200));
         $rows[] = array(phutil_tag('a', array('href' => $drequest->generateURI(array('action' => 'history', 'branch' => $branch->getShortName()))), pht('History')), phutil_tag('a', array('href' => $drequest->generateURI(array('action' => 'browse', 'branch' => $branch->getShortName()))), $branch->getShortName()), self::linkCommit($drequest->getRepository(), $branch->getCommitIdentifier()), $status_icon, $datetime, AphrontTableView::renderSingleDisplayLine($details));
         if ($branch->getShortName() == $current_branch) {
             $rowc[] = 'highlighted';
         } else {
             $rowc[] = null;
         }
     }
     $view = new AphrontTableView($rows);
     $view->setHeaders(array(pht('History'), pht('Branch'), pht('Head'), pht(''), pht('Modified'), pht('Details')));
     $view->setColumnClasses(array('', 'pri', '', '', '', 'wide'));
     $view->setRowClasses($rowc);
     return $view->render();
 }
 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);
 }
    private function getInstructions()
    {
        return pht(<<<EOT
Configure Symbols for this repository.

See [[%s | Symbol Indexes]] for more information on using symbols.
EOT
, PhabricatorEnv::getDoclink('Diffusion User Guide: Symbol Indexes'));
    }
    public function processRequest(AphrontRequest $request)
    {
        $user = $request->getUser();
        $preferences = $user->loadPreferences();
        $pref_monospaced = PhabricatorUserPreferences::PREFERENCE_MONOSPACED;
        $pref_editor = PhabricatorUserPreferences::PREFERENCE_EDITOR;
        $pref_multiedit = PhabricatorUserPreferences::PREFERENCE_MULTIEDIT;
        $pref_titles = PhabricatorUserPreferences::PREFERENCE_TITLES;
        $pref_monospaced_textareas = PhabricatorUserPreferences::PREFERENCE_MONOSPACED_TEXTAREAS;
        $errors = array();
        $e_editor = null;
        if ($request->isFormPost()) {
            $monospaced = $request->getStr($pref_monospaced);
            // Prevent the user from doing stupid things.
            $monospaced = preg_replace('/[^a-z0-9 ,".]+/i', '', $monospaced);
            $preferences->setPreference($pref_titles, $request->getStr($pref_titles));
            $preferences->setPreference($pref_editor, $request->getStr($pref_editor));
            $preferences->setPreference($pref_multiedit, $request->getStr($pref_multiedit));
            $preferences->setPreference($pref_monospaced, $monospaced);
            $preferences->setPreference($pref_monospaced_textareas, $request->getStr($pref_monospaced_textareas));
            $editor_pattern = $preferences->getPreference($pref_editor);
            if (strlen($editor_pattern)) {
                $ok = PhabricatorHelpEditorProtocolController::hasAllowedProtocol($editor_pattern);
                if (!$ok) {
                    $allowed_key = 'uri.allowed-editor-protocols';
                    $allowed_protocols = PhabricatorEnv::getEnvConfig($allowed_key);
                    $proto_names = array();
                    foreach (array_keys($allowed_protocols) as $protocol) {
                        $proto_names[] = $protocol . '://';
                    }
                    $errors[] = pht('Editor link has an invalid or missing protocol. You must ' . 'use a whitelisted editor protocol from this list: %s. To ' . 'add protocols, update %s.', implode(', ', $proto_names), phutil_tag('tt', array(), $allowed_key));
                    $e_editor = pht('Invalid');
                }
            }
            if (!$errors) {
                $preferences->save();
                return id(new AphrontRedirectResponse())->setURI($this->getPanelURI('?saved=true'));
            }
        }
        $example_string = <<<EXAMPLE
// This is what your monospaced font currently looks like.
function helloWorld() {
  alert("Hello world!");
}
EXAMPLE;
        $editor_doc_link = phutil_tag('a', array('href' => PhabricatorEnv::getDoclink('User Guide: Configuring an External Editor')), pht('User Guide: Configuring an External Editor'));
        $font_default = PhabricatorEnv::getEnvConfig('style.monospace');
        $pref_monospaced_textareas_value = $preferences->getPreference($pref_monospaced_textareas);
        if (!$pref_monospaced_textareas_value) {
            $pref_monospaced_textareas_value = 'disabled';
        }
        $editor_instructions = pht('Link to edit files in external editor. ' . '%%f is replaced by filename, %%l by line number, %%r by repository ' . 'callsign, %%%% by literal %%. For documentation, see: %s', $editor_doc_link);
        $form = id(new AphrontFormView())->setUser($user)->appendChild(id(new AphrontFormSelectControl())->setLabel(pht('Page Titles'))->setName($pref_titles)->setValue($preferences->getPreference($pref_titles))->setOptions(array('glyph' => pht("In page titles, show Tool names as unicode glyphs: " . "⚙"), 'text' => pht('In page titles, show Tool names as plain text: ' . '[Differential]'))))->appendChild(id(new AphrontFormTextControl())->setLabel(pht('Editor Link'))->setName($pref_editor)->setCaption($editor_instructions)->setError($e_editor)->setValue($preferences->getPreference($pref_editor)))->appendChild(id(new AphrontFormSelectControl())->setLabel(pht('Edit Multiple Files'))->setName($pref_multiedit)->setOptions(array('' => pht('Supported (paths separated by spaces)'), 'disable' => pht('Not Supported')))->setValue($preferences->getPreference($pref_multiedit)))->appendChild(id(new AphrontFormTextControl())->setLabel(pht('Monospaced Font'))->setName($pref_monospaced)->setCaption(hsprintf('%s<br />(%s: %s)', pht('Overrides default fonts in tools like Differential.'), pht('Default'), $font_default))->setValue($preferences->getPreference($pref_monospaced)))->appendChild(id(new AphrontFormMarkupControl())->setValue(phutil_tag('pre', array('class' => 'PhabricatorMonospaced'), $example_string)))->appendChild(id(new AphrontFormRadioButtonControl())->setLabel(pht('Monospaced Textareas'))->setName($pref_monospaced_textareas)->setValue($pref_monospaced_textareas_value)->addButton('enabled', pht('Enabled'), pht('Show all textareas using the monospaced font defined above.'))->addButton('disabled', pht('Disabled'), null));
        $form->appendChild(id(new AphrontFormSubmitControl())->setValue(pht('Save Preferences')));
        $form_box = id(new PHUIObjectBoxView())->setHeaderText(pht('Display Preferences'))->setFormErrors($errors)->setFormSaved($request->getStr('saved') === 'true')->setForm($form);
        return array($form_box);
    }
 public function buildManagementPanelContent()
 {
     $repository = $this->getRepository();
     $viewer = $this->getViewer();
     $uris = $repository->getURIs();
     Javelin::initBehavior('phabricator-tooltips');
     $rows = array();
     foreach ($uris as $uri) {
         $uri_name = $uri->getDisplayURI();
         $uri_name = phutil_tag('a', array('href' => $uri->getViewURI()), $uri_name);
         if ($uri->getIsDisabled()) {
             $status_icon = 'fa-times grey';
         } else {
             $status_icon = 'fa-check green';
         }
         $uri_status = id(new PHUIIconView())->setIcon($status_icon);
         $io_type = $uri->getEffectiveIOType();
         $io_map = PhabricatorRepositoryURI::getIOTypeMap();
         $io_spec = idx($io_map, $io_type, array());
         $io_icon = idx($io_spec, 'icon');
         $io_color = idx($io_spec, 'color');
         $io_label = idx($io_spec, 'label', $io_type);
         $uri_io = array(id(new PHUIIconView())->setIcon("{$io_icon} {$io_color}"), ' ', $io_label);
         $display_type = $uri->getEffectiveDisplayType();
         $display_map = PhabricatorRepositoryURI::getDisplayTypeMap();
         $display_spec = idx($display_map, $display_type, array());
         $display_icon = idx($display_spec, 'icon');
         $display_color = idx($display_spec, 'color');
         $display_label = idx($display_spec, 'label', $display_type);
         $uri_display = array(id(new PHUIIconView())->setIcon("{$display_icon} {$display_color}"), ' ', $display_label);
         $rows[] = array($uri_status, $uri_name, $uri_io, $uri_display);
     }
     $table = id(new AphrontTableView($rows))->setNoDataString(pht('This repository has no URIs.'))->setHeaders(array(null, pht('URI'), pht('I/O'), pht('Display')))->setColumnClasses(array(null, 'pri wide', null, null));
     $doc_href = PhabricatorEnv::getDoclink('Diffusion User Guide: URIs');
     $add_href = $repository->getPathURI('uri/edit/');
     $header = id(new PHUIHeaderView())->setHeader(pht('Repository URIs'))->addActionLink(id(new PHUIButtonView())->setIcon('fa-plus')->setHref($add_href)->setTag('a')->setText(pht('Add New URI')))->addActionLink(id(new PHUIButtonView())->setIcon('fa-book')->setHref($doc_href)->setTag('a')->setText(pht('Documentation')));
     $is_new = $repository->isNewlyInitialized();
     $messages = array();
     if ($repository->isHosted()) {
         if ($is_new) {
             $host_message = pht('Phabricator will host this repository.');
         } else {
             $host_message = pht('Phabricator is hosting this repository.');
         }
         $messages[] = array(id(new PHUIIconView())->setIcon('fa-folder'), ' ', $host_message);
     } else {
         if ($is_new) {
             $observe_message = pht('Phabricator will observe a remote repository.');
         } else {
             $observe_message = pht('This repository is hosted remotely. Phabricator is observing it.');
         }
         $messages[] = array(id(new PHUIIconView())->setIcon('fa-download'), ' ', $observe_message);
     }
     $info_view = id(new PHUIInfoView())->setSeverity(PHUIInfoView::SEVERITY_NOTICE)->setErrors($messages);
     return id(new PHUIObjectBoxView())->setHeader($header)->setInfoView($info_view)->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)->setTable($table);
 }
 protected function getNewUserBody()
 {
     $doc_name = 'Calendar User Guide: Exporting Events';
     $doc_href = PhabricatorEnv::getDoclink($doc_name);
     $create_button = id(new PHUIButtonView())->setTag('a')->setIcon('fa-book white')->setText($doc_name)->setHref($doc_href)->setColor(PHUIButtonView::GREEN);
     $icon = $this->getApplication()->getIcon();
     $app_name = $this->getApplication()->getName();
     $view = id(new PHUIBigInfoView())->setIcon('fa-download')->setTitle(pht('No Exports Configured'))->setDescription(pht('You have not set up any events for export from Calendar yet. ' . 'See the documentation for instructions on how to get started.'))->addAction($create_button);
     return $view;
 }
 public function getStatusMessages(AlmanacService $service)
 {
     $messages = parent::getStatusMessages($service);
     if (!$service->getIsLocked()) {
         $doc_href = PhabricatorEnv::getDoclink('User Guide: Phabricator Clusters');
         $doc_link = phutil_tag('a', array('href' => $doc_href, 'target' => '_blank'), pht('Learn More'));
         $messages[] = pht('This is an unlocked cluster service. After you finish editing ' . 'it, you should lock it. %s.', $doc_link);
     }
     return $messages;
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     if ($request->isFormPost()) {
         $mail = new PhabricatorMetaMTAMail();
         $mail->addTos($request->getArr('to'));
         $mail->addCCs($request->getArr('cc'));
         $mail->setSubject($request->getStr('subject'));
         $mail->setBody($request->getStr('body'));
         $files = $request->getArr('files');
         if ($files) {
             foreach ($files as $phid) {
                 $file = id(new PhabricatorFile())->loadOneWhere('phid = %s', $phid);
                 $mail->addAttachment(new PhabricatorMetaMTAAttachment($file->loadFileData(), $file->getName(), $file->getMimeType()));
             }
         }
         $mail->setFrom($request->getUser()->getPHID());
         $mail->setSimulatedFailureCount($request->getInt('failures'));
         $mail->setIsHTML($request->getInt('html'));
         $mail->setIsBulk($request->getInt('bulk'));
         $mail->setMailTags($request->getStrList('mailtags'));
         $mail->save();
         if ($request->getInt('immediately')) {
             $mail->sendNow();
         }
         return id(new AphrontRedirectResponse())->setURI($this->getApplicationURI('/view/' . $mail->getID() . '/'));
     }
     $failure_caption = "Enter a number to simulate that many consecutive send failures before " . "really attempting to deliver via the underlying MTA.";
     $doclink_href = PhabricatorEnv::getDoclink('article/Configuring_Outbound_Email.html');
     $doclink = phutil_render_tag('a', array('href' => $doclink_href, 'target' => '_blank'), 'Configuring Outbound Email');
     $instructions = '<p class="aphront-form-instructions">This form will send a normal ' . 'email using the settings you have configured for Phabricator. For more ' . 'information, see ' . $doclink . '.</p>';
     $adapter = PhabricatorEnv::getEnvConfig('metamta.mail-adapter');
     $warning = null;
     if ($adapter == 'PhabricatorMailImplementationTestAdapter') {
         $warning = new AphrontErrorView();
         $warning->setTitle('Email is Disabled');
         $warning->setSeverity(AphrontErrorView::SEVERITY_WARNING);
         $warning->appendChild('<p>This installation of Phabricator is currently set to use ' . '<tt>PhabricatorMailImplementationTestAdapter</tt> to deliver ' . 'outbound email. This completely disables outbound email! All ' . 'outbound email will be thrown in a deep, dark hole until you ' . 'configure a real adapter.</p>');
     }
     $panel_id = celerity_generate_unique_node_id();
     $phdlink_href = PhabricatorEnv::getDoclink('article/Managing_Daemons_with_phd.html');
     $phdlink = phutil_render_tag('a', array('href' => $phdlink_href, 'target' => '_blank'), '"phd start"');
     $form = new AphrontFormView();
     $form->setUser($request->getUser());
     $form->appendChild($instructions)->appendChild(id(new AphrontFormStaticControl())->setLabel('Adapter')->setValue($adapter))->appendChild(id(new AphrontFormTokenizerControl())->setLabel('To')->setName('to')->setDatasource('/typeahead/common/mailable/'))->appendChild(id(new AphrontFormTokenizerControl())->setLabel('CC')->setName('cc')->setDatasource('/typeahead/common/mailable/'))->appendChild(id(new AphrontFormTextControl())->setLabel('Subject')->setName('subject'))->appendChild(id(new AphrontFormTextAreaControl())->setLabel('Body')->setName('body'))->appendChild(id(new AphrontFormTextControl())->setLabel('Mail Tags')->setName('mailtags')->setCaption('Example: <tt>differential-cc, differential-comment</tt>'))->appendChild(id(new AphrontFormDragAndDropUploadControl())->setLabel('Attach Files')->setName('files')->setDragAndDropTarget($panel_id)->setActivatedClass('aphront-panel-view-drag-and-drop'))->appendChild(id(new AphrontFormTextControl())->setLabel('Simulate Failures')->setName('failures')->setCaption($failure_caption))->appendChild(id(new AphrontFormCheckboxControl())->setLabel('HTML')->addCheckbox('html', '1', 'Send as HTML email.'))->appendChild(id(new AphrontFormCheckboxControl())->setLabel('Bulk')->addCheckbox('bulk', '1', 'Send with bulk email headers.'))->appendChild(id(new AphrontFormCheckboxControl())->setLabel('Send Now')->addCheckbox('immediately', '1', 'Send immediately. (Do not enqueue for daemons.)', PhabricatorEnv::getEnvConfig('metamta.send-immediately'))->setCaption('Daemons can be started with ' . $phdlink . '.'))->appendChild(id(new AphrontFormSubmitControl())->setValue('Send Mail'));
     $panel = new AphrontPanelView();
     $panel->setHeader('Send Email');
     $panel->appendChild($form);
     $panel->setID($panel_id);
     $panel->setWidth(AphrontPanelView::WIDTH_FORM);
     $nav = $this->buildSideNavView();
     $nav->selectFilter('send');
     $nav->appendChild(array($warning, $panel));
     return $this->buildApplicationPage($nav, array('title' => 'Send Test'));
 }
 public function getOptions()
 {
     $caches_href = PhabricatorEnv::getDoclink('Managing Caches');
     $custom_field_type = 'custom:PhabricatorCustomFieldConfigOptionType';
     $fields = array(new DifferentialNextStepField(), new DifferentialTitleField(), new DifferentialSummaryField(), new DifferentialTestPlanField(), new DifferentialAuthorField(), new DifferentialReviewersField(), new DifferentialProjectReviewersField(), new DifferentialReviewedByField(), new DifferentialSubscribersField(), new DifferentialRepositoryField(), new DifferentialProjectsField(), new DifferentialViewPolicyField(), new DifferentialEditPolicyField(), new DifferentialDependsOnField(), new DifferentialDependenciesField(), new DifferentialManiphestTasksField(), new DifferentialCommitsField(), new DifferentialJIRAIssuesField(), new DifferentialAsanaRepresentationField(), new DifferentialChangesSinceLastUpdateField(), new DifferentialBranchField(), new DifferentialBlameRevisionField(), new DifferentialPathField(), new DifferentialHostField(), new DifferentialLintField(), new DifferentialUnitField(), new DifferentialRevertPlanField(), new DifferentialApplyPatchField(), new DifferentialRevisionIDField());
     $default_fields = array();
     foreach ($fields as $field) {
         $default_fields[$field->getFieldKey()] = array('disabled' => $field->shouldDisableByDefault());
     }
     return array($this->newOption('differential.fields', $custom_field_type, $default_fields)->setCustomData(id(new DifferentialRevision())->getCustomFieldBaseClass())->setDescription(pht("Select and reorder revision fields.\n\n" . "NOTE: This feature is under active development and subject " . "to change.")), $this->newOption('differential.whitespace-matters', 'list<regex>', array('/\\.py$/', '/\\.l?hs$/'))->setDescription(pht("List of file regexps where whitespace is meaningful and should " . "not use 'ignore-all' by default")), $this->newOption('differential.require-test-plan-field', 'bool', true)->setBoolOptions(array(pht("Require 'Test Plan' field"), pht("Make 'Test Plan' field optional")))->setSummary(pht('Require "Test Plan" field?'))->setDescription(pht("Differential has a required 'Test Plan' field by default. You " . "can make it optional by setting this to false. You can also " . "completely remove it above, if you prefer.")), $this->newOption('differential.enable-email-accept', 'bool', false)->setBoolOptions(array(pht('Enable Email "!accept" Action'), pht('Disable Email "!accept" Action')))->setSummary(pht('Enable or disable "!accept" action via email.'))->setDescription(pht('If inbound email is configured, users can interact with ' . 'revisions by using "!actions" in email replies (for example, ' . '"!resign" or "!rethink"). However, by default, users may not ' . '"!accept" revisions via email: email authentication can be ' . 'configured to be very weak, and email "!accept" is kind of ' . 'sketchy and implies the revision may not actually be receiving ' . 'thorough review. You can enable "!accept" by setting this ' . 'option to true.')), $this->newOption('differential.generated-paths', 'list<regex>', array())->setSummary(pht('File regexps to treat as automatically generated.'))->setDescription(pht('List of file regexps that should be treated as if they are ' . 'generated by an automatic process, and thus be hidden by ' . 'default in Differential.' . "\n\n" . 'NOTE: This property is cached, so you will need to purge the ' . 'cache after making changes if you want the new configuration ' . 'to affect existing revisions. For instructions, see ' . '**[[ %s | Managing Caches ]]** in the documentation.', $caches_href))->addExample("/config\\.h\$/\n#(^|/)autobuilt/#", pht('Valid Setting')), $this->newOption('differential.sticky-accept', 'bool', true)->setBoolOptions(array(pht('Accepts persist across updates'), pht('Accepts are reset by updates')))->setSummary(pht('Should "Accepted" revisions remain "Accepted" after updates?'))->setDescription(pht('Normally, when revisions that have been "Accepted" are updated, ' . 'they remain "Accepted". This allows reviewers to suggest minor ' . 'alterations when accepting, and encourages authors to update ' . 'if they make minor changes in response to this feedback.' . "\n\n" . 'If you want updates to always require re-review, you can disable ' . 'the "stickiness" of the "Accepted" status with this option. ' . 'This may make the process for minor changes much more burdensome ' . 'to both authors and reviewers.')), $this->newOption('differential.allow-self-accept', 'bool', false)->setBoolOptions(array(pht('Allow self-accept'), pht('Disallow self-accept')))->setSummary(pht('Allows users to accept their own revisions.'))->setDescription(pht("If you set this to true, users can accept their own revisions. " . "This action is disabled by default because it's most likely not " . "a behavior you want, but it proves useful if you are working " . "alone on a project and want to make use of all of " . "differential's features.")), $this->newOption('differential.always-allow-close', 'bool', false)->setBoolOptions(array(pht('Allow any user'), pht('Restrict to submitter')))->setSummary(pht('Allows any user to close accepted revisions.'))->setDescription(pht('If you set this to true, any user can close any revision so ' . 'long as it has been accepted. This can be useful depending on ' . 'your development model. For example, github-style pull requests ' . 'where the reviewer is often the actual committer can benefit ' . 'from turning this option to true. If false, only the submitter ' . 'can close a revision.')), $this->newOption('differential.always-allow-abandon', 'bool', false)->setBoolOptions(array(pht('Allow any user'), pht('Restrict to submitter')))->setSummary(pht('Allows any user to abandon revisions.'))->setDescription(pht('If you set this to true, any user can abandon any revision. If ' . 'false, only the submitter can abandon a revision.')), $this->newOption('differential.allow-reopen', 'bool', false)->setBoolOptions(array(pht('Enable reopen'), pht('Disable reopen')))->setSummary(pht('Allows any user to reopen a closed revision.'))->setDescription(pht('If you set this to true, any user can reopen a revision so ' . 'long as it has been closed. This can be useful if a revision ' . 'is accidentally closed or if a developer changes his or her ' . 'mind after closing a revision. If it is false, reopening ' . 'is not allowed.')), $this->newOption('differential.close-on-accept', 'bool', false)->setBoolOptions(array(pht('Treat Accepted Revisions as "Closed"'), pht('Treat Accepted Revisions as "Open"')))->setSummary(pht('Allows "Accepted" to act as a closed status.'))->setDescription(pht('Normally, Differential revisions remain on the dashboard when ' . 'they are "Accepted", and the author then commits the changes ' . 'to "Close" the revision and move it off the dashboard.' . "\n\n" . 'If you have an unusual workflow where Differential is used for ' . 'post-commit review (normally called "Audit", elsewhere in ' . 'Phabricator), you can set this flag to treat the "Accepted" ' . 'state as a "Closed" state and end the review workflow early.' . "\n\n" . 'This sort of workflow is very unusual. Very few installs should ' . 'need to change this option.')), $this->newOption('differential.days-fresh', 'int', 1)->setSummary(pht("For how many business days should a revision be considered " . "'fresh'?"))->setDescription(pht('Revisions newer than this number of days are marked as fresh in ' . 'Action Required and Revisions Waiting on You views. Only work ' . 'days (not weekends and holidays) are included. Set to 0 to ' . 'disable this feature.')), $this->newOption('differential.days-stale', 'int', 3)->setSummary(pht("After this many days, a revision will be considered 'stale'."))->setDescription(pht("Similar to `%s` but marks stale revisions. " . "If the revision is even older than it is when marked as 'old'.", 'differential.days-fresh')), $this->newOption('metamta.differential.subject-prefix', 'string', '[Differential]')->setDescription(pht('Subject prefix for Differential mail.')), $this->newOption('metamta.differential.attach-patches', 'bool', false)->setBoolOptions(array(pht('Attach Patches'), pht('Do Not Attach Patches')))->setSummary(pht('Attach patches to email, as text attachments.'))->setDescription(pht('If you set this to true, Phabricator will attach patches to ' . 'Differential mail (as text attachments). This will not work if ' . 'you are using SendGrid as your mail adapter.')), $this->newOption('metamta.differential.inline-patches', 'int', 0)->setSummary(pht('Inline patches in email, as body text.'))->setDescription(pht("To include patches inline in email bodies, set this to a " . "positive integer. Patches will be inlined if they are at most " . "that many lines. For instance, a value of 100 means 'inline " . "patches if they are no longer than 100 lines'. By default, " . "patches are not inlined.")), $this->newOption('metamta.differential.patch-format', 'string', 'unified')->setDescription(pht("Format for inlined or attached patches: 'git' or 'unified'.")), $this->newOption('metamta.differential.unified-comment-context', 'bool', false)->setBoolOptions(array(pht('Show context'), pht('Do not show context')))->setSummary(pht('Show diff context around inline comments in email.'))->setDescription(pht('Normally, inline comments in emails are shown with a file and ' . 'line but without any diff context. Enabling this option adds ' . 'diff context and the comment thread.')));
 }
 public function handleRequest(AphrontRequest $request)
 {
     $nav = $this->buildSideNavView();
     $nav->selectFilter('cluster/notifications/');
     $title = pht('Cluster Notifications');
     $doc_href = PhabricatorEnv::getDoclink('Cluster: Notifications');
     $header = id(new PHUIHeaderView())->setHeader($title)->setProfileHeader(true)->addActionLink(id(new PHUIButtonView())->setIcon('fa-book')->setHref($doc_href)->setTag('a')->setText(pht('Documentation')));
     $crumbs = $this->buildApplicationCrumbs($nav)->addTextCrumb($title)->setBorder(true);
     $notification_status = $this->buildClusterNotificationStatus();
     $content = id(new PhabricatorConfigPageView())->setHeader($header)->setContent($notification_status);
     return $this->newPage()->setTitle($title)->setCrumbs($crumbs)->setNavigation($nav)->appendChild($content)->addClass('white-background');
 }
Пример #24
0
 public function buildStandardPageResponse($view, array $data)
 {
     $page = $this->buildStandardPageView();
     $page->setApplicationName('Diffusion');
     $page->setBaseURI('/diffusion/');
     $page->setTitle(idx($data, 'title'));
     $page->setGlyph("≈");
     $page->setTabs(array('help' => array('href' => PhabricatorEnv::getDoclink('article/Diffusion_User_Guide.html'), 'name' => 'Help')), null);
     $page->appendChild($view);
     $response = new AphrontWebpageResponse();
     return $response->setContent($page->render());
 }
Пример #25
0
 public function render()
 {
     require_celerity_resource('ponder-core-view-css');
     $is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business');
     $question = $this->question;
     $panel = id(new AphrontPanelView())->addClass("ponder-panel")->setHeader("Your Answer:");
     $form = new AphrontFormView();
     $form->setUser($this->user)->setAction($this->actionURI)->addHiddenInput('question_id', $question->getID())->appendChild(id(new AphrontFormTextAreaControl())->setName('answer')->setID('answer-content')->setEnableDragAndDropFileUploads(true)->setCaption(phutil_render_tag('a', array('href' => PhabricatorEnv::getDoclink('article/Remarkup_Reference.html'), 'tabindex' => '-1', 'target' => '_blank'), 'Formatting Reference')))->appendChild(id(new AphrontFormSubmitControl())->setValue($is_serious ? 'Submit' : 'Make it so.'));
     $panel->appendChild($form);
     $panel->appendChild('<div class="aphront-panel-flush">' . '<div id="answer-preview">' . '<span class="aphront-panel-preview-loading-text">' . 'Loading answer preview...' . '</span>' . '</div>' . '</div>');
     Javelin::initBehavior('ponder-feedback-preview', array('uri' => '/ponder/answer/preview/', 'content' => 'answer-content', 'preview' => 'answer-preview', 'question_id' => $question->getID()));
     return $panel->render();
 }
 public function getOptions()
 {
     if (phutil_is_windows()) {
         $paths = array();
     } else {
         $paths = array('/bin', '/usr/bin', '/usr/local/bin');
     }
     $path = getenv('PATH');
     $proto_doc_href = PhabricatorEnv::getDoclink('User Guide: Prototype Applications');
     $proto_doc_name = pht('User Guide: Prototype Applications');
     $applications_app_href = '/applications/';
     return array($this->newOption('phabricator.base-uri', 'string', null)->setLocked(true)->setSummary(pht('URI where Phabricator is installed.'))->setDescription(pht('Set the URI where Phabricator is installed. Setting this ' . 'improves security by preventing cookies from being set on other ' . 'domains, and allows daemons to send emails with links that have ' . 'the correct domain.'))->addExample('http://phabricator.example.com/', pht('Valid Setting')), $this->newOption('phabricator.production-uri', 'string', null)->setSummary(pht('Primary install URI, for multi-environment installs.'))->setDescription(pht('If you have multiple Phabricator environments (like a ' . 'development/staging environment for working on testing ' . 'Phabricator, and a production environment for deploying it), ' . 'set the production environment URI here so that emails and other ' . 'durable URIs will always generate with links pointing at the ' . 'production environment. If unset, defaults to `%s`. Most ' . 'installs do not need to set this option.', 'phabricator.base-uri'))->addExample('http://phabricator.example.com/', pht('Valid Setting')), $this->newOption('phabricator.allowed-uris', 'list<string>', array())->setLocked(true)->setSummary(pht('Alternative URIs that can access Phabricator.'))->setDescription(pht("These alternative URIs will be able to access 'normal' pages " . "on your Phabricator install. Other features such as OAuth " . "won't work. The major use case for this is moving installs " . "across domains."))->addExample("http://phabricator2.example.com/\n" . "http://phabricator3.example.com/", pht('Valid Setting')), $this->newOption('phabricator.timezone', 'string', null)->setSummary(pht('The timezone Phabricator should use.'))->setDescription(pht("PHP requires that you set a timezone in your php.ini before " . "using date functions, or it will emit a warning. If this isn't " . "possible (for instance, because you are using HPHP) you can set " . "some valid constant for %s here and Phabricator will set it on " . "your behalf, silencing the warning.", 'date_default_timezone_set()'))->addExample('America/New_York', pht('US East (EDT)'))->addExample('America/Chicago', pht('US Central (CDT)'))->addExample('America/Boise', pht('US Mountain (MDT)'))->addExample('America/Los_Angeles', pht('US West (PDT)')), $this->newOption('phabricator.cookie-prefix', 'string', null)->setLocked(true)->setSummary(pht('Set a string Phabricator should use to prefix cookie names.'))->setDescription(pht('Cookies set for x.com are also sent for y.x.com. Assuming ' . 'Phabricator instances are running on both domains, this will ' . 'create a collision preventing you from logging in.'))->addExample('dev', pht('Prefix cookie with "%s"', 'dev')), $this->newOption('phabricator.show-prototypes', 'bool', false)->setLocked(true)->setBoolOptions(array(pht('Enable Prototypes'), pht('Disable Prototypes')))->setSummary(pht('Install applications which are still under development.'))->setDescription(pht("IMPORTANT: The upstream does not provide support for prototype " . "applications." . "\n\n" . "Phabricator includes prototype applications which are in an " . "**early stage of development**. By default, prototype " . "applications are not installed, because they are often not yet " . "developed enough to be generally usable. You can enable " . "this option to install them if you're developing Phabricator " . "or are interested in previewing upcoming features." . "\n\n" . "To learn more about prototypes, see [[ %s | %s ]]." . "\n\n" . "After enabling prototypes, you can selectively uninstall them " . "(like normal applications).", $proto_doc_href, $proto_doc_name)), $this->newOption('phabricator.serious-business', 'bool', false)->setBoolOptions(array(pht('Serious business'), pht('Shenanigans')))->setSummary(pht('Allows you to remove levity and jokes from the UI.'))->setDescription(pht('By default, Phabricator includes some flavor text in the UI, ' . 'like a prompt to "Weigh In" rather than "Add Comment" in ' . 'Maniphest. If you\'d prefer more traditional UI strings like ' . '"Add Comment", you can set this flag to disable most of the ' . 'extra flavor.')), $this->newOption('remarkup.ignored-object-names', 'string', '/^(Q|V)\\d$/')->setSummary(pht('Text values that match this regex and are also object names ' . 'will not be linked.'))->setDescription(pht('By default, Phabricator links object names in Remarkup fields ' . 'to the corresponding object. This regex can be used to modify ' . 'this behavior; object names that match this regex will not be ' . 'linked.')), $this->newOption('environment.append-paths', 'list<string>', $paths)->setSummary(pht('These paths get appended to your %s environment variable.', '$PATH'))->setDescription(pht("Phabricator occasionally shells out to other binaries on the " . "server. An example of this is the `%s` command, used to " . "syntax-highlight code written in languages other than PHP. By " . "default, it is assumed that these binaries are in the %s of the " . "user running Phabricator (normally 'apache', 'httpd', or " . "'nobody'). Here you can add extra directories to the %s " . "environment variable, for when these binaries are in " . "non-standard locations.\n\n" . "Note that you can also put binaries in `%s` (for example, by " . "symlinking them).\n\n" . "The current value of PATH after configuration is applied is:\n\n" . "  lang=text\n" . "  %s", 'pygmentize', '$PATH', '$PATH', 'phabricator/support/bin/', $path))->setLocked(true)->addExample('/usr/local/bin', pht('Add One Path'))->addExample("/usr/bin\n/usr/local/bin", pht('Add Multiple Paths')), $this->newOption('config.lock', 'set', array())->setLocked(true)->setDescription(pht('Additional configuration options to lock.')), $this->newOption('config.hide', 'set', array())->setLocked(true)->setDescription(pht('Additional configuration options to hide.')), $this->newOption('config.ignore-issues', 'set', array())->setLocked(true)->setDescription(pht('Setup issues to ignore.')), $this->newOption('phabricator.env', 'string', null)->setLocked(true)->setDescription(pht('Internal.')), $this->newOption('test.value', 'wild', null)->setLocked(true)->setDescription(pht('Unit test value.')), $this->newOption('phabricator.uninstalled-applications', 'set', array())->setLocked(true)->setLockedMessage(pht('Use the %s to manage installed applications.', phutil_tag('a', array('href' => $applications_app_href), pht('Applications application'))))->setDescription(pht('Array containing list of uninstalled applications.')), $this->newOption('phabricator.application-settings', 'wild', array())->setLocked(true)->setDescription(pht('Customized settings for Phabricator applications.')), $this->newOption('welcome.html', 'string', null)->setLocked(true)->setDescription(pht('Custom HTML to show on the main Phabricator dashboard.')), $this->newOption('phabricator.cache-namespace', 'string', 'phabricator')->setLocked(true)->setDescription(pht('Cache namespace.')), $this->newOption('phabricator.allow-email-users', 'bool', false)->setBoolOptions(array(pht('Allow'), pht('Disallow')))->setDescription(pht('Allow non-members to interact with tasks over email.')), $this->newOption('phabricator.silent', 'bool', false)->setLocked(true)->setBoolOptions(array(pht('Run Silently'), pht('Run Normally')))->setSummary(pht('Stop Phabricator from sending any email, etc.'))->setDescription(pht('This option allows you to stop Phabricator from sending ' . 'any data to external services. Among other things, it will ' . 'disable email, SMS, repository mirroring, and HTTP hooks.' . "\n\n" . 'This option is intended to allow a Phabricator instance to ' . 'be exported, copied, imported, and run in a test environment ' . 'without impacting users. For example, if you are migrating ' . 'to new hardware, you could perform a test migration first, ' . 'make sure things work, and then do a production cutover ' . 'later with higher confidence and less disruption. Without ' . 'this flag, users would receive duplicate email during the ' . 'time the test instance and old production instance were ' . 'both in operation.')));
 }
Пример #27
0
 public function buildStandardPageResponse($view, array $data)
 {
     $page = $this->buildStandardPageView();
     $page->setApplicationName('Herald');
     $page->setBaseURI('/herald/');
     $page->setTitle(idx($data, 'title'));
     $page->setGlyph("☿");
     $page->appendChild($view);
     $doclink = PhabricatorEnv::getDoclink('article/Herald_User_Guide.html');
     $page->setTabs(array('rules' => array('href' => '/herald/', 'name' => 'Rules'), 'test' => array('href' => '/herald/test/', 'name' => 'Test Console'), 'transcripts' => array('href' => '/herald/transcript/', 'name' => 'Transcripts'), 'help' => array('href' => $doclink, 'name' => 'Help')), idx($data, 'tab'));
     $response = new AphrontWebpageResponse();
     return $response->setContent($page->render());
 }
 protected function getNoticeView()
 {
     $user = $this->getRequest()->getUser();
     $new_link = phutil_render_tag('a', array('href' => '/phame/post/new/', 'class' => 'button green'), 'write a blog post');
     $remarkup_link = phutil_render_tag('a', array('href' => PhabricatorEnv::getDoclink('article/Remarkup_Reference.html')), 'remarkup');
     $guide_link = phutil_render_tag('a', array('href' => PhabricatorEnv::getDoclink('article/Phame_User_Guide.html')), 'Phame user guide');
     $notices = array('Seek phame and ' . $new_link, 'Use ' . $remarkup_link . ' for maximal elegance, grace, and style. ', 'If you need more help try the ' . $guide_link . '.');
     $notice_view = $this->buildNoticeView();
     foreach ($notices as $notice) {
         $notice_view->appendChild('<p>' . $notice . '</p>');
     }
     return $notice_view;
 }
 public function processRequest(AphrontRequest $request)
 {
     if ($request->getExists('new')) {
         return $this->processNew($request);
     }
     if ($request->getExists('edit')) {
         return $this->processEdit($request);
     }
     if ($request->getExists('delete')) {
         return $this->processDelete($request);
     }
     $user = $this->getUser();
     $viewer = $request->getUser();
     $factors = id(new PhabricatorAuthFactorConfig())->loadAllWhere('userPHID = %s', $user->getPHID());
     $rows = array();
     $rowc = array();
     $highlight_id = $request->getInt('id');
     foreach ($factors as $factor) {
         $impl = $factor->getImplementation();
         if ($impl) {
             $type = $impl->getFactorName();
         } else {
             $type = $factor->getFactorKey();
         }
         if ($factor->getID() == $highlight_id) {
             $rowc[] = 'highlighted';
         } else {
             $rowc[] = null;
         }
         $rows[] = array(javelin_tag('a', array('href' => $this->getPanelURI('?edit=' . $factor->getID()), 'sigil' => 'workflow'), $factor->getFactorName()), $type, phabricator_datetime($factor->getDateCreated(), $viewer), javelin_tag('a', array('href' => $this->getPanelURI('?delete=' . $factor->getID()), 'sigil' => 'workflow', 'class' => 'small grey button'), pht('Remove')));
     }
     $table = new AphrontTableView($rows);
     $table->setNoDataString(pht("You haven't added any authentication factors to your account yet."));
     $table->setHeaders(array(pht('Name'), pht('Type'), pht('Created'), ''));
     $table->setColumnClasses(array('wide pri', '', 'right', 'action'));
     $table->setRowClasses($rowc);
     $table->setDeviceVisibility(array(true, false, false, true));
     $panel = new PHUIObjectBoxView();
     $header = new PHUIHeaderView();
     $help_uri = PhabricatorEnv::getDoclink('User Guide: Multi-Factor Authentication');
     $help_icon = id(new PHUIIconView())->setIconFont('fa-info-circle');
     $help_button = id(new PHUIButtonView())->setText(pht('Help'))->setHref($help_uri)->setTag('a')->setIcon($help_icon);
     $create_icon = id(new PHUIIconView())->setIconFont('fa-plus');
     $create_button = id(new PHUIButtonView())->setText(pht('Add Authentication Factor'))->setHref($this->getPanelURI('?new=true'))->setTag('a')->setWorkflow(true)->setIcon($create_icon);
     $header->setHeader(pht('Authentication Factors'));
     $header->addActionLink($help_button);
     $header->addActionLink($create_button);
     $panel->setHeader($header);
     $panel->setTable($table);
     return $panel;
 }
Пример #30
0
 protected function addClusterMessage($positive, $negative)
 {
     $can_manage = $this->hasApplicationCapability(AlmanacManageClusterServicesCapability::CAPABILITY);
     $doc_link = phutil_tag('a', array('href' => PhabricatorEnv::getDoclink('Clustering Introduction'), 'target' => '_blank'), pht('Learn More'));
     if ($can_manage) {
         $severity = PHUIInfoView::SEVERITY_NOTICE;
         $message = $positive;
     } else {
         $severity = PHUIInfoView::SEVERITY_WARNING;
         $message = $negative;
     }
     $icon = id(new PHUIIconView())->setIcon('fa-sitemap');
     return id(new PHUIInfoView())->setSeverity($severity)->setErrors(array(array($icon, ' ', $message, ' ', $doc_link)));
 }