diff --git a/.gitignore b/.gitignore index d9f44b6bab..4e3a12e5e9 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ # Diviner /docs/ /.divinercache/ +/webroot/rsrc/externals/javelin/docs/.divinercache/ /src/.cache/ # libphutil diff --git a/conf/aphlict/README b/conf/aphlict/README index 2786ea5658..0704bf6068 100644 --- a/conf/aphlict/README +++ b/conf/aphlict/README @@ -8,7 +8,7 @@ be read by default. To specify a path when starting Aphlict, use the `--config` flag: - phabricator/ $ ./bin/aphlict start --config path/to/config.json + phorge/ $ ./bin/aphlict start --config path/to/config.json Specifying a configuration file explicitly overrides default configuration. diff --git a/resources/celerity/map.php b/resources/celerity/map.php index 3fc6387e77..12ad67b011 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -7,12 +7,12 @@ */ return array( 'names' => array( - 'conpherence.pkg.css' => '76ed87e3', + 'conpherence.pkg.css' => '2f25eb4f', 'conpherence.pkg.js' => '020aebcf', - 'core.pkg.css' => '1a5169fe', + 'core.pkg.css' => 'c0bdb5b4', 'core.pkg.js' => '2eeda9e0', 'dark-console.pkg.js' => '187792c2', - 'differential.pkg.css' => '525f9a1d', + 'differential.pkg.css' => '2431def2', 'differential.pkg.js' => '46fcb3af', 'diffusion.pkg.css' => '42c75c37', 'diffusion.pkg.js' => '78c9885d', @@ -38,21 +38,20 @@ return array( 'rsrc/css/aphront/typeahead.css' => '8779483d', 'rsrc/css/application/almanac/almanac.css' => '2e050f4f', 'rsrc/css/application/auth/auth.css' => 'c2f23d74', - 'rsrc/css/application/base/main-menu-view.css' => '89fc16b6', + 'rsrc/css/application/base/main-menu-view.css' => '5d673247', 'rsrc/css/application/base/notification-menu.css' => '4df1ee30', 'rsrc/css/application/base/phui-theme.css' => '35883b37', 'rsrc/css/application/base/standard-page-view.css' => 'e08c7462', - 'rsrc/css/application/chatlog/chatlog.css' => 'abdc76ee', 'rsrc/css/application/conduit/conduit-api.css' => 'ce2cfc41', 'rsrc/css/application/config/config-options.css' => '16c920ae', 'rsrc/css/application/config/config-template.css' => 'e689dbbd', - 'rsrc/css/application/config/setup-issue.css' => '5eed85b2', + 'rsrc/css/application/config/setup-issue.css' => '93231115', 'rsrc/css/application/config/unhandled-exception.css' => '9ecfc00d', 'rsrc/css/application/conpherence/color.css' => 'b17746b0', 'rsrc/css/application/conpherence/durable-column.css' => '2d57072b', 'rsrc/css/application/conpherence/header-pane.css' => 'c9a3db8e', 'rsrc/css/application/conpherence/menu.css' => '67f4680d', - 'rsrc/css/application/conpherence/message-pane.css' => 'd244db1e', + 'rsrc/css/application/conpherence/message-pane.css' => '50b1345e', 'rsrc/css/application/conpherence/notification.css' => '85c48def', 'rsrc/css/application/conpherence/participant-pane.css' => '69e0058a', 'rsrc/css/application/conpherence/transaction.css' => '3a3f5e7e', @@ -63,7 +62,7 @@ return array( 'rsrc/css/application/diff/diff-tree-view.css' => 'e2d3e222', 'rsrc/css/application/diff/inline-comment-summary.css' => '81eb368d', 'rsrc/css/application/differential/add-comment.css' => '7e5900d9', - 'rsrc/css/application/differential/changeset-view.css' => '8b9caefe', + 'rsrc/css/application/differential/changeset-view.css' => '360630ff', 'rsrc/css/application/differential/core.css' => '7300a73e', 'rsrc/css/application/differential/phui-inline-comment.css' => 'a864426f', 'rsrc/css/application/differential/revision-comment.css' => '7dbc8d1d', @@ -109,7 +108,7 @@ return array( 'rsrc/css/application/slowvote/slowvote.css' => '1694baed', 'rsrc/css/application/tokens/tokens.css' => 'ce5a50bd', 'rsrc/css/application/uiexample/example.css' => 'b4795059', - 'rsrc/css/core/core.css' => 'a708bd25', + 'rsrc/css/core/core.css' => 'b3a5928e', 'rsrc/css/core/remarkup.css' => '3480e1fe', 'rsrc/css/core/syntax.css' => '548567f6', 'rsrc/css/core/z-index.css' => 'ac3bfcd4', @@ -121,7 +120,7 @@ return array( 'rsrc/css/fuel/fuel-handle-list.css' => '2c4cbeca', 'rsrc/css/fuel/fuel-map.css' => 'd6e31510', 'rsrc/css/fuel/fuel-menu.css' => '21f5d199', - 'rsrc/css/layout/phabricator-source-code-view.css' => '49656486', + 'rsrc/css/layout/phabricator-source-code-view.css' => 'e382316a', 'rsrc/css/phui/button/phui-button-bar.css' => 'a4aa75c4', 'rsrc/css/phui/button/phui-button-simple.css' => '1ff278aa', 'rsrc/css/phui/button/phui-button.css' => 'f9d0f9c8', @@ -160,7 +159,7 @@ return array( 'rsrc/css/phui/phui-head-thing.css' => 'd7f293df', 'rsrc/css/phui/phui-header-view.css' => '36c86a58', 'rsrc/css/phui/phui-hovercard.css' => '39fd2e14', - 'rsrc/css/phui/phui-icon-set-selector.css' => '7aa5f3ec', + 'rsrc/css/phui/phui-icon-set-selector.css' => '19e0253b', 'rsrc/css/phui/phui-icon.css' => '084ac612', 'rsrc/css/phui/phui-image-mask.css' => '62c7f4d2', 'rsrc/css/phui/phui-info-view.css' => 'a10a909b', @@ -553,14 +552,14 @@ return array( 'conpherence-durable-column-view' => '2d57072b', 'conpherence-header-pane-css' => 'c9a3db8e', 'conpherence-menu-css' => '67f4680d', - 'conpherence-message-pane-css' => 'd244db1e', + 'conpherence-message-pane-css' => '50b1345e', 'conpherence-notification-css' => '85c48def', 'conpherence-participant-pane-css' => '69e0058a', 'conpherence-thread-manager' => 'aec8e38c', 'conpherence-transaction-css' => '3a3f5e7e', 'd3' => '9d068042', 'diff-tree-view-css' => 'e2d3e222', - 'differential-changeset-view-css' => '8b9caefe', + 'differential-changeset-view-css' => '360630ff', 'differential-core-view-css' => '7300a73e', 'differential-revision-add-comment-css' => '7e5900d9', 'differential-revision-comment-css' => '7dbc8d1d', @@ -770,9 +769,8 @@ return array( 'people-profile-css' => '2ea2daa1', 'phabricator-action-list-view-css' => '1b0085b2', 'phabricator-busy' => '5202e831', - 'phabricator-chatlog-css' => 'abdc76ee', 'phabricator-content-source-view-css' => 'cdf0d579', - 'phabricator-core-css' => 'a708bd25', + 'phabricator-core-css' => 'b3a5928e', 'phabricator-countdown-css' => 'bff8012f', 'phabricator-darklog' => '3b869402', 'phabricator-darkmessage' => '26cd4b73', @@ -792,7 +790,7 @@ return array( 'phabricator-flag-css' => '2b77be8d', 'phabricator-keyboard-shortcut' => '1a844c06', 'phabricator-keyboard-shortcut-manager' => '81debc48', - 'phabricator-main-menu-view' => '89fc16b6', + 'phabricator-main-menu-view' => '5d673247', 'phabricator-nav-view-css' => '423f92cc', 'phabricator-notification' => 'a9b91e3f', 'phabricator-notification-css' => '30240bd2', @@ -805,7 +803,7 @@ return array( 'phabricator-search-results-css' => '9ea70ace', 'phabricator-shaped-request' => '995f5102', 'phabricator-slowvote-css' => '1694baed', - 'phabricator-source-code-view-css' => '49656486', + 'phabricator-source-code-view-css' => 'e382316a', 'phabricator-standard-page-view' => 'e08c7462', 'phabricator-textareautils' => 'f340a484', 'phabricator-title' => '43bc9360', @@ -856,7 +854,7 @@ return array( 'phui-hovercard' => '6199f752', 'phui-hovercard-list' => 'de4b4919', 'phui-hovercard-view-css' => '39fd2e14', - 'phui-icon-set-selector-css' => '7aa5f3ec', + 'phui-icon-set-selector-css' => '19e0253b', 'phui-icon-view-css' => '084ac612', 'phui-image-mask-css' => '62c7f4d2', 'phui-info-view-css' => 'a10a909b', @@ -905,7 +903,7 @@ return array( 'project-card-view-css' => 'c1200da7', 'project-triggers-css' => 'cd9c8bb9', 'project-view-css' => '2f7caa20', - 'setup-issue-css' => '5eed85b2', + 'setup-issue-css' => '93231115', 'sprite-login-css' => '07052ee0', 'sprite-tokens-css' => 'f1896dc5', 'syntax-default-css' => '055fc231', @@ -1228,6 +1226,9 @@ return array( 'aphront-typeahead-control-css', 'phui-tag-view-css', ), + '360630ff' => array( + 'phui-inline-comment-view-css', + ), '3829a3cf' => array( 'javelin-behavior', 'javelin-uri', @@ -1498,6 +1499,9 @@ return array( 'javelin-dom', 'phuix-dropdown-menu', ), + '5d673247' => array( + 'phui-theme-css', + ), '5d83623b' => array( 'javelin-dom', ), @@ -1686,9 +1690,6 @@ return array( 'javelin-stratcom', 'javelin-install', ), - '89fc16b6' => array( - 'phui-theme-css', - ), '8ac32fd9' => array( 'javelin-behavior', 'javelin-stratcom', @@ -1702,9 +1703,6 @@ return array( 'javelin-dom', 'phabricator-busy', ), - '8b9caefe' => array( - 'phui-inline-comment-view-css', - ), '8badee71' => array( 'javelin-install', 'javelin-util', diff --git a/resources/sql/autopatches/20140722.appname.php b/resources/sql/autopatches/20140722.appname.php index dd8e929357..2a337c35aa 100644 --- a/resources/sql/autopatches/20140722.appname.php +++ b/resources/sql/autopatches/20140722.appname.php @@ -4,7 +4,6 @@ $applications = array( 'Audit', 'Auth', 'Calendar', - 'ChatLog', 'Conduit', 'Config', 'Conpherence', diff --git a/resources/sql/autopatches/20230902.repository.01.rebuild-index.php b/resources/sql/autopatches/20230902.repository.01.rebuild-index.php new file mode 100644 index 0000000000..aba27ce78c --- /dev/null +++ b/resources/sql/autopatches/20230902.repository.01.rebuild-index.php @@ -0,0 +1,6 @@ +openTransaction(); -$channel_table->openTransaction(); - -$event_table->beginReadLocking(); -$channel_table->beginReadLocking(); - -$events = new LiskMigrationIterator($event_table); -$conn_w = $channel_table->establishConnection('w'); - -foreach ($events as $event) { - if ($event->getChannelID()) { - continue; - } - - $event_row = queryfx_one( - $conn_w, - 'SELECT channel FROM %T WHERE id = %d', - $event->getTableName(), - $event->getID()); - $event_channel = $event_row['channel']; - - $matched = queryfx_one( - $conn_w, - 'SELECT * FROM %T WHERE - channelName = %s AND serviceName = %s AND serviceType = %s', - $channel_table->getTableName(), - $event_channel, - '', - ''); - - if (!$matched) { - $matched = id(new PhabricatorChatLogChannel()) - ->setChannelName($event_channel) - ->setServiceType('') - ->setServiceName('') - ->setViewPolicy(PhabricatorPolicies::POLICY_USER) - ->setEditPolicy(PhabricatorPolicies::POLICY_USER) - ->save(); - $matched_id = $matched->getID(); - } else { - $matched_id = $matched['id']; - } - - queryfx( - $event->establishConnection('w'), - 'UPDATE %T SET channelID = %d WHERE id = %d', - $event->getTableName(), - $matched_id, - $event->getID()); -} - -$event_table->endReadLocking(); -$channel_table->endReadLocking(); - -$event_table->saveTransaction(); -$channel_table->saveTransaction(); - -echo "\n".pht('Done.')."\n"; +/* This file is intentionally left empty, see T15126 */ diff --git a/resources/sql/patches/20130222.dropchannel.sql b/resources/sql/patches/20130222.dropchannel.sql index 00e6a13f18..04b0e849bc 100644 --- a/resources/sql/patches/20130222.dropchannel.sql +++ b/resources/sql/patches/20130222.dropchannel.sql @@ -1,2 +1 @@ -ALTER TABLE `{$NAMESPACE}_chatlog`.`chatlog_event` - DROP channel; +/* This file is intentionally left empty, see T15126 */ diff --git a/resources/sql/quickstart.sql b/resources/sql/quickstart.sql index b2796d31e6..2df0d4f252 100644 --- a/resources/sql/quickstart.sql +++ b/resources/sql/quickstart.sql @@ -1477,45 +1477,6 @@ CREATE TABLE `edgedata` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET={$CHARSET} COLLATE={$COLLATE_TEXT}; -CREATE DATABASE /*!32312 IF NOT EXISTS*/ `{$NAMESPACE}_chatlog` /*!40100 DEFAULT CHARACTER SET {$CHARSET} COLLATE {$COLLATE_TEXT} */; - -USE `{$NAMESPACE}_chatlog`; - - SET NAMES utf8 ; - - SET character_set_client = {$CHARSET} ; - -CREATE TABLE `chatlog_channel` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `serviceName` varchar(64) CHARACTER SET {$CHARSET} COLLATE {$COLLATE_TEXT} NOT NULL, - `serviceType` varchar(32) CHARACTER SET {$CHARSET} COLLATE {$COLLATE_TEXT} NOT NULL, - `channelName` varchar(64) CHARACTER SET {$CHARSET} COLLATE {$COLLATE_TEXT} NOT NULL, - `viewPolicy` varbinary(64) NOT NULL, - `editPolicy` varbinary(64) NOT NULL, - `dateCreated` int(10) unsigned NOT NULL, - `dateModified` int(10) unsigned NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `key_channel` (`channelName`,`serviceType`,`serviceName`) -) ENGINE=InnoDB DEFAULT CHARSET={$CHARSET} COLLATE={$COLLATE_TEXT}; - -USE `{$NAMESPACE}_chatlog`; - - SET NAMES utf8 ; - - SET character_set_client = {$CHARSET} ; - -CREATE TABLE `chatlog_event` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `epoch` int(10) unsigned NOT NULL, - `author` varchar(64) CHARACTER SET {$CHARSET} COLLATE {$COLLATE_TEXT} NOT NULL, - `type` varchar(4) CHARACTER SET {$CHARSET} COLLATE {$COLLATE_TEXT} NOT NULL, - `message` longtext CHARACTER SET {$CHARSET} COLLATE {$COLLATE_TEXT} NOT NULL, - `loggedByPHID` varbinary(64) NOT NULL, - `channelID` int(10) unsigned NOT NULL, - PRIMARY KEY (`id`), - KEY `channel` (`epoch`) -) ENGINE=InnoDB DEFAULT CHARSET={$CHARSET} COLLATE={$COLLATE_TEXT}; - CREATE DATABASE /*!32312 IF NOT EXISTS*/ `{$NAMESPACE}_conduit` /*!40100 DEFAULT CHARACTER SET {$CHARSET} COLLATE {$COLLATE_TEXT} */; USE `{$NAMESPACE}_conduit`; diff --git a/scripts/init/lib.php b/scripts/init/lib.php index 4c544da9d0..a12c394f3b 100644 --- a/scripts/init/lib.php +++ b/scripts/init/lib.php @@ -13,7 +13,7 @@ function init_phabricator_script(array $options) { if (!$ok) { echo 'FATAL ERROR: Unable to load the "Arcanist" library. '. - 'Put "arcanist/" next to "phabricator/" on disk.'; + 'Put "arcanist/" next to "phorge/" on disk.'; echo "\n"; exit(1); diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 213b6cf6b1..d22dc78970 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -339,9 +339,6 @@ phutil_register_library_map(array( 'CelerityResourcesOnDisk' => 'applications/celerity/resources/CelerityResourcesOnDisk.php', 'CeleritySpriteGenerator' => 'applications/celerity/CeleritySpriteGenerator.php', 'CelerityStaticResourceResponse' => 'applications/celerity/CelerityStaticResourceResponse.php', - 'ChatLogConduitAPIMethod' => 'applications/chatlog/conduit/ChatLogConduitAPIMethod.php', - 'ChatLogQueryConduitAPIMethod' => 'applications/chatlog/conduit/ChatLogQueryConduitAPIMethod.php', - 'ChatLogRecordConduitAPIMethod' => 'applications/chatlog/conduit/ChatLogRecordConduitAPIMethod.php', 'ConduitAPIDocumentationPage' => 'applications/conduit/data/ConduitAPIDocumentationPage.php', 'ConduitAPIMethod' => 'applications/conduit/method/ConduitAPIMethod.php', 'ConduitAPIMethodTestCase' => 'applications/conduit/method/__tests__/ConduitAPIMethodTestCase.php', @@ -488,6 +485,7 @@ phutil_register_library_map(array( 'DifferentialChangesetRenderer' => 'applications/differential/render/DifferentialChangesetRenderer.php', 'DifferentialChangesetSearchConduitAPIMethod' => 'applications/differential/conduit/DifferentialChangesetSearchConduitAPIMethod.php', 'DifferentialChangesetSearchEngine' => 'applications/differential/query/DifferentialChangesetSearchEngine.php', + 'DifferentialChangesetTestCase' => 'applications/differential/storage/__tests__/DifferentialChangesetTestCase.php', 'DifferentialChangesetTestRenderer' => 'applications/differential/render/DifferentialChangesetTestRenderer.php', 'DifferentialChangesetTwoUpRenderer' => 'applications/differential/render/DifferentialChangesetTwoUpRenderer.php', 'DifferentialChangesetTwoUpTestRenderer' => 'applications/differential/render/DifferentialChangesetTwoUpTestRenderer.php', @@ -2807,15 +2805,6 @@ phutil_register_library_map(array( 'PhabricatorChartInterval' => 'applications/fact/chart/PhabricatorChartInterval.php', 'PhabricatorChartRenderingEngine' => 'applications/fact/engine/PhabricatorChartRenderingEngine.php', 'PhabricatorChartStackedAreaDataset' => 'applications/fact/chart/PhabricatorChartStackedAreaDataset.php', - 'PhabricatorChatLogApplication' => 'applications/chatlog/application/PhabricatorChatLogApplication.php', - 'PhabricatorChatLogChannel' => 'applications/chatlog/storage/PhabricatorChatLogChannel.php', - 'PhabricatorChatLogChannelListController' => 'applications/chatlog/controller/PhabricatorChatLogChannelListController.php', - 'PhabricatorChatLogChannelLogController' => 'applications/chatlog/controller/PhabricatorChatLogChannelLogController.php', - 'PhabricatorChatLogChannelQuery' => 'applications/chatlog/query/PhabricatorChatLogChannelQuery.php', - 'PhabricatorChatLogController' => 'applications/chatlog/controller/PhabricatorChatLogController.php', - 'PhabricatorChatLogDAO' => 'applications/chatlog/storage/PhabricatorChatLogDAO.php', - 'PhabricatorChatLogEvent' => 'applications/chatlog/storage/PhabricatorChatLogEvent.php', - 'PhabricatorChatLogQuery' => 'applications/chatlog/query/PhabricatorChatLogQuery.php', 'PhabricatorCheckboxesEditField' => 'applications/transactions/editfield/PhabricatorCheckboxesEditField.php', 'PhabricatorChunkedFileStorageEngine' => 'applications/files/engine/PhabricatorChunkedFileStorageEngine.php', 'PhabricatorClassConfigType' => 'applications/config/type/PhabricatorClassConfigType.php', @@ -4627,6 +4616,7 @@ phutil_register_library_map(array( 'PhabricatorRepositoryIdentityAssignTransaction' => 'applications/repository/xaction/PhabricatorRepositoryIdentityAssignTransaction.php', 'PhabricatorRepositoryIdentityChangeWorker' => 'applications/repository/worker/PhabricatorRepositoryIdentityChangeWorker.php', 'PhabricatorRepositoryIdentityEditEngine' => 'applications/repository/engine/PhabricatorRepositoryIdentityEditEngine.php', + 'PhabricatorRepositoryIdentityEditViewCapability' => 'applications/repository/capability/PhabricatorRepositoryIdentityEditViewCapability.php', 'PhabricatorRepositoryIdentityFerretEngine' => 'applications/repository/search/PhabricatorRepositoryIdentityFerretEngine.php', 'PhabricatorRepositoryIdentityPHIDType' => 'applications/repository/phid/PhabricatorRepositoryIdentityPHIDType.php', 'PhabricatorRepositoryIdentityQuery' => 'applications/repository/query/PhabricatorRepositoryIdentityQuery.php', @@ -5397,6 +5387,8 @@ phutil_register_library_map(array( 'PholioTransactionType' => 'applications/pholio/xaction/PholioTransactionType.php', 'PholioTransactionView' => 'applications/pholio/view/PholioTransactionView.php', 'PholioUploadedImageView' => 'applications/pholio/view/PholioUploadedImageView.php', + 'PhorgeCodeWarningSetupCheck' => 'applications/config/check/PhorgeCodeWarningSetupCheck.php', + 'PhorgeSystemDeprecationWarningListener' => 'applications/system/events/PhorgeSystemDeprecationWarningListener.php', 'PhortuneAccount' => 'applications/phortune/storage/PhortuneAccount.php', 'PhortuneAccountAddManagerController' => 'applications/phortune/controller/account/PhortuneAccountAddManagerController.php', 'PhortuneAccountBillingAddressTransaction' => 'applications/phortune/xaction/PhortuneAccountBillingAddressTransaction.php', @@ -6337,9 +6329,6 @@ phutil_register_library_map(array( 'CelerityResourcesOnDisk' => 'CelerityPhysicalResources', 'CeleritySpriteGenerator' => 'Phobject', 'CelerityStaticResourceResponse' => 'Phobject', - 'ChatLogConduitAPIMethod' => 'ConduitAPIMethod', - 'ChatLogQueryConduitAPIMethod' => 'ChatLogConduitAPIMethod', - 'ChatLogRecordConduitAPIMethod' => 'ChatLogConduitAPIMethod', 'ConduitAPIDocumentationPage' => 'Phobject', 'ConduitAPIMethod' => array( 'Phobject', @@ -6501,6 +6490,7 @@ phutil_register_library_map(array( 'DifferentialChangesetRenderer' => 'Phobject', 'DifferentialChangesetSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod', 'DifferentialChangesetSearchEngine' => 'PhabricatorApplicationSearchEngine', + 'DifferentialChangesetTestCase' => 'PhabricatorTestCase', 'DifferentialChangesetTestRenderer' => 'DifferentialChangesetRenderer', 'DifferentialChangesetTwoUpRenderer' => 'DifferentialChangesetHTMLRenderer', 'DifferentialChangesetTwoUpTestRenderer' => 'DifferentialChangesetTestRenderer', @@ -9188,21 +9178,6 @@ phutil_register_library_map(array( 'PhabricatorChartInterval' => 'Phobject', 'PhabricatorChartRenderingEngine' => 'Phobject', 'PhabricatorChartStackedAreaDataset' => 'PhabricatorChartDataset', - 'PhabricatorChatLogApplication' => 'PhabricatorApplication', - 'PhabricatorChatLogChannel' => array( - 'PhabricatorChatLogDAO', - 'PhabricatorPolicyInterface', - ), - 'PhabricatorChatLogChannelListController' => 'PhabricatorChatLogController', - 'PhabricatorChatLogChannelLogController' => 'PhabricatorChatLogController', - 'PhabricatorChatLogChannelQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', - 'PhabricatorChatLogController' => 'PhabricatorController', - 'PhabricatorChatLogDAO' => 'PhabricatorLiskDAO', - 'PhabricatorChatLogEvent' => array( - 'PhabricatorChatLogDAO', - 'PhabricatorPolicyInterface', - ), - 'PhabricatorChatLogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorCheckboxesEditField' => 'PhabricatorEditField', 'PhabricatorChunkedFileStorageEngine' => 'PhabricatorFileStorageEngine', 'PhabricatorClassConfigType' => 'PhabricatorTextConfigType', @@ -11323,6 +11298,7 @@ phutil_register_library_map(array( 'PhabricatorRepositoryIdentityAssignTransaction' => 'PhabricatorRepositoryIdentityTransactionType', 'PhabricatorRepositoryIdentityChangeWorker' => 'PhabricatorWorker', 'PhabricatorRepositoryIdentityEditEngine' => 'PhabricatorEditEngine', + 'PhabricatorRepositoryIdentityEditViewCapability' => 'PhabricatorPolicyCapability', 'PhabricatorRepositoryIdentityFerretEngine' => 'PhabricatorFerretEngine', 'PhabricatorRepositoryIdentityPHIDType' => 'PhabricatorPHIDType', 'PhabricatorRepositoryIdentityQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', @@ -12234,6 +12210,8 @@ phutil_register_library_map(array( 'PholioTransactionType' => 'PhabricatorModularTransactionType', 'PholioTransactionView' => 'PhabricatorApplicationTransactionView', 'PholioUploadedImageView' => 'AphrontView', + 'PhorgeCodeWarningSetupCheck' => 'PhabricatorSetupCheck', + 'PhorgeSystemDeprecationWarningListener' => 'PhabricatorEventListener', 'PhortuneAccount' => array( 'PhortuneDAO', 'PhabricatorApplicationTransactionInterface', diff --git a/src/applications/audit/storage/PhabricatorAuditTransaction.php b/src/applications/audit/storage/PhabricatorAuditTransaction.php index e6c1062092..8e49d99520 100644 --- a/src/applications/audit/storage/PhabricatorAuditTransaction.php +++ b/src/applications/audit/storage/PhabricatorAuditTransaction.php @@ -338,7 +338,17 @@ final class PhabricatorAuditTransaction $author = null; } - if ($author) { + // Show both Author and Committer only if they are different. + $show_both = $author && $committer; + if ($show_both) { + if ($new['authorPHID']) { + $show_both = $new['authorPHID'] !== $new['committerPHID']; + } else if (phutil_nonempty_string($new['authorName'])) { + $show_both = $new['authorName'] !== $new['committerName']; + } + } + + if ($show_both) { $title = pht( '%s committed %s (authored by %s).', $committer, diff --git a/src/applications/auth/adapter/PhutilOAuth1AuthAdapter.php b/src/applications/auth/adapter/PhutilOAuth1AuthAdapter.php index 08cc65a235..389763da7d 100644 --- a/src/applications/auth/adapter/PhutilOAuth1AuthAdapter.php +++ b/src/applications/auth/adapter/PhutilOAuth1AuthAdapter.php @@ -104,7 +104,7 @@ abstract class PhutilOAuth1AuthAdapter extends PhutilAuthAdapter { ->setSignatureMethod($this->getSignatureMethod()); $consumer_key = $this->getConsumerKey(); - if (strlen($consumer_key)) { + if (phutil_nonempty_string($consumer_key)) { $future->setConsumerKey($consumer_key); } else { throw new Exception( @@ -118,11 +118,11 @@ abstract class PhutilOAuth1AuthAdapter extends PhutilAuthAdapter { $future->setConsumerSecret($consumer_secret); } - if (strlen($this->getToken())) { + if (phutil_nonempty_string($this->getToken())) { $future->setToken($this->getToken()); } - if (strlen($this->getTokenSecret())) { + if (phutil_nonempty_string($this->getTokenSecret())) { $future->setTokenSecret($this->getTokenSecret()); } @@ -137,7 +137,7 @@ abstract class PhutilOAuth1AuthAdapter extends PhutilAuthAdapter { $request_token_uri = $this->getRequestTokenURI(); $future = $this->newOAuth1Future($request_token_uri); - if (strlen($this->getCallbackURI())) { + if (phutil_nonempty_string($this->getCallbackURI())) { $future->setCallbackURI($this->getCallbackURI()); } diff --git a/src/applications/auth/controller/PhabricatorAuthSetExternalController.php b/src/applications/auth/controller/PhabricatorAuthSetExternalController.php index 8b0a44b9dc..2a8bbda7df 100644 --- a/src/applications/auth/controller/PhabricatorAuthSetExternalController.php +++ b/src/applications/auth/controller/PhabricatorAuthSetExternalController.php @@ -40,7 +40,7 @@ final class PhabricatorAuthSetExternalController $text = PhabricatorAuthMessage::loadMessageText( $viewer, PhabricatorAuthLinkMessageType::MESSAGEKEY); - if (!strlen($text)) { + if (!phutil_nonempty_string($text)) { $text = pht( 'You can link your %s account to an external account to '. 'allow you to log in more easily in the future. To continue, choose '. diff --git a/src/applications/auth/controller/contact/PhabricatorAuthContactNumberDisableController.php b/src/applications/auth/controller/contact/PhabricatorAuthContactNumberDisableController.php index a525e7b930..28b7e69593 100644 --- a/src/applications/auth/controller/contact/PhabricatorAuthContactNumberDisableController.php +++ b/src/applications/auth/controller/contact/PhabricatorAuthContactNumberDisableController.php @@ -7,16 +7,19 @@ final class PhabricatorAuthContactNumberDisableController $viewer = $request->getViewer(); $id = $request->getURIData('id'); - $number = id(new PhabricatorAuthContactNumberQuery()) - ->setViewer($viewer) - ->withIDs(array($id)) - ->requireCapabilities( - array( - PhabricatorPolicyCapability::CAN_VIEW, - PhabricatorPolicyCapability::CAN_EDIT, - )) - ->executeOne(); - if (!$number) { + $sms_auth_factor = new PhabricatorSMSAuthFactor(); + if ($sms_auth_factor->isSMSMailerConfigured()) { + $number = id(new PhabricatorAuthContactNumberQuery()) + ->setViewer($viewer) + ->withIDs(array($id)) + ->requireCapabilities( + array( + PhabricatorPolicyCapability::CAN_VIEW, + PhabricatorPolicyCapability::CAN_EDIT, + )) + ->executeOne(); + } + if (!isset($number) || !$number) { return new Aphront404Response(); } diff --git a/src/applications/auth/controller/contact/PhabricatorAuthContactNumberEditController.php b/src/applications/auth/controller/contact/PhabricatorAuthContactNumberEditController.php index 95764496da..c012ca3581 100644 --- a/src/applications/auth/controller/contact/PhabricatorAuthContactNumberEditController.php +++ b/src/applications/auth/controller/contact/PhabricatorAuthContactNumberEditController.php @@ -4,9 +4,14 @@ final class PhabricatorAuthContactNumberEditController extends PhabricatorAuthContactNumberController { public function handleRequest(AphrontRequest $request) { - return id(new PhabricatorAuthContactNumberEditEngine()) - ->setController($this) - ->buildResponse(); + $sms_auth_factor = new PhabricatorSMSAuthFactor(); + if ($sms_auth_factor->isSMSMailerConfigured()) { + return id(new PhabricatorAuthContactNumberEditEngine()) + ->setController($this) + ->buildResponse(); + } else { + return new Aphront404Response(); + } } } diff --git a/src/applications/auth/controller/contact/PhabricatorAuthContactNumberPrimaryController.php b/src/applications/auth/controller/contact/PhabricatorAuthContactNumberPrimaryController.php index cad1bbf3fc..63ba5ad883 100644 --- a/src/applications/auth/controller/contact/PhabricatorAuthContactNumberPrimaryController.php +++ b/src/applications/auth/controller/contact/PhabricatorAuthContactNumberPrimaryController.php @@ -7,16 +7,19 @@ final class PhabricatorAuthContactNumberPrimaryController $viewer = $request->getViewer(); $id = $request->getURIData('id'); - $number = id(new PhabricatorAuthContactNumberQuery()) - ->setViewer($viewer) - ->withIDs(array($id)) - ->requireCapabilities( - array( - PhabricatorPolicyCapability::CAN_VIEW, - PhabricatorPolicyCapability::CAN_EDIT, - )) - ->executeOne(); - if (!$number) { + $sms_auth_factor = new PhabricatorSMSAuthFactor(); + if ($sms_auth_factor->isSMSMailerConfigured()) { + $number = id(new PhabricatorAuthContactNumberQuery()) + ->setViewer($viewer) + ->withIDs(array($id)) + ->requireCapabilities( + array( + PhabricatorPolicyCapability::CAN_VIEW, + PhabricatorPolicyCapability::CAN_EDIT, + )) + ->executeOne(); + } + if (!isset($number) || !$number) { return new Aphront404Response(); } diff --git a/src/applications/auth/controller/contact/PhabricatorAuthContactNumberTestController.php b/src/applications/auth/controller/contact/PhabricatorAuthContactNumberTestController.php index f8c8b013bf..a991c34a6d 100644 --- a/src/applications/auth/controller/contact/PhabricatorAuthContactNumberTestController.php +++ b/src/applications/auth/controller/contact/PhabricatorAuthContactNumberTestController.php @@ -7,16 +7,19 @@ final class PhabricatorAuthContactNumberTestController $viewer = $request->getViewer(); $id = $request->getURIData('id'); - $number = id(new PhabricatorAuthContactNumberQuery()) - ->setViewer($viewer) - ->withIDs(array($id)) - ->requireCapabilities( - array( - PhabricatorPolicyCapability::CAN_VIEW, - PhabricatorPolicyCapability::CAN_EDIT, - )) - ->executeOne(); - if (!$number) { + $sms_auth_factor = new PhabricatorSMSAuthFactor(); + if ($sms_auth_factor->isSMSMailerConfigured()) { + $number = id(new PhabricatorAuthContactNumberQuery()) + ->setViewer($viewer) + ->withIDs(array($id)) + ->requireCapabilities( + array( + PhabricatorPolicyCapability::CAN_VIEW, + PhabricatorPolicyCapability::CAN_EDIT, + )) + ->executeOne(); + } + if (!isset($number) || !$number) { return new Aphront404Response(); } diff --git a/src/applications/auth/controller/contact/PhabricatorAuthContactNumberViewController.php b/src/applications/auth/controller/contact/PhabricatorAuthContactNumberViewController.php index 027d288dbc..75e4b8e3b7 100644 --- a/src/applications/auth/controller/contact/PhabricatorAuthContactNumberViewController.php +++ b/src/applications/auth/controller/contact/PhabricatorAuthContactNumberViewController.php @@ -6,11 +6,14 @@ final class PhabricatorAuthContactNumberViewController public function handleRequest(AphrontRequest $request) { $viewer = $this->getViewer(); - $number = id(new PhabricatorAuthContactNumberQuery()) - ->setViewer($viewer) - ->withIDs(array($request->getURIData('id'))) - ->executeOne(); - if (!$number) { + $sms_auth_factor = new PhabricatorSMSAuthFactor(); + if ($sms_auth_factor->isSMSMailerConfigured()) { + $number = id(new PhabricatorAuthContactNumberQuery()) + ->setViewer($viewer) + ->withIDs(array($request->getURIData('id'))) + ->executeOne(); + } + if (!isset($number) || !$number) { return new Aphront404Response(); } diff --git a/src/applications/auth/engine/PhabricatorAuthCSRFEngine.php b/src/applications/auth/engine/PhabricatorAuthCSRFEngine.php index fcb8c13ab7..856b334039 100644 --- a/src/applications/auth/engine/PhabricatorAuthCSRFEngine.php +++ b/src/applications/auth/engine/PhabricatorAuthCSRFEngine.php @@ -47,7 +47,10 @@ final class PhabricatorAuthCSRFEngine extends Phobject { // We expect a BREACH-mitigating token. See T3684. $breach_prefix = $this->getBREACHPrefix(); $breach_prelen = strlen($breach_prefix); - if (strncmp($token, $breach_prefix, $breach_prelen) !== 0) { + if ( + $token === null || + strncmp($token, $breach_prefix, $breach_prelen) !== 0 + ) { return false; } diff --git a/src/applications/auth/factor/PhabricatorSMSAuthFactor.php b/src/applications/auth/factor/PhabricatorSMSAuthFactor.php index 33f640e692..2350855859 100644 --- a/src/applications/auth/factor/PhabricatorSMSAuthFactor.php +++ b/src/applications/auth/factor/PhabricatorSMSAuthFactor.php @@ -334,7 +334,7 @@ final class PhabricatorSMSAuthFactor return $value; } - private function isSMSMailerConfigured() { + public function isSMSMailerConfigured() { $mailers = PhabricatorMetaMTAMail::newMailers( array( 'outbound' => true, diff --git a/src/applications/auth/guidance/PhabricatorAuthProvidersGuidanceEngineExtension.php b/src/applications/auth/guidance/PhabricatorAuthProvidersGuidanceEngineExtension.php index d4d41f1d83..8d823f82c2 100644 --- a/src/applications/auth/guidance/PhabricatorAuthProvidersGuidanceEngineExtension.php +++ b/src/applications/auth/guidance/PhabricatorAuthProvidersGuidanceEngineExtension.php @@ -53,9 +53,8 @@ final class PhabricatorAuthProvidersGuidanceEngineExtension ->setMessage($message); } else { $message = pht( - 'Anyone who can browse to this this server will be able to '. - 'register an account. To add email domain restrictions, configure '. - '%s.', + 'Anyone who can browse to this server will be able to register '. + 'an account. To add email domain restrictions, configure %s.', $domains_link); $results[] = $this->newGuidance('core.auth.email-domains.off') diff --git a/src/applications/auth/provider/PhabricatorOAuth1AuthProvider.php b/src/applications/auth/provider/PhabricatorOAuth1AuthProvider.php index b1590b9c82..7133cff042 100644 --- a/src/applications/auth/provider/PhabricatorOAuth1AuthProvider.php +++ b/src/applications/auth/provider/PhabricatorOAuth1AuthProvider.php @@ -67,7 +67,7 @@ abstract class PhabricatorOAuth1AuthProvider } $denied = $request->getStr('denied'); - if (strlen($denied)) { + if ($denied) { // Twitter indicates that the user cancelled the login attempt by // returning "denied" as a parameter. throw new PhutilAuthUserAbortedException(); diff --git a/src/applications/auth/storage/PhabricatorAuthProviderConfigTransaction.php b/src/applications/auth/storage/PhabricatorAuthProviderConfigTransaction.php index f60ba8c734..d7f974cb15 100644 --- a/src/applications/auth/storage/PhabricatorAuthProviderConfigTransaction.php +++ b/src/applications/auth/storage/PhabricatorAuthProviderConfigTransaction.php @@ -150,7 +150,7 @@ final class PhabricatorAuthProviderConfigTransaction $provider = $this->getProvider(); if ($provider) { $title = $provider->renderConfigPropertyTransactionTitle($this); - if (strlen($title)) { + if (phutil_nonempty_string($title)) { return $title; } } diff --git a/src/applications/auth/view/PhabricatorAuthAccountView.php b/src/applications/auth/view/PhabricatorAuthAccountView.php index 9746be7841..f903f45d26 100644 --- a/src/applications/auth/view/PhabricatorAuthAccountView.php +++ b/src/applications/auth/view/PhabricatorAuthAccountView.php @@ -29,13 +29,14 @@ final class PhabricatorAuthAccountView extends AphrontView { $realname = $account->getRealName(); $use_name = null; - if (strlen($dispname)) { + if (phutil_nonempty_string($dispname)) { $use_name = $dispname; - } else if (strlen($username) && strlen($realname)) { + } else if (phutil_nonempty_string($username) && + phutil_nonempty_string($realname)) { $use_name = $username.' ('.$realname.')'; - } else if (strlen($username)) { + } else if (phutil_nonempty_string($username)) { $use_name = $username; - } else if (strlen($realname)) { + } else if (phutil_nonempty_string($realname)) { $use_name = $realname; } diff --git a/src/applications/base/PhabricatorApplication.php b/src/applications/base/PhabricatorApplication.php index 9e1ea7d5ba..67294db263 100644 --- a/src/applications/base/PhabricatorApplication.php +++ b/src/applications/base/PhabricatorApplication.php @@ -61,6 +61,21 @@ abstract class PhabricatorApplication return pht('%s Application', $this->getName()); } + /** + * Extensions are allowed to register multi-character monograms. + * The name "Monogram" is actually a bit of a misnomer, + * but we're keeping it due to the history. + * + * @return array + */ + public function getMonograms() { + return array(); + } + + public function isDeprecated() { + return false; + } + final public function isInstalled() { if (!$this->canUninstall()) { return true; diff --git a/src/applications/calendar/application/PhabricatorCalendarApplication.php b/src/applications/calendar/application/PhabricatorCalendarApplication.php index fa534280a0..c9ff3ac9d3 100644 --- a/src/applications/calendar/application/PhabricatorCalendarApplication.php +++ b/src/applications/calendar/application/PhabricatorCalendarApplication.php @@ -28,6 +28,10 @@ final class PhabricatorCalendarApplication extends PhabricatorApplication { return "\xE2\x8C\xA8"; } + public function getMonograms() { + return array('E'); + } + public function getApplicationGroup() { return self::GROUP_UTILITIES; } diff --git a/src/applications/calendar/editor/PhabricatorCalendarImportEditEngine.php b/src/applications/calendar/editor/PhabricatorCalendarImportEditEngine.php index 9a4a7c0107..7be3969671 100644 --- a/src/applications/calendar/editor/PhabricatorCalendarImportEditEngine.php +++ b/src/applications/calendar/editor/PhabricatorCalendarImportEditEngine.php @@ -83,12 +83,6 @@ final class PhabricatorCalendarImportEditEngine $engine = $object->getEngine(); $can_trigger = $engine->supportsTriggers($object); - // calendar URI import - // note that it can contains a secret token - // if we are here you have enough privileges to edit and see the value - $uri_key = PhabricatorCalendarImportICSURITransaction::PARAMKEY_URI; - $uri = $object->getParameter($uri_key); - $fields = array( id(new PhabricatorTextEditField()) ->setKey('name') @@ -100,15 +94,6 @@ final class PhabricatorCalendarImportEditEngine ->setConduitTypeDescription(pht('New import name.')) ->setPlaceholder($object->getDisplayName()) ->setValue($object->getName()), - id(new PhabricatorTextEditField()) - ->setKey('uri') - ->setLabel(pht('URI')) - ->setDescription(pht('URI to import.')) - ->setTransactionType( - PhabricatorCalendarImportICSURITransaction::TRANSACTIONTYPE) - ->setConduitDescription(pht('URI to import.')) - ->setConduitTypeDescription(pht('New URI.')) - ->setValue($uri), id(new PhabricatorBoolEditField()) ->setKey('disabled') ->setOptions(pht('Active'), pht('Disabled')) diff --git a/src/applications/calendar/import/PhabricatorCalendarICSURIImportEngine.php b/src/applications/calendar/import/PhabricatorCalendarICSURIImportEngine.php index bd52ec5bc2..6c992e0836 100644 --- a/src/applications/calendar/import/PhabricatorCalendarICSURIImportEngine.php +++ b/src/applications/calendar/import/PhabricatorCalendarICSURIImportEngine.php @@ -58,16 +58,19 @@ final class PhabricatorCalendarICSURIImportEngine PhabricatorCalendarImport $import) { $fields = array(); - if ($engine->getIsCreate()) { - $fields[] = id(new PhabricatorTextEditField()) - ->setKey('uri') - ->setLabel(pht('URI')) - ->setDescription(pht('URI to import.')) - ->setTransactionType( - PhabricatorCalendarImportICSURITransaction::TRANSACTIONTYPE) - ->setConduitDescription(pht('URI to import.')) - ->setConduitTypeDescription(pht('New URI.')); - } + // If you are here, you already have the "can edit" capability. + // So you are supposed to be able to edit again your Calendar import URI. + $uri_key = PhabricatorCalendarImportICSURITransaction::PARAMKEY_URI; + $uri = $import->getParameter($uri_key); + $fields[] = id(new PhabricatorTextEditField()) + ->setKey('uri') + ->setLabel(pht('URI')) + ->setDescription(pht('URI to import.')) + ->setTransactionType( + PhabricatorCalendarImportICSURITransaction::TRANSACTIONTYPE) + ->setConduitDescription(pht('URI to import.')) + ->setConduitTypeDescription(pht('New URI.')) + ->setValue($uri); return $fields; } diff --git a/src/applications/calendar/import/PhabricatorCalendarImportEngine.php b/src/applications/calendar/import/PhabricatorCalendarImportEngine.php index 35e94634fe..626757c61d 100644 --- a/src/applications/calendar/import/PhabricatorCalendarImportEngine.php +++ b/src/applications/calendar/import/PhabricatorCalendarImportEngine.php @@ -447,7 +447,7 @@ abstract class PhabricatorCalendarImportEngine private function getParentNodeUID(PhutilCalendarEventNode $node) { $recurrence_id = $node->getRecurrenceID(); - if (!strlen($recurrence_id)) { + if (!phutil_nonempty_string($recurrence_id)) { return null; } @@ -456,7 +456,7 @@ abstract class PhabricatorCalendarImportEngine private function getNodeInstanceEpoch(PhutilCalendarEventNode $node) { $instance_iso = $node->getRecurrenceID(); - if (strlen($instance_iso)) { + if (phutil_nonempty_string($instance_iso)) { $instance_datetime = PhutilCalendarAbsoluteDateTime::newFromISO8601( $instance_iso); $instance_epoch = $instance_datetime->getEpoch(); diff --git a/src/applications/chatlog/application/PhabricatorChatLogApplication.php b/src/applications/chatlog/application/PhabricatorChatLogApplication.php deleted file mode 100644 index 912ddd9b6b..0000000000 --- a/src/applications/chatlog/application/PhabricatorChatLogApplication.php +++ /dev/null @@ -1,43 +0,0 @@ - array( - '' => 'PhabricatorChatLogChannelListController', - 'channel/(?P[^/]+)/' - => 'PhabricatorChatLogChannelLogController', - ), - ); - } - -} diff --git a/src/applications/chatlog/conduit/ChatLogConduitAPIMethod.php b/src/applications/chatlog/conduit/ChatLogConduitAPIMethod.php deleted file mode 100644 index e524ef60da..0000000000 --- a/src/applications/chatlog/conduit/ChatLogConduitAPIMethod.php +++ /dev/null @@ -1,9 +0,0 @@ - 'optional list', - 'limit' => 'optional int (default = 100)', - ); - } - - protected function defineReturnType() { - return 'nonempty list'; - } - - protected function execute(ConduitAPIRequest $request) { - $query = new PhabricatorChatLogQuery(); - - $channel_ids = $request->getValue('channelIDs'); - if ($channel_ids) { - $query->withChannelIDs($channel_ids); - } - - $limit = $request->getValue('limit'); - if (!$limit) { - $limit = 100; - } - $query->setLimit($limit); - - $logs = $query->execute(); - - $results = array(); - foreach ($logs as $log) { - $results[] = array( - 'channelID' => $log->getChannelID(), - 'epoch' => $log->getEpoch(), - 'author' => $log->getAuthor(), - 'type' => $log->getType(), - 'message' => $log->getMessage(), - 'loggedByPHID' => $log->getLoggedByPHID(), - ); - } - - return $results; - } - -} diff --git a/src/applications/chatlog/conduit/ChatLogRecordConduitAPIMethod.php b/src/applications/chatlog/conduit/ChatLogRecordConduitAPIMethod.php deleted file mode 100644 index fe972222ae..0000000000 --- a/src/applications/chatlog/conduit/ChatLogRecordConduitAPIMethod.php +++ /dev/null @@ -1,72 +0,0 @@ - 'required list', - ); - } - - protected function defineReturnType() { - return 'list'; - } - - protected function execute(ConduitAPIRequest $request) { - $logs = $request->getValue('logs'); - if (!is_array($logs)) { - $logs = array(); - } - - $template = new PhabricatorChatLogEvent(); - $template->setLoggedByPHID($request->getUser()->getPHID()); - - $objs = array(); - foreach ($logs as $log) { - $channel_name = idx($log, 'channel'); - $service_name = idx($log, 'serviceName'); - $service_type = idx($log, 'serviceType'); - - $channel = id(new PhabricatorChatLogChannel())->loadOneWhere( - 'channelName = %s AND serviceName = %s AND serviceType = %s', - $channel_name, - $service_name, - $service_type); - - if (!$channel) { - $channel = id(new PhabricatorChatLogChannel()) - ->setChannelName($channel_name) - ->setserviceName($service_name) - ->setServiceType($service_type) - ->setViewPolicy(PhabricatorPolicies::POLICY_USER) - ->setEditPolicy(PhabricatorPolicies::POLICY_USER) - ->save(); - } - - $obj = clone $template; - $obj->setChannelID($channel->getID()); - $obj->setType(idx($log, 'type')); - $obj->setAuthor(idx($log, 'author')); - $obj->setEpoch(idx($log, 'epoch')); - $obj->setMessage(idx($log, 'message')); - $obj->save(); - - $objs[] = $obj; - } - - return array_values(mpull($objs, 'getID')); - } - -} diff --git a/src/applications/chatlog/controller/PhabricatorChatLogChannelListController.php b/src/applications/chatlog/controller/PhabricatorChatLogChannelListController.php deleted file mode 100644 index 530c26770a..0000000000 --- a/src/applications/chatlog/controller/PhabricatorChatLogChannelListController.php +++ /dev/null @@ -1,41 +0,0 @@ -getViewer(); - - $channels = id(new PhabricatorChatLogChannelQuery()) - ->setViewer($viewer) - ->execute(); - - $list = new PHUIObjectItemListView(); - foreach ($channels as $channel) { - $item = id(new PHUIObjectItemView()) - ->setHeader($channel->getChannelName()) - ->setHref('/chatlog/channel/'.$channel->getID().'/') - ->addAttribute($channel->getServiceName()) - ->addAttribute($channel->getServiceType()); - $list->addItem($item); - } - - $crumbs = $this - ->buildApplicationCrumbs() - ->addTextCrumb(pht('Channel List'), $this->getApplicationURI()); - - $box = id(new PHUIObjectBoxView()) - ->setHeaderText('Channel List') - ->setObjectList($list); - - return $this->newPage() - ->setTitle(pht('Channel List')) - ->setCrumbs($crumbs) - ->appendChild($box); - - } -} diff --git a/src/applications/chatlog/controller/PhabricatorChatLogChannelLogController.php b/src/applications/chatlog/controller/PhabricatorChatLogChannelLogController.php deleted file mode 100644 index b9893f6924..0000000000 --- a/src/applications/chatlog/controller/PhabricatorChatLogChannelLogController.php +++ /dev/null @@ -1,320 +0,0 @@ -getViewer(); - $id = $request->getURIData('channelID'); - - $uri = new PhutilURI($request->getPath()); - - $pager = new AphrontCursorPagerView(); - $pager->setURI($uri); - $pager->setPageSize(250); - - $query = id(new PhabricatorChatLogQuery()) - ->setViewer($viewer) - ->withChannelIDs(array($id)); - - $channel = id(new PhabricatorChatLogChannelQuery()) - ->setViewer($viewer) - ->withIDs(array($id)) - ->executeOne(); - - if (!$channel) { - return new Aphront404Response(); - } - - list($after, $before, $map) = $this->getPagingParameters($request, $query); - - $pager->setAfterID($after); - $pager->setBeforeID($before); - - $logs = $query->executeWithCursorPager($pager); - - // Show chat logs oldest-first. - $logs = array_reverse($logs); - - - // Divide all the logs into blocks, where a block is the same author saying - // several things in a row. A block ends when another user speaks, or when - // two minutes pass without the author speaking. - - $blocks = array(); - $block = null; - - $last_author = null; - $last_epoch = null; - foreach ($logs as $log) { - $this_author = $log->getAuthor(); - $this_epoch = $log->getEpoch(); - - // Decide whether we should start a new block or not. - $new_block = ($this_author !== $last_author) || - ($this_epoch - (60 * 2) > $last_epoch); - - if ($new_block) { - if ($block) { - $blocks[] = $block; - } - $block = array( - 'id' => $log->getID(), - 'epoch' => $this_epoch, - 'author' => $this_author, - 'logs' => array($log), - ); - } else { - $block['logs'][] = $log; - } - - $last_author = $this_author; - $last_epoch = $this_epoch; - } - if ($block) { - $blocks[] = $block; - } - - // Figure out CSS classes for the blocks. We alternate colors between - // lines, and highlight the entire block which contains the target ID or - // date, if applicable. - - foreach ($blocks as $key => $block) { - $classes = array(); - if ($key % 2) { - $classes[] = 'alternate'; - } - $ids = mpull($block['logs'], 'getID', 'getID'); - if (array_intersect_key($ids, $map)) { - $classes[] = 'highlight'; - } - $blocks[$key]['class'] = $classes ? implode(' ', $classes) : null; - } - - - require_celerity_resource('phabricator-chatlog-css'); - - $out = array(); - foreach ($blocks as $block) { - $author = $block['author']; - $author = id(new PhutilUTF8StringTruncator()) - ->setMaximumGlyphs(18) - ->truncateString($author); - $author = phutil_tag('td', array('class' => 'author'), $author); - - $href = $uri->alter('at', $block['id']); - $timestamp = $block['epoch']; - $timestamp = phabricator_datetime($timestamp, $viewer); - $timestamp = phutil_tag( - 'a', - array( - 'href' => $href, - 'class' => 'timestamp', - ), - $timestamp); - - $message = mpull($block['logs'], 'getMessage'); - $message = implode("\n", $message); - $message = phutil_tag( - 'td', - array( - 'class' => 'message', - ), - array( - $timestamp, - $message, - )); - - $out[] = phutil_tag( - 'tr', - array( - 'class' => $block['class'], - ), - array( - $author, - $message, - )); - } - - $links = array(); - - $first_uri = $pager->getFirstPageURI(); - if ($first_uri) { - $links[] = phutil_tag( - 'a', - array( - 'href' => $first_uri, - ), - "\xC2\xAB ".pht('Newest')); - } - - $prev_uri = $pager->getPrevPageURI(); - if ($prev_uri) { - $links[] = phutil_tag( - 'a', - array( - 'href' => $prev_uri, - ), - "\xE2\x80\xB9 ".pht('Newer')); - } - - $next_uri = $pager->getNextPageURI(); - if ($next_uri) { - $links[] = phutil_tag( - 'a', - array( - 'href' => $next_uri, - ), - pht('Older')." \xE2\x80\xBA"); - } - - $pager_bottom = phutil_tag( - 'div', - array('class' => 'phabricator-chat-log-pager-bottom'), - $links); - - $crumbs = $this - ->buildApplicationCrumbs() - ->addTextCrumb($channel->getChannelName(), $uri); - - $form = id(new AphrontFormView()) - ->setUser($viewer) - ->setMethod('GET') - ->setAction($uri) - ->appendChild( - id(new AphrontFormTextControl()) - ->setLabel(pht('Date')) - ->setName('date') - ->setValue($request->getStr('date'))) - ->appendChild( - id(new AphrontFormSubmitControl()) - ->setValue(pht('Jump'))); - - $table = phutil_tag( - 'table', - array( - 'class' => 'phabricator-chat-log', - ), - $out); - - $log = phutil_tag( - 'div', - array( - 'class' => 'phabricator-chat-log-panel', - ), - $table); - - $jump_link = id(new PHUIButtonView()) - ->setTag('a') - ->setHref('#latest') - ->setText(pht('Jump to Bottom')) - ->setIcon('fa-arrow-circle-down'); - - $jump_target = phutil_tag( - 'div', - array( - 'id' => 'latest', - )); - - $content = phutil_tag( - 'div', - array( - 'class' => 'phabricator-chat-log-wrap', - ), - array( - $log, - $jump_target, - $pager_bottom, - )); - - $header = id(new PHUIHeaderView()) - ->setHeader($channel->getChannelName()) - ->setSubHeader($channel->getServiceName()) - ->addActionLink($jump_link); - - $box = id(new PHUIObjectBoxView()) - ->setHeader($header) - ->setCollapsed(true) - ->appendChild($content); - - $box->setShowHide( - pht('Search Dates'), - pht('Hide Dates'), - $form, - '#'); - - return $this->newPage() - ->setTitle(pht('Channel Log')) - ->setCrumbs($crumbs) - ->appendChild($box); - - } - - /** - * From request parameters, figure out where we should jump to in the log. - * We jump to either a date or log ID, but load a few lines of context before - * it so the user can see the nearby conversation. - */ - private function getPagingParameters( - AphrontRequest $request, - PhabricatorChatLogQuery $query) { - - $viewer = $request->getViewer(); - - $at_id = $request->getInt('at'); - $at_date = $request->getStr('date'); - - $context_log = null; - $map = array(); - - $query = clone $query; - $query->setLimit(8); - - if ($at_id) { - // Jump to the log in question, and load a few lines of context before - // it. - $context_logs = $query - ->setAfterID($at_id) - ->execute(); - - $context_log = last($context_logs); - - $map = array( - $at_id => true, - ); - - } else if ($at_date) { - $timestamp = PhabricatorTime::parseLocalTime($at_date, $viewer); - - if ($timestamp) { - $context_logs = $query - ->withMaximumEpoch($timestamp) - ->execute(); - - $context_log = last($context_logs); - - $target_log = head($context_logs); - if ($target_log) { - $map = array( - $target_log->getID() => true, - ); - } - } - } - - if ($context_log) { - $after = null; - $before = $context_log->getID() - 1; - } else { - $after = $request->getInt('after'); - $before = $request->getInt('before'); - } - - return array($after, $before, $map); - } - -} diff --git a/src/applications/chatlog/controller/PhabricatorChatLogController.php b/src/applications/chatlog/controller/PhabricatorChatLogController.php deleted file mode 100644 index 64fcbf20bb..0000000000 --- a/src/applications/chatlog/controller/PhabricatorChatLogController.php +++ /dev/null @@ -1,3 +0,0 @@ -channels = $channels; - return $this; - } - - public function withIDs(array $channel_ids) { - $this->channelIDs = $channel_ids; - return $this; - } - - protected function loadPage() { - $table = new PhabricatorChatLogChannel(); - $conn_r = $table->establishConnection('r'); - - $data = queryfx_all( - $conn_r, - 'SELECT * FROM %T c %Q %Q %Q', - $table->getTableName(), - $this->buildWhereClause($conn_r), - $this->buildOrderClause($conn_r), - $this->buildLimitClause($conn_r)); - - $logs = $table->loadAllFromArray($data); - - return $logs; - } - - protected function buildWhereClause(AphrontDatabaseConnection $conn) { - $where = array(); - - $where[] = $this->buildPagingClause($conn); - - if ($this->channelIDs) { - $where[] = qsprintf( - $conn, - 'id IN (%Ld)', - $this->channelIDs); - - } - - if ($this->channels) { - $where[] = qsprintf( - $conn, - 'channelName IN (%Ls)', - $this->channels); - } - - return $this->formatWhereClause($conn, $where); - } - - public function getQueryApplicationClass() { - return 'PhabricatorChatLogApplication'; - } - -} diff --git a/src/applications/chatlog/query/PhabricatorChatLogQuery.php b/src/applications/chatlog/query/PhabricatorChatLogQuery.php deleted file mode 100644 index 88cf6da7e3..0000000000 --- a/src/applications/chatlog/query/PhabricatorChatLogQuery.php +++ /dev/null @@ -1,84 +0,0 @@ -channelIDs = $channel_ids; - return $this; - } - - public function withMaximumEpoch($epoch) { - $this->maximumEpoch = $epoch; - return $this; - } - - protected function loadPage() { - $table = new PhabricatorChatLogEvent(); - $conn_r = $table->establishConnection('r'); - - $data = queryfx_all( - $conn_r, - 'SELECT * FROM %T e %Q %Q %Q', - $table->getTableName(), - $this->buildWhereClause($conn_r), - $this->buildOrderClause($conn_r), - $this->buildLimitClause($conn_r)); - - $logs = $table->loadAllFromArray($data); - - return $logs; - } - - protected function willFilterPage(array $events) { - $channel_ids = mpull($events, 'getChannelID', 'getChannelID'); - - $channels = id(new PhabricatorChatLogChannelQuery()) - ->setViewer($this->getViewer()) - ->withIDs($channel_ids) - ->execute(); - $channels = mpull($channels, null, 'getID'); - - foreach ($events as $key => $event) { - $channel = idx($channels, $event->getChannelID()); - if (!$channel) { - unset($events[$key]); - continue; - } - - $event->attachChannel($channel); - } - - return $events; - } - - protected function buildWhereClause(AphrontDatabaseConnection $conn) { - $where = array(); - - $where[] = $this->buildPagingClause($conn); - - if ($this->maximumEpoch !== null) { - $where[] = qsprintf( - $conn, - 'epoch <= %d', - $this->maximumEpoch); - } - - if ($this->channelIDs !== null) { - $where[] = qsprintf( - $conn, - 'channelID IN (%Ld)', - $this->channelIDs); - } - - return $this->formatWhereClause($conn, $where); - } - - public function getQueryApplicationClass() { - return 'PhabricatorChatLogApplication'; - } - -} diff --git a/src/applications/chatlog/storage/PhabricatorChatLogChannel.php b/src/applications/chatlog/storage/PhabricatorChatLogChannel.php deleted file mode 100644 index 2e62bcb6cf..0000000000 --- a/src/applications/chatlog/storage/PhabricatorChatLogChannel.php +++ /dev/null @@ -1,51 +0,0 @@ - array( - 'serviceName' => 'text64', - 'serviceType' => 'text32', - 'channelName' => 'text64', - ), - self::CONFIG_KEY_SCHEMA => array( - 'key_channel' => array( - 'columns' => array('channelName', 'serviceType', 'serviceName'), - 'unique' => true, - ), - ), - ) + parent::getConfiguration(); - } - - public function getCapabilities() { - return array( - PhabricatorPolicyCapability::CAN_VIEW, - PhabricatorPolicyCapability::CAN_EDIT, - ); - } - - public function getPolicy($capability) { - switch ($capability) { - case PhabricatorPolicyCapability::CAN_VIEW: - return $this->viewPolicy; - break; - case PhabricatorPolicyCapability::CAN_EDIT: - return $this->editPolicy; - break; - } - } - - public function hasAutomaticCapability($capability, PhabricatorUser $viewer) { - return false; - } - -} diff --git a/src/applications/chatlog/storage/PhabricatorChatLogDAO.php b/src/applications/chatlog/storage/PhabricatorChatLogDAO.php deleted file mode 100644 index 8014168814..0000000000 --- a/src/applications/chatlog/storage/PhabricatorChatLogDAO.php +++ /dev/null @@ -1,9 +0,0 @@ - false, - self::CONFIG_COLUMN_SCHEMA => array( - 'author' => 'text64', - 'type' => 'text4', - 'message' => 'text', - ), - self::CONFIG_KEY_SCHEMA => array( - 'channel' => array( - 'columns' => array('epoch'), - ), - ), - ) + parent::getConfiguration(); - } - - public function attachChannel(PhabricatorChatLogChannel $channel) { - $this->channel = $channel; - return $this; - } - - public function getChannel() { - return $this->assertAttached($this->channel); - } - - -/* -( PhabricatorPolicyInterface )----------------------------------------- */ - - - public function getCapabilities() { - return array( - PhabricatorPolicyCapability::CAN_VIEW, - ); - } - - public function getPolicy($capability) { - return $this->getChannel()->getPolicy($capability); - } - - public function hasAutomaticCapability($capability, PhabricatorUser $viewer) { - return $this->getChannel()->hasAutomaticCapability($capability, $viewer); - } - -} diff --git a/src/applications/config/check/PhabricatorAuthSetupCheck.php b/src/applications/config/check/PhabricatorAuthSetupCheck.php index e2b076944e..8705047263 100644 --- a/src/applications/config/check/PhabricatorAuthSetupCheck.php +++ b/src/applications/config/check/PhabricatorAuthSetupCheck.php @@ -74,7 +74,8 @@ final class PhabricatorAuthSetupCheck extends PhabricatorSetupCheck { ->addRelatedPhabricatorConfig('auth.lock-config') ->addCommand( hsprintf( - 'phabricator/ $ ./bin/auth lock')); + '%s $./bin/auth lock', + PlatformSymbols::getPlatformServerPath())); } } } diff --git a/src/applications/config/check/PhabricatorBaseURISetupCheck.php b/src/applications/config/check/PhabricatorBaseURISetupCheck.php index 92e46641d7..e73c1455bf 100644 --- a/src/applications/config/check/PhabricatorBaseURISetupCheck.php +++ b/src/applications/config/check/PhabricatorBaseURISetupCheck.php @@ -96,9 +96,8 @@ final class PhabricatorBaseURISetupCheck extends PhabricatorSetupCheck { ->setMessage($message) ->addCommand( hsprintf( - '$ %s', - csprintf( - './bin/config set phabricator.base-uri %s', - $base_uri_guess))); + '%s $./bin/config set phabricator.base-uri %s', + PlatformSymbols::getPlatformServerPath(), + $base_uri_guess)); } } diff --git a/src/applications/config/check/PhabricatorDaemonsSetupCheck.php b/src/applications/config/check/PhabricatorDaemonsSetupCheck.php index df5821665c..ceedd5137e 100644 --- a/src/applications/config/check/PhabricatorDaemonsSetupCheck.php +++ b/src/applications/config/check/PhabricatorDaemonsSetupCheck.php @@ -49,7 +49,10 @@ final class PhabricatorDaemonsSetupCheck extends PhabricatorSetupCheck { ->setName(pht('Daemons Are Not Running')) ->setSummary($summary) ->setMessage($message) - ->addCommand('$ ./bin/phd start'); + ->addCommand( + hsprintf( + '%s $./bin/phd start', + PlatformSymbols::getPlatformServerPath())); } $expect_user = PhabricatorEnv::getEnvConfig('phd.user'); @@ -90,7 +93,10 @@ final class PhabricatorDaemonsSetupCheck extends PhabricatorSetupCheck { ->setSummary($summary) ->setMessage($message) ->addPhabricatorConfig('phd.user') - ->addCommand('$ ./bin/phd restart'); + ->addCommand( + hsprintf( + '%s $./bin/phd restart', + PlatformSymbols::getPlatformServerPath())); break; } diff --git a/src/applications/config/check/PhabricatorDatabaseSetupCheck.php b/src/applications/config/check/PhabricatorDatabaseSetupCheck.php index d3f6d52f04..99815d85e6 100644 --- a/src/applications/config/check/PhabricatorDatabaseSetupCheck.php +++ b/src/applications/config/check/PhabricatorDatabaseSetupCheck.php @@ -35,11 +35,13 @@ final class PhabricatorDatabaseSetupCheck extends PhabricatorSetupCheck { ->addPhabricatorConfig('mysql.port') ->addCommand( hsprintf( - '$ ./bin/config set mysql.host %s', + '%s $./bin/config set mysql.host %s', + PlatformSymbols::getPlatformServerPath(), $host)) ->addCommand( hsprintf( - '$ ./bin/config set mysql.port %s', + '%s $./bin/config set mysql.port %s', + PlatformSymbols::getPlatformServerPath(), $port)); } @@ -134,7 +136,10 @@ final class PhabricatorDatabaseSetupCheck extends PhabricatorSetupCheck { ->setName(pht('Setup MySQL Schema')) ->setMessage($message) ->setIsFatal(true) - ->addCommand(hsprintf('$ ./bin/storage upgrade')); + ->addCommand( + hsprintf( + '%s $./bin/storage upgrade', + PlatformSymbols::getPlatformServerPath())); return true; } @@ -160,7 +165,9 @@ final class PhabricatorDatabaseSetupCheck extends PhabricatorSetupCheck { ->setIsFatal(true) ->setMessage($message) ->addCommand( - hsprintf('$ ./bin/storage upgrade')); + hsprintf( + '%s $./bin/storage upgrade', + PlatformSymbols::getPlatformServerPath())); return true; } diff --git a/src/applications/config/check/PhabricatorElasticsearchSetupCheck.php b/src/applications/config/check/PhabricatorElasticsearchSetupCheck.php index 8466c5a6c6..268f55f80b 100644 --- a/src/applications/config/check/PhabricatorElasticsearchSetupCheck.php +++ b/src/applications/config/check/PhabricatorElasticsearchSetupCheck.php @@ -60,7 +60,10 @@ final class PhabricatorElasticsearchSetupCheck extends PhabricatorSetupCheck { $this ->newIssue('elastic.missing-index') ->setName(pht('Elasticsearch Index Not Found')) - ->addCommand('./bin/search init') + ->addCommand( + hsprintf( + '%s $./bin/search init', + PlatformSymbols::getPlatformServerPath())) ->setSummary($summary) ->setMessage($message); @@ -76,7 +79,10 @@ final class PhabricatorElasticsearchSetupCheck extends PhabricatorSetupCheck { $this ->newIssue('elastic.broken-index') ->setName(pht('Elasticsearch Index Schema Mismatch')) - ->addCommand('./bin/search init') + ->addCommand( + hsprintf( + '%s $./bin/search init', + PlatformSymbols::getPlatformServerPath())) ->setSummary($summary) ->setMessage($message); } diff --git a/src/applications/config/check/PhabricatorExtraConfigSetupCheck.php b/src/applications/config/check/PhabricatorExtraConfigSetupCheck.php index ae14a0ab0a..070127ccbd 100644 --- a/src/applications/config/check/PhabricatorExtraConfigSetupCheck.php +++ b/src/applications/config/check/PhabricatorExtraConfigSetupCheck.php @@ -76,7 +76,10 @@ final class PhabricatorExtraConfigSetupCheck extends PhabricatorSetupCheck { $issue->setMessage($message); if ($found_local) { - $command = csprintf('$ ./bin/config delete %s', $key); + $command = hsprintf( + '%s $./bin/config delete %s', + PlatformSymbols::getPlatformServerPath(), + $key); $issue->addCommand($command); } @@ -166,9 +169,12 @@ final class PhabricatorExtraConfigSetupCheck extends PhabricatorSetupCheck { 'target' => '_blank', ), $doc_name)); - $command = csprintf( - '$ ./bin/config delete --database %R', - $key); + $command = hsprintf( + '%s $%s', + PlatformSymbols::getPlatformServerPath(), + csprintf( + './bin/config delete --database %R', + $key)); $this->newIssue('config.locked.'.$key) ->setShortName(pht('Deprecated Config Source')) diff --git a/src/applications/config/check/PhabricatorWebServerSetupCheck.php b/src/applications/config/check/PhabricatorWebServerSetupCheck.php index cc9660325c..d46f808f58 100644 --- a/src/applications/config/check/PhabricatorWebServerSetupCheck.php +++ b/src/applications/config/check/PhabricatorWebServerSetupCheck.php @@ -23,7 +23,7 @@ final class PhabricatorWebServerSetupCheck extends PhabricatorSetupCheck { } $base_uri = PhabricatorEnv::getEnvConfig('phabricator.base-uri'); - if (!strlen($base_uri)) { + if (!$base_uri) { // If `phabricator.base-uri` is not set then we can't really do // anything. return; diff --git a/src/applications/config/check/PhorgeCodeWarningSetupCheck.php b/src/applications/config/check/PhorgeCodeWarningSetupCheck.php new file mode 100644 index 0000000000..2aaf33ac25 --- /dev/null +++ b/src/applications/config/check/PhorgeCodeWarningSetupCheck.php @@ -0,0 +1,81 @@ +getWarnings(); + if (!$warnings) { + return; + } + + $link = phutil_tag( + 'a', + array('href' => 'https://we.phorge.it/w/docs/report-warnings/'), + pht('%s\'s home page', PlatformSymbols::getPlatformServerName())); + + $message = pht( + 'There is some deprecated code found in the %s code-base.'. + "\n\n". + "This isn't a problem yet, but it means that %s might stop working if ". + 'you upgrade PHP version.'. + "\n\n". + 'This page records a sample of the cases since last server restart. '. + "\n\n". + 'To solve this issue, either:'. + "\n\n". + '- Visit %s, file bug report with the information below, or'. + "\n". + '- Ignore this issue using the `Ignore` button below.'. + "\n\n", + PlatformSymbols::getPlatformServerName(), + PlatformSymbols::getPlatformServerName(), + $link); + $message = array($message); + + $message[] = pht('PHP version: %s', phpversion()); + $message[] = "\n\n"; + + $message[] = pht('Recorded items (sample):'); + $list = array(); + $warnings = array_reverse(isort($warnings, 'counter')); + foreach ($warnings as $key => $data) { + $summary = pht( + '%s, occurrences: %s', + $key, + $data['counter']); + + $trace = phutil_tag('tt', array(), + array($data['message'] , "\n", $data['trace'])); + + $list[] = phutil_tag( + 'li', + array(), + phutil_tag( + 'details', + array(), + array( + phutil_tag('summary', array(), $summary), + $trace, + ))); + } + $message[] = phutil_tag('ul', array(), $list); + + + $this->newIssue('deprecations') + ->setName(pht('Deprecated Code')) + ->setMessage($message) + ->setSummary(pht('There is some deprecated code found in the code-base.')) + ->addLink( + 'https://we.phorge.it/w/docs/report-warnings/', + 'More Details on the website'); + } + +} diff --git a/src/applications/config/option/PhabricatorConfigOption.php b/src/applications/config/option/PhabricatorConfigOption.php index 6b38bbb6d6..ee79005d5d 100644 --- a/src/applications/config/option/PhabricatorConfigOption.php +++ b/src/applications/config/option/PhabricatorConfigOption.php @@ -77,7 +77,7 @@ final class PhabricatorConfigOption 'This configuration is locked and can not be edited from the web '. 'interface. Use %s in %s to edit it.', phutil_tag('tt', array(), './bin/config'), - phutil_tag('tt', array(), 'phabricator/')); + phutil_tag('tt', array(), PlatformSymbols::getPlatformServerPath())); } public function addExample($value, $description) { diff --git a/src/applications/config/view/PhabricatorSetupIssueView.php b/src/applications/config/view/PhabricatorSetupIssueView.php index bfeae20684..9aff749bb2 100644 --- a/src/applications/config/view/PhabricatorSetupIssueView.php +++ b/src/applications/config/view/PhabricatorSetupIssueView.php @@ -83,11 +83,11 @@ final class PhabricatorSetupIssueView extends AphrontView { // TODO: We should do a better job of detecting how to install extensions // on the current system. $install_commands = hsprintf( - "\$ sudo apt-get install php-extname ". + "$sudo apt-get install php-extname ". "# Debian / Ubuntu\n". - "\$ sudo dnf install php-extname ". + "$sudo dnf install php-extname ". "# Red Hat / Derivatives\n". - "\$ sudo yum install php-extname ". + "$sudo yum install php-extname ". "# Older Red Hat versions"); $fallback_info = pht( @@ -286,7 +286,8 @@ final class PhabricatorSetupIssueView extends AphrontView { $update = array(); foreach ($configs as $key) { $update[] = hsprintf( - '$ ./bin/config set %s value', + '%s $./bin/config set %s value', + PlatformSymbols::getPlatformServerPath(), $key); } $update = phutil_tag('pre', array(), phutil_implode_html("\n", $update)); @@ -603,14 +604,14 @@ final class PhabricatorSetupIssueView extends AphrontView { } private function renderRestartLink() { - $doc_href = PhabricatorEnv::getDoclink('Restarting Phabricator'); + $doc_href = PhabricatorEnv::getDoclink('Restarting Phorge'); return phutil_tag( 'a', array( 'href' => $doc_href, 'target' => '_blank', ), - pht('Restarting Phabricator')); + pht('Restarting')); } } diff --git a/src/applications/conpherence/application/PhabricatorConpherenceApplication.php b/src/applications/conpherence/application/PhabricatorConpherenceApplication.php index a0c21bd33a..f3118be9bf 100644 --- a/src/applications/conpherence/application/PhabricatorConpherenceApplication.php +++ b/src/applications/conpherence/application/PhabricatorConpherenceApplication.php @@ -28,6 +28,10 @@ final class PhabricatorConpherenceApplication extends PhabricatorApplication { ); } + public function getMonograms() { + return array('Z'); + } + public function getRoutes() { return array( '/Z(?P[1-9]\d*)' diff --git a/src/applications/conpherence/controller/ConpherenceUpdateController.php b/src/applications/conpherence/controller/ConpherenceUpdateController.php index a792a5a4d4..6d838e72bc 100644 --- a/src/applications/conpherence/controller/ConpherenceUpdateController.php +++ b/src/applications/conpherence/controller/ConpherenceUpdateController.php @@ -328,7 +328,12 @@ final class ConpherenceUpdateController ->executeOne(); $non_update = false; - $participant = $conpherence->getParticipant($user->getPHID()); + + // The User is always available. The Participant may not. See: + // User: it's you, lurking the Chat (maybe it's a public chat). + // Participant: it's you, if you are a Chat Member. + // https://we.phorge.it/T15497 + $participant = $conpherence->getParticipantIfExists($user->getPHID()); if ($need_transactions && $conpherence->getTransactions()) { $data = ConpherenceTransactionRenderer::renderTransactions( @@ -336,7 +341,7 @@ final class ConpherenceUpdateController $conpherence); $key = PhabricatorConpherenceColumnMinimizeSetting::SETTINGKEY; $minimized = $user->getUserSetting($key); - if (!$minimized) { + if (!$minimized && $participant) { $participant->markUpToDate($conpherence); } } else if ($need_transactions) { diff --git a/src/applications/console/plugin/errorlog/DarkConsoleErrorLogPluginAPI.php b/src/applications/console/plugin/errorlog/DarkConsoleErrorLogPluginAPI.php index bc276da0da..fb092ec763 100644 --- a/src/applications/console/plugin/errorlog/DarkConsoleErrorLogPluginAPI.php +++ b/src/applications/console/plugin/errorlog/DarkConsoleErrorLogPluginAPI.php @@ -44,6 +44,7 @@ final class DarkConsoleErrorLogPluginAPI extends Phobject { 'trace' => $metadata['trace'], ); break; + case PhutilErrorHandler::DEPRECATED: case PhutilErrorHandler::ERROR: // $value is a simple string self::$errors[] = array( diff --git a/src/applications/countdown/application/PhabricatorCountdownApplication.php b/src/applications/countdown/application/PhabricatorCountdownApplication.php index e205ba64c3..5f06e6ef9f 100644 --- a/src/applications/countdown/application/PhabricatorCountdownApplication.php +++ b/src/applications/countdown/application/PhabricatorCountdownApplication.php @@ -36,6 +36,10 @@ final class PhabricatorCountdownApplication extends PhabricatorApplication { ); } + public function getMonograms() { + return array('C'); + } + public function getRoutes() { return array( '/C(?P[1-9]\d*)' => 'PhabricatorCountdownViewController', diff --git a/src/applications/daemon/controller/PhabricatorDaemonLogViewController.php b/src/applications/daemon/controller/PhabricatorDaemonLogViewController.php index f4c7ba60c9..253a3d5190 100644 --- a/src/applications/daemon/controller/PhabricatorDaemonLogViewController.php +++ b/src/applications/daemon/controller/PhabricatorDaemonLogViewController.php @@ -171,7 +171,8 @@ final class PhabricatorDaemonLogViewController phutil_tag( 'tt', array(), - "phabricator/ $ ./bin/phd log --id {$id}")); + PlatformSymbols::getPlatformServerPath(). + " $ ./bin/phd log --id {$id}")); return $view; diff --git a/src/applications/dashboard/application/PhabricatorDashboardApplication.php b/src/applications/dashboard/application/PhabricatorDashboardApplication.php index 3cdb932514..aeb2f43195 100644 --- a/src/applications/dashboard/application/PhabricatorDashboardApplication.php +++ b/src/applications/dashboard/application/PhabricatorDashboardApplication.php @@ -30,6 +30,10 @@ final class PhabricatorDashboardApplication extends PhabricatorApplication { return 0.160; } + public function getMonograms() { + return array('W'); + } + public function getRoutes() { $menu_rules = $this->getProfileMenuRouting( 'PhabricatorDashboardPortalViewController'); diff --git a/src/applications/dashboard/controller/dashboard/PhabricatorDashboardAdjustController.php b/src/applications/dashboard/controller/dashboard/PhabricatorDashboardAdjustController.php index fc04b94603..4f3937e3ae 100644 --- a/src/applications/dashboard/controller/dashboard/PhabricatorDashboardAdjustController.php +++ b/src/applications/dashboard/controller/dashboard/PhabricatorDashboardAdjustController.php @@ -32,7 +32,7 @@ final class PhabricatorDashboardAdjustController $panel_ref = null; $panel_key = $request->getStr('panelKey'); - if (strlen($panel_key)) { + if ($panel_key !== null && strlen($panel_key)) { $panel_ref = $ref_list->getPanelRef($panel_key); if (!$panel_ref) { return new Aphront404Response(); diff --git a/src/applications/dashboard/controller/panel/PhabricatorDashboardPanelTabsController.php b/src/applications/dashboard/controller/panel/PhabricatorDashboardPanelTabsController.php index 193e4580d6..7ea0345ceb 100644 --- a/src/applications/dashboard/controller/panel/PhabricatorDashboardPanelTabsController.php +++ b/src/applications/dashboard/controller/panel/PhabricatorDashboardPanelTabsController.php @@ -41,12 +41,12 @@ final class PhabricatorDashboardPanelTabsController $op = $request->getURIData('op'); $after = $request->getStr('after'); - if (!strlen($after)) { + if ($after === '') { $after = null; } $target = $request->getStr('target'); - if (!strlen($target)) { + if ($target === '') { $target = null; } diff --git a/src/applications/dashboard/engine/PhabricatorDashboardPanelRenderingEngine.php b/src/applications/dashboard/engine/PhabricatorDashboardPanelRenderingEngine.php index cce6ee768f..3b9c3ad192 100644 --- a/src/applications/dashboard/engine/PhabricatorDashboardPanelRenderingEngine.php +++ b/src/applications/dashboard/engine/PhabricatorDashboardPanelRenderingEngine.php @@ -155,6 +155,7 @@ final class PhabricatorDashboardPanelRenderingEngine extends Phobject { return $this->renderNormalPanel(); } catch (Exception $ex) { + phlog($ex); return $this->renderErrorPanel( $panel->getName(), pht( diff --git a/src/applications/dashboard/paneltype/PhabricatorDashboardTabsPanelType.php b/src/applications/dashboard/paneltype/PhabricatorDashboardTabsPanelType.php index 9bc84d820e..6b4f2fe5d6 100644 --- a/src/applications/dashboard/paneltype/PhabricatorDashboardTabsPanelType.php +++ b/src/applications/dashboard/paneltype/PhabricatorDashboardTabsPanelType.php @@ -85,10 +85,12 @@ final class PhabricatorDashboardTabsPanelType $rename_uri = id(new PhutilURI($rename_uri)) ->replaceQueryParam('contextPHID', $context_phid); - $selected = 0; - $key_list = array_keys($config); + // In the future we may persist which panel was selected. + // At the moment we have always selected the first one. + $selected = (string)head($key_list); + $next_keys = array(); $prev_keys = array(); for ($ii = 0; $ii < count($key_list); $ii++) { @@ -100,7 +102,7 @@ final class PhabricatorDashboardTabsPanelType $panel_id = idx($tab_spec, 'panelID'); $subpanel = idx($panels, $panel_id); - $name = idx($tab_spec, 'name'); + $name = coalesce(idx($tab_spec, 'name'), ''); if (!strlen($name)) { if ($subpanel) { $name = $subpanel->getName(); @@ -111,7 +113,8 @@ final class PhabricatorDashboardTabsPanelType $name = pht('Unnamed Tab'); } - $is_selected = (string)$idx === (string)$selected; + // The $idx can be something like "0", "1" or "asdasd98". + $is_selected = (string)$idx === $selected; $tab_view = id(new PHUIListItemView()) ->setHref('#') @@ -282,7 +285,8 @@ final class PhabricatorDashboardTabsPanelType $panel_content = pht('(Invalid Panel)'); } - $is_selected = (string)$idx === (string)$selected; + // Note that $idx can be something like "0", "1" or "asdasd98". + $is_selected = (string)$idx === $selected; $content_id = celerity_generate_unique_node_id(); diff --git a/src/applications/differential/application/PhabricatorDifferentialApplication.php b/src/applications/differential/application/PhabricatorDifferentialApplication.php index 5980f738b0..16b3193dac 100644 --- a/src/applications/differential/application/PhabricatorDifferentialApplication.php +++ b/src/applications/differential/application/PhabricatorDifferentialApplication.php @@ -42,6 +42,10 @@ final class PhabricatorDifferentialApplication 'engineers to review, discuss and approve changes to software.'); } + public function getMonograms() { + return array('D'); + } + public function getRoutes() { return array( '/D(?P[1-9]\d*)' => array( diff --git a/src/applications/differential/storage/DifferentialChangeset.php b/src/applications/differential/storage/DifferentialChangeset.php index 770a49e411..d92b27e574 100644 --- a/src/applications/differential/storage/DifferentialChangeset.php +++ b/src/applications/differential/storage/DifferentialChangeset.php @@ -325,14 +325,16 @@ final class DifferentialChangeset public function getOldStatePathVector() { $path = $this->getOldFile(); - if (!strlen($path)) { + if (!phutil_nonempty_string($path)) { $path = $this->getFilename(); } - $path = trim($path, '/'); - $path = explode('/', $path); + if (!phutil_nonempty_string($path)) { + return null; + } - return $path; + $path = trim($path, '/'); + return explode('/', $path); } public function getNewStatePathVector() { diff --git a/src/applications/differential/storage/__tests__/DifferentialChangesetTestCase.php b/src/applications/differential/storage/__tests__/DifferentialChangesetTestCase.php new file mode 100644 index 0000000000..435b77ee87 --- /dev/null +++ b/src/applications/differential/storage/__tests__/DifferentialChangesetTestCase.php @@ -0,0 +1,16 @@ +getOldStatePathVector(); + $this->assertTrue(true, 'getOldStatePathVector did not throw an error'); + } catch (Throwable $ex) { + $this->assertTrue(false, + 'getOldStatePathVector threw an exception:'.$ex->getMessage()); + } + } + +} diff --git a/src/applications/diffusion/application/PhabricatorDiffusionApplication.php b/src/applications/diffusion/application/PhabricatorDiffusionApplication.php index e0e74486da..a2b9f81aee 100644 --- a/src/applications/diffusion/application/PhabricatorDiffusionApplication.php +++ b/src/applications/diffusion/application/PhabricatorDiffusionApplication.php @@ -44,6 +44,11 @@ final class PhabricatorDiffusionApplication extends PhabricatorApplication { ); } + public function getMonograms() { + // This is a special case, as r and R mean different things. + return array('r', 'R'); + } + public function getRoutes() { $repository_routes = array( '/' => array( @@ -183,6 +188,9 @@ final class PhabricatorDiffusionApplication extends PhabricatorApplication { DiffusionCreateRepositoriesCapability::CAPABILITY => array( 'default' => PhabricatorPolicies::POLICY_ADMIN, ), + PhabricatorRepositoryIdentityEditViewCapability::CAPABILITY => array( + 'default' => PhabricatorPolicies::POLICY_USER, + ), ); } diff --git a/src/applications/diffusion/conduit/DiffusionDiffQueryConduitAPIMethod.php b/src/applications/diffusion/conduit/DiffusionDiffQueryConduitAPIMethod.php index 694d4bc012..d97f09cc4e 100644 --- a/src/applications/diffusion/conduit/DiffusionDiffQueryConduitAPIMethod.php +++ b/src/applications/diffusion/conduit/DiffusionDiffQueryConduitAPIMethod.php @@ -23,6 +23,7 @@ final class DiffusionDiffQueryConduitAPIMethod return array( 'path' => 'required string', 'commit' => 'optional string', + 'encoding' => 'optional string', ); } @@ -152,7 +153,7 @@ final class DiffusionDiffQueryConduitAPIMethod $arcanist_changes = DiffusionPathChange::convertToArcanistChanges( $path_changes); - $parser = $this->getDefaultParser(); + $parser = $this->getDefaultParser($request); $parser->setChanges($arcanist_changes); $parser->forcePath($path->getPath()); $changes = $parser->parseDiff($raw_diff); @@ -212,18 +213,20 @@ final class DiffusionDiffQueryConduitAPIMethod return $this->getEmptyResult(); } - $parser = $this->getDefaultParser(); + $parser = $this->getDefaultParser($request); $changes = $parser->parseDiff($raw_diff); return $changes; } - private function getDefaultParser() { + private function getDefaultParser(ConduitAPIRequest $request) { $drequest = $this->getDiffusionRequest(); $repository = $drequest->getRepository(); $parser = new ArcanistDiffParser(); - $try_encoding = $repository->getDetail('encoding'); + $try_encoding = coalesce( + $request->getValue('encoding'), + $repository->getDetail('encoding')); if ($try_encoding) { $parser->setTryEncoding($try_encoding); } diff --git a/src/applications/diffusion/controller/DiffusionBlameController.php b/src/applications/diffusion/controller/DiffusionBlameController.php index 5de464b335..34078a7b7a 100644 --- a/src/applications/diffusion/controller/DiffusionBlameController.php +++ b/src/applications/diffusion/controller/DiffusionBlameController.php @@ -198,6 +198,10 @@ final class DiffusionBlameController extends DiffusionController { $map[$identifier] = $data; } + if (empty($epochs)) { + $epochs[] = 0; + } + $epoch_min = min($epochs); $epoch_max = max($epochs); diff --git a/src/applications/diffusion/controller/DiffusionCloneController.php b/src/applications/diffusion/controller/DiffusionCloneController.php index 8bc4faa1a2..bf118bcf6d 100644 --- a/src/applications/diffusion/controller/DiffusionCloneController.php +++ b/src/applications/diffusion/controller/DiffusionCloneController.php @@ -49,8 +49,6 @@ final class DiffusionCloneController extends DiffusionController { ->appendChild(pht('Repository has no URIs set.')); } - $info = null; - // Try to load alternatives. This may fail for repositories which have not // cloned yet. If it does, just ignore it and continue. try { diff --git a/src/applications/diffusion/controller/DiffusionDiffController.php b/src/applications/diffusion/controller/DiffusionDiffController.php index 69a473dc91..a844dc23d2 100644 --- a/src/applications/diffusion/controller/DiffusionDiffController.php +++ b/src/applications/diffusion/controller/DiffusionDiffController.php @@ -48,6 +48,7 @@ final class DiffusionDiffController extends DiffusionController { array( 'commit' => $drequest->getCommit(), 'path' => $drequest->getPath(), + 'encoding' => $request->getStr('encoding'), )); $drequest->updateSymbolicCommit($data['effectiveCommit']); $raw_changes = ArcanistDiffChange::newFromConduit($data['changes']); diff --git a/src/applications/diffusion/controller/DiffusionRepositoryController.php b/src/applications/diffusion/controller/DiffusionRepositoryController.php index ad3518b81e..3ae237c22d 100644 --- a/src/applications/diffusion/controller/DiffusionRepositoryController.php +++ b/src/applications/diffusion/controller/DiffusionRepositoryController.php @@ -508,7 +508,7 @@ final class DiffusionRepositoryController extends DiffusionController { $repository_name = $repository->getName(); $branch_name = $drequest->getBranch(); - if (strlen($branch_name)) { + if (phutil_nonempty_string($branch_name)) { $repository_name .= ' ('.$branch_name.')'; } diff --git a/src/applications/diffusion/controller/DiffusionRepositoryEditDeleteController.php b/src/applications/diffusion/controller/DiffusionRepositoryEditDeleteController.php index 93fe70c0fe..72e18d17e8 100644 --- a/src/applications/diffusion/controller/DiffusionRepositoryEditDeleteController.php +++ b/src/applications/diffusion/controller/DiffusionRepositoryEditDeleteController.php @@ -28,7 +28,8 @@ final class DiffusionRepositoryEditDeleteController 'the command line:')) ->appendCommand( csprintf( - 'phabricator/ $ ./bin/remove destroy %R', + '%s $ ./bin/remove destroy %R', + PlatformSymbols::getPlatformServerPath(), $repository->getMonogram())) ->appendParagraph( pht( diff --git a/src/applications/diffusion/controller/DiffusionServeController.php b/src/applications/diffusion/controller/DiffusionServeController.php index 93656ea607..d092f9740d 100644 --- a/src/applications/diffusion/controller/DiffusionServeController.php +++ b/src/applications/diffusion/controller/DiffusionServeController.php @@ -878,10 +878,29 @@ final class DiffusionServeController extends DiffusionController { } $args_raw[] = $_SERVER[$header]; } - $args_raw = implode('', $args_raw); - return id(new PhutilQueryStringParser()) - ->parseQueryString($args_raw); + if ($args_raw) { + $args_raw = implode('', $args_raw); + return id(new PhutilQueryStringParser()) + ->parseQueryString($args_raw); + } + + // Sometimes arguments come in via the query string. Note that this will + // not handle multi-value entries e.g. "a[]=1,a[]=2" however it's unclear + // whether or how the mercurial protocol should handle this. + $query = idx($_SERVER, 'QUERY_STRING', ''); + $query_pairs = id(new PhutilQueryStringParser()) + ->parseQueryString($query); + foreach ($query_pairs as $key => $value) { + // Filter out private/internal keys as well as the command itself. + if (strncmp($key, '__', 2) && $key != 'cmd') { + $args_raw[$key] = $value; + } + } + + // TODO: Arguments can also come in via request body for POST requests. The + // body would be all arguments, url-encoded. + return $args_raw; } private function formatMercurialArguments($command, array $arguments) { diff --git a/src/applications/diffusion/data/DiffusionCommitRef.php b/src/applications/diffusion/data/DiffusionCommitRef.php index 06dd4d5ffb..76c3371192 100644 --- a/src/applications/diffusion/data/DiffusionCommitRef.php +++ b/src/applications/diffusion/data/DiffusionCommitRef.php @@ -131,6 +131,8 @@ final class DiffusionCommitRef extends Phobject { } private function formatUser($name, $email) { + $name = coalesce($name, ''); + $email = coalesce($email, ''); if (strlen($name) && strlen($email)) { return "{$name} <{$email}>"; } else if (strlen($email)) { diff --git a/src/applications/diffusion/query/lowlevel/DiffusionLowLevelGitRefQuery.php b/src/applications/diffusion/query/lowlevel/DiffusionLowLevelGitRefQuery.php index d11b658131..21c86e7435 100644 --- a/src/applications/diffusion/query/lowlevel/DiffusionLowLevelGitRefQuery.php +++ b/src/applications/diffusion/query/lowlevel/DiffusionLowLevelGitRefQuery.php @@ -27,7 +27,7 @@ final class DiffusionLowLevelGitRefQuery extends DiffusionLowLevelQuery { $with_branches = isset($ref_types[$type_branch]); $with_tags = isset($ref_types[$type_tag]); - $with_refs = isset($refs_types[$type_ref]); + $with_refs = isset($ref_types[$type_ref]); $repository = $this->getRepository(); diff --git a/src/applications/diffusion/query/lowlevel/DiffusionLowLevelResolveRefsQuery.php b/src/applications/diffusion/query/lowlevel/DiffusionLowLevelResolveRefsQuery.php index 0bbba1dc18..899e69d49b 100644 --- a/src/applications/diffusion/query/lowlevel/DiffusionLowLevelResolveRefsQuery.php +++ b/src/applications/diffusion/query/lowlevel/DiffusionLowLevelResolveRefsQuery.php @@ -140,8 +140,9 @@ final class DiffusionLowLevelResolveRefsQuery if (count($lines) !== count($unresolved)) { throw new Exception( pht( - 'Unexpected line count from `%s`!', - 'git cat-file')); + 'Unexpected line count from `%s` in %s!', + 'git cat-file', + $repository->getMonogram())); } $hits = array(); @@ -153,8 +154,9 @@ final class DiffusionLowLevelResolveRefsQuery if (count($parts) < 2) { throw new Exception( pht( - 'Failed to parse `%s` output: %s', + 'Failed to parse `%s` output in %s: %s', 'git cat-file', + $repository->getMonogram(), $line)); } list($identifier, $type) = $parts; @@ -177,8 +179,9 @@ final class DiffusionLowLevelResolveRefsQuery default: throw new Exception( pht( - 'Unexpected object type from `%s`: %s', + 'Unexpected object type from `%s` in %s: %s', 'git cat-file', + $repository->getMonogram(), $line)); } diff --git a/src/applications/diffusion/request/DiffusionMercurialRequest.php b/src/applications/diffusion/request/DiffusionMercurialRequest.php index b626d62750..676dc097f7 100644 --- a/src/applications/diffusion/request/DiffusionMercurialRequest.php +++ b/src/applications/diffusion/request/DiffusionMercurialRequest.php @@ -3,6 +3,9 @@ final class DiffusionMercurialRequest extends DiffusionRequest { protected function isStableCommit($symbol) { + if ($symbol === null) { + return false; + } return preg_match('/^[a-f0-9]{40}\z/', $symbol); } @@ -10,11 +13,9 @@ final class DiffusionMercurialRequest extends DiffusionRequest { if ($this->branch) { return $this->branch; } - if ($this->repository) { return $this->repository->getDefaultBranch(); } - throw new Exception(pht('Unable to determine branch!')); } diff --git a/src/applications/diffusion/request/DiffusionSvnRequest.php b/src/applications/diffusion/request/DiffusionSvnRequest.php index 5f50366331..33fc3446f9 100644 --- a/src/applications/diffusion/request/DiffusionSvnRequest.php +++ b/src/applications/diffusion/request/DiffusionSvnRequest.php @@ -3,6 +3,9 @@ final class DiffusionSvnRequest extends DiffusionRequest { protected function isStableCommit($symbol) { + if ($symbol === null) { + return false; + } return preg_match('/^[1-9]\d*\z/', $symbol); } diff --git a/src/applications/diffusion/typeahead/DiffusionRepositoryDatasource.php b/src/applications/diffusion/typeahead/DiffusionRepositoryDatasource.php index cc9da44723..5953dac8b3 100644 --- a/src/applications/diffusion/typeahead/DiffusionRepositoryDatasource.php +++ b/src/applications/diffusion/typeahead/DiffusionRepositoryDatasource.php @@ -16,13 +16,16 @@ final class DiffusionRepositoryDatasource } public function loadResults() { - $viewer = $this->getViewer(); - $raw_query = $this->getRawQuery(); - $query = id(new PhabricatorRepositoryQuery()) - ->setOrder('name') - ->withDatasourceQuery($raw_query); - $repos = $this->executeQuery($query); + ->setViewer($this->getViewer()); + + $this->applyFerretConstraints( + $query, + id(new PhabricatorRepository())->newFerretEngine(), + 'title', + $this->getRawQuery()); + + $repos = $query->execute(); $type_icon = id(new PhabricatorRepositoryRepositoryPHIDType()) ->getTypeIcon(); diff --git a/src/applications/diviner/controller/DivinerFindController.php b/src/applications/diviner/controller/DivinerFindController.php index 1bedd65b06..2e3b121706 100644 --- a/src/applications/diviner/controller/DivinerFindController.php +++ b/src/applications/diviner/controller/DivinerFindController.php @@ -32,7 +32,7 @@ final class DivinerFindController extends DivinerController { } $context = $request->getStr('context'); - if (strlen($context)) { + if (phutil_nonempty_string($context)) { $query->withContexts(array($context)); } diff --git a/src/applications/diviner/storage/DivinerLiveSymbol.php b/src/applications/diviner/storage/DivinerLiveSymbol.php index d62e6a1e18..6477e00879 100644 --- a/src/applications/diviner/storage/DivinerLiveSymbol.php +++ b/src/applications/diviner/storage/DivinerLiveSymbol.php @@ -172,7 +172,7 @@ final class DivinerLiveSymbol extends DivinerDAO public function getTitle() { $title = parent::getTitle(); - if (!strlen($title)) { + if (!phutil_nonempty_string($title)) { $title = $this->getName(); } diff --git a/src/applications/diviner/workflow/DivinerGenerateWorkflow.php b/src/applications/diviner/workflow/DivinerGenerateWorkflow.php index 866e8b9ee6..0cde772fc3 100644 --- a/src/applications/diviner/workflow/DivinerGenerateWorkflow.php +++ b/src/applications/diviner/workflow/DivinerGenerateWorkflow.php @@ -348,7 +348,7 @@ final class DivinerGenerateWorkflow extends DivinerWorkflow { $atomizers[$atomizer][] = $file; } - $root = dirname(phutil_get_library_root('phabricator')); + $root = dirname(phutil_get_library_root('phorge')); $config_root = $this->getConfig('root'); $bar = id(new PhutilConsoleProgressBar()) @@ -363,7 +363,6 @@ final class DivinerGenerateWorkflow extends DivinerWorkflow { $this->getBookConfigPath(), $class, $chunk); - $future->setCWD($config_root); $futures[] = $future; diff --git a/src/applications/files/application/PhabricatorFilesApplication.php b/src/applications/files/application/PhabricatorFilesApplication.php index e246d4c90c..4014a6ce62 100644 --- a/src/applications/files/application/PhabricatorFilesApplication.php +++ b/src/applications/files/application/PhabricatorFilesApplication.php @@ -67,6 +67,10 @@ final class PhabricatorFilesApplication extends PhabricatorApplication { ); } + public function getMonograms() { + return array('F'); + } + public function getRoutes() { return array( '/F(?P[1-9]\d*)(?:\$(?P\d+(?:-\d+)?))?' diff --git a/src/applications/files/config/PhabricatorFilesConfigOptions.php b/src/applications/files/config/PhabricatorFilesConfigOptions.php index 7ed96a412b..67d123e2cb 100644 --- a/src/applications/files/config/PhabricatorFilesConfigOptions.php +++ b/src/applications/files/config/PhabricatorFilesConfigOptions.php @@ -134,9 +134,11 @@ final class PhabricatorFilesConfigOptions ->setDescription( pht( "Configure which uploaded file types may be viewed directly ". - "in the browser. Other file types will be downloaded instead ". - "of displayed. This is mainly a usability consideration, since ". - "browsers tend to freak out when viewing very large binary files.". + "in the browser. Other types will be downloaded instead of ". + "displayed. This is a usability and security consideration, ". + "since browsers tend to freak out when viewing very large ". + "binary files, and some types may be vulnerable to XSS attacks ". + "when viewed in a browser.". "\n\n". "The keys in this map are viewable MIME types; the values are ". "the MIME types they are delivered as when they are viewed in ". diff --git a/src/applications/files/document/PhabricatorPDFDocumentEngine.php b/src/applications/files/document/PhabricatorPDFDocumentEngine.php index 1e85bd4ae5..bc6433290a 100644 --- a/src/applications/files/document/PhabricatorPDFDocumentEngine.php +++ b/src/applications/files/document/PhabricatorPDFDocumentEngine.php @@ -14,14 +14,16 @@ final class PhabricatorPDFDocumentEngine } protected function canRenderDocumentType(PhabricatorDocumentRef $ref) { - // Since we just render a link to the document anyway, we don't need to - // check anything fancy in config to see if the MIME type is actually - // viewable. + $viewable_types = PhabricatorEnv::getEnvConfig('files.viewable-mime-types'); + $viewable_types = array_keys($viewable_types); - return $ref->hasAnyMimeType( - array( - 'application/pdf', - )); + $pdf_types = array( + 'application/pdf', + ); + + return + $ref->hasAnyMimeType($viewable_types) && + $ref->hasAnyMimeType($pdf_types); } protected function newDocumentContent(PhabricatorDocumentRef $ref) { diff --git a/src/applications/files/transform/PhabricatorFileImageTransform.php b/src/applications/files/transform/PhabricatorFileImageTransform.php index 468eae0e03..98ffcdd706 100644 --- a/src/applications/files/transform/PhabricatorFileImageTransform.php +++ b/src/applications/files/transform/PhabricatorFileImageTransform.php @@ -137,8 +137,12 @@ abstract class PhabricatorFileImageTransform extends PhabricatorFileTransform { protected function newFileFromData($data) { if ($this->file) { $name = $this->file->getName(); + $inherit_properties = array( + 'viewPolicy' => $this->file->getViewPolicy(), + ); } else { $name = 'default.png'; + $inherit_properties = array(); } $defaults = array( @@ -146,7 +150,7 @@ abstract class PhabricatorFileImageTransform extends PhabricatorFileTransform { 'name' => $this->getTransformKey().'-'.$name, ); - $properties = $this->getFileProperties() + $defaults; + $properties = $this->getFileProperties() + $inherit_properties + $defaults; return PhabricatorFile::newFromFileData($data, $properties); } diff --git a/src/applications/files/transform/PhabricatorFileThumbnailTransform.php b/src/applications/files/transform/PhabricatorFileThumbnailTransform.php index 2c61743078..6cf3914556 100644 --- a/src/applications/files/transform/PhabricatorFileThumbnailTransform.php +++ b/src/applications/files/transform/PhabricatorFileThumbnailTransform.php @@ -58,7 +58,7 @@ final class PhabricatorFileThumbnailTransform public function generateTransforms() { return array( id(new PhabricatorFileThumbnailTransform()) - ->setName(pht("Profile (400px \xC3\x97 400px)")) + ->setName(pht("Profile (400px \xC3\x97 400px) (Image will be Public)")) ->setKey(self::TRANSFORM_PROFILE) ->setDimensions(400, 400) ->setScaleUp(true), diff --git a/src/applications/files/xaction/PhabricatorFileAltTextTransaction.php b/src/applications/files/xaction/PhabricatorFileAltTextTransaction.php index c3151910e4..063a599170 100644 --- a/src/applications/files/xaction/PhabricatorFileAltTextTransaction.php +++ b/src/applications/files/xaction/PhabricatorFileAltTextTransaction.php @@ -50,13 +50,13 @@ final class PhabricatorFileAltTextTransaction $old_value = $this->getOldValue(); $new_value = $this->getNewValue(); - if (!strlen($old_value)) { + if (!phutil_nonempty_string($old_value)) { return pht( '%s set the alternate text for %s to %s.', $this->renderAuthor(), $this->renderObject(), $this->renderNewValue()); - } else if (!strlen($new_value)) { + } else if (!phutil_nonempty_string($new_value)) { return pht( '%s removed the alternate text for %s (was %s).', $this->renderAuthor(), diff --git a/src/applications/fund/application/PhabricatorFundApplication.php b/src/applications/fund/application/PhabricatorFundApplication.php index 58ce4f8922..5e2d33c1a4 100644 --- a/src/applications/fund/application/PhabricatorFundApplication.php +++ b/src/applications/fund/application/PhabricatorFundApplication.php @@ -36,6 +36,10 @@ final class PhabricatorFundApplication extends PhabricatorApplication { ); } + public function getMonograms() { + return array('I'); + } + public function getRoutes() { return array( '/I(?P[1-9]\d*)' => 'FundInitiativeViewController', diff --git a/src/applications/harbormaster/application/PhabricatorHarbormasterApplication.php b/src/applications/harbormaster/application/PhabricatorHarbormasterApplication.php index 6c499bf63a..7de2a658c2 100644 --- a/src/applications/harbormaster/application/PhabricatorHarbormasterApplication.php +++ b/src/applications/harbormaster/application/PhabricatorHarbormasterApplication.php @@ -51,6 +51,10 @@ final class PhabricatorHarbormasterApplication extends PhabricatorApplication { ); } + public function getMonograms() { + return array('B'); + } + public function getRoutes() { return array( '/B(?P[1-9]\d*)' => 'HarbormasterBuildableViewController', diff --git a/src/applications/harbormaster/controller/HarbormasterStepEditController.php b/src/applications/harbormaster/controller/HarbormasterStepEditController.php index 8cd91bb5a4..a420d02627 100644 --- a/src/applications/harbormaster/controller/HarbormasterStepEditController.php +++ b/src/applications/harbormaster/controller/HarbormasterStepEditController.php @@ -139,7 +139,7 @@ final class HarbormasterStepEditController ->setUser($viewer); $instructions = $implementation->getEditInstructions(); - if (strlen($instructions)) { + if (phutil_nonempty_string($instructions)) { $form->appendRemarkupInstructions($instructions); } diff --git a/src/applications/harbormaster/editor/HarbormasterBuildPlanEditEngine.php b/src/applications/harbormaster/editor/HarbormasterBuildPlanEditEngine.php index c0fa80d71b..b7d73f238b 100644 --- a/src/applications/harbormaster/editor/HarbormasterBuildPlanEditEngine.php +++ b/src/applications/harbormaster/editor/HarbormasterBuildPlanEditEngine.php @@ -103,7 +103,7 @@ final class HarbormasterBuildPlanEditEngine $key); $behavior_option = $object->getPlanProperty($storage_key); - if (!strlen($behavior_option)) { + if (!phutil_nonempty_string($behavior_option)) { $behavior_option = $behavior->getPlanOption($object)->getKey(); } diff --git a/src/applications/herald/application/PhabricatorHeraldApplication.php b/src/applications/herald/application/PhabricatorHeraldApplication.php index 0de1c02737..7808820818 100644 --- a/src/applications/herald/application/PhabricatorHeraldApplication.php +++ b/src/applications/herald/application/PhabricatorHeraldApplication.php @@ -49,6 +49,10 @@ final class PhabricatorHeraldApplication extends PhabricatorApplication { ); } + public function getMonograms() { + return array('H'); + } + public function getRoutes() { return array( '/H(?P[1-9]\d*)' => 'HeraldRuleViewController', diff --git a/src/applications/legalpad/application/PhabricatorLegalpadApplication.php b/src/applications/legalpad/application/PhabricatorLegalpadApplication.php index a3eaff5792..47a8f4ebef 100644 --- a/src/applications/legalpad/application/PhabricatorLegalpadApplication.php +++ b/src/applications/legalpad/application/PhabricatorLegalpadApplication.php @@ -48,6 +48,10 @@ final class PhabricatorLegalpadApplication extends PhabricatorApplication { 'open source projects keep track of Contributor License Agreements.'); } + public function getMonograms() { + return array('L'); + } + public function getRoutes() { return array( '/L(?P\d+)' => 'LegalpadDocumentSignController', diff --git a/src/applications/macro/engine/PhabricatorMemeEngine.php b/src/applications/macro/engine/PhabricatorMemeEngine.php index e1befc20a2..71a45033da 100644 --- a/src/applications/macro/engine/PhabricatorMemeEngine.php +++ b/src/applications/macro/engine/PhabricatorMemeEngine.php @@ -273,7 +273,7 @@ final class PhabricatorMemeEngine extends Phobject { $size = $metrics['size']; $above = $this->getAboveText(); - if (strlen($above)) { + if ($above !== null && phutil_nonempty_string(trim($above))) { $x = (int)floor(($dx - $metrics['text']['above']['width']) / 2); $y = $metrics['text']['above']['height'] + 12; @@ -281,7 +281,7 @@ final class PhabricatorMemeEngine extends Phobject { } $below = $this->getBelowText(); - if (strlen($below)) { + if ($below !== null && phutil_nonempty_string(trim($below))) { $x = (int)floor(($dx - $metrics['text']['below']['width']) / 2); $y = $dy - 12 - $metrics['text']['below']['descend']; diff --git a/src/applications/maniphest/application/PhabricatorManiphestApplication.php b/src/applications/maniphest/application/PhabricatorManiphestApplication.php index 8ed20416bb..9296060d81 100644 --- a/src/applications/maniphest/application/PhabricatorManiphestApplication.php +++ b/src/applications/maniphest/application/PhabricatorManiphestApplication.php @@ -42,6 +42,10 @@ final class PhabricatorManiphestApplication extends PhabricatorApplication { ); } + public function getMonograms() { + return array('T'); + } + public function getRoutes() { return array( '/T(?P[1-9]\d*)' => 'ManiphestTaskDetailController', diff --git a/src/applications/maniphest/query/ManiphestTaskQuery.php b/src/applications/maniphest/query/ManiphestTaskQuery.php index 9e58728cff..8bbf976564 100644 --- a/src/applications/maniphest/query/ManiphestTaskQuery.php +++ b/src/applications/maniphest/query/ManiphestTaskQuery.php @@ -1036,7 +1036,7 @@ final class ManiphestTaskQuery extends PhabricatorCursorPagedPolicyAwareQuery { $parts[] = null; } - if (!strlen($parts[1])) { + if (!phutil_nonempty_string($parts[1])) { $parts[1] = null; } diff --git a/src/applications/meta/controller/PhabricatorApplicationDetailViewController.php b/src/applications/meta/controller/PhabricatorApplicationDetailViewController.php index 8cceeb7396..1bf6734db3 100644 --- a/src/applications/meta/controller/PhabricatorApplicationDetailViewController.php +++ b/src/applications/meta/controller/PhabricatorApplicationDetailViewController.php @@ -38,6 +38,30 @@ final class PhabricatorApplicationDetailViewController $header->setStatus('fa-ban', 'dark', pht('Uninstalled')); } + if (!$selected->isFirstParty()) { + $header->addTag(id(new PHUITagView()) + ->setName('Extension') + ->setIcon('fa-plug') + ->setColor(PHUITagView::COLOR_INDIGO) + ->setType(PHUITagView::TYPE_SHADE)); + } + + if ($selected->isPrototype()) { + $header->addTag(id(new PHUITagView()) + ->setName('Prototype') + ->setIcon('fa-exclamation-circle') + ->setColor(PHUITagView::COLOR_ORANGE) + ->setType(PHUITagView::TYPE_SHADE)); + } + + if ($selected->isDeprecated()) { + $header->addTag(id(new PHUITagView()) + ->setName('Deprecated') + ->setIcon('fa-exclamation-triangle') + ->setColor(PHUITagView::COLOR_RED) + ->setType(PHUITagView::TYPE_SHADE)); + } + $timeline = $this->buildTransactionTimeline( $selected, new PhabricatorApplicationApplicationTransactionQuery()); @@ -95,6 +119,27 @@ final class PhabricatorApplicationDetailViewController phutil_tag('em', array(), $application->getFlavorText())); } + $phids = PhabricatorPHIDType::getAllTypesForApplication( + get_class($application)); + + $user_friendly_phids = array(); + foreach ($phids as $phid => $type) { + $user_friendly_phids[] = "PHID-{$phid} ({$type->getTypeName()})"; + } + + if ($user_friendly_phids) { + $properties->addProperty( + 'PHIDs', + phutil_implode_html(phutil_tag('br'), $user_friendly_phids)); + } + + $monograms = $application->getMonograms(); + if ($monograms) { + $properties->addProperty( + 'Monograms', + phutil_implode_html(', ', $monograms)); + } + if ($application->isPrototype()) { $proto_href = PhabricatorEnv::getDoclink( 'User Guide: Prototype Applications'); diff --git a/src/applications/meta/query/PhabricatorAppSearchEngine.php b/src/applications/meta/query/PhabricatorAppSearchEngine.php index e68570fe1c..08283afc2e 100644 --- a/src/applications/meta/query/PhabricatorAppSearchEngine.php +++ b/src/applications/meta/query/PhabricatorAppSearchEngine.php @@ -231,13 +231,13 @@ final class PhabricatorAppSearchEngine ->setSideColumn($configure); if (!$application->isFirstParty()) { - $tag = id(new PHUITagView()) + $extension_tag = id(new PHUITagView()) ->setName(pht('Extension')) - ->setIcon('fa-puzzle-piece') - ->setColor(PHUITagView::COLOR_BLUE) + ->setIcon('fa-plug') + ->setColor(PHUITagView::COLOR_INDIGO) ->setType(PHUITagView::TYPE_SHADE) ->setSlimShady(true); - $item->addAttribute($tag); + $item->addAttribute($extension_tag); } if ($application->isPrototype()) { @@ -250,6 +250,16 @@ final class PhabricatorAppSearchEngine $item->addAttribute($prototype_tag); } + if ($application->isDeprecated()) { + $deprecated_tag = id(new PHUITagView()) + ->setName(pht('Deprecated')) + ->setIcon('fa-exclamation-triangle') + ->setColor(PHUITagView::COLOR_RED) + ->setType(PHUITagView::TYPE_SHADE) + ->setSlimShady(true); + $item->addAttribute($deprecated_tag); + } + $item->addAttribute($description); if ($application->getBaseURI() && $application->isInstalled()) { diff --git a/src/applications/metamta/PhabricatorMetaMTAWorker.php b/src/applications/metamta/PhabricatorMetaMTAWorker.php index dcc6a8dc5e..7d7c51f8b2 100644 --- a/src/applications/metamta/PhabricatorMetaMTAWorker.php +++ b/src/applications/metamta/PhabricatorMetaMTAWorker.php @@ -45,9 +45,10 @@ final class PhabricatorMetaMTAWorker public function renderForDisplay(PhabricatorUser $viewer) { return phutil_tag( 'pre', - array( - ), - 'phabricator/ $ ./bin/mail show-outbound --id '.$this->getTaskData()); + array(), + PlatformSymbols::getPlatformServerPath(). + ' $ ./bin/mail show-outbound --id '. + $this->getTaskData()); } } diff --git a/src/applications/metamta/management/PhabricatorMailManagementReceiveTestWorkflow.php b/src/applications/metamta/management/PhabricatorMailManagementReceiveTestWorkflow.php index 73917a2d84..a3c556e6ac 100644 --- a/src/applications/metamta/management/PhabricatorMailManagementReceiveTestWorkflow.php +++ b/src/applications/metamta/management/PhabricatorMailManagementReceiveTestWorkflow.php @@ -181,8 +181,9 @@ final class PhabricatorMailManagementReceiveTestWorkflow $received->processReceivedMail(); $console->writeErr( - "%s\n\n phabricator/ $ ./bin/mail show-inbound --id %d\n\n", + "%s\n\n %s $ ./bin/mail show-inbound --id %d\n\n", pht('Mail received! You can view details by running this command:'), + PlatformSymbols::getPlatformServerPath(), $received->getID()); } diff --git a/src/applications/metamta/management/PhabricatorMailManagementSendTestWorkflow.php b/src/applications/metamta/management/PhabricatorMailManagementSendTestWorkflow.php index 6ea2c9de5a..54c7ff53f6 100644 --- a/src/applications/metamta/management/PhabricatorMailManagementSendTestWorkflow.php +++ b/src/applications/metamta/management/PhabricatorMailManagementSendTestWorkflow.php @@ -225,8 +225,9 @@ final class PhabricatorMailManagementSendTestWorkflow $mail->save(); $console->writeErr( - "%s\n\n phabricator/ $ ./bin/mail show-outbound --id %d\n\n", + "%s\n\n %s $ ./bin/mail show-outbound --id %d\n\n", pht('Mail sent! You can view details by running this command:'), + PlatformSymbols::getPlatformServerPath(), $mail->getID()); } diff --git a/src/applications/notification/client/PhabricatorNotificationServerRef.php b/src/applications/notification/client/PhabricatorNotificationServerRef.php index c5b0f2f8aa..2fe903fdba 100644 --- a/src/applications/notification/client/PhabricatorNotificationServerRef.php +++ b/src/applications/notification/client/PhabricatorNotificationServerRef.php @@ -143,8 +143,10 @@ final class PhabricatorNotificationServerRef return ($this->type == 'admin'); } - public function getURI($to_path = null) { - $full_path = rtrim($this->getPath(), '/').'/'.ltrim($to_path, '/'); + public function getURI($to_path = '') { + $path = coalesce($this->path, ''); + $to_path = coalesce($to_path, ''); + $full_path = rtrim($path, '/').'/'.ltrim($to_path, '/'); $uri = id(new PhutilURI('http://'.$this->getHost())) ->setProtocol($this->getProtocol()) @@ -159,9 +161,9 @@ final class PhabricatorNotificationServerRef return $uri; } - public function getWebsocketURI($to_path = null) { + public function getWebsocketURI($to_path = '') { $instance = PhabricatorEnv::getEnvConfig('cluster.instance'); - if (strlen($instance)) { + if (phutil_nonempty_string($instance)) { $to_path = $to_path.'~'.$instance.'/'; } diff --git a/src/applications/owners/application/PhabricatorOwnersApplication.php b/src/applications/owners/application/PhabricatorOwnersApplication.php index 3ef5f974d9..34bbc4b7b5 100644 --- a/src/applications/owners/application/PhabricatorOwnersApplication.php +++ b/src/applications/owners/application/PhabricatorOwnersApplication.php @@ -45,6 +45,10 @@ final class PhabricatorOwnersApplication extends PhabricatorApplication { ); } + public function getMonograms() { + return array('O'); + } + public function getRoutes() { return array( '/owners/' => array( diff --git a/src/applications/passphrase/application/PhabricatorPassphraseApplication.php b/src/applications/passphrase/application/PhabricatorPassphraseApplication.php index 2ab4f1e33d..ae79e5c8b5 100644 --- a/src/applications/passphrase/application/PhabricatorPassphraseApplication.php +++ b/src/applications/passphrase/application/PhabricatorPassphraseApplication.php @@ -34,6 +34,10 @@ final class PhabricatorPassphraseApplication extends PhabricatorApplication { return false; } + public function getMonograms() { + return array('K'); + } + public function getRoutes() { return array( '/K(?P\d+)' => 'PassphraseCredentialViewController', diff --git a/src/applications/passphrase/view/PassphraseCredentialControl.php b/src/applications/passphrase/view/PassphraseCredentialControl.php index 8ba1ef9bc8..98294832f7 100644 --- a/src/applications/passphrase/view/PassphraseCredentialControl.php +++ b/src/applications/passphrase/view/PassphraseCredentialControl.php @@ -50,7 +50,8 @@ final class PassphraseCredentialControl extends AphrontFormControl { // credential. Populate it into the menu to allow them to save the form // without making any changes. $current_phid = $this->getValue(); - if (strlen($current_phid) && empty($options_map[$current_phid])) { + if (phutil_nonempty_string($current_phid) && + empty($options_map[$current_phid])) { $viewer = $this->getViewer(); $current_name = null; diff --git a/src/applications/paste/application/PhabricatorPasteApplication.php b/src/applications/paste/application/PhabricatorPasteApplication.php index 26e4b1740e..f6b6f7cf65 100644 --- a/src/applications/paste/application/PhabricatorPasteApplication.php +++ b/src/applications/paste/application/PhabricatorPasteApplication.php @@ -32,6 +32,10 @@ final class PhabricatorPasteApplication extends PhabricatorApplication { ); } + public function getMonograms() { + return array('P'); + } + public function getRoutes() { return array( '/P(?P[1-9]\d*)(?:\$(?P\d+(?:-\d+)?))?' diff --git a/src/applications/paste/conduit/PasteCreateConduitAPIMethod.php b/src/applications/paste/conduit/PasteCreateConduitAPIMethod.php index c62ecd0494..d55d184874 100644 --- a/src/applications/paste/conduit/PasteCreateConduitAPIMethod.php +++ b/src/applications/paste/conduit/PasteCreateConduitAPIMethod.php @@ -43,7 +43,7 @@ final class PasteCreateConduitAPIMethod extends PasteConduitAPIMethod { $title = $request->getValue('title'); $language = $request->getValue('language'); - if (!strlen($content)) { + if (!phutil_nonempty_string($content)) { throw new ConduitException('ERR-NO-PASTE'); } diff --git a/src/applications/people/controller/PhabricatorPeopleDeleteController.php b/src/applications/people/controller/PhabricatorPeopleDeleteController.php index 8e6ac91da7..2f45b40d31 100644 --- a/src/applications/people/controller/PhabricatorPeopleDeleteController.php +++ b/src/applications/people/controller/PhabricatorPeopleDeleteController.php @@ -27,9 +27,12 @@ final class PhabricatorPeopleDeleteController 'To permanently destroy this user, run this command from the '. 'command line:')) ->appendCommand( - csprintf( - 'phabricator/ $ ./bin/remove destroy %R', - $user->getMonogram())) + hsprintf( + '%s $ %s', + PlatformSymbols::getPlatformServerPath(), + csprintf( + './bin/remove destroy %R', + $user->getMonogram()))) ->appendParagraph( pht( 'Unless you have a very good reason to delete this user, consider '. diff --git a/src/applications/phame/application/PhabricatorPhameApplication.php b/src/applications/phame/application/PhabricatorPhameApplication.php index cd2eb4b487..b030673d1f 100644 --- a/src/applications/phame/application/PhabricatorPhameApplication.php +++ b/src/applications/phame/application/PhabricatorPhameApplication.php @@ -31,6 +31,10 @@ final class PhabricatorPhameApplication extends PhabricatorApplication { ); } + public function getMonograms() { + return array('J'); + } + public function getRoutes() { return array( '/J(?P[1-9]\d*)' => 'PhamePostViewController', diff --git a/src/applications/phame/controller/blog/PhameBlogFeedController.php b/src/applications/phame/controller/blog/PhameBlogFeedController.php index c0c6e60cc4..1523a8d5e6 100644 --- a/src/applications/phame/controller/blog/PhameBlogFeedController.php +++ b/src/applications/phame/controller/blog/PhameBlogFeedController.php @@ -71,6 +71,11 @@ final class PhameBlogFeedController extends PhameBlogController { '%s', $bloggers[$post->getBloggerPHID()]->getFullName()); + $content[] = phutil_tag( + 'published', + array(), + date('c', $post->getDatePublished())); + $content[] = phutil_tag( 'updated', array(), diff --git a/src/applications/phame/storage/PhameBlog.php b/src/applications/phame/storage/PhameBlog.php index 587f5daea3..8ab5c2747e 100644 --- a/src/applications/phame/storage/PhameBlog.php +++ b/src/applications/phame/storage/PhameBlog.php @@ -154,7 +154,7 @@ final class PhameBlog extends PhameDAO $href = PhabricatorEnv::getProductionURI( '/config/edit/policy.allow-public/'); return pht( - 'For custom domains to work, this this server must be '. + 'For custom domains to work, this server must be '. 'configured to allow the public access policy. Configure this '. 'setting %s, or ask an administrator to configure this setting. '. 'The domain can be specified later once this setting has been '. diff --git a/src/applications/phid/type/PhabricatorPHIDType.php b/src/applications/phid/type/PhabricatorPHIDType.php index 2f82dcf169..f15df7f886 100644 --- a/src/applications/phid/type/PhabricatorPHIDType.php +++ b/src/applications/phid/type/PhabricatorPHIDType.php @@ -205,4 +205,28 @@ abstract class PhabricatorPHIDType extends Phobject { return $installed_types; } + + /** + * Get all PHID types of applications installed for a given viewer. + * + * @param PhabricatorUser Viewing user. + * @return dict Map of constants to installed + * types. + */ + public static function getAllTypesForApplication( + string $application) { + $all_types = self::getAllTypes(); + + $application_types = array(); + + foreach ($all_types as $key => $type) { + if ($type->getPHIDTypeApplicationClass() != $application) { + continue; + } + + $application_types[$key] = $type; + } + + return $application_types; + } } diff --git a/src/applications/pholio/application/PhabricatorPholioApplication.php b/src/applications/pholio/application/PhabricatorPholioApplication.php index 4d80dd12ae..5ac650cc20 100644 --- a/src/applications/pholio/application/PhabricatorPholioApplication.php +++ b/src/applications/pholio/application/PhabricatorPholioApplication.php @@ -32,6 +32,10 @@ final class PhabricatorPholioApplication extends PhabricatorApplication { ); } + public function getMonograms() { + return array('M'); + } + public function getRoutes() { return array( '/M(?P[1-9]\d*)(?:/(?P\d+)/)?' => 'PholioMockViewController', diff --git a/src/applications/pholio/xaction/PholioImageNameTransaction.php b/src/applications/pholio/xaction/PholioImageNameTransaction.php index 33b01903ee..f4705a98fc 100644 --- a/src/applications/pholio/xaction/PholioImageNameTransaction.php +++ b/src/applications/pholio/xaction/PholioImageNameTransaction.php @@ -31,8 +31,8 @@ final class PholioImageNameTransaction '%s renamed an image (%s) from %s to %s.', $this->renderAuthor(), $this->renderHandle(key($new)), - $this->renderValue($old), - $this->renderValue($new)); + $this->renderValue((string)head($old)), + $this->renderValue((string)head($new))); } public function getTitleForFeed() { diff --git a/src/applications/pholio/xaction/PholioImageSequenceTransaction.php b/src/applications/pholio/xaction/PholioImageSequenceTransaction.php index c98c199adf..4d6099ed14 100644 --- a/src/applications/pholio/xaction/PholioImageSequenceTransaction.php +++ b/src/applications/pholio/xaction/PholioImageSequenceTransaction.php @@ -29,7 +29,7 @@ final class PholioImageSequenceTransaction return pht( '%s updated an image\'s (%s) sequence.', $this->renderAuthor(), - $this->renderHandleLink(key($new))); + $this->renderHandle(head_key($new))); } public function getTitleForFeed() { diff --git a/src/applications/phriction/conduit/PhrictionCreateConduitAPIMethod.php b/src/applications/phriction/conduit/PhrictionCreateConduitAPIMethod.php index 300dbbfa80..61d3611faf 100644 --- a/src/applications/phriction/conduit/PhrictionCreateConduitAPIMethod.php +++ b/src/applications/phriction/conduit/PhrictionCreateConduitAPIMethod.php @@ -25,7 +25,7 @@ final class PhrictionCreateConduitAPIMethod extends PhrictionConduitAPIMethod { protected function execute(ConduitAPIRequest $request) { $slug = $request->getValue('slug'); - if (!strlen($slug)) { + if (!phutil_nonempty_string($slug)) { throw new Exception(pht('No such document.')); } $doc = id(new PhrictionDocumentQuery()) diff --git a/src/applications/phurl/application/PhabricatorPhurlApplication.php b/src/applications/phurl/application/PhabricatorPhurlApplication.php index 14ffda77f1..56290ef5e1 100644 --- a/src/applications/phurl/application/PhabricatorPhurlApplication.php +++ b/src/applications/phurl/application/PhabricatorPhurlApplication.php @@ -37,6 +37,10 @@ final class PhabricatorPhurlApplication extends PhabricatorApplication { ); } + public function getMonograms() { + return array('U'); + } + public function getRoutes() { return array( '/U(?P[1-9]\d*)/?' => 'PhabricatorPhurlURLViewController', diff --git a/src/applications/policy/filter/PhabricatorPolicyFilter.php b/src/applications/policy/filter/PhabricatorPolicyFilter.php index d8f239e51a..3443d17156 100644 --- a/src/applications/policy/filter/PhabricatorPolicyFilter.php +++ b/src/applications/policy/filter/PhabricatorPolicyFilter.php @@ -461,7 +461,7 @@ final class PhabricatorPolicyFilter extends Phobject { // checks make it difficult to create cycles normally, so just do a // simple check here to limit damage. - static $depth; + static $depth = 0; $depth++; diff --git a/src/applications/ponder/application/PhabricatorPonderApplication.php b/src/applications/ponder/application/PhabricatorPonderApplication.php index 56973447f9..e6f4ef8867 100644 --- a/src/applications/ponder/application/PhabricatorPonderApplication.php +++ b/src/applications/ponder/application/PhabricatorPonderApplication.php @@ -47,6 +47,10 @@ final class PhabricatorPonderApplication extends PhabricatorApplication { pht('Learn More'))); } + public function getMonograms() { + return array('Q'); + } + public function getRoutes() { return array( '/Q(?P[1-9]\d*)' diff --git a/src/applications/project/controller/PhabricatorProjectColumnEditController.php b/src/applications/project/controller/PhabricatorProjectColumnEditController.php index 9ddb2b7d8a..bf579b274f 100644 --- a/src/applications/project/controller/PhabricatorProjectColumnEditController.php +++ b/src/applications/project/controller/PhabricatorProjectColumnEditController.php @@ -45,16 +45,32 @@ final class PhabricatorProjectColumnEditController $e_name = null; $e_limit = null; + $e_milestone_name = null; $v_limit = $column->getPointLimit(); $v_name = $column->getName(); + $proxy = $column->getProxy(); + + // Is this a normal Column? Example: when true, this is not a Milestone. + $is_column = !$proxy; + + // Is this a Milestone? Example: when true, this is not a normal Column. + $is_milestone = $proxy && $proxy->isMilestone(); + + // Milestone name, eventually coming from the proxed object. + $v_milestone_name = null; + if ($is_milestone) { + $v_milestone_name = $proxy->getName(); + } + $validation_exception = null; $view_uri = $project->getWorkboardURI(); if ($request->isFormPost()) { $v_name = $request->getStr('name'); $v_limit = $request->getStr('limit'); + $v_milestone_name = $request->getStr('milestone.name'); if ($is_new) { $column->setProjectPHID($project->getPHID()); @@ -74,14 +90,22 @@ final class PhabricatorProjectColumnEditController } $xactions = array(); + $xactions_milestone = array(); $type_name = PhabricatorProjectColumnNameTransaction::TRANSACTIONTYPE; $type_limit = PhabricatorProjectColumnLimitTransaction::TRANSACTIONTYPE; + $type_project_name = PhabricatorProjectNameTransaction::TRANSACTIONTYPE; - if (!$column->getProxy()) { + if ($is_column) { + // Transaction for Column name. $xactions[] = id(new PhabricatorProjectColumnTransaction()) ->setTransactionType($type_name) ->setNewValue($v_name); + } else if ($is_milestone) { + // Transaction for Milestone name (that internally is a Project Name). + $xactions_milestone[] = id(new PhabricatorProjectTransaction()) + ->setTransactionType($type_project_name) + ->setNewValue($v_milestone_name); } $xactions[] = id(new PhabricatorProjectColumnTransaction()) @@ -94,24 +118,53 @@ final class PhabricatorProjectColumnEditController ->setContinueOnNoEffect(true) ->setContentSourceFromRequest($request) ->applyTransactions($column, $xactions); - return id(new AphrontRedirectResponse())->setURI($view_uri); } catch (PhabricatorApplicationTransactionValidationException $ex) { + // Error messages related to the Column (like invalid Name, etc.) $e_name = $ex->getShortMessage($type_name); $e_limit = $ex->getShortMessage($type_limit); $validation_exception = $ex; } + + // Save Milestone-related stuff but only if there were no prior problems + // and only if we have changes. + if (!$validation_exception && $xactions_milestone) { + try { + $editor_milestone = id(new PhabricatorProjectTransactionEditor()) + ->setActor($viewer) + ->setContinueOnNoEffect(true) + ->setContentSourceFromRequest($request) + ->applyTransactions($proxy, $xactions_milestone); + } catch (PhabricatorApplicationTransactionValidationException $ex) { + // Error messages related to the Milestone (like invalid Name, etc.) + $e_milestone_name = $ex->getShortMessage($type_project_name); + $validation_exception = $ex; + } + } + + // Refresh the page only if there are no errors to show. + if (!$validation_exception) { + return id(new AphrontRedirectResponse())->setURI($view_uri); + } } $form = id(new AphrontFormView()) ->setUser($request->getUser()); - if (!$column->getProxy()) { + // Show the most appropriate input field for the name. + if ($is_column) { $form->appendChild( id(new AphrontFormTextControl()) ->setValue($v_name) ->setLabel(pht('Name')) ->setName('name') ->setError($e_name)); + } else if ($is_milestone) { + $form->appendChild( + id(new AphrontFormTextControl()) + ->setValue($v_milestone_name) + ->setLabel(pht('Milestone Name')) + ->setName('milestone.name') + ->setError($e_milestone_name)); } $form->appendChild( diff --git a/src/applications/project/editor/PhabricatorProjectTransactionEditor.php b/src/applications/project/editor/PhabricatorProjectTransactionEditor.php index eb57c39b2c..9c6e5cf4cc 100644 --- a/src/applications/project/editor/PhabricatorProjectTransactionEditor.php +++ b/src/applications/project/editor/PhabricatorProjectTransactionEditor.php @@ -295,6 +295,12 @@ final class PhabricatorProjectTransactionEditor } public function removeSlugs(PhabricatorProject $project, array $slugs) { + // Do not allow removing the project's primary slug which the edit form + // may allow through a series of renames/moves. See T15636 + if (($key = array_search($project->getPrimarySlug(), $slugs)) !== false) { + unset($slugs[$key]); + } + if (!$slugs) { return; } diff --git a/src/applications/repository/capability/PhabricatorRepositoryIdentityEditViewCapability.php b/src/applications/repository/capability/PhabricatorRepositoryIdentityEditViewCapability.php new file mode 100644 index 0000000000..9bb9b62ebc --- /dev/null +++ b/src/applications/repository/capability/PhabricatorRepositoryIdentityEditViewCapability.php @@ -0,0 +1,16 @@ +getApplication()->getPolicy( + PhabricatorRepositoryIdentityEditViewCapability::CAPABILITY); } protected function buildCustomEditFields($object) { diff --git a/src/applications/repository/query/PhabricatorRepositoryQuery.php b/src/applications/repository/query/PhabricatorRepositoryQuery.php index 05b011e85a..8dead39758 100644 --- a/src/applications/repository/query/PhabricatorRepositoryQuery.php +++ b/src/applications/repository/query/PhabricatorRepositoryQuery.php @@ -9,7 +9,6 @@ final class PhabricatorRepositoryQuery private $types; private $uuids; private $uris; - private $datasourceQuery; private $slugs; private $almanacServicePHIDs; @@ -62,6 +61,10 @@ final class PhabricatorRepositoryQuery $slugs = array(); foreach ($identifiers as $identifier) { + if ($identifier === null) { + continue; + } + if (ctype_digit((string)$identifier)) { $ids[$identifier] = $identifier; continue; @@ -120,11 +123,6 @@ final class PhabricatorRepositoryQuery return $this; } - public function withDatasourceQuery($query) { - $this->datasourceQuery = $query; - return $this; - } - public function withSlugs(array $slugs) { $this->slugs = $slugs; return $this; @@ -633,22 +631,6 @@ final class PhabricatorRepositoryQuery $this->uuids); } - if (phutil_nonempty_string($this->datasourceQuery)) { - // This handles having "rP" match callsigns starting with "P...". - $query = trim($this->datasourceQuery); - if (preg_match('/^r/', $query)) { - $callsign = substr($query, 1); - } else { - $callsign = $query; - } - $where[] = qsprintf( - $conn, - 'r.name LIKE %> OR r.callsign LIKE %> OR r.repositorySlug LIKE %>', - $query, - $callsign, - $query); - } - if ($this->slugs !== null) { $where[] = qsprintf( $conn, diff --git a/src/applications/repository/search/PhabricatorRepositoryFulltextEngine.php b/src/applications/repository/search/PhabricatorRepositoryFulltextEngine.php index f666af552f..838692c351 100644 --- a/src/applications/repository/search/PhabricatorRepositoryFulltextEngine.php +++ b/src/applications/repository/search/PhabricatorRepositoryFulltextEngine.php @@ -7,10 +7,21 @@ final class PhabricatorRepositoryFulltextEngine PhabricatorSearchAbstractDocument $document, $object) { $repo = $object; - $document->setDocumentTitle($repo->getName()); + + $title_fields = array( + $repo->getName(), + $repo->getRepositorySlug(), + ); + $callsign = $repo->getCallsign(); + if ($callsign) { + $title_fields[] = $callsign; + $title_fields[] = 'r'.$callsign; + } + + $document->setDocumentTitle(implode("\n", $title_fields)); $document->addField( PhabricatorSearchDocumentFieldType::FIELD_BODY, - $repo->getRepositorySlug()."\n".$repo->getDetail('description')); + $repo->getDetail('description')); $document->setDocumentCreated($repo->getDateCreated()); $document->setDocumentModified($repo->getDateModified()); diff --git a/src/applications/repository/storage/PhabricatorRepository.php b/src/applications/repository/storage/PhabricatorRepository.php index 4a1c923622..b2855c0c06 100644 --- a/src/applications/repository/storage/PhabricatorRepository.php +++ b/src/applications/repository/storage/PhabricatorRepository.php @@ -345,12 +345,12 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO // Make some reasonable effort to produce reasonable default directory // names from repository names. - if (!strlen($name)) { + if (!phutil_nonempty_string($name)) { $name = $this->getName(); $name = phutil_utf8_strtolower($name); $name = preg_replace('@[ -/:->]+@', '-', $name); $name = trim($name, '-'); - if (!strlen($name)) { + if (!phutil_nonempty_string($name)) { $name = $this->getCallsign(); } } diff --git a/src/applications/repository/storage/PhabricatorRepositoryCommit.php b/src/applications/repository/storage/PhabricatorRepositoryCommit.php index 9e20a36676..ef3657d49f 100644 --- a/src/applications/repository/storage/PhabricatorRepositoryCommit.php +++ b/src/applications/repository/storage/PhabricatorRepositoryCommit.php @@ -478,7 +478,7 @@ final class PhabricatorRepositoryCommit } $author = $this->getRawAuthorStringForDisplay(); - if (strlen($author)) { + if (phutil_nonempty_string($author)) { return DiffusionView::renderName($author); } @@ -493,7 +493,7 @@ final class PhabricatorRepositoryCommit } $committer = $this->getRawCommitterStringForDisplay(); - if (strlen($committer)) { + if (phutil_nonempty_string($committer)) { return DiffusionView::renderName($committer); } diff --git a/src/applications/repository/storage/PhabricatorRepositoryCommitData.php b/src/applications/repository/storage/PhabricatorRepositoryCommitData.php index c77da64ec2..96508a2452 100644 --- a/src/applications/repository/storage/PhabricatorRepositoryCommitData.php +++ b/src/applications/repository/storage/PhabricatorRepositoryCommitData.php @@ -97,7 +97,7 @@ final class PhabricatorRepositoryCommitData extends PhabricatorRepositoryDAO { $ref = $this->getCommitRef(); $author = $ref->getAuthor(); - if (strlen($author)) { + if (phutil_nonempty_string($author)) { return $author; } @@ -131,7 +131,7 @@ final class PhabricatorRepositoryCommitData extends PhabricatorRepositoryDAO { $ref = $this->getCommitRef(); $committer = $ref->getCommitter(); - if (strlen($committer)) { + if (phutil_nonempty_string($committer)) { return $committer; } diff --git a/src/applications/repository/storage/PhabricatorRepositoryIdentity.php b/src/applications/repository/storage/PhabricatorRepositoryIdentity.php index 74fbd06544..df19f302f6 100644 --- a/src/applications/repository/storage/PhabricatorRepositoryIdentity.php +++ b/src/applications/repository/storage/PhabricatorRepositoryIdentity.php @@ -142,7 +142,10 @@ final class PhabricatorRepositoryIdentity } public function getPolicy($capability) { - return PhabricatorPolicies::getMostOpenPolicy(); + $app = PhabricatorApplication::getByClass( + 'PhabricatorDiffusionApplication'); + return $app->getPolicy( + PhabricatorRepositoryIdentityEditViewCapability::CAPABILITY); } public function hasAutomaticCapability( diff --git a/src/applications/repository/storage/PhabricatorRepositoryURITransaction.php b/src/applications/repository/storage/PhabricatorRepositoryURITransaction.php index 241a95dad9..49d1a44943 100644 --- a/src/applications/repository/storage/PhabricatorRepositoryURITransaction.php +++ b/src/applications/repository/storage/PhabricatorRepositoryURITransaction.php @@ -57,7 +57,7 @@ final class PhabricatorRepositoryURITransaction $new_label = idx(idx($map, $new, array()), 'label', $new); return pht( - '%s changed the display type for this URI from "%s" to "%s".', + '%s changed the I/O type for this URI from "%s" to "%s".', $this->renderHandleLink($author_phid), $old_label, $new_label); diff --git a/src/applications/repository/worker/commitmessageparser/PhabricatorRepositoryCommitMessageParserWorker.php b/src/applications/repository/worker/commitmessageparser/PhabricatorRepositoryCommitMessageParserWorker.php index a0ea2d84b2..fc0bd42477 100644 --- a/src/applications/repository/worker/commitmessageparser/PhabricatorRepositoryCommitMessageParserWorker.php +++ b/src/applications/repository/worker/commitmessageparser/PhabricatorRepositoryCommitMessageParserWorker.php @@ -36,7 +36,7 @@ abstract class PhabricatorRepositoryCommitMessageParserWorker $author = $ref->getAuthor(); $committer = $ref->getCommitter(); - $has_committer = (bool)strlen($committer); + $has_committer = phutil_nonempty_string($committer); $identity_engine = id(new DiffusionRepositoryIdentityEngine()) ->setViewer($viewer) diff --git a/src/applications/search/engineextension/PhabricatorFerretSearchEngineExtension.php b/src/applications/search/engineextension/PhabricatorFerretSearchEngineExtension.php index 55b7c2225a..2544f8b7da 100644 --- a/src/applications/search/engineextension/PhabricatorFerretSearchEngineExtension.php +++ b/src/applications/search/engineextension/PhabricatorFerretSearchEngineExtension.php @@ -27,7 +27,7 @@ final class PhabricatorFerretSearchEngineExtension PhabricatorSavedQuery $saved, array $map) { - if (!strlen($map['query'])) { + if (!(isset($map['query']) && strlen($map['query']))) { return; } diff --git a/src/applications/settings/controller/PhabricatorSettingsTimezoneController.php b/src/applications/settings/controller/PhabricatorSettingsTimezoneController.php index 8ae2704161..0ed286da02 100644 --- a/src/applications/settings/controller/PhabricatorSettingsTimezoneController.php +++ b/src/applications/settings/controller/PhabricatorSettingsTimezoneController.php @@ -31,11 +31,12 @@ final class PhabricatorSettingsTimezoneController $did_calibrate = false; if ($request->isFormPost()) { $timezone = $request->getStr('timezone'); + $ignore_conflict_checkbox = $request->getInt('ignoreConflict'); $pref_ignore = PhabricatorTimezoneIgnoreOffsetSetting::SETTINGKEY; $pref_timezone = PhabricatorTimezoneSetting::SETTINGKEY; - if ($timezone == 'ignore') { + if ($timezone === 'ignore' || $ignore_conflict_checkbox) { $this->writeSettings( array( $pref_ignore => $client_offset, @@ -83,20 +84,29 @@ final class PhabricatorSettingsTimezoneController $guess = 'ignore'; } - $current_zone = $viewer->getTimezoneIdentifier(); - $current_zone = phutil_tag('strong', array(), $current_zone); + $current_zone_identifier = $viewer->getTimezoneIdentifier(); + $current_zone_formatted = phutil_tag( + 'strong', + array(), + $current_zone_identifier); $form = id(new AphrontFormView()) ->appendChild( id(new AphrontFormMarkupControl()) ->setLabel(pht('Current Setting')) - ->setValue($current_zone)) + ->setValue($current_zone_formatted)) ->appendChild( id(new AphrontFormSelectControl()) ->setName('timezone') ->setLabel(pht('New Setting')) ->setOptions($options) - ->setValue($guess)); + ->setValue($guess)) + ->appendChild(id(new AphrontFormCheckboxControl()) + ->addCheckbox( + 'ignoreConflict', + 1, + pht('Ignore New Setting and Keep %s', $current_zone_identifier))); + return $this->newDialog() ->setTitle(pht('Adjust Timezone')) @@ -104,13 +114,13 @@ final class PhabricatorSettingsTimezoneController ->appendParagraph( pht( 'Your browser timezone (%s) differs from your profile timezone '. - '(%s). You can ignore this conflict or adjust your profile setting '. - 'to match your client.', + '(%s). You can adjust your profile setting to match your browser, '. + 'or ignore this conflict to keep your current profile setting.', $this->formatOffset($client_offset), $this->formatOffset($server_offset))) ->appendForm($form) ->addCancelButton(pht('Cancel')) - ->addSubmitButton(pht('Change Timezone')); + ->addSubmitButton(pht('Confirm')); } private function formatOffset($offset) { diff --git a/src/applications/settings/panel/PhabricatorContactNumbersSettingsPanel.php b/src/applications/settings/panel/PhabricatorContactNumbersSettingsPanel.php index 7056fd02de..60a2064546 100644 --- a/src/applications/settings/panel/PhabricatorContactNumbersSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorContactNumbersSettingsPanel.php @@ -19,6 +19,18 @@ final class PhabricatorContactNumbersSettingsPanel return PhabricatorSettingsAuthenticationPanelGroup::PANELGROUPKEY; } + /** + * Whether to display "Contact Numbers" panel in users' Personal + * Settings by checking if global SMS support is configured + */ + public function isUserPanel() { + $sms_auth_factor = new PhabricatorSMSAuthFactor(); + if ($sms_auth_factor->isSMSMailerConfigured()) { + return true; + } + return false; + } + public function isMultiFactorEnrollmentPanel() { return true; } diff --git a/src/applications/settings/setting/PhabricatorMonospacedFontSetting.php b/src/applications/settings/setting/PhabricatorMonospacedFontSetting.php index 2a96f5d95f..5cfbec1b26 100644 --- a/src/applications/settings/setting/PhabricatorMonospacedFontSetting.php +++ b/src/applications/settings/setting/PhabricatorMonospacedFontSetting.php @@ -25,7 +25,7 @@ final class PhabricatorMonospacedFontSetting } public function validateTransactionValue($value) { - if (!strlen($value)) { + if (!phutil_nonempty_string($value)) { return; } diff --git a/src/applications/slowvote/application/PhabricatorSlowvoteApplication.php b/src/applications/slowvote/application/PhabricatorSlowvoteApplication.php index 1e4bd78419..8fa4edc6f6 100644 --- a/src/applications/slowvote/application/PhabricatorSlowvoteApplication.php +++ b/src/applications/slowvote/application/PhabricatorSlowvoteApplication.php @@ -45,6 +45,10 @@ final class PhabricatorSlowvoteApplication extends PhabricatorApplication { ); } + public function getMonograms() { + return array('V'); + } + public function getRoutes() { return array( '/V(?P[1-9]\d*)' => 'PhabricatorSlowvotePollController', diff --git a/src/applications/spaces/application/PhabricatorSpacesApplication.php b/src/applications/spaces/application/PhabricatorSpacesApplication.php index d542551ae4..f40538b69b 100644 --- a/src/applications/spaces/application/PhabricatorSpacesApplication.php +++ b/src/applications/spaces/application/PhabricatorSpacesApplication.php @@ -49,6 +49,10 @@ final class PhabricatorSpacesApplication extends PhabricatorApplication { ); } + public function getMonograms() { + return array('S'); + } + public function getRoutes() { return array( '/S(?P[1-9]\d*)' => 'PhabricatorSpacesViewController', diff --git a/src/applications/system/application/PhabricatorSystemApplication.php b/src/applications/system/application/PhabricatorSystemApplication.php index 6184c0de24..f3abc54d14 100644 --- a/src/applications/system/application/PhabricatorSystemApplication.php +++ b/src/applications/system/application/PhabricatorSystemApplication.php @@ -17,6 +17,7 @@ final class PhabricatorSystemApplication extends PhabricatorApplication { public function getEventListeners() { return array( new PhabricatorSystemDebugUIEventListener(), + new PhorgeSystemDeprecationWarningListener(), ); } diff --git a/src/applications/system/controller/robots/PhabricatorRobotsPlatformController.php b/src/applications/system/controller/robots/PhabricatorRobotsPlatformController.php index b4a3c4fa37..7151f2e4aa 100644 --- a/src/applications/system/controller/robots/PhabricatorRobotsPlatformController.php +++ b/src/applications/system/controller/robots/PhabricatorRobotsPlatformController.php @@ -18,6 +18,15 @@ final class PhabricatorRobotsPlatformController $out[] = 'User-Agent: *'; $out[] = 'Disallow: /diffusion/'; $out[] = 'Disallow: /source/'; + // See T15670. Also prevent directly accessing commits in Diffusion. + $out[] = 'Disallow: /r*'; + + // See T15662. Prevent indexing line anchor links in Pastes. Per RFC 9309 + // section 2.2.3, percentage-encode "$" to avoid interpretation as end of + // match pattern. However, crawlers may not abide by it but follow the + // original standard at https://www.robotstxt.org/orig.html with no mention + // how to interpret characters like "$" and thus entirely ignore this rule. + $out[] = 'Disallow: /P*%24*'; // Add a small crawl delay (number of seconds between requests) for spiders // which respect it. The intent here is to prevent spiders from affecting diff --git a/src/applications/system/events/PhorgeSystemDeprecationWarningListener.php b/src/applications/system/events/PhorgeSystemDeprecationWarningListener.php new file mode 100644 index 0000000000..147e84a584 --- /dev/null +++ b/src/applications/system/events/PhorgeSystemDeprecationWarningListener.php @@ -0,0 +1,58 @@ +getKey(self::CACHE_KEY); + + if (!$cache_entry) { + $cache_entry = array(); + } + + $trace_entry = idx($cache_entry, $trace_key); + + if ($trace_entry) { + $trace_entry['counter']++; + } else { + $trace_entry = array( + 'counter' => 1, + 'message' => $value, + 'trace' => PhutilErrorHandler::formatStacktrace($metadata['trace']), + ); + } + $cache_entry[$trace_key] = $trace_entry; + + $cache->setKey(self::CACHE_KEY , $cache_entry); + } + + public function getWarnings() { + $cache = PhabricatorCaches::getRuntimeCache(); + return $cache->getKey(self::CACHE_KEY); + } + +} diff --git a/src/applications/tokens/query/PhabricatorTokenGivenQuery.php b/src/applications/tokens/query/PhabricatorTokenGivenQuery.php index 0e6ad9eb54..14e8016cf1 100644 --- a/src/applications/tokens/query/PhabricatorTokenGivenQuery.php +++ b/src/applications/tokens/query/PhabricatorTokenGivenQuery.php @@ -3,10 +3,16 @@ final class PhabricatorTokenGivenQuery extends PhabricatorCursorPagedPolicyAwareQuery { + private $ids; private $authorPHIDs; private $objectPHIDs; private $tokenPHIDs; + public function withIDs(array $ids) { + $this->ids = $ids; + return $this; + } + public function withTokenPHIDs(array $token_phids) { $this->tokenPHIDs = $token_phids; return $this; @@ -29,6 +35,13 @@ final class PhabricatorTokenGivenQuery protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { $where = parent::buildWhereClauseParts($conn); + if ($this->ids !== null) { + $where[] = qsprintf( + $conn, + 'id IN (%Ld)', + $this->ids); + } + if ($this->authorPHIDs !== null) { $where[] = qsprintf( $conn, diff --git a/src/applications/transactions/bulk/PhabricatorEditEngineBulkJobType.php b/src/applications/transactions/bulk/PhabricatorEditEngineBulkJobType.php index 758e7f3439..811b4e1565 100644 --- a/src/applications/transactions/bulk/PhabricatorEditEngineBulkJobType.php +++ b/src/applications/transactions/bulk/PhabricatorEditEngineBulkJobType.php @@ -31,9 +31,9 @@ final class PhabricatorEditEngineBulkJobType $parts[] = pht('To silence this edit, run this command:'); $command = csprintf( - 'phabricator/ $ ./bin/bulk make-silent --id %R', + '%s $ ./bin/bulk make-silent --id %R', + PlatformSymbols::getPlatformServerPath(), $job->getID()); - $command = (string)$command; $parts[] = phutil_tag('tt', array(), $command); diff --git a/src/applications/transactions/xaction/PhabricatorEditEngineDefaultTransaction.php b/src/applications/transactions/xaction/PhabricatorEditEngineDefaultTransaction.php index 7b980cdb1a..38011058b6 100644 --- a/src/applications/transactions/xaction/PhabricatorEditEngineDefaultTransaction.php +++ b/src/applications/transactions/xaction/PhabricatorEditEngineDefaultTransaction.php @@ -65,7 +65,7 @@ final class PhabricatorEditEngineDefaultTransaction return id(new PhutilJSON())->encodeAsList($default_value); } - return id(new PhutilJSON())->encodeAsObject($default_value); + return id(new PhutilJSON())->encodeFormatted($default_value); } } diff --git a/src/applications/uiexample/examples/PhabricatorSetupIssueUIExample.php b/src/applications/uiexample/examples/PhabricatorSetupIssueUIExample.php index d6386e59d4..4343bcb8cb 100644 --- a/src/applications/uiexample/examples/PhabricatorSetupIssueUIExample.php +++ b/src/applications/uiexample/examples/PhabricatorSetupIssueUIExample.php @@ -24,8 +24,12 @@ final class PhabricatorSetupIssueUIExample extends PhabricatorUIExample { ->setSummary(pht('Summary')) ->setMessage(pht('Message')) ->setIssueKey('example.key') - ->addCommand('$ # Add Command') - ->addCommand(hsprintf('$ %s', '$ ls -1 > /dev/null')) + ->addCommand(hsprintf( + '%s $# Add Command', + PlatformSymbols::getPlatformServerPath())) + ->addCommand(hsprintf( + '%s $ls -1 > /dev/null', + PlatformSymbols::getPlatformServerPath())) ->addPHPConfig('php.config.example') ->addPhabricatorConfig('test.value') ->addPHPExtension('libexample'); diff --git a/src/docs/book/phorge.book b/src/docs/book/phorge.book index 0be0d5526d..b421144f2e 100644 --- a/src/docs/book/phorge.book +++ b/src/docs/book/phorge.book @@ -57,10 +57,6 @@ "name": "Celerity", "include": "(^src/applications/celerity/)" }, - "chatlog": { - "name": "Chatlog", - "include": "(^src/applications/chatlog/)" - }, "conduit": { "name": "Conduit", "include": "(^src/applications/conduit/)" diff --git a/src/docs/contributor/contributing_code.diviner b/src/docs/contributor/contributing_code.diviner index c7bdec25c9..adc56aca1a 100644 --- a/src/docs/contributor/contributing_code.diviner +++ b/src/docs/contributor/contributing_code.diviner @@ -194,4 +194,6 @@ Next Steps Continue by: - - returning to the @{article:Contributor Introduction}. + - preparing your development environment as described in the + @{article:Developer Setup} + - returning to the @{article:Contributor Introduction} diff --git a/src/docs/contributor/database.diviner b/src/docs/contributor/database.diviner index dc553678a8..6572e42fc1 100644 --- a/src/docs/contributor/database.diviner +++ b/src/docs/contributor/database.diviner @@ -28,7 +28,7 @@ Databases ========= Each Phorge application has its own database. The names are prefixed by -`phorge_` (this is configurable). +`phabricator_` (this is configurable with `storage.default-namespace`). Phorge uses a separate database for each application. To understand why, see @{article:Why does Phorge need so many databases?}. diff --git a/src/docs/user/installation_guide.diviner b/src/docs/user/installation_guide.diviner index ec7aa186d2..135c94adc0 100644 --- a/src/docs/user/installation_guide.diviner +++ b/src/docs/user/installation_guide.diviner @@ -54,12 +54,12 @@ Phorge from any operating system with a web browser. However, the server software does not run on Windows. It does run on most other operating systems, so choose one of these instead: - - **Linux**: Most installs use Linux. - - **Mac OS X**: Mac OS X is an acceptable flavor of Linux. - - **FreeBSD**: While FreeBSD is certainly not a flavor of Linux, it is a fine + - **GNU/Linux**: Most installs use Linux. + - **Mac OS X**: Mac OS X is an acceptable non-flavor of Linux. + - **BSD**: While BSD is certainly not a flavor of Linux, it is a fine operating system possessed of many desirable qualities, and Phorge will - install and run properly on FreeBSD. - - **Solaris, etc.**: Other systems which look like Linux and quack like Linux + install and run properly on BSD. + - **Solaris, etc.**: Other systems which look like *nix and quack like *nix will generally work fine, although we may suffer a reduced ability to support and resolve issues on unusual operating systems. diff --git a/src/docs/user/userguide/differential.diviner b/src/docs/user/userguide/differential.diviner index d48ff4ceff..fad92dfa4e 100644 --- a/src/docs/user/userguide/differential.diviner +++ b/src/docs/user/userguide/differential.diviner @@ -66,6 +66,7 @@ Continue by: - diving into the details of inline comments in @{article:Differential User Guide: Inline Comments}; or - reading the FAQ at @{article:Differential User Guide: FAQ}; or + - learning how to use markup in comments at @{article:Remarkup Reference}; or - learning about test plans in @{article:Differential User Guide: Test Plans}; or - learning more about Herald in @{article:Herald User Guide}. diff --git a/src/docs/user/userguide/differential_faq.diviner b/src/docs/user/userguide/differential_faq.diviner index 0df1f7b1c9..979daf762a 100644 --- a/src/docs/user/userguide/differential_faq.diviner +++ b/src/docs/user/userguide/differential_faq.diviner @@ -41,8 +41,9 @@ always "request review" of an accepted revision, with a comment like: If authors are being jerks about this (making sweeping changes as soon as they get an accept), solve the problem socially by telling them to stop being jerks. -Unless you've configured additional layers of enforcement, there's nothing -stopping them from silently changing the code before pushing it, anyway. +Unless you've configured additional layers of enforcement (by +using @{article:Herald}), there's nothing stopping them from silently changing +the code before pushing it, anyway. = How can I enable syntax highlighting? = @@ -50,6 +51,10 @@ stopping them from silently changing the code before pushing it, anyway. You need to install and configure **Pygments** to highlight anything else than PHP. See the `pygments.enabled` configuration setting. += What formatting can be used in comments? = + +Phorge implements a markup language similar to other markup languages like +Markdown and Wiki markup. See @{article:Remarkup Reference}. = What do the very light green and red backgrounds mean? = diff --git a/src/docs/user/userguide/diffusion_hosting.diviner b/src/docs/user/userguide/diffusion_hosting.diviner index c8a1c26eed..0d84859082 100644 --- a/src/docs/user/userguide/diffusion_hosting.diviner +++ b/src/docs/user/userguide/diffusion_hosting.diviner @@ -360,13 +360,13 @@ be owned by `root`, and the script must have `755` permissions: ``` $ sudo chown root /path/to/somewhere/ $ sudo chown root /path/to/somewhere/phorge-ssh-hook.sh -$ sudo chmod 755 /path/to/somewhere/phorge-ssh-hook.sh +$ sudo chmod 755 /path/to/somewhere/phorge-ssh-hook.sh ``` If you don't do this, `sshd` will refuse to execute the hook. **Create `sshd_config` for Phorge**: Copy the template in -`phorge/resources/sshd/sshd_config.phabricator.example` to somewhere like +`phorge/resources/sshd/sshd_config.phorge.example` to somewhere like `/etc/ssh/sshd_config.phorge`. Open the file and edit the `AuthorizedKeysCommand`, diff --git a/src/docs/user/userguide/remarkup.diviner b/src/docs/user/userguide/remarkup.diviner index 4fb8fc75f8..fa0128127c 100644 --- a/src/docs/user/userguide/remarkup.diviner +++ b/src/docs/user/userguide/remarkup.diviner @@ -732,3 +732,7 @@ to the first anchor with "xyz" as a prefix of the anchor name. Remarkup editors provide a fullscreen composition mode. This can make it easier to edit large blocks of text, or improve focus by removing distractions. You can exit **Fullscreen** mode by clicking the button again or by pressing escape. + +See Also +======== +* @{article:Remarkup Reference: Cowsay} diff --git a/src/docs/user/userguide/remarkup_cowsay.diviner b/src/docs/user/userguide/remarkup_cowsay.diviner new file mode 100644 index 0000000000..696189afb6 --- /dev/null +++ b/src/docs/user/userguide/remarkup_cowsay.diviner @@ -0,0 +1,61 @@ +@title Remarkup Reference: Cowsay +@group userguide + +Overview +-------- + +Cowsay is an application by Tony Monroe which has been ported over to +Phabricator/Phorge to allow your comments to be voiced by +a cow. + +Basic Usage +----------- + +A basic example of using cowsay would be to add a comment + cowsay{{{Great work!}}} +which generates: +``` + _____________ +< Great work! > + ------------- + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || +``` + +Other Cowsay Templates +---------------------- +Other templates are available in externals/cowsay/cows/, and you can specify +one by calling cowsay with the 'cow' parameter. eg: + cowsay(cow='tux'){{{Great work!}}} +generates +``` + _____________ +< Great work! > + ------------- + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ +``` + +Other Parameters +---------------- +* think (set to 1 for thinking bubbles) +* eyes (default 'oo') +* tongue (default ' ', try 'P') + +See Also +======== +* @{article:Remarkup Reference} +* Have you tried figlet: +``` +figlet{{{figlet generates big text!}}} +``` diff --git a/src/infrastructure/customfield/standard/PhabricatorStandardCustomField.php b/src/infrastructure/customfield/standard/PhabricatorStandardCustomField.php index 373aa9b66a..0c4ea452a2 100644 --- a/src/infrastructure/customfield/standard/PhabricatorStandardCustomField.php +++ b/src/infrastructure/customfield/standard/PhabricatorStandardCustomField.php @@ -268,7 +268,7 @@ abstract class PhabricatorStandardCustomField public function readValueFromRequest(AphrontRequest $request) { $value = $request->getStr($this->getFieldKey()); - if (!strlen($value)) { + if (!phutil_nonempty_string($value)) { $value = null; } $this->setFieldValue($value); diff --git a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldDate.php b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldDate.php index 4aba7543e7..ca56816b42 100644 --- a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldDate.php +++ b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldDate.php @@ -11,7 +11,7 @@ final class PhabricatorStandardCustomFieldDate $indexes = array(); $value = $this->getFieldValue(); - if (strlen($value)) { + if (phutil_nonempty_scalar($value)) { $indexes[] = $this->newNumericIndex((int)$value); } @@ -24,7 +24,7 @@ final class PhabricatorStandardCustomFieldDate public function getValueForStorage() { $value = $this->getFieldValue(); - if (strlen($value)) { + if (phutil_nonempty_scalar($value)) { return (int)$value; } else { return null; @@ -32,7 +32,7 @@ final class PhabricatorStandardCustomFieldDate } public function setValueFromStorage($value) { - if (strlen($value)) { + if (phutil_nonempty_scalar($value)) { $value = (int)$value; } else { $value = null; @@ -74,7 +74,8 @@ final class PhabricatorStandardCustomFieldDate // specify as a string. Parse the string into an epoch. $value = $this->getFieldValue(); - if (!ctype_digit($value)) { + if ($value !== null && gettype($value) !== 'integer' && + !ctype_digit($value)) { $value = PhabricatorTime::parseLocalTime($value, $this->getViewer()); } diff --git a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldPHIDs.php b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldPHIDs.php index a96ebefda1..48d5ea725a 100644 --- a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldPHIDs.php +++ b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldPHIDs.php @@ -40,7 +40,7 @@ abstract class PhabricatorStandardCustomFieldPHIDs // TODO: Clean this up. $result = array(); - if (!is_array($value)) { + if (!is_array($value) && phutil_nonempty_string($value)) { $value = json_decode($value, true); if (is_array($value)) { $result = array_values($value); diff --git a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldSelect.php b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldSelect.php index 5957afe56a..12e0aa6c3d 100644 --- a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldSelect.php +++ b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldSelect.php @@ -73,7 +73,7 @@ final class PhabricatorStandardCustomFieldSelect } public function renderPropertyViewValue(array $handles) { - if (!strlen($this->getFieldValue())) { + if (!phutil_nonempty_string($this->getFieldValue())) { return null; } return idx($this->getOptions(), $this->getFieldValue()); diff --git a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldText.php b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldText.php index 56164bb7b5..758c50e817 100644 --- a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldText.php +++ b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldText.php @@ -11,7 +11,7 @@ final class PhabricatorStandardCustomFieldText $indexes = array(); $value = $this->getFieldValue(); - if (strlen($value)) { + if (phutil_nonempty_string($value)) { $indexes[] = $this->newStringIndex($value); } @@ -30,7 +30,7 @@ final class PhabricatorStandardCustomFieldText PhabricatorCursorPagedPolicyAwareQuery $query, $value) { - if (strlen($value)) { + if (phutil_nonempty_string($value)) { $query->withApplicationSearchContainsConstraint( $this->newStringIndex(null), $value); diff --git a/src/infrastructure/events/PhabricatorAutoEventListener.php b/src/infrastructure/events/PhabricatorAutoEventListener.php index 0ed76b3390..a8419f6865 100644 --- a/src/infrastructure/events/PhabricatorAutoEventListener.php +++ b/src/infrastructure/events/PhabricatorAutoEventListener.php @@ -10,6 +10,6 @@ * * All concrete subclasses of this class are automatically registered at * startup. This allows it to be used with custom one-offs that can be dropped - * into `phabricator/src/extensions/`. + * into `phorge/src/extensions/`. */ abstract class PhabricatorAutoEventListener extends PhabricatorEventListener {} diff --git a/src/infrastructure/markup/blockrule/PhutilRemarkupInterpreterBlockRule.php b/src/infrastructure/markup/blockrule/PhutilRemarkupInterpreterBlockRule.php index a54e6b8b13..5585ddf541 100644 --- a/src/infrastructure/markup/blockrule/PhutilRemarkupInterpreterBlockRule.php +++ b/src/infrastructure/markup/blockrule/PhutilRemarkupInterpreterBlockRule.php @@ -2,13 +2,35 @@ final class PhutilRemarkupInterpreterBlockRule extends PhutilRemarkupBlockRule { - const START_BLOCK_PATTERN = '/^([\w]+)\s*(?:\(([^)]+)\)\s*)?{{{/'; + /** + * Second part of the regex to find stuff like: + * interpreterName {{{ stuff }}} + * interpreterName (options) {{{ stuff }}} + * You have found the kernel of cowsay and figlet. + */ const END_BLOCK_PATTERN = '/}}}\s*$/'; + /** + * Constructs the first part of the regex to find stuff like: + * interpreterName {{{ stuff }}} + * interpreterName (options) {{{ stuff }}} + * The exact regex is constructed from the available interpreters. + * @return string First part of interpreters regex + */ + private function getStartBlockPattern() { + $interpreters = id(new PhutilClassMapQuery()) + ->setAncestorClass('PhutilRemarkupBlockInterpreter') + ->execute(); + $interpreters_regex = mpull($interpreters, 'getInterpreterName'); + $interpreters_regex = array_map('preg_quote', $interpreters_regex); + $interpreters_regex = implode('|', $interpreters_regex); + return "/^($interpreters_regex)\s*(?:\(([^)]+)\)\s*)?{{{/"; + } + public function getMatchingLineCount(array $lines, $cursor) { $num_lines = 0; - if (preg_match(self::START_BLOCK_PATTERN, $lines[$cursor])) { + if (preg_match(self::getStartBlockPattern(), $lines[$cursor])) { $num_lines++; while (isset($lines[$cursor])) { @@ -33,7 +55,7 @@ final class PhutilRemarkupInterpreterBlockRule extends PhutilRemarkupBlockRule { } $matches = null; - preg_match(self::START_BLOCK_PATTERN, head($lines), $matches); + preg_match(self::getStartBlockPattern(), head($lines), $matches); $argv = array(); if (isset($matches[2])) { @@ -49,7 +71,7 @@ final class PhutilRemarkupInterpreterBlockRule extends PhutilRemarkupBlockRule { } $lines[$first_key] = preg_replace( - self::START_BLOCK_PATTERN, + self::getStartBlockPattern(), '', $lines[$first_key]); $lines[$last_key] = preg_replace( diff --git a/src/infrastructure/markup/markuprule/PhutilRemarkupEvalRule.php b/src/infrastructure/markup/markuprule/PhutilRemarkupEvalRule.php index cb67041c62..a525924fff 100644 --- a/src/infrastructure/markup/markuprule/PhutilRemarkupEvalRule.php +++ b/src/infrastructure/markup/markuprule/PhutilRemarkupEvalRule.php @@ -68,11 +68,11 @@ final class PhutilRemarkupEvalRule extends PhutilRemarkupRule { 'platform' => array( 'server' => array( 'name' => PlatformSymbols::getPlatformServerName(), - 'path' => pht('phabricator/'), + 'path' => PlatformSymbols::getPlatformServerPath(), ), 'client' => array( 'name' => PlatformSymbols::getPlatformClientName(), - 'path' => pht('arcanist/'), + 'path' => PlatformSymbols::getPlatformClientPath(), ), ), ), diff --git a/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php b/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php index f68635860a..d29e1bcc07 100644 --- a/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php +++ b/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php @@ -50,7 +50,6 @@ final class PhabricatorBuiltinPatchList extends PhabricatorSQLPatchList { 'after' => array( /* First Patch */ ), ), 'db.calendar' => array(), - 'db.chatlog' => array(), 'db.conduit' => array(), 'db.countdown' => array(), 'db.daemon' => array(), diff --git a/src/view/page/PhabricatorStandardPageView.php b/src/view/page/PhabricatorStandardPageView.php index a81820de3c..005ede23a7 100644 --- a/src/view/page/PhabricatorStandardPageView.php +++ b/src/view/page/PhabricatorStandardPageView.php @@ -413,8 +413,9 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView $font_css = hsprintf( '', $monospaced); } diff --git a/src/view/phui/PHUIObjectItemView.php b/src/view/phui/PHUIObjectItemView.php index 600db9f3b7..527bd51b38 100644 --- a/src/view/phui/PHUIObjectItemView.php +++ b/src/view/phui/PHUIObjectItemView.php @@ -90,11 +90,7 @@ final class PHUIObjectItemView extends AphrontTagView { * @return self */ public function setHref($href) { - - // We have not a very clear idea about what this method should receive - // So, let's log alien stuff for some time - // https://we.phorge.it/T15316 - self::requireValidHref($href, 'href'); + PhutilURI::checkHrefType($href); $this->href = $href; return $this; @@ -161,11 +157,7 @@ final class PHUIObjectItemView extends AphrontTagView { * @return self */ public function setImageHref($image_href) { - - // We have not a very clear idea about what this method should receive - // So, let's log alien stuff for some time - // https://we.phorge.it/T15316 - self::requireValidHref($image_href, 'image_href'); + PhutilURI::checkHrefType($image_href); $this->imageHref = $image_href; return $this; @@ -929,30 +921,4 @@ final class PHUIObjectItemView extends AphrontTagView { return javelin_tag('span', $options, ''); } - - /** - * Receive a href attribute and check if it has expected values - * - * TODO: Feel free to remove after 2023, if no more new reports arrive. - * - * https://we.phorge.it/T15316 - * - * @param mixed $href Value to be checked - * @param string $variable_name Human reference - */ - private static function requireValidHref($href, $variable_name) { - - // We have not a very clear idea about what a "href" should be - if (is_object($href) && !($href instanceof PhutilURI)) { - - // We log stuff with a kind stack trace - phlog(new Exception(pht( - 'The variable %s received an unexpected type: %s. '. - 'Please share this stack trace as comment in Task %s', - $variable_name, - get_class($href), - 'https://we.phorge.it/T15316'))); - } - } - } diff --git a/src/view/phui/PHUISegmentBarView.php b/src/view/phui/PHUISegmentBarView.php index 632c5327eb..8daa41c203 100644 --- a/src/view/phui/PHUISegmentBarView.php +++ b/src/view/phui/PHUISegmentBarView.php @@ -30,7 +30,7 @@ final class PHUISegmentBarView extends AphrontTagView { require_celerity_resource('phui-segment-bar-view-css'); $label = $this->label; - if (strlen($label)) { + if ($label !== null) { $label = phutil_tag( 'div', array( diff --git a/src/view/phui/PHUITagView.php b/src/view/phui/PHUITagView.php index dc837c7156..c36fbab36b 100644 --- a/src/view/phui/PHUITagView.php +++ b/src/view/phui/PHUITagView.php @@ -103,20 +103,11 @@ final class PHUITagView extends AphrontTagView { /** * Set the href attribute * - * @param string|null $href + * @param string|PhutilURI|null $href * @return self */ public function setHref($href) { - - // We have not a very clear idea about what this method should receive - // We suspect that PhutilURI should be allowed... but let's log everything! - // https://we.phorge.it/T15316 - if (is_object($href)) { - phlog(sprintf( - 'Received unexpected type for href: %s. '. - 'Please paste this log as comment in https://we.phorge.it/T15316', - get_class($href))); - } + PhutilURI::checkHrefType($href); $this->href = $href; return $this; diff --git a/support/startup/PhabricatorStartup.php b/support/startup/PhabricatorStartup.php index 58031013ad..b4a4314ac0 100644 --- a/support/startup/PhabricatorStartup.php +++ b/support/startup/PhabricatorStartup.php @@ -210,7 +210,7 @@ final class PhabricatorStartup { if (!$ok) { self::didFatal( 'Unable to load the "Arcanist" library. Put "arcanist/" next to '. - '"phabricator/" on disk.'); + '"phorge/" on disk.'); } // Load Phabricator itself using the absolute path, so we never end up doing @@ -261,10 +261,11 @@ final class PhabricatorStartup { public static function setDebugTimeLimit($limit) { self::$debugTimeLimit = $limit; - static $initialized; + static $initialized = false; if (!$initialized) { declare(ticks=1); register_tick_function(array(__CLASS__, 'onDebugTick')); + $initialized = true; } } diff --git a/webroot/rsrc/css/application/base/main-menu-view.css b/webroot/rsrc/css/application/base/main-menu-view.css index 8c5000247a..6aace18b44 100644 --- a/webroot/rsrc/css/application/base/main-menu-view.css +++ b/webroot/rsrc/css/application/base/main-menu-view.css @@ -70,7 +70,8 @@ float: left; color: #fff; font-size: 18px; - margin: 9px 4px 9px 6px; + line-height: 22px; + margin: 11px 4px 11px 6px; padding-right: 8px; max-width: 175px; overflow: hidden; diff --git a/webroot/rsrc/css/application/chatlog/chatlog.css b/webroot/rsrc/css/application/chatlog/chatlog.css deleted file mode 100644 index b0cb05a0e8..0000000000 --- a/webroot/rsrc/css/application/chatlog/chatlog.css +++ /dev/null @@ -1,81 +0,0 @@ -/** - * @provides phabricator-chatlog-css - */ - -.device-phone .phabricator-chat-log-wrap { - padding: 0; -} - -.phabricator-chat-log-pager-bottom { - padding: 8px 4px 16px; - font-weight: bold; - float: right; -} - -.phabricator-chat-log-pager-bottom a { - padding: 2px 3px; -} - -.phabricator-chat-log-panel { - clear: both; -} - -.phabricator-chat-log { - width: 100%; -} - -.phabricator-chat-log td { - padding: 8px; - line-height: 18px; -} - -.phabricator-chat-log tr { - background: #fff; -} - -.phabricator-chat-log tr td.author { - background: {$greybackground}; -} - -.phabricator-chat-log tr.alternate { - border-top: 1px solid {$thinblueborder}; - border-bottom: 1px solid {$thinblueborder}; -} - -.phabricator-chat-log tr.alternate td.author { - background: {$lightgreybackground}; -} - -.phabricator-chat-log tr.highlight td { - background: {$lightyellow}; -} - -.phabricator-chat-log td.timestamp { - white-space: nowrap; - text-align: right; - width: 12em; -} - -.phabricator-chat-log td.message .timestamp { - color: {$bluetext}; - font-size: {$smallestfontsize}; - float: right; - margin-left: 5px; -} - -.phabricator-chat-log td.author { - white-space: nowrap; - text-align: right; - font-weight: bold; - width: 140px; - color: {$darkbluetext}; -} - -.device-phone .phabricator-chat-log td.author { - width: 80px; -} - -.phabricator-chat-log td.message { - white-space: pre-wrap; - word-break: break-word; -} diff --git a/webroot/rsrc/css/application/config/setup-issue.css b/webroot/rsrc/css/application/config/setup-issue.css index a80b02815c..4af5e9f417 100644 --- a/webroot/rsrc/css/application/config/setup-issue.css +++ b/webroot/rsrc/css/application/config/setup-issue.css @@ -122,6 +122,11 @@ padding: 12px 0; } +.setup-issue-config > pre > tt { + user-select: none; + margin-right: 0.5em; +} + .setup-issue-config + .setup-issue-config { padding-top: 0; } diff --git a/webroot/rsrc/css/application/conpherence/message-pane.css b/webroot/rsrc/css/application/conpherence/message-pane.css index 0dc33789f3..87be9c5897 100644 --- a/webroot/rsrc/css/application/conpherence/message-pane.css +++ b/webroot/rsrc/css/application/conpherence/message-pane.css @@ -9,7 +9,7 @@ position: fixed; left: 240px; right: 240px; - top: 106px; + top: 115px; bottom: 0px; min-width: 300px; width: auto; @@ -55,8 +55,8 @@ position: fixed; left: 240px; right: 240px; - top: 106px; - bottom: 142px; + top: 115px; + bottom: 88px; overflow-x: hidden; overflow-y: auto; -webkit-overflow-scrolling: touch; @@ -95,7 +95,7 @@ .conpherence-message-pane .phui-form-view { border-width: 0; - height: 130px; + height: 76px; padding: 0 20px 12px; position: fixed; bottom: 0; @@ -347,7 +347,7 @@ body .conpherence-message-pane .aphront-form-control { } .conpherence-message-pane .remarkup-assist-textarea { - height: 88px; + height: 34px; padding: 8px; box-sizing: border-box; -moz-box-sizing: border-box; @@ -360,7 +360,6 @@ body .conpherence-message-pane .aphront-form-control { margin: 0; padding: 7px 8px 6px 38px; width: 100%; - height: 34px; resize: none; border-color: {$greyborder}; border-top-left-radius: 3px; diff --git a/webroot/rsrc/css/application/differential/changeset-view.css b/webroot/rsrc/css/application/differential/changeset-view.css index 88bbcfa421..a127d14648 100644 --- a/webroot/rsrc/css/application/differential/changeset-view.css +++ b/webroot/rsrc/css/application/differential/changeset-view.css @@ -183,6 +183,7 @@ should always have a boring grey background. */ cursor: pointer; border-right: 1px solid {$thinblueborder}; overflow: hidden; + white-space: nowrap; } .differential-diff td + td.n { diff --git a/webroot/rsrc/css/application/ponder/ponder-view.css b/webroot/rsrc/css/application/ponder/ponder-view.css index 567d7ae99b..675bc205b7 100644 --- a/webroot/rsrc/css/application/ponder/ponder-view.css +++ b/webroot/rsrc/css/application/ponder/ponder-view.css @@ -77,7 +77,7 @@ } .ponder-answer-view .ponder-answer-content { - background-color: #fff; + background-color: {$page.content}; padding: 16px 16px 0 16px; } diff --git a/webroot/rsrc/css/core/core.css b/webroot/rsrc/css/core/core.css index ccb3d1697f..4a9d3b394b 100644 --- a/webroot/rsrc/css/core/core.css +++ b/webroot/rsrc/css/core/core.css @@ -84,7 +84,7 @@ h2 { } a { - -moz-outline-style: none; + outline-style: none; text-decoration: none; color: {$anchor}; cursor: pointer; diff --git a/webroot/rsrc/css/layout/phabricator-source-code-view.css b/webroot/rsrc/css/layout/phabricator-source-code-view.css index b16b158004..83cda98df4 100644 --- a/webroot/rsrc/css/layout/phabricator-source-code-view.css +++ b/webroot/rsrc/css/layout/phabricator-source-code-view.css @@ -16,7 +16,7 @@ white-space: pre-wrap; padding: 2px 8px 1px; width: 100%; - background: #ffffff; + background: {$diff.background}; } .phabricator-source-line { diff --git a/webroot/rsrc/css/phui/phui-hovercard.css b/webroot/rsrc/css/phui/phui-hovercard.css index ba8057d08d..43c6f66df9 100644 --- a/webroot/rsrc/css/phui/phui-hovercard.css +++ b/webroot/rsrc/css/phui/phui-hovercard.css @@ -113,7 +113,7 @@ } .hovercard-task-view .phui-oi-disabled.phui-workcard { - background-color: #fff; + background-color: {$page.content}; } .phui-hovercard-object-type { diff --git a/webroot/rsrc/css/phui/phui-icon-set-selector.css b/webroot/rsrc/css/phui/phui-icon-set-selector.css index c66c2a6e55..f3bc1b9685 100644 --- a/webroot/rsrc/css/phui/phui-icon-set-selector.css +++ b/webroot/rsrc/css/phui/phui-icon-set-selector.css @@ -3,8 +3,8 @@ */ button.icon-button { - background-color: #F7F7F9; - background-image: linear-gradient(to bottom, #ffffff, #f1f0f1); + background-image: linear-gradient(to bottom, + {$lightgreybackground}, {$greybackground}); border: 1px solid rgba({$alphablue},.2); color: {$darkgreytext}; position: relative; diff --git a/webroot/rsrc/externals/javelin/docs/javelin.book b/webroot/rsrc/externals/javelin/docs/javelin.book new file mode 100644 index 0000000000..7c2a0c2274 --- /dev/null +++ b/webroot/rsrc/externals/javelin/docs/javelin.book @@ -0,0 +1,16 @@ +{ + "name" : "javelin", + "title" : "Javelin Documentation", + "short" : "Javelin Docs", + "preface" : "Documentation for developers using Javelin.", + "uri.source": + "https://we.phorge.it/diffusion/P/browse/master/%f$%l", + "rules": { + "(\\.diviner$)": "DivinerArticleAtomizer" + }, + "groups": { + "concepts": { + "name": "Concepts" + } + } +}