--- /dev/null
+<?php
+
+namespace App\Fluidbook\SEO;
+
+use App\Util\Excel;
+use Cubist\Util\Text;
+use Fluidbook\Tools\Compiler\CompilerInterface;
+
+class Document
+{
+
+ /**
+ * @var CompilerInterface
+ */
+ public $compiler;
+ /**
+ * @var Page[]
+ */
+ public $pages;
+ public $html;
+ protected $_nav = null;
+
+
+ /**
+ * @param $compiler CompilerInterface
+ */
+ public function __construct($compiler)
+ {
+ $this->compiler = $compiler;
+ // Define default seo contents
+ $this->createPages();
+
+ $file=$this->compiler->getSetting('seoAdvanced','');
+ if ($file) {
+ $sheets = Excel::excelToArray($this->compiler->working_path($file), true);
+ foreach ($sheets as $sheet) {
+ $a = $sheet;
+ break;
+ }
+ $minPage = 100000000;
+ foreach ($a as $item) {
+ $minPage = min($minPage, $item['page']);
+ }
+ $offsetPage = -($minPage - 1);
+
+ foreach ($a as $item) {
+ $page = $item['page'] + $offsetPage;
+ $item['url'] = Text::removeAccents($item['url']);
+ foreach ($item as $k => $v) {
+ if ($k == 'page') {
+ continue;
+ }
+ $this->pages[$page]->$k = $v;
+ }
+ }
+ }
+
+ $this->html = file_get_contents($this->compiler->assets . '/_index.html');
+ }
+
+ public function createPages()
+ {
+ $this->pages = [];
+ if (isset($this->compiler->accessibleTexts) && count($this->compiler->accessibleTexts) > 0) {
+ foreach ($this->compiler->accessibleTexts as $page => $accessibleText) {
+ if ($page == 0) {
+ $page = 1;
+ }
+ $this->createPage($page, $accessibleText);
+ }
+ if (!isset($this->pages[1])) {
+ $this->createPage(1, $this->compiler->pages[1]);
+ }
+ return;
+ }
+ foreach ($this->compiler->pages as $page => $infos) {
+ $this->createPage($page, $this->getTextContent($infos));
+ }
+ }
+
+ public function createPage($page, $content)
+ {
+ $p = new Page($this);
+ $p->page = $page;
+ $p->title = ($page == 1) ? $this->compiler->book->parametres->title : $this->_getPageLabel($page);
+ $p->text = $content;
+ $p->description = $this->compiler->book->parametres->seoDescription ? $this->compiler->book->parametres->seoDescription : $this->compiler->book->parametres->title . ' - Powered by Fluidbook';
+ $p->socialDescription = $this->compiler->book->parametres->facebook_description || $this->compiler->book->parametres->seoDescription;
+ $p->keywords = $this->compiler->book->parametres->seoKeywords;
+ $p->robots = $this->compiler->book->parametres->seoRobots ? 'index,follow' : 'noindex,nofollow';
+
+ // Google analytics
+ $p->ua = '';
+ if ($this->compiler->book->parametres->googleAnalytics != '') {
+ $codes = explode(',', $this->compiler->book->parametres->googleAnalytics);
+ $p->ua .= "<script async src=\"https://www.googletagmanager.com/gtag/js?id=" . $codes[0] . "\"></script><script>window.dataLayer = window.dataLayer || [];function gtag(){dataLayer.push(arguments);}</script>";
+ }
+ if ($this->compiler->book->parametres->googleAnalyticsCustom != '') {
+ $p->ua .= $this->compiler->book->parametres->googleAnalyticsCustom;
+ }
+
+ if ($this->compiler->book->parametres->statsCustom != '') {
+ $p->footer = $this->compiler->book->parametres->statsCustom;
+ }
+
+ $this->pages[$page] = $p;
+ }
+
+ public function getTextContent($infos)
+ {
+ switch ($this->compiler->book->parametres->textExtraction) {
+ case 'poppler':
+ $prefix = 'p';
+ break;
+ case 'fluidbook':
+ $prefix = 'f';
+ break;
+ default:
+ $prefix = '';
+ break;
+ }
+
+ $f = wsDocument::getDir($infos['document_id']) . $prefix . 'h' . $infos['document_page'] . '.txt';
+ if (file_exists($f)) {
+ $res = trim(file_get_contents($f));
+ } else {
+ $res = '';
+ }
+
+ if (strpos($res, '<div>') !== 0) {
+ $res = preg_replace('|\<\/div\>$|', '', $res);
+ }
+
+ return $res;
+ }
+
+ public function _getPageLabel($page)
+ {
+ $res = $this->compiler->book->parametres->title;
+ foreach ($this->compiler->book->chapters as $chapter) {
+ if (trim($chapter->label, "\t\r\n\0\x0B-+") == '') {
+ continue;
+ }
+ if ($chapter->page == '') {
+ continue;
+ }
+ $p = $this->compiler->virtualToPhysical($chapter->page);
+ if ($p == '') {
+ continue;
+ }
+ if ($page < $p) {
+ continue;
+ }
+ if ($page >= $p) {
+ $res = $chapter->label;
+ }
+ }
+ return $res;
+ }
+
+ public function getNav()
+ {
+ if (null == $this->_nav) {
+ $this->_nav = '<nav>';
+ foreach ($this->pages as $page => $p) {
+ if (method_exists($p, 'getUrl')) {
+ $this->_nav .= '<a href="' . $p->getUrl() . '">' . $p->title . '</a>';
+ }
+ }
+ $this->_nav .= '</nav>';
+ }
+ return $this->_nav;
+ }
+
+}
--- /dev/null
+<?php
+
+namespace App\Fluidbook\SEO;
+
+class Page
+{
+ public $page;
+ public $text;
+ public $title;
+ public $description;
+ public $url = null;
+ public $h1;
+ public $ua;
+ public $canonical;
+ public $prev;
+ public $next;
+ public $keywords;
+ public $robots;
+ public $footer;
+
+ /**
+ * @var wsHTML5Seo
+ */
+ public $_container;
+
+
+ public function __construct($container)
+ {
+ $this->_container = $container;
+ }
+
+ public function getHTML()
+ {
+ $html = $this->_container->html;
+
+ if (!$this->canonical) {
+ $this->canonical = $this->getURL();
+ }
+ if (!$this->next && isset($this->_container->pages[$this->page + 1]) && $this->_container->pages[$this->page + 1] instanceof wsHTML5SeoPage) {
+ $this->next = $this->_container->pages[$this->page + 1]->getURL();
+ }
+ if (!$this->prev && isset($this->_container->pages[$this->page - 1]) && $this->_container->pages[$this->page - 1] instanceof wsHTML5SeoPage) {
+ $this->prev = $this->_container->pages[$this->page - 1]->getURL();
+ }
+
+ $vars = ['description' => $this->description ? '<meta name="description" content="' . $this->description . '">' : '',
+ 'keywords' => $this->keywords ? '<meta name="keywords" content="' . $this->keywords . '">' : '',
+ 'titre' => $this->title,
+ 'canonical' => $this->canonical ? '<link rel="canonical" href="' . $this->canonical . '">' : '<link rel="canonical" href="' . $this->getURL() . '">',
+ 'prev' => $this->prev ? '<meta name="prev" href="' . $this->prev . '">' : '',
+ 'next' => $this->next ? '<meta name="next" href="' . $this->next . '">' : '',
+ 'robots' => $this->robots ? '<meta name="robots" content="' . $this->robots . '">' : '',
+ 'statsfooter' => $this->footer,
+ 'ga' => $this->ua,
+ 'seoContent' => $this->getSEOContent(),
+ 'startpage' => '<script type="text/javascript">var FLUIDBOOK_START_PAGE="' . $this->page . '";</script>' . "\n"];
+
+ if (!$this->_container->compiler->book->parametres->seoVersion) {
+ $vars['canonical'] = $vars['next'] = $vars['prev'] = '';
+ }
+
+ foreach ($vars as $k => $var) {
+ $html = str_replace('<!-- $' . $k . ' -->', $var, $html);
+ }
+
+ return $html;
+ }
+
+ public function getSEOContent()
+ {
+ $res = '';
+ if (null !== $this->h1) {
+ $res .= '<h1>' . htmlentities($this->h1) . '</h1>';
+ }
+ $res .= $this->text;
+ $res .= $this->_container->getNav();
+ return $res;
+ }
+
+ public function getURL()
+ {
+ if (null === $this->url) {
+ return $this->page . '-' . CubeIT_Text::str2URL(CubeIT_Text::removeAccents($this->title)) . '.html';
+ }
+ return $this->url;
+ }
+
+ public function getHTMLRelativePath()
+ {
+ $url = $this->getURL();
+ if (null == $this->url) {
+ $res = 'p/' . $url;
+ }
+
+ if ($this->_container->compiler->book->parametres->seoBaseURL == '') {
+ $res = $url;
+ } else {
+ $res = str_replace($this->_container->compiler->book->parametres->seoBaseURL, '', $url);
+ }
+
+ return ltrim($res, '/');
+ }
+
+ /**
+ * @param string $html
+ * @param CubeIT_Files_VirtualDirectory $vdir
+ * @param null|string $path
+ */
+ public function writePage($html, $vdir, $path = null)
+ {
+ if ($path == null) {
+ $path = $this->getHTMLRelativePath();
+ }
+ $relativeLevel = count(explode('/', rtrim($path, "/"))) - 1;
+ $base = '';
+ if ($relativeLevel > 0) {
+ $base = '<base href="' . str_repeat('../', $relativeLevel) . '" >';
+ }
+ $html = str_replace('<!-- $base -->', $base, $html);
+
+ $dir = WS_BOOKS . '/seo/' . $this->_container->compiler->book_id . '/';
+ if (!file_exists($dir)) {
+ mkdir($dir, 0777, true);
+ }
+ $file = $dir . $this->page . '.html';
+ $hash = sha1($html);
+ $hashfile = $dir . $this->page . '.hash';
+ if (!file_exists($hashfile) || file_get_contents($hashfile) != $hash) {
+ file_put_contents($file, $html);
+ file_put_contents($hashfile, $hash);
+ }
+ $vdir->copy($file, $path);
+ }
+}
use App\Models\FluidbookPublication;
use App\Models\FluidbookTheme;
+use App\Models\FluidbookTranslate;
use App\Models\Traits\FluidbookPlayerBranches;
use App\Util\FluidbookLinks;
+use Cubist\Locale\Country;
+use Cubist\Locale\Locale;
use Cubist\Util\ArrayUtil;
use Cubist\Util\CommandLine;
use Cubist\Util\Data;
public $seo = null;
/**
- * @var \Cubist\Backpack\Magic\PageData
+ * @var \Cubist\Backpack\Magic\EntityData
*/
public $fluidbookSettings;
/**
- * @var \Cubist\Backpack\Magic\PageData
+ * @var \Cubist\Backpack\Magic\EntityData
*/
public $themeSettings;
if (!isset($this->config->l10n)) {
$this->writeLangs();
}
-
- if (isset($this->config->l10n['default']->$str)) {
- return $this->config->l10n['default']->$str;
- } else {
- return $str;
- }
+ return $this->config->get('l10n.default.' . $str, $str);
}
protected function writeLangs()
{
- $daoLang = new wsDAOLang($core->con);
- $lang = $daoLang->selectById($this->getFluidbook()->lang);
- $langs = $daoLang->selectAll();
-
- $t = ObjectUtil::toArray($this->getFluidbook()->traductions);
-
- $traductions = (!is_countable($t) || !count($t)) ? $lang->traductions : $t;
+ $this->config->defaultLang = $this->getFluidbook()->locale;
+ $l10n = FluidbookTranslate::getCompiledTranslations();
+ $l10n['default'] = $l10n[$this->config->defaultLang];
+ foreach ($this->getFluidbook()->translations as $k => $v) {
+ $l10n['default'][$k] = $v;
+ }
+ $this->config->setRaw('l10n', $l10n);
- $this->config->l10n = array();
- $this->config->l10n['default'] = $traductions;
- $this->config->defaultLang = $this->getFluidbook()->lang;
- foreach ($langs as $lang) {
- $this->config->l10n[$lang->lang_id] = $lang->traductions;
- }
- $iso = l10n::getISOcodes();
- if ($this->fluidbookSettings->multilang != '') {
- $flagsDir = 'images/flags';
- if (!file_exists($flagsDir)) {
- mkdir($flagsDir);
- }
- $ml = str_replace("\r", "\n", $this->fluidbookSettings->multilang);
- $ml = str_replace("\n\n", "\n", $ml);
- $e = explode("\n", $ml);
+ $multilang = Text::explodeNewLines($this->config->get('multilang', ''));
+ if (count($multilang)) {
$m = array();
- foreach ($e as $l1) {
- $l1 = trim($l1);
- if ($l1 == '') {
+ foreach ($multilang as $line) {
+ $line = trim($line);
+ if ($line == '') {
continue;
}
- $l = explode(',', $l1);
+ $l = explode(',', $line);
+ $locale = $l[0];
$flag = $l[1];
-
- $ll = explode('-', $l[0]);
-
- $this->vdir->copy(cubeMedia::getFlagFile($flag), $flagsDir . '/' . $flag . '.png');
- $l[3] = cubeText::ucfirst($iso[$l[0]]);
- $l[4] = cubeCountry::getCountryName($flag, $ll[0]);
+ $this->getVirtualDirectory()->copy(resource_path('fluidbookpublication/flags/' . $flag . '.png'), 'images/flags/' . $flag . '.png');
+ $l[3] = Text::ucfirst(Locale::translate($locale, $locale));
+ $l[4] = Country::translate($flag, $locale);
$m[] = implode(',', $l);
}
- $this->config->multilang = implode("\n", $m);
+ $this->config->setRaw('multilang', implode("\n", $m));
}
}
$t = FluidbookTranslate::find(1);
try {
$json = json_decode($t->getRawOriginal('content_translatable'), true, 512, JSON_THROW_ON_ERROR);
- }catch (\Exception $e){
- $json=[];
+ } catch (\Exception $e) {
+ $json = [];
}
self::$_allTranslations = [];
return self::$_allTranslations;
}
+ public static function getCompiledTranslations()
+ {
+ $raw = self::getAllFluidbookTranslations();
+ $res = [];
+ foreach ($raw as $code => $data) {
+ $res[$code] = [];
+ foreach ($data as $k => $v) {
+ if (is_string($v)) {
+ $res[$code][$k] = $v;
+ } else {
+ $res[$code][$v['str']] = $v['translation'];
+ }
+ }
+ }
+ return $res;
+ }
+
/**
* @throws \JsonException
*/