mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-29 02:02:41 +01:00
(stable) Promote 2016 Week 12
This commit is contained in:
commit
741e2ef4b1
110 changed files with 3080 additions and 1370 deletions
|
@ -7,12 +7,12 @@
|
||||||
*/
|
*/
|
||||||
return array(
|
return array(
|
||||||
'names' => array(
|
'names' => array(
|
||||||
'core.pkg.css' => '9c8e888d',
|
'core.pkg.css' => 'a93de192',
|
||||||
'core.pkg.js' => '7d8faf57',
|
'core.pkg.js' => '7d8faf57',
|
||||||
'darkconsole.pkg.js' => 'e7393ebb',
|
'darkconsole.pkg.js' => 'e7393ebb',
|
||||||
'differential.pkg.css' => '7d0a63a7',
|
'differential.pkg.css' => '7ba78475',
|
||||||
'differential.pkg.js' => 'd0cd0df6',
|
'differential.pkg.js' => 'd0cd0df6',
|
||||||
'diffusion.pkg.css' => 'f45955ed',
|
'diffusion.pkg.css' => 'dc8e0cc2',
|
||||||
'diffusion.pkg.js' => '3a9a8bfa',
|
'diffusion.pkg.js' => '3a9a8bfa',
|
||||||
'maniphest.pkg.css' => '4845691a',
|
'maniphest.pkg.css' => '4845691a',
|
||||||
'maniphest.pkg.js' => '949a7498',
|
'maniphest.pkg.js' => '949a7498',
|
||||||
|
@ -57,16 +57,16 @@ return array(
|
||||||
'rsrc/css/application/dashboard/dashboard.css' => 'eb458607',
|
'rsrc/css/application/dashboard/dashboard.css' => 'eb458607',
|
||||||
'rsrc/css/application/diff/inline-comment-summary.css' => '51efda3a',
|
'rsrc/css/application/diff/inline-comment-summary.css' => '51efda3a',
|
||||||
'rsrc/css/application/differential/add-comment.css' => 'c47f8c40',
|
'rsrc/css/application/differential/add-comment.css' => 'c47f8c40',
|
||||||
'rsrc/css/application/differential/changeset-view.css' => 'b6b0d1bb',
|
'rsrc/css/application/differential/changeset-view.css' => '3e3b0b76',
|
||||||
'rsrc/css/application/differential/core.css' => '7ac3cabc',
|
'rsrc/css/application/differential/core.css' => '5b7b8ff4',
|
||||||
'rsrc/css/application/differential/phui-inline-comment.css' => '5953c28e',
|
'rsrc/css/application/differential/phui-inline-comment.css' => '5953c28e',
|
||||||
'rsrc/css/application/differential/revision-comment.css' => '14b8565a',
|
'rsrc/css/application/differential/revision-comment.css' => '14b8565a',
|
||||||
'rsrc/css/application/differential/revision-history.css' => '0e8eb855',
|
'rsrc/css/application/differential/revision-history.css' => '0e8eb855',
|
||||||
'rsrc/css/application/differential/revision-list.css' => 'f3c47d33',
|
'rsrc/css/application/differential/revision-list.css' => 'f3c47d33',
|
||||||
'rsrc/css/application/differential/table-of-contents.css' => 'ae4b7a55',
|
'rsrc/css/application/differential/table-of-contents.css' => 'ae4b7a55',
|
||||||
'rsrc/css/application/diffusion/diffusion-icons.css' => '2941baf1',
|
'rsrc/css/application/diffusion/diffusion-icons.css' => '3311444d',
|
||||||
'rsrc/css/application/diffusion/diffusion-readme.css' => '356a4f3c',
|
'rsrc/css/application/diffusion/diffusion-readme.css' => '297373eb',
|
||||||
'rsrc/css/application/diffusion/diffusion-source.css' => '075ba788',
|
'rsrc/css/application/diffusion/diffusion-source.css' => '68b30fd3',
|
||||||
'rsrc/css/application/feed/feed.css' => 'ecd4ec57',
|
'rsrc/css/application/feed/feed.css' => 'ecd4ec57',
|
||||||
'rsrc/css/application/files/global-drag-and-drop.css' => '5c1b47c2',
|
'rsrc/css/application/files/global-drag-and-drop.css' => '5c1b47c2',
|
||||||
'rsrc/css/application/flag/flag.css' => '5337623f',
|
'rsrc/css/application/flag/flag.css' => '5337623f',
|
||||||
|
@ -123,7 +123,7 @@ return array(
|
||||||
'rsrc/css/phui/phui-action-panel.css' => '91c7b835',
|
'rsrc/css/phui/phui-action-panel.css' => '91c7b835',
|
||||||
'rsrc/css/phui/phui-badge.css' => 'f25c3476',
|
'rsrc/css/phui/phui-badge.css' => 'f25c3476',
|
||||||
'rsrc/css/phui/phui-big-info-view.css' => 'bd903741',
|
'rsrc/css/phui/phui-big-info-view.css' => 'bd903741',
|
||||||
'rsrc/css/phui/phui-box.css' => '3830ab21',
|
'rsrc/css/phui/phui-box.css' => 'b2d49bae',
|
||||||
'rsrc/css/phui/phui-button.css' => 'a64a8de6',
|
'rsrc/css/phui/phui-button.css' => 'a64a8de6',
|
||||||
'rsrc/css/phui/phui-chart.css' => '6bf6f78e',
|
'rsrc/css/phui/phui-chart.css' => '6bf6f78e',
|
||||||
'rsrc/css/phui/phui-crumbs-view.css' => '79d536e5',
|
'rsrc/css/phui/phui-crumbs-view.css' => '79d536e5',
|
||||||
|
@ -135,28 +135,28 @@ return array(
|
||||||
'rsrc/css/phui/phui-fontkit.css' => '9cda225e',
|
'rsrc/css/phui/phui-fontkit.css' => '9cda225e',
|
||||||
'rsrc/css/phui/phui-form-view.css' => '4a1a0f5e',
|
'rsrc/css/phui/phui-form-view.css' => '4a1a0f5e',
|
||||||
'rsrc/css/phui/phui-form.css' => 'aac1d51d',
|
'rsrc/css/phui/phui-form.css' => 'aac1d51d',
|
||||||
'rsrc/css/phui/phui-head-thing.css' => '31638812',
|
'rsrc/css/phui/phui-head-thing.css' => 'fd311e5f',
|
||||||
'rsrc/css/phui/phui-header-view.css' => '26cffd3d',
|
'rsrc/css/phui/phui-header-view.css' => '230254d3',
|
||||||
'rsrc/css/phui/phui-hovercard.css' => 'de1a2119',
|
'rsrc/css/phui/phui-hovercard.css' => 'de1a2119',
|
||||||
'rsrc/css/phui/phui-icon-set-selector.css' => '1ab67aad',
|
'rsrc/css/phui/phui-icon-set-selector.css' => '1ab67aad',
|
||||||
'rsrc/css/phui/phui-icon.css' => '3f33ab57',
|
'rsrc/css/phui/phui-icon.css' => '3f33ab57',
|
||||||
'rsrc/css/phui/phui-image-mask.css' => 'a8498f9c',
|
'rsrc/css/phui/phui-image-mask.css' => 'a8498f9c',
|
||||||
'rsrc/css/phui/phui-info-panel.css' => '27ea50a1',
|
'rsrc/css/phui/phui-info-panel.css' => '27ea50a1',
|
||||||
'rsrc/css/phui/phui-info-view.css' => '6d7c3509',
|
'rsrc/css/phui/phui-info-view.css' => '28efab79',
|
||||||
'rsrc/css/phui/phui-list.css' => '9da2aa00',
|
'rsrc/css/phui/phui-list.css' => '9da2aa00',
|
||||||
'rsrc/css/phui/phui-object-box.css' => '91628842',
|
'rsrc/css/phui/phui-object-box.css' => '6b487c57',
|
||||||
'rsrc/css/phui/phui-object-item-list-view.css' => '18b2ce8e',
|
'rsrc/css/phui/phui-object-item-list-view.css' => '18b2ce8e',
|
||||||
'rsrc/css/phui/phui-pager.css' => 'bea33d23',
|
'rsrc/css/phui/phui-pager.css' => 'bea33d23',
|
||||||
'rsrc/css/phui/phui-pinboard-view.css' => '2495140e',
|
'rsrc/css/phui/phui-pinboard-view.css' => '2495140e',
|
||||||
'rsrc/css/phui/phui-profile-menu.css' => '7e92a89a',
|
'rsrc/css/phui/phui-profile-menu.css' => '7e92a89a',
|
||||||
'rsrc/css/phui/phui-property-list-view.css' => 'b12e801c',
|
'rsrc/css/phui/phui-property-list-view.css' => '1d42ee7c',
|
||||||
'rsrc/css/phui/phui-remarkup-preview.css' => '1a8f2591',
|
'rsrc/css/phui/phui-remarkup-preview.css' => '1a8f2591',
|
||||||
'rsrc/css/phui/phui-segment-bar-view.css' => '46342871',
|
'rsrc/css/phui/phui-segment-bar-view.css' => '46342871',
|
||||||
'rsrc/css/phui/phui-spacing.css' => '042804d6',
|
'rsrc/css/phui/phui-spacing.css' => '042804d6',
|
||||||
'rsrc/css/phui/phui-status.css' => '37309046',
|
'rsrc/css/phui/phui-status.css' => '37309046',
|
||||||
'rsrc/css/phui/phui-tag-view.css' => '6bbd83e2',
|
'rsrc/css/phui/phui-tag-view.css' => '6bbd83e2',
|
||||||
'rsrc/css/phui/phui-timeline-view.css' => 'a0173eba',
|
'rsrc/css/phui/phui-timeline-view.css' => 'a0173eba',
|
||||||
'rsrc/css/phui/phui-two-column-view.css' => 'e6bf86b6',
|
'rsrc/css/phui/phui-two-column-view.css' => '37d704f3',
|
||||||
'rsrc/css/phui/workboards/phui-workboard-color.css' => 'ac6fe6a7',
|
'rsrc/css/phui/workboards/phui-workboard-color.css' => 'ac6fe6a7',
|
||||||
'rsrc/css/phui/workboards/phui-workboard.css' => 'e6d89647',
|
'rsrc/css/phui/workboards/phui-workboard.css' => 'e6d89647',
|
||||||
'rsrc/css/phui/workboards/phui-workcard.css' => '3646fb96',
|
'rsrc/css/phui/workboards/phui-workcard.css' => '3646fb96',
|
||||||
|
@ -545,17 +545,17 @@ return array(
|
||||||
'conpherence-update-css' => 'faf6be09',
|
'conpherence-update-css' => 'faf6be09',
|
||||||
'conpherence-widget-pane-css' => '775eaaba',
|
'conpherence-widget-pane-css' => '775eaaba',
|
||||||
'd3' => 'a11a5ff2',
|
'd3' => 'a11a5ff2',
|
||||||
'differential-changeset-view-css' => 'b6b0d1bb',
|
'differential-changeset-view-css' => '3e3b0b76',
|
||||||
'differential-core-view-css' => '7ac3cabc',
|
'differential-core-view-css' => '5b7b8ff4',
|
||||||
'differential-inline-comment-editor' => '64a5550f',
|
'differential-inline-comment-editor' => '64a5550f',
|
||||||
'differential-revision-add-comment-css' => 'c47f8c40',
|
'differential-revision-add-comment-css' => 'c47f8c40',
|
||||||
'differential-revision-comment-css' => '14b8565a',
|
'differential-revision-comment-css' => '14b8565a',
|
||||||
'differential-revision-history-css' => '0e8eb855',
|
'differential-revision-history-css' => '0e8eb855',
|
||||||
'differential-revision-list-css' => 'f3c47d33',
|
'differential-revision-list-css' => 'f3c47d33',
|
||||||
'differential-table-of-contents-css' => 'ae4b7a55',
|
'differential-table-of-contents-css' => 'ae4b7a55',
|
||||||
'diffusion-icons-css' => '2941baf1',
|
'diffusion-icons-css' => '3311444d',
|
||||||
'diffusion-readme-css' => '356a4f3c',
|
'diffusion-readme-css' => '297373eb',
|
||||||
'diffusion-source-css' => '075ba788',
|
'diffusion-source-css' => '68b30fd3',
|
||||||
'diviner-shared-css' => 'aa3656aa',
|
'diviner-shared-css' => 'aa3656aa',
|
||||||
'font-aleo' => '8bdb2835',
|
'font-aleo' => '8bdb2835',
|
||||||
'font-fontawesome' => 'c43323c5',
|
'font-fontawesome' => 'c43323c5',
|
||||||
|
@ -805,7 +805,7 @@ return array(
|
||||||
'phui-action-panel-css' => '91c7b835',
|
'phui-action-panel-css' => '91c7b835',
|
||||||
'phui-badge-view-css' => 'f25c3476',
|
'phui-badge-view-css' => 'f25c3476',
|
||||||
'phui-big-info-view-css' => 'bd903741',
|
'phui-big-info-view-css' => 'bd903741',
|
||||||
'phui-box-css' => '3830ab21',
|
'phui-box-css' => 'b2d49bae',
|
||||||
'phui-button-css' => 'a64a8de6',
|
'phui-button-css' => 'a64a8de6',
|
||||||
'phui-calendar-css' => 'ccabe893',
|
'phui-calendar-css' => 'ccabe893',
|
||||||
'phui-calendar-day-css' => 'd1cf6f93',
|
'phui-calendar-day-css' => 'd1cf6f93',
|
||||||
|
@ -822,23 +822,23 @@ return array(
|
||||||
'phui-fontkit-css' => '9cda225e',
|
'phui-fontkit-css' => '9cda225e',
|
||||||
'phui-form-css' => 'aac1d51d',
|
'phui-form-css' => 'aac1d51d',
|
||||||
'phui-form-view-css' => '4a1a0f5e',
|
'phui-form-view-css' => '4a1a0f5e',
|
||||||
'phui-head-thing-view-css' => '31638812',
|
'phui-head-thing-view-css' => 'fd311e5f',
|
||||||
'phui-header-view-css' => '26cffd3d',
|
'phui-header-view-css' => '230254d3',
|
||||||
'phui-hovercard' => '1bd28176',
|
'phui-hovercard' => '1bd28176',
|
||||||
'phui-hovercard-view-css' => 'de1a2119',
|
'phui-hovercard-view-css' => 'de1a2119',
|
||||||
'phui-icon-set-selector-css' => '1ab67aad',
|
'phui-icon-set-selector-css' => '1ab67aad',
|
||||||
'phui-icon-view-css' => '3f33ab57',
|
'phui-icon-view-css' => '3f33ab57',
|
||||||
'phui-image-mask-css' => 'a8498f9c',
|
'phui-image-mask-css' => 'a8498f9c',
|
||||||
'phui-info-panel-css' => '27ea50a1',
|
'phui-info-panel-css' => '27ea50a1',
|
||||||
'phui-info-view-css' => '6d7c3509',
|
'phui-info-view-css' => '28efab79',
|
||||||
'phui-inline-comment-view-css' => '5953c28e',
|
'phui-inline-comment-view-css' => '5953c28e',
|
||||||
'phui-list-view-css' => '9da2aa00',
|
'phui-list-view-css' => '9da2aa00',
|
||||||
'phui-object-box-css' => '91628842',
|
'phui-object-box-css' => '6b487c57',
|
||||||
'phui-object-item-list-view-css' => '18b2ce8e',
|
'phui-object-item-list-view-css' => '18b2ce8e',
|
||||||
'phui-pager-css' => 'bea33d23',
|
'phui-pager-css' => 'bea33d23',
|
||||||
'phui-pinboard-view-css' => '2495140e',
|
'phui-pinboard-view-css' => '2495140e',
|
||||||
'phui-profile-menu-css' => '7e92a89a',
|
'phui-profile-menu-css' => '7e92a89a',
|
||||||
'phui-property-list-view-css' => 'b12e801c',
|
'phui-property-list-view-css' => '1d42ee7c',
|
||||||
'phui-remarkup-preview-css' => '1a8f2591',
|
'phui-remarkup-preview-css' => '1a8f2591',
|
||||||
'phui-segment-bar-view-css' => '46342871',
|
'phui-segment-bar-view-css' => '46342871',
|
||||||
'phui-spacing-css' => '042804d6',
|
'phui-spacing-css' => '042804d6',
|
||||||
|
@ -846,7 +846,7 @@ return array(
|
||||||
'phui-tag-view-css' => '6bbd83e2',
|
'phui-tag-view-css' => '6bbd83e2',
|
||||||
'phui-theme-css' => '027ba77e',
|
'phui-theme-css' => '027ba77e',
|
||||||
'phui-timeline-view-css' => 'a0173eba',
|
'phui-timeline-view-css' => 'a0173eba',
|
||||||
'phui-two-column-view-css' => 'e6bf86b6',
|
'phui-two-column-view-css' => '37d704f3',
|
||||||
'phui-workboard-color-css' => 'ac6fe6a7',
|
'phui-workboard-color-css' => 'ac6fe6a7',
|
||||||
'phui-workboard-view-css' => 'e6d89647',
|
'phui-workboard-view-css' => 'e6d89647',
|
||||||
'phui-workcard-view-css' => '3646fb96',
|
'phui-workcard-view-css' => '3646fb96',
|
||||||
|
@ -1124,6 +1124,9 @@ return array(
|
||||||
'javelin-util',
|
'javelin-util',
|
||||||
'javelin-uri',
|
'javelin-uri',
|
||||||
),
|
),
|
||||||
|
'3e3b0b76' => array(
|
||||||
|
'phui-inline-comment-view-css',
|
||||||
|
),
|
||||||
'3f5d6dbf' => array(
|
'3f5d6dbf' => array(
|
||||||
'javelin-behavior',
|
'javelin-behavior',
|
||||||
'javelin-dom',
|
'javelin-dom',
|
||||||
|
@ -1791,9 +1794,6 @@ return array(
|
||||||
'javelin-json',
|
'javelin-json',
|
||||||
'phabricator-draggable-list',
|
'phabricator-draggable-list',
|
||||||
),
|
),
|
||||||
'b6b0d1bb' => array(
|
|
||||||
'phui-inline-comment-view-css',
|
|
||||||
),
|
|
||||||
'bae58312' => array(
|
'bae58312' => array(
|
||||||
'javelin-install',
|
'javelin-install',
|
||||||
'javelin-workboard-card',
|
'javelin-workboard-card',
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE {$NAMESPACE}_auth.auth_temporarytoken
|
||||||
|
CHANGE objectPHID tokenResource VARBINARY(64) NOT NULL;
|
2
resources/sql/autopatches/20160316.lfs.02.token.user.sql
Normal file
2
resources/sql/autopatches/20160316.lfs.02.token.user.sql
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE {$NAMESPACE}_auth.auth_temporarytoken
|
||||||
|
ADD userPHID VARBINARY(64);
|
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE {$NAMESPACE}_auth.auth_temporarytoken
|
||||||
|
ADD properties LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT};
|
|
@ -0,0 +1,2 @@
|
||||||
|
UPDATE {$NAMESPACE}_auth.auth_temporarytoken
|
||||||
|
SET properties = '{}' WHERE properties = '';
|
11
resources/sql/autopatches/20160317.lfs.01.ref.sql
Normal file
11
resources/sql/autopatches/20160317.lfs.01.ref.sql
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
CREATE TABLE {$NAMESPACE}_repository.repository_gitlfsref (
|
||||||
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
repositoryPHID VARBINARY(64) NOT NULL,
|
||||||
|
objectHash BINARY(64) NOT NULL,
|
||||||
|
byteSize BIGINT UNSIGNED NOT NULL,
|
||||||
|
authorPHID VARBINARY(64) NOT NULL,
|
||||||
|
filePHID VARBINARY(64) NOT NULL,
|
||||||
|
dateCreated INT UNSIGNED NOT NULL,
|
||||||
|
dateModified INT UNSIGNED NOT NULL,
|
||||||
|
UNIQUE KEY `key_hash` (repositoryPHID, objectHash)
|
||||||
|
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
|
@ -473,7 +473,6 @@ phutil_register_library_map(array(
|
||||||
'DifferentialParseCommitMessageConduitAPIMethod' => 'applications/differential/conduit/DifferentialParseCommitMessageConduitAPIMethod.php',
|
'DifferentialParseCommitMessageConduitAPIMethod' => 'applications/differential/conduit/DifferentialParseCommitMessageConduitAPIMethod.php',
|
||||||
'DifferentialParseRenderTestCase' => 'applications/differential/__tests__/DifferentialParseRenderTestCase.php',
|
'DifferentialParseRenderTestCase' => 'applications/differential/__tests__/DifferentialParseRenderTestCase.php',
|
||||||
'DifferentialPathField' => 'applications/differential/customfield/DifferentialPathField.php',
|
'DifferentialPathField' => 'applications/differential/customfield/DifferentialPathField.php',
|
||||||
'DifferentialPrimaryPaneView' => 'applications/differential/view/DifferentialPrimaryPaneView.php',
|
|
||||||
'DifferentialProjectReviewersField' => 'applications/differential/customfield/DifferentialProjectReviewersField.php',
|
'DifferentialProjectReviewersField' => 'applications/differential/customfield/DifferentialProjectReviewersField.php',
|
||||||
'DifferentialProjectsField' => 'applications/differential/customfield/DifferentialProjectsField.php',
|
'DifferentialProjectsField' => 'applications/differential/customfield/DifferentialProjectsField.php',
|
||||||
'DifferentialQueryConduitAPIMethod' => 'applications/differential/conduit/DifferentialQueryConduitAPIMethod.php',
|
'DifferentialQueryConduitAPIMethod' => 'applications/differential/conduit/DifferentialQueryConduitAPIMethod.php',
|
||||||
|
@ -508,7 +507,6 @@ phutil_register_library_map(array(
|
||||||
'DifferentialRevisionControlSystem' => 'applications/differential/constants/DifferentialRevisionControlSystem.php',
|
'DifferentialRevisionControlSystem' => 'applications/differential/constants/DifferentialRevisionControlSystem.php',
|
||||||
'DifferentialRevisionDependedOnByRevisionEdgeType' => 'applications/differential/edge/DifferentialRevisionDependedOnByRevisionEdgeType.php',
|
'DifferentialRevisionDependedOnByRevisionEdgeType' => 'applications/differential/edge/DifferentialRevisionDependedOnByRevisionEdgeType.php',
|
||||||
'DifferentialRevisionDependsOnRevisionEdgeType' => 'applications/differential/edge/DifferentialRevisionDependsOnRevisionEdgeType.php',
|
'DifferentialRevisionDependsOnRevisionEdgeType' => 'applications/differential/edge/DifferentialRevisionDependsOnRevisionEdgeType.php',
|
||||||
'DifferentialRevisionDetailView' => 'applications/differential/view/DifferentialRevisionDetailView.php',
|
|
||||||
'DifferentialRevisionEditController' => 'applications/differential/controller/DifferentialRevisionEditController.php',
|
'DifferentialRevisionEditController' => 'applications/differential/controller/DifferentialRevisionEditController.php',
|
||||||
'DifferentialRevisionFulltextEngine' => 'applications/differential/search/DifferentialRevisionFulltextEngine.php',
|
'DifferentialRevisionFulltextEngine' => 'applications/differential/search/DifferentialRevisionFulltextEngine.php',
|
||||||
'DifferentialRevisionHasCommitEdgeType' => 'applications/differential/edge/DifferentialRevisionHasCommitEdgeType.php',
|
'DifferentialRevisionHasCommitEdgeType' => 'applications/differential/edge/DifferentialRevisionHasCommitEdgeType.php',
|
||||||
|
@ -635,6 +633,9 @@ phutil_register_library_map(array(
|
||||||
'DiffusionGitBranch' => 'applications/diffusion/data/DiffusionGitBranch.php',
|
'DiffusionGitBranch' => 'applications/diffusion/data/DiffusionGitBranch.php',
|
||||||
'DiffusionGitBranchTestCase' => 'applications/diffusion/data/__tests__/DiffusionGitBranchTestCase.php',
|
'DiffusionGitBranchTestCase' => 'applications/diffusion/data/__tests__/DiffusionGitBranchTestCase.php',
|
||||||
'DiffusionGitFileContentQuery' => 'applications/diffusion/query/filecontent/DiffusionGitFileContentQuery.php',
|
'DiffusionGitFileContentQuery' => 'applications/diffusion/query/filecontent/DiffusionGitFileContentQuery.php',
|
||||||
|
'DiffusionGitLFSAuthenticateWorkflow' => 'applications/diffusion/gitlfs/DiffusionGitLFSAuthenticateWorkflow.php',
|
||||||
|
'DiffusionGitLFSResponse' => 'applications/diffusion/response/DiffusionGitLFSResponse.php',
|
||||||
|
'DiffusionGitLFSTemporaryTokenType' => 'applications/diffusion/gitlfs/DiffusionGitLFSTemporaryTokenType.php',
|
||||||
'DiffusionGitRawDiffQuery' => 'applications/diffusion/query/rawdiff/DiffusionGitRawDiffQuery.php',
|
'DiffusionGitRawDiffQuery' => 'applications/diffusion/query/rawdiff/DiffusionGitRawDiffQuery.php',
|
||||||
'DiffusionGitReceivePackSSHWorkflow' => 'applications/diffusion/ssh/DiffusionGitReceivePackSSHWorkflow.php',
|
'DiffusionGitReceivePackSSHWorkflow' => 'applications/diffusion/ssh/DiffusionGitReceivePackSSHWorkflow.php',
|
||||||
'DiffusionGitRequest' => 'applications/diffusion/request/DiffusionGitRequest.php',
|
'DiffusionGitRequest' => 'applications/diffusion/request/DiffusionGitRequest.php',
|
||||||
|
@ -1818,6 +1819,8 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorAuthNewController' => 'applications/auth/controller/config/PhabricatorAuthNewController.php',
|
'PhabricatorAuthNewController' => 'applications/auth/controller/config/PhabricatorAuthNewController.php',
|
||||||
'PhabricatorAuthOldOAuthRedirectController' => 'applications/auth/controller/PhabricatorAuthOldOAuthRedirectController.php',
|
'PhabricatorAuthOldOAuthRedirectController' => 'applications/auth/controller/PhabricatorAuthOldOAuthRedirectController.php',
|
||||||
'PhabricatorAuthOneTimeLoginController' => 'applications/auth/controller/PhabricatorAuthOneTimeLoginController.php',
|
'PhabricatorAuthOneTimeLoginController' => 'applications/auth/controller/PhabricatorAuthOneTimeLoginController.php',
|
||||||
|
'PhabricatorAuthOneTimeLoginTemporaryTokenType' => 'applications/auth/tokentype/PhabricatorAuthOneTimeLoginTemporaryTokenType.php',
|
||||||
|
'PhabricatorAuthPasswordResetTemporaryTokenType' => 'applications/auth/tokentype/PhabricatorAuthPasswordResetTemporaryTokenType.php',
|
||||||
'PhabricatorAuthProvider' => 'applications/auth/provider/PhabricatorAuthProvider.php',
|
'PhabricatorAuthProvider' => 'applications/auth/provider/PhabricatorAuthProvider.php',
|
||||||
'PhabricatorAuthProviderConfig' => 'applications/auth/storage/PhabricatorAuthProviderConfig.php',
|
'PhabricatorAuthProviderConfig' => 'applications/auth/storage/PhabricatorAuthProviderConfig.php',
|
||||||
'PhabricatorAuthProviderConfigController' => 'applications/auth/controller/config/PhabricatorAuthProviderConfigController.php',
|
'PhabricatorAuthProviderConfigController' => 'applications/auth/controller/config/PhabricatorAuthProviderConfigController.php',
|
||||||
|
@ -1843,9 +1846,12 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorAuthSessionQuery' => 'applications/auth/query/PhabricatorAuthSessionQuery.php',
|
'PhabricatorAuthSessionQuery' => 'applications/auth/query/PhabricatorAuthSessionQuery.php',
|
||||||
'PhabricatorAuthSetupCheck' => 'applications/config/check/PhabricatorAuthSetupCheck.php',
|
'PhabricatorAuthSetupCheck' => 'applications/config/check/PhabricatorAuthSetupCheck.php',
|
||||||
'PhabricatorAuthStartController' => 'applications/auth/controller/PhabricatorAuthStartController.php',
|
'PhabricatorAuthStartController' => 'applications/auth/controller/PhabricatorAuthStartController.php',
|
||||||
|
'PhabricatorAuthTOTPKeyTemporaryTokenType' => 'applications/auth/factor/PhabricatorAuthTOTPKeyTemporaryTokenType.php',
|
||||||
'PhabricatorAuthTemporaryToken' => 'applications/auth/storage/PhabricatorAuthTemporaryToken.php',
|
'PhabricatorAuthTemporaryToken' => 'applications/auth/storage/PhabricatorAuthTemporaryToken.php',
|
||||||
'PhabricatorAuthTemporaryTokenGarbageCollector' => 'applications/auth/garbagecollector/PhabricatorAuthTemporaryTokenGarbageCollector.php',
|
'PhabricatorAuthTemporaryTokenGarbageCollector' => 'applications/auth/garbagecollector/PhabricatorAuthTemporaryTokenGarbageCollector.php',
|
||||||
'PhabricatorAuthTemporaryTokenQuery' => 'applications/auth/query/PhabricatorAuthTemporaryTokenQuery.php',
|
'PhabricatorAuthTemporaryTokenQuery' => 'applications/auth/query/PhabricatorAuthTemporaryTokenQuery.php',
|
||||||
|
'PhabricatorAuthTemporaryTokenType' => 'applications/auth/tokentype/PhabricatorAuthTemporaryTokenType.php',
|
||||||
|
'PhabricatorAuthTemporaryTokenTypeModule' => 'applications/auth/tokentype/PhabricatorAuthTemporaryTokenTypeModule.php',
|
||||||
'PhabricatorAuthTerminateSessionController' => 'applications/auth/controller/PhabricatorAuthTerminateSessionController.php',
|
'PhabricatorAuthTerminateSessionController' => 'applications/auth/controller/PhabricatorAuthTerminateSessionController.php',
|
||||||
'PhabricatorAuthTryFactorAction' => 'applications/auth/action/PhabricatorAuthTryFactorAction.php',
|
'PhabricatorAuthTryFactorAction' => 'applications/auth/action/PhabricatorAuthTryFactorAction.php',
|
||||||
'PhabricatorAuthUnlinkController' => 'applications/auth/controller/PhabricatorAuthUnlinkController.php',
|
'PhabricatorAuthUnlinkController' => 'applications/auth/controller/PhabricatorAuthUnlinkController.php',
|
||||||
|
@ -2349,6 +2355,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorFeedStoryPublisher' => 'applications/feed/PhabricatorFeedStoryPublisher.php',
|
'PhabricatorFeedStoryPublisher' => 'applications/feed/PhabricatorFeedStoryPublisher.php',
|
||||||
'PhabricatorFeedStoryReference' => 'applications/feed/storage/PhabricatorFeedStoryReference.php',
|
'PhabricatorFeedStoryReference' => 'applications/feed/storage/PhabricatorFeedStoryReference.php',
|
||||||
'PhabricatorFile' => 'applications/files/storage/PhabricatorFile.php',
|
'PhabricatorFile' => 'applications/files/storage/PhabricatorFile.php',
|
||||||
|
'PhabricatorFileAccessTemporaryTokenType' => 'applications/files/temporarytoken/PhabricatorFileAccessTemporaryTokenType.php',
|
||||||
'PhabricatorFileBundleLoader' => 'applications/files/query/PhabricatorFileBundleLoader.php',
|
'PhabricatorFileBundleLoader' => 'applications/files/query/PhabricatorFileBundleLoader.php',
|
||||||
'PhabricatorFileChunk' => 'applications/files/storage/PhabricatorFileChunk.php',
|
'PhabricatorFileChunk' => 'applications/files/storage/PhabricatorFileChunk.php',
|
||||||
'PhabricatorFileChunkIterator' => 'applications/files/engine/PhabricatorFileChunkIterator.php',
|
'PhabricatorFileChunkIterator' => 'applications/files/engine/PhabricatorFileChunkIterator.php',
|
||||||
|
@ -2447,6 +2454,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorHandlePool' => 'applications/phid/handle/pool/PhabricatorHandlePool.php',
|
'PhabricatorHandlePool' => 'applications/phid/handle/pool/PhabricatorHandlePool.php',
|
||||||
'PhabricatorHandlePoolTestCase' => 'applications/phid/handle/pool/__tests__/PhabricatorHandlePoolTestCase.php',
|
'PhabricatorHandlePoolTestCase' => 'applications/phid/handle/pool/__tests__/PhabricatorHandlePoolTestCase.php',
|
||||||
'PhabricatorHandleQuery' => 'applications/phid/query/PhabricatorHandleQuery.php',
|
'PhabricatorHandleQuery' => 'applications/phid/query/PhabricatorHandleQuery.php',
|
||||||
|
'PhabricatorHandleRemarkupRule' => 'applications/phid/remarkup/PhabricatorHandleRemarkupRule.php',
|
||||||
'PhabricatorHandlesEditField' => 'applications/transactions/editfield/PhabricatorHandlesEditField.php',
|
'PhabricatorHandlesEditField' => 'applications/transactions/editfield/PhabricatorHandlesEditField.php',
|
||||||
'PhabricatorHarbormasterApplication' => 'applications/harbormaster/application/PhabricatorHarbormasterApplication.php',
|
'PhabricatorHarbormasterApplication' => 'applications/harbormaster/application/PhabricatorHarbormasterApplication.php',
|
||||||
'PhabricatorHarbormasterConfigOptions' => 'applications/harbormaster/config/PhabricatorHarbormasterConfigOptions.php',
|
'PhabricatorHarbormasterConfigOptions' => 'applications/harbormaster/config/PhabricatorHarbormasterConfigOptions.php',
|
||||||
|
@ -2493,6 +2501,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorInvalidConfigSetupCheck' => 'applications/config/check/PhabricatorInvalidConfigSetupCheck.php',
|
'PhabricatorInvalidConfigSetupCheck' => 'applications/config/check/PhabricatorInvalidConfigSetupCheck.php',
|
||||||
'PhabricatorIteratedMD5PasswordHasher' => 'infrastructure/util/password/PhabricatorIteratedMD5PasswordHasher.php',
|
'PhabricatorIteratedMD5PasswordHasher' => 'infrastructure/util/password/PhabricatorIteratedMD5PasswordHasher.php',
|
||||||
'PhabricatorIteratedMD5PasswordHasherTestCase' => 'infrastructure/util/password/__tests__/PhabricatorIteratedMD5PasswordHasherTestCase.php',
|
'PhabricatorIteratedMD5PasswordHasherTestCase' => 'infrastructure/util/password/__tests__/PhabricatorIteratedMD5PasswordHasherTestCase.php',
|
||||||
|
'PhabricatorIteratorFileUploadSource' => 'applications/files/uploadsource/PhabricatorIteratorFileUploadSource.php',
|
||||||
'PhabricatorJIRAAuthProvider' => 'applications/auth/provider/PhabricatorJIRAAuthProvider.php',
|
'PhabricatorJIRAAuthProvider' => 'applications/auth/provider/PhabricatorJIRAAuthProvider.php',
|
||||||
'PhabricatorJavelinLinter' => 'infrastructure/lint/linter/PhabricatorJavelinLinter.php',
|
'PhabricatorJavelinLinter' => 'infrastructure/lint/linter/PhabricatorJavelinLinter.php',
|
||||||
'PhabricatorJiraIssueHasObjectEdgeType' => 'applications/doorkeeper/edge/PhabricatorJiraIssueHasObjectEdgeType.php',
|
'PhabricatorJiraIssueHasObjectEdgeType' => 'applications/doorkeeper/edge/PhabricatorJiraIssueHasObjectEdgeType.php',
|
||||||
|
@ -2669,6 +2678,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorNotificationsApplication' => 'applications/notification/application/PhabricatorNotificationsApplication.php',
|
'PhabricatorNotificationsApplication' => 'applications/notification/application/PhabricatorNotificationsApplication.php',
|
||||||
'PhabricatorNuanceApplication' => 'applications/nuance/application/PhabricatorNuanceApplication.php',
|
'PhabricatorNuanceApplication' => 'applications/nuance/application/PhabricatorNuanceApplication.php',
|
||||||
'PhabricatorOAuth1AuthProvider' => 'applications/auth/provider/PhabricatorOAuth1AuthProvider.php',
|
'PhabricatorOAuth1AuthProvider' => 'applications/auth/provider/PhabricatorOAuth1AuthProvider.php',
|
||||||
|
'PhabricatorOAuth1SecretTemporaryTokenType' => 'applications/auth/provider/PhabricatorOAuth1SecretTemporaryTokenType.php',
|
||||||
'PhabricatorOAuth2AuthProvider' => 'applications/auth/provider/PhabricatorOAuth2AuthProvider.php',
|
'PhabricatorOAuth2AuthProvider' => 'applications/auth/provider/PhabricatorOAuth2AuthProvider.php',
|
||||||
'PhabricatorOAuthAuthProvider' => 'applications/auth/provider/PhabricatorOAuthAuthProvider.php',
|
'PhabricatorOAuthAuthProvider' => 'applications/auth/provider/PhabricatorOAuthAuthProvider.php',
|
||||||
'PhabricatorOAuthClientAuthorization' => 'applications/oauthserver/storage/PhabricatorOAuthClientAuthorization.php',
|
'PhabricatorOAuthClientAuthorization' => 'applications/oauthserver/storage/PhabricatorOAuthClientAuthorization.php',
|
||||||
|
@ -3091,6 +3101,8 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorRepositoryEngine' => 'applications/repository/engine/PhabricatorRepositoryEngine.php',
|
'PhabricatorRepositoryEngine' => 'applications/repository/engine/PhabricatorRepositoryEngine.php',
|
||||||
'PhabricatorRepositoryGitCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/PhabricatorRepositoryGitCommitChangeParserWorker.php',
|
'PhabricatorRepositoryGitCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/PhabricatorRepositoryGitCommitChangeParserWorker.php',
|
||||||
'PhabricatorRepositoryGitCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/PhabricatorRepositoryGitCommitMessageParserWorker.php',
|
'PhabricatorRepositoryGitCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/PhabricatorRepositoryGitCommitMessageParserWorker.php',
|
||||||
|
'PhabricatorRepositoryGitLFSRef' => 'applications/repository/storage/PhabricatorRepositoryGitLFSRef.php',
|
||||||
|
'PhabricatorRepositoryGitLFSRefQuery' => 'applications/repository/query/PhabricatorRepositoryGitLFSRefQuery.php',
|
||||||
'PhabricatorRepositoryGraphCache' => 'applications/repository/graphcache/PhabricatorRepositoryGraphCache.php',
|
'PhabricatorRepositoryGraphCache' => 'applications/repository/graphcache/PhabricatorRepositoryGraphCache.php',
|
||||||
'PhabricatorRepositoryGraphStream' => 'applications/repository/daemon/PhabricatorRepositoryGraphStream.php',
|
'PhabricatorRepositoryGraphStream' => 'applications/repository/daemon/PhabricatorRepositoryGraphStream.php',
|
||||||
'PhabricatorRepositoryManagementCacheWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementCacheWorkflow.php',
|
'PhabricatorRepositoryManagementCacheWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementCacheWorkflow.php',
|
||||||
|
@ -4580,7 +4592,6 @@ phutil_register_library_map(array(
|
||||||
'DifferentialParseCommitMessageConduitAPIMethod' => 'DifferentialConduitAPIMethod',
|
'DifferentialParseCommitMessageConduitAPIMethod' => 'DifferentialConduitAPIMethod',
|
||||||
'DifferentialParseRenderTestCase' => 'PhabricatorTestCase',
|
'DifferentialParseRenderTestCase' => 'PhabricatorTestCase',
|
||||||
'DifferentialPathField' => 'DifferentialCustomField',
|
'DifferentialPathField' => 'DifferentialCustomField',
|
||||||
'DifferentialPrimaryPaneView' => 'AphrontView',
|
|
||||||
'DifferentialProjectReviewersField' => 'DifferentialCustomField',
|
'DifferentialProjectReviewersField' => 'DifferentialCustomField',
|
||||||
'DifferentialProjectsField' => 'DifferentialCoreCustomField',
|
'DifferentialProjectsField' => 'DifferentialCoreCustomField',
|
||||||
'DifferentialQueryConduitAPIMethod' => 'DifferentialConduitAPIMethod',
|
'DifferentialQueryConduitAPIMethod' => 'DifferentialConduitAPIMethod',
|
||||||
|
@ -4630,7 +4641,6 @@ phutil_register_library_map(array(
|
||||||
'DifferentialRevisionControlSystem' => 'Phobject',
|
'DifferentialRevisionControlSystem' => 'Phobject',
|
||||||
'DifferentialRevisionDependedOnByRevisionEdgeType' => 'PhabricatorEdgeType',
|
'DifferentialRevisionDependedOnByRevisionEdgeType' => 'PhabricatorEdgeType',
|
||||||
'DifferentialRevisionDependsOnRevisionEdgeType' => 'PhabricatorEdgeType',
|
'DifferentialRevisionDependsOnRevisionEdgeType' => 'PhabricatorEdgeType',
|
||||||
'DifferentialRevisionDetailView' => 'AphrontView',
|
|
||||||
'DifferentialRevisionEditController' => 'DifferentialController',
|
'DifferentialRevisionEditController' => 'DifferentialController',
|
||||||
'DifferentialRevisionFulltextEngine' => 'PhabricatorFulltextEngine',
|
'DifferentialRevisionFulltextEngine' => 'PhabricatorFulltextEngine',
|
||||||
'DifferentialRevisionHasCommitEdgeType' => 'PhabricatorEdgeType',
|
'DifferentialRevisionHasCommitEdgeType' => 'PhabricatorEdgeType',
|
||||||
|
@ -4757,6 +4767,9 @@ phutil_register_library_map(array(
|
||||||
'DiffusionGitBranch' => 'Phobject',
|
'DiffusionGitBranch' => 'Phobject',
|
||||||
'DiffusionGitBranchTestCase' => 'PhabricatorTestCase',
|
'DiffusionGitBranchTestCase' => 'PhabricatorTestCase',
|
||||||
'DiffusionGitFileContentQuery' => 'DiffusionFileContentQuery',
|
'DiffusionGitFileContentQuery' => 'DiffusionFileContentQuery',
|
||||||
|
'DiffusionGitLFSAuthenticateWorkflow' => 'DiffusionGitSSHWorkflow',
|
||||||
|
'DiffusionGitLFSResponse' => 'AphrontResponse',
|
||||||
|
'DiffusionGitLFSTemporaryTokenType' => 'PhabricatorAuthTemporaryTokenType',
|
||||||
'DiffusionGitRawDiffQuery' => 'DiffusionRawDiffQuery',
|
'DiffusionGitRawDiffQuery' => 'DiffusionRawDiffQuery',
|
||||||
'DiffusionGitReceivePackSSHWorkflow' => 'DiffusionGitSSHWorkflow',
|
'DiffusionGitReceivePackSSHWorkflow' => 'DiffusionGitSSHWorkflow',
|
||||||
'DiffusionGitRequest' => 'DiffusionRequest',
|
'DiffusionGitRequest' => 'DiffusionRequest',
|
||||||
|
@ -6127,6 +6140,8 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorAuthNewController' => 'PhabricatorAuthProviderConfigController',
|
'PhabricatorAuthNewController' => 'PhabricatorAuthProviderConfigController',
|
||||||
'PhabricatorAuthOldOAuthRedirectController' => 'PhabricatorAuthController',
|
'PhabricatorAuthOldOAuthRedirectController' => 'PhabricatorAuthController',
|
||||||
'PhabricatorAuthOneTimeLoginController' => 'PhabricatorAuthController',
|
'PhabricatorAuthOneTimeLoginController' => 'PhabricatorAuthController',
|
||||||
|
'PhabricatorAuthOneTimeLoginTemporaryTokenType' => 'PhabricatorAuthTemporaryTokenType',
|
||||||
|
'PhabricatorAuthPasswordResetTemporaryTokenType' => 'PhabricatorAuthTemporaryTokenType',
|
||||||
'PhabricatorAuthProvider' => 'Phobject',
|
'PhabricatorAuthProvider' => 'Phobject',
|
||||||
'PhabricatorAuthProviderConfig' => array(
|
'PhabricatorAuthProviderConfig' => array(
|
||||||
'PhabricatorAuthDAO',
|
'PhabricatorAuthDAO',
|
||||||
|
@ -6163,12 +6178,15 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorAuthSessionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'PhabricatorAuthSessionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
'PhabricatorAuthSetupCheck' => 'PhabricatorSetupCheck',
|
'PhabricatorAuthSetupCheck' => 'PhabricatorSetupCheck',
|
||||||
'PhabricatorAuthStartController' => 'PhabricatorAuthController',
|
'PhabricatorAuthStartController' => 'PhabricatorAuthController',
|
||||||
|
'PhabricatorAuthTOTPKeyTemporaryTokenType' => 'PhabricatorAuthTemporaryTokenType',
|
||||||
'PhabricatorAuthTemporaryToken' => array(
|
'PhabricatorAuthTemporaryToken' => array(
|
||||||
'PhabricatorAuthDAO',
|
'PhabricatorAuthDAO',
|
||||||
'PhabricatorPolicyInterface',
|
'PhabricatorPolicyInterface',
|
||||||
),
|
),
|
||||||
'PhabricatorAuthTemporaryTokenGarbageCollector' => 'PhabricatorGarbageCollector',
|
'PhabricatorAuthTemporaryTokenGarbageCollector' => 'PhabricatorGarbageCollector',
|
||||||
'PhabricatorAuthTemporaryTokenQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'PhabricatorAuthTemporaryTokenQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
|
'PhabricatorAuthTemporaryTokenType' => 'Phobject',
|
||||||
|
'PhabricatorAuthTemporaryTokenTypeModule' => 'PhabricatorConfigModule',
|
||||||
'PhabricatorAuthTerminateSessionController' => 'PhabricatorAuthController',
|
'PhabricatorAuthTerminateSessionController' => 'PhabricatorAuthController',
|
||||||
'PhabricatorAuthTryFactorAction' => 'PhabricatorSystemAction',
|
'PhabricatorAuthTryFactorAction' => 'PhabricatorSystemAction',
|
||||||
'PhabricatorAuthUnlinkController' => 'PhabricatorAuthController',
|
'PhabricatorAuthUnlinkController' => 'PhabricatorAuthController',
|
||||||
|
@ -6763,6 +6781,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorPolicyInterface',
|
'PhabricatorPolicyInterface',
|
||||||
'PhabricatorDestructibleInterface',
|
'PhabricatorDestructibleInterface',
|
||||||
),
|
),
|
||||||
|
'PhabricatorFileAccessTemporaryTokenType' => 'PhabricatorAuthTemporaryTokenType',
|
||||||
'PhabricatorFileBundleLoader' => 'Phobject',
|
'PhabricatorFileBundleLoader' => 'Phobject',
|
||||||
'PhabricatorFileChunk' => array(
|
'PhabricatorFileChunk' => array(
|
||||||
'PhabricatorFileDAO',
|
'PhabricatorFileDAO',
|
||||||
|
@ -6882,6 +6901,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorHandlePool' => 'Phobject',
|
'PhabricatorHandlePool' => 'Phobject',
|
||||||
'PhabricatorHandlePoolTestCase' => 'PhabricatorTestCase',
|
'PhabricatorHandlePoolTestCase' => 'PhabricatorTestCase',
|
||||||
'PhabricatorHandleQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'PhabricatorHandleQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
|
'PhabricatorHandleRemarkupRule' => 'PhutilRemarkupRule',
|
||||||
'PhabricatorHandlesEditField' => 'PhabricatorPHIDListEditField',
|
'PhabricatorHandlesEditField' => 'PhabricatorPHIDListEditField',
|
||||||
'PhabricatorHarbormasterApplication' => 'PhabricatorApplication',
|
'PhabricatorHarbormasterApplication' => 'PhabricatorApplication',
|
||||||
'PhabricatorHarbormasterConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
'PhabricatorHarbormasterConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
||||||
|
@ -6928,6 +6948,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorInvalidConfigSetupCheck' => 'PhabricatorSetupCheck',
|
'PhabricatorInvalidConfigSetupCheck' => 'PhabricatorSetupCheck',
|
||||||
'PhabricatorIteratedMD5PasswordHasher' => 'PhabricatorPasswordHasher',
|
'PhabricatorIteratedMD5PasswordHasher' => 'PhabricatorPasswordHasher',
|
||||||
'PhabricatorIteratedMD5PasswordHasherTestCase' => 'PhabricatorTestCase',
|
'PhabricatorIteratedMD5PasswordHasherTestCase' => 'PhabricatorTestCase',
|
||||||
|
'PhabricatorIteratorFileUploadSource' => 'PhabricatorFileUploadSource',
|
||||||
'PhabricatorJIRAAuthProvider' => 'PhabricatorOAuth1AuthProvider',
|
'PhabricatorJIRAAuthProvider' => 'PhabricatorOAuth1AuthProvider',
|
||||||
'PhabricatorJavelinLinter' => 'ArcanistLinter',
|
'PhabricatorJavelinLinter' => 'ArcanistLinter',
|
||||||
'PhabricatorJiraIssueHasObjectEdgeType' => 'PhabricatorEdgeType',
|
'PhabricatorJiraIssueHasObjectEdgeType' => 'PhabricatorEdgeType',
|
||||||
|
@ -7116,6 +7137,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorNotificationsApplication' => 'PhabricatorApplication',
|
'PhabricatorNotificationsApplication' => 'PhabricatorApplication',
|
||||||
'PhabricatorNuanceApplication' => 'PhabricatorApplication',
|
'PhabricatorNuanceApplication' => 'PhabricatorApplication',
|
||||||
'PhabricatorOAuth1AuthProvider' => 'PhabricatorOAuthAuthProvider',
|
'PhabricatorOAuth1AuthProvider' => 'PhabricatorOAuthAuthProvider',
|
||||||
|
'PhabricatorOAuth1SecretTemporaryTokenType' => 'PhabricatorAuthTemporaryTokenType',
|
||||||
'PhabricatorOAuth2AuthProvider' => 'PhabricatorOAuthAuthProvider',
|
'PhabricatorOAuth2AuthProvider' => 'PhabricatorOAuthAuthProvider',
|
||||||
'PhabricatorOAuthAuthProvider' => 'PhabricatorAuthProvider',
|
'PhabricatorOAuthAuthProvider' => 'PhabricatorAuthProvider',
|
||||||
'PhabricatorOAuthClientAuthorization' => array(
|
'PhabricatorOAuthClientAuthorization' => array(
|
||||||
|
@ -7647,6 +7669,12 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorRepositoryEngine' => 'Phobject',
|
'PhabricatorRepositoryEngine' => 'Phobject',
|
||||||
'PhabricatorRepositoryGitCommitChangeParserWorker' => 'PhabricatorRepositoryCommitChangeParserWorker',
|
'PhabricatorRepositoryGitCommitChangeParserWorker' => 'PhabricatorRepositoryCommitChangeParserWorker',
|
||||||
'PhabricatorRepositoryGitCommitMessageParserWorker' => 'PhabricatorRepositoryCommitMessageParserWorker',
|
'PhabricatorRepositoryGitCommitMessageParserWorker' => 'PhabricatorRepositoryCommitMessageParserWorker',
|
||||||
|
'PhabricatorRepositoryGitLFSRef' => array(
|
||||||
|
'PhabricatorRepositoryDAO',
|
||||||
|
'PhabricatorPolicyInterface',
|
||||||
|
'PhabricatorDestructibleInterface',
|
||||||
|
),
|
||||||
|
'PhabricatorRepositoryGitLFSRefQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
'PhabricatorRepositoryGraphCache' => 'Phobject',
|
'PhabricatorRepositoryGraphCache' => 'Phobject',
|
||||||
'PhabricatorRepositoryGraphStream' => 'Phobject',
|
'PhabricatorRepositoryGraphStream' => 'Phobject',
|
||||||
'PhabricatorRepositoryManagementCacheWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
'PhabricatorRepositoryManagementCacheWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||||
|
|
|
@ -25,12 +25,19 @@ class AphrontDefaultApplicationConfiguration
|
||||||
$content_type = idx($_SERVER, 'CONTENT_TYPE');
|
$content_type = idx($_SERVER, 'CONTENT_TYPE');
|
||||||
$is_form_data = preg_match('@^multipart/form-data@i', $content_type);
|
$is_form_data = preg_match('@^multipart/form-data@i', $content_type);
|
||||||
|
|
||||||
|
$request_method = idx($_SERVER, 'REQUEST_METHOD');
|
||||||
|
if ($request_method === 'PUT') {
|
||||||
|
// For PUT requests, do nothing: in particular, do NOT read input. This
|
||||||
|
// allows us to stream input later and process very large PUT requests,
|
||||||
|
// like those coming from Git LFS.
|
||||||
|
} else {
|
||||||
$raw_input = PhabricatorStartup::getRawInput();
|
$raw_input = PhabricatorStartup::getRawInput();
|
||||||
if (strlen($raw_input) && !$is_form_data) {
|
if (strlen($raw_input) && !$is_form_data) {
|
||||||
$data += $parser->parseQueryString($raw_input);
|
$data += $parser->parseQueryString($raw_input);
|
||||||
} else if ($_POST) {
|
} else if ($_POST) {
|
||||||
$data += $_POST;
|
$data += $_POST;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$data += $parser->parseQueryString(idx($_SERVER, 'QUERY_STRING', ''));
|
$data += $parser->parseQueryString(idx($_SERVER, 'QUERY_STRING', ''));
|
||||||
|
|
||||||
|
|
|
@ -37,9 +37,11 @@ final class PhabricatorAuditCommitStatusConstants extends Phobject {
|
||||||
$color = 'red';
|
$color = 'red';
|
||||||
break;
|
break;
|
||||||
case self::NEEDS_AUDIT:
|
case self::NEEDS_AUDIT:
|
||||||
case self::PARTIALLY_AUDITED:
|
|
||||||
$color = 'orange';
|
$color = 'orange';
|
||||||
break;
|
break;
|
||||||
|
case self::PARTIALLY_AUDITED:
|
||||||
|
$color = 'yellow';
|
||||||
|
break;
|
||||||
case self::FULLY_AUDITED:
|
case self::FULLY_AUDITED:
|
||||||
$color = 'green';
|
$color = 'green';
|
||||||
break;
|
break;
|
||||||
|
@ -53,11 +55,11 @@ final class PhabricatorAuditCommitStatusConstants extends Phobject {
|
||||||
public static function getStatusIcon($code) {
|
public static function getStatusIcon($code) {
|
||||||
switch ($code) {
|
switch ($code) {
|
||||||
case self::CONCERN_RAISED:
|
case self::CONCERN_RAISED:
|
||||||
$icon = 'fa-exclamation-triangle';
|
$icon = 'fa-exclamation-circle';
|
||||||
break;
|
break;
|
||||||
case self::NEEDS_AUDIT:
|
case self::NEEDS_AUDIT:
|
||||||
case self::PARTIALLY_AUDITED:
|
case self::PARTIALLY_AUDITED:
|
||||||
$icon = 'fa-exclamation-triangle';
|
$icon = 'fa-exclamation-circle';
|
||||||
break;
|
break;
|
||||||
case self::FULLY_AUDITED:
|
case self::FULLY_AUDITED:
|
||||||
$icon = 'fa-check';
|
$icon = 'fa-check';
|
||||||
|
|
|
@ -117,12 +117,37 @@ final class PhabricatorAuditTransaction
|
||||||
return 'red';
|
return 'red';
|
||||||
case PhabricatorAuditActionConstants::ACCEPT:
|
case PhabricatorAuditActionConstants::ACCEPT:
|
||||||
return 'green';
|
return 'green';
|
||||||
|
case PhabricatorAuditActionConstants::RESIGN:
|
||||||
|
return 'black';
|
||||||
|
case PhabricatorAuditActionConstants::CLOSE:
|
||||||
|
return 'indigo';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent::getColor();
|
return parent::getColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getIcon() {
|
||||||
|
|
||||||
|
$type = $this->getTransactionType();
|
||||||
|
|
||||||
|
switch ($type) {
|
||||||
|
case PhabricatorAuditActionConstants::ACTION:
|
||||||
|
switch ($this->getNewValue()) {
|
||||||
|
case PhabricatorAuditActionConstants::CONCERN:
|
||||||
|
return 'fa-exclamation-circle';
|
||||||
|
case PhabricatorAuditActionConstants::ACCEPT:
|
||||||
|
return 'fa-check';
|
||||||
|
case PhabricatorAuditActionConstants::RESIGN:
|
||||||
|
return 'fa-plane';
|
||||||
|
case PhabricatorAuditActionConstants::CLOSE:
|
||||||
|
return 'fa-check';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::getIcon();
|
||||||
|
}
|
||||||
|
|
||||||
public function getTitle() {
|
public function getTitle() {
|
||||||
$old = $this->getOldValue();
|
$old = $this->getOldValue();
|
||||||
$new = $this->getNewValue();
|
$new = $this->getNewValue();
|
||||||
|
|
|
@ -105,23 +105,17 @@ final class PhabricatorAuthOneTimeLoginController
|
||||||
// the link in the "Welcome" email is good enough, without requiring users
|
// the link in the "Welcome" email is good enough, without requiring users
|
||||||
// to go through a second round of email verification.
|
// to go through a second round of email verification.
|
||||||
|
|
||||||
|
$editor = id(new PhabricatorUserEditor())
|
||||||
|
->setActor($target_user);
|
||||||
|
|
||||||
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
||||||
// Nuke the token and all other outstanding password reset tokens.
|
// Nuke the token and all other outstanding password reset tokens.
|
||||||
// There is no particular security benefit to destroying them all, but
|
// There is no particular security benefit to destroying them all, but
|
||||||
// it should reduce HackerOne reports of nebulous harm.
|
// it should reduce HackerOne reports of nebulous harm.
|
||||||
|
$editor->revokePasswordResetLinks($target_user);
|
||||||
PhabricatorAuthTemporaryToken::revokeTokens(
|
|
||||||
$target_user,
|
|
||||||
array($target_user->getPHID()),
|
|
||||||
array(
|
|
||||||
PhabricatorAuthSessionEngine::ONETIME_TEMPORARY_TOKEN_TYPE,
|
|
||||||
PhabricatorAuthSessionEngine::PASSWORD_TEMPORARY_TOKEN_TYPE,
|
|
||||||
));
|
|
||||||
|
|
||||||
if ($target_email) {
|
if ($target_email) {
|
||||||
id(new PhabricatorUserEditor())
|
$editor->verifyEmail($target_user, $target_email);
|
||||||
->setActor($target_user)
|
|
||||||
->verifyEmail($target_user, $target_email);
|
|
||||||
}
|
}
|
||||||
unset($unguarded);
|
unset($unguarded);
|
||||||
|
|
||||||
|
@ -133,12 +127,13 @@ final class PhabricatorAuthOneTimeLoginController
|
||||||
// We're going to let the user reset their password without knowing
|
// We're going to let the user reset their password without knowing
|
||||||
// the old one. Generate a one-time token for that.
|
// the old one. Generate a one-time token for that.
|
||||||
$key = Filesystem::readRandomCharacters(16);
|
$key = Filesystem::readRandomCharacters(16);
|
||||||
|
$password_type =
|
||||||
|
PhabricatorAuthPasswordResetTemporaryTokenType::TOKENTYPE;
|
||||||
|
|
||||||
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
||||||
id(new PhabricatorAuthTemporaryToken())
|
id(new PhabricatorAuthTemporaryToken())
|
||||||
->setObjectPHID($target_user->getPHID())
|
->setTokenResource($target_user->getPHID())
|
||||||
->setTokenType(
|
->setTokenType($password_type)
|
||||||
PhabricatorAuthSessionEngine::PASSWORD_TEMPORARY_TOKEN_TYPE)
|
|
||||||
->setTokenExpires(time() + phutil_units('1 hour in seconds'))
|
->setTokenExpires(time() + phutil_units('1 hour in seconds'))
|
||||||
->setTokenCode(PhabricatorHash::digest($key))
|
->setTokenCode(PhabricatorHash::digest($key))
|
||||||
->save();
|
->save();
|
||||||
|
|
|
@ -11,7 +11,7 @@ final class PhabricatorAuthRevokeTokenController
|
||||||
|
|
||||||
$query = id(new PhabricatorAuthTemporaryTokenQuery())
|
$query = id(new PhabricatorAuthTemporaryTokenQuery())
|
||||||
->setViewer($viewer)
|
->setViewer($viewer)
|
||||||
->withObjectPHIDs(array($viewer->getPHID()));
|
->withTokenResources(array($viewer->getPHID()));
|
||||||
if (!$is_all) {
|
if (!$is_all) {
|
||||||
$query->withIDs(array($id));
|
$query->withIDs(array($id));
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,17 +39,6 @@ final class PhabricatorAuthSessionEngine extends Phobject {
|
||||||
const KIND_UNKNOWN = '?';
|
const KIND_UNKNOWN = '?';
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Temporary tokens for one time logins.
|
|
||||||
*/
|
|
||||||
const ONETIME_TEMPORARY_TOKEN_TYPE = 'login:onetime';
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Temporary tokens for password recovery after one time login.
|
|
||||||
*/
|
|
||||||
const PASSWORD_TEMPORARY_TOKEN_TYPE = 'login:password';
|
|
||||||
|
|
||||||
const ONETIME_RECOVER = 'recover';
|
const ONETIME_RECOVER = 'recover';
|
||||||
const ONETIME_RESET = 'reset';
|
const ONETIME_RESET = 'reset';
|
||||||
const ONETIME_WELCOME = 'welcome';
|
const ONETIME_WELCOME = 'welcome';
|
||||||
|
@ -642,11 +631,12 @@ final class PhabricatorAuthSessionEngine extends Phobject {
|
||||||
|
|
||||||
$key = Filesystem::readRandomCharacters(32);
|
$key = Filesystem::readRandomCharacters(32);
|
||||||
$key_hash = $this->getOneTimeLoginKeyHash($user, $email, $key);
|
$key_hash = $this->getOneTimeLoginKeyHash($user, $email, $key);
|
||||||
|
$onetime_type = PhabricatorAuthOneTimeLoginTemporaryTokenType::TOKENTYPE;
|
||||||
|
|
||||||
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
||||||
id(new PhabricatorAuthTemporaryToken())
|
id(new PhabricatorAuthTemporaryToken())
|
||||||
->setObjectPHID($user->getPHID())
|
->setTokenResource($user->getPHID())
|
||||||
->setTokenType(self::ONETIME_TEMPORARY_TOKEN_TYPE)
|
->setTokenType($onetime_type)
|
||||||
->setTokenExpires(time() + phutil_units('1 day in seconds'))
|
->setTokenExpires(time() + phutil_units('1 day in seconds'))
|
||||||
->setTokenCode($key_hash)
|
->setTokenCode($key_hash)
|
||||||
->save();
|
->save();
|
||||||
|
@ -685,11 +675,12 @@ final class PhabricatorAuthSessionEngine extends Phobject {
|
||||||
$key = null) {
|
$key = null) {
|
||||||
|
|
||||||
$key_hash = $this->getOneTimeLoginKeyHash($user, $email, $key);
|
$key_hash = $this->getOneTimeLoginKeyHash($user, $email, $key);
|
||||||
|
$onetime_type = PhabricatorAuthOneTimeLoginTemporaryTokenType::TOKENTYPE;
|
||||||
|
|
||||||
return id(new PhabricatorAuthTemporaryTokenQuery())
|
return id(new PhabricatorAuthTemporaryTokenQuery())
|
||||||
->setViewer($user)
|
->setViewer($user)
|
||||||
->withObjectPHIDs(array($user->getPHID()))
|
->withTokenResources(array($user->getPHID()))
|
||||||
->withTokenTypes(array(self::ONETIME_TEMPORARY_TOKEN_TYPE))
|
->withTokenTypes(array($onetime_type))
|
||||||
->withTokenCodes(array($key_hash))
|
->withTokenCodes(array($key_hash))
|
||||||
->withExpired(false)
|
->withExpired(false)
|
||||||
->executeOne();
|
->executeOne();
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorAuthTOTPKeyTemporaryTokenType
|
||||||
|
extends PhabricatorAuthTemporaryTokenType {
|
||||||
|
|
||||||
|
const TOKENTYPE = 'mfa:totp:key';
|
||||||
|
|
||||||
|
public function getTokenTypeDisplayName() {
|
||||||
|
return pht('TOTP Synchronization');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTokenReadableTypeName(
|
||||||
|
PhabricatorAuthTemporaryToken $token) {
|
||||||
|
return pht('TOTP Sync Token');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2,8 +2,6 @@
|
||||||
|
|
||||||
final class PhabricatorTOTPAuthFactor extends PhabricatorAuthFactor {
|
final class PhabricatorTOTPAuthFactor extends PhabricatorAuthFactor {
|
||||||
|
|
||||||
const TEMPORARY_TOKEN_TYPE = 'mfa:totp:key';
|
|
||||||
|
|
||||||
public function getFactorKey() {
|
public function getFactorKey() {
|
||||||
return 'totp';
|
return 'totp';
|
||||||
}
|
}
|
||||||
|
@ -24,6 +22,8 @@ final class PhabricatorTOTPAuthFactor extends PhabricatorAuthFactor {
|
||||||
AphrontRequest $request,
|
AphrontRequest $request,
|
||||||
PhabricatorUser $user) {
|
PhabricatorUser $user) {
|
||||||
|
|
||||||
|
$totp_token_type = PhabricatorAuthTOTPKeyTemporaryTokenType::TOKENTYPE;
|
||||||
|
|
||||||
$key = $request->getStr('totpkey');
|
$key = $request->getStr('totpkey');
|
||||||
if (strlen($key)) {
|
if (strlen($key)) {
|
||||||
// If the user is providing a key, make sure it's a key we generated.
|
// If the user is providing a key, make sure it's a key we generated.
|
||||||
|
@ -36,8 +36,8 @@ final class PhabricatorTOTPAuthFactor extends PhabricatorAuthFactor {
|
||||||
|
|
||||||
$temporary_token = id(new PhabricatorAuthTemporaryTokenQuery())
|
$temporary_token = id(new PhabricatorAuthTemporaryTokenQuery())
|
||||||
->setViewer($user)
|
->setViewer($user)
|
||||||
->withObjectPHIDs(array($user->getPHID()))
|
->withTokenResources(array($user->getPHID()))
|
||||||
->withTokenTypes(array(self::TEMPORARY_TOKEN_TYPE))
|
->withTokenTypes(array($totp_token_type))
|
||||||
->withExpired(false)
|
->withExpired(false)
|
||||||
->withTokenCodes(array(PhabricatorHash::digest($key)))
|
->withTokenCodes(array(PhabricatorHash::digest($key)))
|
||||||
->executeOne();
|
->executeOne();
|
||||||
|
@ -55,8 +55,8 @@ final class PhabricatorTOTPAuthFactor extends PhabricatorAuthFactor {
|
||||||
|
|
||||||
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
||||||
id(new PhabricatorAuthTemporaryToken())
|
id(new PhabricatorAuthTemporaryToken())
|
||||||
->setObjectPHID($user->getPHID())
|
->setTokenResource($user->getPHID())
|
||||||
->setTokenType(self::TEMPORARY_TOKEN_TYPE)
|
->setTokenType($totp_token_type)
|
||||||
->setTokenExpires(time() + phutil_units('1 hour in seconds'))
|
->setTokenExpires(time() + phutil_units('1 hour in seconds'))
|
||||||
->setTokenCode(PhabricatorHash::digest($key))
|
->setTokenCode(PhabricatorHash::digest($key))
|
||||||
->save();
|
->save();
|
||||||
|
|
|
@ -9,8 +9,6 @@ abstract class PhabricatorOAuth1AuthProvider
|
||||||
const PROPERTY_CONSUMER_SECRET = 'oauth1:consumer:secret';
|
const PROPERTY_CONSUMER_SECRET = 'oauth1:consumer:secret';
|
||||||
const PROPERTY_PRIVATE_KEY = 'oauth1:private:key';
|
const PROPERTY_PRIVATE_KEY = 'oauth1:private:key';
|
||||||
|
|
||||||
const TEMPORARY_TOKEN_TYPE = 'oauth1:request:secret';
|
|
||||||
|
|
||||||
protected function getIDKey() {
|
protected function getIDKey() {
|
||||||
return self::PROPERTY_CONSUMER_KEY;
|
return self::PROPERTY_CONSUMER_KEY;
|
||||||
}
|
}
|
||||||
|
@ -215,13 +213,14 @@ abstract class PhabricatorOAuth1AuthProvider
|
||||||
|
|
||||||
|
|
||||||
private function saveHandshakeTokenSecret($client_code, $secret) {
|
private function saveHandshakeTokenSecret($client_code, $secret) {
|
||||||
|
$secret_type = PhabricatorOAuth1SecretTemporaryTokenType::TOKENTYPE;
|
||||||
$key = $this->getHandshakeTokenKeyFromClientCode($client_code);
|
$key = $this->getHandshakeTokenKeyFromClientCode($client_code);
|
||||||
$type = $this->getTemporaryTokenType(self::TEMPORARY_TOKEN_TYPE);
|
$type = $this->getTemporaryTokenType($secret_type);
|
||||||
|
|
||||||
// Wipe out an existing token, if one exists.
|
// Wipe out an existing token, if one exists.
|
||||||
$token = id(new PhabricatorAuthTemporaryTokenQuery())
|
$token = id(new PhabricatorAuthTemporaryTokenQuery())
|
||||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||||
->withObjectPHIDs(array($key))
|
->withTokenResources(array($key))
|
||||||
->withTokenTypes(array($type))
|
->withTokenTypes(array($type))
|
||||||
->executeOne();
|
->executeOne();
|
||||||
if ($token) {
|
if ($token) {
|
||||||
|
@ -230,7 +229,7 @@ abstract class PhabricatorOAuth1AuthProvider
|
||||||
|
|
||||||
// Save the new secret.
|
// Save the new secret.
|
||||||
id(new PhabricatorAuthTemporaryToken())
|
id(new PhabricatorAuthTemporaryToken())
|
||||||
->setObjectPHID($key)
|
->setTokenResource($key)
|
||||||
->setTokenType($type)
|
->setTokenType($type)
|
||||||
->setTokenExpires(time() + phutil_units('1 hour in seconds'))
|
->setTokenExpires(time() + phutil_units('1 hour in seconds'))
|
||||||
->setTokenCode($secret)
|
->setTokenCode($secret)
|
||||||
|
@ -238,12 +237,13 @@ abstract class PhabricatorOAuth1AuthProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
private function loadHandshakeTokenSecret($client_code) {
|
private function loadHandshakeTokenSecret($client_code) {
|
||||||
|
$secret_type = PhabricatorOAuth1SecretTemporaryTokenType::TOKENTYPE;
|
||||||
$key = $this->getHandshakeTokenKeyFromClientCode($client_code);
|
$key = $this->getHandshakeTokenKeyFromClientCode($client_code);
|
||||||
$type = $this->getTemporaryTokenType(self::TEMPORARY_TOKEN_TYPE);
|
$type = $this->getTemporaryTokenType($secret_type);
|
||||||
|
|
||||||
$token = id(new PhabricatorAuthTemporaryTokenQuery())
|
$token = id(new PhabricatorAuthTemporaryTokenQuery())
|
||||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||||
->withObjectPHIDs(array($key))
|
->withTokenResources(array($key))
|
||||||
->withTokenTypes(array($type))
|
->withTokenTypes(array($type))
|
||||||
->withExpired(false)
|
->withExpired(false)
|
||||||
->executeOne();
|
->executeOne();
|
||||||
|
@ -263,6 +263,9 @@ abstract class PhabricatorOAuth1AuthProvider
|
||||||
// others' toes if a user starts Mediawiki and Bitbucket auth at the
|
// others' toes if a user starts Mediawiki and Bitbucket auth at the
|
||||||
// same time.
|
// same time.
|
||||||
|
|
||||||
|
// TODO: This isn't really a proper use of the table and should get
|
||||||
|
// cleaned up some day: the type should be constant.
|
||||||
|
|
||||||
return $core_type.':'.$this->getProviderConfig()->getID();
|
return $core_type.':'.$this->getProviderConfig()->getID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorOAuth1SecretTemporaryTokenType
|
||||||
|
extends PhabricatorAuthTemporaryTokenType {
|
||||||
|
|
||||||
|
const TOKENTYPE = 'oauth1:request:secret';
|
||||||
|
|
||||||
|
public function getTokenTypeDisplayName() {
|
||||||
|
return pht('OAuth1 Handshake Secret');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTokenReadableTypeName(
|
||||||
|
PhabricatorAuthTemporaryToken $token) {
|
||||||
|
return pht('OAuth1 Handshake Token');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -4,8 +4,9 @@ final class PhabricatorAuthTemporaryTokenQuery
|
||||||
extends PhabricatorCursorPagedPolicyAwareQuery {
|
extends PhabricatorCursorPagedPolicyAwareQuery {
|
||||||
|
|
||||||
private $ids;
|
private $ids;
|
||||||
private $objectPHIDs;
|
private $tokenResources;
|
||||||
private $tokenTypes;
|
private $tokenTypes;
|
||||||
|
private $userPHIDs;
|
||||||
private $expired;
|
private $expired;
|
||||||
private $tokenCodes;
|
private $tokenCodes;
|
||||||
|
|
||||||
|
@ -14,8 +15,8 @@ final class PhabricatorAuthTemporaryTokenQuery
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function withObjectPHIDs(array $object_phids) {
|
public function withTokenResources(array $resources) {
|
||||||
$this->objectPHIDs = $object_phids;
|
$this->tokenResources = $resources;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,41 +35,39 @@ final class PhabricatorAuthTemporaryTokenQuery
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function loadPage() {
|
public function withUserPHIDs(array $phids) {
|
||||||
$table = new PhabricatorAuthTemporaryToken();
|
$this->userPHIDs = $phids;
|
||||||
$conn_r = $table->establishConnection('r');
|
return $this;
|
||||||
|
|
||||||
$data = queryfx_all(
|
|
||||||
$conn_r,
|
|
||||||
'SELECT * FROM %T %Q %Q %Q',
|
|
||||||
$table->getTableName(),
|
|
||||||
$this->buildWhereClause($conn_r),
|
|
||||||
$this->buildOrderClause($conn_r),
|
|
||||||
$this->buildLimitClause($conn_r));
|
|
||||||
|
|
||||||
return $table->loadAllFromArray($data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
|
public function newResultObject() {
|
||||||
$where = array();
|
return new PhabricatorAuthTemporaryToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function loadPage() {
|
||||||
|
return $this->loadStandardPage($this->newResultObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
|
||||||
|
$where = parent::buildWhereClauseParts($conn);
|
||||||
|
|
||||||
if ($this->ids !== null) {
|
if ($this->ids !== null) {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn_r,
|
$conn,
|
||||||
'id IN (%Ld)',
|
'id IN (%Ld)',
|
||||||
$this->ids);
|
$this->ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->objectPHIDs !== null) {
|
if ($this->tokenResources !== null) {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn_r,
|
$conn,
|
||||||
'objectPHID IN (%Ls)',
|
'tokenResource IN (%Ls)',
|
||||||
$this->objectPHIDs);
|
$this->tokenResources);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->tokenTypes !== null) {
|
if ($this->tokenTypes !== null) {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn_r,
|
$conn,
|
||||||
'tokenType IN (%Ls)',
|
'tokenType IN (%Ls)',
|
||||||
$this->tokenTypes);
|
$this->tokenTypes);
|
||||||
}
|
}
|
||||||
|
@ -76,12 +75,12 @@ final class PhabricatorAuthTemporaryTokenQuery
|
||||||
if ($this->expired !== null) {
|
if ($this->expired !== null) {
|
||||||
if ($this->expired) {
|
if ($this->expired) {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn_r,
|
$conn,
|
||||||
'tokenExpires <= %d',
|
'tokenExpires <= %d',
|
||||||
time());
|
time());
|
||||||
} else {
|
} else {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn_r,
|
$conn,
|
||||||
'tokenExpires > %d',
|
'tokenExpires > %d',
|
||||||
time());
|
time());
|
||||||
}
|
}
|
||||||
|
@ -89,14 +88,19 @@ final class PhabricatorAuthTemporaryTokenQuery
|
||||||
|
|
||||||
if ($this->tokenCodes !== null) {
|
if ($this->tokenCodes !== null) {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn_r,
|
$conn,
|
||||||
'tokenCode IN (%Ls)',
|
'tokenCode IN (%Ls)',
|
||||||
$this->tokenCodes);
|
$this->tokenCodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
$where[] = $this->buildPagingClause($conn_r);
|
if ($this->userPHIDs !== null) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn,
|
||||||
|
'userPHID IN (%Ls)',
|
||||||
|
$this->userPHIDs);
|
||||||
|
}
|
||||||
|
|
||||||
return $this->formatWhereClause($where);
|
return $where;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getQueryApplicationClass() {
|
public function getQueryApplicationClass() {
|
||||||
|
|
|
@ -3,42 +3,58 @@
|
||||||
final class PhabricatorAuthTemporaryToken extends PhabricatorAuthDAO
|
final class PhabricatorAuthTemporaryToken extends PhabricatorAuthDAO
|
||||||
implements PhabricatorPolicyInterface {
|
implements PhabricatorPolicyInterface {
|
||||||
|
|
||||||
// TODO: OAuth1 stores a client identifier here, which is not a real PHID.
|
// NOTE: This is usually a PHID, but may be some other kind of resource
|
||||||
// At some point, we should rename this column to be a little more generic.
|
// identifier for some token types.
|
||||||
protected $objectPHID;
|
protected $tokenResource;
|
||||||
|
|
||||||
protected $tokenType;
|
protected $tokenType;
|
||||||
protected $tokenExpires;
|
protected $tokenExpires;
|
||||||
protected $tokenCode;
|
protected $tokenCode;
|
||||||
|
protected $userPHID;
|
||||||
|
protected $properties;
|
||||||
|
|
||||||
protected function getConfiguration() {
|
protected function getConfiguration() {
|
||||||
return array(
|
return array(
|
||||||
self::CONFIG_TIMESTAMPS => false,
|
self::CONFIG_TIMESTAMPS => false,
|
||||||
|
self::CONFIG_SERIALIZATION => array(
|
||||||
|
'properties' => self::SERIALIZATION_JSON,
|
||||||
|
),
|
||||||
self::CONFIG_COLUMN_SCHEMA => array(
|
self::CONFIG_COLUMN_SCHEMA => array(
|
||||||
|
'tokenResource' => 'phid',
|
||||||
'tokenType' => 'text64',
|
'tokenType' => 'text64',
|
||||||
'tokenExpires' => 'epoch',
|
'tokenExpires' => 'epoch',
|
||||||
'tokenCode' => 'text64',
|
'tokenCode' => 'text64',
|
||||||
|
'userPHID' => 'phid?',
|
||||||
),
|
),
|
||||||
self::CONFIG_KEY_SCHEMA => array(
|
self::CONFIG_KEY_SCHEMA => array(
|
||||||
'key_token' => array(
|
'key_token' => array(
|
||||||
'columns' => array('objectPHID', 'tokenType', 'tokenCode'),
|
'columns' => array('tokenResource', 'tokenType', 'tokenCode'),
|
||||||
'unique' => true,
|
'unique' => true,
|
||||||
),
|
),
|
||||||
'key_expires' => array(
|
'key_expires' => array(
|
||||||
'columns' => array('tokenExpires'),
|
'columns' => array('tokenExpires'),
|
||||||
),
|
),
|
||||||
|
'key_user' => array(
|
||||||
|
'columns' => array('userPHID'),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
) + parent::getConfiguration();
|
) + parent::getConfiguration();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function newTokenTypeImplementation() {
|
||||||
|
$types = PhabricatorAuthTemporaryTokenType::getAllTypes();
|
||||||
|
|
||||||
|
$type = idx($types, $this->tokenType);
|
||||||
|
if ($type) {
|
||||||
|
return clone $type;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public function getTokenReadableTypeName() {
|
public function getTokenReadableTypeName() {
|
||||||
// Eventually, it would be nice to let applications implement token types
|
$type = $this->newTokenTypeImplementation();
|
||||||
// so we can put this in modular subclasses.
|
if ($type) {
|
||||||
switch ($this->tokenType) {
|
return $type->getTokenReadableTypeName($this);
|
||||||
case PhabricatorAuthSessionEngine::ONETIME_TEMPORARY_TOKEN_TYPE:
|
|
||||||
return pht('One-Time Login Token');
|
|
||||||
case PhabricatorAuthSessionEngine::PASSWORD_TEMPORARY_TOKEN_TYPE:
|
|
||||||
return pht('Password Reset Token');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->tokenType;
|
return $this->tokenType;
|
||||||
|
@ -49,10 +65,9 @@ final class PhabricatorAuthTemporaryToken extends PhabricatorAuthDAO
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ($this->tokenType) {
|
$type = $this->newTokenTypeImplementation();
|
||||||
case PhabricatorAuthSessionEngine::ONETIME_TEMPORARY_TOKEN_TYPE:
|
if ($type) {
|
||||||
case PhabricatorAuthSessionEngine::PASSWORD_TEMPORARY_TOKEN_TYPE:
|
return $type->isTokenRevocable($this);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -67,12 +82,12 @@ final class PhabricatorAuthTemporaryToken extends PhabricatorAuthDAO
|
||||||
|
|
||||||
public static function revokeTokens(
|
public static function revokeTokens(
|
||||||
PhabricatorUser $viewer,
|
PhabricatorUser $viewer,
|
||||||
array $object_phids,
|
array $token_resources,
|
||||||
array $token_types) {
|
array $token_types) {
|
||||||
|
|
||||||
$tokens = id(new PhabricatorAuthTemporaryTokenQuery())
|
$tokens = id(new PhabricatorAuthTemporaryTokenQuery())
|
||||||
->setViewer($viewer)
|
->setViewer($viewer)
|
||||||
->withObjectPHIDs($object_phids)
|
->withTokenResources($token_resources)
|
||||||
->withTokenTypes($token_types)
|
->withTokenTypes($token_types)
|
||||||
->withExpired(false)
|
->withExpired(false)
|
||||||
->execute();
|
->execute();
|
||||||
|
@ -82,6 +97,15 @@ final class PhabricatorAuthTemporaryToken extends PhabricatorAuthDAO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getTemporaryTokenProperty($key, $default = null) {
|
||||||
|
return idx($this->properties, $key, $default);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setTemporaryTokenProperty($key, $value) {
|
||||||
|
$this->properties[$key] = $value;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorAuthOneTimeLoginTemporaryTokenType
|
||||||
|
extends PhabricatorAuthTemporaryTokenType {
|
||||||
|
|
||||||
|
const TOKENTYPE = 'login:onetime';
|
||||||
|
|
||||||
|
public function getTokenTypeDisplayName() {
|
||||||
|
return pht('One-Time Login');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTokenReadableTypeName(
|
||||||
|
PhabricatorAuthTemporaryToken $token) {
|
||||||
|
return pht('One-Time Login Token');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isTokenRevocable(PhabricatorAuthTemporaryToken $token) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorAuthPasswordResetTemporaryTokenType
|
||||||
|
extends PhabricatorAuthTemporaryTokenType {
|
||||||
|
|
||||||
|
const TOKENTYPE = 'login:password';
|
||||||
|
|
||||||
|
public function getTokenTypeDisplayName() {
|
||||||
|
return pht('Password Reset');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTokenReadableTypeName(
|
||||||
|
PhabricatorAuthTemporaryToken $token) {
|
||||||
|
return pht('Password Reset Token');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isTokenRevocable(PhabricatorAuthTemporaryToken $token) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
abstract class PhabricatorAuthTemporaryTokenType
|
||||||
|
extends Phobject {
|
||||||
|
|
||||||
|
abstract public function getTokenTypeDisplayName();
|
||||||
|
abstract public function getTokenReadableTypeName(
|
||||||
|
PhabricatorAuthTemporaryToken $token);
|
||||||
|
|
||||||
|
public function isTokenRevocable(PhabricatorAuthTemporaryToken $token) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function getTokenTypeConstant() {
|
||||||
|
return $this->getPhobjectClassConstant('TOKENTYPE', 64);
|
||||||
|
}
|
||||||
|
|
||||||
|
final public static function getAllTypes() {
|
||||||
|
return id(new PhutilClassMapQuery())
|
||||||
|
->setAncestorClass(__CLASS__)
|
||||||
|
->setUniqueMethod('getTokenTypeConstant')
|
||||||
|
->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorAuthTemporaryTokenTypeModule
|
||||||
|
extends PhabricatorConfigModule {
|
||||||
|
|
||||||
|
public function getModuleKey() {
|
||||||
|
return 'temporarytoken';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getModuleName() {
|
||||||
|
return pht('Temporary Tokens');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function renderModuleStatus(AphrontRequest $request) {
|
||||||
|
$viewer = $request->getViewer();
|
||||||
|
|
||||||
|
$types = PhabricatorAuthTemporaryTokenType::getAllTypes();
|
||||||
|
|
||||||
|
$rows = array();
|
||||||
|
foreach ($types as $type) {
|
||||||
|
$rows[] = array(
|
||||||
|
get_class($type),
|
||||||
|
$type->getTokenTypeConstant(),
|
||||||
|
$type->getTokenTypeDisplayName(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$table = id(new AphrontTableView($rows))
|
||||||
|
->setHeaders(
|
||||||
|
array(
|
||||||
|
pht('Class'),
|
||||||
|
pht('Key'),
|
||||||
|
pht('Name'),
|
||||||
|
))
|
||||||
|
->setColumnClasses(
|
||||||
|
array(
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
'wide pri',
|
||||||
|
));
|
||||||
|
|
||||||
|
return id(new PHUIObjectBoxView())
|
||||||
|
->setHeaderText(pht('Temporary Token Types'))
|
||||||
|
->setTable($table);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -81,6 +81,21 @@ final class DifferentialChangeType extends Phobject {
|
||||||
return idx($icons, $type, 'fa-file');
|
return idx($icons, $type, 'fa-file');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function getIconColorForFileType($type) {
|
||||||
|
static $icons = array(
|
||||||
|
self::FILE_TEXT => 'black',
|
||||||
|
self::FILE_IMAGE => 'black',
|
||||||
|
self::FILE_BINARY => 'green',
|
||||||
|
self::FILE_DIRECTORY => 'blue',
|
||||||
|
self::FILE_SYMLINK => 'blue',
|
||||||
|
self::FILE_DELETED => 'red',
|
||||||
|
self::FILE_NORMAL => 'black',
|
||||||
|
self::FILE_SUBMODULE => 'blue',
|
||||||
|
);
|
||||||
|
|
||||||
|
return idx($icons, $type, 'black');
|
||||||
|
}
|
||||||
|
|
||||||
public static function isOldLocationChangeType($type) {
|
public static function isOldLocationChangeType($type) {
|
||||||
static $types = array(
|
static $types = array(
|
||||||
self::TYPE_MOVE_AWAY => true,
|
self::TYPE_MOVE_AWAY => true,
|
||||||
|
|
|
@ -28,7 +28,8 @@ abstract class DifferentialController extends PhabricatorController {
|
||||||
$viewer = $this->getViewer();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$toc_view = id(new PHUIDiffTableOfContentsListView())
|
$toc_view = id(new PHUIDiffTableOfContentsListView())
|
||||||
->setUser($viewer);
|
->setUser($viewer)
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY);
|
||||||
|
|
||||||
$have_owners = PhabricatorApplication::isClassInstalledForViewer(
|
$have_owners = PhabricatorApplication::isClassInstalledForViewer(
|
||||||
'PhabricatorOwnersApplication',
|
'PhabricatorOwnersApplication',
|
||||||
|
|
|
@ -126,27 +126,40 @@ final class DifferentialDiffViewController extends DifferentialController {
|
||||||
->setRenderingReferences($refs)
|
->setRenderingReferences($refs)
|
||||||
->setStandaloneURI('/differential/changeset/')
|
->setStandaloneURI('/differential/changeset/')
|
||||||
->setDiff($diff)
|
->setDiff($diff)
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->setTitle(pht('Diff %d', $diff->getID()))
|
->setTitle(pht('Diff %d', $diff->getID()))
|
||||||
->setUser($request->getUser());
|
->setUser($request->getUser());
|
||||||
|
|
||||||
|
$title = pht('Diff %d', $diff->getID());
|
||||||
$crumbs = $this->buildApplicationCrumbs();
|
$crumbs = $this->buildApplicationCrumbs();
|
||||||
$crumbs->addTextCrumb(pht('Diff %d', $diff->getID()));
|
$crumbs->addTextCrumb($title);
|
||||||
|
$crumbs->setBorder(true);
|
||||||
|
|
||||||
|
$header = id(new PHUIHeaderView())
|
||||||
|
->setHeader($title);
|
||||||
|
|
||||||
$prop_box = id(new PHUIObjectBoxView())
|
$prop_box = id(new PHUIObjectBoxView())
|
||||||
->setHeader($property_head)
|
->setHeader($property_head)
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->addPropertyList($property_view)
|
->addPropertyList($property_view)
|
||||||
->setForm($form);
|
->setForm($form);
|
||||||
|
|
||||||
return $this->buildApplicationPage(
|
$view = id(new PHUITwoColumnView())
|
||||||
array(
|
->setHeader($header)
|
||||||
$crumbs,
|
->setMainColumn(array(
|
||||||
|
|
||||||
|
))
|
||||||
|
->setFooter(array(
|
||||||
$prop_box,
|
$prop_box,
|
||||||
$table_of_contents,
|
$table_of_contents,
|
||||||
$details,
|
$details,
|
||||||
),
|
|
||||||
array(
|
|
||||||
'title' => pht('Diff View'),
|
|
||||||
));
|
));
|
||||||
|
|
||||||
|
$page = $this->newPage()
|
||||||
|
->setTitle(pht('Diff View'))
|
||||||
|
->setCrumbs($crumbs)
|
||||||
|
->appendChild($view);
|
||||||
|
return $page;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function loadSelectableRevisions(
|
private function loadSelectableRevisions(
|
||||||
|
|
|
@ -40,7 +40,6 @@ final class DifferentialRevisionViewController extends DifferentialController {
|
||||||
$revision->attachActiveDiff(last($diffs));
|
$revision->attachActiveDiff(last($diffs));
|
||||||
|
|
||||||
$diff_vs = $request->getInt('vs');
|
$diff_vs = $request->getInt('vs');
|
||||||
|
|
||||||
$target_id = $request->getInt('id');
|
$target_id = $request->getInt('id');
|
||||||
$target = idx($diffs, $target_id, end($diffs));
|
$target = idx($diffs, $target_id, end($diffs));
|
||||||
|
|
||||||
|
@ -210,14 +209,10 @@ final class DifferentialRevisionViewController extends DifferentialController {
|
||||||
$commits_for_links = array();
|
$commits_for_links = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
$revision_detail = id(new DifferentialRevisionDetailView())
|
$header = $this->buildHeader($revision);
|
||||||
->setUser($viewer)
|
$subheader = $this->buildSubheaderView($revision);
|
||||||
->setRevision($revision)
|
$details = $this->buildDetails($revision, $field_list);
|
||||||
->setDiff(end($diffs))
|
$curtain = $this->buildCurtain($revision);
|
||||||
->setCustomFields($field_list)
|
|
||||||
->setURI($request->getRequestURI());
|
|
||||||
|
|
||||||
$actions = $this->getRevisionActions($revision);
|
|
||||||
|
|
||||||
$whitespace = $request->getStr(
|
$whitespace = $request->getStr(
|
||||||
'whitespace',
|
'whitespace',
|
||||||
|
@ -232,21 +227,16 @@ final class DifferentialRevisionViewController extends DifferentialController {
|
||||||
$symbol_indexes = array();
|
$symbol_indexes = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
$revision_detail->setActions($actions);
|
|
||||||
$revision_detail->setUser($viewer);
|
|
||||||
|
|
||||||
$revision_detail_box = $revision_detail->render();
|
|
||||||
|
|
||||||
$revision_warnings = $this->buildRevisionWarnings(
|
$revision_warnings = $this->buildRevisionWarnings(
|
||||||
$revision,
|
$revision,
|
||||||
$field_list,
|
$field_list,
|
||||||
$warning_handle_map,
|
$warning_handle_map,
|
||||||
$handles);
|
$handles);
|
||||||
|
$info_view = null;
|
||||||
if ($revision_warnings) {
|
if ($revision_warnings) {
|
||||||
$revision_warnings = id(new PHUIInfoView())
|
$info_view = id(new PHUIInfoView())
|
||||||
->setSeverity(PHUIInfoView::SEVERITY_WARNING)
|
->setSeverity(PHUIInfoView::SEVERITY_WARNING)
|
||||||
->setErrors($revision_warnings);
|
->setErrors($revision_warnings);
|
||||||
$revision_detail_box->setInfoView($revision_warnings);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$detail_diffs = array_select_keys(
|
$detail_diffs = array_select_keys(
|
||||||
|
@ -277,39 +267,31 @@ final class DifferentialRevisionViewController extends DifferentialController {
|
||||||
$comment_view->setQuoteTargetID('comment-content');
|
$comment_view->setQuoteTargetID('comment-content');
|
||||||
}
|
}
|
||||||
|
|
||||||
$wrap_id = celerity_generate_unique_node_id();
|
$changeset_view = id(new DifferentialChangesetListView())
|
||||||
$comment_view = phutil_tag(
|
->setChangesets($changesets)
|
||||||
'div',
|
->setVisibleChangesets($visible_changesets)
|
||||||
array(
|
->setStandaloneURI('/differential/changeset/')
|
||||||
'id' => $wrap_id,
|
->setRawFileURIs(
|
||||||
),
|
'/differential/changeset/?view=old',
|
||||||
$comment_view);
|
'/differential/changeset/?view=new')
|
||||||
|
->setUser($viewer)
|
||||||
|
->setDiff($target)
|
||||||
|
->setRenderingReferences($rendering_references)
|
||||||
|
->setVsMap($vs_map)
|
||||||
|
->setWhitespace($whitespace)
|
||||||
|
->setSymbolIndexes($symbol_indexes)
|
||||||
|
->setTitle(pht('Diff %s', $target->getID()))
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY);
|
||||||
|
|
||||||
$changeset_view = new DifferentialChangesetListView();
|
if ($repository) {
|
||||||
$changeset_view->setChangesets($changesets);
|
$changeset_view->setRepository($repository);
|
||||||
$changeset_view->setVisibleChangesets($visible_changesets);
|
}
|
||||||
|
|
||||||
if (!$viewer_is_anonymous) {
|
if (!$viewer_is_anonymous) {
|
||||||
$changeset_view->setInlineCommentControllerURI(
|
$changeset_view->setInlineCommentControllerURI(
|
||||||
'/differential/comment/inline/edit/'.$revision->getID().'/');
|
'/differential/comment/inline/edit/'.$revision->getID().'/');
|
||||||
}
|
}
|
||||||
|
|
||||||
$changeset_view->setStandaloneURI('/differential/changeset/');
|
|
||||||
$changeset_view->setRawFileURIs(
|
|
||||||
'/differential/changeset/?view=old',
|
|
||||||
'/differential/changeset/?view=new');
|
|
||||||
|
|
||||||
$changeset_view->setUser($viewer);
|
|
||||||
$changeset_view->setDiff($target);
|
|
||||||
$changeset_view->setRenderingReferences($rendering_references);
|
|
||||||
$changeset_view->setVsMap($vs_map);
|
|
||||||
$changeset_view->setWhitespace($whitespace);
|
|
||||||
if ($repository) {
|
|
||||||
$changeset_view->setRepository($repository);
|
|
||||||
}
|
|
||||||
$changeset_view->setSymbolIndexes($symbol_indexes);
|
|
||||||
$changeset_view->setTitle(pht('Diff %s', $target->getID()));
|
|
||||||
|
|
||||||
$diff_history = id(new DifferentialRevisionUpdateHistoryView())
|
$diff_history = id(new DifferentialRevisionUpdateHistoryView())
|
||||||
->setUser($viewer)
|
->setUser($viewer)
|
||||||
->setDiffs($diffs)
|
->setDiffs($diffs)
|
||||||
|
@ -344,6 +326,233 @@ final class DifferentialRevisionViewController extends DifferentialController {
|
||||||
|
|
||||||
$comment_form = null;
|
$comment_form = null;
|
||||||
if (!$viewer_is_anonymous) {
|
if (!$viewer_is_anonymous) {
|
||||||
|
$comment_form = $this->buildCommentForm($revision, $field_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
$signatures = DifferentialRequiredSignaturesField::loadForRevision(
|
||||||
|
$revision);
|
||||||
|
$missing_signatures = false;
|
||||||
|
foreach ($signatures as $phid => $signed) {
|
||||||
|
if (!$signed) {
|
||||||
|
$missing_signatures = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$footer = array();
|
||||||
|
$signature_message = null;
|
||||||
|
if ($missing_signatures) {
|
||||||
|
$signature_message = id(new PHUIInfoView())
|
||||||
|
->setTitle(pht('Content Hidden'))
|
||||||
|
->appendChild(
|
||||||
|
pht(
|
||||||
|
'The content of this revision is hidden until the author has '.
|
||||||
|
'signed all of the required legal agreements.'));
|
||||||
|
} else {
|
||||||
|
$footer[] =
|
||||||
|
array(
|
||||||
|
$diff_history,
|
||||||
|
$warning,
|
||||||
|
$local_view,
|
||||||
|
$toc_view,
|
||||||
|
$other_view,
|
||||||
|
$changeset_view,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($comment_form) {
|
||||||
|
$footer[] = $comment_form;
|
||||||
|
} else {
|
||||||
|
// TODO: For now, just use this to get "Login to Comment".
|
||||||
|
$footer[] = id(new PhabricatorApplicationTransactionCommentView())
|
||||||
|
->setUser($viewer)
|
||||||
|
->setRequestURI($request->getRequestURI());
|
||||||
|
}
|
||||||
|
|
||||||
|
$object_id = 'D'.$revision->getID();
|
||||||
|
$operations_box = $this->buildOperationsBox($revision);
|
||||||
|
|
||||||
|
$crumbs = $this->buildApplicationCrumbs();
|
||||||
|
$crumbs->addTextCrumb($object_id, '/'.$object_id);
|
||||||
|
$crumbs->setBorder(true);
|
||||||
|
|
||||||
|
$prefs = $viewer->loadPreferences();
|
||||||
|
$pref_filetree = PhabricatorUserPreferences::PREFERENCE_DIFF_FILETREE;
|
||||||
|
$nav = null;
|
||||||
|
if ($prefs->getPreference($pref_filetree)) {
|
||||||
|
$collapsed = $prefs->getPreference(
|
||||||
|
PhabricatorUserPreferences::PREFERENCE_NAV_COLLAPSED,
|
||||||
|
false);
|
||||||
|
|
||||||
|
$nav = id(new DifferentialChangesetFileTreeSideNavBuilder())
|
||||||
|
->setTitle('D'.$revision->getID())
|
||||||
|
->setBaseURI(new PhutilURI('/D'.$revision->getID()))
|
||||||
|
->setCollapsed((bool)$collapsed)
|
||||||
|
->build($changesets);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Haunt Mode
|
||||||
|
$pane_id = celerity_generate_unique_node_id();
|
||||||
|
Javelin::initBehavior(
|
||||||
|
'differential-keyboard-navigation',
|
||||||
|
array(
|
||||||
|
'haunt' => $pane_id,
|
||||||
|
));
|
||||||
|
Javelin::initBehavior('differential-user-select');
|
||||||
|
|
||||||
|
$view = id(new PHUITwoColumnView())
|
||||||
|
->setHeader($header)
|
||||||
|
->setSubheader($subheader)
|
||||||
|
->setCurtain($curtain)
|
||||||
|
->setID($pane_id)
|
||||||
|
->setMainColumn(array(
|
||||||
|
$operations_box,
|
||||||
|
$info_view,
|
||||||
|
$details,
|
||||||
|
$diff_detail_box,
|
||||||
|
$unit_box,
|
||||||
|
$comment_view,
|
||||||
|
$signature_message,
|
||||||
|
))
|
||||||
|
->setFooter($footer);
|
||||||
|
|
||||||
|
$page = $this->newPage()
|
||||||
|
->setTitle($object_id.' '.$revision->getTitle())
|
||||||
|
->setCrumbs($crumbs)
|
||||||
|
->setPageObjectPHIDs(array($revision->getPHID()))
|
||||||
|
->appendChild($view);
|
||||||
|
|
||||||
|
if ($nav) {
|
||||||
|
$page->setNavigation($nav);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $page;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildHeader(DifferentialRevision $revision) {
|
||||||
|
$view = id(new PHUIHeaderView())
|
||||||
|
->setHeader($revision->getTitle($revision))
|
||||||
|
->setUser($this->getViewer())
|
||||||
|
->setPolicyObject($revision)
|
||||||
|
->setHeaderIcon('fa-cog');
|
||||||
|
|
||||||
|
$status = $revision->getStatus();
|
||||||
|
$status_name =
|
||||||
|
DifferentialRevisionStatus::renderFullDescription($status);
|
||||||
|
|
||||||
|
$view->addProperty(PHUIHeaderView::PROPERTY_STATUS, $status_name);
|
||||||
|
|
||||||
|
return $view;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildSubheaderView(DifferentialRevision $revision) {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
|
$author_phid = $revision->getAuthorPHID();
|
||||||
|
|
||||||
|
$author = $viewer->renderHandle($author_phid)->render();
|
||||||
|
$date = phabricator_datetime($revision->getDateCreated(), $viewer);
|
||||||
|
$author = phutil_tag('strong', array(), $author);
|
||||||
|
|
||||||
|
$handles = $viewer->loadHandles(array($author_phid));
|
||||||
|
$image_uri = $handles[$author_phid]->getImageURI();
|
||||||
|
$image_href = $handles[$author_phid]->getURI();
|
||||||
|
|
||||||
|
$content = pht('Authored by %s on %s.', $author, $date);
|
||||||
|
|
||||||
|
return id(new PHUIHeadThingView())
|
||||||
|
->setImage($image_uri)
|
||||||
|
->setImageHref($image_href)
|
||||||
|
->setContent($content);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildDetails(
|
||||||
|
DifferentialRevision $revision,
|
||||||
|
$custom_fields) {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
$properties = id(new PHUIPropertyListView())
|
||||||
|
->setUser($viewer);
|
||||||
|
|
||||||
|
if ($custom_fields) {
|
||||||
|
$custom_fields->appendFieldsToPropertyList(
|
||||||
|
$revision,
|
||||||
|
$viewer,
|
||||||
|
$properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
$header = id(new PHUIHeaderView())
|
||||||
|
->setHeader(pht('DETAILS'));
|
||||||
|
|
||||||
|
return id(new PHUIObjectBoxView())
|
||||||
|
->setHeader($header)
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
|
->appendChild($properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildCurtain(DifferentialRevision $revision) {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
$revision_id = $revision->getID();
|
||||||
|
$revision_phid = $revision->getPHID();
|
||||||
|
$curtain = $this->newCurtainView($revision);
|
||||||
|
|
||||||
|
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||||
|
$viewer,
|
||||||
|
$revision,
|
||||||
|
PhabricatorPolicyCapability::CAN_EDIT);
|
||||||
|
|
||||||
|
$curtain->addAction(
|
||||||
|
id(new PhabricatorActionView())
|
||||||
|
->setIcon('fa-pencil')
|
||||||
|
->setHref("/differential/revision/edit/{$revision_id}/")
|
||||||
|
->setName(pht('Edit Revision'))
|
||||||
|
->setDisabled(!$can_edit)
|
||||||
|
->setWorkflow(!$can_edit));
|
||||||
|
|
||||||
|
$curtain->addAction(
|
||||||
|
id(new PhabricatorActionView())
|
||||||
|
->setIcon('fa-upload')
|
||||||
|
->setHref("/differential/revision/update/{$revision_id}/")
|
||||||
|
->setName(pht('Update Diff'))
|
||||||
|
->setDisabled(!$can_edit)
|
||||||
|
->setWorkflow(!$can_edit));
|
||||||
|
|
||||||
|
$this->requireResource('phabricator-object-selector-css');
|
||||||
|
$this->requireResource('javelin-behavior-phabricator-object-selector');
|
||||||
|
|
||||||
|
$curtain->addAction(
|
||||||
|
id(new PhabricatorActionView())
|
||||||
|
->setIcon('fa-link')
|
||||||
|
->setName(pht('Edit Dependencies'))
|
||||||
|
->setHref("/search/attach/{$revision_phid}/DREV/dependencies/")
|
||||||
|
->setWorkflow(true)
|
||||||
|
->setDisabled(!$can_edit));
|
||||||
|
|
||||||
|
$maniphest = 'PhabricatorManiphestApplication';
|
||||||
|
if (PhabricatorApplication::isClassInstalled($maniphest)) {
|
||||||
|
$curtain->addAction(
|
||||||
|
id(new PhabricatorActionView())
|
||||||
|
->setIcon('fa-anchor')
|
||||||
|
->setName(pht('Edit Maniphest Tasks'))
|
||||||
|
->setHref("/search/attach/{$revision_phid}/TASK/")
|
||||||
|
->setWorkflow(true)
|
||||||
|
->setDisabled(!$can_edit));
|
||||||
|
}
|
||||||
|
|
||||||
|
$request_uri = $this->getRequest()->getRequestURI();
|
||||||
|
$curtain->addAction(
|
||||||
|
id(new PhabricatorActionView())
|
||||||
|
->setIcon('fa-download')
|
||||||
|
->setName(pht('Download Raw Diff'))
|
||||||
|
->setHref($request_uri->alter('download', 'true')));
|
||||||
|
|
||||||
|
return $curtain;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildCommentForm(
|
||||||
|
DifferentialRevision $revision,
|
||||||
|
$field_list) {
|
||||||
|
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$draft = id(new PhabricatorDraft())->loadOneWhere(
|
$draft = id(new PhabricatorDraft())->loadOneWhere(
|
||||||
'authorPHID = %s AND draftKey = %s',
|
'authorPHID = %s AND draftKey = %s',
|
||||||
$viewer->getPHID(),
|
$viewer->getPHID(),
|
||||||
|
@ -361,8 +570,8 @@ final class DifferentialRevisionViewController extends DifferentialController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$comment_form = new DifferentialAddCommentView();
|
$comment_form = id(new DifferentialAddCommentView())
|
||||||
$comment_form->setRevision($revision);
|
->setRevision($revision);
|
||||||
|
|
||||||
$review_warnings = array();
|
$review_warnings = array();
|
||||||
foreach ($field_list->getFields() as $field) {
|
foreach ($field_list->getFields() as $field) {
|
||||||
|
@ -377,15 +586,15 @@ final class DifferentialRevisionViewController extends DifferentialController {
|
||||||
$comment_form->setInfoView($review_warnings_panel);
|
$comment_form->setInfoView($review_warnings_panel);
|
||||||
}
|
}
|
||||||
|
|
||||||
$comment_form->setActions($this->getRevisionCommentActions($revision));
|
|
||||||
$action_uri = $this->getApplicationURI(
|
$action_uri = $this->getApplicationURI(
|
||||||
'comment/save/'.$revision->getID().'/');
|
'comment/save/'.$revision->getID().'/');
|
||||||
|
|
||||||
$comment_form->setActionURI($action_uri);
|
$comment_form->setActions($this->getRevisionCommentActions($revision))
|
||||||
$comment_form->setUser($viewer);
|
->setActionURI($action_uri)
|
||||||
$comment_form->setDraft($draft);
|
->setUser($viewer)
|
||||||
$comment_form->setReviewers(mpull($reviewers, 'getFullName', 'getPHID'));
|
->setDraft($draft)
|
||||||
$comment_form->setCCs(mpull($ccs, 'getFullName', 'getPHID'));
|
->setReviewers(mpull($reviewers, 'getFullName', 'getPHID'))
|
||||||
|
->setCCs(mpull($ccs, 'getFullName', 'getPHID'));
|
||||||
|
|
||||||
// TODO: This just makes the "Z" key work. Generalize this and remove
|
// TODO: This just makes the "Z" key work. Generalize this and remove
|
||||||
// it at some point.
|
// it at some point.
|
||||||
|
@ -395,162 +604,7 @@ final class DifferentialRevisionViewController extends DifferentialController {
|
||||||
'class' => 'differential-add-comment-panel',
|
'class' => 'differential-add-comment-panel',
|
||||||
),
|
),
|
||||||
$comment_form);
|
$comment_form);
|
||||||
}
|
return $comment_form;
|
||||||
|
|
||||||
$pane_id = celerity_generate_unique_node_id();
|
|
||||||
Javelin::initBehavior(
|
|
||||||
'differential-keyboard-navigation',
|
|
||||||
array(
|
|
||||||
'haunt' => $pane_id,
|
|
||||||
));
|
|
||||||
Javelin::initBehavior('differential-user-select');
|
|
||||||
|
|
||||||
$page_pane = id(new DifferentialPrimaryPaneView())
|
|
||||||
->setID($pane_id)
|
|
||||||
->appendChild($comment_view);
|
|
||||||
|
|
||||||
$signatures = DifferentialRequiredSignaturesField::loadForRevision(
|
|
||||||
$revision);
|
|
||||||
$missing_signatures = false;
|
|
||||||
foreach ($signatures as $phid => $signed) {
|
|
||||||
if (!$signed) {
|
|
||||||
$missing_signatures = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($missing_signatures) {
|
|
||||||
$signature_message = id(new PHUIInfoView())
|
|
||||||
->setErrors(
|
|
||||||
array(
|
|
||||||
array(
|
|
||||||
phutil_tag('strong', array(), pht('Content Hidden:')),
|
|
||||||
' ',
|
|
||||||
pht(
|
|
||||||
'The content of this revision is hidden until the author has '.
|
|
||||||
'signed all of the required legal agreements.'),
|
|
||||||
),
|
|
||||||
));
|
|
||||||
$page_pane->appendChild($signature_message);
|
|
||||||
} else {
|
|
||||||
$page_pane->appendChild(
|
|
||||||
array(
|
|
||||||
$diff_history,
|
|
||||||
$warning,
|
|
||||||
$local_view,
|
|
||||||
$toc_view,
|
|
||||||
$other_view,
|
|
||||||
$changeset_view,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($comment_form) {
|
|
||||||
$page_pane->appendChild($comment_form);
|
|
||||||
} else {
|
|
||||||
// TODO: For now, just use this to get "Login to Comment".
|
|
||||||
$page_pane->appendChild(
|
|
||||||
id(new PhabricatorApplicationTransactionCommentView())
|
|
||||||
->setUser($viewer)
|
|
||||||
->setRequestURI($request->getRequestURI()));
|
|
||||||
}
|
|
||||||
|
|
||||||
$object_id = 'D'.$revision->getID();
|
|
||||||
|
|
||||||
$operations_box = $this->buildOperationsBox($revision);
|
|
||||||
|
|
||||||
$content = array(
|
|
||||||
$operations_box,
|
|
||||||
$revision_detail_box,
|
|
||||||
$diff_detail_box,
|
|
||||||
$unit_box,
|
|
||||||
$page_pane,
|
|
||||||
);
|
|
||||||
|
|
||||||
$crumbs = $this->buildApplicationCrumbs();
|
|
||||||
$crumbs->addTextCrumb($object_id, '/'.$object_id);
|
|
||||||
|
|
||||||
$prefs = $viewer->loadPreferences();
|
|
||||||
|
|
||||||
$pref_filetree = PhabricatorUserPreferences::PREFERENCE_DIFF_FILETREE;
|
|
||||||
if ($prefs->getPreference($pref_filetree)) {
|
|
||||||
$collapsed = $prefs->getPreference(
|
|
||||||
PhabricatorUserPreferences::PREFERENCE_NAV_COLLAPSED,
|
|
||||||
false);
|
|
||||||
|
|
||||||
$nav = id(new DifferentialChangesetFileTreeSideNavBuilder())
|
|
||||||
->setTitle('D'.$revision->getID())
|
|
||||||
->setBaseURI(new PhutilURI('/D'.$revision->getID()))
|
|
||||||
->setCollapsed((bool)$collapsed)
|
|
||||||
->build($changesets);
|
|
||||||
} else {
|
|
||||||
$nav = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$page = $this->newPage()
|
|
||||||
->setTitle($object_id.' '.$revision->getTitle())
|
|
||||||
->setCrumbs($crumbs)
|
|
||||||
->setPageObjectPHIDs(array($revision->getPHID()))
|
|
||||||
->appendChild($content);
|
|
||||||
|
|
||||||
if ($nav) {
|
|
||||||
$page->setNavigation($nav);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $page;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getRevisionActions(DifferentialRevision $revision) {
|
|
||||||
$viewer = $this->getRequest()->getUser();
|
|
||||||
$revision_id = $revision->getID();
|
|
||||||
$revision_phid = $revision->getPHID();
|
|
||||||
|
|
||||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
|
||||||
$viewer,
|
|
||||||
$revision,
|
|
||||||
PhabricatorPolicyCapability::CAN_EDIT);
|
|
||||||
|
|
||||||
$actions = array();
|
|
||||||
|
|
||||||
$actions[] = id(new PhabricatorActionView())
|
|
||||||
->setIcon('fa-pencil')
|
|
||||||
->setHref("/differential/revision/edit/{$revision_id}/")
|
|
||||||
->setName(pht('Edit Revision'))
|
|
||||||
->setDisabled(!$can_edit)
|
|
||||||
->setWorkflow(!$can_edit);
|
|
||||||
|
|
||||||
$actions[] = id(new PhabricatorActionView())
|
|
||||||
->setIcon('fa-upload')
|
|
||||||
->setHref("/differential/revision/update/{$revision_id}/")
|
|
||||||
->setName(pht('Update Diff'))
|
|
||||||
->setDisabled(!$can_edit)
|
|
||||||
->setWorkflow(!$can_edit);
|
|
||||||
|
|
||||||
$this->requireResource('phabricator-object-selector-css');
|
|
||||||
$this->requireResource('javelin-behavior-phabricator-object-selector');
|
|
||||||
|
|
||||||
$actions[] = id(new PhabricatorActionView())
|
|
||||||
->setIcon('fa-link')
|
|
||||||
->setName(pht('Edit Dependencies'))
|
|
||||||
->setHref("/search/attach/{$revision_phid}/DREV/dependencies/")
|
|
||||||
->setWorkflow(true)
|
|
||||||
->setDisabled(!$can_edit);
|
|
||||||
|
|
||||||
$maniphest = 'PhabricatorManiphestApplication';
|
|
||||||
if (PhabricatorApplication::isClassInstalled($maniphest)) {
|
|
||||||
$actions[] = id(new PhabricatorActionView())
|
|
||||||
->setIcon('fa-anchor')
|
|
||||||
->setName(pht('Edit Maniphest Tasks'))
|
|
||||||
->setHref("/search/attach/{$revision_phid}/TASK/")
|
|
||||||
->setWorkflow(true)
|
|
||||||
->setDisabled(!$can_edit);
|
|
||||||
}
|
|
||||||
|
|
||||||
$request_uri = $this->getRequest()->getRequestURI();
|
|
||||||
$actions[] = id(new PhabricatorActionView())
|
|
||||||
->setIcon('fa-download')
|
|
||||||
->setName(pht('Download Raw Diff'))
|
|
||||||
->setHref($request_uri->alter('download', 'true'));
|
|
||||||
|
|
||||||
return $actions;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getRevisionCommentActions(DifferentialRevision $revision) {
|
private function getRevisionCommentActions(DifferentialRevision $revision) {
|
||||||
|
@ -558,7 +612,7 @@ final class DifferentialRevisionViewController extends DifferentialController {
|
||||||
DifferentialAction::ACTION_COMMENT => true,
|
DifferentialAction::ACTION_COMMENT => true,
|
||||||
);
|
);
|
||||||
|
|
||||||
$viewer = $this->getRequest()->getUser();
|
$viewer = $this->getViewer();
|
||||||
$viewer_phid = $viewer->getPHID();
|
$viewer_phid = $viewer->getPHID();
|
||||||
$viewer_is_owner = ($viewer_phid == $revision->getAuthorPHID());
|
$viewer_is_owner = ($viewer_phid == $revision->getAuthorPHID());
|
||||||
$viewer_is_reviewer = in_array($viewer_phid, $revision->getReviewers());
|
$viewer_is_reviewer = in_array($viewer_phid, $revision->getReviewers());
|
||||||
|
@ -814,11 +868,12 @@ final class DifferentialRevisionViewController extends DifferentialController {
|
||||||
$viewer = $this->getViewer();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$header = id(new PHUIHeaderView())
|
$header = id(new PHUIHeaderView())
|
||||||
->setHeader(pht('Recent Similar Open Revisions'));
|
->setHeader(pht('Recent Similar Revisions'));
|
||||||
|
|
||||||
$view = id(new DifferentialRevisionListView())
|
$view = id(new DifferentialRevisionListView())
|
||||||
->setHeader($header)
|
->setHeader($header)
|
||||||
->setRevisions($revisions)
|
->setRevisions($revisions)
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->setUser($viewer);
|
->setUser($viewer);
|
||||||
|
|
||||||
$phids = $view->getRequiredHandlePHIDs();
|
$phids = $view->getRequiredHandlePHIDs();
|
||||||
|
@ -845,7 +900,7 @@ final class DifferentialRevisionViewController extends DifferentialController {
|
||||||
assert_instances_of($changesets, 'DifferentialChangeset');
|
assert_instances_of($changesets, 'DifferentialChangeset');
|
||||||
assert_instances_of($vs_changesets, 'DifferentialChangeset');
|
assert_instances_of($vs_changesets, 'DifferentialChangeset');
|
||||||
|
|
||||||
$viewer = $this->getRequest()->getUser();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
id(new DifferentialHunkQuery())
|
id(new DifferentialHunkQuery())
|
||||||
->setViewer($viewer)
|
->setViewer($viewer)
|
||||||
|
@ -978,7 +1033,8 @@ final class DifferentialRevisionViewController extends DifferentialController {
|
||||||
}
|
}
|
||||||
|
|
||||||
$box = id(new PHUIObjectBoxView())
|
$box = id(new PHUIObjectBoxView())
|
||||||
->setHeaderText(pht('Diff Detail'))
|
->setHeaderText(pht('DIFF DETAIL'))
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->setUser($viewer);
|
->setUser($viewer);
|
||||||
|
|
||||||
$last_tab = null;
|
$last_tab = null;
|
||||||
|
@ -1061,7 +1117,8 @@ final class DifferentialRevisionViewController extends DifferentialController {
|
||||||
}
|
}
|
||||||
|
|
||||||
$box_view = id(new PHUIObjectBoxView())
|
$box_view = id(new PHUIObjectBoxView())
|
||||||
->setHeaderText(pht('Active Operations'));
|
->setHeaderText(pht('ACTIVE OPERATIONS'))
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY);
|
||||||
|
|
||||||
return id(new DrydockRepositoryOperationStatusView())
|
return id(new DrydockRepositoryOperationStatusView())
|
||||||
->setUser($viewer)
|
->setUser($viewer)
|
||||||
|
@ -1074,11 +1131,11 @@ final class DifferentialRevisionViewController extends DifferentialController {
|
||||||
DifferentialRevision $revision) {
|
DifferentialRevision $revision) {
|
||||||
$viewer = $this->getViewer();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
if (!$diff->getUnitMessages()) {
|
if (!$diff->getBuildable()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$diff->getBuildable()) {
|
if (!$diff->getUnitMessages()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1109,6 +1166,7 @@ final class DifferentialRevisionViewController extends DifferentialController {
|
||||||
->setBuildable($diff->getBuildable())
|
->setBuildable($diff->getBuildable())
|
||||||
->setUnitMessages($diff->getUnitMessages())
|
->setUnitMessages($diff->getUnitMessages())
|
||||||
->setLimit(5)
|
->setLimit(5)
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->setShowViewAll(true);
|
->setShowViewAll(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ final class DifferentialAuthorField
|
||||||
}
|
}
|
||||||
|
|
||||||
public function shouldAppearInPropertyView() {
|
public function shouldAppearInPropertyView() {
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function renderPropertyViewLabel() {
|
public function renderPropertyViewLabel() {
|
||||||
|
|
|
@ -70,8 +70,6 @@ final class DifferentialHovercardEngineExtension
|
||||||
$hovercard->addField(pht('Summary'), $summary);
|
$hovercard->addField(pht('Summary'), $summary);
|
||||||
}
|
}
|
||||||
|
|
||||||
$tag = DifferentialRevisionDetailView::renderTagForRevision($revision);
|
|
||||||
$hovercard->addTag($tag);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,7 +163,7 @@ final class DifferentialAddCommentView extends AphrontView {
|
||||||
$is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business');
|
$is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business');
|
||||||
$header_text = $is_serious
|
$header_text = $is_serious
|
||||||
? pht('Add Comment')
|
? pht('Add Comment')
|
||||||
: pht('Leap Into Action');
|
: pht('Leap Into Action!');
|
||||||
|
|
||||||
$header = id(new PHUIHeaderView())
|
$header = id(new PHUIHeaderView())
|
||||||
->setHeader($header_text);
|
->setHeader($header_text);
|
||||||
|
|
|
@ -8,6 +8,8 @@ final class DifferentialChangesetListView extends AphrontView {
|
||||||
private $inlineURI;
|
private $inlineURI;
|
||||||
private $renderURI = '/differential/changeset/';
|
private $renderURI = '/differential/changeset/';
|
||||||
private $whitespace;
|
private $whitespace;
|
||||||
|
private $background;
|
||||||
|
private $header;
|
||||||
|
|
||||||
private $standaloneURI;
|
private $standaloneURI;
|
||||||
private $leftRawFileURI;
|
private $leftRawFileURI;
|
||||||
|
@ -112,6 +114,16 @@ final class DifferentialChangesetListView extends AphrontView {
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setBackground($background) {
|
||||||
|
$this->background = $background;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setHeader($header) {
|
||||||
|
$this->header = $header;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function render() {
|
public function render() {
|
||||||
$viewer = $this->getViewer();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
|
@ -240,8 +252,12 @@ final class DifferentialChangesetListView extends AphrontView {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->header) {
|
||||||
|
$header = $this->header;
|
||||||
|
} else {
|
||||||
$header = id(new PHUIHeaderView())
|
$header = id(new PHUIHeaderView())
|
||||||
->setHeader($this->getTitle());
|
->setHeader($this->getTitle());
|
||||||
|
}
|
||||||
|
|
||||||
$content = phutil_tag(
|
$content = phutil_tag(
|
||||||
'div',
|
'div',
|
||||||
|
@ -253,6 +269,7 @@ final class DifferentialChangesetListView extends AphrontView {
|
||||||
|
|
||||||
$object_box = id(new PHUIObjectBoxView())
|
$object_box = id(new PHUIObjectBoxView())
|
||||||
->setHeader($header)
|
->setHeader($header)
|
||||||
|
->setBackground($this->background)
|
||||||
->setCollapsed(true)
|
->setCollapsed(true)
|
||||||
->appendChild($content);
|
->appendChild($content);
|
||||||
|
|
||||||
|
|
|
@ -127,6 +127,7 @@ final class DifferentialLocalCommitsView extends AphrontView {
|
||||||
|
|
||||||
return id(new PHUIObjectBoxView())
|
return id(new PHUIObjectBoxView())
|
||||||
->setHeaderText(pht('Local Commits'))
|
->setHeaderText(pht('Local Commits'))
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->setTable($table);
|
->setTable($table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
final class DifferentialPrimaryPaneView extends AphrontView {
|
|
||||||
|
|
||||||
private $id;
|
|
||||||
|
|
||||||
public function setID($id) {
|
|
||||||
$this->id = $id;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function render() {
|
|
||||||
|
|
||||||
return phutil_tag(
|
|
||||||
'div',
|
|
||||||
array(
|
|
||||||
'class' => 'differential-primary-pane',
|
|
||||||
'id' => $this->id,
|
|
||||||
),
|
|
||||||
$this->renderChildren());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,121 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
final class DifferentialRevisionDetailView extends AphrontView {
|
|
||||||
|
|
||||||
private $revision;
|
|
||||||
private $actions;
|
|
||||||
private $customFields;
|
|
||||||
private $diff;
|
|
||||||
private $uri;
|
|
||||||
private $actionList;
|
|
||||||
|
|
||||||
public function setURI($uri) {
|
|
||||||
$this->uri = $uri;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
public function getURI() {
|
|
||||||
return $this->uri;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setDiff(DifferentialDiff $diff) {
|
|
||||||
$this->diff = $diff;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
private function getDiff() {
|
|
||||||
return $this->diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setRevision(DifferentialRevision $revision) {
|
|
||||||
$this->revision = $revision;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setActions(array $actions) {
|
|
||||||
$this->actions = $actions;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
private function getActions() {
|
|
||||||
return $this->actions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setActionList(PhabricatorActionListView $list) {
|
|
||||||
$this->actionList = $list;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getActionList() {
|
|
||||||
return $this->actionList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setCustomFields(PhabricatorCustomFieldList $list) {
|
|
||||||
$this->customFields = $list;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function render() {
|
|
||||||
|
|
||||||
$this->requireResource('differential-core-view-css');
|
|
||||||
|
|
||||||
$revision = $this->revision;
|
|
||||||
$user = $this->getUser();
|
|
||||||
|
|
||||||
$header = $this->renderHeader($revision);
|
|
||||||
|
|
||||||
$actions = id(new PhabricatorActionListView())
|
|
||||||
->setUser($user)
|
|
||||||
->setObject($revision);
|
|
||||||
foreach ($this->getActions() as $action) {
|
|
||||||
$actions->addAction($action);
|
|
||||||
}
|
|
||||||
|
|
||||||
$properties = id(new PHUIPropertyListView())
|
|
||||||
->setUser($user)
|
|
||||||
->setObject($revision);
|
|
||||||
|
|
||||||
$properties->setHasKeyboardShortcuts(true);
|
|
||||||
$properties->setActionList($actions);
|
|
||||||
$this->setActionList($actions);
|
|
||||||
|
|
||||||
$field_list = $this->customFields;
|
|
||||||
if ($field_list) {
|
|
||||||
$field_list->appendFieldsToPropertyList(
|
|
||||||
$revision,
|
|
||||||
$user,
|
|
||||||
$properties);
|
|
||||||
}
|
|
||||||
|
|
||||||
$object_box = id(new PHUIObjectBoxView())
|
|
||||||
->setHeader($header)
|
|
||||||
->addPropertyList($properties);
|
|
||||||
|
|
||||||
return $object_box;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function renderHeader(DifferentialRevision $revision) {
|
|
||||||
$view = id(new PHUIHeaderView())
|
|
||||||
->setHeader($revision->getTitle($revision))
|
|
||||||
->setUser($this->getUser())
|
|
||||||
->setPolicyObject($revision);
|
|
||||||
|
|
||||||
$status = $revision->getStatus();
|
|
||||||
$status_name =
|
|
||||||
DifferentialRevisionStatus::renderFullDescription($status);
|
|
||||||
|
|
||||||
$view->addProperty(PHUIHeaderView::PROPERTY_STATUS, $status_name);
|
|
||||||
|
|
||||||
return $view;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function renderTagForRevision(
|
|
||||||
DifferentialRevision $revision) {
|
|
||||||
|
|
||||||
$status = $revision->getStatus();
|
|
||||||
$status_name =
|
|
||||||
ArcanistDifferentialRevisionStatus::getNameForRevisionStatus($status);
|
|
||||||
|
|
||||||
return id(new PHUITagView())
|
|
||||||
->setType(PHUITagView::TYPE_STATE)
|
|
||||||
->setName($status_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -11,6 +11,7 @@ final class DifferentialRevisionListView extends AphrontView {
|
||||||
private $header;
|
private $header;
|
||||||
private $noDataString;
|
private $noDataString;
|
||||||
private $noBox;
|
private $noBox;
|
||||||
|
private $background = null;
|
||||||
|
|
||||||
public function setNoDataString($no_data_string) {
|
public function setNoDataString($no_data_string) {
|
||||||
$this->noDataString = $no_data_string;
|
$this->noDataString = $no_data_string;
|
||||||
|
@ -38,6 +39,11 @@ final class DifferentialRevisionListView extends AphrontView {
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setBackground($background) {
|
||||||
|
$this->background = $background;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function getRequiredHandlePHIDs() {
|
public function getRequiredHandlePHIDs() {
|
||||||
$phids = array();
|
$phids = array();
|
||||||
foreach ($this->revisions as $revision) {
|
foreach ($this->revisions as $revision) {
|
||||||
|
@ -192,6 +198,7 @@ final class DifferentialRevisionListView extends AphrontView {
|
||||||
if ($this->header && !$this->noBox) {
|
if ($this->header && !$this->noBox) {
|
||||||
$list->setFlush(true);
|
$list->setFlush(true);
|
||||||
$list = id(new PHUIObjectBoxView())
|
$list = id(new PHUIObjectBoxView())
|
||||||
|
->setBackground($this->background)
|
||||||
->setObjectList($list);
|
->setObjectList($list);
|
||||||
|
|
||||||
if ($this->header instanceof PHUIHeaderView) {
|
if ($this->header instanceof PHUIHeaderView) {
|
||||||
|
|
|
@ -305,7 +305,7 @@ final class DifferentialRevisionUpdateHistoryView extends AphrontView {
|
||||||
|
|
||||||
return id(new PHUIObjectBoxView())
|
return id(new PHUIObjectBoxView())
|
||||||
->setHeaderText(pht('Revision Update History'))
|
->setHeaderText(pht('Revision Update History'))
|
||||||
->setFlush(true)
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->setTable($content);
|
->setTable($content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,26 +48,37 @@ final class DiffusionBranchTableController extends DiffusionController {
|
||||||
->withRepository($repository)
|
->withRepository($repository)
|
||||||
->execute();
|
->execute();
|
||||||
|
|
||||||
$view = id(new DiffusionBranchTableView())
|
$table = id(new DiffusionBranchTableView())
|
||||||
->setUser($viewer)
|
->setUser($viewer)
|
||||||
->setBranches($branches)
|
->setBranches($branches)
|
||||||
->setCommits($commits)
|
->setCommits($commits)
|
||||||
->setDiffusionRequest($drequest);
|
->setDiffusionRequest($drequest);
|
||||||
|
|
||||||
$panel = id(new PHUIObjectBoxView())
|
$content = id(new PHUIObjectBoxView())
|
||||||
->setHeaderText(pht('Branches'))
|
->setHeaderText($repository->getName())
|
||||||
->setTable($view);
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
|
->setTable($table);
|
||||||
$content = $panel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$crumbs = $this->buildCrumbs(
|
$crumbs = $this->buildCrumbs(
|
||||||
array(
|
array(
|
||||||
'branches' => true,
|
'branches' => true,
|
||||||
));
|
));
|
||||||
|
$crumbs->setBorder(true);
|
||||||
|
|
||||||
$pager_box = $this->renderTablePagerBox($pager);
|
$pager_box = $this->renderTablePagerBox($pager);
|
||||||
|
|
||||||
|
$header = id(new PHUIHeaderView())
|
||||||
|
->setHeader(pht('Branches'))
|
||||||
|
->setHeaderIcon('fa-code-fork');
|
||||||
|
|
||||||
|
$view = id(new PHUITwoColumnView())
|
||||||
|
->setHeader($header)
|
||||||
|
->setFooter(array(
|
||||||
|
$content,
|
||||||
|
$pager_box,
|
||||||
|
));
|
||||||
|
|
||||||
return $this->newPage()
|
return $this->newPage()
|
||||||
->setTitle(
|
->setTitle(
|
||||||
array(
|
array(
|
||||||
|
@ -77,8 +88,7 @@ final class DiffusionBranchTableController extends DiffusionController {
|
||||||
->setCrumbs($crumbs)
|
->setCrumbs($crumbs)
|
||||||
->appendChild(
|
->appendChild(
|
||||||
array(
|
array(
|
||||||
$content,
|
$view,
|
||||||
$pager_box,
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,20 +55,17 @@ final class DiffusionBrowseController extends DiffusionController {
|
||||||
}
|
}
|
||||||
|
|
||||||
private function browseSearch() {
|
private function browseSearch() {
|
||||||
|
|
||||||
$drequest = $this->getDiffusionRequest();
|
$drequest = $this->getDiffusionRequest();
|
||||||
|
$header = $this->buildHeaderView($drequest);
|
||||||
|
|
||||||
$actions = $this->buildActionView($drequest);
|
$search_form = $this->renderSearchForm();
|
||||||
$properties = $this->buildPropertyView($drequest, $actions);
|
$search_results = $this->renderSearchResults();
|
||||||
|
|
||||||
$object_box = id(new PHUIObjectBoxView())
|
$search_form = id(new PHUIObjectBoxView())
|
||||||
->setHeader($this->buildHeaderView($drequest))
|
->setHeaderText(pht('Search'))
|
||||||
->addPropertyList($properties);
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
|
->appendChild($search_form);
|
||||||
$content = array();
|
|
||||||
|
|
||||||
$content[] = $object_box;
|
|
||||||
$content[] = $this->renderSearchForm($collapsed = false);
|
|
||||||
$content[] = $this->renderSearchResults();
|
|
||||||
|
|
||||||
$crumbs = $this->buildCrumbs(
|
$crumbs = $this->buildCrumbs(
|
||||||
array(
|
array(
|
||||||
|
@ -76,6 +73,14 @@ final class DiffusionBrowseController extends DiffusionController {
|
||||||
'path' => true,
|
'path' => true,
|
||||||
'view' => 'browse',
|
'view' => 'browse',
|
||||||
));
|
));
|
||||||
|
$crumbs->setBorder(true);
|
||||||
|
|
||||||
|
$view = id(new PHUITwoColumnView())
|
||||||
|
->setHeader($header)
|
||||||
|
->setFooter(array(
|
||||||
|
$search_form,
|
||||||
|
$search_results,
|
||||||
|
));
|
||||||
|
|
||||||
return $this->newPage()
|
return $this->newPage()
|
||||||
->setTitle(
|
->setTitle(
|
||||||
|
@ -84,7 +89,7 @@ final class DiffusionBrowseController extends DiffusionController {
|
||||||
$drequest->getRepository()->getDisplayName(),
|
$drequest->getRepository()->getDisplayName(),
|
||||||
))
|
))
|
||||||
->setCrumbs($crumbs)
|
->setCrumbs($crumbs)
|
||||||
->appendChild($content);
|
->appendChild($view);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function browseFile() {
|
private function browseFile() {
|
||||||
|
@ -187,7 +192,25 @@ final class DiffusionBrowseController extends DiffusionController {
|
||||||
}
|
}
|
||||||
|
|
||||||
$data = $file->loadFileData();
|
$data = $file->loadFileData();
|
||||||
if (ArcanistDiffUtils::isHeuristicBinaryFile($data)) {
|
|
||||||
|
$ref = $this->getGitLFSRef($repository, $data);
|
||||||
|
if ($ref) {
|
||||||
|
if ($view == 'git-lfs') {
|
||||||
|
$file = $this->loadGitLFSFile($ref);
|
||||||
|
|
||||||
|
// Rename the file locally so we generate a better vanity URI for
|
||||||
|
// it. In storage, it just has a name like "lfs-13f9a94c0923...",
|
||||||
|
// since we don't get any hints about possible human-readable names
|
||||||
|
// at upload time.
|
||||||
|
$basename = basename($drequest->getPath());
|
||||||
|
$file->makeEphemeral();
|
||||||
|
$file->setName($basename);
|
||||||
|
|
||||||
|
return $file->getRedirectResponse();
|
||||||
|
} else {
|
||||||
|
$corpus = $this->buildGitLFSCorpus($ref);
|
||||||
|
}
|
||||||
|
} else if (ArcanistDiffUtils::isHeuristicBinaryFile($data)) {
|
||||||
$file_uri = $file->getBestURI();
|
$file_uri = $file->getBestURI();
|
||||||
|
|
||||||
if ($file->isViewableImage()) {
|
if ($file->isViewableImage()) {
|
||||||
|
@ -218,20 +241,18 @@ final class DiffusionBrowseController extends DiffusionController {
|
||||||
require_celerity_resource('diffusion-source-css');
|
require_celerity_resource('diffusion-source-css');
|
||||||
|
|
||||||
// Render the page.
|
// Render the page.
|
||||||
$view = $this->buildActionView($drequest);
|
$view = $this->buildCurtain($drequest);
|
||||||
$action_list = $this->enrichActionView(
|
$curtain = $this->enrichCurtain(
|
||||||
$view,
|
$view,
|
||||||
$drequest,
|
$drequest,
|
||||||
$show_blame,
|
$show_blame,
|
||||||
$show_color);
|
$show_color);
|
||||||
|
|
||||||
$properties = $this->buildPropertyView($drequest, $action_list);
|
$properties = $this->buildPropertyView($drequest);
|
||||||
$object_box = id(new PHUIObjectBoxView())
|
$header = $this->buildHeaderView($drequest);
|
||||||
->setHeader($this->buildHeaderView($drequest))
|
$header->setHeaderIcon('fa-file-code-o');
|
||||||
->addPropertyList($properties);
|
|
||||||
|
|
||||||
$content = array();
|
$content = array();
|
||||||
$content[] = $object_box;
|
|
||||||
|
|
||||||
$follow = $request->getStr('follow');
|
$follow = $request->getStr('follow');
|
||||||
if ($follow) {
|
if ($follow) {
|
||||||
|
@ -277,17 +298,31 @@ final class DiffusionBrowseController extends DiffusionController {
|
||||||
'path' => true,
|
'path' => true,
|
||||||
'view' => 'browse',
|
'view' => 'browse',
|
||||||
));
|
));
|
||||||
|
$crumbs->setBorder(true);
|
||||||
|
|
||||||
$basename = basename($this->getDiffusionRequest()->getPath());
|
$basename = basename($this->getDiffusionRequest()->getPath());
|
||||||
|
|
||||||
|
$view = id(new PHUITwoColumnView())
|
||||||
|
->setHeader($header)
|
||||||
|
->setCurtain($curtain)
|
||||||
|
->setMainColumn(array(
|
||||||
|
$content,
|
||||||
|
));
|
||||||
|
|
||||||
|
if ($properties) {
|
||||||
|
$view->addPropertySection(pht('DETAILS'), $properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
$title = array($basename, $repository->getDisplayName());
|
||||||
|
|
||||||
return $this->newPage()
|
return $this->newPage()
|
||||||
->setTitle(
|
->setTitle($title)
|
||||||
array(
|
|
||||||
$basename,
|
|
||||||
$repository->getDisplayName(),
|
|
||||||
))
|
|
||||||
->setCrumbs($crumbs)
|
->setCrumbs($crumbs)
|
||||||
->appendChild($content);
|
->appendChild(
|
||||||
|
array(
|
||||||
|
$view,
|
||||||
|
));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function browseDirectory(
|
public function browseDirectory(
|
||||||
|
@ -300,23 +335,21 @@ final class DiffusionBrowseController extends DiffusionController {
|
||||||
|
|
||||||
$reason = $results->getReasonForEmptyResultSet();
|
$reason = $results->getReasonForEmptyResultSet();
|
||||||
|
|
||||||
$content = array();
|
$curtain = $this->buildCurtain($drequest);
|
||||||
$actions = $this->buildActionView($drequest);
|
$details = $this->buildPropertyView($drequest);
|
||||||
$properties = $this->buildPropertyView($drequest, $actions);
|
|
||||||
|
|
||||||
$object_box = id(new PHUIObjectBoxView())
|
$header = $this->buildHeaderView($drequest);
|
||||||
->setHeader($this->buildHeaderView($drequest))
|
$header->setHeaderIcon('fa-folder-open');
|
||||||
->addPropertyList($properties);
|
|
||||||
|
|
||||||
$content[] = $object_box;
|
$search_form = $this->renderSearchForm();
|
||||||
$content[] = $this->renderSearchForm($collapsed = true);
|
|
||||||
|
|
||||||
|
$empty_result = null;
|
||||||
|
$browse_panel = null;
|
||||||
if (!$results->isValidResults()) {
|
if (!$results->isValidResults()) {
|
||||||
$empty_result = new DiffusionEmptyResultView();
|
$empty_result = new DiffusionEmptyResultView();
|
||||||
$empty_result->setDiffusionRequest($drequest);
|
$empty_result->setDiffusionRequest($drequest);
|
||||||
$empty_result->setDiffusionBrowseResultSet($results);
|
$empty_result->setDiffusionBrowseResultSet($results);
|
||||||
$empty_result->setView($request->getStr('view'));
|
$empty_result->setView($request->getStr('view'));
|
||||||
$content[] = $empty_result;
|
|
||||||
} else {
|
} else {
|
||||||
$phids = array();
|
$phids = array();
|
||||||
foreach ($results->getPaths() as $result) {
|
foreach ($results->getPaths() as $result) {
|
||||||
|
@ -331,21 +364,30 @@ final class DiffusionBrowseController extends DiffusionController {
|
||||||
$phids = array_keys($phids);
|
$phids = array_keys($phids);
|
||||||
$handles = $this->loadViewerHandles($phids);
|
$handles = $this->loadViewerHandles($phids);
|
||||||
|
|
||||||
$browse_table = new DiffusionBrowseTableView();
|
$browse_table = id(new DiffusionBrowseTableView())
|
||||||
$browse_table->setDiffusionRequest($drequest);
|
->setDiffusionRequest($drequest)
|
||||||
$browse_table->setHandles($handles);
|
->setHandles($handles)
|
||||||
$browse_table->setPaths($results->getPaths());
|
->setPaths($results->getPaths())
|
||||||
$browse_table->setUser($request->getUser());
|
->setUser($request->getUser());
|
||||||
|
|
||||||
$browse_panel = new PHUIObjectBoxView();
|
$browse_header = id(new PHUIHeaderView())
|
||||||
$browse_panel->setHeaderText($drequest->getPath(), '/');
|
->setHeader(nonempty(basename($drequest->getPath()), '/'))
|
||||||
$browse_panel->setTable($browse_table);
|
->setHeaderIcon('fa-folder-open');
|
||||||
|
|
||||||
$content[] = $browse_panel;
|
$browse_panel = id(new PHUIObjectBoxView())
|
||||||
|
->setHeader($browse_header)
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
|
->setTable($browse_table);
|
||||||
|
|
||||||
|
$browse_panel->setShowHide(
|
||||||
|
array(pht('Show Search')),
|
||||||
|
pht('Hide Search'),
|
||||||
|
$search_form,
|
||||||
|
'#');
|
||||||
}
|
}
|
||||||
|
|
||||||
$content[] = $this->buildOpenRevisions();
|
$open_revisions = $this->buildOpenRevisions();
|
||||||
$content[] = $this->renderDirectoryReadme($results);
|
$readme = $this->renderDirectoryReadme($results);
|
||||||
|
|
||||||
$crumbs = $this->buildCrumbs(
|
$crumbs = $this->buildCrumbs(
|
||||||
array(
|
array(
|
||||||
|
@ -355,18 +397,34 @@ final class DiffusionBrowseController extends DiffusionController {
|
||||||
));
|
));
|
||||||
|
|
||||||
$pager_box = $this->renderTablePagerBox($pager);
|
$pager_box = $this->renderTablePagerBox($pager);
|
||||||
|
$crumbs->setBorder(true);
|
||||||
|
|
||||||
|
$view = id(new PHUITwoColumnView())
|
||||||
|
->setHeader($header)
|
||||||
|
->setCurtain($curtain)
|
||||||
|
->setMainColumn(array(
|
||||||
|
$empty_result,
|
||||||
|
$browse_panel,
|
||||||
|
))
|
||||||
|
->setFooter(array(
|
||||||
|
$open_revisions,
|
||||||
|
$readme,
|
||||||
|
$pager_box,
|
||||||
|
));
|
||||||
|
|
||||||
|
if ($details) {
|
||||||
|
$view->addPropertySection(pht('DETAILS'), $details);
|
||||||
|
}
|
||||||
|
|
||||||
return $this->newPage()
|
return $this->newPage()
|
||||||
->setTitle(
|
->setTitle(array(
|
||||||
array(
|
|
||||||
nonempty(basename($drequest->getPath()), '/'),
|
nonempty(basename($drequest->getPath()), '/'),
|
||||||
$repository->getDisplayName(),
|
$repository->getDisplayName(),
|
||||||
))
|
))
|
||||||
->setCrumbs($crumbs)
|
->setCrumbs($crumbs)
|
||||||
->appendChild(
|
->appendChild(
|
||||||
array(
|
array(
|
||||||
$content,
|
$view,
|
||||||
$pager_box,
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -431,6 +489,7 @@ final class DiffusionBrowseController extends DiffusionController {
|
||||||
|
|
||||||
$box = id(new PHUIObjectBoxView())
|
$box = id(new PHUIObjectBoxView())
|
||||||
->setHeaderText($header)
|
->setHeaderText($header)
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->setTable($table);
|
->setTable($table);
|
||||||
|
|
||||||
$pager_box = $this->renderTablePagerBox($pager);
|
$pager_box = $this->renderTablePagerBox($pager);
|
||||||
|
@ -697,12 +756,14 @@ final class DiffusionBrowseController extends DiffusionController {
|
||||||
$edit = $this->renderEditButton();
|
$edit = $this->renderEditButton();
|
||||||
$file = $this->renderFileButton();
|
$file = $this->renderFileButton();
|
||||||
$header = id(new PHUIHeaderView())
|
$header = id(new PHUIHeaderView())
|
||||||
->setHeader(pht('File Contents'))
|
->setHeader(basename($this->getDiffusionRequest()->getPath()))
|
||||||
|
->setHeaderIcon('fa-file-code-o')
|
||||||
->addActionLink($edit)
|
->addActionLink($edit)
|
||||||
->addActionLink($file);
|
->addActionLink($file);
|
||||||
|
|
||||||
$corpus = id(new PHUIObjectBoxView())
|
$corpus = id(new PHUIObjectBoxView())
|
||||||
->setHeader($header)
|
->setHeader($header)
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->appendChild($corpus)
|
->appendChild($corpus)
|
||||||
->setCollapsed(true);
|
->setCollapsed(true);
|
||||||
|
|
||||||
|
@ -737,16 +798,16 @@ final class DiffusionBrowseController extends DiffusionController {
|
||||||
return $corpus;
|
return $corpus;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function enrichActionView(
|
private function enrichCurtain(
|
||||||
PhabricatorActionListView $view,
|
PHUICurtainView $curtain,
|
||||||
DiffusionRequest $drequest,
|
DiffusionRequest $drequest,
|
||||||
$show_blame,
|
$show_blame,
|
||||||
$show_color) {
|
$show_color) {
|
||||||
|
|
||||||
$viewer = $this->getRequest()->getUser();
|
$viewer = $this->getViewer();
|
||||||
$base_uri = $this->getRequest()->getRequestURI();
|
$base_uri = $this->getRequest()->getRequestURI();
|
||||||
|
|
||||||
$view->addAction(
|
$curtain->addAction(
|
||||||
id(new PhabricatorActionView())
|
id(new PhabricatorActionView())
|
||||||
->setName(pht('Show Last Change'))
|
->setName(pht('Show Last Change'))
|
||||||
->setHref(
|
->setHref(
|
||||||
|
@ -766,7 +827,7 @@ final class DiffusionBrowseController extends DiffusionController {
|
||||||
$blame_value = 1;
|
$blame_value = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
$view->addAction(
|
$curtain->addAction(
|
||||||
id(new PhabricatorActionView())
|
id(new PhabricatorActionView())
|
||||||
->setName($blame_text)
|
->setName($blame_text)
|
||||||
->setHref($base_uri->alter('blame', $blame_value))
|
->setHref($base_uri->alter('blame', $blame_value))
|
||||||
|
@ -784,7 +845,7 @@ final class DiffusionBrowseController extends DiffusionController {
|
||||||
$highlight_value = 1;
|
$highlight_value = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
$view->addAction(
|
$curtain->addAction(
|
||||||
id(new PhabricatorActionView())
|
id(new PhabricatorActionView())
|
||||||
->setName($highlight_text)
|
->setName($highlight_text)
|
||||||
->setHref($base_uri->alter('color', $highlight_value))
|
->setHref($base_uri->alter('color', $highlight_value))
|
||||||
|
@ -809,14 +870,57 @@ final class DiffusionBrowseController extends DiffusionController {
|
||||||
))->alter('lint', '');
|
))->alter('lint', '');
|
||||||
}
|
}
|
||||||
|
|
||||||
$view->addAction(
|
$curtain->addAction(
|
||||||
id(new PhabricatorActionView())
|
id(new PhabricatorActionView())
|
||||||
->setName($lint_text)
|
->setName($lint_text)
|
||||||
->setHref($href)
|
->setHref($href)
|
||||||
->setIcon('fa-exclamation-triangle')
|
->setIcon('fa-exclamation-triangle')
|
||||||
->setDisabled(!$href));
|
->setDisabled(!$href));
|
||||||
|
|
||||||
return $view;
|
|
||||||
|
$repository = $drequest->getRepository();
|
||||||
|
|
||||||
|
$owners = 'PhabricatorOwnersApplication';
|
||||||
|
if (PhabricatorApplication::isClassInstalled($owners)) {
|
||||||
|
$package_query = id(new PhabricatorOwnersPackageQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withStatuses(array(PhabricatorOwnersPackage::STATUS_ACTIVE))
|
||||||
|
->withControl(
|
||||||
|
$repository->getPHID(),
|
||||||
|
array(
|
||||||
|
$drequest->getPath(),
|
||||||
|
));
|
||||||
|
|
||||||
|
$package_query->execute();
|
||||||
|
|
||||||
|
$packages = $package_query->getControllingPackagesForPath(
|
||||||
|
$repository->getPHID(),
|
||||||
|
$drequest->getPath());
|
||||||
|
|
||||||
|
if ($packages) {
|
||||||
|
$ownership = id(new PHUIStatusListView())
|
||||||
|
->setUser($viewer);
|
||||||
|
|
||||||
|
foreach ($packages as $package) {
|
||||||
|
$icon = 'fa-list-alt';
|
||||||
|
$color = 'grey';
|
||||||
|
|
||||||
|
$item = id(new PHUIStatusItemView())
|
||||||
|
->setIcon($icon, $color)
|
||||||
|
->setTarget($viewer->renderHandle($package->getPHID()));
|
||||||
|
|
||||||
|
$ownership->addItem($item);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$ownership = phutil_tag('em', array(), pht('None'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$curtain->newPanel()
|
||||||
|
->setHeaderText(pht('Owners'))
|
||||||
|
->appendChild($ownership);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $curtain;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function renderEditButton() {
|
private function renderEditButton() {
|
||||||
|
@ -844,7 +948,7 @@ final class DiffusionBrowseController extends DiffusionController {
|
||||||
return $button;
|
return $button;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function renderFileButton($file_uri = null) {
|
private function renderFileButton($file_uri = null, $label = null) {
|
||||||
|
|
||||||
$base_uri = $this->getRequest()->getRequestURI();
|
$base_uri = $this->getRequest()->getRequestURI();
|
||||||
|
|
||||||
|
@ -858,6 +962,10 @@ final class DiffusionBrowseController extends DiffusionController {
|
||||||
$icon = 'fa-file-text';
|
$icon = 'fa-file-text';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($label !== null) {
|
||||||
|
$text = $label;
|
||||||
|
}
|
||||||
|
|
||||||
$button = id(new PHUIButtonView())
|
$button = id(new PHUIButtonView())
|
||||||
->setTag('a')
|
->setTag('a')
|
||||||
->setText($text)
|
->setText($text)
|
||||||
|
@ -867,6 +975,21 @@ final class DiffusionBrowseController extends DiffusionController {
|
||||||
return $button;
|
return $button;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function renderGitLFSButton() {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
|
$uri = $this->getRequest()->getRequestURI();
|
||||||
|
$href = $uri->alter('view', 'git-lfs');
|
||||||
|
|
||||||
|
$text = pht('Download from Git LFS');
|
||||||
|
$icon = 'fa-download';
|
||||||
|
|
||||||
|
return id(new PHUIButtonView())
|
||||||
|
->setTag('a')
|
||||||
|
->setText($text)
|
||||||
|
->setHref($href)
|
||||||
|
->setIcon($icon);
|
||||||
|
}
|
||||||
|
|
||||||
private function buildDisplayRows(
|
private function buildDisplayRows(
|
||||||
array $lines,
|
array $lines,
|
||||||
|
@ -1265,11 +1388,13 @@ final class DiffusionBrowseController extends DiffusionController {
|
||||||
|
|
||||||
$file = $this->renderFileButton($file_uri);
|
$file = $this->renderFileButton($file_uri);
|
||||||
$header = id(new PHUIHeaderView())
|
$header = id(new PHUIHeaderView())
|
||||||
->setHeader(pht('Image'))
|
->setHeader(basename($this->getDiffusionRequest()->getPath()))
|
||||||
->addActionLink($file);
|
->addActionLink($file)
|
||||||
|
->setHeaderIcon('fa-file-image-o');
|
||||||
|
|
||||||
return id(new PHUIObjectBoxView())
|
return id(new PHUIObjectBoxView())
|
||||||
->setHeader($header)
|
->setHeader($header)
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->addPropertyList($properties);
|
->addPropertyList($properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1282,11 +1407,12 @@ final class DiffusionBrowseController extends DiffusionController {
|
||||||
|
|
||||||
$file = $this->renderFileButton($file_uri);
|
$file = $this->renderFileButton($file_uri);
|
||||||
$header = id(new PHUIHeaderView())
|
$header = id(new PHUIHeaderView())
|
||||||
->setHeader(pht('Details'))
|
->setHeader(pht('DETAILS'))
|
||||||
->addActionLink($file);
|
->addActionLink($file);
|
||||||
|
|
||||||
$box = id(new PHUIObjectBoxView())
|
$box = id(new PHUIObjectBoxView())
|
||||||
->setHeader($header)
|
->setHeader($header)
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->appendChild($text);
|
->appendChild($text);
|
||||||
|
|
||||||
return $box;
|
return $box;
|
||||||
|
@ -1298,7 +1424,7 @@ final class DiffusionBrowseController extends DiffusionController {
|
||||||
->appendChild($message);
|
->appendChild($message);
|
||||||
|
|
||||||
$header = id(new PHUIHeaderView())
|
$header = id(new PHUIHeaderView())
|
||||||
->setHeader(pht('Details'));
|
->setHeader(pht('DETAILS'));
|
||||||
|
|
||||||
$box = id(new PHUIObjectBoxView())
|
$box = id(new PHUIObjectBoxView())
|
||||||
->setHeader($header)
|
->setHeader($header)
|
||||||
|
@ -1461,12 +1587,12 @@ final class DiffusionBrowseController extends DiffusionController {
|
||||||
return "{$summary}\n{$date} \xC2\xB7 {$author}";
|
return "{$summary}\n{$date} \xC2\xB7 {$author}";
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function renderSearchForm($collapsed) {
|
protected function renderSearchForm() {
|
||||||
$drequest = $this->getDiffusionRequest();
|
$drequest = $this->getDiffusionRequest();
|
||||||
|
|
||||||
$forms = array();
|
$forms = array();
|
||||||
$form = id(new AphrontFormView())
|
$form = id(new AphrontFormView())
|
||||||
->setUser($this->getRequest()->getUser())
|
->setUser($this->getViewer())
|
||||||
->setMethod('GET');
|
->setMethod('GET');
|
||||||
|
|
||||||
switch ($drequest->getRepository()->getVersionControlSystem()) {
|
switch ($drequest->getRepository()->getVersionControlSystem()) {
|
||||||
|
@ -1492,22 +1618,10 @@ final class DiffusionBrowseController extends DiffusionController {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$filter = new AphrontListFilterView();
|
require_celerity_resource('diffusion-icons-css');
|
||||||
$filter->appendChild($forms);
|
$form_box = phutil_tag_div('diffusion-search-boxen', $forms);
|
||||||
|
|
||||||
if ($collapsed) {
|
return $form_box;
|
||||||
$filter->setCollapsed(
|
|
||||||
pht('Show Search'),
|
|
||||||
pht('Hide Search'),
|
|
||||||
pht('Search for file names or content in this directory.'),
|
|
||||||
'#');
|
|
||||||
}
|
|
||||||
|
|
||||||
$filter = id(new PHUIBoxView())
|
|
||||||
->addClass('mlt mlb')
|
|
||||||
->appendChild($filter);
|
|
||||||
|
|
||||||
return $filter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function markupText($text) {
|
protected function markupText($text) {
|
||||||
|
@ -1526,28 +1640,29 @@ final class DiffusionBrowseController extends DiffusionController {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function buildHeaderView(DiffusionRequest $drequest) {
|
protected function buildHeaderView(DiffusionRequest $drequest) {
|
||||||
$viewer = $this->getRequest()->getUser();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
|
$tag = $this->renderCommitHashTag($drequest);
|
||||||
|
|
||||||
$header = id(new PHUIHeaderView())
|
$header = id(new PHUIHeaderView())
|
||||||
->setUser($viewer)
|
->setUser($viewer)
|
||||||
->setHeader($this->renderPathLinks($drequest, $mode = 'browse'))
|
->setHeader($this->renderPathLinks($drequest, $mode = 'browse'))
|
||||||
->setPolicyObject($drequest->getRepository());
|
->addTag($tag);
|
||||||
|
|
||||||
return $header;
|
return $header;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function buildActionView(DiffusionRequest $drequest) {
|
protected function buildCurtain(DiffusionRequest $drequest) {
|
||||||
$viewer = $this->getRequest()->getUser();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$view = id(new PhabricatorActionListView())
|
$curtain = $this->newCurtainView($drequest);
|
||||||
->setUser($viewer);
|
|
||||||
|
|
||||||
$history_uri = $drequest->generateURI(
|
$history_uri = $drequest->generateURI(
|
||||||
array(
|
array(
|
||||||
'action' => 'history',
|
'action' => 'history',
|
||||||
));
|
));
|
||||||
|
|
||||||
$view->addAction(
|
$curtain->addAction(
|
||||||
id(new PhabricatorActionView())
|
id(new PhabricatorActionView())
|
||||||
->setName(pht('View History'))
|
->setName(pht('View History'))
|
||||||
->setHref($history_uri)
|
->setHref($history_uri)
|
||||||
|
@ -1559,40 +1674,22 @@ final class DiffusionBrowseController extends DiffusionController {
|
||||||
'commit' => '',
|
'commit' => '',
|
||||||
'action' => 'browse',
|
'action' => 'browse',
|
||||||
));
|
));
|
||||||
$view->addAction(
|
$curtain->addAction(
|
||||||
id(new PhabricatorActionView())
|
id(new PhabricatorActionView())
|
||||||
->setName(pht('Jump to HEAD'))
|
->setName(pht('Jump to HEAD'))
|
||||||
->setHref($head_uri)
|
->setHref($head_uri)
|
||||||
->setIcon('fa-home')
|
->setIcon('fa-home')
|
||||||
->setDisabled(!$behind_head));
|
->setDisabled(!$behind_head));
|
||||||
|
|
||||||
return $view;
|
return $curtain;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function buildPropertyView(
|
protected function buildPropertyView(
|
||||||
DiffusionRequest $drequest,
|
DiffusionRequest $drequest) {
|
||||||
PhabricatorActionListView $actions) {
|
|
||||||
|
|
||||||
$viewer = $this->getViewer();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$view = id(new PHUIPropertyListView())
|
$view = id(new PHUIPropertyListView())
|
||||||
->setUser($viewer)
|
->setUser($viewer);
|
||||||
->setActionList($actions);
|
|
||||||
|
|
||||||
$stable_commit = $drequest->getStableCommit();
|
|
||||||
|
|
||||||
$view->addProperty(
|
|
||||||
pht('Commit'),
|
|
||||||
phutil_tag(
|
|
||||||
'a',
|
|
||||||
array(
|
|
||||||
'href' => $drequest->generateURI(
|
|
||||||
array(
|
|
||||||
'action' => 'commit',
|
|
||||||
'commit' => $stable_commit,
|
|
||||||
)),
|
|
||||||
),
|
|
||||||
$drequest->getRepository()->formatCommitName($stable_commit)));
|
|
||||||
|
|
||||||
if ($drequest->getSymbolicType() == 'tag') {
|
if ($drequest->getSymbolicType() == 'tag') {
|
||||||
$symbolic = $drequest->getSymbolicCommit();
|
$symbolic = $drequest->getSymbolicCommit();
|
||||||
|
@ -1616,49 +1713,13 @@ final class DiffusionBrowseController extends DiffusionController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$repository = $drequest->getRepository();
|
if ($view->hasAnyProperties()) {
|
||||||
|
|
||||||
$owners = 'PhabricatorOwnersApplication';
|
|
||||||
if (PhabricatorApplication::isClassInstalled($owners)) {
|
|
||||||
$package_query = id(new PhabricatorOwnersPackageQuery())
|
|
||||||
->setViewer($viewer)
|
|
||||||
->withStatuses(array(PhabricatorOwnersPackage::STATUS_ACTIVE))
|
|
||||||
->withControl(
|
|
||||||
$repository->getPHID(),
|
|
||||||
array(
|
|
||||||
$drequest->getPath(),
|
|
||||||
));
|
|
||||||
|
|
||||||
$package_query->execute();
|
|
||||||
|
|
||||||
$packages = $package_query->getControllingPackagesForPath(
|
|
||||||
$repository->getPHID(),
|
|
||||||
$drequest->getPath());
|
|
||||||
|
|
||||||
if ($packages) {
|
|
||||||
$ownership = id(new PHUIStatusListView())
|
|
||||||
->setUser($viewer);
|
|
||||||
|
|
||||||
foreach ($packages as $package) {
|
|
||||||
$icon = 'fa-list-alt';
|
|
||||||
$color = 'grey';
|
|
||||||
|
|
||||||
$item = id(new PHUIStatusItemView())
|
|
||||||
->setIcon($icon, $color)
|
|
||||||
->setTarget($viewer->renderHandle($package->getPHID()));
|
|
||||||
|
|
||||||
$ownership->addItem($item);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$ownership = phutil_tag('em', array(), pht('None'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$view->addProperty(pht('Packages'), $ownership);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $view;
|
return $view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private function buildOpenRevisions() {
|
private function buildOpenRevisions() {
|
||||||
$viewer = $this->getViewer();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
|
@ -1865,4 +1926,90 @@ final class DiffusionBrowseController extends DiffusionController {
|
||||||
$corpus);
|
$corpus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function getGitLFSRef(PhabricatorRepository $repository, $data) {
|
||||||
|
if (!$repository->canUseGitLFS()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$lfs_pattern = '(^version https://git-lfs\\.github\\.com/spec/v1[\r\n])';
|
||||||
|
if (!preg_match($lfs_pattern, $data)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$matches = null;
|
||||||
|
if (!preg_match('(^oid sha256:(.*)$)m', $data, $matches)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$hash = $matches[1];
|
||||||
|
$hash = trim($hash);
|
||||||
|
|
||||||
|
return id(new PhabricatorRepositoryGitLFSRefQuery())
|
||||||
|
->setViewer($this->getViewer())
|
||||||
|
->withRepositoryPHIDs(array($repository->getPHID()))
|
||||||
|
->withObjectHashes(array($hash))
|
||||||
|
->executeOne();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildGitLFSCorpus(PhabricatorRepositoryGitLFSRef $ref) {
|
||||||
|
// TODO: We should probably test if we can load the file PHID here and
|
||||||
|
// show the user an error if we can't, rather than making them click
|
||||||
|
// through to hit an error.
|
||||||
|
|
||||||
|
$header = id(new PHUIHeaderView())
|
||||||
|
->setHeader(basename($this->getDiffusionRequest()->getPath()))
|
||||||
|
->setHeaderIcon('fa-archive');
|
||||||
|
|
||||||
|
$severity = PHUIInfoView::SEVERITY_NOTICE;
|
||||||
|
|
||||||
|
$messages = array();
|
||||||
|
$messages[] = pht(
|
||||||
|
'This %s file is stored in Git Large File Storage.',
|
||||||
|
phutil_format_bytes($ref->getByteSize()));
|
||||||
|
|
||||||
|
try {
|
||||||
|
$file = $this->loadGitLFSFile($ref);
|
||||||
|
$data = $this->renderGitLFSButton();
|
||||||
|
$header->addActionLink($data);
|
||||||
|
} catch (Exception $ex) {
|
||||||
|
$severity = PHUIInfoView::SEVERITY_ERROR;
|
||||||
|
$messages[] = pht('The data for this file could not be loaded.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$raw = $this->renderFileButton(null, pht('View Raw LFS Pointer'));
|
||||||
|
$header->addActionLink($raw);
|
||||||
|
|
||||||
|
$corpus = id(new PHUIObjectBoxView())
|
||||||
|
->setHeader($header)
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
|
->setCollapsed(true);
|
||||||
|
|
||||||
|
if ($messages) {
|
||||||
|
$corpus->setInfoView(
|
||||||
|
id(new PHUIInfoView())
|
||||||
|
->setSeverity($severity)
|
||||||
|
->setErrors($messages));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $corpus;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function loadGitLFSFile(PhabricatorRepositoryGitLFSRef $ref) {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
|
$file = id(new PhabricatorFileQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withPHIDs(array($ref->getFilePHID()))
|
||||||
|
->executeOne();
|
||||||
|
if (!$file) {
|
||||||
|
throw new Exception(
|
||||||
|
pht(
|
||||||
|
'Failed to load file object for Git LFS ref "%s"!',
|
||||||
|
$ref->getObjectHash()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,6 @@ final class DiffusionChangeController extends DiffusionController {
|
||||||
$viewer = $this->getViewer();
|
$viewer = $this->getViewer();
|
||||||
$drequest = $this->getDiffusionRequest();
|
$drequest = $this->getDiffusionRequest();
|
||||||
|
|
||||||
$content = array();
|
|
||||||
|
|
||||||
$data = $this->callConduitWithDiffusionRequest(
|
$data = $this->callConduitWithDiffusionRequest(
|
||||||
'diffusion.diffquery',
|
'diffusion.diffquery',
|
||||||
array(
|
array(
|
||||||
|
@ -42,9 +40,11 @@ final class DiffusionChangeController extends DiffusionController {
|
||||||
0 => $changeset,
|
0 => $changeset,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$changeset_header = $this->buildChangesetHeader($drequest);
|
||||||
|
|
||||||
$changeset_view = new DifferentialChangesetListView();
|
$changeset_view = new DifferentialChangesetListView();
|
||||||
$changeset_view->setTitle(pht('Change'));
|
|
||||||
$changeset_view->setChangesets($changesets);
|
$changeset_view->setChangesets($changesets);
|
||||||
|
$changeset_view->setBackground(PHUIObjectBoxView::BLUE_PROPERTY);
|
||||||
$changeset_view->setVisibleChangesets($changesets);
|
$changeset_view->setVisibleChangesets($changesets);
|
||||||
$changeset_view->setRenderingReferences(
|
$changeset_view->setRenderingReferences(
|
||||||
array(
|
array(
|
||||||
|
@ -68,11 +68,11 @@ final class DiffusionChangeController extends DiffusionController {
|
||||||
$changeset_view->setWhitespace(
|
$changeset_view->setWhitespace(
|
||||||
DifferentialChangesetParser::WHITESPACE_SHOW_ALL);
|
DifferentialChangesetParser::WHITESPACE_SHOW_ALL);
|
||||||
$changeset_view->setUser($viewer);
|
$changeset_view->setUser($viewer);
|
||||||
|
$changeset_view->setHeader($changeset_header);
|
||||||
|
|
||||||
// TODO: This is pretty awkward, unify the CSS between Diffusion and
|
// TODO: This is pretty awkward, unify the CSS between Diffusion and
|
||||||
// Differential better.
|
// Differential better.
|
||||||
require_celerity_resource('differential-core-view-css');
|
require_celerity_resource('differential-core-view-css');
|
||||||
$content[] = $changeset_view->render();
|
|
||||||
|
|
||||||
$crumbs = $this->buildCrumbs(
|
$crumbs = $this->buildCrumbs(
|
||||||
array(
|
array(
|
||||||
|
@ -80,19 +80,18 @@ final class DiffusionChangeController extends DiffusionController {
|
||||||
'path' => true,
|
'path' => true,
|
||||||
'view' => 'change',
|
'view' => 'change',
|
||||||
));
|
));
|
||||||
|
$crumbs->setBorder(true);
|
||||||
|
|
||||||
$links = $this->renderPathLinks($drequest, $mode = 'browse');
|
$links = $this->renderPathLinks($drequest, $mode = 'browse');
|
||||||
|
$header = $this->buildHeader($drequest, $links);
|
||||||
|
|
||||||
$header = id(new PHUIHeaderView())
|
$view = id(new PHUITwoColumnView())
|
||||||
->setHeader($links)
|
|
||||||
->setUser($viewer)
|
|
||||||
->setPolicyObject($drequest->getRepository());
|
|
||||||
$actions = $this->buildActionView($drequest);
|
|
||||||
$properties = $this->buildPropertyView($drequest, $actions);
|
|
||||||
|
|
||||||
$object_box = id(new PHUIObjectBoxView())
|
|
||||||
->setHeader($header)
|
->setHeader($header)
|
||||||
->addPropertyList($properties);
|
->setMainColumn(array(
|
||||||
|
))
|
||||||
|
->setFooter(array(
|
||||||
|
$changeset_view,
|
||||||
|
));
|
||||||
|
|
||||||
return $this->newPage()
|
return $this->newPage()
|
||||||
->setTitle(
|
->setTitle(
|
||||||
|
@ -103,25 +102,41 @@ final class DiffusionChangeController extends DiffusionController {
|
||||||
->setCrumbs($crumbs)
|
->setCrumbs($crumbs)
|
||||||
->appendChild(
|
->appendChild(
|
||||||
array(
|
array(
|
||||||
$object_box,
|
$view,
|
||||||
$content,
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildActionView(DiffusionRequest $drequest) {
|
private function buildHeader(
|
||||||
$viewer = $this->getRequest()->getUser();
|
DiffusionRequest $drequest,
|
||||||
|
$links) {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$view = id(new PhabricatorActionListView())
|
$tag = $this->renderCommitHashTag($drequest);
|
||||||
->setUser($viewer);
|
|
||||||
|
$header = id(new PHUIHeaderView())
|
||||||
|
->setHeader($links)
|
||||||
|
->setUser($viewer)
|
||||||
|
->setPolicyObject($drequest->getRepository())
|
||||||
|
->addTag($tag);
|
||||||
|
|
||||||
|
return $header;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildChangesetHeader(DiffusionRequest $drequest) {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
|
$header = id(new PHUIHeaderView())
|
||||||
|
->setHeader(pht('Changes'));
|
||||||
|
|
||||||
$history_uri = $drequest->generateURI(
|
$history_uri = $drequest->generateURI(
|
||||||
array(
|
array(
|
||||||
'action' => 'history',
|
'action' => 'history',
|
||||||
));
|
));
|
||||||
|
|
||||||
$view->addAction(
|
$header->addActionLink(
|
||||||
id(new PhabricatorActionView())
|
id(new PHUIButtonView())
|
||||||
->setName(pht('View History'))
|
->setTag('a')
|
||||||
|
->setText(pht('View History'))
|
||||||
->setHref($history_uri)
|
->setHref($history_uri)
|
||||||
->setIcon('fa-clock-o'));
|
->setIcon('fa-clock-o'));
|
||||||
|
|
||||||
|
@ -130,13 +145,14 @@ final class DiffusionChangeController extends DiffusionController {
|
||||||
'action' => 'browse',
|
'action' => 'browse',
|
||||||
));
|
));
|
||||||
|
|
||||||
$view->addAction(
|
$header->addActionLink(
|
||||||
id(new PhabricatorActionView())
|
id(new PHUIButtonView())
|
||||||
->setName(pht('Browse Content'))
|
->setTag('a')
|
||||||
|
->setText(pht('Browse Content'))
|
||||||
->setHref($browse_uri)
|
->setHref($browse_uri)
|
||||||
->setIcon('fa-files-o'));
|
->setIcon('fa-files-o'));
|
||||||
|
|
||||||
return $view;
|
return $header;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function buildPropertyView(
|
protected function buildPropertyView(
|
||||||
|
|
|
@ -24,8 +24,7 @@ final class DiffusionCommitController extends DiffusionController {
|
||||||
}
|
}
|
||||||
|
|
||||||
$drequest = $this->getDiffusionRequest();
|
$drequest = $this->getDiffusionRequest();
|
||||||
|
$viewer = $request->getUser();
|
||||||
$user = $request->getUser();
|
|
||||||
|
|
||||||
if ($request->getStr('diff')) {
|
if ($request->getStr('diff')) {
|
||||||
return $this->buildRawDiffResponse($drequest);
|
return $this->buildRawDiffResponse($drequest);
|
||||||
|
@ -33,9 +32,8 @@ final class DiffusionCommitController extends DiffusionController {
|
||||||
|
|
||||||
$repository = $drequest->getRepository();
|
$repository = $drequest->getRepository();
|
||||||
|
|
||||||
$content = array();
|
|
||||||
$commit = id(new DiffusionCommitQuery())
|
$commit = id(new DiffusionCommitQuery())
|
||||||
->setViewer($request->getUser())
|
->setViewer($viewer)
|
||||||
->withRepository($repository)
|
->withRepository($repository)
|
||||||
->withIdentifiers(array($drequest->getCommit()))
|
->withIdentifiers(array($drequest->getCommit()))
|
||||||
->needCommitData(true)
|
->needCommitData(true)
|
||||||
|
@ -45,6 +43,7 @@ final class DiffusionCommitController extends DiffusionController {
|
||||||
$crumbs = $this->buildCrumbs(array(
|
$crumbs = $this->buildCrumbs(array(
|
||||||
'commit' => true,
|
'commit' => true,
|
||||||
));
|
));
|
||||||
|
$crumbs->setBorder(true);
|
||||||
|
|
||||||
if (!$commit) {
|
if (!$commit) {
|
||||||
if (!$this->getCommitExists()) {
|
if (!$this->getCommitExists()) {
|
||||||
|
@ -70,10 +69,11 @@ final class DiffusionCommitController extends DiffusionController {
|
||||||
|
|
||||||
$audit_requests = $commit->getAudits();
|
$audit_requests = $commit->getAudits();
|
||||||
$this->auditAuthorityPHIDs =
|
$this->auditAuthorityPHIDs =
|
||||||
PhabricatorAuditCommentEditor::loadAuditPHIDsForUser($user);
|
PhabricatorAuditCommentEditor::loadAuditPHIDsForUser($viewer);
|
||||||
|
|
||||||
$commit_data = $commit->getCommitData();
|
$commit_data = $commit->getCommitData();
|
||||||
$is_foreign = $commit_data->getCommitDetail('foreign-svn-stub');
|
$is_foreign = $commit_data->getCommitDetail('foreign-svn-stub');
|
||||||
|
$error_panel = null;
|
||||||
if ($is_foreign) {
|
if ($is_foreign) {
|
||||||
$subpath = $commit_data->getCommitDetail('svn-subpath');
|
$subpath = $commit_data->getCommitDetail('svn-subpath');
|
||||||
|
|
||||||
|
@ -87,43 +87,41 @@ final class DiffusionCommitController extends DiffusionController {
|
||||||
"didn't affect the tracked subdirectory ('%s'), so no ".
|
"didn't affect the tracked subdirectory ('%s'), so no ".
|
||||||
"information is available.",
|
"information is available.",
|
||||||
$subpath));
|
$subpath));
|
||||||
$content[] = $error_panel;
|
|
||||||
} else {
|
} else {
|
||||||
$engine = PhabricatorMarkupEngine::newDifferentialMarkupEngine();
|
$engine = PhabricatorMarkupEngine::newDifferentialMarkupEngine();
|
||||||
$engine->setConfig('viewer', $user);
|
$engine->setConfig('viewer', $viewer);
|
||||||
|
|
||||||
$headsup_view = id(new PHUIHeaderView())
|
$commit_tag = $this->renderCommitHashTag($drequest);
|
||||||
|
$header = id(new PHUIHeaderView())
|
||||||
->setHeader(nonempty($commit->getSummary(), pht('Commit Detail')))
|
->setHeader(nonempty($commit->getSummary(), pht('Commit Detail')))
|
||||||
->setSubheader(pht('Commit: %s', $commit->getCommitIdentifier()));
|
->setHeaderIcon('fa-code-fork')
|
||||||
|
->addTag($commit_tag);
|
||||||
|
|
||||||
$headsup_actions = $this->renderHeadsupActionList($commit, $repository);
|
if ($commit->getAuditStatus()) {
|
||||||
|
$icon = PhabricatorAuditCommitStatusConstants::getStatusIcon(
|
||||||
|
$commit->getAuditStatus());
|
||||||
|
$color = PhabricatorAuditCommitStatusConstants::getStatusColor(
|
||||||
|
$commit->getAuditStatus());
|
||||||
|
$status = PhabricatorAuditCommitStatusConstants::getStatusName(
|
||||||
|
$commit->getAuditStatus());
|
||||||
|
|
||||||
$commit_properties = $this->loadCommitProperties(
|
$header->setStatus($icon, $color, $status);
|
||||||
|
}
|
||||||
|
|
||||||
|
$curtain = $this->buildCurtain($commit, $repository);
|
||||||
|
$subheader = $this->buildSubheaderView($commit, $commit_data);
|
||||||
|
$details = $this->buildPropertyListView(
|
||||||
$commit,
|
$commit,
|
||||||
$commit_data,
|
$commit_data,
|
||||||
$audit_requests);
|
$audit_requests);
|
||||||
$property_list = id(new PHUIPropertyListView())
|
|
||||||
->setHasKeyboardShortcuts(true)
|
|
||||||
->setUser($user)
|
|
||||||
->setObject($commit);
|
|
||||||
foreach ($commit_properties as $key => $value) {
|
|
||||||
$property_list->addProperty($key, $value);
|
|
||||||
}
|
|
||||||
|
|
||||||
$message = $commit_data->getCommitMessage();
|
$message = $commit_data->getCommitMessage();
|
||||||
|
|
||||||
$revision = $commit->getCommitIdentifier();
|
$revision = $commit->getCommitIdentifier();
|
||||||
$message = $this->linkBugtraq($message);
|
$message = $this->linkBugtraq($message);
|
||||||
|
|
||||||
$message = $engine->markupText($message);
|
$message = $engine->markupText($message);
|
||||||
|
|
||||||
$property_list->invokeWillRenderEvent();
|
|
||||||
$property_list->setActionList($headsup_actions);
|
|
||||||
|
|
||||||
$detail_list = new PHUIPropertyListView();
|
$detail_list = new PHUIPropertyListView();
|
||||||
$detail_list->addSectionHeader(
|
|
||||||
pht('Description'),
|
|
||||||
PHUIPropertyListView::ICON_SUMMARY);
|
|
||||||
$detail_list->addTextContent(
|
$detail_list->addTextContent(
|
||||||
phutil_tag(
|
phutil_tag(
|
||||||
'div',
|
'div',
|
||||||
|
@ -132,19 +130,14 @@ final class DiffusionCommitController extends DiffusionController {
|
||||||
),
|
),
|
||||||
$message));
|
$message));
|
||||||
|
|
||||||
$headsup_view->setTall(true);
|
if ($this->getCommitErrors()) {
|
||||||
|
$error_panel = id(new PHUIInfoView())
|
||||||
$object_box = id(new PHUIObjectBoxView())
|
->appendChild($this->getCommitErrors())
|
||||||
->setHeader($headsup_view)
|
->setSeverity(PHUIInfoView::SEVERITY_WARNING);
|
||||||
->setFormErrors($this->getCommitErrors())
|
}
|
||||||
->addPropertyList($property_list)
|
|
||||||
->addPropertyList($detail_list);
|
|
||||||
|
|
||||||
$content[] = $object_box;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$content[] = $this->buildComments($commit);
|
$timeline = $this->buildComments($commit);
|
||||||
|
|
||||||
$hard_limit = 1000;
|
$hard_limit = 1000;
|
||||||
|
|
||||||
if ($commit->isImported()) {
|
if ($commit->isImported()) {
|
||||||
|
@ -161,10 +154,10 @@ final class DiffusionCommitController extends DiffusionController {
|
||||||
$changes = array_slice($changes, 0, $hard_limit);
|
$changes = array_slice($changes, 0, $hard_limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
$content[] = $this->buildMergesTable($commit);
|
$merge_table = $this->buildMergesTable($commit);
|
||||||
|
|
||||||
$highlighted_audits = $commit->getAuthorityAudits(
|
$highlighted_audits = $commit->getAuthorityAudits(
|
||||||
$user,
|
$viewer,
|
||||||
$this->auditAuthorityPHIDs);
|
$this->auditAuthorityPHIDs);
|
||||||
|
|
||||||
$count = count($changes);
|
$count = count($changes);
|
||||||
|
@ -179,32 +172,35 @@ final class DiffusionCommitController extends DiffusionController {
|
||||||
}
|
}
|
||||||
|
|
||||||
$show_changesets = false;
|
$show_changesets = false;
|
||||||
|
$info_panel = null;
|
||||||
|
$change_list = null;
|
||||||
|
$change_table = null;
|
||||||
if ($bad_commit) {
|
if ($bad_commit) {
|
||||||
$content[] = $this->renderStatusMessage(
|
$info_panel = $this->renderStatusMessage(
|
||||||
pht('Bad Commit'),
|
pht('Bad Commit'),
|
||||||
$bad_commit['description']);
|
$bad_commit['description']);
|
||||||
} else if ($is_foreign) {
|
} else if ($is_foreign) {
|
||||||
// Don't render anything else.
|
// Don't render anything else.
|
||||||
} else if (!$commit->isImported()) {
|
} else if (!$commit->isImported()) {
|
||||||
$content[] = $this->renderStatusMessage(
|
$info_panel = $this->renderStatusMessage(
|
||||||
pht('Still Importing...'),
|
pht('Still Importing...'),
|
||||||
pht(
|
pht(
|
||||||
'This commit is still importing. Changes will be visible once '.
|
'This commit is still importing. Changes will be visible once '.
|
||||||
'the import finishes.'));
|
'the import finishes.'));
|
||||||
} else if (!count($changes)) {
|
} else if (!count($changes)) {
|
||||||
$content[] = $this->renderStatusMessage(
|
$info_panel = $this->renderStatusMessage(
|
||||||
pht('Empty Commit'),
|
pht('Empty Commit'),
|
||||||
pht(
|
pht(
|
||||||
'This commit is empty and does not affect any paths.'));
|
'This commit is empty and does not affect any paths.'));
|
||||||
} else if ($was_limited) {
|
} else if ($was_limited) {
|
||||||
$content[] = $this->renderStatusMessage(
|
$info_panel = $this->renderStatusMessage(
|
||||||
pht('Enormous Commit'),
|
pht('Enormous Commit'),
|
||||||
pht(
|
pht(
|
||||||
'This commit is enormous, and affects more than %d files. '.
|
'This commit is enormous, and affects more than %d files. '.
|
||||||
'Changes are not shown.',
|
'Changes are not shown.',
|
||||||
$hard_limit));
|
$hard_limit));
|
||||||
} else if (!$this->getCommitExists()) {
|
} else if (!$this->getCommitExists()) {
|
||||||
$content[] = $this->renderStatusMessage(
|
$info_panel = $this->renderStatusMessage(
|
||||||
pht('Commit No Longer Exists'),
|
pht('Commit No Longer Exists'),
|
||||||
pht('This commit no longer exists in the repository.'));
|
pht('This commit no longer exists in the repository.'));
|
||||||
} else {
|
} else {
|
||||||
|
@ -214,13 +210,11 @@ final class DiffusionCommitController extends DiffusionController {
|
||||||
// changes inline even if there are more than the soft limit.
|
// changes inline even if there are more than the soft limit.
|
||||||
$show_all_details = $request->getBool('show_all');
|
$show_all_details = $request->getBool('show_all');
|
||||||
|
|
||||||
$change_panel = new PHUIObjectBoxView();
|
$change_header = id(new PHUIHeaderView())
|
||||||
$header = new PHUIHeaderView();
|
->setHeader(pht('Changes (%s)', new PhutilNumber($count)));
|
||||||
$header->setHeader(pht('Changes (%s)', new PhutilNumber($count)));
|
|
||||||
$change_panel->setID('toc');
|
|
||||||
|
|
||||||
|
$warning_view = null;
|
||||||
if ($count > self::CHANGES_LIMIT && !$show_all_details) {
|
if ($count > self::CHANGES_LIMIT && !$show_all_details) {
|
||||||
|
|
||||||
$button = id(new PHUIButtonView())
|
$button = id(new PHUIButtonView())
|
||||||
->setText(pht('Show All Changes'))
|
->setText(pht('Show All Changes'))
|
||||||
->setHref('?show_all=true')
|
->setHref('?show_all=true')
|
||||||
|
@ -233,23 +227,19 @@ final class DiffusionCommitController extends DiffusionController {
|
||||||
->appendChild(
|
->appendChild(
|
||||||
pht('This commit is very large. Load each file individually.'));
|
pht('This commit is very large. Load each file individually.'));
|
||||||
|
|
||||||
$change_panel->setInfoView($warning_view);
|
$change_header->addActionLink($button);
|
||||||
$header->addActionLink($button);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$changesets = DiffusionPathChange::convertToDifferentialChangesets(
|
$changesets = DiffusionPathChange::convertToDifferentialChangesets(
|
||||||
$user,
|
$viewer,
|
||||||
$changes);
|
$changes);
|
||||||
|
|
||||||
// TODO: This table and panel shouldn't really be separate, but we need
|
// TODO: This table and panel shouldn't really be separate, but we need
|
||||||
// to clean up the "Load All Files" interaction first.
|
// to clean up the "Load All Files" interaction first.
|
||||||
$change_table = $this->buildTableOfContents(
|
$change_table = $this->buildTableOfContents(
|
||||||
$changesets);
|
$changesets,
|
||||||
|
$change_header,
|
||||||
$change_panel->setTable($change_table);
|
$warning_view);
|
||||||
$change_panel->setHeader($header);
|
|
||||||
|
|
||||||
$content[] = $change_panel;
|
|
||||||
|
|
||||||
$vcs = $repository->getVersionControlSystem();
|
$vcs = $repository->getVersionControlSystem();
|
||||||
switch ($vcs) {
|
switch ($vcs) {
|
||||||
|
@ -296,7 +286,7 @@ final class DiffusionCommitController extends DiffusionController {
|
||||||
} else {
|
} else {
|
||||||
$visible_changesets = array();
|
$visible_changesets = array();
|
||||||
$inlines = PhabricatorAuditInlineComment::loadDraftAndPublishedComments(
|
$inlines = PhabricatorAuditInlineComment::loadDraftAndPublishedComments(
|
||||||
$user,
|
$viewer,
|
||||||
$commit->getPHID());
|
$commit->getPHID());
|
||||||
$path_ids = mpull($inlines, null, 'getPathID');
|
$path_ids = mpull($inlines, null, 'getPathID');
|
||||||
foreach ($changesets as $key => $changeset) {
|
foreach ($changesets as $key => $changeset) {
|
||||||
|
@ -313,10 +303,10 @@ final class DiffusionCommitController extends DiffusionController {
|
||||||
$change_list->setChangesets($changesets);
|
$change_list->setChangesets($changesets);
|
||||||
$change_list->setVisibleChangesets($visible_changesets);
|
$change_list->setVisibleChangesets($visible_changesets);
|
||||||
$change_list->setRenderingReferences($references);
|
$change_list->setRenderingReferences($references);
|
||||||
$change_list->setRenderURI(
|
$change_list->setRenderURI($repository->getPathURI('diff/'));
|
||||||
$repository->getPathURI('diff/'));
|
|
||||||
$change_list->setRepository($repository);
|
$change_list->setRepository($repository);
|
||||||
$change_list->setUser($user);
|
$change_list->setUser($viewer);
|
||||||
|
$change_list->setBackground(PHUIObjectBoxView::BLUE_PROPERTY);
|
||||||
|
|
||||||
// TODO: Try to setBranch() to something reasonable here?
|
// TODO: Try to setBranch() to something reasonable here?
|
||||||
|
|
||||||
|
@ -332,48 +322,74 @@ final class DiffusionCommitController extends DiffusionController {
|
||||||
$change_list->setInlineCommentControllerURI(
|
$change_list->setInlineCommentControllerURI(
|
||||||
'/diffusion/inline/edit/'.phutil_escape_uri($commit->getPHID()).'/');
|
'/diffusion/inline/edit/'.phutil_escape_uri($commit->getPHID()).'/');
|
||||||
|
|
||||||
$content[] = $change_list->render();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$content[] = $this->renderAddCommentPanel($commit, $audit_requests);
|
$add_comment = $this->renderAddCommentPanel($commit, $audit_requests);
|
||||||
|
|
||||||
$prefs = $user->loadPreferences();
|
$prefs = $viewer->loadPreferences();
|
||||||
$pref_filetree = PhabricatorUserPreferences::PREFERENCE_DIFF_FILETREE;
|
$pref_filetree = PhabricatorUserPreferences::PREFERENCE_DIFF_FILETREE;
|
||||||
$pref_collapse = PhabricatorUserPreferences::PREFERENCE_NAV_COLLAPSED;
|
$pref_collapse = PhabricatorUserPreferences::PREFERENCE_NAV_COLLAPSED;
|
||||||
$show_filetree = $prefs->getPreference($pref_filetree);
|
$show_filetree = $prefs->getPreference($pref_filetree);
|
||||||
$collapsed = $prefs->getPreference($pref_collapse);
|
$collapsed = $prefs->getPreference($pref_collapse);
|
||||||
|
|
||||||
|
$nav = null;
|
||||||
if ($show_changesets && $show_filetree) {
|
if ($show_changesets && $show_filetree) {
|
||||||
$nav = id(new DifferentialChangesetFileTreeSideNavBuilder())
|
$nav = id(new DifferentialChangesetFileTreeSideNavBuilder())
|
||||||
->setTitle($commit->getDisplayName())
|
->setTitle($commit->getDisplayName())
|
||||||
->setBaseURI(new PhutilURI($commit->getURI()))
|
->setBaseURI(new PhutilURI($commit->getURI()))
|
||||||
->build($changesets)
|
->build($changesets)
|
||||||
->setCrumbs($crumbs)
|
->setCrumbs($crumbs)
|
||||||
->setCollapsed((bool)$collapsed)
|
->setCollapsed((bool)$collapsed);
|
||||||
->appendChild($content);
|
|
||||||
$content = $nav;
|
|
||||||
} else {
|
|
||||||
$content = array($crumbs, $content);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->buildApplicationPage(
|
$view = id(new PHUITwoColumnView())
|
||||||
$content,
|
->setHeader($header)
|
||||||
|
->setSubheader($subheader)
|
||||||
|
->setMainColumn(array(
|
||||||
|
$error_panel,
|
||||||
|
$timeline,
|
||||||
|
$merge_table,
|
||||||
|
$info_panel,
|
||||||
|
))
|
||||||
|
->setFooter(array(
|
||||||
|
$change_table,
|
||||||
|
$change_list,
|
||||||
|
$add_comment,
|
||||||
|
))
|
||||||
|
->addPropertySection(pht('DESCRIPTION'), $detail_list)
|
||||||
|
->addPropertySection(pht('DETAILS'), $details)
|
||||||
|
->setCurtain($curtain);
|
||||||
|
|
||||||
|
$page = $this->newPage()
|
||||||
|
->setTitle($commit->getDisplayName())
|
||||||
|
->setCrumbs($crumbs)
|
||||||
|
->setPageObjectPHIDS(array($commit->getPHID()))
|
||||||
|
->appendChild(
|
||||||
array(
|
array(
|
||||||
'title' => $commit->getDisplayName(),
|
$view,
|
||||||
'pageObjects' => array($commit->getPHID()),
|
|
||||||
));
|
));
|
||||||
|
|
||||||
|
if ($nav) {
|
||||||
|
$page->setNavigation($nav);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function loadCommitProperties(
|
return $page;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildPropertyListView(
|
||||||
PhabricatorRepositoryCommit $commit,
|
PhabricatorRepositoryCommit $commit,
|
||||||
PhabricatorRepositoryCommitData $data,
|
PhabricatorRepositoryCommitData $data,
|
||||||
array $audit_requests) {
|
array $audit_requests) {
|
||||||
|
|
||||||
$viewer = $this->getRequest()->getUser();
|
$viewer = $this->getViewer();
|
||||||
$commit_phid = $commit->getPHID();
|
$commit_phid = $commit->getPHID();
|
||||||
$drequest = $this->getDiffusionRequest();
|
$drequest = $this->getDiffusionRequest();
|
||||||
$repository = $drequest->getRepository();
|
$repository = $drequest->getRepository();
|
||||||
|
|
||||||
|
$view = id(new PHUIPropertyListView())
|
||||||
|
->setUser($this->getRequest()->getUser());
|
||||||
|
|
||||||
$edge_query = id(new PhabricatorEdgeQuery())
|
$edge_query = id(new PhabricatorEdgeQuery())
|
||||||
->withSourcePHIDs(array($commit_phid))
|
->withSourcePHIDs(array($commit_phid))
|
||||||
->withEdgeTypes(array(
|
->withEdgeTypes(array(
|
||||||
|
@ -437,31 +453,6 @@ final class DiffusionCommitController extends DiffusionController {
|
||||||
|
|
||||||
$props = array();
|
$props = array();
|
||||||
|
|
||||||
if ($commit->getAuditStatus()) {
|
|
||||||
$status = PhabricatorAuditCommitStatusConstants::getStatusName(
|
|
||||||
$commit->getAuditStatus());
|
|
||||||
$tag = id(new PHUITagView())
|
|
||||||
->setType(PHUITagView::TYPE_STATE)
|
|
||||||
->setName($status);
|
|
||||||
|
|
||||||
switch ($commit->getAuditStatus()) {
|
|
||||||
case PhabricatorAuditCommitStatusConstants::NEEDS_AUDIT:
|
|
||||||
$tag->setBackgroundColor(PHUITagView::COLOR_ORANGE);
|
|
||||||
break;
|
|
||||||
case PhabricatorAuditCommitStatusConstants::CONCERN_RAISED:
|
|
||||||
$tag->setBackgroundColor(PHUITagView::COLOR_RED);
|
|
||||||
break;
|
|
||||||
case PhabricatorAuditCommitStatusConstants::PARTIALLY_AUDITED:
|
|
||||||
$tag->setBackgroundColor(PHUITagView::COLOR_BLUE);
|
|
||||||
break;
|
|
||||||
case PhabricatorAuditCommitStatusConstants::FULLY_AUDITED:
|
|
||||||
$tag->setBackgroundColor(PHUITagView::COLOR_GREEN);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$props['Status'] = $tag;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($audit_requests) {
|
if ($audit_requests) {
|
||||||
$user_requests = array();
|
$user_requests = array();
|
||||||
$other_requests = array();
|
$other_requests = array();
|
||||||
|
@ -474,37 +465,21 @@ final class DiffusionCommitController extends DiffusionController {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($user_requests) {
|
if ($user_requests) {
|
||||||
$props['Auditors'] = $this->renderAuditStatusView(
|
$view->addProperty(
|
||||||
$user_requests);
|
pht('Auditors'),
|
||||||
|
$this->renderAuditStatusView($user_requests));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($other_requests) {
|
if ($other_requests) {
|
||||||
$props['Project/Package Auditors'] = $this->renderAuditStatusView(
|
$view->addProperty(
|
||||||
$other_requests);
|
pht('Project/Package Auditors'),
|
||||||
|
$this->renderAuditStatusView($other_requests));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$author_phid = $data->getCommitDetail('authorPHID');
|
$author_phid = $data->getCommitDetail('authorPHID');
|
||||||
$author_name = $data->getAuthorName();
|
$author_name = $data->getAuthorName();
|
||||||
|
|
||||||
if (!$repository->isSVN()) {
|
|
||||||
$authored_info = id(new PHUIStatusItemView());
|
|
||||||
|
|
||||||
$author_epoch = $data->getCommitDetail('authorEpoch');
|
$author_epoch = $data->getCommitDetail('authorEpoch');
|
||||||
if ($author_epoch !== null) {
|
|
||||||
$authored_info->setNote(
|
|
||||||
phabricator_datetime($author_epoch, $viewer));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($author_phid) {
|
|
||||||
$authored_info->setTarget($handles[$author_phid]->renderLink());
|
|
||||||
} else if (strlen($author_name)) {
|
|
||||||
$authored_info->setTarget($author_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
$props['Authored'] = id(new PHUIStatusListView())
|
|
||||||
->addItem($authored_info);
|
|
||||||
}
|
|
||||||
|
|
||||||
$committed_info = id(new PHUIStatusItemView())
|
$committed_info = id(new PHUIStatusItemView())
|
||||||
->setNote(phabricator_datetime($commit->getEpoch(), $viewer));
|
->setNote(phabricator_datetime($commit->getEpoch(), $viewer));
|
||||||
|
@ -521,8 +496,9 @@ final class DiffusionCommitController extends DiffusionController {
|
||||||
$committed_info->setTarget($author_name);
|
$committed_info->setTarget($author_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
$props['Committed'] = id(new PHUIStatusListView())
|
$view->addProperty(
|
||||||
->addItem($committed_info);
|
pht('Committed'),
|
||||||
|
$committed_info);
|
||||||
|
|
||||||
if ($push_logs) {
|
if ($push_logs) {
|
||||||
$pushed_list = new PHUIStatusListView();
|
$pushed_list = new PHUIStatusListView();
|
||||||
|
@ -534,36 +510,49 @@ final class DiffusionCommitController extends DiffusionController {
|
||||||
$pushed_list->addItem($pushed_item);
|
$pushed_list->addItem($pushed_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
$props['Pushed'] = $pushed_list;
|
$view->addProperty(
|
||||||
|
pht('Pushed'),
|
||||||
|
$pushed_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
$reviewer_phid = $data->getCommitDetail('reviewerPHID');
|
$reviewer_phid = $data->getCommitDetail('reviewerPHID');
|
||||||
if ($reviewer_phid) {
|
if ($reviewer_phid) {
|
||||||
$props['Reviewer'] = $handles[$reviewer_phid]->renderLink();
|
$view->addProperty(
|
||||||
|
pht('Reviewer'),
|
||||||
|
$handles[$reviewer_phid]->renderLink());
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($revision_phid) {
|
if ($revision_phid) {
|
||||||
$props['Differential Revision'] = $handles[$revision_phid]->renderLink();
|
$view->addProperty(
|
||||||
|
pht('Differential Revision'),
|
||||||
|
$handles[$revision_phid]->renderLink());
|
||||||
}
|
}
|
||||||
|
|
||||||
$parents = $this->getCommitParents();
|
$parents = $this->getCommitParents();
|
||||||
if ($parents) {
|
if ($parents) {
|
||||||
$props['Parents'] = $viewer->renderHandleList(mpull($parents, 'getPHID'));
|
$view->addProperty(
|
||||||
|
pht('Parents'),
|
||||||
|
$viewer->renderHandleList(mpull($parents, 'getPHID')));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->getCommitExists()) {
|
if ($this->getCommitExists()) {
|
||||||
$props['Branches'] = phutil_tag(
|
$view->addProperty(
|
||||||
|
pht('Branches'),
|
||||||
|
phutil_tag(
|
||||||
'span',
|
'span',
|
||||||
array(
|
array(
|
||||||
'id' => 'commit-branches',
|
'id' => 'commit-branches',
|
||||||
),
|
),
|
||||||
pht('Unknown'));
|
pht('Unknown')));
|
||||||
$props['Tags'] = phutil_tag(
|
|
||||||
|
$view->addProperty(
|
||||||
|
pht('Tags'),
|
||||||
|
phutil_tag(
|
||||||
'span',
|
'span',
|
||||||
array(
|
array(
|
||||||
'id' => 'commit-tags',
|
'id' => 'commit-tags',
|
||||||
),
|
),
|
||||||
pht('Unknown'));
|
pht('Unknown')));
|
||||||
|
|
||||||
$identifier = $commit->getCommitIdentifier();
|
$identifier = $commit->getCommitIdentifier();
|
||||||
$root = $repository->getPathURI("commit/{$identifier}");
|
$root = $repository->getPathURI("commit/{$identifier}");
|
||||||
|
@ -586,16 +575,21 @@ final class DiffusionCommitController extends DiffusionController {
|
||||||
),
|
),
|
||||||
$ref_data['ref']);
|
$ref_data['ref']);
|
||||||
}
|
}
|
||||||
$props['References'] = phutil_implode_html(', ', $ref_links);
|
$view->addProperty(
|
||||||
|
pht('References'),
|
||||||
|
phutil_implode_html(', ', $ref_links));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($reverts_phids) {
|
if ($reverts_phids) {
|
||||||
$props[pht('Reverts')] = $viewer->renderHandleList($reverts_phids);
|
$view->addProperty(
|
||||||
|
pht('Reverts'),
|
||||||
|
$viewer->renderHandleList($reverts_phids));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($reverted_by_phids) {
|
if ($reverted_by_phids) {
|
||||||
$props[pht('Reverted By')] = $viewer->renderHandleList(
|
$view->addProperty(
|
||||||
$reverted_by_phids);
|
pht('Reverted By'),
|
||||||
|
$viewer->renderHandleList($reverted_by_phids));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($task_phids) {
|
if ($task_phids) {
|
||||||
|
@ -604,12 +598,62 @@ final class DiffusionCommitController extends DiffusionController {
|
||||||
$task_list[] = $handles[$phid]->renderLink();
|
$task_list[] = $handles[$phid]->renderLink();
|
||||||
}
|
}
|
||||||
$task_list = phutil_implode_html(phutil_tag('br'), $task_list);
|
$task_list = phutil_implode_html(phutil_tag('br'), $task_list);
|
||||||
$props['Tasks'] = $task_list;
|
$view->addProperty(
|
||||||
|
pht('Tasks'),
|
||||||
|
$task_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $props;
|
return $view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function buildSubheaderView(
|
||||||
|
PhabricatorRepositoryCommit $commit,
|
||||||
|
PhabricatorRepositoryCommitData $data) {
|
||||||
|
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
$drequest = $this->getDiffusionRequest();
|
||||||
|
$repository = $drequest->getRepository();
|
||||||
|
|
||||||
|
if ($repository->isSVN()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$author_phid = $data->getCommitDetail('authorPHID');
|
||||||
|
$author_name = $data->getAuthorName();
|
||||||
|
$author_epoch = $data->getCommitDetail('authorEpoch');
|
||||||
|
$date = null;
|
||||||
|
if ($author_epoch !== null) {
|
||||||
|
$date = phabricator_datetime($author_epoch, $viewer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($author_phid) {
|
||||||
|
$handles = $viewer->loadHandles(array($author_phid));
|
||||||
|
$image_uri = $handles[$author_phid]->getImageURI();
|
||||||
|
$image_href = $handles[$author_phid]->getURI();
|
||||||
|
$author = $handles[$author_phid]->renderLink();
|
||||||
|
} else if (strlen($author_name)) {
|
||||||
|
$author = $author_name;
|
||||||
|
$image_uri = null;
|
||||||
|
$image_href = null;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$author = phutil_tag('strong', array(), $author);
|
||||||
|
if ($date) {
|
||||||
|
$content = pht('Authored by %s on %s.', $author, $date);
|
||||||
|
} else {
|
||||||
|
$content = pht('Authored by %s.', $author);
|
||||||
|
}
|
||||||
|
|
||||||
|
return id(new PHUIHeadThingView())
|
||||||
|
->setImage($image_uri)
|
||||||
|
->setImageHref($image_href)
|
||||||
|
->setContent($content);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private function buildComments(PhabricatorRepositoryCommit $commit) {
|
private function buildComments(PhabricatorRepositoryCommit $commit) {
|
||||||
$timeline = $this->buildTransactionTimeline(
|
$timeline = $this->buildTransactionTimeline(
|
||||||
$commit,
|
$commit,
|
||||||
|
@ -624,11 +668,11 @@ final class DiffusionCommitController extends DiffusionController {
|
||||||
assert_instances_of($audit_requests, 'PhabricatorRepositoryAuditRequest');
|
assert_instances_of($audit_requests, 'PhabricatorRepositoryAuditRequest');
|
||||||
|
|
||||||
$request = $this->getRequest();
|
$request = $this->getRequest();
|
||||||
$user = $request->getUser();
|
$viewer = $request->getUser();
|
||||||
|
|
||||||
if (!$user->isLoggedIn()) {
|
if (!$viewer->isLoggedIn()) {
|
||||||
return id(new PhabricatorApplicationTransactionCommentView())
|
return id(new PhabricatorApplicationTransactionCommentView())
|
||||||
->setUser($user)
|
->setUser($viewer)
|
||||||
->setRequestURI($request->getRequestURI());
|
->setRequestURI($request->getRequestURI());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -643,7 +687,7 @@ final class DiffusionCommitController extends DiffusionController {
|
||||||
|
|
||||||
$draft = id(new PhabricatorDraft())->loadOneWhere(
|
$draft = id(new PhabricatorDraft())->loadOneWhere(
|
||||||
'authorPHID = %s AND draftKey = %s',
|
'authorPHID = %s AND draftKey = %s',
|
||||||
$user->getPHID(),
|
$viewer->getPHID(),
|
||||||
'diffusion-audit-'.$commit->getID());
|
'diffusion-audit-'.$commit->getID());
|
||||||
if ($draft) {
|
if ($draft) {
|
||||||
$draft = $draft->getDraft();
|
$draft = $draft->getDraft();
|
||||||
|
@ -657,7 +701,7 @@ final class DiffusionCommitController extends DiffusionController {
|
||||||
$auditor_source = new DiffusionAuditorDatasource();
|
$auditor_source = new DiffusionAuditorDatasource();
|
||||||
|
|
||||||
$form = id(new AphrontFormView())
|
$form = id(new AphrontFormView())
|
||||||
->setUser($user)
|
->setUser($viewer)
|
||||||
->setAction('/audit/addcomment/')
|
->setAction('/audit/addcomment/')
|
||||||
->addHiddenInput('commit', $commit->getPHID())
|
->addHiddenInput('commit', $commit->getPHID())
|
||||||
->appendChild(
|
->appendChild(
|
||||||
|
@ -690,7 +734,7 @@ final class DiffusionCommitController extends DiffusionController {
|
||||||
->setName('content')
|
->setName('content')
|
||||||
->setValue($draft)
|
->setValue($draft)
|
||||||
->setID('audit-content')
|
->setID('audit-content')
|
||||||
->setUser($user))
|
->setUser($viewer))
|
||||||
->appendChild(
|
->appendChild(
|
||||||
id(new AphrontFormSubmitControl())
|
id(new AphrontFormSubmitControl())
|
||||||
->setValue(pht('Submit')));
|
->setValue(pht('Submit')));
|
||||||
|
@ -776,13 +820,13 @@ final class DiffusionCommitController extends DiffusionController {
|
||||||
PhabricatorRepositoryCommit $commit,
|
PhabricatorRepositoryCommit $commit,
|
||||||
array $audit_requests) {
|
array $audit_requests) {
|
||||||
assert_instances_of($audit_requests, 'PhabricatorRepositoryAuditRequest');
|
assert_instances_of($audit_requests, 'PhabricatorRepositoryAuditRequest');
|
||||||
$user = $this->getRequest()->getUser();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$user_is_author = ($commit->getAuthorPHID() == $user->getPHID());
|
$user_is_author = ($commit->getAuthorPHID() == $viewer->getPHID());
|
||||||
|
|
||||||
$user_request = null;
|
$user_request = null;
|
||||||
foreach ($audit_requests as $audit_request) {
|
foreach ($audit_requests as $audit_request) {
|
||||||
if ($audit_request->getAuditorPHID() == $user->getPHID()) {
|
if ($audit_request->getAuditorPHID() == $viewer->getPHID()) {
|
||||||
$user_request = $audit_request;
|
$user_request = $audit_request;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -876,9 +920,10 @@ final class DiffusionCommitController extends DiffusionController {
|
||||||
|
|
||||||
$history_table->loadRevisions();
|
$history_table->loadRevisions();
|
||||||
|
|
||||||
$panel = new PHUIObjectBoxView();
|
$panel = id(new PHUIObjectBoxView())
|
||||||
$panel->setHeaderText(pht('Merged Changes'));
|
->setHeaderText(pht('Merged Changes'))
|
||||||
$panel->setTable($history_table);
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
|
->setTable($history_table);
|
||||||
if ($caption) {
|
if ($caption) {
|
||||||
$panel->setInfoView($caption);
|
$panel->setInfoView($caption);
|
||||||
}
|
}
|
||||||
|
@ -886,19 +931,16 @@ final class DiffusionCommitController extends DiffusionController {
|
||||||
return $panel;
|
return $panel;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function renderHeadsupActionList(
|
private function buildCurtain(
|
||||||
PhabricatorRepositoryCommit $commit,
|
PhabricatorRepositoryCommit $commit,
|
||||||
PhabricatorRepository $repository) {
|
PhabricatorRepository $repository) {
|
||||||
|
|
||||||
$request = $this->getRequest();
|
$request = $this->getRequest();
|
||||||
$user = $request->getUser();
|
$viewer = $this->getViewer();
|
||||||
|
$curtain = $this->newCurtainView($commit);
|
||||||
$actions = id(new PhabricatorActionListView())
|
|
||||||
->setUser($user)
|
|
||||||
->setObject($commit);
|
|
||||||
|
|
||||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||||
$user,
|
$viewer,
|
||||||
$commit,
|
$commit,
|
||||||
PhabricatorPolicyCapability::CAN_EDIT);
|
PhabricatorPolicyCapability::CAN_EDIT);
|
||||||
|
|
||||||
|
@ -911,7 +953,7 @@ final class DiffusionCommitController extends DiffusionController {
|
||||||
->setIcon('fa-pencil')
|
->setIcon('fa-pencil')
|
||||||
->setDisabled(!$can_edit)
|
->setDisabled(!$can_edit)
|
||||||
->setWorkflow(!$can_edit);
|
->setWorkflow(!$can_edit);
|
||||||
$actions->addAction($action);
|
$curtain->addAction($action);
|
||||||
|
|
||||||
require_celerity_resource('phabricator-object-selector-css');
|
require_celerity_resource('phabricator-object-selector-css');
|
||||||
require_celerity_resource('javelin-behavior-phabricator-object-selector');
|
require_celerity_resource('javelin-behavior-phabricator-object-selector');
|
||||||
|
@ -924,16 +966,16 @@ final class DiffusionCommitController extends DiffusionController {
|
||||||
->setHref('/search/attach/'.$commit->getPHID().'/TASK/edge/')
|
->setHref('/search/attach/'.$commit->getPHID().'/TASK/edge/')
|
||||||
->setWorkflow(true)
|
->setWorkflow(true)
|
||||||
->setDisabled(!$can_edit);
|
->setDisabled(!$can_edit);
|
||||||
$actions->addAction($action);
|
$curtain->addAction($action);
|
||||||
}
|
}
|
||||||
|
|
||||||
$action = id(new PhabricatorActionView())
|
$action = id(new PhabricatorActionView())
|
||||||
->setName(pht('Download Raw Diff'))
|
->setName(pht('Download Raw Diff'))
|
||||||
->setHref($request->getRequestURI()->alter('diff', true))
|
->setHref($request->getRequestURI()->alter('diff', true))
|
||||||
->setIcon('fa-download');
|
->setIcon('fa-download');
|
||||||
$actions->addAction($action);
|
$curtain->addAction($action);
|
||||||
|
|
||||||
return $actions;
|
return $curtain;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildRawDiffResponse(DiffusionRequest $drequest) {
|
private function buildRawDiffResponse(DiffusionRequest $drequest) {
|
||||||
|
@ -1017,12 +1059,22 @@ final class DiffusionCommitController extends DiffusionController {
|
||||||
return $parser->processCorpus($corpus);
|
return $parser->processCorpus($corpus);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildTableOfContents(array $changesets) {
|
private function buildTableOfContents(
|
||||||
|
array $changesets,
|
||||||
|
$header,
|
||||||
|
$info_view) {
|
||||||
|
|
||||||
$drequest = $this->getDiffusionRequest();
|
$drequest = $this->getDiffusionRequest();
|
||||||
$viewer = $this->getViewer();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$toc_view = id(new PHUIDiffTableOfContentsListView())
|
$toc_view = id(new PHUIDiffTableOfContentsListView())
|
||||||
->setUser($viewer);
|
->setUser($viewer)
|
||||||
|
->setHeader($header)
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY);
|
||||||
|
|
||||||
|
if ($info_view) {
|
||||||
|
$toc_view->setInfoView($info_view);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: This is hacky, we just want access to the linkX() methods on
|
// TODO: This is hacky, we just want access to the linkX() methods on
|
||||||
// DiffusionView.
|
// DiffusionView.
|
||||||
|
|
|
@ -291,6 +291,7 @@ abstract class DiffusionController extends PhabricatorController {
|
||||||
return id(new PHUIInfoView())
|
return id(new PHUIInfoView())
|
||||||
->setSeverity(PHUIInfoView::SEVERITY_WARNING)
|
->setSeverity(PHUIInfoView::SEVERITY_WARNING)
|
||||||
->setTitle($title)
|
->setTitle($title)
|
||||||
|
->setFlush(true)
|
||||||
->appendChild($body);
|
->appendChild($body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,6 +301,27 @@ abstract class DiffusionController extends PhabricatorController {
|
||||||
->appendChild($pager);
|
->appendChild($pager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function renderCommitHashTag(DiffusionRequest $drequest) {
|
||||||
|
$stable_commit = $drequest->getStableCommit();
|
||||||
|
$commit = phutil_tag(
|
||||||
|
'a',
|
||||||
|
array(
|
||||||
|
'href' => $drequest->generateURI(
|
||||||
|
array(
|
||||||
|
'action' => 'commit',
|
||||||
|
'commit' => $stable_commit,
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
$drequest->getRepository()->formatCommitName($stable_commit, true));
|
||||||
|
|
||||||
|
$tag = id(new PHUITagView())
|
||||||
|
->setName($commit)
|
||||||
|
->setShade('indigo')
|
||||||
|
->setType(PHUITagView::TYPE_SHADE);
|
||||||
|
|
||||||
|
return $tag;
|
||||||
|
}
|
||||||
|
|
||||||
protected function renderDirectoryReadme(DiffusionBrowseResultSet $browse) {
|
protected function renderDirectoryReadme(DiffusionBrowseResultSet $browse) {
|
||||||
$readme_path = $browse->getReadmePath();
|
$readme_path = $browse->getReadmePath();
|
||||||
if ($readme_path === null) {
|
if ($readme_path === null) {
|
||||||
|
|
|
@ -40,8 +40,6 @@ final class DiffusionHistoryController extends DiffusionController {
|
||||||
$history = $pager->sliceResults($history);
|
$history = $pager->sliceResults($history);
|
||||||
|
|
||||||
$show_graph = !strlen($drequest->getPath());
|
$show_graph = !strlen($drequest->getPath());
|
||||||
$content = array();
|
|
||||||
|
|
||||||
$history_table = id(new DiffusionHistoryTableView())
|
$history_table = id(new DiffusionHistoryTableView())
|
||||||
->setUser($request->getUser())
|
->setUser($request->getUser())
|
||||||
->setDiffusionRequest($drequest)
|
->setDiffusionRequest($drequest)
|
||||||
|
@ -55,23 +53,13 @@ final class DiffusionHistoryController extends DiffusionController {
|
||||||
$history_table->setIsTail(!$pager->getHasMorePages());
|
$history_table->setIsTail(!$pager->getHasMorePages());
|
||||||
}
|
}
|
||||||
|
|
||||||
$history_panel = new PHUIObjectBoxView();
|
$history_header = $this->buildHistoryHeader($drequest);
|
||||||
$history_panel->setHeaderText(pht('History'));
|
$history_panel = id(new PHUIObjectBoxView())
|
||||||
$history_panel->setTable($history_table);
|
->setHeader($history_header)
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
|
->setTable($history_table);
|
||||||
|
|
||||||
$content[] = $history_panel;
|
$header = $this->buildHeader($drequest, $repository);
|
||||||
|
|
||||||
$header = id(new PHUIHeaderView())
|
|
||||||
->setUser($viewer)
|
|
||||||
->setPolicyObject($repository)
|
|
||||||
->setHeader($this->renderPathLinks($drequest, $mode = 'history'));
|
|
||||||
|
|
||||||
$actions = $this->buildActionView($drequest);
|
|
||||||
$properties = $this->buildPropertyView($drequest, $actions);
|
|
||||||
|
|
||||||
$object_box = id(new PHUIObjectBoxView())
|
|
||||||
->setHeader($header)
|
|
||||||
->addPropertyList($properties);
|
|
||||||
|
|
||||||
$crumbs = $this->buildCrumbs(
|
$crumbs = $this->buildCrumbs(
|
||||||
array(
|
array(
|
||||||
|
@ -79,9 +67,17 @@ final class DiffusionHistoryController extends DiffusionController {
|
||||||
'path' => true,
|
'path' => true,
|
||||||
'view' => 'history',
|
'view' => 'history',
|
||||||
));
|
));
|
||||||
|
$crumbs->setBorder(true);
|
||||||
|
|
||||||
$pager_box = $this->renderTablePagerBox($pager);
|
$pager_box = $this->renderTablePagerBox($pager);
|
||||||
|
|
||||||
|
$view = id(new PHUITwoColumnView())
|
||||||
|
->setHeader($header)
|
||||||
|
->setFooter(array(
|
||||||
|
$history_panel,
|
||||||
|
$pager_box,
|
||||||
|
));
|
||||||
|
|
||||||
return $this->newPage()
|
return $this->newPage()
|
||||||
->setTitle(
|
->setTitle(
|
||||||
array(
|
array(
|
||||||
|
@ -91,28 +87,39 @@ final class DiffusionHistoryController extends DiffusionController {
|
||||||
->setCrumbs($crumbs)
|
->setCrumbs($crumbs)
|
||||||
->appendChild(
|
->appendChild(
|
||||||
array(
|
array(
|
||||||
$object_box,
|
$view,
|
||||||
$content,
|
|
||||||
$pager_box,
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildActionView(DiffusionRequest $drequest) {
|
private function buildHeader(DiffusionRequest $drequest) {
|
||||||
$viewer = $this->getRequest()->getUser();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$view = id(new PhabricatorActionListView())
|
$tag = $this->renderCommitHashTag($drequest);
|
||||||
->setUser($viewer);
|
|
||||||
|
$header = id(new PHUIHeaderView())
|
||||||
|
->setUser($viewer)
|
||||||
|
->setPolicyObject($drequest->getRepository())
|
||||||
|
->addTag($tag)
|
||||||
|
->setHeader($this->renderPathLinks($drequest, $mode = 'history'))
|
||||||
|
->setHeaderIcon('fa-clock-o');
|
||||||
|
|
||||||
|
return $header;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildHistoryHeader(DiffusionRequest $drequest) {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$browse_uri = $drequest->generateURI(
|
$browse_uri = $drequest->generateURI(
|
||||||
array(
|
array(
|
||||||
'action' => 'browse',
|
'action' => 'browse',
|
||||||
));
|
));
|
||||||
|
|
||||||
$view->addAction(
|
$browse_button = id(new PHUIButtonView())
|
||||||
id(new PhabricatorActionView())
|
->setTag('a')
|
||||||
->setName(pht('Browse Content'))
|
->setText(pht('Browse'))
|
||||||
->setHref($browse_uri)
|
->setHref($browse_uri)
|
||||||
->setIcon('fa-files-o'));
|
->setIcon('fa-files-o');
|
||||||
|
|
||||||
// TODO: Sometimes we do have a change view, we need to look at the most
|
// TODO: Sometimes we do have a change view, we need to look at the most
|
||||||
// recent history entry to figure it out.
|
// recent history entry to figure it out.
|
||||||
|
@ -130,41 +137,18 @@ final class DiffusionHistoryController extends DiffusionController {
|
||||||
->alter('copies', true);
|
->alter('copies', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
$view->addAction(
|
$branch_button = id(new PHUIButtonView())
|
||||||
id(new PhabricatorActionView())
|
->setTag('a')
|
||||||
->setName($branch_name)
|
->setText($branch_name)
|
||||||
->setIcon('fa-code-fork')
|
->setIcon('fa-code-fork')
|
||||||
->setHref($branch_uri));
|
->setHref($branch_uri);
|
||||||
|
|
||||||
return $view;
|
$header = id(new PHUIHeaderView())
|
||||||
}
|
->setHeader(pht('History'))
|
||||||
|
->addActionLink($browse_button)
|
||||||
|
->addActionLink($branch_button);
|
||||||
|
|
||||||
protected function buildPropertyView(
|
return $header;
|
||||||
DiffusionRequest $drequest,
|
|
||||||
PhabricatorActionListView $actions) {
|
|
||||||
|
|
||||||
$viewer = $this->getRequest()->getUser();
|
|
||||||
|
|
||||||
$view = id(new PHUIPropertyListView())
|
|
||||||
->setUser($viewer)
|
|
||||||
->setActionList($actions);
|
|
||||||
|
|
||||||
$stable_commit = $drequest->getStableCommit();
|
|
||||||
|
|
||||||
$view->addProperty(
|
|
||||||
pht('Commit'),
|
|
||||||
phutil_tag(
|
|
||||||
'a',
|
|
||||||
array(
|
|
||||||
'href' => $drequest->generateURI(
|
|
||||||
array(
|
|
||||||
'action' => 'commit',
|
|
||||||
'commit' => $stable_commit,
|
|
||||||
)),
|
|
||||||
),
|
|
||||||
$drequest->getRepository()->formatCommitName($stable_commit)));
|
|
||||||
|
|
||||||
return $view;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,7 +103,7 @@ final class DiffusionLastModifiedController extends DiffusionController {
|
||||||
$modified = DiffusionView::linkCommit(
|
$modified = DiffusionView::linkCommit(
|
||||||
$drequest->getRepository(),
|
$drequest->getRepository(),
|
||||||
$commit->getCommitIdentifier());
|
$commit->getCommitIdentifier());
|
||||||
$date = phabricator_datetime($epoch, $viewer);
|
$date = $viewer->formatShortDateTime($epoch);
|
||||||
} else {
|
} else {
|
||||||
$modified = '';
|
$modified = '';
|
||||||
$date = '';
|
$date = '';
|
||||||
|
|
|
@ -157,6 +157,7 @@ final class DiffusionLintController extends DiffusionController {
|
||||||
|
|
||||||
$content[] = id(new PHUIObjectBoxView())
|
$content[] = id(new PHUIObjectBoxView())
|
||||||
->setHeaderText(pht('Lint'))
|
->setHeaderText(pht('Lint'))
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->setTable($table);
|
->setTable($table);
|
||||||
|
|
||||||
$title = array('Lint');
|
$title = array('Lint');
|
||||||
|
@ -179,7 +180,7 @@ final class DiffusionLintController extends DiffusionController {
|
||||||
$header = id(new PHUIHeaderView())
|
$header = id(new PHUIHeaderView())
|
||||||
->setHeader($this->renderPathLinks($drequest, 'lint'))
|
->setHeader($this->renderPathLinks($drequest, 'lint'))
|
||||||
->setUser($viewer)
|
->setUser($viewer)
|
||||||
->setPolicyObject($drequest->getRepository());
|
->setHeaderIcon('fa-code');
|
||||||
$actions = $this->buildActionView($drequest);
|
$actions = $this->buildActionView($drequest);
|
||||||
$properties = $this->buildPropertyView(
|
$properties = $this->buildPropertyView(
|
||||||
$drequest,
|
$drequest,
|
||||||
|
@ -189,18 +190,28 @@ final class DiffusionLintController extends DiffusionController {
|
||||||
|
|
||||||
$object_box = id(new PHUIObjectBoxView())
|
$object_box = id(new PHUIObjectBoxView())
|
||||||
->setHeader($header)
|
->setHeader($header)
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->addPropertyList($properties);
|
->addPropertyList($properties);
|
||||||
} else {
|
} else {
|
||||||
$object_box = null;
|
$object_box = null;
|
||||||
|
$header = id(new PHUIHeaderView())
|
||||||
|
->setHeader(pht('All Lint'))
|
||||||
|
->setHeaderIcon('fa-code');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$view = id(new PHUITwoColumnView())
|
||||||
|
->setHeader($header)
|
||||||
|
->setFooter(array(
|
||||||
|
$object_box,
|
||||||
|
$content,
|
||||||
|
));
|
||||||
|
|
||||||
return $this->newPage()
|
return $this->newPage()
|
||||||
->setTitle($title)
|
->setTitle($title)
|
||||||
->setCrumbs($crumbs)
|
->setCrumbs($crumbs)
|
||||||
->appendChild(
|
->appendChild(
|
||||||
array(
|
array(
|
||||||
$object_box,
|
$view,
|
||||||
$content,
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,6 +455,7 @@ final class DiffusionLintController extends DiffusionController {
|
||||||
|
|
||||||
$content[] = id(new PHUIObjectBoxView())
|
$content[] = id(new PHUIObjectBoxView())
|
||||||
->setHeaderText(pht('Lint Details'))
|
->setHeaderText(pht('Lint Details'))
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->setTable($table);
|
->setTable($table);
|
||||||
|
|
||||||
$crumbs = $this->buildCrumbs(
|
$crumbs = $this->buildCrumbs(
|
||||||
|
@ -454,6 +466,16 @@ final class DiffusionLintController extends DiffusionController {
|
||||||
));
|
));
|
||||||
|
|
||||||
$pager_box = $this->renderTablePagerBox($pager);
|
$pager_box = $this->renderTablePagerBox($pager);
|
||||||
|
$header = id(new PHUIHeaderView())
|
||||||
|
->setHeader(pht('Lint: %s', $drequest->getRepository()->getDisplayName()))
|
||||||
|
->setHeaderIcon('fa-code');
|
||||||
|
|
||||||
|
$view = id(new PHUITwoColumnView())
|
||||||
|
->setHeader($header)
|
||||||
|
->setFooter(array(
|
||||||
|
$content,
|
||||||
|
$pager_box,
|
||||||
|
));
|
||||||
|
|
||||||
return $this->newPage()
|
return $this->newPage()
|
||||||
->setTitle(
|
->setTitle(
|
||||||
|
@ -464,8 +486,7 @@ final class DiffusionLintController extends DiffusionController {
|
||||||
->setCrumbs($crumbs)
|
->setCrumbs($crumbs)
|
||||||
->appendChild(
|
->appendChild(
|
||||||
array(
|
array(
|
||||||
$content,
|
$view,
|
||||||
$pager_box,
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,11 +16,14 @@ final class DiffusionRepositoryController extends DiffusionController {
|
||||||
$drequest = $this->getDiffusionRequest();
|
$drequest = $this->getDiffusionRequest();
|
||||||
$repository = $drequest->getRepository();
|
$repository = $drequest->getRepository();
|
||||||
|
|
||||||
$content = array();
|
|
||||||
|
|
||||||
$crumbs = $this->buildCrumbs();
|
$crumbs = $this->buildCrumbs();
|
||||||
|
$crumbs->setBorder(true);
|
||||||
|
|
||||||
$content[] = $this->buildPropertiesTable($drequest->getRepository());
|
$header = $this->buildHeaderView($repository);
|
||||||
|
$curtain = $this->buildCurtain($repository);
|
||||||
|
$property_table = $this->buildPropertiesTable($repository);
|
||||||
|
$description = $this->buildDescriptionView($repository);
|
||||||
|
$locate_file = $this->buildLocateFile();
|
||||||
|
|
||||||
// Before we do any work, make sure we're looking at a some content: we're
|
// Before we do any work, make sure we're looking at a some content: we're
|
||||||
// on a valid branch, and the repository is not empty.
|
// on a valid branch, and the repository is not empty.
|
||||||
|
@ -68,14 +71,24 @@ final class DiffusionRepositoryController extends DiffusionController {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($page_has_content) {
|
if ($page_has_content) {
|
||||||
$content[] = $this->buildNormalContent($drequest);
|
$content = $this->buildNormalContent($drequest);
|
||||||
} else {
|
} else {
|
||||||
$content[] = id(new PHUIInfoView())
|
$content = id(new PHUIInfoView())
|
||||||
->setTitle($empty_title)
|
->setTitle($empty_title)
|
||||||
->setSeverity(PHUIInfoView::SEVERITY_WARNING)
|
->setSeverity(PHUIInfoView::SEVERITY_WARNING)
|
||||||
->setErrors(array($empty_message));
|
->setErrors(array($empty_message));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$view = id(new PHUITwoColumnView())
|
||||||
|
->setHeader($header)
|
||||||
|
->setCurtain($curtain)
|
||||||
|
->setMainColumn(array(
|
||||||
|
$property_table,
|
||||||
|
$description,
|
||||||
|
$locate_file,
|
||||||
|
))
|
||||||
|
->setFooter($content);
|
||||||
|
|
||||||
return $this->newPage()
|
return $this->newPage()
|
||||||
->setTitle(
|
->setTitle(
|
||||||
array(
|
array(
|
||||||
|
@ -83,7 +96,9 @@ final class DiffusionRepositoryController extends DiffusionController {
|
||||||
$repository->getDisplayName(),
|
$repository->getDisplayName(),
|
||||||
))
|
))
|
||||||
->setCrumbs($crumbs)
|
->setCrumbs($crumbs)
|
||||||
->appendChild($content);
|
->appendChild(array(
|
||||||
|
$view,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -206,13 +221,13 @@ final class DiffusionRepositoryController extends DiffusionController {
|
||||||
return $content;
|
return $content;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildPropertiesTable(PhabricatorRepository $repository) {
|
private function buildHeaderView(PhabricatorRepository $repository) {
|
||||||
$user = $this->getRequest()->getUser();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$header = id(new PHUIHeaderView())
|
$header = id(new PHUIHeaderView())
|
||||||
->setHeader($repository->getName())
|
->setHeader($repository->getName())
|
||||||
->setUser($user)
|
->setUser($viewer)
|
||||||
->setPolicyObject($repository);
|
->setPolicyObject($repository)
|
||||||
|
->setHeaderIcon('fa-code');
|
||||||
|
|
||||||
if (!$repository->isTracked()) {
|
if (!$repository->isTracked()) {
|
||||||
$header->setStatus('fa-ban', 'dark', pht('Inactive'));
|
$header->setStatus('fa-ban', 'dark', pht('Inactive'));
|
||||||
|
@ -227,12 +242,64 @@ final class DiffusionRepositoryController extends DiffusionController {
|
||||||
$header->setStatus('fa-check', 'bluegrey', pht('Active'));
|
$header->setStatus('fa-check', 'bluegrey', pht('Active'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $header;
|
||||||
|
}
|
||||||
|
|
||||||
$actions = $this->buildActionList($repository);
|
private function buildCurtain(PhabricatorRepository $repository) {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
|
$edit_uri = $repository->getPathURI('edit/');
|
||||||
|
$curtain = $this->newCurtainView($repository);
|
||||||
|
|
||||||
|
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||||
|
$viewer,
|
||||||
|
$repository,
|
||||||
|
PhabricatorPolicyCapability::CAN_EDIT);
|
||||||
|
|
||||||
|
$curtain->addAction(
|
||||||
|
id(new PhabricatorActionView())
|
||||||
|
->setName(pht('Edit Repository'))
|
||||||
|
->setIcon('fa-pencil')
|
||||||
|
->setHref($edit_uri)
|
||||||
|
->setWorkflow(!$can_edit)
|
||||||
|
->setDisabled(!$can_edit));
|
||||||
|
|
||||||
|
if ($repository->isHosted()) {
|
||||||
|
$push_uri = $this->getApplicationURI(
|
||||||
|
'pushlog/?repositories='.$repository->getMonogram());
|
||||||
|
|
||||||
|
$curtain->addAction(
|
||||||
|
id(new PhabricatorActionView())
|
||||||
|
->setName(pht('View Push Logs'))
|
||||||
|
->setIcon('fa-list-alt')
|
||||||
|
->setHref($push_uri));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $curtain;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildDescriptionView(PhabricatorRepository $repository) {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
$view = id(new PHUIPropertyListView())
|
||||||
|
->setUser($viewer);
|
||||||
|
|
||||||
|
$description = $repository->getDetail('description');
|
||||||
|
if (strlen($description)) {
|
||||||
|
$description = new PHUIRemarkupView($viewer, $description);
|
||||||
|
$view->addTextContent($description);
|
||||||
|
return id(new PHUIObjectBoxView())
|
||||||
|
->setHeaderText(pht('DESCRIPTION'))
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
|
->appendChild($view);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildPropertiesTable(PhabricatorRepository $repository) {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$view = id(new PHUIPropertyListView())
|
$view = id(new PHUIPropertyListView())
|
||||||
->setObject($repository)
|
->setUser($viewer);
|
||||||
->setUser($user);
|
|
||||||
|
|
||||||
if ($repository->isHosted()) {
|
if ($repository->isHosted()) {
|
||||||
$ssh_uri = $repository->getSSHCloneURIObject();
|
$ssh_uri = $repository->getSSHCloneURIObject();
|
||||||
|
@ -286,21 +353,10 @@ final class DiffusionRepositoryController extends DiffusionController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$view->invokeWillRenderEvent();
|
|
||||||
|
|
||||||
$description = $repository->getDetail('description');
|
|
||||||
if (strlen($description)) {
|
|
||||||
$description = new PHUIRemarkupView($user, $description);
|
|
||||||
$view->addSectionHeader(
|
|
||||||
pht('Description'), PHUIPropertyListView::ICON_SUMMARY);
|
|
||||||
$view->addTextContent($description);
|
|
||||||
}
|
|
||||||
|
|
||||||
$view->setActionList($actions);
|
|
||||||
|
|
||||||
$box = id(new PHUIObjectBoxView())
|
$box = id(new PHUIObjectBoxView())
|
||||||
->setHeader($header)
|
->setHeaderText(pht('DETAILS'))
|
||||||
->addPropertyList($view);
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
|
->appendChild($view);
|
||||||
|
|
||||||
$info = null;
|
$info = null;
|
||||||
$drequest = $this->getDiffusionRequest();
|
$drequest = $this->getDiffusionRequest();
|
||||||
|
@ -344,7 +400,7 @@ final class DiffusionRepositoryController extends DiffusionController {
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildBranchListTable(DiffusionRequest $drequest) {
|
private function buildBranchListTable(DiffusionRequest $drequest) {
|
||||||
$viewer = $this->getRequest()->getUser();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
if ($drequest->getBranch() === null) {
|
if ($drequest->getBranch() === null) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -379,7 +435,8 @@ final class DiffusionRepositoryController extends DiffusionController {
|
||||||
->setBranches($branches)
|
->setBranches($branches)
|
||||||
->setCommits($commits);
|
->setCommits($commits);
|
||||||
|
|
||||||
$panel = new PHUIObjectBoxView();
|
$panel = id(new PHUIObjectBoxView())
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY);
|
||||||
$header = new PHUIHeaderView();
|
$header = new PHUIHeaderView();
|
||||||
$header->setHeader(pht('Branches'));
|
$header->setHeader(pht('Branches'));
|
||||||
|
|
||||||
|
@ -388,7 +445,7 @@ final class DiffusionRepositoryController extends DiffusionController {
|
||||||
}
|
}
|
||||||
|
|
||||||
$button = new PHUIButtonView();
|
$button = new PHUIButtonView();
|
||||||
$button->setText(pht('Show All Branches'));
|
$button->setText(pht('Show All'));
|
||||||
$button->setTag('a');
|
$button->setTag('a');
|
||||||
$button->setIcon('fa-code-fork');
|
$button->setIcon('fa-code-fork');
|
||||||
$button->setHref($drequest->generateURI(
|
$button->setHref($drequest->generateURI(
|
||||||
|
@ -404,7 +461,7 @@ final class DiffusionRepositoryController extends DiffusionController {
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildTagListTable(DiffusionRequest $drequest) {
|
private function buildTagListTable(DiffusionRequest $drequest) {
|
||||||
$viewer = $this->getRequest()->getUser();
|
$viewer = $this->getViewer();
|
||||||
$repository = $drequest->getRepository();
|
$repository = $drequest->getRepository();
|
||||||
|
|
||||||
switch ($repository->getVersionControlSystem()) {
|
switch ($repository->getVersionControlSystem()) {
|
||||||
|
@ -469,46 +526,11 @@ final class DiffusionRepositoryController extends DiffusionController {
|
||||||
|
|
||||||
$panel->setHeader($header);
|
$panel->setHeader($header);
|
||||||
$panel->setTable($view);
|
$panel->setTable($view);
|
||||||
|
$panel->setBackground(PHUIObjectBoxView::BLUE_PROPERTY);
|
||||||
|
|
||||||
return $panel;
|
return $panel;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildActionList(PhabricatorRepository $repository) {
|
|
||||||
$viewer = $this->getRequest()->getUser();
|
|
||||||
|
|
||||||
$edit_uri = $repository->getPathURI('edit/');
|
|
||||||
|
|
||||||
$view = id(new PhabricatorActionListView())
|
|
||||||
->setUser($viewer)
|
|
||||||
->setObject($repository);
|
|
||||||
|
|
||||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
|
||||||
$viewer,
|
|
||||||
$repository,
|
|
||||||
PhabricatorPolicyCapability::CAN_EDIT);
|
|
||||||
|
|
||||||
$view->addAction(
|
|
||||||
id(new PhabricatorActionView())
|
|
||||||
->setName(pht('Edit Repository'))
|
|
||||||
->setIcon('fa-pencil')
|
|
||||||
->setHref($edit_uri)
|
|
||||||
->setWorkflow(!$can_edit)
|
|
||||||
->setDisabled(!$can_edit));
|
|
||||||
|
|
||||||
if ($repository->isHosted()) {
|
|
||||||
$push_uri = $this->getApplicationURI(
|
|
||||||
'pushlog/?repositories='.$repository->getMonogram());
|
|
||||||
|
|
||||||
$view->addAction(
|
|
||||||
id(new PhabricatorActionView())
|
|
||||||
->setName(pht('View Push Logs'))
|
|
||||||
->setIcon('fa-list-alt')
|
|
||||||
->setHref($push_uri));
|
|
||||||
}
|
|
||||||
|
|
||||||
return $view;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function buildHistoryTable(
|
private function buildHistoryTable(
|
||||||
$history_results,
|
$history_results,
|
||||||
$history,
|
$history,
|
||||||
|
@ -551,7 +573,7 @@ final class DiffusionRepositoryController extends DiffusionController {
|
||||||
->setIcon('fa-list-alt');
|
->setIcon('fa-list-alt');
|
||||||
|
|
||||||
$button = id(new PHUIButtonView())
|
$button = id(new PHUIButtonView())
|
||||||
->setText(pht('View Full History'))
|
->setText(pht('View History'))
|
||||||
->setHref($drequest->generateURI(
|
->setHref($drequest->generateURI(
|
||||||
array(
|
array(
|
||||||
'action' => 'history',
|
'action' => 'history',
|
||||||
|
@ -559,7 +581,8 @@ final class DiffusionRepositoryController extends DiffusionController {
|
||||||
->setTag('a')
|
->setTag('a')
|
||||||
->setIcon($icon);
|
->setIcon($icon);
|
||||||
|
|
||||||
$panel = new PHUIObjectBoxView();
|
$panel = id(new PHUIObjectBoxView())
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY);
|
||||||
$header = id(new PHUIHeaderView())
|
$header = id(new PHUIHeaderView())
|
||||||
->setHeader(pht('Recent Commits'))
|
->setHeader(pht('Recent Commits'))
|
||||||
->addActionLink($button);
|
->addActionLink($button);
|
||||||
|
@ -569,6 +592,46 @@ final class DiffusionRepositoryController extends DiffusionController {
|
||||||
return $panel;
|
return $panel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function buildLocateFile() {
|
||||||
|
$request = $this->getRequest();
|
||||||
|
$viewer = $request->getUser();
|
||||||
|
$drequest = $this->getDiffusionRequest();
|
||||||
|
$repository = $drequest->getRepository();
|
||||||
|
|
||||||
|
$locate_panel = null;
|
||||||
|
if ($repository->canUsePathTree()) {
|
||||||
|
Javelin::initBehavior(
|
||||||
|
'diffusion-locate-file',
|
||||||
|
array(
|
||||||
|
'controlID' => 'locate-control',
|
||||||
|
'inputID' => 'locate-input',
|
||||||
|
'browseBaseURI' => (string)$drequest->generateURI(
|
||||||
|
array(
|
||||||
|
'action' => 'browse',
|
||||||
|
)),
|
||||||
|
'uri' => (string)$drequest->generateURI(
|
||||||
|
array(
|
||||||
|
'action' => 'pathtree',
|
||||||
|
)),
|
||||||
|
));
|
||||||
|
|
||||||
|
$form = id(new AphrontFormView())
|
||||||
|
->setUser($viewer)
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormTypeaheadControl())
|
||||||
|
->setHardpointID('locate-control')
|
||||||
|
->setID('locate-input')
|
||||||
|
->setLabel(pht('Locate File')));
|
||||||
|
$form_box = id(new PHUIBoxView())
|
||||||
|
->appendChild($form->buildLayoutView());
|
||||||
|
$locate_panel = id(new PHUIObjectBoxView())
|
||||||
|
->setHeaderText(pht('Locate File'))
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
|
->appendChild($form_box);
|
||||||
|
}
|
||||||
|
return $locate_panel;
|
||||||
|
}
|
||||||
|
|
||||||
private function buildBrowseTable(
|
private function buildBrowseTable(
|
||||||
$browse_results,
|
$browse_results,
|
||||||
$browse_paths,
|
$browse_paths,
|
||||||
|
@ -606,9 +669,10 @@ final class DiffusionRepositoryController extends DiffusionController {
|
||||||
|
|
||||||
$browse_uri = $drequest->generateURI(array('action' => 'browse'));
|
$browse_uri = $drequest->generateURI(array('action' => 'browse'));
|
||||||
|
|
||||||
$browse_panel = new PHUIObjectBoxView();
|
$browse_panel = id(new PHUIObjectBoxView())
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY);
|
||||||
$header = id(new PHUIHeaderView())
|
$header = id(new PHUIHeaderView())
|
||||||
->setHeader(pht('Repository'));
|
->setHeader($repository->getName());
|
||||||
|
|
||||||
$icon = id(new PHUIIconView())
|
$icon = id(new PHUIIconView())
|
||||||
->setIcon('fa-folder-open');
|
->setIcon('fa-folder-open');
|
||||||
|
@ -621,38 +685,6 @@ final class DiffusionRepositoryController extends DiffusionController {
|
||||||
|
|
||||||
$header->addActionLink($button);
|
$header->addActionLink($button);
|
||||||
$browse_panel->setHeader($header);
|
$browse_panel->setHeader($header);
|
||||||
|
|
||||||
$locate_panel = null;
|
|
||||||
if ($repository->canUsePathTree()) {
|
|
||||||
Javelin::initBehavior(
|
|
||||||
'diffusion-locate-file',
|
|
||||||
array(
|
|
||||||
'controlID' => 'locate-control',
|
|
||||||
'inputID' => 'locate-input',
|
|
||||||
'browseBaseURI' => (string)$drequest->generateURI(
|
|
||||||
array(
|
|
||||||
'action' => 'browse',
|
|
||||||
)),
|
|
||||||
'uri' => (string)$drequest->generateURI(
|
|
||||||
array(
|
|
||||||
'action' => 'pathtree',
|
|
||||||
)),
|
|
||||||
));
|
|
||||||
|
|
||||||
$form = id(new AphrontFormView())
|
|
||||||
->setUser($viewer)
|
|
||||||
->appendChild(
|
|
||||||
id(new AphrontFormTypeaheadControl())
|
|
||||||
->setHardpointID('locate-control')
|
|
||||||
->setID('locate-input')
|
|
||||||
->setLabel(pht('Locate File')));
|
|
||||||
$form_box = id(new PHUIBoxView())
|
|
||||||
->appendChild($form->buildLayoutView());
|
|
||||||
$locate_panel = id(new PHUIObjectBoxView())
|
|
||||||
->setHeaderText('Locate File')
|
|
||||||
->appendChild($form_box);
|
|
||||||
}
|
|
||||||
|
|
||||||
$browse_panel->setTable($browse_table);
|
$browse_panel->setTable($browse_table);
|
||||||
|
|
||||||
$pager->setURI($browse_uri, 'offset');
|
$pager->setURI($browse_uri, 'offset');
|
||||||
|
@ -664,7 +696,6 @@ final class DiffusionRepositoryController extends DiffusionController {
|
||||||
}
|
}
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
$locate_panel,
|
|
||||||
$browse_panel,
|
$browse_panel,
|
||||||
$pager_box,
|
$pager_box,
|
||||||
);
|
);
|
||||||
|
|
|
@ -262,10 +262,26 @@ final class DiffusionRepositoryCreateController
|
||||||
$crumbs = $this->buildApplicationCrumbs();
|
$crumbs = $this->buildApplicationCrumbs();
|
||||||
$crumbs->addTextCrumb($title);
|
$crumbs->addTextCrumb($title);
|
||||||
|
|
||||||
|
$header = id(new PHUIHeaderView())
|
||||||
|
->setHeader($title)
|
||||||
|
->setHeaderIcon('fa-pencil');
|
||||||
|
|
||||||
|
$form_box = id(new PHUIObjectBoxView())
|
||||||
|
->setHeaderText($title)
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
|
->setForm($form);
|
||||||
|
|
||||||
|
$view = id(new PHUITwoColumnView())
|
||||||
|
->setHeader($header)
|
||||||
|
->setFooter(array(
|
||||||
|
$form,
|
||||||
|
));
|
||||||
|
|
||||||
return $this->newPage()
|
return $this->newPage()
|
||||||
->setTitle($title)
|
->setTitle($title)
|
||||||
->setCrumbs($crumbs)
|
->setCrumbs($crumbs)
|
||||||
->appendChild($form);
|
->appendChild($view);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,10 @@ final class DiffusionRepositoryEditActionsController
|
||||||
|
|
||||||
$title = pht('Edit Actions (%s)', $repository->getName());
|
$title = pht('Edit Actions (%s)', $repository->getName());
|
||||||
|
|
||||||
|
$header = id(new PHUIHeaderView())
|
||||||
|
->setHeader($title)
|
||||||
|
->setHeaderIcon('fa-pencil');
|
||||||
|
|
||||||
$policies = id(new PhabricatorPolicyQuery())
|
$policies = id(new PhabricatorPolicyQuery())
|
||||||
->setViewer($viewer)
|
->setViewer($viewer)
|
||||||
->setObject($repository)
|
->setObject($repository)
|
||||||
|
@ -97,13 +101,21 @@ final class DiffusionRepositoryEditActionsController
|
||||||
->addCancelButton($edit_uri));
|
->addCancelButton($edit_uri));
|
||||||
|
|
||||||
$form_box = id(new PHUIObjectBoxView())
|
$form_box = id(new PHUIObjectBoxView())
|
||||||
->setHeaderText($title)
|
->setHeaderText(pht('Actions'))
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->setForm($form);
|
->setForm($form);
|
||||||
|
|
||||||
|
$view = id(new PHUITwoColumnView())
|
||||||
|
->setHeader($header)
|
||||||
|
->setFooter(array(
|
||||||
|
$form_box,
|
||||||
|
));
|
||||||
|
|
||||||
return $this->newPage()
|
return $this->newPage()
|
||||||
->setTitle($title)
|
->setTitle($title)
|
||||||
->setCrumbs($crumbs)
|
->setCrumbs($crumbs)
|
||||||
->appendChild($form_box);
|
->appendChild($view);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,10 @@ final class DiffusionRepositoryEditAutomationController
|
||||||
|
|
||||||
$title = pht('Edit %s', $repository->getName());
|
$title = pht('Edit %s', $repository->getName());
|
||||||
|
|
||||||
|
$header = id(new PHUIHeaderView())
|
||||||
|
->setHeader($title)
|
||||||
|
->setHeaderIcon('fa-pencil');
|
||||||
|
|
||||||
$form = id(new AphrontFormView())
|
$form = id(new AphrontFormView())
|
||||||
->setUser($viewer)
|
->setUser($viewer)
|
||||||
->appendRemarkupInstructions(
|
->appendRemarkupInstructions(
|
||||||
|
@ -69,14 +73,21 @@ final class DiffusionRepositoryEditAutomationController
|
||||||
->setValue(pht('Save'))
|
->setValue(pht('Save'))
|
||||||
->addCancelButton($edit_uri));
|
->addCancelButton($edit_uri));
|
||||||
|
|
||||||
$object_box = id(new PHUIObjectBoxView())
|
$form_box = id(new PHUIObjectBoxView())
|
||||||
->setHeaderText($title)
|
->setHeaderText(pht('Automation'))
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->setForm($form);
|
->setForm($form);
|
||||||
|
|
||||||
|
$view = id(new PHUITwoColumnView())
|
||||||
|
->setHeader($header)
|
||||||
|
->setFooter(array(
|
||||||
|
$form_box,
|
||||||
|
));
|
||||||
|
|
||||||
return $this->newPage()
|
return $this->newPage()
|
||||||
->setTitle($title)
|
->setTitle($title)
|
||||||
->setCrumbs($crumbs)
|
->setCrumbs($crumbs)
|
||||||
->appendChild($object_box);
|
->appendChild($view);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,6 +105,10 @@ final class DiffusionRepositoryEditBasicController
|
||||||
|
|
||||||
$title = pht('Edit %s', $repository->getName());
|
$title = pht('Edit %s', $repository->getName());
|
||||||
|
|
||||||
|
$header = id(new PHUIHeaderView())
|
||||||
|
->setHeader($title)
|
||||||
|
->setHeaderIcon('fa-pencil');
|
||||||
|
|
||||||
$form = id(new AphrontFormView())
|
$form = id(new AphrontFormView())
|
||||||
->setUser($viewer)
|
->setUser($viewer)
|
||||||
->appendChild(
|
->appendChild(
|
||||||
|
@ -144,16 +148,23 @@ final class DiffusionRepositoryEditBasicController
|
||||||
->appendChild(id(new PHUIFormDividerControl()))
|
->appendChild(id(new PHUIFormDividerControl()))
|
||||||
->appendRemarkupInstructions($this->getReadmeInstructions());
|
->appendRemarkupInstructions($this->getReadmeInstructions());
|
||||||
|
|
||||||
$object_box = id(new PHUIObjectBoxView())
|
$form_box = id(new PHUIObjectBoxView())
|
||||||
->setHeaderText($title)
|
->setHeaderText(pht('Basic Information'))
|
||||||
->setValidationException($validation_exception)
|
->setValidationException($validation_exception)
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->setForm($form)
|
->setForm($form)
|
||||||
->setFormErrors($errors);
|
->setFormErrors($errors);
|
||||||
|
|
||||||
|
$view = id(new PHUITwoColumnView())
|
||||||
|
->setHeader($header)
|
||||||
|
->setFooter(array(
|
||||||
|
$form_box,
|
||||||
|
));
|
||||||
|
|
||||||
return $this->newPage()
|
return $this->newPage()
|
||||||
->setTitle($title)
|
->setTitle($title)
|
||||||
->setCrumbs($crumbs)
|
->setCrumbs($crumbs)
|
||||||
->appendChild($object_box);
|
->appendChild($view);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getReadmeInstructions() {
|
private function getReadmeInstructions() {
|
||||||
|
|
|
@ -98,6 +98,9 @@ final class DiffusionRepositoryEditBranchesController
|
||||||
$crumbs->addTextCrumb(pht('Edit Branches'));
|
$crumbs->addTextCrumb(pht('Edit Branches'));
|
||||||
|
|
||||||
$title = pht('Edit Branches (%s)', $repository->getName());
|
$title = pht('Edit Branches (%s)', $repository->getName());
|
||||||
|
$header = id(new PHUIHeaderView())
|
||||||
|
->setHeader($title)
|
||||||
|
->setHeaderIcon('fa-pencil');
|
||||||
|
|
||||||
$policies = id(new PhabricatorPolicyQuery())
|
$policies = id(new PhabricatorPolicyQuery())
|
||||||
->setViewer($viewer)
|
->setViewer($viewer)
|
||||||
|
@ -213,14 +216,21 @@ final class DiffusionRepositoryEditBranchesController
|
||||||
->addCancelButton($edit_uri));
|
->addCancelButton($edit_uri));
|
||||||
|
|
||||||
$form_box = id(new PHUIObjectBoxView())
|
$form_box = id(new PHUIObjectBoxView())
|
||||||
|
->setHeaderText(pht('Branches'))
|
||||||
->setValidationException($validation_exception)
|
->setValidationException($validation_exception)
|
||||||
->setHeaderText($title)
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->setForm($form);
|
->setForm($form);
|
||||||
|
|
||||||
|
$view = id(new PHUITwoColumnView())
|
||||||
|
->setHeader($header)
|
||||||
|
->setFooter(array(
|
||||||
|
$form_box,
|
||||||
|
));
|
||||||
|
|
||||||
return $this->newPage()
|
return $this->newPage()
|
||||||
->setTitle($title)
|
->setTitle($title)
|
||||||
->setCrumbs($crumbs)
|
->setCrumbs($crumbs)
|
||||||
->appendChild($form_box);
|
->appendChild($view);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function processBranches($string) {
|
private function processBranches($string) {
|
||||||
|
|
|
@ -20,6 +20,7 @@ abstract class DiffusionRepositoryEditController
|
||||||
$crumbs->addTextCrumb(pht('Edit'), $edit_uri);
|
$crumbs->addTextCrumb(pht('Edit'), $edit_uri);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$crumbs->setBorder(true);
|
||||||
|
|
||||||
return $crumbs;
|
return $crumbs;
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,9 @@ final class DiffusionRepositoryEditEncodingController
|
||||||
$crumbs->addTextCrumb(pht('Edit Encoding'));
|
$crumbs->addTextCrumb(pht('Edit Encoding'));
|
||||||
|
|
||||||
$title = pht('Edit %s', $repository->getName());
|
$title = pht('Edit %s', $repository->getName());
|
||||||
|
$header = id(new PHUIHeaderView())
|
||||||
|
->setHeader($title)
|
||||||
|
->setHeaderIcon('fa-pencil');
|
||||||
|
|
||||||
$form = id(new AphrontFormView())
|
$form = id(new AphrontFormView())
|
||||||
->setUser($user)
|
->setUser($user)
|
||||||
|
@ -65,15 +68,22 @@ final class DiffusionRepositoryEditEncodingController
|
||||||
->setValue(pht('Save Encoding'))
|
->setValue(pht('Save Encoding'))
|
||||||
->addCancelButton($edit_uri));
|
->addCancelButton($edit_uri));
|
||||||
|
|
||||||
$object_box = id(new PHUIObjectBoxView())
|
$form_box = id(new PHUIObjectBoxView())
|
||||||
->setHeaderText($title)
|
->setHeaderText(pht('Encoding'))
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->setForm($form)
|
->setForm($form)
|
||||||
->setFormErrors($errors);
|
->setFormErrors($errors);
|
||||||
|
|
||||||
|
$view = id(new PHUITwoColumnView())
|
||||||
|
->setHeader($header)
|
||||||
|
->setFooter(array(
|
||||||
|
$form_box,
|
||||||
|
));
|
||||||
|
|
||||||
return $this->newPage()
|
return $this->newPage()
|
||||||
->setTitle($title)
|
->setTitle($title)
|
||||||
->setCrumbs($crumbs)
|
->setCrumbs($crumbs)
|
||||||
->appendChild($object_box);
|
->appendChild($view);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getEncodingInstructions() {
|
private function getEncodingInstructions() {
|
||||||
|
|
|
@ -57,6 +57,9 @@ final class DiffusionRepositoryEditHostingController
|
||||||
$crumbs->addTextCrumb(pht('Edit Hosting'));
|
$crumbs->addTextCrumb(pht('Edit Hosting'));
|
||||||
|
|
||||||
$title = pht('Edit Hosting (%s)', $repository->getName());
|
$title = pht('Edit Hosting (%s)', $repository->getName());
|
||||||
|
$header = id(new PHUIHeaderView())
|
||||||
|
->setHeader($title)
|
||||||
|
->setHeaderIcon('fa-pencil');
|
||||||
|
|
||||||
$hosted_control = id(new AphrontFormRadioButtonControl())
|
$hosted_control = id(new AphrontFormRadioButtonControl())
|
||||||
->setName('hosting')
|
->setName('hosting')
|
||||||
|
@ -95,14 +98,21 @@ final class DiffusionRepositoryEditHostingController
|
||||||
->setValue(pht('Save and Continue'))
|
->setValue(pht('Save and Continue'))
|
||||||
->addCancelButton($edit_uri));
|
->addCancelButton($edit_uri));
|
||||||
|
|
||||||
$object_box = id(new PHUIObjectBoxView())
|
$form_box = id(new PHUIObjectBoxView())
|
||||||
->setHeaderText($title)
|
->setHeaderText(pht('Hosting'))
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->setForm($form);
|
->setForm($form);
|
||||||
|
|
||||||
|
$view = id(new PHUITwoColumnView())
|
||||||
|
->setHeader($header)
|
||||||
|
->setFooter(array(
|
||||||
|
$form_box,
|
||||||
|
));
|
||||||
|
|
||||||
return $this->newPage()
|
return $this->newPage()
|
||||||
->setTitle($title)
|
->setTitle($title)
|
||||||
->setCrumbs($crumbs)
|
->setCrumbs($crumbs)
|
||||||
->appendChild($object_box);
|
->appendChild($view);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function handleProtocols(PhabricatorRepository $repository) {
|
public function handleProtocols(PhabricatorRepository $repository) {
|
||||||
|
@ -155,7 +165,9 @@ final class DiffusionRepositoryEditHostingController
|
||||||
$crumbs->addTextCrumb(pht('Edit Protocols'));
|
$crumbs->addTextCrumb(pht('Edit Protocols'));
|
||||||
|
|
||||||
$title = pht('Edit Protocols (%s)', $repository->getName());
|
$title = pht('Edit Protocols (%s)', $repository->getName());
|
||||||
|
$header = id(new PHUIHeaderView())
|
||||||
|
->setHeader($title)
|
||||||
|
->setHeaderIcon('fa-pencil');
|
||||||
|
|
||||||
$rw_message = pht(
|
$rw_message = pht(
|
||||||
'Phabricator will serve a read-write copy of this repository.');
|
'Phabricator will serve a read-write copy of this repository.');
|
||||||
|
@ -256,14 +268,21 @@ final class DiffusionRepositoryEditHostingController
|
||||||
->setValue(pht('Save Changes'))
|
->setValue(pht('Save Changes'))
|
||||||
->addCancelButton($prev_uri, pht('Back')));
|
->addCancelButton($prev_uri, pht('Back')));
|
||||||
|
|
||||||
$object_box = id(new PHUIObjectBoxView())
|
$form_box = id(new PHUIObjectBoxView())
|
||||||
->setHeaderText($title)
|
->setHeaderText(pht('Protocols'))
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->setForm($form);
|
->setForm($form);
|
||||||
|
|
||||||
|
$view = id(new PHUITwoColumnView())
|
||||||
|
->setHeader($header)
|
||||||
|
->setFooter(array(
|
||||||
|
$form_box,
|
||||||
|
));
|
||||||
|
|
||||||
return $this->newPage()
|
return $this->newPage()
|
||||||
->setTitle($title)
|
->setTitle($title)
|
||||||
->setCrumbs($crumbs)
|
->setCrumbs($crumbs)
|
||||||
->appendChild($object_box);
|
->appendChild($view);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,16 +38,16 @@ final class DiffusionRepositoryEditMainController
|
||||||
$title = pht('Edit %s', $repository->getName());
|
$title = pht('Edit %s', $repository->getName());
|
||||||
|
|
||||||
$header = id(new PHUIHeaderView())
|
$header = id(new PHUIHeaderView())
|
||||||
->setHeader($title);
|
->setHeader($title)
|
||||||
|
->setHeaderIcon('fa-pencil');
|
||||||
if ($repository->isTracked()) {
|
if ($repository->isTracked()) {
|
||||||
$header->setStatus('fa-check', 'bluegrey', pht('Active'));
|
$header->setStatus('fa-check', 'bluegrey', pht('Active'));
|
||||||
} else {
|
} else {
|
||||||
$header->setStatus('fa-ban', 'dark', pht('Inactive'));
|
$header->setStatus('fa-ban', 'dark', pht('Inactive'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$basic_actions = $this->buildBasicActions($repository);
|
$curtain = $this->buildCurtain($repository);
|
||||||
$basic_properties =
|
$basic_properties = $this->buildBasicProperties($repository);
|
||||||
$this->buildBasicProperties($repository, $basic_actions);
|
|
||||||
|
|
||||||
$policy_actions = $this->buildPolicyActions($repository);
|
$policy_actions = $this->buildPolicyActions($repository);
|
||||||
$policy_properties =
|
$policy_properties =
|
||||||
|
@ -119,16 +119,14 @@ final class DiffusionRepositoryEditMainController
|
||||||
|
|
||||||
$boxes = array();
|
$boxes = array();
|
||||||
|
|
||||||
$boxes[] = id(new PHUIObjectBoxView())
|
|
||||||
->setHeader($header)
|
|
||||||
->addPropertyList($basic_properties);
|
|
||||||
|
|
||||||
$boxes[] = id(new PHUIObjectBoxView())
|
$boxes[] = id(new PHUIObjectBoxView())
|
||||||
->setHeaderText(pht('Policies'))
|
->setHeaderText(pht('Policies'))
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->addPropertyList($policy_properties);
|
->addPropertyList($policy_properties);
|
||||||
|
|
||||||
$boxes[] = id(new PHUIObjectBoxView())
|
$boxes[] = id(new PHUIObjectBoxView())
|
||||||
->setHeaderText(pht('Hosting'))
|
->setHeaderText(pht('Hosting'))
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->addPropertyList($hosting_properties);
|
->addPropertyList($hosting_properties);
|
||||||
|
|
||||||
if ($repository->canMirror()) {
|
if ($repository->canMirror()) {
|
||||||
|
@ -156,6 +154,7 @@ final class DiffusionRepositoryEditMainController
|
||||||
$boxes[] = id(new PHUIObjectBoxView())
|
$boxes[] = id(new PHUIObjectBoxView())
|
||||||
->setFormErrors($mirror_info)
|
->setFormErrors($mirror_info)
|
||||||
->setHeaderText(pht('Mirrors'))
|
->setHeaderText(pht('Mirrors'))
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->addPropertyList($mirror_properties);
|
->addPropertyList($mirror_properties);
|
||||||
|
|
||||||
$boxes[] = $mirror_list;
|
$boxes[] = $mirror_list;
|
||||||
|
@ -164,73 +163,88 @@ final class DiffusionRepositoryEditMainController
|
||||||
if ($remote_properties) {
|
if ($remote_properties) {
|
||||||
$boxes[] = id(new PHUIObjectBoxView())
|
$boxes[] = id(new PHUIObjectBoxView())
|
||||||
->setHeaderText(pht('Remote'))
|
->setHeaderText(pht('Remote'))
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->addPropertyList($remote_properties);
|
->addPropertyList($remote_properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($storage_properties) {
|
if ($storage_properties) {
|
||||||
$boxes[] = id(new PHUIObjectBoxView())
|
$boxes[] = id(new PHUIObjectBoxView())
|
||||||
->setHeaderText(pht('Storage'))
|
->setHeaderText(pht('Storage'))
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->addPropertyList($storage_properties);
|
->addPropertyList($storage_properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($staging_properties) {
|
if ($staging_properties) {
|
||||||
$boxes[] = id(new PHUIObjectBoxView())
|
$boxes[] = id(new PHUIObjectBoxView())
|
||||||
->setHeaderText(pht('Staging'))
|
->setHeaderText(pht('Staging'))
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->addPropertyList($staging_properties);
|
->addPropertyList($staging_properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($automation_properties) {
|
if ($automation_properties) {
|
||||||
$boxes[] = id(new PHUIObjectBoxView())
|
$boxes[] = id(new PHUIObjectBoxView())
|
||||||
->setHeaderText(pht('Automation'))
|
->setHeaderText(pht('Automation'))
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->addPropertyList($automation_properties);
|
->addPropertyList($automation_properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
$boxes[] = id(new PHUIObjectBoxView())
|
$boxes[] = id(new PHUIObjectBoxView())
|
||||||
->setHeaderText(pht('Text Encoding'))
|
->setHeaderText(pht('Text Encoding'))
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->addPropertyList($encoding_properties);
|
->addPropertyList($encoding_properties);
|
||||||
|
|
||||||
$boxes[] = id(new PHUIObjectBoxView())
|
$boxes[] = id(new PHUIObjectBoxView())
|
||||||
->setHeaderText(pht('Symbols'))
|
->setHeaderText(pht('Symbols'))
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->addPropertyList($symbols_properties);
|
->addPropertyList($symbols_properties);
|
||||||
|
|
||||||
if ($branches_properties) {
|
if ($branches_properties) {
|
||||||
$boxes[] = id(new PHUIObjectBoxView())
|
$boxes[] = id(new PHUIObjectBoxView())
|
||||||
->setHeaderText(pht('Branches'))
|
->setHeaderText(pht('Branches'))
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->addPropertyList($branches_properties);
|
->addPropertyList($branches_properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($subversion_properties) {
|
if ($subversion_properties) {
|
||||||
$boxes[] = id(new PHUIObjectBoxView())
|
$boxes[] = id(new PHUIObjectBoxView())
|
||||||
->setHeaderText(pht('Subversion'))
|
->setHeaderText(pht('Subversion'))
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->addPropertyList($subversion_properties);
|
->addPropertyList($subversion_properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
$boxes[] = id(new PHUIObjectBoxView())
|
$boxes[] = id(new PHUIObjectBoxView())
|
||||||
->setHeaderText(pht('Actions'))
|
->setHeaderText(pht('Actions'))
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->addPropertyList($actions_properties);
|
->addPropertyList($actions_properties);
|
||||||
|
|
||||||
return $this->buildApplicationPage(
|
$crumbs->setBorder(true);
|
||||||
array(
|
|
||||||
$crumbs,
|
$view = id(new PHUITwoColumnView())
|
||||||
|
->setHeader($header)
|
||||||
|
->setCurtain($curtain)
|
||||||
|
->addPropertySection(pht('Properties'), $basic_properties)
|
||||||
|
->setMainColumn(array(
|
||||||
$boxes,
|
$boxes,
|
||||||
$timeline,
|
$timeline,
|
||||||
),
|
|
||||||
array(
|
|
||||||
'title' => $title,
|
|
||||||
));
|
));
|
||||||
|
|
||||||
|
return $this->newPage()
|
||||||
|
->setTitle($title)
|
||||||
|
->setCrumbs($crumbs)
|
||||||
|
->appendChild($view);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildBasicActions(PhabricatorRepository $repository) {
|
private function buildCurtain(PhabricatorRepository $repository) {
|
||||||
$viewer = $this->getRequest()->getUser();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$view = id(new PhabricatorActionListView())
|
$curtain = $this->newCurtainView($repository);
|
||||||
->setUser($viewer);
|
|
||||||
|
|
||||||
$edit = id(new PhabricatorActionView())
|
$edit = id(new PhabricatorActionView())
|
||||||
->setIcon('fa-pencil')
|
->setIcon('fa-pencil')
|
||||||
->setName(pht('Edit Basic Information'))
|
->setName(pht('Edit Basic Information'))
|
||||||
->setHref($this->getRepositoryControllerURI($repository, 'edit/basic/'));
|
->setHref($this->getRepositoryControllerURI($repository, 'edit/basic/'));
|
||||||
$view->addAction($edit);
|
$curtain->addAction($edit);
|
||||||
|
|
||||||
$edit = id(new PhabricatorActionView())
|
$edit = id(new PhabricatorActionView())
|
||||||
->setIcon('fa-refresh')
|
->setIcon('fa-refresh')
|
||||||
|
@ -238,7 +252,7 @@ final class DiffusionRepositoryEditMainController
|
||||||
->setWorkflow(true)
|
->setWorkflow(true)
|
||||||
->setHref(
|
->setHref(
|
||||||
$this->getRepositoryControllerURI($repository, 'edit/update/'));
|
$this->getRepositoryControllerURI($repository, 'edit/update/'));
|
||||||
$view->addAction($edit);
|
$curtain->addAction($edit);
|
||||||
|
|
||||||
$activate = id(new PhabricatorActionView())
|
$activate = id(new PhabricatorActionView())
|
||||||
->setHref(
|
->setHref(
|
||||||
|
@ -255,9 +269,9 @@ final class DiffusionRepositoryEditMainController
|
||||||
->setName(pht('Activate Repository'));
|
->setName(pht('Activate Repository'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$view->addAction($activate);
|
$curtain->addAction($activate);
|
||||||
|
|
||||||
$view->addAction(
|
$curtain->addAction(
|
||||||
id(new PhabricatorActionView())
|
id(new PhabricatorActionView())
|
||||||
->setName(pht('Delete Repository'))
|
->setName(pht('Delete Repository'))
|
||||||
->setIcon('fa-times')
|
->setIcon('fa-times')
|
||||||
|
@ -266,19 +280,16 @@ final class DiffusionRepositoryEditMainController
|
||||||
->setDisabled(true)
|
->setDisabled(true)
|
||||||
->setWorkflow(true));
|
->setWorkflow(true));
|
||||||
|
|
||||||
return $view;
|
return $curtain;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildBasicProperties(
|
private function buildBasicProperties(
|
||||||
PhabricatorRepository $repository,
|
PhabricatorRepository $repository) {
|
||||||
PhabricatorActionListView $actions) {
|
|
||||||
|
|
||||||
$viewer = $this->getRequest()->getUser();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$view = id(new PHUIPropertyListView())
|
$view = id(new PHUIPropertyListView())
|
||||||
->setUser($viewer)
|
->setUser($viewer);
|
||||||
->setObject($repository)
|
|
||||||
->setActionList($actions);
|
|
||||||
|
|
||||||
$type = PhabricatorRepositoryType::getNameForRepositoryType(
|
$type = PhabricatorRepositoryType::getNameForRepositoryType(
|
||||||
$repository->getVersionControlSystem());
|
$repository->getVersionControlSystem());
|
||||||
|
@ -322,7 +333,7 @@ final class DiffusionRepositoryEditMainController
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildEncodingActions(PhabricatorRepository $repository) {
|
private function buildEncodingActions(PhabricatorRepository $repository) {
|
||||||
$viewer = $this->getRequest()->getUser();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$view = id(new PhabricatorActionListView())
|
$view = id(new PhabricatorActionListView())
|
||||||
->setUser($viewer);
|
->setUser($viewer);
|
||||||
|
@ -341,7 +352,7 @@ final class DiffusionRepositoryEditMainController
|
||||||
PhabricatorRepository $repository,
|
PhabricatorRepository $repository,
|
||||||
PhabricatorActionListView $actions) {
|
PhabricatorActionListView $actions) {
|
||||||
|
|
||||||
$viewer = $this->getRequest()->getUser();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$view = id(new PHUIPropertyListView())
|
$view = id(new PHUIPropertyListView())
|
||||||
->setUser($viewer)
|
->setUser($viewer)
|
||||||
|
@ -358,7 +369,7 @@ final class DiffusionRepositoryEditMainController
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildPolicyActions(PhabricatorRepository $repository) {
|
private function buildPolicyActions(PhabricatorRepository $repository) {
|
||||||
$viewer = $this->getRequest()->getUser();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$view = id(new PhabricatorActionListView())
|
$view = id(new PhabricatorActionListView())
|
||||||
->setUser($viewer);
|
->setUser($viewer);
|
||||||
|
@ -377,7 +388,7 @@ final class DiffusionRepositoryEditMainController
|
||||||
PhabricatorRepository $repository,
|
PhabricatorRepository $repository,
|
||||||
PhabricatorActionListView $actions) {
|
PhabricatorActionListView $actions) {
|
||||||
|
|
||||||
$viewer = $this->getRequest()->getUser();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$view = id(new PHUIPropertyListView())
|
$view = id(new PHUIPropertyListView())
|
||||||
->setUser($viewer)
|
->setUser($viewer)
|
||||||
|
@ -412,7 +423,7 @@ final class DiffusionRepositoryEditMainController
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildBranchesActions(PhabricatorRepository $repository) {
|
private function buildBranchesActions(PhabricatorRepository $repository) {
|
||||||
$viewer = $this->getRequest()->getUser();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$view = id(new PhabricatorActionListView())
|
$view = id(new PhabricatorActionListView())
|
||||||
->setUser($viewer);
|
->setUser($viewer);
|
||||||
|
@ -431,7 +442,7 @@ final class DiffusionRepositoryEditMainController
|
||||||
PhabricatorRepository $repository,
|
PhabricatorRepository $repository,
|
||||||
PhabricatorActionListView $actions) {
|
PhabricatorActionListView $actions) {
|
||||||
|
|
||||||
$viewer = $this->getRequest()->getUser();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$view = id(new PHUIPropertyListView())
|
$view = id(new PHUIPropertyListView())
|
||||||
->setUser($viewer)
|
->setUser($viewer)
|
||||||
|
@ -461,7 +472,7 @@ final class DiffusionRepositoryEditMainController
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildSubversionActions(PhabricatorRepository $repository) {
|
private function buildSubversionActions(PhabricatorRepository $repository) {
|
||||||
$viewer = $this->getRequest()->getUser();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$view = id(new PhabricatorActionListView())
|
$view = id(new PhabricatorActionListView())
|
||||||
->setUser($viewer);
|
->setUser($viewer);
|
||||||
|
@ -480,7 +491,7 @@ final class DiffusionRepositoryEditMainController
|
||||||
PhabricatorRepository $repository,
|
PhabricatorRepository $repository,
|
||||||
PhabricatorActionListView $actions) {
|
PhabricatorActionListView $actions) {
|
||||||
|
|
||||||
$viewer = $this->getRequest()->getUser();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$view = id(new PHUIPropertyListView())
|
$view = id(new PHUIPropertyListView())
|
||||||
->setUser($viewer)
|
->setUser($viewer)
|
||||||
|
@ -500,7 +511,7 @@ final class DiffusionRepositoryEditMainController
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildActionsActions(PhabricatorRepository $repository) {
|
private function buildActionsActions(PhabricatorRepository $repository) {
|
||||||
$viewer = $this->getRequest()->getUser();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$view = id(new PhabricatorActionListView())
|
$view = id(new PhabricatorActionListView())
|
||||||
->setUser($viewer);
|
->setUser($viewer);
|
||||||
|
@ -519,7 +530,7 @@ final class DiffusionRepositoryEditMainController
|
||||||
PhabricatorRepository $repository,
|
PhabricatorRepository $repository,
|
||||||
PhabricatorActionListView $actions) {
|
PhabricatorActionListView $actions) {
|
||||||
|
|
||||||
$viewer = $this->getRequest()->getUser();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$view = id(new PHUIPropertyListView())
|
$view = id(new PHUIPropertyListView())
|
||||||
->setUser($viewer)
|
->setUser($viewer)
|
||||||
|
@ -541,7 +552,7 @@ final class DiffusionRepositoryEditMainController
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildRemoteActions(PhabricatorRepository $repository) {
|
private function buildRemoteActions(PhabricatorRepository $repository) {
|
||||||
$viewer = $this->getRequest()->getUser();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$view = id(new PhabricatorActionListView())
|
$view = id(new PhabricatorActionListView())
|
||||||
->setUser($viewer);
|
->setUser($viewer);
|
||||||
|
@ -560,7 +571,7 @@ final class DiffusionRepositoryEditMainController
|
||||||
PhabricatorRepository $repository,
|
PhabricatorRepository $repository,
|
||||||
PhabricatorActionListView $actions) {
|
PhabricatorActionListView $actions) {
|
||||||
|
|
||||||
$viewer = $this->getRequest()->getUser();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$view = id(new PHUIPropertyListView())
|
$view = id(new PHUIPropertyListView())
|
||||||
->setUser($viewer)
|
->setUser($viewer)
|
||||||
|
@ -581,7 +592,7 @@ final class DiffusionRepositoryEditMainController
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildStorageActions(PhabricatorRepository $repository) {
|
private function buildStorageActions(PhabricatorRepository $repository) {
|
||||||
$viewer = $this->getRequest()->getUser();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$view = id(new PhabricatorActionListView())
|
$view = id(new PhabricatorActionListView())
|
||||||
->setUser($viewer);
|
->setUser($viewer);
|
||||||
|
@ -600,7 +611,7 @@ final class DiffusionRepositoryEditMainController
|
||||||
PhabricatorRepository $repository,
|
PhabricatorRepository $repository,
|
||||||
PhabricatorActionListView $actions) {
|
PhabricatorActionListView $actions) {
|
||||||
|
|
||||||
$viewer = $this->getRequest()->getUser();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$view = id(new PHUIPropertyListView())
|
$view = id(new PHUIPropertyListView())
|
||||||
->setUser($viewer)
|
->setUser($viewer)
|
||||||
|
@ -801,7 +812,7 @@ final class DiffusionRepositoryEditMainController
|
||||||
private function buildRepositoryStatus(
|
private function buildRepositoryStatus(
|
||||||
PhabricatorRepository $repository) {
|
PhabricatorRepository $repository) {
|
||||||
|
|
||||||
$viewer = $this->getRequest()->getUser();
|
$viewer = $this->getViewer();
|
||||||
$is_cluster = $repository->getAlmanacServicePHID();
|
$is_cluster = $repository->getAlmanacServicePHID();
|
||||||
|
|
||||||
$view = new PHUIStatusListView();
|
$view = new PHUIStatusListView();
|
||||||
|
@ -1188,7 +1199,7 @@ final class DiffusionRepositoryEditMainController
|
||||||
private function buildMirrorActions(
|
private function buildMirrorActions(
|
||||||
PhabricatorRepository $repository) {
|
PhabricatorRepository $repository) {
|
||||||
|
|
||||||
$viewer = $this->getRequest()->getUser();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$mirror_actions = id(new PhabricatorActionListView())
|
$mirror_actions = id(new PhabricatorActionListView())
|
||||||
->setUser($viewer);
|
->setUser($viewer);
|
||||||
|
@ -1211,7 +1222,7 @@ final class DiffusionRepositoryEditMainController
|
||||||
PhabricatorRepository $repository,
|
PhabricatorRepository $repository,
|
||||||
PhabricatorActionListView $actions) {
|
PhabricatorActionListView $actions) {
|
||||||
|
|
||||||
$viewer = $this->getRequest()->getUser();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$mirror_properties = id(new PHUIPropertyListView())
|
$mirror_properties = id(new PHUIPropertyListView())
|
||||||
->setUser($viewer)
|
->setUser($viewer)
|
||||||
|
@ -1262,11 +1273,14 @@ final class DiffusionRepositoryEditMainController
|
||||||
$mirror_list->addItem($item);
|
$mirror_list->addItem($item);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $mirror_list;
|
return id(new PHUIObjectBoxView())
|
||||||
|
->setHeaderText(pht('Configured Mirrors'))
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
|
->setObjectList($mirror_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildSymbolsActions(PhabricatorRepository $repository) {
|
private function buildSymbolsActions(PhabricatorRepository $repository) {
|
||||||
$viewer = $this->getRequest()->getUser();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$view = id(new PhabricatorActionListView())
|
$view = id(new PhabricatorActionListView())
|
||||||
->setUser($viewer);
|
->setUser($viewer);
|
||||||
|
@ -1285,7 +1299,7 @@ final class DiffusionRepositoryEditMainController
|
||||||
PhabricatorRepository $repository,
|
PhabricatorRepository $repository,
|
||||||
PhabricatorActionListView $actions) {
|
PhabricatorActionListView $actions) {
|
||||||
|
|
||||||
$viewer = $this->getRequest()->getUser();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$view = id(new PHUIPropertyListView())
|
$view = id(new PHUIPropertyListView())
|
||||||
->setUser($viewer)
|
->setUser($viewer)
|
||||||
|
|
|
@ -45,7 +45,10 @@ final class DiffusionRepositoryEditStagingController
|
||||||
$crumbs = $this->buildApplicationCrumbs();
|
$crumbs = $this->buildApplicationCrumbs();
|
||||||
$crumbs->addTextCrumb(pht('Edit Staging'));
|
$crumbs->addTextCrumb(pht('Edit Staging'));
|
||||||
|
|
||||||
$title = pht('Edit %s', $repository->getName());
|
$title = pht('Edit Staging (%s)', $repository->getName());
|
||||||
|
$header = id(new PHUIHeaderView())
|
||||||
|
->setHeader($title)
|
||||||
|
->setHeaderIcon('fa-pencil');
|
||||||
|
|
||||||
$form = id(new AphrontFormView())
|
$form = id(new AphrontFormView())
|
||||||
->setUser($viewer)
|
->setUser($viewer)
|
||||||
|
@ -68,14 +71,21 @@ final class DiffusionRepositoryEditStagingController
|
||||||
->setValue(pht('Save'))
|
->setValue(pht('Save'))
|
||||||
->addCancelButton($edit_uri));
|
->addCancelButton($edit_uri));
|
||||||
|
|
||||||
$object_box = id(new PHUIObjectBoxView())
|
$form_box = id(new PHUIObjectBoxView())
|
||||||
->setHeaderText($title)
|
->setHeaderText(pht('Staging'))
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->setForm($form);
|
->setForm($form);
|
||||||
|
|
||||||
|
$view = id(new PHUITwoColumnView())
|
||||||
|
->setHeader($header)
|
||||||
|
->setFooter(array(
|
||||||
|
$form_box,
|
||||||
|
));
|
||||||
|
|
||||||
return $this->newPage()
|
return $this->newPage()
|
||||||
->setTitle($title)
|
->setTitle($title)
|
||||||
->setCrumbs($crumbs)
|
->setCrumbs($crumbs)
|
||||||
->appendChild($object_box);
|
->appendChild($view);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,9 @@ final class DiffusionRepositoryEditStorageController
|
||||||
$crumbs->addTextCrumb(pht('Edit Storage'));
|
$crumbs->addTextCrumb(pht('Edit Storage'));
|
||||||
|
|
||||||
$title = pht('Edit %s', $repository->getName());
|
$title = pht('Edit %s', $repository->getName());
|
||||||
|
$header = id(new PHUIHeaderView())
|
||||||
|
->setHeader($title)
|
||||||
|
->setHeaderIcon('fa-pencil');
|
||||||
|
|
||||||
$service_phid = $repository->getAlmanacServicePHID();
|
$service_phid = $repository->getAlmanacServicePHID();
|
||||||
if ($service_phid) {
|
if ($service_phid) {
|
||||||
|
@ -57,15 +60,21 @@ final class DiffusionRepositoryEditStorageController
|
||||||
id(new AphrontFormSubmitControl())
|
id(new AphrontFormSubmitControl())
|
||||||
->addCancelButton($edit_uri, pht('Done')));
|
->addCancelButton($edit_uri, pht('Done')));
|
||||||
|
|
||||||
$object_box = id(new PHUIObjectBoxView())
|
$form_box = id(new PHUIObjectBoxView())
|
||||||
->setHeaderText($title)
|
->setHeaderText(pht('Storage'))
|
||||||
->setForm($form)
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->setFormErrors($errors);
|
->setForm($form);
|
||||||
|
|
||||||
|
$view = id(new PHUITwoColumnView())
|
||||||
|
->setHeader($header)
|
||||||
|
->setFooter(array(
|
||||||
|
$form_box,
|
||||||
|
));
|
||||||
|
|
||||||
return $this->newPage()
|
return $this->newPage()
|
||||||
->setTitle($title)
|
->setTitle($title)
|
||||||
->setCrumbs($crumbs)
|
->setCrumbs($crumbs)
|
||||||
->appendChild($object_box);
|
->appendChild($view);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,9 @@ final class DiffusionRepositoryEditSubversionController
|
||||||
$crumbs->addTextCrumb(pht('Edit Subversion Info'));
|
$crumbs->addTextCrumb(pht('Edit Subversion Info'));
|
||||||
|
|
||||||
$title = pht('Edit Subversion Info (%s)', $repository->getName());
|
$title = pht('Edit Subversion Info (%s)', $repository->getName());
|
||||||
|
$header = id(new PHUIHeaderView())
|
||||||
|
->setHeader($title)
|
||||||
|
->setHeaderIcon('fa-pencil');
|
||||||
|
|
||||||
$policies = id(new PhabricatorPolicyQuery())
|
$policies = id(new PhabricatorPolicyQuery())
|
||||||
->setViewer($viewer)
|
->setViewer($viewer)
|
||||||
|
@ -96,13 +99,20 @@ final class DiffusionRepositoryEditSubversionController
|
||||||
->addCancelButton($edit_uri));
|
->addCancelButton($edit_uri));
|
||||||
|
|
||||||
$form_box = id(new PHUIObjectBoxView())
|
$form_box = id(new PHUIObjectBoxView())
|
||||||
->setHeaderText($title)
|
->setHeaderText(pht('Subversion'))
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->setForm($form);
|
->setForm($form);
|
||||||
|
|
||||||
|
$view = id(new PHUITwoColumnView())
|
||||||
|
->setHeader($header)
|
||||||
|
->setFooter(array(
|
||||||
|
$form_box,
|
||||||
|
));
|
||||||
|
|
||||||
return $this->newPage()
|
return $this->newPage()
|
||||||
->setTitle($title)
|
->setTitle($title)
|
||||||
->setCrumbs($crumbs)
|
->setCrumbs($crumbs)
|
||||||
->appendChild($form_box);
|
->appendChild($view);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,10 @@ final class DiffusionRepositorySymbolsController
|
||||||
$crumbs = $this->buildApplicationCrumbs();
|
$crumbs = $this->buildApplicationCrumbs();
|
||||||
$crumbs->addTextCrumb(pht('Edit Symbols'));
|
$crumbs->addTextCrumb(pht('Edit Symbols'));
|
||||||
|
|
||||||
$title = pht('Edit %s', $repository->getName());
|
$title = pht('Edit Symbols (%s)', $repository->getName());
|
||||||
|
$header = id(new PHUIHeaderView())
|
||||||
|
->setHeader($title)
|
||||||
|
->setHeaderIcon('fa-pencil');
|
||||||
|
|
||||||
$form = id(new AphrontFormView())
|
$form = id(new AphrontFormView())
|
||||||
->setUser($viewer)
|
->setUser($viewer)
|
||||||
|
@ -85,15 +88,22 @@ final class DiffusionRepositorySymbolsController
|
||||||
->setValue(pht('Save'))
|
->setValue(pht('Save'))
|
||||||
->addCancelButton($edit_uri));
|
->addCancelButton($edit_uri));
|
||||||
|
|
||||||
$object_box = id(new PHUIObjectBoxView())
|
$form_box = id(new PHUIObjectBoxView())
|
||||||
->setHeaderText($title)
|
->setHeaderText(pht('Symbols'))
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->setForm($form)
|
->setForm($form)
|
||||||
->setFormErrors($errors);
|
->setFormErrors($errors);
|
||||||
|
|
||||||
|
$view = id(new PHUITwoColumnView())
|
||||||
|
->setHeader($header)
|
||||||
|
->setFooter(array(
|
||||||
|
$form_box,
|
||||||
|
));
|
||||||
|
|
||||||
return $this->newPage()
|
return $this->newPage()
|
||||||
->setTitle($title)
|
->setTitle($title)
|
||||||
->setCrumbs($crumbs)
|
->setCrumbs($crumbs)
|
||||||
->appendChild($object_box);
|
->appendChild($view);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getInstructions() {
|
private function getInstructions() {
|
||||||
|
|
|
@ -5,7 +5,12 @@ final class DiffusionServeController extends DiffusionController {
|
||||||
private $serviceViewer;
|
private $serviceViewer;
|
||||||
private $serviceRepository;
|
private $serviceRepository;
|
||||||
|
|
||||||
|
private $isGitLFSRequest;
|
||||||
|
private $gitLFSToken;
|
||||||
|
|
||||||
public function setServiceViewer(PhabricatorUser $viewer) {
|
public function setServiceViewer(PhabricatorUser $viewer) {
|
||||||
|
$this->getRequest()->setUser($viewer);
|
||||||
|
|
||||||
$this->serviceViewer = $viewer;
|
$this->serviceViewer = $viewer;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
@ -23,6 +28,14 @@ final class DiffusionServeController extends DiffusionController {
|
||||||
return $this->serviceRepository;
|
return $this->serviceRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getIsGitLFSRequest() {
|
||||||
|
return $this->isGitLFSRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getGitLFSToken() {
|
||||||
|
return $this->gitLFSToken;
|
||||||
|
}
|
||||||
|
|
||||||
public function isVCSRequest(AphrontRequest $request) {
|
public function isVCSRequest(AphrontRequest $request) {
|
||||||
$identifier = $this->getRepositoryIdentifierFromRequest($request);
|
$identifier = $this->getRepositoryIdentifierFromRequest($request);
|
||||||
if ($identifier === null) {
|
if ($identifier === null) {
|
||||||
|
@ -31,6 +44,10 @@ final class DiffusionServeController extends DiffusionController {
|
||||||
|
|
||||||
$content_type = $request->getHTTPHeader('Content-Type');
|
$content_type = $request->getHTTPHeader('Content-Type');
|
||||||
$user_agent = idx($_SERVER, 'HTTP_USER_AGENT');
|
$user_agent = idx($_SERVER, 'HTTP_USER_AGENT');
|
||||||
|
$request_type = $request->getHTTPHeader('X-Phabricator-Request-Type');
|
||||||
|
|
||||||
|
// This may have a "charset" suffix, so only match the prefix.
|
||||||
|
$lfs_pattern = '(^application/vnd\\.git-lfs\\+json(;|\z))';
|
||||||
|
|
||||||
$vcs = null;
|
$vcs = null;
|
||||||
if ($request->getExists('service')) {
|
if ($request->getExists('service')) {
|
||||||
|
@ -46,6 +63,14 @@ final class DiffusionServeController extends DiffusionController {
|
||||||
} else if ($content_type == 'application/x-git-receive-pack-request') {
|
} else if ($content_type == 'application/x-git-receive-pack-request') {
|
||||||
// We get this for `git-receive-pack`.
|
// We get this for `git-receive-pack`.
|
||||||
$vcs = PhabricatorRepositoryType::REPOSITORY_TYPE_GIT;
|
$vcs = PhabricatorRepositoryType::REPOSITORY_TYPE_GIT;
|
||||||
|
} else if (preg_match($lfs_pattern, $content_type)) {
|
||||||
|
// This is a Git LFS HTTP API request.
|
||||||
|
$vcs = PhabricatorRepositoryType::REPOSITORY_TYPE_GIT;
|
||||||
|
$this->isGitLFSRequest = true;
|
||||||
|
} else if ($request_type == 'git-lfs') {
|
||||||
|
// This is a Git LFS object content request.
|
||||||
|
$vcs = PhabricatorRepositoryType::REPOSITORY_TYPE_GIT;
|
||||||
|
$this->isGitLFSRequest = true;
|
||||||
} else if ($request->getExists('cmd')) {
|
} else if ($request->getExists('cmd')) {
|
||||||
// Mercurial also sends an Accept header like
|
// Mercurial also sends an Accept header like
|
||||||
// "application/mercurial-0.1", and a User-Agent like
|
// "application/mercurial-0.1", and a User-Agent like
|
||||||
|
@ -142,7 +167,17 @@ final class DiffusionServeController extends DiffusionController {
|
||||||
$username = $_SERVER['PHP_AUTH_USER'];
|
$username = $_SERVER['PHP_AUTH_USER'];
|
||||||
$password = new PhutilOpaqueEnvelope($_SERVER['PHP_AUTH_PW']);
|
$password = new PhutilOpaqueEnvelope($_SERVER['PHP_AUTH_PW']);
|
||||||
|
|
||||||
|
// Try Git LFS auth first since we can usually reject it without doing
|
||||||
|
// any queries, since the username won't match the one we expect or the
|
||||||
|
// request won't be LFS.
|
||||||
|
$viewer = $this->authenticateGitLFSUser($username, $password);
|
||||||
|
|
||||||
|
// If that failed, try normal auth. Note that we can use normal auth on
|
||||||
|
// LFS requests, so this isn't strictly an alternative to LFS auth.
|
||||||
|
if (!$viewer) {
|
||||||
$viewer = $this->authenticateHTTPRepositoryUser($username, $password);
|
$viewer = $this->authenticateHTTPRepositoryUser($username, $password);
|
||||||
|
}
|
||||||
|
|
||||||
if (!$viewer) {
|
if (!$viewer) {
|
||||||
return new PhabricatorVCSResponse(
|
return new PhabricatorVCSResponse(
|
||||||
403,
|
403,
|
||||||
|
@ -202,6 +237,11 @@ final class DiffusionServeController extends DiffusionController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$response = $this->validateGitLFSRequest($repository, $viewer);
|
||||||
|
if ($response) {
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
$this->setServiceRepository($repository);
|
$this->setServiceRepository($repository);
|
||||||
|
|
||||||
if (!$repository->isTracked()) {
|
if (!$repository->isTracked()) {
|
||||||
|
@ -212,6 +252,12 @@ final class DiffusionServeController extends DiffusionController {
|
||||||
|
|
||||||
$is_push = !$this->isReadOnlyRequest($repository);
|
$is_push = !$this->isReadOnlyRequest($repository);
|
||||||
|
|
||||||
|
if ($this->getIsGitLFSRequest() && $this->getGitLFSToken()) {
|
||||||
|
// We allow git LFS requests over HTTP even if the repository does not
|
||||||
|
// otherwise support HTTP reads or writes, as long as the user is using a
|
||||||
|
// token from SSH. If they're using HTTP username + password auth, they
|
||||||
|
// have to obey the normal HTTP rules.
|
||||||
|
} else {
|
||||||
switch ($repository->getServeOverHTTP()) {
|
switch ($repository->getServeOverHTTP()) {
|
||||||
case PhabricatorRepository::SERVE_READONLY:
|
case PhabricatorRepository::SERVE_READONLY:
|
||||||
if ($is_push) {
|
if ($is_push) {
|
||||||
|
@ -221,6 +267,16 @@ final class DiffusionServeController extends DiffusionController {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PhabricatorRepository::SERVE_READWRITE:
|
case PhabricatorRepository::SERVE_READWRITE:
|
||||||
|
// We'll check for push capability below.
|
||||||
|
break;
|
||||||
|
case PhabricatorRepository::SERVE_OFF:
|
||||||
|
default:
|
||||||
|
return new PhabricatorVCSResponse(
|
||||||
|
403,
|
||||||
|
pht('This repository is not available over HTTP.'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ($is_push) {
|
if ($is_push) {
|
||||||
$can_push = PhabricatorPolicyFilter::hasCapability(
|
$can_push = PhabricatorPolicyFilter::hasCapability(
|
||||||
$viewer,
|
$viewer,
|
||||||
|
@ -230,7 +286,9 @@ final class DiffusionServeController extends DiffusionController {
|
||||||
if ($viewer->isLoggedIn()) {
|
if ($viewer->isLoggedIn()) {
|
||||||
return new PhabricatorVCSResponse(
|
return new PhabricatorVCSResponse(
|
||||||
403,
|
403,
|
||||||
pht('You do not have permission to push to this repository.'));
|
pht(
|
||||||
|
'You do not have permission to push to this '.
|
||||||
|
'repository.'));
|
||||||
} else {
|
} else {
|
||||||
if ($allow_auth) {
|
if ($allow_auth) {
|
||||||
return new PhabricatorVCSResponse(
|
return new PhabricatorVCSResponse(
|
||||||
|
@ -246,13 +304,6 @@ final class DiffusionServeController extends DiffusionController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case PhabricatorRepository::SERVE_OFF:
|
|
||||||
default:
|
|
||||||
return new PhabricatorVCSResponse(
|
|
||||||
403,
|
|
||||||
pht('This repository is not available over HTTP.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$vcs_type = $repository->getVersionControlSystem();
|
$vcs_type = $repository->getVersionControlSystem();
|
||||||
$req_type = $this->isVCSRequest($request);
|
$req_type = $this->isVCSRequest($request);
|
||||||
|
@ -324,6 +375,14 @@ final class DiffusionServeController extends DiffusionController {
|
||||||
PhabricatorRepository $repository,
|
PhabricatorRepository $repository,
|
||||||
PhabricatorUser $viewer) {
|
PhabricatorUser $viewer) {
|
||||||
|
|
||||||
|
// We can serve Git LFS requests first, since we don't need to proxy them.
|
||||||
|
// It's also important that LFS requests never fall through to standard
|
||||||
|
// service pathways, because that would let you use LFS tokens to read
|
||||||
|
// normal repository data.
|
||||||
|
if ($this->getIsGitLFSRequest()) {
|
||||||
|
return $this->serveGitLFSRequest($repository, $viewer);
|
||||||
|
}
|
||||||
|
|
||||||
// If this repository is hosted on a service, we need to proxy the request
|
// If this repository is hosted on a service, we need to proxy the request
|
||||||
// to a host which can serve it.
|
// to a host which can serve it.
|
||||||
$is_cluster_request = $this->getRequest()->isProxiedClusterRequest();
|
$is_cluster_request = $this->getRequest()->isProxiedClusterRequest();
|
||||||
|
@ -363,6 +422,8 @@ final class DiffusionServeController extends DiffusionController {
|
||||||
|
|
||||||
// TODO: This implementation is safe by default, but very incomplete.
|
// TODO: This implementation is safe by default, but very incomplete.
|
||||||
|
|
||||||
|
// TODO: This doesn't get the right result for Git LFS yet.
|
||||||
|
|
||||||
switch ($repository->getVersionControlSystem()) {
|
switch ($repository->getVersionControlSystem()) {
|
||||||
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
|
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
|
||||||
$service = $request->getStr('service');
|
$service = $request->getStr('service');
|
||||||
|
@ -514,6 +575,52 @@ final class DiffusionServeController extends DiffusionController {
|
||||||
return $base_path;
|
return $base_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function authenticateGitLFSUser(
|
||||||
|
$username,
|
||||||
|
PhutilOpaqueEnvelope $password) {
|
||||||
|
|
||||||
|
// Never accept these credentials for requests which aren't LFS requests.
|
||||||
|
if (!$this->getIsGitLFSRequest()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have the wrong username, don't bother checking if the token
|
||||||
|
// is right.
|
||||||
|
if ($username !== DiffusionGitLFSTemporaryTokenType::HTTP_USERNAME) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$lfs_pass = $password->openEnvelope();
|
||||||
|
$lfs_hash = PhabricatorHash::digest($lfs_pass);
|
||||||
|
|
||||||
|
$token = id(new PhabricatorAuthTemporaryTokenQuery())
|
||||||
|
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||||
|
->withTokenTypes(array(DiffusionGitLFSTemporaryTokenType::TOKENTYPE))
|
||||||
|
->withTokenCodes(array($lfs_hash))
|
||||||
|
->withExpired(false)
|
||||||
|
->executeOne();
|
||||||
|
if (!$token) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = id(new PhabricatorPeopleQuery())
|
||||||
|
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||||
|
->withPHIDs(array($token->getUserPHID()))
|
||||||
|
->executeOne();
|
||||||
|
|
||||||
|
if (!$user) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$user->isUserActivated()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->gitLFSToken = $token;
|
||||||
|
|
||||||
|
return $user;
|
||||||
|
}
|
||||||
|
|
||||||
private function authenticateHTTPRepositoryUser(
|
private function authenticateHTTPRepositoryUser(
|
||||||
$username,
|
$username,
|
||||||
PhutilOpaqueEnvelope $password) {
|
PhutilOpaqueEnvelope $password) {
|
||||||
|
@ -739,4 +846,291 @@ final class DiffusionServeController extends DiffusionController {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function validateGitLFSRequest(
|
||||||
|
PhabricatorRepository $repository,
|
||||||
|
PhabricatorUser $viewer) {
|
||||||
|
if (!$this->getIsGitLFSRequest()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$repository->canUseGitLFS()) {
|
||||||
|
return new PhabricatorVCSResponse(
|
||||||
|
403,
|
||||||
|
pht(
|
||||||
|
'The requested repository ("%s") does not support Git LFS.',
|
||||||
|
$repository->getDisplayName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this is using an LFS token, sanity check that we're using it on the
|
||||||
|
// correct repository. This shouldn't really matter since the user could
|
||||||
|
// just request a proper token anyway, but it suspicious and should not
|
||||||
|
// be permitted.
|
||||||
|
|
||||||
|
$token = $this->getGitLFSToken();
|
||||||
|
if ($token) {
|
||||||
|
$resource = $token->getTokenResource();
|
||||||
|
if ($resource !== $repository->getPHID()) {
|
||||||
|
return new PhabricatorVCSResponse(
|
||||||
|
403,
|
||||||
|
pht(
|
||||||
|
'The authentication token provided in the request is bound to '.
|
||||||
|
'a different repository than the requested repository ("%s").',
|
||||||
|
$repository->getDisplayName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function serveGitLFSRequest(
|
||||||
|
PhabricatorRepository $repository,
|
||||||
|
PhabricatorUser $viewer) {
|
||||||
|
|
||||||
|
if (!$this->getIsGitLFSRequest()) {
|
||||||
|
throw new Exception(pht('This is not a Git LFS request!'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$path = $this->getGitLFSRequestPath($repository);
|
||||||
|
$matches = null;
|
||||||
|
|
||||||
|
if (preg_match('(^upload/(.*)\z)', $path, $matches)) {
|
||||||
|
$oid = $matches[1];
|
||||||
|
return $this->serveGitLFSUploadRequest($repository, $viewer, $oid);
|
||||||
|
} else if ($path == 'objects/batch') {
|
||||||
|
return $this->serveGitLFSBatchRequest($repository, $viewer);
|
||||||
|
} else {
|
||||||
|
return DiffusionGitLFSResponse::newErrorResponse(
|
||||||
|
404,
|
||||||
|
pht(
|
||||||
|
'Git LFS operation "%s" is not supported by this server.',
|
||||||
|
$path));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function serveGitLFSBatchRequest(
|
||||||
|
PhabricatorRepository $repository,
|
||||||
|
PhabricatorUser $viewer) {
|
||||||
|
|
||||||
|
$input = PhabricatorStartup::getRawInput();
|
||||||
|
$input = phutil_json_decode($input);
|
||||||
|
|
||||||
|
$operation = idx($input, 'operation');
|
||||||
|
switch ($operation) {
|
||||||
|
case 'upload':
|
||||||
|
$want_upload = true;
|
||||||
|
break;
|
||||||
|
case 'download':
|
||||||
|
$want_upload = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return DiffusionGitLFSResponse::newErrorResponse(
|
||||||
|
404,
|
||||||
|
pht(
|
||||||
|
'Git LFS batch operation "%s" is not supported by this server.',
|
||||||
|
$operation));
|
||||||
|
}
|
||||||
|
|
||||||
|
$objects = idx($input, 'objects', array());
|
||||||
|
|
||||||
|
$hashes = array();
|
||||||
|
foreach ($objects as $object) {
|
||||||
|
$hashes[] = idx($object, 'oid');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($hashes) {
|
||||||
|
$refs = id(new PhabricatorRepositoryGitLFSRefQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withRepositoryPHIDs(array($repository->getPHID()))
|
||||||
|
->withObjectHashes($hashes)
|
||||||
|
->execute();
|
||||||
|
$refs = mpull($refs, null, 'getObjectHash');
|
||||||
|
} else {
|
||||||
|
$refs = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$file_phids = mpull($refs, 'getFilePHID');
|
||||||
|
if ($file_phids) {
|
||||||
|
$files = id(new PhabricatorFileQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withPHIDs($file_phids)
|
||||||
|
->execute();
|
||||||
|
$files = mpull($files, null, 'getPHID');
|
||||||
|
} else {
|
||||||
|
$files = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$authorization = null;
|
||||||
|
$output = array();
|
||||||
|
foreach ($objects as $object) {
|
||||||
|
$oid = idx($object, 'oid');
|
||||||
|
$size = idx($object, 'size');
|
||||||
|
$ref = idx($refs, $oid);
|
||||||
|
$error = null;
|
||||||
|
|
||||||
|
// NOTE: If we already have a ref for this object, we only emit a
|
||||||
|
// "download" action. The client should not upload the file again.
|
||||||
|
|
||||||
|
$actions = array();
|
||||||
|
if ($ref) {
|
||||||
|
$file = idx($files, $ref->getFilePHID());
|
||||||
|
if ($file) {
|
||||||
|
// Git LFS may prompt users for authentication if the action does
|
||||||
|
// not provide an "Authorization" header and does not have a query
|
||||||
|
// parameter named "token". See here for discussion:
|
||||||
|
// <https://github.com/github/git-lfs/issues/1088>
|
||||||
|
$no_authorization = 'Basic '.base64_encode('none');
|
||||||
|
|
||||||
|
$get_uri = $file->getCDNURIWithToken();
|
||||||
|
$actions['download'] = array(
|
||||||
|
'href' => $get_uri,
|
||||||
|
'header' => array(
|
||||||
|
'Authorization' => $no_authorization,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$error = array(
|
||||||
|
'code' => 404,
|
||||||
|
'message' => pht(
|
||||||
|
'Object "%s" was previously uploaded, but no longer exists '.
|
||||||
|
'on this server.',
|
||||||
|
$oid),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else if ($want_upload) {
|
||||||
|
if (!$authorization) {
|
||||||
|
// Here, we could reuse the existing authorization if we have one,
|
||||||
|
// but it's a little simpler to just generate a new one
|
||||||
|
// unconditionally.
|
||||||
|
$authorization = $this->newGitLFSHTTPAuthorization(
|
||||||
|
$repository,
|
||||||
|
$viewer,
|
||||||
|
$operation);
|
||||||
|
}
|
||||||
|
|
||||||
|
$put_uri = $repository->getGitLFSURI("info/lfs/upload/{$oid}");
|
||||||
|
|
||||||
|
$actions['upload'] = array(
|
||||||
|
'href' => $put_uri,
|
||||||
|
'header' => array(
|
||||||
|
'Authorization' => $authorization,
|
||||||
|
'X-Phabricator-Request-Type' => 'git-lfs',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$object = array(
|
||||||
|
'oid' => $oid,
|
||||||
|
'size' => $size,
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($actions) {
|
||||||
|
$object['actions'] = $actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($error) {
|
||||||
|
$object['error'] = $error;
|
||||||
|
}
|
||||||
|
|
||||||
|
$output[] = $object;
|
||||||
|
}
|
||||||
|
|
||||||
|
$output = array(
|
||||||
|
'objects' => $output,
|
||||||
|
);
|
||||||
|
|
||||||
|
return id(new DiffusionGitLFSResponse())
|
||||||
|
->setContent($output);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function serveGitLFSUploadRequest(
|
||||||
|
PhabricatorRepository $repository,
|
||||||
|
PhabricatorUser $viewer,
|
||||||
|
$oid) {
|
||||||
|
|
||||||
|
$ref = id(new PhabricatorRepositoryGitLFSRefQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withRepositoryPHIDs(array($repository->getPHID()))
|
||||||
|
->withObjectHashes(array($oid))
|
||||||
|
->executeOne();
|
||||||
|
if ($ref) {
|
||||||
|
return DiffusionGitLFSResponse::newErrorResponse(
|
||||||
|
405,
|
||||||
|
pht(
|
||||||
|
'Content for object "%s" is already known to this server. It can '.
|
||||||
|
'not be uploaded again.',
|
||||||
|
$oid));
|
||||||
|
}
|
||||||
|
|
||||||
|
$request_stream = new AphrontRequestStream();
|
||||||
|
$request_iterator = $request_stream->getIterator();
|
||||||
|
$hashing_iterator = id(new PhutilHashingIterator($request_iterator))
|
||||||
|
->setAlgorithm('sha256');
|
||||||
|
|
||||||
|
$source = id(new PhabricatorIteratorFileUploadSource())
|
||||||
|
->setName('lfs-'.$oid)
|
||||||
|
->setViewPolicy(PhabricatorPolicies::POLICY_NOONE)
|
||||||
|
->setIterator($hashing_iterator);
|
||||||
|
|
||||||
|
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
||||||
|
$file = $source->uploadFile();
|
||||||
|
unset($unguarded);
|
||||||
|
|
||||||
|
$hash = $hashing_iterator->getHash();
|
||||||
|
if ($hash !== $oid) {
|
||||||
|
return DiffusionGitLFSResponse::newErrorResponse(
|
||||||
|
400,
|
||||||
|
pht(
|
||||||
|
'Uploaded data is corrupt or invalid. Expected hash "%s", actual '.
|
||||||
|
'hash "%s".',
|
||||||
|
$oid,
|
||||||
|
$hash));
|
||||||
|
}
|
||||||
|
|
||||||
|
$ref = id(new PhabricatorRepositoryGitLFSRef())
|
||||||
|
->setRepositoryPHID($repository->getPHID())
|
||||||
|
->setObjectHash($hash)
|
||||||
|
->setByteSize($file->getByteSize())
|
||||||
|
->setAuthorPHID($viewer->getPHID())
|
||||||
|
->setFilePHID($file->getPHID());
|
||||||
|
|
||||||
|
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
||||||
|
// Attach the file to the repository to give users permission
|
||||||
|
// to access it.
|
||||||
|
$file->attachToObject($repository->getPHID());
|
||||||
|
$ref->save();
|
||||||
|
unset($unguarded);
|
||||||
|
|
||||||
|
// This is just a plain HTTP 200 with no content, which is what `git lfs`
|
||||||
|
// expects.
|
||||||
|
return new DiffusionGitLFSResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function newGitLFSHTTPAuthorization(
|
||||||
|
PhabricatorRepository $repository,
|
||||||
|
PhabricatorUser $viewer,
|
||||||
|
$operation) {
|
||||||
|
|
||||||
|
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
||||||
|
|
||||||
|
$authorization = DiffusionGitLFSTemporaryTokenType::newHTTPAuthorization(
|
||||||
|
$repository,
|
||||||
|
$viewer,
|
||||||
|
$operation);
|
||||||
|
|
||||||
|
unset($unguarded);
|
||||||
|
|
||||||
|
return $authorization;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getGitLFSRequestPath(PhabricatorRepository $repository) {
|
||||||
|
$request_path = $this->getRequestDirectoryPath($repository);
|
||||||
|
|
||||||
|
$matches = null;
|
||||||
|
if (preg_match('(^/info/lfs(?:\z|/)(.*))', $request_path, $matches)) {
|
||||||
|
return $matches[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,17 +134,24 @@ final class DiffusionSymbolController extends DiffusionController {
|
||||||
$table->setNoDataString(
|
$table->setNoDataString(
|
||||||
pht('No matching symbol could be found in any indexed repository.'));
|
pht('No matching symbol could be found in any indexed repository.'));
|
||||||
|
|
||||||
$panel = id(new PHUIObjectBoxView())
|
$header = id(new PHUIHeaderView())
|
||||||
->setHeaderText(pht('Similar Symbols'))
|
->setHeader(pht('Similar Symbols'))
|
||||||
->setTable($table);
|
->setHeaderIcon('fa-bullseye');
|
||||||
|
|
||||||
$crumbs = $this->buildApplicationCrumbs();
|
$crumbs = $this->buildApplicationCrumbs();
|
||||||
$crumbs->addTextCrumb(pht('Find Symbol'));
|
$crumbs->addTextCrumb(pht('Find Symbol'));
|
||||||
|
$crumbs->setBorder(true);
|
||||||
|
|
||||||
|
$view = id(new PHUITwoColumnView())
|
||||||
|
->setHeader($header)
|
||||||
|
->setFooter(array(
|
||||||
|
$table,
|
||||||
|
));
|
||||||
|
|
||||||
return $this->newPage()
|
return $this->newPage()
|
||||||
->setTitle(pht('Find Symbol'))
|
->setTitle(pht('Find Symbol'))
|
||||||
->setCrumbs($crumbs)
|
->setCrumbs($crumbs)
|
||||||
->appendChild($panel);
|
->appendChild($view);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,11 @@ final class DiffusionTagListController extends DiffusionController {
|
||||||
$tags = $pager->sliceResults($tags);
|
$tags = $pager->sliceResults($tags);
|
||||||
|
|
||||||
$content = null;
|
$content = null;
|
||||||
|
|
||||||
|
$header = id(new PHUIHeaderView())
|
||||||
|
->setHeader(pht('Tags'))
|
||||||
|
->setHeaderIcon('fa-tags');
|
||||||
|
|
||||||
if (!$tags) {
|
if (!$tags) {
|
||||||
$content = $this->renderStatusMessage(
|
$content = $this->renderStatusMessage(
|
||||||
pht('No Tags'),
|
pht('No Tags'),
|
||||||
|
@ -69,11 +74,7 @@ final class DiffusionTagListController extends DiffusionController {
|
||||||
$handles = $this->loadViewerHandles($phids);
|
$handles = $this->loadViewerHandles($phids);
|
||||||
$view->setHandles($handles);
|
$view->setHandles($handles);
|
||||||
|
|
||||||
$panel = id(new PHUIObjectBoxView())
|
$content = $view;
|
||||||
->setHeaderText(pht('Tags'))
|
|
||||||
->appendChild($view);
|
|
||||||
|
|
||||||
$content = $panel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$crumbs = $this->buildCrumbs(
|
$crumbs = $this->buildCrumbs(
|
||||||
|
@ -81,9 +82,22 @@ final class DiffusionTagListController extends DiffusionController {
|
||||||
'tags' => true,
|
'tags' => true,
|
||||||
'commit' => $drequest->getSymbolicCommit(),
|
'commit' => $drequest->getSymbolicCommit(),
|
||||||
));
|
));
|
||||||
|
$crumbs->setBorder(true);
|
||||||
|
|
||||||
|
$box = id(new PHUIObjectBoxView())
|
||||||
|
->setHeaderText($repository->getDisplayName())
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
|
->setTable($view);
|
||||||
|
|
||||||
$pager_box = $this->renderTablePagerBox($pager);
|
$pager_box = $this->renderTablePagerBox($pager);
|
||||||
|
|
||||||
|
$view = id(new PHUITwoColumnView())
|
||||||
|
->setHeader($header)
|
||||||
|
->setFooter(array(
|
||||||
|
$box,
|
||||||
|
$pager_box,
|
||||||
|
));
|
||||||
|
|
||||||
return $this->newPage()
|
return $this->newPage()
|
||||||
->setTitle(
|
->setTitle(
|
||||||
array(
|
array(
|
||||||
|
@ -91,11 +105,7 @@ final class DiffusionTagListController extends DiffusionController {
|
||||||
$repository->getDisplayName(),
|
$repository->getDisplayName(),
|
||||||
))
|
))
|
||||||
->setCrumbs($crumbs)
|
->setCrumbs($crumbs)
|
||||||
->appendChild(
|
->appendChild($view);
|
||||||
array(
|
|
||||||
$content,
|
|
||||||
$pager_box,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class DiffusionGitLFSAuthenticateWorkflow
|
||||||
|
extends DiffusionGitSSHWorkflow {
|
||||||
|
|
||||||
|
protected function didConstruct() {
|
||||||
|
$this->setName('git-lfs-authenticate');
|
||||||
|
$this->setArguments(
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
'name' => 'argv',
|
||||||
|
'wildcard' => true,
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function identifyRepository() {
|
||||||
|
return $this->loadRepositoryWithPath($this->getLFSPathArgument());
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getLFSPathArgument() {
|
||||||
|
return $this->getLFSArgument(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getLFSOperationArgument() {
|
||||||
|
return $this->getLFSArgument(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getLFSArgument($position) {
|
||||||
|
$args = $this->getArgs();
|
||||||
|
$argv = $args->getArg('argv');
|
||||||
|
|
||||||
|
if (!isset($argv[$position])) {
|
||||||
|
throw new Exception(
|
||||||
|
pht(
|
||||||
|
'Expected `git-lfs-authenticate <path> <operation>`, but received '.
|
||||||
|
'too few arguments.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $argv[$position];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function executeRepositoryOperations() {
|
||||||
|
$operation = $this->getLFSOperationArgument();
|
||||||
|
|
||||||
|
// NOTE: We aren't checking write access here, even for "upload". The
|
||||||
|
// HTTP endpoint should be able to do that for us.
|
||||||
|
|
||||||
|
switch ($operation) {
|
||||||
|
case 'upload':
|
||||||
|
case 'download':
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception(
|
||||||
|
pht(
|
||||||
|
'Git LFS operation "%s" is not supported by this server.',
|
||||||
|
$operation));
|
||||||
|
}
|
||||||
|
|
||||||
|
$repository = $this->getRepository();
|
||||||
|
|
||||||
|
if (!$repository->isGit()) {
|
||||||
|
throw new Exception(
|
||||||
|
pht(
|
||||||
|
'Repository "%s" is not a Git repository. Git LFS is only '.
|
||||||
|
'supported for Git repositories.',
|
||||||
|
$repository->getDisplayName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$repository->canUseGitLFS()) {
|
||||||
|
throw new Exception(
|
||||||
|
pht('Git LFS is not enabled for this repository.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: This is usually the same as the default URI (which does not
|
||||||
|
// need to be specified in the response), but the protocol or domain may
|
||||||
|
// differ in some situations.
|
||||||
|
|
||||||
|
$lfs_uri = $repository->getGitLFSURI('info/lfs');
|
||||||
|
|
||||||
|
// Generate a temporary token to allow the user to acces LFS over HTTP.
|
||||||
|
// This works even if normal HTTP repository operations are not available
|
||||||
|
// on this host, and does not require the user to have a VCS password.
|
||||||
|
|
||||||
|
$user = $this->getUser();
|
||||||
|
|
||||||
|
$authorization = DiffusionGitLFSTemporaryTokenType::newHTTPAuthorization(
|
||||||
|
$repository,
|
||||||
|
$user,
|
||||||
|
$operation);
|
||||||
|
|
||||||
|
$headers = array(
|
||||||
|
'authorization' => $authorization,
|
||||||
|
);
|
||||||
|
|
||||||
|
$result = array(
|
||||||
|
'header' => $headers,
|
||||||
|
'href' => $lfs_uri,
|
||||||
|
);
|
||||||
|
$result = phutil_json_encode($result);
|
||||||
|
|
||||||
|
$this->writeIO($result);
|
||||||
|
$this->waitForGitClient();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class DiffusionGitLFSTemporaryTokenType
|
||||||
|
extends PhabricatorAuthTemporaryTokenType {
|
||||||
|
|
||||||
|
const TOKENTYPE = 'diffusion.git.lfs';
|
||||||
|
const HTTP_USERNAME = '@git-lfs';
|
||||||
|
|
||||||
|
public function getTokenTypeDisplayName() {
|
||||||
|
return pht('Git Large File Storage');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTokenReadableTypeName(
|
||||||
|
PhabricatorAuthTemporaryToken $token) {
|
||||||
|
return pht('Git LFS Token');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function newHTTPAuthorization(
|
||||||
|
PhabricatorRepository $repository,
|
||||||
|
PhabricatorUser $viewer,
|
||||||
|
$operation) {
|
||||||
|
|
||||||
|
$lfs_user = self::HTTP_USERNAME;
|
||||||
|
$lfs_pass = Filesystem::readRandomCharacters(32);
|
||||||
|
$lfs_hash = PhabricatorHash::digest($lfs_pass);
|
||||||
|
|
||||||
|
$ttl = PhabricatorTime::getNow() + phutil_units('1 day in seconds');
|
||||||
|
|
||||||
|
$token = id(new PhabricatorAuthTemporaryToken())
|
||||||
|
->setTokenResource($repository->getPHID())
|
||||||
|
->setTokenType(self::TOKENTYPE)
|
||||||
|
->setTokenCode($lfs_hash)
|
||||||
|
->setUserPHID($viewer->getPHID())
|
||||||
|
->setTemporaryTokenProperty('lfs.operation', $operation)
|
||||||
|
->setTokenExpires($ttl)
|
||||||
|
->save();
|
||||||
|
|
||||||
|
$authorization_header = base64_encode($lfs_user.':'.$lfs_pass);
|
||||||
|
return 'Basic '.$authorization_header;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class DiffusionGitLFSResponse extends AphrontResponse {
|
||||||
|
|
||||||
|
private $content;
|
||||||
|
|
||||||
|
public static function newErrorResponse($code, $message) {
|
||||||
|
|
||||||
|
// We can optionally include "request_id" and "documentation_url" in
|
||||||
|
// this response.
|
||||||
|
|
||||||
|
return id(new self())
|
||||||
|
->setHTTPResponseCode($code)
|
||||||
|
->setContent(
|
||||||
|
array(
|
||||||
|
'message' => $message,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setContent(array $content) {
|
||||||
|
$this->content = phutil_json_encode($content);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildResponseString() {
|
||||||
|
return $this->content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHeaders() {
|
||||||
|
$headers = array(
|
||||||
|
array('Content-Type', 'application/vnd.git-lfs+json'),
|
||||||
|
);
|
||||||
|
|
||||||
|
return array_merge(parent::getHeaders(), $headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -39,7 +39,7 @@ final class DiffusionBranchTableView extends DiffusionView {
|
||||||
$commit = idx($commits, $branch->getCommitIdentifier());
|
$commit = idx($commits, $branch->getCommitIdentifier());
|
||||||
if ($commit) {
|
if ($commit) {
|
||||||
$details = $commit->getSummary();
|
$details = $commit->getSummary();
|
||||||
$datetime = phabricator_datetime($commit->getEpoch(), $viewer);
|
$datetime = $viewer->formatShortDateTime($commit->getEpoch());
|
||||||
$buildable = idx($buildables, $commit->getPHID());
|
$buildable = idx($buildables, $commit->getPHID());
|
||||||
if ($buildable) {
|
if ($buildable) {
|
||||||
$build_status = $this->renderBuildable($buildable);
|
$build_status = $this->renderBuildable($buildable);
|
||||||
|
@ -147,7 +147,7 @@ final class DiffusionBranchTableView extends DiffusionView {
|
||||||
'',
|
'',
|
||||||
'wide',
|
'wide',
|
||||||
'',
|
'',
|
||||||
'',
|
'right',
|
||||||
));
|
));
|
||||||
$view->setColumnVisibility(
|
$view->setColumnVisibility(
|
||||||
array(
|
array(
|
||||||
|
|
|
@ -90,7 +90,6 @@ final class DiffusionBrowseTableView extends DiffusionView {
|
||||||
$browse_link,
|
$browse_link,
|
||||||
idx($dict, 'lint'),
|
idx($dict, 'lint'),
|
||||||
$dict['commit'],
|
$dict['commit'],
|
||||||
$dict['author'],
|
|
||||||
$dict['details'],
|
$dict['details'],
|
||||||
$dict['date'],
|
$dict['date'],
|
||||||
);
|
);
|
||||||
|
@ -120,7 +119,6 @@ final class DiffusionBrowseTableView extends DiffusionView {
|
||||||
pht('Path'),
|
pht('Path'),
|
||||||
($lint ? $lint : pht('Lint')),
|
($lint ? $lint : pht('Lint')),
|
||||||
pht('Modified'),
|
pht('Modified'),
|
||||||
pht('Author/Committer'),
|
|
||||||
pht('Details'),
|
pht('Details'),
|
||||||
pht('Committed'),
|
pht('Committed'),
|
||||||
));
|
));
|
||||||
|
@ -130,9 +128,8 @@ final class DiffusionBrowseTableView extends DiffusionView {
|
||||||
'',
|
'',
|
||||||
'',
|
'',
|
||||||
'',
|
'',
|
||||||
'',
|
|
||||||
'wide',
|
'wide',
|
||||||
'',
|
'right',
|
||||||
));
|
));
|
||||||
$view->setColumnVisibility(
|
$view->setColumnVisibility(
|
||||||
array(
|
array(
|
||||||
|
@ -142,7 +139,6 @@ final class DiffusionBrowseTableView extends DiffusionView {
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
true,
|
|
||||||
));
|
));
|
||||||
|
|
||||||
$view->setDeviceVisibility(
|
$view->setDeviceVisibility(
|
||||||
|
@ -150,7 +146,6 @@ final class DiffusionBrowseTableView extends DiffusionView {
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
true,
|
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
|
|
|
@ -95,7 +95,7 @@ final class DiffusionHistoryTableView extends DiffusionView {
|
||||||
$epoch = $history->getEpoch();
|
$epoch = $history->getEpoch();
|
||||||
|
|
||||||
if ($epoch) {
|
if ($epoch) {
|
||||||
$committed = phabricator_datetime($epoch, $viewer);
|
$committed = $viewer->formatShortDateTime($epoch);
|
||||||
} else {
|
} else {
|
||||||
$committed = null;
|
$committed = null;
|
||||||
}
|
}
|
||||||
|
@ -195,7 +195,7 @@ final class DiffusionHistoryTableView extends DiffusionView {
|
||||||
'',
|
'',
|
||||||
'',
|
'',
|
||||||
'wide',
|
'wide',
|
||||||
'',
|
'right',
|
||||||
));
|
));
|
||||||
$view->setColumnVisibility(
|
$view->setColumnVisibility(
|
||||||
array(
|
array(
|
||||||
|
|
|
@ -88,7 +88,7 @@ final class DiffusionPushLogListView extends AphrontView {
|
||||||
// TODO: Make these human-readable.
|
// TODO: Make these human-readable.
|
||||||
$log->getChangeFlags(),
|
$log->getChangeFlags(),
|
||||||
$log->getPushEvent()->getRejectCode(),
|
$log->getPushEvent()->getRejectCode(),
|
||||||
phabricator_datetime($log->getEpoch(), $viewer),
|
$viewer->formatShortDateTime($log->getEpoch()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ final class DiffusionPushLogListView extends AphrontView {
|
||||||
'wide',
|
'wide',
|
||||||
'n',
|
'n',
|
||||||
'n',
|
'n',
|
||||||
'date',
|
'right',
|
||||||
));
|
));
|
||||||
|
|
||||||
return $table;
|
return $table;
|
||||||
|
|
|
@ -28,6 +28,7 @@ final class DiffusionTagListView extends DiffusionView {
|
||||||
public function render() {
|
public function render() {
|
||||||
$drequest = $this->getDiffusionRequest();
|
$drequest = $this->getDiffusionRequest();
|
||||||
$repository = $drequest->getRepository();
|
$repository = $drequest->getRepository();
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$buildables = $this->loadBuildables($this->commits);
|
$buildables = $this->loadBuildables($this->commits);
|
||||||
$has_builds = false;
|
$has_builds = false;
|
||||||
|
@ -100,7 +101,7 @@ final class DiffusionTagListView extends DiffusionView {
|
||||||
$build,
|
$build,
|
||||||
$author,
|
$author,
|
||||||
$description,
|
$description,
|
||||||
phabricator_datetime($tag->getEpoch(), $this->getViewer()),
|
$viewer->formatShortDateTime($tag->getEpoch()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,6 +124,7 @@ final class DiffusionTagListView extends DiffusionView {
|
||||||
'',
|
'',
|
||||||
'',
|
'',
|
||||||
'wide',
|
'wide',
|
||||||
|
'right',
|
||||||
))
|
))
|
||||||
->setColumnVisibility(
|
->setColumnVisibility(
|
||||||
array(
|
array(
|
||||||
|
|
|
@ -95,7 +95,9 @@ abstract class DiffusionView extends AphrontView {
|
||||||
}
|
}
|
||||||
|
|
||||||
$icon = DifferentialChangeType::getIconForFileType($file_type);
|
$icon = DifferentialChangeType::getIconForFileType($file_type);
|
||||||
$icon_view = id(new PHUIIconView())->setIcon($icon);
|
$color = DifferentialChangeType::getIconColorForFileType($file_type);
|
||||||
|
$icon_view = id(new PHUIIconView())
|
||||||
|
->setIcon($icon.' '.$color);
|
||||||
|
|
||||||
// If we're rendering a file or directory name, don't show the tooltip.
|
// If we're rendering a file or directory name, don't show the tooltip.
|
||||||
if ($display_name !== null) {
|
if ($display_name !== null) {
|
||||||
|
|
|
@ -26,16 +26,14 @@ final class DrydockAuthorizationViewController
|
||||||
->setUser($viewer)
|
->setUser($viewer)
|
||||||
->setPolicyObject($authorization);
|
->setPolicyObject($authorization);
|
||||||
|
|
||||||
|
|
||||||
$state = $authorization->getBlueprintAuthorizationState();
|
$state = $authorization->getBlueprintAuthorizationState();
|
||||||
$icon = DrydockAuthorization::getBlueprintStateIcon($state);
|
$icon = DrydockAuthorization::getBlueprintStateIcon($state);
|
||||||
$name = DrydockAuthorization::getBlueprintStateName($state);
|
$name = DrydockAuthorization::getBlueprintStateName($state);
|
||||||
|
|
||||||
$header->setStatus($icon, null, $name);
|
$header->setStatus($icon, null, $name);
|
||||||
|
|
||||||
$actions = $this->buildActionListView($authorization);
|
$curtain = $this->buildCurtain($authorization);
|
||||||
$properties = $this->buildPropertyListView($authorization);
|
$properties = $this->buildPropertyListView($authorization);
|
||||||
$properties->setActionList($actions);
|
|
||||||
|
|
||||||
$crumbs = $this->buildApplicationCrumbs();
|
$crumbs = $this->buildApplicationCrumbs();
|
||||||
$crumbs->addTextCrumb(
|
$crumbs->addTextCrumb(
|
||||||
|
@ -45,29 +43,32 @@ final class DrydockAuthorizationViewController
|
||||||
$blueprint->getBlueprintName(),
|
$blueprint->getBlueprintName(),
|
||||||
$this->getApplicationURI("blueprint/{$blueprint_id}/"));
|
$this->getApplicationURI("blueprint/{$blueprint_id}/"));
|
||||||
$crumbs->addTextCrumb($title);
|
$crumbs->addTextCrumb($title);
|
||||||
|
$crumbs->setBorder(true);
|
||||||
|
|
||||||
$object_box = id(new PHUIObjectBoxView())
|
$object_box = id(new PHUIObjectBoxView())
|
||||||
->setHeader($header)
|
->setHeader($header)
|
||||||
->addPropertyList($properties);
|
->addPropertyList($properties);
|
||||||
|
|
||||||
return $this->buildApplicationPage(
|
$view = id(new PHUITwoColumnView())
|
||||||
|
->setHeader($header)
|
||||||
|
->setCurtain($curtain)
|
||||||
|
->addPropertySection(pht('Properties'), $properties);
|
||||||
|
|
||||||
|
return $this->newPage()
|
||||||
|
->setTitle($title)
|
||||||
|
->setCrumbs($crumbs)
|
||||||
|
->appendChild(
|
||||||
array(
|
array(
|
||||||
$crumbs,
|
$view,
|
||||||
$object_box,
|
|
||||||
),
|
|
||||||
array(
|
|
||||||
'title' => $title,
|
|
||||||
));
|
));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildActionListView(DrydockAuthorization $authorization) {
|
private function buildCurtain(DrydockAuthorization $authorization) {
|
||||||
$viewer = $this->getViewer();
|
$viewer = $this->getViewer();
|
||||||
$id = $authorization->getID();
|
$id = $authorization->getID();
|
||||||
|
|
||||||
$view = id(new PhabricatorActionListView())
|
$curtain = $this->newCurtainView($authorization);
|
||||||
->setUser($viewer)
|
|
||||||
->setObject($authorization);
|
|
||||||
|
|
||||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||||
$viewer,
|
$viewer,
|
||||||
|
@ -84,7 +85,7 @@ final class DrydockAuthorizationViewController
|
||||||
$can_authorize = $can_edit && ($state != $state_authorized);
|
$can_authorize = $can_edit && ($state != $state_authorized);
|
||||||
$can_decline = $can_edit && ($state != $state_declined);
|
$can_decline = $can_edit && ($state != $state_declined);
|
||||||
|
|
||||||
$view->addAction(
|
$curtain->addAction(
|
||||||
id(new PhabricatorActionView())
|
id(new PhabricatorActionView())
|
||||||
->setHref($authorize_uri)
|
->setHref($authorize_uri)
|
||||||
->setName(pht('Approve Authorization'))
|
->setName(pht('Approve Authorization'))
|
||||||
|
@ -92,7 +93,7 @@ final class DrydockAuthorizationViewController
|
||||||
->setWorkflow(true)
|
->setWorkflow(true)
|
||||||
->setDisabled(!$can_authorize));
|
->setDisabled(!$can_authorize));
|
||||||
|
|
||||||
$view->addAction(
|
$curtain->addAction(
|
||||||
id(new PhabricatorActionView())
|
id(new PhabricatorActionView())
|
||||||
->setHref($decline_uri)
|
->setHref($decline_uri)
|
||||||
->setName(pht('Decline Authorization'))
|
->setName(pht('Decline Authorization'))
|
||||||
|
@ -100,7 +101,7 @@ final class DrydockAuthorizationViewController
|
||||||
->setWorkflow(true)
|
->setWorkflow(true)
|
||||||
->setDisabled(!$can_decline));
|
->setDisabled(!$can_decline));
|
||||||
|
|
||||||
return $view;
|
return $curtain;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildPropertyListView(DrydockAuthorization $authorization) {
|
private function buildPropertyListView(DrydockAuthorization $authorization) {
|
||||||
|
|
|
@ -19,7 +19,8 @@ final class DrydockBlueprintViewController extends DrydockBlueprintController {
|
||||||
$header = id(new PHUIHeaderView())
|
$header = id(new PHUIHeaderView())
|
||||||
->setHeader($title)
|
->setHeader($title)
|
||||||
->setUser($viewer)
|
->setUser($viewer)
|
||||||
->setPolicyObject($blueprint);
|
->setPolicyObject($blueprint)
|
||||||
|
->setHeaderIcon('fa-map-o');
|
||||||
|
|
||||||
if ($blueprint->getIsDisabled()) {
|
if ($blueprint->getIsDisabled()) {
|
||||||
$header->setStatus('fa-ban', 'red', pht('Disabled'));
|
$header->setStatus('fa-ban', 'red', pht('Disabled'));
|
||||||
|
@ -27,15 +28,12 @@ final class DrydockBlueprintViewController extends DrydockBlueprintController {
|
||||||
$header->setStatus('fa-check', 'bluegrey', pht('Active'));
|
$header->setStatus('fa-check', 'bluegrey', pht('Active'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$actions = $this->buildActionListView($blueprint);
|
$curtain = $this->buildCurtain($blueprint);
|
||||||
$properties = $this->buildPropertyListView($blueprint, $actions);
|
$properties = $this->buildPropertyListView($blueprint);
|
||||||
|
|
||||||
$crumbs = $this->buildApplicationCrumbs();
|
$crumbs = $this->buildApplicationCrumbs();
|
||||||
$crumbs->addTextCrumb(pht('Blueprint %d', $blueprint->getID()));
|
$crumbs->addTextCrumb(pht('Blueprint %d', $blueprint->getID()));
|
||||||
|
$crumbs->setBorder(true);
|
||||||
$object_box = id(new PHUIObjectBoxView())
|
|
||||||
->setHeader($header)
|
|
||||||
->addPropertyList($properties);
|
|
||||||
|
|
||||||
$field_list = PhabricatorCustomField::getObjectFields(
|
$field_list = PhabricatorCustomField::getObjectFields(
|
||||||
$blueprint,
|
$blueprint,
|
||||||
|
@ -49,9 +47,8 @@ final class DrydockBlueprintViewController extends DrydockBlueprintController {
|
||||||
$viewer,
|
$viewer,
|
||||||
$properties);
|
$properties);
|
||||||
|
|
||||||
$resource_box = $this->buildResourceBox($blueprint);
|
$resources = $this->buildResourceBox($blueprint);
|
||||||
|
$authorizations = $this->buildAuthorizationsBox($blueprint);
|
||||||
$authorizations_box = $this->buildAuthorizationsBox($blueprint);
|
|
||||||
|
|
||||||
$timeline = $this->buildTransactionTimeline(
|
$timeline = $this->buildTransactionTimeline(
|
||||||
$blueprint,
|
$blueprint,
|
||||||
|
@ -61,33 +58,36 @@ final class DrydockBlueprintViewController extends DrydockBlueprintController {
|
||||||
$log_query = id(new DrydockLogQuery())
|
$log_query = id(new DrydockLogQuery())
|
||||||
->withBlueprintPHIDs(array($blueprint->getPHID()));
|
->withBlueprintPHIDs(array($blueprint->getPHID()));
|
||||||
|
|
||||||
$log_box = $this->buildLogBox(
|
$logs = $this->buildLogBox(
|
||||||
$log_query,
|
$log_query,
|
||||||
$this->getApplicationURI("blueprint/{$id}/logs/query/all/"));
|
$this->getApplicationURI("blueprint/{$id}/logs/query/all/"));
|
||||||
|
|
||||||
return $this->buildApplicationPage(
|
$view = id(new PHUITwoColumnView())
|
||||||
array(
|
->setHeader($header)
|
||||||
$crumbs,
|
->setCurtain($curtain)
|
||||||
$object_box,
|
->addPropertySection(pht('Properties'), $properties)
|
||||||
$resource_box,
|
->setMainColumn(array(
|
||||||
$authorizations_box,
|
$resources,
|
||||||
$log_box,
|
$authorizations,
|
||||||
|
$logs,
|
||||||
$timeline,
|
$timeline,
|
||||||
),
|
));
|
||||||
|
|
||||||
|
return $this->newPage()
|
||||||
|
->setTitle($title)
|
||||||
|
->setCrumbs($crumbs)
|
||||||
|
->appendChild(
|
||||||
array(
|
array(
|
||||||
'title' => $title,
|
$view,
|
||||||
));
|
));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildActionListView(DrydockBlueprint $blueprint) {
|
private function buildCurtain(DrydockBlueprint $blueprint) {
|
||||||
$viewer = $this->getViewer();
|
$viewer = $this->getViewer();
|
||||||
$id = $blueprint->getID();
|
$id = $blueprint->getID();
|
||||||
|
|
||||||
$view = id(new PhabricatorActionListView())
|
$curtain = $this->newCurtainView($blueprint);
|
||||||
->setUser($viewer)
|
|
||||||
->setObject($blueprint);
|
|
||||||
|
|
||||||
$edit_uri = $this->getApplicationURI("blueprint/edit/{$id}/");
|
$edit_uri = $this->getApplicationURI("blueprint/edit/{$id}/");
|
||||||
|
|
||||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||||
|
@ -95,7 +95,7 @@ final class DrydockBlueprintViewController extends DrydockBlueprintController {
|
||||||
$blueprint,
|
$blueprint,
|
||||||
PhabricatorPolicyCapability::CAN_EDIT);
|
PhabricatorPolicyCapability::CAN_EDIT);
|
||||||
|
|
||||||
$view->addAction(
|
$curtain->addAction(
|
||||||
id(new PhabricatorActionView())
|
id(new PhabricatorActionView())
|
||||||
->setHref($edit_uri)
|
->setHref($edit_uri)
|
||||||
->setName(pht('Edit Blueprint'))
|
->setName(pht('Edit Blueprint'))
|
||||||
|
@ -113,7 +113,7 @@ final class DrydockBlueprintViewController extends DrydockBlueprintController {
|
||||||
$disable_uri = $this->getApplicationURI("blueprint/{$id}/enable/");
|
$disable_uri = $this->getApplicationURI("blueprint/{$id}/enable/");
|
||||||
}
|
}
|
||||||
|
|
||||||
$view->addAction(
|
$curtain->addAction(
|
||||||
id(new PhabricatorActionView())
|
id(new PhabricatorActionView())
|
||||||
->setHref($disable_uri)
|
->setHref($disable_uri)
|
||||||
->setName($disable_name)
|
->setName($disable_name)
|
||||||
|
@ -121,19 +121,15 @@ final class DrydockBlueprintViewController extends DrydockBlueprintController {
|
||||||
->setWorkflow(true)
|
->setWorkflow(true)
|
||||||
->setDisabled(!$can_edit));
|
->setDisabled(!$can_edit));
|
||||||
|
|
||||||
return $view;
|
return $curtain;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildPropertyListView(
|
private function buildPropertyListView(
|
||||||
DrydockBlueprint $blueprint,
|
DrydockBlueprint $blueprint) {
|
||||||
PhabricatorActionListView $actions) {
|
|
||||||
$viewer = $this->getViewer();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$view = id(new PHUIPropertyListView())
|
$view = id(new PHUIPropertyListView())
|
||||||
->setUser($viewer)
|
->setUser($viewer);
|
||||||
->setObject($blueprint);
|
|
||||||
|
|
||||||
$view->setActionList($actions);
|
|
||||||
|
|
||||||
$view->addProperty(
|
$view->addProperty(
|
||||||
pht('Type'),
|
pht('Type'),
|
||||||
|
@ -177,6 +173,7 @@ final class DrydockBlueprintViewController extends DrydockBlueprintController {
|
||||||
|
|
||||||
return id(new PHUIObjectBoxView())
|
return id(new PHUIObjectBoxView())
|
||||||
->setHeader($resource_header)
|
->setHeader($resource_header)
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->setObjectList($resource_list);
|
->setObjectList($resource_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,6 +239,7 @@ final class DrydockBlueprintViewController extends DrydockBlueprintController {
|
||||||
|
|
||||||
return id(new PHUIObjectBoxView())
|
return id(new PHUIObjectBoxView())
|
||||||
->setHeader($authorizations_header)
|
->setHeader($authorizations_header)
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->setObjectList($authorization_list);
|
->setObjectList($authorization_list);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,6 +102,7 @@ abstract class DrydockController extends PhabricatorController {
|
||||||
->setText(pht('View All')));
|
->setText(pht('View All')));
|
||||||
|
|
||||||
return id(new PHUIObjectBoxView())
|
return id(new PHUIObjectBoxView())
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->setHeader($log_header)
|
->setHeader($log_header)
|
||||||
->setTable($log_table);
|
->setTable($log_table);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,53 +21,59 @@ final class DrydockLeaseViewController extends DrydockLeaseController {
|
||||||
$title = pht('Lease %d', $lease->getID());
|
$title = pht('Lease %d', $lease->getID());
|
||||||
|
|
||||||
$header = id(new PHUIHeaderView())
|
$header = id(new PHUIHeaderView())
|
||||||
->setHeader($title);
|
->setHeader($title)
|
||||||
|
->setHeaderIcon('fa-link');
|
||||||
|
|
||||||
if ($lease->isReleasing()) {
|
if ($lease->isReleasing()) {
|
||||||
$header->setStatus('fa-exclamation-triangle', 'red', pht('Releasing'));
|
$header->setStatus('fa-exclamation-triangle', 'red', pht('Releasing'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$actions = $this->buildActionListView($lease);
|
$curtain = $this->buildCurtain($lease);
|
||||||
$properties = $this->buildPropertyListView($lease, $actions);
|
$properties = $this->buildPropertyListView($lease);
|
||||||
|
|
||||||
$log_query = id(new DrydockLogQuery())
|
$log_query = id(new DrydockLogQuery())
|
||||||
->withLeasePHIDs(array($lease->getPHID()));
|
->withLeasePHIDs(array($lease->getPHID()));
|
||||||
|
|
||||||
$log_box = $this->buildLogBox(
|
$logs = $this->buildLogBox(
|
||||||
$log_query,
|
$log_query,
|
||||||
$this->getApplicationURI("lease/{$id}/logs/query/all/"));
|
$this->getApplicationURI("lease/{$id}/logs/query/all/"));
|
||||||
|
|
||||||
$crumbs = $this->buildApplicationCrumbs();
|
$crumbs = $this->buildApplicationCrumbs();
|
||||||
$crumbs->addTextCrumb($title, $lease_uri);
|
$crumbs->addTextCrumb($title, $lease_uri);
|
||||||
|
$crumbs->setBorder(true);
|
||||||
|
|
||||||
$locks = $this->buildLocksTab($lease->getPHID());
|
$locks = $this->buildLocksTab($lease->getPHID());
|
||||||
$commands = $this->buildCommandsTab($lease->getPHID());
|
$commands = $this->buildCommandsTab($lease->getPHID());
|
||||||
|
|
||||||
$object_box = id(new PHUIObjectBoxView())
|
$object_box = id(new PHUIObjectBoxView())
|
||||||
->setHeader($header)
|
->setHeaderText(pht('Properties'))
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->addPropertyList($properties, pht('Properties'))
|
->addPropertyList($properties, pht('Properties'))
|
||||||
->addPropertyList($locks, pht('Slot Locks'))
|
->addPropertyList($locks, pht('Slot Locks'))
|
||||||
->addPropertyList($commands, pht('Commands'));
|
->addPropertyList($commands, pht('Commands'));
|
||||||
|
|
||||||
return $this->buildApplicationPage(
|
$view = id(new PHUITwoColumnView())
|
||||||
array(
|
->setHeader($header)
|
||||||
$crumbs,
|
->setCurtain($curtain)
|
||||||
|
->setMainColumn(array(
|
||||||
$object_box,
|
$object_box,
|
||||||
$log_box,
|
$logs,
|
||||||
),
|
));
|
||||||
|
|
||||||
|
return $this->newPage()
|
||||||
|
->setTitle($title)
|
||||||
|
->setCrumbs($crumbs)
|
||||||
|
->appendChild(
|
||||||
array(
|
array(
|
||||||
'title' => $title,
|
$view,
|
||||||
));
|
));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildActionListView(DrydockLease $lease) {
|
private function buildCurtain(DrydockLease $lease) {
|
||||||
$viewer = $this->getViewer();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$view = id(new PhabricatorActionListView())
|
$curtain = $this->newCurtainView($lease);
|
||||||
->setUser($viewer)
|
|
||||||
->setObject($lease);
|
|
||||||
|
|
||||||
$id = $lease->getID();
|
$id = $lease->getID();
|
||||||
|
|
||||||
$can_release = $lease->canRelease();
|
$can_release = $lease->canRelease();
|
||||||
|
@ -80,7 +86,7 @@ final class DrydockLeaseViewController extends DrydockLeaseController {
|
||||||
$lease,
|
$lease,
|
||||||
PhabricatorPolicyCapability::CAN_EDIT);
|
PhabricatorPolicyCapability::CAN_EDIT);
|
||||||
|
|
||||||
$view->addAction(
|
$curtain->addAction(
|
||||||
id(new PhabricatorActionView())
|
id(new PhabricatorActionView())
|
||||||
->setName(pht('Release Lease'))
|
->setName(pht('Release Lease'))
|
||||||
->setIcon('fa-times')
|
->setIcon('fa-times')
|
||||||
|
@ -88,16 +94,14 @@ final class DrydockLeaseViewController extends DrydockLeaseController {
|
||||||
->setWorkflow(true)
|
->setWorkflow(true)
|
||||||
->setDisabled(!$can_release || !$can_edit));
|
->setDisabled(!$can_release || !$can_edit));
|
||||||
|
|
||||||
return $view;
|
return $curtain;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildPropertyListView(
|
private function buildPropertyListView(
|
||||||
DrydockLease $lease,
|
DrydockLease $lease) {
|
||||||
PhabricatorActionListView $actions) {
|
|
||||||
$viewer = $this->getViewer();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$view = new PHUIPropertyListView();
|
$view = new PHUIPropertyListView();
|
||||||
$view->setActionList($actions);
|
|
||||||
|
|
||||||
$view->addProperty(
|
$view->addProperty(
|
||||||
pht('Status'),
|
pht('Status'),
|
||||||
|
|
|
@ -25,50 +25,52 @@ final class DrydockRepositoryOperationViewController
|
||||||
$header = id(new PHUIHeaderView())
|
$header = id(new PHUIHeaderView())
|
||||||
->setHeader($title)
|
->setHeader($title)
|
||||||
->setUser($viewer)
|
->setUser($viewer)
|
||||||
->setPolicyObject($operation);
|
->setPolicyObject($operation)
|
||||||
|
->setHeaderIcon('fa-fighter-jet');
|
||||||
|
|
||||||
$state = $operation->getOperationState();
|
$state = $operation->getOperationState();
|
||||||
$icon = DrydockRepositoryOperation::getOperationStateIcon($state);
|
$icon = DrydockRepositoryOperation::getOperationStateIcon($state);
|
||||||
$name = DrydockRepositoryOperation::getOperationStateName($state);
|
$name = DrydockRepositoryOperation::getOperationStateName($state);
|
||||||
$header->setStatus($icon, null, $name);
|
$header->setStatus($icon, null, $name);
|
||||||
|
|
||||||
$actions = $this->buildActionListView($operation);
|
$curtain = $this->buildCurtain($operation);
|
||||||
$properties = $this->buildPropertyListView($operation);
|
$properties = $this->buildPropertyListView($operation);
|
||||||
$properties->setActionList($actions);
|
|
||||||
|
|
||||||
$crumbs = $this->buildApplicationCrumbs();
|
$crumbs = $this->buildApplicationCrumbs();
|
||||||
$crumbs->addTextCrumb(
|
$crumbs->addTextCrumb(
|
||||||
pht('Operations'),
|
pht('Operations'),
|
||||||
$this->getApplicationURI('operation/'));
|
$this->getApplicationURI('operation/'));
|
||||||
$crumbs->addTextCrumb($title);
|
$crumbs->addTextCrumb($title);
|
||||||
|
$crumbs->setBorder(true);
|
||||||
$object_box = id(new PHUIObjectBoxView())
|
|
||||||
->setHeader($header)
|
|
||||||
->addPropertyList($properties);
|
|
||||||
|
|
||||||
$status_view = id(new DrydockRepositoryOperationStatusView())
|
$status_view = id(new DrydockRepositoryOperationStatusView())
|
||||||
->setUser($viewer)
|
->setUser($viewer)
|
||||||
->setOperation($operation);
|
->setOperation($operation);
|
||||||
|
|
||||||
|
$view = id(new PHUITwoColumnView())
|
||||||
|
->setHeader($header)
|
||||||
|
->setCurtain($curtain)
|
||||||
|
->addPropertySection(pht('Properties'), $properties)
|
||||||
|
->setMainColumn(array(
|
||||||
|
$status_view,
|
||||||
|
));
|
||||||
|
|
||||||
return $this->newPage()
|
return $this->newPage()
|
||||||
->setTitle($title)
|
->setTitle($title)
|
||||||
->setCrumbs($crumbs)
|
->setCrumbs($crumbs)
|
||||||
->appendChild(
|
->appendChild(
|
||||||
array(
|
array(
|
||||||
$object_box,
|
$view,
|
||||||
$status_view,
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildActionListView(DrydockRepositoryOperation $operation) {
|
private function buildCurtain(DrydockRepositoryOperation $operation) {
|
||||||
$viewer = $this->getViewer();
|
$viewer = $this->getViewer();
|
||||||
$id = $operation->getID();
|
$id = $operation->getID();
|
||||||
|
|
||||||
$view = id(new PhabricatorActionListView())
|
$curtain = $this->newCurtainView($operation);
|
||||||
->setUser($viewer)
|
|
||||||
->setObject($operation);
|
|
||||||
|
|
||||||
return $view;
|
return $curtain;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildPropertyListView(
|
private function buildPropertyListView(
|
||||||
|
|
|
@ -23,14 +23,15 @@ final class DrydockResourceViewController extends DrydockResourceController {
|
||||||
$header = id(new PHUIHeaderView())
|
$header = id(new PHUIHeaderView())
|
||||||
->setUser($viewer)
|
->setUser($viewer)
|
||||||
->setPolicyObject($resource)
|
->setPolicyObject($resource)
|
||||||
->setHeader($title);
|
->setHeader($title)
|
||||||
|
->setHeaderIcon('fa-map');
|
||||||
|
|
||||||
if ($resource->isReleasing()) {
|
if ($resource->isReleasing()) {
|
||||||
$header->setStatus('fa-exclamation-triangle', 'red', pht('Releasing'));
|
$header->setStatus('fa-exclamation-triangle', 'red', pht('Releasing'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$actions = $this->buildActionListView($resource);
|
$curtain = $this->buildCurtain($resource);
|
||||||
$properties = $this->buildPropertyListView($resource, $actions);
|
$properties = $this->buildPropertyListView($resource);
|
||||||
|
|
||||||
$id = $resource->getID();
|
$id = $resource->getID();
|
||||||
$resource_uri = $this->getApplicationURI("resource/{$id}/");
|
$resource_uri = $this->getApplicationURI("resource/{$id}/");
|
||||||
|
@ -44,37 +45,42 @@ final class DrydockResourceViewController extends DrydockResourceController {
|
||||||
|
|
||||||
$crumbs = $this->buildApplicationCrumbs();
|
$crumbs = $this->buildApplicationCrumbs();
|
||||||
$crumbs->addTextCrumb(pht('Resource %d', $resource->getID()));
|
$crumbs->addTextCrumb(pht('Resource %d', $resource->getID()));
|
||||||
|
$crumbs->setBorder(true);
|
||||||
|
|
||||||
$locks = $this->buildLocksTab($resource->getPHID());
|
$locks = $this->buildLocksTab($resource->getPHID());
|
||||||
$commands = $this->buildCommandsTab($resource->getPHID());
|
$commands = $this->buildCommandsTab($resource->getPHID());
|
||||||
|
$lease_box = $this->buildLeaseBox($resource);
|
||||||
|
|
||||||
$object_box = id(new PHUIObjectBoxView())
|
$object_box = id(new PHUIObjectBoxView())
|
||||||
->setHeader($header)
|
->setHeaderText(pht('Properties'))
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->addPropertyList($properties, pht('Properties'))
|
->addPropertyList($properties, pht('Properties'))
|
||||||
->addPropertyList($locks, pht('Slot Locks'))
|
->addPropertyList($locks, pht('Slot Locks'))
|
||||||
->addPropertyList($commands, pht('Commands'));
|
->addPropertyList($commands, pht('Commands'));
|
||||||
|
|
||||||
$lease_box = $this->buildLeaseBox($resource);
|
$view = id(new PHUITwoColumnView())
|
||||||
|
->setHeader($header)
|
||||||
return $this->buildApplicationPage(
|
->setCurtain($curtain)
|
||||||
array(
|
->setMainColumn(array(
|
||||||
$crumbs,
|
|
||||||
$object_box,
|
$object_box,
|
||||||
$lease_box,
|
$lease_box,
|
||||||
$log_box,
|
$log_box,
|
||||||
),
|
));
|
||||||
|
|
||||||
|
return $this->newPage()
|
||||||
|
->setTitle($title)
|
||||||
|
->setCrumbs($crumbs)
|
||||||
|
->appendChild(
|
||||||
array(
|
array(
|
||||||
'title' => $title,
|
$view,
|
||||||
));
|
));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildActionListView(DrydockResource $resource) {
|
private function buildCurtain(DrydockResource $resource) {
|
||||||
$viewer = $this->getViewer();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$view = id(new PhabricatorActionListView())
|
$curtain = $this->newCurtainView($resource);
|
||||||
->setUser($viewer)
|
|
||||||
->setObject($resource);
|
|
||||||
|
|
||||||
$can_release = $resource->canRelease();
|
$can_release = $resource->canRelease();
|
||||||
if ($resource->isReleasing()) {
|
if ($resource->isReleasing()) {
|
||||||
|
@ -89,7 +95,7 @@ final class DrydockResourceViewController extends DrydockResourceController {
|
||||||
$uri = '/resource/'.$resource->getID().'/release/';
|
$uri = '/resource/'.$resource->getID().'/release/';
|
||||||
$uri = $this->getApplicationURI($uri);
|
$uri = $this->getApplicationURI($uri);
|
||||||
|
|
||||||
$view->addAction(
|
$curtain->addAction(
|
||||||
id(new PhabricatorActionView())
|
id(new PhabricatorActionView())
|
||||||
->setHref($uri)
|
->setHref($uri)
|
||||||
->setName(pht('Release Resource'))
|
->setName(pht('Release Resource'))
|
||||||
|
@ -97,17 +103,14 @@ final class DrydockResourceViewController extends DrydockResourceController {
|
||||||
->setWorkflow(true)
|
->setWorkflow(true)
|
||||||
->setDisabled(!$can_release || !$can_edit));
|
->setDisabled(!$can_release || !$can_edit));
|
||||||
|
|
||||||
return $view;
|
return $curtain;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildPropertyListView(
|
private function buildPropertyListView(
|
||||||
DrydockResource $resource,
|
DrydockResource $resource) {
|
||||||
PhabricatorActionListView $actions) {
|
|
||||||
$viewer = $this->getViewer();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$view = id(new PHUIPropertyListView())
|
$view = new PHUIPropertyListView();
|
||||||
->setActionList($actions);
|
|
||||||
|
|
||||||
$status = $resource->getStatus();
|
$status = $resource->getStatus();
|
||||||
$status = DrydockResourceStatus::getNameForStatus($status);
|
$status = DrydockResourceStatus::getNameForStatus($status);
|
||||||
|
|
||||||
|
@ -179,6 +182,7 @@ final class DrydockResourceViewController extends DrydockResourceController {
|
||||||
|
|
||||||
return id(new PHUIObjectBoxView())
|
return id(new PHUIObjectBoxView())
|
||||||
->setHeader($lease_header)
|
->setHeader($lease_header)
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->setObjectList($lease_list);
|
->setObjectList($lease_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@ final class DrydockRepositoryOperationStatusView
|
||||||
$box_view = $this->getBoxView();
|
$box_view = $this->getBoxView();
|
||||||
if (!$box_view) {
|
if (!$box_view) {
|
||||||
$box_view = id(new PHUIObjectBoxView())
|
$box_view = id(new PHUIObjectBoxView())
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->setHeaderText(pht('Operation Status'));
|
->setHeaderText(pht('Operation Status'));
|
||||||
}
|
}
|
||||||
$box_view->setObjectList($list);
|
$box_view->setObjectList($list);
|
||||||
|
|
|
@ -26,7 +26,6 @@ final class PhabricatorFile extends PhabricatorFileDAO
|
||||||
PhabricatorPolicyInterface,
|
PhabricatorPolicyInterface,
|
||||||
PhabricatorDestructibleInterface {
|
PhabricatorDestructibleInterface {
|
||||||
|
|
||||||
const ONETIME_TEMPORARY_TOKEN_TYPE = 'file:onetime';
|
|
||||||
const STORAGE_FORMAT_RAW = 'raw';
|
const STORAGE_FORMAT_RAW = 'raw';
|
||||||
|
|
||||||
const METADATA_IMAGE_WIDTH = 'width';
|
const METADATA_IMAGE_WIDTH = 'width';
|
||||||
|
@ -1119,12 +1118,13 @@ final class PhabricatorFile extends PhabricatorFileDAO
|
||||||
|
|
||||||
protected function generateOneTimeToken() {
|
protected function generateOneTimeToken() {
|
||||||
$key = Filesystem::readRandomCharacters(16);
|
$key = Filesystem::readRandomCharacters(16);
|
||||||
|
$token_type = PhabricatorFileAccessTemporaryTokenType::TOKENTYPE;
|
||||||
|
|
||||||
// Save the new secret.
|
// Save the new secret.
|
||||||
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
||||||
$token = id(new PhabricatorAuthTemporaryToken())
|
$token = id(new PhabricatorAuthTemporaryToken())
|
||||||
->setObjectPHID($this->getPHID())
|
->setTokenResource($this->getPHID())
|
||||||
->setTokenType(self::ONETIME_TEMPORARY_TOKEN_TYPE)
|
->setTokenType($token_type)
|
||||||
->setTokenExpires(time() + phutil_units('1 hour in seconds'))
|
->setTokenExpires(time() + phutil_units('1 hour in seconds'))
|
||||||
->setTokenCode(PhabricatorHash::digest($key))
|
->setTokenCode(PhabricatorHash::digest($key))
|
||||||
->save();
|
->save();
|
||||||
|
@ -1134,10 +1134,12 @@ final class PhabricatorFile extends PhabricatorFileDAO
|
||||||
}
|
}
|
||||||
|
|
||||||
public function validateOneTimeToken($token_code) {
|
public function validateOneTimeToken($token_code) {
|
||||||
|
$token_type = PhabricatorFileAccessTemporaryTokenType::TOKENTYPE;
|
||||||
|
|
||||||
$token = id(new PhabricatorAuthTemporaryTokenQuery())
|
$token = id(new PhabricatorAuthTemporaryTokenQuery())
|
||||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||||
->withObjectPHIDs(array($this->getPHID()))
|
->withTokenResources(array($this->getPHID()))
|
||||||
->withTokenTypes(array(self::ONETIME_TEMPORARY_TOKEN_TYPE))
|
->withTokenTypes(array($token_type))
|
||||||
->withExpired(false)
|
->withExpired(false)
|
||||||
->withTokenCodes(array(PhabricatorHash::digest($token_code)))
|
->withTokenCodes(array(PhabricatorHash::digest($token_code)))
|
||||||
->executeOne();
|
->executeOne();
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorFileAccessTemporaryTokenType
|
||||||
|
extends PhabricatorAuthTemporaryTokenType {
|
||||||
|
|
||||||
|
const TOKENTYPE = 'file:onetime';
|
||||||
|
|
||||||
|
public function getTokenTypeDisplayName() {
|
||||||
|
return pht('File Access');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTokenReadableTypeName(
|
||||||
|
PhabricatorAuthTemporaryToken $token) {
|
||||||
|
return pht('File Access Token');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -72,8 +72,10 @@ abstract class PhabricatorFileUploadSource
|
||||||
$data->rewind();
|
$data->rewind();
|
||||||
$this->didRewind = true;
|
$this->didRewind = true;
|
||||||
} else {
|
} else {
|
||||||
|
if ($data->valid()) {
|
||||||
$data->next();
|
$data->next();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!$data->valid()) {
|
if (!$data->valid()) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorIteratorFileUploadSource
|
||||||
|
extends PhabricatorFileUploadSource {
|
||||||
|
|
||||||
|
private $iterator;
|
||||||
|
|
||||||
|
public function setIterator(Iterator $iterator) {
|
||||||
|
$this->iterator = $iterator;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getIterator() {
|
||||||
|
return $this->iterator;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function newDataIterator() {
|
||||||
|
return $this->getIterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getDataLength() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ final class HarbormasterUnitSummaryView extends AphrontView {
|
||||||
private $limit;
|
private $limit;
|
||||||
private $excuse;
|
private $excuse;
|
||||||
private $showViewAll;
|
private $showViewAll;
|
||||||
|
private $background;
|
||||||
|
|
||||||
public function setBuildable(HarbormasterBuildable $buildable) {
|
public function setBuildable(HarbormasterBuildable $buildable) {
|
||||||
$this->buildable = $buildable;
|
$this->buildable = $buildable;
|
||||||
|
@ -33,6 +34,11 @@ final class HarbormasterUnitSummaryView extends AphrontView {
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setBackground($background) {
|
||||||
|
$this->background = $background;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function render() {
|
public function render() {
|
||||||
$messages = $this->messages;
|
$messages = $this->messages;
|
||||||
$buildable = $this->buildable;
|
$buildable = $this->buildable;
|
||||||
|
@ -54,9 +60,14 @@ final class HarbormasterUnitSummaryView extends AphrontView {
|
||||||
$tag_icon = 'fa-ban';
|
$tag_icon = 'fa-ban';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$tag = id(new PHUITagView())
|
||||||
|
->setType(PHUITagView::TYPE_SHADE)
|
||||||
|
->setShade($tag_color)
|
||||||
|
->setIcon($tag_icon)
|
||||||
|
->setName($tag_text);
|
||||||
|
|
||||||
$header = id(new PHUIHeaderView())
|
$header = id(new PHUIHeaderView())
|
||||||
->setHeader(pht('Unit Tests'))
|
->setHeader(array(pht('Unit Tests'), $tag));
|
||||||
->setStatus($tag_icon, $tag_color, $tag_text);
|
|
||||||
|
|
||||||
if ($this->showViewAll) {
|
if ($this->showViewAll) {
|
||||||
$view_all = id(new PHUIButtonView())
|
$view_all = id(new PHUIButtonView())
|
||||||
|
@ -98,6 +109,10 @@ final class HarbormasterUnitSummaryView extends AphrontView {
|
||||||
|
|
||||||
$box->setTable($table);
|
$box->setTable($table);
|
||||||
|
|
||||||
|
if ($this->background) {
|
||||||
|
$box->setBackground($this->background);
|
||||||
|
}
|
||||||
|
|
||||||
return $box;
|
return $box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -700,7 +700,7 @@ final class PhabricatorUserEditor extends PhabricatorEditor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function revokePasswordResetLinks(PhabricatorUser $user) {
|
public function revokePasswordResetLinks(PhabricatorUser $user) {
|
||||||
// Revoke any outstanding password reset links. If an attacker compromises
|
// Revoke any outstanding password reset links. If an attacker compromises
|
||||||
// an account, changes the email address, and sends themselves a password
|
// an account, changes the email address, and sends themselves a password
|
||||||
// reset link, it could otherwise remain live for a short period of time
|
// reset link, it could otherwise remain live for a short period of time
|
||||||
|
@ -710,8 +710,8 @@ final class PhabricatorUserEditor extends PhabricatorEditor {
|
||||||
$user,
|
$user,
|
||||||
array($user->getPHID()),
|
array($user->getPHID()),
|
||||||
array(
|
array(
|
||||||
PhabricatorAuthSessionEngine::ONETIME_TEMPORARY_TOKEN_TYPE,
|
PhabricatorAuthOneTimeLoginTemporaryTokenType::TOKENTYPE,
|
||||||
PhabricatorAuthSessionEngine::PASSWORD_TEMPORARY_TOKEN_TYPE,
|
PhabricatorAuthPasswordResetTemporaryTokenType::TOKENTYPE,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -742,6 +742,38 @@ final class PhabricatorUser
|
||||||
return new DateTimeZone($this->getTimezoneIdentifier());
|
return new DateTimeZone($this->getTimezoneIdentifier());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function formatShortDateTime($when, $now = null) {
|
||||||
|
if ($now === null) {
|
||||||
|
$now = PhabricatorTime::getNow();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$when = new DateTime('@'.$when);
|
||||||
|
$now = new DateTime('@'.$now);
|
||||||
|
} catch (Exception $ex) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$zone = $this->getTimeZone();
|
||||||
|
|
||||||
|
$when->setTimeZone($zone);
|
||||||
|
$now->setTimeZone($zone);
|
||||||
|
|
||||||
|
if ($when->format('Y') !== $now->format('Y')) {
|
||||||
|
// Different year, so show "Feb 31 2075".
|
||||||
|
$format = 'M j Y';
|
||||||
|
} else if ($when->format('Ymd') !== $now->format('Ymd')) {
|
||||||
|
// Same year but different month and day, so show "Feb 31".
|
||||||
|
$format = 'M j';
|
||||||
|
} else {
|
||||||
|
// Same year, month and day so show a time of day.
|
||||||
|
$pref_time = PhabricatorUserPreferences::PREFERENCE_TIME_FORMAT;
|
||||||
|
$format = $this->getPreference($pref_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $when->format($format);
|
||||||
|
}
|
||||||
|
|
||||||
public function getPreference($key) {
|
public function getPreference($key) {
|
||||||
$preferences = $this->loadPreferences();
|
$preferences = $this->loadPreferences();
|
||||||
|
|
||||||
|
|
109
src/applications/phid/remarkup/PhabricatorHandleRemarkupRule.php
Normal file
109
src/applications/phid/remarkup/PhabricatorHandleRemarkupRule.php
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorHandleRemarkupRule extends PhutilRemarkupRule {
|
||||||
|
|
||||||
|
const KEY_RULE_HANDLE = 'rule.handle';
|
||||||
|
const KEY_RULE_HANDLE_ORIGINAL = 'rule.handle.original';
|
||||||
|
|
||||||
|
public function apply($text) {
|
||||||
|
return preg_replace_callback(
|
||||||
|
'/{(PHID-[a-zA-Z0-9-]*)}/',
|
||||||
|
array($this, 'markupHandle'),
|
||||||
|
$text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function markupHandle(array $matches) {
|
||||||
|
$engine = $this->getEngine();
|
||||||
|
$viewer = $engine->getConfig('viewer');
|
||||||
|
|
||||||
|
if (!$this->isFlatText($matches[0])) {
|
||||||
|
return $matches[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
$phid_type = phid_get_type($matches[1]);
|
||||||
|
if ($phid_type == PhabricatorPHIDConstants::PHID_TYPE_UNKNOWN) {
|
||||||
|
return $matches[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
$token = $engine->storeText($matches[0]);
|
||||||
|
if ($engine->isTextMode()) {
|
||||||
|
return $token;
|
||||||
|
}
|
||||||
|
|
||||||
|
$original_key = self::KEY_RULE_HANDLE_ORIGINAL;
|
||||||
|
$original = $engine->getTextMetadata($original_key, array());
|
||||||
|
$original[$token] = $matches[0];
|
||||||
|
$engine->setTextMetadata($original_key, $original);
|
||||||
|
|
||||||
|
$metadata_key = self::KEY_RULE_HANDLE;
|
||||||
|
$metadata = $engine->getTextMetadata($metadata_key, array());
|
||||||
|
$phid = $matches[1];
|
||||||
|
if (empty($metadata[$phid])) {
|
||||||
|
$metadata[$phid] = array();
|
||||||
|
}
|
||||||
|
$metadata[$phid][] = $token;
|
||||||
|
$engine->setTextMetadata($metadata_key, $metadata);
|
||||||
|
|
||||||
|
return $token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function didMarkupText() {
|
||||||
|
$engine = $this->getEngine();
|
||||||
|
|
||||||
|
$metadata_key = self::KEY_RULE_HANDLE;
|
||||||
|
|
||||||
|
$metadata = $engine->getTextMetadata($metadata_key, array());
|
||||||
|
if (empty($metadata)) {
|
||||||
|
// No mentions, or we already processed them.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$original_key = self::KEY_RULE_HANDLE_ORIGINAL;
|
||||||
|
$original = $engine->getTextMetadata($original_key, array());
|
||||||
|
|
||||||
|
$phids = array_keys($metadata);
|
||||||
|
|
||||||
|
$handles = id(new PhabricatorHandleQuery())
|
||||||
|
->setViewer($this->getEngine()->getConfig('viewer'))
|
||||||
|
->withPHIDs($phids)
|
||||||
|
->execute();
|
||||||
|
|
||||||
|
foreach ($metadata as $phid => $tokens) {
|
||||||
|
$handle = idx($handles, $phid);
|
||||||
|
|
||||||
|
if ($handle->isComplete()) {
|
||||||
|
if ($engine->isHTMLMailMode()) {
|
||||||
|
$href = $handle->getURI();
|
||||||
|
$href = PhabricatorEnv::getProductionURI($href);
|
||||||
|
|
||||||
|
$link = phutil_tag(
|
||||||
|
'a',
|
||||||
|
array(
|
||||||
|
'href' => $href,
|
||||||
|
'style' => '
|
||||||
|
border-color: #f1f7ff;
|
||||||
|
color: #19558d;
|
||||||
|
background-color: #f1f7ff;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-weight: bold;
|
||||||
|
padding: 0 4px;',
|
||||||
|
),
|
||||||
|
$handle->getLinkName());
|
||||||
|
} else {
|
||||||
|
$link = $handle->renderTag();
|
||||||
|
$link->setPHID($phid);
|
||||||
|
}
|
||||||
|
foreach ($tokens as $token) {
|
||||||
|
$engine->overwriteStoredText($token, $link);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
foreach ($tokens as $token) {
|
||||||
|
$engine->overwriteStoredText($token, idx($original, $token));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$engine->setTextMetadata($metadata_key, array());
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,7 +18,9 @@ final class PhabricatorPhurlLinkRemarkupRule extends PhutilRemarkupRule {
|
||||||
public function markupLink(array $matches) {
|
public function markupLink(array $matches) {
|
||||||
$engine = $this->getEngine();
|
$engine = $this->getEngine();
|
||||||
$viewer = $engine->getConfig('viewer');
|
$viewer = $engine->getConfig('viewer');
|
||||||
|
|
||||||
$text_mode = $engine->isTextMode();
|
$text_mode = $engine->isTextMode();
|
||||||
|
$html_mode = $engine->isHTMLMailMode();
|
||||||
|
|
||||||
if (!$this->isFlatText($matches[0])) {
|
if (!$this->isFlatText($matches[0])) {
|
||||||
return $matches[0];
|
return $matches[0];
|
||||||
|
@ -28,46 +30,45 @@ final class PhabricatorPhurlLinkRemarkupRule extends PhutilRemarkupRule {
|
||||||
$monogram = null;
|
$monogram = null;
|
||||||
$is_monogram = '/^U(?P<id>[1-9]\d*)/';
|
$is_monogram = '/^U(?P<id>[1-9]\d*)/';
|
||||||
|
|
||||||
|
$query = id(new PhabricatorPhurlURLQuery())
|
||||||
|
->setViewer($viewer);
|
||||||
|
|
||||||
if (preg_match($is_monogram, $ref, $monogram)) {
|
if (preg_match($is_monogram, $ref, $monogram)) {
|
||||||
$phurls = id(new PhabricatorPhurlURLQuery())
|
$query->withIDs(array($monogram[1]));
|
||||||
->setViewer($viewer)
|
|
||||||
->withIDs(array($monogram[1]))
|
|
||||||
->execute();
|
|
||||||
} else if (ctype_digit($ref)) {
|
} else if (ctype_digit($ref)) {
|
||||||
$phurls = id(new PhabricatorPhurlURLQuery())
|
$query->withIDs(array($ref));
|
||||||
->setViewer($viewer)
|
|
||||||
->withIDs(array($ref))
|
|
||||||
->execute();
|
|
||||||
} else {
|
} else {
|
||||||
$phurls = id(new PhabricatorPhurlURLQuery())
|
$query->withAliases(array($ref));
|
||||||
->setViewer($viewer)
|
|
||||||
->withAliases(array($ref))
|
|
||||||
->execute();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$phurl = head($phurls);
|
$phurl = $query->executeOne();
|
||||||
|
if (!$phurl) {
|
||||||
|
return $matches[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
$uri = $phurl->getRedirectURI();
|
||||||
|
$name = $phurl->getDisplayName();
|
||||||
|
|
||||||
|
if ($text_mode || $html_mode) {
|
||||||
|
$uri = PhabricatorEnv::getProductionURI($uri);
|
||||||
|
}
|
||||||
|
|
||||||
if ($phurl) {
|
|
||||||
if ($text_mode) {
|
if ($text_mode) {
|
||||||
return $phurl->getDisplayName().
|
return pht(
|
||||||
' <'.
|
'%s <%s>',
|
||||||
$phurl->getRedirectURI().
|
$name,
|
||||||
'>';
|
$uri);
|
||||||
}
|
} else {
|
||||||
|
|
||||||
$link = phutil_tag(
|
$link = phutil_tag(
|
||||||
'a',
|
'a',
|
||||||
array(
|
array(
|
||||||
'href' => $phurl->getRedirectURI(),
|
'href' => $uri,
|
||||||
'target' => '_blank',
|
'target' => '_blank',
|
||||||
),
|
),
|
||||||
$phurl->getDisplayName());
|
$name);
|
||||||
|
}
|
||||||
|
|
||||||
return $this->getEngine()->storeText($link);
|
return $this->getEngine()->storeText($link);
|
||||||
} else {
|
|
||||||
return $matches[0];
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorRepositoryGitLFSRefQuery
|
||||||
|
extends PhabricatorCursorPagedPolicyAwareQuery {
|
||||||
|
|
||||||
|
private $ids;
|
||||||
|
private $repositoryPHIDs;
|
||||||
|
private $objectHashes;
|
||||||
|
|
||||||
|
public function withIDs(array $ids) {
|
||||||
|
$this->ids = $ids;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withRepositoryPHIDs(array $phids) {
|
||||||
|
$this->repositoryPHIDs = $phids;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withObjectHashes(array $hashes) {
|
||||||
|
$this->objectHashes = $hashes;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function newResultObject() {
|
||||||
|
return new PhabricatorRepositoryGitLFSRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
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->repositoryPHIDs !== null) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn,
|
||||||
|
'repositoryPHID IN (%Ls)',
|
||||||
|
$this->repositoryPHIDs);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->objectHashes !== null) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn,
|
||||||
|
'objectHash IN (%Ls)',
|
||||||
|
$this->objectHashes);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $where;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getQueryApplicationClass() {
|
||||||
|
return 'PhabricatorDiffusionApplication';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1518,6 +1518,10 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $this->getRawHTTPCloneURIObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getRawHTTPCloneURIObject() {
|
||||||
$uri = PhabricatorEnv::getProductionURI($this->getURI());
|
$uri = PhabricatorEnv::getProductionURI($this->getURI());
|
||||||
$uri = new PhutilURI($uri);
|
$uri = new PhutilURI($uri);
|
||||||
|
|
||||||
|
@ -1819,6 +1823,38 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO
|
||||||
return !$this->isSVN();
|
return !$this->isSVN();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function canUseGitLFS() {
|
||||||
|
if (!$this->isGit()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->isHosted()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Unprototype this feature.
|
||||||
|
if (!PhabricatorEnv::getEnvConfig('phabricator.show-prototypes')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getGitLFSURI($path = null) {
|
||||||
|
if (!$this->canUseGitLFS()) {
|
||||||
|
throw new Exception(
|
||||||
|
pht(
|
||||||
|
'This repository does not support Git LFS, so Git LFS URIs can '.
|
||||||
|
'not be generated for it.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$uri = $this->getRawHTTPCloneURIObject();
|
||||||
|
$uri = (string)$uri;
|
||||||
|
$uri = $uri.'/'.$path;
|
||||||
|
|
||||||
|
return $uri;
|
||||||
|
}
|
||||||
|
|
||||||
public function canMirror() {
|
public function canMirror() {
|
||||||
if ($this->isGit() || $this->isHg()) {
|
if ($this->isGit() || $this->isHg()) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -2399,6 +2435,14 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO
|
||||||
$engine->destroyObject($atom);
|
$engine->destroyObject($atom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$lfs_refs = id(new PhabricatorRepositoryGitLFSRefQuery())
|
||||||
|
->setViewer($engine->getViewer())
|
||||||
|
->withRepositoryPHIDs(array($phid))
|
||||||
|
->execute();
|
||||||
|
foreach ($lfs_refs as $ref) {
|
||||||
|
$engine->destroyObject($ref);
|
||||||
|
}
|
||||||
|
|
||||||
$this->saveTransaction();
|
$this->saveTransaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorRepositoryGitLFSRef
|
||||||
|
extends PhabricatorRepositoryDAO
|
||||||
|
implements
|
||||||
|
PhabricatorPolicyInterface,
|
||||||
|
PhabricatorDestructibleInterface {
|
||||||
|
|
||||||
|
protected $repositoryPHID;
|
||||||
|
protected $objectHash;
|
||||||
|
protected $byteSize;
|
||||||
|
protected $authorPHID;
|
||||||
|
protected $filePHID;
|
||||||
|
|
||||||
|
protected function getConfiguration() {
|
||||||
|
return array(
|
||||||
|
self::CONFIG_COLUMN_SCHEMA => array(
|
||||||
|
'objectHash' => 'bytes64',
|
||||||
|
'byteSize' => 'uint64',
|
||||||
|
),
|
||||||
|
self::CONFIG_KEY_SCHEMA => array(
|
||||||
|
'key_hash' => array(
|
||||||
|
'columns' => array('repositoryPHID', 'objectHash'),
|
||||||
|
'unique' => true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
) + parent::getConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
public function getCapabilities() {
|
||||||
|
return array(
|
||||||
|
PhabricatorPolicyCapability::CAN_VIEW,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPolicy($capability) {
|
||||||
|
return PhabricatorPolicies::getMostOpenPolicy();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function describeAutomaticCapability($capability) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -( PhabricatorDestructibleInterface )----------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
public function destroyObjectPermanently(
|
||||||
|
PhabricatorDestructionEngine $engine) {
|
||||||
|
|
||||||
|
$file_phid = $this->getFilePHID();
|
||||||
|
|
||||||
|
$file = id(new PhabricatorFileQuery())
|
||||||
|
->setViewer($engine->getViewer())
|
||||||
|
->withPHIDs(array($file_phid))
|
||||||
|
->executeOne();
|
||||||
|
if ($file) {
|
||||||
|
$engine->destroyObject($file);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -155,9 +155,6 @@ final class PhabricatorRepositorySchemaSpec
|
||||||
'repositoryID' => array(
|
'repositoryID' => array(
|
||||||
'columns' => array('repositoryID', 'pathID', 'commitSequence'),
|
'columns' => array('repositoryID', 'pathID', 'commitSequence'),
|
||||||
),
|
),
|
||||||
'key_history' => array(
|
|
||||||
'columns' => array('commitID', 'isDirect', 'changeType'),
|
|
||||||
),
|
|
||||||
));
|
));
|
||||||
|
|
||||||
$this->buildRawSchema(
|
$this->buildRawSchema(
|
||||||
|
|
|
@ -40,13 +40,14 @@ final class PhabricatorPasswordSettingsPanel extends PhabricatorSettingsPanel {
|
||||||
// the workflow from a password reset email.
|
// the workflow from a password reset email.
|
||||||
|
|
||||||
$key = $request->getStr('key');
|
$key = $request->getStr('key');
|
||||||
|
$password_type = PhabricatorAuthPasswordResetTemporaryTokenType::TOKENTYPE;
|
||||||
|
|
||||||
$token = null;
|
$token = null;
|
||||||
if ($key) {
|
if ($key) {
|
||||||
$token = id(new PhabricatorAuthTemporaryTokenQuery())
|
$token = id(new PhabricatorAuthTemporaryTokenQuery())
|
||||||
->setViewer($user)
|
->setViewer($user)
|
||||||
->withObjectPHIDs(array($user->getPHID()))
|
->withTokenResources(array($user->getPHID()))
|
||||||
->withTokenTypes(
|
->withTokenTypes(array($password_type))
|
||||||
array(PhabricatorAuthSessionEngine::PASSWORD_TEMPORARY_TOKEN_TYPE))
|
|
||||||
->withTokenCodes(array(PhabricatorHash::digest($key)))
|
->withTokenCodes(array(PhabricatorHash::digest($key)))
|
||||||
->withExpired(false)
|
->withExpired(false)
|
||||||
->executeOne();
|
->executeOne();
|
||||||
|
|
|
@ -23,7 +23,7 @@ final class PhabricatorTokensSettingsPanel extends PhabricatorSettingsPanel {
|
||||||
|
|
||||||
$tokens = id(new PhabricatorAuthTemporaryTokenQuery())
|
$tokens = id(new PhabricatorAuthTemporaryTokenQuery())
|
||||||
->setViewer($viewer)
|
->setViewer($viewer)
|
||||||
->withObjectPHIDs(array($viewer->getPHID()))
|
->withTokenResources(array($viewer->getPHID()))
|
||||||
->execute();
|
->execute();
|
||||||
|
|
||||||
$rows = array();
|
$rows = array();
|
||||||
|
|
|
@ -4,6 +4,9 @@ final class PHUIDiffTableOfContentsListView extends AphrontView {
|
||||||
|
|
||||||
private $items = array();
|
private $items = array();
|
||||||
private $authorityPackages;
|
private $authorityPackages;
|
||||||
|
private $header;
|
||||||
|
private $infoView;
|
||||||
|
private $background;
|
||||||
|
|
||||||
public function addItem(PHUIDiffTableOfContentsItemView $item) {
|
public function addItem(PHUIDiffTableOfContentsItemView $item) {
|
||||||
$this->items[] = $item;
|
$this->items[] = $item;
|
||||||
|
@ -20,6 +23,21 @@ final class PHUIDiffTableOfContentsListView extends AphrontView {
|
||||||
return $this->authorityPackages;
|
return $this->authorityPackages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setBackground($background) {
|
||||||
|
$this->background = $background;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setHeader(PHUIHeaderView $header) {
|
||||||
|
$this->header = $header;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setInfoView(PHUIInfoView $infoview) {
|
||||||
|
$this->infoView = $infoview;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function render() {
|
public function render() {
|
||||||
$this->requireResource('differential-core-view-css');
|
$this->requireResource('differential-core-view-css');
|
||||||
$this->requireResource('differential-table-of-contents-css');
|
$this->requireResource('differential-table-of-contents-css');
|
||||||
|
@ -142,11 +160,24 @@ final class PHUIDiffTableOfContentsListView extends AphrontView {
|
||||||
->setAnchorName('toc')
|
->setAnchorName('toc')
|
||||||
->setNavigationMarker(true);
|
->setNavigationMarker(true);
|
||||||
|
|
||||||
return id(new PHUIObjectBoxView())
|
$header = id(new PHUIHeaderView())
|
||||||
->setHeaderText(pht('Table of Contents'))
|
->setHeader(pht('Table of Contents'));
|
||||||
|
|
||||||
|
if ($this->header) {
|
||||||
|
$header = $this->header;
|
||||||
|
}
|
||||||
|
|
||||||
|
$box = id(new PHUIObjectBoxView())
|
||||||
|
->setHeader($header)
|
||||||
|
->setBackground($this->background)
|
||||||
->setTable($table)
|
->setTable($table)
|
||||||
->appendChild($anchor)
|
->appendChild($anchor)
|
||||||
->appendChild($buttons);
|
->appendChild($buttons);
|
||||||
|
|
||||||
|
if ($this->infoView) {
|
||||||
|
$box->setInfoView($this->infoView);
|
||||||
|
}
|
||||||
|
return $box;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -494,6 +494,7 @@ final class PhabricatorMarkupEngine extends Phobject {
|
||||||
|
|
||||||
$rules[] = new PhabricatorIconRemarkupRule();
|
$rules[] = new PhabricatorIconRemarkupRule();
|
||||||
$rules[] = new PhabricatorEmojiRemarkupRule();
|
$rules[] = new PhabricatorEmojiRemarkupRule();
|
||||||
|
$rules[] = new PhabricatorHandleRemarkupRule();
|
||||||
|
|
||||||
$applications = PhabricatorApplication::getAllInstalledApplications();
|
$applications = PhabricatorApplication::getAllInstalledApplications();
|
||||||
foreach ($applications as $application) {
|
foreach ($applications as $application) {
|
||||||
|
|
|
@ -14,6 +14,7 @@ final class PHUIInfoView extends AphrontView {
|
||||||
private $id;
|
private $id;
|
||||||
private $buttons = array();
|
private $buttons = array();
|
||||||
private $isHidden;
|
private $isHidden;
|
||||||
|
private $flush;
|
||||||
|
|
||||||
public function setTitle($title) {
|
public function setTitle($title) {
|
||||||
$this->title = $title;
|
$this->title = $title;
|
||||||
|
@ -40,6 +41,11 @@ final class PHUIInfoView extends AphrontView {
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setFlush($flush) {
|
||||||
|
$this->flush = $flush;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function addButton(PHUIButtonView $button) {
|
public function addButton(PHUIButtonView $button) {
|
||||||
$this->buttons[] = $button;
|
$this->buttons[] = $button;
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -87,6 +93,9 @@ final class PHUIInfoView extends AphrontView {
|
||||||
$classes[] = 'phui-info-view';
|
$classes[] = 'phui-info-view';
|
||||||
$classes[] = 'phui-info-severity-'.$this->severity;
|
$classes[] = 'phui-info-severity-'.$this->severity;
|
||||||
$classes[] = 'grouped';
|
$classes[] = 'grouped';
|
||||||
|
if ($this->flush) {
|
||||||
|
$classes[] = 'phui-info-view-flush';
|
||||||
|
}
|
||||||
$classes = implode(' ', $classes);
|
$classes = implode(' ', $classes);
|
||||||
|
|
||||||
$children = $this->renderChildren();
|
$children = $this->renderChildren();
|
||||||
|
|
|
@ -263,6 +263,7 @@ final class PHUIPagedFormView extends AphrontView {
|
||||||
$form->appendChild($submit);
|
$form->appendChild($submit);
|
||||||
|
|
||||||
$box = id(new PHUIObjectBoxView())
|
$box = id(new PHUIObjectBoxView())
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->setFormErrors($errors)
|
->setFormErrors($errors)
|
||||||
->setForm($form);
|
->setForm($form);
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,9 @@ final class PHUIHeadThingView extends AphrontTagView {
|
||||||
|
|
||||||
$classes = array();
|
$classes = array();
|
||||||
$classes[] = 'phui-head-thing-view';
|
$classes[] = 'phui-head-thing-view';
|
||||||
|
if ($this->image) {
|
||||||
|
$classes[] = 'phui-head-has-image';
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->size) {
|
if ($this->size) {
|
||||||
$classes[] = $this->size;
|
$classes[] = $this->size;
|
||||||
|
@ -57,8 +60,11 @@ final class PHUIHeadThingView extends AphrontTagView {
|
||||||
'href' => $this->imageHref,
|
'href' => $this->imageHref,
|
||||||
));
|
));
|
||||||
|
|
||||||
|
if ($this->image) {
|
||||||
return array($image, $this->content);
|
return array($image, $this->content);
|
||||||
|
} else {
|
||||||
|
return $this->content;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -83,6 +83,26 @@ final class PhabricatorStartup {
|
||||||
* @task info
|
* @task info
|
||||||
*/
|
*/
|
||||||
public static function getRawInput() {
|
public static function getRawInput() {
|
||||||
|
if (self::$rawInput === null) {
|
||||||
|
$stream = new AphrontRequestStream();
|
||||||
|
|
||||||
|
if (isset($_SERVER['HTTP_CONTENT_ENCODING'])) {
|
||||||
|
$encoding = trim($_SERVER['HTTP_CONTENT_ENCODING']);
|
||||||
|
$stream->setEncoding($encoding);
|
||||||
|
}
|
||||||
|
|
||||||
|
$input = '';
|
||||||
|
do {
|
||||||
|
$bytes = $stream->readData();
|
||||||
|
if ($bytes === null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$input .= $bytes;
|
||||||
|
} while (true);
|
||||||
|
|
||||||
|
self::$rawInput = $input;
|
||||||
|
}
|
||||||
|
|
||||||
return self::$rawInput;
|
return self::$rawInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,47 +148,6 @@ final class PhabricatorStartup {
|
||||||
self::detectPostMaxSizeTriggered();
|
self::detectPostMaxSizeTriggered();
|
||||||
|
|
||||||
self::beginOutputCapture();
|
self::beginOutputCapture();
|
||||||
|
|
||||||
if (isset($_SERVER['HTTP_CONTENT_ENCODING'])) {
|
|
||||||
$encoding = trim($_SERVER['HTTP_CONTENT_ENCODING']);
|
|
||||||
} else {
|
|
||||||
$encoding = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$input_stream = fopen('php://input', 'rb');
|
|
||||||
if (!$input_stream) {
|
|
||||||
self::didFatal(
|
|
||||||
'Unable to open "php://input" to read HTTP request body.');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($encoding === 'gzip') {
|
|
||||||
$ok = stream_filter_append(
|
|
||||||
$input_stream,
|
|
||||||
'zlib.inflate',
|
|
||||||
STREAM_FILTER_READ,
|
|
||||||
array(
|
|
||||||
'window' => 30,
|
|
||||||
));
|
|
||||||
|
|
||||||
if (!$ok) {
|
|
||||||
self::didFatal(
|
|
||||||
'Failed to append gzip inflate filter to HTTP request body input '.
|
|
||||||
'stream.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$input_data = '';
|
|
||||||
while (!feof($input_stream)) {
|
|
||||||
$read_bytes = fread($input_stream, 16 * 1024);
|
|
||||||
if ($read_bytes === false) {
|
|
||||||
self::didFatal(
|
|
||||||
'Failed to read input bytes from HTTP request body.');
|
|
||||||
}
|
|
||||||
$input_data .= $read_bytes;
|
|
||||||
}
|
|
||||||
fclose($input_stream);
|
|
||||||
|
|
||||||
self::$rawInput = $input_data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
.differential-changeset {
|
.differential-changeset {
|
||||||
position: relative;
|
position: relative;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding-top: 32px;
|
padding-top: 16px;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
|
|
||||||
/* Fixes what seems to be a layout bug in Firefox which causes scrollbars,
|
/* Fixes what seems to be a layout bug in Firefox which causes scrollbars,
|
||||||
|
@ -265,7 +265,7 @@ td.cov-I {
|
||||||
|
|
||||||
.differential-changeset h1 {
|
.differential-changeset h1 {
|
||||||
font-size: {$biggestfontsize};
|
font-size: {$biggestfontsize};
|
||||||
padding: 2px 0 12px 12px;
|
padding: 2px 0 20px 12px;
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
color: #000;
|
color: #000;
|
||||||
}
|
}
|
||||||
|
@ -322,7 +322,7 @@ td.cov-I {
|
||||||
|
|
||||||
.differential-changeset-buttons {
|
.differential-changeset-buttons {
|
||||||
float: right;
|
float: right;
|
||||||
margin-right: 8px;
|
margin-right: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.device-phone .differential-changeset-buttons {
|
.device-phone .differential-changeset-buttons {
|
||||||
|
@ -362,3 +362,7 @@ tr.differential-inline-hidden {
|
||||||
tr.differential-inline-loading {
|
tr.differential-inline-loading {
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.differential-review-stage {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.differential-primary-pane {
|
.differential-primary-pane {
|
||||||
margin-bottom: 32px;
|
margin-top: -20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.differential-panel {
|
.differential-panel {
|
||||||
|
@ -23,3 +23,7 @@
|
||||||
-ms-user-select: none;
|
-ms-user-select: none;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.differential-content-hidden {
|
||||||
|
margin: 0 0 24px 0;
|
||||||
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue