--- /dev/null
+<?php
+
+namespace App\Http\Controllers\Admin\Operations\FluidbookCollection;
+
+use App\Http\Controllers\Admin\Operations\FluidbookPreviewOperation;
+use App\Jobs\FluidbookCollectionDownload;
+use App\Jobs\FluidbookCompiler;
+use App\Models\FluidbookCollection;
+use App\Models\FluidbookPublication;
+use App\Models\FluidbookTheme;
+use Cubist\Backpack\Http\Controllers\Base\XSendFileController;
+
+// __('!!Paramètres des fluidbooks')
+trait PreviewOperation
+{
+ use FluidbookPreviewOperation;
+
+ protected function setupPreviewRoutes($segment, $routeName, $controller)
+ {
+ $this->_baseRoutes($segment, $controller);
+ }
+
+ protected function setupPreviewDefaults()
+ {
+ $this->crud->addButtonFromView('line', 'preview', 'fluidbook_collection.preview', 'end');
+ }
+
+ protected function _preview($segment, $version, $id, $hash, $time = null, $path = null)
+ {
+ $q = request()->getQueryString();
+ if ($q) {
+ $q = '?' . $q;
+ }
+ $nointerface = !!request('nointerface', false);
+ $shortLoading = !!request('shortLoading', false);
+
+ self::_getCollectionAndTheme($id, $hash, $collection, $theme);
+
+ if (null === $time || ((null === $path || $path === 'index.html') && $time < (time() - 60) && !$nointerface && !$shortLoading)) {
+ $url = backpack_url($segment . '/preview/' . $id . '_' . $hash . '_' . time()) . '/' . $q;
+ return $this->loadingCompile($url, $id, $hash);
+ }
+
+ return $this->preview($version, $collection, $theme, $path);
+ }
+
+
+ /**
+ * @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::_getCollectionAndTheme($id, $hash, $collection, $theme);
+
+ $res = $this->_loadingCompile($theme, $collection->title, $url);
+ return response($res);
+ }
+
+ /**
+ * @param $version string
+ * @param $fluidbook FluidbookPublication
+ * @param $theme FluidbookTheme
+ * @param $path string
+ * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response|object
+ * @throws \Exception
+ */
+ public function preview($version, $collection, $theme, $path = 'index.html')
+ {
+ $nointerface = !!request('nointerface', false);
+ $shortLoading = !!request('shortLoading', false);
+
+ $isScorm = $version === 'scorm';
+
+ $dest = $collection->getFinalPath($theme, $isScorm);
+ if ($path === 'index.html') {
+ $collection->incrementPreviewVisit();
+ $compiler = new FluidbookCollectionDownload($collection, 'export', backpack_user());
+ $compiler->compilePreview();
+ }
+
+ $relayPath = $dest . '/' . $path;
+ if (!file_exists($relayPath)) {
+ throw new \Exception($relayPath . ' not found');
+ }
+ return XSendFileController::sendfile($relayPath);
+ }
+
+ /**
+ * @param $id string
+ * @param $hash string
+ * @param $collection FluidbookCollection
+ * @param $theme FluidbookTheme
+ * @return void
+ */
+ protected static function _getCollectionAndTheme($id, $hash, &$collection, &$theme)
+ {
+ $collection = FluidbookCollection::find($id)->where('hash', $hash)->first();
+ if (null === $collection) {
+ abort(404);
+ }
+ foreach ($collection->publications as $pub) {
+ $firstFluidbookId = $pub['fluidbook'];
+ break;
+ }
+ $fluidbook = FluidbookPublication::find($firstFluidbookId);
+ if (!isset($theme)) {
+ $theme = $fluidbook->getTheme();
+ }
+ }
+}
--- /dev/null
+<?php
+
+namespace App\Http\Controllers\Admin\Operations;
+
+use App\Http\Middleware\CheckIfAdmin;
+use Cubist\Util\Graphics\Color;
+use Illuminate\Support\Facades\Route;
+
+trait FluidbookPreviewOperation
+{
+ protected function _baseRoutes($segment, $controller)
+ {
+ // Redirect to the url with a timestamp to prevent cache
+ Route::match(['get'], $segment . '/preview/{id}_{hash}', function ($id, $hash) use ($segment) {
+ return $this->_preview($segment, 'online', $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) {
+ return $this->_preview($segment, 'online', $id, $hash, $time, $path);
+ })->where('id', '([0-9]+)(-[0-9]+)?')
+ ->where('hash', '[0-9a-f]{32}')
+ ->where('path', '.*')
+ ->withoutMiddleware([CheckIfAdmin::class]);
+ }
+
+ protected function _loadingCompile($theme, $title, $url)
+ {
+ $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('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>' . $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 $res;
+ }
+}
namespace App\Http\Controllers\Admin\Operations\FluidbookPublication;
+use App\Http\Controllers\Admin\Operations\FluidbookPreviewOperation;
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;
+
// __('!!Paramètres des fluidbooks')
trait PreviewOperation
{
+ use FluidbookPreviewOperation;
protected function setupPreviewRoutes($segment, $routeName, $controller)
{
Route::match(['get'], $segment . '/preview/{version}/{id}_{hash}', function ($version, $id, $hash) use ($segment) {
->whereAlpha('version')
->withoutMiddleware([CheckIfAdmin::class]);
- // Redirect to the url with a timestamp to prevent cache
- Route::match(['get'], $segment . '/preview/{id}_{hash}', function ($id, $hash) use ($segment) {
- return $this->_preview($segment, 'online', $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) {
- return $this->_preview($segment, 'online', $id, $hash, $time, $path);
- })->where('id', '([0-9]+)(-[0-9]+)?')
- ->where('hash', '[0-9a-f]{32}')
- ->where('path', '.*')
- ->withoutMiddleware([CheckIfAdmin::class]);
+ $this->_baseRoutes($segment, $controller);
}
protected function setupPreviewDefaults()
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('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>';
+ $res = $this->_loadingCompile($theme, $fluidbook->title, $url);
return response($res);
}
protected function _compile()
{
- $compilepath = protected_path('collection/final/' . $this->entry->id);
- $this->compile($compilepath);
+ $compilepath = $this->entry->getFinalPath();
+ $this->compile($compilepath, true);
return $compilepath;
}
* @return void
* @throws \Exception
*/
- public function compile($path)
+ public function compile($path, $empty = true)
{
$data = $this->entry->getPageData();
- $path = Files::emptyDir($path);
+ if ($empty) {
+ $path = Files::emptyDir($path);
+ }
PHP::neverStop();
if ($data->type === 'scorm_multilang') {
}
}
+ public function compilePreview()
+ {
+ $compilepath = $this->entry->getFinalPath();
+ $this->compile($compilepath, false);
+ return $compilepath;
+ }
+
protected function getCollectionGlobalSettings()
{
$options = [];
return $default;
}
+
public function setSetting($key, $value)
{
if ($this->themeSettings->has($key)) {
$file = $cdir . $this->fluidbookSettings->basketReferences;
$this->config->basketReferences = ExcelToArray::excelToArrayKeyVars($file);
- $this->getLinksAndRulers($links,$rulers);
+ $this->getLinksAndRulers($links, $rulers);
foreach ($links as $link) {
if ($link['type'] == '12') {
}
}
- public function getLinksAndRulers(&$links, &$rulers){
- Links::getLinksAndRulers($this->book_id, $links, $rulers,'latest',true);
+ public function getLinksAndRulers(&$links, &$rulers)
+ {
+ Links::getLinksAndRulers($this->book_id, $links, $rulers, 'latest', true);
}
public function writeMIFCart()
if ($renderer === 'pdfjs') {
- $this->vdir->copyDirectory(WS_COMPILE_ASSETS . '/pdfjs', 'pdfjs');
+ $resource = resource_path('pdfjs/dist-min');
} else if ($renderer === 'pdfjs-legacy') {
- $this->vdir->copyDirectory(WS_COMPILE_ASSETS . '/pdfjs-legacy', 'pdfjs');
+ $resource = resource_path('pdfjs/legacy-min');
}
+ $this->vdir->copyDirectory($resource, 'pdfjs');
$css = '.article #sidebarContainer, .article .toolbar {display:none !important;}';
$css .= '.article .pdfViewer{padding:0 !important;}';
$css .= '.article #viewerContainer{top:0 !important;overflow:visible !important;}';
$css .= '.article{--page-border:0;--page-margin:0;--body-bg-color:transparent;}';
$css .= '.openFile,.rotateCw,.rotateCcw,.rotateCcw + .horizontalToolbarSeparator{display:none !important;}' . $this->fluidbookSettings->PDFJSCSS;
-
- $js = 'window.addEventListener("load", function() {PDFViewerApplication.preferences.set("externalLinkTarget", 2);});';
-
- $this->vdir->file_put_contents('pdfjs/web/viewer.css', file_get_contents(WS_COMPILE_ASSETS . '/' . $renderer . '/web/viewer.css') . $css);
- $this->vdir->file_put_contents('pdfjs/web/viewer.js', $js . ";\n" . file_get_contents(WS_COMPILE_ASSETS . '/' . $renderer . '/web/viewer.js'));
+ $this->vdir->file_put_contents('pdfjs/web/viewer.css', file_get_contents($resource . '/web/viewer.css') . $css);
}
protected function writeJs()
use App\Fields\FluidbookExportVersion;
use App\Http\Controllers\Admin\Operations\FluidbookCollection\DownloadOperation;
+use App\Http\Controllers\Admin\Operations\FluidbookCollection\PreviewOperation;
use App\Models\Base\ToolboxModel;
+use App\Models\Traits\CheckHash;
+use App\Slack\Slack;
use App\SubForms\CollectionPublication;
use App\SubForms\Fluidbook_Setting;
use Cubist\Backpack\Magic\Fields\BunchOfFieldsMultiple;
use Cubist\Backpack\Magic\Fields\Checkbox;
use Cubist\Backpack\Magic\Fields\ExternalPath;
+use Cubist\Backpack\Magic\Fields\Hidden;
+use Cubist\Backpack\Magic\Fields\Integer;
use Cubist\Backpack\Magic\Fields\SelectFromArray;
use Cubist\Backpack\Magic\Fields\Text;
+use Cubist\Util\Files\Files;
// __('!! Collections de fluidbooks')
class FluidbookCollection extends ToolboxModel
{
+ use CheckHash;
+
protected $table = 'fluidbook_collection';
protected $_options = ['name' => 'fluidbook-collection',
'singular' => 'collection',
'plural' => 'collections'];
- protected $_operations = [DownloadOperation::class];
+ protected $_operations = [PreviewOperation::class, DownloadOperation::class];
protected static $_permissionBase = 'fluidbook-collection';
$this->addOwnerField();
+ $this->addField('hash', Hidden::class);
$this->addField('type', SelectFromArray::class, __('Type'), ['column' => true, 'options' => ['export' => __('Export'), 'export_multilang' => __('Export multilingue'), 'scorm_multilang' => __('SCORM multilingue')]]);
$this->addField('locale_switch', Checkbox::class, __('Permettre le changement de langue'), ['when' => ['type' => ['scorm_multilang', 'export_multilang']], 'default' => true]);
$this->addField('version', FluidbookExportVersion::class, __('Version'), ['when' => ['type' => 'export']]);
$this->addField('publications', BunchOfFieldsMultiple::class, __('Publications'), ['bunch' => CollectionPublication::class, 'edit_label' => '%fluidbook > %dir']);
$this->addField('install', ExternalPath::class, 'Installer sur un serveur externe', ['default' => '', 'fake' => true, 'translatable' => false, 'store_in' => 'settings', 'servers_model' => FluidbookExternalInstallServer::class, ['when' => ['type' => ['export', 'export_multilang']]]]);
$this->addField('override_settings', BunchOfFieldsMultiple::class, __('Redéfinir les paramètres lors de l\'export'), ['bunch' => Fluidbook_Setting::class]);
+ $this->addField('visits_counter', Integer::class, 'Compteur de visites', ['read_only' => true, 'default' => 0, 'column' => true, 'column_label' => '<i class="las la-chart-area" title="' . __('Compteur de visites du lien de préview') . '"></i>', 'searchLogic' => false]);
}
public function getFinalPath()
{
- return protected_path('fluidbookcollection/final/' . $this->id);
+ return Files::mkdir(protected_path('fluidbookcollection/final/' . $this->id));
+ }
+
+ public function onSaving(): bool
+ {
+ $this->checkHash();
+ return parent::onSaving();
}
+
+ public function allowsPreview()
+ {
+ return !!$this->hash;
+ }
+
+ public function incrementPreviewVisit()
+ {
+ if (!backpack_user()) {
+ $this->visits_counter++;
+ $this->saveQuietly();
+ if ($this->visits_counter % 20 === 0) {
+ /** @var \App\Models\User $owner */
+ $owner = \App\Models\User::withoutGlobalScopes()->find($this->owner);
+ $actions = [];
+
+ Slack::send(Slack::fluidbookPreviewAlertsChannel,
+ 'Collection #' . $this->id . ' : ' . $this->visits_counter . ' visites',
+ 'Le lien de preview de _' . $this->title . '_ a été utilisé à *' . $this->visits_counter . '* reprises par des visiteurs non authentifiés sur la toolbox. La collection se trouve sur le compte de ' . $owner->getNameWithCompanyAttribute() . '.',
+ $actions,
+ false
+ );
+ }
+ }
+ }
}
use App\Http\Controllers\Admin\Operations\FluidbookPublication\StatsOperation;
use App\Jobs\FluidbookImagesPreprocess;
use App\Models\Base\ToolboxSettingsModel;
+use App\Models\Traits\CheckHash;
use App\Models\Traits\PublicationSettings;
use App\Models\Traits\SCORMVersionTrait;
use App\Slack\Slack;
use PublicationSettings;
use SCORMVersionTrait;
+ use CheckHash;
public function setFields()
{
return parent::onSaved();
}
- protected function checkHash()
- {
- if (!$this->hash) {
- $this->hash = md5(uniqid('fluidbook_hash'), false);
- }
- }
+
protected function setComposedAttributes()
{
--- /dev/null
+<?php
+
+namespace App\Models\Traits;
+
+trait CheckHash
+{
+ protected function checkHash()
+ {
+ if (!$this->hash) {
+ $this->hash = md5(uniqid('fluidbook_hash'), false);
+ }
+ }
+}
"source": {
"type": "git",
"url": "git://git.cubedesigners.com/cubist_util.git",
- "reference": "64323281a1250182f95e7187d13ad15239ff37a7"
+ "reference": "f1358972d45952ca2c2b1ff83aba404fabb3d076"
},
"dist": {
"type": "tar",
- "url": "https://composer.cubedesigners.com/dist/cubist/util/cubist-util-dev-master-91a58a.tar",
- "reference": "64323281a1250182f95e7187d13ad15239ff37a7",
- "shasum": "ae5742d5912900a0fec3d8682eb5cceec2d6956f"
+ "url": "https://composer.cubedesigners.com/dist/cubist/util/cubist-util-dev-master-49ab63.tar",
+ "reference": "f1358972d45952ca2c2b1ff83aba404fabb3d076",
+ "shasum": "fdec46a6c1c5f65735e4432a0bc30afccca55136"
},
"require": {
"cubist/net": "dev-master",
}
],
"description": "Utilities class",
- "time": "2023-03-22T17:16:53+00:00"
+ "time": "2023-03-31T15:50:03+00:00"
},
{
"name": "cviebrock/eloquent-sluggable",
"source": {
"type": "git",
"url": "git://git.cubedesigners.com/fluidbook_tools.git",
- "reference": "33472af7df33e6095bf65bdcefbd1162207ab3a6"
+ "reference": "00cdc67442f8c8bab53ec58593baa3adf705bd74"
},
"dist": {
"type": "tar",
- "url": "https://composer.cubedesigners.com/dist/fluidbook/tools/fluidbook-tools-dev-master-0eb654.tar",
- "reference": "33472af7df33e6095bf65bdcefbd1162207ab3a6",
- "shasum": "bad96b39e6fa52960158a1ef50a9da61dd909b5f"
+ "url": "https://composer.cubedesigners.com/dist/fluidbook/tools/fluidbook-tools-dev-master-a050b1.tar",
+ "reference": "00cdc67442f8c8bab53ec58593baa3adf705bd74",
+ "shasum": "99be90d75de1395ab7c1c4410ba023998730f2cb"
},
"require": {
"barryvdh/laravel-debugbar": "^3.6",
}
],
"description": "Fluidbook Tools",
- "time": "2023-03-30T09:40:52+00:00"
+ "time": "2023-04-03T13:12:37+00:00"
},
{
"name": "genealabs/laravel-model-caching",
},
{
"name": "php-http/discovery",
- "version": "1.15.2",
+ "version": "1.15.3",
"source": {
"type": "git",
"url": "https://github.com/php-http/discovery.git",
- "reference": "5cc428320191ac1d0b6520034c2dc0698628ced5"
+ "reference": "3ccd28dd9fb34b52db946abea1b538568e34eae8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/php-http/discovery/zipball/5cc428320191ac1d0b6520034c2dc0698628ced5",
- "reference": "5cc428320191ac1d0b6520034c2dc0698628ced5",
+ "url": "https://api.github.com/repos/php-http/discovery/zipball/3ccd28dd9fb34b52db946abea1b538568e34eae8",
+ "reference": "3ccd28dd9fb34b52db946abea1b538568e34eae8",
"shasum": ""
},
"require": {
],
"support": {
"issues": "https://github.com/php-http/discovery/issues",
- "source": "https://github.com/php-http/discovery/tree/1.15.2"
+ "source": "https://github.com/php-http/discovery/tree/1.15.3"
},
- "time": "2023-02-11T08:28:41+00:00"
+ "time": "2023-03-31T14:40:37+00:00"
},
{
"name": "php-http/httplug",
},
{
"name": "symfony/console",
- "version": "v5.4.21",
+ "version": "v5.4.22",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
- "reference": "c77433ddc6cdc689caf48065d9ea22ca0853fbd9"
+ "reference": "3cd51fd2e6c461ca678f84d419461281bd87a0a8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/c77433ddc6cdc689caf48065d9ea22ca0853fbd9",
- "reference": "c77433ddc6cdc689caf48065d9ea22ca0853fbd9",
+ "url": "https://api.github.com/repos/symfony/console/zipball/3cd51fd2e6c461ca678f84d419461281bd87a0a8",
+ "reference": "3cd51fd2e6c461ca678f84d419461281bd87a0a8",
"shasum": ""
},
"require": {
"homepage": "https://symfony.com",
"keywords": [
"cli",
- "command line",
+ "command-line",
"console",
"terminal"
],
"support": {
- "source": "https://github.com/symfony/console/tree/v5.4.21"
+ "source": "https://github.com/symfony/console/tree/v5.4.22"
},
"funding": [
{
"type": "tidelift"
}
],
- "time": "2023-02-25T16:59:41+00:00"
+ "time": "2023-03-25T09:27:28+00:00"
},
{
"name": "symfony/css-selector",
},
{
"name": "symfony/event-dispatcher",
- "version": "v6.2.7",
+ "version": "v6.2.8",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
- "reference": "404b307de426c1c488e5afad64403e5f145e82a5"
+ "reference": "04046f35fd7d72f9646e721fc2ecb8f9c67d3339"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/404b307de426c1c488e5afad64403e5f145e82a5",
- "reference": "404b307de426c1c488e5afad64403e5f145e82a5",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/04046f35fd7d72f9646e721fc2ecb8f9c67d3339",
+ "reference": "04046f35fd7d72f9646e721fc2ecb8f9c67d3339",
"shasum": ""
},
"require": {
"description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/event-dispatcher/tree/v6.2.7"
+ "source": "https://github.com/symfony/event-dispatcher/tree/v6.2.8"
},
"funding": [
{
"type": "tidelift"
}
],
- "time": "2023-02-14T08:44:56+00:00"
+ "time": "2023-03-20T16:06:02+00:00"
},
{
"name": "symfony/event-dispatcher-contracts",
},
{
"name": "symfony/http-client",
- "version": "v6.2.7",
+ "version": "v6.2.8",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-client.git",
- "reference": "0a5be6cbc570ae23b51b49d67341f378629d78e4"
+ "reference": "66391ba3a8862c560e1d9134c96d9bd2a619b477"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-client/zipball/0a5be6cbc570ae23b51b49d67341f378629d78e4",
- "reference": "0a5be6cbc570ae23b51b49d67341f378629d78e4",
+ "url": "https://api.github.com/repos/symfony/http-client/zipball/66391ba3a8862c560e1d9134c96d9bd2a619b477",
+ "reference": "66391ba3a8862c560e1d9134c96d9bd2a619b477",
"shasum": ""
},
"require": {
],
"description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously",
"homepage": "https://symfony.com",
+ "keywords": [
+ "http"
+ ],
"support": {
- "source": "https://github.com/symfony/http-client/tree/v6.2.7"
+ "source": "https://github.com/symfony/http-client/tree/v6.2.8"
},
"funding": [
{
"type": "tidelift"
}
],
- "time": "2023-02-21T10:54:55+00:00"
+ "time": "2023-03-31T09:14:44+00:00"
},
{
"name": "symfony/http-client-contracts",
},
{
"name": "symfony/http-foundation",
- "version": "v5.4.21",
+ "version": "v5.4.22",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-foundation.git",
- "reference": "3bb6ee5582366c4176d5ce596b380117c8200bbf"
+ "reference": "05cd1acdd0e3ce8473aaba1d86c188321d85f313"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-foundation/zipball/3bb6ee5582366c4176d5ce596b380117c8200bbf",
- "reference": "3bb6ee5582366c4176d5ce596b380117c8200bbf",
+ "url": "https://api.github.com/repos/symfony/http-foundation/zipball/05cd1acdd0e3ce8473aaba1d86c188321d85f313",
+ "reference": "05cd1acdd0e3ce8473aaba1d86c188321d85f313",
"shasum": ""
},
"require": {
"description": "Defines an object-oriented layer for the HTTP specification",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/http-foundation/tree/v5.4.21"
+ "source": "https://github.com/symfony/http-foundation/tree/v5.4.22"
},
"funding": [
{
"type": "tidelift"
}
],
- "time": "2023-02-17T21:35:35+00:00"
+ "time": "2023-03-28T07:28:17+00:00"
},
{
"name": "symfony/http-kernel",
- "version": "v5.4.21",
+ "version": "v5.4.22",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-kernel.git",
- "reference": "09c19fc7e4218fbcf73fe0330eea38d66064b775"
+ "reference": "2d3a8be2c756353627398827c409af6f126c096d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-kernel/zipball/09c19fc7e4218fbcf73fe0330eea38d66064b775",
- "reference": "09c19fc7e4218fbcf73fe0330eea38d66064b775",
+ "url": "https://api.github.com/repos/symfony/http-kernel/zipball/2d3a8be2c756353627398827c409af6f126c096d",
+ "reference": "2d3a8be2c756353627398827c409af6f126c096d",
"shasum": ""
},
"require": {
"description": "Provides a structured process for converting a Request into a Response",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/http-kernel/tree/v5.4.21"
+ "source": "https://github.com/symfony/http-kernel/tree/v5.4.22"
},
"funding": [
{
"type": "tidelift"
}
],
- "time": "2023-02-28T13:19:09+00:00"
+ "time": "2023-03-31T11:54:37+00:00"
},
{
"name": "symfony/mime",
},
{
"name": "symfony/process",
- "version": "v5.4.21",
+ "version": "v5.4.22",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
- "reference": "d4ce417ebcb0b7d090b4c178ed6d3accc518e8bd"
+ "reference": "4b850da0cc3a2a9181c1ed407adbca4733dc839b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/process/zipball/d4ce417ebcb0b7d090b4c178ed6d3accc518e8bd",
- "reference": "d4ce417ebcb0b7d090b4c178ed6d3accc518e8bd",
+ "url": "https://api.github.com/repos/symfony/process/zipball/4b850da0cc3a2a9181c1ed407adbca4733dc839b",
+ "reference": "4b850da0cc3a2a9181c1ed407adbca4733dc839b",
"shasum": ""
},
"require": {
"description": "Executes commands in sub-processes",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/process/tree/v5.4.21"
+ "source": "https://github.com/symfony/process/tree/v5.4.22"
},
"funding": [
{
"type": "tidelift"
}
],
- "time": "2023-02-21T19:46:44+00:00"
+ "time": "2023-03-06T21:29:33+00:00"
},
{
"name": "symfony/routing",
- "version": "v5.4.21",
+ "version": "v5.4.22",
"source": {
"type": "git",
"url": "https://github.com/symfony/routing.git",
- "reference": "2ea0f3049076e8ef96eab203a809d6b2332f0361"
+ "reference": "c2ac11eb34947999b7c38fb4c835a57306907e6d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/routing/zipball/2ea0f3049076e8ef96eab203a809d6b2332f0361",
- "reference": "2ea0f3049076e8ef96eab203a809d6b2332f0361",
+ "url": "https://api.github.com/repos/symfony/routing/zipball/c2ac11eb34947999b7c38fb4c835a57306907e6d",
+ "reference": "c2ac11eb34947999b7c38fb4c835a57306907e6d",
"shasum": ""
},
"require": {
"url"
],
"support": {
- "source": "https://github.com/symfony/routing/tree/v5.4.21"
+ "source": "https://github.com/symfony/routing/tree/v5.4.22"
},
"funding": [
{
"type": "tidelift"
}
],
- "time": "2023-02-16T09:33:00+00:00"
+ "time": "2023-03-14T14:59:20+00:00"
},
{
"name": "symfony/serializer",
- "version": "v6.2.7",
+ "version": "v6.2.8",
"source": {
"type": "git",
"url": "https://github.com/symfony/serializer.git",
- "reference": "df9599873fdc2540e6f4291f49be4fcc167e9cbf"
+ "reference": "db9d36470bf0990990fda9320b8b001bb582f075"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/serializer/zipball/df9599873fdc2540e6f4291f49be4fcc167e9cbf",
- "reference": "df9599873fdc2540e6f4291f49be4fcc167e9cbf",
+ "url": "https://api.github.com/repos/symfony/serializer/zipball/db9d36470bf0990990fda9320b8b001bb582f075",
+ "reference": "db9d36470bf0990990fda9320b8b001bb582f075",
"shasum": ""
},
"require": {
"conflict": {
"doctrine/annotations": "<1.12",
"phpdocumentor/reflection-docblock": "<3.2.2",
- "phpdocumentor/type-resolver": "<1.4.0|>=1.7.0",
+ "phpdocumentor/type-resolver": "<1.4.0",
"symfony/dependency-injection": "<5.4",
"symfony/property-access": "<5.4",
"symfony/property-info": "<5.4",
"description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/serializer/tree/v6.2.7"
+ "source": "https://github.com/symfony/serializer/tree/v6.2.8"
},
"funding": [
{
"type": "tidelift"
}
],
- "time": "2023-02-24T10:42:00+00:00"
+ "time": "2023-03-31T09:14:44+00:00"
},
{
"name": "symfony/service-contracts",
},
{
"name": "symfony/string",
- "version": "v6.2.7",
+ "version": "v6.2.8",
"source": {
"type": "git",
"url": "https://github.com/symfony/string.git",
- "reference": "67b8c1eec78296b85dc1c7d9743830160218993d"
+ "reference": "193e83bbd6617d6b2151c37fff10fa7168ebddef"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/string/zipball/67b8c1eec78296b85dc1c7d9743830160218993d",
- "reference": "67b8c1eec78296b85dc1c7d9743830160218993d",
+ "url": "https://api.github.com/repos/symfony/string/zipball/193e83bbd6617d6b2151c37fff10fa7168ebddef",
+ "reference": "193e83bbd6617d6b2151c37fff10fa7168ebddef",
"shasum": ""
},
"require": {
"utf8"
],
"support": {
- "source": "https://github.com/symfony/string/tree/v6.2.7"
+ "source": "https://github.com/symfony/string/tree/v6.2.8"
},
"funding": [
{
"type": "tidelift"
}
],
- "time": "2023-02-24T10:42:00+00:00"
+ "time": "2023-03-20T16:06:02+00:00"
},
{
"name": "symfony/translation",
- "version": "v6.2.7",
+ "version": "v6.2.8",
"source": {
"type": "git",
"url": "https://github.com/symfony/translation.git",
- "reference": "90db1c6138c90527917671cd9ffa9e8b359e3a73"
+ "reference": "817535dbb1721df8b3a8f2489dc7e50bcd6209b5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/translation/zipball/90db1c6138c90527917671cd9ffa9e8b359e3a73",
- "reference": "90db1c6138c90527917671cd9ffa9e8b359e3a73",
+ "url": "https://api.github.com/repos/symfony/translation/zipball/817535dbb1721df8b3a8f2489dc7e50bcd6209b5",
+ "reference": "817535dbb1721df8b3a8f2489dc7e50bcd6209b5",
"shasum": ""
},
"require": {
"description": "Provides tools to internationalize your application",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/translation/tree/v6.2.7"
+ "source": "https://github.com/symfony/translation/tree/v6.2.8"
},
"funding": [
{
"type": "tidelift"
}
],
- "time": "2023-02-24T10:42:00+00:00"
+ "time": "2023-03-31T09:14:44+00:00"
},
{
"name": "symfony/translation-contracts",
},
{
"name": "symfony/var-dumper",
- "version": "v5.4.21",
+ "version": "v5.4.22",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
- "reference": "6c5ac3a1be8b849d59a1a77877ee110e1b55eb74"
+ "reference": "e2edac9ce47e6df07e38143c7cfa6bdbc1a6dcc4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/var-dumper/zipball/6c5ac3a1be8b849d59a1a77877ee110e1b55eb74",
- "reference": "6c5ac3a1be8b849d59a1a77877ee110e1b55eb74",
+ "url": "https://api.github.com/repos/symfony/var-dumper/zipball/e2edac9ce47e6df07e38143c7cfa6bdbc1a6dcc4",
+ "reference": "e2edac9ce47e6df07e38143c7cfa6bdbc1a6dcc4",
"shasum": ""
},
"require": {
"dump"
],
"support": {
- "source": "https://github.com/symfony/var-dumper/tree/v5.4.21"
+ "source": "https://github.com/symfony/var-dumper/tree/v5.4.22"
},
"funding": [
{
"type": "tidelift"
}
],
- "time": "2023-02-23T10:00:28+00:00"
+ "time": "2023-03-25T09:27:28+00:00"
},
{
"name": "symfony/yaml",
},
{
"name": "phpdocumentor/type-resolver",
- "version": "1.6.2",
+ "version": "1.7.1",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/TypeResolver.git",
- "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d"
+ "reference": "dfc078e8af9c99210337325ff5aa152872c98714"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/48f445a408c131e38cab1c235aa6d2bb7a0bb20d",
- "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d",
+ "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/dfc078e8af9c99210337325ff5aa152872c98714",
+ "reference": "dfc078e8af9c99210337325ff5aa152872c98714",
"shasum": ""
},
"require": {
+ "doctrine/deprecations": "^1.0",
"php": "^7.4 || ^8.0",
- "phpdocumentor/reflection-common": "^2.0"
+ "phpdocumentor/reflection-common": "^2.0",
+ "phpstan/phpdoc-parser": "^1.13"
},
"require-dev": {
"ext-tokenizer": "*",
+ "phpbench/phpbench": "^1.2",
"phpstan/extension-installer": "^1.1",
"phpstan/phpstan": "^1.8",
"phpstan/phpstan-phpunit": "^1.1",
"description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
"support": {
"issues": "https://github.com/phpDocumentor/TypeResolver/issues",
- "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.2"
+ "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.7.1"
+ },
+ "time": "2023-03-27T19:02:04+00:00"
+ },
+ {
+ "name": "phpstan/phpdoc-parser",
+ "version": "1.16.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpstan/phpdoc-parser.git",
+ "reference": "e27e92d939e2e3636f0a1f0afaba59692c0bf571"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/e27e92d939e2e3636f0a1f0afaba59692c0bf571",
+ "reference": "e27e92d939e2e3636f0a1f0afaba59692c0bf571",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.2 || ^8.0"
+ },
+ "require-dev": {
+ "php-parallel-lint/php-parallel-lint": "^1.2",
+ "phpstan/extension-installer": "^1.0",
+ "phpstan/phpstan": "^1.5",
+ "phpstan/phpstan-phpunit": "^1.1",
+ "phpstan/phpstan-strict-rules": "^1.0",
+ "phpunit/phpunit": "^9.5",
+ "symfony/process": "^5.2"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "PHPStan\\PhpDocParser\\": [
+ "src/"
+ ]
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "PHPDoc parser with support for nullable, intersection and generic types",
+ "support": {
+ "issues": "https://github.com/phpstan/phpdoc-parser/issues",
+ "source": "https://github.com/phpstan/phpdoc-parser/tree/1.16.1"
},
- "time": "2022-10-14T12:47:21+00:00"
+ "time": "2023-02-07T18:11:17+00:00"
},
{
"name": "phpunit/php-code-coverage",
$(function () {
-
+ PDFViewerApplication.preferences.set("externalLinkTarget", 2);
});
--- /dev/null
+{{-- __('!! Paramètres des fluidbooks') --}}
+@php
+ $actions=['preview'=>['label'=>__('Version online'),'url'=>$crud->route.'/preview/'.$entry->getKey().'_'.$entry->hash,'target'=>'_blank']];
+@endphp
+
+@if($entry->allowsPreview())
+ <a class="btn btn-sm btn-link" target="{!! $actions['preview']['target'] !!}"
+ href="{!! $actions['preview']['url'] !!}"
+ @if(count($actions)>1)
+ data-context-actions="{{json_encode($actions)}}"
+ data-context-route="{{$crud->route}}/$id/edit/$action"
+ data-context-id="{{$entry->getKey()}}"
+ @endif
+ data-toggle="tooltip"
+ title="{{__('Voir la collection')}}"><i class="las la-eye"></i> {{__('Voir')}}
+ </a>
+@endif