Refactored Controllers.

This commit is contained in:
Dmitry Khomutov 2018-03-13 20:09:54 +07:00
parent 7abd3febc1
commit ba0d9f14fa
No known key found for this signature in database
GPG key ID: EC19426474B37AAC
20 changed files with 512 additions and 512 deletions

View file

@ -21,7 +21,7 @@ class Application
protected $route;
/**
* @var Controller
* @var Controller|WebController
*/
protected $controller;
@ -30,11 +30,6 @@ class Application
*/
protected $request;
/**
* @var Response
*/
protected $response;
/**
* @var Config
*/
@ -53,7 +48,6 @@ class Application
public function __construct(Config $config, Request $request = null)
{
$this->config = $config;
$this->response = new Response();
if (!is_null($request)) {
$this->request = $request;
@ -128,8 +122,9 @@ class Application
if (!empty($this->route['callback'])) {
$callback = $this->route['callback'];
if (!$callback($this->route, $this->response)) {
return $this->response;
$response = new Response();
if (!$callback($this->route, $response)) {
return $response;
}
}
@ -153,33 +148,30 @@ class Application
public function handleRequest()
{
try {
$this->response = $this->handleRequestInner();
$response = $this->handleRequestInner();
} catch (HttpException $ex) {
$this->config->set('page_title', 'Error');
$view = new View('exception');
$view->exception = $ex;
$this->response->setResponseCode($ex->getErrorCode());
$this->response->setContent($view->render());
$response = new Response();
$response->setResponseCode($ex->getErrorCode());
$response->setContent($view->render());
} catch (\Exception $ex) {
$this->config->set('page_title', 'Error');
$view = new View('exception');
$view->exception = $ex;
$this->response->setResponseCode(500);
$this->response->setContent($view->render());
$response = new Response();
$response->setResponseCode(500);
$response->setContent($view->render());
}
if ($this->response->hasLayout() && $this->controller && $this->controller->layout) {
$this->setLayoutVariables($this->controller->layout);
$this->controller->layout->content = $this->response->getContent();
$this->response->setContent($this->controller->layout->render());
}
return $this->response;
return $response;
}
/**
@ -192,40 +184,13 @@ class Application
protected function loadController($class)
{
/** @var Controller $controller */
$controller = new $class($this->config, $this->request, $this->response);
$controller = new $class($this->config, $this->request);
$controller->init();
$controller->layout = new View('layout');
$controller->layout->title = 'PHP Censor';
$controller->layout->breadcrumb = [];
$controller->layout->version = trim(file_get_contents(ROOT_DIR . 'VERSION.md'));
return $controller;
}
/**
* Injects variables into the layout before rendering it.
*
* @param View $layout
*/
protected function setLayoutVariables(View &$layout)
{
$groups = [];
$groupStore = Factory::getStore('ProjectGroup');
$groupList = $groupStore->getWhere([], 100, 0, ['title' => 'ASC']);
foreach ($groupList['items'] as $group) {
$thisGroup = ['title' => $group->getTitle()];
$projects = Factory::getStore('Project')->getByGroupId($group->getId(), false);
$thisGroup['projects'] = $projects['items'];
$groups[] = $thisGroup;
}
$archivedProjects = Factory::getStore('Project')->getAll(true);
$layout->archived_projects = $archivedProjects['items'];
$layout->groups = $groups;
}
/**
* Check whether we should skip auth (because it is disabled)
*

View file

@ -2,171 +2,35 @@
namespace PHPCensor;
use PHPCensor\Exception\HttpException\ForbiddenException;
use PHPCensor\Http\Request;
use PHPCensor\Http\Response;
use PHPCensor\Store\Factory;
use PHPCensor\Model\User;
use PHPCensor\Store\UserStore;
class Controller
abstract class Controller
{
/**
* @var Request
*/
protected $request;
/**
* @var Response
*/
protected $response;
/**
* @var Config
*/
protected $config;
/**
* @var View
* @param Config $config
* @param Request $request
*/
protected $controllerView;
/**
* @var View
*/
protected $view;
/**
* @var string
*/
protected $className;
/**
* @var View
*/
public $layout;
public function __construct(Config $config, Request $request)
{
$this->config = $config;
$this->request = $request;
}
/**
* Initialise the controller.
*/
public function init()
{
// Extended by actual controllers.
}
/**
* @param Config $config
* @param Request $request
* @param Response $response
*/
public function __construct(Config $config, Request $request, Response $response)
{
$this->config = $config;
$this->request = $request;
$this->response = $response;
$class = explode('\\', get_class($this));
$this->className = substr(array_pop($class), 0, -10);
$this->setControllerView();
if (!empty($_SESSION['php-censor-user'])) {
unset($_SESSION['php-censor-user']);
}
}
/**
* Set the view that this controller should use.
*/
protected function setControllerView()
{
if (View::exists($this->className)) {
$this->controllerView = new View($this->className);
} else {
$this->controllerView = new View('{@content}');
}
}
/**
* Set the view that this controller action should use.
*
* @param string $action
*/
protected function setView($action)
{
if (View::exists($this->className . '/' . $action)) {
$this->view = new View($this->className . '/' . $action);
}
}
/**
* Handle the incoming request.
*
* @param string $action
* @param array $actionParams
*
* @return Response
*/
public function handleAction($action, $actionParams)
{
$this->setView($action);
$response = call_user_func_array([$this, $action], $actionParams);
if ($response instanceof Response) {
return $response;
}
if (is_string($response)) {
$this->controllerView->content = $response;
} elseif (isset($this->view)) {
$this->controllerView->content = $this->view->render();
}
$this->response->setContent($this->controllerView->render());
return $this->response;
}
/**
* Require that the currently logged in user is an administrator.
*
* @throws ForbiddenException
*/
protected function requireAdmin()
{
if (!$this->currentUserIsAdmin()) {
throw new ForbiddenException('You do not have permission to do that.');
}
}
/**
* Check if the currently logged in user is an administrator.
*
* @return boolean
*/
protected function currentUserIsAdmin()
{
$user = $this->getUser();
if (!$user) {
return false;
}
return $this->getUser()->getIsAdmin();
}
/**
* @return User|null
*/
protected function getUser()
{
if (empty($_SESSION['php-censor-user-id'])) {
return null;
}
/** @var UserStore $userStore */
$userStore = Factory::getStore('User');
return $userStore->getById($_SESSION['php-censor-user-id']);
}
abstract public function init();
/**
* @param string $name
@ -186,6 +50,19 @@ class Controller
return false;
}
/**
* Handles an action on this controller and returns a Response object.
*
* @param string $action
* @param array $actionParams
*
* @return Response
*/
public function handleAction($action, $actionParams)
{
return call_user_func_array([$this, $action], $actionParams);
}
/**
* Get a hash of incoming request parameters ($_GET, $_POST)
*

View file

@ -12,7 +12,7 @@ use PHPCensor\Http\Response\RedirectResponse;
use PHPCensor\Model\Build;
use PHPCensor\Model\User;
use PHPCensor\Service\BuildService;
use PHPCensor\Controller;
use PHPCensor\WebController;
use PHPCensor\View;
use PHPCensor\Store\Factory;
@ -21,8 +21,13 @@ use PHPCensor\Store\Factory;
*
* @author Dan Cryer <dan@block8.co.uk>
*/
class BuildController extends Controller
class BuildController extends WebController
{
/**
* @var string
*/
public $layoutName = 'layout';
/**
* @var \PHPCensor\Store\BuildStore
*/
@ -33,11 +38,10 @@ class BuildController extends Controller
*/
protected $buildService;
/**
* Initialise the controller, set up stores and services.
*/
public function init()
{
parent::init();
$this->buildStore = Factory::getStore('Build');
$this->buildService = new BuildService($this->buildStore);
}

View file

@ -10,27 +10,33 @@ use PHPCensor\BuildFactory;
use PHPCensor\Model\Project;
use PHPCensor\Model\Build;
use PHPCensor\Service\BuildStatusService;
use PHPCensor\Controller;
use PHPCensor\WebController;
/**
* Build Status Controller - Allows external access to build status information / images.
*
* @author Dan Cryer <dan@block8.co.uk>
*/
class BuildStatusController extends Controller
class BuildStatusController extends WebController
{
/* @var \PHPCensor\Store\ProjectStore */
protected $projectStore;
/* @var \PHPCensor\Store\BuildStore */
protected $buildStore;
/**
* @var string
*/
public $layoutName = 'layoutPublic';
/**
* Initialise the controller, set up stores and services.
* @var \PHPCensor\Store\ProjectStore
*/
protected $projectStore;
/**
* @var \PHPCensor\Store\BuildStore
*/
protected $buildStore;
public function init()
{
$this->response->disableLayout();
parent::init();
$this->buildStore = Factory::getStore('Build');
$this->projectStore = Factory::getStore('Project');
@ -74,7 +80,7 @@ class BuildStatusController extends Controller
*
* @param $projectId
*
* @return bool
* @return Response
*
* @throws \Exception
*/
@ -114,16 +120,16 @@ class BuildStatusController extends Controller
/**
* @param \SimpleXMLElement $xml
*
* @return boolean
* @return Response
*/
protected function renderXml(\SimpleXMLElement $xml = null)
{
$this->response->setHeader('Content-Type', 'text/xml');
$this->response->setContent($xml->asXML());
$this->response->flush();
echo $xml->asXML();
$response = new Response();
return true;
$response->setHeader('Content-Type', 'text/xml');
$response->setContent($xml->asXML());
return $response;
}
/**
@ -179,11 +185,12 @@ class BuildStatusController extends Controller
$image = file_get_contents($cacheFile);
$this->response->disableLayout();
$this->response->setHeader('Content-Type', 'image/svg+xml');
$this->response->setContent($image);
$response = new Response();
return $this->response;
$response->setHeader('Content-Type', 'image/svg+xml');
$response->setContent($image);
return $response;
}
/**

View file

@ -3,7 +3,7 @@
namespace PHPCensor\Controller;
use PHPCensor\Form;
use PHPCensor\Controller;
use PHPCensor\WebController;
use PHPCensor\Http\Response\RedirectResponse;
use PHPCensor\Model\ProjectGroup;
use PHPCensor\Helper\Lang;
@ -15,18 +15,22 @@ use PHPCensor\Store\Factory;
*
* @author Dan Cryer <dan@block8.co.uk>
*/
class GroupController extends Controller
class GroupController extends WebController
{
/**
* @var string
*/
public $layoutName = 'layout';
/**
* @var \PHPCensor\Store\ProjectGroupStore
*/
protected $groupStore;
/**
* Set up this controller.
*/
public function init()
{
parent::init();
$this->groupStore = Factory::getStore('ProjectGroup');
}

View file

@ -4,13 +4,18 @@ namespace PHPCensor\Controller;
use PHPCensor\Config;
use PHPCensor\Helper\Lang;
use PHPCensor\Controller;
use PHPCensor\WebController;
/**
* Home Controller - Displays the Dashboard.
*/
class HomeController extends Controller
class HomeController extends WebController
{
/**
* @var string
*/
public $layoutName = 'layout';
/**
* Display dashboard:
*/

View file

@ -17,14 +17,20 @@ use PHPCensor\Http\Response\RedirectResponse;
use PHPCensor\View;
use PHPCensor\Store\Factory;
use PHPCensor\Model\Project;
use PHPCensor\WebController;
/**
* Project Controller - Allows users to create, edit and view projects.
*
* @author Dan Cryer <dan@block8.co.uk>
*/
class ProjectController extends PHPCensor\Controller
class ProjectController extends WebController
{
/**
* @var string
*/
public $layoutName = 'layout';
/**
* @var \PHPCensor\Store\ProjectStore
*/
@ -50,6 +56,8 @@ class ProjectController extends PHPCensor\Controller
*/
public function init()
{
parent::init();
$this->buildStore = Factory::getStore('Build');
$this->projectStore = Factory::getStore('Project');
$this->projectService = new ProjectService($this->projectStore);
@ -69,10 +77,10 @@ class ProjectController extends PHPCensor\Controller
$perPage = (integer)$this->getParam('per_page', 10);
$builds = $this->getLatestBuildsHtml($projectId, $branch, $environment, (($page - 1) * $perPage), $perPage);
$this->response->disableLayout();
$this->response->setContent($builds[0]);
$response = new PHPCensor\Http\Response();
$response->setContent($builds[0]);
return $this->response;
return $response;
}
/**
@ -327,10 +335,10 @@ class ProjectController extends PHPCensor\Controller
'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),
'allow_public_status' => (boolean)$this->getParam('allow_public_status', 0),
'branch' => $this->getParam('branch', null),
'default_branch_only' => $this->getParam('default_branch_only', 0),
'group' => $this->getParam('group_id', null),
'default_branch_only' => (boolean)$this->getParam('default_branch_only', 0),
'group' => (integer)$this->getParam('group_id', null),
'environments' => $this->getParam('environments', null),
];
@ -380,11 +388,11 @@ class ProjectController extends PHPCensor\Controller
$form = $this->projectForm($values, 'edit/' . $projectId);
if ($method != 'POST' || ($method == 'POST' && !$form->validate())) {
$view = new View('Project/edit');
$view->type = 'edit';
$view->project = $project;
$view->form = $form;
$view->key = $values['pubkey'];
$view = new View('Project/edit');
$view->type = 'edit';
$view->project = $project;
$view->form = $form;
$view->key = $values['pubkey'];
return $view->render();
}
@ -397,11 +405,11 @@ class ProjectController extends PHPCensor\Controller
'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', false),
'archived' => $this->getParam('archived', false),
'allow_public_status' => (boolean)$this->getParam('allow_public_status', false),
'archived' => (boolean)$this->getParam('archived', false),
'branch' => $this->getParam('branch', null),
'default_branch_only' => $this->getParam('default_branch_only', false),
'group' => $this->getParam('group_id', null),
'default_branch_only' => (boolean)$this->getParam('default_branch_only', false),
'group' => (integer)$this->getParam('group_id', null),
'environments' => $this->getParam('environments', null),
];

View file

@ -5,7 +5,7 @@ namespace PHPCensor\Controller;
use PHPCensor\Form\Element\Csrf;
use PHPCensor\Helper\Email;
use PHPCensor\Helper\Lang;
use PHPCensor\Controller;
use PHPCensor\WebController;
use PHPCensor\Http\Response\RedirectResponse;
use PHPCensor\Security\Authentication\Service;
use PHPCensor\Store\UserStore;
@ -16,8 +16,13 @@ use PHPCensor\Store\Factory;
*
* @author Dan Cryer <dan@block8.co.uk>
*/
class SessionController extends Controller
class SessionController extends WebController
{
/**
* @var string
*/
public $layoutName = 'layoutSession';
/**
* @var UserStore
*/
@ -33,7 +38,7 @@ class SessionController extends Controller
*/
public function init()
{
$this->response->disableLayout();
parent::init();
$this->userStore = Factory::getStore('User');
$this->authentication = Service::getInstance();

View file

@ -5,7 +5,7 @@ namespace PHPCensor\Controller;
use PHPCensor\Config;
use PHPCensor\Exception\HttpException\NotFoundException;
use PHPCensor\Form;
use PHPCensor\Controller;
use PHPCensor\WebController;
use PHPCensor\Helper\Lang;
use PHPCensor\Http\Response\RedirectResponse;
use PHPCensor\Model\User;
@ -18,8 +18,13 @@ use PHPCensor\Store\Factory;
*
* @author Dan Cryer <dan@block8.co.uk>
*/
class UserController extends Controller
class UserController extends WebController
{
/**
* @var string
*/
public $layoutName = 'layout';
/**
* @var \PHPCensor\Store\UserStore
*/
@ -35,6 +40,8 @@ class UserController extends Controller
*/
public function init()
{
parent::init();
$this->userStore = Factory::getStore('User');
$this->userService = new UserService($this->userStore);
}
@ -70,7 +77,7 @@ class UserController extends Controller
$language = null;
}
$perPage = $this->getParam('per_page', null);
$perPage = (integer)$this->getParam('per_page', null);
if (!$perPage) {
$perPage = null;
}
@ -183,7 +190,7 @@ class UserController extends Controller
$name = $this->getParam('name', null);
$email = $this->getParam('email', null);
$password = $this->getParam('password', null);
$isAdmin = (int)$this->getParam('is_admin', 0);
$isAdmin = (boolean)$this->getParam('is_admin', 0);
$this->userService->createUser($name, $email, 'internal', ['type' => 'internal'], $password, $isAdmin);
@ -224,7 +231,7 @@ class UserController extends Controller
$name = $this->getParam('name', null);
$email = $this->getParam('email', null);
$password = $this->getParam('password', null);
$isAdmin = (int)$this->getParam('is_admin', 0);
$isAdmin = (boolean)$this->getParam('is_admin', 0);
$this->userService->updateUser($user, $name, $email, $password, $isAdmin);

View file

@ -43,18 +43,6 @@ class WebhookController extends Controller
*/
protected $buildService;
/**
* @param Config $config
* @param Request $request
* @param Response $response
*/
public function __construct(Config $config, Request $request, Response $response)
{
$this->config = $config;
$this->request = $request;
$this->response = $response;
}
/**
* Initialise the controller, set up stores and services.
*/
@ -77,7 +65,7 @@ class WebhookController extends Controller
{
$response = new Response\JsonResponse();
try {
$data = call_user_func_array([$this, $action], $actionParams);
$data = parent::handleAction($action, $actionParams);
if (isset($data['responseCode'])) {
$response->setResponseCode($data['responseCode']);
unset($data['responseCode']);

View file

@ -3,7 +3,7 @@
namespace PHPCensor\Controller;
use PHPCensor\Model\Build;
use PHPCensor\Controller;
use PHPCensor\WebController;
use PHPCensor\Store\Factory;
use PHPCensor\View;
use PHPCensor\Model\Project;
@ -15,7 +15,7 @@ use PHPCensor\Store\ProjectGroupStore;
/**
* Widget All Projects Controller
*/
class WidgetAllProjectsController extends Controller
class WidgetAllProjectsController extends WebController
{
/**
* @var BuildStore
@ -37,6 +37,8 @@ class WidgetAllProjectsController extends Controller
*/
public function init()
{
parent::init();
$this->buildStore = Factory::getStore('Build');
$this->projectStore = Factory::getStore('Project');
$this->groupStore = Factory::getStore('ProjectGroup');
@ -49,10 +51,10 @@ class WidgetAllProjectsController extends Controller
{
$this->view->groups = $this->getGroupInfo();
$this->response->disableLayout();
$this->response->setContent($this->view->render());
$response = new Response();
$response->setContent($this->view->render());
return $this->response;
return $response;
}
/**
@ -142,9 +144,9 @@ class WidgetAllProjectsController extends Controller
$this->view->failed = $this->buildStore->getLastBuildByStatus($projectId, Build::STATUS_FAILED);
$this->view->counts = $counts;
$this->response->disableLayout();
$this->response->setContent($this->view->render());
$response = new Response();
$response->setContent($this->view->render());
return $this->response;
return $response;
}
}

View file

@ -5,14 +5,14 @@ namespace PHPCensor\Controller;
use PHPCensor\Store\Factory;
use PHPCensor\View;
use PHPCensor\Http\Response;
use PHPCensor\Controller;
use PHPCensor\WebController;
use PHPCensor\Store\BuildStore;
use PHPCensor\Store\ProjectStore;
/**
* Widget Build Errors Controller
*/
class WidgetBuildErrorsController extends Controller
class WidgetBuildErrorsController extends WebController
{
/**
* @var BuildStore
@ -29,6 +29,8 @@ class WidgetBuildErrorsController extends Controller
*/
public function init()
{
parent::init();
$this->buildStore = Factory::getStore('Build');
$this->projectStore = Factory::getStore('Project');
}
@ -42,10 +44,10 @@ class WidgetBuildErrorsController extends Controller
$this->view->projects = $this->renderAllProjectsLatestBuilds($view);
$this->response->disableLayout();
$this->response->setContent($this->view->render());
$response = new Response();
$response->setContent($this->view->render());
return $this->response;
return $response;
}
/**
@ -53,10 +55,10 @@ class WidgetBuildErrorsController extends Controller
*/
public function update()
{
$this->response->disableLayout();
$this->response->setContent($this->renderAllProjectsLatestBuilds($this->view));
$response = new Response();
$response->setContent($this->renderAllProjectsLatestBuilds($this->view));
return $this->response;
return $response;
}
/**

View file

@ -6,13 +6,13 @@ use PHPCensor\Store\Factory;
use PHPCensor\View;
use PHPCensor\Http\Response;
use PHPCensor\BuildFactory;
use PHPCensor\Controller;
use PHPCensor\WebController;
use PHPCensor\Store\BuildStore;
/**
* Widget Last Builds Controller
*/
class WidgetLastBuildsController extends Controller
class WidgetLastBuildsController extends WebController
{
/**
* @var BuildStore
@ -24,6 +24,8 @@ class WidgetLastBuildsController extends Controller
*/
public function init()
{
parent::init();
$this->buildStore = Factory::getStore('Build');
}
@ -43,10 +45,10 @@ class WidgetLastBuildsController extends Controller
$view->builds = $builds;
$this->view->timeline = $view->render();
$this->response->disableLayout();
$this->response->setContent($this->view->render());
$response = new Response();
$response->setContent($this->view->render());
return $this->response;
return $response;
}
/**
@ -62,9 +64,9 @@ class WidgetLastBuildsController extends Controller
$this->view->builds = $builds;
$this->response->disableLayout();
$this->response->setContent($this->view->render());
$response = new Response();
$response->setContent($this->view->render());
return $this->response;
return $response;
}
}

View file

@ -13,21 +13,6 @@ class Response
}
}
public function hasLayout()
{
return !isset($this->data['layout']) ? true : $this->data['layout'];
}
public function disableLayout()
{
$this->data['layout'] = false;
}
public function enableLayout()
{
$this->data['layout'] = true;
}
public function getData()
{
return $this->data;

View file

@ -14,11 +14,6 @@ class JsonResponse extends Response
$this->setHeader('Content-Type', 'application/json');
}
public function hasLayout()
{
return false;
}
protected function flushBody()
{
if (isset($this->data['body'])) {

View file

@ -14,11 +14,6 @@ class RedirectResponse extends Response
$this->setResponseCode(302);
}
public function hasLayout()
{
return false;
}
public function flush()
{
parent::flush();

View file

@ -1,207 +1,161 @@
<!DOCTYPE html>
<html>
<head>
<title><?= $project->getTitle(); ?> - PHP Censor</title>
<?php if (!empty($latest)): ?>
<meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' name='viewport'>
<?php
<link href="<?= APP_URL; ?>assets/vendor/admin-lte/bootstrap/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<link href="<?= APP_URL; ?>assets/vendor/admin-lte/dist/css/AdminLTE.min.css" rel="stylesheet" type="text/css" />
<link href="<?= APP_URL; ?>assets/css/ansi-colors.css" rel="stylesheet" type="text/css" />
<link href="<?= APP_URL; ?>assets/css/main.css" rel="stylesheet" type="text/css" />
$statusClass = null;
$statusText = null;
<link href="<?= APP_URL; ?>assets/vendor/font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css" />
<link href="<?= APP_URL; ?>assets/vendor/ionicons/css/ionicons.min.css" rel="stylesheet" type="text/css" />
switch ($latest->getStatus()) {
case 0:
$statusClass = 'blue';
$statusText = 'Pending';
break;
case 1:
$statusClass = 'yellow';
$statusText = 'Running';
break;
case 2:
$statusClass = 'green';
$statusText = 'Success';
break;
case 3:
$statusClass = 'red';
$statusText = 'Failed';
break;
}
<script src="<?= APP_URL; ?>assets/vendor/admin-lte/plugins/jQuery/jquery-2.2.3.min.js"></script>
<script src="<?= APP_URL; ?>assets/js/class.js"></script>
<script src="<?= APP_URL; ?>assets/vendor/sprintf-js/dist/sprintf.min.js"></script>
<script src="<?= APP_URL; ?>assets/js/app.js?v2" type="text/javascript"></script>
</head>
<body class="hold-transition skin-black layout-top-nav">
<div class="wrapper">
<header class="main-header">
<nav class="navbar navbar-static-top">
<div class="container">
<div class="navbar-header">
<a href="<?= APP_URL; ?>" class="logo" title="PHP Censor" style="background-color: #222D32; width: 170px; padding: 0;">
<img src="<?= APP_URL; ?>assets/img/php-censor-white.svg" width="170" height="auto" alt="PHP Censor" />
</a>
</div>
</div>
</nav>
</header>
<div class="content-wrapper">
<div class="container">
<section class="content" style="padding: 15px 0 15px;">
<?php if (!empty($latest)): ?>
?>
<?php
<div class="small-box small-box-full bg-<?= $statusClass; ?>">
<div class="inner">
<h3 class="box-title">
<?= $latest->getProject()->getTitle(); ?> #<?= $latest->getId(); ?> (<?= $statusText; ?>)
</h3>
<p>
<?php $latestCommitMessage = htmlspecialchars($latest->getCommitMessage()); ?>
<?php if ($latestCommitMessage): ?>
<?= $latestCommitMessage; ?><br /><br />
<?php endif; ?>
$statusClass = null;
$statusText = null;
<strong>Branch: </strong> <?= $latest->getBranch(); ?><br />
<strong>Committer: </strong> <?= $latest->getCommitterEmail(); ?>
switch ($latest->getStatus()) {
case 0:
$statusClass = 'blue';
$statusText = 'Pending';
break;
case 1:
$statusClass = 'yellow';
$statusText = 'Running';
break;
case 2:
$statusClass = 'green';
$statusText = 'Success';
break;
case 3:
$statusClass = 'red';
$statusText = 'Failed';
break;
}
?>
<div class="small-box small-box-full bg-<?= $statusClass; ?>">
<div class="inner">
<h3 class="box-title">
<?= $latest->getProject()->getTitle(); ?> #<?= $latest->getId(); ?> (<?= $statusText; ?>)
</h3>
<p>
<?php $latestCommitMessage = htmlspecialchars($latest->getCommitMessage()); ?>
<?php if ($latestCommitMessage): ?>
<?= $latestCommitMessage; ?><br /><br />
<?php endif; ?>
<strong>Branch: </strong> <?= $latest->getBranch(); ?><br />
<strong>Committer: </strong> <?= $latest->getCommitterEmail(); ?>
<?php if (!empty($latest->getCommitId())): ?>
<br /><strong>Commit: </strong> <?= $latest->getCommitId(); ?><br>
<?php endif; ?>
</p>
</div>
<div class="icon">
<i class="fa fa-<?= $project->getIcon(); ?>"></i>
</div>
<div style="clear: both;"></div>
</div>
<?php endif; ?>
<div class="box">
<div class="box-header"><h3 class="box-title">Builds</h3></div>
<table class="table table-hover">
<thead>
<tr>
<th>ID</th>
<th>Status</th>
<th>Date</th>
<th>Commit</th>
<th>Branch</th>
<th>Environment</th>
<th>Duration</th>
</tr>
</thead>
<tbody id="latest-builds">
<?php if(empty($builds) || !count($builds)): ?>
<tr class="">
<td colspan="6">No builds yet.</td>
</tr>
<?php endif; ?>
<?php foreach($builds as $build): ?>
<?php
switch($build->getStatus())
{
case 0:
$class = 'info';
$status = 'Pending';
break;
case 1:
$class = 'warning';
$status = 'Running';
break;
case 2:
$class = 'success';
$status = 'Success';
break;
case 3:
$class = 'danger';
$status = 'Failed';
break;
}
?>
<tr>
<td><a href="<?= APP_URL; ?>build/view/<?= $build->getId(); ?>">#<?= str_pad($build->getId(), 6, '0', STR_PAD_LEFT); ?></a></td>
<td>
<span class='label label-<?= $class; ?>'><?= $status; ?></span>
</td>
<td><?= $build->getCreateDate()->format('Y-m-d H:i:s'); ?></td>
<td>
<?php
if (!empty($build->getCommitId())) {
print sprintf(
'<a href="%s">%s %s</a>',
$build->getCommitLink(),
substr($build->getCommitId(), 0, 7),
$build->getCommitterEmail() ? ('(' . $build->getCommitterEmail() . ')') : ''
);
} else {
print '&mdash;';
}
?>
</td>
<td>
<?php if (\PHPCensor\Model\Build::SOURCE_WEBHOOK_PULL_REQUEST === $build->getSource()): ?>
<a href="<?= $build->getRemoteBranchLink(); ?>">
<i class="fa fa-code-fork"></i>
<?= $build->getRemoteBranch(); ?> :
</a>
<?php endif; ?>
<a href="<?= $build->getBranchLink();?>">
<i class="fa fa-code-fork"></i>
<?= $build->getBranch(); ?>
</a>
<?php $branches = $build->getExtra('branches'); ?>
<?= $branches ? ' + '.implode(', ', $branches) : ''; ?>
<?php if ($tag = $build->getTag()): ?> /
<a href="<?= $build->getTagLink(); ?>">
<i class="fa fa-tag"></i>
<?= $tag; ?>
</a>
<?php endif; ?>
</td>
<td>
<?php
$environment = $build->getEnvironment();
echo !empty($environment) ? $environment : '—' ;
?>
</td>
<td>
<?= $build->getDuration(); ?> sec.
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</section>
</div>
<?php if (!empty($latest->getCommitId())): ?>
<br /><strong>Commit: </strong> <?= $latest->getCommitId(); ?><br>
<?php endif; ?>
</p>
</div>
<!--<footer class="main-footer">
<div class="container">
</div>
</footer>-->
<div class="icon">
<i class="fa fa-<?= $project->getIcon(); ?>"></i>
</div>
<div style="clear: both;"></div>
</div>
</body>
</html>
<?php endif; ?>
<div class="box">
<div class="box-header"><h3 class="box-title">Builds</h3></div>
<table class="table table-hover">
<thead>
<tr>
<th>ID</th>
<th>Status</th>
<th>Date</th>
<th>Commit</th>
<th>Branch</th>
<th>Environment</th>
<th>Duration</th>
</tr>
</thead>
<tbody id="latest-builds">
<?php if(empty($builds) || !count($builds)): ?>
<tr class="">
<td colspan="6">No builds yet.</td>
</tr>
<?php endif; ?>
<?php foreach($builds as $build): ?>
<?php
switch($build->getStatus())
{
case 0:
$class = 'info';
$status = 'Pending';
break;
case 1:
$class = 'warning';
$status = 'Running';
break;
case 2:
$class = 'success';
$status = 'Success';
break;
case 3:
$class = 'danger';
$status = 'Failed';
break;
}
?>
<tr>
<td><a href="<?= APP_URL; ?>build/view/<?= $build->getId(); ?>">#<?= str_pad($build->getId(), 6, '0', STR_PAD_LEFT); ?></a></td>
<td>
<span class='label label-<?= $class; ?>'><?= $status; ?></span>
</td>
<td><?= $build->getCreateDate()->format('Y-m-d H:i:s'); ?></td>
<td>
<?php
if (!empty($build->getCommitId())) {
print sprintf(
'<a href="%s">%s %s</a>',
$build->getCommitLink(),
substr($build->getCommitId(), 0, 7),
$build->getCommitterEmail() ? ('(' . $build->getCommitterEmail() . ')') : ''
);
} else {
print '&mdash;';
}
?>
</td>
<td>
<?php if (\PHPCensor\Model\Build::SOURCE_WEBHOOK_PULL_REQUEST === $build->getSource()): ?>
<a href="<?= $build->getRemoteBranchLink(); ?>">
<i class="fa fa-code-fork"></i>
<?= $build->getRemoteBranch(); ?> :
</a>
<?php endif; ?>
<a href="<?= $build->getBranchLink();?>">
<i class="fa fa-code-fork"></i>
<?= $build->getBranch(); ?>
</a>
<?php $branches = $build->getExtra('branches'); ?>
<?= $branches ? ' + '.implode(', ', $branches) : ''; ?>
<?php if ($tag = $build->getTag()): ?> /
<a href="<?= $build->getTagLink(); ?>">
<i class="fa fa-tag"></i>
<?= $tag; ?>
</a>
<?php endif; ?>
</td>
<td>
<?php
$environment = $build->getEnvironment();
echo !empty($environment) ? $environment : '—' ;
?>
</td>
<td>
<?= $build->getDuration(); ?> sec.
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>

View file

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html>
<head>
<title><?= $title; ?><?= (!empty($subtitle) ? ' - ' . $subtitle : ''); ?></title>
<meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' name='viewport'>
<link href="<?= APP_URL; ?>assets/vendor/admin-lte/bootstrap/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<link href="<?= APP_URL; ?>assets/vendor/admin-lte/dist/css/AdminLTE.min.css" rel="stylesheet" type="text/css" />
<link href="<?= APP_URL; ?>assets/css/ansi-colors.css" rel="stylesheet" type="text/css" />
<link href="<?= APP_URL; ?>assets/css/main.css" rel="stylesheet" type="text/css" />
<link href="<?= APP_URL; ?>assets/vendor/font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css" />
<link href="<?= APP_URL; ?>assets/vendor/ionicons/css/ionicons.min.css" rel="stylesheet" type="text/css" />
<script src="<?= APP_URL; ?>assets/vendor/admin-lte/plugins/jQuery/jquery-2.2.3.min.js"></script>
<script src="<?= APP_URL; ?>assets/js/class.js"></script>
<script src="<?= APP_URL; ?>assets/vendor/sprintf-js/dist/sprintf.min.js"></script>
<script src="<?= APP_URL; ?>assets/js/app.js?v2" type="text/javascript"></script>
</head>
<body class="hold-transition skin-black layout-top-nav">
<div class="wrapper">
<header class="main-header">
<nav class="navbar navbar-static-top">
<div class="container">
<div class="navbar-header">
<a href="<?= APP_URL; ?>" class="logo" title="PHP Censor" style="background-color: #222D32; width: 170px; padding: 0;">
<img src="<?= APP_URL; ?>assets/img/php-censor-white.svg" width="170" height="auto" alt="PHP Censor" />
</a>
</div>
</div>
</nav>
</header>
<div class="content-wrapper">
<div class="container">
<section class="content" style="padding: 15px 0 15px;">
<?= $content; ?>
</section>
</div>
</div>
</div>
</body>
</html>

152
src/WebController.php Normal file
View file

@ -0,0 +1,152 @@
<?php
namespace PHPCensor;
use PHPCensor\Exception\HttpException\ForbiddenException;
use PHPCensor\Http\Response;
use PHPCensor\Http\Request;
use PHPCensor\Store\Factory;
use PHPCensor\Model\User;
use PHPCensor\Store\UserStore;
abstract class WebController extends Controller
{
/**
* @var string
*/
protected $className;
/**
* @var View
*/
protected $view = null;
/**
* @var string
*/
public $layoutName = '';
/**
* @var View
*/
public $layout = null;
/**
* @param Config $config
* @param Request $request
*/
public function __construct(Config $config, Request $request)
{
parent::__construct($config, $request);
$class = explode('\\', get_class($this));
$this->className = substr(array_pop($class), 0, -10);
}
public function init()
{
if (!empty($this->layoutName)) {
$this->layout = new View($this->layoutName);
$this->layout->title = 'PHP Censor';
$this->layout->breadcrumb = [];
$this->layout->version = trim(file_get_contents(ROOT_DIR . 'VERSION.md'));
$groups = [];
$groupStore = Factory::getStore('ProjectGroup');
$groupList = $groupStore->getWhere([], 100, 0, ['title' => 'ASC']);
foreach ($groupList['items'] as $group) {
$thisGroup = ['title' => $group->getTitle()];
$projects = Factory::getStore('Project')->getByGroupId($group->getId(), false);
$thisGroup['projects'] = $projects['items'];
$groups[] = $thisGroup;
}
$archivedProjects = Factory::getStore('Project')->getAll(true);
$this->layout->archived_projects = $archivedProjects['items'];
$this->layout->groups = $groups;
}
}
/**
* Handle the incoming request.
*
* @param string $action
* @param array $actionParams
*
* @return Response
*/
public function handleAction($action, $actionParams)
{
if (View::exists($this->className . '/' . $action)) {
$this->view = new View($this->className . '/' . $action);
}
$result = parent::handleAction($action, $actionParams);
if ($result instanceof Response) {
return $result;
}
$content = '';
if (is_string($result)) {
$content = $result;
} elseif ($this->view) {
$content = $this->view->render();
}
$response = new Response();
if ($this->layout) {
$this->layout->content = $content;
$response->setContent($this->layout->render());
} else {
$response->setContent($content);
}
return $response;
}
/**
* Require that the currently logged in user is an administrator.
*
* @throws ForbiddenException
*/
protected function requireAdmin()
{
if (!$this->currentUserIsAdmin()) {
throw new ForbiddenException('You do not have permission to do that.');
}
}
/**
* Check if the currently logged in user is an administrator.
*
* @return boolean
*/
protected function currentUserIsAdmin()
{
$user = $this->getUser();
if (!$user) {
return false;
}
return $this->getUser()->getIsAdmin();
}
/**
* @return User|null
*/
protected function getUser()
{
if (empty($_SESSION['php-censor-user-id'])) {
return null;
}
/** @var UserStore $userStore */
$userStore = Factory::getStore('User');
return $userStore->getById($_SESSION['php-censor-user-id']);
}
}