Completed
Push — master ( f61a47...233e03 )
by Hong
02:41
created

Storage::copy()   B

Complexity

Conditions 5
Paths 7

Size

Total Lines 25
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
c 4
b 0
f 0
dl 0
loc 25
rs 8.439
cc 5
eloc 14
nc 7
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
        if ($this->isDir($to)) {
138
            $to = $this->mergePath($to, basename($from));
139
        }
140
141
        $content = $this->get($from);
142
143
        if (is_null($content)) {
144
            return false;
145
146
        } elseif (is_array($content)) {
147
            return $this->copyDir($content, $to);
148
149
        } else {
150
            return $this->put($to, $content);
151
        }
152
    }
153
154
    /**
155
     * {@inheritDoc}
156
     */
157
    public function move(
158
        /*# string */ $from,
159
        /*# string */ $to
160
    )/*# : bool */ {
161
        // same filesystem move
162
        if ($this->isSameFilesystem($from, $to)) {
163
            return $this->sameFilesystemAction($from, $to, 'rename');
164
        }
165
166
        // diff filesystem move
167
        if ($this->copy($from, $to)) {
168
            return $this->delete($from);
169
        }
170
        return false;
171
    }
172
173
    /**
174
     * {@inheritDoc}
175
     */
176
    public function delete(/*# string */ $path)/*# : bool */
177
    {
178
        $obj = $this->path($path);
179
        $res = $obj->delete();
180
        $this->copyError($obj);
181
        return $res;
182
    }
183
184
    /**
185
     * {@inheritDoc}
186
     */
187
    public function isDir(/*# string */ $path)/*# : bool */
188
    {
189
        return $this->path($path)->isDir();
190
    }
191
192
    /**
193
     * Copy or rename
194
     *
195
     * @param  string $from
196
     * @param  string $to
197
     * @param  string $action 'copy' or 'rename'
198
     * @return bool
199
     * @access protected
200
     */
201
    protected function sameFilesystemAction(
202
        /*# string */ $from,
203
        /*# string */ $to,
204
        /*# string */ $action = 'copy'
205
    )/*# : bool */ {
206
        $obj = $this->path($from);
207
        $res = $obj->{$action}($this->path($to)->getPath());
208
        $this->copyError($obj);
209
        return $res;
210
    }
211
212
    /**
213
     * Exists on same filesystem ?
214
     *
215
     * @param  string $path1
216
     * @param  string $path2
217
     * @return bool
218
     * @access protected
219
     */
220
    protected function isSameFilesystem(
221
        /*# string */ $path1,
222
        /*# string */ $path2
223
    )/*# : bool */ {
224
        return $this->path($path1)->getFilesystem() === $this->path($path2)->getFilesystem();
225
    }
226
227
    /**
228
     * Copy an array of paths to destination
229
     *
230
     * @param  array $paths
231
     * @param  string $destination
232
     * @access protected
233
     */
234
    protected function copyDir(array $paths, /*# string */ $destination)
235
    {
236
        foreach ($paths as $path) {
237
            $dest = $this->mergePath($destination, basename($path));
238
            if (!$this->copy($path, $dest)) {
239
                return false;
240
            }
241
        }
242
        return true;
243
    }
244
245
    /**
246
     * Prepend mount point prefix to the array of paths
247
     *
248
     * @param  array $paths
249
     * @param  string $mountPoint
250
     * @return array
251
     * @access protected
252
     */
253
    protected function prependMountPoint(
254
        array $paths,
255
        /*# string */ $mountPoint
256
    )/*# : array */ {
257
        $res = [];
258
        foreach ($paths as $p) {
259
            $res[] = $this->mergePath($mountPoint, $p);
260
        }
261
        return $res;
262
    }
263
}
264