-<?php\r
-\r
-class wsServices extends cubeFlashGateway {\r
-\r
- const CNAME = __CLASS__;\r
-\r
- public static function in($args) {\r
- global $core;\r
- $args = cubePage::getArgs($args);\r
- $n = self::CNAME;\r
- $gateway = new $n($core->con, $args);\r
- }\r
-\r
- public function sendEmail() {\r
- if (!$this->_checkHash()) {\r
- return;\r
- }\r
- // Send the email\r
- $mail = new cubeMail();\r
- $mail->returnPath = 'postmaster@fluidbook.com';\r
- $mail->acknowledge = isset($this->args['askAcknowledge']) && $this->args['askAcknowledge'];\r
- $mail->charset = 'UTF-8';\r
- $mail->to = $this->args['email'];\r
- $mail->from = $this->args['fromname'] . '<' . $this->args['fromemail'] . '>';\r
- $mail->subject = $this->args['subject'];\r
- $mail->body = $this->args['body'];\r
- $this->xml->addChild('ok', $mail->send() ? '1' : '0');\r
- }\r
-\r
- protected function _checkHash() {\r
- // Check protection hash\r
- $hash = md5(substr($this->args['fromemail'], 2, 6) . substr($this->args['email'], 3, 5) . 'SFGHF566!S' . $this->args['id']);\r
- if ($hash != $this->args['hash']) {\r
- $this->xml->addChild('hashOK', '0');\r
- $this->xml->addChild('ok', '0');\r
- return false;\r
- }\r
- $this->xml->addChild('hashOK', '1');\r
- return true;\r
- }\r
-\r
- public function sendBookmarks() {\r
- if (!$this->_checkHash()) {\r
- return;\r
- }\r
-\r
- $bookmarks = json_decode(base64_decode($this->args['bookmarks']), true);\r
- $files = array();\r
- foreach ($bookmarks as $b) {\r
- $range = $b['page'];\r
- if ($b['nb'] > 1) {\r
- $range.='-' . ($b['page'] + $b['nb'] - 1);\r
- }\r
-\r
- $file = $this->getPDFComplex($this->args['id'], $range);\r
- $files[] = array('name' => $b['name'], 'file' => $file['file']);\r
- }\r
-\r
- $limit = 5 * 1024 * 1024 * 0.8;\r
- $groups = array();\r
- $group = array();\r
- $groupsize = 0;\r
- foreach ($files as $f) {\r
- $size = filesize($f['file']);\r
-\r
- if ($groupsize + $size > $limit) {\r
- if (count($group)) {\r
- $groups[] = $group;\r
- $group = array();\r
- $groupsize = 0;\r
- }\r
-\r
- $group[] = $f;\r
- $groupsize = $size;\r
-\r
- if ($groupsize > $limit) {\r
- $groups[] = $group;\r
- $group = array();\r
- $groupsize = 0;\r
- }\r
- } else {\r
- $group[] = $f;\r
- $groupsize+=$size;\r
- }\r
- }\r
-\r
- if (count($group)) {\r
- $groups[] = $group;\r
- }\r
-\r
-\r
- $total = count($groups);\r
- foreach ($groups as $i => $g) {\r
- $s = '';\r
- if ($total > 1) {\r
- $s = ' (' . ($i + 1) . '/' . $total . ')';\r
- }\r
-\r
- // Send the email\r
- $mail = new cubeMail();\r
- $mail->returnPath = 'postmaster@fluidbook.com';\r
- $mail->acknowledge = isset($this->args['askAcknowledge']) && $this->args['askAcknowledge'];\r
- $mail->charset = 'UTF-8';\r
- $mail->to = $this->args['email'];\r
- $mail->from = $this->args['fromname'] . '<' . $this->args['fromemail'] . '>';\r
- $mail->subject = $this->args['subject'] . $s;\r
- $mail->body = $this->args['body'];\r
- foreach ($g as $f) {\r
- $mail->addFile($f['name'] . '.pdf', $f['file']);\r
- }\r
- $this->xml->addChild('ok', $mail->send() ? '1' : '0');\r
- }\r
- }\r
-\r
- protected function shortenURL($url, $id) {\r
- $bitLyUser = 'fluidbook';\r
- $bitLyKey = 'R_3858dd1c9884d5c6a5fe386d7e95cf1d';\r
- // Recherche dans le cache\r
- $r = $this->con->select('SELECT * FROM book_short_url WHERE long_url=\'' . $this->con->escape($url) . '\' LIMIT 1');\r
- if ($r->count() > 0) {\r
- return $r->short_url;\r
- }\r
- // Si pas dans le cache, on le recherche\r
- $short_url = cubeURLShortener::bitLy($url, $bitLyUser, $bitLyKey);\r
- if (is_null($short_url) || empty($short_url) || !$short_url) {\r
- $short_url = cubeURLShortener::tinyURL($url);\r
- }\r
- $short_url = trim($short_url);\r
-\r
- $c = $this->con->openCursor('book_short_url');\r
- $c->long_url = $url;\r
- $c->book_id = $id;\r
- $c->short_url = $short_url;\r
- $c->insert();\r
-\r
- return $short_url;\r
- }\r
-\r
- /**\r
- * wsServices::facebook_thumbnail()\r
- *\r
- * @return\r
- */\r
- public function facebook_thumbnail() {\r
- $this->outputXML = false;\r
- $dao = new wsDAOBook($this->con);\r
-\r
- $book = $dao->selectById($this->args['id']);\r
-\r
-\r
- if (isset($book->parametres->facebook_image) && $book->parametres->facebook_image != '') {\r
- $c = WS_BOOKS . '/working/' . $this->args['id'] . '/' . $book->parametres->facebook_image;\r
- if (file_exists($c)) {\r
- $cover = $c;\r
- }\r
- }\r
- if (!isset($cover)) {\r
- $pages = $dao->getPagesOfBook($this->args['id']);\r
- $cover = WS_DOCS . '/' . $pages[1]['document_id'] . '/html/t36-' . $pages[1]['document_page'] . '.jpg';\r
- if (!file_exists($cover)) {\r
- $cover = WS_DOCS . '/' . $pages[1]['document_id'] . '/p' . $pages[1]['document_page'] . '.jpg';\r
- }\r
- }\r
- cubeHTTP::relayFile($cover);\r
- exit;\r
- }\r
-\r
- public function facebookShare() {\r
- http::redirect('http://www.facebook.com/sharer/sharer.php?u=' . urlencode($this->args['url']));\r
- exit;\r
- }\r
-\r
- public function googleplusShare() {\r
- http::redirect('https://plus.google.com/share?url=' . urlencode($this->args['url']) . "&sgp=1");\r
- exit;\r
- }\r
-\r
- public function linkedinShare() {\r
- http::redirect('https://www.linkedin.com/cws/share?url=' . urlencode($this->args['url']) . '&isFramed=true&_ts=' . microtime(true));\r
- }\r
-\r
- public function viadeoShare() {\r
- http::redirect('http://www.viadeo.com/shareit/share/?url=' . urlencode($this->args['url']));\r
- }\r
-\r
- public function twitterShare() {\r
- $url = $this->shortenURL($this->args['url'], $this->args['id']);\r
-\r
- $post = str_replace('%short%', $url, $this->args['post']);\r
- $post = rawurlencode($post);\r
-\r
- http::redirect('http://twitter.com/intent/tweet?source=webclient&text=' . $post);\r
- exit;\r
- }\r
-\r
- public function searchHints() {\r
- $index = Zend_Search_Lucene::open(WS_BOOKS . '/search/' . $this->args['id']);\r
-\r
- $charsLimit = 2;\r
-\r
- $terms = $this->getTerms($this->args['term']);\r
- $term = array_pop($terms);\r
-\r
- if (strlen($term) < $charsLimit) {\r
- $this->xml->addChild('hints', '{}');\r
- return;\r
- }\r
-\r
- $term = new Zend_Search_Lucene_Index_Term($term . '*', 'contents');\r
- $query = new Zend_Search_Lucene_Search_Query_Wildcard($term);\r
- $query->setMinPrefixLength($charsLimit);\r
-\r
- $index->find($query);\r
- $terms = $query->getQueryTerms();\r
- $res = array();\r
- foreach ($terms as $t) {\r
- $res[$t->text] = array_sum($index->termFreqs($t));\r
- }\r
- arsort($res);\r
- $res = array_slice($res, 0, 10, true);\r
- $this->xml->addChild('hints', json_encode($res));\r
- }\r
-\r
- public function searchResults() {\r
- $index = Zend_Search_Lucene::open(WS_BOOKS . '/search/' . $this->args['id']);\r
-\r
- $terms = $this->getTerms($this->args['term']);\r
-\r
- $query = new Zend_Search_Lucene_Search_Query_MultiTerm();\r
- foreach ($terms as $term) {\r
- $query->addTerm(new Zend_Search_Lucene_Index_Term($term, 'contents'), null);\r
- }\r
-\r
- $hits = $index->find($query);\r
- $res = array();\r
- $terms = array();\r
- foreach ($query->getQueryTerms() as $t) {\r
- $terms[] = $t->text;\r
- foreach ($index->termFreqs($t) as $doc_id => $f) {\r
- $page = trim($index->getDocument($doc_id)->getField('url')->getUtf8Value(), "#");\r
- if (!isset($res[$page])) {\r
- $res[$page] = 0;\r
- }\r
- $res[$page]+=$f;\r
- }\r
- }\r
- $this->xml->addChild('results', json_encode($res));\r
- $this->xml->addChild('terms', implode(',', $terms));\r
- }\r
-\r
- protected function getTerms($term) {\r
- $term = trim($term, '*? ');\r
- $term = mb_strtolower($term);\r
- $term = cubeText::removeAccents($term);\r
- $terms = explode(' ', $term);\r
- return $terms;\r
- }\r
-\r
- public function printpdf() {\r
- $this->outputXML = false;\r
- $this->exportpdf(true);\r
- }\r
-\r
- protected function getPDFComplex($book, $range) {\r
- global $core;\r
-\r
- $daoBook = new wsDAOBook($core->con);\r
-\r
- if (is_int($book) || is_string($book)) {\r
- $book = $daoBook->selectById($book);\r
- }\r
-\r
- if (is_null($book)) {\r
- return;\r
- }\r
-\r
- // Normalize range\r
- $range = cubeArray::parseRange($range);\r
-\r
- if ($k = array_search(0, $range)) {\r
- $range[$k] = 1;\r
- }\r
- if ($k = array_search($book->parametres->pages + 1, $range)) {\r
- $range[$k] = $r->pages;\r
- }\r
-\r
- if (!count($range)) {\r
- return;\r
- }\r
- // Paths init\r
- $baseDocument = WS_BOOKS . '/final/' . $book->book_id . '/data/' . $book->parametres->pdfName;\r
- if (!file_exists($baseDocument)) {\r
- return;\r
- }\r
- $destDir = WS_CACHE . '/exportpdf/' . $book->cid;\r
- if (!file_exists($destDir)) {\r
- mkdir($destDir, 0777, true);\r
- }\r
- $fname = md5(implode(',%ù', $range)) . '.pdf';\r
- $destFile = $destDir . '/' . $fname;\r
- $destURL = '/fluidbook/cache/exportpdf/' . $book->cid . '/' . $fname;\r
- // If result exists, don't make the pdf again\r
- if (file_exists($destFile) && filemtime($destFile) > filemtime($baseDocument)) {\r
- \r
- } else {\r
- // Prepare the command line\r
- $l = array('A=' . $baseDocument, 'cat');\r
- foreach ($range as $page) {\r
- if ($page < 1 || $page > $book->parametres->pages) {\r
- continue;\r
- }\r
- $l[] = 'A' . $page;\r
- }\r
- $l[] = 'output';\r
- $l[] = $destFile;\r
-\r
- $args = implode(' ', $l);\r
- // Execute the command line\r
- $pdftk = new cubeCommandLine('pdftk');\r
- $pdftk->setPath(CONVERTER_PATH);\r
- $pdftk->setManualArg($args);\r
- $pdftk->execute();\r
- }\r
-\r
- return array('url' => $destURL, 'file' => $destFile);\r
- }\r
-\r
- public function e() {\r
- $this->args['cid'] = $this->callArgs[0];\r
- $this->args['range'] = $this->callArgs[1];\r
- return $this->exportpdf();\r
- }\r
-\r
- public function p() {\r
- $this->args['cid'] = $this->callArgs[0];\r
- $this->args['range'] = $this->callArgs[1];\r
- return $this->exportpdf(true);\r
- }\r
-\r
- public function exportpdf($print = false) {\r
- global $core;\r
-\r
- $dao = new wsDAOBook($core->con);\r
- if (isset($this->args['cid'])) {\r
- $book = $dao->selectByCid($this->args['cid']);\r
- } else if ($this->args['id'] < 11202) {\r
- $book = $dao->selectById($this->args['id']);\r
- }\r
-\r
- $dest = $this->getPDFComplex($book, $this->args['range']);\r
-\r
- if (!$print) {\r
- // Return the url of the resulting pdf\r
- http::redirect($dest['url']);\r
- exit;\r
- } else {\r
- $this->outputXML = false;\r
- $res = '<!DOCTYPE html><html><head>\r
- <meta http-equiv="X-UA-Compatible" content="IE=8" /> \r
- <script type="text/javascript" src="http://code.jquery.com/jquery-1.8.2.min.js"></script>\r
- <script type="text/javascript" src="/js/pdfprint.js"></script>\r
- <link rel="stylesheet" type="text/css" href="/style/ws/printpdf.css" />\r
- </head>\r
- <body>\r
- <iframe id="pdf" name="pdff" src="' . $dest['url'] . '" width="100%" height="100%"></iframe>\r
- </body>\r
- </html>';\r
- ob_end_clean();\r
- echo $res;\r
- exit;\r
- }\r
- }\r
-\r
- public function bulle() {\r
- global $core;\r
- $e = explode('-', $this->args['catalogue'], 2);\r
- if (count($e) == 2) {\r
- $catalogue = $e[1];\r
- } else {\r
- $catalogue = $e[0];\r
- }\r
-\r
- $c = $core->con->openCursor('bulle');\r
- $c->prenom = trim($this->args['prenom']);\r
- $c->nom = trim($this->args['nom']);\r
- $c->catalogue = trim($catalogue);\r
- $c->email = trim($this->args['email']);\r
- $c->date = TIME;\r
- $c->insert();\r
- }\r
-\r
- public function getBulleList() {\r
- $user = 'bulle';\r
- $pass = '23bu1l300';\r
- $this->outputXML = false;\r
- $ok = (isset($_SERVER['PHP_AUTH_USER']) && $_SERVER['PHP_AUTH_USER'] == $user && isset($_SERVER['PHP_AUTH_PW']) && $_SERVER['PHP_AUTH_PW'] == $pass);\r
- if (!$ok) {\r
- header('WWW-Authenticate: Basic realm="Protected access"');\r
- header('HTTP/1.0 401 Unauthorized');\r
- ob_end_clean();\r
- header('Content-type: text/html');\r
- echo '<h1>Forbidden</h1>';\r
- exit;\r
- } else {\r
- global $core;\r
- header('Content-type: text/csv');\r
- header('Content-Disposition: attachment; filename="inscriptions.csv"');\r
- $r = $core->con->select('SELECT * FROM bulle ORDER BY date');\r
- ob_end_clean();\r
- echo utf8_decode('"Prénom";"Nom";"E-mail";"Catalogue";"Date"') . "\n";\r
- while ($r->fetch()) {\r
- echo utf8_decode('"' . $r->prenom . '";"' . $r->nom . '";"' . $r->email . '";"' . $r->catalogue . '";"' . date('Y-m-d H:i', $r->date) . '"') . "\n";\r
- }\r
- exit;\r
- }\r
- }\r
-\r
- public function grdfValidForm() {\r
- $notempty = array('civilite', 'prenom', 'nom', 'adresse', 'codepostal', 'ville', 'telephone', 'optin', 'connu', 'energie');\r
- $error = false;\r
- $errors = array();\r
- foreach ($notempty as $f) {\r
- if (!isset($this->args[$f]) || is_null($this->args[$f]) || $this->args[$f] == 'null' || trim($this->args[$f]) == '') {\r
- $error = true;\r
- $errors[] = $f;\r
- }\r
- }\r
-\r
- /* if (!cubeMail::isEmail($this->args['email'])) {\r
- $error = true;\r
- $errors[] = 'email_valid';\r
- } */\r
-\r
- $this->xml->addChild('ok', $error ? '0' : '1');\r
- $this->xml->addChild('errors', implode(',', $errors));\r
- }\r
-\r
- public function grdfSendForm() {\r
- global $core;\r
-\r
- $fields = array('Civilité' => 'civilite', 'Prénom' => 'prenom', 'Nom' => 'nom',\r
- 'E-mail' => 'email', 'Adresse' => 'adresse', 'Code postal' => 'codepostal', 'Ville' => 'ville',\r
- 'Téléphone' => 'telephone', 'Connu par' => 'connu', 'Energie' => 'energie',\r
- 'Optin' => 'optin', 'Coupons sélectionnés' => 'reflist');\r
-\r
- $mail = new cubeMail();\r
- $mail->charset = 'UTF-8';\r
- $mail->subject = '[Chéquier avantages] Validation de coupon';\r
- $mail->from = 'noreply@chequieravantages.fr';\r
- $mail->replyTo = 'noreply@chequiavantages.fr';\r
- $mail->to = 'projetrenogaz@grdf.fr';\r
- $mail->bcc = 'test@cubedesigners.com';\r
- $body = '';\r
-\r
- foreach ($fields as $k => $f) {\r
- $body.=$k . ' : ' . $this->args[$f] . "\r\n";\r
- $datas[$f] = $this->args[$f];\r
- }\r
- $datas['date'] = TIME;\r
-\r
- $c = $core->con->openCursor('grdf2013');\r
- $c->datas = json_encode($datas);\r
- $c->insert();\r
-\r
- $mail->body = $body;\r
- $mail->send();\r
- }\r
-\r
- public function grdfCoupon() {\r
- $this->outputXML = false;\r
- $couponsRoot = WS_BOOKS . '/working/11222/commerce/';\r
-\r
- $xml = simplexml_load_file($couponsRoot . 'references.xml');\r
- // Check hash\r
- $hash = md5('ae' . $_GET['nom'] . '25' . $_GET['ref']);\r
- if ($hash != $_GET['h']) {\r
- exit;\r
- }\r
- $refs = explode(',', $_GET['ref']);\r
- $pdf = new FPDI();\r
- foreach ($refs as $ref) {\r
-\r
- foreach ($xml->xpath('//item[@reference=\'' . $ref . '\']') as $item) {\r
- $code = (string) $item['code'];\r
- }\r
-\r
- $file = $couponsRoot . $ref . '.pdf';\r
-\r
- $pdf->setSourceFile($file);\r
- $idx = $pdf->importPage(1);\r
- $pdf->AddPage();\r
- $pdf->useTemplate($idx);\r
- $pdf->SetXY(11, 12);\r
- $pdf->SetFont('Helvetica', '', 12);\r
- $pdf->SetTextColor(0, 0, 0);\r
- $pdf->Cell(180, 10, utf8_decode(trim($_GET['civilite'] . ' ' . $_GET['prenom'] . ' ' . $_GET['nom']) . ','));\r
- $pdf->SetXY(143, 203);\r
- $pdf->SetFont('Helvetica', 'B', 18);\r
- $pdf->Cell(33, 15, $code);\r
- }\r
- $pdf->Output('coupon.pdf', 'I');\r
- }\r
-\r
- public function grdfExcel12568() {\r
- global $core;\r
- $this->outputXML = false;\r
-\r
-\r
- $couponsRoot = WS_BOOKS . '/working/11222/commerce/';\r
-\r
- $xml = simplexml_load_file($couponsRoot . 'references.xml');\r
-\r
- $cols = array('Date' => 'date', 'Civilité' => 'civilite', 'Prénom' => 'prenom', 'Nom' => 'nom',\r
- 'E-mail' => 'email', 'Adresse' => 'adresse', 'Code postal' => 'codepostal', 'Ville' => 'ville',\r
- 'Téléphone' => 'telephone', 'Connu par' => 'connu', 'Energie' => 'energie',\r
- 'Optin' => 'optin');\r
- $refs = array();\r
- foreach ($xml->xpath('//item') as $i) {\r
- $refs[(string) $i['reference']] = $i['name'];\r
- }\r
-\r
- // \r
- $h = '<table>';\r
- $h.='<tr>';\r
- foreach ($cols as $l => $k) {\r
- $h.='<th>' . utf8_decode($l) . '</th>';\r
- }\r
- foreach ($refs as $k => $l) {\r
- $h.='<th>' . utf8_decode($l) . '</th>';\r
- }\r
- $h.='</tr>';\r
-\r
- $r = $core->con->select('SELECT * FROM grdf2013');\r
- while ($r->fetch()) {\r
- $d = json_decode($r->datas);\r
- $rl = explode(',', $d->reflist);\r
- $h.='<tr>';\r
- foreach ($cols as $l => $k) {\r
- $v = $d->$k;\r
- if ($k == 'date') {\r
- $v = date('Y-m-d H:i', $v);\r
- }\r
- $h.='<td>' . utf8_decode($v) . '</td>';\r
- }\r
- foreach ($refs as $k => $l) {\r
- $v = in_array($k, $rl) ? '1' : '0';\r
- $h.='<td>' . utf8_decode($v) . '</td>';\r
- }\r
- $h.='</tr>';\r
- }\r
-\r
- $h.='</table>';\r
-\r
- if (!file_exists(ROOT . '/cache/12568/')) {\r
- mkdir(ROOT . '/cache/12568/', 0777, true);\r
- }\r
- file_put_contents(ROOT . '/cache/12568/chequieravantage.xls', $h);\r
- http::redirect('/cache/12568/chequieravantage.xls');\r
- exit;\r
- }\r
-\r
- public function proxy() {\r
- ob_end_clean();\r
- fb(netHttp::quickGet($_GET['u'], 'php://output'));\r
- $this->outputXML = false;\r
- }\r
-\r
- public function wescoRef() {\r
- global $core;\r
-\r
- $ref = ltrim(substr($this->args['ref'], 4), '0');\r
-\r
- $r = $core->con->select('SELECT url FROM wescoref WHERE ref="' . $core->con->escape($ref) . '"');\r
- if ($r->count()) {\r
- header('Location: ' . $r->url);\r
- exit;\r
- }\r
- $cache = ROOT . '/cache/wesco/' . $this->args['ref'];\r
- if (file_exists($cache)) {\r
- header('Location: ' . file_get_contents($cache));\r
- exit;\r
- }\r
- $url = 'http://www.wesco-eshop.fr/catalogsearch/result/?q=' . $ref;\r
- $doc = new DOMDocument();\r
- $doc->loadHTML(file_get_contents($url));\r
- $x = simplexml_import_dom($doc);\r
- $xpath = $x->xpath('//a[@class="product-image"]');\r
- if (count($xpath) > 0) {\r
- $r = $xpath[0]['href'];\r
- file_put_contents($cache, $r);\r
- header('Location: ' . $r);\r
- exit;\r
- }\r
- header('Location: http://www.wesco-eshop.fr');\r
- }\r
-\r
- public function flfRef() {\r
- global $core;\r
-\r
- $r = $core->con->select('SELECT url FROM flfref WHERE ref="' . $core->con->escape($this->args['ref']) . '"');\r
- if ($r->count()) {\r
- header('Location: http://www.flf.fr' . $r->url);\r
- exit;\r
- }\r
- }\r
-\r
- public function collection() {\r
- global $core;\r
- $id = $this->callArgs[0];\r
- $os = $this->callArgs[1];\r
- $resolution = $this->callArgs[2];\r
- $local = (isset($this->callArgs[3])) ? $this->callArgs[3] : null;\r
-\r
- if ($id == 4) {\r
- $resolution = 150;\r
- }\r
-\r
- $this->outputXML = false;\r
- header('Content-type: application/json');\r
-\r
- $cache = WS_COLLECTIONS . '/ws/' . $id . '.' . $os . '.' . $resolution . '.json';\r
- $update = WS_COLLECTIONS . '/ws/' . $id . '.' . $os . '.' . $resolution . '.update';\r
-\r
- if (file_exists($update) && filemtime(__FILE__) > filemtime($update)) {\r
- unlink($update);\r
- }\r
-\r
- if (!is_null($local) && file_exists($update) && file_get_contents($update) == $local) {\r
- echo 'false';\r
- exit;\r
- }\r
-\r
- $limit = TIME - 72000;\r
- if (!file_exists($cache) || !file_exists($update) || filemtime($cache) < $limit) {\r
- $r = $core->con->select('SELECT * FROM book_collection_compile WHERE online_' . $os . '=1 AND collection_id=\'' . $core->con->escape($id) . '\'');\r
- $r->fetch();\r
- $version = $r->compile_date;\r
-\r
- $daoCollection = new wsDAOCollection($core->con);\r
- $collection = $daoCollection->selectById($id);\r
-\r
- $ns = $collection->settings['namespace'];\r
-\r
-\r
- $vcompo = WS_COLLECTIONS . '/versions/' . $id . '/' . $version . '/composition.json';\r
- $composition = json_decode(file_get_contents($vcompo));\r
-\r
- $couvertures = array();\r
- $vroot = WS_COLLECTIONS . '/versions/' . $id . '/' . $version . '/' . $os . '/';\r
-\r
- $publications = array();\r
- $langs = array();\r
-\r
- foreach ($composition as $k => $g) {\r
- foreach ($g->publications as $l => $p) {\r
- $publications[] = $p->id;\r
- }\r
- }\r
-\r
- $daoBook = new wsDAOBook($core->con);\r
- $books = $daoBook->selectByIds($publications);\r
-\r
- $langsnames = array();\r
- foreach ($composition as $k => $g) {\r
- foreach ($g->publications as $l => $p) {\r
- $book = $books[$p->id];\r
- $root = WS_COLLECTIONS . '/versions/' . $id . '/' . $version . '/' . $os . '/' . $p->id;\r
- $couv = $root . '/cover.jpg';\r
- $couvertures[$p->id] = base64_encode(file_get_contents($couv));\r
- $composition[$k]->publications[$l]->width = $book->parametres->width;\r
- $composition[$k]->publications[$l]->height = $book->parametres->height;\r
- $composition[$k]->publications[$l]->lang = $book->lang;\r
- $langs[] = $book->lang;\r
- }\r
- }\r
-\r
- $langs = array_unique($langs);\r
-\r
- $w2h = new wiki2xhtml();\r
- $w2h->setOpt('active_pre', 0);\r
-\r
- $contents = $collection->contents;\r
- foreach ($langs as $lang) {\r
- $langsnames[$lang] = cubeLang::getNameByCode($lang);\r
- $contents[$lang]['apropos'] = $w2h->transform($contents[$lang]['apropos']);\r
- }\r
-\r
-\r
- $traductions = array();\r
- $r = $core->con->select('SELECT traductions,lang_id FROM langues WHERE lang_id IN(\'' . implode('\',\'', $langs) . '\')');\r
- while ($r->fetch()) {\r
- $traductions[$r->lang_id] = json_decode($r->traductions);\r
- }\r
-\r
- $d = array('id' => $id, 'res' => $resolution, 'ns' => $ns, 'langs' => $langs, 'langnames' => $langsnames, 'time' => $version, 'datas' => $composition, 'couvertures' => $couvertures, 'traductions' => $traductions, 'contents' => $contents);\r
- $d = array_merge($d, $this->_getManifest($publications, '/fluidbook/collections/versions/' . $id . '/' . $version . '/' . $os, $books, $resolution));\r
-\r
- $dao = new wsDAOCollection($core->con);\r
- $col = $dao->selectById($id);\r
-\r
- $json = json_encode($d);\r
- file_put_contents($cache, $json);\r
- file_put_contents($update, $version);\r
- } else {\r
- $d = json_decode(file_get_contents($cache), true);\r
- }\r
-\r
- $force = false;\r
- if (!is_null($local)) {\r
- $lcompo = WS_COLLECTIONS . '/versions/' . $id . '/' . $local . '/composition.json';\r
- if (!file_exists($lcompo)) {\r
- $force = true;\r
- }\r
- }\r
-\r
- $d['forceUpdate'] = $force;\r
- echo json_encode($d);\r
- exit;\r
- }\r
-\r
- protected function _getManifest($publications, $dir, $books, $resolution) {\r
- global $core;\r
- $res = array();\r
- $res['manifest'] = array('assetRoot' => 'http://workshop.fluidbook.com' . $dir . '/', 'autoDownload' => false);\r
- $res['manifestPub'] = array();\r
-\r
- $bundles = array();\r
-\r
- $removeFromRelative = realpath(ROOT . '/' . $dir) . '/';\r
- $daoTheme = new wsDAOTheme($core->con);\r
-\r
- foreach ($publications as $p) {\r
- $res['manifestPub'][$p] = array('assetRoot' => 'http://workshop.fluidbook.com' . $dir . '/', 'autoDownload' => true);\r
-\r
- $r = $p . '/';\r
- $iterator = CubeIT_Files::getRecursiveDirectoryIterator(ROOT . $dir . '/' . $p);\r
- $book = $books[$p];\r
- $reso = $resolution;\r
-\r
- $theme = $daoTheme->selectById($book->theme);\r
- $orders = $this->_getBundles($book);\r
- $regexp = $this->_getRegExpManifest($r, $book, $theme, $reso);\r
- $reg = $regexp['reg'];\r
- $exclude = $regexp['exclude'];\r
-\r
- $b = array();\r
-\r
- foreach ($iterator as $k => $f) {\r
- if ($f->isDir()) {\r
- continue;\r
- }\r
- $path = str_replace($removeFromRelative, '', $k);\r
-\r
- foreach ($exclude as $e) {\r
- if (preg_match('|' . $e . '|', $path)) {\r
- continue 2;\r
- }\r
- }\r
-\r
- $order = $this->_inFirstManifest($path, $orders, $reg);\r
-\r
- if (!isset($b[$order])) {\r
- $b[$order] = array();\r
- }\r
-\r
- $b[$order][] = $path;\r
- }\r
-\r
- $bundles[] = array('name' => 'p_' . $p, 'contents' => $b['loading']);\r
- $res['manifestPub'][$p]['bundles'] = array();\r
-\r
- foreach ($b as $name => $contents) {\r
- if ($name == 'loading') {\r
- continue;\r
- }\r
- $k = array_search($name, $orders);\r
- $res['manifestPub'][$p]['bundles'][$k] = array('name' => $name, 'contents' => $contents);\r
- }\r
- ksort($res['manifestPub'][$p]['bundles']);\r
- $res['manifestPub'][$p]['bundles'] = array_values($res['manifestPub'][$p]['bundles']);\r
- }\r
-\r
- $res['manifest']['bundles'] = $bundles;\r
- return $res;\r
- }\r
-\r
- protected function _getRegExpManifest($r, $book, $theme, $resolution) {\r
- $reg = array();\r
- $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/(.*)$');\r
- $reg['extras'] = array('^' . $r . 'data/links/(.*).mp4$', '^' . $r . 'data/links/(.*).ogv$', '^' . $r . 'data/links/(.*).webm$', '^' . $r . 'data/(.*).pdf$', '^' . $r . 'cover.jpg$');\r
- $reg['thumbnails'] = array('^' . $r . 'data/thumbnails/p(\d+).jpg$');\r
- for ($i = 1; $i <= $book->parametres->pages; $i++) {\r
- $var = 'content_' . $i;\r
- $reg[$var] = array('^' . $r . 'data/background/\d+/t' . $i . '.jpg$', '^' . $r . 'data/contents/p' . $i . '.svg$');\r
- }\r
- $reg['urgents'] = array('^' . $r . 'images/(.*)$', '^' . $r . 'data/images/(.*)$', '^' . $r . 'data/links/(.*).jpg$', '^' . $r . 'data/links/(.*).png$');\r
- $reg['loading'] = array_merge($reg['loading'], $reg['urgents']);\r
-\r
-\r
- $exclude = array();\r
- if ($resolution == 150) {\r
- $er = 300;\r
- } else {\r
- $er = 150;\r
- }\r
- $exclude[] = '^' . $r . 'data/background/' . $er . '/t\d+.jpg$';\r
- return array('reg' => $reg, 'exclude' => $exclude);\r
- }\r
-\r
- protected function _inFirstManifest($p, $orders, $reg) {\r
- foreach ($orders as $list) {\r
- foreach ($reg[$list] as $v) {\r
- if (preg_match('|' . $v . '|', $p)) {\r
- return $list;\r
- }\r
- }\r
- }\r
- return $list;\r
- }\r
-\r
- protected function _getBundles($book) {\r
- $res = array(0 => 'loading', 20001 => 'extras', 20000 => 'thumbnails', 1 => 'urgents');\r
- for ($i = 1; $i <= $book->parametres->pages; $i++) {\r
- $k = 2 + $i;\r
- $res[$k] = 'content_' . $i;\r
- }\r
- return $res;\r
- }\r
-\r
- public function collectionPushRegister() {\r
- global $core;\r
-\r
- $c = $core->con->openCursor('book_collection_push');\r
- $c->collection_id = $_POST['id'];\r
- $c->token = $_POST['token'];\r
- $c->datas = $_POST['datas'];\r
- $c->platform = $_POST['platform'];\r
- $c->locale = $_POST['locale'];\r
- $c->last_visit = TIME;\r
- try {\r
- $c->insert();\r
- } catch (Exception $e) {\r
- $c->update('WHERE collection_id=\'' . $core->con->escape($_POST['id']) . '\' AND token=\'' . $core->con->escape($_POST['token']) . '\'');\r
- }\r
- }\r
-\r
-}\r
-\r
+<?php
+
+class wsServices extends cubeFlashGateway {
+
+ const CNAME = __CLASS__;
+
+ public static function in($args) {
+ global $core;
+ $args = cubePage::getArgs($args);
+ $n = self::CNAME;
+ $gateway = new $n($core->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 = '<!DOCTYPE html><html><head>
+ <meta http-equiv="X-UA-Compatible" content="IE=8" />
+ <script type="text/javascript" src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
+ <script type="text/javascript" src="/js/pdfprint.js"></script>
+ <link rel="stylesheet" type="text/css" href="/style/ws/printpdf.css" />
+ </head>
+ <body>
+ <iframe id="pdf" name="pdff" src="' . $dest['url'] . '" width="100%" height="100%"></iframe>
+ </body>
+ </html>';
+ 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 '<h1>Forbidden</h1>';
+ 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 = '<table>';
+ $h.='<tr>';
+ foreach ($cols as $l => $k) {
+ $h.='<th>' . utf8_decode($l) . '</th>';
+ }
+ foreach ($refs as $k => $l) {
+ $h.='<th>' . utf8_decode($l) . '</th>';
+ }
+ $h.='</tr>';
+
+ $r = $core->con->select('SELECT * FROM grdf' . $annee);
+ while ($r->fetch()) {
+ $d = json_decode($r->datas);
+ $rl = explode(',', $d->reflist);
+ $h.='<tr>';
+ foreach ($cols as $l => $k) {
+ $v = $d->$k;
+ if ($k == 'date') {
+ $v = date('Y-m-d H:i', $v);
+ }
+ $h.='<td>' . utf8_decode($v) . '</td>';
+ }
+ foreach ($refs as $k => $l) {
+ $v = in_array($k, $rl) ? '1' : '0';
+ $h.='<td>' . utf8_decode($v) . '</td>';
+ }
+ $h.='</tr>';
+ }
+
+ $h.='</table>';
+
+ 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
-<?php\r
-\r
-class wsDAOBook extends commonDAO {\r
-\r
- /**\r
- * wsDAOBook::singleton()\r
- *\r
- * @param mixed $r\r
- * @return\r
- */\r
- protected function singleton($r) {\r
- $book = new wsBook();\r
- $book->book_id = $r->book_id;\r
- $book->cid = $r->cid;\r
- $book->nom = $r->nom;\r
- $book->lang = $r->lang;\r
- $book->theme = $r->theme;\r
- $book->proprietaire = $r->proprietaire_nom;\r
- $book->proprietaire_id = $r->proprietaire_id;\r
- $book->proprietaire_utilisateur = $r->proprietaire_utilisateur;\r
- $book->hash = $r->hash;\r
- $book->compteur_visites = $r->compteur_visites;\r
- $book->status = $r->status;\r
- $book->date_status = $r->date_status;\r
- $book->date = $r->date;\r
- $book->pages = array();\r
- $book->chapters = $r->chapters;\r
- $book->traductions = $r->traductions;\r
- $book->specialLinks = $r->specialLinks;\r
- $book->specialRulers = $r->specialRulers;\r
- $book->parametres = $r->parametres;\r
- $book->extras = $r->extras;\r
- $book->numerotation = $r->numerotation;\r
- $book->changedate = $r->changedate;\r
- $book->compiledate = $r->compiledate;\r
- $book->compile1date = $r->compile1date;\r
- $book->compilehtml5date = $r->compilehtml5date;\r
- $book->facturable = $r->facturable;\r
- $book->facturable_id = $r->facturable_id;\r
- $book->tache = $r->tache;\r
- if (isset($r->projet)) {\r
- $book->projet = $r->projet;\r
- }\r
- $book->version = $r->version;\r
- $book->composition_update = $r->composition_update;\r
- $book->dir_references = $r->dir_references;\r
- $book->dir_hosting = $r->dir_hosting;\r
- $book->dir_macbook_phonegap_ios = $r->dir_macbook_phonegap_ios;\r
- $book->dir_phonegap_android = $r->dir_phonegap_android;\r
- $book->dir_external = $r->dir_external;\r
- $book->demo_counter = $r->demo_counter;\r
- $book->exportdatas = $r->exportdatas;\r
-\r
- return $book;\r
- }\r
-\r
- protected function cree($r) {\r
- $book = new wsBook();\r
- $book->book_id = 'new';\r
- $book->nom = '';\r
- $book->cid = null;\r
- $book->lang = 'fr';\r
- $book->theme = 1;\r
- $book->proprietaire = '';\r
- $book->proprietaire_id = 0;\r
- $book->hash = '';\r
- $book->compteur_visites = 20;\r
- $book->status = 0;\r
- $book->date_status = TIME;\r
- $book->date = TIME;\r
- $book->composition_update = TIME;\r
- $book->chapters = json_encode(array());\r
- $book->parametres = new wsBookParametres();\r
- $book->tache = 0;\r
- $book->pages = array();\r
- $book->version = 2;\r
- return $book;\r
- }\r
-\r
- protected function getNextId() {\r
- $r = $this->con->select('SELECT MAX(book_id) AS book_id FROM books');\r
- if ($r->book_id < 10000) {\r
- return 10000;\r
- }\r
- return $r->book_id + 1;\r
- }\r
-\r
- public function saveExportDatas($book_id, $datas) {\r
- $c = $this->con->openCursor('books');\r
- $c->exportdatas = json_encode($datas);\r
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');\r
- }\r
-\r
- public function addDemoCount($book_id) {\r
-\r
- $r = $this->con->select('SELECT demo_counter,nom FROM books WHERE book_id=\'' . $book_id . '\'');\r
- $m = 20;\r
- if ($r->demo_counter > 0 && $r->demo_counter % $m == 0) {\r
- $mail = new cubeMail();\r
- $mail->charset = 'UTF-8';\r
- $mail->from = 'contact@fluidbook.com';\r
- $mail->to = 'tech@fluidbook.com';\r
- $mail->subject = '[Fluidbook Workshop] Fluidbook consulté via l\'url publique';\r
- $mail->body = 'Le fluidbook suivant a été consulté ' . $m . ' fois (et ' . $r->demo_counter . ' au total) via l\'url publique : ' . "\r\n" .\r
- 'Fluidbook # ' . $book_id . ' - ' . $r->nom;\r
- $mail->send();\r
- }\r
-\r
- $this->con->select('UPDATE books SET demo_counter=demo_counter+1 WHERE book_id=\'' . $book_id . '\'');\r
- }\r
-\r
- public function selectByIds($book_ids = array(), $simple = false) {\r
- if ($simple) {\r
- $table = 'books';\r
- } else {\r
- $table = 'books_vue';\r
- }\r
- $sql = 'SELECT * FROM ' . $table . ' WHERE book_id IN (' . implode(',', $book_ids) . ')';\r
- $books = $this->factory($this->con->select($sql));\r
- $res = array();\r
- foreach ($books as $book) {\r
- $res[$book->book_id] = $book;\r
- }\r
- return $res;\r
- }\r
-\r
- public function selectById($book_id = null, $simple = false) {\r
- if (is_null($book_id)) {\r
- return $this->cree();\r
- }\r
- if ($simple) {\r
- $table = 'books';\r
- } else {\r
- $table = 'books_vue';\r
- }\r
- $sql = 'SELECT * FROM ' . $table . ' WHERE book_id=\'' . $this->con->escape($book_id) . '\' LIMIT 1';\r
- $r = $this->con->select($sql);\r
- return $this->singleton($r);\r
- }\r
-\r
- public function selectByCid($cid = null, $simple = false) {\r
- if ($simple) {\r
- $table = 'books';\r
- } else {\r
- $table = 'books_vue';\r
- }\r
-\r
- $sql = 'SELECT * FROM ' . $table . ' WHERE cid LIKE BINARY \'' . $this->con->escape($cid) . '\' LIMIT 1';\r
- $r = $this->con->select($sql);\r
- return $this->singleton($r);\r
- }\r
-\r
- public function selectLuceneToDo() {\r
- $sql = 'SELECT * FROM books_vue WHERE lucene_time<composition_update AND version=2 ORDER BY book_id ASC LIMIT 1';\r
- $r = $this->con->select($sql);\r
- return $this->factory($r);\r
- }\r
-\r
- public function selectLuceneTimeNotSet() {\r
- $sql = 'SELECT * FROM books_vue WHERE lucene_time=0 AND version=2';\r
- $r = $this->con->select($sql);\r
- return $this->factory($r);\r
- }\r
-\r
- /**\r
- * wsDAOBook::sauve()\r
- *\r
- * @param mixed $createur\r
- * @param mixed $data\r
- * @return\r
- */\r
- public function sauve($createur, $data) {\r
- $c = $this->con->openCursor('books');\r
- if (isset($data['nom'])) {\r
- $c->nom = $data['nom'];\r
- }\r
- if (isset($data['lang'])) {\r
- $c->lang = $data['lang'];\r
- }\r
- if (isset($data['theme'])) {\r
- $c->theme = $data['theme'];\r
- }\r
- if (isset($data['proprietaire'])) {\r
- $c->proprietaire = $data['proprietaire'];\r
- }\r
-\r
- if ($data['book_id'] == 'new' || $data['book_id'] == '') {\r
- $c->date = TIME;\r
- $c->hash = md5(rand(0, 123456789365469));\r
- $c->compteur_visites = 20;\r
- $c->parametres = serialize(new wsParametres());\r
- $c->changedate = TIME;\r
- $book_id = $c->book_id = $this->getNextId();\r
-\r
- $c->insert();\r
- } else {\r
- $c->changedate = TIME;\r
- $book_id = $data['book_id'];\r
- $c->update('WHERE book_id=\'' . $this->con->escape($data['book_id']) . '\'');\r
- }\r
-\r
- return $this->selectById($book_id);\r
- }\r
-\r
- public function duplicate($book_id, $createur, $nom, $pages = false) {\r
- $r = $this->con->select('SELECT * FROM books_vue WHERE book_id=\'' . $this->con->escape($book_id) . '\'');\r
-\r
- $old_id = $book_id;\r
-\r
- $parametres = unserialize($r->parametres);\r
- $parametres->setParent($this);\r
- $parametres->title = $nom;\r
-\r
- $c = $this->con->openCursor('books');\r
- $c->proprietaire = $createur;\r
- $c->date = TIME;\r
- $c->hash = md5(rand(0, 1234567893));\r
- $c->cid = $this->generateCID();\r
- $c->compteur_visites = 20;\r
- $c->status = -1;\r
- $c->date_status = TIME;\r
- $c->lang = $r->lang;\r
- $c->parametres = serialize($parametres);\r
- $c->nom = $nom;\r
- $c->theme = $r->theme;\r
- $c->changedate = TIME;\r
- $c->compiledate = 0;\r
- $c->version = 2;\r
- $c->traductions = $r->traductions;\r
- $c->specialLinks = $r->specialLinks;\r
- $c->specialRulers = $r->specialRulers;\r
- $c->composition_update = TIME;\r
- $book_id = $c->book_id = $this->getNextId();\r
- if ($pages) {\r
- $c->numerotation = $r->numerotation;\r
- $c->chapters = $r->chapters;\r
- $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);\r
- }\r
- $c->insert();\r
- $this->saveCompositionVersion($book_id);\r
-\r
- return $this->selectById($book_id);\r
- }\r
-\r
- public function creeEmpty($createur, $lang, $nom) {\r
- $c = $this->con->openCursor('books');\r
-\r
- $parametres = new wsBookParametres($this);\r
- $parametres->title = $nom;\r
-\r
- $c->proprietaire = $createur;\r
- $c->cid = $this->generateCID();\r
- $c->nom = $nom;\r
- $c->date = TIME;\r
- $c->hash = md5(rand(0, 1234567893));\r
- $c->compteur_visites = 20;\r
- $c->status = -1;\r
- $c->date_status = TIME;\r
- $c->parametres = serialize($parametres);\r
-\r
- $c->theme = 1;\r
- $c->lang = $lang;\r
- $c->changedate = TIME;\r
- $c->compiledate = 0;\r
- $c->version = 2;\r
- $c->composition_update = TIME;\r
- $book_id = $c->book_id = $this->getNextId();\r
- $c->insert();\r
- return $this->selectById($book_id);\r
- }\r
-\r
- public function supprime($book_id) {\r
- $this->con->execute('DELETE FROM book_pages WHERE book_id=\'' . $this->con->escape($book_id) . '\'');\r
- return $this->con->execute('DELETE FROM books WHERE book_id=\'' . $this->con->escape($book_id) . '\'');\r
- }\r
-\r
- public function count($limitedToUserRights = false) {\r
- $filters = $this->makeWhereFromFiltres();\r
- if ($filters == '1=1') {\r
- $table = 'books';\r
- } else {\r
- $table = 'books_vue';\r
- }\r
-\r
- $where = '(' . $filters . ')';\r
- $where .= $this->limitToUserRights($limitedToUserRights);\r
- $r = $this->con->select('SELECT COUNT(*) AS nb FROM ' . $table . ' WHERE ' . $where);\r
- return $r->nb;\r
- }\r
-\r
- public function getPagesOfBookAt($book_id, $time) {\r
- $r = $this->con->select('SELECT * FROM book_pages_versions WHERE book_id=\'' . $this->con->escape($book_id) . '\' ORDER BY `update`');\r
- if (!$r->count()) {\r
- return $this->getPagesOfBook($book_id);\r
- }\r
- if ($r->count() == 1) {\r
- $pages = unserialize($r->composition);\r
- if (!count($pages)) {\r
- return $this->getPagesOfBook($book_id);\r
- }\r
- return $pages;\r
- }\r
- $pages = null;\r
- while ($r->fetch()) {\r
- if ($r->update > $time) {\r
- if (is_null($pages)) {\r
- return $this->getPagesOfBook($book_id);\r
- }\r
- return unserialize($pages);\r
- }\r
- $pages = $r->composition;\r
- }\r
- return unserialize($pages);\r
- }\r
-\r
- public function getDocumentsToUpdate($book_id) {\r
- $res = array();\r
- $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');\r
- while ($r->fetch()) {\r
- $res[] = $r->document_id;\r
- }\r
- return $res;\r
- }\r
-\r
- public function getPagesOfBook($book_id, $conversion = true) {\r
- $pages = array();\r
-\r
- $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
-\r
- $r = $this->con->select($sql);\r
- while ($r->fetch()) {\r
- $n = explode(',', $r->num);\r
-\r
- if (isset($n[$r->document_page - 1])) {\r
- $num = $n[$r->document_page - 1];\r
- } else {\r
- $num = '';\r
- }\r
- $pages[$r->book_page] = array('document_id' => $r->document_id,\r
- 'document_page' => $r->document_page,\r
- 'version' => $r->version,\r
- 'defaultNum' => $num,\r
- 'nb_pages' => $r->doc_pages\r
- );\r
-\r
- if ($conversion) {\r
- if ($r->conversion != '') {\r
- $c = unserialize($r->conversion);\r
- $c = $c->pages[$r->document_page];\r
- }\r
- $qp = array('resolution', 'method', 'quality', 'objects');\r
- foreach ($qp as $p) {\r
- if (isset($c) && isset($c->$p)) {\r
- $pages[$r->book_page][$p] = $c->$p;\r
- }\r
- }\r
- }\r
- }\r
- return $pages;\r
- }\r
-\r
- public function appendDocument($book_id, $document_id) {\r
- $r = $this->con->select('SELECT MAX(book_page) AS book_page FROM book_pages WHERE book_id=\'' . $this->con->escape($book_id) . '\'');\r
- $lastPage = is_null($r->book_page) ? 0 : $r->book_page;\r
- $this->insertDocument($book_id, $lastPage, $document_id);\r
- }\r
-\r
- public function removePage($book_id, $book_page) {\r
- // Supprime la page\r
- $this->con->execute('DELETE FROM book_pages WHERE book_page=\'' . $this->con->escape($book_page) . '\' AND book_id=\'' . $this->con->escape($book_id) . '\'');\r
- // Décale les pages suivantes vers le haut\r
- $this->decalePages($book_id, $book_page, -1);\r
- }\r
-\r
- public function insertPage($book_id, $after_page, $document_id, $document_page) {\r
- // Décale les pages vers le bas\r
- $this->decalePages($book_id, $after_page, 1);\r
- // Insère la page\r
- $c = $this->con->openCursor('book_pages');\r
- $c->book_id = $book_id;\r
- $c->book_page = $after_page + 1;\r
- $c->document_id = $document_id;\r
- $c->document_page = $document_page;\r
- $c->insert();\r
- }\r
-\r
- public function insertDocument($book_id, $after_page, $document_id) {\r
- // Obtiens le book\r
- $book = $this->selectById($book_id);\r
- $num = explode(',', $book->numerotation);\r
- // Obtiens le nombre de pages\r
- $r = $this->con->select('SELECT pages,numberSections FROM documents WHERE document_id=\'' . $this->con->escape($document_id) . '\'');\r
- // Décale les pages vers le bas\r
- if ($after_page > 0) {\r
- $this->decalePages($book_id, $after_page, $r->pages);\r
- }\r
- // Insère les pages\r
- $c = $this->con->openCursor('book_pages');\r
- $c->book_id = $book_id;\r
- $c->document_id = $document_id;\r
- for ($i = 1; $i <= $r->pages; $i++) {\r
- $c->document_page = $i;\r
- $c->book_page = $after_page + $i;\r
- $c->insert();\r
- }\r
- // Mets à jour la liste des numéros des pages\r
- $before = array_slice($num, 0, $after_page);\r
- $after = array_slice($num, $after_page, count($num) - $after_page);\r
-\r
- $newnum = $r->numberSections;\r
- if (trim($newnum, ',') == '') {\r
- // If no number detected, we create a numeric list from 1\r
- $between = range(1, $r->pages);\r
- } else {\r
- // Else, we use numbers detected at conversion\r
- $between = explode(',', $r->numberSections);\r
- }\r
- $num = array_merge($before, $between, $after);\r
- // Mets à jour la numerotation de la publication\r
- $c = $this->con->openCursor('books');\r
- $c->numerotation = implode(',', $num);\r
- $c->composition_update = TIME;\r
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');\r
-\r
- $this->saveCompositionVersion($book_id);\r
- }\r
-\r
- protected function decalePages($book_id, $after_page, $decalage) {\r
- $decalage = ($decalage >= 0) ? '+' . $decalage : $decalage;\r
- $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) . '\'');\r
- }\r
-\r
- public function getListe($orderby = null, $sens = null, $limit = null, $limitedToUserRights = false) {\r
- if (!is_null($this->q)) {\r
- $where = '(';\r
- if ($this->search_id) {\r
- $where .= ' book_id=\'' . $this->con->escape($this->q) . '\' OR ';\r
- }\r
-\r
- if (!cubeMath::is_int($this->q)) {\r
- $where .= 'nom LIKE \'%' . $this->con->escape($this->q) . '%\'';\r
- $daoClient = new commonDAOClient($this->con);\r
- $where .= ' OR proprietaire_id IN(' . $daoClient->querySearchByName($this->q) . ') OR ';\r
- }\r
- $limit = null;\r
- $where .= '1=2)';\r
- } else {\r
- $where = '(' . $this->makeWhereFromFiltres() . ')';\r
- }\r
- $where .= $this->limitToUserRights($limitedToUserRights);\r
-\r
- $orderby = is_null($orderby) ? 'book_id' : $orderby;\r
- $sens = is_null($sens) ? 'DESC' : $sens;\r
- $limit = is_null($limit) ? '' : $this->con->limit($limit);\r
-\r
- $sql = 'SELECT * FROM books_vue WHERE ' . $where . ' ORDER BY ' . $orderby . ' ' . $sens . ' ' . $limit;\r
- $r = $this->con->select($sql);\r
- return $this->factory($r);\r
- }\r
-\r
- protected function limitToUserRights($utilisateur) {\r
- if ($utilisateur) {\r
- if (wsDroits::admin()) {\r
- return '';\r
- }\r
- return ' AND proprietaire IN (' . $utilisateur->ws_rights . ')';\r
- }\r
- return '';\r
- }\r
-\r
- protected function makeWhereFromFiltres() {\r
- if (!is_null($this->filtres)) {\r
- $w = array('1=1');\r
- if (commonFiltre::test('admin_book', $this->filtres)) {\r
- $w[] = 'super_admin IN (' . implode(',', array_keys($this->filtres['admin_book'])) . ')';\r
- }\r
- if (commonFiltre::test('status_book', $this->filtres)) {\r
- $w[] = 'status IN(' . implode(',', array_keys($this->filtres['status_book'])) . ')';\r
- }\r
- if (commonFiltre::test('revendeur_book', $this->filtres)) {\r
- $v = array_keys($this->filtres['revendeur_book']);\r
- $values = array();\r
- foreach ($v as $r) {\r
- $values[] = $this->con->escape($r);\r
- }\r
-\r
-\r
- $w[] = 'facturable IN(\'' . implode('\',\'', $values) . '\')';\r
- }\r
- return implode(' AND ', $w);\r
- } else {\r
- return '1=1';\r
- }\r
- }\r
-\r
- public function setChapters($book_id, $json) {\r
- $chapters = json_decode($json, TRUE);\r
- $res = array();\r
-\r
- foreach ($chapters as $c) {\r
- $c['label'] = trim($c['label']);\r
- $n = (string) $c['page'];\r
- $c['label'] = trim(preg_replace('|\s+' . $n . '$|iu', '', $c['label']));\r
- $res[] = $c;\r
- }\r
-\r
- $c = $this->con->openCursor('books');\r
- $c->chapters = json_encode($res);\r
- $c->changedate = TIME;\r
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');\r
- }\r
-\r
- public function setSpecialLinksAndRulers($book_id, $links, $rulers) {\r
- $c1 = $this->con->openCursor('special_links_versions');\r
- $c = $this->con->openCursor('books');\r
-\r
- if (is_string($links)) {\r
- $links = json_encode(json_decode($links, false));\r
- }\r
- if (is_string($rulers)) {\r
- $rulers = json_encode(json_decode($rulers, false));\r
- }\r
-\r
- if (is_array($links)) {\r
- $links = json_encode($links);\r
- }\r
- if (is_array($rulers)) {\r
- $rulers = json_encode($rulers);\r
- }\r
-\r
-\r
-\r
- $c1->links = $c->specialLinks = $links;\r
- $c1->rulers = $c->specialRulers = $rulers;\r
- $c1->update = $c->changedate = TIME;\r
- $c1->book_id = $book_id;\r
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');\r
- try {\r
- $c1->insert();\r
- } catch (Exception $e) {\r
- $c1->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\' AND `update`=' . TIME);\r
- }\r
- }\r
-\r
- public function setTheme($book_id, $theme) {\r
- $c = $this->con->openCursor('books');\r
- $c->theme = $theme;\r
- $c->changedate = TIME;\r
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');\r
- }\r
-\r
- public function setStatus($book_id, $status) {\r
- $c = $this->con->openCursor('books');\r
- if ($status < 2) {\r
- $c->tache = 0;\r
- }\r
- $c->status = $status;\r
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');\r
- return $this->selectById($book_id);\r
- }\r
-\r
- public function setChaptersFromOldFluidbook($book_id) {\r
- $book = $this->selectById($book_id);\r
- $n = explode(',', $book->numerotation);\r
-\r
- $xml = simplexml_load_file('http://ws.fluidbook.com/books/' . $book_id . '/data/links.xml');\r
- $res = array();\r
- $chapters = $xml->xpath('//chapters');\r
- foreach ($chapters as $ch) {\r
- $c = array();\r
- $c['label'] = (string) $ch->txt;\r
-\r
- $p = intval((string) $ch->page);\r
- if ($p <= 0) {\r
- continue;\r
- }\r
- $c['page'] = $n[$p];\r
- $c['level'] = intval((string) $ch->level);\r
- $res[] = $c;\r
- }\r
-\r
- $c = $this->con->openCursor('books');\r
- $c->chapters = json_encode($res);\r
- $c->changedate = TIME;\r
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');\r
- }\r
-\r
- public function saveCompositionVersion($book_id, $time = null) {\r
-\r
- $time = is_null($time) ? TIME : $time;\r
-\r
- $pages = $this->getPagesOfBook($book_id);\r
-\r
- $c = $this->con->openCursor('book_pages_versions');\r
- $c->update = $time;\r
- $c->book_id = $book_id;\r
- $c->composition = serialize($pages);\r
- $c->insert();\r
- }\r
-\r
- public function setLang($book_id, $base, $traductions) {\r
- // Cleanup user translations\r
- $traductions = json_decode($traductions, true);\r
- foreach ($traductions as $k => $v) {\r
- $traductions[$k] = trim($v);\r
- }\r
-\r
- $daoLang = new wsDAOLang($this->con);\r
- $lang = $daoLang->selectById($base);\r
- // Cleanup base translations\r
- $baseTraductions = $lang->traductions;\r
- foreach ($baseTraductions as $k => $v) {\r
- $baseTraductions[$k] = trim($v);\r
- }\r
- // Then compare them. If there is no differences, we don't save translations in the book\r
- if ($traductions == $baseTraductions) {\r
- $t = '';\r
- } else {\r
- $t = json_encode($traductions);\r
- }\r
-\r
- $c = $this->con->openCursor('books');\r
- $c->lang = $base;\r
- $c->traductions = $t;\r
- $c->changedate = TIME;\r
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');\r
- }\r
-\r
- public function setSettings($book_id, $settings) {\r
- $book = $this->selectById($book_id);\r
- $parametres = $book->parametres;\r
- $new = $settings;\r
- foreach ($new as $k => $v) {\r
- if ($k == '_empty_') {\r
- continue;\r
- }\r
- $parametres->$k = $v;\r
- }\r
-\r
- $ip = array();\r
- if (isset($parametres->stats_exclude_ip) && trim($parametres->stats_exclude_ip) != '') {\r
- $list = $parametres->stats_exclude_ip;\r
- $list = str_replace("\r", "\n", $list);\r
- $e = explode("\n", $list);\r
- foreach ($e as $i) {\r
- $i = trim($i);\r
- if ($i == '') {\r
- continue;\r
- }\r
- $long = ip2long($i);\r
- if ($long !== false) {\r
- $ip[] = $long;\r
- }\r
- }\r
- }\r
-\r
- $file = '/home/stats/www/exclude/' . $book_id;\r
-\r
- if (count($ip)) {\r
- file_put_contents($file, implode(',', $ip));\r
- chmod($file, 0777);\r
- chown($file, 'stats');\r
- } else if (file_exists($file)) {\r
- unlink($file);\r
- }\r
-\r
- $c = $this->con->openCursor('books');\r
- $c->nom = $parametres->title;\r
- $c->parametres = serialize($parametres);\r
- $c->changedate = TIME;\r
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');\r
- }\r
-\r
- public function setProprietaire($book_id, $proprietaire_id) {\r
- $c = $this->con->openCursor('books');\r
- $c->proprietaire = $proprietaire_id;\r
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');\r
- }\r
-\r
- public function setTache($book_id, $tache) {\r
- $c = $this->con->openCursor('books');\r
- $c->tache = $tache;\r
- $c->status = 2;\r
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');\r
- }\r
-\r
- public function setVersion($book_id, $version) {\r
- $c = $this->con->openCursor('books');\r
- $c->version = $version;\r
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');\r
- }\r
-\r
- public function touch($book_id) {\r
- $c = $this->con->openCursor('books');\r
- $c->changedate = TIME;\r
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');\r
- }\r
-\r
- public function touchCompile($book_id, $version = 'all') {\r
- $c = $this->con->openCursor('books');\r
- if ($version == '2') {\r
- $c->compiledate = TIME;\r
- } elseif ($version == '1') {\r
- $c->compile1date = TIME;\r
- } elseif ($version == 'html5') {\r
- $c->compilehtml5date = TIME;\r
- } else {\r
- $c->compiledate = TIME;\r
- $c->compile1date = TIME;\r
- $c->compilehtml5date = TIME;\r
- }\r
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');\r
- }\r
-\r
- public function isUpToDate($book, $version) {\r
- $version = (string) $version;\r
- if ($version == '2') {\r
- if (!file_exists(WS_BOOKS . '/final/' . $book->book_id)) {\r
- return false;\r
- }\r
- if ($book->compiledate < $book->changedate) {\r
- return false;\r
- }\r
- } else if ($version == '1') {\r
- // V1\r
- if (!file_exists(WS_BOOKS . '/finalv1/' . $book->book_id . '/index.swf')) {\r
- return false;\r
- }\r
- if ($book->compile1date < $book->changedate) {\r
- return false;\r
- }\r
- } else if ($version == 'html5') {\r
- // HTML5\r
- $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'));\r
- foreach ($checks as $check) {\r
- if ($check > $book->compilehtml5date) {\r
- return false;\r
- }\r
- }\r
- }\r
- return true;\r
- }\r
-\r
- public function setComposition($book_id, $pages) {\r
- $numerotation = array();\r
- $nb_pages = 0;\r
- foreach ($pages as $p) {\r
- $numerotation[] = $p->virtual;\r
- $nb_pages++;\r
- }\r
-\r
- $book = $this->selectById($book_id);\r
- $parametres = $book->parametres;\r
- $parametres->pages = $nb_pages;\r
-\r
- $c = $this->con->openCursor('books');\r
- $c->parametres = serialize($parametres);\r
- $c->numerotation = implode(',', $numerotation);\r
- $c->changedate = TIME;\r
-\r
- // Check if composition need to be updated\r
- $r = $this->con->select('SELECT * FROM book_pages WHERE book_id=\'' . $this->con->escape($book_id) . '\'');\r
- $tab = array();\r
- $now = array();\r
- while ($r->fetch()) {\r
- $ref[$r->book_page] = array((int) $r->document_id, (int) $r->document_page);\r
- }\r
- $i = 1;\r
- foreach ($pages as $p) {\r
- $now[$i] = array((int) $p->document_id, (int) $p->document_page);\r
- $i++;\r
- }\r
- if ($now != $ref) {\r
- $this->con->execute('DELETE FROM book_pages WHERE book_id=\'' . $this->con->escape($book_id) . '\'');\r
-\r
- $c1 = $this->con->openCursor('book_pages');\r
- $c1->book_id = $book_id;\r
- $i = 1;\r
- foreach ($pages as $p) {\r
- $c1->document_id = $p->document_id;\r
- $c1->document_page = $p->document_page;\r
- $c1->book_page = $i;\r
- $c1->insert();\r
- $i++;\r
- }\r
- $c->composition_update = TIME;\r
- $this->saveCompositionVersion($book_id);\r
- }\r
-\r
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');\r
- }\r
-\r
- public function setInstallDir($book_id, $dir, $server) {\r
- $col = 'dir_' . $server;\r
-\r
- $c = $this->con->openCursor('books');\r
- $c->$col = $dir;\r
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');\r
- }\r
-\r
- public function makeTextsIndexes($book, $pages, &$index, &$textes) {\r
-\r
- $prefix = '';\r
- if ($book->parametres->textExtraction == 'poppler') {\r
- $prefix = 'p';\r
- }\r
-\r
-\r
- $dir = WS_BOOKS . '/index/' . $book->book_id;\r
- if ($book->parametres->ignoreSearchSeparators != '') {\r
- $dir.='/' . sha1($book->parametres->ignoreSearchSeparators);\r
- }\r
- if (!file_exists($dir)) {\r
- mkdir($dir, 0777, true);\r
- }\r
-\r
- $ifilec = $dir . '/' . $prefix . 'index.json';\r
- $tfilec = $dir . '/' . $prefix . 'textes.json';\r
-\r
- if (file_exists($ifilec) && file_exists($tfilec) && (min(filemtime($ifilec), filemtime($tfilec)) >= $book->composition_update)) {\r
- $index = file_get_contents($ifilec);\r
- $textes = file_get_contents($tfilec);\r
- return;\r
- }\r
-\r
- if ($book->parametres->ignoreSearchSeparators != "") {\r
- $docs = array();\r
- foreach ($pages as $p => $i) {\r
- $docs[] = $i['document_id'];\r
- }\r
- $docs = array_unique($docs);\r
-\r
- foreach ($docs as $doc) {\r
- $out = WS_DOCS . '/' . $doc . '/';\r
-\r
- $fwstk = new cubeCommandLine('fwstk');\r
- $fwstk->setPath(CONVERTER_PATH);\r
- $fwstk->setArg('--input ' . $out . '/crop.pdf');\r
- $fwstk->setArg('--extractTexts ' . $out . '%s%d.txt');\r
- $fwstk->setArg('--ignoreSeparators ' . $book->parametres->ignoreSearchSeparators);\r
- $fwstk->execute();\r
- }\r
- }\r
-\r
- $index = array();\r
- $textes = array();\r
- foreach ($pages as $book_page => $infos) {\r
- $tfile = WS_DOCS . '/' . $infos['document_id'] . '/' . $prefix . 'p' . $infos['document_page'] . '.txt';\r
- $ifile = WS_DOCS . '/' . $infos['document_id'] . '/' . $prefix . 'i' . $infos['document_page'] . '.txt';\r
- $text = file_get_contents($tfile);\r
- $ipage = file_get_contents($ifile);\r
-\r
- $this->fillIndexWithWords($index, $book_page, $ipage);\r
- $textes[$book_page] = $text;\r
- }\r
- ksort($index);\r
-\r
-\r
- $textes = json_encode($textes);\r
- $index = json_encode($index);\r
-\r
- file_put_contents($tfilec, $textes);\r
- file_put_contents($ifilec, $index);\r
- }\r
-\r
- protected function fillIndexWithWords(&$index, $page, $ipage) {\r
- $twords = explode("\n", trim($ipage));\r
-\r
- foreach ($twords as $woadata) {\r
- $w1 = explode(',', trim($woadata));\r
- if (count($w1) <= 1) {\r
- continue;\r
- }\r
- list($woa, $worddata) = $w1;\r
- $e = explode("\t", $worddata, 2);\r
- if (count($e) < 2) {\r
- continue;\r
- }\r
- list($total, $wordslist) = $e;\r
-\r
- if ($woa == '') {\r
- continue;\r
- }\r
-\r
- if (!isset($index[$woa])) {\r
- $index[$woa] = array('t' => 0, 'w' => array());\r
- }\r
- $index[$woa]['t'] += $total;\r
-\r
- $words = explode("\t", $wordslist);\r
-\r
- foreach ($words as $word) {\r
- list($wordwa, $count) = explode('$', $word, 2);\r
- if (!isset($index[$woa]['w'][$wordwa])) {\r
- $index[$woa]['w'][$wordwa] = array('t' => 0, 'p' => array());\r
- }\r
- if (!isset($index[$woa]['w'][$wordwa]['p'][$page])) {\r
- $index[$woa]['w'][$wordwa]['p'][$page] = 0;\r
- }\r
- $index[$woa]['w'][$wordwa]['t'] += $count;\r
- $index[$woa]['w'][$wordwa]['p'][$page] += $count;\r
- }\r
- }\r
- }\r
-\r
- public function getNumerotationFromDocs($book_id) {\r
- $pages = $this->getPagesOfBook($book_id);\r
- }\r
-\r
- public function compileTemp($book_id, $version, $dir) {\r
- if ($version == 'ha' || $version == 'hi') {\r
- if ($version == 'ha') {\r
- $os = 'android';\r
- } elseif ($version == 'hi') {\r
- $os = 'ios';\r
- }\r
- $packager = new wsPackagerPhonegap($book_id, $dir, false, true, $os);\r
- $packager->makePackage(false);\r
- }\r
- }\r
-\r
- public function compile($book_id, $version = 'all', $complete = false, $force = false) {\r
- if (is_null($book_id) || !$book_id) {\r
- return;\r
- }\r
-\r
- $v1 = $v2 = $html5 = false;\r
-\r
- if ($version == 'all') {\r
- $v1 = $v2 = $html5 = true;\r
- } else if ($version == '1') {\r
- $v1 = true;\r
- } else if ($version == '2') {\r
- $v2 = true;\r
- } elseif ($version == 'html5') {\r
- $html5 = true;\r
- }\r
-\r
- $book = $this->selectById($book_id);\r
- $pages = $this->getPagesOfBook($book_id);\r
-\r
- if (!$force) {\r
-\r
- $v1 = $v1 && !$this->isUpToDate($book, 1);\r
- $v2 = $v2 && !$this->isUpToDate($book, 2);\r
- $html5 = $html5 && !$this->isUpToDate($book, 'html5');\r
- } else {\r
- $v1 = false;\r
- $html5 = false;\r
- $v2 = true;\r
- }\r
-\r
-\r
-\r
- $res = '';\r
- if ($v1) {\r
- fb(time(), 'Compile V1');\r
- $res.=$this->compile1($book_id, $book, $pages);\r
- $this->touchCompile($book_id, '1');\r
- }\r
- if ($v2) {\r
- fb(time(), 'Compile V2');\r
- $res .= $this->compile3($book_id, $complete, $book, $pages);\r
- $this->touchCompile($book_id, '2');\r
- }\r
- if ($html5) {\r
- fb(time(), 'Compile HTML5');\r
- $res.=$this->compileHTML5($book_id, $book);\r
- $this->touchCompile($book_id, 'html5');\r
- }\r
- if ($v1 || $v2) {\r
- fb(time(), 'Compile PDF & Widget');\r
- $this->compilePDF($book, $pages);\r
- $this->compileWidget($book, $pages);\r
- }\r
-\r
- fb(time(), 'End Compile');\r
- return $res;\r
- }\r
-\r
- public function compile1($book_id, $book, $pages) {\r
- $finalDir = WS_BOOKS . '/finalv1/' . $book_id . '/';\r
- $packager = new wsPackagerV1($book_id, $finalDir, false);\r
- $packager->makePackage(false);\r
- }\r
-\r
- public function compile3($book_id, $complete, $book, $pages) {\r
- $res = '';\r
-\r
- $compilerDir = WS_BOOKS . '/datasCompiler/' . $book_id . '/';\r
- $finalDir = WS_BOOKS . '/final/' . $book_id . '/';\r
-\r
- $rm = new cubeCommandLine('rm');\r
- $rm->setArg('r');\r
- $rm->setArg('f');\r
- $rm->setArg(null, $finalDir);\r
- $rm->execute();\r
- mkdir($finalDir, 0777, true);\r
-\r
- $flex = new cubeFlexCompiler('FluidbookDatas', $compilerDir, 'flash.display.Sprite', explode(';', AS3_SOURCES), MXMLC_PATH, 10);\r
- $flexLight = new cubeFlexCompiler('FluidbookDatasLight', $compilerDir, 'flash.display.Sprite', explode(';', AS3_SOURCES), MXMLC_PATH, 10);\r
-\r
- $filesToCopy = array();\r
- $this->compileFlex($book_id, $complete, $compilerDir, $finalDir, $filesToCopy, $book, $pages, $flex, $flexLight);\r
-\r
- $res .= $flex->compile() . "\n\n-------------------\n\n";\r
- $flexLight->addVariable('datasSize', filesize($compilerDir . '/FluidbookDatas.swf'));\r
- $res .= $flexLight->compile();\r
-\r
- $filesToCopy['data/fd.swf'] = $compilerDir . '/FluidbookDatas.swf';\r
- $filesToCopy['data/fdl.swf'] = $compilerDir . '/FluidbookDatasLight.swf';\r
-\r
- // Copy of files\r
- // Check if dest dir exists\r
- if (!file_exists($finalDir . 'data')) {\r
- mkdir($finalDir . 'data', 0777, true);\r
- }\r
-\r
- foreach ($filesToCopy as $local => $source) {\r
- $localPath = $finalDir . $local;\r
- if (!file_exists($localPath) || filemtime($localPath) < filemtime($source) || filesize($localPath) != filesize($source) || filemtime($localPath) < $book->composition_update) {\r
- if (is_dir($source)) {\r
- continue;\r
- }\r
- $this->copy($source, $localPath);\r
- }\r
- }\r
-\r
- $workingDir = WS_BOOKS . '/working/' . $book_id . '/';\r
- if (file_exists($workingDir . 'media')) {\r
- $cp = new cubeCommandLine('cp');\r
- $cp->setPath(CONVERTER_PATH);\r
- $cp->setArg('r');\r
- $cp->setArg('p');\r
- $cp->setArg(null, $workingDir . 'media');\r
- $cp->setArg(null, $finalDir . 'data');\r
- $cp->execute();\r
- }\r
-\r
- return $res;\r
- }\r
-\r
- public function copy($source, $dest) {\r
- copy($source, $dest);\r
- touch($dest, filemtime($source));\r
- }\r
-\r
- public function compileAir($book_id) {\r
- $compilerDir = WS_BOOKS . '/air/' . $book_id . '/compiler';\r
- $finalDir = WS_BOOKS . '/air/' . $book_id . '/';\r
-\r
- $book = $this->selectById($book_id);\r
- $pages = $this->getPagesOfBook($book_id);\r
-\r
- $src = AS3_FLUIDBOOK_SOURCES . '/_src/';\r
- $lib10 = AS3_FLUIDBOOK_SOURCES . '/lib10/';\r
- $libs = array(\r
- $src,\r
- $lib10,\r
- AS3_SOURCES,\r
- $src . 'lib/fluidbook3dLibrary.swc',\r
- $src . 'lib/mdm.swc',\r
- $lib10 . 'flash.swc',\r
- $lib10 . 'flex.swc',\r
- $lib10 . 'framework.swc',\r
- );\r
-\r
- wsSVN::updateToLastRevision();\r
-\r
- $swf = 'FluidbookAirProjector' . $book_id;\r
- $flex = new cubeFlexCompiler($swf, $compilerDir, 'com.fluidbook.player.AIRMain', $libs, '/usr/local/flex/bin/mxmlc', 'air', 45, 800, 600, true);\r
-\r
- $this->compileFlex($book_id, true, $compilerDir, $finalDir, $filesToCopy, $book, $pages, $flex, $flex);\r
- $res = $flex->compile();\r
-\r
- $air = new cubeAIRCompiler($swf . '.swf', '/usr/local/flex/bin', $compilerDir, '2.0');\r
- $air->setApplicationDatas('com.fluidbook' . $book_id, $book->parametres->title, $book->parametres->title, cubeText::str2URL($book->parametres->title), $book->lang);\r
- $air->setInitialWindow($book->parametres->title);\r
- $res.=$air->compile();\r
-\r
- return $res;\r
- }\r
-\r
- public function compileFlex($book_id, $complete, $compilerDir, $finalDir, &$filesToCopy, $book, $pages, $flex, $flexLight) {\r
- cubePHP::neverStop();\r
- /* @var $flex cubeFlexCompiler */\r
-\r
- $workingDir = WS_BOOKS . '/working/' . $book_id . '/';\r
-\r
- $res = '';\r
-\r
- $daoDoc = new wsDAODocument($this->con);\r
- $firstDoc = $daoDoc->selectById($pages[1]['document_id']);\r
- $size = $firstDoc->generalInfos['size'];\r
-\r
- $daoLang = new wsDAOLang($this->con);\r
- $lang = $daoLang->selectById($book->lang);\r
-\r
- $langs = $daoLang->selectAll();\r
-\r
- $daoTheme = new wsDAOTheme($this->con);\r
- $theme = $daoTheme->getThemeOfBook($book_id, true);\r
-\r
- $daoSignature = new wsDAOSignature($this->con);\r
- $signature = $daoSignature->selectById($book->parametres->signature);\r
-\r
- $exportSignature = array('main' => $signature->main,\r
- 'mainLink' => $signature->mainLink,\r
- 'partner' => $signature->partner,\r
- 'partnerLink' => $signature->partnerLink);\r
-\r
- $index = '';\r
- $textes = '';\r
-\r
- $hash = $book_id;\r
- $hash .= 'kjgl!az4.';\r
- $hash .= count($pages);\r
- $hash .= round($size[0], 3);\r
-\r
- $hash = sha1($hash);\r
-\r
- $this->makeTextsIndexes($book, $pages, $index, $textes);\r
-\r
- $daoDoc->getLinksAndRulers($book_id, $links, $rulers);\r
-\r
- $imagesassets = array();\r
- $id = 1;\r
- foreach ($links as $id => $link) {\r
- $links[$id]['id'] = $id;\r
- if ($link['type'] == 15) {\r
- if (isset($imagesassets[$id])) {\r
- continue;\r
- }\r
- if ($link['page'] <= 1) {\r
- $flexLight->addBitmap($workingDir . '/' . $link['to'], 'link_datas_' . $id);\r
- } else {\r
- $flex->addBitmap($workingDir . '/' . $link['to'], 'link_datas_' . $id);\r
- }\r
- $imagesassets[$id] = true;\r
- } else if (in_array($link['type'], array(4, 6, 7, 9, 16, 17))) {\r
- $workingFile = $workingDir . '/' . $link['to'];\r
- if (file_exists($workingFile)) {\r
- $filesToCopy['data/' . $link['to']] = $workingFile;\r
- }\r
-\r
- if ($link['type'] == 4) {\r
- $poster = $link['to'];\r
- $e = explode('.', $poster);\r
- array_pop($e);\r
- array_push($e, 'jpg');\r
- $poster = implode('.', $e);\r
-\r
- $workingFile = $workingDir . '/' . $poster;\r
- if (file_exists($workingFile)) {\r
- $filesToCopy['data/' . $poster] = $workingFile;\r
- }\r
- }\r
- }\r
- }\r
-\r
- $externalsOptions = array('ongletsSWF', 'tabs2DSWF', 'externalChapters', 'externalArchives');\r
- foreach ($externalsOptions as $e) {\r
- if (isset($book->parametres->$e) && $book->parametres->$e != '') {\r
- $f = $workingDir . '/' . $book->parametres->$e;\r
- if (file_exists($f)) {\r
- $filesToCopy['data/' . $book->parametres->$e] = $f;\r
- }\r
- }\r
- }\r
-\r
- $flex->addVariable('links', $links, false, true, 'JSONObject');\r
-\r
- $flex->addVariable('signature', $exportSignature, false, true, 'JSONObject');\r
- $flexLight->addVariable('datas', $book->parametres->toStandardObject(), false, true, 'JSONObject');\r
- $flexLight->addVariable('id', $book_id, false, true, 'uint');\r
- $flexLight->addVariable('cid', $book->cid, false, true, 'String');\r
-\r
- $traductions = (!count($book->traductions)) ? $lang->traductions : $book->traductions;\r
- $allTraductions = array();\r
- foreach ($langs as $l) {\r
- $allTraductions[$l->lang_id] = $l->traductions;\r
- }\r
-\r
- $flex->addVariable('traductions', $traductions, false, true, 'JSONObject', false);\r
- $flex->addVariable('allTraductions', $allTraductions, false, true, 'JSONObject');\r
- $flex->addVariable('chapters', $book->chapters, false, true, 'JSONObject');\r
- $flex->addVariable('extras', '<extras>' . $book->extras . '</extras>', false, true, 'XML');\r
- $flex->addVariable('numerotation', $book->numerotation, false, true, 'String');\r
- $flexLight->addVariable('theme', $theme->parametres->toStandardObject(), false, true, 'JSONObject');\r
- $flexLight->addVariable('pages', $book->parametres->pages);\r
- $flexLight->addVariable('fwidth', round($size[0], 4), false, true, 'Number');\r
- $flexLight->addVariable('fheight', round($size[1], 4), false, true, 'Number');\r
- $flexLight->addVariable('pagesInDatas', $complete, false, true, 'Boolean');\r
- $flex->addVariable('index', $index, false, true, 'JSONObject', false, false);\r
- $flex->addVariable('textes', $textes, false, true, 'JSONObject', false, false);\r
-\r
- $rasterized = array();\r
- $sizes = array();\r
-\r
- foreach ($pages as $i => $infos) {\r
- $base = WS_DOCS . '/' . $infos['document_id'] . '/p' . $infos['document_page'];\r
- $baset = WS_DOCS . '/' . $infos['document_id'] . '/t' . $infos['document_page'];\r
- $swffile = $base . '.swf';\r
- if (file_exists($swffile)) {\r
- $fsize = filesize($swffile);\r
- } else {\r
- $fsize = 0;\r
- }\r
-\r
- if ($complete) {\r
- $flex->addSWF($swffile, 'page' . $i);\r
- } else {\r
- $filesToCopy['data/p' . $i . '.swf'] = $swffile;\r
- if ($infos['method'] >= wsDocument::BARBARE_PNM) {\r
- $rasterized[$i] = true;\r
- $filesToCopy['data/t' . $i . '.swf'] = $baset . '.swf';\r
- } else {\r
- $rasterized[$i] = false;\r
- }\r
- }\r
-\r
- if ($i == 1) {\r
- $flexLight->addBitmap($base . '.jpg', 'thumb1');\r
- } else {\r
- $flex->addBitmap($base . '.jpg', 'thumb' . $i);\r
- }\r
- $sizes[$i] = $fsize;\r
- }\r
-\r
- $flexLight->addVariable('rasterized', $rasterized, false, true, 'JSONObject');\r
- $flexLight->addVariable('sizes', $sizes, false, true, 'JSONObject');\r
-\r
- if ($book->parametres->soundTheme != '') {\r
- $flex->addSound(WS_SOUNDS . '/' . $book->parametres->soundTheme . '/corner-drag.mp3', 'soundDragCorner');\r
- $flex->addSound(WS_SOUNDS . '/' . $book->parametres->soundTheme . '/corner-release.mp3', 'soundReleaseCorner');\r
- $flex->addSound(WS_SOUNDS . '/' . $book->parametres->soundTheme . '/page-flip-1.mp3', 'soundPage0');\r
- $flex->addSound(WS_SOUNDS . '/' . $book->parametres->soundTheme . '/page-flip-2.mp3', 'soundPage1');\r
- $flex->addSound(WS_SOUNDS . '/' . $book->parametres->soundTheme . '/cover-flip.mp3', 'soundCover0');\r
- }\r
- // Theme assets\r
- $themeRoot = WS_THEMES . '/' . $theme->theme_id . '/';\r
-\r
- if ($theme->parametres->backgroundImage != '') {\r
- $flexLight->addBitmap($themeRoot . $theme->parametres->backgroundImage, 'background');\r
- }\r
- if ($theme->parametres->menuImage != '') {\r
- $flex->addBitmap($themeRoot . $theme->parametres->menuImage, 'menu');\r
- }\r
- if ($theme->parametres->logoLoader != '') {\r
- $flexLight->addBitmap($themeRoot . $theme->parametres->logoLoader, 'logoLoader');\r
- }\r
- if ($theme->parametres->topBar != '') {\r
- $flexLight->addBitmap($themeRoot . $theme->parametres->topBar, 'topBar');\r
- }\r
- if ($theme->parametres->logo != '') {\r
- $flex->addBitmap($themeRoot . $theme->parametres->logo, 'logo');\r
- }\r
- if ($theme->parametres->afterSearch != '') {\r
- $flex->addBitmap($themeRoot . $theme->parametres->afterSearch, 'aftersearch');\r
- }\r
- if ($theme->parametres->favicon != '') {\r
- $filesToCopy['data/fluidbook.ico'] = $themeRoot . 'fluidbook.ico';\r
- }\r
-\r
- // Icons assets\r
- $iconsRoot = WS_ICONS . '/' . $theme->parametres->iconSet . '/';\r
- foreach (wsIcone::$files as $file) {\r
- $flex->addBitmap($iconsRoot . 'nav-' . $file . '.png', 'nav_' . $file);\r
- }\r
- // Share icons\r
- $iconsRoot = WS_ICONS . '/share/';\r
- foreach (wsIcone::$share as $file) {\r
- $flex->addBitmap($iconsRoot . 'share-' . $file . '.png', 'share_' . $file);\r
- }\r
-\r
- // Multilang\r
- if (trim($book->parametres->multilang) != '') {\r
- $m = str_replace("\r", "\n", trim($book->parametres->multilang));\r
- $langs = explode("\n", $m);\r
- $langNames = array();\r
- $countryNames = array();\r
- $iso = l10n::getISOcodes();\r
- $chars = '()';\r
- $vuFlags = array();\r
- foreach ($langs as $l) {\r
- list($mlang, $flag, $url) = explode(',', trim($l), 3);\r
- if (!isset($vuFlags[$flag])) {\r
- $flex->addBitmap(cubeMedia::getFlagFile($flag), 'flag_' . $flag);\r
- $vuFlags[$flag] = true;\r
- }\r
- $n = cubeText::ucfirst($iso[$mlang]);\r
- $langNames[$mlang] = $n;\r
- $cn = cubeCountry::getCountryName($flag, $mlang);\r
- $countryNames[$mlang . '_' . $flag] = $cn;\r
- $chars.=$n . $cn;\r
- }\r
-\r
- $chars = preg_split('/(?<!^)(?!$)/u', $chars);\r
- $chars = array_unique($chars);\r
-\r
- $flex->addFont(WS_FILES . '/fonts/FluidbookMultilang.ttf', 'MultilangFont', $chars);\r
- $flex->addVariable('langNames', $langNames, false, true, 'JSONObject');\r
- $flex->addVariable('countryNames', $countryNames, false, true, 'JSONObject');\r
- }\r
- $flexLight->addVariable('lang', $book->lang);\r
-\r
- // Basket\r
- if ($book->parametres->basket) {\r
- $formats = array('jpg', 'png', 'jpeg');\r
- $referencesFile = $workingDir . 'commerce/' . $book->parametres->basketReferences;\r
-\r
- if (file_exists($referencesFile)) {\r
- $xml = simplexml_load_file($referencesFile);\r
- $i = 0;\r
- $allref = array();\r
- foreach ($xml->item as $item) {\r
- $ref = (string) $item['reference'];\r
- if (isset($allref[$ref])) {\r
- continue;\r
- }\r
- $allref[$ref] = true;\r
- foreach ($formats as $f) {\r
- $refimage = $workingDir . 'commerce/' . $ref . '.' . $f;\r
- if (file_exists($refimage)) {\r
- $flex->addBitmap($refimage, "basket_image_" . $ref);\r
- break;\r
- }\r
- }\r
- $i++;\r
- }\r
- }\r
- if (isset($xml)) {\r
- $flex->addVariable('basketReferences', cubeXML::condense($xml->asXML()), false, true, "String");\r
- }\r
- if ($book->parametres->basketPDFBackground != '') {\r
- $flex->addByteArray($workingDir . 'commerce/' . $book->parametres->basketPDFBackground, 'basket_pdf_background');\r
- }\r
- }\r
- // Fonts\r
- if ($theme->parametres->fontKit == 'auto') {\r
- if ($lang->font != 'system') {\r
- $flex->addFont(FONT_PATH . '/' . $lang->font, 'BoldFont', $lang->charset);\r
- $flex->addFont(FONT_PATH . '/' . $lang->font, 'GeneralFont', $lang->charset);\r
- }\r
- $flex->addFont(FONT_PATH . '/FluidbookCredits.ttf', 'CreditsFont', 'ASCII');\r
- $flexLight->addFont(FONT_PATH . '/FluidbookLoader.ttf', 'LoaderFont', 'Numerals');\r
- } else if ($theme->parametres->fontKit == 'vagrounded') {\r
- $flex->addFont(FONT_PATH . '/vagrounded/VAGRoundedStd-Bold.otf', 'BoldFont', $lang->charset);\r
- $flex->addFont(FONT_PATH . '/vagrounded/VAGRoundedStd-Light.otf', 'GeneralFont', $lang->charset);\r
- $flex->addFont(FONT_PATH . '/FluidbookCredits.ttf', 'CreditsFont', 'ASCII');\r
- $flexLight->addFont(FONT_PATH . '/vagrounded/VAGRoundedStd-Bold.otf', 'LoaderFont', 'Numerals');\r
- } else if ($theme->parametres->fontKit == 'gill') {\r
- $flex->addFont(FONT_PATH . '/gill/gill.ttf', 'BoldFont', $lang->charset);\r
- $flex->addFont(FONT_PATH . '/gill/gill.ttf', 'GeneralFont', $lang->charset);\r
- $flex->addFont(FONT_PATH . '/FluidbookCredits.ttf', 'CreditsFont', 'ASCII');\r
- $flexLight->addFont(FONT_PATH . '/gill/gill.ttf', 'LoaderFont', 'Numerals');\r
- }\r
-\r
- $flexLight->addVariable('checksum', $hash, false, true, 'String');\r
- }\r
-\r
- public function compileWidget($book, $pages) {\r
- if (!$book->parametres->widget) {\r
- return;\r
- }\r
-\r
- global $core;\r
-\r
- $finalDir = WS_BOOKS . '/final/' . $book->book_id . '/widget/';\r
- $finalWidget = $finalDir . 'miniFluidbook.swf';\r
-\r
- if (!file_exists($finalDir)) {\r
- mkdir($finalDir, 0777, true);\r
- }\r
-\r
- if ($book->parametres->widgetCover) {\r
- $file = 'miniFluidbookCouv.swf';\r
- } else {\r
- $file = 'miniFluidbook.swf';\r
- }\r
- $mini = WS_COMPILE_ASSETS . '/_widget/' . $file;\r
-\r
- $from = max(1, $book->parametres->widgetStart);\r
- $to = min($book->parametres->widgetEnd, count($pages));\r
-\r
- $swfcombine = new cubeCommandLine('swfcombine');\r
- $swfcombine->setPath(CONVERTER_PATH);\r
- $swfcombine->setArg('merge');\r
- $swfcombine->setArg('stack1');\r
- $swfcombine->setArg('z');\r
- $swfcombine->setArg('o', $finalWidget);\r
- $swfcombine->setArg(null, $mini);\r
-\r
- $tempimage = array();\r
- $tempswf = array();\r
- $timg = array();\r
-\r
- for ($i = $from; $i <= $to; $i++) {\r
- $page = $pages[$i];\r
-\r
- $timg[$i] = $tempimage[$i] = cubeFiles::tempnam();\r
- $tempswf[$i] = cubeFiles::tempnam();\r
-\r
- $it = new imageTools();\r
- $image = WS_DOCS . '/' . $page['document_id'] . '/html/t150-' . $page['document_page'] . '.jpg';\r
-\r
- try {\r
- $it->loadImage($image);\r
- $it->resize($book->parametres->widgetSize, 10000);\r
- $it->output('jpeg', $tempimage[$i], 100);\r
- } catch (Exception $e) {\r
- $tempimage[$i] = $image;\r
- }\r
- $jpg2swf = new cubeCommandLine('jpeg2swf');\r
- $jpg2swf->setEnv('PATH', '/bin:/usr/bin:/usr/local/bin');\r
- $jpg2swf->setArg('q', $book->parametres->widgetQuality);\r
- $jpg2swf->setArg('o', $tempswf[$i]);\r
- $jpg2swf->setArg(null, $tempimage[$i]);\r
- $jpg2swf->execute();\r
-\r
- $swfcombine->setArg(null, $tempswf[$i]);\r
- }\r
- $swfcombine->execute();\r
-\r
- foreach ($timg as $t) {\r
- if (file_exists($t)) {\r
- unlink($t);\r
- }\r
- }\r
- foreach ($tempswf as $t) {\r
- unlink($t);\r
- }\r
- }\r
-\r
- public function compileHTML5($book_id, $book) {\r
- $htmlCompiler = wsHTML5Compiler::factory($book_id, $book->parametres->mobileLVersion);\r
- $htmlCompiler->compile();\r
- }\r
-\r
- public function indexPDF($book, $pages) {\r
- $indexPath = WS_BOOKS . '/search/' . $book->book_id;\r
-\r
- Zend_Search_Lucene_Analysis_Analyzer::setDefault(new Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8Num_CaseInsensitive());\r
-\r
- if (file_exists($indexPath)) {\r
- files::deltree($indexPath);\r
- }\r
- $index = Zend_Search_Lucene::create($indexPath);\r
-\r
- foreach ($pages as $i => $infos) {\r
- $doc = new Zend_Search_Lucene_Document();\r
- $doc->addField(Zend_Search_Lucene_Field::Text('url', '#' . $i));\r
- $doc->addField(Zend_Search_Lucene_Field::UnStored('contents', file_get_contents(WS_DOCS . '/' . $infos['document_id'] . '/p' . $infos['document_page'] . '.txt')));\r
- $index->addDocument($doc);\r
- }\r
-\r
- $c = $this->con->openCursor('books');\r
- $c->lucene_time = TIME;\r
- $c->update('WHERE book_id=' . $book->book_id);\r
- }\r
-\r
- public function compilePDF($book, $pages) {\r
- if(substr($book->parametres->pdfName,0,4)=='http'){\r
- return;\r
- }\r
- if (isset($book->parametres->pdfName) && $book->parametres->pdfName != '') {\r
- $pdfName = $book->parametres->pdfName;\r
- }\r
-\r
- $cacheDir = WS_BOOKS . '/pdf/' . $book->book_id;\r
- if (!file_exists($cacheDir)) {\r
- mkdir($cacheDir);\r
- }\r
-\r
- $normalPDF = $cacheDir . '/normal.pdf';\r
- $compressedPDF = $cacheDir . '/compressed.pdf';\r
-\r
- if ($book->parametres->pdfReplace) {\r
- $replace = WS_BOOKS . '/working/' . $book->book_id . '/' . $book->parametres->pdfReplace;\r
- if (file_exists($replace)) {\r
- if (!file_exists($normalPDF) || filemtime($normalPDF) < filemtime($replace) || filesize($normalPDF) != filesize($replace)) {\r
- $this->copy($replace, $normalPDF);\r
- }\r
- }\r
- } else {\r
-\r
- if (file_exists($normalPDF)) {\r
- $fmtime = filemtime($normalPDF);\r
- if ($fmtime >= $book->composition_update) {\r
- $invalid = false;\r
- foreach ($pages as $i => $infos) {\r
- $doc = WS_DOCS . '/' . $infos['document_id'] . '/crop.pdf';\r
- if (filemtime($doc) > $fmtime) {\r
- $invalid = true;\r
- }\r
- }\r
- } else {\r
- $invalid = true;\r
- }\r
- } else {\r
- $invalid = true;\r
- }\r
-\r
- fb($invalid, 'invalid ?');\r
-\r
- if ($invalid) {\r
- $pdfList = array();\r
- $pagesList = array();\r
- $nb_pages = array();\r
- $j = 0;\r
- $k = 0;\r
- $original = true;\r
-\r
- foreach ($pages as $i => $infos) {\r
- if (!isset($firstDoc)) {\r
- $firstDoc = $infos['document_id'];\r
- }\r
-\r
- $doc = WS_DOCS . '/' . $infos['document_id'] . '/crop.pdf';\r
- if (!isset($pdfList[$doc])) {\r
- $pdfList[$doc] = $j;\r
- $nb_pages[$doc] = $infos['nb_pages'];\r
- $k = $j;\r
- $j++;\r
- } else {\r
- $k = $pdfList[$doc];\r
- }\r
- $pagesList[$i] = array($k, $infos['document_page']);\r
-\r
- if ($i != $infos['document_page'] || $infos['document_id'] != $firstDoc) {\r
- $original = false;\r
- }\r
- }\r
-\r
- if ($original) {\r
- fb($normalPDF, 'original');\r
- $this->copy(WS_DOCS . '/' . $firstDoc . '/crop.pdf', $normalPDF);\r
- } else {\r
- $args = '';\r
- foreach ($pdfList as $doc => $index) {\r
- $lettre = cubeMath::toPDFLetter($index, true);\r
- $args .= $lettre . '=' . $doc . ' ';\r
- }\r
-\r
- $args .= ' cat ';\r
-\r
- $ranges = array();\r
- $currentRange = null;\r
-\r
- foreach ($pagesList as $p) {\r
- $lettre = cubeMath::toPDFLetter($p[0], true);\r
- $page = $p[1];\r
-\r
- // Initialise l'intervale\r
- if (is_null($currentRange)) {\r
- $currentRange = array('lettre' => $lettre, 'start' => $page, 'end' => $page);\r
- continue;\r
- }\r
-\r
- // Poursuit le remplissage si la lettre est identique et si la page suivante est bien la page suivante dans le document\r
- if ($currentRange['lettre'] == $lettre && $currentRange['end'] + 1 == $page) {\r
- $currentRange['end'] = $page;\r
- continue;\r
- }\r
-\r
- // Ajoute l'intervale à la liste finale\r
- $ranges[] = $currentRange;\r
-\r
- // Réinitialise l'intervale suivant\r
- $currentRange = array('lettre' => $lettre, 'start' => $page, 'end' => $page);\r
- }\r
-\r
- // Ajoute la dernière\r
- if (!is_null($currentRange)) {\r
- $ranges[] = $currentRange;\r
- }\r
- // Si le pdf final est constitué du document complet d'un document\r
- if (count($ranges) == 1 && $ranges[0]['start'] == 1) {\r
- $alldocs = array_keys($pdfList);\r
- $doc = array_pop($alldocs);\r
- if ($nb_pages[$doc] == $ranges[0]['end']) {\r
- $this->copy($doc, $normalPDF);\r
- return;\r
- }\r
- }\r
-\r
- foreach ($ranges as $range) {\r
- $args .= ' ' . $range['lettre'] . $range['start'];\r
- if ($range['start'] == $range['end']) {\r
- continue;\r
- }\r
- $args .= '-' . $range['end'];\r
- }\r
-\r
- $hash = sha1($args);\r
-\r
- $args .= ' output ' . $normalPDF;\r
-\r
- $cached = WS_BOOKS . '/pdf/' . $hash . '.pdf';\r
-\r
- if (file_exists($cached)) {\r
- $this->copy($cached, $normalPDF);\r
- } else {\r
- $pdftk = new cubeCommandLine('pdftk');\r
- $pdftk->setPath(CONVERTER_PATH);\r
- $pdftk->setManualArg($args);\r
- $pdftk->execute();\r
- $this->copy($normalPDF, $cached);\r
- }\r
- }\r
- }\r
- }\r
-\r
- $finalPDF = WS_BOOKS . '/final/' . $book->book_id . '/data/' . $book->parametres->pdfName;\r
-\r
- if ($book->parametres->pdfCompress) {\r
- if (!file_exists($compressedPDF) || filemtime($compressedPDF) < filemtime($normalPDF)) {\r
- $gs = new cubeCommandLine('gs', null, true);\r
- $gs->setPath(CONVERTER_PATH);\r
- $gs->setEnv('GS_FONTPATH', '/home/ws/fonts');\r
- $gs->setArg('-dBATCH');\r
- $gs->setArg('-dNOPAUSE');\r
- $gs->setArg('-dNOPROMPT');\r
- $gs->setArg('-sOutputFile=' . $compressedPDF);\r
- $gs->setArg('-sDEVICE=pdfwrite');\r
- $gs->setArg('-dPDFSETTINGS=/ebook');\r
- $gs->setArg('-dColorImageResolution=72');\r
- $gs->setArg('-dAutoRotatePages=/None');\r
- $gs->setArg('-dColorConversionStrategy=/LeaveColorUnchanged');\r
- $gs->setArg(null, $normalPDF);\r
- $gs->execute();\r
- }\r
- copy($compressedPDF, $finalPDF);\r
- } else {\r
- copy($normalPDF, $finalPDF);\r
- }\r
- }\r
-\r
- public function generateCID() {\r
-\r
- do {\r
- $res = '';\r
- for ($i = 0; $i < 8; $i++) {\r
- $j = rand(0, 61);\r
- $res.=$this->base62($j);\r
- }\r
- $r = $this->con->select('SELECT book_id FROM books WHERE cid=\'' . $res . '\'');\r
- if ($r->count() == 0) {\r
- return $res;\r
- }\r
- } while (true);\r
- }\r
-\r
- protected function base62($val) {\r
- $chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';\r
- $base = strlen($chars);\r
- $str = '';\r
- do {\r
- $i = $val % $base;\r
- $str = $chars[$i] . $str;\r
- $val = ($val - $i) / $base;\r
- } while ($val > 0);\r
- return $str;\r
- }\r
-\r
-}\r
-\r
+<?php
+
+class wsDAOBook extends commonDAO {
+
+ /**
+ * wsDAOBook::singleton()
+ *
+ * @param mixed $r
+ * @return
+ */
+ protected function singleton($r) {
+ $book = new wsBook();
+ $book->book_id = $r->book_id;
+ $book->cid = $r->cid;
+ $book->nom = $r->nom;
+ $book->lang = $r->lang;
+ $book->theme = $r->theme;
+ $book->proprietaire = $r->proprietaire_nom;
+ $book->proprietaire_id = $r->proprietaire_id;
+ $book->proprietaire_utilisateur = $r->proprietaire_utilisateur;
+ $book->hash = $r->hash;
+ $book->compteur_visites = $r->compteur_visites;
+ $book->status = $r->status;
+ $book->date_status = $r->date_status;
+ $book->date = $r->date;
+ $book->pages = array();
+ $book->chapters = $r->chapters;
+ $book->traductions = $r->traductions;
+ $book->specialLinks = $r->specialLinks;
+ $book->specialRulers = $r->specialRulers;
+ $book->parametres = $r->parametres;
+ $book->extras = $r->extras;
+ $book->numerotation = $r->numerotation;
+ $book->changedate = $r->changedate;
+ $book->compiledate = $r->compiledate;
+ $book->compile1date = $r->compile1date;
+ $book->compilehtml5date = $r->compilehtml5date;
+ $book->facturable = $r->facturable;
+ $book->facturable_id = $r->facturable_id;
+ $book->tache = $r->tache;
+ if (isset($r->projet)) {
+ $book->projet = $r->projet;
+ }
+ $book->version = $r->version;
+ $book->composition_update = $r->composition_update;
+ $book->dir_references = $r->dir_references;
+ $book->dir_hosting = $r->dir_hosting;
+ $book->dir_macbook_phonegap_ios = $r->dir_macbook_phonegap_ios;
+ $book->dir_phonegap_android = $r->dir_phonegap_android;
+ $book->dir_external = $r->dir_external;
+ $book->demo_counter = $r->demo_counter;
+ $book->exportdatas = $r->exportdatas;
+
+ return $book;
+ }
+
+ protected function cree($r) {
+ $book = new wsBook();
+ $book->book_id = 'new';
+ $book->nom = '';
+ $book->cid = null;
+ $book->lang = 'fr';
+ $book->theme = 1;
+ $book->proprietaire = '';
+ $book->proprietaire_id = 0;
+ $book->hash = '';
+ $book->compteur_visites = 20;
+ $book->status = 0;
+ $book->date_status = TIME;
+ $book->date = TIME;
+ $book->composition_update = TIME;
+ $book->chapters = json_encode(array());
+ $book->parametres = new wsBookParametres();
+ $book->tache = 0;
+ $book->pages = array();
+ $book->version = 2;
+ return $book;
+ }
+
+ protected function getNextId() {
+ $r = $this->con->select('SELECT MAX(book_id) AS book_id FROM books');
+ if ($r->book_id < 10000) {
+ return 10000;
+ }
+ return $r->book_id + 1;
+ }
+
+ public function saveExportDatas($book_id, $datas) {
+ $c = $this->con->openCursor('books');
+ $c->exportdatas = json_encode($datas);
+ $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ }
+
+ public function addDemoCount($book_id) {
+
+ $r = $this->con->select('SELECT demo_counter,nom FROM books WHERE book_id=\'' . $book_id . '\'');
+ $m = 20;
+ if ($r->demo_counter > 0 && $r->demo_counter % $m == 0) {
+ $mail = new cubeMail();
+ $mail->charset = 'UTF-8';
+ $mail->from = 'contact@fluidbook.com';
+ $mail->to = 'tech@fluidbook.com';
+ $mail->subject = '[Fluidbook Workshop] Fluidbook consulté via l\'url publique';
+ $mail->body = 'Le fluidbook suivant a été consulté ' . $m . ' fois (et ' . $r->demo_counter . ' au total) via l\'url publique : ' . "\r\n" .
+ 'Fluidbook # ' . $book_id . ' - ' . $r->nom;
+ $mail->send();
+ }
+
+ $this->con->select('UPDATE books SET demo_counter=demo_counter+1 WHERE book_id=\'' . $book_id . '\'');
+ }
+
+ public function selectByIds($book_ids = array(), $simple = false) {
+ if ($simple) {
+ $table = 'books';
+ } else {
+ $table = 'books_vue';
+ }
+ $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_time<composition_update AND version=2 ORDER BY book_id ASC LIMIT 1';
+ $r = $this->con->select($sql);
+ return $this->factory($r);
+ }
+
+ public function selectLuceneTimeNotSet() {
+ $sql = 'SELECT * FROM books_vue WHERE lucene_time=0 AND version=2';
+ $r = $this->con->select($sql);
+ return $this->factory($r);
+ }
+
+ /**
+ * wsDAOBook::sauve()
+ *
+ * @param mixed $createur
+ * @param mixed $data
+ * @return
+ */
+ public function sauve($createur, $data) {
+ $c = $this->con->openCursor('books');
+ if (isset($data['nom'])) {
+ $c->nom = $data['nom'];
+ }
+ if (isset($data['lang'])) {
+ $c->lang = $data['lang'];
+ }
+ if (isset($data['theme'])) {
+ $c->theme = $data['theme'];
+ }
+ if (isset($data['proprietaire'])) {
+ $c->proprietaire = $data['proprietaire'];
+ }
+
+ if ($data['book_id'] == 'new' || $data['book_id'] == '') {
+ $c->date = TIME;
+ $c->hash = md5(rand(0, 123456789365469));
+ $c->compteur_visites = 20;
+ $c->parametres = serialize(new wsParametres());
+ $c->changedate = TIME;
+ $book_id = $c->book_id = $this->getNextId();
+
+ $c->insert();
+ } else {
+ $c->changedate = TIME;
+ $book_id = $data['book_id'];
+ $c->update('WHERE book_id=\'' . $this->con->escape($data['book_id']) . '\'');
+ }
+
+ 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', '<extras>' . $book->extras . '</extras>', false, true, 'XML');
+ $flex->addVariable('numerotation', $book->numerotation, false, true, 'String');
+ $flexLight->addVariable('theme', $theme->parametres->toStandardObject(), false, true, 'JSONObject');
+ $flexLight->addVariable('pages', $book->parametres->pages);
+ $flexLight->addVariable('fwidth', round($size[0], 4), false, true, 'Number');
+ $flexLight->addVariable('fheight', round($size[1], 4), false, true, 'Number');
+ $flexLight->addVariable('pagesInDatas', $complete, false, true, 'Boolean');
+ $flex->addVariable('index', $index, false, true, 'JSONObject', false, false);
+ $flex->addVariable('textes', $textes, false, true, 'JSONObject', false, false);
+
+ $rasterized = array();
+ $sizes = array();
+
+ foreach ($pages as $i => $infos) {
+ $base = 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('/(?<!^)(?!$)/u', $chars);
+ $chars = array_unique($chars);
+
+ $flex->addFont(WS_FILES . '/fonts/FluidbookMultilang.ttf', 'MultilangFont', $chars);
+ $flex->addVariable('langNames', $langNames, false, true, 'JSONObject');
+ $flex->addVariable('countryNames', $countryNames, false, true, 'JSONObject');
+ }
+ $flexLight->addVariable('lang', $book->lang);
+
+ // Basket
+ if ($book->parametres->basket) {
+ $formats = array('jpg', 'png', 'jpeg');
+ $referencesFile = $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