Dot segments ("." and "..") are removed/collapsed and all slashes turned
into forward slashes.
php
Path::isBasePath('/webmozart', '/webmozart/css');
=> true
Path::isBasePath('/webmozart', '/webmozart');
=> true
Path::isBasePath('/webmozart', '/webmozart/..');
=> false
Path::isBasePath('/webmozart', '/puli');
=> false
protected static function configureDir(Event $event, $name, $defaultInSkeleton, $prefix = '', $chmod = true) { $default = static::getOption($event, $name . '-dir', $defaultInSkeleton); $validator = function ($value) use($prefix, $name) { if ($prefix) { $basePath = Path::makeAbsolute($prefix, getcwd()); $path = Path::makeAbsolute($value, $basePath); if (!Path::isBasePath($basePath, $path)) { throw new \RuntimeException("The {$name} directory must be inside the {$prefix} directory."); } } return Path::canonicalize($value); }; $default = $validator($default); $relative = $prefix ? '<comment>' . $prefix . '</comment>' : 'project root'; $question = sprintf('<info>Where do you want your <comment>%s</comment> directory? (relative to %s) [default: <comment>%s</comment>] </info>', $name, $relative, $default); $dir = $event->getIO()->askAndValidate($question, $validator, null, $default); $fs = new Filesystem(); $origin = $prefix . $defaultInSkeleton; $target = $prefix . $dir; $dirMode = static::configureDirMode($event); if ($dir !== $defaultInSkeleton) { $event->getIO()->writeError(sprintf('Moving <info>%s</info> directory from <info>%s</info> to <info>%s</info>', $name, $origin, $target)); $fs->mkdir(dirname($target)); // ensure parent directory exists $fs->rename($origin, $target); } if ($chmod) { $it = (new Finder())->directories()->in($target)->append([$target]); $fs->chmod($it, $dirMode); } return $target; }
/** * Splits a path into mount point and path. * * @param string $path The path to split. * * @return array An array with the mount point and the path. If no mount * point was found, both are `null`. */ private function splitPath($path) { Assert::stringNotEmpty($path, 'The path must be a non-empty string. Got: %s'); Assert::startsWith($path, '/', 'The path %s is not absolute.'); $path = Path::canonicalize($path); foreach ($this->repos as $mountPoint => $_) { if (Path::isBasePath($mountPoint, $path)) { // Special case "/": return the complete path if ('/' === $mountPoint) { return array($mountPoint, $path); } return array($mountPoint, substr($path, strlen($mountPoint))); } } return array(null, null); }
/** * @expectedException \InvalidArgumentException * @expectedExceptionMessage The path must be a string. Got: array */ public function testIsBasePathFailsIfInvalidPath() { Path::isBasePath('/base/path', array()); }
/** * @param PackageConflict[] $packageConflicts */ private function deduplicatePackageConflicts(array &$packageConflicts) { $indicesByPath = array(); $indicesToRemove = array(); foreach ($packageConflicts as $index => $packageConflict) { $indicesByPath[$packageConflict->getConflictingToken()] = $index; } foreach ($indicesByPath as $repositoryPath => $index) { foreach ($indicesByPath as $otherPath => $otherIndex) { if ($otherPath !== $repositoryPath && Path::isBasePath($otherPath, $repositoryPath)) { $indicesToRemove[$index] = true; } } } foreach ($indicesToRemove as $index => $true) { unset($packageConflicts[$index]); } // Reorganize indices $packageConflicts = array_values($packageConflicts); }
/** * Adds a conflict to the mapping. * * A mapping can refer to at most one conflict per conflicting repository * path. If the same conflict is added twice, the second addition is * ignored. If a different conflict is added for an existing repository * path, the previous conflict is removed before adding the new conflict * for the repository path. * * The repository path of the conflict must either be the repository path * of the mapping or any path within. If a conflict with a different path * is added, an exception is thrown. * * The method {@link load()} needs to be called before calling this method, * otherwise an exception is thrown. * * @param PathConflict $conflict The conflict to be added. * * @throws NotLoadedException If the mapping is not loaded. * @throws InvalidArgumentException If the path of the conflict is not * within the repository path of the * mapping. */ public function addConflict(PathConflict $conflict) { if (null === $this->state) { throw new NotLoadedException('The mapping is not loaded.'); } if (!Path::isBasePath($this->repositoryPath, $conflict->getRepositoryPath())) { throw new InvalidArgumentException(sprintf('The conflicting path %s is not within the path %s of the ' . 'mapping.', $conflict->getRepositoryPath(), $this->repositoryPath)); } $repositoryPath = $conflict->getRepositoryPath(); $previousConflict = isset($this->conflicts[$repositoryPath]) ? $this->conflicts[$repositoryPath] : null; if ($previousConflict === $conflict) { return; } if ($previousConflict) { $previousConflict->removeMapping($this); } $this->conflicts[$repositoryPath] = $conflict; $conflict->addMapping($this); $this->refreshState(); }
/** * @param string $repositoryPath * @param PathMapping[][] $uncheckedMappings * @param string[][] $filesystemPaths * @param string[][] $filesystemPaths */ private function collectEnabledFilesystemPaths($repositoryPath, array &$uncheckedMappings, array &$filesystemPaths = null, array &$processedPaths = null) { if (null === $filesystemPaths) { $filesystemPaths = array(); $processedPaths = array(); } // We had this one before if (isset($processedPaths[$repositoryPath])) { return; } $processedPaths[$repositoryPath] = true; foreach ($uncheckedMappings as $mappedPath => $mappingsByPackage) { // Check mappings for the passed repository path or any of its // nested paths if ($repositoryPath !== $mappedPath && !Path::isBasePath($repositoryPath, $mappedPath)) { continue; } foreach ($mappingsByPackage as $packageName => $mapping) { // Don't check the mapping again for this repository path unset($uncheckedMappings[$mappedPath][$packageName]); // The path of the mapping is not necessarily the current repository // path. The paths are different when checking the nested paths of // a mapping. $mappingPath = $mapping->getRepositoryPath(); // We added the mapping before or it is not enabled if (isset($filesystemPaths[$packageName][$mappingPath]) || !$mapping->isEnabled()) { continue; } if (!isset($filesystemPaths[$packageName])) { $filesystemPaths[$packageName] = array(); } $filesystemPaths[$packageName][$mappingPath] = $mapping->getFilesystemPaths(); // Check all nested paths of the mapping for other mappings that // map to the same paths foreach ($mapping->listRepositoryPaths() as $nestedRepositoryPath) { // Don't repeat the call for the current path if ($nestedRepositoryPath !== $mappedPath) { $this->collectEnabledFilesystemPaths($nestedRepositoryPath, $uncheckedMappings, $filesystemPaths, $processedPaths); } } } } }
/** * @param string $repositoryPath * @param PathMapping[][] $inMappings * @param PathMapping[][] $outMappings * @param bool[] $processedPaths */ private function filterEnabledMappings($repositoryPath, array &$inMappings, array &$outMappings, array &$processedPaths = array()) { $repositoryPaths = array(); $processedPaths[$repositoryPath] = true; foreach ($inMappings as $mappingPath => $mappingsByPackage) { foreach ($mappingsByPackage as $packageName => $mapping) { if (!$mapping->isEnabled()) { continue; } $nestedMappingPaths = $mapping->listRepositoryPaths(); // Check that the mapping actually contains the path if (!Path::isBasePath($repositoryPath, $mappingPath) && !in_array($repositoryPath, $nestedMappingPaths, true)) { continue; } // Don't check this mapping anymore in recursive calls unset($inMappings[$mappingPath][$packageName]); if (empty($inMappings[$mappingPath])) { unset($inMappings[$mappingPath]); } // Add mapping to output $outMappings[$mappingPath][$packageName] = $mapping; foreach ($nestedMappingPaths as $nestedMappingPath) { $repositoryPaths[$nestedMappingPath] = true; } } } // Continue to search for mappings for the repository paths we collected // already until there are no more mappings if (!empty($inMappings)) { foreach ($repositoryPaths as $nestedMappingPath => $true) { // Don't process paths twice if (!isset($processedPaths[$nestedMappingPath])) { $this->filterEnabledMappings($nestedMappingPath, $inMappings, $outMappings, $processedPaths); } } } }
/** * Returns true if path is located under basepath * @param string $path * @param string $basepath * @return bool */ public static function isBasePath($path, $basepath = '/') { return Path::isBasePath($basepath, $path); }
private function parseAbsoluteInput($input, array $roots, array $vars, array $values) { // If $input is an absolute file path with one of the given roots, // return a file asset foreach ($roots as $root) { if (Path::isBasePath($root, $input)) { $relative = Path::makeRelative($input, $root); $asset = $this->createFileAsset($input, $root, $relative, $vars); $asset->setValues($values); return $asset; } } $inputWithoutVars = VarUtils::resolve($input, $vars, $values); // If $input is an absolute file path with none of the given roots, // return a file asset with its root set to null if (is_file($inputWithoutVars)) { $asset = $this->createFileAsset($input, null, $input, $vars); $asset->setValues($values); return $asset; } // Otherwise assume to have an absolute Puli path if ($this->repo->contains($inputWithoutVars)) { $asset = $this->createPuliAsset($input, $vars); $asset->setValues($values); return $asset; } throw new RuntimeException(sprintf('The asset "%s" could not be found.', $inputWithoutVars)); }
private function createResource($filesystemPath, $path) { $resource = null; if (is_link($filesystemPath)) { $baseDir = rtrim($this->baseDir, '/'); $targetFilesystemPath = $this->readLink($filesystemPath); if (Path::isBasePath($baseDir, $targetFilesystemPath)) { $targetPath = '/' . Path::makeRelative($targetFilesystemPath, $baseDir); $resource = new LinkResource($targetPath); } } if (!$resource && is_dir($filesystemPath)) { $resource = new DirectoryResource($filesystemPath); } if (!$resource) { $resource = new FileResource($filesystemPath); } $resource->attachTo($this, $path); return $resource; }
/** * {@inheritdoc} */ public function getUrl($rootDir, $prefix = '') { if (!Path::isBasePath($rootDir, $this->path)) { throw new \InvalidArgumentException(sprintf('Path "%s" is not inside root directory "%s"', $this->path, $rootDir)); } $url = Path::makeRelative($this->path, $rootDir); $url = str_replace('%2F', '/', rawurlencode($url)); return $prefix . $url; }
/** * Returns whether a resource path matches a query. * * @param string $resourcePath The resource path. * @param string $query The resource query of a binding. * * @return bool Returns `true` if the resource path matches the query. */ protected function resourcePathMatchesQuery($resourcePath, $query) { if (false !== strpos($query, '*')) { return Glob::match($resourcePath, $query); } return $query === $resourcePath || Path::isBasePath($query, $resourcePath); }