use App\Http\Middleware\CheckIfAdmin;
use App\Jobs\FluidbookCompiler;
use App\Models\FluidbookPublication;
+use App\Models\FluidbookTheme;
+use App\Models\User;
use Cubist\Backpack\Http\Controllers\Base\XSendFileController;
+use Cubist\Util\Graphics\Color;
+use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route;
trait PreviewOperation
{
// Redirect to the url with a timestamp to prevent cache
Route::match(['get'], $segment . '/preview/{id}_{hash}', function ($id, $hash) use ($segment) {
- return redirect(backpack_url($segment . '/preview/' . $id . '_' . $hash . '_' . time()) . '/');
- })->whereNumber('id')
+ return $this->_preview($segment, $id, $hash, null, 'index.html');
+ })->where('id', '([0-9]+)(-[0-9]+)?')
->where('hash', '[0-9a-f]{32}')
->withoutMiddleware([CheckIfAdmin::class]);
Route::match(['get'], $segment . '/preview/{id}_{hash}_{time}/{path?}', function ($id, $hash, $time, $path = 'index.html') use ($segment, $controller) {
- // If timestamp is too old, redirect to a more recent one
- if ($path === 'index.html' && (time() - $time) > 30) {
- return redirect(backpack_url($segment . '/preview/' . $id . '_' . $hash . '_' . time()) . '/');
- }
- return $this->preview($id, $hash, $path);
- })->whereNumber('id')
+ return $this->_preview($segment, $id, $hash, $time, $path);
+ })->where('id', '([0-9]+)(-[0-9]+)?')
->where('hash', '[0-9a-f]{32}')
->where('path', '.*')
->withoutMiddleware([CheckIfAdmin::class]);
$this->crud->addButtonFromView('line', 'preview', 'fluidbook_publication.preview', 'end');
}
+ protected function _preview($segment, $id, $hash, $time = null, $path = null)
+ {
+ $q = request()->getQueryString();
+ if ($q) {
+ $q = '?' . $q;
+ }
+ $nointerface = !!request('nointerface', false);
+ $shortLoading = !!request('shortLoading', false);
+
+ if (null === $time || ($time < (time() - 60) && !$nointerface && !$shortLoading)) {
+ $url = backpack_url($segment . '/preview/' . $id . '_' . $hash . '_' . time()) . '/' . $q;
+ return $this->loadingCompile($url, $id, $hash);
+ }
+
+ self::_getFluidbookAndTheme($id, $hash, $fluidbook, $theme);
+ $check = $this->_checkDemoLinkAuth($fluidbook);
+ if ($check !== true) {
+ return $check;
+ }
+ return $this->preview($fluidbook, $theme, $path);
+ }
+
/**
- * @throws \Exception
+ * @param $fluidbook
+ * @return true|\Illuminate\Contracts\Foundation\Application|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
- public function preview($id, $hash, $path = 'index.html')
+ protected function _checkDemoLinkAuth($fluidbook)
{
- $fluidbook = FluidbookPublication::where('id', $id)->where('hash', $hash)->first();
- if (null === $fluidbook) {
+ if (!Auth::guest()) {
+ return true;
+ }
+ if ($fluidbook->redirectDemo) {
+ return redirect($fluidbook->redirectDemo);
+ }
+ if ($fluidbook->disableDemo) {
abort(404);
}
+ }
+
+
+ /**
+ * @param $url string
+ * @param $id string
+ * @param $hash string
+ * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
+ */
+ public function loadingCompile($url, $id, $hash)
+ {
+ self::_getFluidbookAndTheme($id, $hash, $fluidbook, $theme);
+
+ $bgcolor = Color::colorToCSS($theme->backgroundColor);
+ $scolor = Color::colorToCSS($theme->loadingSecColor);
+ $tcolor = $lcolor = Color::colorToCSS($theme->couleurL);
+ if ($tcolor == $bgcolor) {
+ $tcolor = $scolor;
+ }
+
+ $res = '<!DOCTYPE html><html>';
+ $res .= '<head>';
+ $res .= '<script type="text/javascript">function load(){
+ var url=\'' . $url . '\'+window.location.hash;
+ window.location=url;
+};
+</script>';
+ if (!request()->input('shortLoading', false)) {
+ $res .= '<link href="https://fonts.googleapis.com/css2?family=Open+Sans&display=swap" rel="stylesheet">';
+ $res .= '<style>
+@keyframes loader-spin {
+ 0% {
+ transform: rotate(0deg);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
+}
+*{margin:0;padding:0;}
+html,body{height:100%;cursor: wait;font-family: "Open Sans", Arial;background-color:' . $bgcolor . ';}';
+ $res .= 'h2,h3{text-align:center;color:' . $tcolor . ';font-weight:400;position:relative;top:55%;}';
+ $res .= 'h2{font-size:16px;}';
+ $res .= 'h3{font-size:10px;}';
+ $res .= 'svg{position:absolute;top:calc(50% - 24px);left:calc(50% - 24px);
+ animation-name: loader-spin;
+ animation-duration: 1s;
+ animation-iteration-count: infinite;
+ animation-timing-function: linear;}';
+ $res .= '</style>';
+ $res .= '<title>' . $fluidbook->title . '</title>';
+ $res .= '</head>';
+ $res .= '<body onload="load();">';
+ $res .= '<svg width="48" height="48" id="interface-loader" viewBox="0 0 48 48">
+ <circle cx="24" cy="24" r="23" fill="' . $lcolor . '"></circle>
+ <circle class="animate" cx="24" cy="24" fill="none" stroke="' . $scolor . '" stroke-width="3" r="16"
+ stroke-dasharray="80 80"
+ transform="rotate(0 24 24)">
+ </circle>
+ </svg>';
+
+ $res .= '<h2>' . __('Compilation du fluidbook en cours') . '...</h2>';
+ $res .= '<h3>' . __('Cette étape ne sera pas nécessaire lorsque le fluidbook sera installé sur son emplacement définitif') . '</h3>';
+ } else {
+ $res .= '<script>load();</script>';
+ $res .= '</head>';
+ $res .= '<body>';
+ }
+
+ $res .= '</body>';
+ $res .= '</html>';
+ return response($res);
+ }
+
+ /**
+ * @throws \Exception
+ */
+ public function preview($fluidbook, $theme, $path = 'index.html')
+ {
+ $nointerface = !!request('nointerface', false);
+ $shortLoading = !!request('shortLoading', false);
- $dest = $fluidbook->getFinalPath();
+ $dest = $fluidbook->getFinalPath($theme);
if ($path === 'index.html') {
- $compiler = new FluidbookCompiler($fluidbook);
+ $compiler = new FluidbookCompiler($fluidbook, theme: $theme);
$compiler->handle();
}
return XSendFileController::sendfile($dest . '/' . $path);
}
+
+ /**
+ * @param $id string
+ * @param $hash string
+ * @param $fluidbook FluidbookPublication
+ * @param $theme FluidbookTheme
+ * @return void
+ */
+ protected static function _getFluidbookAndTheme($id, $hash, &$fluidbook, &$theme)
+ {
+ $ee = explode('-', $id);
+ if (count($ee) === 1) {
+ $forceThemeData = request('theme', false);
+ if ($forceThemeData) {
+ $theme = FluidbookTheme::fromArray(json_decode($forceThemeData, true));
+ }
+ } else {
+ $theme = FluidbookTheme::find($ee[1]);
+ $id = $ee[0];
+ }
+
+ $fluidbook = FluidbookPublication::where('id', $id)->where('hash', $hash)->first();
+ if (null === $fluidbook) {
+ abort(404);
+ }
+ if (!isset($theme)) {
+ $theme = $fluidbook->getTheme();
+ }
+ }
}
* @param $standalone
* @param $appcache
* @param $home
- * @param $forceTheme
+ * @param $theme FluidbookTheme|null
* @param $hybrid
* @param Command|null $command
* @throws \Exception
*/
- function __construct(FluidbookPublication $book, $version = null, $phonegap = false, $phonegapVersion = 'latest', $dir = null, $standalone = false, $appcache = false, $home = false, $forceTheme = false, $hybrid = false, Command $command = null)
+ function __construct(FluidbookPublication $book, $version = null, $phonegap = false, $phonegapVersion = 'latest', $dir = null, $standalone = false, $appcache = false, $home = false, FluidbookTheme $theme = null, $hybrid = false, Command $command = null)
{
parent::__construct();
$this->book_id = $this->getFluidbook()->id;
$this->log('Start compilation');
- $forceThemeId = FluidbookTheme::hashThemeArray($forceTheme);
- $this->dir = $this->getFluidbook()->getFinalPath();
+ $this->dir = $this->getFluidbook()->getFinalPath($theme);
$this->vdir = new VirtualDirectory($this->dir);
$this->wdir = $this->getFluidbook()->getAssetDir();
$this->pages = $this->getFluidbook()->composition;
$this->maxRes = min(self::MAX_RES, $this->fluidbookSettings->maxResolution);
- if (is_array($forceTheme)) {
- $this->theme = FluidbookTheme::fromArray($forceTheme);
- } else if (is_numeric($forceTheme)) {
- $this->theme = FluidbookTheme::find($forceTheme);
- } else {
- $this->theme = FluidbookTheme::find($this->getFluidbook()->theme);
- }
+ $this->theme = $theme ?? $this->getFluidbook()->getTheme();
+
$this->themeSettings = $this->theme->getPageData();
$this->log('Got data from database');