Completed
Push — master ( 9ef354...ebcd99 )
by Hong
02:10
created

Storage::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 6
rs 9.4285
cc 1
eloc 4
nc 1
nop 2
1
<?php
2
/**
3
 * Phossa Project
4
 *
5
 * PHP version 5.4
6
 *
7
 * @category  Library
8
 * @package   Phossa2\Storage
9
 * @copyright Copyright (c) 2016 phossa.com
10
 * @license   http://mit-license.org/ MIT License
11
 * @link      http://www.phossa.com/
12
 */
13
/*# declare(strict_types=1); */
14
15
namespace Phossa2\Storage;
16
17
use Phossa2\Storage\Message\Message;
18
use Phossa2\Shared\Base\ObjectAbstract;
19
use Phossa2\Shared\Error\ErrorAwareTrait;
20
use Phossa2\Storage\Traits\PathAwareTrait;
21
use Phossa2\Shared\Error\ErrorAwareInterface;
22
use Phossa2\Storage\Interfaces\StorageInterface;
23
use Phossa2\Shared\Extension\ExtensionAwareTrait;
24
use Phossa2\Shared\Extension\ExtensionAwareInterface;
25
use Phossa2\Storage\Interfaces\FilesystemInterface;
26
27
/**
28
 * Storage
29
 *
30
 * @package Phossa2\Storage
31
 * @author  Hong Zhang <[email protected]>
32
 * @see     ObjectAbstract
33
 * @see     StorageInterface
34
 * @see     ErrorAwareInterface
35
 * @see     ExtensionAwareInterface
36
 * @version 2.0.0
37
 * @since   2.0.0 added
38
 */
39
class Storage extends ObjectAbstract implements StorageInterface, ErrorAwareInterface, ExtensionAwareInterface
40
{
41
    use PathAwareTrait, ErrorAwareTrait, ExtensionAwareTrait;
42
43
    /**
44
     * @param  string $mountPoint
45
     * @param  FilesystemInterface $filesystem
46
     * @access public
47
     */
48
    public function __construct(
49
        /*# string */ $mountPoint,
50
        FilesystemInterface $filesystem
51
    ) {
52
        $this->mount($mountPoint, $filesystem);
53
    }
54
55
    /**
56
     * {@inheritDoc}
57
     */
58
    public function has(/*# string */ $path)/*# : bool */
59
    {
60
        // found
61
        if ($this->path($path)->exists()) {
62
            return true;
63
        }
64
65
        // not found
66
        return $this->setError(
67
            Message::get(Message::MSG_PATH_NOTFOUND, $path),
68
            Message::MSG_PATH_NOTFOUND
69
        );
70
    }
71
72
    /**
73
     * {@inheritDoc}
74
     */
75
    public function get(/*# string */ $path, /*# bool */ $stream = false)
76
    {
77
        $obj = $this->path($path);
78
        $res = $obj->getContent($stream);
79
80
        // append mount point if result is array
81
        if (is_array($res)) {
82
            return $this->prependMountPoint(
83
                $res, $this->getMountPoint($obj->getFullPath())
84
            );
85
        }
86
87
        $this->copyError($obj);
88
89
        return $res;
90
    }
91
92
    /**
93
     * {@inheritDoc}
94
     */
95
    public function put(
96
        /*# string */ $path,
97
        $content,
98
        array $meta = []
99
    )/*# : bool */ {
100
        $obj = $this->path($path);
101
102
        // write content
103
        if (null !== $content && !$obj->setContent($content)) {
104
            $this->copyError($obj);
105
            return false;
106
        }
107
108
        // set meta if any
109
        $res = $obj->setMeta($meta);
110
        $this->copyError($obj);
111
        return $res;
112
    }
113
114
    /**
115
     * {@inheritDoc}
116
     */
117
    public function meta(/*# string */ $path)/*# : array */
118
    {
119
        $obj = $this->path($path);
120
        $res = $obj->getMeta();
121
        $this->copyError($obj);
122
        return $res;
123
    }
124
125
    /**
126
     * {@inheritDoc}
127
     */
128
    public function copy(
129
        /*# string */ $from,
130
        /*# string */ $to
131
    )/*# : bool */ {
132
        // same filesystem copy
133
        if ($this->isSameFilesystem($from, $to)) {
134
            return $this->sameFilesystemAction($from, $to, 'copy');
135
        }
136
137
        $content = $this->get($from);
138
        if (is_null($content)) {
139
            return false;
140
        } elseif (is_array($content)) {
141
            return $this->copyDir($content, $to);
142
        } else {
143
            return $this->put($to, $content);
144
        }
145
    }
146
147
    /**
148
     * {@inheritDoc}
149
     */
150
    public function move(
151
        /*# string */ $from,
152
        /*# string */ $to
153
    )/*# : bool */ {
154
        // same filesystem move
155
        if ($this->isSameFilesystem($from, $to)) {
156
            return $this->sameFilesystemAction($from, $to, 'rename');
157
        }
158
159
        // diff filesystem move
160
        if ($this->copy($from, $to)) {
161
            return $this->delete($from);
162
        }
163
        return false;
164
    }
165
166
    /**
167
     * {@inheritDoc}
168
     */
169
    public function delete(/*# string */ $path)/*# : bool */
170
    {
171
        $obj = $this->path($path);
172
        $res = $obj->delete();
173
        $this->copyError($obj);
174
        return $res;
175
    }
176
177
    /**
178
     * Copy or rename
179
     *
180
     * @param  string $from
181
     * @param  string $to
182
     * @param  string $action 'copy' or 'rename'
183
     * @return bool
184
     * @access protected
185
     */
186
    protected function sameFilesystemAction(
187
        /*# string */ $from,
188
        /*# string */ $to,
189
        /*# string */ $action = 'copy'
190
    )/*# : bool */ {
191
        $obj = $this->path($from);
192
        $res = $obj->{$action}($this->path($to)->getPath());
193
        $this->copyError($obj);
194
        return $res;
195
    }
196
197
    /**
198
     * Exists on same filesystem ?
199
     *
200
     * @param  string $path1
201
     * @param  string $path2
202
     * @return bool
203
     * @access protected
204
     */
205
    protected function isSameFilesystem(
206
        /*# string */ $path1,
207
        /*# string */ $path2
208
    )/*# : bool */ {
209
        return $this->path($path1)->getFilesystem() === $this->path($path2)->getFilesystem();
210
    }
211
212
    /**
213
     * Copy an array of paths to destination
214
     *
215
     * @param  array $paths
216
     * @param  string $destination
217
     * @access protected
218
     */
219
    protected function copyDir(array $paths, /*# string */ $destination)
220
    {
221
        foreach ($paths as $path) {
222
            $base = basename($path);
223
            $dest = $this->mergePath($destination, $base);
224
            if (!$this->copy($path, $dest)) {
225
                return false;
226
            }
227
        }
228
        return true;
229
    }
230
231
    /**
232
     * Prepend mount point prefix to the array of paths
233
     *
234
     * @param  array $paths
235
     * @param  string $mountPoint
236
     * @return array
237
     * @access protected
238
     */
239
    protected function prependMountPoint(
240
        array $paths,
241
        /*# string */ $mountPoint
242
    )/*# : array */ {
243
        $res = [];
244
        foreach ($paths as $p) {
245
            $res[] = $this->mergePath($mountPoint, $p);
246
        }
247
        return $res;
248
    }
249
}
250