* @package PHPCI * @subpackage Web */ class BuildController extends \PHPCI\Controller { /** * @var \PHPCI\Store\BuildStore */ protected $buildStore; /** * @var \PHPCI\Service\BuildService */ protected $buildService; public function init() { $this->buildStore = b8\Store\Factory::getStore('Build'); $this->buildService = new BuildService($this->buildStore); } /** * View a specific build. */ public function view($buildId) { try { $build = BuildFactory::getBuildById($buildId); } catch (\Exception $ex) { $build = null; } if (empty($build)) { throw new NotFoundException('Build with ID: ' . $buildId . ' does not exist.'); } $this->view->plugins = $this->getUiPlugins(); $this->view->build = $build; $this->view->data = $this->getBuildData($build); $this->layout->title = 'Build #' . $build->getId(); $this->layout->subtitle = $build->getProjectTitle(); $nav = array( 'title' => 'Build '.$build->getId(), 'icon' => 'cog', 'links' => array( 'build/rebuild/' . $build->getId() => 'Rebuild Now', ), ); if ($this->currentUserIsAdmin()) { $nav['links']['build/delete/' . $build->getId()] = 'Delete Build'; } $this->layout->nav = $nav; } protected function getUiPlugins() { $rtn = array(); $path = APPLICATION_PATH . 'public/assets/js/build-plugins/'; $dir = opendir($path); while ($item = readdir($dir)) { if (substr($item, 0, 1) == '.' || substr($item, -3) != '.js') { continue; } $rtn[] = $item; } return $rtn; } /** * AJAX call to get build data: */ public function data($buildId) { die($this->getBuildData(BuildFactory::getBuildById($buildId))); } /** * AJAX call to get build meta: */ public function meta($buildId) { $build = BuildFactory::getBuildById($buildId); $key = $this->getParam('key', null); $numBuilds = $this->getParam('num_builds', 1); $data = null; if ($key && $build) { $data = $this->buildStore->getMeta($key, $build->getProjectId(), $buildId, $numBuilds); } die(json_encode($data)); } /** * Get build data from database and json encode it: */ protected function getBuildData($build) { $data = array(); $data['status'] = (int)$build->getStatus(); $data['log'] = $this->cleanLog($build->getLog()); $data['created'] = !is_null($build->getCreated()) ? $build->getCreated()->format('Y-m-d H:i:s') : null; $data['started'] = !is_null($build->getStarted()) ? $build->getStarted()->format('Y-m-d H:i:s') : null; $data['finished'] = !is_null($build->getFinished()) ? $build->getFinished()->format('Y-m-d H:i:s') : null; return json_encode($data); } /** * Create a build using an existing build as a template: */ public function rebuild($buildId) { $copy = BuildFactory::getBuildById($buildId); if (empty($copy)) { throw new NotFoundException('Build with ID: ' . $buildId . ' does not exist.'); } $build = $this->buildService->createDuplicateBuild($copy); header('Location: '.PHPCI_URL.'build/view/' . $build->getId()); exit; } /** * Delete a build. */ public function delete($buildId) { $this->requireAdmin(); $build = BuildFactory::getBuildById($buildId); if (empty($build)) { throw new NotFoundException('Build with ID: ' . $buildId . ' does not exist.'); } $this->buildService->deleteBuild($build); header('Location: '.PHPCI_URL.'project/view/' . $build->getProjectId()); exit; } /** * Parse log for unix colours and replace with HTML. */ protected function cleanLog($log) { $log = str_replace('[0;32m', '', $log); $log = str_replace('[0;31m', '', $log); $log = str_replace('[0m', '', $log); return $log; } public function latest() { $rtn = array( 'pending' => $this->formatBuilds($this->buildStore->getByStatus(Build::STATUS_NEW)), 'running' => $this->formatBuilds($this->buildStore->getByStatus(Build::STATUS_RUNNING)), ); if ($this->request->isAjax()) { die(json_encode($rtn)); } } protected function formatBuilds($builds) { Project::$sleepable = array('id', 'title', 'reference', 'type'); $rtn = array('count' => $builds['count'], 'items' => array()); foreach ($builds['items'] as $build) { $item = $build->toArray(1); $header = new b8\View('Build/header-row'); $header->build = $build; $item['header_row'] = $header->render(); $rtn['items'][$item['id']] = $item; } ksort($rtn['items']); return $rtn; } }