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

(stable) Promote 2017 Week 15

This commit is contained in:
epriestley 2017-04-14 13:37:18 -07:00
commit edaebe2fb7
136 changed files with 3912 additions and 1888 deletions

View file

@ -7,10 +7,10 @@
*/ */
return array( return array(
'names' => array( 'names' => array(
'conpherence.pkg.css' => '82aca405', 'conpherence.pkg.css' => '437d3b5a',
'conpherence.pkg.js' => '6249a1cf', 'conpherence.pkg.js' => '281b1a73',
'core.pkg.css' => '1bf8fa70', 'core.pkg.css' => 'b2ad82f4',
'core.pkg.js' => '021685f1', 'core.pkg.js' => 'bf3b5cdf',
'darkconsole.pkg.js' => 'e7393ebb', 'darkconsole.pkg.js' => 'e7393ebb',
'differential.pkg.css' => '90b30783', 'differential.pkg.css' => '90b30783',
'differential.pkg.js' => 'ddfeb49b', 'differential.pkg.js' => 'ddfeb49b',
@ -37,7 +37,7 @@ return array(
'rsrc/css/application/base/main-menu-view.css' => '5294060f', 'rsrc/css/application/base/main-menu-view.css' => '5294060f',
'rsrc/css/application/base/notification-menu.css' => '6a697e43', 'rsrc/css/application/base/notification-menu.css' => '6a697e43',
'rsrc/css/application/base/phui-theme.css' => '9f261c6b', 'rsrc/css/application/base/phui-theme.css' => '9f261c6b',
'rsrc/css/application/base/standard-page-view.css' => '894d8a25', 'rsrc/css/application/base/standard-page-view.css' => '89da5a9c',
'rsrc/css/application/chatlog/chatlog.css' => 'd295b020', 'rsrc/css/application/chatlog/chatlog.css' => 'd295b020',
'rsrc/css/application/conduit/conduit-api.css' => '7bc725c4', 'rsrc/css/application/conduit/conduit-api.css' => '7bc725c4',
'rsrc/css/application/config/config-options.css' => '0ede4c9b', 'rsrc/css/application/config/config-options.css' => '0ede4c9b',
@ -45,11 +45,11 @@ return array(
'rsrc/css/application/config/config-template.css' => '8f18fa41', 'rsrc/css/application/config/config-template.css' => '8f18fa41',
'rsrc/css/application/config/setup-issue.css' => 'f794cfc3', 'rsrc/css/application/config/setup-issue.css' => 'f794cfc3',
'rsrc/css/application/config/unhandled-exception.css' => '4c96257a', 'rsrc/css/application/config/unhandled-exception.css' => '4c96257a',
'rsrc/css/application/conpherence/durable-column.css' => '292c71f0', 'rsrc/css/application/conpherence/durable-column.css' => '89ea6bef',
'rsrc/css/application/conpherence/header-pane.css' => '4082233d', 'rsrc/css/application/conpherence/header-pane.css' => '4082233d',
'rsrc/css/application/conpherence/menu.css' => '3d8e5c9c', 'rsrc/css/application/conpherence/menu.css' => '3d8e5c9c',
'rsrc/css/application/conpherence/message-pane.css' => 'd1fc13e1', 'rsrc/css/application/conpherence/message-pane.css' => 'd1fc13e1',
'rsrc/css/application/conpherence/notification.css' => '965db05b', 'rsrc/css/application/conpherence/notification.css' => 'cef0a3fc',
'rsrc/css/application/conpherence/participant-pane.css' => '604a8b02', 'rsrc/css/application/conpherence/participant-pane.css' => '604a8b02',
'rsrc/css/application/conpherence/transaction.css' => '85129c68', 'rsrc/css/application/conpherence/transaction.css' => '85129c68',
'rsrc/css/application/contentsource/content-source-view.css' => '4b8b05d4', 'rsrc/css/application/contentsource/content-source-view.css' => '4b8b05d4',
@ -103,7 +103,7 @@ return array(
'rsrc/css/application/releeph/releeph-request-differential-create-dialog.css' => '8d8b92cd', 'rsrc/css/application/releeph/releeph-request-differential-create-dialog.css' => '8d8b92cd',
'rsrc/css/application/releeph/releeph-request-typeahead.css' => '667a48ae', 'rsrc/css/application/releeph/releeph-request-typeahead.css' => '667a48ae',
'rsrc/css/application/search/application-search-view.css' => '66ee5d46', 'rsrc/css/application/search/application-search-view.css' => '66ee5d46',
'rsrc/css/application/search/search-results.css' => '64ad079a', 'rsrc/css/application/search/search-results.css' => 'f87d23ad',
'rsrc/css/application/slowvote/slowvote.css' => 'a94b7230', 'rsrc/css/application/slowvote/slowvote.css' => 'a94b7230',
'rsrc/css/application/tokens/tokens.css' => '3d0f239e', 'rsrc/css/application/tokens/tokens.css' => '3d0f239e',
'rsrc/css/application/uiexample/example.css' => '528b19de', 'rsrc/css/application/uiexample/example.css' => '528b19de',
@ -133,20 +133,20 @@ return array(
'rsrc/css/phui/phui-basic-nav-view.css' => 'a0705f53', 'rsrc/css/phui/phui-basic-nav-view.css' => 'a0705f53',
'rsrc/css/phui/phui-big-info-view.css' => 'bd903741', 'rsrc/css/phui/phui-big-info-view.css' => 'bd903741',
'rsrc/css/phui/phui-box.css' => '269cbc99', 'rsrc/css/phui/phui-box.css' => '269cbc99',
'rsrc/css/phui/phui-button.css' => '14bfba79', 'rsrc/css/phui/phui-button.css' => '96787bae',
'rsrc/css/phui/phui-chart.css' => '6bf6f78e', 'rsrc/css/phui/phui-chart.css' => '6bf6f78e',
'rsrc/css/phui/phui-cms.css' => '504b4b23', 'rsrc/css/phui/phui-cms.css' => '504b4b23',
'rsrc/css/phui/phui-comment-form.css' => '7d903c2d', 'rsrc/css/phui/phui-comment-form.css' => '57af2e14',
'rsrc/css/phui/phui-comment-panel.css' => 'f50152ad', 'rsrc/css/phui/phui-comment-panel.css' => 'f50152ad',
'rsrc/css/phui/phui-crumbs-view.css' => '6ece3bbb', 'rsrc/css/phui/phui-crumbs-view.css' => '6ece3bbb',
'rsrc/css/phui/phui-curtain-view.css' => '947bf1a4', 'rsrc/css/phui/phui-curtain-view.css' => '679743bb',
'rsrc/css/phui/phui-document-pro.css' => 'f56738ed', 'rsrc/css/phui/phui-document-pro.css' => 'f56738ed',
'rsrc/css/phui/phui-document-summary.css' => '9ca48bdf', 'rsrc/css/phui/phui-document-summary.css' => '9ca48bdf',
'rsrc/css/phui/phui-document.css' => 'c32e8dec', 'rsrc/css/phui/phui-document.css' => 'c32e8dec',
'rsrc/css/phui/phui-feed-story.css' => '44a9c8e9', 'rsrc/css/phui/phui-feed-story.css' => '44a9c8e9',
'rsrc/css/phui/phui-fontkit.css' => '1320ed01', 'rsrc/css/phui/phui-fontkit.css' => '1320ed01',
'rsrc/css/phui/phui-form-view.css' => '6175808d', 'rsrc/css/phui/phui-form-view.css' => '6175808d',
'rsrc/css/phui/phui-form.css' => 'b62c01d8', 'rsrc/css/phui/phui-form.css' => 'a5570f70',
'rsrc/css/phui/phui-head-thing.css' => 'fd311e5f', 'rsrc/css/phui/phui-head-thing.css' => 'fd311e5f',
'rsrc/css/phui/phui-header-view.css' => '9cf828ce', 'rsrc/css/phui/phui-header-view.css' => '9cf828ce',
'rsrc/css/phui/phui-hovercard.css' => 'ae091fc5', 'rsrc/css/phui/phui-hovercard.css' => 'ae091fc5',
@ -157,7 +157,7 @@ return array(
'rsrc/css/phui/phui-info-view.css' => 'ec92802a', 'rsrc/css/phui/phui-info-view.css' => 'ec92802a',
'rsrc/css/phui/phui-invisible-character-view.css' => '6993d9f0', 'rsrc/css/phui/phui-invisible-character-view.css' => '6993d9f0',
'rsrc/css/phui/phui-lightbox.css' => '0a035e40', 'rsrc/css/phui/phui-lightbox.css' => '0a035e40',
'rsrc/css/phui/phui-list.css' => 'a3ec3cf1', 'rsrc/css/phui/phui-list.css' => '12eb8ce6',
'rsrc/css/phui/phui-object-box.css' => '8b289e3d', 'rsrc/css/phui/phui-object-box.css' => '8b289e3d',
'rsrc/css/phui/phui-pager.css' => '77d8a794', 'rsrc/css/phui/phui-pager.css' => '77d8a794',
'rsrc/css/phui/phui-pinboard-view.css' => '2495140e', 'rsrc/css/phui/phui-pinboard-view.css' => '2495140e',
@ -166,8 +166,8 @@ return array(
'rsrc/css/phui/phui-segment-bar-view.css' => 'b1d1b892', 'rsrc/css/phui/phui-segment-bar-view.css' => 'b1d1b892',
'rsrc/css/phui/phui-spacing.css' => '042804d6', 'rsrc/css/phui/phui-spacing.css' => '042804d6',
'rsrc/css/phui/phui-status.css' => 'd5263e49', 'rsrc/css/phui/phui-status.css' => 'd5263e49',
'rsrc/css/phui/phui-tag-view.css' => '84d65f26', 'rsrc/css/phui/phui-tag-view.css' => 'cc4fd402',
'rsrc/css/phui/phui-timeline-view.css' => 'bf45789e', 'rsrc/css/phui/phui-timeline-view.css' => '1d7ef61d',
'rsrc/css/phui/phui-two-column-view.css' => 'ce9fa0b7', 'rsrc/css/phui/phui-two-column-view.css' => 'ce9fa0b7',
'rsrc/css/phui/workboards/phui-workboard-color.css' => '783cdff5', 'rsrc/css/phui/workboards/phui-workboard-color.css' => '783cdff5',
'rsrc/css/phui/workboards/phui-workboard.css' => '3bc85455', 'rsrc/css/phui/workboards/phui-workboard.css' => '3bc85455',
@ -375,7 +375,7 @@ return array(
'rsrc/js/application/conpherence/behavior-durable-column.js' => 'aa3bd034', 'rsrc/js/application/conpherence/behavior-durable-column.js' => 'aa3bd034',
'rsrc/js/application/conpherence/behavior-menu.js' => '7524fcfa', 'rsrc/js/application/conpherence/behavior-menu.js' => '7524fcfa',
'rsrc/js/application/conpherence/behavior-participant-pane.js' => '8604caa8', 'rsrc/js/application/conpherence/behavior-participant-pane.js' => '8604caa8',
'rsrc/js/application/conpherence/behavior-pontificate.js' => 'f2e58483', 'rsrc/js/application/conpherence/behavior-pontificate.js' => '55616e04',
'rsrc/js/application/conpherence/behavior-quicksand-blacklist.js' => '7927a7d3', 'rsrc/js/application/conpherence/behavior-quicksand-blacklist.js' => '7927a7d3',
'rsrc/js/application/conpherence/behavior-toggle-widget.js' => '3dbf94d5', 'rsrc/js/application/conpherence/behavior-toggle-widget.js' => '3dbf94d5',
'rsrc/js/application/countdown/timer.js' => 'e4cc26b3', 'rsrc/js/application/countdown/timer.js' => 'e4cc26b3',
@ -472,7 +472,7 @@ return array(
'rsrc/js/core/KeyboardShortcutManager.js' => '4a021c10', 'rsrc/js/core/KeyboardShortcutManager.js' => '4a021c10',
'rsrc/js/core/MultirowRowManager.js' => 'b5d57730', 'rsrc/js/core/MultirowRowManager.js' => 'b5d57730',
'rsrc/js/core/Notification.js' => 'ccf1cbf8', 'rsrc/js/core/Notification.js' => 'ccf1cbf8',
'rsrc/js/core/Prefab.js' => '8d40ae75', 'rsrc/js/core/Prefab.js' => 'c5af80a2',
'rsrc/js/core/ShapedRequest.js' => '7cbe244b', 'rsrc/js/core/ShapedRequest.js' => '7cbe244b',
'rsrc/js/core/TextAreaUtils.js' => '320810c8', 'rsrc/js/core/TextAreaUtils.js' => '320810c8',
'rsrc/js/core/Title.js' => '485aaa6c', 'rsrc/js/core/Title.js' => '485aaa6c',
@ -503,14 +503,14 @@ return array(
'rsrc/js/core/behavior-object-selector.js' => 'e0ec7f2f', 'rsrc/js/core/behavior-object-selector.js' => 'e0ec7f2f',
'rsrc/js/core/behavior-oncopy.js' => '2926fff2', 'rsrc/js/core/behavior-oncopy.js' => '2926fff2',
'rsrc/js/core/behavior-phabricator-nav.js' => '08675c6d', 'rsrc/js/core/behavior-phabricator-nav.js' => '08675c6d',
'rsrc/js/core/behavior-phabricator-remarkup-assist.js' => 'a0777ea3', 'rsrc/js/core/behavior-phabricator-remarkup-assist.js' => '0ca788bd',
'rsrc/js/core/behavior-read-only-warning.js' => 'ba158207', 'rsrc/js/core/behavior-read-only-warning.js' => 'ba158207',
'rsrc/js/core/behavior-refresh-csrf.js' => 'ab2f381b', 'rsrc/js/core/behavior-refresh-csrf.js' => 'ab2f381b',
'rsrc/js/core/behavior-remarkup-preview.js' => '4b700e9e', 'rsrc/js/core/behavior-remarkup-preview.js' => '4b700e9e',
'rsrc/js/core/behavior-reorder-applications.js' => '76b9fc3e', 'rsrc/js/core/behavior-reorder-applications.js' => '76b9fc3e',
'rsrc/js/core/behavior-reveal-content.js' => '60821bc7', 'rsrc/js/core/behavior-reveal-content.js' => '60821bc7',
'rsrc/js/core/behavior-scrollbar.js' => '834a1173', 'rsrc/js/core/behavior-scrollbar.js' => '834a1173',
'rsrc/js/core/behavior-search-typeahead.js' => '06c32383', 'rsrc/js/core/behavior-search-typeahead.js' => '0f2a0820',
'rsrc/js/core/behavior-select-content.js' => 'bf5374ef', 'rsrc/js/core/behavior-select-content.js' => 'bf5374ef',
'rsrc/js/core/behavior-select-on-click.js' => '4e3e79a6', 'rsrc/js/core/behavior-select-on-click.js' => '4e3e79a6',
'rsrc/js/core/behavior-setup-check-https.js' => '491416b3', 'rsrc/js/core/behavior-setup-check-https.js' => '491416b3',
@ -528,7 +528,7 @@ return array(
'rsrc/js/phui/behavior-phui-tab-group.js' => '0a0b10e9', 'rsrc/js/phui/behavior-phui-tab-group.js' => '0a0b10e9',
'rsrc/js/phuix/PHUIXActionListView.js' => 'b5c256b8', 'rsrc/js/phuix/PHUIXActionListView.js' => 'b5c256b8',
'rsrc/js/phuix/PHUIXActionView.js' => 'b3465b9b', 'rsrc/js/phuix/PHUIXActionView.js' => 'b3465b9b',
'rsrc/js/phuix/PHUIXAutocomplete.js' => 'd5b2abf3', 'rsrc/js/phuix/PHUIXAutocomplete.js' => 'd713a2c5',
'rsrc/js/phuix/PHUIXDropdownMenu.js' => '8018ee50', 'rsrc/js/phuix/PHUIXDropdownMenu.js' => '8018ee50',
'rsrc/js/phuix/PHUIXFormControl.js' => '83e03671', 'rsrc/js/phuix/PHUIXFormControl.js' => '83e03671',
'rsrc/js/phuix/PHUIXIconView.js' => 'bff6884b', 'rsrc/js/phuix/PHUIXIconView.js' => 'bff6884b',
@ -552,11 +552,11 @@ return array(
'conduit-api-css' => '7bc725c4', 'conduit-api-css' => '7bc725c4',
'config-options-css' => '0ede4c9b', 'config-options-css' => '0ede4c9b',
'config-page-css' => 'c1d5121b', 'config-page-css' => 'c1d5121b',
'conpherence-durable-column-view' => '292c71f0', 'conpherence-durable-column-view' => '89ea6bef',
'conpherence-header-pane-css' => '4082233d', 'conpherence-header-pane-css' => '4082233d',
'conpherence-menu-css' => '3d8e5c9c', 'conpherence-menu-css' => '3d8e5c9c',
'conpherence-message-pane-css' => 'd1fc13e1', 'conpherence-message-pane-css' => 'd1fc13e1',
'conpherence-notification-css' => '965db05b', 'conpherence-notification-css' => 'cef0a3fc',
'conpherence-participant-pane-css' => '604a8b02', 'conpherence-participant-pane-css' => '604a8b02',
'conpherence-thread-manager' => 'c8b5ee6f', 'conpherence-thread-manager' => 'c8b5ee6f',
'conpherence-transaction-css' => '85129c68', 'conpherence-transaction-css' => '85129c68',
@ -600,7 +600,7 @@ return array(
'javelin-behavior-config-reorder-fields' => 'b6993408', 'javelin-behavior-config-reorder-fields' => 'b6993408',
'javelin-behavior-conpherence-menu' => '7524fcfa', 'javelin-behavior-conpherence-menu' => '7524fcfa',
'javelin-behavior-conpherence-participant-pane' => '8604caa8', 'javelin-behavior-conpherence-participant-pane' => '8604caa8',
'javelin-behavior-conpherence-pontificate' => 'f2e58483', 'javelin-behavior-conpherence-pontificate' => '55616e04',
'javelin-behavior-conpherence-search' => '9bbf3762', 'javelin-behavior-conpherence-search' => '9bbf3762',
'javelin-behavior-countdown-timer' => 'e4cc26b3', 'javelin-behavior-countdown-timer' => 'e4cc26b3',
'javelin-behavior-dark-console' => 'f411b6ae', 'javelin-behavior-dark-console' => 'f411b6ae',
@ -664,9 +664,9 @@ return array(
'javelin-behavior-phabricator-notification-example' => '8ce821c5', 'javelin-behavior-phabricator-notification-example' => '8ce821c5',
'javelin-behavior-phabricator-object-selector' => 'e0ec7f2f', 'javelin-behavior-phabricator-object-selector' => 'e0ec7f2f',
'javelin-behavior-phabricator-oncopy' => '2926fff2', 'javelin-behavior-phabricator-oncopy' => '2926fff2',
'javelin-behavior-phabricator-remarkup-assist' => 'a0777ea3', 'javelin-behavior-phabricator-remarkup-assist' => '0ca788bd',
'javelin-behavior-phabricator-reveal-content' => '60821bc7', 'javelin-behavior-phabricator-reveal-content' => '60821bc7',
'javelin-behavior-phabricator-search-typeahead' => '06c32383', 'javelin-behavior-phabricator-search-typeahead' => '0f2a0820',
'javelin-behavior-phabricator-show-older-transactions' => '94c65b72', 'javelin-behavior-phabricator-show-older-transactions' => '94c65b72',
'javelin-behavior-phabricator-tooltips' => 'c420b0b9', 'javelin-behavior-phabricator-tooltips' => 'c420b0b9',
'javelin-behavior-phabricator-transaction-comment-form' => 'b23b49e6', 'javelin-behavior-phabricator-transaction-comment-form' => 'b23b49e6',
@ -792,13 +792,13 @@ return array(
'phabricator-notification-menu-css' => '6a697e43', 'phabricator-notification-menu-css' => '6a697e43',
'phabricator-object-selector-css' => '85ee8ce6', 'phabricator-object-selector-css' => '85ee8ce6',
'phabricator-phtize' => 'd254d646', 'phabricator-phtize' => 'd254d646',
'phabricator-prefab' => '8d40ae75', 'phabricator-prefab' => 'c5af80a2',
'phabricator-remarkup-css' => '17c0fb37', 'phabricator-remarkup-css' => '17c0fb37',
'phabricator-search-results-css' => '64ad079a', 'phabricator-search-results-css' => 'f87d23ad',
'phabricator-shaped-request' => '7cbe244b', 'phabricator-shaped-request' => '7cbe244b',
'phabricator-slowvote-css' => 'a94b7230', 'phabricator-slowvote-css' => 'a94b7230',
'phabricator-source-code-view-css' => '4383192f', 'phabricator-source-code-view-css' => '4383192f',
'phabricator-standard-page-view' => '894d8a25', 'phabricator-standard-page-view' => '89da5a9c',
'phabricator-textareautils' => '320810c8', 'phabricator-textareautils' => '320810c8',
'phabricator-title' => '485aaa6c', 'phabricator-title' => '485aaa6c',
'phabricator-tooltip' => '8fadb715', 'phabricator-tooltip' => '8fadb715',
@ -829,24 +829,24 @@ return array(
'phui-basic-nav-view-css' => 'a0705f53', 'phui-basic-nav-view-css' => 'a0705f53',
'phui-big-info-view-css' => 'bd903741', 'phui-big-info-view-css' => 'bd903741',
'phui-box-css' => '269cbc99', 'phui-box-css' => '269cbc99',
'phui-button-css' => '14bfba79', 'phui-button-css' => '96787bae',
'phui-calendar-css' => '477acfaa', 'phui-calendar-css' => '477acfaa',
'phui-calendar-day-css' => '572b1893', 'phui-calendar-day-css' => '572b1893',
'phui-calendar-list-css' => '576be600', 'phui-calendar-list-css' => '576be600',
'phui-calendar-month-css' => '8e10e92c', 'phui-calendar-month-css' => '8e10e92c',
'phui-chart-css' => '6bf6f78e', 'phui-chart-css' => '6bf6f78e',
'phui-cms-css' => '504b4b23', 'phui-cms-css' => '504b4b23',
'phui-comment-form-css' => '7d903c2d', 'phui-comment-form-css' => '57af2e14',
'phui-comment-panel-css' => 'f50152ad', 'phui-comment-panel-css' => 'f50152ad',
'phui-crumbs-view-css' => '6ece3bbb', 'phui-crumbs-view-css' => '6ece3bbb',
'phui-curtain-view-css' => '947bf1a4', 'phui-curtain-view-css' => '679743bb',
'phui-document-summary-view-css' => '9ca48bdf', 'phui-document-summary-view-css' => '9ca48bdf',
'phui-document-view-css' => 'c32e8dec', 'phui-document-view-css' => 'c32e8dec',
'phui-document-view-pro-css' => 'f56738ed', 'phui-document-view-pro-css' => 'f56738ed',
'phui-feed-story-css' => '44a9c8e9', 'phui-feed-story-css' => '44a9c8e9',
'phui-font-icon-base-css' => '870a7360', 'phui-font-icon-base-css' => '870a7360',
'phui-fontkit-css' => '1320ed01', 'phui-fontkit-css' => '1320ed01',
'phui-form-css' => 'b62c01d8', 'phui-form-css' => 'a5570f70',
'phui-form-view-css' => '6175808d', 'phui-form-view-css' => '6175808d',
'phui-head-thing-view-css' => 'fd311e5f', 'phui-head-thing-view-css' => 'fd311e5f',
'phui-header-view-css' => '9cf828ce', 'phui-header-view-css' => '9cf828ce',
@ -860,7 +860,7 @@ return array(
'phui-inline-comment-view-css' => 'be663c95', 'phui-inline-comment-view-css' => 'be663c95',
'phui-invisible-character-view-css' => '6993d9f0', 'phui-invisible-character-view-css' => '6993d9f0',
'phui-lightbox-css' => '0a035e40', 'phui-lightbox-css' => '0a035e40',
'phui-list-view-css' => 'a3ec3cf1', 'phui-list-view-css' => '12eb8ce6',
'phui-object-box-css' => '8b289e3d', 'phui-object-box-css' => '8b289e3d',
'phui-oi-big-ui-css' => '19f9369b', 'phui-oi-big-ui-css' => '19f9369b',
'phui-oi-color-css' => 'cd2b9b77', 'phui-oi-color-css' => 'cd2b9b77',
@ -875,9 +875,9 @@ return array(
'phui-segment-bar-view-css' => 'b1d1b892', 'phui-segment-bar-view-css' => 'b1d1b892',
'phui-spacing-css' => '042804d6', 'phui-spacing-css' => '042804d6',
'phui-status-list-view-css' => 'd5263e49', 'phui-status-list-view-css' => 'd5263e49',
'phui-tag-view-css' => '84d65f26', 'phui-tag-view-css' => 'cc4fd402',
'phui-theme-css' => '9f261c6b', 'phui-theme-css' => '9f261c6b',
'phui-timeline-view-css' => 'bf45789e', 'phui-timeline-view-css' => '1d7ef61d',
'phui-two-column-view-css' => 'ce9fa0b7', 'phui-two-column-view-css' => 'ce9fa0b7',
'phui-workboard-color-css' => '783cdff5', 'phui-workboard-color-css' => '783cdff5',
'phui-workboard-view-css' => '3bc85455', 'phui-workboard-view-css' => '3bc85455',
@ -885,7 +885,7 @@ return array(
'phui-workpanel-view-css' => 'a3a63478', 'phui-workpanel-view-css' => 'a3a63478',
'phuix-action-list-view' => 'b5c256b8', 'phuix-action-list-view' => 'b5c256b8',
'phuix-action-view' => 'b3465b9b', 'phuix-action-view' => 'b3465b9b',
'phuix-autocomplete' => 'd5b2abf3', 'phuix-autocomplete' => 'd713a2c5',
'phuix-dropdown-menu' => '8018ee50', 'phuix-dropdown-menu' => '8018ee50',
'phuix-form-control-view' => '83e03671', 'phuix-form-control-view' => '83e03671',
'phuix-icon-view' => 'bff6884b', 'phuix-icon-view' => 'bff6884b',
@ -943,17 +943,6 @@ return array(
'javelin-stratcom', 'javelin-stratcom',
'javelin-workflow', 'javelin-workflow',
), ),
'06c32383' => array(
'javelin-behavior',
'javelin-typeahead-ondemand-source',
'javelin-typeahead',
'javelin-dom',
'javelin-uri',
'javelin-util',
'javelin-stratcom',
'phabricator-prefab',
'phuix-icon-view',
),
'0825c27a' => array( '0825c27a' => array(
'javelin-behavior', 'javelin-behavior',
'javelin-dom', 'javelin-dom',
@ -988,6 +977,28 @@ return array(
'javelin-dom', 'javelin-dom',
'javelin-router', 'javelin-router',
), ),
'0ca788bd' => array(
'javelin-behavior',
'javelin-stratcom',
'javelin-dom',
'phabricator-phtize',
'phabricator-textareautils',
'javelin-workflow',
'javelin-vector',
'phuix-autocomplete',
'javelin-mask',
),
'0f2a0820' => array(
'javelin-behavior',
'javelin-typeahead-ondemand-source',
'javelin-typeahead',
'javelin-dom',
'javelin-uri',
'javelin-util',
'javelin-stratcom',
'phabricator-prefab',
'phuix-icon-view',
),
'0f764c35' => array( '0f764c35' => array(
'javelin-install', 'javelin-install',
'javelin-util', 'javelin-util',
@ -1298,6 +1309,14 @@ return array(
'javelin-request', 'javelin-request',
'javelin-typeahead-source', 'javelin-typeahead-source',
), ),
'55616e04' => array(
'javelin-behavior',
'javelin-dom',
'javelin-util',
'javelin-workflow',
'javelin-stratcom',
'conpherence-thread-manager',
),
'558829c2' => array( '558829c2' => array(
'javelin-stratcom', 'javelin-stratcom',
'javelin-behavior', 'javelin-behavior',
@ -1569,18 +1588,6 @@ return array(
'javelin-stratcom', 'javelin-stratcom',
'javelin-install', 'javelin-install',
), ),
'8d40ae75' => array(
'javelin-install',
'javelin-util',
'javelin-dom',
'javelin-typeahead',
'javelin-tokenizer',
'javelin-typeahead-preloaded-source',
'javelin-typeahead-ondemand-source',
'javelin-dom',
'javelin-stratcom',
'javelin-util',
),
'8fadb715' => array( '8fadb715' => array(
'javelin-install', 'javelin-install',
'javelin-util', 'javelin-util',
@ -1686,17 +1693,6 @@ return array(
'javelin-dom', 'javelin-dom',
'javelin-vector', 'javelin-vector',
), ),
'a0777ea3' => array(
'javelin-behavior',
'javelin-stratcom',
'javelin-dom',
'phabricator-phtize',
'phabricator-textareautils',
'javelin-workflow',
'javelin-vector',
'phuix-autocomplete',
'javelin-mask',
),
'a0b57eb8' => array( 'a0b57eb8' => array(
'javelin-behavior', 'javelin-behavior',
'javelin-dom', 'javelin-dom',
@ -1947,6 +1943,18 @@ return array(
'c587b80f' => array( 'c587b80f' => array(
'javelin-install', 'javelin-install',
), ),
'c5af80a2' => array(
'javelin-install',
'javelin-util',
'javelin-dom',
'javelin-typeahead',
'javelin-tokenizer',
'javelin-typeahead-preloaded-source',
'javelin-typeahead-ondemand-source',
'javelin-dom',
'javelin-stratcom',
'javelin-util',
),
'c7ccd872' => array( 'c7ccd872' => array(
'phui-fontkit-css', 'phui-fontkit-css',
), ),
@ -2047,12 +2055,6 @@ return array(
'javelin-uri', 'javelin-uri',
'phabricator-notification', 'phabricator-notification',
), ),
'd5b2abf3' => array(
'javelin-install',
'javelin-dom',
'phuix-icon-view',
'phabricator-prefab',
),
'd6a7e717' => array( 'd6a7e717' => array(
'multirow-row-manager', 'multirow-row-manager',
'javelin-install', 'javelin-install',
@ -2062,6 +2064,12 @@ return array(
'javelin-json', 'javelin-json',
'phabricator-prefab', 'phabricator-prefab',
), ),
'd713a2c5' => array(
'javelin-install',
'javelin-dom',
'phuix-icon-view',
'phabricator-prefab',
),
'd7a74243' => array( 'd7a74243' => array(
'javelin-behavior', 'javelin-behavior',
'javelin-stratcom', 'javelin-stratcom',
@ -2165,14 +2173,6 @@ return array(
'f12cbc9f' => array( 'f12cbc9f' => array(
'phui-oi-list-view-css', 'phui-oi-list-view-css',
), ),
'f2e58483' => array(
'javelin-behavior',
'javelin-dom',
'javelin-util',
'javelin-workflow',
'javelin-stratcom',
'conpherence-thread-manager',
),
'f411b6ae' => array( 'f411b6ae' => array(
'javelin-behavior', 'javelin-behavior',
'javelin-stratcom', 'javelin-stratcom',

View file

@ -0,0 +1,42 @@
<?php
// See T12488. Some events survived "20161004.cal.01.noepoch.php" without
// having "utcInstanceEpoch" computed, which breaks ICS export. This appears
// to be the result of some bug which has been fixed in the meantime, so just
// redo this part of the migration.
$table = new PhabricatorCalendarEvent();
$conn = $table->establishConnection('w');
$table_name = $table->getTableName();
$viewer = PhabricatorUser::getOmnipotentUser();
$all_events = id(new PhabricatorCalendarEventQuery())
->setViewer($viewer)
->execute();
foreach ($all_events as $event) {
$id = $event->getID();
if (!$event->getInstanceOfEventPHID()) {
// Not a child event, so no instance epoch.
continue;
}
if ($event->getUTCInstanceEpoch()) {
// Already has an instance epoch.
continue;
}
try {
$event->updateUTCEpochs();
} catch (Exception $ex) {
phlog($ex);
continue;
}
queryfx(
$conn,
'UPDATE %T SET utcInstanceEpoch = %nd WHERE id = %d',
$table_name,
$event->getUTCInstanceEpoch(),
$id);
}

View file

@ -0,0 +1,2 @@
DELETE FROM {$NAMESPACE}_conpherence.conpherence_transaction
WHERE transactionType = 'picture-crop';

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_conpherence.conpherence_thread
DROP COLUMN recentParticipantPHIDs;

View file

@ -0,0 +1,543 @@
a's
able
about
above
according
accordingly
across
actually
after
afterwards
again
against
ain't
all
allow
allows
almost
alone
along
already
also
although
always
am
among
amongst
an
and
another
any
anybody
anyhow
anyone
anything
anyway
anyways
anywhere
apart
appear
appreciate
appropriate
are
aren't
around
as
aside
ask
asking
associated
at
available
away
awfully
be
became
because
become
becomes
becoming
been
before
beforehand
behind
being
believe
below
beside
besides
best
better
between
beyond
both
brief
but
by
c'mon
c's
came
can
can't
cannot
cant
cause
causes
certain
certainly
changes
clearly
co
com
come
comes
concerning
consequently
consider
considering
contain
containing
contains
corresponding
could
couldn't
course
currently
definitely
described
despite
did
didn't
different
do
does
doesn't
doing
don't
done
down
downwards
during
each
edu
eg
eight
either
else
elsewhere
enough
entirely
especially
et
etc
even
ever
every
everybody
everyone
everything
everywhere
ex
exactly
example
except
far
few
fifth
first
five
followed
following
follows
for
former
formerly
forth
four
from
further
furthermore
get
gets
getting
given
gives
go
goes
going
gone
got
gotten
greetings
had
hadn't
happens
hardly
has
hasn't
have
haven't
having
he
he's
hello
help
hence
her
here
here's
hereafter
hereby
herein
hereupon
hers
herself
hi
him
himself
his
hither
hopefully
how
howbeit
however
i'd
i'll
i'm
i've
ie
if
ignored
immediate
in
inasmuch
inc
indeed
indicate
indicated
indicates
inner
insofar
instead
into
inward
is
isn't
it
it'd
it'll
it's
its
itself
just
keep
keeps
kept
know
known
knows
last
lately
later
latter
latterly
least
less
lest
let
let's
like
liked
likely
little
look
looking
looks
ltd
mainly
many
may
maybe
me
mean
meanwhile
merely
might
more
moreover
most
mostly
much
must
my
myself
name
namely
nd
near
nearly
necessary
need
needs
neither
never
nevertheless
new
next
nine
no
nobody
non
none
noone
nor
normally
not
nothing
novel
now
nowhere
obviously
of
off
often
oh
ok
okay
old
on
once
one
ones
only
onto
or
other
others
otherwise
ought
our
ours
ourselves
out
outside
over
overall
own
particular
particularly
per
perhaps
placed
please
plus
possible
presumably
probably
provides
que
quite
qv
rather
rd
re
really
reasonably
regarding
regardless
regards
relatively
respectively
right
said
same
saw
say
saying
says
second
secondly
see
seeing
seem
seemed
seeming
seems
seen
self
selves
sensible
sent
serious
seriously
seven
several
shall
she
should
shouldn't
since
six
so
some
somebody
somehow
someone
something
sometime
sometimes
somewhat
somewhere
soon
sorry
specified
specify
specifying
still
sub
such
sup
sure
t's
take
taken
tell
tends
th
than
thank
thanks
thanx
that
that's
thats
the
their
theirs
them
themselves
then
thence
there
there's
thereafter
thereby
therefore
therein
theres
thereupon
these
they
they'd
they'll
they're
they've
think
third
this
thorough
thoroughly
those
though
three
through
throughout
thru
thus
to
together
too
took
toward
towards
tried
tries
truly
try
trying
twice
two
un
under
unfortunately
unless
unlikely
until
unto
up
upon
us
use
used
useful
uses
using
usually
value
various
very
via
viz
vs
want
wants
was
wasn't
way
we
we'd
we'll
we're
we've
welcome
well
went
were
weren't
what
what's
whatever
when
whence
whenever
where
where's
whereafter
whereas
whereby
wherein
whereupon
wherever
whether
which
while
whither
who
who's
whoever
whole
whom
whose
why
will
willing
wish
with
within
without
won't
wonder
would
wouldn't
yes
yet
you
you'd
you'll
you're
you've
your
yours
yourself
yourselves
zero

View file

@ -316,15 +316,20 @@ phutil_register_library_map(array(
'ConpherenceTestCase' => 'applications/conpherence/__tests__/ConpherenceTestCase.php', 'ConpherenceTestCase' => 'applications/conpherence/__tests__/ConpherenceTestCase.php',
'ConpherenceThread' => 'applications/conpherence/storage/ConpherenceThread.php', 'ConpherenceThread' => 'applications/conpherence/storage/ConpherenceThread.php',
'ConpherenceThreadDatasource' => 'applications/conpherence/typeahead/ConpherenceThreadDatasource.php', 'ConpherenceThreadDatasource' => 'applications/conpherence/typeahead/ConpherenceThreadDatasource.php',
'ConpherenceThreadDateMarkerTransaction' => 'applications/conpherence/xaction/ConpherenceThreadDateMarkerTransaction.php',
'ConpherenceThreadIndexEngineExtension' => 'applications/conpherence/engineextension/ConpherenceThreadIndexEngineExtension.php', 'ConpherenceThreadIndexEngineExtension' => 'applications/conpherence/engineextension/ConpherenceThreadIndexEngineExtension.php',
'ConpherenceThreadListView' => 'applications/conpherence/view/ConpherenceThreadListView.php', 'ConpherenceThreadListView' => 'applications/conpherence/view/ConpherenceThreadListView.php',
'ConpherenceThreadMailReceiver' => 'applications/conpherence/mail/ConpherenceThreadMailReceiver.php', 'ConpherenceThreadMailReceiver' => 'applications/conpherence/mail/ConpherenceThreadMailReceiver.php',
'ConpherenceThreadMembersPolicyRule' => 'applications/conpherence/policyrule/ConpherenceThreadMembersPolicyRule.php', 'ConpherenceThreadMembersPolicyRule' => 'applications/conpherence/policyrule/ConpherenceThreadMembersPolicyRule.php',
'ConpherenceThreadPictureTransaction' => 'applications/conpherence/xaction/ConpherenceThreadPictureTransaction.php',
'ConpherenceThreadQuery' => 'applications/conpherence/query/ConpherenceThreadQuery.php', 'ConpherenceThreadQuery' => 'applications/conpherence/query/ConpherenceThreadQuery.php',
'ConpherenceThreadRemarkupRule' => 'applications/conpherence/remarkup/ConpherenceThreadRemarkupRule.php', 'ConpherenceThreadRemarkupRule' => 'applications/conpherence/remarkup/ConpherenceThreadRemarkupRule.php',
'ConpherenceThreadSearchController' => 'applications/conpherence/controller/ConpherenceThreadSearchController.php', 'ConpherenceThreadSearchController' => 'applications/conpherence/controller/ConpherenceThreadSearchController.php',
'ConpherenceThreadSearchEngine' => 'applications/conpherence/query/ConpherenceThreadSearchEngine.php', 'ConpherenceThreadSearchEngine' => 'applications/conpherence/query/ConpherenceThreadSearchEngine.php',
'ConpherenceThreadTitleNgrams' => 'applications/conpherence/storage/ConpherenceThreadTitleNgrams.php', 'ConpherenceThreadTitleNgrams' => 'applications/conpherence/storage/ConpherenceThreadTitleNgrams.php',
'ConpherenceThreadTitleTransaction' => 'applications/conpherence/xaction/ConpherenceThreadTitleTransaction.php',
'ConpherenceThreadTopicTransaction' => 'applications/conpherence/xaction/ConpherenceThreadTopicTransaction.php',
'ConpherenceThreadTransactionType' => 'applications/conpherence/xaction/ConpherenceThreadTransactionType.php',
'ConpherenceTransaction' => 'applications/conpherence/storage/ConpherenceTransaction.php', 'ConpherenceTransaction' => 'applications/conpherence/storage/ConpherenceTransaction.php',
'ConpherenceTransactionComment' => 'applications/conpherence/storage/ConpherenceTransactionComment.php', 'ConpherenceTransactionComment' => 'applications/conpherence/storage/ConpherenceTransactionComment.php',
'ConpherenceTransactionQuery' => 'applications/conpherence/query/ConpherenceTransactionQuery.php', 'ConpherenceTransactionQuery' => 'applications/conpherence/query/ConpherenceTransactionQuery.php',
@ -334,6 +339,8 @@ phutil_register_library_map(array(
'ConpherenceUpdateController' => 'applications/conpherence/controller/ConpherenceUpdateController.php', 'ConpherenceUpdateController' => 'applications/conpherence/controller/ConpherenceUpdateController.php',
'ConpherenceUpdateThreadConduitAPIMethod' => 'applications/conpherence/conduit/ConpherenceUpdateThreadConduitAPIMethod.php', 'ConpherenceUpdateThreadConduitAPIMethod' => 'applications/conpherence/conduit/ConpherenceUpdateThreadConduitAPIMethod.php',
'ConpherenceViewController' => 'applications/conpherence/controller/ConpherenceViewController.php', 'ConpherenceViewController' => 'applications/conpherence/controller/ConpherenceViewController.php',
'CountdownEditConduitAPIMethod' => 'applications/countdown/conduit/CountdownEditConduitAPIMethod.php',
'CountdownSearchConduitAPIMethod' => 'applications/countdown/conduit/CountdownSearchConduitAPIMethod.php',
'DarkConsoleController' => 'applications/console/controller/DarkConsoleController.php', 'DarkConsoleController' => 'applications/console/controller/DarkConsoleController.php',
'DarkConsoleCore' => 'applications/console/core/DarkConsoleCore.php', 'DarkConsoleCore' => 'applications/console/core/DarkConsoleCore.php',
'DarkConsoleDataController' => 'applications/console/controller/DarkConsoleDataController.php', 'DarkConsoleDataController' => 'applications/console/controller/DarkConsoleDataController.php',
@ -2366,6 +2373,7 @@ phutil_register_library_map(array(
'PhabricatorConfigPageView' => 'applications/config/view/PhabricatorConfigPageView.php', 'PhabricatorConfigPageView' => 'applications/config/view/PhabricatorConfigPageView.php',
'PhabricatorConfigProxySource' => 'infrastructure/env/PhabricatorConfigProxySource.php', 'PhabricatorConfigProxySource' => 'infrastructure/env/PhabricatorConfigProxySource.php',
'PhabricatorConfigPurgeCacheController' => 'applications/config/controller/PhabricatorConfigPurgeCacheController.php', 'PhabricatorConfigPurgeCacheController' => 'applications/config/controller/PhabricatorConfigPurgeCacheController.php',
'PhabricatorConfigRegexOptionType' => 'applications/config/custom/PhabricatorConfigRegexOptionType.php',
'PhabricatorConfigRequestExceptionHandlerModule' => 'applications/config/module/PhabricatorConfigRequestExceptionHandlerModule.php', 'PhabricatorConfigRequestExceptionHandlerModule' => 'applications/config/module/PhabricatorConfigRequestExceptionHandlerModule.php',
'PhabricatorConfigResponse' => 'applications/config/response/PhabricatorConfigResponse.php', 'PhabricatorConfigResponse' => 'applications/config/response/PhabricatorConfigResponse.php',
'PhabricatorConfigSchemaQuery' => 'applications/config/schema/PhabricatorConfigSchemaQuery.php', 'PhabricatorConfigSchemaQuery' => 'applications/config/schema/PhabricatorConfigSchemaQuery.php',
@ -2387,6 +2395,7 @@ phutil_register_library_map(array(
'PhabricatorConpherenceColumnVisibleSetting' => 'applications/settings/setting/PhabricatorConpherenceColumnVisibleSetting.php', 'PhabricatorConpherenceColumnVisibleSetting' => 'applications/settings/setting/PhabricatorConpherenceColumnVisibleSetting.php',
'PhabricatorConpherenceNotificationsSetting' => 'applications/settings/setting/PhabricatorConpherenceNotificationsSetting.php', 'PhabricatorConpherenceNotificationsSetting' => 'applications/settings/setting/PhabricatorConpherenceNotificationsSetting.php',
'PhabricatorConpherencePreferencesSettingsPanel' => 'applications/settings/panel/PhabricatorConpherencePreferencesSettingsPanel.php', 'PhabricatorConpherencePreferencesSettingsPanel' => 'applications/settings/panel/PhabricatorConpherencePreferencesSettingsPanel.php',
'PhabricatorConpherenceProfileMenuItem' => 'applications/search/menuitem/PhabricatorConpherenceProfileMenuItem.php',
'PhabricatorConpherenceThreadPHIDType' => 'applications/conpherence/phid/PhabricatorConpherenceThreadPHIDType.php', 'PhabricatorConpherenceThreadPHIDType' => 'applications/conpherence/phid/PhabricatorConpherenceThreadPHIDType.php',
'PhabricatorConpherenceWidgetVisibleSetting' => 'applications/settings/setting/PhabricatorConpherenceWidgetVisibleSetting.php', 'PhabricatorConpherenceWidgetVisibleSetting' => 'applications/settings/setting/PhabricatorConpherenceWidgetVisibleSetting.php',
'PhabricatorConsoleApplication' => 'applications/console/application/PhabricatorConsoleApplication.php', 'PhabricatorConsoleApplication' => 'applications/console/application/PhabricatorConsoleApplication.php',
@ -2408,10 +2417,11 @@ phutil_register_library_map(array(
'PhabricatorCountdownDAO' => 'applications/countdown/storage/PhabricatorCountdownDAO.php', 'PhabricatorCountdownDAO' => 'applications/countdown/storage/PhabricatorCountdownDAO.php',
'PhabricatorCountdownDefaultEditCapability' => 'applications/countdown/capability/PhabricatorCountdownDefaultEditCapability.php', 'PhabricatorCountdownDefaultEditCapability' => 'applications/countdown/capability/PhabricatorCountdownDefaultEditCapability.php',
'PhabricatorCountdownDefaultViewCapability' => 'applications/countdown/capability/PhabricatorCountdownDefaultViewCapability.php', 'PhabricatorCountdownDefaultViewCapability' => 'applications/countdown/capability/PhabricatorCountdownDefaultViewCapability.php',
'PhabricatorCountdownDeleteController' => 'applications/countdown/controller/PhabricatorCountdownDeleteController.php', 'PhabricatorCountdownDescriptionTransaction' => 'applications/countdown/xaction/PhabricatorCountdownDescriptionTransaction.php',
'PhabricatorCountdownEditController' => 'applications/countdown/controller/PhabricatorCountdownEditController.php', 'PhabricatorCountdownEditController' => 'applications/countdown/controller/PhabricatorCountdownEditController.php',
'PhabricatorCountdownEditEngine' => 'applications/countdown/editor/PhabricatorCountdownEditEngine.php', 'PhabricatorCountdownEditEngine' => 'applications/countdown/editor/PhabricatorCountdownEditEngine.php',
'PhabricatorCountdownEditor' => 'applications/countdown/editor/PhabricatorCountdownEditor.php', 'PhabricatorCountdownEditor' => 'applications/countdown/editor/PhabricatorCountdownEditor.php',
'PhabricatorCountdownEpochTransaction' => 'applications/countdown/xaction/PhabricatorCountdownEpochTransaction.php',
'PhabricatorCountdownListController' => 'applications/countdown/controller/PhabricatorCountdownListController.php', 'PhabricatorCountdownListController' => 'applications/countdown/controller/PhabricatorCountdownListController.php',
'PhabricatorCountdownMailReceiver' => 'applications/countdown/mail/PhabricatorCountdownMailReceiver.php', 'PhabricatorCountdownMailReceiver' => 'applications/countdown/mail/PhabricatorCountdownMailReceiver.php',
'PhabricatorCountdownQuery' => 'applications/countdown/query/PhabricatorCountdownQuery.php', 'PhabricatorCountdownQuery' => 'applications/countdown/query/PhabricatorCountdownQuery.php',
@ -2419,9 +2429,11 @@ phutil_register_library_map(array(
'PhabricatorCountdownReplyHandler' => 'applications/countdown/mail/PhabricatorCountdownReplyHandler.php', 'PhabricatorCountdownReplyHandler' => 'applications/countdown/mail/PhabricatorCountdownReplyHandler.php',
'PhabricatorCountdownSchemaSpec' => 'applications/countdown/storage/PhabricatorCountdownSchemaSpec.php', 'PhabricatorCountdownSchemaSpec' => 'applications/countdown/storage/PhabricatorCountdownSchemaSpec.php',
'PhabricatorCountdownSearchEngine' => 'applications/countdown/query/PhabricatorCountdownSearchEngine.php', 'PhabricatorCountdownSearchEngine' => 'applications/countdown/query/PhabricatorCountdownSearchEngine.php',
'PhabricatorCountdownTitleTransaction' => 'applications/countdown/xaction/PhabricatorCountdownTitleTransaction.php',
'PhabricatorCountdownTransaction' => 'applications/countdown/storage/PhabricatorCountdownTransaction.php', 'PhabricatorCountdownTransaction' => 'applications/countdown/storage/PhabricatorCountdownTransaction.php',
'PhabricatorCountdownTransactionComment' => 'applications/countdown/storage/PhabricatorCountdownTransactionComment.php', 'PhabricatorCountdownTransactionComment' => 'applications/countdown/storage/PhabricatorCountdownTransactionComment.php',
'PhabricatorCountdownTransactionQuery' => 'applications/countdown/query/PhabricatorCountdownTransactionQuery.php', 'PhabricatorCountdownTransactionQuery' => 'applications/countdown/query/PhabricatorCountdownTransactionQuery.php',
'PhabricatorCountdownTransactionType' => 'applications/countdown/xaction/PhabricatorCountdownTransactionType.php',
'PhabricatorCountdownView' => 'applications/countdown/view/PhabricatorCountdownView.php', 'PhabricatorCountdownView' => 'applications/countdown/view/PhabricatorCountdownView.php',
'PhabricatorCountdownViewController' => 'applications/countdown/controller/PhabricatorCountdownViewController.php', 'PhabricatorCountdownViewController' => 'applications/countdown/controller/PhabricatorCountdownViewController.php',
'PhabricatorCursorPagedPolicyAwareQuery' => 'infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php', 'PhabricatorCursorPagedPolicyAwareQuery' => 'infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php',
@ -2840,7 +2852,9 @@ phutil_register_library_map(array(
'PhabricatorFulltextEngineExtensionModule' => 'applications/search/index/PhabricatorFulltextEngineExtensionModule.php', 'PhabricatorFulltextEngineExtensionModule' => 'applications/search/index/PhabricatorFulltextEngineExtensionModule.php',
'PhabricatorFulltextIndexEngineExtension' => 'applications/search/engineextension/PhabricatorFulltextIndexEngineExtension.php', 'PhabricatorFulltextIndexEngineExtension' => 'applications/search/engineextension/PhabricatorFulltextIndexEngineExtension.php',
'PhabricatorFulltextInterface' => 'applications/search/interface/PhabricatorFulltextInterface.php', 'PhabricatorFulltextInterface' => 'applications/search/interface/PhabricatorFulltextInterface.php',
'PhabricatorFulltextResultSet' => 'applications/search/query/PhabricatorFulltextResultSet.php',
'PhabricatorFulltextStorageEngine' => 'applications/search/fulltextstorage/PhabricatorFulltextStorageEngine.php', 'PhabricatorFulltextStorageEngine' => 'applications/search/fulltextstorage/PhabricatorFulltextStorageEngine.php',
'PhabricatorFulltextToken' => 'applications/search/query/PhabricatorFulltextToken.php',
'PhabricatorFundApplication' => 'applications/fund/application/PhabricatorFundApplication.php', 'PhabricatorFundApplication' => 'applications/fund/application/PhabricatorFundApplication.php',
'PhabricatorGDSetupCheck' => 'applications/config/check/PhabricatorGDSetupCheck.php', 'PhabricatorGDSetupCheck' => 'applications/config/check/PhabricatorGDSetupCheck.php',
'PhabricatorGarbageCollector' => 'infrastructure/daemon/garbagecollector/PhabricatorGarbageCollector.php', 'PhabricatorGarbageCollector' => 'infrastructure/daemon/garbagecollector/PhabricatorGarbageCollector.php',
@ -3414,6 +3428,7 @@ phutil_register_library_map(array(
'PhabricatorPhortuneContentSource' => 'applications/phortune/contentsource/PhabricatorPhortuneContentSource.php', 'PhabricatorPhortuneContentSource' => 'applications/phortune/contentsource/PhabricatorPhortuneContentSource.php',
'PhabricatorPhortuneManagementInvoiceWorkflow' => 'applications/phortune/management/PhabricatorPhortuneManagementInvoiceWorkflow.php', 'PhabricatorPhortuneManagementInvoiceWorkflow' => 'applications/phortune/management/PhabricatorPhortuneManagementInvoiceWorkflow.php',
'PhabricatorPhortuneManagementWorkflow' => 'applications/phortune/management/PhabricatorPhortuneManagementWorkflow.php', 'PhabricatorPhortuneManagementWorkflow' => 'applications/phortune/management/PhabricatorPhortuneManagementWorkflow.php',
'PhabricatorPhortuneTestCase' => 'applications/phortune/__tests__/PhabricatorPhortuneTestCase.php',
'PhabricatorPhragmentApplication' => 'applications/phragment/application/PhabricatorPhragmentApplication.php', 'PhabricatorPhragmentApplication' => 'applications/phragment/application/PhabricatorPhragmentApplication.php',
'PhabricatorPhrequentApplication' => 'applications/phrequent/application/PhabricatorPhrequentApplication.php', 'PhabricatorPhrequentApplication' => 'applications/phrequent/application/PhabricatorPhrequentApplication.php',
'PhabricatorPhrictionApplication' => 'applications/phriction/application/PhabricatorPhrictionApplication.php', 'PhabricatorPhrictionApplication' => 'applications/phriction/application/PhabricatorPhrictionApplication.php',
@ -3940,6 +3955,7 @@ phutil_register_library_map(array(
'PhabricatorStorageManagementDatabasesWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementDatabasesWorkflow.php', 'PhabricatorStorageManagementDatabasesWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementDatabasesWorkflow.php',
'PhabricatorStorageManagementDestroyWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementDestroyWorkflow.php', 'PhabricatorStorageManagementDestroyWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementDestroyWorkflow.php',
'PhabricatorStorageManagementDumpWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementDumpWorkflow.php', 'PhabricatorStorageManagementDumpWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementDumpWorkflow.php',
'PhabricatorStorageManagementOptimizeWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementOptimizeWorkflow.php',
'PhabricatorStorageManagementPartitionWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementPartitionWorkflow.php', 'PhabricatorStorageManagementPartitionWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementPartitionWorkflow.php',
'PhabricatorStorageManagementProbeWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementProbeWorkflow.php', 'PhabricatorStorageManagementProbeWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementProbeWorkflow.php',
'PhabricatorStorageManagementQuickstartWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementQuickstartWorkflow.php', 'PhabricatorStorageManagementQuickstartWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementQuickstartWorkflow.php',
@ -4319,15 +4335,24 @@ phutil_register_library_map(array(
'PholioTransactionView' => 'applications/pholio/view/PholioTransactionView.php', 'PholioTransactionView' => 'applications/pholio/view/PholioTransactionView.php',
'PholioUploadedImageView' => 'applications/pholio/view/PholioUploadedImageView.php', 'PholioUploadedImageView' => 'applications/pholio/view/PholioUploadedImageView.php',
'PhortuneAccount' => 'applications/phortune/storage/PhortuneAccount.php', 'PhortuneAccount' => 'applications/phortune/storage/PhortuneAccount.php',
'PhortuneAccountAddManagerController' => 'applications/phortune/controller/account/PhortuneAccountAddManagerController.php',
'PhortuneAccountBillingController' => 'applications/phortune/controller/account/PhortuneAccountBillingController.php',
'PhortuneAccountChargeListController' => 'applications/phortune/controller/account/PhortuneAccountChargeListController.php', 'PhortuneAccountChargeListController' => 'applications/phortune/controller/account/PhortuneAccountChargeListController.php',
'PhortuneAccountController' => 'applications/phortune/controller/account/PhortuneAccountController.php',
'PhortuneAccountEditController' => 'applications/phortune/controller/account/PhortuneAccountEditController.php', 'PhortuneAccountEditController' => 'applications/phortune/controller/account/PhortuneAccountEditController.php',
'PhortuneAccountEditEngine' => 'applications/phortune/editor/PhortuneAccountEditEngine.php',
'PhortuneAccountEditor' => 'applications/phortune/editor/PhortuneAccountEditor.php', 'PhortuneAccountEditor' => 'applications/phortune/editor/PhortuneAccountEditor.php',
'PhortuneAccountHasMemberEdgeType' => 'applications/phortune/edge/PhortuneAccountHasMemberEdgeType.php', 'PhortuneAccountHasMemberEdgeType' => 'applications/phortune/edge/PhortuneAccountHasMemberEdgeType.php',
'PhortuneAccountListController' => 'applications/phortune/controller/account/PhortuneAccountListController.php', 'PhortuneAccountListController' => 'applications/phortune/controller/account/PhortuneAccountListController.php',
'PhortuneAccountManagerController' => 'applications/phortune/controller/account/PhortuneAccountManagerController.php',
'PhortuneAccountNameTransaction' => 'applications/phortune/xaction/PhortuneAccountNameTransaction.php',
'PhortuneAccountPHIDType' => 'applications/phortune/phid/PhortuneAccountPHIDType.php', 'PhortuneAccountPHIDType' => 'applications/phortune/phid/PhortuneAccountPHIDType.php',
'PhortuneAccountProfileController' => 'applications/phortune/controller/account/PhortuneAccountProfileController.php',
'PhortuneAccountQuery' => 'applications/phortune/query/PhortuneAccountQuery.php', 'PhortuneAccountQuery' => 'applications/phortune/query/PhortuneAccountQuery.php',
'PhortuneAccountSubscriptionController' => 'applications/phortune/controller/account/PhortuneAccountSubscriptionController.php',
'PhortuneAccountTransaction' => 'applications/phortune/storage/PhortuneAccountTransaction.php', 'PhortuneAccountTransaction' => 'applications/phortune/storage/PhortuneAccountTransaction.php',
'PhortuneAccountTransactionQuery' => 'applications/phortune/query/PhortuneAccountTransactionQuery.php', 'PhortuneAccountTransactionQuery' => 'applications/phortune/query/PhortuneAccountTransactionQuery.php',
'PhortuneAccountTransactionType' => 'applications/phortune/xaction/PhortuneAccountTransactionType.php',
'PhortuneAccountViewController' => 'applications/phortune/controller/account/PhortuneAccountViewController.php', 'PhortuneAccountViewController' => 'applications/phortune/controller/account/PhortuneAccountViewController.php',
'PhortuneAdHocCart' => 'applications/phortune/cart/PhortuneAdHocCart.php', 'PhortuneAdHocCart' => 'applications/phortune/cart/PhortuneAdHocCart.php',
'PhortuneAdHocProduct' => 'applications/phortune/product/PhortuneAdHocProduct.php', 'PhortuneAdHocProduct' => 'applications/phortune/product/PhortuneAdHocProduct.php',
@ -4365,20 +4390,30 @@ phutil_register_library_map(array(
'PhortuneMemberHasAccountEdgeType' => 'applications/phortune/edge/PhortuneMemberHasAccountEdgeType.php', 'PhortuneMemberHasAccountEdgeType' => 'applications/phortune/edge/PhortuneMemberHasAccountEdgeType.php',
'PhortuneMemberHasMerchantEdgeType' => 'applications/phortune/edge/PhortuneMemberHasMerchantEdgeType.php', 'PhortuneMemberHasMerchantEdgeType' => 'applications/phortune/edge/PhortuneMemberHasMerchantEdgeType.php',
'PhortuneMerchant' => 'applications/phortune/storage/PhortuneMerchant.php', 'PhortuneMerchant' => 'applications/phortune/storage/PhortuneMerchant.php',
'PhortuneMerchantAddManagerController' => 'applications/phortune/controller/merchant/PhortuneMerchantAddManagerController.php',
'PhortuneMerchantCapability' => 'applications/phortune/capability/PhortuneMerchantCapability.php', 'PhortuneMerchantCapability' => 'applications/phortune/capability/PhortuneMerchantCapability.php',
'PhortuneMerchantContactInfoTransaction' => 'applications/phortune/xaction/PhortuneMerchantContactInfoTransaction.php',
'PhortuneMerchantController' => 'applications/phortune/controller/merchant/PhortuneMerchantController.php', 'PhortuneMerchantController' => 'applications/phortune/controller/merchant/PhortuneMerchantController.php',
'PhortuneMerchantDescriptionTransaction' => 'applications/phortune/xaction/PhortuneMerchantDescriptionTransaction.php',
'PhortuneMerchantEditController' => 'applications/phortune/controller/merchant/PhortuneMerchantEditController.php', 'PhortuneMerchantEditController' => 'applications/phortune/controller/merchant/PhortuneMerchantEditController.php',
'PhortuneMerchantEditEngine' => 'applications/phortune/editor/PhortuneMerchantEditEngine.php', 'PhortuneMerchantEditEngine' => 'applications/phortune/editor/PhortuneMerchantEditEngine.php',
'PhortuneMerchantEditor' => 'applications/phortune/editor/PhortuneMerchantEditor.php', 'PhortuneMerchantEditor' => 'applications/phortune/editor/PhortuneMerchantEditor.php',
'PhortuneMerchantHasMemberEdgeType' => 'applications/phortune/edge/PhortuneMerchantHasMemberEdgeType.php', 'PhortuneMerchantHasMemberEdgeType' => 'applications/phortune/edge/PhortuneMerchantHasMemberEdgeType.php',
'PhortuneMerchantInvoiceCreateController' => 'applications/phortune/controller/merchant/PhortuneMerchantInvoiceCreateController.php', 'PhortuneMerchantInvoiceCreateController' => 'applications/phortune/controller/merchant/PhortuneMerchantInvoiceCreateController.php',
'PhortuneMerchantInvoiceEmailTransaction' => 'applications/phortune/xaction/PhortuneMerchantInvoiceEmailTransaction.php',
'PhortuneMerchantInvoiceFooterTransaction' => 'applications/phortune/xaction/PhortuneMerchantInvoiceFooterTransaction.php',
'PhortuneMerchantListController' => 'applications/phortune/controller/merchant/PhortuneMerchantListController.php', 'PhortuneMerchantListController' => 'applications/phortune/controller/merchant/PhortuneMerchantListController.php',
'PhortuneMerchantManagerController' => 'applications/phortune/controller/merchant/PhortuneMerchantManagerController.php',
'PhortuneMerchantNameTransaction' => 'applications/phortune/xaction/PhortuneMerchantNameTransaction.php',
'PhortuneMerchantPHIDType' => 'applications/phortune/phid/PhortuneMerchantPHIDType.php', 'PhortuneMerchantPHIDType' => 'applications/phortune/phid/PhortuneMerchantPHIDType.php',
'PhortuneMerchantPictureController' => 'applications/phortune/controller/merchant/PhortuneMerchantPictureController.php', 'PhortuneMerchantPictureController' => 'applications/phortune/controller/merchant/PhortuneMerchantPictureController.php',
'PhortuneMerchantPictureTransaction' => 'applications/phortune/xaction/PhortuneMerchantPictureTransaction.php',
'PhortuneMerchantProfileController' => 'applications/phortune/controller/merchant/PhortuneMerchantProfileController.php',
'PhortuneMerchantQuery' => 'applications/phortune/query/PhortuneMerchantQuery.php', 'PhortuneMerchantQuery' => 'applications/phortune/query/PhortuneMerchantQuery.php',
'PhortuneMerchantSearchEngine' => 'applications/phortune/query/PhortuneMerchantSearchEngine.php', 'PhortuneMerchantSearchEngine' => 'applications/phortune/query/PhortuneMerchantSearchEngine.php',
'PhortuneMerchantTransaction' => 'applications/phortune/storage/PhortuneMerchantTransaction.php', 'PhortuneMerchantTransaction' => 'applications/phortune/storage/PhortuneMerchantTransaction.php',
'PhortuneMerchantTransactionQuery' => 'applications/phortune/query/PhortuneMerchantTransactionQuery.php', 'PhortuneMerchantTransactionQuery' => 'applications/phortune/query/PhortuneMerchantTransactionQuery.php',
'PhortuneMerchantTransactionType' => 'applications/phortune/xaction/PhortuneMerchantTransactionType.php',
'PhortuneMerchantViewController' => 'applications/phortune/controller/merchant/PhortuneMerchantViewController.php', 'PhortuneMerchantViewController' => 'applications/phortune/controller/merchant/PhortuneMerchantViewController.php',
'PhortuneMonthYearExpiryControl' => 'applications/phortune/control/PhortuneMonthYearExpiryControl.php', 'PhortuneMonthYearExpiryControl' => 'applications/phortune/control/PhortuneMonthYearExpiryControl.php',
'PhortuneOrderTableView' => 'applications/phortune/view/PhortuneOrderTableView.php', 'PhortuneOrderTableView' => 'applications/phortune/view/PhortuneOrderTableView.php',
@ -4691,6 +4726,7 @@ phutil_register_library_map(array(
'javelin_tag' => 'infrastructure/javelin/markup.php', 'javelin_tag' => 'infrastructure/javelin/markup.php',
'phabricator_date' => 'view/viewutils.php', 'phabricator_date' => 'view/viewutils.php',
'phabricator_datetime' => 'view/viewutils.php', 'phabricator_datetime' => 'view/viewutils.php',
'phabricator_datetimezone' => 'view/viewutils.php',
'phabricator_form' => 'infrastructure/javelin/markup.php', 'phabricator_form' => 'infrastructure/javelin/markup.php',
'phabricator_format_local_time' => 'view/viewutils.php', 'phabricator_format_local_time' => 'view/viewutils.php',
'phabricator_relative_date' => 'view/viewutils.php', 'phabricator_relative_date' => 'view/viewutils.php',
@ -5075,16 +5111,21 @@ phutil_register_library_map(array(
'PhabricatorNgramsInterface', 'PhabricatorNgramsInterface',
), ),
'ConpherenceThreadDatasource' => 'PhabricatorTypeaheadDatasource', 'ConpherenceThreadDatasource' => 'PhabricatorTypeaheadDatasource',
'ConpherenceThreadDateMarkerTransaction' => 'ConpherenceThreadTransactionType',
'ConpherenceThreadIndexEngineExtension' => 'PhabricatorIndexEngineExtension', 'ConpherenceThreadIndexEngineExtension' => 'PhabricatorIndexEngineExtension',
'ConpherenceThreadListView' => 'AphrontView', 'ConpherenceThreadListView' => 'AphrontView',
'ConpherenceThreadMailReceiver' => 'PhabricatorObjectMailReceiver', 'ConpherenceThreadMailReceiver' => 'PhabricatorObjectMailReceiver',
'ConpherenceThreadMembersPolicyRule' => 'PhabricatorPolicyRule', 'ConpherenceThreadMembersPolicyRule' => 'PhabricatorPolicyRule',
'ConpherenceThreadPictureTransaction' => 'ConpherenceThreadTransactionType',
'ConpherenceThreadQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'ConpherenceThreadQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'ConpherenceThreadRemarkupRule' => 'PhabricatorObjectRemarkupRule', 'ConpherenceThreadRemarkupRule' => 'PhabricatorObjectRemarkupRule',
'ConpherenceThreadSearchController' => 'ConpherenceController', 'ConpherenceThreadSearchController' => 'ConpherenceController',
'ConpherenceThreadSearchEngine' => 'PhabricatorApplicationSearchEngine', 'ConpherenceThreadSearchEngine' => 'PhabricatorApplicationSearchEngine',
'ConpherenceThreadTitleNgrams' => 'PhabricatorSearchNgrams', 'ConpherenceThreadTitleNgrams' => 'PhabricatorSearchNgrams',
'ConpherenceTransaction' => 'PhabricatorApplicationTransaction', 'ConpherenceThreadTitleTransaction' => 'ConpherenceThreadTransactionType',
'ConpherenceThreadTopicTransaction' => 'ConpherenceThreadTransactionType',
'ConpherenceThreadTransactionType' => 'PhabricatorModularTransactionType',
'ConpherenceTransaction' => 'PhabricatorModularTransaction',
'ConpherenceTransactionComment' => 'PhabricatorApplicationTransactionComment', 'ConpherenceTransactionComment' => 'PhabricatorApplicationTransactionComment',
'ConpherenceTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'ConpherenceTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'ConpherenceTransactionRenderer' => 'Phobject', 'ConpherenceTransactionRenderer' => 'Phobject',
@ -5093,6 +5134,8 @@ phutil_register_library_map(array(
'ConpherenceUpdateController' => 'ConpherenceController', 'ConpherenceUpdateController' => 'ConpherenceController',
'ConpherenceUpdateThreadConduitAPIMethod' => 'ConpherenceConduitAPIMethod', 'ConpherenceUpdateThreadConduitAPIMethod' => 'ConpherenceConduitAPIMethod',
'ConpherenceViewController' => 'ConpherenceController', 'ConpherenceViewController' => 'ConpherenceController',
'CountdownEditConduitAPIMethod' => 'PhabricatorEditEngineAPIMethod',
'CountdownSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod',
'DarkConsoleController' => 'PhabricatorController', 'DarkConsoleController' => 'PhabricatorController',
'DarkConsoleCore' => 'Phobject', 'DarkConsoleCore' => 'Phobject',
'DarkConsoleDataController' => 'PhabricatorController', 'DarkConsoleDataController' => 'PhabricatorController',
@ -7433,6 +7476,7 @@ phutil_register_library_map(array(
'PhabricatorConfigPageView' => 'AphrontTagView', 'PhabricatorConfigPageView' => 'AphrontTagView',
'PhabricatorConfigProxySource' => 'PhabricatorConfigSource', 'PhabricatorConfigProxySource' => 'PhabricatorConfigSource',
'PhabricatorConfigPurgeCacheController' => 'PhabricatorConfigController', 'PhabricatorConfigPurgeCacheController' => 'PhabricatorConfigController',
'PhabricatorConfigRegexOptionType' => 'PhabricatorConfigJSONOptionType',
'PhabricatorConfigRequestExceptionHandlerModule' => 'PhabricatorConfigModule', 'PhabricatorConfigRequestExceptionHandlerModule' => 'PhabricatorConfigModule',
'PhabricatorConfigResponse' => 'AphrontStandaloneHTMLResponse', 'PhabricatorConfigResponse' => 'AphrontStandaloneHTMLResponse',
'PhabricatorConfigSchemaQuery' => 'Phobject', 'PhabricatorConfigSchemaQuery' => 'Phobject',
@ -7454,6 +7498,7 @@ phutil_register_library_map(array(
'PhabricatorConpherenceColumnVisibleSetting' => 'PhabricatorInternalSetting', 'PhabricatorConpherenceColumnVisibleSetting' => 'PhabricatorInternalSetting',
'PhabricatorConpherenceNotificationsSetting' => 'PhabricatorSelectSetting', 'PhabricatorConpherenceNotificationsSetting' => 'PhabricatorSelectSetting',
'PhabricatorConpherencePreferencesSettingsPanel' => 'PhabricatorEditEngineSettingsPanel', 'PhabricatorConpherencePreferencesSettingsPanel' => 'PhabricatorEditEngineSettingsPanel',
'PhabricatorConpherenceProfileMenuItem' => 'PhabricatorProfileMenuItem',
'PhabricatorConpherenceThreadPHIDType' => 'PhabricatorPHIDType', 'PhabricatorConpherenceThreadPHIDType' => 'PhabricatorPHIDType',
'PhabricatorConpherenceWidgetVisibleSetting' => 'PhabricatorInternalSetting', 'PhabricatorConpherenceWidgetVisibleSetting' => 'PhabricatorInternalSetting',
'PhabricatorConsoleApplication' => 'PhabricatorApplication', 'PhabricatorConsoleApplication' => 'PhabricatorApplication',
@ -7477,6 +7522,8 @@ phutil_register_library_map(array(
'PhabricatorTokenReceiverInterface', 'PhabricatorTokenReceiverInterface',
'PhabricatorSpacesInterface', 'PhabricatorSpacesInterface',
'PhabricatorProjectInterface', 'PhabricatorProjectInterface',
'PhabricatorDestructibleInterface',
'PhabricatorConduitResultInterface',
), ),
'PhabricatorCountdownApplication' => 'PhabricatorApplication', 'PhabricatorCountdownApplication' => 'PhabricatorApplication',
'PhabricatorCountdownController' => 'PhabricatorController', 'PhabricatorCountdownController' => 'PhabricatorController',
@ -7484,10 +7531,11 @@ phutil_register_library_map(array(
'PhabricatorCountdownDAO' => 'PhabricatorLiskDAO', 'PhabricatorCountdownDAO' => 'PhabricatorLiskDAO',
'PhabricatorCountdownDefaultEditCapability' => 'PhabricatorPolicyCapability', 'PhabricatorCountdownDefaultEditCapability' => 'PhabricatorPolicyCapability',
'PhabricatorCountdownDefaultViewCapability' => 'PhabricatorPolicyCapability', 'PhabricatorCountdownDefaultViewCapability' => 'PhabricatorPolicyCapability',
'PhabricatorCountdownDeleteController' => 'PhabricatorCountdownController', 'PhabricatorCountdownDescriptionTransaction' => 'PhabricatorCountdownTransactionType',
'PhabricatorCountdownEditController' => 'PhabricatorCountdownController', 'PhabricatorCountdownEditController' => 'PhabricatorCountdownController',
'PhabricatorCountdownEditEngine' => 'PhabricatorEditEngine', 'PhabricatorCountdownEditEngine' => 'PhabricatorEditEngine',
'PhabricatorCountdownEditor' => 'PhabricatorApplicationTransactionEditor', 'PhabricatorCountdownEditor' => 'PhabricatorApplicationTransactionEditor',
'PhabricatorCountdownEpochTransaction' => 'PhabricatorCountdownTransactionType',
'PhabricatorCountdownListController' => 'PhabricatorCountdownController', 'PhabricatorCountdownListController' => 'PhabricatorCountdownController',
'PhabricatorCountdownMailReceiver' => 'PhabricatorObjectMailReceiver', 'PhabricatorCountdownMailReceiver' => 'PhabricatorObjectMailReceiver',
'PhabricatorCountdownQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorCountdownQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
@ -7495,9 +7543,11 @@ phutil_register_library_map(array(
'PhabricatorCountdownReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler', 'PhabricatorCountdownReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler',
'PhabricatorCountdownSchemaSpec' => 'PhabricatorConfigSchemaSpec', 'PhabricatorCountdownSchemaSpec' => 'PhabricatorConfigSchemaSpec',
'PhabricatorCountdownSearchEngine' => 'PhabricatorApplicationSearchEngine', 'PhabricatorCountdownSearchEngine' => 'PhabricatorApplicationSearchEngine',
'PhabricatorCountdownTransaction' => 'PhabricatorApplicationTransaction', 'PhabricatorCountdownTitleTransaction' => 'PhabricatorCountdownTransactionType',
'PhabricatorCountdownTransaction' => 'PhabricatorModularTransaction',
'PhabricatorCountdownTransactionComment' => 'PhabricatorApplicationTransactionComment', 'PhabricatorCountdownTransactionComment' => 'PhabricatorApplicationTransactionComment',
'PhabricatorCountdownTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'PhabricatorCountdownTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhabricatorCountdownTransactionType' => 'PhabricatorModularTransactionType',
'PhabricatorCountdownView' => 'AphrontView', 'PhabricatorCountdownView' => 'AphrontView',
'PhabricatorCountdownViewController' => 'PhabricatorCountdownController', 'PhabricatorCountdownViewController' => 'PhabricatorCountdownController',
'PhabricatorCursorPagedPolicyAwareQuery' => 'PhabricatorPolicyAwareQuery', 'PhabricatorCursorPagedPolicyAwareQuery' => 'PhabricatorPolicyAwareQuery',
@ -7976,7 +8026,9 @@ phutil_register_library_map(array(
'PhabricatorFulltextEngineExtension' => 'Phobject', 'PhabricatorFulltextEngineExtension' => 'Phobject',
'PhabricatorFulltextEngineExtensionModule' => 'PhabricatorConfigModule', 'PhabricatorFulltextEngineExtensionModule' => 'PhabricatorConfigModule',
'PhabricatorFulltextIndexEngineExtension' => 'PhabricatorIndexEngineExtension', 'PhabricatorFulltextIndexEngineExtension' => 'PhabricatorIndexEngineExtension',
'PhabricatorFulltextResultSet' => 'Phobject',
'PhabricatorFulltextStorageEngine' => 'Phobject', 'PhabricatorFulltextStorageEngine' => 'Phobject',
'PhabricatorFulltextToken' => 'Phobject',
'PhabricatorFundApplication' => 'PhabricatorApplication', 'PhabricatorFundApplication' => 'PhabricatorApplication',
'PhabricatorGDSetupCheck' => 'PhabricatorSetupCheck', 'PhabricatorGDSetupCheck' => 'PhabricatorSetupCheck',
'PhabricatorGarbageCollector' => 'Phobject', 'PhabricatorGarbageCollector' => 'Phobject',
@ -8629,6 +8681,7 @@ phutil_register_library_map(array(
'PhabricatorPhortuneContentSource' => 'PhabricatorContentSource', 'PhabricatorPhortuneContentSource' => 'PhabricatorContentSource',
'PhabricatorPhortuneManagementInvoiceWorkflow' => 'PhabricatorPhortuneManagementWorkflow', 'PhabricatorPhortuneManagementInvoiceWorkflow' => 'PhabricatorPhortuneManagementWorkflow',
'PhabricatorPhortuneManagementWorkflow' => 'PhabricatorManagementWorkflow', 'PhabricatorPhortuneManagementWorkflow' => 'PhabricatorManagementWorkflow',
'PhabricatorPhortuneTestCase' => 'PhabricatorTestCase',
'PhabricatorPhragmentApplication' => 'PhabricatorApplication', 'PhabricatorPhragmentApplication' => 'PhabricatorApplication',
'PhabricatorPhrequentApplication' => 'PhabricatorApplication', 'PhabricatorPhrequentApplication' => 'PhabricatorApplication',
'PhabricatorPhrictionApplication' => 'PhabricatorApplication', 'PhabricatorPhrictionApplication' => 'PhabricatorApplication',
@ -9119,7 +9172,7 @@ phutil_register_library_map(array(
'PhabricatorSearchDocument' => 'PhabricatorSearchDAO', 'PhabricatorSearchDocument' => 'PhabricatorSearchDAO',
'PhabricatorSearchDocumentField' => 'PhabricatorSearchDAO', 'PhabricatorSearchDocumentField' => 'PhabricatorSearchDAO',
'PhabricatorSearchDocumentFieldType' => 'Phobject', 'PhabricatorSearchDocumentFieldType' => 'Phobject',
'PhabricatorSearchDocumentQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorSearchDocumentQuery' => 'PhabricatorPolicyAwareQuery',
'PhabricatorSearchDocumentRelationship' => 'PhabricatorSearchDAO', 'PhabricatorSearchDocumentRelationship' => 'PhabricatorSearchDAO',
'PhabricatorSearchDocumentTypeDatasource' => 'PhabricatorTypeaheadDatasource', 'PhabricatorSearchDocumentTypeDatasource' => 'PhabricatorTypeaheadDatasource',
'PhabricatorSearchEditController' => 'PhabricatorSearchBaseController', 'PhabricatorSearchEditController' => 'PhabricatorSearchBaseController',
@ -9286,6 +9339,7 @@ phutil_register_library_map(array(
'PhabricatorStorageManagementDatabasesWorkflow' => 'PhabricatorStorageManagementWorkflow', 'PhabricatorStorageManagementDatabasesWorkflow' => 'PhabricatorStorageManagementWorkflow',
'PhabricatorStorageManagementDestroyWorkflow' => 'PhabricatorStorageManagementWorkflow', 'PhabricatorStorageManagementDestroyWorkflow' => 'PhabricatorStorageManagementWorkflow',
'PhabricatorStorageManagementDumpWorkflow' => 'PhabricatorStorageManagementWorkflow', 'PhabricatorStorageManagementDumpWorkflow' => 'PhabricatorStorageManagementWorkflow',
'PhabricatorStorageManagementOptimizeWorkflow' => 'PhabricatorStorageManagementWorkflow',
'PhabricatorStorageManagementPartitionWorkflow' => 'PhabricatorStorageManagementWorkflow', 'PhabricatorStorageManagementPartitionWorkflow' => 'PhabricatorStorageManagementWorkflow',
'PhabricatorStorageManagementProbeWorkflow' => 'PhabricatorStorageManagementWorkflow', 'PhabricatorStorageManagementProbeWorkflow' => 'PhabricatorStorageManagementWorkflow',
'PhabricatorStorageManagementQuickstartWorkflow' => 'PhabricatorStorageManagementWorkflow', 'PhabricatorStorageManagementQuickstartWorkflow' => 'PhabricatorStorageManagementWorkflow',
@ -9759,16 +9813,25 @@ phutil_register_library_map(array(
'PhabricatorApplicationTransactionInterface', 'PhabricatorApplicationTransactionInterface',
'PhabricatorPolicyInterface', 'PhabricatorPolicyInterface',
), ),
'PhortuneAccountAddManagerController' => 'PhortuneController',
'PhortuneAccountBillingController' => 'PhortuneAccountProfileController',
'PhortuneAccountChargeListController' => 'PhortuneController', 'PhortuneAccountChargeListController' => 'PhortuneController',
'PhortuneAccountController' => 'PhortuneController',
'PhortuneAccountEditController' => 'PhortuneController', 'PhortuneAccountEditController' => 'PhortuneController',
'PhortuneAccountEditEngine' => 'PhabricatorEditEngine',
'PhortuneAccountEditor' => 'PhabricatorApplicationTransactionEditor', 'PhortuneAccountEditor' => 'PhabricatorApplicationTransactionEditor',
'PhortuneAccountHasMemberEdgeType' => 'PhabricatorEdgeType', 'PhortuneAccountHasMemberEdgeType' => 'PhabricatorEdgeType',
'PhortuneAccountListController' => 'PhortuneController', 'PhortuneAccountListController' => 'PhortuneController',
'PhortuneAccountManagerController' => 'PhortuneAccountProfileController',
'PhortuneAccountNameTransaction' => 'PhortuneAccountTransactionType',
'PhortuneAccountPHIDType' => 'PhabricatorPHIDType', 'PhortuneAccountPHIDType' => 'PhabricatorPHIDType',
'PhortuneAccountProfileController' => 'PhortuneAccountController',
'PhortuneAccountQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhortuneAccountQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhortuneAccountTransaction' => 'PhabricatorApplicationTransaction', 'PhortuneAccountSubscriptionController' => 'PhortuneAccountProfileController',
'PhortuneAccountTransaction' => 'PhabricatorModularTransaction',
'PhortuneAccountTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'PhortuneAccountTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhortuneAccountViewController' => 'PhortuneController', 'PhortuneAccountTransactionType' => 'PhabricatorModularTransactionType',
'PhortuneAccountViewController' => 'PhortuneAccountProfileController',
'PhortuneAdHocCart' => 'PhortuneCartImplementation', 'PhortuneAdHocCart' => 'PhortuneCartImplementation',
'PhortuneAdHocProduct' => 'PhortuneProductImplementation', 'PhortuneAdHocProduct' => 'PhortuneProductImplementation',
'PhortuneCart' => array( 'PhortuneCart' => array(
@ -9816,21 +9879,31 @@ phutil_register_library_map(array(
'PhabricatorApplicationTransactionInterface', 'PhabricatorApplicationTransactionInterface',
'PhabricatorPolicyInterface', 'PhabricatorPolicyInterface',
), ),
'PhortuneMerchantAddManagerController' => 'PhortuneController',
'PhortuneMerchantCapability' => 'PhabricatorPolicyCapability', 'PhortuneMerchantCapability' => 'PhabricatorPolicyCapability',
'PhortuneMerchantContactInfoTransaction' => 'PhortuneMerchantTransactionType',
'PhortuneMerchantController' => 'PhortuneController', 'PhortuneMerchantController' => 'PhortuneController',
'PhortuneMerchantDescriptionTransaction' => 'PhortuneMerchantTransactionType',
'PhortuneMerchantEditController' => 'PhortuneMerchantController', 'PhortuneMerchantEditController' => 'PhortuneMerchantController',
'PhortuneMerchantEditEngine' => 'PhabricatorEditEngine', 'PhortuneMerchantEditEngine' => 'PhabricatorEditEngine',
'PhortuneMerchantEditor' => 'PhabricatorApplicationTransactionEditor', 'PhortuneMerchantEditor' => 'PhabricatorApplicationTransactionEditor',
'PhortuneMerchantHasMemberEdgeType' => 'PhabricatorEdgeType', 'PhortuneMerchantHasMemberEdgeType' => 'PhabricatorEdgeType',
'PhortuneMerchantInvoiceCreateController' => 'PhortuneMerchantController', 'PhortuneMerchantInvoiceCreateController' => 'PhortuneMerchantProfileController',
'PhortuneMerchantInvoiceEmailTransaction' => 'PhortuneMerchantTransactionType',
'PhortuneMerchantInvoiceFooterTransaction' => 'PhortuneMerchantTransactionType',
'PhortuneMerchantListController' => 'PhortuneMerchantController', 'PhortuneMerchantListController' => 'PhortuneMerchantController',
'PhortuneMerchantManagerController' => 'PhortuneMerchantProfileController',
'PhortuneMerchantNameTransaction' => 'PhortuneMerchantTransactionType',
'PhortuneMerchantPHIDType' => 'PhabricatorPHIDType', 'PhortuneMerchantPHIDType' => 'PhabricatorPHIDType',
'PhortuneMerchantPictureController' => 'PhortuneMerchantController', 'PhortuneMerchantPictureController' => 'PhortuneMerchantProfileController',
'PhortuneMerchantPictureTransaction' => 'PhortuneMerchantTransactionType',
'PhortuneMerchantProfileController' => 'PhortuneController',
'PhortuneMerchantQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhortuneMerchantQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhortuneMerchantSearchEngine' => 'PhabricatorApplicationSearchEngine', 'PhortuneMerchantSearchEngine' => 'PhabricatorApplicationSearchEngine',
'PhortuneMerchantTransaction' => 'PhabricatorApplicationTransaction', 'PhortuneMerchantTransaction' => 'PhabricatorModularTransaction',
'PhortuneMerchantTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'PhortuneMerchantTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhortuneMerchantViewController' => 'PhortuneMerchantController', 'PhortuneMerchantTransactionType' => 'PhabricatorModularTransactionType',
'PhortuneMerchantViewController' => 'PhortuneMerchantProfileController',
'PhortuneMonthYearExpiryControl' => 'AphrontFormControl', 'PhortuneMonthYearExpiryControl' => 'AphrontFormControl',
'PhortuneOrderTableView' => 'AphrontView', 'PhortuneOrderTableView' => 'AphrontView',
'PhortunePayPalPaymentProvider' => 'PhortunePaymentProvider', 'PhortunePayPalPaymentProvider' => 'PhortunePaymentProvider',

View file

@ -197,9 +197,7 @@ final class PhabricatorAuthSSHKeyEditor
// After making any change to an SSH key, drop the authfile cache so it // After making any change to an SSH key, drop the authfile cache so it
// is regenerated the next time anyone authenticates. // is regenerated the next time anyone authenticates.
$cache = PhabricatorCaches::getMutableCache(); PhabricatorAuthSSHKeyQuery::deleteSSHKeyCache();
$authfile_key = PhabricatorAuthSSHKeyQuery::AUTHFILE_CACHEKEY;
$cache->deleteKey($authfile_key);
return $xactions; return $xactions;
} }

View file

@ -11,6 +11,12 @@ final class PhabricatorAuthSSHKeyQuery
private $keys; private $keys;
private $isActive; private $isActive;
public static function deleteSSHKeyCache() {
$cache = PhabricatorCaches::getMutableCache();
$authfile_key = self::AUTHFILE_CACHEKEY;
$cache->deleteKey($authfile_key);
}
public function withIDs(array $ids) { public function withIDs(array $ids) {
$this->ids = $ids; $this->ids = $ids;
return $this; return $this;

View file

@ -58,4 +58,12 @@ final class PhabricatorCalendarEventNotificationView
return phabricator_datetime($epoch, $viewer); return phabricator_datetime($epoch, $viewer);
} }
public function getDisplayTimeWithTimezone() {
$viewer = $this->getViewer();
$epoch = $this->getEpoch();
return phabricator_datetimezone($epoch, $viewer);
}
} }

View file

@ -268,7 +268,7 @@ final class PhabricatorCalendarNotificationEngine
'%s is starting in %s minute(s), at %s.', '%s is starting in %s minute(s), at %s.',
$event->getEvent()->getName(), $event->getEvent()->getName(),
$event->getDisplayMinutes(), $event->getDisplayMinutes(),
$event->getDisplayTime())); $event->getDisplayTimeWithTimezone()));
$body->addLinkSection( $body->addLinkSection(
pht('EVENT DETAIL'), pht('EVENT DETAIL'),

View file

@ -226,7 +226,7 @@ final class PhabricatorCalendarEventQuery
$set = $event->newRecurrenceSet(); $set = $event->newRecurrenceSet();
$recurrences = $set->getEventsBetween( $recurrences = $set->getEventsBetween(
null, $start_date,
$end_date, $end_date,
$limit + 1); $limit + 1);

View file

@ -391,6 +391,10 @@ final class PhabricatorCalendarEvent extends PhabricatorCalendarDAO
return ($epoch - $window); return ($epoch - $window);
} }
public function getEndDateTimeEpochForCache() {
return $this->getEndDateTimeEpoch();
}
protected function getConfiguration() { protected function getConfiguration() {
return array( return array(
self::CONFIG_AUX_PHID => true, self::CONFIG_AUX_PHID => true,

View file

@ -0,0 +1,18 @@
<?php
class PhabricatorConfigRegexOptionType
extends PhabricatorConfigJSONOptionType {
public function validateOption(PhabricatorConfigOption $option, $value) {
foreach ($value as $pattern => $spec) {
$ok = preg_match($pattern, '');
if ($ok === false) {
throw new Exception(
pht(
'The following regex is malformed and cannot be used: %s',
$pattern));
}
}
}
}

View file

@ -120,11 +120,11 @@ final class PhabricatorSyntaxHighlightingConfigOptions
'this is where that list is defined.')), 'this is where that list is defined.')),
$this->newOption( $this->newOption(
'syntax.filemap', 'syntax.filemap',
'wild', 'custom:PhabricatorConfigRegexOptionType',
array( array(
'@\.arcconfig$@' => 'js', '@\.arcconfig$@' => 'json',
'@\.arclint$@' => 'js', '@\.arclint$@' => 'json',
'@\.divinerconfig$@' => 'js', '@\.divinerconfig$@' => 'json',
)) ))
->setSummary( ->setSummary(
pht('Override what language files (based on filename) highlight as.')) pht('Override what language files (based on filename) highlight as.'))
@ -138,12 +138,14 @@ final class PhabricatorSyntaxHighlightingConfigOptions
'be tested against the filename. They should map to either an '. 'be tested against the filename. They should map to either an '.
'explicit language as a string value, or a numeric index into '. 'explicit language as a string value, or a numeric index into '.
'the captured groups as an integer.')) 'the captured groups as an integer.'))
->addExample('{"@\\.xyz$@": "php"}', pht('Highlight %s as PHP.', '*.xyz'))
->addExample( ->addExample(
'{"@/httpd\\.conf@": "apacheconf"}', '{"@\\\.xyz$@": "php"}',
pht('Highlight %s as PHP.', '*.xyz'))
->addExample(
'{"@/httpd\\\.conf@": "apacheconf"}',
pht('Highlight httpd.conf as "apacheconf".')) pht('Highlight httpd.conf as "apacheconf".'))
->addExample( ->addExample(
'{"@\\.([^.]+)\\.bak$@": 1}', '{"@\\\.([^.]+)\\\.bak$@": 1}',
pht( pht(
"Treat all '*.x.bak' file as '.x'. NOTE: We map to capturing group ". "Treat all '*.x.bak' file as '.x'. NOTE: We map to capturing group ".
"1 by specifying the mapping as '1'")), "1 by specifying the mapping as '1'")),

View file

@ -60,7 +60,8 @@ final class ConpherenceTransactionRenderer extends Phobject {
// between days. some setup required! // between days. some setup required!
$previous_transaction = null; $previous_transaction = null;
$date_marker_transaction = id(new ConpherenceTransaction()) $date_marker_transaction = id(new ConpherenceTransaction())
->setTransactionType(ConpherenceTransaction::TYPE_DATE_MARKER) ->setTransactionType(
ConpherenceThreadDateMarkerTransaction::TRANSACTIONTYPE)
->makeEphemeral(); ->makeEphemeral();
$date_marker_transaction_view = id(new ConpherenceTransactionView()) $date_marker_transaction_view = id(new ConpherenceTransactionView())
->setUser($user) ->setUser($user)

View file

@ -16,9 +16,6 @@ final class ConpherenceRoomTestCase extends ConpherenceTestCase {
$this->assertTrue((bool)$conpherence->getID()); $this->assertTrue((bool)$conpherence->getID());
$this->assertEqual(1, count($conpherence->getParticipants())); $this->assertEqual(1, count($conpherence->getParticipants()));
$this->assertEqual(
$participant_phids,
$conpherence->getRecentParticipantPHIDs());
} }
public function testNUserRoomCreate() { public function testNUserRoomCreate() {
@ -38,9 +35,6 @@ final class ConpherenceRoomTestCase extends ConpherenceTestCase {
$this->assertTrue((bool)$conpherence->getID()); $this->assertTrue((bool)$conpherence->getID());
$this->assertEqual(4, count($conpherence->getParticipants())); $this->assertEqual(4, count($conpherence->getParticipants()));
$this->assertEqual(
$participant_phids,
$conpherence->getRecentParticipantPHIDs());
} }
public function testRoomParticipantAddition() { public function testRoomParticipantAddition() {
@ -58,16 +52,11 @@ final class ConpherenceRoomTestCase extends ConpherenceTestCase {
$this->assertTrue((bool)$conpherence->getID()); $this->assertTrue((bool)$conpherence->getID());
$this->assertEqual(2, count($conpherence->getParticipants())); $this->assertEqual(2, count($conpherence->getParticipants()));
$this->assertEqual(
$participant_phids,
$conpherence->getRecentParticipantPHIDs());
// test add by creator // test add by creator
$participant_phids[] = $friend_2->getPHID(); $participant_phids[] = $friend_2->getPHID();
$this->addParticipants($creator, $conpherence, array($friend_2->getPHID())); $this->addParticipants($creator, $conpherence, array($friend_2->getPHID()));
$this->assertEqual( $this->assertEqual(3, count($conpherence->getParticipants()));
$participant_phids,
$conpherence->getRecentParticipantPHIDs());
// test add by other participant, so recent participation should // test add by other participant, so recent participation should
// meaningfully change // meaningfully change
@ -81,9 +70,7 @@ final class ConpherenceRoomTestCase extends ConpherenceTestCase {
$friend_2, $friend_2,
$conpherence, $conpherence,
array($friend_3->getPHID())); array($friend_3->getPHID()));
$this->assertEqual( $this->assertEqual(4, count($conpherence->getParticipants()));
$participant_phids,
$conpherence->getRecentParticipantPHIDs());
} }
public function testRoomParticipantDeletion() { public function testRoomParticipantDeletion() {
@ -123,7 +110,8 @@ final class ConpherenceRoomTestCase extends ConpherenceTestCase {
->setTransactionType(ConpherenceTransaction::TYPE_PARTICIPANTS) ->setTransactionType(ConpherenceTransaction::TYPE_PARTICIPANTS)
->setNewValue(array('+' => $participant_phids)); ->setNewValue(array('+' => $participant_phids));
$xactions[] = id(new ConpherenceTransaction()) $xactions[] = id(new ConpherenceTransaction())
->setTransactionType(ConpherenceTransaction::TYPE_TITLE) ->setTransactionType(
ConpherenceThreadTitleTransaction::TRANSACTIONTYPE)
->setNewValue(pht('Test')); ->setNewValue(pht('Test'));
id(new ConpherenceEditor()) id(new ConpherenceEditor())

View file

@ -71,7 +71,6 @@ final class ConpherenceQueryThreadConduitAPIMethod
'conpherencePHID' => $conpherence->getPHID(), 'conpherencePHID' => $conpherence->getPHID(),
'conpherenceTitle' => $conpherence->getTitle(), 'conpherenceTitle' => $conpherence->getTitle(),
'messageCount' => $conpherence->getMessageCount(), 'messageCount' => $conpherence->getMessageCount(),
'recentParticipantPHIDs' => $conpherence->getRecentParticipantPHIDs(),
'conpherenceURI' => $this->getConpherenceURI($conpherence), 'conpherenceURI' => $this->getConpherenceURI($conpherence),
); );
} }

View file

@ -83,7 +83,8 @@ final class ConpherenceUpdateThreadConduitAPIMethod
} }
if ($title) { if ($title) {
$xactions[] = id(new ConpherenceTransaction()) $xactions[] = id(new ConpherenceTransaction())
->setTransactionType(ConpherenceTransaction::TYPE_TITLE) ->setTransactionType(
ConpherenceThreadTitleTransaction::TRANSACTIONTYPE)
->setNewValue($title); ->setNewValue($title);
} }
if ($message) { if ($message) {

View file

@ -17,7 +17,6 @@ final class ConpherenceColumnViewController extends
->setViewer($user) ->setViewer($user)
->withPHIDs($conpherence_phids) ->withPHIDs($conpherence_phids)
->needProfileImage(true) ->needProfileImage(true)
->needParticipantCache(true)
->execute(); ->execute();
$latest_conpherences = mpull($latest_conpherences, null, 'getPHID'); $latest_conpherences = mpull($latest_conpherences, null, 'getPHID');
$latest_conpherences = array_select_keys( $latest_conpherences = array_select_keys(

View file

@ -78,10 +78,6 @@ abstract class ConpherenceController extends PhabricatorController {
} }
$participating = $conpherence->getParticipantIfExists($viewer->getPHID()); $participating = $conpherence->getParticipantIfExists($viewer->getPHID());
$can_join = PhabricatorPolicyFilter::hasCapability(
$viewer,
$conpherence,
PhabricatorPolicyCapability::CAN_JOIN);
$header->addActionItem( $header->addActionItem(
id(new PHUIIconCircleView()) id(new PHUIIconCircleView())
@ -129,7 +125,7 @@ abstract class ConpherenceController extends PhabricatorController {
->setColor('green') ->setColor('green')
->addClass('conpherence-search-toggle')); ->addClass('conpherence-search-toggle'));
if ($can_join && !$participating) { if (!$participating) {
$action = ConpherenceUpdateActions::JOIN_ROOM; $action = ConpherenceUpdateActions::JOIN_ROOM;
$uri = $this->getApplicationURI('update/'.$conpherence->getID().'/'); $uri = $this->getApplicationURI('update/'.$conpherence->getID().'/');
$button = phutil_tag( $button = phutil_tag(

View file

@ -159,7 +159,6 @@ final class ConpherenceListController extends ConpherenceController {
->setViewer($user) ->setViewer($user)
->withPHIDs($conpherence_phids) ->withPHIDs($conpherence_phids)
->needProfileImage(true) ->needProfileImage(true)
->needParticipantCache(true)
->execute(); ->execute();
// this will re-sort by participation data // this will re-sort by participation data

View file

@ -7,7 +7,6 @@ final class ConpherenceNewRoomController extends ConpherenceController {
$title = pht('New Room'); $title = pht('New Room');
$e_title = true; $e_title = true;
$v_message = null;
$validation_exception = null; $validation_exception = null;
$conpherence = ConpherenceThread::initializeNewRoom($user); $conpherence = ConpherenceThread::initializeNewRoom($user);
@ -17,7 +16,7 @@ final class ConpherenceNewRoomController extends ConpherenceController {
$xactions = array(); $xactions = array();
$xactions[] = id(new ConpherenceTransaction()) $xactions[] = id(new ConpherenceTransaction())
->setTransactionType(ConpherenceTransaction::TYPE_TITLE) ->setTransactionType(ConpherenceThreadTitleTransaction::TRANSACTIONTYPE)
->setNewValue($request->getStr('title')); ->setNewValue($request->getStr('title'));
$participants = $request->getArr('participants'); $participants = $request->getArr('participants');
@ -27,7 +26,7 @@ final class ConpherenceNewRoomController extends ConpherenceController {
->setTransactionType(ConpherenceTransaction::TYPE_PARTICIPANTS) ->setTransactionType(ConpherenceTransaction::TYPE_PARTICIPANTS)
->setNewValue(array('+' => $participants)); ->setNewValue(array('+' => $participants));
$xactions[] = id(new ConpherenceTransaction()) $xactions[] = id(new ConpherenceTransaction())
->setTransactionType(ConpherenceTransaction::TYPE_TOPIC) ->setTransactionType(ConpherenceThreadTopicTransaction::TRANSACTIONTYPE)
->setNewValue($request->getStr('topic')); ->setNewValue($request->getStr('topic'));
$xactions[] = id(new ConpherenceTransaction()) $xactions[] = id(new ConpherenceTransaction())
->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY) ->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY)
@ -35,18 +34,6 @@ final class ConpherenceNewRoomController extends ConpherenceController {
$xactions[] = id(new ConpherenceTransaction()) $xactions[] = id(new ConpherenceTransaction())
->setTransactionType(PhabricatorTransactions::TYPE_EDIT_POLICY) ->setTransactionType(PhabricatorTransactions::TYPE_EDIT_POLICY)
->setNewValue($request->getStr('editPolicy')); ->setNewValue($request->getStr('editPolicy'));
$xactions[] = id(new ConpherenceTransaction())
->setTransactionType(PhabricatorTransactions::TYPE_JOIN_POLICY)
->setNewValue($request->getStr('joinPolicy'));
$v_message = $request->getStr('message');
if (strlen($v_message)) {
$message_xactions = $editor->generateTransactionsFromText(
$user,
$conpherence,
$v_message);
$xactions = array_merge($xactions, $message_xactions);
}
try { try {
$editor $editor
@ -60,11 +47,11 @@ final class ConpherenceNewRoomController extends ConpherenceController {
} catch (PhabricatorApplicationTransactionValidationException $ex) { } catch (PhabricatorApplicationTransactionValidationException $ex) {
$validation_exception = $ex; $validation_exception = $ex;
$e_title = $ex->getShortMessage(ConpherenceTransaction::TYPE_TITLE); $e_title = $ex->getShortMessage(
ConpherenceThreadTitleTransaction::TRANSACTIONTYPE);
$conpherence->setViewPolicy($request->getStr('viewPolicy')); $conpherence->setViewPolicy($request->getStr('viewPolicy'));
$conpherence->setEditPolicy($request->getStr('editPolicy')); $conpherence->setEditPolicy($request->getStr('editPolicy'));
$conpherence->setJoinPolicy($request->getStr('joinPolicy'));
} }
} else { } else {
if ($request->getStr('participant')) { if ($request->getStr('participant')) {
@ -119,19 +106,7 @@ final class ConpherenceNewRoomController extends ConpherenceController {
->setName('editPolicy') ->setName('editPolicy')
->setPolicyObject($conpherence) ->setPolicyObject($conpherence)
->setCapability(PhabricatorPolicyCapability::CAN_EDIT) ->setCapability(PhabricatorPolicyCapability::CAN_EDIT)
->setPolicies($policies)) ->setPolicies($policies));
->appendChild(
id(new AphrontFormPolicyControl())
->setName('joinPolicy')
->setPolicyObject($conpherence)
->setCapability(PhabricatorPolicyCapability::CAN_JOIN)
->setPolicies($policies))
->appendChild(
id(new PhabricatorRemarkupControl())
->setUser($user)
->setName('message')
->setLabel(pht('First Message'))
->setValue($v_message));
$dialog->appendChild($form); $dialog->appendChild($form);

View file

@ -20,8 +20,7 @@ final class ConpherenceNotificationPanelController
->withPHIDs(array_keys($participant_data)) ->withPHIDs(array_keys($participant_data))
->needProfileImage(true) ->needProfileImage(true)
->needTransactions(true) ->needTransactions(true)
->setTransactionLimit(50) ->setTransactionLimit(100)
->needParticipantCache(true)
->execute(); ->execute();
} }

View file

@ -76,7 +76,8 @@ final class ConpherenceRoomPictureController
$xactions = array(); $xactions = array();
$xactions[] = id(new ConpherenceTransaction()) $xactions[] = id(new ConpherenceTransaction())
->setTransactionType(ConpherenceTransaction::TYPE_PICTURE) ->setTransactionType(
ConpherenceThreadPictureTransaction::TRANSACTIONTYPE)
->setNewValue($new_value); ->setNewValue($new_value);
$editor = id(new ConpherenceEditor()) $editor = id(new ConpherenceEditor())

View file

@ -24,9 +24,6 @@ final class ConpherenceUpdateController
case ConpherenceUpdateActions::METADATA: case ConpherenceUpdateActions::METADATA:
$needed_capabilities[] = PhabricatorPolicyCapability::CAN_EDIT; $needed_capabilities[] = PhabricatorPolicyCapability::CAN_EDIT;
break; break;
case ConpherenceUpdateActions::JOIN_ROOM:
$needed_capabilities[] = PhabricatorPolicyCapability::CAN_JOIN;
break;
case ConpherenceUpdateActions::NOTIFICATIONS: case ConpherenceUpdateActions::NOTIFICATIONS:
$need_participants = true; $need_participants = true;
break; break;
@ -140,10 +137,12 @@ final class ConpherenceUpdateController
$title = $request->getStr('title'); $title = $request->getStr('title');
$topic = $request->getStr('topic'); $topic = $request->getStr('topic');
$xactions[] = id(new ConpherenceTransaction()) $xactions[] = id(new ConpherenceTransaction())
->setTransactionType(ConpherenceTransaction::TYPE_TITLE) ->setTransactionType(
ConpherenceThreadTitleTransaction::TRANSACTIONTYPE)
->setNewValue($title); ->setNewValue($title);
$xactions[] = id(new ConpherenceTransaction()) $xactions[] = id(new ConpherenceTransaction())
->setTransactionType(ConpherenceTransaction::TYPE_TOPIC) ->setTransactionType(
ConpherenceThreadTopicTransaction::TRANSACTIONTYPE)
->setNewValue($topic); ->setNewValue($topic);
$xactions[] = id(new ConpherenceTransaction()) $xactions[] = id(new ConpherenceTransaction())
->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY) ->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY)
@ -151,9 +150,6 @@ final class ConpherenceUpdateController
$xactions[] = id(new ConpherenceTransaction()) $xactions[] = id(new ConpherenceTransaction())
->setTransactionType(PhabricatorTransactions::TYPE_EDIT_POLICY) ->setTransactionType(PhabricatorTransactions::TYPE_EDIT_POLICY)
->setNewValue($request->getStr('editPolicy')); ->setNewValue($request->getStr('editPolicy'));
$xactions[] = id(new ConpherenceTransaction())
->setTransactionType(PhabricatorTransactions::TYPE_JOIN_POLICY)
->setNewValue($request->getStr('joinPolicy'));
if (!$request->getExists('force_ajax')) { if (!$request->getExists('force_ajax')) {
$response_mode = 'redirect'; $response_mode = 'redirect';
} }
@ -254,16 +250,9 @@ final class ConpherenceUpdateController
$participant = $conpherence->getParticipantIfExists($user->getPHID()); $participant = $conpherence->getParticipantIfExists($user->getPHID());
if (!$participant) { if (!$participant) {
$can_join = PhabricatorPolicyFilter::hasCapability( if ($user->isLoggedIn()) {
$user,
$conpherence,
PhabricatorPolicyCapability::CAN_JOIN);
if ($can_join) {
$text = pht( $text = pht(
'Notification settings are available after joining the room.'); 'Notification settings are available after joining the room.');
} else if ($user->isLoggedIn()) {
$text = pht(
'Notification settings not applicable to rooms you can not join.');
} else { } else {
$text = pht( $text = pht(
'Notification settings are available after logging in and joining '. 'Notification settings are available after logging in and joining '.
@ -457,12 +446,6 @@ final class ConpherenceUpdateController
->setName('editPolicy') ->setName('editPolicy')
->setPolicyObject($conpherence) ->setPolicyObject($conpherence)
->setCapability(PhabricatorPolicyCapability::CAN_EDIT) ->setCapability(PhabricatorPolicyCapability::CAN_EDIT)
->setPolicies($policies))
->appendChild(
id(new AphrontFormPolicyControl())
->setName('joinPolicy')
->setPolicyObject($conpherence)
->setCapability(PhabricatorPolicyCapability::CAN_JOIN)
->setPolicies($policies)); ->setPolicies($policies));
$view = id(new AphrontDialogView()) $view = id(new AphrontDialogView())
@ -487,7 +470,6 @@ final class ConpherenceUpdateController
$latest_transaction_id) { $latest_transaction_id) {
$need_transactions = false; $need_transactions = false;
$need_participant_cache = true;
switch ($action) { switch ($action) {
case ConpherenceUpdateActions::METADATA: case ConpherenceUpdateActions::METADATA:
case ConpherenceUpdateActions::LOAD: case ConpherenceUpdateActions::LOAD:
@ -508,7 +490,6 @@ final class ConpherenceUpdateController
->setViewer($user) ->setViewer($user)
->setAfterTransactionID($latest_transaction_id) ->setAfterTransactionID($latest_transaction_id)
->needProfileImage(true) ->needProfileImage(true)
->needParticipantCache($need_participant_cache)
->needParticipants(true) ->needParticipants(true)
->needTransactions($need_transactions) ->needTransactions($need_transactions)
->withIDs(array($conpherence_id)) ->withIDs(array($conpherence_id))

View file

@ -20,7 +20,6 @@ final class ConpherenceViewController extends
->setViewer($user) ->setViewer($user)
->withIDs(array($conpherence_id)) ->withIDs(array($conpherence_id))
->needProfileImage(true) ->needProfileImage(true)
->needParticipantCache(true)
->needTransactions(true) ->needTransactions(true)
->setTransactionLimit($this->getMainQueryLimit()); ->setTransactionLimit($this->getMainQueryLimit());
@ -119,11 +118,6 @@ final class ConpherenceViewController extends
return id(new AphrontAjaxResponse())->setContent($content); return id(new AphrontAjaxResponse())->setContent($content);
} }
$can_join = PhabricatorPolicyFilter::hasCapability(
$user,
$conpherence,
PhabricatorPolicyCapability::CAN_JOIN);
$layout = id(new ConpherenceLayoutView()) $layout = id(new ConpherenceLayoutView())
->setUser($user) ->setUser($user)
->setBaseURI($this->getApplicationURI()) ->setBaseURI($this->getApplicationURI())
@ -151,12 +145,9 @@ final class ConpherenceViewController extends
$conpherence = $this->getConpherence(); $conpherence = $this->getConpherence();
$user = $this->getRequest()->getUser(); $user = $this->getRequest()->getUser();
$can_join = PhabricatorPolicyFilter::hasCapability(
$user,
$conpherence,
PhabricatorPolicyCapability::CAN_JOIN);
$participating = $conpherence->getParticipantIfExists($user->getPHID()); $participating = $conpherence->getParticipantIfExists($user->getPHID());
if (!$can_join && !$participating && $user->isLoggedIn()) { if (!$participating && $user->isLoggedIn()) {
return null; return null;
} }
$draft = PhabricatorDraft::newFromUserAndKey( $draft = PhabricatorDraft::newFromUserAndKey(
@ -184,6 +175,7 @@ final class ConpherenceViewController extends
id(new PhabricatorRemarkupControl()) id(new PhabricatorRemarkupControl())
->setUser($user) ->setUser($user)
->setName('text') ->setName('text')
->setSendOnEnter(true)
->setValue($draft->getDraft())); ->setValue($draft->getDraft()));
$status_view = phutil_tag( $status_view = phutil_tag(

View file

@ -41,12 +41,14 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
->setNewValue(array('+' => $participant_phids)); ->setNewValue(array('+' => $participant_phids));
if ($title) { if ($title) {
$xactions[] = id(new ConpherenceTransaction()) $xactions[] = id(new ConpherenceTransaction())
->setTransactionType(ConpherenceTransaction::TYPE_TITLE) ->setTransactionType(
ConpherenceThreadTitleTransaction::TRANSACTIONTYPE)
->setNewValue($title); ->setNewValue($title);
} }
if (strlen($topic)) { if (strlen($topic)) {
$xactions[] = id(new ConpherenceTransaction()) $xactions[] = id(new ConpherenceTransaction())
->setTransactionType(ConpherenceTransaction::TYPE_TOPIC) ->setTransactionType(
ConpherenceThreadTopicTransaction::TRANSACTIONTYPE)
->setNewValue($topic); ->setNewValue($topic);
} }
@ -85,30 +87,24 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
public function getTransactionTypes() { public function getTransactionTypes() {
$types = parent::getTransactionTypes(); $types = parent::getTransactionTypes();
$types[] = PhabricatorTransactions::TYPE_COMMENT;
$types[] = ConpherenceTransaction::TYPE_TITLE;
$types[] = ConpherenceTransaction::TYPE_TOPIC;
$types[] = ConpherenceTransaction::TYPE_PARTICIPANTS; $types[] = ConpherenceTransaction::TYPE_PARTICIPANTS;
$types[] = ConpherenceTransaction::TYPE_PICTURE;
$types[] = PhabricatorTransactions::TYPE_COMMENT;
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY; $types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
$types[] = PhabricatorTransactions::TYPE_EDIT_POLICY; $types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
$types[] = PhabricatorTransactions::TYPE_JOIN_POLICY;
return $types; return $types;
} }
public function getCreateObjectTitle($author, $object) {
return pht('%s created this room.', $author);
}
protected function getCustomTransactionOldValue( protected function getCustomTransactionOldValue(
PhabricatorLiskDAO $object, PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) { PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) { switch ($xaction->getTransactionType()) {
case ConpherenceTransaction::TYPE_TITLE:
return $object->getTitle();
case ConpherenceTransaction::TYPE_TOPIC:
return $object->getTopic();
case ConpherenceTransaction::TYPE_PICTURE:
return $object->getProfileImagePHID();
case ConpherenceTransaction::TYPE_PARTICIPANTS: case ConpherenceTransaction::TYPE_PARTICIPANTS:
if ($this->getIsNewObject()) { if ($this->getIsNewObject()) {
return array(); return array();
@ -122,10 +118,6 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
PhabricatorApplicationTransaction $xaction) { PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) { switch ($xaction->getTransactionType()) {
case ConpherenceTransaction::TYPE_TITLE:
case ConpherenceTransaction::TYPE_TOPIC:
case ConpherenceTransaction::TYPE_PICTURE:
return $xaction->getNewValue();
case ConpherenceTransaction::TYPE_PARTICIPANTS: case ConpherenceTransaction::TYPE_PARTICIPANTS:
return $this->getPHIDTransactionNewValue($xaction); return $this->getPHIDTransactionNewValue($xaction);
} }
@ -198,7 +190,6 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
->setSeenMessageCount($message_count) ->setSeenMessageCount($message_count)
->save(); ->save();
$object->attachParticipants($participants); $object->attachParticipants($participants);
$object->setRecentParticipantPHIDs(array_keys($participants));
} }
break; break;
} }
@ -209,48 +200,12 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
PhabricatorLiskDAO $object, PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) { PhabricatorApplicationTransaction $xaction) {
$make_author_recent_participant = true;
switch ($xaction->getTransactionType()) { switch ($xaction->getTransactionType()) {
case ConpherenceTransaction::TYPE_TITLE:
$object->setTitle($xaction->getNewValue());
break;
case ConpherenceTransaction::TYPE_TOPIC:
$object->setTopic($xaction->getNewValue());
break;
case ConpherenceTransaction::TYPE_PICTURE:
$object->setProfileImagePHID($xaction->getNewValue());
break;
case ConpherenceTransaction::TYPE_PARTICIPANTS: case ConpherenceTransaction::TYPE_PARTICIPANTS:
if (!$this->getIsNewObject()) { if (!$this->getIsNewObject()) {}
$old_map = array_fuse($xaction->getOldValue());
$new_map = array_fuse($xaction->getNewValue());
// if we added people, add them to the end of "recent" participants
$add = array_keys(array_diff_key($new_map, $old_map));
// if we remove people, then definintely remove them from "recent"
// participants
$del = array_keys(array_diff_key($old_map, $new_map));
if ($add || $del) {
$participants = $object->getRecentParticipantPHIDs();
if ($add) {
$participants = array_merge($participants, $add);
}
if ($del) {
$participants = array_diff($participants, $del);
$actor = $this->requireActor();
if (in_array($actor->getPHID(), $del)) {
$make_author_recent_participant = false;
}
}
$participants = array_slice(array_unique($participants), 0, 10);
$object->setRecentParticipantPHIDs($participants);
}
}
break; break;
} }
if ($make_author_recent_participant) {
$this->makeAuthorMostRecentParticipant($object, $xaction);
}
} }
protected function applyBuiltinInternalTransaction( protected function applyBuiltinInternalTransaction(
@ -266,17 +221,6 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
return parent::applyBuiltinInternalTransaction($object, $xaction); return parent::applyBuiltinInternalTransaction($object, $xaction);
} }
private function makeAuthorMostRecentParticipant(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
$participants = $object->getRecentParticipantPHIDs();
array_unshift($participants, $xaction->getAuthorPHID());
$participants = array_slice(array_unique($participants), 0, 10);
$object->setRecentParticipantPHIDs($participants);
}
protected function applyCustomExternalTransaction( protected function applyCustomExternalTransaction(
PhabricatorLiskDAO $object, PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) { PhabricatorApplicationTransaction $xaction) {
@ -335,12 +279,8 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
switch ($xaction->getTransactionType()) { switch ($xaction->getTransactionType()) {
case PhabricatorTransactions::TYPE_COMMENT: case PhabricatorTransactions::TYPE_COMMENT:
$message_count++; $message_count++;
break;
}
}
// update everyone's participation status on the last xaction -only- // update everyone's participation status on a message -only-
$xaction = end($xactions);
$xaction_phid = $xaction->getPHID(); $xaction_phid = $xaction->getPHID();
$behind = ConpherenceParticipationStatus::BEHIND; $behind = ConpherenceParticipationStatus::BEHIND;
$up_to_date = ConpherenceParticipationStatus::UP_TO_DATE; $up_to_date = ConpherenceParticipationStatus::UP_TO_DATE;
@ -369,6 +309,10 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
PhabricatorUserMessageCountCacheType::KEY_COUNT, PhabricatorUserMessageCountCacheType::KEY_COUNT,
array_keys($participants)); array_keys($participants));
break;
}
}
if ($xactions) { if ($xactions) {
$data = array( $data = array(
'type' => 'message', 'type' => 'message',
@ -399,27 +343,15 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
$actor_phid = $this->requireActor()->getPHID(); $actor_phid = $this->requireActor()->getPHID();
$is_join = (($add === array($actor_phid)) && !$rem);
$is_leave = (($rem === array($actor_phid)) && !$add);
if ($is_join) {
// You need CAN_JOIN to join a room.
PhabricatorPolicyFilter::requireCapability(
$this->requireActor(),
$object,
PhabricatorPolicyCapability::CAN_JOIN);
} else if ($is_leave) {
// You don't need any capabilities to leave a conpherence thread.
} else {
// You need CAN_EDIT to change participants other than yourself. // You need CAN_EDIT to change participants other than yourself.
PhabricatorPolicyFilter::requireCapability( PhabricatorPolicyFilter::requireCapability(
$this->requireActor(), $this->requireActor(),
$object, $object,
PhabricatorPolicyCapability::CAN_EDIT); PhabricatorPolicyCapability::CAN_EDIT);
}
break; break;
case ConpherenceTransaction::TYPE_TITLE: case ConpherenceThreadTitleTransaction::TRANSACTIONTYPE:
case ConpherenceTransaction::TYPE_TOPIC: case ConpherenceThreadTopicTransaction::TRANSACTIONTYPE:
PhabricatorPolicyFilter::requireCapability( PhabricatorPolicyFilter::requireCapability(
$this->requireActor(), $this->requireActor(),
$object, $object,
@ -434,8 +366,6 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
$type = $u->getTransactionType(); $type = $u->getTransactionType();
switch ($type) { switch ($type) {
case ConpherenceTransaction::TYPE_TITLE:
return $v;
case ConpherenceTransaction::TYPE_PARTICIPANTS: case ConpherenceTransaction::TYPE_PARTICIPANTS:
return $this->mergePHIDOrEdgeTransactions($u, $v); return $this->mergePHIDOrEdgeTransactions($u, $v);
} }
@ -541,23 +471,6 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
return PhabricatorEnv::getEnvConfig('metamta.conpherence.subject-prefix'); return PhabricatorEnv::getEnvConfig('metamta.conpherence.subject-prefix');
} }
protected function shouldPublishFeedStory(
PhabricatorLiskDAO $object,
array $xactions) {
foreach ($xactions as $xaction) {
switch ($xaction->getTransactionType()) {
case ConpherenceTransaction::TYPE_TITLE:
case ConpherenceTransaction::TYPE_TOPIC:
case ConpherenceTransaction::TYPE_PICTURE:
return true;
default:
return false;
}
}
return false;
}
protected function supportsSearch() { protected function supportsSearch() {
return true; return true;
} }
@ -570,26 +483,6 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
$errors = parent::validateTransaction($object, $type, $xactions); $errors = parent::validateTransaction($object, $type, $xactions);
switch ($type) { switch ($type) {
case ConpherenceTransaction::TYPE_TITLE:
if (empty($xactions)) {
break;
}
$missing = $this->validateIsEmptyTextField(
$object->getTitle(),
$xactions);
if ($missing) {
$detail = pht('Room title is required.');
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Required'),
$detail,
last($xactions));
$error->setIsMissingFieldError(true);
$errors[] = $error;
}
break;
case ConpherenceTransaction::TYPE_PARTICIPANTS: case ConpherenceTransaction::TYPE_PARTICIPANTS:
foreach ($xactions as $xaction) { foreach ($xactions as $xaction) {
$new_phids = $this->getPHIDTransactionNewValue($xaction, array()); $new_phids = $this->getPHIDTransactionNewValue($xaction, array());

View file

@ -56,9 +56,9 @@ final class ConpherenceFulltextQuery
} }
if (strlen($this->fulltext)) { if (strlen($this->fulltext)) {
$compiled_query = PhabricatorSearchDocument::newQueryCompiler() $compiler = PhabricatorSearchDocument::newQueryCompiler();
->setQuery($this->fulltext) $tokens = $compiler->newTokens($this->fulltext);
->compileQuery(); $compiled_query = $compiler->compileQuery($tokens);
$where[] = qsprintf( $where[] = qsprintf(
$conn_r, $conn_r,

View file

@ -10,18 +10,12 @@ final class ConpherenceThreadQuery
private $participantPHIDs; private $participantPHIDs;
private $needParticipants; private $needParticipants;
private $needTransactions; private $needTransactions;
private $needParticipantCache;
private $afterTransactionID; private $afterTransactionID;
private $beforeTransactionID; private $beforeTransactionID;
private $transactionLimit; private $transactionLimit;
private $fulltext; private $fulltext;
private $needProfileImage; private $needProfileImage;
public function needParticipantCache($participant_cache) {
$this->needParticipantCache = $participant_cache;
return $this;
}
public function needParticipants($need) { public function needParticipants($need) {
$this->needParticipants = $need; $this->needParticipants = $need;
return $this; return $this;
@ -101,9 +95,6 @@ final class ConpherenceThreadQuery
if ($conpherences) { if ($conpherences) {
$conpherences = mpull($conpherences, null, 'getPHID'); $conpherences = mpull($conpherences, null, 'getPHID');
$this->loadParticipantsAndInitHandles($conpherences); $this->loadParticipantsAndInitHandles($conpherences);
if ($this->needParticipantCache) {
$this->loadCoreHandles($conpherences, 'getRecentParticipantPHIDs');
}
if ($this->needParticipants) { if ($this->needParticipants) {
$this->loadCoreHandles($conpherences, 'getParticipantPHIDs'); $this->loadCoreHandles($conpherences, 'getParticipantPHIDs');
} }

View file

@ -13,7 +13,6 @@ final class ConpherenceThreadSearchEngine
public function newQuery() { public function newQuery() {
return id(new ConpherenceThreadQuery()) return id(new ConpherenceThreadQuery())
->needParticipantCache(true)
->needProfileImage(true); ->needProfileImage(true);
} }
@ -92,14 +91,6 @@ final class ConpherenceThreadSearchEngine
return parent::buildSavedQueryFromBuiltin($query_key); return parent::buildSavedQueryFromBuiltin($query_key);
} }
protected function getRequiredHandlePHIDsForResultList(
array $conpherences,
PhabricatorSavedQuery $query) {
$recent = mpull($conpherences, 'getRecentParticipantPHIDs');
return array_unique(array_mergev($recent));
}
protected function renderResultList( protected function renderResultList(
array $conpherences, array $conpherences,
PhabricatorSavedQuery $query, PhabricatorSavedQuery $query,
@ -153,7 +144,7 @@ final class ConpherenceThreadSearchEngine
$list->setUser($viewer); $list->setUser($viewer);
foreach ($conpherences as $conpherence_phid => $conpherence) { foreach ($conpherences as $conpherence_phid => $conpherence) {
$created = phabricator_date($conpherence->getDateCreated(), $viewer); $created = phabricator_date($conpherence->getDateCreated(), $viewer);
$title = $conpherence->getDisplayTitle($viewer); $title = $conpherence->getTitle();
$monogram = $conpherence->getMonogram(); $monogram = $conpherence->getMonogram();
$icon_name = $conpherence->getPolicyIconName($policy_objects); $icon_name = $conpherence->getPolicyIconName($policy_objects);

View file

@ -12,7 +12,6 @@ final class ConpherenceThread extends ConpherenceDAO
protected $topic; protected $topic;
protected $profileImagePHID; protected $profileImagePHID;
protected $messageCount; protected $messageCount;
protected $recentParticipantPHIDs = array();
protected $mailKey; protected $mailKey;
protected $viewPolicy; protected $viewPolicy;
protected $editPolicy; protected $editPolicy;
@ -33,15 +32,12 @@ final class ConpherenceThread extends ConpherenceDAO
->attachParticipants(array()) ->attachParticipants(array())
->setViewPolicy($default_policy) ->setViewPolicy($default_policy)
->setEditPolicy($default_policy) ->setEditPolicy($default_policy)
->setJoinPolicy($default_policy); ->setJoinPolicy('');
} }
protected function getConfiguration() { protected function getConfiguration() {
return array( return array(
self::CONFIG_AUX_PHID => true, self::CONFIG_AUX_PHID => true,
self::CONFIG_SERIALIZATION => array(
'recentParticipantPHIDs' => self::SERIALIZATION_JSON,
),
self::CONFIG_COLUMN_SCHEMA => array( self::CONFIG_COLUMN_SCHEMA => array(
'title' => 'text255?', 'title' => 'text255?',
'topic' => 'text255', 'topic' => 'text255',
@ -165,72 +161,6 @@ final class ConpherenceThread extends ConpherenceDAO
return pht('Private Room'); return pht('Private Room');
} }
/**
* Get the thread's display title for a user.
*
* If a thread doesn't have a title set, this will return a string describing
* recent participants.
*
* @param PhabricatorUser Viewer.
* @return string Thread title.
*/
public function getDisplayTitle(PhabricatorUser $viewer) {
$title = $this->getTitle();
if (strlen($title)) {
return $title;
}
return $this->getRecentParticipantsString($viewer);
}
/**
* Get recent participants (other than the viewer) as a string.
*
* For example, this method might return "alincoln, htaft, gwashington...".
*
* @param PhabricatorUser Viewer.
* @return string Description of other participants.
*/
private function getRecentParticipantsString(PhabricatorUser $viewer) {
$handles = $this->getHandles();
$phids = $this->getOtherRecentParticipantPHIDs($viewer);
if (count($phids) == 0) {
$phids[] = $viewer->getPHID();
$more = false;
} else {
$limit = 3;
$more = (count($phids) > $limit);
$phids = array_slice($phids, 0, $limit);
}
$names = array_select_keys($handles, $phids);
$names = mpull($names, 'getName');
$names = implode(', ', $names);
if ($more) {
$names = $names.'...';
}
return $names;
}
/**
* Get PHIDs for recent participants who are not the viewer.
*
* @param PhabricatorUser Viewer.
* @return list<phid> Participants who are not the viewer.
*/
private function getOtherRecentParticipantPHIDs(PhabricatorUser $viewer) {
$phids = $this->getRecentParticipantPHIDs();
$phids = array_fuse($phids);
unset($phids[$viewer->getPHID()]);
return array_values($phids);
}
public function getDisplayData(PhabricatorUser $viewer) { public function getDisplayData(PhabricatorUser $viewer) {
$handles = $this->getHandles(); $handles = $this->getHandles();
@ -240,71 +170,33 @@ final class ConpherenceThread extends ConpherenceDAO
$transactions = array(); $transactions = array();
} }
if ($transactions) {
$subtitle_mode = 'message';
} else {
$subtitle_mode = 'recent';
}
$lucky_phid = head($this->getOtherRecentParticipantPHIDs($viewer));
if ($lucky_phid) {
$lucky_handle = $handles[$lucky_phid];
} else {
// This will be just the user talking to themselves. Weirdo.
$lucky_handle = reset($handles);
}
$img_src = $this->getProfileImageURI(); $img_src = $this->getProfileImageURI();
$message_title = null;
if ($subtitle_mode == 'message') {
$message_transaction = null; $message_transaction = null;
$action_transaction = null;
foreach ($transactions as $transaction) { foreach ($transactions as $transaction) {
if ($message_transaction || $action_transaction) { if ($message_transaction) {
break; break;
} }
switch ($transaction->getTransactionType()) { switch ($transaction->getTransactionType()) {
case PhabricatorTransactions::TYPE_COMMENT: case PhabricatorTransactions::TYPE_COMMENT:
$message_transaction = $transaction; $message_transaction = $transaction;
break; break;
case ConpherenceTransaction::TYPE_TITLE:
case ConpherenceTransaction::TYPE_TOPIC:
case ConpherenceTransaction::TYPE_PICTURE:
case ConpherenceTransaction::TYPE_PARTICIPANTS:
$action_transaction = $transaction;
break;
default: default:
break; break;
} }
} }
if ($message_transaction) { if ($message_transaction) {
$message_handle = $handles[$message_transaction->getAuthorPHID()]; $message_handle = $handles[$message_transaction->getAuthorPHID()];
$message_title = sprintf( $subtitle = sprintf(
'%s: %s', '%s: %s',
$message_handle->getName(), $message_handle->getName(),
id(new PhutilUTF8StringTruncator()) id(new PhutilUTF8StringTruncator())
->setMaximumGlyphs(60) ->setMaximumGlyphs(60)
->truncateString( ->truncateString(
$message_transaction->getComment()->getContent())); $message_transaction->getComment()->getContent()));
}
if ($action_transaction) {
$message_title = id(clone $action_transaction)
->setRenderingTarget(PhabricatorApplicationTransaction::TARGET_TEXT)
->getTitle();
}
}
switch ($subtitle_mode) {
case 'recent':
$subtitle = $this->getRecentParticipantsString($viewer);
break;
case 'message':
if ($message_title) {
$subtitle = $message_title;
} else { } else {
$subtitle = $this->getRecentParticipantsString($viewer); // Kinda lame, but maybe add last message to cache?
} $subtitle = pht('No recent messages');
break;
} }
$user_participation = $this->getParticipantIfExists($viewer->getPHID()); $user_participation = $this->getParticipantIfExists($viewer->getPHID());
@ -315,7 +207,7 @@ final class ConpherenceThread extends ConpherenceDAO
} }
$unread_count = $this->getMessageCount() - $user_seen_count; $unread_count = $this->getMessageCount() - $user_seen_count;
$title = $this->getDisplayTitle($viewer); $title = $this->getTitle();
$topic = $this->getTopic(); $topic = $this->getTopic();
return array( return array(
@ -336,7 +228,6 @@ final class ConpherenceThread extends ConpherenceDAO
return array( return array(
PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT, PhabricatorPolicyCapability::CAN_EDIT,
PhabricatorPolicyCapability::CAN_JOIN,
); );
} }
@ -346,8 +237,6 @@ final class ConpherenceThread extends ConpherenceDAO
return $this->getViewPolicy(); return $this->getViewPolicy();
case PhabricatorPolicyCapability::CAN_EDIT: case PhabricatorPolicyCapability::CAN_EDIT:
return $this->getEditPolicy(); return $this->getEditPolicy();
case PhabricatorPolicyCapability::CAN_JOIN:
return $this->getJoinPolicy();
} }
return PhabricatorPolicies::POLICY_NOONE; return PhabricatorPolicies::POLICY_NOONE;
} }
@ -360,7 +249,6 @@ final class ConpherenceThread extends ConpherenceDAO
switch ($capability) { switch ($capability) {
case PhabricatorPolicyCapability::CAN_EDIT: case PhabricatorPolicyCapability::CAN_EDIT:
case PhabricatorPolicyCapability::CAN_JOIN:
return false; return false;
} }

View file

@ -1,13 +1,9 @@
<?php <?php
final class ConpherenceTransaction extends PhabricatorApplicationTransaction { final class ConpherenceTransaction
extends PhabricatorModularTransaction {
const TYPE_TITLE = 'title';
const TYPE_TOPIC = 'topic';
const TYPE_PARTICIPANTS = 'participants'; const TYPE_PARTICIPANTS = 'participants';
const TYPE_DATE_MARKER = 'date-marker';
const TYPE_PICTURE = 'picture';
const TYPE_PICTURE_CROP = 'picture-crop'; // TODO: Nuke these from DB.
public function getApplicationName() { public function getApplicationName() {
return 'conpherence'; return 'conpherence';
@ -21,6 +17,10 @@ final class ConpherenceTransaction extends PhabricatorApplicationTransaction {
return new ConpherenceTransactionComment(); return new ConpherenceTransactionComment();
} }
public function getBaseTransactionClass() {
return 'ConpherenceThreadTransactionType';
}
public function getNoEffectDescription() { public function getNoEffectDescription() {
switch ($this->getTransactionType()) { switch ($this->getTransactionType()) {
case self::TYPE_PARTICIPANTS: case self::TYPE_PARTICIPANTS:
@ -38,13 +38,6 @@ final class ConpherenceTransaction extends PhabricatorApplicationTransaction {
switch ($this->getTransactionType()) { switch ($this->getTransactionType()) {
case self::TYPE_PARTICIPANTS: case self::TYPE_PARTICIPANTS:
return ($old === null); return ($old === null);
case self::TYPE_TITLE:
case self::TYPE_TOPIC:
case self::TYPE_PICTURE:
case self::TYPE_DATE_MARKER:
return false;
case self::TYPE_PICTURE_CROP:
return true;
} }
return parent::shouldHide(); return parent::shouldHide();
@ -57,14 +50,6 @@ final class ConpherenceTransaction extends PhabricatorApplicationTransaction {
$new = $this->getNewValue(); $new = $this->getNewValue();
switch ($this->getTransactionType()) { switch ($this->getTransactionType()) {
case self::TYPE_TITLE:
case self::TYPE_TOPIC:
case PhabricatorTransactions::TYPE_VIEW_POLICY:
case PhabricatorTransactions::TYPE_EDIT_POLICY:
case PhabricatorTransactions::TYPE_JOIN_POLICY:
case self::TYPE_PICTURE:
return $this->getRoomTitle();
break;
case self::TYPE_PARTICIPANTS: case self::TYPE_PARTICIPANTS:
$add = array_diff($new, $old); $add = array_diff($new, $old);
$rem = array_diff($old, $new); $rem = array_diff($old, $new);
@ -97,125 +82,6 @@ final class ConpherenceTransaction extends PhabricatorApplicationTransaction {
return parent::getTitle(); 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_TITLE:
if (strlen($old) && strlen($new)) {
return pht(
'%s renamed %s from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid),
$old,
$new);
} else {
return pht(
'%s created the room %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
}
break;
break;
case self::TYPE_TOPIC:
if (strlen($new)) {
return pht(
'%s set the topic of %s to "%s".',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid),
$new);
} else if (strlen($old)) {
return pht(
'%s deleted the topic in %s',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
}
break;
case self::TYPE_PICTURE:
return pht(
'%s updated the room image for %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
break;
}
return parent::getTitleForFeed();
}
private function getRoomTitle() {
$author_phid = $this->getAuthorPHID();
$old = $this->getOldValue();
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case self::TYPE_TITLE:
if ($old && $new) {
$title = pht(
'%s renamed this room from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$old,
$new);
} else if ($old) {
$title = pht(
'%s deleted the room name "%s".',
$this->renderHandleLink($author_phid),
$old);
} else {
$title = pht(
'%s named this room "%s".',
$this->renderHandleLink($author_phid),
$new);
}
return $title;
break;
case self::TYPE_TOPIC:
if ($new) {
$title = pht(
'%s set the topic of this room to "%s".',
$this->renderHandleLink($author_phid),
$new);
} else if ($old) {
$title = pht(
'%s deleted the room topic "%s"',
$this->renderHandleLink($author_phid),
$old);
}
return $title;
break;
case self::TYPE_PICTURE:
return pht(
'%s updated the room image.',
$this->renderHandleLink($author_phid));
break;
case PhabricatorTransactions::TYPE_VIEW_POLICY:
return pht(
'%s changed the visibility of this room from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$this->renderPolicyName($old, 'old'),
$this->renderPolicyName($new, 'new'));
break;
case PhabricatorTransactions::TYPE_EDIT_POLICY:
return pht(
'%s changed the edit policy of this room from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$this->renderPolicyName($old, 'old'),
$this->renderPolicyName($new, 'new'));
break;
case PhabricatorTransactions::TYPE_JOIN_POLICY:
return pht(
'%s changed the join policy of this room from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$this->renderPolicyName($old, 'old'),
$this->renderPolicyName($new, 'new'));
break;
}
}
public function getRequiredHandlePHIDs() { public function getRequiredHandlePHIDs() {
$phids = parent::getRequiredHandlePHIDs(); $phids = parent::getRequiredHandlePHIDs();
@ -224,10 +90,6 @@ final class ConpherenceTransaction extends PhabricatorApplicationTransaction {
$phids[] = $this->getAuthorPHID(); $phids[] = $this->getAuthorPHID();
switch ($this->getTransactionType()) { switch ($this->getTransactionType()) {
case self::TYPE_TITLE:
case self::TYPE_PICTURE:
case self::TYPE_DATE_MARKER:
break;
case self::TYPE_PARTICIPANTS: case self::TYPE_PARTICIPANTS:
$phids = array_merge($phids, $this->getOldValue()); $phids = array_merge($phids, $this->getOldValue());
$phids = array_merge($phids, $this->getNewValue()); $phids = array_merge($phids, $this->getNewValue());

View file

@ -67,7 +67,7 @@ final class ConpherenceTransactionView extends AphrontView {
$transaction = $this->getConpherenceTransaction(); $transaction = $this->getConpherenceTransaction();
switch ($transaction->getTransactionType()) { switch ($transaction->getTransactionType()) {
case ConpherenceTransaction::TYPE_DATE_MARKER: case ConpherenceThreadDateMarkerTransaction::TRANSACTIONTYPE:
return javelin_tag( return javelin_tag(
'div', 'div',
array( array(
@ -216,17 +216,6 @@ final class ConpherenceTransactionView extends AphrontView {
$content = null; $content = null;
$handles = $this->getHandles(); $handles = $this->getHandles();
switch ($transaction->getTransactionType()) { switch ($transaction->getTransactionType()) {
case ConpherenceTransaction::TYPE_TITLE:
case ConpherenceTransaction::TYPE_TOPIC:
case ConpherenceTransaction::TYPE_PICTURE:
case ConpherenceTransaction::TYPE_PARTICIPANTS:
case PhabricatorTransactions::TYPE_VIEW_POLICY:
case PhabricatorTransactions::TYPE_EDIT_POLICY:
case PhabricatorTransactions::TYPE_JOIN_POLICY:
case PhabricatorTransactions::TYPE_EDGE:
$content = $transaction->getTitle();
$this->addClass('conpherence-edited');
break;
case PhabricatorTransactions::TYPE_COMMENT: case PhabricatorTransactions::TYPE_COMMENT:
$this->addClass('conpherence-comment'); $this->addClass('conpherence-comment');
$author = $handles[$transaction->getAuthorPHID()]; $author = $handles[$transaction->getAuthorPHID()];
@ -236,6 +225,10 @@ final class ConpherenceTransactionView extends AphrontView {
PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT); PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT);
$content_class = 'conpherence-message'; $content_class = 'conpherence-message';
break; break;
default:
$content = $transaction->getTitle();
$this->addClass('conpherence-edited');
break;
} }
$view = phutil_tag( $view = phutil_tag(

View file

@ -0,0 +1,8 @@
<?php
final class ConpherenceThreadDateMarkerTransaction
extends ConpherenceThreadTransactionType {
const TRANSACTIONTYPE = 'date-marker';
}

View file

@ -0,0 +1,29 @@
<?php
final class ConpherenceThreadPictureTransaction
extends ConpherenceThreadTransactionType {
const TRANSACTIONTYPE = 'picture';
public function generateOldValue($object) {
return $object->getProfileImagePHID();
}
public function applyInternalEffects($object, $value) {
$object->setProfileImagePHID($value);
}
public function getTitle() {
return pht(
'%s updated the room image.',
$this->renderAuthor());
}
public function getTitleForFeed() {
return pht(
'%s updated the room image for %s.',
$this->renderAuthor(),
$this->renderObject());
}
}

View file

@ -0,0 +1,75 @@
<?php
final class ConpherenceThreadTitleTransaction
extends ConpherenceThreadTransactionType {
const TRANSACTIONTYPE = 'title';
public function generateOldValue($object) {
return $object->getTitle();
}
public function applyInternalEffects($object, $value) {
$object->setTitle($value);
}
public function getTitle() {
$old = $this->getOldValue();
$new = $this->getNewValue();
if (strlen($old) && strlen($new)) {
return pht(
'%s renamed this room from %s to %s.',
$this->renderAuthor(),
$this->renderOldValue(),
$this->renderNewValue());
} else {
return pht(
'%s created this room.',
$this->renderAuthor());
}
}
public function getTitleForFeed() {
$old = $this->getOldValue();
$new = $this->getNewValue();
if (strlen($old) && strlen($new)) {
return pht(
'%s renamed %s from %s to %s.',
$this->renderAuthor(),
$this->renderObject(),
$this->renderOldValue(),
$this->renderNewValue());
} else {
return pht(
'%s created %s.',
$this->renderAuthor(),
$this->renderObject());
}
}
public function validateTransactions($object, array $xactions) {
$errors = array();
if ($this->isEmptyTextTransaction($object->getTitle(), $xactions)) {
$errors[] = $this->newRequiredError(
pht('Rooms must have a title.'));
}
$max_length = $object->getColumnMaximumByteLength('title');
foreach ($xactions as $xaction) {
$new_value = $xaction->getNewValue();
$new_length = strlen($new_value);
if ($new_length > $max_length) {
$errors[] = $this->newInvalidError(
pht('The title can be no longer than %s characters.',
new PhutilNumber($max_length)));
}
}
return $errors;
}
}

View file

@ -0,0 +1,69 @@
<?php
final class ConpherenceThreadTopicTransaction
extends ConpherenceThreadTransactionType {
const TRANSACTIONTYPE = 'topic';
public function generateOldValue($object) {
return $object->getTopic();
}
public function applyInternalEffects($object, $value) {
$object->setTopic($value);
}
public function getTitle() {
$old = $this->getOldValue();
$new = $this->getNewValue();
if (strlen($new)) {
return pht(
'%s set the room topic to %s.',
$this->renderAuthor(),
$this->renderNewValue());
} else {
return pht(
'%s removed the room topic.',
$this->renderAuthor());
}
}
public function getTitleForFeed() {
$old = $this->getOldValue();
$new = $this->getNewValue();
if (strlen($new)) {
return pht(
'%s set the room topic to %s in %s.',
$this->renderAuthor(),
$this->renderNewValue(),
$this->renderObject());
} else {
return pht(
'%s removed the room topic for %s.',
$this->renderAuthor(),
$this->renderObject());
}
}
public function validateTransactions($object, array $xactions) {
$errors = array();
$max_length = $object->getColumnMaximumByteLength('topic');
foreach ($xactions as $xaction) {
$new_value = $xaction->getNewValue();
$new_length = strlen($new_value);
if ($new_length > $max_length) {
$errors[] = $this->newInvalidError(
pht('The topic can be no longer than %s characters.',
new PhutilNumber($max_length)));
}
}
return $errors;
}
}

View file

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

View file

@ -42,14 +42,10 @@ final class PhabricatorCountdownApplication extends PhabricatorApplication {
'/countdown/' => array( '/countdown/' => array(
'(?:query/(?P<queryKey>[^/]+)/)?' '(?:query/(?P<queryKey>[^/]+)/)?'
=> 'PhabricatorCountdownListController', => 'PhabricatorCountdownListController',
'(?P<id>[1-9]\d*)/'
=> 'PhabricatorCountdownViewController',
'comment/(?P<id>[1-9]\d*)/' 'comment/(?P<id>[1-9]\d*)/'
=> 'PhabricatorCountdownCommentController', => 'PhabricatorCountdownCommentController',
$this->getEditRoutePattern('edit/') $this->getEditRoutePattern('edit/')
=> 'PhabricatorCountdownEditController', => 'PhabricatorCountdownEditController',
'delete/(?P<id>[1-9]\d*)/'
=> 'PhabricatorCountdownDeleteController',
), ),
); );
} }

View file

@ -0,0 +1,18 @@
<?php
final class CountdownEditConduitAPIMethod
extends PhabricatorEditEngineAPIMethod {
public function getAPIMethodName() {
return 'countdown.edit';
}
public function newEditEngine() {
return new PhabricatorCountdownEditEngine();
}
public function getMethodSummary() {
return pht(
'Apply transactions to create a new countdown or edit an existing one.');
}
}

View file

@ -0,0 +1,18 @@
<?php
final class CountdownSearchConduitAPIMethod
extends PhabricatorSearchEngineAPIMethod {
public function getAPIMethodName() {
return 'countdown.search';
}
public function newSearchEngine() {
return new PhabricatorCountdownSearchEngine();
}
public function getMethodSummary() {
return pht('Read information about countdowns.');
}
}

View file

@ -6,6 +6,4 @@ abstract class PhabricatorCountdownController extends PhabricatorController {
return $this->newApplicationMenu() return $this->newApplicationMenu()
->setSearchEngine(new PhabricatorCountdownSearchEngine()); ->setSearchEngine(new PhabricatorCountdownSearchEngine());
} }
} }

View file

@ -1,45 +0,0 @@
<?php
final class PhabricatorCountdownDeleteController
extends PhabricatorCountdownController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$id = $request->getURIData('id');
$countdown = id(new PhabricatorCountdownQuery())
->setViewer($viewer)
->withIDs(array($id))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$countdown) {
return new Aphront404Response();
}
if ($request->isFormPost()) {
$countdown->delete();
return id(new AphrontRedirectResponse())
->setURI('/countdown/');
}
$inst = pht(
'Are you sure you want to delete the countdown %s?',
$countdown->getTitle());
$dialog = new AphrontDialogView();
$dialog->setUser($request->getUser());
$dialog->setTitle(pht('Really delete this countdown?'));
$dialog->appendChild(phutil_tag('p', array(), $inst));
$dialog->addSubmitButton(pht('Delete'));
$dialog->addCancelButton('/countdown/');
$dialog->setSubmitURI($request->getPath());
return id(new AphrontDialogResponse())->setDialog($dialog);
}
}

View file

@ -28,7 +28,7 @@ final class PhabricatorCountdownViewController
$crumbs = $this $crumbs = $this
->buildApplicationCrumbs() ->buildApplicationCrumbs()
->addTextCrumb("C{$id}") ->addTextCrumb($countdown->getMonogram())
->setBorder(true); ->setBorder(true);
$epoch = $countdown->getEpoch(); $epoch = $countdown->getEpoch();
@ -102,14 +102,6 @@ final class PhabricatorCountdownViewController
->setDisabled(!$can_edit) ->setDisabled(!$can_edit)
->setWorkflow(!$can_edit)); ->setWorkflow(!$can_edit));
$curtain->addAction(
id(new PhabricatorActionView())
->setIcon('fa-times')
->setName(pht('Delete Countdown'))
->setHref($this->getApplicationURI("delete/{$id}/"))
->setDisabled(!$can_edit)
->setWorkflow(true));
return $curtain; return $curtain;
} }

View file

@ -81,7 +81,8 @@ final class PhabricatorCountdownEditEngine
->setKey('name') ->setKey('name')
->setLabel(pht('Name')) ->setLabel(pht('Name'))
->setIsRequired(true) ->setIsRequired(true)
->setTransactionType(PhabricatorCountdownTransaction::TYPE_TITLE) ->setTransactionType(
PhabricatorCountdownTitleTransaction::TRANSACTIONTYPE)
->setDescription(pht('The countdown name.')) ->setDescription(pht('The countdown name.'))
->setConduitDescription(pht('Rename the countdown.')) ->setConduitDescription(pht('Rename the countdown.'))
->setConduitTypeDescription(pht('New countdown name.')) ->setConduitTypeDescription(pht('New countdown name.'))
@ -89,7 +90,8 @@ final class PhabricatorCountdownEditEngine
id(new PhabricatorEpochEditField()) id(new PhabricatorEpochEditField())
->setKey('epoch') ->setKey('epoch')
->setLabel(pht('End Date')) ->setLabel(pht('End Date'))
->setTransactionType(PhabricatorCountdownTransaction::TYPE_EPOCH) ->setTransactionType(
PhabricatorCountdownEpochTransaction::TRANSACTIONTYPE)
->setDescription(pht('Date when the countdown ends.')) ->setDescription(pht('Date when the countdown ends.'))
->setConduitDescription(pht('Change the end date of the countdown.')) ->setConduitDescription(pht('Change the end date of the countdown.'))
->setConduitTypeDescription(pht('New countdown end date.')) ->setConduitTypeDescription(pht('New countdown end date.'))
@ -97,7 +99,8 @@ final class PhabricatorCountdownEditEngine
id(new PhabricatorRemarkupEditField()) id(new PhabricatorRemarkupEditField())
->setKey('description') ->setKey('description')
->setLabel(pht('Description')) ->setLabel(pht('Description'))
->setTransactionType(PhabricatorCountdownTransaction::TYPE_DESCRIPTION) ->setTransactionType(
PhabricatorCountdownDescriptionTransaction::TRANSACTIONTYPE)
->setDescription(pht('Description of the countdown.')) ->setDescription(pht('Description of the countdown.'))
->setConduitDescription(pht('Change the countdown description.')) ->setConduitDescription(pht('Change the countdown description.'))
->setConduitTypeDescription(pht('New description.')) ->setConduitTypeDescription(pht('New description.'))

View file

@ -14,10 +14,6 @@ final class PhabricatorCountdownEditor
public function getTransactionTypes() { public function getTransactionTypes() {
$types = parent::getTransactionTypes(); $types = parent::getTransactionTypes();
$types[] = PhabricatorCountdownTransaction::TYPE_TITLE;
$types[] = PhabricatorCountdownTransaction::TYPE_EPOCH;
$types[] = PhabricatorCountdownTransaction::TYPE_DESCRIPTION;
$types[] = PhabricatorTransactions::TYPE_EDGE; $types[] = PhabricatorTransactions::TYPE_EDGE;
$types[] = PhabricatorTransactions::TYPE_SPACE; $types[] = PhabricatorTransactions::TYPE_SPACE;
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY; $types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
@ -27,126 +23,6 @@ final class PhabricatorCountdownEditor
return $types; return $types;
} }
protected function getCustomTransactionOldValue(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorCountdownTransaction::TYPE_TITLE:
return $object->getTitle();
case PhabricatorCountdownTransaction::TYPE_DESCRIPTION:
return $object->getDescription();
case PhabricatorCountdownTransaction::TYPE_EPOCH:
return $object->getEpoch();
}
return parent::getCustomTransactionOldValue($object, $xaction);
}
protected function getCustomTransactionNewValue(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorCountdownTransaction::TYPE_TITLE:
return $xaction->getNewValue();
case PhabricatorCountdownTransaction::TYPE_DESCRIPTION:
return $xaction->getNewValue();
case PhabricatorCountdownTransaction::TYPE_EPOCH:
return $xaction->getNewValue()->getEpoch();
}
return parent::getCustomTransactionNewValue($object, $xaction);
}
protected function applyCustomInternalTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
$type = $xaction->getTransactionType();
switch ($type) {
case PhabricatorCountdownTransaction::TYPE_TITLE:
$object->setTitle($xaction->getNewValue());
return;
case PhabricatorCountdownTransaction::TYPE_DESCRIPTION:
$object->setDescription($xaction->getNewValue());
return;
case PhabricatorCountdownTransaction::TYPE_EPOCH:
$object->setEpoch($xaction->getNewValue());
return;
}
return parent::applyCustomInternalTransaction($object, $xaction);
}
protected function applyCustomExternalTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
$type = $xaction->getTransactionType();
switch ($type) {
case PhabricatorCountdownTransaction::TYPE_TITLE:
return;
case PhabricatorCountdownTransaction::TYPE_DESCRIPTION:
return;
case PhabricatorCountdownTransaction::TYPE_EPOCH:
return;
}
return parent::applyCustomExternalTransaction($object, $xaction);
}
protected function validateTransaction(
PhabricatorLiskDAO $object,
$type,
array $xactions) {
$errors = parent::validateTransaction($object, $type, $xactions);
switch ($type) {
case PhabricatorCountdownTransaction::TYPE_TITLE:
$missing = $this->validateIsEmptyTextField(
$object->getTitle(),
$xactions);
if ($missing) {
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Required'),
pht('You must give the countdown a name.'),
nonempty(last($xactions), null));
$error->setIsMissingFieldError(true);
$errors[] = $error;
}
break;
case PhabricatorCountdownTransaction::TYPE_EPOCH:
if (!$object->getEpoch() && !$xactions) {
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Required'),
pht('You must give the countdown an end date.'),
null);
$error->setIsMissingFieldError(true);
$errors[] = $error;
}
foreach ($xactions as $xaction) {
$value = $xaction->getNewValue();
if (!$value->isValid()) {
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid'),
pht('You must give the countdown a valid end date.'),
$xaction);
$errors[] = $error;
}
}
break;
}
return $errors;
}
protected function shouldSendMail( protected function shouldSendMail(
PhabricatorLiskDAO $object, PhabricatorLiskDAO $object,
array $xactions) { array $xactions) {

View file

@ -35,9 +35,9 @@ final class PhabricatorCountdownCountdownPHIDType extends PhabricatorPHIDType {
$name = $countdown->getTitle(); $name = $countdown->getTitle();
$id = $countdown->getID(); $id = $countdown->getID();
$handle->setName("C{$id}"); $handle->setName($countdown->getMonogram());
$handle->setFullName("C{$id}: {$name}"); $handle->setFullName(pht('%s: %s', $countdown->getMonogram(), $name));
$handle->setURI("/countdown/{$id}/"); $handle->setURI($countdown->getURI());
} }
} }

View file

@ -108,9 +108,9 @@ final class PhabricatorCountdownSearchEngine
$item = id(new PHUIObjectItemView()) $item = id(new PHUIObjectItemView())
->setUser($viewer) ->setUser($viewer)
->setObject($countdown) ->setObject($countdown)
->setObjectName("C{$id}") ->setObjectName($countdown->getMonogram())
->setHeader($countdown->getTitle()) ->setHeader($countdown->getTitle())
->setHref($this->getApplicationURI("{$id}/")) ->setHref($countdown->getURI())
->addByline( ->addByline(
pht( pht(
'Created by %s', 'Created by %s',

View file

@ -8,7 +8,9 @@ final class PhabricatorCountdown extends PhabricatorCountdownDAO
PhabricatorApplicationTransactionInterface, PhabricatorApplicationTransactionInterface,
PhabricatorTokenReceiverInterface, PhabricatorTokenReceiverInterface,
PhabricatorSpacesInterface, PhabricatorSpacesInterface,
PhabricatorProjectInterface { PhabricatorProjectInterface,
PhabricatorDestructibleInterface,
PhabricatorConduitResultInterface {
protected $title; protected $title;
protected $authorPHID; protected $authorPHID;
@ -141,8 +143,54 @@ final class PhabricatorCountdown extends PhabricatorCountdownDAO
/* -( PhabricatorSpacesInterface )------------------------------------------- */ /* -( PhabricatorSpacesInterface )------------------------------------------- */
public function getSpacePHID() { public function getSpacePHID() {
return $this->spacePHID; return $this->spacePHID;
} }
/* -( PhabricatorDestructibleInterface )----------------------------------- */
public function destroyObjectPermanently(
PhabricatorDestructionEngine $engine) {
$this->openTransaction();
$this->delete();
$this->saveTransaction();
}
/* -( PhabricatorConduitResultInterface )---------------------------------- */
public function getFieldSpecificationsForConduit() {
return array(
id(new PhabricatorConduitSearchFieldSpecification())
->setKey('title')
->setType('string')
->setDescription(pht('The title of the countdown.')),
id(new PhabricatorConduitSearchFieldSpecification())
->setKey('description')
->setType('remarkup')
->setDescription(pht('The description of the countdown.')),
id(new PhabricatorConduitSearchFieldSpecification())
->setKey('epoch')
->setType('epoch')
->setDescription(pht('The end date of the countdown.')),
);
}
public function getFieldValuesForConduit() {
return array(
'title' => $this->getTitle(),
'description' => array(
'raw' => $this->getDescription(),
),
'epoch' => (int)$this->getEpoch(),
);
}
public function getConduitSearchAttachments() {
return array();
}
} }

View file

@ -1,11 +1,7 @@
<?php <?php
final class PhabricatorCountdownTransaction final class PhabricatorCountdownTransaction
extends PhabricatorApplicationTransaction { extends PhabricatorModularTransaction {
const TYPE_TITLE = 'countdown:title';
const TYPE_EPOCH = 'countdown:epoch';
const TYPE_DESCRIPTION = 'countdown:description';
const MAILTAG_DETAILS = 'countdown:details'; const MAILTAG_DETAILS = 'countdown:details';
const MAILTAG_COMMENT = 'countdown:comment'; const MAILTAG_COMMENT = 'countdown:comment';
@ -23,62 +19,8 @@ final class PhabricatorCountdownTransaction
return new PhabricatorCountdownTransactionComment(); return new PhabricatorCountdownTransactionComment();
} }
public function getTitle() { public function getBaseTransactionClass() {
$author_phid = $this->getAuthorPHID(); return 'PhabricatorCountdownTransactionType';
$object_phid = $this->getObjectPHID();
$old = $this->getOldValue();
$new = $this->getNewValue();
$type = $this->getTransactionType();
switch ($type) {
case self::TYPE_TITLE:
return pht(
'%s renamed this countdown from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$old,
$new);
case self::TYPE_DESCRIPTION:
return pht(
'%s edited the description of this countdown.',
$this->renderHandleLink($author_phid));
case self::TYPE_EPOCH:
return pht(
'%s updated this countdown to end on %s.',
$this->renderHandleLink($author_phid),
phabricator_datetime($new, $this->getViewer()));
}
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_TITLE:
return pht(
'%s renamed %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
case self::TYPE_DESCRIPTION:
return pht(
'%s edited the description of %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
case self::TYPE_EPOCH:
return pht(
'%s edited the end date of %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
}
return parent::getTitleForFeed();
} }
public function getMailTags() { public function getMailTags() {
@ -88,9 +30,9 @@ final class PhabricatorCountdownTransaction
case PhabricatorTransactions::TYPE_COMMENT: case PhabricatorTransactions::TYPE_COMMENT:
$tags[] = self::MAILTAG_COMMENT; $tags[] = self::MAILTAG_COMMENT;
break; break;
case self::TYPE_TITLE: case PhabricatorCountdownTitleTransaction::TRANSACTIONTYPE:
case self::TYPE_EPOCH: case PhabricatorCountdownEpochTransaction::TRANSACTIONTYPE:
case self::TYPE_DESCRIPTION: case PhabricatorCountdownDescriptionTransaction::TRANSACTIONTYPE:
$tags[] = self::MAILTAG_DETAILS; $tags[] = self::MAILTAG_DETAILS;
break; break;
default: default:
@ -100,21 +42,4 @@ final class PhabricatorCountdownTransaction
return $tags; return $tags;
} }
public function hasChangeDetails() {
switch ($this->getTransactionType()) {
case self::TYPE_DESCRIPTION:
return ($this->getOldValue() !== null);
}
return parent::hasChangeDetails();
}
public function renderChangeDetails(PhabricatorUser $viewer) {
return $this->renderTextCorpusChangeDetails(
$viewer,
$this->getOldValue(),
$this->getNewValue());
}
} }

View file

@ -14,12 +14,12 @@ final class PhabricatorCountdownView extends AphrontView {
require_celerity_resource('phabricator-countdown-css'); require_celerity_resource('phabricator-countdown-css');
$header_text = array( $header_text = array(
'C'.$countdown->getID(), $countdown->getMonogram(),
' ', ' ',
phutil_tag( phutil_tag(
'a', 'a',
array( array(
'href' => '/countdown/'.$countdown->getID(), 'href' => $countdown->getURI(),
), ),
$countdown->getTitle()), $countdown->getTitle()),
); );

View file

@ -0,0 +1,55 @@
<?php
final class PhabricatorCountdownDescriptionTransaction
extends PhabricatorCountdownTransactionType {
const TRANSACTIONTYPE = 'countdown:description';
public function generateOldValue($object) {
return $object->getDescription();
}
public function applyInternalEffects($object, $value) {
$object->setDescription($value);
}
public function getTitle() {
return pht(
'%s updated the countdown description.',
$this->renderAuthor());
}
public function getTitleForFeed() {
return pht(
'%s updated the countdown description for %s.',
$this->renderAuthor(),
$this->renderObject());
}
public function hasChangeDetailView() {
return true;
}
public function getMailDiffSectionHeader() {
return pht('CHANGES TO COUNTDOWN 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,58 @@
<?php
final class PhabricatorCountdownEpochTransaction
extends PhabricatorCountdownTransactionType {
const TRANSACTIONTYPE = 'countdown:epoch';
public function generateOldValue($object) {
return (int)$object->getEpoch();
}
public function generateNewValue($object, $value) {
return $value->newPhutilDateTime()
->newAbsoluteDateTime()
->getEpoch();
}
public function applyInternalEffects($object, $value) {
$object->setEpoch($value);
}
public function getTitle() {
return pht(
'%s updated the countdown end from %s to %s.',
$this->renderAuthor(),
$this->renderOldDate(),
$this->renderNewDate());
}
public function getTitleForFeed() {
return pht(
'%s updated the countdown end for %s from %s to %s.',
$this->renderAuthor(),
$this->renderObject(),
$this->renderOldDate(),
$this->renderNewDate());
}
public function validateTransactions($object, array $xactions) {
$errors = array();
if (!$object->getEpoch() && !$xactions) {
$errors[] = $this->newRequiredError(
pht('You must give the countdown an end date.'));
return $errors;
}
foreach ($xactions as $xaction) {
$value = $xaction->getNewValue();
if (!$value->isValid()) {
$errors[] = $this->newInvalidError(
pht('You must give the countdown an end date.'));
}
}
return $errors;
}
}

View file

@ -0,0 +1,54 @@
<?php
final class PhabricatorCountdownTitleTransaction
extends PhabricatorCountdownTransactionType {
const TRANSACTIONTYPE = 'countdown:title';
public function generateOldValue($object) {
return $object->getTitle();
}
public function applyInternalEffects($object, $value) {
$object->setTitle($value);
}
public function getTitle() {
return pht(
'%s updated the title for this countdown from %s to %s.',
$this->renderAuthor(),
$this->renderOldValue(),
$this->renderNewValue());
}
public function getTitleForFeed() {
return pht(
'%s updated the title for this countdown from %s to %s.',
$this->renderAuthor(),
$this->renderOldValue(),
$this->renderNewValue());
}
public function validateTransactions($object, array $xactions) {
$errors = array();
if ($this->isEmptyTextTransaction($object->getTitle(), $xactions)) {
$errors[] = $this->newRequiredError(pht('Countdowns must have a title.'));
}
$max_length = $object->getColumnMaximumByteLength('title');
foreach ($xactions as $xaction) {
$new_value = $xaction->getNewValue();
$new_length = strlen($new_value);
if ($new_length > $max_length) {
$errors[] = $this->newInvalidError(
pht(
'Countdown titles must not be longer than %s character(s).',
new PhutilNumber($max_length)));
}
}
return $errors;
}
}

View file

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

View file

@ -124,10 +124,14 @@ abstract class DifferentialRevisionActionTransaction
list($options, $value) = $this->getActionOptions($viewer, $revision); list($options, $value) = $this->getActionOptions($viewer, $revision);
// Show the options if the user can select on behalf of two or more // Show the options if the user can select on behalf of two or more
// reviewers, or can force-accept on behalf of one or more reviewers. // reviewers, or can force-accept on behalf of one or more reviewers,
// or can accept on behalf of a reviewer other than themselves (see
// T12533).
$can_multi = (count($options) > 1); $can_multi = (count($options) > 1);
$can_force = (count($value) < count($options)); $can_force = (count($value) < count($options));
if ($can_multi || $can_force) { $not_self = (head_key($options) != $viewer->getPHID());
if ($can_multi || $can_force || $not_self) {
$field->setOptions($options); $field->setOptions($options);
$field->setValue($value); $field->setValue($value);
} }

View file

@ -41,8 +41,8 @@ final class PhabricatorFileInfoController extends PhabricatorFileController {
$ttl = $file->getTTL(); $ttl = $file->getTTL();
if ($ttl !== null) { if ($ttl !== null) {
$ttl_tag = id(new PHUITagView()) $ttl_tag = id(new PHUITagView())
->setType(PHUITagView::TYPE_STATE) ->setType(PHUITagView::TYPE_SHADE)
->setBackgroundColor(PHUITagView::COLOR_YELLOW) ->setShade(PHUITagView::COLOR_YELLOW)
->setName(pht('Temporary')); ->setName(pht('Temporary'));
$header->addTag($ttl_tag); $header->addTag($ttl_tag);
} }
@ -50,8 +50,8 @@ final class PhabricatorFileInfoController extends PhabricatorFileController {
$partial = $file->getIsPartial(); $partial = $file->getIsPartial();
if ($partial) { if ($partial) {
$partial_tag = id(new PHUITagView()) $partial_tag = id(new PHUITagView())
->setType(PHUITagView::TYPE_STATE) ->setType(PHUITagView::TYPE_SHADE)
->setBackgroundColor(PHUITagView::COLOR_ORANGE) ->setShade(PHUITagView::COLOR_ORANGE)
->setName(pht('Partial Upload')); ->setName(pht('Partial Upload'));
$header->addTag($partial_tag); $header->addTag($partial_tag);
} }

View file

@ -195,6 +195,10 @@ final class PhabricatorUserEditor extends PhabricatorEditor {
$user->saveTransaction(); $user->saveTransaction();
// The SSH key cache currently includes usernames, so dirty it. See T12554
// for discussion.
PhabricatorAuthSSHKeyQuery::deleteSSHKeyCache();
$user->sendUsernameChangeEmail($actor, $old_username); $user->sendUsernameChangeEmail($actor, $old_username);
} }

View file

@ -151,7 +151,7 @@ final class PhabricatorMentionRemarkupRule extends PhutilRemarkupRule {
} }
if (!$user->isResponsive()) { if (!$user->isResponsive()) {
$tag->setDotColor(PHUITagView::COLOR_GREY); $tag->setDotColor(PHUITagView::COLOR_VIOLET);
} else { } else {
if ($user->getAwayUntil()) { if ($user->getAwayUntil()) {
$away = PhabricatorCalendarEventInvitee::AVAILABILITY_AWAY; $away = PhabricatorCalendarEventInvitee::AVAILABILITY_AWAY;

View file

@ -62,7 +62,7 @@ final class PhabricatorPeopleUserPHIDType extends PhabricatorPHIDType {
$availability = null; $availability = null;
if (!$user->isResponsive()) { if (!$user->isResponsive()) {
$availability = PhabricatorObjectHandle::AVAILABILITY_DISABLED; $availability = PhabricatorObjectHandle::AVAILABILITY_NOEMAIL;
} else { } else {
$until = $user->getAwayUntil(); $until = $user->getAwayUntil();
if ($until) { if ($until) {

View file

@ -465,7 +465,7 @@ final class PhabricatorPeopleQuery
while (true) { while (true) {
foreach ($events as $event) { foreach ($events as $event) {
$from = $event->getStartDateTimeEpochForCache(); $from = $event->getStartDateTimeEpochForCache();
$to = $event->getEndDateTimeEpoch(); $to = $event->getEndDateTimeEpochForCache();
if (($from <= $cursor) && ($to > $cursor)) { if (($from <= $cursor) && ($to > $cursor)) {
$cursor = $to; $cursor = $to;
if (!$next_event) { if (!$next_event) {
@ -483,7 +483,7 @@ final class PhabricatorPeopleQuery
$availability_type = $invitee->getDisplayAvailability($next_event); $availability_type = $invitee->getDisplayAvailability($next_event);
$availability = array( $availability = array(
'until' => $cursor, 'until' => $cursor,
'eventPHID' => $event->getPHID(), 'eventPHID' => $next_event->getPHID(),
'availability' => $availability_type, 'availability' => $availability_type,
); );
@ -496,7 +496,7 @@ final class PhabricatorPeopleQuery
// simultaneously we should accommodate that. However, it's complex // simultaneously we should accommodate that. However, it's complex
// to compute, rare, and probably not confusing most of the time. // to compute, rare, and probably not confusing most of the time.
$availability_ttl = $next_event->getStartDateTimeEpochForCache(); $availability_ttl = $next_event->getEndDateTimeEpochForCache();
} else { } else {
$availability = array( $availability = array(
'until' => null, 'until' => null,

View file

@ -1082,7 +1082,7 @@ final class PhabricatorUser
'UPDATE %T SET availabilityCache = %s, availabilityCacheTTL = %nd 'UPDATE %T SET availabilityCache = %s, availabilityCacheTTL = %nd
WHERE id = %d', WHERE id = %d',
$this->getTableName(), $this->getTableName(),
json_encode($availability), phutil_json_encode($availability),
$ttl, $ttl,
$this->getID()); $this->getID());
unset($unguarded); unset($unguarded);

View file

@ -68,7 +68,7 @@ final class PhabricatorUserCardView extends AphrontTagView {
} else if (!$user->getIsEmailVerified()) { } else if (!$user->getIsEmailVerified()) {
$tag_icon = 'fa-envelope'; $tag_icon = 'fa-envelope';
$tag_title = pht('Email Not Verified'); $tag_title = pht('Email Not Verified');
$tag_shade = PHUITagView::COLOR_RED; $tag_shade = PHUITagView::COLOR_VIOLET;
} else if ($user->getIsAdmin()) { } else if ($user->getIsAdmin()) {
$tag_icon = 'fa-star'; $tag_icon = 'fa-star';
$tag_title = pht('Administrator'); $tag_title = pht('Administrator');

View file

@ -6,6 +6,7 @@ final class PhabricatorObjectHandle
const AVAILABILITY_FULL = 'full'; const AVAILABILITY_FULL = 'full';
const AVAILABILITY_NONE = 'none'; const AVAILABILITY_NONE = 'none';
const AVAILABILITY_NOEMAIL = 'no-email';
const AVAILABILITY_PARTIAL = 'partial'; const AVAILABILITY_PARTIAL = 'partial';
const AVAILABILITY_DISABLED = 'disabled'; const AVAILABILITY_DISABLED = 'disabled';

View file

@ -0,0 +1,43 @@
<?php
final class PhabricatorPhortuneTestCase
extends PhabricatorTestCase {
protected function getPhabricatorTestCaseConfiguration() {
return array(
self::PHABRICATOR_TESTCONFIG_BUILD_STORAGE_FIXTURES => true,
);
}
public function testNewPhortuneAccount() {
$user = $this->generateNewTestUser();
$content_source = $this->newContentSource();
$accounts = PhortuneAccountQuery::loadAccountsForUser(
$user,
$content_source);
$this->assertEqual(
1,
count($accounts),
pht('Creation of default account for users with no accounts.'));
// Reload the account. The user should be able to view and edit it, and
// should be a member.
$account = head($accounts);
$account = id(new PhortuneAccountQuery())
->setViewer($user)
->withPHIDs(array($account->getPHID()))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
$this->assertEqual(true, ($account instanceof PhortuneAccount));
$this->assertEqual(array($user->getPHID()), $account->getMemberPHIDs());
}
}

View file

@ -67,7 +67,18 @@ final class PhabricatorPhortuneApplication extends PhabricatorApplication {
), ),
'account/' => array( 'account/' => array(
'' => 'PhortuneAccountListController', '' => 'PhortuneAccountListController',
$this->getEditRoutePattern('edit/')
=> 'PhortuneAccountEditController',
'edit/(?:(?P<id>\d+)/)?' => 'PhortuneAccountEditController', 'edit/(?:(?P<id>\d+)/)?' => 'PhortuneAccountEditController',
'add/manager/(?:(?P<id>\d+)/)?'
=> 'PhortuneAccountAddManagerController',
'billing/(?:(?P<id>\d+)/)?' => 'PhortuneAccountBillingController',
'subscription/(?:(?P<id>\d+)/)?'
=> 'PhortuneAccountSubscriptionController',
'manager/' => array(
'(?:(?P<id>\d+)/)?' => 'PhortuneAccountManagerController',
'add/(?:(?P<id>\d+)/)?' => 'PhortuneAccountAddManagerController',
),
), ),
'product/' => array( 'product/' => array(
'' => 'PhortuneProductListController', '' => 'PhortuneProductListController',
@ -87,6 +98,10 @@ final class PhabricatorPhortuneApplication extends PhabricatorApplication {
=> 'PhortuneMerchantEditController', => 'PhortuneMerchantEditController',
'orders/(?P<merchantID>\d+)/(?:query/(?P<queryKey>[^/]+)/)?' 'orders/(?P<merchantID>\d+)/(?:query/(?P<queryKey>[^/]+)/)?'
=> 'PhortuneCartListController', => 'PhortuneCartListController',
'manager/' => array(
'(?:(?P<id>\d+)/)?' => 'PhortuneMerchantManagerController',
'add/(?:(?P<id>\d+)/)?' => 'PhortuneMerchantAddManagerController',
),
'(?P<merchantID>\d+)/' => array( '(?P<merchantID>\d+)/' => array(
'cart/(?P<id>\d+)/' => array( 'cart/(?P<id>\d+)/' => array(
'' => 'PhortuneCartViewController', '' => 'PhortuneCartViewController',

View file

@ -5,17 +5,9 @@ final class PhortuneLandingController extends PhortuneController {
public function handleRequest(AphrontRequest $request) { public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer(); $viewer = $request->getViewer();
$accounts = id(new PhortuneAccountQuery()) $accounts = PhortuneAccountQuery::loadAccountsForUser(
->setViewer($viewer)
->withMemberPHIDs(array($viewer->getPHID()))
->execute();
if (!$accounts) {
$account = PhortuneAccount::createNewAccount(
$viewer, $viewer,
PhabricatorContentSource::newFromRequest($request)); PhabricatorContentSource::newFromRequest($request));
$accounts = array($account);
}
if (count($accounts) == 1) { if (count($accounts) == 1) {
$account = head($accounts); $account = head($accounts);

View file

@ -0,0 +1,75 @@
<?php
final class PhortuneAccountAddManagerController extends PhortuneController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$id = $request->getURIData('id');
$account = id(new PhortuneAccountQuery())
->setViewer($viewer)
->withIDs(array($id))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$account) {
return new Aphront404Response();
}
$v_managers = array();
$e_managers = null;
$account_uri = $this->getApplicationURI("/account/manager/{$id}/");
if ($request->isFormPost()) {
$xactions = array();
$v_managers = $request->getArr('managerPHIDs');
$type_edge = PhabricatorTransactions::TYPE_EDGE;
$xactions[] = id(new PhortuneAccountTransaction())
->setTransactionType($type_edge)
->setMetadataValue(
'edge:type',
PhortuneAccountHasMemberEdgeType::EDGECONST)
->setNewValue(
array(
'+' => array_fuse($v_managers),
));
$editor = id(new PhortuneAccountEditor())
->setActor($viewer)
->setContentSourceFromRequest($request)
->setContinueOnNoEffect(true);
try {
$editor->applyTransactions($account, $xactions);
return id(new AphrontRedirectResponse())->setURI($account_uri);
} catch (PhabricatorApplicationTransactionValidationException $ex) {
$validation_exception = $ex;
$e_managers = $ex->getShortMessage($type_edge);
}
}
$form = id(new AphrontFormView())
->setUser($viewer)
->appendControl(
id(new AphrontFormTokenizerControl())
->setDatasource(new PhabricatorPeopleDatasource())
->setLabel(pht('Managers'))
->setName('managerPHIDs')
->setValue($v_managers)
->setError($e_managers));
return $this->newDialog()
->setTitle(pht('Add New Manager'))
->appendForm($form)
->setWidth(AphrontDialogView::WIDTH_FORM)
->addCancelButton($account_uri)
->addSubmitButton(pht('Add Manager'));
}
}

View file

@ -0,0 +1,161 @@
<?php
final class PhortuneAccountBillingController
extends PhortuneAccountProfileController {
public function handleRequest(AphrontRequest $request) {
$response = $this->loadAccount();
if ($response) {
return $response;
}
$account = $this->getAccount();
$title = $account->getName();
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Billing'));
$header = $this->buildHeaderView();
$methods = $this->buildPaymentMethodsSection($account);
$charge_history = $this->buildChargeHistorySection($account);
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setFooter(array(
$methods,
$charge_history,
));
$navigation = $this->buildSideNavView('billing');
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->setNavigation($navigation)
->appendChild($view);
}
private function buildPaymentMethodsSection(PhortuneAccount $account) {
$viewer = $this->getViewer();
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$account,
PhabricatorPolicyCapability::CAN_EDIT);
$id = $account->getID();
// TODO: Allow adding a card here directly
$add = id(new PHUIButtonView())
->setTag('a')
->setText(pht('New Payment Method'))
->setIcon('fa-plus')
->setHref($this->getApplicationURI("{$id}/card/new/"));
$header = id(new PHUIHeaderView())
->setHeader(pht('Payment Methods'));
$list = id(new PHUIObjectItemListView())
->setUser($viewer)
->setFlush(true)
->setNoDataString(
pht('No payment methods associated with this account.'));
$methods = id(new PhortunePaymentMethodQuery())
->setViewer($viewer)
->withAccountPHIDs(array($account->getPHID()))
->withStatuses(
array(
PhortunePaymentMethod::STATUS_ACTIVE,
))
->execute();
foreach ($methods as $method) {
$id = $method->getID();
$item = new PHUIObjectItemView();
$item->setHeader($method->getFullDisplayName());
switch ($method->getStatus()) {
case PhortunePaymentMethod::STATUS_ACTIVE:
$item->setStatusIcon('fa-check green');
$disable_uri = $this->getApplicationURI('card/'.$id.'/disable/');
$item->addAction(
id(new PHUIListItemView())
->setIcon('fa-times')
->setHref($disable_uri)
->setDisabled(!$can_edit)
->setWorkflow(true));
break;
case PhortunePaymentMethod::STATUS_DISABLED:
$item->setStatusIcon('fa-ban lightbluetext');
$item->setDisabled(true);
break;
}
$provider = $method->buildPaymentProvider();
$item->addAttribute($provider->getPaymentMethodProviderDescription());
$edit_uri = $this->getApplicationURI('card/'.$id.'/edit/');
$item->addAction(
id(new PHUIListItemView())
->setIcon('fa-pencil')
->setHref($edit_uri)
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit));
$list->addItem($item);
}
return id(new PHUIObjectBoxView())
->setHeader($header)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setObjectList($list);
}
private function buildChargeHistorySection(PhortuneAccount $account) {
$viewer = $this->getViewer();
$charges = id(new PhortuneChargeQuery())
->setViewer($viewer)
->withAccountPHIDs(array($account->getPHID()))
->needCarts(true)
->setLimit(10)
->execute();
$phids = array();
foreach ($charges as $charge) {
$phids[] = $charge->getProviderPHID();
$phids[] = $charge->getCartPHID();
$phids[] = $charge->getMerchantPHID();
$phids[] = $charge->getPaymentMethodPHID();
}
$handles = $this->loadViewerHandles($phids);
$charges_uri = $this->getApplicationURI($account->getID().'/charge/');
$table = id(new PhortuneChargeTableView())
->setUser($viewer)
->setCharges($charges)
->setHandles($handles);
$header = id(new PHUIHeaderView())
->setHeader(pht('Charge History'))
->addActionLink(
id(new PHUIButtonView())
->setTag('a')
->setIcon('fa-list')
->setHref($charges_uri)
->setText(pht('View All Charges')));
return id(new PHUIObjectBoxView())
->setHeader($header)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setTable($table);
}
}

View file

@ -0,0 +1,64 @@
<?php
abstract class PhortuneAccountController
extends PhortuneController {
private $account;
protected function getAccount() {
return $this->account;
}
protected function buildApplicationCrumbs() {
$crumbs = parent::buildApplicationCrumbs();
$account = $this->getAccount();
if ($account) {
$crumbs->addTextCrumb($account->getName(), $account->getURI());
}
return $crumbs;
}
protected function loadAccount() {
// TODO: Currently, you must be able to edit an account to view the detail
// page, because the account must be broadly visible so merchants can
// process orders but merchants should not be able to see all the details
// of an account. Ideally the profile pages should be visible to merchants,
// too, just with less information.
return $this->loadAccountForEdit();
}
protected function loadAccountForEdit() {
$viewer = $this->getViewer();
$request = $this->getRequest();
$account_id = $request->getURIData('accountID');
if (!$account_id) {
$account_id = $request->getURIData('id');
}
if (!$account_id) {
return new Aphront404Response();
}
$account = id(new PhortuneAccountQuery())
->setViewer($viewer)
->withIDs(array($account_id))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$account) {
return new Aphront404Response();
}
$this->account = $account;
return null;
}
}

View file

@ -1,137 +1,11 @@
<?php <?php
final class PhortuneAccountEditController extends PhortuneController { final class PhortuneAccountEditController extends
PhortuneController {
public function handleRequest(AphrontRequest $request) { public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer(); return id(new PhortuneAccountEditEngine())
$id = $request->getURIData('id'); ->setController($this)
->buildResponse();
if ($id) {
$account = id(new PhortuneAccountQuery())
->setViewer($viewer)
->withIDs(array($id))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$account) {
return new Aphront404Response();
}
$is_new = false;
} else {
$account = PhortuneAccount::initializeNewAccount($viewer);
$account->attachMemberPHIDs(array($viewer->getPHID()));
$is_new = true;
}
$v_name = $account->getName();
$e_name = true;
$v_members = $account->getMemberPHIDs();
$e_members = null;
$validation_exception = null;
if ($request->isFormPost()) {
$v_name = $request->getStr('name');
$v_members = $request->getArr('memberPHIDs');
$type_name = PhortuneAccountTransaction::TYPE_NAME;
$type_edge = PhabricatorTransactions::TYPE_EDGE;
$xactions = array();
$xactions[] = id(new PhortuneAccountTransaction())
->setTransactionType($type_name)
->setNewValue($v_name);
$xactions[] = id(new PhortuneAccountTransaction())
->setTransactionType($type_edge)
->setMetadataValue(
'edge:type',
PhortuneAccountHasMemberEdgeType::EDGECONST)
->setNewValue(
array(
'=' => array_fuse($v_members),
));
$editor = id(new PhortuneAccountEditor())
->setActor($viewer)
->setContentSourceFromRequest($request)
->setContinueOnNoEffect(true);
try {
$editor->applyTransactions($account, $xactions);
$account_uri = $this->getApplicationURI($account->getID().'/');
return id(new AphrontRedirectResponse())->setURI($account_uri);
} catch (PhabricatorApplicationTransactionValidationException $ex) {
$validation_exception = $ex;
$e_name = $ex->getShortMessage($type_name);
$e_members = $ex->getShortMessage($type_edge);
} }
} }
$crumbs = $this->buildApplicationCrumbs();
$crumbs->setBorder(true);
if ($is_new) {
$cancel_uri = $this->getApplicationURI('account/');
$crumbs->addTextCrumb(pht('Accounts'), $cancel_uri);
$crumbs->addTextCrumb(pht('Create Account'));
$title = pht('Create Payment Account');
$submit_button = pht('Create Account');
} else {
$cancel_uri = $this->getApplicationURI($account->getID().'/');
$crumbs->addTextCrumb($account->getName(), $cancel_uri);
$crumbs->addTextCrumb(pht('Edit'));
$title = pht('Edit %s', $account->getName());
$submit_button = pht('Save Changes');
}
$form = id(new AphrontFormView())
->setUser($viewer)
->appendChild(
id(new AphrontFormTextControl())
->setName('name')
->setLabel(pht('Name'))
->setValue($v_name)
->setError($e_name))
->appendControl(
id(new AphrontFormTokenizerControl())
->setDatasource(new PhabricatorPeopleDatasource())
->setLabel(pht('Members'))
->setName('memberPHIDs')
->setValue($v_members)
->setError($e_members))
->appendChild(
id(new AphrontFormSubmitControl())
->setValue($submit_button)
->addCancelButton($cancel_uri));
$box = id(new PHUIObjectBoxView())
->setHeaderText(pht('Account'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setValidationException($validation_exception)
->setForm($form);
$header = id(new PHUIHeaderView())
->setHeader($title)
->setHeaderIcon('fa-pencil');
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setFooter(array(
$box,
));
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($view);
}
}

View file

@ -0,0 +1,85 @@
<?php
final class PhortuneAccountManagerController
extends PhortuneAccountProfileController {
public function handleRequest(AphrontRequest $request) {
$response = $this->loadAccount();
if ($response) {
return $response;
}
$account = $this->getAccount();
$title = $account->getName();
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Managers'));
$header = $this->buildHeaderView();
$members = $this->buildMembersSection($account);
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setFooter(array(
$members,
));
$navigation = $this->buildSideNavView('managers');
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->setNavigation($navigation)
->appendChild($view);
}
private function buildMembersSection(PhortuneAccount $account) {
$viewer = $this->getViewer();
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$account,
PhabricatorPolicyCapability::CAN_EDIT);
$id = $account->getID();
$add = id(new PHUIButtonView())
->setTag('a')
->setText(pht('New Manager'))
->setIcon('fa-plus')
->setWorkflow(true)
->setDisabled(!$can_edit)
->setHref("/phortune/account/manager/add/{$id}/");
$header = id(new PHUIHeaderView())
->setHeader(pht('Account Managers'))
->addActionLink($add);
$list = id(new PHUIObjectItemListView())
->setUser($viewer);
$member_phids = $account->getMemberPHIDs();
$handles = $viewer->loadHandles($member_phids);
foreach ($member_phids as $member_phid) {
$image_uri = $handles[$member_phid]->getImageURI();
$image_href = $handles[$member_phid]->getURI();
$person = $handles[$member_phid];
$member = id(new PHUIObjectItemView())
->setImageURI($image_uri)
->setHref($image_href)
->setHeader($person->getFullName())
->addAttribute(pht('Account Manager'));
$list->addItem($member);
}
return id(new PHUIObjectBoxView())
->setHeader($header)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setObjectList($list);
}
}

View file

@ -0,0 +1,68 @@
<?php
abstract class PhortuneAccountProfileController
extends PhortuneAccountController {
public function buildApplicationMenu() {
return $this->buildSideNavView()->getMenu();
}
protected function buildHeaderView() {
$viewer = $this->getViewer();
$account = $this->getAccount();
$title = $account->getName();
$header = id(new PHUIHeaderView())
->setUser($viewer)
->setHeader($title)
->setHeaderIcon('fa-user-circle');
return $header;
}
protected function buildApplicationCrumbs() {
$crumbs = parent::buildApplicationCrumbs();
$crumbs->setBorder(true);
return $crumbs;
}
protected function buildSideNavView($filter = null) {
$viewer = $this->getViewer();
$account = $this->getAccount();
$id = $account->getID();
$nav = id(new AphrontSideNavFilterView())
->setBaseURI(new PhutilURI($this->getApplicationURI()));
$nav->addLabel(pht('Account'));
$nav->addFilter(
'overview',
pht('Overview'),
$this->getApplicationURI("/{$id}/"),
'fa-user-circle');
$nav->addFilter(
'subscriptions',
pht('Subscriptions'),
$this->getApplicationURI("/account/subscription/{$id}/"),
'fa-retweet');
$nav->addFilter(
'billing',
pht('Billing / History'),
$this->getApplicationURI("/account/billing/{$id}/"),
'fa-credit-card');
$nav->addFilter(
'managers',
pht('Managers'),
$this->getApplicationURI("/account/manager/{$id}/"),
'fa-group');
$nav->selectFilter($filter);
return $nav;
}
}

View file

@ -0,0 +1,62 @@
<?php
final class PhortuneAccountSubscriptionController
extends PhortuneAccountProfileController {
public function handleRequest(AphrontRequest $request) {
$response = $this->loadAccount();
if ($response) {
return $response;
}
$account = $this->getAccount();
$title = $account->getName();
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Subscriptions'));
$header = $this->buildHeaderView();
$subscriptions = $this->buildSubscriptionsSection($account);
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setFooter(array(
$subscriptions,
));
$navigation = $this->buildSideNavView('subscriptions');
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->setNavigation($navigation)
->appendChild($view);
}
private function buildSubscriptionsSection(PhortuneAccount $account) {
$viewer = $this->getViewer();
$subscriptions = id(new PhortuneSubscriptionQuery())
->setViewer($viewer)
->withAccountPHIDs(array($account->getPHID()))
->setLimit(25)
->execute();
$handles = $this->loadViewerHandles(mpull($subscriptions, 'getPHID'));
$table = id(new PhortuneSubscriptionTableView())
->setUser($viewer)
->setHandles($handles)
->setSubscriptions($subscriptions);
$header = id(new PHUIHeaderView())
->setHeader(pht('Subscriptions'));
return id(new PHUIObjectBoxView())
->setHeader($header)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setTable($table);
}
}

View file

@ -1,32 +1,19 @@
<?php <?php
final class PhortuneAccountViewController extends PhortuneController { final class PhortuneAccountViewController
extends PhortuneAccountProfileController {
public function handleRequest(AphrontRequest $request) { public function handleRequest(AphrontRequest $request) {
$viewer = $this->getViewer(); $response = $this->loadAccount();
if ($response) {
// TODO: Currently, you must be able to edit an account to view the detail return $response;
// page, because the account must be broadly visible so merchants can
// process orders but merchants should not be able to see all the details
// of an account. Ideally this page should be visible to merchants, too,
// just with less information.
$can_edit = true;
$account = id(new PhortuneAccountQuery())
->setViewer($viewer)
->withIDs(array($request->getURIData('accountID')))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$account) {
return new Aphront404Response();
} }
$account = $this->getAccount();
$title = $account->getName(); $title = $account->getName();
$viewer = $this->getViewer();
$invoices = id(new PhortuneCartQuery()) $invoices = id(new PhortuneCartQuery())
->setViewer($viewer) ->setViewer($viewer)
->withAccountPHIDs(array($account->getPHID())) ->withAccountPHIDs(array($account->getPHID()))
@ -35,19 +22,14 @@ final class PhortuneAccountViewController extends PhortuneController {
->execute(); ->execute();
$crumbs = $this->buildApplicationCrumbs(); $crumbs = $this->buildApplicationCrumbs();
$this->addAccountCrumb($crumbs, $account, $link = false);
$crumbs->setBorder(true); $crumbs->setBorder(true);
$header = id(new PHUIHeaderView()) $header = $this->buildHeaderView();
->setHeader($title)
->setHeaderIcon('fa-credit-card');
$curtain = $this->buildCurtainView($account, $invoices); $curtain = $this->buildCurtainView($account);
$status = $this->buildStatusView($account, $invoices);
$invoices = $this->buildInvoicesSection($account, $invoices); $invoices = $this->buildInvoicesSection($account, $invoices);
$purchase_history = $this->buildPurchaseHistorySection($account); $purchase_history = $this->buildPurchaseHistorySection($account);
$charge_history = $this->buildChargeHistorySection($account);
$subscriptions = $this->buildSubscriptionsSection($account);
$payment_methods = $this->buildPaymentMethodsSection($account);
$timeline = $this->buildTransactionTimeline( $timeline = $this->buildTransactionTimeline(
$account, $account,
@ -58,22 +40,34 @@ final class PhortuneAccountViewController extends PhortuneController {
->setHeader($header) ->setHeader($header)
->setCurtain($curtain) ->setCurtain($curtain)
->setMainColumn(array( ->setMainColumn(array(
$status,
$invoices, $invoices,
$purchase_history, $purchase_history,
$charge_history,
$subscriptions,
$payment_methods,
$timeline, $timeline,
)); ));
$navigation = $this->buildSideNavView('overview');
return $this->newPage() return $this->newPage()
->setTitle($title) ->setTitle($title)
->setCrumbs($crumbs) ->setCrumbs($crumbs)
->setNavigation($navigation)
->appendChild($view); ->appendChild($view);
} }
private function buildCurtainView(PhortuneAccount $account, $invoices) { private function buildStatusView(PhortuneAccount $account, $invoices) {
$status_items = $this->getStatusItemsForAccount($account, $invoices);
$view = array();
foreach ($status_items as $item) {
$view[] = id(new PHUIInfoView())
->setSeverity(idx($item, 'severity'))
->appendChild(idx($item, 'note'));
}
return $view;
}
private function buildCurtainView(PhortuneAccount $account) {
$viewer = $this->getViewer(); $viewer = $this->getViewer();
$can_edit = PhabricatorPolicyFilter::hasCapability( $can_edit = PhabricatorPolicyFilter::hasCapability(
@ -92,19 +86,6 @@ final class PhortuneAccountViewController extends PhortuneController {
->setDisabled(!$can_edit) ->setDisabled(!$can_edit)
->setWorkflow(!$can_edit)); ->setWorkflow(!$can_edit));
$status_items = $this->getStatusItemsForAccount($account, $invoices);
$status_view = new PHUIStatusListView();
foreach ($status_items as $item) {
$status_view->addItem(
id(new PHUIStatusItemView())
->setIcon(
idx($item, 'icon'),
idx($item, 'color'),
idx($item, 'label'))
->setTarget(idx($item, 'target'))
->setNote(idx($item, 'note')));
}
$member_phids = $account->getMemberPHIDs(); $member_phids = $account->getMemberPHIDs();
$handles = $viewer->loadHandles($member_phids); $handles = $viewer->loadHandles($member_phids);
@ -125,89 +106,12 @@ final class PhortuneAccountViewController extends PhortuneController {
} }
$curtain->newPanel() $curtain->newPanel()
->setHeaderText(pht('Status')) ->setHeaderText(pht('Managers'))
->appendChild($status_view);
$curtain->newPanel()
->setHeaderText(pht('Members'))
->appendChild($member_list); ->appendChild($member_list);
return $curtain; return $curtain;
} }
private function buildPaymentMethodsSection(PhortuneAccount $account) {
$viewer = $this->getViewer();
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$account,
PhabricatorPolicyCapability::CAN_EDIT);
$id = $account->getID();
$header = id(new PHUIHeaderView())
->setHeader(pht('Payment Methods'));
$list = id(new PHUIObjectItemListView())
->setUser($viewer)
->setFlush(true)
->setNoDataString(
pht('No payment methods associated with this account.'));
$methods = id(new PhortunePaymentMethodQuery())
->setViewer($viewer)
->withAccountPHIDs(array($account->getPHID()))
->withStatuses(
array(
PhortunePaymentMethod::STATUS_ACTIVE,
))
->execute();
foreach ($methods as $method) {
$id = $method->getID();
$item = new PHUIObjectItemView();
$item->setHeader($method->getFullDisplayName());
switch ($method->getStatus()) {
case PhortunePaymentMethod::STATUS_ACTIVE:
$item->setStatusIcon('fa-check green');
$disable_uri = $this->getApplicationURI('card/'.$id.'/disable/');
$item->addAction(
id(new PHUIListItemView())
->setIcon('fa-times')
->setHref($disable_uri)
->setDisabled(!$can_edit)
->setWorkflow(true));
break;
case PhortunePaymentMethod::STATUS_DISABLED:
$item->setStatusIcon('fa-ban lightbluetext');
$item->setDisabled(true);
break;
}
$provider = $method->buildPaymentProvider();
$item->addAttribute($provider->getPaymentMethodProviderDescription());
$edit_uri = $this->getApplicationURI('card/'.$id.'/edit/');
$item->addAction(
id(new PHUIListItemView())
->setIcon('fa-pencil')
->setHref($edit_uri)
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit));
$list->addItem($item);
}
return id(new PHUIObjectBoxView())
->setHeader($header)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setObjectList($list);
}
private function buildInvoicesSection( private function buildInvoicesSection(
PhortuneAccount $account, PhortuneAccount $account,
array $carts) { array $carts) {
@ -289,84 +193,6 @@ final class PhortuneAccountViewController extends PhortuneController {
->setTable($table); ->setTable($table);
} }
private function buildChargeHistorySection(PhortuneAccount $account) {
$viewer = $this->getViewer();
$charges = id(new PhortuneChargeQuery())
->setViewer($viewer)
->withAccountPHIDs(array($account->getPHID()))
->needCarts(true)
->setLimit(10)
->execute();
$phids = array();
foreach ($charges as $charge) {
$phids[] = $charge->getProviderPHID();
$phids[] = $charge->getCartPHID();
$phids[] = $charge->getMerchantPHID();
$phids[] = $charge->getPaymentMethodPHID();
}
$handles = $this->loadViewerHandles($phids);
$charges_uri = $this->getApplicationURI($account->getID().'/charge/');
$table = id(new PhortuneChargeTableView())
->setUser($viewer)
->setCharges($charges)
->setHandles($handles);
$header = id(new PHUIHeaderView())
->setHeader(pht('Recent Charges'))
->addActionLink(
id(new PHUIButtonView())
->setTag('a')
->setIcon('fa-list')
->setHref($charges_uri)
->setText(pht('View All Charges')));
return id(new PHUIObjectBoxView())
->setHeader($header)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setTable($table);
}
private function buildSubscriptionsSection(PhortuneAccount $account) {
$viewer = $this->getViewer();
$subscriptions = id(new PhortuneSubscriptionQuery())
->setViewer($viewer)
->withAccountPHIDs(array($account->getPHID()))
->setLimit(10)
->execute();
$subscriptions_uri = $this->getApplicationURI(
$account->getID().'/subscription/');
$handles = $this->loadViewerHandles(mpull($subscriptions, 'getPHID'));
$table = id(new PhortuneSubscriptionTableView())
->setUser($viewer)
->setHandles($handles)
->setSubscriptions($subscriptions);
$header = id(new PHUIHeaderView())
->setHeader(pht('Recent Subscriptions'))
->addActionLink(
id(new PHUIButtonView())
->setTag('a')
->setIcon(
id(new PHUIIconView())
->setIcon('fa-list'))
->setHref($subscriptions_uri)
->setText(pht('View All Subscriptions')));
return id(new PHUIObjectBoxView())
->setHeader($header)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setTable($table);
}
protected function buildApplicationCrumbs() { protected function buildApplicationCrumbs() {
$crumbs = parent::buildApplicationCrumbs(); $crumbs = parent::buildApplicationCrumbs();
@ -382,25 +208,25 @@ final class PhortuneAccountViewController extends PhortuneController {
private function getStatusItemsForAccount( private function getStatusItemsForAccount(
PhortuneAccount $account, PhortuneAccount $account,
array $invoices) { array $invoices) {
$viewer = $this->getViewer();
assert_instances_of($invoices, 'PhortuneCart'); assert_instances_of($invoices, 'PhortuneCart');
$items = array(); $items = array();
$methods = id(new PhortunePaymentMethodQuery())
->setViewer($viewer)
->withAccountPHIDs(array($account->getPHID()))
->withStatuses(
array(
PhortunePaymentMethod::STATUS_ACTIVE,
))
->execute();
if ($invoices) { if ($invoices) {
$items[] = array( $items[] = array(
'icon' => PHUIStatusItemView::ICON_WARNING, 'severity' => PHUIInfoView::SEVERITY_ERROR,
'color' => 'yellow',
'target' => pht('Invoices'),
'note' => pht('You have %d unpaid invoice(s).', count($invoices)), 'note' => pht('You have %d unpaid invoice(s).', count($invoices)),
); );
} else {
$items[] = array(
'icon' => PHUIStatusItemView::ICON_ACCEPT,
'color' => 'green',
'target' => pht('Invoices'),
'note' => pht('This account has no unpaid invoices.'),
);
} }
// TODO: If a payment method has expired or is expiring soon, we should // TODO: If a payment method has expired or is expiring soon, we should

View file

@ -0,0 +1,76 @@
<?php
final class PhortuneMerchantAddManagerController extends PhortuneController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$id = $request->getURIData('id');
$merchant = id(new PhortuneMerchantQuery())
->setViewer($viewer)
->withIDs(array($id))
->needProfileImage(true)
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$merchant) {
return new Aphront404Response();
}
$v_members = array();
$e_members = null;
$merchant_uri = $this->getApplicationURI("/merchant/manager/{$id}/");
if ($request->isFormPost()) {
$xactions = array();
$v_members = $request->getArr('memberPHIDs');
$type_edge = PhabricatorTransactions::TYPE_EDGE;
$xactions[] = id(new PhortuneMerchantTransaction())
->setTransactionType($type_edge)
->setMetadataValue(
'edge:type',
PhortuneMerchantHasMemberEdgeType::EDGECONST)
->setNewValue(
array(
'+' => array_fuse($v_members),
));
$editor = id(new PhortuneMerchantEditor())
->setActor($viewer)
->setContentSourceFromRequest($request)
->setContinueOnNoEffect(true);
try {
$editor->applyTransactions($merchant, $xactions);
return id(new AphrontRedirectResponse())->setURI($merchant_uri);
} catch (PhabricatorApplicationTransactionValidationException $ex) {
$validation_exception = $ex;
$e_members = $ex->getShortMessage($type_edge);
}
}
$form = id(new AphrontFormView())
->setUser($viewer)
->appendControl(
id(new AphrontFormTokenizerControl())
->setDatasource(new PhabricatorPeopleDatasource())
->setLabel(pht('Members'))
->setName('memberPHIDs')
->setValue($v_members)
->setError($e_members));
return $this->newDialog()
->setTitle(pht('Add New Manager'))
->appendForm($form)
->setWidth(AphrontDialogView::WIDTH_FORM)
->addCancelButton($merchant_uri)
->addSubmitButton(pht('Add Manager'));
}
}

View file

@ -1,7 +1,7 @@
<?php <?php
final class PhortuneMerchantInvoiceCreateController final class PhortuneMerchantInvoiceCreateController
extends PhortuneMerchantController { extends PhortuneMerchantProfileController {
public function handleRequest(AphrontRequest $request) { public function handleRequest(AphrontRequest $request) {
$viewer = $request->getUser(); $viewer = $request->getUser();
@ -11,6 +11,7 @@ final class PhortuneMerchantInvoiceCreateController
return new Aphront404Response(); return new Aphront404Response();
} }
$this->setMerchant($merchant);
$merchant_id = $merchant->getID(); $merchant_id = $merchant->getID();
$cancel_uri = $this->getApplicationURI("/merchant/{$merchant_id}/"); $cancel_uri = $this->getApplicationURI("/merchant/{$merchant_id}/");
@ -88,8 +89,7 @@ final class PhortuneMerchantInvoiceCreateController
$title = pht('New Invoice'); $title = pht('New Invoice');
$crumbs = $this->buildApplicationCrumbs(); $crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb($merchant->getName()); $crumbs->addTextCrumb($title);
$crumbs->setBorder(true);
$v_title = $request->getStr('title'); $v_title = $request->getStr('title');
$e_title = true; $e_title = true;
@ -245,9 +245,12 @@ final class PhortuneMerchantInvoiceCreateController
$box, $box,
)); ));
$navigation = $this->buildSideNavView('orders');
return $this->newPage() return $this->newPage()
->setTitle($title) ->setTitle($title)
->setCrumbs($crumbs) ->setCrumbs($crumbs)
->setNavigation($navigation)
->appendChild($view); ->appendChild($view);
} }

View file

@ -0,0 +1,91 @@
<?php
final class PhortuneMerchantManagerController
extends PhortuneMerchantProfileController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$id = $request->getURIData('id');
$merchant = id(new PhortuneMerchantQuery())
->setViewer($viewer)
->withIDs(array($id))
->needProfileImage(true)
->executeOne();
if (!$merchant) {
return new Aphront404Response();
}
$this->setMerchant($merchant);
$header = $this->buildHeaderView();
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Managers'));
$header = $this->buildHeaderView();
$members = $this->buildMembersSection($merchant);
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setFooter(array(
$members,
));
$navigation = $this->buildSideNavView('managers');
return $this->newPage()
->setTitle(pht('Managers'))
->setCrumbs($crumbs)
->setNavigation($navigation)
->appendChild($view);
}
private function buildMembersSection(PhortuneMerchant $merchant) {
$viewer = $this->getViewer();
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$merchant,
PhabricatorPolicyCapability::CAN_EDIT);
$id = $merchant->getID();
$add = id(new PHUIButtonView())
->setTag('a')
->setText(pht('New Manager'))
->setIcon('fa-plus')
->setWorkflow(true)
->setHref("/phortune/merchant/manager/add/{$id}/");
$header = id(new PHUIHeaderView())
->setHeader(pht('Merchant Account Managers'))
->addActionLink($add);
$list = id(new PHUIObjectItemListView())
->setUser($viewer);
$member_phids = $merchant->getMemberPHIDs();
$handles = $viewer->loadHandles($member_phids);
foreach ($member_phids as $member_phid) {
$image_uri = $handles[$member_phid]->getImageURI();
$image_href = $handles[$member_phid]->getURI();
$person = $handles[$member_phid];
$member = id(new PHUIObjectItemView())
->setImageURI($image_uri)
->setHref($image_href)
->setHeader($person->getFullName())
->addAttribute(pht('Merchant Manager'));
$list->addItem($member);
}
return id(new PHUIObjectBoxView())
->setHeader($header)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setObjectList($list);
}
}

View file

@ -1,7 +1,7 @@
<?php <?php
final class PhortuneMerchantPictureController final class PhortuneMerchantPictureController
extends PhortuneMerchantController { extends PhortuneMerchantProfileController {
public function handleRequest(AphrontRequest $request) { public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer(); $viewer = $request->getViewer();
@ -21,7 +21,8 @@ final class PhortuneMerchantPictureController
return new Aphront404Response(); return new Aphront404Response();
} }
$uri = $merchant->getViewURI(); $this->setMerchant($merchant);
$uri = $merchant->getURI();
$supported_formats = PhabricatorFile::getTransformableImageFormats(); $supported_formats = PhabricatorFile::getTransformableImageFormats();
$e_file = true; $e_file = true;
@ -76,7 +77,8 @@ final class PhortuneMerchantPictureController
$xactions = array(); $xactions = array();
$xactions[] = id(new PhortuneMerchantTransaction()) $xactions[] = id(new PhortuneMerchantTransaction())
->setTransactionType(PhortuneMerchantTransaction::TYPE_PICTURE) ->setTransactionType(
PhortuneMerchantPictureTransaction::TRANSACTIONTYPE)
->setNewValue($new_value); ->setNewValue($new_value);
$editor = id(new PhortuneMerchantEditor()) $editor = id(new PhortuneMerchantEditor())
@ -91,7 +93,7 @@ final class PhortuneMerchantPictureController
} }
} }
$title = pht('Edit Merchant Picture'); $title = pht('Edit Logo');
$form = id(new PHUIFormLayoutView()) $form = id(new PHUIFormLayoutView())
->setUser($viewer); ->setUser($viewer);
@ -207,12 +209,10 @@ final class PhortuneMerchantPictureController
->setForm($upload_form); ->setForm($upload_form);
$crumbs = $this->buildApplicationCrumbs(); $crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb($merchant->getName(), $uri); $crumbs->addTextCrumb(pht('Edit Logo'));
$crumbs->addTextCrumb(pht('Merchant Logo'));
$crumbs->setBorder(true);
$header = id(new PHUIHeaderView()) $header = id(new PHUIHeaderView())
->setHeader(pht('Edit Merchant Logo')) ->setHeader(pht('Edit Logo'))
->setHeaderIcon('fa-camera'); ->setHeaderIcon('fa-camera');
$view = id(new PHUITwoColumnView()) $view = id(new PHUITwoColumnView())
@ -222,9 +222,12 @@ final class PhortuneMerchantPictureController
$upload_box, $upload_box,
)); ));
$navigation = $this->buildSideNavView();
return $this->newPage() return $this->newPage()
->setTitle($title) ->setTitle($title)
->setCrumbs($crumbs) ->setCrumbs($crumbs)
->setNavigation($navigation)
->appendChild( ->appendChild(
array( array(
$view, $view,

View file

@ -0,0 +1,92 @@
<?php
abstract class PhortuneMerchantProfileController
extends PhortuneController {
private $merchant;
public function setMerchant(PhortuneMerchant $merchant) {
$this->merchant = $merchant;
return $this;
}
public function getMerchant() {
return $this->merchant;
}
public function buildApplicationMenu() {
return $this->buildSideNavView()->getMenu();
}
protected function buildHeaderView() {
$viewer = $this->getViewer();
$merchant = $this->getMerchant();
$title = $merchant->getName();
$header = id(new PHUIHeaderView())
->setHeader($title)
->setUser($viewer)
->setPolicyObject($merchant)
->setImage($merchant->getProfileImageURI());
return $header;
}
protected function buildApplicationCrumbs() {
$merchant = $this->getMerchant();
$id = $merchant->getID();
$merchant_uri = $this->getApplicationURI("/merchant/{$id}/");
$crumbs = parent::buildApplicationCrumbs();
$crumbs->addTextCrumb($merchant->getName(), $merchant_uri);
$crumbs->setBorder(true);
return $crumbs;
}
protected function buildSideNavView($filter = null) {
$viewer = $this->getViewer();
$merchant = $this->getMerchant();
$id = $merchant->getID();
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$merchant,
PhabricatorPolicyCapability::CAN_EDIT);
$nav = id(new AphrontSideNavFilterView())
->setBaseURI(new PhutilURI($this->getApplicationURI()));
$nav->addLabel(pht('Merchant'));
$nav->addFilter(
'overview',
pht('Overview'),
$this->getApplicationURI("/merchant/{$id}/"),
'fa-building-o');
if ($can_edit) {
$nav->addFilter(
'orders',
pht('Orders'),
$this->getApplicationURI("merchant/orders/{$id}/"),
'fa-retweet');
$nav->addFilter(
'subscriptions',
pht('Subscriptions'),
$this->getApplicationURI("merchant/{$id}/subscription/"),
'fa-shopping-cart');
$nav->addFilter(
'managers',
pht('Managers'),
$this->getApplicationURI("/merchant/manager/{$id}/"),
'fa-group');
}
$nav->selectFilter($filter);
return $nav;
}
}

View file

@ -1,7 +1,7 @@
<?php <?php
final class PhortuneMerchantViewController final class PhortuneMerchantViewController
extends PhortuneMerchantController { extends PhortuneMerchantProfileController {
public function handleRequest(AphrontRequest $request) { public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer(); $viewer = $request->getViewer();
@ -16,21 +16,15 @@ final class PhortuneMerchantViewController
return new Aphront404Response(); return new Aphront404Response();
} }
$this->setMerchant($merchant);
$crumbs = $this->buildApplicationCrumbs(); $crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb($merchant->getName()); $header = $this->buildHeaderView();
$crumbs->setBorder(true);
$title = pht( $title = pht(
'Merchant %d %s', 'Merchant %d %s',
$merchant->getID(), $merchant->getID(),
$merchant->getName()); $merchant->getName());
$header = id(new PHUIHeaderView())
->setHeader($merchant->getName())
->setUser($viewer)
->setPolicyObject($merchant)
->setImage($merchant->getProfileImageURI());
$providers = id(new PhortunePaymentProviderConfigQuery()) $providers = id(new PhortunePaymentProviderConfigQuery())
->setViewer($viewer) ->setViewer($viewer)
->withMerchantPHIDs(array($merchant->getPHID())) ->withMerchantPHIDs(array($merchant->getPHID()))
@ -48,6 +42,8 @@ final class PhortuneMerchantViewController
new PhortuneMerchantTransactionQuery()); new PhortuneMerchantTransactionQuery());
$timeline->setShouldTerminate(true); $timeline->setShouldTerminate(true);
$navigation = $this->buildSideNavView('overview');
$view = id(new PHUITwoColumnView()) $view = id(new PHUITwoColumnView())
->setHeader($header) ->setHeader($header)
->setCurtain($curtain) ->setCurtain($curtain)
@ -60,6 +56,7 @@ final class PhortuneMerchantViewController
return $this->newPage() return $this->newPage()
->setTitle($title) ->setTitle($title)
->setCrumbs($crumbs) ->setCrumbs($crumbs)
->setNavigation($navigation)
->appendChild($view); ->appendChild($view);
} }
@ -196,22 +193,6 @@ final class PhortuneMerchantViewController
->setWorkflow(!$can_edit) ->setWorkflow(!$can_edit)
->setHref($this->getApplicationURI("merchant/picture/{$id}/"))); ->setHref($this->getApplicationURI("merchant/picture/{$id}/")));
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('View Orders'))
->setIcon('fa-shopping-cart')
->setHref($this->getApplicationURI("merchant/orders/{$id}/"))
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit));
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('View Subscriptions'))
->setIcon('fa-moon-o')
->setHref($this->getApplicationURI("merchant/{$id}/subscription/"))
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit));
$curtain->addAction( $curtain->addAction(
id(new PhabricatorActionView()) id(new PhabricatorActionView())
->setName(pht('New Invoice')) ->setName(pht('New Invoice'))
@ -240,7 +221,7 @@ final class PhortuneMerchantViewController
} }
$curtain->newPanel() $curtain->newPanel()
->setHeaderText(pht('Members')) ->setHeaderText(pht('Managers'))
->appendChild($member_list); ->appendChild($member_list);
return $curtain; return $curtain;

View file

@ -14,7 +14,7 @@ final class PhortuneAccountHasMemberEdgeType extends PhabricatorEdgeType {
$add_edges) { $add_edges) {
return pht( return pht(
'%s added %s account member(s): %s.', '%s added %s account manager(s): %s.',
$actor, $actor,
$add_count, $add_count,
$add_edges); $add_edges);
@ -26,7 +26,7 @@ final class PhortuneAccountHasMemberEdgeType extends PhabricatorEdgeType {
$rem_edges) { $rem_edges) {
return pht( return pht(
'%s removed %s account member(s): %s.', '%s removed %s account manager(s): %s.',
$actor, $actor,
$rem_count, $rem_count,
$rem_edges); $rem_edges);
@ -41,7 +41,7 @@ final class PhortuneAccountHasMemberEdgeType extends PhabricatorEdgeType {
$rem_edges) { $rem_edges) {
return pht( return pht(
'%s edited %s account member(s), added %s: %s; removed %s: %s.', '%s edited %s account manager(s), added %s: %s; removed %s: %s.',
$actor, $actor,
$total_count, $total_count,
$add_count, $add_count,
@ -57,7 +57,7 @@ final class PhortuneAccountHasMemberEdgeType extends PhabricatorEdgeType {
$add_edges) { $add_edges) {
return pht( return pht(
'%s added %s account member(s) to %s: %s.', '%s added %s account manager(s) to %s: %s.',
$actor, $actor,
$add_count, $add_count,
$object, $object,
@ -71,7 +71,7 @@ final class PhortuneAccountHasMemberEdgeType extends PhabricatorEdgeType {
$rem_edges) { $rem_edges) {
return pht( return pht(
'%s removed %s account member(s) from %s: %s.', '%s removed %s account manager(s) from %s: %s.',
$actor, $actor,
$rem_count, $rem_count,
$object, $object,
@ -88,7 +88,7 @@ final class PhortuneAccountHasMemberEdgeType extends PhabricatorEdgeType {
$rem_edges) { $rem_edges) {
return pht( return pht(
'%s edited %s account member(s) for %s, added %s: %s; removed %s: %s.', '%s edited %s account manager(s) for %s, added %s: %s; removed %s: %s.',
$actor, $actor,
$total_count, $total_count,
$object, $object,

View file

@ -14,7 +14,7 @@ final class PhortuneMerchantHasMemberEdgeType extends PhabricatorEdgeType {
$add_edges) { $add_edges) {
return pht( return pht(
'%s added %s merchant member(s): %s.', '%s added %s merchant manager(s): %s.',
$actor, $actor,
$add_count, $add_count,
$add_edges); $add_edges);
@ -26,7 +26,7 @@ final class PhortuneMerchantHasMemberEdgeType extends PhabricatorEdgeType {
$rem_edges) { $rem_edges) {
return pht( return pht(
'%s removed %s merchant member(s): %s.', '%s removed %s merchant manager(s): %s.',
$actor, $actor,
$rem_count, $rem_count,
$rem_edges); $rem_edges);
@ -41,7 +41,7 @@ final class PhortuneMerchantHasMemberEdgeType extends PhabricatorEdgeType {
$rem_edges) { $rem_edges) {
return pht( return pht(
'%s edited %s merchant member(s), added %s: %s; removed %s: %s.', '%s edited %s merchant manager(s), added %s: %s; removed %s: %s.',
$actor, $actor,
$total_count, $total_count,
$add_count, $add_count,
@ -57,7 +57,7 @@ final class PhortuneMerchantHasMemberEdgeType extends PhabricatorEdgeType {
$add_edges) { $add_edges) {
return pht( return pht(
'%s added %s merchant member(s) to %s: %s.', '%s added %s merchant manager(s) to %s: %s.',
$actor, $actor,
$add_count, $add_count,
$object, $object,
@ -71,7 +71,7 @@ final class PhortuneMerchantHasMemberEdgeType extends PhabricatorEdgeType {
$rem_edges) { $rem_edges) {
return pht( return pht(
'%s removed %s merchant member(s) from %s: %s.', '%s removed %s merchant manager(s) from %s: %s.',
$actor, $actor,
$rem_count, $rem_count,
$object, $object,
@ -88,7 +88,7 @@ final class PhortuneMerchantHasMemberEdgeType extends PhabricatorEdgeType {
$rem_edges) { $rem_edges) {
return pht( return pht(
'%s edited %s merchant member(s) for %s, added %s: %s; removed %s: %s.', '%s edited %s merchant manager(s) for %s, added %s: %s; removed %s: %s.',
$actor, $actor,
$total_count, $total_count,
$object, $object,

View file

@ -0,0 +1,108 @@
<?php
final class PhortuneAccountEditEngine
extends PhabricatorEditEngine {
const ENGINECONST = 'phortune.account';
public function getEngineName() {
return pht('Phortune Accounts');
}
public function getEngineApplicationClass() {
return 'PhabricatorPhortuneApplication';
}
public function getSummaryHeader() {
return pht('Configure Phortune Account Forms');
}
public function getSummaryText() {
return pht('Configure creation and editing forms in Phortune Accounts.');
}
public function isEngineConfigurable() {
return false;
}
protected function newEditableObject() {
return PhortuneAccount::initializeNewAccount($this->getViewer());
}
protected function newObjectQuery() {
return new PhortuneAccountQuery();
}
protected function getObjectCreateTitleText($object) {
return pht('Create Payment Account');
}
protected function getObjectEditTitleText($object) {
return pht('Edit Account: %s', $object->getName());
}
protected function getObjectEditShortText($object) {
return $object->getName();
}
protected function getObjectCreateShortText() {
return pht('Create Account');
}
protected function getObjectName() {
return pht('Account');
}
protected function getObjectCreateCancelURI($object) {
return $this->getApplication()->getApplicationURI('/');
}
protected function getEditorURI() {
return $this->getApplication()->getApplicationURI('edit/');
}
protected function getObjectViewURI($object) {
return $object->getURI();
}
protected function buildCustomEditFields($object) {
$viewer = $this->getViewer();
if ($this->getIsCreate()) {
$member_phids = array($viewer->getPHID());
} else {
$member_phids = $object->getMemberPHIDs();
}
$fields = array(
id(new PhabricatorTextEditField())
->setKey('name')
->setLabel(pht('Name'))
->setDescription(pht('Account name.'))
->setConduitTypeDescription(pht('New account name.'))
->setTransactionType(
PhortuneAccountNameTransaction::TRANSACTIONTYPE)
->setValue($object->getName())
->setIsRequired(true),
id(new PhabricatorUsersEditField())
->setKey('managers')
->setAliases(array('memberPHIDs', 'managerPHIDs'))
->setLabel(pht('Managers'))
->setUseEdgeTransactions(true)
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
->setMetadataValue(
'edge:type',
PhortuneAccountHasMemberEdgeType::EDGECONST)
->setDescription(pht('Initial account managers.'))
->setConduitDescription(pht('Set account managers.'))
->setConduitTypeDescription(pht('New list of managers.'))
->setInitialValue($object->getMemberPHIDs())
->setValue($member_phids),
);
return $fields;
}
}

View file

@ -1,6 +1,5 @@
<?php <?php
final class PhortuneAccountEditor final class PhortuneAccountEditor
extends PhabricatorApplicationTransactionEditor { extends PhabricatorApplicationTransactionEditor {
@ -12,57 +11,16 @@ final class PhortuneAccountEditor
return pht('Phortune Accounts'); return pht('Phortune Accounts');
} }
public function getCreateObjectTitle($author, $object) {
return pht('%s created this payment account.', $author);
}
public function getTransactionTypes() { public function getTransactionTypes() {
$types = parent::getTransactionTypes(); $types = parent::getTransactionTypes();
$types[] = PhabricatorTransactions::TYPE_EDGE; $types[] = PhabricatorTransactions::TYPE_EDGE;
$types[] = PhortuneAccountTransaction::TYPE_NAME;
return $types; return $types;
} }
protected function getCustomTransactionOldValue(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhortuneAccountTransaction::TYPE_NAME:
return $object->getName();
}
return parent::getCustomTransactionOldValue($object, $xaction);
}
protected function getCustomTransactionNewValue(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhortuneAccountTransaction::TYPE_NAME:
return $xaction->getNewValue();
}
return parent::getCustomTransactionNewValue($object, $xaction);
}
protected function applyCustomInternalTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhortuneAccountTransaction::TYPE_NAME:
$object->setName($xaction->getNewValue());
return;
}
return parent::applyCustomInternalTransaction($object, $xaction);
}
protected function applyCustomExternalTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhortuneAccountTransaction::TYPE_NAME:
return;
}
return parent::applyCustomExternalTransaction($object, $xaction);
}
protected function validateTransaction( protected function validateTransaction(
PhabricatorLiskDAO $object, PhabricatorLiskDAO $object,
$type, $type,
@ -70,39 +28,46 @@ final class PhortuneAccountEditor
$errors = parent::validateTransaction($object, $type, $xactions); $errors = parent::validateTransaction($object, $type, $xactions);
$viewer = $this->requireActor();
switch ($type) { switch ($type) {
case PhortuneAccountTransaction::TYPE_NAME:
$missing = $this->validateIsEmptyTextField(
$object->getName(),
$xactions);
if ($missing) {
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Required'),
pht('Account name is required.'),
nonempty(last($xactions), null));
$error->setIsMissingFieldError(true);
$errors[] = $error;
}
break;
case PhabricatorTransactions::TYPE_EDGE: case PhabricatorTransactions::TYPE_EDGE:
foreach ($xactions as $xaction) { foreach ($xactions as $xaction) {
switch ($xaction->getMetadataValue('edge:type')) { switch ($xaction->getMetadataValue('edge:type')) {
case PhortuneAccountHasMemberEdgeType::EDGECONST: case PhortuneAccountHasMemberEdgeType::EDGECONST:
// TODO: This is a bit cumbersome, but validation happens before $old = $object->getMemberPHIDs();
// transaction normalization. Maybe provide a cleaner attack on $new = $this->getPHIDTransactionNewValue($xaction, $old);
// this eventually? There's no way to generate "+" or "-"
// transactions right now.
$new = $xaction->getNewValue();
$set = idx($new, '=', array());
if (empty($set[$this->requireActor()->getPHID()])) { $old = array_fuse($old);
$new = array_fuse($new);
foreach ($new as $new_phid) {
if (isset($old[$new_phid])) {
continue;
}
$user = id(new PhabricatorPeopleQuery())
->setViewer($viewer)
->withPHIDs(array($new_phid))
->executeOne();
if (!$user) {
$error = new PhabricatorApplicationTransactionValidationError( $error = new PhabricatorApplicationTransactionValidationError(
$type, $type,
pht('Invalid'), pht('Invalid'),
pht('You can not remove yourself as an account member.'), pht(
'Account managers must be valid users, "%s" is not.',
$new_phid));
$errors[] = $error;
continue;
}
}
$actor_phid = $this->getActingAsPHID();
if (!isset($new[$actor_phid])) {
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid'),
pht('You can not remove yourself as an account manager.'),
$xaction); $xaction);
$errors[] = $error; $errors[] = $error;
} }
@ -111,7 +76,7 @@ final class PhortuneAccountEditor
} }
break; break;
} }
return $errors; return $errors;
} }
} }

View file

@ -58,7 +58,7 @@ final class PhortuneMerchantEditEngine
} }
protected function getObjectViewURI($object) { protected function getObjectViewURI($object) {
return $object->getViewURI(); return $object->getURI();
} }
public function isEngineConfigurable() { public function isEngineConfigurable() {
@ -81,21 +81,22 @@ final class PhortuneMerchantEditEngine
->setDescription(pht('Merchant name.')) ->setDescription(pht('Merchant name.'))
->setConduitTypeDescription(pht('New Merchant name.')) ->setConduitTypeDescription(pht('New Merchant name.'))
->setIsRequired(true) ->setIsRequired(true)
->setTransactionType(PhortuneMerchantTransaction::TYPE_NAME) ->setTransactionType(
PhortuneMerchantNameTransaction::TRANSACTIONTYPE)
->setValue($object->getName()), ->setValue($object->getName()),
id(new PhabricatorUsersEditField()) id(new PhabricatorUsersEditField())
->setKey('members') ->setKey('members')
->setAliases(array('memberPHIDs')) ->setAliases(array('memberPHIDs', 'managerPHIDs'))
->setLabel(pht('Members')) ->setLabel(pht('Managers'))
->setUseEdgeTransactions(true) ->setUseEdgeTransactions(true)
->setTransactionType(PhabricatorTransactions::TYPE_EDGE) ->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
->setMetadataValue( ->setMetadataValue(
'edge:type', 'edge:type',
PhortuneMerchantHasMemberEdgeType::EDGECONST) PhortuneMerchantHasMemberEdgeType::EDGECONST)
->setDescription(pht('Initial merchant members.')) ->setDescription(pht('Initial merchant managers.'))
->setConduitDescription(pht('Set merchant members.')) ->setConduitDescription(pht('Set merchant managers.'))
->setConduitTypeDescription(pht('New list of members.')) ->setConduitTypeDescription(pht('New list of managers.'))
->setInitialValue($object->getMemberPHIDs()) ->setInitialValue($object->getMemberPHIDs())
->setValue($member_phids), ->setValue($member_phids),
@ -104,7 +105,8 @@ final class PhortuneMerchantEditEngine
->setLabel(pht('Description')) ->setLabel(pht('Description'))
->setDescription(pht('Merchant description.')) ->setDescription(pht('Merchant description.'))
->setConduitTypeDescription(pht('New merchant description.')) ->setConduitTypeDescription(pht('New merchant description.'))
->setTransactionType(PhortuneMerchantTransaction::TYPE_DESCRIPTION) ->setTransactionType(
PhortuneMerchantDescriptionTransaction::TRANSACTIONTYPE)
->setValue($object->getDescription()), ->setValue($object->getDescription()),
id(new PhabricatorRemarkupEditField()) id(new PhabricatorRemarkupEditField())
@ -112,7 +114,8 @@ final class PhortuneMerchantEditEngine
->setLabel(pht('Contact Info')) ->setLabel(pht('Contact Info'))
->setDescription(pht('Merchant contact information.')) ->setDescription(pht('Merchant contact information.'))
->setConduitTypeDescription(pht('Merchant contact information.')) ->setConduitTypeDescription(pht('Merchant contact information.'))
->setTransactionType(PhortuneMerchantTransaction::TYPE_CONTACTINFO) ->setTransactionType(
PhortuneMerchantContactInfoTransaction::TRANSACTIONTYPE)
->setValue($object->getContactInfo()), ->setValue($object->getContactInfo()),
id(new PhabricatorTextEditField()) id(new PhabricatorTextEditField())
@ -121,7 +124,8 @@ final class PhortuneMerchantEditEngine
->setDescription(pht('Email address invoices are sent from.')) ->setDescription(pht('Email address invoices are sent from.'))
->setConduitTypeDescription( ->setConduitTypeDescription(
pht('Email address invoices are sent from.')) pht('Email address invoices are sent from.'))
->setTransactionType(PhortuneMerchantTransaction::TYPE_INVOICEEMAIL) ->setTransactionType(
PhortuneMerchantInvoiceEmailTransaction::TRANSACTIONTYPE)
->setValue($object->getInvoiceEmail()), ->setValue($object->getInvoiceEmail()),
id(new PhabricatorRemarkupEditField()) id(new PhabricatorRemarkupEditField())
@ -129,7 +133,8 @@ final class PhortuneMerchantEditEngine
->setLabel(pht('Invoice Footer')) ->setLabel(pht('Invoice Footer'))
->setDescription(pht('Footer on invoice forms.')) ->setDescription(pht('Footer on invoice forms.'))
->setConduitTypeDescription(pht('Footer on invoice forms.')) ->setConduitTypeDescription(pht('Footer on invoice forms.'))
->setTransactionType(PhortuneMerchantTransaction::TYPE_INVOICEFOOTER) ->setTransactionType(
PhortuneMerchantInvoiceFooterTransaction::TRANSACTIONTYPE)
->setValue($object->getInvoiceFooter()), ->setValue($object->getInvoiceFooter()),
); );

View file

@ -11,104 +11,19 @@ final class PhortuneMerchantEditor
return pht('Phortune Merchants'); return pht('Phortune Merchants');
} }
public function getCreateObjectTitle($author, $object) {
return pht('%s created this merchant.', $author);
}
public function getTransactionTypes() { public function getTransactionTypes() {
$types = parent::getTransactionTypes(); $types = parent::getTransactionTypes();
$types[] = PhortuneMerchantTransaction::TYPE_NAME;
$types[] = PhortuneMerchantTransaction::TYPE_DESCRIPTION;
$types[] = PhortuneMerchantTransaction::TYPE_CONTACTINFO;
$types[] = PhortuneMerchantTransaction::TYPE_PICTURE;
$types[] = PhortuneMerchantTransaction::TYPE_INVOICEEMAIL;
$types[] = PhortuneMerchantTransaction::TYPE_INVOICEFOOTER;
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY; $types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
$types[] = PhabricatorTransactions::TYPE_EDGE; $types[] = PhabricatorTransactions::TYPE_EDGE;
return $types; return $types;
} }
protected function getCustomTransactionOldValue(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhortuneMerchantTransaction::TYPE_NAME:
return $object->getName();
case PhortuneMerchantTransaction::TYPE_DESCRIPTION:
return $object->getDescription();
case PhortuneMerchantTransaction::TYPE_CONTACTINFO:
return $object->getContactInfo();
case PhortuneMerchantTransaction::TYPE_INVOICEEMAIL:
return $object->getInvoiceEmail();
case PhortuneMerchantTransaction::TYPE_INVOICEFOOTER:
return $object->getInvoiceFooter();
case PhortuneMerchantTransaction::TYPE_PICTURE:
return $object->getProfileImagePHID();
}
return parent::getCustomTransactionOldValue($object, $xaction);
}
protected function getCustomTransactionNewValue(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhortuneMerchantTransaction::TYPE_NAME:
case PhortuneMerchantTransaction::TYPE_DESCRIPTION:
case PhortuneMerchantTransaction::TYPE_CONTACTINFO:
case PhortuneMerchantTransaction::TYPE_INVOICEEMAIL:
case PhortuneMerchantTransaction::TYPE_INVOICEFOOTER:
case PhortuneMerchantTransaction::TYPE_PICTURE:
return $xaction->getNewValue();
}
return parent::getCustomTransactionNewValue($object, $xaction);
}
protected function applyCustomInternalTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhortuneMerchantTransaction::TYPE_NAME:
$object->setName($xaction->getNewValue());
return;
case PhortuneMerchantTransaction::TYPE_DESCRIPTION:
$object->setDescription($xaction->getNewValue());
return;
case PhortuneMerchantTransaction::TYPE_CONTACTINFO:
$object->setContactInfo($xaction->getNewValue());
return;
case PhortuneMerchantTransaction::TYPE_INVOICEEMAIL:
$object->setInvoiceEmail($xaction->getNewValue());
return;
case PhortuneMerchantTransaction::TYPE_INVOICEFOOTER:
$object->setInvoiceFooter($xaction->getNewValue());
return;
case PhortuneMerchantTransaction::TYPE_PICTURE:
$object->setProfileImagePHID($xaction->getNewValue());
return;
}
return parent::applyCustomInternalTransaction($object, $xaction);
}
protected function applyCustomExternalTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhortuneMerchantTransaction::TYPE_NAME:
case PhortuneMerchantTransaction::TYPE_DESCRIPTION:
case PhortuneMerchantTransaction::TYPE_CONTACTINFO:
case PhortuneMerchantTransaction::TYPE_INVOICEEMAIL:
case PhortuneMerchantTransaction::TYPE_INVOICEFOOTER:
case PhortuneMerchantTransaction::TYPE_PICTURE:
return;
}
return parent::applyCustomExternalTransaction($object, $xaction);
}
protected function validateTransaction( protected function validateTransaction(
PhabricatorLiskDAO $object, PhabricatorLiskDAO $object,
$type, $type,
@ -117,48 +32,28 @@ final class PhortuneMerchantEditor
$errors = parent::validateTransaction($object, $type, $xactions); $errors = parent::validateTransaction($object, $type, $xactions);
switch ($type) { switch ($type) {
case PhortuneMerchantTransaction::TYPE_NAME: case PhabricatorTransactions::TYPE_EDGE:
$missing = $this->validateIsEmptyTextField(
$object->getName(),
$xactions);
if ($missing) {
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Required'),
pht('Merchant name is required.'),
nonempty(last($xactions), null));
$error->setIsMissingFieldError(true);
$errors[] = $error;
}
break;
case PhortuneMerchantTransaction::TYPE_INVOICEEMAIL:
$new_email = null;
foreach ($xactions as $xaction) { foreach ($xactions as $xaction) {
switch ($xaction->getTransactionType()) { switch ($xaction->getMetadataValue('edge:type')) {
case PhortuneMerchantTransaction::TYPE_INVOICEEMAIL: case PhortuneMerchantHasMemberEdgeType::EDGECONST:
$new_email = $xaction->getNewValue(); $new = $xaction->getNewValue();
break; $set = idx($new, '-', array());
} $actor_phid = $this->requireActor()->getPHID();
} foreach ($set as $phid) {
if (strlen($new_email)) { if ($actor_phid == $phid) {
$email = new PhutilEmailAddress($new_email);
$domain = $email->getDomainName();
if (!$domain) {
$error = new PhabricatorApplicationTransactionValidationError( $error = new PhabricatorApplicationTransactionValidationError(
$type, $type,
pht('Invalid'), pht('Invalid'),
pht('%s is not a valid email.', $new_email), pht('You can not remove yourself as an merchant manager.'),
nonempty(last($xactions), null)); $xaction);
$errors[] = $error; $errors[] = $error;
} }
} }
break; break;
} }
}
break;
}
return $errors; return $errors;
} }

View file

@ -16,11 +16,8 @@ final class PhortuneAccount extends PhortuneDAO
private $memberPHIDs = self::ATTACHABLE; private $memberPHIDs = self::ATTACHABLE;
public static function initializeNewAccount(PhabricatorUser $actor) { public static function initializeNewAccount(PhabricatorUser $actor) {
$account = id(new PhortuneAccount()); return id(new self())
->attachMemberPHIDs(array());
$account->memberPHIDs = array();
return $account;
} }
public static function createNewAccount( public static function createNewAccount(
@ -31,7 +28,7 @@ final class PhortuneAccount extends PhortuneDAO
$xactions = array(); $xactions = array();
$xactions[] = id(new PhortuneAccountTransaction()) $xactions[] = id(new PhortuneAccountTransaction())
->setTransactionType(PhortuneAccountTransaction::TYPE_NAME) ->setTransactionType(PhortuneAccountNameTransaction::TRANSACTIONTYPE)
->setNewValue(pht('Default Account')); ->setNewValue(pht('Default Account'));
$xactions[] = id(new PhortuneAccountTransaction()) $xactions[] = id(new PhortuneAccountTransaction())
@ -96,6 +93,10 @@ final class PhortuneAccount extends PhortuneDAO
return $this; return $this;
} }
public function getURI() {
return '/phortune/'.$this->getID().'/';
}
/* -( PhabricatorApplicationTransactionInterface )------------------------- */ /* -( PhabricatorApplicationTransactionInterface )------------------------- */

View file

@ -1,9 +1,7 @@
<?php <?php
final class PhortuneAccountTransaction final class PhortuneAccountTransaction
extends PhabricatorApplicationTransaction { extends PhabricatorModularTransaction {
const TYPE_NAME = 'phortune:name';
public function getApplicationName() { public function getApplicationName() {
return 'phortune'; return 'phortune';
@ -17,29 +15,8 @@ final class PhortuneAccountTransaction
return null; return null;
} }
public function getTitle() { public function getBaseTransactionClass() {
$author_phid = $this->getAuthorPHID(); return 'PhortuneAccountTransactionType';
$old = $this->getOldValue();
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case self::TYPE_NAME:
if ($old === null) {
return pht(
'%s created this account.',
$this->renderHandleLink($author_phid));
} else {
return pht(
'%s renamed this account from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$old,
$new);
}
break;
}
return parent::getTitle();
} }
} }

View file

@ -53,7 +53,7 @@ final class PhortuneMerchant extends PhortuneDAO
return $this; return $this;
} }
public function getViewURI() { public function getURI() {
return '/phortune/merchant/'.$this->getID().'/'; return '/phortune/merchant/'.$this->getID().'/';
} }
@ -70,6 +70,7 @@ final class PhortuneMerchant extends PhortuneDAO
return $this->assertAttached($this->profileImageFile); return $this->assertAttached($this->profileImageFile);
} }
/* -( PhabricatorApplicationTransactionInterface )------------------------- */ /* -( PhabricatorApplicationTransactionInterface )------------------------- */

View file

@ -1,14 +1,7 @@
<?php <?php
final class PhortuneMerchantTransaction final class PhortuneMerchantTransaction
extends PhabricatorApplicationTransaction { extends PhabricatorModularTransaction {
const TYPE_NAME = 'merchant:name';
const TYPE_DESCRIPTION = 'merchant:description';
const TYPE_CONTACTINFO = 'merchant:contactinfo';
const TYPE_INVOICEEMAIL = 'merchant:invoiceemail';
const TYPE_INVOICEFOOTER = 'merchant:invoicefooter';
const TYPE_PICTURE = 'merchant:picture';
public function getApplicationName() { public function getApplicationName() {
return 'phortune'; return 'phortune';
@ -22,79 +15,8 @@ final class PhortuneMerchantTransaction
return null; return null;
} }
public function getTitle() { public function getBaseTransactionClass() {
$author_phid = $this->getAuthorPHID(); return 'PhortuneMerchantTransactionType';
$old = $this->getOldValue();
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case self::TYPE_NAME:
if ($old === null) {
return pht(
'%s created this merchant.',
$this->renderHandleLink($author_phid));
} else {
return pht(
'%s renamed this merchant from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$old,
$new);
}
break;
case self::TYPE_DESCRIPTION:
return pht(
'%s updated the description for this merchant.',
$this->renderHandleLink($author_phid));
case self::TYPE_CONTACTINFO:
return pht(
'%s updated the contact information for this merchant.',
$this->renderHandleLink($author_phid));
case self::TYPE_INVOICEEMAIL:
return pht(
'%s updated the invoice email for this merchant.',
$this->renderHandleLink($author_phid));
case self::TYPE_INVOICEFOOTER:
return pht(
'%s updated the invoice footer for this merchant.',
$this->renderHandleLink($author_phid));
}
return parent::getTitle();
}
public function shouldHide() {
$old = $this->getOldValue();
switch ($this->getTransactionType()) {
case self::TYPE_DESCRIPTION:
case self::TYPE_CONTACTINFO:
case self::TYPE_INVOICEEMAIL:
case self::TYPE_INVOICEFOOTER:
return ($old === null);
}
return parent::shouldHide();
}
public function hasChangeDetails() {
switch ($this->getTransactionType()) {
case self::TYPE_DESCRIPTION:
return ($this->getOldValue() !== null);
case self::TYPE_CONTACTINFO:
return ($this->getOldValue() !== null);
case self::TYPE_INVOICEEMAIL:
return ($this->getOldValue() !== null);
case self::TYPE_INVOICEFOOTER:
return ($this->getOldValue() !== null);
}
return parent::hasChangeDetails();
}
public function renderChangeDetails(PhabricatorUser $viewer) {
return $this->renderTextCorpusChangeDetails(
$viewer,
$this->getOldValue(),
$this->getNewValue());
} }
} }

View file

@ -55,6 +55,7 @@ final class PhortuneChargeTableView extends AphrontView {
} }
$table = id(new AphrontTableView($rows)) $table = id(new AphrontTableView($rows))
->setNoDataString(pht('No charges found.'))
->setHeaders( ->setHeaders(
array( array(
pht('ID'), pht('ID'),

View file

@ -0,0 +1,55 @@
<?php
final class PhortuneAccountNameTransaction
extends PhortuneAccountTransactionType {
const TRANSACTIONTYPE = 'phortune:name';
public function generateOldValue($object) {
return $object->getName();
}
public function applyInternalEffects($object, $value) {
$object->setName($value);
}
public function getTitle() {
$old = $this->getOldValue();
$new = $this->getNewValue();
if (strlen($old) && strlen($new)) {
return pht(
'%s renamed this account from %s to %s.',
$this->renderAuthor(),
$this->renderOldValue(),
$this->renderNewValue());
} else {
return pht(
'%s created this account.',
$this->renderAuthor());
}
}
public function validateTransactions($object, array $xactions) {
$errors = array();
if ($this->isEmptyTextTransaction($object->getName(), $xactions)) {
$errors[] = $this->newRequiredError(
pht('Accounts 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->newRequiredError(
pht('The name can be no longer than %s characters.',
new PhutilNumber($max_length)));
}
}
return $errors;
}
}

View file

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

View file

@ -0,0 +1,56 @@
<?php
final class PhortuneMerchantContactInfoTransaction
extends PhortuneMerchantTransactionType {
const TRANSACTIONTYPE = 'merchant:contactinfo';
public function generateOldValue($object) {
return $object->getContactInfo();
}
public function applyInternalEffects($object, $value) {
$object->setContactInfo($value);
}
public function getTitle() {
return pht(
'%s updated the merchant contact info.',
$this->renderAuthor());
}
public function getTitleForFeed() {
return pht(
'%s updated the merchant contact info for %s.',
$this->renderAuthor(),
$this->renderObject());
}
public function hasChangeDetailView() {
return true;
}
public function getMailDiffSectionHeader() {
return pht('CHANGES TO MERCHANT CONTACT INFO');
}
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,56 @@
<?php
final class PhortuneMerchantDescriptionTransaction
extends PhortuneMerchantTransactionType {
const TRANSACTIONTYPE = 'merchant:description';
public function generateOldValue($object) {
return $object->getDescription();
}
public function applyInternalEffects($object, $value) {
$object->setDescription($value);
}
public function getTitle() {
return pht(
'%s updated the merchant description.',
$this->renderAuthor());
}
public function getTitleForFeed() {
return pht(
'%s updated the merchant description for %s.',
$this->renderAuthor(),
$this->renderObject());
}
public function hasChangeDetailView() {
return true;
}
public function getMailDiffSectionHeader() {
return pht('CHANGES TO MERCHANT 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,94 @@
<?php
final class PhortuneMerchantInvoiceEmailTransaction
extends PhortuneMerchantTransactionType {
const TRANSACTIONTYPE = 'merchant:invoiceemail';
public function generateOldValue($object) {
return $object->getInvoiceEmail();
}
public function applyInternalEffects($object, $value) {
$object->setInvoiceEmail($value);
}
public function getTitle() {
$old = $this->getOldValue();
$new = $this->getNewValue();
if (strlen($old) && strlen($new)) {
return pht(
'%s updated the invoice email from %s to %s.',
$this->renderAuthor(),
$this->renderOldValue(),
$this->renderNewValue());
} else if (strlen($old)) {
return pht(
'%s removed the invoice email.',
$this->renderAuthor());
} else {
return pht(
'%s set the invoice email to %s.',
$this->renderAuthor(),
$this->renderNewValue());
}
}
public function getTitleForFeed() {
$old = $this->getOldValue();
$new = $this->getNewValue();
if (strlen($old) && strlen($new)) {
return pht(
'%s updated %s invoice email from %s to %s.',
$this->renderAuthor(),
$this->renderObject(),
$this->renderOldValue(),
$this->renderNewValue());
} else if (strlen($old)) {
return pht(
'%s removed the invoice email for %s.',
$this->renderAuthor(),
$this->renderObject());
} else {
return pht(
'%s set the invoice email for %s to %s.',
$this->renderAuthor(),
$this->renderObject(),
$this->renderNewValue());
}
}
public function getIcon() {
return 'fa-envelope';
}
public function validateTransactions($object, array $xactions) {
$errors = array();
$max_length = $object->getColumnMaximumByteLength('invoiceEmail');
foreach ($xactions as $xaction) {
if (strlen($xaction->getNewValue())) {
$email = new PhutilEmailAddress($xaction->getNewValue());
$domain = $email->getDomainName();
if (!strlen($domain)) {
$errors[] = $this->newInvalidError(
pht('Invoice email "%s" must be a valid email.',
$xaction->getNewValue()));
}
$new_value = $xaction->getNewValue();
$new_length = strlen($new_value);
if ($new_length > $max_length) {
$errors[] = $this->newInvalidError(
pht('The email can be no longer than %s characters.',
new PhutilNumber($max_length)));
}
}
}
return $errors;
}
}

View file

@ -0,0 +1,56 @@
<?php
final class PhortuneMerchantInvoiceFooterTransaction
extends PhortuneMerchantTransactionType {
const TRANSACTIONTYPE = 'merchant:invoicefooter';
public function generateOldValue($object) {
return $object->getInvoiceFooter();
}
public function applyInternalEffects($object, $value) {
$object->setInvoiceFooter($value);
}
public function getTitle() {
return pht(
'%s updated the merchant invoice footer.',
$this->renderAuthor());
}
public function getTitleForFeed() {
return pht(
'%s updated the merchant invoice footer for %s.',
$this->renderAuthor(),
$this->renderObject());
}
public function hasChangeDetailView() {
return true;
}
public function getMailDiffSectionHeader() {
return pht('CHANGES TO MERCHANT INVOICE FOOTER');
}
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,55 @@
<?php
final class PhortuneMerchantNameTransaction
extends PhortuneMerchantTransactionType {
const TRANSACTIONTYPE = 'merchant:name';
public function generateOldValue($object) {
return $object->getName();
}
public function applyInternalEffects($object, $value) {
$object->setName($value);
}
public function getTitle() {
return pht(
'%s renamed this merchant from %s to %s.',
$this->renderAuthor(),
$this->renderOldValue(),
$this->renderNewValue());
}
public function getTitleForFeed() {
return pht(
'%s renamed %s merchant name 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('Merchants 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('The name can be no longer than %s characters.',
new PhutilNumber($max_length)));
}
}
return $errors;
}
}

View file

@ -0,0 +1,33 @@
<?php
final class PhortuneMerchantPictureTransaction
extends PhortuneMerchantTransactionType {
const TRANSACTIONTYPE = 'merchant:picture';
public function generateOldValue($object) {
return $object->getProfileImagePHID();
}
public function applyInternalEffects($object, $value) {
$object->setProfileImagePHID($value);
}
public function getTitle() {
return pht(
'%s updated the picture.',
$this->renderAuthor());
}
public function getTitleForFeed() {
return pht(
'%s updated the picture for merchant %s.',
$this->renderAuthor(),
$this->renderObject());
}
public function getIcon() {
return 'fa-camera-retro';
}
}

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