Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/diviner/storage/DivinerLiveSymbol.php
12256 views
1
<?php
2
3
final class DivinerLiveSymbol extends DivinerDAO
4
implements
5
PhabricatorPolicyInterface,
6
PhabricatorMarkupInterface,
7
PhabricatorDestructibleInterface,
8
PhabricatorFulltextInterface {
9
10
protected $bookPHID;
11
protected $repositoryPHID;
12
protected $context;
13
protected $type;
14
protected $name;
15
protected $atomIndex;
16
protected $graphHash;
17
protected $identityHash;
18
protected $nodeHash;
19
20
protected $title;
21
protected $titleSlugHash;
22
protected $groupName;
23
protected $summary;
24
protected $isDocumentable = 0;
25
26
private $book = self::ATTACHABLE;
27
private $repository = self::ATTACHABLE;
28
private $atom = self::ATTACHABLE;
29
private $extends = self::ATTACHABLE;
30
private $children = self::ATTACHABLE;
31
32
protected function getConfiguration() {
33
return array(
34
self::CONFIG_AUX_PHID => true,
35
self::CONFIG_TIMESTAMPS => false,
36
self::CONFIG_COLUMN_SCHEMA => array(
37
'context' => 'text255?',
38
'type' => 'text32',
39
'name' => 'text255',
40
'atomIndex' => 'uint32',
41
'identityHash' => 'bytes12',
42
'graphHash' => 'text64?',
43
'title' => 'text?',
44
'titleSlugHash' => 'bytes12?',
45
'groupName' => 'text255?',
46
'summary' => 'text?',
47
'isDocumentable' => 'bool',
48
'nodeHash' => 'text64?',
49
'repositoryPHID' => 'phid?',
50
),
51
self::CONFIG_KEY_SCHEMA => array(
52
'key_phid' => null,
53
'identityHash' => array(
54
'columns' => array('identityHash'),
55
'unique' => true,
56
),
57
'phid' => array(
58
'columns' => array('phid'),
59
'unique' => true,
60
),
61
'graphHash' => array(
62
'columns' => array('graphHash'),
63
'unique' => true,
64
),
65
'nodeHash' => array(
66
'columns' => array('nodeHash'),
67
'unique' => true,
68
),
69
'bookPHID' => array(
70
'columns' => array(
71
'bookPHID',
72
'type',
73
'name(64)',
74
'context(64)',
75
'atomIndex',
76
),
77
),
78
'name' => array(
79
'columns' => array('name(64)'),
80
),
81
'key_slug' => array(
82
'columns' => array('titleSlugHash'),
83
),
84
),
85
) + parent::getConfiguration();
86
}
87
88
public function generatePHID() {
89
return PhabricatorPHID::generateNewPHID(DivinerAtomPHIDType::TYPECONST);
90
}
91
92
public function getBook() {
93
return $this->assertAttached($this->book);
94
}
95
96
public function attachBook(DivinerLiveBook $book) {
97
$this->book = $book;
98
return $this;
99
}
100
101
public function getRepository() {
102
return $this->assertAttached($this->repository);
103
}
104
105
public function attachRepository(PhabricatorRepository $repository = null) {
106
$this->repository = $repository;
107
return $this;
108
}
109
110
public function getAtom() {
111
return $this->assertAttached($this->atom);
112
}
113
114
public function attachAtom(DivinerLiveAtom $atom = null) {
115
if ($atom === null) {
116
$this->atom = null;
117
} else {
118
$this->atom = DivinerAtom::newFromDictionary($atom->getAtomData());
119
}
120
return $this;
121
}
122
123
public function getURI() {
124
$parts = array(
125
'book',
126
$this->getBook()->getName(),
127
$this->getType(),
128
);
129
130
if ($this->getContext()) {
131
$parts[] = $this->getContext();
132
}
133
134
$parts[] = $this->getName();
135
136
if ($this->getAtomIndex()) {
137
$parts[] = $this->getAtomIndex();
138
}
139
140
return '/'.implode('/', $parts).'/';
141
}
142
143
public function getSortKey() {
144
// Sort articles before other types of content. Then, sort atoms in a
145
// case-insensitive way.
146
return sprintf(
147
'%c:%s',
148
($this->getType() == DivinerAtom::TYPE_ARTICLE ? '0' : '1'),
149
phutil_utf8_strtolower($this->getTitle()));
150
}
151
152
public function save() {
153
// NOTE: The identity hash is just a sanity check because the unique tuple
154
// on this table is way too long to fit into a normal `UNIQUE KEY`.
155
// We don't use it directly, but its existence prevents duplicate records.
156
157
if (!$this->identityHash) {
158
$this->identityHash = PhabricatorHash::digestForIndex(
159
serialize(
160
array(
161
'bookPHID' => $this->getBookPHID(),
162
'context' => $this->getContext(),
163
'type' => $this->getType(),
164
'name' => $this->getName(),
165
'index' => $this->getAtomIndex(),
166
)));
167
}
168
169
return parent::save();
170
}
171
172
public function getTitle() {
173
$title = parent::getTitle();
174
175
if (!strlen($title)) {
176
$title = $this->getName();
177
}
178
179
return $title;
180
}
181
182
public function setTitle($value) {
183
$this->writeField('title', $value);
184
185
if ($value !== null && strlen($value)) {
186
$slug = DivinerAtomRef::normalizeTitleString($value);
187
$hash = PhabricatorHash::digestForIndex($slug);
188
$this->titleSlugHash = $hash;
189
} else {
190
$this->titleSlugHash = null;
191
}
192
193
return $this;
194
}
195
196
public function attachExtends(array $extends) {
197
assert_instances_of($extends, __CLASS__);
198
$this->extends = $extends;
199
return $this;
200
}
201
202
public function getExtends() {
203
return $this->assertAttached($this->extends);
204
}
205
206
public function attachChildren(array $children) {
207
assert_instances_of($children, __CLASS__);
208
$this->children = $children;
209
return $this;
210
}
211
212
public function getChildren() {
213
return $this->assertAttached($this->children);
214
}
215
216
217
/* -( PhabricatorPolicyInterface )----------------------------------------- */
218
219
220
public function getCapabilities() {
221
return $this->getBook()->getCapabilities();
222
}
223
224
public function getPolicy($capability) {
225
return $this->getBook()->getPolicy($capability);
226
}
227
228
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
229
return $this->getBook()->hasAutomaticCapability($capability, $viewer);
230
}
231
232
public function describeAutomaticCapability($capability) {
233
return pht('Atoms inherit the policies of the books they are part of.');
234
}
235
236
237
/* -( PhabricatorMarkupInterface )------------------------------------------ */
238
239
240
public function getMarkupFieldKey($field) {
241
return $this->getPHID().':'.$field.':'.$this->getGraphHash();
242
}
243
244
public function newMarkupEngine($field) {
245
return PhabricatorMarkupEngine::getEngine('diviner');
246
}
247
248
public function getMarkupText($field) {
249
if (!$this->getAtom()) {
250
return;
251
}
252
253
return $this->getAtom()->getDocblockText();
254
}
255
256
public function didMarkupText($field, $output, PhutilMarkupEngine $engine) {
257
return $output;
258
}
259
260
public function shouldUseMarkupCache($field) {
261
return true;
262
}
263
264
265
/* -( PhabricatorDestructibleInterface )----------------------------------- */
266
267
268
public function destroyObjectPermanently(
269
PhabricatorDestructionEngine $engine) {
270
271
$this->openTransaction();
272
$conn_w = $this->establishConnection('w');
273
274
queryfx(
275
$conn_w,
276
'DELETE FROM %T WHERE symbolPHID = %s',
277
id(new DivinerLiveAtom())->getTableName(),
278
$this->getPHID());
279
280
$this->delete();
281
$this->saveTransaction();
282
}
283
284
285
/* -( PhabricatorFulltextInterface )--------------------------------------- */
286
287
288
public function newFulltextEngine() {
289
if (!$this->getIsDocumentable()) {
290
return null;
291
}
292
293
return new DivinerLiveSymbolFulltextEngine();
294
}
295
296
}
297
298