Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15454761
D18111.id43613.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
19 KB
Referenced Files
None
Subscribers
None
D18111.id43613.diff
View Options
diff --git a/resources/sql/autopatches/20170614.taskstatus.sql b/resources/sql/autopatches/20170614.taskstatus.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20170614.taskstatus.sql
@@ -0,0 +1,4 @@
+/* Extend from 12 characters to 64. */
+
+ALTER TABLE {$NAMESPACE}_maniphest.maniphest_task
+ CHANGE status status VARCHAR(64) COLLATE utf8mb4_bin NOT NULL;
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -1503,6 +1503,7 @@
'ManiphestSearchConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestSearchConduitAPIMethod.php',
'ManiphestStatusConfigOptionType' => 'applications/maniphest/config/ManiphestStatusConfigOptionType.php',
'ManiphestStatusEmailCommand' => 'applications/maniphest/command/ManiphestStatusEmailCommand.php',
+ 'ManiphestStatusSearchConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestStatusSearchConduitAPIMethod.php',
'ManiphestSubpriorityController' => 'applications/maniphest/controller/ManiphestSubpriorityController.php',
'ManiphestSubtypesConfigOptionsType' => 'applications/maniphest/config/ManiphestSubtypesConfigOptionsType.php',
'ManiphestTask' => 'applications/maniphest/storage/ManiphestTask.php',
@@ -6598,6 +6599,7 @@
'ManiphestSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod',
'ManiphestStatusConfigOptionType' => 'PhabricatorConfigJSONOptionType',
'ManiphestStatusEmailCommand' => 'ManiphestEmailCommand',
+ 'ManiphestStatusSearchConduitAPIMethod' => 'ManiphestConduitAPIMethod',
'ManiphestSubpriorityController' => 'ManiphestController',
'ManiphestSubtypesConfigOptionsType' => 'PhabricatorConfigJSONOptionType',
'ManiphestTask' => array(
diff --git a/src/applications/maniphest/__tests__/ManiphestTaskTestCase.php b/src/applications/maniphest/__tests__/ManiphestTaskTestCase.php
--- a/src/applications/maniphest/__tests__/ManiphestTaskTestCase.php
+++ b/src/applications/maniphest/__tests__/ManiphestTaskTestCase.php
@@ -194,11 +194,14 @@
$dst,
$is_after);
+ $keyword_map = ManiphestTaskPriority::getTaskPriorityKeywordsMap();
+ $keyword = head($keyword_map[$pri]);
+
$xactions = array();
$xactions[] = id(new ManiphestTransaction())
->setTransactionType(ManiphestTaskPriorityTransaction::TRANSACTIONTYPE)
- ->setNewValue($pri);
+ ->setNewValue($keyword);
$xactions[] = id(new ManiphestTransaction())
->setTransactionType(ManiphestTaskSubpriorityTransaction::TRANSACTIONTYPE)
@@ -217,11 +220,14 @@
$target_priority,
$is_end);
+ $keyword_map = ManiphestTaskPriority::getTaskPriorityKeywordsMap();
+ $keyword = head($keyword_map[$pri]);
+
$xactions = array();
$xactions[] = id(new ManiphestTransaction())
->setTransactionType(ManiphestTaskPriorityTransaction::TRANSACTIONTYPE)
- ->setNewValue($pri);
+ ->setNewValue($keyword);
$xactions[] = id(new ManiphestTransaction())
->setTransactionType(ManiphestTaskSubpriorityTransaction::TRANSACTIONTYPE)
diff --git a/src/applications/maniphest/bulk/ManiphestTaskEditBulkJobType.php b/src/applications/maniphest/bulk/ManiphestTaskEditBulkJobType.php
--- a/src/applications/maniphest/bulk/ManiphestTaskEditBulkJobType.php
+++ b/src/applications/maniphest/bulk/ManiphestTaskEditBulkJobType.php
@@ -285,6 +285,11 @@
'=' => array_fuse($value),
));
break;
+ case ManiphestTaskPriorityTransaction::TRANSACTIONTYPE:
+ $keyword_map = ManiphestTaskPriority::getTaskPriorityKeywordsMap();
+ $keyword = head(idx($keyword_map, $value));
+ $xaction->setNewValue($keyword);
+ break;
default:
$xaction->setNewValue($value);
break;
diff --git a/src/applications/maniphest/command/ManiphestPriorityEmailCommand.php b/src/applications/maniphest/command/ManiphestPriorityEmailCommand.php
--- a/src/applications/maniphest/command/ManiphestPriorityEmailCommand.php
+++ b/src/applications/maniphest/command/ManiphestPriorityEmailCommand.php
@@ -49,18 +49,8 @@
array $argv) {
$xactions = array();
- $target = phutil_utf8_strtolower(head($argv));
- $priority = null;
-
- $keywords = ManiphestTaskPriority::getTaskPriorityKeywordsMap();
- foreach ($keywords as $key => $words) {
- foreach ($words as $word) {
- if ($word == $target) {
- $priority = $key;
- break;
- }
- }
- }
+ $keyword = phutil_utf8_strtolower(head($argv));
+ $priority = ManiphestTaskPriority::getTaskPriorityFromKeyword($keyword);
if ($priority === null) {
return array();
@@ -72,7 +62,7 @@
$xactions[] = $object->getApplicationTransactionTemplate()
->setTransactionType(ManiphestTaskPriorityTransaction::TRANSACTIONTYPE)
- ->setNewValue($priority);
+ ->setNewValue($keyword);
return $xactions;
}
diff --git a/src/applications/maniphest/conduit/ManiphestConduitAPIMethod.php b/src/applications/maniphest/conduit/ManiphestConduitAPIMethod.php
--- a/src/applications/maniphest/conduit/ManiphestConduitAPIMethod.php
+++ b/src/applications/maniphest/conduit/ManiphestConduitAPIMethod.php
@@ -99,7 +99,9 @@
throw id(new ConduitException('ERR-INVALID-PARAMETER'))
->setErrorDescription(pht('Priority set to invalid value.'));
}
- $changes[ManiphestTaskPriorityTransaction::TRANSACTIONTYPE] = $priority;
+ $keyword_map = ManiphestTaskPriority::getTaskPriorityKeywordsMap();
+ $keyword = head(idx($keyword_map, $priority));
+ $changes[ManiphestTaskPriorityTransaction::TRANSACTIONTYPE] = $keyword;
}
$owner_phid = $request->getValue('ownerPHID');
diff --git a/src/applications/maniphest/conduit/ManiphestQueryStatusesConduitAPIMethod.php b/src/applications/maniphest/conduit/ManiphestQueryStatusesConduitAPIMethod.php
--- a/src/applications/maniphest/conduit/ManiphestQueryStatusesConduitAPIMethod.php
+++ b/src/applications/maniphest/conduit/ManiphestQueryStatusesConduitAPIMethod.php
@@ -33,4 +33,14 @@
return $results;
}
+ public function getMethodStatus() {
+ return self::METHOD_STATUS_FROZEN;
+ }
+
+ public function getMethodStatusDescription() {
+ return pht(
+ 'This method is frozen and will eventually be deprecated. New code '.
+ 'should use "maniphest.status.search" instead.');
+ }
+
}
diff --git a/src/applications/maniphest/conduit/ManiphestStatusSearchConduitAPIMethod.php b/src/applications/maniphest/conduit/ManiphestStatusSearchConduitAPIMethod.php
new file mode 100644
--- /dev/null
+++ b/src/applications/maniphest/conduit/ManiphestStatusSearchConduitAPIMethod.php
@@ -0,0 +1,52 @@
+<?php
+
+final class ManiphestStatusSearchConduitAPIMethod
+ extends ManiphestConduitAPIMethod {
+
+ public function getAPIMethodName() {
+ return 'maniphest.status.search';
+ }
+
+ public function getMethodSummary() {
+ return pht('Read information about task statuses.');
+ }
+
+ public function getMethodDescription() {
+ return pht(
+ 'Returns information about the possible statuses for Maniphest '.
+ 'tasks.');
+ }
+
+ protected function defineParamTypes() {
+ return array();
+ }
+
+ protected function defineReturnType() {
+ return 'map<string, wild>';
+ }
+
+ public function getRequiredScope() {
+ return self::SCOPE_ALWAYS;
+ }
+
+ protected function execute(ConduitAPIRequest $request) {
+ $config = PhabricatorEnv::getEnvConfig('maniphest.statuses');
+ $results = array();
+ foreach ($config as $code => $status) {
+ $stripped_status = array(
+ 'name' => $status['name'],
+ 'value' => $code,
+ 'closed' => !empty($status['closed']),
+ );
+
+ if (isset($status['special'])) {
+ $stripped_status['special'] = $status['special'];
+ }
+
+ $results[] = $stripped_status;
+ }
+
+ return array('data' => $results);
+ }
+
+}
diff --git a/src/applications/maniphest/constants/ManiphestTaskPriority.php b/src/applications/maniphest/constants/ManiphestTaskPriority.php
--- a/src/applications/maniphest/constants/ManiphestTaskPriority.php
+++ b/src/applications/maniphest/constants/ManiphestTaskPriority.php
@@ -2,6 +2,8 @@
final class ManiphestTaskPriority extends ManiphestConstants {
+ const UNKNOWN_PRIORITY_KEYWORD = '!!unknown!!';
+
/**
* Get the priorities and their full descriptions.
*
@@ -105,6 +107,18 @@
return 'fa-arrow-right';
}
+ public static function getTaskPriorityFromKeyword($keyword) {
+ $map = self::getTaskPriorityKeywordsMap();
+
+ foreach ($map as $priority => $keywords) {
+ if (in_array($keyword, $keywords)) {
+ return $priority;
+ }
+ }
+
+ return null;
+ }
+
public static function isDisabledPriority($priority) {
$config = idx(self::getConfig(), $priority, array());
return idx($config, 'disabled', false);
@@ -116,6 +130,18 @@
return $config;
}
+ private static function isValidPriorityKeyword($keyword) {
+ if (!strlen($keyword) || strlen($keyword) > 64) {
+ return false;
+ }
+
+ // Alphanumeric, but not exclusively numeric
+ if (!preg_match('/^(?![0-9]*$)[a-zA-Z0-9]+$/', $keyword)) {
+ return false;
+ }
+ return true;
+ }
+
public static function validateConfiguration($config) {
if (!is_array($config)) {
throw new Exception(
@@ -147,9 +173,24 @@
'name' => 'string',
'short' => 'optional string',
'color' => 'optional string',
- 'keywords' => 'optional list<string>',
+ 'keywords' => 'list<string>',
'disabled' => 'optional bool',
));
+
+ $keywords = $value['keywords'];
+ foreach ($keywords as $keyword) {
+ if (!self::isValidPriorityKeyword($keyword)) {
+ throw new Exception(
+ pht(
+ 'Key "%s" is not a valid priority keyword. Priority keywords '.
+ 'must be 1-64 alphanumeric characters and cannot be '.
+ 'exclusively digits. For example, "%s" or "%s" are '.
+ 'reasonable choices.',
+ $keyword,
+ 'low',
+ 'critical'));
+ }
+ }
}
}
diff --git a/src/applications/maniphest/constants/ManiphestTaskStatus.php b/src/applications/maniphest/constants/ManiphestTaskStatus.php
--- a/src/applications/maniphest/constants/ManiphestTaskStatus.php
+++ b/src/applications/maniphest/constants/ManiphestTaskStatus.php
@@ -232,16 +232,17 @@
* @task validate
*/
public static function isValidStatusConstant($constant) {
- if (strlen($constant) > 12) {
+ if (!strlen($constant) || strlen($constant) > 64) {
return false;
}
- if (!preg_match('/^[a-z0-9]+\z/', $constant)) {
+
+ // Alphanumeric, but not exclusively numeric
+ if (!preg_match('/^(?![0-9]*$)[a-zA-Z0-9]+$/', $constant)) {
return false;
}
return true;
}
-
/**
* @task validate
*/
@@ -250,10 +251,9 @@
if (!self::isValidStatusConstant($key)) {
throw new Exception(
pht(
- 'Key "%s" is not a valid status constant. Status constants must '.
- 'be 1-12 characters long and contain only lowercase letters (a-z) '.
- 'and digits (0-9). For example, "%s" or "%s" are reasonable '.
- 'choices.',
+ 'Key "%s" is not a valid status constant. Status constants '.
+ 'must be 1-64 alphanumeric characters and cannot be exclusively '.
+ 'digits. For example, "%s" or "%s" are reasonable choices.',
$key,
'open',
'closed'));
diff --git a/src/applications/maniphest/constants/__tests__/ManiphestTaskStatusTestCase.php b/src/applications/maniphest/constants/__tests__/ManiphestTaskStatusTestCase.php
--- a/src/applications/maniphest/constants/__tests__/ManiphestTaskStatusTestCase.php
+++ b/src/applications/maniphest/constants/__tests__/ManiphestTaskStatusTestCase.php
@@ -10,10 +10,15 @@
'duplicate2' => true,
'' => false,
- 'longlonglonglong' => false,
+ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' =>
+ false,
'.' => false,
- 'ABCD' => false,
+ ' ' => false,
+ 'ABCD' => true,
'a b c ' => false,
+ '1' => false,
+ '111' => false,
+ '11a' => true,
);
foreach ($map as $input => $expect) {
diff --git a/src/applications/maniphest/controller/ManiphestSubpriorityController.php b/src/applications/maniphest/controller/ManiphestSubpriorityController.php
--- a/src/applications/maniphest/controller/ManiphestSubpriorityController.php
+++ b/src/applications/maniphest/controller/ManiphestSubpriorityController.php
@@ -40,11 +40,14 @@
$is_end = false);
}
+ $keyword_map = ManiphestTaskPriority::getTaskPriorityKeywordsMap();
+ $keyword = head(idx($keyword_map, $pri));
+
$xactions = array();
$xactions[] = id(new ManiphestTransaction())
->setTransactionType(ManiphestTaskPriorityTransaction::TRANSACTIONTYPE)
- ->setNewValue($pri);
+ ->setNewValue($keyword);
$xactions[] = id(new ManiphestTransaction())
->setTransactionType(ManiphestTaskSubpriorityTransaction::TRANSACTIONTYPE)
diff --git a/src/applications/maniphest/editor/ManiphestEditEngine.php b/src/applications/maniphest/editor/ManiphestEditEngine.php
--- a/src/applications/maniphest/editor/ManiphestEditEngine.php
+++ b/src/applications/maniphest/editor/ManiphestEditEngine.php
@@ -215,7 +215,7 @@
->setConduitTypeDescription(pht('New task priority constant.'))
->setTransactionType(ManiphestTaskPriorityTransaction::TRANSACTIONTYPE)
->setIsCopyable(true)
- ->setValue($object->getPriority())
+ ->setValue($object->getPriorityKeyword())
->setOptions($priority_map)
->setCommentActionLabel(pht('Change Priority')),
);
@@ -289,29 +289,29 @@
private function getTaskPriorityMap(ManiphestTask $task) {
$priority_map = ManiphestTaskPriority::getTaskPriorityMap();
+ $priority_keywords = ManiphestTaskPriority::getTaskPriorityKeywordsMap();
$current_priority = $task->getPriority();
-
- // If the current value isn't a legitimate one, put it in the dropdown
- // anyway so saving the form doesn't cause a side effects.
- if (idx($priority_map, $current_priority) === null) {
- $priority_map[$current_priority] = pht(
- '<Unknown: %s>',
- $current_priority);
- }
+ $results = array();
foreach ($priority_map as $priority => $priority_name) {
- // Always keep the current priority.
- if ($priority == $current_priority) {
+ $disabled = ManiphestTaskPriority::isDisabledPriority($priority);
+ if ($disabled && !($priority == $current_priority)) {
continue;
}
- if (ManiphestTaskPriority::isDisabledPriority($priority)) {
- unset($priority_map[$priority]);
- continue;
- }
+ $keyword = head(idx($priority_keywords, $priority));
+ $results[$keyword] = $priority_name;
+ }
+
+ // If the current value isn't a legitimate one, put it in the dropdown
+ // anyway so saving the form doesn't cause any side effects.
+ if (idx($priority_map, $current_priority) === null) {
+ $results[ManiphestTaskPriority::UNKNOWN_PRIORITY_KEYWORD] = pht(
+ '<Unknown: %s>',
+ $current_priority);
}
- return $priority_map;
+ return $results;
}
protected function newEditResponse(
diff --git a/src/applications/maniphest/herald/ManiphestTaskPriorityHeraldAction.php b/src/applications/maniphest/herald/ManiphestTaskPriorityHeraldAction.php
--- a/src/applications/maniphest/herald/ManiphestTaskPriorityHeraldAction.php
+++ b/src/applications/maniphest/herald/ManiphestTaskPriorityHeraldAction.php
@@ -39,12 +39,15 @@
return;
}
+ $keyword_map = ManiphestTaskPriority::getTaskPriorityKeywordsMap();
+ $keyword = head(idx($keyword_map, $priority));
+
$xaction = $adapter->newTransaction()
->setTransactionType(ManiphestTaskPriorityTransaction::TRANSACTIONTYPE)
- ->setNewValue($priority);
+ ->setNewValue($keyword);
$adapter->queueTransaction($xaction);
- $this->logEffect(self::DO_PRIORITY, $priority);
+ $this->logEffect(self::DO_PRIORITY, $keyword);
}
public function getHeraldActionStandardType() {
diff --git a/src/applications/maniphest/lipsum/PhabricatorManiphestTaskTestDataGenerator.php b/src/applications/maniphest/lipsum/PhabricatorManiphestTaskTestDataGenerator.php
--- a/src/applications/maniphest/lipsum/PhabricatorManiphestTaskTestDataGenerator.php
+++ b/src/applications/maniphest/lipsum/PhabricatorManiphestTaskTestDataGenerator.php
@@ -100,7 +100,10 @@
}
public function generateTaskPriority() {
- return array_rand(ManiphestTaskPriority::getTaskPriorityMap());
+ $pri = array_rand(ManiphestTaskPriority::getTaskPriorityMap());
+ $keyword_map = ManiphestTaskPriority::getTaskPriorityKeywordsMap();
+ $keyword = head(idx($keyword_map, $pri));
+ return $keyword;
}
public function generateTaskSubPriority() {
diff --git a/src/applications/maniphest/storage/ManiphestTask.php b/src/applications/maniphest/storage/ManiphestTask.php
--- a/src/applications/maniphest/storage/ManiphestTask.php
+++ b/src/applications/maniphest/storage/ManiphestTask.php
@@ -79,7 +79,7 @@
),
self::CONFIG_COLUMN_SCHEMA => array(
'ownerPHID' => 'phid?',
- 'status' => 'text12',
+ 'status' => 'text64',
'priority' => 'uint32',
'title' => 'sort',
'originalTitle' => 'text',
@@ -245,6 +245,14 @@
);
}
+ public function getPriorityKeyword() {
+ $priority = $this->getPriority();
+ $map = ManiphestTaskPriority::getTaskPriorityKeywordsMap();
+ $default = array(ManiphestTaskPriority::UNKNOWN_PRIORITY_KEYWORD);
+ $keywords = idx($map, $priority, $default);
+ return head($keywords);
+ }
+
private function comparePriorityTo(ManiphestTask $other) {
$upri = $this->getPriority();
$vpri = $other->getPriority();
diff --git a/src/applications/maniphest/xaction/ManiphestTaskPriorityTransaction.php b/src/applications/maniphest/xaction/ManiphestTaskPriorityTransaction.php
--- a/src/applications/maniphest/xaction/ManiphestTaskPriorityTransaction.php
+++ b/src/applications/maniphest/xaction/ManiphestTaskPriorityTransaction.php
@@ -12,6 +12,19 @@
return $object->getPriority();
}
+ public function generateNewValue($object, $value) {
+ // `$value` is supposed to be a keyword, but if the priority
+ // assigned to a task has been removed from the config,
+ // no such keyword will be available. Other edits to the task
+ // should still be allowed, even if the priority is no longer
+ // valid, so treat this as a no-op.
+ if ($value === ManiphestTaskPriority::UNKNOWN_PRIORITY_KEYWORD) {
+ return $object->getPriority();
+ }
+
+ return (string)ManiphestTaskPriority::getTaskPriorityFromKeyword($value);
+ }
+
public function applyInternalEffects($object, $value) {
$object->setPriority($value);
}
diff --git a/src/applications/project/controller/PhabricatorProjectMoveController.php b/src/applications/project/controller/PhabricatorProjectMoveController.php
--- a/src/applications/project/controller/PhabricatorProjectMoveController.php
+++ b/src/applications/project/controller/PhabricatorProjectMoveController.php
@@ -153,11 +153,14 @@
break;
}
+ $keyword_map = ManiphestTaskPriority::getTaskPriorityKeywordsMap();
+ $keyword = head(idx($keyword_map, $pri));
+
$xactions = array();
if ($pri !== null) {
$xactions[] = id(new ManiphestTransaction())
->setTransactionType(ManiphestTaskPriorityTransaction::TRANSACTIONTYPE)
- ->setNewValue($pri);
+ ->setNewValue($keyword);
$xactions[] = id(new ManiphestTransaction())
->setTransactionType(
ManiphestTaskSubpriorityTransaction::TRANSACTIONTYPE)
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Mar 30, 8:12 PM (5 d, 14 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7727480
Default Alt Text
D18111.id43613.diff (19 KB)
Attached To
Mode
D18111: Use keywords instead of ints to update task priority in ManiphestEditEngine
Attached
Detach File
Event Timeline
Log In to Comment