summaryrefslogtreecommitdiff
path: root/src/Manager/ScormDisk.php
blob: 5f15d386559fd2152e7cdb915d29cebc43e4ce0a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
<?php

namespace Peopleaps\Scorm\Manager;

use Exception;
use Illuminate\Filesystem\FilesystemAdapter;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Peopleaps\Scorm\Exception\StorageNotFoundException;

class ScormDisk
{
    /**
     * Extract zip file into destination directory.
     *
     * @param UploadedFile|string $file zip source
     * @param string $path The path to the destination.
     *
     * @return bool true on success, false on failure.
     */
    function unzipper($file, $target_dir)
    {
        $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));
            }
            return true;
        }

        return false;
    }

    /**
     * @param string $file SCORM archive uri on storage.
     * @param callable $fn function run user stuff before unlink
     */
    public function readScormArchive($file, callable $fn)
    {
        try {
            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
        } catch (Exception $ex) {
            throw new StorageNotFoundException('scorm_archive_not_found');
        }
    }

    /**
     * @param string $directory
     * @return bool
     */
    public function deleteScormFolder($folderHashedName)
    {
        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) ===  '/';
    }

    private function cleanPath($path)
    {
        return str_replace('/', DIRECTORY_SEPARATOR, $path);
    }

    /**
     * @return FilesystemAdapter $disk
     */
    private function getDisk()
    {
        if (!config()->has('filesystems.disks.' . config('scorm.disk'))) {
            throw new StorageNotFoundException('scorm_disk_not_define');
        }
        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'));
    }
}