diff --git a/resources/celerity/map.php b/resources/celerity/map.php index 6f7a7a4568..9f199b2ad2 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -114,7 +114,7 @@ return array( 'rsrc/css/diviner/diviner-shared.css' => '38813222', 'rsrc/css/font/font-awesome.css' => 'e2e712fe', 'rsrc/css/font/font-lato.css' => '5f05d817', - 'rsrc/css/font/font-slabo.css' => '7a85ea13', + 'rsrc/css/font/font-slabo.css' => '1f520937', 'rsrc/css/font/phui-font-icon-base.css' => '3dad2ae3', 'rsrc/css/layout/phabricator-filetree-view.css' => 'fccf9f82', 'rsrc/css/layout/phabricator-hovercard-view.css' => '0d665853', @@ -370,10 +370,10 @@ return array( 'rsrc/js/application/doorkeeper/behavior-doorkeeper-tag.js' => 'e5822781', 'rsrc/js/application/files/behavior-icon-composer.js' => '8ef9ab58', 'rsrc/js/application/files/behavior-launch-icon-composer.js' => '48086888', - 'rsrc/js/application/herald/HeraldRuleEditor.js' => '271ffdd7', + 'rsrc/js/application/herald/HeraldRuleEditor.js' => 'b2cae298', 'rsrc/js/application/herald/PathTypeahead.js' => 'f7fc67ec', 'rsrc/js/application/herald/herald-rule-editor.js' => '7ebaeed3', - 'rsrc/js/application/maniphest/behavior-batch-editor.js' => 'f5d1233b', + 'rsrc/js/application/maniphest/behavior-batch-editor.js' => '782ab6e7', 'rsrc/js/application/maniphest/behavior-batch-selector.js' => '7b98d7c5', 'rsrc/js/application/maniphest/behavior-line-chart.js' => '88f0c5b3', 'rsrc/js/application/maniphest/behavior-list-edit.js' => 'a9f88de2', @@ -390,7 +390,7 @@ return array( 'rsrc/js/application/phortune/behavior-stripe-payment-form.js' => '3f5d6dbf', 'rsrc/js/application/phortune/behavior-test-payment-form.js' => 'fc91ab6c', 'rsrc/js/application/phortune/phortune-credit-card-form.js' => '2290aeef', - 'rsrc/js/application/policy/behavior-policy-control.js' => '9a340b3d', + 'rsrc/js/application/policy/behavior-policy-control.js' => '7d470398', 'rsrc/js/application/policy/behavior-policy-rule-editor.js' => '5e9f347c', 'rsrc/js/application/ponder/behavior-votebox.js' => '4e9b766b', 'rsrc/js/application/projects/behavior-project-boards.js' => 'ba4fa35c', @@ -522,11 +522,11 @@ return array( 'diviner-shared-css' => '38813222', 'font-fontawesome' => 'e2e712fe', 'font-lato' => '5f05d817', - 'font-slabo' => '7a85ea13', + 'font-slabo' => '1f520937', 'global-drag-and-drop-css' => '697324ad', 'harbormaster-css' => '49d64eb4', 'herald-css' => '826075fa', - 'herald-rule-editor' => '271ffdd7', + 'herald-rule-editor' => 'b2cae298', 'herald-test-css' => '778b008e', 'inline-comment-summary-css' => '51efda3a', 'javelin-aphlict' => '5359e785', @@ -585,7 +585,7 @@ return array( 'javelin-behavior-lightbox-attachments' => 'f8ba29d7', 'javelin-behavior-line-chart' => '88f0c5b3', 'javelin-behavior-load-blame' => '42126667', - 'javelin-behavior-maniphest-batch-editor' => 'f5d1233b', + 'javelin-behavior-maniphest-batch-editor' => '782ab6e7', 'javelin-behavior-maniphest-batch-selector' => '7b98d7c5', 'javelin-behavior-maniphest-list-editor' => 'a9f88de2', 'javelin-behavior-maniphest-subpriority-editor' => '84845b5b', @@ -622,7 +622,7 @@ return array( 'javelin-behavior-pholio-mock-view' => 'fbe497e7', 'javelin-behavior-phui-dropdown-menu' => '54733475', 'javelin-behavior-phui-object-box-tabs' => '2bfa2836', - 'javelin-behavior-policy-control' => '9a340b3d', + 'javelin-behavior-policy-control' => '7d470398', 'javelin-behavior-policy-rule-editor' => '5e9f347c', 'javelin-behavior-ponder-votebox' => '4e9b766b', 'javelin-behavior-project-boards' => 'ba4fa35c', @@ -973,6 +973,9 @@ return array( 'javelin-dom', 'javelin-reactor-dom', ), + '1f520937' => array( + 'phui-fontkit-css', + ), '2035b9cb' => array( 'javelin-behavior', 'javelin-dom', @@ -1010,15 +1013,6 @@ return array( 'phabricator-drag-and-drop-file-upload', 'phabricator-draggable-list', ), - '271ffdd7' => array( - 'multirow-row-manager', - 'javelin-install', - 'javelin-util', - 'javelin-dom', - 'javelin-stratcom', - 'javelin-json', - 'phabricator-prefab', - ), '2818f5ce' => array( 'javelin-install', 'javelin-util', @@ -1414,6 +1408,14 @@ return array( 'javelin-util', 'phabricator-busy', ), + '782ab6e7' => array( + 'javelin-behavior', + 'javelin-dom', + 'javelin-util', + 'phabricator-prefab', + 'multirow-row-manager', + 'javelin-json', + ), '7927a7d3' => array( 'javelin-behavior', 'javelin-quicksand', @@ -1422,9 +1424,6 @@ return array( 'owners-path-editor', 'javelin-behavior', ), - '7a85ea13' => array( - 'phui-fontkit-css', - ), '7b98d7c5' => array( 'javelin-behavior', 'javelin-dom', @@ -1437,6 +1436,15 @@ return array( 'javelin-request', 'javelin-router', ), + '7d470398' => array( + 'javelin-behavior', + 'javelin-dom', + 'javelin-util', + 'phuix-dropdown-menu', + 'phuix-action-list-view', + 'phuix-action-view', + 'javelin-workflow', + ), '7e41274a' => array( 'javelin-install', ), @@ -1582,15 +1590,6 @@ return array( 'javelin-dom', 'javelin-reactor-dom', ), - '9a340b3d' => array( - 'javelin-behavior', - 'javelin-dom', - 'javelin-util', - 'phuix-dropdown-menu', - 'phuix-action-list-view', - 'phuix-action-view', - 'javelin-workflow', - ), '9f36c42d' => array( 'javelin-behavior', 'javelin-stratcom', @@ -1707,6 +1706,15 @@ return array( 'javelin-uri', 'javelin-request', ), + 'b2cae298' => array( + 'multirow-row-manager', + 'javelin-install', + 'javelin-util', + 'javelin-dom', + 'javelin-stratcom', + 'javelin-json', + 'phabricator-prefab', + ), 'b3a4b884' => array( 'javelin-behavior', 'phabricator-prefab', @@ -1970,14 +1978,6 @@ return array( 'javelin-request', 'phabricator-keyboard-shortcut', ), - 'f5d1233b' => array( - 'javelin-behavior', - 'javelin-dom', - 'javelin-util', - 'phabricator-prefab', - 'multirow-row-manager', - 'javelin-json', - ), 'f6555212' => array( 'javelin-install', 'javelin-reactornode', diff --git a/resources/sql/autopatches/20150609.spaces.1.pholio.sql b/resources/sql/autopatches/20150609.spaces.1.pholio.sql new file mode 100644 index 0000000000..903afb86da --- /dev/null +++ b/resources/sql/autopatches/20150609.spaces.1.pholio.sql @@ -0,0 +1,2 @@ +ALTER TABLE {$NAMESPACE}_pholio.pholio_mock + ADD spacePHID VARBINARY(64); diff --git a/resources/sql/autopatches/20150609.spaces.2.maniphest.sql b/resources/sql/autopatches/20150609.spaces.2.maniphest.sql new file mode 100644 index 0000000000..d46b5e5908 --- /dev/null +++ b/resources/sql/autopatches/20150609.spaces.2.maniphest.sql @@ -0,0 +1,2 @@ +ALTER TABLE {$NAMESPACE}_maniphest.maniphest_task + ADD spacePHID VARBINARY(64); diff --git a/resources/sql/autopatches/20150610.spaces.1.desc.sql b/resources/sql/autopatches/20150610.spaces.1.desc.sql new file mode 100644 index 0000000000..c62cd8aece --- /dev/null +++ b/resources/sql/autopatches/20150610.spaces.1.desc.sql @@ -0,0 +1,2 @@ +ALTER TABLE {$NAMESPACE}_spaces.spaces_namespace + ADD description LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL; diff --git a/resources/sql/autopatches/20150610.spaces.2.edge.sql b/resources/sql/autopatches/20150610.spaces.2.edge.sql new file mode 100644 index 0000000000..bc72ed2225 --- /dev/null +++ b/resources/sql/autopatches/20150610.spaces.2.edge.sql @@ -0,0 +1,16 @@ +CREATE TABLE {$NAMESPACE}_spaces.edge ( + src VARBINARY(64) NOT NULL, + type INT UNSIGNED NOT NULL, + dst VARBINARY(64) NOT NULL, + dateCreated INT UNSIGNED NOT NULL, + seq INT UNSIGNED NOT NULL, + dataID INT UNSIGNED, + PRIMARY KEY (src, type, dst), + KEY `src` (src, type, dateCreated, seq), + UNIQUE KEY `key_dst` (dst, type, src) +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; + +CREATE TABLE {$NAMESPACE}_spaces.edgedata ( + id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, + data LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT} +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20150610.spaces.3.archive.sql b/resources/sql/autopatches/20150610.spaces.3.archive.sql new file mode 100644 index 0000000000..8dd55959a3 --- /dev/null +++ b/resources/sql/autopatches/20150610.spaces.3.archive.sql @@ -0,0 +1,2 @@ +ALTER TABLE {$NAMESPACE}_spaces.spaces_namespace + ADD isArchived BOOL NOT NULL; diff --git a/resources/sql/autopatches/20150611.spaces.1.mailxaction.sql b/resources/sql/autopatches/20150611.spaces.1.mailxaction.sql new file mode 100644 index 0000000000..fe519f48ab --- /dev/null +++ b/resources/sql/autopatches/20150611.spaces.1.mailxaction.sql @@ -0,0 +1,19 @@ +CREATE TABLE {$NAMESPACE}_metamta.metamta_applicationemailtransaction ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + phid VARBINARY(64) NOT NULL, + authorPHID VARBINARY(64) NOT NULL, + objectPHID VARBINARY(64) NOT NULL, + viewPolicy VARBINARY(64) NOT NULL, + editPolicy VARBINARY(64) NOT NULL, + commentPHID VARBINARY(64) DEFAULT NULL, + commentVersion INT UNSIGNED NOT NULL, + transactionType VARCHAR(32) COLLATE {$COLLATE_TEXT} NOT NULL, + oldValue LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL, + newValue LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL, + contentSource LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL, + metadata LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL, + dateCreated INT UNSIGNED NOT NULL, + dateModified INT UNSIGNED NOT NULL, + UNIQUE KEY `key_phid` (`phid`), + KEY `key_object` (`objectPHID`) +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20150611.spaces.2.appmail.sql b/resources/sql/autopatches/20150611.spaces.2.appmail.sql new file mode 100644 index 0000000000..c846e4338f --- /dev/null +++ b/resources/sql/autopatches/20150611.spaces.2.appmail.sql @@ -0,0 +1,2 @@ +ALTER TABLE {$NAMESPACE}_metamta.metamta_applicationemail + ADD spacePHID VARBINARY(64); diff --git a/resources/sql/patches/20131121.repocredentials.2.mig.php b/resources/sql/patches/20131121.repocredentials.2.mig.php index 3953b8416f..3da813408f 100644 --- a/resources/sql/patches/20131121.repocredentials.2.mig.php +++ b/resources/sql/patches/20131121.repocredentials.2.mig.php @@ -26,7 +26,7 @@ foreach (new LiskMigrationIterator($table) as $repository) { if ($proto == 'http' || $proto == 'https' || $proto == 'svn') { $username = $repository->getDetail('http-login'); $secret = $repository->getDetail('http-pass'); - $type = PassphraseCredentialTypePassword::CREDENTIAL_TYPE; + $type = PassphrasePasswordCredentialType::CREDENTIAL_TYPE; } else { $username = $repository->getDetail('ssh-login'); if (!$username) { @@ -42,10 +42,10 @@ foreach (new LiskMigrationIterator($table) as $repository) { $file = $repository->getDetail('ssh-keyfile'); if ($file) { $secret = $file; - $type = PassphraseCredentialTypeSSHPrivateKeyFile::CREDENTIAL_TYPE; + $type = PassphraseSSHPrivateKeyFileCredentialType::CREDENTIAL_TYPE; } else { $secret = $repository->getDetail('ssh-key'); - $type = PassphraseCredentialTypeSSHPrivateKeyText::CREDENTIAL_TYPE; + $type = PassphraseSSHPrivateKeyTextCredentialType::CREDENTIAL_TYPE; } } diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 14b61c3149..e5a57a3234 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -92,6 +92,7 @@ phutil_register_library_map(array( 'AlmanacServiceTransaction' => 'applications/almanac/storage/AlmanacServiceTransaction.php', 'AlmanacServiceTransactionQuery' => 'applications/almanac/query/AlmanacServiceTransactionQuery.php', 'AlmanacServiceType' => 'applications/almanac/servicetype/AlmanacServiceType.php', + 'AlmanacServiceTypeTestCase' => 'applications/almanac/servicetype/__tests__/AlmanacServiceTypeTestCase.php', 'AlmanacServiceViewController' => 'applications/almanac/controller/AlmanacServiceViewController.php', 'AphlictDropdownDataQuery' => 'applications/aphlict/query/AphlictDropdownDataQuery.php', 'Aphront304Response' => 'aphront/response/Aphront304Response.php', @@ -183,6 +184,7 @@ phutil_register_library_map(array( 'CelerityPhabricatorResourceController' => 'applications/celerity/controller/CelerityPhabricatorResourceController.php', 'CelerityPhabricatorResources' => 'applications/celerity/resources/CelerityPhabricatorResources.php', 'CelerityPhysicalResources' => 'applications/celerity/resources/CelerityPhysicalResources.php', + 'CelerityPhysicalResourcesTestCase' => 'applications/celerity/resources/__tests__/CelerityPhysicalResourcesTestCase.php', 'CelerityResourceController' => 'applications/celerity/controller/CelerityResourceController.php', 'CelerityResourceGraph' => 'applications/celerity/CelerityResourceGraph.php', 'CelerityResourceMap' => 'applications/celerity/CelerityResourceMap.php', @@ -197,6 +199,7 @@ phutil_register_library_map(array( 'ChatLogQueryConduitAPIMethod' => 'applications/chatlog/conduit/ChatLogQueryConduitAPIMethod.php', 'ChatLogRecordConduitAPIMethod' => 'applications/chatlog/conduit/ChatLogRecordConduitAPIMethod.php', 'ConduitAPIMethod' => 'applications/conduit/method/ConduitAPIMethod.php', + 'ConduitAPIMethodTestCase' => 'applications/conduit/method/__tests__/ConduitAPIMethodTestCase.php', 'ConduitAPIRequest' => 'applications/conduit/protocol/ConduitAPIRequest.php', 'ConduitAPIResponse' => 'applications/conduit/protocol/ConduitAPIResponse.php', 'ConduitApplicationNotInstalledException' => 'applications/conduit/protocol/exception/ConduitApplicationNotInstalledException.php', @@ -255,6 +258,7 @@ phutil_register_library_map(array( 'ConpherenceThreadIndexer' => 'applications/conpherence/search/ConpherenceThreadIndexer.php', 'ConpherenceThreadListView' => 'applications/conpherence/view/ConpherenceThreadListView.php', 'ConpherenceThreadMailReceiver' => 'applications/conpherence/mail/ConpherenceThreadMailReceiver.php', + 'ConpherenceThreadMembersPolicyRule' => 'applications/conpherence/policyrule/ConpherenceThreadMembersPolicyRule.php', 'ConpherenceThreadQuery' => 'applications/conpherence/query/ConpherenceThreadQuery.php', 'ConpherenceThreadRemarkupRule' => 'applications/conpherence/remarkup/ConpherenceThreadRemarkupRule.php', 'ConpherenceThreadSearchEngine' => 'applications/conpherence/query/ConpherenceThreadSearchEngine.php', @@ -700,6 +704,7 @@ phutil_register_library_map(array( 'DrydockBlueprintEditController' => 'applications/drydock/controller/DrydockBlueprintEditController.php', 'DrydockBlueprintEditor' => 'applications/drydock/editor/DrydockBlueprintEditor.php', 'DrydockBlueprintImplementation' => 'applications/drydock/blueprint/DrydockBlueprintImplementation.php', + 'DrydockBlueprintImplementationTestCase' => 'applications/drydock/blueprint/__tests__/DrydockBlueprintImplementationTestCase.php', 'DrydockBlueprintListController' => 'applications/drydock/controller/DrydockBlueprintListController.php', 'DrydockBlueprintPHIDType' => 'applications/drydock/phid/DrydockBlueprintPHIDType.php', 'DrydockBlueprintQuery' => 'applications/drydock/query/DrydockBlueprintQuery.php', @@ -762,6 +767,7 @@ phutil_register_library_map(array( 'FeedPublisherWorker' => 'applications/feed/worker/FeedPublisherWorker.php', 'FeedPushWorker' => 'applications/feed/worker/FeedPushWorker.php', 'FeedQueryConduitAPIMethod' => 'applications/feed/conduit/FeedQueryConduitAPIMethod.php', + 'FeedStoryNotificationGarbageCollector' => 'applications/notification/garbagecollector/FeedStoryNotificationGarbageCollector.php', 'FileAllocateConduitAPIMethod' => 'applications/files/conduit/FileAllocateConduitAPIMethod.php', 'FileConduitAPIMethod' => 'applications/files/conduit/FileConduitAPIMethod.php', 'FileCreateMailReceiver' => 'applications/files/mail/FileCreateMailReceiver.php', @@ -841,6 +847,7 @@ phutil_register_library_map(array( 'HarbormasterBuildStepCustomField' => 'applications/harbormaster/customfield/HarbormasterBuildStepCustomField.php', 'HarbormasterBuildStepEditor' => 'applications/harbormaster/editor/HarbormasterBuildStepEditor.php', 'HarbormasterBuildStepImplementation' => 'applications/harbormaster/step/HarbormasterBuildStepImplementation.php', + 'HarbormasterBuildStepImplementationTestCase' => 'applications/harbormaster/step/__tests__/HarbormasterBuildStepImplementationTestCase.php', 'HarbormasterBuildStepPHIDType' => 'applications/harbormaster/phid/HarbormasterBuildStepPHIDType.php', 'HarbormasterBuildStepQuery' => 'applications/harbormaster/query/HarbormasterBuildStepQuery.php', 'HarbormasterBuildStepTransaction' => 'applications/harbormaster/storage/configuration/HarbormasterBuildStepTransaction.php', @@ -1031,6 +1038,7 @@ phutil_register_library_map(array( 'ManiphestEmailCommand' => 'applications/maniphest/command/ManiphestEmailCommand.php', 'ManiphestExcelDefaultFormat' => 'applications/maniphest/export/ManiphestExcelDefaultFormat.php', 'ManiphestExcelFormat' => 'applications/maniphest/export/ManiphestExcelFormat.php', + 'ManiphestExcelFormatTestCase' => 'applications/maniphest/export/__tests__/ManiphestExcelFormatTestCase.php', 'ManiphestExportController' => 'applications/maniphest/controller/ManiphestExportController.php', 'ManiphestGetTaskTransactionsConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestGetTaskTransactionsConduitAPIMethod.php', 'ManiphestHovercardEventListener' => 'applications/maniphest/event/ManiphestHovercardEventListener.php', @@ -1049,6 +1057,7 @@ phutil_register_library_map(array( 'ManiphestStatusEmailCommand' => 'applications/maniphest/command/ManiphestStatusEmailCommand.php', 'ManiphestSubpriorityController' => 'applications/maniphest/controller/ManiphestSubpriorityController.php', 'ManiphestTask' => 'applications/maniphest/storage/ManiphestTask.php', + 'ManiphestTaskAuthorPolicyRule' => 'applications/maniphest/policyrule/ManiphestTaskAuthorPolicyRule.php', 'ManiphestTaskClosedStatusDatasource' => 'applications/maniphest/typeahead/ManiphestTaskClosedStatusDatasource.php', 'ManiphestTaskDependedOnByTaskEdgeType' => 'applications/maniphest/edge/ManiphestTaskDependedOnByTaskEdgeType.php', 'ManiphestTaskDependsOnTaskEdgeType' => 'applications/maniphest/edge/ManiphestTaskDependsOnTaskEdgeType.php', @@ -1082,6 +1091,7 @@ phutil_register_library_map(array( 'ManiphestView' => 'applications/maniphest/view/ManiphestView.php', 'MetaMTAConstants' => 'applications/metamta/constants/MetaMTAConstants.php', 'MetaMTAEmailTransactionCommand' => 'applications/metamta/command/MetaMTAEmailTransactionCommand.php', + 'MetaMTAEmailTransactionCommandTestCase' => 'applications/metamta/command/__tests__/MetaMTAEmailTransactionCommandTestCase.php', 'MetaMTAMailReceivedGarbageCollector' => 'applications/metamta/garbagecollector/MetaMTAMailReceivedGarbageCollector.php', 'MetaMTAMailSentGarbageCollector' => 'applications/metamta/garbagecollector/MetaMTAMailSentGarbageCollector.php', 'MetaMTAReceivedMailStatus' => 'applications/metamta/constants/MetaMTAReceivedMailStatus.php', @@ -1140,6 +1150,7 @@ phutil_register_library_map(array( 'NuanceSourceDefaultEditCapability' => 'applications/nuance/capability/NuanceSourceDefaultEditCapability.php', 'NuanceSourceDefaultViewCapability' => 'applications/nuance/capability/NuanceSourceDefaultViewCapability.php', 'NuanceSourceDefinition' => 'applications/nuance/source/NuanceSourceDefinition.php', + 'NuanceSourceDefinitionTestCase' => 'applications/nuance/source/__tests__/NuanceSourceDefinitionTestCase.php', 'NuanceSourceEditController' => 'applications/nuance/controller/NuanceSourceEditController.php', 'NuanceSourceEditor' => 'applications/nuance/editor/NuanceSourceEditor.php', 'NuanceSourceListController' => 'applications/nuance/controller/NuanceSourceListController.php', @@ -1255,17 +1266,18 @@ phutil_register_library_map(array( 'PassphraseCredentialTransactionEditor' => 'applications/passphrase/editor/PassphraseCredentialTransactionEditor.php', 'PassphraseCredentialTransactionQuery' => 'applications/passphrase/query/PassphraseCredentialTransactionQuery.php', 'PassphraseCredentialType' => 'applications/passphrase/credentialtype/PassphraseCredentialType.php', - 'PassphraseCredentialTypePassword' => 'applications/passphrase/credentialtype/PassphraseCredentialTypePassword.php', - 'PassphraseCredentialTypeSSHGeneratedKey' => 'applications/passphrase/credentialtype/PassphraseCredentialTypeSSHGeneratedKey.php', - 'PassphraseCredentialTypeSSHPrivateKey' => 'applications/passphrase/credentialtype/PassphraseCredentialTypeSSHPrivateKey.php', - 'PassphraseCredentialTypeSSHPrivateKeyFile' => 'applications/passphrase/credentialtype/PassphraseCredentialTypeSSHPrivateKeyFile.php', - 'PassphraseCredentialTypeSSHPrivateKeyText' => 'applications/passphrase/credentialtype/PassphraseCredentialTypeSSHPrivateKeyText.php', + 'PassphraseCredentialTypeTestCase' => 'applications/passphrase/credentialtype/__tests__/PassphraseCredentialTypeTestCase.php', 'PassphraseCredentialViewController' => 'applications/passphrase/controller/PassphraseCredentialViewController.php', 'PassphraseDAO' => 'applications/passphrase/storage/PassphraseDAO.php', + 'PassphrasePasswordCredentialType' => 'applications/passphrase/credentialtype/PassphrasePasswordCredentialType.php', 'PassphrasePasswordKey' => 'applications/passphrase/keys/PassphrasePasswordKey.php', 'PassphraseQueryConduitAPIMethod' => 'applications/passphrase/conduit/PassphraseQueryConduitAPIMethod.php', 'PassphraseRemarkupRule' => 'applications/passphrase/remarkup/PassphraseRemarkupRule.php', + 'PassphraseSSHGeneratedKeyCredentialType' => 'applications/passphrase/credentialtype/PassphraseSSHGeneratedKeyCredentialType.php', 'PassphraseSSHKey' => 'applications/passphrase/keys/PassphraseSSHKey.php', + 'PassphraseSSHPrivateKeyCredentialType' => 'applications/passphrase/credentialtype/PassphraseSSHPrivateKeyCredentialType.php', + 'PassphraseSSHPrivateKeyFileCredentialType' => 'applications/passphrase/credentialtype/PassphraseSSHPrivateKeyFileCredentialType.php', + 'PassphraseSSHPrivateKeyTextCredentialType' => 'applications/passphrase/credentialtype/PassphraseSSHPrivateKeyTextCredentialType.php', 'PassphraseSchemaSpec' => 'applications/passphrase/storage/PassphraseSchemaSpec.php', 'PassphraseSearchIndexer' => 'applications/passphrase/search/PassphraseSearchIndexer.php', 'PassphraseSecret' => 'applications/passphrase/storage/PassphraseSecret.php', @@ -1309,6 +1321,7 @@ phutil_register_library_map(array( 'PhabricatorApplicationApplicationPHIDType' => 'applications/meta/phid/PhabricatorApplicationApplicationPHIDType.php', 'PhabricatorApplicationConfigOptions' => 'applications/config/option/PhabricatorApplicationConfigOptions.php', 'PhabricatorApplicationConfigurationPanel' => 'applications/meta/panel/PhabricatorApplicationConfigurationPanel.php', + 'PhabricatorApplicationConfigurationPanelTestCase' => 'applications/meta/panel/__tests__/PhabricatorApplicationConfigurationPanelTestCase.php', 'PhabricatorApplicationDatasource' => 'applications/meta/typeahead/PhabricatorApplicationDatasource.php', 'PhabricatorApplicationDetailViewController' => 'applications/meta/controller/PhabricatorApplicationDetailViewController.php', 'PhabricatorApplicationEditController' => 'applications/meta/controller/PhabricatorApplicationEditController.php', @@ -1318,8 +1331,10 @@ phutil_register_library_map(array( 'PhabricatorApplicationQuery' => 'applications/meta/query/PhabricatorApplicationQuery.php', 'PhabricatorApplicationSearchController' => 'applications/search/controller/PhabricatorApplicationSearchController.php', 'PhabricatorApplicationSearchEngine' => 'applications/search/engine/PhabricatorApplicationSearchEngine.php', + 'PhabricatorApplicationSearchEngineTestCase' => 'applications/search/engine/__tests__/PhabricatorApplicationSearchEngineTestCase.php', 'PhabricatorApplicationSearchResultsControllerInterface' => 'applications/search/interface/PhabricatorApplicationSearchResultsControllerInterface.php', 'PhabricatorApplicationStatusView' => 'applications/meta/view/PhabricatorApplicationStatusView.php', + 'PhabricatorApplicationTestCase' => 'applications/base/__tests__/PhabricatorApplicationTestCase.php', 'PhabricatorApplicationTransaction' => 'applications/transactions/storage/PhabricatorApplicationTransaction.php', 'PhabricatorApplicationTransactionComment' => 'applications/transactions/storage/PhabricatorApplicationTransactionComment.php', 'PhabricatorApplicationTransactionCommentEditController' => 'applications/transactions/controller/PhabricatorApplicationTransactionCommentEditController.php', @@ -1392,6 +1407,7 @@ phutil_register_library_map(array( 'PhabricatorAuthEditController' => 'applications/auth/controller/config/PhabricatorAuthEditController.php', 'PhabricatorAuthFactor' => 'applications/auth/factor/PhabricatorAuthFactor.php', 'PhabricatorAuthFactorConfig' => 'applications/auth/storage/PhabricatorAuthFactorConfig.php', + 'PhabricatorAuthFactorTestCase' => 'applications/auth/factor/__tests__/PhabricatorAuthFactorTestCase.php', 'PhabricatorAuthFinishController' => 'applications/auth/controller/PhabricatorAuthFinishController.php', 'PhabricatorAuthHighSecurityRequiredException' => 'applications/auth/exception/PhabricatorAuthHighSecurityRequiredException.php', 'PhabricatorAuthHighSecurityToken' => 'applications/auth/data/PhabricatorAuthHighSecurityToken.php', @@ -1781,6 +1797,7 @@ phutil_register_library_map(array( 'PhabricatorEdgeQuery' => 'infrastructure/edges/query/PhabricatorEdgeQuery.php', 'PhabricatorEdgeTestCase' => 'infrastructure/edges/__tests__/PhabricatorEdgeTestCase.php', 'PhabricatorEdgeType' => 'infrastructure/edges/type/PhabricatorEdgeType.php', + 'PhabricatorEdgeTypeTestCase' => 'infrastructure/edges/type/__tests__/PhabricatorEdgeTypeTestCase.php', 'PhabricatorEditor' => 'infrastructure/PhabricatorEditor.php', 'PhabricatorElasticSearchEngine' => 'applications/search/engine/PhabricatorElasticSearchEngine.php', 'PhabricatorElasticSearchSetupCheck' => 'applications/config/check/PhabricatorElasticSearchSetupCheck.php', @@ -1816,6 +1833,7 @@ phutil_register_library_map(array( 'PhabricatorFactDAO' => 'applications/fact/storage/PhabricatorFactDAO.php', 'PhabricatorFactDaemon' => 'applications/fact/daemon/PhabricatorFactDaemon.php', 'PhabricatorFactEngine' => 'applications/fact/engine/PhabricatorFactEngine.php', + 'PhabricatorFactEngineTestCase' => 'applications/fact/engine/__tests__/PhabricatorFactEngineTestCase.php', 'PhabricatorFactHomeController' => 'applications/fact/controller/PhabricatorFactHomeController.php', 'PhabricatorFactLastUpdatedEngine' => 'applications/fact/engine/PhabricatorFactLastUpdatedEngine.php', 'PhabricatorFactManagementAnalyzeWorkflow' => 'applications/fact/management/PhabricatorFactManagementAnalyzeWorkflow.php', @@ -1873,6 +1891,7 @@ phutil_register_library_map(array( 'PhabricatorFileStorageBlob' => 'applications/files/storage/PhabricatorFileStorageBlob.php', 'PhabricatorFileStorageConfigurationException' => 'applications/files/exception/PhabricatorFileStorageConfigurationException.php', 'PhabricatorFileStorageEngine' => 'applications/files/engine/PhabricatorFileStorageEngine.php', + 'PhabricatorFileStorageEngineTestCase' => 'applications/files/engine/__tests__/PhabricatorFileStorageEngineTestCase.php', 'PhabricatorFileTemporaryGarbageCollector' => 'applications/files/garbagecollector/PhabricatorFileTemporaryGarbageCollector.php', 'PhabricatorFileTestCase' => 'applications/files/storage/__tests__/PhabricatorFileTestCase.php', 'PhabricatorFileTestDataGenerator' => 'applications/files/lipsum/PhabricatorFileTestDataGenerator.php', @@ -1883,6 +1902,7 @@ phutil_register_library_map(array( 'PhabricatorFileTransform' => 'applications/files/transform/PhabricatorFileTransform.php', 'PhabricatorFileTransformController' => 'applications/files/controller/PhabricatorFileTransformController.php', 'PhabricatorFileTransformListController' => 'applications/files/controller/PhabricatorFileTransformListController.php', + 'PhabricatorFileTransformTestCase' => 'applications/files/transform/__tests__/PhabricatorFileTransformTestCase.php', 'PhabricatorFileUploadController' => 'applications/files/controller/PhabricatorFileUploadController.php', 'PhabricatorFileUploadDialogController' => 'applications/files/controller/PhabricatorFileUploadDialogController.php', 'PhabricatorFileUploadException' => 'applications/files/exception/PhabricatorFileUploadException.php', @@ -1960,6 +1980,7 @@ phutil_register_library_map(array( 'PhabricatorInternationalizationManagementWorkflow' => 'infrastructure/internationalization/management/PhabricatorInternationalizationManagementWorkflow.php', 'PhabricatorInvalidConfigSetupCheck' => 'applications/config/check/PhabricatorInvalidConfigSetupCheck.php', 'PhabricatorIteratedMD5PasswordHasher' => 'infrastructure/util/password/PhabricatorIteratedMD5PasswordHasher.php', + 'PhabricatorIteratedMD5PasswordHasherTestCase' => 'infrastructure/util/password/__tests__/PhabricatorIteratedMD5PasswordHasherTestCase.php', 'PhabricatorJIRAAuthProvider' => 'applications/auth/provider/PhabricatorJIRAAuthProvider.php', 'PhabricatorJavelinLinter' => 'infrastructure/lint/linter/PhabricatorJavelinLinter.php', 'PhabricatorJiraIssueHasObjectEdgeType' => 'applications/doorkeeper/edge/PhabricatorJiraIssueHasObjectEdgeType.php', @@ -2048,9 +2069,12 @@ phutil_register_library_map(array( 'PhabricatorMetaMTAApplication' => 'applications/metamta/application/PhabricatorMetaMTAApplication.php', 'PhabricatorMetaMTAApplicationEmail' => 'applications/metamta/storage/PhabricatorMetaMTAApplicationEmail.php', 'PhabricatorMetaMTAApplicationEmailDatasource' => 'applications/metamta/typeahead/PhabricatorMetaMTAApplicationEmailDatasource.php', + 'PhabricatorMetaMTAApplicationEmailEditor' => 'applications/metamta/editor/PhabricatorMetaMTAApplicationEmailEditor.php', 'PhabricatorMetaMTAApplicationEmailPHIDType' => 'applications/phid/PhabricatorMetaMTAApplicationEmailPHIDType.php', 'PhabricatorMetaMTAApplicationEmailPanel' => 'applications/metamta/applicationpanel/PhabricatorMetaMTAApplicationEmailPanel.php', 'PhabricatorMetaMTAApplicationEmailQuery' => 'applications/metamta/query/PhabricatorMetaMTAApplicationEmailQuery.php', + 'PhabricatorMetaMTAApplicationEmailTransaction' => 'applications/metamta/storage/PhabricatorMetaMTAApplicationEmailTransaction.php', + 'PhabricatorMetaMTAApplicationEmailTransactionQuery' => 'applications/metamta/query/PhabricatorMetaMTAApplicationEmailTransactionQuery.php', 'PhabricatorMetaMTAAttachment' => 'applications/metamta/storage/PhabricatorMetaMTAAttachment.php', 'PhabricatorMetaMTAConfigOptions' => 'applications/config/option/PhabricatorMetaMTAConfigOptions.php', 'PhabricatorMetaMTAController' => 'applications/metamta/controller/PhabricatorMetaMTAController.php', @@ -2182,6 +2206,7 @@ phutil_register_library_map(array( 'PhabricatorPHIDConstants' => 'applications/phid/PhabricatorPHIDConstants.php', 'PhabricatorPHIDInterface' => 'applications/phid/interface/PhabricatorPHIDInterface.php', 'PhabricatorPHIDType' => 'applications/phid/type/PhabricatorPHIDType.php', + 'PhabricatorPHIDTypeTestCase' => 'applications/phid/type/__tests__/PhabricatorPHIDTypeTestCase.php', 'PhabricatorPHPASTApplication' => 'applications/phpast/application/PhabricatorPHPASTApplication.php', 'PhabricatorPHPConfigSetupCheck' => 'applications/config/check/PhabricatorPHPConfigSetupCheck.php', 'PhabricatorPHPMailerConfigOptions' => 'applications/config/option/PhabricatorPHPMailerConfigOptions.php', @@ -2274,6 +2299,7 @@ phutil_register_library_map(array( 'PhabricatorPolicyCanJoinCapability' => 'applications/policy/capability/PhabricatorPolicyCanJoinCapability.php', 'PhabricatorPolicyCanViewCapability' => 'applications/policy/capability/PhabricatorPolicyCanViewCapability.php', 'PhabricatorPolicyCapability' => 'applications/policy/capability/PhabricatorPolicyCapability.php', + 'PhabricatorPolicyCapabilityTestCase' => 'applications/policy/capability/__tests__/PhabricatorPolicyCapabilityTestCase.php', 'PhabricatorPolicyConfigOptions' => 'applications/policy/config/PhabricatorPolicyConfigOptions.php', 'PhabricatorPolicyConstants' => 'applications/policy/constants/PhabricatorPolicyConstants.php', 'PhabricatorPolicyController' => 'applications/policy/controller/PhabricatorPolicyController.php', @@ -2511,6 +2537,7 @@ phutil_register_library_map(array( 'PhabricatorSearchDocumentTypeDatasource' => 'applications/search/typeahead/PhabricatorSearchDocumentTypeDatasource.php', 'PhabricatorSearchEditController' => 'applications/search/controller/PhabricatorSearchEditController.php', 'PhabricatorSearchEngine' => 'applications/search/engine/PhabricatorSearchEngine.php', + 'PhabricatorSearchEngineTestCase' => 'applications/search/engine/__tests__/PhabricatorSearchEngineTestCase.php', 'PhabricatorSearchField' => 'applications/search/field/PhabricatorSearchField.php', 'PhabricatorSearchHovercardController' => 'applications/search/controller/PhabricatorSearchHovercardController.php', 'PhabricatorSearchIndexer' => 'applications/search/index/PhabricatorSearchIndexer.php', @@ -2544,6 +2571,7 @@ phutil_register_library_map(array( 'PhabricatorSettingsMainController' => 'applications/settings/controller/PhabricatorSettingsMainController.php', 'PhabricatorSettingsPanel' => 'applications/settings/panel/PhabricatorSettingsPanel.php', 'PhabricatorSetupCheck' => 'applications/config/check/PhabricatorSetupCheck.php', + 'PhabricatorSetupCheckTestCase' => 'applications/config/check/__tests__/PhabricatorSetupCheckTestCase.php', 'PhabricatorSetupIssue' => 'applications/config/issue/PhabricatorSetupIssue.php', 'PhabricatorSetupIssueUIExample' => 'applications/uiexample/examples/PhabricatorSetupIssueUIExample.php', 'PhabricatorSetupIssueView' => 'applications/config/view/PhabricatorSetupIssueView.php', @@ -2573,10 +2601,10 @@ phutil_register_library_map(array( 'PhabricatorSortTableUIExample' => 'applications/uiexample/examples/PhabricatorSortTableUIExample.php', 'PhabricatorSourceCodeView' => 'view/layout/PhabricatorSourceCodeView.php', 'PhabricatorSpacesApplication' => 'applications/spaces/application/PhabricatorSpacesApplication.php', + 'PhabricatorSpacesArchiveController' => 'applications/spaces/controller/PhabricatorSpacesArchiveController.php', 'PhabricatorSpacesCapabilityCreateSpaces' => 'applications/spaces/capability/PhabricatorSpacesCapabilityCreateSpaces.php', 'PhabricatorSpacesCapabilityDefaultEdit' => 'applications/spaces/capability/PhabricatorSpacesCapabilityDefaultEdit.php', 'PhabricatorSpacesCapabilityDefaultView' => 'applications/spaces/capability/PhabricatorSpacesCapabilityDefaultView.php', - 'PhabricatorSpacesControl' => 'applications/spaces/view/PhabricatorSpacesControl.php', 'PhabricatorSpacesController' => 'applications/spaces/controller/PhabricatorSpacesController.php', 'PhabricatorSpacesDAO' => 'applications/spaces/storage/PhabricatorSpacesDAO.php', 'PhabricatorSpacesEditController' => 'applications/spaces/controller/PhabricatorSpacesEditController.php', @@ -2591,6 +2619,7 @@ phutil_register_library_map(array( 'PhabricatorSpacesNamespaceTransaction' => 'applications/spaces/storage/PhabricatorSpacesNamespaceTransaction.php', 'PhabricatorSpacesNamespaceTransactionQuery' => 'applications/spaces/query/PhabricatorSpacesNamespaceTransactionQuery.php', 'PhabricatorSpacesRemarkupRule' => 'applications/spaces/remarkup/PhabricatorSpacesRemarkupRule.php', + 'PhabricatorSpacesSchemaSpec' => 'applications/spaces/storage/PhabricatorSpacesSchemaSpec.php', 'PhabricatorSpacesTestCase' => 'applications/spaces/__tests__/PhabricatorSpacesTestCase.php', 'PhabricatorSpacesViewController' => 'applications/spaces/controller/PhabricatorSpacesViewController.php', 'PhabricatorStandardCustomField' => 'infrastructure/customfield/standard/PhabricatorStandardCustomField.php', @@ -2635,6 +2664,7 @@ phutil_register_library_map(array( 'PhabricatorSubscriptionsEditor' => 'applications/subscriptions/editor/PhabricatorSubscriptionsEditor.php', 'PhabricatorSubscriptionsListController' => 'applications/subscriptions/controller/PhabricatorSubscriptionsListController.php', 'PhabricatorSubscriptionsSubscribeEmailCommand' => 'applications/subscriptions/command/PhabricatorSubscriptionsSubscribeEmailCommand.php', + 'PhabricatorSubscriptionsSubscribersPolicyRule' => 'applications/subscriptions/policyrule/PhabricatorSubscriptionsSubscribersPolicyRule.php', 'PhabricatorSubscriptionsTransactionController' => 'applications/subscriptions/controller/PhabricatorSubscriptionsTransactionController.php', 'PhabricatorSubscriptionsUIEventListener' => 'applications/subscriptions/events/PhabricatorSubscriptionsUIEventListener.php', 'PhabricatorSubscriptionsUnsubscribeEmailCommand' => 'applications/subscriptions/command/PhabricatorSubscriptionsUnsubscribeEmailCommand.php', @@ -2959,6 +2989,7 @@ phutil_register_library_map(array( 'PhortunePaymentProviderConfigTransaction' => 'applications/phortune/storage/PhortunePaymentProviderConfigTransaction.php', 'PhortunePaymentProviderConfigTransactionQuery' => 'applications/phortune/query/PhortunePaymentProviderConfigTransactionQuery.php', 'PhortunePaymentProviderPHIDType' => 'applications/phortune/phid/PhortunePaymentProviderPHIDType.php', + 'PhortunePaymentProviderTestCase' => 'applications/phortune/provider/__tests__/PhortunePaymentProviderTestCase.php', 'PhortuneProduct' => 'applications/phortune/storage/PhortuneProduct.php', 'PhortuneProductImplementation' => 'applications/phortune/product/PhortuneProductImplementation.php', 'PhortuneProductListController' => 'applications/phortune/controller/PhortuneProductListController.php', @@ -3375,12 +3406,15 @@ phutil_register_library_map(array( 'AlmanacServiceTransaction' => 'PhabricatorApplicationTransaction', 'AlmanacServiceTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'AlmanacServiceType' => 'Phobject', + 'AlmanacServiceTypeTestCase' => 'PhabricatorTestCase', 'AlmanacServiceViewController' => 'AlmanacServiceController', + 'AphlictDropdownDataQuery' => 'Phobject', 'Aphront304Response' => 'AphrontResponse', 'Aphront400Response' => 'AphrontResponse', 'Aphront403Response' => 'AphrontHTMLResponse', 'Aphront404Response' => 'AphrontHTMLResponse', 'AphrontAjaxResponse' => 'AphrontResponse', + 'AphrontApplicationConfiguration' => 'Phobject', 'AphrontBarView' => 'AphrontView', 'AphrontCSRFException' => 'AphrontException', 'AphrontCalendarEventView' => 'AphrontView', @@ -3415,6 +3449,7 @@ phutil_register_library_map(array( 'AphrontGlyphBarView' => 'AphrontBarView', 'AphrontHTMLResponse' => 'AphrontResponse', 'AphrontHTTPProxyResponse' => 'AphrontResponse', + 'AphrontHTTPSink' => 'Phobject', 'AphrontHTTPSinkTestCase' => 'PhabricatorTestCase', 'AphrontIsolatedDatabaseConnectionTestCase' => 'PhabricatorTestCase', 'AphrontIsolatedHTTPSink' => 'AphrontHTTPSink', @@ -3434,7 +3469,9 @@ phutil_register_library_map(array( 'AphrontRedirectResponse' => 'AphrontResponse', 'AphrontRedirectResponseTestCase' => 'PhabricatorTestCase', 'AphrontReloadResponse' => 'AphrontRedirectResponse', + 'AphrontRequest' => 'Phobject', 'AphrontRequestTestCase' => 'PhabricatorTestCase', + 'AphrontResponse' => 'Phobject', 'AphrontSideNavFilterView' => 'AphrontView', 'AphrontStackTraceView' => 'AphrontView', 'AphrontStandaloneHTMLResponse' => 'AphrontHTMLResponse', @@ -3443,6 +3480,7 @@ phutil_register_library_map(array( 'AphrontTokenizerTemplateView' => 'AphrontView', 'AphrontTwoColumnView' => 'AphrontView', 'AphrontTypeaheadTemplateView' => 'AphrontView', + 'AphrontURIMapper' => 'Phobject', 'AphrontUnhandledExceptionResponse' => 'AphrontStandaloneHTMLResponse', 'AphrontUsageException' => 'AphrontException', 'AphrontView' => array( @@ -3455,16 +3493,25 @@ phutil_register_library_map(array( 'AuditConduitAPIMethod' => 'ConduitAPIMethod', 'AuditQueryConduitAPIMethod' => 'AuditConduitAPIMethod', 'AuthManageProvidersCapability' => 'PhabricatorPolicyCapability', + 'CalendarTimeUtil' => 'Phobject', 'CalendarTimeUtilTestCase' => 'PhabricatorTestCase', + 'CelerityAPI' => 'Phobject', 'CelerityManagementMapWorkflow' => 'CelerityManagementWorkflow', 'CelerityManagementWorkflow' => 'PhabricatorManagementWorkflow', 'CelerityPhabricatorResourceController' => 'CelerityResourceController', 'CelerityPhabricatorResources' => 'CelerityResourcesOnDisk', 'CelerityPhysicalResources' => 'CelerityResources', + 'CelerityPhysicalResourcesTestCase' => 'PhabricatorTestCase', 'CelerityResourceController' => 'PhabricatorController', 'CelerityResourceGraph' => 'AbstractDirectedGraph', + 'CelerityResourceMap' => 'Phobject', + 'CelerityResourceMapGenerator' => 'Phobject', + 'CelerityResourceTransformer' => 'Phobject', 'CelerityResourceTransformerTestCase' => 'PhabricatorTestCase', + 'CelerityResources' => 'Phobject', 'CelerityResourcesOnDisk' => 'CelerityPhysicalResources', + 'CeleritySpriteGenerator' => 'Phobject', + 'CelerityStaticResourceResponse' => 'Phobject', 'ChatLogConduitAPIMethod' => 'ConduitAPIMethod', 'ChatLogQueryConduitAPIMethod' => 'ChatLogConduitAPIMethod', 'ChatLogRecordConduitAPIMethod' => 'ChatLogConduitAPIMethod', @@ -3472,7 +3519,11 @@ phutil_register_library_map(array( 'Phobject', 'PhabricatorPolicyInterface', ), + 'ConduitAPIMethodTestCase' => 'PhabricatorTestCase', + 'ConduitAPIRequest' => 'Phobject', + 'ConduitAPIResponse' => 'Phobject', 'ConduitApplicationNotInstalledException' => 'ConduitMethodNotFoundException', + 'ConduitCall' => 'Phobject', 'ConduitCallTestCase' => 'PhabricatorTestCase', 'ConduitConnectConduitAPIMethod' => 'ConduitAPIMethod', 'ConduitConnectionGarbageCollector' => 'PhabricatorGarbageCollector', @@ -3490,6 +3541,7 @@ phutil_register_library_map(array( 'ConpherenceColumnViewController' => 'ConpherenceController', 'ConpherenceConduitAPIMethod' => 'ConduitAPIMethod', 'ConpherenceConfigOptions' => 'PhabricatorApplicationConfigOptions', + 'ConpherenceConstants' => 'Phobject', 'ConpherenceController' => 'PhabricatorController', 'ConpherenceCreateThreadConduitAPIMethod' => 'ConpherenceConduitAPIMethod', 'ConpherenceCreateThreadMailReceiver' => 'PhabricatorMailReceiver', @@ -3532,6 +3584,7 @@ phutil_register_library_map(array( 'ConpherenceThreadIndexer' => 'PhabricatorSearchDocumentIndexer', 'ConpherenceThreadListView' => 'AphrontView', 'ConpherenceThreadMailReceiver' => 'PhabricatorObjectMailReceiver', + 'ConpherenceThreadMembersPolicyRule' => 'PhabricatorPolicyRule', 'ConpherenceThreadQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'ConpherenceThreadRemarkupRule' => 'PhabricatorObjectRemarkupRule', 'ConpherenceThreadSearchEngine' => 'PhabricatorApplicationSearchEngine', @@ -3539,6 +3592,7 @@ phutil_register_library_map(array( 'ConpherenceTransaction' => 'PhabricatorApplicationTransaction', 'ConpherenceTransactionComment' => 'PhabricatorApplicationTransactionComment', 'ConpherenceTransactionQuery' => 'PhabricatorApplicationTransactionQuery', + 'ConpherenceTransactionRenderer' => 'Phobject', 'ConpherenceTransactionView' => 'AphrontView', 'ConpherenceUpdateActions' => 'ConpherenceConstants', 'ConpherenceUpdateController' => 'ConpherenceController', @@ -3548,14 +3602,22 @@ phutil_register_library_map(array( 'ConpherenceWidgetController' => 'ConpherenceController', 'ConpherenceWidgetView' => 'AphrontView', 'DarkConsoleController' => 'PhabricatorController', + 'DarkConsoleCore' => 'Phobject', 'DarkConsoleDataController' => 'PhabricatorController', 'DarkConsoleErrorLogPlugin' => 'DarkConsolePlugin', + 'DarkConsoleErrorLogPluginAPI' => 'Phobject', 'DarkConsoleEventPlugin' => 'DarkConsolePlugin', 'DarkConsoleEventPluginAPI' => 'PhabricatorEventListener', + 'DarkConsolePlugin' => 'Phobject', 'DarkConsoleRequestPlugin' => 'DarkConsolePlugin', 'DarkConsoleServicesPlugin' => 'DarkConsolePlugin', 'DarkConsoleXHProfPlugin' => 'DarkConsolePlugin', - 'DefaultDatabaseConfigurationProvider' => 'DatabaseConfigurationProvider', + 'DarkConsoleXHProfPluginAPI' => 'Phobject', + 'DefaultDatabaseConfigurationProvider' => array( + 'Phobject', + 'DatabaseConfigurationProvider', + ), + 'DifferentialAction' => 'Phobject', 'DifferentialActionEmailCommand' => 'MetaMTAEmailTransactionCommand', 'DifferentialActionMenuEventListener' => 'PhabricatorEventListener', 'DifferentialAddCommentView' => 'AphrontView', @@ -3567,18 +3629,22 @@ phutil_register_library_map(array( 'DifferentialAuthorField' => 'DifferentialCustomField', 'DifferentialBlameRevisionField' => 'DifferentialStoredCustomField', 'DifferentialBranchField' => 'DifferentialCustomField', + 'DifferentialChangeType' => 'Phobject', 'DifferentialChangesSinceLastUpdateField' => 'DifferentialCustomField', 'DifferentialChangeset' => array( 'DifferentialDAO', 'PhabricatorPolicyInterface', ), 'DifferentialChangesetDetailView' => 'AphrontView', + 'DifferentialChangesetFileTreeSideNavBuilder' => 'Phobject', 'DifferentialChangesetHTMLRenderer' => 'DifferentialChangesetRenderer', 'DifferentialChangesetListView' => 'AphrontView', 'DifferentialChangesetOneUpRenderer' => 'DifferentialChangesetHTMLRenderer', 'DifferentialChangesetOneUpTestRenderer' => 'DifferentialChangesetTestRenderer', + 'DifferentialChangesetParser' => 'Phobject', 'DifferentialChangesetParserTestCase' => 'PhabricatorTestCase', 'DifferentialChangesetQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', + 'DifferentialChangesetRenderer' => 'Phobject', 'DifferentialChangesetTestRenderer' => 'DifferentialChangesetRenderer', 'DifferentialChangesetTwoUpRenderer' => 'DifferentialChangesetHTMLRenderer', 'DifferentialChangesetTwoUpTestRenderer' => 'DifferentialChangesetTestRenderer', @@ -3586,6 +3652,7 @@ phutil_register_library_map(array( 'DifferentialCloseConduitAPIMethod' => 'DifferentialConduitAPIMethod', 'DifferentialCommentPreviewController' => 'DifferentialController', 'DifferentialCommentSaveController' => 'DifferentialController', + 'DifferentialCommitMessageParser' => 'Phobject', 'DifferentialCommitMessageParserTestCase' => 'PhabricatorTestCase', 'DifferentialCommitsField' => 'DifferentialCustomField', 'DifferentialConduitAPIMethod' => 'ConduitAPIMethod', @@ -3641,6 +3708,7 @@ phutil_register_library_map(array( 'DifferentialGetRawDiffConduitAPIMethod' => 'DifferentialConduitAPIMethod', 'DifferentialGetRevisionCommentsConduitAPIMethod' => 'DifferentialConduitAPIMethod', 'DifferentialGetRevisionConduitAPIMethod' => 'DifferentialConduitAPIMethod', + 'DifferentialGetWorkingCopy' => 'Phobject', 'DifferentialGitHubLandingStrategy' => 'DifferentialLandingStrategy', 'DifferentialGitSVNIDField' => 'DifferentialCustomField', 'DifferentialHiddenComment' => 'DifferentialDAO', @@ -3652,18 +3720,24 @@ phutil_register_library_map(array( 'DifferentialDAO', 'PhabricatorPolicyInterface', ), + 'DifferentialHunkParser' => 'Phobject', 'DifferentialHunkParserTestCase' => 'PhabricatorTestCase', 'DifferentialHunkQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'DifferentialHunkTestCase' => 'PhutilTestCase', - 'DifferentialInlineComment' => 'PhabricatorInlineCommentInterface', + 'DifferentialInlineComment' => array( + 'Phobject', + 'PhabricatorInlineCommentInterface', + ), 'DifferentialInlineCommentEditController' => 'PhabricatorInlineCommentController', 'DifferentialInlineCommentPreviewController' => 'PhabricatorInlineCommentPreviewController', 'DifferentialInlineCommentQuery' => 'PhabricatorOffsetPagedQuery', 'DifferentialJIRAIssuesField' => 'DifferentialStoredCustomField', 'DifferentialLandingActionMenuEventListener' => 'PhabricatorEventListener', + 'DifferentialLandingStrategy' => 'Phobject', 'DifferentialLegacyHunk' => 'DifferentialHunk', 'DifferentialLineAdjustmentMap' => 'Phobject', 'DifferentialLintField' => 'DifferentialCustomField', + 'DifferentialLintStatus' => 'Phobject', 'DifferentialLocalCommitsView' => 'AphrontView', 'DifferentialManiphestTasksField' => 'DifferentialCoreCustomField', 'DifferentialModernHunk' => 'DifferentialHunk', @@ -3676,6 +3750,8 @@ phutil_register_library_map(array( 'DifferentialProjectsField' => 'DifferentialCoreCustomField', 'DifferentialQueryConduitAPIMethod' => 'DifferentialConduitAPIMethod', 'DifferentialQueryDiffsConduitAPIMethod' => 'DifferentialConduitAPIMethod', + 'DifferentialRawDiffRenderer' => 'Phobject', + 'DifferentialReleephRequestFieldSpecification' => 'Phobject', 'DifferentialRemarkupRule' => 'PhabricatorObjectRemarkupRule', 'DifferentialReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler', 'DifferentialRepositoryField' => 'DifferentialCoreCustomField', @@ -3684,7 +3760,9 @@ phutil_register_library_map(array( 'DifferentialResultsTableView' => 'AphrontView', 'DifferentialRevertPlanField' => 'DifferentialStoredCustomField', 'DifferentialReviewedByField' => 'DifferentialCoreCustomField', + 'DifferentialReviewer' => 'Phobject', 'DifferentialReviewerForRevisionEdgeType' => 'PhabricatorEdgeType', + 'DifferentialReviewerStatus' => 'Phobject', 'DifferentialReviewersField' => 'DifferentialCoreCustomField', 'DifferentialReviewersView' => 'AphrontView', 'DifferentialRevision' => array( @@ -3703,6 +3781,7 @@ phutil_register_library_map(array( 'PhabricatorProjectInterface', ), 'DifferentialRevisionCloseDetailsController' => 'DifferentialController', + 'DifferentialRevisionControlSystem' => 'Phobject', 'DifferentialRevisionDependedOnByRevisionEdgeType' => 'PhabricatorEdgeType', 'DifferentialRevisionDependsOnRevisionEdgeType' => 'PhabricatorEdgeType', 'DifferentialRevisionDetailView' => 'AphrontView', @@ -3718,6 +3797,7 @@ phutil_register_library_map(array( 'DifferentialRevisionPHIDType' => 'PhabricatorPHIDType', 'DifferentialRevisionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'DifferentialRevisionSearchEngine' => 'PhabricatorApplicationSearchEngine', + 'DifferentialRevisionStatus' => 'Phobject', 'DifferentialRevisionUpdateHistoryView' => 'AphrontView', 'DifferentialRevisionViewController' => 'DifferentialController', 'DifferentialSchemaSpec' => 'PhabricatorConfigSchemaSpec', @@ -3734,6 +3814,8 @@ phutil_register_library_map(array( 'DifferentialTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'DifferentialTransactionView' => 'PhabricatorApplicationTransactionView', 'DifferentialUnitField' => 'DifferentialCustomField', + 'DifferentialUnitStatus' => 'Phobject', + 'DifferentialUnitTestResult' => 'Phobject', 'DifferentialUpdateRevisionConduitAPIMethod' => 'DifferentialConduitAPIMethod', 'DifferentialUpdateUnitResultsConduitAPIMethod' => 'DifferentialConduitAPIMethod', 'DifferentialViewPolicyField' => 'DifferentialCoreCustomField', @@ -3746,6 +3828,7 @@ phutil_register_library_map(array( 'DiffusionBrowseFileController' => 'DiffusionBrowseController', 'DiffusionBrowseMainController' => 'DiffusionBrowseController', 'DiffusionBrowseQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod', + 'DiffusionBrowseResultSet' => 'Phobject', 'DiffusionBrowseSearchController' => 'DiffusionBrowseController', 'DiffusionBrowseTableView' => 'DiffusionView', 'DiffusionCachedResolveRefsQuery' => 'DiffusionLowLevelQuery', @@ -3781,12 +3864,16 @@ phutil_register_library_map(array( 'DiffusionEmptyResultView' => 'DiffusionView', 'DiffusionExistsQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod', 'DiffusionExternalController' => 'DiffusionController', + 'DiffusionExternalSymbolQuery' => 'Phobject', + 'DiffusionExternalSymbolsSource' => 'Phobject', + 'DiffusionFileContent' => 'Phobject', 'DiffusionFileContentQuery' => 'DiffusionQuery', 'DiffusionFileContentQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod', 'DiffusionFindSymbolsConduitAPIMethod' => 'DiffusionConduitAPIMethod', 'DiffusionGetCommitsConduitAPIMethod' => 'DiffusionConduitAPIMethod', 'DiffusionGetLintMessagesConduitAPIMethod' => 'DiffusionConduitAPIMethod', 'DiffusionGetRecentCommitsByPathConduitAPIMethod' => 'DiffusionConduitAPIMethod', + 'DiffusionGitBranch' => 'Phobject', 'DiffusionGitBranchTestCase' => 'PhabricatorTestCase', 'DiffusionGitFileContentQuery' => 'DiffusionFileContentQuery', 'DiffusionGitFileContentQueryTestCase' => 'PhabricatorTestCase', @@ -3807,6 +3894,7 @@ phutil_register_library_map(array( 'DiffusionLintController' => 'DiffusionController', 'DiffusionLintCountQuery' => 'PhabricatorQuery', 'DiffusionLintDetailsController' => 'DiffusionController', + 'DiffusionLintSaveRunner' => 'Phobject', 'DiffusionLookSoonConduitAPIMethod' => 'DiffusionConduitAPIMethod', 'DiffusionLowLevelCommitFieldsQuery' => 'DiffusionLowLevelQuery', 'DiffusionLowLevelCommitQuery' => 'DiffusionLowLevelQuery', @@ -3823,11 +3911,16 @@ phutil_register_library_map(array( 'DiffusionMercurialSSHWorkflow' => 'DiffusionSSHWorkflow', 'DiffusionMercurialServeSSHWorkflow' => 'DiffusionMercurialSSHWorkflow', 'DiffusionMercurialWireClientSSHProtocolChannel' => 'PhutilProtocolChannel', + 'DiffusionMercurialWireProtocol' => 'Phobject', 'DiffusionMercurialWireSSHTestCase' => 'PhabricatorTestCase', 'DiffusionMergedCommitsQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod', 'DiffusionMirrorDeleteController' => 'DiffusionController', 'DiffusionMirrorEditController' => 'DiffusionController', + 'DiffusionPathChange' => 'Phobject', + 'DiffusionPathChangeQuery' => 'Phobject', 'DiffusionPathCompleteController' => 'DiffusionController', + 'DiffusionPathIDQuery' => 'Phobject', + 'DiffusionPathQuery' => 'Phobject', 'DiffusionPathQueryTestCase' => 'PhabricatorTestCase', 'DiffusionPathTreeController' => 'DiffusionController', 'DiffusionPathValidateController' => 'DiffusionController', @@ -3848,6 +3941,7 @@ phutil_register_library_map(array( 'DiffusionRefNotFoundException' => 'Exception', 'DiffusionRefTableController' => 'DiffusionController', 'DiffusionRefsQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod', + 'DiffusionRenameHistoryQuery' => 'Phobject', 'DiffusionRepositoryByIDRemarkupRule' => 'PhabricatorObjectRemarkupRule', 'DiffusionRepositoryController' => 'DiffusionController', 'DiffusionRepositoryCreateController' => 'DiffusionRepositoryEditController', @@ -3869,9 +3963,12 @@ phutil_register_library_map(array( 'DiffusionRepositoryEditUpdateController' => 'DiffusionRepositoryEditController', 'DiffusionRepositoryListController' => 'DiffusionController', 'DiffusionRepositoryNewController' => 'DiffusionController', + 'DiffusionRepositoryPath' => 'Phobject', 'DiffusionRepositoryRef' => 'Phobject', 'DiffusionRepositoryRemarkupRule' => 'PhabricatorObjectRemarkupRule', 'DiffusionRepositorySymbolsController' => 'DiffusionRepositoryEditController', + 'DiffusionRepositoryTag' => 'Phobject', + 'DiffusionRequest' => 'Phobject', 'DiffusionResolveRefsConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod', 'DiffusionResolveUserQuery' => 'Phobject', 'DiffusionSSHWorkflow' => 'PhabricatorSSHWorkflow', @@ -3896,14 +3993,17 @@ phutil_register_library_map(array( 'DiffusionUpdateCoverageConduitAPIMethod' => 'DiffusionConduitAPIMethod', 'DiffusionView' => 'AphrontView', 'DivinerArticleAtomizer' => 'DivinerAtomizer', + 'DivinerAtom' => 'Phobject', 'DivinerAtomCache' => 'DivinerDiskCache', 'DivinerAtomController' => 'DivinerController', 'DivinerAtomListController' => 'DivinerController', 'DivinerAtomPHIDType' => 'PhabricatorPHIDType', 'DivinerAtomQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', + 'DivinerAtomRef' => 'Phobject', 'DivinerAtomSearchEngine' => 'PhabricatorApplicationSearchEngine', 'DivinerAtomSearchIndexer' => 'PhabricatorSearchDocumentIndexer', 'DivinerAtomizeWorkflow' => 'DivinerWorkflow', + 'DivinerAtomizer' => 'Phobject', 'DivinerBookController' => 'DivinerController', 'DivinerBookItemView' => 'AphrontTagView', 'DivinerBookPHIDType' => 'PhabricatorPHIDType', @@ -3912,6 +4012,7 @@ phutil_register_library_map(array( 'DivinerController' => 'PhabricatorController', 'DivinerDAO' => 'PhabricatorLiskDAO', 'DivinerDefaultRenderer' => 'DivinerRenderer', + 'DivinerDiskCache' => 'Phobject', 'DivinerFileAtomizer' => 'DivinerAtomizer', 'DivinerFindController' => 'DivinerController', 'DivinerGenerateWorkflow' => 'DivinerWorkflow', @@ -3932,6 +4033,8 @@ phutil_register_library_map(array( 'DivinerPHPAtomizer' => 'DivinerAtomizer', 'DivinerParameterTableView' => 'AphrontTagView', 'DivinerPublishCache' => 'DivinerDiskCache', + 'DivinerPublisher' => 'Phobject', + 'DivinerRenderer' => 'Phobject', 'DivinerReturnTableView' => 'AphrontTagView', 'DivinerSectionView' => 'AphrontTagView', 'DivinerStaticPublisher' => 'DivinerPublisher', @@ -3949,6 +4052,7 @@ phutil_register_library_map(array( 'PhabricatorPolicyInterface', ), 'DoorkeeperExternalObjectQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', + 'DoorkeeperFeedStoryPublisher' => 'Phobject', 'DoorkeeperFeedWorker' => 'FeedPushWorker', 'DoorkeeperImportEngine' => 'Phobject', 'DoorkeeperJIRAFeedWorker' => 'DoorkeeperFeedWorker', @@ -3976,21 +4080,26 @@ phutil_register_library_map(array( 'DrydockBlueprintCustomField' => 'PhabricatorCustomField', 'DrydockBlueprintEditController' => 'DrydockBlueprintController', 'DrydockBlueprintEditor' => 'PhabricatorApplicationTransactionEditor', + 'DrydockBlueprintImplementation' => 'Phobject', + 'DrydockBlueprintImplementationTestCase' => 'PhabricatorTestCase', 'DrydockBlueprintListController' => 'DrydockBlueprintController', 'DrydockBlueprintPHIDType' => 'PhabricatorPHIDType', 'DrydockBlueprintQuery' => 'DrydockQuery', + 'DrydockBlueprintScopeGuard' => 'Phobject', 'DrydockBlueprintSearchEngine' => 'PhabricatorApplicationSearchEngine', 'DrydockBlueprintTransaction' => 'PhabricatorApplicationTransaction', 'DrydockBlueprintTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'DrydockBlueprintViewController' => 'DrydockBlueprintController', 'DrydockCommandInterface' => 'DrydockInterface', 'DrydockConsoleController' => 'DrydockController', + 'DrydockConstants' => 'Phobject', 'DrydockController' => 'PhabricatorController', 'DrydockCreateBlueprintsCapability' => 'PhabricatorPolicyCapability', 'DrydockDAO' => 'PhabricatorLiskDAO', 'DrydockDefaultEditCapability' => 'PhabricatorPolicyCapability', 'DrydockDefaultViewCapability' => 'PhabricatorPolicyCapability', 'DrydockFilesystemInterface' => 'DrydockInterface', + 'DrydockInterface' => 'Phobject', 'DrydockLease' => array( 'DrydockDAO', 'PhabricatorPolicyInterface', @@ -4044,6 +4153,7 @@ phutil_register_library_map(array( 'FeedPublisherWorker' => 'FeedPushWorker', 'FeedPushWorker' => 'PhabricatorWorker', 'FeedQueryConduitAPIMethod' => 'FeedConduitAPIMethod', + 'FeedStoryNotificationGarbageCollector' => 'PhabricatorGarbageCollector', 'FileAllocateConduitAPIMethod' => 'FileConduitAPIMethod', 'FileConduitAPIMethod' => 'ConduitAPIMethod', 'FileCreateMailReceiver' => 'PhabricatorMailReceiver', @@ -4162,6 +4272,8 @@ phutil_register_library_map(array( ), 'HarbormasterBuildStepCustomField' => 'PhabricatorCustomField', 'HarbormasterBuildStepEditor' => 'PhabricatorApplicationTransactionEditor', + 'HarbormasterBuildStepImplementation' => 'Phobject', + 'HarbormasterBuildStepImplementationTestCase' => 'PhabricatorTestCase', 'HarbormasterBuildStepPHIDType' => 'PhabricatorPHIDType', 'HarbormasterBuildStepQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'HarbormasterBuildStepTransaction' => 'PhabricatorApplicationTransaction', @@ -4227,26 +4339,33 @@ phutil_register_library_map(array( 'HarbormasterWaitForPreviousBuildStepImplementation' => 'HarbormasterBuildStepImplementation', 'HarbormasterWorker' => 'PhabricatorWorker', 'HeraldAction' => 'HeraldDAO', + 'HeraldAdapter' => 'Phobject', 'HeraldApplyTranscript' => 'Phobject', 'HeraldCommitAdapter' => 'HeraldAdapter', 'HeraldCondition' => 'HeraldDAO', + 'HeraldConditionTranscript' => 'Phobject', 'HeraldController' => 'PhabricatorController', + 'HeraldCustomAction' => 'Phobject', 'HeraldDAO' => 'PhabricatorLiskDAO', 'HeraldDifferentialAdapter' => 'HeraldAdapter', 'HeraldDifferentialDiffAdapter' => 'HeraldDifferentialAdapter', 'HeraldDifferentialRevisionAdapter' => 'HeraldDifferentialAdapter', 'HeraldDisableController' => 'HeraldController', + 'HeraldEffect' => 'Phobject', + 'HeraldEngine' => 'Phobject', 'HeraldInvalidActionException' => 'Exception', 'HeraldInvalidConditionException' => 'Exception', 'HeraldManageGlobalRulesCapability' => 'PhabricatorPolicyCapability', 'HeraldManiphestTaskAdapter' => 'HeraldAdapter', 'HeraldNewController' => 'HeraldController', + 'HeraldObjectTranscript' => 'Phobject', 'HeraldPholioMockAdapter' => 'HeraldAdapter', 'HeraldPreCommitAdapter' => 'HeraldAdapter', 'HeraldPreCommitContentAdapter' => 'HeraldPreCommitAdapter', 'HeraldPreCommitRefAdapter' => 'HeraldPreCommitAdapter', 'HeraldRecursiveConditionsException' => 'Exception', 'HeraldRemarkupRule' => 'PhabricatorObjectRemarkupRule', + 'HeraldRepetitionPolicyConfig' => 'Phobject', 'HeraldRule' => array( 'HeraldDAO', 'PhabricatorApplicationTransactionInterface', @@ -4263,6 +4382,8 @@ phutil_register_library_map(array( 'HeraldRuleTestCase' => 'PhabricatorTestCase', 'HeraldRuleTransaction' => 'PhabricatorApplicationTransaction', 'HeraldRuleTransactionComment' => 'PhabricatorApplicationTransactionComment', + 'HeraldRuleTranscript' => 'Phobject', + 'HeraldRuleTypeConfig' => 'Phobject', 'HeraldRuleViewController' => 'HeraldController', 'HeraldSchemaSpec' => 'PhabricatorConfigSchemaSpec', 'HeraldTestConsoleController' => 'HeraldController', @@ -4278,6 +4399,7 @@ phutil_register_library_map(array( 'HeraldTranscriptQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'HeraldTranscriptSearchEngine' => 'PhabricatorApplicationSearchEngine', 'HeraldTranscriptTestCase' => 'PhabricatorTestCase', + 'Javelin' => 'Phobject', 'JavelinReactorUIExample' => 'PhabricatorUIExample', 'JavelinUIExample' => 'PhabricatorUIExample', 'JavelinViewExampleServerView' => 'AphrontView', @@ -4329,6 +4451,8 @@ phutil_register_library_map(array( 'LegalpadTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'LegalpadTransactionView' => 'PhabricatorApplicationTransactionView', 'LiskChunkTestCase' => 'PhabricatorTestCase', + 'LiskDAO' => 'Phobject', + 'LiskDAOSet' => 'Phobject', 'LiskDAOTestCase' => 'PhabricatorTestCase', 'LiskEphemeralObjectException' => 'Exception', 'LiskFixtureTestCase' => 'PhabricatorTestCase', @@ -4351,6 +4475,7 @@ phutil_register_library_map(array( 'ManiphestCustomField', 'PhabricatorStandardCustomFieldInterface', ), + 'ManiphestConstants' => 'Phobject', 'ManiphestController' => 'PhabricatorController', 'ManiphestCreateMailReceiver' => 'PhabricatorMailReceiver', 'ManiphestCreateTaskConduitAPIMethod' => 'ManiphestConduitAPIMethod', @@ -4370,6 +4495,8 @@ phutil_register_library_map(array( 'ManiphestEditStatusCapability' => 'PhabricatorPolicyCapability', 'ManiphestEmailCommand' => 'MetaMTAEmailTransactionCommand', 'ManiphestExcelDefaultFormat' => 'ManiphestExcelFormat', + 'ManiphestExcelFormat' => 'Phobject', + 'ManiphestExcelFormatTestCase' => 'PhabricatorTestCase', 'ManiphestExportController' => 'ManiphestController', 'ManiphestGetTaskTransactionsConduitAPIMethod' => 'ManiphestConduitAPIMethod', 'ManiphestHovercardEventListener' => 'PhabricatorEventListener', @@ -4400,7 +4527,9 @@ phutil_register_library_map(array( 'PhabricatorDestructibleInterface', 'PhabricatorApplicationTransactionInterface', 'PhabricatorProjectInterface', + 'PhabricatorSpacesInterface', ), + 'ManiphestTaskAuthorPolicyRule' => 'PhabricatorPolicyRule', 'ManiphestTaskClosedStatusDatasource' => 'PhabricatorTypeaheadDatasource', 'ManiphestTaskDependedOnByTaskEdgeType' => 'PhabricatorEdgeType', 'ManiphestTaskDependsOnTaskEdgeType' => 'PhabricatorEdgeType', @@ -4432,11 +4561,14 @@ phutil_register_library_map(array( 'ManiphestTransactionSaveController' => 'ManiphestController', 'ManiphestUpdateConduitAPIMethod' => 'ManiphestConduitAPIMethod', 'ManiphestView' => 'AphrontView', + 'MetaMTAConstants' => 'Phobject', 'MetaMTAEmailTransactionCommand' => 'Phobject', + 'MetaMTAEmailTransactionCommandTestCase' => 'PhabricatorTestCase', 'MetaMTAMailReceivedGarbageCollector' => 'PhabricatorGarbageCollector', 'MetaMTAMailSentGarbageCollector' => 'PhabricatorGarbageCollector', 'MetaMTAReceivedMailStatus' => 'MetaMTAConstants', 'MultimeterContext' => 'MultimeterDimension', + 'MultimeterControl' => 'Phobject', 'MultimeterController' => 'PhabricatorController', 'MultimeterDAO' => 'PhabricatorLiskDAO', 'MultimeterDimension' => 'MultimeterDAO', @@ -4505,6 +4637,7 @@ phutil_register_library_map(array( 'NuanceSourceDefaultEditCapability' => 'PhabricatorPolicyCapability', 'NuanceSourceDefaultViewCapability' => 'PhabricatorPolicyCapability', 'NuanceSourceDefinition' => 'Phobject', + 'NuanceSourceDefinitionTestCase' => 'PhabricatorTestCase', 'NuanceSourceEditController' => 'NuanceController', 'NuanceSourceEditor' => 'PhabricatorApplicationTransactionEditor', 'NuanceSourceListController' => 'NuanceController', @@ -4524,6 +4657,7 @@ phutil_register_library_map(array( 'PHIDInfoConduitAPIMethod' => 'PHIDConduitAPIMethod', 'PHIDLookupConduitAPIMethod' => 'PHIDConduitAPIMethod', 'PHIDQueryConduitAPIMethod' => 'PHIDConduitAPIMethod', + 'PHUI' => 'Phobject', 'PHUIActionPanelExample' => 'PhabricatorUIExample', 'PHUIActionPanelView' => 'AphrontTagView', 'PHUIBoxExample' => 'PhabricatorUIExample', @@ -4624,17 +4758,18 @@ phutil_register_library_map(array( 'PassphraseCredentialTransactionEditor' => 'PhabricatorApplicationTransactionEditor', 'PassphraseCredentialTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'PassphraseCredentialType' => 'Phobject', - 'PassphraseCredentialTypePassword' => 'PassphraseCredentialType', - 'PassphraseCredentialTypeSSHGeneratedKey' => 'PassphraseCredentialTypeSSHPrivateKey', - 'PassphraseCredentialTypeSSHPrivateKey' => 'PassphraseCredentialType', - 'PassphraseCredentialTypeSSHPrivateKeyFile' => 'PassphraseCredentialTypeSSHPrivateKey', - 'PassphraseCredentialTypeSSHPrivateKeyText' => 'PassphraseCredentialTypeSSHPrivateKey', + 'PassphraseCredentialTypeTestCase' => 'PhabricatorTestCase', 'PassphraseCredentialViewController' => 'PassphraseController', 'PassphraseDAO' => 'PhabricatorLiskDAO', + 'PassphrasePasswordCredentialType' => 'PassphraseCredentialType', 'PassphrasePasswordKey' => 'PassphraseAbstractKey', 'PassphraseQueryConduitAPIMethod' => 'PassphraseConduitAPIMethod', 'PassphraseRemarkupRule' => 'PhabricatorObjectRemarkupRule', + 'PassphraseSSHGeneratedKeyCredentialType' => 'PassphraseSSHPrivateKeyCredentialType', 'PassphraseSSHKey' => 'PassphraseAbstractKey', + 'PassphraseSSHPrivateKeyCredentialType' => 'PassphraseCredentialType', + 'PassphraseSSHPrivateKeyFileCredentialType' => 'PassphraseSSHPrivateKeyCredentialType', + 'PassphraseSSHPrivateKeyTextCredentialType' => 'PassphraseSSHPrivateKeyCredentialType', 'PassphraseSchemaSpec' => 'PhabricatorConfigSchemaSpec', 'PassphraseSearchIndexer' => 'PhabricatorSearchDocumentIndexer', 'PassphraseSecret' => 'PassphraseDAO', @@ -4654,6 +4789,7 @@ phutil_register_library_map(array( 'Phabricator404Controller' => 'PhabricatorController', 'PhabricatorAWSConfigOptions' => 'PhabricatorApplicationConfigOptions', 'PhabricatorAccessControlTestCase' => 'PhabricatorTestCase', + 'PhabricatorAccessLog' => 'Phobject', 'PhabricatorAccessLogConfigOptions' => 'PhabricatorApplicationConfigOptions', 'PhabricatorAccountSettingsPanel' => 'PhabricatorSettingsPanel', 'PhabricatorActionListView' => 'AphrontView', @@ -4673,10 +4809,14 @@ phutil_register_library_map(array( 'PhabricatorAphrontBarUIExample' => 'PhabricatorUIExample', 'PhabricatorAphrontViewTestCase' => 'PhabricatorTestCase', 'PhabricatorAppSearchEngine' => 'PhabricatorApplicationSearchEngine', - 'PhabricatorApplication' => 'PhabricatorPolicyInterface', + 'PhabricatorApplication' => array( + 'Phobject', + 'PhabricatorPolicyInterface', + ), 'PhabricatorApplicationApplicationPHIDType' => 'PhabricatorPHIDType', 'PhabricatorApplicationConfigOptions' => 'Phobject', 'PhabricatorApplicationConfigurationPanel' => 'Phobject', + 'PhabricatorApplicationConfigurationPanelTestCase' => 'PhabricatorTestCase', 'PhabricatorApplicationDatasource' => 'PhabricatorTypeaheadDatasource', 'PhabricatorApplicationDetailViewController' => 'PhabricatorApplicationsController', 'PhabricatorApplicationEditController' => 'PhabricatorApplicationsController', @@ -4686,7 +4826,9 @@ phutil_register_library_map(array( 'PhabricatorApplicationQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorApplicationSearchController' => 'PhabricatorSearchBaseController', 'PhabricatorApplicationSearchEngine' => 'Phobject', + 'PhabricatorApplicationSearchEngineTestCase' => 'PhabricatorTestCase', 'PhabricatorApplicationStatusView' => 'AphrontView', + 'PhabricatorApplicationTestCase' => 'PhabricatorTestCase', 'PhabricatorApplicationTransaction' => array( 'PhabricatorLiskDAO', 'PhabricatorPolicyInterface', @@ -4734,12 +4876,17 @@ phutil_register_library_map(array( 'PhabricatorAsanaConfigOptions' => 'PhabricatorApplicationConfigOptions', 'PhabricatorAsanaSubtaskHasObjectEdgeType' => 'PhabricatorEdgeType', 'PhabricatorAsanaTaskHasObjectEdgeType' => 'PhabricatorEdgeType', + 'PhabricatorAuditActionConstants' => 'Phobject', 'PhabricatorAuditAddCommentController' => 'PhabricatorAuditController', 'PhabricatorAuditApplication' => 'PhabricatorApplication', 'PhabricatorAuditCommentEditor' => 'PhabricatorEditor', + 'PhabricatorAuditCommitStatusConstants' => 'Phobject', 'PhabricatorAuditController' => 'PhabricatorController', 'PhabricatorAuditEditor' => 'PhabricatorApplicationTransactionEditor', - 'PhabricatorAuditInlineComment' => 'PhabricatorInlineCommentInterface', + 'PhabricatorAuditInlineComment' => array( + 'Phobject', + 'PhabricatorInlineCommentInterface', + ), 'PhabricatorAuditListController' => 'PhabricatorAuditController', 'PhabricatorAuditListView' => 'AphrontView', 'PhabricatorAuditMailReceiver' => 'PhabricatorObjectMailReceiver', @@ -4747,6 +4894,7 @@ phutil_register_library_map(array( 'PhabricatorAuditManagementWorkflow' => 'PhabricatorManagementWorkflow', 'PhabricatorAuditPreviewController' => 'PhabricatorAuditController', 'PhabricatorAuditReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler', + 'PhabricatorAuditStatusConstants' => 'Phobject', 'PhabricatorAuditTransaction' => 'PhabricatorApplicationTransaction', 'PhabricatorAuditTransactionComment' => 'PhabricatorApplicationTransactionComment', 'PhabricatorAuditTransactionQuery' => 'PhabricatorApplicationTransactionQuery', @@ -4764,8 +4912,10 @@ phutil_register_library_map(array( 'PhabricatorAuthEditController' => 'PhabricatorAuthProviderConfigController', 'PhabricatorAuthFactor' => 'Phobject', 'PhabricatorAuthFactorConfig' => 'PhabricatorAuthDAO', + 'PhabricatorAuthFactorTestCase' => 'PhabricatorTestCase', 'PhabricatorAuthFinishController' => 'PhabricatorAuthController', 'PhabricatorAuthHighSecurityRequiredException' => 'Exception', + 'PhabricatorAuthHighSecurityToken' => 'Phobject', 'PhabricatorAuthInvite' => array( 'PhabricatorUserDAO', 'PhabricatorPolicyInterface', @@ -4804,6 +4954,7 @@ phutil_register_library_map(array( 'PhabricatorAuthNewController' => 'PhabricatorAuthProviderConfigController', 'PhabricatorAuthOldOAuthRedirectController' => 'PhabricatorAuthController', 'PhabricatorAuthOneTimeLoginController' => 'PhabricatorAuthController', + 'PhabricatorAuthProvider' => 'Phobject', 'PhabricatorAuthProviderConfig' => array( 'PhabricatorAuthDAO', 'PhabricatorApplicationTransactionInterface', @@ -4860,10 +5011,13 @@ phutil_register_library_map(array( 'PhabricatorBotDebugLogHandler' => 'PhabricatorBotHandler', 'PhabricatorBotFeedNotificationHandler' => 'PhabricatorBotHandler', 'PhabricatorBotFlowdockProtocolAdapter' => 'PhabricatorStreamingProtocolAdapter', + 'PhabricatorBotHandler' => 'Phobject', 'PhabricatorBotLogHandler' => 'PhabricatorBotHandler', 'PhabricatorBotMacroHandler' => 'PhabricatorBotHandler', + 'PhabricatorBotMessage' => 'Phobject', 'PhabricatorBotObjectNameHandler' => 'PhabricatorBotHandler', 'PhabricatorBotSymbolHandler' => 'PhabricatorBotHandler', + 'PhabricatorBotTarget' => 'Phobject', 'PhabricatorBotUser' => 'PhabricatorBotTarget', 'PhabricatorBotWhatsNewHandler' => 'PhabricatorBotHandler', 'PhabricatorBritishEnglishTranslation' => 'PhutilTranslation', @@ -4878,6 +5032,7 @@ phutil_register_library_map(array( 'PhabricatorCacheSetupCheck' => 'PhabricatorSetupCheck', 'PhabricatorCacheSpec' => 'Phobject', 'PhabricatorCacheTTLGarbageCollector' => 'PhabricatorGarbageCollector', + 'PhabricatorCaches' => 'Phobject', 'PhabricatorCachesTestCase' => 'PhabricatorTestCase', 'PhabricatorCalendarApplication' => 'PhabricatorApplication', 'PhabricatorCalendarController' => 'PhabricatorController', @@ -5009,6 +5164,7 @@ phutil_register_library_map(array( 'PhabricatorConfigIgnoreController' => 'PhabricatorConfigController', 'PhabricatorConfigIssueListController' => 'PhabricatorConfigController', 'PhabricatorConfigIssueViewController' => 'PhabricatorConfigController', + 'PhabricatorConfigJSON' => 'Phobject', 'PhabricatorConfigJSONOptionType' => 'PhabricatorConfigOptionType', 'PhabricatorConfigKeySchema' => 'PhabricatorConfigStorageSchema', 'PhabricatorConfigListController' => 'PhabricatorConfigController', @@ -5023,12 +5179,14 @@ phutil_register_library_map(array( 'Phobject', 'PhabricatorMarkupInterface', ), + 'PhabricatorConfigOptionType' => 'Phobject', 'PhabricatorConfigProxySource' => 'PhabricatorConfigSource', 'PhabricatorConfigResponse' => 'AphrontStandaloneHTMLResponse', 'PhabricatorConfigSchemaQuery' => 'Phobject', 'PhabricatorConfigSchemaSpec' => 'Phobject', 'PhabricatorConfigServerSchema' => 'PhabricatorConfigStorageSchema', 'PhabricatorConfigSiteSource' => 'PhabricatorConfigProxySource', + 'PhabricatorConfigSource' => 'Phobject', 'PhabricatorConfigStackSource' => 'PhabricatorConfigSource', 'PhabricatorConfigStorageSchema' => 'Phobject', 'PhabricatorConfigTableSchema' => 'PhabricatorConfigStorageSchema', @@ -5040,6 +5198,7 @@ phutil_register_library_map(array( 'PhabricatorConpherencePreferencesSettingsPanel' => 'PhabricatorSettingsPanel', 'PhabricatorConpherenceThreadPHIDType' => 'PhabricatorPHIDType', 'PhabricatorConsoleApplication' => 'PhabricatorApplication', + 'PhabricatorContentSource' => 'Phobject', 'PhabricatorContentSourceView' => 'AphrontView', 'PhabricatorContributedToObjectEdgeType' => 'PhabricatorEdgeType', 'PhabricatorController' => 'AphrontController', @@ -5064,6 +5223,8 @@ phutil_register_library_map(array( 'PhabricatorCountdownViewController' => 'PhabricatorCountdownController', 'PhabricatorCredentialsUsedByObjectEdgeType' => 'PhabricatorEdgeType', 'PhabricatorCursorPagedPolicyAwareQuery' => 'PhabricatorPolicyAwareQuery', + 'PhabricatorCustomField' => 'Phobject', + 'PhabricatorCustomFieldAttachment' => 'Phobject', 'PhabricatorCustomFieldConfigOptionType' => 'PhabricatorConfigOptionType', 'PhabricatorCustomFieldDataNotAvailableException' => 'Exception', 'PhabricatorCustomFieldImplementationIncompleteException' => 'Exception', @@ -5104,6 +5265,7 @@ phutil_register_library_map(array( 'PhabricatorDaemonManagementStatusWorkflow' => 'PhabricatorDaemonManagementWorkflow', 'PhabricatorDaemonManagementStopWorkflow' => 'PhabricatorDaemonManagementWorkflow', 'PhabricatorDaemonManagementWorkflow' => 'PhabricatorManagementWorkflow', + 'PhabricatorDaemonReference' => 'Phobject', 'PhabricatorDaemonTaskGarbageCollector' => 'PhabricatorGarbageCollector', 'PhabricatorDaemonTasksTableView' => 'AphrontView', 'PhabricatorDaemonsApplication' => 'PhabricatorApplication', @@ -5126,6 +5288,7 @@ phutil_register_library_map(array( 'PhabricatorDashboardHistoryController' => 'PhabricatorDashboardController', 'PhabricatorDashboardInstall' => 'PhabricatorDashboardDAO', 'PhabricatorDashboardInstallController' => 'PhabricatorDashboardController', + 'PhabricatorDashboardLayoutConfig' => 'Phobject', 'PhabricatorDashboardListController' => 'PhabricatorDashboardController', 'PhabricatorDashboardManageController' => 'PhabricatorDashboardController', 'PhabricatorDashboardMovePanelController' => 'PhabricatorDashboardController', @@ -5182,6 +5345,7 @@ phutil_register_library_map(array( 'PhabricatorDeveloperPreferencesSettingsPanel' => 'PhabricatorSettingsPanel', 'PhabricatorDiffInlineCommentQuery' => 'PhabricatorApplicationTransactionCommentQuery', 'PhabricatorDiffPreferencesSettingsPanel' => 'PhabricatorSettingsPanel', + 'PhabricatorDifferenceEngine' => 'Phobject', 'PhabricatorDifferentialApplication' => 'PhabricatorApplication', 'PhabricatorDifferentialConfigOptions' => 'PhabricatorApplicationConfigOptions', 'PhabricatorDifferentialRevisionTestDataGenerator' => 'PhabricatorTestDataGenerator', @@ -5197,12 +5361,14 @@ phutil_register_library_map(array( 'PhabricatorDraftDAO' => 'PhabricatorLiskDAO', 'PhabricatorDrydockApplication' => 'PhabricatorApplication', 'PhabricatorEdgeConfig' => 'PhabricatorEdgeConstants', + 'PhabricatorEdgeConstants' => 'Phobject', 'PhabricatorEdgeCycleException' => 'Exception', 'PhabricatorEdgeEditor' => 'Phobject', 'PhabricatorEdgeGraph' => 'AbstractDirectedGraph', 'PhabricatorEdgeQuery' => 'PhabricatorQuery', 'PhabricatorEdgeTestCase' => 'PhabricatorTestCase', 'PhabricatorEdgeType' => 'Phobject', + 'PhabricatorEdgeTypeTestCase' => 'PhabricatorTestCase', 'PhabricatorEditor' => 'Phobject', 'PhabricatorElasticSearchEngine' => 'PhabricatorSearchEngine', 'PhabricatorElasticSearchSetupCheck' => 'PhabricatorSetupCheck', @@ -5214,8 +5380,10 @@ phutil_register_library_map(array( 'PhabricatorEmbedFileRemarkupRule' => 'PhabricatorObjectRemarkupRule', 'PhabricatorEmojiRemarkupRule' => 'PhutilRemarkupRule', 'PhabricatorEmptyQueryException' => 'Exception', + 'PhabricatorEnv' => 'Phobject', 'PhabricatorEnvTestCase' => 'PhabricatorTestCase', 'PhabricatorEvent' => 'PhutilEvent', + 'PhabricatorEventEngine' => 'Phobject', 'PhabricatorEventListener' => 'PhutilEventListener', 'PhabricatorEventType' => 'PhutilEventType', 'PhabricatorExampleEventListener' => 'PhabricatorEventListener', @@ -5237,6 +5405,8 @@ phutil_register_library_map(array( 'PhabricatorFactCursor' => 'PhabricatorFactDAO', 'PhabricatorFactDAO' => 'PhabricatorLiskDAO', 'PhabricatorFactDaemon' => 'PhabricatorDaemon', + 'PhabricatorFactEngine' => 'Phobject', + 'PhabricatorFactEngineTestCase' => 'PhabricatorTestCase', 'PhabricatorFactHomeController' => 'PhabricatorFactController', 'PhabricatorFactLastUpdatedEngine' => 'PhabricatorFactEngine', 'PhabricatorFactManagementAnalyzeWorkflow' => 'PhabricatorFactManagementWorkflow', @@ -5247,8 +5417,10 @@ phutil_register_library_map(array( 'PhabricatorFactManagementWorkflow' => 'PhabricatorManagementWorkflow', 'PhabricatorFactRaw' => 'PhabricatorFactDAO', 'PhabricatorFactSimpleSpec' => 'PhabricatorFactSpec', + 'PhabricatorFactSpec' => 'Phobject', 'PhabricatorFactUpdateIterator' => 'PhutilBufferedIterator', 'PhabricatorFeedApplication' => 'PhabricatorApplication', + 'PhabricatorFeedBuilder' => 'Phobject', 'PhabricatorFeedConfigOptions' => 'PhabricatorApplicationConfigOptions', 'PhabricatorFeedController' => 'PhabricatorController', 'PhabricatorFeedDAO' => 'PhabricatorLiskDAO', @@ -5260,11 +5432,13 @@ phutil_register_library_map(array( 'PhabricatorFeedQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorFeedSearchEngine' => 'PhabricatorApplicationSearchEngine', 'PhabricatorFeedStory' => array( + 'Phobject', 'PhabricatorPolicyInterface', 'PhabricatorMarkupInterface', ), 'PhabricatorFeedStoryData' => 'PhabricatorFeedDAO', 'PhabricatorFeedStoryNotification' => 'PhabricatorFeedDAO', + 'PhabricatorFeedStoryPublisher' => 'Phobject', 'PhabricatorFeedStoryReference' => 'PhabricatorFeedDAO', 'PhabricatorFile' => array( 'PhabricatorFileDAO', @@ -5275,6 +5449,7 @@ phutil_register_library_map(array( 'PhabricatorPolicyInterface', 'PhabricatorDestructibleInterface', ), + 'PhabricatorFileBundleLoader' => 'Phobject', 'PhabricatorFileChunk' => array( 'PhabricatorFileDAO', 'PhabricatorPolicyInterface', @@ -5313,6 +5488,8 @@ phutil_register_library_map(array( 'PhabricatorFileSearchEngine' => 'PhabricatorApplicationSearchEngine', 'PhabricatorFileStorageBlob' => 'PhabricatorFileDAO', 'PhabricatorFileStorageConfigurationException' => 'Exception', + 'PhabricatorFileStorageEngine' => 'Phobject', + 'PhabricatorFileStorageEngineTestCase' => 'PhabricatorTestCase', 'PhabricatorFileTemporaryGarbageCollector' => 'PhabricatorGarbageCollector', 'PhabricatorFileTestCase' => 'PhabricatorTestCase', 'PhabricatorFileTestDataGenerator' => 'PhabricatorTestDataGenerator', @@ -5323,6 +5500,7 @@ phutil_register_library_map(array( 'PhabricatorFileTransform' => 'Phobject', 'PhabricatorFileTransformController' => 'PhabricatorFileController', 'PhabricatorFileTransformListController' => 'PhabricatorFileController', + 'PhabricatorFileTransformTestCase' => 'PhabricatorTestCase', 'PhabricatorFileUploadController' => 'PhabricatorFileController', 'PhabricatorFileUploadDialogController' => 'PhabricatorFileController', 'PhabricatorFileUploadException' => 'Exception', @@ -5343,6 +5521,7 @@ phutil_register_library_map(array( 'PhabricatorPolicyInterface', ), 'PhabricatorFlagColor' => 'PhabricatorFlagConstants', + 'PhabricatorFlagConstants' => 'Phobject', 'PhabricatorFlagController' => 'PhabricatorController', 'PhabricatorFlagDAO' => 'PhabricatorLiskDAO', 'PhabricatorFlagDeleteController' => 'PhabricatorFlagController', @@ -5370,6 +5549,7 @@ phutil_register_library_map(array( 'ArrayAccess', 'Countable', ), + 'PhabricatorHandleObjectSelectorDataView' => 'Phobject', 'PhabricatorHandlePool' => 'Phobject', 'PhabricatorHandlePoolTestCase' => 'PhabricatorTestCase', 'PhabricatorHandleQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', @@ -5395,6 +5575,7 @@ phutil_register_library_map(array( 'PhabricatorIRCProtocolAdapter' => 'PhabricatorProtocolAdapter', 'PhabricatorIconRemarkupRule' => 'PhutilRemarkupRule', 'PhabricatorImageMacroRemarkupRule' => 'PhutilRemarkupRule', + 'PhabricatorImageTransformer' => 'Phobject', 'PhabricatorImagemagickSetupCheck' => 'PhabricatorSetupCheck', 'PhabricatorInfrastructureTestCase' => 'PhabricatorTestCase', 'PhabricatorInlineCommentController' => 'PhabricatorController', @@ -5405,9 +5586,11 @@ phutil_register_library_map(array( 'PhabricatorInternationalizationManagementWorkflow' => 'PhabricatorManagementWorkflow', 'PhabricatorInvalidConfigSetupCheck' => 'PhabricatorSetupCheck', 'PhabricatorIteratedMD5PasswordHasher' => 'PhabricatorPasswordHasher', + 'PhabricatorIteratedMD5PasswordHasherTestCase' => 'PhabricatorTestCase', 'PhabricatorJIRAAuthProvider' => 'PhabricatorOAuth1AuthProvider', 'PhabricatorJavelinLinter' => 'ArcanistLinter', 'PhabricatorJiraIssueHasObjectEdgeType' => 'PhabricatorEdgeType', + 'PhabricatorJumpNavHandler' => 'Phobject', 'PhabricatorKeyValueDatabaseCache' => 'PhutilKeyValueCache', 'PhabricatorLDAPAuthProvider' => 'PhabricatorAuthProvider', 'PhabricatorLegalpadApplication' => 'PhabricatorApplication', @@ -5415,10 +5598,12 @@ phutil_register_library_map(array( 'PhabricatorLegalpadDocumentPHIDType' => 'PhabricatorPHIDType', 'PhabricatorLegalpadSignaturePolicyRule' => 'PhabricatorPolicyRule', 'PhabricatorLibraryTestCase' => 'PhutilLibraryTestCase', + 'PhabricatorLipsumArtist' => 'Phobject', 'PhabricatorLipsumGenerateWorkflow' => 'PhabricatorLipsumManagementWorkflow', 'PhabricatorLipsumManagementWorkflow' => 'PhabricatorManagementWorkflow', 'PhabricatorLipsumMondrianArtist' => 'PhabricatorLipsumArtist', 'PhabricatorLiskDAO' => 'LiskDAO', + 'PhabricatorLiskSerializer' => 'Phobject', 'PhabricatorListFilterUIExample' => 'PhabricatorUIExample', 'PhabricatorLocalDiskFileStorageEngine' => 'PhabricatorFileStorageEngine', 'PhabricatorLocalTimeTestCase' => 'PhabricatorTestCase', @@ -5449,6 +5634,7 @@ phutil_register_library_map(array( 'PhabricatorMacroTransactionComment' => 'PhabricatorApplicationTransactionComment', 'PhabricatorMacroTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'PhabricatorMacroViewController' => 'PhabricatorMacroController', + 'PhabricatorMailImplementationAdapter' => 'Phobject', 'PhabricatorMailImplementationAmazonSESAdapter' => 'PhabricatorMailImplementationPHPMailerLiteAdapter', 'PhabricatorMailImplementationMailgunAdapter' => 'PhabricatorMailImplementationAdapter', 'PhabricatorMailImplementationPHPMailerAdapter' => 'PhabricatorMailImplementationAdapter', @@ -5463,7 +5649,9 @@ phutil_register_library_map(array( 'PhabricatorMailManagementShowInboundWorkflow' => 'PhabricatorMailManagementWorkflow', 'PhabricatorMailManagementShowOutboundWorkflow' => 'PhabricatorMailManagementWorkflow', 'PhabricatorMailManagementWorkflow' => 'PhabricatorManagementWorkflow', + 'PhabricatorMailReceiver' => 'Phobject', 'PhabricatorMailReceiverTestCase' => 'PhabricatorTestCase', + 'PhabricatorMailReplyHandler' => 'Phobject', 'PhabricatorMailSetupCheck' => 'PhabricatorSetupCheck', 'PhabricatorMailTarget' => 'Phobject', 'PhabricatorMailgunConfigOptions' => 'PhabricatorApplicationConfigOptions', @@ -5474,28 +5662,43 @@ phutil_register_library_map(array( 'PhabricatorManiphestConfigOptions' => 'PhabricatorApplicationConfigOptions', 'PhabricatorManiphestTaskTestDataGenerator' => 'PhabricatorTestDataGenerator', 'PhabricatorMarkupCache' => 'PhabricatorCacheDAO', - 'PhabricatorMarkupOneOff' => 'PhabricatorMarkupInterface', + 'PhabricatorMarkupEngine' => 'Phobject', + 'PhabricatorMarkupOneOff' => array( + 'Phobject', + 'PhabricatorMarkupInterface', + ), 'PhabricatorMarkupPreviewController' => 'PhabricatorController', 'PhabricatorMemeRemarkupRule' => 'PhutilRemarkupRule', 'PhabricatorMentionRemarkupRule' => 'PhutilRemarkupRule', 'PhabricatorMercurialGraphStream' => 'PhabricatorRepositoryGraphStream', + 'PhabricatorMetaMTAActor' => 'Phobject', 'PhabricatorMetaMTAActorQuery' => 'PhabricatorQuery', 'PhabricatorMetaMTAApplication' => 'PhabricatorApplication', 'PhabricatorMetaMTAApplicationEmail' => array( 'PhabricatorMetaMTADAO', 'PhabricatorPolicyInterface', + 'PhabricatorApplicationTransactionInterface', + 'PhabricatorDestructibleInterface', + 'PhabricatorSpacesInterface', ), 'PhabricatorMetaMTAApplicationEmailDatasource' => 'PhabricatorTypeaheadDatasource', + 'PhabricatorMetaMTAApplicationEmailEditor' => 'PhabricatorApplicationTransactionEditor', 'PhabricatorMetaMTAApplicationEmailPHIDType' => 'PhabricatorPHIDType', 'PhabricatorMetaMTAApplicationEmailPanel' => 'PhabricatorApplicationConfigurationPanel', 'PhabricatorMetaMTAApplicationEmailQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', + 'PhabricatorMetaMTAApplicationEmailTransaction' => 'PhabricatorApplicationTransaction', + 'PhabricatorMetaMTAApplicationEmailTransactionQuery' => 'PhabricatorApplicationTransactionQuery', + 'PhabricatorMetaMTAAttachment' => 'Phobject', 'PhabricatorMetaMTAConfigOptions' => 'PhabricatorApplicationConfigOptions', 'PhabricatorMetaMTAController' => 'PhabricatorController', 'PhabricatorMetaMTADAO' => 'PhabricatorLiskDAO', + 'PhabricatorMetaMTAEmailBodyParser' => 'Phobject', 'PhabricatorMetaMTAEmailBodyParserTestCase' => 'PhabricatorTestCase', 'PhabricatorMetaMTAErrorMailAction' => 'PhabricatorSystemAction', 'PhabricatorMetaMTAMail' => 'PhabricatorMetaMTADAO', + 'PhabricatorMetaMTAMailBody' => 'Phobject', 'PhabricatorMetaMTAMailBodyTestCase' => 'PhabricatorTestCase', + 'PhabricatorMetaMTAMailSection' => 'Phobject', 'PhabricatorMetaMTAMailTestCase' => 'PhabricatorTestCase', 'PhabricatorMetaMTAMailableDatasource' => 'PhabricatorTypeaheadCompositeDatasource', 'PhabricatorMetaMTAMailableFunctionDatasource' => 'PhabricatorTypeaheadCompositeDatasource', @@ -5526,7 +5729,9 @@ phutil_register_library_map(array( 'PhabricatorNavigationRemarkupRule' => 'PhutilRemarkupRule', 'PhabricatorNeverTriggerClock' => 'PhabricatorTriggerClock', 'PhabricatorNotificationAdHocFeedStory' => 'PhabricatorFeedStory', + 'PhabricatorNotificationBuilder' => 'Phobject', 'PhabricatorNotificationClearController' => 'PhabricatorNotificationController', + 'PhabricatorNotificationClient' => 'Phobject', 'PhabricatorNotificationConfigOptions' => 'PhabricatorApplicationConfigOptions', 'PhabricatorNotificationController' => 'PhabricatorController', 'PhabricatorNotificationIndividualController' => 'PhabricatorNotificationController', @@ -5555,6 +5760,7 @@ phutil_register_library_map(array( 'PhabricatorOAuthClientSecretController' => 'PhabricatorOAuthClientController', 'PhabricatorOAuthClientViewController' => 'PhabricatorOAuthClientController', 'PhabricatorOAuthResponse' => 'AphrontResponse', + 'PhabricatorOAuthServer' => 'Phobject', 'PhabricatorOAuthServerAccessToken' => 'PhabricatorOAuthServerDAO', 'PhabricatorOAuthServerApplication' => 'PhabricatorApplication', 'PhabricatorOAuthServerAuthController' => 'PhabricatorAuthController', @@ -5572,10 +5778,14 @@ phutil_register_library_map(array( 'PhabricatorOAuthServerController' => 'PhabricatorController', 'PhabricatorOAuthServerCreateClientsCapability' => 'PhabricatorPolicyCapability', 'PhabricatorOAuthServerDAO' => 'PhabricatorLiskDAO', + 'PhabricatorOAuthServerScope' => 'Phobject', 'PhabricatorOAuthServerTestCase' => 'PhabricatorTestCase', 'PhabricatorOAuthServerTestController' => 'PhabricatorOAuthServerController', 'PhabricatorOAuthServerTokenController' => 'PhabricatorAuthController', - 'PhabricatorObjectHandle' => 'PhabricatorPolicyInterface', + 'PhabricatorObjectHandle' => array( + 'Phobject', + 'PhabricatorPolicyInterface', + ), 'PhabricatorObjectHasAsanaSubtaskEdgeType' => 'PhabricatorEdgeType', 'PhabricatorObjectHasAsanaTaskEdgeType' => 'PhabricatorEdgeType', 'PhabricatorObjectHasContributorEdgeType' => 'PhabricatorEdgeType', @@ -5584,6 +5794,7 @@ phutil_register_library_map(array( 'PhabricatorObjectHasSubscriberEdgeType' => 'PhabricatorEdgeType', 'PhabricatorObjectHasUnsubscriberEdgeType' => 'PhabricatorEdgeType', 'PhabricatorObjectHasWatcherEdgeType' => 'PhabricatorEdgeType', + 'PhabricatorObjectListQuery' => 'Phobject', 'PhabricatorObjectListQueryTestCase' => 'PhabricatorTestCase', 'PhabricatorObjectMailReceiver' => 'PhabricatorMailReceiver', 'PhabricatorObjectMailReceiverTestCase' => 'PhabricatorTestCase', @@ -5591,10 +5802,12 @@ phutil_register_library_map(array( 'PhabricatorObjectMentionsObjectEdgeType' => 'PhabricatorEdgeType', 'PhabricatorObjectQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorObjectRemarkupRule' => 'PhutilRemarkupRule', + 'PhabricatorObjectSelectorDialog' => 'Phobject', 'PhabricatorObjectUsesCredentialsEdgeType' => 'PhabricatorEdgeType', 'PhabricatorOffsetPagedQuery' => 'PhabricatorQuery', 'PhabricatorOneTimeTriggerClock' => 'PhabricatorTriggerClock', 'PhabricatorOpcodeCacheSpec' => 'PhabricatorCacheSpec', + 'PhabricatorOwnerPathQuery' => 'Phobject', 'PhabricatorOwnersApplication' => 'PhabricatorApplication', 'PhabricatorOwnersConfigOptions' => 'PhabricatorApplicationConfigOptions', 'PhabricatorOwnersController' => 'PhabricatorController', @@ -5619,6 +5832,10 @@ phutil_register_library_map(array( 'PhabricatorOwnersPath' => 'PhabricatorOwnersDAO', 'PhabricatorOwnersPathsController' => 'PhabricatorOwnersController', 'PhabricatorPHDConfigOptions' => 'PhabricatorApplicationConfigOptions', + 'PhabricatorPHID' => 'Phobject', + 'PhabricatorPHIDConstants' => 'Phobject', + 'PhabricatorPHIDType' => 'Phobject', + 'PhabricatorPHIDTypeTestCase' => 'PhutilTestCase', 'PhabricatorPHPASTApplication' => 'PhabricatorApplication', 'PhabricatorPHPConfigSetupCheck' => 'PhabricatorSetupCheck', 'PhabricatorPHPMailerConfigOptions' => 'PhabricatorApplicationConfigOptions', @@ -5726,21 +5943,26 @@ phutil_register_library_map(array( 'PhabricatorPolicyCanJoinCapability' => 'PhabricatorPolicyCapability', 'PhabricatorPolicyCanViewCapability' => 'PhabricatorPolicyCapability', 'PhabricatorPolicyCapability' => 'Phobject', + 'PhabricatorPolicyCapabilityTestCase' => 'PhabricatorTestCase', 'PhabricatorPolicyConfigOptions' => 'PhabricatorApplicationConfigOptions', + 'PhabricatorPolicyConstants' => 'Phobject', 'PhabricatorPolicyController' => 'PhabricatorController', 'PhabricatorPolicyDAO' => 'PhabricatorLiskDAO', 'PhabricatorPolicyDataTestCase' => 'PhabricatorTestCase', 'PhabricatorPolicyEditController' => 'PhabricatorPolicyController', 'PhabricatorPolicyException' => 'Exception', 'PhabricatorPolicyExplainController' => 'PhabricatorPolicyController', + 'PhabricatorPolicyFilter' => 'Phobject', 'PhabricatorPolicyInterface' => 'PhabricatorPHIDInterface', 'PhabricatorPolicyManagementShowWorkflow' => 'PhabricatorPolicyManagementWorkflow', 'PhabricatorPolicyManagementUnlockWorkflow' => 'PhabricatorPolicyManagementWorkflow', 'PhabricatorPolicyManagementWorkflow' => 'PhabricatorManagementWorkflow', 'PhabricatorPolicyPHIDTypePolicy' => 'PhabricatorPHIDType', 'PhabricatorPolicyQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', + 'PhabricatorPolicyRule' => 'Phobject', 'PhabricatorPolicyTestCase' => 'PhabricatorTestCase', 'PhabricatorPolicyTestObject' => array( + 'Phobject', 'PhabricatorPolicyInterface', 'PhabricatorExtendedPolicyInterface', ), @@ -5826,6 +6048,7 @@ phutil_register_library_map(array( 'PhabricatorProjectCustomField', 'PhabricatorStandardCustomFieldInterface', ), + 'PhabricatorProjectStatus' => 'Phobject', 'PhabricatorProjectTestDataGenerator' => 'PhabricatorTestDataGenerator', 'PhabricatorProjectTransaction' => 'PhabricatorApplicationTransaction', 'PhabricatorProjectTransactionEditor' => 'PhabricatorApplicationTransactionEditor', @@ -5835,7 +6058,9 @@ phutil_register_library_map(array( 'PhabricatorProjectViewController' => 'PhabricatorProjectController', 'PhabricatorProjectWatchController' => 'PhabricatorProjectController', 'PhabricatorProjectsPolicyRule' => 'PhabricatorPolicyRule', + 'PhabricatorProtocolAdapter' => 'Phobject', 'PhabricatorPygmentSetupCheck' => 'PhabricatorSetupCheck', + 'PhabricatorQuery' => 'Phobject', 'PhabricatorQueryConstraint' => 'Phobject', 'PhabricatorQueryOrderItem' => 'Phobject', 'PhabricatorQueryOrderTestCase' => 'PhabricatorTestCase', @@ -5897,13 +6122,16 @@ phutil_register_library_map(array( 'PhabricatorRepositoryCommitOwnersWorker' => 'PhabricatorRepositoryCommitParserWorker', 'PhabricatorRepositoryCommitPHIDType' => 'PhabricatorPHIDType', 'PhabricatorRepositoryCommitParserWorker' => 'PhabricatorWorker', + 'PhabricatorRepositoryCommitRef' => 'Phobject', 'PhabricatorRepositoryCommitSearchIndexer' => 'PhabricatorSearchDocumentIndexer', 'PhabricatorRepositoryConfigOptions' => 'PhabricatorApplicationConfigOptions', 'PhabricatorRepositoryDAO' => 'PhabricatorLiskDAO', 'PhabricatorRepositoryDiscoveryEngine' => 'PhabricatorRepositoryEngine', 'PhabricatorRepositoryEditor' => 'PhabricatorApplicationTransactionEditor', + 'PhabricatorRepositoryEngine' => 'Phobject', 'PhabricatorRepositoryGitCommitChangeParserWorker' => 'PhabricatorRepositoryCommitChangeParserWorker', 'PhabricatorRepositoryGitCommitMessageParserWorker' => 'PhabricatorRepositoryCommitMessageParserWorker', + 'PhabricatorRepositoryGraphCache' => 'Phobject', 'PhabricatorRepositoryGraphStream' => 'Phobject', 'PhabricatorRepositoryManagementCacheWorkflow' => 'PhabricatorRepositoryManagementWorkflow', 'PhabricatorRepositoryManagementDiscoverWorkflow' => 'PhabricatorRepositoryManagementWorkflow', @@ -5963,6 +6191,7 @@ phutil_register_library_map(array( 'PhabricatorRepositoryTestCase' => 'PhabricatorTestCase', 'PhabricatorRepositoryTransaction' => 'PhabricatorApplicationTransaction', 'PhabricatorRepositoryTransactionQuery' => 'PhabricatorApplicationTransactionQuery', + 'PhabricatorRepositoryType' => 'Phobject', 'PhabricatorRepositoryURINormalizer' => 'Phobject', 'PhabricatorRepositoryURINormalizerTestCase' => 'PhabricatorTestCase', 'PhabricatorRepositoryURITestCase' => 'PhabricatorTestCase', @@ -5974,6 +6203,7 @@ phutil_register_library_map(array( 'PhabricatorSMSConfigOptions' => 'PhabricatorApplicationConfigOptions', 'PhabricatorSMSDAO' => 'PhabricatorLiskDAO', 'PhabricatorSMSDemultiplexWorker' => 'PhabricatorSMSWorker', + 'PhabricatorSMSImplementationAdapter' => 'Phobject', 'PhabricatorSMSImplementationTestBlackholeAdapter' => 'PhabricatorSMSImplementationAdapter', 'PhabricatorSMSImplementationTwilioAdapter' => 'PhabricatorSMSImplementationAdapter', 'PhabricatorSMSManagementListOutboundWorkflow' => 'PhabricatorSMSManagementWorkflow', @@ -5982,6 +6212,7 @@ phutil_register_library_map(array( 'PhabricatorSMSManagementWorkflow' => 'PhabricatorManagementWorkflow', 'PhabricatorSMSSendWorker' => 'PhabricatorSMSWorker', 'PhabricatorSMSWorker' => 'PhabricatorWorker', + 'PhabricatorSQLPatchList' => 'Phobject', 'PhabricatorSSHKeyGenerator' => 'Phobject', 'PhabricatorSSHKeysSettingsPanel' => 'PhabricatorSettingsPanel', 'PhabricatorSSHLog' => 'Phobject', @@ -5993,6 +6224,8 @@ phutil_register_library_map(array( ), 'PhabricatorSavedQueryQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorScheduleTaskTriggerAction' => 'PhabricatorTriggerAction', + 'PhabricatorScopedEnv' => 'Phobject', + 'PhabricatorSearchAbstractDocument' => 'Phobject', 'PhabricatorSearchApplication' => 'PhabricatorApplication', 'PhabricatorSearchApplicationSearchEngine' => 'PhabricatorApplicationSearchEngine', 'PhabricatorSearchApplicationStorageEnginePanel' => 'PhabricatorApplicationConfigurationPanel', @@ -6015,8 +6248,11 @@ phutil_register_library_map(array( 'PhabricatorSearchDocumentRelationship' => 'PhabricatorSearchDAO', 'PhabricatorSearchDocumentTypeDatasource' => 'PhabricatorTypeaheadDatasource', 'PhabricatorSearchEditController' => 'PhabricatorSearchBaseController', + 'PhabricatorSearchEngine' => 'Phobject', + 'PhabricatorSearchEngineTestCase' => 'PhabricatorTestCase', 'PhabricatorSearchField' => 'Phobject', 'PhabricatorSearchHovercardController' => 'PhabricatorSearchBaseController', + 'PhabricatorSearchIndexer' => 'Phobject', 'PhabricatorSearchManagementIndexWorkflow' => 'PhabricatorSearchManagementWorkflow', 'PhabricatorSearchManagementInitWorkflow' => 'PhabricatorSearchManagementWorkflow', 'PhabricatorSearchManagementWorkflow' => 'PhabricatorManagementWorkflow', @@ -6025,6 +6261,7 @@ phutil_register_library_map(array( 'PhabricatorSearchOwnersField' => 'PhabricatorSearchTokenizerField', 'PhabricatorSearchPreferencesSettingsPanel' => 'PhabricatorSettingsPanel', 'PhabricatorSearchProjectsField' => 'PhabricatorSearchTokenizerField', + 'PhabricatorSearchRelationship' => 'Phobject', 'PhabricatorSearchResultView' => 'AphrontView', 'PhabricatorSearchSelectController' => 'PhabricatorSearchBaseController', 'PhabricatorSearchSelectField' => 'PhabricatorSearchField', @@ -6044,6 +6281,10 @@ phutil_register_library_map(array( 'PhabricatorSettingsAdjustController' => 'PhabricatorController', 'PhabricatorSettingsApplication' => 'PhabricatorApplication', 'PhabricatorSettingsMainController' => 'PhabricatorController', + 'PhabricatorSettingsPanel' => 'Phobject', + 'PhabricatorSetupCheck' => 'Phobject', + 'PhabricatorSetupCheckTestCase' => 'PhabricatorTestCase', + 'PhabricatorSetupIssue' => 'Phobject', 'PhabricatorSetupIssueUIExample' => 'PhabricatorUIExample', 'PhabricatorSetupIssueView' => 'AphrontView', 'PhabricatorSlowvoteApplication' => 'PhabricatorApplication', @@ -6076,14 +6317,15 @@ phutil_register_library_map(array( 'PhabricatorSlowvoteTransactionComment' => 'PhabricatorApplicationTransactionComment', 'PhabricatorSlowvoteTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'PhabricatorSlowvoteVoteController' => 'PhabricatorSlowvoteController', + 'PhabricatorSlug' => 'Phobject', 'PhabricatorSlugTestCase' => 'PhabricatorTestCase', 'PhabricatorSortTableUIExample' => 'PhabricatorUIExample', 'PhabricatorSourceCodeView' => 'AphrontView', 'PhabricatorSpacesApplication' => 'PhabricatorApplication', + 'PhabricatorSpacesArchiveController' => 'PhabricatorSpacesController', 'PhabricatorSpacesCapabilityCreateSpaces' => 'PhabricatorPolicyCapability', 'PhabricatorSpacesCapabilityDefaultEdit' => 'PhabricatorPolicyCapability', 'PhabricatorSpacesCapabilityDefaultView' => 'PhabricatorPolicyCapability', - 'PhabricatorSpacesControl' => 'AphrontFormControl', 'PhabricatorSpacesController' => 'PhabricatorController', 'PhabricatorSpacesDAO' => 'PhabricatorLiskDAO', 'PhabricatorSpacesEditController' => 'PhabricatorSpacesController', @@ -6103,6 +6345,7 @@ phutil_register_library_map(array( 'PhabricatorSpacesNamespaceTransaction' => 'PhabricatorApplicationTransaction', 'PhabricatorSpacesNamespaceTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'PhabricatorSpacesRemarkupRule' => 'PhabricatorObjectRemarkupRule', + 'PhabricatorSpacesSchemaSpec' => 'PhabricatorConfigSchemaSpec', 'PhabricatorSpacesTestCase' => 'PhabricatorTestCase', 'PhabricatorSpacesViewController' => 'PhabricatorSpacesController', 'PhabricatorStandardCustomField' => 'PhabricatorCustomField', @@ -6120,6 +6363,8 @@ phutil_register_library_map(array( 'PhabricatorStandardPageView' => 'PhabricatorBarePageView', 'PhabricatorStatusController' => 'PhabricatorController', 'PhabricatorStatusUIExample' => 'PhabricatorUIExample', + 'PhabricatorStorageFixtureScopeGuard' => 'Phobject', + 'PhabricatorStorageManagementAPI' => 'Phobject', 'PhabricatorStorageManagementAdjustWorkflow' => 'PhabricatorStorageManagementWorkflow', 'PhabricatorStorageManagementDatabasesWorkflow' => 'PhabricatorStorageManagementWorkflow', 'PhabricatorStorageManagementDestroyWorkflow' => 'PhabricatorStorageManagementWorkflow', @@ -6131,6 +6376,7 @@ phutil_register_library_map(array( 'PhabricatorStorageManagementStatusWorkflow' => 'PhabricatorStorageManagementWorkflow', 'PhabricatorStorageManagementUpgradeWorkflow' => 'PhabricatorStorageManagementWorkflow', 'PhabricatorStorageManagementWorkflow' => 'PhabricatorManagementWorkflow', + 'PhabricatorStoragePatch' => 'Phobject', 'PhabricatorStorageSchemaSpec' => 'PhabricatorConfigSchemaSpec', 'PhabricatorStorageSetupCheck' => 'PhabricatorSetupCheck', 'PhabricatorStreamingProtocolAdapter' => 'PhabricatorProtocolAdapter', @@ -6142,11 +6388,14 @@ phutil_register_library_map(array( 'PhabricatorSubscriptionsEditor' => 'PhabricatorEditor', 'PhabricatorSubscriptionsListController' => 'PhabricatorController', 'PhabricatorSubscriptionsSubscribeEmailCommand' => 'MetaMTAEmailTransactionCommand', + 'PhabricatorSubscriptionsSubscribersPolicyRule' => 'PhabricatorPolicyRule', 'PhabricatorSubscriptionsTransactionController' => 'PhabricatorController', 'PhabricatorSubscriptionsUIEventListener' => 'PhabricatorEventListener', 'PhabricatorSubscriptionsUnsubscribeEmailCommand' => 'MetaMTAEmailTransactionCommand', 'PhabricatorSupportApplication' => 'PhabricatorApplication', + 'PhabricatorSyntaxHighlighter' => 'Phobject', 'PhabricatorSyntaxHighlightingConfigOptions' => 'PhabricatorApplicationConfigOptions', + 'PhabricatorSystemAction' => 'Phobject', 'PhabricatorSystemActionEngine' => 'Phobject', 'PhabricatorSystemActionGarbageCollector' => 'PhabricatorGarbageCollector', 'PhabricatorSystemActionLog' => 'PhabricatorSystemDAO', @@ -6166,9 +6415,12 @@ phutil_register_library_map(array( 'PhabricatorTestApplication' => 'PhabricatorApplication', 'PhabricatorTestCase' => 'PhutilTestCase', 'PhabricatorTestController' => 'PhabricatorController', + 'PhabricatorTestDataGenerator' => 'Phobject', 'PhabricatorTestNoCycleEdgeType' => 'PhabricatorEdgeType', 'PhabricatorTestStorageEngine' => 'PhabricatorFileStorageEngine', 'PhabricatorTestWorker' => 'PhabricatorWorker', + 'PhabricatorTime' => 'Phobject', + 'PhabricatorTimeGuard' => 'Phobject', 'PhabricatorTimeTestCase' => 'PhabricatorTestCase', 'PhabricatorTimezoneSetupCheck' => 'PhabricatorSetupCheck', 'PhabricatorToken' => array( @@ -6196,6 +6448,7 @@ phutil_register_library_map(array( 'PhabricatorTokensApplication' => 'PhabricatorApplication', 'PhabricatorTokensSettingsPanel' => 'PhabricatorSettingsPanel', 'PhabricatorTooltipUIExample' => 'PhabricatorUIExample', + 'PhabricatorTransactions' => 'Phobject', 'PhabricatorTransactionsApplication' => 'PhabricatorApplication', 'PhabricatorTransformedFile' => 'PhabricatorFileDAO', 'PhabricatorTranslationsConfigOptions' => 'PhabricatorApplicationConfigOptions', @@ -6215,9 +6468,11 @@ phutil_register_library_map(array( 'PhabricatorTypeaheadInvalidTokenException' => 'Exception', 'PhabricatorTypeaheadModularDatasourceController' => 'PhabricatorTypeaheadDatasourceController', 'PhabricatorTypeaheadMonogramDatasource' => 'PhabricatorTypeaheadDatasource', + 'PhabricatorTypeaheadResult' => 'Phobject', 'PhabricatorTypeaheadRuntimeCompositeDatasource' => 'PhabricatorTypeaheadCompositeDatasource', 'PhabricatorTypeaheadTokenView' => 'AphrontTagView', 'PhabricatorUIConfigOptions' => 'PhabricatorApplicationConfigOptions', + 'PhabricatorUIExample' => 'Phobject', 'PhabricatorUIExampleRenderController' => 'PhabricatorController', 'PhabricatorUIExamplesApplication' => 'PhabricatorApplication', 'PhabricatorUSEnglishTranslation' => 'PhutilTranslation', @@ -6270,6 +6525,7 @@ phutil_register_library_map(array( 'PhabricatorViewerDatasource' => 'PhabricatorTypeaheadDatasource', 'PhabricatorWatcherHasObjectEdgeType' => 'PhabricatorEdgeType', 'PhabricatorWordPressAuthProvider' => 'PhabricatorOAuth2AuthProvider', + 'PhabricatorWorker' => 'Phobject', 'PhabricatorWorkerActiveTask' => 'PhabricatorWorkerTask', 'PhabricatorWorkerArchiveTask' => 'PhabricatorWorkerTask', 'PhabricatorWorkerArchiveTaskQuery' => 'PhabricatorQuery', @@ -6369,6 +6625,7 @@ phutil_register_library_map(array( 'PhameQueryPostsConduitAPIMethod' => 'PhameConduitAPIMethod', 'PhameResourceController' => 'CelerityResourceController', 'PhameSchemaSpec' => 'PhabricatorConfigSchemaSpec', + 'PhameSkinSpecification' => 'Phobject', 'PhluxController' => 'PhabricatorController', 'PhluxDAO' => 'PhabricatorLiskDAO', 'PhluxEditController' => 'PhluxController', @@ -6410,6 +6667,7 @@ phutil_register_library_map(array( 'PhabricatorApplicationTransactionInterface', 'PhabricatorProjectInterface', 'PhabricatorDestructibleInterface', + 'PhabricatorSpacesInterface', ), 'PholioMockCommentController' => 'PholioController', 'PholioMockEditController' => 'PholioController', @@ -6459,6 +6717,7 @@ phutil_register_library_map(array( 'PhortuneCartCheckoutController' => 'PhortuneCartController', 'PhortuneCartController' => 'PhortuneController', 'PhortuneCartEditor' => 'PhabricatorApplicationTransactionEditor', + 'PhortuneCartImplementation' => 'Phobject', 'PhortuneCartListController' => 'PhortuneController', 'PhortuneCartPHIDType' => 'PhabricatorPHIDType', 'PhortuneCartQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', @@ -6477,7 +6736,9 @@ phutil_register_library_map(array( 'PhortuneChargeQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhortuneChargeSearchEngine' => 'PhabricatorApplicationSearchEngine', 'PhortuneChargeTableView' => 'AphrontView', + 'PhortuneConstants' => 'Phobject', 'PhortuneController' => 'PhabricatorController', + 'PhortuneCreditCardForm' => 'Phobject', 'PhortuneCurrency' => 'Phobject', 'PhortuneCurrencySerializer' => 'PhabricatorLiskSerializer', 'PhortuneCurrencyTestCase' => 'PhabricatorTestCase', @@ -6517,6 +6778,7 @@ phutil_register_library_map(array( 'PhortunePaymentMethodEditController' => 'PhortuneController', 'PhortunePaymentMethodPHIDType' => 'PhabricatorPHIDType', 'PhortunePaymentMethodQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', + 'PhortunePaymentProvider' => 'Phobject', 'PhortunePaymentProviderConfig' => array( 'PhortuneDAO', 'PhabricatorPolicyInterface', @@ -6526,10 +6788,12 @@ phutil_register_library_map(array( 'PhortunePaymentProviderConfigTransaction' => 'PhabricatorApplicationTransaction', 'PhortunePaymentProviderConfigTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'PhortunePaymentProviderPHIDType' => 'PhabricatorPHIDType', + 'PhortunePaymentProviderTestCase' => 'PhabricatorTestCase', 'PhortuneProduct' => array( 'PhortuneDAO', 'PhabricatorPolicyInterface', ), + 'PhortuneProductImplementation' => 'Phobject', 'PhortuneProductListController' => 'PhabricatorController', 'PhortuneProductPHIDType' => 'PhabricatorPHIDType', 'PhortuneProductQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', @@ -6551,6 +6815,7 @@ phutil_register_library_map(array( ), 'PhortuneSubscriptionCart' => 'PhortuneCartImplementation', 'PhortuneSubscriptionEditController' => 'PhortuneController', + 'PhortuneSubscriptionImplementation' => 'Phobject', 'PhortuneSubscriptionListController' => 'PhortuneController', 'PhortuneSubscriptionPHIDType' => 'PhabricatorPHIDType', 'PhortuneSubscriptionProduct' => 'PhortuneProductImplementation', @@ -6626,6 +6891,7 @@ phutil_register_library_map(array( 'PhrequentUserTimeQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhrictionChangeType' => 'PhrictionConstants', 'PhrictionConduitAPIMethod' => 'ConduitAPIMethod', + 'PhrictionConstants' => 'Phobject', 'PhrictionContent' => array( 'PhrictionDAO', 'PhabricatorMarkupInterface', @@ -6690,6 +6956,7 @@ phutil_register_library_map(array( 'PonderAnswerTransaction' => 'PhabricatorApplicationTransaction', 'PonderAnswerTransactionComment' => 'PhabricatorApplicationTransactionComment', 'PonderAnswerTransactionQuery' => 'PhabricatorApplicationTransactionQuery', + 'PonderConstants' => 'Phobject', 'PonderController' => 'PhabricatorController', 'PonderDAO' => 'PhabricatorLiskDAO', 'PonderEditor' => 'PhabricatorApplicationTransactionEditor', @@ -6733,6 +7000,7 @@ phutil_register_library_map(array( 'PonderVotingUserHasAnswerEdgeType' => 'PhabricatorEdgeType', 'PonderVotingUserHasQuestionEdgeType' => 'PhabricatorEdgeType', 'ProjectAddProjectsEmailCommand' => 'MetaMTAEmailTransactionCommand', + 'ProjectBoardTaskCard' => 'Phobject', 'ProjectCanLockProjectsCapability' => 'PhabricatorPolicyCapability', 'ProjectConduitAPIMethod' => 'ConduitAPIMethod', 'ProjectCreateConduitAPIMethod' => 'ProjectConduitAPIMethod', @@ -6763,12 +7031,14 @@ phutil_register_library_map(array( 'ReleephBranchPreviewView' => 'AphrontFormControl', 'ReleephBranchQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'ReleephBranchSearchEngine' => 'PhabricatorApplicationSearchEngine', + 'ReleephBranchTemplate' => 'Phobject', 'ReleephBranchTransaction' => 'PhabricatorApplicationTransaction', 'ReleephBranchTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'ReleephBranchViewController' => array( 'ReleephBranchController', 'PhabricatorApplicationSearchResultsControllerInterface', ), + 'ReleephCommitFinder' => 'Phobject', 'ReleephCommitFinderException' => 'Exception', 'ReleephCommitMessageFieldSpecification' => 'ReleephFieldSpecification', 'ReleephConduitAPIMethod' => 'ConduitAPIMethod', @@ -6780,6 +7050,7 @@ phutil_register_library_map(array( 'ReleephDiffMessageFieldSpecification' => 'ReleephFieldSpecification', 'ReleephDiffSizeFieldSpecification' => 'ReleephFieldSpecification', 'ReleephFieldParseException' => 'Exception', + 'ReleephFieldSelector' => 'Phobject', 'ReleephFieldSpecification' => array( 'PhabricatorCustomField', 'PhabricatorMarkupInterface', @@ -6830,6 +7101,7 @@ phutil_register_library_map(array( 'ReleephRequestQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'ReleephRequestReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler', 'ReleephRequestSearchEngine' => 'PhabricatorApplicationSearchEngine', + 'ReleephRequestStatus' => 'Phobject', 'ReleephRequestTransaction' => 'PhabricatorApplicationTransaction', 'ReleephRequestTransactionComment' => 'PhabricatorApplicationTransactionComment', 'ReleephRequestTransactionQuery' => 'PhabricatorApplicationTransactionQuery', @@ -6859,6 +7131,8 @@ phutil_register_library_map(array( 'SlowvoteEmbedView' => 'AphrontView', 'SlowvoteInfoConduitAPIMethod' => 'SlowvoteConduitAPIMethod', 'SlowvoteRemarkupRule' => 'PhabricatorObjectRemarkupRule', + 'SubscriptionListDialogBuilder' => 'Phobject', + 'SubscriptionListStringBuilder' => 'Phobject', 'TokenConduitAPIMethod' => 'ConduitAPIMethod', 'TokenGiveConduitAPIMethod' => 'TokenConduitAPIMethod', 'TokenGivenConduitAPIMethod' => 'TokenConduitAPIMethod', diff --git a/src/aphront/AphrontRequest.php b/src/aphront/AphrontRequest.php index f4a1ee2cff..d29cd926d1 100644 --- a/src/aphront/AphrontRequest.php +++ b/src/aphront/AphrontRequest.php @@ -5,7 +5,7 @@ * @task cookie Managing Cookies * @task cluster Working With a Phabricator Cluster */ -final class AphrontRequest { +final class AphrontRequest extends Phobject { // NOTE: These magic request-type parameters are automatically included in // certain requests (e.g., by phabricator_form(), JX.Request, @@ -27,6 +27,7 @@ final class AphrontRequest { private $user; private $applicationConfiguration; private $uriData; + private $cookiePrefix; public function __construct($host, $path) { $this->host = $host; diff --git a/src/aphront/AphrontURIMapper.php b/src/aphront/AphrontURIMapper.php index 32f464911a..13108729b7 100644 --- a/src/aphront/AphrontURIMapper.php +++ b/src/aphront/AphrontURIMapper.php @@ -1,6 +1,6 @@ content = $content; return $this; diff --git a/src/aphront/response/AphrontResponse.php b/src/aphront/response/AphrontResponse.php index b1e72f5529..72dacf977e 100644 --- a/src/aphront/response/AphrontResponse.php +++ b/src/aphront/response/AphrontResponse.php @@ -1,6 +1,6 @@ assertTrue(true); + } + +} diff --git a/src/applications/aphlict/query/AphlictDropdownDataQuery.php b/src/applications/aphlict/query/AphlictDropdownDataQuery.php index 4f360f28cc..e8a8edb59f 100644 --- a/src/applications/aphlict/query/AphlictDropdownDataQuery.php +++ b/src/applications/aphlict/query/AphlictDropdownDataQuery.php @@ -1,6 +1,6 @@ ')); } diff --git a/src/applications/auth/data/PhabricatorAuthHighSecurityToken.php b/src/applications/auth/data/PhabricatorAuthHighSecurityToken.php index 5c84cc9fd8..8ea1ed97f8 100644 --- a/src/applications/auth/data/PhabricatorAuthHighSecurityToken.php +++ b/src/applications/auth/data/PhabricatorAuthHighSecurityToken.php @@ -1,3 +1,3 @@ assertTrue(true); + } + +} diff --git a/src/applications/auth/provider/PhabricatorAuthProvider.php b/src/applications/auth/provider/PhabricatorAuthProvider.php index d495a3091f..0b03bed7ff 100644 --- a/src/applications/auth/provider/PhabricatorAuthProvider.php +++ b/src/applications/auth/provider/PhabricatorAuthProvider.php @@ -1,6 +1,6 @@ pht('Core Applications'), self::GROUP_UTILITIES => pht('Utilities'), @@ -35,7 +37,7 @@ abstract class PhabricatorApplication implements PhabricatorPolicyInterface { return pht('%s Application', $this->getName()); } - public function isInstalled() { + final public function isInstalled() { if (!$this->canUninstall()) { return true; } @@ -133,7 +135,7 @@ abstract class PhabricatorApplication implements PhabricatorPolicyInterface { return true; } - public function getPHID() { + final public function getPHID() { return 'PHID-APPS-'.get_class($this); } @@ -145,7 +147,7 @@ abstract class PhabricatorApplication implements PhabricatorPolicyInterface { return null; } - public function getApplicationURI($path = '') { + final public function getApplicationURI($path = '') { return $this->getBaseURI().ltrim($path, '/'); } @@ -169,7 +171,7 @@ abstract class PhabricatorApplication implements PhabricatorPolicyInterface { return null; } - public function getHelpMenuItems(PhabricatorUser $viewer) { + final public function getHelpMenuItems(PhabricatorUser $viewer) { $items = array(); $articles = $this->getHelpDocumentationArticles($viewer); @@ -249,7 +251,7 @@ abstract class PhabricatorApplication implements PhabricatorPolicyInterface { return false; } - protected function getInboundEmailSupportLink() { + final protected function getInboundEmailSupportLink() { return PhabricatorEnv::getDocLink('Configuring Inbound Email'); } @@ -286,7 +288,7 @@ abstract class PhabricatorApplication implements PhabricatorPolicyInterface { * @return string * @task ui */ - public static function formatStatusCount( + final public static function formatStatusCount( $count, $limit_string = '%s', $base_string = '%d') { @@ -359,7 +361,7 @@ abstract class PhabricatorApplication implements PhabricatorPolicyInterface { /* -( Application Management )--------------------------------------------- */ - public static function getByClass($class_name) { + final public static function getByClass($class_name) { $selected = null; $applications = self::getAllApplications(); @@ -377,7 +379,7 @@ abstract class PhabricatorApplication implements PhabricatorPolicyInterface { return $selected; } - public static function getAllApplications() { + final public static function getAllApplications() { static $applications; if ($applications === null) { @@ -401,7 +403,7 @@ abstract class PhabricatorApplication implements PhabricatorPolicyInterface { return $applications; } - public static function getAllInstalledApplications() { + final public static function getAllInstalledApplications() { $all_applications = self::getAllApplications(); $apps = array(); foreach ($all_applications as $app) { @@ -426,7 +428,7 @@ abstract class PhabricatorApplication implements PhabricatorPolicyInterface { * @return bool True if the class is installed. * @task meta */ - public static function isClassInstalled($class) { + final public static function isClassInstalled($class) { return self::getByClass($class)->isInstalled(); } @@ -443,7 +445,7 @@ abstract class PhabricatorApplication implements PhabricatorPolicyInterface { * @return bool True if the class is installed for the viewer. * @task meta */ - public static function isClassInstalledForViewer( + final public static function isClassInstalledForViewer( $class, PhabricatorUser $viewer) { @@ -502,7 +504,7 @@ abstract class PhabricatorApplication implements PhabricatorPolicyInterface { return array(); } - private function getCustomPolicySetting($capability) { + final private function getCustomPolicySetting($capability) { if (!$this->isCapabilityEditable($capability)) { return null; } @@ -528,7 +530,7 @@ abstract class PhabricatorApplication implements PhabricatorPolicyInterface { } - private function getCustomCapabilitySpecification($capability) { + final private function getCustomCapabilitySpecification($capability) { $custom = $this->getCustomCapabilities(); if (!isset($custom[$capability])) { throw new Exception(pht("Unknown capability '%s'!", $capability)); @@ -536,7 +538,7 @@ abstract class PhabricatorApplication implements PhabricatorPolicyInterface { return $custom[$capability]; } - public function getCapabilityLabel($capability) { + final public function getCapabilityLabel($capability) { switch ($capability) { case PhabricatorPolicyCapability::CAN_VIEW: return pht('Can Use Application'); @@ -552,7 +554,7 @@ abstract class PhabricatorApplication implements PhabricatorPolicyInterface { return null; } - public function isCapabilityEditable($capability) { + final public function isCapabilityEditable($capability) { switch ($capability) { case PhabricatorPolicyCapability::CAN_VIEW: return $this->canUninstall(); @@ -564,7 +566,7 @@ abstract class PhabricatorApplication implements PhabricatorPolicyInterface { } } - public function getCapabilityCaption($capability) { + final public function getCapabilityCaption($capability) { switch ($capability) { case PhabricatorPolicyCapability::CAN_VIEW: if (!$this->canUninstall()) { @@ -582,6 +584,17 @@ abstract class PhabricatorApplication implements PhabricatorPolicyInterface { } } + final public function getCapabilityTemplatePHIDType($capability) { + switch ($capability) { + case PhabricatorPolicyCapability::CAN_VIEW: + case PhabricatorPolicyCapability::CAN_EDIT: + return null; + } + + $spec = $this->getCustomCapabilitySpecification($capability); + return idx($spec, 'template'); + } + public function getApplicationSearchDocumentTypes() { return array(); } diff --git a/src/applications/base/__tests__/PhabricatorApplicationTestCase.php b/src/applications/base/__tests__/PhabricatorApplicationTestCase.php new file mode 100644 index 0000000000..ca01cba111 --- /dev/null +++ b/src/applications/base/__tests__/PhabricatorApplicationTestCase.php @@ -0,0 +1,10 @@ +assertTrue(true); + } + +} diff --git a/src/applications/cache/PhabricatorCaches.php b/src/applications/cache/PhabricatorCaches.php index e3290172fb..5824c6458c 100644 --- a/src/applications/cache/PhabricatorCaches.php +++ b/src/applications/cache/PhabricatorCaches.php @@ -7,7 +7,7 @@ * @task setup Setup Cache * @task compress Compression */ -final class PhabricatorCaches { +final class PhabricatorCaches extends Phobject { private static $requestCache; diff --git a/src/applications/calendar/controller/PhabricatorCalendarEventEditController.php b/src/applications/calendar/controller/PhabricatorCalendarEventEditController.php index ccf7cbf0b0..218fe17371 100644 --- a/src/applications/calendar/controller/PhabricatorCalendarEventEditController.php +++ b/src/applications/calendar/controller/PhabricatorCalendarEventEditController.php @@ -17,7 +17,7 @@ final class PhabricatorCalendarEventEditController $viewer = $request->getViewer(); $user_phid = $viewer->getPHID(); $error_name = true; - $error_recurrence_end_date = true; + $error_recurrence_end_date = null; $error_start_date = true; $error_end_date = true; $validation_exception = null; @@ -336,8 +336,7 @@ final class PhabricatorCalendarEventEditController ->setID($recurrence_end_date_id) ->setIsTimeDisabled(true) ->setIsDisabled($recurrence_end_date_value->isDisabled()) - ->setAllowNull(true) - ->isRequired(false); + ->setAllowNull(true); $recurrence_frequency_select = id(new AphrontFormSelectControl()) ->setName('frequency') diff --git a/src/applications/calendar/storage/PhabricatorCalendarEvent.php b/src/applications/calendar/storage/PhabricatorCalendarEvent.php index ea6c6a48ef..f12bf9a9c3 100644 --- a/src/applications/calendar/storage/PhabricatorCalendarEvent.php +++ b/src/applications/calendar/storage/PhabricatorCalendarEvent.php @@ -316,7 +316,7 @@ final class PhabricatorCalendarEvent extends PhabricatorCalendarDAO case 'monthly': return 'month'; case 'yearly': - return 'yearly'; + return 'year'; default: return 'day'; } diff --git a/src/applications/calendar/util/CalendarTimeUtil.php b/src/applications/calendar/util/CalendarTimeUtil.php index 71edb69465..0fc4f2e527 100644 --- a/src/applications/calendar/util/CalendarTimeUtil.php +++ b/src/applications/calendar/util/CalendarTimeUtil.php @@ -10,7 +10,7 @@ * a Sunday -> Saturday list, whilest the profile view shows a more simple * seven day rolling list of events. */ -final class CalendarTimeUtil { +final class CalendarTimeUtil extends Phobject { public static function getCalendarEventEpochs( PhabricatorUser $user, diff --git a/src/applications/celerity/CelerityAPI.php b/src/applications/celerity/CelerityAPI.php index d5649471af..2d5100ad17 100644 --- a/src/applications/celerity/CelerityAPI.php +++ b/src/applications/celerity/CelerityAPI.php @@ -4,7 +4,7 @@ * Indirection layer which provisions for a terrifying future where we need to * build multiple resource responses per page. */ -final class CelerityAPI { +final class CelerityAPI extends Phobject { private static $response; diff --git a/src/applications/celerity/CelerityResourceMap.php b/src/applications/celerity/CelerityResourceMap.php index 7e5e00594b..03ccfe607d 100644 --- a/src/applications/celerity/CelerityResourceMap.php +++ b/src/applications/celerity/CelerityResourceMap.php @@ -6,7 +6,7 @@ * not need to invoke it directly; instead, you call higher-level Celerity APIs * and it uses the resource map to satisfy your requests. */ -final class CelerityResourceMap { +final class CelerityResourceMap extends Phobject { private static $instances = array(); @@ -16,6 +16,7 @@ final class CelerityResourceMap { private $packageMap; private $nameMap; private $hashMap; + private $componentMap; public function __construct(CelerityResources $resources) { $this->resources = $resources; diff --git a/src/applications/celerity/CelerityResourceMapGenerator.php b/src/applications/celerity/CelerityResourceMapGenerator.php index b9c4ddaa37..a5bb657bd9 100644 --- a/src/applications/celerity/CelerityResourceMapGenerator.php +++ b/src/applications/celerity/CelerityResourceMapGenerator.php @@ -1,6 +1,6 @@ assertTrue(true); + } + +} diff --git a/src/applications/conduit/call/ConduitCall.php b/src/applications/conduit/call/ConduitCall.php index 7d767cd8c1..89bddad542 100644 --- a/src/applications/conduit/call/ConduitCall.php +++ b/src/applications/conduit/call/ConduitCall.php @@ -8,9 +8,10 @@ * $result = $call->execute(); * */ -final class ConduitCall { +final class ConduitCall extends Phobject { private $method; + private $handler; private $request; private $user; diff --git a/src/applications/conduit/method/ConduitAPIMethod.php b/src/applications/conduit/method/ConduitAPIMethod.php index 8b9a67f4be..a56f680432 100644 --- a/src/applications/conduit/method/ConduitAPIMethod.php +++ b/src/applications/conduit/method/ConduitAPIMethod.php @@ -115,7 +115,7 @@ abstract class ConduitAPIMethod return head(explode('.', $this->getAPIMethodName(), 2)); } - public static function getConduitMethod($method_name) { + public static function loadAllConduitMethods() { static $method_map = null; if ($method_map === null) { @@ -143,6 +143,11 @@ abstract class ConduitAPIMethod } } + return $method_map; + } + + public static function getConduitMethod($method_name) { + $method_map = self::loadAllConduitMethods(); return idx($method_map, $method_name); } diff --git a/src/applications/conduit/method/__tests__/ConduitAPIMethodTestCase.php b/src/applications/conduit/method/__tests__/ConduitAPIMethodTestCase.php new file mode 100644 index 0000000000..d0f54e297c --- /dev/null +++ b/src/applications/conduit/method/__tests__/ConduitAPIMethodTestCase.php @@ -0,0 +1,10 @@ +assertTrue(true); + } + +} diff --git a/src/applications/conduit/protocol/ConduitAPIRequest.php b/src/applications/conduit/protocol/ConduitAPIRequest.php index fe8af34b65..be1b88323e 100644 --- a/src/applications/conduit/protocol/ConduitAPIRequest.php +++ b/src/applications/conduit/protocol/ConduitAPIRequest.php @@ -1,6 +1,6 @@ setAncestorClass(__CLASS__) ->setConcreteOnly(true) @@ -122,7 +122,11 @@ abstract class PhabricatorSetupCheck { $checks[] = newv($symbol['name'], array()); } - $checks = msort($checks, 'getExecutionOrder'); + return msort($checks, 'getExecutionOrder'); + } + + final public static function runAllChecks() { + $checks = self::loadAllChecks(); $issues = array(); foreach ($checks as $check) { diff --git a/src/applications/config/check/__tests__/PhabricatorSetupCheckTestCase.php b/src/applications/config/check/__tests__/PhabricatorSetupCheckTestCase.php new file mode 100644 index 0000000000..256b69ee7f --- /dev/null +++ b/src/applications/config/check/__tests__/PhabricatorSetupCheckTestCase.php @@ -0,0 +1,10 @@ +assertTrue(true); + } + +} diff --git a/src/applications/config/custom/PhabricatorConfigOptionType.php b/src/applications/config/custom/PhabricatorConfigOptionType.php index c50315a140..3f588452c4 100644 --- a/src/applications/config/custom/PhabricatorConfigOptionType.php +++ b/src/applications/config/custom/PhabricatorConfigOptionType.php @@ -1,6 +1,6 @@ getPHID(); + if (!$viewer_phid) { + return false; + } + + return (bool)$object->getParticipantIfExists($viewer_phid); + } + + public function getValueControlType() { + return self::CONTROL_TYPE_NONE; + } + +} diff --git a/src/applications/console/core/DarkConsoleCore.php b/src/applications/console/core/DarkConsoleCore.php index 321b681d50..6696eb453f 100644 --- a/src/applications/console/core/DarkConsoleCore.php +++ b/src/applications/console/core/DarkConsoleCore.php @@ -1,6 +1,6 @@ array( 'caption' => pht('Default view policy for new countdowns.'), + 'template' => PhabricatorCountdownCountdownPHIDType::TYPECONST, ), ); } diff --git a/src/applications/dashboard/layoutconfig/PhabricatorDashboardLayoutConfig.php b/src/applications/dashboard/layoutconfig/PhabricatorDashboardLayoutConfig.php index 9909515f06..0913be81d5 100644 --- a/src/applications/dashboard/layoutconfig/PhabricatorDashboardLayoutConfig.php +++ b/src/applications/dashboard/layoutconfig/PhabricatorDashboardLayoutConfig.php @@ -1,6 +1,6 @@ array( 'caption' => pht('Default view policy for newly created revisions.'), + 'template' => DifferentialRevisionPHIDType::TYPECONST, ), ); } diff --git a/src/applications/differential/constants/DifferentialAction.php b/src/applications/differential/constants/DifferentialAction.php index 5b5fa9eb71..6227d61dd0 100644 --- a/src/applications/differential/constants/DifferentialAction.php +++ b/src/applications/differential/constants/DifferentialAction.php @@ -1,6 +1,6 @@ rangeStart = $start; $this->rangeEnd = $end; diff --git a/src/applications/differential/parser/DifferentialCommitMessageParser.php b/src/applications/differential/parser/DifferentialCommitMessageParser.php index 00d2fe2c3f..fda7ae05b6 100644 --- a/src/applications/differential/parser/DifferentialCommitMessageParser.php +++ b/src/applications/differential/parser/DifferentialCommitMessageParser.php @@ -19,7 +19,7 @@ * @task support Support Methods * @task internal Internals */ -final class DifferentialCommitMessageParser { +final class DifferentialCommitMessageParser extends Phobject { private $labelMap; private $titleKey; diff --git a/src/applications/differential/parser/DifferentialHunkParser.php b/src/applications/differential/parser/DifferentialHunkParser.php index d49f4e1e26..8903c85f93 100644 --- a/src/applications/differential/parser/DifferentialHunkParser.php +++ b/src/applications/differential/parser/DifferentialHunkParser.php @@ -1,6 +1,6 @@ array(), + DiffusionDefaultViewCapability::CAPABILITY => array( + 'template' => PhabricatorRepositoryRepositoryPHIDType::TYPECONST, + ), DiffusionDefaultEditCapability::CAPABILITY => array( 'default' => PhabricatorPolicies::POLICY_ADMIN, + 'template' => PhabricatorRepositoryRepositoryPHIDType::TYPECONST, + ), + DiffusionDefaultPushCapability::CAPABILITY => array( + 'template' => PhabricatorRepositoryRepositoryPHIDType::TYPECONST, ), - DiffusionDefaultPushCapability::CAPABILITY => array(), DiffusionCreateRepositoriesCapability::CAPABILITY => array( 'default' => PhabricatorPolicies::POLICY_ADMIN, ), diff --git a/src/applications/diffusion/controller/DiffusionRepositoryCreateController.php b/src/applications/diffusion/controller/DiffusionRepositoryCreateController.php index 269523915e..9b6f4eee63 100644 --- a/src/applications/diffusion/controller/DiffusionRepositoryCreateController.php +++ b/src/applications/diffusion/controller/DiffusionRepositoryCreateController.php @@ -591,8 +591,8 @@ final class DiffusionRepositoryCreateController if ($this->isSSHProtocol($proto)) { $c_credential->setLabel(pht('SSH Key')); $c_credential->setCredentialType( - PassphraseCredentialTypeSSHPrivateKeyText::CREDENTIAL_TYPE); - $provides_type = PassphraseCredentialTypeSSHPrivateKey::PROVIDES_TYPE; + PassphraseSSHPrivateKeyTextCredentialType::CREDENTIAL_TYPE); + $provides_type = PassphraseSSHPrivateKeyCredentialType::PROVIDES_TYPE; $page->addRemarkupInstructions( pht( @@ -607,8 +607,8 @@ final class DiffusionRepositoryCreateController $c_credential->setLabel(pht('Password')); $c_credential->setAllowNull(true); $c_credential->setCredentialType( - PassphraseCredentialTypePassword::CREDENTIAL_TYPE); - $provides_type = PassphraseCredentialTypePassword::PROVIDES_TYPE; + PassphrasePasswordCredentialType::CREDENTIAL_TYPE); + $provides_type = PassphrasePasswordCredentialType::PROVIDES_TYPE; $page->addRemarkupInstructions( pht( @@ -663,7 +663,7 @@ final class DiffusionRepositoryCreateController pht('You must choose an SSH credential to connect over SSH.')); } - $ssh_type = PassphraseCredentialTypeSSHPrivateKey::PROVIDES_TYPE; + $ssh_type = PassphraseSSHPrivateKeyCredentialType::PROVIDES_TYPE; if ($credential->getProvidesType() !== $ssh_type) { $c_credential->setError(pht('Invalid')); $page->addPageError( @@ -674,7 +674,7 @@ final class DiffusionRepositoryCreateController } else if ($this->isUsernamePasswordProtocol($proto)) { if ($credential) { - $password_type = PassphraseCredentialTypePassword::PROVIDES_TYPE; + $password_type = PassphrasePasswordCredentialType::PROVIDES_TYPE; if ($credential->getProvidesType() !== $password_type) { $c_credential->setError(pht('Invalid')); $page->addPageError( diff --git a/src/applications/diffusion/data/DiffusionBrowseResultSet.php b/src/applications/diffusion/data/DiffusionBrowseResultSet.php index 4c2d8a1b85..2208aca505 100644 --- a/src/applications/diffusion/data/DiffusionBrowseResultSet.php +++ b/src/applications/diffusion/data/DiffusionBrowseResultSet.php @@ -1,6 +1,6 @@ attachRepository($repo); } else { + $this->didRejectResult($commit); unset($commits[$key]); continue; } diff --git a/src/applications/diffusion/query/DiffusionPathQuery.php b/src/applications/diffusion/query/DiffusionPathQuery.php index f442da7173..45dc978ec1 100644 --- a/src/applications/diffusion/query/DiffusionPathQuery.php +++ b/src/applications/diffusion/query/DiffusionPathQuery.php @@ -1,6 +1,6 @@ paths = $paths; diff --git a/src/applications/diffusion/request/DiffusionRequest.php b/src/applications/diffusion/request/DiffusionRequest.php index 2ed8e1f88e..6cf9aba8b3 100644 --- a/src/applications/diffusion/request/DiffusionRequest.php +++ b/src/applications/diffusion/request/DiffusionRequest.php @@ -7,7 +7,7 @@ * @task new Creating Requests * @task uri Managing Diffusion URIs */ -abstract class DiffusionRequest { +abstract class DiffusionRequest extends Phobject { protected $callsign; protected $path; diff --git a/src/applications/diffusion/ssh/DiffusionSubversionServeSSHWorkflow.php b/src/applications/diffusion/ssh/DiffusionSubversionServeSSHWorkflow.php index 4d085302c9..257e6e9adb 100644 --- a/src/applications/diffusion/ssh/DiffusionSubversionServeSSHWorkflow.php +++ b/src/applications/diffusion/ssh/DiffusionSubversionServeSSHWorkflow.php @@ -4,7 +4,6 @@ * This protocol has a good spec here: * * http://svn.apache.org/repos/asf/subversion/trunk/subversion/libsvn_ra_svn/protocol - * */ final class DiffusionSubversionServeSSHWorkflow extends DiffusionSubversionSSHWorkflow { diff --git a/src/applications/diffusion/symbol/DiffusionExternalSymbolQuery.php b/src/applications/diffusion/symbol/DiffusionExternalSymbolQuery.php index f8ca15aabd..d32f1b3f64 100644 --- a/src/applications/diffusion/symbol/DiffusionExternalSymbolQuery.php +++ b/src/applications/diffusion/symbol/DiffusionExternalSymbolQuery.php @@ -1,6 +1,6 @@ setName($book_name) - ->setViewPolicy(PhabricatorPolicies::POLICY_USER) + ->setViewPolicy(PhabricatorPolicies::getMostOpenPolicy()) ->save(); } diff --git a/src/applications/diviner/publisher/DivinerPublisher.php b/src/applications/diviner/publisher/DivinerPublisher.php index 1c0a56aaf4..591897f0e5 100644 --- a/src/applications/diviner/publisher/DivinerPublisher.php +++ b/src/applications/diviner/publisher/DivinerPublisher.php @@ -1,6 +1,6 @@ array(), + DrydockDefaultViewCapability::CAPABILITY => array( + 'template' => DrydockBlueprintPHIDType::TYPECONST, + ), DrydockDefaultEditCapability::CAPABILITY => array( 'default' => PhabricatorPolicies::POLICY_ADMIN, + 'template' => DrydockBlueprintPHIDType::TYPECONST, ), DrydockCreateBlueprintsCapability::CAPABILITY => array( 'default' => PhabricatorPolicies::POLICY_ADMIN, diff --git a/src/applications/drydock/blueprint/DrydockBlueprintImplementation.php b/src/applications/drydock/blueprint/DrydockBlueprintImplementation.php index d98d33a5e3..0abe12328b 100644 --- a/src/applications/drydock/blueprint/DrydockBlueprintImplementation.php +++ b/src/applications/drydock/blueprint/DrydockBlueprintImplementation.php @@ -5,7 +5,7 @@ * @task resource Resource Allocation * @task log Logging */ -abstract class DrydockBlueprintImplementation { +abstract class DrydockBlueprintImplementation extends Phobject { private $activeResource; private $activeLease; diff --git a/src/applications/drydock/blueprint/__tests__/DrydockBlueprintImplementationTestCase.php b/src/applications/drydock/blueprint/__tests__/DrydockBlueprintImplementationTestCase.php new file mode 100644 index 0000000000..b3f4a78a27 --- /dev/null +++ b/src/applications/drydock/blueprint/__tests__/DrydockBlueprintImplementationTestCase.php @@ -0,0 +1,10 @@ +assertTrue(true); + } + +} diff --git a/src/applications/drydock/constants/DrydockConstants.php b/src/applications/drydock/constants/DrydockConstants.php index 0905d67236..48d06329bf 100644 --- a/src/applications/drydock/constants/DrydockConstants.php +++ b/src/applications/drydock/constants/DrydockConstants.php @@ -1,3 +1,3 @@ getProvidesType() !== - PassphraseCredentialTypeSSHPrivateKey::PROVIDES_TYPE) { + PassphraseSSHPrivateKeyCredentialType::PROVIDES_TYPE) { throw new Exception(pht('Only private key credentials are supported.')); } diff --git a/src/applications/drydock/interface/filesystem/DrydockSFTPFilesystemInterface.php b/src/applications/drydock/interface/filesystem/DrydockSFTPFilesystemInterface.php index fe7d2d1cd3..41b126483d 100644 --- a/src/applications/drydock/interface/filesystem/DrydockSFTPFilesystemInterface.php +++ b/src/applications/drydock/interface/filesystem/DrydockSFTPFilesystemInterface.php @@ -16,7 +16,7 @@ final class DrydockSFTPFilesystemInterface extends DrydockFilesystemInterface { ->executeOne(); if ($credential->getProvidesType() !== - PassphraseCredentialTypeSSHPrivateKey::PROVIDES_TYPE) { + PassphraseSSHPrivateKeyCredentialType::PROVIDES_TYPE) { throw new Exception(pht('Only private key credentials are supported.')); } diff --git a/src/applications/drydock/util/DrydockBlueprintScopeGuard.php b/src/applications/drydock/util/DrydockBlueprintScopeGuard.php index ab8268ba12..343428683b 100644 --- a/src/applications/drydock/util/DrydockBlueprintScopeGuard.php +++ b/src/applications/drydock/util/DrydockBlueprintScopeGuard.php @@ -1,6 +1,8 @@ blueprint = $blueprint; diff --git a/src/applications/fact/engine/PhabricatorFactEngine.php b/src/applications/fact/engine/PhabricatorFactEngine.php index 99cee6a725..734b3296c0 100644 --- a/src/applications/fact/engine/PhabricatorFactEngine.php +++ b/src/applications/fact/engine/PhabricatorFactEngine.php @@ -1,6 +1,6 @@ assertTrue(true); + } + +} diff --git a/src/applications/fact/spec/PhabricatorFactSpec.php b/src/applications/fact/spec/PhabricatorFactSpec.php index a9646b246a..47fcc01d8b 100644 --- a/src/applications/fact/spec/PhabricatorFactSpec.php +++ b/src/applications/fact/spec/PhabricatorFactSpec.php @@ -1,6 +1,6 @@ newOption('feed.http-hooks', 'list', array()) ->setLocked(true) ->setSummary(pht('POST notifications of feed events.')) ->setDescription( pht( - "If you set this to a list of http URIs, when a feed story is ". - "published a task will be created for each uri that posts the ". - "story data to the uri. Daemons automagically retry failures 100 ". - "times, waiting \$fail_count * 60s between each subsequent ". - "failure. Be sure to keep the daemon console (/daemon/) open ". + "If you set this to a list of HTTP URIs, when a feed story is ". + "published a task will be created for each URI that posts the ". + "story data to the URI. Daemons automagically retry failures 100 ". + "times, waiting `\$fail_count * 60s` between each subsequent ". + "failure. Be sure to keep the daemon console (`%s`) open ". "while developing and testing your end points. You may need to". - "restart your daemons to start sending http requests.\n\n". - "NOTE: URIs are not validated, the URI must return http status ". - "200 within 30 seconds, and no permission checks are performed.")), + "restart your daemons to start sending HTTP requests.\n\n". + "NOTE: URIs are not validated, the URI must return HTTP status ". + "200 within 30 seconds, and no permission checks are performed.", + '/daemon/')), ); } diff --git a/src/applications/feed/query/PhabricatorFeedQuery.php b/src/applications/feed/query/PhabricatorFeedQuery.php index b9c7d099aa..13cfb266ed 100644 --- a/src/applications/feed/query/PhabricatorFeedQuery.php +++ b/src/applications/feed/query/PhabricatorFeedQuery.php @@ -101,7 +101,7 @@ final class PhabricatorFeedQuery 'key' => array( 'table' => $table, 'column' => 'chronologicalKey', - 'type' => 'int', + 'type' => 'string', 'unique' => true, ), ); diff --git a/src/applications/feed/story/PhabricatorFeedStory.php b/src/applications/feed/story/PhabricatorFeedStory.php index 253757b8de..03b55df5db 100644 --- a/src/applications/feed/story/PhabricatorFeedStory.php +++ b/src/applications/feed/story/PhabricatorFeedStory.php @@ -9,6 +9,7 @@ * @task policy Policy Implementation */ abstract class PhabricatorFeedStory + extends Phobject implements PhabricatorPolicyInterface, PhabricatorMarkupInterface { diff --git a/src/applications/files/PhabricatorImageTransformer.php b/src/applications/files/PhabricatorImageTransformer.php index 829f5d9f2d..75e83c223d 100644 --- a/src/applications/files/PhabricatorImageTransformer.php +++ b/src/applications/files/PhabricatorImageTransformer.php @@ -4,7 +4,7 @@ * @task enormous Detecting Enormous Images * @task save Saving Image Data */ -final class PhabricatorImageTransformer { +final class PhabricatorImageTransformer extends Phobject { public function executeMemeTransform( PhabricatorFile $file, diff --git a/src/applications/files/application/PhabricatorFilesApplication.php b/src/applications/files/application/PhabricatorFilesApplication.php index b80a8e1ae4..1714719f8e 100644 --- a/src/applications/files/application/PhabricatorFilesApplication.php +++ b/src/applications/files/application/PhabricatorFilesApplication.php @@ -60,6 +60,7 @@ final class PhabricatorFilesApplication extends PhabricatorApplication { return array( FilesDefaultViewCapability::CAPABILITY => array( 'caption' => pht('Default view policy for newly created files.'), + 'template' => PhabricatorFileFilePHIDType::TYPECONST, ), ); } diff --git a/src/applications/files/engine/PhabricatorFileStorageEngine.php b/src/applications/files/engine/PhabricatorFileStorageEngine.php index be2fb2bbd3..3ec0ee2fa5 100644 --- a/src/applications/files/engine/PhabricatorFileStorageEngine.php +++ b/src/applications/files/engine/PhabricatorFileStorageEngine.php @@ -14,7 +14,7 @@ * @task file Managing File Data * @task load Loading Storage Engines */ -abstract class PhabricatorFileStorageEngine { +abstract class PhabricatorFileStorageEngine extends Phobject { /** * Construct a new storage engine. diff --git a/src/applications/files/engine/__tests__/PhabricatorFileStorageEngineTestCase.php b/src/applications/files/engine/__tests__/PhabricatorFileStorageEngineTestCase.php new file mode 100644 index 0000000000..8ffbe0366b --- /dev/null +++ b/src/applications/files/engine/__tests__/PhabricatorFileStorageEngineTestCase.php @@ -0,0 +1,10 @@ +assertTrue(true); + } + +} diff --git a/src/applications/files/query/PhabricatorFileBundleLoader.php b/src/applications/files/query/PhabricatorFileBundleLoader.php index 0cc7603020..76b90debf6 100644 --- a/src/applications/files/query/PhabricatorFileBundleLoader.php +++ b/src/applications/files/query/PhabricatorFileBundleLoader.php @@ -4,7 +4,7 @@ * Callback provider for loading @{class@arcanist:ArcanistBundle} file data * stored in the Files application. */ -final class PhabricatorFileBundleLoader { +final class PhabricatorFileBundleLoader extends Phobject { private $viewer; diff --git a/src/applications/files/transform/__tests__/PhabricatorFileTransformTestCase.php b/src/applications/files/transform/__tests__/PhabricatorFileTransformTestCase.php new file mode 100644 index 0000000000..4cc4a6e54b --- /dev/null +++ b/src/applications/files/transform/__tests__/PhabricatorFileTransformTestCase.php @@ -0,0 +1,10 @@ +assertTrue(true); + } + +} diff --git a/src/applications/flag/constants/PhabricatorFlagConstants.php b/src/applications/flag/constants/PhabricatorFlagConstants.php index 968443a33d..5162b928c6 100644 --- a/src/applications/flag/constants/PhabricatorFlagConstants.php +++ b/src/applications/flag/constants/PhabricatorFlagConstants.php @@ -1,3 +1,3 @@ array( 'caption' => pht('Default view policy for newly created initiatives.'), + 'tempate' => FundInitiativePHIDType::TYPECONST, ), FundCreateInitiativesCapability::CAPABILITY => array( 'default' => PhabricatorPolicies::POLICY_ADMIN, diff --git a/src/applications/harbormaster/query/HarbormasterBuildLogQuery.php b/src/applications/harbormaster/query/HarbormasterBuildLogQuery.php index f0f2021fd8..3d45de686f 100644 --- a/src/applications/harbormaster/query/HarbormasterBuildLogQuery.php +++ b/src/applications/harbormaster/query/HarbormasterBuildLogQuery.php @@ -6,6 +6,7 @@ final class HarbormasterBuildLogQuery private $ids; private $phids; private $buildPHIDs; + private $buildTargetPHIDs; public function withIDs(array $ids) { $this->ids = $ids; diff --git a/src/applications/harbormaster/step/HarbormasterBuildStepImplementation.php b/src/applications/harbormaster/step/HarbormasterBuildStepImplementation.php index 5262366ac9..26450722b9 100644 --- a/src/applications/harbormaster/step/HarbormasterBuildStepImplementation.php +++ b/src/applications/harbormaster/step/HarbormasterBuildStepImplementation.php @@ -1,6 +1,6 @@ pht('Credentials'), 'type' => 'credential', 'credential.type' - => PassphraseCredentialTypePassword::CREDENTIAL_TYPE, + => PassphrasePasswordCredentialType::CREDENTIAL_TYPE, 'credential.provides' - => PassphraseCredentialTypePassword::PROVIDES_TYPE, + => PassphrasePasswordCredentialType::PROVIDES_TYPE, ), ); } diff --git a/src/applications/harbormaster/step/__tests__/HarbormasterBuildStepImplementationTestCase.php b/src/applications/harbormaster/step/__tests__/HarbormasterBuildStepImplementationTestCase.php new file mode 100644 index 0000000000..6a37b0112d --- /dev/null +++ b/src/applications/harbormaster/step/__tests__/HarbormasterBuildStepImplementationTestCase.php @@ -0,0 +1,11 @@ +assertTrue(true); + } + +} diff --git a/src/applications/herald/adapter/HeraldAdapter.php b/src/applications/herald/adapter/HeraldAdapter.php index f50bdf4203..01014adedf 100644 --- a/src/applications/herald/adapter/HeraldAdapter.php +++ b/src/applications/herald/adapter/HeraldAdapter.php @@ -3,7 +3,7 @@ /** * @task customfield Custom Field Integration */ -abstract class HeraldAdapter { +abstract class HeraldAdapter extends Phobject { const FIELD_TITLE = 'title'; const FIELD_BODY = 'body'; @@ -44,6 +44,7 @@ abstract class HeraldAdapter { const FIELD_TASK_STATUS = 'taskstatus'; const FIELD_PUSHER_IS_COMMITTER = 'pusher-is-committer'; const FIELD_PATH = 'path'; + const FIELD_SPACE = 'space'; const CONDITION_CONTAINS = 'contains'; const CONDITION_NOT_CONTAINS = '!contains'; @@ -101,6 +102,7 @@ abstract class HeraldAdapter { const VALUE_TASK_STATUS = 'taskstatus'; const VALUE_LEGAL_DOCUMENTS = 'legaldocuments'; const VALUE_APPLICATION_EMAIL = 'applicationemail'; + const VALUE_SPACE = 'space'; private $contentSource; private $isNewObject; @@ -219,6 +221,19 @@ abstract class HeraldAdapter { $value[] = $this->getApplicationEmail()->getPHID(); } return $value; + case self::FIELD_SPACE: + $object = $this->getObject(); + + if (!($object instanceof PhabricatorSpacesInterface)) { + throw new Exception( + pht( + 'Adapter object (of class "%s") does not implement interface '. + '"%s", so the Space field value can not be determined.', + get_class($object), + 'PhabricatorSpacesInterface')); + } + + return PhabricatorSpacesNamespaceQuery::getObjectSpacePHID($object); default: if ($this->isHeraldCustomKey($field_name)) { return $this->getCustomFieldValue($field_name); @@ -400,6 +415,7 @@ abstract class HeraldAdapter { self::FIELD_TASK_STATUS => pht('Task status'), self::FIELD_PUSHER_IS_COMMITTER => pht('Pusher same as committer'), self::FIELD_PATH => pht('Path'), + self::FIELD_SPACE => pht('Space'), ) + $this->getCustomFieldNameMap(); } @@ -453,6 +469,7 @@ abstract class HeraldAdapter { case self::FIELD_PUSHER: case self::FIELD_TASK_PRIORITY: case self::FIELD_TASK_STATUS: + case self::FIELD_SPACE: return array( self::CONDITION_IS_ANY, self::CONDITION_IS_NOT_ANY, @@ -957,6 +974,8 @@ abstract class HeraldAdapter { return self::VALUE_TASK_PRIORITY; case self::FIELD_TASK_STATUS: return self::VALUE_TASK_STATUS; + case self::FIELD_SPACE: + return self::VALUE_SPACE; default: return self::VALUE_USER; } diff --git a/src/applications/herald/adapter/HeraldDifferentialRevisionAdapter.php b/src/applications/herald/adapter/HeraldDifferentialRevisionAdapter.php index afd328b342..a731254870 100644 --- a/src/applications/herald/adapter/HeraldDifferentialRevisionAdapter.php +++ b/src/applications/herald/adapter/HeraldDifferentialRevisionAdapter.php @@ -3,6 +3,7 @@ final class HeraldDifferentialRevisionAdapter extends HeraldDifferentialAdapter { + protected $diff; protected $revision; protected $explicitReviewers; diff --git a/src/applications/herald/adapter/HeraldManiphestTaskAdapter.php b/src/applications/herald/adapter/HeraldManiphestTaskAdapter.php index a84130095a..906981af39 100644 --- a/src/applications/herald/adapter/HeraldManiphestTaskAdapter.php +++ b/src/applications/herald/adapter/HeraldManiphestTaskAdapter.php @@ -73,6 +73,7 @@ final class HeraldManiphestTaskAdapter extends HeraldAdapter { self::FIELD_TASK_STATUS, self::FIELD_IS_NEW_OBJECT, self::FIELD_APPLICATION_EMAIL, + self::FIELD_SPACE, ), parent::getFields()); } diff --git a/src/applications/herald/adapter/HeraldPholioMockAdapter.php b/src/applications/herald/adapter/HeraldPholioMockAdapter.php index e4aab69e95..5c9c78c0ac 100644 --- a/src/applications/herald/adapter/HeraldPholioMockAdapter.php +++ b/src/applications/herald/adapter/HeraldPholioMockAdapter.php @@ -52,6 +52,7 @@ final class HeraldPholioMockAdapter extends HeraldAdapter { self::FIELD_CC, self::FIELD_PROJECTS, self::FIELD_IS_NEW_OBJECT, + self::FIELD_SPACE, ), parent::getFields()); } diff --git a/src/applications/herald/config/HeraldRepetitionPolicyConfig.php b/src/applications/herald/config/HeraldRepetitionPolicyConfig.php index aa64a0ecc3..40e84f0ae4 100644 --- a/src/applications/herald/config/HeraldRepetitionPolicyConfig.php +++ b/src/applications/herald/config/HeraldRepetitionPolicyConfig.php @@ -1,6 +1,6 @@ new PhabricatorMetaMTAMailableDatasource(), 'userorproject' => new PhabricatorProjectOrUserDatasource(), 'applicationemail' => new PhabricatorMetaMTAApplicationEmailDatasource(), + 'space' => new PhabricatorSpacesNamespaceDatasource(), ); foreach ($sources as $key => $source) { diff --git a/src/applications/herald/engine/HeraldEffect.php b/src/applications/herald/engine/HeraldEffect.php index d9a536be37..52d86cf5df 100644 --- a/src/applications/herald/engine/HeraldEffect.php +++ b/src/applications/herald/engine/HeraldEffect.php @@ -1,6 +1,6 @@ getTableName(), time() - $ttl); diff --git a/src/applications/herald/storage/transcript/HeraldConditionTranscript.php b/src/applications/herald/storage/transcript/HeraldConditionTranscript.php index f78f31a555..36a534e6b0 100644 --- a/src/applications/herald/storage/transcript/HeraldConditionTranscript.php +++ b/src/applications/herald/storage/transcript/HeraldConditionTranscript.php @@ -1,6 +1,6 @@ array(), - LegalpadDefaultViewCapability::CAPABILITY => array(), - LegalpadDefaultEditCapability::CAPABILITY => array(), + LegalpadDefaultViewCapability::CAPABILITY => array( + 'template' => PhabricatorLegalpadDocumentPHIDType::TYPECONST, + ), + LegalpadDefaultEditCapability::CAPABILITY => array( + 'template' => PhabricatorLegalpadDocumentPHIDType::TYPECONST, + ), ); } diff --git a/src/applications/lipsum/generator/PhabricatorTestDataGenerator.php b/src/applications/lipsum/generator/PhabricatorTestDataGenerator.php index 9adf6fca70..9bff25a068 100644 --- a/src/applications/lipsum/generator/PhabricatorTestDataGenerator.php +++ b/src/applications/lipsum/generator/PhabricatorTestDataGenerator.php @@ -1,6 +1,6 @@ getFile(); - $item = new PHUIPinboardItemView(); + $item = id(new PHUIPinboardItemView()) + ->setUser($viewer) + ->setObject($macro); + if ($file) { $item->setImageURI($file->getURIForTransform($xform)); list($x, $y) = $xform->getTransformedDimensions($file); diff --git a/src/applications/maniphest/application/PhabricatorManiphestApplication.php b/src/applications/maniphest/application/PhabricatorManiphestApplication.php index 3937d6be7f..3debdb44ca 100644 --- a/src/applications/maniphest/application/PhabricatorManiphestApplication.php +++ b/src/applications/maniphest/application/PhabricatorManiphestApplication.php @@ -131,9 +131,11 @@ final class PhabricatorManiphestApplication extends PhabricatorApplication { return array( ManiphestDefaultViewCapability::CAPABILITY => array( 'caption' => pht('Default view policy for newly created tasks.'), + 'template' => ManiphestTaskPHIDType::TYPECONST, ), ManiphestDefaultEditCapability::CAPABILITY => array( 'caption' => pht('Default edit policy for newly created tasks.'), + 'template' => ManiphestTaskPHIDType::TYPECONST, ), ManiphestEditStatusCapability::CAPABILITY => array(), ManiphestEditAssignCapability::CAPABILITY => array(), diff --git a/src/applications/maniphest/constants/ManiphestConstants.php b/src/applications/maniphest/constants/ManiphestConstants.php index fa0d78b6a0..7aba636a69 100644 --- a/src/applications/maniphest/constants/ManiphestConstants.php +++ b/src/applications/maniphest/constants/ManiphestConstants.php @@ -1,3 +1,3 @@ setViewer($viewer); $owner_source = new ManiphestAssigneeDatasource(); $owner_source->setViewer($viewer); + $spaces_source = id(new PhabricatorSpacesNamespaceDatasource()) + ->setViewer($viewer); require_celerity_resource('maniphest-batch-editor'); Javelin::initBehavior( @@ -112,6 +114,12 @@ final class ManiphestBatchEditController extends ManiphestController { 'placeholder' => $mailable_source->getPlaceholderText(), 'browseURI' => $mailable_source->getBrowseURI(), ), + 'spaces' => array( + 'src' => $spaces_source->getDatasourceURI(), + 'placeholder' => $spaces_source->getPlaceholderText(), + 'browseURI' => $spaces_source->getBrowseURI(), + 'limit' => 1, + ), ), 'input' => 'batch-form-actions', 'priorityMap' => ManiphestTaskPriority::getTaskPriorityMap(), @@ -201,6 +209,7 @@ final class ManiphestBatchEditController extends ManiphestController { 'remove_project' => PhabricatorTransactions::TYPE_EDGE, 'add_ccs' => PhabricatorTransactions::TYPE_SUBSCRIBERS, 'remove_ccs' => PhabricatorTransactions::TYPE_SUBSCRIBERS, + 'space' => PhabricatorTransactions::TYPE_SPACE, ); $edge_edit_types = array( @@ -246,6 +255,10 @@ final class ManiphestBatchEditController extends ManiphestController { case PhabricatorTransactions::TYPE_SUBSCRIBERS: $current = $task->getSubscriberPHIDs(); break; + case PhabricatorTransactions::TYPE_SPACE: + $current = PhabricatorSpacesNamespaceQuery::getObjectSpacePHID( + $task); + break; } } @@ -260,6 +273,12 @@ final class ManiphestBatchEditController extends ManiphestController { continue 2; } break; + case PhabricatorTransactions::TYPE_SPACE: + if (empty($value)) { + continue 2; + } + $value = head($value); + break; case ManiphestTransaction::TYPE_OWNER: if (empty($value)) { continue 2; diff --git a/src/applications/maniphest/controller/ManiphestTaskEditController.php b/src/applications/maniphest/controller/ManiphestTaskEditController.php index d9a4e44381..72b75c876f 100644 --- a/src/applications/maniphest/controller/ManiphestTaskEditController.php +++ b/src/applications/maniphest/controller/ManiphestTaskEditController.php @@ -155,12 +155,15 @@ final class ManiphestTaskEditController extends ManiphestController { $aux_fields = $field_list->getFields(); + $v_space = $task->getSpacePHID(); + if ($request->isFormPost()) { $changes = array(); $new_title = $request->getStr('title'); $new_desc = $request->getStr('description'); $new_status = $request->getStr('status'); + $v_space = $request->getStr('spacePHID'); if (!$task->getID()) { $workflow = 'create'; @@ -268,6 +271,7 @@ final class ManiphestTaskEditController extends ManiphestController { } if ($can_edit_policies) { + $changes[PhabricatorTransactions::TYPE_SPACE] = $v_space; $changes[PhabricatorTransactions::TYPE_VIEW_POLICY] = $request->getStr('viewPolicy'); $changes[PhabricatorTransactions::TYPE_EDIT_POLICY] = @@ -477,6 +481,8 @@ final class ManiphestTaskEditController extends ManiphestController { $task->setViewPolicy($template_task->getViewPolicy()); $task->setEditPolicy($template_task->getEditPolicy()); + $v_space = $template_task->getSpacePHID(); + $template_fields = PhabricatorCustomField::getObjectFields( $template_task, PhabricatorCustomField::ROLE_EDIT); @@ -643,6 +649,7 @@ final class ManiphestTaskEditController extends ManiphestController { ->setCapability(PhabricatorPolicyCapability::CAN_VIEW) ->setPolicyObject($task) ->setPolicies($policies) + ->setSpacePHID($v_space) ->setName('viewPolicy')) ->appendChild( id(new AphrontFormPolicyControl()) diff --git a/src/applications/maniphest/export/ManiphestExcelFormat.php b/src/applications/maniphest/export/ManiphestExcelFormat.php index f22df69976..29c94f475a 100644 --- a/src/applications/maniphest/export/ManiphestExcelFormat.php +++ b/src/applications/maniphest/export/ManiphestExcelFormat.php @@ -1,6 +1,6 @@ assertTrue(true); + } + +} diff --git a/src/applications/maniphest/policyrule/ManiphestTaskAuthorPolicyRule.php b/src/applications/maniphest/policyrule/ManiphestTaskAuthorPolicyRule.php new file mode 100644 index 0000000000..04a39ff71c --- /dev/null +++ b/src/applications/maniphest/policyrule/ManiphestTaskAuthorPolicyRule.php @@ -0,0 +1,43 @@ +getPHID(); + if (!$viewer_phid) { + return false; + } + + return ($object->getAuthorPHID() == $viewer_phid); + } + + public function getValueControlType() { + return self::CONTROL_TYPE_NONE; + } + +} diff --git a/src/applications/maniphest/query/ManiphestTaskQuery.php b/src/applications/maniphest/query/ManiphestTaskQuery.php index 956810524d..841a917312 100644 --- a/src/applications/maniphest/query/ManiphestTaskQuery.php +++ b/src/applications/maniphest/query/ManiphestTaskQuery.php @@ -721,9 +721,13 @@ final class ManiphestTaskQuery extends PhabricatorCursorPagedPolicyAwareQuery { ), 'updated' => array( 'vector' => array('updated', 'id'), - 'name' => pht('Date Updated'), + 'name' => pht('Date Updated (Latest First)'), 'aliases' => array(self::ORDER_MODIFIED), ), + 'outdated' => array( + 'vector' => array('-updated', '-id'), + 'name' => pht('Date Updated (Oldest First)'), + ), 'title' => array( 'vector' => array('title', 'id'), 'name' => pht('Title'), @@ -739,6 +743,7 @@ final class ManiphestTaskQuery extends PhabricatorCursorPagedPolicyAwareQuery { array( 'priority', 'updated', + 'outdated', 'newest', 'oldest', 'title', diff --git a/src/applications/maniphest/query/ManiphestTaskSearchEngine.php b/src/applications/maniphest/query/ManiphestTaskSearchEngine.php index 8a875202f1..ae5b5353c7 100644 --- a/src/applications/maniphest/query/ManiphestTaskSearchEngine.php +++ b/src/applications/maniphest/query/ManiphestTaskSearchEngine.php @@ -43,7 +43,7 @@ final class ManiphestTaskSearchEngine ->needProjectPHIDs(true); } - public function buildCustomSearchFields() { + protected function buildCustomSearchFields() { return array( id(new PhabricatorSearchOwnersField()) ->setLabel(pht('Assigned To')) @@ -105,7 +105,7 @@ final class ManiphestTaskSearchEngine ); } - public function getDefaultFieldOrder() { + protected function getDefaultFieldOrder() { return array( 'assignedPHIDs', 'projectPHIDs', @@ -128,7 +128,7 @@ final class ManiphestTaskSearchEngine ); } - public function getHiddenFields() { + protected function getHiddenFields() { $keys = array(); if ($this->getIsBoardView()) { @@ -140,7 +140,7 @@ final class ManiphestTaskSearchEngine return $keys; } - public function buildQueryFromParameters(array $map) { + protected function buildQueryFromParameters(array $map) { $query = id(new ManiphestTaskQuery()) ->needProjectPHIDs(true); diff --git a/src/applications/maniphest/storage/ManiphestTask.php b/src/applications/maniphest/storage/ManiphestTask.php index cdf4b4a575..7fbc806bae 100644 --- a/src/applications/maniphest/storage/ManiphestTask.php +++ b/src/applications/maniphest/storage/ManiphestTask.php @@ -12,7 +12,8 @@ final class ManiphestTask extends ManiphestDAO PhabricatorCustomFieldInterface, PhabricatorDestructibleInterface, PhabricatorApplicationTransactionInterface, - PhabricatorProjectInterface { + PhabricatorProjectInterface, + PhabricatorSpacesInterface { const MARKUP_FIELD_DESCRIPTION = 'markup:desc'; @@ -35,6 +36,7 @@ final class ManiphestTask extends ManiphestDAO protected $projectPHIDs = array(); protected $ownerOrdering; + protected $spacePHID; private $subscriberPHIDs = self::ATTACHABLE; private $groupByProjectPHID = self::ATTACHABLE; @@ -56,6 +58,7 @@ final class ManiphestTask extends ManiphestDAO ->setAuthorPHID($actor->getPHID()) ->setViewPolicy($view_policy) ->setEditPolicy($edit_policy) + ->setSpacePHID($actor->getDefaultSpacePHID()) ->attachProjectPHIDs(array()) ->attachSubscriberPHIDs(array()); } @@ -379,4 +382,12 @@ final class ManiphestTask extends ManiphestDAO return $timeline; } + +/* -( PhabricatorSpacesInterface )----------------------------------------- */ + + + public function getSpacePHID() { + return $this->spacePHID; + } + } diff --git a/src/applications/maniphest/view/ManiphestTaskListView.php b/src/applications/maniphest/view/ManiphestTaskListView.php index efab4c42f7..799bb0ae38 100644 --- a/src/applications/maniphest/view/ManiphestTaskListView.php +++ b/src/applications/maniphest/view/ManiphestTaskListView.php @@ -56,10 +56,12 @@ final class ManiphestTaskListView extends ManiphestView { } foreach ($this->tasks as $task) { - $item = new PHUIObjectItemView(); - $item->setObjectName('T'.$task->getID()); - $item->setHeader($task->getTitle()); - $item->setHref('/T'.$task->getID()); + $item = id(new PHUIObjectItemView()) + ->setUser($this->getUser()) + ->setObject($task) + ->setObjectName('T'.$task->getID()) + ->setHeader($task->getTitle()) + ->setHref('/T'.$task->getID()); if ($task->getOwnerPHID()) { $owner = $handles[$task->getOwnerPHID()]; diff --git a/src/applications/meta/controller/PhabricatorApplicationEditController.php b/src/applications/meta/controller/PhabricatorApplicationEditController.php index dffb46c6a1..ba82b30053 100644 --- a/src/applications/meta/controller/PhabricatorApplicationEditController.php +++ b/src/applications/meta/controller/PhabricatorApplicationEditController.php @@ -124,8 +124,7 @@ final class PhabricatorApplicationEditController ->setValue(idx($descriptions, $capability)) ->setCaption($caption)); } else { - $form->appendChild( - id(new AphrontFormPolicyControl()) + $control = id(new AphrontFormPolicyControl()) ->setUser($user) ->setDisabled($locked) ->setCapability($capability) @@ -133,7 +132,28 @@ final class PhabricatorApplicationEditController ->setPolicies($policies) ->setLabel($label) ->setName('policy:'.$capability) - ->setCaption($caption)); + ->setCaption($caption); + + $template = $application->getCapabilityTemplatePHIDType($capability); + if ($template) { + $phid_types = PhabricatorPHIDType::getAllTypes(); + $phid_type = idx($phid_types, $template); + if ($phid_type) { + $template_object = $phid_type->newObject(); + if ($template_object) { + $template_policies = id(new PhabricatorPolicyQuery()) + ->setViewer($user) + ->setObject($template_object) + ->execute(); + $control->setPolicies($template_policies); + $control->setTemplateObject($template_object); + } + } + + $control->setTemplatePHIDType($template); + } + + $form->appendControl($control); } } diff --git a/src/applications/meta/panel/__tests__/PhabricatorApplicationConfigurationPanelTestCase.php b/src/applications/meta/panel/__tests__/PhabricatorApplicationConfigurationPanelTestCase.php new file mode 100644 index 0000000000..10aab23771 --- /dev/null +++ b/src/applications/meta/panel/__tests__/PhabricatorApplicationConfigurationPanelTestCase.php @@ -0,0 +1,11 @@ +assertTrue(true); + } + +} diff --git a/src/applications/metamta/adapter/PhabricatorMailImplementationAdapter.php b/src/applications/metamta/adapter/PhabricatorMailImplementationAdapter.php index 8b7fd60167..3363301909 100644 --- a/src/applications/metamta/adapter/PhabricatorMailImplementationAdapter.php +++ b/src/applications/metamta/adapter/PhabricatorMailImplementationAdapter.php @@ -1,6 +1,6 @@ getViewer(); $application = $this->getApplication(); - $addresses = id(new PhabricatorMetaMTAApplicationEmailQuery()) - ->setViewer($viewer) - ->withApplicationPHIDs(array($application->getPHID())) - ->execute(); - - $rows = array(); - foreach ($addresses as $address) { - $rows[] = array( - $address->getAddress(), - ); - } - - $table = id(new AphrontTableView($rows)) - ->setNoDataString(pht('No email addresses configured.')) - ->setHeaders( - array( - pht('Address'), - )); + $table = $this->buildEmailTable($is_edit = false, null); $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, @@ -91,68 +74,10 @@ final class PhabricatorMetaMTAApplicationEmailPanel return $this->returnDeleteAddressResponse($request, $uri, $delete); } - $emails = id(new PhabricatorMetaMTAApplicationEmailQuery()) - ->setViewer($viewer) - ->withApplicationPHIDs(array($application->getPHID())) - ->execute(); + $table = $this->buildEmailTable( + $is_edit = true, + $request->getInt('id')); - $highlight = $request->getInt('highlight'); - $rowc = array(); - $rows = array(); - foreach ($emails as $email) { - - $button_edit = javelin_tag( - 'a', - array( - 'class' => 'button small grey', - 'href' => $uri->alter('edit', $email->getID()), - 'sigil' => 'workflow', - ), - pht('Edit')); - - $button_remove = javelin_tag( - 'a', - array( - 'class' => 'button small grey', - 'href' => $uri->alter('delete', $email->getID()), - 'sigil' => 'workflow', - ), - pht('Delete')); - - if ($highlight == $email->getID()) { - $rowc[] = 'highlighted'; - } else { - $rowc[] = null; - } - - $rows[] = array( - $email->getAddress(), - $button_edit, - $button_remove, - ); - } - - $table = id(new AphrontTableView($rows)) - ->setNoDataString(pht('No application emails created yet.')); - $table->setHeaders( - array( - pht('Email'), - pht('Edit'), - pht('Delete'), - )); - $table->setColumnClasses( - array( - 'wide', - 'action', - 'action', - )); - $table->setRowClasses($rowc); - $table->setColumnVisibility( - array( - true, - true, - true, - )); $form = id(new AphrontFormView()) ->setUser($viewer); @@ -190,30 +115,6 @@ final class PhabricatorMetaMTAApplicationEmailPanel )); } - private function validateApplicationEmail($email) { - $errors = array(); - $e_email = true; - - if (!strlen($email)) { - $e_email = pht('Required'); - $errors[] = pht('Email is required.'); - } else if (!PhabricatorUserEmail::isValidAddress($email)) { - $e_email = pht('Invalid'); - $errors[] = PhabricatorUserEmail::describeValidAddresses(); - } else if (!PhabricatorUserEmail::isAllowedAddress($email)) { - $e_email = pht('Disallowed'); - $errors[] = PhabricatorUserEmail::describeAllowedAddresses(); - } - $user_emails = id(new PhabricatorUserEmail()) - ->loadAllWhere('address = %s', $email); - if ($user_emails) { - $e_email = pht('Duplicate'); - $errors[] = pht('A user already has this email.'); - } - - return array($e_email, $errors); - } - private function returnNewAddressResponse( AphrontRequest $request, PhutilURI $uri, @@ -265,45 +166,68 @@ final class PhabricatorMetaMTAApplicationEmailPanel $viewer = $request->getUser(); - $e_email = true; - $email = null; - $errors = array(); - $default_user_key = + $config_default = PhabricatorMetaMTAApplicationEmail::CONFIG_DEFAULT_AUTHOR; + + $e_email = true; + $v_email = $email_object->getAddress(); + $e_space = null; + $v_space = $email_object->getSpacePHID(); + $v_default = $email_object->getConfigValue($config_default); + + $validation_exception = null; if ($request->isDialogFormPost()) { - $email = trim($request->getStr('email')); - list($e_email, $errors) = $this->validateApplicationEmail($email); - $email_object->setAddress($email); - $default_user = $request->getArr($default_user_key); - $default_user = reset($default_user); - if ($default_user) { - $email_object->setConfigValue($default_user_key, $default_user); - } + $e_email = null; - if (!$errors) { - try { - $email_object->save(); - return id(new AphrontRedirectResponse())->setURI( - $uri->alter('highlight', $email_object->getID())); - } catch (AphrontDuplicateKeyQueryException $ex) { - $e_email = pht('Duplicate'); - $errors[] = pht( - 'Another application is already configured to use this email '. - 'address.'); - } + $v_email = trim($request->getStr('email')); + $v_space = $request->getStr('spacePHID'); + $v_default = $request->getArr($config_default); + $v_default = nonempty(head($v_default), null); + + $type_address = + PhabricatorMetaMTAApplicationEmailTransaction::TYPE_ADDRESS; + $type_space = PhabricatorTransactions::TYPE_SPACE; + $type_config = + PhabricatorMetaMTAApplicationEmailTransaction::TYPE_CONFIG; + + $key_config = PhabricatorMetaMTAApplicationEmailTransaction::KEY_CONFIG; + + $xactions = array(); + + $xactions[] = id(new PhabricatorMetaMTAApplicationEmailTransaction()) + ->setTransactionType($type_address) + ->setNewValue($v_email); + + $xactions[] = id(new PhabricatorMetaMTAApplicationEmailTransaction()) + ->setTransactionType($type_space) + ->setNewValue($v_space); + + $xactions[] = id(new PhabricatorMetaMTAApplicationEmailTransaction()) + ->setTransactionType($type_config) + ->setMetadataValue($key_config, $config_default) + ->setNewValue($v_default); + + $editor = id(new PhabricatorMetaMTAApplicationEmailEditor()) + ->setActor($viewer) + ->setContentSourceFromRequest($request) + ->setContinueOnNoEffect(true); + + try { + $editor->applyTransactions($email_object, $xactions); + + return id(new AphrontRedirectResponse())->setURI( + $uri->alter('highlight', $email_object->getID())); + } catch (PhabricatorApplicationTransactionValidationException $ex) { + $validation_exception = $ex; + $e_email = $ex->getShortMessage($type_address); + $e_space = $ex->getShortMessage($type_space); } } - if ($errors) { - $errors = id(new PHUIInfoView()) - ->setErrors($errors); - } - - $default_user = $email_object->getConfigValue($default_user_key); - if ($default_user) { - $default_user_value = array($default_user); + if ($v_default) { + $v_default = array($v_default); } else { - $default_user_value = array(); + $v_default = array(); } $form = id(new AphrontFormView()) @@ -312,28 +236,44 @@ final class PhabricatorMetaMTAApplicationEmailPanel id(new AphrontFormTextControl()) ->setLabel(pht('Email')) ->setName('email') - ->setValue($email_object->getAddress()) - ->setCaption(PhabricatorUserEmail::describeAllowedAddresses()) - ->setError($e_email)) + ->setValue($v_email) + ->setError($e_email)); + + if (PhabricatorSpacesNamespaceQuery::getViewerSpacesExist($viewer)) { + $form->appendControl( + id(new AphrontFormSelectControl()) + ->setLabel(pht('Space')) + ->setName('spacePHID') + ->setValue($v_space) + ->setError($e_space) + ->setOptions( + PhabricatorSpacesNamespaceQuery::getSpaceOptionsForViewer( + $viewer, + $v_space))); + } + + $form ->appendControl( id(new AphrontFormTokenizerControl()) ->setDatasource(new PhabricatorPeopleDatasource()) ->setLabel(pht('Default Author')) - ->setName($default_user_key) + ->setName($config_default) ->setLimit(1) - ->setValue($default_user_value) + ->setValue($v_default) ->setCaption(pht( 'Used if the "From:" address does not map to a known account.'))); + if ($is_new) { $title = pht('New Address'); } else { $title = pht('Edit Address'); } + $dialog = id(new AphrontDialogView()) ->setUser($viewer) ->setWidth(AphrontDialogView::WIDTH_FORM) ->setTitle($title) - ->appendChild($errors) + ->setValidationException($validation_exception) ->appendForm($form) ->addSubmitButton(pht('Save')) ->addCancelButton($uri); @@ -350,7 +290,8 @@ final class PhabricatorMetaMTAApplicationEmailPanel PhutilURI $uri, $email_object_id) { - $viewer = $request->getUser(); + $viewer = $this->getViewer(); + $email_object = id(new PhabricatorMetaMTAApplicationEmailQuery()) ->setViewer($viewer) ->withIDs(array($email_object_id)) @@ -365,7 +306,8 @@ final class PhabricatorMetaMTAApplicationEmailPanel } if ($request->isDialogFormPost()) { - $email_object->delete(); + $engine = new PhabricatorDestructionEngine(); + $engine->destroyObject($email_object); return id(new AphrontRedirectResponse())->setURI($uri); } @@ -381,4 +323,85 @@ final class PhabricatorMetaMTAApplicationEmailPanel return id(new AphrontDialogResponse())->setDialog($dialog); } + private function buildEmailTable($is_edit, $highlight) { + $viewer = $this->getViewer(); + $application = $this->getApplication(); + $uri = new PhutilURI($this->getPanelURI()); + + $emails = id(new PhabricatorMetaMTAApplicationEmailQuery()) + ->setViewer($viewer) + ->withApplicationPHIDs(array($application->getPHID())) + ->execute(); + + $rowc = array(); + $rows = array(); + foreach ($emails as $email) { + + $button_edit = javelin_tag( + 'a', + array( + 'class' => 'button small grey', + 'href' => $uri->alter('edit', $email->getID()), + 'sigil' => 'workflow', + ), + pht('Edit')); + + $button_remove = javelin_tag( + 'a', + array( + 'class' => 'button small grey', + 'href' => $uri->alter('delete', $email->getID()), + 'sigil' => 'workflow', + ), + pht('Delete')); + + if ($highlight == $email->getID()) { + $rowc[] = 'highlighted'; + } else { + $rowc[] = null; + } + + $space_phid = PhabricatorSpacesNamespaceQuery::getObjectSpacePHID($email); + if ($space_phid) { + $email_space = $viewer->renderHandle($space_phid); + } else { + $email_space = null; + } + + $rows[] = array( + $email_space, + $email->getAddress(), + $button_edit, + $button_remove, + ); + } + + $table = id(new AphrontTableView($rows)) + ->setNoDataString(pht('No application emails created yet.')); + $table->setHeaders( + array( + pht('Space'), + pht('Email'), + pht('Edit'), + pht('Delete'), + )); + $table->setColumnClasses( + array( + '', + 'wide', + 'action', + 'action', + )); + $table->setRowClasses($rowc); + $table->setColumnVisibility( + array( + PhabricatorSpacesNamespaceQuery::getViewerSpacesExist($viewer), + true, + $is_edit, + $is_edit, + )); + + return $table; + } + } diff --git a/src/applications/metamta/command/__tests__/MetaMTAEmailTransactionCommandTestCase.php b/src/applications/metamta/command/__tests__/MetaMTAEmailTransactionCommandTestCase.php new file mode 100644 index 0000000000..3668594ca1 --- /dev/null +++ b/src/applications/metamta/command/__tests__/MetaMTAEmailTransactionCommandTestCase.php @@ -0,0 +1,10 @@ +assertTrue(true); + } + +} diff --git a/src/applications/metamta/constants/MetaMTAConstants.php b/src/applications/metamta/constants/MetaMTAConstants.php index 0e9e6939a7..9b3fe7121f 100644 --- a/src/applications/metamta/constants/MetaMTAConstants.php +++ b/src/applications/metamta/constants/MetaMTAConstants.php @@ -1,3 +1,3 @@ getTransactionType()) { + case PhabricatorMetaMTAApplicationEmailTransaction::TYPE_ADDRESS: + return $object->getAddress(); + case PhabricatorMetaMTAApplicationEmailTransaction::TYPE_CONFIG: + $key = $xaction->getMetadataValue( + PhabricatorMetaMTAApplicationEmailTransaction::KEY_CONFIG); + return $object->getConfigValue($key); + } + + return parent::getCustomTransactionOldValue($object, $xaction); + } + + protected function getCustomTransactionNewValue( + PhabricatorLiskDAO $object, + PhabricatorApplicationTransaction $xaction) { + + switch ($xaction->getTransactionType()) { + case PhabricatorMetaMTAApplicationEmailTransaction::TYPE_ADDRESS: + case PhabricatorMetaMTAApplicationEmailTransaction::TYPE_CONFIG: + return $xaction->getNewValue(); + } + + return parent::getCustomTransactionNewValue($object, $xaction); + } + + protected function applyCustomInternalTransaction( + PhabricatorLiskDAO $object, + PhabricatorApplicationTransaction $xaction) { + + $new = $xaction->getNewValue(); + + switch ($xaction->getTransactionType()) { + case PhabricatorMetaMTAApplicationEmailTransaction::TYPE_ADDRESS: + $object->setAddress($new); + return; + case PhabricatorMetaMTAApplicationEmailTransaction::TYPE_CONFIG: + $key = $xaction->getMetadataValue( + PhabricatorMetaMTAApplicationEmailTransaction::KEY_CONFIG); + $object->setConfigValue($key, $new); + return; + } + + return parent::applyCustomInternalTransaction($object, $xaction); + } + + protected function applyCustomExternalTransaction( + PhabricatorLiskDAO $object, + PhabricatorApplicationTransaction $xaction) { + + switch ($xaction->getTransactionType()) { + case PhabricatorMetaMTAApplicationEmailTransaction::TYPE_ADDRESS: + case PhabricatorMetaMTAApplicationEmailTransaction::TYPE_CONFIG: + return; + } + + return parent::applyCustomExternalTransaction($object, $xaction); + } + + protected function validateTransaction( + PhabricatorLiskDAO $object, + $type, + array $xactions) { + + $errors = parent::validateTransaction($object, $type, $xactions); + + switch ($type) { + case PhabricatorMetaMTAApplicationEmailTransaction::TYPE_ADDRESS: + foreach ($xactions as $xaction) { + $email = $xaction->getNewValue(); + if (!strlen($email)) { + // We'll deal with this below. + continue; + } + + if (!PhabricatorUserEmail::isValidAddress($email)) { + $errors[] = new PhabricatorApplicationTransactionValidationError( + $type, + pht('Invalid'), + pht('Email address is not formatted properly.')); + } + } + + $missing = $this->validateIsEmptyTextField( + $object->getAddress(), + $xactions); + + if ($missing) { + $error = new PhabricatorApplicationTransactionValidationError( + $type, + pht('Required'), + pht('You must provide an email address.'), + nonempty(last($xactions), null)); + + $error->setIsMissingFieldError(true); + $errors[] = $error; + } + break; + } + + return $errors; + } + + protected function didCatchDuplicateKeyException( + PhabricatorLiskDAO $object, + array $xactions, + Exception $ex) { + + $errors = array(); + $errors[] = new PhabricatorApplicationTransactionValidationError( + PhabricatorMetaMTAApplicationEmailTransaction::TYPE_ADDRESS, + pht('Duplicate'), + pht('This email address is already in use.'), + null); + + throw new PhabricatorApplicationTransactionValidationException($errors); + } + + +} diff --git a/src/applications/metamta/parser/PhabricatorMetaMTAEmailBodyParser.php b/src/applications/metamta/parser/PhabricatorMetaMTAEmailBodyParser.php index 07770600e6..be0401f066 100644 --- a/src/applications/metamta/parser/PhabricatorMetaMTAEmailBodyParser.php +++ b/src/applications/metamta/parser/PhabricatorMetaMTAEmailBodyParser.php @@ -1,6 +1,6 @@ establishConnection('r'); - - $data = queryfx_all( - $conn_r, - 'SELECT * FROM %T appemail %Q %Q %Q %Q', - $table->getTableName(), - $this->buildWhereClause($conn_r), - $this->buildApplicationSearchGroupClause($conn_r), - $this->buildOrderClause($conn_r), - $this->buildLimitClause($conn_r)); - - return $table->loadAllFromArray($data); + return $this->loadStandardPage(new PhabricatorMetaMTAApplicationEmail()); } protected function willFilterPage(array $app_emails) { @@ -71,47 +59,45 @@ final class PhabricatorMetaMTAApplicationEmailQuery return $app_emails; } - protected function buildWhereClause(AphrontDatabaseConnection $conn_r) { - $where = array(); + protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { + $where = parent::buildWhereClauseParts($conn); if ($this->addresses !== null) { $where[] = qsprintf( - $conn_r, + $conn, 'appemail.address IN (%Ls)', $this->addresses); } if ($this->addressPrefix !== null) { $where[] = qsprintf( - $conn_r, + $conn, 'appemail.address LIKE %>', $this->addressPrefix); } if ($this->applicationPHIDs !== null) { $where[] = qsprintf( - $conn_r, + $conn, 'appemail.applicationPHID IN (%Ls)', $this->applicationPHIDs); } if ($this->phids !== null) { $where[] = qsprintf( - $conn_r, + $conn, 'appemail.phid IN (%Ls)', $this->phids); } if ($this->ids !== null) { $where[] = qsprintf( - $conn_r, + $conn, 'appemail.id IN (%Ld)', $this->ids); } - $where[] = $this->buildPagingClause($conn_r); - - return $this->formatWhereClause($where); + return $where; } protected function getPrimaryTableAlias() { diff --git a/src/applications/metamta/query/PhabricatorMetaMTAApplicationEmailTransactionQuery.php b/src/applications/metamta/query/PhabricatorMetaMTAApplicationEmailTransactionQuery.php new file mode 100644 index 0000000000..4f4f6d11de --- /dev/null +++ b/src/applications/metamta/query/PhabricatorMetaMTAApplicationEmailTransactionQuery.php @@ -0,0 +1,10 @@ +setSpacePHID($actor->getDefaultSpacePHID()) ->setConfigData(array()); } @@ -109,4 +115,43 @@ final class PhabricatorMetaMTAApplicationEmail return $this->getApplication()->describeAutomaticCapability($capability); } + +/* -( PhabricatorApplicationTransactionInterface )------------------------- */ + + + public function getApplicationTransactionEditor() { + return new PhabricatorMetaMTAApplicationEmailEditor(); + } + + public function getApplicationTransactionObject() { + return $this; + } + + public function getApplicationTransactionTemplate() { + return new PhabricatorMetaMTAApplicationEmailTransaction(); + } + + public function willRenderTimeline( + PhabricatorApplicationTransactionView $timeline, + AphrontRequest $request) { + return $timeline; + } + + +/* -( PhabricatorDestructibleInterface )----------------------------------- */ + + + public function destroyObjectPermanently( + PhabricatorDestructionEngine $engine) { + $this->delete(); + } + + +/* -( PhabricatorSpacesInterface )----------------------------------------- */ + + + public function getSpacePHID() { + return $this->spacePHID; + } + } diff --git a/src/applications/metamta/storage/PhabricatorMetaMTAApplicationEmailTransaction.php b/src/applications/metamta/storage/PhabricatorMetaMTAApplicationEmailTransaction.php new file mode 100644 index 0000000000..019adb338d --- /dev/null +++ b/src/applications/metamta/storage/PhabricatorMetaMTAApplicationEmailTransaction.php @@ -0,0 +1,23 @@ +establishConnection('w'); + + queryfx( + $conn_w, + 'DELETE FROM %T WHERE chronologicalKey < (%d << 32) + ORDER BY chronologicalKey ASC LIMIT 100', + $table->getTableName(), + time() - $ttl); + + return ($conn_w->getAffectedRows() == 100); + } + +} diff --git a/src/applications/notification/storage/PhabricatorFeedStoryNotification.php b/src/applications/notification/storage/PhabricatorFeedStoryNotification.php index 8f89c987ec..30aec1f281 100644 --- a/src/applications/notification/storage/PhabricatorFeedStoryNotification.php +++ b/src/applications/notification/storage/PhabricatorFeedStoryNotification.php @@ -28,6 +28,9 @@ final class PhabricatorFeedStoryNotification extends PhabricatorFeedDAO { 'key_object' => array( 'columns' => array('primaryObjectPHID'), ), + 'key_chronological' => array( + 'columns' => array('chronologicalKey'), + ), ), ) + parent::getConfiguration(); } diff --git a/src/applications/nuance/application/PhabricatorNuanceApplication.php b/src/applications/nuance/application/PhabricatorNuanceApplication.php index be297f4026..20c58f841c 100644 --- a/src/applications/nuance/application/PhabricatorNuanceApplication.php +++ b/src/applications/nuance/application/PhabricatorNuanceApplication.php @@ -72,9 +72,11 @@ final class PhabricatorNuanceApplication extends PhabricatorApplication { return array( NuanceSourceDefaultViewCapability::CAPABILITY => array( 'caption' => pht('Default view policy for newly created sources.'), + 'template' => NuanceSourcePHIDType::TYPECONST, ), NuanceSourceDefaultEditCapability::CAPABILITY => array( 'caption' => pht('Default edit policy for newly created sources.'), + 'template' => NuanceSourcePHIDType::TYPECONST, ), NuanceSourceManageCapability::CAPABILITY => array(), ); diff --git a/src/applications/nuance/source/__tests__/NuanceSourceDefinitionTestCase.php b/src/applications/nuance/source/__tests__/NuanceSourceDefinitionTestCase.php new file mode 100644 index 0000000000..39b0358f4c --- /dev/null +++ b/src/applications/nuance/source/__tests__/NuanceSourceDefinitionTestCase.php @@ -0,0 +1,10 @@ +assertTrue(true); + } + +} diff --git a/src/applications/oauthserver/PhabricatorOAuthServer.php b/src/applications/oauthserver/PhabricatorOAuthServer.php index 5f75083c89..e1b9f516ba 100644 --- a/src/applications/oauthserver/PhabricatorOAuthServer.php +++ b/src/applications/oauthserver/PhabricatorOAuthServer.php @@ -26,7 +26,7 @@ * and generating @{class:PhabricatorOAuthServerAccessToken}s * @task internal Internals */ -final class PhabricatorOAuthServer { +final class PhabricatorOAuthServer extends Phobject { const AUTHORIZATION_CODE_TIMEOUT = 300; const ACCESS_TOKEN_TIMEOUT = 3600; diff --git a/src/applications/oauthserver/PhabricatorOAuthServerScope.php b/src/applications/oauthserver/PhabricatorOAuthServerScope.php index 146293dfde..4ab6c455d8 100644 --- a/src/applications/oauthserver/PhabricatorOAuthServerScope.php +++ b/src/applications/oauthserver/PhabricatorOAuthServerScope.php @@ -1,6 +1,6 @@ getCredentialType()) { - case PassphraseCredentialTypeSSHPrivateKeyFile::CREDENTIAL_TYPE: + case PassphraseSSHPrivateKeyFileCredentialType::CREDENTIAL_TYPE: if ($secret) { $material['file'] = $secret; } @@ -86,8 +86,8 @@ final class PassphraseQueryConduitAPIMethod $material['publicKey'] = $public_key; } break; - case PassphraseCredentialTypeSSHGeneratedKey::CREDENTIAL_TYPE: - case PassphraseCredentialTypeSSHPrivateKeyText::CREDENTIAL_TYPE: + case PassphraseSSHGeneratedKeyCredentialType::CREDENTIAL_TYPE: + case PassphraseSSHPrivateKeyTextCredentialType::CREDENTIAL_TYPE: if ($secret) { $material['privateKey'] = $secret; } @@ -95,7 +95,7 @@ final class PassphraseQueryConduitAPIMethod $material['publicKey'] = $public_key; } break; - case PassphraseCredentialTypePassword::CREDENTIAL_TYPE: + case PassphrasePasswordCredentialType::CREDENTIAL_TYPE: if ($secret) { $material['password'] = $secret; } diff --git a/src/applications/passphrase/credentialtype/PassphraseCredentialTypePassword.php b/src/applications/passphrase/credentialtype/PassphrasePasswordCredentialType.php similarity index 93% rename from src/applications/passphrase/credentialtype/PassphraseCredentialTypePassword.php rename to src/applications/passphrase/credentialtype/PassphrasePasswordCredentialType.php index bc55f1e4da..695059fd1d 100644 --- a/src/applications/passphrase/credentialtype/PassphraseCredentialTypePassword.php +++ b/src/applications/passphrase/credentialtype/PassphrasePasswordCredentialType.php @@ -1,6 +1,6 @@ assertTrue(true); + } + +} diff --git a/src/applications/passphrase/keys/PassphrasePasswordKey.php b/src/applications/passphrase/keys/PassphrasePasswordKey.php index df2e683c20..ef4cc7a284 100644 --- a/src/applications/passphrase/keys/PassphrasePasswordKey.php +++ b/src/applications/passphrase/keys/PassphrasePasswordKey.php @@ -7,7 +7,7 @@ final class PassphrasePasswordKey extends PassphraseAbstractKey { return $key->loadAndValidateFromPHID( $phid, $viewer, - PassphraseCredentialTypePassword::PROVIDES_TYPE); + PassphrasePasswordCredentialType::PROVIDES_TYPE); } public function getPasswordEnvelope() { diff --git a/src/applications/passphrase/keys/PassphraseSSHKey.php b/src/applications/passphrase/keys/PassphraseSSHKey.php index 0790d5342e..f55eb3be93 100644 --- a/src/applications/passphrase/keys/PassphraseSSHKey.php +++ b/src/applications/passphrase/keys/PassphraseSSHKey.php @@ -9,13 +9,13 @@ final class PassphraseSSHKey extends PassphraseAbstractKey { return $key->loadAndValidateFromPHID( $phid, $viewer, - PassphraseCredentialTypeSSHPrivateKey::PROVIDES_TYPE); + PassphraseSSHPrivateKeyCredentialType::PROVIDES_TYPE); } public function getKeyfileEnvelope() { $credential = $this->requireCredential(); - $file_type = PassphraseCredentialTypeSSHPrivateKeyFile::CREDENTIAL_TYPE; + $file_type = PassphraseSSHPrivateKeyFileCredentialType::CREDENTIAL_TYPE; if ($credential->getCredentialType() != $file_type) { // If the credential does not store a file, write the key text out to a // temporary file so we can pass it to `ssh`. diff --git a/src/applications/paste/application/PhabricatorPasteApplication.php b/src/applications/paste/application/PhabricatorPasteApplication.php index c0afe865bf..f9cd03dd74 100644 --- a/src/applications/paste/application/PhabricatorPasteApplication.php +++ b/src/applications/paste/application/PhabricatorPasteApplication.php @@ -64,9 +64,11 @@ final class PhabricatorPasteApplication extends PhabricatorApplication { return array( PasteDefaultViewCapability::CAPABILITY => array( 'caption' => pht('Default view policy for newly created pastes.'), + 'template' => PhabricatorPastePastePHIDType::TYPECONST, ), PasteDefaultEditCapability::CAPABILITY => array( 'caption' => pht('Default edit policy for newly created pastes.'), + 'template' => PhabricatorPastePastePHIDType::TYPECONST, ), ); } diff --git a/src/applications/paste/controller/PhabricatorPasteEditController.php b/src/applications/paste/controller/PhabricatorPasteEditController.php index 7aa28673da..dcc4900951 100644 --- a/src/applications/paste/controller/PhabricatorPasteEditController.php +++ b/src/applications/paste/controller/PhabricatorPasteEditController.php @@ -167,12 +167,6 @@ final class PhabricatorPasteEditController extends PhabricatorPasteController { ->setObject($paste) ->execute(); - $form->appendControl( - id(new PhabricatorSpacesControl()) - ->setObject($paste) - ->setValue($v_space) - ->setName('spacePHID')); - $form->appendChild( id(new AphrontFormPolicyControl()) ->setUser($user) @@ -180,6 +174,7 @@ final class PhabricatorPasteEditController extends PhabricatorPasteController { ->setPolicyObject($paste) ->setPolicies($policies) ->setValue($v_view_policy) + ->setSpacePHID($v_space) ->setName('can_view')); $form->appendChild( diff --git a/src/applications/paste/storage/PhabricatorPaste.php b/src/applications/paste/storage/PhabricatorPaste.php index da129b8cf4..661701ba09 100644 --- a/src/applications/paste/storage/PhabricatorPaste.php +++ b/src/applications/paste/storage/PhabricatorPaste.php @@ -38,7 +38,8 @@ final class PhabricatorPaste extends PhabricatorPasteDAO ->setTitle('') ->setAuthorPHID($actor->getPHID()) ->setViewPolicy($view_policy) - ->setEditPolicy($edit_policy); + ->setEditPolicy($edit_policy) + ->setSpacePHID($actor->getDefaultSpacePHID()); } public function getURI() { diff --git a/src/applications/people/storage/PhabricatorUser.php b/src/applications/people/storage/PhabricatorUser.php index 1d1d3316c0..55ade255a7 100644 --- a/src/applications/people/storage/PhabricatorUser.php +++ b/src/applications/people/storage/PhabricatorUser.php @@ -118,10 +118,6 @@ final class PhabricatorUser } public function canEstablishWebSessions() { - if (!$this->isUserActivated()) { - return false; - } - if ($this->getIsMailingList()) { return false; } @@ -762,13 +758,22 @@ final class PhabricatorUser // TODO: We might let the user switch which space they're "in" later on; // for now just use the global space if one exists. - $spaces = PhabricatorSpacesNamespaceQuery::getViewerSpaces($this); + // If the viewer has access to the default space, use that. + $spaces = PhabricatorSpacesNamespaceQuery::getViewerActiveSpaces($this); foreach ($spaces as $space) { if ($space->getIsDefaultNamespace()) { return $space->getPHID(); } } + // Otherwise, use the space with the lowest ID that they have access to. + // This just tends to keep the default stable and predictable over time, + // so adding a new space won't change behavior for users. + if ($spaces) { + $spaces = msort($spaces, 'getID'); + return head($spaces)->getPHID(); + } + return null; } diff --git a/src/applications/phame/skins/PhameSkinSpecification.php b/src/applications/phame/skins/PhameSkinSpecification.php index 7dedf8ab4b..9e0265392f 100644 --- a/src/applications/phame/skins/PhameSkinSpecification.php +++ b/src/applications/phame/skins/PhameSkinSpecification.php @@ -1,6 +1,6 @@ Map of type constants to types. */ - public static function getAllTypes() { + final public static function getAllTypes() { static $types; if ($types === null) { $objects = id(new PhutilSymbolLoader()) diff --git a/src/applications/phid/type/__tests__/PhabricatorPHIDTypeTestCase.php b/src/applications/phid/type/__tests__/PhabricatorPHIDTypeTestCase.php new file mode 100644 index 0000000000..e7707095ad --- /dev/null +++ b/src/applications/phid/type/__tests__/PhabricatorPHIDTypeTestCase.php @@ -0,0 +1,10 @@ +assertTrue(true); + } + +} diff --git a/src/applications/phid/view/PHUIHandleView.php b/src/applications/phid/view/PHUIHandleView.php index db4b9e43ab..a4b766a991 100644 --- a/src/applications/phid/view/PHUIHandleView.php +++ b/src/applications/phid/view/PHUIHandleView.php @@ -14,6 +14,7 @@ final class PHUIHandleView private $handleList; private $handlePHID; private $asTag; + private $useShortName; public function setHandleList(PhabricatorHandleList $list) { $this->handleList = $list; @@ -30,12 +31,21 @@ final class PHUIHandleView return $this; } + public function setUseShortName($short) { + $this->useShortName = $short; + return $this; + } + public function render() { $handle = $this->handleList[$this->handlePHID]; if ($this->asTag) { return $handle->renderTag(); } else { - return $handle->renderLink(); + if ($this->useShortName) { + return $handle->renderLink($handle->getName()); + } else { + return $handle->renderLink(); + } } } diff --git a/src/applications/pholio/application/PhabricatorPholioApplication.php b/src/applications/pholio/application/PhabricatorPholioApplication.php index 801a2de4e8..52309ba078 100644 --- a/src/applications/pholio/application/PhabricatorPholioApplication.php +++ b/src/applications/pholio/application/PhabricatorPholioApplication.php @@ -71,8 +71,12 @@ final class PhabricatorPholioApplication extends PhabricatorApplication { protected function getCustomCapabilities() { return array( - PholioDefaultViewCapability::CAPABILITY => array(), - PholioDefaultEditCapability::CAPABILITY => array(), + PholioDefaultViewCapability::CAPABILITY => array( + 'template' => PholioMockPHIDType::TYPECONST, + ), + PholioDefaultEditCapability::CAPABILITY => array( + 'template' => PholioMockPHIDType::TYPECONST, + ), ); } diff --git a/src/applications/pholio/controller/PholioMockEditController.php b/src/applications/pholio/controller/PholioMockEditController.php index 3ed2cc0779..728c7b29d6 100644 --- a/src/applications/pholio/controller/PholioMockEditController.php +++ b/src/applications/pholio/controller/PholioMockEditController.php @@ -65,6 +65,7 @@ final class PholioMockEditController extends PholioController { $v_edit = $mock->getEditPolicy(); $v_cc = PhabricatorSubscribersQuery::loadSubscribersForPHID( $mock->getPHID()); + $v_space = $mock->getSpacePHID(); if ($request->isFormPost()) { $xactions = array(); @@ -75,6 +76,7 @@ final class PholioMockEditController extends PholioController { $type_view = PhabricatorTransactions::TYPE_VIEW_POLICY; $type_edit = PhabricatorTransactions::TYPE_EDIT_POLICY; $type_cc = PhabricatorTransactions::TYPE_SUBSCRIBERS; + $type_space = PhabricatorTransactions::TYPE_SPACE; $v_name = $request->getStr('name'); $v_desc = $request->getStr('description'); @@ -83,6 +85,7 @@ final class PholioMockEditController extends PholioController { $v_edit = $request->getStr('can_edit'); $v_cc = $request->getArr('cc'); $v_projects = $request->getArr('projects'); + $v_space = $request->getStr('spacePHID'); $mock_xactions = array(); $mock_xactions[$type_name] = $v_name; @@ -91,6 +94,7 @@ final class PholioMockEditController extends PholioController { $mock_xactions[$type_view] = $v_view; $mock_xactions[$type_edit] = $v_edit; $mock_xactions[$type_cc] = array('=' => $v_cc); + $mock_xactions[$type_space] = $v_space; if (!strlen($request->getStr('name'))) { $e_name = pht('Required'); @@ -350,6 +354,7 @@ final class PholioMockEditController extends PholioController { ->setCapability(PhabricatorPolicyCapability::CAN_VIEW) ->setPolicyObject($mock) ->setPolicies($policies) + ->setSpacePHID($v_space) ->setName('can_view')) ->appendChild( id(new AphrontFormPolicyControl()) diff --git a/src/applications/pholio/query/PholioMockSearchEngine.php b/src/applications/pholio/query/PholioMockSearchEngine.php index 26b22034a7..23c1decad5 100644 --- a/src/applications/pholio/query/PholioMockSearchEngine.php +++ b/src/applications/pholio/query/PholioMockSearchEngine.php @@ -83,12 +83,6 @@ final class PholioMockSearchEngine extends PhabricatorApplicationSearchEngine { return parent::buildSavedQueryFromBuiltin($query_key); } - protected function getRequiredHandlePHIDsForResultList( - array $mocks, - PhabricatorSavedQuery $query) { - return mpull($mocks, 'getAuthorPHID'); - } - protected function renderResultList( array $mocks, PhabricatorSavedQuery $query, @@ -96,6 +90,7 @@ final class PholioMockSearchEngine extends PhabricatorApplicationSearchEngine { assert_instances_of($mocks, 'PholioMock'); $viewer = $this->requireViewer(); + $handles = $viewer->loadHandles(mpull($mocks, 'getAuthorPHID')); $xform = PhabricatorFileTransform::getTransformByKey( PhabricatorFileThumbnailTransform::TRANSFORM_PINBOARD); @@ -109,7 +104,9 @@ final class PholioMockSearchEngine extends PhabricatorApplicationSearchEngine { $header = 'M'.$mock->getID().' '.$mock->getName(); $item = id(new PHUIPinboardItemView()) + ->setUser($viewer) ->setHeader($header) + ->setObject($mock) ->setURI('/M'.$mock->getID()) ->setImageURI($image_uri) ->setImageSize($x, $y) diff --git a/src/applications/pholio/remarkup/PholioRemarkupRule.php b/src/applications/pholio/remarkup/PholioRemarkupRule.php index 2b1ca0f876..00025b6326 100644 --- a/src/applications/pholio/remarkup/PholioRemarkupRule.php +++ b/src/applications/pholio/remarkup/PholioRemarkupRule.php @@ -64,7 +64,10 @@ final class PholioRemarkupRule extends PhabricatorObjectRemarkupRule { PhabricatorObjectHandle $handle, $options) { + $viewer = $this->getEngine()->getConfig('viewer'); + $embed_mock = id(new PholioMockEmbedView()) + ->setUser($viewer) ->setMock($object); if (strlen($options)) { diff --git a/src/applications/pholio/storage/PholioMock.php b/src/applications/pholio/storage/PholioMock.php index d229aa8020..22c1015704 100644 --- a/src/applications/pholio/storage/PholioMock.php +++ b/src/applications/pholio/storage/PholioMock.php @@ -9,7 +9,8 @@ final class PholioMock extends PholioDAO PhabricatorFlaggableInterface, PhabricatorApplicationTransactionInterface, PhabricatorProjectInterface, - PhabricatorDestructibleInterface { + PhabricatorDestructibleInterface, + PhabricatorSpacesInterface { const MARKUP_FIELD_DESCRIPTION = 'markup:description'; @@ -26,6 +27,7 @@ final class PholioMock extends PholioDAO protected $coverPHID; protected $mailKey; protected $status; + protected $spacePHID; private $images = self::ATTACHABLE; private $allImages = self::ATTACHABLE; @@ -46,7 +48,8 @@ final class PholioMock extends PholioDAO ->attachImages(array()) ->setStatus(self::STATUS_OPEN) ->setViewPolicy($view_policy) - ->setEditPolicy($edit_policy); + ->setEditPolicy($edit_policy) + ->setSpacePHID($actor->getDefaultSpacePHID()); } public function getMonogram() { @@ -308,4 +311,13 @@ final class PholioMock extends PholioDAO $this->saveTransaction(); } + +/* -( PhabricatorSpacesInterface )----------------------------------------- */ + + + public function getSpacePHID() { + return $this->spacePHID; + } + + } diff --git a/src/applications/pholio/view/PholioMockEmbedView.php b/src/applications/pholio/view/PholioMockEmbedView.php index 3429cfd569..88f2f2ac55 100644 --- a/src/applications/pholio/view/PholioMockEmbedView.php +++ b/src/applications/pholio/view/PholioMockEmbedView.php @@ -47,6 +47,8 @@ final class PholioMockEmbedView extends AphrontView { list($x, $y) = $xform->getTransformedDimensions($thumbfile); $item = id(new PHUIPinboardItemView()) + ->setUser($this->getUser()) + ->setObject($mock) ->setHeader($header) ->setURI($uri) ->setImageURI($thumbnail) diff --git a/src/applications/phortune/cart/PhortuneCartImplementation.php b/src/applications/phortune/cart/PhortuneCartImplementation.php index 9085fe9aad..1dbc200806 100644 --- a/src/applications/phortune/cart/PhortuneCartImplementation.php +++ b/src/applications/phortune/cart/PhortuneCartImplementation.php @@ -1,6 +1,6 @@ assertTrue(true); + } + +} diff --git a/src/applications/phortune/subscription/PhortuneSubscriptionImplementation.php b/src/applications/phortune/subscription/PhortuneSubscriptionImplementation.php index ad5126cf65..f8cbc21155 100644 --- a/src/applications/phortune/subscription/PhortuneSubscriptionImplementation.php +++ b/src/applications/phortune/subscription/PhortuneSubscriptionImplementation.php @@ -1,6 +1,6 @@ generateNewTestUser(); + $viewer = $this->generateNewTestUser(); + + $rule = new ManiphestTaskAuthorPolicyRule(); + + $task = ManiphestTask::initializeNewTask($author); + $task->setViewPolicy($rule->getObjectPolicyFullKey()); + $task->save(); + + $this->assertTrue( + PhabricatorPolicyFilter::hasCapability( + $author, + $task, + PhabricatorPolicyCapability::CAN_VIEW)); + + $this->assertFalse( + PhabricatorPolicyFilter::hasCapability( + $viewer, + $task, + PhabricatorPolicyCapability::CAN_VIEW)); + } + + public function testObjectPolicyRuleThreadMembers() { + $author = $this->generateNewTestUser(); + $viewer = $this->generateNewTestUser(); + + $rule = new ConpherenceThreadMembersPolicyRule(); + + $thread = ConpherenceThread::initializeNewRoom($author); + $thread->setViewPolicy($rule->getObjectPolicyFullKey()); + $thread->save(); + + $this->assertFalse( + PhabricatorPolicyFilter::hasCapability( + $author, + $thread, + PhabricatorPolicyCapability::CAN_VIEW)); + + $this->assertFalse( + PhabricatorPolicyFilter::hasCapability( + $viewer, + $thread, + PhabricatorPolicyCapability::CAN_VIEW)); + + $participant = id(new ConpherenceParticipant()) + ->setParticipantPHID($viewer->getPHID()) + ->setConpherencePHID($thread->getPHID()); + + $thread->attachParticipants(array($viewer->getPHID() => $participant)); + + $this->assertTrue( + PhabricatorPolicyFilter::hasCapability( + $viewer, + $thread, + PhabricatorPolicyCapability::CAN_VIEW)); + } + + public function testObjectPolicyRuleSubscribers() { + $author = $this->generateNewTestUser(); + + $rule = new PhabricatorSubscriptionsSubscribersPolicyRule(); + + $task = ManiphestTask::initializeNewTask($author); + $task->setViewPolicy($rule->getObjectPolicyFullKey()); + $task->save(); + + $this->assertFalse( + PhabricatorPolicyFilter::hasCapability( + $author, + $task, + PhabricatorPolicyCapability::CAN_VIEW)); + + id(new PhabricatorSubscriptionsEditor()) + ->setActor($author) + ->setObject($task) + ->subscribeExplicit(array($author->getPHID())) + ->save(); + + $this->assertTrue( + PhabricatorPolicyFilter::hasCapability( + $author, + $task, + PhabricatorPolicyCapability::CAN_VIEW)); + } + } diff --git a/src/applications/policy/__tests__/PhabricatorPolicyTestObject.php b/src/applications/policy/__tests__/PhabricatorPolicyTestObject.php index 60c77aea83..0e8d4c4957 100644 --- a/src/applications/policy/__tests__/PhabricatorPolicyTestObject.php +++ b/src/applications/policy/__tests__/PhabricatorPolicyTestObject.php @@ -4,6 +4,7 @@ * Configurable test object for implementing Policy unit tests. */ final class PhabricatorPolicyTestObject + extends Phobject implements PhabricatorPolicyInterface, PhabricatorExtendedPolicyInterface { diff --git a/src/applications/policy/application/PhabricatorPolicyApplication.php b/src/applications/policy/application/PhabricatorPolicyApplication.php index cefccd2cb5..8aaf8eb1bf 100644 --- a/src/applications/policy/application/PhabricatorPolicyApplication.php +++ b/src/applications/policy/application/PhabricatorPolicyApplication.php @@ -19,7 +19,15 @@ final class PhabricatorPolicyApplication extends PhabricatorApplication { '/policy/' => array( 'explain/(?P[^/]+)/(?P[^/]+)/' => 'PhabricatorPolicyExplainController', - 'edit/(?:(?P[^/]+)/)?' => 'PhabricatorPolicyEditController', + 'edit/'. + '(?:'. + 'object/(?P[^/]+)'. + '|'. + 'type/(?P[^/]+)'. + '|'. + 'template/(?P[^/]+)'. + ')/'. + '(?:(?P[^/]+)/)?' => 'PhabricatorPolicyEditController', ), ); } diff --git a/src/applications/policy/capability/__tests__/PhabricatorPolicyCapabilityTestCase.php b/src/applications/policy/capability/__tests__/PhabricatorPolicyCapabilityTestCase.php new file mode 100644 index 0000000000..0def247621 --- /dev/null +++ b/src/applications/policy/capability/__tests__/PhabricatorPolicyCapabilityTestCase.php @@ -0,0 +1,11 @@ +assertTrue(true); + } + +} diff --git a/src/applications/policy/constants/PhabricatorPolicyConstants.php b/src/applications/policy/constants/PhabricatorPolicyConstants.php index e9594c659d..23e8236f3a 100644 --- a/src/applications/policy/constants/PhabricatorPolicyConstants.php +++ b/src/applications/policy/constants/PhabricatorPolicyConstants.php @@ -1,3 +1,3 @@ 0, - self::TYPE_USER => 1, - self::TYPE_CUSTOM => 2, - self::TYPE_PROJECT => 3, + self::TYPE_OBJECT => 1, + self::TYPE_USER => 2, + self::TYPE_CUSTOM => 3, + self::TYPE_PROJECT => 4, self::TYPE_MASKED => 9, ); return idx($map, $type, 9); @@ -23,6 +25,8 @@ final class PhabricatorPolicyType extends PhabricatorPolicyConstants { switch ($type) { case self::TYPE_GLOBAL: return pht('Basic Policies'); + case self::TYPE_OBJECT: + return pht('Object Policies'); case self::TYPE_USER: return pht('User Policies'); case self::TYPE_CUSTOM: diff --git a/src/applications/policy/controller/PhabricatorPolicyEditController.php b/src/applications/policy/controller/PhabricatorPolicyEditController.php index 80b04e4ea7..30c9836557 100644 --- a/src/applications/policy/controller/PhabricatorPolicyEditController.php +++ b/src/applications/policy/controller/PhabricatorPolicyEditController.php @@ -4,8 +4,37 @@ final class PhabricatorPolicyEditController extends PhabricatorPolicyController { public function handleRequest(AphrontRequest $request) { - $request = $this->getRequest(); - $viewer = $request->getUser(); + $viewer = $this->getViewer(); + + // TODO: This doesn't do anything yet, but sets up template policies; see + // T6860. + $is_template = false; + + $object_phid = $request->getURIData('objectPHID'); + if ($object_phid) { + $object = id(new PhabricatorObjectQuery()) + ->setViewer($viewer) + ->withPHIDs(array($object_phid)) + ->executeOne(); + if (!$object) { + return new Aphront404Response(); + } + } else { + $object_type = $request->getURIData('objectType'); + if (!$object_type) { + $object_type = $request->getURIData('templateType'); + $is_template = true; + } + + $phid_types = PhabricatorPHIDType::getAllInstalledTypes($viewer); + if (empty($phid_types[$object_type])) { + return new Aphront404Response(); + } + $object = $phid_types[$object_type]->newObject(); + if (!$object) { + return new Aphront404Response(); + } + } $action_options = array( PhabricatorPolicy::ACTION_ALLOW => pht('Allow'), @@ -15,6 +44,13 @@ final class PhabricatorPolicyEditController $rules = id(new PhutilSymbolLoader()) ->setAncestorClass('PhabricatorPolicyRule') ->loadObjects(); + + foreach ($rules as $key => $rule) { + if (!$rule->canApplyToObject($object)) { + unset($rules[$key]); + } + } + $rules = msort($rules, 'getRuleOrder'); $default_rule = array( diff --git a/src/applications/policy/filter/PhabricatorPolicyFilter.php b/src/applications/policy/filter/PhabricatorPolicyFilter.php index 46cb9352f7..dcff36d338 100644 --- a/src/applications/policy/filter/PhabricatorPolicyFilter.php +++ b/src/applications/policy/filter/PhabricatorPolicyFilter.php @@ -1,6 +1,6 @@ $object) { $object_capabilities = $object->getCapabilities(); foreach ($capabilities as $capability) { @@ -143,19 +145,31 @@ final class PhabricatorPolicyFilter { } $policy = $this->getObjectPolicy($object, $capability); + + if (PhabricatorPolicyQuery::isObjectPolicy($policy)) { + $need_objpolicies[$policy][] = $object; + continue; + } + $type = phid_get_type($policy); if ($type == PhabricatorProjectProjectPHIDType::TYPECONST) { $need_projects[$policy] = $policy; + continue; } if ($type == PhabricatorPolicyPHIDTypePolicy::TYPECONST) { - $need_policies[$policy] = $policy; + $need_policies[$policy][] = $object; + continue; } } } + if ($need_objpolicies) { + $this->loadObjectPolicies($need_objpolicies); + } + if ($need_policies) { - $this->loadCustomPolicies(array_keys($need_policies)); + $this->loadCustomPolicies($need_policies); } // If we need projects, check if any of the projects we need are also the @@ -486,6 +500,15 @@ final class PhabricatorPolicyFilter { $this->rejectObject($object, $policy, $capability); break; default: + if (PhabricatorPolicyQuery::isObjectPolicy($policy)) { + if ($this->checkObjectPolicy($policy, $object)) { + return true; + } else { + $this->rejectObject($object, $policy, $capability); + break; + } + } + $type = phid_get_type($policy); if ($type == PhabricatorProjectProjectPHIDType::TYPECONST) { if (!empty($this->userProjects[$viewer->getPHID()][$policy])) { @@ -500,7 +523,7 @@ final class PhabricatorPolicyFilter { $this->rejectObject($object, $policy, $capability); } } else if ($type == PhabricatorPolicyPHIDTypePolicy::TYPECONST) { - if ($this->checkCustomPolicy($policy)) { + if ($this->checkCustomPolicy($policy, $object)) { return true; } else { $this->rejectObject($object, $policy, $capability); @@ -573,30 +596,73 @@ final class PhabricatorPolicyFilter { throw $exception; } - private function loadCustomPolicies(array $phids) { + private function loadObjectPolicies(array $map) { + $viewer = $this->viewer; + $viewer_phid = $viewer->getPHID(); + + $rules = PhabricatorPolicyQuery::getObjectPolicyRules(null); + + $results = array(); + foreach ($map as $key => $object_list) { + $rule = idx($rules, $key); + if (!$rule) { + continue; + } + + foreach ($object_list as $object_key => $object) { + if (!$rule->canApplyToObject($object)) { + unset($object_list[$object_key]); + } + } + + $rule->willApplyRules($viewer, array(), $object_list); + $results[$key] = $rule; + } + + $this->objectPolicies[$viewer_phid] = $results; + } + + private function loadCustomPolicies(array $map) { $viewer = $this->viewer; $viewer_phid = $viewer->getPHID(); $custom_policies = id(new PhabricatorPolicyQuery()) ->setViewer($viewer) - ->withPHIDs($phids) + ->withPHIDs(array_keys($map)) ->execute(); $custom_policies = mpull($custom_policies, null, 'getPHID'); - $classes = array(); $values = array(); - foreach ($custom_policies as $policy) { + $objects = array(); + foreach ($custom_policies as $policy_phid => $policy) { foreach ($policy->getCustomRuleClasses() as $class) { $classes[$class] = $class; $values[$class][] = $policy->getCustomRuleValues($class); + + foreach (idx($map, $policy_phid, array()) as $object) { + $objects[$class][] = $object; + } } } foreach ($classes as $class => $ignored) { - $object = newv($class, array()); - $object->willApplyRules($viewer, array_mergev($values[$class])); - $classes[$class] = $object; + $rule_object = newv($class, array()); + + // Filter out any objects which the rule can't apply to. + $target_objects = idx($objects, $class, array()); + foreach ($target_objects as $key => $target_object) { + if (!$rule_object->canApplyToObject($target_object)) { + unset($target_objects[$key]); + } + } + + $rule_object->willApplyRules( + $viewer, + array_mergev($values[$class]), + $target_objects); + + $classes[$class] = $rule_object; } foreach ($custom_policies as $policy) { @@ -610,7 +676,28 @@ final class PhabricatorPolicyFilter { $this->customPolicies[$viewer->getPHID()] += $custom_policies; } - private function checkCustomPolicy($policy_phid) { + private function checkObjectPolicy( + $policy_phid, + PhabricatorPolicyInterface $object) { + $viewer = $this->viewer; + $viewer_phid = $viewer->getPHID(); + + $rule = idx($this->objectPolicies[$viewer_phid], $policy_phid); + if (!$rule) { + return false; + } + + if (!$rule->canApplyToObject($object)) { + return false; + } + + return $rule->applyRule($viewer, null, $object); + } + + private function checkCustomPolicy( + $policy_phid, + PhabricatorPolicyInterface $object) { + $viewer = $this->viewer; $viewer_phid = $viewer->getPHID(); @@ -623,14 +710,19 @@ final class PhabricatorPolicyFilter { $objects = $policy->getRuleObjects(); $action = null; foreach ($policy->getRules() as $rule) { - $object = idx($objects, idx($rule, 'rule')); - if (!$object) { + $rule_object = idx($objects, idx($rule, 'rule')); + if (!$rule_object) { // Reject, this policy has a bogus rule. return false; } + if (!$rule_object->canApplyToObject($object)) { + // Reject, this policy rule can't be applied to the given object. + return false; + } + // If the user matches this rule, use this action. - if ($object->applyRule($viewer, idx($rule, 'value'))) { + if ($rule_object->applyRule($viewer, idx($rule, 'value'), $object)) { $action = idx($rule, 'action'); break; } diff --git a/src/applications/policy/query/PhabricatorPolicyQuery.php b/src/applications/policy/query/PhabricatorPolicyQuery.php index 6a5c2219df..496c704b71 100644 --- a/src/applications/policy/query/PhabricatorPolicyQuery.php +++ b/src/applications/policy/query/PhabricatorPolicyQuery.php @@ -6,6 +6,8 @@ final class PhabricatorPolicyQuery private $object; private $phids; + const OBJECT_POLICY_PREFIX = 'obj.'; + public function setObject(PhabricatorPolicyInterface $object) { $this->object = $object; return $this; @@ -71,7 +73,15 @@ final class PhabricatorPolicyQuery $results = array(); // First, load global policies. - foreach ($this->getGlobalPolicies() as $phid => $policy) { + foreach (self::getGlobalPolicies() as $phid => $policy) { + if (isset($phids[$phid])) { + $results[$phid] = $policy; + unset($phids[$phid]); + } + } + + // Now, load object policies. + foreach (self::getObjectPolicies($this->object) as $phid => $policy) { if (isset($phids[$phid])) { $results[$phid] = $policy; unset($phids[$phid]); @@ -212,7 +222,7 @@ final class PhabricatorPolicyQuery // option unless the object already has a "Public" policy. In this case we // retain the policy but enforce it as though it was "All Users". $show_public = PhabricatorEnv::getEnvConfig('policy.allow-public'); - foreach ($this->getGlobalPolicies() as $phid => $policy) { + foreach (self::getGlobalPolicies() as $phid => $policy) { if ($phid == PhabricatorPolicies::POLICY_PUBLIC) { if (!$show_public) { continue; @@ -221,6 +231,10 @@ final class PhabricatorPolicyQuery $phids[] = $phid; } + foreach (self::getObjectPolicies($this->object) as $phid => $policy) { + $phids[] = $phid; + } + return $phids; } @@ -234,4 +248,99 @@ final class PhabricatorPolicyQuery return 'PhabricatorPolicyApplication'; } + public static function isSpecialPolicy($identifier) { + if (self::isObjectPolicy($identifier)) { + return true; + } + + if (self::isGlobalPolicy($identifier)) { + return true; + } + + return false; + } + + +/* -( Object Policies )---------------------------------------------------- */ + + + public static function isObjectPolicy($identifier) { + $prefix = self::OBJECT_POLICY_PREFIX; + return !strncmp($identifier, $prefix, strlen($prefix)); + } + + public static function getObjectPolicy($identifier) { + if (!self::isObjectPolicy($identifier)) { + return null; + } + + $policies = self::getObjectPolicies(null); + return idx($policies, $identifier); + } + + public static function getObjectPolicyRule($identifier) { + if (!self::isObjectPolicy($identifier)) { + return null; + } + + $rules = self::getObjectPolicyRules(null); + return idx($rules, $identifier); + } + + public static function getObjectPolicies($object) { + $rule_map = self::getObjectPolicyRules($object); + + $results = array(); + foreach ($rule_map as $key => $rule) { + $results[$key] = id(new PhabricatorPolicy()) + ->setType(PhabricatorPolicyType::TYPE_OBJECT) + ->setPHID($key) + ->setIcon($rule->getObjectPolicyIcon()) + ->setName($rule->getObjectPolicyName()) + ->setShortName($rule->getObjectPolicyShortName()) + ->makeEphemeral(); + } + + return $results; + } + + public static function getObjectPolicyRules($object) { + $rules = id(new PhutilSymbolLoader()) + ->setAncestorClass('PhabricatorPolicyRule') + ->loadObjects(); + + $results = array(); + foreach ($rules as $rule) { + $key = $rule->getObjectPolicyKey(); + if (!$key) { + continue; + } + + $full_key = $rule->getObjectPolicyFullKey(); + if (isset($results[$full_key])) { + throw new Exception( + pht( + 'Two policy rules (of classes "%s" and "%s") define the same '. + 'object policy key ("%s"), but each object policy rule must use '. + 'a unique key.', + get_class($rule), + get_class($results[$full_key]), + $key)); + } + + $results[$full_key] = $rule; + } + + if ($object !== null) { + foreach ($results as $key => $rule) { + if (!$rule->canApplyToObject($object)) { + unset($results[$key]); + } + } + } + + return $results; + } + + } diff --git a/src/applications/policy/rule/PhabricatorAdministratorsPolicyRule.php b/src/applications/policy/rule/PhabricatorAdministratorsPolicyRule.php index f232cb3008..b6e450adde 100644 --- a/src/applications/policy/rule/PhabricatorAdministratorsPolicyRule.php +++ b/src/applications/policy/rule/PhabricatorAdministratorsPolicyRule.php @@ -6,7 +6,10 @@ final class PhabricatorAdministratorsPolicyRule extends PhabricatorPolicyRule { return pht('administrators'); } - public function applyRule(PhabricatorUser $viewer, $value) { + public function applyRule( + PhabricatorUser $viewer, + $value, + PhabricatorPolicyInterface $object) { return $viewer->getIsAdmin(); } diff --git a/src/applications/policy/rule/PhabricatorLegalpadSignaturePolicyRule.php b/src/applications/policy/rule/PhabricatorLegalpadSignaturePolicyRule.php index 9797d5ef80..3aa7ef8d9c 100644 --- a/src/applications/policy/rule/PhabricatorLegalpadSignaturePolicyRule.php +++ b/src/applications/policy/rule/PhabricatorLegalpadSignaturePolicyRule.php @@ -9,7 +9,11 @@ final class PhabricatorLegalpadSignaturePolicyRule return pht('signers of legalpad documents'); } - public function willApplyRules(PhabricatorUser $viewer, array $values) { + public function willApplyRules( + PhabricatorUser $viewer, + array $values, + array $objects) { + $values = array_unique(array_filter(array_mergev($values))); if (!$values) { return; @@ -26,12 +30,17 @@ final class PhabricatorLegalpadSignaturePolicyRule $this->signatures = mpull($documents, 'getPHID', 'getPHID'); } - public function applyRule(PhabricatorUser $viewer, $value) { + public function applyRule( + PhabricatorUser $viewer, + $value, + PhabricatorPolicyInterface $object) { + foreach ($value as $document_phid) { if (!isset($this->signatures[$document_phid])) { return false; } } + return true; } diff --git a/src/applications/policy/rule/PhabricatorLunarPhasePolicyRule.php b/src/applications/policy/rule/PhabricatorLunarPhasePolicyRule.php index 24f8f26138..a3336a7971 100644 --- a/src/applications/policy/rule/PhabricatorLunarPhasePolicyRule.php +++ b/src/applications/policy/rule/PhabricatorLunarPhasePolicyRule.php @@ -11,7 +11,11 @@ final class PhabricatorLunarPhasePolicyRule extends PhabricatorPolicyRule { return pht('when the moon'); } - public function applyRule(PhabricatorUser $viewer, $value) { + public function applyRule( + PhabricatorUser $viewer, + $value, + PhabricatorPolicyInterface $object) { + $moon = new PhutilLunarPhase(PhabricatorTime::getNow()); switch ($value) { diff --git a/src/applications/policy/rule/PhabricatorPolicyRule.php b/src/applications/policy/rule/PhabricatorPolicyRule.php index eaa04e1e9e..59fcc954c7 100644 --- a/src/applications/policy/rule/PhabricatorPolicyRule.php +++ b/src/applications/policy/rule/PhabricatorPolicyRule.php @@ -1,6 +1,9 @@ setKey(self::getObjectPolicyCacheKey($object, $rule), $hint); + } + + protected function getTransactionHint( + PhabricatorPolicyInterface $object) { + + $cache = PhabricatorCaches::getRequestCache(); + return $cache->getKey(self::getObjectPolicyCacheKey($object, $this)); + } + + private static function getObjectPolicyCacheKey( + PhabricatorPolicyInterface $object, + PhabricatorPolicyRule $rule) { + $hash = spl_object_hash($object); + $rule = get_class($rule); + return 'policycache.'.$hash.'.'.$rule; + } + + +/* -( Implementing Object Policies )--------------------------------------- */ + + + /** + * Return a unique string like "maniphest.author" to expose this rule as an + * object policy. + * + * Object policy rules, like "Task Author", are more advanced than basic + * policy rules (like "All Users") but not as powerful as custom rules. + * + * @return string Unique identifier for this rule. + * @task objectpolicy + */ + public function getObjectPolicyKey() { + return null; + } + + public function getObjectPolicyFullKey() { + $key = $this->getObjectPolicyKey(); + + if (!$key) { + throw new Exception( + pht( + 'This policy rule (of class "%s") does not have an associated '. + 'object policy key.', + get_class($this))); + } + + return PhabricatorPolicyQuery::OBJECT_POLICY_PREFIX.$key; + } + + public function getObjectPolicyName() { + throw new PhutilMethodNotImplementedException(); + } + + public function getObjectPolicyShortName() { + return $this->getObjectPolicyName(); + } + + public function getObjectPolicyIcon() { + return 'fa-cube'; + } + + public function getPolicyExplanation() { + throw new PhutilMethodNotImplementedException(); + } + } diff --git a/src/applications/policy/rule/PhabricatorProjectsPolicyRule.php b/src/applications/policy/rule/PhabricatorProjectsPolicyRule.php index eca97ce37d..c3fbfd4f7e 100644 --- a/src/applications/policy/rule/PhabricatorProjectsPolicyRule.php +++ b/src/applications/policy/rule/PhabricatorProjectsPolicyRule.php @@ -8,7 +8,11 @@ final class PhabricatorProjectsPolicyRule extends PhabricatorPolicyRule { return pht('members of projects'); } - public function willApplyRules(PhabricatorUser $viewer, array $values) { + public function willApplyRules( + PhabricatorUser $viewer, + array $values, + array $objects) { + $values = array_unique(array_filter(array_mergev($values))); if (!$values) { return; @@ -24,12 +28,17 @@ final class PhabricatorProjectsPolicyRule extends PhabricatorPolicyRule { } } - public function applyRule(PhabricatorUser $viewer, $value) { + public function applyRule( + PhabricatorUser $viewer, + $value, + PhabricatorPolicyInterface $object) { + foreach ($value as $project_phid) { if (isset($this->memberships[$viewer->getPHID()][$project_phid])) { return true; } } + return false; } diff --git a/src/applications/policy/rule/PhabricatorUsersPolicyRule.php b/src/applications/policy/rule/PhabricatorUsersPolicyRule.php index c60e43abb6..aa75027cb1 100644 --- a/src/applications/policy/rule/PhabricatorUsersPolicyRule.php +++ b/src/applications/policy/rule/PhabricatorUsersPolicyRule.php @@ -6,12 +6,17 @@ final class PhabricatorUsersPolicyRule extends PhabricatorPolicyRule { return pht('users'); } - public function applyRule(PhabricatorUser $viewer, $value) { + public function applyRule( + PhabricatorUser $viewer, + $value, + PhabricatorPolicyInterface $object) { + foreach ($value as $phid) { if ($phid == $viewer->getPHID()) { return true; } } + return false; } diff --git a/src/applications/policy/storage/PhabricatorPolicy.php b/src/applications/policy/storage/PhabricatorPolicy.php index c83d09ab5d..e01e0dd416 100644 --- a/src/applications/policy/storage/PhabricatorPolicy.php +++ b/src/applications/policy/storage/PhabricatorPolicy.php @@ -54,6 +54,11 @@ final class PhabricatorPolicy return PhabricatorPolicyQuery::getGlobalPolicy($policy_identifier); } + $policy = PhabricatorPolicyQuery::getObjectPolicy($policy_identifier); + if ($policy) { + return $policy; + } + if (!$handle) { throw new Exception( pht( @@ -158,7 +163,16 @@ final class PhabricatorPolicy return $this->workflow; } + public function setIcon($icon) { + $this->icon = $icon; + return $this; + } + public function getIcon() { + if ($this->icon) { + return $this->icon; + } + switch ($this->getType()) { case PhabricatorPolicyType::TYPE_GLOBAL: static $map = array( @@ -204,6 +218,11 @@ final class PhabricatorPolicy PhabricatorUser $viewer, $policy) { + $rule = PhabricatorPolicyQuery::getObjectPolicyRule($policy); + if ($rule) { + return $rule->getPolicyExplanation(); + } + switch ($policy) { case PhabricatorPolicies::POLICY_PUBLIC: return pht('This object is public.'); diff --git a/src/applications/ponder/constants/PonderConstants.php b/src/applications/ponder/constants/PonderConstants.php index ca281620c4..e096cc0a54 100644 --- a/src/applications/ponder/constants/PonderConstants.php +++ b/src/applications/ponder/constants/PonderConstants.php @@ -1,3 +1,3 @@ requireActor(); if (!$this->votable) { - throw new Exception(pht('Must set votable before saving vote.')); + throw new PhutilInvalidStateException('setVotable'); } $votable = $this->votable; @@ -63,8 +63,8 @@ final class PonderVoteEditor extends PhabricatorEditor { queryfx($conn, 'UPDATE %T as t - SET t.`voteCount` = t.`voteCount` + %d - WHERE t.`PHID` = %s', + SET t.voteCount = t.voteCount + %d + WHERE t.PHID = %s', $votable->getTableName(), $delta, $votable->getVotablePHID()); diff --git a/src/applications/project/application/PhabricatorProjectApplication.php b/src/applications/project/application/PhabricatorProjectApplication.php index e7e4f623f9..adf6378e2a 100644 --- a/src/applications/project/application/PhabricatorProjectApplication.php +++ b/src/applications/project/application/PhabricatorProjectApplication.php @@ -119,16 +119,16 @@ final class PhabricatorProjectApplication extends PhabricatorApplication { 'default' => PhabricatorPolicies::POLICY_ADMIN, ), ProjectDefaultViewCapability::CAPABILITY => array( - 'caption' => pht( - 'Default view policy for newly created projects.'), + 'caption' => pht('Default view policy for newly created projects.'), + 'template' => PhabricatorProjectProjectPHIDType::TYPECONST, ), ProjectDefaultEditCapability::CAPABILITY => array( - 'caption' => pht( - 'Default edit policy for newly created projects.'), + 'caption' => pht('Default edit policy for newly created projects.'), + 'template' => PhabricatorProjectProjectPHIDType::TYPECONST, ), ProjectDefaultJoinCapability::CAPABILITY => array( - 'caption' => pht( - 'Default join policy for newly created projects.'), + 'caption' => pht('Default join policy for newly created projects.'), + 'template' => PhabricatorProjectProjectPHIDType::TYPECONST, ), ); } diff --git a/src/applications/project/constants/PhabricatorProjectStatus.php b/src/applications/project/constants/PhabricatorProjectStatus.php index 16f4a98332..79b1ee823c 100644 --- a/src/applications/project/constants/PhabricatorProjectStatus.php +++ b/src/applications/project/constants/PhabricatorProjectStatus.php @@ -1,6 +1,6 @@ setName(pht('Edit Details')) ->setIcon('fa-pencil') - ->setHref($this->getApplicationURI("details/{$id}/"))); + ->setHref($this->getApplicationURI("details/{$id}/")) + ->setDisabled(!$can_edit)); $view->addAction( id(new PhabricatorActionView()) diff --git a/src/applications/project/view/ProjectBoardTaskCard.php b/src/applications/project/view/ProjectBoardTaskCard.php index a601608ebf..4fc26988d7 100644 --- a/src/applications/project/view/ProjectBoardTaskCard.php +++ b/src/applications/project/view/ProjectBoardTaskCard.php @@ -1,6 +1,6 @@ getPriority(), 'grey'); $card = id(new PHUIObjectItemView()) + ->setObject($task) + ->setUser($this->getViewer()) ->setObjectName('T'.$task->getID()) ->setHeader($task->getTitle()) ->setGrippable($can_edit) diff --git a/src/applications/releeph/commitfinder/ReleephCommitFinder.php b/src/applications/releeph/commitfinder/ReleephCommitFinder.php index 89fd84e196..8c1712c802 100644 --- a/src/applications/releeph/commitfinder/ReleephCommitFinder.php +++ b/src/applications/releeph/commitfinder/ReleephCommitFinder.php @@ -1,6 +1,6 @@ diff --git a/src/applications/releeph/view/branch/ReleephBranchTemplate.php b/src/applications/releeph/view/branch/ReleephBranchTemplate.php index 7efaaad9fb..f29e7a9fc2 100644 --- a/src/applications/releeph/view/branch/ReleephBranchTemplate.php +++ b/src/applications/releeph/view/branch/ReleephBranchTemplate.php @@ -1,9 +1,14 @@ commitHandle = $handle; return $this; diff --git a/src/applications/repository/constants/PhabricatorRepositoryType.php b/src/applications/repository/constants/PhabricatorRepositoryType.php index a99c76d889..b3415f4463 100644 --- a/src/applications/repository/constants/PhabricatorRepositoryType.php +++ b/src/applications/repository/constants/PhabricatorRepositoryType.php @@ -1,6 +1,6 @@ setSecretData('quack')->save(); $http_credential = PassphraseCredential::initializeNewCredential($user) - ->setCredentialType(PassphraseCredentialTypePassword::CREDENTIAL_TYPE) - ->setProvidesType(PassphraseCredentialTypePassword::PROVIDES_TYPE) + ->setCredentialType(PassphrasePasswordCredentialType::CREDENTIAL_TYPE) + ->setProvidesType(PassphrasePasswordCredentialType::PROVIDES_TYPE) ->setUsername('duck') ->setSecretID($http_secret->getID()) ->save(); diff --git a/src/applications/search/constants/PhabricatorSearchRelationship.php b/src/applications/search/constants/PhabricatorSearchRelationship.php index 8631aeec29..0d43f0bdc4 100644 --- a/src/applications/search/constants/PhabricatorSearchRelationship.php +++ b/src/applications/search/constants/PhabricatorSearchRelationship.php @@ -1,6 +1,6 @@ withSpacePHIDs($map['spacePHIDs']); + } else { + // If the user doesn't search for objects in specific spaces, we + // default to "all active spaces you have permission to view". + $query->withSpaceIsArchived(false); } } diff --git a/src/applications/search/engine/PhabricatorJumpNavHandler.php b/src/applications/search/engine/PhabricatorJumpNavHandler.php index 7a340a7e8f..4a03ec9a8a 100644 --- a/src/applications/search/engine/PhabricatorJumpNavHandler.php +++ b/src/applications/search/engine/PhabricatorJumpNavHandler.php @@ -1,6 +1,6 @@ assertTrue(true); + } + +} diff --git a/src/applications/search/engine/__tests__/PhabricatorSearchEngineTestCase.php b/src/applications/search/engine/__tests__/PhabricatorSearchEngineTestCase.php new file mode 100644 index 0000000000..bf997288b6 --- /dev/null +++ b/src/applications/search/engine/__tests__/PhabricatorSearchEngineTestCase.php @@ -0,0 +1,10 @@ +assertTrue(true); + } + +} diff --git a/src/applications/search/index/PhabricatorSearchAbstractDocument.php b/src/applications/search/index/PhabricatorSearchAbstractDocument.php index 09923c7dcc..0e57be848c 100644 --- a/src/applications/search/index/PhabricatorSearchAbstractDocument.php +++ b/src/applications/search/index/PhabricatorSearchAbstractDocument.php @@ -1,6 +1,6 @@ setName('timezone') ->setOptions($timezone_id_map) ->setValue($user->getTimezoneIdentifier())) - ->appendRemarkupInstructions( - pht( - "**Custom Date and Time Formats**\n\n". - "You can specify custom formats which will be used when ". - "rendering dates and times of day. Examples:\n\n". - "| Format | Example | Notes |\n". - "| ------ | -------- | ----- |\n". - "| `g:i A` | 2:34 PM | Default 12-hour time. |\n". - "| `G.i a` | 02.34 pm | Alternate 12-hour time. |\n". - "| `H:i` | 14:34 | 24-hour time. |\n". - "\n\n". - "You can find a [[%s | full reference in the PHP manual]].", - 'http://www.php.net/manual/en/function.date.php')) ->appendChild( - id(new AphrontFormTextControl()) + id(new AphrontFormSelectControl()) ->setLabel(pht('Time-of-Day Format')) ->setName($pref_time) + ->setOptions(array( + 'g:i A' => pht('12-hour (2:34 PM)'), + 'H:i' => pht('24-hour (14:34)'), + )) ->setCaption( pht('Format used when rendering a time of day.')) ->setValue($preferences->getPreference($pref_time))) diff --git a/src/applications/settings/panel/PhabricatorSettingsPanel.php b/src/applications/settings/panel/PhabricatorSettingsPanel.php index f1dacce3a7..341b7a4f69 100644 --- a/src/applications/settings/panel/PhabricatorSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorSettingsPanel.php @@ -13,7 +13,7 @@ * @task panel Panel Implementation * @task internal Internals */ -abstract class PhabricatorSettingsPanel { +abstract class PhabricatorSettingsPanel extends Phobject { private $user; private $viewer; diff --git a/src/applications/slowvote/application/PhabricatorSlowvoteApplication.php b/src/applications/slowvote/application/PhabricatorSlowvoteApplication.php index fa3acfd779..40791659b1 100644 --- a/src/applications/slowvote/application/PhabricatorSlowvoteApplication.php +++ b/src/applications/slowvote/application/PhabricatorSlowvoteApplication.php @@ -64,6 +64,7 @@ final class PhabricatorSlowvoteApplication extends PhabricatorApplication { return array( PhabricatorSlowvoteDefaultViewCapability::CAPABILITY => array( 'caption' => pht('Default view policy for new polls.'), + 'template' => PhabricatorSlowvotePollPHIDType::TYPECONST, ), ); } diff --git a/src/applications/spaces/application/PhabricatorSpacesApplication.php b/src/applications/spaces/application/PhabricatorSpacesApplication.php index 380f80569e..7942caf919 100644 --- a/src/applications/spaces/application/PhabricatorSpacesApplication.php +++ b/src/applications/spaces/application/PhabricatorSpacesApplication.php @@ -38,6 +38,15 @@ final class PhabricatorSpacesApplication extends PhabricatorApplication { return true; } + public function getHelpDocumentationArticles(PhabricatorUser $viewer) { + return array( + array( + 'name' => pht('Spaces User Guide'), + 'href' => PhabricatorEnv::getDoclink('Spaces User Guide'), + ), + ); + } + public function getRemarkupRules() { return array( new PhabricatorSpacesRemarkupRule(), @@ -51,6 +60,8 @@ final class PhabricatorSpacesApplication extends PhabricatorApplication { '(?:query/(?P[^/]+)/)?' => 'PhabricatorSpacesListController', 'create/' => 'PhabricatorSpacesEditController', 'edit/(?:(?P\d+)/)?' => 'PhabricatorSpacesEditController', + '(?Pactivate|archive)/(?P\d+)/' + => 'PhabricatorSpacesArchiveController', ), ); } @@ -62,10 +73,12 @@ final class PhabricatorSpacesApplication extends PhabricatorApplication { ), PhabricatorSpacesCapabilityDefaultView::CAPABILITY => array( 'caption' => pht('Default view policy for newly created spaces.'), + 'template' => PhabricatorSpacesNamespacePHIDType::TYPECONST, ), PhabricatorSpacesCapabilityDefaultEdit::CAPABILITY => array( 'caption' => pht('Default edit policy for newly created spaces.'), 'default' => PhabricatorPolicies::POLICY_ADMIN, + 'template' => PhabricatorSpacesNamespacePHIDType::TYPECONST, ), ); } diff --git a/src/applications/spaces/controller/PhabricatorSpacesArchiveController.php b/src/applications/spaces/controller/PhabricatorSpacesArchiveController.php new file mode 100644 index 0000000000..82cf19e9e8 --- /dev/null +++ b/src/applications/spaces/controller/PhabricatorSpacesArchiveController.php @@ -0,0 +1,76 @@ +getUser(); + + $space = id(new PhabricatorSpacesNamespaceQuery()) + ->setViewer($viewer) + ->withIDs(array($request->getURIData('id'))) + ->requireCapabilities( + array( + PhabricatorPolicyCapability::CAN_VIEW, + PhabricatorPolicyCapability::CAN_EDIT, + )) + ->executeOne(); + if (!$space) { + return new Aphront404Response(); + } + + $is_archive = ($request->getURIData('action') == 'archive'); + $cancel_uri = '/'.$space->getMonogram(); + + if ($request->isFormPost()) { + $type_archive = PhabricatorSpacesNamespaceTransaction::TYPE_ARCHIVE; + + $xactions = array(); + $xactions[] = id(new PhabricatorSpacesNamespaceTransaction()) + ->setTransactionType($type_archive) + ->setNewValue($is_archive ? 1 : 0); + + $editor = id(new PhabricatorSpacesNamespaceEditor()) + ->setActor($viewer) + ->setContinueOnNoEffect(true) + ->setContinueOnMissingFields(true) + ->setContentSourceFromRequest($request); + + $editor->applyTransactions($space, $xactions); + + return id(new AphrontRedirectResponse())->setURI($cancel_uri); + } + + $body = array(); + if ($is_archive) { + $title = pht('Archive Space: %s', $space->getNamespaceName()); + $body[] = pht( + 'If you archive this Space, you will no longer be able to create '. + 'new objects inside it.'); + $body[] = pht( + 'Existing objects in this Space will be hidden from query results '. + 'by default.'); + $button = pht('Archive Space'); + } else { + $title = pht('Activate Space: %s', $space->getNamespaceName()); + $body[] = pht( + 'If you activate this space, you will be able to create objects '. + 'inside it again.'); + $body[] = pht( + 'Existing objects will no longer be hidden from query results.'); + $button = pht('Activate Space'); + } + + + $dialog = $this->newDialog() + ->setTitle($title) + ->addCancelButton($cancel_uri) + ->addSubmitButton($button); + + foreach ($body as $paragraph) { + $dialog->appendParagraph($paragraph); + } + + return $dialog; + } +} diff --git a/src/applications/spaces/controller/PhabricatorSpacesEditController.php b/src/applications/spaces/controller/PhabricatorSpacesEditController.php index b64a16ab97..4dfeeed7ed 100644 --- a/src/applications/spaces/controller/PhabricatorSpacesEditController.php +++ b/src/applications/spaces/controller/PhabricatorSpacesEditController.php @@ -54,6 +54,7 @@ final class PhabricatorSpacesEditController $validation_exception = null; $e_name = true; $v_name = $space->getNamespaceName(); + $v_desc = $space->getDescription(); $v_view = $space->getViewPolicy(); $v_edit = $space->getEditPolicy(); @@ -62,10 +63,12 @@ final class PhabricatorSpacesEditController $e_name = null; $v_name = $request->getStr('name'); + $v_desc = $request->getStr('description'); $v_view = $request->getStr('viewPolicy'); $v_edit = $request->getStr('editPolicy'); $type_name = PhabricatorSpacesNamespaceTransaction::TYPE_NAME; + $type_desc = PhabricatorSpacesNamespaceTransaction::TYPE_DESCRIPTION; $type_default = PhabricatorSpacesNamespaceTransaction::TYPE_DEFAULT; $type_view = PhabricatorTransactions::TYPE_VIEW_POLICY; $type_edit = PhabricatorTransactions::TYPE_EDIT_POLICY; @@ -74,6 +77,10 @@ final class PhabricatorSpacesEditController ->setTransactionType($type_name) ->setNewValue($v_name); + $xactions[] = id(new PhabricatorSpacesNamespaceTransaction()) + ->setTransactionType($type_desc) + ->setNewValue($v_desc); + $xactions[] = id(new PhabricatorSpacesNamespaceTransaction()) ->setTransactionType($type_view) ->setNewValue($v_view); @@ -128,6 +135,11 @@ final class PhabricatorSpacesEditController ->setName('name') ->setValue($v_name) ->setError($e_name)) + ->appendControl( + id(new PhabricatorRemarkupControl()) + ->setLabel(pht('Description')) + ->setName('description') + ->setValue($v_desc)) ->appendChild( id(new AphrontFormPolicyControl()) ->setUser($viewer) diff --git a/src/applications/spaces/controller/PhabricatorSpacesViewController.php b/src/applications/spaces/controller/PhabricatorSpacesViewController.php index 911549234f..511d853151 100644 --- a/src/applications/spaces/controller/PhabricatorSpacesViewController.php +++ b/src/applications/spaces/controller/PhabricatorSpacesViewController.php @@ -37,6 +37,12 @@ final class PhabricatorSpacesViewController ->setHeader($space->getNamespaceName()) ->setPolicyObject($space); + if ($space->getIsArchived()) { + $header->setStatus('fa-ban', 'red', pht('Archived')); + } else { + $header->setStatus('fa-check', 'bluegrey', pht('Active')); + } + $box = id(new PHUIObjectBoxView()) ->setHeader($header) ->addPropertyList($property_list); @@ -75,6 +81,20 @@ final class PhabricatorSpacesViewController pht('Editable By'), $descriptions[PhabricatorPolicyCapability::CAN_EDIT]); + $description = $space->getDescription(); + if (strlen($description)) { + $description = PhabricatorMarkupEngine::renderOneObject( + id(new PhabricatorMarkupOneOff())->setContent($description), + 'default', + $viewer); + + $list->addSectionHeader( + pht('Description'), + PHUIPropertyListView::ICON_SUMMARY); + + $list->addTextContent($description); + } + return $list; } @@ -98,6 +118,26 @@ final class PhabricatorSpacesViewController ->setWorkflow(!$can_edit) ->setDisabled(!$can_edit)); + $id = $space->getID(); + + if ($space->getIsArchived()) { + $list->addAction( + id(new PhabricatorActionView()) + ->setName(pht('Activate Space')) + ->setIcon('fa-check') + ->setHref($this->getApplicationURI("activate/{$id}/")) + ->setDisabled(!$can_edit) + ->setWorkflow(true)); + } else { + $list->addAction( + id(new PhabricatorActionView()) + ->setName(pht('Archive Space')) + ->setIcon('fa-ban') + ->setHref($this->getApplicationURI("archive/{$id}/")) + ->setDisabled(!$can_edit) + ->setWorkflow(true)); + } + return $list; } diff --git a/src/applications/spaces/editor/PhabricatorSpacesNamespaceEditor.php b/src/applications/spaces/editor/PhabricatorSpacesNamespaceEditor.php index 23b01531e9..caa45f28c2 100644 --- a/src/applications/spaces/editor/PhabricatorSpacesNamespaceEditor.php +++ b/src/applications/spaces/editor/PhabricatorSpacesNamespaceEditor.php @@ -15,7 +15,9 @@ final class PhabricatorSpacesNamespaceEditor $types = parent::getTransactionTypes(); $types[] = PhabricatorSpacesNamespaceTransaction::TYPE_NAME; + $types[] = PhabricatorSpacesNamespaceTransaction::TYPE_DESCRIPTION; $types[] = PhabricatorSpacesNamespaceTransaction::TYPE_DEFAULT; + $types[] = PhabricatorSpacesNamespaceTransaction::TYPE_ARCHIVE; $types[] = PhabricatorTransactions::TYPE_VIEW_POLICY; $types[] = PhabricatorTransactions::TYPE_EDIT_POLICY; @@ -34,6 +36,13 @@ final class PhabricatorSpacesNamespaceEditor return null; } return $name; + case PhabricatorSpacesNamespaceTransaction::TYPE_DESCRIPTION: + if ($this->getIsNewObject()) { + return null; + } + return $object->getDescription(); + case PhabricatorSpacesNamespaceTransaction::TYPE_ARCHIVE: + return $object->getIsArchived(); case PhabricatorSpacesNamespaceTransaction::TYPE_DEFAULT: return $object->getIsDefaultNamespace() ? 1 : null; case PhabricatorTransactions::TYPE_VIEW_POLICY: @@ -51,9 +60,12 @@ final class PhabricatorSpacesNamespaceEditor switch ($xaction->getTransactionType()) { case PhabricatorSpacesNamespaceTransaction::TYPE_NAME: + case PhabricatorSpacesNamespaceTransaction::TYPE_DESCRIPTION: case PhabricatorTransactions::TYPE_VIEW_POLICY: case PhabricatorTransactions::TYPE_EDIT_POLICY: return $xaction->getNewValue(); + case PhabricatorSpacesNamespaceTransaction::TYPE_ARCHIVE: + return $xaction->getNewValue() ? 1 : 0; case PhabricatorSpacesNamespaceTransaction::TYPE_DEFAULT: return $xaction->getNewValue() ? 1 : null; } @@ -71,9 +83,15 @@ final class PhabricatorSpacesNamespaceEditor case PhabricatorSpacesNamespaceTransaction::TYPE_NAME: $object->setNamespaceName($new); return; + case PhabricatorSpacesNamespaceTransaction::TYPE_DESCRIPTION: + $object->setDescription($new); + return; case PhabricatorSpacesNamespaceTransaction::TYPE_DEFAULT: $object->setIsDefaultNamespace($new ? 1 : null); return; + case PhabricatorSpacesNamespaceTransaction::TYPE_ARCHIVE: + $object->setIsArchived($new ? 1 : 0); + return; case PhabricatorTransactions::TYPE_VIEW_POLICY: $object->setViewPolicy($new); return; @@ -91,7 +109,9 @@ final class PhabricatorSpacesNamespaceEditor switch ($xaction->getTransactionType()) { case PhabricatorSpacesNamespaceTransaction::TYPE_NAME: + case PhabricatorSpacesNamespaceTransaction::TYPE_DESCRIPTION: case PhabricatorSpacesNamespaceTransaction::TYPE_DEFAULT: + case PhabricatorSpacesNamespaceTransaction::TYPE_ARCHIVE: case PhabricatorTransactions::TYPE_VIEW_POLICY: case PhabricatorTransactions::TYPE_EDIT_POLICY: return; @@ -117,13 +137,27 @@ final class PhabricatorSpacesNamespaceEditor $error = new PhabricatorApplicationTransactionValidationError( $type, pht('Required'), - pht('Spaces must have a name.'), + pht('Spaces must have a name.'), nonempty(last($xactions), null)); $error->setIsMissingFieldError(true); $errors[] = $error; } break; + case PhabricatorSpacesNamespaceTransaction::TYPE_DEFAULT: + if (!$this->getIsNewObject()) { + foreach ($xactions as $xaction) { + $errors[] = new PhabricatorApplicationTransactionValidationError( + $type, + pht('Invalid'), + pht( + 'Only the first space created can be the default space, and '. + 'it must remain the default space evermore.'), + $xaction); + } + } + break; + } return $errors; diff --git a/src/applications/spaces/phid/PhabricatorSpacesNamespacePHIDType.php b/src/applications/spaces/phid/PhabricatorSpacesNamespacePHIDType.php index 22dfcffac4..6645c7edbd 100644 --- a/src/applications/spaces/phid/PhabricatorSpacesNamespacePHIDType.php +++ b/src/applications/spaces/phid/PhabricatorSpacesNamespacePHIDType.php @@ -32,10 +32,17 @@ final class PhabricatorSpacesNamespacePHIDType foreach ($handles as $phid => $handle) { $namespace = $objects[$phid]; - $monogram = $namespace->getMonogram(); - $handle->setName($namespace->getNamespaceName()); + $monogram = $namespace->getMonogram(); + $name = $namespace->getNamespaceName(); + + $handle->setName($name); + $handle->setFullName(pht('%s %s', $monogram, $name)); $handle->setURI('/'.$monogram); + + if ($namespace->getIsArchived()) { + $handle->setStatus(PhabricatorObjectHandle::STATUS_CLOSED); + } } } diff --git a/src/applications/spaces/query/PhabricatorSpacesNamespaceQuery.php b/src/applications/spaces/query/PhabricatorSpacesNamespaceQuery.php index ac02c306e7..65ac146bd0 100644 --- a/src/applications/spaces/query/PhabricatorSpacesNamespaceQuery.php +++ b/src/applications/spaces/query/PhabricatorSpacesNamespaceQuery.php @@ -9,6 +9,7 @@ final class PhabricatorSpacesNamespaceQuery private $ids; private $phids; private $isDefaultNamespace; + private $isArchived; public function withIDs(array $ids) { $this->ids = $ids; @@ -25,38 +26,32 @@ final class PhabricatorSpacesNamespaceQuery return $this; } + public function withIsArchived($archived) { + $this->isArchived = $archived; + return $this; + } + public function getQueryApplicationClass() { return 'PhabricatorSpacesApplication'; } protected function loadPage() { - $table = new PhabricatorSpacesNamespace(); - $conn_r = $table->establishConnection('r'); - - $rows = queryfx_all( - $conn_r, - 'SELECT * FROM %T %Q %Q %Q', - $table->getTableName(), - $this->buildWhereClause($conn_r), - $this->buildOrderClause($conn_r), - $this->buildLimitClause($conn_r)); - - return $table->loadAllFromArray($rows); + return $this->loadStandardPage(new PhabricatorSpacesNamespace()); } - protected function buildWhereClause(AphrontDatabaseConnection $conn_r) { - $where = array(); + protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { + $where = parent::buildWhereClauseParts($conn); if ($this->ids !== null) { $where[] = qsprintf( - $conn_r, + $conn, 'id IN (%Ld)', $this->ids); } if ($this->phids !== null) { $where[] = qsprintf( - $conn_r, + $conn, 'phid IN (%Ls)', $this->phids); } @@ -64,17 +59,23 @@ final class PhabricatorSpacesNamespaceQuery if ($this->isDefaultNamespace !== null) { if ($this->isDefaultNamespace) { $where[] = qsprintf( - $conn_r, + $conn, 'isDefaultNamespace = 1'); } else { $where[] = qsprintf( - $conn_r, + $conn, 'isDefaultNamespace IS NULL'); } } - $where[] = $this->buildPagingClause($conn_r); - return $this->formatWhereClause($where); + if ($this->isArchived !== null) { + $where[] = qsprintf( + $conn, + 'isArchived = %d', + (int)$this->isArchived); + } + + return $where; } public static function destroySpacesCache() { @@ -90,6 +91,17 @@ final class PhabricatorSpacesNamespaceQuery return (bool)self::getAllSpaces(); } + public static function getViewerSpacesExist(PhabricatorUser $viewer) { + if (!self::getSpacesExist()) { + return false; + } + + // If the viewer has access to only one space, pretend spaces simply don't + // exist. + $spaces = self::getViewerSpaces($viewer); + return (count($spaces) > 1); + } + public static function getAllSpaces() { $cache = PhabricatorCaches::getRequestCache(); $cache_key = self::KEY_ALL; @@ -145,6 +157,46 @@ final class PhabricatorSpacesNamespaceQuery return $result; } + + public static function getViewerActiveSpaces(PhabricatorUser $viewer) { + $spaces = self::getViewerSpaces($viewer); + + foreach ($spaces as $key => $space) { + if ($space->getIsArchived()) { + unset($spaces[$key]); + } + } + + return $spaces; + } + + public static function getSpaceOptionsForViewer( + PhabricatorUser $viewer, + $space_phid) { + + $viewer_spaces = self::getViewerSpaces($viewer); + + $map = array(); + foreach ($viewer_spaces as $space) { + + // Skip archived spaces, unless the object is already in that space. + if ($space->getIsArchived()) { + if ($space->getPHID() != $space_phid) { + continue; + } + } + + $map[$space->getPHID()] = pht( + 'Space %s: %s', + $space->getMonogram(), + $space->getNamespaceName()); + } + asort($map); + + return $map; + } + + /** * Get the Space PHID for an object, if one exists. * diff --git a/src/applications/spaces/query/PhabricatorSpacesNamespaceSearchEngine.php b/src/applications/spaces/query/PhabricatorSpacesNamespaceSearchEngine.php index 9b4014c3dd..6a7ea7ca4a 100644 --- a/src/applications/spaces/query/PhabricatorSpacesNamespaceSearchEngine.php +++ b/src/applications/spaces/query/PhabricatorSpacesNamespaceSearchEngine.php @@ -11,28 +11,39 @@ final class PhabricatorSpacesNamespaceSearchEngine return pht('Spaces'); } - public function buildSavedQueryFromRequest(AphrontRequest $request) { - $saved = new PhabricatorSavedQuery(); - - return $saved; + public function newQuery() { + return new PhabricatorSpacesNamespaceQuery(); } - public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { - $query = id(new PhabricatorSpacesNamespaceQuery()); + protected function buildCustomSearchFields() { + return array( + id(new PhabricatorSearchThreeStateField()) + ->setLabel(pht('Active')) + ->setKey('active') + ->setOptions( + pht('(Show All)'), + pht('Show Only Active Spaces'), + pht('Hide Active Spaces')), + ); + } + + protected function buildQueryFromParameters(array $map) { + $query = $this->newQuery(); + + if ($map['active']) { + $query->withIsArchived(!$map['active']); + } return $query; } - public function buildSearchForm( - AphrontFormView $form, - PhabricatorSavedQuery $saved_query) {} - protected function getURI($path) { return '/spaces/'.$path; } protected function getBuiltinQueryNames() { $names = array( + 'active' => pht('Active Spaces'), 'all' => pht('All Spaces'), ); @@ -40,11 +51,12 @@ final class PhabricatorSpacesNamespaceSearchEngine } public function buildSavedQueryFromBuiltin($query_key) { - $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { + case 'active': + return $query->setParameter('active', true); case 'all': return $query; } @@ -72,6 +84,10 @@ final class PhabricatorSpacesNamespaceSearchEngine $item->addIcon('fa-certificate', pht('Default Space')); } + if ($space->getIsArchived()) { + $item->setDisabled(true); + } + $list->addItem($item); } diff --git a/src/applications/spaces/storage/PhabricatorSpacesNamespace.php b/src/applications/spaces/storage/PhabricatorSpacesNamespace.php index 8271f536cb..f728d22dfa 100644 --- a/src/applications/spaces/storage/PhabricatorSpacesNamespace.php +++ b/src/applications/spaces/storage/PhabricatorSpacesNamespace.php @@ -11,6 +11,8 @@ final class PhabricatorSpacesNamespace protected $viewPolicy; protected $editPolicy; protected $isDefaultNamespace; + protected $description; + protected $isArchived; public static function initializeNewNamespace(PhabricatorUser $actor) { $app = id(new PhabricatorApplicationQuery()) @@ -26,7 +28,9 @@ final class PhabricatorSpacesNamespace return id(new PhabricatorSpacesNamespace()) ->setIsDefaultNamespace(null) ->setViewPolicy($view_policy) - ->setEditPolicy($edit_policy); + ->setEditPolicy($edit_policy) + ->setDescription('') + ->setIsArchived(0); } protected function getConfiguration() { @@ -35,6 +39,8 @@ final class PhabricatorSpacesNamespace self::CONFIG_COLUMN_SCHEMA => array( 'namespaceName' => 'text255', 'isDefaultNamespace' => 'bool?', + 'description' => 'text', + 'isArchived' => 'bool', ), self::CONFIG_KEY_SCHEMA => array( 'key_default' => array( diff --git a/src/applications/spaces/storage/PhabricatorSpacesNamespaceTransaction.php b/src/applications/spaces/storage/PhabricatorSpacesNamespaceTransaction.php index 672cb9d8ad..4c438537f1 100644 --- a/src/applications/spaces/storage/PhabricatorSpacesNamespaceTransaction.php +++ b/src/applications/spaces/storage/PhabricatorSpacesNamespaceTransaction.php @@ -5,6 +5,8 @@ final class PhabricatorSpacesNamespaceTransaction const TYPE_NAME = 'spaces:name'; const TYPE_DEFAULT = 'spaces:default'; + const TYPE_DESCRIPTION = 'spaces:description'; + const TYPE_ARCHIVE = 'spaces:archive'; public function getApplicationName() { return 'spaces'; @@ -18,6 +20,38 @@ final class PhabricatorSpacesNamespaceTransaction return null; } + public function shouldHide() { + $old = $this->getOldValue(); + + switch ($this->getTransactionType()) { + case self::TYPE_DESCRIPTION: + return ($old === null); + } + + return parent::shouldHide(); + } + + public function hasChangeDetails() { + switch ($this->getTransactionType()) { + case self::TYPE_DESCRIPTION: + return true; + } + + return parent::hasChangeDetails(); + } + + public function getRemarkupBlocks() { + $blocks = parent::getRemarkupBlocks(); + + switch ($this->getTransactionType()) { + case self::TYPE_DESCRIPTION: + $blocks[] = $this->getNewValue(); + break; + } + + return $blocks; + } + public function getTitle() { $old = $this->getOldValue(); $new = $this->getNewValue(); @@ -37,10 +71,24 @@ final class PhabricatorSpacesNamespaceTransaction $old, $new); } + case self::TYPE_DESCRIPTION: + return pht( + '%s updated the description for this space.', + $this->renderHandleLink($author_phid)); case self::TYPE_DEFAULT: return pht( '%s made this the default space.', $this->renderHandleLink($author_phid)); + case self::TYPE_ARCHIVE: + if ($new) { + return pht( + '%s archived this space.', + $this->renderHandleLink($author_phid)); + } else { + return pht( + '%s activated this space.', + $this->renderHandleLink($author_phid)); + } } return parent::getTitle(); diff --git a/src/applications/spaces/storage/PhabricatorSpacesSchemaSpec.php b/src/applications/spaces/storage/PhabricatorSpacesSchemaSpec.php new file mode 100644 index 0000000000..d69772ef7c --- /dev/null +++ b/src/applications/spaces/storage/PhabricatorSpacesSchemaSpec.php @@ -0,0 +1,10 @@ +buildEdgeSchemata(new PhabricatorSpacesNamespace()); + } + +} diff --git a/src/applications/spaces/typeahead/PhabricatorSpacesNamespaceDatasource.php b/src/applications/spaces/typeahead/PhabricatorSpacesNamespaceDatasource.php index 046e3b0f4f..25951b53af 100644 --- a/src/applications/spaces/typeahead/PhabricatorSpacesNamespaceDatasource.php +++ b/src/applications/spaces/typeahead/PhabricatorSpacesNamespaceDatasource.php @@ -21,9 +21,20 @@ final class PhabricatorSpacesNamespaceDatasource $spaces = $this->executeQuery($query); $results = array(); foreach ($spaces as $space) { - $results[] = id(new PhabricatorTypeaheadResult()) - ->setName($space->getNamespaceName()) + $full_name = pht( + '%s %s', + $space->getMonogram(), + $space->getNamespaceName()); + + $result = id(new PhabricatorTypeaheadResult()) + ->setName($full_name) ->setPHID($space->getPHID()); + + if ($space->getIsArchived()) { + $result->setClosed(pht('Archived')); + } + + $results[] = $result; } return $this->filterResultsAgainstTokens($results); diff --git a/src/applications/spaces/view/PHUISpacesNamespaceContextView.php b/src/applications/spaces/view/PHUISpacesNamespaceContextView.php index ed28f53349..0bb5949b76 100644 --- a/src/applications/spaces/view/PHUISpacesNamespaceContextView.php +++ b/src/applications/spaces/view/PHUISpacesNamespaceContextView.php @@ -21,14 +21,27 @@ final class PHUISpacesNamespaceContextView extends AphrontView { return null; } + // If the viewer can't see spaces, pretend they don't exist. $viewer = $this->getUser(); + if (!PhabricatorSpacesNamespaceQuery::getViewerSpacesExist($viewer)) { + return null; + } + + // If this is the default space, don't show a space label. + $default = PhabricatorSpacesNamespaceQuery::getDefaultSpace(); + if ($default) { + if ($default->getPHID() == $space_phid) { + return null; + } + } + return phutil_tag( 'span', array( 'class' => 'spaces-name', ), array( - $viewer->renderHandle($space_phid), + $viewer->renderHandle($space_phid)->setUseShortName(true), ' | ', )); } diff --git a/src/applications/spaces/view/PhabricatorSpacesControl.php b/src/applications/spaces/view/PhabricatorSpacesControl.php deleted file mode 100644 index aa40238c56..0000000000 --- a/src/applications/spaces/view/PhabricatorSpacesControl.php +++ /dev/null @@ -1,49 +0,0 @@ -object = $object; - return $this; - } - - protected function getCustomControlClass() { - return ''; - } - - protected function getOptions() { - $viewer = $this->getUser(); - $viewer_spaces = PhabricatorSpacesNamespaceQuery::getViewerSpaces($viewer); - - $map = mpull($viewer_spaces, 'getNamespaceName', 'getPHID'); - asort($map); - - return $map; - } - - protected function renderInput() { - $viewer = $this->getUser(); - - $this->setLabel(pht('Space')); - - $value = $this->getValue(); - if ($value === null) { - $value = $viewer->getDefaultSpacePHID(); - } - - return AphrontFormSelectControl::renderSelectTag( - $value, - $this->getOptions(), - array( - 'name' => $this->getName(), - )); - } - -} diff --git a/src/applications/subscriptions/policyrule/PhabricatorSubscriptionsSubscribersPolicyRule.php b/src/applications/subscriptions/policyrule/PhabricatorSubscriptionsSubscribersPolicyRule.php new file mode 100644 index 0000000000..7da35f3703 --- /dev/null +++ b/src/applications/subscriptions/policyrule/PhabricatorSubscriptionsSubscribersPolicyRule.php @@ -0,0 +1,121 @@ +getPHID(); + if (!$viewer_phid) { + return; + } + + if (empty($this->subscribed[$viewer_phid])) { + $this->subscribed[$viewer_phid] = array(); + } + + // Load the project PHIDs the user is a member of. + if (!isset($this->sourcePHIDs[$viewer_phid])) { + $source_phids = PhabricatorEdgeQuery::loadDestinationPHIDs( + $viewer_phid, + PhabricatorProjectMemberOfProjectEdgeType::EDGECONST); + $source_phids[] = $viewer_phid; + $this->sourcePHIDs[$viewer_phid] = $source_phids; + } + + // Look for transaction hints. + foreach ($objects as $key => $object) { + $cache = $this->getTransactionHint($object); + if ($cache === null) { + // We don't have a hint for this object, so we'll deal with it below. + continue; + } + + // We have a hint, so use that as the source of truth. + unset($objects[$key]); + + foreach ($this->sourcePHIDs[$viewer_phid] as $source_phid) { + if (isset($cache[$source_phid])) { + $this->subscribed[$viewer_phid][$object->getPHID()] = true; + break; + } + } + } + + $phids = mpull($objects, 'getPHID'); + if (!$phids) { + return; + } + + $edge_query = id(new PhabricatorEdgeQuery()) + ->withSourcePHIDs($this->sourcePHIDs[$viewer_phid]) + ->withEdgeTypes( + array( + PhabricatorSubscribedToObjectEdgeType::EDGECONST, + )) + ->withDestinationPHIDs($phids); + + $edge_query->execute(); + + $subscribed = $edge_query->getDestinationPHIDs(); + if (!$subscribed) { + return; + } + + $this->subscribed[$viewer_phid] += array_fill_keys($subscribed, true); + } + + public function applyRule( + PhabricatorUser $viewer, + $value, + PhabricatorPolicyInterface $object) { + + $viewer_phid = $viewer->getPHID(); + if (!$viewer_phid) { + return false; + } + + if ($object->isAutomaticallySubscribed($viewer_phid)) { + return true; + } + + $subscribed = idx($this->subscribed, $viewer_phid); + return isset($subscribed[$object->getPHID()]); + } + + public function getValueControlType() { + return self::CONTROL_TYPE_NONE; + } + +} diff --git a/src/applications/subscriptions/view/SubscriptionListDialogBuilder.php b/src/applications/subscriptions/view/SubscriptionListDialogBuilder.php index 67e013d9c2..a4d382e170 100644 --- a/src/applications/subscriptions/view/SubscriptionListDialogBuilder.php +++ b/src/applications/subscriptions/view/SubscriptionListDialogBuilder.php @@ -1,6 +1,6 @@ getPHID(); } } + return $space_phid; case PhabricatorTransactions::TYPE_EDGE: $edge_type = $xaction->getMetadataValue('edge:type'); @@ -360,10 +361,13 @@ abstract class PhabricatorApplicationTransactionEditor case PhabricatorTransactions::TYPE_SPACE: $space_phid = $xaction->getNewValue(); if (!strlen($space_phid)) { - // If an install has no Spaces, we might end up with the empty string - // here instead of a strict `null`. Just make this work like callers - // might reasonably expect. - return null; + // If an install has no Spaces or the Spaces controls are not visible + // to the viewer, we might end up with the empty string here instead + // of a strict `null`, because some controller just used `getStr()` + // to read the space PHID from the request. + // Just make this work like callers might reasonably expect so we + // don't need to handle this specially in every EditController. + return $this->getActor()->getDefaultSpacePHID(); } else { return $space_phid; } @@ -840,6 +844,11 @@ abstract class PhabricatorApplicationTransactionEditor $object->save(); } catch (AphrontDuplicateKeyQueryException $ex) { $object->killTransaction(); + + // This callback has an opportunity to throw a better exception, + // so execution may end here. + $this->didCatchDuplicateKeyException($object, $xactions, $ex); + throw $ex; } @@ -933,14 +942,16 @@ abstract class PhabricatorApplicationTransactionEditor $object, $herald_xactions); - $adapter = $this->getHeraldAdapter(); - $this->heraldEmailPHIDs = $adapter->getEmailPHIDs(); - $this->heraldForcedEmailPHIDs = $adapter->getForcedEmailPHIDs(); - // Merge the new transactions into the transaction list: we want to // send email and publish feed stories about them, too. $xactions = array_merge($xactions, $herald_xactions); } + + // If Herald did not generate transactions, we may still need to handle + // "Send an Email" rules. + $adapter = $this->getHeraldAdapter(); + $this->heraldEmailPHIDs = $adapter->getEmailPHIDs(); + $this->heraldForcedEmailPHIDs = $adapter->getForcedEmailPHIDs(); } $this->didApplyTransactions($xactions); @@ -1015,6 +1026,13 @@ abstract class PhabricatorApplicationTransactionEditor return $xactions; } + protected function didCatchDuplicateKeyException( + PhabricatorLiskDAO $object, + array $xactions, + Exception $ex) { + return; + } + public function publishTransactions( PhabricatorLiskDAO $object, array $xactions) { @@ -2002,14 +2020,17 @@ abstract class PhabricatorApplicationTransactionEditor $transaction_type) { $errors = array(); - $all_spaces = PhabricatorSpacesNamespaceQuery::getAllSpaces(); - $viewer_spaces = PhabricatorSpacesNamespaceQuery::getViewerSpaces( - $this->getActor()); + $actor = $this->getActor(); + + $has_spaces = PhabricatorSpacesNamespaceQuery::getViewerSpacesExist($actor); + $actor_spaces = PhabricatorSpacesNamespaceQuery::getViewerSpaces($actor); + $active_spaces = PhabricatorSpacesNamespaceQuery::getViewerActiveSpaces( + $actor); foreach ($xactions as $xaction) { $space_phid = $xaction->getNewValue(); if ($space_phid === null) { - if (!$all_spaces) { + if (!$has_spaces) { // The install doesn't have any spaces, so this is fine. continue; } @@ -2026,7 +2047,7 @@ abstract class PhabricatorApplicationTransactionEditor // If the PHID isn't `null`, it needs to be a valid space that the // viewer can see. - if (empty($viewer_spaces[$space_phid])) { + if (empty($actor_spaces[$space_phid])) { $errors[] = new PhabricatorApplicationTransactionValidationError( $transaction_type, pht('Invalid'), @@ -2034,6 +2055,23 @@ abstract class PhabricatorApplicationTransactionEditor 'You can not shift this object in the selected space, because '. 'the space does not exist or you do not have access to it.'), $xaction); + } else if (empty($active_spaces[$space_phid])) { + + // It's OK to edit objects in an archived space, so just move on if + // we aren't adjusting the value. + $old_space_phid = $this->getTransactionOldValue($object, $xaction); + if ($space_phid == $old_space_phid) { + continue; + } + + $errors[] = new PhabricatorApplicationTransactionValidationError( + $transaction_type, + pht('Archived'), + pht( + 'You can not shift this object into the selected space, because '. + 'the space is archived. Objects can not be created inside (or '. + 'moved into) archived spaces.'), + $xaction); } } @@ -2045,7 +2083,31 @@ abstract class PhabricatorApplicationTransactionEditor PhabricatorLiskDAO $object, array $xactions) { - return clone $object; + $copy = clone $object; + + foreach ($xactions as $xaction) { + switch ($xaction->getTransactionType()) { + case PhabricatorTransactions::TYPE_SUBSCRIBERS: + $clone_xaction = clone $xaction; + $clone_xaction->setOldValue(array_values($this->subscribers)); + $clone_xaction->setNewValue( + $this->getPHIDTransactionNewValue( + $clone_xaction)); + + PhabricatorPolicyRule::passTransactionHintToRule( + $copy, + new PhabricatorSubscriptionsSubscribersPolicyRule(), + array_fuse($clone_xaction->getNewValue())); + + break; + case PhabricatorTransactions::TYPE_SPACE: + $space_phid = $this->getTransactionNewValue($object, $xaction); + $copy->setSpacePHID($space_phid); + break; + } + } + + return $copy; } protected function validateAllTransactions( diff --git a/src/applications/transactions/replyhandler/PhabricatorApplicationTransactionReplyHandler.php b/src/applications/transactions/replyhandler/PhabricatorApplicationTransactionReplyHandler.php index 14e27edc73..82f3eca2cc 100644 --- a/src/applications/transactions/replyhandler/PhabricatorApplicationTransactionReplyHandler.php +++ b/src/applications/transactions/replyhandler/PhabricatorApplicationTransactionReplyHandler.php @@ -56,6 +56,22 @@ abstract class PhabricatorApplicationTransactionReplyHandler final protected function receiveEmail(PhabricatorMetaMTAReceivedMail $mail) { $viewer = $this->getActor(); $object = $this->getMailReceiver(); + $app_email = $this->getApplicationEmail(); + + $is_new = !$object->getID(); + + // If this is a new object which implements the Spaces interface and was + // created by sending mail to an ApplicationEmail address, put the object + // in the same Space the address is in. + if ($is_new) { + if ($object instanceof PhabricatorSpacesInterface) { + if ($app_email) { + $space_phid = PhabricatorSpacesNamespaceQuery::getObjectSpacePHID( + $app_email); + $object->setSpacePHID($space_phid); + } + } + } $body_data = $mail->parseBody(); $body = $body_data['body']; diff --git a/src/applications/transactions/storage/PhabricatorApplicationTransaction.php b/src/applications/transactions/storage/PhabricatorApplicationTransaction.php index 7439c8728e..e8811da760 100644 --- a/src/applications/transactions/storage/PhabricatorApplicationTransaction.php +++ b/src/applications/transactions/storage/PhabricatorApplicationTransaction.php @@ -243,10 +243,10 @@ abstract class PhabricatorApplicationTransaction case PhabricatorTransactions::TYPE_EDIT_POLICY: case PhabricatorTransactions::TYPE_VIEW_POLICY: case PhabricatorTransactions::TYPE_JOIN_POLICY: - if (!PhabricatorPolicyQuery::isGlobalPolicy($old)) { + if (!PhabricatorPolicyQuery::isSpecialPolicy($old)) { $phids[] = array($old); } - if (!PhabricatorPolicyQuery::isGlobalPolicy($new)) { + if (!PhabricatorPolicyQuery::isSpecialPolicy($new)) { $phids[] = array($new); } break; diff --git a/src/applications/typeahead/storage/PhabricatorTypeaheadResult.php b/src/applications/typeahead/storage/PhabricatorTypeaheadResult.php index 516617093f..6ef913fc5a 100644 --- a/src/applications/typeahead/storage/PhabricatorTypeaheadResult.php +++ b/src/applications/typeahead/storage/PhabricatorTypeaheadResult.php @@ -1,6 +1,6 @@ view) { case 'sampled': - $clause = '`sampleRate` > 0'; + $clause = 'sampleRate > 0'; $show_type = false; break; case 'my-runs': $clause = qsprintf( id(new PhabricatorXHProfSample())->establishConnection('r'), - '`sampleRate` = 0 AND `userPHID` = %s', + 'sampleRate = 0 AND userPHID = %s', $request->getUser()->getPHID()); $show_type = false; break; case 'manual': - $clause = '`sampleRate` = 0'; + $clause = 'sampleRate = 0'; $show_type = false; break; case 'all': diff --git a/src/docs/contributor/css_coding_standards.diviner b/src/docs/contributor/css_coding_standards.diviner index 795d0952f6..c321124eae 100644 --- a/src/docs/contributor/css_coding_standards.diviner +++ b/src/docs/contributor/css_coding_standards.diviner @@ -22,6 +22,7 @@ Great Z-Index War where all indexes grow without bound in an endless arms race. Phabricator's preprocessor provides some standard color variables. You can reference these with `{$color}`. For example: + lang=css span.critical { color: {$red}; } @@ -78,6 +79,7 @@ adjust behavior responsively. In particular: Since many rules are specific to handheld devices, the `.device` class selects either tablets or phones: + lang=css .device { /* Phone or tablet (not desktop). */ } diff --git a/src/docs/contributor/php_coding_standards.diviner b/src/docs/contributor/php_coding_standards.diviner index 03f0bc158b..ff62ebe98e 100644 --- a/src/docs/contributor/php_coding_standards.diviner +++ b/src/docs/contributor/php_coding_standards.diviner @@ -67,6 +67,7 @@ guidelines, you probably don't need to read this super thoroughly. **if/else:** + lang=php if ($some_variable > 3) { // ... } else if ($some_variable === null) { @@ -81,6 +82,7 @@ use the "endif" construct, and write "else if" as two words. **for:** + lang=php for ($ii = 0; $ii < 10; $ii++) { // ... } @@ -90,12 +92,14 @@ visually and react better to "Find Next..." in editors. **foreach:** + lang=php foreach ($map as $key => $value) { // ... } **switch:** + lang=php switch ($value) { case 1: // ... @@ -115,6 +119,7 @@ visually and react better to "Find Next..." in editors. **array literals:** + lang=php $junk = array( 'nuts', 'bolts', @@ -126,6 +131,7 @@ diffs which add elements to the array affect only one line. **operators:** + lang=php $a + $b; // Put spaces around operators. $omg.$lol; // Exception: no spaces around string concatenation. $arr[] = $element; // Couple [] with the array when appending. @@ -133,6 +139,7 @@ diffs which add elements to the array affect only one line. **function/method calls:** + lang=php // One line eject($cargo); @@ -143,6 +150,7 @@ diffs which add elements to the array affect only one line. **function/method definitions:** + lang=php function example_function($base_value, $additional_value) { return $base_value + $additional_value; } @@ -157,6 +165,7 @@ diffs which add elements to the array affect only one line. **class:** + lang=php class Dog extends Animal { const CIRCLES_REQUIRED_TO_LIE_DOWN = 3; diff --git a/src/docs/contributor/using_oauthserver.diviner b/src/docs/contributor/using_oauthserver.diviner index ff6f33a0c1..b09f595a5a 100644 --- a/src/docs/contributor/using_oauthserver.diviner +++ b/src/docs/contributor/using_oauthserver.diviner @@ -35,13 +35,13 @@ clients that implement OAuth 2.0. = Setup - Creating a Client = -# Visit https://phabricator.example.com/oauthserver/client/create/ +# Visit {nav Your Local Install > OAuth Server > Create Application} # Fill out the form # Profit = Obtaining an Authorization Code = -POST or GET https://phabricator.example.com/oauthserver/auth/ with the +POST or GET `https://phabricator.example.com/oauthserver/auth/` with the following parameters: - Required - **client_id** - the id of the newly registered client. @@ -76,7 +76,7 @@ and include the pertinent error information. = Obtaining an Access Token = -POST or GET https://phabricator.example.com/oauthserver/token/ +POST or GET `https://phabricator.example.com/oauthserver/token/` with the following parameters: - Required - **client_id** - the id of the client @@ -101,7 +101,7 @@ message. Simply include a query param with the key of "access_token" and the value as the earlier obtained access token. For example: -https://phabricator.example.com/api/user.whoami?access_token=ykc7ly7vtibj334oga4fnfbuvnwz4ocp +```https://phabricator.example.com/api/user.whoami?access_token=ykc7ly7vtibj334oga4fnfbuvnwz4ocp``` If the token has expired or is otherwise invalid, the client will receive an error indicating as such. In these cases, the client should re-initiate diff --git a/src/docs/flavor/php_pitfalls.diviner b/src/docs/flavor/php_pitfalls.diviner index 09e0f108f0..0ffcaa42da 100644 --- a/src/docs/flavor/php_pitfalls.diviner +++ b/src/docs/flavor/php_pitfalls.diviner @@ -4,11 +4,11 @@ This document discusses difficult traps and pitfalls in PHP, and how to avoid, work around, or at least understand them. -= array_merge() in Incredibly Slow When Merging A List of Arrays = += `array_merge()` in Incredibly Slow When Merging A List of Arrays = If you merge a list of arrays like this: - COUNTEREXAMPLE + COUNTEREXAMPLE, lang=php $result = array(); foreach ($list_of_lists as $one_list) { $result = array_merge($result, $one_list); @@ -21,18 +21,19 @@ you iterate. In a libphutil environment, you can use @{function@libphutil:array_mergev} instead. -= var_export() Hates Baby Animals = += `var_export()` Hates Baby Animals = -If you try to var_export() an object that contains recursive references, your +If you try to `var_export()` an object that contains recursive references, your program will terminate. You have no chance to intercept or react to this or -otherwise stop it from happening. Avoid var_export() unless you are certain -you have only simple data. You can use print_r() or var_dump() to display +otherwise stop it from happening. Avoid `var_export()` unless you are certain +you have only simple data. You can use `print_r()` or `var_dump()` to display complex variables safely. -= isset(), empty() and Truthiness = += `isset()`, `empty()` and Truthiness = A value is "truthy" if it evaluates to true in an `if` clause: + lang=php $value = something(); if ($value) { // Value is truthy. @@ -59,16 +60,16 @@ empty comments) is wrong in PHP: This is wrong because it prevents users from making the comment "0". //THIS COMMENT IS TOTALLY AWESOME AND I MAKE IT ALL THE TIME SO YOU HAD BETTER NOT -BREAK IT!!!// A better test is probably strlen(). +BREAK IT!!!// A better test is probably `strlen()`. In addition to truth tests with `if`, PHP has two special truthiness operators -which look like functions but aren't: empty() and isset(). These operators help -deal with undeclared variables. +which look like functions but aren't: `empty()` and `isset()`. These operators +help deal with undeclared variables. In PHP, there are two major cases where you get undeclared variables -- either you directly use a variable without declaring it: - COUNTEREXAMPLE + COUNTEREXAMPLE, lang=php function f() { if ($not_declared) { // ... @@ -84,218 +85,245 @@ you directly use a variable without declaring it: } } -When you do either of these, PHP issues a warning. Avoid these warnings by using -empty() and isset() to do tests that are safe to apply to undeclared variables. +When you do either of these, PHP issues a warning. Avoid these warnings by +using `empty()` and `isset()` to do tests that are safe to apply to undeclared +variables. -empty() evaluates truthiness exactly opposite of if(). isset() returns true for -everything except null. This is the truth table: +`empty()` evaluates truthiness exactly opposite of `if()`. `isset()` returns +`true` for everything except `null`. This is the truth table: - VALUE if() empty() isset() +| Value | `if()` | `empty()` | `isset()` | +|-------|--------|-----------|-----------| +| `null` | `false` | `true` | `false` | +| `0` | `false` | `true` | `true` | +| `0.0` | `false` | `true` | `true` | +| `"0"` | `false` | `true` | `true` | +| `""` | `false` | `true` | `true` | +| `false` | `false` | `true` | `true` | +| `array()` | `false` | `true` | `true` | +| Everything else | `true` | `false` | `true` | - null false true false - 0 false true true - 0.0 false true true - "0" false true true - "" false true true - false false true true - array() false true true - EVERYTHING ELSE true false true +The value of these operators is that they accept undeclared variables and do +not issue a warning. Specifically, if you try to do this you get a warning: -The value of these operators is that they accept undeclared variables and do not -issue a warning. Specifically, if you try to do this you get a warning: - - COUNTEREXAMPLE - if ($not_previously_declared) { // PHP Notice: Undefined variable! - // ... - } +```lang=php, COUNTEREXAMPLE +if ($not_previously_declared) { // PHP Notice: Undefined variable! + // ... +} +``` But these are fine: - if (empty($not_previously_declared)) { // No notice, returns true. - // ... - } - if (isset($not_previously_declared)) { // No notice, returns false. - // ... - } +```lang=php +if (empty($not_previously_declared)) { // No notice, returns true. + // ... +} +if (isset($not_previously_declared)) { // No notice, returns false. + // ... +} +``` -So, isset() really means is_declared_and_is_set_to_something_other_than_null(). -empty() really means is_falsey_or_is_not_declared(). Thus: +So, `isset()` really means +`is_declared_and_is_set_to_something_other_than_null()`. `empty()` really means +`is_falsey_or_is_not_declared()`. Thus: - - If a variable is known to exist, test falsiness with if (!$v), not empty(). - In particular, test for empty arrays with if (!$array). There is no reason - to ever use empty() on a declared variable. - - When you use isset() on an array key, like isset($array['key']), it will - evaluate to "false" if the key exists but has the value null! Test for index - existence with array_key_exists(). + - If a variable is known to exist, test falsiness with `if (!$v)`, not + `empty()`. In particular, test for empty arrays with `if (!$array)`. There + is no reason to ever use `empty()` on a declared variable. + - When you use `isset()` on an array key, like `isset($array['key'])`, it + will evaluate to "false" if the key exists but has the value `null`! Test + for index existence with `array_key_exists()`. -Put another way, use isset() if you want to type "if ($value !== null)" but are -testing something that may not be declared. Use empty() if you want to type -"if (!$value)" but you are testing something that may not be declared. +Put another way, use `isset()` if you want to type `if ($value !== null)` but +are testing something that may not be declared. Use `empty()` if you want to +type `if (!$value)` but you are testing something that may not be declared. = usort(), uksort(), and uasort() are Slow = This family of functions is often extremely slow for large datasets. You should avoid them if at all possible. Instead, build an array which contains surrogate keys that are naturally sortable with a function that uses native comparison -(e.g., sort(), asort(), ksort(), or natcasesort()). Sort this array instead, and -use it to reorder the original array. +(e.g., `sort()`, `asort()`, `ksort()`, or `natcasesort()`). Sort this array +instead, and use it to reorder the original array. In a libphutil environment, you can often do this easily with @{function@libphutil:isort} or @{function@libphutil:msort}. -= array_intersect() and array_diff() are Also Slow = += `array_intersect()` and `array_diff()` are Also Slow = These functions are much slower for even moderately large inputs than -array_intersect_key() and array_diff_key(), because they can not make the +`array_intersect_key()` and `array_diff_key()`, because they can not make the assumption that their inputs are unique scalars as the `key` varieties can. Strongly prefer the `key` varieties. -= array_uintersect() and array_udiff() are Definitely Slow Too = += `array_uintersect()` and `array_udiff()` are Definitely Slow Too = These functions have the problems of both the `usort()` family and the `array_diff()` family. Avoid them. -= foreach() Does Not Create Scope = += `foreach()` Does Not Create Scope = -Variables survive outside of the scope of foreach(). More problematically, -references survive outside of the scope of foreach(). This code mutates +Variables survive outside of the scope of `foreach()`. More problematically, +references survive outside of the scope of `foreach()`. This code mutates `$array` because the reference leaks from the first loop to the second: - COUNTEREXAMPLE - $array = range(1, 3); - echo implode(',', $array); // Outputs '1,2,3' - foreach ($array as &$value) {} - echo implode(',', $array); // Outputs '1,2,3' - foreach ($array as $value) {} - echo implode(',', $array); // Outputs '1,2,2' +```lang=php, COUNTEREXAMPLE +$array = range(1, 3); +echo implode(',', $array); // Outputs '1,2,3' +foreach ($array as &$value) {} +echo implode(',', $array); // Outputs '1,2,3' +foreach ($array as $value) {} +echo implode(',', $array); // Outputs '1,2,2' +``` The easiest way to avoid this is to avoid using foreach-by-reference. If you do use it, unset the reference after the loop: - foreach ($array as &$value) { - // ... - } - unset($value); +```lang=php +foreach ($array as &$value) { + // ... +} +unset($value); +``` -= unserialize() is Incredibly Slow on Large Datasets = += `unserialize()` is Incredibly Slow on Large Datasets = -The performance of unserialize() is nonlinear in the number of zvals you -unserialize, roughly O(N^2). +The performance of `unserialize()` is nonlinear in the number of zvals you +unserialize, roughly `O(N^2)`. - zvals approximate time - 10000 5ms - 100000 85ms - 1000000 8,000ms - 10000000 72 billion years +| zvals | Approximate time | +|-------|------------------| +| 10000 |5ms | +| 100000 | 85ms | +| 1000000 | 8,000ms | +| 10000000 | 72 billion years | += `call_user_func()` Breaks References = -= call_user_func() Breaks References = - -If you use call_use_func() to invoke a function which takes parameters by +If you use `call_use_func()` to invoke a function which takes parameters by reference, the variables you pass in will have their references broken and will emerge unmodified. That is, if you have a function that takes references: - function add_one(&$v) { - $v++; - } +```lang=php +function add_one(&$v) { + $v++; +} +``` -...and you call it with call_user_func(): +...and you call it with `call_user_func()`: - COUNTEREXAMPLE - $x = 41; - call_user_func('add_one', $x); +```lang=php, COUNTEREXAMPLE +$x = 41; +call_user_func('add_one', $x); +``` -...`$x` will not be modified. The solution is to use call_user_func_array() +...`$x` will not be modified. The solution is to use `call_user_func_array()` and wrap the reference in an array: - $x = 41; - call_user_func_array( - 'add_one', - array(&$x)); // Note '&$x'! +```lang=php +$x = 41; +call_user_func_array( + 'add_one', + array(&$x)); // Note '&$x'! +``` This will work as expected. -= You Can't Throw From __toString() = += You Can't Throw From `__toString()` = -If you throw from __toString(), your program will terminate uselessly and you +If you throw from `__toString()`, your program will terminate uselessly and you won't get the exception. = An Object Can Have Any Scalar as a Property = Object properties are not limited to legal variable names: - $property = '!@#$%^&*()'; - $obj->$property = 'zebra'; - echo $obj->$property; // Outputs 'zebra'. +```lang=php +$property = '!@#$%^&*()'; +$obj->$property = 'zebra'; +echo $obj->$property; // Outputs 'zebra'. +``` So, don't make assumptions about property names. -= There is an (object) Cast = += There is an `(object)` Cast = You can cast a dictionary into an object. - $obj = (object)array('flavor' => 'coconut'); - echo $obj->flavor; // Outputs 'coconut'. - echo get_class($obj); // Outputs 'stdClass'. +```lang=php +$obj = (object)array('flavor' => 'coconut'); +echo $obj->flavor; // Outputs 'coconut'. +echo get_class($obj); // Outputs 'stdClass'. +``` This is occasionally useful, mostly to force an object to become a Javascript -dictionary (vs a list) when passed to json_encode(). +dictionary (vs a list) when passed to `json_encode()`. -= Invoking "new" With an Argument Vector is Really Hard = += Invoking `new` With an Argument Vector is Really Hard = -If you have some `$class_name` and some `$argv` of constructor -arguments and you want to do this: +If you have some `$class_name` and some `$argv` of constructor arguments +and you want to do this: - new $class_name($argv[0], $argv[1], ...); +```lang=php +new $class_name($argv[0], $argv[1], ...); +``` ...you'll probably invent a very interesting, very novel solution that is very wrong. In a libphutil environment, solve this problem with -@{function@libphutil:newv}. Elsewhere, copy newv()'s implementation. +@{function@libphutil:newv}. Elsewhere, copy `newv()`'s implementation. = Equality is not Transitive = This isn't terribly surprising since equality isn't transitive in a lot of -languages, but the == operator is not transitive: +languages, but the `==` operator is not transitive: - $a = ''; $b = 0; $c = '0a'; - $a == $b; // true - $b == $c; // true - $c == $a; // false! +```lang=php +$a = ''; $b = 0; $c = '0a'; +$a == $b; // true +$b == $c; // true +$c == $a; // false! +``` When either operand is an integer, the other operand is cast to an integer -before comparison. Avoid this and similar pitfalls by using the === operator, +before comparison. Avoid this and similar pitfalls by using the `===` operator, which is transitive. = All 676 Letters in the Alphabet = This doesn't do what you'd expect it to do in C: - for ($c = 'a'; $c <= 'z'; $c++) { - // ... - } +```lang=php +for ($c = 'a'; $c <= 'z'; $c++) { + // ... +} +``` -This is because the successor to 'z' is 'aa', which is "less than" 'z'. The -loop will run for ~700 iterations until it reaches 'zz' and terminates. That is, -`$c` will take on these values: +This is because the successor to `z` is `aa`, which is "less than" `z`. +The loop will run for ~700 iterations until it reaches `zz` and terminates. +That is, `$c` will take on these values: - a - b - ... - y - z - aa // loop continues because 'aa' <= 'z' - ab - ... - mf - mg - ... - zw - zx - zy - zz // loop now terminates because 'zz' > 'z' +``` +a +b +... +y +z +aa // loop continues because 'aa' <= 'z' +ab +... +mf +mg +... +zw +zx +zy +zz // loop now terminates because 'zz' > 'z' +``` Instead, use this loop: - foreach (range('a', 'z') as $c) { - // ... - } +```lang=php +foreach (range('a', 'z') as $c) { + // ... +} +``` diff --git a/src/docs/user/userguide/spaces.diviner b/src/docs/user/userguide/spaces.diviner new file mode 100644 index 0000000000..230fa2ddc5 --- /dev/null +++ b/src/docs/user/userguide/spaces.diviner @@ -0,0 +1,169 @@ +@title Spaces User Guide +@group userguide + +Guide to the Spaces application. + +Overview +======== + +IMPORTANT: Spaces is a prototype application. + +The Spaces application makes it easier to manage large groups of objects which +share the same access policy. For example: + + - An organization might make a Space for a project in order to satisfy a + contractual obligation to limit access, even internally. + - An open source organization might make a Space for work related to + internal governance, to separate private and public discussions. + - A contracting company might make Spaces for clients, to separate them from + one another. + - A company might create a Space for consultants, to give them limited + access to only the resources they need to do their work. + - An ambitious manager might create a Space to hide her team's work from her + enemies at the company, that she might use the element of surprise to later + expand her domain. + +Phabricator's access control policies are generally powerful enough to handle +these use cases on their own, but applying the same policy to a large group +of objects requires a lot of effort and is error-prone. + +Spaces build on top of policies and make it easier and more reliable to +configure, review, and manage groups of objects with similar policies. + + +Creating Spaces +================= + +Spaces are optional, and are inactive by default. You don't need to configure +them if you don't plan to use them. You can always set them up later. + +To activate Spaces, you need to create at least two spaces. Create spaces from +the web UI, by navigating to {nav Spaces > Create Space}. By default, only +administrators can create new Spaces, but you can configure this in the +{nav Applications} application. + +The first Space you create will be a special "default" Space, and all existing +objects will be shifted into this space as soon as you create it. Spaces you +create later will be normal spaces, and begin with no objects inside them. + +Create the first space (you may want to name it something like "Default" or +"Global" or "Public", depending on the nature of your organization), then +create a second Space. Usually, the second space will be something like +"Secret Plans" and have a more restrictive "Visible To" policy. + + +Using Spaces +============ + +Once you've created at least two spaces, you can begin using them. + +Application UIs will change for users who can see at least two Spaces, opening +up new controls which let them work with spaces. They will now be able to +choose which space to create new objects into, be able to move objects between +spaces, and be able to search for objects in a specific space or set of spaces. + +In list and detail views, objects will show which space they're in if they're +in a non-default space. + +Users with access to only one space won't see these controls, even if many +spaces exist. This simplifies the UI for users with limited access. + + +Space Policies +============== + +Briefly, Spaces affect policies like this: + + - Spaces apply their view policy to all objects inside the space. + - Space policies are absolute, and stronger than all other policies. A + user who can not see a Space can **never** see objects inside the space. + - Normal policies are still checked: spaces can only reduce access. + +When you create a Space, you choose a view policy for that space by using the +**Visible To** control. This policy controls both who can see the space, and +who can see objects inside the space. + +Spaces apply their view policy to all objects inside the space: if you can't +see a space, you can never see objects inside it. This policy check is absolute +and stronger than all other policy rules, including policy exceptions. + +For example, a user can never see a task in a space they can't see, even if +they are an admin and the author and owner of the task, and subscribed to the +task and the view and edit policies are set to "All Users", and they created +the Space originally and the moon is full and they are pure of heart and +possessed of the noblest purpose. Spaces are impenetrable. + +Even if a user satisfies the view policy for a space, they must still pass the +view policy on the object: the space check is a new check in addition to any +check on the object, and can only limit access. + +The edit policy for a space only affects the Space itself, and is not applied +to objects inside the space. + + +Archiving Spaces +================ + +If you no longer need a Space, you can archive it by choosing +{nav Archive Space} from the detail view. This hides the space and all the +objects in it without deleting any data. + +New objects can't be created into archived spaces, and existing objects can't +be shifted into archived spaces. The UI won't give you options to choose +these spaces when creating or editing objects. + +Additionally, objects (like tasks) in archived spaces won't be shown in most +search result lists by default. If you need to find objects in an archived +space, use the `Spaces` constraint to specifically search for objects in that +space. + +You can reactivate a space later by choosing {nav Activate Space}. + + +Application Email +================= + +After activating Spaces, you can choose a Space when configuring inbound email +addresses in {nav Applications}. + +Spaces affect policies for application email just like they do for other +objects: to see or use the address, you must be able to see the space which +contains it. + +Objects created from inbound email will be created in the Space the email is +associated with. + + +Limitations and Caveats +======================= + +Some information is shared between spaces, so they do not completely isolate +users from other activity on the install. This section discusses limitations +of the isolation model. Most of these limitations are intrinsic to the policy +model Phabricator uses. + +**Shared IDs**: Spaces do not have unique object IDs: there is only one `T1`, +not a separate one in each space. It can be moved between spaces, but `T1` +always refers to the same object. In most cases, this makes working with +spaces simpler and easier. + +However, because IDs are shared, users in any space can look at object IDs to +determine how many objects exist in other spaces, even if they can't see those +objects. If a user creates a new task and sees that it is `T5000`, they can +know that there are 4,999 other tasks they don't have permission to see. + +**Globally Unique Values**: Some values (like usernames, email addresses, +project hashtags, repository callsigns, and application emails) must be +globally unique. + +As with normal policies, users may be able to determine that a `#yolo` project +exists, even if they can't see it: they can try to create a project using the +`#yolo` hashtag, and will receive an error if it is a duplicate. + +**User Accounts**: Spaces do not apply to users, and can not hide the existence +of user accounts. + +For example, if you are a contracting company and have Coke and Pepsi as +clients, the CEO of Coke and the CEO of Pepsi will each be able to see that the +other has an account on the install, even if all the work you are doing for +them is separated into "Coke" and "Pepsi" spaces. diff --git a/src/infrastructure/customfield/field/PhabricatorCustomField.php b/src/infrastructure/customfield/field/PhabricatorCustomField.php index 4b0f68e93a..f9f5979029 100644 --- a/src/infrastructure/customfield/field/PhabricatorCustomField.php +++ b/src/infrastructure/customfield/field/PhabricatorCustomField.php @@ -16,7 +16,7 @@ * @task globalsearch Integration with Global Search * @task herald Integration with Herald */ -abstract class PhabricatorCustomField { +abstract class PhabricatorCustomField extends Phobject { private $viewer; private $object; diff --git a/src/infrastructure/customfield/field/PhabricatorCustomFieldAttachment.php b/src/infrastructure/customfield/field/PhabricatorCustomFieldAttachment.php index 068763527b..31813c0c32 100644 --- a/src/infrastructure/customfield/field/PhabricatorCustomFieldAttachment.php +++ b/src/infrastructure/customfield/field/PhabricatorCustomFieldAttachment.php @@ -8,7 +8,7 @@ * Generally, you should not use this class directly. It is used by * @{class:PhabricatorCustomField} to manage field storage on objects. */ -final class PhabricatorCustomFieldAttachment { +final class PhabricatorCustomFieldAttachment extends Phobject { private $lists = array(); diff --git a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldCredential.php b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldCredential.php index 94fbe165a4..d842ef3d17 100644 --- a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldCredential.php +++ b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldCredential.php @@ -24,7 +24,7 @@ final class PhabricatorStandardCustomFieldCredential $all_types = PassphraseCredentialType::getAllProvidesTypes(); if (!in_array($provides_type, $all_types)) { - $provides_type = PassphraseCredentialTypePassword::PROVIDES_TYPE; + $provides_type = PassphrasePasswordCredentialType::PROVIDES_TYPE; } $credentials = id(new PassphraseCredentialQuery()) diff --git a/src/infrastructure/daemon/bot/PhabricatorBotMessage.php b/src/infrastructure/daemon/bot/PhabricatorBotMessage.php index 27f0c17dbb..64de22f2cf 100644 --- a/src/infrastructure/daemon/bot/PhabricatorBotMessage.php +++ b/src/infrastructure/daemon/bot/PhabricatorBotMessage.php @@ -1,6 +1,6 @@ assertTrue(true); + } + +} diff --git a/src/infrastructure/env/PhabricatorConfigSource.php b/src/infrastructure/env/PhabricatorConfigSource.php index 1fbdf2f209..741d94e15f 100644 --- a/src/infrastructure/env/PhabricatorConfigSource.php +++ b/src/infrastructure/env/PhabricatorConfigSource.php @@ -1,6 +1,6 @@ markupError( - pht('Unable to locate the `figlet` binary. Install figlet.')); + pht( + 'Unable to locate the `%s` binary. Install figlet.', + 'figlet')); } $font = idx($argv, 'font', 'standard'); diff --git a/src/infrastructure/markup/interpreter/PhabricatorRemarkupGraphvizBlockInterpreter.php b/src/infrastructure/markup/interpreter/PhabricatorRemarkupGraphvizBlockInterpreter.php index d18ebbad10..e06432be6e 100644 --- a/src/infrastructure/markup/interpreter/PhabricatorRemarkupGraphvizBlockInterpreter.php +++ b/src/infrastructure/markup/interpreter/PhabricatorRemarkupGraphvizBlockInterpreter.php @@ -10,7 +10,9 @@ final class PhabricatorRemarkupGraphvizBlockInterpreter public function markupContent($content, array $argv) { if (!Filesystem::binaryExists('dot')) { return $this->markupError( - pht('Unable to locate the `dot` binary. Install Graphviz.')); + pht( + 'Unable to locate the `%s` binary. Install Graphviz.', + 'dot')); } $width = $this->parseDimension(idx($argv, 'width')); @@ -24,7 +26,8 @@ final class PhabricatorRemarkupGraphvizBlockInterpreter if ($err) { return $this->markupError( pht( - 'Execution of `dot` failed (#%d), check your syntax: %s', + 'Execution of `%s` failed (#%d), check your syntax: %s', + 'dot', $err, $stderr)); } diff --git a/src/infrastructure/markup/rule/PhabricatorYoutubeRemarkupRule.php b/src/infrastructure/markup/rule/PhabricatorYoutubeRemarkupRule.php index 43af8d3f01..bad8e0eacf 100644 --- a/src/infrastructure/markup/rule/PhabricatorYoutubeRemarkupRule.php +++ b/src/infrastructure/markup/rule/PhabricatorYoutubeRemarkupRule.php @@ -2,6 +2,8 @@ final class PhabricatorYoutubeRemarkupRule extends PhutilRemarkupRule { + private $uri; + public function getPriority() { return 350.0; } diff --git a/src/infrastructure/query/PhabricatorQuery.php b/src/infrastructure/query/PhabricatorQuery.php index f57c43c0ee..5893297dbc 100644 --- a/src/infrastructure/query/PhabricatorQuery.php +++ b/src/infrastructure/query/PhabricatorQuery.php @@ -3,7 +3,7 @@ /** * @task format Formatting Query Clauses */ -abstract class PhabricatorQuery { +abstract class PhabricatorQuery extends Phobject { abstract public function execute(); diff --git a/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php b/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php index b48e1e5c46..4d0f96bde5 100644 --- a/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php +++ b/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php @@ -25,6 +25,7 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery private $edgeLogicConstraints = array(); private $edgeLogicConstraintsAreValid = false; private $spacePHIDs; + private $spaceIsArchived; protected function getPageCursors(array $page) { return array( @@ -1722,6 +1723,11 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery return $this; } + public function withSpaceIsArchived($archived) { + $this->spaceIsArchived = $archived; + return $this; + } + /** * Constrain the query to include only results in valid Spaces. @@ -1760,6 +1766,11 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery $viewer_spaces = PhabricatorSpacesNamespaceQuery::getViewerSpaces( $viewer); foreach ($viewer_spaces as $viewer_space) { + if ($this->spaceIsArchived !== null) { + if ($viewer_space->getIsArchived() != $this->spaceIsArchived) { + continue; + } + } $phid = $viewer_space->getPHID(); $space_phids[$phid] = $phid; if ($viewer_space->getIsDefaultNamespace()) { diff --git a/src/infrastructure/query/policy/PhabricatorPolicyAwareQuery.php b/src/infrastructure/query/policy/PhabricatorPolicyAwareQuery.php index 1d8f10b916..e7b9b35628 100644 --- a/src/infrastructure/query/policy/PhabricatorPolicyAwareQuery.php +++ b/src/infrastructure/query/policy/PhabricatorPolicyAwareQuery.php @@ -338,9 +338,25 @@ abstract class PhabricatorPolicyAwareQuery extends PhabricatorOffsetPagedQuery { } protected function didRejectResult(PhabricatorPolicyInterface $object) { + // Some objects (like commits) may be rejected because related objects + // (like repositories) can not be loaded. In some cases, we may need these + // related objects to determine the object policy, so it's expected that + // we may occasionally be unable to determine the policy. + + try { + $policy = $object->getPolicy(PhabricatorPolicyCapability::CAN_VIEW); + } catch (Exception $ex) { + $policy = null; + } + + // Mark this object as filtered so handles can render "Restricted" instead + // of "Unknown". + $phid = $object->getPHID(); + $this->addPolicyFilteredPHIDs(array($phid => $phid)); + $this->getPolicyFilter()->rejectObject( $object, - $object->getPolicy(PhabricatorPolicyCapability::CAN_VIEW), + $policy, PhabricatorPolicyCapability::CAN_VIEW); } diff --git a/src/infrastructure/sms/adapter/PhabricatorSMSImplementationAdapter.php b/src/infrastructure/sms/adapter/PhabricatorSMSImplementationAdapter.php index 339a224f89..84325774ff 100644 --- a/src/infrastructure/sms/adapter/PhabricatorSMSImplementationAdapter.php +++ b/src/infrastructure/sms/adapter/PhabricatorSMSImplementationAdapter.php @@ -1,6 +1,6 @@ assertEqual( + 'md5:4824a35493d8b5dceab36f017d68425f', + $hasher->getPasswordHashForStorage( + new PhutilOpaqueEnvelope('quack'))->openEnvelope()); + } + +} diff --git a/src/infrastructure/util/password/__tests__/PhabricatorPasswordHasherTestCase.php b/src/infrastructure/util/password/__tests__/PhabricatorPasswordHasherTestCase.php index 053acea4fc..db1bfadf74 100644 --- a/src/infrastructure/util/password/__tests__/PhabricatorPasswordHasherTestCase.php +++ b/src/infrastructure/util/password/__tests__/PhabricatorPasswordHasherTestCase.php @@ -28,13 +28,9 @@ final class PhabricatorPasswordHasherTestCase extends PhabricatorTestCase { pht('Fictional hasher unavailable.')); } - public function testMD5Hasher() { - $hasher = new PhabricatorIteratedMD5PasswordHasher(); - - $this->assertEqual( - 'md5:4824a35493d8b5dceab36f017d68425f', - $hasher->getPasswordHashForStorage( - new PhutilOpaqueEnvelope('quack'))->openEnvelope()); + public function testGetAllHashers() { + PhabricatorPasswordHasher::getAllHashers(); + $this->assertTrue(true); } } diff --git a/src/view/control/PhabricatorObjectSelectorDialog.php b/src/view/control/PhabricatorObjectSelectorDialog.php index f6e107a99c..eaa51e5111 100644 --- a/src/view/control/PhabricatorObjectSelectorDialog.php +++ b/src/view/control/PhabricatorObjectSelectorDialog.php @@ -1,6 +1,6 @@ object = $object; @@ -17,6 +20,25 @@ final class AphrontFormPolicyControl extends AphrontFormControl { return $this; } + public function setSpacePHID($space_phid) { + $this->spacePHID = $space_phid; + return $this; + } + + public function getSpacePHID() { + return $this->spacePHID; + } + + public function setTemplatePHIDType($type) { + $this->templatePHIDType = $type; + return $this; + } + + public function setTemplateObject($object) { + $this->templateObject = $object; + return $this; + } + public function setCapability($capability) { $this->capability = $capability; @@ -48,9 +70,31 @@ final class AphrontFormPolicyControl extends AphrontFormControl { protected function getOptions() { $capability = $this->capability; + $policies = $this->policies; + + // Exclude object policies which don't make sense here. This primarily + // filters object policies associated from template capabilities (like + // "Default Task View Policy" being set to "Task Author") so they aren't + // made available on non-template capabilities (like "Can Bulk Edit"). + foreach ($policies as $key => $policy) { + if ($policy->getType() != PhabricatorPolicyType::TYPE_OBJECT) { + continue; + } + + $rule = PhabricatorPolicyQuery::getObjectPolicyRule($policy->getPHID()); + if (!$rule) { + continue; + } + + $target = nonempty($this->templateObject, $this->object); + if (!$rule->canApplyToObject($target)) { + unset($policies[$key]); + continue; + } + } $options = array(); - foreach ($this->policies as $policy) { + foreach ($policies as $policy) { if ($policy->getPHID() == PhabricatorPolicies::POLICY_PUBLIC) { // Never expose "Public" for capabilities which don't support it. $capobj = PhabricatorPolicyCapability::getCapabilityByKey($capability); @@ -58,6 +102,7 @@ final class AphrontFormPolicyControl extends AphrontFormControl { continue; } } + $policy_short_name = id(new PhutilUTF8StringTruncator()) ->setMaximumGlyphs(28) ->truncateString($policy->getName()); @@ -106,6 +151,7 @@ final class AphrontFormPolicyControl extends AphrontFormControl { $options, array( PhabricatorPolicyType::TYPE_GLOBAL, + PhabricatorPolicyType::TYPE_OBJECT, PhabricatorPolicyType::TYPE_USER, PhabricatorPolicyType::TYPE_CUSTOM, PhabricatorPolicyType::TYPE_PROJECT, @@ -168,6 +214,18 @@ final class AphrontFormPolicyControl extends AphrontFormControl { } + if ($this->templatePHIDType) { + $context_path = 'template/'.$this->templatePHIDType.'/'; + } else { + $object_phid = $this->object->getPHID(); + if ($object_phid) { + $context_path = 'object/'.$object_phid.'/'; + } else { + $object_type = phid_get_type($this->object->generatePHID()); + $context_path = 'type/'.$object_type.'/'; + } + } + Javelin::initBehavior( 'policy-control', array( @@ -180,6 +238,7 @@ final class AphrontFormPolicyControl extends AphrontFormControl { 'labels' => $labels, 'value' => $this->getValue(), 'capability' => $this->capability, + 'editURI' => '/policy/edit/'.$context_path, 'customPlaceholder' => $this->getCustomPolicyPlaceholder(), )); @@ -187,11 +246,14 @@ final class AphrontFormPolicyControl extends AphrontFormControl { $selected_icon = idx($selected, 'icon'); $selected_name = idx($selected, 'name'); + $spaces_control = $this->buildSpacesControl(); + return phutil_tag( 'div', array( ), array( + $spaces_control, javelin_tag( 'a', array( @@ -231,4 +293,35 @@ final class AphrontFormPolicyControl extends AphrontFormControl { return 'custom:placeholder'; } + private function buildSpacesControl() { + if ($this->capability != PhabricatorPolicyCapability::CAN_VIEW) { + return null; + } + + if (!($this->object instanceof PhabricatorSpacesInterface)) { + return null; + } + + $viewer = $this->getUser(); + if (!PhabricatorSpacesNamespaceQuery::getViewerSpacesExist($viewer)) { + return null; + } + + $space_phid = $this->getSpacePHID(); + if ($space_phid === null) { + $space_phid = $viewer->getDefaultSpacePHID(); + } + + $select = AphrontFormSelectControl::renderSelectTag( + $space_phid, + PhabricatorSpacesNamespaceQuery::getSpaceOptionsForViewer( + $viewer, + $space_phid), + array( + 'name' => 'spacePHID', + )); + + return $select; + } + } diff --git a/src/view/phui/PHUI.php b/src/view/phui/PHUI.php index 8848b99e1d..d3510a2315 100644 --- a/src/view/phui/PHUI.php +++ b/src/view/phui/PHUI.php @@ -1,6 +1,6 @@ object = $object; + return $this; + } + public function render() { require_celerity_resource('phui-pinboard-view-css'); $header = null; @@ -55,7 +60,17 @@ final class PHUIPinboardItemView extends AphrontView { array( 'class' => 'phui-pinboard-item-header '.$header_color, ), - phutil_tag('a', array('href' => $this->uri), $this->header)); + array( + id(new PHUISpacesNamespaceContextView()) + ->setUser($this->getUser()) + ->setObject($this->object), + phutil_tag( + 'a', + array( + 'href' => $this->uri, + ), + $this->header), + )); } $image = null; diff --git a/webroot/rsrc/js/application/herald/HeraldRuleEditor.js b/webroot/rsrc/js/application/herald/HeraldRuleEditor.js index e7300528d6..c94dd0d6c0 100644 --- a/webroot/rsrc/js/application/herald/HeraldRuleEditor.js +++ b/webroot/rsrc/js/application/herald/HeraldRuleEditor.js @@ -222,6 +222,7 @@ JX.install('HeraldRuleEditor', { case 'taskstatus': case 'legaldocuments': case 'applicationemail': + case 'space': var tokenizer = this._newTokenizer(type); input = tokenizer[0]; get_fn = tokenizer[1]; diff --git a/webroot/rsrc/js/application/maniphest/behavior-batch-editor.js b/webroot/rsrc/js/application/maniphest/behavior-batch-editor.js index 5cf568ce2c..ad2cf32d9e 100644 --- a/webroot/rsrc/js/application/maniphest/behavior-batch-editor.js +++ b/webroot/rsrc/js/application/maniphest/behavior-batch-editor.js @@ -24,12 +24,14 @@ JX.behavior('maniphest-batch-editor', function(config) { 'add_comment': 'Comment', 'assign': 'Assign', 'add_ccs' : 'Add CCs', - 'remove_ccs' : 'Remove CCs' + 'remove_ccs' : 'Remove CCs', + 'space': 'Shift to Space' }); var proj_tokenizer = build_tokenizer(config.sources.project); var owner_tokenizer = build_tokenizer(config.sources.owner); var cc_tokenizer = build_tokenizer(config.sources.cc); + var space_tokenizer = build_tokenizer(config.sources.spaces); var priority_select = JX.Prefab.renderSelect(config.priorityMap); var status_select = JX.Prefab.renderSelect(config.statusMap); @@ -60,6 +62,12 @@ JX.behavior('maniphest-batch-editor', function(config) { return JX.keys(owner_tokenizer.object.getTokens()); }; break; + case 'space': + JX.DOM.setContent(cell, space_tokenizer.template); + vfunc = function() { + return JX.keys(space_tokenizer.object.getTokens()); + }; + break; case 'add_comment': JX.DOM.setContent(cell, comment_input); vfunc = function() { diff --git a/webroot/rsrc/js/application/policy/behavior-policy-control.js b/webroot/rsrc/js/application/policy/behavior-policy-control.js index ddbe9f17ec..ea66761191 100644 --- a/webroot/rsrc/js/application/policy/behavior-policy-control.js +++ b/webroot/rsrc/js/application/policy/behavior-policy-control.js @@ -101,7 +101,7 @@ JX.behavior('policy-control', function(config) { * Get the workflow URI to create or edit a policy with a given PHID. */ var get_custom_uri = function(phid, capability) { - var uri = '/policy/edit/'; + var uri = config.editURI; if (phid != config.customPlaceholder) { uri += phid + '/'; }