aboutsummaryrefslogtreecommitdiffhomepage
path: root/Digitigrade/Model/StorageObject.php
blob: 333b5b14aa2a36f95d3c6091a39d8f63c484fe7d (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
<?php
namespace Digitigrade\Model;

use Digitigrade\Model;
use Digitigrade\StorageProvider;

class StorageObject extends Model {
    public string $oid;
    public string $provider;
    public string $token;
    public string $filename;
    public string $mimetype;
    public \DateTimeImmutable $created;

    /**
     * Creates a new storage object on the given provider by consuming a local file
     * @param string $provider class name of the storage provider to use
     * @param string $path path to local file (will be deleted)
     * @param bool $checkIsUpload if true, ensures that the local file was uploaded via HTTP
     * @return self
     */
    public static function createFromFile(string $provider, string $path, string $filename, bool $checkIsUpload = false): self {
        if (!is_file($path)) {
            throw new \RuntimeException('local file does not exist');
        }
        $mimetype = mime_content_type($path);
        $p = new $provider();
        assert($p instanceof StorageProvider);
        $token = $p->storeFile($path, $checkIsUpload);

        $obj = new self();
        $obj->oid = random_printable_bytes();
        $obj->provider = $p::class;
        $obj->token = $token;
        $obj->filename = $filename;
        $obj->mimetype = $mimetype;
        $obj->created = new \DateTimeImmutable();

        $obj->save();
        return $obj;
    }

    public static function findByOid(string $oid): ?self {
        return self::findWhere('oid = ?', [$oid]);
    }

    public static function findByProviderTokenPair(string $provider, string $token): ?self {
        return self::findWhere('provider = ? AND token = ?', [$provider, $token]);
    }

    protected function getUpdateWhereClause(\PDO $db): ?string {
        if (isset($this->oid) && self::findByOid($this->oid) != null) {
            return 'oid = ' . $db->quote($this->oid);
        }
        if (self::findByProviderTokenPair($this->provider, $this->token) != null) {
            return 'provider = ' . $db->quote($this->provider) . ' AND token = ' . $db->quote($this->token);
        }
        return null;
    }

    private function getProvider(): StorageProvider {
        return new $this->provider();
    }

    /**
     * Deletes this object from the storage backend and removes it from the database.
     * @return void
     */
    public function delete() {
        $this->getProvider()->delete($this->token);
        $this->remove();
    }

    /**
     * Gets the entire content of this object.
     * @return string
     */
    public function retrieve(): string {
        return $this->getProvider()->retrieve($this->token);
    }

    /**
     * Streams the content of this object to the web client (stdout).
     * @return void
     */
    public function passthrough() {
        $this->getProvider()->passthrough($this->token, $this->mimetype);
    }

    /**
     * Gets a direct public URL to this object, if one exists.
     * @return ?string the URL or null if none is available
     */
    public function getDirectUrl(): ?string {
        return $this->getProvider()->directUrl($this->token);
    }

    public function getUrl(bool $allowDirect = true): string {
        if ($allowDirect) {
            $url = $this->getDirectUrl();
            if ($url != null) {
                return $url;
            }
        }
        return path_to_uri("/storage/$this->oid");
    }
}