]> _ Git - cubeextranet.git/commitdiff
wait #3120 @0.5
authorvincent@cubedesigners.com <vincent@cubedesigners.com@f5622870-0f3c-0410-866d-9cb505b7a8ef>
Thu, 21 Nov 2019 16:53:45 +0000 (16:53 +0000)
committervincent@cubedesigners.com <vincent@cubedesigners.com@f5622870-0f3c-0410-866d-9cb505b7a8ef>
Thu, 21 Nov 2019 16:53:45 +0000 (16:53 +0000)
inc/ws/Controlleur/class.ws.maintenance.php
inc/ws/Metier/class.ws.book.parametres.php

index 48a41a42315b1c1be66c6ebacf3da245c03a39db..172ea5a798d4a32f6c04bd60e88c6693618aa74d 100644 (file)
 class wsMaintenance
 {
 
-       public static function in($args)
-       {
-               $args = cubePage::getArgs($args);
-               $f = array_shift($args);
-               $callback = array('wsMaintenance', $f);
-               if (is_callable($callback)) {
-                       return call_user_func($callback, $args);
-               }
-       }
-
-       public static function cleanOriginauxPDF()
-       {
-               global $core;
-               cubePHP::neverStop();
-               $r = $core->con->select('SELECT document_id FROM documents');
-               while ($r->fetch()) {
-                       $root = WS_DOCS . '/' . $r->document_id . '/';
-                       $original = $root . 'original.pdf';
-                       $crop = $root . 'crop.pdf';
-                       if (file_exists($original) && file_exists($crop) && filesize($original) == filesize($crop)) {
-                               `rm $crop`;
-                               `cd $root;ln -s original.pdf crop.pdf`;
-                               echo $root . '<br />';
-                       }
-               }
-       }
-
-       public static function initCompositionVersions($args)
-       {
-               global $core;
-               $dao = new wsDAOBook($core->con);
-
-               $r = $core->con->select('SELECT * FROM books ORDER by book_id');
-               while ($r->fetch()) {
-                       $dao->saveCompositionVersion($r->book_id, $r->composition_update);
-               }
-       }
-
-       public static function setCID()
-       {
-               global $core;
-               $dao = new wsDAOBook($core->con);
-
-               $r = $core->con->select('SELECT book_id FROM books WHERE cid=\'\'');
-               $c = $core->con->openCursor('books');
-               while ($r->fetch()) {
-                       $c->cid = $dao->generateCID();
-                       $c->update('WHERE book_id=\'' . $core->con->escape($r->book_id) . '\'');
-               }
-       }
-
-       public static function compactLinks()
-       {
-               global $core;
-               $r = $core->con->select('SELECT * FROM `document_links_versions` GROUP BY document_id,links,rulers');
-               $keep = array();
-               while ($r->fetch()) {
-                       if (!isset($keep[$r->document_id])) {
-                               $keep[$r->document_id] = array();
-                       }
-                       $keep[$r->document_id][] = $r->update;
-               }
-
-               foreach ($keep as $document_id => $dates) {
-                       $core->con->execute('DELETE FROM document_links_versions WHERE document_id=' . $document_id . ' AND `update` NOT IN(' . implode(',', $dates) . ')');
-               }
-       }
-
-       public static function checkSerializeLinks()
-       {
-               global $core;
-               $r = $core->con->select('SELECT * FROM document_links_versions');
-               while ($r->fetch()) {
-                       if (substr($r->links, 1, 1) == ':') {
-                               $links = unserialize($r->links);
-                               $rulers = unserialize($r->rulers);
-                               $c = $core->con->openCursor('document_links_versions');
-                               $c->rulers = json_encode($rulers);
-                               $c->links = json_encode($links);
-                               $c->update('WHERE document_id=' . $r->document_id . ' AND `update`=' . $r->update);
-                       }
-               }
-       }
-
-       public static function moveLinksToVersionDB()
-       {
-               global $core;
-               $r = $core->con->select('SELECT * FROM document_links');
-               $d = array();
-               while ($r->fetch()) {
-                       if (!isset($d[$r->document_id])) {
-                               $d[$r->document_id] = array();
-                       }
-                       if (!isset($d[$r->document_id][$r->update])) {
-                               $d[$r->document_id][$r->update] = array();
-                       }
-                       if (!isset($d[$r->document_id][$r->update][$r->document_page])) {
-                               $d[$r->document_id][$r->update]['links'][$r->document_page] = json_decode($r->links);
-                               $d[$r->document_id][$r->update]['rulers'][$r->document_page] = json_encode($r->rulers);
-                       }
-               }
-
-               $c = $core->con->openCursor('document_links_versions');
-               foreach ($d as $document_id => $updates) {
-                       $c->document_id = $document_id;
-                       foreach ($updates as $date => $dummy) {
-                               $c->update = $date;
-                               $c->links = json_encode($d[$document_id][$date]['links']);
-                               $c->rulers = json_encode($d[$document_id][$date]['rulers']);
-                               try {
-                                       $c->insert();
-                               } catch (Exception $e) {
-                                       // fb($e);
-                               }
-                       }
-               }
-       }
-
-       public static function importFromOldWS($args)
-       {
-               global $core;
-               // Import des fluidbooks
-               // Donc le dernier importé est le max dont le numéro est inférieur Ã  10000
-               $r = $core->con->select('SELECT MAX(book_id) AS book_id FROM books WHERE book_id<10000');
-               $lastImported = $r->book_id;
-               // On recherche maintenant les fluidbook dans la vieille base
-               $r = $core->con->select('SELECT bid FROM ws.book WHERE bid>' . $lastImported);
-               $oldBooks = array();
-               while ($r->fetch()) {
-                       $oldBooks[] = $r->bid;
-               }
-
-               if (count($oldBooks)) {
-                       self::importLangs($oldBooks);
-                       self::importThemes($oldBooks);
-                       self::importDocs($oldBooks);
-                       self::importBooks($oldBooks);
-               }
-               $core->refreshWSUsersTree();
-       }
-
-       public static function importLangs($oldBooks)
-       {
-               global $core, $allTrads, $trads;
-               // On regarde d'abord les langues que nous avons déjà
-               $r = $core->con->select('SELECT lang_id FROM langues');
-               $already = array();
-               while ($r->fetch()) {
-                       $already[] = $r->lang_id;
-               }
-
-               $toImport = array();
-               $r = $core->con->select('SELECT DISTINCT lang FROM ws.book WHERE bid ' . self::_sqlIn($oldBooks));
-               while ($r->fetch()) {
-                       $idl = self::_getLangCode($r->lang);
-                       if (in_array($idl, $already)) {
-                               continue;
-                       }
-                       if (strlen($idl) > 2) {
-                               continue;
-                       }
-                       $toImport[] = $r->lang;
-               }
-
-               $allTrads = array();
-               $trad = array();
-               $r = $core->con->select('SELECT * FROM ws.lang_trad,ws.lang_ord WHERE lang_trad.idlt=lang_ord.idlt AND idl ' . self::_sqlIn($toImport) . ' ');
-               while ($r->fetch()) {
-                       $idl = self::_getLangCode($r->idl);
-                       if (!isset($trad[$idl])) {
-                               $trad[$idl] = array();
-                       }
-                       $trad[$idl][$r->ord] = $r->text;
-               }
-
-               foreach ($trad as $idl => $t) {
-                       $traductions = wsLang::getTraductionWithId($trad[$idl]);
-                       $allTrads[$idl] = $traductions;
-               }
-
-               if (!count($toImport)) {
-                       return;
-               }
-
-               foreach ($toImport as $idl) {
-                       $idl = self::_getLangCode($idl);
-
-                       $c = $core->con->openCursor('langues');
-                       $c->lang_id = $idl;
-                       $c->charset = 'Latin1';
-                       $c->font = 'Fluidbook.otf';
-                       $c->traductions = json_encode($allTrads[$idl]);
-                       $c->insert();
-               }
-       }
-
-       public static function importThemes($oldBooks)
-       {
-               global $core, $signatures;
-
-               $r = $core->con->select('SELECT tid,sigid FROM ws.theme');
-               while ($r->fetch()) {
-                       $signatures[$r->tid] = $r->sigid;
-               }
-
-               $r = $core->con->select('SELECT MAX(theme_id) AS theme_id FROM themes WHERE theme_id<1000');
-               $lastImported = $r->theme_id;
-               // Import des thèmes
-               $r = $core->con->select('SELECT * FROM ws.theme WHERE tid IN (SELECT tid FROM ws.book WHERE bid ' . self::_sqlIn($oldBooks) . ') AND tid>' . $lastImported);
-               $theme = new wsTheme();
-               while ($r->fetch()) {
-                       $tid = $r->tid;
-
-                       $c = $core->con->openCursor('themes');
-                       $c->theme_id = $r->tid;
-                       $c->proprietaire = self::_getWsUser($r->proprietaire);
-                       $c->date = $r->date;
-                       $c->nom = $r->titre;
-
-                       $parametres = new wsThemeParametres($theme);
-                       $parametres->fromRecord($r);
-                       self::_oldIconesToColor($r->iid, $parametres);
-                       $c->parametres = serialize($parametres);
-                       $c->insert();
-
-                       $dest = WS_THEMES . '/' . $tid . '/';
-                       if (!file_exists($dest)) {
-                               mkdir($dest, 0777, true);
-                       }
-
-                       `/bin/cp -r /home/ws/www/themes/$tid/* $dest`;
-               }
-       }
-
-       public static function importDocs($oldBooks)
-       {
-               global $core;
-               // On cherche maintenant Ã  savoir si l'on doit importer de nouveaux documents associés
-               $oldDocuments = array();
-               $r = $core->con->select('SELECT DISTINCT did FROM ws.book_pages WHERE bid ' . self::_sqlIn($oldBooks) . '');
-               while ($r->fetch()) {
-                       $oldDocuments[] = $r->did;
-               }
-
-               if (!count($oldDocuments)) {
-                       return;
-               }
-
-               $r = $core->con->select('SELECT * FROM ws.document WHERE did ' . self::_sqlIn($oldDocuments) . ' ORDER BY did');
-               while ($r->fetch()) {
-                       $c = $core->con->openCursor('documents');
-                       $c->document_id = $r->did;
-                       $c->pages = $r->pages;
-                       $c->version = 1;
-                       try {
-                               $c->insert();
-                       } catch (Exception $e) {
-                               fb($e);
-                       }
-               }
-       }
-
-       public static function copyLinks($args, $eraseTo = false)
-       {
-               $from = $args[0];
-               $to = $args[1];
-               global $core;
-
-               $dao = new wsDAODocument($core->con);
-
-               $dao->getLinksAndRulers($from, $fromlinks, $fromrulers);
-               if (!$eraseTo) {
-                       $dao->getLinksAndRulers($to, $tolinks, $torulers);
-
-                       $tolinks = array_merge($tolinks, $fromlinks);
-                       $torulers = array_merge($torulers, $fromrulers);
-               } else {
-                       $tolinks = $fromlinks;
-                       $torulers = $fromrulers;
-               }
-
-               $wt = WS_BOOKS . '/working/' . $to;
-               $wf = WS_BOOKS . '/working/' . $from;
-
-               if (file_exists($wf)) {
-                       $wf1 = $wf . '/*';
-                       if (!file_exists($wt)) {
-                               mkdir($wt, 0777, true);
-                       }
-
-                       $cmd = "cp -r $wf1 $wt";
-                       echo `$cmd`;
-               }
-
-               $dao->setLinksAndRulers($to, $tolinks, $torulers, 'Copy links from #' . $from . '  to #' . $to, $core->user->utilisateur_id);
-       }
-
-       public static function importBooks($oldBooks)
-       {
-               global $core, $allTrads, $signatures;
-               // Importe les fluidbooks
-               $r = $core->con->select('SELECT * FROM ws.book WHERE bid ' . self::_sqlIn($oldBooks) . ' ORDER BY bid');
-               if (!$r->count()) {
-                       return;
-               }
-               // .
-               while ($r->fetch()) {
-                       $c = $core->con->openCursor('books');
-                       $c->book_id = $r->bid;
-                       $c->nom = $r->titre;
-                       $c->lang = substr(self::_getLangCode($r->lang), 0, 2);
-                       $c->theme = $r->tid;
-                       if (strlen($r->lang) > 2) {
-                               $c->traductions = json_encode($allTrads[self::_getLangCode($r->lang)]);
-                       } else {
-                               $c->traductions = '';
-                       }
-                       $c->proprietaire = self::_getWsUser($r->uid);
-                       $c->status = $r->status;
-                       $c->date_status = $r->date_status;
-                       $c->hash = $r->code;
-                       $c->compteur_visites = 20;
-                       $c->date = $r->date;
-                       $c->syncv1 = 1;
-                       $c->version = 1;
-                       $parametres = new wsBookParametres(new stdClass());
-                       $parametres->fromRecord($r);
-
-                       $xml = @simplexml_load_string('<extras>' . $r->extras . '</extras>');
-                       if ($xml !== false) {
-                               $parametres->fromXML($xml);
-                       } else {
-
-                       }
-
-                       $n = array();
-                       // Pages sans numéro
-                       $offset = $r->first_page_nr - 1;
-                       for ($i = 0; $i < $offset; $i++) {
-                               $n[] = '';
-                       }
-                       // Pages avec numero
-                       for ($j = 1; $j + $offset <= $r->pages; $j++) {
-                               $n[] = $j;
-                       }
-                       $c->numerotation = implode(',', $n);
-
-                       $parametres->signature = $signatures[$r->tid];
-                       $parametres->title = $r->titre;
-                       $parametres->visualisationMode = '2';
-                       $c->parametres = serialize($parametres);
-                       $c->version = 1;
-                       $c->insert();
-               }
-               // Import des pages
-               $core->con->execute('INSERT INTO book_pages (book_id,book_page,document_id,document_page) SELECT bid,bpid,did,dpid FROM ws.book_pages WHERE bid ' . self::_sqlIn($oldBooks));
-
-               $dao = new wsDAOBook($core->con);
-               foreach ($oldBooks as $book_id) {
-                       $dao->saveCompositionVersion($book_id);
-               }
-       }
-
-       protected static function _oldIconesToColor($iid, &$parametres)
-       {
-               global $oldIconesColors;
-               if (!isset($oldIconesColors)) {
-                       $oldIconesColors = array();
-                       $fp = fopen(dirname(__FILE__) . '/../../../icones.csv', 'rb');
-                       $i = 1;
-                       while ($line = fgetcsv($fp, 1000, ';', '"')) {
-                               $oldIconesColors[$i] = array('color' => trim($line[0]), 'iid' => trim($line[1]));
-                               $i++;
-                       }
-               }
-               $line = $oldIconesColors[$iid];
-               if ($line['iid'] != '') {
-                       $parametres->iconSet = $line['iid'];
-                       $parametres->iconsHMargin = $line['iid'] == 1 ? 20 : 0;
-                       $parametres->menuHeight = 39;
-                       $parametres->colorizeIcons = false;
-                       $parametres->couleurI = 'ffffff';
-               } else {
-                       $parametres->iconSet = 1;
-                       $parametres->colorizeIcons = 1;
-                       $parametres->iconsHMargin = 20;
-                       $parametres->menuHeight = 39;
-                       $parametres->couleurI = $line['color'];
-               }
-       }
-
-       protected static function _getWsUser($oldid)
-       {
-               global $ws2ext;
-               if (!isset($ws2ext)) {
-                       self::_getAllUsers();
-               }
-               if (!isset($ws2ext[$oldid])) {
-                       self::_importOldUser($oldid);
-               }
-               if (!isset($ws2ext[$oldid])) {
-                       $ws2ext[$oldid] = 1;
-               }
-               return $ws2ext[$oldid];
-       }
-
-       protected static function _getAllUsers()
-       {
-               global $core, $entreprises, $entreprise_id, $utilisateurs_entreprises, $utilisateur_id, $ws2ext, $grades, $utilisateurs;
-               $grades = array(0 => 1, 0.4 => 1, '0.4' => 1, 0.5 => 1, '0.5' => 1, 1 => 1, 2 => 2, 3 => 3, 4 => 5);
-               // Contrôle des entreprises déjà dans la base extranet
-               $entreprises = array();
-               $entreprise_id = 0;
-               $r = $core->con->select('SELECT entreprise_id,nom FROM entreprises');
-               while ($r->fetch()) {
-                       $nom = mb_strtolower(trim($r->nom));
-                       $nom = cubeText::str2URL($nom);
-                       $entreprises[$nom] = $r->entreprise_id;
-                       $entreprise_id = max($entreprise_id, $r->entreprise_id);
-               }
-
-               $utilisateurs_entreprises = array();
-               $r = $core->con->select('SELECT entreprise,utilisateur_id FROM utilisateurs');
-               while ($r->fetch()) {
-                       $utilisateurs_entreprises[$r->utilisateur_id] = $r->entreprise;
-               }
-
-               $entreprise_id++;
-               // Obtient les emails des utilisateurs
-               $utilisateur_id = 0;
-               $utilisateurs = array();
-               $r = $core->con->select('SELECT utilisateur_id,email FROM utilisateurs');
-               while ($r->fetch()) {
-                       $utilisateur_id = max($r->utilisateur_id, $utilisateur_id);
-                       $utilisateurs[trim(mb_strtolower($r->email))] = $r->utilisateur_id;
-               }
-               $utilisateur_id++;
-
-               $ws2ext = array();
-               $r = $core->con->select('SELECT ws_id,utilisateur_id,entreprise FROM utilisateurs WHERE ws_id IS NOT NULL');
-               while ($r->fetch()) {
-                       $ws2ext[$r->ws_id] = $r->utilisateur_id;
-               }
-       }
-
-       protected static function _importOldUser($oldid)
-       {
-               global $core, $entreprises, $entreprise_id, $utilisateurs_entreprises, $utilisateur_id, $ws2ext, $grades, $utilisateurs;
-               // Get user from old
-               $r = $core->con->select('SELECT * FROM ws.user WHERE uid=\'' . $core->con->escape($oldid) . '\'');
-               if ($r->extranet != 0) {
-                       $ws2ext[$r->uid] = $r->extranet;
-                       return;
-               }
-               // On s'occupe de l'entreprise
-               $email = trim(mb_strtolower($r->email));
-
-               $rs = trim($r->rs);
-               if ($rs == '') {
-                       $rs = trim($r->prenom . ' ' . $r->nom);
-               }
-               $nom = mb_strtolower($rs);
-
-               $nom = cubeText::str2URL($nom);
-
-               if (isset($utilisateurs[$email])) {
-                       $newid = $utilisateurs[$email];
-                       $e = $utilisateurs_entreprises[$newid];
-                       $update = true;
-               } elseif (isset($entreprises[$nom])) {
-                       $e = $entreprises[$nom];
-                       $update = true;
-               } else {
-                       $c = $core->con->openCursor('entreprises');
-                       $c->entreprise_id = $entreprise_id;
-                       $c->nom = $rs;
-                       $c->adresse = $r->adresse;
-                       $c->code_postal = $r->code_postal;
-                       $c->ville = $r->ville;
-                       $c->pays = $r->pays;
-                       $c->date_creation = $r->date;
-                       $c->ws_grade = $grades[$r->grade];
-                       $c->ws_admin = self::_getWsUser($r->admin);
-                       $c->insert();
-                       $e = $entreprises[$nom] = $entreprise_id;
-                       $entreprise_id++;
-                       $update = false;
-               }
-
-               if ($update) {
-                       $c = $core->con->openCursor('entreprises');
-                       $c->ws_grade = $grades[$r->grade];
-                       $c->ws_admin = self::_getWsUser($r->admin);
-                       $c->update('WHERE entreprise_id=\'' . $e . '\'');
-               }
-               // Puis de l'utilisateur
-               if (isset($utilisateurs[$email])) {
-                       $c = $core->con->openCursor('utilisateurs');
-                       $c->ws_password = $r->password;
-                       $c->ws_id = $r->uid;
-                       $c->update('WHERE utilisateur_id=\'' . $utilisateurs[$email] . '\'');
-                       $ws2ext[$r->uid] = $utilisateurs[$email];
-                       $utilisateurs_entreprises[$utilisateurs[$email]] = $e;
-               } else {
-                       $c = $core->con->openCursor('utilisateurs');
-                       $c->utilisateur_id = $utilisateur_id;
-                       $c->entreprise = $e;
-                       $c->nom = $r->nom;
-                       $c->prenom = $r->prenom;
-                       $c->email = $r->email;
-                       $c->password = $r->password;
-                       $c->adresse = $r->adresse;
-                       $c->code_postal = $r->code_postal;
-                       $c->ville = $r->ville;
-                       $c->pays = $r->pays;
-                       $c->lang = $r->lang;
-                       $c->telephone = $r->telephone;
-                       $c->date_creation = $r->date;
-                       $c->notes = 'Inséré à  l\'import vers le nouveau Fluidbook Workshop';
-                       $c->ws_password = $r->password;
-                       $c->ws_id = $r->uid;
-                       $c->insert();
-                       $ws2ext[$r->uid] = $utilisateur_id;
-                       $utilisateurs_entreprises[$utilisateur_id] = $e;
-                       $utilisateur_id++;
-               }
-       }
-
-       protected static function _sqlIn($tab)
-       {
-               return ' IN(\'' . implode('\',\'', $tab) . '\') ';
-       }
-
-       protected static function _getLangCode($lang)
-       {
-               $lang = strtolower($lang);
-               if ($lang == 'cz') {
-                       $lang = 'cs';
-               }
-               return $lang;
-       }
-
-       public static function dumpDatabase()
-       {
-               cubeDb::mysqlDump(DB_HOST, DB_NAME, DB_USER, DB_PASSWORD, ROOT . '/backups/dump-' . date('Y-m-d-H-i-s') . '.sql', true, 8);
-       }
-
-       public static function cleanPackages()
-       {
-               $limit = TIME - (2 * 3600); // 2 heures avant maintenant*
-               //
-               $dirs = array(
-                       WS_FILES . '/packager/'
-               );
-               // Clean downloads
-
-               foreach ($dirs as $dir) {
-                       if (!file_exists($dir)) {
-                               continue;
-                       }
-                       $dr = opendir($dir);
-                       while ($file = readdir($dr)) {
-                               if ($file == '.' || $file == '..') {
-                                       continue;
-                               }
-                               $f = $dir . $file;
-                               if ($file == 'download') {
-                                       continue;
-                               }
-                               if (!is_dir($f)) {
-                                       continue;
-                               }
-                               if (filemtime($f) > $limit) {
-                                       continue;
-                               }
-                               `rm -rf $f`;
-                       }
-
-                       if (!file_exists($dir)) {
-                               mkdir($dir, 0777, true);
-                       }
-               }
-       }
-
-       public static function cleanConversionSessions()
-       {
-               $limit = TIME - (4 * 3600); // 4 heures avant maintenant*
-
-               $dir = ROOT . '/cache/conversionSessions/';
-               $dr = opendir($dir);
-               while ($file = readdir($dr)) {
-                       if ($file == '.' || $file == '..') {
-                               continue;
-                       }
-                       $f = $dir . $file;
-                       if (filemtime($f) > $limit) {
-                               continue;
-                       }
-                       unlink($f);
-               }
-       }
-
-       public static function cleanUnusedDocs()
-       {
-               global $core;
-               cubePHP::neverStop();
-               $r = $core->con->select('SELECT document_id FROM documents WHERE document_id NOT IN (SELECT document_id FROM book_pages)');
-               while ($r->fetch()) {
-                       if (file_exists(WS_DOCS . '/' . $r->document_id)) {
-                               $rm = new cubeCommandLine('rm');
-                               $rm->setPath(CONVERTER_PATH);
-                               $rm->setArg('r');
-                               $rm->setArg('f');
-                               $rm->setArg(null, WS_DOCS . '/' . $r->document_id . '/');
-                               $rm->execute();
-                               echo $rm->commande . "<br />";
-                       }
-               }
-
-               self::_moveDocs(WS_DOCS, '/data/extranet/www/fluidbook/docs1', 250);
-               self::_moveDocs('/data/extranet/www/fluidbook/docs1', '/data/extranet/www/fluidbook/docs2', 2000);
-               self::_moveDocs('/data/extranet/www/fluidbook/docs2', '/data/extranet/www/fluidbook/docs3', 7000);
-       }
-
-       protected static function _moveDocs($from, $to, $keep, $batch = 250)
-       {
-               $docs = array();
-               $dr = opendir($from);
-               while ($d = readdir($dr)) {
-                       if ($d == '.' || $d == '..') {
-                               continue;
-                       }
-                       $d = intval($d);
-                       if (!$d) {
-                               continue;
-                       }
-                       $docs[] = intval($d);
-               }
-
-               sort($docs);
-               $docs = array_splice($docs, 0, count($docs) - $keep);
-               if (count($docs)) {
-                       $toMove = array_slice($docs, 0, $batch);
-
-                       foreach ($toMove as $d) {
-                               if (trim($d) == '') {
-                                       continue;
-                               }
-                               $source = $from . '/' . $d . '/';
-                               $dest = $to . '/' . $d . '/';
-                               if (!file_exists($dest)) {
-                                       mkdir($dest, 0777, true);
-                               }
-                               $rsync = "rsync -av $source $dest";
-                               $rm = "rm -rf $source";
-                               `$rsync;$rm`;
-                               echo $rsync . "\n";
-                               echo $rm . "\n";
-                       }
-               }
-       }
-
-       public static function moveFluidbookDatas()
-       {
-               $dir = WS_BOOKS . '/final/';
-               $dr = opendir($dir);
-               while ($d = readdir($dr)) {
-                       if ($d == '.' || $d == '..' || !is_dir($dir . $d)) {
-                               continue;
-                       }
-                       rename($dir . $d . '/FluidbookDatas.swf', $dir . $d . '/data/fd.swf');
-                       rename($dir . $d . '/FluidbookDatasLight.swf', $dir . $d . '/data/fdl.swf');
-               }
-       }
-
-       public static function mergeEntreprise($args)
-       {
-               global $core;
-
-               $from = $args[0];
-               $to = $args[1];
-
-               $c = $core->con->openCursor('utilisateurs');
-               $c->entreprise = $to;
-               $c->update('WHERE entreprise=' . $from);
-
-               $core->con->execute('DELETE FROM entreprises WHERE entreprise_id=' . $from);
-
-               $core->refreshWSUsersTree();
-       }
-
-       public static function updateLuceneTime()
-       {
-               global $core;
-               $dao = new wsDAOBook($core->con);
-               $books = $dao->selectLuceneTimeNotSet();
-               foreach ($books as $book) {
-                       $index = WS_BOOKS . '/search/' . $book->book_id;
-                       if (!file_exists($index)) {
-                               fb($book->book_id, 'Skip');
-                               continue;
-                       }
-
-                       $mtime = 0;
-                       $dr = opendir($index);
-                       while ($file = readdir($dr)) {
-                               if ($file == '.' || $file == '..') {
-                                       continue;
-                               }
-                               $mtime = max($mtime, filemtime($index . '/' . $file));
-                       }
-
-                       $c = $core->con->openCursor('books');
-                       $c->lucene_time = $mtime;
-                       $c->update('WHERE book_id=' . $book->book_id);
-
-                       fb($book->book_id, 'Update : ' . $mtime);
-               }
-       }
-
-       public static function makeLuceneIndexes()
-       {
-               global $core;
-
-               cubePHP::neverStop();
-
-               $dao = new wsDAOBook($core->con);
-               $books = $dao->selectLuceneToDo();
-               foreach ($books as $book) {
-                       $pages = $dao->getPagesOfBook($book->book_id);
-                       $dao->indexPDF($book, $pages);
-               }
-       }
-
-       public static function exportSommaire($args)
-       {
-               global $core;
-               $book_id = $args[0];
-               $dao = new wsDAOBook($core->con);
-               $book = $dao->selectById($book_id);
-
-               header('Content-Type: text/plain');
-               foreach ($book->chapters as $c) {
-                       echo str_repeat("\t", $c->level);
-                       echo $c->label;
-                       echo ' ' . $c->page;
-                       echo "\n";
-
-               }
-               exit;
-       }
-
-       public static function copySommaire($args)
-       {
-               global $core;
-               $from = $args[0];
-               $to = $args[1];
-               $dao = new wsDAOBook($core->con);
-               $fbook = $dao->selectById($from);
-               $dao->setChapters($to, json_encode($fbook->chapters));
-       }
-
-       public static function copyComposition($args)
-       {
-               global $core;
-
-               $from = $args[0];
-               $to = $args[1];
-
-               $r = $core->con->select('SELECT * FROM book_pages_versions WHERE book_id=\'' . $core->con->escape($from) . '\' AND composition!=\'a:0:{}\' ORDER BY `update` DESC LIMIT 1');
-               if (!$r->count()) {
-                       return;
-               }
-
-               $comp = unserialize($r->composition);
-
-               $docs = array();
-               foreach ($comp as $book_page => $infos) {
-                       $docs[$infos['document_id']] = true;
-               }
-               foreach ($docs as $doc => $v) {
-                       $r = $core->con->select('SELECT MAX(document_id) AS document_id FROM documents');
-                       $newid = $r->document_id + 1;
-
-                       self::_duplicateLines('documents', 'document_id', $doc, $newid);
-                       self::_duplicateLines('document_links', 'document_id', $doc, $newid);
-                       self::_duplicateLines('document_links_versions', 'document_id', $doc, $newid);
-
-                       $f = wsDocument::getDir($doc);
-                       $t = WS_DOCS . '/' . $newid;
-
-                       `cp -r $f $t`;
-
-                       $docs[$doc] = $newid;
-               }
-
-               $core->con->execute('DELETE FROM book_pages WHERE book_id=\'' . $core->con->escape($to) . '\'');
-
-               $c = $core->con->openCursor('book_pages');
-               $c->book_id = $to;
-               foreach ($comp as $book_page => $infos) {
-                       $c->book_page = $book_page;
-                       $c->document_id = $docs[$infos['document_id']];
-                       $c->document_page = $infos['document_page'];
-                       $c->insert();
-               }
-
-               $daoBook = new wsDAOBook($core->con);
-               $daoBook->saveCompositionVersion($to);
-       }
-
-       protected static function _duplicateLines($table, $key, $currentKey, $newKey)
-       {
-               global $core;
-               $tmptable = 'tmptable_' . $table . '_' . $newKey;
-
-               $core->con->execute('CREATE TEMPORARY TABLE ' . $tmptable . ' SELECT * FROM ' . $table . ' WHERE ' . $key . ' = ' . $currentKey);
-               $core->con->execute('UPDATE ' . $tmptable . ' SET ' . $key . ' =  ' . $newKey);
-               $core->con->execute('INSERT INTO ' . $table . ' SELECT * FROM ' . $tmptable);
-               $core->con->execute('DROP TEMPORARY TABLE IF EXISTS ' . $tmptable);
-       }
-
-       public static function restoreComposition($args)
-       {
-               global $core;
-               $book_id = $args[0];
-               if (isset($args[1])) {
-                       $date = $args[1];
-               } else {
-                       $date = TIME;
-               }
-
-
-               $r = $core->con->select('SELECT * FROM book_pages_versions WHERE book_id=\'' . $core->con->escape($book_id) . '\' AND composition!=\'a:0:{}\' AND `update`<=' . $date . ' ORDER BY `update` DESC LIMIT 1');
-               if (!$r->count()) {
-                       return;
-               }
-
-               $comp = unserialize($r->composition);
-               $core->con->execute('DELETE FROM book_pages WHERE book_id=\'' . $core->con->escape($book_id) . '\'');
-               $c = $core->con->openCursor('book_pages');
-               $c->book_id = $book_id;
-               foreach ($comp as $book_page => $infos) {
-                       $c->book_page = $book_page;
-                       $c->document_id = $infos['document_id'];
-                       $c->document_page = $infos['document_page'];
-                       $c->insert();
-               }
-       }
-
-       public static function getV1Translations()
-       {
-               wsLang::getV1Translations();
-       }
-
-       public static function appendDocument($args)
-       {
-               global $core;
-               $book_id = $args[0];
-               $document_id = $args[1];
-               $dao = new wsDAOBook($core->con);
-               $dao->appendDocument($book_id, $document_id);
-       }
-
-       public static function reprocessVideos($args)
-       {
-               global $core;
-
-               $book_id = $args[0];
-
-               $dir = WS_BOOKS . '/working/' . $book_id;
-
-               $dao = new wsDAODocument($core->con);
-               $dao->getLinksAndRulers($book_id, $links, $rulers);
-
-               foreach ($links as $link) {
-                       if ($link['type'] != 4) {
-                               continue;
-                       }
-
-                       $file = $dir . '/' . $link['to'];
-                       if (!file_exists($file)) {
-                               continue;
-                       }
-
-                       wsTools::encodeWebVideos($file, null, true, true);
-               }
-       }
-
-       public static function syncLDAP()
-       {
-               global $core;
-               cubePHP::neverStop();
-
-               $res = '<pre>';
-
-               $ds = ldap_connect('localhost', 10389);
-               ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
-               ldap_bind($ds, 'uid=admin,ou=system', '*arica*6');
-
-               $r = $core->con->select('SELECT * FROM utilisateurs_entreprise ORDER BY utilisateur_id');
-               while ($r->fetch()) {
-                       if (is_null($r->utilisateur_id)) {
-                               continue;
-                       }
-                       $entree = array();
-                       $entree['objectClass'][] = 'top';
-                       $entree['objectClass'][] = 'person';
-                       $entree['objectClass'][] = 'organizationalPerson';
-                       $entree['objectClass'][] = 'extensibleObject';
-                       $entree['cn'] = trim($r->prenom . ' ' . $r->nom . ' - ' . $r->rs . ' (' . $r->utilisateur_id . ')', ' -');
-                       $entree['sn'] = $r->nom == '' ? $entree['cn'] : $r->nom;
-                       $entree['mail'] = $r->email;
-                       $entree['uid'] = 'extranet_' . $r->utilisateur_id;
-                       $entree['OrganizationalUnitName'] = $r->rs;
-                       if ($r->telephone && $r->telephone != '+33') {
-                               $entree['telephoneNumber'][] = $r->telephone;
-                       }
-                       if ($r->mobile && $r->mobile != '+33') {
-                               $entree['telephoneNumber'][] = $r->mobile;
-                       }
-                       if ($r->fax && $r->fax != '+33') {
-                               $entree['telexNumber'] = $r->fax;
-                       }
-                       $dn = 'uid=' . $entree['uid'] . ',o=cubedesigners';
-                       if (!ldap_add($ds, $dn, $entree)) {
-                               $e = ldap_error($ds);
-                               if ($e == 'Already exists') {
-                                       ldap_modify($ds, $dn, $entree);
-                               } else {
-                                       fb($entree, $e);
-                               }
-                       }
-               }
-               $res = 'test';
-               $res .= '</pre>';
-
-               ldap_close($ds);
-               return $res;
-       }
-
-       public static function createBranch($args)
-       {
-               commonDroits::min(5);
-               $branch = $args[0];
-
-               self::updateHTML5Sources();
-               $playerDir = WS_COMPILE_ASSETS . '/player/';
-               $branchesDir = $playerDir . 'branches/';
-               $git = new CubeIT_CommandLine_Git($branchesDir . 'fluidbook-html5');
-               echo $git->executeCmd('checkout -b ' . $branch);
-               $git = new CubeIT_CommandLine_Git($branchesDir . 'fluidbook-html5');
-               echo $git->executeCmd('push --set-upstream origin ' . $branch);
-               self::updateHTML5Sources();
-               $git = new CubeIT_CommandLine_Git($branchesDir . 'fluidbook-html5');
-               echo $git->executeCmd('checkout master');
-       }
-
-       public static function deleteBranch($args)
-       {
-               commonDroits::min(5);
-               $branch = trim($args[0]);
-               if ($branch == 'master' || !$branch) {
-                       die('même pas en rêve');
-               }
-
-               self::updateHTML5Sources();
-
-               $playerDir = WS_COMPILE_ASSETS . '/player/';
-               $branchesDir = $playerDir . 'branches/';
-               $localDir = $playerDir . 'local/';
-
-               $git = new CubeIT_CommandLine_Git($branchesDir . 'fluidbook-html5');
-               echo $git->executeCmd('push --delete origin ' . $branch);
-
-               `rm -rf $localDir$branch`;
-               `rm -rf $branchesDir$branch`;
-
-               self::updateHTML5Sources();
-       }
-
-       public static function updateHTML5Sources($args = array(), $externals = true)
-       {
-               $playerDir = WS_COMPILE_ASSETS . '/player/';
-               $branchesDir = $playerDir . 'branches/';
-               $localDir = $playerDir . 'local/';
-               echo '<pre>';
-               $git = new CubeIT_CommandLine_Git($branchesDir . 'fluidbook-html5');
-               echo $git->executeCmd('stash save --keep-index');
-               $git = new CubeIT_CommandLine_Git($branchesDir . 'fluidbook-html5');
-               echo $git->executeCmd('stash drop');
-               $git = new CubeIT_CommandLine_Git($branchesDir . 'fluidbook-html5');
-               echo $git->executeCmd('pull --all');
-               $git = new CubeIT_CommandLine_Git($branchesDir . 'fluidbook-html5');
-               echo $git->executeCmd('fetch --all --prune');
-               $git = new CubeIT_CommandLine_Git($branchesDir . 'fluidbook-html5');
-               $b = $git->executeCmd('branch -r');
-               echo $b;
-               $bb = explode("\n", $b);
-               $branches = array();
-               foreach ($bb as $item) {
-                       $item = trim($item);
-                       if ($item == '') {
-                               continue;
-                       }
-                       $e = explode('->', $item);
-                       if (count($e) == 2) {
-                               $item = $e[1];
-                       } else {
-                               $item = $e[0];
-                       }
-                       $e = explode("/", $item);
-                       $branches[trim($e[1])] = true;
-               }
-               $branches = array_keys($branches);
-               foreach ($branches as $b) {
-                       $gitsource = $branchesDir . $b;
-                       $local = $localDir . $b;
-                       echo '<b>' . $b . '</b>' . "\n";
-                       if (!file_exists($branchesDir . $b)) {
-                               $git = new CubeIT_CommandLine_Git($branchesDir);
-                               echo $git->executeCmd('clone -b ' . $b . ' --single-branch git@git.cubedesigners.com:fluidbook-html5.git ' . $b);
-                       }
-                       if (!file_exists($local)) {
-                               mkdir($local, 0777, true);
-                               `cp -r $gitsource/* $local`;
-                               `rm -rf $local/.git`;
-                       }
-                       $git = new CubeIT_CommandLine_Git($branchesDir . $b);
-                       echo $git->executeCmd('reset --hard origin/' . $b);
-                       $git = new CubeIT_CommandLine_Git($branchesDir . $b);
-                       echo $git->executeCmd('pull');
-               }
-
-               echo '</pre>';
-               file_put_contents(WS_CACHE . '/activebranches', json_encode($branches));
-       }
-
-       public static function cleanDownload($args)
-       {
-               $dirs = [ROOT . '/cache/download/', WS_FILES . '/packager/download'];
-               foreach ($dirs as $dir) {
-                       cubeFiles::scanRecursiveDir($dir, $files);
-                       $limit = TIME - 7200;
-                       if (is_array($files)) {
-                               foreach ($files as $f) {
-                                       if (filemtime($f) < $limit) {
-                                               unlink($f);
-                                       }
-                               }
-                       }
-               }
-       }
-
-       public static function deleteOldFilesFromFTP($args)
-       {
-               global $core;
-               cubePHP::neverStop();
-
-               $dao = new commonDAOFichier($core->con);
-               $dao->deleteOldFiles();
-       }
-
-       public static function reencodeVideos($args)
-       {
-               cubePHP::neverStop();
-
-               $book_id = $args[0];
-               $format = $args[1];
-               $dir = WS_BOOKS . '/working/' . $book_id;
-
-               wsLinks::getLinksAndRulers($book_id, $links, $rulers);
-
-               foreach ($links as $link) {
-                       if ($link['type'] != 4) {
-                               continue;
-                       }
-
-                       $file = $dir . '/' . $link['to'];
-                       if (!file_exists($file)) {
-                               continue;
-                       }
-
-                       wsTools::encodeWebVideos($file, null, false, true, $format);
-               }
-       }
-
-       public static function correctAutoBookmarkLinks($args)
-       {
-               global $core;
-               $book_id = $args[0];
-               wsLinks::getLinksAndRulers($book_id, $links, $rulers);
-
-               $newlinks = array();
-               foreach ($links as $link) {
-                       $link['left'] -= 1;
-                       $link['top'] += 1;
-                       $link['width'] += 5;
-                       $link['height'] += 3;
-                       $newlinks[] = $link;
-               }
-
-               $dao = new wsDAODocument($core->con);
-               $dao->setLinksAndRulers($book_id, json_encode($newlinks), json_encode($rulers), 'Autobookmark links correction', $core->user->utilisateur_id);
-       }
-
-       public static function compress()
-       {
-               `gzip /home/extranet/www/fluidbook/docs/*/p*.csv`;
-               `gzip /home/extranet/www/fluidbook/docs/*/*.txt`;
-       }
-
-       public static function restoreChapters($args)
-       {
-               global $core;
-
-               $book_id = $args[0];
-               $r = $core->con->select('SELECT chapters FROM books_chapters_versions WHERE book_id=\'' . $core->con->escape($book_id) . '\' ORDER BY `time` DESC LIMIT 1');
-               while ($r->fetch()) {
-                       $c = $core->con->openCursor('books');
-                       $c->chapters = $r->chapters;
-                       $c->changedate = TIME;
-                       $c->update('WHERE book_id=\'' . $core->con->escape($book_id) . '\'');
-                       break;
-               }
-               echo $r->chapters;
-       }
-
-       public static function offsetLinksPos($args)
-       {
-               global $core;
-               $book_id = $args[0];
-               $direction = $args[1];
-               $value = intval($args[2]);
-               wsLinks::getLinksAndRulers($book_id, $links, $rulers);
-
-               if ($direction == 'y') {
-                       $k = 'top';
-               } elseif ($direction == 'x') {
-                       $k = 'left';
-               } else {
-                       return;
-               }
-               if (!$value) {
-                       return;
-               }
-               $newlinks = array();
-               foreach ($links as $link) {
-                       $link[$k] += $value;
-                       $newlinks[] = $link;
-               }
-
-               $dao = new wsDAODocument($core->con);
-               $dao->setLinksAndRulers($book_id, json_encode($newlinks), json_encode($rulers), 'Offset links positions (' . $direction . ' :: ' . $value . ')', $core->user->utilisateur_id);
-       }
-
-       public static function duplicateBook($args)
-       {
-               global $core;
-
-               commonDroits::min(5);
-
-               $book_id = $args[0];
-               $times = isset($args[1]) ? $args[1] : 1;
-               $dao = new wsDAOBook($core->con);
-
-               for ($i = 0; $i < $times; $i++) {
-                       $newbook = $dao->duplicate($book_id, $core->user->utilisateur_id, null, true, true);
-                       $new_id = $newbook->book_id;
-                       self::copyComposition([$book_id, $new_id]);
-                       self::copyLinks([$book_id, $new_id], true);
-               }
-       }
-
-       public static function extractTexts($args)
-       {
-               global $core;
-               $book_id = $args[0];
-               $dao = new wsDAOBook($core->con);
-               $book = $dao->selectById($book_id);
-               $pages = $dao->getPagesOfBook($book_id);
-
-               $docs = array();
-               foreach ($pages as $p) {
-                       $docs[] = $p['document_id'];
-               }
-               $docs = array_unique($docs);
-
-               foreach ($docs as $doc) {
-                       $out = WS_DOCS . '/' . $doc . '/';
-
-                       $fwstk = new cubeCommandLine('fwstk.sh');
-                       $fwstk->setPath(CONVERTER_PATH);
-                       $fwstk->setArg('--input ' . $out . '/crop.pdf');
-                       $fwstk->setArg('--extractTexts ' . $out . '%s%d.txt');
-                       $fwstk->setArg('--extractTextsMethod ' . $book->parametres->textExtraction);
-                       if ($book->parametres->ignoreSearchSeparators != '') {
-                               $fwstk->setArg('--ignoreSeparators ' . $book->parametres->ignoreSearchSeparators);
-                       }
-                       $fwstk->setArg('--threads 1');
-                       $fwstk->execute();
-
-                       $res = $fwstk->commande . "\n\n";
-                       $res .= $fwstk->output;
-               }
-
-               $dir = WS_BOOKS . '/index/' . $book->book_id;
-               if ($book->parametres->ignoreSearchSeparators != '') {
-                       $dir .= '/' . sha1($book->parametres->ignoreSearchSeparators);
-               }
-
-               $prefixes = array('', 'p');
-               foreach ($prefixes as $prefix) {
-                       $ifilec = $dir . '/' . $prefix . 'index.json';
-                       $tfilec = $dir . '/' . $prefix . 'textes.json';
-
-                       $files = array($ifilec, $tfilec);
-
-                       foreach ($files as $f) {
-                               CubeIT_Util_Gzip::unlink($f . '.gz');
-                       }
-               }
-
-               $i = WS_BOOKS . '/index/' . $book_id . '/*';
-               `rm -rf $i`;
-               ob_end_clean();
-               die('<pre>' . $res . '</pre>');
-       }
-
-       public static function _reencodeVideos($book_id, $format)
-       {
-               wsLinks::getLinksAndRulers($book_id, $links, $rulers);
-               foreach ($links as $l) {
-                       if ($l['type'] == 10) {
-                               $to = $l['to'];
-                               fb($to);
-                       }
-               }
-       }
-
-       public static function kadreoDevis8524147851()
-       {
-               global $core;
-
-               $xls = new PHPExcel();
-
-               $cols = ['demande_id' => '#', 'date' => 'Date', 'prenom' => 'Prénom', 'nom' => 'Nom', 'rs' => 'Entreprise', 'email' => 'E-mail',
-                       'telephone' => 'Téléphone', 'pays' => 'Pays', 'code_postal' => 'Code postal', 'details' => 'Détails'];
-
-
-               $r = $core->con->select('SELECT * FROM demandes LEFT JOIN utilisateurs_entreprise ON demandes.utilisateur=utilisateurs_entreprise.utilisateur_id WHERE revendeur=94 AND status=2 ORDER BY date DESC');
-               $s = $xls->getActiveSheet();
-               $s->setTitle('Demandes');
-
-               $i = 0;
-               foreach ($cols as $c => $col) {
-                       $s->getColumnDimensionByColumn($i)->setAutoSize(true);
-                       $s->setCellValueByColumnAndRow($i, 1, $col);
-                       $i++;
-               }
-
-               $j = 2;
-               while ($r->fetch()) {
-                       $i = 0;
-                       foreach ($cols as $c => $col) {
-                               $v = $r->{$c};
-                               if ($c == 'telephone') {
-                                       $v = $v . ' ';
-                               }
-                               if ($c == 'date') {
-                                       $v = date('Y-m-d H:i:s', $v);
-                               }
-
-
-                               $s->setCellValueByColumnAndRow($i, $j, $v);
-                               $style = $s->getCellByColumnAndRow($i, $j)->getStyle();
-                               $style->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_LEFT)
-                                       ->setVertical(PHPExcel_Style_Alignment::VERTICAL_TOP)
-                                       ->setWrapText(true);
-                               $i++;
-                       }
-                       $j++;
-               }
-
-
-               $xls->setActiveSheetIndex(0);
-
-               ob_end_clean();
-               files::registerMimeTypes(array('xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'));
-               cubeHTTP::forceDownload('Kadreo_demandes_Fluidbook-com.xlsx', false);
-
-               $writer = new PHPExcel_Writer_Excel2007($xls);
-               $writer->save('php://output');
-               exit;
-       }
-
-       public static function syncKadreoMailchimp()
-       {
-               global $core;
-
-               set_time_limit(0);
-
-
-               $u = array();
-
-               $r = $core->con->select('SELECT * FROM utilisateurs');
-               while ($r->fetch()) {
-                       $u[$r->utilisateur_id] = $r->row();
-               }
-
-               $r = $core->con->select("SELECT * FROM entreprises_ws WHERE revendeur='Kadreo' AND ws_grade<=4 AND ws_grade>0");
-               while ($r->fetch()) {
-                       $e[$r->entreprise_id] = array('COUNTRY' => $r->pays, 'CONTACT' => date('m/d/Y', $r->date_creation), 'COMPANY' => $r->nom);
-               }
-
-               $batch = array();
-               foreach ($u as $user) {
-                       if (!isset($e[$user['entreprise']])) {
-                               continue;
-                       }
-                       if (stristr($user['email'], 'extranet.cubedesigners.com')) {
-                               continue;
-                       }
-
-                       $batch[] = array_merge($e[$user['entreprise']], array('email' => $user['email'], 'LOCALE' => $user['lang'], 'FNAME' => $user['prenom'], 'LNAME' => $user['nom']));
-               }
-
-               $api = new CubeIT_Services_Mailchimp('2b255293f3595181dd7d079d29dc6b99-us14');
-               $res = $api->batchSubscribe('8ff710b78e', $batch);
-               echo '<pre>OK</pre>';
-       }
-
-
-       public static function syncCubedesignersMailchimp()
-       {
-               global $core;
-
-               set_time_limit(0);
-               $api = new CubeIT_Services_Mailchimp('2abe038d70806d50b23b7a37aa2f6067-us12');
-
-               $u = array();
-
-               $r = $core->con->select('SELECT * FROM utilisateurs');
-               $unsubscribe = array();
-               while ($r->fetch()) {
-                       $u[$r->utilisateur_id] = $r->row();
-                       $unsubscribe[$r->email] = true;
-               }
-
-               $r = $core->con->select("SELECT * FROM entreprises_ws WHERE revendeur='Cubedesigners' AND ws_grade<=4 AND ws_grade>0");
-               while ($r->fetch()) {
-                       $e[$r->entreprise_id] = array('lastdate' => 0, 'COUNTRY' => $r->pays, 'CONTACT' => date('m/d/Y', $r->date_creation), 'LASTACTION' => date('m/d/Y', $r->date_creation), 'COMPANY' => $r->nom, 'RESSELER' => ($r->ws_grade > 2) ? 1 : 0, 'FLUIDBOOKS' => 0, 'TURNOVER' => 0);
-               }
-
-               $r = $core->con->select("SELECT * FROM entreprises_vue");
-               while ($r->fetch()) {
-                       if ($r->ca && isset($e[$r->entreprise_id])) {
-                               $e[$r->entreprise_id]['TURNOVER'] = $r->ca;
-                       }
-               }
-
-               $rr = $core->con->select('SELECT COUNT(*) AS nb,MAX(`date`) AS lastdate,facturable_id FROM books_vue WHERE status >= 0 GROUP BY facturable_id');
-               while ($rr->fetch()) {
-                       $eid = $u[$rr->facturable_id]['entreprise'];
-                       if (isset($e[$eid])) {
-                               $e[$eid]['FLUIDBOOKS'] += $rr->nb;
-                               $e[$eid]['lastdate'] = max($e[$eid]['lastdate'], $rr->lastdate);
-                               $e[$eid]['LASTACTION'] = date('m/d/Y', $rr->lastdate);
-                       }
-               }
-
-               $batch = array();
-               foreach ($u as $user) {
-                       if (!isset($e[$user['entreprise']])) {
-                               continue;
-                       }
-                       if (stristr($user['email'], 'extranet.cubedesigners.com')) {
-                               continue;
-                       }
-
-                       $eu = $e[$user['entreprise']];
-                       if (isset($eu['lastdate'])) {
-                               unset($eu['lastdate']);
-                       }
-
-                       unset($unsubscribe[$user['email']]);
-
-                       $batch[] = array_merge($eu, array('email' => $user['email'], 'LOCALE' => $user['lang'], 'FNAME' => $user['prenom'], 'LNAME' => $user['nom'], 'language' => $user['lang']));
-               }
-
-               $res = $api->batchSubscribe('69f69a2bb8', $batch);
-               $runs = $api->batchUnsubscribe('69f69a2bb8', array_keys($unsubscribe));
-               echo '<pre>' . print_r($runs, true) . '</pre>';
-       }
-
-       public static function resetPlayerVersion()
-       {
-               global $core;
-               $dev = [10000, 10003, 1540, 15571, 15837];
-               $r = $core->con->select('SELECT book_id, parametres FROM books WHERE book_id NOT IN(' . implode(',', $dev) . ')');
-               $reset = [];
-               $error = [];
-               $skip = [];
-               while ($r->fetch()) {
-                       /** @var wsBookParametres $parametres */
-                       try {
-                               $parametres = unserialize($r->parametres);
-                               if ($parametres->mobileLVersion == 'stable') {
-                                       $skip[] = $r->book_id;
-                                       continue;
-                               }
-                               $parametres->mobileLVersion = 'stable';
-                               $c = $core->con->openCursor('books');
-                               $c->parametres = serialize($parametres);
-                               $c->changedate = TIME;
-                               $c->update('WHERE book_id=' . $r->book_id);
-                               $reset[] = $r->book_id;
-                               //break;
-                       } catch (Exception $e) {
-                               $error[] = $r->book_id;
-                       }
-               }
-
-               echo 'reset : ' . implode(', ', $reset) . '<br />';
-               echo 'skip : ' . implode(', ', $skip) . '<br />';
-               echo 'error : ' . implode(', ', $error) . '<br />';
-       }
-
-
-       public static function getSVGPage($args)
-       {
-
-               global $core;
-               $fluidbook = $args[0];
-               $page = $args[1];
-               $dao = new wsDAOBook($core->con);
-               $pages = $dao->getPagesOfBook($fluidbook);
-               $p = $pages[$page];
-               ob_clean();
-               header('Content-type: image/svg+xml');
-               $svg = wsDocument::getDir($p['document_id']) . '/html/p' . $p['document_page'] . '.svg';
-
-               $pdftocairo = new cubeCommandLine('pdftocairo');
-               $pdftocairo->setPath(CONVERTER_PATH);
-               $pdftocairo->setArg('f', $p['document_page']);
-               $pdftocairo->setArg('l', $p['document_page']);
-               $pdftocairo->setArg(null, '-svg');
-               //$pdftocairo->setArg(null, '-cropbox');
-               $pdftocairo->setArg(null, wsDocument::getDir($p['document_id']) . 'crop.pdf');
-               $pdftocairo->setArg(null, $svg);
-               $pdftocairo->execute();
-
-               wsDocument::cleanSVG($svg);
-
-               echo file_get_contents(wsDocument::getDir($p['document_id']) . '/html/p' . $p['document_page'] . '.svg');
-               exit;
-       }
-
-       public static function testSVG($args)
-       {
-               global $core;
-
-               $book = $args[0];
-               $page = $args[1];
-
-               $dao = new wsDAOBook($core->con);
-               $pages = $dao->getPagesOfBook($book);
-               $p = $pages[$page];
-
-               $dir = wsDocument::getDir($p['document_id']);
-               $test = $dir . '/html/zz%s.svg';
-               wsTools::optimizeSVG($dir . '/html/fp' . $p['document_page'] . '.svg', $test, [150, 300], true);
-       }
-
-       public static function svgToFlash()
-       {
-               $iconSets = array(15);
-               $names = array('nav-share' => 'nav-friend',
-                       'nav-bookmarks' => 'nav-bookmark',
-                       'nav-chapters' => 'nav-sommaire',
-                       'nav-download' => 'nav-save',
-                       'nav-fullscreen' => 'nav-fullscreen',
-                       'nav-fullscreen-exit' => 'nav-normalscreen',
-                       'nav-sound-off' => 'nav-soundoff',
-                       'nav-sound-on' => 'nav-soundon',
-               );
-
-
-               foreach ($iconSets as $iconSet) {
-                       $dom = new DOMDocument();
-                       $svgFile = WS_ICONS . '/' . $iconSet . '/interface.svg';
-                       if (!$dom->loadXML(file_get_contents($svgFile))) {
-                               die('Error loading xml : ' . $svgFile);
-                       }
-
-                       $symbols = $dom->getElementsByTagName('symbol');
-
-                       foreach ($symbols as $symbol) {
-                               /* @var $symbol DOMElement */
-                               $id = $symbol->getAttribute('id');
-                               list($x, $y, $width, $height) = explode(' ', $symbol->getAttribute('viewBox'));
-
-                               $svg = '<?xml version="1.0" encoding="utf-8"?>
+    public static function in($args)
+    {
+        $args = cubePage::getArgs($args);
+        $f = array_shift($args);
+        $callback = array('wsMaintenance', $f);
+        if (is_callable($callback)) {
+            return call_user_func($callback, $args);
+        }
+    }
+
+    public static function cleanOriginauxPDF()
+    {
+        global $core;
+        cubePHP::neverStop();
+        $r = $core->con->select('SELECT document_id FROM documents');
+        while ($r->fetch()) {
+            $root = WS_DOCS . '/' . $r->document_id . '/';
+            $original = $root . 'original.pdf';
+            $crop = $root . 'crop.pdf';
+            if (file_exists($original) && file_exists($crop) && filesize($original) == filesize($crop)) {
+                `rm $crop`;
+                `cd $root;ln -s original.pdf crop.pdf`;
+                echo $root . '<br />';
+            }
+        }
+    }
+
+    public static function initCompositionVersions($args)
+    {
+        global $core;
+        $dao = new wsDAOBook($core->con);
+
+        $r = $core->con->select('SELECT * FROM books ORDER by book_id');
+        while ($r->fetch()) {
+            $dao->saveCompositionVersion($r->book_id, $r->composition_update);
+        }
+    }
+
+    public static function setCID()
+    {
+        global $core;
+        $dao = new wsDAOBook($core->con);
+
+        $r = $core->con->select('SELECT book_id FROM books WHERE cid=\'\'');
+        $c = $core->con->openCursor('books');
+        while ($r->fetch()) {
+            $c->cid = $dao->generateCID();
+            $c->update('WHERE book_id=\'' . $core->con->escape($r->book_id) . '\'');
+        }
+    }
+
+    public static function compactLinks()
+    {
+        global $core;
+        $r = $core->con->select('SELECT * FROM `document_links_versions` GROUP BY document_id,links,rulers');
+        $keep = array();
+        while ($r->fetch()) {
+            if (!isset($keep[$r->document_id])) {
+                $keep[$r->document_id] = array();
+            }
+            $keep[$r->document_id][] = $r->update;
+        }
+
+        foreach ($keep as $document_id => $dates) {
+            $core->con->execute('DELETE FROM document_links_versions WHERE document_id=' . $document_id . ' AND `update` NOT IN(' . implode(',', $dates) . ')');
+        }
+    }
+
+    public static function checkSerializeLinks()
+    {
+        global $core;
+        $r = $core->con->select('SELECT * FROM document_links_versions');
+        while ($r->fetch()) {
+            if (substr($r->links, 1, 1) == ':') {
+                $links = unserialize($r->links);
+                $rulers = unserialize($r->rulers);
+                $c = $core->con->openCursor('document_links_versions');
+                $c->rulers = json_encode($rulers);
+                $c->links = json_encode($links);
+                $c->update('WHERE document_id=' . $r->document_id . ' AND `update`=' . $r->update);
+            }
+        }
+    }
+
+    public static function moveLinksToVersionDB()
+    {
+        global $core;
+        $r = $core->con->select('SELECT * FROM document_links');
+        $d = array();
+        while ($r->fetch()) {
+            if (!isset($d[$r->document_id])) {
+                $d[$r->document_id] = array();
+            }
+            if (!isset($d[$r->document_id][$r->update])) {
+                $d[$r->document_id][$r->update] = array();
+            }
+            if (!isset($d[$r->document_id][$r->update][$r->document_page])) {
+                $d[$r->document_id][$r->update]['links'][$r->document_page] = json_decode($r->links);
+                $d[$r->document_id][$r->update]['rulers'][$r->document_page] = json_encode($r->rulers);
+            }
+        }
+
+        $c = $core->con->openCursor('document_links_versions');
+        foreach ($d as $document_id => $updates) {
+            $c->document_id = $document_id;
+            foreach ($updates as $date => $dummy) {
+                $c->update = $date;
+                $c->links = json_encode($d[$document_id][$date]['links']);
+                $c->rulers = json_encode($d[$document_id][$date]['rulers']);
+                try {
+                    $c->insert();
+                } catch (Exception $e) {
+                    // fb($e);
+                }
+            }
+        }
+    }
+
+    public static function importFromOldWS($args)
+    {
+        global $core;
+        // Import des fluidbooks
+        // Donc le dernier importé est le max dont le numéro est inférieur Ã  10000
+        $r = $core->con->select('SELECT MAX(book_id) AS book_id FROM books WHERE book_id<10000');
+        $lastImported = $r->book_id;
+        // On recherche maintenant les fluidbook dans la vieille base
+        $r = $core->con->select('SELECT bid FROM ws.book WHERE bid>' . $lastImported);
+        $oldBooks = array();
+        while ($r->fetch()) {
+            $oldBooks[] = $r->bid;
+        }
+
+        if (count($oldBooks)) {
+            self::importLangs($oldBooks);
+            self::importThemes($oldBooks);
+            self::importDocs($oldBooks);
+            self::importBooks($oldBooks);
+        }
+        $core->refreshWSUsersTree();
+    }
+
+    public static function importLangs($oldBooks)
+    {
+        global $core, $allTrads, $trads;
+        // On regarde d'abord les langues que nous avons déjà
+        $r = $core->con->select('SELECT lang_id FROM langues');
+        $already = array();
+        while ($r->fetch()) {
+            $already[] = $r->lang_id;
+        }
+
+        $toImport = array();
+        $r = $core->con->select('SELECT DISTINCT lang FROM ws.book WHERE bid ' . self::_sqlIn($oldBooks));
+        while ($r->fetch()) {
+            $idl = self::_getLangCode($r->lang);
+            if (in_array($idl, $already)) {
+                continue;
+            }
+            if (strlen($idl) > 2) {
+                continue;
+            }
+            $toImport[] = $r->lang;
+        }
+
+        $allTrads = array();
+        $trad = array();
+        $r = $core->con->select('SELECT * FROM ws.lang_trad,ws.lang_ord WHERE lang_trad.idlt=lang_ord.idlt AND idl ' . self::_sqlIn($toImport) . ' ');
+        while ($r->fetch()) {
+            $idl = self::_getLangCode($r->idl);
+            if (!isset($trad[$idl])) {
+                $trad[$idl] = array();
+            }
+            $trad[$idl][$r->ord] = $r->text;
+        }
+
+        foreach ($trad as $idl => $t) {
+            $traductions = wsLang::getTraductionWithId($trad[$idl]);
+            $allTrads[$idl] = $traductions;
+        }
+
+        if (!count($toImport)) {
+            return;
+        }
+
+        foreach ($toImport as $idl) {
+            $idl = self::_getLangCode($idl);
+
+            $c = $core->con->openCursor('langues');
+            $c->lang_id = $idl;
+            $c->charset = 'Latin1';
+            $c->font = 'Fluidbook.otf';
+            $c->traductions = json_encode($allTrads[$idl]);
+            $c->insert();
+        }
+    }
+
+    public static function importThemes($oldBooks)
+    {
+        global $core, $signatures;
+
+        $r = $core->con->select('SELECT tid,sigid FROM ws.theme');
+        while ($r->fetch()) {
+            $signatures[$r->tid] = $r->sigid;
+        }
+
+        $r = $core->con->select('SELECT MAX(theme_id) AS theme_id FROM themes WHERE theme_id<1000');
+        $lastImported = $r->theme_id;
+        // Import des thèmes
+        $r = $core->con->select('SELECT * FROM ws.theme WHERE tid IN (SELECT tid FROM ws.book WHERE bid ' . self::_sqlIn($oldBooks) . ') AND tid>' . $lastImported);
+        $theme = new wsTheme();
+        while ($r->fetch()) {
+            $tid = $r->tid;
+
+            $c = $core->con->openCursor('themes');
+            $c->theme_id = $r->tid;
+            $c->proprietaire = self::_getWsUser($r->proprietaire);
+            $c->date = $r->date;
+            $c->nom = $r->titre;
+
+            $parametres = new wsThemeParametres($theme);
+            $parametres->fromRecord($r);
+            self::_oldIconesToColor($r->iid, $parametres);
+            $c->parametres = serialize($parametres);
+            $c->insert();
+
+            $dest = WS_THEMES . '/' . $tid . '/';
+            if (!file_exists($dest)) {
+                mkdir($dest, 0777, true);
+            }
+
+            `/bin/cp -r /home/ws/www/themes/$tid/* $dest`;
+        }
+    }
+
+    public static function importDocs($oldBooks)
+    {
+        global $core;
+        // On cherche maintenant Ã  savoir si l'on doit importer de nouveaux documents associés
+        $oldDocuments = array();
+        $r = $core->con->select('SELECT DISTINCT did FROM ws.book_pages WHERE bid ' . self::_sqlIn($oldBooks) . '');
+        while ($r->fetch()) {
+            $oldDocuments[] = $r->did;
+        }
+
+        if (!count($oldDocuments)) {
+            return;
+        }
+
+        $r = $core->con->select('SELECT * FROM ws.document WHERE did ' . self::_sqlIn($oldDocuments) . ' ORDER BY did');
+        while ($r->fetch()) {
+            $c = $core->con->openCursor('documents');
+            $c->document_id = $r->did;
+            $c->pages = $r->pages;
+            $c->version = 1;
+            try {
+                $c->insert();
+            } catch (Exception $e) {
+                fb($e);
+            }
+        }
+    }
+
+    public static function copyLinks($args, $eraseTo = false)
+    {
+        $from = $args[0];
+        $to = $args[1];
+        global $core;
+
+        $dao = new wsDAODocument($core->con);
+
+        $dao->getLinksAndRulers($from, $fromlinks, $fromrulers);
+        if (!$eraseTo) {
+            $dao->getLinksAndRulers($to, $tolinks, $torulers);
+
+            $tolinks = array_merge($tolinks, $fromlinks);
+            $torulers = array_merge($torulers, $fromrulers);
+        } else {
+            $tolinks = $fromlinks;
+            $torulers = $fromrulers;
+        }
+
+        $wt = WS_BOOKS . '/working/' . $to;
+        $wf = WS_BOOKS . '/working/' . $from;
+
+        if (file_exists($wf)) {
+            $wf1 = $wf . '/*';
+            if (!file_exists($wt)) {
+                mkdir($wt, 0777, true);
+            }
+
+            $cmd = "cp -r $wf1 $wt";
+            echo `$cmd`;
+        }
+
+        $dao->setLinksAndRulers($to, $tolinks, $torulers, 'Copy links from #' . $from . '  to #' . $to, $core->user->utilisateur_id);
+    }
+
+    public static function importBooks($oldBooks)
+    {
+        global $core, $allTrads, $signatures;
+        // Importe les fluidbooks
+        $r = $core->con->select('SELECT * FROM ws.book WHERE bid ' . self::_sqlIn($oldBooks) . ' ORDER BY bid');
+        if (!$r->count()) {
+            return;
+        }
+        // .
+        while ($r->fetch()) {
+            $c = $core->con->openCursor('books');
+            $c->book_id = $r->bid;
+            $c->nom = $r->titre;
+            $c->lang = substr(self::_getLangCode($r->lang), 0, 2);
+            $c->theme = $r->tid;
+            if (strlen($r->lang) > 2) {
+                $c->traductions = json_encode($allTrads[self::_getLangCode($r->lang)]);
+            } else {
+                $c->traductions = '';
+            }
+            $c->proprietaire = self::_getWsUser($r->uid);
+            $c->status = $r->status;
+            $c->date_status = $r->date_status;
+            $c->hash = $r->code;
+            $c->compteur_visites = 20;
+            $c->date = $r->date;
+            $c->syncv1 = 1;
+            $c->version = 1;
+            $parametres = new wsBookParametres(new stdClass());
+            $parametres->fromRecord($r);
+
+            $xml = @simplexml_load_string('<extras>' . $r->extras . '</extras>');
+            if ($xml !== false) {
+                $parametres->fromXML($xml);
+            } else {
+
+            }
+
+            $n = array();
+            // Pages sans numéro
+            $offset = $r->first_page_nr - 1;
+            for ($i = 0; $i < $offset; $i++) {
+                $n[] = '';
+            }
+            // Pages avec numero
+            for ($j = 1; $j + $offset <= $r->pages; $j++) {
+                $n[] = $j;
+            }
+            $c->numerotation = implode(',', $n);
+
+            $parametres->signature = $signatures[$r->tid];
+            $parametres->title = $r->titre;
+            $parametres->visualisationMode = '2';
+            $c->parametres = serialize($parametres);
+            $c->version = 1;
+            $c->insert();
+        }
+        // Import des pages
+        $core->con->execute('INSERT INTO book_pages (book_id,book_page,document_id,document_page) SELECT bid,bpid,did,dpid FROM ws.book_pages WHERE bid ' . self::_sqlIn($oldBooks));
+
+        $dao = new wsDAOBook($core->con);
+        foreach ($oldBooks as $book_id) {
+            $dao->saveCompositionVersion($book_id);
+        }
+    }
+
+    protected static function _oldIconesToColor($iid, &$parametres)
+    {
+        global $oldIconesColors;
+        if (!isset($oldIconesColors)) {
+            $oldIconesColors = array();
+            $fp = fopen(dirname(__FILE__) . '/../../../icones.csv', 'rb');
+            $i = 1;
+            while ($line = fgetcsv($fp, 1000, ';', '"')) {
+                $oldIconesColors[$i] = array('color' => trim($line[0]), 'iid' => trim($line[1]));
+                $i++;
+            }
+        }
+        $line = $oldIconesColors[$iid];
+        if ($line['iid'] != '') {
+            $parametres->iconSet = $line['iid'];
+            $parametres->iconsHMargin = $line['iid'] == 1 ? 20 : 0;
+            $parametres->menuHeight = 39;
+            $parametres->colorizeIcons = false;
+            $parametres->couleurI = 'ffffff';
+        } else {
+            $parametres->iconSet = 1;
+            $parametres->colorizeIcons = 1;
+            $parametres->iconsHMargin = 20;
+            $parametres->menuHeight = 39;
+            $parametres->couleurI = $line['color'];
+        }
+    }
+
+    protected static function _getWsUser($oldid)
+    {
+        global $ws2ext;
+        if (!isset($ws2ext)) {
+            self::_getAllUsers();
+        }
+        if (!isset($ws2ext[$oldid])) {
+            self::_importOldUser($oldid);
+        }
+        if (!isset($ws2ext[$oldid])) {
+            $ws2ext[$oldid] = 1;
+        }
+        return $ws2ext[$oldid];
+    }
+
+    protected static function _getAllUsers()
+    {
+        global $core, $entreprises, $entreprise_id, $utilisateurs_entreprises, $utilisateur_id, $ws2ext, $grades, $utilisateurs;
+        $grades = array(0 => 1, 0.4 => 1, '0.4' => 1, 0.5 => 1, '0.5' => 1, 1 => 1, 2 => 2, 3 => 3, 4 => 5);
+        // Contrôle des entreprises déjà dans la base extranet
+        $entreprises = array();
+        $entreprise_id = 0;
+        $r = $core->con->select('SELECT entreprise_id,nom FROM entreprises');
+        while ($r->fetch()) {
+            $nom = mb_strtolower(trim($r->nom));
+            $nom = cubeText::str2URL($nom);
+            $entreprises[$nom] = $r->entreprise_id;
+            $entreprise_id = max($entreprise_id, $r->entreprise_id);
+        }
+
+        $utilisateurs_entreprises = array();
+        $r = $core->con->select('SELECT entreprise,utilisateur_id FROM utilisateurs');
+        while ($r->fetch()) {
+            $utilisateurs_entreprises[$r->utilisateur_id] = $r->entreprise;
+        }
+
+        $entreprise_id++;
+        // Obtient les emails des utilisateurs
+        $utilisateur_id = 0;
+        $utilisateurs = array();
+        $r = $core->con->select('SELECT utilisateur_id,email FROM utilisateurs');
+        while ($r->fetch()) {
+            $utilisateur_id = max($r->utilisateur_id, $utilisateur_id);
+            $utilisateurs[trim(mb_strtolower($r->email))] = $r->utilisateur_id;
+        }
+        $utilisateur_id++;
+
+        $ws2ext = array();
+        $r = $core->con->select('SELECT ws_id,utilisateur_id,entreprise FROM utilisateurs WHERE ws_id IS NOT NULL');
+        while ($r->fetch()) {
+            $ws2ext[$r->ws_id] = $r->utilisateur_id;
+        }
+    }
+
+    protected static function _importOldUser($oldid)
+    {
+        global $core, $entreprises, $entreprise_id, $utilisateurs_entreprises, $utilisateur_id, $ws2ext, $grades, $utilisateurs;
+        // Get user from old
+        $r = $core->con->select('SELECT * FROM ws.user WHERE uid=\'' . $core->con->escape($oldid) . '\'');
+        if ($r->extranet != 0) {
+            $ws2ext[$r->uid] = $r->extranet;
+            return;
+        }
+        // On s'occupe de l'entreprise
+        $email = trim(mb_strtolower($r->email));
+
+        $rs = trim($r->rs);
+        if ($rs == '') {
+            $rs = trim($r->prenom . ' ' . $r->nom);
+        }
+        $nom = mb_strtolower($rs);
+
+        $nom = cubeText::str2URL($nom);
+
+        if (isset($utilisateurs[$email])) {
+            $newid = $utilisateurs[$email];
+            $e = $utilisateurs_entreprises[$newid];
+            $update = true;
+        } elseif (isset($entreprises[$nom])) {
+            $e = $entreprises[$nom];
+            $update = true;
+        } else {
+            $c = $core->con->openCursor('entreprises');
+            $c->entreprise_id = $entreprise_id;
+            $c->nom = $rs;
+            $c->adresse = $r->adresse;
+            $c->code_postal = $r->code_postal;
+            $c->ville = $r->ville;
+            $c->pays = $r->pays;
+            $c->date_creation = $r->date;
+            $c->ws_grade = $grades[$r->grade];
+            $c->ws_admin = self::_getWsUser($r->admin);
+            $c->insert();
+            $e = $entreprises[$nom] = $entreprise_id;
+            $entreprise_id++;
+            $update = false;
+        }
+
+        if ($update) {
+            $c = $core->con->openCursor('entreprises');
+            $c->ws_grade = $grades[$r->grade];
+            $c->ws_admin = self::_getWsUser($r->admin);
+            $c->update('WHERE entreprise_id=\'' . $e . '\'');
+        }
+        // Puis de l'utilisateur
+        if (isset($utilisateurs[$email])) {
+            $c = $core->con->openCursor('utilisateurs');
+            $c->ws_password = $r->password;
+            $c->ws_id = $r->uid;
+            $c->update('WHERE utilisateur_id=\'' . $utilisateurs[$email] . '\'');
+            $ws2ext[$r->uid] = $utilisateurs[$email];
+            $utilisateurs_entreprises[$utilisateurs[$email]] = $e;
+        } else {
+            $c = $core->con->openCursor('utilisateurs');
+            $c->utilisateur_id = $utilisateur_id;
+            $c->entreprise = $e;
+            $c->nom = $r->nom;
+            $c->prenom = $r->prenom;
+            $c->email = $r->email;
+            $c->password = $r->password;
+            $c->adresse = $r->adresse;
+            $c->code_postal = $r->code_postal;
+            $c->ville = $r->ville;
+            $c->pays = $r->pays;
+            $c->lang = $r->lang;
+            $c->telephone = $r->telephone;
+            $c->date_creation = $r->date;
+            $c->notes = 'Inséré à  l\'import vers le nouveau Fluidbook Workshop';
+            $c->ws_password = $r->password;
+            $c->ws_id = $r->uid;
+            $c->insert();
+            $ws2ext[$r->uid] = $utilisateur_id;
+            $utilisateurs_entreprises[$utilisateur_id] = $e;
+            $utilisateur_id++;
+        }
+    }
+
+    protected static function _sqlIn($tab)
+    {
+        return ' IN(\'' . implode('\',\'', $tab) . '\') ';
+    }
+
+    protected static function _getLangCode($lang)
+    {
+        $lang = strtolower($lang);
+        if ($lang == 'cz') {
+            $lang = 'cs';
+        }
+        return $lang;
+    }
+
+    public static function dumpDatabase()
+    {
+        cubeDb::mysqlDump(DB_HOST, DB_NAME, DB_USER, DB_PASSWORD, ROOT . '/backups/dump-' . date('Y-m-d-H-i-s') . '.sql', true, 8);
+    }
+
+    public static function cleanPackages()
+    {
+        $limit = TIME - (2 * 3600); // 2 heures avant maintenant*
+        //
+        $dirs = array(
+            WS_FILES . '/packager/'
+        );
+        // Clean downloads
+
+        foreach ($dirs as $dir) {
+            if (!file_exists($dir)) {
+                continue;
+            }
+            $dr = opendir($dir);
+            while ($file = readdir($dr)) {
+                if ($file == '.' || $file == '..') {
+                    continue;
+                }
+                $f = $dir . $file;
+                if ($file == 'download') {
+                    continue;
+                }
+                if (!is_dir($f)) {
+                    continue;
+                }
+                if (filemtime($f) > $limit) {
+                    continue;
+                }
+                `rm -rf $f`;
+            }
+
+            if (!file_exists($dir)) {
+                mkdir($dir, 0777, true);
+            }
+        }
+    }
+
+    public static function cleanConversionSessions()
+    {
+        $limit = TIME - (4 * 3600); // 4 heures avant maintenant*
+
+        $dir = ROOT . '/cache/conversionSessions/';
+        $dr = opendir($dir);
+        while ($file = readdir($dr)) {
+            if ($file == '.' || $file == '..') {
+                continue;
+            }
+            $f = $dir . $file;
+            if (filemtime($f) > $limit) {
+                continue;
+            }
+            unlink($f);
+        }
+    }
+
+    public static function cleanUnusedDocs()
+    {
+        global $core;
+        cubePHP::neverStop();
+        $r = $core->con->select('SELECT document_id FROM documents WHERE document_id NOT IN (SELECT document_id FROM book_pages)');
+        while ($r->fetch()) {
+            if (file_exists(WS_DOCS . '/' . $r->document_id)) {
+                $rm = new cubeCommandLine('rm');
+                $rm->setPath(CONVERTER_PATH);
+                $rm->setArg('r');
+                $rm->setArg('f');
+                $rm->setArg(null, WS_DOCS . '/' . $r->document_id . '/');
+                $rm->execute();
+                echo $rm->commande . "<br />";
+            }
+        }
+
+        self::_moveDocs(WS_DOCS, '/data/extranet/www/fluidbook/docs1', 250);
+        self::_moveDocs('/data/extranet/www/fluidbook/docs1', '/data/extranet/www/fluidbook/docs2', 2000);
+        self::_moveDocs('/data/extranet/www/fluidbook/docs2', '/data/extranet/www/fluidbook/docs3', 7000);
+    }
+
+    protected static function _moveDocs($from, $to, $keep, $batch = 250)
+    {
+        $docs = array();
+        $dr = opendir($from);
+        while ($d = readdir($dr)) {
+            if ($d == '.' || $d == '..') {
+                continue;
+            }
+            $d = intval($d);
+            if (!$d) {
+                continue;
+            }
+            $docs[] = intval($d);
+        }
+
+        sort($docs);
+        $docs = array_splice($docs, 0, count($docs) - $keep);
+        if (count($docs)) {
+            $toMove = array_slice($docs, 0, $batch);
+
+            foreach ($toMove as $d) {
+                if (trim($d) == '') {
+                    continue;
+                }
+                $source = $from . '/' . $d . '/';
+                $dest = $to . '/' . $d . '/';
+                if (!file_exists($dest)) {
+                    mkdir($dest, 0777, true);
+                }
+                $rsync = "rsync -av $source $dest";
+                $rm = "rm -rf $source";
+                `$rsync;$rm`;
+                echo $rsync . "\n";
+                echo $rm . "\n";
+            }
+        }
+    }
+
+    public static function moveFluidbookDatas()
+    {
+        $dir = WS_BOOKS . '/final/';
+        $dr = opendir($dir);
+        while ($d = readdir($dr)) {
+            if ($d == '.' || $d == '..' || !is_dir($dir . $d)) {
+                continue;
+            }
+            rename($dir . $d . '/FluidbookDatas.swf', $dir . $d . '/data/fd.swf');
+            rename($dir . $d . '/FluidbookDatasLight.swf', $dir . $d . '/data/fdl.swf');
+        }
+    }
+
+    public static function mergeEntreprise($args)
+    {
+        global $core;
+
+        $from = $args[0];
+        $to = $args[1];
+
+        $c = $core->con->openCursor('utilisateurs');
+        $c->entreprise = $to;
+        $c->update('WHERE entreprise=' . $from);
+
+        $core->con->execute('DELETE FROM entreprises WHERE entreprise_id=' . $from);
+
+        $core->refreshWSUsersTree();
+    }
+
+    public static function updateLuceneTime()
+    {
+        global $core;
+        $dao = new wsDAOBook($core->con);
+        $books = $dao->selectLuceneTimeNotSet();
+        foreach ($books as $book) {
+            $index = WS_BOOKS . '/search/' . $book->book_id;
+            if (!file_exists($index)) {
+                fb($book->book_id, 'Skip');
+                continue;
+            }
+
+            $mtime = 0;
+            $dr = opendir($index);
+            while ($file = readdir($dr)) {
+                if ($file == '.' || $file == '..') {
+                    continue;
+                }
+                $mtime = max($mtime, filemtime($index . '/' . $file));
+            }
+
+            $c = $core->con->openCursor('books');
+            $c->lucene_time = $mtime;
+            $c->update('WHERE book_id=' . $book->book_id);
+
+            fb($book->book_id, 'Update : ' . $mtime);
+        }
+    }
+
+    public static function makeLuceneIndexes()
+    {
+        global $core;
+
+        cubePHP::neverStop();
+
+        $dao = new wsDAOBook($core->con);
+        $books = $dao->selectLuceneToDo();
+        foreach ($books as $book) {
+            $pages = $dao->getPagesOfBook($book->book_id);
+            $dao->indexPDF($book, $pages);
+        }
+    }
+
+    public static function exportSommaire($args)
+    {
+        global $core;
+        $book_id = $args[0];
+        $dao = new wsDAOBook($core->con);
+        $book = $dao->selectById($book_id);
+
+        header('Content-Type: text/plain');
+        foreach ($book->chapters as $c) {
+            echo str_repeat("\t", $c->level);
+            echo $c->label;
+            echo ' ' . $c->page;
+            echo "\n";
+
+        }
+        exit;
+    }
+
+    public static function copySommaire($args)
+    {
+        global $core;
+        $from = $args[0];
+        $to = $args[1];
+        $dao = new wsDAOBook($core->con);
+        $fbook = $dao->selectById($from);
+        $dao->setChapters($to, json_encode($fbook->chapters));
+    }
+
+    public static function copyComposition($args)
+    {
+        global $core;
+
+        $from = $args[0];
+        $to = $args[1];
+
+        $r = $core->con->select('SELECT * FROM book_pages_versions WHERE book_id=\'' . $core->con->escape($from) . '\' AND composition!=\'a:0:{}\' ORDER BY `update` DESC LIMIT 1');
+        if (!$r->count()) {
+            return;
+        }
+
+        $comp = unserialize($r->composition);
+
+        $docs = array();
+        foreach ($comp as $book_page => $infos) {
+            $docs[$infos['document_id']] = true;
+        }
+        foreach ($docs as $doc => $v) {
+            $r = $core->con->select('SELECT MAX(document_id) AS document_id FROM documents');
+            $newid = $r->document_id + 1;
+
+            self::_duplicateLines('documents', 'document_id', $doc, $newid);
+            self::_duplicateLines('document_links', 'document_id', $doc, $newid);
+            self::_duplicateLines('document_links_versions', 'document_id', $doc, $newid);
+
+            $f = wsDocument::getDir($doc);
+            $t = WS_DOCS . '/' . $newid;
+
+            `cp -r $f $t`;
+
+            $docs[$doc] = $newid;
+        }
+
+        $core->con->execute('DELETE FROM book_pages WHERE book_id=\'' . $core->con->escape($to) . '\'');
+
+        $c = $core->con->openCursor('book_pages');
+        $c->book_id = $to;
+        foreach ($comp as $book_page => $infos) {
+            $c->book_page = $book_page;
+            $c->document_id = $docs[$infos['document_id']];
+            $c->document_page = $infos['document_page'];
+            $c->insert();
+        }
+
+        $daoBook = new wsDAOBook($core->con);
+        $daoBook->saveCompositionVersion($to);
+    }
+
+    protected static function _duplicateLines($table, $key, $currentKey, $newKey)
+    {
+        global $core;
+        $tmptable = 'tmptable_' . $table . '_' . $newKey;
+
+        $core->con->execute('CREATE TEMPORARY TABLE ' . $tmptable . ' SELECT * FROM ' . $table . ' WHERE ' . $key . ' = ' . $currentKey);
+        $core->con->execute('UPDATE ' . $tmptable . ' SET ' . $key . ' =  ' . $newKey);
+        $core->con->execute('INSERT INTO ' . $table . ' SELECT * FROM ' . $tmptable);
+        $core->con->execute('DROP TEMPORARY TABLE IF EXISTS ' . $tmptable);
+    }
+
+    public static function restoreComposition($args)
+    {
+        global $core;
+        $book_id = $args[0];
+        if (isset($args[1])) {
+            $date = $args[1];
+        } else {
+            $date = TIME;
+        }
+
+
+        $r = $core->con->select('SELECT * FROM book_pages_versions WHERE book_id=\'' . $core->con->escape($book_id) . '\' AND composition!=\'a:0:{}\' AND `update`<=' . $date . ' ORDER BY `update` DESC LIMIT 1');
+        if (!$r->count()) {
+            return;
+        }
+
+        $comp = unserialize($r->composition);
+        $core->con->execute('DELETE FROM book_pages WHERE book_id=\'' . $core->con->escape($book_id) . '\'');
+        $c = $core->con->openCursor('book_pages');
+        $c->book_id = $book_id;
+        foreach ($comp as $book_page => $infos) {
+            $c->book_page = $book_page;
+            $c->document_id = $infos['document_id'];
+            $c->document_page = $infos['document_page'];
+            $c->insert();
+        }
+    }
+
+    public static function getV1Translations()
+    {
+        wsLang::getV1Translations();
+    }
+
+    public static function appendDocument($args)
+    {
+        global $core;
+        $book_id = $args[0];
+        $document_id = $args[1];
+        $dao = new wsDAOBook($core->con);
+        $dao->appendDocument($book_id, $document_id);
+    }
+
+    public static function reprocessVideos($args)
+    {
+        global $core;
+
+        $book_id = $args[0];
+
+        $dir = WS_BOOKS . '/working/' . $book_id;
+
+        $dao = new wsDAODocument($core->con);
+        $dao->getLinksAndRulers($book_id, $links, $rulers);
+
+        foreach ($links as $link) {
+            if ($link['type'] != 4) {
+                continue;
+            }
+
+            $file = $dir . '/' . $link['to'];
+            if (!file_exists($file)) {
+                continue;
+            }
+
+            wsTools::encodeWebVideos($file, null, true, true);
+        }
+    }
+
+    public static function syncLDAP()
+    {
+        global $core;
+        cubePHP::neverStop();
+
+        $res = '<pre>';
+
+        $ds = ldap_connect('localhost', 10389);
+        ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
+        ldap_bind($ds, 'uid=admin,ou=system', '*arica*6');
+
+        $r = $core->con->select('SELECT * FROM utilisateurs_entreprise ORDER BY utilisateur_id');
+        while ($r->fetch()) {
+            if (is_null($r->utilisateur_id)) {
+                continue;
+            }
+            $entree = array();
+            $entree['objectClass'][] = 'top';
+            $entree['objectClass'][] = 'person';
+            $entree['objectClass'][] = 'organizationalPerson';
+            $entree['objectClass'][] = 'extensibleObject';
+            $entree['cn'] = trim($r->prenom . ' ' . $r->nom . ' - ' . $r->rs . ' (' . $r->utilisateur_id . ')', ' -');
+            $entree['sn'] = $r->nom == '' ? $entree['cn'] : $r->nom;
+            $entree['mail'] = $r->email;
+            $entree['uid'] = 'extranet_' . $r->utilisateur_id;
+            $entree['OrganizationalUnitName'] = $r->rs;
+            if ($r->telephone && $r->telephone != '+33') {
+                $entree['telephoneNumber'][] = $r->telephone;
+            }
+            if ($r->mobile && $r->mobile != '+33') {
+                $entree['telephoneNumber'][] = $r->mobile;
+            }
+            if ($r->fax && $r->fax != '+33') {
+                $entree['telexNumber'] = $r->fax;
+            }
+            $dn = 'uid=' . $entree['uid'] . ',o=cubedesigners';
+            if (!ldap_add($ds, $dn, $entree)) {
+                $e = ldap_error($ds);
+                if ($e == 'Already exists') {
+                    ldap_modify($ds, $dn, $entree);
+                } else {
+                    fb($entree, $e);
+                }
+            }
+        }
+        $res = 'test';
+        $res .= '</pre>';
+
+        ldap_close($ds);
+        return $res;
+    }
+
+    public static function createBranch($args)
+    {
+        commonDroits::min(5);
+        $branch = $args[0];
+
+        self::updateHTML5Sources();
+        $playerDir = WS_COMPILE_ASSETS . '/player/';
+        $branchesDir = $playerDir . 'branches/';
+        $git = new CubeIT_CommandLine_Git($branchesDir . 'fluidbook-html5');
+        echo $git->executeCmd('checkout -b ' . $branch);
+        $git = new CubeIT_CommandLine_Git($branchesDir . 'fluidbook-html5');
+        echo $git->executeCmd('push --set-upstream origin ' . $branch);
+        self::updateHTML5Sources();
+        $git = new CubeIT_CommandLine_Git($branchesDir . 'fluidbook-html5');
+        echo $git->executeCmd('checkout master');
+    }
+
+    public static function deleteBranch($args)
+    {
+        commonDroits::min(5);
+        $branch = trim($args[0]);
+        if ($branch == 'master' || !$branch) {
+            die('même pas en rêve');
+        }
+
+        self::updateHTML5Sources();
+
+        $playerDir = WS_COMPILE_ASSETS . '/player/';
+        $branchesDir = $playerDir . 'branches/';
+        $localDir = $playerDir . 'local/';
+
+        $git = new CubeIT_CommandLine_Git($branchesDir . 'fluidbook-html5');
+        echo $git->executeCmd('push --delete origin ' . $branch);
+
+        `rm -rf $localDir$branch`;
+        `rm -rf $branchesDir$branch`;
+
+        self::updateHTML5Sources();
+    }
+
+    public static function updateHTML5Sources($args = array(), $externals = true)
+    {
+        $playerDir = WS_COMPILE_ASSETS . '/player/';
+        $branchesDir = $playerDir . 'branches/';
+        $localDir = $playerDir . 'local/';
+        echo '<pre>';
+        $git = new CubeIT_CommandLine_Git($branchesDir . 'fluidbook-html5');
+        echo $git->executeCmd('stash save --keep-index');
+        $git = new CubeIT_CommandLine_Git($branchesDir . 'fluidbook-html5');
+        echo $git->executeCmd('stash drop');
+        $git = new CubeIT_CommandLine_Git($branchesDir . 'fluidbook-html5');
+        echo $git->executeCmd('pull --all');
+        $git = new CubeIT_CommandLine_Git($branchesDir . 'fluidbook-html5');
+        echo $git->executeCmd('fetch --all --prune');
+        $git = new CubeIT_CommandLine_Git($branchesDir . 'fluidbook-html5');
+        $b = $git->executeCmd('branch -r');
+        echo $b;
+        $bb = explode("\n", $b);
+        $branches = array();
+        foreach ($bb as $item) {
+            $item = trim($item);
+            if ($item == '') {
+                continue;
+            }
+            $e = explode('->', $item);
+            if (count($e) == 2) {
+                $item = $e[1];
+            } else {
+                $item = $e[0];
+            }
+            $e = explode("/", $item);
+            $branches[trim($e[1])] = true;
+        }
+        $branches = array_keys($branches);
+        foreach ($branches as $b) {
+            $gitsource = $branchesDir . $b;
+            $local = $localDir . $b;
+            echo '<b>' . $b . '</b>' . "\n";
+            if (!file_exists($branchesDir . $b)) {
+                $git = new CubeIT_CommandLine_Git($branchesDir);
+                echo $git->executeCmd('clone -b ' . $b . ' --single-branch git@git.cubedesigners.com:fluidbook-html5.git ' . $b);
+            }
+            if (!file_exists($local)) {
+                mkdir($local, 0777, true);
+                `cp -r $gitsource/* $local`;
+                `rm -rf $local/.git`;
+            }
+            $git = new CubeIT_CommandLine_Git($branchesDir . $b);
+            echo $git->executeCmd('reset --hard origin/' . $b);
+            $git = new CubeIT_CommandLine_Git($branchesDir . $b);
+            echo $git->executeCmd('pull');
+        }
+
+        echo '</pre>';
+        file_put_contents(WS_CACHE . '/activebranches', json_encode($branches));
+    }
+
+    public static function cleanDownload($args)
+    {
+        $dirs = [ROOT . '/cache/download/', WS_FILES . '/packager/download'];
+        foreach ($dirs as $dir) {
+            cubeFiles::scanRecursiveDir($dir, $files);
+            $limit = TIME - 7200;
+            if (is_array($files)) {
+                foreach ($files as $f) {
+                    if (filemtime($f) < $limit) {
+                        unlink($f);
+                    }
+                }
+            }
+        }
+    }
+
+    public static function deleteOldFilesFromFTP($args)
+    {
+        global $core;
+        cubePHP::neverStop();
+
+        $dao = new commonDAOFichier($core->con);
+        $dao->deleteOldFiles();
+    }
+
+    public static function reencodeVideos($args)
+    {
+        cubePHP::neverStop();
+
+        $book_id = $args[0];
+        $format = $args[1];
+        $dir = WS_BOOKS . '/working/' . $book_id;
+
+        wsLinks::getLinksAndRulers($book_id, $links, $rulers);
+
+        foreach ($links as $link) {
+            if ($link['type'] != 4) {
+                continue;
+            }
+
+            $file = $dir . '/' . $link['to'];
+            if (!file_exists($file)) {
+                continue;
+            }
+
+            wsTools::encodeWebVideos($file, null, false, true, $format);
+        }
+    }
+
+    public static function correctAutoBookmarkLinks($args)
+    {
+        global $core;
+        $book_id = $args[0];
+        wsLinks::getLinksAndRulers($book_id, $links, $rulers);
+
+        $newlinks = array();
+        foreach ($links as $link) {
+            $link['left'] -= 1;
+            $link['top'] += 1;
+            $link['width'] += 5;
+            $link['height'] += 3;
+            $newlinks[] = $link;
+        }
+
+        $dao = new wsDAODocument($core->con);
+        $dao->setLinksAndRulers($book_id, json_encode($newlinks), json_encode($rulers), 'Autobookmark links correction', $core->user->utilisateur_id);
+    }
+
+    public static function compress()
+    {
+        `gzip /home/extranet/www/fluidbook/docs/*/p*.csv`;
+        `gzip /home/extranet/www/fluidbook/docs/*/*.txt`;
+    }
+
+    public static function restoreChapters($args)
+    {
+        global $core;
+
+        $book_id = $args[0];
+        $r = $core->con->select('SELECT chapters FROM books_chapters_versions WHERE book_id=\'' . $core->con->escape($book_id) . '\' ORDER BY `time` DESC LIMIT 1');
+        while ($r->fetch()) {
+            $c = $core->con->openCursor('books');
+            $c->chapters = $r->chapters;
+            $c->changedate = TIME;
+            $c->update('WHERE book_id=\'' . $core->con->escape($book_id) . '\'');
+            break;
+        }
+        echo $r->chapters;
+    }
+
+    public static function offsetLinksPos($args)
+    {
+        global $core;
+        $book_id = $args[0];
+        $direction = $args[1];
+        $value = intval($args[2]);
+        wsLinks::getLinksAndRulers($book_id, $links, $rulers);
+
+        if ($direction == 'y') {
+            $k = 'top';
+        } elseif ($direction == 'x') {
+            $k = 'left';
+        } else {
+            return;
+        }
+        if (!$value) {
+            return;
+        }
+        $newlinks = array();
+        foreach ($links as $link) {
+            $link[$k] += $value;
+            $newlinks[] = $link;
+        }
+
+        $dao = new wsDAODocument($core->con);
+        $dao->setLinksAndRulers($book_id, json_encode($newlinks), json_encode($rulers), 'Offset links positions (' . $direction . ' :: ' . $value . ')', $core->user->utilisateur_id);
+    }
+
+    public static function duplicateBook($args)
+    {
+        global $core;
+
+        commonDroits::min(5);
+
+        $book_id = $args[0];
+        $times = isset($args[1]) ? $args[1] : 1;
+        $dao = new wsDAOBook($core->con);
+
+        for ($i = 0; $i < $times; $i++) {
+            $newbook = $dao->duplicate($book_id, $core->user->utilisateur_id, null, true, true);
+            $new_id = $newbook->book_id;
+            self::copyComposition([$book_id, $new_id]);
+            self::copyLinks([$book_id, $new_id], true);
+        }
+    }
+
+    public static function extractTexts($args)
+    {
+        global $core;
+        $book_id = $args[0];
+        $dao = new wsDAOBook($core->con);
+        $book = $dao->selectById($book_id);
+        $pages = $dao->getPagesOfBook($book_id);
+
+        $docs = array();
+        foreach ($pages as $p) {
+            $docs[] = $p['document_id'];
+        }
+        $docs = array_unique($docs);
+
+        foreach ($docs as $doc) {
+            $out = WS_DOCS . '/' . $doc . '/';
+
+            $fwstk = new cubeCommandLine('fwstk.sh');
+            $fwstk->setPath(CONVERTER_PATH);
+            $fwstk->setArg('--input ' . $out . '/crop.pdf');
+            $fwstk->setArg('--extractTexts ' . $out . '%s%d.txt');
+            $fwstk->setArg('--extractTextsMethod ' . $book->parametres->textExtraction);
+            if ($book->parametres->ignoreSearchSeparators != '') {
+                $fwstk->setArg('--ignoreSeparators ' . $book->parametres->ignoreSearchSeparators);
+            }
+            $fwstk->setArg('--threads 1');
+            $fwstk->execute();
+
+            $res = $fwstk->commande . "\n\n";
+            $res .= $fwstk->output;
+        }
+
+        $dir = WS_BOOKS . '/index/' . $book->book_id;
+        if ($book->parametres->ignoreSearchSeparators != '') {
+            $dir .= '/' . sha1($book->parametres->ignoreSearchSeparators);
+        }
+
+        $prefixes = array('', 'p');
+        foreach ($prefixes as $prefix) {
+            $ifilec = $dir . '/' . $prefix . 'index.json';
+            $tfilec = $dir . '/' . $prefix . 'textes.json';
+
+            $files = array($ifilec, $tfilec);
+
+            foreach ($files as $f) {
+                CubeIT_Util_Gzip::unlink($f . '.gz');
+            }
+        }
+
+        $i = WS_BOOKS . '/index/' . $book_id . '/*';
+        `rm -rf $i`;
+        ob_end_clean();
+        die('<pre>' . $res . '</pre>');
+    }
+
+    public static function _reencodeVideos($book_id, $format)
+    {
+        wsLinks::getLinksAndRulers($book_id, $links, $rulers);
+        foreach ($links as $l) {
+            if ($l['type'] == 10) {
+                $to = $l['to'];
+                fb($to);
+            }
+        }
+    }
+
+    public static function kadreoDevis8524147851()
+    {
+        global $core;
+
+        $xls = new PHPExcel();
+
+        $cols = ['demande_id' => '#', 'date' => 'Date', 'prenom' => 'Prénom', 'nom' => 'Nom', 'rs' => 'Entreprise', 'email' => 'E-mail',
+            'telephone' => 'Téléphone', 'pays' => 'Pays', 'code_postal' => 'Code postal', 'details' => 'Détails'];
+
+
+        $r = $core->con->select('SELECT * FROM demandes LEFT JOIN utilisateurs_entreprise ON demandes.utilisateur=utilisateurs_entreprise.utilisateur_id WHERE revendeur=94 AND status=2 ORDER BY date DESC');
+        $s = $xls->getActiveSheet();
+        $s->setTitle('Demandes');
+
+        $i = 0;
+        foreach ($cols as $c => $col) {
+            $s->getColumnDimensionByColumn($i)->setAutoSize(true);
+            $s->setCellValueByColumnAndRow($i, 1, $col);
+            $i++;
+        }
+
+        $j = 2;
+        while ($r->fetch()) {
+            $i = 0;
+            foreach ($cols as $c => $col) {
+                $v = $r->{$c};
+                if ($c == 'telephone') {
+                    $v = $v . ' ';
+                }
+                if ($c == 'date') {
+                    $v = date('Y-m-d H:i:s', $v);
+                }
+
+
+                $s->setCellValueByColumnAndRow($i, $j, $v);
+                $style = $s->getCellByColumnAndRow($i, $j)->getStyle();
+                $style->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_LEFT)
+                    ->setVertical(PHPExcel_Style_Alignment::VERTICAL_TOP)
+                    ->setWrapText(true);
+                $i++;
+            }
+            $j++;
+        }
+
+
+        $xls->setActiveSheetIndex(0);
+
+        ob_end_clean();
+        files::registerMimeTypes(array('xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'));
+        cubeHTTP::forceDownload('Kadreo_demandes_Fluidbook-com.xlsx', false);
+
+        $writer = new PHPExcel_Writer_Excel2007($xls);
+        $writer->save('php://output');
+        exit;
+    }
+
+    public static function syncKadreoMailchimp()
+    {
+        global $core;
+
+        set_time_limit(0);
+
+
+        $u = array();
+
+        $r = $core->con->select('SELECT * FROM utilisateurs');
+        while ($r->fetch()) {
+            $u[$r->utilisateur_id] = $r->row();
+        }
+
+        $r = $core->con->select("SELECT * FROM entreprises_ws WHERE revendeur='Kadreo' AND ws_grade<=4 AND ws_grade>0");
+        while ($r->fetch()) {
+            $e[$r->entreprise_id] = array('COUNTRY' => $r->pays, 'CONTACT' => date('m/d/Y', $r->date_creation), 'COMPANY' => $r->nom);
+        }
+
+        $batch = array();
+        foreach ($u as $user) {
+            if (!isset($e[$user['entreprise']])) {
+                continue;
+            }
+            if (stristr($user['email'], 'extranet.cubedesigners.com')) {
+                continue;
+            }
+
+            $batch[] = array_merge($e[$user['entreprise']], array('email' => $user['email'], 'LOCALE' => $user['lang'], 'FNAME' => $user['prenom'], 'LNAME' => $user['nom']));
+        }
+
+        $api = new CubeIT_Services_Mailchimp('2b255293f3595181dd7d079d29dc6b99-us14');
+        $res = $api->batchSubscribe('8ff710b78e', $batch);
+        echo '<pre>OK</pre>';
+    }
+
+
+    public static function syncCubedesignersMailchimp()
+    {
+        global $core;
+
+        set_time_limit(0);
+        $api = new CubeIT_Services_Mailchimp('2abe038d70806d50b23b7a37aa2f6067-us12');
+
+        $u = array();
+
+        $r = $core->con->select('SELECT * FROM utilisateurs');
+        $unsubscribe = array();
+        while ($r->fetch()) {
+            $u[$r->utilisateur_id] = $r->row();
+            $unsubscribe[$r->email] = true;
+        }
+
+        $r = $core->con->select("SELECT * FROM entreprises_ws WHERE revendeur='Cubedesigners' AND ws_grade<=4 AND ws_grade>0");
+        while ($r->fetch()) {
+            $e[$r->entreprise_id] = array('lastdate' => 0, 'COUNTRY' => $r->pays, 'CONTACT' => date('m/d/Y', $r->date_creation), 'LASTACTION' => date('m/d/Y', $r->date_creation), 'COMPANY' => $r->nom, 'RESSELER' => ($r->ws_grade > 2) ? 1 : 0, 'FLUIDBOOKS' => 0, 'TURNOVER' => 0);
+        }
+
+        $r = $core->con->select("SELECT * FROM entreprises_vue");
+        while ($r->fetch()) {
+            if ($r->ca && isset($e[$r->entreprise_id])) {
+                $e[$r->entreprise_id]['TURNOVER'] = $r->ca;
+            }
+        }
+
+        $rr = $core->con->select('SELECT COUNT(*) AS nb,MAX(`date`) AS lastdate,facturable_id FROM books_vue WHERE status >= 0 GROUP BY facturable_id');
+        while ($rr->fetch()) {
+            $eid = $u[$rr->facturable_id]['entreprise'];
+            if (isset($e[$eid])) {
+                $e[$eid]['FLUIDBOOKS'] += $rr->nb;
+                $e[$eid]['lastdate'] = max($e[$eid]['lastdate'], $rr->lastdate);
+                $e[$eid]['LASTACTION'] = date('m/d/Y', $rr->lastdate);
+            }
+        }
+
+        $batch = array();
+        foreach ($u as $user) {
+            if (!isset($e[$user['entreprise']])) {
+                continue;
+            }
+            if (stristr($user['email'], 'extranet.cubedesigners.com')) {
+                continue;
+            }
+
+            $eu = $e[$user['entreprise']];
+            if (isset($eu['lastdate'])) {
+                unset($eu['lastdate']);
+            }
+
+            unset($unsubscribe[$user['email']]);
+
+            $batch[] = array_merge($eu, array('email' => $user['email'], 'LOCALE' => $user['lang'], 'FNAME' => $user['prenom'], 'LNAME' => $user['nom'], 'language' => $user['lang']));
+        }
+
+        $res = $api->batchSubscribe('69f69a2bb8', $batch);
+        $runs = $api->batchUnsubscribe('69f69a2bb8', array_keys($unsubscribe));
+        echo '<pre>' . print_r($runs, true) . '</pre>';
+    }
+
+    public static function resetPlayerVersion()
+    {
+        global $core;
+        $dev = [10000, 10003, 15407, 15571, 15837, 16200];
+        $r = $core->con->select('SELECT book_id, parametres FROM books WHERE book_id NOT IN(' . implode(',', $dev) . ')');
+        $reset = [];
+        $error = [];
+        $skip = [];
+        while ($r->fetch()) {
+            /** @var wsBookParametres $parametres */
+            try {
+                $parametres = unserialize($r->parametres);
+                if ($parametres->mobileLVersion === 'stable') {
+                    $skip[] = $r->book_id;
+                    continue;
+                }
+                $parametres->mobileLVersion = 'stable';
+                $c = $core->con->openCursor('books');
+                $c->parametres = serialize($parametres);
+                $c->changedate = TIME;
+                $c->update('WHERE book_id=' . $r->book_id);
+                $reset[] = $r->book_id;
+                //break;
+            } catch (Exception $e) {
+                $error[] = $r->book_id;
+            }
+        }
+
+        echo 'reset : ' . implode(', ', $reset) . '<br />';
+        echo 'skip : ' . implode(', ', $skip) . '<br />';
+        echo 'error : ' . implode(', ', $error) . '<br />';
+    }
+
+
+    public static function getSVGPage($args)
+    {
+
+        global $core;
+        $fluidbook = $args[0];
+        $page = $args[1];
+        $dao = new wsDAOBook($core->con);
+        $pages = $dao->getPagesOfBook($fluidbook);
+        $p = $pages[$page];
+        ob_clean();
+        header('Content-type: image/svg+xml');
+        $svg = wsDocument::getDir($p['document_id']) . '/html/p' . $p['document_page'] . '.svg';
+
+        $pdftocairo = new cubeCommandLine('pdftocairo');
+        $pdftocairo->setPath(CONVERTER_PATH);
+        $pdftocairo->setArg('f', $p['document_page']);
+        $pdftocairo->setArg('l', $p['document_page']);
+        $pdftocairo->setArg(null, '-svg');
+        //$pdftocairo->setArg(null, '-cropbox');
+        $pdftocairo->setArg(null, wsDocument::getDir($p['document_id']) . 'crop.pdf');
+        $pdftocairo->setArg(null, $svg);
+        $pdftocairo->execute();
+
+        wsDocument::cleanSVG($svg);
+
+        echo file_get_contents(wsDocument::getDir($p['document_id']) . '/html/p' . $p['document_page'] . '.svg');
+        exit;
+    }
+
+    public static function testSVG($args)
+    {
+        global $core;
+
+        $book = $args[0];
+        $page = $args[1];
+
+        $dao = new wsDAOBook($core->con);
+        $pages = $dao->getPagesOfBook($book);
+        $p = $pages[$page];
+
+        $dir = wsDocument::getDir($p['document_id']);
+        $test = $dir . '/html/zz%s.svg';
+        wsTools::optimizeSVG($dir . '/html/fp' . $p['document_page'] . '.svg', $test, [150, 300], true);
+    }
+
+    public static function svgToFlash()
+    {
+        $iconSets = array(15);
+        $names = array('nav-share' => 'nav-friend',
+            'nav-bookmarks' => 'nav-bookmark',
+            'nav-chapters' => 'nav-sommaire',
+            'nav-download' => 'nav-save',
+            'nav-fullscreen' => 'nav-fullscreen',
+            'nav-fullscreen-exit' => 'nav-normalscreen',
+            'nav-sound-off' => 'nav-soundoff',
+            'nav-sound-on' => 'nav-soundon',
+        );
+
+
+        foreach ($iconSets as $iconSet) {
+            $dom = new DOMDocument();
+            $svgFile = WS_ICONS . '/' . $iconSet . '/interface.svg';
+            if (!$dom->loadXML(file_get_contents($svgFile))) {
+                die('Error loading xml : ' . $svgFile);
+            }
+
+            $symbols = $dom->getElementsByTagName('symbol');
+
+            foreach ($symbols as $symbol) {
+                /* @var $symbol DOMElement */
+                $id = $symbol->getAttribute('id');
+                list($x, $y, $width, $height) = explode(' ', $symbol->getAttribute('viewBox'));
+
+                $svg = '<?xml version="1.0" encoding="utf-8"?>
 <svg version="1.0" id="' . $id . '" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="' . $width . 'px" height="' . $height . 'px" viewBox="0 0 ' . $width . ' ' . $height . '" enable-background="new 0 0 ' . $width . ' ' . $height . '" xml:space="preserve">
 ' . CubeIT_Util_Xml::innerXML($symbol) . '
 </svg>';
-                               $dest = $id;
-                               if (isset($names[$id])) {
-                                       $dest = $names[$id];
-                               }
-                               $tmp = CubeIT_Files::tempnam() . '.svg';
-                               file_put_contents($tmp, $svg);
-                               $png = WS_ICONS . '/' . $iconSet . '/' . $dest . '.png';
-                               $tmp1 = CubeIT_Files::tempnam() . '.png';
-
-                               $cmd = "/usr/bin/convert -density 200 -resize 25x25 -background none $tmp $tmp1";
-                               echo $cmd . "\n";
-                               echo `$cmd` . "\n";
-
-                               $cmd = "/usr/bin/convert $tmp1 -alpha extract -background white -alpha shape $png";
-                               echo $cmd . "\n";
-                               echo `$cmd` . "\n";
-
-                               unlink($tmp1);
-                               unlink($tmp);
-                       }
-                       header('Content-type: text/plain');
-                       exit;
-               }
-       }
-
-       public static function iconSetToInterface()
-       {
-               $iconSets = array(1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14);
-
-               $names = array('nav-share' => 'nav-friend',
-                       'nav-bookmarks' => 'nav-bookmark',
-                       'nav-chapters' => 'nav-sommaire',
-                       'nav-download' => 'nav-save',
-                       'nav-fullscreen' => 'nav-fullscreen',
-                       'nav-fullscreen-exit' => 'nav-normalscreen',
-                       'nav-sound-off' => 'nav-soundoff',
-                       'nav-sound-on' => 'nav-soundon',
-               );
-
-               $shares = array('email', 'facebook', 'twitter', 'googleplus', 'linkedin', 'viadeo');
-
-               $names = array_flip($names);
-
-               foreach ($iconSets as $iconSet) {
-                       $res = '<?xml version="1.0" encoding="UTF-8" ?>
+                $dest = $id;
+                if (isset($names[$id])) {
+                    $dest = $names[$id];
+                }
+                $tmp = CubeIT_Files::tempnam() . '.svg';
+                file_put_contents($tmp, $svg);
+                $png = WS_ICONS . '/' . $iconSet . '/' . $dest . '.png';
+                $tmp1 = CubeIT_Files::tempnam() . '.png';
+
+                $cmd = "/usr/bin/convert -density 200 -resize 25x25 -background none $tmp $tmp1";
+                echo $cmd . "\n";
+                echo `$cmd` . "\n";
+
+                $cmd = "/usr/bin/convert $tmp1 -alpha extract -background white -alpha shape $png";
+                echo $cmd . "\n";
+                echo `$cmd` . "\n";
+
+                unlink($tmp1);
+                unlink($tmp);
+            }
+            header('Content-type: text/plain');
+            exit;
+        }
+    }
+
+    public static function iconSetToInterface()
+    {
+        $iconSets = array(1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14);
+
+        $names = array('nav-share' => 'nav-friend',
+            'nav-bookmarks' => 'nav-bookmark',
+            'nav-chapters' => 'nav-sommaire',
+            'nav-download' => 'nav-save',
+            'nav-fullscreen' => 'nav-fullscreen',
+            'nav-fullscreen-exit' => 'nav-normalscreen',
+            'nav-sound-off' => 'nav-soundoff',
+            'nav-sound-on' => 'nav-soundon',
+        );
+
+        $shares = array('email', 'facebook', 'twitter', 'googleplus', 'linkedin', 'viadeo');
+
+        $names = array_flip($names);
+
+        foreach ($iconSets as $iconSet) {
+            $res = '<?xml version="1.0" encoding="UTF-8" ?>
 <svg xmlns="http://www.w3.org/2000/svg" style="display: none;">';
-                       $dir = WS_ICONS . '/' . $iconSet . '/mobile/';
-                       $dr = opendir($dir);
-                       while ($f = readdir($dr)) {
-                               if ($f == '.' || $f == '..') {
-                                       continue;
-                               }
-                               $file = $dir . $f;
-                               if (is_dir($file)) {
-                                       continue;
-                               }
-                               $e = explode('.', $f);
-                               $ext = array_pop($e);
-                               if ($ext != 'svg') {
-                                       continue;
-                               }
-
-                               $name = $e[0];
-                               if (isset($names[$name])) {
-                                       $name = $names[$name];
-                               }
-
-                               $dom = new DOMDocument();
-                               $dom->loadXML(file_get_contents($file));
-                               $svg = $dom->getElementsByTagName('svg')[0];
-
-                               $res .= "\n\t" . '<symbol id="' . $name . '" viewBox="' . $svg->getAttribute('viewBox') . '">';
-                               $res .= "\n\t\t" . CubeIT_Util_Xml::innerXML($svg);
-                               $res .= "\n\t" . '</symbol>';
-
-                               if ($name == 'nav-fullscreen') {
-                                       $name = 'nav-fullscreen-exit';
-                                       $res .= "\n\t" . '<symbol id="' . $name . '" viewBox="' . $svg->getAttribute('viewBox') . '">';
-                                       $res .= "\n\t\t" . CubeIT_Util_Xml::innerXML($svg);
-                                       $res .= "\n\t" . '</symbol>';
-                               }
-
-                       }
-
-                       foreach ($shares as $share) {
-                               $name = 'share-' . $share;
-
-                               $dom = new DOMDocument();
-                               $dom->loadXML(file_get_contents(WS_ICONS . '/share/share-' . $share . '.svg'));
-                               $svg = $dom->getElementsByTagName('svg')[0];
-
-                               $res .= "\n\t" . '<symbol id="' . $name . '" viewBox="' . $svg->getAttribute('viewBox') . '">';
-                               $res .= "\n\t\t" . CubeIT_Util_Xml::innerXML($svg);
-                               $res .= "\n\t" . '</symbol>';
-
-                       }
-                       $res .= "\n" . '    <symbol id="nav-locales" viewBox="0 0 19 20">
+            $dir = WS_ICONS . '/' . $iconSet . '/mobile/';
+            $dr = opendir($dir);
+            while ($f = readdir($dr)) {
+                if ($f == '.' || $f == '..') {
+                    continue;
+                }
+                $file = $dir . $f;
+                if (is_dir($file)) {
+                    continue;
+                }
+                $e = explode('.', $f);
+                $ext = array_pop($e);
+                if ($ext != 'svg') {
+                    continue;
+                }
+
+                $name = $e[0];
+                if (isset($names[$name])) {
+                    $name = $names[$name];
+                }
+
+                $dom = new DOMDocument();
+                $dom->loadXML(file_get_contents($file));
+                $svg = $dom->getElementsByTagName('svg')[0];
+
+                $res .= "\n\t" . '<symbol id="' . $name . '" viewBox="' . $svg->getAttribute('viewBox') . '">';
+                $res .= "\n\t\t" . CubeIT_Util_Xml::innerXML($svg);
+                $res .= "\n\t" . '</symbol>';
+
+                if ($name == 'nav-fullscreen') {
+                    $name = 'nav-fullscreen-exit';
+                    $res .= "\n\t" . '<symbol id="' . $name . '" viewBox="' . $svg->getAttribute('viewBox') . '">';
+                    $res .= "\n\t\t" . CubeIT_Util_Xml::innerXML($svg);
+                    $res .= "\n\t" . '</symbol>';
+                }
+
+            }
+
+            foreach ($shares as $share) {
+                $name = 'share-' . $share;
+
+                $dom = new DOMDocument();
+                $dom->loadXML(file_get_contents(WS_ICONS . '/share/share-' . $share . '.svg'));
+                $svg = $dom->getElementsByTagName('svg')[0];
+
+                $res .= "\n\t" . '<symbol id="' . $name . '" viewBox="' . $svg->getAttribute('viewBox') . '">';
+                $res .= "\n\t\t" . CubeIT_Util_Xml::innerXML($svg);
+                $res .= "\n\t" . '</symbol>';
+
+            }
+            $res .= "\n" . '    <symbol id="nav-locales" viewBox="0 0 19 20">
                                        <path d="M7.9,0H1C0.5,0,0,0.5,0,1l0,13c0,0.6,0.4,1,1,1h8V1C8.9,0.5,8.4,0,7.9,0z M6,11L5,9H4l-1,2H1l3-8h1l2.9,8L6,11z M4.7,5.4
                        C4.6,5.1,4.6,4.9,4.5,4.8C4.5,5.2,4.3,5.6,4.2,6.1L3.5,8h2.1L4.9,6C4.9,5.9,4.8,5.7,4.7,5.4z M18,2h-8v14h8c0.6,0,1-0.5,1-1l0-12
                        C19,2.4,18.6,2,18,2z M18,7c0,0.1-0.1,2.1-1.8,4c-1.7,1.9-3.7,2.4-3.8,2.4l-0.3-1.3c0,0,1.7-0.4,3.1-2C16.2,9,16.9,7.8,17,7h-5V6
@@ -1621,111 +1621,111 @@ class wsMaintenance
  
 ';
 
-                       if ($iconSet >= 13) {
-                               $res .= '<symbol id="nav-download" viewBox="0 0 19 20"><path d="M17,9v4H2v-2.006V9c-0.922,0-2,0.807-2,1.729v3.597c0,0.922,0.753,1.677,1.675,1.677h15.651
+            if ($iconSet >= 13) {
+                $res .= '<symbol id="nav-download" viewBox="0 0 19 20"><path d="M17,9v4H2v-2.006V9c-0.922,0-2,0.807-2,1.729v3.597c0,0.922,0.753,1.677,1.675,1.677h15.651
        c0.92,0,1.674-0.755,1.674-1.677v-3.597C19,9.807,17.92,9,17,9z M15.553,6H11V1c0-0.552-0.447-1-1-1H9C8.447,0,8,0.448,8,1v5H3.334
        l6.17,6.279L15.553,6z"/></symbol>';
-                       } else {
-                               $res .= '<symbol id="nav-download" viewBox="0 0 20 20">
+            } else {
+                $res .= '<symbol id="nav-download" viewBox="0 0 20 20">
                <path d="M17.2,1H4.8C3.8,1,3,1.8,3,2.8v12.4c0,1,0.8,1.8,1.8,1.8h0.9v-0.8h0l0-4.5c0-1,0.8-1.8,1.8-1.8h7.1
                c1,0,1.8,0.8,1.8,1.8v4.5H5.7l0,0.8h0v0l11.6,0c1,0,1.8-0.8,1.8-1.8V2.8C19,1.8,18.2,1,17.2,1z M8.3,10.8H7.4
                c-0.5,0-0.9,0.4-0.9,0.9v2.8c0,0.5,0.4,0.9,0.9,0.9h0.9c0.5,0,0.9-0.4,0.9-0.9v-2.8C9.2,11.2,8.8,10.8,8.3,10.8z"/>
        </symbol>';
-                       }
-
-                       $res .= "\n" . '</svg>';
-                       file_put_contents(WS_ICONS . '/' . $iconSet . '/interface.svg', $res);
-               }
-       }
-
-       public static function installAtlanticCommunicationBook()
-       {
-               $exporter = new wsExporter();
-               $exporter->export(15316, $x, 'install_ftp', 'online', "atlanticki-01:Tjz3N85h@ftp.cluster023.hosting.ovh.net/www/", '');
-               header('Location: http://www.atlantic-international-book-com.com/');
-               exit;
-       }
-
-       public static function installWescoVentes()
-       {
-               $exporter = new wsExporter();
-               $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;
-       }
-
-       public static function fixStats($args)
-       {
-               commonDroits::min(5);
-               $book = trim($args[0], ' .');
-               if (!$book) {
-                       return false;
-               }
-               $book = intval($book);
-               if ($book <= 1000) {
-                       return false;
-               }
-
-               `rm -rf /home/stats/www/objects/$book*;/home/stats/www/FWStats.sh /home/stats/www redobook=$book`;
-       }
-
-       public static function processInbox()
-       {
-
-               $base = WS_FILES . '/INBOX/';
-
-               $files = CubeIT_Files::getRecursiveDirectoryIterator($base);
-
-               $publications = array();
-
-               foreach ($files as $file) {
-                       /* @var $file SplFileInfo */
-                       if ($file->isDir() || $file->getExtension() != 'pdf') {
-                               continue;
-                       }
-
-                       $p = str_replace($base, '', $file->getPathname());
-                       $e = explode('/', $p, 3);
-                       $user = $e[0];
-                       $from = $e[1];
-                       $name = $file->getFilename();
-
-                       $publications[] = array('spl' => $file, 'user' => $user, 'from' => $from, 'name' => $name);
-               }
-
-               foreach ($publications as $publication) {
-                       self::_processPDF($publication);
-               }
-
-       }
-
-       public static function _processPDF($publication)
-       {
-               $fluidbook = new CubeIT_Services_Fluidbook();
-               // Login
-               $fluidbook->login($publication['user'], 'Jvia*qpkMydh6tZ#euGa');
-               // Crée un nouveau fluidbook
-               $book_id = $fluidbook->createBook($publication['name'], $publication['from']);
-               // Upload le document
-               echo $fluidbook->uploadPDF($book_id, $publication['spl'])->getBody();
-               // Delete PDF
-
-               unlink($publication['spl']->getPathname());
-       }
-
-       public static function nwbuild($args)
-       {
-               wsPackager::package(16200, 'win-exe-html');
-       }
-
-       public static function gpu()
-       {
-               global $core;
-               $r = $core->con->select('SELECT DISTINCT rgpu FROM gpu_log');
-               while ($r->fetch()) {
-                       echo $r->rgpu . ' : <b>' . file_get_contents('https://workshop.fluidbook.com/services/gup?gup=' . base64_encode($r->rgpu)) . '</b><br>';
-               }
-       }
+            }
+
+            $res .= "\n" . '</svg>';
+            file_put_contents(WS_ICONS . '/' . $iconSet . '/interface.svg', $res);
+        }
+    }
+
+    public static function installAtlanticCommunicationBook()
+    {
+        $exporter = new wsExporter();
+        $exporter->export(15316, $x, 'install_ftp', 'online', "atlanticki-01:Tjz3N85h@ftp.cluster023.hosting.ovh.net/www/", '');
+        header('Location: http://www.atlantic-international-book-com.com/');
+        exit;
+    }
+
+    public static function installWescoVentes()
+    {
+        $exporter = new wsExporter();
+        $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;
+    }
+
+    public static function fixStats($args)
+    {
+        commonDroits::min(5);
+        $book = trim($args[0], ' .');
+        if (!$book) {
+            return false;
+        }
+        $book = intval($book);
+        if ($book <= 1000) {
+            return false;
+        }
+
+        `rm -rf /home/stats/www/objects/$book*;/home/stats/www/FWStats.sh /home/stats/www redobook=$book`;
+    }
+
+    public static function processInbox()
+    {
+
+        $base = WS_FILES . '/INBOX/';
+
+        $files = CubeIT_Files::getRecursiveDirectoryIterator($base);
+
+        $publications = array();
+
+        foreach ($files as $file) {
+            /* @var $file SplFileInfo */
+            if ($file->isDir() || $file->getExtension() != 'pdf') {
+                continue;
+            }
+
+            $p = str_replace($base, '', $file->getPathname());
+            $e = explode('/', $p, 3);
+            $user = $e[0];
+            $from = $e[1];
+            $name = $file->getFilename();
+
+            $publications[] = array('spl' => $file, 'user' => $user, 'from' => $from, 'name' => $name);
+        }
+
+        foreach ($publications as $publication) {
+            self::_processPDF($publication);
+        }
+
+    }
+
+    public static function _processPDF($publication)
+    {
+        $fluidbook = new CubeIT_Services_Fluidbook();
+        // Login
+        $fluidbook->login($publication['user'], 'Jvia*qpkMydh6tZ#euGa');
+        // Crée un nouveau fluidbook
+        $book_id = $fluidbook->createBook($publication['name'], $publication['from']);
+        // Upload le document
+        echo $fluidbook->uploadPDF($book_id, $publication['spl'])->getBody();
+        // Delete PDF
+
+        unlink($publication['spl']->getPathname());
+    }
+
+    public static function nwbuild($args)
+    {
+        wsPackager::package(16200, 'win-exe-html');
+    }
+
+    public static function gpu()
+    {
+        global $core;
+        $r = $core->con->select('SELECT DISTINCT rgpu FROM gpu_log');
+        while ($r->fetch()) {
+            echo $r->rgpu . ' : <b>' . file_get_contents('https://workshop.fluidbook.com/services/gup?gup=' . base64_encode($r->rgpu)) . '</b><br>';
+        }
+    }
 }
 
 
index 0f6ec1acaa9021cb98374280ac39b49d4e002adb..5c179da032b21fb813484958ff3e78a14b1cfb1c 100644 (file)
@@ -395,9 +395,9 @@ class wsBookParametres extends wsParametres
             ]
         ];
         $this->fields['tabsMargin'] = ['type' => 'float', 'label' => __('Marge des onglets'), 'editable' => true, 'default' => '-10', 'grade' => 5, 'hint' => __('Une marge négative = les onglets passent sous la publication')];
-        $this->fields['tabsLinkWidth'] = ['type' => 'float', 'label' => __('Largeur des onglets'), 'editable' => true, 'default' => '100', 'grade' => 5];
+        $this->fields['tabsLinkWidth'] = ['type' => 'float', 'label' => __('Largeur des onglets'), 'editable' => true, 'default' => '100', 'grade' => 5, 'hint' => __('Largeur réservée pour les onglets et largeur de la zone cliquable des liens')];
         $this->forms['tabs'] = ['label' => __('Onglets'),
-            'fieldsnames' => ['tabsHTML5', 'tabsPages', 'tabsSections', 'tabsPagesNumbers', '|', 'tabsSide', 'tabsMargin', 'tabsLinkWidth', '|', 'tabsHideOnCover', 'tabsHideOnLastPage', 'tabsHideEdges', '|', 'tabsPriority', 'tabsHideWhenOverlapingArrows', 'tabsHideOnPortrait', 'tabsHideOnZoom']];
+            'fieldsnames' => ['tabsHTML5', 'tabsPages', 'tabsSections', 'tabsPagesNumbers', '|', 'tabsSide', 'tabsMargin', '|', 'tabsHideOnCover', 'tabsHideOnLastPage', 'tabsHideEdges', '|', 'tabsPriority', 'tabsLinkWidth', 'tabsHideWhenOverlapingArrows', 'tabsHideOnPortrait', 'tabsHideOnZoom']];
 
         $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);