@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+258
+2
src/__phutil_library_map__.php
··· 505 505 'DivinerArticleAtomizer' => 'applications/diviner/atomizer/DivinerArticleAtomizer.php', 506 506 'DivinerAtom' => 'applications/diviner/atom/DivinerAtom.php', 507 507 'DivinerAtomCache' => 'applications/diviner/cache/DivinerAtomCache.php', 508 + 'DivinerAtomController' => 'applications/diviner/controller/DivinerAtomController.php', 508 509 'DivinerAtomListController' => 'applications/diviner/controller/DivinerAtomListController.php', 509 510 'DivinerAtomQuery' => 'applications/diviner/query/DivinerAtomQuery.php', 510 511 'DivinerAtomRef' => 'applications/diviner/atom/DivinerAtomRef.php', ··· 2326 2327 'DiffusionView' => 'AphrontView', 2327 2328 'DivinerArticleAtomizer' => 'DivinerAtomizer', 2328 2329 'DivinerAtomCache' => 'DivinerDiskCache', 2330 + 'DivinerAtomController' => 'DivinerController', 2329 2331 'DivinerAtomListController' => 2330 2332 array( 2331 2333 0 => 'DivinerController',
+7
src/applications/diviner/application/PhabricatorApplicationDiviner.php
··· 24 24 '' => 'DivinerLegacyController', 25 25 'query/((?<key>[^/]+)/)?' => 'DivinerAtomListController', 26 26 ), 27 + '/docs/(?P<keyword>[^/]+)/' => 'DivinerJumpController', 28 + '/book/'. 29 + '(?P<book>[^/]+)/'. 30 + '(?P<type>[^/]+)/'. 31 + '(?:(?P<context>[^/]+)/)?'. 32 + '(?P<name>[^/]+)/'. 33 + '(?:(?P<index>\d+)/)?' => 'DivinerAtomController', 27 34 ); 28 35 } 29 36
+84
src/applications/diviner/controller/DivinerAtomController.php
··· 1 + <?php 2 + 3 + final class DivinerAtomController extends DivinerController { 4 + 5 + private $bookName; 6 + private $atomType; 7 + private $atomName; 8 + private $atomContext; 9 + private $atomIndex; 10 + 11 + public function shouldAllowPublic() { 12 + return true; 13 + } 14 + 15 + public function willProcessRequest(array $data) { 16 + $this->bookName = $data['book']; 17 + $this->atomType = $data['type']; 18 + $this->atomName = $data['name']; 19 + $this->atomContext = nonempty(idx($data, 'context'), null); 20 + $this->atomIndex = nonempty(idx($data, 'index'), null); 21 + } 22 + 23 + public function processRequest() { 24 + $request = $this->getRequest(); 25 + $viewer = $request->getUser(); 26 + 27 + $book = id(new DivinerBookQuery()) 28 + ->setViewer($viewer) 29 + ->withNames(array($this->bookName)) 30 + ->executeOne(); 31 + 32 + if (!$book) { 33 + return new Aphront404Response(); 34 + } 35 + 36 + $atom = id(new DivinerAtomQuery()) 37 + ->setViewer($viewer) 38 + ->withBookPHIDs(array($book->getPHID())) 39 + ->withTypes(array($this->atomType)) 40 + ->withNames(array($this->atomName)) 41 + ->withContexts(array($this->atomContext)) 42 + ->withIndexes(array($this->atomIndex)) 43 + ->needAtoms(true) 44 + ->executeOne(); 45 + 46 + if (!$atom) { 47 + return new Aphront404Response(); 48 + } 49 + 50 + $crumbs = $this->buildApplicationCrumbs(); 51 + 52 + $crumbs->addCrumb( 53 + id(new PhabricatorCrumbView()) 54 + ->setName($book->getName()) 55 + ->setHref('/book/'.$book->getName().'/')); 56 + 57 + $crumbs->addCrumb( 58 + id(new PhabricatorCrumbView()) 59 + ->setName($atom->getName())); 60 + 61 + $header = id(new PhabricatorHeaderView())->setHeader($atom->getName()); 62 + 63 + $document = id(new PHUIDocumentView()) 64 + ->appendChild( 65 + phutil_tag( 66 + 'div', 67 + array( 68 + 'class' => 'phabricator-remarkup', 69 + ), 70 + phutil_safe_html($atom->getContent()))); 71 + 72 + return $this->buildApplicationPage( 73 + array( 74 + $crumbs, 75 + $document, 76 + ), 77 + array( 78 + 'title' => $atom->getName(), 79 + 'dust' => true, 80 + 'device' => true, 81 + )); 82 + } 83 + 84 + }
+1
src/applications/diviner/controller/DivinerAtomListController.php
··· 35 35 foreach ($symbols as $symbol) { 36 36 $item = id(new PhabricatorObjectItemView()) 37 37 ->setHeader($symbol->getName()) 38 + ->setHref($symbol->getURI()) 38 39 ->addIcon('none', $symbol->getType()); 39 40 40 41 $list->addItem($item);
+109
src/applications/diviner/query/DivinerAtomQuery.php
··· 5 5 6 6 private $ids; 7 7 private $phids; 8 + private $bookPHIDs; 9 + private $names; 10 + private $types; 11 + private $contexts; 12 + private $indexes; 13 + 14 + private $needAtoms; 8 15 9 16 public function withIDs(array $ids) { 10 17 $this->ids = $ids; ··· 16 23 return $this; 17 24 } 18 25 26 + public function withBookPHIDs(array $phids) { 27 + $this->bookPHIDs = $phids; 28 + return $this; 29 + } 30 + 31 + public function withTypes(array $types) { 32 + $this->types = $types; 33 + return $this; 34 + } 35 + 36 + public function withNames(array $names) { 37 + $this->names = $names; 38 + return $this; 39 + } 40 + 41 + public function withContexts(array $contexts) { 42 + $this->contexts = $contexts; 43 + return $this; 44 + } 45 + 46 + public function withIndexes(array $indexes) { 47 + $this->indexes = $indexes; 48 + return $this; 49 + } 50 + 51 + public function needAtoms($need) { 52 + $this->needAtoms = $need; 53 + return $this; 54 + } 55 + 19 56 protected function loadPage() { 20 57 $table = new DivinerLiveSymbol(); 21 58 $conn_r = $table->establishConnection('r'); ··· 53 90 $atom->attachBook($book); 54 91 } 55 92 93 + if ($this->needAtoms) { 94 + $atom_data = id(new DivinerLiveAtom())->loadAllWhere( 95 + 'symbolPHID IN (%Ls)', 96 + mpull($atoms, 'getPHID')); 97 + $atom_data = mpull($atom_data, null, 'getSymbolPHID'); 98 + 99 + foreach ($atoms as $key => $atom) { 100 + $data = idx($atom_data, $atom->getPHID()); 101 + if (!$data) { 102 + unset($atoms[$key]); 103 + continue; 104 + } 105 + $atom->attachAtom($data); 106 + } 107 + } 108 + 56 109 return $atoms; 57 110 } 58 111 ··· 71 124 $conn_r, 72 125 'phid IN (%Ls)', 73 126 $this->phids); 127 + } 128 + 129 + if ($this->bookPHIDs) { 130 + $where[] = qsprintf( 131 + $conn_r, 132 + 'bookPHID IN (%Ls)', 133 + $this->bookPHIDs); 134 + } 135 + 136 + if ($this->types) { 137 + $where[] = qsprintf( 138 + $conn_r, 139 + 'type IN (%Ls)', 140 + $this->types); 141 + } 142 + 143 + if ($this->names) { 144 + $where[] = qsprintf( 145 + $conn_r, 146 + 'name IN (%Ls)', 147 + $this->names); 148 + } 149 + 150 + if ($this->contexts) { 151 + $with_null = false; 152 + $contexts = $this->contexts; 153 + foreach ($contexts as $key => $value) { 154 + if ($value === null) { 155 + unset($contexts[$key]); 156 + $with_null = true; 157 + continue; 158 + } 159 + } 160 + 161 + if ($contexts && $with_null) { 162 + $where[] = qsprintf( 163 + $conn_r, 164 + 'context IN (%Ls) OR context IS NULL', 165 + $contexts); 166 + } else if ($contexts) { 167 + $where[] = qsprintf( 168 + $conn_r, 169 + 'context IN (%Ls)', 170 + $contexts); 171 + } else if ($with_null) { 172 + $where[] = qsprintf( 173 + $conn_r, 174 + 'context IS NULL'); 175 + } 176 + } 177 + 178 + if ($this->indexes) { 179 + $where[] = qsprintf( 180 + $conn_r, 181 + 'atomIndex IN (%Ld)', 182 + $this->indexes); 74 183 } 75 184 76 185 $where[] = $this->buildPagingClause($conn_r);
+13
src/applications/diviner/query/DivinerBookQuery.php
··· 5 5 6 6 private $ids; 7 7 private $phids; 8 + private $names; 8 9 9 10 public function withIDs(array $ids) { 10 11 $this->ids = $ids; ··· 13 14 14 15 public function withPHIDs(array $phids) { 15 16 $this->phids = $phids; 17 + return $this; 18 + } 19 + 20 + public function withNames(array $names) { 21 + $this->names = $names; 16 22 return $this; 17 23 } 18 24 ··· 46 52 $conn_r, 47 53 'phid IN (%Ls)', 48 54 $this->phids); 55 + } 56 + 57 + if ($this->names) { 58 + $where[] = qsprintf( 59 + $conn_r, 60 + 'name IN (%Ls)', 61 + $this->names); 49 62 } 50 63 51 64 $where[] = $this->buildPagingClause($conn_r);
+42
src/applications/diviner/storage/DivinerLiveSymbol.php
··· 13 13 protected $identityHash; 14 14 15 15 private $book; 16 + private $content; 17 + private $atom; 16 18 17 19 public function getConfiguration() { 18 20 return array( ··· 36 38 public function attachBook(DivinerLiveBook $book) { 37 39 $this->book = $book; 38 40 return $this; 41 + } 42 + 43 + public function getContent() { 44 + if ($this->content === null) { 45 + throw new Exception("Call attachAtom() before getContent()!"); 46 + } 47 + return $this->content; 48 + } 49 + 50 + public function getAtom() { 51 + if ($this->atom === null) { 52 + throw new Exception("Call attachAtom() before getAtom()!"); 53 + } 54 + return $this->atom; 55 + } 56 + 57 + public function attachAtom(DivinerLiveAtom $atom) { 58 + $this->content = $atom->getContent(); 59 + $this->atom = DivinerAtom::newFromDictionary($atom->getAtomData()); 60 + return $this; 61 + } 62 + 63 + public function getURI() { 64 + $parts = array( 65 + 'book', 66 + $this->getBook()->getName(), 67 + $this->getType(), 68 + ); 69 + 70 + if ($this->getContext()) { 71 + $parts[] = $this->getContext(); 72 + } 73 + 74 + $parts[] = $this->getName(); 75 + 76 + if ($this->getAtomIndex()) { 77 + $parts[] = $this->getAtomIndex(); 78 + } 79 + 80 + return '/'.implode('/', $parts).'/'; 39 81 } 40 82 41 83 public function save() {