@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 AlmanacNamespace
4 extends AlmanacDAO
5 implements
6 PhabricatorPolicyInterface,
7 PhabricatorApplicationTransactionInterface,
8 PhabricatorProjectInterface,
9 PhabricatorDestructibleInterface,
10 PhabricatorNgramsInterface,
11 PhabricatorConduitResultInterface {
12
13 protected $name;
14 protected $nameIndex;
15 protected $viewPolicy;
16 protected $editPolicy;
17
18 public static function initializeNewNamespace() {
19 return id(new self())
20 ->setViewPolicy(PhabricatorPolicies::POLICY_USER)
21 ->setEditPolicy(PhabricatorPolicies::POLICY_ADMIN);
22 }
23
24 protected function getConfiguration() {
25 return array(
26 self::CONFIG_AUX_PHID => true,
27 self::CONFIG_COLUMN_SCHEMA => array(
28 'name' => 'text128',
29 'nameIndex' => 'bytes12',
30 ),
31 self::CONFIG_KEY_SCHEMA => array(
32 'key_nameindex' => array(
33 'columns' => array('nameIndex'),
34 'unique' => true,
35 ),
36 'key_name' => array(
37 'columns' => array('name'),
38 ),
39 ),
40 ) + parent::getConfiguration();
41 }
42
43 public function getPHIDType() {
44 return AlmanacNamespacePHIDType::TYPECONST;
45 }
46
47 public function save() {
48 AlmanacNames::validateName($this->getName());
49
50 $this->nameIndex = PhabricatorHash::digestForIndex($this->getName());
51
52 return parent::save();
53 }
54
55 public function getURI() {
56 return urisprintf(
57 '/almanac/namespace/view/%s/',
58 $this->getName());
59 }
60
61 public function getNameLength() {
62 return strlen($this->getName());
63 }
64
65 /**
66 * Load the namespace which prevents use of an Almanac name, if one exists.
67 */
68 public static function loadRestrictedNamespace(
69 PhabricatorUser $viewer,
70 $name) {
71
72 // For a name like "x.y.z", produce a list of controlling namespaces like
73 // ("z", "y.x", "x.y.z").
74 $names = array();
75 $parts = explode('.', $name);
76 for ($ii = 0; $ii < count($parts); $ii++) {
77 $names[] = implode('.', array_slice($parts, -($ii + 1)));
78 }
79
80 // Load all the possible controlling namespaces.
81 $namespaces = id(new AlmanacNamespaceQuery())
82 ->setViewer(PhabricatorUser::getOmnipotentUser())
83 ->withNames($names)
84 ->execute();
85 if (!$namespaces) {
86 return null;
87 }
88
89 // Find the "nearest" (longest) namespace that exists. If both
90 // "sub.domain.com" and "domain.com" exist, we only care about the policy
91 // on the former.
92 $namespaces = msort($namespaces, 'getNameLength');
93 $namespace = last($namespaces);
94
95 $can_edit = PhabricatorPolicyFilter::hasCapability(
96 $viewer,
97 $namespace,
98 PhabricatorPolicyCapability::CAN_EDIT);
99 if ($can_edit) {
100 return null;
101 }
102
103 return $namespace;
104 }
105
106
107/* -( PhabricatorPolicyInterface )----------------------------------------- */
108
109
110 public function getCapabilities() {
111 return array(
112 PhabricatorPolicyCapability::CAN_VIEW,
113 PhabricatorPolicyCapability::CAN_EDIT,
114 );
115 }
116
117 public function getPolicy($capability) {
118 switch ($capability) {
119 case PhabricatorPolicyCapability::CAN_VIEW:
120 return $this->getViewPolicy();
121 case PhabricatorPolicyCapability::CAN_EDIT:
122 return $this->getEditPolicy();
123 }
124 }
125
126 public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
127 return false;
128 }
129
130
131/* -( PhabricatorApplicationTransactionInterface )------------------------- */
132
133
134 public function getApplicationTransactionEditor() {
135 return new AlmanacNamespaceEditor();
136 }
137
138 public function getApplicationTransactionTemplate() {
139 return new AlmanacNamespaceTransaction();
140 }
141
142
143/* -( PhabricatorDestructibleInterface )----------------------------------- */
144
145
146 public function destroyObjectPermanently(
147 PhabricatorDestructionEngine $engine) {
148 $this->delete();
149 }
150
151
152/* -( PhabricatorNgramsInterface )----------------------------------------- */
153
154
155 public function newNgrams() {
156 return array(
157 id(new AlmanacNamespaceNameNgrams())
158 ->setValue($this->getName()),
159 );
160 }
161
162
163/* -( PhabricatorConduitResultInterface )---------------------------------- */
164
165
166 public function getFieldSpecificationsForConduit() {
167 return array(
168 id(new PhabricatorConduitSearchFieldSpecification())
169 ->setKey('name')
170 ->setType('string')
171 ->setDescription(pht('The name of the namespace.')),
172 );
173 }
174
175 public function getFieldValuesForConduit() {
176 return array(
177 'name' => $this->getName(),
178 );
179 }
180
181 public function getConduitSearchAttachments() {
182 return array();
183 }
184
185
186}