diff --git a/resources/celerity/map.php b/resources/celerity/map.php index d2953c72dd..d14b06d712 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -7,12 +7,12 @@ */ return array( 'names' => array( - 'conpherence.pkg.css' => 'a520d619', + 'conpherence.pkg.css' => '6875302f', 'conpherence.pkg.js' => '6249a1cf', - 'core.pkg.css' => '0d7ecd3b', + 'core.pkg.css' => 'c0340df0', 'core.pkg.js' => '1fa7c0c5', 'darkconsole.pkg.js' => 'e7393ebb', - 'differential.pkg.css' => '4815647b', + 'differential.pkg.css' => '90b30783', 'differential.pkg.js' => 'ddfeb49b', 'diffusion.pkg.css' => '91c5d3a6', 'diffusion.pkg.js' => '84c8f8fd', @@ -45,7 +45,7 @@ return array( 'rsrc/css/application/config/config-template.css' => '8f18fa41', 'rsrc/css/application/config/setup-issue.css' => 'f794cfc3', 'rsrc/css/application/config/unhandled-exception.css' => '4c96257a', - 'rsrc/css/application/conpherence/durable-column.css' => 'd82e130c', + 'rsrc/css/application/conpherence/durable-column.css' => '292c71f0', 'rsrc/css/application/conpherence/header-pane.css' => 'db93ebc6', 'rsrc/css/application/conpherence/menu.css' => '3d8e5c9c', 'rsrc/css/application/conpherence/message-pane.css' => 'b085d40d', @@ -58,7 +58,7 @@ return array( 'rsrc/css/application/dashboard/dashboard.css' => '0921c307', 'rsrc/css/application/diff/inline-comment-summary.css' => '51efda3a', 'rsrc/css/application/differential/add-comment.css' => 'c47f8c40', - 'rsrc/css/application/differential/changeset-view.css' => '6a9bdf9c', + 'rsrc/css/application/differential/changeset-view.css' => '41af6d25', 'rsrc/css/application/differential/core.css' => '5b7b8ff4', 'rsrc/css/application/differential/phui-inline-comment.css' => 'be663c95', 'rsrc/css/application/differential/revision-comment.css' => '14b8565a', @@ -96,8 +96,8 @@ return array( 'rsrc/css/application/policy/policy-transaction-detail.css' => '82100a43', 'rsrc/css/application/policy/policy.css' => '957ea14c', 'rsrc/css/application/ponder/ponder-view.css' => 'fbd45f96', - 'rsrc/css/application/project/project-card-view.css' => 'f25746f5', - 'rsrc/css/application/project/project-view.css' => '9f6ce0e1', + 'rsrc/css/application/project/project-card-view.css' => '77219296', + 'rsrc/css/application/project/project-view.css' => '792c9057', 'rsrc/css/application/releeph/releeph-core.css' => '9b3c5733', 'rsrc/css/application/releeph/releeph-preview-branch.css' => 'b7a6f4a5', 'rsrc/css/application/releeph/releeph-request-differential-create-dialog.css' => '8d8b92cd', @@ -130,7 +130,7 @@ return array( 'rsrc/css/phui/object-item/phui-oi-simple-ui.css' => 'a8beebea', 'rsrc/css/phui/phui-action-list.css' => 'f980c059', 'rsrc/css/phui/phui-action-panel.css' => '91c7b835', - 'rsrc/css/phui/phui-badge.css' => '3baef8db', + 'rsrc/css/phui/phui-badge.css' => '22c0cf4f', 'rsrc/css/phui/phui-basic-nav-view.css' => 'a0705f53', 'rsrc/css/phui/phui-big-info-view.css' => 'bd903741', 'rsrc/css/phui/phui-box.css' => '269cbc99', @@ -150,9 +150,9 @@ return array( 'rsrc/css/phui/phui-form.css' => '5815af7b', 'rsrc/css/phui/phui-head-thing.css' => 'fd311e5f', 'rsrc/css/phui/phui-header-view.css' => 'fef6a54e', - 'rsrc/css/phui/phui-hovercard.css' => 'e904f5dc', + 'rsrc/css/phui/phui-hovercard.css' => 'ae091fc5', 'rsrc/css/phui/phui-icon-set-selector.css' => '87db8fee', - 'rsrc/css/phui/phui-icon.css' => '09f46dd9', + 'rsrc/css/phui/phui-icon.css' => '12b387a1', 'rsrc/css/phui/phui-image-mask.css' => 'a8498f9c', 'rsrc/css/phui/phui-info-panel.css' => '27ea50a1', 'rsrc/css/phui/phui-info-view.css' => 'ec92802a', @@ -160,7 +160,7 @@ return array( 'rsrc/css/phui/phui-lightbox.css' => '0a035e40', 'rsrc/css/phui/phui-list.css' => '9da2aa00', 'rsrc/css/phui/phui-object-box.css' => '8b289e3d', - 'rsrc/css/phui/phui-pager.css' => 'bea33d23', + 'rsrc/css/phui/phui-pager.css' => '77d8a794', 'rsrc/css/phui/phui-pinboard-view.css' => '2495140e', 'rsrc/css/phui/phui-property-list-view.css' => '2dc7993f', 'rsrc/css/phui/phui-remarkup-preview.css' => '1a8f2591', @@ -168,7 +168,7 @@ return array( 'rsrc/css/phui/phui-spacing.css' => '042804d6', 'rsrc/css/phui/phui-status.css' => 'd5263e49', 'rsrc/css/phui/phui-tag-view.css' => '84d65f26', - 'rsrc/css/phui/phui-timeline-view.css' => 'bc523970', + 'rsrc/css/phui/phui-timeline-view.css' => 'bf45789e', 'rsrc/css/phui/phui-two-column-view.css' => '8a1074c7', 'rsrc/css/phui/workboards/phui-workboard-color.css' => '783cdff5', 'rsrc/css/phui/workboards/phui-workboard.css' => '3bc85455', @@ -376,7 +376,7 @@ return array( 'rsrc/js/application/aphlict/behavior-aphlict-dropdown.js' => 'caade6f2', 'rsrc/js/application/aphlict/behavior-aphlict-listen.js' => 'fb20ac8d', 'rsrc/js/application/aphlict/behavior-aphlict-status.js' => '5e2634b9', - 'rsrc/js/application/aphlict/behavior-desktop-notifications-control.js' => 'edd1ba66', + 'rsrc/js/application/aphlict/behavior-desktop-notifications-control.js' => 'd5a2d665', 'rsrc/js/application/calendar/behavior-day-view.js' => '4b3c4443', 'rsrc/js/application/calendar/behavior-event-all-day.js' => 'b41537c9', 'rsrc/js/application/calendar/behavior-month-view.js' => 'fe33e256', @@ -563,7 +563,7 @@ return array( 'conduit-api-css' => '7bc725c4', 'config-options-css' => '0ede4c9b', 'config-page-css' => 'c1d5121b', - 'conpherence-durable-column-view' => 'd82e130c', + 'conpherence-durable-column-view' => '292c71f0', 'conpherence-header-pane-css' => 'db93ebc6', 'conpherence-menu-css' => '3d8e5c9c', 'conpherence-message-pane-css' => 'b085d40d', @@ -572,7 +572,7 @@ return array( 'conpherence-thread-manager' => 'c8b5ee6f', 'conpherence-transaction-css' => '85129c68', 'd3' => 'a11a5ff2', - 'differential-changeset-view-css' => '6a9bdf9c', + 'differential-changeset-view-css' => '41af6d25', 'differential-core-view-css' => '5b7b8ff4', 'differential-inline-comment-editor' => '2e3f9738', 'differential-revision-add-comment-css' => 'c47f8c40', @@ -621,7 +621,7 @@ return array( 'javelin-behavior-dashboard-query-panel-select' => '453c5375', 'javelin-behavior-dashboard-tab-panel' => 'd4eecc63', 'javelin-behavior-day-view' => '4b3c4443', - 'javelin-behavior-desktop-notifications-control' => 'edd1ba66', + 'javelin-behavior-desktop-notifications-control' => 'd5a2d665', 'javelin-behavior-detect-timezone' => '4c193c96', 'javelin-behavior-device' => 'bb1dd507', 'javelin-behavior-diff-preview-link' => '051c7832', @@ -837,7 +837,7 @@ return array( 'phrequent-css' => 'ffc185ad', 'phriction-document-css' => '4282e4ad', 'phui-action-panel-css' => '91c7b835', - 'phui-badge-view-css' => '3baef8db', + 'phui-badge-view-css' => '22c0cf4f', 'phui-basic-nav-view-css' => 'a0705f53', 'phui-big-info-view-css' => 'bd903741', 'phui-box-css' => '269cbc99', @@ -863,9 +863,9 @@ return array( 'phui-head-thing-view-css' => 'fd311e5f', 'phui-header-view-css' => 'fef6a54e', 'phui-hovercard' => '1bd28176', - 'phui-hovercard-view-css' => 'e904f5dc', + 'phui-hovercard-view-css' => 'ae091fc5', 'phui-icon-set-selector-css' => '87db8fee', - 'phui-icon-view-css' => '09f46dd9', + 'phui-icon-view-css' => '12b387a1', 'phui-image-mask-css' => 'a8498f9c', 'phui-info-panel-css' => '27ea50a1', 'phui-info-view-css' => 'ec92802a', @@ -880,7 +880,7 @@ return array( 'phui-oi-flush-ui-css' => '9d9685d6', 'phui-oi-list-view-css' => '5c383524', 'phui-oi-simple-ui-css' => 'a8beebea', - 'phui-pager-css' => 'bea33d23', + 'phui-pager-css' => '77d8a794', 'phui-pinboard-view-css' => '2495140e', 'phui-property-list-view-css' => '2dc7993f', 'phui-remarkup-preview-css' => '1a8f2591', @@ -889,7 +889,7 @@ return array( 'phui-status-list-view-css' => 'd5263e49', 'phui-tag-view-css' => '84d65f26', 'phui-theme-css' => '9f261c6b', - 'phui-timeline-view-css' => 'bc523970', + 'phui-timeline-view-css' => 'bf45789e', 'phui-two-column-view-css' => '8a1074c7', 'phui-workboard-color-css' => '783cdff5', 'phui-workboard-view-css' => '3bc85455', @@ -905,8 +905,8 @@ return array( 'policy-edit-css' => '815c66f7', 'policy-transaction-detail-css' => '82100a43', 'ponder-view-css' => 'fbd45f96', - 'project-card-view-css' => 'f25746f5', - 'project-view-css' => '9f6ce0e1', + 'project-card-view-css' => '77219296', + 'project-view-css' => '792c9057', 'releeph-core' => '9b3c5733', 'releeph-preview-branch' => 'b7a6f4a5', 'releeph-request-differential-create-dialog' => '8d8b92cd', @@ -1166,6 +1166,9 @@ return array( 'javelin-dom', 'javelin-reactor-dom', ), + '41af6d25' => array( + 'phui-inline-comment-view-css', + ), 42126667 => array( 'javelin-behavior', 'javelin-dom', @@ -1386,9 +1389,6 @@ return array( '69adf288' => array( 'javelin-install', ), - '6a9bdf9c' => array( - 'phui-inline-comment-view-css', - ), '6ad39b6f' => array( 'javelin-install', 'javelin-event', @@ -2060,6 +2060,13 @@ return array( 'javelin-dom', 'javelin-stratcom', ), + 'd5a2d665' => array( + 'javelin-behavior', + 'javelin-stratcom', + 'javelin-dom', + 'javelin-uri', + 'phabricator-notification', + ), 'd6a7e717' => array( 'multirow-row-manager', 'javelin-install', @@ -2154,13 +2161,6 @@ return array( 'javelin-dom', 'phabricator-draggable-list', ), - 'edd1ba66' => array( - 'javelin-behavior', - 'javelin-stratcom', - 'javelin-dom', - 'javelin-uri', - 'phabricator-notification', - ), 'edf8a145' => array( 'javelin-behavior', 'javelin-uri', diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index c8b3f97726..0fd7dd8418 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -235,6 +235,7 @@ phutil_register_library_map(array( 'CelerityPhysicalResourcesTestCase' => 'applications/celerity/resources/__tests__/CelerityPhysicalResourcesTestCase.php', 'CelerityPostprocessor' => 'applications/celerity/postprocessor/CelerityPostprocessor.php', 'CelerityPostprocessorTestCase' => 'applications/celerity/__tests__/CelerityPostprocessorTestCase.php', + 'CelerityRedGreenPostprocessor' => 'applications/celerity/postprocessor/CelerityRedGreenPostprocessor.php', 'CelerityResourceController' => 'applications/celerity/controller/CelerityResourceController.php', 'CelerityResourceGraph' => 'applications/celerity/CelerityResourceGraph.php', 'CelerityResourceMap' => 'applications/celerity/CelerityResourceMap.php', @@ -2011,7 +2012,16 @@ phutil_register_library_map(array( 'PhabricatorBadgesAwardController' => 'applications/badges/controller/PhabricatorBadgesAwardController.php', 'PhabricatorBadgesAwardQuery' => 'applications/badges/query/PhabricatorBadgesAwardQuery.php', 'PhabricatorBadgesBadge' => 'applications/badges/storage/PhabricatorBadgesBadge.php', + 'PhabricatorBadgesBadgeAwardTransaction' => 'applications/badges/xaction/PhabricatorBadgesBadgeAwardTransaction.php', + 'PhabricatorBadgesBadgeDescriptionTransaction' => 'applications/badges/xaction/PhabricatorBadgesBadgeDescriptionTransaction.php', + 'PhabricatorBadgesBadgeFlavorTransaction' => 'applications/badges/xaction/PhabricatorBadgesBadgeFlavorTransaction.php', + 'PhabricatorBadgesBadgeIconTransaction' => 'applications/badges/xaction/PhabricatorBadgesBadgeIconTransaction.php', 'PhabricatorBadgesBadgeNameNgrams' => 'applications/badges/storage/PhabricatorBadgesBadgeNameNgrams.php', + 'PhabricatorBadgesBadgeNameTransaction' => 'applications/badges/xaction/PhabricatorBadgesBadgeNameTransaction.php', + 'PhabricatorBadgesBadgeQualityTransaction' => 'applications/badges/xaction/PhabricatorBadgesBadgeQualityTransaction.php', + 'PhabricatorBadgesBadgeRevokeTransaction' => 'applications/badges/xaction/PhabricatorBadgesBadgeRevokeTransaction.php', + 'PhabricatorBadgesBadgeStatusTransaction' => 'applications/badges/xaction/PhabricatorBadgesBadgeStatusTransaction.php', + 'PhabricatorBadgesBadgeTransactionType' => 'applications/badges/xaction/PhabricatorBadgesBadgeTransactionType.php', 'PhabricatorBadgesCommentController' => 'applications/badges/controller/PhabricatorBadgesCommentController.php', 'PhabricatorBadgesController' => 'applications/badges/controller/PhabricatorBadgesController.php', 'PhabricatorBadgesCreateCapability' => 'applications/badges/capability/PhabricatorBadgesCreateCapability.php', @@ -3306,6 +3316,7 @@ phutil_register_library_map(array( 'PhabricatorPeopleAnyOwnerDatasource' => 'applications/people/typeahead/PhabricatorPeopleAnyOwnerDatasource.php', 'PhabricatorPeopleApplication' => 'applications/people/application/PhabricatorPeopleApplication.php', 'PhabricatorPeopleApproveController' => 'applications/people/controller/PhabricatorPeopleApproveController.php', + 'PhabricatorPeopleBadgesProfileMenuItem' => 'applications/people/menuitem/PhabricatorPeopleBadgesProfileMenuItem.php', 'PhabricatorPeopleController' => 'applications/people/controller/PhabricatorPeopleController.php', 'PhabricatorPeopleCreateController' => 'applications/people/controller/PhabricatorPeopleCreateController.php', 'PhabricatorPeopleCreateGuidanceContext' => 'applications/people/guidance/PhabricatorPeopleCreateGuidanceContext.php', @@ -3329,6 +3340,7 @@ phutil_register_library_map(array( 'PhabricatorPeopleNoOwnerDatasource' => 'applications/people/typeahead/PhabricatorPeopleNoOwnerDatasource.php', 'PhabricatorPeopleOwnerDatasource' => 'applications/people/typeahead/PhabricatorPeopleOwnerDatasource.php', 'PhabricatorPeoplePictureProfileMenuItem' => 'applications/people/menuitem/PhabricatorPeoplePictureProfileMenuItem.php', + 'PhabricatorPeopleProfileBadgesController' => 'applications/people/controller/PhabricatorPeopleProfileBadgesController.php', 'PhabricatorPeopleProfileController' => 'applications/people/controller/PhabricatorPeopleProfileController.php', 'PhabricatorPeopleProfileEditController' => 'applications/people/controller/PhabricatorPeopleProfileEditController.php', 'PhabricatorPeopleProfileManageController' => 'applications/people/controller/PhabricatorPeopleProfileManageController.php', @@ -3370,16 +3382,20 @@ phutil_register_library_map(array( 'PhabricatorPhurlShortURLDefaultController' => 'applications/phurl/controller/PhabricatorPhurlShortURLDefaultController.php', 'PhabricatorPhurlURL' => 'applications/phurl/storage/PhabricatorPhurlURL.php', 'PhabricatorPhurlURLAccessController' => 'applications/phurl/controller/PhabricatorPhurlURLAccessController.php', + 'PhabricatorPhurlURLAliasTransaction' => 'applications/phurl/xaction/PhabricatorPhurlURLAliasTransaction.php', 'PhabricatorPhurlURLCommentController' => 'applications/phurl/controller/PhabricatorPhurlURLCommentController.php', 'PhabricatorPhurlURLCreateCapability' => 'applications/phurl/capability/PhabricatorPhurlURLCreateCapability.php', 'PhabricatorPhurlURLDatasource' => 'applications/phurl/typeahead/PhabricatorPhurlURLDatasource.php', + 'PhabricatorPhurlURLDescriptionTransaction' => 'applications/phurl/xaction/PhabricatorPhurlURLDescriptionTransaction.php', 'PhabricatorPhurlURLEditConduitAPIMethod' => 'applications/phurl/conduit/PhabricatorPhurlURLEditConduitAPIMethod.php', 'PhabricatorPhurlURLEditController' => 'applications/phurl/controller/PhabricatorPhurlURLEditController.php', 'PhabricatorPhurlURLEditEngine' => 'applications/phurl/editor/PhabricatorPhurlURLEditEngine.php', 'PhabricatorPhurlURLEditor' => 'applications/phurl/editor/PhabricatorPhurlURLEditor.php', 'PhabricatorPhurlURLListController' => 'applications/phurl/controller/PhabricatorPhurlURLListController.php', + 'PhabricatorPhurlURLLongURLTransaction' => 'applications/phurl/xaction/PhabricatorPhurlURLLongURLTransaction.php', 'PhabricatorPhurlURLMailReceiver' => 'applications/phurl/mail/PhabricatorPhurlURLMailReceiver.php', 'PhabricatorPhurlURLNameNgrams' => 'applications/phurl/storage/PhabricatorPhurlURLNameNgrams.php', + 'PhabricatorPhurlURLNameTransaction' => 'applications/phurl/xaction/PhabricatorPhurlURLNameTransaction.php', 'PhabricatorPhurlURLPHIDType' => 'applications/phurl/phid/PhabricatorPhurlURLPHIDType.php', 'PhabricatorPhurlURLQuery' => 'applications/phurl/query/PhabricatorPhurlURLQuery.php', 'PhabricatorPhurlURLReplyHandler' => 'applications/phurl/mail/PhabricatorPhurlURLReplyHandler.php', @@ -3388,6 +3404,7 @@ phutil_register_library_map(array( 'PhabricatorPhurlURLTransaction' => 'applications/phurl/storage/PhabricatorPhurlURLTransaction.php', 'PhabricatorPhurlURLTransactionComment' => 'applications/phurl/storage/PhabricatorPhurlURLTransactionComment.php', 'PhabricatorPhurlURLTransactionQuery' => 'applications/phurl/query/PhabricatorPhurlURLTransactionQuery.php', + 'PhabricatorPhurlURLTransactionType' => 'applications/phurl/xaction/PhabricatorPhurlURLTransactionType.php', 'PhabricatorPhurlURLViewController' => 'applications/phurl/controller/PhabricatorPhurlURLViewController.php', 'PhabricatorPinnedApplicationsSetting' => 'applications/settings/setting/PhabricatorPinnedApplicationsSetting.php', 'PhabricatorPirateEnglishTranslation' => 'infrastructure/internationalization/translation/PhabricatorPirateEnglishTranslation.php', @@ -4125,12 +4142,15 @@ phutil_register_library_map(array( 'PhabricatorXHProfApplication' => 'applications/xhprof/application/PhabricatorXHProfApplication.php', 'PhabricatorXHProfController' => 'applications/xhprof/controller/PhabricatorXHProfController.php', 'PhabricatorXHProfDAO' => 'applications/xhprof/storage/PhabricatorXHProfDAO.php', + 'PhabricatorXHProfDropController' => 'applications/xhprof/controller/PhabricatorXHProfDropController.php', 'PhabricatorXHProfProfileController' => 'applications/xhprof/controller/PhabricatorXHProfProfileController.php', 'PhabricatorXHProfProfileSymbolView' => 'applications/xhprof/view/PhabricatorXHProfProfileSymbolView.php', 'PhabricatorXHProfProfileTopLevelView' => 'applications/xhprof/view/PhabricatorXHProfProfileTopLevelView.php', 'PhabricatorXHProfProfileView' => 'applications/xhprof/view/PhabricatorXHProfProfileView.php', 'PhabricatorXHProfSample' => 'applications/xhprof/storage/PhabricatorXHProfSample.php', 'PhabricatorXHProfSampleListController' => 'applications/xhprof/controller/PhabricatorXHProfSampleListController.php', + 'PhabricatorXHProfSampleQuery' => 'applications/xhprof/query/PhabricatorXHProfSampleQuery.php', + 'PhabricatorXHProfSampleSearchEngine' => 'applications/xhprof/query/PhabricatorXHProfSampleSearchEngine.php', 'PhabricatorYoutubeRemarkupRule' => 'infrastructure/markup/rule/PhabricatorYoutubeRemarkupRule.php', 'Phame404Response' => 'applications/phame/site/Phame404Response.php', 'PhameBlog' => 'applications/phame/storage/PhameBlog.php', @@ -4911,6 +4931,7 @@ phutil_register_library_map(array( 'CelerityPhysicalResourcesTestCase' => 'PhabricatorTestCase', 'CelerityPostprocessor' => 'Phobject', 'CelerityPostprocessorTestCase' => 'PhabricatorTestCase', + 'CelerityRedGreenPostprocessor' => 'CelerityPostprocessor', 'CelerityResourceController' => 'PhabricatorController', 'CelerityResourceGraph' => 'AbstractDirectedGraph', 'CelerityResourceMap' => 'Phobject', @@ -6949,7 +6970,16 @@ phutil_register_library_map(array( 'PhabricatorConduitResultInterface', 'PhabricatorNgramsInterface', ), + 'PhabricatorBadgesBadgeAwardTransaction' => 'PhabricatorBadgesBadgeTransactionType', + 'PhabricatorBadgesBadgeDescriptionTransaction' => 'PhabricatorBadgesBadgeTransactionType', + 'PhabricatorBadgesBadgeFlavorTransaction' => 'PhabricatorBadgesBadgeTransactionType', + 'PhabricatorBadgesBadgeIconTransaction' => 'PhabricatorBadgesBadgeTransactionType', 'PhabricatorBadgesBadgeNameNgrams' => 'PhabricatorSearchNgrams', + 'PhabricatorBadgesBadgeNameTransaction' => 'PhabricatorBadgesBadgeTransactionType', + 'PhabricatorBadgesBadgeQualityTransaction' => 'PhabricatorBadgesBadgeTransactionType', + 'PhabricatorBadgesBadgeRevokeTransaction' => 'PhabricatorBadgesBadgeTransactionType', + 'PhabricatorBadgesBadgeStatusTransaction' => 'PhabricatorBadgesBadgeTransactionType', + 'PhabricatorBadgesBadgeTransactionType' => 'PhabricatorModularTransactionType', 'PhabricatorBadgesCommentController' => 'PhabricatorBadgesController', 'PhabricatorBadgesController' => 'PhabricatorController', 'PhabricatorBadgesCreateCapability' => 'PhabricatorPolicyCapability', @@ -6975,7 +7005,7 @@ phutil_register_library_map(array( 'PhabricatorBadgesSchemaSpec' => 'PhabricatorConfigSchemaSpec', 'PhabricatorBadgesSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod', 'PhabricatorBadgesSearchEngine' => 'PhabricatorApplicationSearchEngine', - 'PhabricatorBadgesTransaction' => 'PhabricatorApplicationTransaction', + 'PhabricatorBadgesTransaction' => 'PhabricatorModularTransaction', 'PhabricatorBadgesTransactionComment' => 'PhabricatorApplicationTransactionComment', 'PhabricatorBadgesTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'PhabricatorBadgesViewController' => 'PhabricatorBadgesProfileController', @@ -8445,6 +8475,7 @@ phutil_register_library_map(array( 'PhabricatorPeopleAnyOwnerDatasource' => 'PhabricatorTypeaheadDatasource', 'PhabricatorPeopleApplication' => 'PhabricatorApplication', 'PhabricatorPeopleApproveController' => 'PhabricatorPeopleController', + 'PhabricatorPeopleBadgesProfileMenuItem' => 'PhabricatorProfileMenuItem', 'PhabricatorPeopleController' => 'PhabricatorController', 'PhabricatorPeopleCreateController' => 'PhabricatorPeopleController', 'PhabricatorPeopleCreateGuidanceContext' => 'PhabricatorGuidanceContext', @@ -8468,6 +8499,7 @@ phutil_register_library_map(array( 'PhabricatorPeopleNoOwnerDatasource' => 'PhabricatorTypeaheadDatasource', 'PhabricatorPeopleOwnerDatasource' => 'PhabricatorTypeaheadCompositeDatasource', 'PhabricatorPeoplePictureProfileMenuItem' => 'PhabricatorProfileMenuItem', + 'PhabricatorPeopleProfileBadgesController' => 'PhabricatorPeopleProfileController', 'PhabricatorPeopleProfileController' => 'PhabricatorPeopleController', 'PhabricatorPeopleProfileEditController' => 'PhabricatorPeopleProfileController', 'PhabricatorPeopleProfileManageController' => 'PhabricatorPeopleProfileController', @@ -8522,24 +8554,29 @@ phutil_register_library_map(array( 'PhabricatorNgramsInterface', ), 'PhabricatorPhurlURLAccessController' => 'PhabricatorPhurlController', + 'PhabricatorPhurlURLAliasTransaction' => 'PhabricatorPhurlURLTransactionType', 'PhabricatorPhurlURLCommentController' => 'PhabricatorPhurlController', 'PhabricatorPhurlURLCreateCapability' => 'PhabricatorPolicyCapability', 'PhabricatorPhurlURLDatasource' => 'PhabricatorTypeaheadDatasource', + 'PhabricatorPhurlURLDescriptionTransaction' => 'PhabricatorPhurlURLTransactionType', 'PhabricatorPhurlURLEditConduitAPIMethod' => 'PhabricatorEditEngineAPIMethod', 'PhabricatorPhurlURLEditController' => 'PhabricatorPhurlController', 'PhabricatorPhurlURLEditEngine' => 'PhabricatorEditEngine', 'PhabricatorPhurlURLEditor' => 'PhabricatorApplicationTransactionEditor', 'PhabricatorPhurlURLListController' => 'PhabricatorPhurlController', + 'PhabricatorPhurlURLLongURLTransaction' => 'PhabricatorPhurlURLTransactionType', 'PhabricatorPhurlURLMailReceiver' => 'PhabricatorObjectMailReceiver', 'PhabricatorPhurlURLNameNgrams' => 'PhabricatorSearchNgrams', + 'PhabricatorPhurlURLNameTransaction' => 'PhabricatorPhurlURLTransactionType', 'PhabricatorPhurlURLPHIDType' => 'PhabricatorPHIDType', 'PhabricatorPhurlURLQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorPhurlURLReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler', 'PhabricatorPhurlURLSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod', 'PhabricatorPhurlURLSearchEngine' => 'PhabricatorApplicationSearchEngine', - 'PhabricatorPhurlURLTransaction' => 'PhabricatorApplicationTransaction', + 'PhabricatorPhurlURLTransaction' => 'PhabricatorModularTransaction', 'PhabricatorPhurlURLTransactionComment' => 'PhabricatorApplicationTransactionComment', 'PhabricatorPhurlURLTransactionQuery' => 'PhabricatorApplicationTransactionQuery', + 'PhabricatorPhurlURLTransactionType' => 'PhabricatorModularTransactionType', 'PhabricatorPhurlURLViewController' => 'PhabricatorPhurlController', 'PhabricatorPinnedApplicationsSetting' => 'PhabricatorInternalSetting', 'PhabricatorPirateEnglishTranslation' => 'PhutilTranslation', @@ -9436,12 +9473,18 @@ phutil_register_library_map(array( 'PhabricatorXHProfApplication' => 'PhabricatorApplication', 'PhabricatorXHProfController' => 'PhabricatorController', 'PhabricatorXHProfDAO' => 'PhabricatorLiskDAO', + 'PhabricatorXHProfDropController' => 'PhabricatorXHProfController', 'PhabricatorXHProfProfileController' => 'PhabricatorXHProfController', 'PhabricatorXHProfProfileSymbolView' => 'PhabricatorXHProfProfileView', 'PhabricatorXHProfProfileTopLevelView' => 'PhabricatorXHProfProfileView', 'PhabricatorXHProfProfileView' => 'AphrontView', - 'PhabricatorXHProfSample' => 'PhabricatorXHProfDAO', + 'PhabricatorXHProfSample' => array( + 'PhabricatorXHProfDAO', + 'PhabricatorPolicyInterface', + ), 'PhabricatorXHProfSampleListController' => 'PhabricatorXHProfController', + 'PhabricatorXHProfSampleQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', + 'PhabricatorXHProfSampleSearchEngine' => 'PhabricatorApplicationSearchEngine', 'PhabricatorYoutubeRemarkupRule' => 'PhutilRemarkupRule', 'Phame404Response' => 'AphrontHTMLResponse', 'PhameBlog' => array( diff --git a/src/applications/audit/query/PhabricatorCommitSearchEngine.php b/src/applications/audit/query/PhabricatorCommitSearchEngine.php index 7f429dd596..e1c1120608 100644 --- a/src/applications/audit/query/PhabricatorCommitSearchEngine.php +++ b/src/applications/audit/query/PhabricatorCommitSearchEngine.php @@ -4,7 +4,7 @@ final class PhabricatorCommitSearchEngine extends PhabricatorApplicationSearchEngine { public function getResultTypeDescription() { - return pht('Commits'); + return pht('Diffusion Commits'); } public function getApplicationClassName() { diff --git a/src/applications/auth/query/PhabricatorAuthInviteSearchEngine.php b/src/applications/auth/query/PhabricatorAuthInviteSearchEngine.php index d07ed15d41..e439dd9fb8 100644 --- a/src/applications/auth/query/PhabricatorAuthInviteSearchEngine.php +++ b/src/applications/auth/query/PhabricatorAuthInviteSearchEngine.php @@ -4,13 +4,17 @@ final class PhabricatorAuthInviteSearchEngine extends PhabricatorApplicationSearchEngine { public function getResultTypeDescription() { - return pht('Email Invites'); + return pht('Auth Email Invites'); } public function getApplicationClassName() { return 'PhabricatorAuthApplication'; } + public function canUseInPanelContext() { + return false; + } + public function buildSavedQueryFromRequest(AphrontRequest $request) { $saved = new PhabricatorSavedQuery(); diff --git a/src/applications/badges/controller/PhabricatorBadgesArchiveController.php b/src/applications/badges/controller/PhabricatorBadgesArchiveController.php index 52e1b9f1c7..f109d9459a 100644 --- a/src/applications/badges/controller/PhabricatorBadgesArchiveController.php +++ b/src/applications/badges/controller/PhabricatorBadgesArchiveController.php @@ -32,7 +32,8 @@ final class PhabricatorBadgesArchiveController $xactions = array(); $xactions[] = id(new PhabricatorBadgesTransaction()) - ->setTransactionType(PhabricatorBadgesTransaction::TYPE_STATUS) + ->setTransactionType( + PhabricatorBadgesBadgeStatusTransaction::TRANSACTIONTYPE) ->setNewValue($new_status); id(new PhabricatorBadgesEditor()) diff --git a/src/applications/badges/controller/PhabricatorBadgesAwardController.php b/src/applications/badges/controller/PhabricatorBadgesAwardController.php index f9294ec5c6..e934e4f2a1 100644 --- a/src/applications/badges/controller/PhabricatorBadgesAwardController.php +++ b/src/applications/badges/controller/PhabricatorBadgesAwardController.php @@ -15,7 +15,7 @@ final class PhabricatorBadgesAwardController return new Aphront404Response(); } - $view_uri = '/p/'.$user->getUsername(); + $view_uri = '/people/badges/'.$user->getID().'/'; if ($request->isFormPost()) { $badge_phids = $request->getArr('badgePHIDs'); @@ -37,7 +37,8 @@ final class PhabricatorBadgesAwardController foreach ($badges as $badge) { $xactions = array(); $xactions[] = id(new PhabricatorBadgesTransaction()) - ->setTransactionType(PhabricatorBadgesTransaction::TYPE_AWARD) + ->setTransactionType( + PhabricatorBadgesBadgeAwardTransaction::TRANSACTIONTYPE) ->setNewValue($award_phids); $editor = id(new PhabricatorBadgesEditor()) @@ -66,7 +67,7 @@ final class PhabricatorBadgesAwardController )))); $dialog = $this->newDialog() - ->setTitle(pht('Grant Badge')) + ->setTitle(pht('Award Badge')) ->appendForm($form) ->addCancelButton($view_uri) ->addSubmitButton(pht('Award')); diff --git a/src/applications/badges/controller/PhabricatorBadgesEditRecipientsController.php b/src/applications/badges/controller/PhabricatorBadgesEditRecipientsController.php index 546c41a1d4..9045869fc8 100644 --- a/src/applications/badges/controller/PhabricatorBadgesEditRecipientsController.php +++ b/src/applications/badges/controller/PhabricatorBadgesEditRecipientsController.php @@ -37,7 +37,8 @@ final class PhabricatorBadgesEditRecipientsController } $xactions[] = id(new PhabricatorBadgesTransaction()) - ->setTransactionType(PhabricatorBadgesTransaction::TYPE_AWARD) + ->setTransactionType( + PhabricatorBadgesBadgeAwardTransaction::TRANSACTIONTYPE) ->setNewValue($award_phids); $editor = id(new PhabricatorBadgesEditor()) diff --git a/src/applications/badges/controller/PhabricatorBadgesRemoveRecipientsController.php b/src/applications/badges/controller/PhabricatorBadgesRemoveRecipientsController.php index 0185698686..e6638b745c 100644 --- a/src/applications/badges/controller/PhabricatorBadgesRemoveRecipientsController.php +++ b/src/applications/badges/controller/PhabricatorBadgesRemoveRecipientsController.php @@ -29,12 +29,13 @@ final class PhabricatorBadgesRemoveRecipientsController return new Aphront404Response(); } - $view_uri = $this->getApplicationURI('view/'.$badge->getID().'/'); + $view_uri = $this->getApplicationURI('recipients/'.$badge->getID().'/'); if ($request->isFormPost()) { $xactions = array(); $xactions[] = id(new PhabricatorBadgesTransaction()) - ->setTransactionType(PhabricatorBadgesTransaction::TYPE_REVOKE) + ->setTransactionType( + PhabricatorBadgesBadgeRevokeTransaction::TRANSACTIONTYPE) ->setNewValue(array($remove_phid)); $editor = id(new PhabricatorBadgesEditor()) diff --git a/src/applications/badges/controller/PhabricatorBadgesViewController.php b/src/applications/badges/controller/PhabricatorBadgesViewController.php index 3c434ff1d5..a5390ea5f4 100644 --- a/src/applications/badges/controller/PhabricatorBadgesViewController.php +++ b/src/applications/badges/controller/PhabricatorBadgesViewController.php @@ -90,7 +90,6 @@ final class PhabricatorBadgesViewController $id = $badge->getID(); $edit_uri = $this->getApplicationURI("/edit/{$id}/"); $archive_uri = $this->getApplicationURI("/archive/{$id}/"); - $award_uri = $this->getApplicationURI("/recipients/{$id}/add/"); $curtain = $this->newCurtainView($badge); @@ -119,14 +118,6 @@ final class PhabricatorBadgesViewController ->setHref($archive_uri)); } - $curtain->addAction( - id(new PhabricatorActionView()) - ->setName('Add Recipients') - ->setIcon('fa-users') - ->setDisabled(!$can_edit) - ->setWorkflow(true) - ->setHref($award_uri)); - return $curtain; } diff --git a/src/applications/badges/editor/PhabricatorBadgesEditEngine.php b/src/applications/badges/editor/PhabricatorBadgesEditEngine.php index 937dc1bd0e..596e70cd13 100644 --- a/src/applications/badges/editor/PhabricatorBadgesEditEngine.php +++ b/src/applications/badges/editor/PhabricatorBadgesEditEngine.php @@ -21,6 +21,10 @@ final class PhabricatorBadgesEditEngine return pht('Configure creation and editing forms in Badges.'); } + public function isEngineConfigurable() { + return false; + } + protected function newEditableObject() { return PhabricatorBadgesBadge::initializeNewBadge($this->getViewer()); } @@ -82,20 +86,24 @@ final class PhabricatorBadgesEditEngine ->setLabel(pht('Name')) ->setDescription(pht('Badge name.')) ->setConduitTypeDescription(pht('New badge name.')) - ->setTransactionType(PhabricatorBadgesTransaction::TYPE_NAME) - ->setValue($object->getName()), + ->setTransactionType( + PhabricatorBadgesBadgeNameTransaction::TRANSACTIONTYPE) + ->setValue($object->getName()) + ->setIsRequired(true), id(new PhabricatorTextEditField()) ->setKey('flavor') - ->setLabel(pht('Flavor text')) + ->setLabel(pht('Flavor Text')) ->setDescription(pht('Short description of the badge.')) ->setConduitTypeDescription(pht('New badge flavor.')) ->setValue($object->getFlavor()) - ->setTransactionType(PhabricatorBadgesTransaction::TYPE_FLAVOR), + ->setTransactionType( + PhabricatorBadgesBadgeFlavorTransaction::TRANSACTIONTYPE), id(new PhabricatorIconSetEditField()) ->setKey('icon') ->setLabel(pht('Icon')) ->setIconSet(new PhabricatorBadgesIconSet()) - ->setTransactionType(PhabricatorBadgesTransaction::TYPE_ICON) + ->setTransactionType( + PhabricatorBadgesBadgeIconTransaction::TRANSACTIONTYPE) ->setConduitDescription(pht('Change the badge icon.')) ->setConduitTypeDescription(pht('New badge icon.')) ->setValue($object->getIcon()), @@ -105,14 +113,16 @@ final class PhabricatorBadgesEditEngine ->setDescription(pht('Color and rarity of the badge.')) ->setConduitTypeDescription(pht('New badge quality.')) ->setValue($object->getQuality()) - ->setTransactionType(PhabricatorBadgesTransaction::TYPE_QUALITY) + ->setTransactionType( + PhabricatorBadgesBadgeQualityTransaction::TRANSACTIONTYPE) ->setOptions(PhabricatorBadgesQuality::getDropdownQualityMap()), id(new PhabricatorRemarkupEditField()) ->setKey('description') ->setLabel(pht('Description')) ->setDescription(pht('Badge long description.')) ->setConduitTypeDescription(pht('New badge description.')) - ->setTransactionType(PhabricatorBadgesTransaction::TYPE_DESCRIPTION) + ->setTransactionType( + PhabricatorBadgesBadgeDescriptionTransaction::TRANSACTIONTYPE) ->setValue($object->getDescription()), ); } diff --git a/src/applications/badges/editor/PhabricatorBadgesEditor.php b/src/applications/badges/editor/PhabricatorBadgesEditor.php index 45a42a3362..48057f66e6 100644 --- a/src/applications/badges/editor/PhabricatorBadgesEditor.php +++ b/src/applications/badges/editor/PhabricatorBadgesEditor.php @@ -11,22 +11,20 @@ final class PhabricatorBadgesEditor return pht('Badges'); } + public function getCreateObjectTitle($author, $object) { + return pht('%s created this badge.', $author); + } + + public function getCreateObjectTitleForFeed($author, $object) { + return pht('%s created %s.', $author, $object); + } + protected function supportsSearch() { return true; } public function getTransactionTypes() { $types = parent::getTransactionTypes(); - - $types[] = PhabricatorBadgesTransaction::TYPE_NAME; - $types[] = PhabricatorBadgesTransaction::TYPE_FLAVOR; - $types[] = PhabricatorBadgesTransaction::TYPE_DESCRIPTION; - $types[] = PhabricatorBadgesTransaction::TYPE_ICON; - $types[] = PhabricatorBadgesTransaction::TYPE_STATUS; - $types[] = PhabricatorBadgesTransaction::TYPE_QUALITY; - $types[] = PhabricatorBadgesTransaction::TYPE_AWARD; - $types[] = PhabricatorBadgesTransaction::TYPE_REVOKE; - $types[] = PhabricatorTransactions::TYPE_COMMENT; $types[] = PhabricatorTransactions::TYPE_EDGE; $types[] = PhabricatorTransactions::TYPE_EDIT_POLICY; @@ -34,159 +32,6 @@ final class PhabricatorBadgesEditor return $types; } - protected function getCustomTransactionOldValue( - PhabricatorLiskDAO $object, - PhabricatorApplicationTransaction $xaction) { - switch ($xaction->getTransactionType()) { - case PhabricatorBadgesTransaction::TYPE_NAME: - return $object->getName(); - case PhabricatorBadgesTransaction::TYPE_FLAVOR: - return $object->getFlavor(); - case PhabricatorBadgesTransaction::TYPE_DESCRIPTION: - return $object->getDescription(); - case PhabricatorBadgesTransaction::TYPE_ICON: - return $object->getIcon(); - case PhabricatorBadgesTransaction::TYPE_QUALITY: - return (int)$object->getQuality(); - case PhabricatorBadgesTransaction::TYPE_STATUS: - return $object->getStatus(); - case PhabricatorBadgesTransaction::TYPE_AWARD: - $award_phids = mpull($object->getAwards(), 'getRecipientPHID'); - return $award_phids; - case PhabricatorBadgesTransaction::TYPE_REVOKE: - return null; - } - - return parent::getCustomTransactionOldValue($object, $xaction); - } - - protected function getCustomTransactionNewValue( - PhabricatorLiskDAO $object, - PhabricatorApplicationTransaction $xaction) { - - switch ($xaction->getTransactionType()) { - case PhabricatorBadgesTransaction::TYPE_NAME: - case PhabricatorBadgesTransaction::TYPE_FLAVOR: - case PhabricatorBadgesTransaction::TYPE_DESCRIPTION: - case PhabricatorBadgesTransaction::TYPE_ICON: - case PhabricatorBadgesTransaction::TYPE_STATUS: - case PhabricatorBadgesTransaction::TYPE_AWARD: - case PhabricatorBadgesTransaction::TYPE_REVOKE: - return $xaction->getNewValue(); - case PhabricatorBadgesTransaction::TYPE_QUALITY: - return (int)$xaction->getNewValue(); - } - - return parent::getCustomTransactionNewValue($object, $xaction); - } - - protected function applyCustomInternalTransaction( - PhabricatorLiskDAO $object, - PhabricatorApplicationTransaction $xaction) { - - $type = $xaction->getTransactionType(); - switch ($type) { - case PhabricatorBadgesTransaction::TYPE_NAME: - $object->setName($xaction->getNewValue()); - return; - case PhabricatorBadgesTransaction::TYPE_FLAVOR: - $object->setFlavor($xaction->getNewValue()); - return; - case PhabricatorBadgesTransaction::TYPE_DESCRIPTION: - $object->setDescription($xaction->getNewValue()); - return; - case PhabricatorBadgesTransaction::TYPE_ICON: - $object->setIcon($xaction->getNewValue()); - return; - case PhabricatorBadgesTransaction::TYPE_QUALITY: - $object->setQuality($xaction->getNewValue()); - return; - case PhabricatorBadgesTransaction::TYPE_STATUS: - $object->setStatus($xaction->getNewValue()); - return; - case PhabricatorBadgesTransaction::TYPE_AWARD: - case PhabricatorBadgesTransaction::TYPE_REVOKE: - return; - } - - return parent::applyCustomInternalTransaction($object, $xaction); - } - - protected function applyCustomExternalTransaction( - PhabricatorLiskDAO $object, - PhabricatorApplicationTransaction $xaction) { - - $type = $xaction->getTransactionType(); - switch ($type) { - case PhabricatorBadgesTransaction::TYPE_NAME: - case PhabricatorBadgesTransaction::TYPE_FLAVOR: - case PhabricatorBadgesTransaction::TYPE_DESCRIPTION: - case PhabricatorBadgesTransaction::TYPE_ICON: - case PhabricatorBadgesTransaction::TYPE_STATUS: - case PhabricatorBadgesTransaction::TYPE_QUALITY: - return; - case PhabricatorBadgesTransaction::TYPE_REVOKE: - $revoked_recipient_phids = $xaction->getNewValue(); - $awards = $object->getAwards(); - $awards = mpull($awards, null, 'getRecipientPHID'); - - foreach ($revoked_recipient_phids as $phid) { - $awards[$phid]->delete(); - } - $object->attachAwards($awards); - return; - case PhabricatorBadgesTransaction::TYPE_AWARD: - $recipient_phids = $xaction->getNewValue(); - $awards = $object->getAwards(); - $awards = mpull($awards, null, 'getRecipientPHID'); - - foreach ($recipient_phids as $phid) { - $award = idx($awards, $phid); - if (!$award) { - $award = PhabricatorBadgesAward::initializeNewBadgesAward( - $this->getActor(), - $object, - $phid); - $award->save(); - $awards[] = $award; - } - } - $object->attachAwards($awards); - return; - } - - return parent::applyCustomExternalTransaction($object, $xaction); - } - - protected function validateTransaction( - PhabricatorLiskDAO $object, - $type, - array $xactions) { - - $errors = parent::validateTransaction($object, $type, $xactions); - - switch ($type) { - case PhabricatorBadgesTransaction::TYPE_NAME: - $missing = $this->validateIsEmptyTextField( - $object->getName(), - $xactions); - - if ($missing) { - $error = new PhabricatorApplicationTransactionValidationError( - $type, - pht('Required'), - pht('Badge name is required.'), - nonempty(last($xactions), null)); - - $error->setIsMissingFieldError(true); - $errors[] = $error; - } - break; - } - - return $errors; - } - protected function shouldSendMail( PhabricatorLiskDAO $object, array $xactions) { @@ -210,6 +55,30 @@ final class PhabricatorBadgesEditor return true; } + protected function expandTransactions( + PhabricatorLiskDAO $object, + array $xactions) { + + $actor = $this->getActor(); + $actor_phid = $actor->getPHID(); + + $results = parent::expandTransactions($object, $xactions); + + // Automatically subscribe the author when they create a badge. + if ($this->getIsNewObject()) { + if ($actor_phid) { + $results[] = id(new PhabricatorBadgesTransaction()) + ->setTransactionType(PhabricatorTransactions::TYPE_SUBSCRIBERS) + ->setNewValue( + array( + '+' => array($actor_phid => $actor_phid), + )); + } + } + + return $results; + } + protected function buildReplyHandler(PhabricatorLiskDAO $object) { return id(new PhabricatorBadgesReplyHandler()) ->setMailReceiver($object); diff --git a/src/applications/badges/query/PhabricatorBadgesSearchEngine.php b/src/applications/badges/query/PhabricatorBadgesSearchEngine.php index fc2bf7ef1e..4db0cdd979 100644 --- a/src/applications/badges/query/PhabricatorBadgesSearchEngine.php +++ b/src/applications/badges/query/PhabricatorBadgesSearchEngine.php @@ -4,7 +4,7 @@ final class PhabricatorBadgesSearchEngine extends PhabricatorApplicationSearchEngine { public function getResultTypeDescription() { - return pht('Badge'); + return pht('Badges'); } public function getApplicationClassName() { @@ -147,7 +147,7 @@ final class PhabricatorBadgesSearchEngine ->setTitle(pht('Welcome to %s', $app_name)) ->setDescription( pht('Badges let you award and distinguish special users '. - 'throughout your instance.')) + 'throughout your install.')) ->addAction($create_button); return $view; diff --git a/src/applications/badges/storage/PhabricatorBadgesBadge.php b/src/applications/badges/storage/PhabricatorBadgesBadge.php index 4cdc4edf61..cf02f705ce 100644 --- a/src/applications/badges/storage/PhabricatorBadgesBadge.php +++ b/src/applications/badges/storage/PhabricatorBadgesBadge.php @@ -156,7 +156,7 @@ final class PhabricatorBadgesBadge extends PhabricatorBadgesDAO public function isAutomaticallySubscribed($phid) { - return ($this->creatorPHID == $phid); + return false; } diff --git a/src/applications/badges/storage/PhabricatorBadgesTransaction.php b/src/applications/badges/storage/PhabricatorBadgesTransaction.php index 24509f94bb..75d8f7fd59 100644 --- a/src/applications/badges/storage/PhabricatorBadgesTransaction.php +++ b/src/applications/badges/storage/PhabricatorBadgesTransaction.php @@ -1,16 +1,7 @@ getAuthorPHID(); - $object_phid = $this->getObjectPHID(); - - $old = $this->getOldValue(); - $new = $this->getNewValue(); - - $type = $this->getTransactionType(); - switch ($type) { - case PhabricatorTransactions::TYPE_CREATE: - return pht( - '%s created this badge.', - $this->renderHandleLink($author_phid)); - case self::TYPE_NAME: - if ($old === null) { - return pht( - '%s created this badge.', - $this->renderHandleLink($author_phid)); - } else { - return pht( - '%s renamed this badge from "%s" to "%s".', - $this->renderHandleLink($author_phid), - $old, - $new); - } - break; - case self::TYPE_FLAVOR: - if ($old === null) { - return pht( - '%s set the flavor text for this badge.', - $this->renderHandleLink($author_phid)); - } else { - return pht( - '%s updated the flavor text for this badge.', - $this->renderHandleLink($author_phid)); - } - break; - case self::TYPE_DESCRIPTION: - if ($old === null) { - return pht( - '%s set the description for this badge.', - $this->renderHandleLink($author_phid)); - } else { - return pht( - '%s updated the description for this badge.', - $this->renderHandleLink($author_phid)); - } - break; - case self::TYPE_STATUS: - switch ($new) { - case PhabricatorBadgesBadge::STATUS_ACTIVE: - return pht( - '%s activated this badge.', - $this->renderHandleLink($author_phid)); - case PhabricatorBadgesBadge::STATUS_ARCHIVED: - return pht( - '%s archived this badge.', - $this->renderHandleLink($author_phid)); - } - break; - case self::TYPE_ICON: - if ($old === null) { - return pht( - '%s set the icon for this badge as "%s".', - $this->renderHandleLink($author_phid), - $new); - } else { - $set = new PhabricatorBadgesIconSet(); - - $icon_old = $set->getIconLabel($old); - $icon_new = $set->getIconLabel($new); - - return pht( - '%s updated the icon for this badge from "%s" to "%s".', - $this->renderHandleLink($author_phid), - $icon_old, - $icon_new); - } - break; - case self::TYPE_QUALITY: - $qual_new = PhabricatorBadgesQuality::getQualityName($new); - $qual_old = PhabricatorBadgesQuality::getQualityName($old); - if ($old === null) { - return pht( - '%s set the quality for this badge as "%s".', - $this->renderHandleLink($author_phid), - $qual_new); - } else { - return pht( - '%s updated the quality for this badge from "%s" to "%s".', - $this->renderHandleLink($author_phid), - $qual_old, - $qual_new); - } - break; - case self::TYPE_AWARD: - if (!is_array($new)) { - $new = array(); - } - $handles = $this->renderHandleList($new); - return pht( - '%s awarded this badge to %s recipient(s): %s.', - $this->renderHandleLink($author_phid), - new PhutilNumber(count($new)), - $handles); - case self::TYPE_REVOKE: - if (!is_array($new)) { - $new = array(); - } - $handles = $this->renderHandleList($new); - return pht( - '%s revoked this badge from %s recipient(s): %s.', - $this->renderHandleLink($author_phid), - new PhutilNumber(count($new)), - $handles); - } - - 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_NAME: - if ($old === null) { - return pht( - '%s created %s.', - $this->renderHandleLink($author_phid), - $this->renderHandleLink($object_phid)); - - } else { - return pht( - '%s renamed %s.', - $this->renderHandleLink($author_phid), - $this->renderHandleLink($object_phid)); - } - break; - case self::TYPE_FLAVOR: - return pht( - '%s updated the flavor text for %s.', - $this->renderHandleLink($author_phid), - $this->renderHandleLink($object_phid)); - case self::TYPE_ICON: - return pht( - '%s updated the icon for %s.', - $this->renderHandleLink($author_phid), - $this->renderHandleLink($object_phid)); - case self::TYPE_QUALITY: - return pht( - '%s updated the quality level for %s.', - $this->renderHandleLink($author_phid), - $this->renderHandleLink($object_phid)); - case self::TYPE_DESCRIPTION: - return pht( - '%s updated the description for %s.', - $this->renderHandleLink($author_phid), - $this->renderHandleLink($object_phid)); - case self::TYPE_STATUS: - switch ($new) { - case PhabricatorBadgesBadge::STATUS_ACTIVE: - return pht( - '%s activated %s.', - $this->renderHandleLink($author_phid), - $this->renderHandleLink($object_phid)); - case PhabricatorBadgesBadge::STATUS_ARCHIVED: - return pht( - '%s archived %s.', - $this->renderHandleLink($author_phid), - $this->renderHandleLink($object_phid)); - } - break; - case self::TYPE_AWARD: - if (!is_array($new)) { - $new = array(); - } - $handles = $this->renderHandleList($new); - return pht( - '%s awarded %s to %s recipient(s): %s.', - $this->renderHandleLink($author_phid), - $this->renderHandleLink($object_phid), - new PhutilNumber(count($new)), - $handles); - case self::TYPE_REVOKE: - if (!is_array($new)) { - $new = array(); - } - $handles = $this->renderHandleList($new); - return pht( - '%s revoked %s from %s recipient(s): %s.', - $this->renderHandleLink($author_phid), - $this->renderHandleLink($object_phid), - new PhutilNumber(count($new)), - $handles); - } - - return parent::getTitleForFeed(); + public function getBaseTransactionClass() { + return 'PhabricatorBadgesBadgeTransactionType'; } public function getMailTags() { @@ -240,14 +30,16 @@ final class PhabricatorBadgesTransaction case PhabricatorTransactions::TYPE_COMMENT: $tags[] = self::MAILTAG_COMMENT; break; - case self::TYPE_NAME: - case self::TYPE_DESCRIPTION: - case self::TYPE_FLAVOR: - case self::TYPE_ICON: - case self::TYPE_STATUS: - case self::TYPE_QUALITY: + case PhabricatorBadgesBadgeNameTransaction::TRANSACTIONTYPE: + case PhabricatorBadgesBadgeDescriptionTransaction::TRANSACTIONTYPE: + case PhabricatorBadgesBadgeFlavorTransaction::TRANSACTIONTYPE: + case PhabricatorBadgesBadgeIconTransaction::TRANSACTIONTYPE: + case PhabricatorBadgesBadgeStatusTransaction::TRANSACTIONTYPE: + case PhabricatorBadgesBadgeQualityTransaction::TRANSACTIONTYPE: $tags[] = self::MAILTAG_DETAILS; break; + case PhabricatorBadgesBadgeAwardTransaction::TRANSACTIONTYPE: + case PhabricatorBadgesBadgeRevokeTransaction::TRANSACTIONTYPE: default: $tags[] = self::MAILTAG_OTHER; break; @@ -255,49 +47,4 @@ final class PhabricatorBadgesTransaction return $tags; } - - public function shouldHide() { - $old = $this->getOldValue(); - switch ($this->getTransactionType()) { - case self::TYPE_DESCRIPTION: - return ($old === null); - } - return parent::shouldHide(); - } - - 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()); - } - - public function getRequiredHandlePHIDs() { - $phids = parent::getRequiredHandlePHIDs(); - - $type = $this->getTransactionType(); - switch ($type) { - case self::TYPE_AWARD: - case self::TYPE_REVOKE: - $new = $this->getNewValue(); - if (!is_array($new)) { - $new = array(); - } - foreach ($new as $phid) { - $phids[] = $phid; - } - break; - } - - return $phids; - } } diff --git a/src/applications/badges/xaction/PhabricatorBadgesBadgeAwardTransaction.php b/src/applications/badges/xaction/PhabricatorBadgesBadgeAwardTransaction.php new file mode 100644 index 0000000000..5ecacdd441 --- /dev/null +++ b/src/applications/badges/xaction/PhabricatorBadgesBadgeAwardTransaction.php @@ -0,0 +1,90 @@ +getAwards(), 'getRecipientPHID'); + } + + public function applyExternalEffects($object, $value) { + $awards = $object->getAwards(); + $awards = mpull($awards, null, 'getRecipientPHID'); + + foreach ($value as $phid) { + $award = idx($awards, $phid); + if (!$award) { + $award = PhabricatorBadgesAward::initializeNewBadgesAward( + $this->getActor(), + $object, + $phid); + $award->save(); + $awards[] = $award; + } + } + $object->attachAwards($awards); + return; + } + + public function getTitle() { + $new = $this->getNewValue(); + if (!is_array($new)) { + $new = array(); + } + $handles = $this->renderHandleList($new); + return pht( + '%s awarded this badge to %s recipient(s): %s.', + $this->renderAuthor(), + new PhutilNumber(count($new)), + $handles); + } + + public function getTitleForFeed() { + $new = $this->getNewValue(); + if (!is_array($new)) { + $new = array(); + } + $handles = $this->renderHandleList($new); + return pht( + '%s awarded %s to %s recipient(s): %s.', + $this->renderAuthor(), + $this->renderObject(), + new PhutilNumber(count($new)), + $handles); + } + + public function getIcon() { + return 'fa-user-plus'; + } + + public function validateTransactions($object, array $xactions) { + $errors = array(); + + foreach ($xactions as $xaction) { + $user_phids = $xaction->getNewValue(); + if (!$user_phids) { + $errors[] = $this->newRequiredError( + pht('Recipient is required.')); + continue; + } + + foreach ($user_phids as $user_phid) { + $user = id(new PhabricatorPeopleQuery()) + ->setViewer($this->getActor()) + ->withPHIDs(array($user_phid)) + ->executeOne(); + if (!$user) { + $errors[] = $this->newInvalidError( + pht( + 'Recipient PHID "%s" is not a valid user PHID.', + $user_phid)); + } + } + } + + return $errors; + } + +} diff --git a/src/applications/badges/xaction/PhabricatorBadgesBadgeDescriptionTransaction.php b/src/applications/badges/xaction/PhabricatorBadgesBadgeDescriptionTransaction.php new file mode 100644 index 0000000000..0abaafc9c6 --- /dev/null +++ b/src/applications/badges/xaction/PhabricatorBadgesBadgeDescriptionTransaction.php @@ -0,0 +1,57 @@ +getDescription(); + } + + public function applyInternalEffects($object, $value) { + $object->setDescription($value); + } + + public function getTitle() { + return pht( + '%s updated the badge description.', + $this->renderAuthor()); + } + + public function getTitleForFeed() { + return pht( + '%s updated the badge description for %s.', + $this->renderAuthor(), + $this->renderObject()); + } + + public function hasChangeDetailView() { + return true; + } + + public function getMailDiffSectionHeader() { + return pht('CHANGES TO BADGE 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; + } + + +} diff --git a/src/applications/badges/xaction/PhabricatorBadgesBadgeFlavorTransaction.php b/src/applications/badges/xaction/PhabricatorBadgesBadgeFlavorTransaction.php new file mode 100644 index 0000000000..2635aab1a6 --- /dev/null +++ b/src/applications/badges/xaction/PhabricatorBadgesBadgeFlavorTransaction.php @@ -0,0 +1,50 @@ +getFlavor(); + } + + public function applyInternalEffects($object, $value) { + $object->setFlavor($value); + } + + public function getTitle() { + return pht( + '%s updated the flavor from %s to %s.', + $this->renderAuthor(), + $this->renderOldValue(), + $this->renderNewValue()); + } + + public function getTitleForFeed() { + return pht( + '%s updated %s flavor text from %s to %s.', + $this->renderAuthor(), + $this->renderObject(), + $this->renderOldValue(), + $this->renderNewValue()); + } + + public function validateTransactions($object, array $xactions) { + $errors = array(); + + $max_length = $object->getColumnMaximumByteLength('flavor'); + foreach ($xactions as $xaction) { + $new_value = $xaction->getNewValue(); + $new_length = strlen($new_value); + if ($new_length > $max_length) { + $errors[] = $this->newRequiredError( + pht('The flavor text can be no longer than %s characters.', + new PhutilNumber($max_length))); + } + } + + return $errors; + } + +} diff --git a/src/applications/badges/xaction/PhabricatorBadgesBadgeIconTransaction.php b/src/applications/badges/xaction/PhabricatorBadgesBadgeIconTransaction.php new file mode 100644 index 0000000000..7c0f535192 --- /dev/null +++ b/src/applications/badges/xaction/PhabricatorBadgesBadgeIconTransaction.php @@ -0,0 +1,56 @@ +getIcon(); + } + + public function applyInternalEffects($object, $value) { + $object->setIcon($value); + } + + public function shouldHide() { + if ($this->isCreateTransaction()) { + return true; + } + + return false; + } + + public function getTitle() { + $old = $this->getIconLabel($this->getOldValue()); + $new = $this->getIconLabel($this->getNewValue()); + + return pht( + '%s changed the badge icon from %s to %s.', + $this->renderAuthor(), + $this->renderValue($old), + $this->renderValue($new)); + } + + public function getTitleForFeed() { + $old = $this->getIconLabel($this->getOldValue()); + $new = $this->getIconLabel($this->getNewValue()); + + return pht( + '%s changed the badge icon for %s from %s to %s.', + $this->renderAuthor(), + $this->renderObject(), + $this->renderValue($old), + $this->renderValue($new)); + } + + private function getIconLabel($icon) { + $set = new PhabricatorBadgesIconSet(); + return $set->getIconLabel($icon); + } + + public function getIcon() { + return $this->getNewValue(); + } + +} diff --git a/src/applications/badges/xaction/PhabricatorBadgesBadgeNameTransaction.php b/src/applications/badges/xaction/PhabricatorBadgesBadgeNameTransaction.php new file mode 100644 index 0000000000..1df7d89a70 --- /dev/null +++ b/src/applications/badges/xaction/PhabricatorBadgesBadgeNameTransaction.php @@ -0,0 +1,55 @@ +getName(); + } + + public function applyInternalEffects($object, $value) { + $object->setName($value); + } + + public function getTitle() { + return pht( + '%s renamed this badge from %s to %s.', + $this->renderAuthor(), + $this->renderOldValue(), + $this->renderNewValue()); + } + + public function getTitleForFeed() { + return pht( + '%s renamed %s badge %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('Badges 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; + } + +} diff --git a/src/applications/badges/xaction/PhabricatorBadgesBadgeQualityTransaction.php b/src/applications/badges/xaction/PhabricatorBadgesBadgeQualityTransaction.php new file mode 100644 index 0000000000..de060c17e7 --- /dev/null +++ b/src/applications/badges/xaction/PhabricatorBadgesBadgeQualityTransaction.php @@ -0,0 +1,70 @@ +getQuality(); + } + + public function applyInternalEffects($object, $value) { + $object->setQuality($value); + } + + public function shouldHide() { + if ($this->isCreateTransaction()) { + return true; + } + + return false; + } + + public function getTitle() { + $old = $this->getQualityLabel($this->getOldValue()); + $new = $this->getQualityLabel($this->getNewValue()); + + return pht( + '%s updated the quality from %s to %s.', + $this->renderAuthor(), + $old, + $new); + } + + public function getTitleForFeed() { + $old = $this->getQualityLabel($this->getOldValue()); + $new = $this->getQualityLabel($this->getNewValue()); + + return pht( + '%s updated %s quality from %s to %s.', + $this->renderAuthor(), + $this->renderObject(), + $new, + $old); + } + + public function validateTransactions($object, array $xactions) { + $errors = array(); + + if ($this->isEmptyTextTransaction($object->getQuality(), $xactions)) { + $errors[] = $this->newRequiredError( + pht('Badge quality must be set.')); + } + + $map = PhabricatorBadgesQuality::getQualityMap(); + if (!$map[$object->getQuality()]) { + $errors[] = $this->newRequiredError( + pht('Badge quality is not valid.')); + } + + return $errors; + } + + private function getQualityLabel($quality) { + $map = PhabricatorBadgesQuality::getQualityMap(); + $name = $map[$quality]['name']; + return $this->renderValue($name); + } + +} diff --git a/src/applications/badges/xaction/PhabricatorBadgesBadgeRevokeTransaction.php b/src/applications/badges/xaction/PhabricatorBadgesBadgeRevokeTransaction.php new file mode 100644 index 0000000000..a3fa58a060 --- /dev/null +++ b/src/applications/badges/xaction/PhabricatorBadgesBadgeRevokeTransaction.php @@ -0,0 +1,83 @@ +getAwards(); + $awards = mpull($awards, null, 'getRecipientPHID'); + + foreach ($value as $phid) { + $awards[$phid]->delete(); + } + $object->attachAwards($awards); + return; + } + + public function getTitle() { + $new = $this->getNewValue(); + if (!is_array($new)) { + $new = array(); + } + $handles = $this->renderHandleList($new); + return pht( + '%s revoked this badge from %s recipient(s): %s.', + $this->renderAuthor(), + new PhutilNumber(count($new)), + $handles); + } + + public function getTitleForFeed() { + $new = $this->getNewValue(); + if (!is_array($new)) { + $new = array(); + } + $handles = $this->renderHandleList($new); + return pht( + '%s revoked %s from %s recipient(s): %s.', + $this->renderAuthor(), + $this->renderObject(), + new PhutilNumber(count($new)), + $handles); + } + + public function getIcon() { + return 'fa-user-times'; + } + + public function validateTransactions($object, array $xactions) { + $errors = array(); + + foreach ($xactions as $xaction) { + $award_phids = $xaction->getNewValue(); + if (!$award_phids) { + $errors[] = $this->newRequiredError( + pht('Recipient is required.')); + continue; + } + + foreach ($award_phids as $award_phid) { + $award = id(new PhabricatorBadgesAwardQuery()) + ->setViewer($this->getActor()) + ->withRecipientPHIDs(array($award_phid)) + ->withBadgePHIDs(array($object->getPHID())) + ->executeOne(); + if (!$award) { + $errors[] = $this->newInvalidError( + pht( + 'Recipient PHID "%s" has not been awarded.', + $award_phid)); + } + } + } + + return $errors; + } + +} diff --git a/src/applications/badges/xaction/PhabricatorBadgesBadgeStatusTransaction.php b/src/applications/badges/xaction/PhabricatorBadgesBadgeStatusTransaction.php new file mode 100644 index 0000000000..ba5ad4a5c6 --- /dev/null +++ b/src/applications/badges/xaction/PhabricatorBadgesBadgeStatusTransaction.php @@ -0,0 +1,50 @@ +getStatus(); + } + + public function applyInternalEffects($object, $value) { + $object->setStatus($value); + } + + public function getTitle() { + if ($this->getNewValue() == PhabricatorBadgesBadge::STATUS_ARCHIVED) { + return pht( + '%s disabled this badge.', + $this->renderAuthor()); + } else { + return pht( + '%s enabled this badge.', + $this->renderAuthor()); + } + } + + public function getTitleForFeed() { + if ($this->getNewValue() == PhabricatorBadgesBadge::STATUS_ARCHIVED) { + return pht( + '%s disabled the badge %s.', + $this->renderAuthor(), + $this->renderObject()); + } else { + return pht( + '%s enabled the badge %s.', + $this->renderAuthor(), + $this->renderObject()); + } + } + + public function getIcon() { + if ($this->getNewValue() == PhabricatorBadgesBadge::STATUS_ARCHIVED) { + return 'fa-ban'; + } else { + return 'fa-check'; + } + } + +} diff --git a/src/applications/badges/xaction/PhabricatorBadgesBadgeTransactionType.php b/src/applications/badges/xaction/PhabricatorBadgesBadgeTransactionType.php new file mode 100644 index 0000000000..6d47301eeb --- /dev/null +++ b/src/applications/badges/xaction/PhabricatorBadgesBadgeTransactionType.php @@ -0,0 +1,4 @@ +requireViewer(); diff --git a/src/applications/calendar/query/PhabricatorCalendarImportLogSearchEngine.php b/src/applications/calendar/query/PhabricatorCalendarImportLogSearchEngine.php index 81a1256fca..99f292f9a8 100644 --- a/src/applications/calendar/query/PhabricatorCalendarImportLogSearchEngine.php +++ b/src/applications/calendar/query/PhabricatorCalendarImportLogSearchEngine.php @@ -11,6 +11,10 @@ final class PhabricatorCalendarImportLogSearchEngine return 'PhabricatorCalendarApplication'; } + public function canUseInPanelContext() { + return false; + } + public function newQuery() { return new PhabricatorCalendarImportLogQuery(); } diff --git a/src/applications/calendar/query/PhabricatorCalendarImportSearchEngine.php b/src/applications/calendar/query/PhabricatorCalendarImportSearchEngine.php index 75252b6dac..a5e44812ea 100644 --- a/src/applications/calendar/query/PhabricatorCalendarImportSearchEngine.php +++ b/src/applications/calendar/query/PhabricatorCalendarImportSearchEngine.php @@ -11,6 +11,10 @@ final class PhabricatorCalendarImportSearchEngine return 'PhabricatorCalendarApplication'; } + public function canUseInPanelContext() { + return false; + } + public function newQuery() { return new PhabricatorCalendarImportQuery(); } diff --git a/src/applications/calendar/util/CalendarTimeUtil.php b/src/applications/calendar/util/CalendarTimeUtil.php index 6051ade059..781f6adf7a 100644 --- a/src/applications/calendar/util/CalendarTimeUtil.php +++ b/src/applications/calendar/util/CalendarTimeUtil.php @@ -69,7 +69,7 @@ final class CalendarTimeUtil extends Phobject { $today_epoch = PhabricatorTime::parseLocalTime('today', $user); $today = new DateTime('@'.$today_epoch); - $today->setTimeZone($timezone); + $today->setTimezone($timezone); if (strtolower($start_day_str) == 'today' || $today->format('l') == $start_day_str) { @@ -79,7 +79,7 @@ final class CalendarTimeUtil extends Phobject { 'last '.$start_day_str, $user); $start_day = new DateTime('@'.$start_epoch); - $start_day->setTimeZone($timezone); + $start_day->setTimezone($timezone); } return array( 'today' => $today, diff --git a/src/applications/celerity/postprocessor/CelerityDefaultPostprocessor.php b/src/applications/celerity/postprocessor/CelerityDefaultPostprocessor.php index 19a4a363e1..62a4b4fd24 100644 --- a/src/applications/celerity/postprocessor/CelerityDefaultPostprocessor.php +++ b/src/applications/celerity/postprocessor/CelerityDefaultPostprocessor.php @@ -193,10 +193,10 @@ final class CelerityDefaultPostprocessor 'sh-disabledbackground' => '#f3f3f3', // Diffs - 'new-background' => '#eaffea', - 'new-bright' => '#a6f3a6', - 'old-background' => '#ffecec', - 'old-bright' => '#f8cbcb', + 'new-background' => 'rgba(151, 234, 151, .3)', + 'new-bright' => 'rgba(151, 234, 151, .6)', + 'old-background' => 'rgba(251, 175, 175, .3)', + 'old-bright' => 'rgba(251, 175, 175, .7)', 'move-background' => '#fdf5d4', 'copy-background' => '#f1c40f', diff --git a/src/applications/celerity/postprocessor/CelerityRedGreenPostprocessor.php b/src/applications/celerity/postprocessor/CelerityRedGreenPostprocessor.php new file mode 100644 index 0000000000..fc2f9d8e9a --- /dev/null +++ b/src/applications/celerity/postprocessor/CelerityRedGreenPostprocessor.php @@ -0,0 +1,23 @@ + 'rgba(152, 207, 235, .15)', + 'new-bright' => 'rgba(152, 207, 235, .35)', + 'old-background' => 'rgba(250, 212, 175, .3)', + 'old-bright' => 'rgba(250, 212, 175, .55)', + ); + } + +} diff --git a/src/applications/conduit/query/PhabricatorConduitLogSearchEngine.php b/src/applications/conduit/query/PhabricatorConduitLogSearchEngine.php index 68f7060507..20d034168d 100644 --- a/src/applications/conduit/query/PhabricatorConduitLogSearchEngine.php +++ b/src/applications/conduit/query/PhabricatorConduitLogSearchEngine.php @@ -11,6 +11,10 @@ final class PhabricatorConduitLogSearchEngine return 'PhabricatorConduitApplication'; } + public function canUseInPanelContext() { + return false; + } + public function newQuery() { return new PhabricatorConduitLogQuery(); } diff --git a/src/applications/conduit/query/PhabricatorConduitSearchEngine.php b/src/applications/conduit/query/PhabricatorConduitSearchEngine.php index 787c2154d5..9d244401e6 100644 --- a/src/applications/conduit/query/PhabricatorConduitSearchEngine.php +++ b/src/applications/conduit/query/PhabricatorConduitSearchEngine.php @@ -11,6 +11,10 @@ final class PhabricatorConduitSearchEngine return 'PhabricatorConduitApplication'; } + public function canUseInPanelContext() { + return false; + } + public function getPageSize(PhabricatorSavedQuery $saved) { return PHP_INT_MAX - 1; } diff --git a/src/applications/config/check/PhabricatorDaemonsSetupCheck.php b/src/applications/config/check/PhabricatorDaemonsSetupCheck.php index 46ee4efe77..9fc6b587b0 100644 --- a/src/applications/config/check/PhabricatorDaemonsSetupCheck.php +++ b/src/applications/config/check/PhabricatorDaemonsSetupCheck.php @@ -10,7 +10,7 @@ final class PhabricatorDaemonsSetupCheck extends PhabricatorSetupCheck { $task_daemon = id(new PhabricatorDaemonLogQuery()) ->setViewer(PhabricatorUser::getOmnipotentUser()) - ->withStatus(PhabricatorDaemonLogQuery::STATUS_RUNNING) + ->withStatus(PhabricatorDaemonLogQuery::STATUS_ALIVE) ->withDaemonClasses(array('PhabricatorTaskmasterDaemon')) ->setLimit(1) ->execute(); diff --git a/src/applications/conpherence/query/ConpherenceThreadSearchEngine.php b/src/applications/conpherence/query/ConpherenceThreadSearchEngine.php index 3129028c2e..4e0a89d266 100644 --- a/src/applications/conpherence/query/ConpherenceThreadSearchEngine.php +++ b/src/applications/conpherence/query/ConpherenceThreadSearchEngine.php @@ -4,7 +4,7 @@ final class ConpherenceThreadSearchEngine extends PhabricatorApplicationSearchEngine { public function getResultTypeDescription() { - return pht('Rooms'); + return pht('Conpherence Rooms'); } public function getApplicationClassName() { diff --git a/src/applications/daemon/management/PhabricatorDaemonManagementDebugWorkflow.php b/src/applications/daemon/management/PhabricatorDaemonManagementDebugWorkflow.php index e2023ae143..9a535af617 100644 --- a/src/applications/daemon/management/PhabricatorDaemonManagementDebugWorkflow.php +++ b/src/applications/daemon/management/PhabricatorDaemonManagementDebugWorkflow.php @@ -28,10 +28,6 @@ final class PhabricatorDaemonManagementDebugWorkflow 'instead of the configured %s', 'phd.user'), ), - array( - 'name' => 'autoscale', - 'help' => pht('Put the daemon in an autoscale group.'), - ), )); } @@ -44,16 +40,11 @@ final class PhabricatorDaemonManagementDebugWorkflow pht('You must specify which daemon to debug.')); } - $config = array(); - - $config['class'] = array_shift($argv); - $config['argv'] = $argv; - - if ($args->getArg('autoscale')) { - $config['autoscale'] = array( - 'group' => 'debug', - ); - } + $config = array( + 'class' => array_shift($argv), + 'label' => 'debug', + 'argv' => $argv, + ); return $this->launchDaemons( array( diff --git a/src/applications/daemon/management/PhabricatorDaemonManagementRestartWorkflow.php b/src/applications/daemon/management/PhabricatorDaemonManagementRestartWorkflow.php index adb6490f08..3e9f0af8c3 100644 --- a/src/applications/daemon/management/PhabricatorDaemonManagementRestartWorkflow.php +++ b/src/applications/daemon/management/PhabricatorDaemonManagementRestartWorkflow.php @@ -47,7 +47,7 @@ final class PhabricatorDaemonManagementRestartWorkflow return $this->executeStartCommand( array( - 'reserve' => (float)$args->getArg('autoscale-reserve', 0.0), + 'reserve' => (float)$args->getArg('autoscale-reserve'), )); } diff --git a/src/applications/daemon/management/PhabricatorDaemonManagementStartWorkflow.php b/src/applications/daemon/management/PhabricatorDaemonManagementStartWorkflow.php index 9a807357a7..bd23d3bc7d 100644 --- a/src/applications/daemon/management/PhabricatorDaemonManagementStartWorkflow.php +++ b/src/applications/daemon/management/PhabricatorDaemonManagementStartWorkflow.php @@ -34,7 +34,7 @@ final class PhabricatorDaemonManagementStartWorkflow array( 'keep-leases' => $args->getArg('keep-leases'), 'force' => $args->getArg('force'), - 'reserve' => (float)$args->getArg('autoscale-reserve', 0.0), + 'reserve' => (float)$args->getArg('autoscale-reserve'), )); } diff --git a/src/applications/daemon/management/PhabricatorDaemonManagementWorkflow.php b/src/applications/daemon/management/PhabricatorDaemonManagementWorkflow.php index e0218a741d..77f32c293f 100644 --- a/src/applications/daemon/management/PhabricatorDaemonManagementWorkflow.php +++ b/src/applications/daemon/management/PhabricatorDaemonManagementWorkflow.php @@ -362,17 +362,17 @@ abstract class PhabricatorDaemonManagementWorkflow $daemons = array( array( 'class' => 'PhabricatorRepositoryPullLocalDaemon', + 'label' => 'pull', ), array( 'class' => 'PhabricatorTriggerDaemon', + 'label' => 'trigger', ), array( 'class' => 'PhabricatorTaskmasterDaemon', - 'autoscale' => array( - 'group' => 'task', - 'pool' => PhabricatorEnv::getEnvConfig('phd.taskmasters'), - 'reserve' => idx($options, 'reserve', 0), - ), + 'label' => 'task', + 'pool' => PhabricatorEnv::getEnvConfig('phd.taskmasters'), + 'reserve' => idx($options, 'reserve', 0), ), ); @@ -618,23 +618,12 @@ abstract class PhabricatorDaemonManagementWorkflow pht('(Logs will appear in "%s".)', $log_dir)); foreach ($daemons as $daemon) { - $is_autoscale = isset($daemon['autoscale']['group']); - if ($is_autoscale) { - $autoscale = $daemon['autoscale']; - foreach ($autoscale as $key => $value) { - $autoscale[$key] = $key.'='.$value; - } - $autoscale = implode(', ', $autoscale); - - $autoscale = pht('(Autoscaling: %s)', $autoscale); - } else { - $autoscale = pht('(Static)'); - } + $pool_size = pht('(Pool: %s)', idx($daemon, 'pool', 1)); $console->writeOut( " %s %s\n", + $pool_size, $daemon['class'], - $autoscale, implode(' ', idx($daemon, 'argv', array()))); } $console->writeOut("\n"); diff --git a/src/applications/dashboard/controller/PhabricatorDashboardPanelEditController.php b/src/applications/dashboard/controller/PhabricatorDashboardPanelEditController.php index cc7502afef..7aece8c603 100644 --- a/src/applications/dashboard/controller/PhabricatorDashboardPanelEditController.php +++ b/src/applications/dashboard/controller/PhabricatorDashboardPanelEditController.php @@ -193,19 +193,23 @@ final class PhabricatorDashboardPanelEditController ->setLabel(pht('Name')) ->setName('name') ->setValue($v_name) - ->setError($e_name)) - ->appendChild( - id(new AphrontFormPolicyControl()) - ->setName('viewPolicy') - ->setPolicyObject($panel) - ->setCapability(PhabricatorPolicyCapability::CAN_VIEW) - ->setPolicies($policies)) - ->appendChild( - id(new AphrontFormPolicyControl()) - ->setName('editPolicy') - ->setPolicyObject($panel) - ->setCapability(PhabricatorPolicyCapability::CAN_EDIT) - ->setPolicies($policies)); + ->setError($e_name)); + + if (!$request->isAjax() || !$is_create) { + $form + ->appendChild( + id(new AphrontFormPolicyControl()) + ->setName('viewPolicy') + ->setPolicyObject($panel) + ->setCapability(PhabricatorPolicyCapability::CAN_VIEW) + ->setPolicies($policies)) + ->appendChild( + id(new AphrontFormPolicyControl()) + ->setName('editPolicy') + ->setPolicyObject($panel) + ->setCapability(PhabricatorPolicyCapability::CAN_EDIT) + ->setPolicies($policies)); + } $field_list->appendFieldsToForm($form); diff --git a/src/applications/dashboard/query/PhabricatorDashboardPanelSearchEngine.php b/src/applications/dashboard/query/PhabricatorDashboardPanelSearchEngine.php index 89e77997d8..87e908b9c2 100644 --- a/src/applications/dashboard/query/PhabricatorDashboardPanelSearchEngine.php +++ b/src/applications/dashboard/query/PhabricatorDashboardPanelSearchEngine.php @@ -15,6 +15,10 @@ final class PhabricatorDashboardPanelSearchEngine return new PhabricatorDashboardPanelQuery(); } + public function canUseInPanelContext() { + return false; + } + protected function buildQueryFromParameters(array $map) { $query = $this->newQuery(); if ($map['status']) { diff --git a/src/applications/dashboard/query/PhabricatorDashboardSearchEngine.php b/src/applications/dashboard/query/PhabricatorDashboardSearchEngine.php index 6061a0ab8a..a854b066f8 100644 --- a/src/applications/dashboard/query/PhabricatorDashboardSearchEngine.php +++ b/src/applications/dashboard/query/PhabricatorDashboardSearchEngine.php @@ -16,6 +16,10 @@ final class PhabricatorDashboardSearchEngine ->needPanels(true); } + public function canUseInPanelContext() { + return false; + } + protected function buildCustomSearchFields() { return array( id(new PhabricatorSearchTextField()) diff --git a/src/applications/dashboard/storage/PhabricatorDashboard.php b/src/applications/dashboard/storage/PhabricatorDashboard.php index 325e573715..b79fded93f 100644 --- a/src/applications/dashboard/storage/PhabricatorDashboard.php +++ b/src/applications/dashboard/storage/PhabricatorDashboard.php @@ -32,7 +32,7 @@ final class PhabricatorDashboard extends PhabricatorDashboardDAO return id(new PhabricatorDashboard()) ->setName('') ->setIcon('fa-dashboard') - ->setViewPolicy(PhabricatorPolicies::POLICY_USER) + ->setViewPolicy(PhabricatorPolicies::getMostOpenPolicy()) ->setEditPolicy($actor->getPHID()) ->setStatus(self::STATUS_ACTIVE) ->setAuthorPHID($actor->getPHID()) diff --git a/src/applications/dashboard/storage/PhabricatorDashboardPanel.php b/src/applications/dashboard/storage/PhabricatorDashboardPanel.php index 4e82aaa348..9f8875dc1b 100644 --- a/src/applications/dashboard/storage/PhabricatorDashboardPanel.php +++ b/src/applications/dashboard/storage/PhabricatorDashboardPanel.php @@ -27,7 +27,7 @@ final class PhabricatorDashboardPanel return id(new PhabricatorDashboardPanel()) ->setName('') ->setAuthorPHID($actor->getPHID()) - ->setViewPolicy(PhabricatorPolicies::POLICY_USER) + ->setViewPolicy(PhabricatorPolicies::getMostOpenPolicy()) ->setEditPolicy($actor->getPHID()); } diff --git a/src/applications/differential/render/DifferentialChangesetOneUpMailRenderer.php b/src/applications/differential/render/DifferentialChangesetOneUpMailRenderer.php index e720422ecd..ad8939d275 100644 --- a/src/applications/differential/render/DifferentialChangesetOneUpMailRenderer.php +++ b/src/applications/differential/render/DifferentialChangesetOneUpMailRenderer.php @@ -51,6 +51,10 @@ final class DifferentialChangesetOneUpMailRenderer protected function renderPrimitives(array $primitives, $rows) { $out = array(); + $viewer = $this->getUser(); + $old_bright = $viewer->getCSSValue('old-bright'); + $new_bright = $viewer->getCSSValue('new-bright'); + $context_style = array( 'background: #F7F7F7;', 'color: #74777D;', @@ -72,13 +76,13 @@ final class DifferentialChangesetOneUpMailRenderer if ($is_old) { if ($p['htype']) { - $style = 'background: #ffd0d0;'; + $style = "background: {$old_bright};"; } else { $style = null; } } else { if ($p['htype']) { - $style = 'background: #d0ffd0;'; + $style = "background: {$new_bright};"; } else { $style = null; } diff --git a/src/applications/diffusion/conduit/DiffusionBrowseQueryConduitAPIMethod.php b/src/applications/diffusion/conduit/DiffusionBrowseQueryConduitAPIMethod.php index ad5aaeb4eb..7ff0f6725a 100644 --- a/src/applications/diffusion/conduit/DiffusionBrowseQueryConduitAPIMethod.php +++ b/src/applications/diffusion/conduit/DiffusionBrowseQueryConduitAPIMethod.php @@ -52,7 +52,7 @@ final class DiffusionBrowseQueryConduitAPIMethod $commit, $path); } catch (CommandException $e) { - $stderr = $e->getStdErr(); + $stderr = $e->getStderr(); if (preg_match('/^fatal: Not a valid object name/', $stderr)) { // Grab two logs, since the first one is when the object was deleted. list($stdout) = $repository->execxLocalCommand( diff --git a/src/applications/diffusion/controller/DiffusionRepositoryController.php b/src/applications/diffusion/controller/DiffusionRepositoryController.php index ae6a656bd2..a18f2da1d7 100644 --- a/src/applications/diffusion/controller/DiffusionRepositoryController.php +++ b/src/applications/diffusion/controller/DiffusionRepositoryController.php @@ -446,7 +446,7 @@ final class DiffusionRepositoryController extends DiffusionController { $header->setHeader(pht('Branches')); if ($more_branches) { - $header->setSubHeader(pht('Showing %d branches.', $limit)); + $header->setSubheader(pht('Showing %d branches.', $limit)); } $button = new PHUIButtonView(); @@ -505,7 +505,7 @@ final class DiffusionRepositoryController extends DiffusionController { $header->setHeader(pht('Tags')); if ($more_tags) { - $header->setSubHeader( + $header->setSubheader( pht('Showing the %d most recent tags.', $tag_limit)); } diff --git a/src/applications/diffusion/editor/DiffusionCommitEditEngine.php b/src/applications/diffusion/editor/DiffusionCommitEditEngine.php index 28614579a0..3470d02f92 100644 --- a/src/applications/diffusion/editor/DiffusionCommitEditEngine.php +++ b/src/applications/diffusion/editor/DiffusionCommitEditEngine.php @@ -111,7 +111,6 @@ final class DiffusionCommitEditEngine ->setValue($object->getAuditorPHIDsForEdit()); $reason = $data->getCommitDetail('autocloseReason', false); - $reason = PhabricatorRepository::BECAUSE_AUTOCLOSE_FORCED; if ($reason !== false) { switch ($reason) { case PhabricatorRepository::BECAUSE_REPOSITORY_IMPORTING: diff --git a/src/applications/diffusion/herald/DiffusionAuditorsHeraldAction.php b/src/applications/diffusion/herald/DiffusionAuditorsHeraldAction.php index 2ca2ee2b6b..4ec23b1faa 100644 --- a/src/applications/diffusion/herald/DiffusionAuditorsHeraldAction.php +++ b/src/applications/diffusion/herald/DiffusionAuditorsHeraldAction.php @@ -3,6 +3,7 @@ abstract class DiffusionAuditorsHeraldAction extends HeraldAction { + const DO_AUTHORS = 'do.authors'; const DO_ADD_AUDITORS = 'do.add-auditors'; public function getActionGroupKey() { @@ -19,6 +20,22 @@ abstract class DiffusionAuditorsHeraldAction $auditors = $object->getAudits(); + // Don't try to add commit authors as auditors. + $authors = array(); + foreach ($phids as $key => $phid) { + if ($phid == $object->getAuthorPHID()) { + $authors[] = $phid; + unset($phids[$key]); + } + } + + if ($authors) { + $this->logEffect(self::DO_AUTHORS, $authors); + if (!$phids) { + return; + } + } + $current = array(); foreach ($auditors as $auditor) { if ($auditor->isInteresting()) { @@ -53,6 +70,11 @@ abstract class DiffusionAuditorsHeraldAction protected function getActionEffectMap() { return array( + self::DO_AUTHORS => array( + 'icon' => 'fa-user', + 'color' => 'grey', + 'name' => pht('Commit Author'), + ), self::DO_ADD_AUDITORS => array( 'icon' => 'fa-user', 'color' => 'green', @@ -63,6 +85,10 @@ abstract class DiffusionAuditorsHeraldAction protected function renderActionEffectDescription($type, $data) { switch ($type) { + case self::DO_AUTHORS: + return pht( + 'Declined to add commit author as auditor: %s.', + $this->renderHandleList($data)); case self::DO_ADD_AUDITORS: return pht( 'Added %s auditor(s): %s.', diff --git a/src/applications/diffusion/herald/HeraldPreCommitContentAdapter.php b/src/applications/diffusion/herald/HeraldPreCommitContentAdapter.php index 3756651c7e..13c2695fed 100644 --- a/src/applications/diffusion/herald/HeraldPreCommitContentAdapter.php +++ b/src/applications/diffusion/herald/HeraldPreCommitContentAdapter.php @@ -46,7 +46,7 @@ final class HeraldPreCommitContentAdapter extends HeraldPreCommitAdapter { if ($this->changesets instanceof Exception) { $ex_class = get_class($this->changesets); - $ex_message = $this->changesets->getmessage(); + $ex_message = $this->changesets->getMessage(); if ($type === 'name') { return array("<{$ex_class}: {$ex_message}>"); } else { diff --git a/src/applications/diffusion/query/lowlevel/DiffusionLowLevelResolveRefsQuery.php b/src/applications/diffusion/query/lowlevel/DiffusionLowLevelResolveRefsQuery.php index f12dfcf4c0..b649ca65a8 100644 --- a/src/applications/diffusion/query/lowlevel/DiffusionLowLevelResolveRefsQuery.php +++ b/src/applications/diffusion/query/lowlevel/DiffusionLowLevelResolveRefsQuery.php @@ -271,13 +271,13 @@ final class DiffusionLowLevelResolveRefsQuery try { list($stdout) = $future->resolvex(); } catch (CommandException $ex) { - if (preg_match('/ambiguous identifier/', $ex->getStdErr())) { + if (preg_match('/ambiguous identifier/', $ex->getStderr())) { // This indicates that the ref ambiguously matched several things. // Eventually, it would be nice to return all of them, but it is // unclear how to best do that. For now, treat it as a miss instead. continue; } - if (preg_match('/unknown revision/', $ex->getStdErr())) { + if (preg_match('/unknown revision/', $ex->getStderr())) { // No matches for this ref. continue; } diff --git a/src/applications/diffusion/xaction/DiffusionCommitAuditorsTransaction.php b/src/applications/diffusion/xaction/DiffusionCommitAuditorsTransaction.php index a4b1d817b4..a02a34590d 100644 --- a/src/applications/diffusion/xaction/DiffusionCommitAuditorsTransaction.php +++ b/src/applications/diffusion/xaction/DiffusionCommitAuditorsTransaction.php @@ -58,6 +58,31 @@ final class DiffusionCommitAuditorsTransaction return ($old !== $new); } + public function mergeTransactions( + $object, + PhabricatorApplicationTransaction $u, + PhabricatorApplicationTransaction $v) { + + $u_new = $u->getNewValue(); + $v_new = $v->getNewValue(); + + $result = $v_new; + foreach (array('-', '+') as $key) { + $u_value = idx($u_new, $key, array()); + $v_value = idx($v_new, $key, array()); + + $merged = $u_value + $v_value; + + if ($merged) { + $result[$key] = $merged; + } + } + + $u->setNewValue($result); + + return $u; + } + public function applyExternalEffects($object, $value) { $src_phid = $object->getPHID(); diff --git a/src/applications/diviner/atomizer/DivinerPHPAtomizer.php b/src/applications/diviner/atomizer/DivinerPHPAtomizer.php index 201055a15c..0a505a8d6b 100644 --- a/src/applications/diviner/atomizer/DivinerPHPAtomizer.php +++ b/src/applications/diviner/atomizer/DivinerPHPAtomizer.php @@ -128,7 +128,7 @@ final class DivinerPHPAtomizer extends DivinerAtomizer { private function parseParams(DivinerAtom $atom, AASTNode $func) { $params = $func - ->getChildByIndex(3, 'n_DECLARATAION_PARAMETER_LIST') + ->getChildOfType(3, 'n_DECLARATAION_PARAMETER_LIST') ->selectDescendantsOfType('n_DECLARATION_PARAMETER'); $param_spec = array(); diff --git a/src/applications/diviner/query/DivinerAtomSearchEngine.php b/src/applications/diviner/query/DivinerAtomSearchEngine.php index cffdd3592d..35caf20a63 100644 --- a/src/applications/diviner/query/DivinerAtomSearchEngine.php +++ b/src/applications/diviner/query/DivinerAtomSearchEngine.php @@ -10,6 +10,10 @@ final class DivinerAtomSearchEngine extends PhabricatorApplicationSearchEngine { return 'PhabricatorDivinerApplication'; } + public function canUseInPanelContext() { + return false; + } + public function buildSavedQueryFromRequest(AphrontRequest $request) { $saved = new PhabricatorSavedQuery(); diff --git a/src/applications/files/query/PhabricatorFileSearchEngine.php b/src/applications/files/query/PhabricatorFileSearchEngine.php index f2193d3beb..1f2f2de4b3 100644 --- a/src/applications/files/query/PhabricatorFileSearchEngine.php +++ b/src/applications/files/query/PhabricatorFileSearchEngine.php @@ -11,6 +11,10 @@ final class PhabricatorFileSearchEngine return 'PhabricatorFilesApplication'; } + public function canUseInPanelContext() { + return false; + } + public function newQuery() { return new PhabricatorFileQuery(); } diff --git a/src/applications/herald/query/HeraldTranscriptSearchEngine.php b/src/applications/herald/query/HeraldTranscriptSearchEngine.php index cc0d620394..e35620f0da 100644 --- a/src/applications/herald/query/HeraldTranscriptSearchEngine.php +++ b/src/applications/herald/query/HeraldTranscriptSearchEngine.php @@ -11,6 +11,10 @@ final class HeraldTranscriptSearchEngine return 'PhabricatorHeraldApplication'; } + public function canUseInPanelContext() { + return false; + } + public function buildSavedQueryFromRequest(AphrontRequest $request) { $saved = new PhabricatorSavedQuery(); diff --git a/src/applications/maniphest/query/ManiphestTaskSearchEngine.php b/src/applications/maniphest/query/ManiphestTaskSearchEngine.php index 5246f32a0e..d8f5ab493a 100644 --- a/src/applications/maniphest/query/ManiphestTaskSearchEngine.php +++ b/src/applications/maniphest/query/ManiphestTaskSearchEngine.php @@ -31,7 +31,7 @@ final class ManiphestTaskSearchEngine } public function getResultTypeDescription() { - return pht('Tasks'); + return pht('Maniphest Tasks'); } public function getApplicationClassName() { diff --git a/src/applications/metamta/query/PhabricatorMetaMTAMailSearchEngine.php b/src/applications/metamta/query/PhabricatorMetaMTAMailSearchEngine.php index 11ca1116ea..df7774aae2 100644 --- a/src/applications/metamta/query/PhabricatorMetaMTAMailSearchEngine.php +++ b/src/applications/metamta/query/PhabricatorMetaMTAMailSearchEngine.php @@ -11,6 +11,10 @@ final class PhabricatorMetaMTAMailSearchEngine return 'PhabricatorMetaMTAApplication'; } + public function canUseInPanelContext() { + return false; + } + public function newQuery() { return new PhabricatorMetaMTAMailQuery(); } diff --git a/src/applications/metamta/storage/PhabricatorMetaMTAMail.php b/src/applications/metamta/storage/PhabricatorMetaMTAMail.php index 7d8a638401..f2ed8c7721 100644 --- a/src/applications/metamta/storage/PhabricatorMetaMTAMail.php +++ b/src/applications/metamta/storage/PhabricatorMetaMTAMail.php @@ -340,6 +340,9 @@ final class PhabricatorMetaMTAMail return $this->save(); } + /** + * @return this + */ public function save() { if ($this->getID()) { return parent::save(); diff --git a/src/applications/oauthserver/query/PhabricatorOAuthServerClientSearchEngine.php b/src/applications/oauthserver/query/PhabricatorOAuthServerClientSearchEngine.php index 3cb027fe4f..e07b1ea2c2 100644 --- a/src/applications/oauthserver/query/PhabricatorOAuthServerClientSearchEngine.php +++ b/src/applications/oauthserver/query/PhabricatorOAuthServerClientSearchEngine.php @@ -11,6 +11,10 @@ final class PhabricatorOAuthServerClientSearchEngine return 'PhabricatorOAuthServerApplication'; } + public function canUseInPanelContext() { + return false; + } + public function newQuery() { return id(new PhabricatorOAuthServerClientQuery()); } diff --git a/src/applications/owners/query/PhabricatorOwnersPackageSearchEngine.php b/src/applications/owners/query/PhabricatorOwnersPackageSearchEngine.php index 728c3f42a8..d6001419b4 100644 --- a/src/applications/owners/query/PhabricatorOwnersPackageSearchEngine.php +++ b/src/applications/owners/query/PhabricatorOwnersPackageSearchEngine.php @@ -15,6 +15,10 @@ final class PhabricatorOwnersPackageSearchEngine return new PhabricatorOwnersPackageQuery(); } + public function canUseInPanelContext() { + return false; + } + protected function buildCustomSearchFields() { return array( id(new PhabricatorSearchDatasourceField()) diff --git a/src/applications/packages/query/PhabricatorPackagesPackageSearchEngine.php b/src/applications/packages/query/PhabricatorPackagesPackageSearchEngine.php index e01c8db503..817321dec1 100644 --- a/src/applications/packages/query/PhabricatorPackagesPackageSearchEngine.php +++ b/src/applications/packages/query/PhabricatorPackagesPackageSearchEngine.php @@ -15,6 +15,10 @@ final class PhabricatorPackagesPackageSearchEngine return id(new PhabricatorPackagesPackageQuery()); } + public function canUseInPanelContext() { + return false; + } + protected function buildQueryFromParameters(array $map) { $query = $this->newQuery(); diff --git a/src/applications/packages/query/PhabricatorPackagesPublisherSearchEngine.php b/src/applications/packages/query/PhabricatorPackagesPublisherSearchEngine.php index f11738f730..be7b83f5fc 100644 --- a/src/applications/packages/query/PhabricatorPackagesPublisherSearchEngine.php +++ b/src/applications/packages/query/PhabricatorPackagesPublisherSearchEngine.php @@ -15,6 +15,10 @@ final class PhabricatorPackagesPublisherSearchEngine return id(new PhabricatorPackagesPublisherQuery()); } + public function canUseInPanelContext() { + return false; + } + protected function buildQueryFromParameters(array $map) { $query = $this->newQuery(); diff --git a/src/applications/packages/query/PhabricatorPackagesVersionSearchEngine.php b/src/applications/packages/query/PhabricatorPackagesVersionSearchEngine.php index da1581bf80..b3592ffd70 100644 --- a/src/applications/packages/query/PhabricatorPackagesVersionSearchEngine.php +++ b/src/applications/packages/query/PhabricatorPackagesVersionSearchEngine.php @@ -15,6 +15,10 @@ final class PhabricatorPackagesVersionSearchEngine return id(new PhabricatorPackagesVersionQuery()); } + public function canUseInPanelContext() { + return false; + } + protected function buildQueryFromParameters(array $map) { $query = $this->newQuery(); diff --git a/src/applications/people/application/PhabricatorPeopleApplication.php b/src/applications/people/application/PhabricatorPeopleApplication.php index 5278c2e801..d295319b71 100644 --- a/src/applications/people/application/PhabricatorPeopleApplication.php +++ b/src/applications/people/application/PhabricatorPeopleApplication.php @@ -64,6 +64,8 @@ final class PhabricatorPeopleApplication extends PhabricatorApplication { 'ldap/' => 'PhabricatorPeopleLdapController', 'editprofile/(?P[1-9]\d*)/' => 'PhabricatorPeopleProfileEditController', + 'badges/(?P[1-9]\d*)/' => + 'PhabricatorPeopleProfileBadgesController', 'picture/(?P[1-9]\d*)/' => 'PhabricatorPeopleProfilePictureController', 'manage/(?P[1-9]\d*)/' => diff --git a/src/applications/people/controller/PhabricatorPeopleProfileBadgesController.php b/src/applications/people/controller/PhabricatorPeopleProfileBadgesController.php new file mode 100644 index 0000000000..1b22452430 --- /dev/null +++ b/src/applications/people/controller/PhabricatorPeopleProfileBadgesController.php @@ -0,0 +1,137 @@ +getViewer(); + $id = $request->getURIData('id'); + + $user = id(new PhabricatorPeopleQuery()) + ->setViewer($viewer) + ->withIDs(array($id)) + ->needProfile(true) + ->needProfileImage(true) + ->needAvailability(true) + ->needBadges(true) + ->requireCapabilities( + array( + PhabricatorPolicyCapability::CAN_VIEW, + )) + ->executeOne(); + if (!$user) { + return new Aphront404Response(); + } + + $class = 'PhabricatorBadgesApplication'; + if (!PhabricatorApplication::isClassInstalledForViewer($class, $viewer)) { + return new Aphront404Response(); + } + + $this->setUser($user); + $title = array(pht('Badges'), $user->getUsername()); + $header = $this->buildProfileHeader(); + $badges = $this->buildBadgesView($user); + + $crumbs = $this->buildApplicationCrumbs(); + $crumbs->addTextCrumb(pht('Badges')); + $crumbs->setBorder(true); + + $nav = $this->getProfileMenu(); + $nav->selectFilter(PhabricatorPeopleProfileMenuEngine::ITEM_BADGES); + + // Best option? + $badges = id(new PhabricatorBadgesQuery()) + ->setViewer($viewer) + ->withStatuses(array( + PhabricatorBadgesBadge::STATUS_ACTIVE, + )) + ->requireCapabilities( + array( + PhabricatorPolicyCapability::CAN_VIEW, + PhabricatorPolicyCapability::CAN_EDIT, + )) + ->execute(); + + $button = id(new PHUIButtonView()) + ->setTag('a') + ->setIcon('fa-plus') + ->setText(pht('Award Badge')) + ->setWorkflow(true) + ->setHref('/badges/award/'.$user->getID().'/'); + + if (count($badges)) { + $header->addActionLink($button); + } + + $view = id(new PHUITwoColumnView()) + ->setHeader($header) + ->addClass('project-view-home') + ->addClass('project-view-people-home') + ->setFooter(array( + $this->buildBadgesView($user) + )); + + return $this->newPage() + ->setTitle($title) + ->setCrumbs($crumbs) + ->setNavigation($nav) + ->appendChild($view); + } + + private function buildBadgesView(PhabricatorUser $user) { + $viewer = $this->getViewer(); + + $awards = array(); + $badges = array(); + if ($user->getBadgePHIDs()) { + $awards = id(new PhabricatorBadgesAwardQuery()) + ->setViewer($viewer) + ->withRecipientPHIDs(array($user->getPHID())) + ->execute(); + $awards = mpull($awards, null, 'getBadgePHID'); + + $badges = array(); + foreach ($awards as $award) { + $badge = $award->getBadge(); + if ($badge->getStatus() == PhabricatorBadgesBadge::STATUS_ACTIVE) { + $badges[$award->getBadgePHID()] = $badge; + } + } + } + + if (count($badges)) { + $flex = new PHUIBadgeBoxView(); + + foreach ($badges as $badge) { + if ($badge) { + $awarder_info = array(); + + $award = idx($awards, $badge->getPHID(), null); + $awarder_phid = $award->getAwarderPHID(); + $awarder_handle = $viewer->renderHandle($awarder_phid); + + $awarder_info = pht( + 'Awarded by %s', + $awarder_handle->render()); + + $item = id(new PHUIBadgeView()) + ->setIcon($badge->getIcon()) + ->setHeader($badge->getName()) + ->setSubhead($badge->getFlavor()) + ->setQuality($badge->getQuality()) + ->setHref($badge->getViewURI()) + ->addByLine($awarder_info); + + $flex->addItem($item); + } + } + } else { + $flex = id(new PHUIInfoView()) + ->setSeverity(PHUIInfoView::SEVERITY_NOTICE) + ->appendChild(pht('User has not been awarded any badges.')); + } + + return $flex; + } +} diff --git a/src/applications/people/controller/PhabricatorPeopleProfileController.php b/src/applications/people/controller/PhabricatorPeopleProfileController.php index 7393df8455..902b21efcc 100644 --- a/src/applications/people/controller/PhabricatorPeopleProfileController.php +++ b/src/applications/people/controller/PhabricatorPeopleProfileController.php @@ -86,6 +86,9 @@ abstract class PhabricatorPeopleProfileController if ($user->getIsMailingList()) { $roles[] = pht('Mailing List'); } + if (!$user->getIsEmailVerified()) { + $roles[] = pht('Email Not Verified'); + } $tag = null; if ($roles) { @@ -101,10 +104,10 @@ abstract class PhabricatorPeopleProfileController ->setProfileHeader(true) ->addClass('people-profile-header'); + require_celerity_resource('project-view-css'); + if ($user->getIsDisabled()) { $header->setStatus('fa-ban', 'red', pht('Disabled')); - } else if (!$user->getIsEmailVerified()) { - $header->setStatus('fa-envelope', 'red', pht('Email Not Verified')); } else { $header->setStatus($profile_icon, 'bluegrey', $profile_title); } diff --git a/src/applications/people/controller/PhabricatorPeopleProfileManageController.php b/src/applications/people/controller/PhabricatorPeopleProfileManageController.php index 84acfe1af9..2ac3e6de89 100644 --- a/src/applications/people/controller/PhabricatorPeopleProfileManageController.php +++ b/src/applications/people/controller/PhabricatorPeopleProfileManageController.php @@ -39,9 +39,9 @@ final class PhabricatorPeopleProfileManageController $manage = id(new PHUITwoColumnView()) ->setHeader($header) ->addClass('project-view-home') + ->addClass('project-view-people-home') ->setCurtain($curtain) ->addPropertySection(pht('Details'), $properties); - require_celerity_resource('project-view-css'); return $this->newPage() ->setTitle( diff --git a/src/applications/people/controller/PhabricatorPeopleProfilePictureController.php b/src/applications/people/controller/PhabricatorPeopleProfilePictureController.php index 226646bc70..2c9a4bf10c 100644 --- a/src/applications/people/controller/PhabricatorPeopleProfilePictureController.php +++ b/src/applications/people/controller/PhabricatorPeopleProfilePictureController.php @@ -258,12 +258,12 @@ final class PhabricatorPeopleProfilePictureController $nav = $this->getProfileMenu(); $nav->selectFilter(PhabricatorPeopleProfileMenuEngine::ITEM_MANAGE); - $header = id(new PHUIHeaderView()) - ->setHeader(pht('Edit Profile Picture')) - ->setHeaderIcon('fa-camera'); + $header = $this->buildProfileHeader(); $view = id(new PHUITwoColumnView()) ->setHeader($header) + ->addClass('project-view-home') + ->addClass('project-view-people-home') ->setFooter(array( $form_box, $upload_box, diff --git a/src/applications/people/controller/PhabricatorPeopleProfileViewController.php b/src/applications/people/controller/PhabricatorPeopleProfileViewController.php index 889ecd2969..9db106081d 100644 --- a/src/applications/people/controller/PhabricatorPeopleProfileViewController.php +++ b/src/applications/people/controller/PhabricatorPeopleProfileViewController.php @@ -14,7 +14,6 @@ final class PhabricatorPeopleProfileViewController $user = id(new PhabricatorPeopleQuery()) ->setViewer($viewer) ->withUsernames(array($username)) - ->needBadges(true) ->needProfileImage(true) ->needAvailability(true) ->executeOne(); @@ -36,8 +35,6 @@ final class PhabricatorPeopleProfileViewController $projects = $this->buildProjectsView($user); $calendar = $this->buildCalendarDayView($user); - $badges = $this->buildBadgesView($user); - require_celerity_resource('project-view-css'); $home = id(new PHUITwoColumnView()) ->setHeader($header) @@ -52,7 +49,6 @@ final class PhabricatorPeopleProfileViewController array( $projects, $calendar, - $badges, )); $nav = $this->getProfileMenu(); @@ -228,106 +224,6 @@ final class PhabricatorPeopleProfileViewController return $box; } - private function buildBadgesView(PhabricatorUser $user) { - - $viewer = $this->getViewer(); - $class = 'PhabricatorBadgesApplication'; - - if (!PhabricatorApplication::isClassInstalledForViewer($class, $viewer)) { - return null; - } - - $awards = array(); - $badges = array(); - if ($user->getBadgePHIDs()) { - $awards = id(new PhabricatorBadgesAwardQuery()) - ->setViewer($viewer) - ->withRecipientPHIDs(array($user->getPHID())) - ->execute(); - $awards = mpull($awards, null, 'getBadgePHID'); - - $badges = array(); - foreach ($awards as $award) { - $badge = $award->getBadge(); - if ($badge->getStatus() == PhabricatorBadgesBadge::STATUS_ACTIVE) { - $badges[$award->getBadgePHID()] = $badge; - } - } - } - - if (count($badges)) { - $flex = new PHUIBadgeBoxView(); - - foreach ($badges as $badge) { - if ($badge) { - $awarder_info = array(); - - $award = idx($awards, $badge->getPHID(), null); - $awarder_phid = $award->getAwarderPHID(); - $awarder_handle = $viewer->renderHandle($awarder_phid); - - $awarder_info = pht( - 'Awarded by %s', - $awarder_handle->render()); - - $item = id(new PHUIBadgeView()) - ->setIcon($badge->getIcon()) - ->setHeader($badge->getName()) - ->setSubhead($badge->getFlavor()) - ->setQuality($badge->getQuality()) - ->setHref($badge->getViewURI()) - ->addByLine($awarder_info); - - $flex->addItem($item); - } - } - } else { - $flex = id(new PHUIInfoView()) - ->setSeverity(PHUIInfoView::SEVERITY_NODATA) - ->appendChild(pht('User does not have any badges.')); - } - - // Best option? - $badges = id(new PhabricatorBadgesQuery()) - ->setViewer($viewer) - ->withStatuses(array( - PhabricatorBadgesBadge::STATUS_ACTIVE, - )) - ->requireCapabilities( - array( - PhabricatorPolicyCapability::CAN_VIEW, - PhabricatorPolicyCapability::CAN_EDIT, - )) - ->execute(); - - $button = id(new PHUIButtonView()) - ->setTag('a') - ->setIcon('fa-plus') - ->setText(pht('Award')) - ->setWorkflow(true) - ->setHref('/badges/award/'.$user->getID().'/'); - - $can_award = false; - if (count($badges)) { - $can_award = true; - } - - $header = id(new PHUIHeaderView()) - ->setHeader(pht('Badges')); - - if (count($badges)) { - $header->addActionLink($button); - } - - $box = id(new PHUIObjectBoxView()) - ->setHeader($header) - ->addClass('project-view-badges') - ->appendChild($flex) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY); - - return $box; - } - private function buildPeopleFeed( PhabricatorUser $user, $viewer) { diff --git a/src/applications/people/engine/PhabricatorPeopleProfileMenuEngine.php b/src/applications/people/engine/PhabricatorPeopleProfileMenuEngine.php index 2fd2ec3bd2..9e4bbba874 100644 --- a/src/applications/people/engine/PhabricatorPeopleProfileMenuEngine.php +++ b/src/applications/people/engine/PhabricatorPeopleProfileMenuEngine.php @@ -6,6 +6,7 @@ final class PhabricatorPeopleProfileMenuEngine const ITEM_PROFILE = 'people.profile'; const ITEM_MANAGE = 'people.manage'; const ITEM_PICTURE = 'people.picture'; + const ITEM_BADGES = 'people.badges'; protected function isMenuEngineConfigurable() { return false; @@ -31,6 +32,15 @@ final class PhabricatorPeopleProfileMenuEngine ->setBuiltinKey(self::ITEM_PROFILE) ->setMenuItemKey(PhabricatorPeopleDetailsProfileMenuItem::MENUITEMKEY); + $have_badges = PhabricatorApplication::isClassInstalledForViewer( + 'PhabricatorBadgesApplication', + $viewer); + if ($have_badges) { + $items[] = $this->newItem() + ->setBuiltinKey(self::ITEM_BADGES) + ->setMenuItemKey(PhabricatorPeopleBadgesProfileMenuItem::MENUITEMKEY); + } + $have_maniphest = PhabricatorApplication::isClassInstalledForViewer( 'PhabricatorManiphestApplication', $viewer); diff --git a/src/applications/people/engineextension/PeopleHovercardEngineExtension.php b/src/applications/people/engineextension/PeopleHovercardEngineExtension.php index 22d63eda8a..507715d21a 100644 --- a/src/applications/people/engineextension/PeopleHovercardEngineExtension.php +++ b/src/applications/people/engineextension/PeopleHovercardEngineExtension.php @@ -27,7 +27,6 @@ final class PeopleHovercardEngineExtension ->needAvailability(true) ->needProfileImage(true) ->needProfile(true) - ->needBadges(true) ->execute(); $users = mpull($users, null, 'getPHID'); diff --git a/src/applications/people/menuitem/PhabricatorPeopleBadgesProfileMenuItem.php b/src/applications/people/menuitem/PhabricatorPeopleBadgesProfileMenuItem.php new file mode 100644 index 0000000000..0e4da29b61 --- /dev/null +++ b/src/applications/people/menuitem/PhabricatorPeopleBadgesProfileMenuItem.php @@ -0,0 +1,59 @@ +getMenuItemProperty('name'); + + if (strlen($name)) { + return $name; + } + + return $this->getDefaultName(); + } + + public function buildEditEngineFields( + PhabricatorProfileMenuItemConfiguration $config) { + return array( + id(new PhabricatorTextEditField()) + ->setKey('name') + ->setLabel(pht('Name')) + ->setPlaceholder($this->getDefaultName()) + ->setValue($config->getMenuItemProperty('name')), + ); + } + + protected function newNavigationMenuItems( + PhabricatorProfileMenuItemConfiguration $config) { + + $user = $config->getProfileObject(); + $id = $user->getID(); + + $item = $this->newItem() + ->setHref("/people/badges/{$id}/") + ->setName($this->getDisplayName($config)) + ->setIcon('fa-trophy'); + + return array( + $item, + ); + } + +} diff --git a/src/applications/people/menuitem/PhabricatorPeoplePictureProfileMenuItem.php b/src/applications/people/menuitem/PhabricatorPeoplePictureProfileMenuItem.php index 89fb7b9681..938b7cf60a 100644 --- a/src/applications/people/menuitem/PhabricatorPeoplePictureProfileMenuItem.php +++ b/src/applications/people/menuitem/PhabricatorPeoplePictureProfileMenuItem.php @@ -36,6 +36,13 @@ final class PhabricatorPeoplePictureProfileMenuItem $picture = $user->getProfileImageURI(); $name = $user->getUsername(); + + $classes = array(); + $classes[] = 'people-menu-image'; + if ($user->getIsDisabled()) { + $classes[] = 'phui-image-disabled'; + } + $href = urisprintf( '/p/%s/', $user->getUsername()); @@ -44,7 +51,7 @@ final class PhabricatorPeoplePictureProfileMenuItem 'img', array( 'src' => $picture, - 'class' => 'people-menu-image', + 'class' => implode(' ', $classes), )); $can_edit = PhabricatorPolicyFilter::hasCapability( diff --git a/src/applications/people/storage/PhabricatorUser.php b/src/applications/people/storage/PhabricatorUser.php index 813d11c868..f2ebd76210 100644 --- a/src/applications/people/storage/PhabricatorUser.php +++ b/src/applications/people/storage/PhabricatorUser.php @@ -1580,4 +1580,22 @@ final class PhabricatorUser return $this; } + + public function getCSSValue($variable_key) { + $preference = PhabricatorAccessibilitySetting::SETTINGKEY; + $key = $this->getUserSetting($preference); + + $postprocessor = CelerityPostprocessor::getPostprocessor($key); + $variables = $postprocessor->getVariables(); + + if (!isset($variables[$variable_key])) { + throw new Exception( + pht( + 'Unknown CSS variable "%s"!', + $variable_key)); + } + + return $variables[$variable_key]; + } + } diff --git a/src/applications/people/view/PhabricatorUserCardView.php b/src/applications/people/view/PhabricatorUserCardView.php index bb0ab9eebc..4c45549b77 100644 --- a/src/applications/people/view/PhabricatorUserCardView.php +++ b/src/applications/people/view/PhabricatorUserCardView.php @@ -33,9 +33,7 @@ final class PhabricatorUserCardView extends AphrontTagView { $classes[] = 'project-card-view'; if ($this->profile->getIsDisabled()) { - $classes[] = 'project-card-grey'; - } else { - $classes[] = 'project-card-blue'; + $classes[] = 'project-card-disabled'; } return array( @@ -56,10 +54,12 @@ final class PhabricatorUserCardView extends AphrontTagView { // the most important tag. Users can click through to the profile to get // more details. + $classes = array(); if ($user->getIsDisabled()) { $tag_icon = 'fa-ban'; $tag_title = pht('Disabled'); $tag_shade = PHUITagView::COLOR_RED; + $classes[] = 'phui-image-disabled'; } else if (!$user->getIsApproved()) { $tag_icon = 'fa-ban'; $tag_title = pht('Unapproved Account'); @@ -87,47 +87,60 @@ final class PhabricatorUserCardView extends AphrontTagView { $tag->setShade($tag_shade); } - $header = id(new PHUIHeaderView()) - ->setHeader($user->getFullName()) - ->addTag($tag) - ->setUser($viewer) - ->setImage($picture); - $body = array(); + /* TODO: Replace with Conpherence Availability if we ship it */ $body[] = $this->addItem( - pht('User Since'), + 'fa-user-plus', phabricator_date($user->getDateCreated(), $viewer)); if (PhabricatorApplication::isClassInstalledForViewer( 'PhabricatorCalendarApplication', $viewer)) { $body[] = $this->addItem( - pht('Availability'), + 'fa-calendar-o', id(new PHUIUserAvailabilityView()) ->setViewer($viewer) ->setAvailableUser($user)); } - $badges = $this->buildBadges($user, $viewer); - if ($badges) { - $badges = id(new PHUIBadgeBoxView()) - ->addItems($badges) - ->setCollapsed(true); - $body[] = phutil_tag( - 'div', - array( - 'class' => 'phui-hovercard-body-item hovercard-badges', - ), - $badges); - } + $classes[] = 'project-card-image'; + $image = phutil_tag( + 'img', + array( + 'src' => $picture, + 'class' => implode(' ', $classes), + )); - $body = phutil_tag( + $href = urisprintf( + '/p/%s/', + $user->getUsername()); + + $image = phutil_tag( + 'a', + array( + 'href' => $href, + ), + $image); + + $name = phutil_tag_div('project-card-name', + $user->getRealname()); + $username = phutil_tag_div('project-card-username', + '@'.$user->getUsername()); + $tag = phutil_tag_div('phui-header-subheader', + $tag); + + $header = phutil_tag( 'div', array( - 'class' => 'project-card-body', + 'class' => 'project-card-header', ), - $body); + array( + $name, + $username, + $tag, + $body, + )); $card = phutil_tag( 'div', @@ -135,47 +148,24 @@ final class PhabricatorUserCardView extends AphrontTagView { 'class' => 'project-card-inner', ), array( + $image, $header, - $body, )); return $card; } - private function addItem($label, $value) { - $item = array( - phutil_tag('strong', array(), $label), - ': ', - phutil_tag('span', array(), $value), - ); - return phutil_tag_div('project-card-item', $item); - } - - private function buildBadges( - PhabricatorUser $user, - $viewer) { - - $class = 'PhabricatorBadgesApplication'; - $items = array(); - - if (PhabricatorApplication::isClassInstalledForViewer($class, $viewer)) { - $badge_phids = $user->getBadgePHIDs(); - if ($badge_phids) { - $badges = id(new PhabricatorBadgesQuery()) - ->setViewer($viewer) - ->withPHIDs($badge_phids) - ->withStatuses(array(PhabricatorBadgesBadge::STATUS_ACTIVE)) - ->execute(); - - foreach ($badges as $badge) { - $items[] = id(new PHUIBadgeMiniView()) - ->setIcon($badge->getIcon()) - ->setHeader($badge->getName()) - ->setQuality($badge->getQuality()); - } - } - } - return $items; + private function addItem($icon, $value) { + $icon = id(new PHUIIconView()) + ->addClass('project-card-item-icon') + ->setIcon($icon); + $text = phutil_tag( + 'span', + array( + 'class' => 'project-card-item-text', + ), + $value); + return phutil_tag_div('project-card-item', array($icon, $text)); } } diff --git a/src/applications/phortune/management/PhabricatorPhortuneManagementInvoiceWorkflow.php b/src/applications/phortune/management/PhabricatorPhortuneManagementInvoiceWorkflow.php index 673bf812d7..d1fce6dae0 100644 --- a/src/applications/phortune/management/PhabricatorPhortuneManagementInvoiceWorkflow.php +++ b/src/applications/phortune/management/PhabricatorPhortuneManagementInvoiceWorkflow.php @@ -86,7 +86,7 @@ final class PhabricatorPhortuneManagementInvoiceWorkflow $auto_range = $args->getArg('auto-range'); $last_arg = $args->getArg('last'); - $next_arg = $args->getARg('next'); + $next_arg = $args->getArg('next'); if (!$auto_range && !$last_arg && !$next_arg) { throw new PhutilArgumentUsageException( diff --git a/src/applications/phrequent/query/PhrequentSearchEngine.php b/src/applications/phrequent/query/PhrequentSearchEngine.php index d137c40b64..46f7ae769c 100644 --- a/src/applications/phrequent/query/PhrequentSearchEngine.php +++ b/src/applications/phrequent/query/PhrequentSearchEngine.php @@ -10,6 +10,11 @@ final class PhrequentSearchEngine extends PhabricatorApplicationSearchEngine { return 'PhabricatorPhrequentApplication'; } + public function canUseInPanelContext() { + return false; + } + + public function getPageSize(PhabricatorSavedQuery $saved) { return $saved->getParameter('limit', 1000); } diff --git a/src/applications/phurl/editor/PhabricatorPhurlURLEditEngine.php b/src/applications/phurl/editor/PhabricatorPhurlURLEditEngine.php index 3efabcceee..12a4d2672f 100644 --- a/src/applications/phurl/editor/PhabricatorPhurlURLEditEngine.php +++ b/src/applications/phurl/editor/PhabricatorPhurlURLEditEngine.php @@ -21,6 +21,10 @@ final class PhabricatorPhurlURLEditEngine return pht('Configure creation and editing forms in Phurl.'); } + public function isEngineConfigurable() { + return false; + } + protected function newEditableObject() { return PhabricatorPhurlURL::initializeNewPhurlURL($this->getViewer()); } @@ -73,8 +77,10 @@ final class PhabricatorPhurlURLEditEngine ->setKey('name') ->setLabel(pht('Name')) ->setDescription(pht('URL name.')) + ->setIsRequired(true) ->setConduitTypeDescription(pht('New URL name.')) - ->setTransactionType(PhabricatorPhurlURLTransaction::TYPE_NAME) + ->setTransactionType( + PhabricatorPhurlURLNameTransaction::TRANSACTIONTYPE) ->setValue($object->getName()), id(new PhabricatorTextEditField()) ->setKey('url') @@ -83,11 +89,14 @@ final class PhabricatorPhurlURLEditEngine ->setConduitTypeDescription(pht('New URL.')) ->setValue($object->getLongURL()) ->setIsRequired(true) - ->setTransactionType(PhabricatorPhurlURLTransaction::TYPE_URL), + ->setTransactionType( + PhabricatorPhurlURLLongURLTransaction::TRANSACTIONTYPE), id(new PhabricatorTextEditField()) ->setKey('alias') ->setLabel(pht('Alias')) - ->setTransactionType(PhabricatorPhurlURLTransaction::TYPE_ALIAS) + ->setIsRequired(true) + ->setTransactionType( + PhabricatorPhurlURLAliasTransaction::TRANSACTIONTYPE) ->setDescription(pht('The alias to give the URL.')) ->setConduitTypeDescription(pht('New alias.')) ->setValue($object->getAlias()), @@ -96,7 +105,8 @@ final class PhabricatorPhurlURLEditEngine ->setLabel(pht('Description')) ->setDescription(pht('URL long description.')) ->setConduitTypeDescription(pht('New URL description.')) - ->setTransactionType(PhabricatorPhurlURLTransaction::TYPE_DESCRIPTION) + ->setTransactionType( + PhabricatorPhurlURLDescriptionTransaction::TRANSACTIONTYPE) ->setValue($object->getDescription()), ); } diff --git a/src/applications/phurl/editor/PhabricatorPhurlURLEditor.php b/src/applications/phurl/editor/PhabricatorPhurlURLEditor.php index 2b6290851b..439d62f84a 100644 --- a/src/applications/phurl/editor/PhabricatorPhurlURLEditor.php +++ b/src/applications/phurl/editor/PhabricatorPhurlURLEditor.php @@ -11,14 +11,20 @@ final class PhabricatorPhurlURLEditor return pht('Phurl'); } + public function getCreateObjectTitle($author, $object) { + return pht('%s created this URL.', $author); + } + + public function getCreateObjectTitleForFeed($author, $object) { + return pht('%s created %s.', $author, $object); + } + + protected function supportsSearch() { + return true; + } + public function getTransactionTypes() { $types = parent::getTransactionTypes(); - - $types[] = PhabricatorPhurlURLTransaction::TYPE_NAME; - $types[] = PhabricatorPhurlURLTransaction::TYPE_URL; - $types[] = PhabricatorPhurlURLTransaction::TYPE_ALIAS; - $types[] = PhabricatorPhurlURLTransaction::TYPE_DESCRIPTION; - $types[] = PhabricatorTransactions::TYPE_COMMENT; $types[] = PhabricatorTransactions::TYPE_VIEW_POLICY; $types[] = PhabricatorTransactions::TYPE_EDIT_POLICY; @@ -26,160 +32,18 @@ final class PhabricatorPhurlURLEditor return $types; } - protected function getCustomTransactionOldValue( + protected function shouldSendMail( PhabricatorLiskDAO $object, - PhabricatorApplicationTransaction $xaction) { - switch ($xaction->getTransactionType()) { - case PhabricatorPhurlURLTransaction::TYPE_NAME: - return $object->getName(); - case PhabricatorPhurlURLTransaction::TYPE_URL: - return $object->getLongURL(); - case PhabricatorPhurlURLTransaction::TYPE_ALIAS: - return $object->getAlias(); - case PhabricatorPhurlURLTransaction::TYPE_DESCRIPTION: - return $object->getDescription(); - } - - return parent::getCustomTransactionOldValue($object, $xaction); - } - - protected function getCustomTransactionNewValue( - PhabricatorLiskDAO $object, - PhabricatorApplicationTransaction $xaction) { - switch ($xaction->getTransactionType()) { - case PhabricatorPhurlURLTransaction::TYPE_NAME: - case PhabricatorPhurlURLTransaction::TYPE_URL: - case PhabricatorPhurlURLTransaction::TYPE_DESCRIPTION: - return $xaction->getNewValue(); - case PhabricatorPhurlURLTransaction::TYPE_ALIAS: - if (!strlen($xaction->getNewValue())) { - return null; - } - return $xaction->getNewValue(); - } - - return parent::getCustomTransactionNewValue($object, $xaction); - } - - protected function applyCustomInternalTransaction( - PhabricatorLiskDAO $object, - PhabricatorApplicationTransaction $xaction) { - - switch ($xaction->getTransactionType()) { - case PhabricatorPhurlURLTransaction::TYPE_NAME: - $object->setName($xaction->getNewValue()); - return; - case PhabricatorPhurlURLTransaction::TYPE_URL: - $object->setLongURL($xaction->getNewValue()); - return; - case PhabricatorPhurlURLTransaction::TYPE_ALIAS: - $object->setAlias($xaction->getNewValue()); - return; - case PhabricatorPhurlURLTransaction::TYPE_DESCRIPTION: - $object->setDescription($xaction->getNewValue()); - return; - } - - return parent::applyCustomInternalTransaction($object, $xaction); - } - - protected function applyCustomExternalTransaction( - PhabricatorLiskDAO $object, - PhabricatorApplicationTransaction $xaction) { - - switch ($xaction->getTransactionType()) { - case PhabricatorPhurlURLTransaction::TYPE_NAME: - case PhabricatorPhurlURLTransaction::TYPE_URL: - case PhabricatorPhurlURLTransaction::TYPE_ALIAS: - case PhabricatorPhurlURLTransaction::TYPE_DESCRIPTION: - return; - } - - return parent::applyCustomExternalTransaction($object, $xaction); - } - - protected function validateTransaction( - PhabricatorLiskDAO $object, - $type, array $xactions) { + return true; + } - $errors = parent::validateTransaction($object, $type, $xactions); - - switch ($type) { - case PhabricatorPhurlURLTransaction::TYPE_ALIAS: - $overdrawn = $this->validateIsTextFieldTooLong( - $object->getName(), - $xactions, - 64); - - if ($overdrawn) { - $errors[] = new PhabricatorApplicationTransactionValidationError( - $type, - pht('Alias Too Long'), - pht('The alias can be no longer than 64 characters.'), - nonempty(last($xactions), null)); - } - - foreach ($xactions as $xaction) { - if ($xaction->getOldValue() != $xaction->getNewValue()) { - $new_alias = $xaction->getNewValue(); - $debug_alias = new PHUIInvisibleCharacterView($new_alias); - if (!preg_match('/[a-zA-Z]/', $new_alias)) { - $errors[] = new PhabricatorApplicationTransactionValidationError( - $type, - pht('Invalid Alias'), - pht('The alias you provided (%s) must contain at least one '. - 'letter.', - $debug_alias), - $xaction); - } - if (preg_match('/[^a-z0-9]/i', $new_alias)) { - $errors[] = new PhabricatorApplicationTransactionValidationError( - $type, - pht('Invalid Alias'), - pht('The alias you provided (%s) may only contain letters and '. - 'numbers.', - $debug_alias), - $xaction); - } - } - } - - break; - case PhabricatorPhurlURLTransaction::TYPE_URL: - $missing = $this->validateIsEmptyTextField( - $object->getLongURL(), - $xactions); - - if ($missing) { - $error = new PhabricatorApplicationTransactionValidationError( - $type, - pht('Required'), - pht('URL path is required.'), - nonempty(last($xactions), null)); - - $error->setIsMissingFieldError(true); - $errors[] = $error; - } - - foreach ($xactions as $xaction) { - if ($xaction->getOldValue() != $xaction->getNewValue()) { - $protocols = PhabricatorEnv::getEnvConfig('uri.allowed-protocols'); - $uri = new PhutilURI($xaction->getNewValue()); - if (!isset($protocols[$uri->getProtocol()])) { - $errors[] = new PhabricatorApplicationTransactionValidationError( - $type, - pht('Invalid URL'), - pht('The protocol of the URL is invalid.'), - null); - } - } - } - - break; - } - - return $errors; + public function getMailTagsMap() { + return array( + PhabricatorPhurlURLTransaction::MAILTAG_DETAILS => + pht( + "A URL's details change."), + ); } protected function shouldPublishFeedStory( @@ -188,36 +52,17 @@ final class PhabricatorPhurlURLEditor return true; } - protected function supportsSearch() { - return true; - } - - protected function shouldSendMail( - PhabricatorLiskDAO $object, - array $xactions) { - return true; - } - protected function getMailSubjectPrefix() { return pht('[Phurl]'); } protected function getMailTo(PhabricatorLiskDAO $object) { $phids = array(); - $phids[] = $this->getActingAsPHID(); return $phids; } - public function getMailTagsMap() { - return array( - PhabricatorPhurlURLTransaction::MAILTAG_DETAILS => - pht( - "A URL's details change."), - ); - } - protected function buildMailTemplate(PhabricatorLiskDAO $object) { $id = $object->getID(); $name = $object->getName(); @@ -255,7 +100,7 @@ final class PhabricatorPhurlURLEditor $errors = array(); $errors[] = new PhabricatorApplicationTransactionValidationError( - PhabricatorPhurlURLTransaction::TYPE_ALIAS, + PhabricatorPhurlURLAliasTransaction::TRANSACTIONTYPE, pht('Duplicate'), pht('This alias is already in use.'), null); diff --git a/src/applications/phurl/query/PhabricatorPhurlURLSearchEngine.php b/src/applications/phurl/query/PhabricatorPhurlURLSearchEngine.php index f2e2c99399..8814b25b9c 100644 --- a/src/applications/phurl/query/PhabricatorPhurlURLSearchEngine.php +++ b/src/applications/phurl/query/PhabricatorPhurlURLSearchEngine.php @@ -4,7 +4,7 @@ final class PhabricatorPhurlURLSearchEngine extends PhabricatorApplicationSearchEngine { public function getResultTypeDescription() { - return pht('Shortened URLs'); + return pht('Phurl URLs'); } public function getApplicationClassName() { diff --git a/src/applications/phurl/storage/PhabricatorPhurlURLTransaction.php b/src/applications/phurl/storage/PhabricatorPhurlURLTransaction.php index d520b30518..cc2f2a8672 100644 --- a/src/applications/phurl/storage/PhabricatorPhurlURLTransaction.php +++ b/src/applications/phurl/storage/PhabricatorPhurlURLTransaction.php @@ -1,12 +1,7 @@ getTransactionType()) { - case self::TYPE_NAME: - case self::TYPE_URL: - case self::TYPE_ALIAS: - case self::TYPE_DESCRIPTION: + case PhabricatorPhurlURLNameTransaction::TRANSACTIONTYPE: + case PhabricatorPhurlURLLongURLTransaction::TRANSACTIONTYPE: + case PhabricatorPhurlURLAliasTransaction::TRANSACTIONTYPE: + case PhabricatorPhurlURLDescriptionTransaction::TRANSACTIONTYPE: $phids[] = $this->getObjectPHID(); break; } @@ -37,203 +36,13 @@ final class PhabricatorPhurlURLTransaction return $phids; } - public function shouldHide() { - $old = $this->getOldValue(); - switch ($this->getTransactionType()) { - case self::TYPE_DESCRIPTION: - return ($old === null); - } - return parent::shouldHide(); - } - - public function getIcon() { - switch ($this->getTransactionType()) { - case self::TYPE_NAME: - case self::TYPE_URL: - case self::TYPE_ALIAS: - case self::TYPE_DESCRIPTION: - return 'fa-pencil'; - break; - } - return parent::getIcon(); - } - - public function getTitle() { - $author_phid = $this->getAuthorPHID(); - $object_phid = $this->getObjectPHID(); - - $old = $this->getOldValue(); - $new = $this->getNewValue(); - - $type = $this->getTransactionType(); - switch ($type) { - case self::TYPE_NAME: - if ($old === null) { - return pht( - '%s created this URL.', - $this->renderHandleLink($author_phid)); - } else { - return pht( - '%s changed the name of the URL from %s to %s.', - $this->renderHandleLink($author_phid), - $old, - $new); - } - case self::TYPE_URL: - if ($old === null) { - return pht( - '%s set the destination of the URL to %s.', - $this->renderHandleLink($author_phid), - $new); - } else { - return pht( - '%s changed the destination of the URL from %s to %s.', - $this->renderHandleLink($author_phid), - $old, - $new); - } - case self::TYPE_ALIAS: - if ($old === null) { - return pht( - '%s set the alias of the URL to %s.', - $this->renderHandleLink($author_phid), - $new); - } else if ($new === null) { - return pht( - '%s removed the alias of the URL.', - $this->renderHandleLink($author_phid)); - } else { - return pht( - '%s changed the alias of the URL from %s to %s.', - $this->renderHandleLink($author_phid), - $old, - $new); - } - case self::TYPE_DESCRIPTION: - return pht( - "%s updated the URL's description.", - $this->renderHandleLink($author_phid)); - } - return parent::getTitle(); - } - - public function getTitleForFeed() { - $author_phid = $this->getAuthorPHID(); - $object_phid = $this->getObjectPHID(); - - $old = $this->getOldValue(); - $new = $this->getNewValue(); - - $viewer = $this->getViewer(); - - $type = $this->getTransactionType(); - switch ($type) { - case self::TYPE_NAME: - if ($old === null) { - return pht( - '%s created %s.', - $this->renderHandleLink($author_phid), - $this->renderHandleLink($object_phid)); - } else { - return pht( - '%s changed the name of %s from %s to %s.', - $this->renderHandleLink($author_phid), - $this->renderHandleLink($object_phid), - $old, - $new); - } - case self::TYPE_URL: - if ($old === null) { - return pht( - '%s set the destination of %s to %s.', - $this->renderHandleLink($author_phid), - $this->renderHandleLink($object_phid), - $new); - } else { - return pht( - '%s changed the destination of %s from %s to %s.', - $this->renderHandleLink($author_phid), - $this->renderHandleLink($object_phid), - $old, - $new); - } - case self::TYPE_ALIAS: - if ($old === null) { - return pht( - '%s set the alias of %s to %s.', - $this->renderHandleLink($author_phid), - $this->renderHandleLink($object_phid), - $new); - } else if ($new === null) { - return pht( - '%s removed the alias of %s.', - $this->renderHandleLink($author_phid), - $this->renderHandleLink($object_phid)); - } else { - return pht( - '%s changed the alias of %s from %s to %s.', - $this->renderHandleLink($author_phid), - $this->renderHandleLink($object_phid), - $old, - $new); - } - case self::TYPE_DESCRIPTION: - return pht( - '%s updated the description of %s.', - $this->renderHandleLink($author_phid), - $this->renderHandleLink($object_phid)); - } - - return parent::getTitleForFeed(); - } - - public function getColor() { - $old = $this->getOldValue(); - $new = $this->getNewValue(); - - switch ($this->getTransactionType()) { - case self::TYPE_NAME: - case self::TYPE_URL: - case self::TYPE_ALIAS: - case self::TYPE_DESCRIPTION: - return PhabricatorTransactions::COLOR_GREEN; - } - - return parent::getColor(); - } - - - public function hasChangeDetails() { - switch ($this->getTransactionType()) { - case self::TYPE_DESCRIPTION: - return ($this->getOldValue() !== null); - } - - return parent::hasChangeDetails(); - } - - public function renderChangeDetails(PhabricatorUser $viewer) { - switch ($this->getTransactionType()) { - case self::TYPE_DESCRIPTION: - $old = $this->getOldValue(); - $new = $this->getNewValue(); - - return $this->renderTextCorpusChangeDetails( - $viewer, - $old, - $new); - } - - return parent::renderChangeDetails($viewer); - } - public function getMailTags() { $tags = array(); switch ($this->getTransactionType()) { - case self::TYPE_NAME: - case self::TYPE_DESCRIPTION: - case self::TYPE_URL: - case self::TYPE_ALIAS: + case PhabricatorPhurlURLNameTransaction::TRANSACTIONTYPE: + case PhabricatorPhurlURLLongURLTransaction::TRANSACTIONTYPE: + case PhabricatorPhurlURLAliasTransaction::TRANSACTIONTYPE: + case PhabricatorPhurlURLDescriptionTransaction::TRANSACTIONTYPE: $tags[] = self::MAILTAG_DETAILS; break; } diff --git a/src/applications/phurl/xaction/PhabricatorPhurlURLAliasTransaction.php b/src/applications/phurl/xaction/PhabricatorPhurlURLAliasTransaction.php new file mode 100644 index 0000000000..2a1f203ba2 --- /dev/null +++ b/src/applications/phurl/xaction/PhabricatorPhurlURLAliasTransaction.php @@ -0,0 +1,77 @@ +getAlias(); + } + + public function applyInternalEffects($object, $value) { + $object->setAlias($value); + } + + public function getTitle() { + return pht( + '%s changed the alias from %s to %s.', + $this->renderAuthor(), + $this->renderOldValue(), + $this->renderNewValue()); + } + + public function getTitleForFeed() { + return pht( + '%s changed the alias of %s from %s to %s.', + $this->renderAuthor(), + $this->renderObject(), + $this->renderOldValue(), + $this->renderNewValue()); + } + + public function validateTransactions($object, array $xactions) { + $errors = array(); + + if ($this->isEmptyTextTransaction($object->getAlias(), $xactions)) { + $errors[] = $this->newRequiredError( + pht('Phurls must have an alias.')); + } + + $max_length = $object->getColumnMaximumByteLength('alias'); + foreach ($xactions as $xaction) { + $new_alias = $xaction->getNewValue(); + + // Check length + $new_length = strlen($new_alias); + if ($new_length > $max_length) { + $errors[] = $this->newRequiredError( + pht('The alias can be no longer than %d characters.', $max_length)); + } + + // Check characters + if ($xaction->getOldValue() != $xaction->getNewValue()) { + $debug_alias = new PHUIInvisibleCharacterView($new_alias); + if (!preg_match('/[a-zA-Z]/', $new_alias)) { + $errors[] = $this->newRequiredError( + pht('The alias you provided (%s) must contain at least one '. + 'letter.', + $debug_alias)); + } + if (preg_match('/[^a-z0-9]/i', $new_alias)) { + $errors[] = $this->newRequiredError( + pht('The alias you provided (%s) may only contain letters and '. + 'numbers.', + $debug_alias)); + } + } + } + + return $errors; + } + + public function getIcon() { + return 'fa-compress'; + } + +} diff --git a/src/applications/phurl/xaction/PhabricatorPhurlURLDescriptionTransaction.php b/src/applications/phurl/xaction/PhabricatorPhurlURLDescriptionTransaction.php new file mode 100644 index 0000000000..8b6734e1dd --- /dev/null +++ b/src/applications/phurl/xaction/PhabricatorPhurlURLDescriptionTransaction.php @@ -0,0 +1,60 @@ +getDescription(); + } + + public function applyInternalEffects($object, $value) { + $object->setDescription($value); + } + + public function getTitle() { + return pht( + '%s updated the description.', + $this->renderAuthor()); + } + + public function getTitleForFeed() { + return pht( + '%s updated the description for %s.', + $this->renderAuthor(), + $this->renderObject()); + } + + public function hasChangeDetailView() { + return true; + } + + public function getMailDiffSectionHeader() { + return pht('CHANGES TO PHURL 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; + } + + public function getIcon() { + return 'fa-file-text-o'; + } + +} diff --git a/src/applications/phurl/xaction/PhabricatorPhurlURLLongURLTransaction.php b/src/applications/phurl/xaction/PhabricatorPhurlURLLongURLTransaction.php new file mode 100644 index 0000000000..7a4e34516e --- /dev/null +++ b/src/applications/phurl/xaction/PhabricatorPhurlURLLongURLTransaction.php @@ -0,0 +1,59 @@ +getLongURL(); + } + + public function applyInternalEffects($object, $value) { + $object->setLongURL($value); + } + + public function getTitle() { + return pht( + '%s changed the destination URL from %s to %s.', + $this->renderAuthor(), + $this->renderOldValue(), + $this->renderNewValue()); + } + + public function getTitleForFeed() { + return pht( + '%s changed the destination URL %s from %s to %s.', + $this->renderAuthor(), + $this->renderObject(), + $this->renderOldValue(), + $this->renderNewValue()); + } + + public function validateTransactions($object, array $xactions) { + $errors = array(); + + if ($this->isEmptyTextTransaction($object->getLongURL(), $xactions)) { + $errors[] = $this->newRequiredError( + pht('URL path is required')); + } + + foreach ($xactions as $xaction) { + if ($xaction->getOldValue() != $xaction->getNewValue()) { + $protocols = PhabricatorEnv::getEnvConfig('uri.allowed-protocols'); + $uri = new PhutilURI($xaction->getNewValue()); + if (!isset($protocols[$uri->getProtocol()])) { + $errors[] = $this->newRequiredError( + pht('The protocol of the URL is invalid.')); + } + } + } + + return $errors; + } + + public function getIcon() { + return 'fa-external-link-square'; + } + +} diff --git a/src/applications/phurl/xaction/PhabricatorPhurlURLNameTransaction.php b/src/applications/phurl/xaction/PhabricatorPhurlURLNameTransaction.php new file mode 100644 index 0000000000..331f6aa389 --- /dev/null +++ b/src/applications/phurl/xaction/PhabricatorPhurlURLNameTransaction.php @@ -0,0 +1,44 @@ +getName(); + } + + public function applyInternalEffects($object, $value) { + $object->setName($value); + } + + public function getTitle() { + return pht( + '%s changed the name of the URL from %s to %s.', + $this->renderAuthor(), + $this->renderOldValue(), + $this->renderNewValue()); + } + + public function getTitleForFeed() { + return pht( + '%s changed the name of %s from %s to %s.', + $this->renderAuthor(), + $this->renderObject(), + $this->renderOldValue(), + $this->renderNewValue()); + } + + public function validateTransactions($object, array $xactions) { + $errors = array(); + + if ($this->isEmptyTextTransaction($object->getName(), $xactions)) { + $errors[] = $this->newRequiredError( + pht('Phurls must have a name.')); + } + + return $errors; + } + +} diff --git a/src/applications/phurl/xaction/PhabricatorPhurlURLTransactionType.php b/src/applications/phurl/xaction/PhabricatorPhurlURLTransactionType.php new file mode 100644 index 0000000000..a2fa4fcfd2 --- /dev/null +++ b/src/applications/phurl/xaction/PhabricatorPhurlURLTransactionType.php @@ -0,0 +1,4 @@ +newQuery(); diff --git a/src/applications/releeph/query/ReleephBranchSearchEngine.php b/src/applications/releeph/query/ReleephBranchSearchEngine.php index 68ec126eb5..441f70e992 100644 --- a/src/applications/releeph/query/ReleephBranchSearchEngine.php +++ b/src/applications/releeph/query/ReleephBranchSearchEngine.php @@ -9,6 +9,10 @@ final class ReleephBranchSearchEngine return pht('Releeph Branches'); } + public function canUseInPanelContext() { + return false; + } + public function getApplicationClassName() { return 'PhabricatorReleephApplication'; } diff --git a/src/applications/releeph/query/ReleephProductSearchEngine.php b/src/applications/releeph/query/ReleephProductSearchEngine.php index f56125a687..d58ee735f1 100644 --- a/src/applications/releeph/query/ReleephProductSearchEngine.php +++ b/src/applications/releeph/query/ReleephProductSearchEngine.php @@ -11,6 +11,10 @@ final class ReleephProductSearchEngine return 'PhabricatorReleephApplication'; } + public function canUseInPanelContext() { + return false; + } + public function buildSavedQueryFromRequest(AphrontRequest $request) { $saved = new PhabricatorSavedQuery(); diff --git a/src/applications/releeph/query/ReleephRequestSearchEngine.php b/src/applications/releeph/query/ReleephRequestSearchEngine.php index 20aaa38ed9..7f866405c1 100644 --- a/src/applications/releeph/query/ReleephRequestSearchEngine.php +++ b/src/applications/releeph/query/ReleephRequestSearchEngine.php @@ -14,6 +14,10 @@ final class ReleephRequestSearchEngine return 'PhabricatorReleephApplication'; } + public function canUseInPanelContext() { + return false; + } + public function setBranch(ReleephBranch $branch) { $this->branch = $branch; return $this; diff --git a/src/applications/repository/engine/PhabricatorRepositoryDiscoveryEngine.php b/src/applications/repository/engine/PhabricatorRepositoryDiscoveryEngine.php index d7d72e7710..d0b84a6b31 100644 --- a/src/applications/repository/engine/PhabricatorRepositoryDiscoveryEngine.php +++ b/src/applications/repository/engine/PhabricatorRepositoryDiscoveryEngine.php @@ -14,7 +14,7 @@ final class PhabricatorRepositoryDiscoveryEngine private $commitCache = array(); private $workingSet = array(); - const MAX_COMMIT_CACHE_SIZE = 2048; + const MAX_COMMIT_CACHE_SIZE = 65535; /* -( Discovering Repositories )------------------------------------------- */ @@ -233,7 +233,7 @@ final class PhabricatorRepositoryDiscoveryEngine $limit, $repository->getSubversionBaseURI($at_rev)); } catch (CommandException $ex) { - $stderr = $ex->getStdErr(); + $stderr = $ex->getStderr(); if (preg_match('/(path|File) not found/', $stderr)) { // We've gone all the way back through history and this path was not // affected by earlier commits. @@ -476,6 +476,15 @@ final class PhabricatorRepositoryDiscoveryEngine return; } + $max_size = self::MAX_COMMIT_CACHE_SIZE; + + // If we're filling more identifiers than would fit in the cache, ignore + // the ones that don't fit. Because the cache is FIFO, overfilling it can + // cause the entire cache to miss. See T12296. + if (count($identifiers) > $max_size) { + $identifiers = array_slice($identifiers, 0, $max_size); + } + // When filling the cache we ignore commits which have been marked as // unreachable, treating them as though they do not exist. When recording // commits later we'll revive commits that exist but are unreachable. @@ -492,7 +501,7 @@ final class PhabricatorRepositoryDiscoveryEngine $this->commitCache[$commit->getCommitIdentifier()] = true; } - while (count($this->commitCache) > self::MAX_COMMIT_CACHE_SIZE) { + while (count($this->commitCache) > $max_size) { array_shift($this->commitCache); } } diff --git a/src/applications/repository/engine/PhabricatorRepositoryMirrorEngine.php b/src/applications/repository/engine/PhabricatorRepositoryMirrorEngine.php index f07c301bf0..b18f6b1bf8 100644 --- a/src/applications/repository/engine/PhabricatorRepositoryMirrorEngine.php +++ b/src/applications/repository/engine/PhabricatorRepositoryMirrorEngine.php @@ -108,7 +108,7 @@ final class PhabricatorRepositoryMirrorEngine ->setCWD($repository->getLocalPath()) ->resolvex(); } catch (CommandException $ex) { - if (preg_match('/no changes found/', $ex->getStdOut())) { + if (preg_match('/no changes found/', $ex->getStdout())) { // mercurial says nothing changed, but that's good } else { throw $ex; diff --git a/src/applications/repository/engine/PhabricatorRepositoryPullEngine.php b/src/applications/repository/engine/PhabricatorRepositoryPullEngine.php index d7a403acf8..610bbbfc55 100644 --- a/src/applications/repository/engine/PhabricatorRepositoryPullEngine.php +++ b/src/applications/repository/engine/PhabricatorRepositoryPullEngine.php @@ -471,7 +471,7 @@ final class PhabricatorRepositoryPullEngine $future->resolvex(); } catch (CommandException $ex) { $err = $ex->getError(); - $stdout = $ex->getStdOut(); + $stdout = $ex->getStdout(); // NOTE: Between versions 2.1 and 2.1.1, Mercurial changed the behavior // of "hg pull" to return 1 in case of a successful pull with no changes. diff --git a/src/applications/search/query/PhabricatorSearchApplicationSearchEngine.php b/src/applications/search/query/PhabricatorSearchApplicationSearchEngine.php index 835e483cff..cf7dc0f6ba 100644 --- a/src/applications/search/query/PhabricatorSearchApplicationSearchEngine.php +++ b/src/applications/search/query/PhabricatorSearchApplicationSearchEngine.php @@ -11,6 +11,10 @@ final class PhabricatorSearchApplicationSearchEngine return 'PhabricatorSearchApplication'; } + public function canUseInPanelContext() { + return false; + } + public function buildSavedQueryFromRequest(AphrontRequest $request) { $saved = new PhabricatorSavedQuery(); diff --git a/src/applications/settings/panel/PhabricatorDesktopNotificationsSettingsPanel.php b/src/applications/settings/panel/PhabricatorDesktopNotificationsSettingsPanel.php index e987fed4ab..c08a833f1b 100644 --- a/src/applications/settings/panel/PhabricatorDesktopNotificationsSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorDesktopNotificationsSettingsPanel.php @@ -88,15 +88,25 @@ final class PhabricatorDesktopNotificationsSettingsPanel 'for this Phabricator instance. Consult your browser settings / '. 'documentation to figure out how to clear this setting, do so, '. 'and then re-visit this page to grant permission.')); + + $message_id = celerity_generate_unique_node_id(); + + $message_container = phutil_tag( + 'span', + array( + 'id' => $message_id, + )); + $status_box = id(new PHUIInfoView()) ->setSeverity(PHUIInfoView::SEVERITY_NOTICE) ->setID($status_id) ->setIsHidden(true) - ->appendChild($accept_ask); + ->appendChild($message_container); $control_config = array( 'controlID' => $control_id, 'statusID' => $status_id, + 'messageID' => $message_id, 'browserStatusID' => $browser_status_id, 'defaultMode' => 0, 'desktopMode' => 1, diff --git a/src/applications/transactions/editengine/PhabricatorEditEngine.php b/src/applications/transactions/editengine/PhabricatorEditEngine.php index eb4f607ca9..8bfde17fdd 100644 --- a/src/applications/transactions/editengine/PhabricatorEditEngine.php +++ b/src/applications/transactions/editengine/PhabricatorEditEngine.php @@ -2126,6 +2126,13 @@ abstract class PhabricatorEditEngine $configs = msort($configs, 'getCreateSortKey'); + // Attach this specific engine to configurations we load so they can access + // any runtime configuration. For example, this allows us to generate the + // correct "Create Form" buttons when editing forms, see T12301. + foreach ($configs as $config) { + $config->attachEngine($this); + } + return $configs; } diff --git a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php index 5851e0186c..dc615f0f8e 100644 --- a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php +++ b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php @@ -1462,6 +1462,12 @@ abstract class PhabricatorApplicationTransactionEditor $type = $u->getTransactionType(); + $xtype = $this->getModularTransactionType($type); + if ($xtype) { + $object = $this->object; + return $xtype->mergeTransactions($object, $u, $v); + } + switch ($type) { case PhabricatorTransactions::TYPE_SUBSCRIBERS: return $this->mergePHIDOrEdgeTransactions($u, $v); @@ -2318,51 +2324,6 @@ abstract class PhabricatorApplicationTransactionEditor return true; } - /** - * Check that text field input isn't longer than a specified length. - * - * A text field input is invalid if the length of the input is longer than a - * specified length. This length can be determined by the space allotted in - * the database, or given arbitrarily. - * This method is intended to make implementing @{method:validateTransaction} - * more convenient: - * - * $overdrawn = $this->validateIsTextFieldTooLong( - * $object->getName(), - * $xactions, - * $field_length); - * - * This will return `true` if the net effect of the object and transactions - * is a field that is too long. - * - * @param wild Current field value. - * @param list Transactions editing the - * field. - * @param integer for maximum field length. - * @return bool True if the field will be too long after edits. - */ - protected function validateIsTextFieldTooLong( - $field_value, - array $xactions, - $length) { - - if ($xactions) { - $new_value_length = phutil_utf8_strlen(last($xactions)->getNewValue()); - if ($new_value_length <= $length) { - return false; - } else { - return true; - } - } - - $old_value_length = phutil_utf8_strlen($field_value); - if ($old_value_length <= $length) { - return false; - } - - return true; - } - /* -( Implicit CCs )------------------------------------------------------- */ diff --git a/src/applications/transactions/query/PhabricatorEditEngineSearchEngine.php b/src/applications/transactions/query/PhabricatorEditEngineSearchEngine.php index 70cd4cd1a3..4ba1a0e879 100644 --- a/src/applications/transactions/query/PhabricatorEditEngineSearchEngine.php +++ b/src/applications/transactions/query/PhabricatorEditEngineSearchEngine.php @@ -15,6 +15,10 @@ final class PhabricatorEditEngineSearchEngine return id(new PhabricatorEditEngineQuery()); } + public function canUseInPanelContext() { + return false; + } + protected function buildQueryFromParameters(array $map) { $query = $this->newQuery(); return $query; diff --git a/src/applications/transactions/storage/PhabricatorModularTransactionType.php b/src/applications/transactions/storage/PhabricatorModularTransactionType.php index f57d91b08f..55ad678539 100644 --- a/src/applications/transactions/storage/PhabricatorModularTransactionType.php +++ b/src/applications/transactions/storage/PhabricatorModularTransactionType.php @@ -87,6 +87,13 @@ abstract class PhabricatorModularTransactionType return array(); } + public function mergeTransactions( + $object, + PhabricatorApplicationTransaction $u, + PhabricatorApplicationTransaction $v) { + return null; + } + final public function setStorage( PhabricatorApplicationTransaction $xaction) { $this->storage = $xaction; diff --git a/src/applications/transactions/view/PhabricatorApplicationTransactionTextDiffDetailView.php b/src/applications/transactions/view/PhabricatorApplicationTransactionTextDiffDetailView.php index 158090b1a2..755d6a9fcf 100644 --- a/src/applications/transactions/view/PhabricatorApplicationTransactionTextDiffDetailView.php +++ b/src/applications/transactions/view/PhabricatorApplicationTransactionTextDiffDetailView.php @@ -19,17 +19,21 @@ final class PhabricatorApplicationTransactionTextDiffDetailView public function renderForMail() { $diff = $this->buildDiff(); + $viewer = $this->getViewer(); + $old_bright = $viewer->getCSSValue('old-bright'); + $new_bright = $viewer->getCSSValue('new-bright'); + $old_styles = array( 'padding: 0 2px;', 'color: #333333;', - 'background: #f8cbcb;', + "background: {$old_bright};", ); $old_styles = implode(' ', $old_styles); $new_styles = array( 'padding: 0 2px;', 'color: #333333;', - 'background: #a6f3a6;', + "background: {$new_bright};", ); $new_styles = implode(' ', $new_styles); diff --git a/src/applications/xhprof/application/PhabricatorXHProfApplication.php b/src/applications/xhprof/application/PhabricatorXHProfApplication.php index 999e0378a5..bdc299dd4e 100644 --- a/src/applications/xhprof/application/PhabricatorXHProfApplication.php +++ b/src/applications/xhprof/application/PhabricatorXHProfApplication.php @@ -32,6 +32,7 @@ final class PhabricatorXHProfApplication extends PhabricatorApplication { '' => 'PhabricatorXHProfSampleListController', 'list/(?P[^/]+)/' => 'PhabricatorXHProfSampleListController', 'profile/(?P[^/]+)/' => 'PhabricatorXHProfProfileController', + 'import/drop/' => 'PhabricatorXHProfDropController', ), ); } diff --git a/src/applications/xhprof/controller/PhabricatorXHProfDropController.php b/src/applications/xhprof/controller/PhabricatorXHProfDropController.php new file mode 100644 index 0000000000..6c3ab9e22c --- /dev/null +++ b/src/applications/xhprof/controller/PhabricatorXHProfDropController.php @@ -0,0 +1,54 @@ +getViewer(); + + if (!$request->validateCSRF()) { + return new Aphront400Response(); + } + + $cancel_uri = $this->getApplicationURI(); + + $ids = $request->getStrList('h'); + if ($ids) { + $files = id(new PhabricatorFileQuery()) + ->setViewer($viewer) + ->withIDs($ids) + ->setRaisePolicyExceptions(true) + ->execute(); + } else { + $files = array(); + } + + if (!$files) { + return $this->newDialog() + ->setTitle(pht('Nothing Uploaded')) + ->appendParagraph( + pht('Drag and drop .xhprof files to import them.')) + ->addCancelButton($cancel_uri, pht('Done')); + } + + $samples = array(); + foreach ($files as $file) { + $sample = PhabricatorXHProfSample::initializeNewSample() + ->setFilePHID($file->getPHID()) + ->setUserPHID($viewer->getPHID()) + ->save(); + + $samples[] = $sample; + } + + if (count($samples) == 1) { + $event = head($samples); + $next_uri = $event->getURI(); + } else { + $next_uri = $this->getApplicationURI(); + } + + return id(new AphrontRedirectResponse())->setURI($next_uri); + } + +} diff --git a/src/applications/xhprof/controller/PhabricatorXHProfSampleListController.php b/src/applications/xhprof/controller/PhabricatorXHProfSampleListController.php index 5faab70c7a..41d108b85f 100644 --- a/src/applications/xhprof/controller/PhabricatorXHProfSampleListController.php +++ b/src/applications/xhprof/controller/PhabricatorXHProfSampleListController.php @@ -8,91 +8,9 @@ final class PhabricatorXHProfSampleListController } public function handleRequest(AphrontRequest $request) { - $viewer = $request->getViewer(); - $view = $request->getURIData('view'); - - if (!$view) { - $view = 'all'; - } - - $pager = new PHUIPagerView(); - $pager->setOffset($request->getInt('page')); - - switch ($view) { - case 'sampled': - $clause = 'sampleRate > 0'; - $show_type = false; - break; - case 'my-runs': - $clause = qsprintf( - id(new PhabricatorXHProfSample())->establishConnection('r'), - 'sampleRate = 0 AND userPHID = %s', - $request->getUser()->getPHID()); - $show_type = false; - break; - case 'manual': - $clause = 'sampleRate = 0'; - $show_type = false; - break; - case 'all': - default: - $clause = '1 = 1'; - $show_type = true; - break; - } - - $samples = id(new PhabricatorXHProfSample())->loadAllWhere( - '%Q ORDER BY id DESC LIMIT %d, %d', - $clause, - $pager->getOffset(), - $pager->getPageSize() + 1); - - $samples = $pager->sliceResults($samples); - $pager->setURI($request->getRequestURI(), 'page'); - - $list = new PHUIObjectItemListView(); - foreach ($samples as $sample) { - $file_phid = $sample->getFilePHID(); - - $item = id(new PHUIObjectItemView()) - ->setObjectName($sample->getID()) - ->setHeader($sample->getRequestPath()) - ->setHref($this->getApplicationURI('profile/'.$file_phid.'/')) - ->addAttribute( - number_format($sample->getUsTotal())." \xCE\xBCs"); - - if ($sample->getController()) { - $item->addAttribute($sample->getController()); - } - - $item->addAttribute($sample->getHostName()); - - $rate = $sample->getSampleRate(); - if ($rate == 0) { - $item->addIcon('flag-6', pht('Manual Run')); - } else { - $item->addIcon('flag-7', pht('Sampled (1/%d)', $rate)); - } - - $item->addIcon( - 'none', - phabricator_datetime($sample->getDateCreated(), $viewer)); - - $list->addItem($item); - } - - $list->setPager($pager); - $list->setNoDataString(pht('There are no profiling samples.')); - - $crumbs = $this->buildApplicationCrumbs(); - $crumbs->addTextCrumb(pht('XHProf Samples')); - - $title = pht('XHProf Samples'); - - return $this->newPage() - ->setTitle($title) - ->setCrumbs($crumbs) - ->appendChild($list); - + return id(new PhabricatorXHProfSampleSearchEngine()) + ->setController($this) + ->buildResponse(); } + } diff --git a/src/applications/xhprof/query/PhabricatorXHProfSampleQuery.php b/src/applications/xhprof/query/PhabricatorXHProfSampleQuery.php new file mode 100644 index 0000000000..3e9643a7fc --- /dev/null +++ b/src/applications/xhprof/query/PhabricatorXHProfSampleQuery.php @@ -0,0 +1,51 @@ +ids = $ids; + return $this; + } + + public function withPHIDs(array $phids) { + $this->phids = $phids; + return $this; + } + + public function newResultObject() { + return new PhabricatorXHProfSample(); + } + + protected function loadPage() { + return $this->loadStandardPage($this->newResultObject()); + } + + protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { + $where = parent::buildWhereClauseParts($conn); + + if ($this->ids !== null) { + $where[] = qsprintf( + $conn, + 'id IN (%Ld)', + $this->ids); + } + + if ($this->phids !== null) { + $where[] = qsprintf( + $conn, + 'phid IN (%Ls)', + $this->phids); + } + + return $where; + } + + public function getQueryApplicationClass() { + return 'PhabricatorXHProfApplication'; + } + +} diff --git a/src/applications/xhprof/query/PhabricatorXHProfSampleSearchEngine.php b/src/applications/xhprof/query/PhabricatorXHProfSampleSearchEngine.php new file mode 100644 index 0000000000..171f28f027 --- /dev/null +++ b/src/applications/xhprof/query/PhabricatorXHProfSampleSearchEngine.php @@ -0,0 +1,120 @@ +newQuery(); + + return $query; + } + + protected function buildCustomSearchFields() { + return array(); + } + + protected function getURI($path) { + return '/xhprof/'.$path; + } + + protected function getBuiltinQueryNames() { + $names = array( + 'all' => pht('All Samples'), + ); + + return $names; + } + + public function buildSavedQueryFromBuiltin($query_key) { + $query = $this->newSavedQuery(); + $query->setQueryKey($query_key); + + switch ($query_key) { + case 'all': + return $query; + } + + return parent::buildSavedQueryFromBuiltin($query_key); + } + + protected function renderResultList( + array $samples, + PhabricatorSavedQuery $query, + array $handles) { + assert_instances_of($samples, 'PhabricatorXHProfSample'); + + $viewer = $this->requireViewer(); + + $list = new PHUIObjectItemListView(); + foreach ($samples as $sample) { + $file_phid = $sample->getFilePHID(); + + $item = id(new PHUIObjectItemView()) + ->setObjectName($sample->getID()) + ->setHeader($sample->getDisplayName()) + ->setHref($sample->getURI()); + + $us_total = $sample->getUsTotal(); + if ($us_total) { + $item->addAttribute(pht("%s \xCE\xBCs", new PhutilNumber($us_total))); + } + + if ($sample->getController()) { + $item->addAttribute($sample->getController()); + } + + $item->addAttribute($sample->getHostName()); + + $rate = $sample->getSampleRate(); + if ($rate == 0) { + $item->addIcon('flag-6', pht('Manual Run')); + } else { + $item->addIcon('flag-7', pht('Sampled (1/%d)', $rate)); + } + + $item->addIcon( + 'none', + phabricator_datetime($sample->getDateCreated(), $viewer)); + + $list->addItem($item); + } + + return $this->newResultView() + ->setObjectList($list); + } + + + private function newResultView($content = null) { + // If we aren't rendering a dashboard panel, activate global drag-and-drop + // so you can import profiles by dropping them into the list. + + if (!$this->isPanelContext()) { + $drop_upload = id(new PhabricatorGlobalUploadTargetView()) + ->setViewer($this->requireViewer()) + ->setHintText("\xE2\x87\xAA ".pht('Drop .xhprof Files to Import')) + ->setSubmitURI('/xhprof/import/drop/') + ->setViewPolicy(PhabricatorPolicies::POLICY_NOONE); + + $content = array( + $drop_upload, + $content, + ); + } + + return id(new PhabricatorApplicationSearchResultView()) + ->setContent($content); + } + +} diff --git a/src/applications/xhprof/storage/PhabricatorXHProfSample.php b/src/applications/xhprof/storage/PhabricatorXHProfSample.php index 662305429d..3384ef3be2 100644 --- a/src/applications/xhprof/storage/PhabricatorXHProfSample.php +++ b/src/applications/xhprof/storage/PhabricatorXHProfSample.php @@ -1,6 +1,8 @@ setUsTotal(0) + ->setSampleRate(0); + } + protected function getConfiguration() { return array( self::CONFIG_COLUMN_SCHEMA => array( @@ -29,4 +37,38 @@ final class PhabricatorXHProfSample extends PhabricatorXHProfDAO { ) + parent::getConfiguration(); } + public function getURI() { + return '/xhprof/profile/'.$this->getFilePHID().'/'; + } + + public function getDisplayName() { + $request_path = $this->getRequestPath(); + if (strlen($request_path)) { + return $request_path; + } + + return pht('Unnamed Sample'); + } + + +/* -( PhabricatorPolicyInterface )----------------------------------------- */ + + + public function getCapabilities() { + return array( + PhabricatorPolicyCapability::CAN_VIEW, + ); + } + + public function getPolicy($capability) { + switch ($capability) { + case PhabricatorPolicyCapability::CAN_VIEW: + return PhabricatorPolicies::getMostOpenPolicy(); + } + } + + public function hasAutomaticCapability($capability, PhabricatorUser $viewer) { + return false; + } + } diff --git a/src/docs/user/userguide/arcanist_mac_os_x.diviner b/src/docs/user/userguide/arcanist_mac_os_x.diviner index a34adfbf5d..d75df8b33b 100644 --- a/src/docs/user/userguide/arcanist_mac_os_x.diviner +++ b/src/docs/user/userguide/arcanist_mac_os_x.diviner @@ -9,6 +9,7 @@ You need to install: - PHP, which should be installed by default. - Arcanist itself, see @{article:Arcanist User Guide}. + or @{article:Arcanist Quick Start} - SVN, Git, or Mercurial. Then, configure: diff --git a/src/docs/user/userguide/arcanist_quick_start.diviner b/src/docs/user/userguide/arcanist_quick_start.diviner index 98633bfaef..743afe4a11 100644 --- a/src/docs/user/userguide/arcanist_quick_start.diviner +++ b/src/docs/user/userguide/arcanist_quick_start.diviner @@ -4,16 +4,15 @@ Quick guide to getting Arcanist working for a new project. This is a summary of steps to install Arcanist, configure a project for use with -it, and run `arc` to send changes for review. - -= Install Arcanist = - -For detailed instructions on installing Arcanist, see -@{article:Arcanist User Guide}. +it, and run `arc` to send changes for review. For detailed instructions on +installing Arcanist, see @{article:Arcanist User Guide}. OS specific guides +are also available. - For Mac OS X, see @{article:Arcanist User Guide: Mac OS X}. - For Windows, see @{article:Arcanist User Guide: Windows}. += Installing Arcanist = + First, install dependencies: - Install PHP. diff --git a/src/docs/user/userguide/arcanist_windows.diviner b/src/docs/user/userguide/arcanist_windows.diviner index 150e4f3372..56fbfea318 100644 --- a/src/docs/user/userguide/arcanist_windows.diviner +++ b/src/docs/user/userguide/arcanist_windows.diviner @@ -17,6 +17,7 @@ into issues. You need to install: - Arcanist itself, see @{article:Arcanist User Guide}. + or @{article:Arcanist Quick Start}. - PHP (see "Detailed PHP Install Instructions" below). - SVN, Git, or Mercurial. diff --git a/src/infrastructure/daemon/workers/PhabricatorTriggerDaemon.php b/src/infrastructure/daemon/workers/PhabricatorTriggerDaemon.php index cec2fbf80e..02ac55a160 100644 --- a/src/infrastructure/daemon/workers/PhabricatorTriggerDaemon.php +++ b/src/infrastructure/daemon/workers/PhabricatorTriggerDaemon.php @@ -108,6 +108,11 @@ final class PhabricatorTriggerDaemon $sleep_duration = $this->runNuanceImportCursors($sleep_duration); $sleep_duration = $this->runGarbageCollection($sleep_duration); $sleep_duration = $this->runCalendarNotifier($sleep_duration); + + if ($this->shouldHibernate($sleep_duration)) { + break; + } + $this->sleep($sleep_duration); } while (!$this->shouldExit()); } diff --git a/src/infrastructure/daemon/workers/query/PhabricatorWorkerBulkJobSearchEngine.php b/src/infrastructure/daemon/workers/query/PhabricatorWorkerBulkJobSearchEngine.php index 223db0e95a..3b9d6c9d48 100644 --- a/src/infrastructure/daemon/workers/query/PhabricatorWorkerBulkJobSearchEngine.php +++ b/src/infrastructure/daemon/workers/query/PhabricatorWorkerBulkJobSearchEngine.php @@ -4,7 +4,7 @@ final class PhabricatorWorkerBulkJobSearchEngine extends PhabricatorApplicationSearchEngine { public function getResultTypeDescription() { - return pht('Bulk Jobs'); + return pht('Daemon Bulk Jobs'); } public function getApplicationClassName() { @@ -15,6 +15,10 @@ final class PhabricatorWorkerBulkJobSearchEngine return id(new PhabricatorWorkerBulkJobQuery()); } + public function canUseInPanelContext() { + return false; + } + protected function buildQueryFromParameters(array $map) { $query = $this->newQuery(); diff --git a/src/infrastructure/javelin/markup.php b/src/infrastructure/javelin/markup.php index c78de8b86a..1909a3bd2b 100644 --- a/src/infrastructure/javelin/markup.php +++ b/src/infrastructure/javelin/markup.php @@ -98,6 +98,19 @@ function phabricator_form(PhabricatorUser $user, $attributes, $content) { 'name' => '__form__', 'value' => true, )); + + // If the profiler was active for this request, keep it active for any + // forms submitted from this page. + if (DarkConsoleXHProfPluginAPI::isProfilerRequested()) { + $body[] = phutil_tag( + 'input', + array( + 'type' => 'hidden', + 'name' => '__profile__', + 'value' => true, + )); + } + } } diff --git a/src/infrastructure/markup/PhabricatorMarkupEngine.php b/src/infrastructure/markup/PhabricatorMarkupEngine.php index 3ce5578f82..3fbf29c294 100644 --- a/src/infrastructure/markup/PhabricatorMarkupEngine.php +++ b/src/infrastructure/markup/PhabricatorMarkupEngine.php @@ -111,7 +111,7 @@ final class PhabricatorMarkupEngine extends Phobject { } if (!$keys) { - return; + return $this; } $objects = array_select_keys($this->objects, $keys); diff --git a/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php b/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php index 8d43980122..efb08da223 100644 --- a/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php +++ b/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php @@ -1521,6 +1521,7 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery /** + * @return this * @task edgelogic */ public function withEdgeLogicConstraints($edge_type, array $constraints) { diff --git a/src/infrastructure/storage/lisk/LiskDAO.php b/src/infrastructure/storage/lisk/LiskDAO.php index c6712ae873..94eef7d163 100644 --- a/src/infrastructure/storage/lisk/LiskDAO.php +++ b/src/infrastructure/storage/lisk/LiskDAO.php @@ -1094,12 +1094,12 @@ abstract class LiskDAO extends Phobject { /** - * Save this object, forcing the query to use INSERT regardless of object - * state. + * Save this object, forcing the query to use INSERT regardless of object + * state. * - * @return this + * @return this * - * @task save + * @task save */ public function insert() { $this->isEphemeralCheck(); @@ -1108,12 +1108,12 @@ abstract class LiskDAO extends Phobject { /** - * Save this object, forcing the query to use UPDATE regardless of object - * state. + * Save this object, forcing the query to use UPDATE regardless of object + * state. * - * @return this + * @return this * - * @task save + * @task save */ public function update() { $this->isEphemeralCheck(); @@ -1192,6 +1192,7 @@ abstract class LiskDAO extends Phobject { * Internal implementation of INSERT and REPLACE. * * @param const Either "INSERT" or "REPLACE", to force the desired mode. + * @return this * * @task save */ diff --git a/src/infrastructure/time/PhabricatorTime.php b/src/infrastructure/time/PhabricatorTime.php index 250d8f1e23..b221285d13 100644 --- a/src/infrastructure/time/PhabricatorTime.php +++ b/src/infrastructure/time/PhabricatorTime.php @@ -64,7 +64,7 @@ final class PhabricatorTime extends Phobject { public static function getTodayMidnightDateTime($viewer) { $timezone = new DateTimeZone($viewer->getTimezoneIdentifier()); $today = new DateTime('@'.time()); - $today->setTimeZone($timezone); + $today->setTimezone($timezone); $year = $today->format('Y'); $month = $today->format('m'); $day = $today->format('d'); @@ -74,7 +74,7 @@ final class PhabricatorTime extends Phobject { public static function getDateTimeFromEpoch($epoch, PhabricatorUser $viewer) { $datetime = new DateTime('@'.$epoch); - $datetime->setTimeZone($viewer->getTimeZone()); + $datetime->setTimezone($viewer->getTimeZone()); return $datetime; } diff --git a/src/view/phui/calendar/PHUICalendarMonthView.php b/src/view/phui/calendar/PHUICalendarMonthView.php index 8272eb007f..752a9afa15 100644 --- a/src/view/phui/calendar/PHUICalendarMonthView.php +++ b/src/view/phui/calendar/PHUICalendarMonthView.php @@ -577,7 +577,7 @@ final class PHUICalendarMonthView extends AphrontView { private function getTodayMidnight() { $viewer = $this->getUser(); $today = new DateTime('@'.time()); - $today->setTimeZone($viewer->getTimeZone()); + $today->setTimezone($viewer->getTimeZone()); $today->setTime(0, 0, 0); return $today; diff --git a/src/view/viewutils.php b/src/view/viewutils.php index ea89399e22..e0629800c7 100644 --- a/src/view/viewutils.php +++ b/src/view/viewutils.php @@ -88,7 +88,7 @@ function phabricator_format_local_time($epoch, $user, $format) { "raised an exception.", $epoch)); } - $date->setTimeZone($zone); + $date->setTimezone($zone); return PhutilTranslator::getInstance()->translateDate($format, $date); } diff --git a/webroot/rsrc/css/application/conpherence/durable-column.css b/webroot/rsrc/css/application/conpherence/durable-column.css index d141115b73..2b0ab85e44 100644 --- a/webroot/rsrc/css/application/conpherence/durable-column.css +++ b/webroot/rsrc/css/application/conpherence/durable-column.css @@ -18,7 +18,9 @@ box-shadow: 0px 1px 8px rgba(55,55,55, .3); } -.device .conpherence-durable-column { +.device .conpherence-durable-column, +.printable .conpherence-durable-column, +!print .conpherence-durable-column { display: none; } diff --git a/webroot/rsrc/css/application/project/project-card-view.css b/webroot/rsrc/css/application/project/project-card-view.css index 5f5155c130..0ad25c5420 100644 --- a/webroot/rsrc/css/application/project/project-card-view.css +++ b/webroot/rsrc/css/application/project/project-card-view.css @@ -9,7 +9,8 @@ border: 1px solid {$lightblueborder}; border-radius: 3px; box-shadow: {$dropshadow}; - width: 380px; + width: 420px; + position: relative; } .project-card-view .phui-header-shell { @@ -35,6 +36,53 @@ display: block; } +.project-card-view .project-card-image { + height: 140px; + width: 140px; + margin: 6px; + border-radius: 3px; +} + +.project-card-view .project-card-item div { + display: inline; +} + +.project-card-view .project-card-item { + margin-bottom: 2px; +} + +.project-card-view .project-card-item-text { + color: {$greytext}; +} + +.project-card-view .project-card-item-icon { + width: 20px; +} + +.project-card-view .project-card-header { + position: absolute; + top: 12px; + left: 158px; +} + +.project-card-header .project-card-name { + font-size: 20px; + font-family: 'Aleo', {$fontfamily}; + font-weight: bold; + color: #000; + margin-bottom: 2px; + text-overflow: ellipsis; + white-space: nowrap; + width: 250px; + overflow: hidden; +} + +.project-card-header .project-card-username { + font-size: 14px; + color: {$bluetext}; + margin-bottom: 12px; +} + .project-card-view .phui-header-shell .phui-header-col1 { vertical-align: top; width: 64px; @@ -65,7 +113,7 @@ } .project-card-view .project-card-body { - padding: 0 12px 12px 76px; + padding: 0 12px 12px 12px; color: {$darkbluetext}; } diff --git a/webroot/rsrc/css/application/project/project-view.css b/webroot/rsrc/css/application/project/project-view.css index cc8d484426..82c5a2e13b 100644 --- a/webroot/rsrc/css/application/project/project-view.css +++ b/webroot/rsrc/css/application/project/project-view.css @@ -67,10 +67,6 @@ text-align: center; } -.project-view-badges .phui-badge-flex-view { - background-color: #fff; -} - .project-view-home .phui-box-grey .phui-oi-attribute .phui-icon-view { color: {$lightgreytext}; } diff --git a/webroot/rsrc/css/phui/phui-badge.css b/webroot/rsrc/css/phui/phui-badge.css index b702d3e6c5..1538e5de4d 100644 --- a/webroot/rsrc/css/phui/phui-badge.css +++ b/webroot/rsrc/css/phui/phui-badge.css @@ -3,14 +3,13 @@ */ .phui-badge-flex-view { - padding: 12px 4px 8px; + padding: 0; overflow: hidden; - text-align: center; } .phui-badge-flex-item { display: inline-block; - padding: 4px 8px; + padding: 4px 12px 4px 0; } .phui-badge-flex-view.flex-view-collapsed { @@ -183,11 +182,6 @@ line-height: 24px; text-align: center; display: inline-block; - opacity: 0.7; -} - -.phui-badge-mini:hover { - opacity: 1; } .phui-badge-mini .phui-icon-view { diff --git a/webroot/rsrc/css/phui/phui-hovercard.css b/webroot/rsrc/css/phui/phui-hovercard.css index 6431c01cdf..bf81096a71 100644 --- a/webroot/rsrc/css/phui/phui-hovercard.css +++ b/webroot/rsrc/css/phui/phui-hovercard.css @@ -81,7 +81,11 @@ } .hovercard-badges { - margin: 8px 0 0 0; + margin: 6px 0 0 0; + padding: 4px; + background: {$page.background}; + border-bottom-left-radius: 3px; + border-bottom-right-radius: 3px; } .hovercard-badges .phui-badge-flex-item { diff --git a/webroot/rsrc/css/phui/phui-icon.css b/webroot/rsrc/css/phui/phui-icon.css index 142208c110..22b33bca11 100644 --- a/webroot/rsrc/css/phui/phui-icon.css +++ b/webroot/rsrc/css/phui/phui-icon.css @@ -31,7 +31,7 @@ } .phui-icon-has-text:before { - margin-right: 4px; + margin-right: 6px; } a.phui-icon-view:hover { @@ -39,6 +39,12 @@ a.phui-icon-view:hover { color: {$sky}; } +img.phui-image-disabled { + opacity: .8; + -webkit-filter: grayscale(100%); + filter: grayscale(100%); +} + /* - Icon in a Circle ------------------------------------------------------- */ .phui-icon-circle { diff --git a/webroot/rsrc/css/phui/phui-pager.css b/webroot/rsrc/css/phui/phui-pager.css index ff59ad0c77..590b8514ce 100644 --- a/webroot/rsrc/css/phui/phui-pager.css +++ b/webroot/rsrc/css/phui/phui-pager.css @@ -4,5 +4,5 @@ .phui-pager-view { clear: both; - text-align: right; + text-align: center; } diff --git a/webroot/rsrc/css/phui/phui-timeline-view.css b/webroot/rsrc/css/phui/phui-timeline-view.css index 9460fbac2f..fb1ddbd768 100644 --- a/webroot/rsrc/css/phui/phui-timeline-view.css +++ b/webroot/rsrc/css/phui/phui-timeline-view.css @@ -411,6 +411,7 @@ a.phui-timeline-menu .phui-icon-view { left: -64px; top: 52px; width: 54px; + text-align: center; } .phui-timeline-badges .phui-badge-mini { diff --git a/webroot/rsrc/js/application/aphlict/behavior-desktop-notifications-control.js b/webroot/rsrc/js/application/aphlict/behavior-desktop-notifications-control.js index d3cedc8615..3a9b028ca3 100644 --- a/webroot/rsrc/js/application/aphlict/behavior-desktop-notifications-control.js +++ b/webroot/rsrc/js/application/aphlict/behavior-desktop-notifications-control.js @@ -19,22 +19,26 @@ JX.behavior('desktop-notifications-control', function(config, statics) { return el; } function updateFormStatus(permission) { - var statusEl = findEl(config.statusID); - if (!statusEl) { + var status_node = findEl(config.statusID); + if (!status_node) { return; } + + var message_node = JX.$(config.messageID); + switch (permission) { case 'default': - JX.DOM.setContent(statusEl.firstChild, config.cancelAsk); + JX.DOM.setContent(message_node, config.cancelAsk); break; case 'granted': - JX.DOM.setContent(statusEl.firstChild, config.grantedAsk); + JX.DOM.setContent(message_node, config.grantedAsk); break; case 'denied': - JX.DOM.setContent(statusEl.firstChild, config.deniedAsk); + JX.DOM.setContent(message_node, config.deniedAsk); break; } - JX.DOM.show(statusEl); + + JX.DOM.show(status_node); } function updateBrowserStatus(permission) {