mirror of
https://we.phorge.it/source/phorge.git
synced 2025-01-09 22:31:03 +01:00
Add an Atom controller to Diviner
Summary: Ref T988. Lots of rough edges still, but this pulls the right data and dumps it into a reasonable-looking shell. Test Plan: {F44883} Reviewers: chad, btrahan Reviewed By: btrahan CC: aran Maniphest Tasks: T988 Differential Revision: https://secure.phabricator.com/D6104
This commit is contained in:
parent
e349c98188
commit
acff7b1ad5
7 changed files with 258 additions and 0 deletions
|
@ -505,6 +505,7 @@ 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',
|
||||||
|
'DivinerAtomController' => 'applications/diviner/controller/DivinerAtomController.php',
|
||||||
'DivinerAtomListController' => 'applications/diviner/controller/DivinerAtomListController.php',
|
'DivinerAtomListController' => 'applications/diviner/controller/DivinerAtomListController.php',
|
||||||
'DivinerAtomQuery' => 'applications/diviner/query/DivinerAtomQuery.php',
|
'DivinerAtomQuery' => 'applications/diviner/query/DivinerAtomQuery.php',
|
||||||
'DivinerAtomRef' => 'applications/diviner/atom/DivinerAtomRef.php',
|
'DivinerAtomRef' => 'applications/diviner/atom/DivinerAtomRef.php',
|
||||||
|
@ -2326,6 +2327,7 @@ phutil_register_library_map(array(
|
||||||
'DiffusionView' => 'AphrontView',
|
'DiffusionView' => 'AphrontView',
|
||||||
'DivinerArticleAtomizer' => 'DivinerAtomizer',
|
'DivinerArticleAtomizer' => 'DivinerAtomizer',
|
||||||
'DivinerAtomCache' => 'DivinerDiskCache',
|
'DivinerAtomCache' => 'DivinerDiskCache',
|
||||||
|
'DivinerAtomController' => 'DivinerController',
|
||||||
'DivinerAtomListController' =>
|
'DivinerAtomListController' =>
|
||||||
array(
|
array(
|
||||||
0 => 'DivinerController',
|
0 => 'DivinerController',
|
||||||
|
|
|
@ -24,6 +24,13 @@ final class PhabricatorApplicationDiviner extends PhabricatorApplication {
|
||||||
'' => 'DivinerLegacyController',
|
'' => 'DivinerLegacyController',
|
||||||
'query/((?<key>[^/]+)/)?' => 'DivinerAtomListController',
|
'query/((?<key>[^/]+)/)?' => 'DivinerAtomListController',
|
||||||
),
|
),
|
||||||
|
'/docs/(?P<keyword>[^/]+)/' => 'DivinerJumpController',
|
||||||
|
'/book/'.
|
||||||
|
'(?P<book>[^/]+)/'.
|
||||||
|
'(?P<type>[^/]+)/'.
|
||||||
|
'(?:(?P<context>[^/]+)/)?'.
|
||||||
|
'(?P<name>[^/]+)/'.
|
||||||
|
'(?:(?P<index>\d+)/)?' => 'DivinerAtomController',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class DivinerAtomController extends DivinerController {
|
||||||
|
|
||||||
|
private $bookName;
|
||||||
|
private $atomType;
|
||||||
|
private $atomName;
|
||||||
|
private $atomContext;
|
||||||
|
private $atomIndex;
|
||||||
|
|
||||||
|
public function shouldAllowPublic() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function willProcessRequest(array $data) {
|
||||||
|
$this->bookName = $data['book'];
|
||||||
|
$this->atomType = $data['type'];
|
||||||
|
$this->atomName = $data['name'];
|
||||||
|
$this->atomContext = nonempty(idx($data, 'context'), null);
|
||||||
|
$this->atomIndex = nonempty(idx($data, 'index'), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function processRequest() {
|
||||||
|
$request = $this->getRequest();
|
||||||
|
$viewer = $request->getUser();
|
||||||
|
|
||||||
|
$book = id(new DivinerBookQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withNames(array($this->bookName))
|
||||||
|
->executeOne();
|
||||||
|
|
||||||
|
if (!$book) {
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
|
||||||
|
$atom = id(new DivinerAtomQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withBookPHIDs(array($book->getPHID()))
|
||||||
|
->withTypes(array($this->atomType))
|
||||||
|
->withNames(array($this->atomName))
|
||||||
|
->withContexts(array($this->atomContext))
|
||||||
|
->withIndexes(array($this->atomIndex))
|
||||||
|
->needAtoms(true)
|
||||||
|
->executeOne();
|
||||||
|
|
||||||
|
if (!$atom) {
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
|
||||||
|
$crumbs = $this->buildApplicationCrumbs();
|
||||||
|
|
||||||
|
$crumbs->addCrumb(
|
||||||
|
id(new PhabricatorCrumbView())
|
||||||
|
->setName($book->getName())
|
||||||
|
->setHref('/book/'.$book->getName().'/'));
|
||||||
|
|
||||||
|
$crumbs->addCrumb(
|
||||||
|
id(new PhabricatorCrumbView())
|
||||||
|
->setName($atom->getName()));
|
||||||
|
|
||||||
|
$header = id(new PhabricatorHeaderView())->setHeader($atom->getName());
|
||||||
|
|
||||||
|
$document = id(new PHUIDocumentView())
|
||||||
|
->appendChild(
|
||||||
|
phutil_tag(
|
||||||
|
'div',
|
||||||
|
array(
|
||||||
|
'class' => 'phabricator-remarkup',
|
||||||
|
),
|
||||||
|
phutil_safe_html($atom->getContent())));
|
||||||
|
|
||||||
|
return $this->buildApplicationPage(
|
||||||
|
array(
|
||||||
|
$crumbs,
|
||||||
|
$document,
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'title' => $atom->getName(),
|
||||||
|
'dust' => true,
|
||||||
|
'device' => true,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -35,6 +35,7 @@ final class DivinerAtomListController extends DivinerController
|
||||||
foreach ($symbols as $symbol) {
|
foreach ($symbols as $symbol) {
|
||||||
$item = id(new PhabricatorObjectItemView())
|
$item = id(new PhabricatorObjectItemView())
|
||||||
->setHeader($symbol->getName())
|
->setHeader($symbol->getName())
|
||||||
|
->setHref($symbol->getURI())
|
||||||
->addIcon('none', $symbol->getType());
|
->addIcon('none', $symbol->getType());
|
||||||
|
|
||||||
$list->addItem($item);
|
$list->addItem($item);
|
||||||
|
|
|
@ -5,6 +5,13 @@ final class DivinerAtomQuery
|
||||||
|
|
||||||
private $ids;
|
private $ids;
|
||||||
private $phids;
|
private $phids;
|
||||||
|
private $bookPHIDs;
|
||||||
|
private $names;
|
||||||
|
private $types;
|
||||||
|
private $contexts;
|
||||||
|
private $indexes;
|
||||||
|
|
||||||
|
private $needAtoms;
|
||||||
|
|
||||||
public function withIDs(array $ids) {
|
public function withIDs(array $ids) {
|
||||||
$this->ids = $ids;
|
$this->ids = $ids;
|
||||||
|
@ -16,6 +23,36 @@ final class DivinerAtomQuery
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function withBookPHIDs(array $phids) {
|
||||||
|
$this->bookPHIDs = $phids;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withTypes(array $types) {
|
||||||
|
$this->types = $types;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withNames(array $names) {
|
||||||
|
$this->names = $names;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withContexts(array $contexts) {
|
||||||
|
$this->contexts = $contexts;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withIndexes(array $indexes) {
|
||||||
|
$this->indexes = $indexes;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function needAtoms($need) {
|
||||||
|
$this->needAtoms = $need;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
protected function loadPage() {
|
protected function loadPage() {
|
||||||
$table = new DivinerLiveSymbol();
|
$table = new DivinerLiveSymbol();
|
||||||
$conn_r = $table->establishConnection('r');
|
$conn_r = $table->establishConnection('r');
|
||||||
|
@ -53,6 +90,22 @@ final class DivinerAtomQuery
|
||||||
$atom->attachBook($book);
|
$atom->attachBook($book);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->needAtoms) {
|
||||||
|
$atom_data = id(new DivinerLiveAtom())->loadAllWhere(
|
||||||
|
'symbolPHID IN (%Ls)',
|
||||||
|
mpull($atoms, 'getPHID'));
|
||||||
|
$atom_data = mpull($atom_data, null, 'getSymbolPHID');
|
||||||
|
|
||||||
|
foreach ($atoms as $key => $atom) {
|
||||||
|
$data = idx($atom_data, $atom->getPHID());
|
||||||
|
if (!$data) {
|
||||||
|
unset($atoms[$key]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$atom->attachAtom($data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $atoms;
|
return $atoms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,6 +126,62 @@ final class DivinerAtomQuery
|
||||||
$this->phids);
|
$this->phids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->bookPHIDs) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn_r,
|
||||||
|
'bookPHID IN (%Ls)',
|
||||||
|
$this->bookPHIDs);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->types) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn_r,
|
||||||
|
'type IN (%Ls)',
|
||||||
|
$this->types);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->names) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn_r,
|
||||||
|
'name IN (%Ls)',
|
||||||
|
$this->names);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->contexts) {
|
||||||
|
$with_null = false;
|
||||||
|
$contexts = $this->contexts;
|
||||||
|
foreach ($contexts as $key => $value) {
|
||||||
|
if ($value === null) {
|
||||||
|
unset($contexts[$key]);
|
||||||
|
$with_null = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($contexts && $with_null) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn_r,
|
||||||
|
'context IN (%Ls) OR context IS NULL',
|
||||||
|
$contexts);
|
||||||
|
} else if ($contexts) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn_r,
|
||||||
|
'context IN (%Ls)',
|
||||||
|
$contexts);
|
||||||
|
} else if ($with_null) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn_r,
|
||||||
|
'context IS NULL');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->indexes) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn_r,
|
||||||
|
'atomIndex IN (%Ld)',
|
||||||
|
$this->indexes);
|
||||||
|
}
|
||||||
|
|
||||||
$where[] = $this->buildPagingClause($conn_r);
|
$where[] = $this->buildPagingClause($conn_r);
|
||||||
|
|
||||||
return $this->formatWhereClause($where);
|
return $this->formatWhereClause($where);
|
||||||
|
|
|
@ -5,6 +5,7 @@ final class DivinerBookQuery
|
||||||
|
|
||||||
private $ids;
|
private $ids;
|
||||||
private $phids;
|
private $phids;
|
||||||
|
private $names;
|
||||||
|
|
||||||
public function withIDs(array $ids) {
|
public function withIDs(array $ids) {
|
||||||
$this->ids = $ids;
|
$this->ids = $ids;
|
||||||
|
@ -16,6 +17,11 @@ final class DivinerBookQuery
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function withNames(array $names) {
|
||||||
|
$this->names = $names;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
protected function loadPage() {
|
protected function loadPage() {
|
||||||
$table = new DivinerLiveBook();
|
$table = new DivinerLiveBook();
|
||||||
$conn_r = $table->establishConnection('r');
|
$conn_r = $table->establishConnection('r');
|
||||||
|
@ -48,6 +54,13 @@ final class DivinerBookQuery
|
||||||
$this->phids);
|
$this->phids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->names) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn_r,
|
||||||
|
'name IN (%Ls)',
|
||||||
|
$this->names);
|
||||||
|
}
|
||||||
|
|
||||||
$where[] = $this->buildPagingClause($conn_r);
|
$where[] = $this->buildPagingClause($conn_r);
|
||||||
|
|
||||||
return $this->formatWhereClause($where);
|
return $this->formatWhereClause($where);
|
||||||
|
|
|
@ -13,6 +13,8 @@ final class DivinerLiveSymbol extends DivinerDAO
|
||||||
protected $identityHash;
|
protected $identityHash;
|
||||||
|
|
||||||
private $book;
|
private $book;
|
||||||
|
private $content;
|
||||||
|
private $atom;
|
||||||
|
|
||||||
public function getConfiguration() {
|
public function getConfiguration() {
|
||||||
return array(
|
return array(
|
||||||
|
@ -38,6 +40,46 @@ final class DivinerLiveSymbol extends DivinerDAO
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getContent() {
|
||||||
|
if ($this->content === null) {
|
||||||
|
throw new Exception("Call attachAtom() before getContent()!");
|
||||||
|
}
|
||||||
|
return $this->content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAtom() {
|
||||||
|
if ($this->atom === null) {
|
||||||
|
throw new Exception("Call attachAtom() before getAtom()!");
|
||||||
|
}
|
||||||
|
return $this->atom;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function attachAtom(DivinerLiveAtom $atom) {
|
||||||
|
$this->content = $atom->getContent();
|
||||||
|
$this->atom = DivinerAtom::newFromDictionary($atom->getAtomData());
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getURI() {
|
||||||
|
$parts = array(
|
||||||
|
'book',
|
||||||
|
$this->getBook()->getName(),
|
||||||
|
$this->getType(),
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($this->getContext()) {
|
||||||
|
$parts[] = $this->getContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
$parts[] = $this->getName();
|
||||||
|
|
||||||
|
if ($this->getAtomIndex()) {
|
||||||
|
$parts[] = $this->getAtomIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
return '/'.implode('/', $parts).'/';
|
||||||
|
}
|
||||||
|
|
||||||
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
|
||||||
|
|
Loading…
Reference in a new issue