Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
30 / 30
100.00% covered (success)
100.00%
6 / 6
CRAP
100.00% covered (success)
100.00%
1 / 1
File
100.00% covered (success)
100.00%
30 / 30
100.00% covered (success)
100.00%
6 / 6
16
100.00% covered (success)
100.00%
1 / 1
 mustExist
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 mustBeReadable
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 openReadOnly
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 open
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
4
 close
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 getContents
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2
3declare(strict_types=1);
4
5namespace pvc\storage\filesys;
6
7use pvc\storage\filesys\err\FileDoesNotExistException;
8use pvc\storage\filesys\err\FileGetContentsException;
9use pvc\storage\filesys\err\FileNotReadableException;
10use pvc\storage\filesys\err\FileOpenException;
11use pvc\storage\filesys\err\InvalidFileHandleException;
12use pvc\storage\filesys\err\InvalidFileModeException;
13use pvc\storage\resource\err\InvalidResourceException;
14use Throwable;
15
16class File
17{
18    /**
19     * @param string $localFileName
20     * @return true
21     * @throws FileDoesNotExistException
22     */
23    public static function mustExist(string $localFileName): true
24    {
25        /**
26         * type checker is not aware that file
27         */
28        if (!file_exists($localFileName)) {
29            throw new FileDoesNotExistException($localFileName);
30        }
31        return true;
32    }
33
34    /**
35     * @param string $filePath
36     * @return true
37     * @throws FileNotReadableException
38     * @throws FileDoesNotExistException
39     */
40    public static function mustBeReadable(string $filePath): true
41    {
42        if (!file_exists($filePath)) {
43            throw new FileDoesNotExistException($filePath);
44        }
45        if (!is_readable($filePath)) {
46            throw new FileNotReadableException($filePath);
47        }
48        return true;
49    }
50
51
52    /**
53     * @param string $filePath
54     * @return resource
55     * adds a specific test to ensure the file is readable
56     */
57    public static function openReadOnly(string $filePath)
58    {
59        self::mustBeReadable($filePath);
60        return self::open($filePath, FileMode::READ);
61    }
62
63    /**
64     * @param string $filePath
65     * @param string $mode
66     * @return resource
67     */
68    public static function open(string $filePath, string $mode = 'r')
69    {
70        if (!FileMode::isDefined($mode)) {
71            throw new InvalidFileModeException($mode);
72        }
73
74        /**
75         * this may seem a bit laborious, but the VfsStream wrapper will throw its own error or exception
76         * if it fails because of permissions so we need to catch it.
77         */
78        try {
79            $handle = fopen($filePath, $mode);
80        } catch (Throwable $e) {
81            throw new FileOpenException($filePath, $mode, $e);
82        }
83
84        if ($handle === false) {
85            throw new FileOpenException($filePath, $mode);
86        }
87
88        return $handle;
89    }
90
91    /**
92     * @param resource $handle
93     * @return void
94     * @throws InvalidFileHandleException
95     * @throws InvalidResourceException
96     */
97    public static function close($handle): void
98    {
99        if (!is_resource($handle)) {
100            throw new InvalidResourceException();
101        }
102        if (get_resource_type($handle) !== 'stream') {
103            throw new InvalidFileHandleException();
104        }
105        fclose($handle);
106    }
107
108    /**
109     * @param string $filePath
110     * @return string
111     * @throws FileGetContentsException
112     * @throws FileNotReadableException
113     */
114    public static function getContents(string $filePath): string
115    {
116        self::mustBeReadable($filePath);
117        try {
118            $contents = file_get_contents($filePath);
119        } catch (Throwable $e) {
120            throw new FileGetContentsException($filePath, $e);
121        }
122        if ($contents === false) {
123            throw new FileGetContentsException($filePath);
124        }
125        return $contents;
126    }
127}