@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<?php
2
3final class PhabricatorPhurlURL extends PhabricatorPhurlDAO
4 implements PhabricatorPolicyInterface,
5 PhabricatorProjectInterface,
6 PhabricatorApplicationTransactionInterface,
7 PhabricatorSubscribableInterface,
8 PhabricatorTokenReceiverInterface,
9 PhabricatorDestructibleInterface,
10 PhabricatorMentionableInterface,
11 PhabricatorFlaggableInterface,
12 PhabricatorSpacesInterface,
13 PhabricatorConduitResultInterface,
14 PhabricatorNgramsInterface {
15
16 protected $name;
17 protected $alias;
18 protected $longURL;
19 protected $description;
20
21 protected $viewPolicy;
22 protected $editPolicy;
23
24 protected $authorPHID;
25 protected $spacePHID;
26
27 protected $mailKey;
28
29 const DEFAULT_ICON = 'fa-compress';
30
31 public static function initializeNewPhurlURL(PhabricatorUser $actor) {
32 $app = id(new PhabricatorApplicationQuery())
33 ->setViewer($actor)
34 ->withClasses(array(PhabricatorPhurlApplication::class))
35 ->executeOne();
36
37 $view_policy = $app->getPolicy(
38 PhabricatorPhurlURLDefaultViewCapability::CAPABILITY);
39 $edit_policy = $app->getPolicy(
40 PhabricatorPhurlURLDefaultEditCapability::CAPABILITY);
41
42 return id(new PhabricatorPhurlURL())
43 ->setAuthorPHID($actor->getPHID())
44 ->setViewPolicy($view_policy)
45 ->setEditPolicy($edit_policy)
46 ->setSpacePHID($actor->getDefaultSpacePHID());
47 }
48
49 protected function getConfiguration() {
50 return array(
51 self::CONFIG_AUX_PHID => true,
52 self::CONFIG_COLUMN_SCHEMA => array(
53 'name' => 'text',
54 'alias' => 'sort64?',
55 'longURL' => 'text',
56 'description' => 'text',
57 'mailKey' => 'bytes20',
58 ),
59 self::CONFIG_KEY_SCHEMA => array(
60 'key_instance' => array(
61 'columns' => array('alias'),
62 'unique' => true,
63 ),
64 'key_author' => array(
65 'columns' => array('authorPHID'),
66 ),
67 ),
68 ) + parent::getConfiguration();
69 }
70
71 public function save() {
72 if (!$this->getMailKey()) {
73 $this->setMailKey(Filesystem::readRandomCharacters(20));
74 }
75 return parent::save();
76 }
77
78 public function generatePHID() {
79 return PhabricatorPHID::generateNewPHID(
80 PhabricatorPhurlURLPHIDType::TYPECONST);
81 }
82
83 public function getMonogram() {
84 return 'U'.$this->getID();
85 }
86
87 public function getURI() {
88 $uri = '/'.$this->getMonogram();
89 return $uri;
90 }
91
92 public function isValid() {
93 $allowed_protocols = PhabricatorEnv::getEnvConfig('uri.allowed-protocols');
94 $uri = new PhutilURI($this->getLongURL());
95
96 return isset($allowed_protocols[$uri->getProtocol()]);
97 }
98
99 public function getDisplayName() {
100 if ($this->getName()) {
101 return $this->getName();
102 } else {
103 return $this->getLongURL();
104 }
105 }
106
107 public function getRedirectURI() {
108 if (strlen($this->getAlias())) {
109 $path = '/u/'.$this->getAlias();
110 } else {
111 $path = '/u/'.$this->getID();
112 }
113 $domain = PhabricatorEnv::getEnvConfig('phurl.short-uri');
114 if (!$domain) {
115 $domain = PhabricatorEnv::getEnvConfig('phabricator.base-uri');
116 }
117
118 $uri = new PhutilURI($domain);
119 $uri->setPath($path);
120 return (string)$uri;
121 }
122
123/* -( PhabricatorPolicyInterface )----------------------------------------- */
124
125
126 public function getCapabilities() {
127 return array(
128 PhabricatorPolicyCapability::CAN_VIEW,
129 PhabricatorPolicyCapability::CAN_EDIT,
130 );
131 }
132
133 public function getPolicy($capability) {
134 switch ($capability) {
135 case PhabricatorPolicyCapability::CAN_VIEW:
136 return $this->getViewPolicy();
137 case PhabricatorPolicyCapability::CAN_EDIT:
138 return $this->getEditPolicy();
139 }
140 }
141
142 public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
143 $user_phid = $this->getAuthorPHID();
144 if ($user_phid) {
145 $viewer_phid = $viewer->getPHID();
146 if ($viewer_phid == $user_phid) {
147 return true;
148 }
149 }
150
151 return false;
152 }
153
154 public function describeAutomaticCapability($capability) {
155 return pht('The author of a URL can always view and edit it.');
156 }
157
158/* -( PhabricatorApplicationTransactionInterface )------------------------- */
159
160
161 public function getApplicationTransactionEditor() {
162 return new PhabricatorPhurlURLEditor();
163 }
164
165 public function getApplicationTransactionTemplate() {
166 return new PhabricatorPhurlURLTransaction();
167 }
168
169
170/* -( PhabricatorSubscribableInterface )----------------------------------- */
171
172
173 public function isAutomaticallySubscribed($phid) {
174 return ($phid == $this->getAuthorPHID());
175 }
176
177
178/* -( PhabricatorTokenReceiverInterface )---------------------------------- */
179
180
181 public function getUsersToNotifyOfTokenGiven() {
182 return array($this->getAuthorPHID());
183 }
184
185/* -( PhabricatorDestructibleInterface )----------------------------------- */
186
187
188 public function destroyObjectPermanently(
189 PhabricatorDestructionEngine $engine) {
190
191 $this->openTransaction();
192 $this->delete();
193 $this->saveTransaction();
194 }
195
196/* -( PhabricatorSpacesInterface )----------------------------------------- */
197
198
199 public function getSpacePHID() {
200 return $this->spacePHID;
201 }
202
203/* -( PhabricatorConduitResultInterface )---------------------------------- */
204
205
206 public function getFieldSpecificationsForConduit() {
207 return array(
208 id(new PhabricatorConduitSearchFieldSpecification())
209 ->setKey('name')
210 ->setType('string')
211 ->setDescription(pht('URL name.')),
212 id(new PhabricatorConduitSearchFieldSpecification())
213 ->setKey('alias')
214 ->setType('string')
215 ->setDescription(pht('The alias for the URL.')),
216 id(new PhabricatorConduitSearchFieldSpecification())
217 ->setKey('longurl')
218 ->setType('string')
219 ->setDescription(pht('The pre-shortened URL.')),
220 id(new PhabricatorConduitSearchFieldSpecification())
221 ->setKey('description')
222 ->setType('string')
223 ->setDescription(pht('A description of the URL.')),
224 );
225 }
226
227 public function getFieldValuesForConduit() {
228 return array(
229 'name' => $this->getName(),
230 'alias' => $this->getAlias(),
231 'description' => $this->getDescription(),
232 'urls' => array(
233 'long' => $this->getLongURL(),
234 'short' => $this->getRedirectURI(),
235 ),
236 );
237 }
238
239 public function getConduitSearchAttachments() {
240 return array();
241 }
242
243/* -( PhabricatorNgramInterface )------------------------------------------ */
244
245
246 public function newNgrams() {
247 return array(
248 id(new PhabricatorPhurlURLNameNgrams())
249 ->setValue($this->getName()),
250 );
251 }
252
253}