]> _ Git - cubeextranet.git/commitdiff
wait #2475 @4
authorvincent@cubedesigners.com <vincent@cubedesigners.com@f5622870-0f3c-0410-866d-9cb505b7a8ef>
Tue, 19 Mar 2019 14:11:20 +0000 (14:11 +0000)
committervincent@cubedesigners.com <vincent@cubedesigners.com@f5622870-0f3c-0410-866d-9cb505b7a8ef>
Tue, 19 Mar 2019 14:11:20 +0000 (14:11 +0000)
inc/commons/class.common.ajax.php
inc/commons/class.common.tools.php
inc/ws/Controlleur/class.ws.droits.php
inc/ws/Controlleur/class.ws.maintenance.php
inc/ws/Metier/class.ws.book.parametres.php
inc/ws/Util/packager/class.ws.packager.php

index c7474d8b1507958487d599c36dc227a8362dd180..47fae4be1c18275ea237123031c7630f868f4e5c 100644 (file)
 class commonAjax
 {
 
-       public static function form($action, $titre, $form, $bouton = null, $cols = 2, $class = '', $extra = '', $return = false)
-       {
-               global $core;
-               if ($class != '') {
-                       $class = ' ' . $class;
-               }
-               $bouton = is_null($bouton) ? __('Enregister') : $bouton;
-               $colspan = $cols > 2 ? ' colspan="' . ($cols - 1) . '"' : '';
-               $res = commonPage::bh();
-               $res .= '<form action="' . $action . '" method="post">';
-               $res .= '<table class="form' . $class . '">';
-               $res .= '<tr><th' . $colspan . '><h1>' . $titre . '</h1></th><th class="right"><a href="#" class="closePopup">' . cubeMedia::image(IMG . '/close.png') . '</a></th></tr>';
-               $res .= $form;
-               if ($bouton) {
-                       $res .= '<tr><td colspan="' . $cols . '" class="right"><a href="#" class="submit">' . $core->typo->BoutonOK($bouton) . '</a></td></tr>';
-               }
-               $res .= '</table>';
-               $res .= $extra;
-               $res .= '</form>';
-               $res .= commonPage::bf();
-
-               if (!$return) {
-                       echo $res;
-                       exit;
-               }
-               return $res;
-       }
-
-       public static function page($liste, $page)
-       {
-               global $core;
-               $core->user->changeSettings($liste, 'page', $page);
-               $core->sauvePreferencesUtilisateur();
-       }
-
-       public static function parPage($liste, $nb)
-       {
-               global $core;
-               $core->user->changeSettings($liste, 'par_page', $nb);
-               $core->user->changeSettings($liste, 'page', 1);
-               $core->sauvePreferencesUtilisateur();
-       }
-
-       public static function sort($liste, $orderby)
-       {
-               global $core;
-               $settings = $core->user->getSettings($liste);
-               if ($orderby == 'facture_id') {
-                       $orderby = 'CAST(facture_id AS SIGNED)';
-               }
-
-               if ($settings['orderby'] == $orderby) {
-                       $sens = ($settings['sens'] == 'ASC') ? 'DESC' : 'ASC';
-                       $core->user->changeSettings($liste, 'orderby', $orderby);
-                       $core->user->changeSettings($liste, 'sens', $sens);
-               } else {
-                       $core->user->changeSettings($liste, 'orderby', $orderby);
-                       $core->user->changeSettings($liste, 'sens', 'ASC');
-               }
-               $core->sauvePreferencesUtilisateur();
-       }
-
-       public static function filtre($liste, $data = null)
-       {
-               global $core;
-               $core->user->changeSettings($liste, 'filtres', $data);
-               $core->user->changeSettings($liste, 'page', 1);
-               $core->sauvePreferencesUtilisateur();
-       }
-
-       public static function motdepasseOublie($args, &$x)
-       {
-               self::form('recupMotdepasse', 'Mot de passe oublié ?', commonUrl::motdepasseOublie($args), __('Recevoir mon mot de passe par e-mail'));
-       }
-
-       public static function mesParametres($args, &$x)
-       {
-               self::form('sauveMesParametres', 'Mes paramètres', commonUrl::mesParametres($args), false);
-       }
-
-       public static function sauveMesParametres($args, &$x)
-       {
-               global $core;
-               $dao = new commonDAOUtilisateur($core->con);
-               $dao->changeParametres($core->user->utilisateur_id, $_POST['lang'], $_POST['login']);
-               $x->addRedirection();
-       }
-
-       public static function recupMotdepasse($args, &$x)
-       {
-               global $core;
-               $dao = new commonDAOUtilisateur($core->con);
-               $utilisateur = $dao->selectByEmail($_POST['email']);
-
-               if (!is_null($utilisateur) && $utilisateur->enabled) {
-                       $mail = new cubeMail();
-                       $mail->charset = 'UTF-8';
-                       $mail->from = FROM_NAME . '<' . FROM_EMAIL . '>';
-                       $mail->bcc = MAIL_BCC;
-                       $mail->subject = '[' . EMAIL_SUBJECT . '] ' . __('Récupération de vos identifiants');
-                       $mail->to = $utilisateur->prenom . ' ' . $utilisateur->nom . '<' . $utilisateur->email . '>';
-                       $body = __('Bonjour,') . "\r\n\r\n";
-                       $body .= ASK_IDENT . "\r\n";
-                       $body .= __('Voici toutes les informations vous permettant de vous y connecter à nouveau :') . "\r\n\r\n";
-                       $body .= __('Adresse') . ' : https://' . $_SERVER['HTTP_HOST'] . '/' . "\r\n";
-                       $body .= __('Identifiant') . ' : ' . $utilisateur->email . "\r\n";
-                       $body .= __('Mot de passe') . ' : ' . $utilisateur->password . "\r\n\r\n";
-                       $body .= __('Cordialement,') . "\r\n";
-                       $body .= TEAM_NAME;
-                       $mail->body = $body;
-                       $ok = $mail->send();
-                       $message = $ok ? __('Vos identifiants vous ont été envoyé par e-mail') : __("Une erreur s'est produite lors de l'envoi de vos identifiants");
-               } else {
-                       $message = __('Cet e-mail ne correspond à aucun utilisateur du système');
-               }
-               $x->addAlert($message);
-               $x->addClosePopup();
-       }
-
-       public static function changeMotdepasse($args, &$x)
-       {
-               self::form('sauveMotdepasse', 'Changer mon mot de passe', commonUrl::changeMotdepasse(), __('Enregistrer mon nouveau mot de passe'));
-       }
-
-       public static function sauveMotdepasse($args, &$x)
-       {
-               global $core;
-
-               $ok = true;
-               if ($_POST['actuel'] != $core->user->password) {
-                       $x->addError('actuel', '');
-                       $ok = false;
-               } else {
-                       $x->addOk('actuel');
-               }
-
-               if (strlen($_POST['nouveau']) > 10 || strlen($_POST['nouveau']) < 6 || $_POST['nouveau'] != $_POST['confirmation']) {
-                       $x->addError('nouveau', '');
-                       $x->addError('confirmation', '');
-                       $ok = false;
-               } else {
-                       $x->addOk('nouveau');
-                       $x->addOk('confirmation');
-               }
-
-               if ($ok) {
-                       $dao = new commonDAOUtilisateur($core->con);
-                       $dao->changeMotdepasse($core->user->utilisateur_id, $_POST['nouveau']);
-
-                       $_SESSION['user_password'] = $_POST['password'];
-                       $x->addClosePopup();
-                       $x->addAlert(__('Votre mot de passe a été modifié'));
-               }
-       }
-
-       //      public static function connectAs($args, &$x) {
-       //              global $core;
-       //              $dao = new commonDAOUtilisateur($core->con);
-       //              $utilisateur = $dao->selectById($args[1]);
-       //
-       //              $_SESSION['user_email'] = $utilisateur->email;
-       //              $_SESSION['user_password'] = $utilisateur->password;
-       //
-       //              $x->addRedirection(SITE_PATH);
-       //      }
-
-       public static function sortFichiers($args, &$x)
-       {
-               commonAjax::sort('fichiers', $args[1]);
-               $x->addContent('listeFichiers', commonUrl::listeFichiers());
-       }
-
-       public static function pageFichiers($args, &$x)
-       {
-               commonAjax::page('fichiers', $args[1]);
-               $x->addContent('listeFichiers', commonUrl::listeFichiers());
-       }
-
-       public static function parPageFichiers($args, &$x)
-       {
-               commonAjax::parPage('fichiers', $_POST['par_page']);
-               $x->addContent('listeFichiers', commonUrl::listeFichiers());
-       }
-
-       public static function searchFichiers($args, &$x)
-       {
-               $x->addContent('listeFichiers', commonUrl::listeFichiers());
-       }
-
-       public static function refreshFichiers($args, &$x)
-       {
-               $x->addContent('listeFichiers', commonUrl::listeFichiers());
-       }
-
-       public static function supprimeFichier($args, &$x)
-       {
-               global $core;
-
-               array_shift($args);
-               $path = implode('/', $args);
-               $entreprise = array_shift($args);
-               commonDroits::telecharger($entreprise);
-
-               $dao = new commonDAOFichier($core->con);
-               $dao->supprime($path);
-               $x->addContent('listeFichiers', commonUrl::listeFichiers());
-       }
-
-       public static function formDashboard($args, &$x)
-       {
-               commonAjax::form('saveDashboard', __('Ajouter un élément au dashboard'), commonUrl::formDashboard($args));
-       }
-
-       public static function saveDashboard($args, &$x)
-       {
-               global $core;
-
-               $c = $core->con->openCursor('dashboard');
-               $c->site = MODE;
-               $c->nom = $_POST['nom'];
-               if ($_POST['dashboard_id'] == 'new') {
-                       $c->rubrique = $_POST['rubrique'];
-                       $c->equipier = $core->user->utilisateur_id;
-                       $c->settings = serialize($core->user->getSettings($_POST['rubrique']));
-                       $r = $core->con->select('SELECT MAX(dashboard_id) AS dashboard_id FROM dashboard');
-                       $c->dashboard_id = $r->dashboard_id + 1;
-                       $c->insert();
-               } else {
-                       $c->update('WHERE dashboard_id=\'' . $_POST['dashboard_id'] . '\'');
-               }
-               $x->addRedirection(SITE_PATH);
-       }
-
-       public static function pageDashboard($args, &$x)
-       {
-               $settings = self::getDashboardSettings($args[1]);
-               $settings['page'] = $args[2];
-               $r = self::saveDashboardSettings($args[1], $settings);
-               $x->addContent('dashboard_' . $args[1], commonUrl::displayDashboard($r));
-       }
-
-       public static function parPageDashboard($args, &$x)
-       {
-               $settings = self::getDashboardSettings($args[1]);
-               $settings['par_page'] = $_POST['par_page'];
-               $settings['page'] = 1;
-               $r = self::saveDashboardSettings($args[1], $settings);
-               $x->addContent('dashboard_' . $args[1], commonUrl::displayDashboard($r));
-       }
-
-       public static function sortDashboard($args, &$x)
-       {
-               $settings = self::getDashboardSettings($args[1]);
-               if ($settings['orderby'] == $args[2]) {
-                       $settings['sens'] = ($settings['sens'] == 'ASC') ? 'DESC' : 'ASC';
-               } else {
-                       $settings['orderby'] = $args[2];
-                       $settings['sens'] = 'ASC';
-               }
-               $r = self::saveDashboardSettings($args[1], $settings);
-               $x->addContent('dashboard_' . $args[1], commonUrl::displayDashboard($r));
-       }
-
-       public static function saveDashboardSettings($dashboard, $settings)
-       {
-               global $core;
-
-               $settings['page'] = $settings['page'] ? $settings['page'] : 1;
-
-               if ($settings['par_page'] > 0) {
-                       $settings['limit'] = array(($settings['page'] - 1) * $settings['par_page'], $settings['par_page']);
-               } else {
-                       $settings['limit'] = null;
-               }
-
-               $c = $core->con->openCursor('dashboard');
-               $c->settings = serialize($settings);
-               $c->update('WHERE dashboard_id=' . $dashboard);
-               return $core->con->select('SELECT * FROM dashboard WHERE dashboard_id=\'' . $core->con->escape($dashboard) . '\'');
-       }
-
-       public static function getDashboardSettings($dashboard)
-       {
-               global $core;
-               $r = $core->con->select('SELECT * FROM dashboard WHERE dashboard_id=\'' . $core->con->escape($dashboard) . '\'');
-               return unserialize($r->settings);
-       }
-
-       public static function delDashboard($args, &$x)
-       {
-               global $core;
-               $r = $core->con->execute('DELETE FROM dashboard WHERE dashboard_id=\'' . $core->con->escape($args[1]) . '\' AND equipier=\'' . $core->user->utilisateur_id . '\'');
-               $x->addReplace('dashboard_' . $args[1], '');
-       }
-
-       public static function reloadDashboards($args, &$x)
-       {
-               $x->addContent('dash', commonUrl::listeDashboard(array()));
-       }
-
-       public static function orderDashboards($args, &$x)
-       {
-               global $core;
-               $c = $core->con->openCursor('dashboard');
-               $i = 1;
-               foreach ($_GET['dashboard'] as $id) {
-                       $c->sort = $i;
-                       $c->update('WHERE dashboard_id=\'' . $core->con->escape($id) . '\'');
-                       $i++;
-               }
-       }
-
-       public static function toggleDashboard($args, &$x)
-       {
-               global $core;
-
-               $r = $core->con->select('SELECT state FROM dashboard WHERE dashboard_id=\'' . $core->con->escape($args[1]) . '\'');
-               $new = ($r->state == '1') ? '0' : '1';
-
-               $c = $core->con->openCursor('dashboard');
-               $c->state = $new;
-               $c->update('WHERE dashboard_id=\'' . $core->con->escape($args[1]) . '\'');
-       }
-
-       public static function syncftp($args, &$x)
-       {
-               set_time_limit(0);
-               commonDroits::min(5);
-               $u = parse_url('ftp://' . ltrim($_POST['dest'], '/'));
-               if (!isset($u['port'])) {
-                       $u['port'] = '21';
-               }
-
-               $commandes = array(
-                       'set ftp:ssl-allow false',
-                       'set net:reconnect-interval-base 5',
-                       'set net:max-retries 2',
-                       'set ftp:passive-mode ' . $_POST['mode'],
-                       'mkdir -p ' . $u['path'],
-                       'cd ' . $u['path'],
-                       'lcd ' . $_POST['source'],
-                       'mirror -Rve --parallel=5'
-               );
-
-               //$lftp->setManualArg( . '> mirror -Rv ' . $package);
-
-               $lftp = new CubeIT_CommandLine('lftp');
-               $lftp->setArg('u', $u['user'] . ',' . $u['pass']);
-               $lftp->setArg('p', $u['port']);
-               $lftp->setArg('e', implode(';', $commandes));
-               $lftp->setArg(null, $u['host']);
-               $lftp->execute();
-               $lftp->debug();
-
-               $x->addValue('res', utf8_encode($lftp->output));
-       }
-
-       public static function createGitRepos($args, &$x)
-       {
-               commonDroits::min(0.5);
-               $repos = $_POST['repos'] . '.git';
-               $dir = "/mnt/sshfs/batman/home/git/repositories/$repos";
-               `git init --bare $dir`;
-               `ln -s /home/git/.gitolite/hooks/common/post-receive $dir/hooks/post-receive`;
-               $x->addContent('res', 'Dépot crée : <pre>git clone git@git.cubedesigners.com:' . $repos . '</pre>');
-       }
-
-       public static function createDevSpace($args, &$x)
-       {
-               commonDroits::min(1);
-               global $core;
-
-               $domain = $_POST['domain'];
-               $svn = $_POST['svn'];
-               $user = $_POST['user'];
-               $zend = $_POST['zend'];
-               if (!$user) {
-                       $user = $domain;
-               }
-
-               $domain = cubeText::str2URL($domain);
-               $user = cubeText::str2URL($user);
-               $svn = cubeText::str2URL($svn);
-               $password = CubeIT_Crypt::generateRandomString(10);
-               $zend = cubeText::str2URL($zend);
-               $zend = cubeText::ucfirst($zend);
-
-               $body = "Adresse : https://$domain.dev1.cubedesigners.com
+    public static function form($action, $titre, $form, $bouton = null, $cols = 2, $class = '', $extra = '', $return = false)
+    {
+        global $core;
+        if ($class != '') {
+            $class = ' ' . $class;
+        }
+        $bouton = is_null($bouton) ? __('Enregister') : $bouton;
+        $colspan = $cols > 2 ? ' colspan="' . ($cols - 1) . '"' : '';
+        $res = commonPage::bh();
+        $res .= '<form action="' . $action . '" method="post">';
+        $res .= '<table class="form' . $class . '">';
+        $res .= '<tr><th' . $colspan . '><h1>' . $titre . '</h1></th><th class="right"><a href="#" class="closePopup">' . cubeMedia::image(IMG . '/close.png') . '</a></th></tr>';
+        $res .= $form;
+        if ($bouton) {
+            $res .= '<tr><td colspan="' . $cols . '" class="right"><a href="#" class="submit">' . $core->typo->BoutonOK($bouton) . '</a></td></tr>';
+        }
+        $res .= '</table>';
+        $res .= $extra;
+        $res .= '</form>';
+        $res .= commonPage::bf();
+
+        if (!$return) {
+            echo $res;
+            exit;
+        }
+        return $res;
+    }
+
+    public static function page($liste, $page)
+    {
+        global $core;
+        $core->user->changeSettings($liste, 'page', $page);
+        $core->sauvePreferencesUtilisateur();
+    }
+
+    public static function parPage($liste, $nb)
+    {
+        global $core;
+        $core->user->changeSettings($liste, 'par_page', $nb);
+        $core->user->changeSettings($liste, 'page', 1);
+        $core->sauvePreferencesUtilisateur();
+    }
+
+    public static function sort($liste, $orderby)
+    {
+        global $core;
+        $settings = $core->user->getSettings($liste);
+        if ($orderby == 'facture_id') {
+            $orderby = 'CAST(facture_id AS SIGNED)';
+        }
+
+        if ($settings['orderby'] == $orderby) {
+            $sens = ($settings['sens'] == 'ASC') ? 'DESC' : 'ASC';
+            $core->user->changeSettings($liste, 'orderby', $orderby);
+            $core->user->changeSettings($liste, 'sens', $sens);
+        } else {
+            $core->user->changeSettings($liste, 'orderby', $orderby);
+            $core->user->changeSettings($liste, 'sens', 'ASC');
+        }
+        $core->sauvePreferencesUtilisateur();
+    }
+
+    public static function filtre($liste, $data = null)
+    {
+        global $core;
+        $core->user->changeSettings($liste, 'filtres', $data);
+        $core->user->changeSettings($liste, 'page', 1);
+        $core->sauvePreferencesUtilisateur();
+    }
+
+    public static function motdepasseOublie($args, &$x)
+    {
+        self::form('recupMotdepasse', 'Mot de passe oublié ?', commonUrl::motdepasseOublie($args), __('Recevoir mon mot de passe par e-mail'));
+    }
+
+    public static function mesParametres($args, &$x)
+    {
+        self::form('sauveMesParametres', 'Mes paramètres', commonUrl::mesParametres($args), false);
+    }
+
+    public static function sauveMesParametres($args, &$x)
+    {
+        global $core;
+        $dao = new commonDAOUtilisateur($core->con);
+        $dao->changeParametres($core->user->utilisateur_id, $_POST['lang'], $_POST['login']);
+        $x->addRedirection();
+    }
+
+    public static function recupMotdepasse($args, &$x)
+    {
+        global $core;
+        $dao = new commonDAOUtilisateur($core->con);
+        $utilisateur = $dao->selectByEmail($_POST['email']);
+
+        if (!is_null($utilisateur) && $utilisateur->enabled) {
+            $mail = new cubeMail();
+            $mail->charset = 'UTF-8';
+            $mail->from = FROM_NAME . '<' . FROM_EMAIL . '>';
+            $mail->bcc = MAIL_BCC;
+            $mail->subject = '[' . EMAIL_SUBJECT . '] ' . __('Récupération de vos identifiants');
+            $mail->to = $utilisateur->prenom . ' ' . $utilisateur->nom . '<' . $utilisateur->email . '>';
+            $body = __('Bonjour,') . "\r\n\r\n";
+            $body .= ASK_IDENT . "\r\n";
+            $body .= __('Voici toutes les informations vous permettant de vous y connecter à nouveau :') . "\r\n\r\n";
+            $body .= __('Adresse') . ' : https://' . $_SERVER['HTTP_HOST'] . '/' . "\r\n";
+            $body .= __('Identifiant') . ' : ' . $utilisateur->email . "\r\n";
+            $body .= __('Mot de passe') . ' : ' . $utilisateur->password . "\r\n\r\n";
+            $body .= __('Cordialement,') . "\r\n";
+            $body .= TEAM_NAME;
+            $mail->body = $body;
+            $ok = $mail->send();
+            $message = $ok ? __('Vos identifiants vous ont été envoyé par e-mail') : __("Une erreur s'est produite lors de l'envoi de vos identifiants");
+        } else {
+            $message = __('Cet e-mail ne correspond à aucun utilisateur du système');
+        }
+        $x->addAlert($message);
+        $x->addClosePopup();
+    }
+
+    public static function changeMotdepasse($args, &$x)
+    {
+        self::form('sauveMotdepasse', 'Changer mon mot de passe', commonUrl::changeMotdepasse(), __('Enregistrer mon nouveau mot de passe'));
+    }
+
+    public static function sauveMotdepasse($args, &$x)
+    {
+        global $core;
+
+        $ok = true;
+        if ($_POST['actuel'] != $core->user->password) {
+            $x->addError('actuel', '');
+            $ok = false;
+        } else {
+            $x->addOk('actuel');
+        }
+
+        if (strlen($_POST['nouveau']) > 10 || strlen($_POST['nouveau']) < 6 || $_POST['nouveau'] != $_POST['confirmation']) {
+            $x->addError('nouveau', '');
+            $x->addError('confirmation', '');
+            $ok = false;
+        } else {
+            $x->addOk('nouveau');
+            $x->addOk('confirmation');
+        }
+
+        if ($ok) {
+            $dao = new commonDAOUtilisateur($core->con);
+            $dao->changeMotdepasse($core->user->utilisateur_id, $_POST['nouveau']);
+
+            $_SESSION['user_password'] = $_POST['password'];
+            $x->addClosePopup();
+            $x->addAlert(__('Votre mot de passe a été modifié'));
+        }
+    }
+
+    // public static function connectAs($args, &$x) {
+    //         global $core;
+    //         $dao = new commonDAOUtilisateur($core->con);
+    //         $utilisateur = $dao->selectById($args[1]);
+    //
+    //         $_SESSION['user_email'] = $utilisateur->email;
+    //         $_SESSION['user_password'] = $utilisateur->password;
+    //
+    //         $x->addRedirection(SITE_PATH);
+    // }
+
+    public static function sortFichiers($args, &$x)
+    {
+        commonAjax::sort('fichiers', $args[1]);
+        $x->addContent('listeFichiers', commonUrl::listeFichiers());
+    }
+
+    public static function pageFichiers($args, &$x)
+    {
+        commonAjax::page('fichiers', $args[1]);
+        $x->addContent('listeFichiers', commonUrl::listeFichiers());
+    }
+
+    public static function parPageFichiers($args, &$x)
+    {
+        commonAjax::parPage('fichiers', $_POST['par_page']);
+        $x->addContent('listeFichiers', commonUrl::listeFichiers());
+    }
+
+    public static function searchFichiers($args, &$x)
+    {
+        $x->addContent('listeFichiers', commonUrl::listeFichiers());
+    }
+
+    public static function refreshFichiers($args, &$x)
+    {
+        $x->addContent('listeFichiers', commonUrl::listeFichiers());
+    }
+
+    public static function supprimeFichier($args, &$x)
+    {
+        global $core;
+
+        array_shift($args);
+        $path = implode('/', $args);
+        $entreprise = array_shift($args);
+        commonDroits::telecharger($entreprise);
+
+        $dao = new commonDAOFichier($core->con);
+        $dao->supprime($path);
+        $x->addContent('listeFichiers', commonUrl::listeFichiers());
+    }
+
+    public static function formDashboard($args, &$x)
+    {
+        commonAjax::form('saveDashboard', __('Ajouter un élément au dashboard'), commonUrl::formDashboard($args));
+    }
+
+    public static function saveDashboard($args, &$x)
+    {
+        global $core;
+
+        $c = $core->con->openCursor('dashboard');
+        $c->site = MODE;
+        $c->nom = $_POST['nom'];
+        if ($_POST['dashboard_id'] == 'new') {
+            $c->rubrique = $_POST['rubrique'];
+            $c->equipier = $core->user->utilisateur_id;
+            $c->settings = serialize($core->user->getSettings($_POST['rubrique']));
+            $r = $core->con->select('SELECT MAX(dashboard_id) AS dashboard_id FROM dashboard');
+            $c->dashboard_id = $r->dashboard_id + 1;
+            $c->insert();
+        } else {
+            $c->update('WHERE dashboard_id=\'' . $_POST['dashboard_id'] . '\'');
+        }
+        $x->addRedirection(SITE_PATH);
+    }
+
+    public static function pageDashboard($args, &$x)
+    {
+        $settings = self::getDashboardSettings($args[1]);
+        $settings['page'] = $args[2];
+        $r = self::saveDashboardSettings($args[1], $settings);
+        $x->addContent('dashboard_' . $args[1], commonUrl::displayDashboard($r));
+    }
+
+    public static function parPageDashboard($args, &$x)
+    {
+        $settings = self::getDashboardSettings($args[1]);
+        $settings['par_page'] = $_POST['par_page'];
+        $settings['page'] = 1;
+        $r = self::saveDashboardSettings($args[1], $settings);
+        $x->addContent('dashboard_' . $args[1], commonUrl::displayDashboard($r));
+    }
+
+    public static function sortDashboard($args, &$x)
+    {
+        $settings = self::getDashboardSettings($args[1]);
+        if ($settings['orderby'] == $args[2]) {
+            $settings['sens'] = ($settings['sens'] == 'ASC') ? 'DESC' : 'ASC';
+        } else {
+            $settings['orderby'] = $args[2];
+            $settings['sens'] = 'ASC';
+        }
+        $r = self::saveDashboardSettings($args[1], $settings);
+        $x->addContent('dashboard_' . $args[1], commonUrl::displayDashboard($r));
+    }
+
+    public static function saveDashboardSettings($dashboard, $settings)
+    {
+        global $core;
+
+        $settings['page'] = $settings['page'] ? $settings['page'] : 1;
+
+        if ($settings['par_page'] > 0) {
+            $settings['limit'] = array(($settings['page'] - 1) * $settings['par_page'], $settings['par_page']);
+        } else {
+            $settings['limit'] = null;
+        }
+
+        $c = $core->con->openCursor('dashboard');
+        $c->settings = serialize($settings);
+        $c->update('WHERE dashboard_id=' . $dashboard);
+        return $core->con->select('SELECT * FROM dashboard WHERE dashboard_id=\'' . $core->con->escape($dashboard) . '\'');
+    }
+
+    public static function getDashboardSettings($dashboard)
+    {
+        global $core;
+        $r = $core->con->select('SELECT * FROM dashboard WHERE dashboard_id=\'' . $core->con->escape($dashboard) . '\'');
+        return unserialize($r->settings);
+    }
+
+    public static function delDashboard($args, &$x)
+    {
+        global $core;
+        $r = $core->con->execute('DELETE FROM dashboard WHERE dashboard_id=\'' . $core->con->escape($args[1]) . '\' AND equipier=\'' . $core->user->utilisateur_id . '\'');
+        $x->addReplace('dashboard_' . $args[1], '');
+    }
+
+    public static function reloadDashboards($args, &$x)
+    {
+        $x->addContent('dash', commonUrl::listeDashboard(array()));
+    }
+
+    public static function orderDashboards($args, &$x)
+    {
+        global $core;
+        $c = $core->con->openCursor('dashboard');
+        $i = 1;
+        foreach ($_GET['dashboard'] as $id) {
+            $c->sort = $i;
+            $c->update('WHERE dashboard_id=\'' . $core->con->escape($id) . '\'');
+            $i++;
+        }
+    }
+
+    public static function toggleDashboard($args, &$x)
+    {
+        global $core;
+
+        $r = $core->con->select('SELECT state FROM dashboard WHERE dashboard_id=\'' . $core->con->escape($args[1]) . '\'');
+        $new = ($r->state == '1') ? '0' : '1';
+
+        $c = $core->con->openCursor('dashboard');
+        $c->state = $new;
+        $c->update('WHERE dashboard_id=\'' . $core->con->escape($args[1]) . '\'');
+    }
+
+    public static function syncftp($args, &$x)
+    {
+        set_time_limit(0);
+        commonDroits::min(5);
+        $u = parse_url('ftp://' . ltrim($_POST['dest'], '/'));
+        if (!isset($u['port'])) {
+            $u['port'] = '21';
+        }
+
+        $commandes = array(
+            'set ftp:ssl-allow false',
+            'set net:reconnect-interval-base 5',
+            'set net:max-retries 2',
+            'set ftp:passive-mode ' . $_POST['mode'],
+            'mkdir -p ' . $u['path'],
+            'cd ' . $u['path'],
+            'lcd ' . $_POST['source'],
+            'mirror -Rve --parallel=5'
+        );
+
+        //$lftp->setManualArg( . '> mirror -Rv ' . $package);
+
+        $lftp = new CubeIT_CommandLine('lftp');
+        $lftp->setArg('u', $u['user'] . ',' . $u['pass']);
+        $lftp->setArg('p', $u['port']);
+        $lftp->setArg('e', implode(';', $commandes));
+        $lftp->setArg(null, $u['host']);
+        $lftp->execute();
+        $lftp->debug();
+
+        $x->addValue('res', utf8_encode($lftp->output));
+    }
+
+    public static function createGitRepos($args, &$x)
+    {
+        commonDroits::min(0.5);
+        $repos = $_POST['repos'] . '.git';
+        $dir = "/mnt/sshfs/batman/home/git/repositories/$repos";
+        `git init --bare $dir`;
+        `ln -s /home/git/.gitolite/hooks/common/post-receive $dir/hooks/post-receive`;
+        $x->addContent('res', 'Dépot crée : <pre>git clone git@git.cubedesigners.com:' . $repos . '</pre>');
+    }
+
+    public static function ttsBatch($args, &$x)
+    {
+        global $core;
+
+        commonDroits::min(5);
+        $f = $_FILES['file']['tmp_name'];
+        $dir = CubeIT_Files::tmpdir();
+        `unzip $f -d $dir`;
+
+        $dao = new wsDAOBook($core->con);
+
+        $files = CubeIT_Files::getRecursiveDirectoryIterator($dir);
+        $i = 0;
+        foreach ($files as $file) {
+            /** @var $file SplFileInfo */
+            if (!$file->isFile() || $file->getExtension() != 'xlsx') {
+                continue;
+            }
+
+            $base = $file->getBasename('.' . $file->getExtension());
+            $e = explode('$', $base);
+            $id = array_pop($e);
+
+            $f = $file->getRealPath();
+            $f = addcslashes($f, "$ #!\"\'&)(*,;<>?[]\^`{}|~");
+            $n = CubeIT_Text::str2URL($base) . '.xlsx';
+            $dest = WS_BOOKS . '/working/' . $id . '/';
+            $cmd = "mv $f $dest/$n";
+            `$cmd`;
+            $settings = [];
+            if (isset($_POST['voice']) && $_POST['voice'] != '') {
+                $settings['audiodescriptionVoice'] = $_POST['voice'];
+            }
+            $settings['audiodescriptionTexts'] = $n;
+            $dao->setSettings($id, $settings);
+            $i++;
+
+        }
+
+        if ($i == 0) {
+            $res = __('Aucun fichier traité');
+        } else {
+            $res = sprintf(__('%d fichiers ajoutés'), $i);
+        }
+        $x->addAlert($res);
+    }
+
+    public static function createDevSpace($args, &$x)
+    {
+        commonDroits::min(1);
+        global $core;
+
+        $domain = $_POST['domain'];
+        $svn = $_POST['svn'];
+        $user = $_POST['user'];
+        $zend = $_POST['zend'];
+        if (!$user) {
+            $user = $domain;
+        }
+
+        $domain = cubeText::str2URL($domain);
+        $user = cubeText::str2URL($user);
+        $svn = cubeText::str2URL($svn);
+        $password = CubeIT_Crypt::generateRandomString(10);
+        $zend = cubeText::str2URL($zend);
+        $zend = cubeText::ucfirst($zend);
+
+        $body = "Adresse : https://$domain.dev1.cubedesigners.com
 
 SSH : $domain.dev1.cubedesigners.com
 Nom d'utilisateur : $user
@@ -404,148 +451,148 @@ Nom d'utilisateur : $user
 Nom de la base : $user
 Mot de passe : $password";
 
-               if ($svn != '') {
-                       $body .= "\n\nSVN : svn+ssh://svn@svn.cubedesigners.com/projects/$svn";
-               }
-
-               $users = array();
-               if ($zend && isset($_POST['users']) && count($_POST['users'])) {
-
-                       foreach ($_POST['users'] as $u) {
-                               $userpassword = CubeIT_Crypt::generateRandomString(10);
-                               $users[$u] = $userpassword;
-                               $b = $body . "\n\n";
-                               $b .= 'Admin : https://' . $domain . '.dev1.cubedesigners.com/admin/' . "\n";
-                               $b .= 'Nom d\'utilisateur : ' . $u . "\n";
-                               $b .= 'Mot de passe : ' . $userpassword . "\n";
-
-                               $mail = new cubeMail();
-                               $mail->charset = 'UTF-8';
-                               $mail->from = 'extranet@cubedesigners.com';
-                               $mail->to = $u;
-                               $mail->subject = 'Création de l\'espace de développement "' . $domain . '"';
-                               $mail->body = $b;
-                               $mail->send();
-                       }
-               } else {
-                       $mail = new cubeMail();
-                       $mail->charset = 'UTF-8';
-                       $mail->from = 'extranet@cubedesigners.com';
-                       $mail->to = $core->user->email;
-                       $mail->subject = 'Création de l\'espace de développement "' . $domain . '"';
-                       $mail->body = $body;
-                       $mail->send();
-               }
-
-               $args = "-l $user -o $domain -u $user -p $password";
-               if ($zend) {
-                       $args .= " -n $zend";
-               }
-               if ($svn) {
-                       $args .= " -d $svn";
-               }
-               if (count($users)) {
-                       $args .= ' -e ' . base64_encode(json_encode($users));
-               }
-
-               $cmd = "ssh root@clockwork.cubedesigners.com /usr/local/bin/tools/projectcreator/make.php $args";
-               $out = `$cmd`;
-               $x->addDebug($cmd . ' : ' . $out);
-               $x->addAlert('Espace de développement crée. Vous allez recevoir un mail récapitulant les identifiants de l\'espace crée');
-       }
-
-       public static function postMailer($args, &$x)
-       {
-               $mail = new CubeIT_Mail_Mailjet();
-               $mail->setFrom($_POST['from']);
-               $to = explode(',', $_POST['to']);
-               foreach ($to as $t) {
-                       $t = trim($t);
-                       if ($t == '') {
-                               continue;
-                       }
-                       $mail->addTo($t);
-               }
-               $mail->setSubject($_POST['subject']);
-               $mail->setBodyHtmlFromZip($_FILES['src']['tmp_name'], '/mailer/' . time());
-               $transport = new CubeIT_Mail_Transport_Mailjet("ca110b35f8735c223d69c9987c2ac47d", 'b289d0acb08e0fe56ce98ccf0dd1ed8b');
-               $mail->send($transport);
-       }
-
-       /**
-        * @param $args
-        * @param cubeAjax $x
-        * @throws PHPExcel_Exception
-        * @throws PHPExcel_Reader_Exception
-        */
-       public static function importWSReferences($args, &$x)
-       {
-               global $core;
-
-               new PHPExcel();
-
-               $e = explode('.', $_FILES['file']['name']);
-               $ext = mb_strtolower(array_pop($e));
+        if ($svn != '') {
+            $body .= "\n\nSVN : svn+ssh://svn@svn.cubedesigners.com/projects/$svn";
+        }
+
+        $users = array();
+        if ($zend && isset($_POST['users']) && count($_POST['users'])) {
+
+            foreach ($_POST['users'] as $u) {
+                $userpassword = CubeIT_Crypt::generateRandomString(10);
+                $users[$u] = $userpassword;
+                $b = $body . "\n\n";
+                $b .= 'Admin : https://' . $domain . '.dev1.cubedesigners.com/admin/' . "\n";
+                $b .= 'Nom d\'utilisateur : ' . $u . "\n";
+                $b .= 'Mot de passe : ' . $userpassword . "\n";
+
+                $mail = new cubeMail();
+                $mail->charset = 'UTF-8';
+                $mail->from = 'extranet@cubedesigners.com';
+                $mail->to = $u;
+                $mail->subject = 'Création de l\'espace de développement "' . $domain . '"';
+                $mail->body = $b;
+                $mail->send();
+            }
+        } else {
+            $mail = new cubeMail();
+            $mail->charset = 'UTF-8';
+            $mail->from = 'extranet@cubedesigners.com';
+            $mail->to = $core->user->email;
+            $mail->subject = 'Création de l\'espace de développement "' . $domain . '"';
+            $mail->body = $body;
+            $mail->send();
+        }
+
+        $args = "-l $user -o $domain -u $user -p $password";
+        if ($zend) {
+            $args .= " -n $zend";
+        }
+        if ($svn) {
+            $args .= " -d $svn";
+        }
+        if (count($users)) {
+            $args .= ' -e ' . base64_encode(json_encode($users));
+        }
+
+        $cmd = "ssh root@clockwork.cubedesigners.com /usr/local/bin/tools/projectcreator/make.php $args";
+        $out = `$cmd`;
+        $x->addDebug($cmd . ' : ' . $out);
+        $x->addAlert('Espace de développement crée. Vous allez recevoir un mail récapitulant les identifiants de l\'espace crée');
+    }
+
+    public static function postMailer($args, &$x)
+    {
+        $mail = new CubeIT_Mail_Mailjet();
+        $mail->setFrom($_POST['from']);
+        $to = explode(',', $_POST['to']);
+        foreach ($to as $t) {
+            $t = trim($t);
+            if ($t == '') {
+                continue;
+            }
+            $mail->addTo($t);
+        }
+        $mail->setSubject($_POST['subject']);
+        $mail->setBodyHtmlFromZip($_FILES['src']['tmp_name'], '/mailer/' . time());
+        $transport = new CubeIT_Mail_Transport_Mailjet("ca110b35f8735c223d69c9987c2ac47d", 'b289d0acb08e0fe56ce98ccf0dd1ed8b');
+        $mail->send($transport);
+    }
+
+    /**
+     * @param $args
+     * @param cubeAjax $x
+     * @throws PHPExcel_Exception
+     * @throws PHPExcel_Reader_Exception
+     */
+    public static function importWSReferences($args, &$x)
+    {
+        global $core;
+
+        new PHPExcel();
+
+        $e = explode('.', $_FILES['file']['name']);
+        $ext = mb_strtolower(array_pop($e));
 
 //             $x->enableXML=false;
 //             print_r($_FILES);
 //             exit;
 
-               if ($ext == 'xlsx') {
-                       $reader = new PHPExcel_Reader_Excel2007();
-               } else if ($ext == 'csv') {
-                       $reader = new PHPExcel_Reader_CSV();
-                       $reader->setDelimiter(";");
-               }
-
-
-               $phpexcel = $reader->load($_FILES['file']['tmp_name']);
-               $sheet = $phpexcel->getSheet(0);
-               $maxRow = $sheet->getHighestRow(0);
-
-
-               for ($i = 1; $i <= $maxRow; $i++) {
-                       $ref = trim($sheet->getCellByColumnAndRow(0, $i));
-                       $url = trim($sheet->getCellByColumnAndRow(1, $i)->getOldCalculatedValue());
-
-                       if ($ref == '') {
-                               $ref = trim($sheet->getCellByColumnAndRow(0, $i)->getFormattedValue());
-                       }
-                       if ($url == '') {
-                               $url = trim($sheet->getCellByColumnAndRow(1, $i)->getFormattedValue());
-                       }
-
-
-                       if ($url == '' || $ref == '') {
-                               continue;
-                       }
-
-                       $fref = self::_formatWsReferenceRef($ref, $_POST['type']);
-                       $furl = self::_formatWsReferenceUrl($url, $_POST['type']);
-
-                       $delete = "DELETE FROM wsref WHERE ref='" . $core->con->escape($fref) . "' AND type='" . $core->con->escape($_POST['type']) . "'";
-                       $core->con->execute($delete);
-
-                       $c = $core->con->openCursor('wsref');
-                       $c->type = $_POST['type'];
-                       $c->ref = $fref;
-                       $c->url = $furl;
-                       $c->insert();
-               }
-       }
-
-       public static function _formatWsReferenceRef($ref, $type)
-       {
-               if ($type == '10doigts') {
-                       if (stripos($ref, 'ic') === 0) {
-                               return 'C' . substr($ref, 2);
-                       }
-               }
-               return $ref;
-       }
-
-       public static function _formatWsReferenceUrl($url, $type)
-       {
-               return $url;
-       }
+        if ($ext == 'xlsx') {
+            $reader = new PHPExcel_Reader_Excel2007();
+        } else if ($ext == 'csv') {
+            $reader = new PHPExcel_Reader_CSV();
+            $reader->setDelimiter(";");
+        }
+
+
+        $phpexcel = $reader->load($_FILES['file']['tmp_name']);
+        $sheet = $phpexcel->getSheet(0);
+        $maxRow = $sheet->getHighestRow(0);
+
+
+        for ($i = 1; $i <= $maxRow; $i++) {
+            $ref = trim($sheet->getCellByColumnAndRow(0, $i));
+            $url = trim($sheet->getCellByColumnAndRow(1, $i)->getOldCalculatedValue());
+
+            if ($ref == '') {
+                $ref = trim($sheet->getCellByColumnAndRow(0, $i)->getFormattedValue());
+            }
+            if ($url == '') {
+                $url = trim($sheet->getCellByColumnAndRow(1, $i)->getFormattedValue());
+            }
+
+
+            if ($url == '' || $ref == '') {
+                continue;
+            }
+
+            $fref = self::_formatWsReferenceRef($ref, $_POST['type']);
+            $furl = self::_formatWsReferenceUrl($url, $_POST['type']);
+
+            $delete = "DELETE FROM wsref WHERE ref='" . $core->con->escape($fref) . "' AND type='" . $core->con->escape($_POST['type']) . "'";
+            $core->con->execute($delete);
+
+            $c = $core->con->openCursor('wsref');
+            $c->type = $_POST['type'];
+            $c->ref = $fref;
+            $c->url = $furl;
+            $c->insert();
+        }
+    }
+
+    public static function _formatWsReferenceRef($ref, $type)
+    {
+        if ($type == '10doigts') {
+            if (stripos($ref, 'ic') === 0) {
+                return 'C' . substr($ref, 2);
+            }
+        }
+        return $ref;
+    }
+
+    public static function _formatWsReferenceUrl($url, $type)
+    {
+        return $url;
+    }
 }
index 66786fec47d17e986785dc38e67322c9ae268616..65448876ad7c5effcef205d0e4b8495f730fb039 100644 (file)
 class commonTools
 {
 
-       public static function hub($args)
-       {
-               global $core;
-               $args = cubePage::getArgs($args);
-
-               $function = array_shift($args);
-
-               if (!isset($_GET['light'])) {
-                       echo commonPage::header($args);
-               }
-
-               $cb = array('commonTools', $function);
-               if (is_callable($cb)) {
-                       echo call_user_func($cb, $args);
-               }
-
-               if (!isset($_GET['light'])) {
-                       echo commonPage::footer();
-               }
-       }
-
-       public static function des()
-       {
-               global $core;
-               commonDroits::min(2);
-
-               $ue = array_diff(cubeCountry::getUECountries(), array('FR'));
-
-               $countries = "'" . implode("','", $ue) . "'";
-               $limit = TIME - (3600 * 24 * 400);
-
-               $limit = mktime(0, 0, 0, date('m', $limit), 1, date('y', $limit));
-
-               $tvanumbers = array();
-               $r = $core->con->select('SELECT entreprise_id,tva_intra FROM entreprises');
-               $filter = new CubeIT_Filter_VATEurope();
-               while ($r->fetch()) {
-                       $tvanumbers[$r->entreprise_id] = $filter->filter($r->tva_intra);
-               }
-
-               $utilisateurs = array();
-               $r = $core->con->select('SELECT utilisateur_id,entreprise FROM utilisateurs');
-               while ($r->fetch()) {
-                       $utilisateurs[$r->utilisateur_id] = $r->entreprise;
-               }
-
-               $sql = 'SELECT * FROM factures_vue WHERE client_id IN (SELECT utilisateur_id FROM utilisateurs WHERE entreprise IN (SELECT entreprise_id FROM entreprises WHERE pays IN(' . $countries . '))) AND status > 0 AND date_creation>' . $limit . ' ORDER BY date_creation DESC';
-
-               $r = $core->con->select($sql);
-               $xls = new PHPExcel();
-               $i = 0;
-               $data = array();
-               while ($r->fetch()) {
-                       $mois = date('Y-m', $r->date_creation);
-                       if (!isset($data[$mois])) {
-                               $data[$mois] = array();
-                       }
-
-                       $tva = $tvanumbers[$utilisateurs[$r->client_id]];
-                       if (!isset($data[$mois][$tva])) {
-                               $data[$mois][$tva] = array('factures' => array(), 'montant' => 0, 'rs' => array());
-                       }
-
-                       $data[$mois][$tva]['montant'] += $r->total_ht;
-                       $data[$mois][$tva]['factures'][] = $r->facture_id;
-                       $data[$mois][$tva]['rs'][] = $r->client;
-               }
-
-
-               foreach ($data as $mois => $montants) {
-                       if ($i == 0) {
-                               $s = $xls->getActiveSheet();
-                       } else {
-                               $s = $xls->createSheet();
-                       }
-                       $s->setTitle($mois);
-                       $s->getCell('A1')->setValue('# TVA');
-                       $s->getCell('B1')->setValue('Montant');
-                       $s->getCell('C1')->setValue('Nom(s)');
-                       $s->getCell('D1')->setValue('Facture(s)');
-                       $line = 2;
-                       foreach ($montants as $tva => $d) {
-                               $s->getCell('A' . $line)->setValue($tva);
-                               $s->getCell('B' . $line)->setValue($d['montant']);
-                               $s->getCell('C' . $line)->setValue(implode(',', array_unique($d['rs'])));
-                               $s->getCell('D' . $line)->setValue(" " . implode(', ', $d['factures']));
-                               $line++;
-                       }
-                       $s->getColumnDimension('A')->setAutoSize(true);
-                       $s->getColumnDimension('B')->setAutoSize(true);
-                       $s->getColumnDimension('C')->setAutoSize(true);
-                       $s->getColumnDimension('D')->setAutoSize(true);
-                       $i++;
-               }
-
-               header('Content-disposition: attachment; filename="des.xlsx');
-               header('Content-type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
-
-               ob_end_clean();
-               $write = new PHPExcel_Writer_Excel2007($xls);
-               $write->save('php://output');
-               exit;
-
-       }
-
-       public static function urlDecoder($args)
-       {
-               global $js;
-               $js[] = JS_PATH . '/urldecoder.js';
-
-               global $core;
-               $res = commonPage::barre();
-               $res .= commonPage::tMain();
-               $res .= commonPage::bh();
-               $res .= '<form id="urlDecoder" method="post">';
-               $res .= '<table class="liste">';
-               $res .= '<tr><th colspan="2"><strong>' . __('Décoder une URL') . ' (' . __('de la forme') . ' : http%3A%2F%2Fwww )</strong></th></tr>';
-               $res .= '<tr><td>Collez l\'url à décoder</td><td><textarea id="input"></textarea></td></tr>';
-               $res .= '<tr><td>Url décodée</td><td><textarea id="output"></textarea></td></tr>';
-               $res .= '</table>';
-               $res .= '</form>';
-               $res .= '</div>';
-               $res .= commonPage::bf();
-               $res .= commonPage::bMain();
-               return $res;
-       }
-
-       public static function html2php()
-       {
-               global $core;
-
-               if (!isset($_POST['input'])) {
-                       $r = '<textarea id="input" name="input" rows="50" cols="80" style="width:100%;"></textarea>';
-               } else {
-                       $r = '<pre>';
-                       $lines = CubeIT_Text::explodeNewLines($_POST['input']);
-                       foreach ($lines as $l) {
-                               $l = trim($l);
-                               if (!$l) {
-                                       continue;
-                               }
-                               $r .= "\$res.='" . addcslashes(htmlspecialchars($l), "'") . "';\n";
-                       }
-
-                       $r .= '</pre>';
-               }
-
-               $res = commonPage::barre();
-               $res .= commonPage::tMain();
-               $res .= commonPage::bh();
-               $res .= '<form action="" method="post" class="notajax">';
-               $res .= '<table class="liste">';
-               $res .= '<tr><th><strong>HTML2PHP</strong></th></tr>';
-               $res .= '<tr><td>' . $r . '</td></tr>';
-               $res .= '<tr class="odd"><td class="right" ><a href="#" class="submit">' . $core->typo->BoutonOK(__('Générer le PHP')) . '</a></td></td>';
-               $res .= '</table>';
-               $res .= '</form>';
-               $res .= '</div>';
-               $res .= commonPage::bf();
-               $res .= commonPage::bMain();
-               return $res;
-       }
-
-       public static function tubeMeta($args)
-       {
-               $url = $_GET['u'];
-               $hash = sha1($url);
-
-               $web = '/tube/' . $hash . '/';
-               $dir = ROOT . $web;
-
-               header('Content-type: application/json');
-               ob_end_clean();
-
-               $poster = $dir . 'video.jpg';
-               if (file_exists($poster)) {
-                       $dim = getimagesize($poster);
-               }
-
-               $res = array('width' => $dim[0],
-                       'height' => $dim[1],
-                       'ratio' => round($dim[0] / $dim[1], 5));
-
-               echo json_encode($res);
-               exit;
-       }
-
-       public static function url($args)
-       {
-               ob_end_clean();
-               echo '<script type="text/javascript">window.location="' . $_GET['u'] . '"</script>';
-               exit;
-       }
-
-       public static function tube($args)
-       {
-               global $css, $js, $jsnomerge, $jsvar;
-
-               $css = array();
-               $js[] = JS_PATH . '/tube.js';
-               $jsnomerge[] = JS_PATH . '/flashdetect.js';
-               $js[] = JS_PATH . '/modernizr.js';
-
-               $url = $_GET['u'];
-               $hash = sha1($url);
-
-               $onlyplayer = isset($_GET['onlyplayer']);
-
-               if (!$onlyplayer) {
-                       $web = '/tube/' . $hash . '/';
-                       $dir = ROOT . $web;
-                       if (!file_exists($dir)) {
-                               mkdir($dir, 0777, true);
-                               $ext = files::getExtension($url);
-                               if (preg_match('#^(\w+)(.*)$#', $ext, $matches)) {
-                                       $ext = $matches[1];
-                               }
-                               $original = $dir . 'video.' . $ext;
-                               copy($url, $original);
-
-                               require_once ROOT . '/inc/ws/Util/class.ws.tools.php';
-                               wsTools::encodeWebVideos($original);
-                       }
-               } else {
-                       $e = explode('/', $url);
-                       array_pop($e);
-                       $dir = $web = implode('/', $e);
-               }
-
-               $jsvar['priority'] = isset($_GET['html5']) && $_GET['html5'] ? 'html5' : 'flash';
-
-               $loop = isset($_GET['loop']) ? $_GET['loop'] : 0;
-               $autoplay = isset($_GET['autoplay']) ? $_GET['autoplay'] : 0;
-               $controls = isset($_GET['controls']) ? $_GET['controls'] : 1;
-               $displayPoster = isset($_GET['poster']) ? $_GET['poster'] : 1;
-               $background = isset($_GET['background']) ? $_GET['background'] : '000000';
-               $background = trim($background, '# ');
-
-               $fv = array('video' => $url,
-                       'autoPlay' => $autoplay == 1,
-                       'controls' => $controls == 1,
-                       'loop' => $loop == 1,
-                       'background' => $background);
-
-               if (file_exists($dir . 'video.jpg')) {
-                       if ($displayPoster) {
-                               $poster = $web . 'video.jpg';
-                               $fv['poster'] = $poster;
-                       }
-                       $dim = getimagesize($dir . 'video.jpg');
-               }
-
-               $res = '<style type="text/css">';
-               $res .= 'html, body {margin: 0;padding: 0;height: 100%;color:#fff;overflow:hidden;}';
-               $res .= 'body,video{background:#' . $background . ';}';
-               $res .= 'video{width:100%;height:100%;display:none;}';
-               $res .= '#header,#videoflash,#videohtml,#ajaxLoader{display:none;}';
-               $res .= '</style>';
-
-               $video = '<video id="videohtml" width="100 % " height="100 % " data-src="' . $web . '"';
-               if (isset($dim)) {
-                       $video .= ' data-width="' . $dim[0] . '" data-height="' . $dim[1] . '"';
-               }
-
-               $ios = stristr($_SERVER['HTTP_USER_AGENT'], 'ipad') || stristr($_SERVER['HTTP_USER_AGENT'], 'iphone') || stristr($_SERVER['HTTP_USER_AGENT'], 'ipod');
-               $video .= ' controls="controls"';
-               if (!$controls) {
-                       $video .= ' onplay="tubeHideControls(this);"';
-               }
-               if ($loop) {
-                       $video .= ' onended="this . play();"';
-               }
-               if ($autoplay) {
-                       $video .= ' autoplay="autoplay"';
-               }
-               if (($displayPoster || $ios) && isset($poster)) {
-                       $video .= ' poster="' . $web . 'video.jpg"';
-               }
-               $video .= '>';
-               $video .= '</video>';
-
-               $flash = cubeMedia::flashObject('/swf/video.swf', '100%', '100%', $fv, 'videoflash', '', 10, $background, '', 'true', 'noscale', 'opaque');
-
-               $res .= $video;
-               $res .= $flash;
-               echo $res;
-       }
-
-       public static function browserInfos($args)
-       {
-               global $core;
-               global $jsnomerge;
-               global $js;
-               global $jsvar;
-
-               $jsnomerge[] = JS_PATH . '/flashdetect.js';
-               $js[] = JS_PATH . '/browserInfos.js';
-               $js[] = JS_PATH . '/modernizr.js';
-               $jsvar['NO_FLASH'] = __("Adobe Flash Player non détecté");
-               $res = commonPage::barre();
-               $res .= commonPage::tMain();
-               $res .= commonPage::bh();
-               $res .= '<style type="text / css">
+    public static function hub($args)
+    {
+        global $core;
+        $args = cubePage::getArgs($args);
+
+        $function = array_shift($args);
+
+        if (!isset($_GET['light'])) {
+            echo commonPage::header($args);
+        }
+
+        $cb = array('commonTools', $function);
+        if (is_callable($cb)) {
+            echo call_user_func($cb, $args);
+        }
+
+        if (!isset($_GET['light'])) {
+            echo commonPage::footer();
+        }
+    }
+
+    public static function des()
+    {
+        global $core;
+        commonDroits::min(2);
+
+        $ue = array_diff(cubeCountry::getUECountries(), array('FR'));
+
+        $countries = "'" . implode("','", $ue) . "'";
+        $limit = TIME - (3600 * 24 * 400);
+
+        $limit = mktime(0, 0, 0, date('m', $limit), 1, date('y', $limit));
+
+        $tvanumbers = array();
+        $r = $core->con->select('SELECT entreprise_id,tva_intra FROM entreprises');
+        $filter = new CubeIT_Filter_VATEurope();
+        while ($r->fetch()) {
+            $tvanumbers[$r->entreprise_id] = $filter->filter($r->tva_intra);
+        }
+
+        $utilisateurs = array();
+        $r = $core->con->select('SELECT utilisateur_id,entreprise FROM utilisateurs');
+        while ($r->fetch()) {
+            $utilisateurs[$r->utilisateur_id] = $r->entreprise;
+        }
+
+        $sql = 'SELECT * FROM factures_vue WHERE client_id IN (SELECT utilisateur_id FROM utilisateurs WHERE entreprise IN (SELECT entreprise_id FROM entreprises WHERE pays IN(' . $countries . '))) AND status > 0 AND date_creation>' . $limit . ' ORDER BY date_creation DESC';
+
+        $r = $core->con->select($sql);
+        $xls = new PHPExcel();
+        $i = 0;
+        $data = array();
+        while ($r->fetch()) {
+            $mois = date('Y-m', $r->date_creation);
+            if (!isset($data[$mois])) {
+                $data[$mois] = array();
+            }
+
+            $tva = $tvanumbers[$utilisateurs[$r->client_id]];
+            if (!isset($data[$mois][$tva])) {
+                $data[$mois][$tva] = array('factures' => array(), 'montant' => 0, 'rs' => array());
+            }
+
+            $data[$mois][$tva]['montant'] += $r->total_ht;
+            $data[$mois][$tva]['factures'][] = $r->facture_id;
+            $data[$mois][$tva]['rs'][] = $r->client;
+        }
+
+
+        foreach ($data as $mois => $montants) {
+            if ($i == 0) {
+                $s = $xls->getActiveSheet();
+            } else {
+                $s = $xls->createSheet();
+            }
+            $s->setTitle($mois);
+            $s->getCell('A1')->setValue('# TVA');
+            $s->getCell('B1')->setValue('Montant');
+            $s->getCell('C1')->setValue('Nom(s)');
+            $s->getCell('D1')->setValue('Facture(s)');
+            $line = 2;
+            foreach ($montants as $tva => $d) {
+                $s->getCell('A' . $line)->setValue($tva);
+                $s->getCell('B' . $line)->setValue($d['montant']);
+                $s->getCell('C' . $line)->setValue(implode(',', array_unique($d['rs'])));
+                $s->getCell('D' . $line)->setValue(" " . implode(', ', $d['factures']));
+                $line++;
+            }
+            $s->getColumnDimension('A')->setAutoSize(true);
+            $s->getColumnDimension('B')->setAutoSize(true);
+            $s->getColumnDimension('C')->setAutoSize(true);
+            $s->getColumnDimension('D')->setAutoSize(true);
+            $i++;
+        }
+
+        header('Content-disposition: attachment; filename="des.xlsx');
+        header('Content-type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
+
+        ob_end_clean();
+        $write = new PHPExcel_Writer_Excel2007($xls);
+        $write->save('php://output');
+        exit;
+
+    }
+
+    public static function urlDecoder($args)
+    {
+        global $js;
+        $js[] = JS_PATH . '/urldecoder.js';
+
+        global $core;
+        $res = commonPage::barre();
+        $res .= commonPage::tMain();
+        $res .= commonPage::bh();
+        $res .= '<form id="urlDecoder" method="post">';
+        $res .= '<table class="liste">';
+        $res .= '<tr><th colspan="2"><strong>' . __('Décoder une URL') . ' (' . __('de la forme') . ' : http%3A%2F%2Fwww )</strong></th></tr>';
+        $res .= '<tr><td>Collez l\'url à décoder</td><td><textarea id="input"></textarea></td></tr>';
+        $res .= '<tr><td>Url décodée</td><td><textarea id="output"></textarea></td></tr>';
+        $res .= '</table>';
+        $res .= '</form>';
+        $res .= '</div>';
+        $res .= commonPage::bf();
+        $res .= commonPage::bMain();
+        return $res;
+    }
+
+    public static function html2php()
+    {
+        global $core;
+
+        if (!isset($_POST['input'])) {
+            $r = '<textarea id="input" name="input" rows="50" cols="80" style="width:100%;"></textarea>';
+        } else {
+            $r = '<pre>';
+            $lines = CubeIT_Text::explodeNewLines($_POST['input']);
+            foreach ($lines as $l) {
+                $l = trim($l);
+                if (!$l) {
+                    continue;
+                }
+                $r .= "\$res.='" . addcslashes(htmlspecialchars($l), "'") . "';\n";
+            }
+
+            $r .= '</pre>';
+        }
+
+        $res = commonPage::barre();
+        $res .= commonPage::tMain();
+        $res .= commonPage::bh();
+        $res .= '<form action="" method="post" class="notajax">';
+        $res .= '<table class="liste">';
+        $res .= '<tr><th><strong>HTML2PHP</strong></th></tr>';
+        $res .= '<tr><td>' . $r . '</td></tr>';
+        $res .= '<tr class="odd"><td class="right" ><a href="#" class="submit">' . $core->typo->BoutonOK(__('Générer le PHP')) . '</a></td></td>';
+        $res .= '</table>';
+        $res .= '</form>';
+        $res .= '</div>';
+        $res .= commonPage::bf();
+        $res .= commonPage::bMain();
+        return $res;
+    }
+
+    public static function tubeMeta($args)
+    {
+        $url = $_GET['u'];
+        $hash = sha1($url);
+
+        $web = '/tube/' . $hash . '/';
+        $dir = ROOT . $web;
+
+        header('Content-type: application/json');
+        ob_end_clean();
+
+        $poster = $dir . 'video.jpg';
+        if (file_exists($poster)) {
+            $dim = getimagesize($poster);
+        }
+
+        $res = array('width' => $dim[0],
+            'height' => $dim[1],
+            'ratio' => round($dim[0] / $dim[1], 5));
+
+        echo json_encode($res);
+        exit;
+    }
+
+    public static function url($args)
+    {
+        ob_end_clean();
+        echo '<script type="text/javascript">window.location="' . $_GET['u'] . '"</script>';
+        exit;
+    }
+
+    public static function tube($args)
+    {
+        global $css, $js, $jsnomerge, $jsvar;
+
+        $css = array();
+        $js[] = JS_PATH . '/tube.js';
+        $jsnomerge[] = JS_PATH . '/flashdetect.js';
+        $js[] = JS_PATH . '/modernizr.js';
+
+        $url = $_GET['u'];
+        $hash = sha1($url);
+
+        $onlyplayer = isset($_GET['onlyplayer']);
+
+        if (!$onlyplayer) {
+            $web = '/tube/' . $hash . '/';
+            $dir = ROOT . $web;
+            if (!file_exists($dir)) {
+                mkdir($dir, 0777, true);
+                $ext = files::getExtension($url);
+                if (preg_match('#^(\w+)(.*)$#', $ext, $matches)) {
+                    $ext = $matches[1];
+                }
+                $original = $dir . 'video.' . $ext;
+                copy($url, $original);
+
+                require_once ROOT . '/inc/ws/Util/class.ws.tools.php';
+                wsTools::encodeWebVideos($original);
+            }
+        } else {
+            $e = explode('/', $url);
+            array_pop($e);
+            $dir = $web = implode('/', $e);
+        }
+
+        $jsvar['priority'] = isset($_GET['html5']) && $_GET['html5'] ? 'html5' : 'flash';
+
+        $loop = isset($_GET['loop']) ? $_GET['loop'] : 0;
+        $autoplay = isset($_GET['autoplay']) ? $_GET['autoplay'] : 0;
+        $controls = isset($_GET['controls']) ? $_GET['controls'] : 1;
+        $displayPoster = isset($_GET['poster']) ? $_GET['poster'] : 1;
+        $background = isset($_GET['background']) ? $_GET['background'] : '000000';
+        $background = trim($background, '# ');
+
+        $fv = array('video' => $url,
+            'autoPlay' => $autoplay == 1,
+            'controls' => $controls == 1,
+            'loop' => $loop == 1,
+            'background' => $background);
+
+        if (file_exists($dir . 'video.jpg')) {
+            if ($displayPoster) {
+                $poster = $web . 'video.jpg';
+                $fv['poster'] = $poster;
+            }
+            $dim = getimagesize($dir . 'video.jpg');
+        }
+
+        $res = '<style type="text/css">';
+        $res .= 'html, body {margin: 0;padding: 0;height: 100%;color:#fff;overflow:hidden;}';
+        $res .= 'body,video{background:#' . $background . ';}';
+        $res .= 'video{width:100%;height:100%;display:none;}';
+        $res .= '#header,#videoflash,#videohtml,#ajaxLoader{display:none;}';
+        $res .= '</style>';
+
+        $video = '<video id="videohtml" width="100 % " height="100 % " data-src="' . $web . '"';
+        if (isset($dim)) {
+            $video .= ' data-width="' . $dim[0] . '" data-height="' . $dim[1] . '"';
+        }
+
+        $ios = stristr($_SERVER['HTTP_USER_AGENT'], 'ipad') || stristr($_SERVER['HTTP_USER_AGENT'], 'iphone') || stristr($_SERVER['HTTP_USER_AGENT'], 'ipod');
+        $video .= ' controls="controls"';
+        if (!$controls) {
+            $video .= ' onplay="tubeHideControls(this);"';
+        }
+        if ($loop) {
+            $video .= ' onended="this . play();"';
+        }
+        if ($autoplay) {
+            $video .= ' autoplay="autoplay"';
+        }
+        if (($displayPoster || $ios) && isset($poster)) {
+            $video .= ' poster="' . $web . 'video.jpg"';
+        }
+        $video .= '>';
+        $video .= '</video>';
+
+        $flash = cubeMedia::flashObject('/swf/video.swf', '100%', '100%', $fv, 'videoflash', '', 10, $background, '', 'true', 'noscale', 'opaque');
+
+        $res .= $video;
+        $res .= $flash;
+        echo $res;
+    }
+
+    public static function browserInfos($args)
+    {
+        global $core;
+        global $jsnomerge;
+        global $js;
+        global $jsvar;
+
+        $jsnomerge[] = JS_PATH . '/flashdetect.js';
+        $js[] = JS_PATH . '/browserInfos.js';
+        $js[] = JS_PATH . '/modernizr.js';
+        $jsvar['NO_FLASH'] = __("Adobe Flash Player non détecté");
+        $res = commonPage::barre();
+        $res .= commonPage::tMain();
+        $res .= commonPage::bh();
+        $res .= '<style type="text / css">
        @media all and (orientation: portrait) {
                #ol{display:none;}
     }
@@ -313,125 +313,125 @@ class commonTools
     @media all and (orientation: landscape) {
       #op{display:none;}
     }  </style>';
-               $res .= '<table class="liste">';
-               $res .= '<tr><th colspan="3"><strong>' . __('Informations concernant votre navigateur') . '</strong></th></tr>';
-               $res .= '<tr><td rowspan="3">' . __('Navigateur') . '</td><td colspan="2" data-navigator="userAgent">' . $_SERVER['HTTP_USER_AGENT'] . '</td></tr>';
-               $res .= '<tr><td>' . __('Version') . '</td><td data-navigator="appVersion"></td></tr>';
-               $res .= '<tr><td>' . __('Plateforme') . '</td><td data-navigator="platform"></td></tr>';
-               $res .= '<tr><td>' . __('Adresse IP') . '</td><td colspan="2">' . $_SERVER['REMOTE_ADDR'] . '</td></tr>';
-               $res .= '<tr><td>' . __('Adobe Flash Player') . '</td><td colspan="2" class="flashversion"></td></tr>';
-               $res .= '<tr><td rowspan="4">' . __('Support de la video') . '</td><td colspan="2"><strong class="f" data-feature="video"></strong></td></tr>';
-               $res .= '<tr><td>OGV</td><td><span class="f" data-feature="video . ogg"></span></td></tr>';
-               $res .= '<tr><td>H264</td><td><span class="f" data-feature="video . h264"></span></td></tr>';
-               $res .= '<tr><td>WEBM</td><td><span class="f" data-feature="video . webm"></span></tr>';
-               $res .= '<tr><td rowspan="3">' . __('Ecran') . '</td><td>' . __('Orientation') . '</td><td><span id="op">' . __('Portrait') . '</span><span id="ol">' . __('Paysage') . '</span></td></tr>';
-               $res .= '<tr><td>' . __("Largeur") . '</td><td id="swidth"></td></tr>';
-               $res .= '<tr><td>' . __("Hauteur") . '</td><td id="sheight"></td></tr>';
-               $res .= '</table>';
-               $res .= '</div>';
-               $res .= commonPage::bf();
-               $res .= commonPage::bMain();
-               return $res;
-       }
-
-
-       public static function favicon($args)
-       {
-               global $core;
-               $res = commonPage::barre();
-               $res .= commonPage::tMain();
-               $res .= commonPage::bh();
-               $res .= '<form action="' . SITE_PATH . 'tools/makeFavicon" method="post" class="notajax" enctype="multipart/form-data">';
-               $res .= '<table class="liste">';
-               $res .= '<tr><th colspan="3"><strong>' . __('Générer un favicon') . '</strong></th></tr>';
-               $res .= '<tr><td>' . __('Veuillez charger une image carrée (dimensions optimales : 256x256 px)') . '</td>';
-               $res .= '<td colspan="2"><input type="file" name="file" /></td></tr>';
-               $res .= '<tr class="odd"><td>' . __('Bord arrondi') . '</td>';
-               $res .= '<td><input type="number" name="round" value="0" size="5" />%</td><td>' . __('Valeurs typiques') . ' : <br>iOS : 17.54%<br />' . __('Aucun arrondi') . ' : 0%</td></tr>';
-               $res .= '<tr><td colspan="3">' . __("L'arrondi ne sera pas appliqué aux icônes iOS, le système lui même se chargeant d'y appliquer les arrondis et les reflets") . '</td></tr>';
-               $res .= '<tr class="odd"><td class="right" colspan="3"><a href="#" class="submit">' . $core->typo->BoutonOK(__('Générer le favicon')) . '</a></td></td>';
-               $res .= '</table>';
-               $res .= '</form>';
-               $res .= '</div>';
-               $res .= commonPage::bf();
-               $res .= commonPage::bMain();
-               return $res;
-       }
-
-       public static function webfonts($args)
-       {
-               global $core;
-               $res = commonPage::barre();
-               $res .= commonPage::tMain();
-               $res .= commonPage::bh();
-               $res .= '<form action="' . SITE_PATH . 'tools/makeWebfont" method="post" class="notajax" enctype="multipart/form-data">';
-               $res .= '<table class="liste">';
-               $res .= '<tr><th><strong>' . __('Générer un kit webfont') . '</strong></th></tr>';
-               $res .= '<tr><td>' . __('Veuillez charger une police de caractères') . '</td></tr>';
-               $res .= '<tr class="odd"><td><input type="file" name="file[]" multiple="multiple" /></td></tr>';
-               $res .= '<tr><td><label><input type="checkbox" value="1" name="rename" /> Renommer les polices</label></td></tr>';
-               $res .= '<tr><td class="right"><a href="#" class="submit">' . $core->typo->BoutonOK(__('Générer le kit webfont')) . '</a></td></td>';
-               $res .= '</table>';
-               $res .= '</form>';
-               $res .= '</div>';
-               $res .= commonPage::bf();
-               $res .= commonPage::bMain();
-               return $res;
-       }
-
-       public static function makeWebfont()
-       {
-               $tmp = cubeFiles::tempdir();
-               if (!file_exists($tmp)) {
-                       mkdir($tmp, 0777, true);
-               }
-
-               $rename = isset($_POST['rename']);
-
-
-               foreach ($_FILES['file']['name'] as $k => $name) {
-                       $tmp_name = $_FILES['file']['tmp_name'][$k];
-
-                       $ex = explode('.', strtolower($name));
-                       $upext = array_pop($ex);
-                       $fontName = implode('.', $ex);
-
-                       $fontFile = $tmp . '/' . strtolower($name);
-                       move_uploaded_file($tmp_name, $fontFile);
-
-                       $ext = array('ttf', 'woff', 'woff2', 'eot', 'php');
-
-                       foreach ($ext as $e) {
-                               $out = $tmp . '/' . $fontName . '.' . $e;
-                               if ($e == 'ttf' || $e == 'woff') {
-
-                                       $fontforge = new cubeCommandLine('convertrn.pe');
-                                       $fontforge->setPath(CONVERTER_PATH);
-                                       $fontforge->setArg(null, $fontFile);
-                                       $fontforge->setArg(null, $out);
-                                       if ($rename) {
-                                               $fontforge->setArg(null, $fontName);
-                                       }
-                                       $fontforge->execute();
-
-                                       fb($fontforge->commande);
-                                       fb($fontforge->output);
-                               } else if ($e == 'eot') {
-                                       $ttf = $tmp . '/' . $fontName . '.ttf';
-                                       `/usr/local/bin/ttf2eot < $ttf > $out`;
-                               } else if ($e == 'woff2') {
-                                       $ttf = $tmp . '/' . $fontName . '.ttf';
-                                       `cat $ttf | ttf2woff2 >> $out`;
-                               } else if ($e == 'php') {
-                                       $ttf = $tmp . '/' . $fontName . '.ttf';
-                                       include ROOT . '/inc/cube/externals/fpdf/makefont/makefont.php';
-                                       Makefont($ttf);
-                                       rename(ROOT . '/' . $fontName . '.z', $tmp . '/' . $fontName . '.z');
-                                       rename(ROOT . '/' . $fontName . '.php', $tmp . '/' . $fontName . '.php');
-                               }
-                       }
-
-                       $css = "@font-face {
+        $res .= '<table class="liste">';
+        $res .= '<tr><th colspan="3"><strong>' . __('Informations concernant votre navigateur') . '</strong></th></tr>';
+        $res .= '<tr><td rowspan="3">' . __('Navigateur') . '</td><td colspan="2" data-navigator="userAgent">' . $_SERVER['HTTP_USER_AGENT'] . '</td></tr>';
+        $res .= '<tr><td>' . __('Version') . '</td><td data-navigator="appVersion"></td></tr>';
+        $res .= '<tr><td>' . __('Plateforme') . '</td><td data-navigator="platform"></td></tr>';
+        $res .= '<tr><td>' . __('Adresse IP') . '</td><td colspan="2">' . $_SERVER['REMOTE_ADDR'] . '</td></tr>';
+        $res .= '<tr><td>' . __('Adobe Flash Player') . '</td><td colspan="2" class="flashversion"></td></tr>';
+        $res .= '<tr><td rowspan="4">' . __('Support de la video') . '</td><td colspan="2"><strong class="f" data-feature="video"></strong></td></tr>';
+        $res .= '<tr><td>OGV</td><td><span class="f" data-feature="video . ogg"></span></td></tr>';
+        $res .= '<tr><td>H264</td><td><span class="f" data-feature="video . h264"></span></td></tr>';
+        $res .= '<tr><td>WEBM</td><td><span class="f" data-feature="video . webm"></span></tr>';
+        $res .= '<tr><td rowspan="3">' . __('Ecran') . '</td><td>' . __('Orientation') . '</td><td><span id="op">' . __('Portrait') . '</span><span id="ol">' . __('Paysage') . '</span></td></tr>';
+        $res .= '<tr><td>' . __("Largeur") . '</td><td id="swidth"></td></tr>';
+        $res .= '<tr><td>' . __("Hauteur") . '</td><td id="sheight"></td></tr>';
+        $res .= '</table>';
+        $res .= '</div>';
+        $res .= commonPage::bf();
+        $res .= commonPage::bMain();
+        return $res;
+    }
+
+
+    public static function favicon($args)
+    {
+        global $core;
+        $res = commonPage::barre();
+        $res .= commonPage::tMain();
+        $res .= commonPage::bh();
+        $res .= '<form action="' . SITE_PATH . 'tools/makeFavicon" method="post" class="notajax" enctype="multipart/form-data">';
+        $res .= '<table class="liste">';
+        $res .= '<tr><th colspan="3"><strong>' . __('Générer un favicon') . '</strong></th></tr>';
+        $res .= '<tr><td>' . __('Veuillez charger une image carrée (dimensions optimales : 256x256 px)') . '</td>';
+        $res .= '<td colspan="2"><input type="file" name="file" /></td></tr>';
+        $res .= '<tr class="odd"><td>' . __('Bord arrondi') . '</td>';
+        $res .= '<td><input type="number" name="round" value="0" size="5" />%</td><td>' . __('Valeurs typiques') . ' : <br>iOS : 17.54%<br />' . __('Aucun arrondi') . ' : 0%</td></tr>';
+        $res .= '<tr><td colspan="3">' . __("L'arrondi ne sera pas appliqué aux icônes iOS, le système lui même se chargeant d'y appliquer les arrondis et les reflets") . '</td></tr>';
+        $res .= '<tr class="odd"><td class="right" colspan="3"><a href="#" class="submit">' . $core->typo->BoutonOK(__('Générer le favicon')) . '</a></td></td>';
+        $res .= '</table>';
+        $res .= '</form>';
+        $res .= '</div>';
+        $res .= commonPage::bf();
+        $res .= commonPage::bMain();
+        return $res;
+    }
+
+    public static function webfonts($args)
+    {
+        global $core;
+        $res = commonPage::barre();
+        $res .= commonPage::tMain();
+        $res .= commonPage::bh();
+        $res .= '<form action="' . SITE_PATH . 'tools/makeWebfont" method="post" class="notajax" enctype="multipart/form-data">';
+        $res .= '<table class="liste">';
+        $res .= '<tr><th><strong>' . __('Générer un kit webfont') . '</strong></th></tr>';
+        $res .= '<tr><td>' . __('Veuillez charger une police de caractères') . '</td></tr>';
+        $res .= '<tr class="odd"><td><input type="file" name="file[]" multiple="multiple" /></td></tr>';
+        $res .= '<tr><td><label><input type="checkbox" value="1" name="rename" /> Renommer les polices</label></td></tr>';
+        $res .= '<tr><td class="right"><a href="#" class="submit">' . $core->typo->BoutonOK(__('Générer le kit webfont')) . '</a></td></td>';
+        $res .= '</table>';
+        $res .= '</form>';
+        $res .= '</div>';
+        $res .= commonPage::bf();
+        $res .= commonPage::bMain();
+        return $res;
+    }
+
+    public static function makeWebfont()
+    {
+        $tmp = cubeFiles::tempdir();
+        if (!file_exists($tmp)) {
+            mkdir($tmp, 0777, true);
+        }
+
+        $rename = isset($_POST['rename']);
+
+
+        foreach ($_FILES['file']['name'] as $k => $name) {
+            $tmp_name = $_FILES['file']['tmp_name'][$k];
+
+            $ex = explode('.', strtolower($name));
+            $upext = array_pop($ex);
+            $fontName = implode('.', $ex);
+
+            $fontFile = $tmp . '/' . strtolower($name);
+            move_uploaded_file($tmp_name, $fontFile);
+
+            $ext = array('ttf', 'woff', 'woff2', 'eot', 'php');
+
+            foreach ($ext as $e) {
+                $out = $tmp . '/' . $fontName . '.' . $e;
+                if ($e == 'ttf' || $e == 'woff') {
+
+                    $fontforge = new cubeCommandLine('convertrn.pe');
+                    $fontforge->setPath(CONVERTER_PATH);
+                    $fontforge->setArg(null, $fontFile);
+                    $fontforge->setArg(null, $out);
+                    if ($rename) {
+                        $fontforge->setArg(null, $fontName);
+                    }
+                    $fontforge->execute();
+
+                    fb($fontforge->commande);
+                    fb($fontforge->output);
+                } else if ($e == 'eot') {
+                    $ttf = $tmp . '/' . $fontName . '.ttf';
+                    `/usr/local/bin/ttf2eot < $ttf > $out`;
+                } else if ($e == 'woff2') {
+                    $ttf = $tmp . '/' . $fontName . '.ttf';
+                    `cat $ttf | ttf2woff2 >> $out`;
+                } else if ($e == 'php') {
+                    $ttf = $tmp . '/' . $fontName . '.ttf';
+                    include ROOT . '/inc/cube/externals/fpdf/makefont/makefont.php';
+                    Makefont($ttf);
+                    rename(ROOT . '/' . $fontName . '.z', $tmp . '/' . $fontName . '.z');
+                    rename(ROOT . '/' . $fontName . '.php', $tmp . '/' . $fontName . '.php');
+                }
+            }
+
+            $css = "@font-face {
     font-family: '$fontName';
     src: url('$fontName.eot');
     src: url('$fontName.eot?#iefix') format('embedded-opentype'),
@@ -442,831 +442,849 @@ class commonTools
     font-style: normal;
 }";
 
-                       file_put_contents($tmp . '/' . $fontName . '.css', $css);
-               }
-
-               $tmpfile = cubeFiles::tempnam() . '.zip';
+            file_put_contents($tmp . '/' . $fontName . '.css', $css);
+        }
+
+        $tmpfile = cubeFiles::tempnam() . '.zip';
+
+        $zip = new cubeCommandLine('zip');
+        $zip->cd($tmp);
+        $zip->setArg(null, $tmpfile);
+        $zip->setArg('0');
+        $zip->setArg('u');
+        $zip->setArg('r');
+        $zip->setArg('X');
+        $zip->setArg(null, '.');
+        $zip->execute();
+
+        cubeHTTP::downloadFile($tmpfile, $fontName . '.zip');
+    }
+
+    public static function makeFavicon()
+    {
+        $tmp = cubeFiles::tempdir();
+        mkdir($tmp, 0777, true);
+
+        $upload = $tmp . '/upload.png';
+        move_uploaded_file($_FILES['file']['tmp_name'], $upload);
+
+        $dim = getimagesize($upload);
+
+        if (!isset($_POST['round']) || $_POST['round'] == 0) {
+            $round = $upload;
+        } else {
+            $round = $tmp . '/round.png';
+
+            $conv = new CubeIT_CommandLine_Imagemagick_Round();
+            $conv->setSrc($upload);
+            $conv->setDest($round);
+            $conv->setRadius($_POST['round']);
+            $conv->execute();
+            //$conv->debug();
+        }
+
+        $icotool = new cubeCommandLine('icotool');
+        $icotool->setArg('c');
+        $icotool->setArg('o', $tmp . '/favicon.ico');
+
+        $icoSizes = array(8, 16, 20, 24, 32, 40, 48, 64, 96, 128, 256, 512);
+        $sizes = array(16, 32, 48, 64, 128, 256, 512);
+        $apple = array(152, 144, 120, 114, 76, 72, 57);
+
+        $sizes = array_merge($icoSizes, $sizes, $apple);
+        rsort($sizes);
+
+        self::pngToIcns($round, $tmp . '/favicon.icns');
+
+        foreach ($sizes as $s) {
+            if (in_array($s, $apple)) {
+                $r = $tmp . '/favicon-ios-' . $s . '.png';
+                $it = new cubeImageTools();
+                $it->loadImage($upload);
+                $it->resize($s, $s, 'crop', true, 'C', 'M', 'transparent');
+                $it->output('png', $r);
+            }
+            $r = $tmp . '/ico-' . $s . '.png';
+            $it = new cubeImageTools();
+            $it->loadImage($round);
+            $it->resize($s, $s, 'crop', true, 'C', 'M', 'transparent');
+            $it->output('png', $r);
+            if (in_array($s, $apple)) {
+                continue;
+            }
+
+
+            if (in_array($s, $icoSizes)) {
+                $icotool->setArg(null, $r);
+            }
+
+
+        }
+
+        $icotool->execute();
+
+        rename($tmp . '/ico-16.png', $tmp . '/favicon.png');
+
+        foreach ($sizes as $s) {
+            if ($s == 16) {
+                continue;
+            }
+            unlink($tmp . '/ico-' . $s . '.png');
+        }
+
+        $tmpfile = cubeFiles::tempnam() . '.zip';
+
+        $zip = new cubeCommandLine('zip');
+        $zip->cd($tmp);
+        $zip->setArg(null, $tmpfile);
+        $zip->setArg('0');
+        $zip->setArg('u');
+        $zip->setArg('r');
+        $zip->setArg('X');
+        $zip->setArg(null, '.');
+        $zip->execute();
+
+        cubeHTTP::downloadFile($tmpfile, 'favicon.zip');
+
+        // Clean !
+        unlink($tmpfile);
+        unlink($round);
+        `rm -rf $tmp`;
+    }
+
+    public static function pngToIcns($file, $res)
+    {
+        if (!file_exists($file)) {
+            return;
+        }
+        $icns = array(128, 256, 512);
+
+        $png2icns = new CubeIT_CommandLine('png2icns');
+        $png2icns->setArg(null, $res);
+
+        $tmp = array();
+
+        foreach ($icns as $s) {
+            $r = CubeIT_Files::tempnam() . '.png';
+            $tmp[] = $r;
+            $it = new cubeImageTools();
+            $it->loadImage($file);
+            $it->resize($s, $s, 'crop', true, 'C', 'M', 'transparent');
+            $it->output('png', $r);
+            if (in_array($s, $icns)) {
+                $png2icns->setArg(null, $r);
+            }
+        }
+
+        $png2icns->execute();
+        $png2icns->debug();
+        foreach ($tmp as $item) {
+            unlink($tmp);
+        }
+    }
+
+    public static function getDefaultLanguage()
+    {
+        $available = explode(',', $_GET['available']);
+        $accept = null;
+        if (isset($_GET['accept'])) {
+            $accept = base64_decode($_GET['accept']);
+        }
+        header('Content-type: text/plain');
+        header('Access-Control-Allow-Origin: *', true);
+        header('Access-Control-Allow-Methods: GET', true);
+        ob_end_clean();
+        echo cubeLang::getBrowserLang($available, true, $accept);
+        exit;
+    }
+
+    public static function uglify()
+    {
+        $js = '';
+        if (isset($_POST['js'])) {
+            $js = $_POST['js'];
+        } else if (isset($_GET['js'])) {
+            $js = $_GET['js'];
+        }
+
+
+        if ($js == '') {
+            ob_end_clean();
+            exit;
+        }
+        $tmp = cubeFiles::tempnam();
+        $res = cubeFiles::tempnam();
+        file_put_contents($tmp, $js);
+        $uglify = new cubeCommandLine('uglifyjs');
+        $uglify->setPath(CONVERTER_PATH);
+        $uglify->setArg(null, $tmp);
+        $uglify->setArg('o', $res);
+        $uglify->setArg('c');
+        $uglify->setArg('m');
+        $uglify->execute();
+        ob_end_clean();
+
+        header('Content-type: text/javascript');
+        if (file_exists($res)) {
+            echo file_get_contents($res);
+            unlink($res);
+        }
+        unlink($tmp);
+        exit;
+    }
+
+    public static function csr()
+    {
+        commonDroits::min(1);
+        global $core;
+        $res = commonPage::barre();
+        $res .= commonPage::tMain();
+        $res .= commonPage::bh();
+        $res .= '<form action="' . SITE_PATH . 'tools/makeCsr" method="post" class="notajax" enctype="multipart/form-data">';
+        $res .= '<table class="liste">';
+        $res .= '<tr><th colspan="2"><strong>' . __('Générer une demande de signature de certificat') . '</strong></th></tr>';
+        $res .= '<tr><td>' . __("Email") . '</td><td>' . form::field('email', 64, 64, $core->user->email) . '</td></tr>';
+        $res .= '<tr><td>' . __("Nom") . '</td><td>' . form::field('nom', 64, 128, $core->user->prenom . ' ' . $core->user->nom) . '</td></tr>';
+        $res .= '<tr><td>' . __('Pays') . '</td><td>' . form::combo('country', cubeCountry::getList(false), $core->user->pays) . '</td></tr>';
+        $res .= '<tr><td class="right" colspan="2"><a href="#" class="submit">' . $core->typo->BoutonOK(__('Générer la demande de signature')) . '</a></td></td>';
+        $res .= '</table>';
+        $res .= '</form>';
+        $res .= commonPage::bf();
+
+        $res .= commonPage::bh();
+        $res .= '<form action="' . SITE_PATH . 'tools/makeP12" method="post" class="notajax" enctype="multipart/form-data">';
+        $res .= '<table class="liste">';
+        $res .= '<tr><th colspan="2"><strong>' . __('Générer un p12 et pem à partir d\'un certificat et d\'une clé ') . '</strong></th></tr>';
+        $res .= '<tr><td>' . __("Clé privée") . '</td><td><input type="file" name="key" /></td></tr>';
+        $res .= '<tr><td>' . __("Certificat") . '</td><td><input type="file" name="cert" /></td></tr>';
+        $res .= '<tr><td>' . __('Mot de passe') . '</td><td><input type="text" name="password" /></td></tr>';
+        $res .= '<tr><td class="right" colspan="2"><a href="#" class="submit">' . $core->typo->BoutonOK(__('Exporter')) . '</a></td></td>';
+        $res .= '</table>';
+        $res .= '</form>';
+        $res .= commonPage::bf();
+
+        $res .= commonPage::bMain();
+        return $res;
+    }
+
+    public static function makeP12()
+    {
+        //http://help.adobe.com/en_US/as3/iphone/WS144092a96ffef7cc-371badff126abc17b1f-7fff.html
+        commonDroits::min(1);
+        $tmp = cubeFiles::tempdir();
+        if (!file_exists($tmp)) {
+            mkdir($tmp, 0777, true);
+        }
+
+        $e = explode('.', $_FILES['cert']['name']);
+        array_pop($e);
+        $base = CubeIT_Text::str2URL(implode('.', $e));
+
+        $pem = $tmp . '/' . $base . '.pem';
+        $p12 = $tmp . '/' . $base . '.p12';
+
+        // Generate pem file
+        $openssl = new cubeCommandLine('openssl');
+        $openssl->setPath(CONVERTER_PATH);
+        $openssl->setArg(null, 'x509');
+        $openssl->setArg('-in', $_FILES['cert']['tmp_name']);
+        $openssl->setArg('-inform', 'DER');
+        $openssl->setArg('-out', $pem);
+        $openssl->setArg('-outform', 'PEM');
+        $openssl->execute();
+
+        print($openssl->commande);
+        print($openssl->output);
+
+        // Generate p12 file
+        $openssl = new cubeCommandLine('openssl');
+        $openssl->setPath(CONVERTER_PATH);
+        $openssl->setEnv('RANDFILE', $tmp . '/.rnd');
+        $openssl->setArg(null, 'pkcs12');
+        $openssl->setArg('-export');
+        $openssl->setArg('-password', 'pass:' . $_POST['password']);
+        $openssl->setArg('-inkey', $_FILES['key']['tmp_name']);
+        $openssl->setArg('-in', $pem);
+        $openssl->setArg('-out', $p12);
+        $openssl->execute();
+
+        fb($openssl->commande);
+        fb($openssl->output);
+
+        // Generate pem bundle file
+        $openssl = new cubeCommandLine('openssl');
+        $openssl->setPath(CONVERTER_PATH);
+        $openssl->setEnv('RANDFILE', $tmp . '/.rnd');
+        $openssl->setArg(null, 'pkcs12');
+        $openssl->setArg('-password', 'pass:' . $_POST['password']);
+        $openssl->setArg('-in', $p12);
+        $openssl->setArg('-out', $pem);
+        $openssl->setArg('-nodes');
+        $openssl->setArg('-clcerts');
+        $openssl->execute();
+
+        fb($openssl->commande);
+        fb($openssl->output);
+
+        unlink($tmp . '/.rnd');
+
+        $tmpfile = cubeFiles::tempnam() . '.zip';
+
+        $zip = new cubeCommandLine('zip');
+        $zip->cd($tmp);
+        $zip->setArg(null, $tmpfile);
+        $zip->setArg('0');
+        $zip->setArg('u');
+        $zip->setArg('r');
+        $zip->setArg('X');
+        $zip->setArg(null, '.');
+        $zip->execute();
+
+        cubeHTTP::downloadFile($tmpfile, $base . '.zip');
+    }
+
+    public static function makeCsr()
+    {
+
+        // http://help.adobe.com/en_US/as3/iphone/WS144092a96ffef7cc-371badff126abc17b1f-8000.html
+
+        commonDroits::min(1);
+        $tmp = cubeFiles::tempdir();
+        if (!file_exists($tmp)) {
+            mkdir($tmp, 0777, true);
+        }
+
+        // générate key
+        $openssl = new cubeCommandLine('openssl');
+        $openssl->setPath(CONVERTER_PATH);
+        $openssl->setArg(null, 'genrsa');
+        $openssl->setArg('-out', $tmp . '/' . $_POST['email'] . '.key');
+        $openssl->setArg(null, '2048');
+        $openssl->execute();
+
+        // Generate csr
+        // openssl req -new -key mykey.key -out CertificateSigningRequest.certSigningRequest  -subj "/emailAddress=yourAddress@example.com, CN=John Doe, C=US"
+        $openssl = new cubeCommandLine('openssl');
+        $openssl->setPath(CONVERTER_PATH);
+        $openssl->setArg(null, 'req');
+        $openssl->setArg('-new');
+        $openssl->setArg('-key', $tmp . '/' . $_POST['email'] . '.key');
+        $openssl->setArg('-out', $tmp . '/CertificateSigningRequest.certSigningRequest');
+        $openssl->setArg('-subj', '/emailAddress=' . $_POST['email'] . ', CN=' . $_POST['nom'] . ', C=' . $_POST['country']);
+        $openssl->execute();
+
+        $tmpfile = cubeFiles::tempnam() . '.zip';
+
+        $zip = new cubeCommandLine('zip');
+        $zip->cd($tmp);
+        $zip->setArg(null, $tmpfile);
+        $zip->setArg('0');
+        $zip->setArg('u');
+        $zip->setArg('r');
+        $zip->setArg('X');
+        $zip->setArg(null, '.');
+        $zip->execute();
+
+        cubeHTTP::downloadFile($tmpfile, 'csr.zip');
+    }
+
+    public static function geocode()
+    {
+
+        $opt = array();
+        $opt['adapter'] = 'pdo_mysql';
+        $opt['params']['charset'] = 'utf8';
+        $opt['params']['adapterNamespace'] = 'CubeIT_Db_Adapter';
+        $opt['params']['host'] = DB_HOST;
+        $opt['params']['username'] = DB_USER;
+        $opt['params']['password'] = DB_PASSWORD;
+        $opt['params']['dbname'] = DB_NAME;
+        $db = Zend_Db::factory($opt['adapter'], $opt['params']);
+        $db->setFetchMode(Zend_Db::FETCH_OBJ);
+        Zend_Db_Table::setDefaultAdapter($db);
+
+        header('Content-type: application/json');
+        ob_end_clean();
+        $geocoder = new CubeIT_Services_Google_Geocoder(864000, false);
+        $r = $geocoder->geocode(urldecode($_GET['address']), $_GET['region'], true);
+        echo CubeIT_Util_Json::encode($r);
+        exit;
+    }
+
+    public static function syncftp()
+    {
+        commonDroits::min(2);
+        global $core;
+        $res = commonPage::barre();
+        $res .= commonPage::tMain();
+        $res .= commonPage::bh();
+        $res .= '<form action="syncftp" method="post">';
+        $res .= '<table class="liste">';
+        $res .= '<tr><th colspan="2"><strong>' . __('Synchronisation FTP <-> Local') . '</strong></th></tr>';
+        $res .= '<tr><td>Source (local)</td><td>' . form::field('source', 40, 512) . '</td></tr>';
+        $res .= '<tr><td>Destination (distant)</td><td>ftp://' . form::field('dest', 40, 512) . '</td></tr>';
+        $res .= '<tr><td>Mode</td><td>' . form::combo('mode', array(__('Actif') => 'off', __('Passif') => 'on')) . '</td></tr>';
+        $res .= '<tr><td>Résultat</td><td>' . form::textArea('res', 50, 20) . '</td></tr>';
+        $res .= '<tr><td class="right" colspan="2"><a href="#" class="submit">' . $core->typo->BoutonOK(__('Synchronisation')) . '</a></td></td>';
+        $res .= '</table>';
+        $res .= '</form>';
+        $res .= '</div>';
+        $res .= commonPage::bf();
+        $res .= commonPage::bMain();
+        return $res;
+    }
+
+    public static function googleLucky()
+    {
 
-               $zip = new cubeCommandLine('zip');
-               $zip->cd($tmp);
-               $zip->setArg(null, $tmpfile);
-               $zip->setArg('0');
-               $zip->setArg('u');
-               $zip->setArg('r');
-               $zip->setArg('X');
-               $zip->setArg(null, '.');
-               $zip->execute();
-
-               cubeHTTP::downloadFile($tmpfile, $fontName . '.zip');
-       }
-
-       public static function makeFavicon()
-       {
-               $tmp = cubeFiles::tempdir();
-               mkdir($tmp, 0777, true);
-
-               $upload = $tmp . '/upload.png';
-               move_uploaded_file($_FILES['file']['tmp_name'], $upload);
+        $q = $_GET['q'];
+        $cx = $_GET['cx'];
+        $keys = array('AIzaSyBdYNtOMDzG66F29SgYdq9r-4Nabzaq9q0', 'AIzaSyCfivE2-R2fMp-F9Q5nvBHjgSdKFjTu_9A');
+        shuffle($keys);
+        $key = array_shift($keys);
 
-               $dim = getimagesize($upload);
-
-               if (!isset($_POST['round']) || $_POST['round'] == 0) {
-                       $round = $upload;
-               } else {
-                       $round = $tmp . '/round.png';
-
-                       $conv = new CubeIT_CommandLine_Imagemagick_Round();
-                       $conv->setSrc($upload);
-                       $conv->setDest($round);
-                       $conv->setRadius($_POST['round']);
-                       $conv->execute();
-                       //$conv->debug();
-               }
-
-
-               $icotool = new cubeCommandLine('icotool');
-               $icotool->setArg('c');
-               $icotool->setArg('o', $tmp . '/favicon.ico');
-
-               $icoSizes = array(8, 16, 20, 24, 32, 40, 48, 64, 96, 128, 256, 512);
-               $sizes = array(16, 32, 48, 64, 128, 256, 512);
-               $apple = array(152, 144, 120, 114, 76, 72, 57);
-
-
-               $sizes = array_merge($icoSizes, $sizes, $apple);
-               rsort($sizes);
-
-               self::pngToIcns($round, $tmp . '/favicon.icns');
-
-               foreach ($sizes as $s) {
-                       if (in_array($s, $apple)) {
-                               $r = $tmp . '/favicon-ios-' . $s . '.png';
-                               $it = new cubeImageTools();
-                               $it->loadImage($upload);
-                               $it->resize($s, $s, 'crop', true, 'C', 'M', 'transparent');
-                               $it->output('png', $r);
-                       }
-                       $r = $tmp . '/ico-' . $s . '.png';
-                       $it = new cubeImageTools();
-                       $it->loadImage($round);
-                       $it->resize($s, $s, 'crop', true, 'C', 'M', 'transparent');
-                       $it->output('png', $r);
-                       if (in_array($s, $apple)) {
-                               continue;
-                       }
-
-
-                       if (in_array($s, $icoSizes)) {
-                               $icotool->setArg(null, $r);
-                       }
-
-
-               }
-
-               $icotool->execute();
-
-               rename($tmp . '/ico-16.png', $tmp . '/favicon.png');
-
-               foreach ($sizes as $s) {
-                       if ($s == 16) {
-                               continue;
-                       }
-                       unlink($tmp . '/ico-' . $s . '.png');
-               }
-
-               $tmpfile = cubeFiles::tempnam() . '.zip';
-
-               $zip = new cubeCommandLine('zip');
-               $zip->cd($tmp);
-               $zip->setArg(null, $tmpfile);
-               $zip->setArg('0');
-               $zip->setArg('u');
-               $zip->setArg('r');
-               $zip->setArg('X');
-               $zip->setArg(null, '.');
-               $zip->execute();
-
-               cubeHTTP::downloadFile($tmpfile, 'favicon.zip');
-
-               // Clean !
-               unlink($tmpfile);
-               unlink($round);
-               `rm -rf $tmp`;
-       }
-
-       public static function pngToIcns($file, $res)
-       {
-               if (!file_exists($file)) {
-                       return;
-               }
-               $icns = array(128, 256, 512);
-
-               $png2icns = new CubeIT_CommandLine('png2icns');
-               $png2icns->setArg(null, $res);
-
-               $tmp = array();
-
-               foreach ($icns as $s) {
-                       $r = CubeIT_Files::tempnam() . '.png';
-                       $tmp[] = $r;
-                       $it = new cubeImageTools();
-                       $it->loadImage($file);
-                       $it->resize($s, $s, 'crop', true, 'C', 'M', 'transparent');
-                       $it->output('png', $r);
-                       if (in_array($s, $icns)) {
-                               $png2icns->setArg(null, $r);
-                       }
-               }
-
-               $png2icns->execute();
-               $png2icns->debug();
-               foreach ($tmp as $item) {
-                       unlink($tmp);
-               }
-       }
-
-       public static function getDefaultLanguage()
-       {
-               $available = explode(',', $_GET['available']);
-               $accept = null;
-               if (isset($_GET['accept'])) {
-                       $accept = base64_decode($_GET['accept']);
-               }
-               header('Content-type: text/plain');
-               header('Access-Control-Allow-Origin: *', true);
-               header('Access-Control-Allow-Methods: GET', true);
-               ob_end_clean();
-               echo cubeLang::getBrowserLang($available, true, $accept);
-               exit;
-       }
-
-       public static function uglify()
-       {
-               $js = '';
-               if (isset($_POST['js'])) {
-                       $js = $_POST['js'];
-               } else if (isset($_GET['js'])) {
-                       $js = $_GET['js'];
-               }
-
-
-               if ($js == '') {
-                       ob_end_clean();
-                       exit;
-               }
-               $tmp = cubeFiles::tempnam();
-               $res = cubeFiles::tempnam();
-               file_put_contents($tmp, $js);
-               $uglify = new cubeCommandLine('uglifyjs');
-               $uglify->setPath(CONVERTER_PATH);
-               $uglify->setArg(null, $tmp);
-               $uglify->setArg('o', $res);
-               $uglify->setArg('c');
-               $uglify->setArg('m');
-               $uglify->execute();
-               ob_end_clean();
-
-               header('Content-type: text/javascript');
-               if (file_exists($res)) {
-                       echo file_get_contents($res);
-                       unlink($res);
-               }
-               unlink($tmp);
-               exit;
-       }
-
-       public static function csr()
-       {
-               commonDroits::min(1);
-               global $core;
-               $res = commonPage::barre();
-               $res .= commonPage::tMain();
-               $res .= commonPage::bh();
-               $res .= '<form action="' . SITE_PATH . 'tools/makeCsr" method="post" class="notajax" enctype="multipart/form-data">';
-               $res .= '<table class="liste">';
-               $res .= '<tr><th colspan="2"><strong>' . __('Générer une demande de signature de certificat') . '</strong></th></tr>';
-               $res .= '<tr><td>' . __("Email") . '</td><td>' . form::field('email', 64, 64, $core->user->email) . '</td></tr>';
-               $res .= '<tr><td>' . __("Nom") . '</td><td>' . form::field('nom', 64, 128, $core->user->prenom . ' ' . $core->user->nom) . '</td></tr>';
-               $res .= '<tr><td>' . __('Pays') . '</td><td>' . form::combo('country', cubeCountry::getList(false), $core->user->pays) . '</td></tr>';
-               $res .= '<tr><td class="right" colspan="2"><a href="#" class="submit">' . $core->typo->BoutonOK(__('Générer la demande de signature')) . '</a></td></td>';
-               $res .= '</table>';
-               $res .= '</form>';
-               $res .= commonPage::bf();
-
-               $res .= commonPage::bh();
-               $res .= '<form action="' . SITE_PATH . 'tools/makeP12" method="post" class="notajax" enctype="multipart/form-data">';
-               $res .= '<table class="liste">';
-               $res .= '<tr><th colspan="2"><strong>' . __('Générer un p12 et pem à partir d\'un certificat et d\'une clé ') . '</strong></th></tr>';
-               $res .= '<tr><td>' . __("Clé privée") . '</td><td><input type="file" name="key" /></td></tr>';
-               $res .= '<tr><td>' . __("Certificat") . '</td><td><input type="file" name="cert" /></td></tr>';
-               $res .= '<tr><td>' . __('Mot de passe') . '</td><td><input type="text" name="password" /></td></tr>';
-               $res .= '<tr><td class="right" colspan="2"><a href="#" class="submit">' . $core->typo->BoutonOK(__('Exporter')) . '</a></td></td>';
-               $res .= '</table>';
-               $res .= '</form>';
-               $res .= commonPage::bf();
-
-               $res .= commonPage::bMain();
-               return $res;
-       }
-
-       public static function makeP12()
-       {
-               //http://help.adobe.com/en_US/as3/iphone/WS144092a96ffef7cc-371badff126abc17b1f-7fff.html
-               commonDroits::min(1);
-               $tmp = cubeFiles::tempdir();
-               if (!file_exists($tmp)) {
-                       mkdir($tmp, 0777, true);
-               }
-
-               $e = explode('.', $_FILES['cert']['name']);
-               array_pop($e);
-               $base = CubeIT_Text::str2URL(implode('.', $e));
-
-               $pem = $tmp . '/' . $base . '.pem';
-               $p12 = $tmp . '/' . $base . '.p12';
-
-               // Generate pem file
-               $openssl = new cubeCommandLine('openssl');
-               $openssl->setPath(CONVERTER_PATH);
-               $openssl->setArg(null, 'x509');
-               $openssl->setArg('-in', $_FILES['cert']['tmp_name']);
-               $openssl->setArg('-inform', 'DER');
-               $openssl->setArg('-out', $pem);
-               $openssl->setArg('-outform', 'PEM');
-               $openssl->execute();
-
-               print($openssl->commande);
-               print($openssl->output);
-
-               // Generate p12 file
-               $openssl = new cubeCommandLine('openssl');
-               $openssl->setPath(CONVERTER_PATH);
-               $openssl->setEnv('RANDFILE', $tmp . '/.rnd');
-               $openssl->setArg(null, 'pkcs12');
-               $openssl->setArg('-export');
-               $openssl->setArg('-password', 'pass:' . $_POST['password']);
-               $openssl->setArg('-inkey', $_FILES['key']['tmp_name']);
-               $openssl->setArg('-in', $pem);
-               $openssl->setArg('-out', $p12);
-               $openssl->execute();
-
-               fb($openssl->commande);
-               fb($openssl->output);
-
-               // Generate pem bundle file
-               $openssl = new cubeCommandLine('openssl');
-               $openssl->setPath(CONVERTER_PATH);
-               $openssl->setEnv('RANDFILE', $tmp . '/.rnd');
-               $openssl->setArg(null, 'pkcs12');
-               $openssl->setArg('-password', 'pass:' . $_POST['password']);
-               $openssl->setArg('-in', $p12);
-               $openssl->setArg('-out', $pem);
-               $openssl->setArg('-nodes');
-               $openssl->setArg('-clcerts');
-               $openssl->execute();
-
-               fb($openssl->commande);
-               fb($openssl->output);
-
-               unlink($tmp . '/.rnd');
-
-               $tmpfile = cubeFiles::tempnam() . '.zip';
-
-               $zip = new cubeCommandLine('zip');
-               $zip->cd($tmp);
-               $zip->setArg(null, $tmpfile);
-               $zip->setArg('0');
-               $zip->setArg('u');
-               $zip->setArg('r');
-               $zip->setArg('X');
-               $zip->setArg(null, '.');
-               $zip->execute();
-
-               cubeHTTP::downloadFile($tmpfile, $base . '.zip');
-       }
-
-       public static function makeCsr()
-       {
-
-               // http://help.adobe.com/en_US/as3/iphone/WS144092a96ffef7cc-371badff126abc17b1f-8000.html
-
-               commonDroits::min(1);
-               $tmp = cubeFiles::tempdir();
-               if (!file_exists($tmp)) {
-                       mkdir($tmp, 0777, true);
-               }
-
-               // générate key
-               $openssl = new cubeCommandLine('openssl');
-               $openssl->setPath(CONVERTER_PATH);
-               $openssl->setArg(null, 'genrsa');
-               $openssl->setArg('-out', $tmp . '/' . $_POST['email'] . '.key');
-               $openssl->setArg(null, '2048');
-               $openssl->execute();
-
-               // Generate csr
-               // openssl req -new -key mykey.key -out CertificateSigningRequest.certSigningRequest  -subj "/emailAddress=yourAddress@example.com, CN=John Doe, C=US"
-               $openssl = new cubeCommandLine('openssl');
-               $openssl->setPath(CONVERTER_PATH);
-               $openssl->setArg(null, 'req');
-               $openssl->setArg('-new');
-               $openssl->setArg('-key', $tmp . '/' . $_POST['email'] . '.key');
-               $openssl->setArg('-out', $tmp . '/CertificateSigningRequest.certSigningRequest');
-               $openssl->setArg('-subj', '/emailAddress=' . $_POST['email'] . ', CN=' . $_POST['nom'] . ', C=' . $_POST['country']);
-               $openssl->execute();
-
-               $tmpfile = cubeFiles::tempnam() . '.zip';
-
-               $zip = new cubeCommandLine('zip');
-               $zip->cd($tmp);
-               $zip->setArg(null, $tmpfile);
-               $zip->setArg('0');
-               $zip->setArg('u');
-               $zip->setArg('r');
-               $zip->setArg('X');
-               $zip->setArg(null, '.');
-               $zip->execute();
-
-               cubeHTTP::downloadFile($tmpfile, 'csr.zip');
-       }
-
-       public static function geocode()
-       {
-
-               $opt = array();
-               $opt['adapter'] = 'pdo_mysql';
-               $opt['params']['charset'] = 'utf8';
-               $opt['params']['adapterNamespace'] = 'CubeIT_Db_Adapter';
-               $opt['params']['host'] = DB_HOST;
-               $opt['params']['username'] = DB_USER;
-               $opt['params']['password'] = DB_PASSWORD;
-               $opt['params']['dbname'] = DB_NAME;
-               $db = Zend_Db::factory($opt['adapter'], $opt['params']);
-               $db->setFetchMode(Zend_Db::FETCH_OBJ);
-               Zend_Db_Table::setDefaultAdapter($db);
-
-               header('Content-type: application/json');
-               ob_end_clean();
-               $geocoder = new CubeIT_Services_Google_Geocoder(864000, false);
-               $r = $geocoder->geocode(urldecode($_GET['address']), $_GET['region'], true);
-               echo CubeIT_Util_Json::encode($r);
-               exit;
-       }
-
-       public static function syncftp()
-       {
-               commonDroits::min(2);
-               global $core;
-               $res = commonPage::barre();
-               $res .= commonPage::tMain();
-               $res .= commonPage::bh();
-               $res .= '<form action="syncftp" method="post">';
-               $res .= '<table class="liste">';
-               $res .= '<tr><th colspan="2"><strong>' . __('Synchronisation FTP <-> Local') . '</strong></th></tr>';
-               $res .= '<tr><td>Source (local)</td><td>' . form::field('source', 40, 512) . '</td></tr>';
-               $res .= '<tr><td>Destination (distant)</td><td>ftp://' . form::field('dest', 40, 512) . '</td></tr>';
-               $res .= '<tr><td>Mode</td><td>' . form::combo('mode', array(__('Actif') => 'off', __('Passif') => 'on')) . '</td></tr>';
-               $res .= '<tr><td>Résultat</td><td>' . form::textArea('res', 50, 20) . '</td></tr>';
-               $res .= '<tr><td class="right" colspan="2"><a href="#" class="submit">' . $core->typo->BoutonOK(__('Synchronisation')) . '</a></td></td>';
-               $res .= '</table>';
-               $res .= '</form>';
-               $res .= '</div>';
-               $res .= commonPage::bf();
-               $res .= commonPage::bMain();
-               return $res;
-       }
-
-       public static function googleLucky()
-       {
-
-               $q = $_GET['q'];
-               $cx = $_GET['cx'];
-               $keys = array('AIzaSyBdYNtOMDzG66F29SgYdq9r-4Nabzaq9q0', 'AIzaSyCfivE2-R2fMp-F9Q5nvBHjgSdKFjTu_9A');
-               shuffle($keys);
-               $key = array_shift($keys);
-
-               $r = self::searchGoogle($q, $cx, $key);
-               if (!is_null($r)) {
-                       http::redirect($r['items'][0]['link']);
-               }
-       }
-
-       public static function copyWsAssets()
-       {
-               commonDroits::min(5);
-               global $core;
-               $res = commonPage::barre();
-               $res .= commonPage::tMain();
-               $res .= commonPage::bh();
-               $res .= '<form id="copywsassets" action="copywsassets" method="post">';
-               $res .= '<table class="liste">';
-               $res .= '<tr><th><strong>' . __("Copie de fichiers entre deux fluidbook") . '</strong></th></tr>';
-               $res .= '<tr><td>Fluidbook source</td><td>' . form::field('source', 5, 6) . '</td></tr>';
-               $res .= '<tr><td>Fluidbook destination</td><td>' . form::field('dest', 5, 6) . '</td></tr>';
-               $res .= '<tr><td>Fichiers à transférer</td><td id="f">Entrez le numéro du fluidbook source pour sélectionner les fichiers à transférer</td></tr>';
-               $res .= '<tr><td class="right" colspan="2"><a href="#" class="submit">' . $core->typo->BoutonOK(__('Copier')) . '</a></td></td>';
-               $res .= '</table>';
-               $res .= '</form>';
-               $res .= '</div>';
-               $res .= commonPage::bf();
-               $res .= commonPage::bMain();
-               return $res;
-       }
-
-       protected static function searchGoogle($q, $cx, $key)
-       {
-               global $core;
-
-               $url = 'https://www.googleapis.com/customsearch/v1?q=' . rawurlencode($q) . '&cx=' . $cx;
-               $limit = TIME - (3600 * 24 * 10); // Cache de 10j
-
-               $r = $core->con->select('SELECT date,response FROM google_search_api WHERE request=\'' . $core->con->escape($url) . '\'');
-               if ($r->count()) {
-                       $cached = $r->response;
-                       if ($r->date > $limit) {
-                               fb('got cache');
-                               return json_decode($cached, true);
-                       }
-               }
-
-
-               $j = file_get_contents($url . '&key=' . $key);
-               $json = json_decode($j, true);
-               if (isset($json['items'][0]['link'])) {
-                       $c = $core->con->openCursor('google_search_api');
-                       $c->request = $url;
-                       $c->response = $j;
-                       $c->date = TIME;
-                       try {
-                               $c->insert();
-                       } catch (Exception $e) {
-                               $c->update('WHERE request=\'' . $core->con->escape($url) . '\'');
-                       }
-                       return $json;
-               }
-
-               if (isset($cached)) {
-                       return json_decode($cached, true);
-               } else {
-                       return null;
-               }
-       }
-
-       public static function devspace()
-       {
-               commonDroits::min(1);
-               global $core;
-
-               $equipiers = array();
-               $dao = new commonDAOEquipier($core->con);
-               $liste = $dao->getListe(null, 'email', 'ASC', null);
-               foreach ($liste as $e) {
-                       $equipiers[$e->email] = $e->email;
-               }
-
-               $res = commonPage::barre();
-               $res .= commonPage::tMain();
-               $res .= commonPage::bh();
-               $res .= '<form action="createDevSpace" method="post">';
-               $res .= '<table class="liste">';
-               $res .= '<tr><th colspan="2"><strong>' . __('Création d\'un espace de développement') . '</strong></th></tr>';
-               $res .= '<tr><td>' . __('Sous-domaine') . '</td><td>' . form::field('domain', 20, 512) . '.dev.cubedesigners.com</td></tr>';
-               $res .= '<tr><td>' . __('SVN') . '</td><td>svn+ssh://svn@svn.cubedesigners.com/projects/' . form::field('svn', 20, 512) . '</td></tr>';
-               $res .= '<tr><td>' . __('Utilisateur') . '</td><td>' . form::field('user', 20, 512) . ' (' . __('Si différent du sous-domaine') . ')</td></tr>';
-               $res .= '<tr><td>' . __('Namespace Zend') . '</td><td>' . form::field('zend', 20, 512) . ' (' . __('Laisser vide pour un projet vide') . ')</td></tr>';
-               $res .= '<tr><td>' . __('Créer des utilisateurs') . '</td><td>' . cubeForm::checkMultiple('users', $equipiers, 8, array($core->user->email)) . '</td></tr>';
-               $res .= '<tr><td class="right" colspan="2"><a href="#" class="submit">' . $core->typo->BoutonOK(__('Création')) . '</a></td></td>';
-
-               $res .= '</table>';
-               $res .= '</form>';
-               $res .= '</div>';
-               $res .= commonPage::bf();
-               $res .= commonPage::bMain();
-               return $res;
-       }
-
-       public static function createGitRepos()
-       {
-               commonDroits::min(0.5);
-               global $core;
-
-               $res = commonPage::barre();
-               $res .= commonPage::tMain();
-               $res .= commonPage::bh();
-               $res .= '<form action="createGitRepos" method="post">';
-               $res .= '<div id="res">';
-               $res .= '<table class="liste">';
-               $res .= '<tr><th colspan="2"><strong>' . __('Création d\'un dépôt git') . '</strong></th></tr>';
-               $res .= '<tr><td>' . __('Dépôt') . '</td><td>git@git.cubedesigners.com:' . form::field('repos', 20, 512) . '.git</td></tr>';
-               $res .= '<tr><td class="right" colspan="2"><a href="#" class="submit">' . $core->typo->BoutonOK(__('Création')) . '</a></td></td>';
-               $res .= '</table>';
-               $res .= '</div>';
-               $res .= '</form>';
-               $res .= '</div>';
-               $res .= commonPage::bf();
-               $res .= commonPage::bMain();
-               return $res;
-       }
-
-
-       public static function mailer()
-       {
-               commonDroits::min(1);
-               global $core;
-               $res = commonPage::barre();
-               $res .= commonPage::tMain();
-               $res .= commonPage::bh();
-               $res .= '<form action="postMailer" method="post" enctype="multipart/form-data">';
-               $res .= '<table class="liste">';
-               $res .= '<tr><th colspan="3"><strong>' . __('Envoi d\'un mailing') . '</strong></th></tr>';
-               $res .= '<tr><td>' . __('Sources') . '</td><td>' . cubeForm::filehtml('src') . '</td><td>' . __('Fichier contenant les sources html et images du mail') . '</td></tr>';
-               $res .= '<tr><td>' . __('Sujet') . '</td><td>' . form::field('subject', 50, 512, '[Extranet Mailer] ' . date('Y-m-d H:i')) . '</td><td>' . '</td></tr>';
-               $res .= '<tr><td>' . __('Expéditeur') . '</td><td>' . form::hidden('from', $core->user->email) . $core->user->email . '</td><td>' . '</td></tr>';
-               $res .= '<tr><td>' . __('Destinataire(s)') . '</td><td>' . form::field('to', 50, 512, $core->user->email) . '</td><td>' . __('Séparer les adresses par des virgules') . '</td></tr>';
-               $res .= '<tr><td class="right" colspan="3"><a href="#" class="submit">' . $core->typo->BoutonOK(__('Envoi')) . '</a></td></td>';
-               $res .= '</table>';
-               $res .= '</form>';
-               $res .= '</div>';
-               $res .= commonPage::bf();
-               $res .= commonPage::bMain();
-               return $res;
-       }
-
-       public function rasterize()
-       {
-               $type = isset($_GET['type']) ? $_GET['type'] : 'png';
-               $intype = CubeIT_Files::getExtension($_GET['src']);
-
-               $src = cubeFiles::tempnam() . '.' . $intype;
-               $dest = cubeFiles::tempnam() . '.' . $type;
-
-               copy($_GET['src'], $src);
-
-
-               $scale = isset($_GET['scale']) ? $_GET['scale'] : 1;
-
-               $cl = new CubeIT_CommandLine('convert');
-               if ($intype == 'svg') {
-                       $cl->setManualArg('-background none -flatten');
-               } else if ($intype == 'pdf') {
-                       $cl->setManualArg('-density ' . (round(75 * $scale)));
-                       $cl->setManualArg('-background white');
-               }
-
-               if ($intype == 'pdf') {
-                       $cl->setArg(null, $src . '[0]');
-               } else {
-                       $cl->setArg(null, $src);
-               }
-               $cl->setArg(null, $dest);
-               $cl->execute();
-
-               ob_end_clean();
-
-               header('Content-type: image/png');
-               echo file_get_contents($dest);
-
-               unlink($src);
-               unlink($dest);
-               exit;
-       }
-
-       public static function chiffres()
-       {
-               global $core;
-               $datas_types = array();
-               $datas_entreprises = array();
-
-               $dao = new commonDAOClient($core->con);
-               $clients = $dao->getListe();
-
-               $dao = new commonDAOEntreprise($core->con);
-               $entreprises = $dao->getListe();
-
-               $dao = new extranetDAOFacture($core->con);
-               $factures = $dao->getListe('date_creation', 'ASC');
-
-               foreach ($factures as $f) {
-                       if ($f->status < 1 || $f->status > 2) {
-                               continue;
-                       }
-                       $client = $clients[$f->client_id];
-                       $entreprise = $entreprises[$client->entreprise];
-                       $annee = date('Y', $f->date_creation);
-
-                       if (!isset($datas_types[$entreprise->type])) {
-                               $datas_types[$entreprise->type] = array();
-                       }
-                       if (!isset($datas_types[$entreprise->type][$annee])) {
-                               $datas_types[$entreprise->type][$annee] = 0;
-                       }
-                       $datas_types[$entreprise->type][$annee] += $f->total_ht;
-                       sort($datas_types);
-
-                       $csv = fopen(ROOT . '/types.csv', 'wb');
-                       $range = array_merge(array(''), range(2006, date('Y')));
-                       fputcsv($csv, $range, ';');
-                       foreach ($datas_types as $type => $annees) {
-                               $line = array($type);
-                               foreach ($annees as $a => $m) {
-                                       $c = $a - 2005;
-                                       $line[$c] = $m;
-                               }
-                               fputcsv($csv, $line, ';');
-                       }
-                       fclose($csv);
-
-                       if (!isset($datas_entreprises[$entreprise->nom])) {
-                               $datas_entreprises[$entreprise->nom] = array();
-                       }
-                       if (!isset($datas_entreprises[$entreprise->nom][$annee])) {
-                               $datas_entreprises[$entreprise->nom][$annee] = 0;
-                       }
-                       $datas_entreprises[$entreprise->nom][$annee] += $f->total_ht;
-               }
-       }
-
-       public static function wspagestohtml()
-       {
-               commonDroits::min(5);
-               global $core;
-               $res = commonPage::barre();
-               $res .= commonPage::tMain();
-               $res .= commonPage::bh();
-               $res .= '<form action="/tools/dowspagestohtml" class="notajax" method="get">';
-               $res .= '<table class="liste">';
-               $res .= '<tr><th colspan="3"><strong>' . __('Convertir une page du fluidbook en HTML') . '</strong></th></tr>';
-               $res .= '<tr><td>' . __('Fluidbook') . '</td><td>' . form::field('fluidbook', 5, 5) . '</td></tr>';
-               $res .= '<tr><td>' . __('Page') . '</td><td>' . form::field('page', 5, 5) . '</td></tr>';
-               $res .= '<tr><td class="right" colspan="3"><a href="#" class="submit">' . $core->typo->BoutonOK(__('Convertir')) . '</a></td></td>';
-               $res .= '</table>';
-               $res .= '</form>';
-               $res .= '</div>';
-               $res .= commonPage::bf();
-               $res .= commonPage::bMain();
-               return $res;
-       }
-
-       public static function dowspagestohtml()
-       {
-               commonDroits::min(5);
-               global $core;
-
-               $book_id = $_GET['fluidbook'];
-               $page = $_GET['page'];
-
-               $z = wsTools::pages2html($book_id, $page);
-               cubeHTTP::downloadFile($z['path'], $z['name']);
-       }
-
-       public static function SNCFCodes()
-       {
-               //commonDroits::min(1);
-               global $core;
-               $res = commonPage::barre();
-               $res .= commonPage::tMain();
-               $res .= commonPage::bh();
-               $res .= '<form action="' . SITE_PATH . 'tools/makeSNCFCodes" method="post" class="notajax" enctype="multipart/form-data">';
-               $res .= '<table class="liste">';
-               $res .= '<tr><th colspan="2"><strong>' . __('Générer dictionnaires de liens pour fluidbook SNCF') . '</strong></th></tr>';
-               $res .= '<tr><td>' . __("Email") . '</td><td><input type="file" name="file" /></td></tr>';
-               $res .= '<tr><td class="right" colspan="2"><a href="#" class="submit">' . $core->typo->BoutonOK(__('Générer les dictionnaires')) . '</a></td></td>';
-               $res .= '</table>';
-               $res .= '</form>';
-               $res .= commonPage::bf();
-
-               $res .= commonPage::bMain();
-               return $res;
-               $res .= commonPage::bMain();
-               return $res;
-       }
-
-       public static function importWSReferences()
-       {
-               $options = ['10doigts' => '10 doigts',
-                       'ascocelda' => 'Asco & Celda',
-                       'wesco' => 'Wesco'];
-
-               $options = array_flip($options);
-               ksort($options);
-
-               commonDroits::min(5);
-               global $core;
-               $res = commonPage::barre();
-               $res .= commonPage::tMain();
-               $res .= commonPage::bh();
-               $res .= '<form action="importWSReferences" method="post" enctype="multipart/form-data">';
-               $res .= '<table class="liste">';
-               $res .= '<tr><th colspan="2"><strong>' . __('Importer un fichier de références') . '</strong></th></tr>';
-               $res .= '<tr><td>' . __("Fichier XLSX") . '<br>(colonne A : référence, colonne B : URL)</td><td><input type="file" name="file" accept=".xlsx,.csv" /></td></tr>';
-               $res .= '<tr><td>' . __("Type") . '</td><td>' . form::combo('type', $options) . '</td></tr>';
-               $res .= '<tr><td class="right" colspan="2"><a href="#" class="submit">' . $core->typo->BoutonOK(__('Importer les références')) . '</a></td></td>';
-               $res .= '</table>';
-               $res .= '</form>';
-               $res .= commonPage::bf();
-
-               $res .= commonPage::bMain();
-               return $res;
-       }
-
-
-       public static function makeSNCFCodes()
-       {
-               $list = explode("\n", file_get_contents($_FILES['file']['tmp_name']));
-               $labels = [];
-               $links = [];
-
-               foreach ($list as $item) {
-                       $item = trim($item);
-                       if ($item == '') {
-                               continue;
-                       }
-                       $labels[] = ['word' => $item, 'action' => ['type' => 'definelabel', 'action' => $item]];
-                       $links[] = ['word' => $item, 'action' => ['type' => 'gotolabel', 'action' => $item]];
-               }
-
-               ob_end_clean();
-
-               header('Content-type: application/zip');
-               header('Content-Disposition: attachment; filename="sncf.zip"');
-
-               $zip = new ZipArchive();
-               $zip->open('/tmp/sncf', ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE);
-               $zip->addFromString('labels.ald', self::_listToALD($labels));
-               $zip->addFromString('links.ald', self::_listToALD($links));
-               $zip->close();
-
-               echo file_get_contents('/tmp/sncf');
-
-               exit;
-       }
-
-       public static function _listToALD($list)
-       {
-               $res = '<</Link [/c <<  /Desc [/t (AutoBookmark Link Dictionary File)]
+        $r = self::searchGoogle($q, $cx, $key);
+        if (!is_null($r)) {
+            http::redirect($r['items'][0]['link']);
+        }
+    }
+
+    public static function copyWsAssets()
+    {
+        commonDroits::min(5);
+        global $core;
+        $res = commonPage::barre();
+        $res .= commonPage::tMain();
+        $res .= commonPage::bh();
+        $res .= '<form id="copywsassets" action="copywsassets" method="post">';
+        $res .= '<table class="liste">';
+        $res .= '<tr><th><strong>' . __("Copie de fichiers entre deux fluidbook") . '</strong></th></tr>';
+        $res .= '<tr><td>Fluidbook source</td><td>' . form::field('source', 5, 6) . '</td></tr>';
+        $res .= '<tr><td>Fluidbook destination</td><td>' . form::field('dest', 5, 6) . '</td></tr>';
+        $res .= '<tr><td>Fichiers à transférer</td><td id="f">Entrez le numéro du fluidbook source pour sélectionner les fichiers à transférer</td></tr>';
+        $res .= '<tr><td class="right" colspan="2"><a href="#" class="submit">' . $core->typo->BoutonOK(__('Copier')) . '</a></td></td>';
+        $res .= '</table>';
+        $res .= '</form>';
+        $res .= '</div>';
+        $res .= commonPage::bf();
+        $res .= commonPage::bMain();
+        return $res;
+    }
+
+    protected static function searchGoogle($q, $cx, $key)
+    {
+        global $core;
+
+        $url = 'https://www.googleapis.com/customsearch/v1?q=' . rawurlencode($q) . '&cx=' . $cx;
+        $limit = TIME - (3600 * 24 * 10); // Cache de 10j
+
+        $r = $core->con->select('SELECT date,response FROM google_search_api WHERE request=\'' . $core->con->escape($url) . '\'');
+        if ($r->count()) {
+            $cached = $r->response;
+            if ($r->date > $limit) {
+                fb('got cache');
+                return json_decode($cached, true);
+            }
+        }
+
+
+        $j = file_get_contents($url . '&key=' . $key);
+        $json = json_decode($j, true);
+        if (isset($json['items'][0]['link'])) {
+            $c = $core->con->openCursor('google_search_api');
+            $c->request = $url;
+            $c->response = $j;
+            $c->date = TIME;
+            try {
+                $c->insert();
+            } catch (Exception $e) {
+                $c->update('WHERE request=\'' . $core->con->escape($url) . '\'');
+            }
+            return $json;
+        }
+
+        if (isset($cached)) {
+            return json_decode($cached, true);
+        } else {
+            return null;
+        }
+    }
+
+    public static function devspace()
+    {
+        commonDroits::min(1);
+        global $core;
+
+        $equipiers = array();
+        $dao = new commonDAOEquipier($core->con);
+        $liste = $dao->getListe(null, 'email', 'ASC', null);
+        foreach ($liste as $e) {
+            $equipiers[$e->email] = $e->email;
+        }
+
+        $res = commonPage::barre();
+        $res .= commonPage::tMain();
+        $res .= commonPage::bh();
+        $res .= '<form action="createDevSpace" method="post">';
+        $res .= '<table class="liste">';
+        $res .= '<tr><th colspan="2"><strong>' . __('Création d\'un espace de développement') . '</strong></th></tr>';
+        $res .= '<tr><td>' . __('Sous-domaine') . '</td><td>' . form::field('domain', 20, 512) . '.dev.cubedesigners.com</td></tr>';
+        $res .= '<tr><td>' . __('SVN') . '</td><td>svn+ssh://svn@svn.cubedesigners.com/projects/' . form::field('svn', 20, 512) . '</td></tr>';
+        $res .= '<tr><td>' . __('Utilisateur') . '</td><td>' . form::field('user', 20, 512) . ' (' . __('Si différent du sous-domaine') . ')</td></tr>';
+        $res .= '<tr><td>' . __('Namespace Zend') . '</td><td>' . form::field('zend', 20, 512) . ' (' . __('Laisser vide pour un projet vide') . ')</td></tr>';
+        $res .= '<tr><td>' . __('Créer des utilisateurs') . '</td><td>' . cubeForm::checkMultiple('users', $equipiers, 8, array($core->user->email)) . '</td></tr>';
+        $res .= '<tr><td class="right" colspan="2"><a href="#" class="submit">' . $core->typo->BoutonOK(__('Création')) . '</a></td></td>';
+
+        $res .= '</table>';
+        $res .= '</form>';
+        $res .= '</div>';
+        $res .= commonPage::bf();
+        $res .= commonPage::bMain();
+        return $res;
+    }
+
+    public static function createGitRepos()
+    {
+        commonDroits::min(0.5);
+        global $core;
+
+        $res = commonPage::barre();
+        $res .= commonPage::tMain();
+        $res .= commonPage::bh();
+        $res .= '<form action="createGitRepos" method="post">';
+        $res .= '<div id="res">';
+        $res .= '<table class="liste">';
+        $res .= '<tr><th colspan="2"><strong>' . __('Création d\'un dépôt git') . '</strong></th></tr>';
+        $res .= '<tr><td>' . __('Dépôt') . '</td><td>git@git.cubedesigners.com:' . form::field('repos', 20, 512) . '.git</td></tr>';
+        $res .= '<tr><td class="right" colspan="2"><a href="#" class="submit">' . $core->typo->BoutonOK(__('Création')) . '</a></td></td>';
+        $res .= '</table>';
+        $res .= '</div>';
+        $res .= '</form>';
+        $res .= '</div>';
+        $res .= commonPage::bf();
+        $res .= commonPage::bMain();
+        return $res;
+    }
+
+
+    public static function mailer()
+    {
+        commonDroits::min(1);
+        global $core;
+        $res = commonPage::barre();
+        $res .= commonPage::tMain();
+        $res .= commonPage::bh();
+        $res .= '<form action="postMailer" method="post" enctype="multipart/form-data">';
+        $res .= '<table class="liste">';
+        $res .= '<tr><th colspan="3"><strong>' . __('Envoi d\'un mailing') . '</strong></th></tr>';
+        $res .= '<tr><td>' . __('Sources') . '</td><td>' . cubeForm::filehtml('src') . '</td><td>' . __('Fichier contenant les sources html et images du mail') . '</td></tr>';
+        $res .= '<tr><td>' . __('Sujet') . '</td><td>' . form::field('subject', 50, 512, '[Extranet Mailer] ' . date('Y-m-d H:i')) . '</td><td>' . '</td></tr>';
+        $res .= '<tr><td>' . __('Expéditeur') . '</td><td>' . form::hidden('from', $core->user->email) . $core->user->email . '</td><td>' . '</td></tr>';
+        $res .= '<tr><td>' . __('Destinataire(s)') . '</td><td>' . form::field('to', 50, 512, $core->user->email) . '</td><td>' . __('Séparer les adresses par des virgules') . '</td></tr>';
+        $res .= '<tr><td class="right" colspan="3"><a href="#" class="submit">' . $core->typo->BoutonOK(__('Envoi')) . '</a></td></td>';
+        $res .= '</table>';
+        $res .= '</form>';
+        $res .= '</div>';
+        $res .= commonPage::bf();
+        $res .= commonPage::bMain();
+        return $res;
+    }
+
+    public function rasterize()
+    {
+        $type = isset($_GET['type']) ? $_GET['type'] : 'png';
+        $intype = CubeIT_Files::getExtension($_GET['src']);
+
+        $src = cubeFiles::tempnam() . '.' . $intype;
+        $dest = cubeFiles::tempnam() . '.' . $type;
+
+        copy($_GET['src'], $src);
+
+
+        $scale = isset($_GET['scale']) ? $_GET['scale'] : 1;
+
+        $cl = new CubeIT_CommandLine('convert');
+        if ($intype == 'svg') {
+            $cl->setManualArg('-background none -flatten');
+        } else if ($intype == 'pdf') {
+            $cl->setManualArg('-density ' . (round(75 * $scale)));
+            $cl->setManualArg('-background white');
+        }
+
+        if ($intype == 'pdf') {
+            $cl->setArg(null, $src . '[0]');
+        } else {
+            $cl->setArg(null, $src);
+        }
+        $cl->setArg(null, $dest);
+        $cl->execute();
+
+        ob_end_clean();
+
+        header('Content-type: image/png');
+        echo file_get_contents($dest);
+
+        unlink($src);
+        unlink($dest);
+        exit;
+    }
+
+    public static function chiffres()
+    {
+        global $core;
+        $datas_types = array();
+        $datas_entreprises = array();
+
+        $dao = new commonDAOClient($core->con);
+        $clients = $dao->getListe();
+
+        $dao = new commonDAOEntreprise($core->con);
+        $entreprises = $dao->getListe();
+
+        $dao = new extranetDAOFacture($core->con);
+        $factures = $dao->getListe('date_creation', 'ASC');
+
+        foreach ($factures as $f) {
+            if ($f->status < 1 || $f->status > 2) {
+                continue;
+            }
+            $client = $clients[$f->client_id];
+            $entreprise = $entreprises[$client->entreprise];
+            $annee = date('Y', $f->date_creation);
+
+            if (!isset($datas_types[$entreprise->type])) {
+                $datas_types[$entreprise->type] = array();
+            }
+            if (!isset($datas_types[$entreprise->type][$annee])) {
+                $datas_types[$entreprise->type][$annee] = 0;
+            }
+            $datas_types[$entreprise->type][$annee] += $f->total_ht;
+            sort($datas_types);
+
+            $csv = fopen(ROOT . '/types.csv', 'wb');
+            $range = array_merge(array(''), range(2006, date('Y')));
+            fputcsv($csv, $range, ';');
+            foreach ($datas_types as $type => $annees) {
+                $line = array($type);
+                foreach ($annees as $a => $m) {
+                    $c = $a - 2005;
+                    $line[$c] = $m;
+                }
+                fputcsv($csv, $line, ';');
+            }
+            fclose($csv);
+
+            if (!isset($datas_entreprises[$entreprise->nom])) {
+                $datas_entreprises[$entreprise->nom] = array();
+            }
+            if (!isset($datas_entreprises[$entreprise->nom][$annee])) {
+                $datas_entreprises[$entreprise->nom][$annee] = 0;
+            }
+            $datas_entreprises[$entreprise->nom][$annee] += $f->total_ht;
+        }
+    }
+
+    public static function wspagestohtml()
+    {
+        commonDroits::min(5);
+        global $core;
+        $res = commonPage::barre();
+        $res .= commonPage::tMain();
+        $res .= commonPage::bh();
+        $res .= '<form action="/tools/dowspagestohtml" class="notajax" method="get">';
+        $res .= '<table class="liste">';
+        $res .= '<tr><th colspan="3"><strong>' . __('Convertir une page du fluidbook en HTML') . '</strong></th></tr>';
+        $res .= '<tr><td>' . __('Fluidbook') . '</td><td>' . form::field('fluidbook', 5, 5) . '</td></tr>';
+        $res .= '<tr><td>' . __('Page') . '</td><td>' . form::field('page', 5, 5) . '</td></tr>';
+        $res .= '<tr><td class="right" colspan="3"><a href="#" class="submit">' . $core->typo->BoutonOK(__('Convertir')) . '</a></td></td>';
+        $res .= '</table>';
+        $res .= '</form>';
+        $res .= '</div>';
+        $res .= commonPage::bf();
+        $res .= commonPage::bMain();
+        return $res;
+    }
+
+    public static function dowspagestohtml()
+    {
+        commonDroits::min(5);
+        global $core;
+
+        $book_id = $_GET['fluidbook'];
+        $page = $_GET['page'];
+
+        $z = wsTools::pages2html($book_id, $page);
+        cubeHTTP::downloadFile($z['path'], $z['name']);
+    }
+
+    public static function SNCFCodes()
+    {
+        //commonDroits::min(1);
+        global $core;
+        $res = commonPage::barre();
+        $res .= commonPage::tMain();
+        $res .= commonPage::bh();
+        $res .= '<form action="' . SITE_PATH . 'tools/makeSNCFCodes" method="post" class="notajax" enctype="multipart/form-data">';
+        $res .= '<table class="liste">';
+        $res .= '<tr><th colspan="2"><strong>' . __('Générer dictionnaires de liens pour fluidbook SNCF') . '</strong></th></tr>';
+        $res .= '<tr><td>' . __("Email") . '</td><td><input type="file" name="file" /></td></tr>';
+        $res .= '<tr><td class="right" colspan="2"><a href="#" class="submit">' . $core->typo->BoutonOK(__('Générer les dictionnaires')) . '</a></td></td>';
+        $res .= '</table>';
+        $res .= '</form>';
+        $res .= commonPage::bf();
+
+        $res .= commonPage::bMain();
+        return $res;
+    }
+
+    public static function ttsBatch()
+    {
+        commonDroits::min(5);
+        global $core;
+        $res = commonPage::barre();
+        $res .= commonPage::tMain();
+        $res .= commonPage::bh();
+        $res .= '<form action="ttsBatch" method="post" enctype="multipart/form-data">';
+        $res .= '<table class="liste">';
+        $res .= '<tr><th colspan="2"><strong>' . __('Upload groupé de fichier TTS') . '</strong></th></tr>';
+        $res .= '<tr><td>' . __("Fichier ZIP") . '</td><td><input type="file" name="file" /></td></tr>';
+        $res .= '<tr><td>' . __("Voix") . '</td><td>' . form::combo('voice', wsDroits::getTTSVoices(), '') . '</td></tr>';
+        $res .= '<tr><td class="right" colspan="2"><a href="#" class="submit">' . $core->typo->BoutonOK(__('Chargement')) . '</a></td></td>';
+        $res .= '</table>';
+        $res .= '</form>';
+        $res .= commonPage::bf();
+
+        $res .= commonPage::bMain();
+        return $res;
+
+    }
+
+    public static function importWSReferences()
+    {
+        $options = ['10doigts' => '10 doigts',
+            'ascocelda' => 'Asco & Celda',
+            'wesco' => 'Wesco'];
+
+        $options = array_flip($options);
+        ksort($options);
+
+        commonDroits::min(5);
+        global $core;
+        $res = commonPage::barre();
+        $res .= commonPage::tMain();
+        $res .= commonPage::bh();
+        $res .= '<form action="importWSReferences" method="post" enctype="multipart/form-data">';
+        $res .= '<table class="liste">';
+        $res .= '<tr><th colspan="2"><strong>' . __('Importer un fichier de références') . '</strong></th></tr>';
+        $res .= '<tr><td>' . __("Fichier XLSX") . '<br>(colonne A : référence, colonne B : URL)</td><td><input type="file" name="file" accept=".xlsx,.csv" /></td></tr>';
+        $res .= '<tr><td>' . __("Type") . '</td><td>' . form::combo('type', $options) . '</td></tr>';
+        $res .= '<tr><td class="right" colspan="2"><a href="#" class="submit">' . $core->typo->BoutonOK(__('Importer les références')) . '</a></td></td>';
+        $res .= '</table>';
+        $res .= '</form>';
+        $res .= commonPage::bf();
+
+        $res .= commonPage::bMain();
+        return $res;
+    }
+
+
+    public static function makeSNCFCodes()
+    {
+        $list = explode("\n", file_get_contents($_FILES['file']['tmp_name']));
+        $labels = [];
+        $links = [];
+
+        foreach ($list as $item) {
+            $item = trim($item);
+            if ($item == '') {
+                continue;
+            }
+            $labels[] = ['word' => $item, 'action' => ['type' => 'definelabel', 'action' => $item]];
+            $links[] = ['word' => $item, 'action' => ['type' => 'gotolabel', 'action' => $item]];
+        }
+
+        ob_end_clean();
+
+        header('Content-type: application/zip');
+        header('Content-Disposition: attachment; filename="sncf.zip"');
+
+        $zip = new ZipArchive();
+        $zip->open('/tmp/sncf', ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE);
+        $zip->addFromString('labels.ald', self::_listToALD($labels));
+        $zip->addFromString('links.ald', self::_listToALD($links));
+        $zip->close();
+
+        echo file_get_contents('/tmp/sncf');
+
+        exit;
+    }
+
+    public static function _listToALD($list)
+    {
+        $res = '<</Link [/c << /Desc [/t (AutoBookmark Link Dictionary File)]
        /Entries [/c <<         ';
-               foreach ($list as $k => $item) {
-                       $res .= '/' . $k . ' [/c <<                     /code [/t (' . self::_actionToALDCode($item['action']) . ')]
+        foreach ($list as $k => $item) {
+            $res .= '/' . $k . ' [/c <<                        /code [/t (' . self::_actionToALDCode($item['action']) . ')]
                        /word [/t (' . addcslashes($item['word'], "\\") . ')]
 >>]
                ';
-               }
+        }
 
 
-               $res .= '
+        $res .= '
 >>]
        /Name [/t (Dictionary)]
 >>]
 >>';
 
-               return $res;
-       }
-
-       public static function _actionToALDCode($action)
-       {
-               if ($action['type'] == 'gotolabel') {
-                       return '@' . $action['action'];
-               } elseif ($action['type'] == 'uri') {
-                       return 'uri:' . $action['action'];
-               } else if ($action['type'] == 'definelabel') {
-                       return 'uri:pagelabel:' . $action['action'];
-               } else if ($action['type'] == 'page') {
-                       return $action['action'] . ',InheritZoom';
-               }
-       }
-
-       public static function proxy()
-       {
-               ob_end_clean();
-               echo file_get_contents($_GET['url']);
-               exit;
-       }
-
-       public static function phantomjs()
-       {
-               $file = CubeIT_Files::tempnam();
-               $exportformat = isset($_GET['exportformat']) ? $_GET['exportformat'] : 'pdf';
-               $pageformat = isset($_GET['pageformat']) ? $_GET['pageformat'] : '210mm*297mm';
-               $f = $file . '.' . $exportformat;
-
-               CubeIT_CommandLine_Phantomjs::html2pdf($_GET['url'], $f, $pageformat);
-               cubeHTTP::relayFile($f);
-               exit;
-       }
-
-       public static function youtubedl()
-       {
-               $url = $_GET['url'];
-               $dir = '/data/extranet/www/cache/youtubedl';
-               `cd $dir;youtube-dl $url`;
-               $fname = trim(`youtube-dl --get-filename $url`);
-               $path = $dir . '/' . $fname;
-
-
-               header('Content-Type: application/octet-stream');
-               header('Content-Disposition: attachment; filename="' . $fname . '"');
-               header('X-SendFile: ' . $path);
-               ob_end_clean();
-               exit;
-       }
+        return $res;
+    }
+
+    public static function _actionToALDCode($action)
+    {
+        if ($action['type'] == 'gotolabel') {
+            return '@' . $action['action'];
+        } elseif ($action['type'] == 'uri') {
+            return 'uri:' . $action['action'];
+        } else if ($action['type'] == 'definelabel') {
+            return 'uri:pagelabel:' . $action['action'];
+        } else if ($action['type'] == 'page') {
+            return $action['action'] . ',InheritZoom';
+        }
+    }
+
+    public static function proxy()
+    {
+        ob_end_clean();
+        echo file_get_contents($_GET['url']);
+        exit;
+    }
+
+    public static function phantomjs()
+    {
+        $file = CubeIT_Files::tempnam();
+        $exportformat = isset($_GET['exportformat']) ? $_GET['exportformat'] : 'pdf';
+        $pageformat = isset($_GET['pageformat']) ? $_GET['pageformat'] : '210mm*297mm';
+        $f = $file . '.' . $exportformat;
+
+        CubeIT_CommandLine_Phantomjs::html2pdf($_GET['url'], $f, $pageformat);
+        cubeHTTP::relayFile($f);
+        exit;
+    }
+
+    public static function youtubedl()
+    {
+        $url = $_GET['url'];
+        $dir = '/data/extranet/www/cache/youtubedl';
+        `cd $dir;youtube-dl $url`;
+        $fname = trim(`youtube-dl --get-filename $url`);
+        $path = $dir . '/' . $fname;
+
+        header('Content-Type: application/octet-stream');
+        header('Content-Disposition: attachment; filename="' . $fname . '"');
+        header('X-SendFile: ' . $path);
+        ob_end_clean();
+        exit;
+    }
+
 }
index caedb25bbd18926857ab8088d0c76c060e45536f..9046e615e676bc980aaf4657f7b414cdc2adfa4d 100644 (file)
 <?php\r
 \r
-class wsDroits {\r
-\r
-       public static $creation = array(2, 4, 5);\r
-       public static $revendeur = 3;\r
-       public static $admin = 5;\r
-\r
-       public static function navigation() {\r
-               global $core;\r
-\r
-               $nav = array();\r
-\r
-               if (is_null($core->user)) {\r
-                       return $nav;\r
-               }\r
-\r
-               if ($core->user->ws_grade >= 5) {\r
-                       $nav[__('Dashboard')] = 'dashboard';\r
-               }\r
-\r
-               $nav[__('Publications')] = 'publications';\r
-               if ($core->user->ws_grade >= 5) {\r
-                       $nav[__('Collections')] = 'collections';\r
-               }\r
-               if ($core->user->ws_grade >= 3) {\r
-                       $nav[__('Clients')] = 'clients';\r
-               }\r
-               if ($core->user->ws_grade >= 5) {\r
-                       $nav[__('Devis')] = 'demandes';\r
-                       $nav[__('Traductions')] = 'traductions';\r
-               }\r
-               if ($core->user->ws_grade < 5) {\r
-                       $nav[__('Fichiers')] = 'fichiers';\r
-               }\r
-               return $nav;\r
-       }\r
-\r
-       public static function getDroits() {\r
-               $res = new stdClass();\r
-               $res->creation = self::creation(false);\r
-               $res->revendeur = self::revendeur(false);\r
-               $res->admin = self::admin(false);\r
-               return $res;\r
-       }\r
-\r
-       public static function creation($error = false) {\r
-               return self::gradeIn(self::$creation, $error);\r
-       }\r
-\r
-       public static function revendeur($error = false) {\r
-               return commonDroits::min(self::$revendeur, $error);\r
-       }\r
-\r
-       public static function admin($error = false) {\r
-               return commonDroits::min(self::$admin, $error);\r
-       }\r
-\r
-       protected static function gradeIn($list, $error = false) {\r
-               global $core;\r
-\r
-               if (null === $core->user || !isset($core->user->ws_grade) || !in_array($core->user->ws_grade, $list)) {\r
-                       if ($error) {\r
-                               commonDroits::error();\r
-                       }\r
-                       return false;\r
-               }\r
-               return true;\r
-       }\r
-\r
-       public static function getSignatures() {\r
-               global $core;\r
-\r
-               if (is_null($core) || is_null($core->user)) {\r
-                       $s = '';\r
-               } else {\r
-                       $s = $core->user->getWSSignatures();\r
-               }\r
-\r
-               $mySignatures = explode(',', $s);\r
-               $mySignatures[] = 1;\r
-\r
-               $admin = wsDroits::admin(false);\r
-\r
-               $dao = new wsDAOSignature($core->con);\r
-\r
-               if (!isset($GLOBALS['allSignatures'])) {\r
-                       $GLOBALS['allSignatures'] = $dao->selectAll();\r
-               }\r
-               $res = array();\r
-               foreach ($GLOBALS['allSignatures'] as $signature) {\r
-                       if (!$admin && !in_array($signature->signature_id, $mySignatures)) {\r
-                               continue;\r
-                       }\r
-                       if (!$signature->active) {\r
-                               continue;\r
-                       }\r
-                       $res[$signature->nom] = $signature->signature_id;\r
-               }\r
-               return $res;\r
-       }\r
+class wsDroits\r
+{\r
+\r
+    public static $creation = array(2, 4, 5);\r
+    public static $revendeur = 3;\r
+    public static $admin = 5;\r
+\r
+    public static function navigation()\r
+    {\r
+        global $core;\r
+\r
+        $nav = array();\r
+\r
+        if (is_null($core->user)) {\r
+            return $nav;\r
+        }\r
+\r
+        if ($core->user->ws_grade >= 5) {\r
+            $nav[__('Dashboard')] = 'dashboard';\r
+        }\r
+\r
+        $nav[__('Publications')] = 'publications';\r
+        if ($core->user->ws_grade >= 5) {\r
+            $nav[__('Collections')] = 'collections';\r
+        }\r
+        if ($core->user->ws_grade >= 3) {\r
+            $nav[__('Clients')] = 'clients';\r
+        }\r
+        if ($core->user->ws_grade >= 5) {\r
+            $nav[__('Devis')] = 'demandes';\r
+            $nav[__('Traductions')] = 'traductions';\r
+        }\r
+        if ($core->user->ws_grade < 5) {\r
+            $nav[__('Fichiers')] = 'fichiers';\r
+        }\r
+        return $nav;\r
+    }\r
+\r
+    public static function getDroits()\r
+    {\r
+        $res = new stdClass();\r
+        $res->creation = self::creation(false);\r
+        $res->revendeur = self::revendeur(false);\r
+        $res->admin = self::admin(false);\r
+        return $res;\r
+    }\r
+\r
+    public static function creation($error = false)\r
+    {\r
+        return self::gradeIn(self::$creation, $error);\r
+    }\r
+\r
+    public static function revendeur($error = false)\r
+    {\r
+        return commonDroits::min(self::$revendeur, $error);\r
+    }\r
+\r
+    public static function admin($error = false)\r
+    {\r
+        return commonDroits::min(self::$admin, $error);\r
+    }\r
+\r
+    protected static function gradeIn($list, $error = false)\r
+    {\r
+        global $core;\r
+\r
+        if (null === $core->user || !isset($core->user->ws_grade) || !in_array($core->user->ws_grade, $list)) {\r
+            if ($error) {\r
+                commonDroits::error();\r
+            }\r
+            return false;\r
+        }\r
+        return true;\r
+    }\r
+\r
+    public static function getSignatures()\r
+    {\r
+        global $core;\r
+\r
+        if (is_null($core) || is_null($core->user)) {\r
+            $s = '';\r
+        } else {\r
+            $s = $core->user->getWSSignatures();\r
+        }\r
+\r
+        $mySignatures = explode(',', $s);\r
+        $mySignatures[] = 1;\r
+\r
+        $admin = wsDroits::admin(false);\r
+\r
+        $dao = new wsDAOSignature($core->con);\r
+\r
+        if (!isset($GLOBALS['allSignatures'])) {\r
+            $GLOBALS['allSignatures'] = $dao->selectAll();\r
+        }\r
+        $res = array();\r
+        foreach ($GLOBALS['allSignatures'] as $signature) {\r
+            if (!$admin && !in_array($signature->signature_id, $mySignatures)) {\r
+                continue;\r
+            }\r
+            if (!$signature->active) {\r
+                continue;\r
+            }\r
+            $res[$signature->nom] = $signature->signature_id;\r
+        }\r
+        return $res;\r
+    }\r
+\r
+    public static function getTTSVoices()\r
+    {\r
+\r
+        $res = ['' => ''];\r
+        $rights = self::getDroits();\r
+        $freeVoices = [__('Festival (en-US)') => 'festival:voice_cmu_us_slt_arctic_hts'];\r
+        $advancedVoices = [\r
+            __('ReadSpeaker Sophie (en-US)') => 'readspeaker:Sophie/en_us',\r
+            __('ReadSpeaker Marc (en-US)') => 'readspeaker:Marc/en_us',\r
+        ];\r
+        if ($rights->creation || $rights->revendeur) {\r
+            $res = array_merge($res, $freeVoices);\r
+        }\r
+        if ($rights->admin) {\r
+            $res = array_merge($res, $advancedVoices);\r
+        }\r
+        return $res;\r
+\r
+    }\r
 \r
 }\r
 \r
index 7699a87a7d60e243ed1c67e9d0ed4c9cfcb6bcbc..e88a8bc064e693a2bd9e9e073db77f713dd1a9f3 100644 (file)
@@ -622,7 +622,7 @@ class wsMaintenance
                        }
                }
 
-               self::_moveDocs(WS_DOCS, '/data/extranet/www/fluidbook/docs1', 750);
+               self::_moveDocs(WS_DOCS, '/data/extranet/www/fluidbook/docs1', 250);
                self::_moveDocs('/data/extranet/www/fluidbook/docs1', '/data/extranet/www/fluidbook/docs2', 2000);
        }
 
@@ -1651,8 +1651,8 @@ class wsMaintenance
        public static function installWescoVentes()
        {
                $exporter = new wsExporter();
-               $exporter->export(16328, $x, 'install_ftp', 'online', "wescogrolj-catalogca:b9uA7U72eW@ftp.cluster023.hosting.ovh.net", '');
-               header('Location: https://agefard:TB6x9gg9@wesco-group.com/download/Catalogues/2018/Wesco_Rapport_ventes_0-12-ans');
+               $exporter->export(17399, $x, 'install_ftp', 'online', "wescogrolj-catalogca:b9uA7U72eW@ftp.cluster023.hosting.ovh.net", '');
+               header('Location: https://agefard:TB6x9gg9@wesco-group.com/download/Catalogues/Wesco_Rapport_ventes_0-12-ans/');
                exit;
        }
 
index 8e61912369900f856415f55c14dcb734a98c6d8b..672f55b4553b37e50ae4bcc901180e4f2832f19a 100644 (file)
 class wsBookParametres extends wsParametres
 {
 
-       public function __construct($parent)
-       {
-               parent::__construct($parent);
-       }
-
-       /**
-        * wsBookParametres::initFields()
-        *
-        * @return
-        */
-       protected function initFields()
-       {
-               parent::initFields();
-               //              if (is_null($this->parent)) {
-               //                      return;
-               //              }
-
-               // .
-               $swfFilter = new stdClass();
-               $swfFilter->name = __('Animation SWF') . ' (*.swf)';
-               $swfFilter->extensions = '*.swf';
-
-               $multimediaFilter = new stdClass();
-               $multimediaFilter->name = __('Archive ZIP') . ' (*.zip)';
-               $multimediaFilter->extensions = '*.zip';
-
-               $pdfFilter = new stdClass();
-               $pdfFilter->name = __('Document PDF') . ' (*.pdf)';
-               $pdfFilter->extensions = '*.pdf';
-
-               $basketFilter = new stdClass();
-               $basketFilter->name = __('Liste de produits') . ' (*.xml, *.xlsx)';
-               $basketFilter->extensions = '*.xml;*.xlsx';
-
-               $imageFilter = new stdClass();
-               $imageFilter->name = __('Images') . ' (*.jpg, *.png)';
-               $imageFilter->extensions = '*.jpg;*.jpeg;*.png';
-
-               $epsFilter = new stdClass();
-               $epsFilter->name = __('Fichier vectoriel') . ' (*.ai, *.eps)';
-               $epsFilter->extensions = '*.ai;*.eps';
-
-               $svgFilter = new stdClass();
-               $svgFilter->name = __('Fichier SVG') . ' (*.svg)';
-               $svgFilter->extensions = '*.svg';
-
-               $imageExtraFilter = new stdClass();
-               $imageExtraFilter->name = __('Images') . ' (*.svg, *.jpg, *.png, *.gif)';
-               $imageExtraFilter->extensions = '*.svg;*.jpg;*.png;*.gif';
-
-               $soundFilter = new stdClass();
-               $soundFilter->name = __('Fichier sonore') . ' (*.mp3, *.wav)';
-               $soundFilter->extensions = '*.mp3;*.wav';
-
-               $seoFilter = new stdClass();
-               $seoFilter->name = __('Fichier Excel') . ' (.xlsx)';
-               $seoFilter->extensions = '*.xlsx';
-
-               $cssFilter = new stdClass();
-               $cssFilter->name = __('Feuille de style') . ' (.css)';
-               $cssFilter->extensions = '*.css';
-
-               $branches = array('master : git (stable)' => 'stable',
-                       'master : local (dev)' => 'dev');
-               $gitbranches = json_decode(file_get_contents(WS_CACHE . '/activebranches'));
-               foreach ($gitbranches as $b) {
-                       if ($b == 'master') {
-                               continue;
-                       }
-                       $branches[$b . ' : git'] = $b . '|git';
-                       $branches[$b . ' : local'] = $b . '|local';
-               }
-               $extraVisibility = [
-                       __('Navigation horizontale') => 'horizontal',
-                       __('Navigation burger') => 'burger',
-                       __('Navigations horizontale et burger') => 'both'];
-
-               $extraType = [
-                       __('Icône + Label') => 'icon',
-                       __('Image') => 'image'];
-
-               $this->fields['mobileLVersion'] = array('type' => 'combo', 'default' => 'stable', 'editable' => true,
-                       'label' => __('Version logicielle'), 'grade' => 1,
-                       'datas' => $branches
-               );
-               $this->fields['mobileVersion'] = array('type' => 'combo', 'default' => 'html5-desktop', 'editable' => true, 'label' => __('Version mobile'), 'grade' => 3,
-                       'datas' => array(__('Rediriger vers le PDF') => 'pdf',
-                               __('Version HTML5 recommandée (vecteurs sur desktop)') => 'html5-desktop',
-                               __('Version HTML5 vecteurs') => 'html5',
-                               __("Version HTML5 en images") => 'html5-images')
-               );
-
-               $this->fields['version'] = array('type' => 'combo', 'default' => '2', 'editable' => true, 'label' => __('Version'), 'datas' => array('1' => '1', '2' => '2'), 'grade' => 3);
-               $this->fields['title'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("Titre de la publication"), 'embed' => false);
-               $this->fields['url_link'] = array('type' => 'text', 'default' => 'http://', 'editable' => true, 'label' => __("URL du lien de retour au site"));
-               $this->fields['signature'] = array('type' => 'combo', 'default' => '1', 'editable' => true, 'label' => __('Signature'), 'grade' => 3, 'datas' => wsDroits::getSignatures());
-               $this->fields['mobileTransitions'] = array('type' => 'combo', 'default' => 'flip', 'editable' => true, 'label' => __('Transitions entre les pages'), 'grade' => 3,
-                       'datas' => array(__('Aucune transition') => 'none',
-                               __('Glisser') => 'slide',
-                               __('Tourner (rigide)') => 'flip',
-                               __('Tourner (souple, expérimental)') => 'flip3d')
-               );
-               $this->forms['important'] = array('label' => __('Description de la publication'),
-                       'fieldsnames' => array('version', 'mobileLVersion', 'mobileVersion', 'mobileTransitions', 'title', 'url_link', 'signature'));
-               // .
-               // .
-
-               $this->fields['email_title'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("Titre de l'email") . ' "' . __('Envoyer à un ami') . '"', 'hint' => __('Laisser vide pour utiliser la valeur par défaut'));
-               $this->fields['email_body'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __("Corps de l'email") . ' "' . __('Envoyer à un ami') . '"', 'hint' => __('Laisser vide pour utiliser la valeur par défaut'));
-               $this->fields['email_editable'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Permettre au lecteur de modifier le corps de l'email"));
-               $this->fields['askAcknowledge'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Demander au destinataire un accusé de réception"), 'grade' => 3);
-               $this->fields['sendasfluidbook'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Envoyer le mail comme Fluidbook"), 'grade' => 3, 'hint' => __("L'expéditeur apparaîtra en reply-to"));
-               $this->fields['email_mailto'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Envoyer le mail via le client mail du visiteur (mailto:)"), 'grade' => 3);
-
-               $this->fields['facebook_title'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("Titre du contenu partagé"), 'hint' => __('Titre proposé sur les fonction de partage (par défaut, titre de la publication)'));
-               $this->fields['facebook_description'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __("Description du contenu partagé"), 'grade' => 1, 'hint' => __('Description proposée sur les fonctions de partage (par défaut, vide)'));
-               $this->fields['twitter_description'] = array('type' => 'textarea', 'default' => '%title% : %short%', 'editable' => true, 'label' => __("Contenu Partage court"), 'hint' => __('Contenu du partagé sur les partages courts'));
-               $this->fields['facebook_image'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
-                       'label' => __('Miniature affichée'), 'fileFilter' => $imageFilter);
-
-               $this->fields['share'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Activer les fonctions de partage'));
-               $this->fields['friend'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('E-mail'));
-               $this->fields['facebook'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Facebook'));
-               $this->fields['twitter'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Twitter'));
-               $this->fields['googleplus'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Google +'));
-               $this->fields['linkedin'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('LinkedIn'));
-               $this->fields['viadeo'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Viadeo'));
-               $this->fields['customSharer'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("Classe personnalisée de partage"), 'grade' => 5);
-               $this->fields['friendWidth'] = array('type' => 'integer', 'default' => 319, 'editable' => true, 'label' => __('Largeur du menu'), 'grade' => 5);
-               $this->fields['friendHeight'] = array('type' => 'integer', 'default' => 500, 'editable' => true, 'label' => __('Largeur du menu'), 'grade' => 5);
-               $this->forms['share'] = array('label' => __('Fonctions de partage'),
-                       'fieldsnames' => array('share', '|', 'email_title', 'email_body', 'email_editable', 'askAcknowledge', 'sendasfluidbook', 'email_mailto', '|',
-                               'facebook_title', 'facebook_description', 'facebook_image', 'twitter_description', '|',
-                               'friend', 'facebook', 'twitter', 'googleplus', 'linkedin', 'viadeo', '|', 'customSharer', '|', 'friendWidth', 'friendHeight'));
+    public function __construct($parent)
+    {
+        parent::__construct($parent);
+    }
+
+    /**
+     * wsBookParametres::initFields()
+     *
+     * @return
+     */
+    protected function initFields()
+    {
+        parent::initFields();
+        //             if (is_null($this->parent)) {
+        //                     return;
+        //             }
+
+        // .
+        $swfFilter = new stdClass();
+        $swfFilter->name = __('Animation SWF') . ' (*.swf)';
+        $swfFilter->extensions = '*.swf';
+
+        $multimediaFilter = new stdClass();
+        $multimediaFilter->name = __('Archive ZIP') . ' (*.zip)';
+        $multimediaFilter->extensions = '*.zip';
+
+        $pdfFilter = new stdClass();
+        $pdfFilter->name = __('Document PDF') . ' (*.pdf)';
+        $pdfFilter->extensions = '*.pdf';
+
+        $basketFilter = new stdClass();
+        $basketFilter->name = __('Liste de produits') . ' (*.xml, *.xlsx)';
+        $basketFilter->extensions = '*.xml;*.xlsx';
+
+        $imageFilter = new stdClass();
+        $imageFilter->name = __('Images') . ' (*.jpg, *.png)';
+        $imageFilter->extensions = '*.jpg;*.jpeg;*.png';
+
+        $epsFilter = new stdClass();
+        $epsFilter->name = __('Fichier vectoriel') . ' (*.ai, *.eps)';
+        $epsFilter->extensions = '*.ai;*.eps';
+
+        $svgFilter = new stdClass();
+        $svgFilter->name = __('Fichier SVG') . ' (*.svg)';
+        $svgFilter->extensions = '*.svg';
+
+        $imageExtraFilter = new stdClass();
+        $imageExtraFilter->name = __('Images') . ' (*.svg, *.jpg, *.png, *.gif)';
+        $imageExtraFilter->extensions = '*.svg;*.jpg;*.png;*.gif';
+
+        $soundFilter = new stdClass();
+        $soundFilter->name = __('Fichier sonore') . ' (*.mp3, *.wav)';
+        $soundFilter->extensions = '*.mp3;*.wav';
+
+        $seoFilter = new stdClass();
+        $seoFilter->name = __('Fichier Excel') . ' (.xlsx)';
+        $seoFilter->extensions = '*.xlsx';
+
+        $cssFilter = new stdClass();
+        $cssFilter->name = __('Feuille de style') . ' (.css)';
+        $cssFilter->extensions = '*.css';
+
+        $branches = array('master : git (stable)' => 'stable',
+            'master : local (dev)' => 'dev');
+        $gitbranches = json_decode(file_get_contents(WS_CACHE . '/activebranches'));
+        foreach ($gitbranches as $b) {
+            if ($b == 'master') {
+                continue;
+            }
+            $branches[$b . ' : git'] = $b . '|git';
+            $branches[$b . ' : local'] = $b . '|local';
+        }
+        $extraVisibility = [
+            __('Navigation horizontale') => 'horizontal',
+            __('Navigation burger') => 'burger',
+            __('Navigations horizontale et burger') => 'both'];
+
+        $extraType = [
+            __('Icône + Label') => 'icon',
+            __('Image') => 'image'];
+
+        $this->fields['mobileLVersion'] = array('type' => 'combo', 'default' => 'stable', 'editable' => true,
+            'label' => __('Version logicielle'), 'grade' => 1,
+            'datas' => $branches
+        );
+        $this->fields['mobileVersion'] = array('type' => 'combo', 'default' => 'html5-desktop', 'editable' => true, 'label' => __('Version mobile'), 'grade' => 3,
+            'datas' => array(__('Rediriger vers le PDF') => 'pdf',
+                __('Version HTML5 recommandée (vecteurs sur desktop)') => 'html5-desktop',
+                __('Version HTML5 vecteurs') => 'html5',
+                __("Version HTML5 en images") => 'html5-images')
+        );
+
+        $this->fields['version'] = array('type' => 'combo', 'default' => '2', 'editable' => true, 'label' => __('Version'), 'datas' => array('1' => '1', '2' => '2'), 'grade' => 3);
+        $this->fields['title'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("Titre de la publication"), 'embed' => false);
+        $this->fields['url_link'] = array('type' => 'text', 'default' => 'http://', 'editable' => true, 'label' => __("URL du lien de retour au site"));
+        $this->fields['signature'] = array('type' => 'combo', 'default' => '1', 'editable' => true, 'label' => __('Signature'), 'grade' => 3, 'datas' => wsDroits::getSignatures());
+        $this->fields['mobileTransitions'] = array('type' => 'combo', 'default' => 'flip', 'editable' => true, 'label' => __('Transitions entre les pages'), 'grade' => 3,
+            'datas' => array(__('Aucune transition') => 'none',
+                __('Glisser') => 'slide',
+                __('Tourner (rigide)') => 'flip',
+                __('Tourner (souple, expérimental)') => 'flip3d')
+        );
+        $this->forms['important'] = array('label' => __('Description de la publication'),
+            'fieldsnames' => array('version', 'mobileLVersion', 'mobileVersion', 'mobileTransitions', 'title', 'url_link', 'signature'));
+        // .
+        // .
+
+        $this->fields['email_title'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("Titre de l'email") . ' "' . __('Envoyer à un ami') . '"', 'hint' => __('Laisser vide pour utiliser la valeur par défaut'));
+        $this->fields['email_body'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __("Corps de l'email") . ' "' . __('Envoyer à un ami') . '"', 'hint' => __('Laisser vide pour utiliser la valeur par défaut'));
+        $this->fields['email_editable'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Permettre au lecteur de modifier le corps de l'email"));
+        $this->fields['askAcknowledge'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Demander au destinataire un accusé de réception"), 'grade' => 3);
+        $this->fields['sendasfluidbook'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Envoyer le mail comme Fluidbook"), 'grade' => 3, 'hint' => __("L'expéditeur apparaîtra en reply-to"));
+        $this->fields['email_mailto'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Envoyer le mail via le client mail du visiteur (mailto:)"), 'grade' => 3);
+
+        $this->fields['facebook_title'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("Titre du contenu partagé"), 'hint' => __('Titre proposé sur les fonction de partage (par défaut, titre de la publication)'));
+        $this->fields['facebook_description'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __("Description du contenu partagé"), 'grade' => 1, 'hint' => __('Description proposée sur les fonctions de partage (par défaut, vide)'));
+        $this->fields['twitter_description'] = array('type' => 'textarea', 'default' => '%title% : %short%', 'editable' => true, 'label' => __("Contenu Partage court"), 'hint' => __('Contenu du partagé sur les partages courts'));
+        $this->fields['facebook_image'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
+            'label' => __('Miniature affichée'), 'fileFilter' => $imageFilter);
+
+        $this->fields['share'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Activer les fonctions de partage'));
+        $this->fields['friend'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('E-mail'));
+        $this->fields['facebook'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Facebook'));
+        $this->fields['twitter'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Twitter'));
+        $this->fields['googleplus'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Google +'));
+        $this->fields['linkedin'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('LinkedIn'));
+        $this->fields['viadeo'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Viadeo'));
+        $this->fields['customSharer'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("Classe personnalisée de partage"), 'grade' => 5);
+        $this->fields['friendWidth'] = array('type' => 'integer', 'default' => 319, 'editable' => true, 'label' => __('Largeur du menu'), 'grade' => 5);
+        $this->fields['friendHeight'] = array('type' => 'integer', 'default' => 500, 'editable' => true, 'label' => __('Largeur du menu'), 'grade' => 5);
+        $this->forms['share'] = array('label' => __('Fonctions de partage'),
+            'fieldsnames' => array('share', '|', 'email_title', 'email_body', 'email_editable', 'askAcknowledge', 'sendasfluidbook', 'email_mailto', '|',
+                'facebook_title', 'facebook_description', 'facebook_image', 'twitter_description', '|',
+                'friend', 'facebook', 'twitter', 'googleplus', 'linkedin', 'viadeo', '|', 'customSharer', '|', 'friendWidth', 'friendHeight'));
 //.
-               $this->fields['seoVersion'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Générer une version pour les moteurs de recherche'));
-               $this->fields['seoRobots'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Autoriser le parcours par les moteurs de recherche'));
-               $this->fields['seoDescription'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Meta tag Description'));
-               $this->fields['seoKeywords'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Meta tag Keywords'));
-               $this->fields['seoAdvanced'] = ['type' => 'freefile', 'default' => '', 'editable' => true, 'label' => __('Données SEO par page'), 'grade' => 5, 'fileFilter' => $seoFilter];
-               $this->fields['seoBaseURL'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('URL de base'), 'grade' => 5, 'hint' => __("Si l'authentification échoue, redirection vers cette adresse"));
-
-               $this->forms['seo'] = array('label' => __('Optimisation pour les moteurs de recherche'),
-                       'fieldsnames' => array('seoVersion', 'seoRobots', 'seoDescription', "seoKeywords", '|', 'seoBaseURL', 'seoAdvanced'));
-
-               // .
-               $this->fields['pages'] = array('type' => 'integer', 'default' => '', 'editable' => false, 'label' => __('Nombre de pages'));
-               $this->fields['width'] = array('type' => 'float', 'default' => '', 'editable' => false, 'label' => __('Largeur'));
-               $this->fields['height'] = array('type' => 'float', 'default' => '', 'editable' => false, 'label' => __('Hauteur'));
-               // .
-               $this->fields['visualisationMode'] = array('type' => 'combo', 'default' => '3', 'editable' => true, 'label' => __("Mode de visualisation 3D"),
-                       'datas' => array(__('Mode 3D') => '0',
-                               __('Mode 2D (caméra fixe et pages à plat)') => '1',
-                               __("Laisser le choix à l'utilisateur (mode 3D par défaut)") => '2',
-                               __("Laisser le choix à l'utilisateur (mode 2D par défaut)") => '3'));
-               $this->fields['viewMode'] = array('type' => 'combo', 'default' => '0', 'editable' => true, 'label' => __("Mode de visualisation (beta)"),
-                       'datas' => array(__('Classique') => '0',
-                               __("Diaporama") => '1'), 'grade' => 5);
-               $this->fields['antialiasReading'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Amélioration de la lisibilité en mode 2D"));
-               $this->fields['pagesBaseAngle'] = array('type' => 'integer', 'default' => '2', 'editable' => true, 'label' => __('Angle de base entre les pages'), 'grade' => 3,
-                       'hint' => __("0 : Publication à plat") . "\n" . __('2 : Valeur par défaut'));
-               $this->fields['extraXSpace'] = array('type' => 'integer', 'default' => '0', 'editable' => true, 'label' => __('Marge supplémentaire horizontale'), 'grade' => 3);
-               $this->fields['extraYSpace'] = array('type' => 'integer', 'default' => '0', 'editable' => true, 'label' => __('Marge supplémentaire verticale'), 'grade' => 3);
-               $this->fields['centerBook'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Centrer la publication sur les couvertures'), 'grade' => 2);
-               $this->fields['correctCenter'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Corriger les lignes blanches entre les pages'), 'grade' => 2);
-               $this->fields['maxResolution'] = array('type' => 'combo', 'default' => 300, 'editable' => true, 'datas' => array('300dpi' => 300, '150dpi' => 150), 'grade' => 2, 'label' => __('Résolution maximale des pages'));
-               $this->forms['3d_mode'] = array('label' => __('Options de visualisation'),
-                       'fieldsnames' => array('visualisationMode', 'antialiasReading', 'correctCenter', 'pagesBaseAngle', 'centerBook', '|', 'extraXSpace', 'extraYSpace', '|', 'viewMode', '|', 'maxResolution'));
-
-               $this->fields['preload'] = array('type' => 'integer', 'default' => 16, 'editable' => true, 'label' => __('Nombre de pages à précharger'), 'grade' => 3);
-
-               $this->fields['maxPages'] = array('type' => 'integer', 'default' => 0, 'editable' => true, 'label' => __("Nombre de pages maximal affiché à l'ouverture du fluidbook (pas de limite = 0)"), 'grade' => 3);
-               $this->fields['navOrder'] = array('type' => 'textarea', 'default' => 'index, chapters, search, print, friend, bookmark, pdf, archives, basket, fullscreen, sound, 3d, extra, extra1, extra2, extra3, extra4, extra5, help, lang', 'editable' => true, 'label' => __('Ordre des icônes dans la nav'), 'grade' => 3);
-               $this->fields['tooltipTimer'] = array('type' => 'float', 'default' => 3, "editable" => true, 'label' => __("Temps maximum d'apparition des infos-bulles (en secondes)"));
-
-
-               $this->forms['general'] = array('label' => __('Fonctionnalités générales'),
-                       'fieldsnames' => array('navOrder', 'tooltipTimer', 'preload', 'maxPages', 'pages', 'width', 'height'));
-               //.
-               //
-
-               $this->forms['menu'] = array('label' => __('Menu'), 'fieldsnames' => ['afterSearchDisplayForHTML', '|']);
-               $this->fields['afterSearchDisplayForHTML'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Afficher l\'image après le moteur de recherche sur la version HTML5'), 'grade' => 1);
-               $extraNum = 5;
-               for ($i = 0; $i <= $extraNum; $i++) {
-                       if ($i > 0) {
-                               $j = $i;
-                               $this->fields['navExtraIcon' . $j] = array('type' => 'freefile', 'default' => '', 'editable' => true, 'label' => __('Icône supplémentaire') . ' ' . $j, 'fileFilter' => $imageExtraFilter);
-                               $this->fields['navExtraType' . $j] = array('type' => 'combo', 'datas' => $extraType, 'default' => 'icon', 'editable' => true, 'label' => __('Type'));
-                               $this->fields['navExtraLink' . $j] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("URL") . ' ' . $j);
-                               $this->fields['navExtraVisibility' . $j] = array('type' => 'combo', 'datas' => $extraVisibility, 'default' => 'both', 'editable' => true, 'label' => __("Visible") . ' ' . $j);
-                               $this->forms['menu']['fieldsnames'] = array_merge($this->forms['menu']['fieldsnames'], ['navExtraIcon' . $j, 'navExtraType' . $j, 'navExtraLink' . $j, 'navExtraVisibility' . $j, '|']);
-                       } else {
-                               $j = '';
-                               $this->fields['navExtraImage' . $j] = array('type' => 'freefile', 'default' => '', 'editable' => true, 'label' => __('Image pour navigation'), 'fileFilter' => $imageExtraFilter);
-                               $this->fields['navExtraImageMobile' . $j] = array('type' => 'freefile', 'default' => '', 'editable' => true, 'label' => __('Image pour mobile'), 'fileFilter' => $imageExtraFilter);
-                               $this->fields['navExtraLink' . $j] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("URL"));
-                               $this->fields['navExtraTooltip' . $j] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("Infobulle ou label"));
-                               $this->forms['menu']['fieldsnames'] = array_merge($this->forms['menu']['fieldsnames'], ['navExtraImage' . $j, 'navExtraImageMobile' . $j, 'navExtraLink' . $j, 'navExtraTooltip' . $j, '|']);
-                       }
-               }
-
-
-               $this->fields['landingPage'] = array('type' => 'freefile', 'default' => '', 'editable' => true, 'label' => __('Landing Page content'), 'grade' => 3);
-               $this->forms['landing'] = array('label' => __('Custom Landing Page'), 'fieldsnames' => array('landingPage'));
-
-
-               $this->fields['fullscreen'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Activer le mode plein-écran'));
-               $this->fields['fullscreenAuto'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Lancer la publication en mode plein écran (lorsque possible)'));
-               $this->forms['fs'] = array('label' => __('Plein écran'),
-                       'fieldsnames' => array('fullscreen', 'fullscreenAuto'));
-
-
-               $this->fields['bookmark'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Activer les marques-pages'));
-               $this->fields['bookmarkSendEnable'] = array('type' => 'boolean', 'default' => 'true', 'editable' => true, 'label' => __("Activer l'envoi des marques-pages par e-mail"));
-               $this->fields['bookmark_email_title'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("Titre de l'email") . ' "' . __('Envoyer à un ami') . '"', 'hint' => __('Laisser vide pour utiliser la valeur par défaut'));
-               $this->fields['bookmark_email_body'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __("Corps de l'email") . ' "' . __('Envoyer à un ami') . '"', 'hint' => __('Laisser vide pour utiliser la valeur par défaut'));
-               $this->fields['bookmarkCornerSize'] = array('type' => 'integer', 'default' => 8, 'editable' => true, 'label' => __("Taille des marques-pages"), 'hint' => __('Taille relative à la largeur de la page'));
-               $this->fields['bookmarkOffset'] = array('type' => 'integer', 'default' => 0, 'editable' => true, 'label' => __("Décaler de x pixels vers l'intérieur"));
-               $this->fields['bookmarkBlinkOnPageChange'] = array('type' => 'boolean', 'default' => 'false', 'editable' => true, 'label' => __('Faire clignoter le marque page à l\'apparition de la page'));
-               $this->fields['bookmarkUsePDF'] = array('type' => 'combo', 'default' => 'pages', 'editable' => true, 'label' => __('PDF à utiliser pour l\'envoi ou le téléchargement de pages marquées'),
-                       'datas' => [__('PDF des pages') => 'pages',
-                               __('PDF de remplacement') => 'download',
-                               __('PDF des miniatures') => 'thumbnails']);
-               $this->forms['bookmark'] = array('label' => __('Marques-pages'),
-                       'fieldsnames' => array('bookmark', '|', 'bookmarkSendEnable', 'bookmark_email_title', 'bookmark_email_body', '|', 'bookmarkCornerSize', 'bookmarkOffset', 'bookmarkBlinkOnPageChange', 'bookmarkUsePDF'));
-
-               $this->fields['help'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Activer l'aide"));
-               $this->fields['helpBookmarks'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Améliorer l'aide des marques-pages"));
-               $this->fields['helpStartup'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Afficher l'aide au démarrage"));
-               $this->fields['helpStartupTime'] = array('type' => 'integer', 'default' => 15, 'editable' => true, 'label' => __("Temps d'affichage en secondes"));
-               $this->fields['helpArrowTooltip'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Bulle affichée au niveau de la flèche de droite'), 'grade' => 5);
-               $this->forms['help'] = array('label' => __('Aide'),
-                       'fieldsnames' => array('help', '|', 'helpStartup', 'helpStartupTime', '|', 'helpBookmarks', '|', 'helpArrowTooltip'));
-               // .
-               //
-               $this->fields['indexAutoScroll'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Activer le scroll automatique'));
-               $this->fields['pdfThumbnails'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
-                       'label' => __('PDF utilisé pour générer les miniatures'), 'grade' => 1, 'fileFilter' => $pdfFilter);
-               $this->fields['indexMessage'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __("Message en haut"), 'grade' => 1, 'hint' => __('Message en haut de la vue index'));
-
-               $this->forms['index'] = array('label' => __('Vue d\'index (vignettes)'), 'fieldsnames' => array('indexAutoScroll', 'pdfThumbnails', 'indexMessage'));
-
-               // .
-               //
-               $this->fields['print'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Activer l'impression"));
-               $this->fields['printFullBrochure'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Autoriser l'impression de la brochure complète"));
-               $this->fields['printPageRange'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Activer l'option pour imprimer une plage de pages"));
-               $this->fields['printMode'] = array('type' => 'combo', 'default' => 'vector', 'editable' => true, 'label' => __("Mode d'impression"),
-                       'datas' => array(__('Bitmap') => 'bitmap',
-                               __('Vectoriel') => 'vector',
-                               __('PDF') => 'pdf'));
-               $this->fields['printCoverWithMarks'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Imprimer les couvertures avec les pages marquées"), 'grade' => 3);
-               $this->forms['print'] = array('label' => __('Impression'),
-                       'fieldsnames' => array('print', 'printFullBrochure', 'printPageRange', 'printMode', 'printCoverWithMarks'));
-
-
-               $this->fields['search'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Activer le moteur de recherche'));
-               $this->fields['highlightResults'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Surligner les résultats'));
-               $this->fields['highlightAllOccurences'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Surligner toutes les occurences'), 'hint' => __('Même sur les pages non considérées comme un résultat'));
-               $this->fields['ignoreSearch'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Mots à ignorer'),
-                       'hint' => __('Liste des mots à ignorer séparés par des virgules'), 'grade' => 5);
-               $this->fields['ignoreSearchSeparators'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Caractères à ne pas considérer comme un séparateur de mot'));
-               $this->fields['ignoreWordLimit'] = ['type' => 'integer', 'default' => 3, 'editable' => true, 'label' => __('Ignorer les mots de moins de X caractères')];
-               $this->fields['textExtraction'] = array('type' => 'combo', 'default' => 'pdfbox', 'editable' => true, 'label' => __("Méthode d'extraction des textes"),
-                       'datas' => array(__('PDFBox') => 'pdfbox',
-                               __('Poppler') => 'poppler',
-                               __('Fluidbook (expérimentation basée sur PDFBox)') => 'fluidbook'));
-               $this->fields['searchShowNoResultsPages'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Afficher les pages sans résultats"));
-               $this->fields['searchPageSelectionAlgorithm'] = array('type' => 'combo', 'editable' => true, 'default' => 'AND',
-                       'datas' => [__('les double-pages qui contiennent tous les mots recherchés (ET logique)') => 'AND', __('les double-page qui contiennent un des mots recherché (OU logique)') => 'OR'], 'label' => __('Algorithme de sélection des résultats'));
-               $this->fields['searchWordSelectionAlgorithm'] = array('type' => 'combo', 'editable' => true, 'default' => 'begins',
-                       'datas' => [__('mot commençant par la requête') => 'begins', __('mot correspondant exactement à la requête') => 'exact', __('mot contenant la requête') => 'contains', __('expression exacte') => 'expression'],
-                       'label' => __('Algorithme de sélection des occurences'));
-
-               $this->forms['search'] = array('label' => __('Moteur de recherche'),
-                       'fieldsnames' => array('search', '|', 'ignoreWordLimit', 'ignoreSearch', 'ignoreSearchSeparators',
-                               '|', 'searchWordSelectionAlgorithm', 'searchPageSelectionAlgorithm',
-                               '|', 'highlightResults', 'highlightAllOccurences',
-                               '|', 'searchShowNoResultsPages',
-                               '|', 'textExtraction'));
-
-               $this->fields['soundTheme'] = array('type' => 'combo', 'default' => 'classic', 'editable' => true, 'label' => __("Thème sonore"),
-                       'datas' => array(__('Pas de son') => '',
-                               __('Classique') => 'classic',
-                               __("Papier épais") => 'heavy',
-                               __("Papier fin") => 'light'));
-               $this->fields['soundOn'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Activer les effets sonores à l'ouverture"));
-               $this->fields['ambientSound'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
-                       'label' => __('Ambiance sonore'), 'grade' => 3, 'fileFilter' => $soundFilter);
-               $this->fields['ambientSoundVolume'] = array('type' => 'integer', 'default' => 50, 'editable' => true,
-                       'label' => __("Volume de l'ambiance sonore"),
-                       'min' => 0, 'max' => 100);
-               $this->forms['sound'] = array('label' => __('Effets sonores'),
-                       'fieldsnames' => array('soundTheme', 'soundOn', '|', 'ambientSound', 'ambientSoundVolume'));
-               // .
-               $this->fields['pdf'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Activer les fonctions de téléchargement"));
-               $this->fields['pdfName'] = array('type' => 'text', 'default' => 'document.pdf', 'editable' => true, 'label' => __("Nom du fichier PDF"));
-               $this->fields['pdfComplex'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Téchargement de PDF avancé'), "hint" => __("Permet à l'utilisateur de sélectionner les pages qu'il souhaite télécharger"), 'grade' => 3);
-               $this->fields['pdfCompress'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Compression du fichier PDF'));
-               $this->fields['pdfReplace'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
-                       'label' => __('PDF de remplacement'), 'grade' => 3, 'fileFilter' => $pdfFilter);
-               $this->fields['offlineExport'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Téléchargement des versions offline'), "hint" => __('Valable si le téléchargement avancé est activé'), 'grade' => 3);
-               $this->forms['pdf'] = array('label' => __('Fonction de téléchargement'),
-                       'fieldsnames' => array('pdf', 'pdfName', 'pdfReplace', 'pdfCompress', 'pdfComplex', 'offlineExport'));
-               // .
-               $this->fields['zoomMode'] = array('type' => 'combo', 'default' => '0', 'editable' => true, 'label' => __("Mode de zoom"), 'grade' => 3,
-                       'datas' => array(__('Normal') => '0',
-                               __('Une page') => '1',
-                               __('Zoom désactivé') => '2'));
-               $this->fields['zoom'] = array('type' => 'integer', 'default' => 200, 'editable' => true, 'label' => __('Zoom par défaut (atteint au clic)'));
-               $this->fields['zoomw'] = array('type' => 'integer', 'default' => 300, 'editable' => true, 'label' => __("Zoom maximal (atteint à l'aide de la molette)"));
-               $this->forms['zoom'] = array('label' => __('Zoom'),
-                       'fieldsnames' => array('zoomMode', '|', 'zoom', 'zoomw'));
-               // .
-               $this->fields['stats'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Activer les statistiques Fluidbook'), 'grade' => 3);
-               $this->fields['stats_score'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Afficher les scores dans les rapports'), 'grade' => 5);
-               $this->fields['stats_exclude_ip'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Exclure les IP suivantes des statistiques'), 'grade' => 3, 'hint' => sprintf(__('Indiquer une adresse ip de la forme %s par ligne'), 'www.xxx.yyy.zzz'));
-               $this->fields['googleAnalytics'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Code Google Analytics'), 'size' => 10);
-               $this->fields['googleAnalyticsCustom'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Code Stats personnalisé (placé avant fermeture de head)'));
-               $this->fields['statsCustom'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Code Stats personnalisé (placé avant fermeture du body)'));
-               $this->fields['xiti'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Code XiTi global'));
-               $this->fields['xiti_page'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Modèle code xiti (pour tags relatifs aux pages)'));
-               $this->forms['stats'] = array('label' => __('Statistiques'),
-                       'fieldsnames' => array('stats', 'stats_score', 'stats_exclude_ip', '|', 'googleAnalytics', '|', 'googleAnalyticsCustom', 'statsCustom', '|', 'xiti', 'xiti_page'));
-
-               $this->fields['displayChaptersPopup'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Always display chapters in a popup'), 'grade' => 1);
-               $this->fields['displayChaptersIcon'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Affiche l'icône du sommaire"), 'grade' => 1);
-
-               $this->fields['displayChaptersLine'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Affiche une ligne entre le label et le numéro de page"), 'grade' => 5);
-               $this->fields['chaptersPage'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Faire pointer le sommaire sur la page'), 'grade' => 3, 'hint' => __('Laisser vide pour utiliser le sommaire classique'), 'size' => 5);
-               $this->fields['displayChaptersAtStart'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Afficher le sommaire au chargement de la publication"), 'grade' => 3);
-               $this->fields['chaptersColumns'] = array('type' => 'integer', 'default' => 1, 'editable' => true, 'label' => __('Afficher le sommaire sur x colonne(s)'), 'grade' => 3);
-               $this->fields['chaptersColMaxWidth'] = array('type' => 'integer', 'default' => 300, 'editable' => true, 'label' => __("Largeur max d'une colonne"), 'grade' => 3);
-               $this->fields['chaptersLevelLimit'] = array('type' => 'integer', 'default' => 5, 'editable' => true, 'label' => __('Limiter à x niveaux'));
-               $this->fields['externalChapters'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
-                       'label' => __('Sommaire personnalisé'), 'grade' => 3, 'fileFilter' => $swfFilter, 'hint' => __('Laisser vide pour utiliser le sommaire classique'));
-               $this->fields['externalChaptersHTML'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
-                       'label' => __('Sommaire personnalisé (HTML5)'), 'grade' => 3, 'fileFilter' => $multimediaFilter, 'hint' => __('Laisser vide pour utiliser le sommaire classique'));
-               $this->fields['fullExternalChapters'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Sommaire totalement personnalisé"), 'grade' => 3, 'hint' => __('Supprime la flèche de fermeture, titre prédéfini et couleur de fond'));
-               $this->fields['mobileChaptersStyle'] = array('type' => 'combo', 'default' => 'classic', 'editable' => true, 'label' => __('Style des chapîtres') . ' (' . __('version mobile') . ')'
-               , 'datas' => array(__('Classique') => 'classic',
-                               __('INA') => 'ina'));
-               $this->fields['chaptersPagesNumber'] = array('type' => 'combo', 'default' => 'virtual', 'editable' => true, 'label' => __('Numérotation du sommaire'), 'datas' => array(__('Virtuelle') => 'virtual',
-                       __('Physique') => 'physical'));
-
-               $this->fields['chaptersPosition'] = array('type' => 'combo', 'default' => 'center', 'editable' => true, 'label' => __("Position du sommaire"),
-                       'datas' => array(__('Centré') => 'center',
-                               __("Aligné sur l'icône") => 'chaptersIcon'));
-               $this->fields['chaptersCascade'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Sommaire en cascade"), 'grade' => 3);
-
-               $this->forms['sommaire'] = array('label' => __('Sommaire'),
-                       'fieldsnames' => array('displayChaptersIcon', 'displayChaptersPopup', 'displayChaptersAtStart', 'chaptersPage', 'chaptersPosition', 'chaptersLevelLimit', 'chaptersCascade', 'chaptersPagesNumber', '|', 'chaptersColMaxWidth', 'chaptersColumns', 'displayChaptersLine', '|', 'externalChapters', 'fullExternalChapters', '|', 'externalChaptersHTML', '|', 'mobileChaptersStyle'));
-               // .
-
-               $this->fields['ongletsXML'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('XML de configuration des onglets'), 'grade' => 5);
-               $this->fields['ongletsSWF'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
-                       'label' => __('SWF pour onglets personnalisés'), 'grade' => 3, 'fileFilter' => $swfFilter);
-
-               $this->fields['tabs2DSWF'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
-                       'label' => __('SWF pour onglets 2D'), 'grade' => 3, 'fileFilter' => $swfFilter);
-
-               $this->fields['tabsHTML5'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
-                       'label' => __('Onglets HTML5'), 'grade' => 3);
-
-               $this->fields['flatTabsAbsolute'] = array('type' => 'boolean', 'default' => false, "editable" => true,
-                       'label' => __("Positionnement relatif à l'interface"), 'grade' => 5);
-
-               $this->forms['tabs'] = array('label' => __('Onglets'),
-                       'fieldsnames' => array('ongletsSWF', 'ongletsXML', '|', 'tabs2DSWF', 'flatTabsAbsolute', '|', 'tabsHTML5'));
-
-               $this->fields['customLinkClass'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Classe pour les liens personnalisés'), 'grade' => 5);
-               $this->fields['permanentLinks'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Liens visibles en permanence'), 'grade' => 3);
-               $this->fields['ignoreLinksTypes'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Ignorer les liens de type'), 'hint' => __('Liste des numéros séparés par des virgules'), 'grade' => 5);
-               $this->fields['linkBlinkTime'] = array('type' => 'float', 'default' => 1.0, 'editable' => true, 'label' => __("Temps d'apparition du lien à l'ouverture de la page (en secondes)"));
-               $this->fields['linkTooltipManager'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("Gestionnaire des info-bulles"), 'grade' => 5);
-               $this->fields['linkTracker'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Tracking des liens'), 'grade' => 5);
-               $this->fields['linkTrackerRegexp'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Tracking des liens applicables aux liens du domaine'), 'grade' => 5);
-               $this->fields['linkFilePrefix'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Préfixer les liens de téléchargement'));
-               $this->fields['linkMultimediaPerformanceMode'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Mode perfomance pour les liens multimédia'), 'grade' => 5);
-               $this->fields['linkMultimediaQuality'] = array('type' => 'float', 'default' => 1.0, 'editable' => true, 'label' => __('Qualité de rendu des animations'), 'grade' => 5);
-               $this->fields['linkCornerSize'] = array('type' => 'integer', 'default' => '10', 'editable' => true, 'label' => __('Taille des liens de coins de page'), 'hint' => __("Pourcentage de la largeur de la page"));
-               $this->fields['linkTooltipMaxWidth'] = array('type' => 'integer', 'default' => '140', 'editable' => true, 'label' => __('Largeur max des infobulles des liens de type "infobulle"'));
-               $this->fields['videoReset'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Réinitialiser les vidéos après la lecture'), 'grade' => 3);
-               $this->fields['videoBigPlay'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Afficher le gros bouton Play'), 'grade' => 3);
-               $this->fields['brightcovePlayerId'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Brightcove Player Id'), 'grade' => 3);
-               $this->fields['brightcovePlayerSecret'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Brightcove Player Secret'), 'grade' => 3);
-               $this->fields['inlineSlideshowTransitionDuration'] = array('type' => 'float', 'default' => 0.75, 'editable' => true, 'label' => __('Durée de la transition des diaporamas intégrés aux pages (s)'));
-               $this->fields['inlineSlideshowDuration'] = array('type' => 'float', 'default' => 7, 'editable' => true, 'label' => __('Temps d\'attente des diaporamas intégrés aux pages (s)'));
-               $this->fields['textPopupStylesheet'] = ['type' => 'freefile', 'default' => '', 'editable' => true, 'label' => __('Feuille de style des popups de texte'), 'fileFilter' => $cssFilter];
-               $this->fields['textPopupWidth'] = ['type' => 'integer', 'default' => '600', 'editable' => true, 'label' => __('Largeur optimale des popups')];
-               $this->fields['iframePopupMaxWidth'] = ['type' => 'integer', 'default' => '0', 'editable' => true, 'label' => __('Largeur maximale des popups iframe')];
-               $this->forms['multimedia'] = array('label' => __('Liens et multimédia'),
-                       'fieldsnames' => array('permanentLinks', 'linkBlinkTime', 'customLinkClass', 'ignoreLinksTypes', 'linkTooltipManager', 'linkCornerSize', 'linkTooltipMaxWidth', '|', 'linkTracker', 'linkTrackerRegexp', '|', 'linkFilePrefix', '|', 'linkMultimediaPerformanceMode', 'linkMultimediaQuality', '|', 'inlineSlideshowTransitionDuration', 'inlineSlideshowDuration', '|', 'videoReset', 'videoBigPlay', '|', 'brightcovePlayerId', 'brightcovePlayerSecret', '|', 'textPopupStylesheet', 'textPopupWidth', '|', 'iframePopupMaxWidth'));
-               //.
-
-               $voices = [
-                       '' => '',
-                       __('Festival (en-US)') => 'festival:voice_cmu_us_slt_arctic_hts',
-                       __('ReadSpeaker Sophie (en-US)') => 'readspeaker:Sophie/en_us',
-                       __('ReadSpeaker Marc (en-US)') => 'readspeaker:Marc/en_us',
-               ];
-
-               $this->fields['audiodescriptionTexts'] = ['type' => 'freefile', 'default' => '', 'editable' => true, 'label' => __('Contenus textuels pour l\'audiodescription'), 'fileFilter' => $seoFilter];
-               $this->fields['audiodescriptionVoice'] = ['type' => 'combo', 'datas' => $voices, 'editable' => true, 'default' => true, 'label' => __('Voix pour l\'audiodescription')];
-               $this->forms['accessibility'] = ['label' => __('Accessibilité'),
-                       'fieldsnames' => ['audiodescriptionTexts', 'audiodescriptionVoice']
-               ];
-
-               //.
-               $this->fields['externalArchives'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
-                       'label' => __('Archives'), 'grade' => 3, 'fileFilter' => $imageFilter);
-               $this->fields['externalArchivesBack'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
-                       'label' => __('Image de fond'), 'grade' => 3, 'fileFilter' => $imageFilter);
-               $this->fields['archivesLink'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Lien'), 'grade' => 5);
-               $this->fields['archivesLabel'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Label'), 'grade' => 5);
-
-               $this->forms['archives'] = array('label' => __('Archives'),
-                       'fieldsnames' => array('externalArchives', 'externalArchivesBack', '|', 'archivesLink', 'archivesLabel'));
-               // .
-               $this->fields['form'] = array('type' => 'combo', 'default' => '', 'editable' => true, 'grade' => 5, 'label' => __('Formulaire'), 'datas' =>
-                       array(__('Aucun') => '',
-                               'Bulle Groupe' => 'bulle',
-                               'Bourbon / Suggestions' => 'bourbon',
-                               'Avery' => 'avery',
-                       ),
-               );
-               $this->forms['form'] = array('label' => __('Formulaire'),
-                       'fieldsnames' => array('form'));
-
-               $this->fields['cookieConsent'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Message cookie'));
-               $this->fields['cookieConsentMessage'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Texte du consentement'));
-               $this->fields['cookieConsentAutoclose'] = array('type' => 'integer', 'default' => '0', 'editable' => true, 'label' => __('Masquer automatiquement après x secondes'));
-               $this->forms['privacy'] = array('label' => __('Respect de la vie privée'),
-                       'fieldsnames' => array('cookieConsent', 'cookieConsentMessage', 'cookieConsentAutoclose'));
-
-               //.
-               $this->fields['basket'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Panier activé'), 'grade' => 5);
-               $this->fields['basketManager'] = array('type' => 'combo', 'default' => 'classic', 'editable' => true, 'label' => __("Manager de panier"),
-                       'datas' => array(__('Classic') => 'com.fluidbook.player.basket.BasketManager',
-                               'Grdf' => 'com.fluidbook.player.basket.custom.grdf.GrdfBasketManager',
-                               'Grdf 2013' => 'com.fluidbook.player.basket.custom.grdf.grdf2013.GrdfBasketManager2013',
-                               'Grdf 2015' => 'com.fluidbook.player.basket.custom.grdf.grdf2015.GrdfBasketManager2015',
-                               'Essilor' => 'com.fluidbook.player.basket.custom.essilor.EssilorBasketManager',
-                               'Essilor Recap' => 'com.fluidbook.player.basket.custom.essilorrecap.EssilorRecapBasketManager',
-                               'Wesco Ventes' => 'com.fluidbook.player.basket.custom.wesco.WescoBasketManager',
-                               'Atlantic Download' => 'com.fluidbook.player.basket.custom.atlantic.AtlanticDownloadBasketManager',
-                               'Remarkable' => 'Remarkable'
-                       ), 'grade' => 5);
-               $this->fields['basketReferences'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
-                       'label' => __('Références produits'), 'grade' => 3, 'fileFilter' => $basketFilter, 'hint' => __('Fichier contenant les références produits'), 'dir' => 'commerce');
-               $this->fields['basketImages'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
-                       'label' => __('Images des produits'), 'grade' => 5, 'fileFilter' => $imageFilter, 'hint' => __('Chaque image doit avoir pour nom exact la référence du produit'),
-                       'multiple' => true, 'dir' => 'commerce');
-               $this->fields['basketPDFBackground'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
-                       'label' => __('Fond du PDF (bon de commande)'), 'grade' => 5, 'fileFilter' => $epsFilter, 'hint' => __('Fond du bon de commande'), 'dir' => 'commerce');
-
-               $this->forms['basket'] = array('label' => __('Panier'),
-                       'fieldsnames' => array('basket', 'basketManager', 'basketReferences', 'basketImages', 'basketPDFBackground'));
-               // .
-               $this->fields['offlineLink'] = array('type' => 'text', 'default' => 'http://', 'editable' => true, 'label' => __("URL du Fluidbook"), 'hint' => __('URL du fluidbook utilisée pour la version Offline (CD-ROM, clé USB, Exécutables)'));
-               $this->fields['offlineTitle'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("Titre de l'application"));
-               $this->fields['offlineEnableAdvancedPrinting'] = ['type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Activer le menu d\'impression avancée')];
-               $this->forms['offline'] = array('label' => __('Version offline'),
-                       'fieldsnames' => array('offlineTitle', 'offlineLink', '|', 'offlineEnableAdvancedPrinting'));
-
-               $this->fields['alwaysHTML5'] = array('type' => 'boolean', 'default' => 'false', 'editable' => true, 'label' => __('Toujours utiliser la version HTML5'), 'grade' => 1);
-
-               $this->fields['html5priority'] = array('type' => 'combo', 'default' => 'true', 'editable' => true, 'label' => __("Rediriger vers la version HTML5"), 'grade' => 1,
-                       'datas' => array(__('Si l\'utilisateur a un appareil tactile') => 'false',
-                               __('Si flash n\'est pas installé') => 'notinstalled',
-                               __("Si flash n'est pas pas installé ou bloqué") => 'true'));
-
-               $this->fields['flashBlockedWait'] = array('type' => 'float', 'default' => 1.5, 'editable' => true, 'label' => __("Temps d'attente avant de considérer flash comme bloqué"));
-
-
-               $this->fields['navOrderH'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Ordre des icônes dans la nav') . ' (' . __('Si différente') . ')', 'grade' => 3);
-
-               $this->fields['menuBreakpoint'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Breakpoint burger menu'), 'hint' => 'Par défaut 1023px', 'grade' => 3);
-
-
-               $this->fields['mobileNavigationType'] = array('type' => 'combo', 'default' => 'book', 'editable' => true, 'label' => __('Mode de navigation'), 'grade' => 5,
-                       'datas' => array(__('Normal (automatique)') => 'book',
-                               __('Normal (double page)') => 'landscape',
-                               __('Normal (une page)') => 'portrait',
-                               __('Magazine tablette') => 'tab')
-               );
-               $this->fields['rasterizePages'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Ecraser les pages'), 'hint' => '1-3,5 = 1,2,3,5', 'grade' => 1);
-               $this->fields['vectorPages'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Conserver les pages en vecteur'), 'hint' => '1-3,5 = 1,2,3,5', 'grade' => 1);
-
-
-               $this->fields['mobileTransitionDuration'] = array('type' => 'float', 'default' => '0.75', 'editable' => true, 'label' => __('Durée de la transition'));
-               $this->fields['mobileLinksRevealAnim'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Animer les liens après un changement de page"), 'grade' => 3);
-
-               $this->fields['mobileIconVector'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Utiliser les icônes vectorielles'));
-               $this->fields['mobileServerConfig'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Inclure les fichiers de configuration serveur'), 'grade' => 3);
-
-               $this->fields['mobilePlugins'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Plugin'), 'grade' => 5);
-
-               $this->fields['mobileVideosPath'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Chemin vers les vidéos'), 'grade' => 5);
-               $this->fields['mobileExtraXSpace'] = array('type' => 'integer', 'default' => '0', 'editable' => true, 'label' => __('Marge supplémentaire horizontale'), 'grade' => 3);
-               $this->fields['mobileNavScale'] = array('type' => 'integer', 'default' => '100', 'editable' => true, 'label' => __('Taille du menu (en %)'), 'grade' => 3);
-
-               $this->fields['mobileIgnoreBackgroundLinks'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Ignorer les liens de background'));
-
-               $this->forms['mobile'] = array('label' => __('Version mobile'),
-                       'fieldsnames' => array('alwaysHTML5', 'html5priority', 'flashBlockedWait', 'mobileNavigationType', '|', 'rasterizePages', 'vectorPages', '|', 'mobileNavScale', '|', 'mobileTransitionDuration', "mobileLinksRevealAnim", '|', 'menuBreakpoint', 'navOrderH', '|', 'mobileIconVector', 'mobileServerConfig', 'mobilePlugins', '|', 'mobileVideosPath', '|', 'mobileExtraXSpace', '|', 'mobileIgnoreBackgroundLinks'));
-
-
-               $this->fields['phonegapId'] = array('type' => 'text', 'default' => 'com.fluidbook.phonegap.$id', 'editable' => true, 'label' => __("Identifiant de l'identifiant"), 'grade' => 5, 'hint' => __('De la forme') . ' com.fluidbook.phonegap.xxxxx');
-               $this->fields['phonegapVersion'] = array('type' => 'text', 'default' => '1.0.0', 'editable' => true, 'label' => __("Version de l'application"), 'grade' => 5, 'hint' => __('De la forme') . ' 1.2.3');
-               $this->fields['phonegapPlugins'] = array('type' => 'textarea', 'default' => 'ChildBrowser', 'editable' => true, 'label' => __('Plugins Phonegap'), 'grade' => 5);
-               $defaultScreenshots = "P,0\nL,2\nL,index";
-               $this->fields['appScreenshots'] = array('type' => 'textarea', 'default' => $defaultScreenshots, 'editable' => true, 'label' => 'Générer les screenshots', 'grade' => 5, 'hint' => __('Une ligne par vue à générer de la forme X,Y (X : P(ortrait) ou L(andscape), Y : numéro de page ou vue (1, index))'));
-
-               $this->forms['phonegap'] = array('label' => __('Applications mobile'),
-                       'fieldsnames' => array('phonegapId', 'phonegapVersion', 'phonegapPlugins', 'appScreenshots'));
-
-               $this->fields['secureURL'] = array('type' => 'text', 'default' => 'http://', 'editable' => true, 'label' => __('URL de sécurisation'), 'grade' => 5, 'hint' => __('URL intérrogé pour vérifier si le visiteur à les droits pour consulter la publication'));
-               $this->fields['secureURLRedirect'] = array('type' => 'text', 'default' => 'http://', 'editable' => true, 'label' => __('Redirection'), 'grade' => 5, 'hint' => __("Si l'authentification échoue, redirection vers cette adresse"));
-               $this->fields['preventRightClick'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Essayer d'empêcher le clic droit"), 'grade' => 1);
-               $this->forms['secure'] = array('label' => __('Sécurisation'),
-                       'fieldsnames' => array('secureURL', 'secureURLRedirect', '|', 'preventRightClick'));
-
-               $this->fields['home'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("Accueil de l'interface multibrochure"), 'grade' => 5);
-               $this->fields['multilang'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Langues'), 'hint' => __('Code langue') . ',' . __('Code pays') . ',' . __('URL'));
-               $this->fields['country'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Pays de la brochure'));
-               $this->fields['multilangDisplay'] = array('type' => 'combo', 'default' => 'lang', 'editable' => true, 'label' => __('Affichage'),
-                       'datas' => array(__('Langue') => 'lang',
-                               __('Langue') . ' (' . __('Pays') . ')' => 'lang_country',
-                               __('Pays') . ' (' . __('Langue') . ')' => 'country_lang'));
-               $this->forms['multibrochure'] = array('label' => __('Multibrochure'),
-                       'fieldsnames' => array('home', 'country', 'multilangDisplay', 'multilang'));
-
-               $this->fields['plv'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Activer le mode PLV'), 'grade' => 3);
-               $this->fields['plvTimer'] = array('type' => 'integer', 'min' => 1, 'max' => 60, 'default' => 5, 'editable' => true, 'label' => __('Temps'), 'grade' => 3);
-               $this->fields['plvMode'] = array('type' => 'combo', 'default' => 'first', 'editable' => true, 'label' => __('Arrivé à la dernière page'), 'grade' => 3,
-                       'datas' => array(__('Remonter vers la première page') => 'back',
-                               __('Recommencer à la première page') => 'first'));
-               $this->forms['plv'] = array('label' => __('Mode PLV'),
-                       'fieldsnames' => array('plv', 'plvTimer', 'plvMode'));
-
-               $this->fields['widget'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Générer le widget'), 'grade' => 3);
-               $this->fields['widgetCover'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Afficher la couverture') . ')', 'grade' => 3);
-               $this->fields['widgetSize'] = array('type' => 'integer', 'default' => 200, 'editable' => true, 'label' => __('Optimiser pour une hauteur de (en pixels)'), 'grade' => 3);
-               $this->fields['widgetQuality'] = array('type' => 'integer', 'default' => 85, 'min' => 0, 'max' => 100, 'editable' => true, 'label' => __('Qualité JPEG'), 'grade' => 3);
-               $this->fields['widgetStart'] = array('type' => 'integer', 'default' => 1, 'editable' => true, 'label' => __('Page de début'), 'grade' => 3);
-               $this->fields['widgetEnd'] = array('type' => 'integer', 'default' => 8, 'editable' => true, 'label' => __('Page de fin'), 'grade' => 3);
-               $this->forms['widget'] = array('label' => __('Widget') . ' (' . __('Mini Fluidbook') . ')',
-                       'fieldsnames' => array('widget', 'widgetCover', 'widgetSize', 'widgetQuality', 'widgetStart', 'widgetEnd'));
-
-               $this->fields['extras'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Extras'), 'grade' => 3);
-               $this->fields['v1SWF'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
-                       'label' => __('Index.swf spécifique'), 'grade' => 5, 'fileFilter' => $swfFilter);
-               $this->forms['v1'] = array('label' => __('Options spécifiques au fluidbook version 1'),
-                       'fieldsnames' => array('extras', 'v1SWF'));
-
-               $this->fields['themeEnableAfterSearch'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Afficher l'image supplémentaire à droite du moteur de recherche"), 'grade' => 3);
-               $this->forms['theme'] = array('label' => __('Options du thème'),
-                       'fieldsnames' => array('themeEnableAfterSearch'));
-
-               $this->fields['forceCompileOnDownload'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Forcer la compilation lors du téléchargement'), 'grade' => 3);
-               $this->fields['htmlExtension'] = array('type' => 'text', 'default' => 'html', 'editable' => true, 'label' => __('Extension des fichiers html'), 'grade' => 5, 'hint' => __('Ex : php, htm, html, phtml, asp'), 'grade' => 5);
-               $this->fields['htmlPrepend'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Code à insérer en tête des fichiers'), 'grade' => 5);
-               $this->fields['baseUrl'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Base de l\'url'), 'grade' => 5, 'grade' => 5);
-
-               $this->forms['package'] = array('label' => __('Option d\'export'),
-                       'fieldsnames' => array('htmlExtension', 'htmlPrepend', 'baseUrl', 'forceCompileOnDownload'));
-
-               $this->fields['disableDemo'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Désactiver le lien de démo'), 'grade' => 5);
-               $this->fields['redirectDemo'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Rediriger le lien de démo vers'), 'grade' => 5);
-               $this->forms['demo'] = array('label' => __('Lien de démo'),
-                       'fieldsnames' => array('disableDemo', 'redirectDemo'));
-
-
-               $this->fields['scorm_enable'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Activer SCORM'), 'grade' => 5);
-               $this->fields['scorm_version'] = array('type' => 'combo', 'default' => '1.2', 'editable' => true, 'label' => __('Version du standard SCORM'), 'grade' => 5,
-                       'datas' => array(__('SCORM 1.2') => '1.2',
-                               __('SCORM 2004 4th edition') => '2004')
-               );
-               $this->fields['scorm_id'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Identifiant SCORM'), 'grade' => 5);
-               $this->fields['scorm_org'] = array('type' => 'text', 'default' => 'ACME-ORG-1350650111249', 'editable' => true, 'label' => __('Organisation SCORM'), 'grade' => 5);
-               $this->fields['scorm_title'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Titre SCORM'), 'grade' => 5, 'hint' => __('Laisser vide pour utiliser le titre de la publication'));
-               $this->fields['scorm_variables'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Variables SCORM'), 'grade' => 5, 'hint' => __('Laisser vide pour utiliser le titre de la publication'));
-               $this->fields['scorm_score'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Activer le support du score'), 'grade' => 5);
-               $this->fields['scorm_score_min'] = array('type' => 'integer', 'min' => 0, 'max' => 100, 'default' => 50, 'editable' => true, 'label' => __('Score minimal pour marquer le contenu comme réussi'), 'grade' => 5);
-               $this->fields['scorm_quiz_as_questionnaire'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Traiter les quiz comme des questionnaires (toutes les réponses sont considérées comme correctes)'), 'grade' => 5);
-               $this->fields['scorm_quizdata'] = array('type' => 'freefile', 'editable' => true, 'default' => '', 'label' => __('Données de quiz'));
-               $this->fields['scorm_complete_on_exit'] = ['type' => 'boolean', 'default' => false, 'label' => 'Marquer le cours comme "Complete" à la fermeture de la fenêtre', 'editable' => true];
-
-               $this->forms['scorm'] = array('label' => __('SCORM'),
-                       'fieldsnames' => array('scorm_enable', 'scorm_version', 'scorm_id', 'scorm_org', 'scorm_title', 'scorm_variables', '|', 'scorm_complete_on_exit', '|', 'scorm_quizdata', 'scorm_score', 'scorm_score_min', 'scorm_quiz_as_questionnaire'));
-
-               $versions = wsUrl::getFluidbookVersions(false);
-               $ignore = ['v1', 'v2', 'phonegap'];
-               $fields = [];
-               foreach ($versions as $k => $version) {
-                       if (in_array($k, $ignore)) {
-                               continue;
-                       }
-                       $this->fields['download_' . $k] = ['type' => 'boolean', 'editable' => true, 'default' => false, 'label' => $version['title'], 'grade' => 3];
-                       $fields[] = 'download_' . $k;
-               }
-               $this->fields['download_online']['default'] = true;
-
-               $this->forms['downloads'] = array('label' => __('Versions disponibles au téléchargement'),
-                       'fieldsnames' => $fields);
-
-       }
+        $this->fields['seoVersion'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Générer une version pour les moteurs de recherche'));
+        $this->fields['seoRobots'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Autoriser le parcours par les moteurs de recherche'));
+        $this->fields['seoDescription'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Meta tag Description'));
+        $this->fields['seoKeywords'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Meta tag Keywords'));
+        $this->fields['seoAdvanced'] = ['type' => 'freefile', 'default' => '', 'editable' => true, 'label' => __('Données SEO par page'), 'grade' => 5, 'fileFilter' => $seoFilter];
+        $this->fields['seoBaseURL'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('URL de base'), 'grade' => 5, 'hint' => __("Si l'authentification échoue, redirection vers cette adresse"));
+
+        $this->forms['seo'] = array('label' => __('Optimisation pour les moteurs de recherche'),
+            'fieldsnames' => array('seoVersion', 'seoRobots', 'seoDescription', "seoKeywords", '|', 'seoBaseURL', 'seoAdvanced'));
+
+        // .
+        $this->fields['pages'] = array('type' => 'integer', 'default' => '', 'editable' => false, 'label' => __('Nombre de pages'));
+        $this->fields['width'] = array('type' => 'float', 'default' => '', 'editable' => false, 'label' => __('Largeur'));
+        $this->fields['height'] = array('type' => 'float', 'default' => '', 'editable' => false, 'label' => __('Hauteur'));
+        // .
+        $this->fields['visualisationMode'] = array('type' => 'combo', 'default' => '3', 'editable' => true, 'label' => __("Mode de visualisation 3D"),
+            'datas' => array(__('Mode 3D') => '0',
+                __('Mode 2D (caméra fixe et pages à plat)') => '1',
+                __("Laisser le choix à l'utilisateur (mode 3D par défaut)") => '2',
+                __("Laisser le choix à l'utilisateur (mode 2D par défaut)") => '3'));
+        $this->fields['viewMode'] = array('type' => 'combo', 'default' => '0', 'editable' => true, 'label' => __("Mode de visualisation (beta)"),
+            'datas' => array(__('Classique') => '0',
+                __("Diaporama") => '1'), 'grade' => 5);
+        $this->fields['antialiasReading'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Amélioration de la lisibilité en mode 2D"));
+        $this->fields['pagesBaseAngle'] = array('type' => 'integer', 'default' => '2', 'editable' => true, 'label' => __('Angle de base entre les pages'), 'grade' => 3,
+            'hint' => __("0 : Publication à plat") . "\n" . __('2 : Valeur par défaut'));
+        $this->fields['extraXSpace'] = array('type' => 'integer', 'default' => '0', 'editable' => true, 'label' => __('Marge supplémentaire horizontale'), 'grade' => 3);
+        $this->fields['extraYSpace'] = array('type' => 'integer', 'default' => '0', 'editable' => true, 'label' => __('Marge supplémentaire verticale'), 'grade' => 3);
+        $this->fields['centerBook'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Centrer la publication sur les couvertures'), 'grade' => 2);
+        $this->fields['correctCenter'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Corriger les lignes blanches entre les pages'), 'grade' => 2);
+        $this->fields['maxResolution'] = array('type' => 'combo', 'default' => 300, 'editable' => true, 'datas' => array('300dpi' => 300, '150dpi' => 150), 'grade' => 2, 'label' => __('Résolution maximale des pages'));
+        $this->forms['3d_mode'] = array('label' => __('Options de visualisation'),
+            'fieldsnames' => array('visualisationMode', 'antialiasReading', 'correctCenter', 'pagesBaseAngle', 'centerBook', '|', 'extraXSpace', 'extraYSpace', '|', 'viewMode', '|', 'maxResolution'));
+
+        $this->fields['preload'] = array('type' => 'integer', 'default' => 16, 'editable' => true, 'label' => __('Nombre de pages à précharger'), 'grade' => 3);
+
+        $this->fields['maxPages'] = array('type' => 'integer', 'default' => 0, 'editable' => true, 'label' => __("Nombre de pages maximal affiché à l'ouverture du fluidbook (pas de limite = 0)"), 'grade' => 3);
+        $this->fields['navOrder'] = array('type' => 'textarea', 'default' => 'index, chapters, search, print, friend, bookmark, pdf, archives, basket, fullscreen, sound, 3d, extra, extra1, extra2, extra3, extra4, extra5, help, lang', 'editable' => true, 'label' => __('Ordre des icônes dans la nav'), 'grade' => 3);
+        $this->fields['tooltipTimer'] = array('type' => 'float', 'default' => 3, "editable" => true, 'label' => __("Temps maximum d'apparition des infos-bulles (en secondes)"));
+
+
+        $this->forms['general'] = array('label' => __('Fonctionnalités générales'),
+            'fieldsnames' => array('navOrder', 'tooltipTimer', 'preload', 'maxPages', 'pages', 'width', 'height'));
+        //.
+        //
+
+        $this->forms['menu'] = array('label' => __('Menu'), 'fieldsnames' => ['afterSearchDisplayForHTML', '|']);
+        $this->fields['afterSearchDisplayForHTML'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Afficher l\'image après le moteur de recherche sur la version HTML5'), 'grade' => 1);
+        $extraNum = 5;
+        for ($i = 0; $i <= $extraNum; $i++) {
+            if ($i > 0) {
+                $j = $i;
+                $this->fields['navExtraIcon' . $j] = array('type' => 'freefile', 'default' => '', 'editable' => true, 'label' => __('Icône supplémentaire') . ' ' . $j, 'fileFilter' => $imageExtraFilter);
+                $this->fields['navExtraType' . $j] = array('type' => 'combo', 'datas' => $extraType, 'default' => 'icon', 'editable' => true, 'label' => __('Type'));
+                $this->fields['navExtraLink' . $j] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("URL") . ' ' . $j);
+                $this->fields['navExtraVisibility' . $j] = array('type' => 'combo', 'datas' => $extraVisibility, 'default' => 'both', 'editable' => true, 'label' => __("Visible") . ' ' . $j);
+                $this->forms['menu']['fieldsnames'] = array_merge($this->forms['menu']['fieldsnames'], ['navExtraIcon' . $j, 'navExtraType' . $j, 'navExtraLink' . $j, 'navExtraVisibility' . $j, '|']);
+            } else {
+                $j = '';
+                $this->fields['navExtraImage' . $j] = array('type' => 'freefile', 'default' => '', 'editable' => true, 'label' => __('Image pour navigation'), 'fileFilter' => $imageExtraFilter);
+                $this->fields['navExtraImageMobile' . $j] = array('type' => 'freefile', 'default' => '', 'editable' => true, 'label' => __('Image pour mobile'), 'fileFilter' => $imageExtraFilter);
+                $this->fields['navExtraLink' . $j] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("URL"));
+                $this->fields['navExtraTooltip' . $j] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("Infobulle ou label"));
+                $this->forms['menu']['fieldsnames'] = array_merge($this->forms['menu']['fieldsnames'], ['navExtraImage' . $j, 'navExtraImageMobile' . $j, 'navExtraLink' . $j, 'navExtraTooltip' . $j, '|']);
+            }
+        }
+
+
+        $this->fields['landingPage'] = array('type' => 'freefile', 'default' => '', 'editable' => true, 'label' => __('Landing Page content'), 'grade' => 3);
+        $this->forms['landing'] = array('label' => __('Custom Landing Page'), 'fieldsnames' => array('landingPage'));
+
+
+        $this->fields['fullscreen'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Activer le mode plein-écran'));
+        $this->fields['fullscreenAuto'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Lancer la publication en mode plein écran (lorsque possible)'));
+        $this->forms['fs'] = array('label' => __('Plein écran'),
+            'fieldsnames' => array('fullscreen', 'fullscreenAuto'));
+
+
+        $this->fields['bookmark'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Activer les marques-pages'));
+        $this->fields['bookmarkSendEnable'] = array('type' => 'boolean', 'default' => 'true', 'editable' => true, 'label' => __("Activer l'envoi des marques-pages par e-mail"));
+        $this->fields['bookmark_email_title'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("Titre de l'email") . ' "' . __('Envoyer à un ami') . '"', 'hint' => __('Laisser vide pour utiliser la valeur par défaut'));
+        $this->fields['bookmark_email_body'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __("Corps de l'email") . ' "' . __('Envoyer à un ami') . '"', 'hint' => __('Laisser vide pour utiliser la valeur par défaut'));
+        $this->fields['bookmarkCornerSize'] = array('type' => 'integer', 'default' => 8, 'editable' => true, 'label' => __("Taille des marques-pages"), 'hint' => __('Taille relative à la largeur de la page'));
+        $this->fields['bookmarkOffset'] = array('type' => 'integer', 'default' => 0, 'editable' => true, 'label' => __("Décaler de x pixels vers l'intérieur"));
+        $this->fields['bookmarkBlinkOnPageChange'] = array('type' => 'boolean', 'default' => 'false', 'editable' => true, 'label' => __('Faire clignoter le marque page à l\'apparition de la page'));
+        $this->fields['bookmarkUsePDF'] = array('type' => 'combo', 'default' => 'pages', 'editable' => true, 'label' => __('PDF à utiliser pour l\'envoi ou le téléchargement de pages marquées'),
+            'datas' => [__('PDF des pages') => 'pages',
+                __('PDF de remplacement') => 'download',
+                __('PDF des miniatures') => 'thumbnails']);
+        $this->forms['bookmark'] = array('label' => __('Marques-pages'),
+            'fieldsnames' => array('bookmark', '|', 'bookmarkSendEnable', 'bookmark_email_title', 'bookmark_email_body', '|', 'bookmarkCornerSize', 'bookmarkOffset', 'bookmarkBlinkOnPageChange', 'bookmarkUsePDF'));
+
+        $this->fields['help'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Activer l'aide"));
+        $this->fields['helpBookmarks'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Améliorer l'aide des marques-pages"));
+        $this->fields['helpStartup'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Afficher l'aide au démarrage"));
+        $this->fields['helpStartupTime'] = array('type' => 'integer', 'default' => 15, 'editable' => true, 'label' => __("Temps d'affichage en secondes"));
+        $this->fields['helpArrowTooltip'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Bulle affichée au niveau de la flèche de droite'), 'grade' => 5);
+        $this->forms['help'] = array('label' => __('Aide'),
+            'fieldsnames' => array('help', '|', 'helpStartup', 'helpStartupTime', '|', 'helpBookmarks', '|', 'helpArrowTooltip'));
+        // .
+        //
+        $this->fields['indexAutoScroll'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Activer le scroll automatique'));
+        $this->fields['pdfThumbnails'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
+            'label' => __('PDF utilisé pour générer les miniatures'), 'grade' => 1, 'fileFilter' => $pdfFilter);
+        $this->fields['indexMessage'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __("Message en haut"), 'grade' => 1, 'hint' => __('Message en haut de la vue index'));
+
+        $this->forms['index'] = array('label' => __('Vue d\'index (vignettes)'), 'fieldsnames' => array('indexAutoScroll', 'pdfThumbnails', 'indexMessage'));
+
+        // .
+        //
+        $this->fields['print'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Activer l'impression"));
+        $this->fields['printFullBrochure'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Autoriser l'impression de la brochure complète"));
+        $this->fields['printPageRange'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Activer l'option pour imprimer une plage de pages"));
+        $this->fields['printMode'] = array('type' => 'combo', 'default' => 'vector', 'editable' => true, 'label' => __("Mode d'impression"),
+            'datas' => array(__('Bitmap') => 'bitmap',
+                __('Vectoriel') => 'vector',
+                __('PDF') => 'pdf'));
+        $this->fields['printCoverWithMarks'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Imprimer les couvertures avec les pages marquées"), 'grade' => 3);
+        $this->forms['print'] = array('label' => __('Impression'),
+            'fieldsnames' => array('print', 'printFullBrochure', 'printPageRange', 'printMode', 'printCoverWithMarks'));
+
+
+        $this->fields['search'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Activer le moteur de recherche'));
+        $this->fields['highlightResults'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Surligner les résultats'));
+        $this->fields['highlightAllOccurences'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Surligner toutes les occurences'), 'hint' => __('Même sur les pages non considérées comme un résultat'));
+        $this->fields['ignoreSearch'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Mots à ignorer'),
+            'hint' => __('Liste des mots à ignorer séparés par des virgules'), 'grade' => 5);
+        $this->fields['ignoreSearchSeparators'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Caractères à ne pas considérer comme un séparateur de mot'));
+        $this->fields['ignoreWordLimit'] = ['type' => 'integer', 'default' => 3, 'editable' => true, 'label' => __('Ignorer les mots de moins de X caractères')];
+        $this->fields['textExtraction'] = array('type' => 'combo', 'default' => 'pdfbox', 'editable' => true, 'label' => __("Méthode d'extraction des textes"),
+            'datas' => array(__('PDFBox') => 'pdfbox',
+                __('Poppler') => 'poppler',
+                __('Fluidbook (expérimentation basée sur PDFBox)') => 'fluidbook'));
+        $this->fields['searchShowNoResultsPages'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Afficher les pages sans résultats"));
+        $this->fields['searchPageSelectionAlgorithm'] = array('type' => 'combo', 'editable' => true, 'default' => 'AND',
+            'datas' => [__('les double-pages qui contiennent tous les mots recherchés (ET logique)') => 'AND', __('les double-page qui contiennent un des mots recherché (OU logique)') => 'OR'], 'label' => __('Algorithme de sélection des résultats'));
+        $this->fields['searchWordSelectionAlgorithm'] = array('type' => 'combo', 'editable' => true, 'default' => 'begins',
+            'datas' => [__('mot commençant par la requête') => 'begins', __('mot correspondant exactement à la requête') => 'exact', __('mot contenant la requête') => 'contains', __('expression exacte') => 'expression'],
+            'label' => __('Algorithme de sélection des occurences'));
+
+        $this->forms['search'] = array('label' => __('Moteur de recherche'),
+            'fieldsnames' => array('search', '|', 'ignoreWordLimit', 'ignoreSearch', 'ignoreSearchSeparators',
+                '|', 'searchWordSelectionAlgorithm', 'searchPageSelectionAlgorithm',
+                '|', 'highlightResults', 'highlightAllOccurences',
+                '|', 'searchShowNoResultsPages',
+                '|', 'textExtraction'));
+
+        $this->fields['soundTheme'] = array('type' => 'combo', 'default' => 'classic', 'editable' => true, 'label' => __("Thème sonore"),
+            'datas' => array(__('Pas de son') => '',
+                __('Classique') => 'classic',
+                __("Papier épais") => 'heavy',
+                __("Papier fin") => 'light'));
+        $this->fields['soundOn'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Activer les effets sonores à l'ouverture"));
+        $this->fields['ambientSound'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
+            'label' => __('Ambiance sonore'), 'grade' => 3, 'fileFilter' => $soundFilter);
+        $this->fields['ambientSoundVolume'] = array('type' => 'integer', 'default' => 50, 'editable' => true,
+            'label' => __("Volume de l'ambiance sonore"),
+            'min' => 0, 'max' => 100);
+        $this->forms['sound'] = array('label' => __('Effets sonores'),
+            'fieldsnames' => array('soundTheme', 'soundOn', '|', 'ambientSound', 'ambientSoundVolume'));
+        // .
+        $this->fields['pdf'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Activer les fonctions de téléchargement"));
+        $this->fields['pdfName'] = array('type' => 'text', 'default' => 'document.pdf', 'editable' => true, 'label' => __("Nom du fichier PDF"));
+        $this->fields['pdfComplex'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Téchargement de PDF avancé'), "hint" => __("Permet à l'utilisateur de sélectionner les pages qu'il souhaite télécharger"), 'grade' => 3);
+        $this->fields['pdfCompress'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Compression du fichier PDF'));
+        $this->fields['pdfReplace'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
+            'label' => __('PDF de remplacement'), 'grade' => 3, 'fileFilter' => $pdfFilter);
+        $this->fields['offlineExport'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Téléchargement des versions offline'), "hint" => __('Valable si le téléchargement avancé est activé'), 'grade' => 3);
+        $this->forms['pdf'] = array('label' => __('Fonction de téléchargement'),
+            'fieldsnames' => array('pdf', 'pdfName', 'pdfReplace', 'pdfCompress', 'pdfComplex', 'offlineExport'));
+        // .
+        $this->fields['zoomMode'] = array('type' => 'combo', 'default' => '0', 'editable' => true, 'label' => __("Mode de zoom"), 'grade' => 3,
+            'datas' => array(__('Normal') => '0',
+                __('Une page') => '1',
+                __('Zoom désactivé') => '2'));
+        $this->fields['zoom'] = array('type' => 'integer', 'default' => 200, 'editable' => true, 'label' => __('Zoom par défaut (atteint au clic)'));
+        $this->fields['zoomw'] = array('type' => 'integer', 'default' => 300, 'editable' => true, 'label' => __("Zoom maximal (atteint à l'aide de la molette)"));
+        $this->forms['zoom'] = array('label' => __('Zoom'),
+            'fieldsnames' => array('zoomMode', '|', 'zoom', 'zoomw'));
+        // .
+        $this->fields['stats'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Activer les statistiques Fluidbook'), 'grade' => 3);
+        $this->fields['stats_score'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Afficher les scores dans les rapports'), 'grade' => 5);
+        $this->fields['stats_exclude_ip'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Exclure les IP suivantes des statistiques'), 'grade' => 3, 'hint' => sprintf(__('Indiquer une adresse ip de la forme %s par ligne'), 'www.xxx.yyy.zzz'));
+        $this->fields['googleAnalytics'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Code Google Analytics'), 'size' => 10);
+        $this->fields['googleAnalyticsCustom'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Code Stats personnalisé (placé avant fermeture de head)'));
+        $this->fields['statsCustom'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Code Stats personnalisé (placé avant fermeture du body)'));
+        $this->fields['xiti'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Code XiTi global'));
+        $this->fields['xiti_page'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Modèle code xiti (pour tags relatifs aux pages)'));
+        $this->forms['stats'] = array('label' => __('Statistiques'),
+            'fieldsnames' => array('stats', 'stats_score', 'stats_exclude_ip', '|', 'googleAnalytics', '|', 'googleAnalyticsCustom', 'statsCustom', '|', 'xiti', 'xiti_page'));
+
+        $this->fields['displayChaptersPopup'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Always display chapters in a popup'), 'grade' => 1);
+        $this->fields['displayChaptersIcon'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Affiche l'icône du sommaire"), 'grade' => 1);
+
+        $this->fields['displayChaptersLine'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Affiche une ligne entre le label et le numéro de page"), 'grade' => 5);
+        $this->fields['chaptersPage'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Faire pointer le sommaire sur la page'), 'grade' => 3, 'hint' => __('Laisser vide pour utiliser le sommaire classique'), 'size' => 5);
+        $this->fields['displayChaptersAtStart'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Afficher le sommaire au chargement de la publication"), 'grade' => 3);
+        $this->fields['chaptersColumns'] = array('type' => 'integer', 'default' => 1, 'editable' => true, 'label' => __('Afficher le sommaire sur x colonne(s)'), 'grade' => 3);
+        $this->fields['chaptersColMaxWidth'] = array('type' => 'integer', 'default' => 300, 'editable' => true, 'label' => __("Largeur max d'une colonne"), 'grade' => 3);
+        $this->fields['chaptersLevelLimit'] = array('type' => 'integer', 'default' => 5, 'editable' => true, 'label' => __('Limiter à x niveaux'));
+        $this->fields['externalChapters'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
+            'label' => __('Sommaire personnalisé'), 'grade' => 3, 'fileFilter' => $swfFilter, 'hint' => __('Laisser vide pour utiliser le sommaire classique'));
+        $this->fields['externalChaptersHTML'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
+            'label' => __('Sommaire personnalisé (HTML5)'), 'grade' => 3, 'fileFilter' => $multimediaFilter, 'hint' => __('Laisser vide pour utiliser le sommaire classique'));
+        $this->fields['fullExternalChapters'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Sommaire totalement personnalisé"), 'grade' => 3, 'hint' => __('Supprime la flèche de fermeture, titre prédéfini et couleur de fond'));
+        $this->fields['mobileChaptersStyle'] = array('type' => 'combo', 'default' => 'classic', 'editable' => true, 'label' => __('Style des chapîtres') . ' (' . __('version mobile') . ')'
+        , 'datas' => array(__('Classique') => 'classic',
+                __('INA') => 'ina'));
+        $this->fields['chaptersPagesNumber'] = array('type' => 'combo', 'default' => 'virtual', 'editable' => true, 'label' => __('Numérotation du sommaire'), 'datas' => array(__('Virtuelle') => 'virtual',
+            __('Physique') => 'physical'));
+
+        $this->fields['chaptersPosition'] = array('type' => 'combo', 'default' => 'center', 'editable' => true, 'label' => __("Position du sommaire"),
+            'datas' => array(__('Centré') => 'center',
+                __("Aligné sur l'icône") => 'chaptersIcon'));
+        $this->fields['chaptersCascade'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Sommaire en cascade"), 'grade' => 3);
+
+        $this->forms['sommaire'] = array('label' => __('Sommaire'),
+            'fieldsnames' => array('displayChaptersIcon', 'displayChaptersPopup', 'displayChaptersAtStart', 'chaptersPage', 'chaptersPosition', 'chaptersLevelLimit', 'chaptersCascade', 'chaptersPagesNumber', '|', 'chaptersColMaxWidth', 'chaptersColumns', 'displayChaptersLine', '|', 'externalChapters', 'fullExternalChapters', '|', 'externalChaptersHTML', '|', 'mobileChaptersStyle'));
+        // .
+
+        $this->fields['ongletsXML'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('XML de configuration des onglets'), 'grade' => 5);
+        $this->fields['ongletsSWF'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
+            'label' => __('SWF pour onglets personnalisés'), 'grade' => 3, 'fileFilter' => $swfFilter);
+
+        $this->fields['tabs2DSWF'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
+            'label' => __('SWF pour onglets 2D'), 'grade' => 3, 'fileFilter' => $swfFilter);
+
+        $this->fields['tabsHTML5'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
+            'label' => __('Onglets HTML5'), 'grade' => 3);
+
+        $this->fields['flatTabsAbsolute'] = array('type' => 'boolean', 'default' => false, "editable" => true,
+            'label' => __("Positionnement relatif à l'interface"), 'grade' => 5);
+
+        $this->forms['tabs'] = array('label' => __('Onglets'),
+            'fieldsnames' => array('ongletsSWF', 'ongletsXML', '|', 'tabs2DSWF', 'flatTabsAbsolute', '|', 'tabsHTML5'));
+
+        $this->fields['customLinkClass'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Classe pour les liens personnalisés'), 'grade' => 5);
+        $this->fields['permanentLinks'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Liens visibles en permanence'), 'grade' => 3);
+        $this->fields['ignoreLinksTypes'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Ignorer les liens de type'), 'hint' => __('Liste des numéros séparés par des virgules'), 'grade' => 5);
+        $this->fields['linkBlinkTime'] = array('type' => 'float', 'default' => 1.0, 'editable' => true, 'label' => __("Temps d'apparition du lien à l'ouverture de la page (en secondes)"));
+        $this->fields['linkTooltipManager'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("Gestionnaire des info-bulles"), 'grade' => 5);
+        $this->fields['linkTracker'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Tracking des liens'), 'grade' => 5);
+        $this->fields['linkTrackerRegexp'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Tracking des liens applicables aux liens du domaine'), 'grade' => 5);
+        $this->fields['linkFilePrefix'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Préfixer les liens de téléchargement'));
+        $this->fields['linkMultimediaPerformanceMode'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Mode perfomance pour les liens multimédia'), 'grade' => 5);
+        $this->fields['linkMultimediaQuality'] = array('type' => 'float', 'default' => 1.0, 'editable' => true, 'label' => __('Qualité de rendu des animations'), 'grade' => 5);
+        $this->fields['linkCornerSize'] = array('type' => 'integer', 'default' => '10', 'editable' => true, 'label' => __('Taille des liens de coins de page'), 'hint' => __("Pourcentage de la largeur de la page"));
+        $this->fields['linkTooltipMaxWidth'] = array('type' => 'integer', 'default' => '140', 'editable' => true, 'label' => __('Largeur max des infobulles des liens de type "infobulle"'));
+        $this->fields['videoReset'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Réinitialiser les vidéos après la lecture'), 'grade' => 3);
+        $this->fields['videoBigPlay'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Afficher le gros bouton Play'), 'grade' => 3);
+        $this->fields['brightcovePlayerId'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Brightcove Player Id'), 'grade' => 3);
+        $this->fields['brightcovePlayerSecret'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Brightcove Player Secret'), 'grade' => 3);
+        $this->fields['inlineSlideshowTransitionDuration'] = array('type' => 'float', 'default' => 0.75, 'editable' => true, 'label' => __('Durée de la transition des diaporamas intégrés aux pages (s)'));
+        $this->fields['inlineSlideshowDuration'] = array('type' => 'float', 'default' => 7, 'editable' => true, 'label' => __('Temps d\'attente des diaporamas intégrés aux pages (s)'));
+        $this->fields['textPopupStylesheet'] = ['type' => 'freefile', 'default' => '', 'editable' => true, 'label' => __('Feuille de style des popups de texte'), 'fileFilter' => $cssFilter];
+        $this->fields['textPopupWidth'] = ['type' => 'integer', 'default' => '600', 'editable' => true, 'label' => __('Largeur optimale des popups')];
+        $this->fields['iframePopupMaxWidth'] = ['type' => 'integer', 'default' => '0', 'editable' => true, 'label' => __('Largeur maximale des popups iframe')];
+        $this->forms['multimedia'] = array('label' => __('Liens et multimédia'),
+            'fieldsnames' => array('permanentLinks', 'linkBlinkTime', 'customLinkClass', 'ignoreLinksTypes', 'linkTooltipManager', 'linkCornerSize', 'linkTooltipMaxWidth', '|', 'linkTracker', 'linkTrackerRegexp', '|', 'linkFilePrefix', '|', 'linkMultimediaPerformanceMode', 'linkMultimediaQuality', '|', 'inlineSlideshowTransitionDuration', 'inlineSlideshowDuration', '|', 'videoReset', 'videoBigPlay', '|', 'brightcovePlayerId', 'brightcovePlayerSecret', '|', 'textPopupStylesheet', 'textPopupWidth', '|', 'iframePopupMaxWidth'));
+        //.
+
+
+        $this->fields['audiodescriptionTexts'] = ['type' => 'freefile', 'default' => '', 'editable' => true, 'label' => __('Contenus textuels pour l\'audiodescription'), 'fileFilter' => $seoFilter];
+        $this->fields['audiodescriptionVoice'] = ['type' => 'combo', 'datas' => wsDroits::getTTSVoices(), 'editable' => true, 'default' => true, 'label' => __('Voix pour l\'audiodescription')];
+        $this->forms['accessibility'] = ['label' => __('Accessibilité'),
+            'fieldsnames' => ['audiodescriptionTexts', 'audiodescriptionVoice']
+        ];
+
+        //.
+        $this->fields['externalArchives'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
+            'label' => __('Archives'), 'grade' => 3, 'fileFilter' => $imageFilter);
+        $this->fields['externalArchivesBack'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
+            'label' => __('Image de fond'), 'grade' => 3, 'fileFilter' => $imageFilter);
+        $this->fields['archivesLink'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Lien'), 'grade' => 5);
+        $this->fields['archivesLabel'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Label'), 'grade' => 5);
+
+        $this->forms['archives'] = array('label' => __('Archives'),
+            'fieldsnames' => array('externalArchives', 'externalArchivesBack', '|', 'archivesLink', 'archivesLabel'));
+        // .
+        $this->fields['form'] = array('type' => 'combo', 'default' => '', 'editable' => true, 'grade' => 5, 'label' => __('Formulaire'), 'datas' =>
+            array(__('Aucun') => '',
+                'Bulle Groupe' => 'bulle',
+                'Bourbon / Suggestions' => 'bourbon',
+                'Avery' => 'avery',
+            ),
+        );
+        $this->forms['form'] = array('label' => __('Formulaire'),
+            'fieldsnames' => array('form'));
+
+        $this->fields['cookieConsent'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Message cookie'));
+        $this->fields['cookieConsentMessage'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Texte du consentement'));
+        $this->fields['cookieConsentAutoclose'] = array('type' => 'integer', 'default' => '0', 'editable' => true, 'label' => __('Masquer automatiquement après x secondes'));
+        $this->forms['privacy'] = array('label' => __('Respect de la vie privée'),
+            'fieldsnames' => array('cookieConsent', 'cookieConsentMessage', 'cookieConsentAutoclose'));
+
+        //.
+        $this->fields['basket'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Panier activé'), 'grade' => 5);
+        $this->fields['basketManager'] = array('type' => 'combo', 'default' => 'classic', 'editable' => true, 'label' => __("Manager de panier"),
+            'datas' => array(__('Classic') => 'com.fluidbook.player.basket.BasketManager',
+                'Grdf' => 'com.fluidbook.player.basket.custom.grdf.GrdfBasketManager',
+                'Grdf 2013' => 'com.fluidbook.player.basket.custom.grdf.grdf2013.GrdfBasketManager2013',
+                'Grdf 2015' => 'com.fluidbook.player.basket.custom.grdf.grdf2015.GrdfBasketManager2015',
+                'Essilor' => 'com.fluidbook.player.basket.custom.essilor.EssilorBasketManager',
+                'Essilor Recap' => 'com.fluidbook.player.basket.custom.essilorrecap.EssilorRecapBasketManager',
+                'Wesco Ventes' => 'com.fluidbook.player.basket.custom.wesco.WescoBasketManager',
+                'Atlantic Download' => 'com.fluidbook.player.basket.custom.atlantic.AtlanticDownloadBasketManager',
+                'Remarkable' => 'Remarkable'
+            ), 'grade' => 5);
+        $this->fields['basketReferences'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
+            'label' => __('Références produits'), 'grade' => 3, 'fileFilter' => $basketFilter, 'hint' => __('Fichier contenant les références produits'), 'dir' => 'commerce');
+        $this->fields['basketImages'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
+            'label' => __('Images des produits'), 'grade' => 5, 'fileFilter' => $imageFilter, 'hint' => __('Chaque image doit avoir pour nom exact la référence du produit'),
+            'multiple' => true, 'dir' => 'commerce');
+        $this->fields['basketPDFBackground'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
+            'label' => __('Fond du PDF (bon de commande)'), 'grade' => 5, 'fileFilter' => $epsFilter, 'hint' => __('Fond du bon de commande'), 'dir' => 'commerce');
+
+        $this->forms['basket'] = array('label' => __('Panier'),
+            'fieldsnames' => array('basket', 'basketManager', 'basketReferences', 'basketImages', 'basketPDFBackground'));
+        // .
+        $this->fields['offlineLink'] = array('type' => 'text', 'default' => 'http://', 'editable' => true, 'label' => __("URL du Fluidbook"), 'hint' => __('URL du fluidbook utilisée pour la version Offline (CD-ROM, clé USB, Exécutables)'));
+        $this->fields['offlineTitle'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("Titre de l'application"));
+        $this->fields['offlineEnableAdvancedPrinting'] = ['type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Activer le menu d\'impression avancée')];
+        $this->forms['offline'] = array('label' => __('Version offline'),
+            'fieldsnames' => array('offlineTitle', 'offlineLink', '|', 'offlineEnableAdvancedPrinting'));
+
+        $this->fields['alwaysHTML5'] = array('type' => 'boolean', 'default' => 'false', 'editable' => true, 'label' => __('Toujours utiliser la version HTML5'), 'grade' => 1);
+
+        $this->fields['html5priority'] = array('type' => 'combo', 'default' => 'true', 'editable' => true, 'label' => __("Rediriger vers la version HTML5"), 'grade' => 1,
+            'datas' => array(__('Si l\'utilisateur a un appareil tactile') => 'false',
+                __('Si flash n\'est pas installé') => 'notinstalled',
+                __("Si flash n'est pas pas installé ou bloqué") => 'true'));
+
+        $this->fields['flashBlockedWait'] = array('type' => 'float', 'default' => 1.5, 'editable' => true, 'label' => __("Temps d'attente avant de considérer flash comme bloqué"));
+
+
+        $this->fields['navOrderH'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Ordre des icônes dans la nav') . ' (' . __('Si différente') . ')', 'grade' => 3);
+
+        $this->fields['menuBreakpoint'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Breakpoint burger menu'), 'hint' => 'Par défaut 1023px', 'grade' => 3);
+
+
+        $this->fields['mobileNavigationType'] = array('type' => 'combo', 'default' => 'book', 'editable' => true, 'label' => __('Mode de navigation'), 'grade' => 5,
+            'datas' => array(__('Normal (automatique)') => 'book',
+                __('Normal (double page)') => 'landscape',
+                __('Normal (une page)') => 'portrait',
+                __('Magazine tablette') => 'tab')
+        );
+        $this->fields['rasterizePages'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Ecraser les pages'), 'hint' => '1-3,5 = 1,2,3,5', 'grade' => 1);
+        $this->fields['vectorPages'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Conserver les pages en vecteur'), 'hint' => '1-3,5 = 1,2,3,5', 'grade' => 1);
+
+
+        $this->fields['mobileTransitionDuration'] = array('type' => 'float', 'default' => '0.75', 'editable' => true, 'label' => __('Durée de la transition'));
+        $this->fields['mobileLinksRevealAnim'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Animer les liens après un changement de page"), 'grade' => 3);
+
+        $this->fields['mobileIconVector'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Utiliser les icônes vectorielles'));
+        $this->fields['mobileServerConfig'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Inclure les fichiers de configuration serveur'), 'grade' => 3);
+
+        $this->fields['mobilePlugins'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Plugin'), 'grade' => 5);
+
+        $this->fields['mobileVideosPath'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Chemin vers les vidéos'), 'grade' => 5);
+        $this->fields['mobileExtraXSpace'] = array('type' => 'integer', 'default' => '0', 'editable' => true, 'label' => __('Marge supplémentaire horizontale'), 'grade' => 3);
+        $this->fields['mobileNavScale'] = array('type' => 'integer', 'default' => '100', 'editable' => true, 'label' => __('Taille du menu (en %)'), 'grade' => 3);
+
+        $this->fields['mobileIgnoreBackgroundLinks'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Ignorer les liens de background'));
+
+        $this->forms['mobile'] = array('label' => __('Version mobile'),
+            'fieldsnames' => array('alwaysHTML5', 'html5priority', 'flashBlockedWait', 'mobileNavigationType', '|', 'rasterizePages', 'vectorPages', '|', 'mobileNavScale', '|', 'mobileTransitionDuration', "mobileLinksRevealAnim", '|', 'menuBreakpoint', 'navOrderH', '|', 'mobileIconVector', 'mobileServerConfig', 'mobilePlugins', '|', 'mobileVideosPath', '|', 'mobileExtraXSpace', '|', 'mobileIgnoreBackgroundLinks'));
+
+
+        $this->fields['phonegapId'] = array('type' => 'text', 'default' => 'com.fluidbook.phonegap.$id', 'editable' => true, 'label' => __("Identifiant de l'identifiant"), 'grade' => 5, 'hint' => __('De la forme') . ' com.fluidbook.phonegap.xxxxx');
+        $this->fields['phonegapVersion'] = array('type' => 'text', 'default' => '1.0.0', 'editable' => true, 'label' => __("Version de l'application"), 'grade' => 5, 'hint' => __('De la forme') . ' 1.2.3');
+        $this->fields['phonegapPlugins'] = array('type' => 'textarea', 'default' => 'ChildBrowser', 'editable' => true, 'label' => __('Plugins Phonegap'), 'grade' => 5);
+        $defaultScreenshots = "P,0\nL,2\nL,index";
+        $this->fields['appScreenshots'] = array('type' => 'textarea', 'default' => $defaultScreenshots, 'editable' => true, 'label' => 'Générer les screenshots', 'grade' => 5, 'hint' => __('Une ligne par vue à générer de la forme X,Y (X : P(ortrait) ou L(andscape), Y : numéro de page ou vue (1, index))'));
+
+        $this->forms['phonegap'] = array('label' => __('Applications mobile'),
+            'fieldsnames' => array('phonegapId', 'phonegapVersion', 'phonegapPlugins', 'appScreenshots'));
+
+        $this->fields['secureURL'] = array('type' => 'text', 'default' => 'http://', 'editable' => true, 'label' => __('URL de sécurisation'), 'grade' => 5, 'hint' => __('URL intérrogé pour vérifier si le visiteur à les droits pour consulter la publication'));
+        $this->fields['secureURLRedirect'] = array('type' => 'text', 'default' => 'http://', 'editable' => true, 'label' => __('Redirection'), 'grade' => 5, 'hint' => __("Si l'authentification échoue, redirection vers cette adresse"));
+        $this->fields['preventRightClick'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Essayer d'empêcher le clic droit"), 'grade' => 1);
+        $this->forms['secure'] = array('label' => __('Sécurisation'),
+            'fieldsnames' => array('secureURL', 'secureURLRedirect', '|', 'preventRightClick'));
+
+        $this->fields['home'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("Accueil de l'interface multibrochure"), 'grade' => 5);
+        $this->fields['multilang'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Langues'), 'hint' => __('Code langue') . ',' . __('Code pays') . ',' . __('URL'));
+        $this->fields['country'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Pays de la brochure'));
+        $this->fields['multilangDisplay'] = array('type' => 'combo', 'default' => 'lang', 'editable' => true, 'label' => __('Affichage'),
+            'datas' => array(__('Langue') => 'lang',
+                __('Langue') . ' (' . __('Pays') . ')' => 'lang_country',
+                __('Pays') . ' (' . __('Langue') . ')' => 'country_lang'));
+        $this->forms['multibrochure'] = array('label' => __('Multibrochure'),
+            'fieldsnames' => array('home', 'country', 'multilangDisplay', 'multilang'));
+
+        $this->fields['plv'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Activer le mode PLV'), 'grade' => 3);
+        $this->fields['plvTimer'] = array('type' => 'integer', 'min' => 1, 'max' => 60, 'default' => 5, 'editable' => true, 'label' => __('Temps'), 'grade' => 3);
+        $this->fields['plvMode'] = array('type' => 'combo', 'default' => 'first', 'editable' => true, 'label' => __('Arrivé à la dernière page'), 'grade' => 3,
+            'datas' => array(__('Remonter vers la première page') => 'back',
+                __('Recommencer à la première page') => 'first'));
+        $this->forms['plv'] = array('label' => __('Mode PLV'),
+            'fieldsnames' => array('plv', 'plvTimer', 'plvMode'));
+
+        $this->fields['widget'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Générer le widget'), 'grade' => 3);
+        $this->fields['widgetCover'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Afficher la couverture') . ')', 'grade' => 3);
+        $this->fields['widgetSize'] = array('type' => 'integer', 'default' => 200, 'editable' => true, 'label' => __('Optimiser pour une hauteur de (en pixels)'), 'grade' => 3);
+        $this->fields['widgetQuality'] = array('type' => 'integer', 'default' => 85, 'min' => 0, 'max' => 100, 'editable' => true, 'label' => __('Qualité JPEG'), 'grade' => 3);
+        $this->fields['widgetStart'] = array('type' => 'integer', 'default' => 1, 'editable' => true, 'label' => __('Page de début'), 'grade' => 3);
+        $this->fields['widgetEnd'] = array('type' => 'integer', 'default' => 8, 'editable' => true, 'label' => __('Page de fin'), 'grade' => 3);
+        $this->forms['widget'] = array('label' => __('Widget') . ' (' . __('Mini Fluidbook') . ')',
+            'fieldsnames' => array('widget', 'widgetCover', 'widgetSize', 'widgetQuality', 'widgetStart', 'widgetEnd'));
+
+        $this->fields['extras'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Extras'), 'grade' => 3);
+        $this->fields['v1SWF'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
+            'label' => __('Index.swf spécifique'), 'grade' => 5, 'fileFilter' => $swfFilter);
+        $this->forms['v1'] = array('label' => __('Options spécifiques au fluidbook version 1'),
+            'fieldsnames' => array('extras', 'v1SWF'));
+
+        $this->fields['themeEnableAfterSearch'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Afficher l'image supplémentaire à droite du moteur de recherche"), 'grade' => 3);
+        $this->forms['theme'] = array('label' => __('Options du thème'),
+            'fieldsnames' => array('themeEnableAfterSearch'));
+
+        $this->fields['forceCompileOnDownload'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Forcer la compilation lors du téléchargement'), 'grade' => 3);
+        $this->fields['htmlExtension'] = array('type' => 'text', 'default' => 'html', 'editable' => true, 'label' => __('Extension des fichiers html'), 'grade' => 5, 'hint' => __('Ex : php, htm, html, phtml, asp'), 'grade' => 5);
+        $this->fields['htmlPrepend'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Code à insérer en tête des fichiers'), 'grade' => 5);
+        $this->fields['baseUrl'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Base de l\'url'), 'grade' => 5, 'grade' => 5);
+
+        $this->forms['package'] = array('label' => __('Option d\'export'),
+            'fieldsnames' => array('htmlExtension', 'htmlPrepend', 'baseUrl', 'forceCompileOnDownload'));
+
+        $this->fields['disableDemo'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Désactiver le lien de démo'), 'grade' => 5);
+        $this->fields['redirectDemo'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Rediriger le lien de démo vers'), 'grade' => 5);
+        $this->forms['demo'] = array('label' => __('Lien de démo'),
+            'fieldsnames' => array('disableDemo', 'redirectDemo'));
+
+
+        $this->fields['scorm_enable'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Activer SCORM'), 'grade' => 5);
+        $this->fields['scorm_version'] = array('type' => 'combo', 'default' => '1.2', 'editable' => true, 'label' => __('Version du standard SCORM'), 'grade' => 5,
+            'datas' => array(__('SCORM 1.2') => '1.2',
+                __('SCORM 2004 4th edition') => '2004')
+        );
+        $this->fields['scorm_id'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Identifiant SCORM'), 'grade' => 5);
+        $this->fields['scorm_org'] = array('type' => 'text', 'default' => 'ACME-ORG-1350650111249', 'editable' => true, 'label' => __('Organisation SCORM'), 'grade' => 5);
+        $this->fields['scorm_title'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Titre SCORM'), 'grade' => 5, 'hint' => __('Laisser vide pour utiliser le titre de la publication'));
+        $this->fields['scorm_variables'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Variables SCORM'), 'grade' => 5, 'hint' => __('Laisser vide pour utiliser le titre de la publication'));
+        $this->fields['scorm_score'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Activer le support du score'), 'grade' => 5);
+        $this->fields['scorm_score_min'] = array('type' => 'integer', 'min' => 0, 'max' => 100, 'default' => 50, 'editable' => true, 'label' => __('Score minimal pour marquer le contenu comme réussi'), 'grade' => 5);
+        $this->fields['scorm_quiz_as_questionnaire'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Traiter les quiz comme des questionnaires (toutes les réponses sont considérées comme correctes)'), 'grade' => 5);
+        $this->fields['scorm_quizdata'] = array('type' => 'freefile', 'editable' => true, 'default' => '', 'label' => __('Données de quiz'));
+        $this->fields['scorm_complete_on_exit'] = ['type' => 'boolean', 'default' => false, 'label' => 'Marquer le cours comme "Complete" à la fermeture de la fenêtre', 'editable' => true];
+
+        $this->forms['scorm'] = array('label' => __('SCORM'),
+            'fieldsnames' => array('scorm_enable', 'scorm_version', 'scorm_id', 'scorm_org', 'scorm_title', 'scorm_variables', '|', 'scorm_complete_on_exit', '|', 'scorm_quizdata', 'scorm_score', 'scorm_score_min', 'scorm_quiz_as_questionnaire'));
+
+        $versions = wsUrl::getFluidbookVersions(false);
+        $ignore = ['v1', 'v2', 'phonegap'];
+        $fields = [];
+        foreach ($versions as $k => $version) {
+            if (in_array($k, $ignore)) {
+                continue;
+            }
+            $this->fields['download_' . $k] = ['type' => 'boolean', 'editable' => true, 'default' => false, 'label' => $version['title'], 'grade' => 3];
+            $fields[] = 'download_' . $k;
+        }
+        $this->fields['download_online']['default'] = true;
+
+        $this->forms['downloads'] = array('label' => __('Versions disponibles au téléchargement'),
+            'fieldsnames' => $fields);
+
+    }
 
 }
index c514755a37965c630fcfc3c6070aec67e819569f..20f0ef2549c07c34238baa7530566f0445a878c3 100644 (file)
@@ -205,6 +205,7 @@ class wsPackager
                        $zip->setArg(null, '.');
                        $zip->setManualArg('-x "*/\.*"');
                        $zip->execute();
+                       $zip->debug();
                }
 
                if (!file_exists(WS_FILES . '/packager/download')) {