]> _ Git - fluidbook-toolbox.git/commitdiff
wip #5396 @3
authorVincent Vanwaelscappel <vincent@cubedesigners.com>
Thu, 25 Aug 2022 16:01:15 +0000 (18:01 +0200)
committerVincent Vanwaelscappel <vincent@cubedesigners.com>
Thu, 25 Aug 2022 16:01:15 +0000 (18:01 +0200)
app/Http/Controllers/Admin/Operations/FluidbookPublication/PreviewOperation.php
app/Jobs/FluidbookCompiler.php
app/Models/FluidbookPublication.php
app/Models/FluidbookTheme.php

index ee0694ea166b3f12ae90a38b481ce0c0384bed84..20d4a35a17da80075905eb0096d2a77f5ff82ac4 100644 (file)
@@ -5,7 +5,11 @@ namespace App\Http\Controllers\Admin\Operations\FluidbookPublication;
 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
@@ -14,18 +18,14 @@ 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]);
@@ -36,21 +36,158 @@ trait PreviewOperation
         $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();
+        }
+    }
 }
index 825c75c86a34cf8338d92bb1c9971a2062ea02f1..bf75a7cec004ffd4453c9121afab8e0c6168b496 100644 (file)
@@ -272,13 +272,13 @@ class FluidbookCompiler extends Base implements CompilerInterface
      * @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();
 
@@ -306,8 +306,7 @@ class FluidbookCompiler extends Base implements CompilerInterface
         $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();
@@ -317,13 +316,8 @@ class FluidbookCompiler extends Base implements CompilerInterface
         $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');
 
index 3b142db8df752ab3cbcb67c84f990c68f3c2ff51..e3f27b9f4d9e7aa1a64f179cecda76f7a4ab345b 100644 (file)
@@ -154,6 +154,14 @@ class FluidbookPublication extends ToolboxSettingsModel
         return __($str);
     }
 
+    /**
+     * @return FluidbookTheme
+     */
+    public function getTheme()
+    {
+        return FluidbookTheme::find($this->theme);
+    }
+
     /**
      * @return string
      */
@@ -257,9 +265,13 @@ class FluidbookPublication extends ToolboxSettingsModel
         return $this->getDocumentSize($page)[1];
     }
 
-    public function getFinalPath()
+    public function getFinalPath($theme = null)
     {
-        return protected_path('fluidbookpublication/final/' . $this->id);
+        $dir = $this->id;
+        if (null === $theme || $theme->id != $this->theme) {
+            $dir .= '-' . $theme->id;
+        }
+        return protected_path('fluidbookpublication/final/' . $dir);
     }
 
     public function getAssetDir()
index d9f6b8bc6443714ce09d15b72edd3a0ecffc120f..5c52e7a40132415f786c6c6f78cf11779d714a11 100644 (file)
@@ -756,7 +756,12 @@ class FluidbookTheme extends ToolboxSettingsModel
      */
     public static function fromArray(array $a)
     {
-        return new FluidbookTheme($a);
+        $res = new FluidbookTheme();
+        $res->id = self::hashThemeArray($a);
+        foreach ($a as $k => $v) {
+            $res->setAttribute($k, $v);
+        }
+        return $res;
     }
 
     public function getStorage()