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
{
$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 '<img src="data:image/png;base64,' . $b . '" width="150" height="150" alt="" />';
}
+
+
+ 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;
+
+ }
+
+
}
--- /dev/null
+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();
+})();