1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-09 16:32:39 +01:00

Rough sketch of new repository URI editing

Summary:
Ref T10748. Ref T10366. This adds a new EditEngine, EditController, Editor, Query, and Transaction for RepositoryURIs.

None of these really do anything helpful yet, and these URIs are still unused in the actual application.

Test Plan: {F1249794}

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T10366, T10748

Differential Revision: https://secure.phabricator.com/D15815
This commit is contained in:
epriestley 2016-04-28 08:33:44 -07:00
parent 0459e95242
commit 616c9ae887
13 changed files with 524 additions and 6 deletions

View file

@ -0,0 +1,19 @@
CREATE TABLE {$NAMESPACE}_repository.repository_uritransaction (
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) COLLATE {$COLLATE_TEXT} NOT NULL,
oldValue LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
newValue LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
contentSource LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
metadata LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
dateCreated INT UNSIGNED NOT NULL,
dateModified INT UNSIGNED NOT NULL,
UNIQUE KEY `key_phid` (`phid`),
KEY `key_object` (`objectPHID`)
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};

View file

@ -789,6 +789,7 @@ phutil_register_library_map(array(
'DiffusionRepositorySymbolsManagementPanel' => 'applications/diffusion/management/DiffusionRepositorySymbolsManagementPanel.php',
'DiffusionRepositoryTag' => 'applications/diffusion/data/DiffusionRepositoryTag.php',
'DiffusionRepositoryTestAutomationController' => 'applications/diffusion/controller/DiffusionRepositoryTestAutomationController.php',
'DiffusionRepositoryURIEditController' => 'applications/diffusion/controller/DiffusionRepositoryURIEditController.php',
'DiffusionRepositoryURIsIndexEngineExtension' => 'applications/diffusion/engineextension/DiffusionRepositoryURIsIndexEngineExtension.php',
'DiffusionRepositoryURIsManagementPanel' => 'applications/diffusion/management/DiffusionRepositoryURIsManagementPanel.php',
'DiffusionRequest' => 'applications/diffusion/request/DiffusionRequest.php',
@ -814,6 +815,8 @@ phutil_register_library_map(array(
'DiffusionTagListController' => 'applications/diffusion/controller/DiffusionTagListController.php',
'DiffusionTagListView' => 'applications/diffusion/view/DiffusionTagListView.php',
'DiffusionTagsQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionTagsQueryConduitAPIMethod.php',
'DiffusionURIEditEngine' => 'applications/diffusion/editor/DiffusionURIEditEngine.php',
'DiffusionURIEditor' => 'applications/diffusion/editor/DiffusionURIEditor.php',
'DiffusionURITestCase' => 'applications/diffusion/request/__tests__/DiffusionURITestCase.php',
'DiffusionUpdateCoverageConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionUpdateCoverageConduitAPIMethod.php',
'DiffusionView' => 'applications/diffusion/view/DiffusionView.php',
@ -3237,7 +3240,10 @@ phutil_register_library_map(array(
'PhabricatorRepositoryURIIndex' => 'applications/repository/storage/PhabricatorRepositoryURIIndex.php',
'PhabricatorRepositoryURINormalizer' => 'applications/repository/data/PhabricatorRepositoryURINormalizer.php',
'PhabricatorRepositoryURINormalizerTestCase' => 'applications/repository/data/__tests__/PhabricatorRepositoryURINormalizerTestCase.php',
'PhabricatorRepositoryURIPHIDType' => 'applications/repository/phid/PhabricatorRepositoryURIPHIDType.php',
'PhabricatorRepositoryURIQuery' => 'applications/repository/query/PhabricatorRepositoryURIQuery.php',
'PhabricatorRepositoryURITestCase' => 'applications/repository/storage/__tests__/PhabricatorRepositoryURITestCase.php',
'PhabricatorRepositoryURITransaction' => 'applications/repository/storage/PhabricatorRepositoryURITransaction.php',
'PhabricatorRepositoryVCSPassword' => 'applications/repository/storage/PhabricatorRepositoryVCSPassword.php',
'PhabricatorRepositoryVersion' => 'applications/repository/constants/PhabricatorRepositoryVersion.php',
'PhabricatorRepositoryWorkingCopyVersion' => 'applications/repository/storage/PhabricatorRepositoryWorkingCopyVersion.php',
@ -5009,6 +5015,7 @@ phutil_register_library_map(array(
'DiffusionRepositorySymbolsManagementPanel' => 'DiffusionRepositoryManagementPanel',
'DiffusionRepositoryTag' => 'Phobject',
'DiffusionRepositoryTestAutomationController' => 'DiffusionRepositoryEditController',
'DiffusionRepositoryURIEditController' => 'DiffusionRepositoryEditController',
'DiffusionRepositoryURIsIndexEngineExtension' => 'PhabricatorIndexEngineExtension',
'DiffusionRepositoryURIsManagementPanel' => 'DiffusionRepositoryManagementPanel',
'DiffusionRequest' => 'Phobject',
@ -5034,6 +5041,8 @@ phutil_register_library_map(array(
'DiffusionTagListController' => 'DiffusionController',
'DiffusionTagListView' => 'DiffusionView',
'DiffusionTagsQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
'DiffusionURIEditEngine' => 'PhabricatorEditEngine',
'DiffusionURIEditor' => 'PhabricatorApplicationTransactionEditor',
'DiffusionURITestCase' => 'PhutilTestCase',
'DiffusionUpdateCoverageConduitAPIMethod' => 'DiffusionConduitAPIMethod',
'DiffusionView' => 'AphrontView',
@ -7913,11 +7922,19 @@ phutil_register_library_map(array(
'PhabricatorRepositoryTransaction' => 'PhabricatorApplicationTransaction',
'PhabricatorRepositoryTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhabricatorRepositoryType' => 'Phobject',
'PhabricatorRepositoryURI' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositoryURI' => array(
'PhabricatorRepositoryDAO',
'PhabricatorApplicationTransactionInterface',
'PhabricatorPolicyInterface',
'PhabricatorExtendedPolicyInterface',
),
'PhabricatorRepositoryURIIndex' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositoryURINormalizer' => 'Phobject',
'PhabricatorRepositoryURINormalizerTestCase' => 'PhabricatorTestCase',
'PhabricatorRepositoryURIPHIDType' => 'PhabricatorPHIDType',
'PhabricatorRepositoryURIQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorRepositoryURITestCase' => 'PhabricatorTestCase',
'PhabricatorRepositoryURITransaction' => 'PhabricatorApplicationTransaction',
'PhabricatorRepositoryVCSPassword' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositoryVersion' => 'Phobject',
'PhabricatorRepositoryWorkingCopyVersion' => 'PhabricatorRepositoryDAO',

View file

@ -91,6 +91,8 @@ final class PhabricatorDiffusionApplication extends PhabricatorApplication {
=> 'DiffusionCommitEditController',
'manage/(?:(?P<panel>[^/]+)/)?'
=> 'DiffusionRepositoryManageController',
$this->getEditRoutePattern('uri/edit/')
=> 'DiffusionRepositoryURIEditController',
'edit/' => array(
'' => 'DiffusionRepositoryEditMainController',
'basic/' => 'DiffusionRepositoryEditBasicController',

View file

@ -0,0 +1,21 @@
<?php
final class DiffusionRepositoryURIEditController
extends DiffusionRepositoryEditController {
public function handleRequest(AphrontRequest $request) {
$response = $this->loadDiffusionContextForEdit();
if ($response) {
return $response;
}
$drequest = $this->getDiffusionRequest();
$repository = $drequest->getRepository();
return id(new DiffusionURIEditEngine())
->setController($this)
->setRepository($repository)
->buildResponse();
}
}

View file

@ -0,0 +1,93 @@
<?php
final class DiffusionURIEditEngine
extends PhabricatorEditEngine {
const ENGINECONST = 'diffusion.uri';
private $repository;
public function setRepository(PhabricatorRepository $repository) {
$this->repository = $repository;
return $this;
}
public function getRepository() {
return $this->repository;
}
public function isEngineConfigurable() {
return false;
}
public function getEngineName() {
return pht('Repository URIs');
}
public function getSummaryHeader() {
return pht('Edit Repository URI');
}
public function getSummaryText() {
return pht('Creates and edits repository URIs.');
}
public function getEngineApplicationClass() {
return 'PhabricatorDiffusionApplication';
}
protected function newEditableObject() {
$repository = $this->getRepository();
return PhabricatorRepositoryURI::initializeNewURI($repository);
}
protected function newObjectQuery() {
return new PhabricatorRepositoryURIQuery();
}
protected function getObjectCreateTitleText($object) {
return pht('Create Repository URI');
}
protected function getObjectCreateButtonText($object) {
return pht('Create Repository URI');
}
protected function getObjectEditTitleText($object) {
return pht('Edit Repository URI: %s', $object->getDisplayURI());
}
protected function getObjectEditShortText($object) {
return $object->getDisplayURI();
}
protected function getObjectCreateShortText() {
return pht('Create Repository URI');
}
protected function getObjectName() {
return pht('Repository URI');
}
protected function getObjectViewURI($object) {
$repository = $this->getRepository();
return $repository->getPathURI('manage/uris/');
}
protected function buildCustomEditFields($object) {
$viewer = $this->getViewer();
return array(
id(new PhabricatorTextEditField())
->setKey('uri')
->setLabel(pht('URI'))
->setIsRequired(true)
->setTransactionType(PhabricatorRepositoryURITransaction::TYPE_URI)
->setDescription(pht('The repository URI.'))
->setConduitDescription(pht('Change the repository URI.'))
->setConduitTypeDescription(pht('New repository URI.'))
->setValue($object->getURI()),
);
}
}

View file

@ -0,0 +1,99 @@
<?php
final class DiffusionURIEditor
extends PhabricatorApplicationTransactionEditor {
public function getEditorApplicationClass() {
return 'PhabricatorDiffusionApplication';
}
public function getEditorObjectsDescription() {
return pht('Diffusion URIs');
}
public function getTransactionTypes() {
$types = parent::getTransactionTypes();
$types[] = PhabricatorRepositoryURITransaction::TYPE_URI;
return $types;
}
protected function getCustomTransactionOldValue(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorRepositoryURITransaction::TYPE_URI:
return $object->getURI();
}
return parent::getCustomTransactionOldValue($object, $xaction);
}
protected function getCustomTransactionNewValue(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorRepositoryURITransaction::TYPE_URI:
return $xaction->getNewValue();
}
return parent::getCustomTransactionNewValue($object, $xaction);
}
protected function applyCustomInternalTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorRepositoryURITransaction::TYPE_URI:
$object->setURI($xaction->getNewValue());
break;
}
}
protected function applyCustomExternalTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorRepositoryURITransaction::TYPE_URI:
return;
}
return parent::applyCustomExternalTransaction($object, $xaction);
}
protected function validateTransaction(
PhabricatorLiskDAO $object,
$type,
array $xactions) {
$errors = parent::validateTransaction($object, $type, $xactions);
switch ($type) {
case PhabricatorRepositoryURITransaction::TYPE_URI:
$missing = $this->validateIsEmptyTextField(
$object->getURI(),
$xactions);
if ($missing) {
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Required'),
pht('Repository URI is required.'),
nonempty(last($xactions), null));
$error->setIsMissingFieldError(true);
$errors[] = $error;
break;
}
break;
}
return $errors;
}
}

View file

@ -16,8 +16,6 @@ final class DiffusionRepositoryURIsManagementPanel
public function buildManagementPanelContent() {
$repository = $this->getRepository();
$viewer = $this->getViewer();
$repository->attachURIs(array());
$uris = $repository->getURIs();
Javelin::initBehavior('phabricator-tooltips');
@ -25,6 +23,12 @@ final class DiffusionRepositoryURIsManagementPanel
foreach ($uris as $uri) {
$uri_name = $uri->getDisplayURI();
$uri_name = phutil_tag(
'a',
array(
'href' => $repository->getPathURI('uri/edit/'.$uri->getID().'/'),
),
$uri_name);
if ($uri->getIsDisabled()) {
$status_icon = 'fa-times grey';

View file

@ -142,7 +142,8 @@ abstract class DiffusionRequest extends Phobject {
$query = id(new PhabricatorRepositoryQuery())
->setViewer($viewer)
->withIdentifiers(array($identifier));
->withIdentifiers(array($identifier))
->needURIs(true);
if ($need_edit) {
$query->requireCapabilities(

View file

@ -0,0 +1,40 @@
<?php
final class PhabricatorRepositoryURIPHIDType extends PhabricatorPHIDType {
const TYPECONST = 'RURI';
public function getTypeName() {
return pht('Repository URI');
}
public function newObject() {
return new PhabricatorRepositoryURI();
}
public function getPHIDTypeApplicationClass() {
return 'PhabricatorDiffusionApplication';
}
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
return id(new PhabricatorRepositoryURIQuery())
->withPHIDs($phids);
}
public function loadHandles(
PhabricatorHandleQuery $query,
array $handles,
array $objects) {
foreach ($handles as $phid => $handle) {
$uri = $objects[$phid];
$handle->setName(
pht('URI %d %s', $uri->getID(), $uri->getDisplayURI()));
}
}
}

View file

@ -34,6 +34,7 @@ final class PhabricatorRepositoryQuery
private $needMostRecentCommits;
private $needCommitCounts;
private $needProjectPHIDs;
private $needURIs;
public function withIDs(array $ids) {
$this->ids = $ids;
@ -148,6 +149,11 @@ final class PhabricatorRepositoryQuery
return $this;
}
public function needURIs($need_uris) {
$this->needURIs = $need_uris;
return $this;
}
public function getBuiltinOrders() {
return array(
'committed' => array(
@ -348,6 +354,20 @@ final class PhabricatorRepositoryQuery
}
}
$viewer = $this->getViewer();
if ($this->needURIs) {
$uris = id(new PhabricatorRepositoryURIQuery())
->setViewer($viewer)
->withRepositories($repositories)
->execute();
$uri_groups = mgroup($uris, 'getRepositoryPHID');
foreach ($repositories as $repository) {
$repository_uris = idx($uri_groups, $repository->getPHID(), array());
$repository->attachURIs($repository_uris);
}
}
return $repositories;
}

View file

@ -0,0 +1,106 @@
<?php
final class PhabricatorRepositoryURIQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $repositoryPHIDs;
private $repositories = array();
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withRepositoryPHIDs(array $phids) {
$this->repositoryPHIDs = $phids;
return $this;
}
public function withRepositories(array $repositories) {
$repositories = mpull($repositories, null, 'getPHID');
$this->withRepositoryPHIDs(array_keys($repositories));
$this->repositories = $repositories;
return $this;
}
public function withObjectHashes(array $hashes) {
$this->objectHashes = $hashes;
return $this;
}
public function newResultObject() {
return new PhabricatorRepositoryURI();
}
protected function loadPage() {
return $this->loadStandardPage($this->newResultObject());
}
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
$where = parent::buildWhereClauseParts($conn);
if ($this->ids !== null) {
$where[] = qsprintf(
$conn,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn,
'phid IN (%Ls)',
$this->phids);
}
if ($this->repositoryPHIDs !== null) {
$where[] = qsprintf(
$conn,
'repositoryPHID IN (%Ls)',
$this->repositoryPHIDs);
}
return $where;
}
protected function willFilterPage(array $uris) {
$repositories = $this->repositories;
$repository_phids = mpull($uris, 'getRepositoryPHID');
$repository_phids = array_fuse($repository_phids);
$repository_phids = array_diff_key($repository_phids, $repositories);
if ($repository_phids) {
$more_repositories = id(new PhabricatorRepositoryQuery())
->setViewer($this->getViewer())
->withPHIDs($repository_phids)
->execute();
$repositories += mpull($more_repositories, null, 'getPHID');
}
foreach ($uris as $key => $uri) {
$repository_phid = $uri->getRepositoryPHID();
$repository = idx($repositories, $repository_phid);
if (!$repository) {
$this->didRejectResult($uri);
unset($uris[$key]);
continue;
}
$uri->attachRepository($repository);
}
return $uris;
}
public function getQueryApplicationClass() {
return 'PhabricatorDiffusionApplication';
}
}

View file

@ -1,7 +1,11 @@
<?php
final class PhabricatorRepositoryURI
extends PhabricatorRepositoryDAO {
extends PhabricatorRepositoryDAO
implements
PhabricatorApplicationTransactionInterface,
PhabricatorPolicyInterface,
PhabricatorExtendedPolicyInterface {
protected $repositoryPHID;
protected $uri;
@ -67,6 +71,11 @@ final class PhabricatorRepositoryURI
->setIsDisabled(0);
}
public function generatePHID() {
return PhabricatorPHID::generateNewPHID(
PhabricatorRepositoryURIPHIDType::TYPECONST);
}
public function attachRepository(PhabricatorRepository $repository) {
$this->repository = $repository;
return $this;
@ -176,7 +185,7 @@ final class PhabricatorRepositoryURI
}
}
return self::IO_IGNORE;
return self::IO_NONE;
}
@ -298,4 +307,71 @@ final class PhabricatorRepositoryURI
}
}
/* -( PhabricatorApplicationTransactionInterface )------------------------- */
public function getApplicationTransactionEditor() {
return new DiffusionURIEditor();
}
public function getApplicationTransactionObject() {
return $this;
}
public function getApplicationTransactionTemplate() {
return new PhabricatorRepositoryURITransaction();
}
public function willRenderTimeline(
PhabricatorApplicationTransactionView $timeline,
AphrontRequest $request) {
return $timeline;
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */
public function getCapabilities() {
return array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
);
}
public function getPolicy($capability) {
switch ($capability) {
case PhabricatorPolicyCapability::CAN_VIEW:
case PhabricatorPolicyCapability::CAN_EDIT:
return PhabricatorPolicies::getMostOpenPolicy();
}
}
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
/* -( PhabricatorExtendedPolicyInterface )--------------------------------- */
public function getExtendedPolicy($capability, PhabricatorUser $viewer) {
$extended = array();
switch ($capability) {
case PhabricatorPolicyCapability::CAN_EDIT:
// To edit a repository URI, you must be able to edit the
// corresponding repository.
$extended[] = array($this->getRepository(), $capability);
break;
}
return $extended;
}
}

View file

@ -0,0 +1,20 @@
<?php
final class PhabricatorRepositoryURITransaction
extends PhabricatorApplicationTransaction {
const TYPE_URI = 'diffusion.uri.uri';
public function getApplicationName() {
return 'repository';
}
public function getApplicationTransactionType() {
return PhabricatorRepositoryURIPHIDType::TYPECONST;
}
public function getApplicationTransactionCommentObject() {
return null;
}
}