1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-23 23:32:40 +01:00

(stable) Promote 2016 Week 46

This commit is contained in:
epriestley 2016-11-11 17:08:27 -08:00
commit b285d3cebf
133 changed files with 1933 additions and 870 deletions

View file

@ -7,12 +7,12 @@
*/
return array(
'names' => array(
'conpherence.pkg.css' => 'cea72e09',
'conpherence.pkg.css' => '0b64e988',
'conpherence.pkg.js' => '6249a1cf',
'core.pkg.css' => '46d588e4',
'core.pkg.js' => '035325a7',
'core.pkg.css' => 'a729d20e',
'core.pkg.js' => '1a77dddf',
'darkconsole.pkg.js' => 'e7393ebb',
'differential.pkg.css' => 'e1d704ce',
'differential.pkg.css' => 'a4ba74b5',
'differential.pkg.js' => '634399e9',
'diffusion.pkg.css' => '91c5d3a6',
'diffusion.pkg.js' => '84c8f8fd',
@ -21,7 +21,7 @@ return array(
'maniphest.pkg.js' => '949a7498',
'rsrc/css/aphront/aphront-bars.css' => '231ac33c',
'rsrc/css/aphront/dark-console.css' => 'f54bf286',
'rsrc/css/aphront/dialog-view.css' => '593d3f67',
'rsrc/css/aphront/dialog-view.css' => 'ea3745f5',
'rsrc/css/aphront/lightbox-attachment.css' => '7acac05d',
'rsrc/css/aphront/list-filter-view.css' => '5d6f0526',
'rsrc/css/aphront/multi-column.css' => '84cc6640',
@ -29,7 +29,7 @@ return array(
'rsrc/css/aphront/panel-view.css' => '8427b78d',
'rsrc/css/aphront/phabricator-nav-view.css' => 'b29426e9',
'rsrc/css/aphront/table-view.css' => '3225137a',
'rsrc/css/aphront/tokenizer.css' => '056da01b',
'rsrc/css/aphront/tokenizer.css' => '9a8cb501',
'rsrc/css/aphront/tooltip.css' => '1a07aea8',
'rsrc/css/aphront/typeahead-browse.css' => '8904346a',
'rsrc/css/aphront/typeahead.css' => 'd4f16145',
@ -39,7 +39,7 @@ return array(
'rsrc/css/application/base/notification-menu.css' => '1e055865',
'rsrc/css/application/base/phabricator-application-launch-view.css' => '95351601',
'rsrc/css/application/base/phui-theme.css' => '798c69b8',
'rsrc/css/application/base/standard-page-view.css' => '79176f5a',
'rsrc/css/application/base/standard-page-view.css' => '894d8a25',
'rsrc/css/application/chatlog/chatlog.css' => 'd295b020',
'rsrc/css/application/conduit/conduit-api.css' => '7bc725c4',
'rsrc/css/application/config/config-options.css' => '0ede4c9b',
@ -50,7 +50,7 @@ return array(
'rsrc/css/application/conpherence/durable-column.css' => 'd82e130c',
'rsrc/css/application/conpherence/header-pane.css' => '1c81cda6',
'rsrc/css/application/conpherence/menu.css' => '4f51db5a',
'rsrc/css/application/conpherence/message-pane.css' => '394ae8fa',
'rsrc/css/application/conpherence/message-pane.css' => 'b085d40d',
'rsrc/css/application/conpherence/notification.css' => '965db05b',
'rsrc/css/application/conpherence/participant-pane.css' => 'ac1baaa8',
'rsrc/css/application/conpherence/transaction.css' => '85129c68',
@ -60,7 +60,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' => '9ef7d354',
'rsrc/css/application/differential/changeset-view.css' => 'b158cc46',
'rsrc/css/application/differential/core.css' => '5b7b8ff4',
'rsrc/css/application/differential/phui-inline-comment.css' => '5953c28e',
'rsrc/css/application/differential/revision-comment.css' => '14b8565a',
@ -109,7 +109,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' => 'cd912f2c',
'rsrc/css/core/remarkup.css' => 'e70ca862',
'rsrc/css/core/syntax.css' => '769d3498',
'rsrc/css/core/z-index.css' => 'd1270942',
'rsrc/css/diviner/diviner-shared.css' => 'aa3656aa',
@ -132,6 +132,7 @@ return array(
'rsrc/css/phui/phui-button.css' => '4a5fbe3d',
'rsrc/css/phui/phui-chart.css' => '6bf6f78e',
'rsrc/css/phui/phui-cms.css' => 'be43c8a8',
'rsrc/css/phui/phui-comment-form.css' => '4ecc56ef',
'rsrc/css/phui/phui-crumbs-view.css' => '195ac419',
'rsrc/css/phui/phui-curtain-view.css' => '947bf1a4',
'rsrc/css/phui/phui-document-pro.css' => 'ca1fed81',
@ -139,10 +140,10 @@ return array(
'rsrc/css/phui/phui-document.css' => 'c32e8dec',
'rsrc/css/phui/phui-feed-story.css' => '44a9c8e9',
'rsrc/css/phui/phui-fontkit.css' => '9cda225e',
'rsrc/css/phui/phui-form-view.css' => '9e22b190',
'rsrc/css/phui/phui-form.css' => 'aac1d51d',
'rsrc/css/phui/phui-form-view.css' => '91adabe4',
'rsrc/css/phui/phui-form.css' => 'b8fb087a',
'rsrc/css/phui/phui-head-thing.css' => 'fd311e5f',
'rsrc/css/phui/phui-header-view.css' => '06385974',
'rsrc/css/phui/phui-header-view.css' => '6ec8f155',
'rsrc/css/phui/phui-hovercard.css' => 'de1a2119',
'rsrc/css/phui/phui-icon-set-selector.css' => '1ab67aad',
'rsrc/css/phui/phui-icon.css' => '417f80fb',
@ -264,7 +265,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' => 'b25d5444',
'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadSource.js' => '0fcf201c',
'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadStaticSource.js' => '6c0e62fa',
'rsrc/favicons/apple-touch-icon-114x114.png' => '12a24178',
'rsrc/favicons/apple-touch-icon-120x120.png' => '0d1543c7',
@ -301,9 +302,6 @@ return array(
'rsrc/image/grippy_texture.png' => 'aca81e2f',
'rsrc/image/icon/fatcow/arrow_branch.png' => '2537c01c',
'rsrc/image/icon/fatcow/arrow_merge.png' => '21b660e0',
'rsrc/image/icon/fatcow/bullet_black.png' => 'ff190031',
'rsrc/image/icon/fatcow/bullet_orange.png' => 'e273e5bb',
'rsrc/image/icon/fatcow/bullet_red.png' => 'c0b75434',
'rsrc/image/icon/fatcow/calendar_edit.png' => '24632275',
'rsrc/image/icon/fatcow/document_black.png' => '45fe1c60',
'rsrc/image/icon/fatcow/flag_blue.png' => 'a01abb1d',
@ -456,7 +454,7 @@ return array(
'rsrc/js/application/search/behavior-reorder-profile-menu-items.js' => 'e2e0a072',
'rsrc/js/application/search/behavior-reorder-queries.js' => 'e9581f08',
'rsrc/js/application/slowvote/behavior-slowvote-embed.js' => '887ad43f',
'rsrc/js/application/transactions/behavior-comment-actions.js' => '0300eae6',
'rsrc/js/application/transactions/behavior-comment-actions.js' => '1be09f3f',
'rsrc/js/application/transactions/behavior-reorder-configs.js' => 'd7a74243',
'rsrc/js/application/transactions/behavior-reorder-fields.js' => 'b59e1e96',
'rsrc/js/application/transactions/behavior-show-older-transactions.js' => '94c65b72',
@ -487,7 +485,7 @@ return array(
'rsrc/js/core/KeyboardShortcutManager.js' => '4a021c10',
'rsrc/js/core/MultirowRowManager.js' => 'b5d57730',
'rsrc/js/core/Notification.js' => 'ccf1cbf8',
'rsrc/js/core/Prefab.js' => 'cfd23f37',
'rsrc/js/core/Prefab.js' => '8d40ae75',
'rsrc/js/core/ShapedRequest.js' => '7cbe244b',
'rsrc/js/core/TextAreaUtils.js' => '320810c8',
'rsrc/js/core/Title.js' => '485aaa6c',
@ -545,19 +543,19 @@ return array(
'rsrc/js/phuix/PHUIXActionView.js' => '8cf6d262',
'rsrc/js/phuix/PHUIXAutocomplete.js' => '6d86ce8b',
'rsrc/js/phuix/PHUIXDropdownMenu.js' => '82e270da',
'rsrc/js/phuix/PHUIXFormControl.js' => 'e15869a8',
'rsrc/js/phuix/PHUIXFormControl.js' => '301b7812',
'rsrc/js/phuix/PHUIXIconView.js' => 'bff6884b',
),
'symbols' => array(
'almanac-css' => 'dbb9b3af',
'aphront-bars' => '231ac33c',
'aphront-dark-console-css' => 'f54bf286',
'aphront-dialog-view-css' => '593d3f67',
'aphront-dialog-view-css' => 'ea3745f5',
'aphront-list-filter-view-css' => '5d6f0526',
'aphront-multi-column-view-css' => '84cc6640',
'aphront-panel-view-css' => '8427b78d',
'aphront-table-view-css' => '3225137a',
'aphront-tokenizer-control-css' => '056da01b',
'aphront-tokenizer-control-css' => '9a8cb501',
'aphront-tooltip-css' => '1a07aea8',
'aphront-typeahead-control-css' => 'd4f16145',
'application-search-view-css' => '8452c849',
@ -570,13 +568,13 @@ return array(
'conpherence-durable-column-view' => 'd82e130c',
'conpherence-header-pane-css' => '1c81cda6',
'conpherence-menu-css' => '4f51db5a',
'conpherence-message-pane-css' => '394ae8fa',
'conpherence-message-pane-css' => 'b085d40d',
'conpherence-notification-css' => '965db05b',
'conpherence-participant-pane-css' => 'ac1baaa8',
'conpherence-thread-manager' => '358c717b',
'conpherence-transaction-css' => '85129c68',
'd3' => 'a11a5ff2',
'differential-changeset-view-css' => '9ef7d354',
'differential-changeset-view-css' => 'b158cc46',
'differential-core-view-css' => '5b7b8ff4',
'differential-inline-comment-editor' => '64a5550f',
'differential-revision-add-comment-css' => 'c47f8c40',
@ -612,7 +610,7 @@ return array(
'javelin-behavior-bulk-job-reload' => 'edf8a145',
'javelin-behavior-calendar-month-view' => 'fe33e256',
'javelin-behavior-choose-control' => '327a00d1',
'javelin-behavior-comment-actions' => '0300eae6',
'javelin-behavior-comment-actions' => '1be09f3f',
'javelin-behavior-config-reorder-fields' => 'b6993408',
'javelin-behavior-conpherence-menu' => '7524fcfa',
'javelin-behavior-conpherence-participant-pane' => '8604caa8',
@ -758,7 +756,7 @@ return array(
'javelin-typeahead-normalizer' => 'e6e25838',
'javelin-typeahead-ondemand-source' => '013ffff9',
'javelin-typeahead-preloaded-source' => '54f314a0',
'javelin-typeahead-source' => 'b25d5444',
'javelin-typeahead-source' => '0fcf201c',
'javelin-typeahead-static-source' => '6c0e62fa',
'javelin-uri' => 'c989ade3',
'javelin-util' => '93cc50d6',
@ -810,13 +808,13 @@ return array(
'phabricator-notification-menu-css' => '1e055865',
'phabricator-object-selector-css' => '85ee8ce6',
'phabricator-phtize' => 'd254d646',
'phabricator-prefab' => 'cfd23f37',
'phabricator-remarkup-css' => 'cd912f2c',
'phabricator-prefab' => '8d40ae75',
'phabricator-remarkup-css' => 'e70ca862',
'phabricator-search-results-css' => '7dea472c',
'phabricator-shaped-request' => '7cbe244b',
'phabricator-slowvote-css' => 'a94b7230',
'phabricator-source-code-view-css' => 'cbeef983',
'phabricator-standard-page-view' => '79176f5a',
'phabricator-standard-page-view' => '894d8a25',
'phabricator-textareautils' => '320810c8',
'phabricator-title' => '485aaa6c',
'phabricator-tooltip' => '6323f942',
@ -854,6 +852,7 @@ return array(
'phui-calendar-month-css' => '8e10e92c',
'phui-chart-css' => '6bf6f78e',
'phui-cms-css' => 'be43c8a8',
'phui-comment-form-css' => '4ecc56ef',
'phui-crumbs-view-css' => '195ac419',
'phui-curtain-view-css' => '947bf1a4',
'phui-document-summary-view-css' => '9ca48bdf',
@ -862,10 +861,10 @@ return array(
'phui-feed-story-css' => '44a9c8e9',
'phui-font-icon-base-css' => '870a7360',
'phui-fontkit-css' => '9cda225e',
'phui-form-css' => 'aac1d51d',
'phui-form-view-css' => '9e22b190',
'phui-form-css' => 'b8fb087a',
'phui-form-view-css' => '91adabe4',
'phui-head-thing-view-css' => 'fd311e5f',
'phui-header-view-css' => '06385974',
'phui-header-view-css' => '6ec8f155',
'phui-hovercard' => '1bd28176',
'phui-hovercard-view-css' => 'de1a2119',
'phui-icon-set-selector-css' => '1ab67aad',
@ -898,7 +897,7 @@ return array(
'phuix-action-view' => '8cf6d262',
'phuix-autocomplete' => '6d86ce8b',
'phuix-dropdown-menu' => '82e270da',
'phuix-form-control-view' => 'e15869a8',
'phuix-form-control-view' => '301b7812',
'phuix-icon-view' => 'bff6884b',
'policy-css' => '957ea14c',
'policy-edit-css' => '815c66f7',
@ -941,15 +940,6 @@ return array(
'javelin-dom',
'phabricator-keyboard-shortcut',
),
'0300eae6' => array(
'javelin-behavior',
'javelin-stratcom',
'javelin-workflow',
'javelin-dom',
'phuix-form-control-view',
'phuix-icon-view',
'javelin-behavior-phabricator-gesture',
),
'05270951' => array(
'javelin-util',
'javelin-magical-init',
@ -960,10 +950,6 @@ return array(
'javelin-util',
'phabricator-tooltip',
),
'056da01b' => array(
'aphront-typeahead-control-css',
'phui-tag-view-css',
),
'065227cc' => array(
'javelin-behavior',
'javelin-dom',
@ -1013,6 +999,12 @@ return array(
'javelin-install',
'javelin-util',
),
'0fcf201c' => array(
'javelin-install',
'javelin-util',
'javelin-dom',
'javelin-typeahead-normalizer',
),
'116cf19b' => array(
'javelin-behavior',
'javelin-stratcom',
@ -1075,6 +1067,15 @@ return array(
'javelin-request',
'javelin-uri',
),
'1be09f3f' => array(
'javelin-behavior',
'javelin-stratcom',
'javelin-workflow',
'javelin-dom',
'phuix-form-control-view',
'phuix-icon-view',
'javelin-behavior-phabricator-gesture',
),
'1def2711' => array(
'javelin-install',
'javelin-dom',
@ -1142,6 +1143,10 @@ return array(
'2ee659ce' => array(
'javelin-install',
),
'301b7812' => array(
'javelin-install',
'javelin-dom',
),
'320810c8' => array(
'javelin-install',
'javelin-dom',
@ -1652,6 +1657,18 @@ return array(
'javelin-stratcom',
'javelin-install',
),
'8d40ae75' => 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',
),
'8ff5e24c' => array(
'javelin-behavior',
'javelin-stratcom',
@ -1726,6 +1743,10 @@ return array(
'phabricator-phtize',
'changeset-view-manager',
),
'9a8cb501' => array(
'aphront-typeahead-control-css',
'phui-tag-view-css',
),
'9bbf3762' => array(
'javelin-behavior',
'javelin-dom',
@ -1733,9 +1754,6 @@ return array(
'javelin-workflow',
'javelin-stratcom',
),
'9ef7d354' => array(
'phui-inline-comment-view-css',
),
'9f36c42d' => array(
'javelin-behavior',
'javelin-stratcom',
@ -1838,6 +1856,9 @@ return array(
'javelin-util',
'phabricator-shaped-request',
),
'b158cc46' => array(
'phui-inline-comment-view-css',
),
'b1f0ccee' => array(
'javelin-install',
'javelin-dom',
@ -1850,12 +1871,6 @@ return array(
'javelin-request',
'phabricator-shaped-request',
),
'b25d5444' => array(
'javelin-install',
'javelin-util',
'javelin-dom',
'javelin-typeahead-normalizer',
),
'b2b4fbaf' => array(
'javelin-behavior',
'javelin-dom',
@ -1975,18 +1990,6 @@ return array(
'javelin-util',
'phabricator-notification-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',
'javelin-dom',
@ -2063,10 +2066,6 @@ return array(
'javelin-dom',
'phabricator-prefab',
),
'e15869a8' => array(
'javelin-install',
'javelin-dom',
),
'e1d25dfb' => array(
'javelin-behavior',
'javelin-stratcom',

View file

@ -1668,6 +1668,7 @@ phutil_register_library_map(array(
'PHUIPagerView' => 'view/phui/PHUIPagerView.php',
'PHUIPinboardItemView' => 'view/phui/PHUIPinboardItemView.php',
'PHUIPinboardView' => 'view/phui/PHUIPinboardView.php',
'PHUIPolicySectionView' => 'applications/policy/view/PHUIPolicySectionView.php',
'PHUIPropertyGroupView' => 'view/phui/PHUIPropertyGroupView.php',
'PHUIPropertyListExample' => 'applications/uiexample/examples/PHUIPropertyListExample.php',
'PHUIPropertyListView' => 'view/phui/PHUIPropertyListView.php',
@ -2071,6 +2072,7 @@ phutil_register_library_map(array(
'PhabricatorCalendarEventNameTransaction' => 'applications/calendar/xaction/PhabricatorCalendarEventNameTransaction.php',
'PhabricatorCalendarEventNotificationView' => 'applications/calendar/notifications/PhabricatorCalendarEventNotificationView.php',
'PhabricatorCalendarEventPHIDType' => 'applications/calendar/phid/PhabricatorCalendarEventPHIDType.php',
'PhabricatorCalendarEventPolicyCodex' => 'applications/calendar/codex/PhabricatorCalendarEventPolicyCodex.php',
'PhabricatorCalendarEventQuery' => 'applications/calendar/query/PhabricatorCalendarEventQuery.php',
'PhabricatorCalendarEventRSVPEmailCommand' => 'applications/calendar/command/PhabricatorCalendarEventRSVPEmailCommand.php',
'PhabricatorCalendarEventRecurringTransaction' => 'applications/calendar/xaction/PhabricatorCalendarEventRecurringTransaction.php',
@ -2145,6 +2147,7 @@ phutil_register_library_map(array(
'PhabricatorCalendarImportOrphanLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportOrphanLogType.php',
'PhabricatorCalendarImportPHIDType' => 'applications/calendar/phid/PhabricatorCalendarImportPHIDType.php',
'PhabricatorCalendarImportQuery' => 'applications/calendar/query/PhabricatorCalendarImportQuery.php',
'PhabricatorCalendarImportQueueLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportQueueLogType.php',
'PhabricatorCalendarImportReloadController' => 'applications/calendar/controller/PhabricatorCalendarImportReloadController.php',
'PhabricatorCalendarImportReloadTransaction' => 'applications/calendar/xaction/PhabricatorCalendarImportReloadTransaction.php',
'PhabricatorCalendarImportReloadWorker' => 'applications/calendar/worker/PhabricatorCalendarImportReloadWorker.php',
@ -2156,6 +2159,7 @@ phutil_register_library_map(array(
'PhabricatorCalendarImportUpdateLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportUpdateLogType.php',
'PhabricatorCalendarImportViewController' => 'applications/calendar/controller/PhabricatorCalendarImportViewController.php',
'PhabricatorCalendarManagementNotifyWorkflow' => 'applications/calendar/management/PhabricatorCalendarManagementNotifyWorkflow.php',
'PhabricatorCalendarManagementReloadWorkflow' => 'applications/calendar/management/PhabricatorCalendarManagementReloadWorkflow.php',
'PhabricatorCalendarManagementWorkflow' => 'applications/calendar/management/PhabricatorCalendarManagementWorkflow.php',
'PhabricatorCalendarNotification' => 'applications/calendar/storage/PhabricatorCalendarNotification.php',
'PhabricatorCalendarNotificationEngine' => 'applications/calendar/notifications/PhabricatorCalendarNotificationEngine.php',
@ -2482,7 +2486,6 @@ phutil_register_library_map(array(
'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',
@ -3309,6 +3312,9 @@ phutil_register_library_map(array(
'PhabricatorPolicyCanViewCapability' => 'applications/policy/capability/PhabricatorPolicyCanViewCapability.php',
'PhabricatorPolicyCapability' => 'applications/policy/capability/PhabricatorPolicyCapability.php',
'PhabricatorPolicyCapabilityTestCase' => 'applications/policy/capability/__tests__/PhabricatorPolicyCapabilityTestCase.php',
'PhabricatorPolicyCodex' => 'applications/policy/codex/PhabricatorPolicyCodex.php',
'PhabricatorPolicyCodexInterface' => 'applications/policy/codex/PhabricatorPolicyCodexInterface.php',
'PhabricatorPolicyCodexRuleDescription' => 'applications/policy/codex/PhabricatorPolicyCodexRuleDescription.php',
'PhabricatorPolicyConfigOptions' => 'applications/policy/config/PhabricatorPolicyConfigOptions.php',
'PhabricatorPolicyConstants' => 'applications/policy/constants/PhabricatorPolicyConstants.php',
'PhabricatorPolicyController' => 'applications/policy/controller/PhabricatorPolicyController.php',
@ -6445,6 +6451,7 @@ phutil_register_library_map(array(
'PHUIPagerView' => 'AphrontView',
'PHUIPinboardItemView' => 'AphrontView',
'PHUIPinboardView' => 'AphrontView',
'PHUIPolicySectionView' => 'AphrontTagView',
'PHUIPropertyGroupView' => 'AphrontTagView',
'PHUIPropertyListExample' => 'PhabricatorUIExample',
'PHUIPropertyListView' => 'AphrontView',
@ -6868,6 +6875,7 @@ phutil_register_library_map(array(
'PhabricatorCalendarDAO',
'PhabricatorPolicyInterface',
'PhabricatorExtendedPolicyInterface',
'PhabricatorPolicyCodexInterface',
'PhabricatorProjectInterface',
'PhabricatorMarkupInterface',
'PhabricatorApplicationTransactionInterface',
@ -6921,6 +6929,7 @@ phutil_register_library_map(array(
'PhabricatorCalendarEventNameTransaction' => 'PhabricatorCalendarEventTransactionType',
'PhabricatorCalendarEventNotificationView' => 'Phobject',
'PhabricatorCalendarEventPHIDType' => 'PhabricatorPHIDType',
'PhabricatorCalendarEventPolicyCodex' => 'PhabricatorPolicyCodex',
'PhabricatorCalendarEventQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorCalendarEventRSVPEmailCommand' => 'PhabricatorCalendarEventEmailCommand',
'PhabricatorCalendarEventRecurringTransaction' => 'PhabricatorCalendarEventTransactionType',
@ -7012,6 +7021,7 @@ phutil_register_library_map(array(
'PhabricatorCalendarImportOrphanLogType' => 'PhabricatorCalendarImportLogType',
'PhabricatorCalendarImportPHIDType' => 'PhabricatorPHIDType',
'PhabricatorCalendarImportQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorCalendarImportQueueLogType' => 'PhabricatorCalendarImportLogType',
'PhabricatorCalendarImportReloadController' => 'PhabricatorCalendarController',
'PhabricatorCalendarImportReloadTransaction' => 'PhabricatorCalendarImportTransactionType',
'PhabricatorCalendarImportReloadWorker' => 'PhabricatorWorker',
@ -7023,6 +7033,7 @@ phutil_register_library_map(array(
'PhabricatorCalendarImportUpdateLogType' => 'PhabricatorCalendarImportLogType',
'PhabricatorCalendarImportViewController' => 'PhabricatorCalendarController',
'PhabricatorCalendarManagementNotifyWorkflow' => 'PhabricatorCalendarManagementWorkflow',
'PhabricatorCalendarManagementReloadWorkflow' => 'PhabricatorCalendarManagementWorkflow',
'PhabricatorCalendarManagementWorkflow' => 'PhabricatorManagementWorkflow',
'PhabricatorCalendarNotification' => 'PhabricatorCalendarDAO',
'PhabricatorCalendarNotificationEngine' => 'Phobject',
@ -7394,7 +7405,6 @@ phutil_register_library_map(array(
'PhabricatorDifferentialRevisionTestDataGenerator' => 'PhabricatorTestDataGenerator',
'PhabricatorDiffusionApplication' => 'PhabricatorApplication',
'PhabricatorDiffusionBlameSetting' => 'PhabricatorInternalSetting',
'PhabricatorDiffusionColorSetting' => 'PhabricatorInternalSetting',
'PhabricatorDiffusionConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorDisabledUserController' => 'PhabricatorAuthController',
'PhabricatorDisplayPreferencesSettingsPanel' => 'PhabricatorEditEngineSettingsPanel',
@ -8357,6 +8367,8 @@ phutil_register_library_map(array(
'PhabricatorPolicyCanViewCapability' => 'PhabricatorPolicyCapability',
'PhabricatorPolicyCapability' => 'Phobject',
'PhabricatorPolicyCapabilityTestCase' => 'PhabricatorTestCase',
'PhabricatorPolicyCodex' => 'Phobject',
'PhabricatorPolicyCodexRuleDescription' => 'Phobject',
'PhabricatorPolicyConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorPolicyConstants' => 'Phobject',
'PhabricatorPolicyController' => 'PhabricatorController',

View file

@ -167,10 +167,6 @@ final class AlmanacDevice
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
/* -( PhabricatorExtendedPolicyInterface )--------------------------------- */

View file

@ -174,10 +174,6 @@ final class AlmanacNamespace
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
/* -( PhabricatorApplicationTransactionInterface )------------------------- */

View file

@ -92,10 +92,6 @@ final class AlmanacNetwork
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
/* -( PhabricatorDestructibleInterface )----------------------------------- */

View file

@ -184,10 +184,6 @@ final class AlmanacService
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
/* -( PhabricatorExtendedPolicyInterface )--------------------------------- */

View file

@ -130,8 +130,4 @@ final class PhabricatorAuthProviderConfig
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
}

View file

@ -125,8 +125,4 @@ final class PhabricatorAuthTemporaryToken extends PhabricatorAuthDAO
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
}

View file

@ -76,8 +76,4 @@ final class PhabricatorBadgesAward extends PhabricatorBadgesDAO
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
}

View file

@ -129,10 +129,6 @@ final class PhabricatorBadgesBadge extends PhabricatorBadgesDAO
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
/* -( PhabricatorApplicationTransactionInterface )------------------------- */

View file

@ -483,10 +483,6 @@ abstract class PhabricatorApplication
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
/* -( Policies )----------------------------------------------------------- */

View file

@ -0,0 +1,80 @@
<?php
final class PhabricatorCalendarEventPolicyCodex
extends PhabricatorPolicyCodex {
public function getPolicyShortName() {
$object = $this->getObject();
if (!$object->isImportedEvent()) {
return null;
}
return pht('Uses Import Policy');
}
public function getPolicyIcon() {
$object = $this->getObject();
if (!$object->isImportedEvent()) {
return null;
}
return 'fa-download';
}
public function getPolicyTagClasses() {
$object = $this->getObject();
if (!$object->isImportedEvent()) {
return array();
}
return array(
'policy-adjusted-special',
);
}
public function getPolicySpecialRuleDescriptions() {
$object = $this->getObject();
$rules = array();
$rules[] = $this->newRule()
->setDescription(
pht('The host of an event can always view and edit it.'));
$rules[] = $this->newRule()
->setCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
))
->setDescription(
pht('Users who are invited to an event can always view it.'));
$rules[] = $this->newRule()
->setCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
))
->setIsActive($object->isImportedEvent())
->setDescription(
pht(
'Imported events can only be viewed by users who can view '.
'the import source.'));
$rules[] = $this->newRule()
->setCapabilities(
array(
PhabricatorPolicyCapability::CAN_EDIT,
))
->setIsActive($object->isImportedEvent())
->setDescription(
pht(
'Imported events can not be edited in Phabricator.'));
return $rules;
}
}

View file

@ -54,7 +54,7 @@ final class PhabricatorCalendarImportEditor
if ($should_reload) {
$import_engine = $object->getEngine();
$import_engine->importEventsFromSource($actor, $object);
$import_engine->importEventsFromSource($actor, $object, true);
}
if ($should_trigger) {
@ -107,6 +107,7 @@ final class PhabricatorCalendarImportEditor
'class' => 'PhabricatorCalendarImportReloadWorker',
'data' => array(
'importPHID' => $object->getPHID(),
'via' => PhabricatorCalendarImportReloadWorker::VIA_TRIGGER,
),
'options' => array(
'objectPHID' => $object->getPHID(),

View file

@ -65,7 +65,8 @@ final class PhabricatorCalendarICSFileImportEngine
public function importEventsFromSource(
PhabricatorUser $viewer,
PhabricatorCalendarImport $import) {
PhabricatorCalendarImport $import,
$should_queue) {
$phid_key = PhabricatorCalendarImportICSFileTransaction::PARAMKEY_FILE;
$file_phid = $import->getParameter($phid_key);
@ -83,9 +84,12 @@ final class PhabricatorCalendarICSFileImportEngine
$data = $file->loadFileData();
return $this->importICSData($viewer, $import, $data);
if ($should_queue && $this->shouldQueueDataImport($data)) {
return $this->queueDataImport($import, $data);
}
return $this->importICSData($viewer, $import, $data);
}
public function canDisable(
PhabricatorUser $viewer,

View file

@ -77,7 +77,8 @@ final class PhabricatorCalendarICSURIImportEngine
public function importEventsFromSource(
PhabricatorUser $viewer,
PhabricatorCalendarImport $import) {
PhabricatorCalendarImport $import,
$should_queue) {
$uri_key = PhabricatorCalendarImportICSURITransaction::PARAMKEY_URI;
$uri = $import->getParameter($uri_key);
@ -103,6 +104,10 @@ final class PhabricatorCalendarICSURIImportEngine
$data = $file->loadFileData();
if ($should_queue && $this->shouldQueueDataImport($data)) {
return $this->queueDataImport($import, $data);
}
return $this->importICSData($viewer, $import, $data);
}

View file

@ -3,11 +3,12 @@
abstract class PhabricatorCalendarImportEngine
extends Phobject {
const QUEUE_BYTE_LIMIT = 524288;
final public function getImportEngineType() {
return $this->getPhobjectClassConstant('ENGINETYPE', 64);
}
abstract public function getImportEngineName();
abstract public function getImportEngineTypeName();
abstract public function getImportEngineHint();
@ -27,7 +28,8 @@ abstract class PhabricatorCalendarImportEngine
abstract public function importEventsFromSource(
PhabricatorUser $viewer,
PhabricatorCalendarImport $import);
PhabricatorCalendarImport $import,
$should_queue);
abstract public function canDisable(
PhabricatorUser $viewer,
@ -197,7 +199,7 @@ abstract class PhabricatorCalendarImportEngine
if ($node_map) {
$events = id(new PhabricatorCalendarEventQuery())
->setViewer($viewer)
->withImportAuthorPHIDs(array($viewer->getPHID()))
->withImportAuthorPHIDs(array($import->getAuthorPHID()))
->withImportUIDs(array_keys($node_map))
->execute();
$events = mpull($events, null, 'getImportUID');
@ -216,7 +218,7 @@ abstract class PhabricatorCalendarImportEngine
}
$event
->setImportAuthorPHID($viewer->getPHID())
->setImportAuthorPHID($import->getAuthorPHID())
->setImportSourcePHID($import->getPHID())
->setImportUID($full_uid)
->attachImportSource($import);
@ -259,7 +261,7 @@ abstract class PhabricatorCalendarImportEngine
if ($attendee_names) {
$external_invitees = id(new PhabricatorCalendarExternalInviteeQuery())
->setViewer($viewer)
->withNames($attendee_names)
->withNames(array_keys($attendee_names))
->execute();
$external_invitees = mpull($external_invitees, null, 'getName');
@ -568,4 +570,35 @@ abstract class PhabricatorCalendarImportEngine
return (bool)$any_event;
}
final protected function shouldQueueDataImport($data) {
return (strlen($data) > self::QUEUE_BYTE_LIMIT);
}
final protected function queueDataImport(
PhabricatorCalendarImport $import,
$data) {
$import->newLogMessage(
PhabricatorCalendarImportQueueLogType::LOGTYPE,
array(
'data.size' => strlen($data),
'data.limit' => self::QUEUE_BYTE_LIMIT,
));
// When we queue on this pathway, we're queueing in response to an explicit
// user action (like uploading a big `.ics` file), so we queue at normal
// priority instead of bulk/import priority.
PhabricatorWorker::scheduleTask(
'PhabricatorCalendarImportReloadWorker',
array(
'importPHID' => $import->getPHID(),
'via' => PhabricatorCalendarImportReloadWorker::VIA_BACKGROUND,
),
array(
'objectPHID' => $import->getPHID(),
));
}
}

View file

@ -0,0 +1,40 @@
<?php
final class PhabricatorCalendarImportQueueLogType
extends PhabricatorCalendarImportLogType {
const LOGTYPE = 'queue';
public function getDisplayType(
PhabricatorUser $viewer,
PhabricatorCalendarImportLog $log) {
return pht('Queued');
}
public function getDisplayDescription(
PhabricatorUser $viewer,
PhabricatorCalendarImportLog $log) {
$size = $log->getParameter('data.size');
$limit = $log->getParameter('data.limit');
return pht(
'Queued for background import: data size (%s) exceeds limit for '.
'immediate processing (%s).',
phutil_format_bytes($size),
phutil_format_bytes($limit));
}
public function getDisplayIcon(
PhabricatorUser $viewer,
PhabricatorCalendarImportLog $log) {
return 'fa-sort-amount-desc';
}
public function getDisplayColor(
PhabricatorUser $viewer,
PhabricatorCalendarImportLog $log) {
return 'blue';
}
}

View file

@ -14,8 +14,16 @@ final class PhabricatorCalendarImportTriggerLogType
public function getDisplayDescription(
PhabricatorUser $viewer,
PhabricatorCalendarImportLog $log) {
$via = $log->getParameter('via');
switch ($via) {
case PhabricatorCalendarImportReloadWorker::VIA_BACKGROUND:
return pht('Started background processing.');
case PhabricatorCalendarImportReloadWorker::VIA_TRIGGER:
default:
return pht('Triggered a periodic update.');
}
}
public function getDisplayIcon(
PhabricatorUser $viewer,

View file

@ -0,0 +1,68 @@
<?php
final class PhabricatorCalendarManagementReloadWorkflow
extends PhabricatorCalendarManagementWorkflow {
protected function didConstruct() {
$this
->setName('reload')
->setExamples('**reload** [options] __id__ ...')
->setSynopsis(
pht(
'Reload event imports from the command line. Useful for '.
'testing and debugging importers.'))
->setArguments(
array(
array(
'name' => 'ids',
'wildcard' => true,
'help' => pht('List of import IDs to reload.'),
),
));
}
public function execute(PhutilArgumentParser $args) {
$viewer = $this->getViewer();
$ids = $args->getArg('ids');
if (!$ids) {
throw new PhutilArgumentUsageException(
pht('Specify at least one import ID to reload.'));
}
$imports = id(new PhabricatorCalendarImportQuery())
->setViewer($viewer)
->withIDs($ids)
->execute();
$imports = mpull($imports, null, 'getID');
foreach ($ids as $id) {
if (empty($imports[$id])) {
throw new PhutilArgumentUsageException(
pht(
'Unable to load Calendar import with ID "%s".',
$id));
}
}
$imports = array_select_keys($imports, $ids);
foreach ($imports as $import) {
echo tsprintf(
"%s\n",
pht(
'Importing "%s"...',
$import->getDisplayName()));
$engine = $import->getEngine();
$engine->importEventsFromSource($viewer, $import, false);
}
echo tsprintf(
"%s\n",
pht('Done.'));
return 0;
}
}

View file

@ -4,6 +4,7 @@ final class PhabricatorCalendarEvent extends PhabricatorCalendarDAO
implements
PhabricatorPolicyInterface,
PhabricatorExtendedPolicyInterface,
PhabricatorPolicyCodexInterface,
PhabricatorProjectInterface,
PhabricatorMarkupInterface,
PhabricatorApplicationTransactionInterface,
@ -75,9 +76,16 @@ final class PhabricatorCalendarEvent extends PhabricatorCalendarDAO
$now);
list($datetime_start, $datetime_end) = $datetime_defaults;
// When importing events from a context like "bin/calendar reload", we may
// be acting as the omnipotent user.
$host_phid = $actor->getPHID();
if (!$host_phid) {
$host_phid = $app->getPHID();
}
return id(new PhabricatorCalendarEvent())
->setDescription('')
->setHostPHID($actor->getPHID())
->setHostPHID($host_phid)
->setIsCancelled(0)
->setIsAllDay(0)
->setIsStub(0)
@ -586,6 +594,9 @@ final class PhabricatorCalendarEvent extends PhabricatorCalendarDAO
$min_date = $start->newPHPDateTime();
$max_date = $end->newPHPDateTime();
// Subtract one second since the stored date is exclusive.
$max_date = $max_date->modify('-1 second');
$min_day = $min_date->format('Y m d');
$max_day = $max_date->format('Y m d');
@ -842,7 +853,11 @@ final class PhabricatorCalendarEvent extends PhabricatorCalendarDAO
// If this is an all day event, we move the end date time forward to the
// first second of the following day. This is consistent with what users
// expect: an all day event from "Nov 1" to "Nov 1" lasts the entire day.
if ($this->getIsAllDay()) {
// For imported events, the end date is already stored with this
// adjustment.
if ($this->getIsAllDay() && !$this->isImportedEvent()) {
$datetime = $datetime
->newAbsoluteDateTime()
->setHour(0)
@ -1203,18 +1218,6 @@ final class PhabricatorCalendarEvent extends PhabricatorCalendarDAO
return false;
}
public function describeAutomaticCapability($capability) {
if ($this->isImportedEvent()) {
return pht(
'Events imported from external sources can not be edited in '.
'Phabricator.');
}
return pht(
'The host of an event can always view and edit it. Users who are '.
'invited to an event can always view it.');
}
/* -( PhabricatorExtendedPolicyInterface )--------------------------------- */
@ -1237,6 +1240,12 @@ final class PhabricatorCalendarEvent extends PhabricatorCalendarDAO
return $extended;
}
/* -( PhabricatorPolicyCodexInterface )------------------------------------ */
public function newPolicyCodex() {
return new PhabricatorCalendarEventPolicyCodex();
}
/* -( PhabricatorApplicationTransactionInterface )------------------------- */

View file

@ -76,7 +76,7 @@ final class PhabricatorCalendarEventInvitee extends PhabricatorCalendarDAO
'name' => pht('Available'),
),
self::AVAILABILITY_BUSY => array(
'color' => 'yellow',
'color' => 'orange',
'name' => pht('Busy'),
),
self::AVAILABILITY_AWAY => array(
@ -121,7 +121,4 @@ final class PhabricatorCalendarEventInvitee extends PhabricatorCalendarDAO
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
}

View file

@ -159,11 +159,6 @@ final class PhabricatorCalendarExport extends PhabricatorCalendarDAO
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
/* -( PhabricatorApplicationTransactionInterface )------------------------- */

View file

@ -68,7 +68,4 @@ final class PhabricatorCalendarExternalInvitee
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
}

View file

@ -132,10 +132,6 @@ final class PhabricatorCalendarImport
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
/* -( PhabricatorApplicationTransactionInterface )------------------------- */

View file

@ -86,10 +86,6 @@ final class PhabricatorCalendarImportLog
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
/* -( PhabricatorDestructibleInterface )----------------------------------- */

View file

@ -2,6 +2,9 @@
final class PhabricatorCalendarImportReloadWorker extends PhabricatorWorker {
const VIA_TRIGGER = 'trigger';
const VIA_BACKGROUND = 'background';
protected function doWork() {
$import = $this->loadImport();
$viewer = PhabricatorUser::getOmnipotentUser();
@ -18,11 +21,14 @@ final class PhabricatorCalendarImportReloadWorker extends PhabricatorWorker {
$import_engine = $import->getEngine();
$data = $this->getTaskData();
$import->newLogMessage(
PhabricatorCalendarImportTriggerLogType::LOGTYPE,
array());
array(
'via' => idx($data, 'via', self::VIA_TRIGGER),
));
$import_engine->importEventsFromSource($author, $import);
$import_engine->importEventsFromSource($author, $import, false);
}
private function loadImport() {

View file

@ -30,6 +30,10 @@ final class PhabricatorCalendarEventDescriptionTransaction
return true;
}
public function getMailDiffSectionHeader() {
return pht('CHANGES TO EVENT DESCRIPTION');
}
public function newChangeDetailView() {
$viewer = $this->getViewer();

View file

@ -48,8 +48,4 @@ final class PhabricatorChatLogChannel
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
}

View file

@ -56,8 +56,4 @@ final class PhabricatorChatLogEvent
return $this->getChannel()->hasAutomaticCapability($capability, $viewer);
}
public function describeAutomaticCapability($capability) {
return null;
}
}

View file

@ -372,10 +372,6 @@ abstract class ConduitAPIMethod
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
protected function hasApplicationCapability(
$capability,
PhabricatorUser $viewer) {

View file

@ -52,8 +52,4 @@ final class PhabricatorConduitMethodCallLog
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
}

View file

@ -95,8 +95,4 @@ final class PhabricatorConfigEntry
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
}

View file

@ -139,10 +139,6 @@ final class PhabricatorCountdown extends PhabricatorCountdownDAO
return false;
}
public function describeAutomaticCapability($capability) {
return false;
}
/* -( PhabricatorSpacesInterface )------------------------------------------- */
public function getSpacePHID() {

View file

@ -77,8 +77,4 @@ final class PhabricatorDaemonLog extends PhabricatorDaemonDAO
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
}

View file

@ -160,10 +160,6 @@ final class PhabricatorDashboard extends PhabricatorDashboardDAO
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
/* -( PhabricatorDestructibleInterface )----------------------------------- */

View file

@ -159,10 +159,6 @@ final class PhabricatorDashboardPanel
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
/* -( PhabricatorCustomFieldInterface )------------------------------------ */

View file

@ -226,8 +226,4 @@ final class DifferentialChangeset extends DifferentialDAO
return $this->getDiff()->hasAutomaticCapability($capability, $viewer);
}
public function describeAutomaticCapability($capability) {
return null;
}
}

View file

@ -228,8 +228,4 @@ abstract class DifferentialHunk extends DifferentialDAO
return $this->getChangeset()->hasAutomaticCapability($capability, $viewer);
}
public function describeAutomaticCapability($capability) {
return null;
}
}

View file

@ -370,14 +370,6 @@ final class DifferentialRevision extends DifferentialDAO
switch ($capability) {
case PhabricatorPolicyCapability::CAN_VIEW:
// NOTE: In Differential, an automatic capability on a revision (being
// an author) is sufficient to view it, even if you can not see the
// repository the revision belongs to. We can bail out early in this
// case.
if ($this->hasAutomaticCapability($capability, $viewer)) {
break;
}
$repository_phid = $this->getRepositoryPHID();
$repository = $this->getRepository();

View file

@ -106,16 +106,11 @@ final class DiffusionBrowseController extends DiffusionController {
$path = $drequest->getPath();
$blame_key = PhabricatorDiffusionBlameSetting::SETTINGKEY;
$color_key = PhabricatorDiffusionColorSetting::SETTINGKEY;
$show_blame = $request->getBool(
'blame',
$viewer->getUserSetting($blame_key));
$show_color = $request->getBool(
'color',
$viewer->getUserSetting($color_key));
$view = $request->getStr('view');
if ($request->isFormPost() && $view != 'raw' && $viewer->isLoggedIn()) {
$preferences = PhabricatorUserPreferences::loadUserPreferences($viewer);
@ -128,22 +123,18 @@ final class DiffusionBrowseController extends DiffusionController {
$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)
->alter('color', null);
->alter('blame', null);
return id(new AphrontRedirectResponse())->setURI($uri);
}
// We need the blame information if blame is on and we're building plain
// text, or blame is on and this is an Ajax request. If blame is on and
// this is a colorized request, we don't show blame at first (we ajax it
// in afterward) so we don't need to query for it.
$needs_blame = ($show_blame && !$show_color) ||
($show_blame && $request->isAjax());
// We need the blame information if blame is on and this is an Ajax request.
// If blame is on and this is a colorized request, we don't show blame at
// first (we ajax it in afterward) so we don't need to query for it.
$needs_blame = ($show_blame && $request->isAjax());
$params = array(
'commit' => $drequest->getCommit(),
@ -196,10 +187,10 @@ final class DiffusionBrowseController extends DiffusionController {
$data = $file->loadFileData();
$ref = $this->getGitLFSRef($repository, $data);
if ($ref) {
$lfs_ref = $this->getGitLFSRef($repository, $data);
if ($lfs_ref) {
if ($view == 'git-lfs') {
$file = $this->loadGitLFSFile($ref);
$file = $this->loadGitLFSFile($lfs_ref);
// Rename the file locally so we generate a better vanity URI for
// it. In storage, it just has a name like "lfs-13f9a94c0923...",
@ -211,7 +202,7 @@ final class DiffusionBrowseController extends DiffusionController {
return $file->getRedirectResponse();
} else {
$corpus = $this->buildGitLFSCorpus($ref);
$corpus = $this->buildGitLFSCorpus($lfs_ref);
}
} else if (ArcanistDiffUtils::isHeuristicBinaryFile($data)) {
$file_uri = $file->getBestURI();
@ -228,7 +219,6 @@ final class DiffusionBrowseController extends DiffusionController {
// Build the content of the file.
$corpus = $this->buildCorpus(
$show_blame,
$show_color,
$data,
$needs_blame,
$drequest,
@ -248,8 +238,7 @@ final class DiffusionBrowseController extends DiffusionController {
$curtain = $this->enrichCurtain(
$view,
$drequest,
$show_blame,
$show_color);
$show_blame);
$properties = $this->buildPropertyView($drequest);
$header = $this->buildHeaderView($drequest);
@ -647,7 +636,6 @@ final class DiffusionBrowseController extends DiffusionController {
private function buildCorpus(
$show_blame,
$show_color,
$file_corpus,
$needs_blame,
DiffusionRequest $drequest,
@ -675,15 +663,7 @@ final class DiffusionBrowseController extends DiffusionController {
$blame_commits = array();
}
if (!$show_color) {
$corpus = $this->renderPlaintextCorpus(
$file_corpus,
$blame_list,
$blame_commits,
$show_blame);
} else {
require_celerity_resource('syntax-highlighting-css');
if ($can_highlight) {
$highlighted = PhabricatorSyntaxHighlighter::highlightWithFilename(
$path,
@ -701,8 +681,7 @@ final class DiffusionBrowseController extends DiffusionController {
$lines,
$blame_list,
$blame_commits,
$show_blame,
$show_color);
$show_blame);
$corpus_table = javelin_tag(
'table',
@ -758,7 +737,7 @@ final class DiffusionBrowseController extends DiffusionController {
$corpus_table);
Javelin::initBehavior('load-blame', array('id' => $id));
}
$edit = $this->renderEditButton();
$file = $this->renderFileButton();
@ -808,8 +787,7 @@ final class DiffusionBrowseController extends DiffusionController {
private function enrichCurtain(
PHUICurtainView $curtain,
DiffusionRequest $drequest,
$show_blame,
$show_color) {
$show_blame) {
$viewer = $this->getViewer();
$base_uri = $this->getRequest()->getRequestURI();
@ -842,24 +820,6 @@ final class DiffusionBrowseController extends DiffusionController {
->setUser($viewer)
->setRenderAsForm($viewer->isLoggedIn()));
if ($show_color) {
$highlight_text = pht('Disable Highlighting');
$highlight_icon = 'fa-star-o grey';
$highlight_value = 0;
} else {
$highlight_text = pht('Enable Highlighting');
$highlight_icon = 'fa-star';
$highlight_value = 1;
}
$curtain->addAction(
id(new PhabricatorActionView())
->setName($highlight_text)
->setHref($base_uri->alter('color', $highlight_value))
->setIcon($highlight_icon)
->setUser($viewer)
->setRenderAsForm($viewer->isLoggedIn()));
$href = null;
if ($this->getRequest()->getStr('lint') !== null) {
$lint_text = pht('Hide %d Lint Message(s)', count($this->lintMessages));
@ -1002,8 +962,7 @@ final class DiffusionBrowseController extends DiffusionController {
array $lines,
array $blame_list,
array $blame_commits,
$show_blame,
$show_color) {
$show_blame) {
$request = $this->getRequest();
$viewer = $this->getViewer();
@ -1891,79 +1850,6 @@ final class DiffusionBrowseController extends DiffusionController {
return $links;
}
private function renderPlaintextCorpus(
$file_corpus,
array $blame_list,
array $blame_commits,
$show_blame) {
$viewer = $this->getViewer();
if (!$show_blame) {
$corpus = $file_corpus;
} else {
$author_phids = array();
foreach ($blame_commits as $commit) {
$author_phid = $commit->getAuthorPHID();
if ($author_phid === null) {
continue;
}
$author_phids[$author_phid] = $author_phid;
}
if ($author_phids) {
$handles = $viewer->loadHandles($author_phids);
} else {
$handles = array();
}
$authors = array();
$names = array();
foreach ($blame_commits as $identifier => $commit) {
$author = $commit->renderAuthorShortName($handles);
$name = $commit->getLocalName();
$authors[$identifier] = $author;
$names[$identifier] = $name;
}
$lines = phutil_split_lines($file_corpus);
$rows = array();
foreach ($lines as $line_number => $line) {
$commit_name = null;
$author = null;
if (isset($blame_list[$line_number])) {
$identifier = $blame_list[$line_number];
if (isset($names[$identifier])) {
$commit_name = $names[$identifier];
}
if (isset($authors[$identifier])) {
$author = $authors[$identifier];
}
}
$rows[] = sprintf(
'%-10s %-20s %s',
$commit_name,
$author,
$line);
}
$corpus = implode('', $rows);
}
return phutil_tag(
'textarea',
array(
'style' => 'border: none; width: 100%; height: 80em; '.
'font-family: monospace',
),
$corpus);
}
private function getGitLFSRef(PhabricatorRepository $repository, $data) {
if (!$repository->canUseGitLFS()) {
return null;

View file

@ -304,8 +304,9 @@ final class DiffusionURIEditor
$type,
pht('Invalid'),
pht(
'Value "%s" is not a valid display setting for this URI. '.
'Value "%s" is not a valid IO setting for this URI. '.
'Available types for this URI are: %s.',
$new,
implode(', ', array_keys($available))),
$xaction);
continue;
@ -418,6 +419,7 @@ final class DiffusionURIEditor
pht(
'Value "%s" is not a valid display setting for this URI. '.
'Available types for this URI are: %s.',
$new,
implode(', ', array_keys($available))));
}
}

View file

@ -114,10 +114,6 @@ final class DivinerLiveBook extends DivinerDAO
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
/* -( PhabricatorDestructibleInterface )----------------------------------- */

View file

@ -121,8 +121,4 @@ final class DoorkeeperExternalObject extends DoorkeeperDAO
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
}

View file

@ -325,10 +325,6 @@ final class DrydockBlueprint extends DrydockDAO
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
/* -( PhabricatorCustomFieldInterface )------------------------------------ */

View file

@ -454,11 +454,6 @@ abstract class PhabricatorFeedStory
}
public function describeAutomaticCapability($capability) {
return null;
}
/* -( PhabricatorMarkupInterface Implementation )--------------------------- */

View file

@ -77,11 +77,6 @@ final class PhabricatorFileChunk extends PhabricatorFileDAO
}
public function describeAutomaticCapability($capability) {
return null;
}
/* -( PhabricatorDestructibleInterface )----------------------------------- */

View file

@ -188,7 +188,6 @@ final class PhabricatorGuideQuickStartModule extends PhabricatorGuideModule {
$description =
pht('Invite the rest of your team to get started on Phabricator.');
}
}
$item = id(new PhabricatorGuideItemView())
->setTitle($title)
@ -197,9 +196,10 @@ final class PhabricatorGuideQuickStartModule extends PhabricatorGuideModule {
->setIconBackground($icon_bg)
->setDescription($description);
$guide_items->addItem($item);
}
$intro = pht(
'If your new to Phabricator, these optional steps can help you learn '.
'If you\'re new to Phabricator, these optional steps can help you learn '.
'the basics. Conceptually, Phabricator is structured as a graph, and '.
'repositories, tasks, and projects are all independent from each other. '.
'Feel free to set up Phabricator for how you work best, and explore '.

View file

@ -93,8 +93,4 @@ final class LegalpadDocumentSignature
return ($viewer->getPHID() == $this->getSignerPHID());
}
public function describeAutomaticCapability($capability) {
return null;
}
}

View file

@ -139,8 +139,4 @@ final class PhabricatorFileImageMacro extends PhabricatorFileDAO
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
}

View file

@ -30,20 +30,19 @@ final class ManiphestTaskDetailController extends ManiphestController {
->setViewer($viewer)
->setTargetObject($task);
$e_commit = ManiphestTaskHasCommitEdgeType::EDGECONST;
$e_rev = ManiphestTaskHasRevisionEdgeType::EDGECONST;
$e_mock = ManiphestTaskHasMockEdgeType::EDGECONST;
$edge_types = array(
ManiphestTaskHasCommitEdgeType::EDGECONST,
ManiphestTaskHasRevisionEdgeType::EDGECONST,
ManiphestTaskHasMockEdgeType::EDGECONST,
PhabricatorObjectMentionedByObjectEdgeType::EDGECONST,
PhabricatorObjectMentionsObjectEdgeType::EDGECONST,
);
$phid = $task->getPHID();
$query = id(new PhabricatorEdgeQuery())
->withSourcePHIDs(array($phid))
->withEdgeTypes(
array(
$e_commit,
$e_rev,
$e_mock,
));
->withEdgeTypes($edge_types);
$edges = idx($query->execute(), $phid);
$phids = array_fill_keys($query->getDestinationPHIDs(), true);
@ -77,15 +76,8 @@ final class ManiphestTaskDetailController extends ManiphestController {
$timeline->setQuoteRef($monogram);
$comment_view->setTransactionTimeline($timeline);
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setCurtain($curtain)
->setMainColumn(array(
$timeline,
$comment_view,
))
->addPropertySection(pht('Description'), $description)
->addPropertySection(pht('Details'), $details);
$related_tabs = array();
$graph_menu = null;
$graph_limit = 100;
$task_graph = id(new ManiphestTaskGraph())
@ -159,13 +151,50 @@ final class ManiphestTaskDetailController extends ManiphestController {
->setText($search_text)
->setDropdownMenu($dropdown_menu);
$graph_header = id(new PHUIHeaderView())
->setHeader(pht('Task Graph'))
->addActionLink($graph_menu);
$view->addPropertySection($graph_header, $graph_table);
$related_tabs[] = id(new PHUITabView())
->setName(pht('Task Graph'))
->setKey('graph')
->appendChild($graph_table);
}
$related_tabs[] = $this->newMocksTab($task, $query);
$related_tabs[] = $this->newMentionsTab($task, $query);
$tab_view = null;
$related_tabs = array_filter($related_tabs);
if ($related_tabs) {
$tab_group = new PHUITabGroupView();
foreach ($related_tabs as $tab) {
$tab_group->addTab($tab);
}
$related_header = id(new PHUIHeaderView())
->setHeader(pht('Related Objects'));
if ($graph_menu) {
$related_header->addActionLink($graph_menu);
}
$tab_view = id(new PHUIObjectBoxView())
->setHeader($related_header)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->addTabGroup($tab_group);
}
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setCurtain($curtain)
->setMainColumn(
array(
$tab_view,
$timeline,
$comment_view,
))
->addPropertySection(pht('Description'), $description)
->addPropertySection(pht('Details'), $details);
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
@ -173,10 +202,7 @@ final class ManiphestTaskDetailController extends ManiphestController {
array(
$task->getPHID(),
))
->appendChild(
array(
$view,
));
->appendChild($view);
}
@ -356,8 +382,6 @@ final class ManiphestTaskDetailController extends ManiphestController {
$edge_types = array(
ManiphestTaskHasRevisionEdgeType::EDGECONST
=> pht('Differential Revisions'),
ManiphestTaskHasMockEdgeType::EDGECONST
=> pht('Pholio Mocks'),
);
$revisions_commits = array();
@ -435,4 +459,73 @@ final class ManiphestTaskDetailController extends ManiphestController {
return $section;
}
private function newMocksTab(
ManiphestTask $task,
PhabricatorEdgeQuery $edge_query) {
$mock_type = ManiphestTaskHasMockEdgeType::EDGECONST;
$mock_phids = $edge_query->getDestinationPHIDs(array(), array($mock_type));
if (!$mock_phids) {
return null;
}
$viewer = $this->getViewer();
$handles = $viewer->loadHandles($mock_phids);
// TODO: It would be nice to render this as pinboard-style thumbnails,
// similar to "{M123}", instead of a list of links.
$view = id(new PHUIPropertyListView())
->addProperty(pht('Mocks'), $handles->renderList());
return id(new PHUITabView())
->setName(pht('Mocks'))
->setKey('mocks')
->appendChild($view);
}
private function newMentionsTab(
ManiphestTask $task,
PhabricatorEdgeQuery $edge_query) {
$in_type = PhabricatorObjectMentionedByObjectEdgeType::EDGECONST;
$out_type = PhabricatorObjectMentionsObjectEdgeType::EDGECONST;
$in_phids = $edge_query->getDestinationPHIDs(array(), array($in_type));
$out_phids = $edge_query->getDestinationPHIDs(array(), array($out_type));
// Filter out any mentioned users from the list. These are not generally
// very interesting to show in a relationship summary since they usually
// end up as subscribers anyway.
$user_type = PhabricatorPeopleUserPHIDType::TYPECONST;
foreach ($out_phids as $key => $out_phid) {
if (phid_get_type($out_phid) == $user_type) {
unset($out_phids[$key]);
}
}
if (!$in_phids && !$out_phids) {
return null;
}
$viewer = $this->getViewer();
$view = new PHUIPropertyListView();
if ($in_phids) {
$in_handles = $viewer->loadHandles($in_phids);
$view->addProperty(pht('Mentioned In'), $in_handles->renderList());
}
if ($out_phids) {
$out_handles = $viewer->loadHandles($out_phids);
$view->addProperty(pht('Mentioned Here'), $out_handles->renderList());
}
return id(new PHUITabView())
->setName(pht('Mentions'))
->setKey('mentions')
->appendChild($view);
}
}

View file

@ -63,8 +63,4 @@ final class NuanceImportCursorData
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
}

View file

@ -48,8 +48,4 @@ final class NuanceItemCommand
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
}

View file

@ -67,10 +67,6 @@ final class NuanceQueue
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
/* -( PhabricatorApplicationTransactionInterface )------------------------- */

View file

@ -138,10 +138,6 @@ final class NuanceSource extends NuanceDAO
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
/* -( PhabricatorNgramsInterface )----------------------------------------- */

View file

@ -83,10 +83,6 @@ final class PhabricatorOAuthServerClient
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
/* -( PhabricatorApplicationTransactionInterface )------------------------- */

View file

@ -19,6 +19,10 @@ final class PhabricatorOwnersPackageDescriptionTransaction
$this->renderAuthor());
}
public function getMailDiffSectionHeader() {
return pht('CHANGES TO PACKAGE DESCRIPTION');
}
public function newChangeDetailView() {
return id(new PhabricatorApplicationTransactionTextDiffDetailView())
->setViewer($this->getViewer())

View file

@ -158,10 +158,6 @@ final class PhabricatorPackagesPackage
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
/* -( PhabricatorDestructibleInterface )----------------------------------- */

View file

@ -134,10 +134,6 @@ final class PhabricatorPackagesPublisher
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
/* -( PhabricatorDestructibleInterface )----------------------------------- */

View file

@ -126,10 +126,6 @@ final class PhabricatorPackagesVersion
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
/* -( PhabricatorExtendedPolicyInterface )--------------------------------- */

View file

@ -155,10 +155,6 @@ final class PassphraseCredential extends PassphraseDAO
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
/* -( PhabricatorSubscribableInterface )----------------------------------- */

View file

@ -104,6 +104,10 @@ final class PhabricatorPasteContentTransaction
return true;
}
public function getMailDiffSectionHeader() {
return pht('CHANGES TO PASTE CONTENT');
}
public function newChangeDetailView() {
$viewer = $this->getViewer();

View file

@ -154,7 +154,12 @@ final class PhabricatorMentionRemarkupRule extends PhutilRemarkupRule {
$tag->setDotColor(PHUITagView::COLOR_GREY);
} else {
if ($user->getAwayUntil()) {
$away = PhabricatorCalendarEventInvitee::AVAILABILITY_AWAY;
if ($user->getDisplayAvailability() == $away) {
$tag->setDotColor(PHUITagView::COLOR_RED);
} else {
$tag->setDotColor(PHUITagView::COLOR_ORANGE);
}
}
}
}

View file

@ -17,6 +17,7 @@ final class PhabricatorPeopleQuery
private $isApproved;
private $nameLike;
private $nameTokens;
private $namePrefixes;
private $needPrimaryEmail;
private $needProfile;
@ -95,6 +96,11 @@ final class PhabricatorPeopleQuery
return $this;
}
public function withNamePrefixes(array $prefixes) {
$this->namePrefixes = $prefixes;
return $this;
}
public function needPrimaryEmail($need) {
$this->needPrimaryEmail = $need;
return $this;
@ -256,6 +262,17 @@ final class PhabricatorPeopleQuery
$this->usernames);
}
if ($this->namePrefixes) {
$parts = array();
foreach ($this->namePrefixes as $name_prefix) {
$parts[] = qsprintf(
$conn,
'user.username LIKE %>',
$name_prefix);
}
$where[] = '('.implode(' OR ', $parts).')';
}
if ($this->emails !== null) {
$where[] = qsprintf(
$conn,

View file

@ -572,7 +572,7 @@ final class PhabricatorUser
return $this;
}
public function getSex() {
public function getGender() {
return $this->getUserSetting(PhabricatorPronounSetting::SETTINGKEY);
}

View file

@ -17,14 +17,19 @@ final class PhabricatorPeopleDatasource
public function loadResults() {
$viewer = $this->getViewer();
$tokens = $this->getTokens();
$query = id(new PhabricatorPeopleQuery())
->setOrderVector(array('username'));
if ($this->getPhase() == self::PHASE_PREFIX) {
$prefix = $this->getPrefixQuery();
$query->withNamePrefixes(array($prefix));
} else {
$tokens = $this->getTokens();
if ($tokens) {
$query->withNameTokens($tokens);
}
}
$users = $this->executeQuery($query);

View file

@ -314,8 +314,18 @@ final class PhabricatorObjectHandle
$classes[] = 'handle-status-'.$this->status;
}
$circle = null;
if ($this->availability != self::AVAILABILITY_FULL) {
$classes[] = 'handle-availability-'.$this->availability;
$circle = array(
phutil_tag(
'span',
array(
'class' => 'perfect-circle',
),
"\xE2\x80\xA2"),
' ',
);
}
if ($this->getType() == PhabricatorPeopleUserPHIDType::TYPECONST) {
@ -339,7 +349,7 @@ final class PhabricatorObjectHandle
return javelin_tag(
$uri ? 'a' : 'span',
$attributes,
array($icon, $name));
array($circle, $icon, $name));
}
public function renderTag() {

View file

@ -80,8 +80,4 @@ final class PhluxVariable extends PhluxDAO
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
}

View file

@ -119,8 +119,4 @@ final class PholioImage extends PholioDAO
return $this->getMock()->hasAutomaticCapability($capability, $viewer);
}
public function describeAutomaticCapability($capability) {
return null;
}
}

View file

@ -110,8 +110,4 @@ final class PhortuneProduct extends PhortuneDAO
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
}

View file

@ -345,8 +345,4 @@ final class PhragmentFragment extends PhragmentDAO
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
}

View file

@ -52,10 +52,6 @@ final class PhabricatorPolicyTestObject
return $this;
}
public function describeAutomaticCapability($capability) {
return null;
}
public function setExtendedPolicies(array $extended_policies) {
$this->extendedPolicies = $extended_policies;
return $this;

View file

@ -0,0 +1,106 @@
<?php
/**
* Rendering extensions that allows an object to render custom strings,
* descriptions and explanations for the policy system to help users
* understand complex policies.
*/
abstract class PhabricatorPolicyCodex
extends Phobject {
private $viewer;
private $object;
private $policy;
private $capability;
public function getPolicyShortName() {
return null;
}
public function getPolicyIcon() {
return null;
}
public function getPolicyTagClasses() {
return array();
}
public function getPolicySpecialRuleDescriptions() {
return array();
}
final protected function newRule() {
return new PhabricatorPolicyCodexRuleDescription();
}
final public function setViewer(PhabricatorUser $viewer) {
$this->viewer = $viewer;
return $this;
}
final public function getViewer() {
return $this->viewer;
}
final public function setObject(PhabricatorPolicyCodexInterface $object) {
$this->object = $object;
return $this;
}
final public function getObject() {
return $this->object;
}
final public function setCapability($capability) {
$this->capability = $capability;
return $this;
}
final public function getCapability() {
return $this->capability;
}
final public function setPolicy(PhabricatorPolicy $policy) {
$this->policy = $policy;
return $this;
}
final public function getPolicy() {
return $this->policy;
}
final public static function newFromObject(
PhabricatorPolicyCodexInterface $object,
PhabricatorUser $viewer) {
if (!($object instanceof PhabricatorPolicyInterface)) {
throw new Exception(
pht(
'Object (of class "%s") implements interface "%s", but must also '.
'implement interface "%s".',
get_class($object),
'PhabricatorPolicyCodexInterface',
'PhabricatorPolicyInterface'));
}
$codex = $object->newPolicyCodex();
if (!($codex instanceof PhabricatorPolicyCodex)) {
throw new Exception(
pht(
'Object (of class "%s") implements interface "%s", but defines '.
'method "%s" incorrectly: this method must return an object of '.
'class "%s".',
get_class($object),
'PhabricatorPolicyCodexInterface',
'newPolicyCodex()',
__CLASS__));
}
$codex
->setObject($object)
->setViewer($viewer);
return $codex;
}
}

View file

@ -0,0 +1,18 @@
<?php
interface PhabricatorPolicyCodexInterface {
public function newPolicyCodex();
}
// TEMPLATE IMPLEMENTATION /////////////////////////////////////////////////////
/* -( PhabricatorPolicyCodexInterface )------------------------------------ */
/*
public function newPolicyCodex() {
return new <<...>>PolicyCodex();
}
*/

View file

@ -0,0 +1,37 @@
<?php
final class PhabricatorPolicyCodexRuleDescription
extends Phobject {
private $description;
private $capabilities = array();
private $isActive = true;
public function setDescription($description) {
$this->description = $description;
return $this;
}
public function getDescription() {
return $this->description;
}
public function setCapabilities(array $capabilities) {
$this->capabilities = $capabilities;
return $this;
}
public function getCapabilities() {
return $this->capabilities;
}
public function setIsActive($is_active) {
$this->isActive = $is_active;
return $this;
}
public function getIsActive() {
return $this->isActive;
}
}

View file

@ -34,124 +34,118 @@ final class PhabricatorPolicyExplainController
->setViewer($viewer)
->withPHIDs(array($phid))
->executeOne();
$object_name = $handle->getName();
$object_uri = nonempty($handle->getURI(), '/');
$explanation = PhabricatorPolicy::getPolicyExplanation(
$viewer,
$policy->getPHID());
$auto_info = (array)$object->describeAutomaticCapability($capability);
$auto_info = array_merge(
array($explanation),
$auto_info);
$auto_info = array_filter($auto_info);
$capability_name = $capability;
$capobj = PhabricatorPolicyCapability::getCapabilityByKey($capability);
if ($capobj) {
$capability_name = $capobj->getCapabilityName();
}
$dialog = id(new AphrontDialogView())
->setUser($viewer)
->setClass('aphront-access-dialog');
$this->appendSpaceInformation($dialog, $object, $policy, $capability);
$intro = pht(
'Users with the "%s" capability for this object:',
$capability_name);
$object_name = pht(
'%s %s',
$handle->getTypeName(),
$handle->getObjectName());
$dialog
->setClass('aphront-access-dialog aphront-policy-explain-dialog')
->setTitle(pht('Policy Details: %s', $object_name))
->appendParagraph($intro)
->addCancelButton($object_uri, pht('Done'));
if ($auto_info) {
$dialog->appendList($auto_info);
}
$space_section = $this->buildSpaceSection(
$object,
$policy,
$capability);
$extended_section = $this->buildExtendedSection(
$object,
$capability);
$exceptions_section = $this->buildExceptionsSection(
$object,
$capability);
$object_section = $this->buildObjectSection(
$object,
$policy,
$capability,
$handle);
$dialog->appendChild(
array(
$space_section,
$extended_section,
$exceptions_section,
$object_section,
));
$this->appendStrengthInformation($dialog, $object, $policy, $capability);
return $dialog;
}
private function appendSpaceInformation(
AphrontDialogView $dialog,
private function buildSpaceSection(
PhabricatorPolicyInterface $object,
PhabricatorPolicy $policy,
$capability) {
$viewer = $this->getViewer();
if (!($object instanceof PhabricatorSpacesInterface)) {
return;
return null;
}
if (!PhabricatorSpacesNamespaceQuery::getSpacesExist($viewer)) {
return;
return null;
}
// NOTE: We're intentionally letting users through here, even if they only
// have access to one space. The intent is to help users in "space jail"
// understand who objects they create are visible to:
$space_phid = PhabricatorSpacesNamespaceQuery::getObjectSpacePHID(
$object);
$handles = $viewer->loadHandles(array($space_phid));
$doc_href = PhabricatorEnv::getDoclink('Spaces User Guide');
$dialog->appendParagraph(
array(
pht(
'This object is in %s, and can only be seen or edited by users with '.
'access to view objects in the space.',
$handles[$space_phid]->renderLink()),
' ',
phutil_tag(
'strong',
array(),
phutil_tag(
'a',
array(
'href' => $doc_href,
'target' => '_blank',
),
pht('Learn More'))),
));
$spaces = PhabricatorSpacesNamespaceQuery::getViewerSpaces($viewer);
$space = idx($spaces, $space_phid);
if (!$space) {
return;
return null;
}
$space_policies = PhabricatorPolicyQuery::loadPolicies($viewer, $space);
$space_policy = idx($space_policies, PhabricatorPolicyCapability::CAN_VIEW);
if (!$space_policy) {
return;
return null;
}
$doc_href = PhabricatorEnv::getDoclink('Spaces User Guide');
$capability_name = $this->getCapabilityName($capability);
$space_section = id(new PHUIPolicySectionView())
->setViewer($viewer)
->setIcon('fa-th-large bluegrey')
->setHeader(pht('Space'))
->setDocumentationLink(pht('Spaces Documentation'), $doc_href)
->appendList(
array(
array(
phutil_tag('strong', array(), pht('Space:')),
' ',
$viewer->renderHandle($space_phid)->setAsTag(true),
),
array(
phutil_tag('strong', array(), pht('%s:', $capability_name)),
' ',
$space_policy->getShortName(),
),
))
->appendParagraph(
pht(
'This object is in %s and can only be seen or edited by users '.
'with access to view objects in the space.',
$viewer->renderHandle($space_phid)));
$space_explanation = PhabricatorPolicy::getPolicyExplanation(
$viewer,
$space_policy->getPHID());
$items = array();
$items[] = $space_explanation;
$dialog->appendParagraph(pht('Users who can see objects in this space:'));
$dialog->appendList($items);
$space_section
->appendParagraph(pht('Users who can see objects in this space:'))
->appendList($items);
$view_capability = PhabricatorPolicyCapability::CAN_VIEW;
if ($capability == $view_capability) {
$stronger = $space_policy->isStrongerThan($policy);
if ($stronger) {
$dialog->appendParagraph(
$space_section->appendHint(
pht(
'The space this object is in has a more restrictive view '.
'policy ("%s") than the object does ("%s"), so the space\'s '.
@ -161,14 +155,15 @@ final class PhabricatorPolicyExplainController
}
}
$dialog->appendParagraph(
$space_section->appendHint(
pht(
'After a user passes space policy checks, they must still pass '.
'object policy checks.'));
return $space_section;
}
private function appendStrengthInformation(
AphrontDialogView $dialog,
private function getStrengthInformation(
PhabricatorPolicyInterface $object,
PhabricatorPolicy $policy,
$capability) {
@ -206,7 +201,126 @@ final class PhabricatorPolicyExplainController
$default_policy->getShortName());
}
$dialog->appendParagraph($info);
return $info;
}
private function getCapabilityName($capability) {
$capability_name = $capability;
$capobj = PhabricatorPolicyCapability::getCapabilityByKey($capability);
if ($capobj) {
$capability_name = $capobj->getCapabilityName();
}
return $capability_name;
}
private function buildExtendedSection(
PhabricatorPolicyInterface $object,
$capability) {
$viewer = $this->getViewer();
if (!($object instanceof PhabricatorExtendedPolicyInterface)) {
return null;
}
$extended_rules = $object->getExtendedPolicy($capability, $viewer);
if (!$extended_rules) {
return null;
}
$items = array();
foreach ($extended_rules as $extended_rule) {
$extended_target = $extended_rule[0];
$extended_capabilities = (array)$extended_rule[1];
if (is_object($extended_target)) {
$extended_target = $extended_target->getPHID();
}
foreach ($extended_capabilities as $extended_capability) {
$ex_name = $this->getCapabilityName($extended_capability);
$items[] = array(
phutil_tag('strong', array(), pht('%s:', $ex_name)),
' ',
$viewer->renderHandle($extended_target)->setAsTag(true),
);
}
}
return id(new PHUIPolicySectionView())
->setViewer($viewer)
->setIcon('fa-link')
->setHeader(pht('Required Capabilities on Other Objects'))
->appendParagraph(
pht(
'To access this object, users must have first have access '.
'capabilties on these other objects:'))
->appendList($items);
}
private function buildExceptionsSection(
PhabricatorPolicyInterface $object,
$capability) {
$viewer = $this->getViewer();
$exceptions = PhabricatorPolicy::getSpecialRules(
$object,
$viewer,
$capability,
false);
if (!$exceptions) {
return null;
}
return id(new PHUIPolicySectionView())
->setViewer($viewer)
->setIcon('fa-unlock-alt red')
->setHeader(pht('Special Rules'))
->appendParagraph(
pht(
'This object has special rules which override normal object '.
'policy rules:'))
->appendList($exceptions);
}
private function buildObjectSection(
PhabricatorPolicyInterface $object,
PhabricatorPolicy $policy,
$capability,
PhabricatorObjectHandle $handle) {
$viewer = $this->getViewer();
$capability_name = $this->getCapabilityName($capability);
$object_section = id(new PHUIPolicySectionView())
->setViewer($viewer)
->setIcon($handle->getIcon().' bluegrey')
->setHeader(pht('Object Policy'))
->appendList(
array(
array(
phutil_tag('strong', array(), pht('%s:', $capability_name)),
' ',
$policy->getShortName(),
),
))
->appendParagraph(
pht(
'In detail, this means that these users can take this action, '.
'provided they pass all of the checks described above first:'))
->appendList(
array(
PhabricatorPolicy::getPolicyExplanation(
$viewer,
$policy->getPHID()),
));
$strength = $this->getStrengthInformation($object, $policy, $capability);
if ($strength) {
$object_section->appendHint($strength);
}
return $object_section;
}
}

View file

@ -581,9 +581,16 @@ final class PhabricatorPolicyFilter extends Phobject {
}
$more = PhabricatorPolicy::getPolicyExplanation($this->viewer, $policy);
$exceptions = $object->describeAutomaticCapability($capability);
$more = (array)$more;
$more = array_filter($more);
$details = array_filter(array_merge(array($more), (array)$exceptions));
$exceptions = PhabricatorPolicy::getSpecialRules(
$object,
$this->viewer,
$capability,
true);
$details = array_filter(array_merge($more, $exceptions));
$access_denied = $this->renderAccessDenied($object);

View file

@ -6,34 +6,6 @@ interface PhabricatorPolicyInterface extends PhabricatorPHIDInterface {
public function getPolicy($capability);
public function hasAutomaticCapability($capability, PhabricatorUser $viewer);
/**
* Describe exceptions to an object's policy setting.
*
* The intent of this method is to explain and inform users about special
* cases which override configured policy settings. If this object has any
* such exceptions, explain them by returning one or more human-readable
* strings which describe the exception in a broad, categorical way. For
* example:
*
* - "The owner of an X can always view and edit it."
* - "Members of a Y can always view it."
*
* You can return `null`, a single string, or a list of strings.
*
* The relevant capability to explain (like "view") is passed as a parameter.
* You should tailor any messages to be relevant to that capability, although
* they do not need to exclusively describe the capability, and in some cases
* being more general ("The author can view and edit...") will be more clear.
*
* Messages should describe general rules, not specific objects, because the
* main goal is to teach the user the rules. For example, write "the author",
* not the specific author's name.
*
* @param const @{class:PhabricatorPolicyCapability} constant.
* @return wild Description of policy exceptions. See above.
*/
public function describeAutomaticCapability($capability);
}
// TEMPLATE IMPLEMENTATION /////////////////////////////////////////////////////
@ -58,8 +30,4 @@ interface PhabricatorPolicyInterface extends PhabricatorPHIDInterface {
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
*/

View file

@ -225,7 +225,9 @@ final class PhabricatorPolicy
switch ($policy) {
case PhabricatorPolicies::POLICY_PUBLIC:
return pht('This object is public.');
return pht(
'This object is public and can be viewed by anyone, even if they '.
'do not have a Phabricator account.');
case PhabricatorPolicies::POLICY_USER:
return pht('Logged in users can take this action.');
case PhabricatorPolicies::POLICY_ADMIN:
@ -420,6 +422,54 @@ final class PhabricatorPolicy
return ($this_strength > $other_strength);
}
public static function getSpecialRules(
PhabricatorPolicyInterface $object,
PhabricatorUser $viewer,
$capability,
$active_only) {
if ($object instanceof PhabricatorPolicyCodexInterface) {
$codex = PhabricatorPolicyCodex::newFromObject($object, $viewer);
$rules = $codex->getPolicySpecialRuleDescriptions();
$exceptions = array();
foreach ($rules as $rule) {
$is_active = $rule->getIsActive();
if ($is_active) {
$rule_capabilities = $rule->getCapabilities();
if ($rule_capabilities) {
if (!in_array($capability, $rule_capabilities)) {
$is_active = false;
}
}
}
if (!$is_active && $active_only) {
continue;
}
$description = $rule->getDescription();
if (!$is_active) {
$description = phutil_tag(
'span',
array(
'class' => 'phui-policy-section-view-inactive-rule',
),
$description);
}
$exceptions[] = $description;
}
} else if (method_exists($object, 'describeAutomaticCapability')) {
$exceptions = (array)$object->describeAutomaticCapability($capability);
$exceptions = array_filter($exceptions);
} else {
$exceptions = array();
}
return $exceptions;
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */
@ -442,10 +492,6 @@ final class PhabricatorPolicy
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
/* -( PhabricatorDestructibleInterface )----------------------------------- */

View file

@ -0,0 +1,142 @@
<?php
final class PHUIPolicySectionView
extends AphrontTagView {
private $icon;
private $header;
private $documentationLink;
public function setHeader($header) {
$this->header = $header;
return $this;
}
public function getHeader() {
return $this->header;
}
public function setIcon($icon) {
$this->icon = $icon;
return $this;
}
public function getIcon() {
return $this->icon;
}
public function setDocumentationLink($name, $href) {
$link = phutil_tag(
'a',
array(
'href' => $href,
'target' => '_blank',
),
$name);
$this->documentationLink = phutil_tag(
'div',
array(
'class' => 'phui-policy-section-view-link',
),
array(
id(new PHUIIconView())->setIcon('fa-book'),
$link,
));
return $this;
}
public function getDocumentationLink() {
return $this->documentationLink;
}
public function appendList(array $items) {
foreach ($items as $key => $item) {
$items[$key] = phutil_tag(
'li',
array(
'class' => 'remarkup-list-item',
),
$item);
}
$list = phutil_tag(
'ul',
array(
'class' => 'remarkup-list',
),
$items);
return $this->appendChild($list);
}
public function appendHint($content) {
$hint = phutil_tag(
'p',
array(
'class' => 'phui-policy-section-view-hint',
),
array(
id(new PHUIIconView())
->setIcon('fa-sticky-note bluegrey'),
' ',
pht('Note:'),
' ',
$content,
));
return $this->appendChild($hint);
}
public function appendParagraph($content) {
return $this->appendChild(phutil_tag('p', array(), $content));
}
protected function getTagAttributes() {
return array(
'class' => 'phui-policy-section-view',
);
}
protected function getTagContent() {
require_celerity_resource('phui-header-view-css');
$icon_view = null;
$icon = $this->getIcon();
if ($icon !== null) {
$icon_view = id(new PHUIIconView())
->setIcon($icon);
}
$header_view = phutil_tag(
'span',
array(
'class' => 'phui-policy-section-view-header-text',
),
$this->getHeader());
$header = phutil_tag(
'div',
array(
'class' => 'phui-policy-section-view-header',
),
array(
$icon_view,
$header_view,
$this->getDocumentationLink(),
));
return array(
$header,
phutil_tag(
'div',
array(
'class' => 'phui-policy-section-view-body',
),
$this->renderChildren()),
);
}
}

View file

@ -35,7 +35,7 @@ final class PhabricatorProjectSubprojectWarningController
$conversion_help = pht(
"Creating a project's first subproject **moves all ".
"members** to become members of the subproject instead".
"members** to become members of the subproject instead.".
"\n\n".
"See [[ %s | Projects User Guide ]] in the documentation for details. ".
"This process can not be undone.",

View file

@ -12,6 +12,7 @@ final class PhabricatorProjectQuery
private $slugMap;
private $allSlugs;
private $names;
private $namePrefixes;
private $nameTokens;
private $icons;
private $colors;
@ -78,6 +79,11 @@ final class PhabricatorProjectQuery
return $this;
}
public function withNamePrefixes(array $prefixes) {
$this->namePrefixes = $prefixes;
return $this;
}
public function withNameTokens(array $tokens) {
$this->nameTokens = array_values($tokens);
return $this;
@ -254,14 +260,14 @@ final class PhabricatorProjectQuery
$all_graph = $this->getAllReachableAncestors($projects);
if ($this->needAncestorMembers || $this->needWatchers) {
$src_projects = $all_graph;
} else {
$src_projects = $projects;
}
// NOTE: Although we may not need much information about ancestors, we
// always need to test if the viewer is a member, because we will return
// ancestor projects to the policy filter via ExtendedPolicy calls. If
// we skip populating membership data on a parent, the policy framework
// will think the user is not a member of the parent project.
$all_sources = array();
foreach ($src_projects as $project) {
foreach ($all_graph as $project) {
// For milestones, we need parent members.
if ($project->isMilestone()) {
$parent_phid = $project->getParentProjectPHID();
@ -300,7 +306,7 @@ final class PhabricatorProjectQuery
}
$membership_projects = array();
foreach ($src_projects as $project) {
foreach ($all_graph as $project) {
$project_phid = $project->getPHID();
if ($project->isMilestone()) {
@ -464,6 +470,17 @@ final class PhabricatorProjectQuery
$this->names);
}
if ($this->namePrefixes) {
$parts = array();
foreach ($this->namePrefixes as $name_prefix) {
$parts[] = qsprintf(
$conn,
'name LIKE %>',
$name_prefix);
}
$where[] = '('.implode(' OR ', $parts).')';
}
if ($this->icons !== null) {
$where[] = qsprintf(
$conn,

View file

@ -87,8 +87,4 @@ final class PhabricatorProjectColumnPosition extends PhabricatorProjectDAO
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
}

View file

@ -28,7 +28,10 @@ final class PhabricatorProjectDatasource
->needImages(true)
->needSlugs(true);
if ($tokens) {
if ($this->getPhase() == self::PHASE_PREFIX) {
$prefix = $this->getPrefixQuery();
$query->withNamePrefixes(array($prefix));
} else if ($tokens) {
$query->withNameTokens($tokens);
}

View file

@ -153,9 +153,4 @@ final class ReleephProject extends ReleephDAO
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
}

View file

@ -2330,11 +2330,6 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
/* -( PhabricatorMarkupInterface )----------------------------------------- */

View file

@ -130,8 +130,4 @@ final class PhabricatorRepositoryCommitHint
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
}

View file

@ -45,10 +45,6 @@ final class PhabricatorRepositoryGitLFSRef
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
/* -( PhabricatorDestructibleInterface )----------------------------------- */

View file

@ -45,8 +45,4 @@ final class PhabricatorRepositoryOldRef
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
}

View file

@ -642,10 +642,6 @@ final class PhabricatorRepositoryURI
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
/* -( PhabricatorExtendedPolicyInterface )--------------------------------- */

View file

@ -162,11 +162,6 @@ final class PhabricatorProfilePanelConfiguration
}
public function describeAutomaticCapability($capability) {
return null;
}
/* -( PhabricatorExtendedPolicyInterface )--------------------------------- */

View file

@ -81,8 +81,4 @@ final class PhabricatorSavedQuery extends PhabricatorSearchDAO
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
}

View file

@ -1,16 +0,0 @@
<?php
final class PhabricatorDiffusionColorSetting
extends PhabricatorInternalSetting {
const SETTINGKEY = 'diffusion-color';
public function getSettingName() {
return pht('Diffusion Color');
}
public function getSettingDefaultValue() {
return false;
}
}

View file

@ -22,7 +22,7 @@ final class PhabricatorPronounSetting
}
public function getSettingDefaultValue() {
return PhutilPerson::SEX_UNKNOWN;
return PhutilPerson::GENDER_UNKNOWN;
}
protected function getSelectOptions() {
@ -37,9 +37,9 @@ final class PhabricatorPronounSetting
$label_his = pht('%s updated his profile', $username);
return array(
PhutilPerson::SEX_UNKNOWN => $label_unknown,
PhutilPerson::SEX_MALE => $label_his,
PhutilPerson::SEX_FEMALE => $label_her,
PhutilPerson::GENDER_UNKNOWN => $label_unknown,
PhutilPerson::GENDER_MASCULINE => $label_his,
PhutilPerson::GENDER_FEMININE => $label_her,
);
}

View file

@ -32,7 +32,6 @@ final class PhabricatorTranslationSetting
}
protected function getSelectOptionGroups() {
$is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business');
$locales = PhutilLocale::loadAllLocales();
$group_labels = array(
@ -56,10 +55,6 @@ final class PhabricatorTranslationSetting
unset($raw_scope);
if ($locale->isSillyLocale()) {
if ($is_serious) {
// Omit silly locales on serious business installs.
continue;
}
$groups['silly'][$code] = $name;
continue;
}
@ -89,6 +84,20 @@ final class PhabricatorTranslationSetting
$groups[$type][$code] = $name;
}
// Omit silly locales on serious business installs.
$is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business');
if ($is_serious) {
unset($groups['silly']);
}
// Omit limited and test translations if Phabricator is not in developer
// mode.
$is_dev = PhabricatorEnv::getEnvConfig('phabricator.developer-mode');
if (!$is_dev) {
unset($groups['limited']);
unset($groups['test']);
}
$results = array();
foreach ($groups as $key => $group) {
$label = $group_labels[$key];

View file

@ -222,11 +222,6 @@ final class PhabricatorUserPreferences
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
/* -( PhabricatorDestructibleInterface )----------------------------------- */

View file

@ -84,11 +84,6 @@ final class PhabricatorSpacesNamespace
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
/* -( PhabricatorApplicationTransactionInterface )------------------------- */

View file

@ -28,10 +28,6 @@ final class PhabricatorToken extends PhabricatorTokenDAO
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
public function renderIcon() {
// TODO: Maybe move to a View class?

View file

@ -42,6 +42,7 @@ final class PhabricatorApplicationTransactionDetailController
return $this->newDialog()
->setTitle(pht('Change Details'))
->setWidth(AphrontDialogView::WIDTH_FORM)
->setClass('aphront-dialog-tab-group')
->appendChild($details)
->addCancelButton($cancel_uri, $button_text);
}

View file

@ -2275,7 +2275,4 @@ abstract class PhabricatorEditEngine
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
}

View file

@ -1141,9 +1141,15 @@ abstract class PhabricatorApplicationTransactionEditor
PhabricatorLiskDAO $object,
array $xactions) {
$this->object = $object;
$this->xactions = $xactions;
// Hook for edges or other properties that may need (re-)loading
$object = $this->willPublish($object, $xactions);
// The object might have changed, so reassign it.
$this->object = $object;
$messages = array();
if (!$this->getDisableEmail()) {
if ($this->shouldSendMail($object, $xactions)) {
@ -2871,12 +2877,24 @@ abstract class PhabricatorApplicationTransactionEditor
foreach ($details as $xaction) {
$details = $xaction->renderChangeDetailsForMail($body->getViewer());
if ($details !== null) {
$body->addHTMLSection(pht('EDIT DETAILS'), $details);
$label = $this->getMailDiffSectionHeader($xaction);
$body->addHTMLSection($label, $details);
}
}
}
private function getMailDiffSectionHeader($xaction) {
$type = $xaction->getTransactionType();
$xtype = $this->getModularTransactionType($type);
if ($xtype) {
return $xtype->getMailDiffSectionHeader();
}
return pht('EDIT DETAILS');
}
/**
* @task mail
*/

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