'js/libs/fluidbook/fluidbook.zoom.js',
'js/libs/fluidbook/fluidbook.menu.js',
'js/libs/fluidbook/fluidbook.sound.js',
+ 'js/libs/fluidbook/fluidbook.contentlock.js',
'js/libs/fluidbook/fluidbook.scorm.js',
'js/libs/fluidbook/fluidbook.3dflip.js',
'js/libs/fluidbook/menu/fluidbook.chapters.js',
public $logtime = null;
public $beginBody = array();
public $seoArticles = [];
- public $securityPolicyWhitelist = ['*.google-analytics.com', '*.youtube.com', '*.ytimg.com', '*.googletagmanager.com'];
+ public $securityPolicyWhitelist = ['*.google-analytics.com', '*.youtube.com', '*.ytimg.com'];
+ public $writeLinksData = false;
+ public $content_lock = [];
protected $_indexVars = null;
public $_signature;
public $seo = null;
- function __construct($book_id, $version = 'stable', $phonegap = false, $phonegapVersion = 'latest', $dir = null, $standalone = false, $appcache = false, $home = false)
+ function __construct($book_id, $version = 'stable', $phonegap = false, $phonegapVersion = 'latest', $dir = null, $standalone = false, $appcache = false, $home = false, $book = null)
{
global $core;
$this->wdir = WS_BOOKS . '/working/' . $this->book_id . '/';
$this->daoBook = new wsDAOBook($core->con);
+ if (null === $book) {
$this->book = $this->daoBook->selectById($book_id);
- $this->pages = $this->daoBook->getPagesOfBook($book_id);
+ } else {
+ $this->book = $book;
+ }
+
+ $this->widget = !$this->phonegap && $this->book->parametres->widget;
+ $this->pages = $this->daoBook->getPagesOfBook($book_id);
+ $this->maxRes = min(300, $this->book->parametres->maxResolution);
$daoTheme = new wsDAOTheme($core->con);
$this->theme = $daoTheme->getThemeOfBook($book_id, true);
$this->config->vectorPages = array_diff(cubeArray::parseRange($this->config->vectorPages), $this->config->rasterizePages);
}
+ protected function populateConfig()
+ {
+ $this->config->numerotation = explode(',', $this->book->numerotation);
+ $this->config->id = $this->book->book_id;
+ $this->config->cid = $this->book->cid;
+ $this->config->cacheDate = TIME;
+ $this->config->width = $this->cssWidth;
+ $this->config->height = $this->cssHeight;
+ $this->config->optimalWidth = $this->optimalWidth;
+ $this->config->optimalHeight = $this->optimalHeight;
+ $this->config->chapters = $this->book->chapters;
+ $this->config->videoFormats = $this->getVideosFormats(false);
+ $this->config->htmlmultimedia = $this->htmlmultimedia;
+ $this->config->phonegap = $this->phonegap;
+ $this->config->retinaResolution = min($this->book->parametres->maxResolution, $this->maxRes);
+ $this->config->pageLabels = $this->pageLabels;
+ $this->config->pageZoomFactor = $this->z;
+ $this->config->multiply = $this->multiply;
+ $this->config->cssScale = $this->cssScale;
+ $this->config->pdfZoomFactor = $this->pdf2htmlRatio;
+ if ($this->home) {
+ $this->config->home = 'http://home';
+ }
+ $this->config->multiApp = $this->multiApp;
+ foreach ($this->additionalConfig as $k => $v) {
+ $this->config->$k = $v;
+ }
+ if ($this->phonegap && ($this->book->parametres->offlineLink == '' || $this->book->parametres->offlineLink == 'http://')) {
+ $this->config->share = false;
+ }
+ if ($this->config->maxPages > 0) {
+ $this->addContentLock($this->config->maxPages);
+ }
+
+ // We need to be able to reference both navOrder and navOrderH so convert both to arrays
+ // We also make sure there are no empty items in the arrays (see: http://php.net/manual/en/function.array-filter.php#111091)
+ $this->config->navOrder = array_filter(array_map('trim', explode(',', $this->config->navOrder)), 'strlen');
+ $this->config->navOrderH = array_filter(array_map('trim', explode(',', $this->config->navOrderH)), 'strlen');
+
+ $this->config->standalone = $this->standalone;
+ if ($this->config->phonegap) {
+ $this->config->manifest = $this->writeManifest();
+ }
+
+ if ($this->config->form == 'bulle') {
+ $this->addJs('js/libs/fluidbook/forms/fluidbook.form.bulle.js');
+ } else if ($this->config->form == 'bourbon') {
+ $this->addJs('js/libs/parsley.min.js');
+ $this->addJs('js/libs/fluidbook/forms/fluidbook.form.bourbon.js');
+ } else if ($this->config->form == 'avery') {
+ $this->addJs('js/libs/parsley.min.js');
+ $this->addJs('js/libs/fluidbook/forms/fluidbook.form.avery.js');
+ $this->addLess('form/avery');
+ $this->writeCountries();
+ }
+
+ if ($this->config->basket) {
+ $this->addJs('js/libs/fluidbook/fluidbook.cart.js');
+ switch ($this->config->basketManager) {
+ case 'Remarkable':
+ $this->addJs('js/libs/parsley.min.js');
+ $this->addJs('js/libs/jquery/jquery.cookie.js');
+ $this->addJs('js/libs/fluidbook/cart/fluidbook.cart.remarkable.js');
+ break;
+ default:
+ break;
+ }
+
+ if (file_exists($this->config->basketReferences) || CubeIT_Util_Url::isDistant($this->config->basketReferences)) {
+ $referencesFile = $this->config->basketReferences;
+ } else {
+ $referencesFile = $this->wdir . '/commerce/' . $this->config->basketReferences;
+ }
+
+ if (file_exists($referencesFile) || CubeIT_Util_Url::isDistant($referencesFile)) {
+ $ext = CubeIT_Files::getExtension($referencesFile);
+ if ($ext == 'xlsx') {
+ $this->config->basketReferences = wsUtil::excelToArray($referencesFile);
+ if ($this->book->parametres->customLinkClass == 'AtlanticDownloadLink') {
+ $this->config->basketReferences = wsUtil::atlanticReferences($this->config->basketReferences, 'local/', array($this, 'log'), array($this->vdir, "copy"));
+ }
+ }
+ $this->log("Done cart references");
+ }
+ }
+ $this->config->seoArticles = $this->seoArticles;
+ }
+
public function log($step)
{
$currenttime = microtime(true);
$this->log('Images written');
$linksCSS = $this->writeLinks();
$this->log('Links written');
- $this->writeCSS('data/style/style_%d.css', $linksCSS);
- $this->log('CSS written');
$this->writeLangs();
$this->log('Langs written');
$this->writeSEO();
$this->log('SEO written');
- $this->writeIndex();
- $this->log('Index written');
- if ($this->book->parametres->scorm_enable) {
- $this->writeScorm();
- $this->log('SCORM written');
- }
$this->writeWidget();
$this->log('Widget written');
$this->writeSounds();
$this->log('Texts written');
$this->writeExtras();
$this->log('Extras written');
+ $this->populateConfig();
+ $this->writeCSS('data/style/style_%d.css', $linksCSS);
+ $this->log('CSS written');
+ $this->writeIndex();
+ $this->log('Index written');
+ if ($this->book->parametres->scorm_enable) {
+ $this->writeScorm();
+ $this->log('SCORM written');
+ }
$this->writeJs();
$this->log('Js written');
$this->vdir->sync($delete);
/**
* Helper function to add a unique stylesheet entry to the LESS stack for compilation
* Duplicate paths are ignored.
- * @param $path The path of the file relative to the /style folder, without any extension
- * @param $extra_files Optional array of extra files that should be copied across for use during LESS compilation
+ * @param $path string The path of the file relative to the /style folder, without any extension
*/
public function addLess($path)
{
protected function _writeIndex($page)
{
+
+ if (!isset($this->seo->pages[$page])) {
+ return;
+ }
$seo = $this->seo->pages[$page];
$html = $seo->getHTML();
$iscript .= '</script>' . "\n";
}
- $script = '<script type="text/javascript">var FLUIDBOOK_START_PAGE="' . $page . '";</script>' . "\n";
+
$script = '<script type="text/javascript" charset="utf-8" src="data/datas.js"></script>' . "\n";
$script .= '<script type="text/javascript" charset="utf-8" src="data/fluidbook.js"></script>' . "\n";
if ($this->book->parametres->scorm_enable) {
}
$script .= $iscript;
- $socialTitle = $this->book->parametres->facebook_title ? $this->book->parametres->facebook_title : $titre;
- $socialDescription = $this->book->parametres->seoDescription ? $this->book->parametres->seoDescription : $this->book->parametres->seoDescription;
+ $socialTitle = html::escapeHTML($this->book->parametres->facebook_title ? $this->book->parametres->facebook_title : $titre);
+ $socialDescription = html::escapeHTML($this->book->parametres->facebook_description ? $this->book->parametres->facebook_description : $this->book->parametres->seoDescription);
$socialImage = 'https://workshop.fluidbook.com/services/facebook_thumbnail?id=' . $this->book_id . '&j=' . TIME;
$dim = CubeIT_Image::getimagesize($socialImage);
$socialImageWidth = $dim[0];
$socialImageHeight = $dim[1];
- $twittercard = '<meta name="twitter:title" content="' . html::escapeHTML($socialTitle) . '">
- <meta name="twitter:description" content="' . html::escapeHTML($socialDescription) . '">
+ $twittercard = '<meta name="twitter:title" content="' . $socialTitle . '">
+ <meta name="twitter:description" content="' . $socialDescription . '">
<meta name="twitter:image" content="' . $socialImage . '">
<meta name="twitter:site" content="@Fluidbook">
<meta name="twitter:card" content="summary_large_image">';
- $opengraph = '<meta property="og:title" content="' . html::escapeHTML($socialTitle) . '"/>
- <meta property="og:description" content="' . html::escapeHTML($socialDescription) . '"/>
+ $opengraph = '<meta property="og:title" content="' . $socialTitle . '"/>
+ <meta property="og:description" content="' . $socialDescription . '"/>
<meta property="og:image" content="' . $socialImage . '"/>
<meta property="og:image:width" content="' . $socialImageWidth . '"/>
<meta property="og:image:height" content="' . $socialImageHeight . '"/>';
$style = '<link type="text/css" rel="stylesheet" href="style/widget.css">';
$vars = array('titre', 'style', 'script');
foreach ($vars as $v) {
+ if (isset($$v)) {
$whtml = str_replace('<!-- $' . $v . ' -->', $$v, $whtml);
+ } else {
+ $whtml = str_replace('<!-- $' . $v . ' -->', '', $whtml);
+ }
}
$this->vdir->file_put_contents('widget.html', $whtml);
}
$this->seo = new wsHTML5Seo($this);
}
+ public function addContentLock($page, $unlockConditions = '')
+ {
+ $unlockConditions = CubeIT_Text::explodeNewLines($unlockConditions);
+ $conditions = [];
+ foreach ($unlockConditions as $unlockCondition) {
+ $e = explode(',', $unlockCondition);
+ if (!isset($e[1])) {
+ $e[1] = 'click';
+ }
+ $conditions[] = $e;
+ }
+ $page = max(1, $page);
+ if (!isset($this->content_lock[$page])) {
+ $this->content_lock[$page] = ['unlocked' => 0, 'conditions' => []];
+ }
+ $this->content_lock[$page]['conditions'] = array_merge($this->content_lock[$page]['conditions'], $conditions);
+ }
+
protected function writeScorm()
{
if ($this->book->parametres->scorm_version == '1.2') {
$lang = $daoLang->selectById($this->book->lang);
$langs = $daoLang->selectAll();
- $traductions = (!count($this->book->traductions)) ? $lang->traductions : $this->book->traductions;
+ $t = CubeIT_Util_Object::toArray($this->book->traductions);
+
+ $traductions = (!is_countable($t) || !count($t)) ? $lang->traductions : $t;
$this->config->l10n = array();
$this->config->l10n['default'] = $traductions;
'inline' => 1,
'interactive' => 1,
'class' => 'tabslink',
+ 'uid' => 'tabs',
];
}
+ $pagesOfCustomLinks = [];
+ $hiddenLinks = [];
foreach ($links as $linkData) {
if (isset($linkData['image']) && $linkData['image'] && $linkData['type'] != 28) {
$dupData = $linkData;
$dupData['image'] = '';
$dupData['to'] = $linkData['image'];
+ $dupData['rollover'] = $linkData['image_rollover'];
$dupData['type'] = 15;
+ $dupData['uid'] = 'i_' . $linkData['uid'];
+ if (wsHTML5Link::isScorm($linkData)) {
+ $dupData['scorm'] = true;
+ }
array_push($links, $dupData);
}
+ if ($linkData['type'] == 7) {
+ $k = $linkData['to'];
+ if (!isset($pagesOfCustomLinks[$k])) {
+ $pagesOfCustomLinks[$k] = [];
+ }
+ if (!in_array($linkData['page'], $pagesOfCustomLinks[$k])) {
+ $pagesOfCustomLinks[$k][] = $linkData['page'];
+ }
+ }
+ if ($linkData['type'] == 32) {
+ $hiddenLinks[] = $linkData['to'];
+ }
}
+ $this->config->pagesOfCustomLinks = $pagesOfCustomLinks;
+
$i = 0;
$pages = array();
$cpages = array();
$css = array();
+ $linkPages = [];
+ $allLinksData = [];
usort($links, array($this, '_sortLinks'));
if (in_array($linkData['type'], $ignore)) {
continue;
}
+
+
+ $linkData['hidden'] = in_array($linkData['uid'], $hiddenLinks);
if ($linkData['type'] == 28) {
$this->addSEOArticle($linkData['page'], $linkData['to'], $linkData['extra'], $linkData['image']);
continue;
$this->config->afterSearchTooltip = $link->infobulle;
}
+ if (strpos($link->page, 'link_') === 0) {
+ $linkPages[$link->page] = true;
+ }
+
$c = $link->getHTMLContainer();
$css[] = $link->getCSSContainer();
$pages[$link->page] .= $c;
}
+ $allLinksData[$linkData['uid']] = $linkData;
+
if ($link->keep()) {
$this->hiddenContents[] = $c;
}
}
$allpages[] = 'background';
$allpages[] = 'archives';
+ foreach ($linkPages as $linkPage => $true) {
+ $allpages[] = $linkPage;
+ }
foreach ($allpages as $i) {
$this->config->links[$i] = $c;
$this->config->clinks[$i] = $cc;
}
+
+ if ($this->writeLinksData) {
+ $this->config->linksData = $allLinksData;
+ }
+
return $css;
}
$this->copyLinkFile($link['to'], 'data/audiodescription/');
}
+ protected function beforeWriteConfig()
+ {
+ uasort($this->content_lock, function ($a, $b) {
+ return $a['page'] - $b['page'];
+ });
+
+ $this->config->content_lock = $this->content_lock;
+ }
+
protected function writeJs()
{
+ $this->beforeWriteConfig();
+
$config = $this->writeConfig();
$this->vdir->file_put_contents('data/datas.js', $config);
$finals = array('fluidbook' => $this->jsFiles);
if (!$reminimize) {
foreach ($files as $file) {
- if (filemtime($this->assets . '/' . $file) > $mintime) {
+ $f = $this->assets . '/' . $file;
+ if (file_exists($f) && filemtime($f) > $mintime) {
$reminimize = true;
break;
}
if ($reminimize) {
$js = '';
foreach ($files as $file) {
- $js .= file_get_contents($this->assets . '/' . $file);
+ $f = $this->assets . '/' . $file;
+ if (!file_exists($f)) {
+ continue;
+ }
+ $js .= file_get_contents($f);
$js .= ";\n\n";
}
$tmp = cubeFiles::tempnam();
file_put_contents($tmp, $js);
+ if (file_exists($minimized)) {
unlink($minimized);
+ }
$uglify = new CubeIT_CommandLine('/usr/local/bin/uglifyjs');
$uglify->setArg('o', $minimized);
protected function writeConfig()
{
- $this->config->numerotation = explode(',', $this->book->numerotation);
- $this->config->id = $this->book->book_id;
- $this->config->cid = $this->book->cid;
- $this->config->cacheDate = TIME;
- $this->config->width = $this->cssWidth;
- $this->config->height = $this->cssHeight;
- $this->config->optimalWidth = $this->optimalWidth;
- $this->config->optimalHeight = $this->optimalHeight;
- $this->config->chapters = $this->book->chapters;
- $this->config->videoFormats = $this->getVideosFormats(false);
- $this->config->htmlmultimedia = $this->htmlmultimedia;
- $this->config->phonegap = $this->phonegap;
- $this->config->retinaResolution = min($this->book->parametres->maxResolution, $this->maxRes);
- $this->config->pageLabels = $this->pageLabels;
- $this->config->pageZoomFactor = $this->z;
- $this->config->multiply = $this->multiply;
- $this->config->cssScale = $this->cssScale;
- $this->config->pdfZoomFactor = $this->pdf2htmlRatio;
- if ($this->home) {
- $this->config->home = 'http://home';
- }
- $this->config->multiApp = $this->multiApp;
- foreach ($this->additionalConfig as $k => $v) {
- $this->config->$k = $v;
- }
- if ($this->phonegap && ($this->book->parametres->offlineLink == '' || $this->book->parametres->offlineLink == 'http://')) {
- $this->config->share = false;
- }
-
- // We need to be able to reference both navOrder and navOrderH so convert both to arrays
- // We also make sure there are no empty items in the arrays (see: http://php.net/manual/en/function.array-filter.php#111091)
- $this->config->navOrder = array_filter(array_map('trim', explode(',', $this->config->navOrder)), 'strlen');
- $this->config->navOrderH = array_filter(array_map('trim', explode(',', $this->config->navOrderH)), 'strlen');
-
- $this->config->standalone = $this->standalone;
- if ($this->config->phonegap) {
- $this->config->manifest = $this->writeManifest();
- }
-
- if ($this->config->form == 'bulle') {
- $this->addJs('js/libs/fluidbook/forms/fluidbook.form.bulle.js');
- } else if ($this->config->form == 'bourbon') {
- $this->addJs('js/libs/parsley.min.js');
- $this->addJs('js/libs/fluidbook/forms/fluidbook.form.bourbon.js');
- }
-
- if ($this->config->basket) {
- $this->addJs('js/libs/fluidbook/fluidbook.cart.js');
- switch ($this->config->basketManager) {
- case 'Remarkable':
- $this->addJs('js/libs/parsley.min.js');
- $this->addJs('js/libs/jquery/jquery.cookie.js');
- $this->addJs('js/libs/fluidbook/cart/fluidbook.cart.remarkable.js');
- break;
- default:
- break;
- }
-
-
- if (file_exists($this->config->basketReferences) || CubeIT_Util_Url::isDistant($this->config->basketReferences)) {
- $referencesFile = $this->config->basketReferences;
- } else {
- $referencesFile = $this->wdir . '/commerce/' . $this->config->basketReferences;
- }
-
- if (file_exists($referencesFile) || CubeIT_Util_Url::isDistant($referencesFile)) {
- $ext = CubeIT_Files::getExtension($referencesFile);
- if ($ext == 'xlsx') {
- $this->config->basketReferences = wsUtil::excelToArray($referencesFile);
- if ($this->book->parametres->customLinkClass == 'AtlanticDownloadLink') {
- $this->config->basketReferences = wsUtil::atlanticReferences($this->config->basketReferences, 'local/', array($this, 'log'), array($this->vdir, "copy"));
- }
- }
- $this->log("Done cart references");
- }
- }
- $this->config->seoArticles = $this->seoArticles;
-
return 'var DATAS=' . json_encode($this->config) . ';' . "\n";
}
+ protected function writeCountries()
+ {
+ $c = Zend_Locale::getTranslationList('Territory', $this->book->lang, 2);
+ asort($c);
+ $this->config->countries = $c;
+ }
+
protected function writeManifest()
{
$res = array();
$less->execute();
$less->debug();
if (!file_exists($destination_css)) {
- die($less->output);
+ continue;
}
$this->vdir->copy($destination_css, 'style/' . $f . '.css');
if ($f != 'widget') {
}
}
+
+if (!function_exists('is_countable')) {
+
+ function is_countable($c)
+ {
+ return is_array($c) || $c instanceof Countable;
+ }
+
+}