class wsDAOBook extends commonDAO
{
- public static $pagesOfBookCache = array();
-
- /**
- * wsDAOBook::singleton()
- *
- * @param mixed $r
- * @return
- */
- protected function singleton($r)
- {
- $book = new wsBook();
- $book->book_id = $r->book_id;
- $book->cid = $r->cid;
- $book->nom = $r->nom;
- $book->lang = $r->lang;
- $book->theme = $r->theme;
- $book->proprietaire = $r->proprietaire_nom;
- $book->proprietaire_id = $r->proprietaire_id;
- $book->proprietaire_utilisateur = $r->proprietaire_utilisateur;
- $book->hash = $r->hash;
- $book->compteur_visites = $r->compteur_visites;
- $book->status = $r->status;
- $book->date_status = $r->date_status;
- $book->date = $r->date;
- $book->pages = array();
- $book->chapters = $r->chapters;
- $book->traductions = $r->traductions;
- $book->specialLinks = $r->specialLinks;
- $book->specialRulers = $r->specialRulers;
- $book->parametres = $r->parametres;
- $book->extras = $r->extras;
- $book->numerotation = $r->numerotation;
- $book->changedate = $r->changedate;
- $book->compiledate = $r->compiledate;
- $book->compile1date = $r->compile1date;
- $book->compilehtml5date = $r->compilehtml5date;
- $book->facturable = $r->facturable;
- $book->facturable_id = $r->facturable_id;
- $book->tache = $r->tache;
- if (isset($r->projet)) {
- $book->projet = $r->projet;
- }
- $book->version = $r->version;
- $book->composition_update = $r->composition_update;
- $book->dir_references = $r->dir_references;
- $book->dir_hosting = $r->dir_hosting;
- $book->dir_macbook_phonegap_ios = $r->dir_macbook_phonegap_ios;
- $book->dir_phonegap_android = $r->dir_phonegap_android;
- $book->dir_external = $r->dir_external;
- $book->demo_counter = $r->demo_counter;
- $book->exportdatas = $r->exportdatas;
-
- return $book;
- }
-
- protected function cree($r)
- {
- $book = new wsBook();
- $book->book_id = 'new';
- $book->nom = '';
- $book->cid = null;
- $book->lang = 'fr';
- $book->theme = 1;
- $book->proprietaire = '';
- $book->proprietaire_id = 0;
- $book->hash = '';
- $book->compteur_visites = 20;
- $book->status = 0;
- $book->date_status = TIME;
- $book->date = TIME;
- $book->composition_update = TIME;
- $book->chapters = json_encode(array());
- $book->parametres = new wsBookParametres();
- $book->tache = 0;
- $book->pages = array();
- $book->version = 2;
- return $book;
- }
-
- protected function getNextId()
- {
- $r = $this->con->select('SELECT MAX(book_id) AS book_id FROM books');
- if ($r->book_id < 10000) {
- return 10000;
- }
- return $r->book_id + 1;
- }
-
- public function saveExportDatas($book_id, $datas)
- {
- $c = $this->con->openCursor('books');
- $c->exportdatas = json_encode($datas);
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
- }
-
- public function addDemoCount($book_id)
- {
-
- $r = $this->con->select('SELECT demo_counter,nom FROM books WHERE book_id=\'' . $book_id . '\'');
- $m = 20;
- if ($r->demo_counter > 0 && $r->demo_counter % $m == 0) {
- $mail = new cubeMail();
- $mail->charset = 'UTF-8';
- $mail->from = 'contact@fluidbook.com';
- $mail->to = 'tech@fluidbook.com';
- $mail->subject = '[Fluidbook Workshop] Fluidbook consulté via l\'url publique';
- $mail->body = 'Le fluidbook suivant a été consulté ' . $m . ' fois (et ' . $r->demo_counter . ' au total) via l\'url publique : ' . "\r\n" .
- 'Fluidbook # ' . $book_id . ' - ' . $r->nom;
- $mail->send();
- }
-
- $this->con->select('UPDATE books SET demo_counter=demo_counter+1 WHERE book_id=\'' . $book_id . '\'');
- }
-
- public function selectByIds($book_ids = array(), $simple = false)
- {
- if ($simple) {
- $table = 'books';
- } else {
- $table = 'books_vue';
- }
-
- $ids = array();
- foreach ($book_ids as $bid) {
- fb($bid);
- if (intval($bid) > 0) {
- $ids[] = $bid;
- }
- }
-
- $sql = 'SELECT * FROM ' . $table . ' WHERE book_id IN (' . implode(',', $ids) . ')';
- $books = $this->factory($this->con->select($sql));
- $res = array();
- foreach ($books as $book) {
- $res[$book->book_id] = $book;
- }
- return $res;
- }
-
- public function selectById($book_id = null, $simple = false)
- {
- if (is_null($book_id)) {
- return $this->cree();
- }
- if ($simple) {
- $table = 'books';
- } else {
- $table = 'books_vue';
- }
- $sql = 'SELECT * FROM ' . $table . ' WHERE book_id=\'' . $this->con->escape($book_id) . '\' LIMIT 1';
- $r = $this->con->select($sql);
- return $this->singleton($r);
- }
-
- public function selectByCid($cid = null, $simple = false)
- {
- if ($simple) {
- $table = 'books';
- } else {
- $table = 'books_vue';
- }
-
- $sql = 'SELECT * FROM ' . $table . ' WHERE cid LIKE BINARY \'' . $this->con->escape($cid) . '\' LIMIT 1';
- $r = $this->con->select($sql);
- return $this->singleton($r);
- }
-
- public function selectLuceneToDo()
- {
- $sql = 'SELECT * FROM books_vue WHERE lucene_time<composition_update AND version=2 ORDER BY book_id ASC LIMIT 1';
- $r = $this->con->select($sql);
- return $this->factory($r);
- }
-
- public function selectLuceneTimeNotSet()
- {
- $sql = 'SELECT * FROM books_vue WHERE lucene_time=0 AND version=2';
- $r = $this->con->select($sql);
- return $this->factory($r);
- }
-
- /**
- * wsDAOBook::sauve()
- *
- * @param mixed $createur
- * @param mixed $data
- * @return
- */
- public function sauve($createur, $data)
- {
- $c = $this->con->openCursor('books');
- if (isset($data['nom'])) {
- $c->nom = $data['nom'];
- }
- if (isset($data['lang'])) {
- $c->lang = $data['lang'];
- }
- if (isset($data['theme'])) {
- $c->theme = $data['theme'];
- }
- if (isset($data['proprietaire'])) {
- $c->proprietaire = $data['proprietaire'];
- }
-
- if ($data['book_id'] == 'new' || $data['book_id'] == '') {
- $c->date = TIME;
- $c->hash = md5(rand(0, 123456789365469));
- $c->compteur_visites = 20;
- $c->parametres = serialize(new wsParametres());
- $c->changedate = TIME;
- $book_id = $c->book_id = $this->getNextId();
-
- $c->insert();
- } else {
- $c->changedate = TIME;
- $book_id = $data['book_id'];
- $c->update('WHERE book_id=\'' . $this->con->escape($data['book_id']) . '\'');
- }
-
- if (isset(self::$pagesOfBookCache[$book_id])) {
- unset(self::$pagesOfBookCache[$book_id]);
- }
-
- return $this->selectById($book_id);
- }
-
- public function duplicate($book_id, $createur, $nom = null, $pages = false, $complete = false)
- {
- $r = $this->con->select('SELECT * FROM books_vue WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
-
- $old_id = $book_id;
-
-
- $parametres = unserialize($r->parametres);
- $parametres->setParent($this);
- if (null === $nom) {
- $nom = $parametres->title;
- }
- $parametres->title = $nom;
-
- if (!$complete) {
- $parametres->pdfReplace = '';
- }
-
- $c = $this->con->openCursor('books');
- $c->proprietaire = $createur;
- $c->date = TIME;
- $c->hash = md5(rand(0, 1234567893));
- $c->cid = $this->generateCID();
- $c->compteur_visites = 20;
- $c->status = -1;
- $c->date_status = TIME;
- $c->lang = $r->lang;
- $c->parametres = serialize($parametres);
- $c->nom = $nom;
- $c->theme = $r->theme;
- $c->changedate = TIME;
- $c->compiledate = 0;
- $c->version = 2;
- $c->traductions = $r->traductions;
- $c->specialLinks = $r->specialLinks;
- $c->specialRulers = $r->specialRulers;
- $c->composition_update = TIME;
- $book_id = $c->book_id = $this->getNextId();
- if ($pages) {
- $c->numerotation = $r->numerotation;
- $c->chapters = $r->chapters;
- $this->con->execute('INSERT INTO book_pages SELECT ' . $book_id . ' AS book_id,book_page,document_id,document_page FROM book_pages WHERE book_id=' . $old_id);
- }
- if ($complete) {
- $c->numerotation = $r->numerotation;
- $c->chapters = $r->chapters;
- }
- $c->insert();
-
- $this->saveCompositionVersion($book_id);
-
- return $this->selectById($book_id);
- }
-
- public function creeEmpty($createur, $lang, $nom)
- {
- $c = $this->con->openCursor('books');
-
- $parametres = new wsBookParametres($this);
- $parametres->title = $nom;
-
- $c->proprietaire = $createur;
- $c->cid = $this->generateCID();
- $c->nom = $nom;
- $c->date = TIME;
- $c->hash = md5(rand(0, 1234567893));
- $c->compteur_visites = 20;
- $c->status = -1;
- $c->date_status = TIME;
- $c->parametres = serialize($parametres);
-
- $c->theme = 1;
- $c->lang = $lang;
- $c->changedate = TIME;
- $c->compiledate = 0;
- $c->version = 2;
- $c->composition_update = TIME;
- $book_id = $c->book_id = $this->getNextId();
- $c->insert();
- return $this->selectById($book_id);
- }
-
- public function supprime($book_id)
- {
- $this->con->execute('DELETE FROM book_pages_versions WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
- $this->con->execute('DELETE FROM book_pages WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
- return $this->con->execute('DELETE FROM books WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
- }
-
- public function count($limitedToUserRights = false)
- {
- $filters = $this->makeWhereFromFiltres();
- if ($filters == '1=1') {
- $table = 'books';
- } else {
- $table = 'books_vue';
- }
-
- $where = '(' . $filters . ')';
- $where .= $this->limitToUserRights($limitedToUserRights);
- $r = $this->con->select('SELECT COUNT(*) AS nb FROM ' . $table . ' WHERE ' . $where);
- return $r->nb;
- }
-
- public function getPagesOfBookAt($book_id, $time)
- {
- $r = $this->con->select('SELECT * FROM book_pages_versions WHERE book_id=\'' . $this->con->escape($book_id) . '\' ORDER BY `update` ASC');
- if (!$r->count()) {
- return $this->getPagesOfBook($book_id);
- }
- if ($r->count() == 1) {
- $pages = unserialize($r->composition);
- if (null === $pages || !count($pages)) {
- return $this->getPagesOfBook($book_id);
- }
- return $pages;
- }
-
- $pages = null;
- while ($r->fetch()) {
- if ($r->update > $time) {
-
- if (is_null($pages)) {
- return $this->getPagesOfBook($book_id);
- }
- $res = unserialize($pages);
- if (null === $res || !count($res)) {
- return $this->getPagesOfBook($book_id);
- }
- return $res;
- }
- if (!count(unserialize($r->composition))) {
- continue;
- }
- $pages = $r->composition;
- }
-
- $res = unserialize($pages);
- if (null === $res || !count($res)) {
- return $this->getPagesOfBook($book_id);
- }
- return $res;
- }
-
- public function getDocumentsToUpdate($book_id)
- {
- $res = array();
- $r = $this->con->select('SELECT DISTINCT d.document_id FROM book_pages b,documents d WHERE b.book_id=\'' . $this->con->escape($book_id) . '\' AND d.version=1 AND b.document_id=d.document_id');
- while ($r->fetch()) {
- $res[] = $r->document_id;
- }
- return $res;
- }
-
- public function getPagesOfBook($book_id, $conversion = true, $force = false)
- {
- if ($force || !isset(self::$pagesOfBookCache[$book_id])) {
- $pages = array();
-
- $sql = 'SELECT b.*,d.numberSections AS num,d.conversionInfos AS conversion,d.pages AS doc_pages,d.version AS version FROM book_pages b JOIN documents d ON d.document_id=b.document_id WHERE b.book_id=\'' . $this->con->escape($book_id) . '\' ORDER BY book_page';
-
- $r = $this->con->select($sql);
- while ($r->fetch()) {
- $n = explode(',', $r->num);
-
- if (isset($n[$r->document_page - 1])) {
- $num = $n[$r->document_page - 1];
- } else {
- $num = '';
- }
- $pages[$r->book_page] = array('document_id' => $r->document_id,
- 'document_page' => $r->document_page,
- 'version' => $r->version,
- 'defaultNum' => $num,
- 'nb_pages' => $r->doc_pages
- );
-
- if ($conversion) {
- if ($r->conversion != '') {
- $c = unserialize($r->conversion);
- $c = $c->pages[$r->document_page];
- }
- $qp = array('resolution', 'method', 'quality', 'objects');
- foreach ($qp as $p) {
- if (isset($c) && isset($c->$p)) {
- $pages[$r->book_page][$p] = $c->$p;
- }
- }
- }
- }
- if (!count($pages)) {
- return [];
- }
-
- self::$pagesOfBookCache[$book_id] = $pages;
- }
- return self::$pagesOfBookCache[$book_id];
- }
-
- public function appendDocument($book_id, $document_id)
- {
- $r = $this->con->select('SELECT MAX(book_page) AS book_page FROM book_pages WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
- $lastPage = is_null($r->book_page) ? 0 : $r->book_page;
- $this->insertDocument($book_id, $lastPage, $document_id);
- }
-
- public function removePage($book_id, $book_page)
- {
- // Supprime la page
- $this->con->execute('DELETE FROM book_pages WHERE book_page=\'' . $this->con->escape($book_page) . '\' AND book_id=\'' . $this->con->escape($book_id) . '\'');
- // Décale les pages suivantes vers le haut
- $this->decalePages($book_id, $book_page, -1);
- }
-
- public function insertPage($book_id, $after_page, $document_id, $document_page)
- {
- // Décale les pages vers le bas
- $this->decalePages($book_id, $after_page, 1);
- // Insère la page
- $c = $this->con->openCursor('book_pages');
- $c->book_id = $book_id;
- $c->book_page = $after_page + 1;
- $c->document_id = $document_id;
- $c->document_page = $document_page;
- $c->insert();
- }
-
- public function insertDocument($book_id, $after_page, $document_id)
- {
- // Obtiens le book
- $book = $this->selectById($book_id);
- $num = explode(',', $book->numerotation);
- // Obtiens le nombre de pages
- $r = $this->con->select('SELECT pages,numberSections FROM documents WHERE document_id=\'' . $this->con->escape($document_id) . '\'');
- // Décale les pages vers le bas
- if ($after_page > 0) {
- $this->decalePages($book_id, $after_page, $r->pages);
- }
- // Insère les pages
- $c = $this->con->openCursor('book_pages');
- $c->book_id = $book_id;
- $c->document_id = $document_id;
- for ($i = 1; $i <= $r->pages; $i++) {
- $c->document_page = $i;
- $c->book_page = $after_page + $i;
- $c->insert();
- }
- // Mets à jour la liste des numéros des pages
- $before = array_slice($num, 0, $after_page);
- $after = array_slice($num, $after_page, count($num) - $after_page);
-
- $newnum = $r->numberSections;
- if (trim($newnum, ',') == '') {
- // If no number detected, we create a numeric list from 1
- $between = range(1, $r->pages);
- } else {
- // Else, we use numbers detected at conversion
- $between = explode(',', $r->numberSections);
- }
- $num = array_merge($before, $between, $after);
- // Mets à jour la numerotation de la publication
- $c = $this->con->openCursor('books');
- $c->numerotation = implode(',', $num);
- $c->composition_update = TIME;
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
-
- $this->saveCompositionVersion($book_id);
- }
-
- protected function decalePages($book_id, $after_page, $decalage)
- {
- $decalage = ($decalage >= 0) ? '+' . $decalage : $decalage;
- $this->con->execute('UPDATE book_pages SET book_page=book_page' . $decalage . ' WHERE book_page>' . $this->con->escape($after_page) . ' AND book_id=\'' . $this->con->escape($book_id) . '\'');
- }
-
- public function getListe($orderby = null, $sens = null, $limit = null, $limitedToUserRights = false)
- {
- if (!is_null($this->q)) {
- $where = '(';
- if ($this->search_id) {
- $where .= ' book_id=\'' . $this->con->escape($this->q) . '\' OR ';
- }
-
- if (!cubeMath::is_int($this->q)) {
- $where .= 'nom LIKE \'%' . $this->con->escape($this->q) . '%\'';
- $daoClient = new commonDAOClient($this->con);
- $where .= ' OR proprietaire_id IN(' . $daoClient->querySearchByName($this->q) . ') OR ';
- }
- $limit = null;
- $where .= '1=2)';
- } else {
- $where = '(' . $this->makeWhereFromFiltres() . ')';
- }
- $where .= $this->limitToUserRights($limitedToUserRights);
-
- $orderby = is_null($orderby) ? 'book_id' : $orderby;
- $sens = is_null($sens) ? 'DESC' : $sens;
- $limit = is_null($limit) ? '' : $this->con->limit($limit);
-
- $sql = 'SELECT * FROM books_vue WHERE ' . $where . ' ORDER BY ' . $orderby . ' ' . $sens . ' ' . $limit;
- $r = $this->con->select($sql);
- return $this->factory($r);
- }
-
- protected function limitToUserRights($utilisateur)
- {
- if ($utilisateur) {
- if (wsDroits::admin()) {
- return '';
- }
- return ' AND proprietaire IN (' . $utilisateur->ws_rights . ')';
- }
- return '';
- }
-
- protected function makeWhereFromFiltres()
- {
- if (!is_null($this->filtres)) {
- $w = array('1=1');
- if (commonFiltre::test('admin_book', $this->filtres)) {
- $w[] = 'super_admin IN (' . implode(',', array_keys($this->filtres['admin_book'])) . ')';
- }
- if (commonFiltre::test('status_book', $this->filtres)) {
- $w[] = 'status IN(' . implode(',', array_keys($this->filtres['status_book'])) . ')';
- }
- if (commonFiltre::test('revendeur_book', $this->filtres)) {
- $v = array_keys($this->filtres['revendeur_book']);
- $values = array();
- foreach ($v as $r) {
- $values[] = $this->con->escape($r);
- }
-
-
- $w[] = 'facturable IN(\'' . implode('\',\'', $values) . '\')';
- }
- return implode(' AND ', $w);
- } else {
- return '1=1';
- }
- }
-
- public function setChapters($book_id, $json)
- {
- $chapters = json_decode($json, true);
- $res = array();
-
- foreach ($chapters as $c) {
- $c['label'] = trim($c['label']);
- $n = (string)$c['page'];
- $c['label'] = trim(preg_replace('|\s+' . $n . '$|iu', '', $c['label']));
- $res[] = $c;
- }
-
- $json_chapters = json_encode($res);
-
- $c = $this->con->openCursor('books');
- $c->chapters = $json_chapters;
- $c->changedate = TIME;
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
-
- if ($json_chapters && $json_chapters != '[]') {
- if (count($res) == 1) {
- if ($res[0]['label'] == '' && $res[0]['page'] == '') {
- return;
- }
- }
- $c = $this->con->openCursor('books_chapters_versions');
- $c->book_id = $book_id;
- $c->chapters = $json_chapters;
- $c->time = TIME;
- $c->insert();
- }
- }
-
- public function setSpecialLinksAndRulers($book_id, $links, $rulers)
- {
- $c1 = $this->con->openCursor('special_links_versions');
- $c = $this->con->openCursor('books');
-
- if (is_string($links)) {
- $links = json_encode(json_decode($links, false));
- }
- if (is_string($rulers)) {
- $rulers = json_encode(json_decode($rulers, false));
- }
-
-
- $links = wsLinks::encryptLinks(json_decode($links));
-
-
- if (is_array($links)) {
- $links = json_encode($links);
- }
- if (is_array($rulers)) {
- $rulers = json_encode($rulers);
- }
-
- $c1->links = $c->specialLinks = $links;
- $c1->rulers = $c->specialRulers = $rulers;
- $c1->update = $c->changedate = TIME;
- $c1->book_id = $book_id;
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
- try {
- $c1->insert();
- } catch (Exception $e) {
- try {
- $c1->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\' AND `update`=' . TIME);
- } catch (Exception $e) {
-
- }
- }
- }
-
- public function setTheme($book_id, $theme)
- {
- $c = $this->con->openCursor('books');
- $c->theme = $theme;
- $c->changedate = TIME;
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
- }
-
- public function setStatus($book_id, $status)
- {
- $c = $this->con->openCursor('books');
- if ($status < 2) {
- $c->tache = 0;
- }
- $c->status = $status;
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
- return $this->selectById($book_id);
- }
-
- public function setChaptersFromOldFluidbook($book_id)
- {
- $book = $this->selectById($book_id);
- $n = explode(',', $book->numerotation);
-
- $xml = simplexml_load_file('https://ws.fluidbook.com/books/' . $book_id . '/data/links.xml');
- $res = array();
- $chapters = $xml->xpath('//chapters');
- foreach ($chapters as $ch) {
- $c = array();
- $c['label'] = (string)$ch->txt;
-
- $p = intval((string)$ch->page);
- if ($p <= 0) {
- continue;
- }
- $c['page'] = $n[$p];
- $c['level'] = intval((string)$ch->level);
- $res[] = $c;
- }
-
- $c = $this->con->openCursor('books');
- $c->chapters = json_encode($res);
- $c->changedate = TIME;
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
- }
-
- public function saveCompositionVersion($book_id, $time = null)
- {
- $time = is_null($time) ? TIME : $time;
-
- $pages = $this->getPagesOfBook($book_id, true, true);
-
- $c = $this->con->openCursor('book_pages_versions');
- $c->update = $time;
- $c->book_id = $book_id;
- $c->composition = serialize($pages);
- $c->insert();
- }
-
- public function setLang($book_id, $base, $traductions)
- {
- // Cleanup user translations
- $traductions = json_decode($traductions, true);
- foreach ($traductions as $k => $v) {
- $traductions[$k] = $v;
- }
-
- $daoLang = new wsDAOLang($this->con);
- $lang = $daoLang->selectById($base);
- // Cleanup base translations
- $baseTraductions = $lang->traductions;
- foreach ($baseTraductions as $k => $v) {
- $baseTraductions[$k] = $v;
- }
- // Then compare them. If there is no differences, we don't save translations in the book
- if ($traductions == $baseTraductions) {
- $t = '';
- } else {
- $t = json_encode($traductions);
- }
-
- $c = $this->con->openCursor('books');
- $c->lang = $base;
- $c->traductions = $t;
- $c->changedate = TIME;
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
- }
-
- public function setSettings($book_id, $settings)
- {
- $book = $this->selectById($book_id);
- $parametres = $book->parametres;
- $new = $settings;
- foreach ($new as $k => $v) {
- if ($k == '_empty_') {
- continue;
- }
- $parametres->$k = $v;
- }
-
- $ip = array();
- if (isset($parametres->stats_exclude_ip) && trim($parametres->stats_exclude_ip) != '') {
- $list = $parametres->stats_exclude_ip;
- $list = str_replace("\r", "\n", $list);
- $e = explode("\n", $list);
- foreach ($e as $i) {
- $i = trim($i);
- if ($i == '') {
- continue;
- }
- $long = ip2long($i);
- if ($long !== false) {
- $ip[] = $long;
- }
- }
- }
-
- $file = '/home/stats/www/exclude/' . $book_id;
-
- if (count($ip)) {
- file_put_contents($file, implode(',', $ip));
- chmod($file, 0777);
- chown($file, 'stats');
- } else if (file_exists($file)) {
- unlink($file);
- }
-
- $c = $this->con->openCursor('books');
- $c->nom = $parametres->title;
- $c->parametres = serialize($parametres);
- $c->changedate = TIME;
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
- }
-
- public function setProprietaire($book_id, $proprietaire_id)
- {
- $c = $this->con->openCursor('books');
- $c->proprietaire = $proprietaire_id;
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
- }
-
- public function setTache($book_id, $tache)
- {
- $c = $this->con->openCursor('books');
- $c->tache = $tache;
- $c->status = 2;
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
- }
-
- public function setVersion($book_id, $version)
- {
- $c = $this->con->openCursor('books');
- $c->version = $version;
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
- }
-
- public function touch($book_id)
- {
- $c = $this->con->openCursor('books');
- $c->changedate = TIME;
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
- }
-
- public function touchCompile($book_id, $version = 'all')
- {
- $c = $this->con->openCursor('books');
- if ($version == '2') {
- $c->compiledate = TIME;
- } elseif ($version == '1') {
- $c->compile1date = TIME;
- } elseif ($version == 'html5') {
- $c->compilehtml5date = TIME;
- } else {
- $c->compiledate = TIME;
- $c->compile1date = TIME;
- $c->compilehtml5date = TIME;
- }
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
- }
-
- public function isUpToDate($book, $version)
- {
- $version = (string)$version;
- if ($version == '2') {
- if (!file_exists(WS_BOOKS . '/final/' . $book->book_id)) {
- return false;
- }
- if ($book->compiledate < $book->changedate) {
- return false;
- }
- } else if ($version == '1') {
- // V1
- if (!file_exists(WS_BOOKS . '/finalv1/' . $book->book_id . '/index.swf')) {
- return false;
- }
- if ($book->compile1date < $book->changedate) {
- return false;
- }
- } else if ($version == 'html5') {
- return false;
- // HTML5
- $checks = array($book->changedate, cubeFiles::filemtimeRecursive(WS_BOOKS . '/working/' . $book->book_id), cubeFiles::filemtimeRecursive(WS_COMPILE_ASSETS . '/_html5'), cubeFiles::filemtimeRecursive(ROOT . '/inc/ws/Util/html5'));
- foreach ($checks as $check) {
- if ($check > $book->compilehtml5date) {
- return false;
- }
- }
- }
- return true;
- }
-
- public function setComposition($book_id, $pages)
- {
- $numerotation = array();
- $nb_pages = 0;
- foreach ($pages as $p) {
- $numerotation[] = $p->virtual;
- $nb_pages++;
- }
-
- $book = $this->selectById($book_id);
- $parametres = $book->parametres;
- $parametres->pages = $nb_pages;
-
- $c = $this->con->openCursor('books');
- $c->parametres = serialize($parametres);
- $c->numerotation = implode(',', $numerotation);
- $c->changedate = TIME;
-
- // Check if composition need to be updated
- $r = $this->con->select('SELECT * FROM book_pages WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
- $tab = array();
- $now = array();
- $ref = array();
- while ($r->fetch()) {
- $ref[$r->book_page] = array((int)$r->document_id, (int)$r->document_page);
- }
- $i = 1;
- foreach ($pages as $p) {
- $now[$i] = array((int)$p->document_id, (int)$p->document_page);
- $i++;
- }
- if ($now != $ref) {
- $this->con->execute('DELETE FROM book_pages WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
-
- $c1 = $this->con->openCursor('book_pages');
- $c1->book_id = $book_id;
- $i = 1;
- foreach ($pages as $p) {
- $c1->document_id = $p->document_id;
- $c1->document_page = $p->document_page;
- $c1->book_page = $i;
- $c1->insert();
- $i++;
- }
- $c->composition_update = TIME;
- $this->saveCompositionVersion($book_id);
- }
-
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
- }
-
- public function setInstallDir($book_id, $dir, $server)
- {
- $col = 'dir_' . $server;
-
- $c = $this->con->openCursor('books');
- $c->$col = $dir;
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
- }
-
- public function makeTextsIndexes($book, $pages, &$index, &$textes, $simple = false)
- {
- global $core;
- $prefix = '';
- if ($book->parametres->textExtraction == 'poppler') {
- $prefix = 'p';
- } else if ($book->parametres->textExtraction == 'fluidbook') {
- $prefix = 'f';
- }
-
- $dir = WS_BOOKS . '/index/' . $book->book_id;
- if ($book->parametres->ignoreSearchSeparators != '') {
- $dir .= '/' . sha1($book->parametres->ignoreSearchSeparators);
- }
- if (!file_exists($dir)) {
- mkdir($dir, 0777, true);
- }
-
- if ($simple) {
- $ifilec = $dir . '/' . $prefix . 'sindex.json';
- } else {
- $ifilec = $dir . '/' . $prefix . 'index.json';
- }
- $tfilec = $dir . '/' . $prefix . 'textes.json';
-
- if (CubeIT_Util_Gzip::file_exists($ifilec) && CubeIT_Util_Gzip::file_exists($tfilec) && (min(CubeIT_Util_Gzip::filemtime($ifilec), CubeIT_Util_Gzip::filemtime($tfilec)) >= max($book->composition_update, filemtime(__FILE__), filemtime(WS_TOOLS . '/fwstk/out/artifacts/fwstk_jar/fwstk.jar')))) {
- $index = CubeIT_Util_Gzip::file_get_contents($ifilec);
- $textes = CubeIT_Util_Gzip::file_get_contents($tfilec);
- return;
- }
-
- if ($book->parametres->ignoreSearchSeparators != "") {
- $docs = array();
- foreach ($pages as $p => $i) {
- $docs[] = $i['document_id'];
- }
- $docs = array_unique($docs);
-
- foreach ($docs as $doc) {
- $out = wsDocument::getDir($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);
- $fwstk->setArg('--threads 1');
- $fwstk->setArg('--ignoreSeparators ' . $book->parametres->ignoreSearchSeparators);
- $fwstk->execute();
- }
- }
-
- $index = array();
- $textes = array();
- foreach ($pages as $book_page => $infos) {
- $tfile = wsDocument::getDir($infos['document_id']) . $prefix . 'p' . $infos['document_page'] . '.txt';
- $ifile = wsDocument::getDir($infos['document_id']) . $prefix . 'i' . $infos['document_page'] . '.txt';
-
- if (!file_exists($tfile) || !file_exists($ifile)) {
- $daoDoc = new wsDAODocument($core->con);
- $out = wsDocument::getDir($infos['document_id']);
-
- $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();
- }
-
- CubeIT_Util_Gzip::compressIfNotCompressed($tfile);
- CubeIT_Util_Gzip::compressIfNotCompressed($ifile);
- $text = CubeIT_Util_Gzip::file_get_contents($tfile);
- $ipage = CubeIT_Util_Gzip::file_get_contents($ifile);
-
- if ($simple) {
- $this->fillIndexWithWordsSimple($index, $book_page, $ipage);
- } else {
- $this->fillIndexWithWords($index, $book_page, $ipage);
- }
- $textes[$book_page] = $text;
- }
- ksort($index);
-
- $textes = json_encode($textes);
- $index = json_encode($index);
-
- CubeIT_Util_Gzip::file_put_contents($tfilec, $textes);
- CubeIT_Util_Gzip::file_put_contents($ifilec, $index);
- }
-
- public function makeHighlightIndex($book, $pages)
- {
- $jar = WS_TOOLS . '/fwstk/out/artifacts/fwstk_jar/fwstk.jar';
-
- $daoDoc = new wsDAODocument($this->con);
- $res = new stdClass();
- foreach ($pages as $book_page => $infos) {
- $fby = wsDocument::getDir($infos['document_id']) . 'html/p' . $infos['document_page'] . '.fby';
- // Refresh highlight data if fby file doesn't exists or if fwstk has been updated
- $fbymtime = @filemtime($fby);
- if (!file_exists($fby) || filemtime($jar) > $fbymtime || filemtime(__FILE__) > $fbymtime) {
- $doc = $daoDoc->selectById($infos['document_id']);
- $doc->getHighlightTextsData();
- }
-
- if (file_exists($fby)) {
- $words = CubeIT_Util_Json::decode(file_get_contents($fby), CubeIT_Util_Json::TYPE_OBJECT);
-
- if (is_array($words)) {
- foreach ($words as $i => $w) {
- $word = $w->word;
- $word = trim($word, "\0");
- if ($word == '') {
- continue;
- }
- unset($w->word);
- $w->page = $book_page;
- $w->idx = $i;
- if (!isset($res->{$word})) {
- $res->{$word} = array();
- }
- $res->{$word}[] = $w;
- }
- }
- }
- }
- return $res;
- }
-
- protected function _escapeIndex($str)
- {
- $todelete = array('\ufffd');
- foreach ($todelete as $d) {
- $str = str_replace($d, '', $str);
- }
- return $str;
- }
-
- protected function fillIndexWithWordsSimple(&$index, $page, $ipage)
- {
- $twords = explode("\n", trim($ipage));
-
- foreach ($twords as $woadata) {
- $w1 = explode(',', trim($woadata));
- if (count($w1) <= 1) {
- continue;
- }
- list($woa, $worddata) = $w1;
- $e = explode("\t", $worddata, 2);
- if (count($e) < 2) {
- continue;
- }
- list($total, $wordslist) = $e;
-
- if ($woa == '') {
- continue;
- }
-
- if (!isset($index[$woa])) {
- $index[$woa] = array('t' => 0, 'p' => array());
- }
- $index[$woa]['t'] += $total;
-
- $words = explode("\t", $wordslist);
- foreach ($words as $word) {
- list($wordwa, $count) = explode('$', $word, 2);
- if (!isset($index[$woa]['p'][$page])) {
- $index[$woa]['p'][$page] = 0;
- }
- $index[$woa]['p'][$page] += $count;
- }
- }
- }
-
- protected function fillIndexWithWords(&$index, $page, $ipage)
- {
- $twords = explode("\n", trim($ipage));
-
- foreach ($twords as $woadata) {
- $w1 = explode(',', trim($woadata));
- if (count($w1) <= 1) {
- continue;
- }
- list($woa, $worddata) = $w1;
- $e = explode("\t", $worddata, 2);
- if (count($e) < 2) {
- continue;
- }
- list($total, $wordslist) = $e;
-
- if ($woa == '') {
- continue;
- }
-
- if (!isset($index[$woa])) {
- $index[$woa] = array('t' => 0, 'w' => array());
- }
- $index[$woa]['t'] += $total;
-
- $words = explode("\t", $wordslist);
-
- foreach ($words as $word) {
- list($wordwa, $count) = explode('$', $word, 2);
- if (!isset($index[$woa]['w'][$wordwa])) {
- $index[$woa]['w'][$wordwa] = array('t' => 0, 'p' => array());
- }
- if (!isset($index[$woa]['w'][$wordwa]['p'][$page])) {
- $index[$woa]['w'][$wordwa]['p'][$page] = 0;
- }
- $index[$woa]['w'][$wordwa]['t'] += $count;
- $index[$woa]['w'][$wordwa]['p'][$page] += $count;
- }
- }
- }
-
- public function getNumerotationFromDocs($book_id)
- {
- $pages = $this->getPagesOfBook($book_id);
- }
-
- public function compileTemp($book_id, $version, $dir)
- {
- if ($version == 'ha' || $version == 'hi') {
- if ($version == 'ha') {
- $os = 'android';
- } elseif ($version == 'hi') {
- $os = 'ios';
- }
- $packager = new wsPackagerPhonegap($book_id, $dir, false, true, $os);
- $packager->makePackage(false);
- }
- }
-
- public function compile($book_id, $version = 'all', $complete = false, $force = false, $dev = false, $book = null, $delete = true)
- {
- if (is_null($book_id) || !$book_id) {
- return;
- }
-
- $v1 = $v2 = $html5 = false;
-
- if ($version == 'all') {
- $v1 = $v2 = $html5 = true;
- } else if ($version == '1') {
- $v1 = true;
- } else if ($version == '2') {
- $v2 = true;
- } elseif ($version == 'html5') {
- $html5 = true;
- }
-
- if (null === $book) {
- $book = $this->selectById($book_id);
- }
- $pages = $this->getPagesOfBook($book_id);
-
- if (!$force) {
- $v1 = $v1 && !$this->isUpToDate($book, 1);
- $v2 = $v2 && !$this->isUpToDate($book, 2);
- $html5 = $html5 && !$this->isUpToDate($book, 'html5');
- } else {
- $v1 = false;
- $html5 = true;
- $v2 = true;
- }
-
- $res = '';
- if ($v1) {
- fb(time(), 'Compile V1');
- $res .= $this->compile1($book_id, $book, $pages);
- $this->touchCompile($book_id, '1');
- }
- if ($v2) {
- fb(time(), 'Compile V2');
- $res .= $this->compile3($book_id, $complete, $book, $pages);
- $this->touchCompile($book_id, '2');
- }
- if ($html5) {
- fb(time(), 'Compile HTML5');
- $res .= $this->compileHTML5($book_id, $book, $dev, $delete);
- $this->touchCompile($book_id, 'html5');
- }
- if ($v1 || $v2) {
- fb(time(), 'Compile PDF & Widget');
- $this->compilePDF($book, $pages);
- $this->compileWidget($book, $pages);
- }
-
- fb(time(), 'End Compile');
- return $res;
- }
-
- public function compile1($book_id, $book, $pages)
- {
- $finalDir = WS_BOOKS . '/finalv1/' . $book_id . '/';
- $packager = new wsPackagerV1($book_id, $finalDir, false);
- $packager->makePackage(false);
- }
-
- public function compile3($book_id, $complete, $book, $pages)
- {
- $res = '';
-
- $compilerDir = WS_BOOKS . '/datasCompiler/' . $book_id . '/';
- $finalDir = WS_BOOKS . '/final/' . $book_id . '/';
-
- $vdir = new CubeIT_Files_VirtualDirectory($finalDir);
-
- $debug = false;
-
- $flex = new cubeFlexCompiler('FluidbookDatas', $compilerDir, 'flash.display.Sprite', explode(';', AS3_SOURCES), MXMLC_PATH, 10, 30, 800, 600, $debug);
- $flexLight = new cubeFlexCompiler('FluidbookDatasLight', $compilerDir, 'flash.display.Sprite', explode(';', AS3_SOURCES), MXMLC_PATH, 10, 30, 800, 600, $debug);
-
- $filesToCopy = array();
- $this->compileFlex($book_id, $complete, $compilerDir, $vdir, $filesToCopy, $book, $pages, $flex, $flexLight, $finalDir);
-
- $res .= $flex->compile() . "\n\n-------------------\n\n";
- $flexLight->addVariable('datasSize', filesize($compilerDir . '/FluidbookDatas.swf'));
- $res .= $flexLight->compile();
-
- $filesToCopy['data/fd.swf'] = $compilerDir . '/FluidbookDatas.swf';
- $filesToCopy['data/fdl.swf'] = $compilerDir . '/FluidbookDatasLight.swf';
-
- // Copy of files
- // Check if dest dir exists
-
- foreach ($filesToCopy as $local => $source) {
- $localPath = $local;
- $vdir->copy($source, $localPath);
- }
-
- $workingDir = WS_BOOKS . '/working/' . $book_id . '/';
- $vdir->copyDirectory($workingDir . 'media', 'data');
- $vdir->sync(true);
-
- return $res;
- }
-
- public function copy($source, $dest)
- {
- copy($source, $dest);
- touch($dest, filemtime($source));
- }
-
- public static function getDocumentPage($book_id, $book_page)
- {
- global $core;
- $dao = new wsDAOBook($core->con);
- $pages = $dao->getPagesOfBook($book_id);
- return $pages[$book_page];
- }
-
- public function compileAir($book_id)
- {
- $compilerDir = WS_BOOKS . '/air/' . $book_id . '/compiler';
- $finalDir = WS_BOOKS . '/air/' . $book_id . '/';
-
- $book = $this->selectById($book_id);
- $pages = $this->getPagesOfBook($book_id);
-
- $src = AS3_FLUIDBOOK_SOURCES . '/_src/';
- $lib10 = AS3_FLUIDBOOK_SOURCES . '/lib10/';
- $libs = array(
- $src,
- $lib10,
- AS3_SOURCES,
- $src . 'lib/fluidbook3dLibrary.swc',
- $src . 'lib/mdm.swc',
- $lib10 . 'flash.swc',
- $lib10 . 'flex.swc',
- $lib10 . 'framework.swc',
- );
-
- wsSVN::updateToLastRevision();
-
- $swf = 'FluidbookAirProjector' . $book_id;
- $flex = new cubeFlexCompiler($swf, $compilerDir, 'com.fluidbook.player.AIRMain', $libs, '/usr/local/flex/bin/mxmlc', 'air', 45, 800, 600, true);
-
- $this->compileFlex($book_id, true, $compilerDir, $finalDir, $filesToCopy, $book, $pages, $flex, $flex);
- $res = $flex->compile();
-
- $air = new cubeAIRCompiler($swf . '.swf', '/usr/local/flex/bin', $compilerDir, '2.0');
- $air->setApplicationDatas('com.fluidbook' . $book_id, $book->parametres->title, $book->parametres->title, cubeText::str2URL($book->parametres->title), $book->lang);
- $air->setInitialWindow($book->parametres->title);
- $res .= $air->compile();
-
- return $res;
- }
-
- public function compileFlex($book_id, $complete, $compilerDir, $vdir, &$filesToCopy, $book, $pages, $flex, $flexLight)
- {
- /* @var $vdir CubeIT_Files_VirtualDirectory */
-
- cubePHP::neverStop();
- /* @var $flex cubeFlexCompiler */
-
- $workingDir = WS_BOOKS . '/working/' . $book_id . '/';
-
- $res = '';
-
- $daoDoc = new wsDAODocument($this->con);
- $firstDoc = $daoDoc->selectById($pages[1]['document_id']);
- $size = $firstDoc->generalInfos['size'];
-
- $daoLang = new wsDAOLang($this->con);
- $lang = $daoLang->selectById($book->lang);
-
- $langs = $daoLang->selectAll();
-
- $daoTheme = new wsDAOTheme($this->con);
- $theme = $daoTheme->getThemeOfBook($book_id, true);
-
- $daoSignature = new wsDAOSignature($this->con);
- $signature = $daoSignature->selectById($book->parametres->signature);
-
- $exportSignature = array('main' => $signature->main,
- 'mainLink' => $signature->mainLink,
- 'partner' => $signature->partner,
- 'partnerLink' => $signature->partnerLink);
-
- $index = '';
- $textes = '';
- $pageLabels = array();
-
- $hash = $book_id;
- $hash .= 'kjgl!az4.';
- $hash .= count($pages);
- $hash .= round($size[0], 3);
-
- $hash = sha1($hash);
-
- $this->makeTextsIndexes($book, $pages, $index, $textes);
-
- $daoDoc->getLinksAndRulers($book_id, $links, $rulers);
-
- $audiodescription = array();
-
- $imagesassets = array();
- $id = 1;
- $ignoreLinks = array();
- foreach ($links as $id => $link) {
- $links[$id]['id'] = $id;
- $skipCopyAsset = false;
-
- if (isset($link['image']) && $link['image']) {
- $workingFile = $workingDir . '/' . $link['image'];
- $assetId = 'link_datas_i_' . md5($link['image']);
-
- if (isset($imagesassets[$assetId])) {
-
- } else {
- if (file_exists($workingFile)) {
- if ($link['page'] <= 1) {
- $flexLight->addBitmap($workingFile, $assetId);
- } else {
- $flex->addBitmap($workingFile, $assetId);
- }
- }
- $imagesassets[$assetId] = true;
- }
- }
-
- if ($link['type'] == 16 && $book->parametres->linkFilePrefix) {
- if (!CubeIT_Util_Url::isDistant($link['to'])) {
- $skipCopyAsset = true;
- $links[$id]['to'] = $book->parametres->linkFilePrefix . $link['to'];
- }
- }
-
- if ($link['type'] == 15) {
- if (isset($imagesassets[$id])) {
- continue;
- }
- if ($link['page'] <= 1) {
- $flexLight->addBitmap($workingDir . '/' . $link['to'], 'link_datas_' . $id);
- } else {
- $flex->addBitmap($workingDir . '/' . $link['to'], 'link_datas_' . $id);
- }
- $imagesassets[$id] = true;
- } else if (in_array($link['type'], array(4, 6, 7, 9, 16, 17, 25))) {
- if (!$skipCopyAsset) {
- $workingFile = $workingDir . '/' . $link['to'];
- if (file_exists($workingFile)) {
- $filesToCopy['data/' . $link['to']] = $workingFile;
- }
-
- if ($link['type'] == 4) {
- $poster = $link['to'];
- $e = explode('.', $poster);
- array_pop($e);
- array_push($e, 'jpg');
- $poster = implode('.', $e);
-
- $workingFile = $workingDir . '/' . $poster;
- if (file_exists($workingFile)) {
- $filesToCopy['data/' . $poster] = $workingFile;
- }
- }
- }
- }
-
- if ($link['type'] == 25) {
- $audiodescription[$link['page']] = $link['to'];
- $ignoreLinks[] = $id;
- }
- if ($link['type'] == 26) {
- $pageLabels[$link['to']] = $link['page'];
- $ignoreLinks[] = $id;
- }
- }
-
- foreach ($ignoreLinks as $ignoreLink) {
- unset($links[$ignoreLink]);
- }
- $links = array_values($links);
-
- $externalsOptions = array('ongletsSWF', 'tabs2DSWF', 'externalChapters', 'externalArchives', 'ambientSound');
- foreach ($externalsOptions as $e) {
- if (isset($book->parametres->$e) && $book->parametres->$e != '') {
- $f = $workingDir . '/' . $book->parametres->$e;
- if (file_exists($f)) {
- $filesToCopy['data/' . $book->parametres->$e] = $f;
- }
- }
- }
-
- $flex->addVariable('audiodescription', $audiodescription, false, true, "JSONObject");
- $flex->addVariable('pagelabels', $pageLabels, false, true, 'JSONObject');
- $flex->addVariable('links', $links, false, true, 'JSONObject');
-
- $flex->addVariable('signature', $exportSignature, false, true, 'JSONObject');
- $flexLight->addVariable('datas', $book->parametres->toStandardObject(), false, true, 'JSONObject');
- $flexLight->addVariable('id', $book_id, false, true, 'uint');
- $flexLight->addVariable('cid', $book->cid, false, true, 'String');
-
- $traductions = (!count($book->traductions)) ? $lang->traductions : $book->traductions;
- $allTraductions = array();
- foreach ($langs as $l) {
- $allTraductions[$l->lang_id] = $l->traductions;
- }
-
- $flex->addVariable('traductions', $traductions, false, true, 'JSONObject', false);
- $flex->addVariable('allTraductions', $allTraductions, false, true, 'JSONObject');
- $flex->addVariable('chapters', $book->chapters, false, true, 'JSONObject');
- $flex->addVariable('extras', '<extras>' . $book->extras . '</extras>', false, true, 'XML');
- $flex->addVariable('numerotation', $book->numerotation, false, true, 'String');
- $flexLight->addVariable('theme', $theme->parametres->toStandardObject(), false, true, 'JSONObject');
- $flexLight->addVariable('pages', $book->parametres->pages);
- $flexLight->addVariable('fwidth', round($size[0], 4), false, true, 'Number');
- $flexLight->addVariable('fheight', round($size[1], 4), false, true, 'Number');
- $flexLight->addVariable('pagesInDatas', $complete, false, true, 'Boolean');
- $flex->addVariable('index', $index, false, true, 'JSONObject', false, false);
- $flex->addVariable('textes', $textes, false, true, 'JSONObject', false, false);
-
- $rasterized = array();
- $sizes = array();
-
- foreach ($pages as $i => $infos) {
- $base = wsDocument::getDir($infos['document_id']) . 'p' . $infos['document_page'];
- $baset = wsDocument::getDir($infos['document_id']) . 't' . $infos['document_page'];
- $swffile = $base . '.swf';
- if (file_exists($swffile)) {
- clearstatcache(true, $swffile);
- $fsize = filesize($swffile);
- } else {
- $fsize = 0;
- }
-
- if ($complete) {
- $flex->addSWF($swffile, 'page' . $i);
- } else {
- $filesToCopy['data/p' . $i . '.swf'] = $swffile;
- if ($infos['method'] >= wsDocument::BARBARE_PNM) {
- $rasterized[$i] = true;
- $filesToCopy['data/t' . $i . '.swf'] = $baset . '.swf';
- } else {
- $rasterized[$i] = false;
- }
- }
-
- $thumb = false;
- if ($book->parametres->pdfThumbnails) {
- $thumb = wsPDFConvert::getThumbFromPDF($workingDir . '/' . $book->parametres->pdfThumbnails, $i);
- }
- if (!$thumb) {
- $thumb = $base . '.jpg';
- }
-
- if ($i == 1) {
- $flexLight->addBitmap($thumb, 'thumb1');
- } else {
- $flex->addBitmap($thumb, 'thumb' . $i);
- }
- $sizes[$i] = $fsize;
- }
-
- $flexLight->addVariable('rasterized', $rasterized, false, true, 'JSONObject');
- $flexLight->addVariable('sizes', $sizes, false, true, 'JSONObject');
-
- if ($book->parametres->soundTheme != '') {
- $flex->addSound(WS_SOUNDS . '/' . $book->parametres->soundTheme . '/corner-drag.mp3', 'soundDragCorner');
- $flex->addSound(WS_SOUNDS . '/' . $book->parametres->soundTheme . '/corner-release.mp3', 'soundReleaseCorner');
- $flex->addSound(WS_SOUNDS . '/' . $book->parametres->soundTheme . '/page-flip-1.mp3', 'soundPage0');
- $flex->addSound(WS_SOUNDS . '/' . $book->parametres->soundTheme . '/page-flip-2.mp3', 'soundPage1');
- $flex->addSound(WS_SOUNDS . '/' . $book->parametres->soundTheme . '/cover-flip.mp3', 'soundCover0');
- }
- // Theme assets
- $themeRoot = WS_THEMES . '/' . $theme->theme_id . '/';
-
- if ($theme->parametres->backgroundImage != '') {
- $flexLight->addBitmap($themeRoot . $theme->parametres->backgroundImage, 'background');
- }
- if ($theme->parametres->menuImage != '') {
- $flex->addBitmap($themeRoot . $theme->parametres->menuImage, 'menu');
- }
- if ($theme->parametres->logoLoader != '') {
- $flexLight->addBitmap($themeRoot . $theme->parametres->logoLoader, 'logoLoader');
- }
- if ($theme->parametres->topBar != '') {
- $flexLight->addBitmap($themeRoot . $theme->parametres->topBar, 'topBar');
- }
- if ($theme->parametres->logo != '') {
- $flex->addBitmap($themeRoot . $theme->parametres->logo, 'logo');
- }
- if ($theme->parametres->afterSearch != '') {
- $flex->addBitmap($themeRoot . $theme->parametres->afterSearch, 'aftersearch');
- }
- if ($theme->parametres->favicon != '') {
- $filesToCopy['data/fluidbook.ico'] = $themeRoot . 'fluidbook.ico';
- }
-
- // Icons assets
- $iconsRoot = WS_ICONS . '/' . $theme->parametres->iconSet . '/';
- foreach (wsIcone::$files as $file) {
- $flex->addBitmap($iconsRoot . 'nav-' . $file . '.png', 'nav_' . $file);
- }
- // Share icons
- $iconsRoot = WS_ICONS . '/share/';
- foreach (wsIcone::$share as $file) {
- $flex->addBitmap($iconsRoot . 'share-' . $file . '.png', 'share_' . $file);
- }
-
- // Multilang
- if (trim($book->parametres->multilang) != '') {
- $m = str_replace("\r", "\n", trim($book->parametres->multilang));
- $langs = explode("\n", $m);
- $langNames = array();
- $countryNames = array();
- $iso = l10n::getISOcodes();
- $chars = '()';
- $vuFlags = array();
- foreach ($langs as $l) {
- list($mlang, $flag, $url) = explode(',', trim($l), 3);
- if (!isset($vuFlags[$flag])) {
- $flex->addBitmap(cubeMedia::getFlagFile($flag), 'flag_' . $flag);
- $vuFlags[$flag] = true;
- }
- $ll = explode('-', $mlang);
- $n = cubeText::ucfirst($iso[$ll[0]]);
- $langNames[$mlang] = $n;
- $cn = cubeCountry::getCountryName($flag, $mlang);
- $countryNames[$mlang . '_' . $flag] = $cn;
- $chars .= $n . $cn;
- }
-
- $chars = preg_split('/(?<!^)(?!$)/u', $chars);
- $chars = array_unique($chars);
-
- $flex->addFont(WS_FILES . '/fonts/FluidbookMultilang.ttf', 'MultilangFont', $chars);
- $flex->addVariable('langNames', $langNames, false, true, 'JSONObject');
- $flex->addVariable('countryNames', $countryNames, false, true, 'JSONObject');
- }
- $flexLight->addVariable('lang', $book->lang);
-
- // Basket
- if ($book->parametres->basket) {
- $formats = array('jpg', 'png', 'jpeg');
- $referencesFile = self::getWorkingFile($book->parametres->basketReferences, $book_id, 'commerce');
-
- if (file_exists($referencesFile) || CubeIT_Util_Url::isDistant($referencesFile)) {
- $ext = CubeIT_Files::getExtension($referencesFile);
- if ($ext == 'xml') {
- $xml = simplexml_load_file($referencesFile);
- $i = 0;
- $allref = array();
- foreach ($xml->item as $item) {
- $ref = (string)$item['reference'];
- if (isset($allref[$ref])) {
- continue;
- }
- $allref[$ref] = true;
- foreach ($formats as $f) {
- $refimage = $workingDir . 'commerce/' . $ref . '.' . $f;
- if (file_exists($refimage)) {
- $flex->addBitmap($refimage, "basket_image_" . $ref);
- break;
- }
- }
- $i++;
- }
- } elseif ($ext == 'xlsx') {
- $references = wsUtil::excelToArray($referencesFile);
- if ($book->parametres->customLinkClass == 'AtlanticDownloadLink') {
- $references = wsUtil::atlanticReferences($references, 'local/', null, array($vdir, 'copy'));
- }
- $flex->addVariable('basketReferences', $references, false, true, "OrderedObject");
- }
- }
- if (isset($xml)) {
- $flex->addVariable('basketReferences', cubeXML::condense($xml->asXML()), false, true, "String");
- }
- if ($book->parametres->basketPDFBackground != '') {
- $flex->addByteArray($workingDir . 'commerce/' . $book->parametres->basketPDFBackground, 'basket_pdf_background');
- }
- }
- // Fonts
- if ($theme->parametres->fontKit == 'auto') {
- if ($lang->font != 'system') {
- $font = FONT_PATH . '/' . $lang->font;
- $bfont = FONT_PATH . '/B' . $lang->font;
- if (!file_exists($bfont)) {
- $bfont = $font;
- }
-
- $flex->addFont($bfont, 'BoldFont', $lang->charset);
- $flex->addFont($font, 'GeneralFont', $lang->charset);
- }
- $flex->addFont(FONT_PATH . '/FluidbookCredits.ttf', 'CreditsFont', 'ASCII');
- $flexLight->addFont(FONT_PATH . '/FluidbookLoader.ttf', 'LoaderFont', 'Numerals');
- } else if ($theme->parametres->fontKit == 'vagrounded') {
- $flex->addFont(FONT_PATH . '/vagrounded/VAGRoundedStd-Bold.otf', 'BoldFont', $lang->charset);
- $flex->addFont(FONT_PATH . '/vagrounded/VAGRoundedStd-Light.otf', 'GeneralFont', $lang->charset);
- $flex->addFont(FONT_PATH . '/FluidbookCredits.ttf', 'CreditsFont', 'ASCII');
- $flexLight->addFont(FONT_PATH . '/vagrounded/VAGRoundedStd-Bold.otf', 'LoaderFont', 'Numerals');
- } else if ($theme->parametres->fontKit == 'gill') {
- $flex->addFont(FONT_PATH . '/gill/gill.ttf', 'BoldFont', $lang->charset);
- $flex->addFont(FONT_PATH . '/gill/gill.ttf', 'GeneralFont', $lang->charset);
- $flex->addFont(FONT_PATH . '/FluidbookCredits.ttf', 'CreditsFont', 'ASCII');
- $flexLight->addFont(FONT_PATH . '/gill/gill.ttf', 'LoaderFont', 'Numerals');
- }
-
- $flexLight->addVariable('checksum', $hash, false, true, 'String');
- }
-
-
- public static function getWorkingFile($path, $book_id, $dir = "")
- {
- if (CubeIT_Util_Url::isDistant($path) || (substr($path, 0, 1) == '/' && file_exists($path))) {
- return $path;
- }
-
- $workingDir = WS_BOOKS . '/working/' . $book_id . '/';
- return $workingDir . trim($dir, '/') . '/' . $path;
- }
-
- public function compileWidget($book, $pages)
- {
- if (!$book->parametres->widget) {
- return;
- }
-
- global $core;
-
- $finalDir = WS_BOOKS . '/final/' . $book->book_id . '/widget/';
- $finalWidget = $finalDir . 'miniFluidbook.swf';
-
- if (!file_exists($finalDir)) {
- mkdir($finalDir, 0777, true);
- }
-
- if ($book->parametres->widgetCover) {
- $file = 'miniFluidbookCouv.swf';
- } else {
- $file = 'miniFluidbook.swf';
- }
- $mini = WS_COMPILE_ASSETS . '/_widget/' . $file;
-
- $from = max(1, $book->parametres->widgetStart);
- $to = min($book->parametres->widgetEnd, count($pages));
-
- $swfcombine = new cubeCommandLine('swfcombine');
- $swfcombine->setPath(CONVERTER_PATH);
- $swfcombine->setArg('merge');
- $swfcombine->setArg('stack1');
- $swfcombine->setArg('z');
- $swfcombine->setArg('o', $finalWidget);
- $swfcombine->setArg(null, $mini);
-
- $tempimage = array();
- $tempswf = array();
- $timg = array();
-
- for ($i = $from; $i <= $to; $i++) {
- $page = $pages[$i];
-
- $timg[$i] = $tempimage[$i] = cubeFiles::tempnam();
- $tempswf[$i] = cubeFiles::tempnam();
-
- $it = new imageTools();
- $image = wsDocument::getDir($page['document_id']) . '/html/t150-' . $page['document_page'] . '.jpg';
-
- try {
- $it->loadImage($image);
- $it->resize($book->parametres->widgetSize, 10000);
- $it->output('jpeg', $tempimage[$i], 100);
- } catch (Exception $e) {
- $tempimage[$i] = $image;
- }
- $jpg2swf = new cubeCommandLine('jpeg2swf');
- $jpg2swf->setEnv('PATH', '/bin:/usr/bin:/usr/local/bin');
- $jpg2swf->setArg('q', $book->parametres->widgetQuality);
- $jpg2swf->setArg('o', $tempswf[$i]);
- $jpg2swf->setArg(null, $tempimage[$i]);
- $jpg2swf->execute();
-
- $swfcombine->setArg(null, $tempswf[$i]);
- }
- $swfcombine->execute();
-
- foreach ($timg as $t) {
- if (file_exists($t)) {
- unlink($t);
- }
- }
- foreach ($tempswf as $t) {
- unlink($t);
- }
- }
-
- public function compileHTML5($book_id, $book, $dev = false, $delete = true)
- {
- $version = $book->parametres->mobileLVersion;
- if ($dev) {
- $version = 'dev';
- }
-
- $htmlCompiler = wsHTML5::compilerFactory($book_id, $version, false, 'latest', null, false, false, false, $book);
- $htmlCompiler->compile($delete);
- }
-
- /* public function indexPDF($book, $pages) {
- $indexPath = WS_BOOKS . '/search/' . $book->book_id;
-
- Zend_Search_Lucene_Analysis_Analyzer::setDefault(new Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8Num_CaseInsensitive());
-
- if (file_exists($indexPath)) {
- files::deltree($indexPath);
- }
- $index = Zend_Search_Lucene::create($indexPath);
-
- foreach ($pages as $i => $infos) {
- $doc = new Zend_Search_Lucene_Document();
- $doc->addField(Zend_Search_Lucene_Field::Text('url', '#' . $i));
- $doc->addField(Zend_Search_Lucene_Field::UnStored('contents', file_get_contents(wsDocument::getDir($infos['document_id']) . 'p' . $infos['document_page'] . '.txt')));
- $index->addDocument($doc);
- }
-
- $c = $this->con->openCursor('books');
- $c->lucene_time = TIME;
- $c->update('WHERE book_id=' . $book->book_id);
- } */
-
- public function compilePDF($book, $pages)
- {
- $res = wsUtil::compilePDF($book, $pages);
-
- $finalPDF = WS_BOOKS . '/final/' . $book->book_id . '/data/' . $book->parametres->pdfName;
- if ($res) {
- $this->copy($res, $finalPDF);
- }
- }
-
- public function generateCID()
- {
-
- do {
- $res = '';
- for ($i = 0; $i < 8; $i++) {
- $j = rand(0, 61);
- $res .= $this->base62($j);
- }
- $r = $this->con->select('SELECT book_id FROM books WHERE cid=\'' . $res . '\'');
- if ($r->count() == 0) {
- return $res;
- }
- } while (true);
- }
-
- protected function base62($val)
- {
- $chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
- $base = strlen($chars);
- $str = '';
- do {
- $i = $val % $base;
- $str = $chars[$i] . $str;
- $val = ($val - $i) / $base;
- } while ($val > 0);
- return $str;
- }
+ public static $pagesOfBookCache = array();
+
+ /**
+ * wsDAOBook::singleton()
+ *
+ * @param mixed $r
+ * @return
+ */
+ protected function singleton($r)
+ {
+ $book = new wsBook();
+ $book->book_id = $r->book_id;
+ $book->cid = $r->cid;
+ $book->nom = $r->nom;
+ $book->lang = $r->lang;
+ $book->theme = $r->theme;
+ $book->proprietaire = $r->proprietaire_nom;
+ $book->proprietaire_id = $r->proprietaire_id;
+ $book->proprietaire_utilisateur = $r->proprietaire_utilisateur;
+ $book->hash = $r->hash;
+ $book->compteur_visites = $r->compteur_visites;
+ $book->status = $r->status;
+ $book->date_status = $r->date_status;
+ $book->date = $r->date;
+ $book->pages = array();
+ $book->chapters = $r->chapters;
+ $book->traductions = $r->traductions;
+ $book->specialLinks = $r->specialLinks;
+ $book->specialRulers = $r->specialRulers;
+ $book->parametres = $r->parametres;
+ $book->extras = $r->extras;
+ $book->numerotation = $r->numerotation;
+ $book->changedate = $r->changedate;
+ $book->compiledate = $r->compiledate;
+ $book->compile1date = $r->compile1date;
+ $book->compilehtml5date = $r->compilehtml5date;
+ $book->facturable = $r->facturable;
+ $book->facturable_id = $r->facturable_id;
+ $book->tache = $r->tache;
+ if (isset($r->projet)) {
+ $book->projet = $r->projet;
+ }
+ $book->version = $r->version;
+ $book->composition_update = $r->composition_update;
+ $book->dir_references = $r->dir_references;
+ $book->dir_hosting = $r->dir_hosting;
+ $book->dir_macbook_phonegap_ios = $r->dir_macbook_phonegap_ios;
+ $book->dir_phonegap_android = $r->dir_phonegap_android;
+ $book->dir_external = $r->dir_external;
+ $book->demo_counter = $r->demo_counter;
+ $book->exportdatas = $r->exportdatas;
+
+ return $book;
+ }
+
+ protected function cree($r)
+ {
+ $book = new wsBook();
+ $book->book_id = 'new';
+ $book->nom = '';
+ $book->cid = null;
+ $book->lang = 'fr';
+ $book->theme = 1;
+ $book->proprietaire = '';
+ $book->proprietaire_id = 0;
+ $book->hash = '';
+ $book->compteur_visites = 20;
+ $book->status = 0;
+ $book->date_status = TIME;
+ $book->date = TIME;
+ $book->composition_update = TIME;
+ $book->chapters = json_encode(array());
+ $book->parametres = new wsBookParametres();
+ $book->tache = 0;
+ $book->pages = array();
+ $book->version = 2;
+ return $book;
+ }
+
+ protected function getNextId()
+ {
+ $r = $this->con->select('SELECT MAX(book_id) AS book_id FROM books');
+ if ($r->book_id < 10000) {
+ return 10000;
+ }
+ return $r->book_id + 1;
+ }
+
+ public function saveExportDatas($book_id, $datas)
+ {
+ $c = $this->con->openCursor('books');
+ $c->exportdatas = json_encode($datas);
+ $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ }
+
+ public function addDemoCount($book_id)
+ {
+
+ $r = $this->con->select('SELECT demo_counter,nom FROM books WHERE book_id=\'' . $book_id . '\'');
+ $m = 20;
+ if ($r->demo_counter > 0 && $r->demo_counter % $m == 0) {
+ $mail = new cubeMail();
+ $mail->charset = 'UTF-8';
+ $mail->from = 'contact@fluidbook.com';
+ $mail->to = 'tech@fluidbook.com';
+ $mail->subject = '[Fluidbook Workshop] Fluidbook consulté via l\'url publique';
+ $mail->body = 'Le fluidbook suivant a été consulté ' . $m . ' fois (et ' . $r->demo_counter . ' au total) via l\'url publique : ' . "\r\n" .
+ 'Fluidbook # ' . $book_id . ' - ' . $r->nom;
+ $mail->send();
+ }
+
+ $this->con->select('UPDATE books SET demo_counter=demo_counter+1 WHERE book_id=\'' . $book_id . '\'');
+ }
+
+ public function selectByIds($book_ids = array(), $simple = false)
+ {
+ if ($simple) {
+ $table = 'books';
+ } else {
+ $table = 'books_vue';
+ }
+
+ $ids = array();
+ foreach ($book_ids as $bid) {
+ fb($bid);
+ if (intval($bid) > 0) {
+ $ids[] = $bid;
+ }
+ }
+
+ $sql = 'SELECT * FROM ' . $table . ' WHERE book_id IN (' . implode(',', $ids) . ')';
+ $books = $this->factory($this->con->select($sql));
+ $res = array();
+ foreach ($books as $book) {
+ $res[$book->book_id] = $book;
+ }
+ return $res;
+ }
+
+ public function selectById($book_id = null, $simple = false)
+ {
+ if (is_null($book_id)) {
+ return $this->cree();
+ }
+ if ($simple) {
+ $table = 'books';
+ } else {
+ $table = 'books_vue';
+ }
+ $sql = 'SELECT * FROM ' . $table . ' WHERE book_id=\'' . $this->con->escape($book_id) . '\' LIMIT 1';
+ $r = $this->con->select($sql);
+ return $this->singleton($r);
+ }
+
+ public function selectByCid($cid = null, $simple = false)
+ {
+ if ($simple) {
+ $table = 'books';
+ } else {
+ $table = 'books_vue';
+ }
+
+ $sql = 'SELECT * FROM ' . $table . ' WHERE cid LIKE BINARY \'' . $this->con->escape($cid) . '\' LIMIT 1';
+ $r = $this->con->select($sql);
+ return $this->singleton($r);
+ }
+
+ public function selectLuceneToDo()
+ {
+ $sql = 'SELECT * FROM books_vue WHERE lucene_time<composition_update AND version=2 ORDER BY book_id ASC LIMIT 1';
+ $r = $this->con->select($sql);
+ return $this->factory($r);
+ }
+
+ public function selectLuceneTimeNotSet()
+ {
+ $sql = 'SELECT * FROM books_vue WHERE lucene_time=0 AND version=2';
+ $r = $this->con->select($sql);
+ return $this->factory($r);
+ }
+
+ /**
+ * wsDAOBook::sauve()
+ *
+ * @param mixed $createur
+ * @param mixed $data
+ * @return
+ */
+ public function sauve($createur, $data)
+ {
+ $c = $this->con->openCursor('books');
+ if (isset($data['nom'])) {
+ $c->nom = $data['nom'];
+ }
+ if (isset($data['lang'])) {
+ $c->lang = $data['lang'];
+ }
+ if (isset($data['theme'])) {
+ $c->theme = $data['theme'];
+ }
+ if (isset($data['proprietaire'])) {
+ $c->proprietaire = $data['proprietaire'];
+ }
+
+ if ($data['book_id'] == 'new' || $data['book_id'] == '') {
+ $c->date = TIME;
+ $c->hash = md5(rand(0, 123456789365469));
+ $c->compteur_visites = 20;
+ $c->parametres = serialize(new wsParametres());
+ $c->changedate = TIME;
+ $book_id = $c->book_id = $this->getNextId();
+
+ $c->insert();
+ } else {
+ $c->changedate = TIME;
+ $book_id = $data['book_id'];
+ $c->update('WHERE book_id=\'' . $this->con->escape($data['book_id']) . '\'');
+ }
+
+ if (isset(self::$pagesOfBookCache[$book_id])) {
+ unset(self::$pagesOfBookCache[$book_id]);
+ }
+
+ return $this->selectById($book_id);
+ }
+
+ public function duplicate($book_id, $createur, $nom = null, $pages = false, $complete = false)
+ {
+ $r = $this->con->select('SELECT * FROM books_vue WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+
+ $old_id = $book_id;
+
+
+ $parametres = unserialize($r->parametres);
+ $parametres->setParent($this);
+ if (null === $nom) {
+ $nom = $parametres->title;
+ }
+ $parametres->title = $nom;
+
+ if (!$complete) {
+ $parametres->pdfReplace = '';
+ }
+
+ $c = $this->con->openCursor('books');
+ $c->proprietaire = $createur;
+ $c->date = TIME;
+ $c->hash = md5(rand(0, 1234567893));
+ $c->cid = $this->generateCID();
+ $c->compteur_visites = 20;
+ $c->status = -1;
+ $c->date_status = TIME;
+ $c->lang = $r->lang;
+ $c->parametres = serialize($parametres);
+ $c->nom = $nom;
+ $c->theme = $r->theme;
+ $c->changedate = TIME;
+ $c->compiledate = 0;
+ $c->version = 2;
+ $c->traductions = $r->traductions;
+ $c->specialLinks = $r->specialLinks;
+ $c->specialRulers = $r->specialRulers;
+ $c->composition_update = TIME;
+ $book_id = $c->book_id = $this->getNextId();
+ if ($pages) {
+ $c->numerotation = $r->numerotation;
+ $c->chapters = $r->chapters;
+ $this->con->execute('INSERT INTO book_pages SELECT ' . $book_id . ' AS book_id,book_page,document_id,document_page FROM book_pages WHERE book_id=' . $old_id);
+ }
+ if ($complete) {
+ $c->numerotation = $r->numerotation;
+ $c->chapters = $r->chapters;
+ }
+ $c->insert();
+
+ $this->saveCompositionVersion($book_id);
+
+ return $this->selectById($book_id);
+ }
+
+ public function creeEmpty($createur, $lang, $nom)
+ {
+ $c = $this->con->openCursor('books');
+
+ $parametres = new wsBookParametres($this);
+ $parametres->title = $nom;
+
+ $c->proprietaire = $createur;
+ $c->cid = $this->generateCID();
+ $c->nom = $nom;
+ $c->date = TIME;
+ $c->hash = md5(rand(0, 1234567893));
+ $c->compteur_visites = 20;
+ $c->status = -1;
+ $c->date_status = TIME;
+ $c->parametres = serialize($parametres);
+
+ $c->theme = 1;
+ $c->lang = $lang;
+ $c->changedate = TIME;
+ $c->compiledate = 0;
+ $c->version = 2;
+ $c->composition_update = TIME;
+ $book_id = $c->book_id = $this->getNextId();
+ $c->insert();
+ return $this->selectById($book_id);
+ }
+
+ public function supprime($book_id)
+ {
+ $this->con->execute('DELETE FROM book_pages_versions WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ $this->con->execute('DELETE FROM book_pages WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ return $this->con->execute('DELETE FROM books WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ }
+
+ public function count($limitedToUserRights = false)
+ {
+ $filters = $this->makeWhereFromFiltres();
+ if ($filters == '1=1') {
+ $table = 'books';
+ } else {
+ $table = 'books_vue';
+ }
+
+ $where = '(' . $filters . ')';
+ $where .= $this->limitToUserRights($limitedToUserRights);
+ $r = $this->con->select('SELECT COUNT(*) AS nb FROM ' . $table . ' WHERE ' . $where);
+ return $r->nb;
+ }
+
+ public function getPagesOfBookAt($book_id, $time)
+ {
+ $r = $this->con->select('SELECT * FROM book_pages_versions WHERE book_id=\'' . $this->con->escape($book_id) . '\' ORDER BY `update` ASC');
+ if (!$r->count()) {
+ return $this->getPagesOfBook($book_id);
+ }
+ if ($r->count() == 1) {
+ $pages = unserialize($r->composition);
+ if (null === $pages || !count($pages)) {
+ return $this->getPagesOfBook($book_id);
+ }
+ return $pages;
+ }
+
+ $pages = null;
+ while ($r->fetch()) {
+ if ($r->update > $time) {
+
+ if (is_null($pages)) {
+ return $this->getPagesOfBook($book_id);
+ }
+ $res = unserialize($pages);
+ if (null === $res || !count($res)) {
+ return $this->getPagesOfBook($book_id);
+ }
+ return $res;
+ }
+ if (!count(unserialize($r->composition))) {
+ continue;
+ }
+ $pages = $r->composition;
+ }
+
+ $res = unserialize($pages);
+ if (null === $res || !count($res)) {
+ return $this->getPagesOfBook($book_id);
+ }
+ return $res;
+ }
+
+ public function getDocumentsToUpdate($book_id)
+ {
+ $res = array();
+ $r = $this->con->select('SELECT DISTINCT d.document_id FROM book_pages b,documents d WHERE b.book_id=\'' . $this->con->escape($book_id) . '\' AND d.version=1 AND b.document_id=d.document_id');
+ while ($r->fetch()) {
+ $res[] = $r->document_id;
+ }
+ return $res;
+ }
+
+ public function getPagesOfBook($book_id, $conversion = true, $force = false)
+ {
+ if ($force || !isset(self::$pagesOfBookCache[$book_id])) {
+ $pages = array();
+
+ $sql = 'SELECT b.*,d.numberSections AS num,d.conversionInfos AS conversion,d.pages AS doc_pages,d.version AS version FROM book_pages b JOIN documents d ON d.document_id=b.document_id WHERE b.book_id=\'' . $this->con->escape($book_id) . '\' ORDER BY book_page';
+
+ $r = $this->con->select($sql);
+ while ($r->fetch()) {
+ $n = explode(',', $r->num);
+
+ if (isset($n[$r->document_page - 1])) {
+ $num = $n[$r->document_page - 1];
+ } else {
+ $num = '';
+ }
+ $pages[$r->book_page] = array('document_id' => $r->document_id,
+ 'document_page' => $r->document_page,
+ 'version' => $r->version,
+ 'defaultNum' => $num,
+ 'nb_pages' => $r->doc_pages
+ );
+
+ if ($conversion) {
+ if ($r->conversion != '') {
+ $c = unserialize($r->conversion);
+ $c = $c->pages[$r->document_page];
+ }
+ $qp = array('resolution', 'method', 'quality', 'objects');
+ foreach ($qp as $p) {
+ if (isset($c) && isset($c->$p)) {
+ $pages[$r->book_page][$p] = $c->$p;
+ }
+ }
+ }
+ }
+ if (!count($pages)) {
+ return [];
+ }
+
+ self::$pagesOfBookCache[$book_id] = $pages;
+ }
+ return self::$pagesOfBookCache[$book_id];
+ }
+
+ public function appendDocument($book_id, $document_id)
+ {
+ $r = $this->con->select('SELECT MAX(book_page) AS book_page FROM book_pages WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ $lastPage = is_null($r->book_page) ? 0 : $r->book_page;
+ $this->insertDocument($book_id, $lastPage, $document_id);
+ }
+
+ public function removePage($book_id, $book_page)
+ {
+ // Supprime la page
+ $this->con->execute('DELETE FROM book_pages WHERE book_page=\'' . $this->con->escape($book_page) . '\' AND book_id=\'' . $this->con->escape($book_id) . '\'');
+ // Décale les pages suivantes vers le haut
+ $this->decalePages($book_id, $book_page, -1);
+ }
+
+ public function insertPage($book_id, $after_page, $document_id, $document_page)
+ {
+ // Décale les pages vers le bas
+ $this->decalePages($book_id, $after_page, 1);
+ // Insère la page
+ $c = $this->con->openCursor('book_pages');
+ $c->book_id = $book_id;
+ $c->book_page = $after_page + 1;
+ $c->document_id = $document_id;
+ $c->document_page = $document_page;
+ $c->insert();
+ }
+
+ public function insertDocument($book_id, $after_page, $document_id)
+ {
+ // Obtiens le book
+ $book = $this->selectById($book_id);
+ $num = explode(',', $book->numerotation);
+ // Obtiens le nombre de pages
+ $r = $this->con->select('SELECT pages,numberSections FROM documents WHERE document_id=\'' . $this->con->escape($document_id) . '\'');
+ // Décale les pages vers le bas
+ if ($after_page > 0) {
+ $this->decalePages($book_id, $after_page, $r->pages);
+ }
+ // Insère les pages
+ $c = $this->con->openCursor('book_pages');
+ $c->book_id = $book_id;
+ $c->document_id = $document_id;
+ for ($i = 1; $i <= $r->pages; $i++) {
+ $c->document_page = $i;
+ $c->book_page = $after_page + $i;
+ $c->insert();
+ }
+ // Mets à jour la liste des numéros des pages
+ $before = array_slice($num, 0, $after_page);
+ $after = array_slice($num, $after_page, count($num) - $after_page);
+
+ $newnum = $r->numberSections;
+ if (trim($newnum, ',') == '') {
+ // If no number detected, we create a numeric list from 1
+ $between = range(1, $r->pages);
+ } else {
+ // Else, we use numbers detected at conversion
+ $between = explode(',', $r->numberSections);
+ }
+ $num = array_merge($before, $between, $after);
+ // Mets à jour la numerotation de la publication
+ $c = $this->con->openCursor('books');
+ $c->numerotation = implode(',', $num);
+ $c->composition_update = TIME;
+ $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+
+ $this->saveCompositionVersion($book_id);
+ }
+
+ protected function decalePages($book_id, $after_page, $decalage)
+ {
+ $decalage = ($decalage >= 0) ? '+' . $decalage : $decalage;
+ $this->con->execute('UPDATE book_pages SET book_page=book_page' . $decalage . ' WHERE book_page>' . $this->con->escape($after_page) . ' AND book_id=\'' . $this->con->escape($book_id) . '\'');
+ }
+
+ public function getListe($orderby = null, $sens = null, $limit = null, $limitedToUserRights = false)
+ {
+ if (!is_null($this->q)) {
+ $where = '(';
+ if ($this->search_id) {
+ $where .= ' book_id=\'' . $this->con->escape($this->q) . '\' OR ';
+ }
+
+ if (!cubeMath::is_int($this->q)) {
+ $where .= 'nom LIKE \'%' . $this->con->escape($this->q) . '%\'';
+ $daoClient = new commonDAOClient($this->con);
+ $where .= ' OR proprietaire_id IN(' . $daoClient->querySearchByName($this->q) . ') OR ';
+ }
+ $limit = null;
+ $where .= '1=2)';
+ } else {
+ $where = '(' . $this->makeWhereFromFiltres() . ')';
+ }
+ $where .= $this->limitToUserRights($limitedToUserRights);
+
+ $orderby = is_null($orderby) ? 'book_id' : $orderby;
+ $sens = is_null($sens) ? 'DESC' : $sens;
+ $limit = is_null($limit) ? '' : $this->con->limit($limit);
+
+ $sql = 'SELECT * FROM books_vue WHERE ' . $where . ' ORDER BY ' . $orderby . ' ' . $sens . ' ' . $limit;
+ $r = $this->con->select($sql);
+ return $this->factory($r);
+ }
+
+ protected function limitToUserRights($utilisateur)
+ {
+ if ($utilisateur) {
+ if (wsDroits::admin()) {
+ return '';
+ }
+ return ' AND proprietaire IN (' . $utilisateur->ws_rights . ')';
+ }
+ return '';
+ }
+
+ protected function makeWhereFromFiltres()
+ {
+ if (!is_null($this->filtres)) {
+ $w = array('1=1');
+ if (commonFiltre::test('admin_book', $this->filtres)) {
+ $w[] = 'super_admin IN (' . implode(',', array_keys($this->filtres['admin_book'])) . ')';
+ }
+ if (commonFiltre::test('status_book', $this->filtres)) {
+ $w[] = 'status IN(' . implode(',', array_keys($this->filtres['status_book'])) . ')';
+ }
+ if (commonFiltre::test('revendeur_book', $this->filtres)) {
+ $v = array_keys($this->filtres['revendeur_book']);
+ $values = array();
+ foreach ($v as $r) {
+ $values[] = $this->con->escape($r);
+ }
+
+
+ $w[] = 'facturable IN(\'' . implode('\',\'', $values) . '\')';
+ }
+ return implode(' AND ', $w);
+ } else {
+ return '1=1';
+ }
+ }
+
+ public function setChapters($book_id, $json)
+ {
+ $chapters = json_decode($json, true);
+ $res = array();
+
+ foreach ($chapters as $c) {
+ $c['label'] = trim($c['label']);
+ $n = (string)$c['page'];
+ $c['label'] = trim(preg_replace('|\s+' . $n . '$|iu', '', $c['label']));
+ $res[] = $c;
+ }
+
+ $json_chapters = json_encode($res);
+
+ $c = $this->con->openCursor('books');
+ $c->chapters = $json_chapters;
+ $c->changedate = TIME;
+ $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+
+ if ($json_chapters && $json_chapters != '[]') {
+ if (count($res) == 1) {
+ if ($res[0]['label'] == '' && $res[0]['page'] == '') {
+ return;
+ }
+ }
+ $c = $this->con->openCursor('books_chapters_versions');
+ $c->book_id = $book_id;
+ $c->chapters = $json_chapters;
+ $c->time = TIME;
+ $c->insert();
+ }
+ }
+
+ public function setSpecialLinksAndRulers($book_id, $links, $rulers)
+ {
+ $c1 = $this->con->openCursor('special_links_versions');
+ $c = $this->con->openCursor('books');
+
+ if (is_string($links)) {
+ $links = json_encode(json_decode($links, false));
+ }
+ if (is_string($rulers)) {
+ $rulers = json_encode(json_decode($rulers, false));
+ }
+
+
+ $links = wsLinks::encryptLinks(json_decode($links));
+
+
+ if (is_array($links)) {
+ $links = json_encode($links);
+ }
+ if (is_array($rulers)) {
+ $rulers = json_encode($rulers);
+ }
+
+ $c1->links = $c->specialLinks = $links;
+ $c1->rulers = $c->specialRulers = $rulers;
+ $c1->update = $c->changedate = TIME;
+ $c1->book_id = $book_id;
+ $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ try {
+ $c1->insert();
+ } catch (Exception $e) {
+ try {
+ $c1->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\' AND `update`=' . TIME);
+ } catch (Exception $e) {
+
+ }
+ }
+ }
+
+ public function setTheme($book_id, $theme)
+ {
+ $c = $this->con->openCursor('books');
+ $c->theme = $theme;
+ $c->changedate = TIME;
+ $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ }
+
+ public function setStatus($book_id, $status)
+ {
+ $c = $this->con->openCursor('books');
+ if ($status < 2) {
+ $c->tache = 0;
+ }
+ $c->status = $status;
+ $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ return $this->selectById($book_id);
+ }
+
+ public function setChaptersFromOldFluidbook($book_id)
+ {
+ $book = $this->selectById($book_id);
+ $n = explode(',', $book->numerotation);
+
+ $xml = simplexml_load_file('https://ws.fluidbook.com/books/' . $book_id . '/data/links.xml');
+ $res = array();
+ $chapters = $xml->xpath('//chapters');
+ foreach ($chapters as $ch) {
+ $c = array();
+ $c['label'] = (string)$ch->txt;
+
+ $p = intval((string)$ch->page);
+ if ($p <= 0) {
+ continue;
+ }
+ $c['page'] = $n[$p];
+ $c['level'] = intval((string)$ch->level);
+ $res[] = $c;
+ }
+
+ $c = $this->con->openCursor('books');
+ $c->chapters = json_encode($res);
+ $c->changedate = TIME;
+ $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ }
+
+ public function saveCompositionVersion($book_id, $time = null)
+ {
+ $time = is_null($time) ? TIME : $time;
+
+ $pages = $this->getPagesOfBook($book_id, true, true);
+
+ $c = $this->con->openCursor('book_pages_versions');
+ $c->update = $time;
+ $c->book_id = $book_id;
+ $c->composition = serialize($pages);
+ $c->insert();
+ }
+
+ public function setLang($book_id, $base, $traductions)
+ {
+ // Cleanup user translations
+ $traductions = json_decode($traductions, true);
+ foreach ($traductions as $k => $v) {
+ $traductions[$k] = $v;
+ }
+
+ $daoLang = new wsDAOLang($this->con);
+ $lang = $daoLang->selectById($base);
+ // Cleanup base translations
+ $baseTraductions = $lang->traductions;
+ foreach ($baseTraductions as $k => $v) {
+ $baseTraductions[$k] = $v;
+ }
+ // Then compare them. If there is no differences, we don't save translations in the book
+ if ($traductions == $baseTraductions) {
+ $t = '';
+ } else {
+ $t = json_encode($traductions);
+ }
+
+ $c = $this->con->openCursor('books');
+ $c->lang = $base;
+ $c->traductions = $t;
+ $c->changedate = TIME;
+ $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ }
+
+ public function setSettings($book_id, $settings)
+ {
+ $book = $this->selectById($book_id);
+ $parametres = $book->parametres;
+ $new = $settings;
+ $root = ['lang', 'proprietaire_id', 'status'];
+ $rootSettings = [];
+ foreach ($new as $k => $v) {
+ if ($k == '_empty_') {
+ continue;
+ }
+ if (in_array($k, $root)) {
+ $rootSettings[$k] = $v;
+ } else {
+ try {
+ $parametres->$k = $v;
+ } catch (Exception $e) {
+
+ }
+ }
+ }
+
+
+ $ip = array();
+ if (isset($parametres->stats_exclude_ip) && trim($parametres->stats_exclude_ip) != '') {
+ $list = $parametres->stats_exclude_ip;
+ $list = str_replace("\r", "\n", $list);
+ $e = explode("\n", $list);
+ foreach ($e as $i) {
+ $i = trim($i);
+ if ($i == '') {
+ continue;
+ }
+ $long = ip2long($i);
+ if ($long !== false) {
+ $ip[] = $long;
+ }
+ }
+ }
+
+ $file = '/home/stats/www/exclude/' . $book_id;
+
+ if (count($ip)) {
+ file_put_contents($file, implode(',', $ip));
+ chmod($file, 0777);
+ chown($file, 'stats');
+ } else if (file_exists($file)) {
+ unlink($file);
+ }
+
+ $c = $this->con->openCursor('books');
+ $c->nom = $parametres->title;
+ $c->parametres = serialize($parametres);
+ $c->changedate = TIME;
+ foreach ($rootSettings as $k => $v) {
+ $c->$k = $v;
+ }
+ $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ }
+
+ public function setProprietaire($book_id, $proprietaire_id)
+ {
+ $c = $this->con->openCursor('books');
+ $c->proprietaire = $proprietaire_id;
+ $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ }
+
+ public function setTache($book_id, $tache)
+ {
+ $c = $this->con->openCursor('books');
+ $c->tache = $tache;
+ $c->status = 2;
+ $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ }
+
+ public function setVersion($book_id, $version)
+ {
+ $c = $this->con->openCursor('books');
+ $c->version = $version;
+ $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ }
+
+ public function touch($book_id)
+ {
+ $c = $this->con->openCursor('books');
+ $c->changedate = TIME;
+ $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ }
+
+ public function touchCompile($book_id, $version = 'all')
+ {
+ $c = $this->con->openCursor('books');
+ if ($version == '2') {
+ $c->compiledate = TIME;
+ } elseif ($version == '1') {
+ $c->compile1date = TIME;
+ } elseif ($version == 'html5') {
+ $c->compilehtml5date = TIME;
+ } else {
+ $c->compiledate = TIME;
+ $c->compile1date = TIME;
+ $c->compilehtml5date = TIME;
+ }
+ $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ }
+
+ public function isUpToDate($book, $version)
+ {
+ $version = (string)$version;
+ if ($version == '2') {
+ if (!file_exists(WS_BOOKS . '/final/' . $book->book_id)) {
+ return false;
+ }
+ if ($book->compiledate < $book->changedate) {
+ return false;
+ }
+ } else if ($version == '1') {
+ // V1
+ if (!file_exists(WS_BOOKS . '/finalv1/' . $book->book_id . '/index.swf')) {
+ return false;
+ }
+ if ($book->compile1date < $book->changedate) {
+ return false;
+ }
+ } else if ($version == 'html5') {
+ return false;
+ // HTML5
+ $checks = array($book->changedate, cubeFiles::filemtimeRecursive(WS_BOOKS . '/working/' . $book->book_id), cubeFiles::filemtimeRecursive(WS_COMPILE_ASSETS . '/_html5'), cubeFiles::filemtimeRecursive(ROOT . '/inc/ws/Util/html5'));
+ foreach ($checks as $check) {
+ if ($check > $book->compilehtml5date) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ public function setComposition($book_id, $pages)
+ {
+ $numerotation = array();
+ $nb_pages = 0;
+ foreach ($pages as $p) {
+ $numerotation[] = $p->virtual;
+ $nb_pages++;
+ }
+
+ $book = $this->selectById($book_id);
+ $parametres = $book->parametres;
+ $parametres->pages = $nb_pages;
+
+ $c = $this->con->openCursor('books');
+ $c->parametres = serialize($parametres);
+ $c->numerotation = implode(',', $numerotation);
+ $c->changedate = TIME;
+
+ // Check if composition need to be updated
+ $r = $this->con->select('SELECT * FROM book_pages WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ $tab = array();
+ $now = array();
+ $ref = array();
+ while ($r->fetch()) {
+ $ref[$r->book_page] = array((int)$r->document_id, (int)$r->document_page);
+ }
+ $i = 1;
+ foreach ($pages as $p) {
+ $now[$i] = array((int)$p->document_id, (int)$p->document_page);
+ $i++;
+ }
+ if ($now != $ref) {
+ $this->con->execute('DELETE FROM book_pages WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+
+ $c1 = $this->con->openCursor('book_pages');
+ $c1->book_id = $book_id;
+ $i = 1;
+ foreach ($pages as $p) {
+ $c1->document_id = $p->document_id;
+ $c1->document_page = $p->document_page;
+ $c1->book_page = $i;
+ $c1->insert();
+ $i++;
+ }
+ $c->composition_update = TIME;
+ $this->saveCompositionVersion($book_id);
+ }
+
+ $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ }
+
+ public function setInstallDir($book_id, $dir, $server)
+ {
+ $col = 'dir_' . $server;
+
+ $c = $this->con->openCursor('books');
+ $c->$col = $dir;
+ $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ }
+
+ public function makeTextsIndexes($book, $pages, &$index, &$textes, $simple = false)
+ {
+ global $core;
+ $prefix = '';
+ if ($book->parametres->textExtraction == 'poppler') {
+ $prefix = 'p';
+ } else if ($book->parametres->textExtraction == 'fluidbook') {
+ $prefix = 'f';
+ }
+
+ $dir = WS_BOOKS . '/index/' . $book->book_id;
+ if ($book->parametres->ignoreSearchSeparators != '') {
+ $dir .= '/' . sha1($book->parametres->ignoreSearchSeparators);
+ }
+ if (!file_exists($dir)) {
+ mkdir($dir, 0777, true);
+ }
+
+ if ($simple) {
+ $ifilec = $dir . '/' . $prefix . 'sindex.json';
+ } else {
+ $ifilec = $dir . '/' . $prefix . 'index.json';
+ }
+ $tfilec = $dir . '/' . $prefix . 'textes.json';
+
+ if (CubeIT_Util_Gzip::file_exists($ifilec) && CubeIT_Util_Gzip::file_exists($tfilec) && (min(CubeIT_Util_Gzip::filemtime($ifilec), CubeIT_Util_Gzip::filemtime($tfilec)) >= max($book->composition_update, filemtime(__FILE__), filemtime(WS_TOOLS . '/fwstk/out/artifacts/fwstk_jar/fwstk.jar')))) {
+ $index = CubeIT_Util_Gzip::file_get_contents($ifilec);
+ $textes = CubeIT_Util_Gzip::file_get_contents($tfilec);
+ return;
+ }
+
+ if ($book->parametres->ignoreSearchSeparators != "") {
+ $docs = array();
+ foreach ($pages as $p => $i) {
+ $docs[] = $i['document_id'];
+ }
+ $docs = array_unique($docs);
+
+ foreach ($docs as $doc) {
+ $out = wsDocument::getDir($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);
+ $fwstk->setArg('--threads 1');
+ $fwstk->setArg('--ignoreSeparators ' . $book->parametres->ignoreSearchSeparators);
+ $fwstk->execute();
+ }
+ }
+
+ $index = array();
+ $textes = array();
+ foreach ($pages as $book_page => $infos) {
+ $tfile = wsDocument::getDir($infos['document_id']) . $prefix . 'p' . $infos['document_page'] . '.txt';
+ $ifile = wsDocument::getDir($infos['document_id']) . $prefix . 'i' . $infos['document_page'] . '.txt';
+
+ if (!file_exists($tfile) || !file_exists($ifile)) {
+ $daoDoc = new wsDAODocument($core->con);
+ $out = wsDocument::getDir($infos['document_id']);
+
+ $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();
+ }
+
+ CubeIT_Util_Gzip::compressIfNotCompressed($tfile);
+ CubeIT_Util_Gzip::compressIfNotCompressed($ifile);
+ $text = CubeIT_Util_Gzip::file_get_contents($tfile);
+ $ipage = CubeIT_Util_Gzip::file_get_contents($ifile);
+
+ if ($simple) {
+ $this->fillIndexWithWordsSimple($index, $book_page, $ipage);
+ } else {
+ $this->fillIndexWithWords($index, $book_page, $ipage);
+ }
+ $textes[$book_page] = $text;
+ }
+ ksort($index);
+
+ $textes = json_encode($textes);
+ $index = json_encode($index);
+
+ CubeIT_Util_Gzip::file_put_contents($tfilec, $textes);
+ CubeIT_Util_Gzip::file_put_contents($ifilec, $index);
+ }
+
+ public function makeHighlightIndex($book, $pages)
+ {
+ $jar = WS_TOOLS . '/fwstk/out/artifacts/fwstk_jar/fwstk.jar';
+
+ $daoDoc = new wsDAODocument($this->con);
+ $res = new stdClass();
+ foreach ($pages as $book_page => $infos) {
+ $fby = wsDocument::getDir($infos['document_id']) . 'html/p' . $infos['document_page'] . '.fby';
+ // Refresh highlight data if fby file doesn't exists or if fwstk has been updated
+ $fbymtime = @filemtime($fby);
+ if (!file_exists($fby) || filemtime($jar) > $fbymtime || filemtime(__FILE__) > $fbymtime) {
+ $doc = $daoDoc->selectById($infos['document_id']);
+ $doc->getHighlightTextsData();
+ }
+
+ if (file_exists($fby)) {
+ $words = CubeIT_Util_Json::decode(file_get_contents($fby), CubeIT_Util_Json::TYPE_OBJECT);
+
+ if (is_array($words)) {
+ foreach ($words as $i => $w) {
+ $word = $w->word;
+ $word = trim($word, "\0");
+ if ($word == '') {
+ continue;
+ }
+ unset($w->word);
+ $w->page = $book_page;
+ $w->idx = $i;
+ if (!isset($res->{$word})) {
+ $res->{$word} = array();
+ }
+ $res->{$word}[] = $w;
+ }
+ }
+ }
+ }
+ return $res;
+ }
+
+ protected function _escapeIndex($str)
+ {
+ $todelete = array('\ufffd');
+ foreach ($todelete as $d) {
+ $str = str_replace($d, '', $str);
+ }
+ return $str;
+ }
+
+ protected function fillIndexWithWordsSimple(&$index, $page, $ipage)
+ {
+ $twords = explode("\n", trim($ipage));
+
+ foreach ($twords as $woadata) {
+ $w1 = explode(',', trim($woadata));
+ if (count($w1) <= 1) {
+ continue;
+ }
+ list($woa, $worddata) = $w1;
+ $e = explode("\t", $worddata, 2);
+ if (count($e) < 2) {
+ continue;
+ }
+ list($total, $wordslist) = $e;
+
+ if ($woa == '') {
+ continue;
+ }
+
+ if (!isset($index[$woa])) {
+ $index[$woa] = array('t' => 0, 'p' => array());
+ }
+ $index[$woa]['t'] += $total;
+
+ $words = explode("\t", $wordslist);
+ foreach ($words as $word) {
+ list($wordwa, $count) = explode('$', $word, 2);
+ if (!isset($index[$woa]['p'][$page])) {
+ $index[$woa]['p'][$page] = 0;
+ }
+ $index[$woa]['p'][$page] += $count;
+ }
+ }
+ }
+
+ protected function fillIndexWithWords(&$index, $page, $ipage)
+ {
+ $twords = explode("\n", trim($ipage));
+
+ foreach ($twords as $woadata) {
+ $w1 = explode(',', trim($woadata));
+ if (count($w1) <= 1) {
+ continue;
+ }
+ list($woa, $worddata) = $w1;
+ $e = explode("\t", $worddata, 2);
+ if (count($e) < 2) {
+ continue;
+ }
+ list($total, $wordslist) = $e;
+
+ if ($woa == '') {
+ continue;
+ }
+
+ if (!isset($index[$woa])) {
+ $index[$woa] = array('t' => 0, 'w' => array());
+ }
+ $index[$woa]['t'] += $total;
+
+ $words = explode("\t", $wordslist);
+
+ foreach ($words as $word) {
+ list($wordwa, $count) = explode('$', $word, 2);
+ if (!isset($index[$woa]['w'][$wordwa])) {
+ $index[$woa]['w'][$wordwa] = array('t' => 0, 'p' => array());
+ }
+ if (!isset($index[$woa]['w'][$wordwa]['p'][$page])) {
+ $index[$woa]['w'][$wordwa]['p'][$page] = 0;
+ }
+ $index[$woa]['w'][$wordwa]['t'] += $count;
+ $index[$woa]['w'][$wordwa]['p'][$page] += $count;
+ }
+ }
+ }
+
+ public function getNumerotationFromDocs($book_id)
+ {
+ $pages = $this->getPagesOfBook($book_id);
+ }
+
+ public function compileTemp($book_id, $version, $dir)
+ {
+ if ($version == 'ha' || $version == 'hi') {
+ if ($version == 'ha') {
+ $os = 'android';
+ } elseif ($version == 'hi') {
+ $os = 'ios';
+ }
+ $packager = new wsPackagerPhonegap($book_id, $dir, false, true, $os);
+ $packager->makePackage(false);
+ }
+ }
+
+ public function compile($book_id, $version = 'all', $complete = false, $force = false, $dev = false, $book = null, $delete = true)
+ {
+ if (is_null($book_id) || !$book_id) {
+ return;
+ }
+
+ $v1 = $v2 = $html5 = false;
+
+ if ($version == 'all') {
+ $v1 = $v2 = $html5 = true;
+ } else if ($version == '1') {
+ $v1 = true;
+ } else if ($version == '2') {
+ $v2 = true;
+ } elseif ($version == 'html5') {
+ $html5 = true;
+ }
+
+ if (null === $book) {
+ $book = $this->selectById($book_id);
+ }
+ $pages = $this->getPagesOfBook($book_id);
+
+ if (!$force) {
+ $v1 = $v1 && !$this->isUpToDate($book, 1);
+ $v2 = $v2 && !$this->isUpToDate($book, 2);
+ $html5 = $html5 && !$this->isUpToDate($book, 'html5');
+ } else {
+ $v1 = false;
+ $html5 = true;
+ $v2 = true;
+ }
+
+ $res = '';
+ if ($v1) {
+ fb(time(), 'Compile V1');
+ $res .= $this->compile1($book_id, $book, $pages);
+ $this->touchCompile($book_id, '1');
+ }
+ if ($v2) {
+ fb(time(), 'Compile V2');
+ $res .= $this->compile3($book_id, $complete, $book, $pages);
+ $this->touchCompile($book_id, '2');
+ }
+ if ($html5) {
+ fb(time(), 'Compile HTML5');
+ $res .= $this->compileHTML5($book_id, $book, $dev, $delete);
+ $this->touchCompile($book_id, 'html5');
+ }
+ if ($v1 || $v2) {
+ fb(time(), 'Compile PDF & Widget');
+ $this->compilePDF($book, $pages);
+ $this->compileWidget($book, $pages);
+ }
+
+ fb(time(), 'End Compile');
+ return $res;
+ }
+
+ public function compile1($book_id, $book, $pages)
+ {
+ $finalDir = WS_BOOKS . '/finalv1/' . $book_id . '/';
+ $packager = new wsPackagerV1($book_id, $finalDir, false);
+ $packager->makePackage(false);
+ }
+
+ public function compile3($book_id, $complete, $book, $pages)
+ {
+ $res = '';
+
+ $compilerDir = WS_BOOKS . '/datasCompiler/' . $book_id . '/';
+ $finalDir = WS_BOOKS . '/final/' . $book_id . '/';
+
+ $vdir = new CubeIT_Files_VirtualDirectory($finalDir);
+
+ $debug = false;
+
+ $flex = new cubeFlexCompiler('FluidbookDatas', $compilerDir, 'flash.display.Sprite', explode(';', AS3_SOURCES), MXMLC_PATH, 10, 30, 800, 600, $debug);
+ $flexLight = new cubeFlexCompiler('FluidbookDatasLight', $compilerDir, 'flash.display.Sprite', explode(';', AS3_SOURCES), MXMLC_PATH, 10, 30, 800, 600, $debug);
+
+ $filesToCopy = array();
+ $this->compileFlex($book_id, $complete, $compilerDir, $vdir, $filesToCopy, $book, $pages, $flex, $flexLight, $finalDir);
+
+ $res .= $flex->compile() . "\n\n-------------------\n\n";
+ $flexLight->addVariable('datasSize', filesize($compilerDir . '/FluidbookDatas.swf'));
+ $res .= $flexLight->compile();
+
+ $filesToCopy['data/fd.swf'] = $compilerDir . '/FluidbookDatas.swf';
+ $filesToCopy['data/fdl.swf'] = $compilerDir . '/FluidbookDatasLight.swf';
+
+ // Copy of files
+ // Check if dest dir exists
+
+ foreach ($filesToCopy as $local => $source) {
+ $localPath = $local;
+ $vdir->copy($source, $localPath);
+ }
+
+ $workingDir = WS_BOOKS . '/working/' . $book_id . '/';
+ $vdir->copyDirectory($workingDir . 'media', 'data');
+ $vdir->sync(true);
+
+ return $res;
+ }
+
+ public function copy($source, $dest)
+ {
+ copy($source, $dest);
+ touch($dest, filemtime($source));
+ }
+
+ public static function getDocumentPage($book_id, $book_page)
+ {
+ global $core;
+ $dao = new wsDAOBook($core->con);
+ $pages = $dao->getPagesOfBook($book_id);
+ return $pages[$book_page];
+ }
+
+ public function compileAir($book_id)
+ {
+ $compilerDir = WS_BOOKS . '/air/' . $book_id . '/compiler';
+ $finalDir = WS_BOOKS . '/air/' . $book_id . '/';
+
+ $book = $this->selectById($book_id);
+ $pages = $this->getPagesOfBook($book_id);
+
+ $src = AS3_FLUIDBOOK_SOURCES . '/_src/';
+ $lib10 = AS3_FLUIDBOOK_SOURCES . '/lib10/';
+ $libs = array(
+ $src,
+ $lib10,
+ AS3_SOURCES,
+ $src . 'lib/fluidbook3dLibrary.swc',
+ $src . 'lib/mdm.swc',
+ $lib10 . 'flash.swc',
+ $lib10 . 'flex.swc',
+ $lib10 . 'framework.swc',
+ );
+
+ wsSVN::updateToLastRevision();
+
+ $swf = 'FluidbookAirProjector' . $book_id;
+ $flex = new cubeFlexCompiler($swf, $compilerDir, 'com.fluidbook.player.AIRMain', $libs, '/usr/local/flex/bin/mxmlc', 'air', 45, 800, 600, true);
+
+ $this->compileFlex($book_id, true, $compilerDir, $finalDir, $filesToCopy, $book, $pages, $flex, $flex);
+ $res = $flex->compile();
+
+ $air = new cubeAIRCompiler($swf . '.swf', '/usr/local/flex/bin', $compilerDir, '2.0');
+ $air->setApplicationDatas('com.fluidbook' . $book_id, $book->parametres->title, $book->parametres->title, cubeText::str2URL($book->parametres->title), $book->lang);
+ $air->setInitialWindow($book->parametres->title);
+ $res .= $air->compile();
+
+ return $res;
+ }
+
+ public function compileFlex($book_id, $complete, $compilerDir, $vdir, &$filesToCopy, $book, $pages, $flex, $flexLight)
+ {
+ /* @var $vdir CubeIT_Files_VirtualDirectory */
+
+ cubePHP::neverStop();
+ /* @var $flex cubeFlexCompiler */
+
+ $workingDir = WS_BOOKS . '/working/' . $book_id . '/';
+
+ $res = '';
+
+ $daoDoc = new wsDAODocument($this->con);
+ $firstDoc = $daoDoc->selectById($pages[1]['document_id']);
+ $size = $firstDoc->generalInfos['size'];
+
+ $daoLang = new wsDAOLang($this->con);
+ $lang = $daoLang->selectById($book->lang);
+
+ $langs = $daoLang->selectAll();
+
+ $daoTheme = new wsDAOTheme($this->con);
+ $theme = $daoTheme->getThemeOfBook($book_id, true);
+
+ $daoSignature = new wsDAOSignature($this->con);
+ $signature = $daoSignature->selectById($book->parametres->signature);
+
+ $exportSignature = array('main' => $signature->main,
+ 'mainLink' => $signature->mainLink,
+ 'partner' => $signature->partner,
+ 'partnerLink' => $signature->partnerLink);
+
+ $index = '';
+ $textes = '';
+ $pageLabels = array();
+
+ $hash = $book_id;
+ $hash .= 'kjgl!az4.';
+ $hash .= count($pages);
+ $hash .= round($size[0], 3);
+
+ $hash = sha1($hash);
+
+ $this->makeTextsIndexes($book, $pages, $index, $textes);
+
+ $daoDoc->getLinksAndRulers($book_id, $links, $rulers);
+
+ $audiodescription = array();
+
+ $imagesassets = array();
+ $id = 1;
+ $ignoreLinks = array();
+ foreach ($links as $id => $link) {
+ $links[$id]['id'] = $id;
+ $skipCopyAsset = false;
+
+ if (isset($link['image']) && $link['image']) {
+ $workingFile = $workingDir . '/' . $link['image'];
+ $assetId = 'link_datas_i_' . md5($link['image']);
+
+ if (isset($imagesassets[$assetId])) {
+
+ } else {
+ if (file_exists($workingFile)) {
+ if ($link['page'] <= 1) {
+ $flexLight->addBitmap($workingFile, $assetId);
+ } else {
+ $flex->addBitmap($workingFile, $assetId);
+ }
+ }
+ $imagesassets[$assetId] = true;
+ }
+ }
+
+ if ($link['type'] == 16 && $book->parametres->linkFilePrefix) {
+ if (!CubeIT_Util_Url::isDistant($link['to'])) {
+ $skipCopyAsset = true;
+ $links[$id]['to'] = $book->parametres->linkFilePrefix . $link['to'];
+ }
+ }
+
+ if ($link['type'] == 15) {
+ if (isset($imagesassets[$id])) {
+ continue;
+ }
+ if ($link['page'] <= 1) {
+ $flexLight->addBitmap($workingDir . '/' . $link['to'], 'link_datas_' . $id);
+ } else {
+ $flex->addBitmap($workingDir . '/' . $link['to'], 'link_datas_' . $id);
+ }
+ $imagesassets[$id] = true;
+ } else if (in_array($link['type'], array(4, 6, 7, 9, 16, 17, 25))) {
+ if (!$skipCopyAsset) {
+ $workingFile = $workingDir . '/' . $link['to'];
+ if (file_exists($workingFile)) {
+ $filesToCopy['data/' . $link['to']] = $workingFile;
+ }
+
+ if ($link['type'] == 4) {
+ $poster = $link['to'];
+ $e = explode('.', $poster);
+ array_pop($e);
+ array_push($e, 'jpg');
+ $poster = implode('.', $e);
+
+ $workingFile = $workingDir . '/' . $poster;
+ if (file_exists($workingFile)) {
+ $filesToCopy['data/' . $poster] = $workingFile;
+ }
+ }
+ }
+ }
+
+ if ($link['type'] == 25) {
+ $audiodescription[$link['page']] = $link['to'];
+ $ignoreLinks[] = $id;
+ }
+ if ($link['type'] == 26) {
+ $pageLabels[$link['to']] = $link['page'];
+ $ignoreLinks[] = $id;
+ }
+ }
+
+ foreach ($ignoreLinks as $ignoreLink) {
+ unset($links[$ignoreLink]);
+ }
+ $links = array_values($links);
+
+ $externalsOptions = array('ongletsSWF', 'tabs2DSWF', 'externalChapters', 'externalArchives', 'ambientSound');
+ foreach ($externalsOptions as $e) {
+ if (isset($book->parametres->$e) && $book->parametres->$e != '') {
+ $f = $workingDir . '/' . $book->parametres->$e;
+ if (file_exists($f)) {
+ $filesToCopy['data/' . $book->parametres->$e] = $f;
+ }
+ }
+ }
+
+ $flex->addVariable('audiodescription', $audiodescription, false, true, "JSONObject");
+ $flex->addVariable('pagelabels', $pageLabels, false, true, 'JSONObject');
+ $flex->addVariable('links', $links, false, true, 'JSONObject');
+
+ $flex->addVariable('signature', $exportSignature, false, true, 'JSONObject');
+ $flexLight->addVariable('datas', $book->parametres->toStandardObject(), false, true, 'JSONObject');
+ $flexLight->addVariable('id', $book_id, false, true, 'uint');
+ $flexLight->addVariable('cid', $book->cid, false, true, 'String');
+
+ $traductions = (!count($book->traductions)) ? $lang->traductions : $book->traductions;
+ $allTraductions = array();
+ foreach ($langs as $l) {
+ $allTraductions[$l->lang_id] = $l->traductions;
+ }
+
+ $flex->addVariable('traductions', $traductions, false, true, 'JSONObject', false);
+ $flex->addVariable('allTraductions', $allTraductions, false, true, 'JSONObject');
+ $flex->addVariable('chapters', $book->chapters, false, true, 'JSONObject');
+ $flex->addVariable('extras', '<extras>' . $book->extras . '</extras>', false, true, 'XML');
+ $flex->addVariable('numerotation', $book->numerotation, false, true, 'String');
+ $flexLight->addVariable('theme', $theme->parametres->toStandardObject(), false, true, 'JSONObject');
+ $flexLight->addVariable('pages', $book->parametres->pages);
+ $flexLight->addVariable('fwidth', round($size[0], 4), false, true, 'Number');
+ $flexLight->addVariable('fheight', round($size[1], 4), false, true, 'Number');
+ $flexLight->addVariable('pagesInDatas', $complete, false, true, 'Boolean');
+ $flex->addVariable('index', $index, false, true, 'JSONObject', false, false);
+ $flex->addVariable('textes', $textes, false, true, 'JSONObject', false, false);
+
+ $rasterized = array();
+ $sizes = array();
+
+ foreach ($pages as $i => $infos) {
+ $base = wsDocument::getDir($infos['document_id']) . 'p' . $infos['document_page'];
+ $baset = wsDocument::getDir($infos['document_id']) . 't' . $infos['document_page'];
+ $swffile = $base . '.swf';
+ if (file_exists($swffile)) {
+ clearstatcache(true, $swffile);
+ $fsize = filesize($swffile);
+ } else {
+ $fsize = 0;
+ }
+
+ if ($complete) {
+ $flex->addSWF($swffile, 'page' . $i);
+ } else {
+ $filesToCopy['data/p' . $i . '.swf'] = $swffile;
+ if ($infos['method'] >= wsDocument::BARBARE_PNM) {
+ $rasterized[$i] = true;
+ $filesToCopy['data/t' . $i . '.swf'] = $baset . '.swf';
+ } else {
+ $rasterized[$i] = false;
+ }
+ }
+
+ $thumb = false;
+ if ($book->parametres->pdfThumbnails) {
+ $thumb = wsPDFConvert::getThumbFromPDF($workingDir . '/' . $book->parametres->pdfThumbnails, $i);
+ }
+ if (!$thumb) {
+ $thumb = $base . '.jpg';
+ }
+
+ if ($i == 1) {
+ $flexLight->addBitmap($thumb, 'thumb1');
+ } else {
+ $flex->addBitmap($thumb, 'thumb' . $i);
+ }
+ $sizes[$i] = $fsize;
+ }
+
+ $flexLight->addVariable('rasterized', $rasterized, false, true, 'JSONObject');
+ $flexLight->addVariable('sizes', $sizes, false, true, 'JSONObject');
+
+ if ($book->parametres->soundTheme != '') {
+ $flex->addSound(WS_SOUNDS . '/' . $book->parametres->soundTheme . '/corner-drag.mp3', 'soundDragCorner');
+ $flex->addSound(WS_SOUNDS . '/' . $book->parametres->soundTheme . '/corner-release.mp3', 'soundReleaseCorner');
+ $flex->addSound(WS_SOUNDS . '/' . $book->parametres->soundTheme . '/page-flip-1.mp3', 'soundPage0');
+ $flex->addSound(WS_SOUNDS . '/' . $book->parametres->soundTheme . '/page-flip-2.mp3', 'soundPage1');
+ $flex->addSound(WS_SOUNDS . '/' . $book->parametres->soundTheme . '/cover-flip.mp3', 'soundCover0');
+ }
+ // Theme assets
+ $themeRoot = WS_THEMES . '/' . $theme->theme_id . '/';
+
+ if ($theme->parametres->backgroundImage != '') {
+ $flexLight->addBitmap($themeRoot . $theme->parametres->backgroundImage, 'background');
+ }
+ if ($theme->parametres->menuImage != '') {
+ $flex->addBitmap($themeRoot . $theme->parametres->menuImage, 'menu');
+ }
+ if ($theme->parametres->logoLoader != '') {
+ $flexLight->addBitmap($themeRoot . $theme->parametres->logoLoader, 'logoLoader');
+ }
+ if ($theme->parametres->topBar != '') {
+ $flexLight->addBitmap($themeRoot . $theme->parametres->topBar, 'topBar');
+ }
+ if ($theme->parametres->logo != '') {
+ $flex->addBitmap($themeRoot . $theme->parametres->logo, 'logo');
+ }
+ if ($theme->parametres->afterSearch != '') {
+ $flex->addBitmap($themeRoot . $theme->parametres->afterSearch, 'aftersearch');
+ }
+ if ($theme->parametres->favicon != '') {
+ $filesToCopy['data/fluidbook.ico'] = $themeRoot . 'fluidbook.ico';
+ }
+
+ // Icons assets
+ $iconsRoot = WS_ICONS . '/' . $theme->parametres->iconSet . '/';
+ foreach (wsIcone::$files as $file) {
+ $flex->addBitmap($iconsRoot . 'nav-' . $file . '.png', 'nav_' . $file);
+ }
+ // Share icons
+ $iconsRoot = WS_ICONS . '/share/';
+ foreach (wsIcone::$share as $file) {
+ $flex->addBitmap($iconsRoot . 'share-' . $file . '.png', 'share_' . $file);
+ }
+
+ // Multilang
+ if (trim($book->parametres->multilang) != '') {
+ $m = str_replace("\r", "\n", trim($book->parametres->multilang));
+ $langs = explode("\n", $m);
+ $langNames = array();
+ $countryNames = array();
+ $iso = l10n::getISOcodes();
+ $chars = '()';
+ $vuFlags = array();
+ foreach ($langs as $l) {
+ list($mlang, $flag, $url) = explode(',', trim($l), 3);
+ if (!isset($vuFlags[$flag])) {
+ $flex->addBitmap(cubeMedia::getFlagFile($flag), 'flag_' . $flag);
+ $vuFlags[$flag] = true;
+ }
+ $ll = explode('-', $mlang);
+ $n = cubeText::ucfirst($iso[$ll[0]]);
+ $langNames[$mlang] = $n;
+ $cn = cubeCountry::getCountryName($flag, $mlang);
+ $countryNames[$mlang . '_' . $flag] = $cn;
+ $chars .= $n . $cn;
+ }
+
+ $chars = preg_split('/(?<!^)(?!$)/u', $chars);
+ $chars = array_unique($chars);
+
+ $flex->addFont(WS_FILES . '/fonts/FluidbookMultilang.ttf', 'MultilangFont', $chars);
+ $flex->addVariable('langNames', $langNames, false, true, 'JSONObject');
+ $flex->addVariable('countryNames', $countryNames, false, true, 'JSONObject');
+ }
+ $flexLight->addVariable('lang', $book->lang);
+
+ // Basket
+ if ($book->parametres->basket) {
+ $formats = array('jpg', 'png', 'jpeg');
+ $referencesFile = self::getWorkingFile($book->parametres->basketReferences, $book_id, 'commerce');
+
+ if (file_exists($referencesFile) || CubeIT_Util_Url::isDistant($referencesFile)) {
+ $ext = CubeIT_Files::getExtension($referencesFile);
+ if ($ext == 'xml') {
+ $xml = simplexml_load_file($referencesFile);
+ $i = 0;
+ $allref = array();
+ foreach ($xml->item as $item) {
+ $ref = (string)$item['reference'];
+ if (isset($allref[$ref])) {
+ continue;
+ }
+ $allref[$ref] = true;
+ foreach ($formats as $f) {
+ $refimage = $workingDir . 'commerce/' . $ref . '.' . $f;
+ if (file_exists($refimage)) {
+ $flex->addBitmap($refimage, "basket_image_" . $ref);
+ break;
+ }
+ }
+ $i++;
+ }
+ } elseif ($ext == 'xlsx') {
+ $references = wsUtil::excelToArray($referencesFile);
+ if ($book->parametres->customLinkClass == 'AtlanticDownloadLink') {
+ $references = wsUtil::atlanticReferences($references, 'local/', null, array($vdir, 'copy'));
+ }
+ $flex->addVariable('basketReferences', $references, false, true, "OrderedObject");
+ }
+ }
+ if (isset($xml)) {
+ $flex->addVariable('basketReferences', cubeXML::condense($xml->asXML()), false, true, "String");
+ }
+ if ($book->parametres->basketPDFBackground != '') {
+ $flex->addByteArray($workingDir . 'commerce/' . $book->parametres->basketPDFBackground, 'basket_pdf_background');
+ }
+ }
+ // Fonts
+ if ($theme->parametres->fontKit == 'auto') {
+ if ($lang->font != 'system') {
+ $font = FONT_PATH . '/' . $lang->font;
+ $bfont = FONT_PATH . '/B' . $lang->font;
+ if (!file_exists($bfont)) {
+ $bfont = $font;
+ }
+
+ $flex->addFont($bfont, 'BoldFont', $lang->charset);
+ $flex->addFont($font, 'GeneralFont', $lang->charset);
+ }
+ $flex->addFont(FONT_PATH . '/FluidbookCredits.ttf', 'CreditsFont', 'ASCII');
+ $flexLight->addFont(FONT_PATH . '/FluidbookLoader.ttf', 'LoaderFont', 'Numerals');
+ } else if ($theme->parametres->fontKit == 'vagrounded') {
+ $flex->addFont(FONT_PATH . '/vagrounded/VAGRoundedStd-Bold.otf', 'BoldFont', $lang->charset);
+ $flex->addFont(FONT_PATH . '/vagrounded/VAGRoundedStd-Light.otf', 'GeneralFont', $lang->charset);
+ $flex->addFont(FONT_PATH . '/FluidbookCredits.ttf', 'CreditsFont', 'ASCII');
+ $flexLight->addFont(FONT_PATH . '/vagrounded/VAGRoundedStd-Bold.otf', 'LoaderFont', 'Numerals');
+ } else if ($theme->parametres->fontKit == 'gill') {
+ $flex->addFont(FONT_PATH . '/gill/gill.ttf', 'BoldFont', $lang->charset);
+ $flex->addFont(FONT_PATH . '/gill/gill.ttf', 'GeneralFont', $lang->charset);
+ $flex->addFont(FONT_PATH . '/FluidbookCredits.ttf', 'CreditsFont', 'ASCII');
+ $flexLight->addFont(FONT_PATH . '/gill/gill.ttf', 'LoaderFont', 'Numerals');
+ }
+
+ $flexLight->addVariable('checksum', $hash, false, true, 'String');
+ }
+
+
+ public static function getWorkingFile($path, $book_id, $dir = "")
+ {
+ if (CubeIT_Util_Url::isDistant($path) || (substr($path, 0, 1) == '/' && file_exists($path))) {
+ return $path;
+ }
+
+ $workingDir = WS_BOOKS . '/working/' . $book_id . '/';
+ return $workingDir . trim($dir, '/') . '/' . $path;
+ }
+
+ public function compileWidget($book, $pages)
+ {
+ if (!$book->parametres->widget) {
+ return;
+ }
+
+ global $core;
+
+ $finalDir = WS_BOOKS . '/final/' . $book->book_id . '/widget/';
+ $finalWidget = $finalDir . 'miniFluidbook.swf';
+
+ if (!file_exists($finalDir)) {
+ mkdir($finalDir, 0777, true);
+ }
+
+ if ($book->parametres->widgetCover) {
+ $file = 'miniFluidbookCouv.swf';
+ } else {
+ $file = 'miniFluidbook.swf';
+ }
+ $mini = WS_COMPILE_ASSETS . '/_widget/' . $file;
+
+ $from = max(1, $book->parametres->widgetStart);
+ $to = min($book->parametres->widgetEnd, count($pages));
+
+ $swfcombine = new cubeCommandLine('swfcombine');
+ $swfcombine->setPath(CONVERTER_PATH);
+ $swfcombine->setArg('merge');
+ $swfcombine->setArg('stack1');
+ $swfcombine->setArg('z');
+ $swfcombine->setArg('o', $finalWidget);
+ $swfcombine->setArg(null, $mini);
+
+ $tempimage = array();
+ $tempswf = array();
+ $timg = array();
+
+ for ($i = $from; $i <= $to; $i++) {
+ $page = $pages[$i];
+
+ $timg[$i] = $tempimage[$i] = cubeFiles::tempnam();
+ $tempswf[$i] = cubeFiles::tempnam();
+
+ $it = new imageTools();
+ $image = wsDocument::getDir($page['document_id']) . '/html/t150-' . $page['document_page'] . '.jpg';
+
+ try {
+ $it->loadImage($image);
+ $it->resize($book->parametres->widgetSize, 10000);
+ $it->output('jpeg', $tempimage[$i], 100);
+ } catch (Exception $e) {
+ $tempimage[$i] = $image;
+ }
+ $jpg2swf = new cubeCommandLine('jpeg2swf');
+ $jpg2swf->setEnv('PATH', '/bin:/usr/bin:/usr/local/bin');
+ $jpg2swf->setArg('q', $book->parametres->widgetQuality);
+ $jpg2swf->setArg('o', $tempswf[$i]);
+ $jpg2swf->setArg(null, $tempimage[$i]);
+ $jpg2swf->execute();
+
+ $swfcombine->setArg(null, $tempswf[$i]);
+ }
+ $swfcombine->execute();
+
+ foreach ($timg as $t) {
+ if (file_exists($t)) {
+ unlink($t);
+ }
+ }
+ foreach ($tempswf as $t) {
+ unlink($t);
+ }
+ }
+
+ public function compileHTML5($book_id, $book, $dev = false, $delete = true)
+ {
+ $version = $book->parametres->mobileLVersion;
+ if ($dev) {
+ $version = 'dev';
+ }
+
+ $htmlCompiler = wsHTML5::compilerFactory($book_id, $version, false, 'latest', null, false, false, false, $book);
+ $htmlCompiler->compile($delete);
+ }
+
+ /* public function indexPDF($book, $pages) {
+ $indexPath = WS_BOOKS . '/search/' . $book->book_id;
+
+ Zend_Search_Lucene_Analysis_Analyzer::setDefault(new Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8Num_CaseInsensitive());
+
+ if (file_exists($indexPath)) {
+ files::deltree($indexPath);
+ }
+ $index = Zend_Search_Lucene::create($indexPath);
+
+ foreach ($pages as $i => $infos) {
+ $doc = new Zend_Search_Lucene_Document();
+ $doc->addField(Zend_Search_Lucene_Field::Text('url', '#' . $i));
+ $doc->addField(Zend_Search_Lucene_Field::UnStored('contents', file_get_contents(wsDocument::getDir($infos['document_id']) . 'p' . $infos['document_page'] . '.txt')));
+ $index->addDocument($doc);
+ }
+
+ $c = $this->con->openCursor('books');
+ $c->lucene_time = TIME;
+ $c->update('WHERE book_id=' . $book->book_id);
+ } */
+
+ public function compilePDF($book, $pages)
+ {
+ $res = wsUtil::compilePDF($book, $pages);
+
+ $finalPDF = WS_BOOKS . '/final/' . $book->book_id . '/data/' . $book->parametres->pdfName;
+ if ($res) {
+ $this->copy($res, $finalPDF);
+ }
+ }
+
+ public function generateCID()
+ {
+
+ do {
+ $res = '';
+ for ($i = 0; $i < 8; $i++) {
+ $j = rand(0, 61);
+ $res .= $this->base62($j);
+ }
+ $r = $this->con->select('SELECT book_id FROM books WHERE cid=\'' . $res . '\'');
+ if ($r->count() == 0) {
+ return $res;
+ }
+ } while (true);
+ }
+
+ protected function base62($val)
+ {
+ $chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
+ $base = strlen($chars);
+ $str = '';
+ do {
+ $i = $val % $base;
+ $str = $chars[$i] . $str;
+ $val = ($val - $i) / $base;
+ } while ($val > 0);
+ return $str;
+ }
}