Compare commits

...

33 commits

Author SHA1 Message Date
Marco Vito Moscaritolo d22211c4b4 Improved docs. 2015-07-19 20:09:27 +02:00
Marco Vito Moscaritolo da17482a80 Move BuildFactory to factory.build service. 2015-07-19 20:08:25 +02:00
Marco Vito Moscaritolo 6aba86e018 Improved docBlock 2015-05-31 18:19:52 +02:00
Marco Vito Moscaritolo be651b3576 Fixed parameter. 2015-05-31 17:48:09 +02:00
Marco Vito Moscaritolo 7693993df8 Fixed PHPCI in plugins. 2015-05-31 17:44:52 +02:00
Marco Vito Moscaritolo 4fe62ea248 Fixed PHPCS. 2015-05-31 17:39:52 +02:00
Marco Vito Moscaritolo e0803df283 Fixed dockblock. 2015-05-31 17:32:03 +02:00
Marco Vito Moscaritolo 9d03112aed Fixed indendentation. 2015-05-31 17:26:53 +02:00
Marco Vito Moscaritolo b1e387e195 Shields.io integration cleanup. 2015-05-31 17:09:17 +02:00
Marco Vito Moscaritolo f125047951 Use a HttpClient service to get the shield.io badge. 2015-05-31 16:56:42 +02:00
Marco Vito Moscaritolo e977360083 Added BuildStatus::ccxml tests. 2015-05-31 16:32:50 +02:00
Marco Vito Moscaritolo 180bdcf4fe Improve CS. 2015-05-31 16:01:51 +02:00
Marco Vito Moscaritolo 7d9e065963 Fixed tests after DIC introduction refactoring. 2015-05-31 15:19:20 +02:00
Marco Vito Moscaritolo 98221397b5 Check about bootstrap for test phase. 2015-05-31 15:15:38 +02:00
Marco Vito Moscaritolo 4b957e8d5d Daemon application using DIC. 2015-05-31 15:06:45 +02:00
Marco Vito Moscaritolo 56082f201b Controller are now services. 2015-05-31 13:31:34 +02:00
Marco Vito Moscaritolo b6f25e77c3 Load controller as services. 2015-05-31 13:31:16 +02:00
Marco Vito Moscaritolo 601d42ea6e Added container service into application. 2015-05-31 13:30:38 +02:00
Marco Vito Moscaritolo 7e71e2ec7b User services in rebuild command. 2015-05-31 11:43:21 +02:00
Marco Vito Moscaritolo 6a43003f24 User services in rebuild command. 2015-05-31 11:41:18 +02:00
Marco Vito Moscaritolo a461fb580d Update poll command to use services. 2015-05-31 11:33:44 +02:00
Marco Vito Moscaritolo 86de54b658 Use config as service. 2015-05-31 11:20:31 +02:00
Marco Vito Moscaritolo 455f9a59a8 Remove unrequired parameters from CLI command constructors. 2015-05-31 11:20:18 +02:00
Marco Vito Moscaritolo bfe21bc687 Remove unrequired parameters from CLI command constructors. 2015-05-31 11:18:04 +02:00
Marco Vito Moscaritolo 5a516732ed Move process controlll initialization in config. 2015-05-31 11:13:16 +02:00
Marco Vito Moscaritolo e4e08e32b0 Use user service to manage user on admin command. 2015-05-31 11:06:19 +02:00
Marco Vito Moscaritolo 74ed1b14e1 Use user service to manage user on admin command. 2015-05-31 11:05:49 +02:00
Marco Vito Moscaritolo 063bec407d Move CLI app to use DIC. 2015-05-31 11:01:40 +02:00
Marco Vito Moscaritolo 3eb1648e13 Swtich DIC to symfony container. 2015-05-31 10:33:27 +02:00
Marco Vito Moscaritolo a0e72b9bc7 Remove new instance of each store. 2015-05-30 23:24:14 +02:00
Marco Vito Moscaritolo a9545e4104 Added store.entity services and fixed application to use it. 2015-05-30 23:20:13 +02:00
Marco Vito Moscaritolo ebf5a5dd7b First draft of DIC initialization with config. 2015-05-30 23:04:47 +02:00
Marco Vito Moscaritolo 65aba6b3c6 Update pimple to version 3. 2015-05-30 21:33:48 +02:00
37 changed files with 1071 additions and 387 deletions

View file

@ -11,9 +11,14 @@ namespace PHPCI;
use b8;
use b8\Exception\HttpException;
use b8\Http\Request;
use b8\Http\Response;
use b8\Http\Response\RedirectResponse;
use b8\Http\Router;
use b8\View;
use PHPCI\Store\UserStore;
use PHPCI\Store\ProjectStore;
use Symfony\Component\DependencyInjection\Container;
/**
* PHPCI Front Controller
@ -26,6 +31,46 @@ class Application extends b8\Application
*/
protected $controller;
/**
* @var \PHPCI\Store\UserStore
*/
protected $userStore;
/**
* @var \PHPCI\Store\ProjectStore
*/
protected $projectStore;
/**
* Create the PHPCI web application.
*
* @param Config $config
* @param Request $request
* @param Response $response
* @param UserStore $userStore
* @param ProjectStore $projectStore
* @param Container $container
*/
public function __construct(
Config $config,
Request $request,
Response $response,
UserStore $userStore,
ProjectStore $projectStore,
Container $container
) {
$this->config = $config;
$this->response = $response;
$this->request = $request;
$this->userStore = $userStore;
$this->projectStore = $projectStore;
$this->container = $container;
$this->router = new Router($this, $this->request, $this->config);
$this->init();
}
/**
* Initialise PHPCI - Handles session verification, routing, etc.
*/
@ -38,7 +83,7 @@ class Application extends b8\Application
// Inlined as a closure to fix "using $this when not in object context" on 5.3
$validateSession = function () {
if (!empty($_SESSION['phpci_user_id'])) {
$user = b8\Store\Factory::getStore('User')->getByPrimaryKey($_SESSION['phpci_user_id']);
$user = $this->userStore->getByPrimaryKey($_SESSION['phpci_user_id']);
if ($user) {
$_SESSION['phpci_user'] = $user;
@ -106,8 +151,7 @@ class Application extends b8\Application
if ($this->response->hasLayout() && $this->controller->layout) {
$this->setLayoutVariables($this->controller->layout);
$this->controller->layout->content = $this->response->getContent();
$this->controller->layout->content = $this->response->getContent();
$this->response->setContent($this->controller->layout->render());
}
@ -115,29 +159,49 @@ class Application extends b8\Application
}
/**
* Loads a particular controller, and injects our layout view into it.
* @param $class
* @return mixed
* @return \PHPCI\Controller
*/
protected function loadController($class)
public function getController()
{
$controller = parent::loadController($class);
$controller->layout = new View('layout');
$controller->layout->title = 'PHPCI';
$controller->layout->breadcrumb = array();
if (empty($this->controller)) {
$this->controller = $this->container->get($this->getControllerId($this->route));
}
return $controller;
return $this->controller;
}
/**
* Check if the specified controller exist.
*
* @param array $route
*
* @return boolean
*/
public function controllerExists($route)
{
return $this->container->has($this->getControllerId($route));
}
/**
* Create controller service Id based on specified route.
*
* @param array $route
*
* @return string
*/
protected function getControllerId($route)
{
return 'application.controller.' . strtolower($route['controller']);
}
/**
* Injects variables into the layout before rendering it.
*
* @param View $layout
*/
protected function setLayoutVariables(View &$layout)
{
/** @var \PHPCI\Store\ProjectStore $projectStore */
$projectStore = b8\Store\Factory::getStore('Project');
$layout->projects = $projectStore->getWhere(
$layout->projects = $this->projectStore->getWhere(
array('archived' => (int)isset($_GET['archived'])),
50,
0,
@ -148,17 +212,16 @@ class Application extends b8\Application
/**
* Check whether we should skip auth (because it is disabled)
*
* @return bool
*/
protected function shouldSkipAuth()
{
$config = b8\Config::getInstance();
$state = (bool)$config->get('phpci.authentication_settings.state', false);
$userId = $config->get('phpci.authentication_settings.user_id', 0);
$state = (bool) $this->config->get('phpci.authentication_settings.state', false);
$userId = $this->config->get('phpci.authentication_settings.user_id', 0);
if (false !== $state && 0 != (int)$userId) {
$user = b8\Store\Factory::getStore('User')
->getByPrimaryKey($userId);
$user = $this->userStore->getByPrimaryKey($userId);
if ($user) {
$_SESSION['phpci_user'] = $user;

View file

@ -11,6 +11,7 @@ namespace PHPCI;
use b8\Store\Factory;
use PHPCI\Model\Build;
use PHPCI\Store\BuildStore;
/**
* PHPCI Build Factory - Takes in a generic "Build" and returns a type-specific build model.
@ -18,20 +19,30 @@ use PHPCI\Model\Build;
*/
class BuildFactory
{
/**
* @var BuildStore
*/
protected $buildStore;
public function __construct(BuildStore $buildStore)
{
$this->buildStore = $buildStore;
}
/**
* @param $buildId
* @return Build
* @throws \Exception
*/
public static function getBuildById($buildId)
public function getBuildById($buildId)
{
$build = Factory::getStore('Build')->getById($buildId);
$build = $this->buildStore->getById($buildId);
if (empty($build)) {
throw new \Exception('Build ID ' . $buildId . ' does not exist.');
}
return self::getBuild($build);
return $this->getBuild($build);
}
/**
@ -39,7 +50,7 @@ class BuildFactory
* @param Build $base The build from which to get a more specific build type.
* @return Build
*/
public static function getBuild(Build $base)
public function getBuild(Build $base)
{
switch($base->getProject()->getType())
{

View file

@ -99,6 +99,7 @@ class Builder implements LoggerAwareInterface
/**
* Set up the builder.
*
* @param \PHPCI\Model\Build $build
* @param LoggerInterface $logger
*/
@ -130,6 +131,7 @@ class Builder implements LoggerAwareInterface
/**
* Set the config array, as read from phpci.yml
*
* @param array|null $config
* @throws \Exception
*/
@ -144,6 +146,7 @@ class Builder implements LoggerAwareInterface
/**
* Access a variable from the phpci.yml file.
*
* @param string
* @return mixed
*/
@ -160,6 +163,7 @@ class Builder implements LoggerAwareInterface
/**
* Access a variable from the config.yml
*
* @param $key
* @return mixed
*/
@ -259,6 +263,7 @@ class Builder implements LoggerAwareInterface
/**
* Find a binary required by a plugin.
*
* @param string $binary
* @param bool $quiet
*
@ -272,6 +277,7 @@ class Builder implements LoggerAwareInterface
/**
* Replace every occurrence of the interpolation vars in the given string
* Example: "This is build %PHPCI_BUILD%" => "This is build 182"
*
* @param string $input
* @return string
*/
@ -328,6 +334,7 @@ class Builder implements LoggerAwareInterface
/**
* Write to the build log.
*
* @param $message
* @param string $level
* @param array $context
@ -339,6 +346,7 @@ class Builder implements LoggerAwareInterface
/**
* Add a success-coloured message to the log.
*
* @param string
*/
public function logSuccess($message)
@ -348,6 +356,7 @@ class Builder implements LoggerAwareInterface
/**
* Add a failure-coloured message to the log.
*
* @param string $message
* @param \Exception $exception The exception that caused the error.
*/
@ -359,6 +368,7 @@ class Builder implements LoggerAwareInterface
* Returns a configured instance of the plugin factory.
*
* @param Build $build
*
* @return PluginFactory
*/
private function buildPluginFactory(Build $build)

View file

@ -11,7 +11,6 @@ namespace PHPCI\Command;
use PHPCI\Service\UserService;
use PHPCI\Helper\Lang;
use PHPCI\Store\UserStore;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
@ -25,18 +24,18 @@ use Symfony\Component\Console\Output\OutputInterface;
class CreateAdminCommand extends Command
{
/**
* @var UserStore
* @var UserService
*/
protected $userStore;
protected $userService;
/**
* @param UserStore $userStore
* @param UserService $userService
*/
public function __construct(UserStore $userStore)
public function __construct(UserService $userService)
{
parent::__construct();
$this->userStore = $userStore;
$this->userService = $userService;
}
protected function configure()
@ -53,8 +52,6 @@ class CreateAdminCommand extends Command
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$userService = new UserService($this->userStore);
/** @var $dialog \Symfony\Component\Console\Helper\DialogHelper */
$dialog = $this->getHelperSet()->get('dialog');
@ -72,7 +69,7 @@ class CreateAdminCommand extends Command
$adminPass = $dialog->askHiddenResponse($output, Lang::get('enter_password'));
try {
$userService->createUser($adminName, $adminEmail, $adminPass, true);
$this->userService->createUser($adminName, $adminEmail, $adminPass, true);
$output->writeln(Lang::get('user_created'));
} catch (\Exception $e) {
$output->writeln(sprintf('<error>%s</error>', Lang::get('failed_to_create')));

View file

@ -48,11 +48,12 @@ class DaemonCommand extends Command
*/
protected $processControl;
public function __construct(Logger $logger, ProcessControlInterface $processControl = null, $name = null)
public function __construct(Logger $logger, ProcessControlInterface $processControl)
{
parent::__construct($name);
parent::__construct();
$this->logger = $logger;
$this->processControl = $processControl ?: Factory::getInstance();
$this->processControl = $processControl;
}
protected function configure()

View file

@ -47,9 +47,9 @@ class DaemoniseCommand extends Command
* @param \Monolog\Logger $logger
* @param string $name
*/
public function __construct(Logger $logger, $name = null)
public function __construct(Logger $logger)
{
parent::__construct($name);
parent::__construct();
$this->logger = $logger;
}

View file

@ -9,15 +9,16 @@
namespace PHPCI\Command;
use b8\Store\Factory;
use b8\HttpClient;
use Monolog\Logger;
use PHPCI\Helper\Lang;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Yaml\Parser;
use PHPCI\Config;
use PHPCI\Model\Build;
use PHPCI\Store\BuildStore;
use PHPCI\Store\ProjectStore;
/**
* Run console command - Poll github for latest commit id
@ -28,14 +29,39 @@ use PHPCI\Model\Build;
class PollCommand extends Command
{
/**
* @var \Monolog\Logger
* @var Config
*/
protected $config;
/**
* @var Logger
*/
protected $logger;
public function __construct(Logger $logger, $name = null)
/**
* @var BuildStore
*/
protected $buildStore;
/**
* @var ProjectStore
*/
protected $projectStore;
/**
* @var HttpClient
*/
protected $githubClient;
public function __construct(Config $config, Logger $logger, BuildStore $buildStore, ProjectStore $projectStore, HttpClient $githubClient)
{
parent::__construct($name);
parent::__construct();
$this->config = $config;
$this->logger = $logger;
$this->buildStore = $buildStore;
$this->projectStore = $projectStore;
$this->githubClient = $githubClient;
}
protected function configure()
@ -50,27 +76,19 @@ class PollCommand extends Command
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$parser = new Parser();
$yaml = file_get_contents(APPLICATION_PATH . 'PHPCI/config.yml');
$this->settings = $parser->parse($yaml);
$token = $this->settings['phpci']['github']['token'];
$token = $this->config->get('phpci.github.token');
if (!$token) {
$this->logger->error(Lang::get('no_token'));
return;
}
$buildStore = Factory::getStore('Build');
$this->logger->addInfo(Lang::get('finding_projects'));
$projectStore = Factory::getStore('Project');
$result = $projectStore->getWhere();
$result = $this->projectStore->getWhere();
$this->logger->addInfo(Lang::get('found_n_projects', count($result['items'])));
foreach ($result['items'] as $project) {
$http = new HttpClient('https://api.github.com');
$commits = $http->get('/repos/' . $project->getReference() . '/commits', array('access_token' => $token));
$commits = $this->githubClient->get('/repos/' . $project->getReference() . '/commits', array('access_token' => $token));
$last_commit = $commits['body'][0]['sha'];
$last_committer = $commits['body'][0]['commit']['committer']['email'];
@ -89,14 +107,14 @@ class PollCommand extends Command
$build->setStatus(Build::STATUS_NEW);
$build->setBranch($project->getBranch());
$build->setCreated(new \DateTime());
$build->setCommitMessage($message);
$build->setCommitMessage($message);
if (!empty($last_committer)) {
$build->setCommitterEmail($last_committer);
}
$buildStore->save($build);
$this->buildStore->save($build);
$project->setLastCommit($last_commit);
$projectStore->save($project);
$this->projectStore->save($project);
}
}

View file

@ -12,6 +12,7 @@ namespace PHPCI\Command;
use b8\Store\Factory;
use Monolog\Logger;
use PHPCI\Service\BuildService;
use PHPCI\Store\BuildStore;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Input\InputInterface;
@ -46,13 +47,28 @@ class RebuildCommand extends Command
protected $sleep;
/**
* @param \Monolog\Logger $logger
* @param string $name
* @param BuildStore
*/
public function __construct(Logger $logger, $name = null)
protected $buildStore;
/**
* @param BuildService
*/
protected $buildService;
/**
* @param RunCommand
*/
protected $runCommand;
public function __construct(Logger $logger, BuildStore $buildStore, BuildService $buildService, RunCommand $runCommand)
{
parent::__construct($name);
parent::__construct();
$this->logger = $logger;
$this->buildStore = $buildStore;
$this->buildService = $buildService;
$this->runCommand = $runCommand;
}
protected function configure()
@ -67,17 +83,12 @@ class RebuildCommand extends Command
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$runner = new RunCommand($this->logger);
$runner->setMaxBuilds(1);
$runner->setDaemon(false);
$this->runCommand->setMaxBuilds(1);
$this->runCommand->setDaemon(false);
/** @var \PHPCI\Store\BuildStore $store */
$store = Factory::getStore('Build');
$service = new BuildService($store);
$builds = $store->getLatestBuilds(null, 1);
$builds = $this->buildStore->getLatestBuilds(null, 1);
$lastBuild = array_shift($builds);
$service->createDuplicateBuild($lastBuild);
$this->buildService->createDuplicateBuild($lastBuild);
$runner->run(new ArgvInput(array()), $output);
}

View file

@ -41,6 +41,11 @@ class RunCommand extends Command
*/
protected $logger;
/**
* @var BuildFactory
*/
protected $buildFactory;
/**
* @var int
*/
@ -52,12 +57,14 @@ class RunCommand extends Command
protected $isFromDaemon = false;
/**
* @param \Monolog\Logger $logger
* @param string $name
* @param BuildFactory $buildFactory
* @param Logger $logger
*/
public function __construct(Logger $logger, $name = null)
public function __construct(BuildFactory $buildFactory, Logger $logger)
{
parent::__construct($name);
parent::__construct();
$this->buildFactory = $buildFactory;
$this->logger = $logger;
}
@ -95,7 +102,7 @@ class RunCommand extends Command
while (count($result['items'])) {
$build = array_shift($result['items']);
$build = BuildFactory::getBuild($build);
$build = $this->buildFactory->getBuild($build);
// Skip build (for now) if there's already a build running in that project:
if (!$this->isFromDaemon && in_array($build->getProjectId(), $running)) {
@ -156,7 +163,7 @@ class RunCommand extends Command
foreach ($running['items'] as $build) {
/** @var \PHPCI\Model\Build $build */
$build = BuildFactory::getBuild($build);
$build = $this->buildFactory->getBuild($build);
$now = time();
$start = $build->getStarted()->getTimestamp();

View file

@ -9,7 +9,7 @@
namespace PHPCI\Command;
use b8\Config;
use PHPCI\Config;
use Monolog\Logger;
use PHPCI\Helper\Lang;
use Symfony\Component\Console\Command\Command;
@ -29,10 +29,17 @@ class UpdateCommand extends Command
*/
protected $logger;
public function __construct(Logger $logger, $name = null)
/**
* @var Config
*/
protected $config;
public function __construct(Logger $logger, Config $config)
{
parent::__construct($name);
parent::__construct();
$this->logger = $logger;
$this->config = $config;
}
protected function configure()
@ -60,8 +67,7 @@ class UpdateCommand extends Command
protected function verifyInstalled(OutputInterface $output)
{
$config = Config::getInstance();
$phpciUrl = $config->get('phpci.url');
$phpciUrl = $this->config->get('phpci.url');
return !empty($phpciUrl);
}

View file

@ -9,7 +9,6 @@
namespace PHPCI;
use b8\Config;
use b8\Exception\HttpException\ForbiddenException;
use b8\Http\Request;
use b8\Http\Response;
@ -53,6 +52,10 @@ class Controller extends \b8\Controller
{
parent::__construct($config, $request, $response);
$this->layout = new View('layout');
$this->layout->title = 'PHPCI';
$this->layout->breadcrumb = array();
$class = explode('\\', get_class($this));
$this->className = substr(array_pop($class), 0, -10);
$this->setControllerView();

View file

@ -12,11 +12,15 @@ namespace PHPCI\Controller;
use b8;
use b8\Exception\HttpException\NotFoundException;
use b8\Http\Response\JsonResponse;
use b8\Http\Request;
use b8\Http\Response;
use PHPCI\Config;
use PHPCI\BuildFactory;
use PHPCI\Helper\AnsiConverter;
use PHPCI\Helper\Lang;
use PHPCI\Model\Build;
use PHPCI\Model\Project;
use PHPCI\Store\BuildStore;
use PHPCI\Service\BuildService;
/**
@ -28,22 +32,42 @@ use PHPCI\Service\BuildService;
class BuildController extends \PHPCI\Controller
{
/**
* @var \PHPCI\Store\BuildStore
* @var BuildStore
*/
protected $buildStore;
/**
* @var \PHPCI\Service\BuildService
* @var BuildService
*/
protected $buildService;
/**
* Initialise the controller, set up stores and services.
* @var BuildFactory
*/
public function init()
{
$this->buildStore = b8\Store\Factory::getStore('Build');
$this->buildService = new BuildService($this->buildStore);
protected $buildFactory;
/**
* Create the Build controller
*
* @param Config $config
* @param Request $request
* @param Response $response
* @param BuildStore $buildStore
* @param BuildService $buildService
*/
public function __construct(
Config $config,
Request $request,
Response $response,
BuildStore $buildStore,
BuildService $buildService,
BuildFactory $buildFactory
) {
parent::__construct($config, $request, $response);
$this->buildStore = $buildStore;
$this->buildService = $buildService;
$this->buildFactory = $buildFactory;
}
/**
@ -52,7 +76,7 @@ class BuildController extends \PHPCI\Controller
public function view($buildId)
{
try {
$build = BuildFactory::getBuildById($buildId);
$build = $this->buildFactory->getBuildById($buildId);
} catch (\Exception $ex) {
$build = null;
}
@ -110,7 +134,7 @@ class BuildController extends \PHPCI\Controller
public function data($buildId)
{
$response = new JsonResponse();
$build = BuildFactory::getBuildById($buildId);
$build = $this->buildFactory->getBuildById($buildId);
if (!$build) {
$response->setResponseCode(404);
@ -127,7 +151,7 @@ class BuildController extends \PHPCI\Controller
*/
public function meta($buildId)
{
$build = BuildFactory::getBuildById($buildId);
$build = $this->buildFactory->getBuildById($buildId);
$key = $this->getParam('key', null);
$numBuilds = $this->getParam('num_builds', 1);
$data = null;
@ -161,7 +185,7 @@ class BuildController extends \PHPCI\Controller
*/
public function rebuild($buildId)
{
$copy = BuildFactory::getBuildById($buildId);
$copy = $this->buildFactory->getBuildById($buildId);
if (empty($copy)) {
throw new NotFoundException(Lang::get('build_x_not_found', $buildId));
@ -181,7 +205,7 @@ class BuildController extends \PHPCI\Controller
{
$this->requireAdmin();
$build = BuildFactory::getBuildById($buildId);
$build = $this->buildFactory->getBuildById($buildId);
if (empty($build)) {
throw new NotFoundException(Lang::get('build_x_not_found', $buildId));
@ -214,6 +238,7 @@ class BuildController extends \PHPCI\Controller
$response = new JsonResponse();
$response->setContent($rtn);
return $response;
}

View file

@ -11,11 +11,20 @@ namespace PHPCI\Controller;
use b8;
use b8\Exception\HttpException\NotFoundException;
use b8\Exception\HttpException\NotAuthorizedException;
use b8\Store;
use b8\HttpClient;
use b8\Http\Request;
use b8\Http\Response;
use Exception;
use PHPCI\Config;
use PHPCI\BuildFactory;
use PHPCI\Helper\Lang;
use PHPCI\Model\Project;
use PHPCI\Model\Build;
use PHPCI\Service\BuildStatusService;
use PHPCI\Store\BuildStore;
use PHPCI\Store\ProjectStore;
/**
* Build Status Controller - Allows external access to build status information / images.
@ -25,69 +34,73 @@ use PHPCI\Service\BuildStatusService;
*/
class BuildStatusController extends \PHPCI\Controller
{
/* @var \PHPCI\Store\ProjectStore */
protected $projectStore;
/* @var \PHPCI\Store\BuildStore */
/**
* @var BuildStore
*/
protected $buildStore;
/**
* Initialise the controller, set up stores and services.
* @var ProjectStore
*/
public function init()
{
$this->response->disableLayout();
$this->buildStore = Store\Factory::getStore('Build');
$this->projectStore = Store\Factory::getStore('Project');
}
protected $projectStore;
/**
* Returns status of the last build
* @param $projectId
* @return string
* @var BuildFactory
*/
protected function getStatus($projectId)
{
$branch = $this->getParam('branch', 'master');
try {
$project = $this->projectStore->getById($projectId);
$status = 'passing';
protected $buildFactory;
if (!$project->getAllowPublicStatus()) {
return null;
}
/**
* Create the BuildStatus controller.
*
* @param Config $config
* @param Request $request
* @param Response $response
* @param BuildStore $buildStore
* @param ProjectStore $projectStore
* @param HttpClient $shieldsClient
* @param BuildFactory $buildFactory
*/
public function __construct(
Config $config,
Request $request,
Response $response,
BuildStore $buildStore,
ProjectStore $projectStore,
HttpClient $shieldsClient,
BuildFactory $buildFactory
) {
parent::__construct($config, $request, $response);
if (isset($project) && $project instanceof Project) {
$build = $project->getLatestBuild($branch, array(2,3));
if (isset($build) && $build instanceof Build && $build->getStatus() != 2) {
$status = 'failed';
}
}
} catch (\Exception $e) {
$status = 'error';
}
return $status;
$this->buildStore = $buildStore;
$this->projectStore = $projectStore;
$this->shieldsClient = $shieldsClient;
$this->buildFactory = $buildFactory;
}
/**
* Displays projects information in ccmenu format
*
* @param $projectId
* @return bool
* @throws \Exception
* @throws b8\Exception\HttpException
* @param int $projectId
*
* @return Response
*
* @throws Exception
* @throws HttpException
*/
public function ccxml($projectId)
{
/* @var Project $project */
$project = $this->projectStore->getById($projectId);
$xml = new \SimpleXMLElement('<Projects/>');
if (!$project instanceof Project || !$project->getAllowPublicStatus()) {
return $this->renderXml($xml);
if (!$project instanceof Project) {
throw new NotFoundException(Lang::get('project_x_not_found', $projectId));
}
if (!$project->getAllowPublicStatus()) {
throw new NotAuthorizedException();
}
$xml = new \SimpleXMLElement('<Projects/>');
try {
$branchList = $this->buildStore->getBuildBranches($projectId);
@ -104,56 +117,51 @@ class BuildStatusController extends \PHPCI\Controller
}
}
}
} catch (\Exception $e) {
$xml = new \SimpleXMLElement('<projects/>');
}
return $this->renderXml($xml);
}
/**
* @param \SimpleXMLElement $xml
* @return bool
*/
protected function renderXml(\SimpleXMLElement $xml = null)
{
$this->response->disableLayout();
$this->response->setHeader('Content-Type', 'text/xml');
$this->response->setContent($xml->asXML());
$this->response->flush();
echo $xml->asXML();
return true;
return $this->response;
}
/**
* Returns the appropriate build status image in SVG format for a given project.
*
* @param int $projectId
*
* @return Response
*/
public function image($projectId)
{
$style = $this->getParam('style', 'plastic');
$label = $this->getParam('label', 'build');
$project = $this->projectStore->getById($projectId);
$status = $this->getStatus($projectId);
if (is_null($status)) {
$response = new b8\Http\Response\RedirectResponse();
$response->setHeader('Location', '/');
return $response;
if (empty($project)) {
throw new NotFoundException(Lang::get('project_x_not_found', $projectId));
}
if (!$project->getAllowPublicStatus()) {
throw new NotAuthorizedException();
}
$style = $this->getParam('style', 'plastic');
$label = $this->getParam('label', 'build');
$branch = $this->getParam('branch', 'master');
$status = $this->getStatus($project, $branch);
$color = ($status == 'passing') ? 'green' : 'red';
$image = file_get_contents(sprintf(
'http://img.shields.io/badge/%s-%s-%s.svg?style=%s',
$label,
$status,
$color,
$style
));
$image = $this->shieldsClient->get(
sprintf('/badge/%s-%s-%s.svg', $label, $status, $color),
array('style' => $style)
);
$this->response->disableLayout();
$this->response->setHeader('Content-Type', 'image/svg+xml');
$this->response->setContent($image);
$this->response->setContent($image['body']);
return $this->response;
}
@ -168,11 +176,11 @@ class BuildStatusController extends \PHPCI\Controller
$project = $this->projectStore->getById($projectId);
if (empty($project)) {
throw new NotFoundException('Project with id: ' . $projectId . ' not found');
throw new NotFoundException(Lang::get('project_x_not_found', $projectId));
}
if (!$project->getAllowPublicStatus()) {
throw new NotFoundException('Project with id: ' . $projectId . ' not found');
throw new NotAuthorizedException();
}
$builds = $this->getLatestBuilds($projectId);
@ -197,9 +205,33 @@ class BuildStatusController extends \PHPCI\Controller
$builds = $this->buildStore->getWhere($criteria, 10, 0, array(), $order);
foreach ($builds['items'] as &$build) {
$build = BuildFactory::getBuild($build);
$build = $this->buildFactory->getBuild($build);
}
return $builds['items'];
}
/**
* Returns status of the last build
*
* @param int $projectId
*
* @return string
*
* @throws Exception
*/
protected function getStatus($project, $branch)
{
try {
$build = $project->getLatestBuild($branch, array(2,3));
if (isset($build) && $build instanceof Build && $build->getStatus() != 2) {
return 'failed';
}
} catch (Exception $e) {
return 'error';
}
return 'passing';
}
}

View file

@ -10,9 +10,14 @@
namespace PHPCI\Controller;
use b8;
use b8\Http\Request;
use b8\Http\Response;
use PHPCI\Config;
use PHPCI\BuildFactory;
use PHPCI\Helper\Lang;
use PHPCI\Model\Build;
use PHPCI\Store\BuildStore;
use PHPCI\Store\ProjectStore;
/**
* Home Controller - Displays the PHPCI Dashboard.
@ -23,22 +28,43 @@ use PHPCI\Model\Build;
class HomeController extends \PHPCI\Controller
{
/**
* @var \b8\Store\BuildStore
* @var BuildStore
*/
protected $buildStore;
/**
* @var \b8\Store\ProjectStore
* @var BuildFactory
*/
protected $buildFactory;
/**
* @var ProjectStore
*/
protected $projectStore;
/**
* Initialise the controller, set up stores and services.
* Create the Home controller.
*
* @param Config $config
* @param Request $request
* @param Response $response
* @param BuildStore $buildStore
* @param ProjectStore $projectStore
* @param BuildFactory $buildFactory
*/
public function init()
{
$this->buildStore = b8\Store\Factory::getStore('Build');
$this->projectStore = b8\Store\Factory::getStore('Project');
public function __construct(
Config $config,
Request $request,
Response $response,
BuildStore $buildStore,
ProjectStore $projectStore,
BuildFactory $buildFactory
) {
parent::__construct($config, $request, $response);
$this->buildStore = $buildStore;
$this->projectStore = $projectStore;
$this->buildFactory = $buildFactory;
}
/**
@ -59,7 +85,7 @@ class HomeController extends \PHPCI\Controller
$builds = $this->buildStore->getLatestBuilds(null, 10);
foreach ($builds as &$build) {
$build = BuildFactory::getBuild($build);
$build = $this->buildFactory->getBuild($build);
}
$this->view->builds = $builds;
@ -140,7 +166,7 @@ class HomeController extends \PHPCI\Controller
$view = new b8\View('BuildsTable');
foreach ($builds['items'] as &$build) {
$build = BuildFactory::getBuild($build);
$build = $this->buildFactory->getBuild($build);
}
$view->builds = $builds['items'];

View file

@ -13,11 +13,16 @@ use b8;
use b8\Form;
use b8\Exception\HttpException\NotFoundException;
use b8\Store;
use b8\Http\Request;
use b8\Http\Response;
use PHPCI;
use PHPCI\Config;
use PHPCI\BuildFactory;
use PHPCI\Helper\Github;
use PHPCI\Helper\Lang;
use PHPCI\Helper\SshKey;
use PHPCI\Store\BuildStore;
use PHPCI\Store\ProjectStore;
use PHPCI\Service\BuildService;
use PHPCI\Service\ProjectService;
@ -30,34 +35,59 @@ use PHPCI\Service\ProjectService;
class ProjectController extends PHPCI\Controller
{
/**
* @var \PHPCI\Store\ProjectStore
* @var ProjectStore
*/
protected $projectStore;
/**
* @var \PHPCI\Service\ProjectService
* @var ProjectService
*/
protected $projectService;
/**
* @var \PHPCI\Store\BuildStore
* @var BuildStore
*/
protected $buildStore;
/**
* @var \PHPCI\Service\BuildService
* @var BuildService
*/
protected $buildService;
/**
* Initialise the controller, set up stores and services.
* @var BuildFactory
*/
public function init()
{
$this->buildStore = Store\Factory::getStore('Build');
$this->projectStore = Store\Factory::getStore('Project');
$this->projectService = new ProjectService($this->projectStore);
$this->buildService = new BuildService($this->buildStore);
protected $buildFactory;
/**
* Create the Project controller.
*
* @param Config $config
* @param Request $request
* @param Response $response
* @param BuildStore $buildStore
* @param ProjectStore $projectStore
* @param ProjectService $projectService
* @param BuildService $buildService
* @param BuildFactory $buildFactory
*/
public function __construct(
Config $config,
Request $request,
Response $response,
BuildStore $buildStore,
ProjectStore $projectStore,
ProjectService $projectService,
BuildService $buildService,
BuildFactory $buildFactory
) {
parent::__construct($config, $request, $response);
$this->buildStore = $buildStore;
$this->projectStore = $projectStore;
$this->projectService = $projectService;
$this->buildService = $buildService;
$this->buildFactory = $buildFactory;
}
/**
@ -122,8 +152,12 @@ class ProjectController extends PHPCI\Controller
}
/**
* Delete a project.
*/
* Delete a project.
*
* @param int $projectId
*
* @return Response
*/
public function delete($projectId)
{
$this->requireAdmin();
@ -169,7 +203,7 @@ class ProjectController extends PHPCI\Controller
$view = new b8\View('BuildsTable');
foreach ($builds['items'] as &$build) {
$build = BuildFactory::getBuild($build);
$build = $this->buildFactory->getBuild($build);
}
$view->builds = $builds['items'];
@ -313,7 +347,7 @@ class ProjectController extends PHPCI\Controller
'local' => Lang::get('local'),
'hg' => Lang::get('hg'),
'svn' => Lang::get('svn'),
);
);
$field = Form\Element\Select::create('type', Lang::get('where_hosted'), true);
$field->setPattern('^(github|bitbucket|gitlab|remote|local|hg|svn)');

View file

@ -10,8 +10,12 @@
namespace PHPCI\Controller;
use b8;
use b8\Http\Request;
use b8\Http\Response;
use PHPCI\Config;
use PHPCI\Helper\Email;
use PHPCI\Helper\Lang;
use PHPCI\Store\UserStore;
/**
* Session Controller - Handles user login / logout.
@ -22,22 +26,33 @@ use PHPCI\Helper\Lang;
class SessionController extends \PHPCI\Controller
{
/**
* @var \PHPCI\Store\UserStore
* @var UserStore
*/
protected $userStore;
/**
* Initialise the controller, set up stores and services.
* Create the Sesssion controller.
*
* @param Config $config
* @param Request $request
* @param Response $response
* @param UserStore $userStore
*/
public function init()
{
public function __construct(
Config $config,
Request $request,
Response $response,
UserStore $userStore
) {
parent::__construct($config, $request, $response);
$this->response->disableLayout();
$this->userStore = b8\Store\Factory::getStore('User');
$this->userStore = $userStore;
}
/**
* Handles user login (form and processing)
*/
* Handles user login (form and processing)
*/
public function login()
{
$isLoginFailure = false;

View file

@ -12,8 +12,12 @@ namespace PHPCI\Controller;
use b8;
use b8\Exception\HttpException\NotFoundException;
use b8\Form;
use b8\Http\Request;
use b8\Http\Response;
use PHPCI\Config;
use PHPCI\Controller;
use PHPCI\Helper\Lang;
use PHPCI\Store\UserStore;
use PHPCI\Service\UserService;
/**
@ -25,22 +29,35 @@ use PHPCI\Service\UserService;
class UserController extends Controller
{
/**
* @var \PHPCI\Store\UserStore
* @var UserStore
*/
protected $userStore;
/**
* @var \PHPCI\Service\UserService
* @var UserService
*/
protected $userService;
/**
* Initialise the controller, set up stores and services.
* Create the User controller.
*
* @param Config $config
* @param Request $request
* @param Response $response
* @param UserStore $userStore
* @param UserService $userService
*/
public function init()
{
$this->userStore = b8\Store\Factory::getStore('User');
$this->userService = new UserService($this->userStore);
public function __construct(
Config $config,
Request $request,
Response $response,
UserStore $userStore,
UserService $userService
) {
parent::__construct($config, $request, $response);
$this->userStore = $userStore;
$this->userService = $userService;
}
/**
@ -48,8 +65,8 @@ class UserController extends Controller
*/
public function index()
{
$users = $this->userStore->getWhere(array(), 1000, 0, array(), array('email' => 'ASC'));
$this->view->users = $users;
$users = $this->userStore->getWhere(array(), 1000, 0, array(), array('email' => 'ASC'));
$this->view->users = $users;
$this->layout->title = Lang::get('manage_users');
@ -275,8 +292,14 @@ class UserController extends Controller
}
/**
* Delete a user.
*/
* Delete a user.
*
* @param int $userId
*
* @return Response
*
* @throws NotFoundException
*/
public function delete($userId)
{
$this->requireAdmin();
@ -291,6 +314,7 @@ class UserController extends Controller
$response = new b8\Http\Response\RedirectResponse();
$response->setHeader('Location', PHPCI_URL . 'user');
return $response;
}
}

View file

@ -11,7 +11,10 @@ namespace PHPCI\Controller;
use b8;
use b8\Store;
use b8\Http\Request;
use b8\Http\Response;
use Exception;
use PHPCI\Config;
use PHPCI\BuildFactory;
use PHPCI\Model\Project;
use PHPCI\Service\BuildService;
@ -46,13 +49,36 @@ class WebhookController extends \b8\Controller
protected $buildService;
/**
* Initialise the controller, set up stores and services.
* @var BuildFactory
*/
public function init()
{
$this->buildStore = Store\Factory::getStore('Build');
$this->projectStore = Store\Factory::getStore('Project');
$this->buildService = new BuildService($this->buildStore);
protected $buildFactory;
/**
* Create the Webhook controller.
*
* @param Config $config
* @param Request $request
* @param Response $response
* @param BuildStore $buildStore
* @param ProjectStore $projectStore
* @param BuildService $buildService
* @param BuildFactory $buildFactory
*/
public function __construct(
Config $config,
Request $request,
Response $response,
BuildStore $buildStore,
ProjectStore $projectStore,
BuildService $buildService,
BuildFactory $buildFactory
) {
parent::__construct($config, $request, $response);
$this->buildStore = $buildStore;
$this->projectStore = $projectStore;
$this->buildService = $buildService;
$this->buildFactory = $buildFactory;
}
/** Handle the action, Ensuring to return a JsonResponse.
@ -364,7 +390,7 @@ class WebhookController extends \b8\Controller
// If not, create a new build job for it:
$build = $this->buildService->createBuild($project, $commitId, $branch, $committer, $commitMessage, $extra);
$build = BuildFactory::getBuild($build);
$build = $this->buildFactory->getBuild($build);
// Send a status postback if the build type provides one:
$build->sendStatusPostback();

View file

@ -34,9 +34,19 @@ abstract class BaseCommandExecutor implements CommandExecutor
*/
protected $verbose;
/**
* @var string
*/
protected $lastOutput;
/**
* @var string
*/
protected $lastError;
/**
* @var bool
*/
public $logExecOutput = true;
/**

View file

@ -12,15 +12,17 @@ namespace PHPCI\Helper;
use b8\Config;
/**
* Login Is Disabled Helper - Checks if login is disalbed in the view
* @author Stephen Ball <phpci@stephen.rebelinblue.com>
* @package PHPCI
* @subpackage Web
*/
* Login Is Disabled Helper - Checks if login is disalbed in the view
*
* @author Stephen Ball <phpci@stephen.rebelinblue.com>
* @package PHPCI
* @subpackage Web
*/
class LoginIsDisabled
{
/**
* Checks if
*
* @param $method
* @param array $params
* @return mixed|null
@ -28,7 +30,7 @@ class LoginIsDisabled
public function __call($method, $params = array())
{
unset($method, $params);
$config = Config::getInstance();
$state = (bool) $config->get('phpci.authentication_settings.state', false);

View file

@ -11,6 +11,7 @@ namespace PHPCI\Helper;
/**
* Class MailerFactory helps to set up and configure a SwiftMailer object.
*
* @package PHPCI\Helper
*/
class MailerFactory
@ -22,6 +23,7 @@ class MailerFactory
/**
* Set the mailer factory configuration.
*
* @param array $config
*/
public function __construct($config = array())
@ -34,7 +36,8 @@ class MailerFactory
}
/**
* Returns an instance of Swift_Mailer based on the config.s
* Returns an instance of Swift_Mailer based on the config.
*
* @return \Swift_Mailer
*/
public function getSwiftMailerFromConfig()
@ -61,7 +64,9 @@ class MailerFactory
/**
* Return a specific configuration value by key.
*
* @param $configName
*
* @return null|string
*/
public function getMailConfig($configName)
@ -70,7 +75,6 @@ class MailerFactory
return $this->emailConfig[$configName];
} else {
// Check defaults
switch($configName) {
case 'smtp_address':
return "localhost";

View file

@ -137,13 +137,11 @@ class Codeception implements \PHPCI\Plugin, \PHPCI\ZeroConfigPlugin
$configPath = $this->phpci->buildPath . $configPath;
$success = $this->phpci->executeCommand($cmd, $this->phpci->buildPath, $configPath);
$this->phpci->log(
'Codeception XML path: '. $this->phpci->buildPath . $this->path . 'report.xml',
Loglevel::DEBUG
);
$xml = file_get_contents($this->phpci->buildPath . $this->path . 'report.xml', false);
$this->phpci->log(
'Codeception XML path: '. $this->phpci->buildPath . $this->path . 'report.xml',
Loglevel::DEBUG
);
$xml = file_get_contents($this->phpci->buildPath . $this->path . 'report.xml', false);
$parser = new Parser($this->phpci, $xml);
$output = $parser->parse();

View file

@ -2,6 +2,8 @@
namespace PHPCI\Plugin\Util;
use Pimple\Container;
/**
* Plugin Factory - Loads Plugins and passes required dependencies.
* @package PHPCI\Plugin\Util
@ -15,19 +17,19 @@ class Factory
private $currentPluginOptions;
/**
* @var \Pimple
* @var Container
*/
private $container;
/**
* @param \Pimple $container
* @param Container $container
*/
public function __construct(\Pimple $container = null)
public function __construct(Container $container = null)
{
if ($container) {
$this->container = $container;
} else {
$this->container = new \Pimple();
$this->container = new Container();
}
$self = $this;

View file

@ -22,8 +22,10 @@ class BuildMetaStoreBase extends Store
/**
* Returns a BuildMeta model by primary key.
*
* @param mixed $value
* @param string $useConnection
*
* @return \@appNamespace\Model\BuildMeta|null
*/
public function getByPrimaryKey($value, $useConnection = 'read')
@ -33,10 +35,13 @@ class BuildMetaStoreBase extends Store
/**
* Returns a BuildMeta model by Id.
*
* @param mixed $value
* @param string $useConnection
* @throws HttpException
*
* @return \@appNamespace\Model\BuildMeta|null
*
* @throws HttpException
*/
public function getById($value, $useConnection = 'read')
{
@ -59,11 +64,14 @@ class BuildMetaStoreBase extends Store
/**
* Returns an array of BuildMeta models by ProjectId.
*
* @param mixed $value
* @param int $limit
* @param string $useConnection
* @throws HttpException
*
* @return array
*
* @throws HttpException
*/
public function getByProjectId($value, $limit = 1000, $useConnection = 'read')
{
@ -71,7 +79,6 @@ class BuildMetaStoreBase extends Store
throw new HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.');
}
$query = 'SELECT * FROM `build_meta` WHERE `project_id` = :project_id LIMIT :limit';
$stmt = Database::getConnection($useConnection)->prepare($query);
$stmt->bindValue(':project_id', $value);
@ -95,11 +102,14 @@ class BuildMetaStoreBase extends Store
/**
* Returns an array of BuildMeta models by BuildId.
*
* @param mixed $value
* @param int $limit
* @param string $useConnection
* @throws HttpException
*
* @return array
*
* @throws HttpException
*/
public function getByBuildId($value, $limit = 1000, $useConnection = 'read')
{
@ -107,7 +117,6 @@ class BuildMetaStoreBase extends Store
throw new HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.');
}
$query = 'SELECT * FROM `build_meta` WHERE `build_id` = :build_id LIMIT :limit';
$stmt = Database::getConnection($useConnection)->prepare($query);
$stmt->bindValue(':build_id', $value);

View file

@ -22,8 +22,10 @@ class BuildStoreBase extends Store
/**
* Returns a Build model by primary key.
*
* @param mixed $value
* @param string $useConnection
*
* @return \@appNamespace\Model\Build|null
*/
public function getByPrimaryKey($value, $useConnection = 'read')
@ -33,10 +35,13 @@ class BuildStoreBase extends Store
/**
* Returns a Build model by Id.
*
* @param mixed $value
* @param string $useConnection
* @throws HttpException
*
* @return \@appNamespace\Model\Build|null
*
* @throws HttpException
*/
public function getById($value, $useConnection = 'read')
{
@ -59,10 +64,13 @@ class BuildStoreBase extends Store
/**
* Returns an array of Build models by ProjectId.
*
* @param mixed $value
* @param int $limit
* @param string $useConnection
*
* @throws HttpException
*
* @return array
*/
public function getByProjectId($value, $limit = 1000, $useConnection = 'read')
@ -95,11 +103,14 @@ class BuildStoreBase extends Store
/**
* Returns an array of Build models by Status.
*
* @param mixed $value
* @param int $limit
* @param string $useConnection
* @throws HttpException
*
* @return array
*
* @throws HttpException
*/
public function getByStatus($value, $limit = 1000, $useConnection = 'read')
{
@ -107,7 +118,6 @@ class BuildStoreBase extends Store
throw new HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.');
}
$query = 'SELECT * FROM `build` WHERE `status` = :status LIMIT :limit';
$stmt = Database::getConnection($useConnection)->prepare($query);
$stmt->bindValue(':status', $value);

View file

@ -22,8 +22,10 @@ class ProjectStoreBase extends Store
/**
* Returns a Project model by primary key.
*
* @param mixed $value
* @param string $useConnection
*
* @return \@appNamespace\Model\Project|null
*/
public function getByPrimaryKey($value, $useConnection = 'read')
@ -33,10 +35,13 @@ class ProjectStoreBase extends Store
/**
* Returns a Project model by Id.
*
* @param mixed $value
* @param string $useConnection
* @throws HttpException
*
* @return \@appNamespace\Model\Project|null
*
* @throws HttpException
*/
public function getById($value, $useConnection = 'read')
{
@ -59,11 +64,14 @@ class ProjectStoreBase extends Store
/**
* Returns an array of Project models by Title.
*
* @param mixed $value
* @param int $limit
* @param string $useConnection
* @throws HttpException
*
* @return array
*
* @throws HttpException
*/
public function getByTitle($value, $limit = 1000, $useConnection = 'read')
{
@ -71,7 +79,6 @@ class ProjectStoreBase extends Store
throw new HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.');
}
$query = 'SELECT * FROM `project` WHERE `title` = :title LIMIT :limit';
$stmt = Database::getConnection($useConnection)->prepare($query);
$stmt->bindValue(':title', $value);

View file

@ -22,8 +22,10 @@ class UserStoreBase extends Store
/**
* Returns a User model by primary key.
*
* @param mixed $value
* @param string $useConnection
*
* @return \@appNamespace\Model\User|null
*/
public function getByPrimaryKey($value, $useConnection = 'read')
@ -33,10 +35,13 @@ class UserStoreBase extends Store
/**
* Returns a User model by Id.
*
* @param mixed $value
* @param string $useConnection
* @throws HttpException
*
* @return \@appNamespace\Model\User|null
*
* @throws HttpException
*/
public function getById($value, $useConnection = 'read')
{
@ -59,10 +64,13 @@ class UserStoreBase extends Store
/**
* Returns a User model by Email.
*
* @param string $value
* @param string $useConnection
*
* @return \@appNamespace\Model\User|null
*
* @throws HttpException
* @return \@appNamespace\Model\User|null
*/
public function getByEmail($value, $useConnection = 'read')
{
@ -82,13 +90,16 @@ class UserStoreBase extends Store
return null;
}
/**
* Returns a User model by Email.
*
* @param string $value
* @param string $useConnection
* @throws HttpException
*
* @return \@appNamespace\Model\User|null
*
* @throws HttpException
*/
public function getByLoginOrEmail($value, $useConnection = 'read')
{

View file

@ -35,7 +35,7 @@ class CreateAdminCommandTest extends \PHPUnit_Framework_TestCase
parent::setup();
$this->command = $this->getMockBuilder('PHPCI\\Command\\CreateAdminCommand')
->setConstructorArgs(array($this->getMock('PHPCI\\Store\\UserStore')))
->setConstructorArgs(array($this->getMock('PHPCI\\Service\\UserService', array(), array(), '', false)))
->setMethods(array('reloadConfig'))
->getMock()
;

View file

@ -0,0 +1,131 @@
<?php
/**
* PHPCI - Continuous Integration for PHP
*
* @copyright Copyright 2014, Block 8 Limited.
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
* @link https://www.phptesting.org/
*/
namespace Tests\PHPCI\Controller;
use PHPCI\Controller\BuildStatusController;
use PHPCI\Model\Project;
use b8\Exception\HttpException\NotAuthorizedException;
use Prophecy\Argument;
class BuildStatusControllerTest extends \PHPUnit_Framework_TestCase
{
/**
* @expectedException \b8\Exception\HttpException\NotAuthorizedException
*/
public function test_ccxml_hidden_for_non_public_project()
{
$buildStore = $this->prophesize('PHPCI\Store\BuildStore');
$projectStore = $this->prophesize('PHPCI\Store\ProjectStore');
$project = new Project();
$project->setAllowPublicStatus(false);
$projectStore->getById(Argument::any())->willReturn($project);
$webController = new BuildStatusController(
$this->prophesize('PHPCI\Config')->reveal(),
$this->prophesize('b8\Http\Request')->reveal(),
new \b8\Http\Response(),
$buildStore->reveal(),
$projectStore->reveal(),
$this->prophesize('b8\HttpClient')->reveal()
);
$result = $webController->handleAction('ccxml', [1]);
}
public function test_ccxml_visible_for_public_project()
{
$buildStore = $this->prophesize('PHPCI\Store\BuildStore');
$projectStore = $this->prophesize('PHPCI\Store\ProjectStore');
$project = new Project();
$project->setId(1);
$project->setBranch('test');
$project->setAllowPublicStatus(true);
$projectStore->getById(1)->willReturn($project);
$webController = new BuildStatusController(
$this->prophesize('PHPCI\Config')->reveal(),
$this->prophesize('b8\Http\Request')->reveal(),
new \b8\Http\Response(),
$buildStore->reveal(),
$projectStore->reveal(),
$this->prophesize('b8\HttpClient')->reveal()
);
$result = $webController->handleAction('ccxml', [1]);
$this->assertInstanceOf('b8\Http\Response', $result);
$responseData = $result->getData();
$this->assertEquals('text/xml', $responseData['headers']['Content-Type']);
$this->assertXmlStringEqualsXmlString('<Projects/>', $responseData['body']);
}
/**
* @expectedException \b8\Exception\HttpException\NotAuthorizedException
*/
public function test_image_hidden_for_non_public_project()
{
$buildStore = $this->prophesize('PHPCI\Store\BuildStore');
$projectStore = $this->prophesize('PHPCI\Store\ProjectStore');
$project = new Project();
$project->setAllowPublicStatus(false);
$projectStore->getById(Argument::any())->willReturn($project);
$webController = new BuildStatusController(
$this->prophesize('PHPCI\Config')->reveal(),
$this->prophesize('b8\Http\Request')->reveal(),
new \b8\Http\Response(),
$buildStore->reveal(),
$projectStore->reveal(),
$this->prophesize('b8\HttpClient')->reveal()
);
$result = $webController->handleAction('image', [1]);
}
public function test_image_visible_for_public_project()
{
$buildStore = $this->prophesize('PHPCI\Store\BuildStore');
$projectStore = $this->prophesize('PHPCI\Store\ProjectStore');
$project = new Project();
$project->setId(1);
$project->setBranch('test');
$project->setAllowPublicStatus(true);
$projectStore->getById(1)->willReturn($project);
$shieldsClient = $this->prophesize('b8\HttpClient');
$shieldsClient->get(Argument::any(), Argument::any())->willReturn(array(
'body' => '<svg xmlns="http://www.w3.org/2000/svg" width="78" height="18" />',
));
$webController = new BuildStatusController(
$this->prophesize('PHPCI\Config')->reveal(),
$this->prophesize('b8\Http\Request')->reveal(),
new \b8\Http\Response(),
$buildStore->reveal(),
$projectStore->reveal(),
$shieldsClient->reveal()
);
$result = $webController->handleAction('image', [1]);
$this->assertInstanceOf('b8\Http\Response', $result);
$responseData = $result->getData();
$this->assertEquals('image/svg+xml', $responseData['headers']['Content-Type']);
$this->assertXmlStringEqualsXmlString('<svg xmlns="http://www.w3.org/2000/svg" width="78" height="18" />', $responseData['body']);
}
}

View file

@ -7,15 +7,30 @@
* @link http://www.phptesting.org/
*/
// Let PHP take a guess as to the default timezone, if the user hasn't set one:
use PHPCI\Logging\LoggerConfig;
// If composer has not been run, fail at this point and tell the user to install:
if (!file_exists(__DIR__ . '/vendor/autoload.php') && defined('PHPCI_IS_CONSOLE') && PHPCI_IS_CONSOLE) {
$message = 'Please install PHPCI with "composer install" (or "php composer.phar install"';
$message .= ' for Windows) before using console';
file_put_contents('php://stderr', $message);
exit(1);
}
// Load Composer autoloader:
require_once(__DIR__ . '/vendor/autoload.php');
// Let PHP take a guess as to the default timezone, if the user hasn't set one:
$timezone = ini_get('date.timezone');
if (empty($timezone)) {
date_default_timezone_set('UTC');
}
$configFile = dirname(__FILE__) . '/PHPCI/config.yml';
use PHPCI\Logging\LoggerConfig;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
$configFile = __DIR__ . '/PHPCI/config.yml';
$configEnv = getenv('phpci_config_file');
if (!empty($configEnv) && file_exists($configEnv)) {
@ -30,34 +45,18 @@ if (!file_exists($configFile) && (!defined('PHPCI_IS_CONSOLE') || !PHPCI_IS_CONS
die($message);
}
// If composer has not been run, fail at this point and tell the user to install:
if (!file_exists(dirname(__FILE__) . '/vendor/autoload.php') && defined('PHPCI_IS_CONSOLE') && PHPCI_IS_CONSOLE) {
$message = 'Please install PHPCI with "composer install" (or "php composer.phar install"';
$message .= ' for Windows) before using console';
file_put_contents('php://stderr', $message);
exit(1);
}
// Load Composer autoloader:
require_once(dirname(__FILE__) . '/vendor/autoload.php');
\PHPCI\ErrorHandler::register();
if (defined('PHPCI_IS_CONSOLE') && PHPCI_IS_CONSOLE) {
$loggerConfig = LoggerConfig::newFromFile(__DIR__ . "/loggerconfig.php");
}
// Load configuration if present:
$conf = array();
$conf['b8']['app']['namespace'] = 'PHPCI';
$conf['b8']['app']['default_controller'] = 'Home';
$conf['b8']['view']['path'] = dirname(__FILE__) . '/PHPCI/View/';
$config = new b8\Config($conf);
$container = new ContainerBuilder();
$loader = new YamlFileLoader($container, new FileLocator(__DIR__));
$loader->load('services.yml');
if (file_exists($configFile)) {
$config->loadYaml($configFile);
$container->set('config_file', $configFile);
}
/**
@ -66,11 +65,11 @@ if (file_exists($configFile)) {
*
* @ticket 781
*/
$localVarsFile = dirname(__FILE__) . '/local_vars.php';
$localVarsFile = __DIR__ . '/local_vars.php';
if (is_readable($localVarsFile)) {
require_once $localVarsFile;
}
require_once(dirname(__FILE__) . '/vars.php');
require_once(__DIR__ . '/vars.php');
\PHPCI\Helper\Lang::init($config);
\PHPCI\Helper\Lang::init($container->get('config'));

View file

@ -45,10 +45,11 @@
"symfony/console": "~2.1",
"psr/log": "~1.0",
"monolog/monolog": "~1.6",
"pimple/pimple": "~1.1",
"pimple/pimple": "~3.0",
"robmorgan/phinx": "~0.4",
"sensiolabs/ansi-to-html": "~1.1",
"jakub-onderka/php-parallel-lint": "0.8.*"
"jakub-onderka/php-parallel-lint": "0.8.*",
"symfony/dependency-injection": "~2.7"
},
"autoload-dev": {

144
composer.lock generated
View file

@ -1,10 +1,10 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"hash": "0be92d5565a805ffe462c6061ed1dcf4",
"hash": "4c1675c48cc8ac6ab60ff9a6663bcdb8",
"packages": [
{
"name": "block8/b8framework",
@ -216,16 +216,16 @@
},
{
"name": "pimple/pimple",
"version": "v1.1.1",
"version": "v3.0.0",
"source": {
"type": "git",
"url": "https://github.com/fabpot/Pimple.git",
"reference": "2019c145fe393923f3441b23f29bbdfaa5c58c4d"
"url": "https://github.com/silexphp/Pimple.git",
"reference": "876bf0899d01feacd2a2e83f04641e51350099ef"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/fabpot/Pimple/zipball/2019c145fe393923f3441b23f29bbdfaa5c58c4d",
"reference": "2019c145fe393923f3441b23f29bbdfaa5c58c4d",
"url": "https://api.github.com/repos/silexphp/Pimple/zipball/876bf0899d01feacd2a2e83f04641e51350099ef",
"reference": "876bf0899d01feacd2a2e83f04641e51350099ef",
"shasum": ""
},
"require": {
@ -234,12 +234,12 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1.x-dev"
"dev-master": "3.0.x-dev"
}
},
"autoload": {
"psr-0": {
"Pimple": "lib/"
"Pimple": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@ -249,9 +249,7 @@
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
"email": "fabien@symfony.com"
}
],
"description": "Pimple is a simple Dependency Injection Container for PHP 5.3",
@ -260,7 +258,7 @@
"container",
"dependency injection"
],
"time": "2013-11-22 08:30:29"
"time": "2014-07-24 09:48:15"
},
{
"name": "psr/log",
@ -563,6 +561,66 @@
"homepage": "http://symfony.com",
"time": "2015-01-25 04:39:26"
},
{
"name": "symfony/dependency-injection",
"version": "v2.7.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/DependencyInjection.git",
"reference": "137bf489c5151c7eb1e4b7dd34a123f9a74b966d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/137bf489c5151c7eb1e4b7dd34a123f9a74b966d",
"reference": "137bf489c5151c7eb1e4b7dd34a123f9a74b966d",
"shasum": ""
},
"require": {
"php": ">=5.3.9"
},
"conflict": {
"symfony/expression-language": "<2.6"
},
"require-dev": {
"symfony/config": "~2.2",
"symfony/expression-language": "~2.6",
"symfony/phpunit-bridge": "~2.7",
"symfony/yaml": "~2.1"
},
"suggest": {
"symfony/config": "",
"symfony/proxy-manager-bridge": "Generate service proxies to lazy load them",
"symfony/yaml": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.7-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\DependencyInjection\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony DependencyInjection Component",
"homepage": "https://symfony.com",
"time": "2015-05-29 14:44:44"
},
{
"name": "symfony/filesystem",
"version": "v2.6.4",
@ -1925,66 +1983,6 @@
],
"time": "2015-03-04 02:07:03"
},
{
"name": "symfony/dependency-injection",
"version": "v2.6.4",
"target-dir": "Symfony/Component/DependencyInjection",
"source": {
"type": "git",
"url": "https://github.com/symfony/DependencyInjection.git",
"reference": "42bbb43fab66292a1865dc9616c299904c3d4d14"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/42bbb43fab66292a1865dc9616c299904c3d4d14",
"reference": "42bbb43fab66292a1865dc9616c299904c3d4d14",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"conflict": {
"symfony/expression-language": "<2.6"
},
"require-dev": {
"symfony/config": "~2.2",
"symfony/expression-language": "~2.6",
"symfony/yaml": "~2.1"
},
"suggest": {
"symfony/config": "",
"symfony/proxy-manager-bridge": "Generate service proxies to lazy load them",
"symfony/yaml": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.6-dev"
}
},
"autoload": {
"psr-0": {
"Symfony\\Component\\DependencyInjection\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
},
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
}
],
"description": "Symfony DependencyInjection Component",
"homepage": "http://symfony.com",
"time": "2015-01-25 04:39:26"
},
{
"name": "symfony/finder",
"version": "v2.6.4",

26
console
View file

@ -12,29 +12,7 @@ define('PHPCI_IS_CONSOLE', true);
require('bootstrap.php');
use PHPCI\Command\RunCommand;
use PHPCI\Command\RebuildCommand;
use PHPCI\Command\GenerateCommand;
use PHPCI\Command\UpdateCommand;
use PHPCI\Command\InstallCommand;
use PHPCI\Command\DaemonCommand;
use PHPCI\Command\PollCommand;
use PHPCI\Command\CreateAdminCommand;
use PHPCI\Command\CreateBuildCommand;
use PHPCI\Service\BuildService;
use Symfony\Component\Console\Application;
use b8\Store\Factory;
$application = new Application();
$application->add(new RunCommand($loggerConfig->getFor('RunCommand')));
$application->add(new RebuildCommand($loggerConfig->getFor('RunCommand')));
$application->add(new InstallCommand);
$application->add(new UpdateCommand($loggerConfig->getFor('UpdateCommand')));
$application->add(new GenerateCommand);
$application->add(new DaemonCommand($loggerConfig->getFor('DaemonCommand')));
$application->add(new PollCommand($loggerConfig->getFor('PollCommand')));
$application->add(new CreateAdminCommand(Factory::getStore('User')));
$application->add(new CreateBuildCommand(Factory::getStore('Project'), new BuildService(Factory::getStore('Build'))));
/** @var \Symfony\Component\Console\Application */
$application = $container->get('console.application');
$application->run();

View file

@ -12,9 +12,7 @@ define('PHPCI_IS_CONSOLE', true);
require('bootstrap.php');
use PHPCI\Command\DaemoniseCommand;
use Symfony\Component\Console\Application;
/** @var \Symfony\Component\Console\Application */
$application = $container->get('daemon.application');
$application = new Application();
$application->add(new DaemoniseCommand($loggerConfig->getFor('DaemoniseCommand')));
$application->run();

View file

@ -10,7 +10,9 @@
session_set_cookie_params(43200); // Set session cookie to last 12 hours.
session_start();
require_once('../bootstrap.php');
require_once(__DIR__ . '/../bootstrap.php');
$fc = new PHPCI\Application($config, new b8\Http\Request());
print $fc->handleRequest();
/** @var PHPCI\Application */
$app = $container->get('application');
print $app->handleRequest();

215
services.yml Normal file
View file

@ -0,0 +1,215 @@
parameters:
application.name: PHPCI
application.version: 1.7-dev
config_file: PHPCI/config.yml
storage.factory: b8\Store\Factory
services:
storage.user:
class: PHPCI\Store\UserStore
factory: [%storage.factory%, getStore]
arguments:
- User
storage.project:
class: PHPCI\Store\ProjectStore
factory: [%storage.factory%, getStore]
arguments:
- Project
storage.build:
class: PHPCI\Store\BuildStore
factory: [%storage.factory%, getStore]
arguments:
- Build
storage.build_meta:
class: PHPCI\Store\BuildMetaStore
factory: [%storage.factory%, getStore]
arguments:
- BuildMeta
factory.build:
class: PHPCI\BuildFactory
arguments:
- @storage.build
http.request:
class: b8\Http\Request
arguments: []
http.response:
class: b8\Http\Response
arguments: []
http_client.github:
class: b8\HttpClient
arguments:
- https://api.github.com
http_client.shields:
class: b8\HttpClient
arguments:
- http://img.shields.io
config:
class: PHPCI\Config
arguments: [%config_file%]
application:
class: PHPCI\Application
arguments:
- @config
- @http.request
- @http.response
- @storage.user
- @storage.project
- @service_container
application.controller.home:
class: PHPCI\Controller\HomeController
arguments:
- @config
- @http.request
- @http.response
- @storage.build
- @storage.project
- @factory.build
application.controller.project:
class: PHPCI\Controller\ProjectController
arguments:
- @config
- @http.request
- @http.response
- @storage.build
- @storage.project
- @service.project
- @service.build
- @factory.build
application.controller.build:
class: PHPCI\Controller\BuildController
arguments:
- @config
- @http.request
- @http.response
- @storage.build
- @service.build
- @factory.build
application.controller.buildstatus:
class: PHPCI\Controller\BuildStatusController
arguments:
- @config
- @http.request
- @http.response
- @storage.build
- @storage.project
- @http_client.shields
- @factory.build
application.controller.user:
class: PHPCI\Controller\UserController
arguments:
- @config
- @http.request
- @http.response
- @storage.user
- @service.user
application.controller.session:
class: PHPCI\Controller\SessionController
arguments:
- @config
- @http.request
- @http.response
- @storage.user
application.controller.settings:
class: PHPCI\Controller\SettingsController
arguments:
- @config
- @http.request
- @http.response
- @storage.user
- @service.user
application.controller.plugin:
class: PHPCI\Controller\PluginController
arguments:
- @config
- @http.request
- @http.response
application.controller.webhook:
class: PHPCI\Controller\WebhookController
arguments:
- @config
- @http.request
- @http.response
- @storage.build
- @storage.project
- @service.build
- @factory.build
service.build:
class: PHPCI\Service\BuildService
arguments: [@storage.build]
service.user:
class: PHPCI\Service\UserService
arguments: [@storage.user]
service.project:
class: PHPCI\Service\ProjectService
arguments: [@storage.project]
process_control:
factory: [PHPCI\ProcessControl\Factory, getInstance]
console.application:
class: Symfony\Component\Console\Application
arguments:
- %application.name%
- %application.version%
calls:
- [add, ['@console.command.run']]
- [add, ['@console.command.rebuild']]
- [add, ['@console.command.install']]
- [add, ['@console.command.update']]
- [add, ['@console.command.generate']]
- [add, ['@console.command.daemon']]
- [add, ['@console.command.poll']]
- [add, ['@console.command.create_admin']]
- [add, ['@console.command.create_build']]
daemon.application:
class: Symfony\Component\Console\Application
arguments:
- %application.name%
- %application.version%
calls:
- [add, ['@console.command.daemon']]
console.logger:
class: Monolog\Logger
arguments:
- cli
console.command.run:
class: PHPCI\Command\RunCommand
arguments:
- @factory.build
- @console.logger
console.command.rebuild:
class: PHPCI\Command\RebuildCommand
arguments:
- @console.logger
- @storage.build
- @service.build
- @console.command.run
console.command.update:
class: PHPCI\Command\UpdateCommand
arguments:
- @console.logger
- @config
console.command.daemon:
class: PHPCI\Command\DaemonCommand
arguments:
- @console.logger
- @process_control
console.command.poll:
class: PHPCI\Command\PollCommand
arguments:
- @config
- @console.logger
- @storage.build
- @storage.project
- @http_client.github
console.command.create_admin:
class: PHPCI\Command\CreateAdminCommand
arguments:
- @service.user
console.command.create_build:
class: PHPCI\Command\CreateBuildCommand
arguments:
- @storage.project
- @service.build
console.command.install:
class: PHPCI\Command\InstallCommand
console.command.generate:
class: PHPCI\Command\GenerateCommand

View file

@ -2,13 +2,13 @@
// Define our APPLICATION_PATH, if not already defined:
if (!defined('APPLICATION_PATH')) {
define('APPLICATION_PATH', dirname(__FILE__) . '/');
define('APPLICATION_PATH', __DIR__ . '/');
define('PHPCI_DIR', APPLICATION_PATH);
}
// Define our PHPCI_URL, if not already defined:
if (!defined('PHPCI_URL') && isset($config)) {
define('PHPCI_URL', $config->get('phpci.url', '') . '/');
if (!defined('PHPCI_URL')) {
define('PHPCI_URL', isset($container) ? $container->get('config')->get('phpci.url') : '');
}
// Define PHPCI_BIN_DIR
@ -38,5 +38,5 @@ if (!defined('IS_WIN')) {
// If an environment variable is set defining our config location, use that
// otherwise fall back to PHPCI/config.yml.
if (!defined('PHPCI_CONFIG_FILE')) {
define('PHPCI_CONFIG_FILE', $configFile);
define('PHPCI_CONFIG_FILE', isset($container) ? $container->get('config_file') : 'PHPCI/config.yml');
}