From fdd510ba17fe68e712beca69e7789b2e9ed03f78 Mon Sep 17 00:00:00 2001 From: epriestley Date: Sun, 20 Feb 2011 18:41:23 -0800 Subject: [PATCH] Rough cut of projects. Summary: Test Plan: Reviewers: CC: --- resources/sql/patches/project.sql | 31 ++++ src/__phutil_library_map__.php | 18 ++ ...AphrontDefaultApplicationConfiguration.php | 8 + .../PhabricatorPeopleProfileController.php | 1 - .../base/PhabricatorProjectController.php | 34 ++++ .../project/controller/base/__init__.php | 15 ++ .../edit/PhabricatorProjectEditController.php | 126 ++++++++++++++ .../project/controller/edit/__init__.php | 22 +++ ...icatorProjectAffiliationEditController.php | 102 +++++++++++ .../controller/editaffiliation/__init__.php | 21 +++ .../list/PhabricatorProjectListController.php | 65 +++++++ .../project/controller/list/__init__.php | 18 ++ .../PhabricatorProjectProfileController.php | 158 ++++++++++++++++++ .../project/controller/profile/__init__.php | 24 +++ .../PhabricatorProjectAffiliation.php | 26 +++ .../project/storage/affiliation/__init__.php | 12 ++ .../storage/base/PhabricatorProjectDAO.php | 25 +++ .../project/storage/base/__init__.php | 12 ++ .../profile/PhabricatorProjectProfile.php | 34 ++++ .../project/storage/profile/__init__.php | 13 ++ .../storage/project/PhabricatorProject.php | 35 ++++ .../project/storage/project/__init__.php | 13 ++ 22 files changed, 812 insertions(+), 1 deletion(-) create mode 100644 resources/sql/patches/project.sql create mode 100644 src/applications/project/controller/base/PhabricatorProjectController.php create mode 100644 src/applications/project/controller/base/__init__.php create mode 100644 src/applications/project/controller/edit/PhabricatorProjectEditController.php create mode 100644 src/applications/project/controller/edit/__init__.php create mode 100644 src/applications/project/controller/editaffiliation/PhabricatorProjectAffiliationEditController.php create mode 100644 src/applications/project/controller/editaffiliation/__init__.php create mode 100644 src/applications/project/controller/list/PhabricatorProjectListController.php create mode 100644 src/applications/project/controller/list/__init__.php create mode 100644 src/applications/project/controller/profile/PhabricatorProjectProfileController.php create mode 100644 src/applications/project/controller/profile/__init__.php create mode 100644 src/applications/project/storage/affiliation/PhabricatorProjectAffiliation.php create mode 100644 src/applications/project/storage/affiliation/__init__.php create mode 100644 src/applications/project/storage/base/PhabricatorProjectDAO.php create mode 100644 src/applications/project/storage/base/__init__.php create mode 100644 src/applications/project/storage/profile/PhabricatorProjectProfile.php create mode 100644 src/applications/project/storage/profile/__init__.php create mode 100644 src/applications/project/storage/project/PhabricatorProject.php create mode 100644 src/applications/project/storage/project/__init__.php diff --git a/resources/sql/patches/project.sql b/resources/sql/patches/project.sql new file mode 100644 index 0000000000..2f4cf2c89a --- /dev/null +++ b/resources/sql/patches/project.sql @@ -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 +); + diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index bd3e93a1e1..1e60390467 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -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', diff --git a/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php b/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php index 16942c1cc0..5e3b169bcb 100644 --- a/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php +++ b/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php @@ -169,6 +169,14 @@ class AphrontDefaultApplicationConfiguration '$' => 'PhabricatorSearchController', '(?P\d+)/$' => 'PhabricatorSearchController', ), + + '/project/' => array( + '$' => 'PhabricatorProjectListController', + 'edit/(?:(?P\d+)/)?$' => 'PhabricatorProjectEditController', + 'view/(?P\d+)/$' => 'PhabricatorProjectProfileController', + 'affiliation/(?P\d+)/$' + => 'PhabricatorProjectAffiliationEditController', + ) ); } diff --git a/src/applications/people/controller/profile/PhabricatorPeopleProfileController.php b/src/applications/people/controller/profile/PhabricatorPeopleProfileController.php index 2f92731e29..8581a54dbc 100644 --- a/src/applications/people/controller/profile/PhabricatorPeopleProfileController.php +++ b/src/applications/people/controller/profile/PhabricatorPeopleProfileController.php @@ -107,7 +107,6 @@ class PhabricatorPeopleProfileController extends PhabricatorPeopleController { $factory = new DifferentialMarkupEngineFactory(); $engine = $factory->newDifferentialCommentMarkupEngine(); - $blurb = $engine->markupText($blurb); $content = diff --git a/src/applications/project/controller/base/PhabricatorProjectController.php b/src/applications/project/controller/base/PhabricatorProjectController.php new file mode 100644 index 0000000000..23226f36a5 --- /dev/null +++ b/src/applications/project/controller/base/PhabricatorProjectController.php @@ -0,0 +1,34 @@ +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()); + } + +} diff --git a/src/applications/project/controller/base/__init__.php b/src/applications/project/controller/base/__init__.php new file mode 100644 index 0000000000..304773ec63 --- /dev/null +++ b/src/applications/project/controller/base/__init__.php @@ -0,0 +1,15 @@ +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, + )); + } + +} diff --git a/src/applications/project/controller/edit/__init__.php b/src/applications/project/controller/edit/__init__.php new file mode 100644 index 0000000000..4dd12ec538 --- /dev/null +++ b/src/applications/project/controller/edit/__init__.php @@ -0,0 +1,22 @@ +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', + )); + } + +} diff --git a/src/applications/project/controller/editaffiliation/__init__.php b/src/applications/project/controller/editaffiliation/__init__.php new file mode 100644 index 0000000000..5f42c906a4 --- /dev/null +++ b/src/applications/project/controller/editaffiliation/__init__.php @@ -0,0 +1,21 @@ +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', + )); + } + +} diff --git a/src/applications/project/controller/list/__init__.php b/src/applications/project/controller/list/__init__.php new file mode 100644 index 0000000000..aff05271b4 --- /dev/null +++ b/src/applications/project/controller/list/__init__.php @@ -0,0 +1,18 @@ +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 = + ''; + + $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 = 'Former '.$role.''; + } + + $affiliated[] = '
  • '.$user.' — '.$role.$status.'
  • '; + } + if ($affiliated) { + $affiliated = '
      '.implode("\n", $affiliated).'
    '; + } else { + $affiliated = '

    No one is affiliated with this project.

    '; + } + + $timestamp = phabricator_format_timestamp($project->getDateCreated()); + + $content = + '
    +

    Basic Information

    +
    + + + + + + + + + + + + + + + + + +
    Creator'.$handles[$project->getAuthorPHID()]->renderLink().'
    Created'.$timestamp.'
    PHID'.phutil_escape_html($project->getPHID()).'
    Blurb'.$blurb.'
    +
    +
    '; + + $content .= + '
    +

    Resources

    +
    '. + $affiliated. + '
    +
    '; + + + $profile_markup = + ' + + + + +
    '. + '

    '.phutil_escape_html($project->getName()).'

    '. + '
    '. + $picture. + '
    '. + $links. + '
    '. + '
    '. + $content. + '
    '; + + return $this->buildStandardPageResponse( + $profile_markup, + array( + 'title' => $project->getName(), + )); + } + +} diff --git a/src/applications/project/controller/profile/__init__.php b/src/applications/project/controller/profile/__init__.php new file mode 100644 index 0000000000..d51116a235 --- /dev/null +++ b/src/applications/project/controller/profile/__init__.php @@ -0,0 +1,24 @@ +profileImagePHID) { + return $this->profileImagePHID; + } + // TODO: Make a separate one of these for projects. + return PhabricatorEnv::getEnvConfig('user.default-profile-image-phid'); + } + + +} diff --git a/src/applications/project/storage/profile/__init__.php b/src/applications/project/storage/profile/__init__.php new file mode 100644 index 0000000000..f7dbfa86e5 --- /dev/null +++ b/src/applications/project/storage/profile/__init__.php @@ -0,0 +1,13 @@ + true, + ) + parent::getConfiguration(); + } + + public function generatePHID() { + return PhabricatorPHID::generateNewPHID('PROJ'); + } + +} diff --git a/src/applications/project/storage/project/__init__.php b/src/applications/project/storage/project/__init__.php new file mode 100644 index 0000000000..89105fe95c --- /dev/null +++ b/src/applications/project/storage/project/__init__.php @@ -0,0 +1,13 @@ +