Passed
Branch master (d05c4a)
by Adrian Florin
03:53 queued 54s
created

File::getContentFactory()   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\Helper\PathHelper;
16
use NeedleProject\FileIo\Util\ErrorHandler;
17
18
/**
19
 * Class File
20
 *
21
 * @package NeedleProject\FileIo
22
 * @author Adrian Tilita <[email protected]>
23
 * @copyright 2017 Adrian Tilita
24
 * @license https://opensource.org/licenses/MIT MIT Licence
25
 */
26
class File
27
{
28
    /**
29
     * File extension separator
30
     * @const string
31
     */
32
    const EXTENSION_SEPARATOR = '.';
33
34
    /**
35
     * File's name including the path
36
     * @var null|string
37
     */
38
    private $filenameWithPath = null;
39
40
    /**
41
     * File's extension - For no extension a blank string will be used
42
     * @var null|string
43
     */
44
    private $extension = null;
45
46
    /**
47
     * File's name without extension
48
     * @var null|string
49
     */
50
    private $name = null;
51
52
    /**
53
     * Whether the file has an extension or if it is set by us
54
     * @var bool
55
     */
56
    private $hasExtension = false;
57
58
    /**
59
     * @var null|ContentFactory
60
     */
61
    private $contentFactory = null;
62
63
    /**
64
     * File constructor.
65
     *
66
     * @param string $filename_with_path
67
     */
68 39
    public function __construct(string $filename_with_path)
0 ignored issues
show
Coding Style introduced by
$filename_with_path does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

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...
69
    {
70 39
        $pathHelper = new PathHelper();
71 39
        $this->filenameWithPath = $pathHelper->normalizePathSeparator($filename_with_path);
0 ignored issues
show
Coding Style introduced by
$filename_with_path does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

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...
72 39
        $filename = $pathHelper->extractFilenameFromPath($this->filenameWithPath);
73 39
        if (empty($filename)) {
74
            throw new \RuntimeException(
75
                sprintf('Given path %s does not represents a file!', $filename_with_path)
0 ignored issues
show
Coding Style introduced by
$filename_with_path does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

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...
76
            );
77
        }
78 39
        list($this->name, $this->extension) = $pathHelper->splitFilename($filename);
79 39
        $this->hasExtension = (bool)$this->extension;
80 39
    }
81
82
    /**
83
     * States whether the file actually exists on disk
84
     * @return bool
85
     */
86 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...
87
    {
88 19
        return file_exists($this->filenameWithPath);
89
    }
90
91
    /**
92
     * States whether the file is readable
93
     * @return bool
94
     */
95 6
    public function isReadable(): bool
96
    {
97 6
        return is_readable($this->filenameWithPath);
98
    }
99
100
    /**
101
     * @return bool
102
     */
103 7
    public function isWritable(): bool
104
    {
105 7
        if ($this->exists()) {
106 6
            return is_writable($this->filenameWithPath);
107
        }
108 1
        $parts = explode(DIRECTORY_SEPARATOR, $this->filenameWithPath);
109 1
        array_pop($parts);
110 1
        return is_writable(implode(DIRECTORY_SEPARATOR, $parts));
111
    }
112
113
    /**
114
     * Write content to the current file
115
     *
116
     * @param \NeedleProject\FileIo\Content\ContentInterface $content
117
     * @return \NeedleProject\FileIo\File
118
     * @throws \NeedleProject\FileIo\Exception\PermissionDeniedException
119
     */
120 3
    public function write(ContentInterface $content): File
121
    {
122 3
        if ($this->isWritable() === false) {
123 1
            throw new PermissionDeniedException("The current file is not writable!");
124
        }
125 2
        file_put_contents($this->filenameWithPath, $content->get());
126 2
        return $this;
127
    }
128
129
    /**
130
     * @return \NeedleProject\FileIo\Content\ContentInterface
131
     * @throws \NeedleProject\FileIo\Exception\FileNotFoundException
132
     * @throws \NeedleProject\FileIo\Exception\IOException
133
     * @throws \NeedleProject\FileIo\Exception\PermissionDeniedException
134
     */
135 6
    public function getContent(): ContentInterface
136
    {
137 6
        if ($this->exists() === false) {
138 2
            throw new FileNotFoundException(sprintf("%s does not exists!", $this->filenameWithPath));
139
        }
140 4
        if ($this->isReadable() === false) {
141 1
            throw new PermissionDeniedException(
142 1
                sprintf("You do not have permissions to read file %s!", $this->filenameWithPath)
143
            );
144
        }
145 3
        ErrorHandler::convertErrorsToExceptions();
146 3
        $stringContent = file_get_contents($this->filenameWithPath);
147 2
        ErrorHandler::restoreErrorHandler();
148 2
        if (false === $stringContent) {
149 1
            throw new IOException(
150 1
                sprintf("Could not retrieve content! Error message: %s", error_get_last()['message'])
151
            );
152
        }
153 1
        return $this->getContentFactory()
154 1
            ->create($this->extension, $stringContent);
155
    }
156
157
    /**
158
     * Deletes the current file
159
     * @return bool
160
     * @throws \NeedleProject\FileIo\Exception\IOException
161
     */
162 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...
163
    {
164 3
        if ($this->exists() === false) {
165 2
            return false;
166
        }
167 1
        ErrorHandler::convertErrorsToExceptions();
168 1
        $unlinkResult = unlink($this->filenameWithPath);
169 1
        ErrorHandler::restoreErrorHandler();
170 1
        return $unlinkResult;
171
    }
172
173
    /**
174
     * State existence of a file's extension
175
     * @return bool
176
     */
177 10
    public function hasExtension(): bool
178
    {
179 10
        return $this->hasExtension;
180
    }
181
182
    /**
183
     * Get file's extension
184
     * @return string
185
     */
186 4
    public function getExtension(): string
187
    {
188 4
        return $this->extension;
189
    }
190
191
    /**
192
     * Get file's name without extension
193
     * @return string
194
     */
195 4
    public function getName(): string
196
    {
197 4
        return $this->name;
198
    }
199
200
    /**
201
     * Get file's name with extension
202
     * @return string
203
     */
204 5
    public function getBasename(): string
205
    {
206 5
        if (false === $this->hasExtension()) {
207 1
            return $this->name;
208
        }
209 4
        return $this->name . static::EXTENSION_SEPARATOR . $this->extension;
210
    }
211
212
    /**
213
     * Returns a factory responsible for creating appropriate content
214
     * @return \NeedleProject\FileIo\Factory\ContentFactory
215
     */
216 1
    protected function getContentFactory(): ContentFactory
217
    {
218 1
        if (is_null($this->contentFactory)) {
219 1
            $this->contentFactory = new ContentFactory();
220
        }
221 1
        return $this->contentFactory;
222
    }
223
}
224