diff --git a/PHPCI/Controller/ProjectController.php b/PHPCI/Controller/ProjectController.php
index 38986c59..1906fb8c 100644
--- a/PHPCI/Controller/ProjectController.php
+++ b/PHPCI/Controller/ProjectController.php
@@ -20,6 +20,7 @@ use PHPCI\Helper\Github;
use PHPCI\Helper\SshKey;
use PHPCI\Model\Build;
use PHPCI\Model\Project;
+use PHPCI\Service\ProjectService;
/**
* Project Controller - Allows users to create, edit and view projects.
@@ -39,10 +40,16 @@ class ProjectController extends \PHPCI\Controller
*/
protected $projectStore;
+ /**
+ * @var \PHPCI\Service\ProjectService
+ */
+ protected $projectService;
+
public function init()
{
$this->buildStore = Store\Factory::getStore('Build');
$this->projectStore = Store\Factory::getStore('Project');
+ $this->projectService = new ProjectService($this->projectStore);
}
/**
@@ -179,35 +186,23 @@ class ProjectController extends \PHPCI\Controller
return $view->render();
} else {
- return $this->addProject($form);
+ $title = $this->getParam('title', 'New Project');
+ $reference = $this->getParam('reference', null);
+ $type = $this->getParam('type', null);
+
+ $options = array(
+ 'ssh_private_key' => $this->getParam('key', null),
+ 'ssh_public_key' => $this->getParam('pubkey', null),
+ 'build_config' => $this->getParam('build_config', null),
+ 'allow_public_status' => $this->getParam('allow_public_status', 0),
+ );
+
+ $project = $this->projectService->createProject($title, $reference, $type, $options);
+ header('Location: '.PHPCI_URL.'project/view/' . $project->getId());
+ die;
}
}
- protected function addProject(Form $form)
- {
- $values = $form->getValues();
-
- $matches = array();
- if ($values['type'] == "gitlab" && preg_match('`^(.*)@(.*):(.*)/(.*)\.git`', $values['reference'], $matches)) {
- $info = array();
- $info['user'] = $matches[1];
- $info['domain'] = $matches[2];
- $values['access_information'] = serialize($info);
- $values['reference'] = $matches[3]."/".$matches[4];
- }
-
- $values['ssh_private_key'] = $values['key'];
- $values['ssh_public_key'] = $values['pubkey'];
-
- $project = new Project();
- $project->setValues($values);
-
- $project = $this->projectStore->save($project);
-
- header('Location: '.PHPCI_URL.'project/view/' . $project->getId());
- die;
- }
-
/**
* Edit a project. Handles both the form and processing.
*/
diff --git a/PHPCI/Service/ProjectService.php b/PHPCI/Service/ProjectService.php
new file mode 100644
index 00000000..ee2ef7b2
--- /dev/null
+++ b/PHPCI/Service/ProjectService.php
@@ -0,0 +1,105 @@
+projectStore = $projectStore;
+ }
+
+ /**
+ * Create a new project model and use the project store to save it.
+ * @param string $title
+ * @param string $type
+ * @param string $reference
+ * @param array $options
+ * @return \PHPCI\Model\Project
+ */
+ public function createProject($title, $type, $reference, $options = array())
+ {
+ // Create base project and use updateProject() to set its properties:
+ $project = new Project();
+ return $this->updateProject($project, $title, $type, $reference, $options);
+ }
+
+ /**
+ * Update the properties of a given project.
+ * @param Project $project
+ * @param string $title
+ * @param string $type
+ * @param string $reference
+ * @param array $options
+ * @return \PHPCI\Model\Project
+ */
+ public function updateProject(Project $project, $title, $type, $reference, $options = array())
+ {
+ // Set basic properties:
+ $project->setTitle($title);
+ $project->setType($type);
+ $project->setReference($reference);
+
+ // Handle extra project options:
+ if (array_key_exists('ssh_private_key', $options)) {
+ $project->setSshPrivateKey($options['ssh_private_key']);
+ }
+
+ if (array_key_exists('ssh_public_key', $options)) {
+ $project->setSshPublicKey($options['ssh_public_key']);
+ }
+
+ if (array_key_exists('build_config', $options)) {
+ $project->setBuildConfig($options['build_config']);
+ }
+
+ if (array_key_exists('allow_public_status', $options)) {
+ $project->setAllowPublicStatus((int)$options['allow_public_status']);
+ }
+
+ // Allow certain project types to set access information:
+ $this->processAccessInformation($project);
+
+ // Save and return the project:
+ return $this->projectStore->save($project);
+ }
+
+ /**
+ * In circumstances where it is necessary, populate access information based on other project properties.
+ * @see ProjectService::createProject()
+ * @param Project $project
+ */
+ protected function processAccessInformation(Project &$project)
+ {
+ $matches = array();
+ $reference = $project->getReference();
+
+ if ($project->getType() == 'gitlab' && preg_match('`^(.*)@(.*):(.*)/(.*)\.git`', $reference, $matches)) {
+ $info = array();
+ $info['user'] = $matches[1];
+ $info['domain'] = $matches[2];
+
+ /** @todo At a later date, we need to find a way to replace this serialized data with JSON */
+ $project->setAccessInformation(serialize($info));
+ $project->setReference($matches[3] . '/' . $matches[4]);
+ }
+ }
+}
diff --git a/Tests/PHPCI/Service/MockProjectStore.php b/Tests/PHPCI/Service/MockProjectStore.php
new file mode 100644
index 00000000..a19f5e69
--- /dev/null
+++ b/Tests/PHPCI/Service/MockProjectStore.php
@@ -0,0 +1,15 @@
+setId(1);
+ return $project;
+ }
+}
diff --git a/Tests/PHPCI/Service/ProjectServiceTest.php b/Tests/PHPCI/Service/ProjectServiceTest.php
new file mode 100644
index 00000000..b0ff30d6
--- /dev/null
+++ b/Tests/PHPCI/Service/ProjectServiceTest.php
@@ -0,0 +1,101 @@
+
+ */
+class ProjectServiceTest extends \PHPUnit_Framework_TestCase
+{
+
+ /**
+ * @var ProjectService $testedService
+ */
+ protected $testedService;
+
+ /**
+ * @var \ $mockProjectStore
+ */
+ protected $mockProjectStore;
+
+ public function setUp()
+ {
+ $this->mockProjectStore = new MockProjectStore();
+ $this->testedService = new ProjectService($this->mockProjectStore);
+ }
+
+ /**
+ * @covers PHPUnit::execute
+ */
+ public function testExecute_CreateBasicProject()
+ {
+ $returnValue = $this->testedService->createProject('Test Project', 'github', 'block8/phpci');
+
+ $this->assertEquals('Test Project', $returnValue->getTitle());
+ $this->assertEquals('github', $returnValue->getType());
+ $this->assertEquals('block8/phpci', $returnValue->getReference());
+ }
+
+ /**
+ * @covers PHPUnit::execute
+ */
+ public function testExecute_CreateProjectWithOptions()
+ {
+ $options = array(
+ 'ssh_private_key' => 'private',
+ 'ssh_public_key' => 'public',
+ 'allow_public_status' => 1,
+ 'build_config' => 'config',
+ );
+
+ $returnValue = $this->testedService->createProject('Test Project', 'github', 'block8/phpci', $options);
+
+ $this->assertEquals('private', $returnValue->getSshPrivateKey());
+ $this->assertEquals('public', $returnValue->getSshPublicKey());
+ $this->assertEquals('config', $returnValue->getBuildConfig());
+ $this->assertEquals(1, $returnValue->getAllowPublicStatus());
+ }
+
+ /**
+ * @link https://github.com/Block8/PHPCI/issues/484
+ * @covers PHPUnit::execute
+ */
+ public function testExecute_CreateGitlabProjectWithoutPort()
+ {
+ $reference = 'git@gitlab.block8.net:block8/phpci.git';
+ $returnValue = $this->testedService->createProject('Gitlab', 'gitlab', $reference);
+
+ $this->assertEquals('git', $returnValue->getAccessInformation('user'));
+ $this->assertEquals('gitlab.block8.net', $returnValue->getAccessInformation('domain'));
+ $this->assertEquals('block8/phpci', $returnValue->getReference());
+ }
+
+ /**
+ * @covers PHPUnit::execute
+ */
+ public function testExecute_UpdateExistingProject()
+ {
+ $project = new Project();
+ $project->setTitle('Before Title');
+ $project->setReference('Before Reference');
+ $project->setType('github');
+
+ $returnValue = $this->testedService->updateProject($project, 'After Title', 'bitbucket', 'After Reference');
+
+ $this->assertEquals('After Title', $returnValue->getTitle());
+ $this->assertEquals('After Reference', $returnValue->getReference());
+ $this->assertEquals('bitbucket', $returnValue->getType());
+ }
+}
diff --git a/phpunit.xml b/phpunit.xml
index 15bd43aa..0e1d6810 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -20,5 +20,8 @@
./Tests/PHPCI/Plugin
+
+ ./Tests/PHPCI/Service
+