use App\Models\FluidbookPublication;
use App\Models\FluidbookTheme;
use App\Models\Traits\FluidbookPlayerBranches;
+use App\Util\FluidbookLinks;
use Cubist\Util\ArrayUtil;
use Cubist\Util\CommandLine;
use Cubist\Util\Files\Files;
use Cubist\Util\Graphics\Image;
use Cubist\Util\ObjectUtil;
use Cubist\Util\PHP;
+use Cubist\Util\Text;
use Cubist\Util\Url;
use DOMDocument;
use DOMElement;
continue;
}
- $e = CubeIT_Text::multiExplode('_-.', mb_strtolower($file->getFilename()));
+ $e = Text::multiExplode('_-.', mb_strtolower($file->getFilename()));
$ean = $this->findEAN($e);
if (!$ean) {
continue;
$file = $cdir . $this->fluidbookSettings->basketReferences;
$this->config->basketReferences = wsUtil::excelToArrayKeyVars($file);
- wsLinks::getLinksAndRulersFromFile($this->book_id, $links, $rulers);
+ FluidbookLinks::getLinksAndRulers($this->book_id, $links, $rulers);
foreach ($links as $link) {
if ($link['type'] == '12') {
$file = $cdir . $this->fluidbookSettings->basketReferences;
$this->config->basketReferences = wsUtil::excelToArrayKeyVars($file);
- wsLinks::getLinksAndRulersFromFile($this->book_id, $links, $rulers);
+ FluidbookLinks::getLinksAndRulers($this->book_id, $links, $rulers);
foreach ($this->config->basketReferences as $ref => $data) {
$source = $cdir . '/' . $data['Image'];
if (!file_exists($source)) {
continue;
}
- $d = CubeIT_Text::str2URL($ref) . '.jpg';
+ $d = Text::str2URL($ref) . '.jpg';
$dest = $odir . '/' . $d;
if (!file_exists($dest) || !filesize($dest) || filemtime($dest) < filemtime($source)) {
$convert = new Image_Resizer_ImageMagick();
$this->vdir->copy($cdir . $f, 'data/commerce/' . $f);
}
- wsLinks::getLinksAndRulersFromFile($this->book_id, $links, $rulers);
+ FluidbookLinks::getLinksAndRulers($this->book_id, $links, $rulers);
}
public function writeGrandPavoisCart()
$file = $cdir . $this->fluidbookSettings->basketReferences;
$this->config->basketReferences = wsUtil::excelToArrayKeyVars($file);
- wsLinks::getLinksAndRulersFromFile($this->book_id, $links, $rulers);
+ FluidbookLinks::getLinksAndRulers($this->book_id, $links, $rulers);
}
$this->config->eanReferences = wsUtil::excelToArrayIndexKeyVars($eanFile);
}
- wsLinks::getLinksAndRulersFromFile($this->book_id, $links, $rulers);
+ FluidbookLinks::getLinksAndRulers($this->book_id, $links, $rulers);
foreach ($links as $link) {
if ($link['type'] == '12' && isset($this->config->basketReferences[$link['to']])) {
$this->config->basketReferences[$link['to']]['zoom_image'] = 'data/links/zoom_' . $link['uid'] . '.jpg';
public function writeGPUDatabase()
{
- global $core;
$r = $core->con->select('SELECT gpu,rgpu,score FROM gpu');
$gpu = [];
while ($r->fetch()) {
public function getResolutions()
{
- return self::getBookResolutions($this->book);
+ return self::getBookResolutions($this->getFluidbook());
}
+
public static function getBookResolutions($book)
{
- $maxRes = min(300, $book->parametres->maxResolution);
+ $maxRes = min(self::MAX_RES, $book->settings['maxResolution']);
$res = [];
- if ($maxRes == 300) {
- $res = [150, 300];
+ if ($maxRes == self::MAX_RES) {
+ $res = [150, self::MAX_RES];
} else if ($maxRes <= 150) {
$res = [$maxRes];
}
$this->log('Start compile process');
// Raw copy of some directories
- $directories = array('style/fonts/OpenSans', 'images', 'sound', 'video');
+ $directories = array('style/fonts/OpenSans', 'images', 'sound');
foreach ($directories as $directory) {
$from = $this->assets . '/' . $directory;
$this->vdir->copyDirectory($from, $directory);
protected function writeStats()
{
- global $core;
if ($this->fluidbookSettings->stats) {
$this->config->statsMatomo = $this->book_id;
protected function _labelToPage($k)
{
- global $core;
$k = trim($k, '#/');
$k = str_replace('page/page', 'page', $k);
}
if (preg_match('/^page\/(.+)$/', $k, $matches)) {
- $matches[1] = CubeIT_Util_Text::removeAccents($matches[1]);
+ $matches[1] = Text::removeAccents($matches[1]);
$matches[1] = mb_strtolower($matches[1]);
if (isset($this->pageLabels[$matches[1]])) {
return 'page/' . $this->pageLabels[$matches[1]];
protected function writeSecure()
{
- if ($this->fluidbookSettings->secureClientSidePassword !== '') {
- $credentials = CubeIT_Text::explodeNewLines($this->fluidbookSettings->secureClientSidePasswordCredentials);
+ if ($this->fluidbookSettings->secureClientSidePassword) {
+ $credentials = Text::explodeNewLines($this->fluidbookSettings->secureClientSidePasswordCredentials);
$credentials[] = 'fluidbook:LatacaM4##*';
$users = [];
foreach ($credentials as $credential) {
});
});', $secure);
$this->vdir->file_put_contents('secure.html', $secure);
-
$this->config->secureClientSidePasswordCredentials = $users;
}
$text = trim($text);
$text = str_replace(array_keys($replace), array_values($replace), $text);
- $text = CubeIT_Text::cleanUTF8($text, '');
+ $text = Text::cleanUTF8($text, '');
if ($this->fluidbookSettings->audiodescriptionVoice) {
$hash = hash('sha256', $this->fluidbookSettings->audiodescriptionVoice . '_^_' . $text);
public function getIndexVars()
{
if (null === $this->_indexVars) {
- global $core;
$titre = $this->fluidbookSettings->title;
$symbols = array_merge($symbols, $this->_getSVGSymbols($svgfile));
}
$symbols = array_merge($symbols, $this->_svgSymbols);
- return '<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">' . str_replace('> <', '><', CubeIT_Util_Text::removeNewLines(implode('', $symbols))) . '</svg>';
+ return '<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">' . str_replace('> <', '><', Text::removeNewLines(implode('', $symbols))) . '</svg>';
}
protected function _getSVGSymbols($svg)
public function addContentLock($page, $unlockConditions = '')
{
$this->config->hasContentLock = true;
- $unlockConditions = CubeIT_Text::explodeNewLines($unlockConditions);
+ $unlockConditions = Text::explodeNewLines($unlockConditions);
$conditions = [];
foreach ($unlockConditions as $unlockCondition) {
$e = explode(',', $unlockCondition);
{
$variables = [];
$f = str_replace("\r", "\n", $f);
- $e = CubeIT_Text::explodeNewLines($f);
+ $e = Text::explodeNewLines($f);
foreach ($e as $item) {
$item = trim($item);
if ($item == '') {
if (!$this->config->pdfName) {
$this->config->pdfName = 'document.pdf';
}
- $this->config->pdfName = CubeIT_Text::removeAccents($this->config->pdfName);
+ $this->config->pdfName = Text::removeAccents($this->config->pdfName);
if (mb_strtolower(substr($this->config->pdfName, -4)) !== '.pdf') {
$this->config->pdfName .= '.pdf';
}
protected function writeLangs()
{
- global $core;
$daoLang = new wsDAOLang($core->con);
$lang = $daoLang->selectById($this->getFluidbook()->lang);
$langs = $daoLang->selectAll();
protected function writeLinks()
{
- global $core;
switch ($this->fluidbookSettings->customLinkClass) {
case 'WescoSalesLink':
if ($this->fluidbookSettings->externalChaptersHTML != '') {
$d = $this->unzipFile($this->fluidbookSettings->externalChaptersHTML, false, 'data/chapters/');
$meta = $this->getConfigZIP($d['dir']);
- $this->config->externalChaptersSize = new stdClass();
+ $this->config->externalChaptersSize = new \stdClass();
$this->config->externalChaptersSize->width = $meta['width'];
$this->config->externalChaptersSize->height = $meta['height'];
$this->vdir->copyDirectory($d['dir'], $d['fdir']);
}
- wsLinks::getLinksAndRulersFromFile($this->book_id, $links, $rulers);
+ FluidbookLinks::getLinksAndRulers($this->book_id, $links, $rulers);
if ($this->fluidbookSettings->basketManager === 'Puma') {
foreach ($links as $k => $init) {
$anchorExists[$linkData['to']] = $linkData;
}
if ($linkData['type'] == 35 || $linkData['type'] == 15 || $linkData['type'] == 39) {
- $linkData = wsLinks::decryptLink($linkData);
+ $linkData = FluidbookLinks::decryptLink($linkData);
$animations = contentLink::parseAnimations($linkData['image_rollover']);
foreach ($animations as $animation) {
if (isset($animation['backgroundcolor']) && $animation['backgroundcolor'] !== 'transparent') {
$aliases = [];
$anchors = [];
for ($i = 0; $i <= 2; $i++) {
- $lines = CubeIT_Util_Text::explodeNewLines(file_get_contents($this->fluidbookSettings->anchorsAliases));
+ $lines = Text::explodeNewLines(file_get_contents($this->fluidbookSettings->anchorsAliases));
foreach ($lines as $line) {
$e = explode("\t", $line);
$from = anchorLink::normalizeAnchor($e[0]);
public function addSEOArticle($page, $title, $intro, $image, $id = null, $url = null, $content = '')
{
if (null === $url) {
- $url = CubeIT_Text::str2URL($title) . '.html';
+ $url = Text::str2URL($title) . '.html';
}
if (null === $id) {
$id = $title;
$js .= file_get_contents($f);
$js .= ";\n\n";
}
- $tmp = cubeFiles::tempnam();
+ $tmp = Files::tempnam();
file_put_contents($tmp, $js);
if (file_exists($minimized)) {
protected function writeImages()
{
- global $core;
-
- wsBook::precompileImages($this->book_id);
-
switch ($this->fluidbookSettings->mobileVersion) {
case 'html5-desktop':
$this->backgroundsPrefix = array(true, false);
foreach ($thisbackgroundPrefix as $backgroundsPrefix) {
$source = $this->getFluidbook()->getFile($page, $this->imageFormat, $r, $backgroundsPrefix, true, $imdir);
if ($r === $this->maxRes) {
- $this->getPageDimension($infos, $page);
+ $this->getPageDimension($page);
}
$this->vdir->copy($source, 'data/background/' . $r . '/' . ($backgroundsPrefix ? 't' : 'p') . $page . '.' . $this->imageFormat);
}
, 'data/contents/p' . $page . '.svg');
}
- $this->vdir->copy($this->getFluidbook()->getThumbFile($page, $this->imageFormat), 'data/thumbnails/p' . $page . '.' . $this->imageFormat);
+ $this->vdir->copy($this->getFluidbook()->getFile($page, $this->imageFormat, 'thumb'), 'data/thumbnails/p' . $page . '.' . $this->imageFormat);
$this->log('Made image page ' . $page);
}
+
$this->_makeCover($this->getFluidbook()->getFile(1, 'jpg', 150, true, true));
+ $this->log('Made cover for apps');
$this->log('Made images');
}
- protected function getPageDimension($infos, $page)
+ protected function getPageDimension($page)
{
- global $core;
- if (!isset($this->_docDimensions[$infos['document_id']])) {
- $daoDoc = new wsDAODocument($core->con);
- $firstDoc = $daoDoc->selectById($infos['document_id']);
- $this->_docDimensions[$infos['document_id']] = $firstDoc->generalInfos['page'];
- }
- $d = $this->_docDimensions[$infos['document_id']][$infos['document_page']]['size'];
+ $d = $this->getFluidbook()->getDocumentSize($page);
$this->config->pagesDimensions[$page] = array($this->cssWidth, $d[1] * ($this->cssWidth / $d[0]));
}
protected function _makeCover($orig)
{
- $size = Image::getimagesize($orig);
- $w = $size[0];
- $h = $size[1];
+ $cached = $this->wdir . '/_cover.jpg';
- $tmp = cubeFiles::tempnam() . '.png';
+ if (!file_exists($cached) || filemtime($cached) < filemtime($orig)) {
+ $size = Image::getimagesize($orig);
+ $w = $size[0];
+ $h = $size[1];
- $c = new CommandLine('convert');
- $c->setArg(null, ROOT . '/images/ws/shade-cover-app.png');
- $c->setManualArg('-resize ' . round($w / 3) . 'x' . $h);
- $c->setArg(null, $tmp);
- $c->execute();
+ $tmp = Files::tempnam() . '.png';
- $res = cubeFiles::tempnam() . '.jpg';
+ $c = new CommandLine('convert');
+ $c->setArg(null, resource_path('fluidbookpublication/cover/shade-cover-app.png'));
+ $c->setManualArg('-resize ' . round($w / 3) . 'x' . $h);
+ $c->setArg(null, $tmp);
+ $c->execute();
- $convert = new CommandLine('composite');
- $cmd = '-compose Multiply ';
- $cmd .= $tmp . ' ' . $orig . ' ';
- $cmd .= $res;
- $convert->setManualArg($cmd);
- $convert->execute();
+ $convert = new CommandLine('composite');
+ $cmd = '-compose Multiply ';
+ $cmd .= $tmp . ' ' . $orig . ' ';
+ $cmd .= $cached;
+ $convert->setManualArg($cmd);
+ $convert->execute();
- $this->vdir->copy($res, 'cover.jpg', true);
+ unlink($tmp);
+ }
+ $this->vdir->copy($cached, 'cover.jpg', true);
- unlink($tmp);
}
protected function _lessBoolean($val)
public function writeXMLArticles()
{
$f = $this->fluidbookSettings->articlesFile;
+ if (!$f || !file_exists($this->wdir . '/' . $f) || !is_file($this->wdir . '/' . $f)) {
+ return;
+ }
+
$this->lessVariables['articles-title-color'] = '#000000';
$this->lessVariables['articles-font'] = 'Open Sans';
- if ($f !== '' && file_exists($this->wdir . '/' . $f)) {
- $f = $this->wdir . '/' . $f;
+ $f = $this->wdir . '/' . $f;
- $mapFonts = ['OpenSans' => 'Open Sans'];
- $this->addLess('articles');
- if ($this->fluidbookSettings->articlesStyle !== 'default') {
- $this->lessVariables['articles-styles'] = $this->fluidbookSettings->articlesStyle;
- }
- $this->lessVariables['articles-font'] = $mapFonts[$this->fluidbookSettings->articlesFont] ?? $this->fluidbookSettings->articlesFont;
- $fontPath = $this->addFontKit($this->fluidbookSettings->articlesFont);
+ $mapFonts = ['OpenSans' => 'Open Sans'];
+ $this->addLess('articles');
+ if ($this->fluidbookSettings->articlesStyle !== 'default') {
+ $this->lessVariables['articles-styles'] = $this->fluidbookSettings->articlesStyle;
+ }
+ $this->lessVariables['articles-font'] = $mapFonts[$this->fluidbookSettings->articlesFont] ?? $this->fluidbookSettings->articlesFont;
+ $fontPath = $this->addFontKit($this->fluidbookSettings->articlesFont);
- $list = $this->config->articlesList ?? [];
+ $list = $this->config->articlesList ?? [];
- $this->lessVariables['articles-title-color'] = '#565657';
+ $this->lessVariables['articles-title-color'] = '#565657';
- $svg = '<svg xmlns="http://www.w3.org/2000/svg" style="display: none;"><symbol id="nav-print" viewBox="0 0 512 512">
+ $svg = '<svg xmlns="http://www.w3.org/2000/svg" style="display: none;"><symbol id="nav-print" viewBox="0 0 512 512">
<path d="m424 186l-39 0 0-114c0-9-6-15-14-15l-230 0c-8 0-14 6-14 15l0 114-39 0c-22 0-41 19-41 41l0 121c0 23 19 41 41 41l39 0 0 49c0 8 6 15 14 15l230 0c8 0 14-7 14-15l0-49 39 0c22 0 41-18 41-41l0-121c0-22-19-41-41-41z m-268-100l200 0 0 100-200 0z m200 340l-200 0 0-88 200 0z m80-76c0 6-6 12-12 12l-39 0 0-38c0-9-6-15-14-15l-230 0c-8 0-14 6-14 15l0 38-39 0c-6 0-12-6-12-12l0-121c0-6 6-12 12-12l336 0c6 0 12 6 12 12z m-278-96l-33 0c-8 0-14 6-14 14 0 8 6 15 14 15l35 0c8 0 14-7 14-15 0-8-8-14-16-14z m32 139l132 0c8 0 14-6 14-14 0-8-6-14-14-14l-132 0c-8 0-14 6-14 14 0 8 6 14 14 14z"/>
</symbol></svg>';
- $x = simplexml_load_string(file_get_contents($f));
- foreach ($x->xpath('/articles/article') as $k => $a) {
- $dir = isset($a['dir']) ? (string)$a['dir'] : null;
- $url = (string)$a['url'];
- $id = (string)$a['id'];
- $color = (string)$a['color'];
- if (!$color) {
- $color = '#000';
- }
+ $x = simplexml_load_string(file_get_contents($f));
+ foreach ($x->xpath('/articles/article') as $k => $a) {
+ $dir = isset($a['dir']) ? (string)$a['dir'] : null;
+ $url = (string)$a['url'];
+ $id = (string)$a['id'];
+ $color = (string)$a['color'];
+ if (!$color) {
+ $color = '#000';
+ }
- $specificStyles = '## h3, ## figure figcaption{background-color:' . $color . '}';
- $specificStyles .= '## .chapo, ## blockquote, ## a{color:' . $color . ';}';
+ $specificStyles = '## h3, ## figure figcaption{background-color:' . $color . '}';
+ $specificStyles .= '## .chapo, ## blockquote, ## a{color:' . $color . ';}';
- $inner = '<article data-id="$id" class="menu-article" id="article_$id"';
- if (null !== $dir) {
- $inner .= ' dir="' . $dir . '"';
- }
- $inner .= '>';
- $inner .= '<style type="text/css">' . str_replace('##', '#article_$id', $specificStyles) . '</style>';
- $inner .= '<div class="actions">';
- if ($this->fluidbookSettings->articlesShare && $this->fluidbookSettings->share) {
- $inner .= '<a data-id="$id" data-url="$url" href="#" class="articlesShare"><svg viewBox="0 0 512 512" class="nav-share nav-icon svg-icon"><use xlink:href="#nav-share"></use></svg></a>';
- }
- $inner .= '<a href="#" class="articlesPrint"><svg viewBox="0 0 512 512" class="nav-print nav-icon svg-icon"><use xlink:href="#nav-print"></use></svg></a>';
- $inner .= '</div>';
+ $inner = '<article data-id="$id" class="menu-article" id="article_$id"';
+ if (null !== $dir) {
+ $inner .= ' dir="' . $dir . '"';
+ }
+ $inner .= '>';
+ $inner .= '<style type="text/css">' . str_replace('##', '#article_$id', $specificStyles) . '</style>';
+ $inner .= '<div class="actions">';
+ if ($this->fluidbookSettings->articlesShare && $this->fluidbookSettings->share) {
+ $inner .= '<a data-id="$id" data-url="$url" href="#" class="articlesShare"><svg viewBox="0 0 512 512" class="nav-share nav-icon svg-icon"><use xlink:href="#nav-share"></use></svg></a>';
+ }
+ $inner .= '<a href="#" class="articlesPrint"><svg viewBox="0 0 512 512" class="nav-print nav-icon svg-icon"><use xlink:href="#nav-print"></use></svg></a>';
+ $inner .= '</div>';
- $inner .= '<div class="articleBody">';
+ $inner .= '<div class="articleBody">';
- $title = '';
- $lead = '';
- $image = '';
+ $title = '';
+ $lead = '';
+ $image = '';
- $first = true;
+ $first = true;
- foreach ($a->children() as $child) {
- if ($first) {
- $first = false;
- if ($child->getName() !== 'category') {
- $inner .= '<h3> </h3>';
- }
+ foreach ($a->children() as $child) {
+ if ($first) {
+ $first = false;
+ if ($child->getName() !== 'category') {
+ $inner .= '<h3> </h3>';
}
- $inner .= $this->_articleToHTML($child, $title, $lead, $image, $dir);
}
- $inner .= '</div></article>';
+ $inner .= $this->_articleToHTML($child, $title, $lead, $image, $dir);
+ }
+ $inner .= '</div></article>';
- if (!$title) {
- $title = 'Article sans titre ' . $k;
- }
+ if (!$title) {
+ $title = 'Article sans titre ' . $k;
+ }
- if (!$id) {
- $id = CubeIT_Text::str2URL($title);
- }
+ if (!$id) {
+ $id = Text::str2URL($title);
+ }
- if (!$url) {
- $url = $id . '.html';
- }
+ if (!$url) {
+ $url = $id . '.html';
+ }
- $inner = str_replace(array('$id', '$url'), array($id, $url), $inner);
+ $inner = str_replace(array('$id', '$url'), array($id, $url), $inner);
- $article = ['id' => $id,
- 'url' => $url,
- 'color' => $color,
- 'contents' => '',
- 'type' => 'xml'];
+ $article = ['id' => $id,
+ 'url' => $url,
+ 'color' => $color,
+ 'contents' => '',
+ 'type' => 'xml'];
- $article['contents'] = $inner;
- $content = '<html><head>';
- $content .= '<link rel="stylesheet" type="text/css" href="' . $fontPath . '">';
- $content .= '<link rel="stylesheet" type="text/css" href="style/articles.css">';
- $content .= '<style type="text/css">';
- $content .= str_replace('## ', '', $specificStyles);
- $content .= '</style>';
- $content .= '<style type="text/css" media="screen">*{visibility:hidden}</style>';
- $content .= '</head><body>';
- $content .= $svg;
- $content .= $inner;
- $content .= '</body></html>';
- $article['print'] = $content;
- $list[] = $article;
+ $article['contents'] = $inner;
+ $content = '<html><head>';
+ $content .= '<link rel="stylesheet" type="text/css" href="' . $fontPath . '">';
+ $content .= '<link rel="stylesheet" type="text/css" href="style/articles.css">';
+ $content .= '<style type="text/css">';
+ $content .= str_replace('## ', '', $specificStyles);
+ $content .= '</style>';
+ $content .= '<style type="text/css" media="screen">*{visibility:hidden}</style>';
+ $content .= '</head><body>';
+ $content .= $svg;
+ $content .= $inner;
+ $content .= '</body></html>';
+ $article['print'] = $content;
+ $list[] = $article;
- $this->addSEOArticle('#/article/' . $article['url'], $title, $lead, $image, $article['id'], $article['url'], $inner);
- }
+ $this->addSEOArticle('#/article/' . $article['url'], $title, $lead, $image, $article['id'], $article['url'], $inner);
}
if (isset($list)) {
$this->config->articlesList = $list;
}
-
}
public function findArticleById($id)
--- /dev/null
+<?php
+
+namespace App\Util;
+
+use Cubist\Util\ArrayUtil;
+use Cubist\Util\Crypt;
+use Cubist\Util\Files\Files;
+use Cubist\Util\ObjectUtil;
+use SodiumException;
+
+class FluidbookLinks
+{
+ protected static $_testLinkCache = null;
+ protected static $_linksKey = null;
+
+ public static function linksToExcel($links, $rulers, $pages = null)
+ {
+ set_time_limit(0);
+
+ $cols = array(
+ 'uid' => __('Identifiant unique'),
+ 'page' => __('Page de la publication'), 'left' => __('x'), 'top' => __('y'), 'width' => __('Largeur'), 'height' => __('Hauteur'), 'rot' => __('Rotation'),
+ 'type' => __('Type'), 'to' => __('Destination'), 'target' => __('Cible'),
+ 'infobulle' => __('Infobulle'), 'numerotation' => __('Numérotation'),
+ 'display_area' => __('Activer la surbrillance'),
+ 'video_loop' => __('Video : boucle'), 'video_auto_start' => __('Video : démarrage automatique'), 'video_controls' => __('Vidéo : afficher les contrôles'), 'video_sound_on' => __('Vidéo : activer le son'),
+ 'inline' => __('Vidéo : afficher dans la page'), 'video_width' => __('Vidéo : Largeur du popup'), 'video_height' => __('Vidéo : Hauteur du popup'),
+ 'interactive' => __('Interactivité'), 'video_service' => __('Webvideo : service'),
+ 'extra' => __('Paramètre supplémentaire'),
+ 'alternative' => __('Alternative'),
+ 'read_mode' => __('Mode de lecture'),
+ 'image' => __('Image'), 'image_rollover' => __('Animation au survol'),
+ 'animation' => __('Animation'),
+ 'group' => __('Groupe'),
+ 'zindex' => __('Profondeur'),
+ );
+
+ $comments = array();
+
+ $xls = new PHPExcel();
+ $s = $xls->setActiveSheetIndex(0);
+ $s->setTitle('Links');
+
+ // Labels
+ $i = 0;
+ foreach ($cols as $id => $label) {
+ $s->setCellValueByColumnAndRow($i, 1, $id);
+ $s->getColumnDimensionByColumn($i)->setAutoSize(true);
+ $s->getStyleByColumnAndRow($i, 1)->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
+ $i++;
+ }
+
+ // Links
+ self::_correctImageSpecialLinks($links);
+ $j = 2;
+ foreach ($links as $l) {
+ $i = 0;
+ foreach ($cols as $id => $label) {
+ if (($id == 'document_id' || $id == 'document_page')) {
+ if (!is_null($pages)) {
+ $infos = $pages[$l['page']];
+ $value = $infos[$id];
+ } else {
+ $value = '';
+ }
+ } else {
+
+ if (isset($l[$id])) {
+ if (is_bool($l[$id])) {
+ $l[$id] = $l[$id] ? '1' : '0';
+ }
+ if ($id === 'numerotation') {
+ if ($l[$id] === 'false') {
+ $l[$id] = 'physical';
+ }
+ }
+ if ($id === 'to') {
+ $s->getCellByColumnAndRow($i, $j)->setDataType(PHPExcel_Cell_DataType::TYPE_STRING)->getStyle()->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_TEXT);
+ }
+ $value = $l[$id];
+ } else {
+ $value = '';
+ }
+ }
+
+ $s->setCellValueExplicitByColumnAndRow($i, $j, $value);
+ $i++;
+ }
+ $j++;
+ }
+ // Rulers
+ $s = $xls->createSheet();
+ $s->setTitle('Rulers');
+
+ $rcols = array('page', 'type', 'pos');
+ $i = 0;
+ // Labels
+ foreach ($rcols as $id) {
+ $s->setCellValueByColumnAndRow($i, 1, $id);
+ $s->getColumnDimensionByColumn($i)->setAutoSize(true);
+ $i++;
+ }
+
+ // Contents
+ $j = 2;
+ foreach ($rulers as $r) {
+ $i = 0;
+ foreach ($rcols as $id) {
+ if (!is_null($pages) && ($id == 'document_id' || $id == 'document_page')) {
+ $infos = $pages[$r['page']];
+ $value = $infos[$id];
+ } else {
+ $value = $r[$id];
+ }
+ $s->setCellValueByColumnAndRow($i, $j, $value);
+ $s->getStyleByColumnAndRow($i, $j)->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_LEFT);
+ $i++;
+ }
+ $j++;
+ }
+
+ $xls->setActiveSheetIndex(0);
+ return $xls;
+ }
+
+
+ public static function getLinksAndRulers($book_id, &$links, &$rulers, $time = 'latest')
+ {
+ if (null === $time) {
+ $time = 'latest';
+ }
+ $dir = self::getLinksDir($book_id);
+
+ $file = $dir . '/' . $time . '.links.gz';
+ if ($time === 'latest' && !file_exists($file)) {
+ $versions = self::getLinksVersions($book_id);
+ foreach ($versions as $version => $m) {
+ copy($dir . '/' . $version . '.links.gz', $dir . '/latest.links.gz');
+ copy($dir . '/' . $version . '.meta.gz', $dir . '/latest.meta.gz');
+ break;
+ }
+ }
+ if (!file_exists($file)) {
+ $links = [];
+ $rulers = [];
+ return;
+ }
+
+ $r = json_decode(gzdecode(file_get_contents($file)), true);
+ $links = $r['links'];
+ $rulers = $r['rulers'];
+
+ self::_correctImageSpecialLinks($links);
+ }
+
+ protected static function _correctImageSpecialLinks(&$links)
+ {
+ foreach ($links as $k => $link) {
+ if (preg_match('/^link_(.*)$/', $link['page'], $matches) && strlen($matches[1]) !== 32) {
+ $uid = $matches[1];
+ foreach ($links as $l) {
+ if ($l['uid'] === $uid && $l['alternative']) {
+ $links[$k]['page'] = 'link_' . md5($l['alternative']);
+ break;
+ }
+ }
+ } else if (preg_match('/^([0-9a-f]{32})$/', $link['page'], $matches)) {
+ $links[$k]['page'] = 'link_' . $matches[1];
+ }
+ }
+ }
+
+ public static function getLinksFromExcel($xls, &$links, &$rulers)
+ {
+ $s = $xls->setActiveSheetIndexByName('Links');
+ $i = 0;
+ $links = array();
+ foreach ($s->getRowIterator() as $row) {
+ $cellIterator = $row->getCellIterator();
+ $cellIterator->setIterateOnlyExistingCells(false);
+ if ($i == 0) {
+ $cols = array();
+ foreach ($cellIterator as $cell) {
+ $cols[] = $cell->getValue();
+ }
+ } else {
+ $link = array();
+ $j = 0;
+ foreach ($cellIterator as $cell) {
+ $link[$cols[$j]] = $cell->getValue();
+ $j++;
+ }
+ if ($link['display_area'] == '' || !$link['display_area']) {
+ $link['display_area'] = '0';
+ }
+ if (trim($link['infobulle']) == '') {
+ $link['infobulle'] = '';
+ }
+ $links[] = $link;
+ }
+
+ $i++;
+ }
+
+ $i = 0;
+ $rulers = array();
+ $s = $xls->setActiveSheetIndexByName('Rulers');
+ foreach ($s->getRowIterator() as $row) {
+ $cellIterator = $row->getCellIterator();
+ $cellIterator->setIterateOnlyExistingCells(false);
+ if ($i == 0) {
+ $cols = array();
+ foreach ($cellIterator as $cell) {
+ $cols[] = $cell->getValue();
+ }
+ } else {
+ $link = array();
+ $j = 0;
+ foreach ($cellIterator as $cell) {
+ $ruler[$cols[$j]] = $cell->getValue();
+ $j++;
+ }
+
+ $rulers[] = $ruler;
+ }
+ $i++;
+ }
+
+ self::_correctImageSpecialLinks($links);
+ }
+
+ public static function getLinksFromAutobookmarkText($txt, &$links, &$rulers)
+ {
+ $links = array();
+ $rulers = array();
+
+ $lines = explode("\n", $txt);
+
+ $protocols = array('mailto' => 3, 'custom' => 7, 'cart' => 12, 'pagelabel' => 26);
+
+ foreach ($lines as $line) {
+ $line = trim($line);
+ if ($line == '') {
+ continue;
+ }
+ if (strpos('#', $line) === 0) {
+ continue;
+ }
+ $target = $numerotation = '';
+ list($page, $left, $top, $width, $height, $type, $to) = explode(';', $line);
+ if ($type <= 2) {
+ $target = '_blank';
+ } elseif ($type == 5) {
+ $numerotation = 'physical';
+ }
+
+ $links[] = array(
+ 'page' => $page,
+ 'left' => $left, 'top' => $top, 'width' => $width, 'height' => $height, 'rot' => '',
+ 'type' => $type, 'to' => $to, 'target' => $target,
+ 'infobulle' => '', 'numerotation' => $numerotation, 'display_area' => '1');
+ }
+
+ self::_correctImageSpecialLinks($links);
+ }
+
+ public static function _getLinkKey()
+ {
+ if (self::$_linksKey === null) {
+ self::$_linksKey = base64_decode('o2p2yYGI8yMEHf+Y5/e6NdTINbbXg3NIo8BODgdhPxI=');
+ }
+ return self::$_linksKey;
+ }
+
+ public static function encryptLinks($links)
+ {
+ $res = [];
+ foreach ($links as $key => $link) {
+ $res[$key] = self::encryptLinkAttrs($link);
+ }
+ return $res;
+ }
+
+ /**
+ * @throws SodiumException
+ */
+ public static function encryptLinkAttrs($link)
+ {
+ if (is_array($link)) {
+ $link = ObjectUtil::asObject($link);
+ }
+
+ $crypted = [13, 14, 35];
+
+ if (!in_array($link->type, $crypted)) {
+ return $link;
+ }
+
+ $attrs = ['image_rollover'];
+ foreach ($attrs as $attr) {
+ if (!isset($link->$attr)) {
+ continue;
+ }
+ $link->$attr = trim($link->$attr);
+ if (strpos($link->$attr, '///') === 0 || $link->$attr == '') {
+ continue;
+ }
+ $link->$attr = '///' . Crypt::safeEncrypt($link->uid . '|||' . $link->$attr, self::_getLinkKey());
+ }
+ return $link;
+ }
+
+ /**
+ * @throws SodiumException
+ */
+ public static function decryptLink($link)
+ {
+ $array = false;
+ if (is_array($link)) {
+ $array = true;
+ $link = ObjectUtil::asObject($link);
+ }
+
+ foreach ($link as $attr => $item) {
+ if (strpos($item, '///') !== 0) {
+ continue;
+ }
+ $v = Crypt::safeDecrypt(substr($item, 3), self::_getLinkKey());
+ $e = explode('|||', $v);
+ if ($e[0] === $link->uid) {
+ $link->$attr = $e[1];
+ } else {
+ $link->$attr = '';
+ }
+ }
+ if (!$array) {
+ return $link;
+ }
+ return ArrayUtil::asArray($link);
+ }
+
+ /**
+ * @throws SodiumException
+ */
+ public static function decryptLinks($links)
+ {
+ $res = [];
+ foreach ($links as $key => $link) {
+ $res[$key] = self::decryptLink($link);
+ }
+ return $res;
+ }
+
+ public static function saveLinksInFile($book_id, $user_id, $comments, $links, $rulers = [], $specialLinks = [], $specialRulers = [])
+ {
+ $lr = self::mergeLinksAndRulers($links, $rulers, $specialLinks, $specialRulers);
+ $meta = ['links' => count($lr['links']), 'rulers' => count($lr['rulers']), 'comments' => $comments, 'user' => $user_id];
+ $base = self::getLinksDir($book_id) . '/' . time();
+ $latestLinks = self::getLinksDir($book_id) . '/latest.links.gz';
+ $latestMeta = self::getLinksDir($book_id) . '/latest.meta.gz';
+ file_put_contents($base . '.meta.gz', gzencode(json_encode($meta)));
+ file_put_contents($base . '.links.gz', gzencode(json_encode($lr)));
+ copy($base . '.links.gz', $latestLinks);
+ copy($base . '.meta.gz', $latestMeta);
+ }
+
+
+ public static function getLinksDir($book_id)
+ {
+ return Files::mkdir('/data1/extranet/www/fluidbook/books/links/' . $book_id);
+ }
+
+ public static function getLinksVersions($book_id, $withLinks = false)
+ {
+ $dir = self::getLinksDir($book_id);
+ $dr = opendir($dir);
+ $updates = [];
+ while ($f = readdir($dr)) {
+ if ($f === '.' || $f === '..') {
+ continue;
+ }
+ $e = explode('.', $f, 2);
+ if ($e[1] !== 'meta.gz' || $e[0] === 'latest') {
+ continue;
+ }
+
+ $updates[$e[0]] = self::getMeta($book_id, $e[0]);
+ }
+ krsort($updates);
+
+ return $updates;
+ }
+
+ public static function getMeta($book_id, $update = 'latest')
+ {
+ return json_decode(gzdecode(file_get_contents(self::getLinksDir($book_id) . '/' . $update . '.meta.gz')), true);
+ }
+
+ public static function mergeLinksAndRulers($links, $rulers, $specialLinks, $specialRulers)
+ {
+ $finalLinks = [];
+ $l = array_merge(self::_getAsArray($links), self::_getAsArray($specialLinks));
+ foreach ($l as $k => $item) {
+ $item['id'] = $k + 1;
+ if (!isset($item['to'])) {
+ $item['to'] = '';
+ }
+ $finalLinks[] = $item;
+ }
+
+ self::_correctImageSpecialLinks($finalLinks);
+
+ return ['links' => self::encryptLinks($finalLinks), 'rulers' => array_merge(self::_getAsArray($rulers), self::_getAsArray($specialRulers))];
+ }
+
+ protected static function _getAsArray($v)
+ {
+ if (is_array($v)) {
+ return $v;
+ }
+ return json_decode($v, true);
+ }
+
+ public static function addLinksFromPDF($book_id)
+ {
+ global $core;
+
+ $daoBook = new wsDAOBook($core->con);
+ $pages = $daoBook->getPagesOfBook($book_id);
+
+ $booleans = array('video_loop', 'video_auto_start', 'video_controls', 'video_sound_on');
+ $numbers = ['left', 'top', 'width', 'height'];
+
+ $links = [];
+
+ foreach ($pages as $page => $info) {
+ $csv = wsDocument::getDir($info['document_id']) . '/p' . $info['document_page'] . '.csv';
+ if (!file_exists($csv) && file_exists($csv . '.gz')) {
+ $csv = 'compress.zlib://' . $csv . '.gz';
+ } elseif (!file_exists($csv)) {
+ continue;
+ }
+
+ $newformat = (filemtime($csv) > 1363685416);
+
+ $fp = fopen($csv, 'rb');
+
+ while (true) {
+ $line = fgetcsv($fp, 512, ';', '"');
+ // End of file
+ if (!$line) {
+ break;
+ }
+ // Commentaire || ligne vide
+ if (substr($line[0], 0, 1) == '#' || is_null($line[0])) {
+ continue;
+ }
+
+ $link = [];
+ if ($newformat) {
+ $cols = array('page' => '', 'left' => '', 'top' => '', 'width' => '', 'height' => '', 'type' => '', 'to' => '', 'target' => '_blank', 'video_loop' => true, 'video_auto_start' => true, 'video_controls' => true, 'video_sound_on' => true, 'infobulle' => '', 'numerotation' => 'physical', "inline" => true);
+ } else {
+ $cols = array('page' => '', 'type' => '', 'to' => '', 'left' => '', 'top' => '', 'width' => '', 'height' => '', 'target' => '_blank', 'video_loop' => true, 'video_auto_start' => true, 'video_controls' => true, 'video_sound_on' => true, 'infobulle' => '', 'numerotation' => 'physical');
+ }
+
+
+ $k = 0;
+ foreach ($cols as $col => $default) {
+ if (isset($line[$k])) {
+ if (in_array($k, $numbers)) {
+ $link[$col] = (float)str_replace(',', '.', $line[$k]);
+ } else if (in_array($k, $booleans)) {
+ $link[$col] = ($line[$k] == '1');
+ } else {
+ $link[$col] = utf8_encode($line[$k]);
+ }
+ } else {
+ $link[$col] = $default;
+ }
+ $k++;
+ }
+
+ if ($link['type'] == 18) {
+ $link['infobulle'] = $link['to'];
+ $link['to'] = '';
+ }
+
+ $link['display_area'] = '1';
+ $link['page'] = $page;
+ $links[] = $link;
+ }
+
+ }
+
+ self::saveLinksInFile($book_id, $core->user->utilisateur_id, 'Links imported from PDF', $links, []);
+ }
+}