public function handleRequest(AphrontRequest $request)
 {
     $viewer = $request->getViewer();
     $books = id(new DivinerBookQuery())->setViewer($viewer)->execute();
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->setBorder(true);
     $crumbs->addTextCrumb(pht('Books'));
     $query_button = id(new PHUIButtonView())->setTag('a')->setHref($this->getApplicationURI('query/'))->setText(pht('Advanced Search'))->setIcon('fa-search');
     $header = id(new PHUIHeaderView())->setHeader(pht('Documentation Books'))->addActionLink($query_button);
     $document = new PHUIDocumentViewPro();
     $document->setHeader($header);
     $document->addClass('diviner-view');
     if ($books) {
         $books = msort($books, 'getTitle');
         $list = array();
         foreach ($books as $book) {
             $item = id(new DivinerBookItemView())->setTitle($book->getTitle())->setHref('/book/' . $book->getName() . '/')->setSubtitle($book->getPreface());
             $list[] = $item;
         }
         $list = id(new PHUIBoxView())->addPadding(PHUI::PADDING_MEDIUM_TOP)->appendChild($list);
         $document->appendChild($list);
     } else {
         $text = pht("(NOTE) **Looking for Phabricator documentation?** " . "If you're looking for help and information about Phabricator, " . "you can [[https://secure.phabricator.com/diviner/ | " . "browse the public Phabricator documentation]] on the live site.\n\n" . "Diviner is the documentation generator used to build the " . "Phabricator documentation.\n\n" . "You haven't generated any Diviner documentation books yet, so " . "there's nothing to show here. If you'd like to generate your own " . "local copy of the Phabricator documentation and have it appear " . "here, run this command:\n\n" . "  %s\n\n", 'phabricator/ $ ./bin/diviner generate');
         $text = new PHUIRemarkupView($viewer, $text);
         $document->appendChild($text);
     }
     return $this->newPage()->setTitle(pht('Documentation Books'))->setCrumbs($crumbs)->appendChild(array($document));
 }
 public function handleRequest(AphrontRequest $request)
 {
     $viewer = $request->getViewer();
     $book_name = $request->getURIData('book');
     $book = id(new DivinerBookQuery())->setViewer($viewer)->withNames(array($book_name))->needRepositories(true)->executeOne();
     if (!$book) {
         return new Aphront404Response();
     }
     $actions = $this->buildActionView($viewer, $book);
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->setBorder(true);
     $crumbs->addTextCrumb($book->getShortTitle(), '/book/' . $book->getName() . '/');
     $action_button = id(new PHUIButtonView())->setTag('a')->setText(pht('Actions'))->setHref('#')->setIconFont('fa-bars')->addClass('phui-mobile-menu')->setDropdownMenu($actions);
     $header = id(new PHUIHeaderView())->setHeader($book->getTitle())->setUser($viewer)->setPolicyObject($book)->setEpoch($book->getDateModified())->addActionLink($action_button);
     // TODO: This could probably look better.
     if ($book->getRepositoryPHID()) {
         $header->addTag(id(new PHUITagView())->setType(PHUITagView::TYPE_STATE)->setBackgroundColor(PHUITagView::COLOR_BLUE)->setName($book->getRepository()->getMonogram()));
     }
     $document = new PHUIDocumentViewPro();
     $document->setHeader($header);
     $document->addClass('diviner-view');
     $atoms = id(new DivinerAtomQuery())->setViewer($viewer)->withBookPHIDs(array($book->getPHID()))->withGhosts(false)->withIsDocumentable(true)->execute();
     $atoms = msort($atoms, 'getSortKey');
     $group_spec = $book->getConfig('groups');
     if (!is_array($group_spec)) {
         $group_spec = array();
     }
     $groups = mgroup($atoms, 'getGroupName');
     $groups = array_select_keys($groups, array_keys($group_spec)) + $groups;
     if (isset($groups[''])) {
         $no_group = $groups[''];
         unset($groups['']);
         $groups[''] = $no_group;
     }
     $out = array();
     foreach ($groups as $group => $atoms) {
         $group_name = $book->getGroupName($group);
         if (!strlen($group_name)) {
             $group_name = pht('Free Radicals');
         }
         $section = id(new DivinerSectionView())->setHeader($group_name);
         $section->addContent($this->renderAtomList($atoms));
         $out[] = $section;
     }
     $preface = $book->getPreface();
     $preface_view = null;
     if (strlen($preface)) {
         $preface_view = PhabricatorMarkupEngine::renderOneObject(id(new PhabricatorMarkupOneOff())->setContent($preface), 'default', $viewer);
     }
     $document->appendChild($preface_view);
     $document->appendChild($out);
     return $this->buildApplicationPage(array($crumbs, $document), array('title' => $book->getTitle()));
 }