1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-15 18:10:53 +01:00

Manually merge "master" onto "stable"

We had some cherry-picks this week so the auto-merge isn't clean. Just do
it manually.
This commit is contained in:
epriestley 2017-05-19 15:31:30 -07:00
commit 88935dec13
145 changed files with 6383 additions and 4598 deletions

View file

@ -9,11 +9,11 @@ return array(
'names' => array(
'conpherence.pkg.css' => 'ff161f2d',
'conpherence.pkg.js' => 'b5b51108',
'core.pkg.css' => '24ffbe93',
'core.pkg.js' => '2ff7879f',
'core.pkg.css' => '5ffe8b79',
'core.pkg.js' => 'e822b496',
'darkconsole.pkg.js' => '1f9a31bc',
'differential.pkg.css' => '90b30783',
'differential.pkg.js' => 'ddfeb49b',
'differential.pkg.css' => '4d7dd14e',
'differential.pkg.js' => '68a4fa60',
'diffusion.pkg.css' => 'b93d9b8c',
'diffusion.pkg.js' => '84c8f8fd',
'favicon.ico' => '30672e08',
@ -64,9 +64,9 @@ return array(
'rsrc/css/application/dashboard/dashboard.css' => 'fe5b1869',
'rsrc/css/application/diff/inline-comment-summary.css' => '51efda3a',
'rsrc/css/application/differential/add-comment.css' => 'c47f8c40',
'rsrc/css/application/differential/changeset-view.css' => '41af6d25',
'rsrc/css/application/differential/changeset-view.css' => '54774a28',
'rsrc/css/application/differential/core.css' => '5b7b8ff4',
'rsrc/css/application/differential/phui-inline-comment.css' => 'be663c95',
'rsrc/css/application/differential/phui-inline-comment.css' => 'ffd1a542',
'rsrc/css/application/differential/revision-comment.css' => '14b8565a',
'rsrc/css/application/differential/revision-history.css' => '0e8eb855',
'rsrc/css/application/differential/revision-list.css' => 'f3c47d33',
@ -116,7 +116,7 @@ return array(
'rsrc/css/core/core.css' => '9f4cb463',
'rsrc/css/core/remarkup.css' => 'd1a5e11e',
'rsrc/css/core/syntax.css' => 'cae95e89',
'rsrc/css/core/z-index.css' => '0233d039',
'rsrc/css/core/z-index.css' => '998f3ce1',
'rsrc/css/diviner/diviner-shared.css' => '896f1d43',
'rsrc/css/font/font-awesome.css' => 'e838e088',
'rsrc/css/font/font-lato.css' => 'c7ccd872',
@ -129,9 +129,9 @@ return array(
'rsrc/css/phui/calendar/phui-calendar.css' => '477acfaa',
'rsrc/css/phui/object-item/phui-oi-big-ui.css' => '19f9369b',
'rsrc/css/phui/object-item/phui-oi-color.css' => 'cd2b9b77',
'rsrc/css/phui/object-item/phui-oi-drag-ui.css' => 'f12cbc9f',
'rsrc/css/phui/object-item/phui-oi-drag-ui.css' => '08f4ccc3',
'rsrc/css/phui/object-item/phui-oi-flush-ui.css' => '9d9685d6',
'rsrc/css/phui/object-item/phui-oi-list-view.css' => '7c8ec27a',
'rsrc/css/phui/object-item/phui-oi-list-view.css' => '412bef1a',
'rsrc/css/phui/object-item/phui-oi-simple-ui.css' => 'a8beebea',
'rsrc/css/phui/phui-action-list.css' => 'c01858f4',
'rsrc/css/phui/phui-action-panel.css' => '91c7b835',
@ -145,7 +145,7 @@ return array(
'rsrc/css/phui/phui-comment-form.css' => '57af2e14',
'rsrc/css/phui/phui-comment-panel.css' => 'f50152ad',
'rsrc/css/phui/phui-crumbs-view.css' => '6ece3bbb',
'rsrc/css/phui/phui-curtain-view.css' => '679743bb',
'rsrc/css/phui/phui-curtain-view.css' => '55dd0e59',
'rsrc/css/phui/phui-document-pro.css' => '62c4dcbf',
'rsrc/css/phui/phui-document-summary.css' => '9ca48bdf',
'rsrc/css/phui/phui-document.css' => 'c32e8dec',
@ -160,7 +160,7 @@ return array(
'rsrc/css/phui/phui-icon.css' => '12b387a1',
'rsrc/css/phui/phui-image-mask.css' => 'a8498f9c',
'rsrc/css/phui/phui-info-panel.css' => '27ea50a1',
'rsrc/css/phui/phui-info-view.css' => 'ec92802a',
'rsrc/css/phui/phui-info-view.css' => '6e217679',
'rsrc/css/phui/phui-invisible-character-view.css' => '6993d9f0',
'rsrc/css/phui/phui-lightbox.css' => '0a035e40',
'rsrc/css/phui/phui-list.css' => '12eb8ce6',
@ -173,7 +173,7 @@ return array(
'rsrc/css/phui/phui-spacing.css' => '042804d6',
'rsrc/css/phui/phui-status.css' => 'd5263e49',
'rsrc/css/phui/phui-tag-view.css' => 'cc4fd402',
'rsrc/css/phui/phui-timeline-view.css' => '1d7ef61d',
'rsrc/css/phui/phui-timeline-view.css' => '313c7f22',
'rsrc/css/phui/phui-two-column-view.css' => 'ce9fa0b7',
'rsrc/css/phui/workboards/phui-workboard-color.css' => '783cdff5',
'rsrc/css/phui/workboards/phui-workboard.css' => '3bc85455',
@ -237,7 +237,7 @@ return array(
'rsrc/externals/javelin/ext/view/__tests__/ViewInterpreter.js' => '7a94d6a5',
'rsrc/externals/javelin/ext/view/__tests__/ViewRenderer.js' => '6ea96ac9',
'rsrc/externals/javelin/lib/Cookie.js' => '62dfea03',
'rsrc/externals/javelin/lib/DOM.js' => '805b806a',
'rsrc/externals/javelin/lib/DOM.js' => '4976858c',
'rsrc/externals/javelin/lib/History.js' => 'd4505101',
'rsrc/externals/javelin/lib/JSON.js' => '69adf288',
'rsrc/externals/javelin/lib/Leader.js' => '7f243deb',
@ -390,17 +390,15 @@ return array(
'rsrc/js/application/dashboard/behavior-dashboard-move-panels.js' => '408bf173',
'rsrc/js/application/dashboard/behavior-dashboard-query-panel-select.js' => '453c5375',
'rsrc/js/application/dashboard/behavior-dashboard-tab-panel.js' => 'd4eecc63',
'rsrc/js/application/diff/DiffChangeset.js' => 'cf4e2140',
'rsrc/js/application/diff/DiffChangesetList.js' => '5c68c40c',
'rsrc/js/application/diff/DiffInline.js' => '77e14b60',
'rsrc/js/application/diff/ScrollObjective.js' => '0eee7a00',
'rsrc/js/application/diff/ScrollObjectiveList.js' => '1ca4d9db',
'rsrc/js/application/diff/behavior-preview-link.js' => '051c7832',
'rsrc/js/application/differential/ChangesetViewManager.js' => 'a2828756',
'rsrc/js/application/differential/DifferentialInlineCommentEditor.js' => '2e3f9738',
'rsrc/js/application/differential/behavior-comment-jump.js' => '4fdb476d',
'rsrc/js/application/differential/behavior-comment-preview.js' => 'b064af76',
'rsrc/js/application/differential/behavior-comment-preview.js' => '51c5ad07',
'rsrc/js/application/differential/behavior-diff-radios.js' => 'e1ff79b1',
'rsrc/js/application/differential/behavior-dropdown-menus.js' => '9a6b9324',
'rsrc/js/application/differential/behavior-edit-inline-comments.js' => '4fbbc3e9',
'rsrc/js/application/differential/behavior-keyboard-nav.js' => '92904457',
'rsrc/js/application/differential/behavior-populate.js' => '8694b1df',
'rsrc/js/application/differential/behavior-toggle-files.js' => 'ca3f91eb',
'rsrc/js/application/differential/behavior-populate.js' => '5e41c819',
'rsrc/js/application/differential/behavior-user-select.js' => 'a8d8459d',
'rsrc/js/application/diffusion/DiffusionLocateFileSource.js' => 'c93358e3',
'rsrc/js/application/diffusion/behavior-audit-preview.js' => 'd835b03a',
@ -450,7 +448,7 @@ return array(
'rsrc/js/application/transactions/behavior-comment-actions.js' => '9a6dd75c',
'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',
'rsrc/js/application/transactions/behavior-show-older-transactions.js' => 'ae95d984',
'rsrc/js/application/transactions/behavior-transaction-comment-form.js' => 'b23b49e6',
'rsrc/js/application/transactions/behavior-transaction-list.js' => '1f6794f6',
'rsrc/js/application/typeahead/behavior-typeahead-browse.js' => '635de1ec',
@ -475,7 +473,7 @@ return array(
'rsrc/js/core/FileUpload.js' => '680ea2c8',
'rsrc/js/core/Hovercard.js' => '1bd28176',
'rsrc/js/core/KeyboardShortcut.js' => '1ae869f2',
'rsrc/js/core/KeyboardShortcutManager.js' => '4a021c10',
'rsrc/js/core/KeyboardShortcutManager.js' => 'c19dd9b9',
'rsrc/js/core/MultirowRowManager.js' => 'b5d57730',
'rsrc/js/core/Notification.js' => 'ccf1cbf8',
'rsrc/js/core/Prefab.js' => 'c5af80a2',
@ -507,7 +505,7 @@ return array(
'rsrc/js/core/behavior-more.js' => 'a80d0378',
'rsrc/js/core/behavior-object-selector.js' => 'e0ec7f2f',
'rsrc/js/core/behavior-oncopy.js' => '2926fff2',
'rsrc/js/core/behavior-phabricator-nav.js' => '08675c6d',
'rsrc/js/core/behavior-phabricator-nav.js' => '947753e0',
'rsrc/js/core/behavior-phabricator-remarkup-assist.js' => 'acd29eee',
'rsrc/js/core/behavior-read-only-warning.js' => 'ba158207',
'rsrc/js/core/behavior-refresh-csrf.js' => 'ab2f381b',
@ -556,7 +554,6 @@ return array(
'application-search-view-css' => '66ee5d46',
'auth-css' => '0877ed6e',
'bulk-job-css' => 'df9c1d4a',
'changeset-view-manager' => 'a2828756',
'conduit-api-css' => '7bc725c4',
'config-options-css' => '0ede4c9b',
'config-page-css' => 'c1d5121b',
@ -570,9 +567,8 @@ return array(
'conpherence-thread-manager' => '4d863052',
'conpherence-transaction-css' => '85129c68',
'd3' => 'a11a5ff2',
'differential-changeset-view-css' => '41af6d25',
'differential-changeset-view-css' => '54774a28',
'differential-core-view-css' => '5b7b8ff4',
'differential-inline-comment-editor' => '2e3f9738',
'differential-revision-add-comment-css' => 'c47f8c40',
'differential-revision-comment-css' => '14b8565a',
'differential-revision-history-css' => '0e8eb855',
@ -622,14 +618,9 @@ return array(
'javelin-behavior-detect-timezone' => '4c193c96',
'javelin-behavior-device' => 'bb1dd507',
'javelin-behavior-diff-preview-link' => '051c7832',
'javelin-behavior-differential-comment-jump' => '4fdb476d',
'javelin-behavior-differential-diff-radios' => 'e1ff79b1',
'javelin-behavior-differential-dropdown-menus' => '9a6b9324',
'javelin-behavior-differential-edit-inline-comments' => '4fbbc3e9',
'javelin-behavior-differential-feedback-preview' => 'b064af76',
'javelin-behavior-differential-keyboard-navigation' => '92904457',
'javelin-behavior-differential-populate' => '8694b1df',
'javelin-behavior-differential-toggle-files' => 'ca3f91eb',
'javelin-behavior-differential-feedback-preview' => '51c5ad07',
'javelin-behavior-differential-populate' => '5e41c819',
'javelin-behavior-differential-user-select' => 'a8d8459d',
'javelin-behavior-diffusion-browse-file' => '054a0f0b',
'javelin-behavior-diffusion-commit-branches' => 'bdaf4d04',
@ -669,14 +660,14 @@ return array(
'javelin-behavior-phabricator-keyboard-pager' => 'a8da01f0',
'javelin-behavior-phabricator-keyboard-shortcuts' => '01fca1f0',
'javelin-behavior-phabricator-line-linker' => '1499a8cb',
'javelin-behavior-phabricator-nav' => '08675c6d',
'javelin-behavior-phabricator-nav' => '947753e0',
'javelin-behavior-phabricator-notification-example' => '8ce821c5',
'javelin-behavior-phabricator-object-selector' => 'e0ec7f2f',
'javelin-behavior-phabricator-oncopy' => '2926fff2',
'javelin-behavior-phabricator-remarkup-assist' => 'acd29eee',
'javelin-behavior-phabricator-reveal-content' => '60821bc7',
'javelin-behavior-phabricator-search-typeahead' => 'eded9ee8',
'javelin-behavior-phabricator-show-older-transactions' => '94c65b72',
'javelin-behavior-phabricator-show-older-transactions' => 'ae95d984',
'javelin-behavior-phabricator-tooltips' => 'c420b0b9',
'javelin-behavior-phabricator-transaction-comment-form' => 'b23b49e6',
'javelin-behavior-phabricator-transaction-list' => '1f6794f6',
@ -722,7 +713,7 @@ return array(
'javelin-color' => '7e41274a',
'javelin-cookie' => '62dfea03',
'javelin-diffusion-locate-file-source' => 'c93358e3',
'javelin-dom' => '805b806a',
'javelin-dom' => '4976858c',
'javelin-dynval' => 'f6555212',
'javelin-event' => '2ee659ce',
'javelin-fx' => '54b612ba',
@ -786,6 +777,9 @@ return array(
'phabricator-darklog' => 'c8e1ffe3',
'phabricator-darkmessage' => 'c48cccdd',
'phabricator-dashboard-css' => 'fe5b1869',
'phabricator-diff-changeset' => 'cf4e2140',
'phabricator-diff-changeset-list' => '5c68c40c',
'phabricator-diff-inline' => '77e14b60',
'phabricator-drag-and-drop-file-upload' => '58dea2fa',
'phabricator-draggable-list' => 'bea6e7f4',
'phabricator-fatal-config-template-css' => '8f18fa41',
@ -795,7 +789,7 @@ return array(
'phabricator-filetree-view-css' => 'fccf9f82',
'phabricator-flag-css' => 'bba8f811',
'phabricator-keyboard-shortcut' => '1ae869f2',
'phabricator-keyboard-shortcut-manager' => '4a021c10',
'phabricator-keyboard-shortcut-manager' => 'c19dd9b9',
'phabricator-main-menu-view' => '5294060f',
'phabricator-nav-view-css' => 'faf6a6fc',
'phabricator-notification' => 'ccf1cbf8',
@ -805,6 +799,8 @@ return array(
'phabricator-phtize' => 'd254d646',
'phabricator-prefab' => 'c5af80a2',
'phabricator-remarkup-css' => 'd1a5e11e',
'phabricator-scroll-objective' => '0eee7a00',
'phabricator-scroll-objective-list' => '1ca4d9db',
'phabricator-search-results-css' => 'f87d23ad',
'phabricator-shaped-request' => '7cbe244b',
'phabricator-slowvote-css' => 'a94b7230',
@ -824,7 +820,7 @@ return array(
'phabricator-uiexample-reactor-select' => 'a155550f',
'phabricator-uiexample-reactor-sendclass' => '1def2711',
'phabricator-uiexample-reactor-sendproperties' => 'b1f0ccee',
'phabricator-zindex-css' => '0233d039',
'phabricator-zindex-css' => '998f3ce1',
'phame-css' => 'b3a0b3a3',
'pholio-css' => 'ca89d380',
'pholio-edit-css' => '07676f51',
@ -850,7 +846,7 @@ return array(
'phui-comment-form-css' => '57af2e14',
'phui-comment-panel-css' => 'f50152ad',
'phui-crumbs-view-css' => '6ece3bbb',
'phui-curtain-view-css' => '679743bb',
'phui-curtain-view-css' => '55dd0e59',
'phui-document-summary-view-css' => '9ca48bdf',
'phui-document-view-css' => 'c32e8dec',
'phui-document-view-pro-css' => '62c4dcbf',
@ -867,17 +863,17 @@ return array(
'phui-icon-view-css' => '12b387a1',
'phui-image-mask-css' => 'a8498f9c',
'phui-info-panel-css' => '27ea50a1',
'phui-info-view-css' => 'ec92802a',
'phui-inline-comment-view-css' => 'be663c95',
'phui-info-view-css' => '6e217679',
'phui-inline-comment-view-css' => 'ffd1a542',
'phui-invisible-character-view-css' => '6993d9f0',
'phui-lightbox-css' => '0a035e40',
'phui-list-view-css' => '12eb8ce6',
'phui-object-box-css' => '9cff003c',
'phui-oi-big-ui-css' => '19f9369b',
'phui-oi-color-css' => 'cd2b9b77',
'phui-oi-drag-ui-css' => 'f12cbc9f',
'phui-oi-drag-ui-css' => '08f4ccc3',
'phui-oi-flush-ui-css' => '9d9685d6',
'phui-oi-list-view-css' => '7c8ec27a',
'phui-oi-list-view-css' => '412bef1a',
'phui-oi-simple-ui-css' => 'a8beebea',
'phui-pager-css' => '77d8a794',
'phui-pinboard-view-css' => '2495140e',
@ -888,7 +884,7 @@ return array(
'phui-status-list-view-css' => 'd5263e49',
'phui-tag-view-css' => 'cc4fd402',
'phui-theme-css' => '9f261c6b',
'phui-timeline-view-css' => '1d7ef61d',
'phui-timeline-view-css' => '313c7f22',
'phui-two-column-view-css' => 'ce9fa0b7',
'phui-workboard-color-css' => '783cdff5',
'phui-workboard-view-css' => '3bc85455',
@ -960,22 +956,15 @@ return array(
'javelin-stratcom',
'javelin-util',
),
'08675c6d' => array(
'javelin-behavior',
'javelin-behavior-device',
'javelin-stratcom',
'javelin-dom',
'javelin-magical-init',
'javelin-vector',
'javelin-request',
'javelin-util',
),
'087e919c' => array(
'javelin-install',
'javelin-dom',
'javelin-stratcom',
'javelin-vector',
),
'08f4ccc3' => array(
'phui-oi-list-view-css',
),
'0a0b10e9' => array(
'javelin-behavior',
'javelin-stratcom',
@ -988,6 +977,13 @@ return array(
'javelin-dom',
'javelin-router',
),
'0eee7a00' => array(
'javelin-dom',
'javelin-util',
'javelin-stratcom',
'javelin-install',
'javelin-workflow',
),
'0f764c35' => array(
'javelin-install',
'javelin-util',
@ -1038,6 +1034,14 @@ return array(
'javelin-request',
'javelin-uri',
),
'1ca4d9db' => array(
'javelin-dom',
'javelin-util',
'javelin-stratcom',
'javelin-install',
'javelin-workflow',
'phabricator-scroll-objective',
),
'1def2711' => array(
'javelin-install',
'javelin-dom',
@ -1113,14 +1117,6 @@ return array(
'javelin-install',
'javelin-event',
),
'2e3f9738' => array(
'javelin-dom',
'javelin-util',
'javelin-stratcom',
'javelin-install',
'javelin-request',
'javelin-workflow',
),
'2ee659ce' => array(
'javelin-install',
),
@ -1191,9 +1187,6 @@ return array(
'javelin-dom',
'javelin-reactor-dom',
),
'41af6d25' => array(
'phui-inline-comment-view-css',
),
42126667 => array(
'javelin-behavior',
'javelin-dom',
@ -1252,18 +1245,18 @@ return array(
'javelin-uri',
'phabricator-notification',
),
'4976858c' => array(
'javelin-magical-init',
'javelin-install',
'javelin-util',
'javelin-vector',
'javelin-stratcom',
),
'49ae8328' => array(
'javelin-behavior',
'javelin-dom',
'javelin-stratcom',
),
'4a021c10' => array(
'javelin-install',
'javelin-util',
'javelin-stratcom',
'javelin-dom',
'javelin-vector',
),
'4b3c4443' => array(
'phuix-icon-view',
),
@ -1294,19 +1287,6 @@ return array(
'javelin-stratcom',
'javelin-dom',
),
'4fbbc3e9' => array(
'javelin-behavior',
'javelin-stratcom',
'javelin-dom',
'javelin-util',
'javelin-vector',
'differential-inline-comment-editor',
),
'4fdb476d' => array(
'javelin-behavior',
'javelin-stratcom',
'javelin-dom',
),
'503e17fd' => array(
'javelin-install',
'javelin-typeahead-source',
@ -1317,6 +1297,14 @@ return array(
'javelin-dom',
'javelin-reactor-dom',
),
'51c5ad07' => array(
'javelin-behavior',
'javelin-stratcom',
'javelin-dom',
'javelin-request',
'javelin-util',
'phabricator-shaped-request',
),
'522431f7' => array(
'javelin-behavior',
'javelin-util',
@ -1328,6 +1316,9 @@ return array(
'5294060f' => array(
'phui-theme-css',
),
'54774a28' => array(
'phui-inline-comment-view-css',
),
'54b612ba' => array(
'javelin-color',
'javelin-install',
@ -1377,12 +1368,24 @@ return array(
'javelin-stratcom',
'javelin-dom',
),
'5c68c40c' => array(
'javelin-install',
'phabricator-scroll-objective-list',
),
'5e2634b9' => array(
'javelin-behavior',
'javelin-aphlict',
'phabricator-phtize',
'javelin-dom',
),
'5e41c819' => array(
'javelin-behavior',
'javelin-dom',
'javelin-stratcom',
'phabricator-tooltip',
'phabricator-diff-changeset-list',
'phabricator-diff-changeset',
),
'5e9f347c' => array(
'javelin-behavior',
'multirow-row-manager',
@ -1483,6 +1486,9 @@ return array(
'javelin-reactor',
'javelin-util',
),
'77e14b60' => array(
'javelin-dom',
),
'782ab6e7' => array(
'javelin-behavior',
'javelin-dom',
@ -1526,13 +1532,6 @@ return array(
'javelin-vector',
'javelin-stratcom',
),
'805b806a' => array(
'javelin-magical-init',
'javelin-install',
'javelin-util',
'javelin-vector',
'javelin-stratcom',
),
'834a1173' => array(
'javelin-behavior',
'javelin-scrollbar',
@ -1558,13 +1557,6 @@ return array(
'phabricator-notification',
'conpherence-thread-manager',
),
'8694b1df' => array(
'javelin-behavior',
'javelin-dom',
'javelin-stratcom',
'phabricator-tooltip',
'changeset-view-manager',
),
'88236f00' => array(
'javelin-behavior',
'phabricator-keyboard-shortcut',
@ -1623,12 +1615,6 @@ return array(
'javelin-dom',
'javelin-request',
),
92904457 => array(
'javelin-behavior',
'javelin-dom',
'javelin-stratcom',
'phabricator-keyboard-shortcut',
),
'92b9ec77' => array(
'javelin-behavior',
'javelin-stratcom',
@ -1640,6 +1626,16 @@ return array(
'javelin-workflow',
'javelin-dom',
),
'947753e0' => array(
'javelin-behavior',
'javelin-behavior-device',
'javelin-stratcom',
'javelin-dom',
'javelin-magical-init',
'javelin-vector',
'javelin-request',
'javelin-util',
),
'949c0fe5' => array(
'javelin-install',
),
@ -1653,12 +1649,6 @@ return array(
'javelin-resource',
'javelin-routable',
),
'94c65b72' => array(
'javelin-behavior',
'javelin-stratcom',
'javelin-dom',
'phabricator-busy',
),
'960f6a39' => array(
'javelin-behavior',
'javelin-dom',
@ -1671,18 +1661,6 @@ return array(
'javelin-dom',
'javelin-reactor-dom',
),
'9a6b9324' => array(
'javelin-behavior',
'javelin-dom',
'javelin-util',
'javelin-stratcom',
'javelin-workflow',
'phuix-dropdown-menu',
'phuix-action-list-view',
'phuix-action-view',
'phabricator-phtize',
'changeset-view-manager',
),
'9a6dd75c' => array(
'javelin-behavior',
'javelin-stratcom',
@ -1725,16 +1703,6 @@ return array(
'javelin-dom',
'javelin-reactor-dom',
),
'a2828756' => array(
'javelin-dom',
'javelin-util',
'javelin-stratcom',
'javelin-install',
'javelin-workflow',
'javelin-router',
'javelin-behavior-device',
'javelin-vector',
),
'a3a63478' => array(
'phui-workcard-view-css',
),
@ -1822,20 +1790,18 @@ return array(
'phuix-autocomplete',
'javelin-mask',
),
'ae95d984' => array(
'javelin-behavior',
'javelin-stratcom',
'javelin-dom',
'phabricator-busy',
),
'b003d4fb' => array(
'javelin-behavior',
'javelin-stratcom',
'javelin-dom',
'phuix-dropdown-menu',
),
'b064af76' => array(
'javelin-behavior',
'javelin-stratcom',
'javelin-dom',
'javelin-request',
'javelin-util',
'phabricator-shaped-request',
),
'b1f0ccee' => array(
'javelin-install',
'javelin-dom',
@ -1948,6 +1914,13 @@ return array(
'javelin-install',
'javelin-dom',
),
'c19dd9b9' => array(
'javelin-install',
'javelin-util',
'javelin-stratcom',
'javelin-dom',
'javelin-vector',
),
'c420b0b9' => array(
'javelin-behavior',
'javelin-behavior-device',
@ -2005,12 +1978,6 @@ return array(
'phabricator-shaped-request',
'conpherence-thread-manager',
),
'ca3f91eb' => array(
'javelin-behavior',
'javelin-dom',
'javelin-stratcom',
'phabricator-phtize',
),
'caade6f2' => array(
'javelin-behavior',
'javelin-request',
@ -2035,6 +2002,17 @@ return array(
'cd2b9b77' => array(
'phui-oi-list-view-css',
),
'cf4e2140' => array(
'javelin-dom',
'javelin-util',
'javelin-stratcom',
'javelin-install',
'javelin-workflow',
'javelin-router',
'javelin-behavior-device',
'javelin-vector',
'phabricator-diff-inline',
),
'd0c516d5' => array(
'javelin-behavior',
'javelin-dom',
@ -2202,9 +2180,6 @@ return array(
'javelin-workflow',
'javelin-json',
),
'f12cbc9f' => array(
'phui-oi-list-view-css',
),
'f50152ad' => array(
'phui-timeline-view-css',
),
@ -2449,21 +2424,19 @@ return array(
'phabricator-drag-and-drop-file-upload',
'phabricator-shaped-request',
'javelin-behavior-differential-feedback-preview',
'javelin-behavior-differential-edit-inline-comments',
'javelin-behavior-differential-populate',
'javelin-behavior-differential-diff-radios',
'javelin-behavior-differential-comment-jump',
'javelin-behavior-differential-keyboard-navigation',
'javelin-behavior-aphront-drag-and-drop-textarea',
'javelin-behavior-phabricator-object-selector',
'javelin-behavior-repository-crossreference',
'javelin-behavior-load-blame',
'differential-inline-comment-editor',
'javelin-behavior-differential-dropdown-menus',
'javelin-behavior-differential-toggle-files',
'javelin-behavior-differential-user-select',
'javelin-behavior-aphront-more',
'changeset-view-manager',
'phabricator-scroll-objective',
'phabricator-scroll-objective-list',
'phabricator-diff-inline',
'phabricator-diff-changeset',
'phabricator-diff-changeset-list',
),
'diffusion.pkg.css' => array(
'diffusion-icons-css',

View file

@ -193,22 +193,22 @@ return array(
'phabricator-shaped-request',
'javelin-behavior-differential-feedback-preview',
'javelin-behavior-differential-edit-inline-comments',
'javelin-behavior-differential-populate',
'javelin-behavior-differential-diff-radios',
'javelin-behavior-differential-comment-jump',
'javelin-behavior-differential-keyboard-navigation',
'javelin-behavior-aphront-drag-and-drop-textarea',
'javelin-behavior-phabricator-object-selector',
'javelin-behavior-repository-crossreference',
'javelin-behavior-load-blame',
'differential-inline-comment-editor',
'javelin-behavior-differential-dropdown-menus',
'javelin-behavior-differential-toggle-files',
'javelin-behavior-differential-user-select',
'javelin-behavior-aphront-more',
'changeset-view-manager',
'phabricator-scroll-objective',
'phabricator-scroll-objective-list',
'phabricator-diff-inline',
'phabricator-diff-changeset',
'phabricator-diff-changeset-list',
),
'diffusion.pkg.css' => array(
'diffusion-icons-css',

View file

@ -35,7 +35,8 @@ foreach (new LiskMigrationIterator(new ManiphestTransaction()) as $xaction) {
$id = $xaction->getID();
echo pht('Migrating %d...', $id)."\n";
if ($xaction->getTransactionType() == ManiphestTransaction::TYPE_STATUS) {
$xn_type = ManiphestTaskStatusTransaction::TRANSACTIONTYPE;
if ($xaction->getTransactionType() == $xn_type) {
$old = $xaction->getOldValue();
if ($old !== null && isset($status_map[$old])) {
$old = $status_map[$old];

View file

@ -32,9 +32,9 @@ foreach ($rows as $row) {
$project_phid = $project_row['phid'];
$type_map = array(
'name' => PhabricatorProjectTransaction::TYPE_NAME,
'name' => PhabricatorProjectNameTransaction::TRANSACTIONTYPE,
'members' => PhabricatorProjectTransaction::TYPE_MEMBERS,
'status' => PhabricatorProjectTransaction::TYPE_STATUS,
'status' => PhabricatorProjectStatusTransaction::TRANSACTIONTYPE,
'canview' => PhabricatorTransactions::TYPE_VIEW_POLICY,
'canedit' => PhabricatorTransactions::TYPE_EDIT_POLICY,
'canjoin' => PhabricatorTransactions::TYPE_JOIN_POLICY,

View file

@ -1511,14 +1511,18 @@ phutil_register_library_map(array(
'ManiphestTaskAssignOtherHeraldAction' => 'applications/maniphest/herald/ManiphestTaskAssignOtherHeraldAction.php',
'ManiphestTaskAssignSelfHeraldAction' => 'applications/maniphest/herald/ManiphestTaskAssignSelfHeraldAction.php',
'ManiphestTaskAssigneeHeraldField' => 'applications/maniphest/herald/ManiphestTaskAssigneeHeraldField.php',
'ManiphestTaskAttachTransaction' => 'applications/maniphest/xaction/ManiphestTaskAttachTransaction.php',
'ManiphestTaskAuthorHeraldField' => 'applications/maniphest/herald/ManiphestTaskAuthorHeraldField.php',
'ManiphestTaskAuthorPolicyRule' => 'applications/maniphest/policyrule/ManiphestTaskAuthorPolicyRule.php',
'ManiphestTaskCloseAsDuplicateRelationship' => 'applications/maniphest/relationship/ManiphestTaskCloseAsDuplicateRelationship.php',
'ManiphestTaskClosedStatusDatasource' => 'applications/maniphest/typeahead/ManiphestTaskClosedStatusDatasource.php',
'ManiphestTaskCoverImageTransaction' => 'applications/maniphest/xaction/ManiphestTaskCoverImageTransaction.php',
'ManiphestTaskDependedOnByTaskEdgeType' => 'applications/maniphest/edge/ManiphestTaskDependedOnByTaskEdgeType.php',
'ManiphestTaskDependsOnTaskEdgeType' => 'applications/maniphest/edge/ManiphestTaskDependsOnTaskEdgeType.php',
'ManiphestTaskDescriptionHeraldField' => 'applications/maniphest/herald/ManiphestTaskDescriptionHeraldField.php',
'ManiphestTaskDescriptionTransaction' => 'applications/maniphest/xaction/ManiphestTaskDescriptionTransaction.php',
'ManiphestTaskDetailController' => 'applications/maniphest/controller/ManiphestTaskDetailController.php',
'ManiphestTaskEdgeTransaction' => 'applications/maniphest/xaction/ManiphestTaskEdgeTransaction.php',
'ManiphestTaskEditBulkJobType' => 'applications/maniphest/bulk/ManiphestTaskEditBulkJobType.php',
'ManiphestTaskEditController' => 'applications/maniphest/controller/ManiphestTaskEditController.php',
'ManiphestTaskEditEngineLock' => 'applications/maniphest/editor/ManiphestTaskEditEngineLock.php',
@ -1541,14 +1545,20 @@ phutil_register_library_map(array(
'ManiphestTaskListView' => 'applications/maniphest/view/ManiphestTaskListView.php',
'ManiphestTaskMailReceiver' => 'applications/maniphest/mail/ManiphestTaskMailReceiver.php',
'ManiphestTaskMergeInRelationship' => 'applications/maniphest/relationship/ManiphestTaskMergeInRelationship.php',
'ManiphestTaskMergedFromTransaction' => 'applications/maniphest/xaction/ManiphestTaskMergedFromTransaction.php',
'ManiphestTaskMergedIntoTransaction' => 'applications/maniphest/xaction/ManiphestTaskMergedIntoTransaction.php',
'ManiphestTaskOpenStatusDatasource' => 'applications/maniphest/typeahead/ManiphestTaskOpenStatusDatasource.php',
'ManiphestTaskOwnerTransaction' => 'applications/maniphest/xaction/ManiphestTaskOwnerTransaction.php',
'ManiphestTaskPHIDResolver' => 'applications/maniphest/httpparametertype/ManiphestTaskPHIDResolver.php',
'ManiphestTaskPHIDType' => 'applications/maniphest/phid/ManiphestTaskPHIDType.php',
'ManiphestTaskParentTransaction' => 'applications/maniphest/xaction/ManiphestTaskParentTransaction.php',
'ManiphestTaskPoints' => 'applications/maniphest/constants/ManiphestTaskPoints.php',
'ManiphestTaskPointsTransaction' => 'applications/maniphest/xaction/ManiphestTaskPointsTransaction.php',
'ManiphestTaskPriority' => 'applications/maniphest/constants/ManiphestTaskPriority.php',
'ManiphestTaskPriorityDatasource' => 'applications/maniphest/typeahead/ManiphestTaskPriorityDatasource.php',
'ManiphestTaskPriorityHeraldAction' => 'applications/maniphest/herald/ManiphestTaskPriorityHeraldAction.php',
'ManiphestTaskPriorityHeraldField' => 'applications/maniphest/herald/ManiphestTaskPriorityHeraldField.php',
'ManiphestTaskPriorityTransaction' => 'applications/maniphest/xaction/ManiphestTaskPriorityTransaction.php',
'ManiphestTaskQuery' => 'applications/maniphest/query/ManiphestTaskQuery.php',
'ManiphestTaskRelationship' => 'applications/maniphest/relationship/ManiphestTaskRelationship.php',
'ManiphestTaskRelationshipSource' => 'applications/search/relationship/ManiphestTaskRelationshipSource.php',
@ -1560,9 +1570,14 @@ phutil_register_library_map(array(
'ManiphestTaskStatusHeraldAction' => 'applications/maniphest/herald/ManiphestTaskStatusHeraldAction.php',
'ManiphestTaskStatusHeraldField' => 'applications/maniphest/herald/ManiphestTaskStatusHeraldField.php',
'ManiphestTaskStatusTestCase' => 'applications/maniphest/constants/__tests__/ManiphestTaskStatusTestCase.php',
'ManiphestTaskStatusTransaction' => 'applications/maniphest/xaction/ManiphestTaskStatusTransaction.php',
'ManiphestTaskSubpriorityTransaction' => 'applications/maniphest/xaction/ManiphestTaskSubpriorityTransaction.php',
'ManiphestTaskSubtypeDatasource' => 'applications/maniphest/typeahead/ManiphestTaskSubtypeDatasource.php',
'ManiphestTaskTestCase' => 'applications/maniphest/__tests__/ManiphestTaskTestCase.php',
'ManiphestTaskTitleHeraldField' => 'applications/maniphest/herald/ManiphestTaskTitleHeraldField.php',
'ManiphestTaskTitleTransaction' => 'applications/maniphest/xaction/ManiphestTaskTitleTransaction.php',
'ManiphestTaskTransactionType' => 'applications/maniphest/xaction/ManiphestTaskTransactionType.php',
'ManiphestTaskUnblockTransaction' => 'applications/maniphest/xaction/ManiphestTaskUnblockTransaction.php',
'ManiphestTransaction' => 'applications/maniphest/storage/ManiphestTransaction.php',
'ManiphestTransactionComment' => 'applications/maniphest/storage/ManiphestTransactionComment.php',
'ManiphestTransactionEditor' => 'applications/maniphest/editor/ManiphestTransactionEditor.php',
@ -3569,6 +3584,7 @@ phutil_register_library_map(array(
'PhabricatorProjectBoardReorderController' => 'applications/project/controller/PhabricatorProjectBoardReorderController.php',
'PhabricatorProjectBoardViewController' => 'applications/project/controller/PhabricatorProjectBoardViewController.php',
'PhabricatorProjectCardView' => 'applications/project/view/PhabricatorProjectCardView.php',
'PhabricatorProjectColorTransaction' => 'applications/project/xaction/PhabricatorProjectColorTransaction.php',
'PhabricatorProjectColorsConfigOptionType' => 'applications/project/config/PhabricatorProjectColorsConfigOptionType.php',
'PhabricatorProjectColumn' => 'applications/project/storage/PhabricatorProjectColumn.php',
'PhabricatorProjectColumnDetailController' => 'applications/project/controller/PhabricatorProjectColumnDetailController.php',
@ -3605,7 +3621,9 @@ phutil_register_library_map(array(
'PhabricatorProjectHeraldFieldGroup' => 'applications/project/herald/PhabricatorProjectHeraldFieldGroup.php',
'PhabricatorProjectHovercardEngineExtension' => 'applications/project/engineextension/PhabricatorProjectHovercardEngineExtension.php',
'PhabricatorProjectIconSet' => 'applications/project/icon/PhabricatorProjectIconSet.php',
'PhabricatorProjectIconTransaction' => 'applications/project/xaction/PhabricatorProjectIconTransaction.php',
'PhabricatorProjectIconsConfigOptionType' => 'applications/project/config/PhabricatorProjectIconsConfigOptionType.php',
'PhabricatorProjectImageTransaction' => 'applications/project/xaction/PhabricatorProjectImageTransaction.php',
'PhabricatorProjectInterface' => 'applications/project/interface/PhabricatorProjectInterface.php',
'PhabricatorProjectListController' => 'applications/project/controller/PhabricatorProjectListController.php',
'PhabricatorProjectListView' => 'applications/project/view/PhabricatorProjectListView.php',
@ -3629,6 +3647,7 @@ phutil_register_library_map(array(
'PhabricatorProjectMenuItemController' => 'applications/project/controller/PhabricatorProjectMenuItemController.php',
'PhabricatorProjectMoveController' => 'applications/project/controller/PhabricatorProjectMoveController.php',
'PhabricatorProjectNameContextFreeGrammar' => 'applications/project/lipsum/PhabricatorProjectNameContextFreeGrammar.php',
'PhabricatorProjectNameTransaction' => 'applications/project/xaction/PhabricatorProjectNameTransaction.php',
'PhabricatorProjectNoProjectsDatasource' => 'applications/project/typeahead/PhabricatorProjectNoProjectsDatasource.php',
'PhabricatorProjectObjectHasProjectEdgeType' => 'applications/project/edge/PhabricatorProjectObjectHasProjectEdgeType.php',
'PhabricatorProjectOrUserDatasource' => 'applications/project/typeahead/PhabricatorProjectOrUserDatasource.php',
@ -3650,8 +3669,10 @@ phutil_register_library_map(array(
'PhabricatorProjectSilenceController' => 'applications/project/controller/PhabricatorProjectSilenceController.php',
'PhabricatorProjectSilencedEdgeType' => 'applications/project/edge/PhabricatorProjectSilencedEdgeType.php',
'PhabricatorProjectSlug' => 'applications/project/storage/PhabricatorProjectSlug.php',
'PhabricatorProjectSlugsTransaction' => 'applications/project/xaction/PhabricatorProjectSlugsTransaction.php',
'PhabricatorProjectStandardCustomField' => 'applications/project/customfield/PhabricatorProjectStandardCustomField.php',
'PhabricatorProjectStatus' => 'applications/project/constants/PhabricatorProjectStatus.php',
'PhabricatorProjectStatusTransaction' => 'applications/project/xaction/PhabricatorProjectStatusTransaction.php',
'PhabricatorProjectSubprojectWarningController' => 'applications/project/controller/PhabricatorProjectSubprojectWarningController.php',
'PhabricatorProjectSubprojectsController' => 'applications/project/controller/PhabricatorProjectSubprojectsController.php',
'PhabricatorProjectSubprojectsProfileMenuItem' => 'applications/project/menuitem/PhabricatorProjectSubprojectsProfileMenuItem.php',
@ -3659,6 +3680,7 @@ phutil_register_library_map(array(
'PhabricatorProjectTransaction' => 'applications/project/storage/PhabricatorProjectTransaction.php',
'PhabricatorProjectTransactionEditor' => 'applications/project/editor/PhabricatorProjectTransactionEditor.php',
'PhabricatorProjectTransactionQuery' => 'applications/project/query/PhabricatorProjectTransactionQuery.php',
'PhabricatorProjectTransactionType' => 'applications/project/xaction/PhabricatorProjectTransactionType.php',
'PhabricatorProjectUIEventListener' => 'applications/project/events/PhabricatorProjectUIEventListener.php',
'PhabricatorProjectUpdateController' => 'applications/project/controller/PhabricatorProjectUpdateController.php',
'PhabricatorProjectUserFunctionDatasource' => 'applications/project/typeahead/PhabricatorProjectUserFunctionDatasource.php',
@ -4361,9 +4383,12 @@ phutil_register_library_map(array(
'PholioDefaultViewCapability' => 'applications/pholio/capability/PholioDefaultViewCapability.php',
'PholioImage' => 'applications/pholio/storage/PholioImage.php',
'PholioImageDescriptionTransaction' => 'applications/pholio/xaction/PholioImageDescriptionTransaction.php',
'PholioImageFileTransaction' => 'applications/pholio/xaction/PholioImageFileTransaction.php',
'PholioImageNameTransaction' => 'applications/pholio/xaction/PholioImageNameTransaction.php',
'PholioImagePHIDType' => 'applications/pholio/phid/PholioImagePHIDType.php',
'PholioImageQuery' => 'applications/pholio/query/PholioImageQuery.php',
'PholioImageReplaceTransaction' => 'applications/pholio/xaction/PholioImageReplaceTransaction.php',
'PholioImageSequenceTransaction' => 'applications/pholio/xaction/PholioImageSequenceTransaction.php',
'PholioImageTransactionType' => 'applications/pholio/xaction/PholioImageTransactionType.php',
'PholioImageUploadController' => 'applications/pholio/controller/PholioImageUploadController.php',
'PholioInlineController' => 'applications/pholio/controller/PholioInlineController.php',
@ -4383,6 +4408,7 @@ phutil_register_library_map(array(
'PholioMockHeraldField' => 'applications/pholio/herald/PholioMockHeraldField.php',
'PholioMockHeraldFieldGroup' => 'applications/pholio/herald/PholioMockHeraldFieldGroup.php',
'PholioMockImagesView' => 'applications/pholio/view/PholioMockImagesView.php',
'PholioMockInlineTransaction' => 'applications/pholio/xaction/PholioMockInlineTransaction.php',
'PholioMockListController' => 'applications/pholio/controller/PholioMockListController.php',
'PholioMockMailReceiver' => 'applications/pholio/mail/PholioMockMailReceiver.php',
'PholioMockNameHeraldField' => 'applications/pholio/herald/PholioMockNameHeraldField.php',
@ -4598,11 +4624,14 @@ phutil_register_library_map(array(
'PhrictionDocumentHeraldAdapter' => 'applications/phriction/herald/PhrictionDocumentHeraldAdapter.php',
'PhrictionDocumentHeraldField' => 'applications/phriction/herald/PhrictionDocumentHeraldField.php',
'PhrictionDocumentHeraldFieldGroup' => 'applications/phriction/herald/PhrictionDocumentHeraldFieldGroup.php',
'PhrictionDocumentMoveToTransaction' => 'applications/phriction/xaction/PhrictionDocumentMoveToTransaction.php',
'PhrictionDocumentPHIDType' => 'applications/phriction/phid/PhrictionDocumentPHIDType.php',
'PhrictionDocumentPathHeraldField' => 'applications/phriction/herald/PhrictionDocumentPathHeraldField.php',
'PhrictionDocumentQuery' => 'applications/phriction/query/PhrictionDocumentQuery.php',
'PhrictionDocumentStatus' => 'applications/phriction/constants/PhrictionDocumentStatus.php',
'PhrictionDocumentTitleHeraldField' => 'applications/phriction/herald/PhrictionDocumentTitleHeraldField.php',
'PhrictionDocumentTitleTransaction' => 'applications/phriction/xaction/PhrictionDocumentTitleTransaction.php',
'PhrictionDocumentTransactionType' => 'applications/phriction/xaction/PhrictionDocumentTransactionType.php',
'PhrictionEditConduitAPIMethod' => 'applications/phriction/conduit/PhrictionEditConduitAPIMethod.php',
'PhrictionEditController' => 'applications/phriction/controller/PhrictionEditController.php',
'PhrictionHistoryConduitAPIMethod' => 'applications/phriction/conduit/PhrictionHistoryConduitAPIMethod.php',
@ -6569,14 +6598,18 @@ phutil_register_library_map(array(
'ManiphestTaskAssignOtherHeraldAction' => 'ManiphestTaskAssignHeraldAction',
'ManiphestTaskAssignSelfHeraldAction' => 'ManiphestTaskAssignHeraldAction',
'ManiphestTaskAssigneeHeraldField' => 'ManiphestTaskHeraldField',
'ManiphestTaskAttachTransaction' => 'ManiphestTaskTransactionType',
'ManiphestTaskAuthorHeraldField' => 'ManiphestTaskHeraldField',
'ManiphestTaskAuthorPolicyRule' => 'PhabricatorPolicyRule',
'ManiphestTaskCloseAsDuplicateRelationship' => 'ManiphestTaskRelationship',
'ManiphestTaskClosedStatusDatasource' => 'PhabricatorTypeaheadDatasource',
'ManiphestTaskCoverImageTransaction' => 'ManiphestTaskTransactionType',
'ManiphestTaskDependedOnByTaskEdgeType' => 'PhabricatorEdgeType',
'ManiphestTaskDependsOnTaskEdgeType' => 'PhabricatorEdgeType',
'ManiphestTaskDescriptionHeraldField' => 'ManiphestTaskHeraldField',
'ManiphestTaskDescriptionTransaction' => 'ManiphestTaskTransactionType',
'ManiphestTaskDetailController' => 'ManiphestController',
'ManiphestTaskEdgeTransaction' => 'ManiphestTaskTransactionType',
'ManiphestTaskEditBulkJobType' => 'PhabricatorWorkerBulkJobType',
'ManiphestTaskEditController' => 'ManiphestController',
'ManiphestTaskEditEngineLock' => 'PhabricatorEditEngineLock',
@ -6599,14 +6632,20 @@ phutil_register_library_map(array(
'ManiphestTaskListView' => 'ManiphestView',
'ManiphestTaskMailReceiver' => 'PhabricatorObjectMailReceiver',
'ManiphestTaskMergeInRelationship' => 'ManiphestTaskRelationship',
'ManiphestTaskMergedFromTransaction' => 'ManiphestTaskTransactionType',
'ManiphestTaskMergedIntoTransaction' => 'ManiphestTaskTransactionType',
'ManiphestTaskOpenStatusDatasource' => 'PhabricatorTypeaheadDatasource',
'ManiphestTaskOwnerTransaction' => 'ManiphestTaskTransactionType',
'ManiphestTaskPHIDResolver' => 'PhabricatorPHIDResolver',
'ManiphestTaskPHIDType' => 'PhabricatorPHIDType',
'ManiphestTaskParentTransaction' => 'ManiphestTaskTransactionType',
'ManiphestTaskPoints' => 'Phobject',
'ManiphestTaskPointsTransaction' => 'ManiphestTaskTransactionType',
'ManiphestTaskPriority' => 'ManiphestConstants',
'ManiphestTaskPriorityDatasource' => 'PhabricatorTypeaheadDatasource',
'ManiphestTaskPriorityHeraldAction' => 'HeraldAction',
'ManiphestTaskPriorityHeraldField' => 'ManiphestTaskHeraldField',
'ManiphestTaskPriorityTransaction' => 'ManiphestTaskTransactionType',
'ManiphestTaskQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'ManiphestTaskRelationship' => 'PhabricatorObjectRelationship',
'ManiphestTaskRelationshipSource' => 'PhabricatorObjectRelationshipSource',
@ -6618,10 +6657,15 @@ phutil_register_library_map(array(
'ManiphestTaskStatusHeraldAction' => 'HeraldAction',
'ManiphestTaskStatusHeraldField' => 'ManiphestTaskHeraldField',
'ManiphestTaskStatusTestCase' => 'PhabricatorTestCase',
'ManiphestTaskStatusTransaction' => 'ManiphestTaskTransactionType',
'ManiphestTaskSubpriorityTransaction' => 'ManiphestTaskTransactionType',
'ManiphestTaskSubtypeDatasource' => 'PhabricatorTypeaheadDatasource',
'ManiphestTaskTestCase' => 'PhabricatorTestCase',
'ManiphestTaskTitleHeraldField' => 'ManiphestTaskHeraldField',
'ManiphestTransaction' => 'PhabricatorApplicationTransaction',
'ManiphestTaskTitleTransaction' => 'ManiphestTaskTransactionType',
'ManiphestTaskTransactionType' => 'PhabricatorModularTransactionType',
'ManiphestTaskUnblockTransaction' => 'ManiphestTaskTransactionType',
'ManiphestTransaction' => 'PhabricatorModularTransaction',
'ManiphestTransactionComment' => 'PhabricatorApplicationTransactionComment',
'ManiphestTransactionEditor' => 'PhabricatorApplicationTransactionEditor',
'ManiphestTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
@ -8944,6 +8988,7 @@ phutil_register_library_map(array(
'PhabricatorProjectBoardReorderController' => 'PhabricatorProjectBoardController',
'PhabricatorProjectBoardViewController' => 'PhabricatorProjectBoardController',
'PhabricatorProjectCardView' => 'AphrontTagView',
'PhabricatorProjectColorTransaction' => 'PhabricatorProjectTransactionType',
'PhabricatorProjectColorsConfigOptionType' => 'PhabricatorConfigJSONOptionType',
'PhabricatorProjectColumn' => array(
'PhabricatorProjectDAO',
@ -8993,7 +9038,9 @@ phutil_register_library_map(array(
'PhabricatorProjectHeraldFieldGroup' => 'HeraldFieldGroup',
'PhabricatorProjectHovercardEngineExtension' => 'PhabricatorHovercardEngineExtension',
'PhabricatorProjectIconSet' => 'PhabricatorIconSet',
'PhabricatorProjectIconTransaction' => 'PhabricatorProjectTransactionType',
'PhabricatorProjectIconsConfigOptionType' => 'PhabricatorConfigJSONOptionType',
'PhabricatorProjectImageTransaction' => 'PhabricatorProjectTransactionType',
'PhabricatorProjectListController' => 'PhabricatorProjectController',
'PhabricatorProjectListView' => 'AphrontView',
'PhabricatorProjectLockController' => 'PhabricatorProjectController',
@ -9016,6 +9063,7 @@ phutil_register_library_map(array(
'PhabricatorProjectMenuItemController' => 'PhabricatorProjectController',
'PhabricatorProjectMoveController' => 'PhabricatorProjectController',
'PhabricatorProjectNameContextFreeGrammar' => 'PhutilContextFreeGrammar',
'PhabricatorProjectNameTransaction' => 'PhabricatorProjectTransactionType',
'PhabricatorProjectNoProjectsDatasource' => 'PhabricatorTypeaheadDatasource',
'PhabricatorProjectObjectHasProjectEdgeType' => 'PhabricatorEdgeType',
'PhabricatorProjectOrUserDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
@ -9037,18 +9085,21 @@ phutil_register_library_map(array(
'PhabricatorProjectSilenceController' => 'PhabricatorProjectController',
'PhabricatorProjectSilencedEdgeType' => 'PhabricatorEdgeType',
'PhabricatorProjectSlug' => 'PhabricatorProjectDAO',
'PhabricatorProjectSlugsTransaction' => 'PhabricatorProjectTransactionType',
'PhabricatorProjectStandardCustomField' => array(
'PhabricatorProjectCustomField',
'PhabricatorStandardCustomFieldInterface',
),
'PhabricatorProjectStatus' => 'Phobject',
'PhabricatorProjectStatusTransaction' => 'PhabricatorProjectTransactionType',
'PhabricatorProjectSubprojectWarningController' => 'PhabricatorProjectController',
'PhabricatorProjectSubprojectsController' => 'PhabricatorProjectController',
'PhabricatorProjectSubprojectsProfileMenuItem' => 'PhabricatorProfileMenuItem',
'PhabricatorProjectTestDataGenerator' => 'PhabricatorTestDataGenerator',
'PhabricatorProjectTransaction' => 'PhabricatorApplicationTransaction',
'PhabricatorProjectTransaction' => 'PhabricatorModularTransaction',
'PhabricatorProjectTransactionEditor' => 'PhabricatorApplicationTransactionEditor',
'PhabricatorProjectTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhabricatorProjectTransactionType' => 'PhabricatorModularTransactionType',
'PhabricatorProjectUIEventListener' => 'PhabricatorEventListener',
'PhabricatorProjectUpdateController' => 'PhabricatorProjectController',
'PhabricatorProjectUserFunctionDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
@ -9908,9 +9959,12 @@ phutil_register_library_map(array(
'PhabricatorPolicyInterface',
),
'PholioImageDescriptionTransaction' => 'PholioImageTransactionType',
'PholioImageFileTransaction' => 'PholioImageTransactionType',
'PholioImageNameTransaction' => 'PholioImageTransactionType',
'PholioImagePHIDType' => 'PhabricatorPHIDType',
'PholioImageQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PholioImageReplaceTransaction' => 'PholioImageTransactionType',
'PholioImageSequenceTransaction' => 'PholioImageTransactionType',
'PholioImageTransactionType' => 'PholioTransactionType',
'PholioImageUploadController' => 'PholioController',
'PholioInlineController' => 'PholioController',
@ -9943,6 +9997,7 @@ phutil_register_library_map(array(
'PholioMockHeraldField' => 'HeraldField',
'PholioMockHeraldFieldGroup' => 'HeraldFieldGroup',
'PholioMockImagesView' => 'AphrontView',
'PholioMockInlineTransaction' => 'PholioMockTransactionType',
'PholioMockListController' => 'PholioController',
'PholioMockMailReceiver' => 'PhabricatorObjectMailReceiver',
'PholioMockNameHeraldField' => 'PholioMockHeraldField',
@ -10216,11 +10271,14 @@ phutil_register_library_map(array(
'PhrictionDocumentHeraldAdapter' => 'HeraldAdapter',
'PhrictionDocumentHeraldField' => 'HeraldField',
'PhrictionDocumentHeraldFieldGroup' => 'HeraldFieldGroup',
'PhrictionDocumentMoveToTransaction' => 'PhrictionDocumentTransactionType',
'PhrictionDocumentPHIDType' => 'PhabricatorPHIDType',
'PhrictionDocumentPathHeraldField' => 'PhrictionDocumentHeraldField',
'PhrictionDocumentQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhrictionDocumentStatus' => 'PhrictionConstants',
'PhrictionDocumentTitleHeraldField' => 'PhrictionDocumentHeraldField',
'PhrictionDocumentTitleTransaction' => 'PhrictionDocumentTransactionType',
'PhrictionDocumentTransactionType' => 'PhabricatorModularTransactionType',
'PhrictionEditConduitAPIMethod' => 'PhrictionConduitAPIMethod',
'PhrictionEditController' => 'PhrictionController',
'PhrictionHistoryConduitAPIMethod' => 'PhrictionConduitAPIMethod',
@ -10234,7 +10292,7 @@ phutil_register_library_map(array(
'PhrictionReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler',
'PhrictionSchemaSpec' => 'PhabricatorConfigSchemaSpec',
'PhrictionSearchEngine' => 'PhabricatorApplicationSearchEngine',
'PhrictionTransaction' => 'PhabricatorApplicationTransaction',
'PhrictionTransaction' => 'PhabricatorModularTransaction',
'PhrictionTransactionComment' => 'PhabricatorApplicationTransactionComment',
'PhrictionTransactionEditor' => 'PhabricatorApplicationTransactionEditor',
'PhrictionTransactionQuery' => 'PhabricatorApplicationTransactionQuery',

View file

@ -471,7 +471,7 @@ abstract class PhabricatorController extends AphrontController {
->setViewer($this->getViewer());
}
public function newCurtainView($object) {
public function newCurtainView($object = null) {
$viewer = $this->getViewer();
$action_id = celerity_generate_unique_node_id();
@ -491,9 +491,11 @@ abstract class PhabricatorController extends AphrontController {
->setViewer($viewer)
->setActionList($action_list);
$panels = PHUICurtainExtension::buildExtensionPanels($viewer, $object);
foreach ($panels as $panel) {
$curtain->addPanel($panel);
if ($object) {
$panels = PHUICurtainExtension::buildExtensionPanels($viewer, $object);
foreach ($panels as $panel) {
$curtain->addPanel($panel);
}
}
return $curtain;

View file

@ -465,7 +465,6 @@ final class DifferentialRevisionViewController extends DifferentialController {
}
Javelin::initBehavior('differential-user-select');
Javelin::initBehavior('differential-keyboard-navigation');
$view = id(new PHUITwoColumnView())
->setHeader($header)

View file

@ -41,8 +41,6 @@ final class DifferentialChangesetOneUpRenderer
$column_width = 4;
$hidden = new PHUIDiffRevealIconView();
$out = array();
foreach ($primitives as $k => $p) {
$type = $p['type'];
@ -53,27 +51,6 @@ final class DifferentialChangesetOneUpRenderer
case 'new-file':
$is_old = ($type == 'old' || $type == 'old-file');
$o_hidden = array();
$n_hidden = array();
for ($look = $k + 1; isset($primitives[$look]); $look++) {
$next = $primitives[$look];
switch ($next['type']) {
case 'inline':
$comment = $next['comment'];
if ($comment->isHidden()) {
if ($next['right']) {
$n_hidden[] = $comment;
} else {
$o_hidden[] = $comment;
}
}
break;
default:
break 2;
}
}
$cells = array();
if ($is_old) {
if ($p['htype']) {
@ -93,9 +70,6 @@ final class DifferentialChangesetOneUpRenderer
}
$line = $p['line'];
if ($o_hidden) {
$line = array($hidden, $line);
}
$cells[] = phutil_tag(
'th',
@ -122,9 +96,6 @@ final class DifferentialChangesetOneUpRenderer
}
$oline = $p['oline'];
if ($o_hidden) {
$oline = array($hidden, $oline);
}
$cells[] = phutil_tag('th', array('id' => $left_id), $oline);
}
@ -140,9 +111,6 @@ final class DifferentialChangesetOneUpRenderer
}
$line = $p['line'];
if ($n_hidden) {
$line = array($hidden, $line);
}
$cells[] = phutil_tag(
'th',

View file

@ -69,8 +69,6 @@ final class DifferentialChangesetTwoUpRenderer
$depths = $this->getDepths();
$mask = $this->getMask();
$hidden = new PHUIDiffRevealIconView();
for ($ii = $range_start; $ii < $range_start + $range_len; $ii++) {
if (empty($mask[$ii])) {
// If we aren't going to show this line, we've just entered a gap.
@ -241,9 +239,6 @@ final class DifferentialChangesetTwoUpRenderer
$new_comments = $this->getNewComments();
$scaffolds = array();
$o_hidden = array();
$n_hidden = array();
if ($o_num && isset($old_comments[$o_num])) {
foreach ($old_comments[$o_num] as $comment) {
$inline = $this->buildInlineComment(
@ -251,10 +246,6 @@ final class DifferentialChangesetTwoUpRenderer
$on_right = false);
$scaffold = $this->getRowScaffoldForInline($inline);
if ($comment->isHidden()) {
$o_hidden[] = $comment;
}
if ($n_num && isset($new_comments[$n_num])) {
foreach ($new_comments[$n_num] as $key => $new_comment) {
if ($comment->isCompatible($new_comment)) {
@ -262,10 +253,6 @@ final class DifferentialChangesetTwoUpRenderer
$new_comment,
$on_right = true);
if ($new_comment->isHidden()) {
$n_hidden = $new_comment;
}
$scaffold->addInlineView($companion);
unset($new_comments[$n_num][$key]);
break;
@ -284,22 +271,10 @@ final class DifferentialChangesetTwoUpRenderer
$comment,
$on_right = true);
if ($comment->isHidden()) {
$n_hidden[] = $comment;
}
$scaffolds[] = $this->getRowScaffoldForInline($inline);
}
}
if ($o_hidden) {
$o_num = array($hidden, $o_num);
}
if ($n_hidden) {
$n_num = array($hidden, $n_num);
}
// NOTE: This is a unicode zero-width space, which we use as a hint when
// intercepting 'copy' events to make sure sensible text ends up on the
// clipboard. See the 'phabricator-oncopy' behavior.
@ -348,6 +323,12 @@ final class DifferentialChangesetTwoUpRenderer
$new = $this->renderImageStage($new_file);
}
// If we don't have an explicit "vs" changeset, it's the left side of the
// "id" changeset.
if (!$vs) {
$vs = $id;
}
$html_old = array();
$html_new = array();
foreach ($this->getOldComments() as $on_line => $comment_group) {

View file

@ -150,15 +150,51 @@ final class DifferentialChangesetDetailView extends AphrontView {
$renderer = DifferentialChangesetHTMLRenderer::getHTMLRendererByKey(
$this->getRenderer());
$changeset_id = $this->changeset->getID();
$vs_id = $this->getVsChangesetID();
if (!$vs_id) {
// Showing a changeset normally.
$left_id = $changeset_id;
$right_id = $changeset_id;
} else if ($vs_id == -1) {
// Showing a synthetic "deleted" changeset for a file which was
// removed between changes.
$left_id = $changeset_id;
$right_id = null;
} else {
// Showing a diff-of-diffs.
$left_id = $vs_id;
$right_id = $changeset_id;
}
// In the persistent banner, emphasize the current filename.
$path_part = dirname($display_filename);
$file_part = basename($display_filename);
$display_parts = array();
if (strlen($path_part)) {
$path_part = $path_part.'/';
$display_parts[] = phutil_tag(
'span',
array(
'class' => 'diff-banner-path',
),
$path_part);
}
$display_parts[] = phutil_tag(
'span',
array(
'class' => 'diff-banner-file',
),
$file_part);
return javelin_tag(
'div',
array(
'sigil' => 'differential-changeset',
'meta' => array(
'left' => nonempty(
$this->getVsChangesetID(),
$this->changeset->getID()),
'right' => $this->changeset->getID(),
'left' => $left_id,
'right' => $right_id,
'renderURI' => $this->getRenderURI(),
'whitespace' => $this->getWhitespace(),
'highlight' => null,
@ -166,7 +202,10 @@ final class DifferentialChangesetDetailView extends AphrontView {
'ref' => $this->getRenderingRef(),
'autoload' => $this->getAutoload(),
'loaded' => $this->getLoaded(),
'undoTemplates' => $renderer->renderUndoTemplates(),
'undoTemplates' => hsprintf('%s', $renderer->renderUndoTemplates()),
'displayPath' => hsprintf('%s', $display_parts),
'objectiveName' => basename($display_filename),
'icon' => $display_icon,
),
'class' => $class,
'id' => $id,

View file

@ -131,36 +131,6 @@ final class DifferentialChangesetListView extends AphrontView {
$changesets = $this->changesets;
Javelin::initBehavior('differential-toggle-files', array(
'pht' => array(
'undo' => pht('Undo'),
'collapsed' => pht('This file content has been collapsed.'),
),
));
Javelin::initBehavior(
'differential-dropdown-menus',
array(
'pht' => array(
'Open in Editor' => pht('Open in Editor'),
'Show All Context' => pht('Show All Context'),
'All Context Shown' => pht('All Context Shown'),
"Can't Toggle Unloaded File" => pht("Can't Toggle Unloaded File"),
'Expand File' => pht('Expand File'),
'Collapse File' => pht('Collapse File'),
'Browse in Diffusion' => pht('Browse in Diffusion'),
'View Standalone' => pht('View Standalone'),
'Show Raw File (Left)' => pht('Show Raw File (Left)'),
'Show Raw File (Right)' => pht('Show Raw File (Right)'),
'Configure Editor' => pht('Configure Editor'),
'Load Changes' => pht('Load Changes'),
'View Side-by-Side' => pht('View Side-by-Side'),
'View Unified' => pht('View Unified'),
'Change Text Encoding...' => pht('Change Text Encoding...'),
'Highlight As...' => pht('Highlight As...'),
),
));
$renderer = DifferentialChangesetParser::getDefaultRendererForViewer(
$viewer);
@ -169,11 +139,6 @@ final class DifferentialChangesetListView extends AphrontView {
foreach ($changesets as $key => $changeset) {
$file = $changeset->getFilename();
$class = 'differential-changeset';
if (!$this->inlineURI) {
$class .= ' differential-changeset-noneditable';
}
$ref = $this->references[$key];
$detail = id(new DifferentialChangesetDetailView())
@ -238,20 +203,79 @@ final class DifferentialChangesetListView extends AphrontView {
$this->requireResource('aphront-tooltip-css');
$this->initBehavior('differential-populate', array(
$this->initBehavior(
'differential-populate',
array(
'changesetViewIDs' => $ids,
'inlineURI' => $this->inlineURI,
'pht' => array(
'Open in Editor' => pht('Open in Editor'),
'Show All Context' => pht('Show All Context'),
'All Context Shown' => pht('All Context Shown'),
"Can't Toggle Unloaded File" => pht("Can't Toggle Unloaded File"),
'Expand File' => pht('Expand File'),
'Collapse File' => pht('Collapse File'),
'Browse in Diffusion' => pht('Browse in Diffusion'),
'View Standalone' => pht('View Standalone'),
'Show Raw File (Left)' => pht('Show Raw File (Left)'),
'Show Raw File (Right)' => pht('Show Raw File (Right)'),
'Configure Editor' => pht('Configure Editor'),
'Load Changes' => pht('Load Changes'),
'View Side-by-Side' => pht('View Side-by-Side'),
'View Unified' => pht('View Unified'),
'Change Text Encoding...' => pht('Change Text Encoding...'),
'Highlight As...' => pht('Highlight As...'),
'Loading...' => pht('Loading...'),
'Jump to next change.' => pht('Jump to next change.'),
'Jump to previous change.' => pht('Jump to previous change.'),
'Jump to next file.' => pht('Jump to next file.'),
'Jump to previous file.' => pht('Jump to previous file.'),
'Jump to next inline comment.' => pht('Jump to next inline comment.'),
'Jump to previous inline comment.' =>
pht('Jump to previous inline comment.'),
'Jump to the table of contents.' =>
pht('Jump to the table of contents.'),
'Edit selected inline comment.' =>
pht('Edit selected inline comment.'),
'You must select a comment to edit.' =>
pht('You must select a comment to edit.'),
'Reply to selected inline comment or change.' =>
pht('Reply to selected inline comment or change.'),
'You must select a comment or change to reply to.' =>
pht('You must select a comment or change to reply to.'),
'Reply and quote selected inline comment.' =>
pht('Reply and quote selected inline comment.'),
'Mark or unmark selected inline comment as done.' =>
pht('Mark or unmark selected inline comment as done.'),
'You must select a comment to mark done.' =>
pht('You must select a comment to mark done.'),
'Hide or show inline comment.' =>
pht('Hide or show inline comment.'),
'You must select a comment to hide.' =>
pht('You must select a comment to hide.'),
'Jump to next inline comment, including hidden comments.' =>
pht('Jump to next inline comment, including hidden comments.'),
'Jump to previous inline comment, including hidden comments.' =>
pht('Jump to previous inline comment, including hidden comments.'),
'This file content has been collapsed.' =>
pht('This file content has been collapsed.'),
'Show Content' => pht('Show Content'),
'Hide or show the current file.' =>
pht('Hide or show the current file.'),
'You must select a file to hide or show.' =>
pht('You must select a file to hide or show.'),
),
));
$this->initBehavior('differential-comment-jump', array());
if ($this->inlineURI) {
Javelin::initBehavior('differential-edit-inline-comments', array(
'uri' => $this->inlineURI,
'stage' => 'differential-review-stage',
'revealIcon' => hsprintf('%s', new PHUIDiffRevealIconView()),
));
}
if ($this->header) {
$header = $this->header;
} else {

View file

@ -720,8 +720,6 @@ final class DiffusionCommitController extends DiffusionController {
$request = $this->getRequest();
$viewer = $request->getUser();
Javelin::initBehavior('differential-keyboard-navigation');
// TODO: This is pretty awkward, unify the CSS between Diffusion and
// Differential better.
require_celerity_resource('differential-core-view-css');

View file

@ -48,7 +48,8 @@ final class PhabricatorFileComposeController
$xactions = array();
$xactions[] = id(new PhabricatorProjectTransaction())
->setTransactionType(PhabricatorProjectTransaction::TYPE_IMAGE)
->setTransactionType(
PhabricatorProjectImageTransaction::TRANSACTIONTYPE)
->setNewValue($file->getPHID());
$editor = id(new PhabricatorProjectTransactionEditor())

View file

@ -94,11 +94,12 @@ final class PhabricatorFileTestCase extends PhabricatorTestCase {
$xactions = array();
$xactions[] = id(new ManiphestTransaction())
->setTransactionType(ManiphestTransaction::TYPE_TITLE)
->setTransactionType(ManiphestTaskTitleTransaction::TRANSACTIONTYPE)
->setNewValue(pht('File Scramble Test Task'));
$xactions[] = id(new ManiphestTransaction())
->setTransactionType(ManiphestTransaction::TYPE_DESCRIPTION)
->setTransactionType(
ManiphestTaskDescriptionTransaction::TRANSACTIONTYPE)
->setNewValue('{'.$file->getMonogram().'}');
id(new ManiphestTransactionEditor())

View file

@ -133,7 +133,7 @@ final class ManiphestTaskTestCase extends PhabricatorTestCase {
$xactions = array();
$xactions[] = id(new ManiphestTransaction())
->setTransactionType(ManiphestTransaction::TYPE_TITLE)
->setTransactionType(ManiphestTaskTitleTransaction::TRANSACTIONTYPE)
->setNewValue($title);
@ -169,11 +169,11 @@ final class ManiphestTaskTestCase extends PhabricatorTestCase {
$xactions = array();
$xactions[] = id(new ManiphestTransaction())
->setTransactionType(ManiphestTransaction::TYPE_PRIORITY)
->setTransactionType(ManiphestTaskPriorityTransaction::TRANSACTIONTYPE)
->setNewValue($pri);
$xactions[] = id(new ManiphestTransaction())
->setTransactionType(ManiphestTransaction::TYPE_SUBPRIORITY)
->setTransactionType(ManiphestTaskSubpriorityTransaction::TRANSACTIONTYPE)
->setNewValue($sub);
return $this->applyTaskTransactions($viewer, $src, $xactions);
@ -192,11 +192,11 @@ final class ManiphestTaskTestCase extends PhabricatorTestCase {
$xactions = array();
$xactions[] = id(new ManiphestTransaction())
->setTransactionType(ManiphestTransaction::TYPE_PRIORITY)
->setTransactionType(ManiphestTaskPriorityTransaction::TRANSACTIONTYPE)
->setNewValue($pri);
$xactions[] = id(new ManiphestTransaction())
->setTransactionType(ManiphestTransaction::TYPE_SUBPRIORITY)
->setTransactionType(ManiphestTaskSubpriorityTransaction::TRANSACTIONTYPE)
->setNewValue($sub);
return $this->applyTaskTransactions($viewer, $src, $xactions);

View file

@ -76,9 +76,9 @@ final class ManiphestTaskEditBulkJobType
$value_map = array();
$type_map = array(
'add_comment' => PhabricatorTransactions::TYPE_COMMENT,
'assign' => ManiphestTransaction::TYPE_OWNER,
'status' => ManiphestTransaction::TYPE_STATUS,
'priority' => ManiphestTransaction::TYPE_PRIORITY,
'assign' => ManiphestTaskOwnerTransaction::TRANSACTIONTYPE,
'status' => ManiphestTaskStatusTransaction::TRANSACTIONTYPE,
'priority' => ManiphestTaskPriorityTransaction::TRANSACTIONTYPE,
'add_project' => PhabricatorTransactions::TYPE_EDGE,
'remove_project' => PhabricatorTransactions::TYPE_EDGE,
'add_ccs' => PhabricatorTransactions::TYPE_SUBSCRIBERS,
@ -114,13 +114,13 @@ final class ManiphestTaskEditBulkJobType
case PhabricatorTransactions::TYPE_COMMENT:
$current = null;
break;
case ManiphestTransaction::TYPE_OWNER:
case ManiphestTaskOwnerTransaction::TRANSACTIONTYPE:
$current = $task->getOwnerPHID();
break;
case ManiphestTransaction::TYPE_STATUS:
case ManiphestTaskStatusTransaction::TRANSACTIONTYPE:
$current = $task->getStatus();
break;
case ManiphestTransaction::TYPE_PRIORITY:
case ManiphestTaskPriorityTransaction::TRANSACTIONTYPE:
$current = $task->getPriority();
break;
case PhabricatorTransactions::TYPE_EDGE:
@ -153,7 +153,7 @@ final class ManiphestTaskEditBulkJobType
}
$value = head($value);
break;
case ManiphestTransaction::TYPE_OWNER:
case ManiphestTaskOwnerTransaction::TRANSACTIONTYPE:
if (empty($value)) {
continue 2;
}

View file

@ -53,7 +53,7 @@ final class ManiphestAssignEmailCommand
}
$xactions[] = $object->getApplicationTransactionTemplate()
->setTransactionType(ManiphestTransaction::TYPE_OWNER)
->setTransactionType(ManiphestTaskOwnerTransaction::TRANSACTIONTYPE)
->setNewValue($assign_phid);
return $xactions;

View file

@ -23,7 +23,7 @@ final class ManiphestClaimEmailCommand
$xactions = array();
$xactions[] = $object->getApplicationTransactionTemplate()
->setTransactionType(ManiphestTransaction::TYPE_OWNER)
->setTransactionType(ManiphestTaskOwnerTransaction::TRANSACTIONTYPE)
->setNewValue($viewer->getPHID());
return $xactions;

View file

@ -24,7 +24,7 @@ final class ManiphestCloseEmailCommand
$xactions = array();
$xactions[] = $object->getApplicationTransactionTemplate()
->setTransactionType(ManiphestTransaction::TYPE_STATUS)
->setTransactionType(ManiphestTaskStatusTransaction::TRANSACTIONTYPE)
->setNewValue(ManiphestTaskStatus::getDefaultClosedStatus());
return $xactions;

View file

@ -71,7 +71,7 @@ final class ManiphestPriorityEmailCommand
}
$xactions[] = $object->getApplicationTransactionTemplate()
->setTransactionType(ManiphestTransaction::TYPE_PRIORITY)
->setTransactionType(ManiphestTaskPriorityTransaction::TRANSACTIONTYPE)
->setNewValue($priority);
return $xactions;

View file

@ -73,7 +73,7 @@ final class ManiphestStatusEmailCommand
}
$xactions[] = $object->getApplicationTransactionTemplate()
->setTransactionType(ManiphestTransaction::TYPE_STATUS)
->setTransactionType(ManiphestTaskStatusTransaction::TRANSACTIONTYPE)
->setNewValue($status);
return $xactions;

View file

@ -60,7 +60,7 @@ abstract class ManiphestConduitAPIMethod extends ConduitAPIMethod {
if ($is_new) {
$task->setTitle((string)$request->getValue('title'));
$task->setDescription((string)$request->getValue('description'));
$changes[ManiphestTransaction::TYPE_STATUS] =
$changes[ManiphestTaskStatusTransaction::TRANSACTIONTYPE] =
ManiphestTaskStatus::getDefaultStatus();
$changes[PhabricatorTransactions::TYPE_SUBSCRIBERS] =
array('+' => array($request->getUser()->getPHID()));
@ -73,12 +73,12 @@ abstract class ManiphestConduitAPIMethod extends ConduitAPIMethod {
$title = $request->getValue('title');
if ($title !== null) {
$changes[ManiphestTransaction::TYPE_TITLE] = $title;
$changes[ManiphestTaskTitleTransaction::TRANSACTIONTYPE] = $title;
}
$desc = $request->getValue('description');
if ($desc !== null) {
$changes[ManiphestTransaction::TYPE_DESCRIPTION] = $desc;
$changes[ManiphestTaskDescriptionTransaction::TRANSACTIONTYPE] = $desc;
}
$status = $request->getValue('status');
@ -88,7 +88,7 @@ abstract class ManiphestConduitAPIMethod extends ConduitAPIMethod {
throw id(new ConduitException('ERR-INVALID-PARAMETER'))
->setErrorDescription(pht('Status set to invalid value.'));
}
$changes[ManiphestTransaction::TYPE_STATUS] = $status;
$changes[ManiphestTaskStatusTransaction::TRANSACTIONTYPE] = $status;
}
}
@ -99,7 +99,7 @@ abstract class ManiphestConduitAPIMethod extends ConduitAPIMethod {
throw id(new ConduitException('ERR-INVALID-PARAMETER'))
->setErrorDescription(pht('Priority set to invalid value.'));
}
$changes[ManiphestTransaction::TYPE_PRIORITY] = $priority;
$changes[ManiphestTaskPriorityTransaction::TRANSACTIONTYPE] = $priority;
}
$owner_phid = $request->getValue('ownerPHID');
@ -108,7 +108,7 @@ abstract class ManiphestConduitAPIMethod extends ConduitAPIMethod {
array($owner_phid),
PhabricatorPeopleUserPHIDType::TYPECONST,
'ownerPHID');
$changes[ManiphestTransaction::TYPE_OWNER] = $owner_phid;
$changes[ManiphestTaskOwnerTransaction::TRANSACTIONTYPE] = $owner_phid;
}
$ccs = $request->getValue('ccPHIDs');

View file

@ -93,7 +93,7 @@ final class ManiphestReportController extends ManiphestController {
ORDER BY x.dateCreated ASC',
$table->getTableName(),
$joins,
ManiphestTransaction::TYPE_STATUS);
ManiphestTaskStatusTransaction::TRANSACTIONTYPE);
$stats = array();
$day_buckets = array();

View file

@ -43,11 +43,11 @@ final class ManiphestSubpriorityController extends ManiphestController {
$xactions = array();
$xactions[] = id(new ManiphestTransaction())
->setTransactionType(ManiphestTransaction::TYPE_PRIORITY)
->setTransactionType(ManiphestTaskPriorityTransaction::TRANSACTIONTYPE)
->setNewValue($pri);
$xactions[] = id(new ManiphestTransaction())
->setTransactionType(ManiphestTransaction::TYPE_SUBPRIORITY)
->setTransactionType(ManiphestTaskSubpriorityTransaction::TRANSACTIONTYPE)
->setNewValue($sub);
$editor = id(new ManiphestTransactionEditor())

View file

@ -277,7 +277,7 @@ final class ManiphestTaskDetailController extends ManiphestController {
$can_create = (bool)$edit_config;
$can_reassign = $edit_engine->hasEditAccessToTransaction(
ManiphestTransaction::TYPE_OWNER);
ManiphestTaskOwnerTransaction::TRANSACTIONTYPE);
if ($can_create) {
$form_key = $edit_config->getIdentifier();

View file

@ -150,7 +150,7 @@ EODOCS
->setConduitDescription(pht('Create as a subtask of another task.'))
->setConduitTypeDescription(pht('PHID of the parent task.'))
->setAliases(array('parentPHID'))
->setTransactionType(ManiphestTransaction::TYPE_PARENT)
->setTransactionType(ManiphestTaskParentTransaction::TRANSACTIONTYPE)
->setHandleParameterType(new ManiphestTaskListHTTPParameterType())
->setSingleValue(null)
->setIsReorderable(false)
@ -179,7 +179,7 @@ EODOCS
->setDescription(pht('Name of the task.'))
->setConduitDescription(pht('Rename the task.'))
->setConduitTypeDescription(pht('New task name.'))
->setTransactionType(ManiphestTransaction::TYPE_TITLE)
->setTransactionType(ManiphestTaskTitleTransaction::TRANSACTIONTYPE)
->setIsRequired(true)
->setValue($object->getTitle()),
id(new PhabricatorUsersEditField())
@ -190,7 +190,7 @@ EODOCS
->setConduitDescription(pht('Reassign the task.'))
->setConduitTypeDescription(
pht('New task owner, or `null` to unassign.'))
->setTransactionType(ManiphestTransaction::TYPE_OWNER)
->setTransactionType(ManiphestTaskOwnerTransaction::TRANSACTIONTYPE)
->setIsCopyable(true)
->setSingleValue($object->getOwnerPHID())
->setCommentActionLabel(pht('Assign / Claim'))
@ -201,7 +201,7 @@ EODOCS
->setDescription(pht('Status of the task.'))
->setConduitDescription(pht('Change the task status.'))
->setConduitTypeDescription(pht('New task status constant.'))
->setTransactionType(ManiphestTransaction::TYPE_STATUS)
->setTransactionType(ManiphestTaskStatusTransaction::TRANSACTIONTYPE)
->setIsCopyable(true)
->setValue($object->getStatus())
->setOptions($status_map)
@ -213,7 +213,7 @@ EODOCS
->setDescription(pht('Priority of the task.'))
->setConduitDescription(pht('Change the priority of the task.'))
->setConduitTypeDescription(pht('New task priority constant.'))
->setTransactionType(ManiphestTransaction::TYPE_PRIORITY)
->setTransactionType(ManiphestTaskPriorityTransaction::TRANSACTIONTYPE)
->setIsCopyable(true)
->setValue($object->getPriority())
->setOptions($priority_map)
@ -230,7 +230,7 @@ EODOCS
->setDescription(pht('Point value of the task.'))
->setConduitDescription(pht('Change the task point value.'))
->setConduitTypeDescription(pht('New task point value.'))
->setTransactionType(ManiphestTransaction::TYPE_POINTS)
->setTransactionType(ManiphestTaskPointsTransaction::TRANSACTIONTYPE)
->setIsCopyable(true)
->setValue($object->getPoints())
->setCommentActionLabel($action_label);
@ -242,7 +242,7 @@ EODOCS
->setDescription(pht('Task description.'))
->setConduitDescription(pht('Update the task description.'))
->setConduitTypeDescription(pht('New task description.'))
->setTransactionType(ManiphestTransaction::TYPE_DESCRIPTION)
->setTransactionType(ManiphestTaskDescriptionTransaction::TRANSACTIONTYPE)
->setValue($object->getDescription())
->setPreviewPanel(
id(new PHUIRemarkupPreviewPanel())

View file

@ -18,18 +18,6 @@ final class ManiphestTransactionEditor
$types[] = PhabricatorTransactions::TYPE_COMMENT;
$types[] = PhabricatorTransactions::TYPE_EDGE;
$types[] = ManiphestTransaction::TYPE_PRIORITY;
$types[] = ManiphestTransaction::TYPE_STATUS;
$types[] = ManiphestTransaction::TYPE_TITLE;
$types[] = ManiphestTransaction::TYPE_DESCRIPTION;
$types[] = ManiphestTransaction::TYPE_OWNER;
$types[] = ManiphestTransaction::TYPE_SUBPRIORITY;
$types[] = ManiphestTransaction::TYPE_MERGED_INTO;
$types[] = ManiphestTransaction::TYPE_MERGED_FROM;
$types[] = ManiphestTransaction::TYPE_UNBLOCK;
$types[] = ManiphestTransaction::TYPE_PARENT;
$types[] = ManiphestTransaction::TYPE_COVER_IMAGE;
$types[] = ManiphestTransaction::TYPE_POINTS;
$types[] = PhabricatorTransactions::TYPE_COLUMNS;
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
$types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
@ -37,47 +25,19 @@ final class ManiphestTransactionEditor
return $types;
}
public function getCreateObjectTitle($author, $object) {
return pht('%s created this task.', $author);
}
public function getCreateObjectTitleForFeed($author, $object) {
return pht('%s created %s.', $author, $object);
}
protected function getCustomTransactionOldValue(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case ManiphestTransaction::TYPE_PRIORITY:
if ($this->getIsNewObject()) {
return null;
}
return (int)$object->getPriority();
case ManiphestTransaction::TYPE_STATUS:
if ($this->getIsNewObject()) {
return null;
}
return $object->getStatus();
case ManiphestTransaction::TYPE_TITLE:
if ($this->getIsNewObject()) {
return null;
}
return $object->getTitle();
case ManiphestTransaction::TYPE_DESCRIPTION:
if ($this->getIsNewObject()) {
return null;
}
return $object->getDescription();
case ManiphestTransaction::TYPE_OWNER:
return nonempty($object->getOwnerPHID(), null);
case ManiphestTransaction::TYPE_SUBPRIORITY:
return $object->getSubpriority();
case ManiphestTransaction::TYPE_COVER_IMAGE:
return $object->getCoverImageFilePHID();
case ManiphestTransaction::TYPE_POINTS:
$points = $object->getPoints();
if ($points !== null) {
$points = (double)$points;
}
return $points;
case ManiphestTransaction::TYPE_MERGED_INTO:
case ManiphestTransaction::TYPE_MERGED_FROM:
return null;
case ManiphestTransaction::TYPE_PARENT:
case PhabricatorTransactions::TYPE_COLUMNS:
return null;
}
@ -88,31 +48,8 @@ final class ManiphestTransactionEditor
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case ManiphestTransaction::TYPE_PRIORITY:
return (int)$xaction->getNewValue();
case ManiphestTransaction::TYPE_OWNER:
return nonempty($xaction->getNewValue(), null);
case ManiphestTransaction::TYPE_STATUS:
case ManiphestTransaction::TYPE_TITLE:
case ManiphestTransaction::TYPE_DESCRIPTION:
case ManiphestTransaction::TYPE_SUBPRIORITY:
case ManiphestTransaction::TYPE_MERGED_INTO:
case ManiphestTransaction::TYPE_MERGED_FROM:
case ManiphestTransaction::TYPE_UNBLOCK:
case ManiphestTransaction::TYPE_COVER_IMAGE:
return $xaction->getNewValue();
case ManiphestTransaction::TYPE_PARENT:
case PhabricatorTransactions::TYPE_COLUMNS:
return $xaction->getNewValue();
case ManiphestTransaction::TYPE_POINTS:
$value = $xaction->getNewValue();
if (!strlen($value)) {
$value = null;
}
if ($value !== null) {
$value = (double)$value;
}
return $value;
}
}
@ -136,72 +73,6 @@ final class ManiphestTransactionEditor
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case ManiphestTransaction::TYPE_PRIORITY:
return $object->setPriority($xaction->getNewValue());
case ManiphestTransaction::TYPE_STATUS:
return $object->setStatus($xaction->getNewValue());
case ManiphestTransaction::TYPE_TITLE:
return $object->setTitle($xaction->getNewValue());
case ManiphestTransaction::TYPE_DESCRIPTION:
return $object->setDescription($xaction->getNewValue());
case ManiphestTransaction::TYPE_OWNER:
$phid = $xaction->getNewValue();
// Update the "ownerOrdering" column to contain the full name of the
// owner, if the task is assigned.
$handle = null;
if ($phid) {
$handle = id(new PhabricatorHandleQuery())
->setViewer($this->getActor())
->withPHIDs(array($phid))
->executeOne();
}
if ($handle) {
$object->setOwnerOrdering($handle->getName());
} else {
$object->setOwnerOrdering(null);
}
return $object->setOwnerPHID($phid);
case ManiphestTransaction::TYPE_SUBPRIORITY:
$object->setSubpriority($xaction->getNewValue());
return;
case ManiphestTransaction::TYPE_MERGED_INTO:
$object->setStatus(ManiphestTaskStatus::getDuplicateStatus());
return;
case ManiphestTransaction::TYPE_COVER_IMAGE:
$file_phid = $xaction->getNewValue();
if ($file_phid) {
$file = id(new PhabricatorFileQuery())
->setViewer($this->getActor())
->withPHIDs(array($file_phid))
->executeOne();
} else {
$file = null;
}
if (!$file || !$file->isTransformableImage()) {
$object->setProperty('cover.filePHID', null);
$object->setProperty('cover.thumbnailPHID', null);
return;
}
$xform_key = PhabricatorFileThumbnailTransform::TRANSFORM_WORKCARD;
$xform = PhabricatorFileTransform::getTransformByKey($xform_key)
->executeTransform($file);
$object->setProperty('cover.filePHID', $file->getPHID());
$object->setProperty('cover.thumbnailPHID', $xform->getPHID());
return;
case ManiphestTransaction::TYPE_POINTS:
$object->setPoints($xaction->getNewValue());
return;
case ManiphestTransaction::TYPE_MERGED_FROM:
case ManiphestTransaction::TYPE_PARENT:
case PhabricatorTransactions::TYPE_COLUMNS:
return;
}
@ -212,22 +83,11 @@ final class ManiphestTransactionEditor
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case ManiphestTransaction::TYPE_PARENT:
$parent_phid = $xaction->getNewValue();
$parent_type = ManiphestTaskDependsOnTaskEdgeType::EDGECONST;
$task_phid = $object->getPHID();
id(new PhabricatorEdgeEditor())
->addEdge($parent_phid, $parent_type, $task_phid)
->save();
break;
case PhabricatorTransactions::TYPE_COLUMNS:
foreach ($xaction->getNewValue() as $move) {
$this->applyBoardMove($object, $move);
}
break;
default:
break;
}
}
@ -240,7 +100,7 @@ final class ManiphestTransactionEditor
$unblock_xaction = null;
foreach ($xactions as $xaction) {
switch ($xaction->getTransactionType()) {
case ManiphestTransaction::TYPE_STATUS:
case ManiphestTaskStatusTransaction::TRANSACTIONTYPE:
$unblock_xaction = $xaction;
break;
}
@ -265,7 +125,8 @@ final class ManiphestTransactionEditor
foreach ($blocked_tasks as $blocked_task) {
$parent_xaction = id(new ManiphestTransaction())
->setTransactionType(ManiphestTransaction::TYPE_UNBLOCK)
->setTransactionType(
ManiphestTaskUnblockTransaction::TRANSACTIONTYPE)
->setOldValue(array($object->getPHID() => $old))
->setNewValue(array($object->getPHID() => $new));
@ -398,7 +259,7 @@ final class ManiphestTransactionEditor
protected function shouldPublishFeedStory(
PhabricatorLiskDAO $object,
array $xactions) {
return $this->shouldSendMail($object, $xactions);
return true;
}
protected function supportsSearch() {
@ -426,11 +287,11 @@ final class ManiphestTransactionEditor
parent::requireCapabilities($object, $xaction);
$app_capability_map = array(
ManiphestTransaction::TYPE_PRIORITY =>
ManiphestTaskPriorityTransaction::TRANSACTIONTYPE =>
ManiphestEditPriorityCapability::CAPABILITY,
ManiphestTransaction::TYPE_STATUS =>
ManiphestTaskStatusTransaction::TRANSACTIONTYPE =>
ManiphestEditStatusCapability::CAPABILITY,
ManiphestTransaction::TYPE_OWNER =>
ManiphestTaskOwnerTransaction::TRANSACTIONTYPE =>
ManiphestEditAssignCapability::CAPABILITY,
PhabricatorTransactions::TYPE_EDIT_POLICY =>
ManiphestEditPoliciesCapability::CAPABILITY,
@ -471,7 +332,7 @@ final class ManiphestTransactionEditor
$copy = parent::adjustObjectForPolicyChecks($object, $xactions);
foreach ($xactions as $xaction) {
switch ($xaction->getTransactionType()) {
case ManiphestTransaction::TYPE_OWNER:
case ManiphestTaskOwnerTransaction::TRANSACTIONTYPE:
$copy->setOwnerPHID($xaction->getNewValue());
break;
default:
@ -629,157 +490,6 @@ final class ManiphestTransactionEditor
return array($dst->getPriority(), $sub);
}
protected function validateTransaction(
PhabricatorLiskDAO $object,
$type,
array $xactions) {
$errors = parent::validateTransaction($object, $type, $xactions);
switch ($type) {
case ManiphestTransaction::TYPE_TITLE:
$missing = $this->validateIsEmptyTextField(
$object->getTitle(),
$xactions);
if ($missing) {
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Required'),
pht('Task title is required.'),
nonempty(last($xactions), null));
$error->setIsMissingFieldError(true);
$errors[] = $error;
}
break;
case ManiphestTransaction::TYPE_PARENT:
$with_effect = array();
foreach ($xactions as $xaction) {
$task_phid = $xaction->getNewValue();
if (!$task_phid) {
continue;
}
$with_effect[] = $xaction;
$task = id(new ManiphestTaskQuery())
->setViewer($this->getActor())
->withPHIDs(array($task_phid))
->executeOne();
if (!$task) {
$errors[] = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid'),
pht(
'Parent task identifier "%s" does not identify a visible '.
'task.',
$task_phid),
$xaction);
}
}
if ($with_effect && !$this->getIsNewObject()) {
$errors[] = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid'),
pht(
'You can only select a parent task when creating a '.
'transaction for the first time.'),
last($with_effect));
}
break;
case ManiphestTransaction::TYPE_OWNER:
foreach ($xactions as $xaction) {
$old = $xaction->getOldValue();
$new = $xaction->getNewValue();
if (!strlen($new)) {
continue;
}
if ($new === $old) {
continue;
}
$assignee_list = id(new PhabricatorPeopleQuery())
->setViewer($this->getActor())
->withPHIDs(array($new))
->execute();
if (!$assignee_list) {
$errors[] = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid'),
pht(
'User "%s" is not a valid user.',
$new),
$xaction);
}
}
break;
case ManiphestTransaction::TYPE_COVER_IMAGE:
foreach ($xactions as $xaction) {
$old = $xaction->getOldValue();
$new = $xaction->getNewValue();
if (!$new) {
continue;
}
if ($new === $old) {
continue;
}
$file = id(new PhabricatorFileQuery())
->setViewer($this->getActor())
->withPHIDs(array($new))
->executeOne();
if (!$file) {
$errors[] = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid'),
pht('File "%s" is not valid.', $new),
$xaction);
continue;
}
if (!$file->isTransformableImage()) {
$errors[] = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid'),
pht('File "%s" is not a valid image file.', $new),
$xaction);
continue;
}
}
break;
case ManiphestTransaction::TYPE_POINTS:
foreach ($xactions as $xaction) {
$new = $xaction->getNewValue();
if (strlen($new) && !is_numeric($new)) {
$errors[] = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid'),
pht('Points value must be numeric or empty.'),
$xaction);
continue;
}
if ((double)$new < 0) {
$errors[] = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid'),
pht('Points value must be nonnegative.'),
$xaction);
continue;
}
}
break;
}
return $errors;
}
protected function validateAllTransactions(
PhabricatorLiskDAO $object,
array $xactions) {
@ -806,7 +516,8 @@ final class ManiphestTransactionEditor
$any_assign = false;
foreach ($xactions as $xaction) {
if ($xaction->getTransactionType() == ManiphestTransaction::TYPE_OWNER) {
if ($xaction->getTransactionType() ==
ManiphestTaskOwnerTransaction::TRANSACTIONTYPE) {
$any_assign = true;
break;
}
@ -817,7 +528,7 @@ final class ManiphestTransactionEditor
$new_status = null;
foreach ($xactions as $xaction) {
switch ($xaction->getTransactionType()) {
case ManiphestTransaction::TYPE_STATUS:
case ManiphestTaskStatusTransaction::TRANSACTIONTYPE:
$new_status = $xaction->getNewValue();
break;
}
@ -838,7 +549,7 @@ final class ManiphestTransactionEditor
// Don't claim the task if the status is configured to not claim.
if ($actor_phid && $is_claim) {
$results[] = id(new ManiphestTransaction())
->setTransactionType(ManiphestTransaction::TYPE_OWNER)
->setTransactionType(ManiphestTaskOwnerTransaction::TRANSACTIONTYPE)
->setNewValue($actor_phid);
}
}
@ -881,7 +592,7 @@ final class ManiphestTransactionEditor
$this->moreValidationErrors[] = $error;
}
break;
case ManiphestTransaction::TYPE_OWNER:
case ManiphestTaskOwnerTransaction::TRANSACTIONTYPE:
// If this is a no-op update, don't expand it.
$old_value = $object->getOwnerPHID();
$new_value = $xaction->getNewValue();
@ -906,20 +617,6 @@ final class ManiphestTransactionEditor
return $results;
}
protected function extractFilePHIDsFromCustomTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
$phids = parent::extractFilePHIDsFromCustomTransaction($object, $xaction);
switch ($xaction->getTransactionType()) {
case ManiphestTransaction::TYPE_COVER_IMAGE:
$phids[] = $xaction->getNewValue();
break;
}
return $phids;
}
private function buildMoveTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {

View file

@ -40,7 +40,7 @@ abstract class ManiphestTaskAssignHeraldAction
}
$xaction = $adapter->newTransaction()
->setTransactionType(ManiphestTransaction::TYPE_OWNER)
->setTransactionType(ManiphestTaskOwnerTransaction::TRANSACTIONTYPE)
->setNewValue($phid);
$adapter->queueTransaction($xaction);

View file

@ -40,7 +40,7 @@ final class ManiphestTaskPriorityHeraldAction
}
$xaction = $adapter->newTransaction()
->setTransactionType(ManiphestTransaction::TYPE_PRIORITY)
->setTransactionType(ManiphestTaskPriorityTransaction::TRANSACTIONTYPE)
->setNewValue($priority);
$adapter->queueTransaction($xaction);

View file

@ -40,7 +40,7 @@ final class ManiphestTaskStatusHeraldAction
}
$xaction = $adapter->newTransaction()
->setTransactionType(ManiphestTransaction::TYPE_STATUS)
->setTransactionType(ManiphestTaskStatusTransaction::TRANSACTIONTYPE)
->setNewValue($status);
$adapter->queueTransaction($xaction);

View file

@ -22,15 +22,15 @@ final class PhabricatorManiphestTaskTestDataGenerator
$template = new ManiphestTransaction();
// Accumulate Transactions
$changes = array();
$changes[ManiphestTransaction::TYPE_TITLE] =
$changes[ManiphestTaskTitleTransaction::TRANSACTIONTYPE] =
$this->generateTitle();
$changes[ManiphestTransaction::TYPE_DESCRIPTION] =
$changes[ManiphestTaskDescriptionTransaction::TRANSACTIONTYPE] =
$this->generateDescription();
$changes[ManiphestTransaction::TYPE_OWNER] =
$changes[ManiphestTaskOwnerTransaction::TRANSACTIONTYPE] =
$this->loadOwnerPHID();
$changes[ManiphestTransaction::TYPE_STATUS] =
$changes[ManiphestTaskStatusTransaction::TRANSACTIONTYPE] =
$this->generateTaskStatus();
$changes[ManiphestTransaction::TYPE_PRIORITY] =
$changes[ManiphestTaskPriorityTransaction::TRANSACTIONTYPE] =
$this->generateTaskPriority();
$changes[PhabricatorTransactions::TYPE_SUBSCRIBERS] =
array('=' => $this->getCCPHIDs());

View file

@ -25,11 +25,12 @@ final class ManiphestReplyHandler
if ($is_new) {
$xactions[] = $this->newTransaction()
->setTransactionType(ManiphestTransaction::TYPE_TITLE)
->setTransactionType(ManiphestTaskTitleTransaction::TRANSACTIONTYPE)
->setNewValue(nonempty($mail->getSubject(), pht('Untitled Task')));
$xactions[] = $this->newTransaction()
->setTransactionType(ManiphestTransaction::TYPE_DESCRIPTION)
->setTransactionType(
ManiphestTaskDescriptionTransaction::TRANSACTIONTYPE)
->setNewValue($body);
$actor_phid = $actor->getPHID();

View file

@ -19,7 +19,8 @@ abstract class ManiphestTaskRelationship
protected function newMergeIntoTransactions(ManiphestTask $task) {
return array(
id(new ManiphestTransaction())
->setTransactionType(ManiphestTransaction::TYPE_MERGED_INTO)
->setTransactionType(
ManiphestTaskMergedIntoTransaction::TRANSACTIONTYPE)
->setNewValue($task->getPHID()),
);
}
@ -34,7 +35,8 @@ abstract class ManiphestTaskRelationship
->setNewValue(array('+' => $subscriber_phids));
$xactions[] = id(new ManiphestTransaction())
->setTransactionType(ManiphestTransaction::TYPE_MERGED_FROM)
->setTransactionType(
ManiphestTaskMergedFromTransaction::TRANSACTIONTYPE)
->setNewValue(mpull($tasks, 'getPHID'));
return $xactions;

View file

@ -1,25 +1,7 @@
<?php
final class ManiphestTransaction
extends PhabricatorApplicationTransaction {
const TYPE_TITLE = 'title';
const TYPE_STATUS = 'status';
const TYPE_DESCRIPTION = 'description';
const TYPE_OWNER = 'reassign';
const TYPE_PRIORITY = 'priority';
const TYPE_EDGE = 'edge';
const TYPE_SUBPRIORITY = 'subpriority';
const TYPE_MERGED_INTO = 'mergedinto';
const TYPE_MERGED_FROM = 'mergedfrom';
const TYPE_UNBLOCK = 'unblock';
const TYPE_PARENT = 'parent';
const TYPE_COVER_IMAGE = 'cover-image';
const TYPE_POINTS = 'points';
// NOTE: this type is deprecated. Keep it around for legacy installs
// so any transactions render correctly.
const TYPE_ATTACH = 'attach';
extends PhabricatorModularTransaction {
const MAILTAG_STATUS = 'maniphest-status';
const MAILTAG_OWNER = 'maniphest-owner';
@ -44,30 +26,20 @@ final class ManiphestTransaction
return new ManiphestTransactionComment();
}
public function getBaseTransactionClass() {
return 'ManiphestTaskTransactionType';
}
public function shouldGenerateOldValue() {
switch ($this->getTransactionType()) {
case self::TYPE_EDGE:
case self::TYPE_UNBLOCK:
case ManiphestTaskEdgeTransaction::TRANSACTIONTYPE:
case ManiphestTaskUnblockTransaction::TRANSACTIONTYPE:
return false;
}
return parent::shouldGenerateOldValue();
}
protected function newRemarkupChanges() {
$changes = array();
switch ($this->getTransactionType()) {
case self::TYPE_DESCRIPTION:
$changes[] = $this->newRemarkupChange()
->setOldValue($this->getOldValue())
->setNewValue($this->getNewValue());
break;
}
return $changes;
}
public function getRequiredHandlePHIDs() {
$phids = parent::getRequiredHandlePHIDs();
@ -75,7 +47,7 @@ final class ManiphestTransaction
$old = $this->getOldValue();
switch ($this->getTransactionType()) {
case self::TYPE_OWNER:
case ManiphestTaskOwnerTransaction::TRANSACTIONTYPE:
if ($new) {
$phids[] = $new;
}
@ -84,13 +56,13 @@ final class ManiphestTransaction
$phids[] = $old;
}
break;
case self::TYPE_MERGED_INTO:
case ManiphestTaskMergedIntoTransaction::TRANSACTIONTYPE:
$phids[] = $new;
break;
case self::TYPE_MERGED_FROM:
case ManiphestTaskMergedFromTransaction::TRANSACTIONTYPE:
$phids = array_merge($phids, $new);
break;
case self::TYPE_EDGE:
case ManiphestTaskEdgeTransaction::TRANSACTIONTYPE:
$phids = array_mergev(
array(
$phids,
@ -98,7 +70,7 @@ final class ManiphestTransaction
array_keys(nonempty($new, array())),
));
break;
case self::TYPE_ATTACH:
case ManiphestTaskAttachTransaction::TRANSACTIONTYPE:
$old = nonempty($old, array());
$new = nonempty($new, array());
$phids = array_mergev(
@ -108,12 +80,12 @@ final class ManiphestTransaction
array_keys(idx($old, 'FILE', array())),
));
break;
case self::TYPE_UNBLOCK:
case ManiphestTaskUnblockTransaction::TRANSACTIONTYPE:
foreach (array_keys($new) as $phid) {
$phids[] = $phid;
}
break;
case self::TYPE_STATUS:
case ManiphestTaskStatusTransaction::TRANSACTIONTYPE:
$commit_phid = $this->getMetadataValue('commitPHID');
if ($commit_phid) {
$phids[] = $commit_phid;
@ -124,275 +96,27 @@ final class ManiphestTransaction
return $phids;
}
public function shouldHide() {
switch ($this->getTransactionType()) {
case PhabricatorTransactions::TYPE_EDGE:
$commit_phid = $this->getMetadataValue('commitPHID');
$edge_type = $this->getMetadataValue('edge:type');
if ($edge_type == ManiphestTaskHasCommitEdgeType::EDGECONST) {
if ($commit_phid) {
return true;
}
}
break;
case self::TYPE_DESCRIPTION:
case self::TYPE_PRIORITY:
case self::TYPE_STATUS:
if ($this->getOldValue() === null) {
return true;
} else {
return false;
}
break;
case self::TYPE_SUBPRIORITY:
case self::TYPE_PARENT:
return true;
case self::TYPE_COVER_IMAGE:
// At least for now, don't show these.
return true;
case self::TYPE_POINTS:
if (!ManiphestTaskPoints::getIsEnabled()) {
return true;
}
}
return parent::shouldHide();
}
public function shouldHideForMail(array $xactions) {
switch ($this->getTransactionType()) {
case self::TYPE_POINTS:
return true;
}
return parent::shouldHideForMail($xactions);
}
public function shouldHideForFeed() {
switch ($this->getTransactionType()) {
case self::TYPE_UNBLOCK:
// Hide "alice created X, a task blocking Y." from feed because it
// will almost always appear adjacent to "alice created Y".
$is_new = $this->getMetadataValue('blocker.new');
if ($is_new) {
return true;
}
break;
case self::TYPE_POINTS:
return true;
}
return parent::shouldHideForFeed();
}
public function getActionStrength() {
switch ($this->getTransactionType()) {
case self::TYPE_TITLE:
return 1.4;
case self::TYPE_STATUS:
return 1.3;
case self::TYPE_OWNER:
return 1.2;
case self::TYPE_PRIORITY:
return 1.1;
}
return parent::getActionStrength();
}
public function getColor() {
$old = $this->getOldValue();
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case self::TYPE_OWNER:
if ($this->getAuthorPHID() == $new) {
return 'green';
} else if (!$new) {
return 'black';
} else if (!$old) {
return 'green';
} else {
return 'green';
}
case self::TYPE_STATUS:
$color = ManiphestTaskStatus::getStatusColor($new);
if ($color !== null) {
return $color;
}
if (ManiphestTaskStatus::isOpenStatus($new)) {
return 'green';
} else {
return 'indigo';
}
case self::TYPE_PRIORITY:
if ($old == ManiphestTaskPriority::getDefaultPriority()) {
return 'green';
} else if ($old > $new) {
return 'grey';
} else {
return 'yellow';
}
case self::TYPE_MERGED_FROM:
return 'orange';
case self::TYPE_MERGED_INTO:
return 'indigo';
}
return parent::getColor();
}
public function getActionName() {
$old = $this->getOldValue();
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case self::TYPE_TITLE:
if ($old === null) {
return pht('Created');
}
return pht('Retitled');
case self::TYPE_STATUS:
$action = ManiphestTaskStatus::getStatusActionName($new);
if ($action) {
return $action;
}
$old_closed = ManiphestTaskStatus::isClosedStatus($old);
$new_closed = ManiphestTaskStatus::isClosedStatus($new);
if ($new_closed && !$old_closed) {
return pht('Closed');
} else if (!$new_closed && $old_closed) {
return pht('Reopened');
} else {
return pht('Changed Status');
}
case self::TYPE_DESCRIPTION:
return pht('Edited');
case self::TYPE_OWNER:
if ($this->getAuthorPHID() == $new) {
return pht('Claimed');
} else if (!$new) {
return pht('Unassigned');
} else if (!$old) {
return pht('Assigned');
} else {
return pht('Reassigned');
}
case PhabricatorTransactions::TYPE_COLUMNS:
return pht('Changed Project Column');
case self::TYPE_PRIORITY:
if ($old == ManiphestTaskPriority::getDefaultPriority()) {
return pht('Triaged');
} else if ($old > $new) {
return pht('Lowered Priority');
} else {
return pht('Raised Priority');
}
case self::TYPE_EDGE:
case self::TYPE_ATTACH:
return pht('Attached');
case self::TYPE_UNBLOCK:
$old_status = head($old);
$new_status = head($new);
$old_closed = ManiphestTaskStatus::isClosedStatus($old_status);
$new_closed = ManiphestTaskStatus::isClosedStatus($new_status);
if ($old_closed && !$new_closed) {
return pht('Block');
} else if (!$old_closed && $new_closed) {
return pht('Unblock');
} else {
return pht('Blocker');
}
case self::TYPE_MERGED_INTO:
case self::TYPE_MERGED_FROM:
return pht('Merged');
}
return parent::getActionName();
}
public function getIcon() {
$old = $this->getOldValue();
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case self::TYPE_OWNER:
return 'fa-user';
case self::TYPE_TITLE:
if ($old === null) {
return 'fa-pencil';
}
return 'fa-pencil';
case self::TYPE_STATUS:
$action = ManiphestTaskStatus::getStatusIcon($new);
if ($action !== null) {
return $action;
}
if (ManiphestTaskStatus::isClosedStatus($new)) {
return 'fa-check';
} else {
return 'fa-pencil';
}
case self::TYPE_DESCRIPTION:
return 'fa-pencil';
case PhabricatorTransactions::TYPE_COLUMNS:
return 'fa-columns';
case self::TYPE_MERGED_INTO:
return 'fa-check';
case self::TYPE_MERGED_FROM:
return 'fa-compress';
case self::TYPE_PRIORITY:
if ($old == ManiphestTaskPriority::getDefaultPriority()) {
return 'fa-arrow-right';
} else if ($old > $new) {
return 'fa-arrow-down';
} else {
return 'fa-arrow-up';
}
case self::TYPE_EDGE:
case self::TYPE_ATTACH:
return 'fa-thumb-tack';
case self::TYPE_UNBLOCK:
return 'fa-shield';
}
return parent::getIcon();
}
public function getTitle() {
$author_phid = $this->getAuthorPHID();
@ -400,244 +124,13 @@ final class ManiphestTransaction
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case PhabricatorTransactions::TYPE_CREATE:
return pht(
'%s created this task.',
$this->renderHandleLink($author_phid));
case PhabricatorTransactions::TYPE_SUBTYPE:
return pht(
'%s changed the subtype of this task from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$this->renderSubtypeName($old),
$this->renderSubtypeName($new));
case self::TYPE_TITLE:
if ($old === null) {
return pht(
'%s created this task.',
$this->renderHandleLink($author_phid));
}
return pht(
'%s changed the title from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$old,
$new);
case self::TYPE_DESCRIPTION:
return pht(
'%s edited the task description.',
$this->renderHandleLink($author_phid));
case self::TYPE_STATUS:
$old_closed = ManiphestTaskStatus::isClosedStatus($old);
$new_closed = ManiphestTaskStatus::isClosedStatus($new);
$old_name = ManiphestTaskStatus::getTaskStatusName($old);
$new_name = ManiphestTaskStatus::getTaskStatusName($new);
$commit_phid = $this->getMetadataValue('commitPHID');
if ($new_closed && !$old_closed) {
if ($new == ManiphestTaskStatus::getDuplicateStatus()) {
if ($commit_phid) {
return pht(
'%s closed this task as a duplicate by committing %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($commit_phid));
} else {
return pht(
'%s closed this task as a duplicate.',
$this->renderHandleLink($author_phid));
}
} else {
if ($commit_phid) {
return pht(
'%s closed this task as "%s" by committing %s.',
$this->renderHandleLink($author_phid),
$new_name,
$this->renderHandleLink($commit_phid));
} else {
return pht(
'%s closed this task as "%s".',
$this->renderHandleLink($author_phid),
$new_name);
}
}
} else if (!$new_closed && $old_closed) {
if ($commit_phid) {
return pht(
'%s reopened this task as "%s" by committing %s.',
$this->renderHandleLink($author_phid),
$new_name,
$this->renderHandleLink($commit_phid));
} else {
return pht(
'%s reopened this task as "%s".',
$this->renderHandleLink($author_phid),
$new_name);
}
} else {
if ($commit_phid) {
return pht(
'%s changed the task status from "%s" to "%s" by committing %s.',
$this->renderHandleLink($author_phid),
$old_name,
$new_name,
$this->renderHandleLink($commit_phid));
} else {
return pht(
'%s changed the task status from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$old_name,
$new_name);
}
}
case self::TYPE_UNBLOCK:
$blocker_phid = key($new);
$old_status = head($old);
$new_status = head($new);
$old_closed = ManiphestTaskStatus::isClosedStatus($old_status);
$new_closed = ManiphestTaskStatus::isClosedStatus($new_status);
$old_name = ManiphestTaskStatus::getTaskStatusName($old_status);
$new_name = ManiphestTaskStatus::getTaskStatusName($new_status);
if ($this->getMetadataValue('blocker.new')) {
return pht(
'%s created subtask %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($blocker_phid));
} else if ($old_closed && !$new_closed) {
return pht(
'%s reopened subtask %s as "%s".',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($blocker_phid),
$new_name);
} else if (!$old_closed && $new_closed) {
return pht(
'%s closed subtask %s as "%s".',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($blocker_phid),
$new_name);
} else {
return pht(
'%s changed the status of subtask %s from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($blocker_phid),
$old_name,
$new_name);
}
case self::TYPE_OWNER:
if ($author_phid == $new) {
return pht(
'%s claimed this task.',
$this->renderHandleLink($author_phid));
} else if (!$new) {
return pht(
'%s removed %s as the assignee of this task.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($old));
} else if (!$old) {
return pht(
'%s assigned this task to %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($new));
} else {
return pht(
'%s reassigned this task from %s to %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($old),
$this->renderHandleLink($new));
}
case self::TYPE_PRIORITY:
$old_name = ManiphestTaskPriority::getTaskPriorityName($old);
$new_name = ManiphestTaskPriority::getTaskPriorityName($new);
if ($old == ManiphestTaskPriority::getDefaultPriority()) {
return pht(
'%s triaged this task as "%s" priority.',
$this->renderHandleLink($author_phid),
$new_name);
} else if ($old > $new) {
return pht(
'%s lowered the priority of this task from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$old_name,
$new_name);
} else {
return pht(
'%s raised the priority of this task from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$old_name,
$new_name);
}
case self::TYPE_ATTACH:
$old = nonempty($old, array());
$new = nonempty($new, array());
$new = array_keys(idx($new, 'FILE', array()));
$old = array_keys(idx($old, 'FILE', array()));
$added = array_diff($new, $old);
$removed = array_diff($old, $new);
if ($added && !$removed) {
return pht(
'%s attached %s file(s): %s.',
$this->renderHandleLink($author_phid),
phutil_count($added),
$this->renderHandleList($added));
} else if ($removed && !$added) {
return pht(
'%s detached %s file(s): %s.',
$this->renderHandleLink($author_phid),
phutil_count($removed),
$this->renderHandleList($removed));
} else {
return pht(
'%s changed file(s), attached %s: %s; detached %s: %s.',
$this->renderHandleLink($author_phid),
phutil_count($added),
$this->renderHandleList($added),
phutil_count($removed),
$this->renderHandleList($removed));
}
case self::TYPE_MERGED_INTO:
return pht(
'%s closed this task as a duplicate of %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($new));
break;
case self::TYPE_MERGED_FROM:
return pht(
'%s merged %s task(s): %s.',
$this->renderHandleLink($author_phid),
phutil_count($new),
$this->renderHandleList($new));
break;
case self::TYPE_POINTS:
if ($old === null) {
return pht(
'%s set the point value for this task to %s.',
$this->renderHandleLink($author_phid),
$new);
} else if ($new === null) {
return pht(
'%s removed the point value for this task.',
$this->renderHandleLink($author_phid));
} else {
return pht(
'%s changed the point value for this task from %s to %s.',
$this->renderHandleLink($author_phid),
$old,
$new);
}
}
return parent::getTitle();
@ -651,236 +144,6 @@ final class ManiphestTransaction
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case self::TYPE_TITLE:
if ($old === null) {
return pht(
'%s created %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
}
return pht(
'%s renamed %s from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid),
$old,
$new);
case self::TYPE_DESCRIPTION:
return pht(
'%s edited the description of %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
case self::TYPE_STATUS:
$old_closed = ManiphestTaskStatus::isClosedStatus($old);
$new_closed = ManiphestTaskStatus::isClosedStatus($new);
$old_name = ManiphestTaskStatus::getTaskStatusName($old);
$new_name = ManiphestTaskStatus::getTaskStatusName($new);
$commit_phid = $this->getMetadataValue('commitPHID');
if ($new_closed && !$old_closed) {
if ($new == ManiphestTaskStatus::getDuplicateStatus()) {
if ($commit_phid) {
return pht(
'%s closed %s as a duplicate by committing %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid),
$this->renderHandleLink($commit_phid));
} else {
return pht(
'%s closed %s as a duplicate.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
}
} else {
if ($commit_phid) {
return pht(
'%s closed %s as "%s" by committing %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid),
$new_name,
$this->renderHandleLink($commit_phid));
} else {
return pht(
'%s closed %s as "%s".',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid),
$new_name);
}
}
} else if (!$new_closed && $old_closed) {
if ($commit_phid) {
return pht(
'%s reopened %s as "%s" by committing %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid),
$new_name,
$this->renderHandleLink($commit_phid));
} else {
return pht(
'%s reopened %s as "%s".',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid),
$new_name);
}
} else {
if ($commit_phid) {
return pht(
'%s changed the status of %s from "%s" to "%s" by committing %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid),
$old_name,
$new_name,
$this->renderHandleLink($commit_phid));
} else {
return pht(
'%s changed the status of %s from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid),
$old_name,
$new_name);
}
}
case self::TYPE_UNBLOCK:
$blocker_phid = key($new);
$old_status = head($old);
$new_status = head($new);
$old_closed = ManiphestTaskStatus::isClosedStatus($old_status);
$new_closed = ManiphestTaskStatus::isClosedStatus($new_status);
$old_name = ManiphestTaskStatus::getTaskStatusName($old_status);
$new_name = ManiphestTaskStatus::getTaskStatusName($new_status);
if ($old_closed && !$new_closed) {
return pht(
'%s reopened %s, a subtask of %s, as "%s".',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($blocker_phid),
$this->renderHandleLink($object_phid),
$new_name);
} else if (!$old_closed && $new_closed) {
return pht(
'%s closed %s, a subtask of %s, as "%s".',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($blocker_phid),
$this->renderHandleLink($object_phid),
$new_name);
} else {
return pht(
'%s changed the status of %s, a subtask of %s, '.
'from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($blocker_phid),
$this->renderHandleLink($object_phid),
$old_name,
$new_name);
}
case self::TYPE_OWNER:
if ($author_phid == $new) {
return pht(
'%s claimed %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
} else if (!$new) {
return pht(
'%s placed %s up for grabs.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
} else if (!$old) {
return pht(
'%s assigned %s to %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid),
$this->renderHandleLink($new));
} else {
return pht(
'%s reassigned %s from %s to %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid),
$this->renderHandleLink($old),
$this->renderHandleLink($new));
}
case self::TYPE_PRIORITY:
$old_name = ManiphestTaskPriority::getTaskPriorityName($old);
$new_name = ManiphestTaskPriority::getTaskPriorityName($new);
if ($old == ManiphestTaskPriority::getDefaultPriority()) {
return pht(
'%s triaged %s as "%s" priority.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid),
$new_name);
} else if ($old > $new) {
return pht(
'%s lowered the priority of %s from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid),
$old_name,
$new_name);
} else {
return pht(
'%s raised the priority of %s from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid),
$old_name,
$new_name);
}
case self::TYPE_ATTACH:
$old = nonempty($old, array());
$new = nonempty($new, array());
$new = array_keys(idx($new, 'FILE', array()));
$old = array_keys(idx($old, 'FILE', array()));
$added = array_diff($new, $old);
$removed = array_diff($old, $new);
if ($added && !$removed) {
return pht(
'%s attached %d file(s) of %s: %s',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid),
count($added),
$this->renderHandleList($added));
} else if ($removed && !$added) {
return pht(
'%s detached %d file(s) of %s: %s',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid),
count($removed),
$this->renderHandleList($removed));
} else {
return pht(
'%s changed file(s) for %s, attached %d: %s; detached %d: %s',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid),
count($added),
$this->renderHandleList($added),
count($removed),
$this->renderHandleList($removed));
}
case self::TYPE_MERGED_INTO:
return pht(
'%s merged task %s into %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid),
$this->renderHandleLink($new));
case self::TYPE_MERGED_FROM:
return pht(
'%s merged %s task(s) %s into %s.',
$this->renderHandleLink($author_phid),
phutil_count($new),
$this->renderHandleList($new),
$this->renderHandleLink($object_phid));
case PhabricatorTransactions::TYPE_SUBTYPE:
return pht(
'%s changed the subtype of %s from "%s" to "%s".',
@ -893,39 +156,14 @@ final class ManiphestTransaction
return parent::getTitleForFeed();
}
private function renderSubtypeName($value) {
$object = $this->getObject();
$map = $object->newEditEngineSubtypeMap();
if (!isset($map[$value])) {
return $value;
}
return $map[$value]->getName();
}
public function hasChangeDetails() {
switch ($this->getTransactionType()) {
case self::TYPE_DESCRIPTION:
return true;
}
return parent::hasChangeDetails();
}
public function renderChangeDetails(PhabricatorUser $viewer) {
return $this->renderTextCorpusChangeDetails(
$viewer,
$this->getOldValue(),
$this->getNewValue());
}
public function getMailTags() {
$tags = array();
switch ($this->getTransactionType()) {
case self::TYPE_MERGED_INTO:
case self::TYPE_STATUS:
case ManiphestTaskMergedIntoTransaction::TRANSACTIONTYPE:
case ManiphestTaskStatusTransaction::TRANSACTIONTYPE:
$tags[] = self::MAILTAG_STATUS;
break;
case self::TYPE_OWNER:
case ManiphestTaskOwnerTransaction::TRANSACTIONTYPE:
$tags[] = self::MAILTAG_OWNER;
break;
case PhabricatorTransactions::TYPE_SUBSCRIBERS:
@ -941,10 +179,10 @@ final class ManiphestTransaction
break;
}
break;
case self::TYPE_PRIORITY:
case ManiphestTaskPriorityTransaction::TRANSACTIONTYPE:
$tags[] = self::MAILTAG_PRIORITY;
break;
case self::TYPE_UNBLOCK:
case ManiphestTaskUnblockTransaction::TRANSACTIONTYPE:
$tags[] = self::MAILTAG_UNBLOCK;
break;
case PhabricatorTransactions::TYPE_COLUMNS:
@ -961,13 +199,12 @@ final class ManiphestTransaction
}
public function getNoEffectDescription() {
switch ($this->getTransactionType()) {
case self::TYPE_STATUS:
case ManiphestTaskStatusTransaction::TRANSACTIONTYPE:
return pht('The task already has the selected status.');
case self::TYPE_OWNER:
case ManiphestTaskOwnerTransaction::TRANSACTIONTYPE:
return pht('The task already has the selected owner.');
case self::TYPE_PRIORITY:
case ManiphestTaskPriorityTransaction::TRANSACTIONTYPE:
return pht('The task already has the selected priority.');
}

View file

@ -0,0 +1,91 @@
<?php
final class ManiphestTaskAttachTransaction
extends ManiphestTaskTransactionType {
// NOTE: this type is deprecated. Keep it around for legacy installs
// so any transactions render correctly.
const TRANSACTIONTYPE = 'attach';
public function getActionName() {
return pht('Attached');
}
public function getTitle() {
$old = $this->getOldValue();
$new = $this->getNewValue();
$old = nonempty($old, array());
$new = nonempty($new, array());
$new = array_keys(idx($new, 'FILE', array()));
$old = array_keys(idx($old, 'FILE', array()));
$added = array_diff($new, $old);
$removed = array_diff($old, $new);
if ($added && !$removed) {
return pht(
'%s attached %s file(s): %s.',
$this->renderAuthor(),
phutil_count($added),
$this->renderHandleList($added));
} else if ($removed && !$added) {
return pht(
'%s detached %s file(s): %s.',
$this->renderAuthor(),
phutil_count($removed),
$this->renderHandleList($removed));
} else {
return pht(
'%s changed file(s), attached %s: %s; detached %s: %s.',
$this->renderAuthor(),
phutil_count($added),
$this->renderHandleList($added),
phutil_count($removed),
$this->renderHandleList($removed));
}
}
public function getTitleForFeed() {
$old = $this->getOldValue();
$new = $this->getNewValue();
$old = nonempty($old, array());
$new = nonempty($new, array());
$new = array_keys(idx($new, 'FILE', array()));
$old = array_keys(idx($old, 'FILE', array()));
$added = array_diff($new, $old);
$removed = array_diff($old, $new);
if ($added && !$removed) {
return pht(
'%s attached %d file(s) of %s: %s',
$this->renderAuthor(),
$this->renderObject(),
count($added),
$this->renderHandleList($added));
} else if ($removed && !$added) {
return pht(
'%s detached %d file(s) of %s: %s',
$this->renderAuthor(),
$this->renderObject(),
count($removed),
$this->renderHandleList($removed));
} else {
return pht(
'%s changed file(s) for %s, attached %d: %s; detached %d: %s',
$this->renderAuthor(),
$this->renderObject(),
count($added),
$this->renderHandleList($added),
count($removed),
$this->renderHandleList($removed));
}
}
public function getIcon() {
return 'fa-thumb-tack';
}
}

View file

@ -0,0 +1,106 @@
<?php
final class ManiphestTaskCoverImageTransaction
extends ManiphestTaskTransactionType {
const TRANSACTIONTYPE = 'cover-image';
public function generateOldValue($object) {
return $object->getCoverImageFilePHID();
}
public function applyInternalEffects($object, $value) {
$file_phid = $value;
if ($file_phid) {
$file = id(new PhabricatorFileQuery())
->setViewer($this->getActor())
->withPHIDs(array($file_phid))
->executeOne();
} else {
$file = null;
}
if (!$file || !$file->isTransformableImage()) {
$object->setProperty('cover.filePHID', null);
$object->setProperty('cover.thumbnailPHID', null);
return;
}
$xform_key = PhabricatorFileThumbnailTransform::TRANSFORM_WORKCARD;
$xform = PhabricatorFileTransform::getTransformByKey($xform_key)
->executeTransform($file);
$object->setProperty('cover.filePHID', $file->getPHID());
$object->setProperty('cover.thumbnailPHID', $xform->getPHID());
}
public function getTitle() {
$old = $this->getOldValue();
$new = $this->getNewValue();
if ($old === null) {
return pht(
'%s set the cover image to %s.',
$this->renderAuthor(),
$this->renderHandle($new));
}
return pht(
'%s updated the cover image to %s.',
$this->renderAuthor(),
$this->renderHandle($new));
}
public function getTitleForFeed() {
$old = $this->getOldValue();
if ($old === null) {
return pht(
'%s added a cover image to %s.',
$this->renderAuthor(),
$this->renderObject());
}
return pht(
'%s updated the cover image for %s.',
$this->renderAuthor(),
$this->renderObject());
}
public function validateTransactions($object, array $xactions) {
$errors = array();
$viewer = $this->getActor();
foreach ($xactions as $xaction) {
$file_phid = $xaction->getNewValue();
$file = id(new PhabricatorFileQuery())
->setViewer($viewer)
->withPHIDs(array($file_phid))
->executeOne();
if (!$file) {
$errors[] = $this->newInvalidError(
pht('"%s" is not a valid file PHID.',
$file_phid));
} else {
if (!$file->isViewableImage()) {
$mime_type = $file->getMimeType();
$errors[] = $this->newInvalidError(
pht('File mime type of "%s" is not a valid viewable image.',
$mime_type));
}
}
}
return $errors;
}
public function getIcon() {
return 'fa-image';
}
}

View file

@ -0,0 +1,61 @@
<?php
final class ManiphestTaskDescriptionTransaction
extends ManiphestTaskTransactionType {
const TRANSACTIONTYPE = 'description';
public function generateOldValue($object) {
return $object->getDescription();
}
public function applyInternalEffects($object, $value) {
$object->setDescription($value);
}
public function getActionName() {
return pht('Edited');
}
public function getTitle() {
return pht(
'%s updated the task description.',
$this->renderAuthor());
}
public function getTitleForFeed() {
return pht(
'%s updated the task description for %s.',
$this->renderAuthor(),
$this->renderObject());
}
public function hasChangeDetailView() {
return true;
}
public function getMailDiffSectionHeader() {
return pht('CHANGES TO TASK DESCRIPTION');
}
public function newChangeDetailView() {
$viewer = $this->getViewer();
return id(new PhabricatorApplicationTransactionTextDiffDetailView())
->setViewer($viewer)
->setOldText($this->getOldValue())
->setNewText($this->getNewValue());
}
public function newRemarkupChanges() {
$changes = array();
$changes[] = $this->newRemarkupChange()
->setOldValue($this->getOldValue())
->setNewValue($this->getNewValue());
return $changes;
}
}

View file

@ -0,0 +1,31 @@
<?php
final class ManiphestTaskEdgeTransaction
extends ManiphestTaskTransactionType {
const TRANSACTIONTYPE = 'edge';
public function generateOldValue($object) {
return null;
}
public function shouldHide() {
$commit_phid = $this->getMetadataValue('commitPHID');
$edge_type = $this->getMetadataValue('edge:type');
if ($edge_type == ManiphestTaskHasCommitEdgeType::EDGECONST) {
if ($commit_phid) {
return true;
}
}
}
public function getActionName() {
return pht('Attached');
}
public function getIcon() {
return 'fa-thumb-tack';
}
}

View file

@ -0,0 +1,45 @@
<?php
final class ManiphestTaskMergedFromTransaction
extends ManiphestTaskTransactionType {
const TRANSACTIONTYPE = 'mergedfrom';
public function generateOldValue($object) {
return null;
}
public function getActionName() {
return pht('Merged');
}
public function getTitle() {
$new = $this->getNewValue();
return pht(
'%s merged %s task(s): %s.',
$this->renderAuthor(),
phutil_count($new),
$this->renderHandleList($new));
}
public function getTitleForFeed() {
$new = $this->getNewValue();
return pht(
'%s merged %s task(s) %s into %s.',
$this->renderAuthor(),
phutil_count($new),
$this->renderHandleList($new),
$this->renderObject());
}
public function getIcon() {
return 'fa-compress';
}
public function getColor() {
return 'orange';
}
}

View file

@ -0,0 +1,47 @@
<?php
final class ManiphestTaskMergedIntoTransaction
extends ManiphestTaskTransactionType {
const TRANSACTIONTYPE = 'mergedinto';
public function generateOldValue($object) {
return null;
}
public function applyInternalEffects($object, $value) {
$object->setStatus(ManiphestTaskStatus::getDuplicateStatus());
}
public function getActionName() {
return pht('Merged');
}
public function getTitle() {
$new = $this->getNewValue();
return pht(
'%s closed this task as a duplicate of %s.',
$this->renderAuthor(),
$this->renderHandle($new));
}
public function getTitleForFeed() {
$new = $this->getNewValue();
return pht(
'%s merged task %s into %s.',
$this->renderAuthor(),
$this->renderObject(),
$this->renderHandle($new));
}
public function getIcon() {
return 'fa-check';
}
public function getColor() {
return 'indigo';
}
}

View file

@ -0,0 +1,158 @@
<?php
final class ManiphestTaskOwnerTransaction
extends ManiphestTaskTransactionType {
const TRANSACTIONTYPE = 'reassign';
public function generateOldValue($object) {
return nonempty($object->getOwnerPHID(), null);
}
public function applyInternalEffects($object, $value) {
// Update the "ownerOrdering" column to contain the full name of the
// owner, if the task is assigned.
$handle = null;
if ($value) {
$handle = id(new PhabricatorHandleQuery())
->setViewer($this->getActor())
->withPHIDs(array($value))
->executeOne();
}
if ($handle) {
$object->setOwnerOrdering($handle->getName());
} else {
$object->setOwnerOrdering(null);
}
$object->setOwnerPHID($value);
}
public function getActionStrength() {
return 1.2;
}
public function getActionName() {
$old = $this->getOldValue();
$new = $this->getNewValue();
if ($this->getAuthorPHID() == $new) {
return pht('Claimed');
} else if (!$new) {
return pht('Unassigned');
} else if (!$old) {
return pht('Assigned');
} else {
return pht('Reassigned');
}
}
public function getTitle() {
$old = $this->getOldValue();
$new = $this->getNewValue();
if ($this->getAuthorPHID() == $new) {
return pht(
'%s claimed this task.',
$this->renderAuthor());
} else if (!$new) {
return pht(
'%s removed %s as the assignee of this task.',
$this->renderAuthor(),
$this->renderHandle($old));
} else if (!$old) {
return pht(
'%s assigned this task to %s.',
$this->renderAuthor(),
$this->renderHandle($new));
} else {
return pht(
'%s reassigned this task from %s to %s.',
$this->renderAuthor(),
$this->renderHandle($old),
$this->renderHandle($new));
}
}
public function getTitleForFeed() {
$old = $this->getOldValue();
$new = $this->getNewValue();
if ($this->getAuthorPHID() == $new) {
return pht(
'%s claimed %s.',
$this->renderAuthor(),
$this->renderObject());
} else if (!$new) {
return pht(
'%s placed %s up for grabs.',
$this->renderAuthor(),
$this->renderObject());
} else if (!$old) {
return pht(
'%s assigned %s to %s.',
$this->renderAuthor(),
$this->renderObject(),
$this->renderHandle($new));
} else {
return pht(
'%s reassigned %s from %s to %s.',
$this->renderAuthor(),
$this->renderObject(),
$this->renderHandle($old),
$this->renderHandle($new));
}
}
public function validateTransactions($object, array $xactions) {
$errors = array();
foreach ($xactions as $xaction) {
$old = $xaction->getOldValue();
$new = $xaction->getNewValue();
if (!strlen($new)) {
continue;
}
if ($new === $old) {
continue;
}
$assignee_list = id(new PhabricatorPeopleQuery())
->setViewer($this->getActor())
->withPHIDs(array($new))
->execute();
if (!$assignee_list) {
$errors[] = $this->newInvalidError(
pht('User "%s" is not a valid user.',
$new));
}
}
return $errors;
}
public function getIcon() {
return 'fa-user';
}
public function getColor() {
$old = $this->getOldValue();
$new = $this->getNewValue();
if ($this->getAuthorPHID() == $new) {
return 'green';
} else if (!$new) {
return 'black';
} else if (!$old) {
return 'green';
} else {
return 'green';
}
}
}

View file

@ -0,0 +1,60 @@
<?php
final class ManiphestTaskParentTransaction
extends ManiphestTaskTransactionType {
const TRANSACTIONTYPE = 'parent';
public function generateOldValue($object) {
return null;
}
public function shouldHide() {
return true;
}
public function applyExternalEffects($object, $value) {
$parent_phid = $value;
$parent_type = ManiphestTaskDependsOnTaskEdgeType::EDGECONST;
$task_phid = $object->getPHID();
id(new PhabricatorEdgeEditor())
->addEdge($parent_phid, $parent_type, $task_phid)
->save();
}
public function validateTransactions($object, array $xactions) {
$errors = array();
$with_effect = array();
foreach ($xactions as $xaction) {
$task_phid = $xaction->getNewValue();
if (!$task_phid) {
continue;
}
$with_effect[] = $xaction;
$task = id(new ManiphestTaskQuery())
->setViewer($this->getActor())
->withPHIDs(array($task_phid))
->executeOne();
if (!$task) {
$errors[] = $this->newInvalidError(
pht(
'Parent task identifier "%s" does not identify a visible '.
'task.',
$task_phid));
}
}
if ($with_effect && !$this->isNewObject()) {
$errors[] = $this->newInvalidError(
pht(
'You can only select a parent task when creating a '.
'transaction for the first time.'));
}
return $errors;
}
}

View file

@ -0,0 +1,88 @@
<?php
final class ManiphestTaskPointsTransaction
extends ManiphestTaskTransactionType {
const TRANSACTIONTYPE = 'points';
public function generateOldValue($object) {
return $this->getValueForPoints($object->getPoints());
}
public function generateNewValue($object, $value) {
return $this->getValueForPoints($value);
}
public function applyInternalEffects($object, $value) {
$object->setPoints($value);
}
public function shouldHideForFeed() {
return true;
}
public function shouldHide() {
if (!ManiphestTaskPoints::getIsEnabled()) {
return true;
}
return false;
}
public function getTitle() {
$old = $this->getOldValue();
$new = $this->getNewValue();
if ($old === null) {
return pht(
'%s set the point value for this task to %s.',
$this->renderAuthor(),
$this->renderNewValue());
} else if ($new === null) {
return pht(
'%s removed the point value for this task.',
$this->renderAuthor());
} else {
return pht(
'%s changed the point value for this task from %s to %s.',
$this->renderAuthor(),
$this->renderOldValue(),
$this->renderNewValue());
}
}
public function validateTransactions($object, array $xactions) {
$errors = array();
foreach ($xactions as $xaction) {
$new = $xaction->getNewValue();
if (strlen($new) && !is_numeric($new)) {
$errors[] = $this->newInvalidError(
pht('Points value must be numeric or empty.'));
continue;
}
if ((double)$new < 0) {
$errors[] = $this->newInvalidError(
pht('Points value must be nonnegative.'));
continue;
}
}
return $errors;
}
public function getIcon() {
return 'fa-calculator';
}
private function getValueForPoints($value) {
if (!strlen($value)) {
$value = null;
}
if ($value !== null) {
$value = (double)$value;
}
return $value;
}
}

View file

@ -0,0 +1,119 @@
<?php
final class ManiphestTaskPriorityTransaction
extends ManiphestTaskTransactionType {
const TRANSACTIONTYPE = 'priority';
public function generateOldValue($object) {
if ($this->isNewObject()) {
return null;
}
return $object->getPriority();
}
public function applyInternalEffects($object, $value) {
$object->setPriority($value);
}
public function getActionStrength() {
return 1.1;
}
public function getActionName() {
$old = $this->getOldValue();
$new = $this->getNewValue();
if ($old == ManiphestTaskPriority::getDefaultPriority()) {
return pht('Triaged');
} else if ($old > $new) {
return pht('Lowered Priority');
} else {
return pht('Raised Priority');
}
}
public function getTitle() {
$old = $this->getOldValue();
$new = $this->getNewValue();
$old_name = ManiphestTaskPriority::getTaskPriorityName($old);
$new_name = ManiphestTaskPriority::getTaskPriorityName($new);
if ($old == ManiphestTaskPriority::getDefaultPriority()) {
return pht(
'%s triaged this task as %s priority.',
$this->renderAuthor(),
$this->renderValue($new_name));
} else if ($old > $new) {
return pht(
'%s lowered the priority of this task from %s to %s.',
$this->renderAuthor(),
$this->renderValue($old_name),
$this->renderValue($new_name));
} else {
return pht(
'%s raised the priority of this task from %s to %s.',
$this->renderAuthor(),
$this->renderValue($old_name),
$this->renderValue($new_name));
}
}
public function getTitleForFeed() {
$old = $this->getOldValue();
$new = $this->getNewValue();
$old_name = ManiphestTaskPriority::getTaskPriorityName($old);
$new_name = ManiphestTaskPriority::getTaskPriorityName($new);
if ($old == ManiphestTaskPriority::getDefaultPriority()) {
return pht(
'%s triaged %s as %s priority.',
$this->renderAuthor(),
$this->renderObject(),
$this->renderValue($new_name));
} else if ($old > $new) {
return pht(
'%s lowered the priority of %s from %s to %s.',
$this->renderAuthor(),
$this->renderObject(),
$this->renderValue($old_name),
$this->renderValue($new_name));
} else {
return pht(
'%s raised the priority of %s from %s to %s.',
$this->renderAuthor(),
$this->renderObject(),
$this->renderValue($old_name),
$this->renderValue($new_name));
}
}
public function getIcon() {
$old = $this->getOldValue();
$new = $this->getNewValue();
if ($old == ManiphestTaskPriority::getDefaultPriority()) {
return 'fa-arrow-right';
} else if ($old > $new) {
return 'fa-arrow-down';
} else {
return 'fa-arrow-up';
}
}
public function getColor() {
$old = $this->getOldValue();
$new = $this->getNewValue();
if ($old == ManiphestTaskPriority::getDefaultPriority()) {
return 'green';
} else if ($old > $new) {
return 'grey';
} else {
return 'yellow';
}
}
}

View file

@ -0,0 +1,232 @@
<?php
final class ManiphestTaskStatusTransaction
extends ManiphestTaskTransactionType {
const TRANSACTIONTYPE = 'status';
public function generateOldValue($object) {
if ($this->isNewObject()) {
return null;
}
return $object->getStatus();
}
public function applyInternalEffects($object, $value) {
$object->setStatus($value);
}
public function shouldHide() {
if ($this->getOldValue() === null) {
return true;
} else {
return false;
}
}
public function getActionStrength() {
return 1.3;
}
public function getActionName() {
$old = $this->getOldValue();
$new = $this->getNewValue();
$action = ManiphestTaskStatus::getStatusActionName($new);
if ($action) {
return $action;
}
$old_closed = ManiphestTaskStatus::isClosedStatus($old);
$new_closed = ManiphestTaskStatus::isClosedStatus($new);
if ($new_closed && !$old_closed) {
return pht('Closed');
} else if (!$new_closed && $old_closed) {
return pht('Reopened');
} else {
return pht('Changed Status');
}
}
public function getTitle() {
$old = $this->getOldValue();
$new = $this->getNewValue();
$old_closed = ManiphestTaskStatus::isClosedStatus($old);
$new_closed = ManiphestTaskStatus::isClosedStatus($new);
$old_name = ManiphestTaskStatus::getTaskStatusName($old);
$new_name = ManiphestTaskStatus::getTaskStatusName($new);
$commit_phid = $this->getMetadataValue('commitPHID');
if ($new_closed && !$old_closed) {
if ($new == ManiphestTaskStatus::getDuplicateStatus()) {
if ($commit_phid) {
return pht(
'%s closed this task as a duplicate by committing %s.',
$this->renderAuthor(),
$this->renderHandle($commit_phid));
} else {
return pht(
'%s closed this task as a duplicate.',
$this->renderAuthor());
}
} else {
if ($commit_phid) {
return pht(
'%s closed this task as %s by committing %s.',
$this->renderAuthor(),
$this->renderValue($new_name),
$this->renderHandle($commit_phid));
} else {
return pht(
'%s closed this task as %s.',
$this->renderAuthor(),
$this->renderValue($new_name));
}
}
} else if (!$new_closed && $old_closed) {
if ($commit_phid) {
return pht(
'%s reopened this task as %s by committing %s.',
$this->renderAuthor(),
$this->renderValue($new_name),
$this->renderHandle($commit_phid));
} else {
return pht(
'%s reopened this task as %s.',
$this->renderAuthor(),
$this->renderValue($new_name));
}
} else {
if ($commit_phid) {
return pht(
'%s changed the task status from %s to %s by committing %s.',
$this->renderAuthor(),
$this->renderValue($old_name),
$this->renderValue($new_name),
$this->renderHandle($commit_phid));
} else {
return pht(
'%s changed the task status from %s to %s.',
$this->renderAuthor(),
$this->renderValue($old_name),
$this->renderValue($new_name));
}
}
}
public function getTitleForFeed() {
$old = $this->getOldValue();
$new = $this->getNewValue();
$old_closed = ManiphestTaskStatus::isClosedStatus($old);
$new_closed = ManiphestTaskStatus::isClosedStatus($new);
$old_name = ManiphestTaskStatus::getTaskStatusName($old);
$new_name = ManiphestTaskStatus::getTaskStatusName($new);
$commit_phid = $this->getMetadataValue('commitPHID');
if ($new_closed && !$old_closed) {
if ($new == ManiphestTaskStatus::getDuplicateStatus()) {
if ($commit_phid) {
return pht(
'%s closed %s as a duplicate by committing %s.',
$this->renderAuthor(),
$this->renderObject(),
$this->renderHandle($commit_phid));
} else {
return pht(
'%s closed %s as a duplicate.',
$this->renderAuthor(),
$this->renderObject());
}
} else {
if ($commit_phid) {
return pht(
'%s closed %s as %s by committing %s.',
$this->renderAuthor(),
$this->renderObject(),
$this->renderValue($new_name),
$this->renderHandle($commit_phid));
} else {
return pht(
'%s closed %s as %s.',
$this->renderAuthor(),
$this->renderObject(),
$this->renderValue($new_name));
}
}
} else if (!$new_closed && $old_closed) {
if ($commit_phid) {
return pht(
'%s reopened %s as %s by committing %s.',
$this->renderAuthor(),
$this->renderObject(),
$this->renderValue($new_name),
$this->renderHandle($commit_phid));
} else {
return pht(
'%s reopened %s as "%s".',
$this->renderAuthor(),
$this->renderObject(),
$new_name);
}
} else {
if ($commit_phid) {
return pht(
'%s changed the status of %s from %s to %s by committing %s.',
$this->renderAuthor(),
$this->renderObject(),
$this->renderValue($old_name),
$this->renderValue($new_name),
$this->renderHandle($commit_phid));
} else {
return pht(
'%s changed the status of %s from %s to %s.',
$this->renderAuthor(),
$this->renderObject(),
$this->renderValue($old_name),
$this->renderValue($new_name));
}
}
}
public function getIcon() {
$old = $this->getOldValue();
$new = $this->getNewValue();
$action = ManiphestTaskStatus::getStatusIcon($new);
if ($action !== null) {
return $action;
}
if (ManiphestTaskStatus::isClosedStatus($new)) {
return 'fa-check';
} else {
return 'fa-pencil';
}
}
public function getColor() {
$old = $this->getOldValue();
$new = $this->getNewValue();
$color = ManiphestTaskStatus::getStatusColor($new);
if ($color !== null) {
return $color;
}
if (ManiphestTaskStatus::isOpenStatus($new)) {
return 'green';
} else {
return 'indigo';
}
}
}

View file

@ -0,0 +1,21 @@
<?php
final class ManiphestTaskSubpriorityTransaction
extends ManiphestTaskTransactionType {
const TRANSACTIONTYPE = 'subpriority';
public function generateOldValue($object) {
return $object->getSubpriority();
}
public function applyInternalEffects($object, $value) {
$object->setSubpriority($value);
}
public function shouldHide() {
return true;
}
}

View file

@ -0,0 +1,74 @@
<?php
final class ManiphestTaskTitleTransaction
extends ManiphestTaskTransactionType {
const TRANSACTIONTYPE = 'title';
public function generateOldValue($object) {
return $object->getTitle();
}
public function applyInternalEffects($object, $value) {
$object->setTitle($value);
}
public function getActionStrength() {
return 1.4;
}
public function getActionName() {
$old = $this->getOldValue();
$new = $this->getNewValue();
if ($old === null) {
return pht('Created');
}
return pht('Retitled');
}
public function getTitle() {
$old = $this->getOldValue();
if ($old === null) {
return pht(
'%s created this task.',
$this->renderAuthor());
}
return pht(
'%s renamed this task from %s to %s.',
$this->renderAuthor(),
$this->renderOldValue(),
$this->renderNewValue());
}
public function getTitleForFeed() {
$old = $this->getOldValue();
if ($old === null) {
return pht(
'%s created %s.',
$this->renderAuthor(),
$this->renderObject());
}
return pht(
'%s renamed %s from %s to %s.',
$this->renderAuthor(),
$this->renderObject(),
$this->renderOldValue(),
$this->renderNewValue());
}
public function validateTransactions($object, array $xactions) {
$errors = array();
if ($this->isEmptyTextTransaction($object->getTitle(), $xactions)) {
$errors[] = $this->newRequiredError(
pht('Tasks must have a title.'));
}
return $errors;
}
}

View file

@ -0,0 +1,16 @@
<?php
abstract class ManiphestTaskTransactionType
extends PhabricatorModularTransactionType {
public function renderSubtypeName($value) {
$object = $this->getObject();
$map = $object->newEditEngineSubtypeMap();
if (!isset($map[$value])) {
return $value;
}
return $map[$value]->getName();
}
}

View file

@ -0,0 +1,125 @@
<?php
final class ManiphestTaskUnblockTransaction
extends ManiphestTaskTransactionType {
const TRANSACTIONTYPE = 'unblock';
public function generateOldValue($object) {
return null;
}
public function shouldHideForFeed() {
// Hide "alice created X, a task blocking Y." from feed because it
// will almost always appear adjacent to "alice created Y".
$is_new = $this->getMetadataValue('blocker.new');
if ($is_new) {
return true;
}
}
public function getActionName() {
$old = $this->getOldValue();
$new = $this->getNewValue();
$old_status = head($old);
$new_status = head($new);
$old_closed = ManiphestTaskStatus::isClosedStatus($old_status);
$new_closed = ManiphestTaskStatus::isClosedStatus($new_status);
if ($old_closed && !$new_closed) {
return pht('Block');
} else if (!$old_closed && $new_closed) {
return pht('Unblock');
} else {
return pht('Blocker');
}
}
public function getTitle() {
$old = $this->getOldValue();
$new = $this->getNewValue();
$blocker_phid = key($new);
$old_status = head($old);
$new_status = head($new);
$old_closed = ManiphestTaskStatus::isClosedStatus($old_status);
$new_closed = ManiphestTaskStatus::isClosedStatus($new_status);
$old_name = ManiphestTaskStatus::getTaskStatusName($old_status);
$new_name = ManiphestTaskStatus::getTaskStatusName($new_status);
if ($this->getMetadataValue('blocker.new')) {
return pht(
'%s created subtask %s.',
$this->renderAuthor(),
$this->renderHandle($blocker_phid));
} else if ($old_closed && !$new_closed) {
return pht(
'%s reopened subtask %s as %s.',
$this->renderAuthor(),
$this->renderHandle($blocker_phid),
$this->renderValue($new_name));
} else if (!$old_closed && $new_closed) {
return pht(
'%s closed subtask %s as %s.',
$this->renderAuthor(),
$this->renderHandle($blocker_phid),
$this->renderValue($new_name));
} else {
return pht(
'%s changed the status of subtask %s from %s to %s.',
$this->renderAuthor(),
$this->renderHandle($blocker_phid),
$this->renderValue($old_name),
$this->renderValue($new_name));
}
}
public function getTitleForFeed() {
$old = $this->getOldValue();
$new = $this->getNewValue();
$blocker_phid = key($new);
$old_status = head($old);
$new_status = head($new);
$old_closed = ManiphestTaskStatus::isClosedStatus($old_status);
$new_closed = ManiphestTaskStatus::isClosedStatus($new_status);
$old_name = ManiphestTaskStatus::getTaskStatusName($old_status);
$new_name = ManiphestTaskStatus::getTaskStatusName($new_status);
if ($old_closed && !$new_closed) {
return pht(
'%s reopened %s, a subtask of %s, as %s.',
$this->renderAuthor(),
$this->renderHandle($blocker_phid),
$this->renderObject(),
$this->renderValue($new_name));
} else if (!$old_closed && $new_closed) {
return pht(
'%s closed %s, a subtask of %s, as %s.',
$this->renderAuthor(),
$this->renderHandle($blocker_phid),
$this->renderObject(),
$this->renderValue($new_name));
} else {
return pht(
'%s changed the status of %s, a subtask of %s, '.
'from %s to %s.',
$this->renderAuthor(),
$this->renderHandle($blocker_phid),
$this->renderObject(),
$this->renderValue($old_name),
$this->renderValue($new_name));
}
}
public function getIcon() {
return 'fa-shield';
}
}

View file

@ -390,12 +390,14 @@ final class NuanceGitHubEventItemType
$state = $xobj->getProperty('task.state');
$xactions[] = id(new ManiphestTransaction())
->setTransactionType(ManiphestTransaction::TYPE_TITLE)
->setTransactionType(
ManiphestTaskTitleTransaction::TRANSACTIONTYPE)
->setNewValue($title)
->setDateCreated($created);
$xactions[] = id(new ManiphestTransaction())
->setTransactionType(ManiphestTransaction::TYPE_DESCRIPTION)
->setTransactionType(
ManiphestTaskDescriptionTransaction::TRANSACTIONTYPE)
->setNewValue($description)
->setDateCreated($created);

View file

@ -265,6 +265,7 @@ final class PhabricatorPeopleSearchEngine
if ($user->getIsDisabled()) {
$item->addIcon('fa-ban', pht('Disabled'));
$item->setDisabled(true);
}
if (!$is_approval) {

View file

@ -45,7 +45,7 @@ final class PholioMockCommentController extends PholioController {
foreach ($inline_comments as $inline_comment) {
$xactions[] = id(new PholioTransaction())
->setTransactionType(PholioTransaction::TYPE_INLINE)
->setTransactionType(PholioMockInlineTransaction::TRANSACTIONTYPE)
->attachComment($inline_comment);
}

View file

@ -151,7 +151,7 @@ final class PholioMockEditController extends PholioController {
->setSequence($sequence);
$xactions[] = id(new PholioTransaction())
->setTransactionType(
PholioTransaction::TYPE_IMAGE_REPLACE)
PholioImageReplaceTransaction::TRANSACTIONTYPE)
->setNewValue($replace_image);
$posted_mock_images[] = $replace_image;
} else if (!$existing_image) { // this is an add
@ -162,7 +162,7 @@ final class PholioMockEditController extends PholioController {
->setDescription($description)
->setSequence($sequence);
$xactions[] = id(new PholioTransaction())
->setTransactionType(PholioTransaction::TYPE_IMAGE_FILE)
->setTransactionType(PholioImageFileTransaction::TRANSACTIONTYPE)
->setNewValue(
array('+' => array($add_image)));
$posted_mock_images[] = $add_image;
@ -178,7 +178,7 @@ final class PholioMockEditController extends PholioController {
array($existing_image->getPHID() => $description));
$xactions[] = id(new PholioTransaction())
->setTransactionType(
PholioTransaction::TYPE_IMAGE_SEQUENCE)
PholioImageSequenceTransaction::TRANSACTIONTYPE)
->setNewValue(
array($existing_image->getPHID() => $sequence));
@ -189,7 +189,7 @@ final class PholioMockEditController extends PholioController {
if (!isset($files[$file_phid]) && !isset($replaces[$file_phid])) {
// this is an outright delete
$xactions[] = id(new PholioTransaction())
->setTransactionType(PholioTransaction::TYPE_IMAGE_FILE)
->setTransactionType(PholioImageFileTransaction::TRANSACTIONTYPE)
->setNewValue(
array('-' => array($mock_image)));
}

View file

@ -17,7 +17,8 @@ final class PholioMockEditor extends PhabricatorApplicationTransactionEditor {
$this->newImages = $new_images;
return $this;
}
private function getNewImages() {
public function getNewImages() {
return $this->newImages;
}
@ -29,111 +30,17 @@ final class PholioMockEditor extends PhabricatorApplicationTransactionEditor {
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
$types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
$types[] = PholioTransaction::TYPE_INLINE;
$types[] = PholioTransaction::TYPE_IMAGE_FILE;
$types[] = PholioTransaction::TYPE_IMAGE_REPLACE;
$types[] = PholioTransaction::TYPE_IMAGE_SEQUENCE;
return $types;
}
protected function getCustomTransactionOldValue(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PholioTransaction::TYPE_IMAGE_FILE:
$images = $object->getImages();
return mpull($images, 'getPHID');
case PholioTransaction::TYPE_IMAGE_REPLACE:
$raw = $xaction->getNewValue();
return $raw->getReplacesImagePHID();
case PholioTransaction::TYPE_IMAGE_SEQUENCE:
$sequence = null;
$phid = null;
$image = $this->getImageForXaction($object, $xaction);
if ($image) {
$sequence = $image->getSequence();
$phid = $image->getPHID();
}
return array($phid => $sequence);
}
}
protected function getCustomTransactionNewValue(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PholioTransaction::TYPE_IMAGE_SEQUENCE:
return $xaction->getNewValue();
case PholioTransaction::TYPE_IMAGE_REPLACE:
$raw = $xaction->getNewValue();
return $raw->getPHID();
case PholioTransaction::TYPE_IMAGE_FILE:
$raw_new_value = $xaction->getNewValue();
$new_value = array();
foreach ($raw_new_value as $key => $images) {
$new_value[$key] = mpull($images, 'getPHID');
}
$xaction->setNewValue($new_value);
return $this->getPHIDTransactionNewValue($xaction);
}
}
protected function extractFilePHIDsFromCustomTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
$images = $this->getNewImages();
$images = mpull($images, null, 'getPHID');
switch ($xaction->getTransactionType()) {
case PholioTransaction::TYPE_IMAGE_FILE:
$file_phids = array();
foreach ($xaction->getNewValue() as $image_phid) {
$image = idx($images, $image_phid);
if (!$image) {
continue;
}
$file_phids[] = $image->getFilePHID();
}
return $file_phids;
case PholioTransaction::TYPE_IMAGE_REPLACE:
$image_phid = $xaction->getNewValue();
$image = idx($images, $image_phid);
if ($image) {
return array($image->getFilePHID());
}
break;
}
return parent::extractFilePHIDsFromCustomTransaction($object, $xaction);
}
protected function transactionHasEffect(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PholioTransaction::TYPE_INLINE:
return true;
}
return parent::transactionHasEffect($object, $xaction);
}
protected function shouldApplyInitialEffects(
PhabricatorLiskDAO $object,
array $xactions) {
foreach ($xactions as $xaction) {
switch ($xaction->getTransactionType()) {
case PholioTransaction::TYPE_IMAGE_FILE:
case PholioTransaction::TYPE_IMAGE_REPLACE:
case PholioImageFileTransaction::TRANSACTIONTYPE:
case PholioImageReplaceTransaction::TRANSACTIONTYPE:
return true;
break;
}
@ -148,7 +55,7 @@ final class PholioMockEditor extends PhabricatorApplicationTransactionEditor {
$new_images = array();
foreach ($xactions as $xaction) {
switch ($xaction->getTransactionType()) {
case PholioTransaction::TYPE_IMAGE_FILE:
case PholioImageFileTransaction::TRANSACTIONTYPE:
$new_value = $xaction->getNewValue();
foreach ($new_value as $key => $txn_images) {
if ($key != '+') {
@ -160,7 +67,7 @@ final class PholioMockEditor extends PhabricatorApplicationTransactionEditor {
}
}
break;
case PholioTransaction::TYPE_IMAGE_REPLACE:
case PholioImageReplaceTransaction::TRANSACTIONTYPE:
$image = $xaction->getNewValue();
$image->save();
$new_images[] = $image;
@ -170,67 +77,6 @@ final class PholioMockEditor extends PhabricatorApplicationTransactionEditor {
$this->setNewImages($new_images);
}
private function getImageForXaction(
PholioMock $mock,
PhabricatorApplicationTransaction $xaction) {
$raw_new_value = $xaction->getNewValue();
$image_phid = key($raw_new_value);
$images = $mock->getImages();
foreach ($images as $image) {
if ($image->getPHID() == $image_phid) {
return $image;
}
}
return null;
}
protected function applyCustomInternalTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
return;
}
protected function applyCustomExternalTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PholioTransaction::TYPE_IMAGE_FILE:
$old_map = array_fuse($xaction->getOldValue());
$new_map = array_fuse($xaction->getNewValue());
$obsolete_map = array_diff_key($old_map, $new_map);
$images = $object->getImages();
foreach ($images as $seq => $image) {
if (isset($obsolete_map[$image->getPHID()])) {
$image->setIsObsolete(1);
$image->save();
unset($images[$seq]);
}
}
$object->attachImages($images);
break;
case PholioTransaction::TYPE_IMAGE_REPLACE:
$old = $xaction->getOldValue();
$images = $object->getImages();
foreach ($images as $seq => $image) {
if ($image->getPHID() == $old) {
$image->setIsObsolete(1);
$image->save();
unset($images[$seq]);
}
}
$object->attachImages($images);
break;
case PholioTransaction::TYPE_IMAGE_SEQUENCE:
$image = $this->getImageForXaction($object, $xaction);
$value = (int)head($xaction->getNewValue());
$image->setSequence($value);
$image->save();
break;
}
}
protected function applyFinalEffects(
PhabricatorLiskDAO $object,
array $xactions) {
@ -244,35 +90,6 @@ final class PholioMockEditor extends PhabricatorApplicationTransactionEditor {
return $xactions;
}
protected function mergeTransactions(
PhabricatorApplicationTransaction $u,
PhabricatorApplicationTransaction $v) {
$type = $u->getTransactionType();
switch ($type) {
case PholioTransaction::TYPE_IMAGE_REPLACE:
$u_img = $u->getNewValue();
$v_img = $v->getNewValue();
if ($u_img->getReplacesImagePHID() == $v_img->getReplacesImagePHID()) {
return $v;
}
break;
case PholioTransaction::TYPE_IMAGE_FILE:
return $this->mergePHIDOrEdgeTransactions($u, $v);
case PholioTransaction::TYPE_IMAGE_SEQUENCE:
$raw_new_value_u = $u->getNewValue();
$raw_new_value_v = $v->getNewValue();
$phid_u = key($raw_new_value_u);
$phid_v = key($raw_new_value_v);
if ($phid_u == $phid_v) {
return $v;
}
break;
}
return parent::mergeTransactions($u, $v);
}
protected function shouldSendMail(
PhabricatorLiskDAO $object,
array $xactions) {
@ -316,7 +133,7 @@ final class PholioMockEditor extends PhabricatorApplicationTransactionEditor {
}
$comment = $xaction->getComment();
switch ($xaction->getTransactionType()) {
case PholioTransaction::TYPE_INLINE:
case PholioMockInlineTransaction::TRANSACTIONTYPE:
if ($comment && strlen($comment->getContent())) {
$inline_comments[] = $comment;
}
@ -406,7 +223,7 @@ final class PholioMockEditor extends PhabricatorApplicationTransactionEditor {
// Move inline comments to the end, so the comments precede them.
foreach ($xactions as $xaction) {
$type = $xaction->getTransactionType();
if ($type == PholioTransaction::TYPE_INLINE) {
if ($type == PholioMockInlineTransaction::TRANSACTIONTYPE) {
$tail[] = $xaction;
} else {
$head[] = $xaction;
@ -421,7 +238,7 @@ final class PholioMockEditor extends PhabricatorApplicationTransactionEditor {
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PholioTransaction::TYPE_INLINE:
case PholioMockInlineTransaction::TRANSACTIONTYPE:
return true;
}

View file

@ -2,14 +2,6 @@
final class PholioTransaction extends PhabricatorModularTransaction {
// Edits to images within the mock
const TYPE_IMAGE_FILE = 'image-file';
const TYPE_IMAGE_REPLACE = 'image-replace';
const TYPE_IMAGE_SEQUENCE = 'image-sequence';
// Your witty commentary at the mock : image : x,y level
const TYPE_INLINE = 'inline';
const MAILTAG_STATUS = 'pholio-status';
const MAILTAG_COMMENT = 'pholio-comment';
const MAILTAG_UPDATED = 'pholio-updated';
@ -35,65 +27,10 @@ final class PholioTransaction extends PhabricatorModularTransaction {
return new PholioTransactionView();
}
public function getRequiredHandlePHIDs() {
$phids = parent::getRequiredHandlePHIDs();
$phids[] = $this->getObjectPHID();
$new = $this->getNewValue();
$old = $this->getOldValue();
switch ($this->getTransactionType()) {
case self::TYPE_IMAGE_FILE:
$phids = array_merge($phids, $new, $old);
break;
case self::TYPE_IMAGE_REPLACE:
$phids[] = $new;
$phids[] = $old;
break;
case PholioImageDescriptionTransaction::TRANSACTIONTYPE:
case PholioImageNameTransaction::TRANSACTIONTYPE:
case self::TYPE_IMAGE_SEQUENCE:
$phids[] = key($new);
break;
}
return $phids;
}
public function shouldHide() {
$old = $this->getOldValue();
switch ($this->getTransactionType()) {
// this is boring / silly to surface; changing sequence is NBD
case self::TYPE_IMAGE_SEQUENCE:
return true;
}
return parent::shouldHide();
}
public function getIcon() {
$new = $this->getNewValue();
$old = $this->getOldValue();
switch ($this->getTransactionType()) {
case self::TYPE_INLINE:
return 'fa-comment';
case self::TYPE_IMAGE_SEQUENCE:
return 'fa-pencil';
case self::TYPE_IMAGE_FILE:
case self::TYPE_IMAGE_REPLACE:
return 'fa-picture-o';
}
return parent::getIcon();
}
public function getMailTags() {
$tags = array();
switch ($this->getTransactionType()) {
case self::TYPE_INLINE:
case PholioMockInlineTransaction::TRANSACTIONTYPE:
case PhabricatorTransactions::TYPE_COMMENT:
$tags[] = self::MAILTAG_COMMENT;
break;
@ -104,9 +41,9 @@ final class PholioTransaction extends PhabricatorModularTransaction {
case PholioMockDescriptionTransaction::TRANSACTIONTYPE:
case PholioImageNameTransaction::TRANSACTIONTYPE:
case PholioImageDescriptionTransaction::TRANSACTIONTYPE:
case self::TYPE_IMAGE_SEQUENCE:
case self::TYPE_IMAGE_FILE:
case self::TYPE_IMAGE_REPLACE:
case PholioImageSequenceTransaction::TRANSACTIONTYPE:
case PholioImageFileTransaction::TRANSACTIONTYPE:
case PholioImageReplaceTransaction::TRANSACTIONTYPE:
$tags[] = self::MAILTAG_UPDATED;
break;
default:
@ -116,124 +53,4 @@ final class PholioTransaction extends PhabricatorModularTransaction {
return $tags;
}
public function getTitle() {
$author_phid = $this->getAuthorPHID();
$old = $this->getOldValue();
$new = $this->getNewValue();
$type = $this->getTransactionType();
switch ($type) {
case self::TYPE_INLINE:
$count = 1;
foreach ($this->getTransactionGroup() as $xaction) {
if ($xaction->getTransactionType() == $type) {
$count++;
}
}
return pht(
'%s added %d inline comment(s).',
$this->renderHandleLink($author_phid),
$count);
break;
case self::TYPE_IMAGE_REPLACE:
return pht(
'%s replaced %s with %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($old),
$this->renderHandleLink($new));
break;
case self::TYPE_IMAGE_FILE:
$add = array_diff($new, $old);
$rem = array_diff($old, $new);
if ($add && $rem) {
return pht(
'%s edited image(s), added %d: %s; removed %d: %s.',
$this->renderHandleLink($author_phid),
count($add),
$this->renderHandleList($add),
count($rem),
$this->renderHandleList($rem));
} else if ($add) {
return pht(
'%s added %d image(s): %s.',
$this->renderHandleLink($author_phid),
count($add),
$this->renderHandleList($add));
} else {
return pht(
'%s removed %d image(s): %s.',
$this->renderHandleLink($author_phid),
count($rem),
$this->renderHandleList($rem));
}
break;
case self::TYPE_IMAGE_SEQUENCE:
return pht(
'%s updated an image\'s (%s) sequence.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink(key($new)));
break;
}
return parent::getTitle();
}
public function getTitleForFeed() {
$author_phid = $this->getAuthorPHID();
$object_phid = $this->getObjectPHID();
$old = $this->getOldValue();
$new = $this->getNewValue();
$type = $this->getTransactionType();
switch ($type) {
case self::TYPE_INLINE:
return pht(
'%s added an inline comment to %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
break;
case self::TYPE_IMAGE_REPLACE:
case self::TYPE_IMAGE_FILE:
return pht(
'%s updated images of %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
break;
case self::TYPE_IMAGE_SEQUENCE:
return pht(
'%s updated image sequence of %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
break;
}
return parent::getTitleForFeed();
}
public function getColor() {
$old = $this->getOldValue();
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case self::TYPE_IMAGE_REPLACE:
return PhabricatorTransactions::COLOR_YELLOW;
case self::TYPE_IMAGE_FILE:
$add = array_diff($new, $old);
$rem = array_diff($old, $new);
if ($add && $rem) {
return PhabricatorTransactions::COLOR_YELLOW;
} else if ($add) {
return PhabricatorTransactions::COLOR_GREEN;
} else {
return PhabricatorTransactions::COLOR_RED;
}
}
return parent::getColor();
}
}

View file

@ -30,14 +30,14 @@ final class PholioTransactionView
switch ($u->getTransactionType()) {
case PhabricatorTransactions::TYPE_COMMENT:
case PholioTransaction::TYPE_INLINE:
case PholioMockInlineTransaction::TRANSACTIONTYPE:
break;
default:
return false;
}
switch ($v->getTransactionType()) {
case PholioTransaction::TYPE_INLINE:
case PholioMockInlineTransaction::TRANSACTIONTYPE:
return true;
}
@ -50,7 +50,8 @@ final class PholioTransactionView
$out = array();
$group = $xaction->getTransactionGroup();
if ($xaction->getTransactionType() == PholioTransaction::TYPE_INLINE) {
$type = $xaction->getTransactionType();
if ($type == PholioMockInlineTransaction::TRANSACTIONTYPE) {
array_unshift($group, $xaction);
} else {
$out[] = parent::renderTransactionContent($xaction);
@ -63,7 +64,7 @@ final class PholioTransactionView
$inlines = array();
foreach ($group as $xaction) {
switch ($xaction->getTransactionType()) {
case PholioTransaction::TYPE_INLINE:
case PholioMockInlineTransaction::TRANSACTIONTYPE:
$inlines[] = $xaction;
break;
default:

View file

@ -0,0 +1,120 @@
<?php
final class PholioImageFileTransaction
extends PholioImageTransactionType {
const TRANSACTIONTYPE = 'image-file';
public function generateOldValue($object) {
$images = $object->getImages();
return array_values(mpull($images, 'getPHID'));
}
public function generateNewValue($object, $value) {
$new_value = array();
foreach ($value as $key => $images) {
$new_value[$key] = mpull($images, 'getPHID');
}
$old = array_fuse($this->getOldValue());
return $this->getEditor()->getPHIDList($old, $new_value);
}
public function applyInternalEffects($object, $value) {
$old_map = array_fuse($this->getOldValue());
$new_map = array_fuse($this->getNewValue());
$obsolete_map = array_diff_key($old_map, $new_map);
$images = $object->getImages();
foreach ($images as $seq => $image) {
if (isset($obsolete_map[$image->getPHID()])) {
$image->setIsObsolete(1);
$image->save();
unset($images[$seq]);
}
}
$object->attachImages($images);
}
public function getTitle() {
$old = $this->getOldValue();
$new = $this->getNewValue();
$add = array_diff($new, $old);
$rem = array_diff($old, $new);
if ($add && $rem) {
return pht(
'%s edited image(s), added %d: %s; removed %d: %s.',
$this->renderAuthor(),
count($add),
$this->renderHandleList($add),
count($rem),
$this->renderHandleList($rem));
} else if ($add) {
return pht(
'%s added %d image(s): %s.',
$this->renderAuthor(),
count($add),
$this->renderHandleList($add));
} else {
return pht(
'%s removed %d image(s): %s.',
$this->renderAuthor(),
count($rem),
$this->renderHandleList($rem));
}
}
public function getTitleForFeed() {
$old = $this->getOldValue();
$new = $this->getNewValue();
return pht(
'%s updated images of %s.',
$this->renderAuthor(),
$this->renderObject());
}
public function getIcon() {
return 'fa-picture-o';
}
public function getColor() {
$old = $this->getOldValue();
$new = $this->getNewValue();
$add = array_diff($new, $old);
$rem = array_diff($old, $new);
if ($add && $rem) {
return PhabricatorTransactions::COLOR_YELLOW;
} else if ($add) {
return PhabricatorTransactions::COLOR_GREEN;
} else {
return PhabricatorTransactions::COLOR_RED;
}
}
public function extractFilePHIDs($object, $value) {
$images = $this->getEditor()->getNewImages();
$images = mpull($images, null, 'getPHID');
$file_phids = array();
foreach ($value as $image_phid) {
$image = idx($images, $image_phid);
if (!$image) {
continue;
}
$file_phids[] = $image->getFilePHID();
}
return $file_phids;
}
public function mergeTransactions(
$object,
PhabricatorApplicationTransaction $u,
PhabricatorApplicationTransaction $v) {
return $this->getEditor()->mergePHIDOrEdgeTransactions($u, $v);
}
}

View file

@ -0,0 +1,68 @@
<?php
final class PholioImageReplaceTransaction
extends PholioImageTransactionType {
const TRANSACTIONTYPE = 'image-replace';
public function generateOldValue($object) {
$new_image = $this->getNewValue();
return $new_image->getReplacesImagePHID();
}
public function generateNewValue($object, $value) {
return $value->getPHID();
}
public function applyInternalEffects($object, $value) {
$old = $this->getOldValue();
$images = $object->getImages();
foreach ($images as $seq => $image) {
if ($image->getPHID() == $old) {
$image->setIsObsolete(1);
$image->save();
unset($images[$seq]);
}
}
$object->attachImages($images);
}
public function getTitle() {
return pht(
'%s replaced %s with %s.',
$this->renderAuthor(),
$this->renderOldHandle(),
$this->renderNewHandle());
}
public function getTitleForFeed() {
return pht(
'%s updated images of %s.',
$this->renderAuthor(),
$this->renderObject());
}
public function getIcon() {
return 'fa-picture-o';
}
public function getColor() {
return PhabricatorTransactions::COLOR_YELLOW;
}
public function mergeTransactions(
$object,
PhabricatorApplicationTransaction $u,
PhabricatorApplicationTransaction $v) {
$u_img = $u->getNewValue();
$v_img = $v->getNewValue();
if ($u_img->getReplacesImagePHID() == $v_img->getReplacesImagePHID()) {
return $v;
}
}
public function extractFilePHIDs($object, $value) {
return array($value);
}
}

View file

@ -0,0 +1,60 @@
<?php
final class PholioImageSequenceTransaction
extends PholioImageTransactionType {
const TRANSACTIONTYPE = 'image-sequence';
public function generateOldValue($object) {
$sequence = null;
$phid = null;
$image = $this->getImageForXaction($object);
if ($image) {
$sequence = $image->getSequence();
$phid = $image->getPHID();
}
return array($phid => $sequence);
}
public function applyInternalEffects($object, $value) {
$image = $this->getImageForXaction($object);
$value = (int)head($this->getNewValue());
$image->setSequence($value);
$image->save();
}
public function getTitle() {
$new = $this->getNewValue();
return pht(
'%s updated an image\'s (%s) sequence.',
$this->renderAuthor(),
$this->renderHandleLink(key($new)));
}
public function getTitleForFeed() {
return pht(
'%s updated image sequence of %s.',
$this->renderAuthor(),
$this->renderObject());
}
public function shouldHide() {
// this is boring / silly to surface; changing sequence is NBD
return true;
}
public function mergeTransactions(
$object,
PhabricatorApplicationTransaction $u,
PhabricatorApplicationTransaction $v) {
$raw_new_value_u = $u->getNewValue();
$raw_new_value_v = $v->getNewValue();
$phid_u = key($raw_new_value_u);
$phid_v = key($raw_new_value_v);
if ($phid_u == $phid_v) {
return $v;
}
}
}

View file

@ -44,4 +44,14 @@ final class PholioMockDescriptionTransaction
->setNewText($this->getNewValue());
}
public function newRemarkupChanges() {
$changes = array();
$changes[] = $this->newRemarkupChange()
->setOldValue($this->getOldValue())
->setNewValue($this->getNewValue());
return $changes;
}
}

View file

@ -0,0 +1,33 @@
<?php
final class PholioMockInlineTransaction
extends PholioMockTransactionType {
const TRANSACTIONTYPE = 'inline';
public function generateOldValue($object) {
return null;
}
public function getTitle() {
return pht(
'%s added inline comment(s).',
$this->renderAuthor());
}
public function getTitleForFeed() {
return pht(
'%s added an inline comment to %s.',
$this->renderAuthor(),
$this->renderObject());
}
public function getIcon() {
return 'fa-comment';
}
public function getTransactionHasEffect($object, $old, $new) {
return true;
}
}

View file

@ -43,8 +43,8 @@ final class PhortuneSubscriptionViewController extends PhortuneController {
$curtain->addAction(
id(new PhabricatorActionView())
->setIcon('fa-pencil')
->setName(pht('Edit Subscription'))
->setIcon('fa-credit-card')
->setName(pht('Manage Autopay'))
->setHref($edit_uri)
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit));

View file

@ -47,7 +47,7 @@ final class PhrictionCreateConduitAPIMethod extends PhrictionConduitAPIMethod {
$xactions = array();
$xactions[] = id(new PhrictionTransaction())
->setTransactionType(PhrictionTransaction::TYPE_TITLE)
->setTransactionType(PhrictionDocumentTitleTransaction::TRANSACTIONTYPE)
->setNewValue($request->getValue('title'));
$xactions[] = id(new PhrictionTransaction())
->setTransactionType(PhrictionTransaction::TYPE_CONTENT)

View file

@ -42,7 +42,7 @@ final class PhrictionEditConduitAPIMethod extends PhrictionConduitAPIMethod {
$xactions = array();
$xactions[] = id(new PhrictionTransaction())
->setTransactionType(PhrictionTransaction::TYPE_TITLE)
->setTransactionType(PhrictionDocumentTitleTransaction::TRANSACTIONTYPE)
->setNewValue($request->getValue('title'));
$xactions[] = id(new PhrictionTransaction())
->setTransactionType(PhrictionTransaction::TYPE_CONTENT)

View file

@ -133,7 +133,7 @@ final class PhrictionEditController
$xactions = array();
$xactions[] = id(new PhrictionTransaction())
->setTransactionType(PhrictionTransaction::TYPE_TITLE)
->setTransactionType(PhrictionDocumentTitleTransaction::TRANSACTIONTYPE)
->setNewValue($title);
$xactions[] = id(new PhrictionTransaction())
->setTransactionType(PhrictionTransaction::TYPE_CONTENT)
@ -174,7 +174,8 @@ final class PhrictionEditController
} catch (PhabricatorApplicationTransactionValidationException $ex) {
$validation_exception = $ex;
$e_title = nonempty(
$ex->getShortMessage(PhrictionTransaction::TYPE_TITLE),
$ex->getShortMessage(
PhrictionDocumentTitleTransaction::TRANSACTIONTYPE),
true);
$e_content = nonempty(
$ex->getShortMessage(PhrictionTransaction::TYPE_CONTENT),

View file

@ -64,7 +64,8 @@ final class PhrictionMoveController extends PhrictionController {
$xactions = array();
$xactions[] = id(new PhrictionTransaction())
->setTransactionType(PhrictionTransaction::TYPE_MOVE_TO)
->setTransactionType(
PhrictionDocumentMoveToTransaction::TRANSACTIONTYPE)
->setNewValue($document);
$target_document = id(new PhrictionDocumentQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
@ -88,7 +89,8 @@ final class PhrictionMoveController extends PhrictionController {
return id(new AphrontRedirectResponse())->setURI($redir_uri);
} catch (PhabricatorApplicationTransactionValidationException $ex) {
$validation_exception = $ex;
$e_slug = $ex->getShortMessage(PhrictionTransaction::TYPE_MOVE_TO);
$e_slug = $ex->getShortMessage(
PhrictionDocumentMoveToTransaction::TRANSACTIONTYPE);
}
}

View file

@ -29,7 +29,7 @@ final class PhrictionTransactionEditor
return $this;
}
private function getOldContent() {
public function getOldContent() {
return $this->oldContent;
}
@ -38,7 +38,7 @@ final class PhrictionTransactionEditor
return $this;
}
private function getNewContent() {
public function getNewContent() {
return $this->newContent;
}
@ -69,6 +69,11 @@ final class PhrictionTransactionEditor
return $this->processContentVersionError;
}
public function setMoveAwayDocument(PhrictionDocument $document) {
$this->moveAwayDocument = $document;
return $this;
}
public function getEditorApplicationClass() {
return 'PhabricatorPhrictionApplication';
}
@ -80,10 +85,8 @@ final class PhrictionTransactionEditor
public function getTransactionTypes() {
$types = parent::getTransactionTypes();
$types[] = PhrictionTransaction::TYPE_TITLE;
$types[] = PhrictionTransaction::TYPE_CONTENT;
$types[] = PhrictionTransaction::TYPE_DELETE;
$types[] = PhrictionTransaction::TYPE_MOVE_TO;
$types[] = PhrictionTransaction::TYPE_MOVE_AWAY;
$types[] = PhabricatorTransactions::TYPE_EDGE;
@ -99,18 +102,12 @@ final class PhrictionTransactionEditor
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhrictionTransaction::TYPE_TITLE:
if ($this->getIsNewObject()) {
return null;
}
return $this->getOldContent()->getTitle();
case PhrictionTransaction::TYPE_CONTENT:
if ($this->getIsNewObject()) {
return null;
}
return $this->getOldContent()->getContent();
case PhrictionTransaction::TYPE_DELETE:
case PhrictionTransaction::TYPE_MOVE_TO:
case PhrictionTransaction::TYPE_MOVE_AWAY:
return null;
}
@ -121,21 +118,9 @@ final class PhrictionTransactionEditor
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhrictionTransaction::TYPE_TITLE:
case PhrictionTransaction::TYPE_CONTENT:
case PhrictionTransaction::TYPE_DELETE:
return $xaction->getNewValue();
case PhrictionTransaction::TYPE_MOVE_TO:
$document = $xaction->getNewValue();
// grab the real object now for the sub-editor to come
$this->moveAwayDocument = $document;
$dict = array(
'id' => $document->getID(),
'phid' => $document->getPHID(),
'content' => $document->getContent()->getContent(),
'title' => $document->getContent()->getTitle(),
);
return $dict;
case PhrictionTransaction::TYPE_MOVE_AWAY:
$document = $xaction->getNewValue();
$dict = array(
@ -154,10 +139,10 @@ final class PhrictionTransactionEditor
foreach ($xactions as $xaction) {
switch ($xaction->getTransactionType()) {
case PhrictionTransaction::TYPE_TITLE:
case PhrictionDocumentTitleTransaction::TRANSACTIONTYPE:
case PhrictionTransaction::TYPE_CONTENT:
case PhrictionTransaction::TYPE_DELETE:
case PhrictionTransaction::TYPE_MOVE_TO:
case PhrictionDocumentMoveToTransaction::TRANSACTIONTYPE:
case PhrictionTransaction::TYPE_MOVE_AWAY:
return true;
}
@ -178,9 +163,7 @@ final class PhrictionTransactionEditor
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhrictionTransaction::TYPE_TITLE:
case PhrictionTransaction::TYPE_CONTENT:
case PhrictionTransaction::TYPE_MOVE_TO:
$object->setStatus(PhrictionDocumentStatus::STATUS_EXISTS);
return;
case PhrictionTransaction::TYPE_MOVE_AWAY:
@ -210,7 +193,7 @@ final class PhrictionTransactionEditor
->setMetadataValue('contentDelete', true);
}
break;
case PhrictionTransaction::TYPE_MOVE_TO:
case PhrictionDocumentMoveToTransaction::TRANSACTIONTYPE:
$document = $xaction->getNewValue();
$xactions[] = id(new PhrictionTransaction())
->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY)
@ -232,9 +215,6 @@ final class PhrictionTransactionEditor
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhrictionTransaction::TYPE_TITLE:
$this->getNewContent()->setTitle($xaction->getNewValue());
break;
case PhrictionTransaction::TYPE_CONTENT:
$this->getNewContent()->setContent($xaction->getNewValue());
break;
@ -243,14 +223,6 @@ final class PhrictionTransactionEditor
$this->getNewContent()->setChangeType(
PhrictionChangeType::CHANGE_DELETE);
break;
case PhrictionTransaction::TYPE_MOVE_TO:
$dict = $xaction->getNewValue();
$this->getNewContent()->setContent($dict['content']);
$this->getNewContent()->setTitle($dict['title']);
$this->getNewContent()->setChangeType(
PhrictionChangeType::CHANGE_MOVE_HERE);
$this->getNewContent()->setChangeRef($dict['id']);
break;
case PhrictionTransaction::TYPE_MOVE_AWAY:
$dict = $xaction->getNewValue();
$this->getNewContent()->setContent('');
@ -270,11 +242,11 @@ final class PhrictionTransactionEditor
$save_content = false;
foreach ($xactions as $xaction) {
switch ($xaction->getTransactionType()) {
case PhrictionTransaction::TYPE_TITLE:
case PhrictionDocumentTitleTransaction::TRANSACTIONTYPE:
case PhrictionDocumentMoveToTransaction::TRANSACTIONTYPE:
case PhrictionTransaction::TYPE_CONTENT:
case PhrictionTransaction::TYPE_DELETE:
case PhrictionTransaction::TYPE_MOVE_AWAY:
case PhrictionTransaction::TYPE_MOVE_TO:
$save_content = true;
break;
default:
@ -312,7 +284,8 @@ final class PhrictionTransactionEditor
$slug);
$stub_xactions = array();
$stub_xactions[] = id(new PhrictionTransaction())
->setTransactionType(PhrictionTransaction::TYPE_TITLE)
->setTransactionType(
PhrictionDocumentTitleTransaction::TRANSACTIONTYPE)
->setNewValue(PhabricatorSlug::getDefaultTitle($slug))
->setMetadataValue('stub:create:phid', $object->getPHID());
$stub_xactions[] = id(new PhrictionTransaction())
@ -458,7 +431,7 @@ final class PhrictionTransactionEditor
foreach ($xactions as $xaction) {
switch ($xaction->getTransactionType()) {
case PhrictionTransaction::TYPE_MOVE_TO:
case PhrictionDocumentMoveToTransaction::TRANSACTIONTYPE:
$dict = $xaction->getNewValue();
$phids[] = $dict['phid'];
break;
@ -477,30 +450,6 @@ final class PhrictionTransactionEditor
foreach ($xactions as $xaction) {
switch ($type) {
case PhrictionTransaction::TYPE_TITLE:
$title = $object->getContent()->getTitle();
$missing = $this->validateIsEmptyTextField(
$title,
$xactions);
if ($missing) {
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Required'),
pht('Document title is required.'),
nonempty(last($xactions), null));
$error->setIsMissingFieldError(true);
$errors[] = $error;
} else if ($this->getProcessContentVersionError()) {
$error = $this->validateContentVersion($object, $type, $xaction);
if ($error) {
$this->setProcessContentVersionError(false);
$errors[] = $error;
}
}
break;
case PhrictionTransaction::TYPE_CONTENT:
if ($xaction->getMetadataValue('stub:create:phid')) {
continue;
@ -544,31 +493,8 @@ final class PhrictionTransactionEditor
break;
case PhrictionTransaction::TYPE_MOVE_TO:
case PhrictionDocumentMoveToTransaction::TRANSACTIONTYPE:
$source_document = $xaction->getNewValue();
switch ($source_document->getStatus()) {
case PhrictionDocumentStatus::STATUS_DELETED:
$e_text = pht('A deleted document can not be moved.');
break;
case PhrictionDocumentStatus::STATUS_MOVED:
$e_text = pht('A moved document can not be moved again.');
break;
case PhrictionDocumentStatus::STATUS_STUB:
$e_text = pht('A stub document can not be moved.');
break;
default:
$e_text = null;
break;
}
if ($e_text) {
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Can not move document.'),
$e_text,
$xaction);
$errors[] = $error;
}
$ancestry_errors = $this->validateAncestry(
$object,
@ -645,7 +571,7 @@ final class PhrictionTransactionEditor
return $errors;
}
private function validateAncestry(
public function validateAncestry(
PhabricatorLiskDAO $object,
$type,
PhabricatorApplicationTransaction $xaction,

View file

@ -1,12 +1,10 @@
<?php
final class PhrictionTransaction
extends PhabricatorApplicationTransaction {
extends PhabricatorModularTransaction {
const TYPE_TITLE = 'title';
const TYPE_CONTENT = 'content';
const TYPE_DELETE = 'delete';
const TYPE_MOVE_TO = 'move-to';
const TYPE_MOVE_AWAY = 'move-away';
const MAILTAG_TITLE = 'phriction-title';
@ -27,22 +25,25 @@ final class PhrictionTransaction
return new PhrictionTransactionComment();
}
public function getBaseTransactionClass() {
return 'PhrictionDocumentTransactionType';
}
public function getRequiredHandlePHIDs() {
$phids = parent::getRequiredHandlePHIDs();
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case self::TYPE_MOVE_TO:
case PhrictionDocumentMoveToTransaction::TRANSACTIONTYPE:
case self::TYPE_MOVE_AWAY:
$phids[] = $new['phid'];
break;
case self::TYPE_TITLE:
case PhrictionDocumentTitleTransaction::TRANSACTIONTYPE:
if ($this->getMetadataValue('stub:create:phid')) {
$phids[] = $this->getMetadataValue('stub:create:phid');
}
break;
}
return $phids;
}
@ -74,10 +75,10 @@ final class PhrictionTransaction
public function shouldHideForMail(array $xactions) {
switch ($this->getTransactionType()) {
case self::TYPE_MOVE_TO:
case PhrictionDocumentMoveToTransaction::TRANSACTIONTYPE:
case self::TYPE_MOVE_AWAY:
return true;
case self::TYPE_TITLE:
case PhrictionDocumentTitleTransaction::TRANSACTIONTYPE:
return $this->getMetadataValue('stub:create:phid', false);
}
return parent::shouldHideForMail($xactions);
@ -85,10 +86,10 @@ final class PhrictionTransaction
public function shouldHideForFeed() {
switch ($this->getTransactionType()) {
case self::TYPE_MOVE_TO:
case PhrictionDocumentMoveToTransaction::TRANSACTIONTYPE:
case self::TYPE_MOVE_AWAY:
return true;
case self::TYPE_TITLE:
case PhrictionDocumentTitleTransaction::TRANSACTIONTYPE:
return $this->getMetadataValue('stub:create:phid', false);
}
return parent::shouldHideForFeed();
@ -96,13 +97,10 @@ final class PhrictionTransaction
public function getActionStrength() {
switch ($this->getTransactionType()) {
case self::TYPE_TITLE:
return 1.4;
case self::TYPE_CONTENT:
return 1.3;
case self::TYPE_DELETE:
return 1.5;
case self::TYPE_MOVE_TO:
case self::TYPE_MOVE_AWAY:
return 1.0;
}
@ -115,29 +113,12 @@ final class PhrictionTransaction
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case self::TYPE_TITLE:
if ($old === null) {
if ($this->getMetadataValue('stub:create:phid')) {
return pht('Stubbed');
} else {
return pht('Created');
}
}
return pht('Retitled');
case self::TYPE_CONTENT:
return pht('Edited');
case self::TYPE_DELETE:
return pht('Deleted');
case self::TYPE_MOVE_TO:
return pht('Moved');
case self::TYPE_MOVE_AWAY:
return pht('Moved Away');
}
return parent::getActionName();
@ -148,12 +129,10 @@ final class PhrictionTransaction
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case self::TYPE_TITLE:
case self::TYPE_CONTENT:
return 'fa-pencil';
case self::TYPE_DELETE:
return 'fa-times';
case self::TYPE_MOVE_TO:
case self::TYPE_MOVE_AWAY:
return 'fa-arrows';
}
@ -169,26 +148,6 @@ final class PhrictionTransaction
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case self::TYPE_TITLE:
if ($old === null) {
if ($this->getMetadataValue('stub:create:phid')) {
return pht(
'%s stubbed out this document when creating %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink(
$this->getMetadataValue('stub:create:phid')));
} else {
return pht(
'%s created this document.',
$this->renderHandleLink($author_phid));
}
}
return pht(
'%s changed the title from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$old,
$new);
case self::TYPE_CONTENT:
return pht(
'%s edited the document content.',
@ -199,12 +158,6 @@ final class PhrictionTransaction
'%s deleted this document.',
$this->renderHandleLink($author_phid));
case self::TYPE_MOVE_TO:
return pht(
'%s moved this document from %s',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($new['phid']));
case self::TYPE_MOVE_AWAY:
return pht(
'%s moved this document to %s',
@ -224,20 +177,6 @@ final class PhrictionTransaction
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case self::TYPE_TITLE:
if ($old === null) {
return pht(
'%s created %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
}
return pht(
'%s renamed %s from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid),
$old,
$new);
case self::TYPE_CONTENT:
return pht(
@ -273,7 +212,7 @@ final class PhrictionTransaction
public function getMailTags() {
$tags = array();
switch ($this->getTransactionType()) {
case self::TYPE_TITLE:
case PhrictionDocumentTitleTransaction::TRANSACTIONTYPE:
$tags[] = self::MAILTAG_TITLE;
break;
case self::TYPE_CONTENT:

View file

@ -0,0 +1,105 @@
<?php
final class PhrictionDocumentMoveToTransaction
extends PhrictionDocumentTransactionType {
const TRANSACTIONTYPE = 'move-to';
public function generateOldValue($object) {
return null;
}
public function generateNewValue($object, $value) {
$document = $value;
$dict = array(
'id' => $document->getID(),
'phid' => $document->getPHID(),
'content' => $document->getContent()->getContent(),
'title' => $document->getContent()->getTitle(),
);
$editor = $this->getEditor();
$editor->setMoveAwayDocument($document);
return $dict;
}
public function applyInternalEffects($object, $value) {
$object->setStatus(PhrictionDocumentStatus::STATUS_EXISTS);
}
public function applyExternalEffects($object, $value) {
$dict = $value;
$this->getEditor()->getNewContent()->setContent($dict['content']);
$this->getEditor()->getNewContent()->setTitle($dict['title']);
$this->getEditor()->getNewContent()->setChangeType(
PhrictionChangeType::CHANGE_MOVE_HERE);
$this->getEditor()->getNewContent()->setChangeRef($dict['id']);
}
public function getActionStrength() {
return 1.0;
}
public function getActionName() {
return pht('Moved');
}
public function getTitle() {
$old = $this->getOldValue();
$new = $this->getNewValue();
return pht(
'%s moved this document from %s',
$this->renderAuthor(),
$this->renderHandle($new['phid']));
}
public function getTitleForFeed() {
$old = $this->getOldValue();
$new = $this->getNewValue();
return pht(
'%s moved %s from %s',
$this->renderAuthor(),
$this->renderObject(),
$this->renderHandle($new['phid']));
}
public function validateTransactions($object, array $xactions) {
$errors = array();
$e_text = null;
foreach ($xactions as $xaction) {
$source_document = $xaction->getNewValue();
switch ($source_document->getStatus()) {
case PhrictionDocumentStatus::STATUS_DELETED:
$e_text = pht('A deleted document can not be moved.');
break;
case PhrictionDocumentStatus::STATUS_MOVED:
$e_text = pht('A moved document can not be moved again.');
break;
case PhrictionDocumentStatus::STATUS_STUB:
$e_text = pht('A stub document can not be moved.');
break;
default:
$e_text = null;
break;
}
if ($e_text !== null) {
$errors[] = $this->newInvalidError($e_text);
}
}
// TODO: Move Ancestry validation here once all types are converted.
return $errors;
}
public function getIcon() {
return 'fa-arrows';
}
}

View file

@ -0,0 +1,97 @@
<?php
final class PhrictionDocumentTitleTransaction
extends PhrictionDocumentTransactionType {
const TRANSACTIONTYPE = 'title';
public function generateOldValue($object) {
if ($this->isNewObject()) {
return null;
}
return $this->getEditor()->getOldContent()->getTitle();
}
public function applyInternalEffects($object, $value) {
$object->setStatus(PhrictionDocumentStatus::STATUS_EXISTS);
}
public function applyExternalEffects($object, $value) {
$this->getEditor()->getNewContent()->setTitle($value);
}
public function getActionStrength() {
return 1.4;
}
public function getActionName() {
$old = $this->getOldValue();
$new = $this->getNewValue();
if ($old === null) {
if ($this->getMetadataValue('stub:create:phid')) {
return pht('Stubbed');
} else {
return pht('Created');
}
}
return pht('Retitled');
}
public function getTitle() {
$old = $this->getOldValue();
$new = $this->getNewValue();
if ($old === null) {
if ($this->getMetadataValue('stub:create:phid')) {
return pht(
'%s stubbed out this document when creating %s.',
$this->renderAuthor(),
$this->renderHandleLink(
$this->getMetadataValue('stub:create:phid')));
} else {
return pht(
'%s created this document.',
$this->renderAuthor());
}
}
return pht(
'%s changed the title from %s to %s.',
$this->renderAuthor(),
$this->renderOldValue(),
$this->renderNewValue());
}
public function getTitleForFeed() {
$old = $this->getOldValue();
$new = $this->getNewValue();
if ($old === null) {
return pht(
'%s created %s.',
$this->renderAuthor(),
$this->renderObject());
}
return pht(
'%s renamed %s from %s to %s.',
$this->renderAuthor(),
$this->renderObject(),
$this->renderOldValue(),
$this->renderNewValue());
}
public function validateTransactions($object, array $xactions) {
$errors = array();
$title = $object->getContent()->getTitle();
if ($this->isEmptyTextTransaction($title, $xactions)) {
$errors[] = $this->newRequiredError(
pht('Documents must have a title.'));
}
return $errors;
}
}

View file

@ -0,0 +1,4 @@
<?php
abstract class PhrictionDocumentTransactionType
extends PhabricatorModularTransactionType {}

View file

@ -356,13 +356,13 @@ final class PhabricatorProjectCoreTestCase extends PhabricatorTestCase {
$xactions = array();
$xactions[] = id(new PhabricatorProjectTransaction())
->setTransactionType(PhabricatorProjectTransaction::TYPE_NAME)
->setTransactionType(PhabricatorProjectNameTransaction::TRANSACTIONTYPE)
->setNewValue($name);
$this->applyTransactions($project, $user, $xactions);
$xactions = array();
$xactions[] = id(new PhabricatorProjectTransaction())
->setTransactionType(PhabricatorProjectTransaction::TYPE_SLUGS)
->setTransactionType(PhabricatorProjectSlugsTransaction::TRANSACTIONTYPE)
->setNewValue(array($name));
$this->applyTransactions($project, $user, $xactions);
@ -382,11 +382,11 @@ final class PhabricatorProjectCoreTestCase extends PhabricatorTestCase {
$xactions = array();
$xactions[] = id(new PhabricatorProjectTransaction())
->setTransactionType(PhabricatorProjectTransaction::TYPE_NAME)
->setTransactionType(PhabricatorProjectNameTransaction::TRANSACTIONTYPE)
->setNewValue($name2);
$xactions[] = id(new PhabricatorProjectTransaction())
->setTransactionType(PhabricatorProjectTransaction::TYPE_SLUGS)
->setTransactionType(PhabricatorProjectSlugsTransaction::TRANSACTIONTYPE)
->setNewValue(array($name2));
$this->applyTransactions($project, $user, $xactions);
@ -416,7 +416,7 @@ final class PhabricatorProjectCoreTestCase extends PhabricatorTestCase {
$xactions = array();
$xactions[] = id(new PhabricatorProjectTransaction())
->setTransactionType(PhabricatorProjectTransaction::TYPE_SLUGS)
->setTransactionType(PhabricatorProjectSlugsTransaction::TRANSACTIONTYPE)
->setNewValue(array($input, $input));
$this->applyTransactions($project, $user, $xactions);
@ -448,7 +448,7 @@ final class PhabricatorProjectCoreTestCase extends PhabricatorTestCase {
$xactions = array();
$xactions[] = id(new PhabricatorProjectTransaction())
->setTransactionType(PhabricatorProjectTransaction::TYPE_SLUGS)
->setTransactionType(PhabricatorProjectSlugsTransaction::TRANSACTIONTYPE)
->setNewValue(array($input));
$this->applyTransactions($project, $user, $xactions);
@ -474,7 +474,7 @@ final class PhabricatorProjectCoreTestCase extends PhabricatorTestCase {
$xactions = array();
$xactions[] = id(new PhabricatorProjectTransaction())
->setTransactionType(PhabricatorProjectTransaction::TYPE_SLUGS)
->setTransactionType(PhabricatorProjectSlugsTransaction::TRANSACTIONTYPE)
->setNewValue(array($input));
$caught = null;
@ -503,7 +503,7 @@ final class PhabricatorProjectCoreTestCase extends PhabricatorTestCase {
$xactions = array();
$xactions[] = id(new PhabricatorProjectTransaction())
->setTransactionType(PhabricatorProjectTransaction::TYPE_NAME)
->setTransactionType(PhabricatorProjectNameTransaction::TRANSACTIONTYPE)
->setNewValue($name);
$xactions[] = id(new PhabricatorProjectTransaction())
@ -601,11 +601,11 @@ final class PhabricatorProjectCoreTestCase extends PhabricatorTestCase {
$xactions = array();
$xactions[] = id(new PhabricatorProjectTransaction())
->setTransactionType(PhabricatorProjectTransaction::TYPE_NAME)
->setTransactionType(PhabricatorProjectNameTransaction::TRANSACTIONTYPE)
->setNewValue($name);
$xactions[] = id(new PhabricatorProjectTransaction())
->setTransactionType(PhabricatorProjectTransaction::TYPE_SLUGS)
->setTransactionType(PhabricatorProjectSlugsTransaction::TRANSACTIONTYPE)
->setNewValue(array($slug));
$this->applyTransactions($project, $user, $xactions);
@ -1290,7 +1290,8 @@ final class PhabricatorProjectCoreTestCase extends PhabricatorTestCase {
$new_name = $proj->getName().' '.mt_rand();
$xaction = new PhabricatorProjectTransaction();
$xaction->setTransactionType(PhabricatorProjectTransaction::TYPE_NAME);
$xaction->setTransactionType(
PhabricatorProjectNameTransaction::TRANSACTIONTYPE);
$xaction->setNewValue($new_name);
$this->applyTransactions($proj, $user, array($xaction));
@ -1337,7 +1338,7 @@ final class PhabricatorProjectCoreTestCase extends PhabricatorTestCase {
$xactions = array();
$xactions[] = id(new ManiphestTransaction())
->setTransactionType(ManiphestTransaction::TYPE_TITLE)
->setTransactionType(ManiphestTaskTitleTransaction::TRANSACTIONTYPE)
->setNewValue($name);
if ($projects) {
@ -1440,7 +1441,7 @@ final class PhabricatorProjectCoreTestCase extends PhabricatorTestCase {
$xactions = array();
$xactions[] = id(new PhabricatorProjectTransaction())
->setTransactionType(PhabricatorProjectTransaction::TYPE_NAME)
->setTransactionType(PhabricatorProjectNameTransaction::TRANSACTIONTYPE)
->setNewValue($name);
if ($parent) {

View file

@ -42,7 +42,7 @@ final class ProjectCreateConduitAPIMethod extends ProjectConduitAPIMethod {
$user);
$project = PhabricatorProject::initializeNewProject($user);
$type_name = PhabricatorProjectTransaction::TYPE_NAME;
$type_name = PhabricatorProjectNameTransaction::TRANSACTIONTYPE;
$members = $request->getValue('members');
$xactions = array();
@ -52,19 +52,22 @@ final class ProjectCreateConduitAPIMethod extends ProjectConduitAPIMethod {
if ($request->getValue('icon')) {
$xactions[] = id(new PhabricatorProjectTransaction())
->setTransactionType(PhabricatorProjectTransaction::TYPE_ICON)
->setTransactionType(
PhabricatorProjectIconTransaction::TRANSACTIONTYPE)
->setNewValue($request->getValue('icon'));
}
if ($request->getValue('color')) {
$xactions[] = id(new PhabricatorProjectTransaction())
->setTransactionType(PhabricatorProjectTransaction::TYPE_COLOR)
->setTransactionType(
PhabricatorProjectColorTransaction::TRANSACTIONTYPE)
->setNewValue($request->getValue('color'));
}
if ($request->getValue('tags')) {
$xactions[] = id(new PhabricatorProjectTransaction())
->setTransactionType(PhabricatorProjectTransaction::TYPE_SLUGS)
->setTransactionType(
PhabricatorProjectSlugsTransaction::TRANSACTIONTYPE)
->setNewValue($request->getValue('tags'));
}

View file

@ -32,7 +32,8 @@ final class PhabricatorProjectArchiveController
$xactions = array();
$xactions[] = id(new PhabricatorProjectTransaction())
->setTransactionType(PhabricatorProjectTransaction::TYPE_STATUS)
->setTransactionType(
PhabricatorProjectStatusTransaction::TRANSACTIONTYPE)
->setNewValue($new_status);
id(new PhabricatorProjectTransactionEditor())

View file

@ -31,6 +31,7 @@ final class PhabricatorProjectBoardManageController
$board_id = $board->getID();
$header = $this->buildHeaderView($board);
$curtain = $this->buildCurtainView($board);
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Workboard'), "/project/board/{$board_id}/");
@ -40,9 +41,14 @@ final class PhabricatorProjectBoardManageController
$nav = $this->getProfileMenu();
$columns_list = $this->buildColumnsList($board, $columns);
require_celerity_resource('project-view-css');
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setFooter($columns_list);
->addClass('project-view-home')
->addClass('project-view-people-home')
->setCurtain($curtain)
->setMainColumn($columns_list);
$title = array(
pht('Manage Workboard'),
@ -59,30 +65,35 @@ final class PhabricatorProjectBoardManageController
private function buildHeaderView(PhabricatorProject $board) {
$viewer = $this->getViewer();
$header = id(new PHUIHeaderView())
->setHeader(pht('Workboard: %s', $board->getDisplayName()))
->setUser($viewer);
return $header;
}
private function buildCurtainView(PhabricatorProject $board) {
$viewer = $this->getViewer();
$id = $board->getID();
$curtain = $this->newCurtainView();
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$board,
PhabricatorPolicyCapability::CAN_EDIT);
$id = $board->getID();
$disable_uri = $this->getApplicationURI("board/{$id}/disable/");
$button = id(new PHUIButtonView())
->setTag('a')
->setIcon('fa-ban')
->setText(pht('Disable Board'))
->setHref($disable_uri)
->setDisabled(!$can_edit)
->setWorkflow(true);
$curtain->addAction(
id(new PhabricatorActionView())
->setIcon('fa-ban')
->setName(pht('Disable Workboard'))
->setHref($disable_uri)
->setDisabled(!$can_edit)
->setWorkflow(true));
$header = id(new PHUIHeaderView())
->setHeader(pht('Workboard: %s', $board->getDisplayName()))
->setUser($viewer)
->setPolicyObject($board)
->setProfileHeader(true)
->addActionLink($button);
return $header;
return $curtain;
}
private function buildColumnsList(
@ -123,6 +134,7 @@ final class PhabricatorProjectBoardManageController
return id(new PHUIObjectBoxView())
->setHeaderText(pht('Columns'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setObjectList($view);
}

View file

@ -94,7 +94,8 @@ final class PhabricatorProjectBoardReorderController
$list = id(new PHUIObjectItemListView())
->setUser($viewer)
->setID($list_id)
->setFlush(true);
->setFlush(true)
->setDrag(true);
foreach ($columns as $column) {
// Don't allow milestone columns to be reordered.
@ -134,14 +135,9 @@ final class PhabricatorProjectBoardReorderController
'reorderURI' => $reorder_uri,
));
$note = id(new PHUIInfoView())
->appendChild(pht('Drag and drop columns to reorder them.'))
->setSeverity(PHUIInfoView::SEVERITY_NOTICE);
return $this->newDialog()
->setTitle(pht('Reorder Columns'))
->setWidth(AphrontDialogView::WIDTH_FORM)
->appendChild($note)
->appendChild($list)
->addSubmitButton(pht('Done'));
}

View file

@ -879,12 +879,6 @@ final class PhabricatorProjectBoardViewController
->setWorkflow(true);
}
$details_uri = 'board/'.$this->id.'/column/'.$column->getID().'/';
$column_items[] = id(new PhabricatorActionView())
->setName(pht('Column History'))
->setIcon('fa-columns')
->setHref($this->getApplicationURI($details_uri));
$column_menu = id(new PhabricatorActionListView())
->setUser($viewer);
foreach ($column_items as $item) {

View file

@ -44,36 +44,38 @@ final class PhabricatorProjectColumnDetailController
$title = $column->getDisplayName();
$header = $this->buildHeaderView($column);
$actions = $this->buildActionView($column);
$properties = $this->buildPropertyView($column, $actions);
$properties = $this->buildPropertyView($column);
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Workboard'), "/project/board/{$project_id}/");
$crumbs->addTextCrumb(pht('Column: %s', $title));
$box = id(new PHUIObjectBoxView())
->setHeader($header)
->addPropertyList($properties);
$crumbs->setBorder(true);
$nav = $this->getProfileMenu();
require_celerity_resource('project-view-css');
$view = id(new PHUITwoColumnView())
->setHeader($header)
->addClass('project-view-home')
->addClass('project-view-people-home')
->setMainColumn(array(
$properties,
$timeline,
));
return $this->newPage()
->setTitle($title)
->setNavigation($nav)
->setCrumbs($crumbs)
->appendChild(
array(
$box,
$timeline,
));
->appendChild($view);
}
private function buildHeaderView(PhabricatorProjectColumn $column) {
$viewer = $this->getRequest()->getUser();
$viewer = $this->getViewer();
$header = id(new PHUIHeaderView())
->setUser($viewer)
->setHeader($column->getDisplayName());
->setHeader(pht('Column: %s', $column->getDisplayName()))
->setUser($viewer);
if ($column->isHidden()) {
$header->setStatus('fa-ban', 'dark', pht('Hidden'));
@ -82,41 +84,13 @@ final class PhabricatorProjectColumnDetailController
return $header;
}
private function buildActionView(PhabricatorProjectColumn $column) {
$viewer = $this->getRequest()->getUser();
$id = $column->getID();
$project_id = $this->getProject()->getID();
$base_uri = '/board/'.$project_id.'/';
$actions = id(new PhabricatorActionListView())
->setUser($viewer);
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$column,
PhabricatorPolicyCapability::CAN_EDIT);
$actions->addAction(
id(new PhabricatorActionView())
->setName(pht('Edit Column'))
->setIcon('fa-pencil')
->setHref($this->getApplicationURI($base_uri.'edit/'.$id.'/'))
->setDisabled(!$can_edit)
->setWorkflow(true));
return $actions;
}
private function buildPropertyView(
PhabricatorProjectColumn $column,
PhabricatorActionListView $actions) {
$viewer = $this->getRequest()->getUser();
PhabricatorProjectColumn $column) {
$viewer = $this->getViewer();
$properties = id(new PHUIPropertyListView())
->setUser($viewer)
->setObject($column)
->setActionList($actions);
->setObject($column);
$limit = $column->getPointLimit();
if ($limit === null) {
@ -126,7 +100,12 @@ final class PhabricatorProjectColumnDetailController
}
$properties->addProperty(pht('Point Limit'), $limit_text);
return $properties;
$box = id(new PHUIObjectBoxView())
->setHeaderText(pht('Details'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->appendChild($properties);
return $box;
}
}

View file

@ -65,7 +65,8 @@ final class PhabricatorProjectColumnHideController
$xactions = array();
$xactions[] = id(new PhabricatorProjectTransaction())
->setTransactionType(PhabricatorProjectTransaction::TYPE_STATUS)
->setTransactionType(
PhabricatorProjectStatusTransaction::TRANSACTIONTYPE)
->setNewValue($new_status);
id(new PhabricatorProjectTransactionEditor())

View file

@ -36,7 +36,7 @@ final class PhabricatorProjectCoverController
$xactions = array();
$xactions[] = id(new ManiphestTransaction())
->setTransactionType(ManiphestTransaction::TYPE_COVER_IMAGE)
->setTransactionType(ManiphestTaskCoverImageTransaction::TRANSACTIONTYPE)
->setNewValue($file->getPHID());
$editor = id(new ManiphestTransactionEditor())

View file

@ -23,8 +23,7 @@ final class PhabricatorProjectEditPictureController
$this->setProject($project);
$edit_uri = $this->getApplicationURI('profile/'.$project->getID().'/');
$view_uri = $this->getApplicationURI('profile/'.$project->getID().'/');
$manage_uri = $this->getApplicationURI('manage/'.$project->getID().'/');
$supported_formats = PhabricatorFile::getTransformableImageFormats();
$e_file = true;
@ -78,7 +77,8 @@ final class PhabricatorProjectEditPictureController
$xactions = array();
$xactions[] = id(new PhabricatorProjectTransaction())
->setTransactionType(PhabricatorProjectTransaction::TYPE_IMAGE)
->setTransactionType(
PhabricatorProjectImageTransaction::TRANSACTIONTYPE)
->setNewValue($new_value);
$editor = id(new PhabricatorProjectTransactionEditor())
@ -89,7 +89,7 @@ final class PhabricatorProjectEditPictureController
$editor->applyTransactions($project, $xactions);
return id(new AphrontRedirectResponse())->setURI($edit_uri);
return id(new AphrontRedirectResponse())->setURI($manage_uri);
}
}
@ -242,7 +242,7 @@ final class PhabricatorProjectEditPictureController
pht('Supported formats: %s', implode(', ', $supported_formats))))
->appendChild(
id(new AphrontFormSubmitControl())
->addCancelButton($edit_uri)
->addCancelButton($manage_uri)
->setValue(pht('Upload Picture')));
$form_box = id(new PHUIObjectBoxView())

View file

@ -20,26 +20,21 @@ final class PhabricatorProjectMembersViewController
$this->setProject($project);
$title = pht('Members and Watchers');
$properties = $this->buildProperties($project);
$curtain = $this->buildCurtainView($project);
$object_box = id(new PHUIObjectBoxView())
->setHeaderText(pht('Details'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->addPropertyList($properties);
$member_list = id(new PhabricatorProjectMemberListView())
->setUser($viewer)
->setProject($project)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setUserPHIDs($project->getMemberPHIDs());
->setUserPHIDs($project->getMemberPHIDs())
->setShowNote(true);
$watcher_list = id(new PhabricatorProjectWatcherListView())
->setUser($viewer)
->setProject($project)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setUserPHIDs($project->getWatcherPHIDs());
->setUserPHIDs($project->getWatcherPHIDs())
->setShowNote(true);
$nav = $this->getProfileMenu();
$nav->selectFilter(PhabricatorProject::ITEM_MEMBERS);
@ -52,16 +47,18 @@ final class PhabricatorProjectMembersViewController
->setHeader($title)
->setHeaderIcon('fa-group');
require_celerity_resource('project-view-css');
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setCurtain($curtain)
->addClass('project-view-home')
->addClass('project-view-people-home')
->setMainColumn(array(
$object_box,
$member_list,
$watcher_list,
));
return $this->newPage()
->setNavigation($nav)
->setCrumbs($crumbs)
@ -69,110 +66,11 @@ final class PhabricatorProjectMembersViewController
->appendChild($view);
}
private function buildProperties(PhabricatorProject $project) {
$viewer = $this->getViewer();
$view = id(new PHUIPropertyListView())
->setUser($viewer)
->setObject($project);
if ($project->isMilestone()) {
$icon_key = PhabricatorProjectIconSet::getMilestoneIconKey();
$icon = PhabricatorProjectIconSet::getIconIcon($icon_key);
$target = PhabricatorProjectIconSet::getIconName($icon_key);
$note = pht(
'Members of the parent project are members of this project.');
$show_join = false;
} else if ($project->getHasSubprojects()) {
$icon = 'fa-sitemap';
$target = pht('Parent Project');
$note = pht(
'Members of all subprojects are members of this project.');
$show_join = false;
} else if ($project->getIsMembershipLocked()) {
$icon = 'fa-lock';
$target = pht('Locked Project');
$note = pht(
'Users with access may join this project, but may not leave.');
$show_join = true;
} else {
$icon = 'fa-briefcase';
$target = pht('Normal Project');
$note = pht('Users with access may join and leave this project.');
$show_join = true;
}
$item = id(new PHUIStatusItemView())
->setIcon($icon)
->setTarget(phutil_tag('strong', array(), $target))
->setNote($note);
$status = id(new PHUIStatusListView())
->addItem($item);
$view->addProperty(pht('Membership'), $status);
if ($show_join) {
$descriptions = PhabricatorPolicyQuery::renderPolicyDescriptions(
$viewer,
$project);
$view->addProperty(
pht('Joinable By'),
$descriptions[PhabricatorPolicyCapability::CAN_JOIN]);
}
$viewer_phid = $viewer->getPHID();
if ($project->isUserWatcher($viewer_phid)) {
$watch_item = id(new PHUIStatusItemView())
->setIcon('fa-eye green')
->setTarget(phutil_tag('strong', array(), pht('Watching')))
->setNote(
pht(
'You will receive mail about changes made to any related '.
'object.'));
$watch_status = id(new PHUIStatusListView())
->addItem($watch_item);
$view->addProperty(pht('Watching'), $watch_status);
}
if ($project->isUserMember($viewer_phid)) {
$is_silenced = $this->isProjectSilenced($project);
if ($is_silenced) {
$mail_icon = 'fa-envelope-o grey';
$mail_target = pht('Disabled');
$mail_note = pht(
'When mail is sent to project members, you will not receive '.
'a copy.');
} else {
$mail_icon = 'fa-envelope-o green';
$mail_target = pht('Enabled');
$mail_note = pht(
'You will receive mail that is sent to project members.');
}
$mail_item = id(new PHUIStatusItemView())
->setIcon($mail_icon)
->setTarget(phutil_tag('strong', array(), $mail_target))
->setNote($mail_note);
$mail_status = id(new PHUIStatusListView())
->addItem($mail_item);
$view->addProperty(pht('Mail to Members'), $mail_status);
}
return $view;
}
private function buildCurtainView(PhabricatorProject $project) {
$viewer = $this->getViewer();
$id = $project->getID();
$curtain = $this->newCurtainView($project);
$curtain = $this->newCurtainView();
$is_locked = $project->getIsMembershipLocked();
@ -272,6 +170,42 @@ final class PhabricatorProjectMembersViewController
->setDisabled(!$can_lock)
->setWorkflow(true));
if ($project->isMilestone()) {
$icon_key = PhabricatorProjectIconSet::getMilestoneIconKey();
$header = PhabricatorProjectIconSet::getIconName($icon_key);
$note = pht(
'Members of the parent project are members of this project.');
$show_join = false;
} else if ($project->getHasSubprojects()) {
$header = pht('Parent Project');
$note = pht(
'Members of all subprojects are members of this project.');
$show_join = false;
} else if ($project->getIsMembershipLocked()) {
$header = pht('Locked Project');
$note = pht(
'Users with access may join this project, but may not leave.');
$show_join = true;
} else {
$header = pht('Normal Project');
$note = pht('Users with access may join and leave this project.');
$show_join = true;
}
$curtain->newPanel()
->setHeaderText($header)
->appendChild($note);
if ($show_join) {
$descriptions = PhabricatorPolicyQuery::renderPolicyDescriptions(
$viewer,
$project);
$curtain->newPanel()
->setHeaderText(pht('Joinable By'))
->appendChild($descriptions[PhabricatorPolicyCapability::CAN_JOIN]);
}
return $curtain;
}

View file

@ -153,10 +153,11 @@ final class PhabricatorProjectMoveController
$xactions = array();
if ($pri !== null) {
$xactions[] = id(new ManiphestTransaction())
->setTransactionType(ManiphestTransaction::TYPE_PRIORITY)
->setTransactionType(ManiphestTaskPriorityTransaction::TRANSACTIONTYPE)
->setNewValue($pri);
$xactions[] = id(new ManiphestTransaction())
->setTransactionType(ManiphestTransaction::TYPE_SUBPRIORITY)
->setTransactionType(
ManiphestTaskSubpriorityTransaction::TRANSACTIONTYPE)
->setNewValue($sub);
}

View file

@ -113,10 +113,7 @@ final class PhabricatorProjectProfileController
->setCrumbs($crumbs)
->setTitle($project->getDisplayName())
->setPageObjectPHIDs(array($project->getPHID()))
->appendChild(
array(
$home,
));
->appendChild($home);
}
private function buildPropertyListView(

View file

@ -26,6 +26,9 @@ final class PhabricatorProjectSubprojectsController
$allows_subprojects = $project->supportsSubprojects();
$allows_milestones = $project->supportsMilestones();
$subproject_list = null;
$milestone_list = null;
if ($allows_subprojects) {
$subprojects = id(new PhabricatorProjectQuery())
->setViewer($viewer)
@ -33,6 +36,16 @@ final class PhabricatorProjectSubprojectsController
->needImages(true)
->withIsMilestone(false)
->execute();
$subproject_list = id(new PHUIObjectBoxView())
->setHeaderText(pht('%s Subprojects', $project->getName()))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setObjectList(
id(new PhabricatorProjectListView())
->setUser($viewer)
->setProjects($subprojects)
->setNoDataString(pht('This project has no subprojects.'))
->renderList());
} else {
$subprojects = array();
}
@ -45,52 +58,25 @@ final class PhabricatorProjectSubprojectsController
->withIsMilestone(true)
->setOrderVector(array('milestoneNumber', 'id'))
->execute();
} else {
$milestones = array();
}
if ($milestones) {
$milestone_list = id(new PHUIObjectBoxView())
->setHeaderText(pht('Milestones'))
->setHeaderText(pht('%s Milestones', $project->getName()))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setObjectList(
id(new PhabricatorProjectListView())
->setUser($viewer)
->setProjects($milestones)
->setNoDataString(pht('This project has no milestones.'))
->renderList());
} else {
$milestone_list = null;
$milestones = array();
}
if ($subprojects) {
$subproject_list = id(new PHUIObjectBoxView())
->setHeaderText(pht('Subprojects'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setObjectList(
id(new PhabricatorProjectListView())
->setUser($viewer)
->setProjects($subprojects)
->renderList());
} else {
$subproject_list = null;
}
$property_list = $this->buildPropertyList(
$project,
$milestones,
$subprojects);
$curtain = $this->buildCurtainView(
$project,
$milestones,
$subprojects);
$details = id(new PHUIObjectBoxView())
->setHeaderText(pht('Details'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->addPropertyList($property_list);
$nav = $this->getProfileMenu();
$nav->selectFilter(PhabricatorProject::ITEM_SUBPROJECTS);
@ -102,11 +88,24 @@ final class PhabricatorProjectSubprojectsController
->setHeader(pht('Subprojects and Milestones'))
->setHeaderIcon('fa-sitemap');
require_celerity_resource('project-view-css');
// This page isn't reachable via UI, but make it pretty anyways.
$info_view = null;
if (!$milestone_list && !$subproject_list) {
$info_view = id(new PHUIInfoView())
->setSeverity(PHUIInfoView::SEVERITY_NOTICE)
->appendChild(pht('Milestone projects do not support subprojects '.
'or milestones.'));
}
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setCurtain($curtain)
->addClass('project-view-home')
->addClass('project-view-people-home')
->setMainColumn(array(
$details,
$info_view,
$milestone_list,
$subproject_list,
));
@ -118,73 +117,6 @@ final class PhabricatorProjectSubprojectsController
->appendChild($view);
}
private function buildPropertyList(
PhabricatorProject $project,
array $milestones,
array $subprojects) {
$viewer = $this->getViewer();
$view = id(new PHUIPropertyListView())
->setUser($viewer);
$view->addProperty(
pht('Prototype'),
$this->renderStatus(
'fa-exclamation-triangle red',
pht('Warning'),
pht('Subprojects and milestones are only partially implemented.')));
if (!$project->supportsMilestones()) {
$milestone_status = $this->renderStatus(
'fa-times grey',
pht('Already Milestone'),
pht(
'This project is already a milestone, and milestones may not '.
'have their own milestones.'));
} else {
if (!$milestones) {
$milestone_status = $this->renderStatus(
'fa-check grey',
pht('None Created'),
pht(
'You can create milestones for this project.'));
} else {
$milestone_status = $this->renderStatus(
'fa-check green',
pht('Has Milestones'),
pht('This project has milestones.'));
}
}
$view->addProperty(pht('Milestones'), $milestone_status);
if (!$project->supportsSubprojects()) {
$subproject_status = $this->renderStatus(
'fa-times grey',
pht('Milestone'),
pht(
'This project is a milestone, and milestones may not have '.
'subprojects.'));
} else {
if (!$subprojects) {
$subproject_status = $this->renderStatus(
'fa-check grey',
pht('None Created'),
pht('You can create subprojects for this project.'));
} else {
$subproject_status = $this->renderStatus(
'fa-check green',
pht('Has Subprojects'),
pht(
'This project has subprojects.'));
}
}
$view->addProperty(pht('Subprojects'), $subproject_status);
return $view;
}
private function buildCurtainView(
PhabricatorProject $project,
array $milestones,
@ -203,7 +135,7 @@ final class PhabricatorProjectSubprojectsController
$allows_milestones = $project->supportsMilestones();
$allows_subprojects = $project->supportsSubprojects();
$curtain = $this->newCurtainView($project);
$curtain = $this->newCurtainView();
if ($allows_milestones && $milestones) {
$milestone_text = pht('Create Next Milestone');
@ -244,6 +176,39 @@ final class PhabricatorProjectSubprojectsController
->setDisabled($subproject_disabled)
->setWorkflow($subproject_workflow));
if (!$project->supportsMilestones()) {
$note = pht(
'This project is already a milestone, and milestones may not '.
'have their own milestones.');
} else {
if (!$milestones) {
$note = pht('Milestones can be created for this project.');
} else {
$note = pht('This project has milestones.');
}
}
$curtain->newPanel()
->setHeaderText(pht('Milestones'))
->appendChild($note);
if (!$project->supportsSubprojects()) {
$note = pht(
'This project is a milestone, and milestones may not have '.
'subprojects.');
} else {
if (!$subprojects) {
$note = pht('Subprojects can be created for this project.');
} else {
$note = pht('This project has subprojects.');
}
}
$curtain->newPanel()
->setHeaderText(pht('Subprojects'))
->appendChild($note);
return $curtain;
}

View file

@ -10,7 +10,7 @@ final class PhabricatorProjectTransactionEditor
return $this;
}
private function getIsMilestone() {
public function getIsMilestone() {
return $this->isMilestone;
}
@ -30,12 +30,6 @@ final class PhabricatorProjectTransactionEditor
$types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
$types[] = PhabricatorTransactions::TYPE_JOIN_POLICY;
$types[] = PhabricatorProjectTransaction::TYPE_NAME;
$types[] = PhabricatorProjectTransaction::TYPE_SLUGS;
$types[] = PhabricatorProjectTransaction::TYPE_STATUS;
$types[] = PhabricatorProjectTransaction::TYPE_IMAGE;
$types[] = PhabricatorProjectTransaction::TYPE_ICON;
$types[] = PhabricatorProjectTransaction::TYPE_COLOR;
$types[] = PhabricatorProjectTransaction::TYPE_LOCKED;
$types[] = PhabricatorProjectTransaction::TYPE_PARENT;
$types[] = PhabricatorProjectTransaction::TYPE_MILESTONE;
@ -52,21 +46,6 @@ final class PhabricatorProjectTransactionEditor
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorProjectTransaction::TYPE_NAME:
return $object->getName();
case PhabricatorProjectTransaction::TYPE_SLUGS:
$slugs = $object->getSlugs();
$slugs = mpull($slugs, 'getSlug', 'getSlug');
unset($slugs[$object->getPrimarySlug()]);
return array_keys($slugs);
case PhabricatorProjectTransaction::TYPE_STATUS:
return $object->getStatus();
case PhabricatorProjectTransaction::TYPE_IMAGE:
return $object->getProfileImagePHID();
case PhabricatorProjectTransaction::TYPE_ICON:
return $object->getIcon();
case PhabricatorProjectTransaction::TYPE_COLOR:
return $object->getColor();
case PhabricatorProjectTransaction::TYPE_LOCKED:
return (int)$object->getIsMembershipLocked();
case PhabricatorProjectTransaction::TYPE_HASWORKBOARD:
@ -90,11 +69,6 @@ final class PhabricatorProjectTransactionEditor
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorProjectTransaction::TYPE_NAME:
case PhabricatorProjectTransaction::TYPE_STATUS:
case PhabricatorProjectTransaction::TYPE_IMAGE:
case PhabricatorProjectTransaction::TYPE_ICON:
case PhabricatorProjectTransaction::TYPE_COLOR:
case PhabricatorProjectTransaction::TYPE_LOCKED:
case PhabricatorProjectTransaction::TYPE_PARENT:
case PhabricatorProjectTransaction::TYPE_MILESTONE:
@ -109,8 +83,6 @@ final class PhabricatorProjectTransactionEditor
return null;
}
return $value;
case PhabricatorProjectTransaction::TYPE_SLUGS:
return $this->normalizeSlugs($xaction->getNewValue());
}
return parent::getCustomTransactionNewValue($object, $xaction);
@ -121,27 +93,6 @@ final class PhabricatorProjectTransactionEditor
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorProjectTransaction::TYPE_NAME:
$name = $xaction->getNewValue();
$object->setName($name);
if (!$this->getIsMilestone()) {
$object->setPrimarySlug(PhabricatorSlug::normalizeProjectSlug($name));
}
return;
case PhabricatorProjectTransaction::TYPE_SLUGS:
return;
case PhabricatorProjectTransaction::TYPE_STATUS:
$object->setStatus($xaction->getNewValue());
return;
case PhabricatorProjectTransaction::TYPE_IMAGE:
$object->setProfileImagePHID($xaction->getNewValue());
return;
case PhabricatorProjectTransaction::TYPE_ICON:
$object->setIcon($xaction->getNewValue());
return;
case PhabricatorProjectTransaction::TYPE_COLOR:
$object->setColor($xaction->getNewValue());
return;
case PhabricatorProjectTransaction::TYPE_LOCKED:
$object->setIsMembershipLocked($xaction->getNewValue());
return;
@ -178,32 +129,6 @@ final class PhabricatorProjectTransactionEditor
$new = $xaction->getNewValue();
switch ($xaction->getTransactionType()) {
case PhabricatorProjectTransaction::TYPE_NAME:
// First, add the old name as a secondary slug; this is helpful
// for renames and generally a good thing to do.
if (!$this->getIsMilestone()) {
if ($old !== null) {
$this->addSlug($object, $old, false);
}
$this->addSlug($object, $new, false);
}
return;
case PhabricatorProjectTransaction::TYPE_SLUGS:
$old = $xaction->getOldValue();
$new = $xaction->getNewValue();
$add = array_diff($new, $old);
$rem = array_diff($old, $new);
foreach ($add as $slug) {
$this->addSlug($object, $slug, true);
}
$this->removeSlugs($object, $rem);
return;
case PhabricatorProjectTransaction::TYPE_STATUS:
case PhabricatorProjectTransaction::TYPE_IMAGE:
case PhabricatorProjectTransaction::TYPE_ICON:
case PhabricatorProjectTransaction::TYPE_COLOR:
case PhabricatorProjectTransaction::TYPE_LOCKED:
case PhabricatorProjectTransaction::TYPE_PARENT:
case PhabricatorProjectTransaction::TYPE_MILESTONE:
@ -299,118 +224,6 @@ final class PhabricatorProjectTransactionEditor
$errors = parent::validateTransaction($object, $type, $xactions);
switch ($type) {
case PhabricatorProjectTransaction::TYPE_NAME:
$missing = $this->validateIsEmptyTextField(
$object->getName(),
$xactions);
if ($missing) {
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Required'),
pht('Project name is required.'),
nonempty(last($xactions), null));
$error->setIsMissingFieldError(true);
$errors[] = $error;
}
if (!$xactions) {
break;
}
if ($this->getIsMilestone()) {
break;
}
$name = last($xactions)->getNewValue();
if (!PhabricatorSlug::isValidProjectSlug($name)) {
$errors[] = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid'),
pht(
'Project names must contain at least one letter or number.'),
last($xactions));
break;
}
$slug = PhabricatorSlug::normalizeProjectSlug($name);
$slug_used_already = id(new PhabricatorProjectSlug())
->loadOneWhere('slug = %s', $slug);
if ($slug_used_already &&
$slug_used_already->getProjectPHID() != $object->getPHID()) {
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Duplicate'),
pht(
'Project name generates the same hashtag ("%s") as another '.
'existing project. Choose a unique name.',
'#'.$slug),
nonempty(last($xactions), null));
$errors[] = $error;
}
break;
case PhabricatorProjectTransaction::TYPE_SLUGS:
if (!$xactions) {
break;
}
$slug_xaction = last($xactions);
$new = $slug_xaction->getNewValue();
$invalid = array();
foreach ($new as $slug) {
if (!PhabricatorSlug::isValidProjectSlug($slug)) {
$invalid[] = $slug;
}
}
if ($invalid) {
$errors[] = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid'),
pht(
'Hashtags must contain at least one letter or number. %s '.
'project hashtag(s) are invalid: %s.',
phutil_count($invalid),
implode(', ', $invalid)),
$slug_xaction);
break;
}
$new = $this->normalizeSlugs($new);
if ($new) {
$slugs_used_already = id(new PhabricatorProjectSlug())
->loadAllWhere('slug IN (%Ls)', $new);
} else {
// The project doesn't have any extra slugs.
$slugs_used_already = array();
}
$slugs_used_already = mgroup($slugs_used_already, 'getProjectPHID');
foreach ($slugs_used_already as $project_phid => $used_slugs) {
if ($project_phid == $object->getPHID()) {
continue;
}
$used_slug_strs = mpull($used_slugs, 'getSlug');
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid'),
pht(
'%s project hashtag(s) are already used by other projects: %s.',
phutil_count($used_slug_strs),
implode(', ', $used_slug_strs)),
$slug_xaction);
$errors[] = $error;
}
break;
case PhabricatorProjectTransaction::TYPE_PARENT:
case PhabricatorProjectTransaction::TYPE_MILESTONE:
if (!$xactions) {
@ -497,11 +310,11 @@ final class PhabricatorProjectTransactionEditor
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorProjectTransaction::TYPE_NAME:
case PhabricatorProjectTransaction::TYPE_STATUS:
case PhabricatorProjectTransaction::TYPE_IMAGE:
case PhabricatorProjectTransaction::TYPE_ICON:
case PhabricatorProjectTransaction::TYPE_COLOR:
case PhabricatorProjectNameTransaction::TRANSACTIONTYPE:
case PhabricatorProjectStatusTransaction::TRANSACTIONTYPE:
case PhabricatorProjectImageTransaction::TRANSACTIONTYPE:
case PhabricatorProjectIconTransaction::TRANSACTIONTYPE:
case PhabricatorProjectColorTransaction::TRANSACTIONTYPE:
PhabricatorPolicyFilter::requireCapability(
$this->requireActor(),
$object,
@ -638,22 +451,6 @@ final class PhabricatorProjectTransactionEditor
return true;
}
protected function extractFilePHIDsFromCustomTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorProjectTransaction::TYPE_IMAGE:
$new = $xaction->getNewValue();
if ($new) {
return array($new);
}
break;
}
return parent::extractFilePHIDsFromCustomTransaction($object, $xaction);
}
protected function applyFinalEffects(
PhabricatorLiskDAO $object,
array $xactions) {
@ -717,7 +514,7 @@ final class PhabricatorProjectTransactionEditor
return parent::applyFinalEffects($object, $xactions);
}
private function addSlug(PhabricatorProject $project, $slug, $force) {
public function addSlug(PhabricatorProject $project, $slug, $force) {
$slug = PhabricatorSlug::normalizeProjectSlug($slug);
$table = new PhabricatorProjectSlug();
$project_phid = $project->getPHID();
@ -748,7 +545,7 @@ final class PhabricatorProjectTransactionEditor
->save();
}
private function removeSlugs(PhabricatorProject $project, array $slugs) {
public function removeSlugs(PhabricatorProject $project, array $slugs) {
if (!$slugs) {
return;
}
@ -770,7 +567,7 @@ final class PhabricatorProjectTransactionEditor
}
}
private function normalizeSlugs(array $slugs) {
public function normalizeSlugs(array $slugs) {
foreach ($slugs as $key => $slug) {
$slugs[$key] = PhabricatorSlug::normalizeProjectSlug($slug);
}

View file

@ -112,8 +112,8 @@ final class PhabricatorProjectEditEngine
PhabricatorTransactions::TYPE_VIEW_POLICY,
PhabricatorTransactions::TYPE_EDIT_POLICY,
PhabricatorTransactions::TYPE_JOIN_POLICY,
PhabricatorProjectTransaction::TYPE_ICON,
PhabricatorProjectTransaction::TYPE_COLOR,
PhabricatorProjectIconTransaction::TRANSACTIONTYPE,
PhabricatorProjectColorTransaction::TRANSACTIONTYPE,
);
$unavailable = array_fuse($unavailable);
@ -235,7 +235,7 @@ final class PhabricatorProjectEditEngine
id(new PhabricatorTextEditField())
->setKey('name')
->setLabel(pht('Name'))
->setTransactionType(PhabricatorProjectTransaction::TYPE_NAME)
->setTransactionType(PhabricatorProjectNameTransaction::TRANSACTIONTYPE)
->setIsRequired(true)
->setDescription(pht('Project name.'))
->setConduitDescription(pht('Rename the project'))
@ -244,7 +244,7 @@ final class PhabricatorProjectEditEngine
id(new PhabricatorIconSetEditField())
->setKey('icon')
->setLabel(pht('Icon'))
->setTransactionType(PhabricatorProjectTransaction::TYPE_ICON)
->setTransactionType(PhabricatorProjectIconTransaction::TRANSACTIONTYPE)
->setIconSet(new PhabricatorProjectIconSet())
->setDescription(pht('Project icon.'))
->setConduitDescription(pht('Change the project icon.'))
@ -253,7 +253,8 @@ final class PhabricatorProjectEditEngine
id(new PhabricatorSelectEditField())
->setKey('color')
->setLabel(pht('Color'))
->setTransactionType(PhabricatorProjectTransaction::TYPE_COLOR)
->setTransactionType(
PhabricatorProjectColorTransaction::TRANSACTIONTYPE)
->setOptions(PhabricatorProjectIconSet::getColorMap())
->setDescription(pht('Project tag color.'))
->setConduitDescription(pht('Change the project tag color.'))
@ -262,7 +263,8 @@ final class PhabricatorProjectEditEngine
id(new PhabricatorStringListEditField())
->setKey('slugs')
->setLabel(pht('Additional Hashtags'))
->setTransactionType(PhabricatorProjectTransaction::TYPE_SLUGS)
->setTransactionType(
PhabricatorProjectSlugsTransaction::TRANSACTIONTYPE)
->setDescription(pht('Additional project slugs.'))
->setConduitDescription(pht('Change project slugs.'))
->setConduitTypeDescription(pht('New list of slugs.'))

View file

@ -16,11 +16,11 @@ final class PhabricatorProjectTestDataGenerator
$xactions = array();
$xactions[] = $this->newTransaction(
PhabricatorProjectTransaction::TYPE_NAME,
PhabricatorProjectNameTransaction::TRANSACTIONTYPE,
$this->newProjectTitle());
$xactions[] = $this->newTransaction(
PhabricatorProjectTransaction::TYPE_STATUS,
PhabricatorProjectStatusTransaction::TRANSACTIONTYPE,
$this->newProjectStatus());
// Almost always make the author a member.

View file

@ -1,14 +1,8 @@
<?php
final class PhabricatorProjectTransaction
extends PhabricatorApplicationTransaction {
extends PhabricatorModularTransaction {
const TYPE_NAME = 'project:name';
const TYPE_SLUGS = 'project:slugs';
const TYPE_STATUS = 'project:status';
const TYPE_IMAGE = 'project:image';
const TYPE_ICON = 'project:icon';
const TYPE_COLOR = 'project:color';
const TYPE_LOCKED = 'project:locked';
const TYPE_PARENT = 'project:parent';
const TYPE_MILESTONE = 'project:milestone';
@ -33,6 +27,10 @@ final class PhabricatorProjectTransaction
return PhabricatorProjectProjectPHIDType::TYPECONST;
}
public function getBaseTransactionClass() {
return 'PhabricatorProjectTransactionType';
}
public function getRequiredHandlePHIDs() {
$old = $this->getOldValue();
$new = $this->getNewValue();
@ -44,31 +42,11 @@ final class PhabricatorProjectTransaction
$rem = array_diff($old, $new);
$req_phids = array_merge($add, $rem);
break;
case self::TYPE_IMAGE:
$req_phids[] = $old;
$req_phids[] = $new;
break;
}
return array_merge($req_phids, parent::getRequiredHandlePHIDs());
}
public function getColor() {
$old = $this->getOldValue();
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case self::TYPE_STATUS:
if ($old == 0) {
return 'red';
} else {
return 'green';
}
}
return parent::getColor();
}
public function shouldHide() {
switch ($this->getTransactionType()) {
case PhabricatorTransactions::TYPE_EDGE:
@ -113,26 +91,14 @@ final class PhabricatorProjectTransaction
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case self::TYPE_STATUS:
if ($old == 0) {
return 'fa-ban';
} else {
return 'fa-check';
}
case self::TYPE_LOCKED:
if ($new) {
return 'fa-lock';
} else {
return 'fa-unlock';
}
case self::TYPE_ICON:
return PhabricatorProjectIconSet::getIconIcon($new);
case self::TYPE_IMAGE:
return 'fa-photo';
case self::TYPE_MEMBERS:
return 'fa-user';
case self::TYPE_SLUGS:
return 'fa-tag';
}
return parent::getIcon();
}
@ -149,68 +115,6 @@ final class PhabricatorProjectTransaction
'%s created this project.',
$this->renderHandleLink($author_phid));
case self::TYPE_NAME:
if ($old === null) {
return pht(
'%s created this project.',
$author_handle);
} else {
return pht(
'%s renamed this project from "%s" to "%s".',
$author_handle,
$old,
$new);
}
break;
case self::TYPE_STATUS:
if ($old == 0) {
return pht(
'%s archived this project.',
$author_handle);
} else {
return pht(
'%s activated this project.',
$author_handle);
}
break;
case self::TYPE_IMAGE:
// TODO: Some day, it would be nice to show the images.
if (!$old) {
return pht(
"%s set this project's image to %s.",
$author_handle,
$this->renderHandleLink($new));
} else if (!$new) {
return pht(
"%s removed this project's image.",
$author_handle);
} else {
return pht(
"%s updated this project's image from %s to %s.",
$author_handle,
$this->renderHandleLink($old),
$this->renderHandleLink($new));
}
break;
case self::TYPE_ICON:
$set = new PhabricatorProjectIconSet();
return pht(
"%s set this project's icon to %s.",
$author_handle,
$set->getIconLabel($new));
break;
case self::TYPE_COLOR:
return pht(
"%s set this project's color to %s.",
$author_handle,
PHUITagView::getShadeName($new));
break;
case self::TYPE_LOCKED:
if ($new) {
return pht(
@ -223,33 +127,6 @@ final class PhabricatorProjectTransaction
}
break;
case self::TYPE_SLUGS:
$add = array_diff($new, $old);
$rem = array_diff($old, $new);
if ($add && $rem) {
return pht(
'%s changed project hashtag(s), added %d: %s; removed %d: %s.',
$author_handle,
count($add),
$this->renderSlugList($add),
count($rem),
$this->renderSlugList($rem));
} else if ($add) {
return pht(
'%s added %d project hashtag(s): %s.',
$author_handle,
count($add),
$this->renderSlugList($add));
} else if ($rem) {
return pht(
'%s removed %d project hashtag(s): %s.',
$author_handle,
count($rem),
$this->renderSlugList($rem));
}
break;
case self::TYPE_MEMBERS:
$add = array_diff($new, $old);
$rem = array_diff($old, $new);
@ -329,112 +206,18 @@ final class PhabricatorProjectTransaction
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case self::TYPE_NAME:
if ($old === null) {
return pht(
'%s created %s.',
$author_handle,
$object_handle);
} else {
return pht(
'%s renamed %s from "%s" to "%s".',
$author_handle,
$object_handle,
$old,
$new);
}
case self::TYPE_STATUS:
if ($old == 0) {
return pht(
'%s archived %s.',
$author_handle,
$object_handle);
} else {
return pht(
'%s activated %s.',
$author_handle,
$object_handle);
}
case self::TYPE_IMAGE:
// TODO: Some day, it would be nice to show the images.
if (!$old) {
return pht(
'%s set the image for %s to %s.',
$author_handle,
$object_handle,
$this->renderHandleLink($new));
} else if (!$new) {
return pht(
'%s removed the image for %s.',
$author_handle,
$object_handle);
} else {
return pht(
'%s updated the image for %s from %s to %s.',
$author_handle,
$object_handle,
$this->renderHandleLink($old),
$this->renderHandleLink($new));
}
case self::TYPE_ICON:
$set = new PhabricatorProjectIconSet();
return pht(
'%s set the icon for %s to %s.',
$author_handle,
$object_handle,
$set->getIconLabel($new));
case self::TYPE_COLOR:
return pht(
'%s set the color for %s to %s.',
$author_handle,
$object_handle,
PHUITagView::getShadeName($new));
case self::TYPE_LOCKED:
if ($new) {
return pht(
'%s locked %s membership.',
'%s locked membership for %s.',
$author_handle,
$object_handle);
} else {
return pht(
'%s unlocked %s membership.',
'%s unlocked membership for %s.',
$author_handle,
$object_handle);
}
case self::TYPE_SLUGS:
$add = array_diff($new, $old);
$rem = array_diff($old, $new);
if ($add && $rem) {
return pht(
'%s changed %s hashtag(s), added %d: %s; removed %d: %s.',
$author_handle,
$object_handle,
count($add),
$this->renderSlugList($add),
count($rem),
$this->renderSlugList($rem));
} else if ($add) {
return pht(
'%s added %d %s hashtag(s): %s.',
$author_handle,
count($add),
$object_handle,
$this->renderSlugList($add));
} else if ($rem) {
return pht(
'%s removed %d %s hashtag(s): %s.',
$author_handle,
count($rem),
$object_handle,
$this->renderSlugList($rem));
}
}
return parent::getTitleForFeed();
@ -443,11 +226,11 @@ final class PhabricatorProjectTransaction
public function getMailTags() {
$tags = array();
switch ($this->getTransactionType()) {
case self::TYPE_NAME:
case self::TYPE_SLUGS:
case self::TYPE_IMAGE:
case self::TYPE_ICON:
case self::TYPE_COLOR:
case PhabricatorProjectNameTransaction::TRANSACTIONTYPE:
case PhabricatorProjectSlugsTransaction::TRANSACTIONTYPE:
case PhabricatorProjectImageTransaction::TRANSACTIONTYPE:
case PhabricatorProjectIconTransaction::TRANSACTIONTYPE:
case PhabricatorProjectColorTransaction::TRANSACTIONTYPE:
$tags[] = self::MAILTAG_METADATA;
break;
case PhabricatorTransactions::TYPE_EDGE:
@ -463,7 +246,7 @@ final class PhabricatorProjectTransaction
$tags[] = self::MAILTAG_OTHER;
}
break;
case self::TYPE_STATUS:
case PhabricatorProjectStatusTransaction::TRANSACTIONTYPE:
case self::TYPE_LOCKED:
default:
$tags[] = self::MAILTAG_OTHER;
@ -472,8 +255,4 @@ final class PhabricatorProjectTransaction
return $tags;
}
private function renderSlugList($slugs) {
return implode(', ', $slugs);
}
}

View file

@ -5,6 +5,7 @@ final class PhabricatorProjectListView extends AphrontView {
private $projects;
private $showMember;
private $showWatching;
private $noDataString;
public function setProjects(array $projects) {
$this->projects = $projects;
@ -25,6 +26,11 @@ final class PhabricatorProjectListView extends AphrontView {
return $this;
}
public function setNoDataString($text) {
$this->noDataString = $text;
return $this;
}
public function renderList() {
$viewer = $this->getUser();
$viewer_phid = $viewer->getPHID();
@ -32,8 +38,14 @@ final class PhabricatorProjectListView extends AphrontView {
$handles = $viewer->loadHandles(mpull($projects, 'getPHID'));
$no_data = pht('No projects found.');
if ($this->noDataString) {
$no_data = $this->noDataString;
}
$list = id(new PHUIObjectItemListView())
->setUser($viewer);
->setUser($viewer)
->setNoDataString($no_data);
foreach ($projects as $key => $project) {
$id = $project->getID();
@ -56,7 +68,7 @@ final class PhabricatorProjectListView extends AphrontView {
));
if ($project->getStatus() == PhabricatorProjectStatus::STATUS_ARCHIVED) {
$item->addIcon('delete-grey', pht('Archived'));
$item->addIcon('fa-ban', pht('Archived'));
$item->setDisabled(true);
}

View file

@ -4,7 +4,7 @@ final class PhabricatorProjectMemberListView
extends PhabricatorProjectUserListView {
protected function canEditList() {
$viewer = $this->getUser();
$viewer = $this->getViewer();
$project = $this->getProject();
if (!$project->supportsEditMembers()) {
@ -31,4 +31,35 @@ final class PhabricatorProjectMemberListView
return pht('Members');
}
protected function getMembershipNote() {
$viewer = $this->getViewer();
$viewer_phid = $viewer->getPHID();
$project = $this->getProject();
if (!$viewer_phid) {
return null;
}
$note = null;
if ($project->isUserMember($viewer_phid)) {
$edge_type = PhabricatorProjectSilencedEdgeType::EDGECONST;
$silenced = PhabricatorEdgeQuery::loadDestinationPHIDs(
$project->getPHID(),
$edge_type);
$silenced = array_fuse($silenced);
$is_silenced = isset($silenced[$viewer_phid]);
if ($is_silenced) {
$note = pht(
'You have disabled mail. When mail is sent to project members, '.
'you will not receive a copy.');
} else {
$note = pht(
'You are a member and you will receive mail that is sent to all '.
'project members.');
}
}
return $note;
}
}

View file

@ -6,6 +6,7 @@ abstract class PhabricatorProjectUserListView extends AphrontView {
private $userPHIDs;
private $limit;
private $background;
private $showNote;
public function setProject(PhabricatorProject $project) {
$this->project = $project;
@ -39,10 +40,16 @@ abstract class PhabricatorProjectUserListView extends AphrontView {
return $this;
}
public function setShowNote($show) {
$this->showNote = $show;
return $this;
}
abstract protected function canEditList();
abstract protected function getNoDataString();
abstract protected function getRemoveURI($phid);
abstract protected function getHeaderText();
abstract protected function getMembershipNote();
public function render() {
$viewer = $this->getViewer();
@ -135,6 +142,15 @@ abstract class PhabricatorProjectUserListView extends AphrontView {
->setHeader($header)
->setObjectList($list);
if ($this->showNote) {
if ($this->getMembershipNote()) {
$info = id(new PHUIInfoView())
->setSeverity(PHUIInfoView::SEVERITY_PLAIN)
->appendChild($this->getMembershipNote());
$box->setInfoView($info);
}
}
if ($this->background) {
$box->setBackground($this->background);
}

View file

@ -4,7 +4,7 @@ final class PhabricatorProjectWatcherListView
extends PhabricatorProjectUserListView {
protected function canEditList() {
$viewer = $this->getUser();
$viewer = $this->getViewer();
$project = $this->getProject();
return PhabricatorPolicyFilter::hasCapability(
@ -27,4 +27,17 @@ final class PhabricatorProjectWatcherListView
return pht('Watchers');
}
protected function getMembershipNote() {
$viewer = $this->getViewer();
$viewer_phid = $viewer->getPHID();
$project = $this->getProject();
$note = null;
if ($project->isUserWatcher($viewer_phid)) {
$note = pht('You are watching this project and will receive mail about '.
'changes made to any related object.');
}
return $note;
}
}

View file

@ -0,0 +1,33 @@
<?php
final class PhabricatorProjectColorTransaction
extends PhabricatorProjectTransactionType {
const TRANSACTIONTYPE = 'project:color';
public function generateOldValue($object) {
return $object->getColor();
}
public function applyInternalEffects($object, $value) {
$object->setColor($value);
}
public function getTitle() {
$new = $this->getNewValue();
return pht(
"%s set this project's color to %s.",
$this->renderAuthor(),
$this->renderValue(PHUITagView::getShadeName($new)));
}
public function getTitleForFeed() {
$new = $this->getNewValue();
return pht(
'%s set the color for %s to %s.',
$this->renderAuthor(),
$this->renderObject(),
$this->renderValue(PHUITagView::getShadeName($new)));
}
}

View file

@ -0,0 +1,42 @@
<?php
final class PhabricatorProjectIconTransaction
extends PhabricatorProjectTransactionType {
const TRANSACTIONTYPE = 'project:icon';
public function generateOldValue($object) {
return $object->getIcon();
}
public function applyInternalEffects($object, $value) {
$object->setIcon($value);
}
public function getTitle() {
$set = new PhabricatorProjectIconSet();
$new = $this->getNewValue();
return pht(
"%s set this project's icon to %s.",
$this->renderAuthor(),
$this->renderValue($set->getIconLabel($new)));
}
public function getTitleForFeed() {
$set = new PhabricatorProjectIconSet();
$new = $this->getNewValue();
return pht(
'%s set the icon for %s to %s.',
$this->renderAuthor(),
$this->renderObject(),
$this->renderValue($set->getIconLabel($new)));
}
public function getIcon() {
$new = $this->getNewValue();
return PhabricatorProjectIconSet::getIconIcon($new);
}
}

View file

@ -0,0 +1,136 @@
<?php
final class PhabricatorProjectImageTransaction
extends PhabricatorProjectTransactionType {
const TRANSACTIONTYPE = 'project:image';
public function generateOldValue($object) {
return $object->getProfileImagePHID();
}
public function applyInternalEffects($object, $value) {
$object->setProfileImagePHID($value);
}
public function applyExternalEffects($object, $value) {
$old = $this->getOldValue();
$new = $value;
$all = array();
if ($old) {
$all[] = $old;
}
if ($new) {
$all[] = $new;
}
$files = id(new PhabricatorFileQuery())
->setViewer($this->getActor())
->withPHIDs($all)
->execute();
$files = mpull($files, null, 'getPHID');
$old_file = idx($files, $old);
if ($old_file) {
$old_file->detachFromObject($object->getPHID());
}
$new_file = idx($files, $new);
if ($new_file) {
$new_file->attachToObject($object->getPHID());
}
}
public function getTitle() {
$old = $this->getOldValue();
$new = $this->getNewValue();
// TODO: Some day, it would be nice to show the images.
if (!$old) {
return pht(
"%s set this project's image to %s.",
$this->renderAuthor(),
$this->renderNewHandle());
} else if (!$new) {
return pht(
"%s removed this project's image.",
$this->renderAuthor());
} else {
return pht(
"%s updated this project's image from %s to %s.",
$this->renderAuthor(),
$this->renderOldHandle(),
$this->renderNewHandle());
}
}
public function getTitleForFeed() {
$old = $this->getOldValue();
$new = $this->getNewValue();
// TODO: Some day, it would be nice to show the images.
if (!$old) {
return pht(
'%s set the image for %s to %s.',
$this->renderAuthor(),
$this->renderObject(),
$this->renderNewHandle());
} else if (!$new) {
return pht(
'%s removed the image for %s.',
$this->renderAuthor(),
$this->renderObject());
} else {
return pht(
'%s updated the image for %s from %s to %s.',
$this->renderAuthor(),
$this->renderObject(),
$this->renderOldHandle(),
$this->renderNewHandle());
}
}
public function getIcon() {
return 'fa-photo';
}
public function extractFilePHIDs($object, $value) {
if ($value) {
return array($value);
}
return array();
}
public function validateTransactions($object, array $xactions) {
$errors = array();
$viewer = $this->getActor();
foreach ($xactions as $xaction) {
$file_phid = $xaction->getNewValue();
// Only validate if file was uploaded
if ($file_phid) {
$file = id(new PhabricatorFileQuery())
->setViewer($viewer)
->withPHIDs(array($file_phid))
->executeOne();
if (!$file) {
$errors[] = $this->newInvalidError(
pht('"%s" is not a valid file PHID.',
$file_phid));
} else {
if (!$file->isViewableImage()) {
$mime_type = $file->getMimeType();
$errors[] = $this->newInvalidError(
pht('File mime type of "%s" is not a valid viewable image.',
$mime_type));
}
}
}
}
return $errors;
}
}

View file

@ -0,0 +1,112 @@
<?php
final class PhabricatorProjectNameTransaction
extends PhabricatorProjectTransactionType {
const TRANSACTIONTYPE = 'project:name';
public function generateOldValue($object) {
return $object->getName();
}
public function applyInternalEffects($object, $value) {
$object->setName($value);
if (!$this->getEditor()->getIsMilestone()) {
$object->setPrimarySlug(PhabricatorSlug::normalizeProjectSlug($value));
}
}
public function applyExternalEffects($object, $value) {
$old = $this->getOldValue();
// First, add the old name as a secondary slug; this is helpful
// for renames and generally a good thing to do.
if (!$this->getEditor()->getIsMilestone()) {
if ($old !== null) {
$this->getEditor()->addSlug($object, $old, false);
}
$this->getEditor()->addSlug($object, $value, false);
}
return;
}
public function getTitle() {
$old = $this->getOldValue();
if ($old === null) {
return pht(
'%s created this project.',
$this->renderAuthor());
} else {
return pht(
'%s renamed this project from %s to %s.',
$this->renderAuthor(),
$this->renderOldValue(),
$this->renderNewValue());
}
}
public function getTitleForFeed() {
$old = $this->getOldValue();
if ($old === null) {
return pht(
'%s created %s.',
$this->renderAuthor(),
$this->renderObject());
} else {
return pht(
'%s renamed %s from %s to %s.',
$this->renderAuthor(),
$this->renderObject(),
$this->renderOldValue(),
$this->renderNewValue());
}
}
public function validateTransactions($object, array $xactions) {
$errors = array();
if ($this->isEmptyTextTransaction($object->getName(), $xactions)) {
$errors[] = $this->newRequiredError(pht('Projects must have a name.'));
}
$max_length = $object->getColumnMaximumByteLength('name');
foreach ($xactions as $xaction) {
$new_value = $xaction->getNewValue();
$new_length = strlen($new_value);
if ($new_length > $max_length) {
$errors[] = $this->newInvalidError(
pht(
'Project names must not be longer than %s character(s).',
new PhutilNumber($max_length)));
}
}
if ($this->getEditor()->getIsMilestone() || !$xactions) {
return $errors;
}
$name = last($xactions)->getNewValue();
if (!PhabricatorSlug::isValidProjectSlug($name)) {
$errors[] = $this->newInvalidError(
pht('Project names must contain at least one letter or number.'));
}
$slug = PhabricatorSlug::normalizeProjectSlug($name);
$slug_used_already = id(new PhabricatorProjectSlug())
->loadOneWhere('slug = %s', $slug);
if ($slug_used_already &&
$slug_used_already->getProjectPHID() != $object->getPHID()) {
$errors[] = $this->newInvalidError(
pht(
'Project name generates the same hashtag ("%s") as another '.
'existing project. Choose a unique name.',
'#'.$slug));
}
return $errors;
}
}

View file

@ -0,0 +1,174 @@
<?php
final class PhabricatorProjectSlugsTransaction
extends PhabricatorProjectTransactionType {
const TRANSACTIONTYPE = 'project:slugs';
public function generateOldValue($object) {
$slugs = $object->getSlugs();
$slugs = mpull($slugs, 'getSlug', 'getSlug');
unset($slugs[$object->getPrimarySlug()]);
return array_keys($slugs);
}
public function generateNewValue($object, $value) {
return $this->getEditor()->normalizeSlugs($value);
}
public function applyInternalEffects($object, $value) {
return;
}
public function applyExternalEffects($object, $value) {
$old = $this->getOldValue();
$new = $value;
$add = array_diff($new, $old);
$rem = array_diff($old, $new);
foreach ($add as $slug) {
$this->getEditor()->addSlug($object, $slug, true);
}
$this->getEditor()->removeSlugs($object, $rem);
}
public function getTitle() {
$old = $this->getOldValue();
$new = $this->getNewValue();
$add = array_diff($new, $old);
$rem = array_diff($old, $new);
$add = $this->renderHashtags($add);
$rem = $this->renderHashtags($rem);
if ($add && $rem) {
return pht(
'%s changed project hashtag(s), added %d: %s; removed %d: %s.',
$this->renderAuthor(),
count($add),
$this->renderValueList($add),
count($rem),
$this->renderValueList($rem));
} else if ($add) {
return pht(
'%s added %d project hashtag(s): %s.',
$this->renderAuthor(),
count($add),
$this->renderValueList($add));
} else if ($rem) {
return pht(
'%s removed %d project hashtag(s): %s.',
$this->renderAuthor(),
count($rem),
$this->renderValueList($rem));
}
}
public function getTitleForFeed() {
$old = $this->getOldValue();
$new = $this->getNewValue();
$add = array_diff($new, $old);
$rem = array_diff($old, $new);
$add = $this->renderHashtags($add);
$rem = $this->renderHashtags($rem);
if ($add && $rem) {
return pht(
'%s changed %s hashtag(s), added %d: %s; removed %d: %s.',
$this->renderAuthor(),
$this->renderObject(),
count($add),
$this->renderValueList($add),
count($rem),
$this->renderValueList($rem));
} else if ($add) {
return pht(
'%s added %d %s hashtag(s): %s.',
$this->renderAuthor(),
count($add),
$this->renderObject(),
$this->renderValueList($add));
} else if ($rem) {
return pht(
'%s removed %d %s hashtag(s): %s.',
$this->renderAuthor(),
count($rem),
$this->renderObject(),
$this->renderValueList($rem));
}
}
public function getIcon() {
return 'fa-tag';
}
public function validateTransactions($object, array $xactions) {
$errors = array();
if (!$xactions) {
return $errors;
}
$slug_xaction = last($xactions);
$new = $slug_xaction->getNewValue();
$invalid = array();
foreach ($new as $slug) {
if (!PhabricatorSlug::isValidProjectSlug($slug)) {
$invalid[] = $slug;
}
}
if ($invalid) {
$errors[] = $this->newInvalidError(
pht(
'Hashtags must contain at least one letter or number. %s '.
'project hashtag(s) are invalid: %s.',
phutil_count($invalid),
implode(', ', $invalid)));
return $errors;
}
$new = $this->getEditor()->normalizeSlugs($new);
if ($new) {
$slugs_used_already = id(new PhabricatorProjectSlug())
->loadAllWhere('slug IN (%Ls)', $new);
} else {
// The project doesn't have any extra slugs.
$slugs_used_already = array();
}
$slugs_used_already = mgroup($slugs_used_already, 'getProjectPHID');
foreach ($slugs_used_already as $project_phid => $used_slugs) {
if ($project_phid == $object->getPHID()) {
continue;
}
$used_slug_strs = mpull($used_slugs, 'getSlug');
$errors[] = $this->newInvalidError(
pht(
'%s project hashtag(s) are already used by other projects: %s.',
phutil_count($used_slug_strs),
implode(', ', $used_slug_strs)));
}
return $errors;
}
private function renderHashtags(array $tags) {
$result = array();
foreach ($tags as $tag) {
$result[] = '#'.$tag;
}
return $result;
}
}

View file

@ -0,0 +1,66 @@
<?php
final class PhabricatorProjectStatusTransaction
extends PhabricatorProjectTransactionType {
const TRANSACTIONTYPE = 'project:status';
public function generateOldValue($object) {
return $object->getStatus();
}
public function applyInternalEffects($object, $value) {
$object->setStatus($value);
}
public function getTitle() {
$old = $this->getOldValue();
if ($old == 0) {
return pht(
'%s archived this project.',
$this->renderAuthor());
} else {
return pht(
'%s activated this project.',
$this->renderAuthor());
}
}
public function getTitleForFeed() {
$old = $this->getOldValue();
if ($old == 0) {
return pht(
'%s archived %s.',
$this->renderAuthor(),
$this->renderObject());
} else {
return pht(
'%s activated %s.',
$this->renderAuthor(),
$this->renderObject());
}
}
public function getColor() {
$old = $this->getOldValue();
if ($old == 0) {
return 'red';
} else {
return 'green';
}
}
public function getIcon() {
$old = $this->getOldValue();
if ($old == 0) {
return 'fa-ban';
} else {
return 'fa-check';
}
}
}

View file

@ -0,0 +1,4 @@
<?php
abstract class PhabricatorProjectTransactionType
extends PhabricatorModularTransactionType {}

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