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

Rough cut of projects.

Summary:

Test Plan:

Reviewers:

CC:
This commit is contained in:
epriestley 2011-02-20 18:41:23 -08:00
parent fd1318bf4c
commit fdd510ba17
22 changed files with 812 additions and 1 deletions

View file

@ -0,0 +1,31 @@
create database phabricator_project;
create table phabricator_project.project (
id int unsigned not null auto_increment primary key,
name varchar(255) not null,
unique key (name),
phid varchar(64) binary not null,
authorPHID varchar(64) binary not null,
dateCreated int unsigned not null,
dateModified int unsigned not null
);
create table phabricator_project.project_profile (
id int unsigned not null auto_increment primary key,
projectPHID varchar(64) binary not null,
unique key (projectPHID),
blurb longtext not null,
profileImagePHID varchar(64) binary,
dateCreated int unsigned not null,
dateModified int unsigned not null
);
create table phabricator_project.project_affiliation (
id int unsigned not null auto_increment primary key,
projectPHID varchar(64) binary not null,
userPHID varchar(64) binary not null,
unique key (projectPHID, userPHID),
key (userPHID),
role varchar(255) not null,
status varchar(32) not null,
dateCreated int unsigned not null,
dateModified int unsigned not null
);

View file

@ -231,6 +231,15 @@ phutil_register_library_map(array(
'PhabricatorPeopleListController' => 'applications/people/controller/list',
'PhabricatorPeopleProfileController' => 'applications/people/controller/profile',
'PhabricatorPeopleProfileEditController' => 'applications/people/controller/profileedit',
'PhabricatorProject' => 'applications/project/storage/project',
'PhabricatorProjectAffiliation' => 'applications/project/storage/affiliation',
'PhabricatorProjectAffiliationEditController' => 'applications/project/controller/editaffiliation',
'PhabricatorProjectController' => 'applications/project/controller/base',
'PhabricatorProjectDAO' => 'applications/project/storage/base',
'PhabricatorProjectEditController' => 'applications/project/controller/edit',
'PhabricatorProjectListController' => 'applications/project/controller/list',
'PhabricatorProjectProfile' => 'applications/project/storage/profile',
'PhabricatorProjectProfileController' => 'applications/project/controller/profile',
'PhabricatorRemarkupRuleDifferential' => 'infrastructure/markup/remarkup/markuprule/differential',
'PhabricatorRemarkupRuleManiphest' => 'infrastructure/markup/remarkup/markuprule/maniphest',
'PhabricatorRepository' => 'applications/repository/storage/repository',
@ -464,6 +473,15 @@ phutil_register_library_map(array(
'PhabricatorPeopleListController' => 'PhabricatorPeopleController',
'PhabricatorPeopleProfileController' => 'PhabricatorPeopleController',
'PhabricatorPeopleProfileEditController' => 'PhabricatorPeopleController',
'PhabricatorProject' => 'PhabricatorProjectDAO',
'PhabricatorProjectAffiliation' => 'PhabricatorProjectDAO',
'PhabricatorProjectAffiliationEditController' => 'PhabricatorProjectController',
'PhabricatorProjectController' => 'PhabricatorController',
'PhabricatorProjectDAO' => 'PhabricatorLiskDAO',
'PhabricatorProjectEditController' => 'PhabricatorProjectController',
'PhabricatorProjectListController' => 'PhabricatorProjectController',
'PhabricatorProjectProfile' => 'PhabricatorProjectDAO',
'PhabricatorProjectProfileController' => 'PhabricatorProjectController',
'PhabricatorRemarkupRuleDifferential' => 'PhutilRemarkupRule',
'PhabricatorRemarkupRuleManiphest' => 'PhutilRemarkupRule',
'PhabricatorRepository' => 'PhabricatorRepositoryDAO',

View file

@ -169,6 +169,14 @@ class AphrontDefaultApplicationConfiguration
'$' => 'PhabricatorSearchController',
'(?P<id>\d+)/$' => 'PhabricatorSearchController',
),
'/project/' => array(
'$' => 'PhabricatorProjectListController',
'edit/(?:(?P<id>\d+)/)?$' => 'PhabricatorProjectEditController',
'view/(?P<id>\d+)/$' => 'PhabricatorProjectProfileController',
'affiliation/(?P<id>\d+)/$'
=> 'PhabricatorProjectAffiliationEditController',
)
);
}

View file

@ -107,7 +107,6 @@ class PhabricatorPeopleProfileController extends PhabricatorPeopleController {
$factory = new DifferentialMarkupEngineFactory();
$engine = $factory->newDifferentialCommentMarkupEngine();
$blurb = $engine->markupText($blurb);
$content =

View file

@ -0,0 +1,34 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
abstract class PhabricatorProjectController extends PhabricatorController {
public function buildStandardPageResponse($view, array $data) {
$page = $this->buildStandardPageView();
$page->setApplicationName('Project');
$page->setBaseURI('/project/');
$page->setTitle(idx($data, 'title'));
$page->setGlyph("\xE2\x98\xA3");
$page->appendChild($view);
$response = new AphrontWebpageResponse();
return $response->setContent($page->render());
}
}

View file

@ -0,0 +1,15 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'aphront/response/webpage');
phutil_require_module('phabricator', 'applications/base/controller/base');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorProjectController.php');

View file

@ -0,0 +1,126 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class PhabricatorProjectEditController
extends PhabricatorProjectController {
private $id;
public function willProcessRequest(array $data) {
$this->id = idx($data, 'id');
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
if ($this->id) {
$project = id(new PhabricatorProject())->load($this->id);
if (!$project) {
return new Aphront404Response();
}
$profile = id(new PhabricatorProjectProfile())->loadOneWhere(
'projectPHID = %s',
$project->getPHID());
} else {
$project = new PhabricatorProject();
$project->setAuthorPHID($user->getPHID());
}
if (empty($profile)) {
$profile = new PhabricatorProjectProfile();
}
$e_name = true;
$errors = array();
if ($request->isFormPost()) {
$project->setName($request->getStr('name'));
$profile->setBlurb($request->getStr('blurb'));
if (!strlen($project->getName())) {
$e_name = 'Required';
$errors[] = 'Project name is required.';
} else {
$e_name = null;
}
if (!$errors) {
$project->save();
$profile->setProjectPHID($project->getPHID());
$profile->save();
return id(new AphrontRedirectResponse())
->setURI('/project/view/'.$project->getID().'/');
}
}
$error_view = null;
if ($errors) {
$error_view = new AphrontErrorView();
$error_view->setTitle('Form Errors');
$error_view->setErrors($errors);
}
if ($project->getID()) {
$header_name = 'Edit Project';
$title = 'Edit Project';
$action = '/project/edit/'.$project->getID().'/';
} else {
$header_name = 'Create Project';
$title = 'Create Project';
$action = '/project/edit/';
}
$form = new AphrontFormView();
$form
->setUser($user)
->setAction($action)
->appendChild(
id(new AphrontFormTextControl())
->setLabel('Name')
->setName('name')
->setValue($project->getName())
->setError($e_name))
->appendChild(
id(new AphrontFormTextAreaControl())
->setLabel('Blurb')
->setName('blurb')
->setValue($profile->getBlurb()))
->appendChild(
id(new AphrontFormSubmitControl())
->addCancelButton('/project/')
->setValue('Save'));
$panel = new AphrontPanelView();
$panel->setHeader($header_name);
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
$panel->appendChild($form);
return $this->buildStandardPageResponse(
array(
$error_view,
$panel,
),
array(
'title' => $title,
));
}
}

View file

@ -0,0 +1,22 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'aphront/response/404');
phutil_require_module('phabricator', 'aphront/response/redirect');
phutil_require_module('phabricator', 'applications/project/controller/base');
phutil_require_module('phabricator', 'applications/project/storage/profile');
phutil_require_module('phabricator', 'applications/project/storage/project');
phutil_require_module('phabricator', 'view/form/base');
phutil_require_module('phabricator', 'view/form/control/submit');
phutil_require_module('phabricator', 'view/form/error');
phutil_require_module('phabricator', 'view/layout/panel');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorProjectEditController.php');

View file

@ -0,0 +1,102 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class PhabricatorProjectAffiliationEditController
extends PhabricatorProjectController {
private $id;
public function willProcessRequest(array $data) {
$this->id = $data['id'];
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$project = id(new PhabricatorProject())->load($this->id);
if (!$project) {
return new Aphront404Response();
}
$affiliation = id(new PhabricatorProjectAffiliation())->loadOneWhere(
'projectPHID = %s AND userPHID = %s',
$project->getPHID(),
$user->getPHID());
if (!$affiliation) {
$affiliation = new PhabricatorProjectAffiliation();
$affiliation->setUserPHID($user->getPHID());
$affiliation->setProjectPHID($project->getPHID());
}
if ($request->isFormPost()) {
$affiliation->setRole($request->getStr('role'));
$affiliation->setStatus($request->getStr('status'));
if (!strlen($affiliation->getRole())) {
if ($affiliation->getID()) {
$affiliation->delete();
}
} else {
$affiliation->save();
}
return id(new AphrontRedirectResponse())
->setURI('/project/view/'.$project->getID().'/');
}
$status_options = array(
'' => 'Current',
'former' => 'Former',
);
$form = new AphrontFormView();
$form
->setUser($user)
->setAction('/project/affiliation/'.$project->getID().'/')
->appendChild(
id(new AphrontFormTextControl())
->setLabel('Role')
->setName('role')
->setValue($affiliation->getRole()))
->appendChild(
id(new AphrontFormSelectControl())
->setLabel('Status')
->setName('status')
->setOptions($status_options)
->setValue($affiliation->getStatus()))
->appendChild(
id(new AphrontFormSubmitControl())
->addCancelButton('/project/view/'.$project->getID().'/')
->setValue('Save'));
$panel = new AphrontPanelView();
$panel->setHeader('Edit Project Affiliation');
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
$panel->appendChild($form);
return $this->buildStandardPageResponse(
$panel,
array(
'title' => 'Edit Project Affiliation',
));
}
}

View file

@ -0,0 +1,21 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'aphront/response/404');
phutil_require_module('phabricator', 'aphront/response/redirect');
phutil_require_module('phabricator', 'applications/project/controller/base');
phutil_require_module('phabricator', 'applications/project/storage/affiliation');
phutil_require_module('phabricator', 'applications/project/storage/project');
phutil_require_module('phabricator', 'view/form/base');
phutil_require_module('phabricator', 'view/form/control/submit');
phutil_require_module('phabricator', 'view/layout/panel');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorProjectAffiliationEditController.php');

View file

@ -0,0 +1,65 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class PhabricatorProjectListController
extends PhabricatorProjectController {
public function processRequest() {
$projects = id(new PhabricatorProject())->loadAllWhere(
'1 = 1 ORDER BY id DESC limit 100');
$rows = array();
foreach ($projects as $project) {
$rows[] = array(
phutil_escape_html($project->getName()),
phutil_render_tag(
'a',
array(
'class' => 'small grey button',
'href' => '/project/view/'.$project->getID().'/',
),
'View Profile'),
);
}
$table = new AphrontTableView($rows);
$table->setHeaders(
array(
'Project',
'',
));
$table->setColumnClasses(
array(
'wide',
'action',
));
$panel = new AphrontPanelView();
$panel->appendChild($table);
$panel->setHeader('People');
$panel->setCreateButton('Create New Project Project', '/project/edit/');
return $this->buildStandardPageResponse(
$panel,
array(
'title' => 'Project Projects',
));
}
}

View file

@ -0,0 +1,18 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/project/controller/base');
phutil_require_module('phabricator', 'applications/project/storage/project');
phutil_require_module('phabricator', 'view/control/table');
phutil_require_module('phabricator', 'view/layout/panel');
phutil_require_module('phutil', 'markup');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorProjectListController.php');

View file

@ -0,0 +1,158 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class PhabricatorProjectProfileController
extends PhabricatorProjectController {
private $id;
public function willProcessRequest(array $data) {
$this->id = $data['id'];
}
public function processRequest() {
$project = id(new PhabricatorProject())->load($this->id);
if (!$project) {
return new Aphront404Response();
}
$profile = id(new PhabricatorProjectProfile())->loadOneWhere(
'projectPHID = %s',
$project->getPHID());
if (!$profile) {
$profile = new PhabricatorProjectProfile();
}
require_celerity_resource('phabricator-profile-css');
$src_phid = $profile->getProfileImagePHID();
$src = PhabricatorFileURI::getViewURIForPHID($src_phid);
$picture = phutil_render_tag(
'img',
array(
'class' => 'profile-image',
'src' => $src,
));
$links =
'<ul class="profile-nav-links">'.
'<li><a href="/project/edit/'.$project->getID().'/">'.
'Edit Project</a></li>'.
'<li><a href="/project/affiliation/'.$project->getID().'/">'.
'Edit Affiliation</a></li>'.
'</ul>';
$blurb = nonempty(
$profile->getBlurb(),
'//Nothing is known about this elusive project.//');
$factory = new DifferentialMarkupEngineFactory();
$engine = $factory->newDifferentialCommentMarkupEngine();
$blurb = $engine->markupText($blurb);
$affiliations = id(new PhabricatorProjectAffiliation())->loadAllWhere(
'projectPHID = %s ORDER BY IF(status = "former", 1, 0), dateCreated',
$project->getPHID());
$phids = array_merge(
array($project->getAuthorPHID()),
mpull($affiliations, 'getUserPHID'));
$handles = id(new PhabricatorObjectHandleData($phids))
->loadHandles();
$affiliated = array();
foreach ($affiliations as $affiliation) {
$user = $handles[$affiliation->getUserPHID()]->renderLink();
$role = phutil_escape_html($affiliation->getRole());
$status = null;
if ($affiliation->getStatus() == 'former') {
$role = '<em>Former '.$role.'</em>';
}
$affiliated[] = '<li>'.$user.' &mdash; '.$role.$status.'</li>';
}
if ($affiliated) {
$affiliated = '<ul>'.implode("\n", $affiliated).'</ul>';
} else {
$affiliated = '<p><em>No one is affiliated with this project.</em></p>';
}
$timestamp = phabricator_format_timestamp($project->getDateCreated());
$content =
'<div class="phabricator-profile-info-group">
<h1 class="phabricator-profile-info-header">Basic Information</h1>
<div class="phabricator-profile-info-pane">
<table class="phabricator-profile-info-table">
<tr>
<th>Creator</th>
<td>'.$handles[$project->getAuthorPHID()]->renderLink().'</td>
</tr>
<tr>
<th>Created</th>
<td>'.$timestamp.'</td>
</tr>
<tr>
<th>PHID</th>
<td>'.phutil_escape_html($project->getPHID()).'</td>
</tr>
<tr>
<th>Blurb</th>
<td>'.$blurb.'</td>
</tr>
</table>
</div>
</div>';
$content .=
'<div class="phabricator-profile-info-group">
<h1 class="phabricator-profile-info-header">Resources</h1>
<div class="phabricator-profile-info-pane">'.
$affiliated.
'</div>
</div>';
$profile_markup =
'<table class="phabricator-profile-master-layout">
<tr>
<td class="phabricator-profile-navigation">'.
'<h1>'.phutil_escape_html($project->getName()).'</h1>'.
'<hr />'.
$picture.
'<hr />'.
$links.
'<hr />'.
'</td>
<td class="phabricator-profile-content">'.
$content.
'</td>
</tr>
</table>';
return $this->buildStandardPageResponse(
$profile_markup,
array(
'title' => $project->getName(),
));
}
}

View file

@ -0,0 +1,24 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'aphront/response/404');
phutil_require_module('phabricator', 'applications/differential/parser/markup');
phutil_require_module('phabricator', 'applications/files/uri');
phutil_require_module('phabricator', 'applications/phid/handle/data');
phutil_require_module('phabricator', 'applications/project/controller/base');
phutil_require_module('phabricator', 'applications/project/storage/affiliation');
phutil_require_module('phabricator', 'applications/project/storage/profile');
phutil_require_module('phabricator', 'applications/project/storage/project');
phutil_require_module('phabricator', 'infrastructure/celerity/api');
phutil_require_module('phabricator', 'view/utils');
phutil_require_module('phutil', 'markup');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorProjectProfileController.php');

View file

@ -0,0 +1,26 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class PhabricatorProjectAffiliation extends PhabricatorProjectDAO {
protected $projectPHID;
protected $userPHID;
protected $role;
protected $status;
}

View file

@ -0,0 +1,12 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/project/storage/base');
phutil_require_source('PhabricatorProjectAffiliation.php');

View file

@ -0,0 +1,25 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class PhabricatorProjectDAO extends PhabricatorLiskDAO {
public function getApplicationName() {
return 'project';
}
}

View file

@ -0,0 +1,12 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/base/storage/lisk');
phutil_require_source('PhabricatorProjectDAO.php');

View file

@ -0,0 +1,34 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class PhabricatorProjectProfile extends PhabricatorProjectDAO {
protected $projectPHID;
protected $blurb;
protected $profileImagePHID;
public function getProfileImagePHID() {
if ($this->profileImagePHID) {
return $this->profileImagePHID;
}
// TODO: Make a separate one of these for projects.
return PhabricatorEnv::getEnvConfig('user.default-profile-image-phid');
}
}

View file

@ -0,0 +1,13 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/project/storage/base');
phutil_require_module('phabricator', 'infrastructure/env');
phutil_require_source('PhabricatorProjectProfile.php');

View file

@ -0,0 +1,35 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class PhabricatorProject extends PhabricatorProjectDAO {
protected $name;
protected $phid;
protected $authorPHID;
public function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
) + parent::getConfiguration();
}
public function generatePHID() {
return PhabricatorPHID::generateNewPHID('PROJ');
}
}

View file

@ -0,0 +1,13 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/phid/storage/phid');
phutil_require_module('phabricator', 'applications/project/storage/base');
phutil_require_source('PhabricatorProject.php');