The relative path is created relative to the given base path:
php
echo Path::makeRelative("/webmozart/style.css", "/webmozart/puli");
=> ../style.css
If a relative path is passed and the base path is absolute, the relative
path is returned unchanged:
php
Path::makeRelative("style.css", "/webmozart/puli/css");
=> style.css
If both paths are relative, the relative path is created with the
assumption that both paths are relative to the same directory:
php
Path::makeRelative("style.css", "webmozart/puli/css");
=> ../../../style.css
If both paths are absolute, their root directory must be the same,
otherwise an exception is thrown:
php
Path::makeRelative("C:/webmozart/style.css", "/webmozart/puli");
InvalidArgumentException
If the passed path is absolute, but the base path is not, an exception
is thrown as well:
php
Path::makeRelative("/webmozart/style.css", "webmozart/puli");
InvalidArgumentException
If the base path is not an absolute path, an exception is thrown.
The result is a canonical path.
/** * {@inheritdoc} */ public function generateNewInstance($varName, Method $targetMethod, GeneratorRegistry $generatorRegistry, array $options = array()) { Assert::keyExists($options, 'root-dir', 'The "root-dir" option is missing.'); $options = array_replace(self::$defaultOptions, $options); Assert::stringNotEmpty($options['path'], 'The "path" option should be a non-empty string. Got: %s'); Assert::stringNotEmpty($options['root-dir'], 'The "root-dir" option should be a non-empty string. Got: %s'); Assert::boolean($options['serialize-strings'], 'The "serialize-strings" option should be a boolean. Got: %s'); Assert::boolean($options['serialize-arrays'], 'The "serialize-arrays" option should be a boolean. Got: %s'); Assert::boolean($options['escape-slash'], 'The "escape-slash" option should be a boolean. Got: %s'); Assert::boolean($options['pretty-print'], 'The "pretty-print" option should be a boolean. Got: %s'); $path = Path::makeAbsolute($options['path'], $options['root-dir']); $relPath = Path::makeRelative($path, $targetMethod->getClass()->getDirectory()); $flags = array(); if (!$options['serialize-strings']) { $flags[] = 'JsonFileStore::NO_SERIALIZE_STRINGS'; } if (!$options['serialize-arrays']) { $flags[] = 'JsonFileStore::NO_SERIALIZE_ARRAYS'; } if (!$options['serialize-arrays']) { $flags[] = 'JsonFileStore::NO_ESCAPE_SLASH'; } if ($options['pretty-print']) { $flags[] = 'JsonFileStore::PRETTY_PRINT'; } $targetMethod->getClass()->addImport(new Import('Webmozart\\KeyValueStore\\JsonFileStore')); $targetMethod->addBody(sprintf('$%s = new JsonFileStore(%s%s%s);', $varName, $flags ? "\n " : '', '__DIR__.' . var_export('/' . $relPath, true), $flags ? ",\n " . implode("\n | ", $flags) . "\n" : '')); }
/** * {@inheritdoc} */ public function generateNewInstance($varName, Method $targetMethod, GeneratorRegistry $generatorRegistry, array $options = array()) { Assert::keyExists($options, 'root-dir', 'The "root-dir" option is missing.'); $options = array_replace_recursive(self::$defaultOptions, $options); if (!isset($options['path'])) { $options['path'] = $targetMethod->getClass()->getDirectory() . '/path-mappings.json'; } Assert::stringNotEmpty($options['path'], 'The "path" option should be a non-empty string. Got: %s'); Assert::stringNotEmpty($options['root-dir'], 'The "root-dir" option should be a non-empty string. Got: %s'); Assert::boolean($options['optimize'], 'The "optimize" option should be a boolean. Got: %s'); Assert::isArray($options['change-stream'], 'The "change-stream" option should be an array. Got: %s'); $path = Path::makeAbsolute($options['path'], $options['root-dir']); $relPath = Path::makeRelative($path, $targetMethod->getClass()->getDirectory()); $relBaseDir = Path::makeRelative($options['root-dir'], $targetMethod->getClass()->getDirectory()); $escPath = '__DIR__.' . var_export('/' . $relPath, true); $escBaseDir = $relBaseDir ? '__DIR__.' . var_export('/' . $relBaseDir, true) : '__DIR__'; if ($options['optimize']) { $streamGenerator = $generatorRegistry->getServiceGenerator(GeneratorRegistry::CHANGE_STREAM, $options['change-stream']['type']); $streamOptions = $options['change-stream']; $streamOptions['root-dir'] = $options['root-dir']; $streamGenerator->generateNewInstance('stream', $targetMethod, $generatorRegistry, $streamOptions); $targetMethod->getClass()->addImport(new Import('Puli\\Repository\\OptimizedJsonRepository')); $targetMethod->addBody(sprintf('$%s = new OptimizedJsonRepository(%s, %s, false, $stream);', $varName, $escPath, $escBaseDir)); } else { $targetMethod->getClass()->addImport(new Import('Puli\\Repository\\JsonRepository')); $targetMethod->addBody(sprintf('$%s = new JsonRepository(%s, %s, true);', $varName, $escPath, $escBaseDir)); } }
/** * {@inheritdoc} */ public function generateNewInstance($varName, Method $targetMethod, GeneratorRegistry $generatorRegistry, array $options = array()) { Assert::keyExists($options, 'rootDir', 'The "rootDir" option is missing.'); $options = array_replace(self::$defaultOptions, $options); if (!isset($options['path'])) { $options['path'] = $targetMethod->getClass()->getDirectory() . '/repository'; } Assert::string($options['path'], 'The "path" option should be a string. Got: %s'); Assert::string($options['rootDir'], 'The "rootDir" option should be a string. Got: %s'); Assert::boolean($options['symlink'], 'The "symlink" option should be a boolean. Got: %s'); $path = Path::makeAbsolute($options['path'], $options['rootDir']); $relPath = Path::makeRelative($path, $targetMethod->getClass()->getDirectory()); $escPath = $relPath ? '__DIR__.' . var_export('/' . $relPath, true) : '__DIR__'; if ($relPath) { $targetMethod->addBody(<<<EOF if (!file_exists({$escPath})) { mkdir({$escPath}, 0777, true); } EOF ); } $targetMethod->getClass()->addImport(new Import('Puli\\Repository\\FilesystemRepository')); $targetMethod->addBody(sprintf('$%s = new FilesystemRepository(%s, %s);', $varName, $escPath, var_export($options['symlink'], true))); }
/** * Concat two path member only if the second is not absolute * and make the result relative to the last parameter. */ public static function makeConfigPathRelative($config_path, $option_path, $current_path = null) { $current_path = $current_path === null ? getcwd() : $current_path; $config_path = Path::makeAbsolute($config_path, $current_path); $absolute_path = Path::makeAbsolute($option_path, $config_path); $relative_path = Path::makeRelative($absolute_path, $current_path); return $relative_path === '' ? '.' : $relative_path; }
/** * {@inheritDoc} */ public function collect() : AssetCollection { $files = []; $this->finder->files()->ignoreDotFiles(false)->in((string) $this->srcDir)->name('/\\.txt$/')->sortByType(); foreach ($this->finder as $file) { $files[] = new TextFile(new File($file->getPathname()), $this->filesystem, dirname(Path::makeRelative($file->getPathname(), (string) $this->srcDir))); } return new AssetCollection($files); }
/** * {@inheritdoc} */ public function generateNewInstance($varName, Method $targetMethod, GeneratorRegistry $generatorRegistry, array $options = array()) { Assert::keyExists($options, 'rootDir', 'The "rootDir" option is missing.'); $options = array_replace(self::$defaultOptions, $options); $path = Path::makeAbsolute($options['path'], $options['rootDir']); $relPath = Path::makeRelative($path, $targetMethod->getClass()->getDirectory()); $targetMethod->getClass()->addImport(new Import('Webmozart\\KeyValueStore\\JsonFileStore')); $targetMethod->addBody(sprintf('$%s = new JsonFileStore(%s, %s);', $varName, '__DIR__.' . var_export('/' . $relPath, true), $options['cache'] ? 'true' : 'false')); }
/** * {@inheritDoc} */ public function collect() : AssetCollection { $templates = []; $this->finder->files()->ignoreDotFiles(false)->in((string) $this->srcDir)->name('/\\.twig$/')->sortByType(); foreach ($this->finder as $template) { $templates[] = new TwigTemplateFile(Path::makeRelative($template->getPathname(), (string) $this->srcDir), $this->twigData, $this->twig, $this->filesystem); } return new AssetCollection($templates); }
/** * @param GadgetResultEvent $event */ public function onGadgetResult(GadgetResultEvent $event) { $result = $event->getResult(); $path = $event->getPath(); foreach ($result->getIssues() as $issue) { if (!$issue->getFile()) { continue; } $issue->setFile(Path::makeRelative($issue->getFile(), $path)); } }
public function postAutoloadDump(Event $event) { // This method is called twice. Run it only once. if (!$this->runPostAutoloadDump) { return; } $this->runPostAutoloadDump = false; $config = $this->composer->getConfig(); $suffix = $config->get('autoloader-suffix'); $vendorDir = $config->get('vendor-dir'); $binDir = $config->get('bin-dir'); $autoloadFile = $vendorDir . '/autoload.php'; if (!file_exists($autoloadFile)) { throw new \RuntimeException(sprintf('Could not adjust autoloader: The file %s was not found.', $autoloadFile)); } if (!$suffix && !$config->get('autoloader-suffix') && is_readable($autoloadFile)) { $content = file_get_contents($vendorDir . '/autoload.php'); if (preg_match('{' . self::COMPOSER_AUTOLOADER_BASE . '([^:\\s]+)::}', $content, $match)) { $suffix = $match[1]; } } $contents = file_get_contents($autoloadFile); $constant = ''; $values = array('AUTOLOAD_CLASS' => var_export(self::COMPOSER_AUTOLOADER_BASE . $suffix, true)); foreach ($values as $key => $value) { $this->io->write('<info>Generating ' . $this->constantPrefix . $key . ' constant</info>'); $constant .= "if (!defined('{$this->constantPrefix}{$key}')) {\n"; $constant .= sprintf(" define('{$this->constantPrefix}{$key}', %s);\n", $value); $constant .= "}\n\n"; } $values = array_map(function ($value) { return var_export($value, true); }, array('BASE_DIR' => Path::makeRelative(getcwd(), $vendorDir), 'BIN_DIR' => Path::makeRelative($binDir, $vendorDir), 'FILE' => Path::makeRelative(realpath(Factory::getComposerFile()), $vendorDir))); foreach ($values as $key => $value) { $this->io->write('<info>Generating ' . $this->constantPrefix . $key . ' constant</info>'); $constant .= "if (!defined('{$this->constantPrefix}{$key}')) {\n"; $constant .= sprintf(" define('{$this->constantPrefix}{$key}', realpath(__DIR__ . DIRECTORY_SEPARATOR . %s));\n", $value); $constant .= "}\n\n"; } $values = array('VENDOR_DIR' => $vendorDir); foreach ($values as $key => $value) { $this->io->write('<info>Generating ' . $this->constantPrefix . $key . ' constant</info>'); $constant .= "if (!defined('{$this->constantPrefix}{$key}')) {\n"; $constant .= sprintf(" define('{$this->constantPrefix}{$key}', realpath(__DIR__));\n"); $constant .= "}\n\n"; } // Regex modifiers: // "m": \s matches newlines // "D": $ matches at EOF only // Translation: insert before the last "return" in the file $contents = preg_replace('/\\n(?=return [^;]+;\\s*$)/mD', "\n" . $constant, $contents); file_put_contents($autoloadFile, $contents); }
/** * {@inheritdoc} */ public function generateNewInstance($varName, Method $targetMethod, GeneratorRegistry $generatorRegistry, array $options = array()) { Assert::keyExists($options, 'rootDir', 'The "rootDir" option is missing.'); $options = array_replace_recursive(self::$defaultOptions, $options); $kvsGenerator = $generatorRegistry->getServiceGenerator(GeneratorRegistry::KEY_VALUE_STORE, $options['store']['type']); $kvsOptions = $options['store']; $kvsOptions['rootDir'] = $options['rootDir']; $kvsGenerator->generateNewInstance('store', $targetMethod, $generatorRegistry, $kvsOptions); $relPath = Path::makeRelative($options['rootDir'], $targetMethod->getClass()->getDirectory()); $escPath = $relPath ? '__DIR__.' . var_export('/' . $relPath, true) : '__DIR__'; $className = ($options['optimize'] ? 'Optimized' : '') . 'PathMappingRepository'; $targetMethod->getClass()->addImport(new Import('Puli\\Repository\\' . $className)); $targetMethod->addBody(sprintf('$%s = new %s($store, %s);', $varName, $className, $escPath)); }
/** * {@inheritdoc} */ public function generateNewInstance($varName, Method $targetMethod, GeneratorRegistry $generatorRegistry, array $options = array()) { Assert::keyExists($options, 'root-dir', 'The "root-dir" option is missing.'); if (!isset($options['path'])) { $options['path'] = $targetMethod->getClass()->getDirectory() . '/change-stream.json'; } Assert::stringNotEmpty($options['root-dir'], 'The "root-dir" option should be a non-empty string. Got: %s'); Assert::stringNotEmpty($options['path'], 'The "path" option should be a non-empty string. Got: %s'); $path = Path::makeAbsolute($options['path'], $options['root-dir']); $relPath = Path::makeRelative($path, $targetMethod->getClass()->getDirectory()); $escPath = '__DIR__.' . var_export('/' . $relPath, true); $targetMethod->getClass()->addImport(new Import('Puli\\Repository\\ChangeStream\\JsonChangeStream')); $targetMethod->addBody(sprintf('$%s = new JsonChangeStream(%s);', $varName, $escPath)); }
/** * {@inheritdoc} */ public function generateNewInstance($varName, Method $targetMethod, GeneratorRegistry $generatorRegistry, array $options = array()) { Assert::keyExists($options, 'root-dir', 'The "root-dir" option is missing.'); if (!isset($options['path'])) { $options['path'] = $targetMethod->getClass()->getDirectory() . '/bindings.json'; } Assert::stringNotEmpty($options['root-dir'], 'The "root-dir" option should be a non-empty string. Got: %s'); Assert::stringNotEmpty($options['path'], 'The "path" option should be a non-empty string. Got: %s'); $path = Path::makeAbsolute($options['path'], $options['root-dir']); $relPath = Path::makeRelative($path, $targetMethod->getClass()->getDirectory()); $escPath = '__DIR__.' . var_export('/' . $relPath, true); $targetMethod->getClass()->addImport(new Import('Puli\\Discovery\\JsonDiscovery')); $targetMethod->getClass()->addImport(new Import('Puli\\Discovery\\Binding\\Initializer\\ResourceBindingInitializer')); $targetMethod->addBody(sprintf("\$%s = new JsonDiscovery(%s, array(\n new ResourceBindingInitializer(\$repo),\n));", $varName, $escPath)); }
public static function filterReferences($content, $callback) { return CssUtils::filterReferences($content, function ($matches) use($callback) { // 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.', $matches['url'], $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]); }); }
/** * Turns a URL into a relative path. * * The result is a canonical path. This class is using functionality of Path class. * * @see Path * * @param string $url A URL to make relative. * @param string $baseUrl A base URL. * * @return string * * @throws InvalidArgumentException If the URL and base URL does * not match. */ public static function makeRelative($url, $baseUrl) { Assert::string($url, 'The URL must be a string. Got: %s'); Assert::string($baseUrl, 'The base URL must be a string. Got: %s'); Assert::contains($baseUrl, '://', '%s is not an absolute Url.'); list($baseHost, $basePath) = self::split($baseUrl); if (false === strpos($url, '://')) { if (0 === strpos($url, '/')) { $host = $baseHost; } else { $host = ''; } $path = $url; } else { list($host, $path) = self::split($url); } if ('' !== $host && $host !== $baseHost) { throw new InvalidArgumentException(sprintf('The URL "%s" cannot be made relative to "%s" since their host names are different.', $host, $baseHost)); } return Path::makeRelative($path, $basePath); }
/** * {@inheritdoc} * * @throws FileExistsException * @throws \InvalidArgumentException * @throws FileNotFoundException * @throws LogicException */ public function backup(Filesystem $source, Filesystem $destination, Database $database, array $parameter) { if (0 === $source->has($parameter['directory'])) { $this->output->writeln(sprintf(' Directory "%s" not found.', $parameter['directory'])); return; } // TODO make it smoother $files = $source->listFiles($parameter['directory'], true); if (0 === count($files)) { $this->output->writeln(sprintf(' No files found in directory "%s".', $parameter['directory'])); return; } $progressBar = new ProgressBar($this->output, count($files)); $progressBar->setOverwrite(true); $progressBar->setFormat(' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s% %memory:6s%'); $progressBar->start(); foreach ($files as $file) { $destination->writeStream(Path::makeRelative($file['path'], $parameter['directory']), $source->readStream($file['path'])); $progressBar->advance(); } $progressBar->finish(); }
/** * {@inheritdoc} */ public function installPackage($installPath, $name = null, $installerName = InstallInfo::DEFAULT_INSTALLER_NAME) { Assert::string($installPath, 'The install path must be a string. Got: %s'); Assert::string($installerName, 'The installer name must be a string. Got: %s'); Assert::nullOrPackageName($name); $this->assertPackagesLoaded(); $installPath = Path::makeAbsolute($installPath, $this->rootDir); foreach ($this->packages as $package) { if ($installPath === $package->getInstallPath()) { return; } } if (null === $name) { // Read the name from the package file $name = $this->loadPackageFile($installPath)->getPackageName(); } if (null === $name) { throw new InvalidConfigException(sprintf('Could not find a name for the package at %s. The name should ' . 'either be passed to the installer or be set in the "name" ' . 'property of %s.', $installPath, $installPath . '/puli.json')); } if ($this->packages->contains($name)) { throw NameConflictException::forName($name); } $relInstallPath = Path::makeRelative($installPath, $this->rootDir); $installInfo = new InstallInfo($name, $relInstallPath); $installInfo->setInstallerName($installerName); $package = $this->loadPackage($installInfo); $this->assertNoLoadErrors($package); $this->rootPackageFile->addInstallInfo($installInfo); try { $this->packageFileStorage->saveRootPackageFile($this->rootPackageFile); } catch (Exception $e) { $this->rootPackageFile->removeInstallInfo($name); throw $e; } $this->packages->add($package); }
private function printPackageWarning(IOInterface $io, $message, $packageName, $installPath, PuliRunnerException $exception = null) { $this->printWarning($io, sprintf($message, $packageName, Path::makeRelative($installPath, $this->rootDir)), $exception); }
/** * @dataProvider provideAbsolutePathsWithDifferentRoots * @expectedException \InvalidArgumentException */ public function testMakeRelativeFailsIfDifferentRoot($absolutePath, $basePath) { Path::makeRelative($absolutePath, $basePath); }
/** * Creates a symlink with a relative path. * * @throws \derhasi\symlinker\SymlinkFailedException */ public function createRelative() { $this->validate(); $source = Path::makeRelative($this->source, dirname($this->link)); $success = symlink($source, $this->link); if (!$success) { throw new SymlinkFailedException($this->link, $this->source); } }
/** * {@inheritdoc} */ public function installModule($installPath, $name = null, $installerName = InstallInfo::DEFAULT_INSTALLER_NAME, $env = Environment::PROD) { Assert::string($installPath, 'The install path must be a string. Got: %s'); Assert::string($installerName, 'The installer name must be a string. Got: %s'); Assert::oneOf($env, Environment::all(), 'The environment must be one of: %2$s. Got: %s'); Assert::nullOrModuleName($name); $this->assertModulesLoaded(); $installPath = Path::makeAbsolute($installPath, $this->rootDir); foreach ($this->modules as $module) { if ($installPath === $module->getInstallPath()) { return; } } if (null === $name && ($moduleFile = $this->loadModuleFile($installPath))) { // Read the name from the module file $name = $moduleFile->getModuleName(); } if (null === $name) { throw new InvalidConfigException(sprintf('Could not find a name for the module at %s. The name should ' . 'either be passed to the installer or be set in the "name" ' . 'property of %s.', $installPath, $installPath . '/puli.json')); } if ($this->modules->contains($name)) { throw NameConflictException::forName($name); } $relInstallPath = Path::makeRelative($installPath, $this->rootDir); $installInfo = new InstallInfo($name, $relInstallPath); $installInfo->setInstallerName($installerName); $installInfo->setEnvironment($env); $module = $this->loadModule($installInfo); $this->assertNoLoadErrors($module); $this->rootModuleFile->addInstallInfo($installInfo); try { $this->moduleFileStorage->saveRootModuleFile($this->rootModuleFile); } catch (Exception $e) { $this->rootModuleFile->removeInstallInfo($name); throw $e; } $this->modules->add($module); }
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)); }
/** * {@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; }
/** * {@inheritdoc} */ public function listContents($directory = '', $recursive = false) { $contents = $this->adapter->listContents($this->getPath($directory), $recursive); $root = ltrim($this->root, '/'); return array_map(function ($file) use($root) { $file['path'] = Path::makeRelative($file['path'], $root); if (array_key_exists('dirname', $file)) { $file['dirname'] = Path::makeRelative($file['dirname'], $root); } return $file; }, array_filter($contents, function ($file) use($root) { if (0 !== strpos($file['path'], $root)) { return false; } return true; })); }
/** * 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); }
/** * Returns the path where a resource is going to be installed. * * This is a path relative to the document root of the target server. * * @param Resource $resource The resource. * * @return string The server path. */ public function getServerPathForResource(Resource $resource) { $relPath = Path::makeRelative($resource->getRepositoryPath(), $this->basePath); return '/' . trim($this->mapping->getServerPath() . '/' . $relPath, '/'); }
/** * Enforce the default JSON settings. * * @param array $json * * @return array */ private function setJsonDefaults(array $json) { $rootPath = $this->app['resources']->getPath('root'); $extensionsPath = $this->app['resources']->getPath('extensions'); $srcPath = $this->app['resources']->getPath('src'); $webPath = $this->app['resources']->getPath('web'); $pathToRoot = Path::makeRelative($rootPath, $extensionsPath); $pathToWeb = Path::makeRelative($webPath, $extensionsPath); $eventPath = Path::makeRelative($srcPath . '/Composer/EventListener', $extensionsPath); // Enforce standard settings $defaults = ['name' => 'bolt/extensions', 'description' => 'Bolt extension installation interface', 'license' => 'MIT', 'repositories' => ['packagist' => false, 'bolt' => ['type' => 'composer', 'url' => $this->app['extend.site'] . 'satis/']], 'minimum-stability' => $this->app['config']->get('general/extensions/stability', 'stable'), 'prefer-stable' => true, 'config' => ['discard-changes' => true, 'preferred-install' => 'dist'], 'provide' => ['bolt/bolt' => Bolt\Version::forComposer()], 'extra' => ['bolt-web-path' => $pathToWeb, 'bolt-root-path' => $pathToRoot], 'autoload' => ['psr-4' => ['Bolt\\Composer\\EventListener\\' => $eventPath]], 'scripts' => ['post-autoload-dump' => 'Bolt\\Composer\\EventListener\\PackageEventListener::dump', 'post-package-install' => 'Bolt\\Composer\\EventListener\\PackageEventListener::handle', 'post-package-update' => 'Bolt\\Composer\\EventListener\\PackageEventListener::handle']]; $json = Arr::mergeRecursiveDistinct($json, $defaults); ksort($json); return $json; }
/** * Adds a filesystem resource to the JSON file. * * @param string $path The Puli path. * @param FilesystemResource $resource The resource to add. */ protected function addFilesystemResource($path, FilesystemResource $resource) { $resource = clone $resource; $resource->attachTo($this, $path); $relativePath = Path::makeRelative($resource->getFilesystemPath(), $this->baseDirectory); $this->insertReference($path, $relativePath); $this->storeVersion($resource); }
private function symlinkMirror($origin, $target, array $dirsToKeep = array()) { $targetIsDir = is_dir($target); $forceDir = in_array($target, $dirsToKeep, true); // Merge directories if (is_dir($origin) && ($targetIsDir || $forceDir)) { if (is_link($target)) { $this->replaceLinkByCopy($target, $dirsToKeep); } $iterator = $this->getDirectoryIterator($origin); foreach ($iterator as $path) { $this->symlinkMirror($path, $target . '/' . basename($path), $dirsToKeep); } return; } // Replace target if (file_exists($target)) { $this->filesystem->remove($target); } // Try creating a relative link if ($this->relative && $this->trySymlink(Path::makeRelative($origin, Path::getDirectory($target)), $target)) { return; } // Try creating a absolute link if ($this->trySymlink($origin, $target)) { return; } // Fall back to copy if (is_dir($origin)) { $this->filesystem->mirror($origin, $target); return; } $this->filesystem->copy($origin, $target); }
/** * Gets the directory requested either from configured application or composer's extra section/environment variable. * * @param Event $event * @param string $name * @param string|null $default * * @return string */ protected static function getDir(Event $event, $name, $default = null) { try { $app = static::getApp($event); $dir = $app['resources']->getPath($name); $dir = Path::makeRelative($dir, getcwd()); } catch (LowlevelException $e) { $dir = static::getOption($event, $name . '-dir', $default); } return rtrim($dir, '/'); }
private function symlinkMirror($origin, $target) { // Merge directories if (is_dir($target) && is_dir($origin)) { if (is_link($target)) { $this->replaceLinkByCopy($target); } $iterator = new RecursiveDirectoryIterator($origin, RecursiveDirectoryIterator::CURRENT_AS_FILE); foreach ($iterator as $path => $filename) { $this->symlinkMirror($path, $target . '/' . $filename); } return; } // Try creating a relative link if ($this->relative && $this->trySymlink(Path::makeRelative($origin, Path::getDirectory($target)), $target)) { return; } // Try creating a absolute link if ($this->trySymlink($origin, $target)) { return; } // Fall back to copy if (is_dir($origin)) { $this->filesystem->mirror($origin, $target); return; } $this->filesystem->copy($origin, $target); }