From ad4a8ecc7e5613418a5dfddf83fe392492a69559 Mon Sep 17 00:00:00 2001 From: Khaled Lela Date: Fri, 11 Feb 2022 16:40:35 +0200 Subject: add doc for laravel builder dynamic where handler --- src/Manager/ScormManager.php | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'src/Manager/ScormManager.php') diff --git a/src/Manager/ScormManager.php b/src/Manager/ScormManager.php index 56c723c..935bb2d 100644 --- a/src/Manager/ScormManager.php +++ b/src/Manager/ScormManager.php @@ -60,6 +60,31 @@ class ScormManager throw new InvalidScormArchiveException('invalid_scorm_data'); } + /** + * ScormModel::whereOriginFile Query Builder style equals ScormModel::where('origin_file',$value) + * + * From Laravel doc https://laravel.com/docs/5.0/queries#advanced-wheres. + * Dynamic Where Clauses + * You may even use "dynamic" where statements to fluently build where statements using magic methods: + * + * Examples: + * + * $admin = DB::table('users')->whereId(1)->first(); + * + * $john = DB::table('users') + * ->whereIdAndEmail(2, 'john@doe.com') + * ->first(); + * + * $jane = DB::table('users') + * ->whereNameOrAge('Jane', 22) + * ->first(); + * + * + * From laravel framework https://github.com/laravel/framework/blob/9.x/src/Illuminate/Database/Query/Builder.php' + * + * Handle dynamic method calls into the method. + * return $this->dynamicWhere($method, $parameters); + **/ $scorm = ScormModel::whereOriginFile($scormData['identifier']); // Check if scom package already exists to drop old one. if (!$scorm->exists()) { -- cgit v1.2.3 From f03f57dcbbbf34feb4eb03bba7ea73dfe9b182b3 Mon Sep 17 00:00:00 2001 From: Khaled Lela Date: Sat, 19 Feb 2022 21:00:00 +0200 Subject: feat(disk): add download scorm package zip. --- src/Manager/ScormManager.php | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/Manager/ScormManager.php') diff --git a/src/Manager/ScormManager.php b/src/Manager/ScormManager.php index 935bb2d..aedfae3 100644 --- a/src/Manager/ScormManager.php +++ b/src/Manager/ScormManager.php @@ -667,4 +667,9 @@ class ScormManager return $formattedValue; } + + + public function download(Scorm $scorm){ + return $this->scormDisk->download($scorm); + } } -- cgit v1.2.3 From 7303302c322e105b5095bf412e8d154971088282 Mon Sep 17 00:00:00 2001 From: Khaled Lela Date: Wed, 23 Feb 2022 16:13:24 +0200 Subject: handle read scorm archive from uri, in case have two differet storage for package archive and unzipped package for serve. --- src/Manager/ScormManager.php | 74 +++++++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 32 deletions(-) (limited to 'src/Manager/ScormManager.php') diff --git a/src/Manager/ScormManager.php b/src/Manager/ScormManager.php index aedfae3..9de1439 100644 --- a/src/Manager/ScormManager.php +++ b/src/Manager/ScormManager.php @@ -17,7 +17,6 @@ use Peopleaps\Scorm\Model\ScormScoModel; use Peopleaps\Scorm\Model\ScormScoTrackingModel; use Illuminate\Support\Str; use Peopleaps\Scorm\Entity\Sco; -use ZipArchive; class ScormManager { @@ -38,28 +37,53 @@ class ScormManager $this->scormDisk = new ScormDisk(); } + public function uploadScormFromUri($file) + { + $scorm = null; + $this->scormDisk->readScormArchive($file, function ($path) use (&$scorm, $file) { + $this->validatePackage($path); + $uuid = dirname($file); + $filename = basename($file); + $scorm = $this->saveScorm($path, $uuid, $filename); + }); + return $scorm; + } + public function uploadScormArchive(UploadedFile $file) { - // Checks if it is a valid scorm archive - $scormData = null; - $zip = new ZipArchive(); - $openValue = $zip->open($file); + $this->validatePackage($file); + return $this->saveScorm($file, Str::uuid(), $file->getClientOriginalName()); + } + /** + * Checks if it is a valid scorm archive + * + * @param string|UploadedFile $file zip. + */ + private function validatePackage($file) + { + $zip = new \ZipArchive(); + $openValue = $zip->open($file); $isScormArchive = (true === $openValue) && $zip->getStream('imsmanifest.xml'); $zip->close(); - if (!$isScormArchive) { throw new InvalidScormArchiveException('invalid_scorm_archive_message'); - } else { - $scormData = $this->generateScorm($file); } + } + /** + * Save scom data + * + * @param string|UploadedFile $file zip. + */ + private function saveScorm($file, $uuid, $filename) + { + $scormData = $this->generateScorm($file, $uuid); // save to db if (is_null($scormData) || !is_array($scormData)) { throw new InvalidScormArchiveException('invalid_scorm_data'); } - /** * ScormModel::whereOriginFile Query Builder style equals ScormModel::where('origin_file',$value) * @@ -70,18 +94,7 @@ class ScormManager * Examples: * * $admin = DB::table('users')->whereId(1)->first(); - * - * $john = DB::table('users') - * ->whereIdAndEmail(2, 'john@doe.com') - * ->first(); - * - * $jane = DB::table('users') - * ->whereNameOrAge('Jane', 22) - * ->first(); - * - * * From laravel framework https://github.com/laravel/framework/blob/9.x/src/Illuminate/Database/Query/Builder.php' - * * Handle dynamic method calls into the method. * return $this->dynamicWhere($method, $parameters); **/ @@ -93,12 +106,12 @@ class ScormManager $scorm = $scorm->first(); $this->deleteScormData($scorm); } - $scorm->uuid = $scormData['uuid']; $scorm->title = $scormData['title']; $scorm->version = $scormData['version']; $scorm->entry_url = $scormData['entryUrl']; - $scorm->origin_file = $scormData['identifier']; + $scorm->identifier = $scormData['identifier']; + $scorm->origin_file = $filename; $scorm->save(); if (!empty($scormData['scos']) && is_array($scormData['scos'])) { @@ -145,7 +158,10 @@ class ScormManager return $sco; } - private function parseScormArchive(UploadedFile $file) + /** + * @param string|UploadedFile $file zip. + */ + private function parseScormArchive($file) { $data = []; $contents = ''; @@ -238,20 +254,19 @@ class ScormManager } /** - * @param UploadedFile $file + * @param string|UploadedFile $file zip. * @return array * @throws InvalidScormArchiveException */ - private function generateScorm(UploadedFile $file) + private function generateScorm($file, $uuid) { - $uuid = Str::uuid(); $scormData = $this->parseScormArchive($file); /** * Unzip a given ZIP file into the web resources directory. * * @param string $hashName name of the destination directory */ - $this->scormDisk->unzip($file, $uuid); + $this->scormDisk->unzipper($file, $uuid); return [ 'identifier' => $scormData['identifier'], @@ -667,9 +682,4 @@ class ScormManager return $formattedValue; } - - - public function download(Scorm $scorm){ - return $this->scormDisk->download($scorm); - } } -- cgit v1.2.3 From b518a5bbc9e18f6a2ac1827e24e733ec508ff0d5 Mon Sep 17 00:00:00 2001 From: Khaled Lela Date: Wed, 23 Feb 2022 16:29:05 +0200 Subject: fix where origin file reference --- src/Manager/ScormManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/Manager/ScormManager.php') diff --git a/src/Manager/ScormManager.php b/src/Manager/ScormManager.php index 9de1439..0ff7ed8 100644 --- a/src/Manager/ScormManager.php +++ b/src/Manager/ScormManager.php @@ -98,7 +98,7 @@ class ScormManager * Handle dynamic method calls into the method. * return $this->dynamicWhere($method, $parameters); **/ - $scorm = ScormModel::whereOriginFile($scormData['identifier']); + $scorm = ScormModel::whereOriginFile($filename); // Check if scom package already exists to drop old one. if (!$scorm->exists()) { $scorm = new ScormModel(); -- cgit v1.2.3 From f3da307a245c7d0ed59592c06ca0fbd7806e0f51 Mon Sep 17 00:00:00 2001 From: Khaled Lela Date: Sun, 27 Feb 2022 21:41:47 +0200 Subject: update runtime progress data. --- src/Manager/ScormManager.php | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'src/Manager/ScormManager.php') diff --git a/src/Manager/ScormManager.php b/src/Manager/ScormManager.php index 0ff7ed8..61a0628 100644 --- a/src/Manager/ScormManager.php +++ b/src/Manager/ScormManager.php @@ -300,9 +300,8 @@ class ScormManager */ public function getScoByUuid($scoUuid) { - $sco = ScormScoModel::with([ - 'scorm' - ])->where('uuid', $scoUuid) + $sco = ScormScoModel::with(['scorm']) + ->where('uuid', $scoUuid) ->firstOrFail(); return $sco; @@ -313,7 +312,7 @@ class ScormManager return ScormScoTrackingModel::where('sco_id', $scoId)->where('user_id', $userId)->first(); } - public function createScoTracking($scoUuid, $userId = null) + public function createScoTracking($scoUuid, $userId = null, $userName = null) { $sco = ScormScoModel::where('uuid', $scoUuid)->firstOrFail(); @@ -321,6 +320,7 @@ class ScormManager $scoTracking = new ScoTracking(); $scoTracking->setSco($sco->toArray()); + $cmi = null; switch ($version) { case Scorm::SCORM_12: $scoTracking->setLessonStatus('not attempted'); @@ -338,16 +338,29 @@ class ScormManager } else { $scoTracking->setIsLocked(true); } + $cmi = [ + 'cmi.core.entry' => $scoTracking->getEntry(), + 'cmi.core.student_id' => $userId, + 'cmi.core.student_name' => $userName, + ]; + break; case Scorm::SCORM_2004: $scoTracking->setTotalTimeString('PT0S'); $scoTracking->setCompletionStatus('unknown'); $scoTracking->setLessonStatus('unknown'); $scoTracking->setIsLocked(false); + $cmi = [ + 'cmi.entry' => 'ab-initio', + 'cmi.learner_id' => $userId, + 'cmi.learner_name' => $userName, + 'cmi.scaled_passing_score' => 0.5, + ]; break; } $scoTracking->setUserId($userId); + $scoTracking->setDetails($cmi); // Create a new tracking model $storeTracking = ScormScoTrackingModel::firstOrCreate([ -- cgit v1.2.3 From 04fc94e0157136e6ce04c3d20edbf2845c4e0ebe Mon Sep 17 00:00:00 2001 From: Khaled Lela Date: Tue, 1 Mar 2022 11:02:49 +0200 Subject: refactor onerror clean resources and throw exception --- src/Manager/ScormManager.php | 47 +++++++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 18 deletions(-) (limited to 'src/Manager/ScormManager.php') diff --git a/src/Manager/ScormManager.php b/src/Manager/ScormManager.php index 61a0628..243036c 100644 --- a/src/Manager/ScormManager.php +++ b/src/Manager/ScormManager.php @@ -24,6 +24,8 @@ class ScormManager private $scormLib; /** @var ScormDisk */ private $scormDisk; + /** @var string $uuid */ + private $uuid; /** * Constructor. @@ -41,18 +43,17 @@ class ScormManager { $scorm = null; $this->scormDisk->readScormArchive($file, function ($path) use (&$scorm, $file) { - $this->validatePackage($path); - $uuid = dirname($file); + $this->uuid = dirname($file); $filename = basename($file); - $scorm = $this->saveScorm($path, $uuid, $filename); + $scorm = $this->saveScorm($path, $filename); }); return $scorm; } public function uploadScormArchive(UploadedFile $file) { - $this->validatePackage($file); - return $this->saveScorm($file, Str::uuid(), $file->getClientOriginalName()); + $this->uuid = Str::uuid(); + return $this->saveScorm($file, $file->getClientOriginalName()); } /** @@ -68,7 +69,7 @@ class ScormManager $zip->close(); if (!$isScormArchive) { - throw new InvalidScormArchiveException('invalid_scorm_archive_message'); + $this->onError('invalid_scorm_archive_message'); } } @@ -77,12 +78,13 @@ class ScormManager * * @param string|UploadedFile $file zip. */ - private function saveScorm($file, $uuid, $filename) + private function saveScorm($file, $filename) { - $scormData = $this->generateScorm($file, $uuid); + $this->validatePackage($file); + $scormData = $this->generateScorm($file); // save to db if (is_null($scormData) || !is_array($scormData)) { - throw new InvalidScormArchiveException('invalid_scorm_data'); + $this->onError('invalid_scorm_data'); } /** * ScormModel::whereOriginFile Query Builder style equals ScormModel::where('origin_file',$value) @@ -178,14 +180,14 @@ class ScormManager $dom = new DOMDocument(); if (!$dom->loadXML($contents)) { - throw new InvalidScormArchiveException('cannot_load_imsmanifest_message'); + $this->onError('cannot_load_imsmanifest_message'); } $manifest = $dom->getElementsByTagName('manifest')->item(0); if (!is_null($manifest->attributes->getNamedItem('identifier'))) { $data['identifier'] = $manifest->attributes->getNamedItem('identifier')->nodeValue; } else { - throw new InvalidScormArchiveException('invalid_scorm_manifest_identifier'); + $this->onError('invalid_scorm_manifest_identifier'); } $titles = $dom->getElementsByTagName('title'); if ($titles->length > 0) { @@ -204,15 +206,15 @@ class ScormManager $data['version'] = Scorm::SCORM_2004; break; default: - throw new InvalidScormArchiveException('invalid_scorm_version_message'); + $this->onError('invalid_scorm_version_message'); } } else { - throw new InvalidScormArchiveException('invalid_scorm_version_message'); + $this->onError('invalid_scorm_version_message'); } $scos = $this->scormLib->parseOrganizationsNode($dom); if (0 >= count($scos)) { - throw new InvalidScormArchiveException('no_sco_in_scorm_archive_message'); + $this->onError('no_sco_in_scorm_archive_message'); } $data['entryUrl'] = $scos[0]->entryUrl ?? $scos[0]->scoChildren[0]->entryUrl; @@ -250,7 +252,7 @@ class ScormManager */ protected function deleteScormFolder($folderHashedName) { - return $this->scormDisk->deleteScormFolder($folderHashedName); + return $this->scormDisk->deleteScorm($folderHashedName); } /** @@ -258,7 +260,7 @@ class ScormManager * @return array * @throws InvalidScormArchiveException */ - private function generateScorm($file, $uuid) + private function generateScorm($file) { $scormData = $this->parseScormArchive($file); /** @@ -266,11 +268,11 @@ class ScormManager * * @param string $hashName name of the destination directory */ - $this->scormDisk->unzipper($file, $uuid); + $this->scormDisk->unzipper($file, $this->uuid); return [ 'identifier' => $scormData['identifier'], - 'uuid' => $uuid, + 'uuid' => $this->uuid, 'title' => $scormData['title'], // to follow standard file data format 'version' => $scormData['version'], 'entryUrl' => $scormData['entryUrl'], @@ -695,4 +697,13 @@ class ScormManager return $formattedValue; } + + /** + * Clean resources and throw exception. + */ + private function onError($msg) + { + $this->scormDisk->deleteScorm($this->uuid); + throw new InvalidScormArchiveException($msg); + } } -- cgit v1.2.3