1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-30 10:42:41 +01:00

Use ApplicationSearch in Diviner

Summary: Ref T988. Ref T2625. Rough cut of ApplicationSearch in Diviner, for detailed Atom queries. This isn't useful yet, and isn't linked in the UI.

Test Plan: {F44836}

Reviewers: btrahan, chad

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T988, T2625

Differential Revision: https://secure.phabricator.com/D6094
This commit is contained in:
epriestley 2013-05-31 10:52:25 -07:00
parent 87bc6eb28c
commit 06c94b8515
10 changed files with 316 additions and 8 deletions

View file

@ -503,15 +503,20 @@ phutil_register_library_map(array(
'DivinerArticleAtomizer' => 'applications/diviner/atomizer/DivinerArticleAtomizer.php', 'DivinerArticleAtomizer' => 'applications/diviner/atomizer/DivinerArticleAtomizer.php',
'DivinerAtom' => 'applications/diviner/atom/DivinerAtom.php', 'DivinerAtom' => 'applications/diviner/atom/DivinerAtom.php',
'DivinerAtomCache' => 'applications/diviner/cache/DivinerAtomCache.php', 'DivinerAtomCache' => 'applications/diviner/cache/DivinerAtomCache.php',
'DivinerAtomListController' => 'applications/diviner/controller/DivinerAtomListController.php',
'DivinerAtomQuery' => 'applications/diviner/query/DivinerAtomQuery.php',
'DivinerAtomRef' => 'applications/diviner/atom/DivinerAtomRef.php', 'DivinerAtomRef' => 'applications/diviner/atom/DivinerAtomRef.php',
'DivinerAtomSearchEngine' => 'applications/diviner/query/DivinerAtomSearchEngine.php',
'DivinerAtomizeWorkflow' => 'applications/diviner/workflow/DivinerAtomizeWorkflow.php', 'DivinerAtomizeWorkflow' => 'applications/diviner/workflow/DivinerAtomizeWorkflow.php',
'DivinerAtomizer' => 'applications/diviner/atomizer/DivinerAtomizer.php', 'DivinerAtomizer' => 'applications/diviner/atomizer/DivinerAtomizer.php',
'DivinerBookQuery' => 'applications/diviner/query/DivinerBookQuery.php',
'DivinerController' => 'applications/diviner/controller/DivinerController.php',
'DivinerDAO' => 'applications/diviner/storage/DivinerDAO.php', 'DivinerDAO' => 'applications/diviner/storage/DivinerDAO.php',
'DivinerDefaultRenderer' => 'applications/diviner/renderer/DivinerDefaultRenderer.php', 'DivinerDefaultRenderer' => 'applications/diviner/renderer/DivinerDefaultRenderer.php',
'DivinerDiskCache' => 'applications/diviner/cache/DivinerDiskCache.php', 'DivinerDiskCache' => 'applications/diviner/cache/DivinerDiskCache.php',
'DivinerFileAtomizer' => 'applications/diviner/atomizer/DivinerFileAtomizer.php', 'DivinerFileAtomizer' => 'applications/diviner/atomizer/DivinerFileAtomizer.php',
'DivinerGenerateWorkflow' => 'applications/diviner/workflow/DivinerGenerateWorkflow.php', 'DivinerGenerateWorkflow' => 'applications/diviner/workflow/DivinerGenerateWorkflow.php',
'DivinerListController' => 'applications/diviner/controller/DivinerListController.php', 'DivinerLegacyController' => 'applications/diviner/controller/DivinerLegacyController.php',
'DivinerLiveAtom' => 'applications/diviner/storage/DivinerLiveAtom.php', 'DivinerLiveAtom' => 'applications/diviner/storage/DivinerLiveAtom.php',
'DivinerLiveBook' => 'applications/diviner/storage/DivinerLiveBook.php', 'DivinerLiveBook' => 'applications/diviner/storage/DivinerLiveBook.php',
'DivinerLivePublisher' => 'applications/diviner/publisher/DivinerLivePublisher.php', 'DivinerLivePublisher' => 'applications/diviner/publisher/DivinerLivePublisher.php',
@ -2316,12 +2321,21 @@ phutil_register_library_map(array(
'DiffusionView' => 'AphrontView', 'DiffusionView' => 'AphrontView',
'DivinerArticleAtomizer' => 'DivinerAtomizer', 'DivinerArticleAtomizer' => 'DivinerAtomizer',
'DivinerAtomCache' => 'DivinerDiskCache', 'DivinerAtomCache' => 'DivinerDiskCache',
'DivinerAtomListController' =>
array(
0 => 'DivinerController',
1 => 'PhabricatorApplicationSearchResultsControllerInterface',
),
'DivinerAtomQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'DivinerAtomSearchEngine' => 'PhabricatorApplicationSearchEngine',
'DivinerAtomizeWorkflow' => 'DivinerWorkflow', 'DivinerAtomizeWorkflow' => 'DivinerWorkflow',
'DivinerBookQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'DivinerController' => 'PhabricatorController',
'DivinerDAO' => 'PhabricatorLiskDAO', 'DivinerDAO' => 'PhabricatorLiskDAO',
'DivinerDefaultRenderer' => 'DivinerRenderer', 'DivinerDefaultRenderer' => 'DivinerRenderer',
'DivinerFileAtomizer' => 'DivinerAtomizer', 'DivinerFileAtomizer' => 'DivinerAtomizer',
'DivinerGenerateWorkflow' => 'DivinerWorkflow', 'DivinerGenerateWorkflow' => 'DivinerWorkflow',
'DivinerListController' => 'PhabricatorController', 'DivinerLegacyController' => 'DivinerController',
'DivinerLiveAtom' => 'DivinerDAO', 'DivinerLiveAtom' => 'DivinerDAO',
'DivinerLiveBook' => 'DivinerLiveBook' =>
array( array(
@ -2329,7 +2343,11 @@ phutil_register_library_map(array(
1 => 'PhabricatorPolicyInterface', 1 => 'PhabricatorPolicyInterface',
), ),
'DivinerLivePublisher' => 'DivinerPublisher', 'DivinerLivePublisher' => 'DivinerPublisher',
'DivinerLiveSymbol' => 'DivinerDAO', 'DivinerLiveSymbol' =>
array(
0 => 'DivinerDAO',
1 => 'PhabricatorPolicyInterface',
),
'DivinerPublishCache' => 'DivinerDiskCache', 'DivinerPublishCache' => 'DivinerDiskCache',
'DivinerRemarkupRuleSymbol' => 'PhutilRemarkupRule', 'DivinerRemarkupRuleSymbol' => 'PhutilRemarkupRule',
'DivinerStaticPublisher' => 'DivinerPublisher', 'DivinerStaticPublisher' => 'DivinerPublisher',

View file

@ -20,7 +20,10 @@ final class PhabricatorApplicationDiviner extends PhabricatorApplication {
public function getRoutes() { public function getRoutes() {
return array( return array(
'/diviner/' => 'DivinerListController', '/diviner/' => array(
'' => 'DivinerLegacyController',
'query/((?<key>[^/]+)/)?' => 'DivinerAtomListController',
),
); );
} }

View file

@ -0,0 +1,46 @@
<?php
final class DivinerAtomListController extends DivinerController
implements PhabricatorApplicationSearchResultsControllerInterface {
private $key;
public function shouldAllowPublic() {
return true;
}
public function willProcessRequest(array $data) {
$this->key = idx($data, 'key', 'all');
}
public function processRequest() {
$request = $this->getRequest();
$controller = id(new PhabricatorApplicationSearchController($request))
->setQueryKey($this->key)
->setSearchEngine(new DivinerAtomSearchEngine())
->setNavigation($this->buildSideNavView());
return $this->delegateToController($controller);
}
public function renderResultsList(array $symbols) {
assert_instances_of($symbols, 'DivinerLiveSymbol');
$request = $this->getRequest();
$user = $request->getUser();
$list = id(new PhabricatorObjectItemListView())
->setUser($user);
foreach ($symbols as $symbol) {
$item = id(new PhabricatorObjectItemView())
->setHeader($symbol->getName())
->addIcon('none', $symbol->getType());
$list->addItem($item);
}
return $list;
}
}

View file

@ -0,0 +1,24 @@
<?php
abstract class DivinerController extends PhabricatorController {
protected function buildSideNavView() {
$menu = $this->buildMenu();
return AphrontSideNavFilterView::newFromMenu($menu);
}
protected function buildApplicationMenu() {
return $this->buildMenu();
}
private function buildMenu() {
$menu = new PhabricatorMenuView();
id(new DivinerAtomSearchEngine())
->setViewer($this->getRequest()->getUser())
->addNavigationItems($menu);
return $menu;
}
}

View file

@ -1,6 +1,6 @@
<?php <?php
final class DivinerListController extends PhabricatorController { final class DivinerLegacyController extends DivinerController {
public function processRequest() { public function processRequest() {

View file

@ -104,9 +104,9 @@ final class DivinerLivePublisher extends DivinerPublisher {
if ($this->shouldGenerateDocumentForAtom($atom)) { if ($this->shouldGenerateDocumentForAtom($atom)) {
$content = $this->getRenderer()->renderAtom($atom); $content = $this->getRenderer()->renderAtom($atom);
$this->loadAtomStorageForSymbol($symbol) $storage = $this->loadAtomStorageForSymbol($symbol)
->setAtomData($atom->toDictionary()) ->setAtomData($atom->toDictionary())
->setContent(phutil_safe_html($content)) ->setContent((string)phutil_safe_html($content))
->save(); ->save();
} }
} }

View file

@ -0,0 +1,81 @@
<?php
final class DivinerAtomQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
protected function loadPage() {
$table = new DivinerLiveSymbol();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function willFilterPage(array $atoms) {
if (!$atoms) {
return $atoms;
}
$books = array_unique(mpull($atoms, 'getBookPHID'));
$books = id(new DivinerBookQuery())
->setViewer($this->getViewer())
->withPHIDs($books)
->execute();
$books = mpull($books, null, 'getPHID');
foreach ($atoms as $key => $atom) {
$book = idx($books, $atom->getBookPHID());
if (!$book) {
unset($atoms[$key]);
continue;
}
$atom->attachBook($book);
}
return $atoms;
}
private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
}

View file

@ -0,0 +1,49 @@
<?php
final class DivinerAtomSearchEngine
extends PhabricatorApplicationSearchEngine {
public function buildSavedQueryFromRequest(AphrontRequest $request) {
$saved = new PhabricatorSavedQuery();
return $saved;
}
public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) {
$query = id(new DivinerAtomQuery());
return $query;
}
public function buildSearchForm(
AphrontFormView $form,
PhabricatorSavedQuery $saved_query) {
}
protected function getURI($path) {
return '/diviner/'.$path;
}
public function getBuiltinQueryNames() {
$names = array(
'all' => pht('All'),
);
return $names;
}
public function buildSavedQueryFromBuiltin($query_key) {
$query = $this->newSavedQuery();
$query->setQueryKey($query_key);
switch ($query_key) {
case 'all':
return $query;
}
return parent::buildSavedQueryFromBuiltin($query_key);
}
}

View file

@ -0,0 +1,56 @@
<?php
final class DivinerBookQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
protected function loadPage() {
$table = new DivinerLiveBook();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
}

View file

@ -1,6 +1,7 @@
<?php <?php
final class DivinerLiveSymbol extends DivinerDAO { final class DivinerLiveSymbol extends DivinerDAO
implements PhabricatorPolicyInterface {
protected $phid; protected $phid;
protected $bookPHID; protected $bookPHID;
@ -11,6 +12,8 @@ final class DivinerLiveSymbol extends DivinerDAO {
protected $graphHash; protected $graphHash;
protected $identityHash; protected $identityHash;
private $book;
public function getConfiguration() { public function getConfiguration() {
return array( return array(
self::CONFIG_AUX_PHID => true, self::CONFIG_AUX_PHID => true,
@ -23,6 +26,18 @@ final class DivinerLiveSymbol extends DivinerDAO {
PhabricatorPHIDConstants::PHID_TYPE_ATOM); PhabricatorPHIDConstants::PHID_TYPE_ATOM);
} }
public function getBook() {
if ($this->book === null) {
throw new Exception("Call attachBook() before getBook()!");
}
return $this->book;
}
public function attachBook(DivinerLiveBook $book) {
$this->book = $book;
return $this;
}
public function save() { public function save() {
// NOTE: The identity hash is just a sanity check because the unique tuple // NOTE: The identity hash is just a sanity check because the unique tuple
@ -45,4 +60,20 @@ final class DivinerLiveSymbol extends DivinerDAO {
} }
/* -( PhabricatorPolicyInterface )----------------------------------------- */
public function getCapabilities() {
return $this->getBook()->getCapabilities();
}
public function getPolicy($capability) {
return $this->getBook()->getPolicy($capability);
}
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
return $this->getBook()->hasAutomaticCapability($capability, $viewer);
}
} }