This method is similar to PHP's dirname(), but handles various cases
where dirname() returns a weird result:
- dirname() does not accept backslashes on UNIX
- dirname("C:/webmozart") returns "C:", not "C:/"
- dirname("C:/") returns ".", not "C:/"
- dirname("C:") returns ".", not "C:/"
- dirname("webmozart") returns ".", not ""
- dirname() does not canonicalize the result
This method fixes these shortcomings and behaves like dirname()
otherwise.
The result is a canonical path.
public static getDirectory ( string $path ) : string | ||
$path | string | A path string. |
return | string | The canonical directory part. Returns the root directory if the root directory is passed. Returns an empty string if a relative path is passed that contains no slashes. Returns an empty string if an empty string is passed. |
/** * {@inheritdoc} */ public function write($path, $contents) { Assert::notEmpty($path, 'Cannot write to an empty path.'); if (is_dir($path)) { throw new StorageException(sprintf('Cannot write %s: Is a directory.', $path)); } if (!is_dir($dir = Path::getDirectory($path))) { $filesystem = new Filesystem(); $filesystem->mkdir($dir); } if (false === ($numBytes = @file_put_contents($path, $contents))) { $error = error_get_last(); throw new StorageException(sprintf('Could not write %s: %s.', $path, $error['message'])); } return $numBytes; }
/** * Called after child nodes are visited. * * @param Twig_Node $node The node to visit * @param Twig_Environment $env The Twig environment instance * * @return Twig_Node|false The modified node or false if the node must be removed */ protected function doLeaveNode(Twig_Node $node, Twig_Environment $env) { // Tag the node if it contains a LoadedByPuliNode // This cannot be done in enterNode(), because only leaveNode() may // return false in order to remove a node if ($node instanceof LoadedByPuliNode) { if (null !== $this->moduleNode) { $this->moduleNode->setAttribute('puli-dir', Path::getDirectory($this->moduleNode->getAttribute('filename'))); } // Remove that node from the final tree return false; } // Special case: Empty files that contained only the LoadedByPuliNode // now contain no nodes anymore. Twig, however, expects Twig_Node_Body // instances to have at least one (even if empty) node with name 0. if ($node instanceof Twig_Node_Body) { if (0 === $node->count()) { $node->setNode(0, new Twig_Node(array(), array(), 1)); } } return $node; }
private function encodeFile($jsonData, $path) { if (!is_string($path) || !Path::isAbsolute($path)) { throw new IOException(sprintf('Cannot write "%s": Expected an absolute path.', $path)); } if (is_dir($path)) { throw new IOException(sprintf('Cannot write %s: Is a directory.', $path)); } $encoder = new JsonEncoder(); $encoder->setPrettyPrinting(true); $encoder->setEscapeSlash(false); $encoder->setTerminateWithLineFeed(true); $decoder = new JsonDecoder(); // We can't use realpath(), which doesn't work inside PHARs. // However, we want to display nice paths if the file is not found. $schema = $decoder->decodeFile(Path::canonicalize(__DIR__ . '/../../res/schema/package-schema-1.0.json')); $configSchema = $schema->properties->config; if (!is_dir($dir = Path::getDirectory($path))) { $filesystem = new Filesystem(); $filesystem->mkdir($dir); } $encoder->encodeFile($jsonData, $path, $configSchema); }
/** * Filters an asset just before it's dumped. * * @param AssetInterface $asset An asset */ public function filterDump(AssetInterface $asset) { if (!$asset instanceof PuliAsset) { return; } $pathMap = array(); // Get a map of repository paths to target paths // e.g. "/webmozart/puli/images/bg.png" => "/images/bg.png" foreach ($this->am->getNames() as $name) { $this->extractTargetPaths($this->am->get($name), $pathMap); } // Remember the repository dir of the current resource $repoPath = $asset->getSourcePath(); $repoDir = Path::getDirectory($repoPath); // Get the target directory of the current resource // e.g. "css" $targetPath = $asset->getTargetPath(); $targetDir = Path::getDirectory($targetPath); // Convert to an absolute path so that we can create a proper // relative path later on // e.g. "/css" if (!Path::isAbsolute($targetDir)) { $targetDir = '/' . $targetDir; } $content = CssUtils::filterReferences($asset->getContent(), function ($matches) use($pathMap, $repoDir, $repoPath, $targetDir, $targetPath) { // The referenced path is a repository path // e.g. "/webmozart/puli/images/bg.png" $referencedPath = $matches['url']; // Ignore empty URLs if ('' === $referencedPath) { return $matches[0]; } // Ignore non-local paths if (!Path::isLocal($referencedPath)) { return $matches[0]; } // Ignore "data:" URLs if (0 === strpos($referencedPath, 'data:')) { return $matches[0]; } // If the referenced path is not absolute, resolve it relative to // the directory of the source file if (!Path::isAbsolute($referencedPath)) { $referencedPath = Path::makeAbsolute($referencedPath, $repoDir); } // The referenced asset must be known if (!array_key_exists($referencedPath, $pathMap)) { throw new AssetException(sprintf('The asset "%s" referenced in "%s" could not be found.', $referencedPath, $repoPath)); } // The target path of the referenced file must be set if (!$pathMap[$referencedPath]) { throw new AssetException(sprintf('The referenced path "%s" in "%s" cannot be resolved, because ' . 'the target path of "%s" is not set.', $matches['url'], $repoPath, $matches['url'])); } // The target path of the source file must be set if (!$targetPath) { throw new AssetException(sprintf('The referenced path "%s" in "%s" cannot be resolved, because ' . 'the target path of "%s" is not set.', $matches['url'], $repoPath, $repoPath)); } // Get the relative path from the source directory to the reference // e.g. "/css/style.css" + "/images/bg.png" = "../images/bg.png" $relativePath = Path::makeRelative($pathMap[$referencedPath], $targetDir); return str_replace($matches['url'], $relativePath, $matches[0]); }); $asset->setContent($content); }
/** * @expectedException \InvalidArgumentException * @expectedExceptionMessage The path must be a string. Got: array */ public function testGetDirectoryFailsIfInvalidPath() { Path::getDirectory(array()); }
/** * Recursively creates a directory for a path. * * @param string $path A directory path. */ private function ensureDirectoryExists($path) { if (!isset($this->resources[$path])) { // Recursively initialize parent directories if ($path !== '/') { $this->ensureDirectoryExists(Path::getDirectory($path)); } $this->resources[$path] = new GenericResource($path); $this->resources[$path]->attachTo($this); return; } }
/** * Return autocomplete data for a file name. * * @param Request $request * * @return \Symfony\Component\HttpFoundation\JsonResponse */ public function filesAutoComplete(Request $request) { $term = $request->query->get('term', '.*'); $dir = Path::getDirectory($term); $term = Path::getFilename($term); $term = preg_quote($term); $extensions = implode('|', explode(',', $request->query->get('ext', '.*'))); $regex = sprintf('/.*(%s).*\\.(%s)$/', $term, $extensions); $files = $this->filesystem()->find()->in('files://' . $dir)->name($regex); $result = []; /** @var \Bolt\Filesystem\Handler\File $file */ foreach ($files as $file) { $result[] = $file->toJs(); } return $this->json($result); }
/** * Adds all ancestor directories of a path to the repository. * * @param string $path A Puli path. */ private function ensureDirectoryExists($path) { if (array_key_exists($path, $this->json)) { return; } // Recursively initialize parent directories if ('/' !== $path) { $this->ensureDirectoryExists(Path::getDirectory($path)); } $this->json[$path] = null; }
/** * Sets the absolute file path of the factory class file. * * @param string $filePath The absolute file path. * * @return static The current instance. */ public function setFilePath($filePath) { Assert::stringNotEmpty($filePath, 'The factory file path must be a non-empty string. Got: %s'); $this->setDirectory(Path::getDirectory($filePath)); $this->setFileName(Path::getFilename($filePath)); return $this; }
/** * Initializes the order of a path with the default order. * * This is necessary if we want to insert a non-default order entry for * the first time. * * @param string $path The path to initialize. * @param string $insertedPath The path that is being inserted. * @param array $references The references for each defined path mapping * in the path chain. */ private function initWithDefaultOrder($path, $insertedPath, $references) { $this->json['_order'][$path] = array(); // Insert the default order, if none exists // i.e. long paths /a/b/c before short paths /a/b $parentPath = $path; while (true) { if (isset($references[$parentPath])) { $parentEntry = array('path' => $parentPath, 'references' => count($references[$parentPath])); // Edge case: $parentPath equals $insertedPath. In this case we have // to subtract the entry that we're adding if ($parentPath === $insertedPath) { --$parentEntry['references']; } if (0 !== $parentEntry['references']) { $this->json['_order'][$path][] = $parentEntry; } } if ('/' === $parentPath) { break; } $parentPath = Path::getDirectory($parentPath); } }
private function replaceLinkByCopy($path, array $dirsToKeep = array()) { $target = Path::makeAbsolute($this->readLink($path), Path::getDirectory($path)); $this->filesystem->remove($path); $this->filesystem->mkdir($path); $this->symlinkMirror($target, $path, $dirsToKeep); }
public function getRelativePath($conf_path, $sugar_path) { $conf_path = Path::getDirectory($conf_path); return Utils::makeConfigPathRelative($conf_path, $sugar_path); }