mirror of
https://we.phorge.it/source/phorge.git
synced 2025-01-10 14:51:06 +01:00
(stable) Promote 2018 Week 37
This commit is contained in:
commit
f65b846ecf
72 changed files with 1513 additions and 459 deletions
|
@ -9,7 +9,7 @@ return array(
|
||||||
'names' => array(
|
'names' => array(
|
||||||
'conpherence.pkg.css' => 'e68cf1fa',
|
'conpherence.pkg.css' => 'e68cf1fa',
|
||||||
'conpherence.pkg.js' => '15191c65',
|
'conpherence.pkg.js' => '15191c65',
|
||||||
'core.pkg.css' => 'badf3f16',
|
'core.pkg.css' => '2574c199',
|
||||||
'core.pkg.js' => 'b5a949ca',
|
'core.pkg.js' => 'b5a949ca',
|
||||||
'differential.pkg.css' => '06dc617c',
|
'differential.pkg.css' => '06dc617c',
|
||||||
'differential.pkg.js' => 'c1cfa143',
|
'differential.pkg.js' => 'c1cfa143',
|
||||||
|
@ -122,7 +122,7 @@ return array(
|
||||||
'rsrc/css/layout/phabricator-source-code-view.css' => '2ab25dfa',
|
'rsrc/css/layout/phabricator-source-code-view.css' => '2ab25dfa',
|
||||||
'rsrc/css/phui/button/phui-button-bar.css' => 'f1ff5494',
|
'rsrc/css/phui/button/phui-button-bar.css' => 'f1ff5494',
|
||||||
'rsrc/css/phui/button/phui-button-simple.css' => '8e1baf68',
|
'rsrc/css/phui/button/phui-button-simple.css' => '8e1baf68',
|
||||||
'rsrc/css/phui/button/phui-button.css' => '1863cc6e',
|
'rsrc/css/phui/button/phui-button.css' => '6ccb303c',
|
||||||
'rsrc/css/phui/calendar/phui-calendar-day.css' => '572b1893',
|
'rsrc/css/phui/calendar/phui-calendar-day.css' => '572b1893',
|
||||||
'rsrc/css/phui/calendar/phui-calendar-list.css' => '576be600',
|
'rsrc/css/phui/calendar/phui-calendar-list.css' => '576be600',
|
||||||
'rsrc/css/phui/calendar/phui-calendar-month.css' => '21154caf',
|
'rsrc/css/phui/calendar/phui-calendar-month.css' => '21154caf',
|
||||||
|
@ -146,12 +146,12 @@ return array(
|
||||||
'rsrc/css/phui/phui-comment-panel.css' => 'f50152ad',
|
'rsrc/css/phui/phui-comment-panel.css' => 'f50152ad',
|
||||||
'rsrc/css/phui/phui-crumbs-view.css' => '10728aaa',
|
'rsrc/css/phui/phui-crumbs-view.css' => '10728aaa',
|
||||||
'rsrc/css/phui/phui-curtain-view.css' => '2bdaf026',
|
'rsrc/css/phui/phui-curtain-view.css' => '2bdaf026',
|
||||||
'rsrc/css/phui/phui-document-pro.css' => '1a08ef4b',
|
'rsrc/css/phui/phui-document-pro.css' => 'd033e8d5',
|
||||||
'rsrc/css/phui/phui-document-summary.css' => '9ca48bdf',
|
'rsrc/css/phui/phui-document-summary.css' => '9ca48bdf',
|
||||||
'rsrc/css/phui/phui-document.css' => 'c4ac41f9',
|
'rsrc/css/phui/phui-document.css' => 'c4ac41f9',
|
||||||
'rsrc/css/phui/phui-feed-story.css' => '44a9c8e9',
|
'rsrc/css/phui/phui-feed-story.css' => '44a9c8e9',
|
||||||
'rsrc/css/phui/phui-fontkit.css' => '1320ed01',
|
'rsrc/css/phui/phui-fontkit.css' => '1320ed01',
|
||||||
'rsrc/css/phui/phui-form-view.css' => 'f808e5be',
|
'rsrc/css/phui/phui-form-view.css' => '2f43fae7',
|
||||||
'rsrc/css/phui/phui-form.css' => '7aaa04e3',
|
'rsrc/css/phui/phui-form.css' => '7aaa04e3',
|
||||||
'rsrc/css/phui/phui-head-thing.css' => 'fd311e5f',
|
'rsrc/css/phui/phui-head-thing.css' => 'fd311e5f',
|
||||||
'rsrc/css/phui/phui-header-view.css' => '1ba8b707',
|
'rsrc/css/phui/phui-header-view.css' => '1ba8b707',
|
||||||
|
@ -423,7 +423,7 @@ return array(
|
||||||
'rsrc/js/application/search/behavior-reorder-profile-menu-items.js' => 'e2e0a072',
|
'rsrc/js/application/search/behavior-reorder-profile-menu-items.js' => 'e2e0a072',
|
||||||
'rsrc/js/application/search/behavior-reorder-queries.js' => 'e9581f08',
|
'rsrc/js/application/search/behavior-reorder-queries.js' => 'e9581f08',
|
||||||
'rsrc/js/application/slowvote/behavior-slowvote-embed.js' => '887ad43f',
|
'rsrc/js/application/slowvote/behavior-slowvote-embed.js' => '887ad43f',
|
||||||
'rsrc/js/application/transactions/behavior-comment-actions.js' => '54110499',
|
'rsrc/js/application/transactions/behavior-comment-actions.js' => '038bf27f',
|
||||||
'rsrc/js/application/transactions/behavior-reorder-configs.js' => 'd7a74243',
|
'rsrc/js/application/transactions/behavior-reorder-configs.js' => 'd7a74243',
|
||||||
'rsrc/js/application/transactions/behavior-reorder-fields.js' => 'b59e1e96',
|
'rsrc/js/application/transactions/behavior-reorder-fields.js' => 'b59e1e96',
|
||||||
'rsrc/js/application/transactions/behavior-show-older-transactions.js' => '8f29b364',
|
'rsrc/js/application/transactions/behavior-show-older-transactions.js' => '8f29b364',
|
||||||
|
@ -575,7 +575,7 @@ return array(
|
||||||
'javelin-behavior-bulk-job-reload' => 'edf8a145',
|
'javelin-behavior-bulk-job-reload' => 'edf8a145',
|
||||||
'javelin-behavior-calendar-month-view' => 'fe33e256',
|
'javelin-behavior-calendar-month-view' => 'fe33e256',
|
||||||
'javelin-behavior-choose-control' => '327a00d1',
|
'javelin-behavior-choose-control' => '327a00d1',
|
||||||
'javelin-behavior-comment-actions' => '54110499',
|
'javelin-behavior-comment-actions' => '038bf27f',
|
||||||
'javelin-behavior-config-reorder-fields' => 'b6993408',
|
'javelin-behavior-config-reorder-fields' => 'b6993408',
|
||||||
'javelin-behavior-conpherence-menu' => '4047cd35',
|
'javelin-behavior-conpherence-menu' => '4047cd35',
|
||||||
'javelin-behavior-conpherence-participant-pane' => 'd057e45a',
|
'javelin-behavior-conpherence-participant-pane' => 'd057e45a',
|
||||||
|
@ -800,7 +800,7 @@ return array(
|
||||||
'phui-box-css' => '4bd6cdb9',
|
'phui-box-css' => '4bd6cdb9',
|
||||||
'phui-bulk-editor-css' => '9a81e5d5',
|
'phui-bulk-editor-css' => '9a81e5d5',
|
||||||
'phui-button-bar-css' => 'f1ff5494',
|
'phui-button-bar-css' => 'f1ff5494',
|
||||||
'phui-button-css' => '1863cc6e',
|
'phui-button-css' => '6ccb303c',
|
||||||
'phui-button-simple-css' => '8e1baf68',
|
'phui-button-simple-css' => '8e1baf68',
|
||||||
'phui-calendar-css' => 'f1ddf11c',
|
'phui-calendar-css' => 'f1ddf11c',
|
||||||
'phui-calendar-day-css' => '572b1893',
|
'phui-calendar-day-css' => '572b1893',
|
||||||
|
@ -814,12 +814,12 @@ return array(
|
||||||
'phui-curtain-view-css' => '2bdaf026',
|
'phui-curtain-view-css' => '2bdaf026',
|
||||||
'phui-document-summary-view-css' => '9ca48bdf',
|
'phui-document-summary-view-css' => '9ca48bdf',
|
||||||
'phui-document-view-css' => 'c4ac41f9',
|
'phui-document-view-css' => 'c4ac41f9',
|
||||||
'phui-document-view-pro-css' => '1a08ef4b',
|
'phui-document-view-pro-css' => 'd033e8d5',
|
||||||
'phui-feed-story-css' => '44a9c8e9',
|
'phui-feed-story-css' => '44a9c8e9',
|
||||||
'phui-font-icon-base-css' => '870a7360',
|
'phui-font-icon-base-css' => '870a7360',
|
||||||
'phui-fontkit-css' => '1320ed01',
|
'phui-fontkit-css' => '1320ed01',
|
||||||
'phui-form-css' => '7aaa04e3',
|
'phui-form-css' => '7aaa04e3',
|
||||||
'phui-form-view-css' => 'f808e5be',
|
'phui-form-view-css' => '2f43fae7',
|
||||||
'phui-head-thing-view-css' => 'fd311e5f',
|
'phui-head-thing-view-css' => 'fd311e5f',
|
||||||
'phui-header-view-css' => '1ba8b707',
|
'phui-header-view-css' => '1ba8b707',
|
||||||
'phui-hovercard' => '1bd28176',
|
'phui-hovercard' => '1bd28176',
|
||||||
|
@ -905,6 +905,15 @@ return array(
|
||||||
'javelin-behavior',
|
'javelin-behavior',
|
||||||
'javelin-uri',
|
'javelin-uri',
|
||||||
),
|
),
|
||||||
|
'038bf27f' => array(
|
||||||
|
'javelin-behavior',
|
||||||
|
'javelin-stratcom',
|
||||||
|
'javelin-workflow',
|
||||||
|
'javelin-dom',
|
||||||
|
'phuix-form-control-view',
|
||||||
|
'phuix-icon-view',
|
||||||
|
'javelin-behavior-phabricator-gesture',
|
||||||
|
),
|
||||||
'040fce04' => array(
|
'040fce04' => array(
|
||||||
'javelin-behavior',
|
'javelin-behavior',
|
||||||
'javelin-request',
|
'javelin-request',
|
||||||
|
@ -1251,15 +1260,6 @@ return array(
|
||||||
'javelin-vector',
|
'javelin-vector',
|
||||||
'javelin-typeahead-static-source',
|
'javelin-typeahead-static-source',
|
||||||
),
|
),
|
||||||
54110499 => array(
|
|
||||||
'javelin-behavior',
|
|
||||||
'javelin-stratcom',
|
|
||||||
'javelin-workflow',
|
|
||||||
'javelin-dom',
|
|
||||||
'phuix-form-control-view',
|
|
||||||
'phuix-icon-view',
|
|
||||||
'javelin-behavior-phabricator-gesture',
|
|
||||||
),
|
|
||||||
'549459b8' => array(
|
'549459b8' => array(
|
||||||
'javelin-behavior',
|
'javelin-behavior',
|
||||||
),
|
),
|
||||||
|
|
54
resources/sql/autopatches/20180910.audit.01.searches.php
Normal file
54
resources/sql/autopatches/20180910.audit.01.searches.php
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$table = new PhabricatorSavedQuery();
|
||||||
|
$conn = $table->establishConnection('w');
|
||||||
|
|
||||||
|
$status_map = array(
|
||||||
|
0 => 'none',
|
||||||
|
1 => 'needs-audit',
|
||||||
|
2 => 'concern-raised',
|
||||||
|
3 => 'partially-audited',
|
||||||
|
4 => 'audited',
|
||||||
|
5 => 'needs-verification',
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach (new LiskMigrationIterator($table) as $query) {
|
||||||
|
if ($query->getEngineClassName() !== 'PhabricatorCommitSearchEngine') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$parameters = $query->getParameters();
|
||||||
|
$status = idx($parameters, 'statuses');
|
||||||
|
|
||||||
|
if (!$status) {
|
||||||
|
// No saved "status" constraint.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($status)) {
|
||||||
|
// Saved constraint isn't a list.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Migrate old integer values to new string values.
|
||||||
|
$old_status = $status;
|
||||||
|
foreach ($status as $key => $value) {
|
||||||
|
if (is_numeric($value)) {
|
||||||
|
$status[$key] = $status_map[$value];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($status === $old_status) {
|
||||||
|
// Nothing changed.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$parameters['statuses'] = $status;
|
||||||
|
|
||||||
|
queryfx(
|
||||||
|
$conn,
|
||||||
|
'UPDATE %T SET parameters = %s WHERE id = %d',
|
||||||
|
$table->getTableName(),
|
||||||
|
phutil_json_encode($parameters),
|
||||||
|
$query->getID());
|
||||||
|
}
|
2
resources/sql/autopatches/20180910.audit.02.string.sql
Normal file
2
resources/sql/autopatches/20180910.audit.02.string.sql
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE {$NAMESPACE}_repository.repository_commit
|
||||||
|
CHANGE auditStatus auditStatus VARCHAR(32) NOT NULL COLLATE {$COLLATE_TEXT};
|
28
resources/sql/autopatches/20180910.audit.03.status.php
Normal file
28
resources/sql/autopatches/20180910.audit.03.status.php
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$table = new PhabricatorRepositoryCommit();
|
||||||
|
$conn = $table->establishConnection('w');
|
||||||
|
|
||||||
|
$status_map = array(
|
||||||
|
0 => 'none',
|
||||||
|
1 => 'needs-audit',
|
||||||
|
2 => 'concern-raised',
|
||||||
|
3 => 'partially-audited',
|
||||||
|
4 => 'audited',
|
||||||
|
5 => 'needs-verification',
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach (new LiskMigrationIterator($table) as $commit) {
|
||||||
|
$status = $commit->getAuditStatus();
|
||||||
|
|
||||||
|
if (!isset($status_map[$status])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
queryfx(
|
||||||
|
$conn,
|
||||||
|
'UPDATE %T SET auditStatus = %s WHERE id = %d',
|
||||||
|
$table->getTableName(),
|
||||||
|
$status_map[$status],
|
||||||
|
$commit->getID());
|
||||||
|
}
|
48
resources/sql/autopatches/20180910.audit.04.xactions.php
Normal file
48
resources/sql/autopatches/20180910.audit.04.xactions.php
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$table = new PhabricatorAuditTransaction();
|
||||||
|
$conn = $table->establishConnection('w');
|
||||||
|
|
||||||
|
$status_map = array(
|
||||||
|
0 => 'none',
|
||||||
|
1 => 'needs-audit',
|
||||||
|
2 => 'concern-raised',
|
||||||
|
3 => 'partially-audited',
|
||||||
|
4 => 'audited',
|
||||||
|
5 => 'needs-verification',
|
||||||
|
);
|
||||||
|
|
||||||
|
$state_type = DiffusionCommitStateTransaction::TRANSACTIONTYPE;
|
||||||
|
|
||||||
|
foreach (new LiskMigrationIterator($table) as $xaction) {
|
||||||
|
if ($xaction->getTransactionType() !== $state_type) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$old_value = $xaction->getOldValue();
|
||||||
|
$new_value = $xaction->getNewValue();
|
||||||
|
|
||||||
|
$any_change = false;
|
||||||
|
|
||||||
|
if (isset($status_map[$old_value])) {
|
||||||
|
$old_value = $status_map[$old_value];
|
||||||
|
$any_change = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($status_map[$new_value])) {
|
||||||
|
$new_value = $status_map[$new_value];
|
||||||
|
$any_change = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$any_change) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
queryfx(
|
||||||
|
$conn,
|
||||||
|
'UPDATE %T SET oldValue = %s, newValue = %s WHERE id = %d',
|
||||||
|
$table->getTableName(),
|
||||||
|
phutil_json_encode($old_value),
|
||||||
|
phutil_json_encode($new_value),
|
||||||
|
$xaction->getID());
|
||||||
|
}
|
26
resources/sql/autopatches/20180914.audit.01.mailkey.php
Normal file
26
resources/sql/autopatches/20180914.audit.01.mailkey.php
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$commit_table = new PhabricatorRepositoryCommit();
|
||||||
|
$commit_conn = $commit_table->establishConnection('w');
|
||||||
|
$commit_name = $commit_table->getTableName();
|
||||||
|
|
||||||
|
$properties_table = new PhabricatorMetaMTAMailProperties();
|
||||||
|
$conn = $properties_table->establishConnection('w');
|
||||||
|
|
||||||
|
$iterator = new LiskRawMigrationIterator($commit_conn, $commit_name);
|
||||||
|
foreach ($iterator as $commit) {
|
||||||
|
queryfx(
|
||||||
|
$conn,
|
||||||
|
'INSERT IGNORE INTO %T
|
||||||
|
(objectPHID, mailProperties, dateCreated, dateModified)
|
||||||
|
VALUES
|
||||||
|
(%s, %s, %d, %d)',
|
||||||
|
$properties_table->getTableName(),
|
||||||
|
$commit['phid'],
|
||||||
|
phutil_json_encode(
|
||||||
|
array(
|
||||||
|
'mailKey' => $commit['mailKey'],
|
||||||
|
)),
|
||||||
|
PhabricatorTime::getNow(),
|
||||||
|
PhabricatorTime::getNow());
|
||||||
|
}
|
2
resources/sql/autopatches/20180914.audit.02.rmkey.sql
Normal file
2
resources/sql/autopatches/20180914.audit.02.rmkey.sql
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE {$NAMESPACE}_repository.repository_commit
|
||||||
|
DROP mailKey;
|
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE {$NAMESPACE}_drydock.drydock_log
|
||||||
|
ADD operationPHID VARBINARY(64);
|
|
@ -704,6 +704,7 @@ phutil_register_library_map(array(
|
||||||
'DiffusionCommitAcceptTransaction' => 'applications/diffusion/xaction/DiffusionCommitAcceptTransaction.php',
|
'DiffusionCommitAcceptTransaction' => 'applications/diffusion/xaction/DiffusionCommitAcceptTransaction.php',
|
||||||
'DiffusionCommitActionTransaction' => 'applications/diffusion/xaction/DiffusionCommitActionTransaction.php',
|
'DiffusionCommitActionTransaction' => 'applications/diffusion/xaction/DiffusionCommitActionTransaction.php',
|
||||||
'DiffusionCommitAffectedFilesHeraldField' => 'applications/diffusion/herald/DiffusionCommitAffectedFilesHeraldField.php',
|
'DiffusionCommitAffectedFilesHeraldField' => 'applications/diffusion/herald/DiffusionCommitAffectedFilesHeraldField.php',
|
||||||
|
'DiffusionCommitAuditStatus' => 'applications/diffusion/DiffusionCommitAuditStatus.php',
|
||||||
'DiffusionCommitAuditTransaction' => 'applications/diffusion/xaction/DiffusionCommitAuditTransaction.php',
|
'DiffusionCommitAuditTransaction' => 'applications/diffusion/xaction/DiffusionCommitAuditTransaction.php',
|
||||||
'DiffusionCommitAuditorsHeraldField' => 'applications/diffusion/herald/DiffusionCommitAuditorsHeraldField.php',
|
'DiffusionCommitAuditorsHeraldField' => 'applications/diffusion/herald/DiffusionCommitAuditorsHeraldField.php',
|
||||||
'DiffusionCommitAuditorsTransaction' => 'applications/diffusion/xaction/DiffusionCommitAuditorsTransaction.php',
|
'DiffusionCommitAuditorsTransaction' => 'applications/diffusion/xaction/DiffusionCommitAuditorsTransaction.php',
|
||||||
|
@ -1167,6 +1168,7 @@ phutil_register_library_map(array(
|
||||||
'DrydockManagementUpdateResourceWorkflow' => 'applications/drydock/management/DrydockManagementUpdateResourceWorkflow.php',
|
'DrydockManagementUpdateResourceWorkflow' => 'applications/drydock/management/DrydockManagementUpdateResourceWorkflow.php',
|
||||||
'DrydockManagementWorkflow' => 'applications/drydock/management/DrydockManagementWorkflow.php',
|
'DrydockManagementWorkflow' => 'applications/drydock/management/DrydockManagementWorkflow.php',
|
||||||
'DrydockObjectAuthorizationView' => 'applications/drydock/view/DrydockObjectAuthorizationView.php',
|
'DrydockObjectAuthorizationView' => 'applications/drydock/view/DrydockObjectAuthorizationView.php',
|
||||||
|
'DrydockOperationWorkLogType' => 'applications/drydock/logtype/DrydockOperationWorkLogType.php',
|
||||||
'DrydockQuery' => 'applications/drydock/query/DrydockQuery.php',
|
'DrydockQuery' => 'applications/drydock/query/DrydockQuery.php',
|
||||||
'DrydockRepositoryOperation' => 'applications/drydock/storage/DrydockRepositoryOperation.php',
|
'DrydockRepositoryOperation' => 'applications/drydock/storage/DrydockRepositoryOperation.php',
|
||||||
'DrydockRepositoryOperationController' => 'applications/drydock/controller/DrydockRepositoryOperationController.php',
|
'DrydockRepositoryOperationController' => 'applications/drydock/controller/DrydockRepositoryOperationController.php',
|
||||||
|
@ -1204,6 +1206,7 @@ phutil_register_library_map(array(
|
||||||
'DrydockSlotLockException' => 'applications/drydock/exception/DrydockSlotLockException.php',
|
'DrydockSlotLockException' => 'applications/drydock/exception/DrydockSlotLockException.php',
|
||||||
'DrydockSlotLockFailureLogType' => 'applications/drydock/logtype/DrydockSlotLockFailureLogType.php',
|
'DrydockSlotLockFailureLogType' => 'applications/drydock/logtype/DrydockSlotLockFailureLogType.php',
|
||||||
'DrydockTestRepositoryOperation' => 'applications/drydock/operation/DrydockTestRepositoryOperation.php',
|
'DrydockTestRepositoryOperation' => 'applications/drydock/operation/DrydockTestRepositoryOperation.php',
|
||||||
|
'DrydockTextLogType' => 'applications/drydock/logtype/DrydockTextLogType.php',
|
||||||
'DrydockWebrootInterface' => 'applications/drydock/interface/webroot/DrydockWebrootInterface.php',
|
'DrydockWebrootInterface' => 'applications/drydock/interface/webroot/DrydockWebrootInterface.php',
|
||||||
'DrydockWorker' => 'applications/drydock/worker/DrydockWorker.php',
|
'DrydockWorker' => 'applications/drydock/worker/DrydockWorker.php',
|
||||||
'DrydockWorkingCopyBlueprintImplementation' => 'applications/drydock/blueprint/DrydockWorkingCopyBlueprintImplementation.php',
|
'DrydockWorkingCopyBlueprintImplementation' => 'applications/drydock/blueprint/DrydockWorkingCopyBlueprintImplementation.php',
|
||||||
|
@ -2147,7 +2150,6 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorAuditActionConstants' => 'applications/audit/constants/PhabricatorAuditActionConstants.php',
|
'PhabricatorAuditActionConstants' => 'applications/audit/constants/PhabricatorAuditActionConstants.php',
|
||||||
'PhabricatorAuditApplication' => 'applications/audit/application/PhabricatorAuditApplication.php',
|
'PhabricatorAuditApplication' => 'applications/audit/application/PhabricatorAuditApplication.php',
|
||||||
'PhabricatorAuditCommentEditor' => 'applications/audit/editor/PhabricatorAuditCommentEditor.php',
|
'PhabricatorAuditCommentEditor' => 'applications/audit/editor/PhabricatorAuditCommentEditor.php',
|
||||||
'PhabricatorAuditCommitStatusConstants' => 'applications/audit/constants/PhabricatorAuditCommitStatusConstants.php',
|
|
||||||
'PhabricatorAuditController' => 'applications/audit/controller/PhabricatorAuditController.php',
|
'PhabricatorAuditController' => 'applications/audit/controller/PhabricatorAuditController.php',
|
||||||
'PhabricatorAuditEditor' => 'applications/audit/editor/PhabricatorAuditEditor.php',
|
'PhabricatorAuditEditor' => 'applications/audit/editor/PhabricatorAuditEditor.php',
|
||||||
'PhabricatorAuditInlineComment' => 'applications/audit/storage/PhabricatorAuditInlineComment.php',
|
'PhabricatorAuditInlineComment' => 'applications/audit/storage/PhabricatorAuditInlineComment.php',
|
||||||
|
@ -5021,6 +5023,9 @@ phutil_register_library_map(array(
|
||||||
'PhrictionDocumentController' => 'applications/phriction/controller/PhrictionDocumentController.php',
|
'PhrictionDocumentController' => 'applications/phriction/controller/PhrictionDocumentController.php',
|
||||||
'PhrictionDocumentDatasource' => 'applications/phriction/typeahead/PhrictionDocumentDatasource.php',
|
'PhrictionDocumentDatasource' => 'applications/phriction/typeahead/PhrictionDocumentDatasource.php',
|
||||||
'PhrictionDocumentDeleteTransaction' => 'applications/phriction/xaction/PhrictionDocumentDeleteTransaction.php',
|
'PhrictionDocumentDeleteTransaction' => 'applications/phriction/xaction/PhrictionDocumentDeleteTransaction.php',
|
||||||
|
'PhrictionDocumentDraftTransaction' => 'applications/phriction/xaction/PhrictionDocumentDraftTransaction.php',
|
||||||
|
'PhrictionDocumentEditEngine' => 'applications/phriction/editor/PhrictionDocumentEditEngine.php',
|
||||||
|
'PhrictionDocumentEditTransaction' => 'applications/phriction/xaction/PhrictionDocumentEditTransaction.php',
|
||||||
'PhrictionDocumentFerretEngine' => 'applications/phriction/search/PhrictionDocumentFerretEngine.php',
|
'PhrictionDocumentFerretEngine' => 'applications/phriction/search/PhrictionDocumentFerretEngine.php',
|
||||||
'PhrictionDocumentFulltextEngine' => 'applications/phriction/search/PhrictionDocumentFulltextEngine.php',
|
'PhrictionDocumentFulltextEngine' => 'applications/phriction/search/PhrictionDocumentFulltextEngine.php',
|
||||||
'PhrictionDocumentHeraldAdapter' => 'applications/phriction/herald/PhrictionDocumentHeraldAdapter.php',
|
'PhrictionDocumentHeraldAdapter' => 'applications/phriction/herald/PhrictionDocumentHeraldAdapter.php',
|
||||||
|
@ -5042,6 +5047,7 @@ phutil_register_library_map(array(
|
||||||
'PhrictionDocumentVersionTransaction' => 'applications/phriction/xaction/PhrictionDocumentVersionTransaction.php',
|
'PhrictionDocumentVersionTransaction' => 'applications/phriction/xaction/PhrictionDocumentVersionTransaction.php',
|
||||||
'PhrictionEditConduitAPIMethod' => 'applications/phriction/conduit/PhrictionEditConduitAPIMethod.php',
|
'PhrictionEditConduitAPIMethod' => 'applications/phriction/conduit/PhrictionEditConduitAPIMethod.php',
|
||||||
'PhrictionEditController' => 'applications/phriction/controller/PhrictionEditController.php',
|
'PhrictionEditController' => 'applications/phriction/controller/PhrictionEditController.php',
|
||||||
|
'PhrictionEditEngineController' => 'applications/phriction/controller/PhrictionEditEngineController.php',
|
||||||
'PhrictionHistoryConduitAPIMethod' => 'applications/phriction/conduit/PhrictionHistoryConduitAPIMethod.php',
|
'PhrictionHistoryConduitAPIMethod' => 'applications/phriction/conduit/PhrictionHistoryConduitAPIMethod.php',
|
||||||
'PhrictionHistoryController' => 'applications/phriction/controller/PhrictionHistoryController.php',
|
'PhrictionHistoryController' => 'applications/phriction/controller/PhrictionHistoryController.php',
|
||||||
'PhrictionInfoConduitAPIMethod' => 'applications/phriction/conduit/PhrictionInfoConduitAPIMethod.php',
|
'PhrictionInfoConduitAPIMethod' => 'applications/phriction/conduit/PhrictionInfoConduitAPIMethod.php',
|
||||||
|
@ -6066,6 +6072,7 @@ phutil_register_library_map(array(
|
||||||
'DiffusionCommitAcceptTransaction' => 'DiffusionCommitAuditTransaction',
|
'DiffusionCommitAcceptTransaction' => 'DiffusionCommitAuditTransaction',
|
||||||
'DiffusionCommitActionTransaction' => 'DiffusionCommitTransactionType',
|
'DiffusionCommitActionTransaction' => 'DiffusionCommitTransactionType',
|
||||||
'DiffusionCommitAffectedFilesHeraldField' => 'DiffusionCommitHeraldField',
|
'DiffusionCommitAffectedFilesHeraldField' => 'DiffusionCommitHeraldField',
|
||||||
|
'DiffusionCommitAuditStatus' => 'Phobject',
|
||||||
'DiffusionCommitAuditTransaction' => 'DiffusionCommitActionTransaction',
|
'DiffusionCommitAuditTransaction' => 'DiffusionCommitActionTransaction',
|
||||||
'DiffusionCommitAuditorsHeraldField' => 'DiffusionCommitHeraldField',
|
'DiffusionCommitAuditorsHeraldField' => 'DiffusionCommitHeraldField',
|
||||||
'DiffusionCommitAuditorsTransaction' => 'DiffusionCommitTransactionType',
|
'DiffusionCommitAuditorsTransaction' => 'DiffusionCommitTransactionType',
|
||||||
|
@ -6570,6 +6577,7 @@ phutil_register_library_map(array(
|
||||||
'DrydockManagementUpdateResourceWorkflow' => 'DrydockManagementWorkflow',
|
'DrydockManagementUpdateResourceWorkflow' => 'DrydockManagementWorkflow',
|
||||||
'DrydockManagementWorkflow' => 'PhabricatorManagementWorkflow',
|
'DrydockManagementWorkflow' => 'PhabricatorManagementWorkflow',
|
||||||
'DrydockObjectAuthorizationView' => 'AphrontView',
|
'DrydockObjectAuthorizationView' => 'AphrontView',
|
||||||
|
'DrydockOperationWorkLogType' => 'DrydockLogType',
|
||||||
'DrydockQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'DrydockQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
'DrydockRepositoryOperation' => array(
|
'DrydockRepositoryOperation' => array(
|
||||||
'DrydockDAO',
|
'DrydockDAO',
|
||||||
|
@ -6613,6 +6621,7 @@ phutil_register_library_map(array(
|
||||||
'DrydockSlotLockException' => 'Exception',
|
'DrydockSlotLockException' => 'Exception',
|
||||||
'DrydockSlotLockFailureLogType' => 'DrydockLogType',
|
'DrydockSlotLockFailureLogType' => 'DrydockLogType',
|
||||||
'DrydockTestRepositoryOperation' => 'DrydockRepositoryOperationType',
|
'DrydockTestRepositoryOperation' => 'DrydockRepositoryOperationType',
|
||||||
|
'DrydockTextLogType' => 'DrydockLogType',
|
||||||
'DrydockWebrootInterface' => 'DrydockInterface',
|
'DrydockWebrootInterface' => 'DrydockInterface',
|
||||||
'DrydockWorker' => 'PhabricatorWorker',
|
'DrydockWorker' => 'PhabricatorWorker',
|
||||||
'DrydockWorkingCopyBlueprintImplementation' => 'DrydockBlueprintImplementation',
|
'DrydockWorkingCopyBlueprintImplementation' => 'DrydockBlueprintImplementation',
|
||||||
|
@ -7715,7 +7724,6 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorAuditActionConstants' => 'Phobject',
|
'PhabricatorAuditActionConstants' => 'Phobject',
|
||||||
'PhabricatorAuditApplication' => 'PhabricatorApplication',
|
'PhabricatorAuditApplication' => 'PhabricatorApplication',
|
||||||
'PhabricatorAuditCommentEditor' => 'PhabricatorEditor',
|
'PhabricatorAuditCommentEditor' => 'PhabricatorEditor',
|
||||||
'PhabricatorAuditCommitStatusConstants' => 'Phobject',
|
|
||||||
'PhabricatorAuditController' => 'PhabricatorController',
|
'PhabricatorAuditController' => 'PhabricatorController',
|
||||||
'PhabricatorAuditEditor' => 'PhabricatorApplicationTransactionEditor',
|
'PhabricatorAuditEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||||
'PhabricatorAuditInlineComment' => array(
|
'PhabricatorAuditInlineComment' => array(
|
||||||
|
@ -11136,10 +11144,13 @@ phutil_register_library_map(array(
|
||||||
),
|
),
|
||||||
'PhrictionDocumentAuthorHeraldField' => 'PhrictionDocumentHeraldField',
|
'PhrictionDocumentAuthorHeraldField' => 'PhrictionDocumentHeraldField',
|
||||||
'PhrictionDocumentContentHeraldField' => 'PhrictionDocumentHeraldField',
|
'PhrictionDocumentContentHeraldField' => 'PhrictionDocumentHeraldField',
|
||||||
'PhrictionDocumentContentTransaction' => 'PhrictionDocumentVersionTransaction',
|
'PhrictionDocumentContentTransaction' => 'PhrictionDocumentEditTransaction',
|
||||||
'PhrictionDocumentController' => 'PhrictionController',
|
'PhrictionDocumentController' => 'PhrictionController',
|
||||||
'PhrictionDocumentDatasource' => 'PhabricatorTypeaheadDatasource',
|
'PhrictionDocumentDatasource' => 'PhabricatorTypeaheadDatasource',
|
||||||
'PhrictionDocumentDeleteTransaction' => 'PhrictionDocumentVersionTransaction',
|
'PhrictionDocumentDeleteTransaction' => 'PhrictionDocumentVersionTransaction',
|
||||||
|
'PhrictionDocumentDraftTransaction' => 'PhrictionDocumentEditTransaction',
|
||||||
|
'PhrictionDocumentEditEngine' => 'PhabricatorEditEngine',
|
||||||
|
'PhrictionDocumentEditTransaction' => 'PhrictionDocumentVersionTransaction',
|
||||||
'PhrictionDocumentFerretEngine' => 'PhabricatorFerretEngine',
|
'PhrictionDocumentFerretEngine' => 'PhabricatorFerretEngine',
|
||||||
'PhrictionDocumentFulltextEngine' => 'PhabricatorFulltextEngine',
|
'PhrictionDocumentFulltextEngine' => 'PhabricatorFulltextEngine',
|
||||||
'PhrictionDocumentHeraldAdapter' => 'HeraldAdapter',
|
'PhrictionDocumentHeraldAdapter' => 'HeraldAdapter',
|
||||||
|
@ -11161,6 +11172,7 @@ phutil_register_library_map(array(
|
||||||
'PhrictionDocumentVersionTransaction' => 'PhrictionDocumentTransactionType',
|
'PhrictionDocumentVersionTransaction' => 'PhrictionDocumentTransactionType',
|
||||||
'PhrictionEditConduitAPIMethod' => 'PhrictionConduitAPIMethod',
|
'PhrictionEditConduitAPIMethod' => 'PhrictionConduitAPIMethod',
|
||||||
'PhrictionEditController' => 'PhrictionController',
|
'PhrictionEditController' => 'PhrictionController',
|
||||||
|
'PhrictionEditEngineController' => 'PhrictionController',
|
||||||
'PhrictionHistoryConduitAPIMethod' => 'PhrictionConduitAPIMethod',
|
'PhrictionHistoryConduitAPIMethod' => 'PhrictionConduitAPIMethod',
|
||||||
'PhrictionHistoryController' => 'PhrictionController',
|
'PhrictionHistoryController' => 'PhrictionController',
|
||||||
'PhrictionInfoConduitAPIMethod' => 'PhrictionConduitAPIMethod',
|
'PhrictionInfoConduitAPIMethod' => 'PhrictionConduitAPIMethod',
|
||||||
|
|
|
@ -68,17 +68,17 @@ final class AuditQueryConduitAPIMethod extends AuditConduitAPIMethod {
|
||||||
|
|
||||||
$status_map = array(
|
$status_map = array(
|
||||||
self::AUDIT_LEGACYSTATUS_OPEN => array(
|
self::AUDIT_LEGACYSTATUS_OPEN => array(
|
||||||
PhabricatorAuditCommitStatusConstants::NEEDS_AUDIT,
|
DiffusionCommitAuditStatus::NEEDS_AUDIT,
|
||||||
PhabricatorAuditCommitStatusConstants::CONCERN_RAISED,
|
DiffusionCommitAuditStatus::CONCERN_RAISED,
|
||||||
),
|
),
|
||||||
self::AUDIT_LEGACYSTATUS_CONCERN => array(
|
self::AUDIT_LEGACYSTATUS_CONCERN => array(
|
||||||
PhabricatorAuditCommitStatusConstants::CONCERN_RAISED,
|
DiffusionCommitAuditStatus::CONCERN_RAISED,
|
||||||
),
|
),
|
||||||
self::AUDIT_LEGACYSTATUS_ACCEPTED => array(
|
self::AUDIT_LEGACYSTATUS_ACCEPTED => array(
|
||||||
PhabricatorAuditCommitStatusConstants::FULLY_AUDITED,
|
DiffusionCommitAuditStatus::AUDITED,
|
||||||
),
|
),
|
||||||
self::AUDIT_LEGACYSTATUS_PARTIAL => array(
|
self::AUDIT_LEGACYSTATUS_PARTIAL => array(
|
||||||
PhabricatorAuditCommitStatusConstants::PARTIALLY_AUDITED,
|
DiffusionCommitAuditStatus::PARTIALLY_AUDITED,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -1,140 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
final class PhabricatorAuditCommitStatusConstants extends Phobject {
|
|
||||||
|
|
||||||
private $key;
|
|
||||||
private $spec = array();
|
|
||||||
|
|
||||||
const NONE = 0;
|
|
||||||
const NEEDS_AUDIT = 1;
|
|
||||||
const CONCERN_RAISED = 2;
|
|
||||||
const PARTIALLY_AUDITED = 3;
|
|
||||||
const FULLY_AUDITED = 4;
|
|
||||||
const NEEDS_VERIFICATION = 5;
|
|
||||||
|
|
||||||
const MODERN_NONE = 'none';
|
|
||||||
const MODERN_NEEDS_AUDIT = 'needs-audit';
|
|
||||||
const MODERN_CONCERN_RAISED = 'concern-raised';
|
|
||||||
const MODERN_PARTIALLY_AUDITED = 'partially-audited';
|
|
||||||
const MODERN_AUDITED = 'audited';
|
|
||||||
const MODERN_NEEDS_VERIFICATION = 'needs-verification';
|
|
||||||
|
|
||||||
public static function newForLegacyStatus($status) {
|
|
||||||
$map = self::getMap();
|
|
||||||
|
|
||||||
foreach ($map as $key => $spec) {
|
|
||||||
if (idx($spec, 'legacy') == $status) {
|
|
||||||
return self::newForStatus($key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return self::newForStatus($status);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function newForStatus($status) {
|
|
||||||
$result = new self();
|
|
||||||
|
|
||||||
$result->key = $status;
|
|
||||||
|
|
||||||
$map = self::getMap();
|
|
||||||
if (isset($map[$status])) {
|
|
||||||
$result->spec = $map[$status];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getKey() {
|
|
||||||
return $this->key;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getIcon() {
|
|
||||||
return idx($this->spec, 'icon');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getColor() {
|
|
||||||
return idx($this->spec, 'color');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getName() {
|
|
||||||
return idx($this->spec, 'name', pht('Unknown ("%s")', $this->key));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getStatusNameMap() {
|
|
||||||
$map = self::getMap();
|
|
||||||
return ipull($map, 'name', 'legacy');
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getStatusName($code) {
|
|
||||||
return idx(self::getStatusNameMap(), $code, pht('Unknown'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getOpenStatusConstants() {
|
|
||||||
$constants = array();
|
|
||||||
foreach (self::getMap() as $map) {
|
|
||||||
if (!$map['closed']) {
|
|
||||||
$constants[] = $map['legacy'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $constants;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getStatusColor($code) {
|
|
||||||
$map = self::getMap();
|
|
||||||
$map = ipull($map, 'color', 'legacy');
|
|
||||||
return idx($map, $code);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getStatusIcon($code) {
|
|
||||||
$map = self::getMap();
|
|
||||||
$map = ipull($map, 'icon', 'legacy');
|
|
||||||
return idx($map, $code);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static function getMap() {
|
|
||||||
return array(
|
|
||||||
self::MODERN_NONE => array(
|
|
||||||
'name' => pht('No Audits'),
|
|
||||||
'legacy' => self::NONE,
|
|
||||||
'icon' => 'fa-check',
|
|
||||||
'color' => 'bluegrey',
|
|
||||||
'closed' => true,
|
|
||||||
),
|
|
||||||
self::MODERN_NEEDS_AUDIT => array(
|
|
||||||
'name' => pht('Audit Required'),
|
|
||||||
'legacy' => self::NEEDS_AUDIT,
|
|
||||||
'icon' => 'fa-exclamation-circle',
|
|
||||||
'color' => 'orange',
|
|
||||||
'closed' => false,
|
|
||||||
),
|
|
||||||
self::MODERN_CONCERN_RAISED => array(
|
|
||||||
'name' => pht('Concern Raised'),
|
|
||||||
'legacy' => self::CONCERN_RAISED,
|
|
||||||
'icon' => 'fa-times-circle',
|
|
||||||
'color' => 'red',
|
|
||||||
'closed' => false,
|
|
||||||
),
|
|
||||||
self::MODERN_PARTIALLY_AUDITED => array(
|
|
||||||
'name' => pht('Partially Audited'),
|
|
||||||
'legacy' => self::PARTIALLY_AUDITED,
|
|
||||||
'icon' => 'fa-check-circle-o',
|
|
||||||
'color' => 'yellow',
|
|
||||||
'closed' => false,
|
|
||||||
),
|
|
||||||
self::MODERN_AUDITED => array(
|
|
||||||
'name' => pht('Audited'),
|
|
||||||
'legacy' => self::FULLY_AUDITED,
|
|
||||||
'icon' => 'fa-check-circle',
|
|
||||||
'color' => 'green',
|
|
||||||
'closed' => true,
|
|
||||||
),
|
|
||||||
self::MODERN_NEEDS_VERIFICATION => array(
|
|
||||||
'name' => pht('Needs Verification'),
|
|
||||||
'legacy' => self::NEEDS_VERIFICATION,
|
|
||||||
'icon' => 'fa-refresh',
|
|
||||||
'color' => 'indigo',
|
|
||||||
'closed' => false,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -206,12 +206,10 @@ final class PhabricatorAuditEditor
|
||||||
$object->writeImportStatusFlag($import_status_flag);
|
$object->writeImportStatusFlag($import_status_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
$partial_status = PhabricatorAuditCommitStatusConstants::PARTIALLY_AUDITED;
|
|
||||||
|
|
||||||
// If the commit has changed state after this edit, add an informational
|
// If the commit has changed state after this edit, add an informational
|
||||||
// transaction about the state change.
|
// transaction about the state change.
|
||||||
if ($old_status != $new_status) {
|
if ($old_status != $new_status) {
|
||||||
if ($new_status == $partial_status) {
|
if ($object->isAuditStatusPartiallyAudited()) {
|
||||||
// This state isn't interesting enough to get a transaction. The
|
// This state isn't interesting enough to get a transaction. The
|
||||||
// best way we could lead the user forward is something like "This
|
// best way we could lead the user forward is something like "This
|
||||||
// commit still requires additional audits." but that's redundant and
|
// commit still requires additional audits." but that's redundant and
|
||||||
|
|
|
@ -15,6 +15,7 @@ final class PhabricatorCommitSearchEngine
|
||||||
return id(new DiffusionCommitQuery())
|
return id(new DiffusionCommitQuery())
|
||||||
->needAuditRequests(true)
|
->needAuditRequests(true)
|
||||||
->needCommitData(true)
|
->needCommitData(true)
|
||||||
|
->needIdentities(true)
|
||||||
->needDrafts(true);
|
->needDrafts(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +93,9 @@ final class PhabricatorCommitSearchEngine
|
||||||
->setLabel(pht('Audit Status'))
|
->setLabel(pht('Audit Status'))
|
||||||
->setKey('statuses')
|
->setKey('statuses')
|
||||||
->setAliases(array('status'))
|
->setAliases(array('status'))
|
||||||
->setOptions(PhabricatorAuditCommitStatusConstants::getStatusNameMap())
|
->setOptions(DiffusionCommitAuditStatus::newOptions())
|
||||||
|
->setDeprecatedOptions(
|
||||||
|
DiffusionCommitAuditStatus::newDeprecatedOptions())
|
||||||
->setDescription(pht('Find commits with given audit statuses.')),
|
->setDescription(pht('Find commits with given audit statuses.')),
|
||||||
id(new PhabricatorSearchDatasourceField())
|
id(new PhabricatorSearchDatasourceField())
|
||||||
->setLabel(pht('Repositories'))
|
->setLabel(pht('Repositories'))
|
||||||
|
@ -160,7 +163,7 @@ final class PhabricatorCommitSearchEngine
|
||||||
case 'active':
|
case 'active':
|
||||||
$bucket_key = DiffusionCommitRequiredActionResultBucket::BUCKETKEY;
|
$bucket_key = DiffusionCommitRequiredActionResultBucket::BUCKETKEY;
|
||||||
|
|
||||||
$open = PhabricatorAuditCommitStatusConstants::getOpenStatusConstants();
|
$open = DiffusionCommitAuditStatus::getOpenStatusConstants();
|
||||||
|
|
||||||
$query
|
$query
|
||||||
->setParameter('responsiblePHIDs', array($viewer_phid))
|
->setParameter('responsiblePHIDs', array($viewer_phid))
|
||||||
|
|
|
@ -490,8 +490,7 @@ final class PhabricatorAuthSessionEngine extends Phobject {
|
||||||
PhabricatorAuthSession $session,
|
PhabricatorAuthSession $session,
|
||||||
$force = false) {
|
$force = false) {
|
||||||
|
|
||||||
$until = $session->getHighSecurityUntil();
|
if ($session->isHighSecuritySession() || $force) {
|
||||||
if ($until > time() || $force) {
|
|
||||||
return new PhabricatorAuthHighSecurityToken();
|
return new PhabricatorAuthHighSecurityToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,22 @@ final class PhabricatorAuthSession extends PhabricatorAuthDAO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isHighSecuritySession() {
|
||||||
|
$until = $this->getHighSecurityUntil();
|
||||||
|
|
||||||
|
if (!$until) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$now = PhabricatorTime::getNow();
|
||||||
|
if ($until < $now) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ final class ConduitConstantDescription extends Phobject {
|
||||||
|
|
||||||
private $key;
|
private $key;
|
||||||
private $value;
|
private $value;
|
||||||
|
private $isDeprecated;
|
||||||
|
|
||||||
public function setKey($key) {
|
public function setKey($key) {
|
||||||
$this->key = $key;
|
$this->key = $key;
|
||||||
|
@ -23,4 +24,13 @@ final class ConduitConstantDescription extends Phobject {
|
||||||
return $this->value;
|
return $this->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setIsDeprecated($is_deprecated) {
|
||||||
|
$this->isDeprecated = $is_deprecated;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getIsDeprecated() {
|
||||||
|
return $this->isDeprecated;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
173
src/applications/diffusion/DiffusionCommitAuditStatus.php
Normal file
173
src/applications/diffusion/DiffusionCommitAuditStatus.php
Normal file
|
@ -0,0 +1,173 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class DiffusionCommitAuditStatus extends Phobject {
|
||||||
|
|
||||||
|
private $key;
|
||||||
|
private $spec = array();
|
||||||
|
|
||||||
|
const NONE = 'none';
|
||||||
|
const NEEDS_AUDIT = 'needs-audit';
|
||||||
|
const CONCERN_RAISED = 'concern-raised';
|
||||||
|
const PARTIALLY_AUDITED = 'partially-audited';
|
||||||
|
const AUDITED = 'audited';
|
||||||
|
const NEEDS_VERIFICATION = 'needs-verification';
|
||||||
|
|
||||||
|
public static function newModernKeys(array $values) {
|
||||||
|
$map = self::getMap();
|
||||||
|
|
||||||
|
$modern = array();
|
||||||
|
foreach ($map as $key => $spec) {
|
||||||
|
if (isset($spec['legacy'])) {
|
||||||
|
$modern[$spec['legacy']] = $key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($values as $key => $value) {
|
||||||
|
$values[$key] = idx($modern, $value, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $values;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function newForStatus($status) {
|
||||||
|
$result = new self();
|
||||||
|
|
||||||
|
$result->key = $status;
|
||||||
|
|
||||||
|
$map = self::getMap();
|
||||||
|
if (isset($map[$status])) {
|
||||||
|
$result->spec = $map[$status];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getKey() {
|
||||||
|
return $this->key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getIcon() {
|
||||||
|
return idx($this->spec, 'icon');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getColor() {
|
||||||
|
return idx($this->spec, 'color');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAnsiColor() {
|
||||||
|
return idx($this->spec, 'color.ansi');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName() {
|
||||||
|
return idx($this->spec, 'name', pht('Unknown ("%s")', $this->key));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isNoAudit() {
|
||||||
|
return ($this->key == self::NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isNeedsAudit() {
|
||||||
|
return ($this->key == self::NEEDS_AUDIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isConcernRaised() {
|
||||||
|
return ($this->key == self::CONCERN_RAISED);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isNeedsVerification() {
|
||||||
|
return ($this->key == self::NEEDS_VERIFICATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isPartiallyAudited() {
|
||||||
|
return ($this->key == self::PARTIALLY_AUDITED);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isAudited() {
|
||||||
|
return ($this->key == self::AUDITED);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getIsClosed() {
|
||||||
|
return idx($this->spec, 'closed');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getOpenStatusConstants() {
|
||||||
|
$constants = array();
|
||||||
|
foreach (self::getMap() as $key => $map) {
|
||||||
|
if (!$map['closed']) {
|
||||||
|
$constants[] = $key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $constants;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function newOptions() {
|
||||||
|
$map = self::getMap();
|
||||||
|
return ipull($map, 'name');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function newDeprecatedOptions() {
|
||||||
|
$map = self::getMap();
|
||||||
|
|
||||||
|
$results = array();
|
||||||
|
foreach ($map as $key => $spec) {
|
||||||
|
if (isset($spec['legacy'])) {
|
||||||
|
$results[$spec['legacy']] = $key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function getMap() {
|
||||||
|
return array(
|
||||||
|
self::NONE => array(
|
||||||
|
'name' => pht('No Audits'),
|
||||||
|
'legacy' => 0,
|
||||||
|
'icon' => 'fa-check',
|
||||||
|
'color' => 'bluegrey',
|
||||||
|
'closed' => true,
|
||||||
|
'color.ansi' => null,
|
||||||
|
),
|
||||||
|
self::NEEDS_AUDIT => array(
|
||||||
|
'name' => pht('Audit Required'),
|
||||||
|
'legacy' => 1,
|
||||||
|
'icon' => 'fa-exclamation-circle',
|
||||||
|
'color' => 'orange',
|
||||||
|
'closed' => false,
|
||||||
|
'color.ansi' => 'magenta',
|
||||||
|
),
|
||||||
|
self::CONCERN_RAISED => array(
|
||||||
|
'name' => pht('Concern Raised'),
|
||||||
|
'legacy' => 2,
|
||||||
|
'icon' => 'fa-times-circle',
|
||||||
|
'color' => 'red',
|
||||||
|
'closed' => false,
|
||||||
|
'color.ansi' => 'red',
|
||||||
|
),
|
||||||
|
self::PARTIALLY_AUDITED => array(
|
||||||
|
'name' => pht('Partially Audited'),
|
||||||
|
'legacy' => 3,
|
||||||
|
'icon' => 'fa-check-circle-o',
|
||||||
|
'color' => 'yellow',
|
||||||
|
'closed' => false,
|
||||||
|
'color.ansi' => 'yellow',
|
||||||
|
),
|
||||||
|
self::AUDITED => array(
|
||||||
|
'name' => pht('Audited'),
|
||||||
|
'legacy' => 4,
|
||||||
|
'icon' => 'fa-check-circle',
|
||||||
|
'color' => 'green',
|
||||||
|
'closed' => true,
|
||||||
|
'color.ansi' => 'green',
|
||||||
|
),
|
||||||
|
self::NEEDS_VERIFICATION => array(
|
||||||
|
'name' => pht('Needs Verification'),
|
||||||
|
'legacy' => 5,
|
||||||
|
'icon' => 'fa-refresh',
|
||||||
|
'color' => 'indigo',
|
||||||
|
'closed' => false,
|
||||||
|
'color.ansi' => 'magenta',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -171,13 +171,12 @@ final class DiffusionCommitController extends DiffusionController {
|
||||||
->setHeaderIcon('fa-code-fork')
|
->setHeaderIcon('fa-code-fork')
|
||||||
->addTag($commit_tag);
|
->addTag($commit_tag);
|
||||||
|
|
||||||
if ($commit->getAuditStatus()) {
|
if (!$commit->isAuditStatusNoAudit()) {
|
||||||
$icon = PhabricatorAuditCommitStatusConstants::getStatusIcon(
|
$status = $commit->getAuditStatusObject();
|
||||||
$commit->getAuditStatus());
|
|
||||||
$color = PhabricatorAuditCommitStatusConstants::getStatusColor(
|
$icon = $status->getIcon();
|
||||||
$commit->getAuditStatus());
|
$color = $status->getColor();
|
||||||
$status = PhabricatorAuditCommitStatusConstants::getStatusName(
|
$status = $status->getName();
|
||||||
$commit->getAuditStatus());
|
|
||||||
|
|
||||||
$header->setStatus($icon, $color, $status);
|
$header->setStatus($icon, $color, $status);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,8 +31,6 @@ final class DiffusionDoorkeeperCommitFeedStoryPublisher
|
||||||
// After ApplicationTransactions, we could annotate feed stories more
|
// After ApplicationTransactions, we could annotate feed stories more
|
||||||
// explicitly.
|
// explicitly.
|
||||||
|
|
||||||
$fully_audited = PhabricatorAuditCommitStatusConstants::FULLY_AUDITED;
|
|
||||||
|
|
||||||
$story = $this->getFeedStory();
|
$story = $this->getFeedStory();
|
||||||
$xaction = $story->getPrimaryTransaction();
|
$xaction = $story->getPrimaryTransaction();
|
||||||
switch ($xaction->getTransactionType()) {
|
switch ($xaction->getTransactionType()) {
|
||||||
|
@ -41,7 +39,7 @@ final class DiffusionDoorkeeperCommitFeedStoryPublisher
|
||||||
case PhabricatorAuditActionConstants::CLOSE:
|
case PhabricatorAuditActionConstants::CLOSE:
|
||||||
return true;
|
return true;
|
||||||
case PhabricatorAuditActionConstants::ACCEPT:
|
case PhabricatorAuditActionConstants::ACCEPT:
|
||||||
if ($object->getAuditStatus() == $fully_audited) {
|
if ($object->isAuditStatusAudited()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -165,14 +163,7 @@ final class DiffusionDoorkeeperCommitFeedStoryPublisher
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isObjectClosed($object) {
|
public function isObjectClosed($object) {
|
||||||
switch ($object->getAuditStatus()) {
|
return $object->getAuditStatusObject()->getIsClosed();
|
||||||
case PhabricatorAuditCommitStatusConstants::NEEDS_AUDIT:
|
|
||||||
case PhabricatorAuditCommitStatusConstants::CONCERN_RAISED:
|
|
||||||
case PhabricatorAuditCommitStatusConstants::PARTIALLY_AUDITED:
|
|
||||||
return false;
|
|
||||||
default:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getResponsibilityTitle($object) {
|
public function getResponsibilityTitle($object) {
|
||||||
|
|
|
@ -41,12 +41,12 @@ final class DiffusionHovercardEngineExtension
|
||||||
$hovercard->addField(pht('Date'),
|
$hovercard->addField(pht('Date'),
|
||||||
phabricator_date($commit->getEpoch(), $viewer));
|
phabricator_date($commit->getEpoch(), $viewer));
|
||||||
|
|
||||||
if ($commit->getAuditStatus() !=
|
if (!$commit->isAuditStatusNoAudit()) {
|
||||||
PhabricatorAuditCommitStatusConstants::NONE) {
|
$status = $commit->getAuditStatusObject();
|
||||||
|
|
||||||
$hovercard->addField(pht('Audit Status'),
|
$hovercard->addField(
|
||||||
PhabricatorAuditCommitStatusConstants::getStatusName(
|
pht('Audit Status'),
|
||||||
$commit->getAuditStatus()));
|
$status->getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -714,10 +714,13 @@ final class DiffusionCommitQuery
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->statuses !== null) {
|
if ($this->statuses !== null) {
|
||||||
|
$statuses = DiffusionCommitAuditStatus::newModernKeys(
|
||||||
|
$this->statuses);
|
||||||
|
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn,
|
$conn,
|
||||||
'commit.auditStatus IN (%Ld)',
|
'commit.auditStatus IN (%Ls)',
|
||||||
$this->statuses);
|
$statuses);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->packagePHIDs !== null) {
|
if ($this->packagePHIDs !== null) {
|
||||||
|
|
|
@ -69,14 +69,12 @@ final class DiffusionCommitRequiredActionResultBucket
|
||||||
$results = array();
|
$results = array();
|
||||||
$objects = $this->objects;
|
$objects = $this->objects;
|
||||||
|
|
||||||
$status_concern = PhabricatorAuditCommitStatusConstants::CONCERN_RAISED;
|
|
||||||
|
|
||||||
foreach ($objects as $key => $object) {
|
foreach ($objects as $key => $object) {
|
||||||
if (empty($phids[$object->getAuthorPHID()])) {
|
if (empty($phids[$object->getAuthorPHID()])) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($object->getAuditStatus() != $status_concern) {
|
if (!$object->isAuditStatusConcernRaised()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +89,6 @@ final class DiffusionCommitRequiredActionResultBucket
|
||||||
$results = array();
|
$results = array();
|
||||||
$objects = $this->objects;
|
$objects = $this->objects;
|
||||||
|
|
||||||
$status_verify = PhabricatorAuditCommitStatusConstants::NEEDS_VERIFICATION;
|
|
||||||
$has_concern = array(
|
$has_concern = array(
|
||||||
PhabricatorAuditStatusConstants::CONCERNED,
|
PhabricatorAuditStatusConstants::CONCERNED,
|
||||||
);
|
);
|
||||||
|
@ -102,7 +99,7 @@ final class DiffusionCommitRequiredActionResultBucket
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($object->getAuditStatus() != $status_verify) {
|
if (!$object->isAuditStatusNeedsVerification()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,10 +144,8 @@ final class DiffusionCommitRequiredActionResultBucket
|
||||||
$results = array();
|
$results = array();
|
||||||
$objects = $this->objects;
|
$objects = $this->objects;
|
||||||
|
|
||||||
$status_concern = PhabricatorAuditCommitStatusConstants::CONCERN_RAISED;
|
|
||||||
|
|
||||||
foreach ($objects as $key => $object) {
|
foreach ($objects as $key => $object) {
|
||||||
if ($object->getAuditStatus() != $status_concern) {
|
if (!$object->isAuditStatusConcernRaised()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,15 +164,13 @@ final class DiffusionCommitRequiredActionResultBucket
|
||||||
$results = array();
|
$results = array();
|
||||||
$objects = $this->objects;
|
$objects = $this->objects;
|
||||||
|
|
||||||
$status_waiting = array(
|
|
||||||
PhabricatorAuditCommitStatusConstants::NEEDS_AUDIT,
|
|
||||||
PhabricatorAuditCommitStatusConstants::NEEDS_VERIFICATION,
|
|
||||||
PhabricatorAuditCommitStatusConstants::PARTIALLY_AUDITED,
|
|
||||||
);
|
|
||||||
$status_waiting = array_fuse($status_waiting);
|
|
||||||
|
|
||||||
foreach ($objects as $key => $object) {
|
foreach ($objects as $key => $object) {
|
||||||
if (empty($status_waiting[$object->getAuditStatus()])) {
|
$any_waiting =
|
||||||
|
$object->isAuditStatusNeedsAudit() ||
|
||||||
|
$object->isAuditStatusNeedsVerification() ||
|
||||||
|
$object->isAuditStatusPartiallyAudited();
|
||||||
|
|
||||||
|
if (!$any_waiting) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,8 +33,7 @@ final class DiffusionCommitConcernTransaction
|
||||||
public function applyInternalEffects($object, $value) {
|
public function applyInternalEffects($object, $value) {
|
||||||
// NOTE: We force the commit directly into "Concern Raised" so that we
|
// NOTE: We force the commit directly into "Concern Raised" so that we
|
||||||
// override a possible "Needs Verification" state.
|
// override a possible "Needs Verification" state.
|
||||||
$object->setAuditStatus(
|
$object->setAuditStatus(DiffusionCommitAuditStatus::CONCERN_RAISED);
|
||||||
PhabricatorAuditCommitStatusConstants::CONCERN_RAISED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyExternalEffects($object, $value) {
|
public function applyExternalEffects($object, $value) {
|
||||||
|
@ -54,10 +53,8 @@ final class DiffusionCommitConcernTransaction
|
||||||
|
|
||||||
// Even if you've already raised a concern, you can raise again as long
|
// Even if you've already raised a concern, you can raise again as long
|
||||||
// as the author requested you verify.
|
// as the author requested you verify.
|
||||||
$state_verify = PhabricatorAuditCommitStatusConstants::NEEDS_VERIFICATION;
|
|
||||||
|
|
||||||
if ($this->isViewerFullyRejected($object, $viewer)) {
|
if ($this->isViewerFullyRejected($object, $viewer)) {
|
||||||
if ($object->getAuditStatus() != $state_verify) {
|
if (!$object->isAuditStatusNeedsVerification()) {
|
||||||
throw new Exception(
|
throw new Exception(
|
||||||
pht(
|
pht(
|
||||||
'You can not raise a concern with this commit because you have '.
|
'You can not raise a concern with this commit because you have '.
|
||||||
|
|
|
@ -11,29 +11,32 @@ final class DiffusionCommitStateTransaction
|
||||||
throw new PhutilMethodNotImplementedException();
|
throw new PhutilMethodNotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getIcon() {
|
private function getAuditStatusObject() {
|
||||||
$new = $this->getNewValue();
|
$new = $this->getNewValue();
|
||||||
return PhabricatorAuditCommitStatusConstants::getStatusIcon($new);
|
return DiffusionCommitAuditStatus::newForStatus($new);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getIcon() {
|
||||||
|
return $this->getAuditStatusObject()->getIcon();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getColor() {
|
public function getColor() {
|
||||||
$new = $this->getNewValue();
|
return $this->getAuditStatusObject()->getColor();
|
||||||
return PhabricatorAuditCommitStatusConstants::getStatusColor($new);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTitle() {
|
public function getTitle() {
|
||||||
$new = $this->getNewValue();
|
$status = $this->getAuditStatusObject();
|
||||||
|
|
||||||
switch ($new) {
|
switch ($status->getKey()) {
|
||||||
case PhabricatorAuditCommitStatusConstants::NONE:
|
case DiffusionCommitAuditStatus::NONE:
|
||||||
return pht('This commit no longer requires audit.');
|
return pht('This commit no longer requires audit.');
|
||||||
case PhabricatorAuditCommitStatusConstants::NEEDS_AUDIT:
|
case DiffusionCommitAuditStatus::NEEDS_AUDIT:
|
||||||
return pht('This commit now requires audit.');
|
return pht('This commit now requires audit.');
|
||||||
case PhabricatorAuditCommitStatusConstants::CONCERN_RAISED:
|
case DiffusionCommitAuditStatus::CONCERN_RAISED:
|
||||||
return pht('This commit now has outstanding concerns.');
|
return pht('This commit now has outstanding concerns.');
|
||||||
case PhabricatorAuditCommitStatusConstants::NEEDS_VERIFICATION:
|
case DiffusionCommitAuditStatus::NEEDS_VERIFICATION:
|
||||||
return pht('This commit now requires verification by auditors.');
|
return pht('This commit now requires verification by auditors.');
|
||||||
case PhabricatorAuditCommitStatusConstants::FULLY_AUDITED:
|
case DiffusionCommitAuditStatus::AUDITED:
|
||||||
return pht('All concerns with this commit have now been addressed.');
|
return pht('All concerns with this commit have now been addressed.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,26 +44,26 @@ final class DiffusionCommitStateTransaction
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTitleForFeed() {
|
public function getTitleForFeed() {
|
||||||
$new = $this->getNewValue();
|
$status = $this->getAuditStatusObject();
|
||||||
|
|
||||||
switch ($new) {
|
switch ($status->getKey()) {
|
||||||
case PhabricatorAuditCommitStatusConstants::NONE:
|
case DiffusionCommitAuditStatus::NONE:
|
||||||
return pht(
|
return pht(
|
||||||
'%s no longer requires audit.',
|
'%s no longer requires audit.',
|
||||||
$this->renderObject());
|
$this->renderObject());
|
||||||
case PhabricatorAuditCommitStatusConstants::NEEDS_AUDIT:
|
case DiffusionCommitAuditStatus::NEEDS_AUDIT:
|
||||||
return pht(
|
return pht(
|
||||||
'%s now requires audit.',
|
'%s now requires audit.',
|
||||||
$this->renderObject());
|
$this->renderObject());
|
||||||
case PhabricatorAuditCommitStatusConstants::CONCERN_RAISED:
|
case DiffusionCommitAuditStatus::CONCERN_RAISED:
|
||||||
return pht(
|
return pht(
|
||||||
'%s now has outstanding concerns.',
|
'%s now has outstanding concerns.',
|
||||||
$this->renderObject());
|
$this->renderObject());
|
||||||
case PhabricatorAuditCommitStatusConstants::NEEDS_VERIFICATION:
|
case DiffusionCommitAuditStatus::NEEDS_VERIFICATION:
|
||||||
return pht(
|
return pht(
|
||||||
'%s now requires verification by auditors.',
|
'%s now requires verification by auditors.',
|
||||||
$this->renderObject());
|
$this->renderObject());
|
||||||
case PhabricatorAuditCommitStatusConstants::FULLY_AUDITED:
|
case DiffusionCommitAuditStatus::AUDITED:
|
||||||
return pht(
|
return pht(
|
||||||
'All concerns with %s have now been addressed.',
|
'All concerns with %s have now been addressed.',
|
||||||
$this->renderObject());
|
$this->renderObject());
|
||||||
|
|
|
@ -36,8 +36,7 @@ final class DiffusionCommitVerifyTransaction
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyInternalEffects($object, $value) {
|
public function applyInternalEffects($object, $value) {
|
||||||
$object->setAuditStatus(
|
$object->setAuditStatus(DiffusionCommitAuditStatus::NEEDS_VERIFICATION);
|
||||||
PhabricatorAuditCommitStatusConstants::NEEDS_VERIFICATION);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function validateAction($object, PhabricatorUser $viewer) {
|
protected function validateAction($object, PhabricatorUser $viewer) {
|
||||||
|
@ -48,8 +47,7 @@ final class DiffusionCommitVerifyTransaction
|
||||||
'are not the author.'));
|
'are not the author.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$status = $object->getAuditStatus();
|
if (!$object->isAuditStatusConcernRaised()) {
|
||||||
if ($status != PhabricatorAuditCommitStatusConstants::CONCERN_RAISED) {
|
|
||||||
throw new Exception(
|
throw new Exception(
|
||||||
pht(
|
pht(
|
||||||
'You can not request verification of this commit because no '.
|
'You can not request verification of this commit because no '.
|
||||||
|
|
|
@ -93,6 +93,8 @@ final class PhabricatorDrydockApplication extends PhabricatorApplication {
|
||||||
'' => 'DrydockRepositoryOperationViewController',
|
'' => 'DrydockRepositoryOperationViewController',
|
||||||
'status/' => 'DrydockRepositoryOperationStatusController',
|
'status/' => 'DrydockRepositoryOperationStatusController',
|
||||||
'dismiss/' => 'DrydockRepositoryOperationDismissController',
|
'dismiss/' => 'DrydockRepositoryOperationDismissController',
|
||||||
|
'logs/(?:query/(?P<queryKey>[^/]+)/)?' =>
|
||||||
|
'DrydockLogListController',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -58,8 +58,11 @@ final class DrydockBlueprintViewController extends DrydockBlueprintController {
|
||||||
$log_query = id(new DrydockLogQuery())
|
$log_query = id(new DrydockLogQuery())
|
||||||
->withBlueprintPHIDs(array($blueprint->getPHID()));
|
->withBlueprintPHIDs(array($blueprint->getPHID()));
|
||||||
|
|
||||||
|
$log_table = $this->buildLogTable($log_query)
|
||||||
|
->setHideBlueprints(true);
|
||||||
|
|
||||||
$logs = $this->buildLogBox(
|
$logs = $this->buildLogBox(
|
||||||
$log_query,
|
$log_table,
|
||||||
$this->getApplicationURI("blueprint/{$id}/logs/query/all/"));
|
$this->getApplicationURI("blueprint/{$id}/logs/query/all/"));
|
||||||
|
|
||||||
$view = id(new PHUITwoColumnView())
|
$view = id(new PHUITwoColumnView())
|
||||||
|
|
|
@ -79,7 +79,7 @@ abstract class DrydockController extends PhabricatorController {
|
||||||
->addRawContent($table);
|
->addRawContent($table);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function buildLogBox(DrydockLogQuery $query, $all_uri) {
|
protected function buildLogTable(DrydockLogQuery $query) {
|
||||||
$viewer = $this->getViewer();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$logs = $query
|
$logs = $query
|
||||||
|
@ -89,9 +89,12 @@ abstract class DrydockController extends PhabricatorController {
|
||||||
|
|
||||||
$log_table = id(new DrydockLogListView())
|
$log_table = id(new DrydockLogListView())
|
||||||
->setUser($viewer)
|
->setUser($viewer)
|
||||||
->setLogs($logs)
|
->setLogs($logs);
|
||||||
->render();
|
|
||||||
|
|
||||||
|
return $log_table;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function buildLogBox(DrydockLogListView $log_table, $all_uri) {
|
||||||
$log_header = id(new PHUIHeaderView())
|
$log_header = id(new PHUIHeaderView())
|
||||||
->setHeader(pht('Logs'))
|
->setHeader(pht('Logs'))
|
||||||
->addActionLink(
|
->addActionLink(
|
||||||
|
|
|
@ -43,8 +43,11 @@ final class DrydockLeaseViewController extends DrydockLeaseController {
|
||||||
$log_query = id(new DrydockLogQuery())
|
$log_query = id(new DrydockLogQuery())
|
||||||
->withLeasePHIDs(array($lease->getPHID()));
|
->withLeasePHIDs(array($lease->getPHID()));
|
||||||
|
|
||||||
|
$log_table = $this->buildLogTable($log_query)
|
||||||
|
->setHideLeases(true);
|
||||||
|
|
||||||
$logs = $this->buildLogBox(
|
$logs = $this->buildLogBox(
|
||||||
$log_query,
|
$log_table,
|
||||||
$this->getApplicationURI("lease/{$id}/logs/query/all/"));
|
$this->getApplicationURI("lease/{$id}/logs/query/all/"));
|
||||||
|
|
||||||
$crumbs = $this->buildApplicationCrumbs();
|
$crumbs = $this->buildApplicationCrumbs();
|
||||||
|
|
|
@ -6,6 +6,7 @@ abstract class DrydockLogController
|
||||||
private $blueprint;
|
private $blueprint;
|
||||||
private $resource;
|
private $resource;
|
||||||
private $lease;
|
private $lease;
|
||||||
|
private $operation;
|
||||||
|
|
||||||
public function setBlueprint(DrydockBlueprint $blueprint) {
|
public function setBlueprint(DrydockBlueprint $blueprint) {
|
||||||
$this->blueprint = $blueprint;
|
$this->blueprint = $blueprint;
|
||||||
|
@ -34,6 +35,15 @@ abstract class DrydockLogController
|
||||||
return $this->lease;
|
return $this->lease;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setOperation(DrydockRepositoryOperation $operation) {
|
||||||
|
$this->operation = $operation;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getOperation() {
|
||||||
|
return $this->operation;
|
||||||
|
}
|
||||||
|
|
||||||
public function buildSideNavView() {
|
public function buildSideNavView() {
|
||||||
$nav = new AphrontSideNavFilterView();
|
$nav = new AphrontSideNavFilterView();
|
||||||
$nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
|
$nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
|
||||||
|
@ -56,6 +66,11 @@ abstract class DrydockLogController
|
||||||
$engine->setLease($lease);
|
$engine->setLease($lease);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$operation = $this->getOperation();
|
||||||
|
if ($operation) {
|
||||||
|
$engine->setOperation($operation);
|
||||||
|
}
|
||||||
|
|
||||||
$engine->addNavigationItems($nav->getMenu());
|
$engine->addNavigationItems($nav->getMenu());
|
||||||
|
|
||||||
$nav->selectFilter(null);
|
$nav->selectFilter(null);
|
||||||
|
@ -66,9 +81,12 @@ abstract class DrydockLogController
|
||||||
protected function buildApplicationCrumbs() {
|
protected function buildApplicationCrumbs() {
|
||||||
$crumbs = parent::buildApplicationCrumbs();
|
$crumbs = parent::buildApplicationCrumbs();
|
||||||
|
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$blueprint = $this->getBlueprint();
|
$blueprint = $this->getBlueprint();
|
||||||
$resource = $this->getResource();
|
$resource = $this->getResource();
|
||||||
$lease = $this->getLease();
|
$lease = $this->getLease();
|
||||||
|
$operation = $this->getOperation();
|
||||||
if ($blueprint) {
|
if ($blueprint) {
|
||||||
$id = $blueprint->getID();
|
$id = $blueprint->getID();
|
||||||
|
|
||||||
|
@ -111,6 +129,20 @@ abstract class DrydockLogController
|
||||||
$crumbs->addTextCrumb(
|
$crumbs->addTextCrumb(
|
||||||
pht('Logs'),
|
pht('Logs'),
|
||||||
$this->getApplicationURI("lease/{$id}/logs/"));
|
$this->getApplicationURI("lease/{$id}/logs/"));
|
||||||
|
} else if ($operation) {
|
||||||
|
$id = $operation->getID();
|
||||||
|
|
||||||
|
$crumbs->addTextCrumb(
|
||||||
|
pht('Operations'),
|
||||||
|
$this->getApplicationURI('operation/'));
|
||||||
|
|
||||||
|
$crumbs->addTextCrumb(
|
||||||
|
pht('Repository Operation %d', $id),
|
||||||
|
$this->getApplicationURI("operation/{$id}/"));
|
||||||
|
|
||||||
|
$crumbs->addTextCrumb(
|
||||||
|
pht('Logs'),
|
||||||
|
$this->getApplicationURI("operation/{$id}/logs/"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $crumbs;
|
return $crumbs;
|
||||||
|
|
|
@ -46,6 +46,17 @@ final class DrydockLogListController extends DrydockLogController {
|
||||||
$engine->setLease($lease);
|
$engine->setLease($lease);
|
||||||
$this->setLease($lease);
|
$this->setLease($lease);
|
||||||
break;
|
break;
|
||||||
|
case 'operation':
|
||||||
|
$operation = id(new DrydockRepositoryOperationQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withIDs(array($id))
|
||||||
|
->executeOne();
|
||||||
|
if (!$operation) {
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
$engine->setOperation($operation);
|
||||||
|
$this->setOperation($operation);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return new Aphront404Response();
|
return new Aphront404Response();
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,13 +47,25 @@ final class DrydockRepositoryOperationViewController
|
||||||
->setUser($viewer)
|
->setUser($viewer)
|
||||||
->setOperation($operation);
|
->setOperation($operation);
|
||||||
|
|
||||||
|
$log_query = id(new DrydockLogQuery())
|
||||||
|
->withOperationPHIDs(array($operation->getPHID()));
|
||||||
|
|
||||||
|
$log_table = $this->buildLogTable($log_query)
|
||||||
|
->setHideOperations(true);
|
||||||
|
|
||||||
|
$logs = $this->buildLogBox(
|
||||||
|
$log_table,
|
||||||
|
$this->getApplicationURI("operation/{$id}/logs/query/all/"));
|
||||||
|
|
||||||
$view = id(new PHUITwoColumnView())
|
$view = id(new PHUITwoColumnView())
|
||||||
->setHeader($header)
|
->setHeader($header)
|
||||||
->setCurtain($curtain)
|
->setCurtain($curtain)
|
||||||
->addPropertySection(pht('Properties'), $properties)
|
->addPropertySection(pht('Properties'), $properties)
|
||||||
->setMainColumn(array(
|
->setMainColumn(
|
||||||
$status_view,
|
array(
|
||||||
));
|
$status_view,
|
||||||
|
$logs,
|
||||||
|
));
|
||||||
|
|
||||||
return $this->newPage()
|
return $this->newPage()
|
||||||
->setTitle($title)
|
->setTitle($title)
|
||||||
|
|
|
@ -48,8 +48,11 @@ final class DrydockResourceViewController extends DrydockResourceController {
|
||||||
$log_query = id(new DrydockLogQuery())
|
$log_query = id(new DrydockLogQuery())
|
||||||
->withResourcePHIDs(array($resource->getPHID()));
|
->withResourcePHIDs(array($resource->getPHID()));
|
||||||
|
|
||||||
$log_box = $this->buildLogBox(
|
$log_table = $this->buildLogTable($log_query)
|
||||||
$log_query,
|
->setHideResources(true);
|
||||||
|
|
||||||
|
$logs = $this->buildLogBox(
|
||||||
|
$log_table,
|
||||||
$this->getApplicationURI("resource/{$id}/logs/query/all/"));
|
$this->getApplicationURI("resource/{$id}/logs/query/all/"));
|
||||||
|
|
||||||
$crumbs = $this->buildApplicationCrumbs();
|
$crumbs = $this->buildApplicationCrumbs();
|
||||||
|
@ -86,11 +89,12 @@ final class DrydockResourceViewController extends DrydockResourceController {
|
||||||
$view = id(new PHUITwoColumnView())
|
$view = id(new PHUITwoColumnView())
|
||||||
->setHeader($header)
|
->setHeader($header)
|
||||||
->setCurtain($curtain)
|
->setCurtain($curtain)
|
||||||
->setMainColumn(array(
|
->setMainColumn(
|
||||||
$object_box,
|
array(
|
||||||
$lease_box,
|
$object_box,
|
||||||
$log_box,
|
$lease_box,
|
||||||
));
|
$logs,
|
||||||
|
));
|
||||||
|
|
||||||
return $this->newPage()
|
return $this->newPage()
|
||||||
->setTitle($title)
|
->setTitle($title)
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class DrydockOperationWorkLogType extends DrydockLogType {
|
||||||
|
|
||||||
|
const LOGCONST = 'core.operation.work';
|
||||||
|
|
||||||
|
public function getLogTypeName() {
|
||||||
|
return pht('Started Work');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLogTypeIcon(array $data) {
|
||||||
|
return 'fa-check green';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function renderLog(array $data) {
|
||||||
|
return pht('Started this operation in a working copy.');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
27
src/applications/drydock/logtype/DrydockTextLogType.php
Normal file
27
src/applications/drydock/logtype/DrydockTextLogType.php
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple convenience log type for logging arbitrary text.
|
||||||
|
*
|
||||||
|
* Drydock logs can be given formal types, which allows them to be translated
|
||||||
|
* and filtered. If you don't particularly care about fancy logging features,
|
||||||
|
* you can use this log type to just dump some text into the log. Maybe you
|
||||||
|
* could upgrade to more formal logging later.
|
||||||
|
*/
|
||||||
|
final class DrydockTextLogType extends DrydockLogType {
|
||||||
|
|
||||||
|
const LOGCONST = 'core.text';
|
||||||
|
|
||||||
|
public function getLogTypeName() {
|
||||||
|
return pht('Text');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLogTypeIcon(array $data) {
|
||||||
|
return 'fa-file-text-o grey';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function renderLog(array $data) {
|
||||||
|
return idx($data, 'text');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -5,7 +5,7 @@ final class DrydockRepositoryOperationPHIDType extends PhabricatorPHIDType {
|
||||||
const TYPECONST = 'DRYO';
|
const TYPECONST = 'DRYO';
|
||||||
|
|
||||||
public function getTypeName() {
|
public function getTypeName() {
|
||||||
return pht('Drydock Repository Operation');
|
return pht('Repository Operation');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function newObject() {
|
public function newObject() {
|
||||||
|
@ -33,7 +33,7 @@ final class DrydockRepositoryOperationPHIDType extends PhabricatorPHIDType {
|
||||||
$operation = $objects[$phid];
|
$operation = $objects[$phid];
|
||||||
$id = $operation->getID();
|
$id = $operation->getID();
|
||||||
|
|
||||||
$handle->setName(pht('Drydock Repository Operation %d', $id));
|
$handle->setName(pht('Repository Operation %d', $id));
|
||||||
$handle->setURI("/drydock/operation/{$id}/");
|
$handle->setURI("/drydock/operation/{$id}/");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ final class DrydockLogQuery extends DrydockQuery {
|
||||||
private $blueprintPHIDs;
|
private $blueprintPHIDs;
|
||||||
private $resourcePHIDs;
|
private $resourcePHIDs;
|
||||||
private $leasePHIDs;
|
private $leasePHIDs;
|
||||||
|
private $operationPHIDs;
|
||||||
|
|
||||||
public function withBlueprintPHIDs(array $phids) {
|
public function withBlueprintPHIDs(array $phids) {
|
||||||
$this->blueprintPHIDs = $phids;
|
$this->blueprintPHIDs = $phids;
|
||||||
|
@ -21,6 +22,11 @@ final class DrydockLogQuery extends DrydockQuery {
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function withOperationPHIDs(array $phids) {
|
||||||
|
$this->operationPHIDs = $phids;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function newResultObject() {
|
public function newResultObject() {
|
||||||
return new DrydockLog();
|
return new DrydockLog();
|
||||||
}
|
}
|
||||||
|
@ -93,6 +99,27 @@ final class DrydockLogQuery extends DrydockQuery {
|
||||||
$log->attachLease($lease);
|
$log->attachLease($lease);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$operation_phids = array_filter(mpull($logs, 'getOperationPHID'));
|
||||||
|
if ($operation_phids) {
|
||||||
|
$operations = id(new DrydockRepositoryOperationQuery())
|
||||||
|
->setParentQuery($this)
|
||||||
|
->setViewer($this->getViewer())
|
||||||
|
->withPHIDs($operation_phids)
|
||||||
|
->execute();
|
||||||
|
$operations = mpull($operations, null, 'getPHID');
|
||||||
|
} else {
|
||||||
|
$operations = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($logs as $key => $log) {
|
||||||
|
$operation = null;
|
||||||
|
$operation_phid = $log->getOperationPHID();
|
||||||
|
if ($operation_phid) {
|
||||||
|
$operation = idx($operations, $operation_phid);
|
||||||
|
}
|
||||||
|
$log->attachOperation($operation);
|
||||||
|
}
|
||||||
|
|
||||||
return $logs;
|
return $logs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,6 +147,13 @@ final class DrydockLogQuery extends DrydockQuery {
|
||||||
$this->leasePHIDs);
|
$this->leasePHIDs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->operationPHIDs !== null) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn,
|
||||||
|
'operationPHID IN (%Ls)',
|
||||||
|
$this->operationPHIDs);
|
||||||
|
}
|
||||||
|
|
||||||
return $where;
|
return $where;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ final class DrydockLogSearchEngine extends PhabricatorApplicationSearchEngine {
|
||||||
private $blueprint;
|
private $blueprint;
|
||||||
private $resource;
|
private $resource;
|
||||||
private $lease;
|
private $lease;
|
||||||
|
private $operation;
|
||||||
|
|
||||||
public function setBlueprint(DrydockBlueprint $blueprint) {
|
public function setBlueprint(DrydockBlueprint $blueprint) {
|
||||||
$this->blueprint = $blueprint;
|
$this->blueprint = $blueprint;
|
||||||
|
@ -33,6 +34,15 @@ final class DrydockLogSearchEngine extends PhabricatorApplicationSearchEngine {
|
||||||
return $this->lease;
|
return $this->lease;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setOperation(DrydockRepositoryOperation $operation) {
|
||||||
|
$this->operation = $operation;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getOperation() {
|
||||||
|
return $this->operation;
|
||||||
|
}
|
||||||
|
|
||||||
public function canUseInPanelContext() {
|
public function canUseInPanelContext() {
|
||||||
// Prevent use on Dashboard panels since all log queries currently need a
|
// Prevent use on Dashboard panels since all log queries currently need a
|
||||||
// parent object and these don't seem particularly useful in any case.
|
// parent object and these don't seem particularly useful in any case.
|
||||||
|
@ -65,6 +75,11 @@ final class DrydockLogSearchEngine extends PhabricatorApplicationSearchEngine {
|
||||||
$query->withLeasePHIDs(array($lease->getPHID()));
|
$query->withLeasePHIDs(array($lease->getPHID()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$operation = $this->getOperation();
|
||||||
|
if ($operation) {
|
||||||
|
$query->withOperationPHIDs(array($operation->getPHID()));
|
||||||
|
}
|
||||||
|
|
||||||
return $query;
|
return $query;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,9 +112,15 @@ final class DrydockLogSearchEngine extends PhabricatorApplicationSearchEngine {
|
||||||
return "/drydock/lease/{$id}/logs/{$path}";
|
return "/drydock/lease/{$id}/logs/{$path}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$operation = $this->getOperation();
|
||||||
|
if ($operation) {
|
||||||
|
$id = $operation->getID();
|
||||||
|
return "/drydock/operation/{$id}/logs/{$path}";
|
||||||
|
}
|
||||||
|
|
||||||
throw new Exception(
|
throw new Exception(
|
||||||
pht(
|
pht(
|
||||||
'Search engine has no blueprint, resource, or lease.'));
|
'Search engine has no blueprint, resource, lease, or operation.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getBuiltinQueryNames() {
|
protected function getBuiltinQueryNames() {
|
||||||
|
|
|
@ -6,6 +6,7 @@ final class DrydockLog extends DrydockDAO
|
||||||
protected $blueprintPHID;
|
protected $blueprintPHID;
|
||||||
protected $resourcePHID;
|
protected $resourcePHID;
|
||||||
protected $leasePHID;
|
protected $leasePHID;
|
||||||
|
protected $operationPHID;
|
||||||
protected $epoch;
|
protected $epoch;
|
||||||
protected $type;
|
protected $type;
|
||||||
protected $data = array();
|
protected $data = array();
|
||||||
|
@ -13,6 +14,7 @@ final class DrydockLog extends DrydockDAO
|
||||||
private $blueprint = self::ATTACHABLE;
|
private $blueprint = self::ATTACHABLE;
|
||||||
private $resource = self::ATTACHABLE;
|
private $resource = self::ATTACHABLE;
|
||||||
private $lease = self::ATTACHABLE;
|
private $lease = self::ATTACHABLE;
|
||||||
|
private $operation = self::ATTACHABLE;
|
||||||
|
|
||||||
protected function getConfiguration() {
|
protected function getConfiguration() {
|
||||||
return array(
|
return array(
|
||||||
|
@ -24,6 +26,7 @@ final class DrydockLog extends DrydockDAO
|
||||||
'blueprintPHID' => 'phid?',
|
'blueprintPHID' => 'phid?',
|
||||||
'resourcePHID' => 'phid?',
|
'resourcePHID' => 'phid?',
|
||||||
'leasePHID' => 'phid?',
|
'leasePHID' => 'phid?',
|
||||||
|
'operationPHID' => 'phid?',
|
||||||
'type' => 'text64',
|
'type' => 'text64',
|
||||||
),
|
),
|
||||||
self::CONFIG_KEY_SCHEMA => array(
|
self::CONFIG_KEY_SCHEMA => array(
|
||||||
|
@ -36,6 +39,9 @@ final class DrydockLog extends DrydockDAO
|
||||||
'key_lease' => array(
|
'key_lease' => array(
|
||||||
'columns' => array('leasePHID', 'type'),
|
'columns' => array('leasePHID', 'type'),
|
||||||
),
|
),
|
||||||
|
'key_operation' => array(
|
||||||
|
'columns' => array('operationPHID', 'type'),
|
||||||
|
),
|
||||||
'epoch' => array(
|
'epoch' => array(
|
||||||
'columns' => array('epoch'),
|
'columns' => array('epoch'),
|
||||||
),
|
),
|
||||||
|
@ -70,6 +76,16 @@ final class DrydockLog extends DrydockDAO
|
||||||
return $this->assertAttached($this->lease);
|
return $this->assertAttached($this->lease);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function attachOperation(
|
||||||
|
DrydockRepositoryOperation $operation = null) {
|
||||||
|
$this->operation = $operation;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getOperation() {
|
||||||
|
return $this->assertAttached($this->operation);
|
||||||
|
}
|
||||||
|
|
||||||
public function isComplete() {
|
public function isComplete() {
|
||||||
if ($this->getBlueprintPHID() && !$this->getBlueprint()) {
|
if ($this->getBlueprintPHID() && !$this->getBlueprint()) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -83,6 +99,10 @@ final class DrydockLog extends DrydockDAO
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->getOperationPHID() && !$this->getOperation()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,8 +128,8 @@ final class DrydockLog extends DrydockDAO
|
||||||
|
|
||||||
public function describeAutomaticCapability($capability) {
|
public function describeAutomaticCapability($capability) {
|
||||||
return pht(
|
return pht(
|
||||||
'To view log details, you must be able to view the associated '.
|
'To view log details, you must be able to view all associated '.
|
||||||
'blueprint, resource and lease.');
|
'blueprints, resources, leases, and repository operations.');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ final class DrydockRepositoryOperation extends DrydockDAO
|
||||||
private $repository = self::ATTACHABLE;
|
private $repository = self::ATTACHABLE;
|
||||||
private $object = self::ATTACHABLE;
|
private $object = self::ATTACHABLE;
|
||||||
private $implementation = self::ATTACHABLE;
|
private $implementation = self::ATTACHABLE;
|
||||||
|
private $workingCopyLease = self::ATTACHABLE;
|
||||||
|
|
||||||
public static function initializeNewOperation(
|
public static function initializeNewOperation(
|
||||||
DrydockRepositoryOperationType $op) {
|
DrydockRepositoryOperationType $op) {
|
||||||
|
@ -90,6 +91,19 @@ final class DrydockRepositoryOperation extends DrydockDAO
|
||||||
return $this->implementation;
|
return $this->implementation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getWorkingCopyLease() {
|
||||||
|
return $this->assertAttached($this->workingCopyLease);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function attachWorkingCopyLease(DrydockLease $lease) {
|
||||||
|
$this->workingCopyLease = $lease;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasWorkingCopyLease() {
|
||||||
|
return ($this->workingCopyLease !== self::ATTACHABLE);
|
||||||
|
}
|
||||||
|
|
||||||
public function getProperty($key, $default = null) {
|
public function getProperty($key, $default = null) {
|
||||||
return idx($this->properties, $key, $default);
|
return idx($this->properties, $key, $default);
|
||||||
}
|
}
|
||||||
|
@ -189,6 +203,37 @@ final class DrydockRepositoryOperation extends DrydockDAO
|
||||||
return $this->getProperty('exec.workingcopy.error');
|
return $this->getProperty('exec.workingcopy.error');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function logText($text) {
|
||||||
|
return $this->logEvent(
|
||||||
|
DrydockTextLogType::LOGCONST,
|
||||||
|
array(
|
||||||
|
'text' => $text,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function logEvent($type, array $data = array()) {
|
||||||
|
$log = id(new DrydockLog())
|
||||||
|
->setEpoch(PhabricatorTime::getNow())
|
||||||
|
->setType($type)
|
||||||
|
->setData($data);
|
||||||
|
|
||||||
|
$log->setOperationPHID($this->getPHID());
|
||||||
|
|
||||||
|
if ($this->hasWorkingCopyLease()) {
|
||||||
|
$lease = $this->getWorkingCopyLease();
|
||||||
|
$log->setLeasePHID($lease->getPHID());
|
||||||
|
|
||||||
|
$resource_phid = $lease->getResourcePHID();
|
||||||
|
if ($resource_phid) {
|
||||||
|
$resource = $lease->getResource();
|
||||||
|
|
||||||
|
$log->setResourcePHID($resource->getPHID());
|
||||||
|
$log->setBlueprintPHID($resource->getBlueprintPHID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $log->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
||||||
|
|
|
@ -3,6 +3,46 @@
|
||||||
final class DrydockLogListView extends AphrontView {
|
final class DrydockLogListView extends AphrontView {
|
||||||
|
|
||||||
private $logs;
|
private $logs;
|
||||||
|
private $hideBlueprints;
|
||||||
|
private $hideResources;
|
||||||
|
private $hideLeases;
|
||||||
|
private $hideOperations;
|
||||||
|
|
||||||
|
public function setHideBlueprints($hide_blueprints) {
|
||||||
|
$this->hideBlueprints = $hide_blueprints;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHideBlueprints() {
|
||||||
|
return $this->hideBlueprints;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setHideResources($hide_resources) {
|
||||||
|
$this->hideResources = $hide_resources;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHideResources() {
|
||||||
|
return $this->hideResources;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setHideLeases($hide_leases) {
|
||||||
|
$this->hideLeases = $hide_leases;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHideLeases() {
|
||||||
|
return $this->hideLeases;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setHideOperations($hide_operations) {
|
||||||
|
$this->hideOperations = $hide_operations;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHideOperations() {
|
||||||
|
return $this->hideOperations;
|
||||||
|
}
|
||||||
|
|
||||||
public function setLogs(array $logs) {
|
public function setLogs(array $logs) {
|
||||||
assert_instances_of($logs, 'DrydockLog');
|
assert_instances_of($logs, 'DrydockLog');
|
||||||
|
@ -41,6 +81,13 @@ final class DrydockLogListView extends AphrontView {
|
||||||
$lease = null;
|
$lease = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$operation_phid = $log->getOperationPHID();
|
||||||
|
if ($operation_phid) {
|
||||||
|
$operation = $viewer->renderHandle($operation_phid);
|
||||||
|
} else {
|
||||||
|
$operation = null;
|
||||||
|
}
|
||||||
|
|
||||||
if ($log->isComplete()) {
|
if ($log->isComplete()) {
|
||||||
$type_key = $log->getType();
|
$type_key = $log->getType();
|
||||||
if (isset($types[$type_key])) {
|
if (isset($types[$type_key])) {
|
||||||
|
@ -72,6 +119,7 @@ final class DrydockLogListView extends AphrontView {
|
||||||
$blueprint,
|
$blueprint,
|
||||||
$resource,
|
$resource,
|
||||||
$lease,
|
$lease,
|
||||||
|
$operation,
|
||||||
id(new PHUIIconView())->setIcon($icon),
|
id(new PHUIIconView())->setIcon($icon),
|
||||||
$type,
|
$type,
|
||||||
$data,
|
$data,
|
||||||
|
@ -86,16 +134,25 @@ final class DrydockLogListView extends AphrontView {
|
||||||
pht('Blueprint'),
|
pht('Blueprint'),
|
||||||
pht('Resource'),
|
pht('Resource'),
|
||||||
pht('Lease'),
|
pht('Lease'),
|
||||||
|
pht('Operation'),
|
||||||
null,
|
null,
|
||||||
pht('Type'),
|
pht('Type'),
|
||||||
pht('Data'),
|
pht('Data'),
|
||||||
pht('Date'),
|
pht('Date'),
|
||||||
))
|
))
|
||||||
|
->setColumnVisibility(
|
||||||
|
array(
|
||||||
|
!$this->getHideBlueprints(),
|
||||||
|
!$this->getHideResources(),
|
||||||
|
!$this->getHideLeases(),
|
||||||
|
!$this->getHideOperations(),
|
||||||
|
))
|
||||||
->setColumnClasses(
|
->setColumnClasses(
|
||||||
array(
|
array(
|
||||||
'',
|
'',
|
||||||
'',
|
'',
|
||||||
'',
|
'',
|
||||||
|
'',
|
||||||
'icon',
|
'icon',
|
||||||
'',
|
'',
|
||||||
'wide',
|
'wide',
|
||||||
|
|
|
@ -59,6 +59,10 @@ final class DrydockRepositoryOperationUpdateWorker
|
||||||
// No matter what happens here, destroy the lease away once we're done.
|
// No matter what happens here, destroy the lease away once we're done.
|
||||||
$lease->setReleaseOnDestruction(true);
|
$lease->setReleaseOnDestruction(true);
|
||||||
|
|
||||||
|
$operation->attachWorkingCopyLease($lease);
|
||||||
|
|
||||||
|
$operation->logEvent(DrydockOperationWorkLogType::LOGCONST);
|
||||||
|
|
||||||
$operation->applyOperation($interface);
|
$operation->applyOperation($interface);
|
||||||
|
|
||||||
} catch (PhabricatorWorkerYieldException $ex) {
|
} catch (PhabricatorWorkerYieldException $ex) {
|
||||||
|
|
|
@ -71,7 +71,7 @@ final class PhabricatorOwnersDetailController
|
||||||
'package' => $package->getPHID(),
|
'package' => $package->getPHID(),
|
||||||
));
|
));
|
||||||
|
|
||||||
$status_concern = PhabricatorAuditCommitStatusConstants::CONCERN_RAISED;
|
$status_concern = DiffusionCommitAuditStatus::CONCERN_RAISED;
|
||||||
|
|
||||||
$attention_commits = id(new DiffusionCommitQuery())
|
$attention_commits = id(new DiffusionCommitQuery())
|
||||||
->setViewer($request->getUser())
|
->setViewer($request->getUser())
|
||||||
|
|
|
@ -306,6 +306,14 @@ final class PhabricatorUser
|
||||||
return ($this->session !== self::ATTACHABLE);
|
return ($this->session !== self::ATTACHABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function hasHighSecuritySession() {
|
||||||
|
if (!$this->hasSession()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->getSession()->isHighSecuritySession();
|
||||||
|
}
|
||||||
|
|
||||||
private function generateConduitCertificate() {
|
private function generateConduitCertificate() {
|
||||||
return Filesystem::readRandomCharacters(255);
|
return Filesystem::readRandomCharacters(255);
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,9 @@ final class PhabricatorPhrictionApplication extends PhabricatorApplication {
|
||||||
|
|
||||||
'preview/(?P<slug>.*/)' => 'PhrictionMarkupPreviewController',
|
'preview/(?P<slug>.*/)' => 'PhrictionMarkupPreviewController',
|
||||||
'diff/(?P<id>[1-9]\d*)/' => 'PhrictionDiffController',
|
'diff/(?P<id>[1-9]\d*)/' => 'PhrictionDiffController',
|
||||||
|
|
||||||
|
$this->getEditRoutePattern('document/edit/')
|
||||||
|
=> 'PhrictionEditEngineController',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,7 +95,7 @@ final class PhrictionDiffController extends PhrictionController {
|
||||||
$navigation_table = null;
|
$navigation_table = null;
|
||||||
if ($l + 1 == $r) {
|
if ($l + 1 == $r) {
|
||||||
$nav_l = ($l > 1);
|
$nav_l = ($l > 1);
|
||||||
$nav_r = ($r != $current->getVersion());
|
$nav_r = ($r != $document->getMaxVersion());
|
||||||
|
|
||||||
$uri = $request->getRequestURI();
|
$uri = $request->getRequestURI();
|
||||||
|
|
||||||
|
@ -191,30 +191,28 @@ final class PhrictionDiffController extends PhrictionController {
|
||||||
PhrictionChangeType::CHANGE_MOVE_AWAY => true, // Plain silly
|
PhrictionChangeType::CHANGE_MOVE_AWAY => true, // Plain silly
|
||||||
PhrictionChangeType::CHANGE_STUB => true, // Utterly silly
|
PhrictionChangeType::CHANGE_STUB => true, // Utterly silly
|
||||||
);
|
);
|
||||||
|
|
||||||
if (isset($hidden_statuses[$content->getChangeType()])) {
|
if (isset($hidden_statuses[$content->getChangeType()])) {
|
||||||
// Don't show an edit/revert button for changes which deleted, moved or
|
// Don't show an edit/revert button for changes which deleted, moved or
|
||||||
// stubbed the content since it's silly.
|
// stubbed the content since it's silly.
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($content->getID() == $current->getID()) {
|
if ($version == $current->getVersion()) {
|
||||||
return phutil_tag(
|
$label = pht('Edit Current Version %s...', new PhutilNumber($version));
|
||||||
'a',
|
} else if ($version < $current->getVersion()) {
|
||||||
array(
|
$label = pht('Edit Older Version %s...', new PhutilNumber($version));
|
||||||
'href' => '/phriction/edit/'.$document_id.'/',
|
} else {
|
||||||
'class' => 'button button-grey',
|
$label = pht('Edit Draft Version %s...', new PhutilNumber($version));
|
||||||
),
|
|
||||||
pht('Edit Current Version'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return phutil_tag(
|
return phutil_tag(
|
||||||
'a',
|
'a',
|
||||||
array(
|
array(
|
||||||
'href' => '/phriction/edit/'.$document_id.'/?revert='.$version,
|
'href' => '/phriction/edit/'.$document_id.'/?revert='.$version,
|
||||||
'class' => 'button button-grey',
|
'class' => 'button button-grey',
|
||||||
),
|
),
|
||||||
pht('Revert to Version %s...', $version));
|
$label);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function renderComparisonTable(array $content) {
|
private function renderComparisonTable(array $content) {
|
||||||
|
|
|
@ -186,6 +186,35 @@ final class PhrictionDocumentController
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
$content = $document->getContent();
|
$content = $document->getContent();
|
||||||
|
|
||||||
|
if ($content->getVersion() < $document->getMaxVersion()) {
|
||||||
|
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||||
|
$viewer,
|
||||||
|
$document,
|
||||||
|
PhabricatorPolicyCapability::CAN_EDIT);
|
||||||
|
if ($can_edit) {
|
||||||
|
$document_uri = new PhutilURI($document->getURI());
|
||||||
|
$draft_uri = $document_uri->alter('v', $document->getMaxVersion());
|
||||||
|
|
||||||
|
$draft_link = phutil_tag(
|
||||||
|
'a',
|
||||||
|
array(
|
||||||
|
'href' => $draft_uri,
|
||||||
|
),
|
||||||
|
pht('View Draft Version'));
|
||||||
|
|
||||||
|
$draft_link = phutil_tag('strong', array(), $draft_link);
|
||||||
|
|
||||||
|
$version_note = id(new PHUIInfoView())
|
||||||
|
->setSeverity(PHUIInfoView::SEVERITY_NOTICE)
|
||||||
|
->appendChild(
|
||||||
|
array(
|
||||||
|
pht('This document has unpublished draft changes.'),
|
||||||
|
' ',
|
||||||
|
$draft_link,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$page_title = $content->getTitle();
|
$page_title = $content->getTitle();
|
||||||
|
@ -348,6 +377,17 @@ final class PhrictionDocumentController
|
||||||
$page_content->setCurtain($curtain);
|
$page_content->setCurtain($curtain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$timeline = $this->buildTransactionTimeline(
|
||||||
|
$document,
|
||||||
|
new PhrictionTransactionQuery());
|
||||||
|
|
||||||
|
$edit_engine = id(new PhrictionDocumentEditEngine())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->setTargetObject($document);
|
||||||
|
|
||||||
|
$comment_view = $edit_engine
|
||||||
|
->buildEditEngineCommentView($document);
|
||||||
|
|
||||||
return $this->newPage()
|
return $this->newPage()
|
||||||
->setTitle($page_title)
|
->setTitle($page_title)
|
||||||
->setCrumbs($crumbs)
|
->setCrumbs($crumbs)
|
||||||
|
@ -356,7 +396,16 @@ final class PhrictionDocumentController
|
||||||
array(
|
array(
|
||||||
$page_content,
|
$page_content,
|
||||||
$prop_list,
|
$prop_list,
|
||||||
$children,
|
phutil_tag(
|
||||||
|
'div',
|
||||||
|
array(
|
||||||
|
'class' => 'phui-document-view-pro-box',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
$children,
|
||||||
|
$timeline,
|
||||||
|
$comment_view,
|
||||||
|
)),
|
||||||
));
|
));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -427,22 +476,31 @@ final class PhrictionDocumentController
|
||||||
if ($is_draft) {
|
if ($is_draft) {
|
||||||
$publish_name = pht('Publish Draft');
|
$publish_name = pht('Publish Draft');
|
||||||
} else {
|
} else {
|
||||||
$publish_name = pht('Publish Revert');
|
$publish_name = pht('Publish Older Version');
|
||||||
|
}
|
||||||
|
|
||||||
|
// If you're looking at the current version; and it's an unpublished
|
||||||
|
// draft; and you can publish it, add a UI hint that this might be an
|
||||||
|
// interesting action to take.
|
||||||
|
$hint_publish = false;
|
||||||
|
if ($is_draft) {
|
||||||
|
if ($can_publish) {
|
||||||
|
if ($document->getMaxVersion() == $content->getVersion()) {
|
||||||
|
$hint_publish = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$publish_uri = "/phriction/publish/{$id}/{$content_id}/";
|
$publish_uri = "/phriction/publish/{$id}/{$content_id}/";
|
||||||
|
|
||||||
if (PhabricatorEnv::getEnvConfig('phabricator.show-prototypes')) {
|
$curtain->addAction(
|
||||||
$publish_name = pht('Publish (Prototype!)');
|
id(new PhabricatorActionView())
|
||||||
|
->setName($publish_name)
|
||||||
$curtain->addAction(
|
->setIcon('fa-upload')
|
||||||
id(new PhabricatorActionView())
|
->setSelected($hint_publish)
|
||||||
->setName($publish_name)
|
->setDisabled(!$can_publish)
|
||||||
->setIcon('fa-upload')
|
->setWorkflow(true)
|
||||||
->setDisabled(!$can_publish)
|
->setHref($publish_uri));
|
||||||
->setWorkflow(true)
|
|
||||||
->setHref($publish_uri));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($document->getStatus() == PhrictionDocumentStatus::STATUS_EXISTS) {
|
if ($document->getStatus() == PhrictionDocumentStatus::STATUS_EXISTS) {
|
||||||
$curtain->addAction(
|
$curtain->addAction(
|
||||||
|
@ -600,7 +658,7 @@ final class PhrictionDocumentController
|
||||||
),
|
),
|
||||||
$list)));
|
$list)));
|
||||||
|
|
||||||
return phutil_tag_div('phui-document-view-pro-box', $box);
|
return $box;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function renderChildDocumentLink(array $info) {
|
private function renderChildDocumentLink(array $info) {
|
||||||
|
|
|
@ -72,43 +72,6 @@ final class PhrictionEditController
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($request->getBool('nodraft')) {
|
|
||||||
$draft = null;
|
|
||||||
$draft_key = null;
|
|
||||||
} else {
|
|
||||||
if ($document->getPHID()) {
|
|
||||||
$draft_key = $document->getPHID().':'.$content->getVersion();
|
|
||||||
} else {
|
|
||||||
$draft_key = 'phriction:'.$content->getSlug();
|
|
||||||
}
|
|
||||||
$draft = id(new PhabricatorDraft())->loadOneWhere(
|
|
||||||
'authorPHID = %s AND draftKey = %s',
|
|
||||||
$viewer->getPHID(),
|
|
||||||
$draft_key);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($draft &&
|
|
||||||
strlen($draft->getDraft()) &&
|
|
||||||
($draft->getDraft() != $content->getContent())) {
|
|
||||||
$content_text = $draft->getDraft();
|
|
||||||
|
|
||||||
$discard = phutil_tag(
|
|
||||||
'a',
|
|
||||||
array(
|
|
||||||
'href' => $request->getRequestURI()->alter('nodraft', true),
|
|
||||||
),
|
|
||||||
pht('discard this draft'));
|
|
||||||
|
|
||||||
$draft_note = new PHUIInfoView();
|
|
||||||
$draft_note->setSeverity(PHUIInfoView::SEVERITY_NOTICE);
|
|
||||||
$draft_note->setTitle(pht('Recovered Draft'));
|
|
||||||
$draft_note->appendChild(
|
|
||||||
pht('Showing a saved draft of your edits, you can %s.', $discard));
|
|
||||||
} else {
|
|
||||||
$content_text = $content->getContent();
|
|
||||||
$draft_note = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
require_celerity_resource('phriction-document-css');
|
require_celerity_resource('phriction-document-css');
|
||||||
|
|
||||||
$e_title = true;
|
$e_title = true;
|
||||||
|
@ -131,7 +94,15 @@ final class PhrictionEditController
|
||||||
|
|
||||||
$v_space = $document->getSpacePHID();
|
$v_space = $document->getSpacePHID();
|
||||||
|
|
||||||
|
$content_text = $content->getContent();
|
||||||
|
$is_draft_mode = ($document->getContent()->getVersion() != $max_version);
|
||||||
|
|
||||||
if ($request->isFormPost()) {
|
if ($request->isFormPost()) {
|
||||||
|
if ($is_new) {
|
||||||
|
$save_as_draft = false;
|
||||||
|
} else {
|
||||||
|
$save_as_draft = ($is_draft_mode || $request->getExists('draft'));
|
||||||
|
}
|
||||||
|
|
||||||
$title = $request->getStr('title');
|
$title = $request->getStr('title');
|
||||||
$content_text = $request->getStr('content');
|
$content_text = $request->getStr('content');
|
||||||
|
@ -143,13 +114,19 @@ final class PhrictionEditController
|
||||||
$v_projects = $request->getArr('projects');
|
$v_projects = $request->getArr('projects');
|
||||||
$v_space = $request->getStr('spacePHID');
|
$v_space = $request->getStr('spacePHID');
|
||||||
|
|
||||||
|
if ($save_as_draft) {
|
||||||
|
$edit_type = PhrictionDocumentDraftTransaction::TRANSACTIONTYPE;
|
||||||
|
} else {
|
||||||
|
$edit_type = PhrictionDocumentContentTransaction::TRANSACTIONTYPE;
|
||||||
|
}
|
||||||
|
|
||||||
$xactions = array();
|
$xactions = array();
|
||||||
|
|
||||||
$xactions[] = id(new PhrictionTransaction())
|
$xactions[] = id(new PhrictionTransaction())
|
||||||
->setTransactionType(PhrictionDocumentTitleTransaction::TRANSACTIONTYPE)
|
->setTransactionType(PhrictionDocumentTitleTransaction::TRANSACTIONTYPE)
|
||||||
->setNewValue($title);
|
->setNewValue($title);
|
||||||
$xactions[] = id(new PhrictionTransaction())
|
$xactions[] = id(new PhrictionTransaction())
|
||||||
->setTransactionType(
|
->setTransactionType($edit_type)
|
||||||
PhrictionDocumentContentTransaction::TRANSACTIONTYPE)
|
|
||||||
->setNewValue($content_text);
|
->setNewValue($content_text);
|
||||||
$xactions[] = id(new PhrictionTransaction())
|
$xactions[] = id(new PhrictionTransaction())
|
||||||
->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY)
|
->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY)
|
||||||
|
@ -181,11 +158,15 @@ final class PhrictionEditController
|
||||||
try {
|
try {
|
||||||
$editor->applyTransactions($document, $xactions);
|
$editor->applyTransactions($document, $xactions);
|
||||||
|
|
||||||
if ($draft) {
|
$uri = PhrictionDocument::getSlugURI($document->getSlug());
|
||||||
$draft->delete();
|
$uri = new PhutilURI($uri);
|
||||||
|
|
||||||
|
// If the user clicked "Save as Draft", take them to the draft, not
|
||||||
|
// to the current published page.
|
||||||
|
if ($save_as_draft) {
|
||||||
|
$uri = $uri->alter('v', $document->getMaxVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
$uri = PhrictionDocument::getSlugURI($document->getSlug());
|
|
||||||
return id(new AphrontRedirectResponse())->setURI($uri);
|
return id(new AphrontRedirectResponse())->setURI($uri);
|
||||||
} catch (PhabricatorApplicationTransactionValidationException $ex) {
|
} catch (PhabricatorApplicationTransactionValidationException $ex) {
|
||||||
$validation_exception = $ex;
|
$validation_exception = $ex;
|
||||||
|
@ -215,7 +196,7 @@ final class PhrictionEditController
|
||||||
if ($overwrite) {
|
if ($overwrite) {
|
||||||
$submit_button = pht('Overwrite Changes');
|
$submit_button = pht('Overwrite Changes');
|
||||||
} else {
|
} else {
|
||||||
$submit_button = pht('Save Changes');
|
$submit_button = pht('Save and Publish');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$submit_button = pht('Create Document');
|
$submit_button = pht('Create Document');
|
||||||
|
@ -235,11 +216,9 @@ final class PhrictionEditController
|
||||||
$view_capability = PhabricatorPolicyCapability::CAN_VIEW;
|
$view_capability = PhabricatorPolicyCapability::CAN_VIEW;
|
||||||
$edit_capability = PhabricatorPolicyCapability::CAN_EDIT;
|
$edit_capability = PhabricatorPolicyCapability::CAN_EDIT;
|
||||||
|
|
||||||
|
|
||||||
$form = id(new AphrontFormView())
|
$form = id(new AphrontFormView())
|
||||||
->setUser($viewer)
|
->setUser($viewer)
|
||||||
->addHiddenInput('slug', $document->getSlug())
|
->addHiddenInput('slug', $document->getSlug())
|
||||||
->addHiddenInput('nodraft', $request->getBool('nodraft'))
|
|
||||||
->addHiddenInput('contentVersion', $max_version)
|
->addHiddenInput('contentVersion', $max_version)
|
||||||
->addHiddenInput('overwrite', $overwrite)
|
->addHiddenInput('overwrite', $overwrite)
|
||||||
->appendChild(
|
->appendChild(
|
||||||
|
@ -293,11 +272,31 @@ final class PhrictionEditController
|
||||||
->setLabel(pht('Edit Notes'))
|
->setLabel(pht('Edit Notes'))
|
||||||
->setValue($notes)
|
->setValue($notes)
|
||||||
->setError(null)
|
->setError(null)
|
||||||
->setName('description'))
|
->setName('description'));
|
||||||
->appendChild(
|
|
||||||
|
if ($is_draft_mode) {
|
||||||
|
$form->appendControl(
|
||||||
id(new AphrontFormSubmitControl())
|
id(new AphrontFormSubmitControl())
|
||||||
->addCancelButton($cancel_uri)
|
->addCancelButton($cancel_uri)
|
||||||
->setValue($submit_button));
|
->setValue(pht('Save Draft')));
|
||||||
|
} else {
|
||||||
|
$submit = id(new AphrontFormSubmitControl());
|
||||||
|
|
||||||
|
if (!$is_new) {
|
||||||
|
$draft_button = id(new PHUIButtonView())
|
||||||
|
->setTag('input')
|
||||||
|
->setName('draft')
|
||||||
|
->setText(pht('Save as Draft'))
|
||||||
|
->setColor(PHUIButtonView::GREEN);
|
||||||
|
$submit->addButton($draft_button);
|
||||||
|
}
|
||||||
|
|
||||||
|
$submit
|
||||||
|
->addCancelButton($cancel_uri)
|
||||||
|
->setValue($submit_button);
|
||||||
|
|
||||||
|
$form->appendControl($submit);
|
||||||
|
}
|
||||||
|
|
||||||
$form_box = id(new PHUIObjectBoxView())
|
$form_box = id(new PHUIObjectBoxView())
|
||||||
->setHeaderText($page_title)
|
->setHeaderText($page_title)
|
||||||
|
@ -325,7 +324,6 @@ final class PhrictionEditController
|
||||||
$view = id(new PHUITwoColumnView())
|
$view = id(new PHUITwoColumnView())
|
||||||
->setFooter(
|
->setFooter(
|
||||||
array(
|
array(
|
||||||
$draft_note,
|
|
||||||
$form_box,
|
$form_box,
|
||||||
$preview,
|
$preview,
|
||||||
));
|
));
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhrictionEditEngineController
|
||||||
|
extends PhrictionController {
|
||||||
|
|
||||||
|
public function handleRequest(AphrontRequest $request) {
|
||||||
|
// NOTE: For now, this controller is only used to handle comments.
|
||||||
|
|
||||||
|
return id(new PhrictionDocumentEditEngine())
|
||||||
|
->setController($this)
|
||||||
|
->buildResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -63,7 +63,7 @@ final class PhrictionPublishController
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($content->getVersion() < $document->getContent()->getVersion()) {
|
if ($content->getVersion() < $document->getContent()->getVersion()) {
|
||||||
$title = pht('Revert Document?');
|
$title = pht('Publish Older Version?');
|
||||||
$body = pht(
|
$body = pht(
|
||||||
'Revert the published version of this document to an older '.
|
'Revert the published version of this document to an older '.
|
||||||
'version?');
|
'version?');
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhrictionDocumentEditEngine
|
||||||
|
extends PhabricatorEditEngine {
|
||||||
|
|
||||||
|
const ENGINECONST = 'phriction.document';
|
||||||
|
|
||||||
|
public function isEngineConfigurable() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getEngineName() {
|
||||||
|
return pht('Phriction Document');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSummaryHeader() {
|
||||||
|
return pht('Edit Phriction Document Configurations');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSummaryText() {
|
||||||
|
return pht('This engine is used to edit Phriction documents.');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getEngineApplicationClass() {
|
||||||
|
return 'PhabricatorPhrictionApplication';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function newEditableObject() {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
return PhrictionDocument::initializeNewDocument(
|
||||||
|
$viewer,
|
||||||
|
'/');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function newObjectQuery() {
|
||||||
|
return id(new PhrictionDocumentQuery())
|
||||||
|
->needContent(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getObjectCreateTitleText($object) {
|
||||||
|
return pht('Create Document');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getObjectCreateButtonText($object) {
|
||||||
|
return pht('Create Document');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getObjectEditTitleText($object) {
|
||||||
|
return pht('Edit Document: %s', $object->getContent()->getTitle());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getObjectEditShortText($object) {
|
||||||
|
return pht('Edit Document');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getObjectCreateShortText() {
|
||||||
|
return pht('Create Document');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getObjectName() {
|
||||||
|
return pht('Document');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getEditorURI() {
|
||||||
|
return '/phriction/document/edit/';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getObjectCreateCancelURI($object) {
|
||||||
|
return '/phriction/document/';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getObjectViewURI($object) {
|
||||||
|
return $object->getURI();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getCreateNewObjectPolicy() {
|
||||||
|
// NOTE: For now, this engine is only to support commenting.
|
||||||
|
return PhabricatorPolicies::POLICY_NOONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function buildCustomEditFields($object) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -74,6 +74,21 @@ final class PhrictionTransactionEditor
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setShouldPublishContent(
|
||||||
|
PhrictionDocument $object,
|
||||||
|
$publish) {
|
||||||
|
|
||||||
|
if ($publish) {
|
||||||
|
$content_phid = $this->getNewContent()->getPHID();
|
||||||
|
} else {
|
||||||
|
$content_phid = $this->getOldContent()->getPHID();
|
||||||
|
}
|
||||||
|
|
||||||
|
$object->setContentPHID($content_phid);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function getEditorApplicationClass() {
|
public function getEditorApplicationClass() {
|
||||||
return 'PhabricatorPhrictionApplication';
|
return 'PhabricatorPhrictionApplication';
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,87 +1,25 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
final class PhrictionDocumentContentTransaction
|
final class PhrictionDocumentContentTransaction
|
||||||
extends PhrictionDocumentVersionTransaction {
|
extends PhrictionDocumentEditTransaction {
|
||||||
|
|
||||||
const TRANSACTIONTYPE = 'content';
|
const TRANSACTIONTYPE = 'content';
|
||||||
|
|
||||||
public function generateOldValue($object) {
|
|
||||||
if ($this->getEditor()->getIsNewObject()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return $object->getContent()->getContent();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function generateNewValue($object, $value) {
|
|
||||||
return $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function applyInternalEffects($object, $value) {
|
public function applyInternalEffects($object, $value) {
|
||||||
|
parent::applyInternalEffects($object, $value);
|
||||||
|
|
||||||
$object->setStatus(PhrictionDocumentStatus::STATUS_EXISTS);
|
$object->setStatus(PhrictionDocumentStatus::STATUS_EXISTS);
|
||||||
|
|
||||||
$content = $this->getNewDocumentContent($object);
|
$this->getEditor()->setShouldPublishContent($object, true);
|
||||||
$content->setContent($value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function shouldHide() {
|
|
||||||
if ($this->getOldValue() === null) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getActionStrength() {
|
|
||||||
return 1.3;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getActionName() {
|
|
||||||
return pht('Edited');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getTitle() {
|
|
||||||
return pht(
|
|
||||||
'%s edited the content of this document.',
|
|
||||||
$this->renderAuthor());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getTitleForFeed() {
|
|
||||||
return pht(
|
|
||||||
'%s edited the content of %s.',
|
|
||||||
$this->renderAuthor(),
|
|
||||||
$this->renderObject());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function hasChangeDetailView() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getMailDiffSectionHeader() {
|
|
||||||
return pht('CHANGES TO DOCUMENT CONTENT');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function newChangeDetailView() {
|
|
||||||
$viewer = $this->getViewer();
|
|
||||||
|
|
||||||
return id(new PhabricatorApplicationTransactionTextDiffDetailView())
|
|
||||||
->setViewer($viewer)
|
|
||||||
->setOldText($this->getOldValue())
|
|
||||||
->setNewText($this->getNewValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function newRemarkupChanges() {
|
|
||||||
$changes = array();
|
|
||||||
|
|
||||||
$changes[] = $this->newRemarkupChange()
|
|
||||||
->setOldValue($this->getOldValue())
|
|
||||||
->setNewValue($this->getNewValue());
|
|
||||||
|
|
||||||
return $changes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function validateTransactions($object, array $xactions) {
|
public function validateTransactions($object, array $xactions) {
|
||||||
$errors = array();
|
$errors = array();
|
||||||
|
|
||||||
|
// NOTE: This is slightly different from the draft validation. Here,
|
||||||
|
// we're validating that: you can't edit away a document; and you can't
|
||||||
|
// create an empty document.
|
||||||
|
|
||||||
$content = $object->getContent()->getContent();
|
$content = $object->getContent()->getContent();
|
||||||
if ($this->isEmptyTextTransaction($content, $xactions)) {
|
if ($this->isEmptyTextTransaction($content, $xactions)) {
|
||||||
$errors[] = $this->newRequiredError(
|
$errors[] = $this->newRequiredError(
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhrictionDocumentDraftTransaction
|
||||||
|
extends PhrictionDocumentEditTransaction {
|
||||||
|
|
||||||
|
const TRANSACTIONTYPE = 'draft';
|
||||||
|
|
||||||
|
public function applyInternalEffects($object, $value) {
|
||||||
|
parent::applyInternalEffects($object, $value);
|
||||||
|
|
||||||
|
$this->getEditor()->setShouldPublishContent($object, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function shouldHideForFeed() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function validateTransactions($object, array $xactions) {
|
||||||
|
$errors = array();
|
||||||
|
|
||||||
|
// NOTE: We're only validating that you can't edit a document down to
|
||||||
|
// nothing in a draft transaction. Alone, this doesn't prevent you from
|
||||||
|
// creating a document with no content. The content transaction has
|
||||||
|
// validation for that.
|
||||||
|
|
||||||
|
if (!$xactions) {
|
||||||
|
return $errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
$content = $object->getContent()->getContent();
|
||||||
|
if ($this->isEmptyTextTransaction($content, $xactions)) {
|
||||||
|
$errors[] = $this->newRequiredError(
|
||||||
|
pht('Documents must have content.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
abstract class PhrictionDocumentEditTransaction
|
||||||
|
extends PhrictionDocumentVersionTransaction {
|
||||||
|
|
||||||
|
public function generateOldValue($object) {
|
||||||
|
if ($this->getEditor()->getIsNewObject()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: We want to get the newest version of the content here, regardless
|
||||||
|
// of whether it's published or not.
|
||||||
|
|
||||||
|
$actor = $this->getActor();
|
||||||
|
|
||||||
|
return id(new PhrictionContentQuery())
|
||||||
|
->setViewer($actor)
|
||||||
|
->withDocumentPHIDs(array($object->getPHID()))
|
||||||
|
->setOrder('newest')
|
||||||
|
->setLimit(1)
|
||||||
|
->executeOne()
|
||||||
|
->getContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function generateNewValue($object, $value) {
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function applyInternalEffects($object, $value) {
|
||||||
|
$content = $this->getNewDocumentContent($object);
|
||||||
|
$content->setContent($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getActionStrength() {
|
||||||
|
return 1.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getActionName() {
|
||||||
|
return pht('Edited');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTitle() {
|
||||||
|
return pht(
|
||||||
|
'%s edited the content of this document.',
|
||||||
|
$this->renderAuthor());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTitleForFeed() {
|
||||||
|
return pht(
|
||||||
|
'%s edited the content of %s.',
|
||||||
|
$this->renderAuthor(),
|
||||||
|
$this->renderObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMailDiffSectionHeader() {
|
||||||
|
return pht('CHANGES TO DOCUMENT CONTENT');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasChangeDetailView() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function newChangeDetailView() {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
|
return id(new PhabricatorApplicationTransactionTextDiffDetailView())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->setOldText($this->getOldValue())
|
||||||
|
->setNewText($this->getNewValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function newRemarkupChanges() {
|
||||||
|
$changes = array();
|
||||||
|
|
||||||
|
$changes[] = $this->newRemarkupChange()
|
||||||
|
->setOldValue($this->getOldValue())
|
||||||
|
->setNewValue($this->getNewValue());
|
||||||
|
|
||||||
|
return $changes;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -25,9 +25,8 @@ final class PhabricatorRepositoryCommit
|
||||||
protected $committerIdentityPHID;
|
protected $committerIdentityPHID;
|
||||||
protected $commitIdentifier;
|
protected $commitIdentifier;
|
||||||
protected $epoch;
|
protected $epoch;
|
||||||
protected $mailKey;
|
|
||||||
protected $authorPHID;
|
protected $authorPHID;
|
||||||
protected $auditStatus = PhabricatorAuditCommitStatusConstants::NONE;
|
protected $auditStatus = DiffusionCommitAuditStatus::NONE;
|
||||||
protected $summary = '';
|
protected $summary = '';
|
||||||
protected $importStatus = 0;
|
protected $importStatus = 0;
|
||||||
|
|
||||||
|
@ -116,11 +115,10 @@ final class PhabricatorRepositoryCommit
|
||||||
self::CONFIG_TIMESTAMPS => false,
|
self::CONFIG_TIMESTAMPS => false,
|
||||||
self::CONFIG_COLUMN_SCHEMA => array(
|
self::CONFIG_COLUMN_SCHEMA => array(
|
||||||
'commitIdentifier' => 'text40',
|
'commitIdentifier' => 'text40',
|
||||||
'mailKey' => 'bytes20',
|
|
||||||
'authorPHID' => 'phid?',
|
'authorPHID' => 'phid?',
|
||||||
'authorIdentityPHID' => 'phid?',
|
'authorIdentityPHID' => 'phid?',
|
||||||
'committerIdentityPHID' => 'phid?',
|
'committerIdentityPHID' => 'phid?',
|
||||||
'auditStatus' => 'uint32',
|
'auditStatus' => 'text32',
|
||||||
'summary' => 'text255',
|
'summary' => 'text255',
|
||||||
'importStatus' => 'uint32',
|
'importStatus' => 'uint32',
|
||||||
),
|
),
|
||||||
|
@ -321,13 +319,6 @@ final class PhabricatorRepositoryCommit
|
||||||
return mpull($audits, 'getAuditorPHID');
|
return mpull($audits, 'getAuditorPHID');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function save() {
|
|
||||||
if (!$this->mailKey) {
|
|
||||||
$this->mailKey = Filesystem::readRandomCharacters(20);
|
|
||||||
}
|
|
||||||
return parent::save();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function delete() {
|
public function delete() {
|
||||||
$data = $this->loadCommitData();
|
$data = $this->loadCommitData();
|
||||||
$audits = id(new PhabricatorRepositoryAuditRequest())
|
$audits = id(new PhabricatorRepositoryAuditRequest())
|
||||||
|
@ -381,27 +372,24 @@ final class PhabricatorRepositoryCommit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$current_status = $this->getAuditStatus();
|
|
||||||
$status_verify = PhabricatorAuditCommitStatusConstants::NEEDS_VERIFICATION;
|
|
||||||
|
|
||||||
if ($any_concern) {
|
if ($any_concern) {
|
||||||
if ($current_status == $status_verify) {
|
if ($this->isAuditStatusNeedsVerification()) {
|
||||||
// If the change is in "Needs Verification", we keep it there as
|
// If the change is in "Needs Verification", we keep it there as
|
||||||
// long as any auditors still have concerns.
|
// long as any auditors still have concerns.
|
||||||
$status = $status_verify;
|
$status = DiffusionCommitAuditStatus::NEEDS_VERIFICATION;
|
||||||
} else {
|
} else {
|
||||||
$status = PhabricatorAuditCommitStatusConstants::CONCERN_RAISED;
|
$status = DiffusionCommitAuditStatus::CONCERN_RAISED;
|
||||||
}
|
}
|
||||||
} else if ($any_accept) {
|
} else if ($any_accept) {
|
||||||
if ($any_need) {
|
if ($any_need) {
|
||||||
$status = PhabricatorAuditCommitStatusConstants::PARTIALLY_AUDITED;
|
$status = DiffusionCommitAuditStatus::PARTIALLY_AUDITED;
|
||||||
} else {
|
} else {
|
||||||
$status = PhabricatorAuditCommitStatusConstants::FULLY_AUDITED;
|
$status = DiffusionCommitAuditStatus::AUDITED;
|
||||||
}
|
}
|
||||||
} else if ($any_need) {
|
} else if ($any_need) {
|
||||||
$status = PhabricatorAuditCommitStatusConstants::NEEDS_AUDIT;
|
$status = DiffusionCommitAuditStatus::NEEDS_AUDIT;
|
||||||
} else {
|
} else {
|
||||||
$status = PhabricatorAuditCommitStatusConstants::NONE;
|
$status = DiffusionCommitAuditStatus::NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->setAuditStatus($status);
|
return $this->setAuditStatus($status);
|
||||||
|
@ -532,7 +520,31 @@ final class PhabricatorRepositoryCommit
|
||||||
|
|
||||||
public function getAuditStatusObject() {
|
public function getAuditStatusObject() {
|
||||||
$status = $this->getAuditStatus();
|
$status = $this->getAuditStatus();
|
||||||
return PhabricatorAuditCommitStatusConstants::newForLegacyStatus($status);
|
return DiffusionCommitAuditStatus::newForStatus($status);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isAuditStatusNoAudit() {
|
||||||
|
return $this->getAuditStatusObject()->isNoAudit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isAuditStatusNeedsAudit() {
|
||||||
|
return $this->getAuditStatusObject()->isNeedsAudit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isAuditStatusConcernRaised() {
|
||||||
|
return $this->getAuditStatusObject()->isConcernRaised();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isAuditStatusNeedsVerification() {
|
||||||
|
return $this->getAuditStatusObject()->isNeedsVerification();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isAuditStatusPartiallyAudited() {
|
||||||
|
return $this->getAuditStatusObject()->isPartiallyAudited();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isAuditStatusAudited() {
|
||||||
|
return $this->getAuditStatusObject()->isAudited();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
||||||
|
@ -584,7 +596,6 @@ final class PhabricatorRepositoryCommit
|
||||||
'phid' => $this->getPHID(),
|
'phid' => $this->getPHID(),
|
||||||
'commitIdentifier' => $this->getCommitIdentifier(),
|
'commitIdentifier' => $this->getCommitIdentifier(),
|
||||||
'epoch' => $this->getEpoch(),
|
'epoch' => $this->getEpoch(),
|
||||||
'mailKey' => $this->getMailKey(),
|
|
||||||
'authorPHID' => $this->getAuthorPHID(),
|
'authorPHID' => $this->getAuthorPHID(),
|
||||||
'auditStatus' => $this->getAuditStatus(),
|
'auditStatus' => $this->getAuditStatus(),
|
||||||
'summary' => $this->getSummary(),
|
'summary' => $this->getSummary(),
|
||||||
|
@ -830,16 +841,110 @@ final class PhabricatorRepositoryCommit
|
||||||
->setKey('identifier')
|
->setKey('identifier')
|
||||||
->setType('string')
|
->setType('string')
|
||||||
->setDescription(pht('The commit identifier.')),
|
->setDescription(pht('The commit identifier.')),
|
||||||
|
id(new PhabricatorConduitSearchFieldSpecification())
|
||||||
|
->setKey('repositoryPHID')
|
||||||
|
->setType('phid')
|
||||||
|
->setDescription(pht('The repository this commit belongs to.')),
|
||||||
|
id(new PhabricatorConduitSearchFieldSpecification())
|
||||||
|
->setKey('author')
|
||||||
|
->setType('map<string, wild>')
|
||||||
|
->setDescription(pht('Information about the commit author.')),
|
||||||
|
id(new PhabricatorConduitSearchFieldSpecification())
|
||||||
|
->setKey('committer')
|
||||||
|
->setType('map<string, wild>')
|
||||||
|
->setDescription(pht('Information about the committer.')),
|
||||||
|
id(new PhabricatorConduitSearchFieldSpecification())
|
||||||
|
->setKey('isImported')
|
||||||
|
->setType('bool')
|
||||||
|
->setDescription(pht('True if the commit is fully imported.')),
|
||||||
|
id(new PhabricatorConduitSearchFieldSpecification())
|
||||||
|
->setKey('isUnreachable')
|
||||||
|
->setType('bool')
|
||||||
|
->setDescription(
|
||||||
|
pht(
|
||||||
|
'True if the commit is not the ancestor of any tag, branch, or '.
|
||||||
|
'ref.')),
|
||||||
|
id(new PhabricatorConduitSearchFieldSpecification())
|
||||||
|
->setKey('auditStatus')
|
||||||
|
->setType('map<string, wild>')
|
||||||
|
->setDescription(pht('Information about the current audit status.')),
|
||||||
|
id(new PhabricatorConduitSearchFieldSpecification())
|
||||||
|
->setKey('message')
|
||||||
|
->setType('string')
|
||||||
|
->setDescription(pht('The commit message.')),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getFieldValuesForConduit() {
|
public function getFieldValuesForConduit() {
|
||||||
|
$data = $this->getCommitData();
|
||||||
|
|
||||||
// NOTE: This data should be similar to the information returned about
|
$author_identity = $this->getAuthorIdentity();
|
||||||
// commmits by "differential.diff.search" with the "commits" attachment.
|
if ($author_identity) {
|
||||||
|
$author_name = $author_identity->getIdentityDisplayName();
|
||||||
|
$author_email = $author_identity->getIdentityEmailAddress();
|
||||||
|
$author_raw = $author_identity->getIdentityName();
|
||||||
|
$author_identity_phid = $author_identity->getPHID();
|
||||||
|
$author_user_phid = $author_identity->getCurrentEffectiveUserPHID();
|
||||||
|
} else {
|
||||||
|
$author_name = null;
|
||||||
|
$author_email = null;
|
||||||
|
$author_raw = null;
|
||||||
|
$author_identity_phid = null;
|
||||||
|
$author_user_phid = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$committer_identity = $this->getCommitterIdentity();
|
||||||
|
if ($committer_identity) {
|
||||||
|
$committer_name = $committer_identity->getIdentityDisplayName();
|
||||||
|
$committer_email = $committer_identity->getIdentityEmailAddress();
|
||||||
|
$committer_raw = $committer_identity->getIdentityName();
|
||||||
|
$committer_identity_phid = $committer_identity->getPHID();
|
||||||
|
$committer_user_phid = $committer_identity->getCurrentEffectiveUserPHID();
|
||||||
|
} else {
|
||||||
|
$committer_name = null;
|
||||||
|
$committer_email = null;
|
||||||
|
$committer_raw = null;
|
||||||
|
$committer_identity_phid = null;
|
||||||
|
$committer_user_phid = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$author_epoch = $data->getCommitDetail('authorEpoch');
|
||||||
|
if ($author_epoch) {
|
||||||
|
$author_epoch = (int)$author_epoch;
|
||||||
|
} else {
|
||||||
|
$author_epoch = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$audit_status = $this->getAuditStatusObject();
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
'identifier' => $this->getCommitIdentifier(),
|
'identifier' => $this->getCommitIdentifier(),
|
||||||
|
'repositoryPHID' => $this->getRepository()->getPHID(),
|
||||||
|
'author' => array(
|
||||||
|
'name' => $author_name,
|
||||||
|
'email' => $author_email,
|
||||||
|
'raw' => $author_raw,
|
||||||
|
'epoch' => $author_epoch,
|
||||||
|
'identityPHID' => $author_identity_phid,
|
||||||
|
'userPHID' => $author_user_phid,
|
||||||
|
),
|
||||||
|
'committer' => array(
|
||||||
|
'name' => $committer_name,
|
||||||
|
'email' => $committer_email,
|
||||||
|
'raw' => $committer_raw,
|
||||||
|
'epoch' => (int)$this->getEpoch(),
|
||||||
|
'identityPHID' => $committer_identity_phid,
|
||||||
|
'userPHID' => $committer_user_phid,
|
||||||
|
),
|
||||||
|
'isUnreachable' => (bool)$this->isUnreachable(),
|
||||||
|
'isImported' => (bool)$this->isImported(),
|
||||||
|
'auditStatus' => array(
|
||||||
|
'value' => $audit_status->getKey(),
|
||||||
|
'name' => $audit_status->getName(),
|
||||||
|
'closed' => (bool)$audit_status->getIsClosed(),
|
||||||
|
'color.ansi' => $audit_status->getAnsiColor(),
|
||||||
|
),
|
||||||
|
'message' => $data->getCommitMessage(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -230,9 +230,20 @@ EOTEXT
|
||||||
|
|
||||||
$constants_rows = array();
|
$constants_rows = array();
|
||||||
foreach ($constants as $constant) {
|
foreach ($constants as $constant) {
|
||||||
|
if ($constant->getIsDeprecated()) {
|
||||||
|
$icon = id(new PHUIIconView())
|
||||||
|
->setIcon('fa-exclamation-triangle', 'red');
|
||||||
|
} else {
|
||||||
|
$icon = null;
|
||||||
|
}
|
||||||
|
|
||||||
$constants_rows[] = array(
|
$constants_rows[] = array(
|
||||||
$constant->getKey(),
|
$constant->getKey(),
|
||||||
$constant->getValue(),
|
array(
|
||||||
|
$icon,
|
||||||
|
' ',
|
||||||
|
$constant->getValue(),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,7 +255,7 @@ EOTEXT
|
||||||
))
|
))
|
||||||
->setColumnClasses(
|
->setColumnClasses(
|
||||||
array(
|
array(
|
||||||
'pre',
|
'mono',
|
||||||
'wide',
|
'wide',
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ final class PhabricatorSearchCheckboxesField
|
||||||
extends PhabricatorSearchField {
|
extends PhabricatorSearchField {
|
||||||
|
|
||||||
private $options;
|
private $options;
|
||||||
|
private $deprecatedOptions = array();
|
||||||
|
|
||||||
public function setOptions(array $options) {
|
public function setOptions(array $options) {
|
||||||
$this->options = $options;
|
$this->options = $options;
|
||||||
|
@ -14,6 +15,15 @@ final class PhabricatorSearchCheckboxesField
|
||||||
return $this->options;
|
return $this->options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setDeprecatedOptions(array $deprecated_options) {
|
||||||
|
$this->deprecatedOptions = $deprecated_options;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDeprecatedOptions() {
|
||||||
|
return $this->deprecatedOptions;
|
||||||
|
}
|
||||||
|
|
||||||
protected function getDefaultValue() {
|
protected function getDefaultValue() {
|
||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
|
@ -23,11 +33,12 @@ final class PhabricatorSearchCheckboxesField
|
||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $value;
|
return $this->getCanonicalValue($value);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getValueFromRequest(AphrontRequest $request, $key) {
|
protected function getValueFromRequest(AphrontRequest $request, $key) {
|
||||||
return $this->getListFromRequest($request, $key);
|
$value = $this->getListFromRequest($request, $key);
|
||||||
|
return $this->getCanonicalValue($value);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function newControl() {
|
protected function newControl() {
|
||||||
|
@ -58,7 +69,29 @@ final class PhabricatorSearchCheckboxesField
|
||||||
->setValue($option);
|
->setValue($option);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach ($this->getDeprecatedOptions() as $key => $value) {
|
||||||
|
$list[] = id(new ConduitConstantDescription())
|
||||||
|
->setKey($key)
|
||||||
|
->setIsDeprecated(true)
|
||||||
|
->setValue(pht('Deprecated alias for "%s".', $value));
|
||||||
|
}
|
||||||
|
|
||||||
return $list;
|
return $list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function getCanonicalValue(array $values) {
|
||||||
|
// Always map the current normal options to themselves.
|
||||||
|
$normal_options = array_fuse(array_keys($this->getOptions()));
|
||||||
|
|
||||||
|
// Map deprecated values to their new values.
|
||||||
|
$deprecated_options = $this->getDeprecatedOptions();
|
||||||
|
|
||||||
|
$map = $normal_options + $deprecated_options;
|
||||||
|
foreach ($values as $key => $value) {
|
||||||
|
$values[$key] = idx($map, $value, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $values;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -850,6 +850,10 @@ abstract class PhabricatorApplicationTransactionEditor
|
||||||
$xaction->setIsSilentTransaction(true);
|
$xaction->setIsSilentTransaction(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($actor->hasHighSecuritySession()) {
|
||||||
|
$xaction->setIsMFATransaction(true);
|
||||||
|
}
|
||||||
|
|
||||||
return $xaction;
|
return $xaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -83,7 +83,15 @@ final class PhabricatorApplicationTransactionResponse
|
||||||
$xactions[$key] = hsprintf('%s', $xaction);
|
$xactions[$key] = hsprintf('%s', $xaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$aural = phutil_tag(
|
||||||
|
'h3',
|
||||||
|
array(
|
||||||
|
'class' => 'aural-only',
|
||||||
|
),
|
||||||
|
pht('Comment Preview'));
|
||||||
|
|
||||||
$content = array(
|
$content = array(
|
||||||
|
'header' => hsprintf('%s', $aural),
|
||||||
'xactions' => $xactions,
|
'xactions' => $xactions,
|
||||||
'spacer' => PHUITimelineView::renderSpacer(),
|
'spacer' => PHUITimelineView::renderSpacer(),
|
||||||
'previewContent' => hsprintf('%s', $this->getPreviewContent()),
|
'previewContent' => hsprintf('%s', $this->getPreviewContent()),
|
||||||
|
|
|
@ -165,6 +165,14 @@ abstract class PhabricatorApplicationTransaction
|
||||||
return (bool)$this->getMetadataValue('core.silent', false);
|
return (bool)$this->getMetadataValue('core.silent', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setIsMFATransaction($mfa) {
|
||||||
|
return $this->setMetadataValue('core.mfa', $mfa);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getIsMFATransaction() {
|
||||||
|
return (bool)$this->getMetadataValue('core.mfa', false);
|
||||||
|
}
|
||||||
|
|
||||||
public function attachComment(
|
public function attachComment(
|
||||||
PhabricatorApplicationTransactionComment $comment) {
|
PhabricatorApplicationTransactionComment $comment) {
|
||||||
$this->comment = $comment;
|
$this->comment = $comment;
|
||||||
|
@ -1461,6 +1469,12 @@ abstract class PhabricatorApplicationTransaction
|
||||||
if ($is_silent != $xaction->getIsSilentTransaction()) {
|
if ($is_silent != $xaction->getIsSilentTransaction()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't group MFA and non-MFA transactions together.
|
||||||
|
$is_mfa = $this->getIsMFATransaction();
|
||||||
|
if ($is_mfa != $xaction->getIsMFATransaction()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -243,8 +243,16 @@ class PhabricatorApplicationTransactionCommentView extends AphrontView {
|
||||||
|
|
||||||
$comment_box = id(new PHUIObjectBoxView())
|
$comment_box = id(new PHUIObjectBoxView())
|
||||||
->setFlush(true)
|
->setFlush(true)
|
||||||
|
->setNoBorder(true)
|
||||||
->addClass('phui-comment-form-view')
|
->addClass('phui-comment-form-view')
|
||||||
->addSigil('phui-comment-form')
|
->addSigil('phui-comment-form')
|
||||||
|
->appendChild(
|
||||||
|
phutil_tag(
|
||||||
|
'h3',
|
||||||
|
array(
|
||||||
|
'class' => 'aural-only',
|
||||||
|
),
|
||||||
|
pht('Add Comment')))
|
||||||
->appendChild($image)
|
->appendChild($image)
|
||||||
->appendChild($badge_view)
|
->appendChild($badge_view)
|
||||||
->appendChild($wedge)
|
->appendChild($wedge)
|
||||||
|
|
|
@ -424,7 +424,8 @@ class PhabricatorApplicationTransactionView extends AphrontView {
|
||||||
->setIcon($xaction->getIcon())
|
->setIcon($xaction->getIcon())
|
||||||
->setColor($xaction->getColor())
|
->setColor($xaction->getColor())
|
||||||
->setHideCommentOptions($this->getHideCommentOptions())
|
->setHideCommentOptions($this->getHideCommentOptions())
|
||||||
->setIsSilent($xaction->getIsSilentTransaction());
|
->setIsSilent($xaction->getIsSilentTransaction())
|
||||||
|
->setIsMFA($xaction->getIsMFATransaction());
|
||||||
|
|
||||||
list($token, $token_removed) = $xaction->getToken();
|
list($token, $token_removed) = $xaction->getToken();
|
||||||
if ($token) {
|
if ($token) {
|
||||||
|
|
|
@ -6,5 +6,78 @@ Construct a detailed written history of your civilization.
|
||||||
Overview
|
Overview
|
||||||
========
|
========
|
||||||
|
|
||||||
Phriction is a simple wiki. You can edit pages, and the text you write will stay
|
Phriction is a wiki. You can edit pages, and the text you write will stay
|
||||||
there. Other people can see it later.
|
there. Other people can see it later.
|
||||||
|
|
||||||
|
Phriction documents are arranged in a hierarchy, like a filesystem. This can
|
||||||
|
make it easier to keep things organized and to apply policy controls to
|
||||||
|
groups of documents.
|
||||||
|
|
||||||
|
|
||||||
|
Policies
|
||||||
|
========
|
||||||
|
|
||||||
|
Documents and policies in Phriction are hierarchical, similar to a filesystem.
|
||||||
|
For example, a document called "Zebra Information" may be located
|
||||||
|
at `/zoo/animals/zebra/`.
|
||||||
|
|
||||||
|
To view a document in Phrction, you must first be able to view all of its
|
||||||
|
ancestors. So a user can only see {nav Zoo > Animals > Zebra Information} if
|
||||||
|
they can see the pages {nav Zoo} and {nav Zoo > Animals}.
|
||||||
|
|
||||||
|
This allows sections of the wiki to be restricted by applying a restrictive
|
||||||
|
policy to the parent (or grandparent) document. For example, if you apply a
|
||||||
|
restrictive view policy to the {nav Zoo} page, it will implicitly apply to
|
||||||
|
all sub-pages, including {nav Zoo > Animals > Zebra Information}.
|
||||||
|
|
||||||
|
|
||||||
|
Versions and Drafts
|
||||||
|
===================
|
||||||
|
|
||||||
|
Document content is tracked with linear version numbers: version 1, version 2,
|
||||||
|
version 3, and so on. Each time a page is edited, a new version of the page is
|
||||||
|
created.
|
||||||
|
|
||||||
|
You can {nav View History} to review older versions of a page and see how it
|
||||||
|
has changed over time (and who has changed it).
|
||||||
|
|
||||||
|
When you visit a particular document, you are normally shown the most recent
|
||||||
|
version of that document. For example, if there are 17 versions, you'll see
|
||||||
|
version 17.
|
||||||
|
|
||||||
|
Likewise, when you edit a document using {nav Edit Document > Save and Publish},
|
||||||
|
your changes are published immediately. If there were previously 17 versions,
|
||||||
|
your new changes will become version 18 and visitors to the document will begin
|
||||||
|
seeing version 18.
|
||||||
|
|
||||||
|
If you want to edit a document without publishing the changes right away, you
|
||||||
|
can use {nav Edit Document > Save as Draft} instead. This will still create a
|
||||||
|
new version 18, but it won't change which version users see when they visit the
|
||||||
|
document: they'll still see version 17 (the last published version).
|
||||||
|
|
||||||
|
You (and other users) can continue editing the draft by using
|
||||||
|
{nav Edit Document}. (Once a document has an unpublished draft, editing will
|
||||||
|
stay in draft mode.)
|
||||||
|
|
||||||
|
Once you're satisfied with your changes, use {nav Publish Draft} to make your
|
||||||
|
changes the current visible version of the document that users see by default
|
||||||
|
when they visit it.
|
||||||
|
|
||||||
|
If you made a mistake and published something you didn't intend to, you can
|
||||||
|
navigate back to an older version of the document and use
|
||||||
|
{nav Publish Older Version} to change the current visible version of the
|
||||||
|
document to some older version.
|
||||||
|
|
||||||
|
Note that draft versions are still normal versions of the document: they are
|
||||||
|
not private, they can not be deleted, other users can see them if they can see
|
||||||
|
the document, and they will eventually become a standard part of the document
|
||||||
|
history. The only private parts of drafts are: editing a draft does not
|
||||||
|
generate a feed story; and users won't see draft content by default when
|
||||||
|
viewing a document.
|
||||||
|
|
||||||
|
Drafts may be a good fit if you are:
|
||||||
|
|
||||||
|
- working on changes over time; or
|
||||||
|
- starting with a rough change and refining it in several iterations; or
|
||||||
|
- collaborating with others on a change; or
|
||||||
|
- sharing changes before they're published to get feedback.
|
||||||
|
|
|
@ -233,14 +233,15 @@ final class PHUIButtonView extends AphrontTagView {
|
||||||
$classes = array();
|
$classes = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
// See PHI823. If we aren't rendering a "<button>" tag, give the tag we
|
// See PHI823. If we aren't rendering a "<button>" or "<input>" tag,
|
||||||
// are rendering a "button" role as a hint to screen readers.
|
// give the tag we are rendering a "button" role as a hint to screen
|
||||||
|
// readers.
|
||||||
$role = null;
|
$role = null;
|
||||||
if ($this->tag !== 'button') {
|
if ($this->tag !== 'button' && $this->tag !== 'input') {
|
||||||
$role = 'button';
|
$role = 'button';
|
||||||
}
|
}
|
||||||
|
|
||||||
return array(
|
$attrs = array(
|
||||||
'class' => $classes,
|
'class' => $classes,
|
||||||
'href' => $this->href,
|
'href' => $this->href,
|
||||||
'name' => $this->name,
|
'name' => $this->name,
|
||||||
|
@ -249,9 +250,19 @@ final class PHUIButtonView extends AphrontTagView {
|
||||||
'meta' => $meta,
|
'meta' => $meta,
|
||||||
'role' => $role,
|
'role' => $role,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if ($this->tag == 'input') {
|
||||||
|
$attrs['type'] = 'submit';
|
||||||
|
$attrs['value'] = $this->text;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $attrs;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getTagContent() {
|
protected function getTagContent() {
|
||||||
|
if ($this->tag === 'input') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
$icon = $this->icon;
|
$icon = $this->icon;
|
||||||
$text = null;
|
$text = null;
|
||||||
|
|
|
@ -25,6 +25,7 @@ final class PHUIObjectBoxView extends AphrontTagView {
|
||||||
private $showHideHref;
|
private $showHideHref;
|
||||||
private $showHideContent;
|
private $showHideContent;
|
||||||
private $showHideOpen;
|
private $showHideOpen;
|
||||||
|
private $noBorder;
|
||||||
|
|
||||||
private $propertyLists = array();
|
private $propertyLists = array();
|
||||||
|
|
||||||
|
@ -147,6 +148,11 @@ final class PHUIObjectBoxView extends AphrontTagView {
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setNoBorder($no_border) {
|
||||||
|
$this->noBorder = $no_border;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function setValidationException(
|
public function setValidationException(
|
||||||
PhabricatorApplicationTransactionValidationException $ex = null) {
|
PhabricatorApplicationTransactionValidationException $ex = null) {
|
||||||
$this->validationException = $ex;
|
$this->validationException = $ex;
|
||||||
|
@ -156,7 +162,9 @@ final class PHUIObjectBoxView extends AphrontTagView {
|
||||||
protected function getTagAttributes() {
|
protected function getTagAttributes() {
|
||||||
$classes = array();
|
$classes = array();
|
||||||
$classes[] = 'phui-box';
|
$classes[] = 'phui-box';
|
||||||
$classes[] = 'phui-box-border';
|
if (!$this->noBorder) {
|
||||||
|
$classes[] = 'phui-box-border';
|
||||||
|
}
|
||||||
$classes[] = 'phui-object-box';
|
$classes[] = 'phui-object-box';
|
||||||
$classes[] = 'mlt mll mlr';
|
$classes[] = 'mlt mll mlr';
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ final class PHUITimelineEventView extends AphrontView {
|
||||||
private $badges = array();
|
private $badges = array();
|
||||||
private $pinboardItems = array();
|
private $pinboardItems = array();
|
||||||
private $isSilent;
|
private $isSilent;
|
||||||
|
private $isMFA;
|
||||||
|
|
||||||
public function setAuthorPHID($author_phid) {
|
public function setAuthorPHID($author_phid) {
|
||||||
$this->authorPHID = $author_phid;
|
$this->authorPHID = $author_phid;
|
||||||
|
@ -187,6 +188,15 @@ final class PHUITimelineEventView extends AphrontView {
|
||||||
return $this->isSilent;
|
return $this->isSilent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setIsMFA($is_mfa) {
|
||||||
|
$this->isMFA = $is_mfa;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getIsMFA() {
|
||||||
|
return $this->isMFA;
|
||||||
|
}
|
||||||
|
|
||||||
public function setReallyMajorEvent($me) {
|
public function setReallyMajorEvent($me) {
|
||||||
$this->reallyMajorEvent = $me;
|
$this->reallyMajorEvent = $me;
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -590,6 +600,14 @@ final class PHUITimelineEventView extends AphrontView {
|
||||||
->setIcon('fa-bell-slash', 'red')
|
->setIcon('fa-bell-slash', 'red')
|
||||||
->setTooltip(pht('Silent Edit'));
|
->setTooltip(pht('Silent Edit'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If this edit was applied while the actor was in high-security mode,
|
||||||
|
// provide a hint that it was extra authentic.
|
||||||
|
if ($this->getIsMFA()) {
|
||||||
|
$extra[] = id(new PHUIIconView())
|
||||||
|
->setIcon('fa-vcard', 'green')
|
||||||
|
->setTooltip(pht('MFA Authenticated'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$extra = javelin_tag(
|
$extra = javelin_tag(
|
||||||
|
|
|
@ -83,7 +83,15 @@ final class PHUITimelineView extends AphrontView {
|
||||||
'class' => 'phui-timeline-view',
|
'class' => 'phui-timeline-view',
|
||||||
'id' => $this->id,
|
'id' => $this->id,
|
||||||
),
|
),
|
||||||
$events);
|
array(
|
||||||
|
phutil_tag(
|
||||||
|
'h3',
|
||||||
|
array(
|
||||||
|
'class' => 'aural-only',
|
||||||
|
),
|
||||||
|
pht('Event Timeline')),
|
||||||
|
$events,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function buildEvents() {
|
public function buildEvents() {
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
|
|
||||||
|
|
||||||
button,
|
button,
|
||||||
a.button {
|
a.button,
|
||||||
|
input[type="submit"] {
|
||||||
font: {$basefont};
|
font: {$basefont};
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
|
@ -72,7 +73,8 @@ a.icon:visited {
|
||||||
|
|
||||||
button.button-green,
|
button.button-green,
|
||||||
a.button-green.button,
|
a.button-green.button,
|
||||||
a.button-green.button:visited {
|
a.button-green.button:visited,
|
||||||
|
input[type="submit"].button-green {
|
||||||
background-color: {$green.button.color};
|
background-color: {$green.button.color};
|
||||||
border-color: {$green.button.color};
|
border-color: {$green.button.color};
|
||||||
background-image: {$green.button.gradient};
|
background-image: {$green.button.gradient};
|
||||||
|
@ -80,16 +82,17 @@ a.button-green.button:visited {
|
||||||
|
|
||||||
button.button-red,
|
button.button-red,
|
||||||
a.button-red.button,
|
a.button-red.button,
|
||||||
a.button-red.button:visited {
|
a.button-red.button:visited,
|
||||||
|
input[type="submit"].button-red {
|
||||||
background-color: {$red.button.color};
|
background-color: {$red.button.color};
|
||||||
border-color: {$red.button.color};
|
border-color: {$red.button.color};
|
||||||
background-image: {$red.button.gradient};
|
background-image: {$red.button.gradient};
|
||||||
}
|
}
|
||||||
|
|
||||||
button.button-grey,
|
button.button-grey,
|
||||||
input[type="submit"].button-grey,
|
|
||||||
a.button-grey,
|
a.button-grey,
|
||||||
a.button-grey:visited {
|
a.button-grey:visited,
|
||||||
|
input[type="submit"].button-grey {
|
||||||
background-color: {$grey.button.color};
|
background-color: {$grey.button.color};
|
||||||
background-image: {$grey.button.gradient};
|
background-image: {$grey.button.gradient};
|
||||||
border: 1px solid rgba({$alphablue}, 0.3);
|
border: 1px solid rgba({$alphablue}, 0.3);
|
||||||
|
|
|
@ -241,10 +241,13 @@ body.printable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.phui-document-view-pro-box {
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
.phui-document-view-pro-box .phui-timeline-view {
|
.phui-document-view-pro-box .phui-timeline-view {
|
||||||
padding: 16px 0 0 0;
|
padding: 16px 0 0 0;
|
||||||
background: none;
|
background: none;
|
||||||
border-top: 1px solid rgba({$alphablue}, 0.20);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.phui-document-view-pro-box .phui-timeline-wedge {
|
.phui-document-view-pro-box .phui-timeline-wedge {
|
||||||
|
|
|
@ -133,19 +133,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.aphront-form-control-submit button,
|
.aphront-form-control-submit button,
|
||||||
.aphront-form-control-submit a.button {
|
.aphront-form-control-submit a.button,
|
||||||
|
.aphront-form-control-submit input[type="submit"] {
|
||||||
float: right;
|
float: right;
|
||||||
margin: 4px 0 0 8px;
|
margin: 4px 0 0 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.phui-form-control-multi-submit input,
|
|
||||||
.phui-form-control-multi-submit button,
|
|
||||||
.phui-form-control-multi-submit a {
|
|
||||||
float: right;
|
|
||||||
margin: 4px 0 0 8px;
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.aphront-form-control-textarea textarea.aphront-textarea-very-short {
|
.aphront-form-control-textarea textarea.aphront-textarea-very-short {
|
||||||
height: 44px;
|
height: 44px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,6 +105,7 @@ JX.behavior('comment-actions', function(config) {
|
||||||
JX.DOM.setContent(
|
JX.DOM.setContent(
|
||||||
preview_root,
|
preview_root,
|
||||||
[
|
[
|
||||||
|
JX.$H(response.header),
|
||||||
JX.$H(response.xactions.join('')),
|
JX.$H(response.xactions.join('')),
|
||||||
JX.$H(response.previewContent)
|
JX.$H(response.previewContent)
|
||||||
]);
|
]);
|
||||||
|
|
Loading…
Reference in a new issue