LocalDriver   A
last analyzed

Complexity

Total Complexity 27

Size/Duplication

Total Lines 221
Duplicated Lines 19.91 %

Coupling/Cohesion

Components 2
Dependencies 4

Importance

Changes 0
Metric Value
wmc 27
lcom 2
cbo 4
dl 44
loc 221
rs 10
c 0
b 0
f 0

14 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 10 2
A realPath() 0 5 2
A realExists() 0 4 1
A openReadStream() 0 13 2
A readFile() 14 14 2
A getRealMeta() 0 18 2
A ensurePath() 0 8 2
A writeStream() 15 15 3
A writeFile() 15 15 2
A setRealMeta() 0 15 3
A renameFile() 0 6 1
A copyFile() 0 6 1
A deleteFile() 0 4 1
A renameTempFile() 0 13 3

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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(),
53
                $this->getErrorCode()
54
            );
55
        }
56
        $this->root = rtrim($rootDir, "/\\") . \DIRECTORY_SEPARATOR;
57
    }
58
59
    /**
60
     * {@inheritDoc}
61
     */
62
    protected function realPath(/*# string */ $path)/*# : string */
63
    {
64
        return $this->root . ('/' !== \DIRECTORY_SEPARATOR ?
65
            str_replace('/', \DIRECTORY_SEPARATOR, $path) : $path);
66
    }
67
68
    /**
69
     * {@inheritDoc}
70
     */
71
    protected function realExists(/*# string */ $realPath)/*# : bool */
72
    {
73
        return file_exists($realPath);
74
    }
75
76
    /**
77
     * {@inheritDoc}
78
     */
79
    protected function openReadStream(/*# string */ $realPath)
80
    {
81
        $stream = fopen($realPath, 'r');
82
        if (is_resource($stream)) {
83
            return $stream;
84
        } else {
85
            $this->setError(
86
                Message::get(Message::STR_OPENSTREAM_FAIL, $realPath),
87
                Message::STR_OPENSTREAM_FAIL
88
            );
89
            return null;
90
        }
91
    }
92
93
    /**
94
     * {@inheritDoc}
95
     */
96 View Code Duplication
    protected function readFile(/*# string */ $realPath)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
97
    {
98
        $str = file_get_contents($realPath);
99
100
        if (false === $str) {
101
            $this->setError(
102
                Message::get(Message::STR_OPENSTREAM_FAIL, $realPath),
103
                Message::STR_OPENSTREAM_FAIL
104
            );
105
            return null;
106
        }
107
108
        return $str;
109
    }
110
111
    /**
112
     * {@inheritDoc}
113
     */
114
    protected function getRealMeta(/*# string */ $realPath)/*# : array */
115
    {
116
        try {
117
            $info = new \SplFileInfo($realPath);
118
            return [
119
                'size'  => $info->getSize(),
120
                'perm'  => $info->getPerms() & PermissionAwareInterface::PERM_ALL,
121
                'ctime' => $info->getCTime(),
122
                'mtime' => $info->getMTime(),
123
            ];
124
        } catch (\Exception $e) {
125
            $this->setError(
126
                Message::get(Message::STR_GETMETA_FAIL, $realPath),
127
                Message::STR_GETMETA_FAIL
128
            );
129
            return [];
130
        }
131
    }
132
133
    /**
134
     * {@inheritDoc}
135
     */
136
    protected function ensurePath(/*# string */ $realPath)/*# : bool */
137
    {
138
        $parent = dirname($realPath);
139
        if (!$this->makeDirectory($parent)) {
140
            return false;
141
        }
142
        return true;
143
    }
144
145
    /**
146
     * {@inheritDoc}
147
     */
148 View Code Duplication
    protected function writeStream(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
149
        /*# string */ $realPath,
150
        $resource
151
    )/*# : bool */ {
152
        $tmpfname = tempnam(dirname($realPath), 'FOO');
153
        if (false !== $tmpfname) {
154
            $stream = fopen($tmpfname, 'w+b');
155
            if (is_resource($stream)) {
156
                stream_copy_to_stream($resource, $stream);
157
                fclose($stream);
158
                return $this->renameTempFile($tmpfname, $realPath);
159
            }
160
        }
161
        return false;
162
    }
163
164
    /**
165
     * {@inheritDoc}
166
     */
167 View Code Duplication
    protected function writeFile(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
168
        /*# string */ $realPath,
169
        /*# string */ $content
170
    )/*# : bool */ {
171
        // write to a temp file
172
        $tmpfname = tempnam(dirname($realPath), 'FOO');
173
        if (false !== $tmpfname) {
174
            $handle = fopen($tmpfname, 'w');
175
            fwrite($handle, $content);
176
            fclose($handle);
177
178
            return $this->renameTempFile($tmpfname, $realPath);
179
        }
180
        return false;
181
    }
182
183
    /**
184
     * {@inheritDoc}
185
     */
186
    protected function setRealMeta(
187
        /*# string */ $realPath,
188
        array $meta
189
    )/*# : bool */ {
190
        clearstatcache(true, $realPath);
191
192
        if (isset($meta['mtime'])) {
193
            touch($realPath, $meta['mtime']);
194
        }
195
196
        if (isset($meta['perm'])) {
197
            chmod($realPath, (int) $meta['perm']);
198
        }
199
        return true;
200
    }
201
202
    /**
203
     * {@inheritDoc}
204
     */
205
    protected function renameFile(
206
        /*# string */ $from,
207
        /*# string */ $to
208
    )/*# : bool */ {
209
        return @rename($from, $to);
210
    }
211
212
    /**
213
     * {@inheritDoc}
214
     */
215
    protected function copyFile(
216
        /*# string */ $from,
217
        /*# string */ $to
218
    )/*# : bool */ {
219
        return @copy($from, $to);
220
    }
221
222
    /**
223
     * {@inheritDoc}
224
     */
225
    protected function deleteFile(/*# string */ $realPath)/*# : bool */
226
    {
227
        return unlink($realPath);
228
    }
229
230
    /**
231
     * Rename tmpfile
232
     *
233
     * @param  string $tmpFile
234
     * @param  string $realPath
235
     * @return bool
236
     * @access protected
237
     */
238
    protected function renameTempFile(
239
        /*# string */ $tmpFile,
240
        /*# string */ $realPath
241
    )/*# : bool */ {
242
        if (@rename($tmpFile, $realPath) &&
243
            @chmod($realPath, PermissionAwareInterface::PERM_ALL)) {
244
            return true;
245
        }
246
        $err = error_get_last();
247
        $this->setError($err['message'], Message::STR_WRITEFILE_FAIL);
248
        @unlink($tmpFile);
0 ignored issues
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...
249
        return false;
250
    }
251
}
252