1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-29 02:02:41 +01:00

(stable) Promote 2016 Week 11

This commit is contained in:
epriestley 2016-03-12 11:30:06 -08:00
commit fd72a2ff81
235 changed files with 6811 additions and 2417 deletions

View file

@ -61,7 +61,19 @@
"type": "spelling"
},
"text": {
"type": "text"
"type": "text",
"exclude": [
"(^src/(.*/)?__tests__/[^/]+/.*\\.(txt|json))"
]
},
"text-without-length": {
"type": "text",
"include": [
"(^src/(.*/)?__tests__/[^/]+/.*\\.(txt|json))"
],
"severity": {
"3": "disabled"
}
},
"xhpast": {
"type": "xhpast",

1
bin/nuance Symbolic link
View file

@ -0,0 +1 @@
../scripts/setup/manage_nuance.php

View file

@ -7,10 +7,10 @@
*/
return array(
'names' => array(
'core.pkg.css' => 'dd1447be',
'core.pkg.css' => '9c8e888d',
'core.pkg.js' => '7d8faf57',
'darkconsole.pkg.js' => 'e7393ebb',
'differential.pkg.css' => '2de124c9',
'differential.pkg.css' => '7d0a63a7',
'differential.pkg.js' => 'd0cd0df6',
'diffusion.pkg.css' => 'f45955ed',
'diffusion.pkg.js' => '3a9a8bfa',
@ -59,7 +59,7 @@ return array(
'rsrc/css/application/differential/add-comment.css' => 'c47f8c40',
'rsrc/css/application/differential/changeset-view.css' => 'b6b0d1bb',
'rsrc/css/application/differential/core.css' => '7ac3cabc',
'rsrc/css/application/differential/phui-inline-comment.css' => '0fdb3667',
'rsrc/css/application/differential/phui-inline-comment.css' => '5953c28e',
'rsrc/css/application/differential/revision-comment.css' => '14b8565a',
'rsrc/css/application/differential/revision-history.css' => '0e8eb855',
'rsrc/css/application/differential/revision-list.css' => 'f3c47d33',
@ -72,7 +72,7 @@ return array(
'rsrc/css/application/flag/flag.css' => '5337623f',
'rsrc/css/application/harbormaster/harbormaster.css' => '834879db',
'rsrc/css/application/herald/herald-test.css' => 'a52e323e',
'rsrc/css/application/herald/herald.css' => '46596280',
'rsrc/css/application/herald/herald.css' => 'dc31f6e9',
'rsrc/css/application/maniphest/batch-editor.css' => 'b0f0b6d5',
'rsrc/css/application/maniphest/report.css' => '9b9580b7',
'rsrc/css/application/maniphest/task-edit.css' => 'fda62a9b',
@ -111,7 +111,7 @@ return array(
'rsrc/css/font/font-aleo.css' => '8bdb2835',
'rsrc/css/font/font-awesome.css' => 'c43323c5',
'rsrc/css/font/font-lato.css' => 'c7ccd872',
'rsrc/css/font/phui-font-icon-base.css' => 'ecbbb4c2',
'rsrc/css/font/phui-font-icon-base.css' => '6449bce8',
'rsrc/css/layout/phabricator-filetree-view.css' => 'fccf9f82',
'rsrc/css/layout/phabricator-side-menu-view.css' => '3a3d9f41',
'rsrc/css/layout/phabricator-source-code-view.css' => 'cbeef983',
@ -123,10 +123,11 @@ return array(
'rsrc/css/phui/phui-action-panel.css' => '91c7b835',
'rsrc/css/phui/phui-badge.css' => 'f25c3476',
'rsrc/css/phui/phui-big-info-view.css' => 'bd903741',
'rsrc/css/phui/phui-box.css' => 'c9e01148',
'rsrc/css/phui/phui-box.css' => '3830ab21',
'rsrc/css/phui/phui-button.css' => 'a64a8de6',
'rsrc/css/phui/phui-chart.css' => '6bf6f78e',
'rsrc/css/phui/phui-crumbs-view.css' => '79d536e5',
'rsrc/css/phui/phui-curtain-view.css' => '7148ae25',
'rsrc/css/phui/phui-document-pro.css' => '92d5b648',
'rsrc/css/phui/phui-document-summary.css' => '9ca48bdf',
'rsrc/css/phui/phui-document.css' => '9c71d2bf',
@ -134,8 +135,8 @@ return array(
'rsrc/css/phui/phui-fontkit.css' => '9cda225e',
'rsrc/css/phui/phui-form-view.css' => '4a1a0f5e',
'rsrc/css/phui/phui-form.css' => 'aac1d51d',
'rsrc/css/phui/phui-head-thing.css' => '11731da0',
'rsrc/css/phui/phui-header-view.css' => 'fc4acf14',
'rsrc/css/phui/phui-head-thing.css' => '31638812',
'rsrc/css/phui/phui-header-view.css' => '26cffd3d',
'rsrc/css/phui/phui-hovercard.css' => 'de1a2119',
'rsrc/css/phui/phui-icon-set-selector.css' => '1ab67aad',
'rsrc/css/phui/phui-icon.css' => '3f33ab57',
@ -148,14 +149,14 @@ return array(
'rsrc/css/phui/phui-pager.css' => 'bea33d23',
'rsrc/css/phui/phui-pinboard-view.css' => '2495140e',
'rsrc/css/phui/phui-profile-menu.css' => '7e92a89a',
'rsrc/css/phui/phui-property-list-view.css' => '27b2849e',
'rsrc/css/phui/phui-property-list-view.css' => 'b12e801c',
'rsrc/css/phui/phui-remarkup-preview.css' => '1a8f2591',
'rsrc/css/phui/phui-segment-bar-view.css' => '46342871',
'rsrc/css/phui/phui-spacing.css' => '042804d6',
'rsrc/css/phui/phui-status.css' => '37309046',
'rsrc/css/phui/phui-tag-view.css' => '9d5d4400',
'rsrc/css/phui/phui-timeline-view.css' => '2efceff8',
'rsrc/css/phui/phui-two-column-view.css' => 'd0ad8c10',
'rsrc/css/phui/phui-tag-view.css' => '6bbd83e2',
'rsrc/css/phui/phui-timeline-view.css' => 'a0173eba',
'rsrc/css/phui/phui-two-column-view.css' => 'e6bf86b6',
'rsrc/css/phui/workboards/phui-workboard-color.css' => 'ac6fe6a7',
'rsrc/css/phui/workboards/phui-workboard.css' => 'e6d89647',
'rsrc/css/phui/workboards/phui-workcard.css' => '3646fb96',
@ -272,6 +273,7 @@ return array(
'rsrc/image/checker_dark.png' => 'd8e65881',
'rsrc/image/checker_light.png' => 'a0155918',
'rsrc/image/checker_lighter.png' => 'd5da91b6',
'rsrc/image/d5d8e1.png' => '0c2a1497',
'rsrc/image/darkload.gif' => '1ffd3ec6',
'rsrc/image/divot.png' => '94dded62',
'rsrc/image/examples/hero.png' => '979a86ae',
@ -419,7 +421,7 @@ return array(
'rsrc/js/application/policy/behavior-policy-rule-editor.js' => '5e9f347c',
'rsrc/js/application/projects/WorkboardBoard.js' => '52291776',
'rsrc/js/application/projects/WorkboardCard.js' => 'c587b80f',
'rsrc/js/application/projects/WorkboardColumn.js' => 'f05d6e5d',
'rsrc/js/application/projects/WorkboardColumn.js' => 'bae58312',
'rsrc/js/application/projects/WorkboardController.js' => '55baf5ed',
'rsrc/js/application/projects/behavior-project-boards.js' => '14a1faae',
'rsrc/js/application/projects/behavior-project-create.js' => '065227cc',
@ -560,7 +562,7 @@ return array(
'font-lato' => 'c7ccd872',
'global-drag-and-drop-css' => '5c1b47c2',
'harbormaster-css' => '834879db',
'herald-css' => '46596280',
'herald-css' => 'dc31f6e9',
'herald-rule-editor' => '746ca158',
'herald-test-css' => 'a52e323e',
'inline-comment-summary-css' => '51efda3a',
@ -730,7 +732,7 @@ return array(
'javelin-websocket' => 'e292eaf4',
'javelin-workboard-board' => '52291776',
'javelin-workboard-card' => 'c587b80f',
'javelin-workboard-column' => 'f05d6e5d',
'javelin-workboard-column' => 'bae58312',
'javelin-workboard-controller' => '55baf5ed',
'javelin-workflow' => '5b2e3e2b',
'lightbox-attachment-css' => '7acac05d',
@ -803,7 +805,7 @@ return array(
'phui-action-panel-css' => '91c7b835',
'phui-badge-view-css' => 'f25c3476',
'phui-big-info-view-css' => 'bd903741',
'phui-box-css' => 'c9e01148',
'phui-box-css' => '3830ab21',
'phui-button-css' => 'a64a8de6',
'phui-calendar-css' => 'ccabe893',
'phui-calendar-day-css' => 'd1cf6f93',
@ -811,16 +813,17 @@ return array(
'phui-calendar-month-css' => '476be7e0',
'phui-chart-css' => '6bf6f78e',
'phui-crumbs-view-css' => '79d536e5',
'phui-curtain-view-css' => '7148ae25',
'phui-document-summary-view-css' => '9ca48bdf',
'phui-document-view-css' => '9c71d2bf',
'phui-document-view-pro-css' => '92d5b648',
'phui-feed-story-css' => '04aec08f',
'phui-font-icon-base-css' => 'ecbbb4c2',
'phui-font-icon-base-css' => '6449bce8',
'phui-fontkit-css' => '9cda225e',
'phui-form-css' => 'aac1d51d',
'phui-form-view-css' => '4a1a0f5e',
'phui-head-thing-view-css' => '11731da0',
'phui-header-view-css' => 'fc4acf14',
'phui-head-thing-view-css' => '31638812',
'phui-header-view-css' => '26cffd3d',
'phui-hovercard' => '1bd28176',
'phui-hovercard-view-css' => 'de1a2119',
'phui-icon-set-selector-css' => '1ab67aad',
@ -828,22 +831,22 @@ return array(
'phui-image-mask-css' => 'a8498f9c',
'phui-info-panel-css' => '27ea50a1',
'phui-info-view-css' => '6d7c3509',
'phui-inline-comment-view-css' => '0fdb3667',
'phui-inline-comment-view-css' => '5953c28e',
'phui-list-view-css' => '9da2aa00',
'phui-object-box-css' => '91628842',
'phui-object-item-list-view-css' => '18b2ce8e',
'phui-pager-css' => 'bea33d23',
'phui-pinboard-view-css' => '2495140e',
'phui-profile-menu-css' => '7e92a89a',
'phui-property-list-view-css' => '27b2849e',
'phui-property-list-view-css' => 'b12e801c',
'phui-remarkup-preview-css' => '1a8f2591',
'phui-segment-bar-view-css' => '46342871',
'phui-spacing-css' => '042804d6',
'phui-status-list-view-css' => '37309046',
'phui-tag-view-css' => '9d5d4400',
'phui-tag-view-css' => '6bbd83e2',
'phui-theme-css' => '027ba77e',
'phui-timeline-view-css' => '2efceff8',
'phui-two-column-view-css' => 'd0ad8c10',
'phui-timeline-view-css' => 'a0173eba',
'phui-two-column-view-css' => 'e6bf86b6',
'phui-workboard-color-css' => 'ac6fe6a7',
'phui-workboard-view-css' => 'e6d89647',
'phui-workcard-view-css' => '3646fb96',
@ -1791,6 +1794,10 @@ return array(
'b6b0d1bb' => array(
'phui-inline-comment-view-css',
),
'bae58312' => array(
'javelin-install',
'javelin-workboard-card',
),
'bcaccd64' => array(
'javelin-behavior',
'javelin-behavior-device',
@ -2059,10 +2066,6 @@ return array(
'javelin-workflow',
'javelin-json',
),
'f05d6e5d' => array(
'javelin-install',
'javelin-workboard-card',
),
'f411b6ae' => array(
'javelin-behavior',
'javelin-stratcom',

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_nuance.nuance_source
ADD isDisabled BOOL NOT NULL;

View file

@ -0,0 +1,12 @@
CREATE TABLE {$NAMESPACE}_nuance.nuance_importcursordata (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
phid VARBINARY(64) NOT NULL,
sourcePHID VARBINARY(64) NOT NULL,
cursorKey VARCHAR(32) NOT NULL COLLATE {$COLLATE_TEXT},
cursorType VARCHAR(32) NOT NULL COLLATE {$COLLATE_TEXT},
properties LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT},
dateCreated INT UNSIGNED NOT NULL,
dateModified INT UNSIGNED NOT NULL,
UNIQUE KEY `key_phid` (phid),
UNIQUE KEY `key_source` (sourcePHID, cursorKey)
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};

View file

@ -0,0 +1,7 @@
CREATE TABLE {$NAMESPACE}_nuance.nuance_sourcename_ngrams (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
objectID INT UNSIGNED NOT NULL,
ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT},
KEY `key_object` (objectID),
KEY `key_ngram` (ngram, objectID)
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};

View file

@ -0,0 +1,11 @@
<?php
$table = new NuanceSource();
foreach (new LiskMigrationIterator($table) as $source) {
PhabricatorSearchWorker::queueDocumentForIndexing(
$source->getPHID(),
array(
'force' => true,
));
}

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_nuance.nuance_source
CHANGE name name VARCHAR(255) NOT NULL COLLATE {$COLLATE_SORT};

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_nuance.nuance_item
DROP sourceLabel;

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_nuance.nuance_item
ADD itemType VARCHAR(64) NOT NULL COLLATE {$COLLATE_TEXT};

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_nuance.nuance_item
ADD itemKey VARCHAR(64) NOT NULL COLLATE {$COLLATE_TEXT};

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_nuance.nuance_item
ADD itemContainerKey VARCHAR(64) COLLATE {$COLLATE_TEXT};

View file

@ -0,0 +1,2 @@
UPDATE {$NAMESPACE}_nuance.nuance_item
SET itemKey = id WHERE itemKey = '';

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_nuance.nuance_item
CHANGE requestorPHID requestorPHID VARBINARY(64);

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_nuance.nuance_item
CHANGE queuePHID queuePHID VARBINARY(64);

21
scripts/setup/manage_nuance.php Executable file
View file

@ -0,0 +1,21 @@
#!/usr/bin/env php
<?php
$root = dirname(dirname(dirname(__FILE__)));
require_once $root.'/scripts/__init_script__.php';
$args = new PhutilArgumentParser($argv);
$args->setTagline(pht('manage Nuance'));
$args->setSynopsis(<<<EOSYNOPSIS
**nuance** __command__ [__options__]
Manage and debug Nuance.
EOSYNOPSIS
);
$args->parseStandardArguments();
$workflows = id(new PhutilClassMapQuery())
->setAncestorClass('NuanceManagementWorkflow')
->execute();
$workflows[] = new PhutilHelpArgumentWorkflow();
$args->parseWorkflows($workflows);

View file

@ -840,6 +840,8 @@ phutil_register_library_map(array(
'DoorkeeperAsanaRemarkupRule' => 'applications/doorkeeper/remarkup/DoorkeeperAsanaRemarkupRule.php',
'DoorkeeperBridge' => 'applications/doorkeeper/bridge/DoorkeeperBridge.php',
'DoorkeeperBridgeAsana' => 'applications/doorkeeper/bridge/DoorkeeperBridgeAsana.php',
'DoorkeeperBridgeGitHub' => 'applications/doorkeeper/bridge/DoorkeeperBridgeGitHub.php',
'DoorkeeperBridgeGitHubIssue' => 'applications/doorkeeper/bridge/DoorkeeperBridgeGitHubIssue.php',
'DoorkeeperBridgeJIRA' => 'applications/doorkeeper/bridge/DoorkeeperBridgeJIRA.php',
'DoorkeeperBridgeJIRATestCase' => 'applications/doorkeeper/bridge/__tests__/DoorkeeperBridgeJIRATestCase.php',
'DoorkeeperDAO' => 'applications/doorkeeper/storage/DoorkeeperDAO.php',
@ -886,7 +888,7 @@ phutil_register_library_map(array(
'DrydockBlueprintTransactionQuery' => 'applications/drydock/query/DrydockBlueprintTransactionQuery.php',
'DrydockBlueprintViewController' => 'applications/drydock/controller/DrydockBlueprintViewController.php',
'DrydockCommand' => 'applications/drydock/storage/DrydockCommand.php',
'DrydockCommandError' => 'applications/drydock/DrydockCommandError/DrydockCommandError.php',
'DrydockCommandError' => 'applications/drydock/exception/DrydockCommandError.php',
'DrydockCommandInterface' => 'applications/drydock/interface/command/DrydockCommandInterface.php',
'DrydockCommandQuery' => 'applications/drydock/query/DrydockCommandQuery.php',
'DrydockConsoleController' => 'applications/drydock/controller/DrydockConsoleController.php',
@ -1419,22 +1421,42 @@ phutil_register_library_map(array(
'NuanceConduitAPIMethod' => 'applications/nuance/conduit/NuanceConduitAPIMethod.php',
'NuanceConsoleController' => 'applications/nuance/controller/NuanceConsoleController.php',
'NuanceController' => 'applications/nuance/controller/NuanceController.php',
'NuanceCreateItemConduitAPIMethod' => 'applications/nuance/conduit/NuanceCreateItemConduitAPIMethod.php',
'NuanceDAO' => 'applications/nuance/storage/NuanceDAO.php',
'NuanceGitHubEventItemType' => 'applications/nuance/item/NuanceGitHubEventItemType.php',
'NuanceGitHubImportCursor' => 'applications/nuance/cursor/NuanceGitHubImportCursor.php',
'NuanceGitHubIssuesImportCursor' => 'applications/nuance/cursor/NuanceGitHubIssuesImportCursor.php',
'NuanceGitHubRawEvent' => 'applications/nuance/github/NuanceGitHubRawEvent.php',
'NuanceGitHubRawEventTestCase' => 'applications/nuance/github/__tests__/NuanceGitHubRawEventTestCase.php',
'NuanceGitHubRepositoryImportCursor' => 'applications/nuance/cursor/NuanceGitHubRepositoryImportCursor.php',
'NuanceGitHubRepositorySourceDefinition' => 'applications/nuance/source/NuanceGitHubRepositorySourceDefinition.php',
'NuanceImportCursor' => 'applications/nuance/cursor/NuanceImportCursor.php',
'NuanceImportCursorData' => 'applications/nuance/storage/NuanceImportCursorData.php',
'NuanceImportCursorDataQuery' => 'applications/nuance/query/NuanceImportCursorDataQuery.php',
'NuanceImportCursorPHIDType' => 'applications/nuance/phid/NuanceImportCursorPHIDType.php',
'NuanceItem' => 'applications/nuance/storage/NuanceItem.php',
'NuanceItemEditController' => 'applications/nuance/controller/NuanceItemEditController.php',
'NuanceItemController' => 'applications/nuance/controller/NuanceItemController.php',
'NuanceItemEditor' => 'applications/nuance/editor/NuanceItemEditor.php',
'NuanceItemListController' => 'applications/nuance/controller/NuanceItemListController.php',
'NuanceItemManageController' => 'applications/nuance/controller/NuanceItemManageController.php',
'NuanceItemPHIDType' => 'applications/nuance/phid/NuanceItemPHIDType.php',
'NuanceItemQuery' => 'applications/nuance/query/NuanceItemQuery.php',
'NuanceItemSearchEngine' => 'applications/nuance/query/NuanceItemSearchEngine.php',
'NuanceItemTransaction' => 'applications/nuance/storage/NuanceItemTransaction.php',
'NuanceItemTransactionComment' => 'applications/nuance/storage/NuanceItemTransactionComment.php',
'NuanceItemTransactionQuery' => 'applications/nuance/query/NuanceItemTransactionQuery.php',
'NuanceItemType' => 'applications/nuance/item/NuanceItemType.php',
'NuanceItemUpdateWorker' => 'applications/nuance/worker/NuanceItemUpdateWorker.php',
'NuanceItemViewController' => 'applications/nuance/controller/NuanceItemViewController.php',
'NuanceManagementImportWorkflow' => 'applications/nuance/management/NuanceManagementImportWorkflow.php',
'NuanceManagementUpdateWorkflow' => 'applications/nuance/management/NuanceManagementUpdateWorkflow.php',
'NuanceManagementWorkflow' => 'applications/nuance/management/NuanceManagementWorkflow.php',
'NuancePhabricatorFormSourceDefinition' => 'applications/nuance/source/NuancePhabricatorFormSourceDefinition.php',
'NuanceQuery' => 'applications/nuance/query/NuanceQuery.php',
'NuanceQueue' => 'applications/nuance/storage/NuanceQueue.php',
'NuanceQueueController' => 'applications/nuance/controller/NuanceQueueController.php',
'NuanceQueueDatasource' => 'applications/nuance/typeahead/NuanceQueueDatasource.php',
'NuanceQueueEditController' => 'applications/nuance/controller/NuanceQueueEditController.php',
'NuanceQueueEditEngine' => 'applications/nuance/editor/NuanceQueueEditEngine.php',
'NuanceQueueEditor' => 'applications/nuance/editor/NuanceQueueEditor.php',
'NuanceQueueListController' => 'applications/nuance/controller/NuanceQueueListController.php',
'NuanceQueuePHIDType' => 'applications/nuance/phid/NuanceQueuePHIDType.php',
@ -1457,15 +1479,17 @@ phutil_register_library_map(array(
'NuanceSchemaSpec' => 'applications/nuance/storage/NuanceSchemaSpec.php',
'NuanceSource' => 'applications/nuance/storage/NuanceSource.php',
'NuanceSourceActionController' => 'applications/nuance/controller/NuanceSourceActionController.php',
'NuanceSourceCreateController' => 'applications/nuance/controller/NuanceSourceCreateController.php',
'NuanceSourceController' => 'applications/nuance/controller/NuanceSourceController.php',
'NuanceSourceDefaultEditCapability' => 'applications/nuance/capability/NuanceSourceDefaultEditCapability.php',
'NuanceSourceDefaultViewCapability' => 'applications/nuance/capability/NuanceSourceDefaultViewCapability.php',
'NuanceSourceDefinition' => 'applications/nuance/source/NuanceSourceDefinition.php',
'NuanceSourceDefinitionTestCase' => 'applications/nuance/source/__tests__/NuanceSourceDefinitionTestCase.php',
'NuanceSourceEditController' => 'applications/nuance/controller/NuanceSourceEditController.php',
'NuanceSourceEditEngine' => 'applications/nuance/editor/NuanceSourceEditEngine.php',
'NuanceSourceEditor' => 'applications/nuance/editor/NuanceSourceEditor.php',
'NuanceSourceListController' => 'applications/nuance/controller/NuanceSourceListController.php',
'NuanceSourceManageCapability' => 'applications/nuance/capability/NuanceSourceManageCapability.php',
'NuanceSourceNameNgrams' => 'applications/nuance/storage/NuanceSourceNameNgrams.php',
'NuanceSourcePHIDType' => 'applications/nuance/phid/NuanceSourcePHIDType.php',
'NuanceSourceQuery' => 'applications/nuance/query/NuanceSourceQuery.php',
'NuanceSourceSearchEngine' => 'applications/nuance/query/NuanceSourceSearchEngine.php',
@ -1474,6 +1498,7 @@ phutil_register_library_map(array(
'NuanceSourceTransactionQuery' => 'applications/nuance/query/NuanceSourceTransactionQuery.php',
'NuanceSourceViewController' => 'applications/nuance/controller/NuanceSourceViewController.php',
'NuanceTransaction' => 'applications/nuance/storage/NuanceTransaction.php',
'NuanceWorker' => 'applications/nuance/worker/NuanceWorker.php',
'OwnersConduitAPIMethod' => 'applications/owners/conduit/OwnersConduitAPIMethod.php',
'OwnersEditConduitAPIMethod' => 'applications/owners/conduit/OwnersEditConduitAPIMethod.php',
'OwnersPackageReplyHandler' => 'applications/owners/mail/OwnersPackageReplyHandler.php',
@ -1505,6 +1530,9 @@ phutil_register_library_map(array(
'PHUIColorPalletteExample' => 'applications/uiexample/examples/PHUIColorPalletteExample.php',
'PHUICrumbView' => 'view/phui/PHUICrumbView.php',
'PHUICrumbsView' => 'view/phui/PHUICrumbsView.php',
'PHUICurtainExtension' => 'view/extension/PHUICurtainExtension.php',
'PHUICurtainPanelView' => 'view/layout/PHUICurtainPanelView.php',
'PHUICurtainView' => 'view/layout/PHUICurtainView.php',
'PHUIDiffInlineCommentDetailView' => 'infrastructure/diff/view/PHUIDiffInlineCommentDetailView.php',
'PHUIDiffInlineCommentEditView' => 'infrastructure/diff/view/PHUIDiffInlineCommentEditView.php',
'PHUIDiffInlineCommentRowScaffold' => 'infrastructure/diff/view/PHUIDiffInlineCommentRowScaffold.php',
@ -3011,6 +3039,7 @@ phutil_register_library_map(array(
'PhabricatorProjectWatcherListView' => 'applications/project/view/PhabricatorProjectWatcherListView.php',
'PhabricatorProjectWorkboardBackgroundColor' => 'applications/project/constants/PhabricatorProjectWorkboardBackgroundColor.php',
'PhabricatorProjectWorkboardProfilePanel' => 'applications/project/profilepanel/PhabricatorProjectWorkboardProfilePanel.php',
'PhabricatorProjectsCurtainExtension' => 'applications/project/engineextension/PhabricatorProjectsCurtainExtension.php',
'PhabricatorProjectsEditEngineExtension' => 'applications/project/engineextension/PhabricatorProjectsEditEngineExtension.php',
'PhabricatorProjectsEditField' => 'applications/transactions/editfield/PhabricatorProjectsEditField.php',
'PhabricatorProjectsFulltextEngineExtension' => 'applications/project/engineextension/PhabricatorProjectsFulltextEngineExtension.php',
@ -3320,6 +3349,7 @@ phutil_register_library_map(array(
'PhabricatorSubscriptionsAddSelfHeraldAction' => 'applications/subscriptions/herald/PhabricatorSubscriptionsAddSelfHeraldAction.php',
'PhabricatorSubscriptionsAddSubscribersHeraldAction' => 'applications/subscriptions/herald/PhabricatorSubscriptionsAddSubscribersHeraldAction.php',
'PhabricatorSubscriptionsApplication' => 'applications/subscriptions/application/PhabricatorSubscriptionsApplication.php',
'PhabricatorSubscriptionsCurtainExtension' => 'applications/subscriptions/engineextension/PhabricatorSubscriptionsCurtainExtension.php',
'PhabricatorSubscriptionsEditController' => 'applications/subscriptions/controller/PhabricatorSubscriptionsEditController.php',
'PhabricatorSubscriptionsEditEngineExtension' => 'applications/subscriptions/engineextension/PhabricatorSubscriptionsEditEngineExtension.php',
'PhabricatorSubscriptionsEditor' => 'applications/subscriptions/editor/PhabricatorSubscriptionsEditor.php',
@ -3388,6 +3418,7 @@ phutil_register_library_map(array(
'PhabricatorTokenUIEventListener' => 'applications/tokens/event/PhabricatorTokenUIEventListener.php',
'PhabricatorTokenizerEditField' => 'applications/transactions/editfield/PhabricatorTokenizerEditField.php',
'PhabricatorTokensApplication' => 'applications/tokens/application/PhabricatorTokensApplication.php',
'PhabricatorTokensCurtainExtension' => 'applications/tokens/engineextension/PhabricatorTokensCurtainExtension.php',
'PhabricatorTokensSettingsPanel' => 'applications/settings/panel/PhabricatorTokensSettingsPanel.php',
'PhabricatorTooltipUIExample' => 'applications/uiexample/examples/PhabricatorTooltipUIExample.php',
'PhabricatorTransactions' => 'applications/transactions/constants/PhabricatorTransactions.php',
@ -3763,6 +3794,7 @@ phutil_register_library_map(array(
'PhragmentZIPController' => 'applications/phragment/controller/PhragmentZIPController.php',
'PhrequentConduitAPIMethod' => 'applications/phrequent/conduit/PhrequentConduitAPIMethod.php',
'PhrequentController' => 'applications/phrequent/controller/PhrequentController.php',
'PhrequentCurtainExtension' => 'applications/phrequent/engineextension/PhrequentCurtainExtension.php',
'PhrequentDAO' => 'applications/phrequent/storage/PhrequentDAO.php',
'PhrequentListController' => 'applications/phrequent/controller/PhrequentListController.php',
'PhrequentPopConduitAPIMethod' => 'applications/phrequent/conduit/PhrequentPopConduitAPIMethod.php',
@ -4943,6 +4975,8 @@ phutil_register_library_map(array(
'DoorkeeperAsanaRemarkupRule' => 'DoorkeeperRemarkupRule',
'DoorkeeperBridge' => 'Phobject',
'DoorkeeperBridgeAsana' => 'DoorkeeperBridge',
'DoorkeeperBridgeGitHub' => 'DoorkeeperBridge',
'DoorkeeperBridgeGitHubIssue' => 'DoorkeeperBridgeGitHub',
'DoorkeeperBridgeJIRA' => 'DoorkeeperBridge',
'DoorkeeperBridgeJIRATestCase' => 'PhabricatorTestCase',
'DoorkeeperDAO' => 'PhabricatorLiskDAO',
@ -5008,6 +5042,7 @@ phutil_register_library_map(array(
'DrydockDAO',
'PhabricatorPolicyInterface',
),
'DrydockCommandError' => 'Phobject',
'DrydockCommandInterface' => 'DrydockInterface',
'DrydockCommandQuery' => 'DrydockQuery',
'DrydockConsoleController' => 'DrydockController',
@ -5649,21 +5684,42 @@ phutil_register_library_map(array(
'NuanceConduitAPIMethod' => 'ConduitAPIMethod',
'NuanceConsoleController' => 'NuanceController',
'NuanceController' => 'PhabricatorController',
'NuanceCreateItemConduitAPIMethod' => 'NuanceConduitAPIMethod',
'NuanceDAO' => 'PhabricatorLiskDAO',
'NuanceGitHubEventItemType' => 'NuanceItemType',
'NuanceGitHubImportCursor' => 'NuanceImportCursor',
'NuanceGitHubIssuesImportCursor' => 'NuanceGitHubImportCursor',
'NuanceGitHubRawEvent' => 'Phobject',
'NuanceGitHubRawEventTestCase' => 'PhabricatorTestCase',
'NuanceGitHubRepositoryImportCursor' => 'NuanceGitHubImportCursor',
'NuanceGitHubRepositorySourceDefinition' => 'NuanceSourceDefinition',
'NuanceImportCursor' => 'Phobject',
'NuanceImportCursorData' => array(
'NuanceDAO',
'PhabricatorPolicyInterface',
),
'NuanceImportCursorDataQuery' => 'NuanceQuery',
'NuanceImportCursorPHIDType' => 'PhabricatorPHIDType',
'NuanceItem' => array(
'NuanceDAO',
'PhabricatorPolicyInterface',
'PhabricatorApplicationTransactionInterface',
),
'NuanceItemEditController' => 'NuanceController',
'NuanceItemController' => 'NuanceController',
'NuanceItemEditor' => 'PhabricatorApplicationTransactionEditor',
'NuanceItemListController' => 'NuanceItemController',
'NuanceItemManageController' => 'NuanceController',
'NuanceItemPHIDType' => 'PhabricatorPHIDType',
'NuanceItemQuery' => 'NuanceQuery',
'NuanceItemSearchEngine' => 'PhabricatorApplicationSearchEngine',
'NuanceItemTransaction' => 'NuanceTransaction',
'NuanceItemTransactionComment' => 'PhabricatorApplicationTransactionComment',
'NuanceItemTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'NuanceItemType' => 'Phobject',
'NuanceItemUpdateWorker' => 'NuanceWorker',
'NuanceItemViewController' => 'NuanceController',
'NuanceManagementImportWorkflow' => 'NuanceManagementWorkflow',
'NuanceManagementUpdateWorkflow' => 'NuanceManagementWorkflow',
'NuanceManagementWorkflow' => 'PhabricatorManagementWorkflow',
'NuancePhabricatorFormSourceDefinition' => 'NuanceSourceDefinition',
'NuanceQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'NuanceQueue' => array(
@ -5671,17 +5727,19 @@ phutil_register_library_map(array(
'PhabricatorPolicyInterface',
'PhabricatorApplicationTransactionInterface',
),
'NuanceQueueController' => 'NuanceController',
'NuanceQueueDatasource' => 'PhabricatorTypeaheadDatasource',
'NuanceQueueEditController' => 'NuanceController',
'NuanceQueueEditController' => 'NuanceQueueController',
'NuanceQueueEditEngine' => 'PhabricatorEditEngine',
'NuanceQueueEditor' => 'PhabricatorApplicationTransactionEditor',
'NuanceQueueListController' => 'NuanceController',
'NuanceQueueListController' => 'NuanceQueueController',
'NuanceQueuePHIDType' => 'PhabricatorPHIDType',
'NuanceQueueQuery' => 'NuanceQuery',
'NuanceQueueSearchEngine' => 'PhabricatorApplicationSearchEngine',
'NuanceQueueTransaction' => 'NuanceTransaction',
'NuanceQueueTransactionComment' => 'PhabricatorApplicationTransactionComment',
'NuanceQueueTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'NuanceQueueViewController' => 'NuanceController',
'NuanceQueueViewController' => 'NuanceQueueController',
'NuanceRequestor' => array(
'NuanceDAO',
'PhabricatorPolicyInterface',
@ -5701,25 +5759,29 @@ phutil_register_library_map(array(
'NuanceDAO',
'PhabricatorApplicationTransactionInterface',
'PhabricatorPolicyInterface',
'PhabricatorNgramsInterface',
),
'NuanceSourceActionController' => 'NuanceController',
'NuanceSourceCreateController' => 'NuanceController',
'NuanceSourceController' => 'NuanceController',
'NuanceSourceDefaultEditCapability' => 'PhabricatorPolicyCapability',
'NuanceSourceDefaultViewCapability' => 'PhabricatorPolicyCapability',
'NuanceSourceDefinition' => 'Phobject',
'NuanceSourceDefinitionTestCase' => 'PhabricatorTestCase',
'NuanceSourceEditController' => 'NuanceController',
'NuanceSourceEditController' => 'NuanceSourceController',
'NuanceSourceEditEngine' => 'PhabricatorEditEngine',
'NuanceSourceEditor' => 'PhabricatorApplicationTransactionEditor',
'NuanceSourceListController' => 'NuanceController',
'NuanceSourceListController' => 'NuanceSourceController',
'NuanceSourceManageCapability' => 'PhabricatorPolicyCapability',
'NuanceSourceNameNgrams' => 'PhabricatorSearchNgrams',
'NuanceSourcePHIDType' => 'PhabricatorPHIDType',
'NuanceSourceQuery' => 'NuanceQuery',
'NuanceSourceSearchEngine' => 'PhabricatorApplicationSearchEngine',
'NuanceSourceTransaction' => 'NuanceTransaction',
'NuanceSourceTransactionComment' => 'PhabricatorApplicationTransactionComment',
'NuanceSourceTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'NuanceSourceViewController' => 'NuanceController',
'NuanceSourceViewController' => 'NuanceSourceController',
'NuanceTransaction' => 'PhabricatorApplicationTransaction',
'NuanceWorker' => 'PhabricatorWorker',
'OwnersConduitAPIMethod' => 'ConduitAPIMethod',
'OwnersEditConduitAPIMethod' => 'PhabricatorEditEngineAPIMethod',
'OwnersPackageReplyHandler' => 'PhabricatorMailReplyHandler',
@ -5751,6 +5813,9 @@ phutil_register_library_map(array(
'PHUIColorPalletteExample' => 'PhabricatorUIExample',
'PHUICrumbView' => 'AphrontView',
'PHUICrumbsView' => 'AphrontView',
'PHUICurtainExtension' => 'Phobject',
'PHUICurtainPanelView' => 'AphrontTagView',
'PHUICurtainView' => 'AphrontTagView',
'PHUIDiffInlineCommentDetailView' => 'PHUIDiffInlineCommentView',
'PHUIDiffInlineCommentEditView' => 'PHUIDiffInlineCommentView',
'PHUIDiffInlineCommentRowScaffold' => 'AphrontView',
@ -7503,6 +7568,7 @@ phutil_register_library_map(array(
'PhabricatorProjectWatcherListView' => 'PhabricatorProjectUserListView',
'PhabricatorProjectWorkboardBackgroundColor' => 'Phobject',
'PhabricatorProjectWorkboardProfilePanel' => 'PhabricatorProfilePanel',
'PhabricatorProjectsCurtainExtension' => 'PHUICurtainExtension',
'PhabricatorProjectsEditEngineExtension' => 'PhabricatorEditEngineExtension',
'PhabricatorProjectsEditField' => 'PhabricatorTokenizerEditField',
'PhabricatorProjectsFulltextEngineExtension' => 'PhabricatorFulltextEngineExtension',
@ -7872,6 +7938,7 @@ phutil_register_library_map(array(
'PhabricatorSubscriptionsAddSelfHeraldAction' => 'PhabricatorSubscriptionsHeraldAction',
'PhabricatorSubscriptionsAddSubscribersHeraldAction' => 'PhabricatorSubscriptionsHeraldAction',
'PhabricatorSubscriptionsApplication' => 'PhabricatorApplication',
'PhabricatorSubscriptionsCurtainExtension' => 'PHUICurtainExtension',
'PhabricatorSubscriptionsEditController' => 'PhabricatorController',
'PhabricatorSubscriptionsEditEngineExtension' => 'PhabricatorEditEngineExtension',
'PhabricatorSubscriptionsEditor' => 'PhabricatorEditor',
@ -7945,6 +8012,7 @@ phutil_register_library_map(array(
'PhabricatorTokenUIEventListener' => 'PhabricatorEventListener',
'PhabricatorTokenizerEditField' => 'PhabricatorPHIDListEditField',
'PhabricatorTokensApplication' => 'PhabricatorApplication',
'PhabricatorTokensCurtainExtension' => 'PHUICurtainExtension',
'PhabricatorTokensSettingsPanel' => 'PhabricatorSettingsPanel',
'PhabricatorTooltipUIExample' => 'PhabricatorUIExample',
'PhabricatorTransactions' => 'Phobject',
@ -8431,6 +8499,7 @@ phutil_register_library_map(array(
'PhragmentZIPController' => 'PhragmentController',
'PhrequentConduitAPIMethod' => 'ConduitAPIMethod',
'PhrequentController' => 'PhabricatorController',
'PhrequentCurtainExtension' => 'PHUICurtainExtension',
'PhrequentDAO' => 'PhabricatorLiskDAO',
'PhrequentListController' => 'PhrequentController',
'PhrequentPopConduitAPIMethod' => 'PhrequentConduitAPIMethod',

View file

@ -26,26 +26,23 @@ final class AlmanacBindingViewController
$title = pht('Binding %s', $binding->getID());
$property_list = $this->buildPropertyList($binding);
$action_list = $this->buildActionList($binding);
$property_list->setActionList($action_list);
$properties = $this->buildPropertyList($binding);
$details = $this->buildPropertySection($binding);
$curtain = $this->buildCurtain($binding);
$header = id(new PHUIHeaderView())
->setUser($viewer)
->setHeader($title)
->setPolicyObject($binding);
->setPolicyObject($binding)
->setHeaderIcon('fa-object-group');
if ($binding->getIsDisabled()) {
$header->setStatus('fa-ban', 'red', pht('Disabled'));
}
$box = id(new PHUIObjectBoxView())
->setHeader($header)
->addPropertyList($property_list);
$issue = null;
if ($binding->getService()->isClusterService()) {
$this->addClusterMessage(
$box,
$issue = $this->addClusterMessage(
pht('The service for this binding is a cluster service.'),
pht(
'The service for this binding is a cluster service. You do not '.
@ -56,24 +53,33 @@ final class AlmanacBindingViewController
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb($service->getName(), $service_uri);
$crumbs->addTextCrumb($title);
$crumbs->setBorder(true);
$timeline = $this->buildTransactionTimeline(
$binding,
new AlmanacBindingTransactionQuery());
$timeline->setShouldTerminate(true);
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setCurtain($curtain)
->setMainColumn(array(
$issue,
$this->buildAlmanacPropertiesTable($binding),
$timeline,
))
->addPropertySection(pht('DETAILS'), $details);
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild(
array(
$box,
$this->buildAlmanacPropertiesTable($binding),
$timeline,
$view,
));
}
private function buildPropertyList(AlmanacBinding $binding) {
private function buildPropertySection(AlmanacBinding $binding) {
$viewer = $this->getViewer();
$properties = id(new PHUIPropertyListView())
@ -98,23 +104,36 @@ final class AlmanacBindingViewController
return $properties;
}
private function buildActionList(AlmanacBinding $binding) {
private function buildPropertyList(AlmanacBinding $binding) {
$viewer = $this->getViewer();
$properties = id(new PHUIPropertyListView())
->setUser($viewer)
->setObject($binding);
$properties->invokeWillRenderEvent();
return $properties;
}
private function buildCurtain(AlmanacBinding $binding) {
$viewer = $this->getViewer();
$id = $binding->getID();
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$binding,
PhabricatorPolicyCapability::CAN_EDIT);
$actions = id(new PhabricatorActionListView())
->setUser($viewer);
$id = $binding->getID();
$edit_uri = $this->getApplicationURI("binding/edit/{$id}/");
$disable_uri = $this->getApplicationURI("binding/disable/{$id}/");
$actions->addAction(
$curtain = $this->newCurtainView($binding);
$curtain->addAction(
id(new PhabricatorActionView())
->setIcon('fa-pencil')
->setName(pht('Edit Binding'))
->setHref($this->getApplicationURI("binding/edit/{$id}/"))
->setHref($edit_uri)
->setWorkflow(!$can_edit)
->setDisabled(!$can_edit));
@ -126,17 +145,15 @@ final class AlmanacBindingViewController
$disable_text = pht('Disable Binding');
}
$disable_href = $this->getApplicationURI("binding/disable/{$id}/");
$actions->addAction(
$curtain->addAction(
id(new PhabricatorActionView())
->setIcon($disable_icon)
->setName($disable_text)
->setHref($disable_href)
->setHref($disable_uri)
->setWorkflow(true)
->setDisabled(!$can_edit));
return $actions;
return $curtain;
}
}

View file

@ -23,8 +23,7 @@ final class AlmanacDeviceViewController
$title = pht('Device %s', $device->getName());
$properties = $this->buildPropertyList($device);
$actions = $this->buildActionList($device);
$curtain = $this->buildCurtain($device);
$header = id(new PHUIHeaderView())
->setUser($viewer)
@ -55,6 +54,7 @@ final class AlmanacDeviceViewController
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setCurtain($curtain)
->setMainColumn(array(
$issue,
$interfaces,
@ -62,9 +62,7 @@ final class AlmanacDeviceViewController
$this->buildSSHKeysTable($device),
$this->buildServicesTable($device),
$timeline,
))
->setPropertyList($properties)
->setActionList($actions);
));
return $this->newPage()
->setTitle($title)
@ -75,37 +73,28 @@ final class AlmanacDeviceViewController
));
}
private function buildPropertyList(AlmanacDevice $device) {
private function buildCurtain(AlmanacDevice $device) {
$viewer = $this->getViewer();
$properties = id(new PHUIPropertyListView())
->setUser($viewer)
->setObject($device);
return $properties;
}
private function buildActionList(AlmanacDevice $device) {
$viewer = $this->getViewer();
$id = $device->getID();
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$device,
PhabricatorPolicyCapability::CAN_EDIT);
$actions = id(new PhabricatorActionListView())
->setUser($viewer);
$id = $device->getID();
$edit_uri = $this->getApplicationURI("device/edit/{$id}/");
$actions->addAction(
$curtain = $this->newCurtainView($device);
$curtain->addAction(
id(new PhabricatorActionView())
->setIcon('fa-pencil')
->setName(pht('Edit Device'))
->setHref($this->getApplicationURI("device/edit/{$id}/"))
->setHref($edit_uri)
->setWorkflow(!$can_edit)
->setDisabled(!$can_edit));
return $actions;
return $curtain;
}
private function buildInterfaceList(AlmanacDevice $device) {

View file

@ -21,8 +21,7 @@ final class AlmanacNamespaceViewController
$title = pht('Namespace %s', $namespace->getName());
$properties = $this->buildPropertyList($namespace);
$actions = $this->buildActionList($namespace);
$curtain = $this->buildCurtain($namespace);
$header = id(new PHUIHeaderView())
->setUser($viewer)
@ -41,11 +40,10 @@ final class AlmanacNamespaceViewController
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setCurtain($curtain)
->setMainColumn(array(
$timeline,
))
->setPropertyList($properties)
->setActionList($actions);
));
return $this->newPage()
->setTitle($title)
@ -56,39 +54,28 @@ final class AlmanacNamespaceViewController
));
}
private function buildPropertyList(AlmanacNamespace $namespace) {
private function buildCurtain(AlmanacNamespace $namespace) {
$viewer = $this->getViewer();
$properties = id(new PHUIPropertyListView())
->setUser($viewer)
->setObject($namespace);
$properties->invokeWillRenderEvent();
return $properties;
}
private function buildActionList(AlmanacNamespace $namespace) {
$viewer = $this->getViewer();
$id = $namespace->getID();
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$namespace,
PhabricatorPolicyCapability::CAN_EDIT);
$actions = id(new PhabricatorActionListView())
->setUser($viewer);
$id = $namespace->getID();
$edit_uri = $this->getApplicationURI("namespace/edit/{$id}/");
$actions->addAction(
$curtain = $this->newCurtainView($namespace);
$curtain->addAction(
id(new PhabricatorActionView())
->setIcon('fa-pencil')
->setName(pht('Edit Namespace'))
->setHref($this->getApplicationURI("namespace/edit/{$id}/"))
->setHref($edit_uri)
->setWorkflow(!$can_edit)
->setDisabled(!$can_edit));
return $actions;
return $curtain;
}
}

View file

@ -21,8 +21,7 @@ final class AlmanacNetworkViewController
$title = pht('Network %s', $network->getName());
$properties = $this->buildPropertyList($network);
$actions = $this->buildActionList($network);
$curtain = $this->buildCurtain($network);
$header = id(new PHUIHeaderView())
->setUser($viewer)
@ -41,11 +40,10 @@ final class AlmanacNetworkViewController
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setCurtain($curtain)
->setMainColumn(array(
$timeline,
))
->setPropertyList($properties)
->setActionList($actions);
));
return $this->newPage()
->setTitle($title)
@ -56,39 +54,29 @@ final class AlmanacNetworkViewController
));
}
private function buildPropertyList(AlmanacNetwork $network) {
private function buildCurtain(AlmanacNetwork $network) {
$viewer = $this->getViewer();
$properties = id(new PHUIPropertyListView())
->setUser($viewer)
->setObject($network);
$properties->invokeWillRenderEvent();
return $properties;
}
private function buildActionList(AlmanacNetwork $network) {
$viewer = $this->getViewer();
$id = $network->getID();
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$network,
PhabricatorPolicyCapability::CAN_EDIT);
$actions = id(new PhabricatorActionListView())
->setUser($viewer);
$id = $network->getID();
$edit_uri = $this->getApplicationURI("network/edit/{$id}/");
$actions->addAction(
$curtain = $this->newCurtainView($network);
$curtain->addAction(
id(new PhabricatorActionView())
->setIcon('fa-pencil')
->setName(pht('Edit Network'))
->setHref($this->getApplicationURI("network/edit/{$id}/"))
->setHref($edit_uri)
->setWorkflow(!$can_edit)
->setDisabled(!$can_edit));
return $actions;
return $curtain;
}
}

View file

@ -23,8 +23,7 @@ final class AlmanacServiceViewController
$title = pht('Service %s', $service->getName());
$properties = $this->buildPropertyList($service);
$actions = $this->buildActionList($service);
$curtain = $this->buildCurtain($service);
$details = $this->buildPropertySection($service);
$header = id(new PHUIHeaderView())
@ -55,36 +54,19 @@ final class AlmanacServiceViewController
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setCurtain($curtain)
->setMainColumn(array(
$issue,
$details,
$bindings,
$this->buildAlmanacPropertiesTable($service),
$timeline,
))
->setPropertyList($properties)
->setActionList($actions);
));
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild(
array(
$view,
));
}
private function buildPropertyList(
AlmanacService $service) {
$viewer = $this->getViewer();
$view = id(new PHUIPropertyListView())
->setUser($viewer)
->setObject($service);
$view->invokeWillRenderEvent();
return $view;
->appendChild($view);
}
private function buildPropertySection(
@ -104,27 +86,28 @@ final class AlmanacServiceViewController
->appendChild($properties);
}
private function buildActionList(AlmanacService $service) {
private function buildCurtain(AlmanacService $service) {
$viewer = $this->getViewer();
$id = $service->getID();
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$service,
PhabricatorPolicyCapability::CAN_EDIT);
$actions = id(new PhabricatorActionListView())
->setUser($viewer);
$id = $service->getID();
$edit_uri = $this->getApplicationURI("service/edit/{$id}/");
$actions->addAction(
$curtain = $this->newCurtainView($service);
$curtain->addAction(
id(new PhabricatorActionView())
->setIcon('fa-pencil')
->setName(pht('Edit Service'))
->setHref($this->getApplicationURI("service/edit/{$id}/"))
->setHref($edit_uri)
->setWorkflow(!$can_edit)
->setDisabled(!$can_edit));
return $actions;
return $curtain;
}
private function buildBindingList(AlmanacService $service) {

View file

@ -15,10 +15,6 @@ final class AlmanacServiceSearchEngine
return new AlmanacServiceQuery();
}
public function newResultObject() {
return new AlmanacService();
}
protected function buildQueryFromParameters(array $map) {
$query = $this->newQuery();

View file

@ -246,7 +246,7 @@ final class AlmanacDevice
}
/* -( PhabricatorNgramInterface )------------------------------------------ */
/* -( PhabricatorNgramsInterface )----------------------------------------- */
public function newNgrams() {

View file

@ -210,7 +210,7 @@ final class AlmanacNamespace
}
/* -( PhabricatorNgramInterface )------------------------------------------ */
/* -( PhabricatorNgramsInterface )----------------------------------------- */
public function newNgrams() {

View file

@ -116,7 +116,7 @@ final class AlmanacNetwork
}
/* -( PhabricatorNgramInterface )------------------------------------------ */
/* -( PhabricatorNgramsInterface )----------------------------------------- */
public function newNgrams() {

View file

@ -251,7 +251,7 @@ final class AlmanacService
}
/* -( PhabricatorNgramInterface )------------------------------------------ */
/* -( PhabricatorNgramsInterface )----------------------------------------- */
public function newNgrams() {

View file

@ -636,6 +636,8 @@ final class PhabricatorAuditEditor
}
}
$phids[] = $this->getActingAsPHID();
return $phids;
}

View file

@ -43,8 +43,7 @@ final class PhabricatorBadgesViewController
->setStatus($status_icon, $status_color, $status_name)
->setHeaderIcon('fa-trophy');
$properties = $this->buildPropertyListView($badge);
$actions = $this->buildActionListView($badge);
$curtain = $this->buildCurtain($badge);
$details = $this->buildDetailsView($badge);
$timeline = $this->buildTransactionTimeline(
@ -64,36 +63,19 @@ final class PhabricatorBadgesViewController
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setCurtain($curtain)
->setMainColumn(array(
$recipient_list,
$timeline,
$add_comment,
))
->setPropertyList($properties)
->setActionList($actions)
->addPropertySection(pht('BADGE DETAILS'), $details);
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->setPageObjectPHIDs(array($badge->getPHID()))
->appendChild(
array(
$view,
));
}
private function buildPropertyListView(
PhabricatorBadgesBadge $badge) {
$viewer = $this->getViewer();
$view = id(new PHUIPropertyListView())
->setUser($viewer)
->setObject($badge);
$view->invokeWillRenderEvent();
return $view;
->appendChild($view);
}
private function buildDetailsView(
@ -137,53 +119,55 @@ final class PhabricatorBadgesViewController
return $view;
}
private function buildActionListView(PhabricatorBadgesBadge $badge) {
private function buildCurtain(PhabricatorBadgesBadge $badge) {
$viewer = $this->getViewer();
$id = $badge->getID();
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$badge,
PhabricatorPolicyCapability::CAN_EDIT);
$view = id(new PhabricatorActionListView())
->setUser($viewer)
->setObject($badge);
$id = $badge->getID();
$edit_uri = $this->getApplicationURI("/edit/{$id}/");
$archive_uri = $this->getApplicationURI("/archive/{$id}/");
$award_uri = $this->getApplicationURI("/recipients/{$id}/");
$view->addAction(
$curtain = $this->newCurtainView($badge);
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('Edit Badge'))
->setIcon('fa-pencil')
->setDisabled(!$can_edit)
->setHref($this->getApplicationURI("/edit/{$id}/")));
->setHref($edit_uri));
if ($badge->isArchived()) {
$view->addAction(
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('Activate Badge'))
->setIcon('fa-check')
->setDisabled(!$can_edit)
->setWorkflow($can_edit)
->setHref($this->getApplicationURI("/archive/{$id}/")));
->setHref($archive_uri));
} else {
$view->addAction(
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('Archive Badge'))
->setIcon('fa-ban')
->setDisabled(!$can_edit)
->setWorkflow($can_edit)
->setHref($this->getApplicationURI("/archive/{$id}/")));
->setHref($archive_uri));
}
$view->addAction(
$curtain->addAction(
id(new PhabricatorActionView())
->setName('Add Recipients')
->setIcon('fa-users')
->setDisabled(!$can_edit)
->setWorkflow(true)
->setHref($this->getApplicationURI("/recipients/{$id}/")));
->setHref($award_uri));
return $view;
return $curtain;
}
private function buildCommentForm(PhabricatorBadgesBadge $badge) {

View file

@ -181,10 +181,6 @@ final class PhabricatorBadgesBadge extends PhabricatorBadgesDAO
return ($this->creatorPHID == $phid);
}
public function shouldShowSubscribersProperty() {
return true;
}
/* -( PhabricatorTokenReceiverInterface )---------------------------------- */

View file

@ -16,8 +16,7 @@ final class PhabricatorBadgesRecipientsListView extends AphrontView {
}
public function render() {
$viewer = $this->user;
$viewer = $this->getViewer();
$badge = $this->badge;
$handles = $this->handles;

View file

@ -468,7 +468,32 @@ abstract class PhabricatorController extends AphrontController {
public function newApplicationMenu() {
return id(new PHUIApplicationMenuView())
->setViewer($this->getRequest()->getUser());
->setViewer($this->getViewer());
}
public function newCurtainView($object) {
$viewer = $this->getViewer();
$action_list = id(new PhabricatorActionListView())
->setViewer($viewer);
// NOTE: Applications (objects of class PhabricatorApplication) can't
// currently be set here, although they don't need any of the extensions
// anyway. This should probably work differently than it does, though.
if ($object instanceof PhabricatorLiskDAO) {
$action_list->setObject($object);
}
$curtain = id(new PHUICurtainView())
->setViewer($viewer)
->setActionList($action_list);
$panels = PHUICurtainExtension::buildExtensionPanels($viewer, $object);
foreach ($panels as $panel) {
$curtain->addPanel($panel);
}
return $curtain;
}
protected function buildTransactionTimeline(

View file

@ -63,8 +63,7 @@ final class PhabricatorCalendarEventViewController
}
$header = $this->buildHeaderView($event);
$actions = $this->buildActionView($event);
$properties = $this->buildPropertyListView($event);
$curtain = $this->buildCurtain($event);
$details = $this->buildPropertySection($event);
$description = $this->buildDescriptionView($event);
@ -90,11 +89,13 @@ final class PhabricatorCalendarEventViewController
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setMainColumn($timeline)
->setPropertyList($properties)
->setMainColumn(array(
$timeline,
$add_comment_form,
))
->setCurtain($curtain)
->addPropertySection(pht('DETAILS'), $details)
->addPropertySection(pht('DESCRIPTION'), $description)
->setActionList($actions);
->addPropertySection(pht('DESCRIPTION'), $description);
return $this->newPage()
->setTitle($page_title)
@ -148,16 +149,12 @@ final class PhabricatorCalendarEventViewController
return $header;
}
private function buildActionView(PhabricatorCalendarEvent $event) {
private function buildCurtain(PhabricatorCalendarEvent $event) {
$viewer = $this->getRequest()->getUser();
$id = $event->getID();
$is_cancelled = $event->getIsCancelled();
$is_attending = $event->getIsUserAttending($viewer->getPHID());
$actions = id(new PhabricatorActionListView())
->setUser($viewer)
->setObject($event);
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$event,
@ -178,8 +175,10 @@ final class PhabricatorCalendarEventViewController
$edit_uri = "event/edit/{$id}/";
}
$curtain = $this->newCurtainView($event);
if ($edit_label && $edit_uri) {
$actions->addAction(
$curtain->addAction(
id(new PhabricatorActionView())
->setName($edit_label)
->setIcon('fa-pencil')
@ -189,14 +188,14 @@ final class PhabricatorCalendarEventViewController
}
if ($is_attending) {
$actions->addAction(
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('Decline Event'))
->setIcon('fa-user-times')
->setHref($this->getApplicationURI("event/join/{$id}/"))
->setWorkflow(true));
} else {
$actions->addAction(
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('Join Event'))
->setIcon('fa-user-plus')
@ -230,7 +229,7 @@ final class PhabricatorCalendarEventViewController
}
if ($is_cancelled) {
$actions->addAction(
$curtain->addAction(
id(new PhabricatorActionView())
->setName($reinstate_label)
->setIcon('fa-plus')
@ -238,7 +237,7 @@ final class PhabricatorCalendarEventViewController
->setDisabled($cancel_disabled)
->setWorkflow(true));
} else {
$actions->addAction(
$curtain->addAction(
id(new PhabricatorActionView())
->setName($cancel_label)
->setIcon('fa-times')
@ -247,20 +246,7 @@ final class PhabricatorCalendarEventViewController
->setWorkflow(true));
}
return $actions;
}
private function buildPropertyListView(
PhabricatorCalendarEvent $event) {
$viewer = $this->getViewer();
$properties = id(new PHUIPropertyListView())
->setUser($viewer)
->setObject($event);
$properties->invokeWillRenderEvent();
return $properties;
return $curtain;
}
private function buildPropertySection(

View file

@ -531,10 +531,6 @@ final class PhabricatorCalendarEvent extends PhabricatorCalendarDAO
return ($phid == $this->getUserPHID());
}
public function shouldShowSubscribersProperty() {
return true;
}
/* -( PhabricatorTokenReceiverInterface )---------------------------------- */

View file

@ -71,6 +71,7 @@ final class CelerityDefaultPostprocessor
'hoverselectedgrey' => '#bbc4ca',
'hoverselectedblue' => '#e6e9ee',
'borderinset' => 'inset 0 0 0 1px rgba(55,55,55,.15)',
'timeline' => '#d5d8e1',
// Alphas
'alphawhite' => '255,255,255',

View file

@ -76,7 +76,7 @@ final class ConpherenceWidgetController extends ConpherenceController {
),
id(new PHUIHeaderView())
->setHeader($header)
->addActionIcon($new_icon));
->addActionItem($new_icon));
$user = $this->getRequest()->getUser();
// now the widget bodies
$widgets[] = javelin_tag(

View file

@ -49,8 +49,7 @@ final class PhabricatorCountdownViewController
->setStatus($icon, $color, $status)
->setHeaderIcon('fa-rocket');
$actions = $this->buildActionListView($countdown);
$properties = $this->buildPropertyListView($countdown);
$curtain = $this->buildCurtain($countdown);
$subheader = $this->buildSubheaderView($countdown);
$timeline = $this->buildTransactionTimeline(
@ -67,9 +66,8 @@ final class PhabricatorCountdownViewController
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setSubheader($subheader)
->setMainColumn($content)
->setPropertyList($properties)
->setActionList($actions);
->setCurtain($curtain)
->setMainColumn($content);
return $this->newPage()
->setTitle($title)
@ -78,28 +76,22 @@ final class PhabricatorCountdownViewController
array(
$countdown->getPHID(),
))
->appendChild(
array(
$view,
));
->appendChild($view);
}
private function buildActionListView(PhabricatorCountdown $countdown) {
$request = $this->getRequest();
$viewer = $request->getUser();
private function buildCurtain(PhabricatorCountdown $countdown) {
$viewer = $this->getViewer();
$id = $countdown->getID();
$view = id(new PhabricatorActionListView())
->setObject($countdown)
->setUser($viewer);
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$countdown,
PhabricatorPolicyCapability::CAN_EDIT);
$view->addAction(
$curtain = $this->newCurtainView($countdown);
$curtain->addAction(
id(new PhabricatorActionView())
->setIcon('fa-pencil')
->setName(pht('Edit Countdown'))
@ -107,7 +99,7 @@ final class PhabricatorCountdownViewController
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit));
$view->addAction(
$curtain->addAction(
id(new PhabricatorActionView())
->setIcon('fa-times')
->setName(pht('Delete Countdown'))
@ -115,17 +107,7 @@ final class PhabricatorCountdownViewController
->setDisabled(!$can_edit)
->setWorkflow(true));
return $view;
}
private function buildPropertyListView(
PhabricatorCountdown $countdown) {
$viewer = $this->getViewer();
$view = id(new PHUIPropertyListView())
->setUser($viewer)
->setObject($countdown);
$view->invokeWillRenderEvent();
return $view;
return $curtain;
}
private function buildSubheaderView(

View file

@ -70,9 +70,6 @@ final class PhabricatorCountdown extends PhabricatorCountdownDAO
return ($phid == $this->getAuthorPHID());
}
public function shouldShowSubscribersProperty() {
return true;
}
/* -( PhabricatorApplicationTransactionInterface )------------------------- */

View file

@ -158,8 +158,10 @@ abstract class PhabricatorDaemonManagementWorkflow
$this->printLaunchingDaemons($daemons, $debug);
$trace = PhutilArgumentParser::isTraceModeEnabled();
$flags = array();
if ($debug || PhabricatorEnv::getEnvConfig('phd.trace')) {
if ($trace || PhabricatorEnv::getEnvConfig('phd.trace')) {
$flags[] = '--trace';
}

View file

@ -24,12 +24,9 @@ final class PhabricatorDaemonLogEventsView extends AphrontView {
}
public function render() {
$viewer = $this->getViewer();
$rows = array();
if (!$this->user) {
throw new PhutilInvalidStateException('setUser');
}
foreach ($this->events as $event) {
// Limit display log size. If a daemon gets stuck in an output loop this
@ -83,8 +80,8 @@ final class PhabricatorDaemonLogEventsView extends AphrontView {
$row = array(
$event->getLogType(),
phabricator_date($event->getEpoch(), $this->user),
phabricator_time($event->getEpoch(), $this->user),
phabricator_date($event->getEpoch(), $viewer),
phabricator_time($event->getEpoch(), $viewer),
array(
$message,
$more,

View file

@ -11,11 +11,9 @@ final class PhabricatorDaemonLogListView extends AphrontView {
}
public function render() {
$rows = array();
$viewer = $this->getViewer();
if (!$this->user) {
throw new PhutilInvalidStateException('setUser');
}
$rows = array();
$list = new PHUIObjectItemListView();
$list->setFlush(true);
@ -27,7 +25,7 @@ final class PhabricatorDaemonLogListView extends AphrontView {
->setObjectName(pht('Daemon %s', $id))
->setHeader($log->getDaemon())
->setHref("/daemon/log/{$id}/")
->addIcon('none', phabricator_datetime($epoch, $this->user));
->addIcon('none', phabricator_datetime($epoch, $viewer));
$status = $log->getStatus();
switch ($status) {

View file

@ -253,7 +253,7 @@ final class PhabricatorDashboardPanelRenderingEngine extends Phobject {
->setIcon('fa-pencil')
->setWorkflow(true)
->setHref((string)$edit_uri);
$header->addActionIcon($action_edit);
$header->addActionItem($action_edit);
if ($dashboard_id) {
$uri = id(new PhutilURI(
@ -263,7 +263,7 @@ final class PhabricatorDashboardPanelRenderingEngine extends Phobject {
->setIcon('fa-trash-o')
->setHref((string)$uri)
->setWorkflow(true);
$header->addActionIcon($action_remove);
$header->addActionItem($action_remove);
}
return $header;
}

View file

@ -119,7 +119,7 @@ final class PhabricatorDashboardQueryPanelType
$icon = id(new PHUIIconView())
->setIcon('fa-search')
->setHref($href);
$header->addActionIcon($icon);
$header->addActionItem($icon);
return $header;
}

View file

@ -8,10 +8,11 @@
final class DifferentialRevisionStatus extends Phobject {
const COLOR_STATUS_DEFAULT = 'status';
const COLOR_STATUS_DARK = 'status-dark';
const COLOR_STATUS_GREEN = 'status-green';
const COLOR_STATUS_RED = 'status-red';
const COLOR_STATUS_DEFAULT = 'bluegrey';
const COLOR_STATUS_DARK = 'indigo';
const COLOR_STATUS_BLUE = 'blue';
const COLOR_STATUS_GREEN = 'green';
const COLOR_STATUS_RED = 'red';
public static function getRevisionStatusColor($status) {
$default = self::COLOR_STATUS_DEFAULT;
@ -30,7 +31,7 @@ final class DifferentialRevisionStatus extends Phobject {
ArcanistDifferentialRevisionStatus::ABANDONED =>
self::COLOR_STATUS_DARK,
ArcanistDifferentialRevisionStatus::IN_PREPARATION =>
self::COLOR_STATUS_DARK,
self::COLOR_STATUS_BLUE,
);
return idx($map, $status, $default);
}
@ -42,38 +43,30 @@ final class DifferentialRevisionStatus extends Phobject {
ArcanistDifferentialRevisionStatus::NEEDS_REVIEW =>
'fa-square-o bluegrey',
ArcanistDifferentialRevisionStatus::NEEDS_REVISION =>
'fa-refresh red',
'fa-refresh',
ArcanistDifferentialRevisionStatus::CHANGES_PLANNED =>
'fa-headphones red',
'fa-headphones',
ArcanistDifferentialRevisionStatus::ACCEPTED =>
'fa-check green',
'fa-check',
ArcanistDifferentialRevisionStatus::CLOSED =>
'fa-check-square-o',
ArcanistDifferentialRevisionStatus::ABANDONED =>
'fa-check-square-o',
'fa-plane',
ArcanistDifferentialRevisionStatus::IN_PREPARATION =>
'fa-question-circle blue',
'fa-question-circle',
);
return idx($map, $status, $default);
}
public static function renderFullDescription($status) {
$color = self::getRevisionStatusColor($status);
$status_name =
ArcanistDifferentialRevisionStatus::getNameForRevisionStatus($status);
$img = id(new PHUIIconView())
->setIcon(self::getRevisionStatusIcon($status));
$tag = phutil_tag(
'span',
array(
'class' => 'phui-header-status phui-header-'.$color,
),
array(
$img,
$status_name,
));
$tag = id(new PHUITagView())
->setName($status_name)
->setIcon(self::getRevisionStatusIcon($status))
->setShade(self::getRevisionStatusColor($status))
->setType(PHUITagView::TYPE_SHADE);
return $tag;
}

View file

@ -190,6 +190,12 @@ abstract class DifferentialController extends PhabricatorController {
}
}
// Cast duration to a float since it used to be a string in some
// cases.
if (isset($map['duration'])) {
$map['duration'] = (double)$map['duration'];
}
return $map;
}

View file

@ -481,19 +481,21 @@ final class DifferentialRevisionViewController extends DifferentialController {
->setBaseURI(new PhutilURI('/D'.$revision->getID()))
->setCollapsed((bool)$collapsed)
->build($changesets);
$nav->appendChild($content);
$nav->setCrumbs($crumbs);
$content = $nav;
} else {
array_unshift($content, $crumbs);
$nav = null;
}
return $this->buildApplicationPage(
$content,
array(
'title' => $object_id.' '.$revision->getTitle(),
'pageObjects' => array($revision->getPHID()),
));
$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) {
@ -1076,6 +1078,10 @@ final class DifferentialRevisionViewController extends DifferentialController {
return null;
}
if (!$diff->getBuildable()) {
return null;
}
$interesting_messages = array();
foreach ($diff->getUnitMessages() as $message) {
switch ($message->getResult()) {

View file

@ -1000,7 +1000,8 @@ final class DifferentialChangesetParser extends Phobject {
}
}
$this->comments = msort($this->comments, 'getID');
$this->comments = $this->reorderAndThreadComments($this->comments);
foreach ($this->comments as $comment) {
$final = $comment->getLineNumber() +
$comment->getLineLength();
@ -1569,4 +1570,67 @@ final class DifferentialChangesetParser extends Phobject {
return array($old_back, $new_back);
}
private function reorderAndThreadComments(array $comments) {
$comments = msort($comments, 'getID');
// Build an empty map of all the comments we actually have. If a comment
// is a reply but the parent has gone missing, we don't want it to vanish
// completely.
$comment_phids = mpull($comments, 'getPHID');
$replies = array_fill_keys($comment_phids, array());
// Now, remove all comments which are replies, leaving only the top-level
// comments.
foreach ($comments as $key => $comment) {
$reply_phid = $comment->getReplyToCommentPHID();
if (isset($replies[$reply_phid])) {
$replies[$reply_phid][] = $comment;
unset($comments[$key]);
}
}
// For each top level comment, add the comment, then add any replies
// to it. Do this recursively so threads are shown in threaded order.
$results = array();
foreach ($comments as $comment) {
$results[] = $comment;
$phid = $comment->getPHID();
$descendants = $this->getInlineReplies($replies, $phid, 1);
foreach ($descendants as $descendant) {
$results[] = $descendant;
}
}
// If we have anything left, they were cyclic references. Just dump
// them in a the end. This should be impossible, but users are very
// creative.
foreach ($replies as $phid => $comments) {
foreach ($comments as $comment) {
$results[] = $comment;
}
}
return $results;
}
private function getInlineReplies(array &$replies, $phid, $depth) {
$comments = idx($replies, $phid, array());
unset($replies[$phid]);
$results = array();
foreach ($comments as $comment) {
$results[] = $comment;
$descendants = $this->getInlineReplies(
$replies,
$comment->getPHID(),
$depth + 1);
foreach ($descendants as $descendant) {
$results[] = $descendant;
}
}
return $results;
}
}

View file

@ -6,7 +6,9 @@ final class DifferentialDiffQuery
private $ids;
private $phids;
private $revisionIDs;
private $needChangesets = false;
private $needProperties;
public function withIDs(array $ids) {
$this->ids = $ids;
@ -28,19 +30,17 @@ final class DifferentialDiffQuery
return $this;
}
public function needProperties($need_properties) {
$this->needProperties = $need_properties;
return $this;
}
public function newResultObject() {
return new DifferentialDiff();
}
protected function loadPage() {
$table = new DifferentialDiff();
$conn_r = $table->establishConnection('r');
$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);
return $this->loadStandardPage($this->newResultObject());
}
protected function willFilterPage(array $diffs) {
@ -76,6 +76,23 @@ final class DifferentialDiffQuery
return $diffs;
}
protected function didFilterPage(array $diffs) {
if ($this->needProperties) {
$properties = id(new DifferentialDiffProperty())->loadAllWhere(
'diffID IN (%Ld)',
mpull($diffs, 'getID'));
$properties = mgroup($properties, 'getDiffID');
foreach ($diffs as $diff) {
$map = idx($properties, $diff->getID(), array());
$map = mpull($map, 'getData', 'getName');
$diff->attachDiffProperties($map);
}
}
return $diffs;
}
private function loadChangesets(array $diffs) {
id(new DifferentialChangesetQuery())
->setViewer($this->getViewer())
@ -88,32 +105,31 @@ final class DifferentialDiffQuery
return $diffs;
}
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
$where = parent::buildWhereClauseParts($conn);
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
$conn,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
$conn,
'phid IN (%Ls)',
$this->phids);
}
if ($this->revisionIDs) {
$where[] = qsprintf(
$conn_r,
$conn,
'revisionID IN (%Ld)',
$this->revisionIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
return $where;
}
public function getQueryApplicationClass() {

View file

@ -485,10 +485,6 @@ final class DifferentialRevision extends DifferentialDAO
return false;
}
public function shouldShowSubscribersProperty() {
return true;
}
/* -( PhabricatorCustomFieldInterface )------------------------------------ */

View file

@ -50,6 +50,7 @@ final class DifferentialAddCommentView extends AphrontView {
}
public function render() {
$viewer = $this->getViewer();
$this->requireResource('differential-revision-add-comment-css');
$revision = $this->revision;
@ -73,7 +74,7 @@ final class DifferentialAddCommentView extends AphrontView {
$form = new AphrontFormView();
$form
->setWorkflow(true)
->setUser($this->user)
->setViewer($viewer)
->setAction($this->actionURI)
->addHiddenInput('revision_id', $revision->getID())
->appendChild(
@ -108,7 +109,7 @@ final class DifferentialAddCommentView extends AphrontView {
->setID('comment-content')
->setLabel(pht('Comment'))
->setValue($this->draft ? $this->draft->getDraft() : null)
->setUser($this->user))
->setViewer($viewer))
->appendChild(
id(new AphrontFormSubmitControl())
->setValue(pht('Submit')));

View file

@ -113,6 +113,8 @@ final class DifferentialChangesetListView extends AphrontView {
}
public function render() {
$viewer = $this->getViewer();
$this->requireResource('differential-changeset-view-css');
$changesets = $this->changesets;
@ -148,7 +150,7 @@ final class DifferentialChangesetListView extends AphrontView {
));
$renderer = DifferentialChangesetParser::getDefaultRendererForViewer(
$this->getUser());
$viewer);
$output = array();
$ids = array();
@ -163,7 +165,7 @@ final class DifferentialChangesetListView extends AphrontView {
$ref = $this->references[$key];
$detail = id(new DifferentialChangesetDetailView())
->setUser($this->getUser());
->setUser($viewer);
$uniq_id = 'diff-'.$changeset->getAnchorName();
$detail->setID($uniq_id);
@ -261,6 +263,7 @@ final class DifferentialChangesetListView extends AphrontView {
DifferentialChangesetDetailView $detail,
$ref,
DifferentialChangeset $changeset) {
$viewer = $this->getViewer();
$meta = array();
@ -280,7 +283,7 @@ final class DifferentialChangesetListView extends AphrontView {
try {
$meta['diffusionURI'] =
(string)$repository->getDiffusionBrowseURIForPath(
$this->user,
$viewer,
$changeset->getAbsoluteRepositoryPath($repository, $this->diff),
idx($changeset->getMetadata(), 'line:first'),
$this->getBranch());
@ -308,13 +311,12 @@ final class DifferentialChangesetListView extends AphrontView {
}
}
$user = $this->user;
if ($user && $repository) {
if ($viewer && $repository) {
$path = ltrim(
$changeset->getAbsoluteRepositoryPath($repository, $this->diff),
'/');
$line = idx($changeset->getMetadata(), 'line:first', 1);
$editor_link = $user->loadEditorLink($path, $line, $repository);
$editor_link = $viewer->loadEditorLink($path, $line, $repository);
if ($editor_link) {
$meta['editor'] = $editor_link;
} else {

View file

@ -17,10 +17,7 @@ final class DifferentialLocalCommitsView extends AphrontView {
}
public function render() {
$user = $this->user;
if (!$user) {
throw new PhutilInvalidStateException('setUser');
}
$viewer = $this->getViewer();
$local = $this->localCommits;
if (!$local) {
@ -94,7 +91,7 @@ final class DifferentialLocalCommitsView extends AphrontView {
idx($commit, 'date'),
idx($commit, 'time'));
if ($date) {
$date = phabricator_datetime($date, $user);
$date = phabricator_datetime($date, $viewer);
}
$row[] = $date;

View file

@ -57,10 +57,7 @@ final class DifferentialRevisionListView extends AphrontView {
}
public function render() {
$user = $this->user;
if (!$user) {
throw new PhutilInvalidStateException('setUser');
}
$viewer = $this->getViewer();
$fresh = PhabricatorEnv::getEnvConfig('differential.days-fresh');
if ($fresh) {
@ -83,12 +80,12 @@ final class DifferentialRevisionListView extends AphrontView {
foreach ($this->revisions as $revision) {
$item = id(new PHUIObjectItemView())
->setUser($user);
->setUser($viewer);
$icons = array();
$phid = $revision->getPHID();
$flag = $revision->getFlag($user);
$flag = $revision->getFlag($viewer);
if ($flag) {
$flag_class = PhabricatorFlagColor::getCSSClass($flag->getColor());
$icons['flag'] = phutil_tag(
@ -99,7 +96,7 @@ final class DifferentialRevisionListView extends AphrontView {
'');
}
if ($revision->getDrafts($user)) {
if ($revision->getDrafts($viewer)) {
$icons['draft'] = true;
}

View file

@ -100,7 +100,7 @@ final class DiffusionTagListView extends DiffusionView {
$build,
$author,
$description,
phabricator_datetime($tag->getEpoch(), $this->user),
phabricator_datetime($tag->getEpoch(), $this->getViewer()),
);
}

View file

@ -3,6 +3,7 @@
abstract class DoorkeeperBridge extends Phobject {
private $viewer;
private $context = array();
private $throwOnMissingLink;
public function setThrowOnMissingLink($throw_on_missing_link) {
@ -19,6 +20,15 @@ abstract class DoorkeeperBridge extends Phobject {
return $this->viewer;
}
final public function setContext($context) {
$this->context = $context;
return $this;
}
final public function getContextProperty($key, $default = null) {
return idx($this->context, $key, $default);
}
public function isEnabled() {
return true;
}

View file

@ -0,0 +1,50 @@
<?php
abstract class DoorkeeperBridgeGitHub extends DoorkeeperBridge {
const APPTYPE_GITHUB = 'github';
const APPDOMAIN_GITHUB = 'github.com';
public function canPullRef(DoorkeeperObjectRef $ref) {
if ($ref->getApplicationType() != self::APPTYPE_GITHUB) {
return false;
}
if ($ref->getApplicationDomain() != self::APPDOMAIN_GITHUB) {
return false;
}
return true;
}
protected function getGitHubAccessToken() {
$context_token = $this->getContextProperty('github.token');
if ($context_token) {
return $context_token->openEnvelope();
}
// TODO: Do a bunch of work to fetch the viewer's linked account if
// they have one.
return $this->didFailOnMissingLink();
}
protected function parseGitHubIssueID($id) {
$matches = null;
if (!preg_match('(^([^/]+)/([^/]+)#([1-9]\d*)\z)', $id, $matches)) {
throw new Exception(
pht(
'GitHub Issue ID "%s" is not properly formatted. Expected an ID '.
'in the form "owner/repository#123".',
$id));
}
return array(
$matches[1],
$matches[2],
(int)$matches[3],
);
}
}

View file

@ -0,0 +1,97 @@
<?php
final class DoorkeeperBridgeGitHubIssue
extends DoorkeeperBridgeGitHub {
const OBJTYPE_GITHUB_ISSUE = 'github.issue';
public function canPullRef(DoorkeeperObjectRef $ref) {
if (!parent::canPullRef($ref)) {
return false;
}
if ($ref->getObjectType() !== self::OBJTYPE_GITHUB_ISSUE) {
return false;
}
return true;
}
public function pullRefs(array $refs) {
$token = $this->getGitHubAccessToken();
if (!strlen($token)) {
return null;
}
$template = id(new PhutilGitHubFuture())
->setAccessToken($token);
$futures = array();
$id_map = mpull($refs, 'getObjectID', 'getObjectKey');
foreach ($id_map as $key => $id) {
list($user, $repository, $number) = $this->parseGitHubIssueID($id);
$uri = "/repos/{$user}/{$repository}/issues/{$number}";
$data = array();
$futures[$key] = id(clone $template)
->setRawGitHubQuery($uri, $data);
}
$results = array();
$failed = array();
foreach (new FutureIterator($futures) as $key => $future) {
try {
$results[$key] = $future->resolve();
} catch (Exception $ex) {
if (($ex instanceof HTTPFutureResponseStatus) &&
($ex->getStatusCode() == 404)) {
// TODO: Do we end up here for deleted objects and invisible
// objects?
} else {
phlog($ex);
$failed[$key] = $ex;
}
}
}
$viewer = $this->getViewer();
foreach ($refs as $ref) {
$ref->setAttribute('name', pht('GitHub Issue %s', $ref->getObjectID()));
$did_fail = idx($failed, $ref->getObjectKey());
if ($did_fail) {
$ref->setSyncFailed(true);
continue;
}
$result = idx($results, $ref->getObjectKey());
if (!$result) {
continue;
}
$body = $result->getBody();
$ref->setIsVisible(true);
$ref->setAttribute('api.raw', $body);
$ref->setAttribute('name', $body['title']);
$obj = $ref->getExternalObject();
if ($obj->getID()) {
continue;
}
$this->fillObjectFromData($obj, $result);
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
$obj->save();
unset($unguarded);
}
}
public function fillObjectFromData(DoorkeeperExternalObject $obj, $result) {
$body = $result->getBody();
$uri = $body['html_url'];
$obj->setObjectURI($uri);
}
}

View file

@ -7,6 +7,7 @@ final class DoorkeeperImportEngine extends Phobject {
private $phids = array();
private $localOnly;
private $throwOnMissingLink;
private $context = array();
public function setViewer(PhabricatorUser $viewer) {
$this->viewer = $viewer;
@ -37,6 +38,10 @@ final class DoorkeeperImportEngine extends Phobject {
return $this;
}
public function setContextProperty($key, $value) {
$this->context[$key] = $value;
return $this;
}
/**
* Configure behavior if remote refs can not be retrieved because an
@ -96,6 +101,7 @@ final class DoorkeeperImportEngine extends Phobject {
foreach ($bridges as $key => $bridge) {
$bridge->setViewer($viewer);
$bridge->setThrowOnMissingLink($this->throwOnMissingLink);
$bridge->setContext($this->context);
}
$working_set = $refs;

View file

@ -1,18 +0,0 @@
<?php
class DrydockCommandError {
public static function newFromCommandException(
$phase,
$command,
CommandException $ex) {
$error = array(
'phase' => $phase,
'command' => (string)$command,
'raw' => (string)$ex->getCommand(),
'err' => $ex->getError(),
'stdout' => $ex->getStdout(),
'stderr' => $ex->getStderr(),
);
return $error;
}
}

View file

@ -4,6 +4,8 @@ final class DrydockWorkingCopyBlueprintImplementation
extends DrydockBlueprintImplementation {
const PHASE_SQUASHMERGE = 'squashmerge';
const PHASE_REMOTEFETCH = 'blueprint.workingcopy.fetch.remote';
const PHASE_MERGEFETCH = 'blueprint.workingcopy.fetch.staging';
public function isEnabled() {
return true;
@ -240,11 +242,11 @@ final class DrydockWorkingCopyBlueprintImplementation
$default = null;
foreach ($map as $directory => $spec) {
$interface->pushWorkingDirectory("{$root}/repo/{$directory}/");
$cmd = array();
$arg = array();
$interface->pushWorkingDirectory("{$root}/repo/{$directory}/");
$cmd[] = 'git clean -d --force';
$cmd[] = 'git fetch';
@ -266,7 +268,20 @@ final class DrydockWorkingCopyBlueprintImplementation
$cmd[] = 'git reset --hard origin/%s';
$arg[] = $branch;
} else if ($ref) {
}
$this->execxv($interface, $cmd, $arg);
if (idx($spec, 'default')) {
$default = $directory;
}
// If we're fetching a ref from a remote, do that separately so we can
// raise a more tailored error.
if ($ref) {
$cmd = array();
$arg = array();
$ref_uri = $ref['uri'];
$ref_ref = $ref['ref'];
@ -277,17 +292,25 @@ final class DrydockWorkingCopyBlueprintImplementation
$cmd[] = 'git checkout %s --';
$arg[] = $ref_ref;
}
$cmd = implode(' && ', $cmd);
$argv = array_merge(array($cmd), $arg);
try {
$this->execxv($interface, $cmd, $arg);
} catch (CommandException $ex) {
$display_command = csprintf(
'git fetch %R %R',
$ref_uri,
$ref_ref);
$result = call_user_func_array(
array($interface, 'execx'),
$argv);
$error = DrydockCommandError::newFromCommandException($ex)
->setPhase(self::PHASE_REMOTEFETCH)
->setDisplayCommand($display_command);
if (idx($spec, 'default')) {
$default = $directory;
$lease->setAttribute(
'workingcopy.vcs.error',
$error->toDictionary());
throw $ex;
}
}
$merges = idx($spec, 'merges');
@ -428,11 +451,29 @@ final class DrydockWorkingCopyBlueprintImplementation
$src_uri = $merge['src.uri'];
$src_ref = $merge['src.ref'];
$interface->execx(
'git fetch --no-tags -- %s +%s:%s',
$src_uri,
$src_ref,
$src_ref);
try {
$interface->execx(
'git fetch --no-tags -- %s +%s:%s',
$src_uri,
$src_ref,
$src_ref);
} catch (CommandException $ex) {
$display_command = csprintf(
'git fetch %R +%R:%R',
$src_uri,
$src_ref,
$src_ref);
$error = DrydockCommandError::newFromCommandException($ex)
->setPhase(self::PHASE_MERGEFETCH)
->setDisplayCommand($display_command);
$lease->setAttribute('workingcopy.vcs.error', $error->toDictionary());
throw $ex;
}
// NOTE: This can never actually generate a commit because we pass
// "--squash", but git sometimes runs code to check that a username and
@ -443,32 +484,36 @@ final class DrydockWorkingCopyBlueprintImplementation
'drydock@phabricator',
$src_ref);
// Show the user a simplified command if the operation fails and we need to
// report an error.
$show_command = csprintf(
'git merge --squash -- %R',
$src_ref);
try {
$interface->execx('%C', $real_command);
} catch (CommandException $ex) {
$error = DrydockCommandError::newFromCommandException(
self::PHASE_SQUASHMERGE,
$show_command,
$ex);
$display_command = csprintf(
'git merge --squash %R',
$src_ref);
$lease->setAttribute('workingcopy.vcs.error', $error);
$error = DrydockCommandError::newFromCommandException($ex)
->setPhase(self::PHASE_SQUASHMERGE)
->setDisplayCommand($display_command);
$lease->setAttribute('workingcopy.vcs.error', $error->toDictionary());
throw $ex;
}
}
public function getCommandError(DrydockLease $lease) {
$error = $lease->getAttribute('workingcopy.vcs.error');
if (!$error) {
return null;
} else {
return $error;
}
return $lease->getAttribute('workingcopy.vcs.error');
}
private function execxv(
DrydockCommandInterface $interface,
array $commands,
array $arguments) {
$commands = implode(' && ', $commands);
$argv = array_merge(array($commands), $arguments);
return call_user_func_array(array($interface, 'execx'), $argv);
}
}

View file

@ -0,0 +1,58 @@
<?php
final class DrydockCommandError extends Phobject {
private $phase;
private $displayCommand;
private $command;
private $error;
private $stdout;
private $stderr;
public static function newFromCommandException(CommandException $ex) {
$error = new self();
$error->command = (string)$ex->getCommand();
$error->error = $ex->getError();
$error->stdout = $ex->getStdout();
$error->stderr = $ex->getStderr();
return $error;
}
public function setPhase($phase) {
$this->phase = $phase;
return $this;
}
public function getPhase() {
return $this->phase;
}
public function setDisplayCommand($display_command) {
$this->displayCommand = (string)$display_command;
return $this;
}
public function getDisplayCommand() {
return $this->displayCommand;
}
public function toDictionary() {
$display_command = $this->getDisplayCommand();
if ($display_command === null) {
$display_command = $this->command;
}
return array(
'phase' => $this->getPhase(),
'command' => $display_command,
'raw' => $this->command,
'err' => $this->error,
'stdout' => $this->stdout,
'stderr' => $this->stderr,
);
}
}

View file

@ -4,7 +4,9 @@ final class DrydockLandRepositoryOperation
extends DrydockRepositoryOperationType {
const OPCONST = 'land';
const PHASE_PUSH = 'push';
const PHASE_PUSH = 'op.land.push';
const PHASE_COMMIT = 'op.land.commit';
public function getOperationDescription(
DrydockRepositoryOperation $operation,
@ -119,25 +121,42 @@ final class DrydockLandRepositoryOperation
$committer_info['email'],
"{$author_name} <{$author_email}>");
$future
->write($commit_message)
->resolvex();
$future->write($commit_message);
try {
$interface->execx(
'git push origin -- %s:%s',
'HEAD',
$push_dst);
$future->resolvex();
} catch (CommandException $ex) {
$show_command = csprintf(
'git push origin -- %s:%s',
'HEAD',
$push_dst);
$error = DrydockCommandError::newFromCommandException(
self::PHASE_PUSH,
$show_command,
$ex);
$operation->setCommandError($error);
$display_command = csprintf('git commit');
// TODO: One reason this can fail is if the changes have already been
// merged. We could try to detect that.
$error = DrydockCommandError::newFromCommandException($ex)
->setPhase(self::PHASE_COMMIT)
->setDisplayCommand($display_command);
$operation->setCommandError($error->toDictionary());
throw $ex;
}
try {
$interface->execx(
'git push origin -- %s:%s',
'HEAD',
$push_dst);
} catch (CommandException $ex) {
$display_command = csprintf(
'git push origin %R:%R',
'HEAD',
$push_dst);
$error = DrydockCommandError::newFromCommandException($ex)
->setPhase(self::PHASE_PUSH)
->setDisplayCommand($display_command);
$operation->setCommandError($error->toDictionary());
throw $ex;
}
}
@ -229,6 +248,29 @@ final class DrydockLandRepositoryOperation
);
}
// Check if this diff was pushed to a staging area.
$diff = id(new DifferentialDiffQuery())
->setViewer($viewer)
->withIDs(array($revision->getActiveDiff()->getID()))
->needProperties(true)
->executeOne();
// Older diffs won't have this property. They may still have been pushed.
// At least for now, assume staging changes are present if the property
// is missing. This should smooth the transition to the more formal
// approach.
$has_staging = $diff->hasDiffProperty('arc.staging');
if ($has_staging) {
$staging = $diff->getProperty('arc.staging');
if (!is_array($staging)) {
$staging = array();
}
$status = idx($staging, 'status');
if ($status != ArcanistDiffWorkflow::STAGING_PUSHED) {
return $this->getBarrierToLandingFromStagingStatus($status);
}
}
// TODO: At some point we should allow installs to give "land reviewed
// code" permission to more users than "push any commit", because it is
// a much less powerful operation. For now, just require push so this
@ -317,4 +359,85 @@ final class DrydockLandRepositoryOperation
return null;
}
private function getBarrierToLandingFromStagingStatus($status) {
switch ($status) {
case ArcanistDiffWorkflow::STAGING_USER_SKIP:
return array(
'title' => pht('Staging Area Skipped'),
'body' => pht(
'The diff author used the %s flag to skip pushing this change to '.
'staging. Changes must be pushed to staging before they can be '.
'landed from the web.',
phutil_tag('tt', array(), '--skip-staging')),
);
case ArcanistDiffWorkflow::STAGING_DIFF_RAW:
return array(
'title' => pht('Raw Diff Source'),
'body' => pht(
'The diff was generated from a raw input source, so the change '.
'could not be pushed to staging. Changes must be pushed to '.
'staging before they can be landed from the web.'),
);
case ArcanistDiffWorkflow::STAGING_REPOSITORY_UNKNOWN:
return array(
'title' => pht('Unknown Repository'),
'body' => pht(
'When the diff was generated, the client was not able to '.
'determine which repository it belonged to, so the change '.
'was not pushed to staging. Changes must be pushed to staging '.
'before they can be landed from the web.'),
);
case ArcanistDiffWorkflow::STAGING_REPOSITORY_UNAVAILABLE:
return array(
'title' => pht('Staging Unavailable'),
'body' => pht(
'When this diff was generated, the server was running an older '.
'version of Phabricator which did not support staging areas, so '.
'the change was not pushed to staging. Changes must be pushed '.
'to staging before they can be landed from the web.'),
);
case ArcanistDiffWorkflow::STAGING_REPOSITORY_UNSUPPORTED:
return array(
'title' => pht('Repository Unsupported'),
'body' => pht(
'When this diff was generated, the server was running an older '.
'version of Phabricator which did not support staging areas for '.
'this version control system, so the chagne was not pushed to '.
'staging. Changes must be pushed to staging before they can be '.
'landed from the web.'),
);
case ArcanistDiffWorkflow::STAGING_REPOSITORY_UNCONFIGURED:
return array(
'title' => pht('Repository Unconfigured'),
'body' => pht(
'When this diff was generated, the repository was not configured '.
'with a staging area, so the change was not pushed to staging. '.
'Changes must be pushed to staging before they can be landed '.
'from the web.'),
);
case ArcanistDiffWorkflow::STAGING_CLIENT_UNSUPPORTED:
return array(
'title' => pht('Client Support Unavailable'),
'body' => pht(
'When this diff was generated, the client did not support '.
'staging areas for this version control system, so the change '.
'was not pushed to staging. Changes must be pushed to staging '.
'before they can be landed from the web. Updating the client '.
'may resolve this issue.'),
);
default:
return array(
'title' => pht('Unknown Error'),
'body' => pht(
'When this diff was generated, it was not pushed to staging for '.
'an unknown reason (the status code was "%s"). Changes must be '.
'pushed to staging before they can be landed from the web. '.
'The server may be running an out-of-date version of Phabricator, '.
'and updating may provide more information about this error.',
$status),
);
}
}
}

View file

@ -350,7 +350,7 @@ final class DrydockBlueprint extends DrydockDAO
}
/* -( PhabricatorNgramInterface )------------------------------------------ */
/* -( PhabricatorNgramsInterface )----------------------------------------- */
public function newNgrams() {

View file

@ -82,6 +82,20 @@ final class DrydockRepositoryOperationStatusView
'This change did not merge cleanly. This usually indicates '.
'that the change is out of date and needs to be updated.');
break;
case DrydockWorkingCopyBlueprintImplementation::PHASE_REMOTEFETCH:
$message = pht(
'This change could not be fetched from the remote.');
break;
case DrydockWorkingCopyBlueprintImplementation::PHASE_MERGEFETCH:
$message = pht(
'This change could not be fetched from the remote staging '.
'area. It may not have been pushed, or may have been removed.');
break;
case DrydockLandRepositoryOperation::PHASE_COMMIT:
$message = pht(
'Committing this change failed. It may already have been '.
'merged.');
break;
case DrydockLandRepositoryOperation::PHASE_PUSH:
$message = pht(
'The push failed. This usually indicates '.
@ -123,10 +137,23 @@ final class DrydockRepositoryOperationStatusView
private function renderVCSErrorTable(array $vcs_error) {
$rows = array();
$rows[] = array(pht('Command'), $vcs_error['command']);
$rows[] = array(
pht('Command'),
phutil_censor_credentials($vcs_error['command']),
);
$rows[] = array(pht('Error'), $vcs_error['err']);
$rows[] = array(pht('Stdout'), $vcs_error['stdout']);
$rows[] = array(pht('Stderr'), $vcs_error['stderr']);
$rows[] = array(
pht('Stdout'),
phutil_censor_credentials($vcs_error['stdout']),
);
$rows[] = array(
pht('Stderr'),
phutil_censor_credentials($vcs_error['stderr']),
);
$table = id(new AphrontTableView($rows))
->setColumnClasses(

View file

@ -1348,10 +1348,6 @@ final class PhabricatorFile extends PhabricatorFileDAO
return ($this->authorPHID == $phid);
}
public function shouldShowSubscribersProperty() {
return true;
}
/* -( PhabricatorTokenReceiverInterface )---------------------------------- */

View file

@ -46,8 +46,7 @@ final class FundInitiativeViewController
->setStatus($status_icon, $status_color, $status_name)
->setHeaderIcon('fa-heart');
$properties = $this->buildPropertyListView($initiative);
$actions = $this->buildActionListView($initiative);
$curtain = $this->buildCurtain($initiative);
$details = $this->buildPropertySectionView($initiative);
$timeline = $this->buildTransactionTimeline(
@ -57,31 +56,15 @@ final class FundInitiativeViewController
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setCurtain($curtain)
->setMainColumn($timeline)
->setPropertyList($properties)
->addPropertySection(pht('DETAILS'), $details)
->setActionList($actions);
->addPropertySection(pht('DETAILS'), $details);
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->setPageObjectPHIDs(array($initiative->getPHID()))
->appendChild(
array(
$view,
));
}
private function buildPropertyListView(FundInitiative $initiative) {
$viewer = $this->getRequest()->getUser();
$view = id(new PHUIPropertyListView())
->setUser($viewer)
->setObject($initiative);
$view->invokeWillRenderEvent();
return $view;
->appendChild($view);
}
private function buildPropertySectionView(FundInitiative $initiative) {
@ -124,8 +107,9 @@ final class FundInitiativeViewController
return $view;
}
private function buildActionListView(FundInitiative $initiative) {
$viewer = $this->getRequest()->getUser();
private function buildCurtain(FundInitiative $initiative) {
$viewer = $this->getViewer();
$id = $initiative->getID();
$can_edit = PhabricatorPolicyFilter::hasCapability(
@ -133,11 +117,9 @@ final class FundInitiativeViewController
$initiative,
PhabricatorPolicyCapability::CAN_EDIT);
$view = id(new PhabricatorActionListView())
->setUser($viewer)
->setObject($initiative);
$curtain = $this->newCurtainView($initiative);
$view->addAction(
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('Edit Initiative'))
->setIcon('fa-pencil')
@ -153,7 +135,7 @@ final class FundInitiativeViewController
$close_icon = 'fa-times';
}
$view->addAction(
$curtain->addAction(
id(new PhabricatorActionView())
->setName($close_name)
->setIcon($close_icon)
@ -161,7 +143,7 @@ final class FundInitiativeViewController
->setWorkflow(true)
->setHref($this->getApplicationURI("/close/{$id}/")));
$view->addAction(
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('Back Initiative'))
->setIcon('fa-money')
@ -169,13 +151,13 @@ final class FundInitiativeViewController
->setWorkflow(true)
->setHref($this->getApplicationURI("/back/{$id}/")));
$view->addAction(
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('View Backers'))
->setIcon('fa-bank')
->setHref($this->getApplicationURI("/backers/{$id}/")));
return $view;
return $curtain;
}
}

View file

@ -178,10 +178,6 @@ final class FundInitiative extends FundDAO
return ($phid == $this->getOwnerPHID());
}
public function shouldShowSubscribersProperty() {
return true;
}
/* -( PhabricatorTokenRecevierInterface )---------------------------------- */

View file

@ -114,6 +114,8 @@ final class HarbormasterBuildLog
$this->rope->append($content);
$this->flush();
return $this;
}
private function flush() {

View file

@ -127,10 +127,6 @@ final class HarbormasterBuildPlan extends HarbormasterDAO
return false;
}
public function shouldShowSubscribersProperty() {
return true;
}
/* -( PhabricatorApplicationTransactionInterface )------------------------- */
@ -201,7 +197,7 @@ final class HarbormasterBuildPlan extends HarbormasterDAO
}
/* -( PhabricatorNgramInterface )------------------------------------------ */
/* -( PhabricatorNgramsInterface )----------------------------------------- */
public function newNgrams() {

View file

@ -33,8 +33,7 @@ final class HeraldRuleViewController extends HeraldController {
pht('Active'));
}
$actions = $this->buildActionView($rule);
$properties = $this->buildPropertyView($rule);
$curtain = $this->buildCurtain($rule);
$details = $this->buildPropertySectionView($rule);
$description = $this->buildDescriptionView($rule);
@ -44,10 +43,6 @@ final class HeraldRuleViewController extends HeraldController {
$crumbs->addTextCrumb("H{$id}");
$crumbs->setBorder(true);
$object_box = id(new PHUIObjectBoxView())
->setHeader($header)
->addPropertyList($properties);
$timeline = $this->buildTransactionTimeline(
$rule,
new HeraldTransactionQuery());
@ -57,35 +52,30 @@ final class HeraldRuleViewController extends HeraldController {
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setCurtain($curtain)
->setMainColumn($timeline)
->addPropertySection(pht('DETAILS'), $details)
->addPropertySection(pht('DESCRIPTION'), $description)
->setPropertyList($properties)
->setActionList($actions);
->addPropertySection(pht('DESCRIPTION'), $description);
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild(
array(
$view,
));
->appendChild($view);
}
private function buildActionView(HeraldRule $rule) {
$viewer = $this->getRequest()->getUser();
$id = $rule->getID();
private function buildCurtain(HeraldRule $rule) {
$viewer = $this->getViewer();
$view = id(new PhabricatorActionListView())
->setUser($viewer)
->setObject($rule);
$id = $rule->getID();
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$rule,
PhabricatorPolicyCapability::CAN_EDIT);
$view->addAction(
$curtain = $this->newCurtainView($rule);
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('Edit Rule'))
->setHref($this->getApplicationURI("edit/{$id}/"))
@ -103,7 +93,7 @@ final class HeraldRuleViewController extends HeraldController {
$disable_name = pht('Archive Rule');
}
$view->addAction(
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('Disable Rule'))
->setHref($this->getApplicationURI($disable_uri))
@ -112,23 +102,10 @@ final class HeraldRuleViewController extends HeraldController {
->setDisabled(!$can_edit)
->setWorkflow(true));
return $view;
return $curtain;
}
private function buildPropertyView(
HeraldRule $rule) {
$viewer = $this->getRequest()->getUser();
$view = id(new PHUIPropertyListView())
->setUser($viewer)
->setObject($rule);
$view->invokeWillRenderEvent();
return $view;
}
private function buildPropertySectionView(
private function buildPropertySectionView(
HeraldRule $rule) {
$viewer = $this->getRequest()->getUser();

View file

@ -328,10 +328,6 @@ final class HeraldRule extends HeraldDAO
return $this->isPersonalRule() && $phid == $this->getAuthorPHID();
}
public function shouldShowSubscribersProperty() {
return true;
}
/* -( PhabricatorDestructibleInterface )----------------------------------- */

View file

@ -322,7 +322,7 @@ final class PhabricatorHomeMainController extends PhabricatorHomeController {
->setHref($href);
$header = id(new PHUIHeaderView())
->setHeader($title)
->addActionIcon($icon);
->addActionItem($icon);
return $header;
}

View file

@ -163,10 +163,6 @@ final class LegalpadDocument extends LegalpadDAO
return ($this->creatorPHID == $phid);
}
public function shouldShowSubscribersProperty() {
return true;
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */

View file

@ -23,9 +23,8 @@ final class PhabricatorMacroViewController
$title_short = pht('Macro "%s"', $macro->getName());
$title_long = pht('Image Macro "%s"', $macro->getName());
$actions = $this->buildActionView($macro);
$curtain = $this->buildCurtain($macro);
$subheader = $this->buildSubheaderView($macro);
$properties = $this->buildPropertyView($macro);
$file = $this->buildFileView($macro);
$details = $this->buildPropertySectionView($macro);
@ -40,7 +39,8 @@ final class PhabricatorMacroViewController
$header = id(new PHUIHeaderView())
->setUser($viewer)
->setPolicyObject($macro)
->setHeader($title_long);
->setHeader($macro->getName())
->setHeaderIcon('fa-file-image-o');
if (!$macro->getIsDisabled()) {
$header->setStatus('fa-check', 'bluegrey', pht('Active'));
@ -67,35 +67,29 @@ final class PhabricatorMacroViewController
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setSubheader($subheader)
->setCurtain($curtain)
->setMainColumn(array(
$timeline,
$add_comment_form,
))
->addPropertySection(pht('MACRO'), $file)
->addPropertySection(pht('DETAILS'), $details)
->setPropertyList($properties)
->setActionList($actions);
->addPropertySection(pht('DETAILS'), $details);
return $this->newPage()
->setTitle($title_short)
->setCrumbs($crumbs)
->setPageObjectPHIDs(array($macro->getPHID()))
->appendChild(
array(
$view,
));
->appendChild($view);
}
private function buildActionView(
private function buildCurtain(
PhabricatorFileImageMacro $macro) {
$can_manage = $this->hasApplicationCapability(
PhabricatorMacroManageCapability::CAPABILITY);
$request = $this->getRequest();
$view = id(new PhabricatorActionListView())
->setUser($request->getUser())
->setObject($macro)
->addAction(
$curtain = $this->newCurtainView($macro);
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('Edit Macro'))
->setHref($this->getApplicationURI('/edit/'.$macro->getID().'/'))
@ -103,7 +97,7 @@ final class PhabricatorMacroViewController
->setWorkflow(!$can_manage)
->setIcon('fa-pencil'));
$view->addAction(
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('Edit Audio'))
->setHref($this->getApplicationURI('/audio/'.$macro->getID().'/'))
@ -112,7 +106,7 @@ final class PhabricatorMacroViewController
->setIcon('fa-music'));
if ($macro->getIsDisabled()) {
$view->addAction(
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('Activate Macro'))
->setHref($this->getApplicationURI('/disable/'.$macro->getID().'/'))
@ -120,7 +114,7 @@ final class PhabricatorMacroViewController
->setDisabled(!$can_manage)
->setIcon('fa-check'));
} else {
$view->addAction(
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('Archive Macro'))
->setHref($this->getApplicationURI('/disable/'.$macro->getID().'/'))
@ -129,7 +123,7 @@ final class PhabricatorMacroViewController
->setIcon('fa-ban'));
}
return $view;
return $curtain;
}
private function buildSubheaderView(
@ -177,7 +171,11 @@ final class PhabricatorMacroViewController
$viewer->renderHandle($audio_phid));
}
return $view;
if ($view->hasAnyProperties()) {
return $view;
}
return null;
}
private function buildFileView(
@ -201,17 +199,4 @@ final class PhabricatorMacroViewController
return null;
}
private function buildPropertyView(
PhabricatorFileImageMacro $macro) {
$viewer = $this->getViewer();
$view = id(new PHUIPropertyListView())
->setUser($this->getRequest()->getUser())
->setObject($macro);
$view->invokeWillRenderEvent();
return $view;
}
}

View file

@ -111,10 +111,6 @@ final class PhabricatorFileImageMacro extends PhabricatorFileDAO
return false;
}
public function shouldShowSubscribersProperty() {
return true;
}
/* -( PhabricatorTokenRecevierInterface )---------------------------------- */

View file

@ -77,6 +77,7 @@ final class PhabricatorManiphestConfigOptions
'name.full' => pht('Closed, Resolved'),
'closed' => true,
'special' => ManiphestTaskStatus::SPECIAL_CLOSED,
'transaction.icon' => 'fa-check-circle',
'prefixes' => array(
'closed',
'closes',
@ -97,6 +98,7 @@ final class PhabricatorManiphestConfigOptions
'wontfix' => array(
'name' => pht('Wontfix'),
'name.full' => pht('Closed, Wontfix'),
'transaction.icon' => 'fa-ban',
'closed' => true,
'prefixes' => array(
'wontfix',
@ -110,6 +112,7 @@ final class PhabricatorManiphestConfigOptions
'invalid' => array(
'name' => pht('Invalid'),
'name.full' => pht('Closed, Invalid'),
'transaction.icon' => 'fa-minus-circle',
'closed' => true,
'claim' => false,
'prefixes' => array(

View file

@ -82,29 +82,22 @@ final class ManiphestTaskStatus extends ManiphestConstants {
return self::getStatusAttribute($status, 'name', pht('Unknown Status'));
}
public static function renderFullDescription($status) {
public static function renderFullDescription($status, $priority) {
if (self::isOpenStatus($status)) {
$color = 'status';
$icon_color = 'bluegrey';
$name = pht('%s, %s', self::getTaskStatusFullName($status), $priority);
$color = 'grey';
$icon = 'fa-square-o';
} else {
$color = 'status-dark';
$icon_color = '';
$name = self::getTaskStatusFullName($status);
$color = 'indigo';
$icon = 'fa-check-square-o';
}
$icon = self::getStatusIcon($status);
$img = id(new PHUIIconView())
->setIcon($icon.' '.$icon_color);
$tag = phutil_tag(
'span',
array(
'class' => 'phui-header-status phui-header-'.$color,
),
array(
$img,
self::getTaskStatusFullName($status),
));
$tag = id(new PHUITagView())
->setName($name)
->setIcon($icon)
->setType(PHUITagView::TYPE_SHADE)
->setShade($color);
return $tag;
}

View file

@ -26,6 +26,10 @@ final class ManiphestTaskDetailController extends ManiphestController {
->setViewer($viewer)
->readFieldsFromStorage($task);
$edit_engine = id(new ManiphestEditEngine())
->setViewer($viewer)
->setTargetObject($task);
$e_commit = ManiphestTaskHasCommitEdgeType::EDGECONST;
$e_dep_on = ManiphestTaskDependsOnTaskEdgeType::EDGECONST;
$e_dep_by = ManiphestTaskDependedOnByTaskEdgeType::EDGECONST;
@ -65,34 +69,34 @@ final class ManiphestTaskDetailController extends ManiphestController {
new ManiphestTransactionQuery(),
$engine);
$actions = $this->buildActionView($task);
$monogram = $task->getMonogram();
$crumbs = $this->buildApplicationCrumbs()
->addTextCrumb($monogram, '/'.$monogram);
->addTextCrumb($monogram)
->setBorder(true);
$header = $this->buildHeaderView($task);
$properties = $this->buildPropertyView(
$task, $field_list, $edges, $actions, $handles);
$details = $this->buildPropertyView($task, $field_list, $edges, $handles);
$description = $this->buildDescriptionView($task, $engine);
$object_box = id(new PHUIObjectBoxView())
->setHeader($header)
->addPropertyList($properties);
if ($description) {
$object_box->addPropertyList($description);
}
$curtain = $this->buildCurtain($task, $edit_engine);
$title = pht('%s %s', $monogram, $task->getTitle());
$comment_view = id(new ManiphestEditEngine())
->setViewer($viewer)
$comment_view = $edit_engine
->buildEditEngineCommentView($task);
$timeline->setQuoteRef($monogram);
$comment_view->setTransactionTimeline($timeline);
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setCurtain($curtain)
->setMainColumn(array(
$timeline,
$comment_view,
))
->addPropertySection(pht('DESCRIPTION'), $description)
->addPropertySection(pht('DETAILS'), $details);
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
@ -102,10 +106,9 @@ final class ManiphestTaskDetailController extends ManiphestController {
))
->appendChild(
array(
$object_box,
$timeline,
$comment_view,
));
$view,
));
}
private function buildHeaderView(ManiphestTask $task) {
@ -114,17 +117,42 @@ final class ManiphestTaskDetailController extends ManiphestController {
->setUser($this->getRequest()->getUser())
->setPolicyObject($task);
$status = $task->getStatus();
$status_name = ManiphestTaskStatus::renderFullDescription($status);
$priority_name = ManiphestTaskPriority::getTaskPriorityName(
$task->getPriority());
$priority_color = ManiphestTaskPriority::getTaskPriorityColor(
$task->getPriority());
$status = $task->getStatus();
$status_name = ManiphestTaskStatus::renderFullDescription(
$status, $priority_name, $priority_color);
$view->addProperty(PHUIHeaderView::PROPERTY_STATUS, $status_name);
$view->setHeaderIcon(ManiphestTaskStatus::getStatusIcon(
$task->getStatus()).' '.$priority_color);
if (ManiphestTaskPoints::getIsEnabled()) {
$points = $task->getPoints();
if ($points !== null) {
$points_name = pht('%s %s',
$task->getPoints(),
ManiphestTaskPoints::getPointsLabel());
$tag = id(new PHUITagView())
->setName($points_name)
->setShade('blue')
->setType(PHUITagView::TYPE_SHADE);
$view->addTag($tag);
}
}
return $view;
}
private function buildActionView(ManiphestTask $task) {
$viewer = $this->getRequest()->getUser();
private function buildCurtain(
ManiphestTask $task,
PhabricatorEditEngine $edit_engine) {
$viewer = $this->getViewer();
$id = $task->getID();
$phid = $task->getPHID();
@ -134,11 +162,9 @@ final class ManiphestTaskDetailController extends ManiphestController {
$task,
PhabricatorPolicyCapability::CAN_EDIT);
$view = id(new PhabricatorActionListView())
->setUser($viewer)
->setObject($task);
$curtain = $this->newCurtainView($task);
$view->addAction(
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('Edit Task'))
->setIcon('fa-pencil')
@ -146,7 +172,7 @@ final class ManiphestTaskDetailController extends ManiphestController {
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit));
$view->addAction(
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('Merge Duplicates In'))
->setHref("/search/attach/{$phid}/TASK/merge/")
@ -155,11 +181,12 @@ final class ManiphestTaskDetailController extends ManiphestController {
->setDisabled(!$can_edit)
->setWorkflow(true));
$edit_config = id(new ManiphestEditEngine())
->setViewer($viewer)
->loadDefaultEditConfiguration();
$edit_config = $edit_engine->loadDefaultEditConfiguration();
$can_create = (bool)$edit_config;
$can_reassign = $edit_engine->hasEditAccessToTransaction(
ManiphestTransaction::TYPE_OWNER);
if ($can_create) {
$form_key = $edit_config->getIdentifier();
$edit_uri = id(new PhutilURI("/task/edit/form/{$form_key}/"))
@ -174,7 +201,7 @@ final class ManiphestTaskDetailController extends ManiphestController {
$edit_uri = $this->getApplicationURI($edit_uri);
}
$view->addAction(
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('Create Subtask'))
->setHref($edit_uri)
@ -182,7 +209,7 @@ final class ManiphestTaskDetailController extends ManiphestController {
->setDisabled(!$can_create)
->setWorkflow(!$can_create));
$view->addAction(
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('Edit Blocking Tasks'))
->setHref("/search/attach/{$phid}/TASK/blocks/")
@ -191,52 +218,55 @@ final class ManiphestTaskDetailController extends ManiphestController {
->setDisabled(!$can_edit)
->setWorkflow(true));
return $view;
$owner_phid = $task->getOwnerPHID();
$author_phid = $task->getAuthorPHID();
$handles = $viewer->loadHandles(array($owner_phid, $author_phid));
if ($owner_phid) {
$image_uri = $handles[$owner_phid]->getImageURI();
$image_href = $handles[$owner_phid]->getURI();
$owner = $viewer->renderHandle($owner_phid)->render();
$content = phutil_tag('strong', array(), $owner);
$assigned_to = id(new PHUIHeadThingView())
->setImage($image_uri)
->setImageHref($image_href)
->setContent($content);
} else {
$assigned_to = phutil_tag('em', array(), pht('None'));
}
$curtain->newPanel()
->setHeaderText(pht('Assigned To'))
->appendChild($assigned_to);
$author_uri = $handles[$author_phid]->getImageURI();
$author_href = $handles[$author_phid]->getURI();
$author = $viewer->renderHandle($author_phid)->render();
$content = phutil_tag('strong', array(), $author);
$date = phabricator_date($task->getDateCreated(), $viewer);
$content = pht('%s, %s', $content, $date);
$authored_by = id(new PHUIHeadThingView())
->setImage($author_uri)
->setImageHref($author_href)
->setContent($content);
$curtain->newPanel()
->setHeaderText(pht('Authored By'))
->appendChild($authored_by);
return $curtain;
}
private function buildPropertyView(
ManiphestTask $task,
PhabricatorCustomFieldList $field_list,
array $edges,
PhabricatorActionListView $actions,
$handles) {
$viewer = $this->getRequest()->getUser();
$view = id(new PHUIPropertyListView())
->setUser($viewer)
->setObject($task)
->setActionList($actions);
$owner_phid = $task->getOwnerPHID();
if ($owner_phid) {
$assigned_to = $handles
->renderHandle($owner_phid)
->setShowHovercard(true);
} else {
$assigned_to = phutil_tag('em', array(), pht('None'));
}
$view->addProperty(pht('Assigned To'), $assigned_to);
$view->addProperty(
pht('Priority'),
ManiphestTaskPriority::getTaskPriorityName($task->getPriority()));
$author = $handles
->renderHandle($task->getAuthorPHID())
->setShowHovercard(true);
$view->addProperty(pht('Author'), $author);
if (ManiphestTaskPoints::getIsEnabled()) {
$points = $task->getPoints();
if ($points !== null) {
$view->addProperty(
ManiphestTaskPoints::getPointsLabel(),
$task->getPoints());
}
}
->setUser($viewer);
$source = $task->getOriginalEmailSource();
if ($source) {
@ -304,14 +334,16 @@ final class ManiphestTaskDetailController extends ManiphestController {
phutil_implode_html(phutil_tag('br'), $revisions_commits));
}
$view->invokeWillRenderEvent();
$field_list->appendFieldsToPropertyList(
$task,
$viewer,
$view);
return $view;
if ($view->hasAnyProperties()) {
return $view;
}
return null;
}
private function buildDescriptionView(
@ -321,9 +353,6 @@ final class ManiphestTaskDetailController extends ManiphestController {
$section = null;
if (strlen($task->getDescription())) {
$section = new PHUIPropertyListView();
$section->addSectionHeader(
pht('Description'),
PHUIPropertyListView::ICON_SUMMARY);
$section->addTextContent(
phutil_tag(
'div',

View file

@ -269,10 +269,6 @@ final class ManiphestTask extends ManiphestDAO
return ($phid == $this->getOwnerPHID());
}
public function shouldShowSubscribersProperty() {
return true;
}
/* -( Markup Interface )--------------------------------------------------- */

View file

@ -301,7 +301,7 @@ final class ManiphestTransaction
if ($this->getAuthorPHID() == $new) {
return pht('Claimed');
} else if (!$new) {
return pht('Up For Grabs');
return pht('Unassigned');
} else if (!$old) {
return pht('Assigned');
} else {
@ -547,8 +547,9 @@ final class ManiphestTransaction
$this->renderHandleLink($author_phid));
} else if (!$new) {
return pht(
'%s placed this task up for grabs.',
$this->renderHandleLink($author_phid));
'%s removed %s as the assignee of this task.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($old));
} else if (!$old) {
return pht(
'%s assigned this task to %s.',

View file

@ -24,11 +24,13 @@ final class PhabricatorApplicationDetailViewController
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb($selected->getName());
$crumbs->setBorder(true);
$header = id(new PHUIHeaderView())
->setHeader($title)
->setUser($viewer)
->setPolicyObject($selected);
->setPolicyObject($selected)
->setHeaderIcon($selected->getIcon());
if ($selected->isInstalled()) {
$header->setStatus('fa-check', 'bluegrey', pht('Installed'));
@ -36,12 +38,9 @@ final class PhabricatorApplicationDetailViewController
$header->setStatus('fa-ban', 'dark', pht('Uninstalled'));
}
$actions = $this->buildActionView($viewer, $selected);
$properties = $this->buildPropertyView($selected, $actions);
$object_box = id(new PHUIObjectBoxView())
->setHeader($header)
->addPropertyList($properties);
$curtain = $this->buildCurtain($selected);
$details = $this->buildPropertySectionView($selected);
$policies = $this->buildPolicyView($selected);
$configs =
PhabricatorApplicationConfigurationPanel::loadAllPanelsForApplication(
@ -51,29 +50,35 @@ final class PhabricatorApplicationDetailViewController
foreach ($configs as $config) {
$config->setViewer($viewer);
$config->setApplication($selected);
$panel = $config->buildConfigurationPagePanel();
$panel->setBackground(PHUIObjectBoxView::BLUE_PROPERTY);
$panels[] = $panel;
$panels[] = $config->buildConfigurationPagePanel();
}
return $this->buildApplicationPage(
array(
$crumbs,
$object_box,
$panels,
),
array(
'title' => $title,
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setCurtain($curtain)
->setMainColumn(array(
$policies,
$panels,
))
->addPropertySection(pht('DETAILS'), $details);
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild(
array(
$view,
));
}
private function buildPropertyView(
PhabricatorApplication $application,
PhabricatorActionListView $actions) {
$viewer = $this->getRequest()->getUser();
private function buildPropertySectionView(
PhabricatorApplication $application) {
$viewer = $this->getViewer();
$properties = id(new PHUIPropertyListView());
$properties->setActionList($actions);
$properties->addProperty(
pht('Description'),
@ -111,37 +116,53 @@ final class PhabricatorApplicationDetailViewController
$properties->addTextContent($overview);
}
return $properties;
}
private function buildPolicyView(
PhabricatorApplication $application) {
$viewer = $this->getViewer();
$properties = id(new PHUIPropertyListView())
->setStacked(true);
$header = id(new PHUIHeaderView())
->setHeader(pht('POLICIES'))
->setHeaderIcon('fa-lock');
$descriptions = PhabricatorPolicyQuery::renderPolicyDescriptions(
$viewer,
$application);
$properties->addSectionHeader(
pht('Policies'), 'fa-lock');
foreach ($application->getCapabilities() as $capability) {
$properties->addProperty(
$application->getCapabilityLabel($capability),
idx($descriptions, $capability));
}
return $properties;
return id(new PHUIObjectBoxView())
->setHeader($header)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->appendChild($properties);
}
private function buildActionView(
PhabricatorUser $user,
PhabricatorApplication $selected) {
$view = id(new PhabricatorActionListView())
->setUser($user);
private function buildCurtain(PhabricatorApplication $application) {
$viewer = $this->getViewer();
$can_edit = PhabricatorPolicyFilter::hasCapability(
$user,
$selected,
$viewer,
$application,
PhabricatorPolicyCapability::CAN_EDIT);
$edit_uri = $this->getApplicationURI('edit/'.get_class($selected).'/');
$key = get_class($application);
$edit_uri = $this->getApplicationURI("edit/{$key}/");
$install_uri = $this->getApplicationURI("{$key}/install/");
$uninstall_uri = $this->getApplicationURI("{$key}/uninstall/");
$view->addAction(
$curtain = $this->newCurtainView($application);
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('Edit Policies'))
->setIcon('fa-pencil')
@ -149,45 +170,42 @@ final class PhabricatorApplicationDetailViewController
->setWorkflow(!$can_edit)
->setHref($edit_uri));
if ($selected->canUninstall()) {
if ($selected->isInstalled()) {
$view->addAction(
if ($application->canUninstall()) {
if ($application->isInstalled()) {
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('Uninstall'))
->setIcon('fa-times')
->setDisabled(!$can_edit)
->setWorkflow(true)
->setHref(
$this->getApplicationURI(get_class($selected).'/uninstall/')));
->setHref($uninstall_uri));
} else {
$action = id(new PhabricatorActionView())
->setName(pht('Install'))
->setIcon('fa-plus')
->setDisabled(!$can_edit)
->setWorkflow(true)
->setHref(
$this->getApplicationURI(get_class($selected).'/install/'));
->setHref($install_uri);
$prototypes_enabled = PhabricatorEnv::getEnvConfig(
'phabricator.show-prototypes');
if ($selected->isPrototype() && !$prototypes_enabled) {
if ($application->isPrototype() && !$prototypes_enabled) {
$action->setDisabled(true);
}
$view->addAction($action);
$curtain->addAction($action);
}
} else {
$view->addAction(
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('Uninstall'))
->setIcon('fa-times')
->setWorkflow(true)
->setDisabled(true)
->setHref(
$this->getApplicationURI(get_class($selected).'/uninstall/')));
->setHref($uninstall_uri));
}
return $view;
return $curtain;
}
}

View file

@ -9,6 +9,13 @@ final class PhabricatorContentSourceView extends AphrontView {
return $this;
}
public function getSourceName() {
$map = PhabricatorContentSource::getSourceNameMap();
$source = $this->contentSource->getSource();
return idx($map, $source, null);
}
public function render() {
require_celerity_resource('phabricator-content-source-view-css');

View file

@ -254,10 +254,19 @@ abstract class PhabricatorMailReplyHandler extends Phobject {
$map = $to + $cc;
foreach ($map as $phid => $user) {
// Preserve the original To/Cc information on the target.
if (isset($to[$phid])) {
$target_to = array($phid => $user);
$target_cc = array();
} else {
$target_to = array();
$target_cc = array($phid => $user);
}
$target = id(clone $template)
->setViewer($user)
->setToMap(array($phid => $user))
->setCCMap(array());
->setToMap($target_to)
->setCCMap($target_cc);
if ($supports_private_replies) {
$reply_to = $this->getPrivateReplyHandlerEmailAddress($user);

View file

@ -40,22 +40,19 @@ final class PhabricatorNuanceApplication extends PhabricatorApplication {
'/nuance/' => array(
'' => 'NuanceConsoleController',
'item/' => array(
$this->getQueryRoutePattern() => 'NuanceItemListController',
'view/(?P<id>[1-9]\d*)/' => 'NuanceItemViewController',
'edit/(?P<id>[1-9]\d*)/' => 'NuanceItemEditController',
'new/' => 'NuanceItemEditController',
'manage/(?P<id>[1-9]\d*)/' => 'NuanceItemManageController',
),
'source/' => array(
'(?:query/(?P<queryKey>[^/]+)/)?' => 'NuanceSourceListController',
$this->getQueryRoutePattern() => 'NuanceSourceListController',
$this->getEditRoutePattern('edit/') => 'NuanceSourceEditController',
'view/(?P<id>[1-9]\d*)/' => 'NuanceSourceViewController',
'edit/(?P<id>[1-9]\d*)/' => 'NuanceSourceEditController',
'new/(?P<type>[^/]+)/' => 'NuanceSourceEditController',
'create/' => 'NuanceSourceCreateController',
),
'queue/' => array(
'(?:query/(?P<queryKey>[^/]+)/)?' => 'NuanceQueueListController',
$this->getQueryRoutePattern() => 'NuanceQueueListController',
$this->getEditRoutePattern('edit/') => 'NuanceQueueEditController',
'view/(?P<id>[1-9]\d*)/' => 'NuanceQueueViewController',
'edit/(?P<id>[1-9]\d*)/' => 'NuanceQueueEditController',
'new/' => 'NuanceQueueEditController',
),
'requestor/' => array(
'view/(?P<id>[1-9]\d*)/' => 'NuanceRequestorViewController',

View file

@ -1,73 +0,0 @@
<?php
final class NuanceCreateItemConduitAPIMethod extends NuanceConduitAPIMethod {
public function getAPIMethodName() {
return 'nuance.createitem';
}
public function getMethodDescription() {
return pht('Create a new item.');
}
protected function defineParamTypes() {
return array(
'requestorPHID' => 'required string',
'sourcePHID' => 'required string',
'ownerPHID' => 'optional string',
);
}
protected function defineReturnType() {
return 'nonempty dict';
}
protected function defineErrorTypes() {
return array(
'ERR-NO-REQUESTOR-PHID' => pht('Items must have a requestor.'),
'ERR-NO-SOURCE-PHID' => pht('Items must have a source.'),
);
}
protected function execute(ConduitAPIRequest $request) {
$source_phid = $request->getValue('sourcePHID');
$owner_phid = $request->getValue('ownerPHID');
$requestor_phid = $request->getValue('requestorPHID');
$user = $request->getUser();
$item = NuanceItem::initializeNewItem();
$xactions = array();
if ($source_phid) {
$xactions[] = id(new NuanceItemTransaction())
->setTransactionType(NuanceItemTransaction::TYPE_SOURCE)
->setNewValue($source_phid);
} else {
throw new ConduitException('ERR-NO-SOURCE-PHID');
}
if ($owner_phid) {
$xactions[] = id(new NuanceItemTransaction())
->setTransactionType(NuanceItemTransaction::TYPE_OWNER)
->setNewValue($owner_phid);
}
if ($requestor_phid) {
$xactions[] = id(new NuanceItemTransaction())
->setTransactionType(NuanceItemTransaction::TYPE_REQUESTOR)
->setNewValue($requestor_phid);
} else {
throw new ConduitException('ERR-NO-REQUESTOR-PHID');
}
$source = PhabricatorContentSource::newFromConduitRequest($request);
$editor = id(new NuanceItemEditor())
->setActor($user)
->setContentSource($source)
->applyTransactions($item, $xactions);
return $item->toDictionary();
}
}

View file

@ -26,6 +26,13 @@ final class NuanceConsoleController extends NuanceController {
->setIcon('fa-filter')
->addAttribute(pht('Manage Nuance sources.')));
$menu->addItem(
id(new PHUIObjectItemView())
->setHeader(pht('Items'))
->setHref($this->getApplicationURI('item/'))
->setIcon('fa-clone')
->addAttribute(pht('Manage Nuance items.')));
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Console'));

View file

@ -0,0 +1,11 @@
<?php
abstract class NuanceItemController
extends NuanceController {
public function buildApplicationMenu() {
return $this->newApplicationMenu()
->setSearchEngine(new NuanceItemSearchEngine());
}
}

View file

@ -1,104 +0,0 @@
<?php
final class NuanceItemEditController extends NuanceController {
public function handleRequest(AphrontRequest $request) {
$viewer = $this->getViewer();
$id = $request->getURIData('id');
$item = id(new NuanceItemQuery())
->setViewer($viewer)
->withIDs(array($id))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$item) {
return new Aphront404Response();
}
$title = pht('Item %d', $item->getID());
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb($title);
$crumbs->addTextCrumb(pht('Edit'));
$properties = $this->buildPropertyView($item);
$actions = $this->buildActionView($item);
$properties->setActionList($actions);
$box = id(new PHUIObjectBoxView())
->setHeaderText($title)
->addPropertyList($properties);
$timeline = $this->buildTransactionTimeline(
$item,
new NuanceItemTransactionQuery());
$timeline->setShouldTerminate(true);
return $this->buildApplicationPage(
array(
$crumbs,
$box,
$timeline,
),
array(
'title' => $title,
));
}
private function buildPropertyView(NuanceItem $item) {
$viewer = $this->getViewer();
$properties = id(new PHUIPropertyListView())
->setUser($viewer)
->setObject($item);
$properties->addProperty(
pht('Date Created'),
phabricator_datetime($item->getDateCreated(), $viewer));
$properties->addProperty(
pht('Requestor'),
$viewer->renderHandle($item->getRequestorPHID()));
$properties->addProperty(
pht('Source'),
$viewer->renderHandle($item->getSourcePHID()));
$properties->addProperty(
pht('Queue'),
$viewer->renderHandle($item->getQueuePHID()));
$source = $item->getSource();
$definition = $source->requireDefinition();
$definition->renderItemEditProperties(
$viewer,
$item,
$properties);
return $properties;
}
private function buildActionView(NuanceItem $item) {
$viewer = $this->getViewer();
$id = $item->getID();
$actions = id(new PhabricatorActionListView())
->setUser($viewer);
$actions->addAction(
id(new PhabricatorActionView())
->setName(pht('View Item'))
->setIcon('fa-eye')
->setHref($this->getApplicationURI("item/view/{$id}/")));
return $actions;
}
}

View file

@ -0,0 +1,12 @@
<?php
final class NuanceItemListController
extends NuanceItemController {
public function handleRequest(AphrontRequest $request) {
return id(new NuanceItemSearchEngine())
->setController($this)
->buildResponse();
}
}

View file

@ -0,0 +1,109 @@
<?php
final class NuanceItemManageController extends NuanceController {
public function handleRequest(AphrontRequest $request) {
$viewer = $this->getViewer();
$id = $request->getURIData('id');
$item = id(new NuanceItemQuery())
->setViewer($viewer)
->withIDs(array($id))
->executeOne();
if (!$item) {
return new Aphront404Response();
}
$title = pht('Item %d', $item->getID());
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(
pht('Items'),
$this->getApplicationURI('item/'));
$crumbs->addTextCrumb(
$title,
$item->getURI());
$crumbs->addTextCrumb(pht('Manage'));
$crumbs->setBorder(true);
$properties = $this->buildPropertyView($item);
$curtain = $this->buildCurtain($item);
$header = id(new PHUIHeaderView())
->setHeader($title);
$timeline = $this->buildTransactionTimeline(
$item,
new NuanceItemTransactionQuery());
$timeline->setShouldTerminate(true);
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setCurtain($curtain)
->addPropertySection(pht('DETAILS'), $properties)
->setMainColumn($timeline);
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($view);
}
private function buildPropertyView(NuanceItem $item) {
$viewer = $this->getViewer();
$properties = id(new PHUIPropertyListView())
->setUser($viewer);
$properties->addProperty(
pht('Date Created'),
phabricator_datetime($item->getDateCreated(), $viewer));
$requestor_phid = $item->getRequestorPHID();
if ($requestor_phid) {
$requestor_view = $viewer->renderHandle($requestor_phid);
} else {
$requestor_view = phutil_tag('em', array(), pht('None'));
}
$properties->addProperty(pht('Requestor'), $requestor_view);
$properties->addProperty(
pht('Source'),
$viewer->renderHandle($item->getSourcePHID()));
$queue_phid = $item->getQueuePHID();
if ($queue_phid) {
$queue_view = $viewer->renderHandle($queue_phid);
} else {
$queue_view = phutil_tag('em', array(), pht('None'));
}
$properties->addProperty(pht('Queue'), $queue_view);
$source = $item->getSource();
$definition = $source->getDefinition();
$definition->renderItemEditProperties(
$viewer,
$item,
$properties);
return $properties;
}
private function buildCurtain(NuanceItem $item) {
$viewer = $this->getViewer();
$id = $item->getID();
$curtain = $this->newCurtainView($item);
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('View Item'))
->setIcon('fa-eye')
->setHref($item->getURI()));
return $curtain;
}
}

View file

@ -15,72 +15,58 @@ final class NuanceItemViewController extends NuanceController {
}
$title = pht('Item %d', $item->getID());
$name = $item->getDisplayName();
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(
pht('Items'),
$this->getApplicationURI('item/'));
$crumbs->addTextCrumb($title);
$crumbs->setBorder(true);
$properties = $this->buildPropertyView($item);
$actions = $this->buildActionView($item);
$properties->setActionList($actions);
$curtain = $this->buildCurtain($item);
$content = $this->buildContent($item);
$box = id(new PHUIObjectBoxView())
->setHeaderText($title)
->addPropertyList($properties);
$header = id(new PHUIHeaderView())
->setHeader($name);
return $this->buildApplicationPage(
array(
$crumbs,
$box,
),
array(
'title' => $title,
));
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setCurtain($curtain)
->setMainColumn($content);
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($view);
}
private function buildPropertyView(NuanceItem $item) {
$viewer = $this->getViewer();
$properties = id(new PHUIPropertyListView())
->setUser($viewer)
->setObject($item);
$properties->addProperty(
pht('Date Created'),
phabricator_datetime($item->getDateCreated(), $viewer));
$source = $item->getSource();
$definition = $source->requireDefinition();
$definition->renderItemViewProperties(
$viewer,
$item,
$properties);
return $properties;
}
private function buildActionView(NuanceItem $item) {
private function buildCurtain(NuanceItem $item) {
$viewer = $this->getViewer();
$id = $item->getID();
$actions = id(new PhabricatorActionListView())
->setUser($viewer);
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$item,
PhabricatorPolicyCapability::CAN_EDIT);
$actions->addAction(
id(new PhabricatorActionView())
->setName(pht('Edit Item'))
->setIcon('fa-pencil')
->setHref($this->getApplicationURI("item/edit/{$id}/"))
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit));
$curtain = $this->newCurtainView($item);
return $actions;
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('Manage Item'))
->setIcon('fa-cogs')
->setHref($this->getApplicationURI("item/manage/{$id}/")));
return $curtain;
}
private function buildContent(NuanceItem $item) {
$viewer = $this->getViewer();
$impl = $item->getImplementation();
$impl->setViewer($viewer);
return $impl->buildItemView($item);
}
}

View file

@ -0,0 +1,11 @@
<?php
abstract class NuanceQueueController
extends NuanceController {
public function buildApplicationMenu() {
return $this->newApplicationMenu()
->setSearchEngine(new NuanceQueueSearchEngine());
}
}

View file

@ -1,135 +1,12 @@
<?php
final class NuanceQueueEditController extends NuanceController {
final class NuanceQueueEditController
extends NuanceQueueController {
public function handleRequest(AphrontRequest $request) {
$viewer = $this->getViewer();
$queues_uri = $this->getApplicationURI('queue/');
$queue_id = $request->getURIData('id');
$is_new = !$queue_id;
if ($is_new) {
$queue = NuanceQueue::initializeNewQueue();
$cancel_uri = $queues_uri;
} else {
$queue = id(new NuanceQueueQuery())
->setViewer($viewer)
->withIDs(array($queue_id))
->executeOne();
if (!$queue) {
return new Aphront404Response();
}
$cancel_uri = $queue->getURI();
}
$v_name = $queue->getName();
$e_name = true;
$v_edit = $queue->getEditPolicy();
$v_view = $queue->getViewPolicy();
$validation_exception = null;
if ($request->isFormPost()) {
$e_name = null;
$v_name = $request->getStr('name');
$v_edit = $request->getStr('editPolicy');
$v_view = $request->getStr('viewPolicy');
$type_name = NuanceQueueTransaction::TYPE_NAME;
$type_view = PhabricatorTransactions::TYPE_VIEW_POLICY;
$type_edit = PhabricatorTransactions::TYPE_EDIT_POLICY;
$xactions = array();
$xactions[] = id(new NuanceQueueTransaction())
->setTransactionType($type_name)
->setNewValue($v_name);
$xactions[] = id(new NuanceQueueTransaction())
->setTransactionType($type_view)
->setNewValue($v_view);
$xactions[] = id(new NuanceQueueTransaction())
->setTransactionType($type_edit)
->setNewValue($v_edit);
$editor = id(new NuanceQueueEditor())
->setActor($viewer)
->setContentSourceFromRequest($request)
->setContinueOnNoEffect(true);
try {
$editor->applyTransactions($queue, $xactions);
$uri = $queue->getURI();
return id(new AphrontRedirectResponse())->setURI($uri);
} catch (PhabricatorApplicationTransactionValidationException $ex) {
$validation_exception = $ex;
$e_name = $ex->getShortMessage($type_name);
}
}
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Queues'), $queues_uri);
if ($is_new) {
$title = pht('Create Queue');
$crumbs->addTextCrumb(pht('Create'));
} else {
$title = pht('Edit %s', $queue->getName());
$crumbs->addTextCrumb($queue->getName(), $queue->getURI());
$crumbs->addTextCrumb(pht('Edit'));
}
$policies = id(new PhabricatorPolicyQuery())
->setViewer($viewer)
->setObject($queue)
->execute();
$form = id(new AphrontFormView())
->setUser($viewer)
->appendChild(
id(new AphrontFormTextControl())
->setLabel(pht('Name'))
->setName('name')
->setError($e_name)
->setValue($v_name))
->appendChild(
id(new AphrontFormPolicyControl())
->setUser($viewer)
->setCapability(PhabricatorPolicyCapability::CAN_VIEW)
->setPolicyObject($queue)
->setPolicies($policies)
->setValue($v_view)
->setName('viewPolicy'))
->appendChild(
id(new AphrontFormPolicyControl())
->setUser($viewer)
->setCapability(PhabricatorPolicyCapability::CAN_EDIT)
->setPolicyObject($queue)
->setPolicies($policies)
->setValue($v_edit)
->setName('editPolicy'))
->appendChild(
id(new AphrontFormSubmitControl())
->addCancelButton($cancel_uri)
->setValue(pht('Save')));
$box = id(new PHUIObjectBoxView())
->setHeaderText($title)
->setValidationException($validation_exception)
->appendChild($form);
return $this->buildApplicationPage(
array(
$crumbs,
$box,
),
array(
'title' => $title,
));
return id(new NuanceQueueEditEngine())
->setController($this)
->buildResponse();
}
}

View file

@ -1,46 +1,20 @@
<?php
final class NuanceQueueListController
extends NuanceController {
extends NuanceQueueController {
public function handleRequest(AphrontRequest $request) {
$request = $this->getRequest();
$controller = id(new PhabricatorApplicationSearchController($request))
->setQueryKey($request->getURIData('queryKey'))
->setSearchEngine(new NuanceQueueSearchEngine())
->setNavigation($this->buildSideNavView());
return $this->delegateToController($controller);
}
public function buildSideNavView($for_app = false) {
$user = $this->getRequest()->getUser();
$nav = new AphrontSideNavFilterView();
$nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
id(new NuanceQueueSearchEngine())
->setViewer($user)
->addNavigationItems($nav->getMenu());
$nav->selectFilter(null);
return $nav;
return id(new NuanceQueueSearchEngine())
->setController($this)
->buildResponse();
}
protected function buildApplicationCrumbs() {
$crumbs = parent::buildApplicationCrumbs();
// TODO: Maybe use SourceManage capability?
$can_create = true;
$crumbs->addAction(
id(new PHUIListItemView())
->setName(pht('Create Queue'))
->setHref($this->getApplicationURI('queue/new/'))
->setIcon('fa-plus-square')
->setDisabled(!$can_create)
->setWorkflow(!$can_create));
id(new NuanceQueueEditEngine())
->setViewer($this->getViewer())
->addActionToCrumbs($crumbs);
return $crumbs;
}

View file

@ -1,6 +1,7 @@
<?php
final class NuanceQueueViewController extends NuanceController {
final class NuanceQueueViewController
extends NuanceQueueController {
public function handleRequest(AphrontRequest $request) {
$viewer = $this->getViewer();
@ -18,29 +19,25 @@ final class NuanceQueueViewController extends NuanceController {
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Queues'), $this->getApplicationURI('queue/'));
$crumbs->addTextCrumb($queue->getName());
$crumbs->setBorder(true);
$header = $this->buildHeaderView($queue);
$actions = $this->buildActionView($queue);
$properties = $this->buildPropertyView($queue, $actions);
$box = id(new PHUIObjectBoxView())
->setHeader($header)
->addPropertyList($properties);
$curtain = $this->buildCurtain($queue);
$timeline = $this->buildTransactionTimeline(
$queue,
new NuanceQueueTransactionQuery());
$timeline->setShouldTerminate(true);
return $this->buildApplicationPage(
array(
$crumbs,
$box,
$timeline,
),
array(
'title' => $title,
));
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setCurtain($curtain)
->setMainColumn($timeline);
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($view);
}
private function buildHeaderView(NuanceQueue $queue) {
@ -54,19 +51,18 @@ final class NuanceQueueViewController extends NuanceController {
return $header;
}
private function buildActionView(NuanceQueue $queue) {
private function buildCurtain(NuanceQueue $queue) {
$viewer = $this->getViewer();
$id = $queue->getID();
$actions = id(new PhabricatorActionListView())
->setUser($viewer);
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$queue,
PhabricatorPolicyCapability::CAN_EDIT);
$actions->addAction(
$curtain = $this->newCurtainView($queue);
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('Edit Queue'))
->setIcon('fa-pencil')
@ -74,19 +70,7 @@ final class NuanceQueueViewController extends NuanceController {
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit));
return $actions;
return $curtain;
}
private function buildPropertyView(
NuanceQueue $queue,
PhabricatorActionListView $actions) {
$viewer = $this->getViewer();
$properties = id(new PHUIPropertyListView())
->setUser($viewer)
->setObject($queue)
->setActionList($actions);
return $properties;
}
}

View file

@ -13,8 +13,11 @@ final class NuanceSourceActionController extends NuanceController {
return new Aphront404Response();
}
$def = $source->requireDefinition();
$def->setActor($viewer);
$def = $source->getDefinition();
$def
->setViewer($viewer)
->setSource($source);
$response = $def->handleActionRequest($request);
if ($response instanceof AphrontResponse) {
@ -25,14 +28,10 @@ final class NuanceSourceActionController extends NuanceController {
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb($title);
return $this->buildApplicationPage(
array(
$crumbs,
$response,
),
array(
'title' => $title,
));
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($response);
}
}

View file

@ -0,0 +1,11 @@
<?php
abstract class NuanceSourceController
extends NuanceController {
public function buildApplicationMenu() {
return $this->newApplicationMenu()
->setSearchEngine(new NuanceSourceSearchEngine());
}
}

View file

@ -1,57 +0,0 @@
<?php
final class NuanceSourceCreateController extends NuanceController {
public function handleRequest(AphrontRequest $request) {
$can_edit = $this->requireApplicationCapability(
NuanceSourceManageCapability::CAPABILITY);
$viewer = $this->getViewer();
$map = NuanceSourceDefinition::getAllDefinitions();
$cancel_uri = $this->getApplicationURI('source/');
if ($request->isFormPost()) {
$type = $request->getStr('type');
if (isset($map[$type])) {
$uri = $this->getApplicationURI('source/new/'.$type.'/');
return id(new AphrontRedirectResponse())->setURI($uri);
}
}
$source_types = id(new AphrontFormRadioButtonControl())
->setName('type')
->setLabel(pht('Source Type'));
foreach ($map as $type => $definition) {
$source_types->addButton(
$type,
$definition->getName(),
$definition->getSourceDescription());
}
$form = id(new AphrontFormView())
->setUser($viewer)
->appendChild($source_types)
->appendChild(
id(new AphrontFormSubmitControl())
->setValue(pht('Continue'))
->addCancelButton($cancel_uri));
$box = id(new PHUIObjectBoxView())
->setHeaderText(pht('Choose Source Type'))
->appendChild($form);
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Sources'), $cancel_uri);
$crumbs->addTextCrumb(pht('New'));
return $this->buildApplicationPage(
array(
$crumbs,
$box,
),
array(
'title' => pht('Choose Source Type'),
));
}
}

View file

@ -1,72 +1,76 @@
<?php
final class NuanceSourceEditController extends NuanceController {
final class NuanceSourceEditController
extends NuanceSourceController {
public function handleRequest(AphrontRequest $request) {
$can_edit = $this->requireApplicationCapability(
NuanceSourceManageCapability::CAPABILITY);
$engine = id(new NuanceSourceEditEngine())
->setController($this);
$viewer = $this->getViewer();
$id = $request->getURIData('id');
if (!$id) {
$this->requireApplicationCapability(
NuanceSourceManageCapability::CAPABILITY);
$sources_uri = $this->getApplicationURI('source/');
$source_id = $request->getURIData('id');
$is_new = !$source_id;
if ($is_new) {
$source = NuanceSource::initializeNewSource($viewer);
$type = $request->getURIData('type');
$cancel_uri = $this->getApplicationURI('source/');
$map = NuanceSourceDefinition::getAllDefinitions();
if (empty($map[$type])) {
return new Aphront404Response();
$source_type = $request->getStr('sourceType');
if (!isset($map[$source_type])) {
return $this->buildSourceTypeResponse($cancel_uri);
}
$source->setType($type);
$cancel_uri = $sources_uri;
} else {
$source = id(new NuanceSourceQuery())
->setViewer($viewer)
->withIDs(array($source_id))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$source) {
return new Aphront404Response();
}
$cancel_uri = $source->getURI();
$engine
->setSourceDefinition($map[$source_type])
->addContextParameter('sourceType', $source_type);
}
$definition = $source->requireDefinition();
$definition->setActor($viewer);
return $engine->buildResponse();
}
$response = $definition->buildEditLayout($request);
if ($response instanceof AphrontResponse) {
return $response;
private function buildSourceTypeResponse($cancel_uri) {
$viewer = $this->getViewer();
$request = $this->getRequest();
$map = NuanceSourceDefinition::getAllDefinitions();
$errors = array();
$e_source = null;
if ($request->isFormPost()) {
$errors[] = pht('You must choose a source type.');
$e_source = pht('Required');
}
$layout = $response;
$source_types = id(new AphrontFormRadioButtonControl())
->setName('sourceType')
->setLabel(pht('Source Type'));
foreach ($map as $type => $definition) {
$source_types->addButton(
$type,
$definition->getName(),
$definition->getSourceDescription());
}
$form = id(new AphrontFormView())
->setUser($viewer)
->appendChild($source_types)
->appendChild(
id(new AphrontFormSubmitControl())
->setValue(pht('Continue'))
->addCancelButton($cancel_uri));
$box = id(new PHUIObjectBoxView())
->setFormErrors($errors)
->setHeaderText(pht('Choose Source Type'))
->appendChild($form);
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Sources'), $sources_uri);
$crumbs->addTextCrumb(pht('Sources'), $cancel_uri);
$crumbs->addTextCrumb(pht('New'));
if ($is_new) {
$crumbs->addTextCrumb(pht('New'));
} else {
$crumbs->addTextCrumb($source->getName(), $cancel_uri);
$crumbs->addTextCrumb(pht('Edit'));
}
return $this->buildApplicationPage(
array(
$crumbs,
$layout,
),
array(
'title' => $definition->getEditTitle(),
));
return $this->newPage()
->setTitle(pht('Choose Source Type'))
->setCrumbs($crumbs)
->appendChild($box);
}
}

View file

@ -1,46 +1,20 @@
<?php
final class NuanceSourceListController
extends NuanceController {
extends NuanceSourceController {
public function handleRequest(AphrontRequest $request) {
$request = $this->getRequest();
$controller = id(new PhabricatorApplicationSearchController($request))
->setQueryKey($request->getURIData('queryKey'))
->setSearchEngine(new NuanceSourceSearchEngine())
->setNavigation($this->buildSideNavView());
return $this->delegateToController($controller);
}
public function buildSideNavView($for_app = false) {
$user = $this->getRequest()->getUser();
$nav = new AphrontSideNavFilterView();
$nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
id(new NuanceSourceSearchEngine())
->setViewer($user)
->addNavigationItems($nav->getMenu());
$nav->selectFilter(null);
return $nav;
return id(new NuanceSourceSearchEngine())
->setController($this)
->buildResponse();
}
protected function buildApplicationCrumbs() {
$crumbs = parent::buildApplicationCrumbs();
$can_create = $this->hasApplicationCapability(
NuanceSourceManageCapability::CAPABILITY);
$crumbs->addAction(
id(new PHUIListItemView())
->setName(pht('Create Source'))
->setHref($this->getApplicationURI('source/create/'))
->setIcon('fa-plus-square')
->setDisabled(!$can_create)
->setWorkflow(!$can_create));
id(new NuanceSourceEditEngine())
->setViewer($this->getViewer())
->addActionToCrumbs($crumbs);
return $crumbs;
}

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