Completed
Push — master ( 2a17e7...e610ee )
by Arne
04:45
created

IndexObject   B

Complexity

Total Complexity 38

Size/Duplication

Total Lines 243
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
wmc 38
lcom 1
cbo 2
dl 0
loc 243
rs 8.3999
c 0
b 0
f 0

19 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 1 1
A getRelativePath() 0 4 1
A getBasename() 0 6 2
A getType() 0 4 1
A isDirectory() 0 4 1
A isFile() 0 4 1
A isLink() 0 4 1
A getMtime() 0 4 1
A getCtime() 0 4 1
A getMode() 0 4 1
A getSize() 0 4 1
A getLinkTarget() 0 4 1
A getHashes() 0 4 1
A getBlobId() 0 4 1
A setBlobId() 0 6 1
F equals() 0 24 12
A toScalarArray() 0 14 2
A fromScalarArray() 0 15 3
B fromPath() 0 39 5
1
<?php
2
3
namespace Storeman\Index;
4
5
use Storeman\Exception;
6
use Storeman\Hash\HashContainer;
7
8
/**
9
 * An index object is the representation of one of this filesystem primitives contained in the index.
10
 */
11
class IndexObject
12
{
13
    public const TYPE_DIR = 1;
14
    public const TYPE_FILE = 2;
15
    public const TYPE_LINK = 3;
16
17
18
    /**
19
     * @var string
20
     */
21
    protected $relativePath;
22
23
    /**
24
     * @var int
25
     */
26
    protected $type;
27
28
    /**
29
     * @var int
30
     */
31
    protected $mtime;
32
33
    /**
34
     * @var int
35
     */
36
    protected $ctime;
37
38
    /**
39
     * Full file mode.
40
     * May include additional modes like setuid, guid, etc.
41
     *
42
     * @var int
43
     */
44
    protected $mode;
45
46
    /**
47
     * @var int
48
     */
49
    protected $size;
50
51
    /**
52
     * @var string
53
     */
54
    protected $linkTarget;
55
56
    /**
57
     * @var HashContainer
58
     */
59
    protected $hashes;
60
61
    /**
62
     * @var string
63
     */
64
    protected $blobId;
65
66
    /**
67
     * Prevent construction not using static factory methods.
68
     */
69
    protected function __construct() {}
70
71
    public function getRelativePath(): string
72
    {
73
        return $this->relativePath;
74
    }
75
76
    public function getBasename(): string
77
    {
78
        $pos = strrpos($this->relativePath, DIRECTORY_SEPARATOR);
79
80
        return ($pos === false) ? $this->relativePath : substr($this->relativePath, $pos + 1);
81
    }
82
83
    public function getType(): int
84
    {
85
        return $this->type;
86
    }
87
88
    public function isDirectory(): bool
89
    {
90
        return $this->type === static::TYPE_DIR;
91
    }
92
93
    public function isFile(): bool
94
    {
95
        return $this->type === static::TYPE_FILE;
96
    }
97
98
    public function isLink(): bool
99
    {
100
        return $this->type === static::TYPE_LINK;
101
    }
102
103
    public function getMtime(): int
104
    {
105
        return $this->mtime;
106
    }
107
108
    public function getCtime(): int
109
    {
110
        return $this->ctime;
111
    }
112
113
    public function getMode(): int
114
    {
115
        return $this->mode;
116
    }
117
118
    public function getSize(): ?int
119
    {
120
        return $this->size;
121
    }
122
123
    public function getLinkTarget(): ?string
124
    {
125
        return $this->linkTarget;
126
    }
127
128
    public function getHashes(): ?HashContainer
129
    {
130
        return $this->hashes;
131
    }
132
133
    public function getBlobId(): ?string
134
    {
135
        return $this->blobId;
136
    }
137
138
    public function setBlobId(string $blobId): IndexObject
139
    {
140
        $this->blobId = $blobId;
141
142
        return $this;
143
    }
144
145
    /**
146
     * Equality check with all attributes.
147
     *
148
     * @param IndexObject $other
149
     * @return bool
150
     */
151
    public function equals(?IndexObject $other): bool
152
    {
153
        if ($other === null)
154
        {
155
            return false;
156
        }
157
158
        $equals = true;
159
        $equals = $equals && ($this->relativePath === $other->relativePath);
160
        $equals = $equals && ($this->type === $other->type);
161
        $equals = $equals && ($this->mtime === $other->mtime);
162
        $equals = $equals && ($this->ctime === $other->ctime);
163
        $equals = $equals && ($this->mode === $other->mode);
164
        $equals = $equals && ($this->size === $other->size);
165
        $equals = $equals && ($this->linkTarget === $other->linkTarget);
166
        $equals = $equals && ($this->blobId === $other->blobId);
167
168
        if ($this->hashes)
169
        {
170
            $equals = $equals && $this->hashes->equals($other->hashes);
171
        }
172
173
        return $equals;
174
    }
175
176
    public function toScalarArray(): array
177
    {
178
        return [
179
            $this->relativePath,
180
            $this->type,
181
            $this->mtime,
182
            $this->ctime,
183
            $this->mode,
184
            $this->size,
185
            $this->blobId,
186
            $this->linkTarget,
187
            $this->hashes ? $this->hashes->serialize() : null,
188
        ];
189
    }
190
191
    public static function fromScalarArray(array $array): IndexObject
192
    {
193
        $object = new static;
194
        $object->relativePath = $array[0];
195
        $object->type = (int)$array[1];
196
        $object->mtime = (int)$array[2];
197
        $object->ctime = (int)$array[3];
198
        $object->mode = (int)$array[4];
199
        $object->size = (int)$array[5];
200
        $object->blobId = $array[6];
201
        $object->linkTarget = $array[7] ?: null;
202
        $object->hashes = empty($array[8]) ? null : (new HashContainer())->unserialize($array[8]);
203
204
        return $object;
205
    }
206
207
    /**
208
     * Returns an instance representing the filesystem object that can be found under the given path.
209
     *
210
     * @param string $basePath
211
     * @param string $relativePath
212
     * @return IndexObject
213
     */
214
    public static function fromPath(string $basePath, string $relativePath): IndexObject
215
    {
216
        $absolutePath = rtrim($basePath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $relativePath;
217
218
        clearstatcache(null, $absolutePath);
219
220
        if (!($stat = @lstat($absolutePath)))
221
        {
222
            throw new Exception("lstat() failed for {$absolutePath}");
223
        }
224
225
        $object = new static;
226
        $object->relativePath = $relativePath;
227
        $object->mtime = $stat['mtime'];
228
        $object->ctime = $stat['ctime'];
229
        $object->mode = $stat['mode'];
230
231
        if (is_link($absolutePath))
232
        {
233
            $object->type = static::TYPE_LINK;
234
            $object->linkTarget = str_replace("{$basePath}/", '', readlink($absolutePath));
235
        }
236
        elseif (is_file($absolutePath))
237
        {
238
            $object->type = static::TYPE_FILE;
239
            $object->size = (int)$stat['size'];
240
            $object->hashes = new HashContainer();
241
        }
242
        elseif (is_dir($absolutePath))
243
        {
244
            $object->type = static::TYPE_DIR;
245
        }
246
        else
247
        {
248
            throw new \LogicException();
249
        }
250
251
        return $object;
252
    }
253
}
254