mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-26 00:32:42 +01:00
Add controllers/search/edit engine functionality to RepositoryIdentity
Summary: Depends on D19423. Ref T12164. Adds controllers capable of listing and editing `PhabricatorRepositoryIdentity` objects. Starts creating those objects when commits are parsed. Test Plan: Reparsed some revisions, observed objects getting created in the database. Altered some `Identity` objects using the controllers and observed effects in the database. No attempts made to validate behavior under "challenging" author/committer strings. Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin, PHID-OPKG-gm6ozazyms6q6i22gyam Maniphest Tasks: T12164 Differential Revision: https://secure.phabricator.com/D19429
This commit is contained in:
parent
cd84e53c44
commit
f191a66490
18 changed files with 674 additions and 6 deletions
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE {$NAMESPACE}_repository.repository_identity
|
||||
ADD COLUMN authorPHID VARBINARY(64) NOT NULL;
|
19
resources/sql/autopatches/20180504.repo_identity.xaction.sql
Normal file
19
resources/sql/autopatches/20180504.repo_identity.xaction.sql
Normal file
|
@ -0,0 +1,19 @@
|
|||
CREATE TABLE {$NAMESPACE}_repository.repository_identitytransaction (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
phid VARBINARY(64) NOT NULL,
|
||||
authorPHID VARBINARY(64) NOT NULL,
|
||||
objectPHID VARBINARY(64) NOT NULL,
|
||||
viewPolicy VARBINARY(64) NOT NULL,
|
||||
editPolicy VARBINARY(64) NOT NULL,
|
||||
commentPHID VARBINARY(64) DEFAULT NULL,
|
||||
commentVersion INT UNSIGNED NOT NULL,
|
||||
transactionType VARCHAR(32) NOT NULL,
|
||||
oldValue LONGTEXT NOT NULL,
|
||||
newValue LONGTEXT NOT NULL,
|
||||
contentSource LONGTEXT NOT NULL,
|
||||
metadata LONGTEXT NOT NULL,
|
||||
dateCreated INT UNSIGNED NOT NULL,
|
||||
dateModified INT UNSIGNED NOT NULL,
|
||||
UNIQUE KEY `key_phid` (`phid`),
|
||||
KEY `key_object` (`objectPHID`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET={$CHARSET} COLLATE {$COLLATE_TEXT};
|
|
@ -815,6 +815,9 @@ phutil_register_library_map(array(
|
|||
'DiffusionHistoryTableView' => 'applications/diffusion/view/DiffusionHistoryTableView.php',
|
||||
'DiffusionHistoryView' => 'applications/diffusion/view/DiffusionHistoryView.php',
|
||||
'DiffusionHovercardEngineExtension' => 'applications/diffusion/engineextension/DiffusionHovercardEngineExtension.php',
|
||||
'DiffusionIdentityEditController' => 'applications/diffusion/controller/DiffusionIdentityEditController.php',
|
||||
'DiffusionIdentityListController' => 'applications/diffusion/controller/DiffusionIdentityListController.php',
|
||||
'DiffusionIdentityViewController' => 'applications/diffusion/controller/DiffusionIdentityViewController.php',
|
||||
'DiffusionInlineCommentController' => 'applications/diffusion/controller/DiffusionInlineCommentController.php',
|
||||
'DiffusionInlineCommentPreviewController' => 'applications/diffusion/controller/DiffusionInlineCommentPreviewController.php',
|
||||
'DiffusionInternalAncestorsConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionInternalAncestorsConduitAPIMethod.php',
|
||||
|
@ -937,6 +940,8 @@ phutil_register_library_map(array(
|
|||
'DiffusionRepositoryEditUpdateController' => 'applications/diffusion/controller/DiffusionRepositoryEditUpdateController.php',
|
||||
'DiffusionRepositoryFunctionDatasource' => 'applications/diffusion/typeahead/DiffusionRepositoryFunctionDatasource.php',
|
||||
'DiffusionRepositoryHistoryManagementPanel' => 'applications/diffusion/management/DiffusionRepositoryHistoryManagementPanel.php',
|
||||
'DiffusionRepositoryIdentityEditor' => 'applications/diffusion/editor/DiffusionRepositoryIdentityEditor.php',
|
||||
'DiffusionRepositoryIdentitySearchEngine' => 'applications/diffusion/query/DiffusionRepositoryIdentitySearchEngine.php',
|
||||
'DiffusionRepositoryListController' => 'applications/diffusion/controller/DiffusionRepositoryListController.php',
|
||||
'DiffusionRepositoryManageController' => 'applications/diffusion/controller/DiffusionRepositoryManageController.php',
|
||||
'DiffusionRepositoryManagePanelsController' => 'applications/diffusion/controller/DiffusionRepositoryManagePanelsController.php',
|
||||
|
@ -4086,8 +4091,14 @@ phutil_register_library_map(array(
|
|||
'PhabricatorRepositoryGraphCache' => 'applications/repository/graphcache/PhabricatorRepositoryGraphCache.php',
|
||||
'PhabricatorRepositoryGraphStream' => 'applications/repository/daemon/PhabricatorRepositoryGraphStream.php',
|
||||
'PhabricatorRepositoryIdentity' => 'applications/repository/storage/PhabricatorRepositoryIdentity.php',
|
||||
'PhabricatorRepositoryIdentityAssignTransaction' => 'applications/repository/xaction/PhabricatorRepositoryIdentityAssignTransaction.php',
|
||||
'PhabricatorRepositoryIdentityEditEngine' => 'applications/repository/engine/PhabricatorRepositoryIdentityEditEngine.php',
|
||||
'PhabricatorRepositoryIdentityFerretEngine' => 'applications/repository/search/PhabricatorRepositoryIdentityFerretEngine.php',
|
||||
'PhabricatorRepositoryIdentityPHIDType' => 'applications/repository/phid/PhabricatorRepositoryIdentityPHIDType.php',
|
||||
'PhabricatorRepositoryIdentityQuery' => 'applications/repository/query/PhabricatorRepositoryIdentityQuery.php',
|
||||
'PhabricatorRepositoryIdentityTransaction' => 'applications/repository/storage/PhabricatorRepositoryIdentityTransaction.php',
|
||||
'PhabricatorRepositoryIdentityTransactionQuery' => 'applications/repository/query/PhabricatorRepositoryIdentityTransactionQuery.php',
|
||||
'PhabricatorRepositoryIdentityTransactionType' => 'applications/repository/xaction/PhabricatorRepositoryIdentityTransactionType.php',
|
||||
'PhabricatorRepositoryManagementCacheWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementCacheWorkflow.php',
|
||||
'PhabricatorRepositoryManagementClusterizeWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementClusterizeWorkflow.php',
|
||||
'PhabricatorRepositoryManagementDiscoverWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementDiscoverWorkflow.php',
|
||||
|
@ -6155,6 +6166,9 @@ phutil_register_library_map(array(
|
|||
'DiffusionHistoryTableView' => 'DiffusionHistoryView',
|
||||
'DiffusionHistoryView' => 'DiffusionView',
|
||||
'DiffusionHovercardEngineExtension' => 'PhabricatorHovercardEngineExtension',
|
||||
'DiffusionIdentityEditController' => 'DiffusionController',
|
||||
'DiffusionIdentityListController' => 'DiffusionController',
|
||||
'DiffusionIdentityViewController' => 'DiffusionController',
|
||||
'DiffusionInlineCommentController' => 'PhabricatorInlineCommentController',
|
||||
'DiffusionInlineCommentPreviewController' => 'PhabricatorInlineCommentPreviewController',
|
||||
'DiffusionInternalAncestorsConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
|
||||
|
@ -6276,6 +6290,8 @@ phutil_register_library_map(array(
|
|||
'DiffusionRepositoryEditUpdateController' => 'DiffusionRepositoryManageController',
|
||||
'DiffusionRepositoryFunctionDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
|
||||
'DiffusionRepositoryHistoryManagementPanel' => 'DiffusionRepositoryManagementPanel',
|
||||
'DiffusionRepositoryIdentityEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'DiffusionRepositoryIdentitySearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'DiffusionRepositoryListController' => 'DiffusionController',
|
||||
'DiffusionRepositoryManageController' => 'DiffusionController',
|
||||
'DiffusionRepositoryManagePanelsController' => 'DiffusionRepositoryManageController',
|
||||
|
@ -9978,9 +9994,19 @@ phutil_register_library_map(array(
|
|||
'PhabricatorRepositoryGitLFSRefQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhabricatorRepositoryGraphCache' => 'Phobject',
|
||||
'PhabricatorRepositoryGraphStream' => 'Phobject',
|
||||
'PhabricatorRepositoryIdentity' => 'PhabricatorRepositoryDAO',
|
||||
'PhabricatorRepositoryIdentity' => array(
|
||||
'PhabricatorRepositoryDAO',
|
||||
'PhabricatorPolicyInterface',
|
||||
'PhabricatorApplicationTransactionInterface',
|
||||
),
|
||||
'PhabricatorRepositoryIdentityAssignTransaction' => 'PhabricatorRepositoryIdentityTransactionType',
|
||||
'PhabricatorRepositoryIdentityEditEngine' => 'PhabricatorEditEngine',
|
||||
'PhabricatorRepositoryIdentityFerretEngine' => 'PhabricatorFerretEngine',
|
||||
'PhabricatorRepositoryIdentityPHIDType' => 'PhabricatorPHIDType',
|
||||
'PhabricatorRepositoryIdentityQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhabricatorRepositoryIdentityTransaction' => 'PhabricatorModularTransaction',
|
||||
'PhabricatorRepositoryIdentityTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
'PhabricatorRepositoryIdentityTransactionType' => 'PhabricatorModularTransactionType',
|
||||
'PhabricatorRepositoryManagementCacheWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||
'PhabricatorRepositoryManagementClusterizeWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||
'PhabricatorRepositoryManagementDiscoverWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||
|
|
|
@ -124,6 +124,15 @@ final class PhabricatorDiffusionApplication extends PhabricatorApplication {
|
|||
'(?P<repositoryCallsign>[A-Z]+)' => $repository_routes,
|
||||
'(?P<repositoryID>[1-9]\d*)' => $repository_routes,
|
||||
|
||||
'identity/' => array(
|
||||
$this->getQueryRoutePattern() =>
|
||||
'DiffusionIdentityListController',
|
||||
$this->getEditRoutePattern('edit/') =>
|
||||
'DiffusionIdentityEditController',
|
||||
'view/(?P<id>[^/]+)/' =>
|
||||
'DiffusionIdentityViewController',
|
||||
),
|
||||
|
||||
'inline/' => array(
|
||||
'edit/(?P<phid>[^/]+)/' => 'DiffusionInlineCommentController',
|
||||
'preview/(?P<phid>[^/]+)/'
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
final class DiffusionIdentityEditController
|
||||
extends DiffusionController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
return id(new PhabricatorRepositoryIdentityEditEngine())
|
||||
->setController($this)
|
||||
->buildResponse();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
final class DiffusionIdentityListController
|
||||
extends DiffusionController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
return id(new DiffusionRepositoryIdentitySearchEngine())
|
||||
->setController($this)
|
||||
->buildResponse();
|
||||
}
|
||||
|
||||
protected function buildApplicationCrumbs() {
|
||||
$crumbs = parent::buildApplicationCrumbs();
|
||||
|
||||
id(new PhabricatorRepositoryIdentityEditEngine())
|
||||
->setViewer($this->getViewer())
|
||||
->addActionToCrumbs($crumbs);
|
||||
|
||||
return $crumbs;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
<?php
|
||||
|
||||
final class DiffusionIdentityViewController
|
||||
extends DiffusionController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
|
||||
$id = $request->getURIData('id');
|
||||
$identity = id(new PhabricatorRepositoryIdentityQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->executeOne();
|
||||
if (!$identity) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$title = pht('Identity %d', $identity->getID());
|
||||
|
||||
$curtain = $this->buildCurtain($identity);
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setUser($viewer)
|
||||
->setHeader($identity->getIdentityShortName())
|
||||
->setHeaderIcon('fa-globe')
|
||||
->setPolicyObject($identity);
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb($identity->getID());
|
||||
$crumbs->setBorder(true);
|
||||
|
||||
$timeline = $this->buildTransactionTimeline(
|
||||
$identity,
|
||||
new PhabricatorRepositoryIdentityTransactionQuery());
|
||||
$timeline->setShouldTerminate(true);
|
||||
|
||||
$properties = $this->buildPropertyList($identity);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setCurtain($curtain)
|
||||
->setMainColumn(array(
|
||||
$properties,
|
||||
$timeline,
|
||||
));
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->appendChild(
|
||||
array(
|
||||
$view,
|
||||
));
|
||||
}
|
||||
|
||||
private function buildCurtain(PhabricatorRepositoryIdentity $identity) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$identity,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$id = $identity->getID();
|
||||
$edit_uri = $this->getApplicationURI("identity/edit/{$id}/");
|
||||
|
||||
$curtain = $this->newCurtainView($identity);
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('fa-pencil')
|
||||
->setName(pht('Edit Identity'))
|
||||
->setHref($edit_uri)
|
||||
->setWorkflow(!$can_edit)
|
||||
->setDisabled(!$can_edit));
|
||||
|
||||
return $curtain;
|
||||
}
|
||||
|
||||
private function buildPropertyList(
|
||||
PhabricatorRepositoryIdentity $identity) {
|
||||
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$properties = id(new PHUIPropertyListView())
|
||||
->setUser($viewer);
|
||||
|
||||
$effective_phid = $identity->getCurrentEffectiveUserPHID();
|
||||
$automatic_phid = $identity->getAutomaticGuessedUserPHID();
|
||||
$manual_phid = $identity->getManuallySetUserPHID();
|
||||
|
||||
if ($effective_phid) {
|
||||
$tag = id(new PHUITagView())
|
||||
->setType(PHUITagView::TYPE_SHADE)
|
||||
->setColor('green')
|
||||
->setIcon('fa-check')
|
||||
->setName('Assigned');
|
||||
} else {
|
||||
$tag = id(new PHUITagView())
|
||||
->setType(PHUITagView::TYPE_SHADE)
|
||||
->setColor('indigo')
|
||||
->setIcon('fa-bomb')
|
||||
->setName('Unassigned');
|
||||
}
|
||||
$properties->addProperty(
|
||||
pht('Effective User'),
|
||||
$viewer->renderHandle($effective_phid));
|
||||
$properties->addProperty(
|
||||
pht('Automatically Detected User'),
|
||||
$viewer->renderHandle($automatic_phid));
|
||||
$properties->addProperty(
|
||||
pht('Manually Set User'),
|
||||
$viewer->renderHandle($manual_phid));
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(array(pht('Identity Assignments'), $tag));
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeader($header)
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->addPropertyList($properties);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
final class DiffusionRepositoryIdentityEditor
|
||||
extends PhabricatorApplicationTransactionEditor {
|
||||
|
||||
public function getEditorObjectsDescription() {
|
||||
return pht('Repository Identity');
|
||||
}
|
||||
|
||||
public function getCreateObjectTitle($author, $object) {
|
||||
return pht('%s created this identity.', $author);
|
||||
}
|
||||
|
||||
public function getCreateObjectTitleForFeed($author, $object) {
|
||||
return pht('%s created %s.', $author, $object);
|
||||
}
|
||||
|
||||
protected function supportsSearch() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getEditorApplicationClass() {
|
||||
return 'PhabricatorDiffusionApplication';
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
<?php
|
||||
|
||||
final class DiffusionRepositoryIdentitySearchEngine
|
||||
extends PhabricatorApplicationSearchEngine {
|
||||
|
||||
public function getResultTypeDescription() {
|
||||
return pht('Repository Identities');
|
||||
}
|
||||
|
||||
public function getApplicationClassName() {
|
||||
return 'PhabricatorDiffusionApplication';
|
||||
}
|
||||
|
||||
public function newQuery() {
|
||||
return new PhabricatorRepositoryIdentityQuery();
|
||||
}
|
||||
|
||||
protected function buildCustomSearchFields() {
|
||||
return array(
|
||||
id(new PhabricatorSearchThreeStateField())
|
||||
->setLabel(pht('Is Assigned'))
|
||||
->setKey('hasEffectivePHID')
|
||||
->setOptions(
|
||||
pht('(Show All)'),
|
||||
pht('Show Only Assigned Identities'),
|
||||
pht('Show Only Unassigned Identities')),
|
||||
);
|
||||
}
|
||||
|
||||
protected function buildQueryFromParameters(array $map) {
|
||||
$query = $this->newQuery();
|
||||
|
||||
if ($map['hasEffectivePHID'] !== null) {
|
||||
$query->withHasEffectivePHID($map['hasEffectivePHID']);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
protected function getURI($path) {
|
||||
return '/diffusion/identity/'.$path;
|
||||
}
|
||||
|
||||
protected function getBuiltinQueryNames() {
|
||||
$names = array(
|
||||
'all' => pht('All Identities'),
|
||||
);
|
||||
|
||||
return $names;
|
||||
}
|
||||
|
||||
public function buildSavedQueryFromBuiltin($query_key) {
|
||||
|
||||
$query = $this->newSavedQuery();
|
||||
$query->setQueryKey($query_key);
|
||||
|
||||
switch ($query_key) {
|
||||
case 'all':
|
||||
return $query;
|
||||
}
|
||||
|
||||
return parent::buildSavedQueryFromBuiltin($query_key);
|
||||
}
|
||||
|
||||
protected function renderResultList(
|
||||
array $identities,
|
||||
PhabricatorSavedQuery $query,
|
||||
array $handles) {
|
||||
assert_instances_of($identities, 'PhabricatorRepositoryIdentity');
|
||||
|
||||
$viewer = $this->requireViewer();
|
||||
|
||||
$list = new PHUIObjectItemListView();
|
||||
$list->setUser($viewer);
|
||||
foreach ($identities as $identity) {
|
||||
$item = id(new PHUIObjectItemView())
|
||||
->setObjectName(pht('Identity %d', $identity->getID()))
|
||||
->setHeader($identity->getIdentityShortName())
|
||||
->setHref($identity->getURI())
|
||||
->setObject($identity);
|
||||
|
||||
$list->addItem($item);
|
||||
}
|
||||
|
||||
$result = new PhabricatorApplicationSearchResultView();
|
||||
$result->setObjectList($list);
|
||||
$result->setNoDataString(pht('No Identities found.'));
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorRepositoryIdentityEditEngine
|
||||
extends PhabricatorEditEngine {
|
||||
|
||||
const ENGINECONST = 'repository.identity';
|
||||
|
||||
public function isEngineConfigurable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getEngineName() {
|
||||
return pht('Repository Identities');
|
||||
}
|
||||
|
||||
public function getSummaryHeader() {
|
||||
return pht('Edit Repository Identity Configurations');
|
||||
}
|
||||
|
||||
public function getSummaryText() {
|
||||
return pht('This engine is used to edit Repository identities.');
|
||||
}
|
||||
|
||||
public function getEngineApplicationClass() {
|
||||
return 'PhabricatorDiffusionApplication';
|
||||
}
|
||||
|
||||
protected function newEditableObject() {
|
||||
return new PhabricatorRepositoryIdentity();
|
||||
}
|
||||
|
||||
protected function newObjectQuery() {
|
||||
return new PhabricatorRepositoryIdentityQuery();
|
||||
}
|
||||
|
||||
protected function getObjectCreateTitleText($object) {
|
||||
return pht('Create Identity');
|
||||
}
|
||||
|
||||
protected function getObjectCreateButtonText($object) {
|
||||
return pht('Create Identity');
|
||||
}
|
||||
|
||||
protected function getObjectEditTitleText($object) {
|
||||
return pht('Edit Identity: %s', $object->getIdentityShortName());
|
||||
}
|
||||
|
||||
protected function getObjectEditShortText($object) {
|
||||
return pht('Edit Identity');
|
||||
}
|
||||
|
||||
protected function getObjectCreateShortText() {
|
||||
return pht('Create Identity');
|
||||
}
|
||||
|
||||
protected function getObjectName() {
|
||||
return pht('Identity');
|
||||
}
|
||||
|
||||
protected function getEditorURI() {
|
||||
return '/diffusion/identity/edit/';
|
||||
}
|
||||
|
||||
protected function getObjectCreateCancelURI($object) {
|
||||
return '/diffusion/identity/';
|
||||
}
|
||||
|
||||
protected function getObjectViewURI($object) {
|
||||
return $object->getURI();
|
||||
}
|
||||
|
||||
protected function getCreateNewObjectPolicy() {
|
||||
return PhabricatorPolicies::POLICY_USER;
|
||||
}
|
||||
|
||||
protected function buildCustomEditFields($object) {
|
||||
return array(
|
||||
id(new PhabricatorUsersEditField())
|
||||
->setKey('manuallySetUserPHID')
|
||||
->setLabel(pht('Assigned To'))
|
||||
->setDescription(pht('Override this identity\'s assignment.'))
|
||||
->setTransactionType(
|
||||
PhabricatorRepositoryIdentityAssignTransaction::TRANSACTIONTYPE)
|
||||
->setIsCopyable(true)
|
||||
->setIsNullable(true)
|
||||
->setSingleValue($object->getManuallySetUserPHID()),
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -6,6 +6,7 @@ final class PhabricatorRepositoryIdentityQuery
|
|||
private $ids;
|
||||
private $phids;
|
||||
private $identityNames;
|
||||
private $hasEffectivePHID;
|
||||
|
||||
public function withIDs(array $ids) {
|
||||
$this->ids = $ids;
|
||||
|
@ -22,10 +23,19 @@ final class PhabricatorRepositoryIdentityQuery
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function withHasEffectivePHID($has_effective_phid) {
|
||||
$this->hasEffectivePHID = $has_effective_phid;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function newResultObject() {
|
||||
return new PhabricatorRepositoryIdentity();
|
||||
}
|
||||
|
||||
protected function getPrimaryTableAlias() {
|
||||
return 'repository_identity';
|
||||
}
|
||||
|
||||
protected function loadPage() {
|
||||
return $this->loadStandardPage($this->newResultObject());
|
||||
}
|
||||
|
@ -36,17 +46,30 @@ final class PhabricatorRepositoryIdentityQuery
|
|||
if ($this->ids !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'id IN (%Ld)',
|
||||
'repository_identity.id IN (%Ld)',
|
||||
$this->ids);
|
||||
}
|
||||
|
||||
if ($this->phids !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'phid IN (%Ls)',
|
||||
'repository_identity.phid IN (%Ls)',
|
||||
$this->phids);
|
||||
}
|
||||
|
||||
if ($this->hasEffectivePHID !== null) {
|
||||
|
||||
if ($this->hasEffectivePHID) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'repository_identity.currentEffectiveUserPHID IS NOT NULL');
|
||||
} else {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'repository_identity.currentEffectiveUserPHID IS NULL');
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->identityNames !== null) {
|
||||
$name_hashes = array();
|
||||
foreach ($this->identityNames as $name) {
|
||||
|
@ -55,7 +78,7 @@ final class PhabricatorRepositoryIdentityQuery
|
|||
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'identityNameHash IN (%Ls)',
|
||||
'repository_identity.identityNameHash IN (%Ls)',
|
||||
$name_hashes);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorRepositoryIdentityTransactionQuery
|
||||
extends PhabricatorApplicationTransactionQuery {
|
||||
|
||||
public function getTemplateApplicationTransaction() {
|
||||
return new PhabricatorRepositoryIdentityTransaction();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorRepositoryIdentityFerretEngine
|
||||
extends PhabricatorFerretEngine {
|
||||
|
||||
public function getApplicationName() {
|
||||
return 'repository';
|
||||
}
|
||||
|
||||
public function getScopeName() {
|
||||
return 'identity';
|
||||
}
|
||||
|
||||
public function newSearchEngine() {
|
||||
return new DiffusionRepositoryIdentitySearchEngine();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,12 +1,15 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorRepositoryIdentity
|
||||
extends PhabricatorRepositoryDAO {
|
||||
extends PhabricatorRepositoryDAO
|
||||
implements
|
||||
PhabricatorPolicyInterface,
|
||||
PhabricatorApplicationTransactionInterface {
|
||||
|
||||
protected $authorPHID;
|
||||
protected $identityNameHash;
|
||||
protected $identityNameRaw;
|
||||
protected $identityNameEncoding;
|
||||
|
||||
protected $automaticGuessedUserPHID;
|
||||
protected $manuallySetUserPHID;
|
||||
protected $currentEffectiveUserPHID;
|
||||
|
@ -37,4 +40,79 @@ final class PhabricatorRepositoryIdentity
|
|||
return PhabricatorRepositoryIdentityPHIDType::TYPECONST;
|
||||
}
|
||||
|
||||
public function setIdentityName($name_raw) {
|
||||
$this->setIdentityNameRaw($name_raw);
|
||||
$this->setIdentityNameHash(PhabricatorHash::digestForIndex($name_raw));
|
||||
$this->setIdentityNameEncoding($this->detectEncodingForStorage($name_raw));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getIdentityName() {
|
||||
return $this->getUTF8StringFromStorage(
|
||||
$this->getIdentityNameRaw(),
|
||||
$this->getIdentityNameEncoding());
|
||||
}
|
||||
|
||||
public function getIdentityShortName() {
|
||||
// TODO
|
||||
return $this->getIdentityName();
|
||||
}
|
||||
|
||||
public function getURI() {
|
||||
return '/diffusion/identity/view/'.$this->getID().'/';
|
||||
}
|
||||
|
||||
public function save() {
|
||||
if ($this->manuallySetUserPHID) {
|
||||
$this->currentEffectiveUserPHID = $this->manuallySetUserPHID;
|
||||
} else {
|
||||
$this->currentEffectiveUserPHID = $this->automaticGuessedUserPHID;
|
||||
}
|
||||
|
||||
return parent::save();
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
||||
|
||||
|
||||
public function getCapabilities() {
|
||||
return array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
);
|
||||
}
|
||||
|
||||
public function getPolicy($capability) {
|
||||
return PhabricatorPolicies::getMostOpenPolicy();
|
||||
}
|
||||
|
||||
public function hasAutomaticCapability(
|
||||
$capability, PhabricatorUser $viewer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorApplicationTransactionInterface )------------------------- */
|
||||
|
||||
|
||||
public function getApplicationTransactionEditor() {
|
||||
return new DiffusionRepositoryIdentityEditor();
|
||||
}
|
||||
|
||||
public function getApplicationTransactionObject() {
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getApplicationTransactionTemplate() {
|
||||
return new PhabricatorRepositoryIdentityTransaction();
|
||||
}
|
||||
|
||||
public function willRenderTimeline(
|
||||
PhabricatorApplicationTransactionView $timeline,
|
||||
AphrontRequest $request) {
|
||||
|
||||
return $timeline;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorRepositoryIdentityTransaction
|
||||
extends PhabricatorModularTransaction {
|
||||
|
||||
public function getApplicationTransactionType() {
|
||||
return PhabricatorRepositoryIdentityPHIDType::TYPECONST;
|
||||
}
|
||||
|
||||
public function getBaseTransactionClass() {
|
||||
return 'PhabricatorRepositoryIdentityTransactionType';
|
||||
}
|
||||
|
||||
public function getApplicationName() {
|
||||
return 'repository';
|
||||
}
|
||||
|
||||
}
|
|
@ -66,6 +66,34 @@ abstract class PhabricatorRepositoryCommitMessageParserWorker
|
|||
$committer = $ref->getCommitter();
|
||||
$hashes = $ref->getHashes();
|
||||
|
||||
$author_identity = id(new PhabricatorRepositoryIdentityQuery())
|
||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||
->withIdentityNames(array($author))
|
||||
->executeOne();
|
||||
|
||||
if (!$author_identity) {
|
||||
$author_identity = id(new PhabricatorRepositoryIdentity())
|
||||
->setAuthorPHID($commit->getPHID())
|
||||
->setIdentityName($author)
|
||||
->setAutomaticGuessedUserPHID(
|
||||
$this->resolveUserPHID($commit, $author))
|
||||
->save();
|
||||
}
|
||||
|
||||
$committer_identity = id(new PhabricatorRepositoryIdentityQuery())
|
||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||
->withIdentityNames(array($committer))
|
||||
->executeOne();
|
||||
|
||||
if (!$committer_identity) {
|
||||
$committer_identity = id(new PhabricatorRepositoryIdentity())
|
||||
->setAuthorPHID($commit->getPHID())
|
||||
->setIdentityName($committer)
|
||||
->setAutomaticGuessedUserPHID(
|
||||
$this->resolveUserPHID($commit, $committer))
|
||||
->save();
|
||||
}
|
||||
|
||||
$data = id(new PhabricatorRepositoryCommitData())->loadOneWhere(
|
||||
'commitID = %d',
|
||||
$commit->getID());
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorRepositoryIdentityAssignTransaction
|
||||
extends PhabricatorRepositoryIdentityTransactionType {
|
||||
|
||||
const TRANSACTIONTYPE = 'repository:identity:assign';
|
||||
|
||||
public function generateOldValue($object) {
|
||||
return nonempty($object->getManuallySetUserPHID(), null);
|
||||
}
|
||||
|
||||
public function applyInternalEffects($object, $value) {
|
||||
$object->setManuallySetUserPHID($value);
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
$old = $this->getOldValue();
|
||||
$new = $this->getNewValue();
|
||||
|
||||
if (!$old) {
|
||||
return pht(
|
||||
'%s assigned this identity to %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderHandle($new));
|
||||
} else if (!$new) {
|
||||
return pht(
|
||||
'%s removed %s as the assignee of this identity.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderHandle($old));
|
||||
} else {
|
||||
return pht(
|
||||
'%s changed the assigned user for this identity from %s to %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderHandle($old),
|
||||
$this->renderHandle($new));
|
||||
}
|
||||
}
|
||||
|
||||
public function validateTransactions($object, array $xactions) {
|
||||
$errors = array();
|
||||
|
||||
foreach ($xactions as $xaction) {
|
||||
$old = $xaction->getOldValue();
|
||||
$new = $xaction->getNewValue();
|
||||
if (!strlen($new)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($new === $old) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$assignee_list = id(new PhabricatorPeopleQuery())
|
||||
->setViewer($this->getActor())
|
||||
->withPHIDs(array($new))
|
||||
->execute();
|
||||
|
||||
if (!$assignee_list) {
|
||||
$errors[] = $this->newInvalidError(
|
||||
pht('User "%s" is not a valid user.',
|
||||
$new));
|
||||
}
|
||||
}
|
||||
return $errors;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
<?php
|
||||
|
||||
abstract class PhabricatorRepositoryIdentityTransactionType
|
||||
extends PhabricatorModularTransactionType {}
|
Loading…
Reference in a new issue