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