Completed
Push — master ( 23f8cc...771781 )
by Adrien
02:41
created

FileSystemHelper::deleteFile()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
ccs 6
cts 6
cp 1
cc 3
eloc 4
nc 2
nop 1
crap 3
1
<?php
2
3
namespace Box\Spout\Common\Helper;
4
5
use Box\Spout\Common\Exception\IOException;
6
7
/**
8
 * Class FileSystemHelper
9
 * This class provides helper functions to help with the file system operations
10
 * like files/folders creation & deletion
11
 *
12
 * @package Box\Spout\Common\Helper
13
 */
14
class FileSystemHelper
15
{
16
    /** @var string Real path of the base folder where all the I/O can occur */
17
    protected $baseFolderRealPath;
18
19
    /**
20
     * @param string $baseFolderPath The path of the base folder where all the I/O can occur
21
     */
22 276
    public function __construct($baseFolderPath)
23
    {
24 276
        $this->baseFolderRealPath = realpath($baseFolderPath);
25 276
    }
26
27
    /**
28
     * Creates an empty folder with the given name under the given parent folder.
29
     *
30
     * @param string $parentFolderPath The parent folder path under which the folder is going to be created
31
     * @param string $folderName The name of the folder to create
32
     * @return string Path of the created folder
33
     * @throws \Box\Spout\Common\Exception\IOException If unable to create the folder or if the folder path is not inside of the base folder
34
     */
35 267
    public function createFolder($parentFolderPath, $folderName)
36
    {
37 267
        $this->throwIfOperationNotInBaseFolder($parentFolderPath);
38
39 264
        $folderPath = $parentFolderPath . '/' . $folderName;
40
41 264
        $wasCreationSuccessful = mkdir($folderPath, 0777, true);
42 264
        if (!$wasCreationSuccessful) {
43
            throw new IOException("Unable to create folder: $folderPath");
44
        }
45
46 264
        return $folderPath;
47
    }
48
49
    /**
50
     * Creates a file with the given name and content in the given folder.
51
     * The parent folder must exist.
52
     *
53
     * @param string $parentFolderPath The parent folder path where the file is going to be created
54
     * @param string $fileName The name of the file to create
55
     * @param string $fileContents The contents of the file to create
56
     * @return string Path of the created file
57
     * @throws \Box\Spout\Common\Exception\IOException If unable to create the file or if the file path is not inside of the base folder
58
     */
59 243
    public function createFileWithContents($parentFolderPath, $fileName, $fileContents)
60
    {
61 243
        $this->throwIfOperationNotInBaseFolder($parentFolderPath);
62
63 240
        $filePath = $parentFolderPath . '/' . $fileName;
64
65 240
        $wasCreationSuccessful = file_put_contents($filePath, $fileContents);
66 240
        if ($wasCreationSuccessful === false) {
67
            throw new IOException("Unable to create file: $filePath");
68
        }
69
70 240
        return $filePath;
71
    }
72
73
    /**
74
     * Delete the file at the given path
75
     *
76
     * @param string $filePath Path of the file to delete
77
     * @return void
78
     * @throws \Box\Spout\Common\Exception\IOException If the file path is not inside of the base folder
79
     */
80 186
    public function deleteFile($filePath)
81
    {
82 186
        $this->throwIfOperationNotInBaseFolder($filePath);
83
84 183
        if (file_exists($filePath) && is_file($filePath)) {
85 183
            unlink($filePath);
86 183
        }
87 183
    }
88
89
    /**
90
     * Delete the folder at the given path as well as all its contents
91
     *
92
     * @param string $folderPath Path of the folder to delete
93
     * @return void
94
     * @throws \Box\Spout\Common\Exception\IOException If the folder path is not inside of the base folder
95
     */
96 210
    public function deleteFolderRecursively($folderPath)
97
    {
98 210
        $this->throwIfOperationNotInBaseFolder($folderPath);
99
100 207
        $itemIterator = new \RecursiveIteratorIterator(
101 207
            new \RecursiveDirectoryIterator($folderPath, \RecursiveDirectoryIterator::SKIP_DOTS),
102
            \RecursiveIteratorIterator::CHILD_FIRST
103 207
        );
104
105 207
        foreach ($itemIterator as $item) {
106 189
            if ($item->isDir()) {
107 183
                rmdir($item->getPathname());
108 183
            } else {
109 189
                unlink($item->getPathname());
110
            }
111 207
        }
112
113 207
        rmdir($folderPath);
114 207
    }
115
116
    /**
117
     * All I/O operations must occur inside the base folder, for security reasons.
118
     * This function will throw an exception if the folder where the I/O operation
119
     * should occur is not inside the base folder.
120
     *
121
     * @param string $operationFolderPath The path of the folder where the I/O operation should occur
122
     * @return void
123
     * @throws \Box\Spout\Common\Exception\IOException If the folder where the I/O operation should occur is not inside the base folder
124
     */
125 276
    protected function throwIfOperationNotInBaseFolder($operationFolderPath)
126
    {
127 276
        $operationFolderRealPath = realpath($operationFolderPath);
128 276
        $isInBaseFolder = (strpos($operationFolderRealPath, $this->baseFolderRealPath) === 0);
129 276
        if (!$isInBaseFolder) {
130 12
            throw new IOException("Cannot perform I/O operation outside of the base folder: {$this->baseFolderRealPath}");
131
        }
132 264
    }
133
}
134