Passed
Push — master ( d487cc...3d4422 )
by Adrian Florin
02:34
created

File::hasExtension()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 1
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\Content;
11
use NeedleProject\FileIo\Content\ContentInterface;
12
use NeedleProject\FileIo\Exception\FileNotFoundException;
13
use NeedleProject\FileIo\Exception\IOException;
14
use NeedleProject\FileIo\Exception\PermissionDeniedException;
15
use NeedleProject\FileIo\Util\ErrorHandler;
16
17
/**
18
 * Class File
19
 *
20
 * @package NeedleProject\FileIo
21
 * @author Adrian Tilita <[email protected]>
22
 * @copyright 2016-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
     * File constructor.
59
     *
60
     * @param string $filename
61
     */
62 39
    public function __construct(string $filename)
63
    {
64 39
        $this->filename = preg_replace('#(\\\|\/)#', DIRECTORY_SEPARATOR, $filename);
65 39
        $fileParts = explode(DIRECTORY_SEPARATOR, $this->filename);
66 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...
67 39
        if (false !== strpos($filename, static::EXTENSION_SEPARATOR)) {
68 32
            $this->hasExtension = true;
69 32
            $filenameParts = explode(static::EXTENSION_SEPARATOR, $filename);
70 32
            $this->extension = array_pop($filenameParts);
71 32
            $this->name = implode(static::EXTENSION_SEPARATOR, $filenameParts);
72
        } else {
73 7
            $this->name = $filename;
74 7
            $this->extension = '';
75
        }
76 39
    }
77
78
    /**
79
     * States whether the file actually exists on disk
80
     * @return bool
81
     */
82 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...
83
    {
84 19
        return file_exists($this->filename);
85
    }
86
87
    /**
88
     * States whether the file is readable
89
     * @return bool
90
     */
91 6
    public function isReadable(): bool
92
    {
93 6
        return is_readable($this->filename);
94
    }
95
96
    /**
97
     * @return bool
98
     */
99 7
    public function isWritable(): bool
100
    {
101 7
        if ($this->exists()) {
102 6
            return is_writable($this->filename);
103
        }
104 1
        $parts = explode(DIRECTORY_SEPARATOR, $this->filename);
105 1
        array_pop($parts);
106 1
        return is_writable(implode(DIRECTORY_SEPARATOR, $parts));
107
    }
108
109
    /**
110
     * Write content to the current file
111
     *
112
     * @param \NeedleProject\FileIo\Content\ContentInterface $content
113
     * @return \NeedleProject\FileIo\File
114
     * @throws \NeedleProject\FileIo\Exception\PermissionDeniedException
115
     */
116 3
    public function write(ContentInterface $content): File
117
    {
118 3
        if ($this->isWritable() === false) {
119 1
            throw new PermissionDeniedException("The current file is not writable!");
120
        }
121 2
        file_put_contents($this->filename, $content->get());
122 2
        return $this;
123
    }
124
125
    /**
126
     * @return \NeedleProject\FileIo\Content\ContentInterface
127
     * @throws \NeedleProject\FileIo\Exception\FileNotFoundException
128
     * @throws \NeedleProject\FileIo\Exception\IOException
129
     * @throws \NeedleProject\FileIo\Exception\PermissionDeniedException
130
     */
131 6
    public function getContent(): ContentInterface
132
    {
133 6
        if ($this->exists() === false) {
134 2
            throw new FileNotFoundException(sprintf("%s does not exists!", $this->filename));
135
        }
136 4
        if ($this->isReadable() === false) {
137 1
            throw new PermissionDeniedException(
138 1
                sprintf("You do not have permissions to read file %s!", $this->filename)
139
            );
140
        }
141 3
        ErrorHandler::convertErrorsToExceptions();
142 3
        $stringContent = file_get_contents($this->filename);
143 2
        ErrorHandler::restoreErrorHandler();
144 2
        if (false === $stringContent) {
145 1
            throw new IOException(
146 1
                sprintf("Could not retrieve content! Error message: %s", error_get_last()['message'])
147
            );
148
        }
149 1
        return new Content($stringContent);
150
    }
151
152
    /**
153
     * Deletes the current file
154
     * @return bool
155
     * @throws \NeedleProject\FileIo\Exception\IOException
156
     */
157 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...
158
    {
159 3
        if ($this->exists() === false) {
160 2
            return false;
161
        }
162 1
        ErrorHandler::convertErrorsToExceptions();
163 1
        $unlinkResult = unlink($this->filename);
164 1
        ErrorHandler::restoreErrorHandler();
165 1
        return $unlinkResult;
166
    }
167
168
    /**
169
     * State existence of a file's extension
170
     * @return bool
171
     */
172 10
    public function hasExtension(): bool
173
    {
174 10
        return $this->hasExtension;
175
    }
176
177
    /**
178
     * Get file's extension
179
     * @return string
180
     */
181 4
    public function getExtension(): string
182
    {
183 4
        return $this->extension;
184
    }
185
186
    /**
187
     * Get file's name without extension
188
     * @return string
189
     */
190 4
    public function getName(): string
191
    {
192 4
        return $this->name;
193
    }
194
195
    /**
196
     * Get file's name with extension
197
     * @return string
198
     */
199 5
    public function getBasename(): string
200
    {
201 5
        if (false === $this->hasExtension()) {
202 1
            return $this->name;
203
        }
204 4
        return $this->name . static::EXTENSION_SEPARATOR . $this->extension;
205
    }
206
}
207