From 439f8771edd5702b835e3c1d879484ef6e72a277 Mon Sep 17 00:00:00 2001 From: "vincent@cubedesigners.com" Date: Mon, 20 Jan 2014 10:36:58 +0000 Subject: [PATCH] --- inc/ws/Controlleur/class.ws.services.php | 1730 +++++------ inc/ws/DAO/class.ws.dao.book.php | 3340 +++++++++++----------- 2 files changed, 2555 insertions(+), 2515 deletions(-) diff --git a/inc/ws/Controlleur/class.ws.services.php b/inc/ws/Controlleur/class.ws.services.php index 302331732..894e70c9a 100644 --- a/inc/ws/Controlleur/class.ws.services.php +++ b/inc/ws/Controlleur/class.ws.services.php @@ -1,849 +1,883 @@ -con, $args); - } - - public function sendEmail() { - if (!$this->_checkHash()) { - return; - } - // Send the email - $mail = new cubeMail(); - $mail->returnPath = 'postmaster@fluidbook.com'; - $mail->acknowledge = isset($this->args['askAcknowledge']) && $this->args['askAcknowledge']; - $mail->charset = 'UTF-8'; - $mail->to = $this->args['email']; - $mail->from = $this->args['fromname'] . '<' . $this->args['fromemail'] . '>'; - $mail->subject = $this->args['subject']; - $mail->body = $this->args['body']; - $this->xml->addChild('ok', $mail->send() ? '1' : '0'); - } - - protected function _checkHash() { - // Check protection hash - $hash = md5(substr($this->args['fromemail'], 2, 6) . substr($this->args['email'], 3, 5) . 'SFGHF566!S' . $this->args['id']); - if ($hash != $this->args['hash']) { - $this->xml->addChild('hashOK', '0'); - $this->xml->addChild('ok', '0'); - return false; - } - $this->xml->addChild('hashOK', '1'); - return true; - } - - public function sendBookmarks() { - if (!$this->_checkHash()) { - return; - } - - $bookmarks = json_decode(base64_decode($this->args['bookmarks']), true); - $files = array(); - foreach ($bookmarks as $b) { - $range = $b['page']; - if ($b['nb'] > 1) { - $range.='-' . ($b['page'] + $b['nb'] - 1); - } - - $file = $this->getPDFComplex($this->args['id'], $range); - $files[] = array('name' => $b['name'], 'file' => $file['file']); - } - - $limit = 5 * 1024 * 1024 * 0.8; - $groups = array(); - $group = array(); - $groupsize = 0; - foreach ($files as $f) { - $size = filesize($f['file']); - - if ($groupsize + $size > $limit) { - if (count($group)) { - $groups[] = $group; - $group = array(); - $groupsize = 0; - } - - $group[] = $f; - $groupsize = $size; - - if ($groupsize > $limit) { - $groups[] = $group; - $group = array(); - $groupsize = 0; - } - } else { - $group[] = $f; - $groupsize+=$size; - } - } - - if (count($group)) { - $groups[] = $group; - } - - - $total = count($groups); - foreach ($groups as $i => $g) { - $s = ''; - if ($total > 1) { - $s = ' (' . ($i + 1) . '/' . $total . ')'; - } - - // Send the email - $mail = new cubeMail(); - $mail->returnPath = 'postmaster@fluidbook.com'; - $mail->acknowledge = isset($this->args['askAcknowledge']) && $this->args['askAcknowledge']; - $mail->charset = 'UTF-8'; - $mail->to = $this->args['email']; - $mail->from = $this->args['fromname'] . '<' . $this->args['fromemail'] . '>'; - $mail->subject = $this->args['subject'] . $s; - $mail->body = $this->args['body']; - foreach ($g as $f) { - $mail->addFile($f['name'] . '.pdf', $f['file']); - } - $this->xml->addChild('ok', $mail->send() ? '1' : '0'); - } - } - - protected function shortenURL($url, $id) { - $bitLyUser = 'fluidbook'; - $bitLyKey = 'R_3858dd1c9884d5c6a5fe386d7e95cf1d'; - // Recherche dans le cache - $r = $this->con->select('SELECT * FROM book_short_url WHERE long_url=\'' . $this->con->escape($url) . '\' LIMIT 1'); - if ($r->count() > 0) { - return $r->short_url; - } - // Si pas dans le cache, on le recherche - $short_url = cubeURLShortener::bitLy($url, $bitLyUser, $bitLyKey); - if (is_null($short_url) || empty($short_url) || !$short_url) { - $short_url = cubeURLShortener::tinyURL($url); - } - $short_url = trim($short_url); - - $c = $this->con->openCursor('book_short_url'); - $c->long_url = $url; - $c->book_id = $id; - $c->short_url = $short_url; - $c->insert(); - - return $short_url; - } - - /** - * wsServices::facebook_thumbnail() - * - * @return - */ - public function facebook_thumbnail() { - $this->outputXML = false; - $dao = new wsDAOBook($this->con); - - $book = $dao->selectById($this->args['id']); - - - if (isset($book->parametres->facebook_image) && $book->parametres->facebook_image != '') { - $c = WS_BOOKS . '/working/' . $this->args['id'] . '/' . $book->parametres->facebook_image; - if (file_exists($c)) { - $cover = $c; - } - } - if (!isset($cover)) { - $pages = $dao->getPagesOfBook($this->args['id']); - $cover = WS_DOCS . '/' . $pages[1]['document_id'] . '/html/t36-' . $pages[1]['document_page'] . '.jpg'; - if (!file_exists($cover)) { - $cover = WS_DOCS . '/' . $pages[1]['document_id'] . '/p' . $pages[1]['document_page'] . '.jpg'; - } - } - cubeHTTP::relayFile($cover); - exit; - } - - public function facebookShare() { - http::redirect('http://www.facebook.com/sharer/sharer.php?u=' . urlencode($this->args['url'])); - exit; - } - - public function googleplusShare() { - http::redirect('https://plus.google.com/share?url=' . urlencode($this->args['url']) . "&sgp=1"); - exit; - } - - public function linkedinShare() { - http::redirect('https://www.linkedin.com/cws/share?url=' . urlencode($this->args['url']) . '&isFramed=true&_ts=' . microtime(true)); - } - - public function viadeoShare() { - http::redirect('http://www.viadeo.com/shareit/share/?url=' . urlencode($this->args['url'])); - } - - public function twitterShare() { - $url = $this->shortenURL($this->args['url'], $this->args['id']); - - $post = str_replace('%short%', $url, $this->args['post']); - $post = rawurlencode($post); - - http::redirect('http://twitter.com/intent/tweet?source=webclient&text=' . $post); - exit; - } - - public function searchHints() { - $index = Zend_Search_Lucene::open(WS_BOOKS . '/search/' . $this->args['id']); - - $charsLimit = 2; - - $terms = $this->getTerms($this->args['term']); - $term = array_pop($terms); - - if (strlen($term) < $charsLimit) { - $this->xml->addChild('hints', '{}'); - return; - } - - $term = new Zend_Search_Lucene_Index_Term($term . '*', 'contents'); - $query = new Zend_Search_Lucene_Search_Query_Wildcard($term); - $query->setMinPrefixLength($charsLimit); - - $index->find($query); - $terms = $query->getQueryTerms(); - $res = array(); - foreach ($terms as $t) { - $res[$t->text] = array_sum($index->termFreqs($t)); - } - arsort($res); - $res = array_slice($res, 0, 10, true); - $this->xml->addChild('hints', json_encode($res)); - } - - public function searchResults() { - $index = Zend_Search_Lucene::open(WS_BOOKS . '/search/' . $this->args['id']); - - $terms = $this->getTerms($this->args['term']); - - $query = new Zend_Search_Lucene_Search_Query_MultiTerm(); - foreach ($terms as $term) { - $query->addTerm(new Zend_Search_Lucene_Index_Term($term, 'contents'), null); - } - - $hits = $index->find($query); - $res = array(); - $terms = array(); - foreach ($query->getQueryTerms() as $t) { - $terms[] = $t->text; - foreach ($index->termFreqs($t) as $doc_id => $f) { - $page = trim($index->getDocument($doc_id)->getField('url')->getUtf8Value(), "#"); - if (!isset($res[$page])) { - $res[$page] = 0; - } - $res[$page]+=$f; - } - } - $this->xml->addChild('results', json_encode($res)); - $this->xml->addChild('terms', implode(',', $terms)); - } - - protected function getTerms($term) { - $term = trim($term, '*? '); - $term = mb_strtolower($term); - $term = cubeText::removeAccents($term); - $terms = explode(' ', $term); - return $terms; - } - - public function printpdf() { - $this->outputXML = false; - $this->exportpdf(true); - } - - protected function getPDFComplex($book, $range) { - global $core; - - $daoBook = new wsDAOBook($core->con); - - if (is_int($book) || is_string($book)) { - $book = $daoBook->selectById($book); - } - - if (is_null($book)) { - return; - } - - // Normalize range - $range = cubeArray::parseRange($range); - - if ($k = array_search(0, $range)) { - $range[$k] = 1; - } - if ($k = array_search($book->parametres->pages + 1, $range)) { - $range[$k] = $r->pages; - } - - if (!count($range)) { - return; - } - // Paths init - $baseDocument = WS_BOOKS . '/final/' . $book->book_id . '/data/' . $book->parametres->pdfName; - if (!file_exists($baseDocument)) { - return; - } - $destDir = WS_CACHE . '/exportpdf/' . $book->cid; - if (!file_exists($destDir)) { - mkdir($destDir, 0777, true); - } - $fname = md5(implode(',%ù', $range)) . '.pdf'; - $destFile = $destDir . '/' . $fname; - $destURL = '/fluidbook/cache/exportpdf/' . $book->cid . '/' . $fname; - // If result exists, don't make the pdf again - if (file_exists($destFile) && filemtime($destFile) > filemtime($baseDocument)) { - - } else { - // Prepare the command line - $l = array('A=' . $baseDocument, 'cat'); - foreach ($range as $page) { - if ($page < 1 || $page > $book->parametres->pages) { - continue; - } - $l[] = 'A' . $page; - } - $l[] = 'output'; - $l[] = $destFile; - - $args = implode(' ', $l); - // Execute the command line - $pdftk = new cubeCommandLine('pdftk'); - $pdftk->setPath(CONVERTER_PATH); - $pdftk->setManualArg($args); - $pdftk->execute(); - } - - return array('url' => $destURL, 'file' => $destFile); - } - - public function e() { - $this->args['cid'] = $this->callArgs[0]; - $this->args['range'] = $this->callArgs[1]; - return $this->exportpdf(); - } - - public function p() { - $this->args['cid'] = $this->callArgs[0]; - $this->args['range'] = $this->callArgs[1]; - return $this->exportpdf(true); - } - - public function exportpdf($print = false) { - global $core; - - $dao = new wsDAOBook($core->con); - if (isset($this->args['cid'])) { - $book = $dao->selectByCid($this->args['cid']); - } else if ($this->args['id'] < 11202) { - $book = $dao->selectById($this->args['id']); - } - - $dest = $this->getPDFComplex($book, $this->args['range']); - - if (!$print) { - // Return the url of the resulting pdf - http::redirect($dest['url']); - exit; - } else { - $this->outputXML = false; - $res = ' - - - - - - - - - '; - ob_end_clean(); - echo $res; - exit; - } - } - - public function bulle() { - global $core; - $e = explode('-', $this->args['catalogue'], 2); - if (count($e) == 2) { - $catalogue = $e[1]; - } else { - $catalogue = $e[0]; - } - - $c = $core->con->openCursor('bulle'); - $c->prenom = trim($this->args['prenom']); - $c->nom = trim($this->args['nom']); - $c->catalogue = trim($catalogue); - $c->email = trim($this->args['email']); - $c->date = TIME; - $c->insert(); - } - - public function getBulleList() { - $user = 'bulle'; - $pass = '23bu1l300'; - $this->outputXML = false; - $ok = (isset($_SERVER['PHP_AUTH_USER']) && $_SERVER['PHP_AUTH_USER'] == $user && isset($_SERVER['PHP_AUTH_PW']) && $_SERVER['PHP_AUTH_PW'] == $pass); - if (!$ok) { - header('WWW-Authenticate: Basic realm="Protected access"'); - header('HTTP/1.0 401 Unauthorized'); - ob_end_clean(); - header('Content-type: text/html'); - echo '

Forbidden

'; - exit; - } else { - global $core; - header('Content-type: text/csv'); - header('Content-Disposition: attachment; filename="inscriptions.csv"'); - $r = $core->con->select('SELECT * FROM bulle ORDER BY date'); - ob_end_clean(); - echo utf8_decode('"Prénom";"Nom";"E-mail";"Catalogue";"Date"') . "\n"; - while ($r->fetch()) { - echo utf8_decode('"' . $r->prenom . '";"' . $r->nom . '";"' . $r->email . '";"' . $r->catalogue . '";"' . date('Y-m-d H:i', $r->date) . '"') . "\n"; - } - exit; - } - } - - public function grdfValidForm() { - $notempty = array('civilite', 'prenom', 'nom', 'adresse', 'codepostal', 'ville', 'telephone', 'optin', 'connu', 'energie'); - $error = false; - $errors = array(); - foreach ($notempty as $f) { - if (!isset($this->args[$f]) || is_null($this->args[$f]) || $this->args[$f] == 'null' || trim($this->args[$f]) == '') { - $error = true; - $errors[] = $f; - } - } - - /* if (!cubeMail::isEmail($this->args['email'])) { - $error = true; - $errors[] = 'email_valid'; - } */ - - $this->xml->addChild('ok', $error ? '0' : '1'); - $this->xml->addChild('errors', implode(',', $errors)); - } - - public function grdfSendForm() { - global $core; - - $fields = array('Civilité' => 'civilite', 'Prénom' => 'prenom', 'Nom' => 'nom', - 'E-mail' => 'email', 'Adresse' => 'adresse', 'Code postal' => 'codepostal', 'Ville' => 'ville', - 'Téléphone' => 'telephone', 'Connu par' => 'connu', 'Energie' => 'energie', - 'Optin' => 'optin', 'Coupons sélectionnés' => 'reflist'); - - $mail = new cubeMail(); - $mail->charset = 'UTF-8'; - $mail->subject = '[Chéquier avantages] Validation de coupon'; - $mail->from = 'noreply@chequieravantages.fr'; - $mail->replyTo = 'noreply@chequiavantages.fr'; - $mail->to = 'projetrenogaz@grdf.fr'; - $mail->bcc = 'test@cubedesigners.com'; - $body = ''; - - foreach ($fields as $k => $f) { - $body.=$k . ' : ' . $this->args[$f] . "\r\n"; - $datas[$f] = $this->args[$f]; - } - $datas['date'] = TIME; - - $c = $core->con->openCursor('grdf2013'); - $c->datas = json_encode($datas); - $c->insert(); - - $mail->body = $body; - $mail->send(); - } - - public function grdfCoupon() { - $this->outputXML = false; - $couponsRoot = WS_BOOKS . '/working/11222/commerce/'; - - $xml = simplexml_load_file($couponsRoot . 'references.xml'); - // Check hash - $hash = md5('ae' . $_GET['nom'] . '25' . $_GET['ref']); - if ($hash != $_GET['h']) { - exit; - } - $refs = explode(',', $_GET['ref']); - $pdf = new FPDI(); - foreach ($refs as $ref) { - - foreach ($xml->xpath('//item[@reference=\'' . $ref . '\']') as $item) { - $code = (string) $item['code']; - } - - $file = $couponsRoot . $ref . '.pdf'; - - $pdf->setSourceFile($file); - $idx = $pdf->importPage(1); - $pdf->AddPage(); - $pdf->useTemplate($idx); - $pdf->SetXY(11, 12); - $pdf->SetFont('Helvetica', '', 12); - $pdf->SetTextColor(0, 0, 0); - $pdf->Cell(180, 10, utf8_decode(trim($_GET['civilite'] . ' ' . $_GET['prenom'] . ' ' . $_GET['nom']) . ',')); - $pdf->SetXY(143, 203); - $pdf->SetFont('Helvetica', 'B', 18); - $pdf->Cell(33, 15, $code); - } - $pdf->Output('coupon.pdf', 'I'); - } - - public function grdfExcel12568() { - global $core; - $this->outputXML = false; - - - $couponsRoot = WS_BOOKS . '/working/11222/commerce/'; - - $xml = simplexml_load_file($couponsRoot . 'references.xml'); - - $cols = array('Date' => 'date', 'Civilité' => 'civilite', 'Prénom' => 'prenom', 'Nom' => 'nom', - 'E-mail' => 'email', 'Adresse' => 'adresse', 'Code postal' => 'codepostal', 'Ville' => 'ville', - 'Téléphone' => 'telephone', 'Connu par' => 'connu', 'Energie' => 'energie', - 'Optin' => 'optin'); - $refs = array(); - foreach ($xml->xpath('//item') as $i) { - $refs[(string) $i['reference']] = $i['name']; - } - - // - $h = ''; - $h.=''; - foreach ($cols as $l => $k) { - $h.=''; - } - foreach ($refs as $k => $l) { - $h.=''; - } - $h.=''; - - $r = $core->con->select('SELECT * FROM grdf2013'); - while ($r->fetch()) { - $d = json_decode($r->datas); - $rl = explode(',', $d->reflist); - $h.=''; - foreach ($cols as $l => $k) { - $v = $d->$k; - if ($k == 'date') { - $v = date('Y-m-d H:i', $v); - } - $h.=''; - } - foreach ($refs as $k => $l) { - $v = in_array($k, $rl) ? '1' : '0'; - $h.=''; - } - $h.=''; - } - - $h.='
' . utf8_decode($l) . '' . utf8_decode($l) . '
' . utf8_decode($v) . '' . utf8_decode($v) . '
'; - - if (!file_exists(ROOT . '/cache/12568/')) { - mkdir(ROOT . '/cache/12568/', 0777, true); - } - file_put_contents(ROOT . '/cache/12568/chequieravantage.xls', $h); - http::redirect('/cache/12568/chequieravantage.xls'); - exit; - } - - public function proxy() { - ob_end_clean(); - fb(netHttp::quickGet($_GET['u'], 'php://output')); - $this->outputXML = false; - } - - public function wescoRef() { - global $core; - - $ref = ltrim(substr($this->args['ref'], 4), '0'); - - $r = $core->con->select('SELECT url FROM wescoref WHERE ref="' . $core->con->escape($ref) . '"'); - if ($r->count()) { - header('Location: ' . $r->url); - exit; - } - $cache = ROOT . '/cache/wesco/' . $this->args['ref']; - if (file_exists($cache)) { - header('Location: ' . file_get_contents($cache)); - exit; - } - $url = 'http://www.wesco-eshop.fr/catalogsearch/result/?q=' . $ref; - $doc = new DOMDocument(); - $doc->loadHTML(file_get_contents($url)); - $x = simplexml_import_dom($doc); - $xpath = $x->xpath('//a[@class="product-image"]'); - if (count($xpath) > 0) { - $r = $xpath[0]['href']; - file_put_contents($cache, $r); - header('Location: ' . $r); - exit; - } - header('Location: http://www.wesco-eshop.fr'); - } - - public function flfRef() { - global $core; - - $r = $core->con->select('SELECT url FROM flfref WHERE ref="' . $core->con->escape($this->args['ref']) . '"'); - if ($r->count()) { - header('Location: http://www.flf.fr' . $r->url); - exit; - } - } - - public function collection() { - global $core; - $id = $this->callArgs[0]; - $os = $this->callArgs[1]; - $resolution = $this->callArgs[2]; - $local = (isset($this->callArgs[3])) ? $this->callArgs[3] : null; - - if ($id == 4) { - $resolution = 150; - } - - $this->outputXML = false; - header('Content-type: application/json'); - - $cache = WS_COLLECTIONS . '/ws/' . $id . '.' . $os . '.' . $resolution . '.json'; - $update = WS_COLLECTIONS . '/ws/' . $id . '.' . $os . '.' . $resolution . '.update'; - - if (file_exists($update) && filemtime(__FILE__) > filemtime($update)) { - unlink($update); - } - - if (!is_null($local) && file_exists($update) && file_get_contents($update) == $local) { - echo 'false'; - exit; - } - - $limit = TIME - 72000; - if (!file_exists($cache) || !file_exists($update) || filemtime($cache) < $limit) { - $r = $core->con->select('SELECT * FROM book_collection_compile WHERE online_' . $os . '=1 AND collection_id=\'' . $core->con->escape($id) . '\''); - $r->fetch(); - $version = $r->compile_date; - - $daoCollection = new wsDAOCollection($core->con); - $collection = $daoCollection->selectById($id); - - $ns = $collection->settings['namespace']; - - - $vcompo = WS_COLLECTIONS . '/versions/' . $id . '/' . $version . '/composition.json'; - $composition = json_decode(file_get_contents($vcompo)); - - $couvertures = array(); - $vroot = WS_COLLECTIONS . '/versions/' . $id . '/' . $version . '/' . $os . '/'; - - $publications = array(); - $langs = array(); - - foreach ($composition as $k => $g) { - foreach ($g->publications as $l => $p) { - $publications[] = $p->id; - } - } - - $daoBook = new wsDAOBook($core->con); - $books = $daoBook->selectByIds($publications); - - $langsnames = array(); - foreach ($composition as $k => $g) { - foreach ($g->publications as $l => $p) { - $book = $books[$p->id]; - $root = WS_COLLECTIONS . '/versions/' . $id . '/' . $version . '/' . $os . '/' . $p->id; - $couv = $root . '/cover.jpg'; - $couvertures[$p->id] = base64_encode(file_get_contents($couv)); - $composition[$k]->publications[$l]->width = $book->parametres->width; - $composition[$k]->publications[$l]->height = $book->parametres->height; - $composition[$k]->publications[$l]->lang = $book->lang; - $langs[] = $book->lang; - } - } - - $langs = array_unique($langs); - - $w2h = new wiki2xhtml(); - $w2h->setOpt('active_pre', 0); - - $contents = $collection->contents; - foreach ($langs as $lang) { - $langsnames[$lang] = cubeLang::getNameByCode($lang); - $contents[$lang]['apropos'] = $w2h->transform($contents[$lang]['apropos']); - } - - - $traductions = array(); - $r = $core->con->select('SELECT traductions,lang_id FROM langues WHERE lang_id IN(\'' . implode('\',\'', $langs) . '\')'); - while ($r->fetch()) { - $traductions[$r->lang_id] = json_decode($r->traductions); - } - - $d = array('id' => $id, 'res' => $resolution, 'ns' => $ns, 'langs' => $langs, 'langnames' => $langsnames, 'time' => $version, 'datas' => $composition, 'couvertures' => $couvertures, 'traductions' => $traductions, 'contents' => $contents); - $d = array_merge($d, $this->_getManifest($publications, '/fluidbook/collections/versions/' . $id . '/' . $version . '/' . $os, $books, $resolution)); - - $dao = new wsDAOCollection($core->con); - $col = $dao->selectById($id); - - $json = json_encode($d); - file_put_contents($cache, $json); - file_put_contents($update, $version); - } else { - $d = json_decode(file_get_contents($cache), true); - } - - $force = false; - if (!is_null($local)) { - $lcompo = WS_COLLECTIONS . '/versions/' . $id . '/' . $local . '/composition.json'; - if (!file_exists($lcompo)) { - $force = true; - } - } - - $d['forceUpdate'] = $force; - echo json_encode($d); - exit; - } - - protected function _getManifest($publications, $dir, $books, $resolution) { - global $core; - $res = array(); - $res['manifest'] = array('assetRoot' => 'http://workshop.fluidbook.com' . $dir . '/', 'autoDownload' => false); - $res['manifestPub'] = array(); - - $bundles = array(); - - $removeFromRelative = realpath(ROOT . '/' . $dir) . '/'; - $daoTheme = new wsDAOTheme($core->con); - - foreach ($publications as $p) { - $res['manifestPub'][$p] = array('assetRoot' => 'http://workshop.fluidbook.com' . $dir . '/', 'autoDownload' => true); - - $r = $p . '/'; - $iterator = CubeIT_Files::getRecursiveDirectoryIterator(ROOT . $dir . '/' . $p); - $book = $books[$p]; - $reso = $resolution; - - $theme = $daoTheme->selectById($book->theme); - $orders = $this->_getBundles($book); - $regexp = $this->_getRegExpManifest($r, $book, $theme, $reso); - $reg = $regexp['reg']; - $exclude = $regexp['exclude']; - - $b = array(); - - foreach ($iterator as $k => $f) { - if ($f->isDir()) { - continue; - } - $path = str_replace($removeFromRelative, '', $k); - - foreach ($exclude as $e) { - if (preg_match('|' . $e . '|', $path)) { - continue 2; - } - } - - $order = $this->_inFirstManifest($path, $orders, $reg); - - if (!isset($b[$order])) { - $b[$order] = array(); - } - - $b[$order][] = $path; - } - - $bundles[] = array('name' => 'p_' . $p, 'contents' => $b['loading']); - $res['manifestPub'][$p]['bundles'] = array(); - - foreach ($b as $name => $contents) { - if ($name == 'loading') { - continue; - } - $k = array_search($name, $orders); - $res['manifestPub'][$p]['bundles'][$k] = array('name' => $name, 'contents' => $contents); - } - ksort($res['manifestPub'][$p]['bundles']); - $res['manifestPub'][$p]['bundles'] = array_values($res['manifestPub'][$p]['bundles']); - } - - $res['manifest']['bundles'] = $bundles; - return $res; - } - - protected function _getRegExpManifest($r, $book, $theme, $resolution) { - $reg = array(); - $reg['loading'] = array('^' . $r . 'style/(.*).css$', '^' . $r . 'index.html$', '^' . $r . 'data/style/(.*)$', '^' . $r . 'data/(.*).js$', '^' . $r . 'data/images/' . $theme->parametres->logoLoader . '$', '^' . $r . 'style/fonts/(.*).ttf$', '^' . $r . 'data/images/interface-down.svg$', '^' . $r . 'plugins/(.*)$'); - $reg['extras'] = array('^' . $r . 'data/links/(.*).mp4$', '^' . $r . 'data/links/(.*).ogv$', '^' . $r . 'data/links/(.*).webm$', '^' . $r . 'data/(.*).pdf$', '^' . $r . 'cover.jpg$'); - $reg['thumbnails'] = array('^' . $r . 'data/thumbnails/p(\d+).jpg$'); - for ($i = 1; $i <= $book->parametres->pages; $i++) { - $var = 'content_' . $i; - $reg[$var] = array('^' . $r . 'data/background/\d+/t' . $i . '.jpg$', '^' . $r . 'data/contents/p' . $i . '.svg$'); - } - $reg['urgents'] = array('^' . $r . 'images/(.*)$', '^' . $r . 'data/images/(.*)$', '^' . $r . 'data/links/(.*).jpg$', '^' . $r . 'data/links/(.*).png$'); - $reg['loading'] = array_merge($reg['loading'], $reg['urgents']); - - - $exclude = array(); - if ($resolution == 150) { - $er = 300; - } else { - $er = 150; - } - $exclude[] = '^' . $r . 'data/background/' . $er . '/t\d+.jpg$'; - return array('reg' => $reg, 'exclude' => $exclude); - } - - protected function _inFirstManifest($p, $orders, $reg) { - foreach ($orders as $list) { - foreach ($reg[$list] as $v) { - if (preg_match('|' . $v . '|', $p)) { - return $list; - } - } - } - return $list; - } - - protected function _getBundles($book) { - $res = array(0 => 'loading', 20001 => 'extras', 20000 => 'thumbnails', 1 => 'urgents'); - for ($i = 1; $i <= $book->parametres->pages; $i++) { - $k = 2 + $i; - $res[$k] = 'content_' . $i; - } - return $res; - } - - public function collectionPushRegister() { - global $core; - - $c = $core->con->openCursor('book_collection_push'); - $c->collection_id = $_POST['id']; - $c->token = $_POST['token']; - $c->datas = $_POST['datas']; - $c->platform = $_POST['platform']; - $c->locale = $_POST['locale']; - $c->last_visit = TIME; - try { - $c->insert(); - } catch (Exception $e) { - $c->update('WHERE collection_id=\'' . $core->con->escape($_POST['id']) . '\' AND token=\'' . $core->con->escape($_POST['token']) . '\''); - } - } - -} - +con, $args); + } + + public function sendEmail() { + if (!$this->_checkHash()) { + return; + } + // Send the email + $mail = new cubeMail(); + $mail->returnPath = 'postmaster@fluidbook.com'; + $mail->acknowledge = isset($this->args['askAcknowledge']) && $this->args['askAcknowledge']; + $mail->charset = 'UTF-8'; + $mail->to = $this->args['email']; + $mail->from = $this->args['fromname'] . '<' . $this->args['fromemail'] . '>'; + $mail->subject = $this->args['subject']; + $mail->body = $this->args['body']; + $this->xml->addChild('ok', $mail->send() ? '1' : '0'); + } + + protected function _checkHash() { + // Check protection hash + $hash = md5(substr($this->args['fromemail'], 2, 6) . substr($this->args['email'], 3, 5) . 'SFGHF566!S' . $this->args['id']); + if ($hash != $this->args['hash']) { + $this->xml->addChild('hashOK', '0'); + $this->xml->addChild('ok', '0'); + return false; + } + $this->xml->addChild('hashOK', '1'); + return true; + } + + public function sendBookmarks() { + if (!$this->_checkHash()) { + return; + } + + $bookmarks = json_decode(base64_decode($this->args['bookmarks']), true); + $files = array(); + foreach ($bookmarks as $b) { + $range = $b['page']; + if ($b['nb'] > 1) { + $range.='-' . ($b['page'] + $b['nb'] - 1); + } + + $file = $this->getPDFComplex($this->args['id'], $range); + $files[] = array('name' => $b['name'], 'file' => $file['file']); + } + + $limit = 5 * 1024 * 1024 * 0.8; + $groups = array(); + $group = array(); + $groupsize = 0; + foreach ($files as $f) { + $size = filesize($f['file']); + + if ($groupsize + $size > $limit) { + if (count($group)) { + $groups[] = $group; + $group = array(); + $groupsize = 0; + } + + $group[] = $f; + $groupsize = $size; + + if ($groupsize > $limit) { + $groups[] = $group; + $group = array(); + $groupsize = 0; + } + } else { + $group[] = $f; + $groupsize+=$size; + } + } + + if (count($group)) { + $groups[] = $group; + } + + + $total = count($groups); + foreach ($groups as $i => $g) { + $s = ''; + if ($total > 1) { + $s = ' (' . ($i + 1) . '/' . $total . ')'; + } + + // Send the email + $mail = new cubeMail(); + $mail->returnPath = 'postmaster@fluidbook.com'; + $mail->acknowledge = isset($this->args['askAcknowledge']) && $this->args['askAcknowledge']; + $mail->charset = 'UTF-8'; + $mail->to = $this->args['email']; + $mail->from = $this->args['fromname'] . '<' . $this->args['fromemail'] . '>'; + $mail->subject = $this->args['subject'] . $s; + $mail->body = $this->args['body']; + foreach ($g as $f) { + $mail->addFile($f['name'] . '.pdf', $f['file']); + } + $this->xml->addChild('ok', $mail->send() ? '1' : '0'); + } + } + + protected function shortenURL($url, $id) { + $bitLyUser = 'fluidbook'; + $bitLyKey = 'R_3858dd1c9884d5c6a5fe386d7e95cf1d'; + // Recherche dans le cache + $r = $this->con->select('SELECT * FROM book_short_url WHERE long_url=\'' . $this->con->escape($url) . '\' LIMIT 1'); + if ($r->count() > 0) { + return $r->short_url; + } + // Si pas dans le cache, on le recherche + $short_url = cubeURLShortener::bitLy($url, $bitLyUser, $bitLyKey); + if (is_null($short_url) || empty($short_url) || !$short_url) { + $short_url = cubeURLShortener::tinyURL($url); + } + $short_url = trim($short_url); + + $c = $this->con->openCursor('book_short_url'); + $c->long_url = $url; + $c->book_id = $id; + $c->short_url = $short_url; + $c->insert(); + + return $short_url; + } + + /** + * wsServices::facebook_thumbnail() + * + * @return + */ + public function facebook_thumbnail() { + $this->outputXML = false; + $dao = new wsDAOBook($this->con); + + $book = $dao->selectById($this->args['id']); + + + if (isset($book->parametres->facebook_image) && $book->parametres->facebook_image != '') { + $c = WS_BOOKS . '/working/' . $this->args['id'] . '/' . $book->parametres->facebook_image; + if (file_exists($c)) { + $cover = $c; + } + } + if (!isset($cover)) { + $pages = $dao->getPagesOfBook($this->args['id']); + $cover = WS_DOCS . '/' . $pages[1]['document_id'] . '/html/t36-' . $pages[1]['document_page'] . '.jpg'; + if (!file_exists($cover)) { + $cover = WS_DOCS . '/' . $pages[1]['document_id'] . '/p' . $pages[1]['document_page'] . '.jpg'; + } + } + cubeHTTP::relayFile($cover); + exit; + } + + public function facebookShare() { + http::redirect('http://www.facebook.com/sharer/sharer.php?u=' . urlencode($this->args['url'])); + exit; + } + + public function googleplusShare() { + http::redirect('https://plus.google.com/share?url=' . urlencode($this->args['url']) . "&sgp=1"); + exit; + } + + public function linkedinShare() { + http::redirect('https://www.linkedin.com/cws/share?url=' . urlencode($this->args['url']) . '&isFramed=true&_ts=' . microtime(true)); + } + + public function viadeoShare() { + http::redirect('http://www.viadeo.com/shareit/share/?url=' . urlencode($this->args['url'])); + } + + public function twitterShare() { + $url = $this->shortenURL($this->args['url'], $this->args['id']); + + $post = str_replace('%short%', $url, $this->args['post']); + $post = rawurlencode($post); + + http::redirect('http://twitter.com/intent/tweet?source=webclient&text=' . $post); + exit; + } + + public function searchHints() { + $index = Zend_Search_Lucene::open(WS_BOOKS . '/search/' . $this->args['id']); + + $charsLimit = 2; + + $terms = $this->getTerms($this->args['term']); + $term = array_pop($terms); + + if (strlen($term) < $charsLimit) { + $this->xml->addChild('hints', '{}'); + return; + } + + $term = new Zend_Search_Lucene_Index_Term($term . '*', 'contents'); + $query = new Zend_Search_Lucene_Search_Query_Wildcard($term); + $query->setMinPrefixLength($charsLimit); + + $index->find($query); + $terms = $query->getQueryTerms(); + $res = array(); + foreach ($terms as $t) { + $res[$t->text] = array_sum($index->termFreqs($t)); + } + arsort($res); + $res = array_slice($res, 0, 10, true); + $this->xml->addChild('hints', json_encode($res)); + } + + public function searchResults() { + $index = Zend_Search_Lucene::open(WS_BOOKS . '/search/' . $this->args['id']); + + $terms = $this->getTerms($this->args['term']); + + $query = new Zend_Search_Lucene_Search_Query_MultiTerm(); + foreach ($terms as $term) { + $query->addTerm(new Zend_Search_Lucene_Index_Term($term, 'contents'), null); + } + + $hits = $index->find($query); + $res = array(); + $terms = array(); + foreach ($query->getQueryTerms() as $t) { + $terms[] = $t->text; + foreach ($index->termFreqs($t) as $doc_id => $f) { + $page = trim($index->getDocument($doc_id)->getField('url')->getUtf8Value(), "#"); + if (!isset($res[$page])) { + $res[$page] = 0; + } + $res[$page]+=$f; + } + } + $this->xml->addChild('results', json_encode($res)); + $this->xml->addChild('terms', implode(',', $terms)); + } + + protected function getTerms($term) { + $term = trim($term, '*? '); + $term = mb_strtolower($term); + $term = cubeText::removeAccents($term); + $terms = explode(' ', $term); + return $terms; + } + + public function printpdf() { + $this->outputXML = false; + $this->exportpdf(true); + } + + public function getPDFComplex($book = null, $range = null) { + global $core; + + if (is_null($book)) { + $book = $this->callArgs[0]; + $range = $this->callArgs[1]; + } + + $daoBook = new wsDAOBook($core->con); + + if (is_int($book) || is_string($book)) { + $book = $daoBook->selectById($book); + } + + if (is_null($book)) { + return; + } + + // Normalize range + $range = cubeArray::parseRange($range); + + if ($k = array_search(0, $range)) { + $range[$k] = 1; + } + if ($k = array_search($book->parametres->pages + 1, $range)) { + $range[$k] = $r->pages; + } + + if (!count($range)) { + return; + } + // Paths init + $baseDocument = $this->getPDFComplexBaseDocument($book); + if (!file_exists($baseDocument)) { + return; + } + $destDir = WS_CACHE . '/exportpdf/' . $book->cid; + if (!file_exists($destDir)) { + mkdir($destDir, 0777, true); + } + $fname = md5(implode(',%ù', $range)) . '.pdf'; + $destFile = $destDir . '/' . $fname; + $destURL = '/fluidbook/cache/exportpdf/' . $book->cid . '/' . $fname; + // If result exists, don't make the pdf again + if (file_exists($destFile) && filemtime($destFile) > filemtime($baseDocument)) { + + } else { + // Prepare the command line + $l = array('A=' . $baseDocument, 'cat'); + foreach ($range as $page) { + if ($page < 1 || $page > $book->parametres->pages) { + continue; + } + $l[] = 'A' . $page; + } + $l[] = 'output'; + $l[] = $destFile; + + $args = implode(' ', $l); + // Execute the command line + $pdftk = new cubeCommandLine('pdftk'); + $pdftk->setPath(CONVERTER_PATH); + $pdftk->setManualArg($args); + $pdftk->execute(); + } + + return array('url' => $destURL, 'file' => $destFile); + } + + public function getPDFComplexBaseDocument($book) { + $normal = WS_BOOKS . '/pdf/' . $book->book_id . '/original.pdf'; + + if ($book->parametres->pdfReplace != '' && file_exists($normal)) { + $this->xml->addChild('normal', $normal); + return $normal; + } + return WS_BOOKS . '/final/' . $book->book_id . '/data/' . $book->parametres->pdfName; + } + + public function e() { + $this->args['cid'] = $this->callArgs[0]; + $this->args['range'] = $this->callArgs[1]; + return $this->exportpdf(); + } + + public function p() { + $this->args['cid'] = $this->callArgs[0]; + $this->args['range'] = $this->callArgs[1]; + return $this->exportpdf(true); + } + + public function exportpdf($print = false) { + global $core; + + $dao = new wsDAOBook($core->con); + if (isset($this->args['cid'])) { + $book = $dao->selectByCid($this->args['cid']); + } else if ($this->args['id'] < 11202) { + $book = $dao->selectById($this->args['id']); + } + + $dest = $this->getPDFComplex($book, $this->args['range']); + + if (!$print) { + // Return the url of the resulting pdf + http::redirect($dest['url']); + exit; + } else { + $this->outputXML = false; + $res = ' + + + + + + + + + '; + ob_end_clean(); + echo $res; + exit; + } + } + + public function bulle() { + global $core; + $e = explode('-', $this->args['catalogue'], 2); + if (count($e) == 2) { + $catalogue = $e[1]; + } else { + $catalogue = $e[0]; + } + + $c = $core->con->openCursor('bulle'); + $c->prenom = trim($this->args['prenom']); + $c->nom = trim($this->args['nom']); + $c->catalogue = trim($catalogue); + $c->email = trim($this->args['email']); + $c->date = TIME; + $c->insert(); + } + + public function getBulleList() { + $user = 'bulle'; + $pass = '23bu1l300'; + $this->outputXML = false; + $ok = (isset($_SERVER['PHP_AUTH_USER']) && $_SERVER['PHP_AUTH_USER'] == $user && isset($_SERVER['PHP_AUTH_PW']) && $_SERVER['PHP_AUTH_PW'] == $pass); + if (!$ok) { + header('WWW-Authenticate: Basic realm="Protected access"'); + header('HTTP/1.0 401 Unauthorized'); + ob_end_clean(); + header('Content-type: text/html'); + echo '

Forbidden

'; + exit; + } else { + global $core; + header('Content-type: text/csv'); + header('Content-Disposition: attachment; filename="inscriptions.csv"'); + $r = $core->con->select('SELECT * FROM bulle ORDER BY date'); + ob_end_clean(); + echo utf8_decode('"Prénom";"Nom";"E-mail";"Catalogue";"Date"') . "\n"; + while ($r->fetch()) { + echo utf8_decode('"' . $r->prenom . '";"' . $r->nom . '";"' . $r->email . '";"' . $r->catalogue . '";"' . date('Y-m-d H:i', $r->date) . '"') . "\n"; + } + exit; + } + } + + public function grdfValidForm() { + $notempty = array('civilite', 'prenom', 'nom', 'adresse', 'codepostal', 'ville', 'telephone', 'optin', 'connu', 'energie'); + $error = false; + $errors = array(); + foreach ($notempty as $f) { + if (!isset($this->args[$f]) || is_null($this->args[$f]) || $this->args[$f] == 'null' || trim($this->args[$f]) == '') { + $error = true; + $errors[] = $f; + } + } + + /* if (!cubeMail::isEmail($this->args['email'])) { + $error = true; + $errors[] = 'email_valid'; + } */ + + $this->xml->addChild('ok', $error ? '0' : '1'); + $this->xml->addChild('errors', implode(',', $errors)); + } + + public function grdfSendForm() { + global $core; + + if ($this->args['id'] == 11222) { + $annee = 2013; + } else if ($this->args['id'] == 12235) { + $annee = 2014; + } + + $fields = array('Civilité' => 'civilite', 'Prénom' => 'prenom', 'Nom' => 'nom', + 'E-mail' => 'email', 'Adresse' => 'adresse', 'Code postal' => 'codepostal', 'Ville' => 'ville', + 'Téléphone' => 'telephone', 'Connu par' => 'connu', 'Energie' => 'energie', + 'Optin' => 'optin', 'Coupons sélectionnés' => 'reflist'); + + $mail = new cubeMail(); + $mail->charset = 'UTF-8'; + $mail->subject = '[Chéquier avantages] Validation de coupon'; + $mail->from = 'noreply@chequieravantages.fr'; + $mail->replyTo = 'noreply@chequiavantages.fr'; + $mail->to = 'projetrenogaz@grdf.fr'; + $mail->bcc = 'test@cubedesigners.com'; + $body = ''; + + foreach ($fields as $k => $f) { + $body.=$k . ' : ' . $this->args[$f] . "\r\n"; + $datas[$f] = $this->args[$f]; + } + $datas['date'] = TIME; + + $c = $core->con->openCursor('grdf' . $annee); + $c->datas = json_encode($datas); + $c->insert(); + + $mail->body = $body; + $mail->send(); + } + + public function grdfCoupon() { + $id = $this->args['id']; + + $this->outputXML = false; + $couponsRoot = WS_BOOKS . '/working/' . $id . '/commerce/'; + + $xml = simplexml_load_file($couponsRoot . 'references.xml'); + // Check hash + $hash = md5('ae' . $_GET['nom'] . '25' . $_GET['ref']); + if ($hash != $_GET['h']) { + exit; + } + $refs = explode(',', $_GET['ref']); + $pdf = new FPDI(); + foreach ($refs as $ref) { + + foreach ($xml->xpath('//item[@reference=\'' . $ref . '\']') as $item) { + $code = (string) $item['code']; + } + + $file = $couponsRoot . $ref . '.pdf'; + + $pdf->setSourceFile($file); + $idx = $pdf->importPage(1); + $pdf->AddPage(); + $pdf->useTemplate($idx); + $pdf->SetXY(11, 12); + $pdf->SetFont('Helvetica', '', 12); + $pdf->SetTextColor(0, 0, 0); + $pdf->Cell(180, 10, utf8_decode(trim($_GET['civilite'] . ' ' . $_GET['prenom'] . ' ' . $_GET['nom']) . ',')); + $pdf->SetXY(135, 203); + $pdf->SetFont('Helvetica', 'B', 16); + $pdf->Cell(50, 15, $code, 0, 1, "C"); + } + $pdf->Output('coupon.pdf', 'I'); + } + + public function grdfExcel12568() { + global $core; + $this->outputXML = false; + + if (!isset($_GET['annee'])) { + $_GET['annee'] = 2013; + } + $annee = $_GET['annee']; + + if ($annee == 2013) { + $id = 11222; + } elseif ($annee == 2014) { + $id = 12235; + } + + + $couponsRoot = WS_BOOKS . '/working/' . $id . '/commerce/'; + + $xml = simplexml_load_file($couponsRoot . 'references.xml'); + + $cols = array('Date' => 'date', 'Civilité' => 'civilite', 'Prénom' => 'prenom', 'Nom' => 'nom', + 'E-mail' => 'email', 'Adresse' => 'adresse', 'Code postal' => 'codepostal', 'Ville' => 'ville', + 'Téléphone' => 'telephone', 'Connu par' => 'connu', 'Energie' => 'energie', + 'Optin' => 'optin'); + $refs = array(); + foreach ($xml->xpath('//item') as $i) { + $refs[(string) $i['reference']] = $i['name']; + } + + // + $h = ''; + $h.=''; + foreach ($cols as $l => $k) { + $h.=''; + } + foreach ($refs as $k => $l) { + $h.=''; + } + $h.=''; + + $r = $core->con->select('SELECT * FROM grdf' . $annee); + while ($r->fetch()) { + $d = json_decode($r->datas); + $rl = explode(',', $d->reflist); + $h.=''; + foreach ($cols as $l => $k) { + $v = $d->$k; + if ($k == 'date') { + $v = date('Y-m-d H:i', $v); + } + $h.=''; + } + foreach ($refs as $k => $l) { + $v = in_array($k, $rl) ? '1' : '0'; + $h.=''; + } + $h.=''; + } + + $h.='
' . utf8_decode($l) . '' . utf8_decode($l) . '
' . utf8_decode($v) . '' . utf8_decode($v) . '
'; + + if (!file_exists(ROOT . '/cache/12568/')) { + mkdir(ROOT . '/cache/12568/', 0777, true); + } + file_put_contents(ROOT . '/cache/12568/chequieravantage.xls', $h); + http::redirect('/cache/12568/chequieravantage.xls'); + exit; + } + + public function proxy() { + ob_end_clean(); + fb(netHttp::quickGet($_GET['u'], 'php://output')); + $this->outputXML = false; + } + + public function wescoRef() { + global $core; + + $ref = ltrim(substr($this->args['ref'], 4), '0'); + + $r = $core->con->select('SELECT url FROM wescoref WHERE ref="' . $core->con->escape($ref) . '"'); + if ($r->count()) { + header('Location: ' . $r->url); + exit; + } + $cache = ROOT . '/cache/wesco/' . $this->args['ref']; + if (file_exists($cache)) { + header('Location: ' . file_get_contents($cache)); + exit; + } + $url = 'http://www.wesco-eshop.fr/catalogsearch/result/?q=' . $ref; + $doc = new DOMDocument(); + $doc->loadHTML(file_get_contents($url)); + $x = simplexml_import_dom($doc); + $xpath = $x->xpath('//a[@class="product-image"]'); + if (count($xpath) > 0) { + $r = $xpath[0]['href']; + file_put_contents($cache, $r); + header('Location: ' . $r); + exit; + } + header('Location: http://www.wesco-eshop.fr'); + } + + public function flfRef() { + global $core; + + $r = $core->con->select('SELECT url FROM flfref WHERE ref="' . $core->con->escape($this->args['ref']) . '"'); + if ($r->count()) { + header('Location: http://www.flf.fr' . $r->url); + exit; + } + } + + public function collection() { + global $core; + $id = $this->callArgs[0]; + $os = $this->callArgs[1]; + $resolution = $this->callArgs[2]; + $local = (isset($this->callArgs[3])) ? $this->callArgs[3] : null; + + if ($id == 4) { + $resolution = 150; + } + + $this->outputXML = false; + header('Content-type: application/json'); + + $cache = WS_COLLECTIONS . '/ws/' . $id . '.' . $os . '.' . $resolution . '.json'; + $update = WS_COLLECTIONS . '/ws/' . $id . '.' . $os . '.' . $resolution . '.update'; + + if (file_exists($update) && filemtime(__FILE__) > filemtime($update)) { + unlink($update); + } + + if (!is_null($local) && file_exists($update) && file_get_contents($update) == $local) { + echo 'false'; + exit; + } + + $limit = TIME - 72000; + if (!file_exists($cache) || !file_exists($update) || filemtime($cache) < $limit) { + $r = $core->con->select('SELECT * FROM book_collection_compile WHERE online_' . $os . '=1 AND collection_id=\'' . $core->con->escape($id) . '\''); + $r->fetch(); + $version = $r->compile_date; + + $daoCollection = new wsDAOCollection($core->con); + $collection = $daoCollection->selectById($id); + + $ns = $collection->settings['namespace']; + + + $vcompo = WS_COLLECTIONS . '/versions/' . $id . '/' . $version . '/composition.json'; + $composition = json_decode(file_get_contents($vcompo)); + + $couvertures = array(); + $vroot = WS_COLLECTIONS . '/versions/' . $id . '/' . $version . '/' . $os . '/'; + + $publications = array(); + $langs = array(); + + foreach ($composition as $k => $g) { + foreach ($g->publications as $l => $p) { + $publications[] = $p->id; + } + } + + $daoBook = new wsDAOBook($core->con); + $books = $daoBook->selectByIds($publications); + + $langsnames = array(); + foreach ($composition as $k => $g) { + foreach ($g->publications as $l => $p) { + $book = $books[$p->id]; + $root = WS_COLLECTIONS . '/versions/' . $id . '/' . $version . '/' . $os . '/' . $p->id; + $couv = $root . '/cover.jpg'; + $couvertures[$p->id] = base64_encode(file_get_contents($couv)); + $composition[$k]->publications[$l]->width = $book->parametres->width; + $composition[$k]->publications[$l]->height = $book->parametres->height; + $composition[$k]->publications[$l]->lang = $book->lang; + $langs[] = $book->lang; + } + } + + $langs = array_unique($langs); + + $w2h = new wiki2xhtml(); + $w2h->setOpt('active_pre', 0); + + $contents = $collection->contents; + foreach ($langs as $lang) { + $langsnames[$lang] = cubeLang::getNameByCode($lang); + $contents[$lang]['apropos'] = $w2h->transform($contents[$lang]['apropos']); + } + + + $traductions = array(); + $r = $core->con->select('SELECT traductions,lang_id FROM langues WHERE lang_id IN(\'' . implode('\',\'', $langs) . '\')'); + while ($r->fetch()) { + $traductions[$r->lang_id] = json_decode($r->traductions); + } + + $d = array('id' => $id, 'res' => $resolution, 'ns' => $ns, 'langs' => $langs, 'langnames' => $langsnames, 'time' => $version, 'datas' => $composition, 'couvertures' => $couvertures, 'traductions' => $traductions, 'contents' => $contents); + $d = array_merge($d, $this->_getManifest($publications, '/fluidbook/collections/versions/' . $id . '/' . $version . '/' . $os, $books, $resolution)); + + $dao = new wsDAOCollection($core->con); + $col = $dao->selectById($id); + + $json = json_encode($d); + file_put_contents($cache, $json); + file_put_contents($update, $version); + } else { + $d = json_decode(file_get_contents($cache), true); + } + + $force = false; + if (!is_null($local)) { + $lcompo = WS_COLLECTIONS . '/versions/' . $id . '/' . $local . '/composition.json'; + if (!file_exists($lcompo)) { + $force = true; + } + } + + $d['forceUpdate'] = $force; + echo json_encode($d); + exit; + } + + protected function _getManifest($publications, $dir, $books, $resolution) { + global $core; + $res = array(); + $res['manifest'] = array('assetRoot' => 'http://workshop.fluidbook.com' . $dir . '/', 'autoDownload' => false); + $res['manifestPub'] = array(); + + $bundles = array(); + + $removeFromRelative = realpath(ROOT . '/' . $dir) . '/'; + $daoTheme = new wsDAOTheme($core->con); + + foreach ($publications as $p) { + $res['manifestPub'][$p] = array('assetRoot' => 'http://workshop.fluidbook.com' . $dir . '/', 'autoDownload' => true); + + $r = $p . '/'; + $iterator = CubeIT_Files::getRecursiveDirectoryIterator(ROOT . $dir . '/' . $p); + $book = $books[$p]; + $reso = $resolution; + + $theme = $daoTheme->selectById($book->theme); + $orders = $this->_getBundles($book); + $regexp = $this->_getRegExpManifest($r, $book, $theme, $reso); + $reg = $regexp['reg']; + $exclude = $regexp['exclude']; + + $b = array(); + + foreach ($iterator as $k => $f) { + if ($f->isDir()) { + continue; + } + $path = str_replace($removeFromRelative, '', $k); + + foreach ($exclude as $e) { + if (preg_match('|' . $e . '|', $path)) { + continue 2; + } + } + + $order = $this->_inFirstManifest($path, $orders, $reg); + + if (!isset($b[$order])) { + $b[$order] = array(); + } + + $b[$order][] = $path; + } + + $bundles[] = array('name' => 'p_' . $p, 'contents' => $b['loading']); + $res['manifestPub'][$p]['bundles'] = array(); + + foreach ($b as $name => $contents) { + if ($name == 'loading') { + continue; + } + $k = array_search($name, $orders); + $res['manifestPub'][$p]['bundles'][$k] = array('name' => $name, 'contents' => $contents); + } + ksort($res['manifestPub'][$p]['bundles']); + $res['manifestPub'][$p]['bundles'] = array_values($res['manifestPub'][$p]['bundles']); + } + + $res['manifest']['bundles'] = $bundles; + return $res; + } + + protected function _getRegExpManifest($r, $book, $theme, $resolution) { + $reg = array(); + $reg['loading'] = array('^' . $r . 'style/(.*).css$', '^' . $r . 'index.html$', '^' . $r . 'data/style/(.*)$', '^' . $r . 'data/(.*).js$', '^' . $r . 'data/images/' . $theme->parametres->logoLoader . '$', '^' . $r . 'style/fonts/(.*).ttf$', '^' . $r . 'data/images/interface-down.svg$', '^' . $r . 'plugins/(.*)$'); + $reg['extras'] = array('^' . $r . 'data/links/(.*).mp4$', '^' . $r . 'data/links/(.*).ogv$', '^' . $r . 'data/links/(.*).webm$', '^' . $r . 'data/(.*).pdf$', '^' . $r . 'cover.jpg$'); + $reg['thumbnails'] = array('^' . $r . 'data/thumbnails/p(\d+).jpg$'); + for ($i = 1; $i <= $book->parametres->pages; $i++) { + $var = 'content_' . $i; + $reg[$var] = array('^' . $r . 'data/background/\d+/t' . $i . '.jpg$', '^' . $r . 'data/contents/p' . $i . '.svg$'); + } + $reg['urgents'] = array('^' . $r . 'images/(.*)$', '^' . $r . 'data/images/(.*)$', '^' . $r . 'data/links/(.*).jpg$', '^' . $r . 'data/links/(.*).png$'); + $reg['loading'] = array_merge($reg['loading'], $reg['urgents']); + + + $exclude = array(); + if ($resolution == 150) { + $er = 300; + } else { + $er = 150; + } + $exclude[] = '^' . $r . 'data/background/' . $er . '/t\d+.jpg$'; + return array('reg' => $reg, 'exclude' => $exclude); + } + + protected function _inFirstManifest($p, $orders, $reg) { + foreach ($orders as $list) { + foreach ($reg[$list] as $v) { + if (preg_match('|' . $v . '|', $p)) { + return $list; + } + } + } + return $list; + } + + protected function _getBundles($book) { + $res = array(0 => 'loading', 20001 => 'extras', 20000 => 'thumbnails', 1 => 'urgents'); + for ($i = 1; $i <= $book->parametres->pages; $i++) { + $k = 2 + $i; + $res[$k] = 'content_' . $i; + } + return $res; + } + + public function collectionPushRegister() { + global $core; + + $c = $core->con->openCursor('book_collection_push'); + $c->collection_id = $_POST['id']; + $c->token = $_POST['token']; + $c->datas = $_POST['datas']; + $c->platform = $_POST['platform']; + $c->locale = $_POST['locale']; + $c->last_visit = TIME; + try { + $c->insert(); + } catch (Exception $e) { + $c->update('WHERE collection_id=\'' . $core->con->escape($_POST['id']) . '\' AND token=\'' . $core->con->escape($_POST['token']) . '\''); + } + } + +} + ?> \ No newline at end of file diff --git a/inc/ws/DAO/class.ws.dao.book.php b/inc/ws/DAO/class.ws.dao.book.php index 133f51d05..bd263961d 100644 --- a/inc/ws/DAO/class.ws.dao.book.php +++ b/inc/ws/DAO/class.ws.dao.book.php @@ -1,1668 +1,1674 @@ -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'; - } - $sql = 'SELECT * FROM ' . $table . ' WHERE book_id IN (' . implode(',', $book_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_timecon->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']) . '\''); - } - - return $this->selectById($book_id); - } - - public function duplicate($book_id, $createur, $nom, $pages = 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); - $parametres->title = $nom; - - $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); - } - $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 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`'); - if (!$r->count()) { - return $this->getPagesOfBook($book_id); - } - if ($r->count() == 1) { - $pages = unserialize($r->composition); - if (!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); - } - return unserialize($pages); - } - $pages = $r->composition; - } - return unserialize($pages); - } - - 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) { - $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; - } - } - } - } - return $pages; - } - - 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; - } - - $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 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)); - } - - 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) { - $c1->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\' AND `update`=' . TIME); - } - } - - 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('http://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); - - $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] = trim($v); - } - - $daoLang = new wsDAOLang($this->con); - $lang = $daoLang->selectById($base); - // Cleanup base translations - $baseTraductions = $lang->traductions; - foreach ($baseTraductions as $k => $v) { - $baseTraductions[$k] = trim($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') { - // 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(); - 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) { - - $prefix = ''; - if ($book->parametres->textExtraction == 'poppler') { - $prefix = 'p'; - } - - - $dir = WS_BOOKS . '/index/' . $book->book_id; - if ($book->parametres->ignoreSearchSeparators != '') { - $dir.='/' . sha1($book->parametres->ignoreSearchSeparators); - } - if (!file_exists($dir)) { - mkdir($dir, 0777, true); - } - - $ifilec = $dir . '/' . $prefix . 'index.json'; - $tfilec = $dir . '/' . $prefix . 'textes.json'; - - if (file_exists($ifilec) && file_exists($tfilec) && (min(filemtime($ifilec), filemtime($tfilec)) >= $book->composition_update)) { - $index = file_get_contents($ifilec); - $textes = 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 = WS_DOCS . '/' . $doc . '/'; - - $fwstk = new cubeCommandLine('fwstk'); - $fwstk->setPath(CONVERTER_PATH); - $fwstk->setArg('--input ' . $out . '/crop.pdf'); - $fwstk->setArg('--extractTexts ' . $out . '%s%d.txt'); - $fwstk->setArg('--ignoreSeparators ' . $book->parametres->ignoreSearchSeparators); - $fwstk->execute(); - } - } - - $index = array(); - $textes = array(); - foreach ($pages as $book_page => $infos) { - $tfile = WS_DOCS . '/' . $infos['document_id'] . '/' . $prefix . 'p' . $infos['document_page'] . '.txt'; - $ifile = WS_DOCS . '/' . $infos['document_id'] . '/' . $prefix . 'i' . $infos['document_page'] . '.txt'; - $text = file_get_contents($tfile); - $ipage = file_get_contents($ifile); - - $this->fillIndexWithWords($index, $book_page, $ipage); - $textes[$book_page] = $text; - } - ksort($index); - - - $textes = json_encode($textes); - $index = json_encode($index); - - file_put_contents($tfilec, $textes); - file_put_contents($ifilec, $index); - } - - 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) { - 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; - } - - $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 = false; - $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); - $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 . '/'; - - $rm = new cubeCommandLine('rm'); - $rm->setArg('r'); - $rm->setArg('f'); - $rm->setArg(null, $finalDir); - $rm->execute(); - mkdir($finalDir, 0777, true); - - $flex = new cubeFlexCompiler('FluidbookDatas', $compilerDir, 'flash.display.Sprite', explode(';', AS3_SOURCES), MXMLC_PATH, 10); - $flexLight = new cubeFlexCompiler('FluidbookDatasLight', $compilerDir, 'flash.display.Sprite', explode(';', AS3_SOURCES), MXMLC_PATH, 10); - - $filesToCopy = array(); - $this->compileFlex($book_id, $complete, $compilerDir, $finalDir, $filesToCopy, $book, $pages, $flex, $flexLight); - - $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 - if (!file_exists($finalDir . 'data')) { - mkdir($finalDir . 'data', 0777, true); - } - - foreach ($filesToCopy as $local => $source) { - $localPath = $finalDir . $local; - if (!file_exists($localPath) || filemtime($localPath) < filemtime($source) || filesize($localPath) != filesize($source) || filemtime($localPath) < $book->composition_update) { - if (is_dir($source)) { - continue; - } - $this->copy($source, $localPath); - } - } - - $workingDir = WS_BOOKS . '/working/' . $book_id . '/'; - if (file_exists($workingDir . 'media')) { - $cp = new cubeCommandLine('cp'); - $cp->setPath(CONVERTER_PATH); - $cp->setArg('r'); - $cp->setArg('p'); - $cp->setArg(null, $workingDir . 'media'); - $cp->setArg(null, $finalDir . 'data'); - $cp->execute(); - } - - return $res; - } - - public function copy($source, $dest) { - copy($source, $dest); - touch($dest, filemtime($source)); - } - - 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, $finalDir, &$filesToCopy, $book, $pages, $flex, $flexLight) { - 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 = ''; - - $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); - - $imagesassets = array(); - $id = 1; - foreach ($links as $id => $link) { - $links[$id]['id'] = $id; - 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))) { - $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; - } - } - } - } - - $externalsOptions = array('ongletsSWF', 'tabs2DSWF', 'externalChapters', 'externalArchives'); - 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('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', '' . $book->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 = WS_DOCS . '/' . $infos['document_id'] . '/p' . $infos['document_page']; - $baset = WS_DOCS . '/' . $infos['document_id'] . '/t' . $infos['document_page']; - $swffile = $base . '.swf'; - if (file_exists($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; - } - } - - if ($i == 1) { - $flexLight->addBitmap($base . '.jpg', 'thumb1'); - } else { - $flex->addBitmap($base . '.jpg', '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; - } - $n = cubeText::ucfirst($iso[$mlang]); - $langNames[$mlang] = $n; - $cn = cubeCountry::getCountryName($flag, $mlang); - $countryNames[$mlang . '_' . $flag] = $cn; - $chars.=$n . $cn; - } - - $chars = preg_split('/(?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 = $workingDir . 'commerce/' . $book->parametres->basketReferences; - - if (file_exists($referencesFile)) { - $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++; - } - } - 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') { - $flex->addFont(FONT_PATH . '/' . $lang->font, 'BoldFont', $lang->charset); - $flex->addFont(FONT_PATH . '/' . $lang->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 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 = WS_DOCS . '/' . $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) { - $htmlCompiler = wsHTML5Compiler::factory($book_id, $book->parametres->mobileLVersion); - $htmlCompiler->compile(); - } - - 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(WS_DOCS . '/' . $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) { - if(substr($book->parametres->pdfName,0,4)=='http'){ - return; - } - if (isset($book->parametres->pdfName) && $book->parametres->pdfName != '') { - $pdfName = $book->parametres->pdfName; - } - - $cacheDir = WS_BOOKS . '/pdf/' . $book->book_id; - if (!file_exists($cacheDir)) { - mkdir($cacheDir); - } - - $normalPDF = $cacheDir . '/normal.pdf'; - $compressedPDF = $cacheDir . '/compressed.pdf'; - - if ($book->parametres->pdfReplace) { - $replace = WS_BOOKS . '/working/' . $book->book_id . '/' . $book->parametres->pdfReplace; - if (file_exists($replace)) { - if (!file_exists($normalPDF) || filemtime($normalPDF) < filemtime($replace) || filesize($normalPDF) != filesize($replace)) { - $this->copy($replace, $normalPDF); - } - } - } else { - - if (file_exists($normalPDF)) { - $fmtime = filemtime($normalPDF); - if ($fmtime >= $book->composition_update) { - $invalid = false; - foreach ($pages as $i => $infos) { - $doc = WS_DOCS . '/' . $infos['document_id'] . '/crop.pdf'; - if (filemtime($doc) > $fmtime) { - $invalid = true; - } - } - } else { - $invalid = true; - } - } else { - $invalid = true; - } - - fb($invalid, 'invalid ?'); - - if ($invalid) { - $pdfList = array(); - $pagesList = array(); - $nb_pages = array(); - $j = 0; - $k = 0; - $original = true; - - foreach ($pages as $i => $infos) { - if (!isset($firstDoc)) { - $firstDoc = $infos['document_id']; - } - - $doc = WS_DOCS . '/' . $infos['document_id'] . '/crop.pdf'; - if (!isset($pdfList[$doc])) { - $pdfList[$doc] = $j; - $nb_pages[$doc] = $infos['nb_pages']; - $k = $j; - $j++; - } else { - $k = $pdfList[$doc]; - } - $pagesList[$i] = array($k, $infos['document_page']); - - if ($i != $infos['document_page'] || $infos['document_id'] != $firstDoc) { - $original = false; - } - } - - if ($original) { - fb($normalPDF, 'original'); - $this->copy(WS_DOCS . '/' . $firstDoc . '/crop.pdf', $normalPDF); - } else { - $args = ''; - foreach ($pdfList as $doc => $index) { - $lettre = cubeMath::toPDFLetter($index, true); - $args .= $lettre . '=' . $doc . ' '; - } - - $args .= ' cat '; - - $ranges = array(); - $currentRange = null; - - foreach ($pagesList as $p) { - $lettre = cubeMath::toPDFLetter($p[0], true); - $page = $p[1]; - - // Initialise l'intervale - if (is_null($currentRange)) { - $currentRange = array('lettre' => $lettre, 'start' => $page, 'end' => $page); - continue; - } - - // Poursuit le remplissage si la lettre est identique et si la page suivante est bien la page suivante dans le document - if ($currentRange['lettre'] == $lettre && $currentRange['end'] + 1 == $page) { - $currentRange['end'] = $page; - continue; - } - - // Ajoute l'intervale à la liste finale - $ranges[] = $currentRange; - - // Réinitialise l'intervale suivant - $currentRange = array('lettre' => $lettre, 'start' => $page, 'end' => $page); - } - - // Ajoute la dernière - if (!is_null($currentRange)) { - $ranges[] = $currentRange; - } - // Si le pdf final est constitué du document complet d'un document - if (count($ranges) == 1 && $ranges[0]['start'] == 1) { - $alldocs = array_keys($pdfList); - $doc = array_pop($alldocs); - if ($nb_pages[$doc] == $ranges[0]['end']) { - $this->copy($doc, $normalPDF); - return; - } - } - - foreach ($ranges as $range) { - $args .= ' ' . $range['lettre'] . $range['start']; - if ($range['start'] == $range['end']) { - continue; - } - $args .= '-' . $range['end']; - } - - $hash = sha1($args); - - $args .= ' output ' . $normalPDF; - - $cached = WS_BOOKS . '/pdf/' . $hash . '.pdf'; - - if (file_exists($cached)) { - $this->copy($cached, $normalPDF); - } else { - $pdftk = new cubeCommandLine('pdftk'); - $pdftk->setPath(CONVERTER_PATH); - $pdftk->setManualArg($args); - $pdftk->execute(); - $this->copy($normalPDF, $cached); - } - } - } - } - - $finalPDF = WS_BOOKS . '/final/' . $book->book_id . '/data/' . $book->parametres->pdfName; - - if ($book->parametres->pdfCompress) { - if (!file_exists($compressedPDF) || filemtime($compressedPDF) < filemtime($normalPDF)) { - $gs = new cubeCommandLine('gs', null, true); - $gs->setPath(CONVERTER_PATH); - $gs->setEnv('GS_FONTPATH', '/home/ws/fonts'); - $gs->setArg('-dBATCH'); - $gs->setArg('-dNOPAUSE'); - $gs->setArg('-dNOPROMPT'); - $gs->setArg('-sOutputFile=' . $compressedPDF); - $gs->setArg('-sDEVICE=pdfwrite'); - $gs->setArg('-dPDFSETTINGS=/ebook'); - $gs->setArg('-dColorImageResolution=72'); - $gs->setArg('-dAutoRotatePages=/None'); - $gs->setArg('-dColorConversionStrategy=/LeaveColorUnchanged'); - $gs->setArg(null, $normalPDF); - $gs->execute(); - } - copy($compressedPDF, $finalPDF); - } else { - copy($normalPDF, $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; - } - -} - +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'; + } + $sql = 'SELECT * FROM ' . $table . ' WHERE book_id IN (' . implode(',', $book_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_timecon->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']) . '\''); + } + + return $this->selectById($book_id); + } + + public function duplicate($book_id, $createur, $nom, $pages = 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); + $parametres->title = $nom; + + $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); + } + $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 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`'); + if (!$r->count()) { + return $this->getPagesOfBook($book_id); + } + if ($r->count() == 1) { + $pages = unserialize($r->composition); + if (!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); + } + return unserialize($pages); + } + $pages = $r->composition; + } + return unserialize($pages); + } + + 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) { + $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; + } + } + } + } + return $pages; + } + + 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; + } + + $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 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)); + } + + 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) { + $c1->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\' AND `update`=' . TIME); + } + } + + 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('http://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); + + $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] = trim($v); + } + + $daoLang = new wsDAOLang($this->con); + $lang = $daoLang->selectById($base); + // Cleanup base translations + $baseTraductions = $lang->traductions; + foreach ($baseTraductions as $k => $v) { + $baseTraductions[$k] = trim($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') { + // 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(); + 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) { + + $prefix = ''; + if ($book->parametres->textExtraction == 'poppler') { + $prefix = 'p'; + } + + + $dir = WS_BOOKS . '/index/' . $book->book_id; + if ($book->parametres->ignoreSearchSeparators != '') { + $dir.='/' . sha1($book->parametres->ignoreSearchSeparators); + } + if (!file_exists($dir)) { + mkdir($dir, 0777, true); + } + + $ifilec = $dir . '/' . $prefix . 'index.json'; + $tfilec = $dir . '/' . $prefix . 'textes.json'; + + if (file_exists($ifilec) && file_exists($tfilec) && (min(filemtime($ifilec), filemtime($tfilec)) >= $book->composition_update)) { + $index = file_get_contents($ifilec); + $textes = 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 = WS_DOCS . '/' . $doc . '/'; + + $fwstk = new cubeCommandLine('fwstk'); + $fwstk->setPath(CONVERTER_PATH); + $fwstk->setArg('--input ' . $out . '/crop.pdf'); + $fwstk->setArg('--extractTexts ' . $out . '%s%d.txt'); + $fwstk->setArg('--ignoreSeparators ' . $book->parametres->ignoreSearchSeparators); + $fwstk->execute(); + } + } + + $index = array(); + $textes = array(); + foreach ($pages as $book_page => $infos) { + $tfile = WS_DOCS . '/' . $infos['document_id'] . '/' . $prefix . 'p' . $infos['document_page'] . '.txt'; + $ifile = WS_DOCS . '/' . $infos['document_id'] . '/' . $prefix . 'i' . $infos['document_page'] . '.txt'; + $text = file_get_contents($tfile); + $ipage = file_get_contents($ifile); + + $this->fillIndexWithWords($index, $book_page, $ipage); + $textes[$book_page] = $text; + } + ksort($index); + + + $textes = json_encode($textes); + $index = json_encode($index); + + file_put_contents($tfilec, $textes); + file_put_contents($ifilec, $index); + } + + 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) { + 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; + } + + $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 = false; + $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); + $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 . '/'; + + $rm = new cubeCommandLine('rm'); + $rm->setArg('r'); + $rm->setArg('f'); + $rm->setArg(null, $finalDir); + $rm->execute(); + mkdir($finalDir, 0777, true); + + $flex = new cubeFlexCompiler('FluidbookDatas', $compilerDir, 'flash.display.Sprite', explode(';', AS3_SOURCES), MXMLC_PATH, 10); + $flexLight = new cubeFlexCompiler('FluidbookDatasLight', $compilerDir, 'flash.display.Sprite', explode(';', AS3_SOURCES), MXMLC_PATH, 10); + + $filesToCopy = array(); + $this->compileFlex($book_id, $complete, $compilerDir, $finalDir, $filesToCopy, $book, $pages, $flex, $flexLight); + + $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 + if (!file_exists($finalDir . 'data')) { + mkdir($finalDir . 'data', 0777, true); + } + + foreach ($filesToCopy as $local => $source) { + $localPath = $finalDir . $local; + if (!file_exists($localPath) || filemtime($localPath) < filemtime($source) || filesize($localPath) != filesize($source) || filemtime($localPath) < $book->composition_update) { + if (is_dir($source)) { + continue; + } + $this->copy($source, $localPath); + } + } + + $workingDir = WS_BOOKS . '/working/' . $book_id . '/'; + if (file_exists($workingDir . 'media')) { + $cp = new cubeCommandLine('cp'); + $cp->setPath(CONVERTER_PATH); + $cp->setArg('r'); + $cp->setArg('p'); + $cp->setArg(null, $workingDir . 'media'); + $cp->setArg(null, $finalDir . 'data'); + $cp->execute(); + } + + return $res; + } + + public function copy($source, $dest) { + copy($source, $dest); + touch($dest, filemtime($source)); + } + + 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, $finalDir, &$filesToCopy, $book, $pages, $flex, $flexLight) { + 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 = ''; + + $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); + + $imagesassets = array(); + $id = 1; + foreach ($links as $id => $link) { + $links[$id]['id'] = $id; + 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))) { + $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; + } + } + } + } + + $externalsOptions = array('ongletsSWF', 'tabs2DSWF', 'externalChapters', 'externalArchives'); + 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('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', '' . $book->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 = WS_DOCS . '/' . $infos['document_id'] . '/p' . $infos['document_page']; + $baset = WS_DOCS . '/' . $infos['document_id'] . '/t' . $infos['document_page']; + $swffile = $base . '.swf'; + if (file_exists($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; + } + } + + if ($i == 1) { + $flexLight->addBitmap($base . '.jpg', 'thumb1'); + } else { + $flex->addBitmap($base . '.jpg', '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; + } + $n = cubeText::ucfirst($iso[$mlang]); + $langNames[$mlang] = $n; + $cn = cubeCountry::getCountryName($flag, $mlang); + $countryNames[$mlang . '_' . $flag] = $cn; + $chars.=$n . $cn; + } + + $chars = preg_split('/(?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 = $workingDir . 'commerce/' . $book->parametres->basketReferences; + + if (file_exists($referencesFile)) { + $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++; + } + } + 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') { + $flex->addFont(FONT_PATH . '/' . $lang->font, 'BoldFont', $lang->charset); + $flex->addFont(FONT_PATH . '/' . $lang->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 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 = WS_DOCS . '/' . $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) { + $htmlCompiler = wsHTML5Compiler::factory($book_id, $book->parametres->mobileLVersion); + $htmlCompiler->compile(); + } + + 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(WS_DOCS . '/' . $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) { + if (substr($book->parametres->pdfName, 0, 4) == 'http') { + return; + } + if (isset($book->parametres->pdfName) && $book->parametres->pdfName != '') { + $pdfName = $book->parametres->pdfName; + } + + $cacheDir = WS_BOOKS . '/pdf/' . $book->book_id; + if (!file_exists($cacheDir)) { + mkdir($cacheDir); + } + + $normalPDF = $cacheDir . '/normal.pdf'; + $originalPDF = $cacheDir . '/original.pdf'; + $compressedPDF = $cacheDir . '/compressed.pdf'; + + + + + if (file_exists($originalPDF)) { + $fmtime = filemtime($originalPDF); + if ($fmtime >= $book->composition_update) { + $invalid = false; + foreach ($pages as $i => $infos) { + $doc = WS_DOCS . '/' . $infos['document_id'] . '/crop.pdf'; + if (filemtime($doc) > $fmtime) { + $invalid = true; + } + } + } else { + $invalid = true; + } + } else { + $invalid = true; + } + + + if ($invalid) { + $pdfList = array(); + $pagesList = array(); + $nb_pages = array(); + $j = 0; + $k = 0; + $original = true; + + foreach ($pages as $i => $infos) { + if (!isset($firstDoc)) { + $firstDoc = $infos['document_id']; + } + + $doc = WS_DOCS . '/' . $infos['document_id'] . '/crop.pdf'; + if (!isset($pdfList[$doc])) { + $pdfList[$doc] = $j; + $nb_pages[$doc] = $infos['nb_pages']; + $k = $j; + $j++; + } else { + $k = $pdfList[$doc]; + } + $pagesList[$i] = array($k, $infos['document_page']); + + if ($i != $infos['document_page'] || $infos['document_id'] != $firstDoc) { + $original = false; + } + } + + if ($original) { + + $this->copy(WS_DOCS . '/' . $firstDoc . '/crop.pdf', $originalPDF); + } else { + $args = ''; + foreach ($pdfList as $doc => $index) { + $lettre = cubeMath::toPDFLetter($index, true); + $args .= $lettre . '=' . $doc . ' '; + } + + $args .= ' cat '; + + $ranges = array(); + $currentRange = null; + + foreach ($pagesList as $p) { + $lettre = cubeMath::toPDFLetter($p[0], true); + $page = $p[1]; + + // Initialise l'intervale + if (is_null($currentRange)) { + $currentRange = array('lettre' => $lettre, 'start' => $page, 'end' => $page); + continue; + } + + // Poursuit le remplissage si la lettre est identique et si la page suivante est bien la page suivante dans le document + if ($currentRange['lettre'] == $lettre && $currentRange['end'] + 1 == $page) { + $currentRange['end'] = $page; + continue; + } + + // Ajoute l'intervale à la liste finale + $ranges[] = $currentRange; + + // Réinitialise l'intervale suivant + $currentRange = array('lettre' => $lettre, 'start' => $page, 'end' => $page); + } + + // Ajoute la dernière + if (!is_null($currentRange)) { + $ranges[] = $currentRange; + } + // Si le pdf final est constitué du document complet d'un document + if (count($ranges) == 1 && $ranges[0]['start'] == 1) { + $alldocs = array_keys($pdfList); + $doc = array_pop($alldocs); + if ($nb_pages[$doc] == $ranges[0]['end']) { + $this->copy($doc, $originalPDF); + return; + } + } + + foreach ($ranges as $range) { + $args .= ' ' . $range['lettre'] . $range['start']; + if ($range['start'] == $range['end']) { + continue; + } + $args .= '-' . $range['end']; + } + + $hash = sha1($args); + + $args .= ' output ' . $originalPDF; + + $cached = WS_BOOKS . '/pdf/' . $hash . '.pdf'; + + if (file_exists($cached)) { + $this->copy($cached, $originalPDF); + } else { + $pdftk = new cubeCommandLine('pdftk'); + $pdftk->setPath(CONVERTER_PATH); + $pdftk->setManualArg($args); + $pdftk->execute(); + $this->copy($normalPDF, $cached); + } + } + } + + + + + if ($book->parametres->pdfReplace) { + $replace = WS_BOOKS . '/working/' . $book->book_id . '/' . $book->parametres->pdfReplace; + if (file_exists($replace)) { + if (!file_exists($normalPDF) || filemtime($normalPDF) < filemtime($replace) || filesize($normalPDF) != filesize($replace)) { + $this->copy($replace, $normalPDF); + } + } + } else { + $this->copy($originalPDF, $normalPDF); + } + $finalPDF = WS_BOOKS . '/final/' . $book->book_id . '/data/' . $book->parametres->pdfName; + + if ($book->parametres->pdfCompress) { + if (!file_exists($compressedPDF) || filemtime($compressedPDF) < filemtime($normalPDF)) { + $gs = new cubeCommandLine('gs', null, true); + $gs->setPath(CONVERTER_PATH); + $gs->setEnv('GS_FONTPATH', '/home/ws/fonts'); + $gs->setArg('-dBATCH'); + $gs->setArg('-dNOPAUSE'); + $gs->setArg('-dNOPROMPT'); + $gs->setArg('-sOutputFile=' . $compressedPDF); + $gs->setArg('-sDEVICE=pdfwrite'); + $gs->setArg('-dPDFSETTINGS=/ebook'); + $gs->setArg('-dColorImageResolution=72'); + $gs->setArg('-dAutoRotatePages=/None'); + $gs->setArg('-dColorConversionStrategy=/LeaveColorUnchanged'); + $gs->setArg(null, $normalPDF); + $gs->execute(); + } + copy($compressedPDF, $finalPDF); + } else { + copy($normalPDF, $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; + } + +} + ?> \ No newline at end of file -- 2.39.5