1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265
<?php
/**
***********************************************************************************************
* Klasse zum vereinfachten Umgang mit Dateiordnern
*
* @copyright 2004-2016 The Admidio Team
* @see http://www.admidio.org/
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License v2.0 only
***********************************************************************************************
*/
/**
* @class Folder
* Mit dieser Klasse koennen Ordner leichter verwaltet werden. Das rekursive Verschieben,
* Kopieren, Loeschen uvw. wird unterstuetzt.
*
* The following functions are available:
*
* setFolder($folderWithPath = '') - Ordner mit zugehoerigem Pfad setzen
* getFolder() - Ordner zurueckgeben
* createFolder($newFolder, $writeable) - den Ordner ggf. mit Schreibrechten erstellen
* copy($destinationFolder, $sourceFolder = '')
* - kopiert den kompletten Ordner mit allen Unterordnern und
* Dateien in einen neuen Pfad
* delete($folder = '') - der Ordner wird mit allen Unterordnern / Dateien geloescht
* move($destinationFolder, $sourceFolder = '')
* - verschiebt den kompletten Ordner mit allen Unterordnern
* und Dateien in einen neuen Pfad
*/
class Folder
{
protected $folderWithPath;
/**
* @param string $folderWithPath
*/
public function __construct($folderWithPath = '')
{
$this->folderWithPath = '';
if($folderWithPath !== '' && is_dir($folderWithPath))
{
$this->folderWithPath = $folderWithPath;
}
}
/**
* Ordner mit zugehoerigem Pfad setzen
* @param string $folderWithPath
* @return bool Returns true if given folder is an existing folder
*/
public function setFolder($folderWithPath = '')
{
if($folderWithPath !== '' && is_dir($folderWithPath))
{
$this->folderWithPath = $folderWithPath;
return true;
}
return false;
}
/**
* Ordner zurueckgeben
* @return string
*/
public function getFolder()
{
return $this->folderWithPath;
}
/**
* den Ordner der Klasse mit Schreibrechten erstellen
*
* [1] (!@mkdir($dirPath, 0777) && !is_dir($dirPath))
* This issue is difficult to reproduce, as any of concurrency-related issues. Appears when several
* processes attempting to create a directory which is not yet existing, but between is_dir() and mkdir()
* calls another process already managed to create a directory.
* @param string $newFolder
* @param bool $writable
* @return bool
*/
public function createFolder($newFolder, $writable)
{
$newPath = $this->folderWithPath.'/'.$newFolder;
$returnValue = true;
// existiert der Ordner noch nicht, dann diesen anlegen
if(!is_dir($newPath))
{
if($writable)
{
$returnValue = !(!@mkdir($newPath, 0777) && !is_dir($newPath)); // [1] // do NOT simplify to (@mkdir($path, 0777) || is_dir($path))
}
else
{
$returnValue = !(!@mkdir($newPath) && !is_dir($newPath)); // [1] // do NOT simplify to (@mkdir($path) || is_dir($path))
}
}
// der Ordner existiert, aber die Schreibrechte noch nicht
if($writable && is_dir($newPath) && !is_writable($newPath))
{
$returnValue = @chmod($newPath, 0777);
}
return $returnValue;
}
/**
* kopiert den kompletten Ordner mit allen Unterordnern und Dateien in einen neuen Pfad
* destinationFolder : das neue Zielverzeichnis
* sourceFolder : der zu kopierende Ordner, falls nicht gefuellt wird der Ordner aus der Klasse genommen
* @param string $destinationFolder
* @param string $sourceFolder
* @return bool
*/
public function copy($destinationFolder, $sourceFolder = '')
{
if($sourceFolder === '')
{
$sourceFolder = $this->folderWithPath;
}
if (!is_dir($sourceFolder))
{
return false;
}
// erst einmal vom Zielpfad den letzten Ordner absplitten, damit dieser angelegt werden kann
$newPath = substr($destinationFolder, 0, strrpos($destinationFolder, '/'));
$newFolder = substr($destinationFolder, strrpos($destinationFolder, '/') + 1);
// nun erst einmal den Zielordner erstellen
$this->setFolder($newPath);
if(!$this->createFolder($newFolder, true))
{
return false;
}
$dirHandle = @opendir($sourceFolder);
if($dirHandle)
{
while (($entry = readdir($dirHandle)) !== false)
{
if($entry === '.' || $entry === '..')
{
continue;
}
$currentFolderEntry = $sourceFolder.'/'.$entry;
$destinationEntry = $destinationFolder.'/'.$entry;
if(is_dir($currentFolderEntry))
{
// copy the content of the folder
$this->copy($destinationEntry, $currentFolderEntry);
}
if(is_file($currentFolderEntry))
{
// copy the file
if(!copy($currentFolderEntry, $destinationEntry))
{
return false;
}
}
}
closedir($dirHandle);
}
return true;
}
/**
* Deletes the current folder recursive with all files and subfolders.
* @param string $folder Name of a folder that should be deleted. Default is always the current folder
* @param bool $onlyDeleteContent If set to @b true then only files and folders in the current
* folder will be deleted. The current folder will not be deleted.
* @return bool
*/
public function delete($folder = '', $onlyDeleteContent = false)
{
if($folder === '')
{
$folder = $this->folderWithPath;
}
if (!is_dir($folder))
{
return false;
}
$dirHandle = @opendir($folder);
if($dirHandle)
{
while (($entry = readdir($dirHandle)) !== false)
{
if($entry === '.' || $entry === '..')
{
continue;
}
$currentFolderEntry = $folder.'/'.$entry;
if(is_dir($currentFolderEntry))
{
// deletes the content of the folder
$this->delete($currentFolderEntry, false);
}
if(is_file($currentFolderEntry))
{
// deletes the file
if(!@unlink($currentFolderEntry))
{
return false;
}
}
}
closedir($dirHandle);
}
if(!$onlyDeleteContent)
{
// now delete current folder
if(!@rmdir($folder))
{
return false;
}
}
return true;
}
/**
* verschiebt den kompletten Ordner mit allen Unterordnern und Dateien in einen neuen Pfad
* @param string $destFolder das neue Zielverzeichnis
* @param string $sourceFolder der zu verschiebende Ordner, falls nicht gefuellt wird der Ordner aus der Klasse genommen
* @return bool Returns true if the move works successfully
*/
public function move($destFolder, $sourceFolder = '')
{
if($sourceFolder === '')
{
$sourceFolder = $this->folderWithPath;
}
// First copy the full source folder to destination
if($this->copy($destFolder, $sourceFolder))
{
// If copy was successful delete source folder
return $this->delete($sourceFolder);
}
return false;
}
/**
* Attempts to rename oldname to newname, moving it between directories if necessary.
* If newname exists, it will be overwritten.
* @param string $newName The new name of the folder.
* @return bool Returns @b true on success or @b false on failure.
*/
public function rename($newName)
{
return rename($this->folderWithPath, $newName);
}
}