diff --git a/resources/celerity/map.php b/resources/celerity/map.php index fcd593750d..13401f8d2c 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -7,7 +7,7 @@ */ return array( 'names' => array( - 'core.pkg.css' => 'e4baf17e', + 'core.pkg.css' => 'bd69d3a2', 'core.pkg.js' => 'cbdbd552', 'darkconsole.pkg.js' => 'df001cab', 'differential.pkg.css' => '36884139', @@ -28,7 +28,6 @@ return array( 'rsrc/css/aphront/pager-view.css' => '2e3539af', 'rsrc/css/aphront/panel-view.css' => '5846dfa2', 'rsrc/css/aphront/phabricator-nav-view.css' => '9283c2df', - 'rsrc/css/aphront/request-failure-view.css' => '7a83dc3a', 'rsrc/css/aphront/table-view.css' => 'b22b7216', 'rsrc/css/aphront/tokenizer.css' => '82ce2142', 'rsrc/css/aphront/tooltip.css' => '9c90229d', @@ -39,7 +38,7 @@ return array( 'rsrc/css/application/base/main-menu-view.css' => 'a1c976b2', 'rsrc/css/application/base/notification-menu.css' => '6aa0a74b', 'rsrc/css/application/base/phabricator-application-launch-view.css' => '5d71008f', - 'rsrc/css/application/base/standard-page-view.css' => 'dd860661', + 'rsrc/css/application/base/standard-page-view.css' => '1b000ec8', 'rsrc/css/application/chatlog/chatlog.css' => '852140ff', 'rsrc/css/application/config/config-options.css' => '7fedf08b', 'rsrc/css/application/config/config-template.css' => '25d446d6', @@ -93,7 +92,7 @@ return array( 'rsrc/css/application/ponder/feed.css' => 'e62615b6', 'rsrc/css/application/ponder/post.css' => 'ebab8a70', 'rsrc/css/application/ponder/vote.css' => '8ed6ed8b', - 'rsrc/css/application/profile/profile-view.css' => 'b459416e', + 'rsrc/css/application/profile/profile-view.css' => '28f433ef', 'rsrc/css/application/projects/project-icon.css' => 'c2ecb7f1', 'rsrc/css/application/releeph/releeph-core.css' => '9b3c5733', 'rsrc/css/application/releeph/releeph-preview-branch.css' => 'b7a6f4a5', @@ -508,7 +507,6 @@ return array( 'aphront-multi-column-view-css' => '1b95ab2e', 'aphront-pager-view-css' => '2e3539af', 'aphront-panel-view-css' => '5846dfa2', - 'aphront-request-failure-view-css' => '7a83dc3a', 'aphront-table-view-css' => 'b22b7216', 'aphront-tokenizer-control-css' => '82ce2142', 'aphront-tooltip-css' => '9c90229d', @@ -734,14 +732,14 @@ return array( 'phabricator-object-selector-css' => '029a133d', 'phabricator-phtize' => 'd254d646', 'phabricator-prefab' => 'bbae734c', - 'phabricator-profile-css' => 'b459416e', + 'phabricator-profile-css' => '28f433ef', 'phabricator-remarkup-css' => '45313445', 'phabricator-search-results-css' => 'f240504c', 'phabricator-shaped-request' => '7cbe244b', 'phabricator-side-menu-view-css' => 'a2ccd7bd', 'phabricator-slowvote-css' => '266df6a1', 'phabricator-source-code-view-css' => '7d346aa4', - 'phabricator-standard-page-view' => 'dd860661', + 'phabricator-standard-page-view' => '1b000ec8', 'phabricator-textareautils' => '5c93c52c', 'phabricator-title' => '5c1c758c', 'phabricator-tooltip' => '3915d490', diff --git a/resources/sql/autopatches/20140926.schema.01.droprelev.sql b/resources/sql/autopatches/20140926.schema.01.droprelev.sql new file mode 100644 index 0000000000..7542e2b209 --- /dev/null +++ b/resources/sql/autopatches/20140926.schema.01.droprelev.sql @@ -0,0 +1 @@ +DROP TABLE {$NAMESPACE}_releeph.releeph_event; diff --git a/resources/sql/autopatches/20140926.schema.02.droprelreqev.sql b/resources/sql/autopatches/20140926.schema.02.droprelreqev.sql new file mode 100644 index 0000000000..de0218ef2d --- /dev/null +++ b/resources/sql/autopatches/20140926.schema.02.droprelreqev.sql @@ -0,0 +1 @@ +DROP TABLE {$NAMESPACE}_releeph.releeph_requestevent; diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index aad704cb27..159dcbe89c 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -79,7 +79,6 @@ phutil_register_library_map(array( 'AphrontRedirectResponseTestCase' => 'aphront/response/__tests__/AphrontRedirectResponseTestCase.php', 'AphrontReloadResponse' => 'aphront/response/AphrontReloadResponse.php', 'AphrontRequest' => 'aphront/AphrontRequest.php', - 'AphrontRequestFailureView' => 'view/page/AphrontRequestFailureView.php', 'AphrontRequestTestCase' => 'aphront/__tests__/AphrontRequestTestCase.php', 'AphrontResponse' => 'aphront/response/AphrontResponse.php', 'AphrontSideNavFilterView' => 'view/layout/AphrontSideNavFilterView.php', @@ -111,6 +110,7 @@ phutil_register_library_map(array( 'CelerityResourceController' => 'infrastructure/celerity/CelerityResourceController.php', 'CelerityResourceGraph' => 'infrastructure/celerity/CelerityResourceGraph.php', 'CelerityResourceMap' => 'infrastructure/celerity/CelerityResourceMap.php', + 'CelerityResourceMapGenerator' => 'infrastructure/celerity/CelerityResourceMapGenerator.php', 'CelerityResourceTransformer' => 'infrastructure/celerity/CelerityResourceTransformer.php', 'CelerityResourceTransformerTestCase' => 'infrastructure/celerity/__tests__/CelerityResourceTransformerTestCase.php', 'CelerityResources' => 'infrastructure/celerity/resources/CelerityResources.php', @@ -992,6 +992,7 @@ phutil_register_library_map(array( 'NuanceRequestorTransactionComment' => 'applications/nuance/storage/NuanceRequestorTransactionComment.php', 'NuanceRequestorTransactionQuery' => 'applications/nuance/query/NuanceRequestorTransactionQuery.php', 'NuanceRequestorViewController' => 'applications/nuance/controller/NuanceRequestorViewController.php', + 'NuanceSchemaSpec' => 'applications/nuance/storage/NuanceSchemaSpec.php', 'NuanceSource' => 'applications/nuance/storage/NuanceSource.php', 'NuanceSourceDefaultEditCapability' => 'applications/nuance/capability/NuanceSourceDefaultEditCapability.php', 'NuanceSourceDefaultViewCapability' => 'applications/nuance/capability/NuanceSourceDefaultViewCapability.php', @@ -1104,6 +1105,7 @@ phutil_register_library_map(array( 'PassphraseQueryConduitAPIMethod' => 'applications/passphrase/conduit/PassphraseQueryConduitAPIMethod.php', 'PassphraseRemarkupRule' => 'applications/passphrase/remarkup/PassphraseRemarkupRule.php', 'PassphraseSSHKey' => 'applications/passphrase/keys/PassphraseSSHKey.php', + 'PassphraseSchemaSpec' => 'applications/passphrase/storage/PassphraseSchemaSpec.php', 'PassphraseSecret' => 'applications/passphrase/storage/PassphraseSecret.php', 'PasteConduitAPIMethod' => 'applications/paste/conduit/PasteConduitAPIMethod.php', 'PasteCreateConduitAPIMethod' => 'applications/paste/conduit/PasteCreateConduitAPIMethod.php', @@ -1308,6 +1310,7 @@ phutil_register_library_map(array( 'PhabricatorCalendarSchemaSpec' => 'applications/calendar/storage/PhabricatorCalendarSchemaSpec.php', 'PhabricatorCalendarViewController' => 'applications/calendar/controller/PhabricatorCalendarViewController.php', 'PhabricatorCampfireProtocolAdapter' => 'infrastructure/daemon/bot/adapter/PhabricatorCampfireProtocolAdapter.php', + 'PhabricatorCelerityTestCase' => '__tests__/PhabricatorCelerityTestCase.php', 'PhabricatorChangeParserTestCase' => 'applications/repository/worker/__tests__/PhabricatorChangeParserTestCase.php', 'PhabricatorChangesetResponse' => 'infrastructure/diff/PhabricatorChangesetResponse.php', 'PhabricatorChatLogApplication' => 'applications/chatlog/application/PhabricatorChatLogApplication.php', @@ -1540,6 +1543,7 @@ phutil_register_library_map(array( 'PhabricatorEmailLoginController' => 'applications/auth/controller/PhabricatorEmailLoginController.php', 'PhabricatorEmailVerificationController' => 'applications/auth/controller/PhabricatorEmailVerificationController.php', 'PhabricatorEmbedFileRemarkupRule' => 'applications/files/markup/PhabricatorEmbedFileRemarkupRule.php', + 'PhabricatorEmojiRemarkupRule' => 'applications/macro/markup/PhabricatorEmojiRemarkupRule.php', 'PhabricatorEmptyQueryException' => 'infrastructure/query/PhabricatorEmptyQueryException.php', 'PhabricatorEnglishTranslation' => 'infrastructure/internationalization/translation/PhabricatorEnglishTranslation.php', 'PhabricatorEnv' => 'infrastructure/env/PhabricatorEnv.php', @@ -1810,6 +1814,7 @@ phutil_register_library_map(array( 'PhabricatorMetaMTAReceivedMail' => 'applications/metamta/storage/PhabricatorMetaMTAReceivedMail.php', 'PhabricatorMetaMTAReceivedMailProcessingException' => 'applications/metamta/exception/PhabricatorMetaMTAReceivedMailProcessingException.php', 'PhabricatorMetaMTAReceivedMailTestCase' => 'applications/metamta/storage/__tests__/PhabricatorMetaMTAReceivedMailTestCase.php', + 'PhabricatorMetaMTASchemaSpec' => 'applications/metamta/storage/PhabricatorMetaMTASchemaSpec.php', 'PhabricatorMetaMTASendGridReceiveController' => 'applications/metamta/controller/PhabricatorMetaMTASendGridReceiveController.php', 'PhabricatorMetaMTAWorker' => 'applications/metamta/PhabricatorMetaMTAWorker.php', 'PhabricatorMultiColumnExample' => 'applications/uiexample/examples/PhabricatorMultiColumnExample.php', @@ -1846,6 +1851,7 @@ phutil_register_library_map(array( 'PhabricatorOAuthClientListController' => 'applications/oauthserver/controller/client/PhabricatorOAuthClientListController.php', 'PhabricatorOAuthClientViewController' => 'applications/oauthserver/controller/client/PhabricatorOAuthClientViewController.php', 'PhabricatorOAuthResponse' => 'applications/oauthserver/PhabricatorOAuthResponse.php', + 'PhabricatorOAuthSchemaSpec' => 'applications/oauthserver/storage/PhabricatorOAuthSchemaSpec.php', 'PhabricatorOAuthServer' => 'applications/oauthserver/PhabricatorOAuthServer.php', 'PhabricatorOAuthServerAccessToken' => 'applications/oauthserver/storage/PhabricatorOAuthServerAccessToken.php', 'PhabricatorOAuthServerApplication' => 'applications/oauthserver/application/PhabricatorOAuthServerApplication.php', @@ -1919,6 +1925,7 @@ phutil_register_library_map(array( 'PhabricatorPastePastePHIDType' => 'applications/paste/phid/PhabricatorPastePastePHIDType.php', 'PhabricatorPasteQuery' => 'applications/paste/query/PhabricatorPasteQuery.php', 'PhabricatorPasteRemarkupRule' => 'applications/paste/remarkup/PhabricatorPasteRemarkupRule.php', + 'PhabricatorPasteSchemaSpec' => 'applications/paste/storage/PhabricatorPasteSchemaSpec.php', 'PhabricatorPasteSearchEngine' => 'applications/paste/query/PhabricatorPasteSearchEngine.php', 'PhabricatorPasteTestDataGenerator' => 'applications/paste/lipsum/PhabricatorPasteTestDataGenerator.php', 'PhabricatorPasteTransaction' => 'applications/paste/storage/PhabricatorPasteTransaction.php', @@ -2141,6 +2148,7 @@ phutil_register_library_map(array( 'PhabricatorRepositoryRefCursorQuery' => 'applications/repository/query/PhabricatorRepositoryRefCursorQuery.php', 'PhabricatorRepositoryRefEngine' => 'applications/repository/engine/PhabricatorRepositoryRefEngine.php', 'PhabricatorRepositoryRepositoryPHIDType' => 'applications/repository/phid/PhabricatorRepositoryRepositoryPHIDType.php', + 'PhabricatorRepositorySchemaSpec' => 'applications/repository/storage/PhabricatorRepositorySchemaSpec.php', 'PhabricatorRepositorySearchEngine' => 'applications/repository/query/PhabricatorRepositorySearchEngine.php', 'PhabricatorRepositoryStatusMessage' => 'applications/repository/storage/PhabricatorRepositoryStatusMessage.php', 'PhabricatorRepositorySvnCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/PhabricatorRepositorySvnCommitChangeParserWorker.php', @@ -2254,6 +2262,7 @@ phutil_register_library_map(array( 'PhabricatorSetupCheckPath' => 'applications/config/check/PhabricatorSetupCheckPath.php', 'PhabricatorSetupCheckPygment' => 'applications/config/check/PhabricatorSetupCheckPygment.php', 'PhabricatorSetupCheckRepositories' => 'applications/config/check/PhabricatorSetupCheckRepositories.php', + 'PhabricatorSetupCheckSecurity' => 'applications/config/check/PhabricatorSetupCheckSecurity.php', 'PhabricatorSetupCheckStorage' => 'applications/config/check/PhabricatorSetupCheckStorage.php', 'PhabricatorSetupCheckTimezone' => 'applications/config/check/PhabricatorSetupCheckTimezone.php', 'PhabricatorSetupIssue' => 'applications/config/issue/PhabricatorSetupIssue.php', @@ -2308,6 +2317,7 @@ phutil_register_library_map(array( 'PhabricatorStorageManagementUpgradeWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementUpgradeWorkflow.php', 'PhabricatorStorageManagementWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementWorkflow.php', 'PhabricatorStoragePatch' => 'infrastructure/storage/management/PhabricatorStoragePatch.php', + 'PhabricatorStorageSchemaSpec' => 'infrastructure/storage/schema/PhabricatorStorageSchemaSpec.php', 'PhabricatorSubscribableInterface' => 'applications/subscriptions/interface/PhabricatorSubscribableInterface.php', 'PhabricatorSubscribersQuery' => 'applications/subscriptions/query/PhabricatorSubscribersQuery.php', 'PhabricatorSubscriptionsApplication' => 'applications/subscriptions/application/PhabricatorSubscriptionsApplication.php', @@ -2492,11 +2502,13 @@ phutil_register_library_map(array( 'PhameQueryConduitAPIMethod' => 'applications/phame/conduit/PhameQueryConduitAPIMethod.php', 'PhameQueryPostsConduitAPIMethod' => 'applications/phame/conduit/PhameQueryPostsConduitAPIMethod.php', 'PhameResourceController' => 'applications/phame/controller/PhameResourceController.php', + 'PhameSchemaSpec' => 'applications/phame/storage/PhameSchemaSpec.php', 'PhameSkinSpecification' => 'applications/phame/skins/PhameSkinSpecification.php', 'PhluxController' => 'applications/phlux/controller/PhluxController.php', 'PhluxDAO' => 'applications/phlux/storage/PhluxDAO.php', 'PhluxEditController' => 'applications/phlux/controller/PhluxEditController.php', 'PhluxListController' => 'applications/phlux/controller/PhluxListController.php', + 'PhluxSchemaSpec' => 'applications/phlux/storage/PhluxSchemaSpec.php', 'PhluxTransaction' => 'applications/phlux/storage/PhluxTransaction.php', 'PhluxTransactionQuery' => 'applications/phlux/query/PhluxTransactionQuery.php', 'PhluxVariable' => 'applications/phlux/storage/PhluxVariable.php', @@ -2796,6 +2808,7 @@ phutil_register_library_map(array( 'ReleephRequestViewController' => 'applications/releeph/controller/request/ReleephRequestViewController.php', 'ReleephRequestorFieldSpecification' => 'applications/releeph/field/specification/ReleephRequestorFieldSpecification.php', 'ReleephRevisionFieldSpecification' => 'applications/releeph/field/specification/ReleephRevisionFieldSpecification.php', + 'ReleephSchemaSpec' => 'applications/releeph/storage/ReleephSchemaSpec.php', 'ReleephSeverityFieldSpecification' => 'applications/releeph/field/specification/ReleephSeverityFieldSpecification.php', 'ReleephSummaryFieldSpecification' => 'applications/releeph/field/specification/ReleephSummaryFieldSpecification.php', 'ReleephWorkCanPushConduitAPIMethod' => 'applications/releeph/conduit/work/ReleephWorkCanPushConduitAPIMethod.php', @@ -2917,7 +2930,6 @@ phutil_register_library_map(array( 'AphrontRedirectResponse' => 'AphrontResponse', 'AphrontRedirectResponseTestCase' => 'PhabricatorTestCase', 'AphrontReloadResponse' => 'AphrontRedirectResponse', - 'AphrontRequestFailureView' => 'AphrontView', 'AphrontRequestTestCase' => 'PhabricatorTestCase', 'AphrontSideNavFilterView' => 'AphrontView', 'AphrontStackTraceView' => 'AphrontView', @@ -3896,6 +3908,7 @@ phutil_register_library_map(array( 'NuanceRequestorTransactionComment' => 'PhabricatorApplicationTransactionComment', 'NuanceRequestorTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'NuanceRequestorViewController' => 'NuanceController', + 'NuanceSchemaSpec' => 'PhabricatorConfigSchemaSpec', 'NuanceSource' => array( 'NuanceDAO', 'PhabricatorPolicyInterface', @@ -4014,6 +4027,7 @@ phutil_register_library_map(array( 'PassphraseQueryConduitAPIMethod' => 'PassphraseConduitAPIMethod', 'PassphraseRemarkupRule' => 'PhabricatorObjectRemarkupRule', 'PassphraseSSHKey' => 'PassphraseAbstractKey', + 'PassphraseSchemaSpec' => 'PhabricatorConfigSchemaSpec', 'PassphraseSecret' => 'PassphraseDAO', 'PasteConduitAPIMethod' => 'ConduitAPIMethod', 'PasteCreateConduitAPIMethod' => 'PasteConduitAPIMethod', @@ -4225,6 +4239,7 @@ phutil_register_library_map(array( 'PhabricatorCalendarSchemaSpec' => 'PhabricatorConfigSchemaSpec', 'PhabricatorCalendarViewController' => 'PhabricatorCalendarController', 'PhabricatorCampfireProtocolAdapter' => 'PhabricatorBotBaseStreamingProtocolAdapter', + 'PhabricatorCelerityTestCase' => 'PhabricatorTestCase', 'PhabricatorChangeParserTestCase' => 'PhabricatorWorkingCopyTestCase', 'PhabricatorChangesetResponse' => 'AphrontProxyResponse', 'PhabricatorChatLogApplication' => 'PhabricatorApplication', @@ -4477,6 +4492,7 @@ phutil_register_library_map(array( 'PhabricatorEmailLoginController' => 'PhabricatorAuthController', 'PhabricatorEmailVerificationController' => 'PhabricatorAuthController', 'PhabricatorEmbedFileRemarkupRule' => 'PhabricatorObjectRemarkupRule', + 'PhabricatorEmojiRemarkupRule' => 'PhutilRemarkupRule', 'PhabricatorEmptyQueryException' => 'Exception', 'PhabricatorEnglishTranslation' => 'PhabricatorBaseEnglishTranslation', 'PhabricatorEnvTestCase' => 'PhabricatorTestCase', @@ -4744,6 +4760,7 @@ phutil_register_library_map(array( 'PhabricatorMetaMTAReceivedMail' => 'PhabricatorMetaMTADAO', 'PhabricatorMetaMTAReceivedMailProcessingException' => 'Exception', 'PhabricatorMetaMTAReceivedMailTestCase' => 'PhabricatorTestCase', + 'PhabricatorMetaMTASchemaSpec' => 'PhabricatorConfigSchemaSpec', 'PhabricatorMetaMTASendGridReceiveController' => 'PhabricatorMetaMTAController', 'PhabricatorMetaMTAWorker' => 'PhabricatorWorker', 'PhabricatorMultiColumnExample' => 'PhabricatorUIExample', @@ -4784,6 +4801,7 @@ phutil_register_library_map(array( 'PhabricatorOAuthClientListController' => 'PhabricatorOAuthClientController', 'PhabricatorOAuthClientViewController' => 'PhabricatorOAuthClientController', 'PhabricatorOAuthResponse' => 'AphrontResponse', + 'PhabricatorOAuthSchemaSpec' => 'PhabricatorConfigSchemaSpec', 'PhabricatorOAuthServerAccessToken' => 'PhabricatorOAuthServerDAO', 'PhabricatorOAuthServerApplication' => 'PhabricatorApplication', 'PhabricatorOAuthServerAuthController' => 'PhabricatorAuthController', @@ -4848,6 +4866,8 @@ phutil_register_library_map(array( 'PhabricatorMentionableInterface', 'PhabricatorPolicyInterface', 'PhabricatorProjectInterface', + 'PhabricatorDestructibleInterface', + 'PhabricatorApplicationTransactionInterface', ), 'PhabricatorPasteApplication' => 'PhabricatorApplication', 'PhabricatorPasteCommentController' => 'PhabricatorPasteController', @@ -4860,6 +4880,7 @@ phutil_register_library_map(array( 'PhabricatorPastePastePHIDType' => 'PhabricatorPHIDType', 'PhabricatorPasteQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorPasteRemarkupRule' => 'PhabricatorObjectRemarkupRule', + 'PhabricatorPasteSchemaSpec' => 'PhabricatorConfigSchemaSpec', 'PhabricatorPasteSearchEngine' => 'PhabricatorApplicationSearchEngine', 'PhabricatorPasteTestDataGenerator' => 'PhabricatorTestDataGenerator', 'PhabricatorPasteTransaction' => 'PhabricatorApplicationTransaction', @@ -5131,6 +5152,7 @@ phutil_register_library_map(array( 'PhabricatorRepositoryRefCursorQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorRepositoryRefEngine' => 'PhabricatorRepositoryEngine', 'PhabricatorRepositoryRepositoryPHIDType' => 'PhabricatorPHIDType', + 'PhabricatorRepositorySchemaSpec' => 'PhabricatorConfigSchemaSpec', 'PhabricatorRepositorySearchEngine' => 'PhabricatorApplicationSearchEngine', 'PhabricatorRepositoryStatusMessage' => 'PhabricatorRepositoryDAO', 'PhabricatorRepositorySvnCommitChangeParserWorker' => 'PhabricatorRepositoryCommitChangeParserWorker', @@ -5234,6 +5256,7 @@ phutil_register_library_map(array( 'PhabricatorSetupCheckPath' => 'PhabricatorSetupCheck', 'PhabricatorSetupCheckPygment' => 'PhabricatorSetupCheck', 'PhabricatorSetupCheckRepositories' => 'PhabricatorSetupCheck', + 'PhabricatorSetupCheckSecurity' => 'PhabricatorSetupCheck', 'PhabricatorSetupCheckStorage' => 'PhabricatorSetupCheck', 'PhabricatorSetupCheckTimezone' => 'PhabricatorSetupCheck', 'PhabricatorSetupIssueExample' => 'PhabricatorUIExample', @@ -5290,6 +5313,7 @@ phutil_register_library_map(array( 'PhabricatorStorageManagementStatusWorkflow' => 'PhabricatorStorageManagementWorkflow', 'PhabricatorStorageManagementUpgradeWorkflow' => 'PhabricatorStorageManagementWorkflow', 'PhabricatorStorageManagementWorkflow' => 'PhabricatorManagementWorkflow', + 'PhabricatorStorageSchemaSpec' => 'PhabricatorConfigSchemaSpec', 'PhabricatorSubscribersQuery' => 'PhabricatorQuery', 'PhabricatorSubscriptionsApplication' => 'PhabricatorApplication', 'PhabricatorSubscriptionsEditController' => 'PhabricatorController', @@ -5489,10 +5513,12 @@ phutil_register_library_map(array( 'PhameQueryConduitAPIMethod' => 'PhameConduitAPIMethod', 'PhameQueryPostsConduitAPIMethod' => 'PhameConduitAPIMethod', 'PhameResourceController' => 'CelerityResourceController', + 'PhameSchemaSpec' => 'PhabricatorConfigSchemaSpec', 'PhluxController' => 'PhabricatorController', 'PhluxDAO' => 'PhabricatorLiskDAO', 'PhluxEditController' => 'PhluxController', 'PhluxListController' => 'PhluxController', + 'PhluxSchemaSpec' => 'PhabricatorConfigSchemaSpec', 'PhluxTransaction' => 'PhabricatorApplicationTransaction', 'PhluxTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'PhluxVariable' => array( @@ -5881,6 +5907,7 @@ phutil_register_library_map(array( 'ReleephRequestViewController' => 'ReleephBranchController', 'ReleephRequestorFieldSpecification' => 'ReleephFieldSpecification', 'ReleephRevisionFieldSpecification' => 'ReleephFieldSpecification', + 'ReleephSchemaSpec' => 'PhabricatorConfigSchemaSpec', 'ReleephSeverityFieldSpecification' => 'ReleephLevelFieldSpecification', 'ReleephSummaryFieldSpecification' => 'ReleephFieldSpecification', 'ReleephWorkCanPushConduitAPIMethod' => 'ReleephConduitAPIMethod', diff --git a/src/__tests__/PhabricatorCelerityTestCase.php b/src/__tests__/PhabricatorCelerityTestCase.php new file mode 100644 index 0000000000..d36ef051c8 --- /dev/null +++ b/src/__tests__/PhabricatorCelerityTestCase.php @@ -0,0 +1,33 @@ +generate(); + + $this->assertEqual( + $new_map->getNameMap(), + $old_map->getNameMap()); + $this->assertEqual( + $new_map->getSymbolMap(), + $old_map->getSymbolMap()); + $this->assertEqual( + $new_map->getRequiresMap(), + $old_map->getRequiresMap()); + $this->assertEqual( + $new_map->getPackageMap(), + $old_map->getPackageMap()); + } + } + +} diff --git a/src/aphront/response/Aphront403Response.php b/src/aphront/response/Aphront403Response.php index 8866b0ec0b..3f7f6d73ca 100644 --- a/src/aphront/response/Aphront403Response.php +++ b/src/aphront/response/Aphront403Response.php @@ -19,16 +19,23 @@ final class Aphront403Response extends AphrontHTMLResponse { $forbidden_text = $this->getForbiddenText(); if (!$forbidden_text) { $forbidden_text = - 'You do not have privileges to access the requested page.'; + pht('You do not have privileges to access the requested page.'); } - $failure = new AphrontRequestFailureView(); - $failure->setHeader('403 Forbidden'); - $failure->appendChild(phutil_tag('p', array(), $forbidden_text)); - $view = new PhabricatorStandardPageView(); - $view->setTitle('403 Forbidden'); - $view->setRequest($this->getRequest()); - $view->appendChild($failure); + $request = $this->getRequest(); + $user = $request->getUser(); + + $dialog = id(new AphrontDialogView()) + ->setUser($user) + ->setTitle(pht('403 Forbidden')) + ->addCancelButton('/', pht('Peace Out')) + ->appendParagraph($forbidden_text); + + $view = id(new PhabricatorStandardPageView()) + ->setTitle(pht('403 Forbidden')) + ->setRequest($request) + ->setDeviceReady(true) + ->appendChild($dialog); return $view->render(); } diff --git a/src/aphront/response/Aphront404Response.php b/src/aphront/response/Aphront404Response.php index 1dddc7a01f..85dec30555 100644 --- a/src/aphront/response/Aphront404Response.php +++ b/src/aphront/response/Aphront404Response.php @@ -7,16 +7,22 @@ final class Aphront404Response extends AphrontHTMLResponse { } public function buildResponseString() { - $failure = id(new AphrontRequestFailureView()) - ->setHeader(pht('404 Not Found')) - ->appendChild(phutil_tag('p', array(), pht( - 'The page you requested was not found.'))); + $request = $this->getRequest(); + $user = $request->getUser(); + + $dialog = id(new AphrontDialogView()) + ->setUser($user) + ->setTitle(pht('404 Not Found')) + ->addCancelButton('/', pht('Focus')) + ->appendParagraph(pht( + 'Do not dwell in the past, do not dream of the future, '. + 'concentrate the mind on the present moment.')); $view = id(new PhabricatorStandardPageView()) ->setTitle('404 Not Found') - ->setRequest($this->getRequest()) + ->setRequest($request) ->setDeviceReady(true) - ->appendChild($failure); + ->appendChild($dialog); return $view->render(); } diff --git a/src/applications/auth/controller/PhabricatorDisabledUserController.php b/src/applications/auth/controller/PhabricatorDisabledUserController.php index 364a9a61ec..842f2daad6 100644 --- a/src/applications/auth/controller/PhabricatorDisabledUserController.php +++ b/src/applications/auth/controller/PhabricatorDisabledUserController.php @@ -14,16 +14,11 @@ final class PhabricatorDisabledUserController return new Aphront404Response(); } - $failure_view = new AphrontRequestFailureView(); - $failure_view->setHeader(pht('Account Disabled')); - $failure_view->appendChild(phutil_tag('p', array(), pht( - 'Your account has been disabled.'))); - - return $this->buildStandardPageResponse( - $failure_view, - array( - 'title' => pht('Account Disabled'), - )); + return id(new AphrontDialogView()) + ->setUser($user) + ->setTitle(pht('Account Disabled')) + ->addCancelButton('/logout/', pht('Okay')) + ->appendParagraph(pht('Your account has been disabled.')); } } diff --git a/src/applications/config/check/PhabricatorSetupCheckSecurity.php b/src/applications/config/check/PhabricatorSetupCheckSecurity.php new file mode 100644 index 0000000000..f399d5302d --- /dev/null +++ b/src/applications/config/check/PhabricatorSetupCheckSecurity.php @@ -0,0 +1,49 @@ + '() { :;} ; echo VULNERABLE', + ); + + list($err, $stdout) = id(new ExecFuture('echo shellshock-test')) + ->setEnv($payload, $wipe_process_env = true) + ->resolve(); + + if (!$err && preg_match('/VULNERABLE/', $stdout)) { + $summary = pht( + 'This system has an unpatched version of Bash with a severe, widely '. + 'disclosed vulnerability.'); + + $message = pht( + 'The version of %s on this system is out of date and contains a '. + 'major, widely disclosed vulnerability (the "Shellshock" '. + 'vulnerability).'. + "\n\n". + 'Upgrade %s to a patched version.'. + "\n\n". + 'To learn more about how this issue affects Phabricator, see %s.', + phutil_tag('tt', array(), 'bash'), + phutil_tag('tt', array(), 'bash'), + phutil_tag( + 'a', + array( + 'href' => 'https://secure.phabricator.com/T6185', + 'target' => '_blank', + ), + pht('T6185 "Shellshock" Bash Vulnerability'))); + + $this + ->newIssue('security.shellshock') + ->setName(pht('Severe Security Vulnerability: Unpatched Bash')) + ->setSummary($summary) + ->setMessage($message); + } + + } +} diff --git a/src/applications/config/schema/PhabricatorConfigSchemaSpec.php b/src/applications/config/schema/PhabricatorConfigSchemaSpec.php index eda715639d..22fbea4117 100644 --- a/src/applications/config/schema/PhabricatorConfigSchemaSpec.php +++ b/src/applications/config/schema/PhabricatorConfigSchemaSpec.php @@ -138,6 +138,10 @@ abstract class PhabricatorConfigSchemaSpec extends Phobject { 'src' => array( 'columns' => array('src', 'type', 'dateCreated', 'seq'), ), + 'key_dst' => array( + 'columns' => array('dst', 'type', 'src'), + 'unique' => true, + ), )); $this->buildRawSchema( @@ -246,16 +250,29 @@ abstract class PhabricatorConfigSchemaSpec extends Phobject { $charset = 'binary'; $collation = 'binary'; break; + case 'bytes32': + $column_type = 'char(32)'; + $charset = 'binary'; + $collation = 'binary'; + break; + case 'bytes20': + $column_type = 'char(20)'; + $charset = 'binary'; + $collation = 'binary'; + break; case 'bytes12': $column_type = 'char(12)'; $charset = 'binary'; $collation = 'binary'; break; - case 'bytes': - $column_type = 'longblob'; + case 'bytes4': + $column_type = 'char(4)'; $charset = 'binary'; $collation = 'binary'; break; + case 'bytes': + $column_type = 'longblob'; + break; case 'text255': $column_type = 'varchar(255)'; $charset = $this->getUTF8Charset(); @@ -266,11 +283,21 @@ abstract class PhabricatorConfigSchemaSpec extends Phobject { $charset = $this->getUTF8Charset(); $collation = $this->getUTF8Collation(); break; + case 'text80': + $column_type = 'varchar(80)'; + $charset = $this->getUTF8Charset(); + $collation = $this->getUTF8Collation(); + break; case 'text64': $column_type = 'varchar(64)'; $charset = $this->getUTF8Charset(); $collation = $this->getUTF8Collation(); break; + case 'text40': + $column_type = 'varchar(40)'; + $charset = $this->getUTF8Charset(); + $collation = $this->getUTF8Collation(); + break; case 'text32': $column_type = 'varchar(32)'; $charset = $this->getUTF8Charset(); diff --git a/src/applications/differential/customfield/DifferentialRepositoryField.php b/src/applications/differential/customfield/DifferentialRepositoryField.php index cab25dbbe5..06ada847c9 100644 --- a/src/applications/differential/customfield/DifferentialRepositoryField.php +++ b/src/applications/differential/customfield/DifferentialRepositoryField.php @@ -107,19 +107,25 @@ final class DifferentialRepositoryField $old = $xaction->getOldValue(); $new = $xaction->getNewValue(); - if ($old) { + if ($old && $new) { return pht( '%s updated the repository for %s from %s to %s.', $xaction->renderHandleLink($author_phid), $xaction->renderHandleLink($object_phid), $xaction->renderHandleLink($old), $xaction->renderHandleLink($new)); - } else { + } else if ($new) { return pht( '%s set the repository for %s to %s.', $xaction->renderHandleLink($author_phid), $xaction->renderHandleLink($object_phid), $xaction->renderHandleLink($new)); + } else { + return pht( + '%s removed the repository for %s. (Repository was %s.)', + $xaction->renderHandleLink($author_phid), + $xaction->renderHandleLink($object_phid), + $xaction->renderHandleLink($old)); } } diff --git a/src/applications/differential/event/DifferentialHovercardEventListener.php b/src/applications/differential/event/DifferentialHovercardEventListener.php index 5e7556cbc3..80ef4eb249 100644 --- a/src/applications/differential/event/DifferentialHovercardEventListener.php +++ b/src/applications/differential/event/DifferentialHovercardEventListener.php @@ -56,9 +56,6 @@ final class DifferentialHovercardEventListener $hovercard->addField(pht('Author'), $handles[$rev->getAuthorPHID()]->renderLink()); - $hovercard->addField(pht('Date'), - phabricator_datetime($rev->getDateModified(), $viewer)); - $hovercard->addField(pht('Reviewers'), implode_selected_handle_links(', ', $handles, $reviewer_phids)); diff --git a/src/applications/differential/storage/DifferentialAffectedPath.php b/src/applications/differential/storage/DifferentialAffectedPath.php index ac0e9c23ec..35e7ba5d70 100644 --- a/src/applications/differential/storage/DifferentialAffectedPath.php +++ b/src/applications/differential/storage/DifferentialAffectedPath.php @@ -14,6 +14,18 @@ final class DifferentialAffectedPath extends DifferentialDAO { public function getConfiguration() { return array( self::CONFIG_TIMESTAMPS => false, + self::CONFIG_COLUMN_SCHEMA => array( + 'id' => null, + ), + self::CONFIG_KEY_SCHEMA => array( + 'PRIMARY' => null, + 'repositoryID' => array( + 'columns' => array('repositoryID', 'pathID', 'epoch'), + ), + 'revisionID' => array( + 'columns' => array('revisionID'), + ), + ), ) + parent::getConfiguration(); } diff --git a/src/applications/differential/storage/DifferentialChangeset.php b/src/applications/differential/storage/DifferentialChangeset.php index 743bf172b1..5ae22d8a2c 100644 --- a/src/applications/differential/storage/DifferentialChangeset.php +++ b/src/applications/differential/storage/DifferentialChangeset.php @@ -28,7 +28,21 @@ final class DifferentialChangeset extends DifferentialDAO 'oldProperties' => self::SERIALIZATION_JSON, 'newProperties' => self::SERIALIZATION_JSON, 'awayPaths' => self::SERIALIZATION_JSON, - )) + parent::getConfiguration(); + ), + self::CONFIG_COLUMN_SCHEMA => array( + 'oldFile' => 'text255?', + 'filename' => 'text255', + 'changeType' => 'uint32', + 'fileType' => 'uint32', + 'addLines' => 'uint32', + 'delLines' => 'uint32', + ), + self::CONFIG_KEY_SCHEMA => array( + 'diffID' => array( + 'columns' => array('diffID'), + ), + ), + ) + parent::getConfiguration(); } public function getAffectedLineCount() { diff --git a/src/applications/differential/storage/DifferentialDiff.php b/src/applications/differential/storage/DifferentialDiff.php index 863312520d..7828510f80 100644 --- a/src/applications/differential/storage/DifferentialDiff.php +++ b/src/applications/differential/storage/DifferentialDiff.php @@ -42,6 +42,30 @@ final class DifferentialDiff public function getConfiguration() { return array( self::CONFIG_AUX_PHID => true, + self::CONFIG_COLUMN_SCHEMA => array( + 'revisionID' => 'id?', + 'authorPHID' => 'phid?', + 'repositoryPHID' => 'phid?', + 'sourceMachine' => 'text255?', + 'sourcePath' => 'text255?', + 'sourceControlSystem' => 'text64?', + 'sourceControlBaseRevision' => 'text255?', + 'sourceControlPath' => 'text255?', + 'lintStatus' => 'uint32', + 'unitStatus' => 'uint32', + 'lineCount' => 'uint32', + 'branch' => 'text255?', + 'bookmark' => 'text255?', + 'arcanistProjectPHID' => 'phid?', + 'creationMethod' => 'text255', + 'description' => 'text255', + 'repositoryUUID' => 'text64?', + ), + self::CONFIG_KEY_SCHEMA => array( + 'revisionID' => array( + 'columns' => array('revisionID'), + ), + ), ) + parent::getConfiguration(); } diff --git a/src/applications/differential/storage/DifferentialDiffProperty.php b/src/applications/differential/storage/DifferentialDiffProperty.php index 11be887eb4..a7286bfec1 100644 --- a/src/applications/differential/storage/DifferentialDiffProperty.php +++ b/src/applications/differential/storage/DifferentialDiffProperty.php @@ -10,7 +10,17 @@ final class DifferentialDiffProperty extends DifferentialDAO { return array( self::CONFIG_SERIALIZATION => array( 'data' => self::SERIALIZATION_JSON, - )) + parent::getConfiguration(); + ), + self::CONFIG_COLUMN_SCHEMA => array( + 'name' => 'text255', + ), + self::CONFIG_KEY_SCHEMA => array( + 'diffID' => array( + 'columns' => array('diffID', 'name'), + 'unique' => true, + ), + ), + ) + parent::getConfiguration(); } } diff --git a/src/applications/differential/storage/DifferentialDraft.php b/src/applications/differential/storage/DifferentialDraft.php index 6ad406d3f0..8ea12f73e0 100644 --- a/src/applications/differential/storage/DifferentialDraft.php +++ b/src/applications/differential/storage/DifferentialDraft.php @@ -6,6 +6,20 @@ final class DifferentialDraft extends DifferentialDAO { protected $authorPHID; protected $draftKey; + public function getConfiguration() { + return array( + self::CONFIG_COLUMN_SCHEMA => array( + 'draftKey' => 'text64', + ), + self::CONFIG_KEY_SCHEMA => array( + 'key_unique' => array( + 'columns' => array('objectPHID', 'authorPHID', 'draftKey'), + 'unique' => true, + ), + ), + ) + parent::getConfiguration(); + } + public static function markHasDraft( $author_phid, $object_phid, diff --git a/src/applications/differential/storage/DifferentialHunkLegacy.php b/src/applications/differential/storage/DifferentialHunkLegacy.php index 7eedd770c1..c64a4f1c9d 100644 --- a/src/applications/differential/storage/DifferentialHunkLegacy.php +++ b/src/applications/differential/storage/DifferentialHunkLegacy.php @@ -4,6 +4,23 @@ final class DifferentialHunkLegacy extends DifferentialHunk { protected $changes; + public function getConfiguration() { + return array( + self::CONFIG_COLUMN_SCHEMA => array( + 'changes' => 'text?', + 'oldOffset' => 'uint32', + 'oldLen' => 'uint32', + 'newOffset' => 'uint32', + 'newLen' => 'uint32', + ), + self::CONFIG_KEY_SCHEMA => array( + 'changesetID' => array( + 'columns' => array('changesetID'), + ), + ), + ) + parent::getConfiguration(); + } + public function getTableName() { return 'differential_hunk'; } diff --git a/src/applications/differential/storage/DifferentialHunkModern.php b/src/applications/differential/storage/DifferentialHunkModern.php index eae36a6f7f..0279dd5f78 100644 --- a/src/applications/differential/storage/DifferentialHunkModern.php +++ b/src/applications/differential/storage/DifferentialHunkModern.php @@ -25,6 +25,23 @@ final class DifferentialHunkModern extends DifferentialHunk { self::CONFIG_BINARY => array( 'data' => true, ), + self::CONFIG_COLUMN_SCHEMA => array( + 'dataType' => 'bytes4', + 'dataEncoding' => 'text16?', + 'dataFormat' => 'bytes4', + 'oldOffset' => 'uint32', + 'oldLen' => 'uint32', + 'newOffset' => 'uint32', + 'newLen' => 'uint32', + ), + self::CONFIG_KEY_SCHEMA => array( + 'key_changeset' => array( + 'columns' => array('changesetID'), + ), + 'key_created' => array( + 'columns' => array('dateCreated'), + ), + ), ) + parent::getConfiguration(); } diff --git a/src/applications/differential/storage/DifferentialRevision.php b/src/applications/differential/storage/DifferentialRevision.php index 428536a0e1..c8b3fa17af 100644 --- a/src/applications/differential/storage/DifferentialRevision.php +++ b/src/applications/differential/storage/DifferentialRevision.php @@ -74,6 +74,33 @@ final class DifferentialRevision extends DifferentialDAO 'attached' => self::SERIALIZATION_JSON, 'unsubscribed' => self::SERIALIZATION_JSON, ), + self::CONFIG_COLUMN_SCHEMA => array( + 'title' => 'text255', + 'originalTitle' => 'text255', + 'status' => 'text32', + 'summary' => 'text', + 'testPlan' => 'text', + 'authorPHID' => 'phid?', + 'lastReviewerPHID' => 'phid?', + 'lineCount' => 'uint32?', + 'mailKey' => 'bytes40', + 'branchName' => 'text255', + 'arcanistProjectPHID' => 'phid?', + 'repositoryPHID' => 'phid?', + ), + self::CONFIG_KEY_SCHEMA => array( + 'key_phid' => null, + 'phid' => array( + 'columns' => array('phid'), + 'unique' => true, + ), + 'authorPHID' => array( + 'columns' => array('authorPHID', 'status'), + ), + 'repositoryPHID' => array( + 'columns' => array('repositoryPHID'), + ), + ), ) + parent::getConfiguration(); } diff --git a/src/applications/differential/storage/DifferentialSchemaSpec.php b/src/applications/differential/storage/DifferentialSchemaSpec.php index e568da0a45..fc75096381 100644 --- a/src/applications/differential/storage/DifferentialSchemaSpec.php +++ b/src/applications/differential/storage/DifferentialSchemaSpec.php @@ -4,7 +4,74 @@ final class DifferentialSchemaSpec extends PhabricatorConfigSchemaSpec { public function buildSchemata() { $this->buildLiskSchemata('DifferentialDAO'); -// $this->addEdgeSchemata($server, new DifferentialRevision()); + + $this->buildEdgeSchemata(new DifferentialRevision()); + + $this->buildTransactionSchema( + new DifferentialTransaction(), + new DifferentialTransactionComment()); + + $this->buildCustomFieldSchemata( + new DifferentialCustomFieldStorage(), + array( + new DifferentialCustomFieldNumericIndex(), + new DifferentialCustomFieldStringIndex(), + )); + + $this->buildRawSchema( + id(new DifferentialRevision())->getApplicationName(), + DifferentialChangeset::TABLE_CACHE, + array( + 'id' => 'id', + 'cache' => 'bytes', + 'dateCreated' => 'epoch', + ), + array( + 'PRIMARY' => array( + 'columns' => array('id'), + 'unique' => true, + ), + 'dateCreated' => array( + 'columns' => array('dateCreated'), + ), + )); + + $this->buildRawSchema( + id(new DifferentialRevision())->getApplicationName(), + DifferentialRevision::TABLE_COMMIT, + array( + 'revisionID' => 'id', + 'commitPHID' => 'phid', + ), + array( + 'PRIMARY' => array( + 'columns' => array('revisionID', 'commitPHID'), + 'unique' => true, + ), + 'commitPHID' => array( + 'columns' => array('commitPHID'), + 'unique' => true, + ), + )); + + $this->buildRawSchema( + id(new DifferentialRevision())->getApplicationName(), + ArcanistDifferentialRevisionHash::TABLE_NAME, + array( + 'revisionID' => 'id', + 'type' => 'bytes4', + 'hash' => 'bytes40', + ), + array( + 'type' => array( + 'columns' => array('type', 'hash'), + ), + 'revisionID' => array( + 'columns' => array('revisionID'), + ), + )); + + } } diff --git a/src/applications/differential/storage/DifferentialTransactionComment.php b/src/applications/differential/storage/DifferentialTransactionComment.php index 90086618ec..d8835e3b1a 100644 --- a/src/applications/differential/storage/DifferentialTransactionComment.php +++ b/src/applications/differential/storage/DifferentialTransactionComment.php @@ -16,6 +16,32 @@ final class DifferentialTransactionComment return new DifferentialTransaction(); } + public function getConfiguration() { + $config = parent::getConfiguration(); + $config[self::CONFIG_COLUMN_SCHEMA] = array( + 'revisionPHID' => 'phid?', + 'changesetID' => 'id?', + 'isNewFile' => 'bool', + 'lineNumber' => 'uint32', + 'lineLength' => 'uint32', + 'fixedState' => 'text12?', + 'hasReplies' => 'bool', + 'replyToCommentPHID' => 'phid?', + ) + $config[self::CONFIG_COLUMN_SCHEMA]; + $config[self::CONFIG_KEY_SCHEMA] = array( + 'key_draft' => array( + 'columns' => array('authorPHID', 'transactionPHID'), + ), + 'key_changeset' => array( + 'columns' => array('changesetID'), + ), + 'key_revision' => array( + 'columns' => array('revisionPHID'), + ), + ) + $config[self::CONFIG_KEY_SCHEMA]; + return $config; + } + public function shouldUseMarkupCache($field) { // Only cache submitted comments. return ($this->getTransactionPHID() != null); diff --git a/src/applications/drydock/worker/DrydockAllocatorWorker.php b/src/applications/drydock/worker/DrydockAllocatorWorker.php index 3b955f16fe..6d8e740e18 100644 --- a/src/applications/drydock/worker/DrydockAllocatorWorker.php +++ b/src/applications/drydock/worker/DrydockAllocatorWorker.php @@ -4,6 +4,10 @@ final class DrydockAllocatorWorker extends PhabricatorWorker { private $lease; + public function getRequiredLeaseTime() { + return 3600 * 24; + } + public function getMaximumRetryCount() { // TODO: Allow Drydock allocations to retry. For now, every failure is // permanent and most of them are because I am bad at programming, so fail diff --git a/src/applications/macro/application/PhabricatorMacroApplication.php b/src/applications/macro/application/PhabricatorMacroApplication.php index 51b1152ba6..384d9fa951 100644 --- a/src/applications/macro/application/PhabricatorMacroApplication.php +++ b/src/applications/macro/application/PhabricatorMacroApplication.php @@ -45,6 +45,7 @@ final class PhabricatorMacroApplication extends PhabricatorApplication { public function getRemarkupRules() { return array( new PhabricatorIconRemarkupRule(), + new PhabricatorEmojiRemarkupRule(), ); } diff --git a/src/applications/macro/markup/PhabricatorEmojiRemarkupRule.php b/src/applications/macro/markup/PhabricatorEmojiRemarkupRule.php new file mode 100644 index 0000000000..b1e24c23ff --- /dev/null +++ b/src/applications/macro/markup/PhabricatorEmojiRemarkupRule.php @@ -0,0 +1,903 @@ +isFlatText($matches[0])) { + return $matches[0]; + } + + static $map = array( + 'watch' => "\xE2\x8C\x9A", + 'hourglass' => "\xE2\x8C\x9B", + 'fast_forward' => "\xE2\x8F\xA9", + 'rewind' => "\xE2\x8F\xAA", + 'arrow_double_up' => "\xE2\x8F\xAB", + 'arrow_double_down' => "\xE2\x8F\xAC", + 'alarm_clock' => "\xE2\x8F\xB0", + 'hourglass_flowing_sand' => "\xE2\x8F\xB3", + 'white_medium_small_square' => "\xE2\x97\xBD", + 'black_medium_small_square' => "\xE2\x97\xBE", + 'umbrella' => "\xE2\x98\x94", + 'coffee' => "\xE2\x98\x95", + 'aries' => "\xE2\x99\x88", + 'taurus' => "\xE2\x99\x89", + 'gemini' => "\xE2\x99\x8A", + 'cancer' => "\xE2\x99\x8B", + 'leo' => "\xE2\x99\x8C", + 'virgo' => "\xE2\x99\x8D", + 'libra' => "\xE2\x99\x8E", + 'scorpius' => "\xE2\x99\x8F", + 'sagittarius' => "\xE2\x99\x90", + 'capricorn' => "\xE2\x99\x91", + 'aquarius' => "\xE2\x99\x92", + 'pisces' => "\xE2\x99\x93", + 'wheelchair' => "\xE2\x99\xBF", + 'anchor' => "\xE2\x9A\x93", + 'zap' => "\xE2\x9A\xA1", + 'white_circle' => "\xE2\x9A\xAA", + 'black_circle' => "\xE2\x9A\xAB", + 'soccer' => "\xE2\x9A\xBD", + 'snowman' => "\xE2\x9B\x84", + 'partly_sunny' => "\xE2\x9B\x85", + 'ophiuchus' => "\xE2\x9B\x8E", + 'no_entry' => "\xE2\x9B\x94", + 'church' => "\xE2\x9B\xAA", + 'fountain' => "\xE2\x9B\xB2", + 'golf' => "\xE2\x9B\xB3", + 'sailboat' => "\xE2\x9B\xB5", + 'boat' => "\xE2\x9B\xB5", + 'tent' => "\xE2\x9B\xBA", + 'fuelpump' => "\xE2\x9B\xBD", + 'white_check_mark' => "\xE2\x9C\x85", + 'fist' => "\xE2\x9C\x8A", + 'hand' => "\xE2\x9C\x8B", + 'raised_hand' => "\xE2\x9C\x8B", + 'sparkles' => "\xE2\x9C\xA8", + 'x' => "\xE2\x9D\x8C", + 'negative_squared_cross_mark' => "\xE2\x9D\x8E", + 'question' => "\xE2\x9D\x93", + 'grey_question' => "\xE2\x9D\x94", + 'grey_exclamation' => "\xE2\x9D\x95", + 'exclamation' => "\xE2\x9D\x97", + 'heavy_exclamation_mark' => "\xE2\x9D\x97", + 'heavy_plus_sign' => "\xE2\x9E\x95", + 'heavy_minus_sign' => "\xE2\x9E\x96", + 'heavy_division_sign' => "\xE2\x9E\x97", + 'curly_loop' => "\xE2\x9E\xB0", + 'loop' => "\xE2\x9E\xBF", + 'black_large_square' => "\xE2\xAC\x9B", + 'white_large_square' => "\xE2\xAC\x9C", + 'star' => "\xE2\xAD\x90", + 'o' => "\xE2\xAD\x95", + 'mahjong' => "\xF0\x9F\x80\x84", + 'black_joker' => "\xF0\x9F\x83\x8F", + 'ab' => "\xF0\x9F\x86\x8E", + 'cl' => "\xF0\x9F\x86\x91", + 'cool' => "\xF0\x9F\x86\x92", + 'free' => "\xF0\x9F\x86\x93", + 'id' => "\xF0\x9F\x86\x94", + 'new' => "\xF0\x9F\x86\x95", + 'ng' => "\xF0\x9F\x86\x96", + 'ok' => "\xF0\x9F\x86\x97", + 'sos' => "\xF0\x9F\x86\x98", + 'up' => "\xF0\x9F\x86\x99", + 'vs' => "\xF0\x9F\x86\x9A", + 'koko' => "\xF0\x9F\x88\x81", + 'u7121' => "\xF0\x9F\x88\x9A", + 'u6307' => "\xF0\x9F\x88\xAF", + 'u7981' => "\xF0\x9F\x88\xB2", + 'u7a7a' => "\xF0\x9F\x88\xB3", + 'u5408' => "\xF0\x9F\x88\xB4", + 'u6e80' => "\xF0\x9F\x88\xB5", + 'u6709' => "\xF0\x9F\x88\xB6", + 'u7533' => "\xF0\x9F\x88\xB8", + 'u5272' => "\xF0\x9F\x88\xB9", + 'u55b6' => "\xF0\x9F\x88\xBA", + 'ideograph_advantage' => "\xF0\x9F\x89\x90", + 'accept' => "\xF0\x9F\x89\x91", + 'cyclone' => "\xF0\x9F\x8C\x80", + 'foggy' => "\xF0\x9F\x8C\x81", + 'closed_umbrella' => "\xF0\x9F\x8C\x82", + 'night_with_stars' => "\xF0\x9F\x8C\x83", + 'sunrise_over_mountains' => "\xF0\x9F\x8C\x84", + 'sunrise' => "\xF0\x9F\x8C\x85", + 'city_sunset' => "\xF0\x9F\x8C\x86", + 'city_sunrise' => "\xF0\x9F\x8C\x87", + 'rainbow' => "\xF0\x9F\x8C\x88", + 'bridge_at_night' => "\xF0\x9F\x8C\x89", + 'ocean' => "\xF0\x9F\x8C\x8A", + 'volcano' => "\xF0\x9F\x8C\x8B", + 'milky_way' => "\xF0\x9F\x8C\x8C", + 'earth_africa' => "\xF0\x9F\x8C\x8D", + 'earth_americas' => "\xF0\x9F\x8C\x8E", + 'earth_asia' => "\xF0\x9F\x8C\x8F", + 'globe_with_meridians' => "\xF0\x9F\x8C\x90", + 'new_moon' => "\xF0\x9F\x8C\x91", + 'waxing_crescent_moon' => "\xF0\x9F\x8C\x92", + 'first_quarter_moon' => "\xF0\x9F\x8C\x93", + 'waxing_gibbous_moon' => "\xF0\x9F\x8C\x94", + 'moon' => "\xF0\x9F\x8C\x94", + 'full_moon' => "\xF0\x9F\x8C\x95", + 'waning_gibbous_moon' => "\xF0\x9F\x8C\x96", + 'last_quarter_moon' => "\xF0\x9F\x8C\x97", + 'waning_crescent_moon' => "\xF0\x9F\x8C\x98", + 'crescent_moon' => "\xF0\x9F\x8C\x99", + 'new_moon_with_face' => "\xF0\x9F\x8C\x9A", + 'first_quarter_moon_with_face' => "\xF0\x9F\x8C\x9B", + 'last_quarter_moon_with_face' => "\xF0\x9F\x8C\x9C", + 'full_moon_with_face' => "\xF0\x9F\x8C\x9D", + 'sun_with_face' => "\xF0\x9F\x8C\x9E", + 'star2' => "\xF0\x9F\x8C\x9F", + 'stars' => "\xF0\x9F\x8C\xA0", + 'chestnut' => "\xF0\x9F\x8C\xB0", + 'seedling' => "\xF0\x9F\x8C\xB1", + 'evergreen_tree' => "\xF0\x9F\x8C\xB2", + 'deciduous_tree' => "\xF0\x9F\x8C\xB3", + 'palm_tree' => "\xF0\x9F\x8C\xB4", + 'cactus' => "\xF0\x9F\x8C\xB5", + 'tulip' => "\xF0\x9F\x8C\xB7", + 'cherry_blossom' => "\xF0\x9F\x8C\xB8", + 'rose' => "\xF0\x9F\x8C\xB9", + 'hibiscus' => "\xF0\x9F\x8C\xBA", + 'sunflower' => "\xF0\x9F\x8C\xBB", + 'blossom' => "\xF0\x9F\x8C\xBC", + 'corn' => "\xF0\x9F\x8C\xBD", + 'ear_of_rice' => "\xF0\x9F\x8C\xBE", + 'herb' => "\xF0\x9F\x8C\xBF", + 'four_leaf_clover' => "\xF0\x9F\x8D\x80", + 'maple_leaf' => "\xF0\x9F\x8D\x81", + 'fallen_leaf' => "\xF0\x9F\x8D\x82", + 'leaves' => "\xF0\x9F\x8D\x83", + 'mushroom' => "\xF0\x9F\x8D\x84", + 'tomato' => "\xF0\x9F\x8D\x85", + 'eggplant' => "\xF0\x9F\x8D\x86", + 'grapes' => "\xF0\x9F\x8D\x87", + 'melon' => "\xF0\x9F\x8D\x88", + 'watermelon' => "\xF0\x9F\x8D\x89", + 'tangerine' => "\xF0\x9F\x8D\x8A", + 'lemon' => "\xF0\x9F\x8D\x8B", + 'banana' => "\xF0\x9F\x8D\x8C", + 'pineapple' => "\xF0\x9F\x8D\x8D", + 'apple' => "\xF0\x9F\x8D\x8E", + 'green_apple' => "\xF0\x9F\x8D\x8F", + 'pear' => "\xF0\x9F\x8D\x90", + 'peach' => "\xF0\x9F\x8D\x91", + 'cherries' => "\xF0\x9F\x8D\x92", + 'strawberry' => "\xF0\x9F\x8D\x93", + 'hamburger' => "\xF0\x9F\x8D\x94", + 'pizza' => "\xF0\x9F\x8D\x95", + 'meat_on_bone' => "\xF0\x9F\x8D\x96", + 'poultry_leg' => "\xF0\x9F\x8D\x97", + 'rice_cracker' => "\xF0\x9F\x8D\x98", + 'rice_ball' => "\xF0\x9F\x8D\x99", + 'rice' => "\xF0\x9F\x8D\x9A", + 'curry' => "\xF0\x9F\x8D\x9B", + 'ramen' => "\xF0\x9F\x8D\x9C", + 'spaghetti' => "\xF0\x9F\x8D\x9D", + 'bread' => "\xF0\x9F\x8D\x9E", + 'fries' => "\xF0\x9F\x8D\x9F", + 'sweet_potato' => "\xF0\x9F\x8D\xA0", + 'dango' => "\xF0\x9F\x8D\xA1", + 'oden' => "\xF0\x9F\x8D\xA2", + 'sushi' => "\xF0\x9F\x8D\xA3", + 'fried_shrimp' => "\xF0\x9F\x8D\xA4", + 'fish_cake' => "\xF0\x9F\x8D\xA5", + 'icecream' => "\xF0\x9F\x8D\xA6", + 'shaved_ice' => "\xF0\x9F\x8D\xA7", + 'ice_cream' => "\xF0\x9F\x8D\xA8", + 'doughnut' => "\xF0\x9F\x8D\xA9", + 'cookie' => "\xF0\x9F\x8D\xAA", + 'chocolate_bar' => "\xF0\x9F\x8D\xAB", + 'candy' => "\xF0\x9F\x8D\xAC", + 'lollipop' => "\xF0\x9F\x8D\xAD", + 'custard' => "\xF0\x9F\x8D\xAE", + 'honey_pot' => "\xF0\x9F\x8D\xAF", + 'cake' => "\xF0\x9F\x8D\xB0", + 'bento' => "\xF0\x9F\x8D\xB1", + 'stew' => "\xF0\x9F\x8D\xB2", + 'egg' => "\xF0\x9F\x8D\xB3", + 'fork_and_knife' => "\xF0\x9F\x8D\xB4", + 'tea' => "\xF0\x9F\x8D\xB5", + 'sake' => "\xF0\x9F\x8D\xB6", + 'wine_glass' => "\xF0\x9F\x8D\xB7", + 'cocktail' => "\xF0\x9F\x8D\xB8", + 'tropical_drink' => "\xF0\x9F\x8D\xB9", + 'beer' => "\xF0\x9F\x8D\xBA", + 'beers' => "\xF0\x9F\x8D\xBB", + 'baby_bottle' => "\xF0\x9F\x8D\xBC", + 'ribbon' => "\xF0\x9F\x8E\x80", + 'gift' => "\xF0\x9F\x8E\x81", + 'birthday' => "\xF0\x9F\x8E\x82", + 'jack_o_lantern' => "\xF0\x9F\x8E\x83", + 'christmas_tree' => "\xF0\x9F\x8E\x84", + 'santa' => "\xF0\x9F\x8E\x85", + 'fireworks' => "\xF0\x9F\x8E\x86", + 'sparkler' => "\xF0\x9F\x8E\x87", + 'balloon' => "\xF0\x9F\x8E\x88", + 'tada' => "\xF0\x9F\x8E\x89", + 'confetti_ball' => "\xF0\x9F\x8E\x8A", + 'tanabata_tree' => "\xF0\x9F\x8E\x8B", + 'crossed_flags' => "\xF0\x9F\x8E\x8C", + 'bamboo' => "\xF0\x9F\x8E\x8D", + 'dolls' => "\xF0\x9F\x8E\x8E", + 'flags' => "\xF0\x9F\x8E\x8F", + 'wind_chime' => "\xF0\x9F\x8E\x90", + 'rice_scene' => "\xF0\x9F\x8E\x91", + 'school_satchel' => "\xF0\x9F\x8E\x92", + 'mortar_board' => "\xF0\x9F\x8E\x93", + 'carousel_horse' => "\xF0\x9F\x8E\xA0", + 'ferris_wheel' => "\xF0\x9F\x8E\xA1", + 'roller_coaster' => "\xF0\x9F\x8E\xA2", + 'fishing_pole_and_fish' => "\xF0\x9F\x8E\xA3", + 'microphone' => "\xF0\x9F\x8E\xA4", + 'movie_camera' => "\xF0\x9F\x8E\xA5", + 'cinema' => "\xF0\x9F\x8E\xA6", + 'headphones' => "\xF0\x9F\x8E\xA7", + 'art' => "\xF0\x9F\x8E\xA8", + 'tophat' => "\xF0\x9F\x8E\xA9", + 'circus_tent' => "\xF0\x9F\x8E\xAA", + 'ticket' => "\xF0\x9F\x8E\xAB", + 'clapper' => "\xF0\x9F\x8E\xAC", + 'performing_arts' => "\xF0\x9F\x8E\xAD", + 'video_game' => "\xF0\x9F\x8E\xAE", + 'dart' => "\xF0\x9F\x8E\xAF", + 'slot_machine' => "\xF0\x9F\x8E\xB0", + '8ball' => "\xF0\x9F\x8E\xB1", + 'game_die' => "\xF0\x9F\x8E\xB2", + 'bowling' => "\xF0\x9F\x8E\xB3", + 'flower_playing_cards' => "\xF0\x9F\x8E\xB4", + 'musical_note' => "\xF0\x9F\x8E\xB5", + 'notes' => "\xF0\x9F\x8E\xB6", + 'saxophone' => "\xF0\x9F\x8E\xB7", + 'guitar' => "\xF0\x9F\x8E\xB8", + 'musical_keyboard' => "\xF0\x9F\x8E\xB9", + 'trumpet' => "\xF0\x9F\x8E\xBA", + 'violin' => "\xF0\x9F\x8E\xBB", + 'musical_score' => "\xF0\x9F\x8E\xBC", + 'running_shirt_with_sash' => "\xF0\x9F\x8E\xBD", + 'tennis' => "\xF0\x9F\x8E\xBE", + 'ski' => "\xF0\x9F\x8E\xBF", + 'basketball' => "\xF0\x9F\x8F\x80", + 'checkered_flag' => "\xF0\x9F\x8F\x81", + 'snowboarder' => "\xF0\x9F\x8F\x82", + 'runner' => "\xF0\x9F\x8F\x83", + 'running' => "\xF0\x9F\x8F\x83", + 'surfer' => "\xF0\x9F\x8F\x84", + 'trophy' => "\xF0\x9F\x8F\x86", + 'horse_racing' => "\xF0\x9F\x8F\x87", + 'football' => "\xF0\x9F\x8F\x88", + 'rugby_football' => "\xF0\x9F\x8F\x89", + 'swimmer' => "\xF0\x9F\x8F\x8A", + 'house' => "\xF0\x9F\x8F\xA0", + 'house_with_garden' => "\xF0\x9F\x8F\xA1", + 'office' => "\xF0\x9F\x8F\xA2", + 'post_office' => "\xF0\x9F\x8F\xA3", + 'european_post_office' => "\xF0\x9F\x8F\xA4", + 'hospital' => "\xF0\x9F\x8F\xA5", + 'bank' => "\xF0\x9F\x8F\xA6", + 'atm' => "\xF0\x9F\x8F\xA7", + 'hotel' => "\xF0\x9F\x8F\xA8", + 'love_hotel' => "\xF0\x9F\x8F\xA9", + 'convenience_store' => "\xF0\x9F\x8F\xAA", + 'school' => "\xF0\x9F\x8F\xAB", + 'department_store' => "\xF0\x9F\x8F\xAC", + 'factory' => "\xF0\x9F\x8F\xAD", + 'lantern' => "\xF0\x9F\x8F\xAE", + 'izakaya_lantern' => "\xF0\x9F\x8F\xAE", + 'japanese_castle' => "\xF0\x9F\x8F\xAF", + 'european_castle' => "\xF0\x9F\x8F\xB0", + 'rat' => "\xF0\x9F\x90\x80", + 'mouse2' => "\xF0\x9F\x90\x81", + 'ox' => "\xF0\x9F\x90\x82", + 'water_buffalo' => "\xF0\x9F\x90\x83", + 'cow2' => "\xF0\x9F\x90\x84", + 'tiger2' => "\xF0\x9F\x90\x85", + 'leopard' => "\xF0\x9F\x90\x86", + 'rabbit2' => "\xF0\x9F\x90\x87", + 'cat2' => "\xF0\x9F\x90\x88", + 'dragon' => "\xF0\x9F\x90\x89", + 'crocodile' => "\xF0\x9F\x90\x8A", + 'whale2' => "\xF0\x9F\x90\x8B", + 'snail' => "\xF0\x9F\x90\x8C", + 'snake' => "\xF0\x9F\x90\x8D", + 'racehorse' => "\xF0\x9F\x90\x8E", + 'ram' => "\xF0\x9F\x90\x8F", + 'goat' => "\xF0\x9F\x90\x90", + 'sheep' => "\xF0\x9F\x90\x91", + 'monkey' => "\xF0\x9F\x90\x92", + 'rooster' => "\xF0\x9F\x90\x93", + 'chicken' => "\xF0\x9F\x90\x94", + 'dog2' => "\xF0\x9F\x90\x95", + 'pig2' => "\xF0\x9F\x90\x96", + 'boar' => "\xF0\x9F\x90\x97", + 'elephant' => "\xF0\x9F\x90\x98", + 'octopus' => "\xF0\x9F\x90\x99", + 'shell' => "\xF0\x9F\x90\x9A", + 'bug' => "\xF0\x9F\x90\x9B", + 'ant' => "\xF0\x9F\x90\x9C", + 'bee' => "\xF0\x9F\x90\x9D", + 'honeybee' => "\xF0\x9F\x90\x9D", + 'beetle' => "\xF0\x9F\x90\x9E", + 'fish' => "\xF0\x9F\x90\x9F", + 'tropical_fish' => "\xF0\x9F\x90\xA0", + 'blowfish' => "\xF0\x9F\x90\xA1", + 'turtle' => "\xF0\x9F\x90\xA2", + 'hatching_chick' => "\xF0\x9F\x90\xA3", + 'baby_chick' => "\xF0\x9F\x90\xA4", + 'hatched_chick' => "\xF0\x9F\x90\xA5", + 'bird' => "\xF0\x9F\x90\xA6", + 'penguin' => "\xF0\x9F\x90\xA7", + 'koala' => "\xF0\x9F\x90\xA8", + 'poodle' => "\xF0\x9F\x90\xA9", + 'dromedary_camel' => "\xF0\x9F\x90\xAA", + 'camel' => "\xF0\x9F\x90\xAB", + 'dolphin' => "\xF0\x9F\x90\xAC", + 'flipper' => "\xF0\x9F\x90\xAC", + 'mouse' => "\xF0\x9F\x90\xAD", + 'cow' => "\xF0\x9F\x90\xAE", + 'tiger' => "\xF0\x9F\x90\xAF", + 'rabbit' => "\xF0\x9F\x90\xB0", + 'cat' => "\xF0\x9F\x90\xB1", + 'dragon_face' => "\xF0\x9F\x90\xB2", + 'whale' => "\xF0\x9F\x90\xB3", + 'horse' => "\xF0\x9F\x90\xB4", + 'monkey_face' => "\xF0\x9F\x90\xB5", + 'dog' => "\xF0\x9F\x90\xB6", + 'pig' => "\xF0\x9F\x90\xB7", + 'frog' => "\xF0\x9F\x90\xB8", + 'hamster' => "\xF0\x9F\x90\xB9", + 'wolf' => "\xF0\x9F\x90\xBA", + 'bear' => "\xF0\x9F\x90\xBB", + 'panda_face' => "\xF0\x9F\x90\xBC", + 'pig_nose' => "\xF0\x9F\x90\xBD", + 'paw_prints' => "\xF0\x9F\x90\xBE", + 'feet' => "\xF0\x9F\x90\xBE", + 'eyes' => "\xF0\x9F\x91\x80", + 'ear' => "\xF0\x9F\x91\x82", + 'nose' => "\xF0\x9F\x91\x83", + 'lips' => "\xF0\x9F\x91\x84", + 'tongue' => "\xF0\x9F\x91\x85", + 'point_up_2' => "\xF0\x9F\x91\x86", + 'point_down' => "\xF0\x9F\x91\x87", + 'point_left' => "\xF0\x9F\x91\x88", + 'point_right' => "\xF0\x9F\x91\x89", + 'punch' => "\xF0\x9F\x91\x8A", + 'facepunch' => "\xF0\x9F\x91\x8A", + 'wave' => "\xF0\x9F\x91\x8B", + 'ok_hand' => "\xF0\x9F\x91\x8C", + '+1' => "\xF0\x9F\x91\x8D", + 'thumbsup' => "\xF0\x9F\x91\x8D", + '_1' => "\xF0\x9F\x91\x8E", + 'thumbsdown' => "\xF0\x9F\x91\x8E", + 'clap' => "\xF0\x9F\x91\x8F", + 'open_hands' => "\xF0\x9F\x91\x90", + 'crown' => "\xF0\x9F\x91\x91", + 'womans_hat' => "\xF0\x9F\x91\x92", + 'eyeglasses' => "\xF0\x9F\x91\x93", + 'necktie' => "\xF0\x9F\x91\x94", + 'tshirt' => "\xF0\x9F\x91\x95", + 'shirt' => "\xF0\x9F\x91\x95", + 'jeans' => "\xF0\x9F\x91\x96", + 'dress' => "\xF0\x9F\x91\x97", + 'kimono' => "\xF0\x9F\x91\x98", + 'bikini' => "\xF0\x9F\x91\x99", + 'womans_clothes' => "\xF0\x9F\x91\x9A", + 'purse' => "\xF0\x9F\x91\x9B", + 'handbag' => "\xF0\x9F\x91\x9C", + 'pouch' => "\xF0\x9F\x91\x9D", + 'mans_shoe' => "\xF0\x9F\x91\x9E", + 'shoe' => "\xF0\x9F\x91\x9E", + 'athletic_shoe' => "\xF0\x9F\x91\x9F", + 'high_heel' => "\xF0\x9F\x91\xA0", + 'sandal' => "\xF0\x9F\x91\xA1", + 'boot' => "\xF0\x9F\x91\xA2", + 'footprints' => "\xF0\x9F\x91\xA3", + 'bust_in_silhouette' => "\xF0\x9F\x91\xA4", + 'busts_in_silhouette' => "\xF0\x9F\x91\xA5", + 'boy' => "\xF0\x9F\x91\xA6", + 'girl' => "\xF0\x9F\x91\xA7", + 'man' => "\xF0\x9F\x91\xA8", + 'woman' => "\xF0\x9F\x91\xA9", + 'family' => "\xF0\x9F\x91\xAA", + 'couple' => "\xF0\x9F\x91\xAB", + 'two_men_holding_hands' => "\xF0\x9F\x91\xAC", + 'two_women_holding_hands' => "\xF0\x9F\x91\xAD", + 'cop' => "\xF0\x9F\x91\xAE", + 'dancers' => "\xF0\x9F\x91\xAF", + 'bride_with_veil' => "\xF0\x9F\x91\xB0", + 'person_with_blond_hair' => "\xF0\x9F\x91\xB1", + 'man_with_gua_pi_mao' => "\xF0\x9F\x91\xB2", + 'man_with_turban' => "\xF0\x9F\x91\xB3", + 'older_man' => "\xF0\x9F\x91\xB4", + 'older_woman' => "\xF0\x9F\x91\xB5", + 'baby' => "\xF0\x9F\x91\xB6", + 'construction_worker' => "\xF0\x9F\x91\xB7", + 'princess' => "\xF0\x9F\x91\xB8", + 'japanese_ogre' => "\xF0\x9F\x91\xB9", + 'japanese_goblin' => "\xF0\x9F\x91\xBA", + 'ghost' => "\xF0\x9F\x91\xBB", + 'angel' => "\xF0\x9F\x91\xBC", + 'alien' => "\xF0\x9F\x91\xBD", + 'space_invader' => "\xF0\x9F\x91\xBE", + 'imp' => "\xF0\x9F\x91\xBF", + 'skull' => "\xF0\x9F\x92\x80", + 'information_desk_person' => "\xF0\x9F\x92\x81", + 'guardsman' => "\xF0\x9F\x92\x82", + 'dancer' => "\xF0\x9F\x92\x83", + 'lipstick' => "\xF0\x9F\x92\x84", + 'nail_care' => "\xF0\x9F\x92\x85", + 'massage' => "\xF0\x9F\x92\x86", + 'haircut' => "\xF0\x9F\x92\x87", + 'barber' => "\xF0\x9F\x92\x88", + 'syringe' => "\xF0\x9F\x92\x89", + 'pill' => "\xF0\x9F\x92\x8A", + 'kiss' => "\xF0\x9F\x92\x8B", + 'love_letter' => "\xF0\x9F\x92\x8C", + 'ring' => "\xF0\x9F\x92\x8D", + 'gem' => "\xF0\x9F\x92\x8E", + 'couplekiss' => "\xF0\x9F\x92\x8F", + 'bouquet' => "\xF0\x9F\x92\x90", + 'couple_with_heart' => "\xF0\x9F\x92\x91", + 'wedding' => "\xF0\x9F\x92\x92", + 'heartbeat' => "\xF0\x9F\x92\x93", + 'broken_heart' => "\xF0\x9F\x92\x94", + 'two_hearts' => "\xF0\x9F\x92\x95", + 'sparkling_heart' => "\xF0\x9F\x92\x96", + 'heartpulse' => "\xF0\x9F\x92\x97", + 'cupid' => "\xF0\x9F\x92\x98", + 'blue_heart' => "\xF0\x9F\x92\x99", + 'green_heart' => "\xF0\x9F\x92\x9A", + 'yellow_heart' => "\xF0\x9F\x92\x9B", + 'purple_heart' => "\xF0\x9F\x92\x9C", + 'gift_heart' => "\xF0\x9F\x92\x9D", + 'revolving_hearts' => "\xF0\x9F\x92\x9E", + 'heart_decoration' => "\xF0\x9F\x92\x9F", + 'diamond_shape_with_a_dot_inside' => "\xF0\x9F\x92\xA0", + 'bulb' => "\xF0\x9F\x92\xA1", + 'anger' => "\xF0\x9F\x92\xA2", + 'bomb' => "\xF0\x9F\x92\xA3", + 'zzz' => "\xF0\x9F\x92\xA4", + 'boom' => "\xF0\x9F\x92\xA5", + 'collision' => "\xF0\x9F\x92\xA5", + 'sweat_drops' => "\xF0\x9F\x92\xA6", + 'droplet' => "\xF0\x9F\x92\xA7", + 'dash' => "\xF0\x9F\x92\xA8", + 'poop' => "\xF0\x9F\x92\xA9", + 'shit' => "\xF0\x9F\x92\xA9", + 'hankey' => "\xF0\x9F\x92\xA9", + 'muscle' => "\xF0\x9F\x92\xAA", + 'dizzy' => "\xF0\x9F\x92\xAB", + 'speech_balloon' => "\xF0\x9F\x92\xAC", + 'thought_balloon' => "\xF0\x9F\x92\xAD", + 'white_flower' => "\xF0\x9F\x92\xAE", + '100' => "\xF0\x9F\x92\xAF", + 'moneybag' => "\xF0\x9F\x92\xB0", + 'currency_exchange' => "\xF0\x9F\x92\xB1", + 'heavy_dollar_sign' => "\xF0\x9F\x92\xB2", + 'credit_card' => "\xF0\x9F\x92\xB3", + 'yen' => "\xF0\x9F\x92\xB4", + 'dollar' => "\xF0\x9F\x92\xB5", + 'euro' => "\xF0\x9F\x92\xB6", + 'pound' => "\xF0\x9F\x92\xB7", + 'money_with_wings' => "\xF0\x9F\x92\xB8", + 'chart' => "\xF0\x9F\x92\xB9", + 'seat' => "\xF0\x9F\x92\xBA", + 'computer' => "\xF0\x9F\x92\xBB", + 'briefcase' => "\xF0\x9F\x92\xBC", + 'minidisc' => "\xF0\x9F\x92\xBD", + 'floppy_disk' => "\xF0\x9F\x92\xBE", + 'cd' => "\xF0\x9F\x92\xBF", + 'dvd' => "\xF0\x9F\x93\x80", + 'file_folder' => "\xF0\x9F\x93\x81", + 'open_file_folder' => "\xF0\x9F\x93\x82", + 'page_with_curl' => "\xF0\x9F\x93\x83", + 'page_facing_up' => "\xF0\x9F\x93\x84", + 'date' => "\xF0\x9F\x93\x85", + 'calendar' => "\xF0\x9F\x93\x86", + 'card_index' => "\xF0\x9F\x93\x87", + 'chart_with_upwards_trend' => "\xF0\x9F\x93\x88", + 'chart_with_downwards_trend' => "\xF0\x9F\x93\x89", + 'bar_chart' => "\xF0\x9F\x93\x8A", + 'clipboard' => "\xF0\x9F\x93\x8B", + 'pushpin' => "\xF0\x9F\x93\x8C", + 'round_pushpin' => "\xF0\x9F\x93\x8D", + 'paperclip' => "\xF0\x9F\x93\x8E", + 'straight_ruler' => "\xF0\x9F\x93\x8F", + 'triangular_ruler' => "\xF0\x9F\x93\x90", + 'bookmark_tabs' => "\xF0\x9F\x93\x91", + 'ledger' => "\xF0\x9F\x93\x92", + 'notebook' => "\xF0\x9F\x93\x93", + 'notebook_with_decorative_cover' => "\xF0\x9F\x93\x94", + 'closed_book' => "\xF0\x9F\x93\x95", + 'book' => "\xF0\x9F\x93\x96", + 'open_book' => "\xF0\x9F\x93\x96", + 'green_book' => "\xF0\x9F\x93\x97", + 'blue_book' => "\xF0\x9F\x93\x98", + 'orange_book' => "\xF0\x9F\x93\x99", + 'books' => "\xF0\x9F\x93\x9A", + 'name_badge' => "\xF0\x9F\x93\x9B", + 'scroll' => "\xF0\x9F\x93\x9C", + 'pencil' => "\xF0\x9F\x93\x9D", + 'memo' => "\xF0\x9F\x93\x9D", + 'telephone_receiver' => "\xF0\x9F\x93\x9E", + 'pager' => "\xF0\x9F\x93\x9F", + 'fax' => "\xF0\x9F\x93\xA0", + 'satellite' => "\xF0\x9F\x93\xA1", + 'loudspeaker' => "\xF0\x9F\x93\xA2", + 'mega' => "\xF0\x9F\x93\xA3", + 'outbox_tray' => "\xF0\x9F\x93\xA4", + 'inbox_tray' => "\xF0\x9F\x93\xA5", + 'package' => "\xF0\x9F\x93\xA6", + 'e_mail' => "\xF0\x9F\x93\xA7", + 'incoming_envelope' => "\xF0\x9F\x93\xA8", + 'envelope_with_arrow' => "\xF0\x9F\x93\xA9", + 'mailbox_closed' => "\xF0\x9F\x93\xAA", + 'mailbox' => "\xF0\x9F\x93\xAB", + 'mailbox_with_mail' => "\xF0\x9F\x93\xAC", + 'mailbox_with_no_mail' => "\xF0\x9F\x93\xAD", + 'postbox' => "\xF0\x9F\x93\xAE", + 'postal_horn' => "\xF0\x9F\x93\xAF", + 'newspaper' => "\xF0\x9F\x93\xB0", + 'iphone' => "\xF0\x9F\x93\xB1", + 'calling' => "\xF0\x9F\x93\xB2", + 'vibration_mode' => "\xF0\x9F\x93\xB3", + 'mobile_phone_off' => "\xF0\x9F\x93\xB4", + 'no_mobile_phones' => "\xF0\x9F\x93\xB5", + 'signal_strength' => "\xF0\x9F\x93\xB6", + 'camera' => "\xF0\x9F\x93\xB7", + 'video_camera' => "\xF0\x9F\x93\xB9", + 'tv' => "\xF0\x9F\x93\xBA", + 'radio' => "\xF0\x9F\x93\xBB", + 'vhs' => "\xF0\x9F\x93\xBC", + 'twisted_rightwards_arrows' => "\xF0\x9F\x94\x80", + 'repeat' => "\xF0\x9F\x94\x81", + 'repeat_one' => "\xF0\x9F\x94\x82", + 'arrows_clockwise' => "\xF0\x9F\x94\x83", + 'arrows_counterclockwise' => "\xF0\x9F\x94\x84", + 'low_brightness' => "\xF0\x9F\x94\x85", + 'high_brightness' => "\xF0\x9F\x94\x86", + 'mute' => "\xF0\x9F\x94\x87", + 'speaker' => "\xF0\x9F\x94\x88", + 'sound' => "\xF0\x9F\x94\x89", + 'loud_sound' => "\xF0\x9F\x94\x8A", + 'battery' => "\xF0\x9F\x94\x8B", + 'electric_plug' => "\xF0\x9F\x94\x8C", + 'mag' => "\xF0\x9F\x94\x8D", + 'mag_right' => "\xF0\x9F\x94\x8E", + 'lock_with_ink_pen' => "\xF0\x9F\x94\x8F", + 'closed_lock_with_key' => "\xF0\x9F\x94\x90", + 'key' => "\xF0\x9F\x94\x91", + 'lock' => "\xF0\x9F\x94\x92", + 'unlock' => "\xF0\x9F\x94\x93", + 'bell' => "\xF0\x9F\x94\x94", + 'no_bell' => "\xF0\x9F\x94\x95", + 'bookmark' => "\xF0\x9F\x94\x96", + 'link' => "\xF0\x9F\x94\x97", + 'radio_button' => "\xF0\x9F\x94\x98", + 'back' => "\xF0\x9F\x94\x99", + 'end' => "\xF0\x9F\x94\x9A", + 'on' => "\xF0\x9F\x94\x9B", + 'soon' => "\xF0\x9F\x94\x9C", + 'top' => "\xF0\x9F\x94\x9D", + 'underage' => "\xF0\x9F\x94\x9E", + 'keycap_ten' => "\xF0\x9F\x94\x9F", + 'capital_abcd' => "\xF0\x9F\x94\xA0", + 'abcd' => "\xF0\x9F\x94\xA1", + '1234' => "\xF0\x9F\x94\xA2", + 'symbols' => "\xF0\x9F\x94\xA3", + 'abc' => "\xF0\x9F\x94\xA4", + 'fire' => "\xF0\x9F\x94\xA5", + 'flashlight' => "\xF0\x9F\x94\xA6", + 'wrench' => "\xF0\x9F\x94\xA7", + 'hammer' => "\xF0\x9F\x94\xA8", + 'nut_and_bolt' => "\xF0\x9F\x94\xA9", + 'knife' => "\xF0\x9F\x94\xAA", + 'hocho' => "\xF0\x9F\x94\xAA", + 'gun' => "\xF0\x9F\x94\xAB", + 'microscope' => "\xF0\x9F\x94\xAC", + 'telescope' => "\xF0\x9F\x94\xAD", + 'crystal_ball' => "\xF0\x9F\x94\xAE", + 'six_pointed_star' => "\xF0\x9F\x94\xAF", + 'beginner' => "\xF0\x9F\x94\xB0", + 'trident' => "\xF0\x9F\x94\xB1", + 'black_square_button' => "\xF0\x9F\x94\xB2", + 'white_square_button' => "\xF0\x9F\x94\xB3", + 'red_circle' => "\xF0\x9F\x94\xB4", + 'large_blue_circle' => "\xF0\x9F\x94\xB5", + 'large_orange_diamond' => "\xF0\x9F\x94\xB6", + 'large_blue_diamond' => "\xF0\x9F\x94\xB7", + 'small_orange_diamond' => "\xF0\x9F\x94\xB8", + 'small_blue_diamond' => "\xF0\x9F\x94\xB9", + 'small_red_triangle' => "\xF0\x9F\x94\xBA", + 'small_red_triangle_down' => "\xF0\x9F\x94\xBB", + 'arrow_up_small' => "\xF0\x9F\x94\xBC", + 'arrow_down_small' => "\xF0\x9F\x94\xBD", + 'clock1' => "\xF0\x9F\x95\x90", + 'clock2' => "\xF0\x9F\x95\x91", + 'clock3' => "\xF0\x9F\x95\x92", + 'clock4' => "\xF0\x9F\x95\x93", + 'clock5' => "\xF0\x9F\x95\x94", + 'clock6' => "\xF0\x9F\x95\x95", + 'clock7' => "\xF0\x9F\x95\x96", + 'clock8' => "\xF0\x9F\x95\x97", + 'clock9' => "\xF0\x9F\x95\x98", + 'clock10' => "\xF0\x9F\x95\x99", + 'clock11' => "\xF0\x9F\x95\x9A", + 'clock12' => "\xF0\x9F\x95\x9B", + 'clock130' => "\xF0\x9F\x95\x9C", + 'clock230' => "\xF0\x9F\x95\x9D", + 'clock330' => "\xF0\x9F\x95\x9E", + 'clock430' => "\xF0\x9F\x95\x9F", + 'clock530' => "\xF0\x9F\x95\xA0", + 'clock630' => "\xF0\x9F\x95\xA1", + 'clock730' => "\xF0\x9F\x95\xA2", + 'clock830' => "\xF0\x9F\x95\xA3", + 'clock930' => "\xF0\x9F\x95\xA4", + 'clock1030' => "\xF0\x9F\x95\xA5", + 'clock1130' => "\xF0\x9F\x95\xA6", + 'clock1230' => "\xF0\x9F\x95\xA7", + 'mount_fuji' => "\xF0\x9F\x97\xBB", + 'tokyo_tower' => "\xF0\x9F\x97\xBC", + 'statue_of_liberty' => "\xF0\x9F\x97\xBD", + 'japan' => "\xF0\x9F\x97\xBE", + 'moyai' => "\xF0\x9F\x97\xBF", + 'grinning' => "\xF0\x9F\x98\x80", + 'grin' => "\xF0\x9F\x98\x81", + 'joy' => "\xF0\x9F\x98\x82", + 'smiley' => "\xF0\x9F\x98\x83", + 'smile' => "\xF0\x9F\x98\x84", + 'sweat_smile' => "\xF0\x9F\x98\x85", + 'satisfied' => "\xF0\x9F\x98\x86", + 'laughing' => "\xF0\x9F\x98\x86", + 'innocent' => "\xF0\x9F\x98\x87", + 'smiling_imp' => "\xF0\x9F\x98\x88", + 'wink' => "\xF0\x9F\x98\x89", + 'blush' => "\xF0\x9F\x98\x8A", + 'yum' => "\xF0\x9F\x98\x8B", + 'relieved' => "\xF0\x9F\x98\x8C", + 'heart_eyes' => "\xF0\x9F\x98\x8D", + 'sunglasses' => "\xF0\x9F\x98\x8E", + 'smirk' => "\xF0\x9F\x98\x8F", + 'neutral_face' => "\xF0\x9F\x98\x90", + 'expressionless' => "\xF0\x9F\x98\x91", + 'unamused' => "\xF0\x9F\x98\x92", + 'sweat' => "\xF0\x9F\x98\x93", + 'pensive' => "\xF0\x9F\x98\x94", + 'confused' => "\xF0\x9F\x98\x95", + 'confounded' => "\xF0\x9F\x98\x96", + 'kissing' => "\xF0\x9F\x98\x97", + 'kissing_heart' => "\xF0\x9F\x98\x98", + 'kissing_smiling_eyes' => "\xF0\x9F\x98\x99", + 'kissing_closed_eyes' => "\xF0\x9F\x98\x9A", + 'stuck_out_tongue' => "\xF0\x9F\x98\x9B", + 'stuck_out_tongue_winking_eye' => "\xF0\x9F\x98\x9C", + 'stuck_out_tongue_closed_eyes' => "\xF0\x9F\x98\x9D", + 'disappointed' => "\xF0\x9F\x98\x9E", + 'worried' => "\xF0\x9F\x98\x9F", + 'angry' => "\xF0\x9F\x98\xA0", + 'rage' => "\xF0\x9F\x98\xA1", + 'cry' => "\xF0\x9F\x98\xA2", + 'persevere' => "\xF0\x9F\x98\xA3", + 'triumph' => "\xF0\x9F\x98\xA4", + 'disappointed_relieved' => "\xF0\x9F\x98\xA5", + 'frowning' => "\xF0\x9F\x98\xA6", + 'anguished' => "\xF0\x9F\x98\xA7", + 'fearful' => "\xF0\x9F\x98\xA8", + 'weary' => "\xF0\x9F\x98\xA9", + 'sleepy' => "\xF0\x9F\x98\xAA", + 'tired_face' => "\xF0\x9F\x98\xAB", + 'grimacing' => "\xF0\x9F\x98\xAC", + 'sob' => "\xF0\x9F\x98\xAD", + 'open_mouth' => "\xF0\x9F\x98\xAE", + 'hushed' => "\xF0\x9F\x98\xAF", + 'cold_sweat' => "\xF0\x9F\x98\xB0", + 'scream' => "\xF0\x9F\x98\xB1", + 'astonished' => "\xF0\x9F\x98\xB2", + 'flushed' => "\xF0\x9F\x98\xB3", + 'sleeping' => "\xF0\x9F\x98\xB4", + 'dizzy_face' => "\xF0\x9F\x98\xB5", + 'no_mouth' => "\xF0\x9F\x98\xB6", + 'mask' => "\xF0\x9F\x98\xB7", + 'smile_cat' => "\xF0\x9F\x98\xB8", + 'joy_cat' => "\xF0\x9F\x98\xB9", + 'smiley_cat' => "\xF0\x9F\x98\xBA", + 'heart_eyes_cat' => "\xF0\x9F\x98\xBB", + 'smirk_cat' => "\xF0\x9F\x98\xBC", + 'kissing_cat' => "\xF0\x9F\x98\xBD", + 'pouting_cat' => "\xF0\x9F\x98\xBE", + 'crying_cat_face' => "\xF0\x9F\x98\xBF", + 'scream_cat' => "\xF0\x9F\x99\x80", + 'no_good' => "\xF0\x9F\x99\x85", + 'ok_woman' => "\xF0\x9F\x99\x86", + 'bow' => "\xF0\x9F\x99\x87", + 'see_no_evil' => "\xF0\x9F\x99\x88", + 'hear_no_evil' => "\xF0\x9F\x99\x89", + 'speak_no_evil' => "\xF0\x9F\x99\x8A", + 'raising_hand' => "\xF0\x9F\x99\x8B", + 'raised_hands' => "\xF0\x9F\x99\x8C", + 'person_frowning' => "\xF0\x9F\x99\x8D", + 'person_with_pouting_face' => "\xF0\x9F\x99\x8E", + 'pray' => "\xF0\x9F\x99\x8F", + 'rocket' => "\xF0\x9F\x9A\x80", + 'helicopter' => "\xF0\x9F\x9A\x81", + 'steam_locomotive' => "\xF0\x9F\x9A\x82", + 'railway_car' => "\xF0\x9F\x9A\x83", + 'bullettrain_side' => "\xF0\x9F\x9A\x84", + 'bullettrain_front' => "\xF0\x9F\x9A\x85", + 'train2' => "\xF0\x9F\x9A\x86", + 'metro' => "\xF0\x9F\x9A\x87", + 'light_rail' => "\xF0\x9F\x9A\x88", + 'station' => "\xF0\x9F\x9A\x89", + 'tram' => "\xF0\x9F\x9A\x8A", + 'train' => "\xF0\x9F\x9A\x8B", + 'bus' => "\xF0\x9F\x9A\x8C", + 'oncoming_bus' => "\xF0\x9F\x9A\x8D", + 'trolleybus' => "\xF0\x9F\x9A\x8E", + 'busstop' => "\xF0\x9F\x9A\x8F", + 'minibus' => "\xF0\x9F\x9A\x90", + 'ambulance' => "\xF0\x9F\x9A\x91", + 'fire_engine' => "\xF0\x9F\x9A\x92", + 'police_car' => "\xF0\x9F\x9A\x93", + 'oncoming_police_car' => "\xF0\x9F\x9A\x94", + 'taxi' => "\xF0\x9F\x9A\x95", + 'oncoming_taxi' => "\xF0\x9F\x9A\x96", + 'red_car' => "\xF0\x9F\x9A\x97", + 'car' => "\xF0\x9F\x9A\x97", + 'oncoming_automobile' => "\xF0\x9F\x9A\x98", + 'blue_car' => "\xF0\x9F\x9A\x99", + 'truck' => "\xF0\x9F\x9A\x9A", + 'articulated_lorry' => "\xF0\x9F\x9A\x9B", + 'tractor' => "\xF0\x9F\x9A\x9C", + 'monorail' => "\xF0\x9F\x9A\x9D", + 'mountain_railway' => "\xF0\x9F\x9A\x9E", + 'suspension_railway' => "\xF0\x9F\x9A\x9F", + 'mountain_cableway' => "\xF0\x9F\x9A\xA0", + 'aerial_tramway' => "\xF0\x9F\x9A\xA1", + 'ship' => "\xF0\x9F\x9A\xA2", + 'rowboat' => "\xF0\x9F\x9A\xA3", + 'speedboat' => "\xF0\x9F\x9A\xA4", + 'traffic_light' => "\xF0\x9F\x9A\xA5", + 'vertical_traffic_light' => "\xF0\x9F\x9A\xA6", + 'construction' => "\xF0\x9F\x9A\xA7", + 'rotating_light' => "\xF0\x9F\x9A\xA8", + 'triangular_flag_on_post' => "\xF0\x9F\x9A\xA9", + 'door' => "\xF0\x9F\x9A\xAA", + 'no_entry_sign' => "\xF0\x9F\x9A\xAB", + 'smoking' => "\xF0\x9F\x9A\xAC", + 'no_smoking' => "\xF0\x9F\x9A\xAD", + 'put_litter_in_its_place' => "\xF0\x9F\x9A\xAE", + 'do_not_litter' => "\xF0\x9F\x9A\xAF", + 'potable_water' => "\xF0\x9F\x9A\xB0", + 'non_potable_water' => "\xF0\x9F\x9A\xB1", + 'bike' => "\xF0\x9F\x9A\xB2", + 'no_bicycles' => "\xF0\x9F\x9A\xB3", + 'bicyclist' => "\xF0\x9F\x9A\xB4", + 'mountain_bicyclist' => "\xF0\x9F\x9A\xB5", + 'walking' => "\xF0\x9F\x9A\xB6", + 'no_pedestrians' => "\xF0\x9F\x9A\xB7", + 'children_crossing' => "\xF0\x9F\x9A\xB8", + 'mens' => "\xF0\x9F\x9A\xB9", + 'womens' => "\xF0\x9F\x9A\xBA", + 'restroom' => "\xF0\x9F\x9A\xBB", + 'baby_symbol' => "\xF0\x9F\x9A\xBC", + 'toilet' => "\xF0\x9F\x9A\xBD", + 'wc' => "\xF0\x9F\x9A\xBE", + 'shower' => "\xF0\x9F\x9A\xBF", + 'bath' => "\xF0\x9F\x9B\x80", + 'bathtub' => "\xF0\x9F\x9B\x81", + 'passport_control' => "\xF0\x9F\x9B\x82", + 'customs' => "\xF0\x9F\x9B\x83", + 'baggage_claim' => "\xF0\x9F\x9B\x84", + 'left_luggage' => "\xF0\x9F\x9B\x85", + 'copyright' => "\xC2\xA9\xEF\xB8\x8F", + 'registered' => "\xC2\xAE\xEF\xB8\x8F", + 'bangbang' => "\xE2\x80\xBC\xEF\xB8\x8F", + 'interrobang' => "\xE2\x81\x89\xEF\xB8\x8F", + 'tm' => "\xE2\x84\xA2\xEF\xB8\x8F", + 'information_source' => "\xE2\x84\xB9\xEF\xB8\x8F", + 'left_right_arrow' => "\xE2\x86\x94\xEF\xB8\x8F", + 'arrow_up_down' => "\xE2\x86\x95\xEF\xB8\x8F", + 'arrow_upper_left' => "\xE2\x86\x96\xEF\xB8\x8F", + 'arrow_upper_right' => "\xE2\x86\x97\xEF\xB8\x8F", + 'arrow_lower_right' => "\xE2\x86\x98\xEF\xB8\x8F", + 'arrow_lower_left' => "\xE2\x86\x99\xEF\xB8\x8F", + 'leftwards_arrow_with_hook' => "\xE2\x86\xA9\xEF\xB8\x8F", + 'arrow_right_hook' => "\xE2\x86\xAA\xEF\xB8\x8F", + 'm' => "\xE2\x93\x82\xEF\xB8\x8F", + 'black_small_square' => "\xE2\x96\xAA\xEF\xB8\x8F", + 'white_small_square' => "\xE2\x96\xAB\xEF\xB8\x8F", + 'arrow_forward' => "\xE2\x96\xB6\xEF\xB8\x8F", + 'arrow_backward' => "\xE2\x97\x80\xEF\xB8\x8F", + 'white_medium_square' => "\xE2\x97\xBB\xEF\xB8\x8F", + 'black_medium_square' => "\xE2\x97\xBC\xEF\xB8\x8F", + 'sunny' => "\xE2\x98\x80\xEF\xB8\x8F", + 'cloud' => "\xE2\x98\x81\xEF\xB8\x8F", + 'telephone' => "\xE2\x98\x8E\xEF\xB8\x8F", + 'phone' => "\xE2\x98\x8E\xEF\xB8\x8F", + 'ballot_box_with_check' => "\xE2\x98\x91\xEF\xB8\x8F", + 'point_up' => "\xE2\x98\x9D\xEF\xB8\x8F", + 'relaxed' => "\xE2\x98\xBA\xEF\xB8\x8F", + 'spades' => "\xE2\x99\xA0\xEF\xB8\x8F", + 'clubs' => "\xE2\x99\xA3\xEF\xB8\x8F", + 'hearts' => "\xE2\x99\xA5\xEF\xB8\x8F", + 'diamonds' => "\xE2\x99\xA6\xEF\xB8\x8F", + 'hotsprings' => "\xE2\x99\xA8\xEF\xB8\x8F", + 'recycle' => "\xE2\x99\xBB\xEF\xB8\x8F", + 'warning' => "\xE2\x9A\xA0\xEF\xB8\x8F", + 'baseball' => "\xE2\x9A\xBE\xEF\xB8\x8F", + 'scissors' => "\xE2\x9C\x82\xEF\xB8\x8F", + 'airplane' => "\xE2\x9C\x88\xEF\xB8\x8F", + 'email' => "\xE2\x9C\x89\xEF\xB8\x8F", + 'envelope' => "\xE2\x9C\x89\xEF\xB8\x8F", + 'v' => "\xE2\x9C\x8C\xEF\xB8\x8F", + 'pencil2' => "\xE2\x9C\x8F\xEF\xB8\x8F", + 'black_nib' => "\xE2\x9C\x92\xEF\xB8\x8F", + 'heavy_check_mark' => "\xE2\x9C\x94\xEF\xB8\x8F", + 'heavy_multiplication_x' => "\xE2\x9C\x96\xEF\xB8\x8F", + 'eight_spoked_asterisk' => "\xE2\x9C\xB3\xEF\xB8\x8F", + 'eight_pointed_black_star' => "\xE2\x9C\xB4\xEF\xB8\x8F", + 'snowflake' => "\xE2\x9D\x84\xEF\xB8\x8F", + 'sparkle' => "\xE2\x9D\x87\xEF\xB8\x8F", + 'heart' => "\xE2\x9D\xA4\xEF\xB8\x8F", + 'arrow_right' => "\xE2\x9E\xA1\xEF\xB8\x8F", + 'arrow_heading_up' => "\xE2\xA4\xB4\xEF\xB8\x8F", + 'arrow_heading_down' => "\xE2\xA4\xB5\xEF\xB8\x8F", + 'arrow_left' => "\xE2\xAC\x85\xEF\xB8\x8F", + 'arrow_up' => "\xE2\xAC\x86\xEF\xB8\x8F", + 'arrow_down' => "\xE2\xAC\x87\xEF\xB8\x8F", + 'wavy_dash' => "\xE3\x80\xB0\xEF\xB8\x8F", + 'part_alternation_mark' => "\xE3\x80\xBD\xEF\xB8\x8F", + 'congratulations' => "\xE3\x8A\x97\xEF\xB8\x8F", + 'secret' => "\xE3\x8A\x99\xEF\xB8\x8F", + 'hash' => "\x23\xEF\xB8\x8F\xE2\x83\xA3", + 'zero' => "\x30\xEF\xB8\x8F\xE2\x83\xA3", + 'one' => "\x31\xEF\xB8\x8F\xE2\x83\xA3", + 'two' => "\x32\xEF\xB8\x8F\xE2\x83\xA3", + 'three' => "\x33\xEF\xB8\x8F\xE2\x83\xA3", + 'four' => "\x34\xEF\xB8\x8F\xE2\x83\xA3", + 'five' => "\x35\xEF\xB8\x8F\xE2\x83\xA3", + 'six' => "\x36\xEF\xB8\x8F\xE2\x83\xA3", + 'seven' => "\x37\xEF\xB8\x8F\xE2\x83\xA3", + 'eight' => "\x38\xEF\xB8\x8F\xE2\x83\xA3", + 'nine' => "\x39\xEF\xB8\x8F\xE2\x83\xA3", + 'a' => "\xF0\x9F\x85\xB0\xEF\xB8\x8F", + 'b' => "\xF0\x9F\x85\xB1\xEF\xB8\x8F", + 'o2' => "\xF0\x9F\x85\xBE\xEF\xB8\x8F", + 'parking' => "\xF0\x9F\x85\xBF\xEF\xB8\x8F", + 'sa' => "\xF0\x9F\x88\x82\xEF\xB8\x8F", + 'u6708' => "\xF0\x9F\x88\xB7\xEF\xB8\x8F", + 'cn' => "\xF0\x9F\x87\xA8\xF0\x9F\x87\xB3", + 'de' => "\xF0\x9F\x87\xA9\xF0\x9F\x87\xAA", + 'es' => "\xF0\x9F\x87\xAA\xF0\x9F\x87\xB8", + 'fr' => "\xF0\x9F\x87\xAB\xF0\x9F\x87\xB7", + 'uk' => "\xF0\x9F\x87\xAC\xF0\x9F\x87\xA7", + 'gb' => "\xF0\x9F\x87\xAC\xF0\x9F\x87\xA7", + 'it' => "\xF0\x9F\x87\xAE\xF0\x9F\x87\xB9", + 'jp' => "\xF0\x9F\x87\xAF\xF0\x9F\x87\xB5", + 'kr' => "\xF0\x9F\x87\xB0\xF0\x9F\x87\xB7", + 'ru' => "\xF0\x9F\x87\xB7\xF0\x9F\x87\xBA", + 'us' => "\xF0\x9F\x87\xBA\xF0\x9F\x87\xB8", + ); + + $matches[1] = str_replace('-', '_', $matches[1]); + + if (isset($map[$matches[1]])) { + return $map[$matches[1]]; + } + + return $matches[0]; + } + +} diff --git a/src/applications/mailinglists/storage/PhabricatorMetaMTAMailingList.php b/src/applications/mailinglists/storage/PhabricatorMetaMTAMailingList.php index 794560e723..b2607e4848 100644 --- a/src/applications/mailinglists/storage/PhabricatorMetaMTAMailingList.php +++ b/src/applications/mailinglists/storage/PhabricatorMetaMTAMailingList.php @@ -17,6 +17,26 @@ final class PhabricatorMetaMTAMailingList extends PhabricatorMetaMTADAO public function getConfiguration() { return array( self::CONFIG_AUX_PHID => true, + self::CONFIG_COLUMN_SCHEMA => array( + 'name' => 'text255', + 'email' => 'text255', + 'uri' => 'text255?', + ), + self::CONFIG_KEY_SCHEMA => array( + 'key_phid' => null, + 'phid' => array( + 'columns' => array('phid'), + 'unique' => true, + ), + 'email' => array( + 'columns' => array('email'), + 'unique' => true, + ), + 'name' => array( + 'columns' => array('name'), + 'unique' => true, + ), + ), ) + parent::getConfiguration(); } diff --git a/src/applications/metamta/storage/PhabricatorMetaMTAMail.php b/src/applications/metamta/storage/PhabricatorMetaMTAMail.php index 7a055ed773..0dbd6eab00 100644 --- a/src/applications/metamta/storage/PhabricatorMetaMTAMail.php +++ b/src/applications/metamta/storage/PhabricatorMetaMTAMail.php @@ -32,6 +32,22 @@ final class PhabricatorMetaMTAMail extends PhabricatorMetaMTADAO { self::CONFIG_SERIALIZATION => array( 'parameters' => self::SERIALIZATION_JSON, ), + self::CONFIG_COLUMN_SCHEMA => array( + 'status' => 'text255', + 'message' => 'text', + 'relatedPHID' => 'phid?', + ), + self::CONFIG_KEY_SCHEMA => array( + 'status' => array( + 'columns' => array('status'), + ), + 'relatedPHID' => array( + 'columns' => array('relatedPHID'), + ), + 'key_created' => array( + 'columns' => array('dateCreated'), + ), + ), ) + parent::getConfiguration(); } diff --git a/src/applications/metamta/storage/PhabricatorMetaMTAReceivedMail.php b/src/applications/metamta/storage/PhabricatorMetaMTAReceivedMail.php index 742b4e1ee4..b3828fce24 100644 --- a/src/applications/metamta/storage/PhabricatorMetaMTAReceivedMail.php +++ b/src/applications/metamta/storage/PhabricatorMetaMTAReceivedMail.php @@ -19,6 +19,27 @@ final class PhabricatorMetaMTAReceivedMail extends PhabricatorMetaMTADAO { 'bodies' => self::SERIALIZATION_JSON, 'attachments' => self::SERIALIZATION_JSON, ), + self::CONFIG_COLUMN_SCHEMA => array( + 'relatedPHID' => 'phid?', + 'authorPHID' => 'phid?', + 'message' => 'text?', + 'messageIDHash' => 'bytes12', + 'status' => 'text32', + ), + self::CONFIG_KEY_SCHEMA => array( + 'relatedPHID' => array( + 'columns' => array('relatedPHID'), + ), + 'authorPHID' => array( + 'columns' => array('authorPHID'), + ), + 'key_messageIDHash' => array( + 'columns' => array('messageIDHash'), + ), + 'key_created' => array( + 'columns' => array('dateCreated'), + ), + ), ) + parent::getConfiguration(); } diff --git a/src/applications/metamta/storage/PhabricatorMetaMTASchemaSpec.php b/src/applications/metamta/storage/PhabricatorMetaMTASchemaSpec.php new file mode 100644 index 0000000000..4754a74c48 --- /dev/null +++ b/src/applications/metamta/storage/PhabricatorMetaMTASchemaSpec.php @@ -0,0 +1,14 @@ +buildLiskSchemata('PhabricatorMetaMTADAO'); + $this->buildLiskSchemata('PhabricatorSMSDAO'); + + $this->buildEdgeSchemata( + new PhabricatorMetaMTAMail()); + } + +} diff --git a/src/applications/nuance/storage/NuanceItem.php b/src/applications/nuance/storage/NuanceItem.php index 5f6193d1b0..fe02f7679a 100644 --- a/src/applications/nuance/storage/NuanceItem.php +++ b/src/applications/nuance/storage/NuanceItem.php @@ -22,12 +22,31 @@ final class NuanceItem ->setDateNuanced(time()) ->setStatus(NuanceItem::STATUS_OPEN); } + public function getConfiguration() { return array( self::CONFIG_AUX_PHID => true, self::CONFIG_SERIALIZATION => array( 'data' => self::SERIALIZATION_JSON, ), + self::CONFIG_COLUMN_SCHEMA => array( + 'ownerPHID' => 'phid?', + 'sourceLabel' => 'text255?', + 'status' => 'uint32', + 'mailKey' => 'bytes20', + 'dateNuanced' => 'epoch', + ), + self::CONFIG_KEY_SCHEMA => array( + 'key_source' => array( + 'columns' => array('sourcePHID', 'status', 'dateNuanced'), + ), + 'key_owner' => array( + 'columns' => array('ownerPHID', 'status', 'dateNuanced'), + ), + 'key_contacter' => array( + 'columns' => array('requestorPHID', 'status', 'dateNuanced'), + ), + ), ) + parent::getConfiguration(); } diff --git a/src/applications/nuance/storage/NuanceQueue.php b/src/applications/nuance/storage/NuanceQueue.php index 5871df8504..4a172a9401 100644 --- a/src/applications/nuance/storage/NuanceQueue.php +++ b/src/applications/nuance/storage/NuanceQueue.php @@ -12,6 +12,10 @@ final class NuanceQueue public function getConfiguration() { return array( self::CONFIG_AUX_PHID => true, + self::CONFIG_COLUMN_SCHEMA => array( + 'name' => 'text255?', + 'mailKey' => 'bytes20', + ), ) + parent::getConfiguration(); } diff --git a/src/applications/nuance/storage/NuanceQueueItem.php b/src/applications/nuance/storage/NuanceQueueItem.php index 92bbb51056..3fbaecd099 100644 --- a/src/applications/nuance/storage/NuanceQueueItem.php +++ b/src/applications/nuance/storage/NuanceQueueItem.php @@ -8,5 +8,22 @@ final class NuanceQueueItem protected $itemStatus; protected $itemDateNuanced; + public function getConfiguration() { + return array( + self::CONFIG_COLUMN_SCHEMA => array( + 'itemStatus' => 'uint32', + 'itemDateNuanced' => 'epoch', + ), + self::CONFIG_KEY_SCHEMA => array( + 'key_one_per_queue' => array( + 'columns' => array('itemPHID', 'queuePHID'), + 'unique' => true, + ), + 'key_queue' => array( + 'columns' => array('queuePHID', 'itemStatus', 'itemDateNuanced'), + ), + ), + ) + parent::getConfiguration(); + } } diff --git a/src/applications/nuance/storage/NuanceSchemaSpec.php b/src/applications/nuance/storage/NuanceSchemaSpec.php new file mode 100644 index 0000000000..993dfe63f6 --- /dev/null +++ b/src/applications/nuance/storage/NuanceSchemaSpec.php @@ -0,0 +1,27 @@ +buildLiskSchemata('NuanceDAO'); + $this->buildEdgeSchemata(new NuanceItem()); + + $this->buildTransactionSchema( + new NuanceItemTransaction(), + new NuanceItemTransactionComment()); + + $this->buildTransactionSchema( + new NuanceQueueTransaction(), + new NuanceQueueTransactionComment()); + + $this->buildTransactionSchema( + new NuanceRequestorTransaction(), + new NuanceRequestorTransactionComment()); + + $this->buildTransactionSchema( + new NuanceSourceTransaction(), + new NuanceSourceTransactionComment()); + } + +} diff --git a/src/applications/nuance/storage/NuanceSource.php b/src/applications/nuance/storage/NuanceSource.php index e6fc9da86b..025a60dd89 100644 --- a/src/applications/nuance/storage/NuanceSource.php +++ b/src/applications/nuance/storage/NuanceSource.php @@ -16,6 +16,16 @@ final class NuanceSource extends NuanceDAO self::CONFIG_SERIALIZATION => array( 'data' => self::SERIALIZATION_JSON, ), + self::CONFIG_COLUMN_SCHEMA => array( + 'name' => 'text255?', + 'type' => 'text32', + 'mailKey' => 'bytes20', + ), + self::CONFIG_KEY_SCHEMA => array( + 'key_type' => array( + 'columns' => array('type', 'dateModified'), + ), + ), ) + parent::getConfiguration(); } diff --git a/src/applications/oauthserver/storage/PhabricatorOAuthClientAuthorization.php b/src/applications/oauthserver/storage/PhabricatorOAuthClientAuthorization.php index c29c06eda2..505df7b2d7 100644 --- a/src/applications/oauthserver/storage/PhabricatorOAuthClientAuthorization.php +++ b/src/applications/oauthserver/storage/PhabricatorOAuthClientAuthorization.php @@ -23,6 +23,20 @@ final class PhabricatorOAuthClientAuthorization self::CONFIG_SERIALIZATION => array( 'scope' => self::SERIALIZATION_JSON, ), + self::CONFIG_COLUMN_SCHEMA => array( + 'scope' => 'text', + ), + self::CONFIG_KEY_SCHEMA => array( + 'key_phid' => null, + 'phid' => array( + 'columns' => array('phid'), + 'unique' => true, + ), + 'userPHID' => array( + 'columns' => array('userPHID', 'clientPHID'), + 'unique' => true, + ), + ), ) + parent::getConfiguration(); } diff --git a/src/applications/oauthserver/storage/PhabricatorOAuthSchemaSpec.php b/src/applications/oauthserver/storage/PhabricatorOAuthSchemaSpec.php new file mode 100644 index 0000000000..e7c8c002f1 --- /dev/null +++ b/src/applications/oauthserver/storage/PhabricatorOAuthSchemaSpec.php @@ -0,0 +1,10 @@ +buildLiskSchemata('PhabricatorOAuthServerDAO'); + } + +} diff --git a/src/applications/oauthserver/storage/PhabricatorOAuthServerAccessToken.php b/src/applications/oauthserver/storage/PhabricatorOAuthServerAccessToken.php index fd2e2d1080..1deadaa92b 100644 --- a/src/applications/oauthserver/storage/PhabricatorOAuthServerAccessToken.php +++ b/src/applications/oauthserver/storage/PhabricatorOAuthServerAccessToken.php @@ -7,4 +7,19 @@ final class PhabricatorOAuthServerAccessToken protected $token; protected $userPHID; protected $clientPHID; + + public function getConfiguration() { + return array( + self::CONFIG_COLUMN_SCHEMA => array( + 'token' => 'text32', + ), + self::CONFIG_KEY_SCHEMA => array( + 'token' => array( + 'columns' => array('token'), + 'unique' => true, + ), + ), + ) + parent::getConfiguration(); + } + } diff --git a/src/applications/oauthserver/storage/PhabricatorOAuthServerAuthorizationCode.php b/src/applications/oauthserver/storage/PhabricatorOAuthServerAuthorizationCode.php index bbc39d2bc4..32212d987d 100644 --- a/src/applications/oauthserver/storage/PhabricatorOAuthServerAuthorizationCode.php +++ b/src/applications/oauthserver/storage/PhabricatorOAuthServerAuthorizationCode.php @@ -9,4 +9,21 @@ final class PhabricatorOAuthServerAuthorizationCode protected $clientSecret; protected $userPHID; protected $redirectURI; + + public function getConfiguration() { + return array( + self::CONFIG_COLUMN_SCHEMA => array( + 'code' => 'text32', + 'clientSecret' => 'text32', + 'redirectURI' => 'text255', + ), + self::CONFIG_KEY_SCHEMA => array( + 'code' => array( + 'columns' => array('code'), + 'unique' => true, + ), + ), + ) + parent::getConfiguration(); + } + } diff --git a/src/applications/oauthserver/storage/PhabricatorOAuthServerClient.php b/src/applications/oauthserver/storage/PhabricatorOAuthServerClient.php index 1483ca5ce7..1316e5f017 100644 --- a/src/applications/oauthserver/storage/PhabricatorOAuthServerClient.php +++ b/src/applications/oauthserver/storage/PhabricatorOAuthServerClient.php @@ -30,6 +30,21 @@ final class PhabricatorOAuthServerClient public function getConfiguration() { return array( self::CONFIG_AUX_PHID => true, + self::CONFIG_COLUMN_SCHEMA => array( + 'name' => 'text255', + 'secret' => 'text32', + 'redirectURI' => 'text255', + ), + self::CONFIG_KEY_SCHEMA => array( + 'key_phid' => null, + 'phid' => array( + 'columns' => array('phid'), + 'unique' => true, + ), + 'creatorPHID' => array( + 'columns' => array('creatorPHID'), + ), + ), ) + parent::getConfiguration(); } diff --git a/src/applications/passphrase/controller/PassphraseCredentialViewController.php b/src/applications/passphrase/controller/PassphraseCredentialViewController.php index 12dcd64287..e99484a61b 100644 --- a/src/applications/passphrase/controller/PassphraseCredentialViewController.php +++ b/src/applications/passphrase/controller/PassphraseCredentialViewController.php @@ -47,6 +47,8 @@ final class PassphraseCredentialViewController extends PassphraseController { $actions = $this->buildActionView($credential, $type); $properties = $this->buildPropertyView($credential, $type, $actions); + $crumbs->setActionList($actions); + $box = id(new PHUIObjectBoxView()) ->setHeader($header) ->addPropertyList($properties); diff --git a/src/applications/passphrase/storage/PassphraseCredential.php b/src/applications/passphrase/storage/PassphraseCredential.php index 241da9ca41..641988714d 100644 --- a/src/applications/passphrase/storage/PassphraseCredential.php +++ b/src/applications/passphrase/storage/PassphraseCredential.php @@ -35,6 +35,29 @@ final class PassphraseCredential extends PassphraseDAO public function getConfiguration() { return array( self::CONFIG_AUX_PHID => true, + self::CONFIG_COLUMN_SCHEMA => array( + 'name' => 'text255', + 'credentialType' => 'text64', + 'providesType' => 'text64', + 'description' => 'text', + 'username' => 'text255', + 'secretID' => 'id?', + 'isDestroyed' => 'bool', + 'isLocked' => 'bool', + 'allowConduit' => 'bool', + ), + self::CONFIG_KEY_SCHEMA => array( + 'key_secret' => array( + 'columns' => array('secretID'), + 'unique' => true, + ), + 'key_type' => array( + 'columns' => array('credentialType'), + ), + 'key_provides' => array( + 'columns' => array('providesType'), + ), + ), ) + parent::getConfiguration(); } diff --git a/src/applications/passphrase/storage/PassphraseSchemaSpec.php b/src/applications/passphrase/storage/PassphraseSchemaSpec.php new file mode 100644 index 0000000000..a3dbfd8328 --- /dev/null +++ b/src/applications/passphrase/storage/PassphraseSchemaSpec.php @@ -0,0 +1,15 @@ +buildLiskSchemata('PassphraseDAO'); + + $this->buildTransactionSchema( + new PassphraseCredentialTransaction()); + + $this->buildEdgeSchemata(new PassphraseCredential()); + } + +} diff --git a/src/applications/paste/storage/PhabricatorPaste.php b/src/applications/paste/storage/PhabricatorPaste.php index 4e5ac1332e..9191f316a2 100644 --- a/src/applications/paste/storage/PhabricatorPaste.php +++ b/src/applications/paste/storage/PhabricatorPaste.php @@ -7,7 +7,9 @@ final class PhabricatorPaste extends PhabricatorPasteDAO PhabricatorFlaggableInterface, PhabricatorMentionableInterface, PhabricatorPolicyInterface, - PhabricatorProjectInterface { + PhabricatorProjectInterface, + PhabricatorDestructibleInterface, + PhabricatorApplicationTransactionInterface { protected $title; protected $authorPHID; @@ -41,6 +43,26 @@ final class PhabricatorPaste extends PhabricatorPasteDAO public function getConfiguration() { return array( self::CONFIG_AUX_PHID => true, + self::CONFIG_COLUMN_SCHEMA => array( + 'title' => 'text255', + 'language' => 'text64', + 'mailKey' => 'bytes20', + 'parentPHID' => 'phid?', + ), + self::CONFIG_KEY_SCHEMA => array( + 'parentPHID' => array( + 'columns' => array('parentPHID'), + ), + 'authorPHID' => array( + 'columns' => array('authorPHID'), + ), + 'key_dateCreated' => array( + 'columns' => array('dateCreated'), + ), + 'key_language' => array( + 'columns' => array('language'), + ), + ), ) + parent::getConfiguration(); } @@ -132,4 +154,40 @@ final class PhabricatorPaste extends PhabricatorPasteDAO return pht('The author of a paste can always view and edit it.'); } + +/* -( PhabricatorDestructibleInterface )----------------------------------- */ + + + public function destroyObjectPermanently( + PhabricatorDestructionEngine $engine) { + + if ($this->filePHID) { + $file = id(new PhabricatorFileQuery()) + ->setViewer(PhabricatorUser::getOmnipotentUser()) + ->withPHIDs(array($this->filePHID)) + ->executeOne(); + if ($file) { + $engine->destroyObject($file); + } + } + + $this->delete(); + } + + +/* -( PhabricatorApplicationTransactionInterface )------------------------- */ + + + public function getApplicationTransactionEditor() { + return new PhabricatorPasteEditor(); + } + + public function getApplicationTransactionObject() { + return $this; + } + + public function getApplicationTransactionTemplate() { + return new PhabricatorPasteTransaction(); + } + } diff --git a/src/applications/paste/storage/PhabricatorPasteSchemaSpec.php b/src/applications/paste/storage/PhabricatorPasteSchemaSpec.php new file mode 100644 index 0000000000..94df0246a3 --- /dev/null +++ b/src/applications/paste/storage/PhabricatorPasteSchemaSpec.php @@ -0,0 +1,16 @@ +buildLiskSchemata('PhabricatorPasteDAO'); + + $this->buildTransactionSchema( + new PhabricatorPasteTransaction(), + new PhabricatorPasteTransactionComment()); + + $this->buildEdgeSchemata(new PhabricatorPaste()); + } + +} diff --git a/src/applications/paste/storage/PhabricatorPasteTransactionComment.php b/src/applications/paste/storage/PhabricatorPasteTransactionComment.php index 145a375793..b50a9afc25 100644 --- a/src/applications/paste/storage/PhabricatorPasteTransactionComment.php +++ b/src/applications/paste/storage/PhabricatorPasteTransactionComment.php @@ -15,4 +15,13 @@ final class PhabricatorPasteTransactionComment return ($this->getTransactionPHID() != null); } + public function getConfiguration() { + $config = parent::getConfiguration(); + $config[self::CONFIG_COLUMN_SCHEMA] = array( + 'lineNumber' => 'uint32?', + 'lineLength' => 'uint32?', + ) + $config[self::CONFIG_COLUMN_SCHEMA]; + return $config; + } + } diff --git a/src/applications/people/controller/PhabricatorPeopleProfileController.php b/src/applications/people/controller/PhabricatorPeopleProfileController.php index 398ffe8f4c..4a4524d8aa 100644 --- a/src/applications/people/controller/PhabricatorPeopleProfileController.php +++ b/src/applications/people/controller/PhabricatorPeopleProfileController.php @@ -133,11 +133,20 @@ final class PhabricatorPeopleProfileController $crumbs->addTextCrumb($user->getUsername()); $crumbs->setActionList($actions); $feed = $this->renderUserFeed($user); - $calendar = $this->renderUserCalendar($user); + $cal_class = 'PhabricatorCalendarApplication'; + $classes = array(); + $classes[] = 'profile-activity-view'; + if (PhabricatorApplication::isClassInstalledForViewer($cal_class, $user)) { + $calendar = $this->renderUserCalendar($user); + $classes[] = 'profile-has-calendar'; + $classes[] = 'grouped'; + } else { + $calendar = null; + } $activity = phutil_tag( 'div', array( - 'class' => 'profile-activity-view grouped' + 'class' => implode($classes, ' '), ), array( $calendar, diff --git a/src/applications/phame/storage/PhameBlog.php b/src/applications/phame/storage/PhameBlog.php index b4c2d5a88a..beccfdc329 100644 --- a/src/applications/phame/storage/PhameBlog.php +++ b/src/applications/phame/storage/PhameBlog.php @@ -27,6 +27,23 @@ final class PhameBlog extends PhameDAO self::CONFIG_SERIALIZATION => array( 'configData' => self::SERIALIZATION_JSON, ), + self::CONFIG_COLUMN_SCHEMA => array( + 'name' => 'text64', + 'description' => 'text', + 'domain' => 'text255?', + 'joinPolicy' => 'policy', + ), + self::CONFIG_KEY_SCHEMA => array( + 'key_phid' => null, + 'phid' => array( + 'columns' => array('phid'), + 'unique' => true, + ), + 'domain' => array( + 'columns' => array('domain'), + 'unique' => true, + ), + ), ) + parent::getConfiguration(); } diff --git a/src/applications/phame/storage/PhamePost.php b/src/applications/phame/storage/PhamePost.php index a60b9d361c..bef665b7d6 100644 --- a/src/applications/phame/storage/PhamePost.php +++ b/src/applications/phame/storage/PhamePost.php @@ -88,6 +88,27 @@ final class PhamePost extends PhameDAO self::CONFIG_SERIALIZATION => array( 'configData' => self::SERIALIZATION_JSON, ), + self::CONFIG_COLUMN_SCHEMA => array( + 'title' => 'text255', + 'phameTitle' => 'text64', + 'body' => 'text', + 'visibility' => 'uint32', + 'datePublished' => 'epoch?', + ), + self::CONFIG_KEY_SCHEMA => array( + 'key_phid' => null, + 'phid' => array( + 'columns' => array('phid'), + 'unique' => true, + ), + 'phameTitle' => array( + 'columns' => array('bloggerPHID', 'phameTitle'), + 'unique' => true, + ), + 'bloggerPosts' => array( + 'columns' => array('bloggerPHID', 'visibility', 'datePublished'), + ), + ), ) + parent::getConfiguration(); } diff --git a/src/applications/phame/storage/PhameSchemaSpec.php b/src/applications/phame/storage/PhameSchemaSpec.php new file mode 100644 index 0000000000..7897316bf2 --- /dev/null +++ b/src/applications/phame/storage/PhameSchemaSpec.php @@ -0,0 +1,11 @@ +buildLiskSchemata('PhameDAO'); + $this->buildEdgeSchemata(new PhameBlog()); + } + +} diff --git a/src/applications/phlux/storage/PhluxSchemaSpec.php b/src/applications/phlux/storage/PhluxSchemaSpec.php new file mode 100644 index 0000000000..b243d94fe1 --- /dev/null +++ b/src/applications/phlux/storage/PhluxSchemaSpec.php @@ -0,0 +1,11 @@ +buildLiskSchemata('PhluxDAO'); + $this->buildTransactionSchema(new PhluxTransaction()); + } + +} diff --git a/src/applications/phlux/storage/PhluxVariable.php b/src/applications/phlux/storage/PhluxVariable.php index 88aa3ac22a..23a0ffcc82 100644 --- a/src/applications/phlux/storage/PhluxVariable.php +++ b/src/applications/phlux/storage/PhluxVariable.php @@ -16,6 +16,15 @@ final class PhluxVariable extends PhluxDAO self::CONFIG_SERIALIZATION => array( 'variableValue' => self::SERIALIZATION_JSON ), + self::CONFIG_COLUMN_SCHEMA => array( + 'variableKey' => 'text64', + ), + self::CONFIG_KEY_SCHEMA => array( + 'key_key' => array( + 'columns' => array('variableKey'), + 'unique' => true, + ), + ), ) + parent::getConfiguration(); } diff --git a/src/applications/policy/__tests__/PhabricatorPolicyDataTestCase.php b/src/applications/policy/__tests__/PhabricatorPolicyDataTestCase.php index 1e74f8bc9e..7f3c22666d 100644 --- a/src/applications/policy/__tests__/PhabricatorPolicyDataTestCase.php +++ b/src/applications/policy/__tests__/PhabricatorPolicyDataTestCase.php @@ -16,12 +16,14 @@ final class PhabricatorPolicyDataTestCase extends PhabricatorTestCase { ->setAuthorPHID($author->getPHID()) ->setIcon(PhabricatorProject::DEFAULT_ICON) ->setColor(PhabricatorProject::DEFAULT_COLOR) + ->setIsMembershipLocked(0) ->save(); $proj_b = id(new PhabricatorProject()) ->setName('B') ->setAuthorPHID($author->getPHID()) ->setIcon(PhabricatorProject::DEFAULT_ICON) ->setColor(PhabricatorProject::DEFAULT_COLOR) + ->setIsMembershipLocked(0) ->save(); $proj_a->setViewPolicy($proj_b->getPHID())->save(); diff --git a/src/applications/ponder/storage/PonderAnswerTransaction.php b/src/applications/ponder/storage/PonderAnswerTransaction.php index e1a7c029a2..b9c7bf2190 100644 --- a/src/applications/ponder/storage/PonderAnswerTransaction.php +++ b/src/applications/ponder/storage/PonderAnswerTransaction.php @@ -33,6 +33,18 @@ final class PonderAnswerTransaction return $phids; } + public function getRemarkupBlocks() { + $blocks = parent::getRemarkupBlocks(); + + switch ($this->getTransactionType()) { + case self::TYPE_CONTENT: + $blocks[] = $this->getNewValue(); + break; + } + + return $blocks; + } + public function getTitle() { $author_phid = $this->getAuthorPHID(); $object_phid = $this->getObjectPHID(); diff --git a/src/applications/ponder/storage/PonderQuestionTransaction.php b/src/applications/ponder/storage/PonderQuestionTransaction.php index 9bfaf6a741..19590838c4 100644 --- a/src/applications/ponder/storage/PonderQuestionTransaction.php +++ b/src/applications/ponder/storage/PonderQuestionTransaction.php @@ -37,6 +37,18 @@ final class PonderQuestionTransaction return $phids; } + public function getRemarkupBlocks() { + $blocks = parent::getRemarkupBlocks(); + + switch ($this->getTransactionType()) { + case self::TYPE_CONTENT: + $blocks[] = $this->getNewValue(); + break; + } + + return $blocks; + } + public function getTitle() { $author_phid = $this->getAuthorPHID(); $object_phid = $this->getObjectPHID(); diff --git a/src/applications/releeph/application/PhabricatorReleephApplication.php b/src/applications/releeph/application/PhabricatorReleephApplication.php index 91e8246f85..e04337f912 100644 --- a/src/applications/releeph/application/PhabricatorReleephApplication.php +++ b/src/applications/releeph/application/PhabricatorReleephApplication.php @@ -18,11 +18,8 @@ final class PhabricatorReleephApplication extends PhabricatorApplication { return 'releeph'; } - public function isInstalled() { - if (PhabricatorEnv::getEnvConfig('releeph.installed')) { - return parent::isInstalled(); - } - return false; + public function isPrototype() { + return true; } public function getRoutes() { diff --git a/src/applications/releeph/config/PhabricatorReleephApplicationConfigOptions.php b/src/applications/releeph/config/PhabricatorReleephApplicationConfigOptions.php index 6f54a7ceb2..dc62b59166 100644 --- a/src/applications/releeph/config/PhabricatorReleephApplicationConfigOptions.php +++ b/src/applications/releeph/config/PhabricatorReleephApplicationConfigOptions.php @@ -42,19 +42,6 @@ final class PhabricatorReleephApplicationConfigOptions $custom_field_type = 'custom:PhabricatorCustomFieldConfigOptionType'; return array( - $this->newOption('releeph.installed', 'bool', false) - ->setSummary(pht('Enable the Releeph application.')) - ->setDescription( - pht( - 'Releeph, a tool for managing release branches, will eventually '. - 'fit in to the Phabricator suite as a general purpose tool. '. - 'However Releeph is currently unstable in multiple ways that may '. - 'not migrate properly for you: the code is still in alpha stage '. - 'of design, the storage format is likely to change in unexpected '. - 'ways, and the workflows presented are very specific to a core '. - 'set of alpha testers at Facebook. For the time being you are '. - 'strongly discouraged from relying on Releeph being at all '. - 'stable.')), $this->newOption('releeph.fields', $custom_field_type, $default) ->setCustomData('ReleephFieldSpecification'), $this->newOption( diff --git a/src/applications/releeph/storage/ReleephBranch.php b/src/applications/releeph/storage/ReleephBranch.php index 647406f1a2..f6cb1834c9 100644 --- a/src/applications/releeph/storage/ReleephBranch.php +++ b/src/applications/releeph/storage/ReleephBranch.php @@ -29,6 +29,26 @@ final class ReleephBranch extends ReleephDAO self::CONFIG_SERIALIZATION => array( 'details' => self::SERIALIZATION_JSON, ), + self::CONFIG_COLUMN_SCHEMA => array( + 'basename' => 'text64', + 'isActive' => 'bool', + 'symbolicName' => 'text64?', + 'name' => 'text128', + ), + self::CONFIG_KEY_SCHEMA => array( + 'releephProjectID' => array( + 'columns' => array('releephProjectID', 'symbolicName'), + 'unique' => true, + ), + 'releephProjectID_2' => array( + 'columns' => array('releephProjectID', 'basename'), + 'unique' => true, + ), + 'releephProjectID_name' => array( + 'columns' => array('releephProjectID', 'name'), + 'unique' => true, + ), + ), ) + parent::getConfiguration(); } diff --git a/src/applications/releeph/storage/ReleephProject.php b/src/applications/releeph/storage/ReleephProject.php index f52b847eb0..0465541c60 100644 --- a/src/applications/releeph/storage/ReleephProject.php +++ b/src/applications/releeph/storage/ReleephProject.php @@ -29,6 +29,17 @@ final class ReleephProject extends ReleephDAO self::CONFIG_SERIALIZATION => array( 'details' => self::SERIALIZATION_JSON, ), + self::CONFIG_COLUMN_SCHEMA => array( + 'name' => 'text255', + 'trunkBranch' => 'text255', + 'isActive' => 'bool', + ), + self::CONFIG_KEY_SCHEMA => array( + 'projectName' => array( + 'columns' => array('name'), + 'unique' => true, + ), + ), ) + parent::getConfiguration(); } diff --git a/src/applications/releeph/storage/ReleephRequest.php b/src/applications/releeph/storage/ReleephRequest.php index 2c495099b6..09cc903d48 100644 --- a/src/applications/releeph/storage/ReleephRequest.php +++ b/src/applications/releeph/storage/ReleephRequest.php @@ -153,6 +153,31 @@ final class ReleephRequest extends ReleephDAO 'details' => self::SERIALIZATION_JSON, 'userIntents' => self::SERIALIZATION_JSON, ), + self::CONFIG_COLUMN_SCHEMA => array( + 'summary' => 'text', + 'requstCommitPHID' => 'phid?', + 'commitIdentifier' => 'text40', + 'pickStatus' => 'uint32', + 'inBranch' => 'bool', + 'mailKey' => 'bytes20', + ), + self::CONFIG_KEY_SCHEMA => array( + 'key_phid' => null, + 'phid' => array( + 'columns' => array('phid'), + 'unique' => true, + ), + 'requestIdentifierBranch' => array( + 'columns' => array('requestCommitPHID', 'branchID'), + 'unique' => true, + ), + 'branchID' => array( + 'columns' => array('branchID'), + ), + 'key_requestedObject' => array( + 'columns' => array('requestedObjectPHID'), + ), + ), ) + parent::getConfiguration(); } diff --git a/src/applications/releeph/storage/ReleephSchemaSpec.php b/src/applications/releeph/storage/ReleephSchemaSpec.php new file mode 100644 index 0000000000..346c4355fc --- /dev/null +++ b/src/applications/releeph/storage/ReleephSchemaSpec.php @@ -0,0 +1,20 @@ +buildLiskSchemata('ReleephDAO'); + + $this->buildTransactionSchema( + new ReleephProductTransaction()); + + $this->buildTransactionSchema( + new ReleephBranchTransaction()); + + $this->buildTransactionSchema( + new ReleephRequestTransaction(), + new ReleephRequestTransactionComment()); + } + +} diff --git a/src/applications/repository/storage/PhabricatorRepository.php b/src/applications/repository/storage/PhabricatorRepository.php index 10f225173f..858729d6dd 100644 --- a/src/applications/repository/storage/PhabricatorRepository.php +++ b/src/applications/repository/storage/PhabricatorRepository.php @@ -29,6 +29,7 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO const TABLE_BADCOMMIT = 'repository_badcommit'; const TABLE_LINTMESSAGE = 'repository_lintmessage'; const TABLE_PARENTS = 'repository_parents'; + const TABLE_COVERAGE = 'repository_coverage'; const SERVE_OFF = 'off'; const SERVE_READONLY = 'readonly'; @@ -77,6 +78,31 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO self::CONFIG_SERIALIZATION => array( 'details' => self::SERIALIZATION_JSON, ), + self::CONFIG_COLUMN_SCHEMA => array( + 'name' => 'text255', + 'callsign' => 'text32', + 'versionControlSystem' => 'text32', + 'uuid' => 'text64?', + 'pushPolicy' => 'policy', + 'credentialPHID' => 'phid?', + ), + self::CONFIG_KEY_SCHEMA => array( + 'key_phid' => null, + 'phid' => array( + 'columns' => array('phid'), + 'unique' => true, + ), + 'callsign' => array( + 'columns' => array('callsign'), + 'unique' => true, + ), + 'key_name' => array( + 'columns' => array('name'), + ), + 'key_vcs' => array( + 'columns' => array('versionControlSystem'), + ), + ), ) + parent::getConfiguration(); } diff --git a/src/applications/repository/storage/PhabricatorRepositoryArcanistProject.php b/src/applications/repository/storage/PhabricatorRepositoryArcanistProject.php index b325cc245a..9f51be32c1 100644 --- a/src/applications/repository/storage/PhabricatorRepositoryArcanistProject.php +++ b/src/applications/repository/storage/PhabricatorRepositoryArcanistProject.php @@ -22,6 +22,21 @@ final class PhabricatorRepositoryArcanistProject 'symbolIndexLanguages' => self::SERIALIZATION_JSON, 'symbolIndexProjects' => self::SERIALIZATION_JSON, ), + self::CONFIG_COLUMN_SCHEMA => array( + 'name' => 'text255', + 'repositoryID' => 'id?', + ), + self::CONFIG_KEY_SCHEMA => array( + 'key_phid' => null, + 'phid' => array( + 'columns' => array('phid'), + 'unique' => true, + ), + 'name' => array( + 'columns' => array('name'), + 'unique' => true, + ), + ), ) + parent::getConfiguration(); } diff --git a/src/applications/repository/storage/PhabricatorRepositoryAuditRequest.php b/src/applications/repository/storage/PhabricatorRepositoryAuditRequest.php index 78d969f746..9752529253 100644 --- a/src/applications/repository/storage/PhabricatorRepositoryAuditRequest.php +++ b/src/applications/repository/storage/PhabricatorRepositoryAuditRequest.php @@ -17,6 +17,17 @@ final class PhabricatorRepositoryAuditRequest self::CONFIG_SERIALIZATION => array( 'auditReasons' => self::SERIALIZATION_JSON, ), + self::CONFIG_COLUMN_SCHEMA => array( + 'auditStatus' => 'text64', + ), + self::CONFIG_KEY_SCHEMA => array( + 'commitPHID' => array( + 'columns' => array('commitPHID'), + ), + 'auditorPHID' => array( + 'columns' => array('auditorPHID', 'auditStatus'), + ), + ), ) + parent::getConfiguration(); } diff --git a/src/applications/repository/storage/PhabricatorRepositoryBranch.php b/src/applications/repository/storage/PhabricatorRepositoryBranch.php index 5eb4d1f46f..c6eccb902a 100644 --- a/src/applications/repository/storage/PhabricatorRepositoryBranch.php +++ b/src/applications/repository/storage/PhabricatorRepositoryBranch.php @@ -6,6 +6,21 @@ final class PhabricatorRepositoryBranch extends PhabricatorRepositoryDAO { protected $name; protected $lintCommit; + public function getConfiguration() { + return array( + self::CONFIG_COLUMN_SCHEMA => array( + 'name' => 'text255', + 'lintCommit' => 'text40?', + ), + self::CONFIG_KEY_SCHEMA => array( + 'repositoryID' => array( + 'columns' => array('repositoryID', 'name'), + 'unique' => true, + ), + ), + ) + parent::getConfiguration(); + } + public static function loadBranch($repository_id, $branch_name) { return id(new PhabricatorRepositoryBranch())->loadOneWhere( 'repositoryID = %d AND name = %s', diff --git a/src/applications/repository/storage/PhabricatorRepositoryCommit.php b/src/applications/repository/storage/PhabricatorRepositoryCommit.php index cea1c9ad39..159177c8e9 100644 --- a/src/applications/repository/storage/PhabricatorRepositoryCommit.php +++ b/src/applications/repository/storage/PhabricatorRepositoryCommit.php @@ -66,6 +66,34 @@ final class PhabricatorRepositoryCommit return array( self::CONFIG_AUX_PHID => true, self::CONFIG_TIMESTAMPS => false, + self::CONFIG_COLUMN_SCHEMA => array( + 'commitIdentifier' => 'text40', + 'mailKey' => 'bytes20', + 'authorPHID' => 'phid?', + 'auditStatus' => 'uint32', + 'summary' => 'text80', + 'importStatus' => 'uint32', + ), + self::CONFIG_KEY_SCHEMA => array( + 'key_phid' => null, + 'phid' => array( + 'columns' => array('phid'), + 'unique' => true, + ), + 'repositoryID' => array( + 'columns' => array('repositoryID', 'importStatus'), + ), + 'authorPHID' => array( + 'columns' => array('authorPHID', 'auditStatus', 'epoch'), + ), + 'repositoryID_2' => array( + 'columns' => array('repositoryID', 'epoch'), + ), + 'key_commit_identity' => array( + 'columns' => array('commitIdentifier', 'repositoryID'), + 'unique' => true, + ), + ), ) + parent::getConfiguration(); } diff --git a/src/applications/repository/storage/PhabricatorRepositoryCommitData.php b/src/applications/repository/storage/PhabricatorRepositoryCommitData.php index 499e16ab78..474a8a239d 100644 --- a/src/applications/repository/storage/PhabricatorRepositoryCommitData.php +++ b/src/applications/repository/storage/PhabricatorRepositoryCommitData.php @@ -19,6 +19,19 @@ final class PhabricatorRepositoryCommitData extends PhabricatorRepositoryDAO { self::CONFIG_SERIALIZATION => array( 'commitDetails' => self::SERIALIZATION_JSON, ), + self::CONFIG_COLUMN_SCHEMA => array( + 'authorName' => 'text255', + 'commitMessage' => 'text', + ), + self::CONFIG_KEY_SCHEMA => array( + 'commitID' => array( + 'columns' => array('commitID'), + 'unique' => true, + ), + 'authorName' => array( + 'columns' => array('authorName'), + ), + ), ) + parent::getConfiguration(); } diff --git a/src/applications/repository/storage/PhabricatorRepositoryMirror.php b/src/applications/repository/storage/PhabricatorRepositoryMirror.php index d215a83d03..b778806f33 100644 --- a/src/applications/repository/storage/PhabricatorRepositoryMirror.php +++ b/src/applications/repository/storage/PhabricatorRepositoryMirror.php @@ -17,6 +17,15 @@ final class PhabricatorRepositoryMirror extends PhabricatorRepositoryDAO public function getConfiguration() { return array( self::CONFIG_AUX_PHID => true, + self::CONFIG_COLUMN_SCHEMA => array( + 'remoteURI' => 'text255', + 'credentialPHID' => 'phid?', + ), + self::CONFIG_KEY_SCHEMA => array( + 'key_repository' => array( + 'columns' => array('repositoryPHID'), + ), + ), ) + parent::getConfiguration(); } diff --git a/src/applications/repository/storage/PhabricatorRepositoryPushEvent.php b/src/applications/repository/storage/PhabricatorRepositoryPushEvent.php index b2539a2283..cb8cfe057f 100644 --- a/src/applications/repository/storage/PhabricatorRepositoryPushEvent.php +++ b/src/applications/repository/storage/PhabricatorRepositoryPushEvent.php @@ -28,6 +28,17 @@ final class PhabricatorRepositoryPushEvent return array( self::CONFIG_AUX_PHID => true, self::CONFIG_TIMESTAMPS => false, + self::CONFIG_COLUMN_SCHEMA => array( + 'remoteAddress' => 'uint32?', + 'remoteProtocol' => 'text32?', + 'rejectCode' => 'uint32', + 'rejectDetails' => 'text64?', + ), + self::CONFIG_KEY_SCHEMA => array( + 'key_repository' => array( + 'columns' => array('repositoryPHID'), + ), + ), ) + parent::getConfiguration(); } diff --git a/src/applications/repository/storage/PhabricatorRepositoryPushLog.php b/src/applications/repository/storage/PhabricatorRepositoryPushLog.php index a96f89c498..721003f933 100644 --- a/src/applications/repository/storage/PhabricatorRepositoryPushLog.php +++ b/src/applications/repository/storage/PhabricatorRepositoryPushLog.php @@ -71,6 +71,33 @@ final class PhabricatorRepositoryPushLog self::CONFIG_BINARY => array( 'refNameRaw' => true, ), + self::CONFIG_COLUMN_SCHEMA => array( + 'refType' => 'text12', + 'refNameHash' => 'bytes12?', + 'refNameRaw' => 'bytes?', + 'refNameEncoding' => 'text16?', + 'refOld' => 'text40?', + 'refNew' => 'text40', + 'mergeBase' => 'text40?', + 'changeFlags' => 'uint32', + ), + self::CONFIG_KEY_SCHEMA => array( + 'key_repository' => array( + 'columns' => array('repositoryPHID'), + ), + 'key_ref' => array( + 'columns' => array('repositoryPHID', 'refNew'), + ), + 'key_name' => array( + 'columns' => array('repositoryPHID', 'refNameHash'), + ), + 'key_event' => array( + 'columns' => array('pushEventPHID'), + ), + 'key_pusher' => array( + 'columns' => array('pusherPHID'), + ), + ), ) + parent::getConfiguration(); } diff --git a/src/applications/repository/storage/PhabricatorRepositoryRefCursor.php b/src/applications/repository/storage/PhabricatorRepositoryRefCursor.php index 7cc6eeaa9e..7a9acb9912 100644 --- a/src/applications/repository/storage/PhabricatorRepositoryRefCursor.php +++ b/src/applications/repository/storage/PhabricatorRepositoryRefCursor.php @@ -27,6 +27,17 @@ final class PhabricatorRepositoryRefCursor extends PhabricatorRepositoryDAO self::CONFIG_BINARY => array( 'refNameRaw' => true, ), + self::CONFIG_COLUMN_SCHEMA => array( + 'refType' => 'text32', + 'refNameHash' => 'bytes12', + 'refNameEncoding' => 'text16', + 'commitIdentifier' => 'text40', + ), + self::CONFIG_KEY_SCHEMA => array( + 'key_cursor' => array( + 'columns' => array('repositoryPHID', 'refType', 'refNameHash'), + ), + ), ) + parent::getConfiguration(); } diff --git a/src/applications/repository/storage/PhabricatorRepositorySchemaSpec.php b/src/applications/repository/storage/PhabricatorRepositorySchemaSpec.php new file mode 100644 index 0000000000..92014e738e --- /dev/null +++ b/src/applications/repository/storage/PhabricatorRepositorySchemaSpec.php @@ -0,0 +1,185 @@ +buildLiskSchemata('PhabricatorRepositoryDAO'); + + $this->buildEdgeSchemata(new PhabricatorRepository()); + + $this->buildTransactionSchema( + new PhabricatorRepositoryTransaction()); + + $this->buildRawSchema( + id(new PhabricatorRepository())->getApplicationName(), + PhabricatorRepository::TABLE_BADCOMMIT, + array( + 'fullCommitName' => 'text255', + 'description' => 'text', + ), + array( + 'PRIMARY' => array( + 'columns' => array('fullCommitName'), + 'unique' => true, + ), + )); + + $this->buildRawSchema( + id(new PhabricatorRepository())->getApplicationName(), + PhabricatorRepository::TABLE_COVERAGE, + array( + 'id' => 'id', + 'branchID' => 'id', + 'commitID' => 'id', + 'pathID' => 'id', + 'coverage' => 'bytes', + ), + array( + 'PRIMARY' => array( + 'columns' => array('id'), + 'unique' => true, + ), + 'key_path' => array( + 'columns' => array('branchID', 'pathID', 'commitID'), + ), + )); + + $this->buildRawSchema( + id(new PhabricatorRepository())->getApplicationName(), + PhabricatorRepository::TABLE_FILESYSTEM, + array( + 'repositoryID' => 'id', + 'parentID' => 'id', + 'svnCommit' => 'uint32', + 'pathID' => 'id', + 'existed' => 'bool', + 'fileType' => 'uint32', + ), + array( + 'PRIMARY' => array( + 'columns' => array('repositoryID', 'parentID', 'pathID', 'svnCommit'), + 'unique' => true, + ), + 'repositoryID' => array( + 'columns' => array('repositoryID', 'svnCommit'), + ), + )); + + $this->buildRawSchema( + id(new PhabricatorRepository())->getApplicationName(), + PhabricatorRepository::TABLE_LINTMESSAGE, + array( + 'id' => 'id', + 'branchID' => 'id', + 'path' => 'text', + 'line' => 'uint32', + 'authorPHID' => 'phid?', + 'code' => 'text32', + 'severity' => 'text16', + 'name' => 'text255', + 'description' => 'text', + ), + array( + 'PRIMARY' => array( + 'columns' => array('id'), + 'unique' => true, + ), + 'branchID' => array( + 'columns' => array('branchID', 'path(64)'), + ), + 'branchID_2' => array( + 'columns' => array('branchID', 'code', 'path(64)'), + ), + 'key_author' => array( + 'columns' => array('authorPHID'), + ), + )); + + $this->buildRawSchema( + id(new PhabricatorRepository())->getApplicationName(), + PhabricatorRepository::TABLE_PARENTS, + array( + 'id' => 'id', + 'childCommitID' => 'id', + 'parentCommitID' => 'id', + ), + array( + 'PRIMARY' => array( + 'columns' => array('id'), + 'unique' => true, + ), + 'key_child' => array( + 'columns' => array('childCommitID', 'parentCommitID'), + 'unique' => true, + ), + 'key_parent' => array( + 'columns' => array('parentCommitID'), + ), + )); + + $this->buildRawSchema( + id(new PhabricatorRepository())->getApplicationName(), + PhabricatorRepository::TABLE_PATH, + array( + 'id' => 'id', + 'path' => 'text', + 'pathHash' => 'bytes32', + ), + array( + 'PRIMARY' => array( + 'columns' => array('id'), + 'unique' => true, + ), + 'pathHash' => array( + 'columns' => array('pathHash'), + 'unique' => true, + ), + )); + + $this->buildRawSchema( + id(new PhabricatorRepository())->getApplicationName(), + PhabricatorRepository::TABLE_PATHCHANGE, + array( + 'repositoryID' => 'id', + 'pathID' => 'id', + 'commitID' => 'id', + 'targetPathID' => 'id?', + 'targetCommitID' => 'id?', + 'changeType' => 'uint32', + 'fileType' => 'uint32', + 'isDirect' => 'bool', + 'commitSequence' => 'uint32', + ), + array( + 'PRIMARY' => array( + 'columns' => array('commitID', 'pathID'), + 'unique' => true, + ), + 'repositoryID' => array( + 'columns' => array('repositoryID', 'pathID', 'commitSequence'), + ), + )); + + $this->buildRawSchema( + id(new PhabricatorRepository())->getApplicationName(), + PhabricatorRepository::TABLE_SUMMARY, + array( + 'repositoryID' => 'id', + 'size' => 'uint32', + 'lastCommitID' => 'id', + 'epoch' => 'epoch?', + ), + array( + 'PRIMARY' => array( + 'columns' => array('repositoryID'), + 'unique' => true, + ), + 'key_epoch' => array( + 'columns' => array('epoch'), + ), + )); + + } + +} diff --git a/src/applications/repository/storage/PhabricatorRepositoryStatusMessage.php b/src/applications/repository/storage/PhabricatorRepositoryStatusMessage.php index f35eec1cf2..967aec7911 100644 --- a/src/applications/repository/storage/PhabricatorRepositoryStatusMessage.php +++ b/src/applications/repository/storage/PhabricatorRepositoryStatusMessage.php @@ -23,6 +23,16 @@ final class PhabricatorRepositoryStatusMessage self::CONFIG_SERIALIZATION => array( 'parameters' => self::SERIALIZATION_JSON, ), + self::CONFIG_COLUMN_SCHEMA => array( + 'statusType' => 'text32', + 'statusCode' => 'text32', + ), + self::CONFIG_KEY_SCHEMA => array( + 'repositoryID' => array( + 'columns' => array('repositoryID', 'statusType'), + 'unique' => true, + ), + ), ) + parent::getConfiguration(); } diff --git a/src/applications/repository/storage/PhabricatorRepositorySymbol.php b/src/applications/repository/storage/PhabricatorRepositorySymbol.php index 9adde51cc9..353ff5ba5e 100644 --- a/src/applications/repository/storage/PhabricatorRepositorySymbol.php +++ b/src/applications/repository/storage/PhabricatorRepositorySymbol.php @@ -24,6 +24,20 @@ final class PhabricatorRepositorySymbol extends PhabricatorRepositoryDAO { return array( self::CONFIG_IDS => self::IDS_MANUAL, self::CONFIG_TIMESTAMPS => false, + self::CONFIG_COLUMN_SCHEMA => array( + 'id' => null, + 'symbolContext' => 'text128', + 'symbolName' => 'text128', + 'symbolType' => 'text12', + 'symbolLanguage' => 'text32', + 'lineNumber' => 'uint32', + ), + self::CONFIG_KEY_SCHEMA => array( + 'PRIMARY' => null, + 'symbolName' => array( + 'columns' => array('symbolName'), + ), + ), ) + parent::getConfiguration(); } diff --git a/src/applications/repository/storage/PhabricatorRepositoryVCSPassword.php b/src/applications/repository/storage/PhabricatorRepositoryVCSPassword.php index f3ba350282..cafbfa22ba 100644 --- a/src/applications/repository/storage/PhabricatorRepositoryVCSPassword.php +++ b/src/applications/repository/storage/PhabricatorRepositoryVCSPassword.php @@ -6,6 +6,20 @@ final class PhabricatorRepositoryVCSPassword extends PhabricatorRepositoryDAO { protected $userPHID; protected $passwordHash; + public function getConfiguration() { + return array( + self::CONFIG_COLUMN_SCHEMA => array( + 'passwordHash' => 'text128', + ), + self::CONFIG_KEY_SCHEMA => array( + 'key_phid' => array( + 'columns' => array('userPHID'), + 'unique' => true, + ), + ), + ) + parent::getConfiguration(); + } + public function setPassword( PhutilOpaqueEnvelope $password, PhabricatorUser $user) { diff --git a/src/docs/user/userguide/arcanist.diviner b/src/docs/user/userguide/arcanist.diviner index 8f8ba37eb5..cccdbaf243 100644 --- a/src/docs/user/userguide/arcanist.diviner +++ b/src/docs/user/userguide/arcanist.diviner @@ -158,7 +158,7 @@ several sources: # User can specify the settings in `~/.arcrc` (JSON) through the `config` key. This file can be modified also by `arc set-config --global`. # Machine can specify the settings with `/etc/arcconfig` (JSON). On Windows, - the file path is 'C:\ProgramData\Phabricator\Arcanist\config`. + the file path is `C:\ProgramData\Phabricator\Arcanist\config`. The first place where the setting is defined wins. diff --git a/src/docs/user/userguide/diffusion_hosting.diviner b/src/docs/user/userguide/diffusion_hosting.diviner index a2d845577a..ecf7e1c3e3 100644 --- a/src/docs/user/userguide/diffusion_hosting.diviner +++ b/src/docs/user/userguide/diffusion_hosting.diviner @@ -127,7 +127,7 @@ If you plan to use authenticated HTTP, you need to set use only anonymous HTTP, you can leave this setting disabled. If you plan to use authenticated HTTP, you'll also need to configure a VCS -password in "Settings" -> "VCS Password". This is a different password than +password in {nav Settings > VCS Password}. This is a different password than your main Phabricator password primarily for security reasons. Otherwise, if you've configured system accounts above, you're all set. No @@ -254,9 +254,9 @@ Some general tips for troubleshooting problems with HTTP: - Make sure `diffusion.allow-http-auth` is enabled in your Phabricator config. - Make sure HTTP serving is enabled for the repository you're trying to clone. - You can find this in "Edit Repository" -> "Hosting". + You can find this in {nav Edit Repository > Hosting}. - Make sure you've configured a VCS password. This is separate from your main - account password. You can configure this in "Settings" -> "VCS Password". + account password. You can configure this in {nav Settings > VCS Password}. - Make sure the main repository screen in Diffusion shows a clone/checkout command for HTTP. If it doesn't, something above isn't set up correctly: double-check your configuration. You should see a `svn checkout http://...`, @@ -283,14 +283,22 @@ Some general tips for troubleshooting problems with SSH: - Check that you've configured `diffusion.ssh-user`. - Check that you've configured `phd.user`. - Make sure SSH serving is enabled for the repository you're trying to clone. - You can find this in "Edit Repository" -> "Hosting". + You can change this setting from a main repository screen in Diffusion by + {nav Edit Repository > + Edit Hosting > + Host Repository on Phabricator > + Save and Continue > + SSH Read Only or Read/Write > + Save Changes}. - Make sure you've added an SSH public key to your account. You can do this - in "Settings" -> "SSH Keys". + in {nav Settings > SSH Public Keys}. - Make sure the main repository screen in Diffusion shows a clone/checkout command for SSH. If it doesn't, something above isn't set up correctly. You should see an `svn checkout svn+ssh://...`, `git clone ssh://...` or `hg clone ssh://...` command. Run that command verbatim to clone the repository. + - Check your `phabricator-ssh-hook.sh` file for proper settings. + - Check your `sshd_config.phabricator` file for proper settings. To troubleshoot SSH setup: connect to the server with `ssh`, without running a command. You may need to use the `-T` flag. You should see a message like diff --git a/src/docs/user/userguide/diffusion_symbols.diviner b/src/docs/user/userguide/diffusion_symbols.diviner index b9b96ec209..0a212055d5 100644 --- a/src/docs/user/userguide/diffusion_symbols.diviner +++ b/src/docs/user/userguide/diffusion_symbols.diviner @@ -77,7 +77,7 @@ configuration. To configure Differential integration, you need to tell Phabricator which projects have symbol indexes you want to use, and which other projects they should pull symbols from. To do this, go to -`Repositories -> Arcanist Projects -> Edit` as an administrator. You need to +{nav Repositories > Arcanist Projects > Edit} as an administrator. You need to fill out these fields: - **Repository**: Associate the project with a tracked repository. diff --git a/src/docs/user/userguide/external_editor.diviner b/src/docs/user/userguide/external_editor.diviner index 675ed7eb1f..c98ccb1903 100644 --- a/src/docs/user/userguide/external_editor.diviner +++ b/src/docs/user/userguide/external_editor.diviner @@ -10,8 +10,8 @@ and Diffusion in your preferred text editor. = Configuring Editors = -To configure an external editor, go to Settings -> Application Settings -> -Display Preferences and set "Editor Link" to a URI pattern (see below). This +To configure an external editor, go to {nav Settings > Application Settings > +Display Preferences} and set "Editor Link" to a URI pattern (see below). This will enable an "Open in Editor" link in Differential, and an "Edit" button in Diffusion. diff --git a/src/docs/user/userguide/mail_rules.diviner b/src/docs/user/userguide/mail_rules.diviner index cc0860a1ae..64d0723fdb 100644 --- a/src/docs/user/userguide/mail_rules.diviner +++ b/src/docs/user/userguide/mail_rules.diviner @@ -16,7 +16,7 @@ write sophisticated rules to route, categorize, or delete email. = Reducing Email = You can reduce the amount of email you receive by turning off some types of -email in ##Settings -> Email Preferences##. For example, you can turn off email +email in {nav Settings > Email Preferences}. For example, you can turn off email produced by your own actions (like when you comment on a revision), and some types of less-important notifications about events. diff --git a/src/docs/user/userguide/phame.diviner b/src/docs/user/userguide/phame.diviner index 8422a8e8c7..28635886d8 100644 --- a/src/docs/user/userguide/phame.diviner +++ b/src/docs/user/userguide/phame.diviner @@ -59,4 +59,5 @@ of whether that post is being viewed in the context of a blog. = Next Steps = - Phame is extremely new and very basic for now. Give us feedback on -what you'd like to see improve! See @{article:Give Feedback! Get Support!}. + what you'd like to see improve! See @{article:Give Feedback! Get + Support!}. diff --git a/src/infrastructure/celerity/CelerityResourceMap.php b/src/infrastructure/celerity/CelerityResourceMap.php index 030fd3233d..5b0c374dab 100644 --- a/src/infrastructure/celerity/CelerityResourceMap.php +++ b/src/infrastructure/celerity/CelerityResourceMap.php @@ -53,6 +53,22 @@ final class CelerityResourceMap { return self::$instances[$name]; } + public function getNameMap() { + return $this->nameMap; + } + + public function getSymbolMap() { + return $this->symbolMap; + } + + public function getRequiresMap() { + return $this->requiresMap; + } + + public function getPackageMap() { + return $this->packageMap; + } + public function getPackagedNamesForSymbols(array $symbols) { $resolved = $this->resolveResources($symbols); return $this->packageResources($resolved); diff --git a/src/infrastructure/celerity/CelerityResourceMapGenerator.php b/src/infrastructure/celerity/CelerityResourceMapGenerator.php new file mode 100644 index 0000000000..b7a1dfb563 --- /dev/null +++ b/src/infrastructure/celerity/CelerityResourceMapGenerator.php @@ -0,0 +1,361 @@ +resources = $resources; + } + + public function getNameMap() { + return $this->nameMap; + } + + public function getSymbolMap() { + return $this->symbolMap; + } + + public function getRequiresMap() { + return $this->requiresMap; + } + + public function getPackageMap() { + return $this->packageMap; + } + + public function setDebug($debug) { + $this->debug = $debug; + return $this; + } + + protected function log($message) { + if ($this->debug) { + $console = PhutilConsole::getConsole(); + $console->writeErr("%s\n", $message); + } + } + + public function generate() { + $binary_map = $this->rebuildBinaryResources($this->resources); + + $this->log(pht('Found %d binary resources.', count($binary_map))); + + $xformer = id(new CelerityResourceTransformer()) + ->setMinify(false) + ->setRawURIMap(ipull($binary_map, 'uri')); + + $text_map = $this->rebuildTextResources($this->resources, $xformer); + + $this->log(pht('Found %d text resources.', count($text_map))); + + $resource_graph = array(); + $requires_map = array(); + $symbol_map = array(); + foreach ($text_map as $name => $info) { + if (isset($info['provides'])) { + $symbol_map[$info['provides']] = $info['hash']; + + // We only need to check for cycles and add this to the requires map + // if it actually requires anything. + if (!empty($info['requires'])) { + $resource_graph[$info['provides']] = $info['requires']; + $requires_map[$info['hash']] = $info['requires']; + } + } + } + + $this->detectGraphCycles($resource_graph); + $name_map = ipull($binary_map, 'hash') + ipull($text_map, 'hash'); + $hash_map = array_flip($name_map); + + $package_map = $this->rebuildPackages( + $this->resources, + $symbol_map, + $hash_map); + + $this->log(pht('Found %d packages.', count($package_map))); + + $component_map = array(); + foreach ($package_map as $package_name => $package_info) { + foreach ($package_info['symbols'] as $symbol) { + $component_map[$symbol] = $package_name; + } + } + + $name_map = $this->mergeNameMaps( + array( + array(pht('Binary'), ipull($binary_map, 'hash')), + array(pht('Text'), ipull($text_map, 'hash')), + array(pht('Package'), ipull($package_map, 'hash')), + )); + $package_map = ipull($package_map, 'symbols'); + + ksort($name_map); + ksort($symbol_map); + ksort($requires_map); + ksort($package_map); + + $this->nameMap = $name_map; + $this->symbolMap = $symbol_map; + $this->requiresMap = $requires_map; + $this->packageMap = $package_map; + + return $this; + } + + public function write() { + $map_content = $this->formatMapContent(array( + 'names' => $this->getNameMap(), + 'symbols' => $this->getSymbolMap(), + 'requires' => $this->getRequiresMap(), + 'packages' => $this->getPackageMap(), + )); + + $map_path = $this->resources->getPathToMap(); + $this->log(pht('Writing map "%s".', Filesystem::readablePath($map_path))); + Filesystem::writeFile($map_path, $map_content); + + return $this; + } + + private function formatMapContent(array $data) { + $content = phutil_var_export($data); + $generated = '@'.'generated'; + + return <<> Resource information map. + */ + private function rebuildBinaryResources( + CelerityPhysicalResources $resources) { + + $binary_map = $resources->findBinaryResources(); + $result_map = array(); + + foreach ($binary_map as $name => $data_hash) { + $hash = $resources->getCelerityHash($data_hash.$name); + + $result_map[$name] = array( + 'hash' => $hash, + 'uri' => $resources->getResourceURI($hash, $name), + ); + } + + return $result_map; + } + + /** + * Find text resources (like JS and CSS) and return information about them. + * + * @param CelerityPhysicalResources Resource map to find text resources for. + * @param CelerityResourceTransformer Configured resource transformer. + * @return map> Resource information map. + */ + private function rebuildTextResources( + CelerityPhysicalResources $resources, + CelerityResourceTransformer $xformer) { + + $text_map = $resources->findTextResources(); + $result_map = array(); + + foreach ($text_map as $name => $data_hash) { + $raw_data = $resources->getResourceData($name); + $xformed_data = $xformer->transformResource($name, $raw_data); + + $data_hash = $resources->getCelerityHash($xformed_data); + $hash = $resources->getCelerityHash($data_hash.$name); + + list($provides, $requires) = $this->getProvidesAndRequires( + $name, + $raw_data); + + $result_map[$name] = array( + 'hash' => $hash, + ); + + if ($provides !== null) { + $result_map[$name] += array( + 'provides' => $provides, + 'requires' => $requires, + ); + } + } + + return $result_map; + } + + /** + * Parse the `@provides` and `@requires` symbols out of a text resource, like + * JS or CSS. + * + * @param string Resource name. + * @param string Resource data. + * @return pair|null> The `@provides` symbol and + * the list of `@requires` symbols. If the resource is not part of the + * dependency graph, both are null. + */ + private function getProvidesAndRequires($name, $data) { + $parser = new PhutilDocblockParser(); + + $matches = array(); + $ok = preg_match('@/[*][*].*?[*]/@s', $data, $matches); + if (!$ok) { + throw new Exception( + pht( + 'Resource "%s" does not have a header doc comment. Encode '. + 'dependency data in a header docblock.', + $name)); + } + + list($description, $metadata) = $parser->parse($matches[0]); + + $provides = preg_split('/\s+/', trim(idx($metadata, 'provides'))); + $requires = preg_split('/\s+/', trim(idx($metadata, 'requires'))); + $provides = array_filter($provides); + $requires = array_filter($requires); + + if (!$provides) { + // Tests and documentation-only JS is permitted to @provide no targets. + return array(null, null); + } + + if (count($provides) > 1) { + throw new Exception( + pht('Resource "%s" must @provide at most one Celerity target.', $name)); + } + + return array(head($provides), $requires); + } + + /** + * Check for dependency cycles in the resource graph. Raises an exception if + * a cycle is detected. + * + * @param map> Map of `@provides` symbols to their + * `@requires` symbols. + * @return void + */ + private function detectGraphCycles(array $nodes) { + $graph = id(new CelerityResourceGraph()) + ->addNodes($nodes) + ->setResourceGraph($nodes) + ->loadGraph(); + + foreach ($nodes as $provides => $requires) { + $cycle = $graph->detectCycles($provides); + if ($cycle) { + throw new Exception( + pht('Cycle detected in resource graph: %s', implode(' > ', $cycle))); + } + } + } + + /** + * Build package specifications for a given resource source. + * + * @param CelerityPhysicalResources Resource source to rebuild. + * @param map Map of `@provides` to hashes. + * @param map Map of hashes to resource names. + * @return map> Package information maps. + */ + private function rebuildPackages( + CelerityPhysicalResources $resources, + array $symbol_map, + array $reverse_map) { + + $package_map = array(); + + $package_spec = $resources->getResourcePackages(); + foreach ($package_spec as $package_name => $package_symbols) { + $type = null; + $hashes = array(); + foreach ($package_symbols as $symbol) { + $symbol_hash = idx($symbol_map, $symbol); + if ($symbol_hash === null) { + throw new Exception( + pht( + 'Package specification for "%s" includes "%s", but that symbol '. + 'is not @provided by any resource.', + $package_name, + $symbol)); + } + + $resource_name = $reverse_map[$symbol_hash]; + $resource_type = $resources->getResourceType($resource_name); + if ($type === null) { + $type = $resource_type; + } else if ($type !== $resource_type) { + throw new Exception( + pht( + 'Package specification for "%s" includes resources of multiple '. + 'types (%s, %s). Each package may only contain one type of '. + 'resource.', + $package_name, + $type, + $resource_type)); + } + + $hashes[] = $symbol.':'.$symbol_hash; + } + + $hash = $resources->getCelerityHash(implode("\n", $hashes)); + $package_map[$package_name] = array( + 'hash' => $hash, + 'symbols' => $package_symbols, + ); + } + + return $package_map; + } + + private function mergeNameMaps(array $maps) { + $result = array(); + $origin = array(); + + foreach ($maps as $map) { + list($map_name, $data) = $map; + foreach ($data as $name => $hash) { + if (empty($result[$name])) { + $result[$name] = $hash; + $origin[$name] = $map_name; + } else { + $old = $origin[$name]; + $new = $map_name; + throw new Exception( + pht( + 'Resource source defines two resources with the same name, '. + '"%s". One is defined in the "%s" map; the other in the "%s" '. + 'map. Each resource must have a unique name.', + $name, + $old, + $new)); + } + } + } + return $result; + } + +} diff --git a/src/infrastructure/celerity/management/CelerityManagementMapWorkflow.php b/src/infrastructure/celerity/management/CelerityManagementMapWorkflow.php index 81179c086e..be844137e2 100644 --- a/src/infrastructure/celerity/management/CelerityManagementMapWorkflow.php +++ b/src/infrastructure/celerity/management/CelerityManagementMapWorkflow.php @@ -42,330 +42,15 @@ final class CelerityManagementMapWorkflow $resources->getName(), get_class($resources))); - $binary_map = $this->rebuildBinaryResources($resources); - - $this->log( - pht( - 'Found %d binary resources.', - new PhutilNumber(count($binary_map)))); - - $xformer = id(new CelerityResourceTransformer()) - ->setMinify(false) - ->setRawURIMap(ipull($binary_map, 'uri')); - - $text_map = $this->rebuildTextResources($resources, $xformer); - - $this->log( - pht( - 'Found %d text resources.', - new PhutilNumber(count($text_map)))); - - $resource_graph = array(); - $requires_map = array(); - $symbol_map = array(); - foreach ($text_map as $name => $info) { - if (isset($info['provides'])) { - $symbol_map[$info['provides']] = $info['hash']; - - // We only need to check for cycles and add this to the requires map - // if it actually requires anything. - if (!empty($info['requires'])) { - $resource_graph[$info['provides']] = $info['requires']; - $requires_map[$info['hash']] = $info['requires']; - } - } - } - - $this->detectGraphCycles($resource_graph); - $name_map = ipull($binary_map, 'hash') + ipull($text_map, 'hash'); - $hash_map = array_flip($name_map); - - $package_map = $this->rebuildPackages( - $resources, - $symbol_map, - $hash_map); - - $this->log( - pht( - 'Found %d packages.', - new PhutilNumber(count($package_map)))); - - $component_map = array(); - foreach ($package_map as $package_name => $package_info) { - foreach ($package_info['symbols'] as $symbol) { - $component_map[$symbol] = $package_name; - } - } - - $name_map = $this->mergeNameMaps( - array( - array(pht('Binary'), ipull($binary_map, 'hash')), - array(pht('Text'), ipull($text_map, 'hash')), - array(pht('Package'), ipull($package_map, 'hash')), - )); - $package_map = ipull($package_map, 'symbols'); - - ksort($name_map); - ksort($symbol_map); - ksort($requires_map); - ksort($package_map); - - $map_content = $this->formatMapContent(array( - 'names' => $name_map, - 'symbols' => $symbol_map, - 'requires' => $requires_map, - 'packages' => $package_map, - )); - - $map_path = $resources->getPathToMap(); - $this->log(pht('Writing map "%s".', Filesystem::readablePath($map_path))); - Filesystem::writeFile($map_path, $map_content); + id(new CelerityResourceMapGenerator($resources)) + ->setDebug(true) + ->generate() + ->write(); } - - /** - * Find binary resources (like PNG and SWF) and return information about - * them. - * - * @param CelerityPhysicalResources Resource map to find binary resources for. - * @return map> Resource information map. - */ - private function rebuildBinaryResources( - CelerityPhysicalResources $resources) { - - $binary_map = $resources->findBinaryResources(); - - $result_map = array(); - foreach ($binary_map as $name => $data_hash) { - $hash = $resources->getCelerityHash($data_hash.$name); - - $result_map[$name] = array( - 'hash' => $hash, - 'uri' => $resources->getResourceURI($hash, $name), - ); - } - - return $result_map; - } - - - /** - * Find text resources (like JS and CSS) and return information about them. - * - * @param CelerityPhysicalResources Resource map to find text resources for. - * @param CelerityResourceTransformer Configured resource transformer. - * @return map> Resource information map. - */ - private function rebuildTextResources( - CelerityPhysicalResources $resources, - CelerityResourceTransformer $xformer) { - - $text_map = $resources->findTextResources(); - - $result_map = array(); - foreach ($text_map as $name => $data_hash) { - $raw_data = $resources->getResourceData($name); - $xformed_data = $xformer->transformResource($name, $raw_data); - - $data_hash = $resources->getCelerityHash($xformed_data); - $hash = $resources->getCelerityHash($data_hash.$name); - - list($provides, $requires) = $this->getProvidesAndRequires( - $name, - $raw_data); - - $result_map[$name] = array( - 'hash' => $hash, - ); - - if ($provides !== null) { - $result_map[$name] += array( - 'provides' => $provides, - 'requires' => $requires, - ); - } - } - - return $result_map; - } - - - /** - * Parse the `@provides` and `@requires` symbols out of a text resource, like - * JS or CSS. - * - * @param string Resource name. - * @param string Resource data. - * @return pair|null> The `@provides` symbol and the - * list of `@requires` symbols. If the resource is not part of the - * dependency graph, both are null. - */ - private function getProvidesAndRequires($name, $data) { - $parser = new PhutilDocblockParser(); - - $matches = array(); - $ok = preg_match('@/[*][*].*?[*]/@s', $data, $matches); - if (!$ok) { - throw new Exception( - pht( - 'Resource "%s" does not have a header doc comment. Encode '. - 'dependency data in a header docblock.', - $name)); - } - - list($description, $metadata) = $parser->parse($matches[0]); - - $provides = preg_split('/\s+/', trim(idx($metadata, 'provides'))); - $requires = preg_split('/\s+/', trim(idx($metadata, 'requires'))); - $provides = array_filter($provides); - $requires = array_filter($requires); - - if (!$provides) { - // Tests and documentation-only JS is permitted to @provide no targets. - return array(null, null); - } - - if (count($provides) > 1) { - throw new Exception( - pht( - 'Resource "%s" must @provide at most one Celerity target.', - $name)); - } - - return array(head($provides), $requires); - } - - - /** - * Check for dependency cycles in the resource graph. Raises an exception if - * a cycle is detected. - * - * @param map> Map of `@provides` symbols to their - * `@requires` symbols. - * @return void - */ - private function detectGraphCycles(array $nodes) { - $graph = id(new CelerityResourceGraph()) - ->addNodes($nodes) - ->setResourceGraph($nodes) - ->loadGraph(); - - foreach ($nodes as $provides => $requires) { - $cycle = $graph->detectCycles($provides); - if ($cycle) { - throw new Exception( - pht( - 'Cycle detected in resource graph: %s', - implode(' > ', $cycle))); - } - } - } - - /** - * Build package specifications for a given resource source. - * - * @param CelerityPhysicalResources Resource source to rebuild. - * @param list Map of `@provides` to hashes. - * @param list Map of hashes to resource names. - * @return map> Package information maps. - */ - private function rebuildPackages( - CelerityPhysicalResources $resources, - array $symbol_map, - array $reverse_map) { - - $package_map = array(); - - $package_spec = $resources->getResourcePackages(); - foreach ($package_spec as $package_name => $package_symbols) { - $type = null; - $hashes = array(); - foreach ($package_symbols as $symbol) { - $symbol_hash = idx($symbol_map, $symbol); - if ($symbol_hash === null) { - throw new Exception( - pht( - 'Package specification for "%s" includes "%s", but that symbol '. - 'is not @provided by any resource.', - $package_name, - $symbol)); - } - - $resource_name = $reverse_map[$symbol_hash]; - $resource_type = $resources->getResourceType($resource_name); - if ($type === null) { - $type = $resource_type; - } else if ($type !== $resource_type) { - throw new Exception( - pht( - 'Package specification for "%s" includes resources of multiple '. - 'types (%s, %s). Each package may only contain one type of '. - 'resource.', - $package_name, - $type, - $resource_type)); - } - - $hashes[] = $symbol.':'.$symbol_hash; - } - - $hash = $resources->getCelerityHash(implode("\n", $hashes)); - $package_map[$package_name] = array( - 'hash' => $hash, - 'symbols' => $package_symbols, - ); - } - - return $package_map; - } - - private function mergeNameMaps(array $maps) { - $result = array(); - $origin = array(); - foreach ($maps as $map) { - list($map_name, $data) = $map; - foreach ($data as $name => $hash) { - if (empty($result[$name])) { - $result[$name] = $hash; - $origin[$name] = $map_name; - } else { - $old = $origin[$name]; - $new = $map_name; - throw new Exception( - pht( - 'Resource source defines two resources with the same name, '. - '"%s". One is defined in the "%s" map; the other in the "%s" '. - 'map. Each resource must have a unique name.', - $name, - $old, - $new)); - } - } - } - return $result; - } - - private function log($message) { + protected function log($message) { $console = PhutilConsole::getConsole(); $console->writeErr("%s\n", $message); } - private function formatMapContent(array $data) { - $content = phutil_var_export($data); - - $generated = '@'.'generated'; - return << array( array( '%s added a revision: %3$s.', - '%s added revisionss: %3$s.', + '%s added revisions: %3$s.', ), ), diff --git a/src/infrastructure/sms/storage/PhabricatorSMS.php b/src/infrastructure/sms/storage/PhabricatorSMS.php index e880fad01d..eb03d890de 100644 --- a/src/infrastructure/sms/storage/PhabricatorSMS.php +++ b/src/infrastructure/sms/storage/PhabricatorSMS.php @@ -43,6 +43,25 @@ final class PhabricatorSMS ->setProviderSMSID(Filesystem::readRandomCharacters(40)); } + public function getConfiguration() { + return array( + self::CONFIG_COLUMN_SCHEMA => array( + 'providerShortName' => 'text16', + 'providerSMSID' => 'text40', + 'toNumber' => 'text20', + 'fromNumber' => 'text20?', + 'body' => 'text', + 'sendStatus' => 'text16?', + ), + self::CONFIG_KEY_SCHEMA => array( + 'key_provider' => array( + 'columns' => array('providerSMSID', 'providerShortName'), + 'unique' => true, + ), + ), + ) + parent::getConfiguration(); + } + public function getTableName() { // Slightly non-standard, but otherwise this class needs "MetaMTA" in its // name. :/ diff --git a/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementDumpWorkflow.php b/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementDumpWorkflow.php index fa47ca2133..4e01446929 100644 --- a/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementDumpWorkflow.php +++ b/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementDumpWorkflow.php @@ -43,10 +43,8 @@ final class PhabricatorStorageManagementDumpWorkflow : ''; return phutil_passthru( - - 'mysqldump --default-character-set=utf8 '. + 'mysqldump --single-transaction --default-character-set=utf8 '. '-u %s %C -h %s %C --databases %Ls', - $api->getUser(), $flag_password, $host, diff --git a/src/infrastructure/storage/schema/PhabricatorStorageSchemaSpec.php b/src/infrastructure/storage/schema/PhabricatorStorageSchemaSpec.php new file mode 100644 index 0000000000..39a1f1c2d9 --- /dev/null +++ b/src/infrastructure/storage/schema/PhabricatorStorageSchemaSpec.php @@ -0,0 +1,22 @@ +buildRawSchema( + 'meta_data', + 'patch_status', + array( + 'patch' => 'text255', + 'applied' => 'uint32', + ), + array( + 'PRIMARY' => array( + 'columns' => array('patch'), + 'unique' => true, + ), + )); + } + +} diff --git a/src/infrastructure/testing/PhabricatorTestCase.php b/src/infrastructure/testing/PhabricatorTestCase.php index 14e2a30142..effec47d86 100644 --- a/src/infrastructure/testing/PhabricatorTestCase.php +++ b/src/infrastructure/testing/PhabricatorTestCase.php @@ -116,9 +116,6 @@ abstract class PhabricatorTestCase extends ArcanistPhutilTestCase { 'notification.enabled', false); - // TODO: Remove this when we remove "releeph.installed". - $this->env->overrideEnvConfig('releeph.installed', true); - $this->env->overrideEnvConfig( 'phabricator.base-uri', 'http://phabricator.example.com'); diff --git a/src/view/page/AphrontRequestFailureView.php b/src/view/page/AphrontRequestFailureView.php deleted file mode 100644 index 5910b4468f..0000000000 --- a/src/view/page/AphrontRequestFailureView.php +++ /dev/null @@ -1,27 +0,0 @@ -header = $header; - return $this; - } - - - final public function render() { - require_celerity_resource('aphront-request-failure-view-css'); - - $head = phutil_tag_div( - 'aphront-request-failure-head', - phutil_tag('h1', array(), $this->header)); - - $body = phutil_tag_div( - 'aphront-request-failure-body', - $this->renderChildren()); - - return phutil_tag_div('aphront-request-failure-view', array($head, $body)); - } - -} diff --git a/src/view/page/PhabricatorStandardPageView.php b/src/view/page/PhabricatorStandardPageView.php index bcf274817b..9af3affb75 100644 --- a/src/view/page/PhabricatorStandardPageView.php +++ b/src/view/page/PhabricatorStandardPageView.php @@ -352,7 +352,6 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView { phutil_tag_div('phabricator-standard-page-body', array( ($console ? hsprintf('') : null), parent::getBody(), - phutil_tag('div', array('style' => 'clear: both;')), $this->renderFooter(), )), )); @@ -508,7 +507,7 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView { return phutil_tag( 'div', array( - 'class' => 'phabricator-standard-page-footer', + 'class' => 'phabricator-standard-page-footer grouped', ), $foot); } diff --git a/webroot/rsrc/css/aphront/request-failure-view.css b/webroot/rsrc/css/aphront/request-failure-view.css deleted file mode 100644 index 7a2cca8063..0000000000 --- a/webroot/rsrc/css/aphront/request-failure-view.css +++ /dev/null @@ -1,45 +0,0 @@ -/** - * @provides aphront-request-failure-view-css - */ - -.aphront-request-failure-view { - margin: 16px auto; - background: #eff2f7; - width: 600px; -} - -.device .aphront-request-failure-view { - width: 90%; -} - -.aphront-request-failure-view .aphront-request-failure-head { - padding: 1em 2em; - border-bottom: 1px solid #afb2b7; - background: #dfe2e7; -} - -.aphront-request-failure-view .aphront-request-failure-head h1 { - font-size: 24px; -} - -.aphront-request-failure-view .aphront-request-failure-body { - padding: 1em 2em 1.5em; -} - -.aphront-request-failure-view .aphront-request-failure-body p { - margin: .5em 0; -} - -.aphront-failure-continue { - margin-top: 1.5em; - text-align: right; -} - -.aphront-failure-continue a.button { - margin-left: 1em; -} - -.aphront-request-failure-view ul { - list-style: disc; - margin-left: 3em; -} diff --git a/webroot/rsrc/css/application/base/standard-page-view.css b/webroot/rsrc/css/application/base/standard-page-view.css index 301137c338..2a13e05bac 100644 --- a/webroot/rsrc/css/application/base/standard-page-view.css +++ b/webroot/rsrc/css/application/base/standard-page-view.css @@ -15,12 +15,16 @@ .phabricator-standard-page-footer { text-align: right; - margin: 0 16px; - padding: 8px 0; + margin: 4px 16px; + padding: 12px 0; border-top: 1px solid {$lightgreyborder}; color: {$lightgreytext}; } +.has-local-nav + .phabricator-standard-page-footer { + margin-left: 221px; +} + .keyboard-shortcut-help td, .keyboard-shortcut-help th { padding: 8px; diff --git a/webroot/rsrc/css/application/profile/profile-view.css b/webroot/rsrc/css/application/profile/profile-view.css index 47214d9d68..a51fa5a195 100644 --- a/webroot/rsrc/css/application/profile/profile-view.css +++ b/webroot/rsrc/css/application/profile/profile-view.css @@ -30,6 +30,10 @@ } .profile-activity-view .profile-feed { + margin-left: 16px; +} + +.profile-activity-view.profile-has-calendar .profile-feed { margin-left: 332px; }