Merge branch 'master' into dist/envole/6/master

This commit is contained in:
Arnaud Fornerot 2020-09-29 09:09:32 +02:00
commit 0999f11f8c
23 changed files with 58897 additions and 22 deletions

View File

@ -28,6 +28,14 @@
<variables> <variables>
<family name='Ninegate'> <family name='Ninegate'>
<variable type='oui/non' name='activer_cadolesldap' description='Activer Annuaire Cadoles' hidden='True' exists='False'/>
<variable type='string' name='cadolesldap_pwdadmin' description="Mot de passe du compte admin durant l'instance" hidden='True' exists='False'/>
<variable type='string' name='cadolesldap_organization' description="Nom de l'organisation principale" hidden='True' exists='False'/>
<variable type='string' name='cadolesldap_niveau01branche' description="Nom de la branche de Niveau 01" hidden='True' exists='False'><value>niveau01</value></variable>
<variable type='string' name='cadolesldap_niveau02branche' description="Nom de la branche de Niveau 02" hidden='True' exists='False'><value>niveau02</value></variable>
<variable type='string' name='cadolesldap_niveau01name' description="Nom de la première orgranisation de Niveau 01" hidden='True' exists='False'/>
<variable type='string' name='cadolesldap_niveau01siren' description="SIREN de la première orgranisation de Niveau 01" hidden='True' exists='False'/>
<variable name="ninegate_test_ninegate" type="oui/non" hidden='True' exists='False'><value>non</value></variable> <variable name="ninegate_test_ninegate" type="oui/non" hidden='True' exists='False'><value>non</value></variable>
<variable name="activer_adminer" type="oui/non" description="Activer Adminer" hidden='True' exists='False'><value>non</value></variable> <variable name="activer_adminer" type="oui/non" description="Activer Adminer" hidden='True' exists='False'><value>non</value></variable>
<variable name="activer_balado" type="oui/non" description="Activer Balado" hidden='True' exists='False'><value>non</value></variable> <variable name="activer_balado" type="oui/non" description="Activer Balado" hidden='True' exists='False'><value>non</value></variable>
@ -76,17 +84,17 @@
<variable type='string' name='ninegate_mode_auth' description="Mode Authentification" mandatory='True'><value>CAS</value></variable> <variable type='string' name='ninegate_mode_auth' description="Mode Authentification" mandatory='True'><value>CAS</value></variable>
<variable type='string' name='ninegate_api_key' description="Clé d'accès API" mandatory='True'><value>APIKeyNinegate</value></variable> <variable type='string' name='ninegate_api_key' description="Clé d'accès API" mandatory='True'><value>APIKeyNinegate</value></variable>
<variable type='oui/non' name='ninegate_syncldap' description="Synchroniser Ninegate vers votre annuaire"><value>non</value></variable> <variable type='oui/non' name='ninegate_syncldap' description="Synchroniser Ninegate vers votre Annuaire CadolesLDAP"><value>non</value></variable>
<variable type='string' name='ninegate_ldaptemplate' description="Modèle d'annuaire"><value>scribe</value></variable> <variable type='string' name='ninegate_ldaptemplate' description="Modèle d'annuaire"><value>scribe</value></variable>
<variable type='oui/non' name='ninegate_scribegroup' description="Considérer les classes/options comme des groupes de travail"><value>oui</value></variable> <variable type='oui/non' name='ninegate_scribegroup' description="Considérer les classes/options comme des groupes de travail"><value>oui</value></variable>
<variable type='oui/non' name='ninegate_scribemaster' description="Placer les professeurs comme manager des groupes classes/options"><value>oui</value></variable> <variable type='oui/non' name='ninegate_scribemaster' description="Placer les professeurs comme manager des groupes classes/options"><value>oui</value></variable>
<variable type='string' name='ninegate_pwdadmin' description="Mot de passe du compte admin durant l'instance (idem valeur Cadoles ldap)" mandatory='True'><value>cadoles</value></variable> <variable type='string' name='ninegate_pwdadmin' description="Mot de passe du compte admin durant l'instance (idem valeur Cadoles ldap)" mandatory='True'><value></value></variable>
<variable type='string' name='ninegate_organization' description="Nom de l'organisation principale (idem valeur Cadoles ldap)" mandatory='True'><value>cadoles</value></variable> <variable type='string' name='ninegate_organization' description="Nom de l'organisation principale (idem valeur Cadoles ldap)" mandatory='True'><value></value></variable>
<variable type='string' name='ninegate_niveau01branche' description="Nom de la branche de Niveau 01 (idem valeur Cadoles ldap)" mandatory='True'><value>niveau01</value></variable> <variable type='string' name='ninegate_niveau01branche' description="Nom de la branche de Niveau 01 (idem valeur Cadoles ldap)" mandatory='True'><value>niveau01</value></variable>
<variable type='string' name='ninegate_niveau02branche' description="Nom de la branche de Niveau 02 (idem valeur Cadoles ldap)" mandatory='True'><value>niveau02</value></variable> <variable type='string' name='ninegate_niveau02branche' description="Nom de la branche de Niveau 02 (idem valeur Cadoles ldap)" mandatory='True'><value>niveau02</value></variable>
<variable type='string' name='ninegate_niveau01name' description="Nom de la première orgranisation de Niveau 01 (idem valeur Cadoles ldap)" mandatory='True'><value>cadoles</value></variable> <variable type='string' name='ninegate_niveau01name' description="Nom de la première orgranisation de Niveau 01 (idem valeur Cadoles ldap)" mandatory='True'><value></value></variable>
<variable type='string' name='ninegate_niveau01siren' description="SIREN de la première orgranisation de Niveau 01 (idem valeur Cadoles ldap)" mandatory='True'><value>cadoles</value></variable> <variable type='string' name='ninegate_niveau01siren' description="SIREN de la première orgranisation de Niveau 01 (idem valeur Cadoles ldap)"><value></value></variable>
<variable type='string' name='ninegate_niveau01label' description="Label singulier du niveau 01 d'organisation" mandatory='True'><value>Ecole</value></variable> <variable type='string' name='ninegate_niveau01label' description="Label singulier du niveau 01 d'organisation" mandatory='True'><value>Ecole</value></variable>
<variable type='string' name='ninegate_niveau01labels' description="Label pluriel du niveau 01 d'organisation" mandatory='True'><value>Ecoles</value></variable> <variable type='string' name='ninegate_niveau01labels' description="Label pluriel du niveau 01 d'organisation" mandatory='True'><value>Ecoles</value></variable>
@ -507,6 +515,16 @@
<target type='variable'>ninegate_niveau01siren</target> <target type='variable'>ninegate_niveau01siren</target>
</condition> </condition>
<fill name='calc_multi_condition' target='activer_admin_passfile'>
<param>non</param>
<param type='eole' name='condition_1' hidden='False'>ninegate_syncldap</param>
<param name="operator">AND</param>
<param type='eole' name='condition_2' hidden='False'>activer_cadolesldap</param>
<param name='match'>non</param>
<param name='mismatch'>oui</param>
<param name='default_mismatch'>non</param>
</fill>
<auto name='calc_multi_condition' target='ninegate_test_conf_cadolesldap'> <auto name='calc_multi_condition' target='ninegate_test_conf_cadolesldap'>
<param>CadolesLDAP</param> <param>CadolesLDAP</param>
<param type='eole' name='condition_1' hidden='False'>ninegate_ldaptemplate</param> <param type='eole' name='condition_1' hidden='False'>ninegate_ldaptemplate</param>
@ -549,13 +567,42 @@
<!-- AFFICHAGE EN FONCTION DU MODE SCRIBE --> <!-- AFFICHAGE EN FONCTION DE CADOLESLDAP -->
<condition name='hidden_if_not_in' source='ninegate_ldaptemplate'> <fill name='calc_val' target='ninegate_pwdadmin'>
<param>scribe</param> <param type='eole' hidden='False'>cadolesldap_pwdadmin</param>
</fill>
<target type='variable'>ninegate_scribegroup</target> <fill name='calc_val_first_value' target='ninegate_organization'>
<target type='variable'>ninegate_scribemaster</target> <param type='eole' optional='True' hidden='False'>cadolesldap_organization</param>
</condition> <param type='eole'>libelle_etab</param>
</fill>
<fill name='calc_val_first_value' target='ninegate_niveau01branche'>
<param type='eole' hidden='False'>cadolesldap_niveau01branche</param>
<param>niveau01</param>
</fill>
<fill name='calc_val_first_value' target='ninegate_niveau02branche'>
<param type='eole' hidden='False'>cadolesldap_niveau02branche</param>
<param>niveau01</param>
</fill>
<fill name='calc_val_first_value' target='ninegate_niveau01name'>
<param type='eole' optional='True' hidden='False'>cadolesldap_niveau01name</param>
<param type='eole'>libelle_etab</param>
</fill>
<fill name='calc_val' target='ninegate_niveau01siren'>
<param type='eole' hidden='False'>cadolesldap_niveau01siren</param>
</fill>
<!-- AFFICHAGE EN FONCTION DU MODE SCRIBE -->
<condition name='hidden_if_not_in' source='ninegate_ldaptemplate'>
<param>scribe</param>
<target type='variable'>ninegate_scribegroup</target>
<target type='variable'>ninegate_scribemaster</target>
</condition>

View File

@ -0,0 +1,330 @@
<?php
namespace Cadoles\CoreBundle\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ConfirmationQuestion;
use Symfony\Component\Console\Input\ArrayInput;
use Cadoles\CoreBundle\Entity\User;
use Cadoles\CoreBundle\Entity\Group;
use Cadoles\CoreBundle\Entity\UserGroup;
class ScribeToNinegateCommand extends Command
{
private $container;
private $em;
private $output;
private $connection;
private $host;
private $port;
private $pwd;
private $user;
protected function configure()
{
$this
->setName('Core:ScribeToNinegate')
->setDescription('Récupére un annuaire Scribe et le transforme en donnée Ninegate')
->setHelp('Récupére un annuaire Scribe et le transforme en donnée Ninegate')
->addArgument('host', InputArgument::REQUIRED, 'host du ldap scribe')
->addArgument('pwd', InputArgument::REQUIRED, 'pwd du compte cn=admin,o=gouv,c=fr')
;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->container = $this->getApplication()->getKernel()->getContainer();
$this->em = $this->container->get('doctrine')->getEntityManager();
$this->output = $output;
// Récupérer les parametres
$this->host = $input->getArgument('host');
$this->port = 389;
$this->pwd = $input->getArgument('pwd');
$this->user = "cn=admin,o=gouv,c=fr";
$ldap_basedn = $this->container->getParameter('ldap_basedn');
$ldap_username = $this->container->getParameter('ldap_username');
$ldap_firstname = $this->container->getParameter('ldap_firstname');
$ldap_lastname = $this->container->getParameter('ldap_lastname');
$ldap_email = $this->container->getParameter('ldap_email');
$ldap_usersadmin = $this->container->getParameter('ldap_usersadmin');
$fieldstoread = array($ldap_username,$ldap_firstname,$ldap_lastname,$ldap_email,"userPassword");
if(!$this->connect()) {
$this->writelnred("IMPOSSIBLE DE SE CONNECTER A L'ANNUAIRE SCRIBE");
return 0;
}
// On arrive à se connecter à l'annuaire du scribe
$this->writeln("CONNEXION A L'ANNUAIRE SCRIBE");
// Attention confirmation
$this->writeln('');
$this->writelnred('ATTENTION');
$this->writelnred('En confirmant vous allez totalement réinitialiser votre Ninegate');
$helper = $this->getHelper('question');
$question = new ConfirmationQuestion('Souhaitez-vous poursuivre (yes/no)?', false);
if (!$helper->ask($input, $output, $question)) {
return 0;
}
$this->writelnred('');
$this->writelnred('== PURGE');
$this->writelnred('PURGE DES CONFIG');
$this->purge('CadolesCoreBundle:Config');
$this->purge('CadolesCoreBundle:Script');
$this->purge('CadolesCoreBundle:Statistic');
$this->purge('CadolesCoreBundle:Whitelist');
$this->writelnred('PURGE DES ITEMS');
$this->purge('CadolesPortalBundle:Item');
$this->purge('CadolesPortalBundle:Itemcategory');
$this->writelnred('PURGE DES BOOKMARKS');
$this->purge('CadolesPortalBundle:Bookmark');
$this->writelnred('PURGE DES ALERTES');
$this->purge('CadolesPortalBundle:Alert');
$this->purge('CadolesPortalBundle:Alertcategory');
$this->writelnred('PURGE DES NOTICE');
$this->purge('CadolesPortalBundle:Notice');
$this->writelnred('PURGE DES CALENDAR');
$this->purge('CadolesPortalBundle:Calendar');
$this->writelnred('PURGE DES FLUX');
$this->purge('CadolesPortalBundle:Flux');
$this->writelnred('PURGE DES BLOG');
$this->purge('CadolesPortalBundle:Blog');
$this->writelnred('PURGE DES PAGES');
$this->purge('CadolesPortalBundle:Page');
$this->writelnred('PURGE DES PROJECT');
$this->purge('CadolesPortalBundle:Project');
$this->writelnred('PURGE DES UTILISATEURS');
$this->purge('CadolesCoreBundle:User');
$this->writelnred('PURGE DES INSCRIPTIONS');
$this->purge('CadolesCoreBundle:Registration');
$this->writelnred('PURGE DES GROUPES');
$this->purge('CadolesCoreBundle:Group');
$this->writelnred('PURGE DES NIVEAU 02');
$this->purge('CadolesCoreBundle:Niveau02');
$this->writelnred('PURGE DES NIVEAU 01');
$this->purge('CadolesCoreBundle:Niveau01');
$this->writelnred('PURGE DES ICONES');
$this->purge('CadolesPortalBundle:Icon');
$this->writeln('');
$this->writelnred('');
$this->writelnred('== INIT DATA');
$command = $this->getApplication()->find("Core:InitData");
$parameter = new ArrayInput([]);
$command->run($parameter, $output);
$command = $this->getApplication()->find("Cron:InitData");
$parameter = new ArrayInput([]);
$command->run($parameter, $output);
$command = $this->getApplication()->find("Portal:InitData");
$parameter = new ArrayInput([]);
$command->run($parameter, $output);
$command = $this->getApplication()->find("Core:Script");
$parameter = new ArrayInput([]);
$command->run($parameter, $output);
$this->writelnred('');
$this->writelnred('== USERS SCRIBE TO USERS NINEGATE');
$niveau01=$this->em->getRepository('CadolesCoreBundle:Niveau01')->find(-100);
$niveau01->setSiren("");
$this->em->persist($niveau01);
$this->em->flush();
$scribeusers = $this->search("(&(uid=*)(mail=*)(objectClass=person)(!(description=Computer)))", $fieldstoread, $ldap_basedn);
foreach($scribeusers as $scribeuser) {
if($scribeuser[$ldap_email]=="") {
$this->writelnred("Compte sans mail = ".$scribeuser[$ldap_username]." ".$scribeuser[$ldap_email]);
continue;
}
$user=$this->em->getRepository('CadolesCoreBundle:User')->findOneBy(array('email' => $scribeuser[$ldap_email]));
if($user&&$user->getUsername()!=$scribeuser[$ldap_username]) {
$this->writelnred("EMAIL en double = ".$scribeuser[$ldap_username]." ".$scribeuser[$ldap_email]);
continue;
}
$this->writeln($scribeuser[$ldap_username]." ".$scribeuser[$ldap_email]);
$user=$this->em->getRepository('CadolesCoreBundle:User')->findOneBy(array('username' => $scribeuser[$ldap_username]));
if(!$user) {
$user = new User();
$user->setUsername($scribeuser[$ldap_username]);
}
$user->setLastname($scribeuser[$ldap_lastname]);
$user->setFirstname($scribeuser[$ldap_firstname]);
$user->setEmail($scribeuser[$ldap_email]);
$user->setNiveau01($niveau01);
$user->setSiren($niveau01->getSiren());
$user->setPasswordDirect($scribeuser["userpassword"]);
$user->setSalt(uniqid(mt_rand(), true));
$user->setVisible(true);
$user->setAuthlevel("simple");
$user->setBelongingpopulation("agent");
if(in_array($scribeuser[$ldap_username],$ldap_usersadmin))
$user->setRole("ROLE_ADMIN");
else
$user->setRole("ROLE_USER");
$this->em->persist($user);
$this->em->flush();
}
$this->writelnred('');
$this->writelnred('== USERS SCRIBE TO USERS NINEGATE');
$scribegroups = $this->search("(objectClass=posixGroup)", ["cn","memberuid"], $ldap_basedn);
$exludgroupe=["DomainAdmins","DomainUsers","DomainComputers","PrintOperators","eleves","professeurs"];
foreach($scribegroups as $scribegroup) {
if(in_array($scribegroup["cn"],$exludgroupe)) continue;
$this->writeln($scribegroup["cn"]);
$group=$this->em->getRepository('CadolesCoreBundle:Group')->findOneBy(array('label' => $scribegroup["cn"]));
if(!$group) {
$group = new Group();
$group->setLabel($scribegroup["cn"]);
}
$group->setFgcanshare(false);
$group->setFgcancreatepage(false);
$group->setFgcancreateblog(false);
$group->setFgcancreatecalendar(false);
$group->setFgcancreateproject(false);
$group->setFgopen(false);
$group->setFgall(false);
$group->setFgtemplate(false);
$this->em->persist($group);
$this->em->flush();
if(array_key_exists("memberuid",$scribegroup))
{
if(!is_array($scribegroup["memberuid"]))
$scribegroup["memberuid"] = [ $scribegroup["memberuid"] ];
}
else
$scribegroup["memberuid"] = [];
foreach($scribegroup["memberuid"] as $scribemember) {
$user=$this->em->getRepository('CadolesCoreBundle:User')->findOneBy(array('username' => $scribemember));
if($user) {
$member=$this->em->getRepository('CadolesCoreBundle:UserGroup')->findOneBy(array('group' => $group, 'user' => $user));
if(!$member) {
$member= new UserGroup();
$member->setGroup($group);
$member->setUser($user);
$this->em->persist($member);
$this->em->flush();
}
}
}
}
return 1;
}
private function purge($entityname) {
$entitys=$this->em->getRepository($entityname)->findAll();
foreach ($entitys as $entity) {
$this->em->remove($entity);
}
$this->em->flush();
}
private function connect() {
if($this->connection){
return $this->connection;
} else {
$ldapConn = ldap_connect($this->host, $this->port);
if($ldapConn){
ldap_set_option($ldapConn, LDAP_OPT_PROTOCOL_VERSION, 3);
if(ldap_bind( $ldapConn, $this->user, $this->pwd)){
$this->connection = $ldapConn;
return $this->connection;
}
}
}
}
public function search($filter, $attributes = array(), $subBranch = '') {
$connection = $this->connect();
$branch = ($subBranch ? $subBranch : $this->baseDN);
$result = ldap_search($connection, $branch, $filter, $attributes,0,0,0);
if(!$result) {
$this->ldapError();
}
return $this->resultToArray($result);
}
private function resultToArray($result){
$connection = $this->connect();
$resultArray = array();
if($result){
$entry = ldap_first_entry($connection, $result);
while ($entry){
$row = array();
$attr = ldap_first_attribute($connection, $entry);
while ($attr){
$val = ldap_get_values_len($connection, $entry, $attr);
if(array_key_exists('count', $val) AND $val['count'] == 1){
$row[strtolower($attr)] = $val[0];
} else {
$row[strtolower($attr)] = $val;
}
$attr = ldap_next_attribute($connection, $entry);
}
$resultArray[] = $row;
$entry = ldap_next_entry($connection, $entry);
}
}
return $resultArray;
}
public function ldapError(){
$connection = $this->connect();
throw new \Exception(
'Error: ('. ldap_errno($connection) .') '. ldap_error($connection)
);
}
private function writelnred($string) {
$this->output->writeln('<fg=red>'.$string.'</>');
}
private function writeln($string) {
$this->output->writeln($string);
}
}

View File

@ -213,6 +213,10 @@ class SynchroCommand extends Command
$result[$ldap_username]=utf8_encode($result[$ldap_username]); $result[$ldap_username]=utf8_encode($result[$ldap_username]);
if(!isset($result[$ldap_lastname])) $result[$ldap_lastname] = ""; if(!isset($result[$ldap_lastname])) $result[$ldap_lastname] = "";
if(!isset($result[$ldap_firstname])) $result[$ldap_firstname] = ""; if(!isset($result[$ldap_firstname])) $result[$ldap_firstname] = "";
if(!array_key_exists($ldap_email,$result)) {
$this->writelnred(" - Création dans Bundle impossible >> ".$result[$ldap_username]." sans email");
continue;
}
$result[$ldap_email]=strtolower($result[$ldap_email]); $result[$ldap_email]=strtolower($result[$ldap_email]);
$result[$ldap_email]=utf8_encode($result[$ldap_email]); $result[$ldap_email]=utf8_encode($result[$ldap_email]);

View File

@ -67,6 +67,23 @@ class TestRestCommand extends Command
$this->writeln(''); $this->writeln('');
return 1; return 1;
// rest/alert/hide
// Cache une alert à un utilisateur
// key = parametre obligatoire
// key = clé d'accès de l'api
// login = parametre obligatoire
// login = uid de l'utilisateur sur lequel on souhaite ajouter un bookmark
// idalert = parametre obligatoire
// idalert = id de l'alert à chacher
$apiurl = $url."/rest/alert/hide";
$this->writeln($apiurl);
$response = \Unirest\Request::post($apiurl,$headers,["key"=>$masterapikey,"login"=>"admin","idalert"=>2]);
$idbookmark=$response->body;
dump($response->body);
// rest/bookmark/add // rest/bookmark/add
// Ajout d'un item ninegate existant comme bookmark d'un utilisateur // Ajout d'un item ninegate existant comme bookmark d'un utilisateur
// key = parametre obligatoire // key = parametre obligatoire

View File

@ -152,6 +152,7 @@ class RestController extends Controller
$tmp["order"] = $alert->getRoworder(); $tmp["order"] = $alert->getRoworder();
$tmp["category"] = $alert->getAlertcategory()->getId(); $tmp["category"] = $alert->getAlertcategory()->getId();
$tmp["description"] = $alert->getContent(); $tmp["description"] = $alert->getContent();
$tmp["fghideable"] = $alert->getFghideable();
array_push($output["alerts"],$tmp); array_push($output["alerts"],$tmp);
} }
@ -349,6 +350,65 @@ class RestController extends Controller
return new Response(json_encode($output), 200); return new Response(json_encode($output), 200);
} }
// rest/alert/hide
// Cache une alert à un utilisateur
// key = parametre obligatoire
// key = clé d'accès de l'api
// login = parametre obligatoire
// login = uid de l'utilisateur sur lequel on souhaite ajouter un bookmark
// idalert = parametre obligatoire
// idalert = id de l'alert à chacher
public function alerthideAction(Request $request) {
$em = $this->getDoctrine()->getManager();
$key=$request->get('key');
$login=$request->get('login');
$idalert=$request->get('idalert');
// Vérification de la clé
$realkey = $this->getParameter("apikeyninegate");
if($key!=$realkey) {
$output["error"]="error key";
return new Response(json_encode($output), 400);
}
// Tester présence des parametres
if(is_null($login)||is_null($idalert)) {
$output["error"]="missing parameter : login - idalert";
return new Response(json_encode($output), 400);
}
// Tester l'existance du login
$user=$em->getRepository('CadolesCoreBundle:User')->findOneBy(["username"=>$login]);
if(!$user) {
$output["error"]="user not exist";
return new Response(json_encode($output), 400);
}
// Tester l'existance de l'alert
$alert=$em->getRepository('CadolesPortalBundle:Alert')->find($idalert);
if(!$alert) {
$output["error"]="alert not exist";
return new Response(json_encode($output), 400);
}
// Tester que l'alert est masquable
if(!$alert->getFghideable()) {
$output["error"]="alert not hideable";
return new Response(json_encode($output), 400);
}
// Masquer l'alert
if(!$alert->getReaders()->contains($user)) {
$alert->addReader($user);
$em->persist($alert);
$em->flush();
}
$output=[];
return new Response(json_encode($output), 200);
}
} }

View File

@ -0,0 +1,95 @@
<?php
namespace Cadoles\CoreBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\OptionsResolver;
class IconChoiceType extends AbstractType
{
/**
* Cache for multiple icon fields or sub-requests.
*
* @var array
*/
private $choices;
private $fontawesomeIconsFile;
public function __construct($fontawesomeIconsFile)
{
// Liste des icones FontAwesome au format JSON
// Récupéré depuis le dépôt officiel via la commande "make fetch-fontawesome-icons"
// Voir service.yml
$this->fontawesomeIconsFile = $fontawesomeIconsFile;
}
public function buildView(FormView $view, FormInterface $form, array $options)
{
// Pass this flag is necessary to render the label as raw.
// See below the twig field template for more details.
$view->vars['raw_label'] = true;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'attr' => [
// It's the key of the solution and can be done in many ways.
// Now, the rendered <select> element will have a new font.
'style' => "font-family: 'FontAwesome';",
'class' => 'select2-icon',
],
'choices' => $this->getFontAwesomeIconChoices(),
]);
}
public function getParent()
{
return ChoiceType::class;
}
protected function getFontAwesomeIconChoices()
{
if (null !== $this->choices) {
return $this->choices;
}
$fileContent = file_get_contents($this->fontawesomeIconsFile);
if (!$fileContent) {
throw new \Error('Could not load fontawesome icons file');
}
$icons = json_decode($fileContent, true);
foreach ($icons as $iconName => $iconMetadata) {
foreach ($iconMetadata['free'] as $iconStyle) {
if ('brands' === $iconStyle) {
// On ne propose pas les icônes de marques déposées.
continue;
}
$iconClass = '';
switch ($iconStyle) {
case 'solid':
$iconClass .= ' fas';
break;
case 'regular':
$iconClass .= ' far';
break;
case 'brands':
default:
$iconClass .= ' fa';
break;
}
$iconClass .= ' fa-' . $iconName;
$this->choices[$iconMetadata['label'] . ' (' . $iconStyle . ')'] = trim($iconClass);
}
}
return $this->choices;
}
}

View File

@ -536,3 +536,7 @@ cadoles_core_rest_bookmark_add:
cadoles_core_rest_bookmark_del: cadoles_core_rest_bookmark_del:
path: /rest/bookmark/del path: /rest/bookmark/del
defaults: { _controller: CadolesCoreBundle:Rest:bookmarkdel } defaults: { _controller: CadolesCoreBundle:Rest:bookmarkdel }
cadoles_core_rest_alert_hide:
path: /rest/alert/hide
defaults: { _controller: CadolesCoreBundle:Rest:alerthide }

View File

@ -158,6 +158,16 @@ services:
public: true public: true
class: Cadoles\CoreBundle\Service\samlAttributeMapperService class: Cadoles\CoreBundle\Service\samlAttributeMapperService
cadoles.form.icon_choice_type:
class: Cadoles\CoreBundle\Form\Type\IconChoiceType
arguments:
# Liste des icones FontAwesome au format JSON
# Récupéré depuis le dépôt officiel via la commande "make fetch-fontawesome-icons"
# Voir Makefile du MSE
- "%kernel.root_dir%/../web/fonts/fontawesome/fontawesome-icons.json"
tags:
- { name: form.type }

File diff suppressed because one or more lines are too long

View File

@ -192,3 +192,5 @@ les plus importants pour y ajouter le class imposée par Bootstrap 3 #}
<input type="{{ type }}" {{ block('widget_attributes') }} /> <input type="{{ type }}" {{ block('widget_attributes') }} />
{% endspaceless %} {% endspaceless %}
{% endblock file_widget %} {% endblock file_widget %}

View File

@ -91,6 +91,24 @@
<script> <script>
function iformat(icon) {
return $('<span><i class="' + icon.id + '"></i> ' + icon.text + '</span>');
}
$('.select2-icon').select2({
width: "100%",
placeholder: 'choisir un icône',
allowClear: true,
templateSelection: iformat,
templateResult: iformat,
formatResult: iformat,
allowHtml: true,
escapeMarkup: function(m) {
return m;
}
})
function seeUser(id) { function seeUser(id) {
{% if app.user %} {% if app.user %}
$("#mymodal").find(".modal-title").html("FICHE UTILISATEUR"); $("#mymodal").find(".modal-title").html("FICHE UTILISATEUR");

View File

@ -46,6 +46,13 @@ class Page
*/ */
private $maxwidth; private $maxwidth;
/**
* @var string
*
* @ORM\Column(name="fonticon", type="string", nullable=true)
*/
private $fonticon;
/** /**
* @var string * @var string
* *
@ -585,4 +592,28 @@ class Page
{ {
return $this->templategroups; return $this->templategroups;
} }
/**
* Set fonticon
*
* @param string $fonticon
*
* @return Page
*/
public function setFonticon($fonticon)
{
$this->fonticon = $fonticon;
return $this;
}
/**
* Get fonticon
*
* @return string
*/
public function getFonticon()
{
return $this->fonticon;
}
} }

View File

@ -10,6 +10,7 @@ use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Tetranz\Select2EntityBundle\Form\Type\Select2EntityType; use Tetranz\Select2EntityBundle\Form\Type\Select2EntityType;
use Cadoles\CoreBundle\Form\Type\IconChoiceType;
use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\OptionsResolver\OptionsResolver;
@ -56,6 +57,10 @@ class PageSubmitType extends AbstractType
"disabled" => ($options["mode"]=="delete"?true:false), "disabled" => ($options["mode"]=="delete"?true:false),
]) ])
->add('fonticon', IconChoiceType::class, [
'label' => 'Icône',
'required' => false,
])
->add('page', ->add('page',
Select2EntityType::class, array( Select2EntityType::class, array(

View File

@ -12,6 +12,7 @@ use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Ivory\CKEditorBundle\Form\Type\CKEditorType; use Ivory\CKEditorBundle\Form\Type\CKEditorType;
use Tetranz\Select2EntityBundle\Form\Type\Select2EntityType; use Tetranz\Select2EntityBundle\Form\Type\Select2EntityType;
use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\OptionsResolver\OptionsResolver;
use Cadoles\CoreBundle\Form\Type\IconChoiceType;
class PageUpdateEditorType extends AbstractType class PageUpdateEditorType extends AbstractType
{ {
@ -31,6 +32,11 @@ class PageUpdateEditorType extends AbstractType
'label' => 'Ordre' 'label' => 'Ordre'
]) ])
->add('fonticon', IconChoiceType::class, [
'label' => 'Icône',
'required' => false,
])
->add('maxwidth', IntegerType::class, [ ->add('maxwidth', IntegerType::class, [
'label' => "Largeur maximum (0 pour largeur de l'écran)", 'label' => "Largeur maximum (0 pour largeur de l'écran)",
]) ])

View File

@ -11,6 +11,7 @@ use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Tetranz\Select2EntityBundle\Form\Type\Select2EntityType; use Tetranz\Select2EntityBundle\Form\Type\Select2EntityType;
use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\OptionsResolver\OptionsResolver;
use Cadoles\CoreBundle\Form\Type\IconChoiceType;
class PageUpdateToolType extends AbstractType class PageUpdateToolType extends AbstractType
{ {
@ -28,8 +29,14 @@ class PageUpdateToolType extends AbstractType
->add('roworder', IntegerType::class, [ ->add('roworder', IntegerType::class, [
'label' => 'Ordre', 'label' => 'Ordre',
])
->add('fonticon', IconChoiceType::class, [
'label' => 'Icône',
'required' => false,
]); ]);
if($options["access"]=="config") { if($options["access"]=="config") {
$builder $builder
->add('roles', ChoiceType::class, [ ->add('roles', ChoiceType::class, [

View File

@ -11,6 +11,7 @@ use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Tetranz\Select2EntityBundle\Form\Type\Select2EntityType; use Tetranz\Select2EntityBundle\Form\Type\Select2EntityType;
use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\OptionsResolver\OptionsResolver;
use Cadoles\CoreBundle\Form\Type\IconChoiceType;
class PageUpdateURLType extends AbstractType class PageUpdateURLType extends AbstractType
{ {
@ -34,6 +35,11 @@ class PageUpdateURLType extends AbstractType
'label' => 'Ordre', 'label' => 'Ordre',
]) ])
->add('fonticon', IconChoiceType::class, [
'label' => 'Icône',
'required' => false,
])
->add('maxwidth', IntegerType::class, [ ->add('maxwidth', IntegerType::class, [
'label' => "Largeur maximum (0 pour largeur de l'écran)", 'label' => "Largeur maximum (0 pour largeur de l'écran)",
]); ]);

View File

@ -12,6 +12,7 @@ use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Tetranz\Select2EntityBundle\Form\Type\Select2EntityType; use Tetranz\Select2EntityBundle\Form\Type\Select2EntityType;
use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\OptionsResolver\OptionsResolver;
use Cadoles\CoreBundle\Form\Type\IconChoiceType;
class PageUpdateWidgetType extends AbstractType class PageUpdateWidgetType extends AbstractType
{ {
@ -31,6 +32,11 @@ class PageUpdateWidgetType extends AbstractType
'label' => 'Ordre', 'label' => 'Ordre',
]) ])
->add('fonticon', IconChoiceType::class, [
'label' => 'Icône',
'required' => false,
])
->add('maxwidth', IntegerType::class, [ ->add('maxwidth', IntegerType::class, [
'label' => "Largeur maximum (0 pour largeur de l'écran)", 'label' => "Largeur maximum (0 pour largeur de l'écran)",
]) ])

View File

@ -14,9 +14,23 @@
{% endif %} {% endif %}
{% if entity.id is defined and page.id==entity.id %} {% if entity.id is defined and page.id==entity.id %}
<li id="menupage-{{page.id}}" class="active" style="cursor:pointer"><a onClick="showPage({{ page.id }},{{ page.pagecategory.id }},'{{ page.canupdate }}','portal','{{forcereload}}')">{{ page.name }}</a></li> <li id="menupage-{{page.id}}" class="active" style="cursor:pointer">
<a onClick="showPage({{ page.id }},{{ page.pagecategory.id }},'{{ page.canupdate }}','portal','{{forcereload}}')">
{% if page.fonticon %}
<i class="{{ page.fonticon }} fa-faw"></i>&nbsp;
{% endif %}
{{ page.name }}
</a>
</li>
{% else %} {% else %}
<li id="menupage-{{page.id}}"><a style="cursor:pointer" onClick="showPage({{ page.id }},{{ page.pagecategory.id }},'{{ page.canupdate }}','portal','{{forcereload}}')">{{ page.name }}</a></li> <li id="menupage-{{page.id}}">
<a style="cursor:pointer" onClick="showPage({{ page.id }},{{ page.pagecategory.id }},'{{ page.canupdate }}','portal','{{forcereload}}')">
{% if page.fonticon %}
<i class="{{ page.fonticon }} fa-faw"></i>&nbsp;
{% endif %}
{{ page.name }}
</a>
</li>
{% endif %} {% endif %}
{% endfor %} {% endfor %}
</ul> </ul>
@ -29,9 +43,27 @@
{% endif %} {% endif %}
{% if entity.id is defined and page.id==entity.id %} {% if entity.id is defined and page.id==entity.id %}
<li id="menupage-{{page.id}}" class="active" style="cursor:pointer"><a onClick="showPage({{ page.id }},{{ page.pagecategory.id }},'{{ page.canupdate }}','user','{{forcereload}}')"><i class="fa fa-user fa-fw"></i>&nbsp;{{ page.name }}</a></li> <li id="menupage-{{page.id}}" class="active" style="cursor:pointer">
<a onClick="showPage({{ page.id }},{{ page.pagecategory.id }},'{{ page.canupdate }}','user','{{forcereload}}')">
{% if page.fonticon %}
<i class="{{ page.fonticon }} fa-faw"></i>
{% else %}
<i class="fa fa-user fa-fw"></i>
{% endif %}
&nbsp;{{ page.name }}
</a>
</li>
{% else %} {% else %}
<li id="menupage-{{page.id}}"><a style="cursor:pointer" onClick="showPage({{ page.id }},{{ page.pagecategory.id }},'{{ page.canupdate }}','user','{{forcereload}}')"><i class="fa fa-user fa-fw"></i>&nbsp;{{ page.name }}</a></li> <li id="menupage-{{page.id}}">
<a style="cursor:pointer" onClick="showPage({{ page.id }},{{ page.pagecategory.id }},'{{ page.canupdate }}','user','{{forcereload}}')">
{% if page.fonticon %}
<i class="{{ page.fonticon }} fa-faw"></i>
{% else %}
<i class="fa fa-user fa-fw"></i>
{% endif %}
&nbsp;{{ page.name }}
</a>
</li>
{% endif %} {% endif %}
{% endfor %} {% endfor %}
</ul> </ul>
@ -45,7 +77,7 @@
<ul id="pagesshared" class="nav navbar-top-links navbar-left"> <ul id="pagesshared" class="nav navbar-top-links navbar-left">
<li class="dropdown"> <li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
<i class="fa fa-users fa-fw"></i>Mes Groupes <i class="fa fa-users fa-fw"></i>&nbsp;Mes Groupes
<span class="caret"></span> <span class="caret"></span>
</a> </a>
@ -67,7 +99,13 @@
<li id="menupage-{{page.id}}" {{ isactive }} style="cursor:pointer"> <li id="menupage-{{page.id}}" {{ isactive }} style="cursor:pointer">
<a data-group="{{groupshared.id}}" onClick="showPage({{ page.id }},{{ page.pagecategory.id }},'{{ page.canupdate }}','group','{{forcereload}}','{{groupshared.id}}')"> <a data-group="{{groupshared.id}}" onClick="showPage({{ page.id }},{{ page.pagecategory.id }},'{{ page.canupdate }}','group','{{forcereload}}','{{groupshared.id}}')">
<i class="fa fa-users fa-fw"></i>&nbsp;{{ groupshared.label }} {% if page.fonticon %}
<i class="{{ page.fonticon }} fa-faw"></i>
{% else %}
<i class="fa fa-users fa-fw"></i>
{% endif %}
&nbsp;{{ groupshared.label }}
{% if page.counterread > 0 %} {% if page.counterread > 0 %}
<span id="badge-{{groupshared.id}}" class="badge">{{page.counterread}}</span> <span id="badge-{{groupshared.id}}" class="badge">{{page.counterread}}</span>
{% endif %} {% endif %}
@ -77,9 +115,11 @@
<ul id="pagesshared" class="nav navbar-top-links navbar-left"> <ul id="pagesshared" class="nav navbar-top-links navbar-left">
<li class="dropdown{{submenu}}"> <li class="dropdown{{submenu}}">
<a data-group="{{groupshared.id}}" href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"> <a data-group="{{groupshared.id}}" href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
<i class="fa fa-users fa-fw"></i>&nbsp;{{ groupshared.label }} <i class="fa fa-users fa-fw"></i>
&nbsp;{{ groupshared.label }}
{%if submenu is empty %} {%if submenu is empty %}
<span class="caret"></span> <span class="caret"></span>
{% endif %} {% endif %}
{% if groupshared.pagesshared[0].counterread > 0 %} {% if groupshared.pagesshared[0].counterread > 0 %}
<span id="badge-{{groupshared.id}}" class="badge">{{groupshared.pagesshared[0].counterread}}</span> <span id="badge-{{groupshared.id}}" class="badge">{{groupshared.pagesshared[0].counterread}}</span>
@ -100,6 +140,9 @@
<li id="menupage-{{page.id}}" {{isactive}} style="cursor:pointer"> <li id="menupage-{{page.id}}" {{isactive}} style="cursor:pointer">
<a onClick="showPage({{ page.id }},{{ page.pagecategory.id }},'{{ page.canupdate }}','group','{{forcereload}}','{{groupshared.id}}')"> <a onClick="showPage({{ page.id }},{{ page.pagecategory.id }},'{{ page.canupdate }}','group','{{forcereload}}','{{groupshared.id}}')">
{% if page.fonticon %}
<i class="{{ page.fonticon }} fa-faw"></i>
{% endif %}
{{ page.name }} {{ page.name }}
</a> </a>
</li> </li>

View File

@ -49,6 +49,7 @@
<div id="pagegroup">{{ form_row(form.page) }}</div> <div id="pagegroup">{{ form_row(form.page) }}</div>
<div id="groupworkgroup">{{ form_row(form.groups) }}</div> <div id="groupworkgroup">{{ form_row(form.groups) }}</div>
{{ form_row(form.roworder) }} {{ form_row(form.roworder) }}
{{ form_row(form.fonticon) }}
{{ form_row(form.maxwidth) }} {{ form_row(form.maxwidth) }}
</div> </div>
</div> </div>

View File

@ -55,6 +55,7 @@
{{ form_row(form.name) }} {{ form_row(form.name) }}
{{ form_row(form.roworder) }} {{ form_row(form.roworder) }}
{{ form_row(form.fonticon) }}
{{ form_row(form.maxwidth) }} {{ form_row(form.maxwidth) }}
{{ form_row(form.html) }} {{ form_row(form.html) }}
</div> </div>

View File

@ -51,6 +51,7 @@
{{ form_row(form.name) }} {{ form_row(form.name) }}
{{ form_row(form.roworder) }} {{ form_row(form.roworder) }}
{{ form_row(form.fonticon) }}
</div> </div>
{% if form.roles is defined %} {% if form.roles is defined %}

View File

@ -58,6 +58,7 @@
<em>le mot clé #login# sera remplacé par le login de l'utilisateur</em><br> <em>le mot clé #login# sera remplacé par le login de l'utilisateur</em><br>
<em>Attention certains sites n'acceptent pas d'être encapsulés dans une frame.<br><br> <em>Attention certains sites n'acceptent pas d'être encapsulés dans une frame.<br><br>
{{ form_row(form.roworder) }} {{ form_row(form.roworder) }}
{{ form_row(form.fonticon) }}
{{ form_row(form.maxwidth) }} {{ form_row(form.maxwidth) }}
</div> </div>

View File

@ -208,6 +208,7 @@
{{ form_row(form.name) }} {{ form_row(form.name) }}
{{ form_row(form.roworder) }} {{ form_row(form.roworder) }}
{{ form_row(form.fonticon) }}
{{ form_row(form.maxwidth) }} {{ form_row(form.maxwidth) }}
{{ form_row(form.template) }} {{ form_row(form.template) }}
</div> </div>