--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 15.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">\r
+<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+ width="20px" height="20px" viewBox="0 0 20 20" enable-background="new 0 0 20 20" xml:space="preserve">\r
+<path fill="$colorize" d="M16.811,0.935H2.921c-1.13,0-2.055,0.925-2.055,2.055v13.893c0,1.131,0.925,2.055,2.055,2.055h13.889\r
+ c1.131,0,2.056-0.924,2.056-2.055V2.99C18.866,1.859,17.941,0.935,16.811,0.935z M15.828,6.942c-0.569,0-1.183,0-1.474,0\r
+ S13.77,7.248,13.77,7.474s0,1.514,0,1.514s1.818,0,2.055,0c-0.082,1.161-0.252,2.224-0.252,2.224h-1.813v6.581h-2.702v-6.581H9.741\r
+ V8.996h1.316c0,0,0-1.48,0-1.811c0-0.332-0.067-2.548,2.769-2.548c0.381,0,1.244,0,2.003,0C15.828,5.6,15.828,6.641,15.828,6.942z"\r
+ />\r
+</svg>\r
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 15.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">\r
+<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+ width="20px" height="20px" viewBox="0 0 20 20" enable-background="new 0 0 20 20" xml:space="preserve">\r
+<path fill="$colorize" d="M19,3.055C19,1.92,18.08,1,16.944,1H3.056C1.92,1,1,1.92,1,3.055v13.89C1,18.08,1.92,19,3.056,19h13.889\r
+ C18.08,19,19,18.08,19,16.945V3.055z M14.871,10.326c-1.059,4.3-8.175,6.125-11.448,1.66c1.254,1.197,3.438,1.304,4.822-0.13\r
+ c-0.812,0.119-1.403-0.678-0.405-1.108c-0.897,0.098-1.396-0.379-1.6-0.785c0.21-0.22,0.443-0.323,0.891-0.352\r
+ C6.148,9.379,5.786,8.898,5.675,8.315C5.947,8.25,6.288,8.194,6.474,8.219c-0.859-0.45-1.158-1.126-1.111-1.636\r
+ c1.537,0.571,2.517,1.03,3.335,1.469c0.292,0.156,0.618,0.437,0.985,0.793c0.467-1.237,1.045-2.513,2.035-3.146\r
+ c-0.017,0.144-0.094,0.277-0.195,0.386c0.281-0.255,0.645-0.431,1.016-0.481c-0.043,0.278-0.442,0.436-0.685,0.525\r
+ c0.184-0.057,1.157-0.491,1.262-0.243c0.127,0.28-0.672,0.411-0.806,0.459c-0.103,0.034-0.203,0.072-0.302,0.112\r
+ c1.233-0.124,2.411,0.895,2.755,2.159c0.024,0.092,0.049,0.193,0.071,0.298c0.452,0.169,1.269-0.007,1.531-0.17\r
+ C16.176,9.198,15.681,9.53,14.95,9.59c0.352,0.146,1.016,0.228,1.473,0.15C16.134,10.051,15.668,10.332,14.871,10.326z"/>\r
+</svg>\r
$db->books->numerotation('text', 0, false);\r
$db->books->changedate('integer', 0, false);\r
$db->books->compiledate('integer', 0, false);\r
- $db->books->version('integer',0,false,2);\r
+ $db->books->version('integer', 0, false, 2);\r
+ $db->books->composition_update('integer', 0, false);\r
// Clés\r
$db->books->primary('pk_books', 'book_id');\r
$db->books->index('index_books_nom', 'BTREE', 'nom');\r
<?php\r
+\r
class wsServices extends cubeFlashGateway {\r
const CNAME = __CLASS__;\r
- public static function in($args)\r
- {\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
- {\r
+ public function sendEmail() {\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
$mail->to = $this->args['email'];\r
$mail->from = $this->args['fromname'] . '<' . $this->args['fromemail'] . '>';\r
$mail->subject = $this->args['subject'];\r
- /*if ($this->args['attachPDFInEmail'] == '1') {\r
- $doc_name = isset($this->args['attachmentName'])?$this->args['attachmentName']:'document.pdf';\r
- $file = fwsConverter::extractPages($this->args['id'], $this->args['attachPDFInEmail'], false);\r
- $mail->addFile($doc_name, $file);\r
- }*/\r
+ /* if ($this->args['attachPDFInEmail'] == '1') {\r
+ $doc_name = isset($this->args['attachmentName'])?$this->args['attachmentName']:'document.pdf';\r
+ $file = fwsConverter::extractPages($this->args['id'], $this->args['attachPDFInEmail'], false);\r
+ $mail->addFile($doc_name, $file);\r
+ } */\r
$mail->body = $this->args['body'];\r
- $this->xml->addChild('ok', $mail->send()?'1':'0');\r
+ $this->xml->addChild('ok', $mail->send() ? '1' : '0');\r
}\r
\r
- protected function shortenURL($url, $id)\r
- {\r
+ protected function shortenURL($url, $id) {\r
$bitLyUser = 'fluidbook';\r
$bitLyKey = 'R_3858dd1c9884d5c6a5fe386d7e95cf1d';\r
// Recherche dans le cache\r
*\r
* @return\r
*/\r
- public function facebook_thumbnail()\r
- {\r
+ public function facebook_thumbnail() {\r
$this->outputXML = false;\r
$dao = new wsDAOBook($this->con);\r
$pages = $dao->getPagesOfBook($this->args['id']);\r
exit;\r
}\r
\r
- public function facebookShare()\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 twitterShare()\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/?status=' . $post);\r
+ http::redirect('http://twitter.com/intent/tweet?source=webclient&text=' . $post);\r
exit;\r
}\r
\r
- public function exportpdf()\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
+ foreach ($query->getQueryTerms() as $t) {\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
+ }\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 exportpdf() {\r
global $core;\r
\r
$daoBook = new wsDAOBook($core->con);\r
mkdir($destDir, 0777, true);\r
}\r
$fname = md5(implode(',%ù', $range)) . '.pdf';\r
- $destFile = $destDir . '/' . $fname ;\r
+ $destFile = $destDir . '/' . $fname;\r
$destURL = '/fluidbook/cache/exportpdf/' . $book->book_id . '/' . $fname;\r
// If result exists, don't make the pdf again\r
if (file_exists($destFile) && filemtime($destFile) > filemtime($baseDocument)) {\r
}\r
// Prepare the command line\r
$l = array('A=' . $baseDocument, 'cat');\r
- foreach($range as $page) {\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
+ $l[] = $destFile;\r
\r
$args = implode(' ', $l);\r
// Execute the command line\r
http::redirect($destURL);\r
exit;\r
}\r
+\r
}\r
\r
?>
\ No newline at end of file
$book->tache = $r->tache;\r
$book->projet = $r->projet;\r
$book->version = $r->version;\r
+ $book->composition_update = $r->composition_update;\r
\r
return $book;\r
}\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
return $this->selectById($book_id);\r
}\r
\r
- public function duplicate($book_id, $createur, $nom,$pages=false) {\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
+ $old_id = $book_id;\r
+\r
$parametres = unserialize($r->parametres);\r
$parametres->setParent($this);\r
$parametres->title = $nom;\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->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
+ 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
\r
$c->changedate = TIME;\r
$c->compiledate = TIME;\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
$c->parametres = serialize($parametres);\r
$c->numerotation = implode(',', $numerotation);\r
$c->changedate = TIME;\r
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');\r
-\r
- $this->con->execute('DELETE FROM book_pages WHERE book_id=\'' . $this->con->escape($book_id) . '\'');\r
\r
- $c = $this->con->openCursor('book_pages');\r
- $c->book_id = $book_id;\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
- $c->document_id = $p->document_id;\r
- $c->document_page = $p->document_page;\r
- $c->book_page = $i;\r
- $c->insert();\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
+ $c = $this->con->openCursor('book_pages');\r
+ $c->book_id = $book_id;\r
+ $i = 1;\r
+ foreach ($pages as $p) {\r
+ $c->document_id = $p->document_id;\r
+ $c->document_page = $p->document_page;\r
+ $c->book_page = $i;\r
+ $c->insert();\r
+ $i++;\r
+ }\r
+ $c->composition_update = TIME;\r
+ }\r
+\r
+ $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');\r
}\r
\r
public function makeTextsIndexes($book_id, &$index, &$textes) {\r
}\r
\r
$this->compilePDF($book, $pages);\r
+ $this->indexPDF($book, $pages);\r
$this->touchCompile($book_id);\r
\r
return $res;\r
}\r
\r
+ public function indexPDF($book, $pages) {\r
+ $indexPath = WS_BOOKS . '/search/' . $book->book_id;\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
+\r
public function compilePDF($book, $pages) {\r
$finalPDF = WS_BOOKS . '/final/' . $book->book_id . '/data/document.pdf';\r
\r
return;\r
}\r
\r
+ if (file_exists($finalPDF)) {\r
+ $fmtime = filemtime($finalPDF);\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
+ if (!$invalid) {\r
+ return;\r
+ }\r
+ }\r
+ }\r
+\r
$pdfList = array();\r
$pagesList = array();\r
$nb_pages = array();\r
}\r
}\r
\r
- fb($ranges);\r
-\r
foreach ($ranges as $range) {\r
$args .= ' ' . $range['lettre'] . $range['start'];\r
if ($range['start'] == $range['end']) {\r
$pdftk->setPath(CONVERTER_PATH);\r
$pdftk->setManualArg($args);\r
$pdftk->execute();\r
-\r
- fb($pdftk->commande);\r
- fb($pdftk->output);\r
}\r
\r
}\r
protected $specialRulers;\r
protected $changedate;\r
protected $compiledate;\r
+ protected $composition_update;\r
protected $version;\r
+ \r
\r
public function __get($varname) {\r
if (!property_exists($this, $varname)) {\r
$arrowsColor = '#' . $this->theme->parametres->arrowsColor;\r
// Set the icon list with the color\r
$icons = array('nav-bookmark' => $couleurI, 'nav-friend' => $couleurI, 'nav-help' => $couleurI, 'nav-index' => $couleurI, 'nav-sommaire' => $couleurI,\r
- 'next' => $arrowsColor, 'previous' => $arrowsColor, 'search' => $couleurI);\r
+ 'next' => $arrowsColor, 'previous' => $arrowsColor, 'search' => $couleurI,'nav-facebook'=>$couleurI,'nav-twitter'=>$couleurI);\r
\r
foreach ($icons as $icon => $color) {\r
wsTools::colorizeAndRasterizeIcon($this->theme->parametres->iconSet, $icon, $color, $this->vdir . '/data/images/', 4, $w, $h);\r
$res = array_merge($res, $links);\r
$res[] = '.link a.displayArea:hover,.link a.displayArea.animating{background-color:' . self::colorToCSS($this->theme->parametres->linksColor, 0.4) . ';}';\r
\r
+ // Menus\r
+ # View\r
+ $res[] = '.portrait #view{width:' . $w . ';min-height:' . $h . '}';\r
+ $res[] = '.landscape #view{width:' . $w2 . ';min-height:' . $h . '}';\r
+ $res[] = '#view{background-color:' . self::colorToCSS($this->theme->parametres->couleurB) . ';color:' . self::colorToCSS($this->theme->parametres->subTextColor) . ';}';\r
+ # Index\r
+ $ratio = $this->book->parametres->width / $this->book->parametres->height;\r
+ $thumbh = round(100 / $ratio);\r
+ $res[] = '#index .thumb img{width:100px;height:' . $thumbh . 'px;}';\r
+ $res[] = '#index .doubleThumb{height:' . $thumbh . 'px;' . $this->writeCSSUA('box-shadow', '0 0 3px ' . $shadowColor) . '}';\r
+\r
// Pages styles\r
foreach ($this->cssColor as $color => $index) {\r
$res[] = '.c' . $index . '{color:#' . $color . '}';\r
}\r
\r
public function copyLinkFile($source, $dest, $video=false) {\r
-\r
+ // TODO delete that return;\r
+ return;\r
$origDir = WS_BOOKS . '/working/' . $this->book_id . '/';\r
$types = array('mp4', 'ogv', 'webm', 'jpg');\r
if ($video) {\r
\r
foreach ($source as $so) {\r
$s = $origDir . $so;\r
- fb($s);\r
if (file_exists($s)) {\r
$d = $this->vdir . '/' . $dest . '/' . $so;\r
if (!file_exists(dirname($d))) {\r