Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/diviner/atom/DivinerAtomRef.php
12256 views
1
<?php
2
3
final class DivinerAtomRef extends Phobject {
4
5
private $book;
6
private $context;
7
private $type;
8
private $name;
9
private $group;
10
private $summary;
11
private $index;
12
private $title;
13
14
public function getSortKey() {
15
return implode(
16
"\0",
17
array(
18
$this->getName(),
19
$this->getType(),
20
$this->getContext(),
21
$this->getBook(),
22
$this->getIndex(),
23
));
24
}
25
26
public function setIndex($index) {
27
$this->index = $index;
28
return $this;
29
}
30
31
public function getIndex() {
32
return $this->index;
33
}
34
35
public function setSummary($summary) {
36
$this->summary = $summary;
37
return $this;
38
}
39
40
public function getSummary() {
41
return $this->summary;
42
}
43
44
public function setName($name) {
45
$normal_name = self::normalizeString($name);
46
if (preg_match('/^@\d+\z/', $normal_name)) {
47
throw new Exception(
48
pht(
49
"Atom names must not be in the form '%s'. This pattern is ".
50
"reserved for disambiguating atoms with similar names.",
51
'/@\d+/'));
52
}
53
$this->name = $normal_name;
54
return $this;
55
}
56
57
public function getName() {
58
return $this->name;
59
}
60
61
public function setType($type) {
62
$this->type = self::normalizeString($type);
63
return $this;
64
}
65
66
public function getType() {
67
return $this->type;
68
}
69
70
public function setContext($context) {
71
if ($context === null) {
72
$this->context = $context;
73
} else {
74
$this->context = self::normalizeString($context);
75
}
76
return $this;
77
}
78
79
public function getContext() {
80
return $this->context;
81
}
82
83
public function setBook($book) {
84
if ($book === null) {
85
$this->book = $book;
86
} else {
87
$this->book = self::normalizeString($book);
88
}
89
return $this;
90
}
91
92
public function getBook() {
93
return $this->book;
94
}
95
96
public function setGroup($group) {
97
$this->group = $group;
98
return $this;
99
}
100
101
public function getGroup() {
102
return $this->group;
103
}
104
105
public function setTitle($title) {
106
$this->title = $title;
107
return $this;
108
}
109
110
public function getTitle() {
111
return $this->title;
112
}
113
114
public function getTitleSlug() {
115
return self::normalizeTitleString($this->getTitle());
116
}
117
118
public function toDictionary() {
119
return array(
120
'book' => $this->getBook(),
121
'context' => $this->getContext(),
122
'type' => $this->getType(),
123
'name' => $this->getName(),
124
'group' => $this->getGroup(),
125
'summary' => $this->getSummary(),
126
'index' => $this->getIndex(),
127
'title' => $this->getTitle(),
128
);
129
}
130
131
public function toHash() {
132
$dict = $this->toDictionary();
133
134
unset($dict['group']);
135
unset($dict['index']);
136
unset($dict['summary']);
137
unset($dict['title']);
138
139
ksort($dict);
140
return md5(serialize($dict)).'S';
141
}
142
143
public static function newFromDictionary(array $dict) {
144
return id(new DivinerAtomRef())
145
->setBook(idx($dict, 'book'))
146
->setContext(idx($dict, 'context'))
147
->setType(idx($dict, 'type'))
148
->setName(idx($dict, 'name'))
149
->setGroup(idx($dict, 'group'))
150
->setSummary(idx($dict, 'summary'))
151
->setIndex(idx($dict, 'index'))
152
->setTitle(idx($dict, 'title'));
153
}
154
155
public static function normalizeString($str) {
156
// These characters create problems on the filesystem or in URIs. Replace
157
// them with non-problematic approximations (instead of simply removing
158
// them) to keep the URIs fairly useful and avoid unnecessary collisions.
159
// These approximations are selected based on some domain knowledge of
160
// common languages: where a character is used as a delimiter, it is more
161
// helpful to replace it with a "." or a ":" or similar, while it's better
162
// if operator overloads read as, e.g., "operator_div".
163
164
$map = array(
165
// Hopefully not used anywhere by anything.
166
'#' => '.',
167
168
// Used in Ruby methods.
169
'?' => 'Q',
170
171
// Used in PHP namespaces.
172
'\\' => '.',
173
174
// Used in "operator +" in C++.
175
'+' => 'plus',
176
177
// Used in "operator %" in C++.
178
'%' => 'mod',
179
180
// Used in "operator /" in C++.
181
'/' => 'div',
182
);
183
$str = str_replace(array_keys($map), array_values($map), $str);
184
185
// Replace all spaces with underscores.
186
$str = preg_replace('/ +/', '_', $str);
187
188
// Replace control characters with "X".
189
$str = preg_replace('/[\x00-\x19]/', 'X', $str);
190
191
// Replace specific problematic names with alternative names.
192
$alternates = array(
193
'.' => 'dot',
194
'..' => 'dotdot',
195
'' => 'null',
196
);
197
198
return idx($alternates, $str, $str);
199
}
200
201
public static function normalizeTitleString($str) {
202
// Remove colons from titles. This is mostly to accommodate legacy rules
203
// from the old Diviner, which generated a significant number of article
204
// URIs without colons present in the titles.
205
$str = str_replace(':', '', $str);
206
$str = self::normalizeString($str);
207
return phutil_utf8_strtolower($str);
208
}
209
210
}
211
212