Completed
Push — master ( a851cc...20dc5c )
by Arne
02:03
created

IndexObject::getMode()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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