namespace App\Http\Controllers\Admin\Operations\FluidbookPublication;
+use App\Jobs\FluidbookDocumentUpload;
use App\Models\FluidbookDocument;
use Cubist\Backpack\Http\Controllers\Base\XSendFileController;
+use Cubist\Util\Crypt;
use Cubist\Util\Files\Files;
+use Cubist\Util\Str;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Session;
{
Route::match(['get'], $segment . '/{id}/composition', $controller . '@getComposition');
Route::match(['get'], $segment . '/docs/{doc_id}/thumb_{doc_page}.jpg', $controller . '@getThumb');
+ Route::match(['post'], $segment . '/uploaddocument', $controller . '@upload');
}
protected function setupCompositionDefaults()
$path = $doc->getFile($doc_page, 'jpg', 'thumb', true, true, '');
return XSendFileController::sendfile($path);
}
+
+ protected function upload()
+ {
+ $uploadID = Str::random();
+ FluidbookDocumentUpload::updateProgression($uploadID, __('Copie du document'), 1);
+
+ $file = request()->file('file');
+ $document = new FluidbookDocument();
+ $document->file = $file->getClientOriginalName();
+ $document->file_data = ["fileName" => $file->getClientOriginalName(), "fileSize" => $file->getSize(), "modificationDate" => $file->getMTime(), "creationDate" => $file->getCTime()];
+ $document->owner = backpack_user()->id;
+ $document->save();
+ move_uploaded_file($file->getPathname(), Files::mkdir($document->path()) . 'original.pdf');
+ FluidbookDocumentUpload::updateProgression($uploadID, __('Mise en file d\'attente du traitement du document'), 1.2);
+
+ FluidbookDocumentUpload::dispatch($uploadID, $document, backpack_user());
+ return response()->json(['uploadID' => $uploadID]);
+ }
}
namespace App\Models;
+use App\Jobs\FluidbookDocumentFileProcess;
+use App\Jobs\FluidbookDocumentUpload;
use App\Models\Base\ToolboxModel;
use App\Util\FluidbookFarm;
use Cubist\Backpack\Magic\Fields\Integer;
use Cubist\Backpack\Magic\Fields\Text;
use Cubist\Backpack\Magic\Fields\Textarea;
use Cubist\PDF\PDFTools;
+use Illuminate\Support\Facades\Cache;
class FluidbookDocument extends ToolboxModel
{
return sqrt($a4surface / $docSurface);
}
+ public function processUpload($uploadID)
+ {
+ FluidbookDocumentUpload::updateProgression($uploadID, __('Analyse du document'), 1.3);
+ $this->checkInfos();
+ FluidbookDocumentUpload::updateProgression($uploadID, __('Génération des miniatures (:done/:pages)', ['pages' => $this->pages, 'done' => 0]), 2);
+ $jobs = [];
+ for ($i = 1; $i <= $this->pages; $i++) {
+ $job = new FluidbookDocumentFileProcess($this, $i, 'jpg', 'thumb');
+ $job->dispatch();
+ $jobs[] = $job;
+ }
+
+ while (true) {
+ $done = 0;
+ foreach ($jobs as $job) {
+ /** @var $job FluidbookDocumentFileProcess */
+ if ($job->isDone()) {
+ $done++;
+ }
+ }
+ $progress = $done / $this->pages;
+ FluidbookDocumentUpload::updateProgression($uploadID, __('Génération des miniatures (:done/:pages)', ['pages' => $this->pages, 'done' => $done]), 2 + $progress);
+ usleep(0.25 * 1000000);
+ if ($progress === 1) {
+ break;
+ }
+ }
+ }
+
public function getMobileFirstRatio()
{
$this->checkInfos();
{
if (null === $this->pdf_data) {
$infos = PDFTools::infos();
+ $this->pages = $infos['pages'];
$this->pdf_data = $infos['infos'];
$this->bookmarks = $infos['bookmarks'];
- $this->pagenumbers = $infos['numberSections'];
+ $this->pagesnumbers = $infos['numberSections'];
$this->saveWithoutFlushingCache();
}
}
return rtrim(self::WS_DOCS . $this->id . ($path ? DIRECTORY_SEPARATOR . ltrim($path, DIRECTORY_SEPARATOR) : $path), DIRECTORY_SEPARATOR);
}
- public function getFilesData()
+ public function hasFile($page, $format = 'jpg', $resolution = 150, $withText = true, $withGraphics = true, $version = 'html')
{
- if ($this->_filesData === null) {
- $limit = time() - 604800;
- $f = $this->path('filesdata.json');
- if (file_exists($f) && filemtime($f) > $limit) {
- $this->_filesData = json_decode(file_get_contents($f), true);
- } else {
- $this->_filesData = [];
+ $cacheKey = $this->fileCacheKey($page, $format, $resolution, $withText, $withGraphics, $version);
+ if (Cache::has($cacheKey)) {
+ return true;
+ } else {
+ $path = $this->_getPath($page, $format, $resolution, $withText, $withGraphics, $version);
+ $minsize = $format === 'svg' ? 100 : 1;
+
+ if (!file_exists($path)) {
+ return false;
+ }
+ if (filesize($path) < $minsize) {
+ return false;
+ }
+ if ($format === 'svg') {
+ $reffile = $this->path('/html/fp' . $page . '.svg');
+ if (!file_exists($reffile) || filemtime($path) < filemtime($reffile)) {
+ return false;
+ }
+ $t = filemtime($path);
+ if ($t < 1603181003 && $t > 1602662603) {
+ return false;
+ }
}
+ Cache::put($cacheKey, $path);
+ return true;
}
- return $this->_filesData;
}
- public function getFile($page, $format = 'jpg', $resolution = 150, $withText = true, $withGraphics = true, $version = 'html', $force = false)
+ protected function _getPath($page, $format = 'jpg', $resolution = 150, $withText = true, $withGraphics = true, $version = 'html')
{
- $this->getFilesData();
- $cacheKey = md5($page . '||' . $format . '//' . $resolution . '""' . ($withText ? '1' : '0') . '---' . ($withGraphics ? '1' : '0') . '%%' . $version);
- if (!isset($this->_filesData[$cacheKey]) || $force) {
- $this->_filesData[$cacheKey] = $this->_getFile($page, $format, $resolution, $withText, $withGraphics, $version, $force);
+ $cacheKey = $this->fileCacheKey($page, $format, $resolution, $withText, $withGraphics, $version);
+ if (Cache::has($cacheKey)) {
+ return Cache::get($cacheKey);
}
- return $this->_filesData[$cacheKey];
- }
-
- public function _getFile($page, $format = 'jpg', $resolution = 150, $withText = true, $withGraphics = true, $version = 'html', $force = false)
- {
if ($format === 'jpeg') {
$format = 'jpg';
}
}
$dir = $this->path($version) . '/';
- $minsize = 1;
+
if ($format === 'svg') {
$prefix = $withGraphics ? 'f' : 't';
$file = $dir . $prefix . 'o' . $page;
}
$file .= '.svg';
- $reffile = $this->path('/html/fp' . $page . '.svg');
- $minsize = 100;
} else if ($format === 'png' || $format === 'jpg') {
$prefix = $withText ? 't' : 'h';
if ($resolution === 'thumb') {
$file = $dir . 'p' . $page . '.' . $format;
}
- $do = false;
- if (!file_exists($file)) {
- $do = true;
- } else if (filesize($file) < $minsize) {
- $do = true;
- } else if (isset($reffile) && (!file_exists($reffile) || filemtime($file) < filemtime($reffile))) {
- $do = true;
- } else if ($format === 'svg') {
- $t = filemtime($file);
- $do = $t < 1603181003 && $t > 1602662603;
- }
+ return $file;
+ }
- if ($do || $force) {
- return FluidbookFarm::getFile($page, $format, $resolution, $withText, $withGraphics, $version, $this->getResolutionRatio(), $this->getMobileFirstRatio(), $this->path(), $force);
+ protected function fileCacheKey($page, $format = 'jpg', $resolution = 150, $withText = true, $withGraphics = true, $version = 'html')
+ {
+ return 'FluidbookDocument_' . $this->id . '_' . $page . '_' . $format . '_' . $resolution . '_' . ($withText ? '1' : '0') . '_' . ($withGraphics ? '1' : '0') . '_' . $version;
+ }
+
+ public function getFile($page, $format = 'jpg', $resolution = 150, $withText = true, $withGraphics = true, $version = 'html', $force = false)
+ {
+ if ($force) {
+ $this->removeFile($page, $format, $resolution, $withText, $withGraphics, $version);
}
- touch($file);
- return $file;
+ $doc = $this;
+ return Cache::rememberForever($this->fileCacheKey($page, $format, $resolution, $withText, $withGraphics, $version), function () use ($doc, $page, $format, $resolution, $withText, $withGraphics, $version) {
+ return $doc->_getFile($page, $format, $resolution, $withText, $withGraphics, $version);
+ });
}
- public function __destruct()
+ public function removeFile($page, $format = 'jpg', $resolution = 150, $withText = true, $withGraphics = true, $version = 'html')
{
- if (null !== $this->_filesData) {
- file_put_contents($this->path('filesdata.json'), json_encode($this->_filesData));
+ $path = $this->_getPath($page, $format, $resolution, $withText, $withGraphics, $version);
+ if (file_exists($path)) {
+ unlink($path);
}
+ Cache::forget($this->fileCacheKey($page, $format, $resolution, $withText, $withGraphics, $version));
}
+
+
+ public function _getFile($page, $format = 'jpg', $resolution = 150, $withText = true, $withGraphics = true, $version = 'html')
+ {
+ if (!$this->hasFile($page, $format, $resolution, $withText, $withGraphics, $version)) {
+ return FluidbookFarm::getFile($page, $format, $resolution, $withText, $withGraphics, $version, $this->getResolutionRatio(), $this->getMobileFirstRatio(), $this->path(), $force);
+ }
+
+ $path = $this->_getPath($page, $format, $resolution, $withText, $withGraphics, $version);
+ touch($path);
+ return $path;
+ }
+
}
@push('crud_fields_scripts')
<script>
$(function () {
- var conversion = 0;
+ var conversion = '';
var conversionOperation;
var conversionPages;
$("#compositionUploadForm").submit();
});
$(document).on('submit', '#compositionUploadForm', function () {
- $(form).ajaxSubmit({
- success: function (data) {
- var bm = $('[data-bunch-name="{{$field['name']}}"]').data('bunchmultiple');
- bm.replaceData(data[0].data);
+ $(this).ajaxSubmit({
+ complete: function (data) {
+ console.log(data);
+ },
+ uploadProgress: function (event, position, total, percentComplete) {
+ console.log(percentComplete);
+ },
+ error: function (data) {
+ new Noty({
+ type: 'error',
+ text: '{{__('Une erreur s\'est produite lors du chargement du document')}}',
+ }).show();
+ conversion = '';
}
});
return false;
}
function compositionBrowse(operation, pages) {
- if (conversion > 0) {
- Noty.warn('{{__("Un document est déjà en cours d'ajout")}}');
+ if (conversion !== '') {
+ new Noty({
+ type: 'warning',
+ text: '{{__("Un document est déjà en cours d'ajout")}}',
+ }).show();
return;
}
conversionOperation = operation;
conversionPages = pages;
$("#compositionUploadForm").remove();
- var form = $('<form id="compositionUploadForm" action="{{backpack_url('publications/uploaddocument')}}" enctype="multipart/form-data" method="post">' +
+ var form = $('<form id="compositionUploadForm" action="{{backpack_url($entry->getOption('name').'/uploaddocument')}}" enctype="multipart/form-data" method="post">' +
'<input type="file" id="compositionUploadBrowse" name="file" value="" accept=".pdf" />' +
'<input type="hidden" name="_token" value="{{csrf_token()}}" />' +
'</form>');
compositionBrowse('before', opt.$trigger[0].index() + 1);
}
},
+ replacePage: {
+ name: "{{__('Remplacer cette page')}}",
+ callback: function (key, opt) {
+ compositionBrowse('replace', [opt.$trigger[0].index() + 1]);
+ }
+ },
sep3: "---------",
nonum: {
name: "{{__('Pas de numérotation à partir de cette page')}}",
.context-menu-item.context-menu-hover {
background-color: #467fcf;
}
- #composition_uploader{
+
+ #composition_uploader {
position: relative;
- top:-10px;
- left:12px;
+ top: -10px;
+ left: 12px;
}
</style>