Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/diviner/publisher/DivinerLivePublisher.php
12256 views
1
<?php
2
3
final class DivinerLivePublisher extends DivinerPublisher {
4
5
private $book;
6
7
protected function getBook() {
8
if (!$this->book) {
9
$book_name = $this->getConfig('name');
10
11
$book = id(new DivinerLiveBook())->loadOneWhere(
12
'name = %s',
13
$book_name);
14
15
if (!$book) {
16
$book = id(new DivinerLiveBook())
17
->setName($book_name)
18
->setViewPolicy(PhabricatorPolicies::getMostOpenPolicy())
19
->setEditPolicy(PhabricatorPolicies::POLICY_ADMIN)
20
->save();
21
}
22
23
$conn_w = $book->establishConnection('w');
24
$conn_w->openTransaction();
25
26
$book
27
->setRepositoryPHID($this->getRepositoryPHID())
28
->setConfigurationData($this->getConfigurationData())
29
->save();
30
31
// TODO: This is gross. Without this, the repository won't be updated for
32
// atoms which have already been published.
33
queryfx(
34
$conn_w,
35
'UPDATE %T SET repositoryPHID = %s WHERE bookPHID = %s',
36
id(new DivinerLiveSymbol())->getTableName(),
37
$this->getRepositoryPHID(),
38
$book->getPHID());
39
40
$conn_w->saveTransaction();
41
$this->book = $book;
42
43
PhabricatorSearchWorker::queueDocumentForIndexing($book->getPHID());
44
}
45
46
return $this->book;
47
}
48
49
private function loadSymbolForAtom(DivinerAtom $atom) {
50
$symbol = id(new DivinerAtomQuery())
51
->setViewer(PhabricatorUser::getOmnipotentUser())
52
->withBookPHIDs(array($this->getBook()->getPHID()))
53
->withTypes(array($atom->getType()))
54
->withNames(array($atom->getName()))
55
->withContexts(array($atom->getContext()))
56
->withIndexes(array($this->getAtomSimilarIndex($atom)))
57
->executeOne();
58
59
if ($symbol) {
60
return $symbol;
61
}
62
63
return id(new DivinerLiveSymbol())
64
->setBookPHID($this->getBook()->getPHID())
65
->setType($atom->getType())
66
->setName($atom->getName())
67
->setContext($atom->getContext())
68
->setAtomIndex($this->getAtomSimilarIndex($atom));
69
}
70
71
private function loadAtomStorageForSymbol(DivinerLiveSymbol $symbol) {
72
$storage = id(new DivinerLiveAtom())->loadOneWhere(
73
'symbolPHID = %s',
74
$symbol->getPHID());
75
76
if ($storage) {
77
return $storage;
78
}
79
80
return id(new DivinerLiveAtom())
81
->setSymbolPHID($symbol->getPHID());
82
}
83
84
protected function loadAllPublishedHashes() {
85
$symbols = id(new DivinerAtomQuery())
86
->setViewer(PhabricatorUser::getOmnipotentUser())
87
->withBookPHIDs(array($this->getBook()->getPHID()))
88
->withGhosts(false)
89
->execute();
90
91
return mpull($symbols, 'getGraphHash');
92
}
93
94
protected function deleteDocumentsByHash(array $hashes) {
95
$atom_table = new DivinerLiveAtom();
96
$symbol_table = new DivinerLiveSymbol();
97
$conn_w = $symbol_table->establishConnection('w');
98
99
$strings = array();
100
foreach ($hashes as $hash) {
101
$strings[] = qsprintf($conn_w, '%s', $hash);
102
}
103
104
foreach (PhabricatorLiskDAO::chunkSQL($strings) as $chunk) {
105
queryfx(
106
$conn_w,
107
'UPDATE %T SET graphHash = NULL, nodeHash = NULL
108
WHERE graphHash IN (%LQ)',
109
$symbol_table->getTableName(),
110
$chunk);
111
}
112
113
queryfx(
114
$conn_w,
115
'DELETE a FROM %T a LEFT JOIN %T s
116
ON a.symbolPHID = s.phid
117
WHERE s.graphHash IS NULL',
118
$atom_table->getTableName(),
119
$symbol_table->getTableName());
120
}
121
122
protected function createDocumentsByHash(array $hashes) {
123
foreach ($hashes as $hash) {
124
$atom = $this->getAtomFromGraphHash($hash);
125
$ref = $atom->getRef();
126
127
$symbol = $this->loadSymbolForAtom($atom);
128
129
$is_documentable = $this->shouldGenerateDocumentForAtom($atom);
130
131
$symbol
132
->setRepositoryPHID($this->getRepositoryPHID())
133
->setGraphHash($hash)
134
->setIsDocumentable((int)$is_documentable)
135
->setTitle($ref->getTitle())
136
->setGroupName($ref->getGroup())
137
->setNodeHash($atom->getHash());
138
139
if ($atom->getType() !== DivinerAtom::TYPE_FILE) {
140
$renderer = $this->getRenderer();
141
$summary = $renderer->getAtomSummary($atom);
142
$symbol->setSummary($summary);
143
} else {
144
$symbol->setSummary('');
145
}
146
147
$symbol->save();
148
149
PhabricatorSearchWorker::queueDocumentForIndexing($symbol->getPHID());
150
151
// TODO: We probably need a finer-grained sense of what "documentable"
152
// atoms are. Neither files nor methods are currently considered
153
// documentable, but for different reasons: files appear nowhere, while
154
// methods just don't appear at the top level. These are probably
155
// separate concepts. Since we need atoms in order to build method
156
// documentation, we insert them here. This also means we insert files,
157
// which are unnecessary and unused. Make sure this makes sense, but then
158
// probably introduce separate "isTopLevel" and "isDocumentable" flags?
159
// TODO: Yeah do that soon ^^^
160
161
if ($atom->getType() !== DivinerAtom::TYPE_FILE) {
162
$storage = $this->loadAtomStorageForSymbol($symbol)
163
->setAtomData($atom->toDictionary())
164
->setContent(null)
165
->save();
166
}
167
}
168
}
169
170
public function findAtomByRef(DivinerAtomRef $ref) {
171
// TODO: Actually implement this.
172
return null;
173
}
174
175
}
176
177