]> _ Git - cubeextranet.git/commitdiff
(no commit message)
authorvincent@cubedesigners.com <vincent@cubedesigners.com@f5622870-0f3c-0410-866d-9cb505b7a8ef>
Thu, 9 Jan 2014 13:08:39 +0000 (13:08 +0000)
committervincent@cubedesigners.com <vincent@cubedesigners.com@f5622870-0f3c-0410-866d-9cb505b7a8ef>
Thu, 9 Jan 2014 13:08:39 +0000 (13:08 +0000)
inc/ws/Controlleur/class.ws.maintenance.php

index b3e1e3702996d32b081eaac9e75b32dc4629b736..bbcac4f28c550c7bfa07050f094a741cd3ce60c1 100644 (file)
-<?php\r
-\r
-class wsMaintenance {\r
-\r
-       public static function in($args) {\r
-               $args = cubePage::getArgs($args);\r
-               $f = array_shift($args);\r
-               $callback = array('wsMaintenance', $f);\r
-               if (is_callable($callback)) {\r
-                       return call_user_func($callback, $args);\r
-               }\r
-       }\r
-\r
-       public static function initCompositionVersions($args) {\r
-               global $core;\r
-               $dao = new wsDAOBook($core->con);\r
-\r
-               $r = $core->con->select('SELECT * FROM books ORDER by book_id');\r
-               while ($r->fetch()) {\r
-                       $dao->saveCompositionVersion($r->book_id, $r->composition_update);\r
-               }\r
-       }\r
-\r
-       public static function setCID() {\r
-               global $core;\r
-               $dao = new wsDAOBook($core->con);\r
-\r
-               $r = $core->con->select('SELECT book_id FROM books WHERE cid=\'\'');\r
-               $c = $core->con->openCursor('books');\r
-               while ($r->fetch()) {\r
-                       $c->cid = $dao->generateCID();\r
-                       $c->update('WHERE book_id=\'' . $core->con->escape($r->book_id) . '\'');\r
-               }\r
-       }\r
-\r
-       public static function compactLinks() {\r
-               global $core;\r
-               $r = $core->con->select('SELECT * FROM `document_links_versions` GROUP BY document_id,links,rulers');\r
-               $keep = array();\r
-               while ($r->fetch()) {\r
-                       if (!isset($keep[$r->document_id])) {\r
-                               $keep[$r->document_id] = array();\r
-                       }\r
-                       $keep[$r->document_id][] = $r->update;\r
-               }\r
-\r
-               foreach ($keep as $document_id => $dates) {\r
-                       $core->con->execute('DELETE FROM document_links_versions WHERE document_id=' . $document_id . ' AND `update` NOT IN(' . implode(',', $dates) . ')');\r
-               }\r
-       }\r
-\r
-       public static function checkSerializeLinks() {\r
-               global $core;\r
-               $r = $core->con->select('SELECT * FROM document_links_versions');\r
-               while ($r->fetch()) {\r
-                       if (substr($r->links, 1, 1) == ':') {\r
-                               $links = unserialize($r->links);\r
-                               $rulers = unserialize($r->rulers);\r
-                               $c = $core->con->openCursor('document_links_versions');\r
-                               $c->rulers = json_encode($rulers);\r
-                               $c->links = json_encode($links);\r
-                               $c->update('WHERE document_id=' . $r->document_id . ' AND `update`=' . $r->update);\r
-                       }\r
-               }\r
-       }\r
-\r
-       public static function moveLinksToVersionDB() {\r
-               global $core;\r
-               $r = $core->con->select('SELECT * FROM document_links');\r
-               $d = array();\r
-               while ($r->fetch()) {\r
-                       if (!isset($d[$r->document_id])) {\r
-                               $d[$r->document_id] = array();\r
-                       }\r
-                       if (!isset($d[$r->document_id][$r->update])) {\r
-                               $d[$r->document_id][$r->update] = array();\r
-                       }\r
-                       if (!isset($d[$r->document_id][$r->update][$r->document_page])) {\r
-                               $d[$r->document_id][$r->update]['links'][$r->document_page] = json_decode($r->links);\r
-                               $d[$r->document_id][$r->update]['rulers'][$r->document_page] = json_encode($r->rulers);\r
-                       }\r
-               }\r
-\r
-               $c = $core->con->openCursor('document_links_versions');\r
-               foreach ($d as $document_id => $updates) {\r
-                       $c->document_id = $document_id;\r
-                       foreach ($updates as $date => $dummy) {\r
-                               $c->update = $date;\r
-                               $c->links = json_encode($d[$document_id][$date]['links']);\r
-                               $c->rulers = json_encode($d[$document_id][$date]['rulers']);\r
-                               try {\r
-                                       $c->insert();\r
-                               } catch (Exception $e) {\r
-                                       // fb($e);\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-\r
-       public static function importFromOldWS($args) {\r
-               global $core;\r
-               // Import des fluidbooks\r
-               // Donc le dernier importé est le max dont le numéro est inférieur à 10000\r
-               $r = $core->con->select('SELECT MAX(book_id) AS book_id FROM books WHERE book_id<10000');\r
-               $lastImported = $r->book_id;\r
-               // On recherche maintenant les fluidbook dans la vieille base\r
-               $r = $core->con->select('SELECT bid FROM ws.book WHERE bid>' . $lastImported);\r
-               $oldBooks = array();\r
-               while ($r->fetch()) {\r
-                       $oldBooks[] = $r->bid;\r
-               }\r
-\r
-               if (count($oldBooks)) {\r
-                       self::importLangs($oldBooks);\r
-                       self::importThemes($oldBooks);\r
-                       self::importDocs($oldBooks);\r
-                       self::importBooks($oldBooks);\r
-               }\r
-               $core->refreshWSUsersTree();\r
-       }\r
-\r
-       public static function importLangs($oldBooks) {\r
-               global $core, $allTrads, $trads;\r
-               // On regarde d'abord les langues que nous avons déjà\r
-               $r = $core->con->select('SELECT lang_id FROM langues');\r
-               $already = array();\r
-               while ($r->fetch()) {\r
-                       $already[] = $r->lang_id;\r
-               }\r
-\r
-               $toImport = array();\r
-               $r = $core->con->select('SELECT DISTINCT lang FROM ws.book WHERE bid ' . self::_sqlIn($oldBooks));\r
-               while ($r->fetch()) {\r
-                       $idl = self::_getLangCode($r->lang);\r
-                       if (in_array($idl, $already)) {\r
-                               continue;\r
-                       }\r
-                       if (strlen($idl) > 2) {\r
-                               continue;\r
-                       }\r
-                       $toImport[] = $r->lang;\r
-               }\r
-\r
-               $allTrads = array();\r
-               $trad = array();\r
-               $r = $core->con->select('SELECT * FROM ws.lang_trad,ws.lang_ord WHERE lang_trad.idlt=lang_ord.idlt AND idl ' . self::_sqlIn($toImport) . ' ');\r
-               while ($r->fetch()) {\r
-                       $idl = self::_getLangCode($r->idl);\r
-                       if (!isset($trad[$idl])) {\r
-                               $trad[$idl] = array();\r
-                       }\r
-                       $trad[$idl][$r->ord] = $r->text;\r
-               }\r
-\r
-               foreach ($trad as $idl => $t) {\r
-                       $traductions = wsLang::getTraductionWithId($trad[$idl]);\r
-                       $allTrads[$idl] = $traductions;\r
-               }\r
-\r
-               if (!count($toImport)) {\r
-                       return;\r
-               }\r
-\r
-               foreach ($toImport as $idl) {\r
-                       $idl = self::_getLangCode($idl);\r
-\r
-                       $c = $core->con->openCursor('langues');\r
-                       $c->lang_id = $idl;\r
-                       $c->charset = 'Latin1';\r
-                       $c->font = 'Fluidbook.otf';\r
-                       $c->traductions = json_encode($allTrads[$idl]);\r
-                       $c->insert();\r
-               }\r
-       }\r
-\r
-       public static function importThemes($oldBooks) {\r
-               global $core, $signatures;\r
-\r
-               $r = $core->con->select('SELECT tid,sigid FROM ws.theme');\r
-               while ($r->fetch()) {\r
-                       $signatures[$r->tid] = $r->sigid;\r
-               }\r
-\r
-               $r = $core->con->select('SELECT MAX(theme_id) AS theme_id FROM themes WHERE theme_id<1000');\r
-               $lastImported = $r->theme_id;\r
-               // Import des thèmes\r
-               $r = $core->con->select('SELECT * FROM ws.theme WHERE tid IN (SELECT tid FROM ws.book WHERE bid ' . self::_sqlIn($oldBooks) . ') AND tid>' . $lastImported);\r
-               $theme = new wsTheme();\r
-               while ($r->fetch()) {\r
-                       $tid = $r->tid;\r
-\r
-                       $c = $core->con->openCursor('themes');\r
-                       $c->theme_id = $r->tid;\r
-                       $c->proprietaire = self::_getWsUser($r->proprietaire);\r
-                       $c->date = $r->date;\r
-                       $c->nom = $r->titre;\r
-\r
-                       $parametres = new wsThemeParametres($theme);\r
-                       $parametres->fromRecord($r);\r
-                       self::_oldIconesToColor($r->iid, $parametres);\r
-                       $c->parametres = serialize($parametres);\r
-                       $c->insert();\r
-\r
-                       $dest = WS_THEMES . '/' . $tid . '/';\r
-                       if (!file_exists($dest)) {\r
-                               mkdir($dest, 0777, true);\r
-                       }\r
-\r
-                       `/bin/cp -r /home/ws/www/themes/$tid/* $dest`;\r
-               }\r
-       }\r
-\r
-       public static function importDocs($oldBooks) {\r
-               global $core;\r
-               // On cherche maintenant à savoir si l'on doit importer de nouveaux documents associés\r
-               $oldDocuments = array();\r
-               $r = $core->con->select('SELECT DISTINCT did FROM ws.book_pages WHERE bid ' . self::_sqlIn($oldBooks) . '');\r
-               while ($r->fetch()) {\r
-                       $oldDocuments[] = $r->did;\r
-               }\r
-\r
-               if (!count($oldDocuments)) {\r
-                       return;\r
-               }\r
-\r
-               $r = $core->con->select('SELECT * FROM ws.document WHERE did ' . self::_sqlIn($oldDocuments) . ' ORDER BY did');\r
-               while ($r->fetch()) {\r
-                       $c = $core->con->openCursor('documents');\r
-                       $c->document_id = $r->did;\r
-                       $c->pages = $r->pages;\r
-                       $c->version = 1;\r
-                       try {\r
-                               $c->insert();\r
-                       } catch (Exception $e) {\r
-                               fb($e);\r
-                       }\r
-               }\r
-       }\r
-\r
-       public static function copyLinks($args) {\r
-               list($from, $to) = $args;\r
-               global $core;\r
-\r
-               $dao = new wsDAODocument($core->con);\r
-\r
-               $dao->getLinksAndRulers($from, $fromlinks, $fromrulers);\r
-               $dao->getLinksAndRulers($to, $tolinks, $torulers);\r
-\r
-               $tolinks = array_merge($tolinks, $fromlinks);\r
-               $torulers = array_merge($torulers, $fromrulers);\r
-\r
-               $dao->setLinksAndRulers($to, $tolinks, $torulers, 'Copy links from #' . $from . '  to #' . $to, $core->user->utilisateur_id);\r
-       }\r
-\r
-       public static function importBooks($oldBooks) {\r
-               global $core, $allTrads, $signatures;\r
-               // Importe les fluidbooks\r
-               $r = $core->con->select('SELECT * FROM ws.book WHERE bid ' . self::_sqlIn($oldBooks) . ' ORDER BY bid');\r
-               if (!$r->count()) {\r
-                       return;\r
-               }\r
-               // .\r
-               while ($r->fetch()) {\r
-                       $c = $core->con->openCursor('books');\r
-                       $c->book_id = $r->bid;\r
-                       $c->nom = $r->titre;\r
-                       $c->lang = substr(self::_getLangCode($r->lang), 0, 2);\r
-                       $c->theme = $r->tid;\r
-                       if (strlen($r->lang) > 2) {\r
-                               $c->traductions = json_encode($allTrads[self::_getLangCode($r->lang)]);\r
-                       } else {\r
-                               $c->traductions = '';\r
-                       }\r
-                       $c->proprietaire = self::_getWsUser($r->uid);\r
-                       $c->status = $r->status;\r
-                       $c->date_status = $r->date_status;\r
-                       $c->hash = $r->code;\r
-                       $c->compteur_visites = 20;\r
-                       $c->date = $r->date;\r
-                       $c->syncv1 = 1;\r
-                       $c->version = 1;\r
-                       $parametres = new wsBookParametres(new stdClass());\r
-                       $parametres->fromRecord($r);\r
-\r
-                       $xml = @simplexml_load_string('<extras>' . $r->extras . '</extras>');\r
-                       if ($xml !== false) {\r
-                               $parametres->fromXML($xml);\r
-                       } else {\r
-                               \r
-                       }\r
-\r
-                       $n = array();\r
-                       // Pages sans numéro\r
-                       $offset = $r->first_page_nr - 1;\r
-                       for ($i = 0; $i < $offset; $i++) {\r
-                               $n[] = '';\r
-                       }\r
-                       // Pages avec numero\r
-                       for ($j = 1; $j + $offset <= $r->pages; $j++) {\r
-                               $n[] = $j;\r
-                       }\r
-                       $c->numerotation = implode(',', $n);\r
-\r
-                       $parametres->signature = $signatures[$r->tid];\r
-                       $parametres->title = $r->titre;\r
-                       $parametres->visualisationMode = '2';\r
-                       $c->parametres = serialize($parametres);\r
-                       $c->version = 1;\r
-                       $c->insert();\r
-               }\r
-               // Import des pages\r
-               $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));\r
-\r
-               $dao = new wsDAOBook($core->con);\r
-               foreach ($oldBooks as $book_id) {\r
-                       $dao->saveCompositionVersion($book_id);\r
-               }\r
-       }\r
-\r
-       protected static function _oldIconesToColor($iid, &$parametres) {\r
-               global $oldIconesColors;\r
-               if (!isset($oldIconesColors)) {\r
-                       $oldIconesColors = array();\r
-                       $fp = fopen(dirname(__FILE__) . '/../../../icones.csv', 'rb');\r
-                       $i = 1;\r
-                       while ($line = fgetcsv($fp, 1000, ';', '"')) {\r
-                               $oldIconesColors[$i] = array('color' => trim($line[0]), 'iid' => trim($line[1]));\r
-                               $i++;\r
-                       }\r
-               }\r
-               $line = $oldIconesColors[$iid];\r
-               if ($line['iid'] != '') {\r
-                       $parametres->iconSet = $line['iid'];\r
-                       $parametres->iconsHMargin = $line['iid'] == 1 ? 20 : 0;\r
-                       $parametres->menuHeight = 39;\r
-                       $parametres->colorizeIcons = false;\r
-                       $parametres->couleurI = 'ffffff';\r
-               } else {\r
-                       $parametres->iconSet = 1;\r
-                       $parametres->colorizeIcons = 1;\r
-                       $parametres->iconsHMargin = 20;\r
-                       $parametres->menuHeight = 39;\r
-                       $parametres->couleurI = $line['color'];\r
-               }\r
-       }\r
-\r
-       protected static function _getWsUser($oldid) {\r
-               global $ws2ext;\r
-               if (!isset($ws2ext)) {\r
-                       self::_getAllUsers();\r
-               }\r
-               if (!isset($ws2ext[$oldid])) {\r
-                       self::_importOldUser($oldid);\r
-               }\r
-               if (!isset($ws2ext[$oldid])) {\r
-                       $ws2ext[$oldid] = 1;\r
-               }\r
-               return $ws2ext[$oldid];\r
-       }\r
-\r
-       protected static function _getAllUsers() {\r
-               global $core, $entreprises, $entreprise_id, $utilisateurs_entreprises, $utilisateur_id, $ws2ext, $grades, $utilisateurs;\r
-               $grades = array(0 => 1, 0.4 => 1, '0.4' => 1, 0.5 => 1, '0.5' => 1, 1 => 1, 2 => 2, 3 => 3, 4 => 5);\r
-               // Contrôle des entreprises déjà dans la base extranet\r
-               $entreprises = array();\r
-               $entreprise_id = 0;\r
-               $r = $core->con->select('SELECT entreprise_id,nom FROM entreprises');\r
-               while ($r->fetch()) {\r
-                       $nom = mb_strtolower(trim($r->nom));\r
-                       $nom = cubeText::str2URL($nom);\r
-                       $entreprises[$nom] = $r->entreprise_id;\r
-                       $entreprise_id = max($entreprise_id, $r->entreprise_id);\r
-               }\r
-\r
-               $utilisateurs_entreprises = array();\r
-               $r = $core->con->select('SELECT entreprise,utilisateur_id FROM utilisateurs');\r
-               while ($r->fetch()) {\r
-                       $utilisateurs_entreprises[$r->utilisateur_id] = $r->entreprise;\r
-               }\r
-\r
-               $entreprise_id++;\r
-               // Obtient les emails des utilisateurs\r
-               $utilisateur_id = 0;\r
-               $utilisateurs = array();\r
-               $r = $core->con->select('SELECT utilisateur_id,email FROM utilisateurs');\r
-               while ($r->fetch()) {\r
-                       $utilisateur_id = max($r->utilisateur_id, $utilisateur_id);\r
-                       $utilisateurs[trim(mb_strtolower($r->email))] = $r->utilisateur_id;\r
-               }\r
-               $utilisateur_id++;\r
-\r
-               $ws2ext = array();\r
-               $r = $core->con->select('SELECT ws_id,utilisateur_id,entreprise FROM utilisateurs WHERE ws_id IS NOT NULL');\r
-               while ($r->fetch()) {\r
-                       $ws2ext[$r->ws_id] = $r->utilisateur_id;\r
-               }\r
-       }\r
-\r
-       protected static function _importOldUser($oldid) {\r
-               global $core, $entreprises, $entreprise_id, $utilisateurs_entreprises, $utilisateur_id, $ws2ext, $grades, $utilisateurs;\r
-               // Get user from old\r
-               $r = $core->con->select('SELECT * FROM ws.user WHERE uid=\'' . $core->con->escape($oldid) . '\'');\r
-               if ($r->extranet != 0) {\r
-                       $ws2ext[$r->uid] = $r->extranet;\r
-                       return;\r
-               }\r
-               // On s'occupe de l'entreprise\r
-               $email = trim(mb_strtolower($r->email));\r
-\r
-               $rs = trim($r->rs);\r
-               if ($rs == '') {\r
-                       $rs = trim($r->prenom . ' ' . $r->nom);\r
-               }\r
-               $nom = mb_strtolower($rs);\r
-\r
-               $nom = cubeText::str2URL($nom);\r
-\r
-               if (isset($utilisateurs[$email])) {\r
-                       $newid = $utilisateurs[$email];\r
-                       $e = $utilisateurs_entreprises[$newid];\r
-                       $update = true;\r
-               } elseif (isset($entreprises[$nom])) {\r
-                       $e = $entreprises[$nom];\r
-                       $update = true;\r
-               } else {\r
-                       $c = $core->con->openCursor('entreprises');\r
-                       $c->entreprise_id = $entreprise_id;\r
-                       $c->nom = $rs;\r
-                       $c->adresse = $r->adresse;\r
-                       $c->code_postal = $r->code_postal;\r
-                       $c->ville = $r->ville;\r
-                       $c->pays = $r->pays;\r
-                       $c->date_creation = $r->date;\r
-                       $c->ws_grade = $grades[$r->grade];\r
-                       $c->ws_admin = self::_getWsUser($r->admin);\r
-                       $c->insert();\r
-                       $e = $entreprises[$nom] = $entreprise_id;\r
-                       $entreprise_id++;\r
-                       $update = false;\r
-               }\r
-\r
-               if ($update) {\r
-                       $c = $core->con->openCursor('entreprises');\r
-                       $c->ws_grade = $grades[$r->grade];\r
-                       $c->ws_admin = self::_getWsUser($r->admin);\r
-                       $c->update('WHERE entreprise_id=\'' . $e . '\'');\r
-               }\r
-               // Puis de l'utilisateur\r
-               if (isset($utilisateurs[$email])) {\r
-                       $c = $core->con->openCursor('utilisateurs');\r
-                       $c->ws_password = $r->password;\r
-                       $c->ws_id = $r->uid;\r
-                       $c->update('WHERE utilisateur_id=\'' . $utilisateurs[$email] . '\'');\r
-                       $ws2ext[$r->uid] = $utilisateurs[$email];\r
-                       $utilisateurs_entreprises[$utilisateurs[$email]] = $e;\r
-               } else {\r
-                       $c = $core->con->openCursor('utilisateurs');\r
-                       $c->utilisateur_id = $utilisateur_id;\r
-                       $c->entreprise = $e;\r
-                       $c->nom = $r->nom;\r
-                       $c->prenom = $r->prenom;\r
-                       $c->email = $r->email;\r
-                       $c->password = $r->password;\r
-                       $c->adresse = $r->adresse;\r
-                       $c->code_postal = $r->code_postal;\r
-                       $c->ville = $r->ville;\r
-                       $c->pays = $r->pays;\r
-                       $c->lang = $r->lang;\r
-                       $c->telephone = $r->telephone;\r
-                       $c->date_creation = $r->date;\r
-                       $c->notes = 'Inséré à l\'import vers le nouveau Fluidbook Workshop';\r
-                       $c->ws_password = $r->password;\r
-                       $c->ws_id = $r->uid;\r
-                       $c->insert();\r
-                       $ws2ext[$r->uid] = $utilisateur_id;\r
-                       $utilisateurs_entreprises[$utilisateur_id] = $e;\r
-                       $utilisateur_id++;\r
-               }\r
-       }\r
-\r
-       protected static function _sqlIn($tab) {\r
-               return ' IN(\'' . implode('\',\'', $tab) . '\') ';\r
-       }\r
-\r
-       protected static function _getLangCode($lang) {\r
-               $lang = strtolower($lang);\r
-               if ($lang == 'cz') {\r
-                       $lang = 'cs';\r
-               }\r
-               return $lang;\r
-       }\r
-\r
-       public static function dumpDatabase() {\r
-               cubeDb::mysqlDump(DB_HOST, DB_NAME, DB_USER, DB_PASSWORD, ROOT . '/backups/dump-' . date('Y-m-d-H-i-s') . '.sql', true, 8);\r
-       }\r
-\r
-       public static function cleanPackages() {\r
-               $limit = TIME - (4 * 3600); // 4 heures avant maintenant*\r
-               //\r
-               $dirs = array(ROOT . '/cache/download',\r
-                       WS_FILES . '/packager/download/',\r
-                       WS_FILES . '/packager/',\r
-                       '/home/ws/www/download');\r
-               // Clean downloads\r
-\r
-               foreach ($dirs as $dir) {\r
-                       if (!file_exists($dir)) {\r
-                               continue;\r
-                       }\r
-                       $dr = opendir($dir);\r
-                       while ($file = readdir($dr)) {\r
-                               if ($file == '.' || $file == '..') {\r
-                                       continue;\r
-                               }\r
-                               $f = $dir . $file;\r
-                               if (!is_dir($f)) {\r
-                                       continue;\r
-                               }\r
-                               if (filemtime($f) > $limit) {\r
-                                       continue;\r
-                               }\r
-                               `rm -rf $f`;\r
-                       }\r
-\r
-                       if (!file_exists($dir)) {\r
-                               mkdir($dir, 0777, true);\r
-                       }\r
-               }\r
-       }\r
-\r
-       public static function cleanConversionSessions() {\r
-               $limit = TIME - (4 * 3600); // 4 heures avant maintenant*\r
-\r
-               $dir = ROOT . '/cache/conversionSessions/';\r
-               $dr = opendir($dir);\r
-               while ($file = readdir($dr)) {\r
-                       if ($file == '.' || $file == '..') {\r
-                               continue;\r
-                       }\r
-                       $f = $dir . $file;\r
-                       if (filemtime($f) > $limit) {\r
-                               continue;\r
-                       }\r
-                       unlink($f);\r
-               }\r
-       }\r
-\r
-       public static function cleanUnusedDocs() {\r
-               global $core;\r
-               cubePHP::neverStop();\r
-               $r = $core->con->select('SELECT document_id FROM documents WHERE document_id NOT IN (SELECT document_id FROM book_pages)');\r
-               while ($r->fetch()) {\r
-                       if (file_exists(WS_DOCS . '/' . $r->document_id)) {\r
-                               $rm = new cubeCommandLine('rm');\r
-                               $rm->setPath(CONVERTER_PATH);\r
-                               $rm->setArg('r');\r
-                               $rm->setArg('f');\r
-                               $rm->setArg(null, WS_DOCS . '/' . $r->document_id . '/');\r
-                               $rm->execute();\r
-                               echo $rm->commande . "<br />";\r
-                       }\r
-               }\r
-       }\r
-\r
-       public static function moveFluidbookDatas() {\r
-               $dir = WS_BOOKS . '/final/';\r
-               $dr = opendir($dir);\r
-               while ($d = readdir($dr)) {\r
-                       if ($d == '.' || $d == '..' || !is_dir($dir . $d)) {\r
-                               continue;\r
-                       }\r
-                       rename($dir . $d . '/FluidbookDatas.swf', $dir . $d . '/data/fd.swf');\r
-                       rename($dir . $d . '/FluidbookDatasLight.swf', $dir . $d . '/data/fdl.swf');\r
-               }\r
-       }\r
-\r
-       public static function mergeEntreprise($args) {\r
-               global $core;\r
-\r
-               $from = $args[0];\r
-               $to = $args[1];\r
-\r
-               $c = $core->con->openCursor('utilisateurs');\r
-               $c->entreprise = $to;\r
-               $c->update('WHERE entreprise=' . $from);\r
-\r
-               $core->con->execute('DELETE FROM entreprises WHERE entreprise_id=' . $from);\r
-\r
-               $core->refreshWSUsersTree();\r
-       }\r
-\r
-       public static function updateLuceneTime() {\r
-               global $core;\r
-               $dao = new wsDAOBook($core->con);\r
-               $books = $dao->selectLuceneTimeNotSet();\r
-               foreach ($books as $book) {\r
-                       $index = WS_BOOKS . '/search/' . $book->book_id;\r
-                       if (!file_exists($index)) {\r
-                               fb($book->book_id, 'Skip');\r
-                               continue;\r
-                       }\r
-\r
-                       $mtime = 0;\r
-                       $dr = opendir($index);\r
-                       while ($file = readdir($dr)) {\r
-                               if ($file == '.' || $file == '..') {\r
-                                       continue;\r
-                               }\r
-                               $mtime = max($mtime, filemtime($index . '/' . $file));\r
-                       }\r
-\r
-                       $c = $core->con->openCursor('books');\r
-                       $c->lucene_time = $mtime;\r
-                       $c->update('WHERE book_id=' . $book->book_id);\r
-\r
-                       fb($book->book_id, 'Update : ' . $mtime);\r
-               }\r
-       }\r
-\r
-       public static function makeLuceneIndexes() {\r
-               global $core;\r
-\r
-               cubePHP::neverStop();\r
-\r
-               $dao = new wsDAOBook($core->con);\r
-               $books = $dao->selectLuceneToDo();\r
-               foreach ($books as $book) {\r
-                       $pages = $dao->getPagesOfBook($book->book_id);\r
-                       $dao->indexPDF($book, $pages);\r
-               }\r
-       }\r
-\r
-       public static function restoreComposition($args) {\r
-               global $core;\r
-               $book_id = $args[0];\r
-\r
-               $r = $core->con->select('SELECT * FROM book_pages_versions WHERE book_id=\'' . $core->con->escape($book_id) . '\' AND composition!=\'a:0:{}\' ORDER BY `update` DESC LIMIT 1');\r
-               if (!$r->count()) {\r
-                       return;\r
-               }\r
-\r
-               $comp = unserialize($r->composition);\r
-               $core->con->execute('DELETE FROM book_pages WHERE book_id=\'' . $core->con->escape($book_id) . '\'');\r
-\r
-               $c = $core->con->openCursor('book_pages');\r
-               $c->book_id = $book_id;\r
-               foreach ($comp as $book_page => $infos) {\r
-                       $c->book_page = $book_page;\r
-                       $c->document_id = $infos['document_id'];\r
-                       $c->document_page = $infos['document_page'];\r
-                       $c->insert();\r
-               }\r
-       }\r
-\r
-       public static function getV1Translations() {\r
-               wsLang::getV1Translations();\r
-       }\r
-\r
-       public static function appendDocument($args) {\r
-               global $core;\r
-               $book_id = $args[0];\r
-               $document_id = $args[1];\r
-               $dao = new wsDAOBook($core->con);\r
-               $dao->appendDocument($book_id, $document_id);\r
-       }\r
-\r
-       public static function reprocessVideos($args) {\r
-               global $core;\r
-\r
-               $book_id = $args[0];\r
-\r
-               $dir = WS_BOOKS . '/working/' . $book_id;\r
-\r
-               $dao = new wsDAODocument($core->con);\r
-               $dao->getLinksAndRulers($book_id, $links, $rulers);\r
-\r
-               foreach ($links as $link) {\r
-                       if ($link['type'] != 4) {\r
-                               continue;\r
-                       }\r
-\r
-                       $file = $dir . '/' . $link['to'];\r
-                       if (!file_exists($file)) {\r
-                               continue;\r
-                       }\r
-\r
-                       wsTools::encodeWebVideos($file, null, true, true);\r
-               }\r
-       }\r
-\r
-       public static function syncLDAP() {\r
-               global $core;\r
-               cubePHP::neverStop();\r
-\r
-               $res = '<pre>';\r
-\r
-               $ds = ldap_connect('localhost', 10389);\r
-               ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);\r
-               ldap_bind($ds, 'uid=admin,ou=system', '*arica*6');\r
-\r
-               $r = $core->con->select('SELECT * FROM utilisateurs_entreprise ORDER BY utilisateur_id');\r
-               while ($r->fetch()) {\r
-                       if (is_null($r->utilisateur_id)) {\r
-                               continue;\r
-                       }\r
-                       $entree = array();\r
-                       $entree['objectClass'][] = 'top';\r
-                       $entree['objectClass'][] = 'person';\r
-                       $entree['objectClass'][] = 'organizationalPerson';\r
-                       $entree['objectClass'][] = 'extensibleObject';\r
-                       $entree['cn'] = trim($r->prenom . ' ' . $r->nom . ' - ' . $r->rs . ' (' . $r->utilisateur_id . ')', ' -');\r
-                       $entree['sn'] = $r->nom == '' ? $entree['cn'] : $r->nom;\r
-                       $entree['mail'] = $r->email;\r
-                       $entree['uid'] = 'extranet_' . $r->utilisateur_id;\r
-                       $entree['OrganizationalUnitName'] = $r->rs;\r
-                       if ($r->telephone && $r->telephone != '+33') {\r
-                               $entree['telephoneNumber'][] = $r->telephone;\r
-                       }\r
-                       if ($r->mobile && $r->mobile != '+33') {\r
-                               $entree['telephoneNumber'][] = $r->mobile;\r
-                       }\r
-                       if ($r->fax && $r->fax != '+33') {\r
-                               $entree['telexNumber'] = $r->fax;\r
-                       }\r
-                       $dn = 'uid=' . $entree['uid'] . ',o=cubedesigners';\r
-                       if (!ldap_add($ds, $dn, $entree)) {\r
-                               $e = ldap_error($ds);\r
-                               if ($e == 'Already exists') {\r
-                                       ldap_modify($ds, $dn, $entree);\r
-                               } else {\r
-                                       fb($entree, $e);\r
-                               }\r
-                       }\r
-               }\r
-               $res = 'test';\r
-               $res.='</pre>';\r
-\r
-               ldap_close($ds);\r
-               return $res;\r
-       }\r
-\r
-       public static function updateHTML5Sources($args = array(), $externals = true) {\r
-               $svn = new cubeCommandLine('updatewshtml5prod');\r
-               $svn->setPath(CONVERTER_PATH);\r
-               $svn->execute();\r
-       }\r
-\r
-       public static function cleanDownload($args) {\r
-               $root = ROOT . '/cache/download/';\r
-               cubeFiles::scanRecursiveDir($root, $files);\r
-               $limit = TIME - 14400;\r
-               foreach ($files as $f) {\r
-                       if (filemtime($f) < $limit) {\r
-                               unlink($f);\r
-                       }\r
-               }\r
-               $files = cubeFiles::scandir($root, true);\r
-               foreach ($files as $f) {\r
-                       if (cubeFiles::isEmpty($f)) {\r
-                               @rmdir($f);\r
-                       }\r
-               }\r
-       }\r
-\r
-       public static function deleteOldFilesFromFTP($args) {\r
-               global $core;\r
-               cubePHP::neverStop();\r
-\r
-               $dao = new commonDAOFichier($core->con);\r
-               $dao->deleteOldFiles();\r
-\r
-               cubeFiles::deleteFilesOlderThan('/home/ws/ftp', 60, array('*.ipa', '*.apk'));\r
-               cubeFiles::deleteFilesOlderThan('/home/ws/www/getpdf', 60);\r
-       }\r
-\r
-       public static function reencodeVideos($args) {\r
-\r
-               cubePHP::neverStop();\r
-\r
-               $book_id = $args[0];\r
-               $dir = WS_BOOKS . '/working/' . $book_id;\r
-\r
-               wsLinks::getLinksAndRulers($book_id, $links, $rulers);\r
-\r
-               foreach ($links as $link) {\r
-                       if ($link['type'] != 4) {\r
-                               continue;\r
-                       }\r
-\r
-                       $file = $dir . '/' . $link['to'];\r
-                       if (!file_exists($file)) {\r
-                               continue;\r
-                       }\r
-\r
-                       wsTools::encodeWebVideos($file, null, false, true);\r
-               }\r
-       }\r
-\r
-       public static function correctAutoBookmarkLinks($args) {\r
-               global $core;\r
-               $book_id = $args[0];\r
-               wsLinks::getLinksAndRulers($book_id, $links, $rulers);\r
-\r
-\r
-               $newlinks = array();\r
-               foreach ($links as $link) {\r
-                       $link['left']-=1;\r
-                       $link['top']+=1;\r
-                       $link['width']+=5;\r
-                       $link['height']+=3;\r
-                       $newlinks[] = $link;\r
-               }\r
-\r
-               $dao = new wsDAODocument($core->con);\r
-               $dao->setLinksAndRulers($book_id, json_encode($newlinks), json_encode($rulers), 'Autobookmark links correction', $core->user->utilisateur_id);\r
-       }\r
-\r
-}\r
-\r
+<?php
+
+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 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) {
+               list($from, $to) = $args;
+               global $core;
+
+               $dao = new wsDAODocument($core->con);
+
+               $dao->getLinksAndRulers($from, $fromlinks, $fromrulers);
+               $dao->getLinksAndRulers($to, $tolinks, $torulers);
+
+               $tolinks = array_merge($tolinks, $fromlinks);
+               $torulers = array_merge($torulers, $fromrulers);
+
+               $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 - (4 * 3600); // 4 heures avant maintenant*
+               //
+               $dirs = array(ROOT . '/cache/download',
+                       WS_FILES . '/packager/download/',
+                       WS_FILES . '/packager/',
+                       '/home/ws/www/download');
+               // 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 (!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 />";
+                       }
+               }
+       }
+
+       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 restoreComposition($args) {
+               global $core;
+               $book_id = $args[0];
+
+               $r = $core->con->select('SELECT * FROM book_pages_versions WHERE book_id=\'' . $core->con->escape($book_id) . '\' AND composition!=\'a:0:{}\' 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 updateHTML5Sources($args = array(), $externals = true) {
+               $svn = new cubeCommandLine('updatewshtml5prod');
+               $svn->setPath(CONVERTER_PATH);
+               $svn->execute();
+       }
+
+       public static function cleanDownload($args) {
+               $root = ROOT . '/cache/download/';
+               cubeFiles::scanRecursiveDir($root, $files);
+               $limit = TIME - 14400;
+               foreach ($files as $f) {
+                       if (filemtime($f) < $limit) {
+                               unlink($f);
+                       }
+               }
+               $files = cubeFiles::scandir($root, true);
+               foreach ($files as $f) {
+                       if (cubeFiles::isEmpty($f)) {
+                               @rmdir($f);
+                       }
+               }
+       }
+
+       public static function deleteOldFilesFromFTP($args) {
+               global $core;
+               cubePHP::neverStop();
+
+               $dao = new commonDAOFichier($core->con);
+               $dao->deleteOldFiles();
+
+               cubeFiles::deleteFilesOlderThan('/home/ws/ftp', 60, array('*.ipa', '*.apk'));
+               cubeFiles::deleteFilesOlderThan('/home/ws/www/getpdf', 60);
+       }
+
+       public static function reencodeVideos($args) {
+
+               cubePHP::neverStop();
+
+               $book_id = $args[0];
+               $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);
+               }
+       }
+
+       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 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);
+       }
+
+}
+
 ?>
\ No newline at end of file