// __('!! e-Learning')
use App\Http\Middleware\CheckIfAdmin;
+use App\Jobs\ScormDownloadBase;
+use App\Models\Base\ToolboxStatusModel;
use Cubist\Backpack\Http\Controllers\Base\XSendFileController;
use Illuminate\Support\Facades\Route;
use Prologue\Alerts\Facades\Alert;
{
protected function setupDownloadRoutes($segment, $routeName, $controller)
{
- Route::match(['get'], $segment . '/{id}/package/{action}/{version?}', $controller . '@package');
+ Route::match(['get'], $segment . '/{id}/package/{action}/{version?}', $controller . '@package')->whereNumber('id');
Route::match(['get'], $segment . '/{id}_{hash}/download/{file}', $controller . '@download')->withoutMiddleware([CheckIfAdmin::class]);;
}
abort(401);
}
$instance = $model::withoutGlobalScopes()->find($id);
- $version = $version ?? $instance->scorm_version;
- $job::dispatch($instance, $action, $version, backpack_user())->onQueue('download');;
+ if (is_subclass_of($job, ScormDownloadBase::class)) {
+ $version = $version ?? $instance->scorm_version ?? null;
+ $job::dispatch($instance, $action, $version, backpack_user())->onQueue('download');
+ } else {
+ $job::dispatch($instance, $action, backpack_user())->onQueue('download');
+ }
+
+ if ($instance instanceof ToolboxStatusModel) {
+ // Mark the fluidbook as downloaded when status is ready and user is not an admin
+ if ($instance->status == 1 && backpack_user() && $instance->canAdmin(backpack_user())) {
+ $instance->setStatus(2);
+ $instance->save();
+ }
+ }
+
+
Alert::add('success', __('La compilation a été placée en file d\'attente. Vous recevrez un email lorsqu\'elle sera terminée.'))->flash();
return redirect(backpack_url($entry->getOption('name')));
}
protected function download($id, $hash, $file)
{
+ $e = explode('-', $file);
+ if ($e[1] != $id) {
+ abort(404, __('Erreur de correspondance du fichier'));
+ }
$entry = $this->getModelInstance();
$model = get_class($entry);
if (null === $instance) {
abort(404, __('Ce fichier est indisponible'));
}
- $path = protected_path($entry->getOption('name') . '/download/' . $id . '/' . $file);
+ $path = protected_path(str_replace('-', '', $entry->getOption('name')) . '/download/' . $id . '/' . $file);
if (!file_exists($path)) {
abort(404, __('Le fichier n\'existe pas'));
}
return XSendFileController::sendfile($path);
}
+
}
namespace App\Http\Controllers\Admin\Operations\ELearningMedia;
-use Cubist\Util\Files\Files;
-use Illuminate\Support\Facades\Route;
+use App\Http\Controllers\Admin\Operations\ElearningPreviewOperation;
+use App\Models\ELearningMedia;
trait PreviewOperation
{
- protected function setupPreviewRoutes($segment, $routeName, $controller)
- {
- Route::match(['get'], $segment . '/{id}/preview/{path?}', $controller . '@preview')
- ->where(['id' => '[0-9]+', 'path' => '.*']);
- }
+ use ElearningPreviewOperation;
- protected function setupPreviewDefaults()
- {
- $this->crud->addButtonFromView('line', 'open_preview', 'elearningmedia.preview', 'begining');
- }
+ protected $button = 'elearningmedia';
+ protected $path = 'elearningmedia';
+ protected $entryClass=ElearningMedia::class;
- protected function preview($id, $path = 'index.html')
- {
- $entry = $this->crud->getEntry($id);
- $dest = $entry->getFinalPath();
- if ($path === 'index.html') {
+ protected function getCompileMessage()
+ {
+ return __('Compilation du media en cours');
+ }
- $entry->compile($dest);
- }
- $p = $dest . '/' . $path;
- return response(null)->header('Content-Type', Files::_getMimeType($p))->header('X-Sendfile', $p);
- }
}
namespace App\Http\Controllers\Admin\Operations\ELearningPackage;
-use Cubist\Util\Files\Files;
-use Illuminate\Support\Facades\Route;
+use App\Http\Controllers\Admin\Operations\ElearningPreviewOperation;
+use App\Models\ELearningMedia;
+use App\Models\ELearningPackage;
// __('!! e-Learning')
trait PreviewOperation
{
- protected function setupPreviewRoutes($segment, $routeName, $controller)
- {
- Route::match(['get'], $segment . '/{id}/preview/{path?}', $controller . '@preview')
- ->where(['id' => '[0-9]+', 'path' => '.*']);
- }
+ use ElearningPreviewOperation;
- protected function setupPreviewDefaults()
- {
- $this->crud->addButtonFromView('line', 'open_preview', 'elearningpackage.preview', 'begining');
- }
+ protected $button = 'elearningpackage';
+ protected $path = 'elearningpackage';
- protected function preview($id, $path = 'index.html')
- {
- $entry = $this->crud->getEntry($id);
- $dest = $entry->getFinalPath();
-
- if ($path === 'index.html') {
- $entry->compile($dest);
- }
+ protected $entryClass = ELearningPackage::class;
- $p = $dest . '/' . $path;
- return response(null)->header('Content-Type', Files::_getMimeType($p))->header('X-Sendfile', $p);
+ protected function getCompileMessage()
+ {
+ return __('Compilation du package en cours');
}
}
--- /dev/null
+<?php
+
+namespace App\Http\Controllers\Admin\Operations;
+
+use App\Http\Middleware\CheckIfAdmin;
+use App\Models\Quiz;
+use App\Models\QuizTheme;
+use Cubist\Util\Files\Files;
+use Cubist\Util\Graphics\Color;
+use Cubist\Util\PHP;
+use Illuminate\Support\Facades\Route;
+
+trait ElearningPreviewOperation
+{
+ use FluidbookPreviewOperation;
+ protected function setupPreviewRoutes($segment, $routeName, $controller)
+
+ {
+ Route::match(['get'], $segment . '/preview/{id}_{hash}', function ($id, $hash) use ($segment) {
+ return $this->_preview($segment, $id, $hash, null, 'index.html');
+ })->where('id', '([0-9]+)(-[0-9]+)?')
+ ->where('hash', '[0-9a-f]{32}')
+ ->withoutMiddleware([CheckIfAdmin::class])
+ ->name($segment . '_preview');
+
+ Route::match(['get'], $segment . '/preview/{id}_{hash}_{time}/{path?}', function ($id, $hash, $time, $path = 'index.html') use ($segment, $controller) {
+ return $this->_preview($segment, $id, $hash, $time, $path);
+ })->where('id', '([0-9]+)(-[0-9]+)?')
+ ->where('hash', '[0-9a-f]{32}')
+ ->where('path', '.*')
+ ->whereNumber('time')
+ ->withoutMiddleware([CheckIfAdmin::class])
+ ->name($segment . '_preview_with_time');
+ }
+
+ protected function setupPreviewDefaults()
+ {
+ $this->crud->addButtonFromView('line', 'open_preview', 'preview', 'begining');
+ }
+
+ protected function _preview($segment, $id, $hash, $time = null, $path = null)
+ {
+ PHP::neverStop(true);
+ $q = request()->getQueryString();
+ if ($q) {
+ $q = '?' . $q;
+ }
+ $nointerface = !!request('nointerface', false);
+ $shortLoading = !!request('shortLoading', false);
+ $forceTheme = false;
+
+ $this->_getEntryAndTheme($id, $hash, $entry, $theme, $forceTheme);
+
+ if (null === $time || ((null === $path || $path === 'index.html') && $time > 0 && $time < (time() - 60) && !$nointerface && !$shortLoading)) {
+ $url = backpack_url($segment . '/preview/' . $id . '_' . $hash . '_' . time()) . '/' . $q;
+ return $this->loadingCompile($url, $id, $hash);
+ }
+
+ return $this->preview($entry, $theme, $forceTheme, $path);
+ }
+
+ /**
+ * @param Quiz $quiz
+ * @param QuizTheme $theme
+ * @param string $path
+ * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Foundation\Application|\Illuminate\Http\Response
+ */
+ protected function preview($entry, $theme, $forceTheme = false, $path = 'index.html')
+ {
+ $id = $forceTheme ? $entry->id . '-' . $theme->id : $entry->id;
+
+ $dest = protected_path($this->path . '/final/' . $id);
+ if ($path === 'index.html') {
+ $entry->compile($dest, $theme);
+ }
+ $p = $dest . '/' . $path;
+ return response(null)->header('Content-Type', Files::_getMimeType($p))->header('X-Sendfile', $p);
+ }
+
+ /**
+ * @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)
+ {
+ PHP::neverStop(false);
+
+ self::_getEntryAndTheme($id, $hash, $entry, $theme, $forceTheme);
+ if (null === $entry) {
+ abort(404);
+ }
+
+ $back = $theme->backgroundColor;
+ $text = (new Color($back))->closestColor([(new Color('#000000')), (new Color('#ffffff'))], true)->toCss();
+
+ $res = $this->_compileScreen(
+ $entry->title, $url, $this->getCompileMessage()
+ ,
+ __('Cette étape ne sera pas nécessaire lorsque le contenu sera installé sur son emplacement définitif'),
+ $back,
+ $text,
+ );
+ return response($res);
+ }
+
+ protected function getCompileMessage()
+ {
+ return __('Compilation du quiz en cours');
+ }
+
+ /**
+ * @param $id string
+ * @param $hash string
+ * @param $entry Quiz
+ * @param $theme QuizTheme
+ * @return void
+ */
+ protected function _getEntryAndTheme($id, $hash, &$entry, &$theme, &$forceTheme)
+ {
+ $theme = new \stdClass();
+ $theme->backgroundColor = '#ffffff';
+ $this->id = 0;
+
+ $c = $this->entryClass;
+
+ $entry = $c::withoutGlobalScopes()->where('id', $id)->where('hash', $hash)->first();
+ if (null === $entry) {
+ abort(404, __('Lien de prévisualisation invalide'));
+ }
+ $forceTheme = false;
+ }
+}
namespace App\Http\Controllers\Admin\Operations\FluidbookCollection;
+use App\Http\Controllers\Admin\Operations\Base\BaseDownloadOperation;
use App\Http\Middleware\CheckIfAdmin;
use App\Jobs\FluidbookCollectionDownload;
+use App\Jobs\QuizDownload;
use App\Models\FluidbookCollection;
use Cubist\Backpack\Http\Controllers\Base\XSendFileController;
use Illuminate\Support\Facades\Route;
trait DownloadOperation
{
- protected function setupDownloadRoutes($segment, $routeName, $controller)
- {
+ use BaseDownloadOperation;
- Route::match(['get'], $segment . '/{id}_{hash}/download/{file}', $controller . '@downloadFile')->withoutMiddleware([CheckIfAdmin::class]);;
- Route::match(['get'], $segment . '/{id}/download/{action}', $controller . '@download')->whereNumber('id');
- }
+ protected $button = 'fluidbook_collection';
+ protected $downloadJob = FluidbookCollectionDownload::class;
- protected function setupDownloadDefaults()
- {
- $this->crud->addButtonFromView('line', 'download', 'fluidbook_collection.download', 'end');
- }
-
- protected function download($id, $action)
- {
- $collection = FluidbookCollection::withoutGlobalScopes()->find($id);
- FluidbookCollectionDownload::dispatch($collection, $action, backpack_user())->onQueue('download');
-
- // Mark the fluidbook as downloaded when status is ready and user is not an admin
- if ($collection->status == 1 && !can('fluidbook-publication:admin')) {
- $collection->setStatus(2);
- $collection->save();
- }
-
- Alert::add('success', __('La compilation a été placée en file d\'attente. Vous recevrez un email lorsqu\'elle sera terminée.'))->flash();
- return redirect(backpack_url('fluidbook-collection'));
- }
-
- protected function downloadFile($id, $hash, $file)
- {
- $e = explode('-', $file);
- if ($e[1] != $id) {
- abort(404, __('Erreur de correspondance du fichier'));
- }
- $collection = FluidbookCollection::where('id', $id)->where('hash', $hash)->first();
- if (null === $collection) {
- abort(404, __('Ce fichier est indisponible'));
- }
- $path = protected_path('fluidbookcollection/download/' . $id . '/' . $file);
- if (!file_exists($path)) {
- abort(404, __('Le fichier n\'existe pas'));
- }
- return XSendFileController::sendfile($path);
- }
}
namespace App\Http\Controllers\Admin\Operations\Quiz;
use App\Http\Controllers\Admin\Operations\FluidbookPreviewOperation;
+use App\Http\Controllers\Admin\Operations\ElearningPreviewOperation;
use App\Http\Middleware\CheckIfAdmin;
use App\Models\FluidbookTheme;
use App\Models\Quiz;
trait PreviewOperation
{
- use FluidbookPreviewOperation;
- protected function setupPreviewRoutes($segment, $routeName, $controller)
- {
- Route::match(['get'], $segment . '/preview/{id}_{hash}', function ($id, $hash) use ($segment) {
- return $this->_preview($segment, $id, $hash, null, 'index.html');
- })->where('id', '([0-9]+)(-[0-9]+)?')
- ->where('hash', '[0-9a-f]{32}')
- ->withoutMiddleware([CheckIfAdmin::class])
- ->name('quiz_preview');
-
- Route::match(['get'], $segment . '/preview/{id}_{hash}_{time}/{path?}', function ($id, $hash, $time, $path = 'index.html') use ($segment, $controller) {
- return $this->_preview($segment, $id, $hash, $time, $path);
- })->where('id', '([0-9]+)(-[0-9]+)?')
- ->where('hash', '[0-9a-f]{32}')
- ->where('path', '.*')
- ->whereNumber('time')
- ->withoutMiddleware([CheckIfAdmin::class])
- ->name('quiz_preview_with_time');
- }
-
- protected function setupPreviewDefaults()
- {
- $this->crud->addButtonFromView('line', 'open_preview', 'quiz.preview', 'begining');
- }
-
-
- protected function _preview($segment, $id, $hash, $time = null, $path = null)
- {
- PHP::neverStop(true);
- $q = request()->getQueryString();
- if ($q) {
- $q = '?' . $q;
- }
- $nointerface = !!request('nointerface', false);
- $shortLoading = !!request('shortLoading', false);
- $forceTheme = false;
-
- self::_getQuizAndTheme($id, $hash, $quiz, $theme, $forceTheme);
-
- if (null === $time || ((null === $path || $path === 'index.html') && $time > 0 && $time < (time() - 60) && !$nointerface && !$shortLoading)) {
- $url = backpack_url($segment . '/preview/' . $id . '_' . $hash . '_' . time()) . '/' . $q;
- return $this->loadingCompile($url, $id, $hash);
- }
-
- return $this->preview($quiz, $theme, $forceTheme, $path);
- }
+ use ElearningPreviewOperation;
+ protected $button = 'quiz';
+ protected $entryClass = Quiz::class;
- /**
- * @param Quiz $quiz
- * @param QuizTheme $theme
- * @param string $path
- * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Foundation\Application|\Illuminate\Http\Response
- */
- protected function preview($quiz, $theme, $forceTheme = false, $path = 'index.html')
- {
- $id = $forceTheme ? $quiz->id . '-' . $theme->id : $quiz->id;
-
- $dest = protected_path('quiz/final/' . $id);
- if ($path === 'index.html') {
- $quiz->compile($dest, $theme);
- }
- $p = $dest . '/' . $path;
- return response(null)->header('Content-Type', Files::_getMimeType($p))->header('X-Sendfile', $p);
- }
-
- /**
- * @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)
- {
- PHP::neverStop(false);
-
- self::_getQuizAndTheme($id, $hash, $quiz, $theme, $forceTheme);
- if (null === $theme || null === $quiz) {
- abort(404);
- }
+ protected $path='quiz';
- $back = $theme->backgroundColor;
- $text = (new Color($back))->closestColor([(new Color('#000000')), (new Color('#ffffff'))], true)->toCss();
- $res = $this->_compileScreen(
- $quiz->title, $url, __('Compilation du quiz en cours'),
- __('Cette étape ne sera pas nécessaire lorsque le fluidbook sera installé sur son emplacement définitif'),
- $back,
- $text,
- );
- return response($res);
+ protected function getCompileMessage(){
+ return __('Compilation du quiz en cours');
}
/**
* @param $theme QuizTheme
* @return void
*/
- protected static function _getQuizAndTheme($id, $hash, &$quiz, &$theme, &$forceTheme)
+ protected function _getEntryAndTheme($id, $hash, &$quiz, &$theme, &$forceTheme)
{
$ee = explode('-', $id);
$forceThemeData = request('theme', false);
protected function _url($fname)
{
- return url('/' . $this->getBaseURL() . '/' . $this->entry->id . '_' . $this->entry->hash . '/' . $fname);
+ return url('/' . $this->getBaseURL() . '/' . $this->entry->id . '_' . $this->entry->hash . '/download/' . $fname);
}
protected function _title()
use App\Jobs\Base;
use App\Models\ELearningMedia;
use App\Models\ELearningPackage;
+use App\Models\FluidbookCollection;
use App\Models\FluidbookPublication;
use App\Models\Quiz;
use Illuminate\Support\Facades\Log;
{
public function handle()
{
- $classes = ['Quiz' => Quiz::class, 'Elearning Media' => ELearningMedia::class, 'Elearning Package' => ELearningPackage::class];
+ $classes = ['Quiz' => Quiz::class, 'Elearning Media' => ELearningMedia::class, 'Elearning Package' => ELearningPackage::class, 'Collection' => FluidbookCollection::class];
foreach ($classes as $name => $class) {
$class::withoutGlobalScopes()->where('created_ok', '0')->forceDelete();
})->get() as $instance) {
$instance->save();
};
-
-
}
/** @var FluidbookPublication $fluidbook */
public function getFinalPath()
{
- return Files::mkdir(protected_path($this->getOption('name') . '/final/' . $this->id));
+ return Files::mkdir(protected_path(str_replace('-', '', $this->getOption('name')) . '/final/' . $this->id));
}
}
$this->{static::$_ownerAttribute} = $owner;
}
+
+ public function getPreviewURL($attrs = [])
+ {
+ $routeName = $this->getOption('name') . '_preview';
+ if (isset($attrs['time']) || isset($attrs['path'])) {
+ $routeName .= '_with_time';
+ $default = ['path' => '', 'time' => time()];
+ $attrs = array_merge($default, $attrs);
+ }
+ return route($routeName, array_merge(['id' => $this->id, 'hash' => $this->hash], $attrs));
+ }
}
{
use SCORMVersionTrait;
use ToolboxDownloadable;
+ use CheckHash;
protected $table = 'elearning_media';
$owner = User::withoutGlobalScopes()->findOrFail($this->owner);
$organization = $owner->companyName;
-
/** @var Media $file */
$file = $this->getMediaInField('file')->first()->getPath();
self::compileFromFile($file, $dest, $this->title, $organization, 'MEDIA_' . $this->id, $this->scorm_version, 75);
{
use SCORMVersionTrait;
use ToolboxDownloadable;
+ use CheckHash;
protected $table = 'elearning_package';
}
// Create data.js
- $locale = $data->get('translation', 'en') ?? 'en';
+ $locale = $data->get('translation',
+ 'en') ?? 'en';
// Countries
$d['countriesList'] = \Cubist\Locale\Country::getList($locale);
return parent::create($data);
}
- public function getPreviewURL($attrs = [])
- {
- $routeName = 'quiz_preview';
- if (isset($attrs['time']) || isset($attrs['path'])) {
- $routeName .= '_with_time';
- $default = ['path' => '', 'time' => time()];
- $attrs = array_merge($default, $attrs);
- }
- return route($routeName, array_merge(['id' => $this->id, 'hash' => $this->hash], $attrs));
- }
-
/**
* @return QuizTheme
*/
data-context-confirm="{{json_encode($confirm)}}"
@endif
data-context-actions="{{json_encode($actions)}}"
- data-context-route="{{$crud->route}}/$id/download/$action"
+ data-context-route="{{$crud->route}}/$id/package/$action"
data-context-id="{{$entry->getKey()}}"
>
<i class="la la-arrow-circle-down"></i> {{__('Export')}}
--- /dev/null
+{{-- __('!! e-Learning') --}}
+<a class="btn btn-sm btn-link" target="_blank" href="{{$entry->getPreviewURL()}}"
+ data-toggle="tooltip" title="{{__('Prévisualiser')}}"><i class="la la-eye"></i> {{__('Prévisualiser')}}</a>
+++ /dev/null
-{{-- __('!! e-Learning') --}}
-<a class="btn btn-sm btn-link" target="_blank" href="{{$entry->getPreviewURL()}}"
- data-toggle="tooltip" title="{{__('Prévisualiser le quiz')}}"><i class="la la-eye"></i> {{__('Prévisualiser')}}</a>