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:
commit
55693ec631
219 changed files with 4068 additions and 2295 deletions
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE {$NAMESPACE}_user.user
|
||||
DROP COLUMN consoleEnabled;
|
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE {$NAMESPACE}_user.user
|
||||
DROP COLUMN consoleTab;
|
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE {$NAMESPACE}_user.user
|
||||
DROP COLUMN consoleVisible;
|
|
@ -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);
|
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE {$NAMESPACE}_user.user
|
||||
DROP COLUMN profileImageCache;
|
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE {$NAMESPACE}_user.user_preferences
|
||||
CHANGE userPHID userPHID VARBINARY(64);
|
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE {$NAMESPACE}_user.user_preferences
|
||||
ADD builtinKey VARCHAR(32) COLLATE {$COLLATE_TEXT};
|
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE {$NAMESPACE}_user.user_preferences
|
||||
ADD UNIQUE KEY `key_builtin` (builtinKey);
|
|
@ -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';
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -495,4 +495,12 @@ abstract class PhabricatorAuthProvider extends Phobject {
|
|||
}
|
||||
}
|
||||
|
||||
public function supportsAutoLogin() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getAutoLoginURI(AphrontRequest $request) {
|
||||
throw new PhutilMethodNotImplementedException();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 )--------------------------------------------- */
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -487,6 +487,10 @@ final class PhabricatorConduitAPIController
|
|||
}
|
||||
|
||||
$request->setUser($user);
|
||||
|
||||
id(new PhabricatorAuthSessionEngine())
|
||||
->willServeRequestForUser($user);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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`.")),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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/.*',
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
&&
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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.');
|
||||
}
|
||||
|
||||
}
|
|
@ -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')),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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.'))
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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');
|
||||
|
||||
|
|
|
@ -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');
|
||||
|
||||
|
|
|
@ -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 )----------------------------------------- */
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -18,6 +18,10 @@ final class PhabricatorNotificationClearController
|
|||
$viewer->getPHID(),
|
||||
$chrono_key);
|
||||
|
||||
PhabricatorUserCache::clearCache(
|
||||
PhabricatorUserNotificationCountCacheType::KEY_COUNT,
|
||||
$viewer->getPHID());
|
||||
|
||||
return id(new AphrontReloadResponse())
|
||||
->setURI('/notification/');
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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) {
|
||||
|
|
41
src/applications/people/cache/PhabricatorUserMessageCountCacheType.php
vendored
Normal file
41
src/applications/people/cache/PhabricatorUserMessageCountCacheType.php
vendored
Normal 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;
|
||||
}
|
||||
|
||||
}
|
46
src/applications/people/cache/PhabricatorUserNotificationCountCacheType.php
vendored
Normal file
46
src/applications/people/cache/PhabricatorUserNotificationCountCacheType.php
vendored
Normal 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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
82
src/applications/people/cache/PhabricatorUserProfileImageCacheType.php
vendored
Normal file
82
src/applications/people/cache/PhabricatorUserProfileImageCacheType.php
vendored
Normal 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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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';
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
@ -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');
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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*)'
|
||||
|
|
|
@ -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());
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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
Loading…
Reference in a new issue