private function buildChartForm()
 {
     $request = $this->getRequest();
     $viewer = $request->getUser();
     $table = new PhabricatorFactRaw();
     $conn_r = $table->establishConnection('r');
     $table_name = $table->getTableName();
     $facts = queryfx_all($conn_r, 'SELECT DISTINCT factType from %T', $table_name);
     $specs = PhabricatorFactSpec::newSpecsForFactTypes(PhabricatorFactEngine::loadAllEngines(), ipull($facts, 'factType'));
     $options = array();
     foreach ($specs as $spec) {
         if ($spec->getUnit() == PhabricatorFactSpec::UNIT_COUNT) {
             $options[$spec->getType()] = $spec->getName();
         }
     }
     if (!$options) {
         return id(new PHUIInfoView())->setSeverity(PHUIInfoView::SEVERITY_NODATA)->setTitle(pht('No Chartable Facts'))->appendChild(phutil_tag('p', array(), pht('There are no facts that can be plotted yet.')));
     }
     $form = id(new AphrontFormView())->setUser($viewer)->appendChild(id(new AphrontFormSelectControl())->setLabel(pht('Y-Axis'))->setName('y1')->setOptions($options))->appendChild(id(new AphrontFormSubmitControl())->setValue(pht('Plot Chart')));
     $panel = new PHUIObjectBoxView();
     $panel->setForm($form);
     $panel->setHeaderText(pht('Plot Chart'));
     return $panel;
 }
 private function processSearchRequest()
 {
     $parent = $this->getDelegatingController();
     $request = $this->getRequest();
     $user = $request->getUser();
     $engine = $this->getSearchEngine();
     $nav = $this->getNavigation();
     if ($request->isFormPost()) {
         $saved_query = $engine->buildSavedQueryFromRequest($request);
         $engine->saveQuery($saved_query);
         return id(new AphrontRedirectResponse())->setURI($engine->getQueryResultsPageURI($saved_query->getQueryKey()) . '#R');
     }
     $named_query = null;
     $run_query = true;
     $query_key = $this->queryKey;
     if ($this->queryKey == 'advanced') {
         $run_query = false;
         $query_key = $request->getStr('query');
     } else {
         if (!strlen($this->queryKey)) {
             $found_query_data = false;
             if ($request->isHTTPGet()) {
                 // If this is a GET request and it has some query data, don't
                 // do anything unless it's only before= or after=. We'll build and
                 // execute a query from it below. This allows external tools to build
                 // URIs like "/query/?users=a,b".
                 $pt_data = $request->getPassthroughRequestData();
                 foreach ($pt_data as $pt_key => $pt_value) {
                     if ($pt_key != 'before' && $pt_key != 'after') {
                         $found_query_data = true;
                         break;
                     }
                 }
             }
             if (!$found_query_data) {
                 // Otherwise, there's no query data so just run the user's default
                 // query for this application.
                 $query_key = head_key($engine->loadEnabledNamedQueries());
             }
         }
     }
     if ($engine->isBuiltinQuery($query_key)) {
         $saved_query = $engine->buildSavedQueryFromBuiltin($query_key);
         $named_query = idx($engine->loadEnabledNamedQueries(), $query_key);
     } else {
         if ($query_key) {
             $saved_query = id(new PhabricatorSavedQueryQuery())->setViewer($user)->withQueryKeys(array($query_key))->executeOne();
             if (!$saved_query) {
                 return new Aphront404Response();
             }
             $named_query = idx($engine->loadEnabledNamedQueries(), $query_key);
         } else {
             $saved_query = $engine->buildSavedQueryFromRequest($request);
             // Save the query to generate a query key, so "Save Custom Query..." and
             // other features like Maniphest's "Export..." work correctly.
             $engine->saveQuery($saved_query);
         }
     }
     $nav->selectFilter('query/' . $saved_query->getQueryKey(), 'query/advanced');
     $form = id(new AphrontFormView())->setUser($user)->setAction($request->getPath());
     $engine->buildSearchForm($form, $saved_query);
     $errors = $engine->getErrors();
     if ($errors) {
         $run_query = false;
     }
     $submit = id(new AphrontFormSubmitControl())->setValue(pht('Execute Query'));
     if ($run_query && !$named_query && $user->isLoggedIn()) {
         $submit->addCancelButton('/search/edit/' . $saved_query->getQueryKey() . '/', pht('Save Custom Query...'));
     }
     // TODO: A "Create Dashboard Panel" action goes here somewhere once
     // we sort out T5307.
     $form->appendChild($submit);
     if ($this->getPreface()) {
         $nav->appendChild($this->getPreface());
     }
     if ($named_query) {
         $title = $named_query->getQueryName();
     } else {
         $title = pht('Advanced Search');
     }
     $box = new PHUIObjectBoxView();
     if ($run_query || $named_query) {
         $box->setShowHide(pht('Edit Query'), pht('Hide Query'), $form, $this->getApplicationURI('query/advanced/?query=' . $query_key), !$named_query ? true : false);
     } else {
         $box->setForm($form);
     }
     $nav->appendChild($box);
     if ($run_query) {
         $box->setAnchor(id(new PhabricatorAnchorView())->setAnchorName('R'));
         try {
             $query = $engine->buildQueryFromSavedQuery($saved_query);
             $pager = $engine->newPagerForSavedQuery($saved_query);
             $pager->readFromRequest($request);
             $objects = $engine->executeQuery($query, $pager);
             // TODO: To support Dashboard panels, rendering is moving into
             // SearchEngines. Move it all the way in and then get rid of this.
             $interface = 'PhabricatorApplicationSearchResultsControllerInterface';
             if ($parent instanceof $interface) {
                 $list = $parent->renderResultsList($objects, $saved_query);
             } else {
                 $engine->setRequest($request);
                 $list = $engine->renderResults($objects, $saved_query);
             }
             $header = id(new PHUIHeaderView())->setHeader($title);
             if ($list->getActions()) {
                 foreach ($list->getActions() as $action) {
                     $header->addActionLink($action);
                 }
             }
             $box->setHeader($header);
             if ($list->getObjectList()) {
                 $box->setObjectList($list->getObjectList());
             }
             if ($list->getTable()) {
                 $box->setTable($list->getTable());
             }
             if ($list->getInfoView()) {
                 $box->setInfoView($list->getInfoView());
             }
             if ($list->getContent()) {
                 $box->appendChild($list->getContent());
             }
             if ($list->getCollapsed()) {
                 $box->setCollapsed(true);
             }
             if ($pager->willShowPagingControls()) {
                 $pager_box = id(new PHUIBoxView())->addPadding(PHUI::PADDING_MEDIUM)->addMargin(PHUI::MARGIN_LARGE)->setBorder(true)->appendChild($pager);
                 $nav->appendChild($pager_box);
             }
         } catch (PhabricatorTypeaheadInvalidTokenException $ex) {
             $errors[] = pht('This query specifies an invalid parameter. Review the ' . 'query parameters and correct errors.');
         }
     } else {
         $box->setHeaderText($title);
     }
     if ($errors) {
         $box->setFormErrors($errors, pht('Query Errors'));
     }
     $crumbs = $parent->buildApplicationCrumbs()->addTextCrumb($title);
     $nav->setCrumbs($crumbs);
     return $this->buildApplicationPage($nav, array('title' => pht('Query: %s', $title)));
 }