From: Vincent Vanwaelscappel Date: Tue, 16 Jul 2024 10:00:17 +0000 (+0200) Subject: wait #7003 @2.5 X-Git-Url: http://git.cubedesigners.com/?a=commitdiff_plain;h=a44afd648ce5f5217880918bb6f1224872f1ced7;p=fluidbook-toolbox.git wait #7003 @2.5 --- diff --git a/app/Fields/BadgeIssuer.php b/app/Fields/BadgeIssuer.php index 20f97956c..f421af15b 100644 --- a/app/Fields/BadgeIssuer.php +++ b/app/Fields/BadgeIssuer.php @@ -15,4 +15,5 @@ class BadgeIssuer extends SelectFromModel parent::__construct($attributes); } + } diff --git a/app/Http/Controllers/Admin/Operations/Badges/OpenBadgesOperation.php b/app/Http/Controllers/Admin/Operations/Badges/OpenBadgesOperation.php new file mode 100644 index 000000000..3102e112e --- /dev/null +++ b/app/Http/Controllers/Admin/Operations/Badges/OpenBadgesOperation.php @@ -0,0 +1,86 @@ +withoutMiddleware([CheckIfAdmin::class]); + Route::match(['get'], '/ob/assertion/{uid}/image', $controller . '@openBadgesAssertionImage')->withoutMiddleware([CheckIfAdmin::class]); + Route::match(['get'], '/ob/issuer/{uid}', $controller . '@openBadgesIssuer')->withoutMiddleware([CheckIfAdmin::class]); + Route::match(['get'], '/ob/issuer/{uid}/image', $controller . '@openBadgesIssuerImage')->withoutMiddleware([CheckIfAdmin::class]); + Route::match(['get'], '/ob/badge/{uid}', $controller . '@openBadgesBadge')->withoutMiddleware([CheckIfAdmin::class]); + Route::match(['get'], '/ob/badge/{uid}/image', $controller . '@openBadgesBadgeImage')->withoutMiddleware([CheckIfAdmin::class]); + } + + public function openBadgesAssertion($uid) + { + return response()->json($this->_getAssertionInstance($uid)->getOpenBadgesData()); + } + + public function openBadgesAssertionImage($uid) + { + return response()->file($this->_getAssertionInstance($uid)->getImagePath(), ['content-type' => 'image/png']); + } + + /** + * @param $uid + * @return Assertion + */ + protected function _getAssertionInstance($uid) + { + return Assertion::withoutGlobalScopes()->whereUid($uid)->first(); + } + + /** + * @param $uid + * @return Issuer + */ + protected function _getIssuerInstance($uid) + { + return Issuer::withoutGlobalScopes()->whereUid($uid)->first(); + } + + /** + * @param $uid + * @return BadgeClass + */ + protected function _getBadgeInstance($uid) + { + return BadgeClass::withoutGlobalScopes()->whereUid($uid)->first(); + } + + public function openBadgesIssuer($uid) + { + return response()->json($this->_getIssuerInstance($uid)->getOpenBadgesData()); + } + + public function openBadgesIssuerImage($uid) + { + $file = $this->_getIssuerInstance($uid)->getImagePath(); + return response()->file($file, ['content-type' => Files::getMimeType($file)]); + } + + public function openBadgesBadge($uid) + { + + return response()->json($this->_getBadgeInstance($uid)->getOpenBadgesData()); + } + + public function openBadgesBadgeImage($uid) + { + return response()->file($this->_getBadgeInstance($uid)->getImagePath(), ['content-type' => 'image/png']); + } +} + diff --git a/app/Models/Badges/Assertion.php b/app/Models/Badges/Assertion.php index 5ff012be4..dbef947a8 100644 --- a/app/Models/Badges/Assertion.php +++ b/app/Models/Badges/Assertion.php @@ -3,9 +3,11 @@ namespace App\Models\Badges; use App\Fields\Badge; +use App\Http\Controllers\Admin\Operations\Badges\OpenBadgesOperation; use Cubist\Backpack\Magic\Fields\Code; use Cubist\Backpack\Magic\Fields\Datetime; use Cubist\Backpack\Magic\Fields\Email; +use Cubist\Backpack\Magic\Fields\NoValue; use Cubist\Backpack\Magic\Fields\Text; use Cubist\Util\Files\Files; @@ -21,6 +23,8 @@ class Assertion extends Base protected static $_ownerAttribute = null; + protected $_operations = [OpenBadgesOperation::class]; + public function setFields() { parent::setFields(); @@ -32,9 +36,28 @@ class Assertion extends Base $this->addField('badge', Badge::class, __('Badge'), ['column' => true]); } - public function getAssertionJSON() + public function getOpenBadgesData($context = true) { + return array_merge(parent::getOpenBadgesData($context), ["type" => "Assertion", + "recipient" => [ + "type" => "email", + 'hashed' => true, + "identity" => 'sha256$' . hash('sha256', $this->email), + ], + "issuedOn" => (new \DateTime($this->created_at))->format(\DateTime::ATOM), + "verification" => [ + "type" => "hosted" + ], + "badge" => $this->getBadgeClassInstance()->getOpenBadgeURL() + ]); + } + /** + * @return BadgeClass + */ + public function getBadgeClassInstance() + { + return BadgeClass::withoutGlobalScopes()->find($this->badge); } public function onSaved(): bool @@ -47,13 +70,23 @@ class Assertion extends Base $d['date'] = (new \DateTime($this->created_at))->format('Y-m-d'); $image = BadgeClass::generateImage($d); - $dest = Files::mkdir(protected_path('badge/assertions')) . $this->uid . '.png'; + $dest = $this->getImagePath(); $im = new \Imagick($image); - $im->setImageProperty('openbadges', 'https://toolbox.fluidbook.com/ob/assertion/' . $this->uid); + $im->setImageProperty('openbadges', $this->getOpenBadgeURL()); $im->writeImage($dest); return $res; } + public function getImagePath() + { + return Files::mkdir(protected_path('badge/assertions')) . $this->uid . '.png'; + } + + public function getOpenBadgeURL() + { + return 'https://toolbox.fluidbook.com/ob/assertion/' . $this->uid; + } + } diff --git a/app/Models/Badges/BadgeClass.php b/app/Models/Badges/BadgeClass.php index a0b7823b4..45225605e 100644 --- a/app/Models/Badges/BadgeClass.php +++ b/app/Models/Badges/BadgeClass.php @@ -27,16 +27,37 @@ 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('criteria', Textarea::class, __('Critères'), ['hint' => __('Contenus de la formation, compétences validées, connaissances aquises, etc.')]); $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 getOpenBadgesData($context = true) + { + + return array_merge(parent::getOpenBadgesData($context), ["type" => "BadgeClass", + "name" => $this->name, + "description" => $this->description, + "criteria" => ['narative' => $this->criteria], + 'issuer' => $this->getIssuerInstance()->getOpenBadgeURL() + ]); + } + + /** + * @return Issuer + */ + public function getIssuerInstance() + { + return Issuer::withoutGlobalScopes()->find($this->issuer); + } + public function onSaved(): bool { $res = parent::onSaved(); $this->generateSampleImage(); + $this->getImagePath(); return $res; } @@ -57,6 +78,13 @@ class BadgeClass extends Base return $d; } + public function getImagePath() + { + $data = $this->getPreviewData(); + $data['earner'] = $data['completed'] = $data['date'] = ''; + return self::generateImage($data); + } + public function generateSampleImage() { return self::generateImage($this->getPreviewData()); @@ -117,5 +145,10 @@ class BadgeClass extends Base } + public function getOpenBadgeURL() + { + return 'https://toolbox.fluidbook.com/ob/badge/' . $this->uid; + } + } diff --git a/app/Models/Badges/Base.php b/app/Models/Badges/Base.php index 90fb421d0..902f2d948 100644 --- a/app/Models/Badges/Base.php +++ b/app/Models/Badges/Base.php @@ -17,12 +17,34 @@ class Base extends ToolboxModel public function setFields() { parent::setFields(); - $this->addField('uid', HiddenVisible::class, __('UID'), ['column' => true, 'unique' => true]); - if(null!==static::$_ownerAttribute) { + $this->addField('uid', HiddenVisible::class, __('UID'), ['column' => true, 'unique' => true, 'column_escape' => false, 'column_type' => 'model_function', 'column_function_name' => 'getUIDColumn', 'column_limit' => 200000]); + if (null !== static::$_ownerAttribute) { $this->addOwnerField(); } } + public function getOpenBadgesData($context = true) + { + $res = []; + if ($context) { + $res["@context"] = "https://w3id.org/openbadges/v2"; + + } + $res['id'] = $this->getOpenBadgeURL(); + $res['image'] = $this->getOpenBadgeURL() . '/image'; + return $res; + } + + public function getUIDColumn() + { + $url = $this->getOpenBadgeURL(); + if (!$url) { + return $this->uid; + } + + return '' . $this->uid . ''; + } + public function onSaving(): bool { if (!$this->uid) { @@ -31,4 +53,9 @@ class Base extends ToolboxModel return parent::onSaving(); } + public function getOpenBadgeURL() + { + return false; + } + } diff --git a/app/Models/Badges/Issuer.php b/app/Models/Badges/Issuer.php index ed96ff7cd..5ca7c0e04 100644 --- a/app/Models/Badges/Issuer.php +++ b/app/Models/Badges/Issuer.php @@ -2,6 +2,7 @@ namespace App\Models\Badges; +use Cubist\Backpack\Magic\Fields\Email; use Cubist\Backpack\Magic\Fields\Images; use Cubist\Backpack\Magic\Fields\Text; use Cubist\Backpack\Magic\Fields\URL; @@ -21,8 +22,32 @@ class Issuer extends Base $this->addField('name', Text::class, __('Nom de l\'émetteur'), ['column' => true]); $this->addField('url', URL::class, __('URL')); + $this->addField('email', Email::class, __('E-mail')); $this->addField('logo', Images::class, __('Logo')); } + + public function getOpenBadgesData($context = true) + { + return array_merge(parent::getOpenBadgesData($context), [ + "name" => $this->name, + "type" => "Profile", + "url" => $this->url, + "email" => $this->email, + "verification" => [ + "allowedOrigins" => "toolbox.fluidbook.com" + ] + ]); + } + + public function getOpenBadgeURL() + { + return 'https://toolbox.fluidbook.com/ob/issuer/' . $this->uid; + } + + public function getImagePath() + { + return $this->getFirstMediaInField('logo')->getPath(); + } }