1 <?php
2
3 /* --------------------------------------------------------------
4 AbstractFileStorage.inc.php 2016-02-15
5 Gambio GmbH
6 http://www.gambio.de
7 Copyright (c) 2016 Gambio GmbH
8 Released under the GNU General Public License (Version 2)
9 [http://www.gnu.org/licenses/gpl-2.0.html]
10 --------------------------------------------------------------
11 */
12
13 /**
14 * Class AbstractFileStorage
15 *
16 *
17 * @category System
18 * @package Shared
19 * @subpackage Storage
20 */
21 abstract class AbstractFileStorage
22 {
23 /**
24 * Storage Directory.
25 *
26 * @var \WritableDirectory
27 */
28 protected $storageDirectory;
29
30
31 /**
32 * AbstractFileStorage constructor.
33 *
34 * @param \WritableDirectory $storageDirectory
35 */
36 public function __construct(WritableDirectory $storageDirectory)
37 {
38 $this->storageDirectory = $storageDirectory;
39 }
40
41
42 /**
43 * Import File.
44 *
45 * Saves an image to a writable directory.
46 *
47 * @param \ExistingFile $sourceFile The source file to import.
48 * @param \FilenameStringType $preferredFilename The preferred name of the file to be saved.
49 *
50 * @throws \InvalidArgumentException
51 *
52 * @return string The created filename
53 */
54 public function importFile(ExistingFile $sourceFile, FilenameStringType $preferredFilename)
55 {
56 $this->_validateFile($sourceFile);
57 $uniqueFilename = $preferredFilename;
58
59 if($this->fileExists($preferredFilename))
60 {
61 $uniqueFilename = new FilenameStringType($this->_createAndReturnNewFilename($preferredFilename));
62 }
63
64 copy($sourceFile->getFilePath(),
65 $this->storageDirectory->getDirPath() . DIRECTORY_SEPARATOR . $uniqueFilename->asString());
66
67 return $uniqueFilename->asString();
68 }
69
70
71 /**
72 * Rename File
73 *
74 * Renames an existing image file.
75 *
76 * @param FilenameStringType $oldName The old name of the file.
77 * @param FilenameStringType $newName The new name of the file.
78 *
79 * @throws InvalidArgumentException If the file that should be renamed does not exists.
80 * @throws InvalidArgumentException If a file with the preferred name already exists.
81 *
82 * @return AbstractFileStorage Same instance for chained method calls.
83 */
84 public function renameFile(FilenameStringType $oldName, FilenameStringType $newName)
85 {
86 if(!$this->fileExists($oldName))
87 {
88 throw new InvalidArgumentException($oldName->asString() . ' does not exist in '
89 . $this->storageDirectory->getDirPath());
90 }
91
92 if($this->fileExists($newName))
93 {
94 throw new InvalidArgumentException($newName->asString() . ' already exists in '
95 . $this->storageDirectory->getDirPath());
96 }
97
98 rename($this->storageDirectory->getDirPath() . DIRECTORY_SEPARATOR . $oldName->asString(),
99 $this->storageDirectory->getDirPath() . DIRECTORY_SEPARATOR . $newName->asString());
100
101 return $this;
102 }
103
104
105 /**
106 * File Exists.
107 *
108 * Checks if the provided file exists.
109 *
110 * @param \FilenameStringType $filename The filename of the file to be checked.
111 *
112 * @return bool
113 */
114 public function fileExists(FilenameStringType $filename)
115 {
116 $filepath = $this->storageDirectory->getDirPath() . DIRECTORY_SEPARATOR . $filename->asString();
117
118 return file_exists($filepath) && !is_dir($filepath);
119 }
120
121
122 /**
123 * Delete File.
124 *
125 * Deletes an existing file.
126 *
127 * @param \FilenameStringType $filename The file to delete.
128 *
129 * @return AbstractFileStorage Same instance for chained method calls.
130 */
131 public function deleteFile(FilenameStringType $filename)
132 {
133 if($this->fileExists($filename))
134 {
135 unlink($this->storageDirectory->getDirPath() . DIRECTORY_SEPARATOR . $filename->asString());
136 }
137
138 return $this;
139 }
140
141
142 /**
143 * Validates the provided file.
144 *
145 * @param \ExistingFile $sourceFile The file to validate.
146 *
147 * @throws \InvalidArgumentException
148 *
149 * @return AbstractFileStorage Same instance for chained method calls.
150 */
151 abstract protected function _validateFile(ExistingFile $sourceFile);
152
153
154 /**
155 * Create and Return the New Filename
156 *
157 * Checks whether the provided preferred filename already exists and generates one,
158 * with appending the next available number, which does not already exist.
159 *
160 * @param \FilenameStringType $existingFilename The existing filename to change.
161 *
162 * @throws \InvalidArgumentException
163 *
164 * @return string The created filename
165 */
166 protected function _createAndReturnNewFilename(FilenameStringType $existingFilename)
167 {
168 $nextAvailableNumber = 0;
169
170 do
171 {
172 $extensionPosition = strrpos($existingFilename->asString(), '.');
173 $filenameWithoutExtension = substr($existingFilename->asString(), 0, $extensionPosition);
174 $filenameExtensionInclDot = substr($existingFilename->asString(), $extensionPosition);
175 $newFilename = $filenameWithoutExtension . '_' . $nextAvailableNumber
176 . $filenameExtensionInclDot;
177
178 $newFilenameObject = new FilenameStringType($newFilename);
179
180 $nextAvailableNumber++;
181 }
182 while($this->fileExists($newFilenameObject));
183
184 return $newFilenameObject->asString();
185 }
186 }
187