Merge branch 'master' into dc/db-types
This commit is contained in:
commit
57a02a82e9
|
@ -22,6 +22,11 @@ use PHPCI\Model\Build;
|
|||
*/
|
||||
class Application extends b8\Application
|
||||
{
|
||||
/**
|
||||
* @var \PHPCI\Controller
|
||||
*/
|
||||
protected $controller;
|
||||
|
||||
/**
|
||||
* Initialise PHPCI - Handles session verification, routing, etc.
|
||||
*/
|
||||
|
@ -100,7 +105,7 @@ class Application extends b8\Application
|
|||
$this->response->setContent($view->render());
|
||||
}
|
||||
|
||||
if ($this->response->hasLayout()) {
|
||||
if ($this->response->hasLayout() && $this->controller->layout) {
|
||||
$this->setLayoutVariables($this->controller->layout);
|
||||
|
||||
$this->controller->layout->content = $this->response->getContent();
|
||||
|
|
|
@ -30,6 +30,11 @@ class Controller extends \b8\Controller
|
|||
*/
|
||||
protected $view;
|
||||
|
||||
/**
|
||||
* @var \b8\View
|
||||
*/
|
||||
public $layout;
|
||||
|
||||
/**
|
||||
* Initialise the controller.
|
||||
*/
|
||||
|
|
|
@ -13,6 +13,7 @@ use b8\Config;
|
|||
|
||||
/**
|
||||
* Languages Helper Class - Handles loading strings files and the strings within them.
|
||||
*
|
||||
* @package PHPCI\Helper
|
||||
*/
|
||||
class Lang
|
||||
|
@ -23,6 +24,7 @@ class Lang
|
|||
|
||||
/**
|
||||
* Get a specific string from the language file.
|
||||
*
|
||||
* @param $string
|
||||
* @return mixed|string
|
||||
*/
|
||||
|
@ -48,6 +50,7 @@ class Lang
|
|||
|
||||
/**
|
||||
* Get the currently active language.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public static function getLanguage()
|
||||
|
@ -57,7 +60,9 @@ class Lang
|
|||
|
||||
/**
|
||||
* Try and load a language, and if successful, set it for use throughout the system.
|
||||
*
|
||||
* @param $language
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function setLanguage($language)
|
||||
|
@ -73,6 +78,7 @@ class Lang
|
|||
|
||||
/**
|
||||
* Return a list of available languages and their names.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getLanguageOptions()
|
||||
|
@ -90,6 +96,7 @@ class Lang
|
|||
|
||||
/**
|
||||
* Get the strings for the currently active language.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public static function getStrings()
|
||||
|
@ -99,6 +106,7 @@ class Lang
|
|||
|
||||
/**
|
||||
* Initialise the Language helper, try load the language file for the user's browser or the configured default.
|
||||
*
|
||||
* @param Config $config
|
||||
*/
|
||||
public static function init(Config $config)
|
||||
|
@ -137,6 +145,7 @@ class Lang
|
|||
|
||||
/**
|
||||
* Load a specific language file.
|
||||
*
|
||||
* @return string[]|null
|
||||
*/
|
||||
protected static function loadLanguage()
|
||||
|
@ -168,4 +177,24 @@ class Lang
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a time tag for localization.
|
||||
*
|
||||
* See http://momentjs.com/docs/#/displaying/format/ for a list of supported formats.
|
||||
*
|
||||
* @param \DateTime $dateTime The dateTime to represent.
|
||||
* @param string $format The moment.js format to use.
|
||||
*
|
||||
* @return string The formatted tag.
|
||||
*/
|
||||
public static function formatDateTime(\DateTime $dateTime, $format = 'lll')
|
||||
{
|
||||
return sprintf(
|
||||
'<time datetime="%s" data-format="%s">%s</time>',
|
||||
$dateTime->format(\DateTime::ISO8601),
|
||||
$format,
|
||||
$dateTime->format(\DateTime::RFC2822)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ class SshKey
|
|||
*/
|
||||
public function canGenerateKeys()
|
||||
{
|
||||
$keygen = @shell_exec('ssh-keygen -h');
|
||||
$keygen = @shell_exec('ssh-keygen --help');
|
||||
$canGenerateKeys = !empty($keygen);
|
||||
|
||||
return $canGenerateKeys;
|
||||
|
|
|
@ -14,21 +14,21 @@ $strings = array(
|
|||
// Log in:
|
||||
'log_in_to_phpci' => 'Connectez-vous à PHPCI',
|
||||
'login_error' => 'Adresse email ou mot de passe invalide',
|
||||
'forgotten_password_link' => 'Mot de passe oublié ?',
|
||||
'forgotten_password_link' => 'Mot de passe oublié ?',
|
||||
'reset_emailed' => 'Nous vous avons envoyé un email avec un lien pour réinitialiser votre mot de passe.',
|
||||
'reset_header' => '<strong>Pas d\'inquiétude</strong><br>Entrez simplement votre adresse email ci-dessous
|
||||
et nous vous enverrons un message avec un lien pour réinitialiser votre mot de passe.',
|
||||
'reset_email_address' => 'Entrez votre adresse email:',
|
||||
'reset_send_email' => 'Envoyer le mail',
|
||||
'reset_enter_password' => 'Veuillez entrer un nouveau mot de passe',
|
||||
'reset_new_password' => 'Nouveau mot de passe :',
|
||||
'reset_new_password' => 'Nouveau mot de passe :',
|
||||
'reset_change_password' => 'Modifier le mot de passe',
|
||||
'reset_no_user_exists' => 'Il n\'existe aucun utilisateur avec cette adresse email, merci de réessayer.',
|
||||
'reset_email_body' => 'Bonjour %s,
|
||||
|
||||
Vous avez reçu cet email parce qu\'une demande de réinitialisation de mot de passe a été faite pour votre compte PHPCI.
|
||||
|
||||
Si c\'est bien vous, merci de cliquer sur le lien suivant pour réinitialiser votre mot de passe : %ssession/reset-password/%d/%s
|
||||
Si c\'est bien vous, merci de cliquer sur le lien suivant pour réinitialiser votre mot de passe : %ssession/reset-password/%d/%s
|
||||
|
||||
Sinon, merci d\'ignorer ce message.
|
||||
|
||||
|
@ -49,9 +49,9 @@ PHPCI',
|
|||
'n_builds_running' => '%d builds en cours d\'exécution',
|
||||
'edit_profile' => 'Éditer le profil',
|
||||
'sign_out' => 'Déconnexion',
|
||||
'branch_x' => 'Branche : %s',
|
||||
'created_x' => 'Créé à : %s',
|
||||
'started_x' => 'Démarré à : %s',
|
||||
'branch_x' => 'Branche : %s',
|
||||
'created_x' => 'Créé à : %s',
|
||||
'started_x' => 'Démarré à : %s',
|
||||
|
||||
// Sidebar
|
||||
'hello_name' => 'Salut %s',
|
||||
|
@ -67,19 +67,19 @@ PHPCI',
|
|||
'delete_project' => 'Supprimer le projet',
|
||||
|
||||
// Project Summary:
|
||||
'no_builds_yet' => 'Aucun build pour le moment!',
|
||||
'x_of_x_failed' => '%d parmis les derniers %d builds ont échoué.',
|
||||
'x_of_x_failed_short' => '%d / %d ont échoué.',
|
||||
'last_successful_build' => ' Le dernier build qui a réussi est %s.',
|
||||
'never_built_successfully' => ' Aucun build n\'a été exécuté avec succès sur ce projet.',
|
||||
'all_builds_passed' => 'Les derniers %d builds ont réussis.',
|
||||
'all_builds_passed_short' => '%d / %d ont réussis.',
|
||||
'last_failed_build' => ' Le dernier build en échec est %s.',
|
||||
'never_failed_build' => ' Ce projet n\'a jamais eu un build en échec.',
|
||||
'no_builds_yet' => 'Aucun build pour le moment !',
|
||||
'x_of_x_failed' => '%d des %d derniers builds ont échoué.',
|
||||
'x_of_x_failed_short' => '%d échecs / %d.',
|
||||
'last_successful_build' => ' Le dernier build réussi date du %s.',
|
||||
'never_built_successfully' => ' Aucun build de ce projet n\'a réussi.',
|
||||
'all_builds_passed' => 'Les %d derniers builds ont réussi.',
|
||||
'all_builds_passed_short' => '%d réussites / %d.',
|
||||
'last_failed_build' => ' Le dernier build en échec date du %s.',
|
||||
'never_failed_build' => ' Aucun build de ce projet n\'a échoué.',
|
||||
'view_project' => 'Voir le projet',
|
||||
|
||||
// Timeline:
|
||||
'latest_builds' => 'Les derniers Builds',
|
||||
'latest_builds' => 'Derniers builds',
|
||||
'pending' => 'En attente',
|
||||
'running' => 'En cours',
|
||||
'success' => 'Terminé',
|
||||
|
@ -102,8 +102,8 @@ PHPCI',
|
|||
'local' => 'Chemin local',
|
||||
'hg' => 'Mercurial',
|
||||
|
||||
'where_hosted' => 'Où est hébergé votre projet ?',
|
||||
'choose_github' => 'Choisissez un dépôt GitHub :',
|
||||
'where_hosted' => 'Où est hébergé votre projet ?',
|
||||
'choose_github' => 'Choisissez un dépôt GitHub :',
|
||||
|
||||
'repo_name' => 'Nom du dépôt / URL (distance) ou chemin (local)',
|
||||
'project_title' => 'Titre du projet',
|
||||
|
@ -112,7 +112,7 @@ PHPCI',
|
|||
'build_config' => 'Configuration PHPCI spécifique pour ce projet
|
||||
(si vous ne pouvez pas ajouter de fichier phpci.yml à la racine du dépôt)',
|
||||
'default_branch' => 'Nom de la branche par défaut',
|
||||
'allow_public_status' => 'Activer la page de statut publique et l\'image pour ce projet ?',
|
||||
'allow_public_status' => 'Activer la page de statut publique et l\'image pour ce projet ?',
|
||||
'save_project' => 'Enregistrer le projet',
|
||||
|
||||
'error_mercurial' => 'Les URLs de dépôt Mercurial doivent commencer par http:// ou https://',
|
||||
|
@ -155,7 +155,7 @@ PHPCI',
|
|||
|
||||
|
||||
'committed_by_x' => 'Committé par %s',
|
||||
'commit_id_x' => 'Commit: %s',
|
||||
'commit_id_x' => 'Commit : %s',
|
||||
|
||||
'chart_display' => 'Ce graphique s\'affichera une fois que le build sera terminé.',
|
||||
|
||||
|
@ -207,7 +207,7 @@ PHPCI',
|
|||
'update_your_details' => 'Mettre à jour vos préférences',
|
||||
'your_details_updated' => 'Vos préférences ont été bien mises à jour.',
|
||||
'add_user' => 'Ajouter un utilisateur',
|
||||
'is_admin' => 'Est-il administrateur ?',
|
||||
'is_admin' => 'Est-il administrateur ?',
|
||||
'yes' => 'Oui',
|
||||
'no' => 'Non',
|
||||
'edit' => 'Éditer',
|
||||
|
@ -287,17 +287,17 @@ PHPCI',
|
|||
'config_path' => 'Chemin vers le fichier de configuration',
|
||||
'install_phpci' => 'Installer PHPCI',
|
||||
'welcome_to_phpci' => 'Bienvenue sur PHPCI',
|
||||
'please_answer' => 'Merci de répondre aux questions suivantes:',
|
||||
'please_answer' => 'Merci de répondre aux questions suivantes :',
|
||||
'phpci_php_req' => 'PHPCI requiert au moins PHP 5.3.8 pour fonctionner.',
|
||||
'extension_required' => 'Extensions requises: %s',
|
||||
'extension_required' => 'Extensions requises : %s',
|
||||
'function_required' => 'PHPCI doit être capable d\'appeler la fonction %s(). Est-ce qu\'elle est désactivée dans votre php.ini?',
|
||||
'requirements_not_met' => 'PHPCI ne peut pas être installé parce que toutes les conditions requises ne sont pas respectées.
|
||||
Merci de corriger les erreurs ci-dessus avant de continuer.',
|
||||
'must_be_valid_email' => 'Doit être une adresse email valide.',
|
||||
'must_be_valid_url' => 'Doit être une URL valide.',
|
||||
'enter_name' => 'Nom de l\'admin:',
|
||||
'enter_email' => 'Email de l\'admin:',
|
||||
'enter_password' => 'Mot de passe de l\'admin:',
|
||||
'enter_name' => 'Nom de l\'admin :',
|
||||
'enter_email' => 'Email de l\'admin :',
|
||||
'enter_password' => 'Mot de passe de l\'admin :',
|
||||
'enter_phpci_url' => 'Votre URL vers PHPCI (par exemple "http://phpci.local"): ',
|
||||
|
||||
'enter_db_host' => 'Merci d\'entrer le nom d\'hôte MySQL [localhost]: ',
|
||||
|
@ -306,7 +306,7 @@ PHPCI',
|
|||
'enter_db_pass' => 'Merci d\'entrer le mot de passe MySQL: ',
|
||||
'could_not_connect' => 'PHPCI ne peut pas se connecter à MySQL à partir des informations fournies. Veuillez réessayer..',
|
||||
'setting_up_db' => 'Paramétrage de la base de données... ',
|
||||
'user_created' => 'Le compte utilisateur a été créé!',
|
||||
'user_created' => 'Le compte utilisateur a été créé !',
|
||||
'failed_to_create' => 'PHPCI n\'a pas réussi à créer votre compte admin.',
|
||||
'config_exists' => 'Le fichier de configuration PHPCI existe et n\'est pas vide.',
|
||||
'update_instead' => 'Si vous essayez de mettre à jour PHPCI, merci d\'utiliser la commande phpci:update.',
|
||||
|
@ -365,7 +365,7 @@ PHPCI',
|
|||
'n_emails_sent' => '%d emails envoyés.',
|
||||
'n_emails_failed' => '%d emails dont l\'envoi a échoué.',
|
||||
'unable_to_set_env' => 'Impossible d\'initialiser la variable d\'environnement',
|
||||
'tag_created' => 'Tag créé par PHPCI: %s',
|
||||
'tag_created' => 'Tag créé par PHPCI : %s',
|
||||
'x_built_at_x' => '%PROJECT_TITLE% construit à %BUILD_URI%',
|
||||
'hipchat_settings' => 'Merci de définir une "room" et un "authToken" pour le plugin hipchat_notify',
|
||||
'irc_settings' => 'Vous devez configurer un serveur, une "room" et un "nick".',
|
||||
|
|
|
@ -84,7 +84,7 @@ PHPCI',
|
|||
'success' => 'Успешно',
|
||||
'successful' => 'Успешна',
|
||||
'failed' => 'Провалена',
|
||||
'manual_build' => 'Ручной сборки',
|
||||
'manual_build' => 'Запущена вручную',
|
||||
|
||||
// Add/Edit Project:
|
||||
'new_project' => 'Новый проект',
|
||||
|
|
|
@ -194,6 +194,10 @@ class Build extends BuildBase
|
|||
return $rtn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the commit message for this build.
|
||||
* @return string
|
||||
*/
|
||||
public function getCommitMessage()
|
||||
{
|
||||
$rtn = htmlspecialchars($this->data['commit_message']);
|
||||
|
|
|
@ -182,7 +182,7 @@ class Email implements \PHPCI\Plugin
|
|||
$addresses[] = $this->options['default_mailto_address'];
|
||||
return $addresses;
|
||||
}
|
||||
return $addresses;
|
||||
return array_unique($addresses);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -83,7 +83,7 @@ class Pgsql implements \PHPCI\Plugin
|
|||
$pdo = new PDO('pgsql:host=' . $this->host, $this->user, $this->pass, $opts);
|
||||
|
||||
foreach ($this->queries as $query) {
|
||||
$pdo->query($query);
|
||||
$pdo->query($this->phpci->interpolate($query));
|
||||
}
|
||||
} catch (\Exception $ex) {
|
||||
$this->phpci->logFailure($ex->getMessage());
|
||||
|
|
|
@ -70,7 +70,7 @@ class Sqlite implements \PHPCI\Plugin
|
|||
$pdo = new PDO('sqlite:' . $this->path, $opts);
|
||||
|
||||
foreach ($this->queries as $query) {
|
||||
$pdo->query($query);
|
||||
$pdo->query($this->phpci->interpolate($query));
|
||||
}
|
||||
} catch (\Exception $ex) {
|
||||
$this->phpci->logFailure($ex->getMessage());
|
||||
|
|
|
@ -100,6 +100,7 @@ class BuildService
|
|||
$build = new Build();
|
||||
$build->setValues($data);
|
||||
$build->setCreated(new \DateTime());
|
||||
$build->setStatus(0);
|
||||
|
||||
return $this->buildStore->save($build);
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
?>
|
||||
<li class="time-label">
|
||||
<span class="bg-gray">
|
||||
<?php print $last->format('M j Y'); ?>
|
||||
<?php print Lang::formatDateTime($last, 'll'); ?>
|
||||
</span>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
|
@ -58,7 +58,7 @@
|
|||
<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('H:i'); ?></span>
|
||||
<span class="time"><i class="fa fa-clock-o"></i> <?php print Lang::formatDateTime($updated, 'LT'); ?></span>
|
||||
<h3 class="timeline-header">
|
||||
<a href="<?php print PHPCI_URL; ?>project/view/<?php print $build->getProjectId(); ?>">
|
||||
<?php print $build->getProject()->getTitle(); ?>
|
||||
|
|
|
@ -27,12 +27,12 @@ foreach($projects as $project):
|
|||
case 2:
|
||||
$successes++;
|
||||
$statuses[] = 'ok';
|
||||
$success = is_null($success) && !is_null($build->getFinished()) ? $build->getFinished()->format('M j Y g:ia') : $success;
|
||||
$success = is_null($success) && !is_null($build->getFinished()) ? Lang::formatDateTime($build->getFinished()) : $success;
|
||||
break;
|
||||
case 3:
|
||||
$failures++;
|
||||
$statuses[] = 'failed';
|
||||
$failure = is_null($failure) && !is_null($build->getFinished()) ? $build->getFinished()->format('M j Y g:ia') : $failure;
|
||||
$failure = is_null($failure) && !is_null($build->getFinished()) ? Lang::formatDateTime($build->getFinished()) : $failure;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ foreach($projects as $project):
|
|||
$message = Lang::get('x_of_x_failed', $failures, $buildCount);
|
||||
|
||||
if (!is_null($lastSuccess) && !is_null($lastSuccess->getFinished())) {
|
||||
$message .= Lang::get('last_successful_build', $lastSuccess->getFinished()->format('M j Y'));
|
||||
$message .= Lang::get('last_successful_build', Lang::formatDateTime($lastSuccess->getFinished()));
|
||||
} else {
|
||||
$message .= Lang::get('never_built_successfully');
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ foreach($projects as $project):
|
|||
$shortMessage = Lang::get('all_builds_passed_short', $buildCount, $buildCount);
|
||||
|
||||
if (!is_null($lastFailure) && !is_null($lastFailure->getFinished())) {
|
||||
$message .= Lang::get('last_failed_build', $lastFailure->getFinished()->format('M j Y'));
|
||||
$message .= Lang::get('last_failed_build', Lang::formatDateTime($lastFailure->getFinished()));
|
||||
} else {
|
||||
$message .= Lang::get('never_failed_build');
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
<!-- Theme style -->
|
||||
<link href="<?php print PHPCI_URL; ?>assets/css/AdminLTE.css" rel="stylesheet" type="text/css" />
|
||||
<link href="<?php print PHPCI_URL; ?>assets/css/AdminLTE-custom.css" rel="stylesheet" type="text/css" />
|
||||
|
||||
<script>
|
||||
var PHPCI_URL = '<?php print PHPCI_URL; ?>';
|
||||
|
@ -41,53 +42,7 @@
|
|||
<![endif]-->
|
||||
|
||||
<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;
|
||||
}
|
||||
|
||||
.build-info-panel {
|
||||
|
||||
}
|
||||
|
||||
.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>
|
||||
|
@ -320,6 +275,7 @@
|
|||
|
||||
<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/plugins/datepicker/locales/bootstrap-datepicker.<?php print Lang::getLanguage(); ?>.js" type="text/javascript"></script>
|
||||
<script src="<?php print PHPCI_URL; ?>assets/js/AdminLTE/app.js" type="text/javascript"></script>
|
||||
|
||||
</body>
|
||||
|
|
28
Tests/PHPCI/Helper/LangTest.php
Normal file
28
Tests/PHPCI/Helper/LangTest.php
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace PHPCI\Tests\Helper;
|
||||
|
||||
use DateTime;
|
||||
use PHPCI\Helper\Lang;
|
||||
use Prophecy\PhpUnit\ProphecyTestCase;
|
||||
|
||||
class LangTest extends ProphecyTestCase
|
||||
{
|
||||
public function testLang_UsePassedParameters()
|
||||
{
|
||||
$dateTime = $this->prophesize('DateTime');
|
||||
$dateTime->format(DateTime::ISO8601)->willReturn("ISODATE");
|
||||
$dateTime->format(DateTime::RFC2822)->willReturn("RFCDATE");
|
||||
|
||||
$this->assertEquals('<time datetime="ISODATE" data-format="FORMAT">RFCDATE</time>', Lang::formatDateTime($dateTime->reveal(), 'FORMAT'));
|
||||
}
|
||||
|
||||
public function testLang_UseDefaultFormat()
|
||||
{
|
||||
$dateTime = $this->prophesize('DateTime');
|
||||
$dateTime->format(DateTime::ISO8601)->willReturn("ISODATE");
|
||||
$dateTime->format(DateTime::RFC2822)->willReturn("RFCDATE");
|
||||
|
||||
$this->assertEquals('<time datetime="ISODATE" data-format="lll">RFCDATE</time>', Lang::formatDateTime($dateTime->reveal()));
|
||||
}
|
||||
}
|
|
@ -57,6 +57,10 @@ class EmailTest extends \PHPUnit_Framework_TestCase
|
|||
->method('getStatus')
|
||||
->will($this->returnValue(\PHPCI\Model\Build::STATUS_SUCCESS));
|
||||
|
||||
$this->mockBuild->expects($this->any())
|
||||
->method('getCommitterEmail')
|
||||
->will($this->returnValue("committer@test.com"));
|
||||
|
||||
$this->mockCiBuilder = $this->getMock(
|
||||
'\PHPCI\Builder',
|
||||
array(
|
||||
|
@ -151,8 +155,53 @@ class EmailTest extends \PHPUnit_Framework_TestCase
|
|||
);
|
||||
|
||||
$this->assertEquals($expectedReturn, $returnValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers PHPUnit::execute
|
||||
*/
|
||||
public function testExecute_UniqueRecipientsFromWithCommitter()
|
||||
{
|
||||
$this->loadEmailPluginWithOptions(
|
||||
array(
|
||||
'addresses' => array('test-receiver@example.com', 'test-receiver2@example.com')
|
||||
)
|
||||
);
|
||||
|
||||
$actualMails = [];
|
||||
$this->catchMailPassedToSend($actualMails);
|
||||
|
||||
$returnValue = $this->testedEmailPlugin->execute();
|
||||
$this->assertTrue($returnValue);
|
||||
|
||||
$this->assertCount(2, $actualMails);
|
||||
|
||||
$actualTos = array(key($actualMails[0]->getTo()), key($actualMails[1]->getTo()));
|
||||
$this->assertContains('test-receiver@example.com', $actualTos);
|
||||
$this->assertContains('test-receiver2@example.com', $actualTos);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers PHPUnit::execute
|
||||
*/
|
||||
public function testExecute_UniqueRecipientsWithCommiter()
|
||||
{
|
||||
$this->loadEmailPluginWithOptions(
|
||||
array(
|
||||
'commiter' => true,
|
||||
'addresses' => array('test-receiver@example.com', 'committer@test.com')
|
||||
)
|
||||
);
|
||||
|
||||
$actualMails = [];
|
||||
$this->catchMailPassedToSend($actualMails);
|
||||
|
||||
$returnValue = $this->testedEmailPlugin->execute();
|
||||
$this->assertTrue($returnValue);
|
||||
|
||||
$actualTos = array(key($actualMails[0]->getTo()), key($actualMails[1]->getTo()));
|
||||
$this->assertContains('test-receiver@example.com', $actualTos);
|
||||
$this->assertContains('committer@test.com', $actualTos);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -215,12 +264,16 @@ class EmailTest extends \PHPUnit_Framework_TestCase
|
|||
*/
|
||||
protected function catchMailPassedToSend(&$actualMail)
|
||||
{
|
||||
$this->mockMailer->expects($this->once())
|
||||
$this->mockMailer->expects(is_array($actualMail) ? $this->atLeast(1) : $this->once())
|
||||
->method('send')
|
||||
->will(
|
||||
$this->returnCallback(
|
||||
function ($passedMail) use (&$actualMail) {
|
||||
$actualMail = $passedMail;
|
||||
if(is_array($actualMail)) {
|
||||
$actualMail[] = $passedMail;
|
||||
} else {
|
||||
$actualMail = $passedMail;
|
||||
}
|
||||
return array();
|
||||
}
|
||||
)
|
||||
|
|
|
@ -56,7 +56,7 @@ class BuildServiceTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertNull($returnValue->getStarted());
|
||||
$this->assertNull($returnValue->getFinished());
|
||||
$this->assertNull($returnValue->getLog());
|
||||
$this->assertNull($returnValue->getCommitMessage());
|
||||
$this->assertEmpty($returnValue->getCommitMessage());
|
||||
$this->assertNull($returnValue->getCommitterEmail());
|
||||
$this->assertNull($returnValue->getExtra());
|
||||
$this->assertEquals('master', $returnValue->getBranch());
|
||||
|
|
53
public/assets/css/AdminLTE-custom.css
Normal file
53
public/assets/css/AdminLTE-custom.css
Normal file
|
@ -0,0 +1,53 @@
|
|||
.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;
|
||||
}
|
||||
|
||||
.build-info-panel {
|
||||
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
#plugins table td {
|
||||
max-width: 300px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
|
@ -18,11 +18,16 @@
|
|||
margin: 4px;
|
||||
}
|
||||
|
||||
.daterangepicker.opensright .ranges, .daterangepicker.opensright .calendar {
|
||||
.daterangepicker.opensright .ranges, .daterangepicker.opensright .calendar,
|
||||
.daterangepicker.openscenter .ranges, .daterangepicker.openscenter .calendar {
|
||||
float: right;
|
||||
margin: 4px;
|
||||
}
|
||||
|
||||
.daterangepicker.single .ranges, .daterangepicker.single .calendar {
|
||||
float: none;
|
||||
}
|
||||
|
||||
.daterangepicker .ranges {
|
||||
width: 160px;
|
||||
text-align: left;
|
||||
|
@ -41,6 +46,14 @@
|
|||
max-width: 270px;
|
||||
}
|
||||
|
||||
.daterangepicker.show-calendar .calendar {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.daterangepicker .calendar.single .calendar-date {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.daterangepicker .calendar th, .daterangepicker .calendar td {
|
||||
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
white-space: nowrap;
|
||||
|
@ -48,7 +61,8 @@
|
|||
min-width: 32px;
|
||||
}
|
||||
|
||||
.daterangepicker .ranges label {
|
||||
.daterangepicker .daterangepicker_start_input label,
|
||||
.daterangepicker .daterangepicker_end_input label {
|
||||
color: #333;
|
||||
display: block;
|
||||
font-size: 11px;
|
||||
|
@ -66,7 +80,6 @@
|
|||
}
|
||||
|
||||
.daterangepicker .ranges .input-mini {
|
||||
background-color: #eee;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
color: #555;
|
||||
|
@ -153,6 +166,37 @@
|
|||
content: '';
|
||||
}
|
||||
|
||||
.daterangepicker.openscenter:before {
|
||||
position: absolute;
|
||||
top: -7px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
width: 0;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
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.openscenter:after {
|
||||
position: absolute;
|
||||
top: -6px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
width: 0;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
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;
|
||||
|
@ -196,7 +240,7 @@
|
|||
color: #999;
|
||||
}
|
||||
|
||||
.daterangepicker td.disabled {
|
||||
.daterangepicker td.disabled, .daterangepicker option.disabled {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
|
@ -211,6 +255,24 @@
|
|||
border-radius: 0;
|
||||
}
|
||||
|
||||
.daterangepicker td.start-date {
|
||||
-webkit-border-radius: 4px 0 0 4px;
|
||||
-moz-border-radius: 4px 0 0 4px;
|
||||
border-radius: 4px 0 0 4px;
|
||||
}
|
||||
|
||||
.daterangepicker td.end-date {
|
||||
-webkit-border-radius: 0 4px 4px 0;
|
||||
-moz-border-radius: 0 4px 4px 0;
|
||||
border-radius: 0 4px 4px 0;
|
||||
}
|
||||
|
||||
.daterangepicker td.start-date.end-date {
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.daterangepicker td.active, .daterangepicker td.active:hover {
|
||||
background-color: #357ebd;
|
||||
border-color: #3071a9;
|
||||
|
@ -239,7 +301,20 @@
|
|||
width: 40%;
|
||||
}
|
||||
|
||||
.daterangepicker select.hourselect, .daterangepicker select.minuteselect, .daterangepicker select.ampmselect {
|
||||
.daterangepicker select.hourselect, .daterangepicker select.minuteselect, .daterangepicker select.secondselect, .daterangepicker select.ampmselect {
|
||||
width: 50px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.daterangepicker_start_input {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.daterangepicker_end_input {
|
||||
float: left;
|
||||
padding-left: 11px
|
||||
}
|
||||
|
||||
.daterangepicker th.month {
|
||||
width: auto;
|
||||
}
|
||||
|
|
|
@ -23,14 +23,14 @@ var phpcpdPlugin = ActiveBuild.UiPlugin.extend({
|
|||
|
||||
render: function() {
|
||||
|
||||
return $('<table class="table" id="phpcpd-data">' +
|
||||
return $('<div class="table-responsive"><table class="table" id="phpcpd-data">' +
|
||||
'<thead>' +
|
||||
'<tr>' +
|
||||
' <th>'+Lang.get('file')+'</th>' +
|
||||
' <th>'+Lang.get('start')+'</th>' +
|
||||
' <th>'+Lang.get('end')+'</th>' +
|
||||
'</tr>' +
|
||||
'</thead><tbody></tbody></table>');
|
||||
'</thead><tbody></tbody></table></div>');
|
||||
|
||||
},
|
||||
|
||||
|
|
|
@ -22,14 +22,14 @@ var phpcsPlugin = ActiveBuild.UiPlugin.extend({
|
|||
},
|
||||
|
||||
render: function() {
|
||||
return $('<table class="table" id="phpcs-data">' +
|
||||
return $('<div class="table-responsive"><table class="table" id="phpcs-data">' +
|
||||
'<thead>' +
|
||||
'<tr>' +
|
||||
' <th>'+Lang.get('file')+'</th>' +
|
||||
' <th>'+Lang.get('line')+'</th>' +
|
||||
' <th>'+Lang.get('message')+'</th>' +
|
||||
'</tr>' +
|
||||
'</thead><tbody></tbody></table>');
|
||||
'</thead><tbody></tbody></table></div>');
|
||||
},
|
||||
|
||||
onUpdate: function(e) {
|
||||
|
|
|
@ -24,7 +24,7 @@ var phpdoccheckPlugin = ActiveBuild.UiPlugin.extend({
|
|||
},
|
||||
|
||||
render: function() {
|
||||
return $('<table class="table" id="phpdoccheck-data">' +
|
||||
return $('<div class="table-responsive"><table class="table" id="phpdoccheck-data">' +
|
||||
'<thead>' +
|
||||
'<tr>' +
|
||||
' <th>'+Lang.get('file')+'</th>' +
|
||||
|
@ -32,7 +32,7 @@ var phpdoccheckPlugin = ActiveBuild.UiPlugin.extend({
|
|||
' <th>'+Lang.get('class')+'</th>' +
|
||||
' <th>'+Lang.get('method')+'</th>' +
|
||||
'</tr>' +
|
||||
'</thead><tbody></tbody></table>');
|
||||
'</thead><tbody></tbody></table></div>');
|
||||
},
|
||||
|
||||
onUpdate: function(e) {
|
||||
|
|
|
@ -25,7 +25,7 @@ var phpmdPlugin = ActiveBuild.UiPlugin.extend({
|
|||
|
||||
render: function() {
|
||||
|
||||
return $('<table class="table" id="phpmd-data">' +
|
||||
return $('<div class="table-responsive"><table class="table" id="phpmd-data">' +
|
||||
'<thead>' +
|
||||
'<tr>' +
|
||||
' <th>'+Lang.get('file')+'</th>' +
|
||||
|
@ -33,7 +33,7 @@ var phpmdPlugin = ActiveBuild.UiPlugin.extend({
|
|||
' <th>'+Lang.get('end')+'</th>' +
|
||||
' <th>'+Lang.get('message')+'</th>' +
|
||||
'</tr>' +
|
||||
'</thead><tbody></tbody></table>');
|
||||
'</thead><tbody></tbody></table></div>');
|
||||
},
|
||||
|
||||
onUpdate: function(e) {
|
||||
|
|
|
@ -22,14 +22,14 @@ var phptalPlugin = ActiveBuild.UiPlugin.extend({
|
|||
},
|
||||
|
||||
render: function() {
|
||||
return $('<table class="table" id="phptal-data">' +
|
||||
return $('<div class="table-responsive"><table class="table" id="phptal-data">' +
|
||||
'<thead>' +
|
||||
'<tr>' +
|
||||
' <th>File</th>' +
|
||||
' <th>Line</th>' +
|
||||
' <th>Message</th>' +
|
||||
'</tr>' +
|
||||
'</thead><tbody></tbody></table>');
|
||||
'</thead><tbody></tbody></table></div>');
|
||||
},
|
||||
|
||||
onUpdate: function(e) {
|
||||
|
|
|
@ -25,12 +25,12 @@ var phpunitPlugin = ActiveBuild.UiPlugin.extend({
|
|||
|
||||
render: function() {
|
||||
|
||||
return $('<table class="table" id="phpunit-data">' +
|
||||
return $('<div class="table-responsive"><table class="table" id="phpunit-data">' +
|
||||
'<thead>' +
|
||||
'<tr>' +
|
||||
' <th>'+Lang.get('test')+'</th>' +
|
||||
'</tr>' +
|
||||
'</thead><tbody></tbody></table>');
|
||||
'</thead><tbody></tbody></table></div>');
|
||||
},
|
||||
|
||||
onUpdate: function(e) {
|
||||
|
|
|
@ -3,7 +3,16 @@ var PHPCI = {
|
|||
intervals: {},
|
||||
|
||||
init: function () {
|
||||
// Setup the date locale
|
||||
moment.locale(PHPCI_LANGUAGE);
|
||||
|
||||
$(document).ready(function () {
|
||||
// Format datetimes
|
||||
$('time[datetime]').each(function() {
|
||||
var $this = $(this);
|
||||
$this.text(moment(this.dateTime).format($this.data('format') || 'lll'));
|
||||
});
|
||||
|
||||
// Update latest builds every 5 seconds:
|
||||
PHPCI.getBuilds();
|
||||
PHPCI.intervals.getBuilds = setInterval(PHPCI.getBuilds, 5000);
|
||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue