1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-01-08 22:01: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:
epriestley 2013-05-31 15:14:39 -07:00
parent e349c98188
commit acff7b1ad5
7 changed files with 258 additions and 0 deletions

View file

@ -505,6 +505,7 @@ phutil_register_library_map(array(
'DivinerArticleAtomizer' => 'applications/diviner/atomizer/DivinerArticleAtomizer.php',
'DivinerAtom' => 'applications/diviner/atom/DivinerAtom.php',
'DivinerAtomCache' => 'applications/diviner/cache/DivinerAtomCache.php',
'DivinerAtomController' => 'applications/diviner/controller/DivinerAtomController.php',
'DivinerAtomListController' => 'applications/diviner/controller/DivinerAtomListController.php',
'DivinerAtomQuery' => 'applications/diviner/query/DivinerAtomQuery.php',
'DivinerAtomRef' => 'applications/diviner/atom/DivinerAtomRef.php',
@ -2326,6 +2327,7 @@ phutil_register_library_map(array(
'DiffusionView' => 'AphrontView',
'DivinerArticleAtomizer' => 'DivinerAtomizer',
'DivinerAtomCache' => 'DivinerDiskCache',
'DivinerAtomController' => 'DivinerController',
'DivinerAtomListController' =>
array(
0 => 'DivinerController',

View file

@ -24,6 +24,13 @@ final class PhabricatorApplicationDiviner extends PhabricatorApplication {
'' => 'DivinerLegacyController',
'query/((?<key>[^/]+)/)?' => 'DivinerAtomListController',
),
'/docs/(?P<keyword>[^/]+)/' => 'DivinerJumpController',
'/book/'.
'(?P<book>[^/]+)/'.
'(?P<type>[^/]+)/'.
'(?:(?P<context>[^/]+)/)?'.
'(?P<name>[^/]+)/'.
'(?:(?P<index>\d+)/)?' => 'DivinerAtomController',
);
}

View file

@ -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,
));
}
}

View file

@ -35,6 +35,7 @@ final class DivinerAtomListController extends DivinerController
foreach ($symbols as $symbol) {
$item = id(new PhabricatorObjectItemView())
->setHeader($symbol->getName())
->setHref($symbol->getURI())
->addIcon('none', $symbol->getType());
$list->addItem($item);

View file

@ -5,6 +5,13 @@ final class DivinerAtomQuery
private $ids;
private $phids;
private $bookPHIDs;
private $names;
private $types;
private $contexts;
private $indexes;
private $needAtoms;
public function withIDs(array $ids) {
$this->ids = $ids;
@ -16,6 +23,36 @@ final class DivinerAtomQuery
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() {
$table = new DivinerLiveSymbol();
$conn_r = $table->establishConnection('r');
@ -53,6 +90,22 @@ final class DivinerAtomQuery
$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;
}
@ -73,6 +126,62 @@ final class DivinerAtomQuery
$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);
return $this->formatWhereClause($where);

View file

@ -5,6 +5,7 @@ final class DivinerBookQuery
private $ids;
private $phids;
private $names;
public function withIDs(array $ids) {
$this->ids = $ids;
@ -16,6 +17,11 @@ final class DivinerBookQuery
return $this;
}
public function withNames(array $names) {
$this->names = $names;
return $this;
}
protected function loadPage() {
$table = new DivinerLiveBook();
$conn_r = $table->establishConnection('r');
@ -48,6 +54,13 @@ final class DivinerBookQuery
$this->phids);
}
if ($this->names) {
$where[] = qsprintf(
$conn_r,
'name IN (%Ls)',
$this->names);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);

View file

@ -13,6 +13,8 @@ final class DivinerLiveSymbol extends DivinerDAO
protected $identityHash;
private $book;
private $content;
private $atom;
public function getConfiguration() {
return array(
@ -38,6 +40,46 @@ final class DivinerLiveSymbol extends DivinerDAO
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() {
// NOTE: The identity hash is just a sanity check because the unique tuple