1<?php 2 3 4namespace ComboStrap; 5 6 7use renderer_plugin_combo_analytics; 8 9class FileSystems 10{ 11 12 public const CONTAINER = "container"; 13 public const LEAF = "leaf"; 14 15 static function exists(Path $path): bool 16 { 17 $scheme = $path->getScheme(); 18 switch ($scheme) { 19 case LocalFileSystem::SCHEME: 20 return LocalFileSystem::getOrCreate()->exists($path); 21 case WikiFileSystem::SCHEME: 22 return WikiFileSystem::getOrCreate()->exists($path); 23 case MarkupFileSystem::SCHEME: 24 return MarkupFileSystem::getOrCreate()->exists($path); 25 default: 26 throw new ExceptionRuntime("File system ($scheme) unknown"); 27 } 28 } 29 30 /** 31 * @throws ExceptionNotFound - if the file does not exists or the mime is unknown 32 */ 33 public static function getContent(Path $path): string 34 { 35 $scheme = $path->getScheme(); 36 switch ($scheme) { 37 case LocalFileSystem::SCHEME: 38 return LocalFileSystem::getOrCreate()->getContent($path); 39 case WikiFileSystem::SCHEME: 40 return WikiFileSystem::getOrCreate()->getContent($path); 41 } 42 throw new ExceptionRuntime("File system ($scheme) unknown"); 43 } 44 45 /** 46 * @throws ExceptionNotFound - if the file does not exist 47 */ 48 public static function getModifiedTime(Path $path): \DateTime 49 { 50 $scheme = $path->getScheme(); 51 switch ($scheme) { 52 case LocalFileSystem::SCHEME: 53 /** @noinspection PhpParamsInspection */ 54 return LocalFileSystem::getOrCreate()->getModifiedTime($path); 55 case WikiFileSystem::SCHEME: 56 return WikiFileSystem::getOrCreate()->getModifiedTime($path); 57 default: 58 throw new ExceptionRuntime("File system ($scheme) unknown"); 59 } 60 61 } 62 63 /** 64 * @throws ExceptionNotFound 65 */ 66 public static function getCreationTime(Path $path) 67 { 68 $scheme = $path->getScheme(); 69 switch ($scheme) { 70 case LocalFileSystem::SCHEME: 71 return LocalFileSystem::getOrCreate()->getCreationTime($path); 72 case WikiFileSystem::SCHEME: 73 return WikiFileSystem::getOrCreate()->getCreationTime($path); 74 default: 75 // Internal Error: should not happen 76 throw new ExceptionRuntime("File system ($scheme) unknown"); 77 } 78 } 79 80 public static function deleteIfExists(Path $path) 81 { 82 if (FileSystems::exists($path)) { 83 FileSystems::delete($path); 84 } 85 } 86 87 /** 88 * @throws ExceptionFileSystem 89 */ 90 public static function delete(Path $path) 91 { 92 $scheme = $path->getScheme(); 93 switch ($scheme) { 94 case LocalFileSystem::SCHEME: 95 LocalFileSystem::getOrCreate()->delete($path); 96 return; 97 case WikiFileSystem::SCHEME: 98 WikiFileSystem::getOrCreate()->delete($path); 99 return; 100 case MarkupFileSystem::SCHEME: 101 MarkupFileSystem::getOrCreate()->delete($path); 102 return; 103 default: 104 throw new ExceptionRuntime("File system ($scheme) unknown"); 105 } 106 } 107 108 public static function getSize(Path $path) 109 { 110 111 $scheme = $path->getScheme(); 112 switch ($scheme) { 113 case LocalFileSystem::SCHEME: 114 return LocalFileSystem::getOrCreate()->getSize($path); 115 case WikiFileSystem::SCHEME: 116 return WikiFileSystem::getOrCreate()->getSize($path); 117 default: 118 throw new ExceptionRuntime("File system ($scheme) unknown"); 119 } 120 } 121 122 123 /** 124 * @throws ExceptionCompile 125 */ 126 public static function createDirectory(Path $dirPath) 127 { 128 $scheme = $dirPath->getScheme(); 129 switch ($scheme) { 130 case LocalFileSystem::SCHEME: 131 return LocalFileSystem::getOrCreate()->createDirectory($dirPath); 132 case WikiFileSystem::SCHEME: 133 return WikiFileSystem::getOrCreate()->createDirectory($dirPath); 134 default: 135 throw new ExceptionRuntime("File system ($scheme) unknown"); 136 } 137 } 138 139 public static function isDirectory(Path $path): bool 140 { 141 $scheme = $path->getScheme(); 142 switch ($scheme) { 143 case LocalFileSystem::SCHEME: 144 return LocalFileSystem::getOrCreate()->isDirectory($path); 145 case WikiFileSystem::SCHEME: 146 return WikiFileSystem::getOrCreate()->isDirectory($path); 147 default: 148 throw new ExceptionRuntime("File system ($scheme) unknown"); 149 } 150 } 151 152 153 /** 154 * @return Path[] 155 */ 156 public static function getChildren(Path $path, string $type = null): array 157 { 158 $scheme = $path->getScheme(); 159 switch ($scheme) { 160 case LocalFileSystem::SCHEME: 161 return LocalFileSystem::getOrCreate()->getChildren($path, $type); 162 case WikiFileSystem::SCHEME: 163 return WikiFileSystem::getOrCreate()->getChildren($path, $type); 164 case MarkupFileSystem::SCHEME: 165 return MarkupFileSystem::getOrCreate()->getChildren($path, $type); 166 default: 167 throw new ExceptionRuntime("File system ($scheme) unknown"); 168 } 169 } 170 171 /** 172 * @param Path $namespacePath 173 * @return Path[] 174 */ 175 public static function getChildrenContainer(Path $namespacePath): array 176 { 177 return self::getChildren($namespacePath, FileSystems::CONTAINER); 178 } 179 180 /** 181 * @param Path $namespacePath 182 * @return Path[] 183 */ 184 public static function getChildrenLeaf(Path $namespacePath): array 185 { 186 try { 187 return self::getChildren($namespacePath, FileSystems::LEAF); 188 } catch (ExceptionBadArgument $e) { 189 // as we path the type, it should not happen 190 throw new ExceptionRuntime("Error getting the children. Error: {$e->getMessage()}"); 191 } 192 } 193 194 /** 195 * Return a cache buster 196 * @throws ExceptionNotFound 197 * Utility function to calculate a buster based on a path for the implementation of {@link FetchAbstract::getBuster()} 198 */ 199 public static function getCacheBuster(Path $path): string 200 { 201 $time = FileSystems::getModifiedTime($path); 202 return strval($time->getTimestamp()); 203 } 204 205 /** 206 * @throws ExceptionNotFound 207 */ 208 public static function closest(Path $path, string $name): Path 209 { 210 $scheme = $path->getScheme(); 211 switch ($scheme) { 212 case LocalFileSystem::SCHEME: 213 return LocalFileSystem::getOrCreate()->closest($path, $name); 214 case WikiFileSystem::SCHEME: 215 return WikiFileSystem::getOrCreate()->closest($path, $name); 216 default: 217 throw new ExceptionRuntime("File system ($scheme) unknown"); 218 } 219 } 220 221 public static function createRegularFile(Path $path) 222 { 223 $scheme = $path->getScheme(); 224 switch ($scheme) { 225 case LocalFileSystem::SCHEME: 226 LocalFileSystem::getOrCreate()->createRegularFile($path); 227 break; 228 case WikiFileSystem::SCHEME: 229 WikiFileSystem::getOrCreate()->createRegularFile($path); 230 break; 231 default: 232 throw new ExceptionRuntime("File system ($scheme) unknown"); 233 } 234 } 235 236 /** 237 * @throws ExceptionNotFound - if the mime is unknown and was not found 238 */ 239 public static function getMime(Path $path): Mime 240 { 241 $extension = $path->getExtension(); 242 try { 243 return Mime::createFromExtension($extension); 244 } catch (ExceptionNotFound $e) { 245 $mime = mimetype($path->getLastName(), true)[1]; 246 if ($mime === null || $mime === false) { 247 throw new ExceptionNotFound("No mime found for path ($path). The mime type of the media is <a href=\"https://www.dokuwiki.org/mime\">unknown (not in the configuration file)</a>"); 248 } 249 return new Mime($mime); 250 } 251 } 252 253 public static function setContent(Path $path, string $content) 254 { 255 $scheme = $path->getScheme(); 256 switch ($scheme) { 257 case LocalFileSystem::SCHEME: 258 LocalFileSystem::getOrCreate()->setContent($path, $content); 259 break; 260 case WikiFileSystem::SCHEME: 261 WikiFileSystem::getOrCreate()->setContent($path, $content); 262 break; 263 case MarkupFileSystem::SCHEME: 264 MarkupFileSystem::getOrCreate()->setContent($path, $content); 265 break; 266 default: 267 throw new ExceptionRuntime("File system ($scheme) unknown"); 268 } 269 } 270 271 /** 272 * @param Path[] $paths 273 * @return Path 274 * @throws ExceptionNotFound 275 */ 276 public static function getFirstExistingPath(array $paths): Path 277 { 278 279 foreach ($paths as $path) { 280 if (FileSystems::exists($path)) { 281 return $path; 282 } 283 } 284 throw new ExceptionNotFound("Existing file could be found"); 285 286 } 287 288 public static function getTree(Path $path): PathTreeNode 289 { 290 return PathTreeNode::buildTreeViaFileSystemChildren($path); 291 } 292 293 /** 294 * @throws ExceptionBadArgument - if they are not local path 295 */ 296 public static function copy(Path $source, Path $destination) 297 { 298 $sourceLocal = LocalPath::createFromPathObject($source); 299 $destinationLocal = LocalPath::createFromPathObject($destination); 300 copy($sourceLocal->toAbsoluteId(), $destinationLocal->toAbsoluteId()); 301 302 // D:\dokuwiki\lib\plugins\combo\_test\resources\bootstrapLocal.json 303 } 304 305 /** 306 * Debug 307 * @param Path $mediaFile 308 * @return void 309 * Unfortunately, due to php, the time may be not use 310 * at the second 311 * as for the same file, we may end up in the same 312 * process to two differents modified time. 313 * ie 314 * Fri, 10 Feb 2023 18:22:09 +0000 315 * Fri, 10 Feb 2023 18:22:30 +0000 316 */ 317 public static function printModificationTimeToConsole(Path $mediaFile, string $log) 318 { 319 fputs(STDOUT, "ModificationTime of {$mediaFile->toAbsoluteId()}" . PHP_EOL); 320 $filename = $mediaFile->toAbsolutePath()->toAbsoluteId(); 321 fputs(STDOUT, "ModificationTime of $filename at $log "); 322 $timestamp = filemtime($filename); 323 fputs(STDOUT, " $timestamp" . PHP_EOL); 324 } 325 326 public static function clearStatCache(Path $path) 327 { 328 try { 329 $pathString = $path->toLocalPath()->toCanonicalAbsolutePath()->toAbsoluteId(); 330 clearstatcache(true, $pathString); 331 } catch (ExceptionCast $e) { 332 throw new ExceptionRuntimeInternal("The cache can be clear only for local path"); 333 } 334 335 } 336 337 338 /** 339 * @throws ExceptionBadSyntax 340 * @throws ExceptionBadArgument 341 */ 342 public static function createPathFromUri($uri): Path 343 { 344 $firstColon = strpos($uri, ":"); 345 if ($firstColon === false) { 346 throw new ExceptionBadSyntax("$uri is not a valid uri"); 347 } 348 $scheme = substr($uri, 0, $firstColon); 349 switch ($scheme) { 350 case WikiFileSystem::SCHEME: 351 return WikiPath::createFromUri($uri); 352 case LocalFileSystem::SCHEME: 353 return LocalPath::createFromUri($uri); 354 default: 355 throw new ExceptionRuntimeInternal("The scheme ($scheme) is not yet supported"); 356 } 357 358 } 359 360 /** 361 * @throws ExceptionCompile 362 */ 363 public static function createDirectoryIfNotExists(Path $directoryPath) 364 { 365 if (!self::exists($directoryPath)){ 366 self::createDirectory($directoryPath); 367 } 368 } 369} 370