Add a book controller and various amenities to Diviner's live view
Summary: Ref T988. Mostly backend changes, with a very rough frontend on top of them. See Conpherence discussion.
Test Plan: {F45010}
Reviewers: btrahan, chad
Reviewed By: chad
CC: aran
Maniphest Tasks: T988
Differential Revision: https://secure.phabricator.com/D6113
			
			
This commit is contained in:
		
							
								
								
									
										17
									
								
								resources/sql/patches/20130602.morediviner.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								resources/sql/patches/20130602.morediviner.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | |||||||
|  | ALTER TABLE {$NAMESPACE}_diviner.diviner_livebook | ||||||
|  |   ADD configurationData LONGTEXT COLLATE utf8_bin NOT NULL; | ||||||
|  |  | ||||||
|  | UPDATE {$NAMESPACE}_diviner.diviner_livebook | ||||||
|  |   SET configurationData = '{}' WHERE configurationData = ''; | ||||||
|  |  | ||||||
|  | ALTER TABLE {$NAMESPACE}_diviner.diviner_livesymbol | ||||||
|  |   ADD title VARCHAR(255); | ||||||
|  |  | ||||||
|  | ALTER TABLE {$NAMESPACE}_diviner.diviner_livesymbol | ||||||
|  |   ADD groupName VARCHAR(255); | ||||||
|  |  | ||||||
|  | ALTER TABLE {$NAMESPACE}_diviner.diviner_livesymbol | ||||||
|  |   ADD summary LONGTEXT COLLATE utf8_bin; | ||||||
|  |  | ||||||
|  | ALTER TABLE {$NAMESPACE}_diviner.diviner_livesymbol | ||||||
|  |   ADD isDocumentable BOOL NOT NULL; | ||||||
| @@ -514,6 +514,7 @@ phutil_register_library_map(array( | |||||||
|     'DivinerAtomSearchEngine' => 'applications/diviner/query/DivinerAtomSearchEngine.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', | ||||||
|  |     'DivinerBookController' => 'applications/diviner/controller/DivinerBookController.php', | ||||||
|     'DivinerBookQuery' => 'applications/diviner/query/DivinerBookQuery.php', |     'DivinerBookQuery' => 'applications/diviner/query/DivinerBookQuery.php', | ||||||
|     'DivinerController' => 'applications/diviner/controller/DivinerController.php', |     'DivinerController' => 'applications/diviner/controller/DivinerController.php', | ||||||
|     'DivinerDAO' => 'applications/diviner/storage/DivinerDAO.php', |     'DivinerDAO' => 'applications/diviner/storage/DivinerDAO.php', | ||||||
| @@ -2342,6 +2343,7 @@ phutil_register_library_map(array( | |||||||
|     'DivinerAtomQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', |     'DivinerAtomQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', | ||||||
|     'DivinerAtomSearchEngine' => 'PhabricatorApplicationSearchEngine', |     'DivinerAtomSearchEngine' => 'PhabricatorApplicationSearchEngine', | ||||||
|     'DivinerAtomizeWorkflow' => 'DivinerWorkflow', |     'DivinerAtomizeWorkflow' => 'DivinerWorkflow', | ||||||
|  |     'DivinerBookController' => 'DivinerController', | ||||||
|     'DivinerBookQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', |     'DivinerBookQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', | ||||||
|     'DivinerController' => 'PhabricatorController', |     'DivinerController' => 'PhabricatorController', | ||||||
|     'DivinerDAO' => 'PhabricatorLiskDAO', |     'DivinerDAO' => 'PhabricatorLiskDAO', | ||||||
|   | |||||||
| @@ -25,6 +25,7 @@ final class PhabricatorApplicationDiviner extends PhabricatorApplication { | |||||||
|         'query/((?<key>[^/]+)/)?' => 'DivinerAtomListController', |         'query/((?<key>[^/]+)/)?' => 'DivinerAtomListController', | ||||||
|       ), |       ), | ||||||
|       '/docs/(?P<keyword>[^/]+)/' => 'DivinerJumpController', |       '/docs/(?P<keyword>[^/]+)/' => 'DivinerJumpController', | ||||||
|  |       '/book/(?P<book>[^/]+)/' => 'DivinerBookController', | ||||||
|       '/book/'. |       '/book/'. | ||||||
|         '(?P<book>[^/]+)/'. |         '(?P<book>[^/]+)/'. | ||||||
|         '(?P<type>[^/]+)/'. |         '(?P<type>[^/]+)/'. | ||||||
|   | |||||||
| @@ -24,24 +24,7 @@ final class DivinerAtomListController extends DivinerController | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   public function renderResultsList(array $symbols) { |   public function renderResultsList(array $symbols) { | ||||||
|     assert_instances_of($symbols, 'DivinerLiveSymbol'); |     return $this->renderAtomList($symbols); | ||||||
|  |  | ||||||
|     $request = $this->getRequest(); |  | ||||||
|     $user = $request->getUser(); |  | ||||||
|  |  | ||||||
|     $list = id(new PhabricatorObjectItemListView()) |  | ||||||
|       ->setUser($user); |  | ||||||
|  |  | ||||||
|     foreach ($symbols as $symbol) { |  | ||||||
|       $item = id(new PhabricatorObjectItemView()) |  | ||||||
|         ->setHeader($symbol->getName()) |  | ||||||
|         ->setHref($symbol->getURI()) |  | ||||||
|         ->addIcon('none', $symbol->getType()); |  | ||||||
|  |  | ||||||
|       $list->addItem($item); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     return $list; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										112
									
								
								src/applications/diviner/controller/DivinerBookController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								src/applications/diviner/controller/DivinerBookController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,112 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | final class DivinerBookController extends DivinerController { | ||||||
|  |  | ||||||
|  |   private $bookName; | ||||||
|  |  | ||||||
|  |   public function shouldAllowPublic() { | ||||||
|  |     return true; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public function willProcessRequest(array $data) { | ||||||
|  |     $this->bookName = $data['book']; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   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(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     $crumbs = $this->buildApplicationCrumbs(); | ||||||
|  |  | ||||||
|  |     $crumbs->addCrumb( | ||||||
|  |       id(new PhabricatorCrumbView()) | ||||||
|  |         ->setName($book->getTitle()) | ||||||
|  |         ->setHref('/book/'.$book->getName().'/')); | ||||||
|  |  | ||||||
|  |     $header = id(new PhabricatorHeaderView())->setHeader($book->getTitle()); | ||||||
|  |     $properties = $this->buildPropertyList($book); | ||||||
|  |  | ||||||
|  |     $atoms = id(new DivinerAtomQuery()) | ||||||
|  |       ->setViewer($viewer) | ||||||
|  |       ->withBookPHIDs(array($book->getPHID())) | ||||||
|  |       ->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_info = idx($group_spec, $group); | ||||||
|  |       if (!is_array($group_info)) { | ||||||
|  |         $group_info = array(); | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       $group_name = idx($group_info, 'name'); | ||||||
|  |       if (!strlen($group_name)) { | ||||||
|  |         if (strlen($group)) { | ||||||
|  |           $group_name = $group; | ||||||
|  |         } else { | ||||||
|  |           $group_name = pht('Free Radicals'); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       $out[] = id(new PhabricatorHeaderView()) | ||||||
|  |         ->setHeader($group_name); | ||||||
|  |       $out[] = $this->renderAtomList($atoms); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return $this->buildApplicationPage( | ||||||
|  |       array( | ||||||
|  |         $crumbs, | ||||||
|  |         $header, | ||||||
|  |         $properties, | ||||||
|  |         $out, | ||||||
|  |       ), | ||||||
|  |       array( | ||||||
|  |         'title' => $book->getTitle(), | ||||||
|  |         'dust' => true, | ||||||
|  |         'device' => true, | ||||||
|  |       )); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   private function buildPropertyList(DivinerLiveBook $book) { | ||||||
|  |     $user = $this->getRequest()->getUser(); | ||||||
|  |     $view = id(new PhabricatorPropertyListView()) | ||||||
|  |       ->setUser($user); | ||||||
|  |  | ||||||
|  |     $policies = PhabricatorPolicyQuery::renderPolicyDescriptions( | ||||||
|  |       $user, | ||||||
|  |       $book); | ||||||
|  |  | ||||||
|  |     $view->addProperty( | ||||||
|  |       pht('Visible To'), | ||||||
|  |       $policies[PhabricatorPolicyCapability::CAN_VIEW]); | ||||||
|  |  | ||||||
|  |     $view->addProperty( | ||||||
|  |       pht('Updated'), | ||||||
|  |       phabricator_datetime($book->getDateModified(), $user)); | ||||||
|  |  | ||||||
|  |     return $view; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -21,4 +21,27 @@ abstract class DivinerController extends PhabricatorController { | |||||||
|     return $menu; |     return $menu; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   protected function renderAtomList(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->getTitle()) | ||||||
|  |         ->setHref($symbol->getURI()) | ||||||
|  |         ->addIcon('none', $symbol->getType()); | ||||||
|  |  | ||||||
|  |       $item->addAttribute(phutil_safe_html($symbol->getSummary())); | ||||||
|  |  | ||||||
|  |       $list->addItem($item); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return $list; | ||||||
|  |   } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -18,20 +18,23 @@ final class DivinerLivePublisher extends DivinerPublisher { | |||||||
|           ->save(); |           ->save(); | ||||||
|       } |       } | ||||||
|  |  | ||||||
|  |       $book->setConfigurationData($this->getConfigurationData())->save(); | ||||||
|  |  | ||||||
|       $this->book = $book; |       $this->book = $book; | ||||||
|     } |     } | ||||||
|     return $this->book; |     return $this->book; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private function loadSymbolForAtom(DivinerAtom $atom) { |   private function loadSymbolForAtom(DivinerAtom $atom) { | ||||||
|     $symbol = id(new DivinerLiveSymbol())->loadOneWhere( |     $symbol = id(new DivinerAtomQuery()) | ||||||
|       'bookPHID = %s AND type = %s AND name = %s AND context = %ns |       ->setViewer(PhabricatorUser::getOmnipotentUser()) | ||||||
|         AND atomIndex = %d', |       ->withBookPHIDs(array($this->loadBook()->getPHID())) | ||||||
|       $this->loadBook()->getPHID(), |       ->withTypes(array($atom->getType())) | ||||||
|       $atom->getType(), |       ->withNames(array($atom->getName())) | ||||||
|       $atom->getName(), |       ->withContexts(array($atom->getContext())) | ||||||
|       $atom->getContext(), |       ->withIndexes(array($this->getAtomSimilarIndex($atom))) | ||||||
|       $this->getAtomSimilarIndex($atom)); |       ->withIncludeUndocumentable(true) | ||||||
|  |       ->executeOne(); | ||||||
|  |  | ||||||
|     if ($symbol) { |     if ($symbol) { | ||||||
|       return $symbol; |       return $symbol; | ||||||
| @@ -97,18 +100,33 @@ final class DivinerLivePublisher extends DivinerPublisher { | |||||||
|   protected function createDocumentsByHash(array $hashes) { |   protected function createDocumentsByHash(array $hashes) { | ||||||
|     foreach ($hashes as $hash) { |     foreach ($hashes as $hash) { | ||||||
|       $atom = $this->getAtomFromGraphHash($hash); |       $atom = $this->getAtomFromGraphHash($hash); | ||||||
|  |       $ref = $atom->getRef(); | ||||||
|  |  | ||||||
|       $symbol = $this->loadSymbolForAtom($atom); |       $symbol = $this->loadSymbolForAtom($atom); | ||||||
|       $symbol->setGraphHash($hash)->save(); |  | ||||||
|  |  | ||||||
|       if ($this->shouldGenerateDocumentForAtom($atom)) { |       $is_documentable = $this->shouldGenerateDocumentForAtom($atom); | ||||||
|         $content = $this->getRenderer()->renderAtom($atom); |  | ||||||
|  |       $symbol | ||||||
|  |         ->setGraphHash($hash) | ||||||
|  |         ->setIsDocumentable((int)$is_documentable) | ||||||
|  |         ->setTitle($ref->getTitle()) | ||||||
|  |         ->setGroupName($ref->getGroup()); | ||||||
|  |  | ||||||
|  |       if ($is_documentable) { | ||||||
|  |         $renderer = $this->getRenderer(); | ||||||
|  |         $content = $renderer->renderAtom($atom); | ||||||
|  |  | ||||||
|         $storage = $this->loadAtomStorageForSymbol($symbol) |         $storage = $this->loadAtomStorageForSymbol($symbol) | ||||||
|           ->setAtomData($atom->toDictionary()) |           ->setAtomData($atom->toDictionary()) | ||||||
|           ->setContent((string)phutil_safe_html($content)) |           ->setContent((string)phutil_safe_html($content)) | ||||||
|           ->save(); |           ->save(); | ||||||
|  |  | ||||||
|  |         $summary = $renderer->renderAtomSummary($atom); | ||||||
|  |         $summary = (string)phutil_safe_html($summary); | ||||||
|  |         $symbol->setSummary($summary); | ||||||
|       } |       } | ||||||
|  |  | ||||||
|  |       $symbol->save(); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,6 +8,12 @@ abstract class DivinerPublisher { | |||||||
|   private $renderer; |   private $renderer; | ||||||
|   private $config; |   private $config; | ||||||
|   private $symbolReverseMap; |   private $symbolReverseMap; | ||||||
|  |   private $dropCaches; | ||||||
|  |  | ||||||
|  |   public function setDropCaches($drop_caches) { | ||||||
|  |     $this->dropCaches = $drop_caches; | ||||||
|  |     return $this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   public function setRenderer(DivinerRenderer $renderer) { |   public function setRenderer(DivinerRenderer $renderer) { | ||||||
|     $renderer->setPublisher($this); |     $renderer->setPublisher($this); | ||||||
| @@ -28,6 +34,10 @@ abstract class DivinerPublisher { | |||||||
|     return idx($this->config, $key, $default); |     return idx($this->config, $key, $default); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   public function getConfigurationData() { | ||||||
|  |     return $this->config; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   public function setAtomCache(DivinerAtomCache $cache) { |   public function setAtomCache(DivinerAtomCache $cache) { | ||||||
|     $this->atomCache = $cache; |     $this->atomCache = $cache; | ||||||
|     $graph_map = $this->atomCache->getGraphMap(); |     $graph_map = $this->atomCache->getGraphMap(); | ||||||
| @@ -109,17 +119,25 @@ abstract class DivinerPublisher { | |||||||
|   final public function publishAtoms(array $hashes) { |   final public function publishAtoms(array $hashes) { | ||||||
|     $existing = $this->loadAllPublishedHashes(); |     $existing = $this->loadAllPublishedHashes(); | ||||||
|  |  | ||||||
|  |     if ($this->dropCaches) { | ||||||
|  |       $deleted = $existing; | ||||||
|  |       $created = $hashes; | ||||||
|  |     } else { | ||||||
|       $existing_map = array_fill_keys($existing, true); |       $existing_map = array_fill_keys($existing, true); | ||||||
|       $hashes_map = array_fill_keys($hashes, true); |       $hashes_map = array_fill_keys($hashes, true); | ||||||
|  |  | ||||||
|       $deleted = array_diff_key($existing_map, $hashes_map); |       $deleted = array_diff_key($existing_map, $hashes_map); | ||||||
|       $created = array_diff_key($hashes_map, $existing_map); |       $created = array_diff_key($hashes_map, $existing_map); | ||||||
|  |  | ||||||
|  |       $deleted = array_keys($deleted); | ||||||
|  |       $created = array_keys($created); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     echo pht('Deleting %d documents.', count($deleted))."\n"; |     echo pht('Deleting %d documents.', count($deleted))."\n"; | ||||||
|     $this->deleteDocumentsByHash(array_keys($deleted)); |     $this->deleteDocumentsByHash($deleted); | ||||||
|  |  | ||||||
|     echo pht('Creating %d documents.', count($created))."\n"; |     echo pht('Creating %d documents.', count($created))."\n"; | ||||||
|     $this->createDocumentsByHash(array_keys($created)); |     $this->createDocumentsByHash($created); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   protected function shouldGenerateDocumentForAtom(DivinerAtom $atom) { |   protected function shouldGenerateDocumentForAtom(DivinerAtom $atom) { | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ final class DivinerAtomQuery | |||||||
|   private $types; |   private $types; | ||||||
|   private $contexts; |   private $contexts; | ||||||
|   private $indexes; |   private $indexes; | ||||||
|  |   private $includeUndocumentable; | ||||||
|  |  | ||||||
|   private $needAtoms; |   private $needAtoms; | ||||||
|  |  | ||||||
| @@ -53,6 +54,11 @@ final class DivinerAtomQuery | |||||||
|     return $this; |     return $this; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   public function withIncludeUndocumentable($include) { | ||||||
|  |     $this->includeUndocumentable = $include; | ||||||
|  |     return $this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   protected function loadPage() { |   protected function loadPage() { | ||||||
|     $table = new DivinerLiveSymbol(); |     $table = new DivinerLiveSymbol(); | ||||||
|     $conn_r = $table->establishConnection('r'); |     $conn_r = $table->establishConnection('r'); | ||||||
| @@ -182,6 +188,12 @@ final class DivinerAtomQuery | |||||||
|         $this->indexes); |         $this->indexes); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     if (!$this->includeUndocumentable) { | ||||||
|  |       $where[] = qsprintf( | ||||||
|  |         $conn_r, | ||||||
|  |         'isDocumentable = 1'); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     $where[] = $this->buildPagingClause($conn_r); |     $where[] = $this->buildPagingClause($conn_r); | ||||||
|  |  | ||||||
|     return $this->formatWhereClause($where); |     return $this->formatWhereClause($where); | ||||||
|   | |||||||
| @@ -6,18 +6,35 @@ final class DivinerLiveBook extends DivinerDAO | |||||||
|   protected $phid; |   protected $phid; | ||||||
|   protected $name; |   protected $name; | ||||||
|   protected $viewPolicy; |   protected $viewPolicy; | ||||||
|  |   protected $configurationData = array(); | ||||||
|  |  | ||||||
|   public function getConfiguration() { |   public function getConfiguration() { | ||||||
|     return array( |     return array( | ||||||
|       self::CONFIG_AUX_PHID => true, |       self::CONFIG_AUX_PHID => true, | ||||||
|  |       self::CONFIG_SERIALIZATION => array( | ||||||
|  |         'configurationData' => self::SERIALIZATION_JSON, | ||||||
|  |       ), | ||||||
|     ) + parent::getConfiguration(); |     ) + parent::getConfiguration(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   public function getConfig($key, $default = null) { | ||||||
|  |     return idx($this->configurationData, $key, $default); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public function setConfig($key, $value) { | ||||||
|  |     $this->configurationData[$key] = $value; | ||||||
|  |     return $this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   public function generatePHID() { |   public function generatePHID() { | ||||||
|     return PhabricatorPHID::generateNewPHID( |     return PhabricatorPHID::generateNewPHID( | ||||||
|       PhabricatorPHIDConstants::PHID_TYPE_BOOK); |       PhabricatorPHIDConstants::PHID_TYPE_BOOK); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   public function getTitle() { | ||||||
|  |     return $this->getConfig('title', $this->getName()); | ||||||
|  |   } | ||||||
|  |  | ||||||
| /* -(  PhabricatorPolicyInterface  )----------------------------------------- */ | /* -(  PhabricatorPolicyInterface  )----------------------------------------- */ | ||||||
|  |  | ||||||
|   public function getCapabilities() { |   public function getCapabilities() { | ||||||
|   | |||||||
| @@ -12,6 +12,11 @@ final class DivinerLiveSymbol extends DivinerDAO | |||||||
|   protected $graphHash; |   protected $graphHash; | ||||||
|   protected $identityHash; |   protected $identityHash; | ||||||
|  |  | ||||||
|  |   protected $title; | ||||||
|  |   protected $groupName; | ||||||
|  |   protected $summary; | ||||||
|  |   protected $isDocumentable = 0; | ||||||
|  |  | ||||||
|   private $book; |   private $book; | ||||||
|   private $content; |   private $content; | ||||||
|   private $atom; |   private $atom; | ||||||
| @@ -80,6 +85,10 @@ final class DivinerLiveSymbol extends DivinerDAO | |||||||
|     return '/'.implode('/', $parts).'/'; |     return '/'.implode('/', $parts).'/'; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   public function getSortKey() { | ||||||
|  |     return $this->getTitle(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   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 | ||||||
| @@ -101,6 +110,14 @@ final class DivinerLiveSymbol extends DivinerDAO | |||||||
|     return parent::save(); |     return parent::save(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   public function getTitle() { | ||||||
|  |     $title = parent::getTitle(); | ||||||
|  |     if (!strlen($title)) { | ||||||
|  |       $title = $this->getName(); | ||||||
|  |     } | ||||||
|  |     return $title; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  | ||||||
| /* -(  PhabricatorPolicyInterface  )----------------------------------------- */ | /* -(  PhabricatorPolicyInterface  )----------------------------------------- */ | ||||||
|  |  | ||||||
|   | |||||||
| @@ -131,7 +131,7 @@ final class DivinerGenerateWorkflow extends DivinerWorkflow { | |||||||
|     $this->buildAtomCache(); |     $this->buildAtomCache(); | ||||||
|     $this->buildGraphCache(); |     $this->buildGraphCache(); | ||||||
|  |  | ||||||
|     $this->publishDocumentation(); |     $this->publishDocumentation($args->getArg('clean')); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| /* -(  Atom Cache  )--------------------------------------------------------- */ | /* -(  Atom Cache  )--------------------------------------------------------- */ | ||||||
| @@ -439,13 +439,14 @@ final class DivinerGenerateWorkflow extends DivinerWorkflow { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|   private function publishDocumentation() { |   private function publishDocumentation($clean) { | ||||||
|     $atom_cache = $this->getAtomCache(); |     $atom_cache = $this->getAtomCache(); | ||||||
|     $graph_map = $atom_cache->getGraphMap(); |     $graph_map = $atom_cache->getGraphMap(); | ||||||
|  |  | ||||||
|     $this->log(pht('PUBLISHING DOCUMENTATION')); |     $this->log(pht('PUBLISHING DOCUMENTATION')); | ||||||
|  |  | ||||||
|     $publisher = new DivinerLivePublisher(); |     $publisher = new DivinerLivePublisher(); | ||||||
|  |     $publisher->setDropCaches($clean); | ||||||
|     $publisher->setConfig($this->getAllConfig()); |     $publisher->setConfig($this->getAllConfig()); | ||||||
|     $publisher->setAtomCache($atom_cache); |     $publisher->setAtomCache($atom_cache); | ||||||
|     $publisher->setRenderer(new DivinerDefaultRenderer()); |     $publisher->setRenderer(new DivinerDefaultRenderer()); | ||||||
|   | |||||||
| @@ -1,4 +1,34 @@ | |||||||
| { | { | ||||||
|   "name" : "phabricator", |   "name" : "phabricator", | ||||||
|   "root" : "../../../" |   "title" : "Phabricator User Documentation", | ||||||
|  |   "root" : "../../../", | ||||||
|  |   "groups" : { | ||||||
|  |     "intro" : { | ||||||
|  |       "name" : "Introduction" | ||||||
|  |     }, | ||||||
|  |     "config" : { | ||||||
|  |       "name" : "Configuration" | ||||||
|  |     }, | ||||||
|  |     "userguide" : { | ||||||
|  |       "name" : "Application User Guides" | ||||||
|  |     }, | ||||||
|  |     "differential" : { | ||||||
|  |       "name" : "Differential (Code Review)" | ||||||
|  |     }, | ||||||
|  |     "diffusion" : { | ||||||
|  |       "name" : "Diffusion (Repository Browser)" | ||||||
|  |     }, | ||||||
|  |     "maniphest" : { | ||||||
|  |       "name" : "Maniphest (Task Tracking)" | ||||||
|  |     }, | ||||||
|  |     "slowvote" : { | ||||||
|  |       "name" : "Slowvote (Polls)" | ||||||
|  |     }, | ||||||
|  |     "herald" : { | ||||||
|  |       "name" : "Herald (Notifications)" | ||||||
|  |     }, | ||||||
|  |     "phriction" : { | ||||||
|  |       "name" : "Phriction (Wiki)" | ||||||
|  |     } | ||||||
|  |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1342,6 +1342,10 @@ final class PhabricatorBuiltinPatchList extends PhabricatorSQLPatchList { | |||||||
|         'type' => 'sql', |         'type' => 'sql', | ||||||
|         'name' => $this->getPatchPath('20130531.filekeys.sql'), |         'name' => $this->getPatchPath('20130531.filekeys.sql'), | ||||||
|       ), |       ), | ||||||
|  |       '20130602.morediviner.sql' => array( | ||||||
|  |         'type' => 'sql', | ||||||
|  |         'name' => $this->getPatchPath('20130602.morediviner.sql'), | ||||||
|  |       ), | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 epriestley
					epriestley