merged current upstream/master
|
@ -14,7 +14,7 @@ use b8\Exception\HttpException;
|
|||
use b8\Http\Response;
|
||||
use b8\Http\Response\RedirectResponse;
|
||||
use b8\View;
|
||||
use Symfony\Component\Yaml\Parser;
|
||||
use PHPCI\Model\Build;
|
||||
|
||||
/**
|
||||
* PHPCI Front Controller
|
||||
|
@ -30,15 +30,15 @@ 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['user_id'])) {
|
||||
$user = b8\Store\Factory::getStore('User')->getByPrimaryKey($_SESSION['user_id']);
|
||||
if (!empty($_SESSION['phpci_user_id'])) {
|
||||
$user = b8\Store\Factory::getStore('User')->getByPrimaryKey($_SESSION['phpci_user_id']);
|
||||
|
||||
if ($user) {
|
||||
$_SESSION['user'] = $user;
|
||||
$_SESSION['phpci_user'] = $user;
|
||||
return true;
|
||||
}
|
||||
|
||||
unset($_SESSION['user_id']);
|
||||
unset($_SESSION['phpci_user_id']);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -46,7 +46,7 @@ class Application extends b8\Application
|
|||
|
||||
// load settings to check if there's a configured default user and auth disabled
|
||||
$skipAuth = function () {
|
||||
$parser = new Parser();
|
||||
/** $parser = new Parser();
|
||||
$yaml = file_get_contents(APPLICATION_PATH . 'PHPCI/config.yml');
|
||||
$settings = $parser->parse($yaml);
|
||||
if ((!empty($settings['phpci']['authentication_settings']['state'])
|
||||
|
@ -61,7 +61,7 @@ class Application extends b8\Application
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
return false;
|
||||
};
|
||||
|
||||
|
@ -74,7 +74,7 @@ class Application extends b8\Application
|
|||
$response->setResponseCode(401);
|
||||
$response->setContent('');
|
||||
} else {
|
||||
$_SESSION['login_redirect'] = substr($request->getPath(), 1);
|
||||
$_SESSION['phpci_login_redirect'] = substr($request->getPath(), 1);
|
||||
$response = new RedirectResponse($response);
|
||||
$response->setHeader('Location', PHPCI_URL.'session/login');
|
||||
}
|
||||
|
@ -113,18 +113,30 @@ class Application extends b8\Application
|
|||
$this->response->setContent($view->render());
|
||||
}
|
||||
|
||||
if (View::exists('layout') && $this->response->hasLayout()) {
|
||||
$view = new View('layout');
|
||||
$pageTitle = $this->config->get('page_title', null);
|
||||
if ($this->response->hasLayout()) {
|
||||
$this->setLayoutVariables($this->controller->layout);
|
||||
|
||||
if (!is_null($pageTitle)) {
|
||||
$view->title = $pageTitle;
|
||||
}
|
||||
|
||||
$view->content = $this->response->getContent();
|
||||
$this->response->setContent($view->render());
|
||||
$this->controller->layout->content = $this->response->getContent();
|
||||
$this->response->setContent($this->controller->layout->render());
|
||||
}
|
||||
|
||||
return $this->response;
|
||||
}
|
||||
|
||||
protected function loadController($class)
|
||||
{
|
||||
$controller = parent::loadController($class);
|
||||
$controller->layout = new View('layout');
|
||||
$controller->layout->title = 'PHPCI';
|
||||
$controller->layout->breadcrumb = array();
|
||||
|
||||
return $controller;
|
||||
}
|
||||
|
||||
protected function setLayoutVariables(View &$layout)
|
||||
{
|
||||
/** @var \PHPCI\Store\ProjectStore $projectStore */
|
||||
$projectStore = b8\Store\Factory::getStore('Project');
|
||||
$layout->projects = $projectStore->getAll();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,11 +36,6 @@ class Builder implements LoggerAwareInterface
|
|||
*/
|
||||
public $ignore = array();
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $ciDir;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
|
@ -287,10 +282,7 @@ class Builder implements LoggerAwareInterface
|
|||
*/
|
||||
protected function setupBuild()
|
||||
{
|
||||
$buildId = 'project' . $this->build->getProject()->getId()
|
||||
. '-build' . $this->build->getId();
|
||||
$this->ciDir = dirname(dirname(__FILE__) . '/../') . '/';
|
||||
$this->buildPath = $this->ciDir . 'build/' . $buildId . '/';
|
||||
$this->buildPath = PHPCI_DIR . 'PHPCI/build/' . $this->build->getId() . '/';
|
||||
$this->build->currentBuildPath = $this->buildPath;
|
||||
|
||||
$this->interpolator->setupInterpolationVars(
|
||||
|
|
|
@ -75,7 +75,8 @@ class DaemoniseCommand extends Command
|
|||
$this->run = true;
|
||||
$this->sleep = 0;
|
||||
$runner = new RunCommand($this->logger);
|
||||
$runner->setBaxBuilds(1);
|
||||
$runner->setMaxBuilds(1);
|
||||
$runner->setIsDaemon(true);
|
||||
|
||||
$emptyInput = new ArgvInput(array());
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@ use Symfony\Component\Console\Output\OutputInterface;
|
|||
use Symfony\Component\Console\Helper\DialogHelper;
|
||||
use PHPCI\Service\UserService;
|
||||
|
||||
|
||||
/**
|
||||
* Install console command - Installs PHPCI.
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
|
@ -32,10 +31,23 @@ use PHPCI\Service\UserService;
|
|||
*/
|
||||
class InstallCommand extends Command
|
||||
{
|
||||
protected $configFilePath;
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$defaultPath = PHPCI_DIR . 'PHPCI/config.yml';
|
||||
|
||||
$this
|
||||
->setName('phpci:install')
|
||||
->addOption('url', null, InputOption::VALUE_OPTIONAL, 'PHPCI Installation URL')
|
||||
->addOption('db-host', null, InputOption::VALUE_OPTIONAL, 'Database hostname')
|
||||
->addOption('db-name', null, InputOption::VALUE_OPTIONAL, 'Database name')
|
||||
->addOption('db-user', null, InputOption::VALUE_OPTIONAL, 'Database username')
|
||||
->addOption('db-pass', null, InputOption::VALUE_OPTIONAL, 'Database password')
|
||||
->addOption('admin-name', null, InputOption::VALUE_OPTIONAL, 'Admin username')
|
||||
->addOption('admin-pass', null, InputOption::VALUE_OPTIONAL, 'Admin password')
|
||||
->addOption('admin-mail', null, InputOption::VALUE_OPTIONAL, 'Admin e-mail')
|
||||
->addOption('config-path', null, InputOption::VALUE_OPTIONAL, 'Config file path', $defaultPath)
|
||||
->setDescription('Install PHPCI.');
|
||||
}
|
||||
|
||||
|
@ -44,6 +56,8 @@ class InstallCommand extends Command
|
|||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$this->configFilePath = $input->getOption('config-path');
|
||||
|
||||
$this->verifyNotInstalled($output);
|
||||
|
||||
$output->writeln('');
|
||||
|
@ -58,60 +72,39 @@ class InstallCommand extends Command
|
|||
$output->writeln('-------------------------------------');
|
||||
$output->writeln('');
|
||||
|
||||
|
||||
/**
|
||||
* @var \Symfony\Component\Console\Helper\DialogHelper
|
||||
*/
|
||||
$dialog = $this->getHelperSet()->get('dialog');
|
||||
|
||||
// ----
|
||||
// Get MySQL connection information and verify that it works:
|
||||
// ----
|
||||
$connectionVerified = false;
|
||||
|
||||
while (!$connectionVerified) {
|
||||
$db = array();
|
||||
$db['servers']['read'] = $dialog->ask($output, 'Please enter your MySQL host [localhost]: ', 'localhost');
|
||||
$db['servers']['write'] = $db['servers']['read'];
|
||||
$db['name'] = $dialog->ask($output, 'Please enter your database name [phpci]: ', 'phpci');
|
||||
$db['username'] = $dialog->ask($output, 'Please enter your database username [phpci]: ', 'phpci');
|
||||
$db['password'] = $dialog->askHiddenResponse($output, 'Please enter your database password: ');
|
||||
$db = $this->getDatabaseInformation($input, $output);
|
||||
|
||||
$connectionVerified = $this->verifyDatabaseDetails($db, $output);
|
||||
}
|
||||
|
||||
$output->writeln('');
|
||||
|
||||
$conf = array();
|
||||
$conf['b8']['database'] = $db;
|
||||
|
||||
// ----
|
||||
// Get basic installation details (URL, etc)
|
||||
// ----
|
||||
|
||||
$conf = array();
|
||||
$conf['b8']['database'] = $db;
|
||||
$conf['phpci']['url'] = $dialog->askAndValidate(
|
||||
$output,
|
||||
'Your PHPCI URL ("http://phpci.local" for example): ',
|
||||
function ($answer) {
|
||||
if (!filter_var($answer, FILTER_VALIDATE_URL)) {
|
||||
throw new Exception('Must be a valid URL');
|
||||
}
|
||||
|
||||
return rtrim($answer, '/');
|
||||
},
|
||||
false
|
||||
);
|
||||
$conf['phpci'] = $this->getPhpciConfigInformation($input, $output);
|
||||
|
||||
$this->writeConfigFile($conf);
|
||||
$this->setupDatabase($output);
|
||||
$this->createAdminUser($output, $dialog);
|
||||
$admin = $this->getAdminInforamtion($input, $output);
|
||||
$this->createAdminUser($admin, $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check PHP version, required modules and for disabled functions.
|
||||
*
|
||||
* @param OutputInterface $output
|
||||
* @throws \Exception
|
||||
*/
|
||||
|
||||
protected function checkRequirements(OutputInterface $output)
|
||||
{
|
||||
$output->write('Checking requirements...');
|
||||
|
@ -160,6 +153,127 @@ class InstallCommand extends Command
|
|||
$output->writeln('');
|
||||
}
|
||||
|
||||
/**
|
||||
* Load information for admin user form CLI options or ask info to user.
|
||||
*
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
* @return array
|
||||
*/
|
||||
protected function getAdminInforamtion(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$admin = array();
|
||||
|
||||
/**
|
||||
* @var \Symfony\Component\Console\Helper\DialogHelper
|
||||
*/
|
||||
$dialog = $this->getHelperSet()->get('dialog');
|
||||
|
||||
// Function to validate mail address.
|
||||
$mailValidator =function ($answer) {
|
||||
if (!filter_var($answer, FILTER_VALIDATE_EMAIL)) {
|
||||
throw new Exception('Must be a valid email address.');
|
||||
}
|
||||
|
||||
return $answer;
|
||||
};
|
||||
|
||||
if ($adminEmail = $input->getOption('admin-mail')) {
|
||||
$adminEmail = $mailValidator($adminEmail);
|
||||
} else {
|
||||
$adminEmail = $dialog->askAndValidate($output, 'Your email address: ', $mailValidator, false);
|
||||
}
|
||||
if (!$adminName = $input->getOption('admin-name')) {
|
||||
$adminName = $dialog->ask($output, 'Enter your name: ');
|
||||
}
|
||||
if (!$adminPass = $input->getOption('admin-pass')) {
|
||||
$adminPass = $dialog->askHiddenResponse($output, 'Enter your desired admin password: ');
|
||||
}
|
||||
|
||||
$admin['mail'] = $adminEmail;
|
||||
$admin['name'] = $adminName;
|
||||
$admin['pass'] = $adminPass;
|
||||
|
||||
return $admin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load configuration for PHPCI form CLI options or ask info to user.
|
||||
*
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
* @return array
|
||||
*/
|
||||
protected function getPhpciConfigInformation(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$phpci = array();
|
||||
|
||||
/**
|
||||
* @var \Symfony\Component\Console\Helper\DialogHelper
|
||||
*/
|
||||
$dialog = $this->getHelperSet()->get('dialog');
|
||||
|
||||
// FUnction do validate URL.
|
||||
$urlValidator = function ($answer) {
|
||||
if (!filter_var($answer, FILTER_VALIDATE_URL)) {
|
||||
throw new Exception('Must be a valid URL');
|
||||
}
|
||||
|
||||
return rtrim($answer, '/');
|
||||
};
|
||||
|
||||
if ($url = $input->getOption('url')) {
|
||||
$url = $urlValidator($url);
|
||||
} else {
|
||||
$url = $dialog->askAndValidate($output, 'Your PHPCI URL ("http://phpci.local" for example): ', $urlValidator, false);
|
||||
}
|
||||
|
||||
$phpci['url'] = $url;
|
||||
|
||||
return $phpci;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load configuration for DB form CLI options or ask info to user.
|
||||
*
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
* @return array
|
||||
*/
|
||||
protected function getDatabaseInformation(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$db = array();
|
||||
|
||||
/**
|
||||
* @var \Symfony\Component\Console\Helper\DialogHelper
|
||||
*/
|
||||
$dialog = $this->getHelperSet()->get('dialog');
|
||||
|
||||
if (!$dbHost = $input->getOption('db-host')) {
|
||||
$dbHost = $dialog->ask($output, 'Please enter your MySQL host [localhost]: ', 'localhost');
|
||||
}
|
||||
|
||||
if (!$dbName = $input->getOption('db-name')) {
|
||||
$dbName = $dialog->ask($output, 'Please enter your database name [phpci]: ', 'phpci');
|
||||
}
|
||||
|
||||
if (!$dbUser = $input->getOption('db-user')) {
|
||||
$dbUser = $dialog->ask($output, 'Please enter your database username [phpci]: ', 'phpci');
|
||||
}
|
||||
|
||||
if (!$dbPass = $input->getOption('db-pass')) {
|
||||
$dbPass = $dialog->askHiddenResponse($output, 'Please enter your database password: ');
|
||||
}
|
||||
|
||||
$db['servers']['read'] = $dbHost;
|
||||
$db['servers']['write'] = $dbHost;
|
||||
$db['name'] = $dbName;
|
||||
$db['username'] = $dbUser;
|
||||
$db['password'] = $dbPass;
|
||||
|
||||
return $db;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try and connect to MySQL using the details provided.
|
||||
* @param array $db
|
||||
|
@ -198,9 +312,9 @@ class InstallCommand extends Command
|
|||
protected function writeConfigFile(array $config)
|
||||
{
|
||||
$dumper = new \Symfony\Component\Yaml\Dumper();
|
||||
$yaml = $dumper->dump($config, 2);
|
||||
$yaml = $dumper->dump($config, 4);
|
||||
|
||||
file_put_contents(PHPCI_DIR . 'PHPCI/config.yml', $yaml);
|
||||
file_put_contents($this->configFilePath, $yaml);
|
||||
}
|
||||
|
||||
protected function setupDatabase(OutputInterface $output)
|
||||
|
@ -213,34 +327,19 @@ class InstallCommand extends Command
|
|||
}
|
||||
|
||||
/**
|
||||
* Create admin user using information loaded before.
|
||||
*
|
||||
* @param array $admin
|
||||
* @param OutputInterface $output
|
||||
* @param DialogHelper $dialog
|
||||
*/
|
||||
protected function createAdminUser(OutputInterface $output, DialogHelper $dialog)
|
||||
protected function createAdminUser($admin, $output)
|
||||
{
|
||||
// Try to create a user account:
|
||||
$adminEmail = $dialog->askAndValidate(
|
||||
$output,
|
||||
'Your email address: ',
|
||||
function ($answer) {
|
||||
if (!filter_var($answer, FILTER_VALIDATE_EMAIL)) {
|
||||
throw new Exception('Must be a valid email address.');
|
||||
}
|
||||
|
||||
return $answer;
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
$adminPass = $dialog->askHiddenResponse($output, 'Enter your desired admin password: ');
|
||||
$adminName = $dialog->ask($output, 'Enter your name: ');
|
||||
|
||||
try {
|
||||
$this->reloadConfig();
|
||||
|
||||
$userStore = Factory::getStore('User');
|
||||
$userService = new UserService($userStore);
|
||||
$userService->createUser($adminName, $adminEmail, $adminPass, 1);
|
||||
$userService->createUser($admin['name'], $admin['mail'], $admin['pass'], 1);
|
||||
|
||||
$output->writeln('<info>User account created!</info>');
|
||||
} catch (\Exception $ex) {
|
||||
|
@ -252,11 +351,10 @@ class InstallCommand extends Command
|
|||
|
||||
protected function reloadConfig()
|
||||
{
|
||||
$configFile = PHPCI_DIR . 'PHPCI/config.yml';
|
||||
$config = Config::getInstance();
|
||||
$config = Config::getInstance();
|
||||
|
||||
if (file_exists($configFile)) {
|
||||
$config->loadYaml($configFile);
|
||||
if (file_exists($this->configFilePath)) {
|
||||
$config->loadYaml($this->configFilePath);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -265,11 +363,11 @@ class InstallCommand extends Command
|
|||
*/
|
||||
protected function verifyNotInstalled(OutputInterface $output)
|
||||
{
|
||||
if (file_exists(PHPCI_DIR . 'PHPCI/config.yml')) {
|
||||
$content = file_get_contents(PHPCI_DIR . 'PHPCI/config.yml');
|
||||
if (file_exists($this->configFilePath)) {
|
||||
$content = file_get_contents($this->configFilePath);
|
||||
|
||||
if (!empty($content)) {
|
||||
$output->writeln('<error>PHPCI/config.yml exists and is not empty.</error>');
|
||||
$output->writeln('<error>The PHPCI config file exists and is not empty.</error>');
|
||||
$output->writeln('<error>If you were trying to update PHPCI, please use phpci:update instead.</error>');
|
||||
die;
|
||||
}
|
||||
|
|
|
@ -75,6 +75,7 @@ class PollCommand extends Command
|
|||
|
||||
$last_commit = $commits['body'][0]['sha'];
|
||||
$last_committer = $commits['body'][0]['commit']['committer']['email'];
|
||||
$message = $commits['body'][0]['commit']['message'];
|
||||
|
||||
$this->logger->info("Last commit to github for " . $project->getTitle() . " is " . $last_commit);
|
||||
|
||||
|
@ -89,6 +90,7 @@ class PollCommand extends Command
|
|||
$build->setStatus(Build::STATUS_NEW);
|
||||
$build->setBranch($project->getBranch());
|
||||
$build->setCreated(new \DateTime());
|
||||
$build->setCommitMessage($message);
|
||||
if (!empty($last_committer)) {
|
||||
$build->setCommitterEmail($last_committer);
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
namespace PHPCI\Command;
|
||||
|
||||
use b8\Config;
|
||||
use Monolog\Logger;
|
||||
use PHPCI\Logging\BuildDBLogHandler;
|
||||
use PHPCI\Logging\LoggedBuildContextTidier;
|
||||
|
@ -47,6 +48,11 @@ class RunCommand extends Command
|
|||
*/
|
||||
protected $maxBuilds = null;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $isFromDaemon = false;
|
||||
|
||||
/**
|
||||
* @param \Monolog\Logger $logger
|
||||
* @param string $name
|
||||
|
@ -73,14 +79,15 @@ class RunCommand extends Command
|
|||
|
||||
// For verbose mode we want to output all informational and above
|
||||
// messages to the symphony output interface.
|
||||
if ($input->hasOption('verbose')) {
|
||||
if ($input->hasOption('verbose') && $input->getOption('verbose')) {
|
||||
$this->logger->pushHandler(
|
||||
new OutputLogHandler($this->output, Logger::INFO)
|
||||
);
|
||||
}
|
||||
|
||||
$this->logger->pushProcessor(new LoggedBuildContextTidier());
|
||||
$running = $this->validateRunningBuilds();
|
||||
|
||||
$this->logger->pushProcessor(new LoggedBuildContextTidier());
|
||||
$this->logger->addInfo("Finding builds to process");
|
||||
$store = Factory::getStore('Build');
|
||||
$result = $store->getByStatus(0, $this->maxBuilds);
|
||||
|
@ -88,11 +95,22 @@ class RunCommand extends Command
|
|||
|
||||
$builds = 0;
|
||||
|
||||
foreach ($result['items'] as $build) {
|
||||
$builds++;
|
||||
|
||||
while (count($result['items'])) {
|
||||
$build = array_shift($result['items']);
|
||||
$build = 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)) {
|
||||
$this->logger->addInfo('Skipping Build #'.$build->getId() . ' - Project build already in progress.');
|
||||
$result['items'][] = $build;
|
||||
|
||||
// Re-run build validator:
|
||||
$running = $this->validateRunningBuilds();
|
||||
continue;
|
||||
}
|
||||
|
||||
$builds++;
|
||||
|
||||
try {
|
||||
// Logging relevant to this build should be stored
|
||||
// against the build itself.
|
||||
|
@ -107,6 +125,7 @@ class RunCommand extends Command
|
|||
$this->logger->popHandler($buildDbLog);
|
||||
} catch (\Exception $ex) {
|
||||
$build->setStatus(Build::STATUS_FAILED);
|
||||
$build->setFinished(new \DateTime());
|
||||
$build->setLog($build->getLog() . PHP_EOL . PHP_EOL . $ex->getMessage());
|
||||
$store->save($build);
|
||||
}
|
||||
|
@ -118,8 +137,59 @@ class RunCommand extends Command
|
|||
return $builds;
|
||||
}
|
||||
|
||||
public function setBaxBuilds($numBuilds)
|
||||
public function setMaxBuilds($numBuilds)
|
||||
{
|
||||
$this->maxBuilds = (int)$numBuilds;
|
||||
}
|
||||
|
||||
public function setIsDaemon($fromDaemon)
|
||||
{
|
||||
$this->isFromDaemon = (bool)$fromDaemon;
|
||||
}
|
||||
|
||||
protected function validateRunningBuilds()
|
||||
{
|
||||
/** @var \PHPCI\Store\BuildStore $store */
|
||||
$store = Factory::getStore('Build');
|
||||
$running = $store->getByStatus(1);
|
||||
$rtn = array();
|
||||
|
||||
$timeout = Config::getInstance()->get('phpci.build.failed_after', 1800);
|
||||
|
||||
foreach ($running['items'] as $build) {
|
||||
/** @var \PHPCI\Model\Build $build */
|
||||
$build = BuildFactory::getBuild($build);
|
||||
|
||||
$now = time();
|
||||
$start = $build->getStarted()->getTimestamp();
|
||||
|
||||
if (($now - $start) > $timeout) {
|
||||
$this->logger->addInfo('Build #'.$build->getId().' marked as failed due to timeout.');
|
||||
$build->setStatus(Build::STATUS_FAILED);
|
||||
$build->setFinished(new \DateTime());
|
||||
$store->save($build);
|
||||
$this->removeBuildDirectory($build);
|
||||
continue;
|
||||
}
|
||||
|
||||
$rtn[$build->getProjectId()] = true;
|
||||
}
|
||||
|
||||
return $rtn;
|
||||
}
|
||||
|
||||
protected function removeBuildDirectory($build)
|
||||
{
|
||||
$buildPath = PHPCI_DIR . 'PHPCI/build/' . $build->getId() . '/';
|
||||
|
||||
if (is_dir($buildPath)) {
|
||||
$cmd = 'rm -Rf "%s"';
|
||||
|
||||
if (IS_WIN) {
|
||||
$cmd = 'rmdir /S /Q "%s"';
|
||||
}
|
||||
|
||||
shell_exec($cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,10 +72,23 @@ class Controller extends \b8\Controller
|
|||
return $this->response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Require that the currently logged in user is an administrator.
|
||||
* @throws ForbiddenException
|
||||
*/
|
||||
protected function requireAdmin()
|
||||
{
|
||||
if (!$_SESSION['user']->getIsAdmin()) {
|
||||
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 bool
|
||||
*/
|
||||
protected function currentUserIsAdmin()
|
||||
{
|
||||
return $_SESSION['phpci_user']->getIsAdmin();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ use b8;
|
|||
use b8\Exception\HttpException\NotFoundException;
|
||||
use PHPCI\BuildFactory;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\Model\Project;
|
||||
use PHPCI\Service\BuildService;
|
||||
|
||||
/**
|
||||
|
@ -58,8 +59,22 @@ class BuildController extends \PHPCI\Controller
|
|||
$this->view->build = $build;
|
||||
$this->view->data = $this->getBuildData($build);
|
||||
|
||||
$title = 'Build #' . $build->getId() . ' - ' . $build->getProjectTitle();
|
||||
$this->config->set('page_title', $title);
|
||||
$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()
|
||||
|
@ -141,9 +156,7 @@ class BuildController extends \PHPCI\Controller
|
|||
*/
|
||||
public function delete($buildId)
|
||||
{
|
||||
if (empty($_SESSION['user']) || !$_SESSION['user']->getIsAdmin()) {
|
||||
throw new \Exception('You do not have permission to do that.');
|
||||
}
|
||||
$this->requireAdmin();
|
||||
|
||||
$build = BuildFactory::getBuildById($buildId);
|
||||
|
||||
|
@ -168,4 +181,36 @@ class BuildController extends \PHPCI\Controller
|
|||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,23 +68,15 @@ class BuildStatusController extends \PHPCI\Controller
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the appropriate build status image for a given project.
|
||||
* Returns the appropriate build status image in SVG format for a given project.
|
||||
*/
|
||||
public function image($projectId)
|
||||
{
|
||||
$status = $this->getStatus($projectId);
|
||||
header('Content-Type: image/png');
|
||||
die(file_get_contents(APPLICATION_PATH . 'public/assets/img/build-' . $status . '.png'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the appropriate build status image in SVG format for a given project.
|
||||
*/
|
||||
public function svg($projectId)
|
||||
{
|
||||
$status = $this->getStatus($projectId);
|
||||
$color = ($status == 'passing') ? 'green' : 'red';
|
||||
|
||||
header('Content-Type: image/svg+xml');
|
||||
die(file_get_contents(APPLICATION_PATH . 'public/assets/img/build-' . $status . '.svg'));
|
||||
die(file_get_contents('http://img.shields.io/badge/build-' . $status . '-' . $color . '.svg'));
|
||||
}
|
||||
|
||||
public function view($projectId)
|
||||
|
|
|
@ -11,6 +11,7 @@ namespace PHPCI\Controller;
|
|||
|
||||
use b8;
|
||||
use PHPCI\BuildFactory;
|
||||
use PHPCI\Model\Build;
|
||||
|
||||
/**
|
||||
* Home Controller - Displays the PHPCI Dashboard.
|
||||
|
@ -41,14 +42,20 @@ class HomeController extends \PHPCI\Controller
|
|||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->layout->title = 'Dashboard';
|
||||
|
||||
$projects = $this->projectStore->getWhere(array(), 50, 0, array(), array('title' => 'ASC'));
|
||||
|
||||
$this->view->builds = $this->getLatestBuildsHtml();
|
||||
$builds = $this->buildStore->getLatestBuilds(null, 10);
|
||||
|
||||
foreach ($builds as &$build) {
|
||||
$build = BuildFactory::getBuild($build);
|
||||
}
|
||||
|
||||
$this->view->builds = $builds;
|
||||
$this->view->projects = $projects['items'];
|
||||
$this->view->summary = $this->getSummaryHtml($projects);
|
||||
|
||||
$this->config->set('page_title', 'Dashboard');
|
||||
|
||||
return $this->view->render();
|
||||
}
|
||||
|
||||
|
@ -69,13 +76,24 @@ class HomeController extends \PHPCI\Controller
|
|||
protected function getSummaryHtml($projects)
|
||||
{
|
||||
$summaryBuilds = array();
|
||||
$successes = array();
|
||||
$failures = array();
|
||||
|
||||
foreach ($projects['items'] as $project) {
|
||||
$summaryBuilds[$project->getId()] = $this->buildStore->getLatestBuilds($project->getId());
|
||||
|
||||
$success = $this->buildStore->getLastBuildByStatus($project->getId(), Build::STATUS_SUCCESS);
|
||||
$failure = $this->buildStore->getLastBuildByStatus($project->getId(), Build::STATUS_FAILED);
|
||||
|
||||
$successes[$project->getId()] = $success;
|
||||
$failures[$project->getId()] = $failure;
|
||||
}
|
||||
|
||||
$summaryView = new b8\View('SummaryTable');
|
||||
$summaryView->projects = $projects['items'];
|
||||
$summaryView->builds = $summaryBuilds;
|
||||
$summaryView->successful = $successes;
|
||||
$summaryView->failed = $failures;
|
||||
|
||||
return $summaryView->render();
|
||||
}
|
||||
|
|
|
@ -24,6 +24,10 @@ use PHPCI\Plugin\Util\PluginInformationCollection;
|
|||
class PluginController extends \PHPCI\Controller
|
||||
{
|
||||
protected $required = array(
|
||||
'php',
|
||||
'ext-mcrypt',
|
||||
'ext-pdo',
|
||||
'ext-pdo_mysql',
|
||||
'block8/b8framework',
|
||||
'ircmaxell/password-compat',
|
||||
'swiftmailer/swiftmailer',
|
||||
|
@ -31,7 +35,8 @@ class PluginController extends \PHPCI\Controller
|
|||
'symfony/console',
|
||||
'psr/log',
|
||||
'monolog/monolog',
|
||||
'pimple/pimple'
|
||||
'pimple/pimple',
|
||||
'robmorgan/phinx',
|
||||
);
|
||||
|
||||
protected $canInstall;
|
||||
|
@ -39,9 +44,7 @@ class PluginController extends \PHPCI\Controller
|
|||
|
||||
public function index()
|
||||
{
|
||||
if (!$_SESSION['user']->getIsAdmin()) {
|
||||
throw new \Exception('You do not have permission to do that.');
|
||||
}
|
||||
$this->requireAdmin();
|
||||
|
||||
$this->view->canWrite = is_writable(APPLICATION_PATH . 'composer.json');
|
||||
$this->view->required = $this->required;
|
||||
|
@ -60,16 +63,14 @@ class PluginController extends \PHPCI\Controller
|
|||
|
||||
$this->view->plugins = $pluginInfo->getInstalledPlugins();
|
||||
|
||||
$this->config->set('page_title', 'Plugins');
|
||||
$this->layout->title = 'Plugins';
|
||||
|
||||
return $this->view->render();
|
||||
}
|
||||
|
||||
public function remove()
|
||||
{
|
||||
if (!$_SESSION['user']->getIsAdmin()) {
|
||||
throw new \Exception('You do not have permission to do that.');
|
||||
}
|
||||
$this->requireAdmin();
|
||||
|
||||
$package = $this->getParam('package', null);
|
||||
$json = $this->getComposerJson();
|
||||
|
@ -88,9 +89,7 @@ class PluginController extends \PHPCI\Controller
|
|||
|
||||
public function install()
|
||||
{
|
||||
if (!$_SESSION['user']->getIsAdmin()) {
|
||||
throw new \Exception('You do not have permission to do that.');
|
||||
}
|
||||
$this->requireAdmin();
|
||||
|
||||
$package = $this->getParam('package', null);
|
||||
$version = $this->getParam('version', '*');
|
||||
|
@ -109,9 +108,19 @@ class PluginController extends \PHPCI\Controller
|
|||
return json_decode($json, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert array to json and save composer.json
|
||||
*
|
||||
* @param $array
|
||||
*/
|
||||
protected function setComposerJson($array)
|
||||
{
|
||||
$json = json_encode($array);
|
||||
if (defined('JSON_PRETTY_PRINT')) {
|
||||
$json = json_encode($array, JSON_PRETTY_PRINT);
|
||||
} else {
|
||||
$json = json_encode($array);
|
||||
}
|
||||
|
||||
file_put_contents(APPLICATION_PATH . 'composer.json', $json);
|
||||
}
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@ class ProjectController extends \PHPCI\Controller
|
|||
*/
|
||||
public function view($projectId)
|
||||
{
|
||||
$branch = $this->getParam('branch', '');
|
||||
$project = $this->projectStore->getById($projectId);
|
||||
|
||||
if (empty($project)) {
|
||||
|
@ -72,20 +73,23 @@ class ProjectController extends \PHPCI\Controller
|
|||
|
||||
$per_page = 10;
|
||||
$page = $this->getParam('p', 1);
|
||||
$builds = $this->getLatestBuildsHtml($projectId, (($page - 1) * $per_page));
|
||||
$builds = $this->getLatestBuildsHtml($projectId, urldecode($branch), (($page - 1) * $per_page));
|
||||
$pages = $builds[1] == 0 ? 1 : ceil($builds[1] / $per_page);
|
||||
|
||||
if ($page > $pages) {
|
||||
throw new NotFoundException('Page with number: ' . $page . ' not found');
|
||||
}
|
||||
|
||||
$this->view->builds = $builds[0];
|
||||
$this->view->total = $builds[1];
|
||||
$this->view->project = $project;
|
||||
$this->view->page = $page;
|
||||
$this->view->pages = $pages;
|
||||
$this->view->builds = $builds[0];
|
||||
$this->view->total = $builds[1];
|
||||
$this->view->project = $project;
|
||||
$this->view->branch = urldecode($branch);
|
||||
$this->view->branches = $this->projectStore->getKnownBranches($projectId);
|
||||
$this->view->page = $page;
|
||||
$this->view->pages = $pages;
|
||||
|
||||
$this->config->set('page_title', $project->getTitle());
|
||||
$this->layout->title = $project->getTitle();
|
||||
$this->layout->subtitle = $this->view->branch;
|
||||
|
||||
return $this->view->render();
|
||||
}
|
||||
|
@ -93,16 +97,21 @@ class ProjectController extends \PHPCI\Controller
|
|||
/**
|
||||
* Create a new pending build for a project.
|
||||
*/
|
||||
public function build($projectId)
|
||||
public function build($projectId, $branch = '')
|
||||
{
|
||||
/* @var \PHPCI\Model\Project $project */
|
||||
$project = $this->projectStore->getById($projectId);
|
||||
|
||||
if (empty($branch)) {
|
||||
$branch = $project->getBranch();
|
||||
}
|
||||
|
||||
if (empty($project)) {
|
||||
throw new NotFoundException('Project with id: ' . $projectId . ' not found');
|
||||
}
|
||||
|
||||
$build = $this->buildService->createBuild($project, null, null, $_SESSION['user']->getEmail());
|
||||
$email = $_SESSION['phpci_user']->getEmail();
|
||||
$build = $this->buildService->createBuild($project, null, urldecode($branch), $email);
|
||||
|
||||
header('Location: '.PHPCI_URL.'build/view/' . $build->getId());
|
||||
exit;
|
||||
|
@ -113,9 +122,7 @@ class ProjectController extends \PHPCI\Controller
|
|||
*/
|
||||
public function delete($projectId)
|
||||
{
|
||||
if (!$_SESSION['user']->getIsAdmin()) {
|
||||
throw new ForbiddenException('You do not have permission to do that.');
|
||||
}
|
||||
$this->requireAdmin();
|
||||
|
||||
$project = $this->projectStore->getById($projectId);
|
||||
$this->projectService->deleteProject($project);
|
||||
|
@ -129,16 +136,26 @@ class ProjectController extends \PHPCI\Controller
|
|||
*/
|
||||
public function builds($projectId)
|
||||
{
|
||||
$builds = $this->getLatestBuildsHtml($projectId);
|
||||
$branch = $this->getParam('branch', '');
|
||||
$builds = $this->getLatestBuildsHtml($projectId, urldecode($branch));
|
||||
die($builds[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render latest builds for project as HTML table.
|
||||
*/
|
||||
protected function getLatestBuildsHtml($projectId, $start = 0)
|
||||
* Render latest builds for project as HTML table.
|
||||
*
|
||||
* @param $projectId
|
||||
* @param string $branch A urldecoded branch name.
|
||||
* @param int $start
|
||||
* @return array
|
||||
*/
|
||||
protected function getLatestBuildsHtml($projectId, $branch = '', $start = 0)
|
||||
{
|
||||
$criteria = array('project_id' => $projectId);
|
||||
if (!empty($branch)) {
|
||||
$criteria['branch'] = $branch;
|
||||
}
|
||||
|
||||
$order = array('id' => 'DESC');
|
||||
$builds = $this->buildStore->getWhere($criteria, 10, $start, array(), $order);
|
||||
$view = new b8\View('BuildsTable');
|
||||
|
@ -157,7 +174,7 @@ class ProjectController extends \PHPCI\Controller
|
|||
*/
|
||||
public function add()
|
||||
{
|
||||
$this->config->set('page_title', 'Add Project');
|
||||
$this->layout->title = 'Add Project';
|
||||
$this->requireAdmin();
|
||||
|
||||
$method = $this->request->getMethod();
|
||||
|
@ -208,9 +225,7 @@ class ProjectController extends \PHPCI\Controller
|
|||
*/
|
||||
public function edit($projectId)
|
||||
{
|
||||
if (!$_SESSION['user']->getIsAdmin()) {
|
||||
throw new ForbiddenException('You do not have permission to do that.');
|
||||
}
|
||||
$this->requireAdmin();
|
||||
|
||||
$method = $this->request->getMethod();
|
||||
$project = $this->projectStore->getById($projectId);
|
||||
|
@ -322,7 +337,6 @@ class ProjectController extends \PHPCI\Controller
|
|||
$form->addField($field);
|
||||
|
||||
$field = Form\Element\Text::create('branch', 'Default branch name', true);
|
||||
$field->setValidator($this->getReferenceValidator($values));
|
||||
$field->setClass('form-control')->setContainerClass('form-group')->setValue('master');
|
||||
$form->addField($field);
|
||||
|
||||
|
|
|
@ -40,9 +40,9 @@ class SessionController extends \PHPCI\Controller
|
|||
|
||||
if ($this->request->getMethod() == 'POST') {
|
||||
$user = $this->userStore->getByEmail($this->getParam('email'));
|
||||
|
||||
|
||||
if ($user && password_verify($this->getParam('password', ''), $user->getHash())) {
|
||||
$_SESSION['user_id'] = $user->getId();
|
||||
$_SESSION['phpci_user_id'] = $user->getId();
|
||||
header('Location: ' . $this->getLoginRedirect());
|
||||
die;
|
||||
} else {
|
||||
|
@ -84,7 +84,9 @@ class SessionController extends \PHPCI\Controller
|
|||
*/
|
||||
public function logout()
|
||||
{
|
||||
$_SESSION = array();
|
||||
unset($_SESSION['phpci_user']);
|
||||
unset($_SESSION['phpci_user_id']);
|
||||
|
||||
session_destroy();
|
||||
header('Location: ' . PHPCI_URL);
|
||||
die;
|
||||
|
@ -147,8 +149,8 @@ MSG;
|
|||
$hash = password_hash($this->getParam('password'), PASSWORD_DEFAULT);
|
||||
$user->setHash($hash);
|
||||
|
||||
$_SESSION['user'] = $this->userStore->save($user);
|
||||
$_SESSION['user_id'] = $user->getId();
|
||||
$_SESSION['phpci_user'] = $this->userStore->save($user);
|
||||
$_SESSION['phpci_user_id'] = $user->getId();
|
||||
|
||||
header('Location: ' . PHPCI_URL);
|
||||
die;
|
||||
|
@ -164,9 +166,9 @@ MSG;
|
|||
{
|
||||
$rtn = PHPCI_URL;
|
||||
|
||||
if (!empty($_SESSION['login_redirect'])) {
|
||||
$rtn .= $_SESSION['login_redirect'];
|
||||
$_SESSION['login_redirect'] = null;
|
||||
if (!empty($_SESSION['phpci_login_redirect'])) {
|
||||
$rtn .= $_SESSION['phpci_login_redirect'];
|
||||
$_SESSION['phpci_login_redirect'] = null;
|
||||
}
|
||||
|
||||
return $rtn;
|
||||
|
|
|
@ -41,19 +41,18 @@ class SettingsController extends Controller
|
|||
$this->view->settings = $this->settings;
|
||||
|
||||
$emailSettings = array();
|
||||
$authenticationSettings = array();
|
||||
|
||||
if (isset($this->settings['phpci']['email_settings'])) {
|
||||
$emailSettings = $this->settings['phpci']['email_settings'];
|
||||
}
|
||||
|
||||
if (isset($this->settings['phpci']['authentication_settings'])) {
|
||||
$authenticationSettings = $this->settings['phpci']['authentication_settings'];
|
||||
$buildSettings = array();
|
||||
if (isset($this->settings['phpci']['build'])) {
|
||||
$buildSettings = $this->settings['phpci']['build'];
|
||||
}
|
||||
|
||||
$this->view->github = $this->getGithubForm();
|
||||
$this->view->emailSettings = $this->getEmailForm($emailSettings);
|
||||
$this->view->authenticationSettings = $this->getAuthenticationForm($authenticationSettings);
|
||||
$this->view->buildSettings = $this->getBuildForm($buildSettings);
|
||||
$this->view->isWriteable = $this->canWriteConfig();
|
||||
|
||||
if (!empty($this->settings['phpci']['github']['token'])) {
|
||||
|
@ -65,6 +64,8 @@ class SettingsController extends Controller
|
|||
|
||||
public function github()
|
||||
{
|
||||
$this->requireAdmin();
|
||||
|
||||
$this->settings['phpci']['github']['id'] = $this->getParam('githubid', '');
|
||||
$this->settings['phpci']['github']['secret'] = $this->getParam('githubsecret', '');
|
||||
$error = $this->storeSettings();
|
||||
|
@ -80,6 +81,8 @@ class SettingsController extends Controller
|
|||
|
||||
public function email()
|
||||
{
|
||||
$this->requireAdmin();
|
||||
|
||||
$this->settings['phpci']['email_settings'] = $this->getParams();
|
||||
$this->settings['phpci']['email_settings']['smtp_encryption'] = $this->getParam('smtp_encryption', 0);
|
||||
|
||||
|
@ -94,10 +97,11 @@ class SettingsController extends Controller
|
|||
die;
|
||||
}
|
||||
|
||||
public function authentication()
|
||||
public function build()
|
||||
{
|
||||
$this->settings['phpci']['authentication_settings']['state'] = $this->getParam('disable_authentication', 0);
|
||||
$this->settings['phpci']['authentication_settings']['user_id'] = $_SESSION['user_id'];
|
||||
$this->requireAdmin();
|
||||
|
||||
$this->settings['phpci']['build'] = $this->getParams();
|
||||
|
||||
$error = $this->storeSettings();
|
||||
|
||||
|
@ -110,7 +114,6 @@ class SettingsController extends Controller
|
|||
die;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Github redirects users back to this URL when t
|
||||
*/
|
||||
|
@ -141,11 +144,16 @@ class SettingsController extends Controller
|
|||
die;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert config to yaml and store to file.
|
||||
* @return mixed
|
||||
*/
|
||||
protected function storeSettings()
|
||||
{
|
||||
$dumper = new Dumper();
|
||||
$yaml = $dumper->dump($this->settings);
|
||||
$yaml = $dumper->dump($this->settings, 4);
|
||||
file_put_contents(APPLICATION_PATH . 'PHPCI/config.yml', $yaml);
|
||||
|
||||
if (error_get_last()) {
|
||||
$error_get_last = error_get_last();
|
||||
return $error_get_last['message'];
|
||||
|
@ -243,8 +251,8 @@ class SettingsController extends Controller
|
|||
$field->setContainerClass('form-group');
|
||||
$form->addField($field);
|
||||
|
||||
$field = new Form\Element\Checkbox('smtp_encryption');
|
||||
$field->setCheckedValue(1);
|
||||
$field = new Form\Element\Select('smtp_encryption');
|
||||
$field->setOptions(['' => 'None', 'tls' => 'TLS', 'ssl' => 'SSL']);
|
||||
$field->setRequired(false);
|
||||
$field->setLabel('Use SMTP encryption?');
|
||||
$field->setContainerClass('form-group');
|
||||
|
@ -261,6 +269,51 @@ class SettingsController extends Controller
|
|||
return $form;
|
||||
}
|
||||
|
||||
protected function getGithubUser($token)
|
||||
{
|
||||
$http = new HttpClient('https://api.github.com');
|
||||
$user = $http->get('/user', array('access_token' => $token));
|
||||
|
||||
return $user['body'];
|
||||
}
|
||||
|
||||
protected function canWriteConfig()
|
||||
{
|
||||
return is_writeable(APPLICATION_PATH . 'PHPCI/config.yml');
|
||||
}
|
||||
|
||||
protected function getBuildForm($values = array())
|
||||
{
|
||||
$form = new Form();
|
||||
$form->setMethod('POST');
|
||||
$form->setAction(PHPCI_URL . 'settings/build');
|
||||
|
||||
$field = new Form\Element\Select('failed_after');
|
||||
$field->setRequired(false);
|
||||
$field->setLabel('Consider a build failed after');
|
||||
$field->setClass('form-control');
|
||||
$field->setContainerClass('form-group');
|
||||
$field->setOptions([
|
||||
300 => '5 Minutes',
|
||||
900 => '15 Minutes',
|
||||
1800 => '30 Minutes',
|
||||
3600 => '1 Hour',
|
||||
10800 => '3 Hours',
|
||||
]);
|
||||
$field->setValue(1800);
|
||||
$form->addField($field);
|
||||
|
||||
|
||||
$field = new Form\Element\Submit();
|
||||
$field->setValue('Save »');
|
||||
$field->setClass('btn btn-success pull-right');
|
||||
$form->addField($field);
|
||||
|
||||
$form->setValues($values);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
protected function getAuthenticationForm($values = array())
|
||||
{
|
||||
$form = new Form();
|
||||
|
@ -290,17 +343,4 @@ class SettingsController extends Controller
|
|||
|
||||
return $form;
|
||||
}
|
||||
|
||||
protected function getGithubUser($token)
|
||||
{
|
||||
$http = new HttpClient('https://api.github.com');
|
||||
$user = $http->get('/user', array('access_token' => $token));
|
||||
|
||||
return $user['body'];
|
||||
}
|
||||
|
||||
protected function canWriteConfig()
|
||||
{
|
||||
return is_writeable(APPLICATION_PATH . 'PHPCI/config.yml');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,24 +49,30 @@ class UserController extends Controller
|
|||
$users = $this->userStore->getWhere(array(), 1000, 0, array(), array('email' => 'ASC'));
|
||||
$this->view->users = $users;
|
||||
|
||||
$this->config->set('page_title', 'Users');
|
||||
$this->layout->title = 'Users';
|
||||
|
||||
return $this->view->render();
|
||||
}
|
||||
|
||||
public function profile()
|
||||
{
|
||||
$user = $_SESSION['user'];
|
||||
$values = $user->getDataArray();
|
||||
$user = $_SESSION['phpci_user'];
|
||||
|
||||
$this->layout->title = 'Edit Profile';
|
||||
|
||||
if ($this->request->getMethod() == 'POST') {
|
||||
$name = $this->getParam('name', null);
|
||||
$email = $this->getParam('email', null);
|
||||
$password = $this->getParam('password', null);
|
||||
|
||||
$_SESSION['user'] = $this->userService->updateUser($name, $email, $password);
|
||||
$_SESSION['phpci_user'] = $this->userService->updateUser($user, $name, $email, $password);
|
||||
$user = $_SESSION['phpci_user'];
|
||||
|
||||
$this->view->updated = 1;
|
||||
}
|
||||
|
||||
$values = $user->getDataArray();
|
||||
|
||||
$form = new Form();
|
||||
$form->setAction(PHPCI_URL.'user/profile');
|
||||
$form->setMethod('POST');
|
||||
|
@ -109,11 +115,9 @@ class UserController extends Controller
|
|||
*/
|
||||
public function add()
|
||||
{
|
||||
if (!$_SESSION['user']->getIsAdmin()) {
|
||||
throw new ForbiddenException('You do not have permission to do that.');
|
||||
}
|
||||
$this->requireAdmin();
|
||||
|
||||
$this->config->set('page_title', 'Add User');
|
||||
$this->layout->title = 'Add User';
|
||||
|
||||
$method = $this->request->getMethod();
|
||||
|
||||
|
@ -151,9 +155,7 @@ class UserController extends Controller
|
|||
*/
|
||||
public function edit($userId)
|
||||
{
|
||||
if (!$_SESSION['user']->getIsAdmin()) {
|
||||
throw new ForbiddenException('You do not have permission to do that.');
|
||||
}
|
||||
$this->requireAdmin();
|
||||
|
||||
$method = $this->request->getMethod();
|
||||
$user = $this->userStore->getById($userId);
|
||||
|
@ -162,6 +164,9 @@ class UserController extends Controller
|
|||
throw new NotFoundException('User with ID: ' . $userId . ' does not exist.');
|
||||
}
|
||||
|
||||
$this->layout->title = $user->getName();
|
||||
$this->layout->subtitle = 'Edit User';
|
||||
|
||||
$values = array_merge($user->getDataArray(), $this->getParams());
|
||||
$form = $this->userForm($values, 'edit/' . $userId);
|
||||
|
||||
|
@ -244,10 +249,8 @@ class UserController extends Controller
|
|||
*/
|
||||
public function delete($userId)
|
||||
{
|
||||
if (!$_SESSION['user']->getIsAdmin()) {
|
||||
throw new ForbiddenException('You do not have permission to do that.');
|
||||
}
|
||||
|
||||
$this->requireAdmin();
|
||||
|
||||
$user = $this->userStore->getById($userId);
|
||||
|
||||
if (empty($user)) {
|
||||
|
|
|
@ -56,7 +56,6 @@ class WebhookController extends \PHPCI\Controller
|
|||
|
||||
foreach ($payload['commits'] as $commit) {
|
||||
try {
|
||||
|
||||
$email = $commit['raw_author'];
|
||||
$email = substr($email, 0, strpos($email, '>'));
|
||||
$email = substr($email, strpos($email, '<') + 1);
|
||||
|
@ -73,7 +72,7 @@ class WebhookController extends \PHPCI\Controller
|
|||
}
|
||||
|
||||
/**
|
||||
* Called by POSTing to /git/webhook/<project_id>?branch=<branch>&commit=<commit>
|
||||
* Called by POSTing to /webhook/git/<project_id>?branch=<branch>&commit=<commit>
|
||||
*
|
||||
* @param string $project
|
||||
*/
|
||||
|
@ -81,6 +80,8 @@ class WebhookController extends \PHPCI\Controller
|
|||
{
|
||||
$branch = $this->getParam('branch');
|
||||
$commit = $this->getParam('commit');
|
||||
$commitMessage = $this->getParam('message');
|
||||
$committer = $this->getParam('committer');
|
||||
|
||||
try {
|
||||
if (empty($branch)) {
|
||||
|
@ -91,8 +92,15 @@ class WebhookController extends \PHPCI\Controller
|
|||
$commit = null;
|
||||
}
|
||||
|
||||
$this->createBuild($project, $commit, $branch, null, null);
|
||||
if (empty($commitMessage)) {
|
||||
$commitMessage = null;
|
||||
}
|
||||
|
||||
if (empty($committer)) {
|
||||
$committer = null;
|
||||
}
|
||||
|
||||
$this->createBuild($project, $commit, $branch, $committer, $commitMessage);
|
||||
} catch (\Exception $ex) {
|
||||
header('HTTP/1.1 400 Bad Request');
|
||||
header('Ex: ' . $ex->getMessage());
|
||||
|
@ -107,7 +115,19 @@ class WebhookController extends \PHPCI\Controller
|
|||
*/
|
||||
public function github($project)
|
||||
{
|
||||
$payload = json_decode($this->getParam('payload'), true);
|
||||
switch ($_SERVER['CONTENT_TYPE']) {
|
||||
case 'application/json':
|
||||
$payload = json_decode(file_get_contents('php://input'), true);
|
||||
break;
|
||||
|
||||
case 'application/x-www-form-urlencoded':
|
||||
$payload = json_decode($this->getParam('payload'), true);
|
||||
break;
|
||||
|
||||
default:
|
||||
header('HTTP/1.1 400 Bad Request');
|
||||
die('Request content type not supported');
|
||||
}
|
||||
|
||||
// Handle Pull Request web hooks:
|
||||
if (array_key_exists('pull_request', $payload)) {
|
||||
|
|
|
@ -32,6 +32,7 @@ class BuildInterpolator
|
|||
$this->interpolation_vars = array();
|
||||
$this->interpolation_vars['%PHPCI%'] = 1;
|
||||
$this->interpolation_vars['%COMMIT%'] = $build->getCommitId();
|
||||
$this->interpolation_vars['%BRANCH%'] = $build->getBranch();
|
||||
$this->interpolation_vars['%PROJECT%'] = $build->getProjectId();
|
||||
$this->interpolation_vars['%BUILD%'] = $build->getId();
|
||||
$this->interpolation_vars['%PROJECT_TITLE%'] = $build->getProjectTitle();
|
||||
|
|
|
@ -28,11 +28,19 @@ class MailerFactory
|
|||
*/
|
||||
public function getSwiftMailerFromConfig()
|
||||
{
|
||||
$encryptionType = $this->getMailConfig('smtp_encryption');
|
||||
|
||||
// Workaround issue where smtp_encryption could == 1 in the past by
|
||||
// checking it is a valid transport
|
||||
if ($encryptionType && !in_array($encryptionType, stream_get_transports())) {
|
||||
$encryptionType = null;
|
||||
}
|
||||
|
||||
/** @var \Swift_SmtpTransport $transport */
|
||||
$transport = \Swift_SmtpTransport::newInstance(
|
||||
$this->getMailConfig('smtp_address'),
|
||||
$this->getMailConfig('smtp_port'),
|
||||
$this->getMailConfig('smtp_encryption')
|
||||
$encryptionType
|
||||
);
|
||||
$transport->setUsername($this->getMailConfig('smtp_username'));
|
||||
$transport->setPassword($this->getMailConfig('smtp_password'));
|
||||
|
|
|
@ -19,7 +19,7 @@ class User
|
|||
{
|
||||
public function __call($method, $params = array())
|
||||
{
|
||||
$user = $_SESSION['user'];
|
||||
$user = $_SESSION['phpci_user'];
|
||||
|
||||
if (!is_object($user)) {
|
||||
return null;
|
||||
|
|
|
@ -9,6 +9,13 @@ class FixDatabaseColumns extends AbstractMigration
|
|||
*/
|
||||
public function up()
|
||||
{
|
||||
$dbAdapter = $this->getAdapter();
|
||||
|
||||
if ($dbAdapter instanceof \Phinx\Db\Adapter\PdoAdapter) {
|
||||
$pdo = $dbAdapter->getConnection();
|
||||
$pdo->exec('SET foreign_key_checks = 0');
|
||||
}
|
||||
|
||||
$build = $this->table('build');
|
||||
$build->changeColumn('project_id', 'integer', array('null' => false));
|
||||
$build->changeColumn('commit_id', 'string', array('limit' => 50, 'null' => false));
|
||||
|
@ -45,5 +52,10 @@ class FixDatabaseColumns extends AbstractMigration
|
|||
$user->changeColumn('hash', 'string', array('limit' => 250, 'null' => false));
|
||||
$user->changeColumn('is_admin', 'integer', array('null' => false, 'default' => 0));
|
||||
$user->changeColumn('name', 'string', array('limit' => 250, 'null' => false));
|
||||
|
||||
if ($dbAdapter instanceof \Phinx\Db\Adapter\PdoAdapter) {
|
||||
$pdo = $dbAdapter->getConnection();
|
||||
$pdo->exec('SET foreign_key_checks = 1');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -110,16 +110,15 @@ class BuildBase extends Model
|
|||
'commit_id' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 50,
|
||||
'nullable' => true,
|
||||
'default' => null,
|
||||
),
|
||||
'status' => array(
|
||||
'type' => 'tinyint',
|
||||
'length' => 4,
|
||||
'type' => 'int',
|
||||
'length' => 11,
|
||||
'default' => null,
|
||||
),
|
||||
'log' => array(
|
||||
'type' => 'longtext',
|
||||
'type' => 'text',
|
||||
'nullable' => true,
|
||||
'default' => null,
|
||||
),
|
||||
|
@ -155,7 +154,7 @@ class BuildBase extends Model
|
|||
'default' => null,
|
||||
),
|
||||
'extra' => array(
|
||||
'type' => 'longtext',
|
||||
'type' => 'text',
|
||||
'nullable' => true,
|
||||
'default' => null,
|
||||
),
|
||||
|
@ -382,10 +381,12 @@ class BuildBase extends Model
|
|||
/**
|
||||
* Set the value of CommitId / commit_id.
|
||||
*
|
||||
* Must not be null.
|
||||
* @param $value string
|
||||
*/
|
||||
public function setCommitId($value)
|
||||
{
|
||||
$this->_validateNotNull('CommitId', $value);
|
||||
$this->_validateString('CommitId', $value);
|
||||
|
||||
if ($this->data['commit_id'] === $value) {
|
||||
|
|
|
@ -91,17 +91,15 @@ class BuildMetaBase extends Model
|
|||
'build_id' => array(
|
||||
'type' => 'int',
|
||||
'length' => 11,
|
||||
'nullable' => true,
|
||||
'default' => null,
|
||||
),
|
||||
'meta_key' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'length' => 250,
|
||||
'default' => null,
|
||||
),
|
||||
'meta_value' => array(
|
||||
'type' => 'longtext',
|
||||
'nullable' => true,
|
||||
'type' => 'text',
|
||||
'default' => null,
|
||||
),
|
||||
);
|
||||
|
@ -238,10 +236,12 @@ class BuildMetaBase extends Model
|
|||
/**
|
||||
* Set the value of BuildId / build_id.
|
||||
*
|
||||
* Must not be null.
|
||||
* @param $value int
|
||||
*/
|
||||
public function setBuildId($value)
|
||||
{
|
||||
$this->_validateNotNull('BuildId', $value);
|
||||
$this->_validateInt('BuildId', $value);
|
||||
|
||||
if ($this->data['build_id'] === $value) {
|
||||
|
@ -276,10 +276,12 @@ class BuildMetaBase extends Model
|
|||
/**
|
||||
* Set the value of MetaValue / meta_value.
|
||||
*
|
||||
* Must not be null.
|
||||
* @param $value string
|
||||
*/
|
||||
public function setMetaValue($value)
|
||||
{
|
||||
$this->_validateNotNull('MetaValue', $value);
|
||||
$this->_validateString('MetaValue', $value);
|
||||
|
||||
if ($this->data['meta_value'] === $value) {
|
||||
|
|
|
@ -38,11 +38,11 @@ class ProjectBase extends Model
|
|||
'reference' => null,
|
||||
'branch' => null,
|
||||
'ssh_private_key' => null,
|
||||
'ssh_public_key' => null,
|
||||
'type' => null,
|
||||
'access_information' => null,
|
||||
'last_commit' => null,
|
||||
'build_config' => null,
|
||||
'ssh_public_key' => null,
|
||||
'allow_public_status' => null,
|
||||
);
|
||||
|
||||
|
@ -56,11 +56,11 @@ class ProjectBase extends Model
|
|||
'reference' => 'getReference',
|
||||
'branch' => 'getBranch',
|
||||
'ssh_private_key' => 'getSshPrivateKey',
|
||||
'ssh_public_key' => 'getSshPublicKey',
|
||||
'type' => 'getType',
|
||||
'access_information' => 'getAccessInformation',
|
||||
'last_commit' => 'getLastCommit',
|
||||
'build_config' => 'getBuildConfig',
|
||||
'ssh_public_key' => 'getSshPublicKey',
|
||||
'allow_public_status' => 'getAllowPublicStatus',
|
||||
|
||||
// Foreign key getters:
|
||||
|
@ -76,11 +76,11 @@ class ProjectBase extends Model
|
|||
'reference' => 'setReference',
|
||||
'branch' => 'setBranch',
|
||||
'ssh_private_key' => 'setSshPrivateKey',
|
||||
'ssh_public_key' => 'setSshPublicKey',
|
||||
'type' => 'setType',
|
||||
'access_information' => 'setAccessInformation',
|
||||
'last_commit' => 'setLastCommit',
|
||||
'build_config' => 'setBuildConfig',
|
||||
'ssh_public_key' => 'setSshPublicKey',
|
||||
'allow_public_status' => 'setAllowPublicStatus',
|
||||
|
||||
// Foreign key setters:
|
||||
|
@ -109,23 +109,18 @@ class ProjectBase extends Model
|
|||
),
|
||||
'branch' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 250,
|
||||
'default' => null,
|
||||
'length' => 50,
|
||||
'default' => 'master',
|
||||
),
|
||||
'ssh_private_key' => array(
|
||||
'type' => 'text',
|
||||
'nullable' => true,
|
||||
'default' => null,
|
||||
),
|
||||
'ssh_public_key' => array(
|
||||
'type' => 'text',
|
||||
'nullable' => true,
|
||||
'default' => null,
|
||||
),
|
||||
'type' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 50,
|
||||
'default' => 1,
|
||||
'default' => null,
|
||||
),
|
||||
'access_information' => array(
|
||||
'type' => 'varchar',
|
||||
|
@ -144,9 +139,14 @@ class ProjectBase extends Model
|
|||
'nullable' => true,
|
||||
'default' => null,
|
||||
),
|
||||
'ssh_public_key' => array(
|
||||
'type' => 'text',
|
||||
'nullable' => true,
|
||||
'default' => null,
|
||||
),
|
||||
'allow_public_status' => array(
|
||||
'type' => 'tinyint',
|
||||
'length' => 4,
|
||||
'type' => 'int',
|
||||
'length' => 11,
|
||||
),
|
||||
);
|
||||
|
||||
|
@ -224,18 +224,6 @@ class ProjectBase extends Model
|
|||
return $rtn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of SshPublicKey / ssh_public_key.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSshPublicKey()
|
||||
{
|
||||
$rtn = $this->data['ssh_public_key'];
|
||||
|
||||
return $rtn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of Type / type.
|
||||
*
|
||||
|
@ -284,6 +272,18 @@ class ProjectBase extends Model
|
|||
return $rtn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of SshPublicKey / ssh_public_key.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSshPublicKey()
|
||||
{
|
||||
$rtn = $this->data['ssh_public_key'];
|
||||
|
||||
return $rtn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of AllowPublicStatus / allow_public_status.
|
||||
*
|
||||
|
@ -394,24 +394,6 @@ class ProjectBase extends Model
|
|||
$this->_setModified('ssh_private_key');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of SshPublicKey / ssh_public_key.
|
||||
*
|
||||
* @param $value string
|
||||
*/
|
||||
public function setSshPublicKey($value)
|
||||
{
|
||||
$this->_validateString('SshPublicKey', $value);
|
||||
|
||||
if ($this->data['ssh_public_key'] === $value) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->data['ssh_public_key'] = $value;
|
||||
|
||||
$this->_setModified('ssh_public_key');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of Type / type.
|
||||
*
|
||||
|
@ -486,6 +468,24 @@ class ProjectBase extends Model
|
|||
$this->_setModified('build_config');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of SshPublicKey / ssh_public_key.
|
||||
*
|
||||
* @param $value string
|
||||
*/
|
||||
public function setSshPublicKey($value)
|
||||
{
|
||||
$this->_validateString('SshPublicKey', $value);
|
||||
|
||||
if ($this->data['ssh_public_key'] === $value) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->data['ssh_public_key'] = $value;
|
||||
|
||||
$this->_setModified('ssh_public_key');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of AllowPublicStatus / allow_public_status.
|
||||
*
|
||||
|
|
|
@ -90,14 +90,12 @@ class UserBase extends Model
|
|||
'default' => null,
|
||||
),
|
||||
'is_admin' => array(
|
||||
'type' => 'tinyint',
|
||||
'length' => 1,
|
||||
'default' => null,
|
||||
'type' => 'int',
|
||||
'length' => 11,
|
||||
),
|
||||
'name' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 250,
|
||||
'nullable' => true,
|
||||
'default' => null,
|
||||
),
|
||||
);
|
||||
|
@ -259,10 +257,12 @@ class UserBase extends Model
|
|||
/**
|
||||
* Set the value of Name / name.
|
||||
*
|
||||
* Must not be null.
|
||||
* @param $value string
|
||||
*/
|
||||
public function setName($value)
|
||||
{
|
||||
$this->_validateNotNull('Name', $value);
|
||||
$this->_validateString('Name', $value);
|
||||
|
||||
if ($this->data['name'] === $value) {
|
||||
|
|
|
@ -88,4 +88,28 @@ class Project extends ProjectBase
|
|||
return $this->data['branch'];
|
||||
}
|
||||
}
|
||||
|
||||
public function getIcon()
|
||||
{
|
||||
switch ($this->getType()) {
|
||||
case 'github':
|
||||
$icon = 'github';
|
||||
break;
|
||||
|
||||
case 'bitbucket':
|
||||
$icon = 'bitbucket';
|
||||
break;
|
||||
|
||||
case 'git':
|
||||
case 'gitlab':
|
||||
$icon = 'git';
|
||||
break;
|
||||
|
||||
default:
|
||||
$icon = 'cog';
|
||||
break;
|
||||
}
|
||||
|
||||
return $icon;
|
||||
}
|
||||
}
|
||||
|
|
85
PHPCI/Plugin/Gulp.php
Normal file
|
@ -0,0 +1,85 @@
|
|||
<?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 PHPCI\Plugin;
|
||||
|
||||
use PHPCI\Builder;
|
||||
use PHPCI\Model\Build;
|
||||
|
||||
/**
|
||||
* Gulp Plugin - Provides access to gulp functionality.
|
||||
* @author Dirk Heilig <dirk@heilig-online.com>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class Gulp implements \PHPCI\Plugin
|
||||
{
|
||||
protected $directory;
|
||||
protected $task;
|
||||
protected $preferDist;
|
||||
protected $phpci;
|
||||
protected $build;
|
||||
protected $gulp;
|
||||
protected $gulpfile;
|
||||
|
||||
public function __construct(Builder $phpci, Build $build, array $options = array())
|
||||
{
|
||||
$path = $phpci->buildPath;
|
||||
$this->build = $build;
|
||||
$this->phpci = $phpci;
|
||||
$this->directory = $path;
|
||||
$this->task = null;
|
||||
$this->gulp = $this->phpci->findBinary('gulp');
|
||||
$this->gulpfile = 'gulpfile.js';
|
||||
|
||||
// Handle options:
|
||||
if (isset($options['directory'])) {
|
||||
$this->directory = $path . '/' . $options['directory'];
|
||||
}
|
||||
|
||||
if (isset($options['task'])) {
|
||||
$this->task = $options['task'];
|
||||
}
|
||||
|
||||
if (isset($options['gulp'])) {
|
||||
$this->gulp = $options['gulp'];
|
||||
}
|
||||
|
||||
if (isset($options['gulpfile'])) {
|
||||
$this->gulpfile = $options['gulpfile'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes gulp and runs a specified command (e.g. install / update)
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
// if npm does not work, we cannot use gulp, so we return false
|
||||
$cmd = 'cd %s && npm install';
|
||||
if (IS_WIN) {
|
||||
$cmd = 'cd /d %s && npm install';
|
||||
}
|
||||
if (!$this->phpci->executeCommand($cmd, $this->directory)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// build the gulp command
|
||||
$cmd = 'cd %s && ' . $this->gulp;
|
||||
if (IS_WIN) {
|
||||
$cmd = 'cd /d %s && ' . $this->gulp;
|
||||
}
|
||||
$cmd .= ' --no-color';
|
||||
$cmd .= ' --gulpfile %s';
|
||||
$cmd .= ' %s'; // the task that will be executed
|
||||
|
||||
// and execute it
|
||||
return $this->phpci->executeCommand($cmd, $this->directory, $this->gulpfile, $this->task);
|
||||
}
|
||||
}
|
|
@ -62,6 +62,7 @@ class Irc implements \PHPCI\Plugin
|
|||
$sock = fsockopen($this->server, $this->port);
|
||||
fputs($sock, 'USER ' . $this->nick . ' phptesting.org ' . $this->nick . ' :' . $this->nick . "\r\n");
|
||||
fputs($sock, 'NICK ' . $this->nick . "\r\n");
|
||||
fputs($sock, 'JOIN ' . $this->room . "\r\n");
|
||||
fputs($sock, 'PRIVMSG ' . $this->room . ' :' . $msg . "\r\n");
|
||||
|
||||
while (fgets($sock)) {
|
||||
|
|
240
PHPCI/Plugin/Phar.php
Normal file
|
@ -0,0 +1,240 @@
|
|||
<?php
|
||||
namespace PHPCI\Plugin;
|
||||
|
||||
use Exception;
|
||||
use PHPCI\Builder;
|
||||
use PHPCI\Model\Build;
|
||||
use Phar as PHPPhar;
|
||||
|
||||
/**
|
||||
* Phar Plugin
|
||||
*/
|
||||
class Phar implements \PHPCI\Plugin
|
||||
{
|
||||
/**
|
||||
* PHPCI
|
||||
* @var Builder
|
||||
*/
|
||||
protected $phpci;
|
||||
|
||||
/**
|
||||
* Build
|
||||
* @var Build
|
||||
*/
|
||||
protected $build;
|
||||
|
||||
/**
|
||||
* Output Directory
|
||||
* @var string
|
||||
*/
|
||||
protected $directory;
|
||||
|
||||
/**
|
||||
* Phar Filename
|
||||
* @var string
|
||||
*/
|
||||
protected $filename;
|
||||
|
||||
/**
|
||||
* Regular Expression Filename Capture
|
||||
* @var string
|
||||
*/
|
||||
protected $regexp;
|
||||
|
||||
/**
|
||||
* Stub Filename
|
||||
* @var string
|
||||
*/
|
||||
protected $stub;
|
||||
|
||||
/**
|
||||
* Standard Constructor
|
||||
*
|
||||
* $options['directory'] Output Directory. Default: %BUILDPATH%
|
||||
* $options['filename'] Phar Filename. Default: build.phar
|
||||
* $options['regexp'] Regular Expression Filename Capture. Default: /\.php$/
|
||||
* $options['stub'] Stub Content. No Default Value
|
||||
*
|
||||
* @param Builder $phpci
|
||||
* @param Build $build
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct(Builder $phpci, Build $build, array $options = array())
|
||||
{
|
||||
// Basic
|
||||
$this->phpci = $phpci;
|
||||
$this->build = $build;
|
||||
|
||||
// Directory?
|
||||
if (isset($options['directory'])) {
|
||||
$this->setDirectory($options['directory']);
|
||||
}
|
||||
|
||||
// Filename?
|
||||
if (isset($options['filename'])) {
|
||||
$this->setFilename($options['filename']);
|
||||
}
|
||||
|
||||
// RegExp?
|
||||
if (isset($options['regexp'])) {
|
||||
$this->setRegExp($options['regexp']);
|
||||
}
|
||||
|
||||
// Stub?
|
||||
if (isset($options['stub'])) {
|
||||
$this->setStub($options['stub']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns PHPCI
|
||||
*
|
||||
* @return PHPCI
|
||||
*/
|
||||
public function getPHPCI()
|
||||
{
|
||||
return $this->phpci;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Build
|
||||
*
|
||||
* @return Build
|
||||
*/
|
||||
public function getBuild()
|
||||
{
|
||||
return $this->build;
|
||||
}
|
||||
|
||||
/**
|
||||
* Directory Setter
|
||||
*
|
||||
* @param string $directory Configuration Value
|
||||
* @return Phar Fluent Interface
|
||||
*/
|
||||
public function setDirectory($directory)
|
||||
{
|
||||
$this->directory = $directory;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Directory Getter
|
||||
*
|
||||
* @return string Configurated or Default Value
|
||||
*/
|
||||
public function getDirectory()
|
||||
{
|
||||
if (!isset($this->directory)) {
|
||||
$this->setDirectory($this->getPHPCI()->buildPath);
|
||||
}
|
||||
return $this->directory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filename Setter
|
||||
*
|
||||
* @param string $filename Configuration Value
|
||||
* @return Phar Fluent Interface
|
||||
*/
|
||||
public function setFilename($filename)
|
||||
{
|
||||
$this->filename = $filename;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filename Getter
|
||||
*
|
||||
* @return string Configurated or Default Value
|
||||
*/
|
||||
public function getFilename()
|
||||
{
|
||||
if (!isset($this->filename)) {
|
||||
$this->setFilename('build.phar');
|
||||
}
|
||||
return $this->filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Regular Expression Setter
|
||||
*
|
||||
* @param string $regexp Configuration Value
|
||||
* @return Phar Fluent Interface
|
||||
*/
|
||||
public function setRegExp($regexp)
|
||||
{
|
||||
$this->regexp = $regexp;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Regular Expression Getter
|
||||
*
|
||||
* @return string Configurated or Default Value
|
||||
*/
|
||||
public function getRegExp()
|
||||
{
|
||||
if (!isset($this->regexp)) {
|
||||
$this->setRegExp('/\.php$/');
|
||||
}
|
||||
return $this->regexp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stub Filename Setter
|
||||
*
|
||||
* @param string $stub Configuration Value
|
||||
* @return Phar Fluent Interface
|
||||
*/
|
||||
public function setStub($stub)
|
||||
{
|
||||
$this->stub = $stub;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stub Filename Getter
|
||||
*
|
||||
* @return string Configurated Value
|
||||
*/
|
||||
public function getStub()
|
||||
{
|
||||
return $this->stub;
|
||||
}
|
||||
|
||||
public function getStubContent()
|
||||
{
|
||||
$content = '';
|
||||
$filename = $this->getStub();
|
||||
if ($filename) {
|
||||
$content = file_get_contents($this->getPHPCI()->buildPath . '/' . $this->getStub());
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
|
||||
// Execution
|
||||
public function execute()
|
||||
{
|
||||
$success = false;
|
||||
|
||||
try {
|
||||
|
||||
$phar = new PHPPhar($this->getDirectory() . '/' . $this->getFilename(), 0, $this->getFilename());
|
||||
$phar->buildFromDirectory($this->getPHPCI()->buildPath, $this->getRegExp());
|
||||
|
||||
$stub = $this->getStubContent();
|
||||
if ($stub) {
|
||||
$phar->setStub($stub);
|
||||
}
|
||||
|
||||
$success = true;
|
||||
|
||||
} catch (Exception $e) {
|
||||
$this->getPHPCI()->log('Phar Plugin Internal Error');
|
||||
$this->getPHPCI()->log($e->getMessage());
|
||||
}
|
||||
|
||||
return $success;
|
||||
}
|
||||
}
|
|
@ -90,7 +90,7 @@ class PhpCpd implements \PHPCI\Plugin
|
|||
|
||||
$tmpfilename = tempnam('/tmp', 'phpcpd');
|
||||
|
||||
$cmd = $phpcpd . ' --log-pmd="%s" %s "%s"';
|
||||
$cmd = $phpcpd . ' --log-pmd "%s" %s "%s"';
|
||||
$success = $this->phpci->executeCommand($cmd, $tmpfilename, $ignore, $this->path);
|
||||
|
||||
print $this->phpci->getLastOutput();
|
||||
|
|
|
@ -48,7 +48,7 @@ class PhpParallelLint implements \PHPCI\Plugin
|
|||
$this->ignore = $this->phpci->ignore;
|
||||
|
||||
if (isset($options['directory'])) {
|
||||
$this->directory = $options['directory'];
|
||||
$this->directory = $phpci->buildPath.$options['directory'];
|
||||
}
|
||||
|
||||
if (isset($options['ignore'])) {
|
||||
|
|
|
@ -58,10 +58,91 @@ class PhpSpec implements PHPCI\Plugin
|
|||
return false;
|
||||
}
|
||||
|
||||
$success = $this->phpci->executeCommand($phpspec . ' --format=pretty --no-code-generation run');
|
||||
$success = $this->phpci->executeCommand($phpspec . ' --format=junit --no-code-generation run');
|
||||
$output = $this->phpci->getLastOutput();
|
||||
|
||||
chdir($curdir);
|
||||
|
||||
|
||||
/*
|
||||
* process xml output
|
||||
*
|
||||
* <testsuites time=FLOAT tests=INT failures=INT errors=INT>
|
||||
* <testsuite name=STRING time=FLOAT tests=INT failures=INT errors=INT skipped=INT>
|
||||
* <testcase name=STRING time=FLOAT classname=STRING status=STRING/>
|
||||
* </testsuite>
|
||||
* </testsuites
|
||||
*/
|
||||
|
||||
$xml = new \SimpleXMLElement($output);
|
||||
$attr = $xml->attributes();
|
||||
$data = array(
|
||||
'time' => (float)$attr['time'],
|
||||
'tests' => (int)$attr['tests'],
|
||||
'failures' => (int)$attr['failures'],
|
||||
'errors' => (int)$attr['errors'],
|
||||
|
||||
// now all the tests
|
||||
'suites' => array()
|
||||
);
|
||||
|
||||
/**
|
||||
* @var \SimpleXMLElement $group
|
||||
*/
|
||||
foreach ($xml->xpath('testsuite') as $group) {
|
||||
$attr = $group->attributes();
|
||||
$suite = array(
|
||||
'name' => (String)$attr['name'],
|
||||
'time' => (float)$attr['time'],
|
||||
'tests' => (int)$attr['tests'],
|
||||
'failures' => (int)$attr['failures'],
|
||||
'errors' => (int)$attr['errors'],
|
||||
'skipped' => (int)$attr['skipped'],
|
||||
|
||||
// now the cases
|
||||
'cases' => array()
|
||||
);
|
||||
|
||||
/**
|
||||
* @var \SimpleXMLElement $child
|
||||
*/
|
||||
foreach ($group->xpath('testcase') as $child) {
|
||||
$attr = $child->attributes();
|
||||
$case = array(
|
||||
'name' => (String)$attr['name'],
|
||||
'classname' => (String)$attr['classname'],
|
||||
'time' => (float)$attr['time'],
|
||||
'status' => (String)$attr['status'],
|
||||
);
|
||||
|
||||
if ($case['status']=='failed') {
|
||||
$error = array();
|
||||
/*
|
||||
* ok, sad, we had an error
|
||||
*
|
||||
* there should be one - foreach makes this easier
|
||||
*/
|
||||
foreach ($child->xpath('failure') as $failure) {
|
||||
$attr = $failure->attributes();
|
||||
$error['type'] = (String)$attr['type'];
|
||||
$error['message'] = (String)$attr['message'];
|
||||
}
|
||||
|
||||
foreach ($child->xpath('system-err') as $system_err) {
|
||||
$error['raw'] = (String)$system_err;
|
||||
}
|
||||
|
||||
$case['error'] = $error;
|
||||
}
|
||||
|
||||
$suite['cases'][] = $case;
|
||||
}
|
||||
|
||||
$data['suites'][] = $suite;
|
||||
}
|
||||
|
||||
$this->build->storeMeta('phpspec', $data);
|
||||
|
||||
|
||||
return $success;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -129,7 +129,7 @@ class PhpUnit implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
|
|||
|
||||
// Run any dirs next. Again this can be either a single value or an array.
|
||||
if ($this->directory !== null) {
|
||||
$success &= $this->runDir();
|
||||
$success &= $this->runDir($this->directory);
|
||||
}
|
||||
|
||||
$tapString = $this->phpci->getLastOutput();
|
||||
|
@ -182,10 +182,10 @@ class PhpUnit implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
|
|||
}
|
||||
}
|
||||
|
||||
protected function runDir()
|
||||
protected function runDir($directory)
|
||||
{
|
||||
if (is_array($this->directory)) {
|
||||
return $this->recurseArg($this->directory, array($this, "runDir"));
|
||||
if (is_array($directory)) {
|
||||
return $this->recurseArg($directory, array($this, "runDir"));
|
||||
} else {
|
||||
$curdir = getcwd();
|
||||
chdir($this->phpci->buildPath);
|
||||
|
@ -198,7 +198,7 @@ class PhpUnit implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
|
|||
}
|
||||
|
||||
$cmd = $phpunit . ' --tap %s "%s"';
|
||||
$success = $this->phpci->executeCommand($cmd, $this->args, $this->phpci->buildPath . $this->directory);
|
||||
$success = $this->phpci->executeCommand($cmd, $this->args, $this->phpci->buildPath . $directory);
|
||||
chdir($curdir);
|
||||
return $success;
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ class FilesPluginInformation implements InstalledPluginInformation
|
|||
$this->pluginInfo = array();
|
||||
foreach ($this->files as $fileInfo) {
|
||||
if ($fileInfo instanceof \SplFileInfo) {
|
||||
if ($fileInfo->isFile()) {
|
||||
if ($fileInfo->isFile() && $fileInfo->getExtension()=='php') {
|
||||
$this->addPluginFromFile($fileInfo);
|
||||
}
|
||||
}
|
||||
|
@ -76,13 +76,17 @@ class FilesPluginInformation implements InstalledPluginInformation
|
|||
|
||||
protected function addPluginFromFile(\SplFileInfo $fileInfo)
|
||||
{
|
||||
$newPlugin = new \stdClass();
|
||||
$newPlugin->class = $this->getFullClassFromFile($fileInfo);
|
||||
$newPlugin->source = "core";
|
||||
$parts = explode('\\', $newPlugin->class);
|
||||
$newPlugin->name = end($parts);
|
||||
$class = $this->getFullClassFromFile($fileInfo);
|
||||
|
||||
$this->pluginInfo[] = $newPlugin;
|
||||
if (!is_null($class)) {
|
||||
$newPlugin = new \stdClass();
|
||||
$newPlugin->class = $class;
|
||||
$newPlugin->source = "core";
|
||||
$parts = explode('\\', $newPlugin->class);
|
||||
$newPlugin->name = end($parts);
|
||||
|
||||
$this->pluginInfo[] = $newPlugin;
|
||||
}
|
||||
}
|
||||
|
||||
protected function getFullClassFromFile(\SplFileInfo $fileInfo)
|
||||
|
@ -90,15 +94,20 @@ class FilesPluginInformation implements InstalledPluginInformation
|
|||
//TODO: Something less horrible than a regular expression
|
||||
// on the contents of a file
|
||||
$contents = file_get_contents($fileInfo->getRealPath());
|
||||
|
||||
$matches = array();
|
||||
|
||||
preg_match('#class +([A-Za-z]+) +implements#i', $contents, $matches);
|
||||
$className = $matches[1];
|
||||
|
||||
$matches = array();
|
||||
preg_match('#namespace +([A-Za-z\\\\]+);#i', $contents, $matches);
|
||||
$namespace = $matches[1];
|
||||
|
||||
return $namespace . '\\' . $className;
|
||||
if (isset($matches[1])) {
|
||||
$className = $matches[1];
|
||||
|
||||
$matches = array();
|
||||
preg_match('#namespace +([A-Za-z\\\\]+);#i', $contents, $matches);
|
||||
$namespace = $matches[1];
|
||||
|
||||
return $namespace . '\\' . $className;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ class TapParser
|
|||
const TEST_LINE_PATTERN = '/(ok|not ok)\s+[0-9]+\s+\-\s+([^\n]+)::([^\n]+)/';
|
||||
const TEST_MESSAGE_PATTERN = '/message\:\s+\'([^\']+)\'/';
|
||||
const TEST_COVERAGE_PATTERN = '/Generating code coverage report/';
|
||||
const TEST_SKIP_PATTERN = '/ok\s+[0-9]+\s+\-\s+#\s+SKIP/';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
|
@ -43,7 +44,7 @@ class TapParser
|
|||
throw new \Exception('TapParser only supports TAP version 13');
|
||||
}
|
||||
|
||||
if (preg_match(self::TEST_COVERAGE_PATTERN, $lines[count($lines) - 1])) {
|
||||
if (isset($lines[count($lines) - 1]) && preg_match(self::TEST_COVERAGE_PATTERN, $lines[count($lines) - 1])) {
|
||||
array_pop($lines);
|
||||
if ($lines[count($lines) - 1] == "") {
|
||||
array_pop($lines);
|
||||
|
@ -57,7 +58,8 @@ class TapParser
|
|||
$totalTests = (int) $matches[2];
|
||||
}
|
||||
|
||||
if (preg_match(self::TEST_COUNTS_PATTERN, $lines[count($lines) - 1], $matches)) {
|
||||
if (isset($lines[count($lines) - 1]) &&
|
||||
preg_match(self::TEST_COUNTS_PATTERN, $lines[count($lines) - 1], $matches)) {
|
||||
array_pop($lines);
|
||||
$totalTests = (int) $matches[2];
|
||||
}
|
||||
|
@ -92,6 +94,8 @@ class TapParser
|
|||
);
|
||||
|
||||
$rtn[] = $item;
|
||||
} elseif (preg_match(self::TEST_SKIP_PATTERN, $line, $matches)) {
|
||||
$rtn[] = array('message' => 'SKIP');
|
||||
} elseif (preg_match(self::TEST_MESSAGE_PATTERN, $line, $matches)) {
|
||||
$rtn[count($rtn) - 1]['message'] = $matches[1];
|
||||
}
|
||||
|
|
|
@ -56,7 +56,6 @@ class BuildMetaStoreBase extends Store
|
|||
$add .= ' LIMIT ' . $limit;
|
||||
}
|
||||
|
||||
$count = null;
|
||||
|
||||
$query = 'SELECT * FROM `build_meta` WHERE `project_id` = :project_id' . $add;
|
||||
$stmt = Database::getConnection($useConnection)->prepare($query);
|
||||
|
@ -70,6 +69,9 @@ class BuildMetaStoreBase extends Store
|
|||
};
|
||||
$rtn = array_map($map, $res);
|
||||
|
||||
$count = count($rtn);
|
||||
|
||||
|
||||
return array('items' => $rtn, 'count' => $count);
|
||||
} else {
|
||||
return array('items' => array(), 'count' => 0);
|
||||
|
@ -88,7 +90,6 @@ class BuildMetaStoreBase extends Store
|
|||
$add .= ' LIMIT ' . $limit;
|
||||
}
|
||||
|
||||
$count = null;
|
||||
|
||||
$query = 'SELECT * FROM `build_meta` WHERE `build_id` = :build_id' . $add;
|
||||
$stmt = Database::getConnection($useConnection)->prepare($query);
|
||||
|
@ -102,6 +103,9 @@ class BuildMetaStoreBase extends Store
|
|||
};
|
||||
$rtn = array_map($map, $res);
|
||||
|
||||
$count = count($rtn);
|
||||
|
||||
|
||||
return array('items' => $rtn, 'count' => $count);
|
||||
} else {
|
||||
return array('items' => array(), 'count' => 0);
|
||||
|
|
|
@ -56,7 +56,6 @@ class BuildStoreBase extends Store
|
|||
$add .= ' LIMIT ' . $limit;
|
||||
}
|
||||
|
||||
$count = null;
|
||||
|
||||
$query = 'SELECT * FROM `build` WHERE `project_id` = :project_id' . $add;
|
||||
$stmt = Database::getConnection($useConnection)->prepare($query);
|
||||
|
@ -70,6 +69,9 @@ class BuildStoreBase extends Store
|
|||
};
|
||||
$rtn = array_map($map, $res);
|
||||
|
||||
$count = count($rtn);
|
||||
|
||||
|
||||
return array('items' => $rtn, 'count' => $count);
|
||||
} else {
|
||||
return array('items' => array(), 'count' => 0);
|
||||
|
@ -88,7 +90,6 @@ class BuildStoreBase extends Store
|
|||
$add .= ' LIMIT ' . $limit;
|
||||
}
|
||||
|
||||
$count = null;
|
||||
|
||||
$query = 'SELECT * FROM `build` WHERE `status` = :status' . $add;
|
||||
$stmt = Database::getConnection($useConnection)->prepare($query);
|
||||
|
@ -102,6 +103,9 @@ class BuildStoreBase extends Store
|
|||
};
|
||||
$rtn = array_map($map, $res);
|
||||
|
||||
$count = count($rtn);
|
||||
|
||||
|
||||
return array('items' => $rtn, 'count' => $count);
|
||||
} else {
|
||||
return array('items' => array(), 'count' => 0);
|
||||
|
|
|
@ -56,7 +56,6 @@ class ProjectStoreBase extends Store
|
|||
$add .= ' LIMIT ' . $limit;
|
||||
}
|
||||
|
||||
$count = null;
|
||||
|
||||
$query = 'SELECT * FROM `project` WHERE `title` = :title' . $add;
|
||||
$stmt = Database::getConnection($useConnection)->prepare($query);
|
||||
|
@ -70,6 +69,9 @@ class ProjectStoreBase extends Store
|
|||
};
|
||||
$rtn = array_map($map, $res);
|
||||
|
||||
$count = count($rtn);
|
||||
|
||||
|
||||
return array('items' => $rtn, 'count' => $count);
|
||||
} else {
|
||||
return array('items' => array(), 'count' => 0);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
namespace PHPCI\Store;
|
||||
|
||||
use b8\Database;
|
||||
use PHPCI\BuildFactory;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\Store\Base\BuildStoreBase;
|
||||
|
||||
|
@ -21,11 +22,22 @@ use PHPCI\Store\Base\BuildStoreBase;
|
|||
*/
|
||||
class BuildStore extends BuildStoreBase
|
||||
{
|
||||
public function getLatestBuilds($projectId)
|
||||
public function getLatestBuilds($projectId = null, $limit = 5)
|
||||
{
|
||||
$query = 'SELECT * FROM build WHERE project_id = :pid ORDER BY id DESC LIMIT 5';
|
||||
$where = '';
|
||||
|
||||
if (!is_null($projectId)) {
|
||||
$where = ' WHERE `project_id` = :pid ';
|
||||
}
|
||||
|
||||
$query = 'SELECT * FROM build '.$where.' ORDER BY id DESC LIMIT :limit';
|
||||
$stmt = Database::getConnection('read')->prepare($query);
|
||||
$stmt->bindValue(':pid', $projectId);
|
||||
|
||||
if (!is_null($projectId)) {
|
||||
$stmt->bindValue(':pid', $projectId);
|
||||
}
|
||||
|
||||
$stmt->bindValue(':limit', $limit, \PDO::PARAM_INT);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
$res = $stmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||
|
@ -41,6 +53,22 @@ class BuildStore extends BuildStoreBase
|
|||
}
|
||||
}
|
||||
|
||||
public function getLastBuildByStatus($projectId = null, $status = Build::STATUS_SUCCESS)
|
||||
{
|
||||
$query = 'SELECT * FROM build WHERE project_id = :pid AND status = :status ORDER BY id DESC LIMIT 1';
|
||||
$stmt = Database::getConnection('read')->prepare($query);
|
||||
$stmt->bindValue(':pid', $projectId);
|
||||
$stmt->bindValue(':status', $status);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
if ($data = $stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
return new Build($data);
|
||||
}
|
||||
} else {
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
public function getByProjectAndCommit($projectId, $commitId)
|
||||
{
|
||||
$query = 'SELECT * FROM `build` WHERE `project_id` = :project_id AND `commit_id` = :commit_id';
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
namespace PHPCI\Store;
|
||||
|
||||
use b8\Database;
|
||||
use PHPCI\Model\Project;
|
||||
use PHPCI\Store\Base\ProjectStoreBase;
|
||||
|
||||
/**
|
||||
|
@ -19,5 +21,45 @@ use PHPCI\Store\Base\ProjectStoreBase;
|
|||
*/
|
||||
class ProjectStore extends ProjectStoreBase
|
||||
{
|
||||
// This class has been left blank so that you can modify it - changes in this file will not be overwritten.
|
||||
public function getKnownBranches($projectId)
|
||||
{
|
||||
$query = 'SELECT DISTINCT branch from build WHERE project_id = :pid';
|
||||
$stmt = Database::getConnection('read')->prepare($query);
|
||||
$stmt->bindValue(':pid', $projectId);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
$res = $stmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||
|
||||
$map = function ($item) {
|
||||
return $item['branch'];
|
||||
};
|
||||
$rtn = array_map($map, $res);
|
||||
|
||||
return $rtn;
|
||||
} else {
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
public function getAll()
|
||||
{
|
||||
$query = 'SELECT * FROM `project` ORDER BY `title` ASC';
|
||||
$stmt = Database::getConnection('read')->prepare($query);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
$res = $stmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||
|
||||
$map = function ($item) {
|
||||
return new Project($item);
|
||||
};
|
||||
$rtn = array_map($map, $res);
|
||||
|
||||
$count = count($rtn);
|
||||
|
||||
|
||||
return array('items' => $rtn, 'count' => $count);
|
||||
} else {
|
||||
return array('items' => array(), 'count' => 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
20
PHPCI/View/Build/header-row.phtml
Normal file
|
@ -0,0 +1,20 @@
|
|||
<li>
|
||||
<a href="<?php print PHPCI_URL; ?>build/view/<?php print $build->getId(); ?>">
|
||||
<?php if ($build->getCommitterEmail()): ?>
|
||||
<div class="pull-left">
|
||||
<img src="https://www.gravatar.com/avatar/<?php print md5($build->getCommitterEmail()); ?>?d=mm&s=40" class="img-circle" alt="">
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<h4>
|
||||
<?php print $build->getProject()->getTitle(); ?>
|
||||
|
||||
<?php if ($build->getStatus() == \PHPCI\Model\Build::STATUS_NEW): ?>
|
||||
<small class="pull-right">Created <?php print $build->getCreated()->format('g:ia'); ?></small>
|
||||
<?php elseif ($build->getStatus() == \PHPCI\Model\Build::STATUS_RUNNING): ?>
|
||||
<small class="pull-right">Started <?php print $build->getStarted()->format('g:ia'); ?></small>
|
||||
<?php endif; ?>
|
||||
</h4>
|
||||
<p>Branch: <?php print $build->getBranch(); ?></p>
|
||||
</a>
|
||||
</li>
|
|
@ -1,17 +1,15 @@
|
|||
<div class="build-info-panel panel panel-default">
|
||||
<img class="pull-left" src="//www.gravatar.com/avatar/<?php print md5($build->getCommitterEmail()); ?>?d=mm">
|
||||
|
||||
<div class="panel-heading">
|
||||
<h1 class="panel-title">
|
||||
<a href="<?php print PHPCI_URL; ?>project/view/<?php print $build->getProjectId(); ?>">
|
||||
<?php print $build->getProject()->getTitle(); ?></a>
|
||||
<span>#<?php print $build->getId(); ?></span>
|
||||
<div class="build-info-panel box box-solid">
|
||||
|
||||
<div class="box-header">
|
||||
<h1 class="box-title">
|
||||
Committed by <?php print $build->getCommitterEmail(); ?>
|
||||
<label class="pull-right label"></label>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div class="panel-body">
|
||||
<div class="box-body">
|
||||
<img class="pull-left" src="//www.gravatar.com/avatar/<?php print md5($build->getCommitterEmail()); ?>?d=mm">
|
||||
|
||||
<div id="build-info">
|
||||
<?php if ($build->getCommitMessage()): ?>
|
||||
<div class="commit-message">
|
||||
|
@ -19,8 +17,7 @@
|
|||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<strong>Branch: </strong> <?php print $build->getBranch(); ?><br>
|
||||
<strong>Committer: </strong> <?php print $build->getCommitterEmail(); ?>
|
||||
<strong>Branch: </strong> <?php print $build->getBranch(); ?>
|
||||
|
||||
<?php if ($build->getCommitId() != 'Manual'): ?>
|
||||
<br><strong>Commit ID: </strong> <?php print $build->getCommitId(); ?><br>
|
||||
|
@ -30,35 +27,19 @@
|
|||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-3">
|
||||
<div class="panel panel-default affix">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">Options</h4>
|
||||
</div>
|
||||
<ul class="list-group">
|
||||
<a class="list-group-item" href="<?php echo PHPCI_URL ?>build/rebuild/<?php print $build->getId(); ?>"><i class="icon-cog"></i> Rebuild</a>
|
||||
<?php if($this->User()->getIsAdmin()): ?>
|
||||
<a class="list-group-item" href="<?php echo PHPCI_URL ?>build/delete/<?php print $build->getId(); ?>" id="delete-build"><i class="icon-trash"></i> Delete Build</a>
|
||||
<?php endif; ?>
|
||||
</ul>
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">Quick links</h4>
|
||||
</div>
|
||||
<ul class="list-group" id="anchorPlugins"></ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-9">
|
||||
<div class="col-lg-12">
|
||||
<div id="status"></div>
|
||||
<div id="plugins" class="row"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="<?php print PHPCI_URL; ?>assets/js/build.js"></script>
|
||||
<script>
|
||||
var PHPCI = new PHPCIObject(<?php print $build->getId() ?>);
|
||||
PHPCI.buildData = <?php print $data; ?>;
|
||||
PHPCI.fileLinkTemplate = <?php print json_encode($build->getFileLinkTemplate()); ?>;
|
||||
|
||||
var ActiveBuild = new Build(<?php print $build->getId() ?>);
|
||||
ActiveBuild.buildData = <?php print $data; ?>;
|
||||
ActiveBuild.fileLinkTemplate = <?php print json_encode($build->getFileLinkTemplate()); ?>;
|
||||
|
||||
</script>
|
||||
|
||||
<?php
|
||||
|
@ -69,7 +50,7 @@ foreach ($plugins as $plugin) {
|
|||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
PHPCI.renderPlugins();
|
||||
ActiveBuild.renderPlugins();
|
||||
|
||||
$('#delete-build').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
@ -86,41 +67,38 @@ foreach ($plugins as $plugin) {
|
|||
});
|
||||
|
||||
function updateBuildStatus(status) {
|
||||
var statusClass = null;
|
||||
var statusText = null;
|
||||
|
||||
switch (status) {
|
||||
case 0:
|
||||
statusClass = 'info';
|
||||
statusText = 'Pending';
|
||||
$('.build-info-panel')
|
||||
.removeClass('bg-yellow')
|
||||
.removeClass('bg-green')
|
||||
.removeClass('bg-red')
|
||||
.addClass('bg-blue');
|
||||
break;
|
||||
|
||||
case 1:
|
||||
statusClass = 'warning';
|
||||
statusText = 'Running';
|
||||
$('.build-info-panel')
|
||||
.removeClass('bg-green')
|
||||
.removeClass('bg-red')
|
||||
.removeClass('bg-blue')
|
||||
.addClass('bg-yellow');
|
||||
break;
|
||||
|
||||
case 2:
|
||||
statusClass = 'success';
|
||||
statusText = 'Success';
|
||||
$('.build-info-panel')
|
||||
.removeClass('bg-yellow')
|
||||
.removeClass('bg-red')
|
||||
.removeClass('bg-blue')
|
||||
.addClass('bg-green');
|
||||
break;
|
||||
|
||||
case 3:
|
||||
statusClass = 'danger';
|
||||
statusText = 'Failed';
|
||||
$('.build-info-panel')
|
||||
.removeClass('bg-yellow')
|
||||
.removeClass('bg-green')
|
||||
.removeClass('bg-blue')
|
||||
.addClass('bg-red');
|
||||
break;
|
||||
}
|
||||
|
||||
$('.build-info-panel')
|
||||
.removeClass('panel-info')
|
||||
.removeClass('panel-warning')
|
||||
.removeClass('panel-success')
|
||||
.removeClass('panel-danger')
|
||||
.addClass('panel-' + statusClass);
|
||||
|
||||
$('.build-info-panel .label')
|
||||
.removeClass('label-info')
|
||||
.removeClass('label-warning')
|
||||
.removeClass('label-success')
|
||||
.removeClass('label-danger')
|
||||
.addClass('label-' + statusClass)
|
||||
.text(statusText);
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -66,8 +66,8 @@
|
|||
<div class="build-info-panel panel panel-<?php print $statusClass; ?>">
|
||||
<img class="pull-left" src="//www.gravatar.com/avatar/<?php print md5($latest->getCommitterEmail()); ?>?d=mm">
|
||||
|
||||
<div class="panel-heading">
|
||||
<h1 class="panel-title">
|
||||
<div class="box-header">
|
||||
<h1 class="box-title">
|
||||
<a href="/project/view/<?php print $latest->getProjectId(); ?>">
|
||||
<?php print $latest->getProject()->getTitle(); ?></a>
|
||||
<span>#<?php print $latest->getId(); ?></span>
|
||||
|
@ -76,7 +76,7 @@
|
|||
</h1>
|
||||
</div>
|
||||
|
||||
<div class="panel-body">
|
||||
<div class="box-body">
|
||||
<div id="build-info">
|
||||
<?php if ($latest->getCommitMessage()): ?>
|
||||
<div class="commit-message">
|
||||
|
@ -97,8 +97,8 @@
|
|||
|
||||
|
||||
<!-- Recent builds: -->
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading"><h3 class="panel-title">Builds</h3></div>
|
||||
<div class="box box-primary">
|
||||
<div class="box-header"><h3 class="box-title">Builds</h3></div>
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
|
|
|
@ -47,19 +47,22 @@ switch($build->getStatus())
|
|||
}
|
||||
?></a></td>
|
||||
|
||||
<td>
|
||||
<td class="hidden-md hidden-sm hidden-xs">
|
||||
<?php
|
||||
if ($build->getCommitId() !== 'Manual') {
|
||||
print '<a href="' . $build->getCommitLink() . '">';
|
||||
}
|
||||
print $build->getCommitId();
|
||||
if ($build->getCommitId() !== 'Manual') {
|
||||
print '</a>';
|
||||
print sprintf(
|
||||
'<a href="%s" target="_blank">%s (%s)</a>',
|
||||
$build->getCommitLink(),
|
||||
substr($build->getCommitId(), 0, 7),
|
||||
$build->getCommitterEmail()
|
||||
);
|
||||
} else {
|
||||
print 'Manual Build';
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
|
||||
<td><a href="<?php print $build->getBranchLink(); ?>"><?php print $build->getBranch(); ?></a></td>
|
||||
<td><a href="<?php print $build->getBranchLink(); ?>" target="_blank"><?php print $build->getBranch(); ?></a></td>
|
||||
<td>
|
||||
<span class='label label-<?php echo $subcls ?>'><?php echo $status ?></span>
|
||||
</td>
|
||||
|
|
|
@ -1,93 +1,102 @@
|
|||
<div id="title">
|
||||
<h1><i class="glyphicon glyphicon-home"></i> Dashboard</h1>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-3">
|
||||
<?php if (count($projects)): ?>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">Projects</h4>
|
||||
</div>
|
||||
<div class="list-group">
|
||||
<?php foreach($projects as $project): ?>
|
||||
<a class="list-group-item" href="<?php echo PHPCI_URL ?>project/view/<?php print $project->getId(); ?>"><?php print htmlspecialchars($project->getTitle()); ?></a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php endif; ?>
|
||||
<div class="col-sm-5">
|
||||
<?php print $summary; ?>
|
||||
</div>
|
||||
<div class="col-lg-9">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading"><h3 class="panel-title">Project Overview</h3></div>
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Health</th>
|
||||
<th>Project</th>
|
||||
<th>Last Success</th>
|
||||
<th>Last Failure</th>
|
||||
<th>Success/Failures</th>
|
||||
<th style="width: 100px"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="project-overview">
|
||||
<?php print $summary; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">Last 5 Builds</h3>
|
||||
<div class="col-sm-7 pull-left">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header">
|
||||
<h3 class="box-title">Latest Builds</h3>
|
||||
</div>
|
||||
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Project</th>
|
||||
<th>Commit</th>
|
||||
<th>Branch</th>
|
||||
<th>Status</th>
|
||||
<th style="width: 100px"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="latest-builds">
|
||||
<?php print $builds; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="box-body">
|
||||
<ul class="timeline">
|
||||
<?php $last = new \DateTime('-1 Year'); ?>
|
||||
|
||||
<?php
|
||||
foreach ($builds as $build):
|
||||
|
||||
switch ($build->getStatus()) {
|
||||
case \PHPCI\Model\Build::STATUS_NEW:
|
||||
$updated = $build->getCreated();
|
||||
$label = 'Created';
|
||||
$color = 'blue';
|
||||
break;
|
||||
|
||||
case \PHPCI\Model\Build::STATUS_RUNNING:
|
||||
$updated = $build->getStarted();
|
||||
$label = 'Started';
|
||||
$color = 'yellow';
|
||||
break;
|
||||
|
||||
case \PHPCI\Model\Build::STATUS_SUCCESS:
|
||||
$updated = $build->getFinished();
|
||||
$label = 'Successful';
|
||||
$color = 'green';
|
||||
break;
|
||||
|
||||
case \PHPCI\Model\Build::STATUS_FAILED:
|
||||
$updated = $build->getFinished();
|
||||
$label = 'Failed';
|
||||
$color = 'red';
|
||||
break;
|
||||
}
|
||||
|
||||
if ($updated->format('Y-m-d') != $last->format('Y-m-d')): $last = $updated;
|
||||
?>
|
||||
<li class="time-label">
|
||||
<span class="bg-gray">
|
||||
<?php print $last->format('M j Y'); ?>
|
||||
</span>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- /.timeline-label -->
|
||||
<!-- timeline item -->
|
||||
<li>
|
||||
<i class="fa fa-<?php print $build->getProject()->getIcon(); ?> bg-<?php print $color; ?>"></i>
|
||||
<div class="timeline-item">
|
||||
<span class="time"><i class="fa fa-clock-o"></i> <?php print $updated->format('g:ia'); ?></span>
|
||||
<h3 class="timeline-header">
|
||||
<a href="<?php print PHPCI_URL; ?>project/view/<?php print $build->getProjectId(); ?>">
|
||||
<?php print $build->getProject()->getTitle(); ?>
|
||||
</a>
|
||||
-
|
||||
<a href="<?php print PHPCI_URL; ?>build/view/<?php print $build->getId(); ?>">
|
||||
Build #<?php print $build->getId(); ?>
|
||||
</a>
|
||||
-
|
||||
<?php print $label; ?>
|
||||
</h3>
|
||||
|
||||
<div class="timeline-body">
|
||||
<?php
|
||||
if ($build->getCommitId() !== 'Manual') {
|
||||
print sprintf(
|
||||
'<a href="%s" target="_blank">%s (%s)</a>',
|
||||
$build->getCommitLink(),
|
||||
substr($build->getCommitId(), 0, 7),
|
||||
$build->getCommitterEmail()
|
||||
);
|
||||
} else {
|
||||
print 'Manual Build';
|
||||
}
|
||||
?>
|
||||
- <?php print $build->getCommitMessage(); ?>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<!-- END timeline item -->
|
||||
|
||||
<?php endforeach; ?>
|
||||
|
||||
<li>
|
||||
<i class="fa fa-clock-o"></i>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var refreshProjectData = function()
|
||||
{
|
||||
$.ajax({
|
||||
url: '<?php echo PHPCI_URL ?>home/latest',
|
||||
|
||||
success: function (data) {
|
||||
$('#latest-builds').html(data);
|
||||
$('#latest-builds').trigger('latest-builds:reload');
|
||||
},
|
||||
|
||||
error: handleFailedAjax
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
url: '<?php echo PHPCI_URL ?>home/summary',
|
||||
|
||||
success: function (data) {
|
||||
$('#project-overview').html(data);
|
||||
$('#project-overview').trigger('project-overview:reload');
|
||||
},
|
||||
|
||||
error: handleFailedAjax
|
||||
});
|
||||
};
|
||||
|
||||
setInterval(refreshProjectData, 10000);
|
||||
</script>
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
<h1 id="title">Packages and Provided Plugins</h1>
|
||||
|
||||
<?php if (!$canWrite): ?>
|
||||
<p class="alert alert-danger">PHPCI cannot update composer.json for you as it is not writable.</p>
|
||||
<?php endif; ?>
|
||||
|
@ -12,10 +10,12 @@
|
|||
<p class="alert alert-success"><strong><?php echo $_GET['w']; ?></strong> has been added to composer.json for you and will be installed next time you run composer update.</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="box">
|
||||
<h3 class="title">Available Plugins</h3>
|
||||
<div class="box box-primary">
|
||||
<div class="box-header">
|
||||
<h3 class="box-title">Enabled Plugins</h3>
|
||||
</div>
|
||||
|
||||
<table class="table-striped table-bordered table">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
|
@ -35,85 +35,104 @@
|
|||
</table>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<h3 class="title">Installed Packages</h3>
|
||||
|
||||
<table class="table-striped table-bordered table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Title</th>
|
||||
<th>Version</th>
|
||||
<th width="1"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($installedPackages as $package => $version): ?>
|
||||
<tr>
|
||||
<td><?php echo $package; ?></td>
|
||||
<td><?php echo $version; ?></td>
|
||||
<td>
|
||||
<?php if (!in_array($package, $required) && $canWrite): ?>
|
||||
<a class="btn btn-danger btn-small" href="<?php echo PHPCI_URL ?>plugin/remove?package=<?php echo $package; ?>">Remove »</a>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header">
|
||||
<h3 class="box-title">Installed Packages</h3>
|
||||
</div>
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Title</th>
|
||||
<th>Version</th>
|
||||
<th width="1"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($installedPackages as $package => $version): ?>
|
||||
<tr>
|
||||
<td><?php echo $package; ?></td>
|
||||
<td><?php echo $version; ?></td>
|
||||
<td>
|
||||
<?php if (!in_array($package, $required) && $canWrite): ?>
|
||||
<a class="btn btn-danger btn-small" href="<?php echo PHPCI_URL ?>plugin/remove?package=<?php echo $package; ?>">Remove »</a>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="col-lg-6">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header">
|
||||
<h3 class="box-title">Suggested Packages</h3>
|
||||
</div>
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Title</th>
|
||||
<th>Description</th>
|
||||
<th width="1"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($suggestedPackages as $package => $version): ?>
|
||||
<?php if (in_array($package, array_keys($installedPackages))) { continue; } ?>
|
||||
<tr>
|
||||
<td><?php echo $package; ?></td>
|
||||
<td><?php echo $version; ?></td>
|
||||
<td>
|
||||
<?php if ($canWrite): ?>
|
||||
<button data-name="<?php echo $package; ?>" class="install-package btn btn-success btn-small">Install »</button>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<h3 class="title">Suggested Packages</h3>
|
||||
<div class="box box-primary">
|
||||
<div class="box-header">
|
||||
<h3 class="box-title">Search Packagist for More Packages</h3>
|
||||
</div>
|
||||
|
||||
<table class="table-striped table-bordered table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Title</th>
|
||||
<th>Description</th>
|
||||
<th width="1"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($suggestedPackages as $package => $version): ?>
|
||||
<?php if (in_array($package, array_keys($installedPackages))) { continue; } ?>
|
||||
<tr>
|
||||
<td><?php echo $package; ?></td>
|
||||
<td><?php echo $version; ?></td>
|
||||
<td>
|
||||
<?php if ($canWrite): ?>
|
||||
<button data-name="<?php echo $package; ?>" class="install-package btn btn-success btn-small">Install »</button>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<h3 class="title">Search Packagist for More Packages</h3>
|
||||
|
||||
<div class="input-group">
|
||||
<input id="search-query" type="text" class="form-control">
|
||||
<div class="box-body">
|
||||
<div class="input-group">
|
||||
<input id="search-query" type="text" class="form-control">
|
||||
<span class="input-group-btn">
|
||||
<button id="search-button" class="btn btn-success" type="button">Search</button>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div id="results" style="margin-top: 15px; display: none;">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Title</th>
|
||||
<th>Description</th>
|
||||
<th width="1"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="search-results">
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="results" style="margin-top: 15px; display: none;">
|
||||
<table class="table-striped table-bordered table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Title</th>
|
||||
<th>Description</th>
|
||||
<th width="1"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="search-results">
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
|
|
@ -1,73 +1,47 @@
|
|||
<h1><i class="glyphicon glyphicon-th-list"></i> <?php print htmlspecialchars($project->getTitle()); ?></h1>
|
||||
<script>
|
||||
var PHPCI_PROJECT_ID = <?php print $project->getId(); ?>;
|
||||
var PHPCI_PROJECT_BRANCH = '<?php print $branch; ?>';
|
||||
</script>
|
||||
|
||||
<div class="clearfix" style="margin-bottom: 20px;">
|
||||
<div class="pull-right btn-group">
|
||||
<a class="btn btn-success" href="<?php print PHPCI_URL . 'project/build/' . $project->getId(); ?>">Build Now</a>
|
||||
|
||||
<div class="btn-group branch-btn pull-right">
|
||||
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
|
||||
Branch<?php print !empty($branch) ? ': ' . $branch : ''; ?> <span class="caret"></span>
|
||||
</button>
|
||||
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<?php foreach ($branches as $curbranch) : ?>
|
||||
<li <?php echo ($curbranch == $branch) ? 'class="active"' : ''?>>
|
||||
<a href="<?php echo PHPCI_URL ?>project/view/<?php print $project->getId(); ?>?branch=<?php echo urlencode($curbranch) ?>">
|
||||
<?php echo $curbranch ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
|
||||
<li class="divider"></li>
|
||||
<li><a href="<?php echo PHPCI_URL ?>project/view/<?php print $project->getId(); ?>">All</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-3">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">Options</h3>
|
||||
<div class="col-lg-9 col-md-8 col-sm-8">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header">
|
||||
|
||||
<h3 class="box-title">Builds</h3>
|
||||
</div>
|
||||
|
||||
<div class="list-group">
|
||||
<a class="list-group-item" href="<?php echo PHPCI_URL ?>project/build/<?php print $project->getId(); ?>"><i class="glyphicon glyphicon-cog"></i> Build Now</a>
|
||||
|
||||
<?php if($this->User()->getIsAdmin()): ?>
|
||||
<a class="list-group-item" href="<?php echo PHPCI_URL ?>project/edit/<?php print $project->getId(); ?>"><i class="glyphicon glyphicon-edit"></i> Edit Project</a>
|
||||
<a class="list-group-item" href="#" id="delete-project"><i class="glyphicon glyphicon-trash"></i> Delete Project</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (in_array($project->getType(), array('github', 'gitlab', 'bitbucket'))): ?>
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">Webhooks</h4>
|
||||
</div>
|
||||
|
||||
<div class="panel-body">
|
||||
To automatically build this project when new commits are pushed, add the URL below
|
||||
|
||||
<?php
|
||||
switch($project->getType())
|
||||
{
|
||||
case 'github':
|
||||
$url = PHPCI_URL . 'webhook/github/' . $project->getId();
|
||||
print ' as a "WebHook URL" in the <a href="https://github.com/' . $project->getReference() . '/settings/hooks">Service Hooks</a> section of your Github repository.<br><br><strong style="word-wrap: break-word;">' . $url . '</strong>';
|
||||
break;
|
||||
|
||||
case 'gitlab':
|
||||
$url = PHPCI_URL. 'webhook/gitlab/' . $project->getId();
|
||||
print ' as a "WebHook URL" in the Web Hooks section of your Gitlab repository.<br><br><strong style="word-wrap: break-word;">' . $url . '</strong>';
|
||||
break;
|
||||
|
||||
case 'bitbucket':
|
||||
$url = PHPCI_URL . 'webhook/bitbucket/' . $project->getId();
|
||||
print ' as a "POST" service in the <a href="https://bitbucket.org/' . $project->getReference() . '/admin/services">Services</a> section of your Bitbucket repository.<br><br><strong style="word-wrap: break-word;">' . $url . '</strong>';
|
||||
break;
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($project->getSshPublicKey()): ?>
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading"><h3 class="panel-title"><a data-toggle="collapse" data-parent="#accordion" href="#publicCollapse">Public Key</a></h3></div>
|
||||
<div id="publicCollapse" class="panel-collapse collapse out">
|
||||
<div class="panel-body word-wrap"><?php print $project->getSshPublicKey(); ?></div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="col-lg-9">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading"><h3 class="panel-title">Builds</h3></div>
|
||||
<table class="table table-striped table-bordered">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Project</th>
|
||||
<th>Commit</th>
|
||||
<th class="hidden-md hidden-sm hidden-xs">Commit</th>
|
||||
<th>Branch</th>
|
||||
<th>Status</th>
|
||||
<th style="width: 100px"></th>
|
||||
|
@ -78,61 +52,103 @@
|
|||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
|
||||
print '<div><ul class="pagination">';
|
||||
|
||||
if ($page > 1) {
|
||||
print '<li><a href="' . PHPCI_URL . 'project/view/'.$project->getId().'?p='.($page == 1 ? '1' : $page - 1).'">« Prev</a></li>';
|
||||
}
|
||||
|
||||
if ($pages > 1) {
|
||||
for($i = 1; $i <= $pages; $i++)
|
||||
{
|
||||
if ($i == $page) {
|
||||
print '<li><span>' . $i . '</span></li>';
|
||||
} else {
|
||||
print '<li><a href="' . PHPCI_URL . 'project/view/' . $project->getId() . '?p=' . $i . '">' . $i . '</a></li>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($page < $pages) {
|
||||
print '<li><a href="' . PHPCI_URL . 'project/view/'.$project->getId().'?p='.($page == $pages ? $pages : $page + 1).'">Next »</a></li>';
|
||||
}
|
||||
|
||||
print '</ul></div>';
|
||||
|
||||
?>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="col-lg-3 col-md-4 col-sm-4">
|
||||
|
||||
<?php if (in_array($project->getType(), array('github', 'gitlab', 'bitbucket'))): ?>
|
||||
<div class="box box-info">
|
||||
<div class="box-header">
|
||||
<h4 class="box-title">Webhooks</h4>
|
||||
</div>
|
||||
|
||||
<div class="box-body">
|
||||
To automatically build this project when new commits are pushed, add the URL below
|
||||
|
||||
<?php
|
||||
switch($project->getType())
|
||||
{
|
||||
case 'github':
|
||||
$url = PHPCI_URL . 'webhook/github/' . $project->getId();
|
||||
print ' as a new "Webhook" in the <a href="https://github.com/' . $project->getReference() . '/settings/hooks">Webhooks and Services</a> section of your Github repository.<br><br><strong style="word-wrap: break-word;">' . $url . '</strong>';
|
||||
break;
|
||||
|
||||
case 'gitlab':
|
||||
$url = PHPCI_URL. 'webhook/gitlab/' . $project->getId();
|
||||
print ' as a "WebHook URL" in the Web Hooks section of your Gitlab repository.<br><br><strong style="word-wrap: break-word;">' . $url . '</strong>';
|
||||
break;
|
||||
|
||||
case 'bitbucket':
|
||||
$url = PHPCI_URL . 'webhook/bitbucket/' . $project->getId();
|
||||
print ' as a "POST" service in the <a href="https://bitbucket.org/' . $project->getReference() . '/admin/services">Services</a> section of your Bitbucket repository.<br><br><strong style="word-wrap: break-word;">' . $url . '</strong>';
|
||||
break;
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($project->getSshPublicKey()): ?>
|
||||
<div class="box box-info">
|
||||
<div class="box-header"><h3 class="box-title"><a data-toggle="collapse" data-parent="#accordion" href="#publicCollapse">Public Key</a></h3></div>
|
||||
<div class="box-body" style="word-break: break-word;"><?php print $project->getSshPublicKey(); ?></div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if($page == 1): ?>
|
||||
<script>
|
||||
setInterval(function()
|
||||
<?php
|
||||
|
||||
print '<div><ul class="pagination">';
|
||||
|
||||
$project_url = PHPCI_URL . 'project/view/' . $project->getId() . ((!empty($branch)) ? '/' . urlencode($branch) : '');
|
||||
|
||||
if ($page > 1) {
|
||||
print '<li><a href="' . $project_url . '?p='.($page == 1 ? '1' : $page - 1).'">« Prev</a></li>';
|
||||
}
|
||||
|
||||
if ($pages > 1) {
|
||||
|
||||
$start = $page - 3;
|
||||
|
||||
if ($start <= 0) {
|
||||
$start = 1;
|
||||
}
|
||||
|
||||
$end = $page + 3;
|
||||
|
||||
if ($end > $pages) {
|
||||
$end = $pages;
|
||||
}
|
||||
|
||||
if ($start > 1) {
|
||||
print '<li><a href="' . $project_url . '">1...</a></li>';
|
||||
}
|
||||
|
||||
for($i = $start; $i <= $end; $i++)
|
||||
{
|
||||
$.ajax({
|
||||
url: '<?php echo PHPCI_URL ?>project/builds/<?php print $project->getId(); ?>',
|
||||
if ($pages > $end && $i == $pages) continue;
|
||||
|
||||
success: function (data) {
|
||||
$('#latest-builds').html(data);
|
||||
$('#latest-builds').trigger('latest-builds:reload');
|
||||
},
|
||||
if ($i == $page) {
|
||||
print '<li class="bg-blue"><span>' . $i . '</span></li>';
|
||||
} else {
|
||||
print '<li><a href="' . $project_url . '?p=' . $i . '">' . $i . '</a></li>';
|
||||
}
|
||||
}
|
||||
|
||||
error: handleFailedAjax
|
||||
});
|
||||
}, 10000);
|
||||
if ($pages > $end) {
|
||||
print '<li><a href="' . $project_url . '?p='.$pages.'">...'.$pages.'</a></li>';
|
||||
}
|
||||
}
|
||||
|
||||
$(function() {
|
||||
$('#delete-project').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
confirmDelete(
|
||||
"<?php echo PHPCI_URL ?>project/delete/<?php print $project->getId(); ?>", "Project"
|
||||
).onCloseConfirmed = function () {window.location = '/'};
|
||||
});
|
||||
})
|
||||
</script>
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
if ($page < $pages - 1) {
|
||||
print '<li><a href="' . $project_url . '?p='.($page == $pages ? $pages : $page + 1).'">Next »</a></li>';
|
||||
}
|
||||
|
||||
|
||||
|
||||
print '</ul></div>';
|
||||
|
||||
?>
|
|
@ -1,34 +1,29 @@
|
|||
<div id="title">
|
||||
<h1><?php print $type == 'add' ? 'Add Project' : 'Edit Project' ?></h1>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-4">
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-body">
|
||||
<?php if(!is_null($key)): ?>
|
||||
<p>To make it easier to get started, we've generated a public / private key pair for you to use for this project. To use it, just add the following public key to the "deploy keys" section of your repository settings on Github / Bitbucket.</p>
|
||||
|
||||
<textarea style="width: 90%; height: 150px;"><?php print $key ?></textarea>
|
||||
<?php elseif($type == 'add'): ?>
|
||||
<p style="margin-bottom:0;">Fill in the form to the right to add your new project.</p>
|
||||
<?php else: ?>
|
||||
<p style="margin-bottom:0;">Edit your project details using the form to the right.</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-8">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">Project Details</h3>
|
||||
<div class="col-sm-8">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header">
|
||||
<h3 class="box-title">Project Details</h3>
|
||||
</div>
|
||||
|
||||
<div class="panel-body">
|
||||
<div class="box-body">
|
||||
<?php print $form; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if(!is_null($key)): ?>
|
||||
<div class="col-sm-4">
|
||||
<div class="box box-info">
|
||||
<div class="box-body">
|
||||
<p>To make it easier to get started, we've generated a public / private key pair for you to use for this project. To use it, just add the following public key to the "deploy keys" section of your repository settings on Github / Bitbucket.</p>
|
||||
|
||||
<textarea style="width: 90%; height: 150px;"><?php print $key ?></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
|
|
@ -5,17 +5,17 @@
|
|||
<?php else: ?>
|
||||
<?php if (empty($error)): ?>
|
||||
<div class="panel panel-success" style="margin-bottom: 0">
|
||||
<div class="panel-heading">
|
||||
<div class="box-header">
|
||||
<strong>Don't worry!</strong><br>Just enter your email address below and we'll email you a link to reset your password.
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="panel panel-danger" style="margin-bottom: 0">
|
||||
<div class="panel-heading">
|
||||
<div class="box-header">
|
||||
<?php print $error; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="panel-body">
|
||||
<div class="box-body">
|
||||
<form class="form" action="<?php print PHPCI_URL; ?>session/forgot-password" method="POST">
|
||||
<div class="form-group">
|
||||
<label for="email">Enter your email address:</label>
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
|
||||
<?php if (empty($error)): ?>
|
||||
<div class="panel panel-success" style="margin-bottom: 0">
|
||||
<div class="panel-heading">
|
||||
<div class="box-header">
|
||||
Please enter a new password
|
||||
</div>
|
||||
|
||||
<div class="panel-body">
|
||||
<div class="box-body">
|
||||
<form class="form" action="<?php print PHPCI_URL; ?>session/reset-password/<?php print $id; ?>/<?php print $key; ?>" method="POST">
|
||||
<div class="form-group">
|
||||
<label for="password">New password:</label>
|
||||
|
|
|
@ -28,77 +28,81 @@
|
|||
</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="box">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<h3 class="title">Github Application</h3>
|
||||
|
||||
<?php
|
||||
$id = null;
|
||||
|
||||
if (isset($settings['phpci']['github']['id'])) {
|
||||
$id = $settings['phpci']['github']['id'];
|
||||
}
|
||||
|
||||
$returnTo = PHPCI_URL . 'settings/github-callback';
|
||||
$githubUri = 'https://github.com/login/oauth/authorize?client_id='.$id.'&scope=repo&redirect_uri=' . $returnTo;
|
||||
?>
|
||||
<?php if (!empty($id) && empty($settings['phpci']['github']['token'])): ?>
|
||||
<p class="alert alert-warning clearfix">
|
||||
Before you can start using Github, you need to <a href="<?php echo $githubUri; ?>">sign in</a> and grant PHPCI access to your account.
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($id) && !empty($settings['phpci']['github']['token'])): ?>
|
||||
<p class="alert alert-success">
|
||||
PHPCI is successfully linked to Github account
|
||||
<strong>
|
||||
<a href="<?php echo $githubUser['html_url']; ?>"><?php echo $githubUser['name']; ?></a>
|
||||
</strong>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-8">
|
||||
<?php print $github; ?>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4">
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">Where to find these...</h3>
|
||||
</div>
|
||||
|
||||
<div class="panel-body">
|
||||
<p>If you own the application you would like to use, you can find this information within your
|
||||
<a href="https://github.com/settings/applications">applications</a> settings area.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box box-primary">
|
||||
<div class="box-header"><h3 class="box-title">Build Settings</h3></div>
|
||||
<div class="box-body clearfix">
|
||||
<?php print $buildSettings; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<h3 class="title">Email Settings</h3>
|
||||
<div class="box box-primary">
|
||||
<div class="box-header"><h3 class="box-title">Github Application</h3></div>
|
||||
<div class="box-body clearfix">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<?php
|
||||
$id = null;
|
||||
|
||||
<?php if (!isset($settings['phpci']['email_settings'])): ?>
|
||||
<p class="alert alert-warning clearfix">
|
||||
Before PHPCI can send build status emails, you need to configure your SMTP settings below.
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
if (isset($settings['phpci']['github']['id'])) {
|
||||
$id = $settings['phpci']['github']['id'];
|
||||
}
|
||||
|
||||
$returnTo = PHPCI_URL . 'settings/github-callback';
|
||||
$githubUri = 'https://github.com/login/oauth/authorize?client_id='.$id.'&scope=repo&redirect_uri=' . $returnTo;
|
||||
?>
|
||||
<?php if (!empty($id) && empty($settings['phpci']['github']['token'])): ?>
|
||||
<p class="alert alert-warning clearfix">
|
||||
Before you can start using Github, you need to <a href="<?php echo $githubUri; ?>">sign in</a> and grant PHPCI access to your account.
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($id) && !empty($settings['phpci']['github']['token'])): ?>
|
||||
<p class="alert alert-success">
|
||||
PHPCI is successfully linked to Github account
|
||||
<strong>
|
||||
<a href="<?php echo $githubUser['html_url']; ?>"><?php echo $githubUser['name']; ?></a>
|
||||
</strong>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-8">
|
||||
<?php print $github; ?>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4">
|
||||
<div class="box box-info">
|
||||
<div class="box-header">
|
||||
<h3 class="box-title">Where to find these...</h3>
|
||||
</div>
|
||||
|
||||
<div class="box-body">
|
||||
<p>If you own the application you would like to use, you can find this information within your
|
||||
<a href="https://github.com/settings/applications">applications</a> settings area.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-8">
|
||||
<?php print $emailSettings; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="box box-primary">
|
||||
<div class="box-header">
|
||||
<h3 class="box-title">Email Settings</h3>
|
||||
</div>
|
||||
|
||||
<div class="box-body clearfix">
|
||||
<?php if (!isset($settings['phpci']['email_settings'])): ?>
|
||||
<p class="alert alert-warning clearfix">
|
||||
Before PHPCI can send build status emails, you need to configure your SMTP settings below.
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php print $emailSettings; ?>
|
||||
|
||||
<div class="col-lg-4">
|
||||
<!-- nothing -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -53,12 +53,12 @@ foreach($projects as $project):
|
|||
case 2:
|
||||
$successes++;
|
||||
$statuses[] = 'ok';
|
||||
$success = is_null($success) && !is_null($build->getFinished()) ? $build->getFinished()->format('Y-m-d H:i:s') : $success;
|
||||
$success = is_null($success) && !is_null($build->getFinished()) ? $build->getFinished()->format('M j Y g:ia') : $success;
|
||||
break;
|
||||
case 3:
|
||||
$failures++;
|
||||
$statuses[] = 'failed';
|
||||
$failure = is_null($failure) && !is_null($build->getFinished()) ? $build->getFinished()->format('Y-m-d H:i:s') : $failure;
|
||||
$failure = is_null($failure) && !is_null($build->getFinished()) ? $build->getFinished()->format('M j Y g:ia') : $failure;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -66,32 +66,83 @@ foreach($projects as $project):
|
|||
|
||||
if ($failures == 0) {
|
||||
$health = 'Good';
|
||||
$subcls = 'success';
|
||||
} elseif ($failures > $successes) {
|
||||
$subcls = 'green';
|
||||
} elseif ($successes == 0) {
|
||||
$health = 'Bad';
|
||||
$subcls = 'danger';
|
||||
$subcls = 'red';
|
||||
} else {
|
||||
$health = 'Warning';
|
||||
$subcls = 'warning';
|
||||
$subcls = 'yellow';
|
||||
}
|
||||
|
||||
|
||||
$buildCount = count($builds[$project->getId()]);
|
||||
$lastSuccess = $successful[$project->getId()];
|
||||
$lastFailure = $failed[$project->getId()];
|
||||
$message = 'No builds yet!';
|
||||
$shortMessage = 'No builds yet!';
|
||||
|
||||
if ($buildCount > 0) {
|
||||
if ($failures > 0) {
|
||||
$shortMessage = $failures . ' / ' . $buildCount . ' failed.';
|
||||
$message = $failures . ' out of the last ' . $buildCount . ' builds failed.';
|
||||
|
||||
if (!is_null($lastSuccess) && !is_null($lastSuccess->getFinished())) {
|
||||
$message .= ' The last successful build was ' . $lastSuccess->getFinished()->format('M j Y') . '.';
|
||||
} else {
|
||||
$message .= ' This project has never built successfully.';
|
||||
}
|
||||
} else {
|
||||
$shortMessage = $buildCount . ' / ' . $buildCount . ' passed.';
|
||||
$message = 'All of the last ' . $buildCount . ' builds passed.';
|
||||
|
||||
if (!is_null($lastFailure) && !is_null($lastFailure->getFinished())) {
|
||||
$message .= ' The last failed build was ' . $lastFailure->getFinished()->format('M j Y') . '.';
|
||||
} else {
|
||||
$message .= ' This project has never failed to build.';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
<tr class="<?php print $cls; ?>">
|
||||
<td>
|
||||
<span class='label label-<?php echo $subcls ?>'>
|
||||
<?php echo $health ?>
|
||||
</span>
|
||||
</td>
|
||||
<td><a href='<?php echo PHPCI_URL ?>project/view/<?php echo $project->getId() ?>'><?php echo htmlspecialchars($project->getTitle()) ?></a></td>
|
||||
<td><?php print is_null($success) ? 'Never' : $success; ?></td>
|
||||
<td><?php print is_null($failure) ? 'Never' : $failure; ?></td>
|
||||
<td>
|
||||
<?php
|
||||
foreach ($statuses as $status) {
|
||||
print '<img alt="'.$status.'" src="' . PHPCI_URL . 'assets/img/icon-build-' . $status . '.png">';
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
<td><a class="btn btn-default btn-sm" href='<?php echo PHPCI_URL ?>project/build/<?php echo $project->getId(); ?>'>build now »</a></td>
|
||||
</tr>
|
||||
|
||||
<?php if (count($projects) > 10): ?>
|
||||
|
||||
<div class="small-box bg-<?php print $subcls; ?>">
|
||||
<div class="inner">
|
||||
<h4>
|
||||
<strong>
|
||||
<a href="<?php print PHPCI_URL; ?>project/view/<?php print $project->getId(); ?>">
|
||||
<?php print $project->getTitle(); ?>
|
||||
</a>
|
||||
</strong> -
|
||||
<?php print $shortMessage; ?>
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php else: ?>
|
||||
|
||||
<div class="small-box bg-<?php print $subcls; ?>">
|
||||
<div class="inner">
|
||||
<h3>
|
||||
<a href="<?php print PHPCI_URL; ?>project/view/<?php print $project->getId(); ?>">
|
||||
<?php print $project->getTitle(); ?>
|
||||
</a>
|
||||
</h3>
|
||||
|
||||
<p>
|
||||
<?php print $message; ?>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
<div class="icon">
|
||||
<i class="fa fa-<?php print $project->getIcon(); ?>"></i>
|
||||
</div>
|
||||
<a href="<?php print PHPCI_URL; ?>project/view/<?php print $project->getId(); ?>" class="small-box-footer">
|
||||
View Project <i class="fa fa-arrow-circle-right"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
|
|
|
@ -1,67 +1,60 @@
|
|||
<div id="title">
|
||||
<h1>Users</h1>
|
||||
<div class="clearfix" style="margin-bottom: 20px;">
|
||||
<div class="pull-right btn-group">
|
||||
<a class="btn btn-primary" href="<?php print PHPCI_URL; ?>user/add">Add User</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-3">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">Options</h4>
|
||||
</div>
|
||||
<div class="col-xs-12">
|
||||
<div class="box box-primary">
|
||||
|
||||
<div class="list-group">
|
||||
<?php if($this->User()->getIsAdmin()): ?>
|
||||
<a class="list-group-item" href="<?php echo PHPCI_URL ?>user/add"><i class="icon-plus-sign"></i> Add User</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-9">
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Email Address</th>
|
||||
<th>Name</th>
|
||||
<th>Administrator</th>
|
||||
<th style="width: 100px"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="users">
|
||||
<?php foreach($users['items'] as $user): ?>
|
||||
<?php
|
||||
switch($user->getIsAdmin())
|
||||
{
|
||||
case 0:
|
||||
$cls = '';
|
||||
$status = 'No';
|
||||
break;
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Email Address</th>
|
||||
<th>Name</th>
|
||||
<th>Administrator</th>
|
||||
<th style="width: 100px"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="users">
|
||||
<?php foreach($users['items'] as $user): ?>
|
||||
<?php
|
||||
switch($user->getIsAdmin())
|
||||
{
|
||||
case 0:
|
||||
$cls = '';
|
||||
$status = 'No';
|
||||
break;
|
||||
|
||||
case 1:
|
||||
$cls = 'warning';
|
||||
$status = 'Yes';
|
||||
break;
|
||||
}
|
||||
?>
|
||||
<tr class="<?php print $cls; ?>">
|
||||
<td><a href="<?php echo PHPCI_URL ?>user/edit/<?php print $user->getId(); ?>"><?php print $user->getEmail(); ?></a></td>
|
||||
<td><?php print htmlspecialchars($user->getName()); ?></td>
|
||||
<td><?php print $status; ?></td>
|
||||
<td>
|
||||
<?php if($this->User()->getIsAdmin()): ?>
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-default btn-small" href="<?php echo PHPCI_URL ?>user/edit/<?php print $user->getId(); ?>">Edit</a>
|
||||
<button class="btn btn-default btn-small dropdown-toggle" data-toggle="dropdown">
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="<?php echo PHPCI_URL ?>user/delete/<?php print $user->getId(); ?>" class="phpci-app-delete-user">Delete User</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
case 1:
|
||||
$cls = 'warning';
|
||||
$status = 'Yes';
|
||||
break;
|
||||
}
|
||||
?>
|
||||
<tr class="<?php print $cls; ?>">
|
||||
<td><a href="<?php echo PHPCI_URL ?>user/edit/<?php print $user->getId(); ?>"><?php print $user->getEmail(); ?></a></td>
|
||||
<td><?php print htmlspecialchars($user->getName()); ?></td>
|
||||
<td><?php print $status; ?></td>
|
||||
<td>
|
||||
<?php if($this->User()->getIsAdmin()): ?>
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-default btn-small" href="<?php echo PHPCI_URL ?>user/edit/<?php print $user->getId(); ?>">Edit</a>
|
||||
<button class="btn btn-default btn-small dropdown-toggle" data-toggle="dropdown">
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="<?php echo PHPCI_URL ?>user/delete/<?php print $user->getId(); ?>" class="phpci-app-delete-user">Delete User</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
<h1><?php print $this->User()->getName(); ?></h1>
|
||||
|
||||
<?php if (isset($updated)): ?>
|
||||
<p class="alert alert-success">Your details have been updated.</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">Update your details</h3>
|
||||
<div class="box box-primary">
|
||||
<div class="box-header">
|
||||
<h3 class="box-title">Update your details</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="box-body">
|
||||
<?php print $form; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,20 +1,9 @@
|
|||
<div id="title">
|
||||
<h1><?php print $type == 'add' ? 'Add User' : 'Edit ' . htmlspecialchars($user->getName()) ?></h1>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-4">
|
||||
<div class="well" style="">
|
||||
<?php if($type == 'add'): ?>
|
||||
<p style="margin-bottom:0;">Fill in the form to the right to add a new user.</p>
|
||||
<?php else: ?>
|
||||
<p style="margin-bottom:0;">Edit user details using the form to the right.</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-8">
|
||||
<div class="box">
|
||||
<?php print $form; ?>
|
||||
<div class="col-sm-12">
|
||||
<div class="box box-primary">
|
||||
<div class="box-body">
|
||||
<?php print $form; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<div class="panel panel-danger">
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title">Sorry, there was a problem</h2>
|
||||
<div class="box-header">
|
||||
<h2 class="box-title">Sorry, there was a problem</h2>
|
||||
</div>
|
||||
|
||||
<div class="panel-body">
|
||||
<div class="box-body">
|
||||
<?php print $exception->getMessage(); ?>
|
||||
</div>
|
||||
</div>
|
|
@ -1,86 +1,312 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title><?php if (!empty($title)) { print $title . ' - '; } ?>PHPCI</title>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title><?php print $title; ?><?php print !empty($subtitle) ? ' - ' . $subtitle : ''; ?></title>
|
||||
<meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' name='viewport'>
|
||||
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="//cdnjs.cloudflare.com/ajax/libs/ionicons/1.5.2/css/ionicons.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="//cdnjs.cloudflare.com/ajax/libs/morris.js/0.5.1/morris.css" rel="stylesheet" type="text/css" />
|
||||
|
||||
<link href='//fonts.googleapis.com/css?family=Roboto:300,500&subset=latin,latin-ext' rel='stylesheet' type='text/css'>
|
||||
<link rel="stylesheet" type="text/css" href="<?php echo PHPCI_URL ?>assets/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" type="text/css" href="<?php echo PHPCI_URL ?>assets/css/phpci.css">
|
||||
<link href="<?php print PHPCI_URL; ?>assets/css/datepicker/datepicker3.css" rel="stylesheet" type="text/css" />
|
||||
<link href="<?php print PHPCI_URL; ?>assets/css/daterangepicker/daterangepicker-bs3.css" rel="stylesheet" type="text/css" />
|
||||
|
||||
<link rel="shortcut icon" type="image/x-icon" href="<?php echo PHPCI_URL ?>favicon.ico">
|
||||
<link rel="shortcut icon" type="image/png" href="<?php echo PHPCI_URL ?>assets/img/favicon.png">
|
||||
<!-- Theme style -->
|
||||
<link href="<?php print PHPCI_URL; ?>assets/css/AdminLTE.css" rel="stylesheet" type="text/css" />
|
||||
|
||||
<script>window.PHPCI_URL = <?php print json_encode(PHPCI_URL) ?></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.js"></script>
|
||||
<script src="<?php print PHPCI_URL; ?>assets/js/class.js"></script>
|
||||
<script src="<?php print PHPCI_URL; ?>assets/js/phpci.js" type="text/javascript"></script>
|
||||
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
|
||||
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
|
||||
<!--[if lt IE 9]>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.2/html5shiv.min.js"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/respond.js/1.4.2/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<script src="<?php echo PHPCI_URL ?>assets/js/bootstrap.min.js"></script>
|
||||
<script src="<?php echo PHPCI_URL ?>assets/js/jqueryui.js"></script>
|
||||
<script src="<?php echo PHPCI_URL ?>assets/js/class.js"></script>
|
||||
<script src="<?php echo PHPCI_URL ?>assets/js/phpci.js"></script>
|
||||
<script src="<?php echo PHPCI_URL ?>assets/js/init.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="navbar navbar-fixed-top">
|
||||
<div class="container">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<script>var PHPCI_URL = '<?php print PHPCI_URL; ?>';</script>
|
||||
|
||||
<a class="navbar-brand" href="<?php echo PHPCI_URL ?>"><img src="<?php echo PHPCI_URL ?>/assets/img/logo.png"></a>
|
||||
<style>
|
||||
.skin-blue .logo, .skin-blue .logo:hover {
|
||||
background-image: url('/assets/img/logo-large.png');
|
||||
background-repeat: no-repeat;
|
||||
background-size: 40%;
|
||||
background-position: 65px;
|
||||
text-indent: -5000px;
|
||||
}
|
||||
|
||||
<div class="navbar-collapse collapse">
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
.build-info-panel {
|
||||
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||
<img class="pull-left" style="margin-right: 7px; margin-top: -5px; border-radius: 50%" src="//www.gravatar.com/avatar/<?php print md5($this->User()->getEmail()); ?>?d=mm&s=30">
|
||||
}
|
||||
|
||||
<strong><?php print htmlspecialchars($this->User()->getName()); ?></strong> <b class="caret"></b>
|
||||
.build-info-panel .box-header h1.box-title {
|
||||
border: 0;
|
||||
font-size: 1.5em;
|
||||
font-weight: bold;
|
||||
margin-left: 110px;
|
||||
}
|
||||
|
||||
.build-info-panel h1.box-title span {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.build-info-panel img {
|
||||
border: 2px solid #fff;
|
||||
border-radius: 50%;
|
||||
margin-top: -40px;
|
||||
}
|
||||
|
||||
.build-info-panel #build-info {
|
||||
margin-left: 110px;
|
||||
min-height: 50px;
|
||||
}
|
||||
|
||||
.build-info-panel .commit-message {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.small-box h3 a, .small-box h4 a {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.pagination>li>span {
|
||||
font-weight: bold;
|
||||
background: #337ab7;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body class="skin-blue">
|
||||
<!-- header logo: style can be found in header.less -->
|
||||
<header class="header">
|
||||
<a href="<?php print PHPCI_URL; ?>" class="logo">PHPCI</a>
|
||||
<!-- Header Navbar: style can be found in header.less -->
|
||||
<nav class="navbar navbar-static-top" role="navigation">
|
||||
<!-- Sidebar toggle button-->
|
||||
<a href="#" class="navbar-btn sidebar-toggle" data-toggle="offcanvas" role="button">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</a>
|
||||
<div class="navbar-right">
|
||||
<ul class="nav navbar-nav">
|
||||
|
||||
<li class="dropdown messages-menu phpci-pending">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||
<i class="fa fa-clock-o"></i>
|
||||
<span class="label label-info phpci-pending-count"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li class="header"><span class="phpci-pending-count"></span> builds pending</li>
|
||||
<li>
|
||||
<ul class="menu phpci-pending-list">
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="dropdown messages-menu phpci-running">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||
<i class="fa fa-cogs"></i>
|
||||
<span class="label label-warning phpci-running-count"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li class="header"><span class="phpci-running-count"></span> builds running</li>
|
||||
<li>
|
||||
<ul class="menu phpci-running-list">
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
|
||||
<!-- User Account: style can be found in dropdown.less -->
|
||||
<li class="dropdown user user-menu">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||
<i class="glyphicon glyphicon-user"></i>
|
||||
<span><?php print $this->User()->getName(); ?> <i class="caret"></i></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<!-- User image -->
|
||||
<li class="user-header bg-light-blue">
|
||||
<img src="https://www.gravatar.com/avatar/<?php print md5($this->User()->getEmail()); ?>?d=mm" class="img-circle" alt="<?php print $this->User()->getName(); ?>" />
|
||||
<p>
|
||||
<?php print $this->User()->getName(); ?>
|
||||
</p>
|
||||
</li>
|
||||
|
||||
<!-- Menu Footer-->
|
||||
<li class="user-footer">
|
||||
<div class="pull-left">
|
||||
<a href="<?php print PHPCI_URL ?>user/profile" class="btn btn-default btn-flat">Edit Profile</a>
|
||||
</div>
|
||||
<div class="pull-right">
|
||||
<a href="<?php print PHPCI_URL ?>session/logout" class="btn btn-default btn-flat">Sign out</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
<div class="wrapper row-offcanvas row-offcanvas-left">
|
||||
<!-- Left side column. contains the logo and sidebar -->
|
||||
<aside class="left-side sidebar-offcanvas">
|
||||
<!-- sidebar: style can be found in sidebar.less -->
|
||||
<section class="sidebar">
|
||||
<!-- Sidebar user panel -->
|
||||
<div class="user-panel">
|
||||
<div class="pull-left image">
|
||||
<img src="https://www.gravatar.com/avatar/<?php print md5($this->User()->getEmail()); ?>?d=mm" class="img-circle" alt="<?php print $this->User()->getName(); ?>" />
|
||||
</div>
|
||||
<div class="pull-left info">
|
||||
<p>Hello, <?php print $this->User()->getName(); ?></p>
|
||||
|
||||
<a href="#"><i class="fa fa-circle text-success"></i> Online</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- sidebar menu: : style can be found in sidebar.less -->
|
||||
<ul class="sidebar-menu">
|
||||
<li class="active">
|
||||
<a href="<?php print PHPCI_URL; ?>">
|
||||
<i class="fa fa-dashboard"></i> <span>Dashboard</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<?php if ($this->User()->getIsAdmin()): ?>
|
||||
<li class="treeview">
|
||||
<a href="#">
|
||||
<i class="fa fa-edit"></i>
|
||||
<span>Admin Options</span>
|
||||
<i class="fa fa-angle-left pull-right"></i>
|
||||
</a>
|
||||
|
||||
<ul class="treeview-menu">
|
||||
<li>
|
||||
<a href="<?php print PHPCI_URL; ?>project/add">
|
||||
<i class="fa fa-angle-double-right"></i> Add Project
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="<?php print PHPCI_URL; ?>settings">
|
||||
<i class="fa fa-angle-double-right"></i> Settings
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="<?php print PHPCI_URL; ?>user">
|
||||
<i class="fa fa-angle-double-right"></i> Manage Users
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="<?php print PHPCI_URL; ?>plugin">
|
||||
<i class="fa fa-angle-double-right"></i> Plugins
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php foreach ($projects['items'] as $project): ?>
|
||||
<li class="treeview">
|
||||
<a href="#">
|
||||
<i class="fa fa-<?php print $project->getIcon(); ?>"></i>
|
||||
<span><?php print $project->getTitle(); ?></span>
|
||||
<i class="fa fa-angle-left pull-right"></i>
|
||||
</a>
|
||||
|
||||
<ul class="treeview-menu">
|
||||
<li>
|
||||
<a href="<?php print PHPCI_URL; ?>project/view/<?php print $project->getId(); ?>">
|
||||
<i class="fa fa-angle-double-right"></i> View
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="<?php print PHPCI_URL; ?>project/build/<?php print $project->getId(); ?>">
|
||||
<i class="fa fa-angle-double-right"></i> Build Now
|
||||
</a>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><a href="<?php print PHPCI_URL ?>user/profile">Edit Profile</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="<?php print PHPCI_URL ?>session/logout">Log out</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<?php if ($this->User()->getIsAdmin()): ?>
|
||||
<li>
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-success navbar-btn" href="<?php echo PHPCI_URL ?>project/add">Add Project</a>
|
||||
</div>
|
||||
<a href="<?php print PHPCI_URL; ?>project/edit/<?php print $project->getId(); ?>">
|
||||
<i class="fa fa-angle-double-right"></i> Edit Project
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn navbar-btn btn-default dropdown-toggle" data-toggle="dropdown">
|
||||
Admin <span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><a href="<?php echo PHPCI_URL ?>settings">Settings</a></li>
|
||||
<li><a href="<?php echo PHPCI_URL ?>plugin">Manage Plugins</a></li>
|
||||
<li><a href="<?php echo PHPCI_URL ?>user">Manage Users</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<li>
|
||||
<a href="<?php print PHPCI_URL; ?>project/delete/<?php print $project->getId(); ?>">
|
||||
<i class="fa fa-angle-double-right"></i> Delete Project
|
||||
</a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
|
||||
<?php if (isset($nav)): ?>
|
||||
<li class="treeview">
|
||||
<a href="#">
|
||||
<i class="fa fa-<?php print $nav['icon']; ?>"></i>
|
||||
<span><?php print $nav['title']; ?></span>
|
||||
<i class="fa fa-angle-left pull-right"></i>
|
||||
</a>
|
||||
|
||||
<ul class="treeview-menu">
|
||||
<?php foreach ($nav['links'] as $link => $linkTitle): ?>
|
||||
<li>
|
||||
<a href="<?php print PHPCI_URL . $link; ?>">
|
||||
<i class="fa fa-angle-double-right"></i> <?php print $linkTitle; ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
|
||||
</ul>
|
||||
</section>
|
||||
<!-- /.sidebar -->
|
||||
</aside>
|
||||
|
||||
<!-- Right side column. Contains the navbar and content of the page -->
|
||||
<aside class="right-side">
|
||||
<!-- Content Header (Page header) -->
|
||||
<section class="content-header">
|
||||
<h1>
|
||||
<?php print !empty($title) ? $title : 'PHPCI'; ?>
|
||||
|
||||
<?php if (!empty($subtitle)): ?>
|
||||
<small><?php print $subtitle; ?></small>
|
||||
<?php endif; ?>
|
||||
</h1>
|
||||
</section>
|
||||
|
||||
<!-- Main content -->
|
||||
<section class="content">
|
||||
<?php print $content; ?>
|
||||
</section><!-- /.content -->
|
||||
</aside><!-- /.right-side -->
|
||||
</div><!-- ./wrapper -->
|
||||
|
||||
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js" type="text/javascript"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.1/js/bootstrap.min.js" type="text/javascript"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/morris.js/0.5.1/morris.min.js" type="text/javascript"></script>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<script src="<?php print PHPCI_URL; ?>assets/js/plugins/daterangepicker/daterangepicker.js" type="text/javascript"></script>
|
||||
<script src="<?php print PHPCI_URL; ?>assets/js/plugins/datepicker/bootstrap-datepicker.js" type="text/javascript"></script>
|
||||
<script src="<?php print PHPCI_URL; ?>assets/js/AdminLTE/app.js" type="text/javascript"></script>
|
||||
|
||||
<div id="content" class="container">
|
||||
<?php print $content; ?>
|
||||
</div>
|
||||
|
||||
<div id="loading">Loading...</div>
|
||||
</body>
|
||||
</html>
|
||||
</body>
|
||||
</html>
|
|
@ -7,6 +7,10 @@ PHPCI is a free and open source (BSD License) continuous integration tool specif
|
|||
|
||||
[![Build Status](http://phpci.block8.net/build-status/image/2?branch=master)](http://phpci.block8.net/build-status/view/2?branch=master)
|
||||
|
||||
**Chat Room**
|
||||
|
||||
We have a chat room for discussing PHPCI, you can access it here: [![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/Block8/PHPCI?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=body_badge)
|
||||
|
||||
##What it does:
|
||||
* Clones your project from Github, Bitbucket or a local path
|
||||
* Allows you to set up and tear down test databases.
|
||||
|
|
237
Tests/PHPCI/Command/InstallCommandTest.php
Normal file
|
@ -0,0 +1,237 @@
|
|||
<?php
|
||||
|
||||
namespace PHPCI\Plugin\Tests\Command;
|
||||
|
||||
use Symfony\Component\Console\Application;
|
||||
use PHPCI\Command\InstallCommand;
|
||||
use Prophecy\PhpUnit\ProphecyTestCase;
|
||||
use Symfony\Component\Console\Tester\CommandTester;
|
||||
use Symfony\Component\Console\Helper\HelperSet;
|
||||
|
||||
class InstallCommandTest extends ProphecyTestCase
|
||||
{
|
||||
protected $config;
|
||||
protected $admin;
|
||||
protected $command;
|
||||
protected $dialog;
|
||||
protected $application;
|
||||
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
// Current command, we need to mock all method that interact with
|
||||
// Database & File system.
|
||||
$this->command = $this->getMockBuilder('PHPCI\\Command\\InstallCommand')
|
||||
->setMethods(array(
|
||||
'reloadConfig',
|
||||
'verifyNotInstalled',
|
||||
'verifyDatabaseDetails',
|
||||
'setupDatabase',
|
||||
'createAdminUser',
|
||||
'writeConfigFile',
|
||||
))
|
||||
->getMock();
|
||||
|
||||
$this->command->expects($this->once())->method('verifyDatabaseDetails')->willReturn(true);
|
||||
$this->command->expects($this->once())->method('setupDatabase')->willReturn(true);
|
||||
$this->command->expects($this->once())->method('createAdminUser')->will(
|
||||
$this->returnCallback(function ($adm) {// use (&$admin) {
|
||||
$this->admin = $adm;
|
||||
})
|
||||
);
|
||||
$this->command->expects($this->once())->method('writeConfigFile')->will(
|
||||
$this->returnCallback(function ($cfg) { //use (&$config) {
|
||||
$this->config = $cfg;
|
||||
})
|
||||
);
|
||||
|
||||
// We check that there's no interaction with user.
|
||||
$this->dialog = $this->getMockBuilder('Symfony\\Component\\Console\\Helper\\DialogHelper')
|
||||
->setMethods(array(
|
||||
'ask',
|
||||
'askConfirmation',
|
||||
'askAndValidate',
|
||||
'askHiddenResponse',
|
||||
'askHiddenResponseAndValidate',
|
||||
))
|
||||
->getMock();
|
||||
|
||||
$this->application = new Application();
|
||||
$this->application->setHelperSet(new HelperSet());
|
||||
}
|
||||
|
||||
protected function getCommandTester()
|
||||
{
|
||||
$this->application->getHelperSet()->set($this->dialog, 'dialog');
|
||||
$this->application->add($this->command);
|
||||
$command = $this->application->find('phpci:install');
|
||||
$commandTester = new CommandTester($command);
|
||||
|
||||
return $commandTester;
|
||||
}
|
||||
|
||||
protected function getConfig($exclude = null)
|
||||
{
|
||||
$config = array(
|
||||
'--db-host' => 'localhost',
|
||||
'--db-name' => 'phpci1',
|
||||
'--db-user' => 'phpci2',
|
||||
'--db-pass' => 'phpci3',
|
||||
'--admin-mail' => 'phpci@phpci.test',
|
||||
'--admin-name' => 'phpci4',
|
||||
'--admin-pass' => 'phpci5',
|
||||
'--url' => 'http://test.phpci.org',
|
||||
);
|
||||
|
||||
if (!is_null($exclude)) {
|
||||
unset($config[$exclude]);
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
protected function executeWithoutParam($param = null)
|
||||
{
|
||||
// Clean result variables.
|
||||
$this->admin = array();
|
||||
$this->config = array();
|
||||
|
||||
// Get tester and execute with extracted parameters.
|
||||
$commandTester = $this->getCommandTester();
|
||||
$parameters = $this->getConfig($param);
|
||||
$commandTester->execute($parameters);
|
||||
}
|
||||
|
||||
public function testAutomticInstallation()
|
||||
{
|
||||
$this->dialog->expects($this->never())->method('ask');
|
||||
$this->dialog->expects($this->never())->method('askConfirmation');
|
||||
$this->dialog->expects($this->never())->method('askAndValidate');
|
||||
$this->dialog->expects($this->never())->method('askHiddenResponse');
|
||||
$this->dialog->expects($this->never())->method('askHiddenResponseAndValidate');
|
||||
|
||||
$this->executeWithoutParam();
|
||||
}
|
||||
|
||||
public function testDatabaseHostnameConfig()
|
||||
{
|
||||
// We specified an input value for hostname.
|
||||
$this->dialog->expects($this->once())->method('ask')->willReturn('testedvalue');
|
||||
$this->dialog->expects($this->never())->method('askConfirmation');
|
||||
$this->dialog->expects($this->never())->method('askAndValidate');
|
||||
$this->dialog->expects($this->never())->method('askHiddenResponse');
|
||||
$this->dialog->expects($this->never())->method('askHiddenResponseAndValidate');
|
||||
|
||||
$this->executeWithoutParam('--db-host');
|
||||
|
||||
// Check that specified arguments are correctly loaded.
|
||||
$this->assertEquals('testedvalue', $this->config['b8']['database']['servers']['read']);
|
||||
$this->assertEquals('testedvalue', $this->config['b8']['database']['servers']['write']);
|
||||
}
|
||||
|
||||
public function testDatabaseNameConfig()
|
||||
{
|
||||
// We specified an input value for hostname.
|
||||
$this->dialog->expects($this->once())->method('ask')->willReturn('testedvalue');
|
||||
$this->dialog->expects($this->never())->method('askConfirmation');
|
||||
$this->dialog->expects($this->never())->method('askAndValidate');
|
||||
$this->dialog->expects($this->never())->method('askHiddenResponse');
|
||||
$this->dialog->expects($this->never())->method('askHiddenResponseAndValidate');
|
||||
|
||||
$this->executeWithoutParam('--db-name');
|
||||
|
||||
// Check that specified arguments are correctly loaded.
|
||||
$this->assertEquals('testedvalue', $this->config['b8']['database']['name']);
|
||||
}
|
||||
|
||||
public function testDatabaseUserameConfig()
|
||||
{
|
||||
// We specified an input value for hostname.
|
||||
$this->dialog->expects($this->once())->method('ask')->willReturn('testedvalue');
|
||||
$this->dialog->expects($this->never())->method('askConfirmation');
|
||||
$this->dialog->expects($this->never())->method('askAndValidate');
|
||||
$this->dialog->expects($this->never())->method('askHiddenResponse');
|
||||
$this->dialog->expects($this->never())->method('askHiddenResponseAndValidate');
|
||||
|
||||
$this->executeWithoutParam('--db-user');
|
||||
|
||||
// Check that specified arguments are correctly loaded.
|
||||
$this->assertEquals('testedvalue', $this->config['b8']['database']['username']);
|
||||
}
|
||||
|
||||
public function testDatabasePasswordConfig()
|
||||
{
|
||||
// We specified an input value for hostname.
|
||||
$this->dialog->expects($this->never())->method('ask');
|
||||
$this->dialog->expects($this->never())->method('askConfirmation');
|
||||
$this->dialog->expects($this->never())->method('askAndValidate');
|
||||
$this->dialog->expects($this->once())->method('askHiddenResponse')->willReturn('testedvalue');
|
||||
$this->dialog->expects($this->never())->method('askHiddenResponseAndValidate');
|
||||
|
||||
$this->executeWithoutParam('--db-pass');
|
||||
|
||||
// Check that specified arguments are correctly loaded.
|
||||
$this->assertEquals('testedvalue', $this->config['b8']['database']['password']);
|
||||
}
|
||||
|
||||
public function testPhpciUrlConfig()
|
||||
{
|
||||
// We specified an input value for hostname.
|
||||
$this->dialog->expects($this->never())->method('ask');
|
||||
$this->dialog->expects($this->never())->method('askConfirmation');
|
||||
$this->dialog->expects($this->once())->method('askAndValidate')->willReturn('http://testedvalue.com');
|
||||
$this->dialog->expects($this->never())->method('askHiddenResponse');
|
||||
$this->dialog->expects($this->never())->method('askHiddenResponseAndValidate');
|
||||
|
||||
$this->executeWithoutParam('--url');
|
||||
|
||||
// Check that specified arguments are correctly loaded.
|
||||
$this->assertEquals('http://testedvalue.com', $this->config['phpci']['url']);
|
||||
}
|
||||
|
||||
public function testAdminEmailConfig()
|
||||
{
|
||||
// We specified an input value for hostname.
|
||||
$this->dialog->expects($this->never())->method('ask');
|
||||
$this->dialog->expects($this->never())->method('askConfirmation');
|
||||
$this->dialog->expects($this->once())->method('askAndValidate')->willReturn('test@phpci.com');
|
||||
$this->dialog->expects($this->never())->method('askHiddenResponse');
|
||||
$this->dialog->expects($this->never())->method('askHiddenResponseAndValidate');
|
||||
|
||||
$this->executeWithoutParam('--admin-mail');
|
||||
|
||||
// Check that specified arguments are correctly loaded.
|
||||
$this->assertEquals('test@phpci.com', $this->admin['mail']);
|
||||
}
|
||||
|
||||
public function testAdminUserameConfig()
|
||||
{
|
||||
// Define expectation for dialog.
|
||||
$this->dialog->expects($this->once())->method('ask')->willReturn('testedvalue');
|
||||
$this->dialog->expects($this->never())->method('askConfirmation');
|
||||
$this->dialog->expects($this->never())->method('askAndValidate');
|
||||
$this->dialog->expects($this->never())->method('askHiddenResponse');
|
||||
$this->dialog->expects($this->never())->method('askHiddenResponseAndValidate');
|
||||
|
||||
$this->executeWithoutParam('--admin-name');
|
||||
|
||||
// Check that specified arguments are correctly loaded.
|
||||
$this->assertEquals('testedvalue', $this->admin['name']);
|
||||
}
|
||||
|
||||
public function testAdminPasswordConfig()
|
||||
{
|
||||
// We specified an input value for hostname.
|
||||
$this->dialog->expects($this->never())->method('ask');
|
||||
$this->dialog->expects($this->never())->method('askConfirmation');
|
||||
$this->dialog->expects($this->never())->method('askAndValidate');
|
||||
$this->dialog->expects($this->once())->method('askHiddenResponse')->willReturn('testedvalue');
|
||||
$this->dialog->expects($this->never())->method('askHiddenResponseAndValidate');
|
||||
|
||||
$this->executeWithoutParam('--admin-pass');
|
||||
|
||||
// Check that specified arguments are correctly loaded.
|
||||
$this->assertEquals('testedvalue', $this->admin['pass']);
|
||||
}
|
||||
}
|
201
Tests/PHPCI/Plugin/PharTest.php
Normal file
|
@ -0,0 +1,201 @@
|
|||
<?php
|
||||
namespace PHPCI\Plugin\Tests;
|
||||
|
||||
use PHPCI\Plugin\Phar as PharPlugin;
|
||||
use Phar as PHPPhar;
|
||||
use RuntimeException;
|
||||
|
||||
class PharTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $directory;
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
$this->cleanSource();
|
||||
}
|
||||
|
||||
protected function getPlugin(array $options = array())
|
||||
{
|
||||
$build = $this
|
||||
->getMockBuilder('PHPCI\Model\Build')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$phpci = $this
|
||||
->getMockBuilder('PHPCI\Builder')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
return new PharPlugin($phpci, $build, $options);
|
||||
}
|
||||
|
||||
protected function buildTemp()
|
||||
{
|
||||
$directory = tempnam(APPLICATION_PATH . '/Tests/temp', 'source');
|
||||
unlink($directory);
|
||||
return $directory;
|
||||
}
|
||||
|
||||
protected function buildSource()
|
||||
{
|
||||
$directory = $this->buildTemp();
|
||||
mkdir($directory);
|
||||
file_put_contents($directory . '/one.php', '<?php echo "one";');
|
||||
file_put_contents($directory . '/two.php', '<?php echo "two";');
|
||||
mkdir($directory . '/config');
|
||||
file_put_contents($directory . '/config/config.ini', '[config]');
|
||||
mkdir($directory . '/views');
|
||||
file_put_contents($directory . '/views/index.phtml', '<?php echo "hello";');
|
||||
$this->directory = $directory;
|
||||
return $directory;
|
||||
}
|
||||
|
||||
protected function cleanSource()
|
||||
{
|
||||
if ($this->directory) {
|
||||
$filenames = array(
|
||||
'/build.phar',
|
||||
'/stub.php',
|
||||
'/views/index.phtml',
|
||||
'/views',
|
||||
'/config/config.ini',
|
||||
'/config',
|
||||
'/two.php',
|
||||
'/one.php',
|
||||
);
|
||||
foreach ($filenames as $filename) {
|
||||
if (is_dir($this->directory . $filename)) {
|
||||
rmdir($this->directory . $filename);
|
||||
} else if (is_file($this->directory . $filename)) {
|
||||
unlink($this->directory . $filename);
|
||||
}
|
||||
}
|
||||
rmdir($this->directory);
|
||||
$this->directory = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected function checkReadonly()
|
||||
{
|
||||
if (ini_get('phar.readonly')) {
|
||||
$this->markTestSkipped();
|
||||
throw new RuntimeException('Readonly Phar');
|
||||
}
|
||||
}
|
||||
|
||||
public function testPlugin()
|
||||
{
|
||||
$plugin = $this->getPlugin();
|
||||
$this->assertInstanceOf('PHPCI\Plugin', $plugin);
|
||||
$this->assertInstanceOf('PHPCI\Model\Build', $plugin->getBuild());
|
||||
$this->assertInstanceOf('PHPCI\Builder', $plugin->getPHPCI());
|
||||
}
|
||||
|
||||
public function testDirectory()
|
||||
{
|
||||
$plugin = $this->getPlugin();
|
||||
$plugin->getPHPCI()->buildPath = 'foo';
|
||||
$this->assertEquals('foo', $plugin->getDirectory());
|
||||
|
||||
$plugin = $this->getPlugin(array('directory' => 'dirname'));
|
||||
$this->assertEquals('dirname', $plugin->getDirectory());
|
||||
}
|
||||
|
||||
public function testFilename()
|
||||
{
|
||||
$plugin = $this->getPlugin();
|
||||
$this->assertEquals('build.phar', $plugin->getFilename());
|
||||
|
||||
$plugin = $this->getPlugin(array('filename' => 'another.phar'));
|
||||
$this->assertEquals('another.phar', $plugin->getFilename());
|
||||
}
|
||||
|
||||
public function testRegExp()
|
||||
{
|
||||
$plugin = $this->getPlugin();
|
||||
$this->assertEquals('/\.php$/', $plugin->getRegExp());
|
||||
|
||||
$plugin = $this->getPlugin(array('regexp' => '/\.(php|phtml)$/'));
|
||||
$this->assertEquals('/\.(php|phtml)$/', $plugin->getRegExp());
|
||||
}
|
||||
|
||||
public function testStub()
|
||||
{
|
||||
$plugin = $this->getPlugin();
|
||||
$this->assertNull($plugin->getStub());
|
||||
|
||||
$plugin = $this->getPlugin(array('stub' => 'stub.php'));
|
||||
$this->assertEquals('stub.php', $plugin->getStub());
|
||||
}
|
||||
|
||||
public function testExecute()
|
||||
{
|
||||
$this->checkReadonly();
|
||||
|
||||
$plugin = $this->getPlugin();
|
||||
$path = $this->buildSource();
|
||||
$plugin->getPHPCI()->buildPath = $path;
|
||||
|
||||
$this->assertTrue($plugin->execute());
|
||||
|
||||
$this->assertFileExists($path . '/build.phar');
|
||||
PHPPhar::loadPhar($path . '/build.phar');
|
||||
$this->assertFileEquals($path . '/one.php', 'phar://build.phar/one.php');
|
||||
$this->assertFileEquals($path . '/two.php', 'phar://build.phar/two.php');
|
||||
$this->assertFileNotExists('phar://build.phar/config/config.ini');
|
||||
$this->assertFileNotExists('phar://build.phar/views/index.phtml');
|
||||
}
|
||||
|
||||
public function testExecuteRegExp()
|
||||
{
|
||||
$this->checkReadonly();
|
||||
|
||||
$plugin = $this->getPlugin(array('regexp' => '/\.(php|phtml)$/'));
|
||||
$path = $this->buildSource();
|
||||
$plugin->getPHPCI()->buildPath = $path;
|
||||
|
||||
$this->assertTrue($plugin->execute());
|
||||
|
||||
$this->assertFileExists($path . '/build.phar');
|
||||
PHPPhar::loadPhar($path . '/build.phar');
|
||||
$this->assertFileEquals($path . '/one.php', 'phar://build.phar/one.php');
|
||||
$this->assertFileEquals($path . '/two.php', 'phar://build.phar/two.php');
|
||||
$this->assertFileNotExists('phar://build.phar/config/config.ini');
|
||||
$this->assertFileEquals($path . '/views/index.phtml', 'phar://build.phar/views/index.phtml');
|
||||
}
|
||||
|
||||
public function testExecuteStub()
|
||||
{
|
||||
$this->checkReadonly();
|
||||
|
||||
$content = <<<STUB
|
||||
<?php
|
||||
Phar::mapPhar();
|
||||
__HALT_COMPILER(); ?>
|
||||
STUB;
|
||||
|
||||
$path = $this->buildSource();
|
||||
file_put_contents($path . '/stub.php', $content);
|
||||
|
||||
$plugin = $this->getPlugin(array('stub' => 'stub.php'));
|
||||
$plugin->getPHPCI()->buildPath = $path;
|
||||
|
||||
$this->assertTrue($plugin->execute());
|
||||
|
||||
$this->assertFileExists($path . '/build.phar');
|
||||
$phar = new PHPPhar($path . '/build.phar');
|
||||
$this->assertEquals($content, trim($phar->getStub())); // + trim because PHP adds newline char
|
||||
}
|
||||
|
||||
public function testExecuteUnknownDirectory()
|
||||
{
|
||||
$this->checkReadonly();
|
||||
|
||||
$directory = $this->buildTemp();
|
||||
|
||||
$plugin = $this->getPlugin(array('directory' => $directory));
|
||||
$plugin->getPHPCI()->buildPath = $this->buildSource();
|
||||
|
||||
$this->assertFalse($plugin->execute());
|
||||
}
|
||||
}
|
26
Tests/PHPCI/Plugin/Util/TapParserTest.php
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
namespace PHPCI\Plugin\Tests\Util;
|
||||
|
||||
use PHPCI\Plugin\Util\TapParser;
|
||||
|
||||
class TapParserTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testSkipped()
|
||||
{
|
||||
$content = <<<TAP
|
||||
TAP version 13
|
||||
ok 1 - SomeTest::testAnother
|
||||
ok 2 - # SKIP
|
||||
1..2
|
||||
TAP;
|
||||
$parser = new TapParser($content);
|
||||
$result = $parser->parse();
|
||||
|
||||
$this->assertEquals(array(
|
||||
array('pass' => true, 'suite' => 'SomeTest', 'test' => 'testAnother'),
|
||||
array('message' => 'SKIP'),
|
||||
), $result);
|
||||
|
||||
$this->assertEquals(0, $parser->getTotalFailures());
|
||||
}
|
||||
}
|
|
@ -10,23 +10,6 @@
|
|||
// Let PHP take a guess as to the default timezone, if the user hasn't set one:
|
||||
date_default_timezone_set(@date_default_timezone_get());
|
||||
|
||||
// Set up a basic autoloader for PHPCI:
|
||||
$autoload = function ($class) {
|
||||
$file = str_replace(array('\\', '_'), '/', $class);
|
||||
$file .= '.php';
|
||||
|
||||
if (substr($file, 0, 1) == '/') {
|
||||
$file = substr($file, 1);
|
||||
}
|
||||
|
||||
if (is_file(dirname(__DIR__) . '/' . $file)) {
|
||||
include(dirname(__DIR__) . '/' . $file);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
spl_autoload_register($autoload, true, true);
|
||||
|
||||
// Load Composer autoloader:
|
||||
require_once(dirname(__DIR__) . '/vendor/autoload.php');
|
||||
|
||||
|
|
2
Tests/temp/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
*
|
||||
!.gitignore
|
|
@ -16,23 +16,6 @@ if (empty($timezone)) {
|
|||
date_default_timezone_set('UTC');
|
||||
}
|
||||
|
||||
// Set up a basic autoloader for PHPCI:
|
||||
$autoload = function ($class) {
|
||||
$file = str_replace(array('\\', '_'), '/', $class);
|
||||
$file .= '.php';
|
||||
|
||||
if (substr($file, 0, 1) == '/') {
|
||||
$file = substr($file, 1);
|
||||
}
|
||||
|
||||
if (is_file(dirname(__FILE__) . '/' . $file)) {
|
||||
include(dirname(__FILE__) . '/' . $file);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
spl_autoload_register($autoload, true, true);
|
||||
|
||||
// If the PHPCI config file is not where we expect it, try looking in
|
||||
// env for an alternative config path.
|
||||
$configFile = dirname(__FILE__) . '/PHPCI/config.yml';
|
||||
|
@ -47,12 +30,18 @@ if (!file_exists($configFile)) {
|
|||
|
||||
// If we don't have a config file at all, fail at this point and tell the user to install:
|
||||
if (!file_exists($configFile) && (!defined('PHPCI_IS_CONSOLE') || !PHPCI_IS_CONSOLE)) {
|
||||
die('PHPCI has not yet been installed - Please use the command ./console phpci:install to install it.');
|
||||
$message = 'PHPCI has not yet been installed - Please use the command "./console phpci:install" ';
|
||||
$message .= '(or "php ./console phpci:install" for Windows) to install it.';
|
||||
|
||||
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) {
|
||||
file_put_contents('php://stderr', 'Please install PHPCI with "composer install" before using 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);
|
||||
}
|
||||
|
||||
|
|
|
@ -22,12 +22,18 @@
|
|||
"source": "https://github.com/Block8/PHPCI"
|
||||
},
|
||||
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"PHPCI\\": "PHPCI"
|
||||
}
|
||||
},
|
||||
|
||||
"require": {
|
||||
"php": ">=5.3.8",
|
||||
"ext-mcrypt": "*",
|
||||
"ext-pdo": "*",
|
||||
"ext-pdo_mysql": "*",
|
||||
"block8/b8framework": "~1.1",
|
||||
"block8/b8framework": "~1.0",
|
||||
"ircmaxell/password-compat": "~1.0",
|
||||
"swiftmailer/swiftmailer": "~5.0",
|
||||
"symfony/yaml": "~2.1",
|
||||
|
|
970
composer.lock
generated
|
@ -11,6 +11,9 @@
|
|||
bootstrap="./Tests/bootstrap.php"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite name="PHPCI Command Test Suite">
|
||||
<directory suffix="Test.php">./Tests/PHPCI/Command</directory>
|
||||
</testsuite>
|
||||
<testsuite name="PHPCI Helper Test Suite">
|
||||
<directory suffix="Test.php">./Tests/PHPCI/Helper</directory>
|
||||
</testsuite>
|
||||
|
|
7
public/.htaccess.dist
Normal file
|
@ -0,0 +1,7 @@
|
|||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine On
|
||||
RewriteBase /
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteRule . /index.php [L]
|
||||
</IfModule>
|
3539
public/assets/css/AdminLTE.css
Executable file
169
public/assets/css/bootstrap-slider/slider.css
Executable file
|
@ -0,0 +1,169 @@
|
|||
/*!
|
||||
* Slider for Bootstrap
|
||||
*
|
||||
* Copyright 2012 Stefan Petre
|
||||
* Licensed under the Apache License v2.0
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*/
|
||||
.slider {
|
||||
display: block;
|
||||
vertical-align: middle;
|
||||
position: relative;
|
||||
|
||||
}
|
||||
.slider.slider-horizontal {
|
||||
width: 100%;
|
||||
height: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.slider.slider-horizontal:last-of-type {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.slider.slider-horizontal .slider-track {
|
||||
height: 10px;
|
||||
width: 100%;
|
||||
margin-top: -5px;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
}
|
||||
.slider.slider-horizontal .slider-selection {
|
||||
height: 100%;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
.slider.slider-horizontal .slider-handle {
|
||||
margin-left: -10px;
|
||||
margin-top: -5px;
|
||||
}
|
||||
.slider.slider-horizontal .slider-handle.triangle {
|
||||
border-width: 0 10px 10px 10px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-bottom-color: #0480be;
|
||||
margin-top: 0;
|
||||
}
|
||||
.slider.slider-vertical {
|
||||
height: 230px;
|
||||
width: 20px;
|
||||
margin-right: 20px;
|
||||
display: inline-block;
|
||||
}
|
||||
.slider.slider-vertical:last-of-type {
|
||||
margin-right: 0;
|
||||
}
|
||||
.slider.slider-vertical .slider-track {
|
||||
width: 10px;
|
||||
height: 100%;
|
||||
margin-left: -5px;
|
||||
left: 50%;
|
||||
top: 0;
|
||||
}
|
||||
.slider.slider-vertical .slider-selection {
|
||||
width: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
.slider.slider-vertical .slider-handle {
|
||||
margin-left: -5px;
|
||||
margin-top: -10px;
|
||||
}
|
||||
.slider.slider-vertical .slider-handle.triangle {
|
||||
border-width: 10px 0 10px 10px;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
border-left-color: #0480be;
|
||||
margin-left: 0;
|
||||
}
|
||||
.slider input {
|
||||
display: none;
|
||||
}
|
||||
.slider .tooltip-inner {
|
||||
white-space: nowrap;
|
||||
}
|
||||
.slider-track {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
background-color: #f7f7f7;
|
||||
background-image: -moz-linear-gradient(top, #f0f0f0, #f9f9f9);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f0f0f0), to(#f9f9f9));
|
||||
background-image: -webkit-linear-gradient(top, #f0f0f0, #f9f9f9);
|
||||
background-image: -o-linear-gradient(top, #f0f0f0, #f9f9f9);
|
||||
background-image: linear-gradient(to bottom, #f0f0f0, #f9f9f9);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0f0f0', endColorstr='#fff9f9f9', GradientType=0);
|
||||
-webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
-moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.slider-selection {
|
||||
position: absolute;
|
||||
background-color: #f7f7f7;
|
||||
background-image: -moz-linear-gradient(top, #f9f9f9, #f5f5f5);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f9f9f9), to(#f5f5f5));
|
||||
background-image: -webkit-linear-gradient(top, #f9f9f9, #f5f5f5);
|
||||
background-image: -o-linear-gradient(top, #f9f9f9, #f5f5f5);
|
||||
background-image: linear-gradient(to bottom, #f9f9f9, #f5f5f5);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9f9f9', endColorstr='#fff5f5f5', GradientType=0);
|
||||
-webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
|
||||
-moz-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
|
||||
box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.slider-handle {
|
||||
position: absolute;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-color: #444;
|
||||
-webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);
|
||||
-moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);
|
||||
box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);
|
||||
opacity: 1;
|
||||
border: 0px solid transparent;
|
||||
}
|
||||
.slider-handle.round {
|
||||
-webkit-border-radius: 20px;
|
||||
-moz-border-radius: 20px;
|
||||
border-radius: 20px;
|
||||
}
|
||||
.slider-handle.triangle {
|
||||
background: transparent none;
|
||||
}
|
||||
|
||||
.slider-disabled .slider-selection {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
#red .slider-selection {
|
||||
background: #f56954;
|
||||
}
|
||||
|
||||
#blue .slider-selection {
|
||||
background: #3c8dbc;
|
||||
}
|
||||
|
||||
#green .slider-selection {
|
||||
background: #00a65a;
|
||||
}
|
||||
|
||||
#yellow .slider-selection {
|
||||
background: #f39c12;
|
||||
}
|
||||
|
||||
#aqua .slider-selection {
|
||||
background: #00c0ef;
|
||||
}
|
||||
|
||||
#purple .slider-selection {
|
||||
background: #932ab6;
|
||||
}
|
2
public/assets/css/bootstrap-theme.min.css
vendored
102
public/assets/css/bootstrap-wysihtml5/bootstrap3-wysihtml5.css
vendored
Executable file
|
@ -0,0 +1,102 @@
|
|||
ul.wysihtml5-toolbar {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
ul.wysihtml5-toolbar::after {
|
||||
clear: both;
|
||||
display: table;
|
||||
content: "";
|
||||
}
|
||||
|
||||
ul.wysihtml5-toolbar > li {
|
||||
float: left;
|
||||
display: list-item;
|
||||
list-style: none;
|
||||
margin: 0 5px 10px 0;
|
||||
}
|
||||
|
||||
ul.wysihtml5-toolbar a[data-wysihtml5-command=bold] {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
ul.wysihtml5-toolbar a[data-wysihtml5-command=italic] {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
ul.wysihtml5-toolbar a[data-wysihtml5-command=underline] {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
ul.wysihtml5-toolbar a.btn.wysihtml5-command-active {
|
||||
background-image: none;
|
||||
-webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);
|
||||
-moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);
|
||||
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);
|
||||
background-color: #E6E6E6;
|
||||
background-color: #D9D9D9;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
ul.wysihtml5-commands-disabled .dropdown-menu {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
ul.wysihtml5-toolbar div.wysihtml5-colors {
|
||||
display:block;
|
||||
width: 50px;
|
||||
height: 20px;
|
||||
margin-top: 2px;
|
||||
margin-left: 5px;
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
ul.wysihtml5-toolbar a.wysihtml5-colors-title {
|
||||
padding-left: 70px;
|
||||
}
|
||||
|
||||
ul.wysihtml5-toolbar div[data-wysihtml5-command-value="black"] {
|
||||
background: black !important;
|
||||
}
|
||||
|
||||
ul.wysihtml5-toolbar div[data-wysihtml5-command-value="silver"] {
|
||||
background: silver !important;
|
||||
}
|
||||
|
||||
ul.wysihtml5-toolbar div[data-wysihtml5-command-value="gray"] {
|
||||
background: gray !important;
|
||||
}
|
||||
|
||||
ul.wysihtml5-toolbar div[data-wysihtml5-command-value="maroon"] {
|
||||
background: maroon !important;
|
||||
}
|
||||
|
||||
ul.wysihtml5-toolbar div[data-wysihtml5-command-value="red"] {
|
||||
background: red !important;
|
||||
}
|
||||
|
||||
ul.wysihtml5-toolbar div[data-wysihtml5-command-value="purple"] {
|
||||
background: purple !important;
|
||||
}
|
||||
|
||||
ul.wysihtml5-toolbar div[data-wysihtml5-command-value="green"] {
|
||||
background: green !important;
|
||||
}
|
||||
|
||||
ul.wysihtml5-toolbar div[data-wysihtml5-command-value="olive"] {
|
||||
background: olive !important;
|
||||
}
|
||||
|
||||
ul.wysihtml5-toolbar div[data-wysihtml5-command-value="navy"] {
|
||||
background: navy !important;
|
||||
}
|
||||
|
||||
ul.wysihtml5-toolbar div[data-wysihtml5-command-value="blue"] {
|
||||
background: blue !important;
|
||||
}
|
||||
|
||||
ul.wysihtml5-toolbar div[data-wysihtml5-command-value="orange"] {
|
||||
background: orange !important;
|
||||
}
|
3
public/assets/css/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css
vendored
Executable file
|
@ -0,0 +1,3 @@
|
|||
/*! bootstrap3-wysihtml5-bower 2013-11-22 */
|
||||
|
||||
ul.wysihtml5-toolbar{margin:0;padding:0;display:block}ul.wysihtml5-toolbar::after{clear:both;display:table;content:""}ul.wysihtml5-toolbar>li{float:left;display:list-item;list-style:none;margin:0 5px 10px 0}ul.wysihtml5-toolbar a[data-wysihtml5-command=bold]{font-weight:700}ul.wysihtml5-toolbar a[data-wysihtml5-command=italic]{font-style:italic}ul.wysihtml5-toolbar a[data-wysihtml5-command=underline]{text-decoration:underline}ul.wysihtml5-toolbar a.btn.wysihtml5-command-active{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,.15),0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,.15),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 2px 4px rgba(0,0,0,.15),0 1px 2px rgba(0,0,0,.05);background-color:#E6E6E6;background-color:#D9D9D9;outline:0}ul.wysihtml5-commands-disabled .dropdown-menu{display:none!important}ul.wysihtml5-toolbar div.wysihtml5-colors{display:block;width:50px;height:20px;margin-top:2px;margin-left:5px;position:absolute;pointer-events:none}ul.wysihtml5-toolbar a.wysihtml5-colors-title{padding-left:70px}ul.wysihtml5-toolbar div[data-wysihtml5-command-value=black]{background:#000!important}ul.wysihtml5-toolbar div[data-wysihtml5-command-value=silver]{background:silver!important}ul.wysihtml5-toolbar div[data-wysihtml5-command-value=gray]{background:gray!important}ul.wysihtml5-toolbar div[data-wysihtml5-command-value=maroon]{background:maroon!important}ul.wysihtml5-toolbar div[data-wysihtml5-command-value=red]{background:red!important}ul.wysihtml5-toolbar div[data-wysihtml5-command-value=purple]{background:purple!important}ul.wysihtml5-toolbar div[data-wysihtml5-command-value=green]{background:green!important}ul.wysihtml5-toolbar div[data-wysihtml5-command-value=olive]{background:olive!important}ul.wysihtml5-toolbar div[data-wysihtml5-command-value=navy]{background:navy!important}ul.wysihtml5-toolbar div[data-wysihtml5-command-value=blue]{background:#00f!important}ul.wysihtml5-toolbar div[data-wysihtml5-command-value=orange]{background:orange!important}
|
2
public/assets/css/bootstrap.min.css
vendored
214
public/assets/css/colorpicker/bootstrap-colorpicker.css
vendored
Executable file
|
@ -0,0 +1,214 @@
|
|||
/*!
|
||||
* Bootstrap Colorpicker
|
||||
* http://mjolnic.github.io/bootstrap-colorpicker/
|
||||
*
|
||||
* Originally written by (c) 2012 Stefan Petre
|
||||
* Licensed under the Apache License v2.0
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
*
|
||||
*/
|
||||
|
||||
.colorpicker-saturation {
|
||||
float: left;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
cursor: crosshair;
|
||||
background-image: url("../../img/bootstrap-colorpicker/saturation.png");
|
||||
}
|
||||
|
||||
.colorpicker-saturation i {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: block;
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
margin: -4px 0 0 -4px;
|
||||
border: 1px solid #000;
|
||||
-webkit-border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.colorpicker-saturation i b {
|
||||
display: block;
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
border: 1px solid #fff;
|
||||
-webkit-border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.colorpicker-hue,
|
||||
.colorpicker-alpha {
|
||||
float: left;
|
||||
width: 15px;
|
||||
height: 100px;
|
||||
margin-bottom: 4px;
|
||||
margin-left: 4px;
|
||||
cursor: row-resize;
|
||||
}
|
||||
|
||||
.colorpicker-hue i,
|
||||
.colorpicker-alpha i {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
margin-top: -1px;
|
||||
background: #000;
|
||||
border-top: 1px solid #fff;
|
||||
}
|
||||
|
||||
.colorpicker-hue {
|
||||
background-image: url("../../img/bootstrap-colorpicker/hue.png");
|
||||
}
|
||||
|
||||
.colorpicker-alpha {
|
||||
display: none;
|
||||
background-image: url("../../img/bootstrap-colorpicker/alpha.png");
|
||||
}
|
||||
|
||||
.colorpicker {
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 2500;
|
||||
min-width: 130px;
|
||||
padding: 4px;
|
||||
margin-top: 1px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
*zoom: 1;
|
||||
}
|
||||
|
||||
.colorpicker:before,
|
||||
.colorpicker:after {
|
||||
display: table;
|
||||
line-height: 0;
|
||||
content: "";
|
||||
}
|
||||
|
||||
.colorpicker:after {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.colorpicker:before {
|
||||
position: absolute;
|
||||
top: -7px;
|
||||
left: 6px;
|
||||
display: inline-block;
|
||||
border-right: 7px solid transparent;
|
||||
border-bottom: 7px solid #ccc;
|
||||
border-left: 7px solid transparent;
|
||||
border-bottom-color: rgba(0, 0, 0, 0.2);
|
||||
content: '';
|
||||
}
|
||||
|
||||
.colorpicker:after {
|
||||
position: absolute;
|
||||
top: -6px;
|
||||
left: 7px;
|
||||
display: inline-block;
|
||||
border-right: 6px solid transparent;
|
||||
border-bottom: 6px solid #ffffff;
|
||||
border-left: 6px solid transparent;
|
||||
content: '';
|
||||
}
|
||||
|
||||
.colorpicker div {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.colorpicker.colorpicker-with-alpha {
|
||||
min-width: 140px;
|
||||
}
|
||||
|
||||
.colorpicker.colorpicker-with-alpha .colorpicker-alpha {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.colorpicker-color {
|
||||
height: 10px;
|
||||
margin-top: 5px;
|
||||
clear: both;
|
||||
background-image: url("../../img/bootstrap-colorpicker/alpha.png");
|
||||
background-position: 0 100%;
|
||||
}
|
||||
|
||||
.colorpicker-color div {
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
.colorpicker-element .input-group-addon i {
|
||||
display: block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.colorpicker.colorpicker-inline {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
float: none;
|
||||
}
|
||||
|
||||
.colorpicker.colorpicker-horizontal {
|
||||
width: 110px;
|
||||
height: auto;
|
||||
min-width: 110px;
|
||||
}
|
||||
|
||||
.colorpicker.colorpicker-horizontal .colorpicker-saturation {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.colorpicker.colorpicker-horizontal .colorpicker-color {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.colorpicker.colorpicker-horizontal .colorpicker-hue,
|
||||
.colorpicker.colorpicker-horizontal .colorpicker-alpha {
|
||||
float: left;
|
||||
width: 100px;
|
||||
height: 15px;
|
||||
margin-bottom: 4px;
|
||||
margin-left: 0;
|
||||
cursor: col-resize;
|
||||
}
|
||||
|
||||
.colorpicker.colorpicker-horizontal .colorpicker-hue i,
|
||||
.colorpicker.colorpicker-horizontal .colorpicker-alpha i {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: block;
|
||||
width: 1px;
|
||||
height: 15px;
|
||||
margin-top: 0;
|
||||
background: #ffffff;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.colorpicker.colorpicker-horizontal .colorpicker-hue {
|
||||
background-image: url("../../img/bootstrap-colorpicker/hue-horizontal.png");
|
||||
}
|
||||
|
||||
.colorpicker.colorpicker-horizontal .colorpicker-alpha {
|
||||
background-image: url("../../img/bootstrap-colorpicker/alpha-horizontal.png");
|
||||
}
|
||||
|
||||
.colorpicker.colorpicker-hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.colorpicker.colorpicker-visible {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.colorpicker-inline.colorpicker-visible {
|
||||
display: inline-block;
|
||||
}
|
9
public/assets/css/colorpicker/bootstrap-colorpicker.min.css
vendored
Executable file
|
@ -0,0 +1,9 @@
|
|||
/*!
|
||||
* Bootstrap Colorpicker
|
||||
* http://mjolnic.github.io/bootstrap-colorpicker/
|
||||
*
|
||||
* Originally written by (c) 2012 Stefan Petre
|
||||
* Licensed under the Apache License v2.0
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
*
|
||||
*/.colorpicker-saturation{float:left;width:100px;height:100px;cursor:crosshair;background-image:url("../../img/bootstrap-colorpicker/saturation.png")}.colorpicker-saturation i{position:absolute;top:0;left:0;display:block;width:5px;height:5px;margin:-4px 0 0 -4px;border:1px solid #000;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.colorpicker-saturation i b{display:block;width:5px;height:5px;border:1px solid #fff;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.colorpicker-hue,.colorpicker-alpha{float:left;width:15px;height:100px;margin-bottom:4px;margin-left:4px;cursor:row-resize}.colorpicker-hue i,.colorpicker-alpha i{position:absolute;top:0;left:0;display:block;width:100%;height:1px;margin-top:-1px;background:#000;border-top:1px solid #fff}.colorpicker-hue{background-image:url("../../img/bootstrap-colorpicker/hue.png")}.colorpicker-alpha{display:none;background-image:url("../../img/bootstrap-colorpicker/alpha.png")}.colorpicker{top:0;left:0;z-index:2500;min-width:130px;padding:4px;margin-top:1px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*zoom:1}.colorpicker:before,.colorpicker:after{display:table;line-height:0;content:""}.colorpicker:after{clear:both}.colorpicker:before{position:absolute;top:-7px;left:6px;display:inline-block;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-left:7px solid transparent;border-bottom-color:rgba(0,0,0,0.2);content:''}.colorpicker:after{position:absolute;top:-6px;left:7px;display:inline-block;border-right:6px solid transparent;border-bottom:6px solid #fff;border-left:6px solid transparent;content:''}.colorpicker div{position:relative}.colorpicker.colorpicker-with-alpha{min-width:140px}.colorpicker.colorpicker-with-alpha .colorpicker-alpha{display:block}.colorpicker-color{height:10px;margin-top:5px;clear:both;background-image:url("../../img/bootstrap-colorpicker/alpha.png");background-position:0 100%}.colorpicker-color div{height:10px}.colorpicker-element .input-group-addon i{display:block;width:16px;height:16px;cursor:pointer}.colorpicker.colorpicker-inline{position:relative;display:inline-block;float:none}.colorpicker.colorpicker-horizontal{width:110px;height:auto;min-width:110px}.colorpicker.colorpicker-horizontal .colorpicker-saturation{margin-bottom:4px}.colorpicker.colorpicker-horizontal .colorpicker-color{width:100px}.colorpicker.colorpicker-horizontal .colorpicker-hue,.colorpicker.colorpicker-horizontal .colorpicker-alpha{float:left;width:100px;height:15px;margin-bottom:4px;margin-left:0;cursor:col-resize}.colorpicker.colorpicker-horizontal .colorpicker-hue i,.colorpicker.colorpicker-horizontal .colorpicker-alpha i{position:absolute;top:0;left:0;display:block;width:1px;height:15px;margin-top:0;background:#fff;border:0}.colorpicker.colorpicker-horizontal .colorpicker-hue{background-image:url("../../img/bootstrap-colorpicker/hue-horizontal.png")}.colorpicker.colorpicker-horizontal .colorpicker-alpha{background-image:url("../../img/bootstrap-colorpicker/alpha-horizontal.png")}.colorpicker.colorpicker-hidden{display:none}.colorpicker.colorpicker-visible{display:block}.colorpicker-inline.colorpicker-visible{display:inline-block}
|
223
public/assets/css/datatables/dataTables.bootstrap.css
Executable file
|
@ -0,0 +1,223 @@
|
|||
div.dataTables_length label {
|
||||
font-weight: normal;
|
||||
float: left;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
div.dataTables_length select {
|
||||
width: 75px;
|
||||
}
|
||||
|
||||
div.dataTables_filter label {
|
||||
font-weight: normal;
|
||||
float: right;
|
||||
}
|
||||
|
||||
div.dataTables_filter input {
|
||||
width: 16em;
|
||||
}
|
||||
|
||||
div.dataTables_info {
|
||||
padding-top: 8px;
|
||||
}
|
||||
|
||||
div.dataTables_paginate {
|
||||
float: right;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div.dataTables_paginate ul.pagination {
|
||||
margin: 2px 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
table.dataTable,
|
||||
table.dataTable td,
|
||||
table.dataTable th {
|
||||
-webkit-box-sizing: content-box;
|
||||
-moz-box-sizing: content-box;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
|
||||
table.dataTable {
|
||||
clear: both;
|
||||
margin-top: 6px !important;
|
||||
margin-bottom: 6px !important;
|
||||
max-width: none !important;
|
||||
}
|
||||
|
||||
table.dataTable thead .sorting,
|
||||
table.dataTable thead .sorting_asc,
|
||||
table.dataTable thead .sorting_desc,
|
||||
table.dataTable thead .sorting_asc_disabled,
|
||||
table.dataTable thead .sorting_desc_disabled {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
table.dataTable thead .sorting { background: url('images/sort_both.png') no-repeat center right; }
|
||||
table.dataTable thead .sorting_asc { background: url('images/sort_asc.png') no-repeat center right; }
|
||||
table.dataTable thead .sorting_desc { background: url('images/sort_desc.png') no-repeat center right; }
|
||||
|
||||
table.dataTable thead .sorting_asc_disabled { background: url('images/sort_asc_disabled.png') no-repeat center right; }
|
||||
table.dataTable thead .sorting_desc_disabled { background: url('images/sort_desc_disabled.png') no-repeat center right; }
|
||||
|
||||
table.dataTable th:active {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/* Scrolling */
|
||||
div.dataTables_scrollHead table {
|
||||
margin-bottom: 0 !important;
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
div.dataTables_scrollHead table thead tr:last-child th:first-child,
|
||||
div.dataTables_scrollHead table thead tr:last-child td:first-child {
|
||||
border-bottom-left-radius: 0 !important;
|
||||
border-bottom-right-radius: 0 !important;
|
||||
}
|
||||
|
||||
div.dataTables_scrollBody table {
|
||||
border-top: none;
|
||||
margin-top: 0 !important;
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
div.dataTables_scrollBody tbody tr:first-child th,
|
||||
div.dataTables_scrollBody tbody tr:first-child td {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
div.dataTables_scrollFoot table {
|
||||
margin-top: 0 !important;
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* TableTools styles
|
||||
*/
|
||||
.table tbody tr.active td,
|
||||
.table tbody tr.active th {
|
||||
background-color: #08C;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.table tbody tr.active:hover td,
|
||||
.table tbody tr.active:hover th {
|
||||
background-color: #0075b0 !important;
|
||||
}
|
||||
|
||||
.table tbody tr.active a {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.table-striped tbody tr.active:nth-child(odd) td,
|
||||
.table-striped tbody tr.active:nth-child(odd) th {
|
||||
background-color: #017ebc;
|
||||
}
|
||||
|
||||
table.DTTT_selectable tbody tr {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
div.DTTT .btn {
|
||||
color: #333 !important;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
div.DTTT .btn:hover {
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
ul.DTTT_dropdown.dropdown-menu {
|
||||
z-index: 2003;
|
||||
}
|
||||
|
||||
ul.DTTT_dropdown.dropdown-menu a {
|
||||
color: #333 !important; /* needed only when demo_page.css is included */
|
||||
}
|
||||
|
||||
ul.DTTT_dropdown.dropdown-menu li {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
ul.DTTT_dropdown.dropdown-menu li:hover a {
|
||||
background-color: #0088cc;
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
div.DTTT_collection_background {
|
||||
z-index: 2002;
|
||||
}
|
||||
|
||||
/* TableTools information display */
|
||||
div.DTTT_print_info.modal {
|
||||
height: 150px;
|
||||
margin-top: -75px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
div.DTTT_print_info h6 {
|
||||
font-weight: normal;
|
||||
font-size: 28px;
|
||||
line-height: 28px;
|
||||
margin: 1em;
|
||||
}
|
||||
|
||||
div.DTTT_print_info p {
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* FixedColumns styles
|
||||
*/
|
||||
div.DTFC_LeftHeadWrapper table,
|
||||
div.DTFC_LeftFootWrapper table,
|
||||
div.DTFC_RightHeadWrapper table,
|
||||
div.DTFC_RightFootWrapper table,
|
||||
table.DTFC_Cloned tr.even {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
div.DTFC_RightHeadWrapper table ,
|
||||
div.DTFC_LeftHeadWrapper table {
|
||||
margin-bottom: 0 !important;
|
||||
border-top-right-radius: 0 !important;
|
||||
border-bottom-left-radius: 0 !important;
|
||||
border-bottom-right-radius: 0 !important;
|
||||
}
|
||||
|
||||
div.DTFC_RightHeadWrapper table thead tr:last-child th:first-child,
|
||||
div.DTFC_RightHeadWrapper table thead tr:last-child td:first-child,
|
||||
div.DTFC_LeftHeadWrapper table thead tr:last-child th:first-child,
|
||||
div.DTFC_LeftHeadWrapper table thead tr:last-child td:first-child {
|
||||
border-bottom-left-radius: 0 !important;
|
||||
border-bottom-right-radius: 0 !important;
|
||||
}
|
||||
|
||||
div.DTFC_RightBodyWrapper table,
|
||||
div.DTFC_LeftBodyWrapper table {
|
||||
border-top: none;
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
div.DTFC_RightBodyWrapper tbody tr:first-child th,
|
||||
div.DTFC_RightBodyWrapper tbody tr:first-child td,
|
||||
div.DTFC_LeftBodyWrapper tbody tr:first-child th,
|
||||
div.DTFC_LeftBodyWrapper tbody tr:first-child td {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
div.DTFC_RightFootWrapper table,
|
||||
div.DTFC_LeftFootWrapper table {
|
||||
border-top: none;
|
||||
}
|
||||
|
BIN
public/assets/css/datatables/images/sort_asc.png
Executable file
After Width: | Height: | Size: 1.1 KiB |
BIN
public/assets/css/datatables/images/sort_asc_disabled.png
Executable file
After Width: | Height: | Size: 1 KiB |
BIN
public/assets/css/datatables/images/sort_both.png
Executable file
After Width: | Height: | Size: 1.1 KiB |
BIN
public/assets/css/datatables/images/sort_desc.png
Executable file
After Width: | Height: | Size: 1.1 KiB |
BIN
public/assets/css/datatables/images/sort_desc_disabled.png
Executable file
After Width: | Height: | Size: 1 KiB |
790
public/assets/css/datepicker/datepicker3.css
Executable file
|
@ -0,0 +1,790 @@
|
|||
/*!
|
||||
* Datepicker for Bootstrap
|
||||
*
|
||||
* Copyright 2012 Stefan Petre
|
||||
* Improvements by Andrew Rowls
|
||||
* Licensed under the Apache License v2.0
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*/
|
||||
.datepicker {
|
||||
padding: 4px;
|
||||
border-radius: 4px;
|
||||
direction: ltr;
|
||||
/*.dow {
|
||||
border-top: 1px solid #ddd !important;
|
||||
}*/
|
||||
}
|
||||
.datepicker-inline {
|
||||
width: 100%;
|
||||
}
|
||||
.datepicker.datepicker-rtl {
|
||||
direction: rtl;
|
||||
}
|
||||
.datepicker.datepicker-rtl table tr td span {
|
||||
float: right;
|
||||
}
|
||||
.datepicker-dropdown {
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
.datepicker-dropdown:before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
border-left: 7px solid transparent;
|
||||
border-right: 7px solid transparent;
|
||||
border-bottom: 7px solid #ccc;
|
||||
border-top: 0;
|
||||
border-bottom-color: rgba(0, 0, 0, 0.2);
|
||||
position: absolute;
|
||||
}
|
||||
.datepicker-dropdown:after {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-bottom: 6px solid #fff;
|
||||
border-top: 0;
|
||||
position: absolute;
|
||||
}
|
||||
.datepicker-dropdown.datepicker-orient-left:before {
|
||||
left: 6px;
|
||||
}
|
||||
.datepicker-dropdown.datepicker-orient-left:after {
|
||||
left: 7px;
|
||||
}
|
||||
.datepicker-dropdown.datepicker-orient-right:before {
|
||||
right: 6px;
|
||||
}
|
||||
.datepicker-dropdown.datepicker-orient-right:after {
|
||||
right: 7px;
|
||||
}
|
||||
.datepicker-dropdown.datepicker-orient-top:before {
|
||||
top: -7px;
|
||||
}
|
||||
.datepicker-dropdown.datepicker-orient-top:after {
|
||||
top: -6px;
|
||||
}
|
||||
.datepicker-dropdown.datepicker-orient-bottom:before {
|
||||
bottom: -7px;
|
||||
border-bottom: 0;
|
||||
border-top: 7px solid #999;
|
||||
}
|
||||
.datepicker-dropdown.datepicker-orient-bottom:after {
|
||||
bottom: -6px;
|
||||
border-bottom: 0;
|
||||
border-top: 6px solid #fff;
|
||||
}
|
||||
.datepicker > div {
|
||||
display: none;
|
||||
}
|
||||
.datepicker.days div.datepicker-days {
|
||||
display: block;
|
||||
}
|
||||
.datepicker.months div.datepicker-months {
|
||||
display: block;
|
||||
}
|
||||
.datepicker.years div.datepicker-years {
|
||||
display: block;
|
||||
}
|
||||
.datepicker table {
|
||||
margin: 0;
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
.datepicker table tr td,
|
||||
.datepicker table tr th {
|
||||
text-align: center;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border-radius: 4px;
|
||||
border: none;
|
||||
}
|
||||
.table-striped .datepicker table tr td,
|
||||
.table-striped .datepicker table tr th {
|
||||
background-color: transparent;
|
||||
}
|
||||
.datepicker table tr td.day:hover,
|
||||
.datepicker table tr td.day.focused {
|
||||
background: rgba(0,0,0,0.2);
|
||||
cursor: pointer;
|
||||
}
|
||||
.datepicker table tr td.old,
|
||||
.datepicker table tr td.new {
|
||||
color: #777;
|
||||
}
|
||||
.datepicker table tr td.disabled,
|
||||
.datepicker table tr td.disabled:hover {
|
||||
background: none;
|
||||
color: #444;
|
||||
cursor: default;
|
||||
}
|
||||
.datepicker table tr td.today,
|
||||
.datepicker table tr td.today:hover,
|
||||
.datepicker table tr td.today.disabled,
|
||||
.datepicker table tr td.today.disabled:hover {
|
||||
color: #000000;
|
||||
background: rgba(0,0,0,0.2);
|
||||
border-color: #ffb733;
|
||||
}
|
||||
.datepicker table tr td.today:hover,
|
||||
.datepicker table tr td.today:hover:hover,
|
||||
.datepicker table tr td.today.disabled:hover,
|
||||
.datepicker table tr td.today.disabled:hover:hover,
|
||||
.datepicker table tr td.today:focus,
|
||||
.datepicker table tr td.today:hover:focus,
|
||||
.datepicker table tr td.today.disabled:focus,
|
||||
.datepicker table tr td.today.disabled:hover:focus,
|
||||
.datepicker table tr td.today:active,
|
||||
.datepicker table tr td.today:hover:active,
|
||||
.datepicker table tr td.today.disabled:active,
|
||||
.datepicker table tr td.today.disabled:hover:active,
|
||||
.datepicker table tr td.today.active,
|
||||
.datepicker table tr td.today:hover.active,
|
||||
.datepicker table tr td.today.disabled.active,
|
||||
.datepicker table tr td.today.disabled:hover.active,
|
||||
.open .dropdown-toggle.datepicker table tr td.today,
|
||||
.open .dropdown-toggle.datepicker table tr td.today:hover,
|
||||
.open .dropdown-toggle.datepicker table tr td.today.disabled,
|
||||
.open .dropdown-toggle.datepicker table tr td.today.disabled:hover {
|
||||
color: #000000;
|
||||
background: rgba(0,0,0,0.2);
|
||||
border-color: #f59e00;
|
||||
}
|
||||
.datepicker table tr td.today:active,
|
||||
.datepicker table tr td.today:hover:active,
|
||||
.datepicker table tr td.today.disabled:active,
|
||||
.datepicker table tr td.today.disabled:hover:active,
|
||||
.datepicker table tr td.today.active,
|
||||
.datepicker table tr td.today:hover.active,
|
||||
.datepicker table tr td.today.disabled.active,
|
||||
.datepicker table tr td.today.disabled:hover.active,
|
||||
.open .dropdown-toggle.datepicker table tr td.today,
|
||||
.open .dropdown-toggle.datepicker table tr td.today:hover,
|
||||
.open .dropdown-toggle.datepicker table tr td.today.disabled,
|
||||
.open .dropdown-toggle.datepicker table tr td.today.disabled:hover {
|
||||
background-image: none;
|
||||
}
|
||||
.datepicker table tr td.today.disabled,
|
||||
.datepicker table tr td.today:hover.disabled,
|
||||
.datepicker table tr td.today.disabled.disabled,
|
||||
.datepicker table tr td.today.disabled:hover.disabled,
|
||||
.datepicker table tr td.today[disabled],
|
||||
.datepicker table tr td.today:hover[disabled],
|
||||
.datepicker table tr td.today.disabled[disabled],
|
||||
.datepicker table tr td.today.disabled:hover[disabled],
|
||||
fieldset[disabled] .datepicker table tr td.today,
|
||||
fieldset[disabled] .datepicker table tr td.today:hover,
|
||||
fieldset[disabled] .datepicker table tr td.today.disabled,
|
||||
fieldset[disabled] .datepicker table tr td.today.disabled:hover,
|
||||
.datepicker table tr td.today.disabled:hover,
|
||||
.datepicker table tr td.today:hover.disabled:hover,
|
||||
.datepicker table tr td.today.disabled.disabled:hover,
|
||||
.datepicker table tr td.today.disabled:hover.disabled:hover,
|
||||
.datepicker table tr td.today[disabled]:hover,
|
||||
.datepicker table tr td.today:hover[disabled]:hover,
|
||||
.datepicker table tr td.today.disabled[disabled]:hover,
|
||||
.datepicker table tr td.today.disabled:hover[disabled]:hover,
|
||||
fieldset[disabled] .datepicker table tr td.today:hover,
|
||||
fieldset[disabled] .datepicker table tr td.today:hover:hover,
|
||||
fieldset[disabled] .datepicker table tr td.today.disabled:hover,
|
||||
fieldset[disabled] .datepicker table tr td.today.disabled:hover:hover,
|
||||
.datepicker table tr td.today.disabled:focus,
|
||||
.datepicker table tr td.today:hover.disabled:focus,
|
||||
.datepicker table tr td.today.disabled.disabled:focus,
|
||||
.datepicker table tr td.today.disabled:hover.disabled:focus,
|
||||
.datepicker table tr td.today[disabled]:focus,
|
||||
.datepicker table tr td.today:hover[disabled]:focus,
|
||||
.datepicker table tr td.today.disabled[disabled]:focus,
|
||||
.datepicker table tr td.today.disabled:hover[disabled]:focus,
|
||||
fieldset[disabled] .datepicker table tr td.today:focus,
|
||||
fieldset[disabled] .datepicker table tr td.today:hover:focus,
|
||||
fieldset[disabled] .datepicker table tr td.today.disabled:focus,
|
||||
fieldset[disabled] .datepicker table tr td.today.disabled:hover:focus,
|
||||
.datepicker table tr td.today.disabled:active,
|
||||
.datepicker table tr td.today:hover.disabled:active,
|
||||
.datepicker table tr td.today.disabled.disabled:active,
|
||||
.datepicker table tr td.today.disabled:hover.disabled:active,
|
||||
.datepicker table tr td.today[disabled]:active,
|
||||
.datepicker table tr td.today:hover[disabled]:active,
|
||||
.datepicker table tr td.today.disabled[disabled]:active,
|
||||
.datepicker table tr td.today.disabled:hover[disabled]:active,
|
||||
fieldset[disabled] .datepicker table tr td.today:active,
|
||||
fieldset[disabled] .datepicker table tr td.today:hover:active,
|
||||
fieldset[disabled] .datepicker table tr td.today.disabled:active,
|
||||
fieldset[disabled] .datepicker table tr td.today.disabled:hover:active,
|
||||
.datepicker table tr td.today.disabled.active,
|
||||
.datepicker table tr td.today:hover.disabled.active,
|
||||
.datepicker table tr td.today.disabled.disabled.active,
|
||||
.datepicker table tr td.today.disabled:hover.disabled.active,
|
||||
.datepicker table tr td.today[disabled].active,
|
||||
.datepicker table tr td.today:hover[disabled].active,
|
||||
.datepicker table tr td.today.disabled[disabled].active,
|
||||
.datepicker table tr td.today.disabled:hover[disabled].active,
|
||||
fieldset[disabled] .datepicker table tr td.today.active,
|
||||
fieldset[disabled] .datepicker table tr td.today:hover.active,
|
||||
fieldset[disabled] .datepicker table tr td.today.disabled.active,
|
||||
fieldset[disabled] .datepicker table tr td.today.disabled:hover.active {
|
||||
background: rgba(0,0,0,0.2);
|
||||
border-color: #ffb733;
|
||||
}
|
||||
.datepicker table tr td.today:hover:hover {
|
||||
color: #000;
|
||||
}
|
||||
.datepicker table tr td.today.active:hover {
|
||||
color: #fff;
|
||||
}
|
||||
.datepicker table tr td.range,
|
||||
.datepicker table tr td.range:hover,
|
||||
.datepicker table tr td.range.disabled,
|
||||
.datepicker table tr td.range.disabled:hover {
|
||||
background: rgba(0,0,0,0.2);
|
||||
border-radius: 0;
|
||||
}
|
||||
.datepicker table tr td.range.today,
|
||||
.datepicker table tr td.range.today:hover,
|
||||
.datepicker table tr td.range.today.disabled,
|
||||
.datepicker table tr td.range.today.disabled:hover {
|
||||
color: #000000;
|
||||
background: rgba(0,0,0,0.2);
|
||||
border-color: #f1a417;
|
||||
border-radius: 0;
|
||||
}
|
||||
.datepicker table tr td.range.today:hover,
|
||||
.datepicker table tr td.range.today:hover:hover,
|
||||
.datepicker table tr td.range.today.disabled:hover,
|
||||
.datepicker table tr td.range.today.disabled:hover:hover,
|
||||
.datepicker table tr td.range.today:focus,
|
||||
.datepicker table tr td.range.today:hover:focus,
|
||||
.datepicker table tr td.range.today.disabled:focus,
|
||||
.datepicker table tr td.range.today.disabled:hover:focus,
|
||||
.datepicker table tr td.range.today:active,
|
||||
.datepicker table tr td.range.today:hover:active,
|
||||
.datepicker table tr td.range.today.disabled:active,
|
||||
.datepicker table tr td.range.today.disabled:hover:active,
|
||||
.datepicker table tr td.range.today.active,
|
||||
.datepicker table tr td.range.today:hover.active,
|
||||
.datepicker table tr td.range.today.disabled.active,
|
||||
.datepicker table tr td.range.today.disabled:hover.active,
|
||||
.open .dropdown-toggle.datepicker table tr td.range.today,
|
||||
.open .dropdown-toggle.datepicker table tr td.range.today:hover,
|
||||
.open .dropdown-toggle.datepicker table tr td.range.today.disabled,
|
||||
.open .dropdown-toggle.datepicker table tr td.range.today.disabled:hover {
|
||||
color: #000000;
|
||||
background: rgba(0,0,0,0.2);
|
||||
border-color: #bf800c;
|
||||
}
|
||||
.datepicker table tr td.range.today:active,
|
||||
.datepicker table tr td.range.today:hover:active,
|
||||
.datepicker table tr td.range.today.disabled:active,
|
||||
.datepicker table tr td.range.today.disabled:hover:active,
|
||||
.datepicker table tr td.range.today.active,
|
||||
.datepicker table tr td.range.today:hover.active,
|
||||
.datepicker table tr td.range.today.disabled.active,
|
||||
.datepicker table tr td.range.today.disabled:hover.active,
|
||||
.open .dropdown-toggle.datepicker table tr td.range.today,
|
||||
.open .dropdown-toggle.datepicker table tr td.range.today:hover,
|
||||
.open .dropdown-toggle.datepicker table tr td.range.today.disabled,
|
||||
.open .dropdown-toggle.datepicker table tr td.range.today.disabled:hover {
|
||||
background-image: none;
|
||||
}
|
||||
.datepicker table tr td.range.today.disabled,
|
||||
.datepicker table tr td.range.today:hover.disabled,
|
||||
.datepicker table tr td.range.today.disabled.disabled,
|
||||
.datepicker table tr td.range.today.disabled:hover.disabled,
|
||||
.datepicker table tr td.range.today[disabled],
|
||||
.datepicker table tr td.range.today:hover[disabled],
|
||||
.datepicker table tr td.range.today.disabled[disabled],
|
||||
.datepicker table tr td.range.today.disabled:hover[disabled],
|
||||
fieldset[disabled] .datepicker table tr td.range.today,
|
||||
fieldset[disabled] .datepicker table tr td.range.today:hover,
|
||||
fieldset[disabled] .datepicker table tr td.range.today.disabled,
|
||||
fieldset[disabled] .datepicker table tr td.range.today.disabled:hover,
|
||||
.datepicker table tr td.range.today.disabled:hover,
|
||||
.datepicker table tr td.range.today:hover.disabled:hover,
|
||||
.datepicker table tr td.range.today.disabled.disabled:hover,
|
||||
.datepicker table tr td.range.today.disabled:hover.disabled:hover,
|
||||
.datepicker table tr td.range.today[disabled]:hover,
|
||||
.datepicker table tr td.range.today:hover[disabled]:hover,
|
||||
.datepicker table tr td.range.today.disabled[disabled]:hover,
|
||||
.datepicker table tr td.range.today.disabled:hover[disabled]:hover,
|
||||
fieldset[disabled] .datepicker table tr td.range.today:hover,
|
||||
fieldset[disabled] .datepicker table tr td.range.today:hover:hover,
|
||||
fieldset[disabled] .datepicker table tr td.range.today.disabled:hover,
|
||||
fieldset[disabled] .datepicker table tr td.range.today.disabled:hover:hover,
|
||||
.datepicker table tr td.range.today.disabled:focus,
|
||||
.datepicker table tr td.range.today:hover.disabled:focus,
|
||||
.datepicker table tr td.range.today.disabled.disabled:focus,
|
||||
.datepicker table tr td.range.today.disabled:hover.disabled:focus,
|
||||
.datepicker table tr td.range.today[disabled]:focus,
|
||||
.datepicker table tr td.range.today:hover[disabled]:focus,
|
||||
.datepicker table tr td.range.today.disabled[disabled]:focus,
|
||||
.datepicker table tr td.range.today.disabled:hover[disabled]:focus,
|
||||
fieldset[disabled] .datepicker table tr td.range.today:focus,
|
||||
fieldset[disabled] .datepicker table tr td.range.today:hover:focus,
|
||||
fieldset[disabled] .datepicker table tr td.range.today.disabled:focus,
|
||||
fieldset[disabled] .datepicker table tr td.range.today.disabled:hover:focus,
|
||||
.datepicker table tr td.range.today.disabled:active,
|
||||
.datepicker table tr td.range.today:hover.disabled:active,
|
||||
.datepicker table tr td.range.today.disabled.disabled:active,
|
||||
.datepicker table tr td.range.today.disabled:hover.disabled:active,
|
||||
.datepicker table tr td.range.today[disabled]:active,
|
||||
.datepicker table tr td.range.today:hover[disabled]:active,
|
||||
.datepicker table tr td.range.today.disabled[disabled]:active,
|
||||
.datepicker table tr td.range.today.disabled:hover[disabled]:active,
|
||||
fieldset[disabled] .datepicker table tr td.range.today:active,
|
||||
fieldset[disabled] .datepicker table tr td.range.today:hover:active,
|
||||
fieldset[disabled] .datepicker table tr td.range.today.disabled:active,
|
||||
fieldset[disabled] .datepicker table tr td.range.today.disabled:hover:active,
|
||||
.datepicker table tr td.range.today.disabled.active,
|
||||
.datepicker table tr td.range.today:hover.disabled.active,
|
||||
.datepicker table tr td.range.today.disabled.disabled.active,
|
||||
.datepicker table tr td.range.today.disabled:hover.disabled.active,
|
||||
.datepicker table tr td.range.today[disabled].active,
|
||||
.datepicker table tr td.range.today:hover[disabled].active,
|
||||
.datepicker table tr td.range.today.disabled[disabled].active,
|
||||
.datepicker table tr td.range.today.disabled:hover[disabled].active,
|
||||
fieldset[disabled] .datepicker table tr td.range.today.active,
|
||||
fieldset[disabled] .datepicker table tr td.range.today:hover.active,
|
||||
fieldset[disabled] .datepicker table tr td.range.today.disabled.active,
|
||||
fieldset[disabled] .datepicker table tr td.range.today.disabled:hover.active {
|
||||
background: rgba(0,0,0,0.2);
|
||||
border-color: #f1a417;
|
||||
}
|
||||
.datepicker table tr td.selected,
|
||||
.datepicker table tr td.selected:hover,
|
||||
.datepicker table tr td.selected.disabled,
|
||||
.datepicker table tr td.selected.disabled:hover {
|
||||
color: #ffffff;
|
||||
background: rgba(0,0,0,0.2);
|
||||
border-color: #555555;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
.datepicker table tr td.selected:hover,
|
||||
.datepicker table tr td.selected:hover:hover,
|
||||
.datepicker table tr td.selected.disabled:hover,
|
||||
.datepicker table tr td.selected.disabled:hover:hover,
|
||||
.datepicker table tr td.selected:focus,
|
||||
.datepicker table tr td.selected:hover:focus,
|
||||
.datepicker table tr td.selected.disabled:focus,
|
||||
.datepicker table tr td.selected.disabled:hover:focus,
|
||||
.datepicker table tr td.selected:active,
|
||||
.datepicker table tr td.selected:hover:active,
|
||||
.datepicker table tr td.selected.disabled:active,
|
||||
.datepicker table tr td.selected.disabled:hover:active,
|
||||
.datepicker table tr td.selected.active,
|
||||
.datepicker table tr td.selected:hover.active,
|
||||
.datepicker table tr td.selected.disabled.active,
|
||||
.datepicker table tr td.selected.disabled:hover.active,
|
||||
.open .dropdown-toggle.datepicker table tr td.selected,
|
||||
.open .dropdown-toggle.datepicker table tr td.selected:hover,
|
||||
.open .dropdown-toggle.datepicker table tr td.selected.disabled,
|
||||
.open .dropdown-toggle.datepicker table tr td.selected.disabled:hover {
|
||||
color: #ffffff;
|
||||
background: rgba(0,0,0,0.2);
|
||||
border-color: #373737;
|
||||
}
|
||||
.datepicker table tr td.selected:active,
|
||||
.datepicker table tr td.selected:hover:active,
|
||||
.datepicker table tr td.selected.disabled:active,
|
||||
.datepicker table tr td.selected.disabled:hover:active,
|
||||
.datepicker table tr td.selected.active,
|
||||
.datepicker table tr td.selected:hover.active,
|
||||
.datepicker table tr td.selected.disabled.active,
|
||||
.datepicker table tr td.selected.disabled:hover.active,
|
||||
.open .dropdown-toggle.datepicker table tr td.selected,
|
||||
.open .dropdown-toggle.datepicker table tr td.selected:hover,
|
||||
.open .dropdown-toggle.datepicker table tr td.selected.disabled,
|
||||
.open .dropdown-toggle.datepicker table tr td.selected.disabled:hover {
|
||||
background-image: none;
|
||||
}
|
||||
.datepicker table tr td.selected.disabled,
|
||||
.datepicker table tr td.selected:hover.disabled,
|
||||
.datepicker table tr td.selected.disabled.disabled,
|
||||
.datepicker table tr td.selected.disabled:hover.disabled,
|
||||
.datepicker table tr td.selected[disabled],
|
||||
.datepicker table tr td.selected:hover[disabled],
|
||||
.datepicker table tr td.selected.disabled[disabled],
|
||||
.datepicker table tr td.selected.disabled:hover[disabled],
|
||||
fieldset[disabled] .datepicker table tr td.selected,
|
||||
fieldset[disabled] .datepicker table tr td.selected:hover,
|
||||
fieldset[disabled] .datepicker table tr td.selected.disabled,
|
||||
fieldset[disabled] .datepicker table tr td.selected.disabled:hover,
|
||||
.datepicker table tr td.selected.disabled:hover,
|
||||
.datepicker table tr td.selected:hover.disabled:hover,
|
||||
.datepicker table tr td.selected.disabled.disabled:hover,
|
||||
.datepicker table tr td.selected.disabled:hover.disabled:hover,
|
||||
.datepicker table tr td.selected[disabled]:hover,
|
||||
.datepicker table tr td.selected:hover[disabled]:hover,
|
||||
.datepicker table tr td.selected.disabled[disabled]:hover,
|
||||
.datepicker table tr td.selected.disabled:hover[disabled]:hover,
|
||||
fieldset[disabled] .datepicker table tr td.selected:hover,
|
||||
fieldset[disabled] .datepicker table tr td.selected:hover:hover,
|
||||
fieldset[disabled] .datepicker table tr td.selected.disabled:hover,
|
||||
fieldset[disabled] .datepicker table tr td.selected.disabled:hover:hover,
|
||||
.datepicker table tr td.selected.disabled:focus,
|
||||
.datepicker table tr td.selected:hover.disabled:focus,
|
||||
.datepicker table tr td.selected.disabled.disabled:focus,
|
||||
.datepicker table tr td.selected.disabled:hover.disabled:focus,
|
||||
.datepicker table tr td.selected[disabled]:focus,
|
||||
.datepicker table tr td.selected:hover[disabled]:focus,
|
||||
.datepicker table tr td.selected.disabled[disabled]:focus,
|
||||
.datepicker table tr td.selected.disabled:hover[disabled]:focus,
|
||||
fieldset[disabled] .datepicker table tr td.selected:focus,
|
||||
fieldset[disabled] .datepicker table tr td.selected:hover:focus,
|
||||
fieldset[disabled] .datepicker table tr td.selected.disabled:focus,
|
||||
fieldset[disabled] .datepicker table tr td.selected.disabled:hover:focus,
|
||||
.datepicker table tr td.selected.disabled:active,
|
||||
.datepicker table tr td.selected:hover.disabled:active,
|
||||
.datepicker table tr td.selected.disabled.disabled:active,
|
||||
.datepicker table tr td.selected.disabled:hover.disabled:active,
|
||||
.datepicker table tr td.selected[disabled]:active,
|
||||
.datepicker table tr td.selected:hover[disabled]:active,
|
||||
.datepicker table tr td.selected.disabled[disabled]:active,
|
||||
.datepicker table tr td.selected.disabled:hover[disabled]:active,
|
||||
fieldset[disabled] .datepicker table tr td.selected:active,
|
||||
fieldset[disabled] .datepicker table tr td.selected:hover:active,
|
||||
fieldset[disabled] .datepicker table tr td.selected.disabled:active,
|
||||
fieldset[disabled] .datepicker table tr td.selected.disabled:hover:active,
|
||||
.datepicker table tr td.selected.disabled.active,
|
||||
.datepicker table tr td.selected:hover.disabled.active,
|
||||
.datepicker table tr td.selected.disabled.disabled.active,
|
||||
.datepicker table tr td.selected.disabled:hover.disabled.active,
|
||||
.datepicker table tr td.selected[disabled].active,
|
||||
.datepicker table tr td.selected:hover[disabled].active,
|
||||
.datepicker table tr td.selected.disabled[disabled].active,
|
||||
.datepicker table tr td.selected.disabled:hover[disabled].active,
|
||||
fieldset[disabled] .datepicker table tr td.selected.active,
|
||||
fieldset[disabled] .datepicker table tr td.selected:hover.active,
|
||||
fieldset[disabled] .datepicker table tr td.selected.disabled.active,
|
||||
fieldset[disabled] .datepicker table tr td.selected.disabled:hover.active {
|
||||
background: rgba(0,0,0,0.2);
|
||||
border-color: #555555;
|
||||
}
|
||||
.datepicker table tr td.active,
|
||||
.datepicker table tr td.active:hover,
|
||||
.datepicker table tr td.active.disabled,
|
||||
.datepicker table tr td.active.disabled:hover {
|
||||
color: #ffffff;
|
||||
background: rgba(0,0,0,0.2);
|
||||
border-color: #357ebd;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
.datepicker table tr td.active:hover,
|
||||
.datepicker table tr td.active:hover:hover,
|
||||
.datepicker table tr td.active.disabled:hover,
|
||||
.datepicker table tr td.active.disabled:hover:hover,
|
||||
.datepicker table tr td.active:focus,
|
||||
.datepicker table tr td.active:hover:focus,
|
||||
.datepicker table tr td.active.disabled:focus,
|
||||
.datepicker table tr td.active.disabled:hover:focus,
|
||||
.datepicker table tr td.active:active,
|
||||
.datepicker table tr td.active:hover:active,
|
||||
.datepicker table tr td.active.disabled:active,
|
||||
.datepicker table tr td.active.disabled:hover:active,
|
||||
.datepicker table tr td.active.active,
|
||||
.datepicker table tr td.active:hover.active,
|
||||
.datepicker table tr td.active.disabled.active,
|
||||
.datepicker table tr td.active.disabled:hover.active,
|
||||
.open .dropdown-toggle.datepicker table tr td.active,
|
||||
.open .dropdown-toggle.datepicker table tr td.active:hover,
|
||||
.open .dropdown-toggle.datepicker table tr td.active.disabled,
|
||||
.open .dropdown-toggle.datepicker table tr td.active.disabled:hover {
|
||||
color: #ffffff;
|
||||
background: rgba(0,0,0,0.5);
|
||||
border-color: #285e8e;
|
||||
}
|
||||
.datepicker table tr td.active:active,
|
||||
.datepicker table tr td.active:hover:active,
|
||||
.datepicker table tr td.active.disabled:active,
|
||||
.datepicker table tr td.active.disabled:hover:active,
|
||||
.datepicker table tr td.active.active,
|
||||
.datepicker table tr td.active:hover.active,
|
||||
.datepicker table tr td.active.disabled.active,
|
||||
.datepicker table tr td.active.disabled:hover.active,
|
||||
.open .dropdown-toggle.datepicker table tr td.active,
|
||||
.open .dropdown-toggle.datepicker table tr td.active:hover,
|
||||
.open .dropdown-toggle.datepicker table tr td.active.disabled,
|
||||
.open .dropdown-toggle.datepicker table tr td.active.disabled:hover {
|
||||
background-image: none;
|
||||
}
|
||||
.datepicker table tr td.active.disabled,
|
||||
.datepicker table tr td.active:hover.disabled,
|
||||
.datepicker table tr td.active.disabled.disabled,
|
||||
.datepicker table tr td.active.disabled:hover.disabled,
|
||||
.datepicker table tr td.active[disabled],
|
||||
.datepicker table tr td.active:hover[disabled],
|
||||
.datepicker table tr td.active.disabled[disabled],
|
||||
.datepicker table tr td.active.disabled:hover[disabled],
|
||||
fieldset[disabled] .datepicker table tr td.active,
|
||||
fieldset[disabled] .datepicker table tr td.active:hover,
|
||||
fieldset[disabled] .datepicker table tr td.active.disabled,
|
||||
fieldset[disabled] .datepicker table tr td.active.disabled:hover,
|
||||
.datepicker table tr td.active.disabled:hover,
|
||||
.datepicker table tr td.active:hover.disabled:hover,
|
||||
.datepicker table tr td.active.disabled.disabled:hover,
|
||||
.datepicker table tr td.active.disabled:hover.disabled:hover,
|
||||
.datepicker table tr td.active[disabled]:hover,
|
||||
.datepicker table tr td.active:hover[disabled]:hover,
|
||||
.datepicker table tr td.active.disabled[disabled]:hover,
|
||||
.datepicker table tr td.active.disabled:hover[disabled]:hover,
|
||||
fieldset[disabled] .datepicker table tr td.active:hover,
|
||||
fieldset[disabled] .datepicker table tr td.active:hover:hover,
|
||||
fieldset[disabled] .datepicker table tr td.active.disabled:hover,
|
||||
fieldset[disabled] .datepicker table tr td.active.disabled:hover:hover,
|
||||
.datepicker table tr td.active.disabled:focus,
|
||||
.datepicker table tr td.active:hover.disabled:focus,
|
||||
.datepicker table tr td.active.disabled.disabled:focus,
|
||||
.datepicker table tr td.active.disabled:hover.disabled:focus,
|
||||
.datepicker table tr td.active[disabled]:focus,
|
||||
.datepicker table tr td.active:hover[disabled]:focus,
|
||||
.datepicker table tr td.active.disabled[disabled]:focus,
|
||||
.datepicker table tr td.active.disabled:hover[disabled]:focus,
|
||||
fieldset[disabled] .datepicker table tr td.active:focus,
|
||||
fieldset[disabled] .datepicker table tr td.active:hover:focus,
|
||||
fieldset[disabled] .datepicker table tr td.active.disabled:focus,
|
||||
fieldset[disabled] .datepicker table tr td.active.disabled:hover:focus,
|
||||
.datepicker table tr td.active.disabled:active,
|
||||
.datepicker table tr td.active:hover.disabled:active,
|
||||
.datepicker table tr td.active.disabled.disabled:active,
|
||||
.datepicker table tr td.active.disabled:hover.disabled:active,
|
||||
.datepicker table tr td.active[disabled]:active,
|
||||
.datepicker table tr td.active:hover[disabled]:active,
|
||||
.datepicker table tr td.active.disabled[disabled]:active,
|
||||
.datepicker table tr td.active.disabled:hover[disabled]:active,
|
||||
fieldset[disabled] .datepicker table tr td.active:active,
|
||||
fieldset[disabled] .datepicker table tr td.active:hover:active,
|
||||
fieldset[disabled] .datepicker table tr td.active.disabled:active,
|
||||
fieldset[disabled] .datepicker table tr td.active.disabled:hover:active,
|
||||
.datepicker table tr td.active.disabled.active,
|
||||
.datepicker table tr td.active:hover.disabled.active,
|
||||
.datepicker table tr td.active.disabled.disabled.active,
|
||||
.datepicker table tr td.active.disabled:hover.disabled.active,
|
||||
.datepicker table tr td.active[disabled].active,
|
||||
.datepicker table tr td.active:hover[disabled].active,
|
||||
.datepicker table tr td.active.disabled[disabled].active,
|
||||
.datepicker table tr td.active.disabled:hover[disabled].active,
|
||||
fieldset[disabled] .datepicker table tr td.active.active,
|
||||
fieldset[disabled] .datepicker table tr td.active:hover.active,
|
||||
fieldset[disabled] .datepicker table tr td.active.disabled.active,
|
||||
fieldset[disabled] .datepicker table tr td.active.disabled:hover.active {
|
||||
background-color: #428bca;
|
||||
border-color: #357ebd;
|
||||
}
|
||||
.datepicker table tr td span {
|
||||
display: block;
|
||||
width: 23%;
|
||||
height: 54px;
|
||||
line-height: 54px;
|
||||
float: left;
|
||||
margin: 1%;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.datepicker table tr td span:hover {
|
||||
background: rgba(0,0,0,0.2);
|
||||
}
|
||||
.datepicker table tr td span.disabled,
|
||||
.datepicker table tr td span.disabled:hover {
|
||||
background: none;
|
||||
color: #444;
|
||||
cursor: default;
|
||||
}
|
||||
.datepicker table tr td span.active,
|
||||
.datepicker table tr td span.active:hover,
|
||||
.datepicker table tr td span.active.disabled,
|
||||
.datepicker table tr td span.active.disabled:hover {
|
||||
color: #ffffff;
|
||||
background-color: #428bca;
|
||||
border-color: #357ebd;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
.datepicker table tr td span.active:hover,
|
||||
.datepicker table tr td span.active:hover:hover,
|
||||
.datepicker table tr td span.active.disabled:hover,
|
||||
.datepicker table tr td span.active.disabled:hover:hover,
|
||||
.datepicker table tr td span.active:focus,
|
||||
.datepicker table tr td span.active:hover:focus,
|
||||
.datepicker table tr td span.active.disabled:focus,
|
||||
.datepicker table tr td span.active.disabled:hover:focus,
|
||||
.datepicker table tr td span.active:active,
|
||||
.datepicker table tr td span.active:hover:active,
|
||||
.datepicker table tr td span.active.disabled:active,
|
||||
.datepicker table tr td span.active.disabled:hover:active,
|
||||
.datepicker table tr td span.active.active,
|
||||
.datepicker table tr td span.active:hover.active,
|
||||
.datepicker table tr td span.active.disabled.active,
|
||||
.datepicker table tr td span.active.disabled:hover.active,
|
||||
.open .dropdown-toggle.datepicker table tr td span.active,
|
||||
.open .dropdown-toggle.datepicker table tr td span.active:hover,
|
||||
.open .dropdown-toggle.datepicker table tr td span.active.disabled,
|
||||
.open .dropdown-toggle.datepicker table tr td span.active.disabled:hover {
|
||||
color: #ffffff;
|
||||
background-color: #3276b1;
|
||||
border-color: #285e8e;
|
||||
}
|
||||
.datepicker table tr td span.active:active,
|
||||
.datepicker table tr td span.active:hover:active,
|
||||
.datepicker table tr td span.active.disabled:active,
|
||||
.datepicker table tr td span.active.disabled:hover:active,
|
||||
.datepicker table tr td span.active.active,
|
||||
.datepicker table tr td span.active:hover.active,
|
||||
.datepicker table tr td span.active.disabled.active,
|
||||
.datepicker table tr td span.active.disabled:hover.active,
|
||||
.open .dropdown-toggle.datepicker table tr td span.active,
|
||||
.open .dropdown-toggle.datepicker table tr td span.active:hover,
|
||||
.open .dropdown-toggle.datepicker table tr td span.active.disabled,
|
||||
.open .dropdown-toggle.datepicker table tr td span.active.disabled:hover {
|
||||
background-image: none;
|
||||
}
|
||||
.datepicker table tr td span.active.disabled,
|
||||
.datepicker table tr td span.active:hover.disabled,
|
||||
.datepicker table tr td span.active.disabled.disabled,
|
||||
.datepicker table tr td span.active.disabled:hover.disabled,
|
||||
.datepicker table tr td span.active[disabled],
|
||||
.datepicker table tr td span.active:hover[disabled],
|
||||
.datepicker table tr td span.active.disabled[disabled],
|
||||
.datepicker table tr td span.active.disabled:hover[disabled],
|
||||
fieldset[disabled] .datepicker table tr td span.active,
|
||||
fieldset[disabled] .datepicker table tr td span.active:hover,
|
||||
fieldset[disabled] .datepicker table tr td span.active.disabled,
|
||||
fieldset[disabled] .datepicker table tr td span.active.disabled:hover,
|
||||
.datepicker table tr td span.active.disabled:hover,
|
||||
.datepicker table tr td span.active:hover.disabled:hover,
|
||||
.datepicker table tr td span.active.disabled.disabled:hover,
|
||||
.datepicker table tr td span.active.disabled:hover.disabled:hover,
|
||||
.datepicker table tr td span.active[disabled]:hover,
|
||||
.datepicker table tr td span.active:hover[disabled]:hover,
|
||||
.datepicker table tr td span.active.disabled[disabled]:hover,
|
||||
.datepicker table tr td span.active.disabled:hover[disabled]:hover,
|
||||
fieldset[disabled] .datepicker table tr td span.active:hover,
|
||||
fieldset[disabled] .datepicker table tr td span.active:hover:hover,
|
||||
fieldset[disabled] .datepicker table tr td span.active.disabled:hover,
|
||||
fieldset[disabled] .datepicker table tr td span.active.disabled:hover:hover,
|
||||
.datepicker table tr td span.active.disabled:focus,
|
||||
.datepicker table tr td span.active:hover.disabled:focus,
|
||||
.datepicker table tr td span.active.disabled.disabled:focus,
|
||||
.datepicker table tr td span.active.disabled:hover.disabled:focus,
|
||||
.datepicker table tr td span.active[disabled]:focus,
|
||||
.datepicker table tr td span.active:hover[disabled]:focus,
|
||||
.datepicker table tr td span.active.disabled[disabled]:focus,
|
||||
.datepicker table tr td span.active.disabled:hover[disabled]:focus,
|
||||
fieldset[disabled] .datepicker table tr td span.active:focus,
|
||||
fieldset[disabled] .datepicker table tr td span.active:hover:focus,
|
||||
fieldset[disabled] .datepicker table tr td span.active.disabled:focus,
|
||||
fieldset[disabled] .datepicker table tr td span.active.disabled:hover:focus,
|
||||
.datepicker table tr td span.active.disabled:active,
|
||||
.datepicker table tr td span.active:hover.disabled:active,
|
||||
.datepicker table tr td span.active.disabled.disabled:active,
|
||||
.datepicker table tr td span.active.disabled:hover.disabled:active,
|
||||
.datepicker table tr td span.active[disabled]:active,
|
||||
.datepicker table tr td span.active:hover[disabled]:active,
|
||||
.datepicker table tr td span.active.disabled[disabled]:active,
|
||||
.datepicker table tr td span.active.disabled:hover[disabled]:active,
|
||||
fieldset[disabled] .datepicker table tr td span.active:active,
|
||||
fieldset[disabled] .datepicker table tr td span.active:hover:active,
|
||||
fieldset[disabled] .datepicker table tr td span.active.disabled:active,
|
||||
fieldset[disabled] .datepicker table tr td span.active.disabled:hover:active,
|
||||
.datepicker table tr td span.active.disabled.active,
|
||||
.datepicker table tr td span.active:hover.disabled.active,
|
||||
.datepicker table tr td span.active.disabled.disabled.active,
|
||||
.datepicker table tr td span.active.disabled:hover.disabled.active,
|
||||
.datepicker table tr td span.active[disabled].active,
|
||||
.datepicker table tr td span.active:hover[disabled].active,
|
||||
.datepicker table tr td span.active.disabled[disabled].active,
|
||||
.datepicker table tr td span.active.disabled:hover[disabled].active,
|
||||
fieldset[disabled] .datepicker table tr td span.active.active,
|
||||
fieldset[disabled] .datepicker table tr td span.active:hover.active,
|
||||
fieldset[disabled] .datepicker table tr td span.active.disabled.active,
|
||||
fieldset[disabled] .datepicker table tr td span.active.disabled:hover.active {
|
||||
background-color: #428bca;
|
||||
border-color: #357ebd;
|
||||
}
|
||||
.datepicker table tr td span.old,
|
||||
.datepicker table tr td span.new {
|
||||
color: #444;
|
||||
}
|
||||
.datepicker th.datepicker-switch {
|
||||
width: 145px;
|
||||
}
|
||||
.datepicker thead tr:first-child th,
|
||||
.datepicker tfoot tr th {
|
||||
cursor: pointer;
|
||||
}
|
||||
.datepicker thead tr:first-child th:hover,
|
||||
.datepicker tfoot tr th:hover {
|
||||
background: rgba(0,0,0,0.2);
|
||||
}
|
||||
.datepicker .cw {
|
||||
font-size: 10px;
|
||||
width: 12px;
|
||||
padding: 0 2px 0 5px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.datepicker thead tr:first-child th.cw {
|
||||
cursor: default;
|
||||
background-color: transparent;
|
||||
}
|
||||
.input-group.date .input-group-addon i {
|
||||
cursor: pointer;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
.input-daterange input {
|
||||
text-align: center;
|
||||
}
|
||||
.input-daterange input:first-child {
|
||||
border-radius: 3px 0 0 3px;
|
||||
}
|
||||
.input-daterange input:last-child {
|
||||
border-radius: 0 3px 3px 0;
|
||||
}
|
||||
.input-daterange .input-group-addon {
|
||||
width: auto;
|
||||
min-width: 16px;
|
||||
padding: 4px 5px;
|
||||
font-weight: normal;
|
||||
line-height: 1.428571429;
|
||||
text-align: center;
|
||||
text-shadow: 0 1px 0 #fff;
|
||||
vertical-align: middle;
|
||||
background-color: #eeeeee;
|
||||
border: solid #cccccc;
|
||||
border-width: 1px 0;
|
||||
margin-left: -5px;
|
||||
margin-right: -5px;
|
||||
}
|
||||
.datepicker.dropdown-menu {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
z-index: 1000;
|
||||
float: left;
|
||||
display: none;
|
||||
min-width: 160px;
|
||||
list-style: none;
|
||||
background-color: #ffffff;
|
||||
border: 1px solid #ccc;
|
||||
border: 1px solid rgba(0, 0, 0, 0.2);
|
||||
border-radius: 5px;
|
||||
-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
|
||||
-moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
|
||||
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
|
||||
-webkit-background-clip: padding-box;
|
||||
-moz-background-clip: padding;
|
||||
background-clip: padding-box;
|
||||
*border-right-width: 2px;
|
||||
*border-bottom-width: 2px;
|
||||
color: #333333;
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
font-size: 13px;
|
||||
line-height: 1.428571429;
|
||||
}
|
||||
.datepicker.dropdown-menu th,
|
||||
.datepicker.dropdown-menu td {
|
||||
padding: 4px 5px;
|
||||
}
|
245
public/assets/css/daterangepicker/daterangepicker-bs3.css
Executable file
|
@ -0,0 +1,245 @@
|
|||
/*!
|
||||
* Stylesheet for the Date Range Picker, for use with Bootstrap 3.x
|
||||
*
|
||||
* Copyright 2013 Dan Grossman ( http://www.dangrossman.info )
|
||||
* Licensed under the Apache License v2.0
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Built for http://www.improvely.com
|
||||
*/
|
||||
|
||||
.daterangepicker.dropdown-menu {
|
||||
max-width: none;
|
||||
z-index: 3000;
|
||||
}
|
||||
|
||||
.daterangepicker.opensleft .ranges, .daterangepicker.opensleft .calendar {
|
||||
float: left;
|
||||
margin: 4px;
|
||||
}
|
||||
|
||||
.daterangepicker.opensright .ranges, .daterangepicker.opensright .calendar {
|
||||
float: right;
|
||||
margin: 4px;
|
||||
}
|
||||
|
||||
.daterangepicker .ranges {
|
||||
width: 160px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.daterangepicker .ranges .range_inputs>div {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.daterangepicker .ranges .range_inputs>div:nth-child(2) {
|
||||
padding-left: 11px;
|
||||
}
|
||||
|
||||
.daterangepicker .calendar {
|
||||
display: none;
|
||||
max-width: 270px;
|
||||
}
|
||||
|
||||
.daterangepicker .calendar th, .daterangepicker .calendar td {
|
||||
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
white-space: nowrap;
|
||||
text-align: center;
|
||||
min-width: 32px;
|
||||
}
|
||||
|
||||
.daterangepicker .ranges label {
|
||||
color: #333;
|
||||
display: block;
|
||||
font-size: 11px;
|
||||
font-weight: normal;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
margin-bottom: 2px;
|
||||
text-shadow: #fff 1px 1px 0px;
|
||||
text-transform: uppercase;
|
||||
width: 74px;
|
||||
}
|
||||
|
||||
.daterangepicker .ranges input {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.daterangepicker .ranges .input-mini {
|
||||
background-color: #eee;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
color: #555;
|
||||
display: block;
|
||||
font-size: 11px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
vertical-align: middle;
|
||||
margin: 0 0 10px 0;
|
||||
padding: 0 6px;
|
||||
width: 74px;
|
||||
}
|
||||
|
||||
.daterangepicker .ranges ul {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.daterangepicker .ranges li {
|
||||
font-size: 13px;
|
||||
background: #f5f5f5;
|
||||
border: 1px solid #f5f5f5;
|
||||
color: #08c;
|
||||
padding: 3px 12px;
|
||||
margin-bottom: 8px;
|
||||
-webkit-border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.daterangepicker .ranges li.active, .daterangepicker .ranges li:hover {
|
||||
background: #08c;
|
||||
border: 1px solid #08c;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.daterangepicker .calendar-date {
|
||||
border: 1px solid #ddd;
|
||||
padding: 4px;
|
||||
border-radius: 4px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.daterangepicker .calendar-time {
|
||||
text-align: center;
|
||||
margin: 8px auto 0 auto;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.daterangepicker {
|
||||
position: absolute;
|
||||
background: #fff;
|
||||
top: 100px;
|
||||
left: 20px;
|
||||
padding: 4px;
|
||||
margin-top: 1px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.daterangepicker.opensleft:before {
|
||||
position: absolute;
|
||||
top: -7px;
|
||||
right: 9px;
|
||||
display: inline-block;
|
||||
border-right: 7px solid transparent;
|
||||
border-bottom: 7px solid #ccc;
|
||||
border-left: 7px solid transparent;
|
||||
border-bottom-color: rgba(0, 0, 0, 0.2);
|
||||
content: '';
|
||||
}
|
||||
|
||||
.daterangepicker.opensleft:after {
|
||||
position: absolute;
|
||||
top: -6px;
|
||||
right: 10px;
|
||||
display: inline-block;
|
||||
border-right: 6px solid transparent;
|
||||
border-bottom: 6px solid #fff;
|
||||
border-left: 6px solid transparent;
|
||||
content: '';
|
||||
}
|
||||
|
||||
.daterangepicker.opensright:before {
|
||||
position: absolute;
|
||||
top: -7px;
|
||||
left: 9px;
|
||||
display: inline-block;
|
||||
border-right: 7px solid transparent;
|
||||
border-bottom: 7px solid #ccc;
|
||||
border-left: 7px solid transparent;
|
||||
border-bottom-color: rgba(0, 0, 0, 0.2);
|
||||
content: '';
|
||||
}
|
||||
|
||||
.daterangepicker.opensright:after {
|
||||
position: absolute;
|
||||
top: -6px;
|
||||
left: 10px;
|
||||
display: inline-block;
|
||||
border-right: 6px solid transparent;
|
||||
border-bottom: 6px solid #fff;
|
||||
border-left: 6px solid transparent;
|
||||
content: '';
|
||||
}
|
||||
|
||||
.daterangepicker table {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.daterangepicker td, .daterangepicker th {
|
||||
text-align: center;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.daterangepicker td.off {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.daterangepicker td.disabled {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.daterangepicker td.available:hover, .daterangepicker th.available:hover {
|
||||
background: #eee;
|
||||
}
|
||||
|
||||
.daterangepicker td.in-range {
|
||||
background: #ebf4f8;
|
||||
-webkit-border-radius: 0;
|
||||
-moz-border-radius: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.daterangepicker td.active, .daterangepicker td.active:hover {
|
||||
background-color: #357ebd;
|
||||
border-color: #3071a9;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.daterangepicker td.week, .daterangepicker th.week {
|
||||
font-size: 80%;
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.daterangepicker select.monthselect, .daterangepicker select.yearselect {
|
||||
font-size: 12px;
|
||||
padding: 1px;
|
||||
height: auto;
|
||||
margin: 0;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.daterangepicker select.monthselect {
|
||||
margin-right: 2%;
|
||||
width: 56%;
|
||||
}
|
||||
|
||||
.daterangepicker select.yearselect {
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
.daterangepicker select.hourselect, .daterangepicker select.minuteselect, .daterangepicker select.ampmselect {
|
||||
width: 50px;
|
||||
margin-bottom: 0;
|
||||
}
|
61
public/assets/css/iCheck/all.css
Executable file
|
@ -0,0 +1,61 @@
|
|||
/* iCheck plugin skins
|
||||
----------------------------------- */
|
||||
@import url("minimal/_all.css");
|
||||
/*
|
||||
@import url("minimal/minimal.css");
|
||||
@import url("minimal/red.css");
|
||||
@import url("minimal/green.css");
|
||||
@import url("minimal/blue.css");
|
||||
@import url("minimal/aero.css");
|
||||
@import url("minimal/grey.css");
|
||||
@import url("minimal/orange.css");
|
||||
@import url("minimal/yellow.css");
|
||||
@import url("minimal/pink.css");
|
||||
@import url("minimal/purple.css");
|
||||
*/
|
||||
|
||||
@import url("square/_all.css");
|
||||
/*
|
||||
@import url("square/square.css");
|
||||
@import url("square/red.css");
|
||||
@import url("square/green.css");
|
||||
@import url("square/blue.css");
|
||||
@import url("square/aero.css");
|
||||
@import url("square/grey.css");
|
||||
@import url("square/orange.css");
|
||||
@import url("square/yellow.css");
|
||||
@import url("square/pink.css");
|
||||
@import url("square/purple.css");
|
||||
*/
|
||||
|
||||
@import url("flat/_all.css");
|
||||
/*
|
||||
@import url("flat/flat.css");
|
||||
@import url("flat/red.css");
|
||||
@import url("flat/green.css");
|
||||
@import url("flat/blue.css");
|
||||
@import url("flat/aero.css");
|
||||
@import url("flat/grey.css");
|
||||
@import url("flat/orange.css");
|
||||
@import url("flat/yellow.css");
|
||||
@import url("flat/pink.css");
|
||||
@import url("flat/purple.css");
|
||||
*/
|
||||
|
||||
@import url("line/_all.css");
|
||||
/*
|
||||
@import url("line/line.css");
|
||||
@import url("line/red.css");
|
||||
@import url("line/green.css");
|
||||
@import url("line/blue.css");
|
||||
@import url("line/aero.css");
|
||||
@import url("line/grey.css");
|
||||
@import url("line/orange.css");
|
||||
@import url("line/yellow.css");
|
||||
@import url("line/pink.css");
|
||||
@import url("line/purple.css");
|
||||
*/
|
||||
|
||||
@import url("polaris/polaris.css");
|
||||
|
||||
@import url("futurico/futurico.css");
|
560
public/assets/css/iCheck/flat/_all.css
Executable file
|
@ -0,0 +1,560 @@
|
|||
/* iCheck plugin Flat skin
|
||||
----------------------------------- */
|
||||
.icheckbox_flat,
|
||||
.iradio_flat {
|
||||
display: inline-block;
|
||||
*display: inline;
|
||||
vertical-align: middle;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: url(flat.png) no-repeat;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.icheckbox_flat {
|
||||
background-position: 0 0;
|
||||
}
|
||||
.icheckbox_flat.checked {
|
||||
background-position: -22px 0;
|
||||
}
|
||||
.icheckbox_flat.disabled {
|
||||
background-position: -44px 0;
|
||||
cursor: default;
|
||||
}
|
||||
.icheckbox_flat.checked.disabled {
|
||||
background-position: -66px 0;
|
||||
}
|
||||
|
||||
.iradio_flat {
|
||||
background-position: -88px 0;
|
||||
}
|
||||
.iradio_flat.checked {
|
||||
background-position: -110px 0;
|
||||
}
|
||||
.iradio_flat.disabled {
|
||||
background-position: -132px 0;
|
||||
cursor: default;
|
||||
}
|
||||
.iradio_flat.checked.disabled {
|
||||
background-position: -154px 0;
|
||||
}
|
||||
|
||||
/* Retina support */
|
||||
@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
|
||||
only screen and (-moz-min-device-pixel-ratio: 1.5),
|
||||
only screen and (-o-min-device-pixel-ratio: 3/2),
|
||||
only screen and (min-device-pixel-ratio: 1.5) {
|
||||
.icheckbox_flat,
|
||||
.iradio_flat {
|
||||
background-image: url(flat@2x.png);
|
||||
-webkit-background-size: 176px 22px;
|
||||
background-size: 176px 22px;
|
||||
}
|
||||
}
|
||||
|
||||
/* red */
|
||||
.icheckbox_flat-red,
|
||||
.iradio_flat-red {
|
||||
display: inline-block;
|
||||
*display: inline;
|
||||
vertical-align: middle;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: url(red.png) no-repeat;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.icheckbox_flat-red {
|
||||
background-position: 0 0;
|
||||
}
|
||||
.icheckbox_flat-red.checked {
|
||||
background-position: -22px 0;
|
||||
}
|
||||
.icheckbox_flat-red.disabled {
|
||||
background-position: -44px 0;
|
||||
cursor: default;
|
||||
}
|
||||
.icheckbox_flat-red.checked.disabled {
|
||||
background-position: -66px 0;
|
||||
}
|
||||
|
||||
.iradio_flat-red {
|
||||
background-position: -88px 0;
|
||||
}
|
||||
.iradio_flat-red.checked {
|
||||
background-position: -110px 0;
|
||||
}
|
||||
.iradio_flat-red.disabled {
|
||||
background-position: -132px 0;
|
||||
cursor: default;
|
||||
}
|
||||
.iradio_flat-red.checked.disabled {
|
||||
background-position: -154px 0;
|
||||
}
|
||||
|
||||
/* Retina support */
|
||||
@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
|
||||
only screen and (-moz-min-device-pixel-ratio: 1.5),
|
||||
only screen and (-o-min-device-pixel-ratio: 3/2),
|
||||
only screen and (min-device-pixel-ratio: 1.5) {
|
||||
.icheckbox_flat-red,
|
||||
.iradio_flat-red {
|
||||
background-image: url(red@2x.png);
|
||||
-webkit-background-size: 176px 22px;
|
||||
background-size: 176px 22px;
|
||||
}
|
||||
}
|
||||
|
||||
/* green */
|
||||
.icheckbox_flat-green,
|
||||
.iradio_flat-green {
|
||||
display: inline-block;
|
||||
*display: inline;
|
||||
vertical-align: middle;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: url(green.png) no-repeat;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.icheckbox_flat-green {
|
||||
background-position: 0 0;
|
||||
}
|
||||
.icheckbox_flat-green.checked {
|
||||
background-position: -22px 0;
|
||||
}
|
||||
.icheckbox_flat-green.disabled {
|
||||
background-position: -44px 0;
|
||||
cursor: default;
|
||||
}
|
||||
.icheckbox_flat-green.checked.disabled {
|
||||
background-position: -66px 0;
|
||||
}
|
||||
|
||||
.iradio_flat-green {
|
||||
background-position: -88px 0;
|
||||
}
|
||||
.iradio_flat-green.checked {
|
||||
background-position: -110px 0;
|
||||
}
|
||||
.iradio_flat-green.disabled {
|
||||
background-position: -132px 0;
|
||||
cursor: default;
|
||||
}
|
||||
.iradio_flat-green.checked.disabled {
|
||||
background-position: -154px 0;
|
||||
}
|
||||
|
||||
/* Retina support */
|
||||
@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
|
||||
only screen and (-moz-min-device-pixel-ratio: 1.5),
|
||||
only screen and (-o-min-device-pixel-ratio: 3/2),
|
||||
only screen and (min-device-pixel-ratio: 1.5) {
|
||||
.icheckbox_flat-green,
|
||||
.iradio_flat-green {
|
||||
background-image: url(green@2x.png);
|
||||
-webkit-background-size: 176px 22px;
|
||||
background-size: 176px 22px;
|
||||
}
|
||||
}
|
||||
|
||||
/* blue */
|
||||
.icheckbox_flat-blue,
|
||||
.iradio_flat-blue {
|
||||
display: inline-block;
|
||||
*display: inline;
|
||||
vertical-align: middle;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: url(blue.png) no-repeat;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.icheckbox_flat-blue {
|
||||
background-position: 0 0;
|
||||
}
|
||||
.icheckbox_flat-blue.checked {
|
||||
background-position: -22px 0;
|
||||
}
|
||||
.icheckbox_flat-blue.disabled {
|
||||
background-position: -44px 0;
|
||||
cursor: default;
|
||||
}
|
||||
.icheckbox_flat-blue.checked.disabled {
|
||||
background-position: -66px 0;
|
||||
}
|
||||
|
||||
.iradio_flat-blue {
|
||||
background-position: -88px 0;
|
||||
}
|
||||
.iradio_flat-blue.checked {
|
||||
background-position: -110px 0;
|
||||
}
|
||||
.iradio_flat-blue.disabled {
|
||||
background-position: -132px 0;
|
||||
cursor: default;
|
||||
}
|
||||
.iradio_flat-blue.checked.disabled {
|
||||
background-position: -154px 0;
|
||||
}
|
||||
|
||||
/* Retina support */
|
||||
@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
|
||||
only screen and (-moz-min-device-pixel-ratio: 1.5),
|
||||
only screen and (-o-min-device-pixel-ratio: 3/2),
|
||||
only screen and (min-device-pixel-ratio: 1.5) {
|
||||
.icheckbox_flat-blue,
|
||||
.iradio_flat-blue {
|
||||
background-image: url(blue@2x.png);
|
||||
-webkit-background-size: 176px 22px;
|
||||
background-size: 176px 22px;
|
||||
}
|
||||
}
|
||||
|
||||
/* aero */
|
||||
.icheckbox_flat-aero,
|
||||
.iradio_flat-aero {
|
||||
display: inline-block;
|
||||
*display: inline;
|
||||
vertical-align: middle;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: url(aero.png) no-repeat;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.icheckbox_flat-aero {
|
||||
background-position: 0 0;
|
||||
}
|
||||
.icheckbox_flat-aero.checked {
|
||||
background-position: -22px 0;
|
||||
}
|
||||
.icheckbox_flat-aero.disabled {
|
||||
background-position: -44px 0;
|
||||
cursor: default;
|
||||
}
|
||||
.icheckbox_flat-aero.checked.disabled {
|
||||
background-position: -66px 0;
|
||||
}
|
||||
|
||||
.iradio_flat-aero {
|
||||
background-position: -88px 0;
|
||||
}
|
||||
.iradio_flat-aero.checked {
|
||||
background-position: -110px 0;
|
||||
}
|
||||
.iradio_flat-aero.disabled {
|
||||
background-position: -132px 0;
|
||||
cursor: default;
|
||||
}
|
||||
.iradio_flat-aero.checked.disabled {
|
||||
background-position: -154px 0;
|
||||
}
|
||||
|
||||
/* Retina support */
|
||||
@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
|
||||
only screen and (-moz-min-device-pixel-ratio: 1.5),
|
||||
only screen and (-o-min-device-pixel-ratio: 3/2),
|
||||
only screen and (min-device-pixel-ratio: 1.5) {
|
||||
.icheckbox_flat-aero,
|
||||
.iradio_flat-aero {
|
||||
background-image: url(aero@2x.png);
|
||||
-webkit-background-size: 176px 22px;
|
||||
background-size: 176px 22px;
|
||||
}
|
||||
}
|
||||
|
||||
/* grey */
|
||||
.icheckbox_flat-grey,
|
||||
.iradio_flat-grey {
|
||||
display: inline-block;
|
||||
*display: inline;
|
||||
vertical-align: middle;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: url(grey.png) no-repeat;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.icheckbox_flat-grey {
|
||||
background-position: 0 0;
|
||||
}
|
||||
.icheckbox_flat-grey.checked {
|
||||
background-position: -22px 0;
|
||||
}
|
||||
.icheckbox_flat-grey.disabled {
|
||||
background-position: -44px 0;
|
||||
cursor: default;
|
||||
}
|
||||
.icheckbox_flat-grey.checked.disabled {
|
||||
background-position: -66px 0;
|
||||
}
|
||||
|
||||
.iradio_flat-grey {
|
||||
background-position: -88px 0;
|
||||
}
|
||||
.iradio_flat-grey.checked {
|
||||
background-position: -110px 0;
|
||||
}
|
||||
.iradio_flat-grey.disabled {
|
||||
background-position: -132px 0;
|
||||
cursor: default;
|
||||
}
|
||||
.iradio_flat-grey.checked.disabled {
|
||||
background-position: -154px 0;
|
||||
}
|
||||
|
||||
/* Retina support */
|
||||
@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
|
||||
only screen and (-moz-min-device-pixel-ratio: 1.5),
|
||||
only screen and (-o-min-device-pixel-ratio: 3/2),
|
||||
only screen and (min-device-pixel-ratio: 1.5) {
|
||||
.icheckbox_flat-grey,
|
||||
.iradio_flat-grey {
|
||||
background-image: url(grey@2x.png);
|
||||
-webkit-background-size: 176px 22px;
|
||||
background-size: 176px 22px;
|
||||
}
|
||||
}
|
||||
|
||||
/* orange */
|
||||
.icheckbox_flat-orange,
|
||||
.iradio_flat-orange {
|
||||
display: inline-block;
|
||||
*display: inline;
|
||||
vertical-align: middle;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: url(orange.png) no-repeat;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.icheckbox_flat-orange {
|
||||
background-position: 0 0;
|
||||
}
|
||||
.icheckbox_flat-orange.checked {
|
||||
background-position: -22px 0;
|
||||
}
|
||||
.icheckbox_flat-orange.disabled {
|
||||
background-position: -44px 0;
|
||||
cursor: default;
|
||||
}
|
||||
.icheckbox_flat-orange.checked.disabled {
|
||||
background-position: -66px 0;
|
||||
}
|
||||
|
||||
.iradio_flat-orange {
|
||||
background-position: -88px 0;
|
||||
}
|
||||
.iradio_flat-orange.checked {
|
||||
background-position: -110px 0;
|
||||
}
|
||||
.iradio_flat-orange.disabled {
|
||||
background-position: -132px 0;
|
||||
cursor: default;
|
||||
}
|
||||
.iradio_flat-orange.checked.disabled {
|
||||
background-position: -154px 0;
|
||||
}
|
||||
|
||||
/* Retina support */
|
||||
@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
|
||||
only screen and (-moz-min-device-pixel-ratio: 1.5),
|
||||
only screen and (-o-min-device-pixel-ratio: 3/2),
|
||||
only screen and (min-device-pixel-ratio: 1.5) {
|
||||
.icheckbox_flat-orange,
|
||||
.iradio_flat-orange {
|
||||
background-image: url(orange@2x.png);
|
||||
-webkit-background-size: 176px 22px;
|
||||
background-size: 176px 22px;
|
||||
}
|
||||
}
|
||||
|
||||
/* yellow */
|
||||
.icheckbox_flat-yellow,
|
||||
.iradio_flat-yellow {
|
||||
display: inline-block;
|
||||
*display: inline;
|
||||
vertical-align: middle;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: url(yellow.png) no-repeat;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.icheckbox_flat-yellow {
|
||||
background-position: 0 0;
|
||||
}
|
||||
.icheckbox_flat-yellow.checked {
|
||||
background-position: -22px 0;
|
||||
}
|
||||
.icheckbox_flat-yellow.disabled {
|
||||
background-position: -44px 0;
|
||||
cursor: default;
|
||||
}
|
||||
.icheckbox_flat-yellow.checked.disabled {
|
||||
background-position: -66px 0;
|
||||
}
|
||||
|
||||
.iradio_flat-yellow {
|
||||
background-position: -88px 0;
|
||||
}
|
||||
.iradio_flat-yellow.checked {
|
||||
background-position: -110px 0;
|
||||
}
|
||||
.iradio_flat-yellow.disabled {
|
||||
background-position: -132px 0;
|
||||
cursor: default;
|
||||
}
|
||||
.iradio_flat-yellow.checked.disabled {
|
||||
background-position: -154px 0;
|
||||
}
|
||||
|
||||
/* Retina support */
|
||||
@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
|
||||
only screen and (-moz-min-device-pixel-ratio: 1.5),
|
||||
only screen and (-o-min-device-pixel-ratio: 3/2),
|
||||
only screen and (min-device-pixel-ratio: 1.5) {
|
||||
.icheckbox_flat-yellow,
|
||||
.iradio_flat-yellow {
|
||||
background-image: url(yellow@2x.png);
|
||||
-webkit-background-size: 176px 22px;
|
||||
background-size: 176px 22px;
|
||||
}
|
||||
}
|
||||
|
||||
/* pink */
|
||||
.icheckbox_flat-pink,
|
||||
.iradio_flat-pink {
|
||||
display: inline-block;
|
||||
*display: inline;
|
||||
vertical-align: middle;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: url(pink.png) no-repeat;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.icheckbox_flat-pink {
|
||||
background-position: 0 0;
|
||||
}
|
||||
.icheckbox_flat-pink.checked {
|
||||
background-position: -22px 0;
|
||||
}
|
||||
.icheckbox_flat-pink.disabled {
|
||||
background-position: -44px 0;
|
||||
cursor: default;
|
||||
}
|
||||
.icheckbox_flat-pink.checked.disabled {
|
||||
background-position: -66px 0;
|
||||
}
|
||||
|
||||
.iradio_flat-pink {
|
||||
background-position: -88px 0;
|
||||
}
|
||||
.iradio_flat-pink.checked {
|
||||
background-position: -110px 0;
|
||||
}
|
||||
.iradio_flat-pink.disabled {
|
||||
background-position: -132px 0;
|
||||
cursor: default;
|
||||
}
|
||||
.iradio_flat-pink.checked.disabled {
|
||||
background-position: -154px 0;
|
||||
}
|
||||
|
||||
/* Retina support */
|
||||
@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
|
||||
only screen and (-moz-min-device-pixel-ratio: 1.5),
|
||||
only screen and (-o-min-device-pixel-ratio: 3/2),
|
||||
only screen and (min-device-pixel-ratio: 1.5) {
|
||||
.icheckbox_flat-pink,
|
||||
.iradio_flat-pink {
|
||||
background-image: url(pink@2x.png);
|
||||
-webkit-background-size: 176px 22px;
|
||||
background-size: 176px 22px;
|
||||
}
|
||||
}
|
||||
|
||||
/* purple */
|
||||
.icheckbox_flat-purple,
|
||||
.iradio_flat-purple {
|
||||
display: inline-block;
|
||||
*display: inline;
|
||||
vertical-align: middle;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: url(purple.png) no-repeat;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.icheckbox_flat-purple {
|
||||
background-position: 0 0;
|
||||
}
|
||||
.icheckbox_flat-purple.checked {
|
||||
background-position: -22px 0;
|
||||
}
|
||||
.icheckbox_flat-purple.disabled {
|
||||
background-position: -44px 0;
|
||||
cursor: default;
|
||||
}
|
||||
.icheckbox_flat-purple.checked.disabled {
|
||||
background-position: -66px 0;
|
||||
}
|
||||
|
||||
.iradio_flat-purple {
|
||||
background-position: -88px 0;
|
||||
}
|
||||
.iradio_flat-purple.checked {
|
||||
background-position: -110px 0;
|
||||
}
|
||||
.iradio_flat-purple.disabled {
|
||||
background-position: -132px 0;
|
||||
cursor: default;
|
||||
}
|
||||
.iradio_flat-purple.checked.disabled {
|
||||
background-position: -154px 0;
|
||||
}
|
||||
|
||||
/* Retina support */
|
||||
@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
|
||||
only screen and (-moz-min-device-pixel-ratio: 1.5),
|
||||
only screen and (-o-min-device-pixel-ratio: 3/2),
|
||||
only screen and (min-device-pixel-ratio: 1.5) {
|
||||
.icheckbox_flat-purple,
|
||||
.iradio_flat-purple {
|
||||
background-image: url(purple@2x.png);
|
||||
-webkit-background-size: 176px 22px;
|
||||
background-size: 176px 22px;
|
||||
}
|
||||
}
|
56
public/assets/css/iCheck/flat/aero.css
Executable file
|
@ -0,0 +1,56 @@
|
|||
/* iCheck plugin Flat skin, aero
|
||||
----------------------------------- */
|
||||
.icheckbox_flat-aero,
|
||||
.iradio_flat-aero {
|
||||
display: inline-block;
|
||||
*display: inline;
|
||||
vertical-align: middle;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: url(aero.png) no-repeat;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.icheckbox_flat-aero {
|
||||
background-position: 0 0;
|
||||
}
|
||||
.icheckbox_flat-aero.checked {
|
||||
background-position: -22px 0;
|
||||
}
|
||||
.icheckbox_flat-aero.disabled {
|
||||
background-position: -44px 0;
|
||||
cursor: default;
|
||||
}
|
||||
.icheckbox_flat-aero.checked.disabled {
|
||||
background-position: -66px 0;
|
||||
}
|
||||
|
||||
.iradio_flat-aero {
|
||||
background-position: -88px 0;
|
||||
}
|
||||
.iradio_flat-aero.checked {
|
||||
background-position: -110px 0;
|
||||
}
|
||||
.iradio_flat-aero.disabled {
|
||||
background-position: -132px 0;
|
||||
cursor: default;
|
||||
}
|
||||
.iradio_flat-aero.checked.disabled {
|
||||
background-position: -154px 0;
|
||||
}
|
||||
|
||||
/* Retina support */
|
||||
@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
|
||||
only screen and (-moz-min-device-pixel-ratio: 1.5),
|
||||
only screen and (-o-min-device-pixel-ratio: 3/2),
|
||||
only screen and (min-device-pixel-ratio: 1.5) {
|
||||
.icheckbox_flat-aero,
|
||||
.iradio_flat-aero {
|
||||
background-image: url(aero@2x.png);
|
||||
-webkit-background-size: 176px 22px;
|
||||
background-size: 176px 22px;
|
||||
}
|
||||
}
|
BIN
public/assets/css/iCheck/flat/aero.png
Executable file
After Width: | Height: | Size: 1.5 KiB |
BIN
public/assets/css/iCheck/flat/aero@2x.png
Executable file
After Width: | Height: | Size: 3.1 KiB |
56
public/assets/css/iCheck/flat/blue.css
Executable file
|
@ -0,0 +1,56 @@
|
|||
/* iCheck plugin Flat skin, blue
|
||||
----------------------------------- */
|
||||
.icheckbox_flat-blue,
|
||||
.iradio_flat-blue {
|
||||
display: inline-block;
|
||||
*display: inline;
|
||||
vertical-align: middle;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: url(blue.png) no-repeat;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.icheckbox_flat-blue {
|
||||
background-position: 0 0;
|
||||
}
|
||||
.icheckbox_flat-blue.checked {
|
||||
background-position: -22px 0;
|
||||
}
|
||||
.icheckbox_flat-blue.disabled {
|
||||
background-position: -44px 0;
|
||||
cursor: default;
|
||||
}
|
||||
.icheckbox_flat-blue.checked.disabled {
|
||||
background-position: -66px 0;
|
||||
}
|
||||
|
||||
.iradio_flat-blue {
|
||||
background-position: -88px 0;
|
||||
}
|
||||
.iradio_flat-blue.checked {
|
||||
background-position: -110px 0;
|
||||
}
|
||||
.iradio_flat-blue.disabled {
|
||||
background-position: -132px 0;
|
||||
cursor: default;
|
||||
}
|
||||
.iradio_flat-blue.checked.disabled {
|
||||
background-position: -154px 0;
|
||||
}
|
||||
|
||||
/* Retina support */
|
||||
@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
|
||||
only screen and (-moz-min-device-pixel-ratio: 1.5),
|
||||
only screen and (-o-min-device-pixel-ratio: 3/2),
|
||||
only screen and (min-device-pixel-ratio: 1.5) {
|
||||
.icheckbox_flat-blue,
|
||||
.iradio_flat-blue {
|
||||
background-image: url(blue@2x.png);
|
||||
-webkit-background-size: 176px 22px;
|
||||
background-size: 176px 22px;
|
||||
}
|
||||
}
|
BIN
public/assets/css/iCheck/flat/blue.png
Executable file
After Width: | Height: | Size: 1.5 KiB |
BIN
public/assets/css/iCheck/flat/blue@2x.png
Executable file
After Width: | Height: | Size: 3.1 KiB |
56
public/assets/css/iCheck/flat/flat.css
Executable file
|
@ -0,0 +1,56 @@
|
|||
/* iCheck plugin flat skin, black
|
||||
----------------------------------- */
|
||||
.icheckbox_flat,
|
||||
.iradio_flat {
|
||||
display: inline-block;
|
||||
*display: inline;
|
||||
vertical-align: middle;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: url(flat.png) no-repeat;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.icheckbox_flat {
|
||||
background-position: 0 0;
|
||||
}
|
||||
.icheckbox_flat.checked {
|
||||
background-position: -22px 0;
|
||||
}
|
||||
.icheckbox_flat.disabled {
|
||||
background-position: -44px 0;
|
||||
cursor: default;
|
||||
}
|
||||
.icheckbox_flat.checked.disabled {
|
||||
background-position: -66px 0;
|
||||
}
|
||||
|
||||
.iradio_flat {
|
||||
background-position: -88px 0;
|
||||
}
|
||||
.iradio_flat.checked {
|
||||
background-position: -110px 0;
|
||||
}
|
||||
.iradio_flat.disabled {
|
||||
background-position: -132px 0;
|
||||
cursor: default;
|
||||
}
|
||||
.iradio_flat.checked.disabled {
|
||||
background-position: -154px 0;
|
||||
}
|
||||
|
||||
/* Retina support */
|
||||
@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
|
||||
only screen and (-moz-min-device-pixel-ratio: 1.5),
|
||||
only screen and (-o-min-device-pixel-ratio: 3/2),
|
||||
only screen and (min-device-pixel-ratio: 1.5) {
|
||||
.icheckbox_flat,
|
||||
.iradio_flat {
|
||||
background-image: url(flat@2x.png);
|
||||
-webkit-background-size: 176px 22px;
|
||||
background-size: 176px 22px;
|
||||
}
|
||||
}
|
BIN
public/assets/css/iCheck/flat/flat.png
Executable file
After Width: | Height: | Size: 1.5 KiB |
BIN
public/assets/css/iCheck/flat/flat@2x.png
Executable file
After Width: | Height: | Size: 3.1 KiB |
56
public/assets/css/iCheck/flat/green.css
Executable file
|
@ -0,0 +1,56 @@
|
|||
/* iCheck plugin Flat skin, green
|
||||
----------------------------------- */
|
||||
.icheckbox_flat-green,
|
||||
.iradio_flat-green {
|
||||
display: inline-block;
|
||||
*display: inline;
|
||||
vertical-align: middle;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: url(green.png) no-repeat;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.icheckbox_flat-green {
|
||||
background-position: 0 0;
|
||||
}
|
||||
.icheckbox_flat-green.checked {
|
||||
background-position: -22px 0;
|
||||
}
|
||||
.icheckbox_flat-green.disabled {
|
||||
background-position: -44px 0;
|
||||
cursor: default;
|
||||
}
|
||||
.icheckbox_flat-green.checked.disabled {
|
||||
background-position: -66px 0;
|
||||
}
|
||||
|
||||
.iradio_flat-green {
|
||||
background-position: -88px 0;
|
||||
}
|
||||
.iradio_flat-green.checked {
|
||||
background-position: -110px 0;
|
||||
}
|
||||
.iradio_flat-green.disabled {
|
||||
background-position: -132px 0;
|
||||
cursor: default;
|
||||
}
|
||||
.iradio_flat-green.checked.disabled {
|
||||
background-position: -154px 0;
|
||||
}
|
||||
|
||||
/* Retina support */
|
||||
@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
|
||||
only screen and (-moz-min-device-pixel-ratio: 1.5),
|
||||
only screen and (-o-min-device-pixel-ratio: 3/2),
|
||||
only screen and (min-device-pixel-ratio: 1.5) {
|
||||
.icheckbox_flat-green,
|
||||
.iradio_flat-green {
|
||||
background-image: url(green@2x.png);
|
||||
-webkit-background-size: 176px 22px;
|
||||
background-size: 176px 22px;
|
||||
}
|
||||
}
|
BIN
public/assets/css/iCheck/flat/green.png
Executable file
After Width: | Height: | Size: 1.4 KiB |
BIN
public/assets/css/iCheck/flat/green@2x.png
Executable file
After Width: | Height: | Size: 3 KiB |
56
public/assets/css/iCheck/flat/grey.css
Executable file
|
@ -0,0 +1,56 @@
|
|||
/* iCheck plugin Flat skin, grey
|
||||
----------------------------------- */
|
||||
.icheckbox_flat-grey,
|
||||
.iradio_flat-grey {
|
||||
display: inline-block;
|
||||
*display: inline;
|
||||
vertical-align: middle;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: url(grey.png) no-repeat;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.icheckbox_flat-grey {
|
||||
background-position: 0 0;
|
||||
}
|
||||
.icheckbox_flat-grey.checked {
|
||||
background-position: -22px 0;
|
||||
}
|
||||
.icheckbox_flat-grey.disabled {
|
||||
background-position: -44px 0;
|
||||
cursor: default;
|
||||
}
|
||||
.icheckbox_flat-grey.checked.disabled {
|
||||
background-position: -66px 0;
|
||||
}
|
||||
|
||||
.iradio_flat-grey {
|
||||
background-position: -88px 0;
|
||||
}
|
||||
.iradio_flat-grey.checked {
|
||||
background-position: -110px 0;
|
||||
}
|
||||
.iradio_flat-grey.disabled {
|
||||
background-position: -132px 0;
|
||||
cursor: default;
|
||||
}
|
||||
.iradio_flat-grey.checked.disabled {
|
||||
background-position: -154px 0;
|
||||
}
|
||||
|
||||
/* Retina support */
|
||||
@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
|
||||
only screen and (-moz-min-device-pixel-ratio: 1.5),
|
||||
only screen and (-o-min-device-pixel-ratio: 3/2),
|
||||
only screen and (min-device-pixel-ratio: 1.5) {
|
||||
.icheckbox_flat-grey,
|
||||
.iradio_flat-grey {
|
||||
background-image: url(grey@2x.png);
|
||||
-webkit-background-size: 176px 22px;
|
||||
background-size: 176px 22px;
|
||||
}
|
||||
}
|
BIN
public/assets/css/iCheck/flat/grey.png
Executable file
After Width: | Height: | Size: 1.5 KiB |
BIN
public/assets/css/iCheck/flat/grey@2x.png
Executable file
After Width: | Height: | Size: 3.1 KiB |