1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-28 09:42:41 +01:00

(stable) Promote 2016 Week 23

This commit is contained in:
epriestley 2016-06-11 04:28:45 -07:00
commit 55693ec631
219 changed files with 4068 additions and 2295 deletions

View file

@ -7,10 +7,10 @@
*/
return array(
'names' => array(
'core.pkg.css' => '8aeacc63',
'core.pkg.js' => '3f15fa62',
'core.pkg.css' => '6913fe66',
'core.pkg.js' => '10275c16',
'darkconsole.pkg.js' => 'e7393ebb',
'differential.pkg.css' => 'a3a7e5df',
'differential.pkg.css' => 'b3eea3f5',
'differential.pkg.js' => '4b7d8f19',
'diffusion.pkg.css' => '91c5d3a6',
'diffusion.pkg.js' => '3a9a8bfa',
@ -32,7 +32,7 @@ return array(
'rsrc/css/aphront/typeahead.css' => 'd4f16145',
'rsrc/css/application/almanac/almanac.css' => 'dbb9b3af',
'rsrc/css/application/auth/auth.css' => '0877ed6e',
'rsrc/css/application/base/main-menu-view.css' => 'd00a795a',
'rsrc/css/application/base/main-menu-view.css' => 'b623169f',
'rsrc/css/application/base/notification-menu.css' => 'f31c0bde',
'rsrc/css/application/base/phabricator-application-launch-view.css' => '95351601',
'rsrc/css/application/base/phui-theme.css' => '027ba77e',
@ -57,7 +57,7 @@ return array(
'rsrc/css/application/dashboard/dashboard.css' => 'bc6f2127',
'rsrc/css/application/diff/inline-comment-summary.css' => '51efda3a',
'rsrc/css/application/differential/add-comment.css' => 'c47f8c40',
'rsrc/css/application/differential/changeset-view.css' => 'febd2372',
'rsrc/css/application/differential/changeset-view.css' => 'ccfbc869',
'rsrc/css/application/differential/core.css' => '5b7b8ff4',
'rsrc/css/application/differential/phui-inline-comment.css' => '5953c28e',
'rsrc/css/application/differential/revision-comment.css' => '14b8565a',
@ -82,11 +82,11 @@ return array(
'rsrc/css/application/paste/paste.css' => '1898e534',
'rsrc/css/application/people/people-profile.css' => '2473d929',
'rsrc/css/application/phame/phame.css' => '7448a969',
'rsrc/css/application/pholio/pholio-edit.css' => 'b15fec4a',
'rsrc/css/application/pholio/pholio-edit.css' => '07676f51',
'rsrc/css/application/pholio/pholio-inline-comments.css' => '8e545e49',
'rsrc/css/application/pholio/pholio.css' => 'ca89d380',
'rsrc/css/application/phortune/phortune-credit-card-form.css' => '8391eb02',
'rsrc/css/application/phortune/phortune.css' => '9149f103',
'rsrc/css/application/phortune/phortune.css' => '5b99dae0',
'rsrc/css/application/phrequent/phrequent.css' => 'ffc185ad',
'rsrc/css/application/phriction/phriction-document-css.css' => '4282e4ad',
'rsrc/css/application/policy/policy-edit.css' => '815c66f7',
@ -104,7 +104,7 @@ return array(
'rsrc/css/application/tokens/tokens.css' => '3d0f239e',
'rsrc/css/application/uiexample/example.css' => '528b19de',
'rsrc/css/core/core.css' => 'd0801452',
'rsrc/css/core/remarkup.css' => '787105d6',
'rsrc/css/core/remarkup.css' => '523d34bb',
'rsrc/css/core/syntax.css' => '9fc496d5',
'rsrc/css/core/z-index.css' => '5b6fcf3f',
'rsrc/css/diviner/diviner-shared.css' => 'aa3656aa',
@ -149,7 +149,7 @@ return array(
'rsrc/css/phui/phui-pager.css' => 'bea33d23',
'rsrc/css/phui/phui-pinboard-view.css' => '2495140e',
'rsrc/css/phui/phui-profile-menu.css' => 'c8557f33',
'rsrc/css/phui/phui-property-list-view.css' => '1d42ee7c',
'rsrc/css/phui/phui-property-list-view.css' => 'd4bbd0cb',
'rsrc/css/phui/phui-remarkup-preview.css' => '1a8f2591',
'rsrc/css/phui/phui-segment-bar-view.css' => '46342871',
'rsrc/css/phui/phui-spacing.css' => '042804d6',
@ -258,7 +258,7 @@ return array(
'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadCompositeSource.js' => '503e17fd',
'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadOnDemandSource.js' => '013ffff9',
'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadPreloadedSource.js' => '54f314a0',
'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadSource.js' => '1bc11c4a',
'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadSource.js' => 'b25d5444',
'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadStaticSource.js' => '6c0e62fa',
'rsrc/favicons/apple-touch-icon-120x120.png' => '43742962',
'rsrc/favicons/apple-touch-icon-152x152.png' => '669eaec3',
@ -414,7 +414,7 @@ return array(
'rsrc/js/application/owners/OwnersPathEditor.js' => 'aa1733d0',
'rsrc/js/application/owners/owners-path-editor.js' => '7a68dda3',
'rsrc/js/application/passphrase/passphrase-credential-control.js' => '3cb0b2fc',
'rsrc/js/application/pholio/behavior-pholio-mock-edit.js' => '246dc085',
'rsrc/js/application/pholio/behavior-pholio-mock-edit.js' => 'bee502c8',
'rsrc/js/application/pholio/behavior-pholio-mock-view.js' => 'fbe497e7',
'rsrc/js/application/phortune/behavior-stripe-payment-form.js' => '3f5d6dbf',
'rsrc/js/application/phortune/behavior-test-payment-form.js' => 'fc91ab6c',
@ -465,7 +465,7 @@ return array(
'rsrc/js/core/KeyboardShortcutManager.js' => 'c1700f6f',
'rsrc/js/core/MultirowRowManager.js' => 'b5d57730',
'rsrc/js/core/Notification.js' => 'ccf1cbf8',
'rsrc/js/core/Prefab.js' => 'e67df814',
'rsrc/js/core/Prefab.js' => 'cfd23f37',
'rsrc/js/core/ShapedRequest.js' => '7cbe244b',
'rsrc/js/core/TextAreaUtils.js' => '320810c8',
'rsrc/js/core/Title.js' => 'df5e11d2',
@ -507,6 +507,7 @@ return array(
'rsrc/js/core/behavior-search-typeahead.js' => '06c32383',
'rsrc/js/core/behavior-select-content.js' => 'bf5374ef',
'rsrc/js/core/behavior-select-on-click.js' => '4e3e79a6',
'rsrc/js/core/behavior-setup-check-https.js' => '491416b3',
'rsrc/js/core/behavior-time-typeahead.js' => '522431f7',
'rsrc/js/core/behavior-toggle-class.js' => '92b9ec77',
'rsrc/js/core/behavior-tokenizer.js' => 'b3a4b884',
@ -552,7 +553,7 @@ return array(
'conpherence-update-css' => 'faf6be09',
'conpherence-widget-pane-css' => '775eaaba',
'd3' => 'a11a5ff2',
'differential-changeset-view-css' => 'febd2372',
'differential-changeset-view-css' => 'ccfbc869',
'differential-core-view-css' => '5b7b8ff4',
'differential-inline-comment-editor' => '64a5550f',
'differential-revision-add-comment-css' => 'c47f8c40',
@ -665,7 +666,7 @@ return array(
'javelin-behavior-phabricator-transaction-comment-form' => 'b23b49e6',
'javelin-behavior-phabricator-transaction-list' => '13c739ea',
'javelin-behavior-phabricator-watch-anchor' => '9f36c42d',
'javelin-behavior-pholio-mock-edit' => '246dc085',
'javelin-behavior-pholio-mock-edit' => 'bee502c8',
'javelin-behavior-pholio-mock-view' => 'fbe497e7',
'javelin-behavior-phui-dropdown-menu' => '54733475',
'javelin-behavior-phui-file-upload' => 'b003d4fb',
@ -692,6 +693,7 @@ return array(
'javelin-behavior-search-reorder-queries' => 'e9581f08',
'javelin-behavior-select-content' => 'bf5374ef',
'javelin-behavior-select-on-click' => '4e3e79a6',
'javelin-behavior-setup-check-https' => '491416b3',
'javelin-behavior-slowvote-embed' => '887ad43f',
'javelin-behavior-stripe-payment-form' => '3f5d6dbf',
'javelin-behavior-test-payment-form' => 'fc91ab6c',
@ -732,7 +734,7 @@ return array(
'javelin-typeahead-normalizer' => 'e6e25838',
'javelin-typeahead-ondemand-source' => '013ffff9',
'javelin-typeahead-preloaded-source' => '54f314a0',
'javelin-typeahead-source' => '1bc11c4a',
'javelin-typeahead-source' => 'b25d5444',
'javelin-typeahead-static-source' => '6c0e62fa',
'javelin-uri' => 'c989ade3',
'javelin-util' => '93cc50d6',
@ -776,15 +778,15 @@ return array(
'phabricator-flag-css' => '5337623f',
'phabricator-keyboard-shortcut' => '1ae869f2',
'phabricator-keyboard-shortcut-manager' => 'c1700f6f',
'phabricator-main-menu-view' => 'd00a795a',
'phabricator-main-menu-view' => 'b623169f',
'phabricator-nav-view-css' => 'ac79a758',
'phabricator-notification' => 'ccf1cbf8',
'phabricator-notification-css' => '3f6c89c9',
'phabricator-notification-menu-css' => 'f31c0bde',
'phabricator-object-selector-css' => '85ee8ce6',
'phabricator-phtize' => 'd254d646',
'phabricator-prefab' => 'e67df814',
'phabricator-remarkup-css' => '787105d6',
'phabricator-prefab' => 'cfd23f37',
'phabricator-remarkup-css' => '523d34bb',
'phabricator-search-results-css' => '7dea472c',
'phabricator-shaped-request' => '7cbe244b',
'phabricator-side-menu-view-css' => 'dd849797',
@ -808,11 +810,11 @@ return array(
'phabricator-zindex-css' => '5b6fcf3f',
'phame-css' => '7448a969',
'pholio-css' => 'ca89d380',
'pholio-edit-css' => 'b15fec4a',
'pholio-edit-css' => '07676f51',
'pholio-inline-comments-css' => '8e545e49',
'phortune-credit-card-form' => '2290aeef',
'phortune-credit-card-form-css' => '8391eb02',
'phortune-css' => '9149f103',
'phortune-css' => '5b99dae0',
'phrequent-css' => 'ffc185ad',
'phriction-document-css' => '4282e4ad',
'phui-action-panel-css' => '91c7b835',
@ -851,7 +853,7 @@ return array(
'phui-pager-css' => 'bea33d23',
'phui-pinboard-view-css' => '2495140e',
'phui-profile-menu-css' => 'c8557f33',
'phui-property-list-view-css' => '1d42ee7c',
'phui-property-list-view-css' => 'd4bbd0cb',
'phui-remarkup-preview-css' => '1a8f2591',
'phui-segment-bar-view-css' => '46342871',
'phui-spacing-css' => '042804d6',
@ -1043,12 +1045,6 @@ return array(
'javelin-util',
'phabricator-keyboard-shortcut-manager',
),
'1bc11c4a' => array(
'javelin-install',
'javelin-util',
'javelin-dom',
'javelin-typeahead-normalizer',
),
'1bd28176' => array(
'javelin-install',
'javelin-dom',
@ -1090,16 +1086,6 @@ return array(
'javelin-workflow',
'javelin-util',
),
'246dc085' => array(
'javelin-behavior',
'javelin-stratcom',
'javelin-dom',
'javelin-workflow',
'javelin-quicksand',
'phabricator-phtize',
'phabricator-drag-and-drop-file-upload',
'phabricator-draggable-list',
),
'2926fff2' => array(
'javelin-behavior',
'javelin-dom',
@ -1214,6 +1200,11 @@ return array(
'phabricator-drag-and-drop-file-upload',
'phabricator-textareautils',
),
'491416b3' => array(
'javelin-behavior',
'javelin-uri',
'phabricator-notification',
),
'49b73b36' => array(
'javelin-behavior',
'javelin-dom',
@ -1779,6 +1770,12 @@ return array(
'javelin-request',
'phabricator-shaped-request',
),
'b25d5444' => array(
'javelin-install',
'javelin-util',
'javelin-dom',
'javelin-typeahead-normalizer',
),
'b2b4fbaf' => array(
'javelin-behavior',
'javelin-dom',
@ -1815,6 +1812,9 @@ return array(
'javelin-dom',
'javelin-util',
),
'b623169f' => array(
'phui-theme-css',
),
'b6993408' => array(
'javelin-behavior',
'javelin-stratcom',
@ -1858,6 +1858,16 @@ return array(
'javelin-util',
'javelin-request',
),
'bee502c8' => array(
'javelin-behavior',
'javelin-stratcom',
'javelin-dom',
'javelin-workflow',
'javelin-quicksand',
'phabricator-phtize',
'phabricator-drag-and-drop-file-upload',
'phabricator-draggable-list',
),
'bf5374ef' => array(
'javelin-behavior',
'javelin-stratcom',
@ -1913,14 +1923,26 @@ return array(
'javelin-util',
'phabricator-notification-css',
),
'ccfbc869' => array(
'phui-inline-comment-view-css',
),
'cf86d16a' => array(
'javelin-behavior',
'javelin-dom',
'javelin-workflow',
'phabricator-drag-and-drop-file-upload',
),
'd00a795a' => array(
'phui-theme-css',
'cfd23f37' => array(
'javelin-install',
'javelin-util',
'javelin-dom',
'javelin-typeahead',
'javelin-tokenizer',
'javelin-typeahead-preloaded-source',
'javelin-typeahead-ondemand-source',
'javelin-dom',
'javelin-stratcom',
'javelin-util',
),
'd0c516d5' => array(
'javelin-behavior',
@ -2067,18 +2089,6 @@ return array(
'javelin-workflow',
'javelin-magical-init',
),
'e67df814' => array(
'javelin-install',
'javelin-util',
'javelin-dom',
'javelin-typeahead',
'javelin-tokenizer',
'javelin-typeahead-preloaded-source',
'javelin-typeahead-ondemand-source',
'javelin-dom',
'javelin-stratcom',
'javelin-util',
),
'e6e25838' => array(
'javelin-install',
),
@ -2200,9 +2210,6 @@ return array(
'fea0eb47' => array(
'javelin-install',
),
'febd2372' => array(
'phui-inline-comment-view-css',
),
),
'packages' => array(
'core.pkg.css' => array(
@ -2340,6 +2347,7 @@ return array(
'javelin-behavior-durable-column',
'conpherence-thread-manager',
'javelin-behavior-detect-timezone',
'javelin-behavior-setup-check-https',
),
'darkconsole.pkg.js' => array(
'javelin-behavior-dark-console',

View file

@ -82,6 +82,7 @@ return array(
'javelin-behavior-durable-column',
'conpherence-thread-manager',
'javelin-behavior-detect-timezone',
'javelin-behavior-setup-check-https',
),
'core.pkg.css' => array(
'phabricator-core-css',

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_user.user
DROP COLUMN consoleEnabled;

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_user.user
DROP COLUMN consoleTab;

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_user.user
DROP COLUMN consoleVisible;

View file

@ -0,0 +1,47 @@
<?php
$table = new PhabricatorUserPreferences();
$conn_w = $table->establishConnection('w');
// Convert "Mail Format", "Re Prefix" and "Vary Subjects" mail settings to
// string constants to avoid weird stuff where we store "true" and "false" as
// strings in the database.
// Each of these keys will be converted to the first value if present and
// truthy, or the second value if present and falsey.
$remap = array(
'html-emails' => array('html', 'text'),
're-prefix' => array('re', 'none'),
'vary-subject' => array('vary', 'static'),
);
foreach (new LiskMigrationIterator($table) as $row) {
$dict = $row->getPreferences();
$should_update = false;
foreach ($remap as $key => $value) {
if (isset($dict[$key])) {
if ($dict[$key]) {
$dict[$key] = $value[0];
} else {
$dict[$key] = $value[1];
}
$should_update = true;
}
}
if (!$should_update) {
continue;
}
queryfx(
$conn_w,
'UPDATE %T SET preferences = %s WHERE id = %d',
$table->getTableName(),
phutil_json_encode($dict),
$row->getID());
}
$prefs_key = PhabricatorUserPreferencesCacheType::KEY_PREFERENCES;
PhabricatorUserCache::clearCacheForAllUsers($prefs_key);

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_user.user
DROP COLUMN profileImageCache;

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_user.user_preferences
CHANGE userPHID userPHID VARBINARY(64);

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_user.user_preferences
ADD builtinKey VARCHAR(32) COLLATE {$COLLATE_TEXT};

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_user.user_preferences
ADD UNIQUE KEY `key_builtin` (builtinKey);

View file

@ -5,6 +5,8 @@
// script, except it loads the Phabricator environment and adds some Phabricator
// specific flags.
declare(ticks = 1);
$root = dirname(dirname(dirname(__FILE__)));
require_once $root.'/scripts/__init_script__.php';

View file

@ -103,6 +103,9 @@ try {
'Invalid username ("%s"). There is no user with this username.',
$user_name));
}
id(new PhabricatorAuthSessionEngine())
->willServeRequestForUser($user);
} else if (strlen($device_name)) {
if (!$remote_address) {
throw new Exception(

View file

@ -312,7 +312,6 @@ phutil_register_library_map(array(
'ConpherenceRoomListController' => 'applications/conpherence/controller/ConpherenceRoomListController.php',
'ConpherenceRoomTestCase' => 'applications/conpherence/__tests__/ConpherenceRoomTestCase.php',
'ConpherenceSchemaSpec' => 'applications/conpherence/storage/ConpherenceSchemaSpec.php',
'ConpherenceSettings' => 'applications/conpherence/constants/ConpherenceSettings.php',
'ConpherenceTestCase' => 'applications/conpherence/__tests__/ConpherenceTestCase.php',
'ConpherenceThread' => 'applications/conpherence/storage/ConpherenceThread.php',
'ConpherenceThreadIndexEngineExtension' => 'applications/conpherence/engineextension/ConpherenceThreadIndexEngineExtension.php',
@ -542,6 +541,7 @@ phutil_register_library_map(array(
'DifferentialRevisionRequiredActionResultBucket' => 'applications/differential/query/DifferentialRevisionRequiredActionResultBucket.php',
'DifferentialRevisionResultBucket' => 'applications/differential/query/DifferentialRevisionResultBucket.php',
'DifferentialRevisionReviewersHeraldField' => 'applications/differential/herald/DifferentialRevisionReviewersHeraldField.php',
'DifferentialRevisionSearchConduitAPIMethod' => 'applications/differential/conduit/DifferentialRevisionSearchConduitAPIMethod.php',
'DifferentialRevisionSearchEngine' => 'applications/differential/query/DifferentialRevisionSearchEngine.php',
'DifferentialRevisionStatus' => 'applications/differential/constants/DifferentialRevisionStatus.php',
'DifferentialRevisionSummaryHeraldField' => 'applications/differential/herald/DifferentialRevisionSummaryHeraldField.php',
@ -2145,6 +2145,8 @@ phutil_register_library_map(array(
'PhabricatorConfigVersionsModule' => 'applications/config/module/PhabricatorConfigVersionsModule.php',
'PhabricatorConfigWelcomeController' => 'applications/config/controller/PhabricatorConfigWelcomeController.php',
'PhabricatorConpherenceApplication' => 'applications/conpherence/application/PhabricatorConpherenceApplication.php',
'PhabricatorConpherenceColumnVisibleSetting' => 'applications/settings/setting/PhabricatorConpherenceColumnVisibleSetting.php',
'PhabricatorConpherenceNotificationsSetting' => 'applications/settings/setting/PhabricatorConpherenceNotificationsSetting.php',
'PhabricatorConpherencePreferencesSettingsPanel' => 'applications/settings/panel/PhabricatorConpherencePreferencesSettingsPanel.php',
'PhabricatorConpherenceThreadPHIDType' => 'applications/conpherence/phid/PhabricatorConpherenceThreadPHIDType.php',
'PhabricatorConsoleApplication' => 'applications/console/application/PhabricatorConsoleApplication.php',
@ -2240,6 +2242,8 @@ phutil_register_library_map(array(
'PhabricatorDaemonsSetupCheck' => 'applications/config/check/PhabricatorDaemonsSetupCheck.php',
'PhabricatorDailyRoutineTriggerClock' => 'infrastructure/daemon/workers/clock/PhabricatorDailyRoutineTriggerClock.php',
'PhabricatorDarkConsoleSetting' => 'applications/settings/setting/PhabricatorDarkConsoleSetting.php',
'PhabricatorDarkConsoleTabSetting' => 'applications/settings/setting/PhabricatorDarkConsoleTabSetting.php',
'PhabricatorDarkConsoleVisibleSetting' => 'applications/settings/setting/PhabricatorDarkConsoleVisibleSetting.php',
'PhabricatorDashboard' => 'applications/dashboard/storage/PhabricatorDashboard.php',
'PhabricatorDashboardAddPanelController' => 'applications/dashboard/controller/PhabricatorDashboardAddPanelController.php',
'PhabricatorDashboardApplication' => 'applications/dashboard/application/PhabricatorDashboardApplication.php',
@ -2302,6 +2306,7 @@ phutil_register_library_map(array(
'PhabricatorDebugController' => 'applications/system/controller/PhabricatorDebugController.php',
'PhabricatorDefaultRequestExceptionHandler' => 'aphront/handler/PhabricatorDefaultRequestExceptionHandler.php',
'PhabricatorDefaultSyntaxStyle' => 'infrastructure/syntax/PhabricatorDefaultSyntaxStyle.php',
'PhabricatorDesktopNotificationsSetting' => 'applications/settings/setting/PhabricatorDesktopNotificationsSetting.php',
'PhabricatorDesktopNotificationsSettingsPanel' => 'applications/settings/panel/PhabricatorDesktopNotificationsSettingsPanel.php',
'PhabricatorDestructibleInterface' => 'applications/system/interface/PhabricatorDestructibleInterface.php',
'PhabricatorDestructionEngine' => 'applications/system/engine/PhabricatorDestructionEngine.php',
@ -2319,6 +2324,8 @@ phutil_register_library_map(array(
'PhabricatorDifferentialManagementWorkflow' => 'applications/differential/management/PhabricatorDifferentialManagementWorkflow.php',
'PhabricatorDifferentialRevisionTestDataGenerator' => 'applications/differential/lipsum/PhabricatorDifferentialRevisionTestDataGenerator.php',
'PhabricatorDiffusionApplication' => 'applications/diffusion/application/PhabricatorDiffusionApplication.php',
'PhabricatorDiffusionBlameSetting' => 'applications/settings/setting/PhabricatorDiffusionBlameSetting.php',
'PhabricatorDiffusionColorSetting' => 'applications/settings/setting/PhabricatorDiffusionColorSetting.php',
'PhabricatorDiffusionConfigOptions' => 'applications/diffusion/config/PhabricatorDiffusionConfigOptions.php',
'PhabricatorDisabledUserController' => 'applications/auth/controller/PhabricatorDisabledUserController.php',
'PhabricatorDisplayPreferencesSettingsPanel' => 'applications/settings/panel/PhabricatorDisplayPreferencesSettingsPanel.php',
@ -2364,6 +2371,7 @@ phutil_register_library_map(array(
'PhabricatorEditEngineConfigurationTransactionQuery' => 'applications/transactions/query/PhabricatorEditEngineConfigurationTransactionQuery.php',
'PhabricatorEditEngineConfigurationViewController' => 'applications/transactions/controller/PhabricatorEditEngineConfigurationViewController.php',
'PhabricatorEditEngineController' => 'applications/transactions/controller/PhabricatorEditEngineController.php',
'PhabricatorEditEngineCreateQuickActions' => 'applications/settings/quickmenu/PhabricatorEditEngineCreateQuickActions.php',
'PhabricatorEditEngineExtension' => 'applications/transactions/engineextension/PhabricatorEditEngineExtension.php',
'PhabricatorEditEngineExtensionModule' => 'applications/transactions/engineextension/PhabricatorEditEngineExtensionModule.php',
'PhabricatorEditEngineListController' => 'applications/transactions/controller/PhabricatorEditEngineListController.php',
@ -2371,6 +2379,7 @@ phutil_register_library_map(array(
'PhabricatorEditEngineQuery' => 'applications/transactions/query/PhabricatorEditEngineQuery.php',
'PhabricatorEditEngineSearchEngine' => 'applications/transactions/query/PhabricatorEditEngineSearchEngine.php',
'PhabricatorEditEngineSelectCommentAction' => 'applications/transactions/commentaction/PhabricatorEditEngineSelectCommentAction.php',
'PhabricatorEditEngineSettingsPanel' => 'applications/settings/panel/PhabricatorEditEngineSettingsPanel.php',
'PhabricatorEditEngineTokenizerCommentAction' => 'applications/transactions/commentaction/PhabricatorEditEngineTokenizerCommentAction.php',
'PhabricatorEditField' => 'applications/transactions/editfield/PhabricatorEditField.php',
'PhabricatorEditPage' => 'applications/transactions/editengine/PhabricatorEditPage.php',
@ -2382,6 +2391,7 @@ phutil_register_library_map(array(
'PhabricatorElasticSearchSetupCheck' => 'applications/config/check/PhabricatorElasticSearchSetupCheck.php',
'PhabricatorEmailAddressesSettingsPanel' => 'applications/settings/panel/PhabricatorEmailAddressesSettingsPanel.php',
'PhabricatorEmailContentSource' => 'applications/metamta/contentsource/PhabricatorEmailContentSource.php',
'PhabricatorEmailDeliverySettingsPanel' => 'applications/settings/panel/PhabricatorEmailDeliverySettingsPanel.php',
'PhabricatorEmailFormatSetting' => 'applications/settings/setting/PhabricatorEmailFormatSetting.php',
'PhabricatorEmailFormatSettingsPanel' => 'applications/settings/panel/PhabricatorEmailFormatSettingsPanel.php',
'PhabricatorEmailLoginController' => 'applications/auth/controller/PhabricatorEmailLoginController.php',
@ -2389,6 +2399,7 @@ phutil_register_library_map(array(
'PhabricatorEmailPreferencesSettingsPanel' => 'applications/settings/panel/PhabricatorEmailPreferencesSettingsPanel.php',
'PhabricatorEmailRePrefixSetting' => 'applications/settings/setting/PhabricatorEmailRePrefixSetting.php',
'PhabricatorEmailSelfActionsSetting' => 'applications/settings/setting/PhabricatorEmailSelfActionsSetting.php',
'PhabricatorEmailTagsSetting' => 'applications/settings/setting/PhabricatorEmailTagsSetting.php',
'PhabricatorEmailVarySubjectsSetting' => 'applications/settings/setting/PhabricatorEmailVarySubjectsSetting.php',
'PhabricatorEmailVerificationController' => 'applications/auth/controller/PhabricatorEmailVerificationController.php',
'PhabricatorEmbedFileRemarkupRule' => 'applications/files/markup/PhabricatorEmbedFileRemarkupRule.php',
@ -2510,6 +2521,7 @@ phutil_register_library_map(array(
'PhabricatorFilesManagementWorkflow' => 'applications/files/management/PhabricatorFilesManagementWorkflow.php',
'PhabricatorFilesOnDiskBuiltinFile' => 'applications/files/builtin/PhabricatorFilesOnDiskBuiltinFile.php',
'PhabricatorFilesOutboundRequestAction' => 'applications/files/action/PhabricatorFilesOutboundRequestAction.php',
'PhabricatorFiletreeVisibleSetting' => 'applications/settings/setting/PhabricatorFiletreeVisibleSetting.php',
'PhabricatorFlag' => 'applications/flag/storage/PhabricatorFlag.php',
'PhabricatorFlagAddFlagHeraldAction' => 'applications/flag/herald/PhabricatorFlagAddFlagHeraldAction.php',
'PhabricatorFlagColor' => 'applications/flag/constants/PhabricatorFlagColor.php',
@ -2593,6 +2605,7 @@ phutil_register_library_map(array(
'PhabricatorInlineCommentPreviewController' => 'infrastructure/diff/PhabricatorInlineCommentPreviewController.php',
'PhabricatorInlineSummaryView' => 'infrastructure/diff/view/PhabricatorInlineSummaryView.php',
'PhabricatorInstructionsEditField' => 'applications/transactions/editfield/PhabricatorInstructionsEditField.php',
'PhabricatorInternalSetting' => 'applications/settings/setting/PhabricatorInternalSetting.php',
'PhabricatorInternationalizationManagementExtractWorkflow' => 'infrastructure/internationalization/management/PhabricatorInternationalizationManagementExtractWorkflow.php',
'PhabricatorInternationalizationManagementWorkflow' => 'infrastructure/internationalization/management/PhabricatorInternationalizationManagementWorkflow.php',
'PhabricatorInvalidConfigSetupCheck' => 'applications/config/check/PhabricatorInvalidConfigSetupCheck.php',
@ -3004,6 +3017,7 @@ phutil_register_library_map(array(
'PhabricatorPhurlURLTransactionComment' => 'applications/phurl/storage/PhabricatorPhurlURLTransactionComment.php',
'PhabricatorPhurlURLTransactionQuery' => 'applications/phurl/query/PhabricatorPhurlURLTransactionQuery.php',
'PhabricatorPhurlURLViewController' => 'applications/phurl/controller/PhabricatorPhurlURLViewController.php',
'PhabricatorPinnedApplicationsSetting' => 'applications/settings/setting/PhabricatorPinnedApplicationsSetting.php',
'PhabricatorPirateEnglishTranslation' => 'infrastructure/internationalization/translation/PhabricatorPirateEnglishTranslation.php',
'PhabricatorPlatformSite' => 'aphront/site/PhabricatorPlatformSite.php',
'PhabricatorPointsEditField' => 'applications/transactions/editfield/PhabricatorPointsEditField.php',
@ -3027,6 +3041,7 @@ phutil_register_library_map(array(
'PhabricatorPolicyEditField' => 'applications/transactions/editfield/PhabricatorPolicyEditField.php',
'PhabricatorPolicyException' => 'applications/policy/exception/PhabricatorPolicyException.php',
'PhabricatorPolicyExplainController' => 'applications/policy/controller/PhabricatorPolicyExplainController.php',
'PhabricatorPolicyFavoritesSetting' => 'applications/settings/setting/PhabricatorPolicyFavoritesSetting.php',
'PhabricatorPolicyFilter' => 'applications/policy/filter/PhabricatorPolicyFilter.php',
'PhabricatorPolicyInterface' => 'applications/policy/interface/PhabricatorPolicyInterface.php',
'PhabricatorPolicyManagementShowWorkflow' => 'applications/policy/management/PhabricatorPolicyManagementShowWorkflow.php',
@ -3041,6 +3056,7 @@ phutil_register_library_map(array(
'PhabricatorPolicyTestObject' => 'applications/policy/__tests__/PhabricatorPolicyTestObject.php',
'PhabricatorPolicyType' => 'applications/policy/constants/PhabricatorPolicyType.php',
'PhabricatorPonderApplication' => 'applications/ponder/application/PhabricatorPonderApplication.php',
'PhabricatorProfileMenuCollapsedSetting' => 'applications/settings/setting/PhabricatorProfileMenuCollapsedSetting.php',
'PhabricatorProfilePanel' => 'applications/search/profilepanel/PhabricatorProfilePanel.php',
'PhabricatorProfilePanelConfiguration' => 'applications/search/storage/PhabricatorProfilePanelConfiguration.php',
'PhabricatorProfilePanelConfigurationQuery' => 'applications/search/query/PhabricatorProfilePanelConfigurationQuery.php',
@ -3177,6 +3193,7 @@ phutil_register_library_map(array(
'PhabricatorQueryOrderItem' => 'infrastructure/query/order/PhabricatorQueryOrderItem.php',
'PhabricatorQueryOrderTestCase' => 'infrastructure/query/order/__tests__/PhabricatorQueryOrderTestCase.php',
'PhabricatorQueryOrderVector' => 'infrastructure/query/order/PhabricatorQueryOrderVector.php',
'PhabricatorQuickActions' => 'applications/settings/quickmenu/PhabricatorQuickActions.php',
'PhabricatorRateLimitRequestExceptionHandler' => 'aphront/handler/PhabricatorRateLimitRequestExceptionHandler.php',
'PhabricatorRecaptchaConfigOptions' => 'applications/config/option/PhabricatorRecaptchaConfigOptions.php',
'PhabricatorRecipientHasBadgeEdgeType' => 'applications/badges/edge/PhabricatorRecipientHasBadgeEdgeType.php',
@ -3352,6 +3369,7 @@ phutil_register_library_map(array(
'PhabricatorSearchResultBucketGroup' => 'applications/search/buckets/PhabricatorSearchResultBucketGroup.php',
'PhabricatorSearchResultView' => 'applications/search/view/PhabricatorSearchResultView.php',
'PhabricatorSearchSchemaSpec' => 'applications/search/storage/PhabricatorSearchSchemaSpec.php',
'PhabricatorSearchScopeSetting' => 'applications/settings/setting/PhabricatorSearchScopeSetting.php',
'PhabricatorSearchSelectController' => 'applications/search/controller/PhabricatorSearchSelectController.php',
'PhabricatorSearchSelectField' => 'applications/search/field/PhabricatorSearchSelectField.php',
'PhabricatorSearchStringListField' => 'applications/search/field/PhabricatorSearchStringListField.php',
@ -3367,14 +3385,21 @@ phutil_register_library_map(array(
'PhabricatorSendGridConfigOptions' => 'applications/config/option/PhabricatorSendGridConfigOptions.php',
'PhabricatorSessionsSettingsPanel' => 'applications/settings/panel/PhabricatorSessionsSettingsPanel.php',
'PhabricatorSetting' => 'applications/settings/setting/PhabricatorSetting.php',
'PhabricatorSettingsAccountPanelGroup' => 'applications/settings/panelgroup/PhabricatorSettingsAccountPanelGroup.php',
'PhabricatorSettingsAddEmailAction' => 'applications/settings/action/PhabricatorSettingsAddEmailAction.php',
'PhabricatorSettingsAdjustController' => 'applications/settings/controller/PhabricatorSettingsAdjustController.php',
'PhabricatorSettingsApplication' => 'applications/settings/application/PhabricatorSettingsApplication.php',
'PhabricatorSettingsEditController' => 'applications/settings/controller/PhabricatorSettingsEditController.php',
'PhabricatorSettingsApplicationsPanelGroup' => 'applications/settings/panelgroup/PhabricatorSettingsApplicationsPanelGroup.php',
'PhabricatorSettingsAuthenticationPanelGroup' => 'applications/settings/panelgroup/PhabricatorSettingsAuthenticationPanelGroup.php',
'PhabricatorSettingsDeveloperPanelGroup' => 'applications/settings/panelgroup/PhabricatorSettingsDeveloperPanelGroup.php',
'PhabricatorSettingsEditEngine' => 'applications/settings/editor/PhabricatorSettingsEditEngine.php',
'PhabricatorSettingsEmailPanelGroup' => 'applications/settings/panelgroup/PhabricatorSettingsEmailPanelGroup.php',
'PhabricatorSettingsListController' => 'applications/settings/controller/PhabricatorSettingsListController.php',
'PhabricatorSettingsLogsPanelGroup' => 'applications/settings/panelgroup/PhabricatorSettingsLogsPanelGroup.php',
'PhabricatorSettingsMainController' => 'applications/settings/controller/PhabricatorSettingsMainController.php',
'PhabricatorSettingsMainMenuBarExtension' => 'applications/settings/extension/PhabricatorSettingsMainMenuBarExtension.php',
'PhabricatorSettingsPanel' => 'applications/settings/panel/PhabricatorSettingsPanel.php',
'PhabricatorSettingsPanelGroup' => 'applications/settings/panelgroup/PhabricatorSettingsPanelGroup.php',
'PhabricatorSettingsTimezoneController' => 'applications/settings/controller/PhabricatorSettingsTimezoneController.php',
'PhabricatorSetupCheck' => 'applications/config/check/PhabricatorSetupCheck.php',
'PhabricatorSetupCheckTestCase' => 'applications/config/check/__tests__/PhabricatorSetupCheckTestCase.php',
@ -3537,6 +3562,7 @@ phutil_register_library_map(array(
'PhabricatorTimeFormatSetting' => 'applications/settings/setting/PhabricatorTimeFormatSetting.php',
'PhabricatorTimeGuard' => 'infrastructure/time/PhabricatorTimeGuard.php',
'PhabricatorTimeTestCase' => 'infrastructure/time/__tests__/PhabricatorTimeTestCase.php',
'PhabricatorTimezoneIgnoreOffsetSetting' => 'applications/settings/setting/PhabricatorTimezoneIgnoreOffsetSetting.php',
'PhabricatorTimezoneSetting' => 'applications/settings/setting/PhabricatorTimezoneSetting.php',
'PhabricatorTimezoneSetupCheck' => 'applications/config/check/PhabricatorTimezoneSetupCheck.php',
'PhabricatorTitleGlyphsSetting' => 'applications/settings/setting/PhabricatorTitleGlyphsSetting.php',
@ -3618,15 +3644,20 @@ phutil_register_library_map(array(
'PhabricatorUserIconField' => 'applications/people/customfield/PhabricatorUserIconField.php',
'PhabricatorUserLog' => 'applications/people/storage/PhabricatorUserLog.php',
'PhabricatorUserLogView' => 'applications/people/view/PhabricatorUserLogView.php',
'PhabricatorUserMessageCountCacheType' => 'applications/people/cache/PhabricatorUserMessageCountCacheType.php',
'PhabricatorUserNotificationCountCacheType' => 'applications/people/cache/PhabricatorUserNotificationCountCacheType.php',
'PhabricatorUserPHIDResolver' => 'applications/phid/resolver/PhabricatorUserPHIDResolver.php',
'PhabricatorUserPreferences' => 'applications/settings/storage/PhabricatorUserPreferences.php',
'PhabricatorUserPreferencesCacheType' => 'applications/people/cache/PhabricatorUserPreferencesCacheType.php',
'PhabricatorUserPreferencesEditor' => 'applications/settings/editor/PhabricatorUserPreferencesEditor.php',
'PhabricatorUserPreferencesPHIDType' => 'applications/settings/phid/PhabricatorUserPreferencesPHIDType.php',
'PhabricatorUserPreferencesQuery' => 'applications/settings/query/PhabricatorUserPreferencesQuery.php',
'PhabricatorUserPreferencesSearchEngine' => 'applications/settings/query/PhabricatorUserPreferencesSearchEngine.php',
'PhabricatorUserPreferencesTransaction' => 'applications/settings/storage/PhabricatorUserPreferencesTransaction.php',
'PhabricatorUserPreferencesTransactionQuery' => 'applications/settings/query/PhabricatorUserPreferencesTransactionQuery.php',
'PhabricatorUserProfile' => 'applications/people/storage/PhabricatorUserProfile.php',
'PhabricatorUserProfileEditor' => 'applications/people/editor/PhabricatorUserProfileEditor.php',
'PhabricatorUserProfileImageCacheType' => 'applications/people/cache/PhabricatorUserProfileImageCacheType.php',
'PhabricatorUserRealNameField' => 'applications/people/customfield/PhabricatorUserRealNameField.php',
'PhabricatorUserRolesField' => 'applications/people/customfield/PhabricatorUserRolesField.php',
'PhabricatorUserSchemaSpec' => 'applications/people/storage/PhabricatorUserSchemaSpec.php',
@ -4032,6 +4063,7 @@ phutil_register_library_map(array(
'PonderModerateCapability' => 'applications/ponder/capability/PonderModerateCapability.php',
'PonderQuestion' => 'applications/ponder/storage/PonderQuestion.php',
'PonderQuestionCommentController' => 'applications/ponder/controller/PonderQuestionCommentController.php',
'PonderQuestionCreateMailReceiver' => 'applications/ponder/mail/PonderQuestionCreateMailReceiver.php',
'PonderQuestionEditController' => 'applications/ponder/controller/PonderQuestionEditController.php',
'PonderQuestionEditor' => 'applications/ponder/editor/PonderQuestionEditor.php',
'PonderQuestionFulltextEngine' => 'applications/ponder/search/PonderQuestionFulltextEngine.php',
@ -4554,7 +4586,6 @@ phutil_register_library_map(array(
'ConpherenceRoomListController' => 'ConpherenceController',
'ConpherenceRoomTestCase' => 'ConpherenceTestCase',
'ConpherenceSchemaSpec' => 'PhabricatorConfigSchemaSpec',
'ConpherenceSettings' => 'ConpherenceConstants',
'ConpherenceTestCase' => 'PhabricatorTestCase',
'ConpherenceThread' => array(
'ConpherenceDAO',
@ -4790,6 +4821,7 @@ phutil_register_library_map(array(
'PhabricatorDestructibleInterface',
'PhabricatorProjectInterface',
'PhabricatorFulltextInterface',
'PhabricatorConduitResultInterface',
),
'DifferentialRevisionAffectedFilesHeraldField' => 'DifferentialRevisionHeraldField',
'DifferentialRevisionAuthorHeraldField' => 'DifferentialRevisionHeraldField',
@ -4823,6 +4855,7 @@ phutil_register_library_map(array(
'DifferentialRevisionRequiredActionResultBucket' => 'DifferentialRevisionResultBucket',
'DifferentialRevisionResultBucket' => 'PhabricatorSearchResultBucket',
'DifferentialRevisionReviewersHeraldField' => 'DifferentialRevisionHeraldField',
'DifferentialRevisionSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod',
'DifferentialRevisionSearchEngine' => 'PhabricatorApplicationSearchEngine',
'DifferentialRevisionStatus' => 'Phobject',
'DifferentialRevisionSummaryHeraldField' => 'DifferentialRevisionHeraldField',
@ -6163,7 +6196,7 @@ phutil_register_library_map(array(
'PhabricatorAccessLog' => 'Phobject',
'PhabricatorAccessLogConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorAccessibilitySetting' => 'PhabricatorSelectSetting',
'PhabricatorAccountSettingsPanel' => 'PhabricatorSettingsPanel',
'PhabricatorAccountSettingsPanel' => 'PhabricatorEditEngineSettingsPanel',
'PhabricatorActionListView' => 'AphrontView',
'PhabricatorActionView' => 'AphrontView',
'PhabricatorActivitySettingsPanel' => 'PhabricatorSettingsPanel',
@ -6676,7 +6709,9 @@ phutil_register_library_map(array(
'PhabricatorConfigVersionsModule' => 'PhabricatorConfigModule',
'PhabricatorConfigWelcomeController' => 'PhabricatorConfigController',
'PhabricatorConpherenceApplication' => 'PhabricatorApplication',
'PhabricatorConpherencePreferencesSettingsPanel' => 'PhabricatorSettingsPanel',
'PhabricatorConpherenceColumnVisibleSetting' => 'PhabricatorInternalSetting',
'PhabricatorConpherenceNotificationsSetting' => 'PhabricatorSelectSetting',
'PhabricatorConpherencePreferencesSettingsPanel' => 'PhabricatorEditEngineSettingsPanel',
'PhabricatorConpherenceThreadPHIDType' => 'PhabricatorPHIDType',
'PhabricatorConsoleApplication' => 'PhabricatorApplication',
'PhabricatorConsoleContentSource' => 'PhabricatorContentSource',
@ -6782,6 +6817,8 @@ phutil_register_library_map(array(
'PhabricatorDaemonsSetupCheck' => 'PhabricatorSetupCheck',
'PhabricatorDailyRoutineTriggerClock' => 'PhabricatorTriggerClock',
'PhabricatorDarkConsoleSetting' => 'PhabricatorSelectSetting',
'PhabricatorDarkConsoleTabSetting' => 'PhabricatorInternalSetting',
'PhabricatorDarkConsoleVisibleSetting' => 'PhabricatorInternalSetting',
'PhabricatorDashboard' => array(
'PhabricatorDashboardDAO',
'PhabricatorApplicationTransactionInterface',
@ -6858,18 +6895,19 @@ phutil_register_library_map(array(
'PhabricatorDatasourceEditField' => 'PhabricatorTokenizerEditField',
'PhabricatorDatasourceEditType' => 'PhabricatorPHIDListEditType',
'PhabricatorDateFormatSetting' => 'PhabricatorSelectSetting',
'PhabricatorDateTimeSettingsPanel' => 'PhabricatorSettingsPanel',
'PhabricatorDateTimeSettingsPanel' => 'PhabricatorEditEngineSettingsPanel',
'PhabricatorDebugController' => 'PhabricatorController',
'PhabricatorDefaultRequestExceptionHandler' => 'PhabricatorRequestExceptionHandler',
'PhabricatorDefaultSyntaxStyle' => 'PhabricatorSyntaxStyle',
'PhabricatorDesktopNotificationsSetting' => 'PhabricatorInternalSetting',
'PhabricatorDesktopNotificationsSettingsPanel' => 'PhabricatorSettingsPanel',
'PhabricatorDestructionEngine' => 'Phobject',
'PhabricatorDestructionEngineExtension' => 'Phobject',
'PhabricatorDestructionEngineExtensionModule' => 'PhabricatorConfigModule',
'PhabricatorDeveloperConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorDeveloperPreferencesSettingsPanel' => 'PhabricatorSettingsPanel',
'PhabricatorDeveloperPreferencesSettingsPanel' => 'PhabricatorEditEngineSettingsPanel',
'PhabricatorDiffInlineCommentQuery' => 'PhabricatorApplicationTransactionCommentQuery',
'PhabricatorDiffPreferencesSettingsPanel' => 'PhabricatorSettingsPanel',
'PhabricatorDiffPreferencesSettingsPanel' => 'PhabricatorEditEngineSettingsPanel',
'PhabricatorDifferenceEngine' => 'Phobject',
'PhabricatorDifferentialApplication' => 'PhabricatorApplication',
'PhabricatorDifferentialAttachCommitWorkflow' => 'PhabricatorDifferentialManagementWorkflow',
@ -6878,9 +6916,11 @@ phutil_register_library_map(array(
'PhabricatorDifferentialManagementWorkflow' => 'PhabricatorManagementWorkflow',
'PhabricatorDifferentialRevisionTestDataGenerator' => 'PhabricatorTestDataGenerator',
'PhabricatorDiffusionApplication' => 'PhabricatorApplication',
'PhabricatorDiffusionBlameSetting' => 'PhabricatorInternalSetting',
'PhabricatorDiffusionColorSetting' => 'PhabricatorInternalSetting',
'PhabricatorDiffusionConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorDisabledUserController' => 'PhabricatorAuthController',
'PhabricatorDisplayPreferencesSettingsPanel' => 'PhabricatorSettingsPanel',
'PhabricatorDisplayPreferencesSettingsPanel' => 'PhabricatorEditEngineSettingsPanel',
'PhabricatorDisqusAuthProvider' => 'PhabricatorOAuth2AuthProvider',
'PhabricatorDividerProfilePanel' => 'PhabricatorProfilePanel',
'PhabricatorDivinerApplication' => 'PhabricatorApplication',
@ -6930,6 +6970,7 @@ phutil_register_library_map(array(
'PhabricatorEditEngineConfigurationTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhabricatorEditEngineConfigurationViewController' => 'PhabricatorEditEngineController',
'PhabricatorEditEngineController' => 'PhabricatorApplicationTransactionController',
'PhabricatorEditEngineCreateQuickActions' => 'PhabricatorQuickActions',
'PhabricatorEditEngineExtension' => 'Phobject',
'PhabricatorEditEngineExtensionModule' => 'PhabricatorConfigModule',
'PhabricatorEditEngineListController' => 'PhabricatorEditEngineController',
@ -6937,6 +6978,7 @@ phutil_register_library_map(array(
'PhabricatorEditEngineQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorEditEngineSearchEngine' => 'PhabricatorApplicationSearchEngine',
'PhabricatorEditEngineSelectCommentAction' => 'PhabricatorEditEngineCommentAction',
'PhabricatorEditEngineSettingsPanel' => 'PhabricatorSettingsPanel',
'PhabricatorEditEngineTokenizerCommentAction' => 'PhabricatorEditEngineCommentAction',
'PhabricatorEditField' => 'Phobject',
'PhabricatorEditPage' => 'Phobject',
@ -6948,13 +6990,15 @@ phutil_register_library_map(array(
'PhabricatorElasticSearchSetupCheck' => 'PhabricatorSetupCheck',
'PhabricatorEmailAddressesSettingsPanel' => 'PhabricatorSettingsPanel',
'PhabricatorEmailContentSource' => 'PhabricatorContentSource',
'PhabricatorEmailDeliverySettingsPanel' => 'PhabricatorEditEngineSettingsPanel',
'PhabricatorEmailFormatSetting' => 'PhabricatorSelectSetting',
'PhabricatorEmailFormatSettingsPanel' => 'PhabricatorSettingsPanel',
'PhabricatorEmailFormatSettingsPanel' => 'PhabricatorEditEngineSettingsPanel',
'PhabricatorEmailLoginController' => 'PhabricatorAuthController',
'PhabricatorEmailNotificationsSetting' => 'PhabricatorSelectSetting',
'PhabricatorEmailPreferencesSettingsPanel' => 'PhabricatorSettingsPanel',
'PhabricatorEmailRePrefixSetting' => 'PhabricatorSelectSetting',
'PhabricatorEmailSelfActionsSetting' => 'PhabricatorSelectSetting',
'PhabricatorEmailTagsSetting' => 'PhabricatorInternalSetting',
'PhabricatorEmailVarySubjectsSetting' => 'PhabricatorSelectSetting',
'PhabricatorEmailVerificationController' => 'PhabricatorAuthController',
'PhabricatorEmbedFileRemarkupRule' => 'PhabricatorObjectRemarkupRule',
@ -7104,6 +7148,7 @@ phutil_register_library_map(array(
'PhabricatorFilesManagementWorkflow' => 'PhabricatorManagementWorkflow',
'PhabricatorFilesOnDiskBuiltinFile' => 'PhabricatorFilesBuiltinFile',
'PhabricatorFilesOutboundRequestAction' => 'PhabricatorSystemAction',
'PhabricatorFiletreeVisibleSetting' => 'PhabricatorInternalSetting',
'PhabricatorFlag' => array(
'PhabricatorFlagDAO',
'PhabricatorPolicyInterface',
@ -7194,6 +7239,7 @@ phutil_register_library_map(array(
'PhabricatorInlineCommentPreviewController' => 'PhabricatorController',
'PhabricatorInlineSummaryView' => 'AphrontView',
'PhabricatorInstructionsEditField' => 'PhabricatorEditField',
'PhabricatorInternalSetting' => 'PhabricatorSetting',
'PhabricatorInternationalizationManagementExtractWorkflow' => 'PhabricatorInternationalizationManagementWorkflow',
'PhabricatorInternationalizationManagementWorkflow' => 'PhabricatorManagementWorkflow',
'PhabricatorInvalidConfigSetupCheck' => 'PhabricatorSetupCheck',
@ -7662,6 +7708,7 @@ phutil_register_library_map(array(
'PhabricatorPhurlURLTransactionComment' => 'PhabricatorApplicationTransactionComment',
'PhabricatorPhurlURLTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhabricatorPhurlURLViewController' => 'PhabricatorPhurlController',
'PhabricatorPinnedApplicationsSetting' => 'PhabricatorInternalSetting',
'PhabricatorPirateEnglishTranslation' => 'PhutilTranslation',
'PhabricatorPlatformSite' => 'PhabricatorSite',
'PhabricatorPointsEditField' => 'PhabricatorEditField',
@ -7689,6 +7736,7 @@ phutil_register_library_map(array(
'PhabricatorPolicyEditField' => 'PhabricatorEditField',
'PhabricatorPolicyException' => 'Exception',
'PhabricatorPolicyExplainController' => 'PhabricatorPolicyController',
'PhabricatorPolicyFavoritesSetting' => 'PhabricatorInternalSetting',
'PhabricatorPolicyFilter' => 'Phobject',
'PhabricatorPolicyInterface' => 'PhabricatorPHIDInterface',
'PhabricatorPolicyManagementShowWorkflow' => 'PhabricatorPolicyManagementWorkflow',
@ -7707,6 +7755,7 @@ phutil_register_library_map(array(
),
'PhabricatorPolicyType' => 'PhabricatorPolicyConstants',
'PhabricatorPonderApplication' => 'PhabricatorApplication',
'PhabricatorProfileMenuCollapsedSetting' => 'PhabricatorInternalSetting',
'PhabricatorProfilePanel' => 'Phobject',
'PhabricatorProfilePanelConfiguration' => array(
'PhabricatorSearchDAO',
@ -7876,6 +7925,7 @@ phutil_register_library_map(array(
'Phobject',
'Iterator',
),
'PhabricatorQuickActions' => 'Phobject',
'PhabricatorRateLimitRequestExceptionHandler' => 'PhabricatorRequestExceptionHandler',
'PhabricatorRecaptchaConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorRecipientHasBadgeEdgeType' => 'PhabricatorEdgeType',
@ -8101,6 +8151,7 @@ phutil_register_library_map(array(
'PhabricatorSearchResultBucketGroup' => 'Phobject',
'PhabricatorSearchResultView' => 'AphrontView',
'PhabricatorSearchSchemaSpec' => 'PhabricatorConfigSchemaSpec',
'PhabricatorSearchScopeSetting' => 'PhabricatorInternalSetting',
'PhabricatorSearchSelectController' => 'PhabricatorSearchBaseController',
'PhabricatorSearchSelectField' => 'PhabricatorSearchField',
'PhabricatorSearchStringListField' => 'PhabricatorSearchField',
@ -8116,14 +8167,21 @@ phutil_register_library_map(array(
'PhabricatorSendGridConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorSessionsSettingsPanel' => 'PhabricatorSettingsPanel',
'PhabricatorSetting' => 'Phobject',
'PhabricatorSettingsAccountPanelGroup' => 'PhabricatorSettingsPanelGroup',
'PhabricatorSettingsAddEmailAction' => 'PhabricatorSystemAction',
'PhabricatorSettingsAdjustController' => 'PhabricatorController',
'PhabricatorSettingsApplication' => 'PhabricatorApplication',
'PhabricatorSettingsEditController' => 'PhabricatorController',
'PhabricatorSettingsApplicationsPanelGroup' => 'PhabricatorSettingsPanelGroup',
'PhabricatorSettingsAuthenticationPanelGroup' => 'PhabricatorSettingsPanelGroup',
'PhabricatorSettingsDeveloperPanelGroup' => 'PhabricatorSettingsPanelGroup',
'PhabricatorSettingsEditEngine' => 'PhabricatorEditEngine',
'PhabricatorSettingsEmailPanelGroup' => 'PhabricatorSettingsPanelGroup',
'PhabricatorSettingsListController' => 'PhabricatorController',
'PhabricatorSettingsLogsPanelGroup' => 'PhabricatorSettingsPanelGroup',
'PhabricatorSettingsMainController' => 'PhabricatorController',
'PhabricatorSettingsMainMenuBarExtension' => 'PhabricatorMainMenuBarExtension',
'PhabricatorSettingsPanel' => 'Phobject',
'PhabricatorSettingsPanelGroup' => 'Phobject',
'PhabricatorSettingsTimezoneController' => 'PhabricatorController',
'PhabricatorSetupCheck' => 'Phobject',
'PhabricatorSetupCheckTestCase' => 'PhabricatorTestCase',
@ -8302,6 +8360,7 @@ phutil_register_library_map(array(
'PhabricatorTimeFormatSetting' => 'PhabricatorSelectSetting',
'PhabricatorTimeGuard' => 'Phobject',
'PhabricatorTimeTestCase' => 'PhabricatorTestCase',
'PhabricatorTimezoneIgnoreOffsetSetting' => 'PhabricatorInternalSetting',
'PhabricatorTimezoneSetting' => 'PhabricatorOptionGroupSetting',
'PhabricatorTimezoneSetupCheck' => 'PhabricatorSetupCheck',
'PhabricatorTitleGlyphsSetting' => 'PhabricatorSelectSetting',
@ -8405,6 +8464,8 @@ phutil_register_library_map(array(
'PhabricatorPolicyInterface',
),
'PhabricatorUserLogView' => 'AphrontView',
'PhabricatorUserMessageCountCacheType' => 'PhabricatorUserCacheType',
'PhabricatorUserNotificationCountCacheType' => 'PhabricatorUserCacheType',
'PhabricatorUserPHIDResolver' => 'PhabricatorPHIDResolver',
'PhabricatorUserPreferences' => array(
'PhabricatorUserDAO',
@ -8416,9 +8477,12 @@ phutil_register_library_map(array(
'PhabricatorUserPreferencesEditor' => 'PhabricatorApplicationTransactionEditor',
'PhabricatorUserPreferencesPHIDType' => 'PhabricatorPHIDType',
'PhabricatorUserPreferencesQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorUserPreferencesSearchEngine' => 'PhabricatorApplicationSearchEngine',
'PhabricatorUserPreferencesTransaction' => 'PhabricatorApplicationTransaction',
'PhabricatorUserPreferencesTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhabricatorUserProfile' => 'PhabricatorUserDAO',
'PhabricatorUserProfileEditor' => 'PhabricatorApplicationTransactionEditor',
'PhabricatorUserProfileImageCacheType' => 'PhabricatorUserCacheType',
'PhabricatorUserRealNameField' => 'PhabricatorUserCustomField',
'PhabricatorUserRolesField' => 'PhabricatorUserCustomField',
'PhabricatorUserSchemaSpec' => 'PhabricatorConfigSchemaSpec',
@ -8953,6 +9017,7 @@ phutil_register_library_map(array(
'PhabricatorFulltextInterface',
),
'PonderQuestionCommentController' => 'PonderController',
'PonderQuestionCreateMailReceiver' => 'PhabricatorMailReceiver',
'PonderQuestionEditController' => 'PonderController',
'PonderQuestionEditor' => 'PonderEditor',
'PonderQuestionFulltextEngine' => 'PhabricatorFulltextEngine',

View file

@ -64,8 +64,8 @@ final class AphrontAjaxResponse extends AphrontResponse {
if ($request) {
$viewer = $request->getViewer();
if ($viewer) {
$postprocessor_key = $viewer->getPreference(
PhabricatorUserPreferences::PREFERENCE_RESOURCE_POSTPROCESSOR);
$postprocessor_key = $viewer->getUserSetting(
PhabricatorAccessibilitySetting::SETTINGKEY);
if (strlen($postprocessor_key)) {
$response->setPostprocessorKey($postprocessor_key);
}

View file

@ -46,17 +46,15 @@ final class AphlictDropdownDataQuery extends Phobject {
$is_c_installed = PhabricatorApplication::isClassInstalledForViewer(
$conpherence_app,
$viewer);
if ($is_c_installed) {
$raw_message_count_number = $viewer->getUnreadMessageCount();
$message_count_number = $this->formatNumber($raw_message_count_number);
} else {
$raw_message_count_number = null;
$message_count_number = null;
if ($is_c_installed) {
$unread_status = ConpherenceParticipationStatus::BEHIND;
$unread = id(new ConpherenceParticipantCountQuery())
->withParticipantPHIDs(array($viewer->getPHID()))
->withParticipationStatus($unread_status)
->execute();
$raw_message_count_number = idx($unread, $viewer->getPHID(), 0);
$message_count_number = $this->formatNumber($raw_message_count_number);
}
$conpherence_data = array(
'isInstalled' => $is_c_installed,
'countType' => 'messages',
@ -69,15 +67,15 @@ final class AphlictDropdownDataQuery extends Phobject {
$is_n_installed = PhabricatorApplication::isClassInstalledForViewer(
$notification_app,
$viewer);
$notification_count_number = null;
$raw_notification_count_number = null;
if ($is_n_installed) {
$raw_notification_count_number =
id(new PhabricatorFeedStoryNotification())
->countUnread($viewer);
$raw_notification_count_number = $viewer->getUnreadNotificationCount();
$notification_count_number = $this->formatNumber(
$raw_notification_count_number);
} else {
$notification_count_number = null;
$raw_notification_count_number = null;
}
$notification_data = array(
'isInstalled' => $is_n_installed,
'countType' => 'notifications',

View file

@ -139,7 +139,10 @@ final class PhabricatorAuthOneTimeLoginController
->save();
unset($unguarded);
$next = (string)id(new PhutilURI('/settings/panel/password/'))
$username = $target_user->getUsername();
$panel_uri = "/settings/user/{$username}/page/password/";
$next = (string)id(new PhutilURI($panel_uri))
->setQueryParams(
array(
'key' => $key,

View file

@ -113,17 +113,9 @@ final class PhabricatorAuthStartController
PhabricatorCookies::setClientIDCookie($request);
}
if (!$request->getURIData('loggedout') && count($providers) == 1) {
$auto_login_provider = head($providers);
$auto_login_config = $auto_login_provider->getProviderConfig();
if ($auto_login_provider instanceof PhabricatorPhabricatorAuthProvider &&
$auto_login_config->getShouldAutoLogin()) {
$auto_login_adapter = $provider->getAdapter();
$auto_login_adapter->setState($provider->getAuthCSRFCode($request));
return id(new AphrontRedirectResponse())
->setIsExternal(true)
->setURI($provider->getAdapter()->getAuthenticateURI());
}
$auto_response = $this->tryAutoLogin($providers);
if ($auto_response) {
return $auto_response;
}
$invite = $this->loadInvite();
@ -282,4 +274,35 @@ final class PhabricatorAuthStartController
array($message));
}
private function tryAutoLogin(array $providers) {
$request = $this->getRequest();
// If the user just logged out, don't immediately log them in again.
if ($request->getURIData('loggedout')) {
return null;
}
// If we have more than one provider, we can't autologin because we
// don't know which one the user wants.
if (count($providers) != 1) {
return null;
}
$provider = head($providers);
if (!$provider->supportsAutoLogin()) {
return null;
}
$config = $provider->getProviderConfig();
if (!$config->getShouldAutoLogin()) {
return null;
}
$auto_uri = $provider->getAutoLoginURI($request);
return id(new AphrontRedirectResponse())
->setIsExternal(true)
->setURI($auto_uri);
}
}

View file

@ -3,10 +3,6 @@
final class PhabricatorMustVerifyEmailController
extends PhabricatorAuthController {
public function shouldRequireLogin() {
return false;
}
public function shouldRequireEmailVerification() {
// NOTE: We don't technically need this since PhabricatorController forces
// us here in either case, but it's more consistent with intent.

View file

@ -130,7 +130,7 @@ final class PhabricatorAuthEditController
PhabricatorAuthProviderConfigTransaction::TYPE_TRUST_EMAILS)
->setNewValue($request->getInt('trustEmails', 0));
if ($provider instanceof PhabricatorPhabricatorAuthProvider) {
if ($provider->supportsAutoLogin()) {
$xactions[] = id(new PhabricatorAuthProviderConfigTransaction())
->setTransactionType(
PhabricatorAuthProviderConfigTransaction::TYPE_AUTO_LOGIN)
@ -314,7 +314,7 @@ final class PhabricatorAuthEditController
$v_trust_email));
}
if ($provider instanceof PhabricatorPhabricatorAuthProvider) {
if ($provider->supportsAutoLogin()) {
$form->appendChild(
id(new AphrontFormCheckboxControl())
->addCheckbox(

View file

@ -113,7 +113,7 @@ final class PhabricatorAuthSessionEngine extends Phobject {
$session_key = PhabricatorHash::digest($session_token);
$cache_parts = $this->getUserCacheQueryParts($conn_r);
list($cache_selects, $cache_joins, $cache_map) = $cache_parts;
list($cache_selects, $cache_joins, $cache_map, $types_map) = $cache_parts;
$info = queryfx_one(
$conn_r,
@ -162,6 +162,7 @@ final class PhabricatorAuthSessionEngine extends Phobject {
$user = $user_table->loadFromArray($info);
$cache_raw = $this->filterRawCacheData($user, $types_map, $cache_raw);
$user->attachRawCacheData($cache_raw);
switch ($session_type) {
@ -760,11 +761,13 @@ final class PhabricatorAuthSessionEngine extends Phobject {
$cache_map = array();
$keys = array();
$types_map = array();
$cache_types = PhabricatorUserCacheType::getAllCacheTypes();
foreach ($cache_types as $cache_type) {
foreach ($cache_type->getAutoloadKeys() as $autoload_key) {
$keys[] = $autoload_key;
$types_map[$autoload_key] = $cache_type;
}
}
@ -808,7 +811,32 @@ final class PhabricatorAuthSessionEngine extends Phobject {
$cache_joins = '';
}
return array($cache_selects, $cache_joins, $cache_map);
return array($cache_selects, $cache_joins, $cache_map, $types_map);
}
private function filterRawCacheData(
PhabricatorUser $user,
array $types_map,
array $cache_raw) {
foreach ($cache_raw as $cache_key => $cache_data) {
$type = $types_map[$cache_key];
if ($type->shouldValidateRawCacheData()) {
if (!$type->isRawCacheDataValid($user, $cache_key, $cache_data)) {
unset($cache_raw[$cache_key]);
}
}
}
return $cache_raw;
}
public function willServeRequestForUser(PhabricatorUser $user) {
// We allow the login user to generate any missing cache data inline.
$user->setAllowInlineCacheGeneration(true);
// Switch to the user's translation.
PhabricatorEnv::setLocaleCode($user->getTranslation());
}
}

View file

@ -495,4 +495,12 @@ abstract class PhabricatorAuthProvider extends Phobject {
}
}
public function supportsAutoLogin() {
return false;
}
public function getAutoLoginURI(AphrontRequest $request) {
throw new PhutilMethodNotImplementedException();
}
}

View file

@ -273,4 +273,17 @@ abstract class PhabricatorOAuth2AuthProvider
parent::willRenderLinkedAccount($viewer, $item, $account);
}
public function supportsAutoLogin() {
return true;
}
public function getAutoLoginURI(AphrontRequest $request) {
$csrf_code = $this->getAuthCSRFCode($request);
$adapter = $this->getAdapter();
$adapter->setState($csrf_code);
return $adapter->getAuthenticateURI();
}
}

View file

@ -335,17 +335,6 @@ abstract class PhabricatorApplication
}
/**
* Build items for the "quick create" menu.
*
* @param PhabricatorUser The viewing user.
* @return list<PHUIListItemView> List of menu items.
*/
public function getQuickCreateItems(PhabricatorUser $viewer) {
return array();
}
/* -( Application Management )--------------------------------------------- */

View file

@ -104,7 +104,8 @@ abstract class PhabricatorController extends AphrontController {
$request->setUser($user);
}
PhabricatorEnv::setLocaleCode($user->getTranslation());
id(new PhabricatorAuthSessionEngine())
->willServeRequestForUser($user);
if (PhabricatorEnv::getEnvConfig('darkconsole.enabled')) {
$dark_console = PhabricatorDarkConsoleSetting::SETTINGKEY;

View file

@ -26,6 +26,10 @@ final class PhabricatorCacheManagementPurgeWorkflow
'name' => 'purge-general',
'help' => pht('Purge the general cache.'),
),
array(
'name' => 'purge-user',
'help' => pht('Purge the user cache.'),
),
));
}
@ -38,6 +42,7 @@ final class PhabricatorCacheManagementPurgeWorkflow
'remarkup' => $purge_all || $args->getArg('purge-remarkup'),
'changeset' => $purge_all || $args->getArg('purge-changeset'),
'general' => $purge_all || $args->getArg('purge-general'),
'user' => $purge_all || $args->getArg('purge-user'),
);
if (!array_filter($purge)) {
@ -72,6 +77,12 @@ final class PhabricatorCacheManagementPurgeWorkflow
$this->purgeGeneralCache();
$console->writeOut("%s\n", pht('Done.'));
}
if ($purge['user']) {
$console->writeOut(pht('Purging user cache...'));
$this->purgeUserCache();
$console->writeOut("%s\n", pht('Done.'));
}
}
private function purgeRemarkupCache() {
@ -100,4 +111,14 @@ final class PhabricatorCacheManagementPurgeWorkflow
'cache_general');
}
private function purgeUserCache() {
$table = new PhabricatorUserCache();
$conn_w = $table->establishConnection('w');
queryfx(
$conn_w,
'TRUNCATE TABLE %T',
$table->getTableName());
}
}

View file

@ -73,18 +73,6 @@ final class PhabricatorCalendarApplication extends PhabricatorApplication {
);
}
public function getQuickCreateItems(PhabricatorUser $viewer) {
$items = array();
$item = id(new PHUIListItemView())
->setName(pht('Calendar Event'))
->setIcon('fa-calendar')
->setHref($this->getBaseURI().'event/create/');
$items[] = $item;
return $items;
}
public function getMailCommandObjects() {
return array(
'event' => array(

View file

@ -487,6 +487,10 @@ final class PhabricatorConduitAPIController
}
$request->setUser($user);
id(new PhabricatorAuthSessionEngine())
->willServeRequestForUser($user);
return null;
}

View file

@ -3,7 +3,11 @@
final class PhabricatorConduitTokensSettingsPanel
extends PhabricatorSettingsPanel {
public function isEditableByAdministrators() {
public function isManagementPanel() {
if ($this->getUser()->getIsMailingList()) {
return false;
}
return true;
}
@ -15,15 +19,11 @@ final class PhabricatorConduitTokensSettingsPanel
return pht('Conduit API Tokens');
}
public function getPanelGroup() {
return pht('Sessions and Logs');
public function getPanelGroupKey() {
return PhabricatorSettingsLogsPanelGroup::PANELGROUPKEY;
}
public function isEnabled() {
if ($this->getUser()->getIsMailingList()) {
return false;
}
return true;
}

View file

@ -55,7 +55,7 @@ final class PhabricatorPHPMailerConfigOptions
$this->newOption('phpmailer.smtp-password', 'string', null)
->setHidden(true)
->setDescription(pht('Password for SMTP.')),
$this->newOption('phpmailer.smtp-encoding', 'string', '8bit')
$this->newOption('phpmailer.smtp-encoding', 'string', 'base64')
->setSummary(pht('Configure how mail is encoded.'))
->setDescription(
pht(
@ -64,14 +64,8 @@ final class PhabricatorPHPMailerConfigOptions
"encoding. If you're having trouble with mail being mangled or ".
"arriving with too many or too few newlines, you may try ".
"adjusting this setting.\n\n".
"Supported values are `8bit` (default), `quoted-printable`, ".
"`7bit`, `binary` and `base64`.\n\n".
"The settings in the table below may work well.\n\n".
"| MTA | Setting | Notes\n".
"|-----|---------|------\n".
"| SendGrid via SMTP | `quoted-printable` | Double newlines under ".
"`8bit`.\n".
"| All Other MTAs | `8bit` | Default setting.")),
"Supported values are `8bit`, `quoted-printable`, ".
"`7bit`, `binary` and `base64`.")),
);
}

View file

@ -48,19 +48,6 @@ final class PhabricatorConpherenceApplication extends PhabricatorApplication {
);
}
public function getQuickCreateItems(PhabricatorUser $viewer) {
$items = array();
$item = id(new PHUIListItemView())
->setName(pht('Conpherence Room'))
->setIcon('fa-comments')
->setWorkflow(true)
->setHref($this->getBaseURI().'new/');
$items[] = $item;
return $items;
}
public function getQuicksandURIPatternBlacklist() {
return array(
'/conpherence/.*',

View file

@ -1,22 +0,0 @@
<?php
final class ConpherenceSettings extends ConpherenceConstants {
const EMAIL_ALWAYS = 0;
const NOTIFICATIONS_ONLY = 1;
public static function getHumanString($constant) {
$string = pht('Unknown setting.');
switch ($constant) {
case self::EMAIL_ALWAYS:
$string = pht('Email me every update.');
break;
case self::NOTIFICATIONS_ONLY:
$string = pht('Notifications only.');
break;
}
return $string;
}
}

View file

@ -127,9 +127,14 @@ final class ConpherenceUpdateController
}
$participant->setSettings(array('notifications' => $notifications));
$participant->save();
$label = PhabricatorConpherenceNotificationsSetting::getSettingLabel(
$notifications);
$result = pht(
'Updated notification settings to "%s".',
ConpherenceSettings::getHumanString($notifications));
$label);
return id(new AphrontAjaxResponse())
->setContent($result);
break;

View file

@ -68,10 +68,13 @@ final class ConpherenceViewController extends
$latest_transaction = head($transactions);
$participant = $conpherence->getParticipantIfExists($user->getPHID());
if ($participant) {
if (!$participant->isUpToDate($conpherence)) {
$write_guard = AphrontWriteGuard::beginScopedUnguardedWrites();
$participant->markUpToDate($conpherence, $latest_transaction);
$user->clearCacheData(PhabricatorUserMessageCountCacheType::KEY_COUNT);
unset($write_guard);
}
}
$data = ConpherenceTransactionRenderer::renderTransactions(
$user,

View file

@ -2,17 +2,6 @@
final class ConpherenceWidgetController extends ConpherenceController {
private $userPreferences;
public function setUserPreferences(PhabricatorUserPreferences $pref) {
$this->userPreferences = $pref;
return $this;
}
public function getUserPreferences() {
return $this->userPreferences;
}
public function shouldAllowPublic() {
return true;
}
@ -35,8 +24,6 @@ final class ConpherenceWidgetController extends ConpherenceController {
}
$this->setConpherence($conpherence);
$this->setUserPreferences($user->loadPreferences());
switch ($request->getStr('widget')) {
case 'widgets-people':
$content = $this->renderPeopleWidgetPaneContent();
@ -143,28 +130,24 @@ final class ConpherenceWidgetController extends ConpherenceController {
),
$text);
}
$default = ConpherenceSettings::EMAIL_ALWAYS;
$preference = $this->getUserPreferences();
if ($preference) {
$default = $preference->getPreference(
PhabricatorUserPreferences::PREFERENCE_CONPH_NOTIFICATIONS,
ConpherenceSettings::EMAIL_ALWAYS);
}
$notification_key = PhabricatorConpherenceNotificationsSetting::SETTINGKEY;
$notification_default = $viewer->getUserSetting($notification_key);
$settings = $participant->getSettings();
$notifications = idx(
$settings,
'notifications',
$default);
$notification_default);
$options = id(new AphrontFormRadioButtonControl())
->addButton(
ConpherenceSettings::EMAIL_ALWAYS,
ConpherenceSettings::getHumanString(
ConpherenceSettings::EMAIL_ALWAYS),
PhabricatorConpherenceNotificationsSetting::VALUE_CONPHERENCE_EMAIL,
PhabricatorConpherenceNotificationsSetting::getSettingLabel(
PhabricatorConpherenceNotificationsSetting::VALUE_CONPHERENCE_EMAIL),
'')
->addButton(
ConpherenceSettings::NOTIFICATIONS_ONLY,
ConpherenceSettings::getHumanString(
ConpherenceSettings::NOTIFICATIONS_ONLY),
PhabricatorConpherenceNotificationsSetting::VALUE_CONPHERENCE_NOTIFY,
PhabricatorConpherenceNotificationsSetting::getSettingLabel(
PhabricatorConpherenceNotificationsSetting::VALUE_CONPHERENCE_NOTIFY),
'')
->setName('notifications')
->setValue($notifications);

View file

@ -422,6 +422,10 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
$participant->save();
}
PhabricatorUserCache::clearCaches(
PhabricatorUserMessageCountCacheType::KEY_COUNT,
array_keys($participants));
if ($xactions) {
$data = array(
'type' => 'message',
@ -541,26 +545,29 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
$participant_phids = mpull($participants, 'getParticipantPHID');
$preferences = id(new PhabricatorUserPreferencesQuery())
$users = id(new PhabricatorPeopleQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withUserPHIDs($participant_phids)
->withPHIDs($participant_phids)
->needUserSettings(true)
->execute();
$preferences = mpull($preferences, null, 'getUserPHID');
$users = mpull($users, null, 'getPHID');
$notification_key = PhabricatorConpherenceNotificationsSetting::SETTINGKEY;
$notification_email =
PhabricatorConpherenceNotificationsSetting::VALUE_CONPHERENCE_EMAIL;
foreach ($participants as $phid => $participant) {
$default = ConpherenceSettings::EMAIL_ALWAYS;
$preference = idx($preferences, $phid);
if ($preference) {
$default = $preference->getPreference(
PhabricatorUserPreferences::PREFERENCE_CONPH_NOTIFICATIONS,
ConpherenceSettings::EMAIL_ALWAYS);
$user = idx($users, $phid);
if ($user) {
$default = $user->getUserSetting($notification_key);
} else {
$default = $notification_email;
}
$settings = $participant->getSettings();
$notifications = idx(
$settings,
'notifications',
$default);
if ($notifications == ConpherenceSettings::EMAIL_ALWAYS) {
$notifications = idx($settings, 'notifications', $default);
if ($notifications == $notification_email) {
$to_phids[] = $phid;
}
}

View file

@ -100,7 +100,7 @@ final class ConpherenceThreadQuery
$data = queryfx_all(
$conn_r,
'SELECT conpherence_thread.* FROM %T conpherence_thread %Q %Q %Q %Q %Q',
'SELECT thread.* FROM %T thread %Q %Q %Q %Q %Q',
$table->getTableName(),
$this->buildJoinClause($conn_r),
$this->buildWhereClause($conn_r),
@ -144,7 +144,7 @@ final class ConpherenceThreadQuery
protected function buildGroupClause(AphrontDatabaseConnection $conn_r) {
if ($this->participantPHIDs !== null || strlen($this->fulltext)) {
return 'GROUP BY conpherence_thread.id';
return 'GROUP BY thread.id';
} else {
return $this->buildApplicationSearchGroupClause($conn_r);
}
@ -156,14 +156,14 @@ final class ConpherenceThreadQuery
if ($this->participantPHIDs !== null) {
$joins[] = qsprintf(
$conn_r,
'JOIN %T p ON p.conpherencePHID = conpherence_thread.phid',
'JOIN %T p ON p.conpherencePHID = thread.phid',
id(new ConpherenceParticipant())->getTableName());
}
if (strlen($this->fulltext)) {
$joins[] = qsprintf(
$conn_r,
'JOIN %T idx ON idx.threadPHID = conpherence_thread.phid',
'JOIN %T idx ON idx.threadPHID = thread.phid',
id(new ConpherenceIndex())->getTableName());
}
@ -179,14 +179,14 @@ final class ConpherenceThreadQuery
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'conpherence_thread.id IN (%Ld)',
'thread.id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
'conpherence_thread.phid IN (%Ls)',
'thread.phid IN (%Ls)',
$this->phids);
}
@ -438,4 +438,8 @@ final class ConpherenceThreadQuery
return 'PhabricatorConpherenceApplication';
}
protected function getPrimaryTableAlias() {
return 'thread';
}
}

View file

@ -47,11 +47,16 @@ final class ConpherenceParticipant extends ConpherenceDAO {
$this->setBehindTransactionPHID($xaction->getPHID());
$this->setSeenMessageCount($conpherence->getMessageCount());
$this->save();
PhabricatorUserCache::clearCache(
PhabricatorUserMessageCountCacheType::KEY_COUNT,
$this->getParticipantPHID());
}
return $this;
}
private function isUpToDate(ConpherenceThread $conpherence) {
public function isUpToDate(ConpherenceThread $conpherence) {
return
($this->getSeenMessageCount() == $conpherence->getMessageCount())
&&

View file

@ -108,7 +108,7 @@ final class ConpherenceDurableColumnView extends AphrontTagView {
}
protected function getTagContent() {
$column_key = PhabricatorUserPreferences::PREFERENCE_CONPHERENCE_COLUMN;
$column_key = PhabricatorConpherenceColumnVisibleSetting::SETTINGKEY;
Javelin::initBehavior(
'durable-column',

View file

@ -17,30 +17,59 @@ final class DarkConsoleController extends PhabricatorController {
return true;
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
public function handleRequest(AphrontRequest $request) {
$viewer = $this->getViewer();
$response = id(new AphrontAjaxResponse())->setDisableConsole(true);
if (!$user->isLoggedIn()) {
if (!$viewer->isLoggedIn()) {
return $response;
}
$visible = $request->getStr('visible');
if (strlen($visible)) {
$user->setConsoleVisible((int)$visible);
$user->save();
$this->writeDarkConsoleSetting(
PhabricatorDarkConsoleVisibleSetting::SETTINGKEY,
(int)$visible);
return $response;
}
$tab = $request->getStr('tab');
if (strlen($tab)) {
$user->setConsoleTab($tab);
$user->save();
$this->writeDarkConsoleSetting(
PhabricatorDarkConsoleTabSetting::SETTINGKEY,
$tab);
return $response;
}
return new Aphront404Response();
}
private function writeDarkConsoleSetting($key, $value) {
$viewer = $this->getViewer();
$request = $this->getRequest();
$preferences = PhabricatorUserPreferences::loadUserPreferences($viewer);
$editor = id(new PhabricatorUserPreferencesEditor())
->setActor($viewer)
->setContentSourceFromRequest($request)
->setContinueOnNoEffect(true)
->setContinueOnMissingFields(true);
$xactions = array();
$xactions[] = $preferences->newTransaction($key, $value);
$editor->applyTransactions($preferences, $xactions);
// Reload the user to regenerate their preferences cache. If we don't
// do this, the "Services" tab gets misleadingly spammed up with cache
// fills that are only filling because you toggled the console or switched
// tabs. This makes it harder to see what's really going on, so just force
// a cache regeneration here.
id(new PhabricatorPeopleQuery())
->setViewer($viewer)
->withPHIDs(array($viewer->getPHID()))
->needUserSettings(true)
->execute();
}
}

View file

@ -93,7 +93,8 @@ final class DarkConsoleCore extends Phobject {
public function render(AphrontRequest $request) {
$user = $request->getUser();
$visible = $user ? $user->getConsoleVisible() : true;
$visible = $user->getUserSetting(
PhabricatorDarkConsoleVisibleSetting::SETTINGKEY);
return javelin_tag(
'div',

View file

@ -147,7 +147,7 @@ final class PhabricatorCountdownSearchEngine
$create_button = id(new PHUIButtonView())
->setTag('a')
->setText(pht('Create a Countdown'))
->setHref('/countdown/create/')
->setHref('/countdown/edit/')
->setColor(PHUIButtonView::GREEN);
$icon = $this->getApplication()->getIcon();

View file

@ -268,10 +268,10 @@ final class PhabricatorDashboardEditController
$request,
$viewer,
'query',
pht('Recent Tasks'),
pht('Open Tasks'),
array(
'class' => 'ManiphestTaskSearchEngine',
'key' => 'all',
'key' => 'open',
));
$panel_phids[] = $task_panel->getPHID();

View file

@ -0,0 +1,18 @@
<?php
final class DifferentialRevisionSearchConduitAPIMethod
extends PhabricatorSearchEngineAPIMethod {
public function getAPIMethodName() {
return 'differential.revision.search';
}
public function newSearchEngine() {
return new DifferentialRevisionSearchEngine();
}
public function getMethodSummary() {
return pht('Read information about revisions.');
}
}

View file

@ -261,13 +261,14 @@ final class PhabricatorDifferentialConfigOptions
"that many lines. For instance, a value of 100 means 'inline ".
"patches if they are no longer than 100 lines'. By default, ".
"patches are not inlined.")),
// TODO: Implement 'enum'? Options are 'unified' or 'git'.
$this->newOption(
'metamta.differential.patch-format',
'string',
'enum',
'unified')
->setDescription(
pht("Format for inlined or attached patches: 'git' or 'unified'.")),
pht('Format for inlined or attached patches.'))
->setEnumOptions(
array('unified' => 'unified', 'git' => 'git')),
);
}

View file

@ -381,7 +381,7 @@ final class DifferentialRevisionViewController extends DifferentialController {
$nav = null;
if ($filetree_on) {
$collapsed_key = PhabricatorUserPreferences::PREFERENCE_NAV_COLLAPSED;
$collapsed_key = PhabricatorFiletreeVisibleSetting::SETTINGKEY;
$collapsed_value = $viewer->getUserSetting($collapsed_key);
$nav = id(new DifferentialChangesetFileTreeSideNavBuilder())

View file

@ -626,6 +626,8 @@ abstract class DifferentialChangesetRenderer extends Phobject {
unset($old['unix:filemode']);
}
$metadata = $changeset->getMetadata();
if ($this->hasOldFile()) {
$file = $this->getOldFile();
if ($file->getImageWidth()) {
@ -634,6 +636,12 @@ abstract class DifferentialChangesetRenderer extends Phobject {
}
$old['file:mimetype'] = $file->getMimeType();
$old['file:size'] = phutil_format_bytes($file->getByteSize());
} else {
$old['file:mimetype'] = idx($metadata, 'old:file:mime-type');
$size = idx($metadata, 'old:file:size');
if ($size !== null) {
$old['file:size'] = phutil_format_bytes($size);
}
}
if ($this->hasNewFile()) {
@ -644,6 +652,12 @@ abstract class DifferentialChangesetRenderer extends Phobject {
}
$new['file:mimetype'] = $file->getMimeType();
$new['file:size'] = phutil_format_bytes($file->getByteSize());
} else {
$new['file:mimetype'] = idx($metadata, 'new:file:mime-type');
$size = idx($metadata, 'new:file:size');
if ($size !== null) {
$new['file:size'] = phutil_format_bytes($size);
}
}
return array($old, $new);

View file

@ -32,6 +32,13 @@ abstract class DifferentialChangesetTestRenderer
$changeset = $this->getChangeset();
list($old, $new) = $this->getChangesetProperties($changeset);
foreach (array_keys($old) as $key) {
if ($old[$key] === idx($new, $key)) {
unset($old[$key]);
unset($new[$key]);
}
}
if (!$old && !$new) {
return null;
}

View file

@ -14,7 +14,8 @@ final class DifferentialRevision extends DifferentialDAO
PhabricatorMentionableInterface,
PhabricatorDestructibleInterface,
PhabricatorProjectInterface,
PhabricatorFulltextInterface {
PhabricatorFulltextInterface,
PhabricatorConduitResultInterface {
protected $title = '';
protected $originalTitle;
@ -635,4 +636,31 @@ final class DifferentialRevision extends DifferentialDAO
}
/* -( PhabricatorConduitResultInterface )---------------------------------- */
public function getFieldSpecificationsForConduit() {
return array(
id(new PhabricatorConduitSearchFieldSpecification())
->setKey('title')
->setType('string')
->setDescription(pht('The revision title.')),
id(new PhabricatorConduitSearchFieldSpecification())
->setKey('authorPHID')
->setType('phid')
->setDescription(pht('Revision author PHID.')),
);
}
public function getFieldValuesForConduit() {
return array(
'title' => $this->getTitle(),
'authorPHID' => $this->getAuthorPHID(),
);
}
public function getConduitSearchAttachments() {
return array();
}
}

View file

@ -105,28 +105,31 @@ final class DiffusionBrowseController extends DiffusionController {
$path = $drequest->getPath();
$preferences = $viewer->loadPreferences();
$blame_key = PhabricatorDiffusionBlameSetting::SETTINGKEY;
$color_key = PhabricatorDiffusionColorSetting::SETTINGKEY;
$show_blame = $request->getBool(
'blame',
$preferences->getPreference(
PhabricatorUserPreferences::PREFERENCE_DIFFUSION_BLAME,
false));
$viewer->getUserSetting($blame_key));
$show_color = $request->getBool(
'color',
$preferences->getPreference(
PhabricatorUserPreferences::PREFERENCE_DIFFUSION_COLOR,
true));
$viewer->getUserSetting($color_key));
$view = $request->getStr('view');
if ($request->isFormPost() && $view != 'raw' && $viewer->isLoggedIn()) {
$preferences->setPreference(
PhabricatorUserPreferences::PREFERENCE_DIFFUSION_BLAME,
$show_blame);
$preferences->setPreference(
PhabricatorUserPreferences::PREFERENCE_DIFFUSION_COLOR,
$show_color);
$preferences->save();
$preferences = PhabricatorUserPreferences::loadUserPreferences($viewer);
$editor = id(new PhabricatorUserPreferencesEditor())
->setActor($viewer)
->setContentSourceFromRequest($request)
->setContinueOnNoEffect(true)
->setContinueOnMissingFields(true);
$xactions = array();
$xactions[] = $preferences->newTransaction($blame_key, $show_blame);
$xactions[] = $preferences->newTransaction($color_key, $show_color);
$editor->applyTransactions($preferences, $xactions);
$uri = $request->getRequestURI()
->alter('blame', null)

View file

@ -329,7 +329,7 @@ final class DiffusionCommitController extends DiffusionController {
PhabricatorShowFiletreeSetting::SETTINGKEY,
PhabricatorShowFiletreeSetting::VALUE_ENABLE_FILETREE);
$pref_collapse = PhabricatorUserPreferences::PREFERENCE_NAV_COLLAPSED;
$pref_collapse = PhabricatorFiletreeVisibleSetting::SETTINGKEY;
$collapsed = $viewer->getUserSetting($pref_collapse);
$nav = null;

View file

@ -2,7 +2,11 @@
final class DiffusionSetPasswordSettingsPanel extends PhabricatorSettingsPanel {
public function isEditableByAdministrators() {
public function isManagementPanel() {
if ($this->getUser()->getIsMailingList()) {
return false;
}
return true;
}
@ -14,15 +18,11 @@ final class DiffusionSetPasswordSettingsPanel extends PhabricatorSettingsPanel {
return pht('VCS Password');
}
public function getPanelGroup() {
return pht('Authentication');
public function getPanelGroupKey() {
return PhabricatorSettingsAuthenticationPanelGroup::PANELGROUPKEY;
}
public function isEnabled() {
if ($this->getUser()->getIsMailingList()) {
return false;
}
return PhabricatorEnv::getEnvConfig('diffusion.allow-http-auth');
}

View file

@ -9,6 +9,7 @@ abstract class DiffusionCommandEngine extends Phobject {
private $passthru;
private $connectAsDevice;
private $sudoAsDaemon;
private $uri;
public static function newCommandEngine(PhabricatorRepository $repository) {
$engines = self::newCommandEngines();
@ -48,6 +49,16 @@ abstract class DiffusionCommandEngine extends Phobject {
return $this->repository;
}
public function setURI(PhutilURI $uri) {
$this->uri = $uri;
$this->setProtocol($uri->getProtocol());
return $this;
}
public function getURI() {
return $this->uri;
}
public function setProtocol($protocol) {
$this->protocol = $protocol;
return $this;

View file

@ -30,6 +30,21 @@ final class DiffusionGitCommandEngine
$env['GIT_SSH'] = $this->getSSHWrapper();
}
if ($this->isAnyHTTPProtocol()) {
$uri = $this->getURI();
if ($uri) {
$proxy = PhutilHTTPEngineExtension::buildHTTPProxyURI($uri);
if ($proxy) {
if ($this->isHTTPSProtocol()) {
$env_key = 'https_proxy';
} else {
$env_key = 'http_proxy';
}
$env[$env_key] = (string)$proxy;
}
}
}
return $env;
}

View file

@ -598,7 +598,7 @@ final class DiffusionRepositoryClusterEngine extends Phobject {
->setArgv($argv)
->setSudoAsDaemon(true)
->setCredentialPHID($repository->getCredentialPHID())
->setProtocol($repository->getRemoteProtocol())
->setURI($repository->getRemoteURI())
->newFuture();
$future->setCWD($local_path);
@ -704,7 +704,7 @@ final class DiffusionRepositoryClusterEngine extends Phobject {
->setArgv($argv)
->setConnectAsDevice(true)
->setSudoAsDaemon(true)
->setProtocol($fetch_uri->getProtocol())
->setURI($fetch_uri)
->newFuture();
$future->setCWD($local_path);

View file

@ -159,7 +159,8 @@ final class PhabricatorFeedStoryPublisher extends Phobject {
$will_receive_mail = array_fill_keys($this->mailRecipientPHIDs, true);
foreach (array_unique($subscribed_phids) as $user_phid) {
$user_phids = array_unique($subscribed_phids);
foreach ($user_phids as $user_phid) {
if (isset($will_receive_mail[$user_phid])) {
$mark_read = 1;
} else {
@ -184,6 +185,10 @@ final class PhabricatorFeedStoryPublisher extends Phobject {
$notif->getTableName(),
implode(', ', $sql));
}
PhabricatorUserCache::clearCaches(
PhabricatorUserNotificationCountCacheType::KEY_COUNT,
$user_phids);
}
private function sendNotification($chrono_key, array $subscribed_phids) {
@ -214,8 +219,8 @@ final class PhabricatorFeedStoryPublisher extends Phobject {
$all_prefs = mpull($all_prefs, null, 'getUserPHID');
}
$pref_default = PhabricatorUserPreferences::MAILTAG_PREFERENCE_EMAIL;
$pref_ignore = PhabricatorUserPreferences::MAILTAG_PREFERENCE_IGNORE;
$pref_default = PhabricatorEmailTagsSetting::VALUE_EMAIL;
$pref_ignore = PhabricatorEmailTagsSetting::VALUE_IGNORE;
$keep = array();
foreach ($phids as $phid) {
@ -224,9 +229,8 @@ final class PhabricatorFeedStoryPublisher extends Phobject {
}
if ($tags && isset($all_prefs[$phid])) {
$mailtags = $all_prefs[$phid]->getPreference(
PhabricatorUserPreferences::PREFERENCE_MAILTAGS,
array());
$mailtags = $all_prefs[$phid]->getSettingValue(
PhabricatorEmailTagsSetting::SETTINGKEY);
$notify = false;
foreach ($tags as $tag) {

View file

@ -81,7 +81,8 @@ final class PhabricatorFilesApplication extends PhabricatorApplication {
'proxy/' => 'PhabricatorFileProxyController',
'transforms/(?P<id>[1-9]\d*)/' =>
'PhabricatorFileTransformListController',
'uploaddialog/' => 'PhabricatorFileUploadDialogController',
'uploaddialog/(?P<single>single/)?'
=> 'PhabricatorFileUploadDialogController',
'download/(?P<phid>[^/]+)/' => 'PhabricatorFileDialogController',
'iconset/(?P<key>[^/]+)/' => array(
'select/' => 'PhabricatorFileIconSetSelectController',

View file

@ -34,9 +34,16 @@ final class PhabricatorFilesConfigOptions
'image/x-icon' => 'image/x-icon',
'image/vnd.microsoft.icon' => 'image/x-icon',
'audio/x-wav' => 'audio/x-wav',
// This is a generic type for both OGG video and OGG audio.
'application/ogg' => 'application/ogg',
'audio/x-wav' => 'audio/x-wav',
'audio/mpeg' => 'audio/mpeg',
'audio/ogg' => 'audio/ogg',
'video/mp4' => 'video/mp4',
'video/ogg' => 'video/ogg',
'video/webm' => 'video/webm',
);
$image_default = array(
@ -49,10 +56,29 @@ final class PhabricatorFilesConfigOptions
'image/vnd.microsoft.icon' => true,
);
// The "application/ogg" type is listed as both an audio and video type,
// because it may contain either type of content.
$audio_default = array(
'audio/x-wav' => true,
'application/ogg' => true,
'audio/mpeg' => true,
'audio/ogg' => true,
// These are video or ambiguous types, but can be forced to render as
// audio with `media=audio`, which seems to work properly in browsers.
// (For example, you can embed a music video as audio if you just want
// to set the mood for your task without distracting viewers.)
'video/mp4' => true,
'video/ogg' => true,
'application/ogg' => true,
);
$video_default = array(
'video/mp4' => true,
'video/ogg' => true,
'video/webm' => true,
'application/ogg' => true,
);
// largely lifted from http://en.wikipedia.org/wiki/Internet_media_type
@ -70,6 +96,7 @@ final class PhabricatorFilesConfigOptions
// movie file icon
'video/mpeg' => 'fa-file-movie-o',
'video/mp4' => 'fa-file-movie-o',
'application/ogg' => 'fa-file-movie-o',
'video/ogg' => 'fa-file-movie-o',
'video/quicktime' => 'fa-file-movie-o',
'video/webm' => 'fa-file-movie-o',
@ -122,8 +149,14 @@ final class PhabricatorFilesConfigOptions
->setSummary(pht('Configure which MIME types are audio.'))
->setDescription(
pht(
'List of MIME types which can be used to render an `%s` tag.',
'List of MIME types which can be rendered with an `%s` tag.',
'<audio />')),
$this->newOption('files.video-mime-types', 'set', $video_default)
->setSummary(pht('Configure which MIME types are video.'))
->setDescription(
pht(
'List of MIME types which can be rendered with a `%s` tag.',
'<video />')),
$this->newOption('files.icon-mime-types', 'wild', $icon_default)
->setLocked(true)
->setSummary(pht('Configure which MIME types map to which icons.'))

View file

@ -230,23 +230,34 @@ final class PhabricatorFileInfoController extends PhabricatorFileController {
$cache_string = pht('Not Applicable');
}
$finfo->addProperty(pht('Viewable Image'), $image_string);
$finfo->addProperty(pht('Cacheable'), $cache_string);
$builtin = $file->getBuiltinName();
if ($builtin === null) {
$builtin_string = pht('No');
} else {
$builtin_string = $builtin;
$types = array();
if ($file->isViewableImage()) {
$types[] = pht('Image');
}
$finfo->addProperty(pht('Builtin'), $builtin_string);
if ($file->isVideo()) {
$types[] = pht('Video');
}
$is_profile = $file->getIsProfileImage()
? pht('Yes')
: pht('No');
if ($file->isAudio()) {
$types[] = pht('Audio');
}
$finfo->addProperty(pht('Profile'), $is_profile);
if ($file->getCanCDN()) {
$types[] = pht('Can CDN');
}
$builtin = $file->getBuiltinName();
if ($builtin !== null) {
$types[] = pht('Builtin ("%s")', $builtin);
}
if ($file->getIsProfileImage()) {
$types[] = pht('Profile');
}
$types = implode(', ', $types);
$finfo->addProperty(pht('Attributes'), $types);
$storage_properties = new PHUIPropertyListView();
$box->addPropertyList($storage_properties, pht('Storage'));
@ -292,6 +303,23 @@ final class PhabricatorFileInfoController extends PhabricatorFileController {
$media = id(new PHUIPropertyListView())
->addImageContent($linked_image);
$box->addPropertyList($media);
} else if ($file->isVideo()) {
$video = phutil_tag(
'video',
array(
'controls' => 'controls',
'class' => 'phui-property-list-video',
),
phutil_tag(
'source',
array(
'src' => $file->getViewURI(),
'type' => $file->getMimeType(),
)));
$media = id(new PHUIPropertyListView())
->addImageContent($video);
$box->addPropertyList($media);
} else if ($file->isAudio()) {
$audio = phutil_tag(

View file

@ -37,12 +37,18 @@ final class PhabricatorFileUploadDialogController
}
}
if ($request->getURIData('single')) {
$allow_multiple = false;
} else {
$allow_multiple = true;
}
$form = id(new AphrontFormView())
->appendChild(
id(new PHUIFormFileControl())
->setName('filePHIDs')
->setLabel(pht('Upload File'))
->setAllowMultiple(true)
->setAllowMultiple($allow_multiple)
->setError($e_file));
return $this->newDialog()

View file

@ -43,12 +43,27 @@ final class PhabricatorEmbedFileRemarkupRule
$is_viewable_image = $object->isViewableImage();
$is_audio = $object->isAudio();
$is_video = $object->isVideo();
$force_link = ($options['layout'] == 'link');
$options['viewable'] = ($is_viewable_image || $is_audio);
// If a file is both audio and video, as with "application/ogg" by default,
// render it as video but allow the user to specify `media=audio` if they
// want to force it to render as audio.
if ($is_audio && $is_video) {
$media = $options['media'];
if ($media == 'audio') {
$is_video = false;
} else {
$is_audio = false;
}
}
$options['viewable'] = ($is_viewable_image || $is_audio || $is_video);
if ($is_viewable_image && !$force_link) {
return $this->renderImageFile($object, $handle, $options);
} else if ($is_video && !$force_link) {
return $this->renderVideoFile($object, $handle, $options);
} else if ($is_audio && !$force_link) {
return $this->renderAudioFile($object, $handle, $options);
} else {
@ -64,6 +79,9 @@ final class PhabricatorEmbedFileRemarkupRule
'width' => null,
'height' => null,
'alt' => null,
'media' => null,
'autoplay' => null,
'loop' => null,
);
if ($option_string) {
@ -201,22 +219,47 @@ final class PhabricatorEmbedFileRemarkupRule
PhabricatorFile $file,
PhabricatorObjectHandle $handle,
array $options) {
return $this->renderMediaFile('audio', $file, $handle, $options);
}
private function renderVideoFile(
PhabricatorFile $file,
PhabricatorObjectHandle $handle,
array $options) {
return $this->renderMediaFile('video', $file, $handle, $options);
}
private function renderMediaFile(
$tag,
PhabricatorFile $file,
PhabricatorObjectHandle $handle,
array $options) {
$is_video = ($tag == 'video');
if (idx($options, 'autoplay')) {
$preload = 'auto';
$autoplay = 'autoplay';
} else {
// If we don't preload video, the user can't see the first frame and
// has no clue what they're looking at, so always preload.
if ($is_video) {
$preload = 'auto';
} else {
$preload = 'none';
}
$autoplay = null;
}
return $this->newTag(
'audio',
$tag,
array(
'controls' => 'controls',
'preload' => $preload,
'autoplay' => $autoplay,
'loop' => idx($options, 'loop') ? 'loop' : null,
'alt' => $options['alt'],
'class' => 'phabricator-media',
),
$this->newTag(
'source',

View file

@ -134,6 +134,9 @@ final class PhabricatorFileQuery
return $files;
}
$viewer = $this->getViewer();
$is_omnipotent = $viewer->isOmnipotent();
// We need to load attached objects to perform policy checks for files.
// First, load the edges.
@ -156,6 +159,13 @@ final class PhabricatorFileQuery
continue;
}
if ($is_omnipotent) {
// If the viewer is omnipotent, we don't need to load the associated
// objects either since they can certainly see the object. Skipping
// this can improve performance and prevent cycles.
continue;
}
foreach ($phids as $phid) {
$object_phids[$phid] = true;
}

View file

@ -802,6 +802,16 @@ final class PhabricatorFile extends PhabricatorFileDAO
return idx($mime_map, $mime_type);
}
public function isVideo() {
if (!$this->isViewableInBrowser()) {
return false;
}
$mime_map = PhabricatorEnv::getEnvConfig('files.video-mime-types');
$mime_type = $this->getMimeType();
return idx($mime_map, $mime_type);
}
public function isTransformableImage() {
// NOTE: The way the 'gd' extension works in PHP is that you can install it
// with support for only some file types, so it might be able to handle

View file

@ -2,6 +2,7 @@
final class PhabricatorHomeApplication extends PhabricatorApplication {
private $quickItems;
const DASHBOARD_DEFAULT = 'dashboard:default';
public function getBaseURI() {
@ -42,13 +43,14 @@ final class PhabricatorHomeApplication extends PhabricatorApplication {
PhabricatorUser $user,
PhabricatorController $controller = null) {
$quick_create_items = $this->loadAllQuickCreateItems($user);
$items = array();
$quick_items = $this->getQuickActionItems($user);
if (!$quick_items) {
return array();
}
if ($user->isLoggedIn() &&
$user->isUserActivated() &&
$quick_create_items) {
$items = array();
$create_id = celerity_generate_unique_node_id();
Javelin::initBehavior(
'aphlict-dropdown',
array(
@ -60,33 +62,15 @@ final class PhabricatorHomeApplication extends PhabricatorApplication {
));
$item = id(new PHUIListItemView())
->setName(pht('Create New...'))
->setName(pht('Quick Actions'))
->setIcon('fa-plus')
->addClass('core-menu-item')
->setHref('/home/create/')
->addSigil('quick-create-menu')
->setID($create_id)
->setAural(pht('Quick Create'))
->setAural(pht('Quick Actions'))
->setOrder(300);
$items[] = $item;
}
return $items;
}
public function loadAllQuickCreateItems(PhabricatorUser $viewer) {
$applications = id(new PhabricatorApplicationQuery())
->setViewer($viewer)
->withInstalled(true)
->execute();
$items = array();
foreach ($applications as $application) {
$app_items = $application->getQuickCreateItems($viewer);
foreach ($app_items as $app_item) {
$items[] = $app_item;
}
}
return $items;
}
@ -95,7 +79,7 @@ final class PhabricatorHomeApplication extends PhabricatorApplication {
PhabricatorUser $viewer,
PhabricatorController $controller = null) {
$items = $this->loadAllQuickCreateItems($viewer);
$items = $this->getQuickActionItems($viewer);
$view = null;
if ($items) {
@ -116,4 +100,12 @@ final class PhabricatorHomeApplication extends PhabricatorApplication {
return $view;
}
private function getQuickActionItems(PhabricatorUser $viewer) {
if ($this->quickItems === null) {
$items = PhabricatorQuickActions::loadMenuItemsForUser($viewer);
$this->quickItems = $items;
}
return $this->quickItems;
}
}

View file

@ -15,9 +15,8 @@ abstract class PhabricatorHomeController extends PhabricatorController {
->withLaunchable(true)
->execute();
$pinned = $user->loadPreferences()->getPinnedApplications(
$applications,
$user);
$pinned = $user->getUserSetting(
PhabricatorPinnedApplicationsSetting::SETTINGKEY);
// Force "Applications" to appear at the bottom.
$meta_app = 'PhabricatorApplicationsApplication';

View file

@ -6,7 +6,7 @@ final class PhabricatorHomeQuickCreateController
public function handleRequest(AphrontRequest $request) {
$viewer = $this->getViewer();
$items = $this->getCurrentApplication()->loadAllQuickCreateItems($viewer);
$items = PhabricatorQuickActions::loadMenuItemsForUser($viewer);
$list = id(new PHUIObjectItemListView())
->setUser($viewer);

View file

@ -90,12 +90,6 @@ final class PhabricatorManiphestApplication extends PhabricatorApplication {
return $status;
}
public function getQuickCreateItems(PhabricatorUser $viewer) {
return id(new ManiphestEditEngine())
->setViewer($viewer)
->loadQuickCreateItems();
}
public function supportsEmailIntegration() {
return true;
}

View file

@ -59,6 +59,7 @@ final class PhabricatorMetaMTAActorQuery extends PhabricatorQuery {
$users = id(new PhabricatorPeopleQuery())
->setViewer($this->getViewer())
->withPHIDs($phids)
->needUserSettings(true)
->execute();
$users = mpull($users, null, 'getPHID');

View file

@ -337,9 +337,12 @@ abstract class PhabricatorMailReplyHandler extends Phobject {
$all_phids = array_merge($to, $cc);
if ($all_phids) {
// We need user settings here because we'll check translations later
// when generating mail.
$users = id(new PhabricatorPeopleQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withPHIDs($all_phids)
->needUserSettings(true)
->execute();
$users = mpull($users, null, 'getPHID');

View file

@ -435,13 +435,6 @@ final class PhabricatorMetaMTAMail
$add_cc = array();
$add_to = array();
// Only try to use preferences if everything is multiplexed, so we
// get consistent behavior.
$use_prefs = self::shouldMultiplexAllMail();
$prefs = null;
if ($use_prefs) {
// If multiplexing is enabled, some recipients will be in "Cc"
// rather than "To". We'll move them to "To" later (or supply a
// dummy "To") but need to look for the recipient in either the
@ -451,15 +444,7 @@ final class PhabricatorMetaMTAMail
$target_phid = head(idx($params, 'cc', array()));
}
if ($target_phid) {
$user = id(new PhabricatorUser())->loadOneWhere(
'phid = %s',
$target_phid);
if ($user) {
$prefs = $user->loadPreferences();
}
}
}
$preferences = $this->loadPreferences($target_phid);
foreach ($params as $key => $value) {
switch ($key) {
@ -526,15 +511,7 @@ final class PhabricatorMetaMTAMail
$subject = array();
if ($is_threaded) {
$add_re = PhabricatorEnv::getEnvConfig('metamta.re-prefix');
if ($prefs) {
$add_re = $prefs->getPreference(
PhabricatorUserPreferences::PREFERENCE_RE_PREFIX,
$add_re);
}
if ($add_re) {
if ($this->shouldAddRePrefix($preferences)) {
$subject[] = 'Re:';
}
}
@ -543,16 +520,7 @@ final class PhabricatorMetaMTAMail
$vary_prefix = idx($params, 'vary-subject-prefix');
if ($vary_prefix != '') {
$use_subject = PhabricatorEnv::getEnvConfig(
'metamta.vary-subjects');
if ($prefs) {
$use_subject = $prefs->getPreference(
PhabricatorUserPreferences::PREFERENCE_VARY_SUBJECT,
$use_subject);
}
if ($use_subject) {
if ($this->shouldVarySubject($preferences)) {
$subject[] = $vary_prefix;
}
}
@ -607,13 +575,7 @@ final class PhabricatorMetaMTAMail
}
$mailer->setBody($body);
$html_emails = true;
if ($use_prefs && $prefs) {
$html_emails = $prefs->getPreference(
PhabricatorUserPreferences::PREFERENCE_HTML_EMAILS,
$html_emails);
}
$html_emails = $this->shouldSendHTML($preferences);
if ($html_emails && isset($params['html-body'])) {
$mailer->setHTMLBody($params['html-body']);
}
@ -900,13 +862,12 @@ final class PhabricatorMetaMTAMail
$from_user = id(new PhabricatorPeopleQuery())
->setViewer($viewer)
->withPHIDs(array($from_phid))
->needUserSettings(true)
->execute();
$from_user = head($from_user);
if ($from_user) {
$pref_key = PhabricatorUserPreferences::PREFERENCE_NO_SELF_MAIL;
$exclude_self = $from_user
->loadPreferences()
->getPreference($pref_key);
$pref_key = PhabricatorEmailSelfActionsSetting::SETTINGKEY;
$exclude_self = $from_user->getUserSetting($pref_key);
if ($exclude_self) {
$from_actor->setUndeliverable(PhabricatorMetaMTAActor::REASON_SELF);
}
@ -919,7 +880,7 @@ final class PhabricatorMetaMTAMail
->execute();
$all_prefs = mpull($all_prefs, null, 'getUserPHID');
$value_email = PhabricatorUserPreferences::MAILTAG_PREFERENCE_EMAIL;
$value_email = PhabricatorEmailTagsSetting::VALUE_EMAIL;
// Exclude all recipients who have set preferences to not receive this type
// of email (for example, a user who says they don't want emails about task
@ -927,9 +888,8 @@ final class PhabricatorMetaMTAMail
$tags = $this->getParam('mailtags');
if ($tags) {
foreach ($all_prefs as $phid => $prefs) {
$user_mailtags = $prefs->getPreference(
PhabricatorUserPreferences::PREFERENCE_MAILTAGS,
array());
$user_mailtags = $prefs->getSettingValue(
PhabricatorEmailTagsSetting::SETTINGKEY);
// The user must have elected to receive mail for at least one
// of the mailtags.
@ -982,9 +942,8 @@ final class PhabricatorMetaMTAMail
// Exclude recipients who don't want any mail. This rule is very strong
// and runs last.
foreach ($all_prefs as $phid => $prefs) {
$exclude = $prefs->getPreference(
PhabricatorUserPreferences::PREFERENCE_NO_MAIL,
false);
$exclude = $prefs->getSettingValue(
PhabricatorEmailNotificationsSetting::SETTINGKEY);
if ($exclude) {
$actors[$phid]->setUndeliverable(
PhabricatorMetaMTAActor::REASON_MAIL_DISABLED);
@ -1142,6 +1101,67 @@ final class PhabricatorMetaMTAMail
return $this->routingMap;
}
/* -( Preferences )-------------------------------------------------------- */
private function loadPreferences($target_phid) {
if (!self::shouldMultiplexAllMail()) {
$target_phid = null;
}
if ($target_phid) {
$preferences = id(new PhabricatorUserPreferencesQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withUserPHIDs(array($target_phid))
->executeOne();
} else {
$preferences = null;
}
// TODO: Here, we would load global preferences once they exist.
if (!$preferences) {
// If we haven't found suitable preferences yet, return an empty object
// which implicitly has all the default values.
$preferences = id(new PhabricatorUserPreferences())
->attachUser(new PhabricatorUser());
}
return $preferences;
}
private function shouldAddRePrefix(PhabricatorUserPreferences $preferences) {
$default_value = PhabricatorEnv::getEnvConfig('metamta.re-prefix');
$value = $preferences->getPreference(
PhabricatorEmailRePrefixSetting::SETTINGKEY);
if ($value === null) {
return $default_value;
}
return ($value == PhabricatorEmailRePrefixSetting::VALUE_RE_PREFIX);
}
private function shouldVarySubject(PhabricatorUserPreferences $preferences) {
$default_value = PhabricatorEnv::getEnvConfig('metamta.vary-subjects');
$value = $preferences->getPreference(
PhabricatorEmailVarySubjectsSetting::SETTINGKEY);
if ($value === null) {
return $default_value;
}
return ($value == PhabricatorEmailVarySubjectsSetting::VALUE_VARY_SUBJECTS);
}
private function shouldSendHTML(PhabricatorUserPreferences $preferences) {
$value = $preferences->getSettingValue(
PhabricatorEmailFormatSetting::SETTINGKEY);
return ($value == PhabricatorEmailFormatSetting::VALUE_HTML_EMAIL);
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */

View file

@ -60,8 +60,6 @@ final class PhabricatorMetaMTAMailTestCase extends PhabricatorTestCase {
$user = $this->generateNewTestUser();
$phid = $user->getPHID();
$prefs = $user->loadPreferences();
$mailer = new PhabricatorMailImplementationTestAdapter();
$mail = new PhabricatorMetaMTAMail();
@ -79,27 +77,28 @@ final class PhabricatorMetaMTAMailTestCase extends PhabricatorTestCase {
in_array($phid, $mail->buildRecipientList()),
pht('"From" does not exclude recipients by default.'));
$prefs->setPreference(
PhabricatorUserPreferences::PREFERENCE_NO_SELF_MAIL,
$user = $this->writeSetting(
$user,
PhabricatorEmailSelfActionsSetting::SETTINGKEY,
true);
$prefs->save();
$this->assertFalse(
in_array($phid, $mail->buildRecipientList()),
pht('"From" excludes recipients with no-self-mail set.'));
$prefs->unsetPreference(
PhabricatorUserPreferences::PREFERENCE_NO_SELF_MAIL);
$prefs->save();
$user = $this->writeSetting(
$user,
PhabricatorEmailSelfActionsSetting::SETTINGKEY,
null);
$this->assertTrue(
in_array($phid, $mail->buildRecipientList()),
pht('"From" does not exclude recipients by default.'));
$prefs->setPreference(
PhabricatorUserPreferences::PREFERENCE_NO_MAIL,
$user = $this->writeSetting(
$user,
PhabricatorEmailNotificationsSetting::SETTINGKEY,
true);
$prefs->save();
$this->assertFalse(
in_array($phid, $mail->buildRecipientList()),
@ -113,15 +112,15 @@ final class PhabricatorMetaMTAMailTestCase extends PhabricatorTestCase {
$mail->setForceDelivery(false);
$prefs->unsetPreference(
PhabricatorUserPreferences::PREFERENCE_NO_MAIL);
$prefs->save();
$user = $this->writeSetting(
$user,
PhabricatorEmailNotificationsSetting::SETTINGKEY,
null);
$this->assertTrue(
in_array($phid, $mail->buildRecipientList()),
pht('"From" does not exclude recipients by default.'));
// Test that explicit exclusion works correctly.
$mail->setExcludeMailRecipientPHIDs(array($phid));
@ -133,12 +132,12 @@ final class PhabricatorMetaMTAMailTestCase extends PhabricatorTestCase {
// Test that mail tag preferences exclude recipients.
$prefs->setPreference(
PhabricatorUserPreferences::PREFERENCE_MAILTAGS,
$user = $this->writeSetting(
$user,
PhabricatorEmailTagsSetting::SETTINGKEY,
array(
'test-tag' => false,
));
$prefs->save();
$mail->setMailTags(array('test-tag'));
@ -146,8 +145,10 @@ final class PhabricatorMetaMTAMailTestCase extends PhabricatorTestCase {
in_array($phid, $mail->buildRecipientList()),
pht('Tag preference excludes recipients.'));
$prefs->unsetPreference(PhabricatorUserPreferences::PREFERENCE_MAILTAGS);
$prefs->save();
$user = $this->writeSetting(
$user,
PhabricatorEmailTagsSetting::SETTINGKEY,
null);
$this->assertTrue(
in_array($phid, $mail->buildRecipientList()),
@ -215,4 +216,23 @@ final class PhabricatorMetaMTAMailTestCase extends PhabricatorTestCase {
$case));
}
private function writeSetting(PhabricatorUser $user, $key, $value) {
$preferences = PhabricatorUserPreferences::loadUserPreferences($user);
$editor = id(new PhabricatorUserPreferencesEditor())
->setActor($user)
->setContentSource($this->newContentSource())
->setContinueOnNoEffect(true)
->setContinueOnMissingFields(true);
$xactions = array();
$xactions[] = $preferences->newTransaction($key, $value);
$editor->applyTransactions($preferences, $xactions);
return id(new PhabricatorPeopleQuery())
->setViewer($user)
->withIDs(array($user->getID()))
->executeOne();
}
}

View file

@ -131,10 +131,14 @@ final class PhabricatorNotificationBuilder extends Phobject {
$stories = $this->parseStories();
$dict = array();
$viewer = $this->user;
$desktop_key = PhabricatorDesktopNotificationsSetting::SETTINGKEY;
$desktop_enabled = $viewer->getUserSetting($desktop_key);
foreach ($stories as $story) {
if ($story instanceof PhabricatorApplicationTransactionFeedStory) {
$dict[] = array(
'desktopReady' => true,
'desktopReady' => $desktop_enabled,
'title' => $story->renderText(),
'body' => $story->renderTextBody(),
'href' => $story->getURI(),
@ -142,7 +146,7 @@ final class PhabricatorNotificationBuilder extends Phobject {
);
} else if ($story instanceof PhabricatorNotificationTestFeedStory) {
$dict[] = array(
'desktopReady' => true,
'desktopReady' => $desktop_enabled,
'title' => pht('Test Notification'),
'body' => $story->renderText(),
'href' => null,

View file

@ -18,6 +18,10 @@ final class PhabricatorNotificationClearController
$viewer->getPHID(),
$chrono_key);
PhabricatorUserCache::clearCache(
PhabricatorUserNotificationCountCacheType::KEY_COUNT,
$viewer->getPHID());
return id(new AphrontReloadResponse())
->setURI('/notification/');
}

View file

@ -30,7 +30,9 @@ final class PhabricatorNotificationIndividualController
return $this->buildEmptyResponse();
}
$builder = new PhabricatorNotificationBuilder(array($story));
$builder = id(new PhabricatorNotificationBuilder(array($story)))
->setUser($viewer);
$content = $builder->buildView()->render();
$dict = $builder->buildDict();
$data = $dict[0];

View file

@ -16,7 +16,9 @@ final class PhabricatorNotificationPanelController
$clear_ui_class = 'phabricator-notification-clear-all';
$clear_uri = id(new PhutilURI('/notification/clear/'));
if ($stories) {
$builder = new PhabricatorNotificationBuilder($stories);
$builder = id(new PhabricatorNotificationBuilder($stories))
->setUser($viewer);
$notifications_view = $builder->buildView();
$content = $notifications_view->render();
$clear_uri->setQueryParam(
@ -69,8 +71,7 @@ final class PhabricatorNotificationPanelController
$content,
$connection_ui);
$unread_count = id(new PhabricatorFeedStoryNotification())
->countUnread($viewer);
$unread_count = $viewer->getUnreadNotificationCount();
$json = array(
'content' => $content,

View file

@ -60,20 +60,10 @@ final class PhabricatorFeedStoryNotification extends PhabricatorFeedDAO {
$object_phid);
unset($unguarded);
}
public function countUnread(PhabricatorUser $user) {
$conn = $this->establishConnection('r');
$data = queryfx_one(
$conn,
'SELECT COUNT(*) as count
FROM %T
WHERE userPHID = %s AND hasViewed = 0',
$this->getTableName(),
$user->getPHID());
return $data['count'];
$count_key = PhabricatorUserNotificationCountCacheType::KEY_COUNT;
PhabricatorUserCache::clearCache($count_key, $user->getPHID());
$user->clearCacheData($count_key);
}
}

View file

@ -11,8 +11,8 @@ final class PhabricatorOAuthServerAuthorizationsSettingsPanel
return pht('OAuth Authorizations');
}
public function getPanelGroup() {
return pht('Sessions and Logs');
public function getPanelGroupKey() {
return PhabricatorSettingsLogsPanelGroup::PANELGROUPKEY;
}
public function isEnabled() {

View file

@ -76,12 +76,6 @@ final class PhabricatorPasteApplication extends PhabricatorApplication {
);
}
public function getQuickCreateItems(PhabricatorUser $viewer) {
return id(new PhabricatorPasteEditEngine())
->setViewer($viewer)
->loadQuickCreateItems();
}
public function getMailCommandObjects() {
return array(
'paste' => array(

View file

@ -127,31 +127,6 @@ final class PhabricatorPeopleApplication extends PhabricatorApplication {
return $status;
}
public function getQuickCreateItems(PhabricatorUser $viewer) {
$items = array();
$can_create = PhabricatorPolicyFilter::hasCapability(
$viewer,
$this,
PeopleCreateUsersCapability::CAPABILITY);
if ($can_create) {
$item = id(new PHUIListItemView())
->setName(pht('User Account'))
->setIcon('fa-users')
->setHref($this->getBaseURI().'create/');
$items[] = $item;
} else if ($viewer->getIsAdmin()) {
$item = id(new PHUIListItemView())
->setName(pht('Bot Account'))
->setIcon('fa-android')
->setHref($this->getBaseURI().'new/bot/');
$items[] = $item;
}
return $items;
}
public function getApplicationSearchDocumentTypes() {
return array(
PhabricatorPeopleUserPHIDType::TYPECONST,

View file

@ -18,12 +18,16 @@ abstract class PhabricatorUserCacheType extends Phobject {
return array();
}
public function getValueFromStorage($value) {
return phutil_json_decode($value);
public function shouldValidateRawCacheData() {
return false;
}
public function getValueForStorage($value) {
return phutil_json_encode($value);
public function isRawCacheDataValid(PhabricatorUser $user, $key, $data) {
throw new PhutilMethodNotImplementedException();
}
public function getValueFromStorage($value) {
return $value;
}
public function newValueForUsers($key, array $users) {

View file

@ -0,0 +1,41 @@
<?php
final class PhabricatorUserMessageCountCacheType
extends PhabricatorUserCacheType {
const CACHETYPE = 'message.count';
const KEY_COUNT = 'user.message.count.v1';
public function getAutoloadKeys() {
return array(
self::KEY_COUNT,
);
}
public function canManageKey($key) {
return ($key === self::KEY_COUNT);
}
public function getValueFromStorage($value) {
return (int)$value;
}
public function newValueForUsers($key, array $users) {
if (!$users) {
return array();
}
$user_phids = mpull($users, 'getPHID');
$unread_status = ConpherenceParticipationStatus::BEHIND;
$unread = id(new ConpherenceParticipantCountQuery())
->withParticipantPHIDs($user_phids)
->withParticipationStatus($unread_status)
->execute();
$empty = array_fill_keys($user_phids, 0);
return $unread + $empty;
}
}

View file

@ -0,0 +1,46 @@
<?php
final class PhabricatorUserNotificationCountCacheType
extends PhabricatorUserCacheType {
const CACHETYPE = 'notification.count';
const KEY_COUNT = 'user.notification.count.v1';
public function getAutoloadKeys() {
return array(
self::KEY_COUNT,
);
}
public function canManageKey($key) {
return ($key === self::KEY_COUNT);
}
public function getValueFromStorage($value) {
return (int)$value;
}
public function newValueForUsers($key, array $users) {
if (!$users) {
return array();
}
$user_phids = mpull($users, 'getPHID');
$table = new PhabricatorFeedStoryNotification();
$conn_r = $table->establishConnection('r');
$rows = queryfx_all(
$conn_r,
'SELECT userPHID, COUNT(*) N FROM %T
WHERE userPHID IN (%Ls) AND hasViewed = 0
GROUP BY userPHID',
$table->getTableName(),
$user_phids);
$empty = array_fill_keys($user_phids, 0);
return ipull($rows, 'N', 'userPHID') + $empty;
}
}

View file

@ -17,15 +17,49 @@ final class PhabricatorUserPreferencesCacheType
return ($key === self::KEY_PREFERENCES);
}
public function getValueFromStorage($value) {
return phutil_json_decode($value);
}
public function newValueForUsers($key, array $users) {
$viewer = $this->getViewer();
$users = mpull($users, null, 'getPHID');
$user_phids = array_keys($users);
$preferences = id(new PhabricatorUserPreferencesQuery())
->setViewer($viewer)
->withUserPHIDs(mpull($users, 'getPHID'))
->withUserPHIDs($user_phids)
->execute();
return mpull($preferences, 'getPreferences', 'getUserPHID');
$all_settings = PhabricatorSetting::getAllSettings();
$settings = array();
foreach ($preferences as $preference) {
$user_phid = $preference->getUserPHID();
foreach ($all_settings as $key => $setting) {
$value = $preference->getSettingValue($key);
// As an optimization, we omit the value from the cache if it is
// exactly the same as the hardcoded default.
$default_value = id(clone $setting)
->setViewer($users[$user_phid])
->getSettingDefaultValue();
if ($value === $default_value) {
continue;
}
$settings[$user_phid][$key] = $value;
}
}
$results = array();
foreach ($user_phids as $user_phid) {
$value = idx($settings, $user_phid, array());
$results[$user_phid] = phutil_json_encode($value);
}
return $results;
}
}

View file

@ -0,0 +1,82 @@
<?php
final class PhabricatorUserProfileImageCacheType
extends PhabricatorUserCacheType {
const CACHETYPE = 'user.profile';
const KEY_URI = 'user.profile.image.uri.v1';
public function getAutoloadKeys() {
return array(
self::KEY_URI,
);
}
public function canManageKey($key) {
return ($key === self::KEY_URI);
}
public function getDefaultValue() {
return PhabricatorUser::getDefaultProfileImageURI();
}
public function newValueForUsers($key, array $users) {
$viewer = $this->getViewer();
$file_phids = mpull($users, 'getProfileImagePHID');
$file_phids = array_filter($file_phids);
if ($file_phids) {
$files = id(new PhabricatorFileQuery())
->setViewer($viewer)
->withPHIDs($file_phids)
->execute();
$files = mpull($files, null, 'getPHID');
} else {
$files = array();
}
$results = array();
foreach ($users as $user) {
$image_phid = $user->getProfileImagePHID();
if (isset($files[$image_phid])) {
$image_uri = $files[$image_phid]->getBestURI();
} else {
$image_uri = PhabricatorUser::getDefaultProfileImageURI();
}
$user_phid = $user->getPHID();
$version = $this->getCacheVersion($user);
$results[$user_phid] = "{$version},{$image_uri}";
}
return $results;
}
public function getValueFromStorage($value) {
$parts = explode(',', $value, 2);
return end($parts);
}
public function shouldValidateRawCacheData() {
return true;
}
public function isRawCacheDataValid(PhabricatorUser $user, $key, $data) {
$parts = explode(',', $data, 2);
$version = reset($parts);
return ($version === $this->getCacheVersion($user));
}
private function getCacheVersion(PhabricatorUser $user) {
$parts = array(
PhabricatorEnv::getCDNURI('/'),
PhabricatorEnv::getEnvConfig('cluster.instance'),
$user->getProfileImagePHID(),
);
$parts = serialize($parts);
return PhabricatorHash::digestForIndex($parts);
}
}

View file

@ -124,7 +124,7 @@ final class PhabricatorPeopleProfileManageController
->setName(pht('Edit Settings'))
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit)
->setHref('/settings/'.$user->getID().'/'));
->setHref('/settings/user/'.$user->getUsername().'/'));
if ($user->getIsAdmin()) {
$empower_icon = 'fa-arrow-circle-o-down';

View file

@ -7,15 +7,7 @@ final class PhabricatorPeopleMainMenuBarExtension
public function buildMainMenus() {
$viewer = $this->getViewer();
// TODO: This should get cached.
$profile = id(new PhabricatorPeopleQuery())
->setViewer($viewer)
->needProfileImage(true)
->withPHIDs(array($viewer->getPHID()))
->executeOne();
$image = $profile->getProfileImageURI();
$image = $viewer->getProfileImageURI();
$bar_item = id(new PHUIListItemView())
->setName($viewer->getUsername())

View file

@ -23,6 +23,7 @@ final class PhabricatorPeopleQuery
private $needProfileImage;
private $needAvailability;
private $needBadges;
private $cacheKeys = array();
public function withIDs(array $ids) {
$this->ids = $ids;
@ -105,7 +106,14 @@ final class PhabricatorPeopleQuery
}
public function needProfileImage($need) {
$this->needProfileImage = $need;
$cache_key = PhabricatorUserProfileImageCacheType::KEY_URI;
if ($need) {
$this->cacheKeys[$cache_key] = true;
} else {
unset($this->cacheKeys[$cache_key]);
}
return $this;
}
@ -119,6 +127,18 @@ final class PhabricatorPeopleQuery
return $this;
}
public function needUserSettings($need) {
$cache_key = PhabricatorUserPreferencesCacheType::KEY_PREFERENCES;
if ($need) {
$this->cacheKeys[$cache_key] = true;
} else {
unset($this->cacheKeys[$cache_key]);
}
return $this;
}
public function newResultObject() {
return new PhabricatorUser();
}
@ -169,59 +189,6 @@ final class PhabricatorPeopleQuery
}
}
if ($this->needProfileImage) {
$rebuild = array();
foreach ($users as $user) {
$image_uri = $user->getProfileImageCache();
if ($image_uri) {
// This user has a valid cache, so we don't need to fetch any
// data or rebuild anything.
$user->attachProfileImageURI($image_uri);
continue;
}
// This user's cache is invalid or missing, so we're going to rebuild
// it.
$rebuild[] = $user;
}
if ($rebuild) {
$file_phids = mpull($rebuild, 'getProfileImagePHID');
$file_phids = array_filter($file_phids);
if ($file_phids) {
// NOTE: We're using the omnipotent user here because older profile
// images do not have the 'profile' flag, so they may not be visible
// to the executing viewer. At some point, we could migrate to add
// this flag and then use the real viewer, or just use the real
// viewer after enough time has passed to limit the impact of old
// data. The consequence of missing here is that we cache a default
// image when a real image exists.
$files = id(new PhabricatorFileQuery())
->setParentQuery($this)
->setViewer(PhabricatorUser::getOmnipotentUser())
->withPHIDs($file_phids)
->execute();
$files = mpull($files, null, 'getPHID');
} else {
$files = array();
}
foreach ($rebuild as $user) {
$image_phid = $user->getProfileImagePHID();
if (isset($files[$image_phid])) {
$image_uri = $files[$image_phid]->getBestURI();
} else {
$image_uri = PhabricatorUser::getDefaultProfileImageURI();
}
$user->writeProfileImageCache($image_uri);
$user->attachProfileImageURI($image_uri);
}
}
}
if ($this->needAvailability) {
$rebuild = array();
foreach ($users as $user) {
@ -238,6 +205,8 @@ final class PhabricatorPeopleQuery
}
}
$this->fillUserCaches($users);
return $users;
}
@ -481,4 +450,120 @@ final class PhabricatorPeopleQuery
}
}
private function fillUserCaches(array $users) {
if (!$this->cacheKeys) {
return;
}
$user_map = mpull($users, null, 'getPHID');
$keys = array_keys($this->cacheKeys);
$hashes = array();
foreach ($keys as $key) {
$hashes[] = PhabricatorHash::digestForIndex($key);
}
$types = PhabricatorUserCacheType::getAllCacheTypes();
// First, pull any available caches. If we wanted to be particularly clever
// we could do this with JOINs in the main query.
$cache_table = new PhabricatorUserCache();
$cache_conn = $cache_table->establishConnection('r');
$cache_data = queryfx_all(
$cache_conn,
'SELECT cacheKey, userPHID, cacheData, cacheType FROM %T
WHERE cacheIndex IN (%Ls) AND userPHID IN (%Ls)',
$cache_table->getTableName(),
$hashes,
array_keys($user_map));
$skip_validation = array();
// After we read caches from the database, discard any which have data that
// invalid or out of date. This allows cache types to implement TTLs or
// versions instead of or in addition to explicit cache clears.
foreach ($cache_data as $row_key => $row) {
$cache_type = $row['cacheType'];
if (isset($skip_validation[$cache_type])) {
continue;
}
if (empty($types[$cache_type])) {
unset($cache_data[$row_key]);
continue;
}
$type = $types[$cache_type];
if (!$type->shouldValidateRawCacheData()) {
$skip_validation[$cache_type] = true;
continue;
}
$user = $user_map[$row['userPHID']];
$raw_data = $row['cacheData'];
if (!$type->isRawCacheDataValid($user, $row['cacheKey'], $raw_data)) {
unset($cache_data[$row_key]);
continue;
}
}
$need = array();
$cache_data = igroup($cache_data, 'userPHID');
foreach ($user_map as $user_phid => $user) {
$raw_rows = idx($cache_data, $user_phid, array());
$raw_data = ipull($raw_rows, 'cacheData', 'cacheKey');
foreach ($keys as $key) {
if (isset($raw_data[$key]) || array_key_exists($key, $raw_data)) {
continue;
}
$need[$key][$user_phid] = $user;
}
$user->attachRawCacheData($raw_data);
}
// If we missed any cache values, bulk-construct them now. This is
// usually much cheaper than generating them on-demand for each user
// record.
if (!$need) {
return;
}
$writes = array();
foreach ($need as $cache_key => $need_users) {
$type = PhabricatorUserCacheType::getCacheTypeForKey($cache_key);
if (!$type) {
continue;
}
$data = $type->newValueForUsers($cache_key, $need_users);
foreach ($data as $user_phid => $raw_value) {
$data[$user_phid] = $raw_value;
$writes[] = array(
'userPHID' => $user_phid,
'key' => $cache_key,
'type' => $type,
'value' => $raw_value,
);
}
foreach ($need_users as $user_phid => $user) {
if (isset($data[$user_phid]) || array_key_exists($user_phid, $data)) {
$user->attachRawCacheData(
array(
$cache_key => $data[$user_phid],
));
}
}
}
PhabricatorUserCache::writeCaches($writes);
}
}

View file

@ -30,14 +30,9 @@ final class PhabricatorUser
protected $passwordSalt;
protected $passwordHash;
protected $profileImagePHID;
protected $profileImageCache;
protected $availabilityCache;
protected $availabilityCacheTTL;
protected $consoleEnabled = 0;
protected $consoleVisible = 0;
protected $consoleTab = '';
protected $conduitCertificate;
protected $isSystemAgent = 0;
@ -50,7 +45,6 @@ final class PhabricatorUser
protected $accountSecret;
private $profileImage = self::ATTACHABLE;
private $profile = null;
private $availability = self::ATTACHABLE;
private $preferences = null;
@ -66,7 +60,10 @@ final class PhabricatorUser
private $authorities = array();
private $handlePool;
private $csrfSalt;
private $timezoneOverride;
private $settingCacheKeys = array();
private $settingCache = array();
private $allowInlineCacheGeneration;
protected function readField($field) {
switch ($field) {
@ -188,9 +185,6 @@ final class PhabricatorUser
'passwordSalt' => 'text32?',
'passwordHash' => 'text128?',
'profileImagePHID' => 'phid?',
'consoleEnabled' => 'bool',
'consoleVisible' => 'bool',
'consoleTab' => 'text64',
'conduitCertificate' => 'text255',
'isSystemAgent' => 'bool',
'isMailingList' => 'bool',
@ -200,7 +194,6 @@ final class PhabricatorUser
'isApproved' => 'uint32',
'accountSecret' => 'bytes64',
'isEnrolledInMultiFactor' => 'bool',
'profileImageCache' => 'text255?',
'availabilityCache' => 'text255?',
'availabilityCacheTTL' => 'uint32?',
),
@ -222,7 +215,6 @@ final class PhabricatorUser
),
),
self::CONFIG_NO_MUTATE => array(
'profileImageCache' => true,
'availabilityCache' => true,
'availabilityCacheTTL' => true,
),
@ -481,19 +473,54 @@ final class PhabricatorUser
public function getUserSetting($key) {
// NOTE: We store available keys and cached values separately to make it
// faster to check for `null` in the cache, which is common.
if (isset($this->settingCacheKeys[$key])) {
return $this->settingCache[$key];
}
$settings_key = PhabricatorUserPreferencesCacheType::KEY_PREFERENCES;
if ($this->getPHID()) {
$settings = $this->requireCacheData($settings_key);
} else {
$settings = array();
}
// NOTE: To slightly improve performance, we're using all settings here,
// not just settings that are enabled for the current viewer. It's fine to
// get the value of a setting that we wouldn't let the user edit in the UI.
$defaults = PhabricatorSetting::getAllSettings();
if (array_key_exists($key, $settings)) {
return $settings[$key];
}
$value = $settings[$key];
$defaults = PhabricatorSetting::getAllEnabledSettings($this);
// Make sure the value is valid before we return it. This makes things
// more robust when options are changed or removed.
if (isset($defaults[$key])) {
return $defaults[$key]->getSettingDefaultValue();
try {
id(clone $defaults[$key])
->setViewer($this)
->assertValidValue($value);
return $this->writeUserSettingCache($key, $value);
} catch (Exception $ex) {
// Fall through below and return the default value.
}
} else {
// This is an ad-hoc setting with no controlling object.
return $this->writeUserSettingCache($key, $value);
}
}
return null;
if (isset($defaults[$key])) {
$value = id(clone $defaults[$key])
->setViewer($this)
->getSettingDefaultValue();
} else {
$value = null;
}
return $this->writeUserSettingCache($key, $value);
}
@ -510,15 +537,17 @@ final class PhabricatorUser
return ($actual == $value);
}
private function writeUserSettingCache($key, $value) {
$this->settingCacheKeys[$key] = true;
$this->settingCache[$key] = $value;
return $value;
}
public function getTranslation() {
return $this->getUserSetting(PhabricatorTranslationSetting::SETTINGKEY);
}
public function getTimezoneIdentifier() {
if ($this->timezoneOverride) {
return $this->timezoneOverride;
}
return $this->getUserSetting(PhabricatorTimezoneSetting::SETTINGKEY);
}
@ -533,7 +562,9 @@ final class PhabricatorUser
* @task settings
*/
public function overrideTimezoneIdentifier($identifier) {
$this->timezoneOverride = $identifier;
$timezone_key = PhabricatorTimezoneSetting::SETTINGKEY;
$this->settingCacheKeys[$timezone_key] = true;
$this->settingCache[$timezone_key] = $identifier;
return $this;
}
@ -541,54 +572,22 @@ final class PhabricatorUser
return $this->getUserSetting(PhabricatorPronounSetting::SETTINGKEY);
}
public function loadPreferences() {
if ($this->preferences) {
return $this->preferences;
}
$preferences = null;
if ($this->getPHID()) {
$preferences = id(new PhabricatorUserPreferencesQuery())
->setViewer($this)
->withUsers(array($this))
->executeOne();
}
if (!$preferences) {
$preferences = new PhabricatorUserPreferences();
$preferences->setUserPHID($this->getPHID());
$preferences->attachUser($this);
$default_dict = array(
PhabricatorUserPreferences::PREFERENCE_TITLES => 'glyph',
PhabricatorUserPreferences::PREFERENCE_EDITOR => '',
PhabricatorUserPreferences::PREFERENCE_MONOSPACED => '',
PhabricatorUserPreferences::PREFERENCE_DARK_CONSOLE => 0,
);
$preferences->setPreferences($default_dict);
}
$this->preferences = $preferences;
return $preferences;
}
public function loadEditorLink(
$path,
$line,
PhabricatorRepository $repository = null) {
$editor = $this->loadPreferences()->getPreference(
PhabricatorUserPreferences::PREFERENCE_EDITOR);
$editor = $this->getUserSetting(PhabricatorEditorSetting::SETTINGKEY);
if (is_array($path)) {
$multiedit = $this->loadPreferences()->getPreference(
PhabricatorUserPreferences::PREFERENCE_MULTIEDIT);
$multi_key = PhabricatorEditorMultipleSetting::SETTINGKEY;
$multiedit = $this->getUserSetting($multi_key);
switch ($multiedit) {
case '':
case PhabricatorEditorMultipleSetting::VALUE_SPACES:
$path = implode(' ', $path);
break;
case 'disable':
case PhabricatorEditorMultipleSetting::VALUE_SINGLE:
default:
return null;
}
}
@ -791,13 +790,19 @@ final class PhabricatorUser
return celerity_get_resource_uri('/rsrc/image/avatar.png');
}
public function attachProfileImageURI($uri) {
$this->profileImage = $uri;
return $this;
public function getProfileImageURI() {
$uri_key = PhabricatorUserProfileImageCacheType::KEY_URI;
return $this->requireCacheData($uri_key);
}
public function getProfileImageURI() {
return $this->assertAttached($this->profileImage);
public function getUnreadNotificationCount() {
$notification_key = PhabricatorUserNotificationCountCacheType::KEY_COUNT;
return $this->requireCacheData($notification_key);
}
public function getUnreadMessageCount() {
$message_key = PhabricatorUserMessageCountCacheType::KEY_COUNT;
return $this->requireCacheData($message_key);
}
public function getFullName() {
@ -848,48 +853,13 @@ final class PhabricatorUser
$format = 'M j';
} else {
// Same year, month and day so show a time of day.
$pref_time = PhabricatorUserPreferences::PREFERENCE_TIME_FORMAT;
$format = $this->getPreference($pref_time);
$pref_time = PhabricatorTimeFormatSetting::SETTINGKEY;
$format = $this->getUserSetting($pref_time);
}
return $when->format($format);
}
public function getPreference($key) {
$preferences = $this->loadPreferences();
// TODO: After T4103 and T7707 this should eventually be pushed down the
// stack into modular preference definitions and role profiles. This is
// just fixing T8601 and mildly anticipating those changes.
$value = $preferences->getPreference($key);
$allowed_values = null;
switch ($key) {
case PhabricatorUserPreferences::PREFERENCE_TIME_FORMAT:
$allowed_values = array(
'g:i A',
'H:i',
);
break;
case PhabricatorUserPreferences::PREFERENCE_DATE_FORMAT:
$allowed_values = array(
'Y-m-d',
'n/j/Y',
'd-m-Y',
);
break;
}
if ($allowed_values !== null) {
$allowed_values = array_fuse($allowed_values);
if (empty($allowed_values[$value])) {
$value = head($allowed_values);
}
}
return $value;
}
public function __toString() {
return $this->getUsername();
}
@ -1043,72 +1013,6 @@ final class PhabricatorUser
}
/* -( Profile Image Cache )------------------------------------------------ */
/**
* Get this user's cached profile image URI.
*
* @return string|null Cached URI, if a URI is cached.
* @task image-cache
*/
public function getProfileImageCache() {
$version = $this->getProfileImageVersion();
$parts = explode(',', $this->profileImageCache, 2);
if (count($parts) !== 2) {
return null;
}
if ($parts[0] !== $version) {
return null;
}
return $parts[1];
}
/**
* Generate a new cache value for this user's profile image.
*
* @return string New cache value.
* @task image-cache
*/
public function writeProfileImageCache($uri) {
$version = $this->getProfileImageVersion();
$cache = "{$version},{$uri}";
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
queryfx(
$this->establishConnection('w'),
'UPDATE %T SET profileImageCache = %s WHERE id = %d',
$this->getTableName(),
$cache,
$this->getID());
unset($unguarded);
}
/**
* Get a version identifier for a user's profile image.
*
* This version will change if the image changes, or if any of the
* environment configuration which goes into generating a URI changes.
*
* @return string Cache version.
* @task image-cache
*/
private function getProfileImageVersion() {
$parts = array(
PhabricatorEnv::getCDNURI('/'),
PhabricatorEnv::getEnvConfig('cluster.instance'),
$this->getProfileImagePHID(),
);
$parts = serialize($parts);
return PhabricatorHash::digestForIndex($parts);
}
/* -( Multi-Factor Authentication )---------------------------------------- */
@ -1526,6 +1430,10 @@ final class PhabricatorUser
return $this;
}
public function setAllowInlineCacheGeneration($allow_cache_generation) {
$this->allowInlineCacheGeneration = $allow_cache_generation;
return $this;
}
/**
* @task cache
@ -1546,14 +1454,20 @@ final class PhabricatorUser
return $usable_value;
}
// By default, we throw if a cache isn't available. This is consistent
// with the standard `needX()` + `attachX()` + `getX()` interaction.
if (!$this->allowInlineCacheGeneration) {
throw new PhabricatorDataNotAttachedException($this);
}
$usable_value = $type->getDefaultValue();
$user_phid = $this->getPHID();
if ($user_phid) {
$map = $type->newValueForUsers($key, array($this));
if (array_key_exists($user_phid, $map)) {
$usable_value = $map[$user_phid];
$raw_value = $type->getValueForStorage($usable_value);
$raw_value = $map[$user_phid];
$usable_value = $type->getValueFromStorage($raw_value);
$this->rawCacheData[$key] = $raw_value;
PhabricatorUserCache::writeCache(

View file

@ -42,36 +42,73 @@ final class PhabricatorUserCache extends PhabricatorUserDAO {
$key,
$user_phid,
$raw_value) {
self::writeCaches(
array(
array(
'type' => $type,
'key' => $key,
'userPHID' => $user_phid,
'value' => $raw_value,
),
));
}
public static function writeCaches(array $values) {
if (PhabricatorEnv::isReadOnly()) {
return;
}
if (!$values) {
return;
}
$table = new self();
$conn_w = $table->establishConnection('w');
$sql = array();
foreach ($values as $value) {
$key = $value['key'];
$sql[] = qsprintf(
$conn_w,
'(%s, %s, %s, %s, %s)',
$value['userPHID'],
PhabricatorHash::digestForIndex($key),
$key,
$value['value'],
$value['type']->getUserCacheType());
}
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
foreach (PhabricatorLiskDAO::chunkSQL($sql) as $chunk) {
queryfx(
$conn_w,
'INSERT INTO %T (userPHID, cacheIndex, cacheKey, cacheData, cacheType)
VALUES (%s, %s, %s, %s, %s)
ON DUPLICATE KEY UPDATE cacheData = VALUES(cacheData)',
VALUES %Q
ON DUPLICATE KEY UPDATE
cacheData = VALUES(cacheData),
cacheType = VALUES(cacheType)',
$table->getTableName(),
$user_phid,
PhabricatorHash::digestForIndex($key),
$key,
$raw_value,
$type->getUserCacheType());
$chunk);
}
unset($unguarded);
}
public static function clearCache($key, $user_phid) {
return self::clearCaches($key, array($user_phid));
}
public static function clearCaches($key, array $user_phids) {
if (PhabricatorEnv::isReadOnly()) {
return;
}
if (!$user_phids) {
return;
}
$table = new self();
$conn_w = $table->establishConnection('w');
@ -79,15 +116,14 @@ final class PhabricatorUserCache extends PhabricatorUserDAO {
queryfx(
$conn_w,
'DELETE FROM %T WHERE cacheIndex = %s AND userPHID = %s',
'DELETE FROM %T WHERE cacheIndex = %s AND userPHID IN (%Ls)',
$table->getTableName(),
PhabricatorHash::digestForIndex($key),
$user_phid);
$user_phids);
unset($unguarded);
}
public static function clearCacheForAllUsers($key) {
if (PhabricatorEnv::isReadOnly()) {
return;

View file

@ -59,18 +59,6 @@ final class PhabricatorPholioApplication extends PhabricatorApplication {
);
}
public function getQuickCreateItems(PhabricatorUser $viewer) {
$items = array();
$item = id(new PHUIListItemView())
->setName(pht('Pholio Mock'))
->setIcon('fa-picture-o')
->setHref($this->getBaseURI().'create/');
$items[] = $item;
return $items;
}
protected function getCustomCapabilities() {
return array(
PholioDefaultViewCapability::CAPABILITY => array(

View file

@ -267,12 +267,12 @@ final class PholioMockEditController extends PholioController {
$image_elements);
$drop_control = phutil_tag(
'div',
'a',
array(
'id' => $drop_id,
'class' => 'pholio-edit-drop',
),
pht('Drag and drop images here to add them to the mock.'));
pht('Click here, or drag and drop images to add them to the mock.'));
$order_control = phutil_tag(
'input',

View file

@ -137,9 +137,12 @@ final class PholioImageQuery
$all_files = mpull($all_files, null, 'getPHID');
if ($this->needInlineComments) {
$all_inline_comments = id(new PholioTransactionComment())
->loadAllWhere('imageid IN (%Ld)',
mpull($images, 'getID'));
// Only load inline comments the viewer has permission to see.
$all_inline_comments = id(new PholioTransactionComment())->loadAllWhere(
'imageID IN (%Ld)
AND (transactionPHID IS NOT NULL OR authorPHID = %s)',
mpull($images, 'getID'),
$this->getViewer()->getPHID());
$all_inline_comments = mgroup($all_inline_comments, 'getImageID');
}

View file

@ -42,11 +42,12 @@ final class PholioUploadedImageView extends AphrontView {
PhabricatorFileThumbnailTransform::TRANSFORM_PINBOARD);
$thumbnail_uri = $file->getURIForTransform($xform);
$thumb_img = phutil_tag(
$thumb_img = javelin_tag(
'img',
array(
'class' => 'pholio-thumb-img',
'src' => $thumbnail_uri,
'sigil' => 'pholio-uploaded-thumb',
));
$thumb_frame = phutil_tag(

View file

@ -8,6 +8,7 @@ final class PhortuneCartViewController
$id = $request->getURIData('id');
$authority = $this->loadMerchantAuthority();
require_celerity_resource('phortune-css');
$query = id(new PhortuneCartQuery())
->setViewer($viewer)
@ -208,6 +209,7 @@ final class PhortuneCartViewController
return $this->newPage()
->setTitle(pht('Cart %d', $cart->getID()))
->setCrumbs($crumbs)
->addClass('phortune-cart-page')
->appendChild($view);
}

View file

@ -45,61 +45,20 @@ final class PhrictionDiffController extends PhrictionController {
$text_l = $content_l->getContent();
$text_r = $content_r->getContent();
$text_l = phutil_utf8_hard_wrap($text_l, 80);
$text_l = implode("\n", $text_l);
$text_r = phutil_utf8_hard_wrap($text_r, 80);
$text_r = implode("\n", $text_r);
$diff_view = id(new PhabricatorApplicationTransactionTextDiffDetailView())
->setOldText($text_l)
->setNewText($text_r);
$engine = new PhabricatorDifferenceEngine();
$changeset = $engine->generateChangesetFromFileContent($text_l, $text_r);
$changeset->setFilename($content_r->getTitle());
$changeset->setOldProperties(
array(
'Title' => $content_l->getTitle(),
));
$changeset->setNewProperties(
array(
'Title' => $content_r->getTitle(),
));
$whitespace_mode = DifferentialChangesetParser::WHITESPACE_SHOW_ALL;
$parser = id(new DifferentialChangesetParser())
->setUser($viewer)
->setChangeset($changeset)
->setRenderingReference("{$l},{$r}");
$parser->readParametersFromRequest($request);
$parser->setWhitespaceMode($whitespace_mode);
$engine = new PhabricatorMarkupEngine();
$engine->setViewer($viewer);
$engine->process();
$parser->setMarkupEngine($engine);
$spec = $request->getStr('range');
list($range_s, $range_e, $mask) =
DifferentialChangesetParser::parseRangeSpecification($spec);
$parser->setRange($range_s, $range_e);
$parser->setMask($mask);
if ($request->isAjax()) {
return id(new PhabricatorChangesetResponse())
->setRenderedChangeset($parser->renderChangeset());
}
$changes = id(new DifferentialChangesetListView())
->setUser($this->getViewer())
->setChangesets(array($changeset))
->setVisibleChangesets(array($changeset))
->setRenderingReferences(array("{$l},{$r}"))
->setRenderURI('/phriction/diff/'.$document->getID().'/')
->setTitle(pht('Changes'))
$changes = id(new PHUIObjectBoxView())
->setHeaderText(pht('Content Changes'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setParser($parser);
->appendChild(
phutil_tag(
'div',
array(
'class' => 'prose-diff-frame',
),
$diff_view));
require_celerity_resource('phriction-document-css');

View file

@ -16,7 +16,15 @@ final class PhrictionRemarkupRule extends PhutilRemarkupRule {
}
public function markupDocumentLink(array $matches) {
$link = trim($matches[1]);
// If the link contains an anchor, separate that off first.
$parts = explode('#', trim($matches[1]), 2);
if (count($parts) == 2) {
$link = $parts[0];
$anchor = $parts[1];
} else {
$link = $parts[0];
$anchor = null;
}
// Handle relative links.
if ((substr($link, 0, 2) === './') || (substr($link, 0, 3) === '../')) {
@ -67,6 +75,7 @@ final class PhrictionRemarkupRule extends PhutilRemarkupRule {
$metadata[] = array(
'token' => $token,
'link' => $link,
'anchor' => $anchor,
'explicitName' => $name,
);
$engine->setTextMetadata(self::KEY_RULE_PHRICTION_LINK, $metadata);
@ -142,10 +151,11 @@ final class PhrictionRemarkupRule extends PhutilRemarkupRule {
$uri = new PhutilURI($link);
$slug = $uri->getPath();
$fragment = $uri->getFragment();
$slug = PhabricatorSlug::normalize($slug);
$slug = PhrictionDocument::getSlugURI($slug);
$href = (string)id(new PhutilURI($slug))->setFragment($fragment);
$anchor = idx($spec, 'anchor');
$href = (string)id(new PhutilURI($slug))->setFragment($anchor);
$text_mode = $this->getEngine()->isTextMode();
$mail_mode = $this->getEngine()->isHTMLMailMode();

View file

@ -281,10 +281,8 @@ final class PhabricatorPolicyEditController
// Save this project as one of the user's most recently used projects,
// so we'll show it by default in future menus.
$pref_key = PhabricatorUserPreferences::PREFERENCE_FAVORITE_POLICIES;
$preferences = $viewer->loadPreferences();
$favorites = $preferences->getPreference($pref_key);
$favorites_key = PhabricatorPolicyFavoritesSetting::SETTINGKEY;
$favorites = $viewer->getUserSetting($favorites_key);
if (!is_array($favorites)) {
$favorites = array();
}
@ -293,8 +291,17 @@ final class PhabricatorPolicyEditController
unset($favorites[$project_phid]);
$favorites[$project_phid] = true;
$preferences->setPreference($pref_key, $favorites);
$preferences->save();
$preferences = PhabricatorUserPreferences::loadUserPreferences($viewer);
$editor = id(new PhabricatorUserPreferencesEditor())
->setActor($viewer)
->setContentSourceFromRequest($request)
->setContinueOnNoEffect(true)
->setContinueOnMissingFields(true);
$xactions = array();
$xactions[] = $preferences->newTransaction($favorites_key, $favorites);
$editor->applyTransactions($preferences, $xactions);
$data = array(
'phid' => $project->getPHID(),

View file

@ -195,7 +195,7 @@ final class PhabricatorPolicyQuery
$viewer = $this->getViewer();
if ($viewer->getPHID()) {
$pref_key = PhabricatorUserPreferences::PREFERENCE_FAVORITE_POLICIES;
$pref_key = PhabricatorPolicyFavoritesSetting::SETTINGKEY;
$favorite_limit = 10;
$default_limit = 5;

View file

@ -34,6 +34,21 @@ final class PhabricatorPonderApplication extends PhabricatorApplication {
);
}
public function supportsEmailIntegration() {
return true;
}
public function getAppEmailBlurb() {
return pht(
'Send email to these addresses to create questions. %s',
phutil_tag(
'a',
array(
'href' => $this->getInboundEmailSupportLink(),
),
pht('Learn More')));
}
public function getRoutes() {
return array(
'/Q(?P<id>[1-9]\d*)'

View file

@ -0,0 +1,49 @@
<?php
final class PonderQuestionCreateMailReceiver extends PhabricatorMailReceiver {
public function isEnabled() {
$app_class = 'PhabricatorPonderApplication';
return PhabricatorApplication::isClassInstalled($app_class);
}
public function canAcceptMail(PhabricatorMetaMTAReceivedMail $mail) {
$ponder_app = new PhabricatorPonderApplication();
return $this->canAcceptApplicationMail($ponder_app, $mail);
}
protected function processReceivedMail(
PhabricatorMetaMTAReceivedMail $mail,
PhabricatorUser $sender) {
$title = $mail->getSubject();
if (!strlen($title)) {
$title = pht('New Question');
}
$xactions = array();
$xactions[] = id(new PonderQuestionTransaction())
->setTransactionType(PonderQuestionTransaction::TYPE_TITLE)
->setNewValue($title);
$xactions[] = id(new PonderQuestionTransaction())
->setTransactionType(PonderQuestionTransaction::TYPE_CONTENT)
->setNewValue($mail->getCleanTextBody());
$question = PonderQuestion::initializeNewQuestion($sender);
$content_source = $mail->newContentSource();
$editor = id(new PonderQuestionEditor())
->setActor($sender)
->setContentSource($content_source)
->setContinueOnNoEffect(true);
$xactions = $editor->applyTransactions($question, $xactions);
$mail->setRelatedPHID($question->getPHID());
}
}

View file

@ -48,6 +48,7 @@ final class PonderQuestion extends PonderDAO
->setViewPolicy($view_policy)
->setStatus(PonderQuestionStatus::STATUS_OPEN)
->setAnswerCount(0)
->setAnswerWiki('')
->setSpacePHID($actor->getDefaultSpacePHID());
}

Some files were not shown because too many files have changed in this diff Show more