Page MenuHomePhabricator

D14404.id.diff
No OneTemporary

D14404.id.diff

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
@@ -156,6 +156,7 @@
'AphrontPageView' => 'view/page/AphrontPageView.php',
'AphrontPlainTextResponse' => 'aphront/response/AphrontPlainTextResponse.php',
'AphrontProgressBarView' => 'view/widget/bars/AphrontProgressBarView.php',
+ 'AphrontProjectListHTTPParameterType' => 'aphront/httpparametertype/AphrontProjectListHTTPParameterType.php',
'AphrontProxyResponse' => 'aphront/response/AphrontProxyResponse.php',
'AphrontRedirectResponse' => 'aphront/response/AphrontRedirectResponse.php',
'AphrontRedirectResponseTestCase' => 'aphront/response/__tests__/AphrontRedirectResponseTestCase.php',
@@ -179,6 +180,7 @@
'AphrontTokenizerTemplateView' => 'view/control/AphrontTokenizerTemplateView.php',
'AphrontTypeaheadTemplateView' => 'view/control/AphrontTypeaheadTemplateView.php',
'AphrontUnhandledExceptionResponse' => 'aphront/response/AphrontUnhandledExceptionResponse.php',
+ 'AphrontUserListHTTPParameterType' => 'aphront/httpparametertype/AphrontUserListHTTPParameterType.php',
'AphrontView' => 'view/AphrontView.php',
'AphrontWebpageResponse' => 'aphront/response/AphrontWebpageResponse.php',
'ArcanistConduitAPIMethod' => 'applications/arcanist/conduit/ArcanistConduitAPIMethod.php',
@@ -2549,6 +2551,7 @@
'PhabricatorPHID' => 'applications/phid/storage/PhabricatorPHID.php',
'PhabricatorPHIDConstants' => 'applications/phid/PhabricatorPHIDConstants.php',
'PhabricatorPHIDInterface' => 'applications/phid/interface/PhabricatorPHIDInterface.php',
+ 'PhabricatorPHIDResolver' => 'applications/phid/resolver/PhabricatorPHIDResolver.php',
'PhabricatorPHIDType' => 'applications/phid/type/PhabricatorPHIDType.php',
'PhabricatorPHIDTypeTestCase' => 'applications/phid/type/__tests__/PhabricatorPHIDTypeTestCase.php',
'PhabricatorPHPASTApplication' => 'applications/phpast/application/PhabricatorPHPASTApplication.php',
@@ -2738,6 +2741,7 @@
'PhabricatorProjectObjectHasProjectEdgeType' => 'applications/project/edge/PhabricatorProjectObjectHasProjectEdgeType.php',
'PhabricatorProjectOrUserDatasource' => 'applications/project/typeahead/PhabricatorProjectOrUserDatasource.php',
'PhabricatorProjectOrUserFunctionDatasource' => 'applications/project/typeahead/PhabricatorProjectOrUserFunctionDatasource.php',
+ 'PhabricatorProjectPHIDResolver' => 'applications/phid/resolver/PhabricatorProjectPHIDResolver.php',
'PhabricatorProjectProfileController' => 'applications/project/controller/PhabricatorProjectProfileController.php',
'PhabricatorProjectProjectHasMemberEdgeType' => 'applications/project/edge/PhabricatorProjectProjectHasMemberEdgeType.php',
'PhabricatorProjectProjectHasObjectEdgeType' => 'applications/project/edge/PhabricatorProjectProjectHasObjectEdgeType.php',
@@ -2760,6 +2764,7 @@
'PhabricatorProjectUserFunctionDatasource' => 'applications/project/typeahead/PhabricatorProjectUserFunctionDatasource.php',
'PhabricatorProjectViewController' => 'applications/project/controller/PhabricatorProjectViewController.php',
'PhabricatorProjectWatchController' => 'applications/project/controller/PhabricatorProjectWatchController.php',
+ 'PhabricatorProjectsEditField' => 'applications/transactions/editfield/PhabricatorProjectsEditField.php',
'PhabricatorProjectsPolicyRule' => 'applications/policy/rule/PhabricatorProjectsPolicyRule.php',
'PhabricatorProtocolAdapter' => 'infrastructure/daemon/bot/adapter/PhabricatorProtocolAdapter.php',
'PhabricatorPygmentSetupCheck' => 'applications/config/check/PhabricatorPygmentSetupCheck.php',
@@ -3040,6 +3045,7 @@
'PhabricatorStreamingProtocolAdapter' => 'infrastructure/daemon/bot/adapter/PhabricatorStreamingProtocolAdapter.php',
'PhabricatorSubscribableInterface' => 'applications/subscriptions/interface/PhabricatorSubscribableInterface.php',
'PhabricatorSubscribedToObjectEdgeType' => 'applications/transactions/edges/PhabricatorSubscribedToObjectEdgeType.php',
+ 'PhabricatorSubscribersEditField' => 'applications/transactions/editfield/PhabricatorSubscribersEditField.php',
'PhabricatorSubscribersQuery' => 'applications/subscriptions/query/PhabricatorSubscribersQuery.php',
'PhabricatorSubscriptionTriggerClock' => 'infrastructure/daemon/workers/clock/PhabricatorSubscriptionTriggerClock.php',
'PhabricatorSubscriptionsAddSelfHeraldAction' => 'applications/subscriptions/herald/PhabricatorSubscriptionsAddSelfHeraldAction.php',
@@ -3154,6 +3160,7 @@
'PhabricatorUserEmailTestCase' => 'applications/people/storage/__tests__/PhabricatorUserEmailTestCase.php',
'PhabricatorUserLog' => 'applications/people/storage/PhabricatorUserLog.php',
'PhabricatorUserLogView' => 'applications/people/view/PhabricatorUserLogView.php',
+ 'PhabricatorUserPHIDResolver' => 'applications/phid/resolver/PhabricatorUserPHIDResolver.php',
'PhabricatorUserPreferences' => 'applications/settings/storage/PhabricatorUserPreferences.php',
'PhabricatorUserProfile' => 'applications/people/storage/PhabricatorUserProfile.php',
'PhabricatorUserProfileEditor' => 'applications/people/editor/PhabricatorUserProfileEditor.php',
@@ -3166,6 +3173,7 @@
'PhabricatorUserTestCase' => 'applications/people/storage/__tests__/PhabricatorUserTestCase.php',
'PhabricatorUserTitleField' => 'applications/people/customfield/PhabricatorUserTitleField.php',
'PhabricatorUserTransaction' => 'applications/people/storage/PhabricatorUserTransaction.php',
+ 'PhabricatorUsersEditField' => 'applications/transactions/editfield/PhabricatorUsersEditField.php',
'PhabricatorUsersPolicyRule' => 'applications/policy/rule/PhabricatorUsersPolicyRule.php',
'PhabricatorUsersSearchField' => 'applications/people/searchfield/PhabricatorUsersSearchField.php',
'PhabricatorVCSResponse' => 'applications/repository/response/PhabricatorVCSResponse.php',
@@ -3895,6 +3903,7 @@
'AphrontPageView' => 'AphrontView',
'AphrontPlainTextResponse' => 'AphrontResponse',
'AphrontProgressBarView' => 'AphrontBarView',
+ 'AphrontProjectListHTTPParameterType' => 'AphrontHTTPParameterType',
'AphrontProxyResponse' => array(
'AphrontResponse',
'AphrontResponseProducerInterface',
@@ -3920,6 +3929,7 @@
'AphrontTokenizerTemplateView' => 'AphrontView',
'AphrontTypeaheadTemplateView' => 'AphrontView',
'AphrontUnhandledExceptionResponse' => 'AphrontStandaloneHTMLResponse',
+ 'AphrontUserListHTTPParameterType' => 'AphrontHTTPParameterType',
'AphrontView' => array(
'Phobject',
'PhutilSafeHTMLProducerInterface',
@@ -6654,6 +6664,7 @@
'PhabricatorPHDConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorPHID' => 'Phobject',
'PhabricatorPHIDConstants' => 'Phobject',
+ 'PhabricatorPHIDResolver' => 'Phobject',
'PhabricatorPHIDType' => 'Phobject',
'PhabricatorPHIDTypeTestCase' => 'PhutilTestCase',
'PhabricatorPHPASTApplication' => 'PhabricatorApplication',
@@ -6891,6 +6902,7 @@
'PhabricatorProjectObjectHasProjectEdgeType' => 'PhabricatorEdgeType',
'PhabricatorProjectOrUserDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
'PhabricatorProjectOrUserFunctionDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
+ 'PhabricatorProjectPHIDResolver' => 'PhabricatorPHIDResolver',
'PhabricatorProjectProfileController' => 'PhabricatorProjectController',
'PhabricatorProjectProjectHasMemberEdgeType' => 'PhabricatorEdgeType',
'PhabricatorProjectProjectHasObjectEdgeType' => 'PhabricatorEdgeType',
@@ -6916,6 +6928,7 @@
'PhabricatorProjectUserFunctionDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
'PhabricatorProjectViewController' => 'PhabricatorProjectController',
'PhabricatorProjectWatchController' => 'PhabricatorProjectController',
+ 'PhabricatorProjectsEditField' => 'PhabricatorTokenizerEditField',
'PhabricatorProjectsPolicyRule' => 'PhabricatorPolicyRule',
'PhabricatorProtocolAdapter' => 'Phobject',
'PhabricatorPygmentSetupCheck' => 'PhabricatorSetupCheck',
@@ -7252,6 +7265,7 @@
'PhabricatorStorageSetupCheck' => 'PhabricatorSetupCheck',
'PhabricatorStreamingProtocolAdapter' => 'PhabricatorProtocolAdapter',
'PhabricatorSubscribedToObjectEdgeType' => 'PhabricatorEdgeType',
+ 'PhabricatorSubscribersEditField' => 'PhabricatorTokenizerEditField',
'PhabricatorSubscribersQuery' => 'PhabricatorQuery',
'PhabricatorSubscriptionTriggerClock' => 'PhabricatorTriggerClock',
'PhabricatorSubscriptionsAddSelfHeraldAction' => 'PhabricatorSubscriptionsHeraldAction',
@@ -7386,6 +7400,7 @@
'PhabricatorPolicyInterface',
),
'PhabricatorUserLogView' => 'AphrontView',
+ 'PhabricatorUserPHIDResolver' => 'PhabricatorPHIDResolver',
'PhabricatorUserPreferences' => 'PhabricatorUserDAO',
'PhabricatorUserProfile' => 'PhabricatorUserDAO',
'PhabricatorUserProfileEditor' => 'PhabricatorApplicationTransactionEditor',
@@ -7398,6 +7413,7 @@
'PhabricatorUserTestCase' => 'PhabricatorTestCase',
'PhabricatorUserTitleField' => 'PhabricatorUserCustomField',
'PhabricatorUserTransaction' => 'PhabricatorApplicationTransaction',
+ 'PhabricatorUsersEditField' => 'PhabricatorTokenizerEditField',
'PhabricatorUsersPolicyRule' => 'PhabricatorPolicyRule',
'PhabricatorUsersSearchField' => 'PhabricatorSearchTokenizerField',
'PhabricatorVCSResponse' => 'AphrontResponse',
diff --git a/src/aphront/httpparametertype/AphrontProjectListHTTPParameterType.php b/src/aphront/httpparametertype/AphrontProjectListHTTPParameterType.php
new file mode 100644
--- /dev/null
+++ b/src/aphront/httpparametertype/AphrontProjectListHTTPParameterType.php
@@ -0,0 +1,42 @@
+<?php
+
+final class AphrontProjectListHTTPParameterType
+ extends AphrontHTTPParameterType {
+
+ protected function getParameterValue(AphrontRequest $request, $key) {
+ $type = new AphrontStringListHTTPParameterType();
+ $list = $this->getValueWithType($type, $request, $key);
+
+ return id(new PhabricatorProjectPHIDResolver())
+ ->setViewer($this->getViewer())
+ ->resolvePHIDs($list);
+ }
+
+ protected function getParameterTypeName() {
+ return 'list<project>';
+ }
+
+ protected function getParameterFormatDescriptions() {
+ return array(
+ pht('Comma-separated list of project PHIDs.'),
+ pht('List of project PHIDs, as array.'),
+ pht('Comma-separated list of project hashtags.'),
+ pht('List of project hashtags, as array.'),
+ pht('Mixture of hashtags and PHIDs.'),
+ );
+ }
+
+ protected function getParameterExamples() {
+ return array(
+ 'v=PHID-PROJ-1111',
+ 'v=PHID-PROJ-1111,PHID-PROJ-2222',
+ 'v=hashtag',
+ 'v=frontend,backend',
+ 'v[]=PHID-PROJ-1111&v[]=PHID-PROJ-2222',
+ 'v[]=frontend&v[]=backend',
+ 'v=PHID-PROJ-1111,frontend',
+ 'v[]=PHID-PROJ-1111&v[]=backend',
+ );
+ }
+
+}
diff --git a/src/aphront/httpparametertype/AphrontUserListHTTPParameterType.php b/src/aphront/httpparametertype/AphrontUserListHTTPParameterType.php
new file mode 100644
--- /dev/null
+++ b/src/aphront/httpparametertype/AphrontUserListHTTPParameterType.php
@@ -0,0 +1,42 @@
+<?php
+
+final class AphrontUserListHTTPParameterType
+ extends AphrontHTTPParameterType {
+
+ protected function getParameterValue(AphrontRequest $request, $key) {
+ $type = new AphrontStringListHTTPParameterType();
+ $list = $this->getValueWithType($type, $request, $key);
+
+ return id(new PhabricatorUserPHIDResolver())
+ ->setViewer($this->getViewer())
+ ->resolvePHIDs($list);
+ }
+
+ protected function getParameterTypeName() {
+ return 'list<user>';
+ }
+
+ protected function getParameterFormatDescriptions() {
+ return array(
+ pht('Comma-separated list of user PHIDs.'),
+ pht('List of user PHIDs, as array.'),
+ pht('Comma-separated list of usernames.'),
+ pht('List of usernames, as array.'),
+ pht('Mixture of usernames and PHIDs.'),
+ );
+ }
+
+ protected function getParameterExamples() {
+ return array(
+ 'v=PHID-USER-1111',
+ 'v=PHID-USER-1111,PHID-USER-2222',
+ 'v=username',
+ 'v=alincoln,htaft',
+ 'v[]=PHID-USER-1111&v[]=PHID-USER-2222',
+ 'v[]=htaft&v[]=alincoln',
+ 'v=PHID-USER-1111,alincoln',
+ 'v[]=PHID-USER-1111&v[]=htaft',
+ );
+ }
+
+}
diff --git a/src/applications/phid/resolver/PhabricatorPHIDResolver.php b/src/applications/phid/resolver/PhabricatorPHIDResolver.php
new file mode 100644
--- /dev/null
+++ b/src/applications/phid/resolver/PhabricatorPHIDResolver.php
@@ -0,0 +1,46 @@
+<?php
+
+/**
+ * Resolve a list of identifiers into PHIDs.
+ *
+ * This class simplifies the process of convering a list of mixed token types
+ * (like some PHIDs and some usernames) into a list of just PHIDs.
+ */
+abstract class PhabricatorPHIDResolver extends Phobject {
+
+ private $viewer;
+
+ final public function setViewer(PhabricatorUser $viewer) {
+ $this->viewer = $viewer;
+ return $this;
+ }
+
+ final public function getViewer() {
+ return $this->viewer;
+ }
+
+ final public function resolvePHIDs(array $phids) {
+ $type_unknown = PhabricatorPHIDConstants::PHID_TYPE_UNKNOWN;
+
+ $names = array();
+ foreach ($phids as $key => $phid) {
+ if (phid_get_type($phid) == $type_unknown) {
+ $names[$key] = $phid;
+ }
+ }
+
+ if ($names) {
+ $map = $this->getResolutionMap($names);
+ foreach ($names as $key => $name) {
+ if (isset($map[$name])) {
+ $phids[$key] = $map[$name];
+ }
+ }
+ }
+
+ return $phids;
+ }
+
+ abstract protected function getResolutionMap(array $names);
+
+}
diff --git a/src/applications/phid/resolver/PhabricatorProjectPHIDResolver.php b/src/applications/phid/resolver/PhabricatorProjectPHIDResolver.php
new file mode 100644
--- /dev/null
+++ b/src/applications/phid/resolver/PhabricatorProjectPHIDResolver.php
@@ -0,0 +1,28 @@
+<?php
+
+final class PhabricatorProjectPHIDResolver
+ extends PhabricatorPHIDResolver {
+
+ protected function getResolutionMap(array $names) {
+ // This is a little awkward but we want to pick up the normalization
+ // rules from the PHIDType. This flow could perhaps be made cleaner.
+
+ foreach ($names as $key => $name) {
+ $names[$key] = '#'.$name;
+ }
+
+ $query = id(new PhabricatorObjectQuery())
+ ->setViewer($this->getViewer());
+
+ $projects = id(new PhabricatorProjectProjectPHIDType())
+ ->loadNamedObjects($query, $names);
+
+ $results = array();
+ foreach ($projects as $hashtag => $project) {
+ $results[substr($hashtag, 1)] = $project->getPHID();
+ }
+
+ return $results;
+ }
+
+}
diff --git a/src/applications/phid/resolver/PhabricatorUserPHIDResolver.php b/src/applications/phid/resolver/PhabricatorUserPHIDResolver.php
new file mode 100644
--- /dev/null
+++ b/src/applications/phid/resolver/PhabricatorUserPHIDResolver.php
@@ -0,0 +1,27 @@
+<?php
+
+final class PhabricatorUserPHIDResolver
+ extends PhabricatorPHIDResolver {
+
+ protected function getResolutionMap(array $names) {
+ // Pick up the normalization and case rules from the PHID type query.
+
+ foreach ($names as $key => $name) {
+ $names[$key] = '@'.$name;
+ }
+
+ $query = id(new PhabricatorObjectQuery())
+ ->setViewer($this->getViewer());
+
+ $users = id(new PhabricatorPeopleUserPHIDType())
+ ->loadNamedObjects($query, $names);
+
+ $results = array();
+ foreach ($users as $at_username => $user) {
+ $results[substr($at_username, 1)] = $user->getPHID();
+ }
+
+ return $results;
+ }
+
+}
diff --git a/src/applications/transactions/editengine/PhabricatorApplicationEditEngine.php b/src/applications/transactions/editengine/PhabricatorApplicationEditEngine.php
--- a/src/applications/transactions/editengine/PhabricatorApplicationEditEngine.php
+++ b/src/applications/transactions/editengine/PhabricatorApplicationEditEngine.php
@@ -146,14 +146,11 @@
$project_phids = array();
}
- $edge_field = id(new PhabricatorDatasourceEditField())
+ $edge_field = id(new PhabricatorProjectsEditField())
->setKey('projectPHIDs')
->setLabel(pht('Projects'))
->setEditTypeKey('projects')
- ->setDescription(
- pht(
- 'Add or remove associated projects.'))
- ->setDatasource(new PhabricatorProjectDatasource())
+ ->setDescription(pht('Add or remove associated projects.'))
->setAliases(array('project', 'projects'))
->setTransactionType($edge_type)
->setMetadataValue('edge:type', $project_edge_type)
@@ -175,12 +172,11 @@
$sub_phids = array();
}
- $subscribers_field = id(new PhabricatorDatasourceEditField())
+ $subscribers_field = id(new PhabricatorSubscribersEditField())
->setKey('subscriberPHIDs')
->setLabel(pht('Subscribers'))
->setEditTypeKey('subscribers')
->setDescription(pht('Manage subscribers.'))
- ->setDatasource(new PhabricatorMetaMTAMailableDatasource())
->setAliases(array('subscriber', 'subscribers'))
->setTransactionType($subscribers_type)
->setValue($sub_phids);
diff --git a/src/applications/transactions/editfield/PhabricatorProjectsEditField.php b/src/applications/transactions/editfield/PhabricatorProjectsEditField.php
new file mode 100644
--- /dev/null
+++ b/src/applications/transactions/editfield/PhabricatorProjectsEditField.php
@@ -0,0 +1,14 @@
+<?php
+
+final class PhabricatorProjectsEditField
+ extends PhabricatorTokenizerEditField {
+
+ protected function newDatasource() {
+ return new PhabricatorProjectDatasource();
+ }
+
+ protected function newHTTPParameterType() {
+ return new AphrontProjectListHTTPParameterType();
+ }
+
+}
diff --git a/src/applications/transactions/editfield/PhabricatorSubscribersEditField.php b/src/applications/transactions/editfield/PhabricatorSubscribersEditField.php
new file mode 100644
--- /dev/null
+++ b/src/applications/transactions/editfield/PhabricatorSubscribersEditField.php
@@ -0,0 +1,16 @@
+<?php
+
+final class PhabricatorSubscribersEditField
+ extends PhabricatorTokenizerEditField {
+
+ protected function newDatasource() {
+ return new PhabricatorMetaMTAMailableDatasource();
+ }
+
+ protected function newHTTPParameterType() {
+ // TODO: Implement a more expansive "Mailable" parameter type which
+ // accepts users or projects.
+ return new AphrontUserListHTTPParameterType();
+ }
+
+}
diff --git a/src/applications/transactions/editfield/PhabricatorUsersEditField.php b/src/applications/transactions/editfield/PhabricatorUsersEditField.php
new file mode 100644
--- /dev/null
+++ b/src/applications/transactions/editfield/PhabricatorUsersEditField.php
@@ -0,0 +1,14 @@
+<?php
+
+final class PhabricatorUsersEditField
+ extends PhabricatorTokenizerEditField {
+
+ protected function newDatasource() {
+ return new PhabricatorPeopleDatasource();
+ }
+
+ protected function newHTTPParameterType() {
+ return new AphrontUserListHTTPParameterType();
+ }
+
+}

File Metadata

Mime Type
text/plain
Expires
Sun, Mar 23, 9:53 PM (3 w, 4 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7719088
Default Alt Text
D14404.id.diff (18 KB)

Event Timeline