This commit is contained in:
root 2020-07-07 17:21:15 +02:00
parent b4fb8ab9a0
commit 398d10c1ce
26 changed files with 1145 additions and 508 deletions

View File

@ -59,17 +59,14 @@ class CronInitCommand extends Command
protected function insertCron() {
$metadata = $this->em->getClassMetaData('App:Cron');
$metadata->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_NONE);
$metadata->setIdGenerator(new AssignedGenerator());
// Job Mail
// Toute les minutes
$entity = $this->em->getRepository('App:Cron')->find(1);
$entity = $this->em->getRepository('App:Cron')->findOneBy(["command"=>"app:sendMail"]);
if(!$entity) {
$entity = new Cron;
$entity->setCommand("app:sendMail");
$entity->setDescription("Execution du spool de mail en attente");
$entity->setId(1);
$entity->setStatut(2);
$entity->setRepeatcall(0);
$entity->setRepeatexec(0);
@ -81,14 +78,13 @@ class CronInitCommand extends Command
// Job de purge des fichiers obsolète
// Toute les 24h à 3h00
$entity = $this->em->getRepository('App:Cron')->find(200);
$entity = $this->em->getRepository('App:Cron')->findOneBy(["command"=>"app:purgeFile"]);
if(!$entity) {
$entity = new Cron;
$nextdate=$entity->getSubmitdate();
$nextdate->setTime(3,0);
$entity->setCommand("app:purgeFile");
$entity->setDescription("Suppression des fichiers obsolètes");
$entity->setId(200);
$entity->setStatut(2);
$entity->setRepeatcall(0);
$entity->setRepeatexec(0);
@ -99,14 +95,13 @@ class CronInitCommand extends Command
// Job synchronisation des comptes utilisateur
// Toute les 24h à 3h00
$entity = $this->em->getRepository('App:Cron')->find(100);
$entity = $this->em->getRepository('App:Cron')->findOneBy(["command"=>"app:synchroUsers"]);
if(!$entity) {
$entity = new Cron;
$nextdate=$entity->getSubmitdate();
$nextdate->setTime(3,0);
$entity->setCommand("app:synchroUsers");
$entity->setDescription("Synchronisation des comptes utilisateurs");
$entity->setId(100);
$entity->setStatut(2);
$entity->setRepeatcall(0);
$entity->setRepeatexec(0);
@ -118,14 +113,13 @@ class CronInitCommand extends Command
// Job Dump
// Toute les 24h à 2h00
$entity = $this->em->getRepository('App:Cron')->find(220);
$entity = $this->em->getRepository('App:Cron')->findOneBy(["command"=>"app:dumpBdd"]);
if(!$entity) {
$entity = new Cron;
$nextdate=$entity->getSubmitdate();
$nextdate->setTime(2,0);
$entity->setCommand("app:dumpBdd");
$entity->setDescription("Sauvegarde de la BDD");
$entity->setId(220);
$entity->setStatut(2);
$entity->setRepeatcall(0);
$entity->setRepeatexec(0);

View File

@ -228,17 +228,12 @@ class SynchroUsersCommand extends Command
}
}
if(!$simulate) {
$this->em->clear();
}
if($nbusers%1000==0) $this->writeln(" == Nombre d'utilisateurs traités = $nbusers sur $nbuserstotal ==");
}
if(!$simulate) {
$this->writeln(" == Nombre d'utilisateurs traités = $nbusers sur $nbuserstotal ==");
$this->em->flush();
$this->em->clear();
}
foreach($tberrors as $error) {
@ -348,7 +343,6 @@ class SynchroUsersCommand extends Command
unset($flipped[$data["username"]]);
}
$this->em->clear();
if($nbusers%1000==0) $this->writelnred(" == Nombre d'utilisateurs traités = $nbusers==");
}

View File

@ -1,143 +0,0 @@
<?php
namespace App\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\ButtonType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Tetranz\Select2EntityBundle\Form\Type\Select2EntityType;
use FOS\CKEditorBundle\Form\Type\CKEditorType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\EntityManager;
class ActivityType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('submit',
SubmitType::class, [
"label" => "Valider",
"attr" => ["class" => "btn btn-success"],
]
);
if($options["status"]==0) {
$builder->add('distribution',
SubmitType::class, [
"label" => "Distribuer",
"attr" => [
"class" => "btn btn-success",
"data-method" => "submit",
"data-confirm" => "Confirmez vous la distribution de l'activité ? Une foi validée, vous ne pourrez plus modifier son entête et son énoncé." ],
]
);
}
if($options["status"]==1) {
$builder->add('archiving',
SubmitType::class, [
"label" => "Archiver",
"attr" => [
"class" => "btn btn-danger float-right",
"data-method" => "submit",
"data-confirm" => "Confirmez vous l'archivage' de l'activité ?" ],
]
);
}
if($options["status"]==10) {
$builder->add('distribution',
SubmitType::class, [
"label" => "Réouvrir",
"attr" => [
"class" => "btn btn-success",
"data-method" => "submit",
"data-confirm" => "Confirmez vous la réouverture de l'activité ?" ],
]
);
}
$builder->add('name',
TextType::class, [
"disabled" => ($options["status"]>0),
"label" =>"Nom",
]
);
$builder->add('subject',
TextType::class, [
"disabled" => ($options["status"]>0),
"required" => false,
"label" =>"Matière",
]
);
$builder->add('group',
Select2EntityType::class, [
"label" => "Groupe",
"disabled" => ($options["status"]>0),
"required" => true,
"multiple" => false,
"remote_route" => "app_group_select",
"class" => "App:Group",
"primary_key" => "id",
"text_property" => "name",
"minimum_input_length" => 0,
"page_limit" => 100,
"allow_clear" => true,
"delay" => 250,
"cache" => false,
"cache_timeout" => 60000,
"language" => "fr",
"placeholder" => "Selectionner un Groupe",
]
);
$builder->add('activity',
CKEditorType::class, [
"disabled" => ($options["status"]>0),
"required" => false,
"config" => [
'uiColor' => '#ffffff',
'height' => 600,
'filebrowserUploadRoute' => 'app_ckeditor_upload',
'language' => 'fr',
],
]
);
$builder->add('corrected',
CKEditorType::class, [
"disabled" => ($options["status"]==10),
"required" => false,
"config" => [
'uiColor' => '#ffffff',
'height' => 600,
'filebrowserUploadRoute' => 'app_ckeditor_upload',
'language' => 'fr',
],
]
);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'App\Entity\Activity',
'mode' => 'string',
'status' => 'integer',
));
}
}

View File

@ -1,81 +0,0 @@
<?php
namespace App\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\ButtonType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Tetranz\Select2EntityBundle\Form\Type\Select2EntityType;
use FOS\CKEditorBundle\Form\Type\CKEditorType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\EntityManager;
class ActivitymessageType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('submit',
SubmitType::class, [
"label" => "Envoyer",
"attr" => ["class" => "btn btn-success"],
]
);
$builder->add('message',
CKEditorType::class, [
"mapped" => false,
"required" => true,
"config_name" => 'small_config',
"config" => [
'uiColor' => '#ffffff',
'height' => 150,
'filebrowserUploadRoute' => 'app_ckeditor_upload',
'language' => 'fr',
],
]
);
$builder->add('answers',
Select2EntityType::class, [
"label" => "Elèves",
"mapped" => false,
"required" => true,
"multiple" => true,
"remote_route" => "app_answer_select",
"remote_params" => ["activity"=>$options["id"]],
"class" => "App:Answer",
"primary_key" => "id",
"text_property" => "displayname",
"minimum_input_length" => 0,
"page_limit" => 100,
"allow_clear" => true,
"delay" => 250,
"cache" => false,
"cache_timeout" => 60000,
"language" => "fr",
"placeholder" => "Selectionner des élèves",
]
);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'App\Entity\Activity',
'mode' => 'string',
'id' => 'integer',
));
}
}

View File

@ -1,71 +0,0 @@
<?php
namespace App\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\ButtonType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Tetranz\Select2EntityBundle\Form\Type\Select2EntityType;
use FOS\CKEditorBundle\Form\Type\CKEditorType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\EntityManager;
class AnswerType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('submit',
SubmitType::class, [
"label" => "Valider",
"attr" => ["class" => "btn btn-success"],
]
);
if($options["status"]<10 && $options["activitystatus"] == 1) {
$builder->add('returned',
SubmitType::class, [
"label" => "Rendre l'activité",
"attr" => [
"class" => "btn btn-success",
"data-method" => "submit",
"data-confirm" => "Confirmez vous ? Une foi rendues, vous ne pourrez plus modifier l'activité."],
]
);
}
$builder->add('answer',
CKEditorType::class, [
"disabled" => ($options["status"]>=10||$options["activitystatus"]!=1),
"required" => false,
"config" => [
'uiColor' => '#ffffff',
'height' => 400,
'filebrowserUploadRoute' => 'app_ckeditor_upload',
'language' => 'fr',
],
]
);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'App\Entity\Answer',
'mode' => 'string',
'status' => 'integer',
'activitystatus' => 'integer'
));
}
}

View File

@ -1,83 +0,0 @@
<?php
namespace App\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\ButtonType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Tetranz\Select2EntityBundle\Form\Type\Select2EntityType;
use FOS\CKEditorBundle\Form\Type\CKEditorType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\EntityManager;
class CorrectedType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('submit',
SubmitType::class, [
"label" => "Valider",
"attr" => ["class" => "btn btn-success"],
]
);
if($options["status"]>=10 && $options["status"]<15 && $options["activitystatus"]==1) {
$builder->add('corrected',
SubmitType::class, [
"label" => "Rendre le corrigé",
"attr" => [
"class" => "btn btn-success",
"data-method" => "submit",
"data-confirm" => "Confirmez vous ? Une foi corrigé, vous ne pourrez plus modifier l'activité."],
]
);
$builder->add('canceled',
SubmitType::class, [
"label" => "Permettre à l'élève de revoir sa copie",
"attr" => [
"class" => "btn btn-danger",
"data-method" => "submit",
"data-confirm" => "Confirmez vous ? L'élève pourra modifier de nouveau son activité."],
]
);
}
if($options["status"]>=10) {
$builder->add('answercorrected',
CKEditorType::class, [
"disabled" => ($options["status"]>=15 || $options["activitystatus"]!=1),
"required" => false,
"config" => [
'uiColor' => '#ffffff',
'height' => 400,
'filebrowserUploadRoute' => 'app_ckeditor_upload',
'language' => 'fr',
],
]
);
}
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'App\Entity\Answer',
'mode' => 'string',
'status' => 'integer',
'activitystatus' => 'integer'
));
}
}

View File

@ -1,62 +0,0 @@
<?php
namespace App\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\ButtonType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Tetranz\Select2EntityBundle\Form\Type\Select2EntityType;
use FOS\CKEditorBundle\Form\Type\CKEditorType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\EntityManager;
class DocumentType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('submit',
SubmitType::class, [
"label" => "Valider",
"attr" => ["class" => "btn btn-success no-print"],
]
);
$builder->add('name',
TextType::class, [
"label" =>"Nom",
]
);
$builder->add('description',
CKEditorType::class, [
"required" => false,
"config" => [
'uiColor' => '#ffffff',
'height' => 300,
'filebrowserUploadRoute' => 'app_ckeditor_upload',
'language' => 'fr',
],
]
);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'App\Entity\Document',
'mode' => 'string',
));
}
}

View File

@ -1,52 +0,0 @@
<?php
namespace App\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\ButtonType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Tetranz\Select2EntityBundle\Form\Type\Select2EntityType;
use FOS\CKEditorBundle\Form\Type\CKEditorType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\EntityManager;
class MessageType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('message',
CKEditorType::class, [
"disabled" => ($options["status"]>=10),
"required" => false,
"config_name" => 'small_config',
"config" => [
'uiColor' => '#ffffff',
'height' => 150,
'filebrowserUploadRoute' => 'app_ckeditor_upload',
'language' => 'fr',
],
]
);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'App\Entity\Message',
'mode' => 'string',
'status' => 'integer',
));
}
}

View File

@ -0,0 +1,59 @@
{% extends 'base.html.twig' %}
{% block body %}
{{ form_start(form) }}
<h1 class="page-header">
{% if mode=="update" %}
Modification JOB
{% endif %}
</h1>
{{ form_widget(form.submit) }}
<a class="btn btn-secondary" href={{ path('app_cron') }}>Annuler</a>
<br><br>
{% if app.session.flashbag.has('error') %}
<div class='alert alert-danger' style='margin: 5px 0px'>
<strong>Erreur</strong><br>
{% for flashMessage in app.session.flashbag.get('error') %}
{{ flashMessage }}<br>
{% endfor %}
</div>
{% endif %}
{% if app.session.flashbag.has('notice') %}
<div class='alert alert-info' style='margin: 5px 0px'>
<strong>Information</strong><br>
{% for flashMessage in app.session.flashbag.get('notice') %}
{{ flashMessage }}<br>
{% endfor %}
</div>
{% endif %}
<div class="card">
<div class="card-header">
<i class="fa fa-pencil-alt fa-fw"></i> Informations
</div>
<div class="card-body">
{{ form_row(form.command) }}
{{ form_row(form.jsonargument) }}
{{ form_row(form.statut) }}
{{ form_row(form.repeatcall) }}
{{ form_row(form.repeatinterval) }}
{{ form_row(form.nextexecdate) }}
</div>
</div>
{{ form_end(form) }}
{% endblock %}
{% block localjavascript %}
$(document).ready(function() {
$("#command").focus();
});
{% endblock %}

View File

@ -0,0 +1,54 @@
{% extends "base.html.twig" %}
{% block body %}
<h1 class="page-header">
JOBS
</h1>
<div class="card">
<div class="card-header">
<i class="fa fa-table fa-fw"></i> Liste des Jobs
</div>
<div class="card-body">
<div class="dataTable_wrapper">
<table class="table table-striped table-bordered table-hover" id="dataTables" style="width:100%">
<thead>
<tr>
<th width="70px" class="no-sort">Action</th>
<th>Prochaine exécution</th>
<th>Command</th>
<th>Description</th>
<th>Statut</th>
</tr>
</thead>
<tbody>
{% for cron in crons %}
<tr>
<td>
<a href="{{path("app_cron_update",{id:cron.id})}}"><i class="fa fa-file"></i></a>
</td>
<td>{{cron.nextexecdate|date("d/m/Y H:i")}}</td>
<td>{{cron.command}}</td>
<td>{{cron.description}}</td>
<td>{{cron.statutlabel}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endblock %}
{% block localjavascript %}
$(document).ready(function() {
$('#dataTables').DataTable({
columnDefs: [ { "targets": "no-sort", "orderable": false }, { "targets": "no-string", "type" : "num" } ],
responsive: true,
iDisplayLength: 100,
order: [[ 1, "asc" ]]
});
});
{% endblock %}

View File

@ -0,0 +1,16 @@
{% extends 'base.html.twig' %}
{% block body %}
<h1 class="page-header">
Télécharger les logs
</h1>
{% if appCron %}
<a class="btn btn-secondary" href={{ path("app_cron_getlog",{"id":"cron"}) }}>Log CRON</a>
{% endif %}
<a class="btn btn-secondary" href={{ path("app_cron_getlog",{"id":"prod"}) }}>Log PROD</a>
<a class="btn btn-secondary" href={{ path("app_cron_getlog",{"id":"dev"}) }}>Log DEV</a>
{% if appCron %}
<a class="btn btn-secondary" href={{ path("app_cron_getlog",{"id":"dump"}) }}>Dump de la Base</a>
{% endif %}
{% endblock %}

View File

@ -0,0 +1,36 @@
{% extends 'base.html.twig' %}
{% block encorelinktags %}
{{ encore_entry_link_tags('dropzone') }}
{% endblock encorelinktags %}
{% block body %}
<h3 class="page-header"></h3>
<button class="btn btn-secondary" onClick="closeModal();">Annuler</button>
<form action="{{ oneup_uploader_endpoint('avatar') }}" class="dropzone" id="MyDropZone" style="margin-top:10px">
{% endblock %}
{% block encorescripttags %}
{{ encore_entry_script_tags('dropzone') }}
{% endblock %}
{% block localjavascript %}
window.parent.$(".modal-title").html("ETAPE 1 - Téléchargez votre image");
Dropzone.options.MyDropZone = {
maxFiles: 1,
acceptedMimeTypes: 'image/*',
//renameFilename: false,
success: function(file, response){
$(location).attr('href',"{{ path('app_crop02') }}");
}
}
function closeModal() {
window.parent.$("#extraLargeModal").modal('hide');
}
{% endblock %}

View File

@ -0,0 +1,71 @@
{% extends 'base.html.twig' %}
{% block body %}
{{ form_start(form) }}
{{ form_widget(form.submit) }}
<button class="btn btn-secondary" onClick="closeModal();">Annuler</button>
<div id='preview' style='overflow:hidden; width:90px; height:90px; position: absolute; top: 0px; right: 10px;'>
<img src="/{{ appAlias }}/uploads/avatar/{{ app.session.get('uploadavatar') }}" style='position: relative;' alt='Thumbnail Preview' />
</div>
<div style="width:800px; height:590px; overflow:hidden; margin:65px auto 0px auto;">
<div id="largeimg" class="crop-select-js" style="width:800px;">
</div>
</div>
{{ form_end(form) }}
{% endblock %}
{% block localjavascript %}
function move(data) {
$('#form_x').val(data.xScaledToImage);
$('#form_y').val(data.yScaledToImage);
preview();
}
function resize(data) {
$('#form_w').val(data.widthScaledToImage);
$('#form_h').val(data.heightScaledToImage);
preview();
}
function preview(data) {
var scaleX = 90 / $('#form_w').val();
var scaleY = 90 / $('#form_h').val();
$('#preview img').css({
width: Math.round(scaleX * $('#largeimg').width()) + 'px',
height: Math.round(scaleY * $('#largeimg').height()) + 'px',
marginLeft: '-' + Math.round(scaleX * $('#form_x').val()) + 'px',
marginTop: '-' + Math.round(scaleY * $('#form_y').val()) + 'px'
});
}
function reportThumb() {
window.parent.$("#user_avatar").val("thumb_{{ app.session.get('uploadavatar') }}");
window.parent.$("#user_avatar_img").attr("src","/{{ appAlias }}/uploads/avatar/thumb_{{ app.session.get('uploadavatar') }}");
closeModal();
}
function closeModal() {
window.parent.$("#extraLargeModal").modal('hide');
}
$(document).ready(function() {
window.parent.$(".modal-title").html("ETAPE 2 - Découper votre image");
$('#largeimg').CropSelectJs({
imageSrc: "/{{ appAlias }}/uploads/avatar/{{ app.session.get('uploadavatar') }}",
selectionResize: function(data) { resize(data); },
selectionMove: function(data) { move(data); },
});
$('#largeimg').CropSelectJs('setSelectionAspectRatio',1);
});
{% endblock %}

View File

@ -0,0 +1,175 @@
{% extends 'form_div_layout.html.twig' %}
{# Voir https://github.com/symfony/symfony/blob/master/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig #}
{# On commence par simplement ajouter le form-group au row de nos formulaires #}
{% block form_row -%}
{% set attr = attr|merge({'help': (attr.help|default(true)) }) %}
<div class="form-group {{ errors|length > 0 ? 'has-error' : '' }}">
{{- form_label(form) }}
{{- form_widget(form) }}
{{ form_errors(form) }}
</div>
{%- endblock form_row %}
{# Puis on modifie très simplement nos input et textarea
les plus importants pour y ajouter le class imposée par Bootstrap 3 #}
{% block textarea_widget %}
{% set attr = attr|merge({'class': attr.class|default('') ~ ' form-control'}) %}
{{ parent() }}
{% endblock textarea_widget %}
{% block form_widget_simple %}
{% set attr = attr|merge({'class': attr.class|default('') ~ ' form-control'}) %}
{{ parent() }}
{% endblock form_widget_simple %}
{% block form_label -%}
{% set label_attr = label_attr|merge({'class': (label_attr.class|default('') ~ ' control-label')|trim}) %}
{% if 'checkbox' not in block_prefixes %}
{% if label is not same as(false) -%}
{% if not compound -%}
{% set label_attr = label_attr|merge({'for': id}) %}
{%- endif %}
{% if required -%}
{% set label_attr = label_attr|merge({'class': (label_attr.class|default('') ~ ' required')|trim}) %}
{%- endif %}
{% if label is empty -%}
{% set label = name|humanize %}
{%- endif -%}
<label{% for attrname, attrvalue in label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}>
{{ label|trans({}, translation_domain)|raw }}
<span class="mandatory">{% if required %}*{% endif %}</span>
</label>
{%- endif %}
{% endif %}
{%- endblock form_label %}
{# et enfin les erreurs #}
{% block form_errors %}
{% if errors|length > 0 %}
{% if attr.help is defined and attr.help %}
<p class="help-block text-danger">
{% for error in errors %}
{{ error.message }}<br />
{% endfor %}
</p>
{% else %}
<div class="alert alert-danger alert-dismissible">
<button type="button" class="close" data-dismiss="alert">
<span aria-hidden="true">&times;</span>
<span class="sr-only">Close</span>
</button>
{% for error in errors %}
{{ error.message|raw }}<br />
{% endfor %}
</div>
{% endif %}
{% endif %}
{% endblock form_errors %}
{# Personnalisation des boutons #}
{% block button_widget -%}
{% if label is empty -%}
{% set label = name|humanize %}
{%- endif -%}
{% set attr = attr|merge({'class': (attr.class|default('') ~ '')|trim}) %}
<button type="{{ type|default('button') }}" {{ block('button_attributes') }}>{{
label|trans({}, translation_domain) }}
{% if type is defined and type == 'submit' -%}
{% endif %}
</button>
{%- endblock button_widget %}
{# Personnalisation des attributs des boutons #}
{% block button_attributes -%}
{% if type is defined and type == 'submit' -%}
{% set class = 'btn-primary' %}
{% else %}
{% set class = 'btn-default' %}
{%- endif -%}
{% set attr = attr|merge({'class': (attr.class|default('') ~ ' btn ' ~ class)|trim}) %}
{{ parent() }}
{%- endblock button_attributes %}
{# Personnalisation des select #}
{% block choice_widget_collapsed %}
{% set attr = attr|merge({'class': (attr.class|default('') ~ ' form-control')|trim}) %}
{{ parent() }}
{%- endblock choice_widget_collapsed %}
{% block choice_widget %}
{% if expanded %}
<ul {{ block('widget_container_attributes') }} style="list-style: none; padding-left: 0">
{% for child in form %}
<li>
{{ form_widget(child) }}
{{ form_label(child) }}
</li>
{% endfor %}
</ul>
{% else %}
{{ parent() }}
{% endif %}
{% endblock choice_widget %}
{% block checkbox_widget %}
<label for="{{ id }}">
<input type="checkbox" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />
{{ label|trans({}, translation_domain) }}</label>
{% endblock checkbox_widget %}
{% block radio_widget %}
<label for="{{ id }}">
<input type="radio" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />
{{ label|trans({}, translation_domain) }}
</label>&nbsp;&nbsp;
{% endblock radio_widget %}
{# Inline date marcro #}
{% macro date_form_widget(form) %}
<div class="col col-xs-4">
{{ form_widget(form) }}
</div>
{% endmacro %}
{# Inline date #}
{% block date_widget %}
{% if widget == 'single_text' %}
{{ block('form_widget_simple') }}
{% else %}
{% import _self as self %}
<div class="row">
{{ date_pattern|replace({
'{{ year }}': self.date_form_widget(form.year),
'{{ month }}': self.date_form_widget(form.month),
'{{ day }}': self.date_form_widget(form.day),
})|raw }}
</div>
{% endif %}
{% endblock date_widget %}
{# Inline date_time
{% block time_widget %}
{% if widget == 'single_text' %}
{{ block('form_widget_simple') }}
{% else %}
{% import _self as self %}
<div class="row">
{{ time_pattern|replace({
'{{ hour }}': self.date_form_widget(form.hour),
'{{ minute }}': self.date_form_widget(form.minute),
})|raw }}
</div>
{% endif %}
{% endblock time_widget %}
#}
{% block file_widget %}
{% set type = type|default('file') %}
<input type="{{ type }}" {{ block('widget_attributes') }} />
{% endblock file_widget %}

View File

@ -0,0 +1,64 @@
{% extends 'base.html.twig' %}
{% block body %}
{{ form_start(form) }}
<h1 class="page-header">
{% if mode=="update" %}
Modification GROUPE
{% elseif mode=="submit" %}
Création GROUPE
{% endif %}
</h1>
{{ form_widget(form.submit) }}
<a class="btn btn-secondary" href={{ path('app_group') }}>Annuler</a>
{% if mode=="update" %}
<a href="{{ path('app_group_delete',{'id':group.id}) }}"
class="btn btn-danger float-right"
data-method="delete"
data-confirm="Êtes-vous sûr de vouloir supprimer cet entregistrement ?">
Supprimer
</a>
{% endif %}
<br><br>
{% if app.session.flashbag.has('error') %}
<div class='alert alert-danger' style='margin: 5px 0px'>
<strong>Erreur</strong><br>
{% for flashMessage in app.session.flashbag.get('error') %}
{{ flashMessage }}<br>
{% endfor %}
</div>
{% endif %}
{% if app.session.flashbag.has('notice') %}
<div class='alert alert-info' style='margin: 5px 0px'>
<strong>Information</strong><br>
{% for flashMessage in app.session.flashbag.get('notice') %}
{{ flashMessage }}<br>
{% endfor %}
</div>
{% endif %}
<div class="card">
<div class="card-header">
<i class="fa fa-pencil-alt fa-fw"></i> Informations
</div>
<div class="card-body">
{{ form_row(form.name) }}
{{ form_row(form.users) }}
</div>
</div>
{{ form_end(form) }}
{% endblock %}
{% block localjavascript %}
$(document).ready(function() {
$("#group_name").focus();
});
{% endblock %}

View File

@ -0,0 +1,61 @@
{% extends "base.html.twig" %}
{% block body %}
<h1 class="page-header">
GROUPES
</h1>
<p><a class="btn btn-success" href={{ path('app_group_submit') }}>Ajouter</a></p>
<div class="card">
<div class="card-header">
<i class="fa fa-table fa-fw"></i> Liste des Groupes
</div>
<div class="card-body">
<div class="dataTable_wrapper">
<table class="table table-striped table-bordered table-hover" id="dataTables" style="width:100%">
<thead>
<tr>
<th width="70px" class="no-sort">Action</th>
<th>Nom</th>
<th>Source</th>
</tr>
</thead>
<tbody>
{% for group in groups %}
<tr>
<td>
{% if not group.ldapfilter and not group.idexternal %}
<a href="{{path("app_group_update",{id:group.id})}}"><i class="fa fa-file"></i></a>
{% endif %}
</td>
<td>{{group.name}}</td>
<td>
{% if group.ldapfilter %}
LDAP
{% elseif group.idexternal %}
Ninegate
{% else %}
Interne
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endblock %}
{% block localjavascript %}
$(document).ready(function() {
$('#dataTables').DataTable({
columnDefs: [ { "targets": "no-sort", "orderable": false }, { "targets": "no-string", "type" : "num" } ],
responsive: true,
iDisplayLength: 100,
order: [[ 1, "asc" ]]
});
});
{% endblock %}

View File

@ -0,0 +1,7 @@
{% extends "base.html.twig" %}
{% block body %}
{% endblock %}

View File

@ -0,0 +1,8 @@
{% extends "base.html.twig" %}
{% block body %}
{% endblock %}

View File

@ -0,0 +1,36 @@
{% extends "base.html.twig" %}
{% block localstyle %}
body {
background-color: #efefef;
}
.homecard {
padding-top: 20px;
}
{% endblock %}
{% block body %}
<div style="text-align:center">
<img src="/{{appAlias}}/images/logo.png" style="height:120px;margin-top:10px;"><br>
<h1>{{appName}}</h1>
<form action="{{ path('app_login') }}" method="post">
<div class="card homecard" style="width:400px; margin:auto">
<div class="card-body">
{% if error %}
<div class="alert alert-danger">{{ error.messageKey|trans(error.messageData, 'security') }}</div>
{% endif %}
<label for="username">Login</label>
<input type="text" id="username" name="_username" value="{{ last_username }}" class="form-control" style="margin-bottom:15px;" />
<label for="password">Password</label>
<input type="password" id="password" name="_password" class="form-control" style="margin-bottom:15px;" />
<input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}">
<input type="submit" name="login" class="btn btn-success form-control" />
</div>
</div>
</form>
</div>
{% endblock %}

View File

@ -0,0 +1,9 @@
{% block subject %}
{{ subject }}
{% endblock %}
{% block body %}
{% autoescape %}
<p>{{ body|raw }}</p>
{% endautoescape %}
{% endblock %}

View File

@ -0,0 +1,23 @@
$(document).ready(function() {
var doit = true;
$("a[data-method]").on('click',function(){
if($(this).data('confirm')){
doit = confirm($(this).data('confirm'));
if(!doit) return false;
}
});
$("button[data-method]").on('click',function(){
if($(this).data('confirm')){
doit = confirm($(this).data('confirm'));
if(!doit) return false;
}
});
});
function ModalLoad(idmodal,title,path) {
$("#"+idmodal+" .modal-header h4").text(title);
$("#"+idmodal+" #framemodal").attr("src",path);
$("#"+idmodal).modal("show");
}

View File

@ -0,0 +1,33 @@
<div id="sidebar" class="collapse">
<ul class="nav">
{% if is_granted('ROLE_ADMIN') %}
<br>
<li class="title">Administration</li>
<li>
<a href="{{path("app_user")}}">
<i class="fa fa-user"></i>Utilisateurs
</a>
</li>
<li>
<a href="{{path("app_group")}}">
<i class="fa fa-users"></i>Groupes
</a>
</li>
{% if appCron %}
<li>
<a href="{{path("app_cron")}}">
<i class="fa fa-cogs"></i>Jobs
</a>
</li>
{% endif %}
<li class="last">
<a href="{{path("app_cron_log")}}">
<i class="fa fa-list-alt"></i>Logs / Dump
</a>
</li>
{% endif %}
</ul>
</div>

View File

@ -0,0 +1,149 @@
/* global */
h1{
padding: 40px 0px 9px 0px;
border-bottom: 1px solid #eee;
}
.nav a{
background: none;
color: #CFD8DC;
font-size: 14px;
padding: 5px 0px 5px 25px;
display: block;
}
/* Sidebar Styles */
.contentsidebar {
margin-left:250px;
}
#sidebar {
z-index: 1000;
position: fixed;
left: 250px;
width: 250px;
height: 100%;
margin-left: -250px;
overflow-y: auto;
background: #37474F;
-webkit-transition: all 0.5s ease;
-moz-transition: all 0.5s ease;
-o-transition: all 0.5s ease;
transition: all 0.5s ease;
}
#sidebar header {
background-color: #263238;
font-size: 20px;
line-height: 52px;
text-align: center;
}
#sidebar header a {
color: #fff;
display: block;
text-decoration: none;
}
#sidebar header a:hover {
color: #fff;
}
#sidebar .nav{
display: block;
}
#sidebar .nav a {
padding: 0px 10px 5px 10px;
}
#sidebar .nav .last{
border-bottom: 5px solid #455A64;
padding-bottom:5px;
}
#sidebar .title {
color: #CFD8DC;
font-size: 16px;
padding: 0px 10px 0px 10px;
display: block;
text-transform: uppercase;
margin-left: 0px !important;
font-weight: bold;
}
#sidebar .nav .last{
border-bottom: 5px solid #455A64;
padding-bottom:5px;
}
#sidebar .nav a:hover{
background: none;
color: #ECEFF1;
}
#sidebar .nav a .fa{
margin-right: 5px;
}
#sidebar .nav .select-control {
padding: 0px 10px 5px 10px;
margin-top: -12px;
}
.avatar {
background-color: #343a40;
width: 35px;
height: 35px;
border-radius: 100%;
margin-top: -5px;
}
.avatar.big{
width: 90px;
height: 90px;
margin-bottom: 10px;
}
@media (max-width: 991px) {
.contentsidebar {
margin-left: auto;
}
#sidebar {
position: static;
margin:0px -15px;
width: auto;
}
}
a.btn {
color:#ffffff;
}
.btn-link {
padding:0px;
width:25px;
}
.media-body p {
font-size :12px;
margin-bottom:0px;
}
@media (min-width: 992px) {
#sidebar {
display: block;
}
}
{% if useheader is defined and useheader %}
#main {
padding-top:55px;
}
{% endif %}
th.dt-center, td.dt-center { text-align: center; }

View File

@ -0,0 +1,129 @@
{% extends 'base.html.twig' %}
{% block body %}
{{ form_start(form) }}
<h1 class="page-header">
{% if mode=="update" %}
Modification UTILISATEUR
{% elseif mode=="submit" %}
Création UTILISATEUR
{% elseif mode=="profil" %}
Profil UTILISATEUR
{% endif %}
</h1>
{{ form_widget(form.submit) }}
{% if mode=="profil" %}
<a class="btn btn-secondary" href={{ path('app_home') }}>Annuler</a>
{% else %}
<a class="btn btn-secondary" href={{ path('app_user') }}>Annuler</a>
{% endif %}
<br><br>
{% if app.session.flashbag.has('error') %}
<div class='alert alert-danger' style='margin: 5px 0px'>
<strong>Erreur</strong><br>
{% for flashMessage in app.session.flashbag.get('error') %}
{{ flashMessage }}<br>
{% endfor %}
</div>
{% endif %}
{% if app.session.flashbag.has('notice') %}
<div class='alert alert-info' style='margin: 5px 0px'>
<strong>Information</strong><br>
{% for flashMessage in app.session.flashbag.get('notice') %}
{{ flashMessage }}<br>
{% endfor %}
</div>
{% endif %}
<div style="width:90px; margin:auto;">
{% set avatar= "noavatar.png" %}
{% if user.avatar %}
{% set avatar= user.avatar %}
{% endif %}
<img id="user_avatar_img" src="{{ avatar|urlavatar }}" class="avatar big" >
{{ form_widget(form.avatar) }}
{% if appMasteridentity=="LDAP" %}
<a class="btn btn-info" style="width:100%; margin-bottom:15px;" onClick="showModal();" title='Ajouter un avatar'>Modifier</a>
{% endif %}
</div>
<div class="row justify-content-md-center">
<div class="col-md-6">
<div class="card">
<div class="card-header">
<i class="fa fa-pencil-alt fa-fw"></i> Informations
</div>
<div class="card-body">
{{ form_row(form.username) }}
{% if form.password is defined %}
{{ form_row(form.password) }}
{%endif%}
{{ form_row(form.lastname) }}
{{ form_row(form.firstname) }}
{{ form_row(form.email) }}
{{ form_row(form.apikey) }}
</div>
</div>
</div>
{% if form.roles is defined %}
<div class="col-md-6">
<div class="card">
<div class="card-header">
<i class="fa fa-pencil-alt fa-fw"></i> Organisation
</div>
<div class="card-body">
{{ form_row(form.groups) }}
{{ form_row(form.roles) }}
</div>
</div>
</div>
{%endif%}
</div>
{{ form_end(form) }}
<div id="extraLargeModal" class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog modal-xl">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"></h5>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
</div>
<div class="modal-body">
<iframe id="frameModal" frameborder=0 width="100%" height="700px"></iframe>
</div>
</div>
</div>
</div>
{% endblock %}
{% block localjavascript %}
$(document).ready(function() {
$("#user_password_first").val("");
$("#user_login").focus();
});
$("#user_avatar_img").on('load', function() {
})
$("#user_avatar_img").on('error', function(){
console.log("la");
var imgSrc = $(this).attr('src');
if(imgSrc!="/{{appAlias}}/uploads/avatar/")
$(this).attr('src',imgSrc);
});
function showModal() {
$("#frameModal").attr("src","{{path("app_crop01")}}");
$("#extraLargeModal").modal("show");
}
{% endblock %}

View File

@ -0,0 +1,73 @@
{% extends "base.html.twig" %}
{% block body %}
<h1 class="page-header">
UTILISATEURS
</h1>
<div class="card">
<div class="card-header">
<i class="fa fa-table fa-fw"></i> Liste des Utilisateurs
</div>
<div class="card-body">
<div class="dataTable_wrapper">
<table class="table table-striped table-bordered table-hover" id="dataTables" style="width:100%">
<thead>
<tr>
<th width="70px" class="no-sort">Action</th>
<th width="70px" class="no-sort">Avatar</th>
<th>Login</th>
<th>Prénom</th>
<th>Nom</th>
<th>Rôles</th>
<th>Groupes</th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr>
<td>
<a href="{{path("app_user_update",{id:user.id})}}"><i class="fa fa-file"></i></a>
</td>
<td><img id="user_avatar_img" src="{{ user.avatar|urlavatar }}" class="avatar" ></td>
<td>{{user.username}}</td>
<td>{{user.firstname}}</td>
<td>{{user.lastname}}</td>
<td>
{%for role in user.roles %}
{%if role=="ROLE_ADMIN" %}
Administrateur<br>
{%elseif role=="ROLE_MODO" %}
Modérateur<br>
{%elseif role=="ROLE_MASTER" %}
Master<br>
{%elseif role=="ROLE_USER" %}
Utilisateur<br>
{%endif%}
{% endfor %}
</td>
<td>
{% for group in user.groups %}
{{ group.name }}<br>
{% endfor %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endblock %}
{% block localjavascript %}
$(document).ready(function() {
$('#dataTables').DataTable({
columnDefs: [ { "targets": "no-sort", "orderable": false }, { "targets": "no-string", "type" : "num" } ],
responsive: true,
iDisplayLength: 100,
order: [[ 2, "asc" ]]
});
});
{% endblock %}

View File

@ -0,0 +1,138 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html"; charset="utf-8" />
<title>{% block title %}{{ appName }}{% endblock %}</title>
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
{{ encore_entry_link_tags('app') }}
{% block encorelinktags %}
{% endblock encorelinktags %}
<link rel="shortcut icon" href="/{{ appAlias }}/images/logo.png" />
</head>
<style>
{{ include('Include/style.css.twig') }}
{% block localstyle %}
{% endblock %}
</style>
<body>
{% if useheader is defined and useheader %}
<nav class="navbar navbar-expand-lg navbar-dark fixed-top bg-dark">
<a class="navbar-brand" href="{{ path('app_home')}}">
<img src="/{{appAlias}}/images/logo.png" style="height:30px;margin-top:-3px;">
{{appName}}
</a>
{% if usesidebar is defined and usesidebar %}
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#sidebar" aria-controls="sidebar" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
{% endif %}
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
</ul>
</div>
<ul class="nav navbar-top-links navbar-right">
{% if app.user %}
<li>
<a href="{{path("app_user_profil")}}">
<img src="{{app.user.avatar|urlavatar}}" class="avatar">
</a>
</li>
{% endif %}
{% if is_granted('ROLE_ADMIN') %}
<li>
<a href="{{path("app_admin")}}"><i class="fa fa-cog fa-fw"></i></a>
</li>
{% endif %}
<li>
{% if app.user %}
{% if appAuth=="MYSQL" %}
<a href="{{path("app_logout")}}"><i class="fa fa-sign-out-alt fa-fw"></i></a>
{% elseif appAuth=="CAS" %}
<a href="{{path("app_logoutcas")}}"><i class="fa fa-sign-out-alt fa-fw"></i></a>
{% endif %}
{% else %}
{% if appAuth=="MYSQL" %}
<a href="{{path("app_login")}}"><i class="fa fa-sign-in-alt fa-fw"></i></a>
{% elseif appAuth=="CAS" %}
<a href="{{path("app_logincas")}}"><i class="fa fa-sign-in-alt fa-fw"></i></a>
{% endif %}
{% endif %}
</li>
</ul>
</nav>
{% endif %}
<main id="main" class="container-fluid">
{% set contentsidebar="" %}
{% if usesidebar is defined and usesidebar %}
{% set contentsidebar="contentsidebar" %}
{{ include('Include/sidebar.html.twig') }}
{%endif%}
<div id="mycontent" class="content {{contentsidebar}}">
{% block body %}
{% endblock %}
</div>
</main>
<div id="mymodal" class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Modification Evènement</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<iframe id="framemodal" frameborder=0 width="100%" height="600px"></iframe>
</div>
</div>
</div>
</div>
{{ encore_entry_script_tags('app') }}
{% block encorescripttags %}
{% endblock %}
{% block localexternalscript %}
{% endblock %}
<script>
{{ include('Include/javascript.js.twig') }}
</script>
<script>
{% block localjavascript %}
{% endblock %}
</script>
{% if sondeUse %}
<script src='{{ sondeUrl }}?appli={{ appName }}'></script>
{% endif %}
</body>
</html>