Completed
Push — feature/configuration ( 7325c4 )
by Pierre
06:36
created

Local::createFromConfiguration()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 9
rs 9.6667
cc 1
eloc 5
nc 1
nop 1
1
<?php
2
3
namespace Gaufrette\Adapter;
4
5
use Gaufrette\Adapter\Metadata\MetadataAccessor;
6
use Gaufrette\Core\Adapter;
7
use Gaufrette\Core\Adapter\CanListKeys;
8
use Gaufrette\Core\Adapter\HasConfiguration;
9
use Gaufrette\Core\Adapter\KnowsContent;
10
use Gaufrette\Core\Adapter\KnowsLastAccess;
11
use Gaufrette\Core\Adapter\KnowsLastModification;
12
use Gaufrette\Core\Adapter\KnowsMetadata;
13
use Gaufrette\Core\Adapter\KnowsMimeType;
14
use Gaufrette\Core\Adapter\KnowsSize;
15
use Phine\Path\Path;
16
17
class Local implements
18
    Adapter,
19
    CanListKeys,
20
    HasConfiguration,
21
    KnowsContent,
22
    KnowsLastAccess,
23
    KnowsLastModification,
24
    KnowsMetadata,
25
    KnowsMimeType,
26
    KnowsSize
27
{
28
    /**
29
     * @type string
30
     */
31
    private $directory;
32
33
    /**
34
     * @type bool
35
     */
36
    private $create;
37
38
    /**
39
     * @type int
40
     */
41
    private $mode;
42
43
    /**
44
     * @type MetadataAccessor
45
     */
46
    private $metadataAccessor;
47
48
    /**
49
     * @param string $directory
50
     * @param bool   $create
51
     * @param int    $mode
52
     */
53
    public function __construct($directory, $create = false, $mode = 0777)
54
    {
55
        $this->directory        = Path::canonical($directory);
56
        $this->create           = $create;
57
        $this->mode             = $mode;
58
        $this->metadataAccessor = new MetadataAccessor();
59
    }
60
61
    /**
62
     * {@inheritdoc}
63
     */
64
    public static function createFromConfiguration(array $configuration)
65
    {
66
        $configuration = array_merge(
67
            array('create' => false, 'mode' => 0777),
68
            $configuration
69
        );
70
71
        return new self($configuration['directory'], $configuration['create'], $configuration['mode']);
72
    }
73
74
    /**
75
     * @param MetadataAccessor|null $metadataAccessor if null, metadata feature will be disabled
76
     *
77
     * @return
78
     */
79
    public function setMetadataAccessor(MetadataAccessor $metadataAccessor = null)
80
    {
81
        $this->metadataAccessor = $metadataAccessor;
82
83
        return $this;
84
    }
85
86
    /**
87
     * {@inheritdoc}
88
     */
89
    public function readContent($key)
90
    {
91
        return file_get_contents($this->getFullPath($key));
92
    }
93
94
    /**
95
     * {@inheritdoc}
96
     */
97
    public function writeContent($key, $content)
98
    {
99
        file_put_contents($this->getFullPath($key), $content);
100
101
        return $this;
102
    }
103
104
    /**
105
     * {@inheritdoc}
106
     */
107
    public function readMetadata($key)
108
    {
109
        if (null !== $this->metadataAccessor) {
110
            return $this->metadataAccessor->readMetadata($this->getFullPath($key));
111
        }
112
113
        return array();
114
    }
115
116
    public function writeMetadata($key, array $metadata)
117
    {
118
        if (null !== $this->metadataAccessor) {
119
            $this->metadataAccessor->writeMetadata($this->getFullPath($key), $metadata);
120
        }
121
122
        return $this;
123
    }
124
125
    /**
126
     * {@inheritdoc}
127
     */
128
    public function readMimeType($key)
129
    {
130
        $info = new \finfo(FILEINFO_MIME_TYPE);
131
132
        return $info->buffer($this->readContent($key));
133
    }
134
135
    /**
136
     * {@inheritdoc}
137
     */
138
    public function readSize($key)
139
    {
140
        return filesize($this->getFullPath($key));
141
    }
142
143
    /**
144
     * {@inheritdoc}
145
     */
146
    public function readLastModification($key)
147
    {
148
        return filemtime($this->getFullPath($key));
149
    }
150
151
    /**
152
     * {@inheritdoc}
153
     */
154
    public function writeLastModification($key, $time)
155
    {
156
        touch($this->getFullPath($key), $time);
157
158
        return $this;
159
    }
160
161
    /**
162
     * {@inheritdoc}
163
     */
164
    public function readLastAccess($key)
165
    {
166
        return fileatime($this->getFullPath($key));
167
    }
168
169
    /**
170
     * {@inheritdoc}
171
     */
172
    public function writeLastAccess($key, $time)
173
    {
174
        touch($this->getFullPath($key), $this->readLastModification($key), $time);
175
176
        return $this;
177
    }
178
179
    /**
180
     * {@inheritdoc}
181
     */
182
    public function listKeys($prefix = '')
183
    {
184
        $files     = array();
185
        $directory = new \DirectoryIterator($this->getDirectory());
186
187
        foreach ($directory as $file) {
188
            if (true === $file->isFile()) {
189
                $files[] = $file->getFilename();
190
            }
191
        }
192
        sort($files);
193
194
        if ('' !== $prefix) {
195
            $files = array_filter($files, function ($e) use ($prefix) { return 0 === strpos($e, $prefix); });
196
        }
197
198
        return $files;
199
    }
200
201
    /**
202
     * {@inheritdoc}
203
     */
204
    public function delete($key)
205
    {
206
        unlink($this->getFullPath($key));
207
208
        return $this;
209
    }
210
211
    /**
212
     * {@inheritdoc}
213
     */
214
    public function exists($key)
215
    {
216
        return true === file_exists($this->getFullPath($key));
217
    }
218
219
    /**
220
     * @param string $key
221
     *
222
     * @return string
223
     */
224
    private function getFullPath($key)
225
    {
226
        $fullpath = sprintf('%s/%s', $this->getDirectory(), $key);
227
228
        return Path::canonical($fullpath);
229
    }
230
231
    /**
232
     * @return string
233
     */
234
    private function getDirectory()
235
    {
236
        $this->ensureDirectoryExists($this->directory);
237
238
        if (true === is_link($this->directory)) {
239
            $this->directory = realpath($this->directory);
240
        }
241
242
        return $this->directory;
243
    }
244
245
    /**
246
     * @param string $directory
247
     */
248
    private function ensureDirectoryExists($directory)
249
    {
250
        if (true === is_dir($directory)) {
251
            return;
252
        }
253
254
        if (false === $this->create) {
255
            throw new \RuntimeException(sprintf('The directory "%s" does not exist.', $directory));
256
        }
257
258
        $created = mkdir($directory, $this->mode, true);
259
260
        if (false === $created && false === is_dir($directory)) {
261
            throw new \RuntimeException(sprintf('The directory \'%s\' could not be created.', $directory));
262
        }
263
    }
264
}
265