Passed
Push — master ( 3d4422...fdd4ed )
by Adrian Florin
02:35
created

File::getFactory()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 7
ccs 4
cts 4
cp 1
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 0
crap 2
1
<?php
2
/**
3
 * This file is part of the NeedleProject\FileIo package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
namespace NeedleProject\FileIo;
9
10
use NeedleProject\FileIo\Content\ContentInterface;
11
use NeedleProject\FileIo\Exception\FileNotFoundException;
12
use NeedleProject\FileIo\Exception\IOException;
13
use NeedleProject\FileIo\Exception\PermissionDeniedException;
14
use NeedleProject\FileIo\Factory\ContentFactory;
15
use NeedleProject\FileIo\Util\ErrorHandler;
16
17
/**
18
 * Class File
19
 *
20
 * @package NeedleProject\FileIo
21
 * @author Adrian Tilita <[email protected]>
22
 * @copyright 2017 Adrian Tilita
23
 * @license https://opensource.org/licenses/MIT MIT Licence
24
 */
25
class File
26
{
27
    /**
28
     * File extension separator
29
     * @const string
30
     */
31
    const EXTENSION_SEPARATOR = '.';
32
33
    /**
34
     * File's name including the path
35
     * @var null|string
36
     */
37
    private $filename = null;
38
39
    /**
40
     * File's extension - For no extension a blank string will be used
41
     * @var null|string
42
     */
43
    private $extension = null;
44
45
    /**
46
     * File's name without extension
47
     * @var null|string
48
     */
49
    private $name = null;
50
51
    /**
52
     * Whether the file has an extension or if it is set by us
53
     * @var bool
54
     */
55
    private $hasExtension = false;
56
57
    /**
58
     * @var null|ContentFactory
59
     */
60
    private $contentFactory = null;
61
62
    /**
63
     * File constructor.
64
     *
65
     * @param string $filename
66
     */
67 39
    public function __construct(string $filename)
68
    {
69 39
        $this->filename = preg_replace('#(\\\|\/)#', DIRECTORY_SEPARATOR, $filename);
70 39
        $fileParts = explode(DIRECTORY_SEPARATOR, $this->filename);
71 39
        $filename = array_pop($fileParts);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $filename. This often makes code more readable.
Loading history...
72 39
        if (false !== strpos($filename, static::EXTENSION_SEPARATOR)) {
73 32
            $this->hasExtension = true;
74 32
            $filenameParts = explode(static::EXTENSION_SEPARATOR, $filename);
75 32
            $this->extension = array_pop($filenameParts);
76 32
            $this->name = implode(static::EXTENSION_SEPARATOR, $filenameParts);
77
        } else {
78 7
            $this->name = $filename;
79 7
            $this->extension = '';
80
        }
81 39
    }
82
83
    /**
84
     * States whether the file actually exists on disk
85
     * @return bool
86
     */
87 19
    public function exists(): bool
0 ignored issues
show
Coding Style introduced by
function exists() does not seem to conform to the naming convention (^(?:is|has|should|may|supports)).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
88
    {
89 19
        return file_exists($this->filename);
90
    }
91
92
    /**
93
     * States whether the file is readable
94
     * @return bool
95
     */
96 6
    public function isReadable(): bool
97
    {
98 6
        return is_readable($this->filename);
99
    }
100
101
    /**
102
     * @return bool
103
     */
104 7
    public function isWritable(): bool
105
    {
106 7
        if ($this->exists()) {
107 6
            return is_writable($this->filename);
108
        }
109 1
        $parts = explode(DIRECTORY_SEPARATOR, $this->filename);
110 1
        array_pop($parts);
111 1
        return is_writable(implode(DIRECTORY_SEPARATOR, $parts));
112
    }
113
114
    /**
115
     * Write content to the current file
116
     *
117
     * @param \NeedleProject\FileIo\Content\ContentInterface $content
118
     * @return \NeedleProject\FileIo\File
119
     * @throws \NeedleProject\FileIo\Exception\PermissionDeniedException
120
     */
121 3
    public function write(ContentInterface $content): File
122
    {
123 3
        if ($this->isWritable() === false) {
124 1
            throw new PermissionDeniedException("The current file is not writable!");
125
        }
126 2
        file_put_contents($this->filename, $content->get());
127 2
        return $this;
128
    }
129
130
    /**
131
     * @return \NeedleProject\FileIo\Content\ContentInterface
132
     * @throws \NeedleProject\FileIo\Exception\FileNotFoundException
133
     * @throws \NeedleProject\FileIo\Exception\IOException
134
     * @throws \NeedleProject\FileIo\Exception\PermissionDeniedException
135
     */
136 6
    public function getContent(): ContentInterface
137
    {
138 6
        if ($this->exists() === false) {
139 2
            throw new FileNotFoundException(sprintf("%s does not exists!", $this->filename));
140
        }
141 4
        if ($this->isReadable() === false) {
142 1
            throw new PermissionDeniedException(
143 1
                sprintf("You do not have permissions to read file %s!", $this->filename)
144
            );
145
        }
146 3
        ErrorHandler::convertErrorsToExceptions();
147 3
        $stringContent = file_get_contents($this->filename);
148 2
        ErrorHandler::restoreErrorHandler();
149 2
        if (false === $stringContent) {
150 1
            throw new IOException(
151 1
                sprintf("Could not retrieve content! Error message: %s", error_get_last()['message'])
152
            );
153
        }
154 1
        return $this->getFactory()
155 1
            ->create($this->extension, $stringContent);
156
    }
157
158
    /**
159
     * Deletes the current file
160
     * @return bool
161
     * @throws \NeedleProject\FileIo\Exception\IOException
162
     */
163 3
    public function delete(): bool
0 ignored issues
show
Coding Style introduced by
function delete() does not seem to conform to the naming convention (^(?:is|has|should|may|supports)).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
164
    {
165 3
        if ($this->exists() === false) {
166 2
            return false;
167
        }
168 1
        ErrorHandler::convertErrorsToExceptions();
169 1
        $unlinkResult = unlink($this->filename);
170 1
        ErrorHandler::restoreErrorHandler();
171 1
        return $unlinkResult;
172
    }
173
174
    /**
175
     * State existence of a file's extension
176
     * @return bool
177
     */
178 10
    public function hasExtension(): bool
179
    {
180 10
        return $this->hasExtension;
181
    }
182
183
    /**
184
     * Get file's extension
185
     * @return string
186
     */
187 4
    public function getExtension(): string
188
    {
189 4
        return $this->extension;
190
    }
191
192
    /**
193
     * Get file's name without extension
194
     * @return string
195
     */
196 4
    public function getName(): string
197
    {
198 4
        return $this->name;
199
    }
200
201
    /**
202
     * Get file's name with extension
203
     * @return string
204
     */
205 5
    public function getBasename(): string
206
    {
207 5
        if (false === $this->hasExtension()) {
208 1
            return $this->name;
209
        }
210 4
        return $this->name . static::EXTENSION_SEPARATOR . $this->extension;
211
    }
212
213
    /**
214
     * Returns a factory responsible for creating appropriate content
215
     * @return \NeedleProject\FileIo\Factory\ContentFactory
216
     */
217 1
    protected function getFactory(): ContentFactory
218
    {
219 1
        if (is_null($this->contentFactory)) {
220 1
            $this->contentFactory = new ContentFactory();
221
        }
222 1
        return $this->contentFactory;
223
    }
224
}
225