mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-27 17:22:42 +01:00
(stable) Promote 2016 Week 46
This commit is contained in:
commit
b285d3cebf
133 changed files with 1933 additions and 870 deletions
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -167,10 +167,6 @@ final class AlmanacDevice
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorExtendedPolicyInterface )--------------------------------- */
|
||||
|
||||
|
|
|
@ -174,10 +174,6 @@ final class AlmanacNamespace
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorApplicationTransactionInterface )------------------------- */
|
||||
|
||||
|
|
|
@ -92,10 +92,6 @@ final class AlmanacNetwork
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorDestructibleInterface )----------------------------------- */
|
||||
|
||||
|
|
|
@ -184,10 +184,6 @@ final class AlmanacService
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorExtendedPolicyInterface )--------------------------------- */
|
||||
|
||||
|
|
|
@ -130,8 +130,4 @@ final class PhabricatorAuthProviderConfig
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -125,8 +125,4 @@ final class PhabricatorAuthTemporaryToken extends PhabricatorAuthDAO
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -76,8 +76,4 @@ final class PhabricatorBadgesAward extends PhabricatorBadgesDAO
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -129,10 +129,6 @@ final class PhabricatorBadgesBadge extends PhabricatorBadgesDAO
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorApplicationTransactionInterface )------------------------- */
|
||||
|
||||
|
|
|
@ -483,10 +483,6 @@ abstract class PhabricatorApplication
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* -( Policies )----------------------------------------------------------- */
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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(),
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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(),
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
}
|
||||
|
||||
}
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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 )------------------------- */
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -159,11 +159,6 @@ final class PhabricatorCalendarExport extends PhabricatorCalendarDAO
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorApplicationTransactionInterface )------------------------- */
|
||||
|
||||
|
||||
|
|
|
@ -68,7 +68,4 @@ final class PhabricatorCalendarExternalInvitee
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -132,10 +132,6 @@ final class PhabricatorCalendarImport
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorApplicationTransactionInterface )------------------------- */
|
||||
|
||||
|
|
|
@ -86,10 +86,6 @@ final class PhabricatorCalendarImportLog
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorDestructibleInterface )----------------------------------- */
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -30,6 +30,10 @@ final class PhabricatorCalendarEventDescriptionTransaction
|
|||
return true;
|
||||
}
|
||||
|
||||
public function getMailDiffSectionHeader() {
|
||||
return pht('CHANGES TO EVENT DESCRIPTION');
|
||||
}
|
||||
|
||||
public function newChangeDetailView() {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
|
|
|
@ -48,8 +48,4 @@ final class PhabricatorChatLogChannel
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -56,8 +56,4 @@ final class PhabricatorChatLogEvent
|
|||
return $this->getChannel()->hasAutomaticCapability($capability, $viewer);
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -372,10 +372,6 @@ abstract class ConduitAPIMethod
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function hasApplicationCapability(
|
||||
$capability,
|
||||
PhabricatorUser $viewer) {
|
||||
|
|
|
@ -52,8 +52,4 @@ final class PhabricatorConduitMethodCallLog
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -95,8 +95,4 @@ final class PhabricatorConfigEntry
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -139,10 +139,6 @@ final class PhabricatorCountdown extends PhabricatorCountdownDAO
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* -( PhabricatorSpacesInterface )------------------------------------------- */
|
||||
|
||||
public function getSpacePHID() {
|
||||
|
|
|
@ -77,8 +77,4 @@ final class PhabricatorDaemonLog extends PhabricatorDaemonDAO
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -160,10 +160,6 @@ final class PhabricatorDashboard extends PhabricatorDashboardDAO
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorDestructibleInterface )----------------------------------- */
|
||||
|
||||
|
|
|
@ -159,10 +159,6 @@ final class PhabricatorDashboardPanel
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorCustomFieldInterface )------------------------------------ */
|
||||
|
||||
|
|
|
@ -226,8 +226,4 @@ final class DifferentialChangeset extends DifferentialDAO
|
|||
return $this->getDiff()->hasAutomaticCapability($capability, $viewer);
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -228,8 +228,4 @@ abstract class DifferentialHunk extends DifferentialDAO
|
|||
return $this->getChangeset()->hasAutomaticCapability($capability, $viewer);
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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))));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -114,10 +114,6 @@ final class DivinerLiveBook extends DivinerDAO
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorDestructibleInterface )----------------------------------- */
|
||||
|
||||
|
|
|
@ -121,8 +121,4 @@ final class DoorkeeperExternalObject extends DoorkeeperDAO
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -325,10 +325,6 @@ final class DrydockBlueprint extends DrydockDAO
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorCustomFieldInterface )------------------------------------ */
|
||||
|
||||
|
|
|
@ -454,11 +454,6 @@ abstract class PhabricatorFeedStory
|
|||
}
|
||||
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorMarkupInterface Implementation )--------------------------- */
|
||||
|
||||
|
||||
|
|
|
@ -77,11 +77,6 @@ final class PhabricatorFileChunk extends PhabricatorFileDAO
|
|||
}
|
||||
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorDestructibleInterface )----------------------------------- */
|
||||
|
||||
|
||||
|
|
|
@ -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 '.
|
||||
|
|
|
@ -93,8 +93,4 @@ final class LegalpadDocumentSignature
|
|||
return ($viewer->getPHID() == $this->getSignerPHID());
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -139,8 +139,4 @@ final class PhabricatorFileImageMacro extends PhabricatorFileDAO
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -63,8 +63,4 @@ final class NuanceImportCursorData
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -48,8 +48,4 @@ final class NuanceItemCommand
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -67,10 +67,6 @@ final class NuanceQueue
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorApplicationTransactionInterface )------------------------- */
|
||||
|
||||
|
|
|
@ -138,10 +138,6 @@ final class NuanceSource extends NuanceDAO
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorNgramsInterface )----------------------------------------- */
|
||||
|
||||
|
|
|
@ -83,10 +83,6 @@ final class PhabricatorOAuthServerClient
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorApplicationTransactionInterface )------------------------- */
|
||||
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -158,10 +158,6 @@ final class PhabricatorPackagesPackage
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorDestructibleInterface )----------------------------------- */
|
||||
|
||||
|
|
|
@ -134,10 +134,6 @@ final class PhabricatorPackagesPublisher
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorDestructibleInterface )----------------------------------- */
|
||||
|
||||
|
|
|
@ -126,10 +126,6 @@ final class PhabricatorPackagesVersion
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorExtendedPolicyInterface )--------------------------------- */
|
||||
|
||||
|
|
|
@ -155,10 +155,6 @@ final class PassphraseCredential extends PassphraseDAO
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorSubscribableInterface )----------------------------------- */
|
||||
|
||||
|
|
|
@ -104,6 +104,10 @@ final class PhabricatorPasteContentTransaction
|
|||
return true;
|
||||
}
|
||||
|
||||
public function getMailDiffSectionHeader() {
|
||||
return pht('CHANGES TO PASTE CONTENT');
|
||||
}
|
||||
|
||||
public function newChangeDetailView() {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -572,7 +572,7 @@ final class PhabricatorUser
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function getSex() {
|
||||
public function getGender() {
|
||||
return $this->getUserSetting(PhabricatorPronounSetting::SETTINGKEY);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -80,8 +80,4 @@ final class PhluxVariable extends PhluxDAO
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -119,8 +119,4 @@ final class PholioImage extends PholioDAO
|
|||
return $this->getMock()->hasAutomaticCapability($capability, $viewer);
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -110,8 +110,4 @@ final class PhortuneProduct extends PhortuneDAO
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -345,8 +345,4 @@ final class PhragmentFragment extends PhragmentDAO
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
106
src/applications/policy/codex/PhabricatorPolicyCodex.php
Normal file
106
src/applications/policy/codex/PhabricatorPolicyCodex.php
Normal 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;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
interface PhabricatorPolicyCodexInterface {
|
||||
|
||||
public function newPolicyCodex();
|
||||
|
||||
}
|
||||
|
||||
// TEMPLATE IMPLEMENTATION /////////////////////////////////////////////////////
|
||||
|
||||
/* -( PhabricatorPolicyCodexInterface )------------------------------------ */
|
||||
/*
|
||||
|
||||
public function newPolicyCodex() {
|
||||
return new <<...>>PolicyCodex();
|
||||
}
|
||||
|
||||
*/
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
*/
|
||||
|
|
|
@ -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 )----------------------------------- */
|
||||
|
||||
|
|
142
src/applications/policy/view/PHUIPolicySectionView.php
Normal file
142
src/applications/policy/view/PHUIPolicySectionView.php
Normal 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()),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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.",
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -87,8 +87,4 @@ final class PhabricatorProjectColumnPosition extends PhabricatorProjectDAO
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -153,9 +153,4 @@ final class ReleephProject extends ReleephDAO
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -2330,11 +2330,6 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* -( PhabricatorMarkupInterface )----------------------------------------- */
|
||||
|
||||
|
|
|
@ -130,8 +130,4 @@ final class PhabricatorRepositoryCommitHint
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -45,10 +45,6 @@ final class PhabricatorRepositoryGitLFSRef
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorDestructibleInterface )----------------------------------- */
|
||||
|
||||
|
|
|
@ -45,8 +45,4 @@ final class PhabricatorRepositoryOldRef
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -642,10 +642,6 @@ final class PhabricatorRepositoryURI
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorExtendedPolicyInterface )--------------------------------- */
|
||||
|
||||
|
|
|
@ -162,11 +162,6 @@ final class PhabricatorProfilePanelConfiguration
|
|||
}
|
||||
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorExtendedPolicyInterface )--------------------------------- */
|
||||
|
||||
|
||||
|
|
|
@ -81,8 +81,4 @@ final class PhabricatorSavedQuery extends PhabricatorSearchDAO
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -222,11 +222,6 @@ final class PhabricatorUserPreferences
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorDestructibleInterface )----------------------------------- */
|
||||
|
||||
|
||||
|
|
|
@ -84,11 +84,6 @@ final class PhabricatorSpacesNamespace
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorApplicationTransactionInterface )------------------------- */
|
||||
|
||||
|
||||
|
|
|
@ -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?
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -2275,7 +2275,4 @@ abstract class PhabricatorEditEngine
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
Loading…
Reference in a new issue