@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 ManiphestTaskPriority extends ManiphestConstants {
4
5 const UNKNOWN_PRIORITY_KEYWORD = '!!unknown!!';
6
7 /**
8 * Get the priorities and their full descriptions.
9 *
10 * @return map Priorities to descriptions.
11 */
12 public static function getTaskPriorityMap() {
13 $map = self::getConfig();
14 foreach ($map as $key => $spec) {
15 $map[$key] = idx($spec, 'name', $key);
16 }
17 return $map;
18 }
19
20
21 /**
22 * Get the priorities and their command keywords.
23 *
24 * @return map Priorities to lists of command keywords.
25 */
26 public static function getTaskPriorityKeywordsMap() {
27 $map = self::getConfig();
28 foreach ($map as $key => $spec) {
29 $words = idx($spec, 'keywords', array());
30 if (!is_array($words)) {
31 $words = array($words);
32 }
33
34 foreach ($words as $word_key => $word) {
35 $words[$word_key] = phutil_utf8_strtolower($word);
36 }
37
38 $words = array_unique($words);
39
40 $map[$key] = $words;
41 }
42
43 return $map;
44 }
45
46 /**
47 * Get the canonical keyword for a given priority constant.
48 *
49 * @return string|null Keyword, or `null` if no keyword is configured.
50 */
51 public static function getKeywordForTaskPriority($priority) {
52 $map = self::getConfig();
53
54 $spec = idx($map, $priority);
55 if (!$spec) {
56 return null;
57 }
58
59 $keywords = idx($spec, 'keywords');
60 if (!$keywords) {
61 return null;
62 }
63
64 return head($keywords);
65 }
66
67
68 /**
69 * Get a map of supported alternate names for each priority.
70 *
71 * Keys are aliases, like "wish" and "wishlist". Values are canonical
72 * priority keywords, like "wishlist".
73 *
74 * @return map<string, string> Map of aliases to canonical priority keywords.
75 */
76 public static function getTaskPriorityAliasMap() {
77 $keyword_map = self::getTaskPriorityKeywordsMap();
78
79 $result = array();
80 foreach ($keyword_map as $key => $keywords) {
81 $target = self::getKeywordForTaskPriority($key);
82 if ($target === null) {
83 continue;
84 }
85
86 // NOTE: Include the raw priority value, like "25", in the list of
87 // aliases. This supports legacy sources like saved EditEngine forms.
88 $result[$key] = $target;
89
90 foreach ($keywords as $keyword) {
91 $result[$keyword] = $target;
92 }
93 }
94
95 return $result;
96 }
97
98
99 /**
100 * Get the priorities and their related short (one-word) descriptions.
101 *
102 * @return map Priorities to short descriptions.
103 */
104 public static function getShortNameMap() {
105 $map = self::getConfig();
106 foreach ($map as $key => $spec) {
107 $map[$key] = idx($spec, 'short', idx($spec, 'name', $key));
108 }
109 return $map;
110 }
111
112
113 /**
114 * Get a map from priority constants to their colors.
115 *
116 * @return map<int, string> Priorities to colors.
117 */
118 public static function getColorMap() {
119 $map = self::getConfig();
120 foreach ($map as $key => $spec) {
121 $map[$key] = idx($spec, 'color', 'grey');
122 }
123 return $map;
124 }
125
126
127 /**
128 * Return the default priority for this instance of Phabricator.
129 *
130 * @return int The value of the default priority constant.
131 */
132 public static function getDefaultPriority() {
133 return PhabricatorEnv::getEnvConfig('maniphest.default-priority');
134 }
135
136
137 /**
138 * Retrieve the full name of the priority level provided.
139 *
140 * @param int $priority A priority level.
141 * @return string The priority name if the level is a valid one.
142 */
143 public static function getTaskPriorityName($priority) {
144 return idx(self::getTaskPriorityMap(), $priority, $priority);
145 }
146
147 /**
148 * Retrieve the color of the priority level given
149 *
150 * @param int $priority A priority level.
151 * @return string The color of the priority if the level is valid,
152 * or black if it is not.
153 */
154 public static function getTaskPriorityColor($priority) {
155 return idx(self::getColorMap(), $priority, 'black');
156 }
157
158 public static function getTaskPriorityIcon($priority) {
159 return 'fa-arrow-right';
160 }
161
162 public static function getTaskPriorityFromKeyword($keyword) {
163 $map = self::getTaskPriorityKeywordsMap();
164
165 foreach ($map as $priority => $keywords) {
166 if (in_array($keyword, $keywords)) {
167 return $priority;
168 }
169 }
170
171 return null;
172 }
173
174 public static function isDisabledPriority($priority) {
175 $config = idx(self::getConfig(), $priority, array());
176 return idx($config, 'disabled', false);
177 }
178
179 public static function getConfig() {
180 $config = PhabricatorEnv::getEnvConfig('maniphest.priorities');
181 krsort($config);
182 return $config;
183 }
184
185 private static function isValidPriorityKeyword($keyword) {
186 if (!strlen($keyword) || strlen($keyword) > 64) {
187 return false;
188 }
189
190 // Alphanumeric, but not exclusively numeric
191 if (!preg_match('/^(?![0-9]*$)[a-zA-Z0-9]+$/', $keyword)) {
192 return false;
193 }
194 return true;
195 }
196
197 public static function validateConfiguration($config) {
198 if (!is_array($config)) {
199 throw new Exception(
200 pht(
201 'Configuration is not valid. Maniphest priority configurations '.
202 'must be dictionaries.'));
203 }
204
205 $all_keywords = array();
206 foreach ($config as $key => $value) {
207 if (!ctype_digit((string)$key)) {
208 throw new Exception(
209 pht(
210 'Key "%s" is not a valid priority constant. Priority constants '.
211 'must be nonnegative integers.',
212 $key));
213 }
214
215 if (!is_array($value)) {
216 throw new Exception(
217 pht(
218 'Value for key "%s" should be a dictionary.',
219 $key));
220 }
221
222 PhutilTypeSpec::checkMap(
223 $value,
224 array(
225 'name' => 'string',
226 'keywords' => 'list<string>',
227 'short' => 'optional string',
228 'color' => 'optional string',
229 'disabled' => 'optional bool',
230 ));
231
232 $keywords = $value['keywords'];
233 foreach ($keywords as $keyword) {
234 if (!self::isValidPriorityKeyword($keyword)) {
235 throw new Exception(
236 pht(
237 'Key "%s" is not a valid priority keyword. Priority keywords '.
238 'must be 1-64 alphanumeric characters and cannot be '.
239 'exclusively digits. For example, "%s" or "%s" are '.
240 'reasonable choices.',
241 $keyword,
242 'low',
243 'critical'));
244 }
245
246 if (isset($all_keywords[$keyword])) {
247 throw new Exception(
248 pht(
249 'Two different task priorities ("%s" and "%s") have the same '.
250 'keyword ("%s"). Keywords must uniquely identify priorities.',
251 $value['name'],
252 $all_keywords[$keyword],
253 $keyword));
254 }
255
256 $all_keywords[$keyword] = $value['name'];
257 }
258 }
259 }
260
261}