Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/releeph/controller/project/ReleephProjectCreateController.php b/src/applications/releeph/controller/project/ReleephProjectCreateController.php
index 9d4bd89c2f..d478aebe6c 100644
--- a/src/applications/releeph/controller/project/ReleephProjectCreateController.php
+++ b/src/applications/releeph/controller/project/ReleephProjectCreateController.php
@@ -1,149 +1,171 @@
<?php
final class ReleephProjectCreateController extends ReleephProjectController {
public function processRequest() {
$request = $this->getRequest();
$name = trim($request->getStr('name'));
$trunk_branch = trim($request->getStr('trunkBranch'));
$arc_pr_id = $request->getInt('arcPrID');
-
- // Only allow arc projects with repositories. Sort and re-key by ID.
- $arc_projects = id(new PhabricatorRepositoryArcanistProject())->loadAll();
- $arc_projects = mpull(
- msort(
- mfilter($arc_projects, 'getRepositoryID'),
- 'getName'),
- null,
- 'getID');
+ $arc_projects = $this->loadArcProjects();
$e_name = true;
$e_trunk_branch = true;
$errors = array();
if ($request->isFormPost()) {
if (!$name) {
$e_name = pht('Required');
- $errors[] =
- pht('Your Releeph project should have a simple descriptive name.');
+ $errors[] = pht(
+ 'Your Releeph project should have a simple descriptive name.');
}
if (!$trunk_branch) {
$e_trunk_branch = pht('Required');
- $errors[] =
- pht('You must specify which branch you will be picking from.');
- }
-
- $all_names = mpull(id(new ReleephProject())->loadAll(), 'getName');
-
- if (in_array($name, $all_names)) {
- $errors[] = pht('Releeph project name %s is already taken', $name);
+ $errors[] = pht(
+ 'You must specify which branch you will be picking from.');
}
$arc_project = $arc_projects[$arc_pr_id];
$pr_repository = $arc_project->loadRepository();
if (!$errors) {
$releeph_project = id(new ReleephProject())
->setName($name)
->setTrunkBranch($trunk_branch)
->setRepositoryID($pr_repository->getID())
->setRepositoryPHID($pr_repository->getPHID())
->setArcanistProjectID($arc_project->getID())
->setCreatedByUserPHID($request->getUser()->getPHID())
- ->setIsActive(1)
- ->save();
+ ->setIsActive(1);
- return id(new AphrontRedirectResponse())->setURI('/releeph/');
+ try {
+ $releeph_project->save();
+
+ return id(new AphrontRedirectResponse())
+ ->setURI($releeph_project->getURI());
+ } catch (AphrontQueryDuplicateKeyException $ex) {
+ $e_name = pht('Not Unique');
+ $errors[] = pht(
+ 'Another project already uses this name.');
+ }
}
}
$error_view = null;
if ($errors) {
$error_view = new AphrontErrorView();
$error_view->setErrors($errors);
- $error_view->setTitle(pht('Form Errors'));
}
- // Make our own optgroup select control
- $arc_project_choices = array();
- $pr_repositories = mpull(
- msort(
- array_filter(
- // Some arc-projects don't have repositories
- mpull($arc_projects, 'loadRepository')),
- 'getName'),
- null,
- 'getID');
-
- foreach ($pr_repositories as $pr_repo_id => $pr_repository) {
- $options = array();
- foreach ($arc_projects as $arc_project) {
- if ($arc_project->getRepositoryID() == $pr_repo_id) {
- $options[$arc_project->getID()] = $arc_project->getName();
- }
- }
- $arc_project_choices[$pr_repository->getName()] = $options;
- }
+ $arc_project_options = $this->getArcProjectSelectOptions($arc_projects);
$project_name_input = id(new AphrontFormTextControl())
->setLabel(pht('Name'))
->setDisableAutocomplete(true)
->setName('name')
->setValue($name)
->setError($e_name)
->setCaption(pht('A name like "Thrift" but not "Thrift releases".'));
$arc_project_input = id(new AphrontFormSelectControl())
->setLabel(pht('Arc Project'))
->setName('arcPrID')
->setValue($arc_pr_id)
->setCaption(pht(
'If your Arc project isn\'t listed, associate it with a repository %s',
phutil_tag(
'a',
array(
'href' => '/repository/',
'target' => '_blank',
),
'here')))
- ->setOptions($arc_project_choices);
+ ->setOptions($arc_project_options);
$branch_name_preview = id(new ReleephBranchPreviewView())
->setLabel(pht('Example Branch'))
->addControl('projectName', $project_name_input)
->addControl('arcProjectID', $arc_project_input)
->addStatic('template', '')
->addStatic('isSymbolic', false);
$form = id(new AphrontFormView())
->setUser($request->getUser())
+ ->setFlexible(true)
->appendChild($project_name_input)
->appendChild($arc_project_input)
->appendChild(
id(new AphrontFormTextControl())
->setLabel(pht('Trunk'))
->setName('trunkBranch')
->setValue($trunk_branch)
->setError($e_trunk_branch)
->setCaption(pht('The development branch, '.
'from which requests will be picked.')))
->appendChild($branch_name_preview)
->appendChild(
id(new AphrontFormSubmitControl())
->addCancelButton('/releeph/project/')
->setValue(pht('Create')));
- $panel = id(new AphrontPanelView())
- ->setHeader(pht('Create Releeph Project'))
- ->appendChild($form)
- ->setWidth(AphrontPanelView::WIDTH_FORM);
+ $crumbs = $this->buildApplicationCrumbs();
+ $crumbs->addCrumb(
+ id(new PhabricatorCrumbView())
+ ->setName(pht('New Project')));
- return $this->buildStandardPageResponse(
- array($error_view, $panel),
+ return $this->buildApplicationPage(
+ array(
+ $crumbs,
+ $error_view,
+ $form,
+ ),
array(
- 'title' => pht('Create New Releeph Project')
+ 'title' => pht('Create New Project'),
+ 'dust' => true,
+ 'device' => true,
));
}
+
+ private function loadArcProjects() {
+ $viewer = $this->getRequest()->getUser();
+
+ $projects = id(new PhabricatorRepositoryArcanistProjectQuery())
+ ->setViewer($viewer)
+ ->needRepositories(true)
+ ->execute();
+
+ $projects = mfilter($projects, 'getRepository');
+ $projects = msort($projects, 'getName');
+
+ return $projects;
+ }
+
+ private function getArcProjectSelectOptions(array $arc_projects) {
+ assert_instances_of($arc_projects, 'PhabricatorRepositoryArcanistProject');
+
+ $repos = mpull($arc_projects, 'getRepository');
+ $repos = mpull($repos, null, 'getID');
+
+ $groups = array();
+ foreach ($arc_projects as $arc_project) {
+ $id = $arc_project->getID();
+ $repo_id = $arc_project->getRepository()->getID();
+ $groups[$repo_id][$id] = $arc_project->getName();
+ }
+
+ $choices = array();
+ foreach ($groups as $repo_id => $group) {
+ $repo_name = $repos[$repo_id]->getName();
+ $callsign = $repos[$repo_id]->getCallsign();
+ $name = "r{$callsign} ({$repo_name})";
+ $choices[$name] = $group;
+ }
+
+ ksort($choices);
+
+ return $choices;
+ }
+
}
diff --git a/src/applications/repository/query/PhabricatorRepositoryArcanistProjectQuery.php b/src/applications/repository/query/PhabricatorRepositoryArcanistProjectQuery.php
index 1118099e86..9e34bda100 100644
--- a/src/applications/repository/query/PhabricatorRepositoryArcanistProjectQuery.php
+++ b/src/applications/repository/query/PhabricatorRepositoryArcanistProjectQuery.php
@@ -1,59 +1,84 @@
<?php
/**
* @group repository
*/
final class PhabricatorRepositoryArcanistProjectQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
+ private $needRepositories;
+
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
+ public function needRepositories($need_repositories) {
+ $this->needRepositories = $need_repositories;
+ return $this;
+ }
+
protected function loadPage() {
$table = new PhabricatorRepositoryArcanistProject();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
+ public function willFilterPage(array $projects) {
+ assert_instances_of($projects, 'PhabricatorRepositoryArcanistProject');
+
+ if ($this->needRepositories) {
+ $repository_ids = mpull($projects, 'getRepositoryID');
+ $repositories = id(new PhabricatorRepositoryQuery())
+ ->setViewer($this->getViewer())
+ ->withIDs($repository_ids)
+ ->execute();
+ foreach ($projects as $project) {
+ $repo = idx($repositories, $project->getRepositoryID());
+ $project->attachRepository($repo);
+ }
+ }
+
+ return $projects;
+ }
+
private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
}
diff --git a/src/applications/repository/storage/PhabricatorRepositoryArcanistProject.php b/src/applications/repository/storage/PhabricatorRepositoryArcanistProject.php
index a34a616868..0ce6daafb2 100644
--- a/src/applications/repository/storage/PhabricatorRepositoryArcanistProject.php
+++ b/src/applications/repository/storage/PhabricatorRepositoryArcanistProject.php
@@ -1,78 +1,90 @@
<?php
/**
* @group repository
*/
final class PhabricatorRepositoryArcanistProject
extends PhabricatorRepositoryDAO
implements PhabricatorPolicyInterface {
protected $name;
protected $phid;
protected $repositoryID;
protected $symbolIndexLanguages = array();
protected $symbolIndexProjects = array();
+ private $repository = self::ATTACHABLE;
+
public function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
self::CONFIG_TIMESTAMPS => false,
self::CONFIG_SERIALIZATION => array(
'symbolIndexLanguages' => self::SERIALIZATION_JSON,
'symbolIndexProjects' => self::SERIALIZATION_JSON,
),
) + parent::getConfiguration();
}
public function generatePHID() {
return PhabricatorPHID::generateNewPHID(
PhabricatorRepositoryPHIDTypeArcanistProject::TYPECONST);
}
+ // TODO: Remove.
public function loadRepository() {
if (!$this->getRepositoryID()) {
return null;
}
return id(new PhabricatorRepository())->load($this->getRepositoryID());
}
public function delete() {
$this->openTransaction();
queryfx(
$this->establishConnection('w'),
'DELETE FROM %T WHERE arcanistProjectID = %d',
id(new PhabricatorRepositorySymbol())->getTableName(),
$this->getID());
$result = parent::delete();
$this->saveTransaction();
return $result;
}
+ public function getRepository() {
+ return $this->assertAttached($this->repository);
+ }
+
+ public function attachRepository(PhabricatorRepository $repository = null) {
+ $this->repository = $repository;
+ return $this;
+ }
+
/* -( PhabricatorPolicyInterface )----------------------------------------- */
public function getCapabilities() {
return array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
);
}
public function getPolicy($capability) {
switch ($capability) {
case PhabricatorPolicyCapability::CAN_VIEW:
return PhabricatorPolicies::POLICY_USER;
case PhabricatorPolicyCapability::CAN_EDIT:
return PhabricatorPolicies::POLICY_ADMIN;
}
}
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
return false;
}
}

File Metadata

Mime Type
text/x-diff
Expires
Wed, Jul 23, 10:36 PM (21 h, 25 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
182371
Default Alt Text
(12 KB)

Event Timeline