summaryrefslogtreecommitdiff
path: root/src/Manager
diff options
context:
space:
mode:
Diffstat (limited to 'src/Manager')
-rw-r--r--src/Manager/ScormDisk.php90
-rw-r--r--src/Manager/ScormManager.php74
2 files changed, 96 insertions, 68 deletions
diff --git a/src/Manager/ScormDisk.php b/src/Manager/ScormDisk.php
index 9417ef3..cb09db5 100644
--- a/src/Manager/ScormDisk.php
+++ b/src/Manager/ScormDisk.php
@@ -3,59 +3,56 @@
namespace Peopleaps\Scorm\Manager;
use Illuminate\Filesystem\FilesystemAdapter;
+use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
-use Peopleaps\Scorm\Entity\Scorm;
use Peopleaps\Scorm\Exception\StorageNotFoundException;
-use ZipArchive;
-use ZipStream\ZipStream;
class ScormDisk
{
/**
* Extract zip file into destination directory.
*
- * @param string $path Destination directory
- * @param string $zipFilePath The path to the zip file.
+ * @param UploadedFile|string $file zip source
+ * @param string $path The path to the destination.
*
- * @return bool True on success, false on failure.
+ * @return bool true on success, false on failure.
*/
- public function unzip($file, $path)
+ function unzipper($file, $target_dir)
{
- $path = $this->cleanPath($path);
-
- $zipArchive = new ZipArchive();
- if ($zipArchive->open($file) !== true) {
- return false;
- }
-
- /** @var FilesystemAdapter $disk */
- $disk = $this->getDisk();
-
- for ($i = 0; $i < $zipArchive->numFiles; ++$i) {
- $zipEntryName = $zipArchive->getNameIndex($i);
- $destination = $path . DIRECTORY_SEPARATOR . $this->cleanPath($zipEntryName);
- if ($this->isDirectory($zipEntryName)) {
- $disk->createDir($destination);
- continue;
+ $target_dir = $this->cleanPath($target_dir);
+ $unzipper = resolve(\ZipArchive::class);
+ if ($unzipper->open($file)) {
+ /** @var FilesystemAdapter $disk */
+ $disk = $this->getDisk();
+ for ($i = 0; $i < $unzipper->numFiles; ++$i) {
+ $zipEntryName = $unzipper->getNameIndex($i);
+ $destination = $this->join($target_dir, $this->cleanPath($zipEntryName));
+ if ($this->isDirectory($zipEntryName)) {
+ $disk->createDir($destination);
+ continue;
+ }
+ $disk->putStream($destination, $unzipper->getStream($zipEntryName));
}
- $disk->putStream($destination, $zipArchive->getStream($zipEntryName));
+ return true;
}
- return true;
+ return false;
}
- public function download(Scorm $scorm)
+ /**
+ * @param string $file SCORM archive uri on storage.
+ * @param callable $fn function run user stuff before unlink
+ */
+ public function readScormArchive($file, callable $fn)
{
- return response()->stream(function () use ($scorm) {
- // enable output of HTTP headers
- // $options = new ZipStream\Option\Archive();
- // $options->setSendHttpHeaders(true);
- $zip = new ZipStream($scorm->title . ".zip");
- /** @var FilesystemAdapter $disk */
- $disk = $this->getDisk();
- $zip->addFileFromStream($scorm->title, $disk->readStream($scorm->uuid));
- $zip->finish();
- });
+ if (Storage::exists($file)) {
+ Storage::delete($file);
+ }
+ Storage::writeStream($file, $this->getArchiveDisk()->readStream($file));
+ $path = Storage::path($file);
+ call_user_func($fn, $path);
+ unlink($path); // delete temp package
+ Storage::deleteDirectory(dirname($file)); // delete temp dir
}
/**
@@ -67,6 +64,16 @@ class ScormDisk
return $this->getDisk()->deleteDirectory($folderHashedName);
}
+ /**
+ *
+ * @param array $paths
+ * @return string joined path
+ */
+ private function join(...$paths)
+ {
+ return implode(DIRECTORY_SEPARATOR, $paths);
+ }
+
private function isDirectory($zipEntryName)
{
return substr($zipEntryName, -1) === '/';
@@ -87,4 +94,15 @@ class ScormDisk
}
return Storage::disk(config('scorm.disk'));
}
+
+ /**
+ * @return FilesystemAdapter $disk
+ */
+ private function getArchiveDisk()
+ {
+ if (!config()->has('filesystems.disks.' . config('scorm.archive'))) {
+ throw new StorageNotFoundException('scorm_archive_disk_not_define');
+ }
+ return Storage::disk(config('scorm.archive'));
+ }
}
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);
- }
}