From e325e42794b6ac41a56f67bbc81b31ee88d3c6be Mon Sep 17 00:00:00 2001 From: Vincent Vanwaelscappel Date: Mon, 15 Jul 2024 17:29:55 +0200 Subject: [PATCH] wip #7003 @3 --- app/Models/Badges/BadgeClass.php | 93 +++++++++++++++++++ app/Models/ElearningTranslate.php | 7 ++ .../badge/generate_image/generate_image.js | 30 ++++++ resources/badge/translate.js | 4 - resources/badge/translate/translate.js | 5 + 5 files changed, 135 insertions(+), 4 deletions(-) create mode 100644 resources/badge/generate_image/generate_image.js delete mode 100644 resources/badge/translate.js create mode 100644 resources/badge/translate/translate.js diff --git a/app/Models/Badges/BadgeClass.php b/app/Models/Badges/BadgeClass.php index 8198139ef..e89038c58 100644 --- a/app/Models/Badges/BadgeClass.php +++ b/app/Models/Badges/BadgeClass.php @@ -3,9 +3,13 @@ namespace App\Models\Badges; use App\Fields\BadgeIssuer; +use App\Fields\ElearningLocale; +use App\Models\ElearningTranslate; use Cubist\Backpack\Magic\Fields\Files; use Cubist\Backpack\Magic\Fields\Text; use Cubist\Backpack\Magic\Fields\Textarea; +use Cubist\Util\CommandLine; +use Cubist\Util\Zip; class BadgeClass extends Base { @@ -23,6 +27,95 @@ class BadgeClass extends Base $this->addField('name', Text::class, __('Nom du certificat'), ['column' => true]); $this->addField('area', Text::class, __('Domaine de formation')); $this->addField('description', Textarea::class, __('Description du certificat'), ['hint' => __('Description de la formation. Sera intégré dans les métadonnées du certificat, mais invisible dans l\'image')]); + $this->addField('locale', ElearningLocale::class, __('Locale'), ['default' => 'en']); $this->addField('template', Files::class, __('Template du badge')); + $this->addField('preview', 'NoValue', __('Preview'), ['column_escape' => false, 'column' => true, 'column_type' => 'model_function', 'column_function_name' => 'getPreviewImage', 'column_limit' => -1]); + + } + + public function onSaved(): bool + { + $res = parent::onSaved(); + $this->generateSampleImage(); + return $res; + } + + /** + * @return array + */ + protected function getPreviewData() + { + $l = ElearningTranslate::getLocaleTranslations($this->locale); + + $d = ['earner' => 'Rameshbhulabbhai Patel-Rajjesh', + 'name' => $this->name, + 'area' => $this->area, + 'date' => '2024-09-21', + 'completed' => $l['Completed'] ?? 'Completed', + 'template' => $this->unzipTemplate(), + ]; + return $d; + } + + public function generateSampleImage() + { + return self::generateImage($this->getPreviewData()); + } + + public static function generateImage($data) + { + $hash = sha1(json_encode($data)); + + + if (!file_exists($data['template'] . $hash . '.html')) { + $html = file_get_contents($data['template'] . 'template.html'); + foreach ($data as $key => $value) { + $html = str_replace('$' . $key, $value, $html); + } + file_put_contents($data['template'] . $hash . '.html', $html); + } + + $dest = \Cubist\Util\Files\Files::mkdir(protected_path('badge/images/')) . $hash . '.png'; + if (!file_exists($dest)) { + $cl = new CommandLine('node'); + $cl->setArg(null, resource_path('badge/generate_image/generate_image.js')); + $cl->setArg('width', 500); + $cl->setArg('height', 500); + $cl->setArg('delay', 3); + $cl->setArg('scale', 1); + $cl->setArg('dest', $dest); + $cl->setArg('url', 'file://' . $data['template'] . $hash . '.html'); + $cl->execute(); + } + return $dest; + + } + + public function getPreviewImage() + { + $f = $this->generateSampleImage(); + if (!file_exists($f)) { + $b = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mN89x8AAuEB74Y0o2cAAAAASUVORK5CYII='; + } else { + $b = base64_encode(file_get_contents($f)); + } + return ''; } + + + protected function unzipTemplate() + { + $zipPath = $this->getFirstMediaInField('template')->getPath(); + $dir = \Cubist\Util\Files\Files::mkdir(protected_path('badge/cache/unzip') . '/' . \Cubist\Util\Files\Files::hashFileAttributes($zipPath)); + + if (!file_exists($dir . 'template.html')) { + \Cubist\Util\Files\Files::mkdir($dir); + Zip::extract($zipPath, $dir); + } + + return $dir; + + } + + } diff --git a/app/Models/ElearningTranslate.php b/app/Models/ElearningTranslate.php index aff48873c..c37debb30 100644 --- a/app/Models/ElearningTranslate.php +++ b/app/Models/ElearningTranslate.php @@ -30,4 +30,11 @@ class ElearningTranslate extends ToolboxContentTranslate protected static $_permissionBase = 'elearning-translate'; protected $_operations = [ExcelExportOperation::class, ExcelImportOperation::class]; + + public function getPaths() + { + $res = parent::getPaths(); + $res['OpenBadges'] = 'resources/badge/translate'; + return $res; + } } diff --git a/resources/badge/generate_image/generate_image.js b/resources/badge/generate_image/generate_image.js new file mode 100644 index 000000000..d8e33330b --- /dev/null +++ b/resources/badge/generate_image/generate_image.js @@ -0,0 +1,30 @@ +const puppeteer = require('puppeteer'); +const commandLineArgs = require('command-line-args'); +const optionDefinitions = [ + {name: 'url', type: String}, + {name: 'dest', type: String}, + {name: 'delay', type: Number, defaultOption: 3}, + {name: 'scale', type: Number, defaultOption: 1}, + {name: 'width', type: Number, defaultOption: 500}, + {name: 'height', type: Number, defaultOption: 500}, +]; + +(async () => { + const options = commandLineArgs(optionDefinitions); + const browser = await puppeteer.launch({ + headless: true, + args: [ + "--disable-setuid-sandbox", + "--no-sandbox", + ], + executablePath: 'google-chrome-stable', + }); + + const page = await browser.newPage(); + await page.setViewport({ + width: options.width / options.scale, height: options.height / options.scale, deviceScaleFactor: options.scale, + }); + await page.goto(options.url, {waitUntil: 'networkidle2'}); + await page.screenshot({path: options.dest, type: 'png', omitBackground: true}); + await browser.close(); +})(); diff --git a/resources/badge/translate.js b/resources/badge/translate.js deleted file mode 100644 index 1985c522f..000000000 --- a/resources/badge/translate.js +++ /dev/null @@ -1,4 +0,0 @@ -/* -__('Réussi') - - */ diff --git a/resources/badge/translate/translate.js b/resources/badge/translate/translate.js new file mode 100644 index 000000000..c3bf9a242 --- /dev/null +++ b/resources/badge/translate/translate.js @@ -0,0 +1,5 @@ +/* +__('Completed') +__('badgedateformat') + + */ -- 2.39.5