From: Vincent Vanwaelscappel Date: Wed, 24 Aug 2022 11:19:00 +0000 (+0200) Subject: wip #5414 @0.25 X-Git-Url: http://git.cubedesigners.com/?a=commitdiff_plain;h=1257b7f8fac7a1026a51a45ece7d51c6d3999c9a;p=fluidbook-toolbox.git wip #5414 @0.25 --- diff --git a/app/Http/Controllers/Admin/OpenToolsController.php b/app/Http/Controllers/Admin/OpenToolsController.php new file mode 100644 index 000000000..4e23fff76 --- /dev/null +++ b/app/Http/Controllers/Admin/OpenToolsController.php @@ -0,0 +1,31 @@ + $args]); + } else { + return $this->$tool($args); + } + + } + + +} diff --git a/app/Http/Controllers/Admin/Operations/Tools/Excel2JSON.php b/app/Http/Controllers/Admin/Operations/Tools/Excel2JSON.php index ab5732499..e96628099 100644 --- a/app/Http/Controllers/Admin/Operations/Tools/Excel2JSON.php +++ b/app/Http/Controllers/Admin/Operations/Tools/Excel2JSON.php @@ -5,21 +5,47 @@ namespace App\Http\Controllers\Admin\Operations\Tools; use Cubist\Backpack\Magic\Fields\SelectFromArray; use Cubist\Backpack\Magic\Fields\StandardFile; use Cubist\Backpack\Magic\Form; +use ExcelToArray; use PhpOffice\PhpSpreadsheet\Reader\Xlsx; use Symfony\Component\HttpFoundation\File\UploadedFile; trait Excel2JSON { use BaseTool; + + protected function _getExcelToArrayDataOrgs() + { + return [ + 'excelToArray' => ['label' => __('Conforme à la source'), 'function' => 'excelToArrayRaw'], + 'excelToArrayKeyVars' => ['label' => __('Liste nommée par le titre de colonne') . '(' . __('Clé = valeur de la colonne A') . ')'], + 'excelToArrayIndexKeyVars' => ['label' => __('Liste nommée par le titre de colonne') . '(' . __('Clé = nombre séquentiel') . ')'], + 'excelToArrayKeyVal' => ['label' => __('Couples clé (colonne A) / valeur (colonne B)')], + 'excelToArrayKeyValMulti' => ['label' => __('Couples clé (colonne A) / valeurs (colonnes suivantes)')], + ]; + } + public function excel2json() { - $form = new Form(backpack_url('tools/doexcel2json')); + $form = new Form(backpack_url('opentools/doexcel2json')); $form->setTitle(__('Convertir un fichier Excel en JSON')); $form->setEnctype('multipart/form-data'); $form->setSubmitLabel(__('Convertir')); $form->setSubmitIcon('lab la-js-square'); $form->addField('file', StandardFile::class, __('Fichier excel'), ['accept' => '.xlsx']); - $form->addField('type', SelectFromArray::class, __('Type'), ['allows_null' => false, 'default' => 'firstrowaskey', 'options' => ['firstrowaskey' => __('Clé sur la première ligne'), 'raw' => __('Données brutes')]]); + + $options = []; + foreach ($this->_getExcelToArrayDataOrgs() as $name => $data) { + $options[$name] = $data['label']; + } + + $form->addField('dataorg', SelectFromArray::class, __('Type'), ['allows_null' => false, 'default' => 'excelToArray', 'options' => $options]); + $form->addField('format', SelectFromArray::class, __('Format de sortie'), ['allows_null' => false, 'default' => 'json', 'options' => + [ + 'json' => 'JSON', + 'js' => 'Javascript' + ] + ] + ); return view('tools.form', ['form' => $form]); } @@ -27,42 +53,25 @@ trait Excel2JSON { /** @var UploadedFile $file */ $file = request()->file('file'); - $type = request()->file('type', 'firstrowaskey'); + $dataorg = request()->file('dataorg', 'excelToArray'); + $format = request()->file('format', 'json'); - $reader = new Xlsx(); - $spreadsheet = $reader->load($file->getPathname()); + ExcelToArray::setCache(protected_path('tools/exceltojson')); - $res = []; - foreach ($spreadsheet->getAllSheets() as $sheet) { - $array = $sheet->toArray(''); - if ($type === 'raw') { - $data = $array; - } else if ($type === 'firstrowaskey') { - $data = self::_firstRowAsKey($array); - } - $s = ['title' => $sheet->getTitle(), 'data' => $data]; - $res[] = $s; + $dataOrgs = $this->_getExcelToArrayDataOrgs(); + if (!isset($dataOrgs[$dataorg])) { + throw new \Exception('Type not allowed'); } - return response()->json($res); + $function = $dataOrgs[$dataorg]['function'] ?? $dataorg; + $res = ExcelToArray::$function($file->getFilename()); - } - - protected function _firstRowAsKey($array) - { - $res = []; - foreach ($array as $lineNumber => $line) { - if ($lineNumber === 0) { - $keys = array_values($line); - continue; - } - $l = []; - foreach ($line as $k => $v) { - $l[$keys[$k]] = $v; - } - $res[] = $l; + if ($format === 'json') { + return response()->json($res); + } + if ($format === 'js') { + header('Content-Type: application/javascript'); + header('Content-Disposition: attachment; filename="data.js"'); + return response()->header('Content-Type', 'application/javascript')->setContent('var DATA=' . json_encode($res) . ';'); } - return $res; } - - } diff --git a/app/Jobs/FluidbookCompiler.php b/app/Jobs/FluidbookCompiler.php index d3e07acc4..eb77069ba 100644 --- a/app/Jobs/FluidbookCompiler.php +++ b/app/Jobs/FluidbookCompiler.php @@ -26,9 +26,11 @@ use Cubist\Util\Graphics\Resizer; use Cubist\Util\PHP; use Cubist\Util\Text; use Cubist\Util\Url; +use Cubist\Util\WebVideo; use DOMDocument; use DOMElement; use DOMXPath; +use ExcelToArray; use Fluidbook\Tools\Compiler\CompilerInterface; use Fluidbook\Tools\Links\AnchorLink; use Fluidbook\Tools\Links\ContentLink; @@ -545,7 +547,7 @@ class FluidbookCompiler extends Base implements CompilerInterface $cdir = $this->wdir . '/commerce/'; $file = $cdir . $this->fluidbookSettings->basketReferences; - $refs = wsUtil::excelToArrayKeyVars($file, 'Excel2007', true); + $refs = ExcelToArray::excelToArrayKeyVars($file, 'Excel2007', true); $this->config->basketReferences = []; foreach ($refs as $ean => $ref) { $this->config->basketReferences[$ean] = $ref; @@ -636,7 +638,7 @@ class FluidbookCompiler extends Base implements CompilerInterface $file = $cdir . $this->fluidbookSettings->basketReferences; - $this->config->basketReferences = wsUtil::excelToArrayKeyVars($file); + $this->config->basketReferences = ExcelToArray::excelToArrayKeyVars($file); FluidbookLinks::getLinksAndRulers($this->book_id, $links, $rulers); @@ -667,7 +669,7 @@ class FluidbookCompiler extends Base implements CompilerInterface } $file = $cdir . $this->fluidbookSettings->basketReferences; - $this->config->basketReferences = wsUtil::excelToArrayKeyVars($file); + $this->config->basketReferences = ExcelToArray::excelToArrayKeyVars($file); FluidbookLinks::getLinksAndRulers($this->book_id, $links, $rulers); @@ -679,7 +681,7 @@ class FluidbookCompiler extends Base implements CompilerInterface $d = Text::str2URL($ref) . '.jpg'; $dest = $odir . '/' . $d; if (!file_exists($dest) || !filesize($dest) || filemtime($dest) < filemtime($source)) { - $convert = new Image_Resizer_ImageMagick(); + $convert = new Resizer(); $convert->loadImage($source); $convert->resize(500, 500, 'ratio', false, 'C', 'M', 'ffffff'); $convert->output('jpg', $dest, 80); @@ -733,7 +735,7 @@ class FluidbookCompiler extends Base implements CompilerInterface $cdir = $this->wdir . '/commerce/'; $file = $cdir . $this->fluidbookSettings->basketReferences; - $this->config->basketReferences = wsUtil::excelToArrayKeyVars($file); + $this->config->basketReferences = ExcelToArray::excelToArrayKeyVars($file); foreach ($this->config->basketReferences as $ref => $data) { $dest = $cdir . $ref . '.jpg'; @@ -769,7 +771,7 @@ class FluidbookCompiler extends Base implements CompilerInterface } $file = $cdir . $this->fluidbookSettings->basketReferences; - $this->config->basketReferences = wsUtil::excelToArrayKeyVars($file); + $this->config->basketReferences = ExcelToArray::excelToArrayKeyVars($file); FluidbookLinks::getLinksAndRulers($this->book_id, $links, $rulers); } @@ -786,10 +788,10 @@ class FluidbookCompiler extends Base implements CompilerInterface $this->addJsLib('exceljs', 'js/libs/exceljs.min.js'); $this->addVideoJs(); - $this->config->basketReferences = wsUtil::excelToArrayKeyVars($this->wdir . 'commerce/' . $this->fluidbookSettings->basketReferences); + $this->config->basketReferences = ExcelToArray::excelToArrayKeyVars($this->wdir . 'commerce/' . $this->fluidbookSettings->basketReferences); $eanFile = $this->wdir . 'commerce/ean.xlsx'; if (file_exists($eanFile)) { - $this->config->eanReferences = wsUtil::excelToArrayIndexKeyVars($eanFile); + $this->config->eanReferences = ExcelToArray::excelToArrayIndexKeyVars($eanFile); } FluidbookLinks::getLinksAndRulers($this->book_id, $links, $rulers); @@ -857,7 +859,7 @@ class FluidbookCompiler extends Base implements CompilerInterface $references = []; if (file_exists($referencesFile) || Url::isDistant($referencesFile)) { - $raw_data = wsUtil::excelToArray($referencesFile); + $raw_data = ExcelToArray::excelToArray($referencesFile); $first_sheet_rows = reset($raw_data); // First sheet's data will be returned since it's the first array element // Expected headings are: EXCLU, LIGNE, EAN, REF, DESIGNATION, COULEUR, QTE MINI, PRIX TTC @@ -923,7 +925,7 @@ class FluidbookCompiler extends Base implements CompilerInterface $references = []; if (file_exists($referencesFile) || Url::isDistant($referencesFile)) { - $raw_data = wsUtil::excelToArray($referencesFile); + $raw_data = ExcelToArray::excelToArray($referencesFile); $first_sheet_rows = reset($raw_data); // First sheet's data will be returned since it's the first array element // Expected headings are: n° page, Chapitre, Article Code, Article, Conditionnement @@ -1015,7 +1017,7 @@ class FluidbookCompiler extends Base implements CompilerInterface $referencesFile = $this->wdir . '/commerce/' . $this->config->product_zoom_references; } if (file_exists($referencesFile) || Url::isDistant($referencesFile)) { - $this->config->product_zoom_references = wsUtil::excelToArrayKeyValMulti($referencesFile, 'Excel2007', true); + $this->config->product_zoom_references = ExcelToArray::excelToArrayKeyValMulti($referencesFile, 'Excel2007', true); } } @@ -1034,9 +1036,9 @@ class FluidbookCompiler extends Base implements CompilerInterface } else { $function = 'excelToArray'; } - $this->config->basketReferences = wsUtil::$function($referencesFile); + $this->config->basketReferences = ExcelToArray::$function($referencesFile); if ($this->fluidbookSettings->customLinkClass == 'AtlanticDownloadLink') { - $this->config->basketReferences = wsUtil::atlanticReferences($this->config->basketReferences, 'local/', array($this, 'log'), array($this->vdir, "copy")); + $this->config->basketReferences = self::atlanticReferences($this->config->basketReferences, 'local/', array($this, 'log'), array($this->vdir, "copy")); } } $this->log("Done cart references"); @@ -1044,6 +1046,34 @@ class FluidbookCompiler extends Base implements CompilerInterface } } + public static function atlanticReferences($references, $dir, $log = null, $copy = 'copy') + { + foreach ($references as $i => $sheet) { + foreach ($sheet as $j => $line) { + foreach ($line as $k => $v) { + if (preg_match('|^http:\/\/atlantic-international-book-com\.com\/files\/(.*)$|', $v, $matches)) { + $local = $dir . '/' . $matches[1]; + $url = str_replace(' ', '%20', $v); + $cache = protected_path('fluidbookpublication/atlantic') . md5($url); + if (!file_exists($cache) || filemtime($url) > filemtime($cache)) { + copy($url, $cache); + $copylog = ' (copy) '; + } else { + $copylog = ' '; + } + call_user_func($copy, $cache, $dir . '/' . $matches[1]); + $references[$i][$j][$k] = 'local/' . $matches[1]; + if (null !== $log) { + call_user_func($log, 'Done' . $copylog . $matches[1]); + } + } + } + } + } + + return $references; + } + public function log($step) { $currenttime = microtime(true); @@ -1247,7 +1277,7 @@ class FluidbookCompiler extends Base implements CompilerInterface if ($this->fluidbookSettings->tagcommander_plan) { $planPath = $this->_wdirOrAbsolute($this->fluidbookSettings->tagcommander_plan); - $plan = wsUtil::excelToArrayKeyVars($planPath); + $plan = ExcelToArray::excelToArrayKeyVars($planPath); $fixedplan = []; foreach ($plan as $k => $v) { $e = explode('#', $k); @@ -1974,7 +2004,7 @@ height="0" width="0" style="display:none;visibility:hidden"> $this->config->scorm_variables = $this->fluidbookSettings->scorm_variables = $this->parseVariables($this->fluidbookSettings->scorm_variables); if ($this->fluidbookSettings->scorm_quizdata) { - $this->config->scorm_quizdata = wsUtil::excelToArray($this->wdir . '/' . $this->fluidbookSettings->scorm_quizdata); + $this->config->scorm_quizdata = ExcelToArray::excelToArray($this->wdir . '/' . $this->fluidbookSettings->scorm_quizdata); } } @@ -2046,7 +2076,7 @@ height="0" width="0" style="display:none;visibility:hidden"> $this->config->defaultLang = $this->getFluidbook()->locale; $l10n = FluidbookTranslate::getCompiledTranslations(); $l10n['default'] = $l10n[$this->config->defaultLang]; - if($this->getFluidbook()->translations) { + if ($this->getFluidbook()->translations) { foreach ($this->getFluidbook()->translations as $k => $v) { $l10n['default'][$k] = $v; } @@ -2782,7 +2812,7 @@ height="0" width="0" style="display:none;visibility:hidden"> public function writeTexts() { - $cache = sha1($this->fluidbookSettings->highlightResults . '/--/' . $this->fluidbookSettings->searchWordSelectionAlgorithm . '///' . $this->fluidbookSettings->textExtraction . '|--|' . $this->fluidbookSettings->ignoreSearchSeparators . '|||' . $this->getFluidbook()->getCompositionUpdate(). '()()()' . FWSTK::lastUpdate()); + $cache = sha1($this->fluidbookSettings->highlightResults . '/--/' . $this->fluidbookSettings->searchWordSelectionAlgorithm . '///' . $this->fluidbookSettings->textExtraction . '|--|' . $this->fluidbookSettings->ignoreSearchSeparators . '|||' . $this->getFluidbook()->getCompositionUpdate() . '()()()' . FWSTK::lastUpdate()); $cacheDir = Files::mkdir(protected_path('fluidbookpublication/index/' . $this->book_id . '/' . $cache . '/')); $indexFile = $cacheDir . '/search.index.js'; $textFile = $cacheDir . '/search.texts.js'; @@ -3884,9 +3914,7 @@ height="0" width="0" style="display:none;visibility:hidden"> } $res .= ''; } else if ($tag === 'youtube') { - $filter = new CubeIT_Filter_WebVideo(); - $e = explode(':', $filter->filter((string)$child['link'])); - $res .= '
'; + $res .= '
'; } else if ($tag === 'image') { $srcattrs = ['href', 'src', 'file']; $file = ''; diff --git a/composer.json b/composer.json index 7a5ce98d6..826fdf976 100644 --- a/composer.json +++ b/composer.json @@ -32,6 +32,7 @@ "cubedesigners/userdatabase": "dev-master", "cubist/azuretts": "dev-master", "cubist/cms-back": "dev-master", + "cubist/excel": "dev-master", "cubist/matomo": "dev-master", "cubist/pdf": "dev-master", "cubist/scorm": "dev-master", @@ -41,9 +42,8 @@ "mxl/laravel-job": "^1.3", "nyholm/psr7": "^1.5", "php-ffmpeg/php-ffmpeg": "^0.18.0", - "phpoffice/phpspreadsheet": "^1.22", "rustici-software/scormcloud-api-v2-client-php": "^2.0", - "symfony/http-client": "^v6.0" + "symfony/http-client": "^v6.1" }, "require-dev": { "facade/ignition": "^2.17", diff --git a/composer.lock b/composer.lock index b9ba2271a..d5f5e8d70 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e6570a7a1b3b53182de40f6e0ce4f5e2", + "content-hash": "019aa2a9f00c7b3efacf70112d0d11fc", "packages": [ { "name": "ahmadshah/lucy", @@ -1792,6 +1792,45 @@ "description": "Cubist CMS Front", "time": "2021-08-31T14:57:42+00:00" }, + { + "name": "cubist/excel", + "version": "dev-master", + "source": { + "type": "git", + "url": "git://git.cubedesigners.com/cubist_excel.git", + "reference": "f5d72b0bbf09fd9d0037ea107839946ac77997e4" + }, + "dist": { + "type": "tar", + "url": "https://composer.cubedesigners.com/dist/cubist/excel/cubist-excel-dev-master-421b6a.tar", + "reference": "f5d72b0bbf09fd9d0037ea107839946ac77997e4", + "shasum": "d33eed52497f10dab39a583e2f4ed44d66fe646f" + }, + "require": { + "cubist/util": "dev-master", + "ext-json": "*", + "php": ">=7.2", + "phpoffice/phpspreadsheet": "^1.24" + }, + "default-branch": true, + "type": "library", + "autoload": { + "psr-4": { + "Cubist\\Excel\\": "src" + } + }, + "license": [ + "proprietary" + ], + "authors": [ + { + "name": "Vincent Vanwaelscappel", + "email": "vincent@cubedesigners.com" + } + ], + "description": "Excel files manipulation", + "time": "2022-08-24T11:02:03+00:00" + }, { "name": "cubist/gtag", "version": "dev-master", @@ -2126,16 +2165,17 @@ "source": { "type": "git", "url": "git://git.cubedesigners.com/cubist_util.git", - "reference": "bbc6a1884edcdc5a700a3686ca719adfcb0d7d11" + "reference": "787856a609e73933d86be1bfd65c106b93d01805" }, "dist": { "type": "tar", - "url": "https://composer.cubedesigners.com/dist/cubist/util/cubist-util-dev-master-655736.tar", - "reference": "bbc6a1884edcdc5a700a3686ca719adfcb0d7d11", - "shasum": "b64ade6c61fcb2adb718dae612333897de215ce9" + "url": "https://composer.cubedesigners.com/dist/cubist/util/cubist-util-dev-master-805791.tar", + "reference": "787856a609e73933d86be1bfd65c106b93d01805", + "shasum": "f00eeb374afc43252615e6ec33c173fd97d694f7" }, "require": { "cubist/net": "dev-master", + "dpb587/microdata-dom": "dev-master", "ext-dom": "*", "ext-iconv": "*", "ext-json": "*", @@ -2163,7 +2203,7 @@ } ], "description": "Utilities class", - "time": "2022-08-22T18:08:07+00:00" + "time": "2022-08-24T08:49:41+00:00" }, { "name": "cviebrock/eloquent-sluggable", @@ -2884,6 +2924,43 @@ ], "time": "2022-02-28T11:07:21+00:00" }, + { + "name": "dpb587/microdata-dom", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/dpb587/microdata-dom.php.git", + "reference": "8eaef2b88f7675784e6457e9a73b1d6f6b67b362" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dpb587/microdata-dom.php/zipball/8eaef2b88f7675784e6457e9a73b1d6f6b67b362", + "reference": "8eaef2b88f7675784e6457e9a73b1d6f6b67b362", + "shasum": "" + }, + "default-branch": true, + "type": "library", + "autoload": { + "psr-0": { + "MicrodataDOM": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A library extending the PHP DOMDocument to support the Microdata DOM API.", + "keywords": [ + "microdata", + "structured-data" + ], + "support": { + "issues": "https://github.com/dpb587/microdata-dom.php/issues", + "source": "https://github.com/dpb587/microdata-dom.php/tree/master" + }, + "abandoned": true, + "time": "2016-04-04T05:09:29+00:00" + }, { "name": "dragon-code/contracts", "version": "v1.22.1", @@ -14793,6 +14870,7 @@ "cubedesigners/userdatabase": 20, "cubist/azuretts": 20, "cubist/cms-back": 20, + "cubist/excel": 20, "cubist/matomo": 20, "cubist/pdf": 20, "cubist/scorm": 20, diff --git a/resources/views/fields/fluidbook_chapters.blade.php b/resources/views/fields/fluidbook_chapters.blade.php index 32e4358dc..14ad09817 100644 --- a/resources/views/fields/fluidbook_chapters.blade.php +++ b/resources/views/fields/fluidbook_chapters.blade.php @@ -1,79 +1,94 @@ @if (!isset($seenFluidbookChapters)) - @php $seenFluidbookChapters=true;@endphp - @push('crud_fields_scripts') - - @endpush + +@endpush - @push('crud_fields_styles') - - @endpush + .bunchmultiple_oneline .bunchmultiple__wrapper .item .legend .legendsize .form-group[data-name="decoration"] { + width: 160px; + } + +@endpush @endif @php - $additionalButtons=' '.__('Remplacer par le contenu d\'un fichier excel').''; - $additionalButtons.=' '.__('Exporter au format excel').''; +$additionalButtons=' + '.__('Remplacer par le contenu d\'un fichier excel').''; +$additionalButtons.=' + '.__('Exporter au format excel').''; @endphp @include('cubist_back::fields.bunch_oneline_multiple') @php - $additionalButtons=''; +$additionalButtons=''; @endphp diff --git a/resources/views/tools/sidebar.blade.php b/resources/views/tools/sidebar.blade.php index b7e1eeb17..c5a28ad5a 100644 --- a/resources/views/tools/sidebar.blade.php +++ b/resources/views/tools/sidebar.blade.php @@ -17,7 +17,7 @@ - - - {{-- --}} diff --git a/routes/web.php b/routes/web.php index 1935bff92..262847bb0 100644 --- a/routes/web.php +++ b/routes/web.php @@ -10,6 +10,7 @@ Route::group([ 'namespace' => '\App\Http\Controllers\Admin', ], function () { // custom admin routes Route::any('tools/{tool}/{args?}', 'ToolsController@index')->where(['args' => '.*']); + Route::any('opentools/{tool}/{args?}', 'OpenToolsController@index')->where(['args' => '.*'])->withoutMiddleware([CheckIfAdmin::class]); Route::any('maintenance/{function}/{args?}', 'MaintenanceController@index')->where(['args' => '.*']); Route::any('openmaintenance/{function}/{args?}', 'OpenMaintenanceController@index')->where(['args' => '.*'])->withoutMiddleware([CheckIfAdmin::class]); Route::post('toolbox_setting', 'ToolboxSettingsController@set');