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

LocalDriver::renameTempFile()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 13
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 13
rs 9.4285
cc 3
eloc 10
nc 2
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\Driver;
16
17
use Phossa2\Storage\Message\Message;
18
use Phossa2\Storage\Traits\LocalDirTrait;
19
use Phossa2\Storage\Exception\LogicException;
20
use Phossa2\Storage\Interfaces\PermissionAwareInterface;
21
22
/**
23
 * LocalDriver
24
 *
25
 * @package Phossa2\Storage
26
 * @author  Hong Zhang <[email protected]>
27
 * @see     DriverAbstract
28
 * @version 2.0.0
29
 * @since   2.0.0 added
30
 */
31
class LocalDriver extends DriverAbstract
32
{
33
    use LocalDirTrait;
34
35
    /**
36
     * driver root
37
     *
38
     * @var    string
39
     * @access protected
40
     */
41
    protected $root;
42
43
    /**
44
     * @param  string $rootDir
45
     * @throws LogicException
46
     * @access public
47
     */
48
    public function __construct(/*# string */ $rootDir)
49
    {
50
        if (!$this->makeDirectory($rootDir)) {
51
            throw new LogicException(
52
                $this->getError(), $this->getErrorCode()
53
            );
54
        }
55
        $this->root = rtrim($rootDir, "/\\") . \DIRECTORY_SEPARATOR;
56
    }
57
58
    /**
59
     * {@inheritDoc}
60
     */
61
    protected function realPath(/*# string */ $path)/*# : string */
62
    {
63
        return $this->root . ('/' !== \DIRECTORY_SEPARATOR ?
64
            str_replace('/', \DIRECTORY_SEPARATOR, $path) : $path);
65
    }
66
67
    /**
68
     * {@inheritDoc}
69
     */
70
    protected function realExists(/*# string */ $realPath)/*# : bool */
71
    {
72
        return file_exists($realPath);
73
    }
74
75
    /**
76
     * {@inheritDoc}
77
     */
78
    protected function openReadStream(/*# string */ $realPath)
79
    {
80
        $stream = fopen($realPath, 'r');
81
        if (is_resource($stream)) {
82
            return $stream;
83
        } else {
84
            $this->setError(
85
                Message::get(Message::STR_OPENSTREAM_FAIL, $realPath),
86
                Message::STR_OPENSTREAM_FAIL
87
            );
88
            return null;
89
        }
90
    }
91
92
    /**
93
     * {@inheritDoc}
94
     */
95
    protected function readFile(/*# string */ $realPath)
96
    {
97
        $str = file_get_contents($realPath);
98
99
        if (false === $str) {
100
            $this->setError(
101
                Message::get(Message::STR_OPENSTREAM_FAIL, $realPath),
102
                Message::STR_OPENSTREAM_FAIL
103
            );
104
            return null;
105
        }
106
107
        return $str;
108
    }
109
110
    /**
111
     * {@inheritDoc}
112
     */
113
    protected function getRealMeta(/*# string */ $realPath)/*# : array */
114
    {
115
        try {
116
            $info = new \SplFileInfo($realPath);
117
            return [
118
                'size'  => $info->getSize(),
119
                'perm'  => $info->getPerms() & PermissionAwareInterface::PERM_ALL,
120
                'ctime' => $info->getCTime(),
121
                'mtime' => $info->getMTime(),
122
            ];
123
        } catch (\Exception $e) {
124
            $this->setError(
125
                Message::get(Message::STR_GETMETA_FAIL, $realPath),
126
                Message::STR_GETMETA_FAIL
127
            );
128
            return [];
129
        }
130
    }
131
132
    /**
133
     * {@inheritDoc}
134
     */
135
    protected function ensurePath(/*# string */ $realPath)/*# : bool */
136
    {
137
        $parent = dirname($realPath);
138
        if (!$this->makeDirectory($parent)) {
139
            return false;
140
        }
141
        return true;
142
    }
143
144
    /**
145
     * {@inheritDoc}
146
     */
147 View Code Duplication
    protected function writeStream(
148
        /*# string */ $realPath,
149
        $resource
150
    )/*# : bool */ {
151
        $tmpfname = tempnam(dirname($realPath), 'FOO');
152
        if (false !== $tmpfname) {
153
            $stream = fopen($tmpfname, 'w+b');
154
            if (is_resource($stream)) {
155
                stream_copy_to_stream($resource, $stream);
156
                fclose($stream);
157
                return $this->renameTempFile($tmpfname, $realPath);
158
            }
159
        }
160
        return false;
161
    }
162
163
    /**
164
     * {@inheritDoc}
165
     */
166 View Code Duplication
    protected function writeFile(
167
        /*# string */ $realPath,
168
        /*# string */ $content
169
    )/*# : bool */ {
170
        // write to a temp file
171
        $tmpfname = tempnam(dirname($realPath), 'FOO');
172
        if (false !== $tmpfname) {
173
            $handle = fopen($tmpfname, 'w');
174
            fwrite($handle, $content);
175
            fclose($handle);
176
177
            return $this->renameTempFile($tmpfname, $realPath);
178
        }
179
        return false;
180
    }
181
182
    /**
183
     * {@inheritDoc}
184
     */
185
    protected function setRealMeta(
186
        /*# string */ $realPath,
187
        array $meta
188
    )/*# : bool */ {
189
        clearstatcache(true, $realPath);
190
191
        if (isset($meta['mtime'])) {
192
            touch($realPath, $meta['mtime']);
193
        }
194
195
        if (isset($meta['perm'])) {
196
            chmod($realPath, (int) $meta['perm']);
197
        }
198
        return true;
199
    }
200
201
    /**
202
     * {@inheritDoc}
203
     */
204
    protected function renameFile(
205
        /*# string */ $from,
206
        /*# string */ $to
207
    )/*# : bool */ {
208
        return @rename($from, $to);
209
    }
210
211
    /**
212
     * {@inheritDoc}
213
     */
214
    protected function copyFile(
215
        /*# string */ $from,
216
        /*# string */ $to
217
    )/*# : bool */ {
218
        return @copy($from, $to);
219
    }
220
221
    /**
222
     * {@inheritDoc}
223
     */
224
    protected function deleteFile(/*# string */ $realPath)/*# : bool */
225
    {
226
        return unlink($realPath);
227
    }
228
229
    /**
230
     * Rename tmpfile
231
     *
232
     * @param  string $tmpFile
233
     * @param  string $realPath
234
     * @return bool
235
     * @access protected
236
     */
237
    protected function renameTempFile(
238
        /*# string */ $tmpFile,
239
        /*# string */ $realPath
240
    )/*# : bool */ {
241
        if (@rename($tmpFile, $realPath) &&
242
            @chmod($realPath, PermissionAwareInterface::PERM_ALL)) {
243
            return true;
244
        }
245
        $err = error_get_last();
246
        $this->setError($err['message'], Message::STR_WRITEFILE_FAIL);
247
        @unlink($tmpFile);
1 ignored issue
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
248
        return false;
249
    }
250
}
251