This commit is contained in:
afornerot 2019-06-25 15:53:10 +02:00
parent dc9f198cce
commit 222676cf5b
14 changed files with 503 additions and 102 deletions

View File

@ -65,6 +65,7 @@ swiftmailer:
password: '%mailer_password%'
auth_mode: '%mailer_authmode%'
encryption: '%mailer_encryption%'
timeout: 5
stream-options:
ssl:
allow_self_signed : true
@ -97,6 +98,11 @@ oneup_uploader:
frontend: dropzone # or any uploader you use in the frontend
blogarticle:
frontend: dropzone # or any uploader you use in the frontend
importuser:
frontend: dropzone # or any uploader you use in the frontend
namer: cadoles.core.upload.namer.same
storage:
directory: "%kernel.root_dir%/../uploads/importuser"
file:
frontend: dropzone # or any uploader you use in the frontend
namer: cadoles.core.upload.namer.same

View File

@ -27,6 +27,7 @@ class SynchroCommand extends Command
private $output;
private $filesystem;
private $rootlog;
private $cptcommit;
protected function configure()
{
@ -146,6 +147,8 @@ class SynchroCommand extends Command
}
// On parcours les niveaux 01 pour connaitre les filtres ldap associé
$nbusers=0;
$this->cptcommit=0;
$datas=$this->em->createQueryBuilder()->select('table')->from('CadolesCoreBundle:Niveau01','table')->where('table.ldapfilter IS NOT NULL')->getQuery()->getResult();
foreach($datas as $data) {
// On execute le filtre d'appartenance à ce niveau
@ -153,6 +156,9 @@ class SynchroCommand extends Command
// Pour chaque utilisateur ldap
foreach($results as $result) {
// Compteur de users
$nbusers++;
// Formatage du résultat
if(is_array($result[$ldap_username])) {
$result[$ldap_username]=$result[$ldap_username][0];
@ -202,9 +208,17 @@ class SynchroCommand extends Command
}
}
}
}
}
if(!$simulate&&$this->cptcommit>0&&($this->cptcommit%100==0)) {
$this->writelnred(" == COMMIT ==");
$this->em->flush();
}
}
}
if(!$simulate) {
$this->writelnred(" == COMMIT ==");
$this->em->flush();
}
$this->writeln('');
$this->writeln('== USERS GROUP ======================================');
@ -786,6 +800,7 @@ class SynchroCommand extends Command
else
$user->setRole("ROLE_USER");
$this->cptcommit++;
$this->em->persist($user);
}
@ -797,6 +812,7 @@ class SynchroCommand extends Command
if(in_array($username,$usersadmin))
$user->setRole("ROLE_ADMIN");
$this->cptcommit++;
$this->em->persist($user);
}

View File

@ -8,7 +8,7 @@ INSERT IGNORE INTO `niveau01` (`id`, `label`, `siren`) VALUES
(-100, 'DRAAF', '130007107');
INSERT IGNORE INTO `user` (`id`, `niveau01_id`, `username`, `firstname`, `lastname`, `password`, `email`, `avatar`, `role`,`siren`,`authlevel`) VALUES
(-100, -100, 'admin', 'Administrateur', 'draaf', '{SSHA}6LUh9OzkGYupIHk89S/DJV+tXmVglWPE
(-100, -100, 'admin', 'Administrateur', 'draaf', '{SSHA}EHcsvjQ0ZSD0/jiRa6+mC4AtCXMZesgA
', 'admin@ldapbundle.ac-arno.fr', 'admin.jpg', 'ROLE_ADMIN', '130007107', 'simple');
@ -27,6 +27,7 @@ INSERT IGNORE INTO `sidebar` (`id`, `parent_id`, `roworder`, `label`, `path`, `f
(1240, 1200, 1240, 'Groupes', 'cadoles_core_config_group', 'fa-users', 'ROLE_ADMIN,ROLE_MODO', ''),
(1250, 1200, 1250, 'Inscriptions', 'cadoles_core_config_registration', 'fa-pencil-square-o', 'ROLE_ADMIN,ROLE_MODO', ''),
(1260, 1200, 1260, 'Utilisateurs', 'cadoles_core_config_user', 'fa-child', 'ROLE_ADMIN,ROLE_MODO', ''),
(1270, 1200, 1270, 'Import Utilisateurs', 'cadoles_core_config_importuser', 'fa-download', 'ROLE_ADMIN,ROLE_MODO', 'importuser_activate'),
(1500, NULL, 1500, 'PORTAIL', NULL, 'fa-cubes', 'ROLE_ADMIN,ROLE_MODO', 'portal_activate'),
(1510, 1500, 1510, 'Pages', 'cadoles_portal_config_page', 'fa-file', 'ROLE_ADMIN,ROLE_MODO', 'portal_activate'),

View File

@ -13,11 +13,16 @@ use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\BufferedOutput;
use Symfony\Component\Console\Output\OutputInterface;
use Ramsey\Uuid\Uuid;
use Ramsey\Uuid\Exception\UnsatisfiedDependencyException;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Cadoles\CoreBundle\Entity\User;
use Cadoles\CoreBundle\Entity\UserGroup;
use Cadoles\CoreBundle\Entity\UserModo;
use Cadoles\CoreBundle\Entity\Niveau01;
use Cadoles\CoreBundle\Entity\Niveau02;
use Cadoles\CoreBundle\Form\UserType;
@ -574,6 +579,224 @@ class UserController extends Controller
return $this->updateAction($user->getId(),"user",$request);
}
public function importuserAction(Request $request) {
if($this->GetParameter("masteridentity")!="SQL")
throw $this->createNotFoundException('Permission denied');
return $this->render('CadolesCoreBundle:User:import.html.twig',[
'useheader' => true,
'usemenu' => false,
'usesidebar' => true,
]);
}
public function importuserfileAction()
{
return $this->render('CadolesCoreBundle:User:importfile.html.twig',[
'useheader' => false,
'usemenu' => false,
'usesidebar' => false,
]);
}
public function importuserfilectrlAction(Request $request)
{
// S'assurer que c'est un appel ajax
if (!$request->isXmlHttpRequest()) return new JsonResponse(array('message' => 'Interdit'), 400);
$em = $this->getDoctrine()->getManager();
$output=array();
$file = $request->request->get('file');
$csv = file_get_contents($this->get('kernel')->getRootDir()."/../".$file);
$tbfile = $this->csv_to_array($csv);
$error="";
if(empty($tbfile)||!$tbfile[0])
$error.="<p>Votre fichier CSV est mal formé, merci de le corriger<p>";
else {
// On s'assure que les données minimums sont présentes en colonne
if(!array_key_exists("login",$tbfile[0])) $error.="<p>Colonne login manquante</p>";
if(!array_key_exists("nom",$tbfile[0])) $error.="<p>Colonne nom manquante</p>";
if(!array_key_exists("email",$tbfile[0])) $error.="<p>Colonne email manquante</p>";
if(!array_key_exists("niveau01",$tbfile[0])) $error.="<p>Colonne niveau01 manquante</p>";
// On s'assure que toutes les colonnes sont des colonnes gérées par l'import
$tbkey=["login","prenom","nom","email","niveau01","niveau02","metier","fonction","nomusage","sexe","autreprenom","telephone","adresse","datenaissance","pays","ville","visible","role"];
foreach($tbfile[0] as $key => $value) {
if(!in_array($key,$tbkey))
$error.="<p>La colonne $key n'est pas une colonne gérée par l'import</p>";
}
// On vérifie les données
foreach($tbfile as $user) {
// On regarde si le login n'est pas déjà existant
$userbdd=$em->getRepository('CadolesCoreBundle:User')->findOneBy(["username"=>$user["login"]]);
if($userbdd) {
$error.="<p>Utilisateur = ".$user["login"]." existe déjà</p>";
}
if(strlen($user["login"])<5) $error.="<p>Utilisateur = ".$user["login"]." login trop court doit être >= 5</p>";
// On regarde si le email n'est pas déjà existant
$userbdd=$em->getRepository('CadolesCoreBundle:User')->findOneBy(["email"=>$user["email"]]);
if($userbdd) {
$error.="<p>Email = ".$user["email"]." existe déjà</p>";
}
// On regarde si le login / mail / nom n'est pas vide
if($user["login"]==""||$user["nom"]==""||$user["email"]=="")
$error.="<p>Valeur obligatoire pour login / nom / email</p>";
// On regarde si le niveau01 existe
$niveau01=$em->getRepository('CadolesCoreBundle:Niveau01')->findOneBy(["label"=>$user["niveau01"]]);
if(!$niveau01) $error.="<p>Niveau 01 = ".$user["niveau01"]." inexistant</p>";
// On regarde si le niveau02 existe
if(array_key_exists("niveau02",$user)&&$user["niveau02"]!="") {
$niveau02=$em->getRepository('CadolesCoreBundle:Niveau02')->findOneBy(["label"=>$user["niveau02"],"niveau01"=>$niveau01]);
if(!$niveau02) $error.="<p>Niveau 02 = ".$user["niveau02"]." inexistant</p>";
}
// On regarde si le sexe est correctement formatté
if(array_key_exists("sexe",$user)&&$user["sexe"]!="") {
if($user["sexe"]!="male"&&$user["sexe"]!="female")
$error.="<p>Sexe ne peut prendre que la valeur vide / male / female</p>";
}
// On regarde si la date de naissance est correctement formatté
if(array_key_exists("datenaissance",$user)&&$user["datenaissance"]!="") {
try {
$date = \DateTime::createFromFormat('d/m/Y', $user["datenaissance"]);
if(!$date) $error.="<p>Date de naissance mal formattée</p>";
}
catch (Exception $e) {
$error.="<p>Date de naissance mal formattée</p>";
}
}
// On regarde si la pays existe
if(array_key_exists("pays",$user)&&$user["pays"]!="") {
$country=$em->getRepository('CadolesCoreBundle:Country')->findOneBy(["label"=>$user["pays"]]);
if(!$country) $error.="<p>Pays = ".$user["pays"]." inexistant</p>";
}
// On regarde si la ville existe
if(array_key_exists("ville",$user)&&$user["ville"]!="") {
$city=$em->getRepository('CadolesCoreBundle:City')->findOneBy(["label"=>$user["ville"]]);
if(!$city) $error.="<p>Ville = ".$user["ville"]." inexistant</p>";
}
// On regarde si visible est correctement formatté
if(array_key_exists("visible",$user)&&$user["visible"]!="") {
if($user["visible"]!="oui"&&$user["sexe"]!="non")
$error.="<p>Visible ne peut prendre que la valeur vide / oui / non</p>";
}
// On regarde si visible est correctement formatté
if(array_key_exists("role",$user)&&$user["role"]!="") {
if($user["role"]!="ROLE_ADMIN"&&$user["role"]!="ROLE_MODO"&&$user["role"]!="ROLE_USER")
$error.="<p>Role ne peut prendre que la valeur vide / ROLE_ADMIN / ROLE_MODO / ROLE_USER</p>";
}
}
}
if($error!="") {
$output["status"]="KO";
$output["error"]=$error;
}
else {
$output["status"] ="OK";
$output["users"] ="";
$appname = $this->get('session')->get('appname');
$noreply = $this->getParameter('noreply');
// On importe
foreach($tbfile as $csvuser) {
$output["users"].="Création Utilisateur = ".$csvuser["login"]."<br>";
$user = new User();
$username = $csvuser["login"];
$password = Uuid::uuid4();
$email = $csvuser["email"];
$lastname = $csvuser["nom"];
$firstname = (array_key_exists("prenom",$csvuser)?$csvuser["prenom"]:null);
$niveau01 = $em->getRepository('CadolesCoreBundle:Niveau01')->findOneBy(["label"=>$csvuser["niveau01"]]);
$niveau02 = (array_key_exists("niveau02",$csvuser)?$em->getRepository('CadolesCoreBundle:Niveau02')->findOneBy(["label"=>$csvuser["niveau02"]]):null);
$job = (array_key_exists("metier",$csvuser)?$csvuser["metier"]:null);
$position = (array_key_exists("fonction",$csvuser)?$csvuser["fonction"]:null);
$usalname = (array_key_exists("nomusage",$csvuser)?$csvuser["nomusage"]:null);
$gender = (array_key_exists("sexe",$csvuser)?$csvuser["sexe"]:null);
$givensname = (array_key_exists("autreprenom",$csvuser)?$csvuser["autreprenom"]:null);
$telephonenumber = (array_key_exists("telephone",$csvuser)?$csvuser["telephone"]:null);
$postaladress = (array_key_exists("adresse",$csvuser)?$csvuser["adresse"]:null);
$birthdate = (array_key_exists("datenaissance",$csvuser)&&$csvuser["datenaissance"]!=""?$csvuser["datenaissance"]:null);
$birthdate = (!is_null($birthdate)?\DateTime::createFromFormat('d/m/Y', $csvuser["datenaissance"]):null);
$birthcountry = (array_key_exists("pays",$csvuser)?$em->getRepository('CadolesCoreBundle:Country')->findOneBy(["label"=>$csvuser["pays"]]):null);
$birthplace = (array_key_exists("ville",$csvuser)?$em->getRepository('CadolesCoreBundle:City')->findOneBy(["label"=>$csvuser["ville"]]):null);
$visible = (array_key_exists("visible",$csvuser)&&$csvuser["visible"]!=""?($csvuser["visible"]=="oui"):true);
$role = (array_key_exists("role",$csvuser)&&$csvuser["role"]!=""?$csvuser["role"]:"ROLE_USER");
$user->setUsername($username);
$user->setPassword($password);
$user->setEmail($email);
$user->setLastname($lastname);
$user->setFirstname($firstname);
$user->setNiveau01($niveau01);
$user->setNiveau02($niveau02);
$user->setJob($job);
$user->setPosition($position);
$user->setUsualname($usalname);
$user->setGender($gender);
$user->setGivensname($givensname);
$user->setTelephonenumber($telephonenumber);
$user->setPostaladress($postaladress);
$user->setBirthdate($birthdate);
$user->setBirthcountry($birthcountry);
$user->setBirthplace($birthplace);
$user->setVisible($visible);
$user->setVisible(true);
$user->setRole($role);
$user->setSiren($niveau01->getSiren());
$user->setSiret((!is_null($niveau02)?$niveau02->getSiret():null));
$user->setAuthlevel("simple");
$user->setBelongingpopulation("agent");
$em->persist($user);
$em->flush();
// Email à destination de l'inscript pour le prévenir qu'il dispose d'un compte
$url = $this->generateUrl('cadoles_core_resetpwd01', [], UrlGeneratorInterface::ABSOLUTE_URL);
$text ="Vous venez d'être inscrit au portail = ".$appname."\n\n";
$text.="Login = ".$username."\n";
$text.="Password = Merci de suivre le lien suivant pour définir votre password\n\n";
$texthtml=$text."<a href='$url'>$url</a>";
$text.=$url;
$template="template";
$mail_params=array(
"subject" => $appname." : Inscription automatique",
"body_html"=>nl2br($texthtml),
"body_text"=>$text
);
$to = $email;
$from = $noreply;
$fromName = $appname;
$message = $this->container->get('cadoles.core.service.mail');
$message->sendEmail($template, $mail_params, $to, $from, $fromName);
}
}
$response = new Response(json_encode($output));
$response->headers->set('Content-Type', 'application/json');
return $response;
}
protected function getDatas()
{
$em = $this->getDoctrine()->getManager();
@ -672,4 +895,21 @@ class UserController extends Controller
}
}
}
protected function csv_to_array($csv, $delimiter = ';', $enclosure = '', $escape = '\\', $terminator = "\n") {
$r = array();
$rows = explode($terminator,trim($csv));
$names = array_shift($rows);
$names = str_getcsv($names,$delimiter,$enclosure,$escape);
$nc = count($names);
foreach ($rows as $row) {
if (trim($row)) {
$values = str_getcsv($row,$delimiter,$enclosure,$escape);
if (!$values) $values = array_fill(0,$nc,null);
@$r[] = array_combine($names,$values);
}
}
return $r;
}
}

View File

@ -67,8 +67,17 @@
if($curentuser=="anon.") $roles=[];
else $roles=$curentuser->getRoles();
// Masteridentity
$masteridentity =$this->container->getParameter('masteridentity');
$session->set('masteridentity',$masteridentity);
// mode_auth
$mode_auth =$this->container->getParameter('mode_auth');
$session->set('mode_auth',$mode_auth);
// App activate
$app=[];
$app["importuser_activate"] =($masteridentity=="SQL");
$app["portal_activate"] =$this->container->getParameter('portal_activate');
$app["cron_activate"] =$this->container->getParameter('cron_activate');
$app["module_activate"] =$this->container->getParameter('module_activate');
@ -85,14 +94,6 @@
$app["activate_widpiwik"] =$this->container->getParameter('activate_widpiwik');
$app["activate_widwordpress"] =$this->container->getParameter('activate_widwordpress');
// Masteridentity
$masteridentity =$this->container->getParameter('masteridentity');
$session->set('masteridentity',$masteridentity);
// mode_auth
$mode_auth =$this->container->getParameter('mode_auth');
$session->set('mode_auth',$mode_auth);
// Chargement de la sidebar
$iconniveau01 =$this->container->getParameter('iconniveau01');
$labelsniveau01 =$this->container->getParameter('labelsniveau01');

View File

@ -47,6 +47,7 @@ class UserType extends AbstractType
$builder->add('firstname',
TextType::class, array(
"label" =>"Prénom",
"required" => false,
"disabled" => ($options["mode"]=="delete"||$options["masteridentity"]!="SQL"?true:false),
"attr" => array("class" => "form-control", "style" => "margin-bottom:15px")
)

View File

@ -224,6 +224,18 @@ cadoles_core_config_user_ajax_list:
path: /config/user/ajax/list
defaults: { _controller: CadolesCoreBundle:User:ajaxlist, access: config }
cadoles_core_config_importuser:
path: /config/importuser
defaults: { _controller: CadolesCoreBundle:User:importuser }
cadoles_core_config_importuser_file:
path: /config/importuserfile
defaults: { _controller: CadolesCoreBundle:User:importuserfile }
cadoles_core_config_importuser_filectrl:
path: /config/importuserfilectrl
defaults: { _controller: CadolesCoreBundle:User:importuserfilectrl }
#-- Access user
cadoles_core_profil:
path: /user

View File

@ -7,7 +7,7 @@
{{ form_start(form) }}
<h1 class="page-header">
Mot de passe oublié
Réinitialisation du mot de passe
</h1>
{{ form_widget(form.submit) }}

View File

@ -7,7 +7,7 @@
{{ form_start(form) }}
<h1 class="page-header">
Mot de passe oublié
Réinitialisation du mot de passe
</h1>
{{ form_widget(form.submit) }}

View File

@ -0,0 +1,72 @@
{% extends '@CadolesCore/base.html.twig' %}
{% block pagewrapper %}
<h1 class="page-header">Import Utilisateurs</h1>
<div class="panel panel-primary">
<div class="panel-heading">
<i class="fa fa-table fa-fw"></i>Importer votre fichier CSV
</div>
<div class="panel-body">
<div class="dataTable_wrapper">
<a class="btn btn-info" style="width:100%; margin-bottom:15px;" data-toggle="modal" data-target="#mymodal" onClick="ModalLoad('mymodal','Importuser','{{ path('cadoles_core_config_importuser_file') }}');" title='Ajouter un avatar'>Importer Fichier CSV</a>
<input type="text" id="file_value" name="file_value" required="required" class="form-control form-control" style="margin-bottom:15px">
</div>
Colonnes possibles<br>
<code>
login;prenom;nom;email;niveau01;niveau02;metier;fonction;nomusage;sexe;autreprenom;telephone;adresse;datenaissance;pays;ville;visible;role
</code><br><br>
Colonne obligatoire = login / nom / email / niveau01<br><br>
Sexe = vide / male / female<br>
Visible = vide / oui / non<br>
Rôle = vide / ROLE_USER / ROLE_MODO / ROLE_ADMIN<br><br>
Niveau01 & Niveau02 & Pays & Ville = doivent exister dans la base<br><br>
Importation impossible si login et/ou email déjà existant en base<br>
A chaque création un mail sera envoyé à l'utilisateur pour lui préceser qu'il est inscrit et qu'il devra suivre le process de reinitialisation de password pour ce connecter au portail.
</div>
</div>
<a id="exec" class="btn btn-danger" style="width:100%; margin-bottom:15px;" >EXECUTER L'IMPORT</a>
<div id='info'></div>
{% endblock %}
{% block localjavascript %}
$(document).ready(function() {
$( "#exec" ).click(function() {
if($("#file_value").val()=="")
alert( "Vous devez importer un fichier CSV" );
else {
$("#info").html("");
$("#info").append("<h1>Importation Utilisateur</h1>");
$("#info").append("<h2>Contrôle Cohérance du Fichier</h2>");
$.ajax({
method: "POST",
url: "{{ path('cadoles_core_config_importuser_filectrl') }}",
data: {
file:$("#file_value").val(),
},
success: function(data) {
console.log(data);
if(data.status=="OK") {
$("#info").append("<p>Fichier correct</p>");
$("#info").append("<h2>Importation</h2>");
$("#info").append("<p>"+data.users+"</p>");
}
else {
$("#info").append("<p style='color:red'>Fichier incorrect</p>");
$("#info").append("<p style='color:red'>Merci de corriger votre fichier</p>");
$("#info").append("<p style='color:red'>"+data.error+"</p>");
}
}
});
}
});
});
{% endblock %}

View File

@ -0,0 +1,34 @@
{% extends '@CadolesCore/base.html.twig' %}
{% block pagewrapper %}
<h3 class="page-header">Téléchargez votre Fichier CSV</h3>
<a class="btn btn-default" onClick="closeModal();">Annuler</a>
<form action="{{ oneup_uploader_endpoint('importuser') }}" class="dropzone" id="MyDropZone" style="margin-top:10px">
</form>
{% endblock %}
{% block localjavascript %}
Dropzone.options.MyDropZone = {
acceptedFiles: 'text/csv',
maxFiles: 1,
success: function( file, response ){
parent.$("#file_value").val("uploads/importuser/"+response["file"]);
closeModal();
}
}
function closeModal() {
window.parent.$("#mymodal").modal('hide');
}
$(window).load(function () {
// On vérifie que l'execution se fait bien dans le cadre d'une modal
if(!window.parent.$("#mymodal #framemodal").length) {
$(location).attr('href',"{{ path('cadoles_core_home') }}");
}
});
{% endblock %}

View File

@ -8,6 +8,8 @@ use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Command\LockableTrait;
use Cadoles\CronBundle\Entity\Cron;
@ -16,6 +18,7 @@ class CronCommand extends ContainerAwareCommand
private $output;
private $filesystem;
private $rootlog;
use LockableTrait;
protected function configure()
{
@ -40,8 +43,9 @@ class CronCommand extends ContainerAwareCommand
return false;
}
if($this->filesystem->exists($this->rootlog."cron.lock")) {
return false;
if (!$this->lock()) {
$this->output->writeln("CRON LOCK");
return 0;
}
$this->filesystem->appendToFile($this->rootlog.'cron.lock', "lock");
@ -90,7 +94,12 @@ class CronCommand extends ContainerAwareCommand
$parameter = new ArrayInput($jsonparameter);
// Executer la commande
try{
$returnCode = $command->run($parameter, $output);
}
catch(\Exception $e) {
$this->writelnred("JOB EN ERREUR");
}
// Flag de fin d'execution
$now=new \DateTime();
@ -121,12 +130,12 @@ class CronCommand extends ContainerAwareCommand
$entityManager->flush();
}
if($crons) {
$this->writelnred("==");
$this->writelnred("FIN CRON");
$this->writelnred("==");
$this->writelnred("");
$this->filesystem->remove($this->rootlog."cron.lock");
}
}
private function writelnred($string) {

View File

@ -49,7 +49,15 @@ class MailCommand extends Command
$tbparameter["--message-limit"]=100;
$tbparameter["--env"]="prod";
$parameter = new ArrayInput($tbparameter);
try{
$returnCode = $command->run($parameter, $output);
}
catch(\Exception $e) {
$this->writeln("");
$this->writelnred("Impossible d'envoyer des mails");
$this->writeln("");
return 0;
}
$this->writeln("");
return 1;

View File

@ -38,6 +38,7 @@ INSERT IGNORE INTO `sidebar` (`id`, `parent_id`, `roworder`, `label`, `path`, `f
(1240, 1200, 1240, 'Groupes', 'cadoles_core_config_group', 'fa-users', 'ROLE_ADMIN,ROLE_MODO', ''),
(1250, 1200, 1250, 'Inscriptions', 'cadoles_core_config_registration', 'fa-pencil-square-o', 'ROLE_ADMIN,ROLE_MODO', ''),
(1260, 1200, 1260, 'Utilisateurs', 'cadoles_core_config_user', 'fa-child', 'ROLE_ADMIN,ROLE_MODO', ''),
(1270, 1200, 1270, 'Import Utilisateurs', 'cadoles_core_config_importuser', 'fa-download', 'ROLE_ADMIN,ROLE_MODO', 'importuser_activate'),
(1500, NULL, 1500, 'PORTAIL', NULL, 'fa-cubes', 'ROLE_ADMIN,ROLE_MODO', 'portal_activate'),
(1510, 1500, 1510, 'Pages', 'cadoles_portal_config_page', 'fa-file', 'ROLE_ADMIN,ROLE_MODO', 'portal_activate'),