getFileIterator($sourceRoot, $filePatterns); foreach($fileIterator as $path => $info) { $relativePath = substr($path, strlen($sourceRoot)); $destination = $destinationRoot . $relativePath; // Only copy non-existent files if (file_exists($destination)) { continue; } $this->io->write("Installing recipe $recipe file $relativePath"); $this->filesystem->ensureDirectoryExists(dirname($destination)); copy($path, $destination); } } /** * Get iterator of matching source files to copy * * @param string $sourceRoot Root directory of sources (no trailing slash) * @param array $patterns List of wildcard patterns to match * @return Iterator File iterator, where key is path and value is file info object */ protected function getFileIterator($sourceRoot, $patterns) { // Build regexp pattern $expressions = []; foreach($patterns as $pattern) { $expressions[] = $this->globToRegexp($pattern); } $regExp = '#^' . $this->globToRegexp($sourceRoot . '/').'(('.implode(')|(', $expressions).'))$#'; // Build directory iterator $directoryIterator = new RecursiveDirectoryIterator( $sourceRoot, FilesystemIterator::SKIP_DOTS | FilesystemIterator::UNIX_PATHS | FilesystemIterator::KEY_AS_PATHNAME | FilesystemIterator::CURRENT_AS_FILEINFO ); // Return filtered iterator $iterator = new RecursiveIteratorIterator($directoryIterator); return new RegexIterator($iterator, $regExp); } /** * Convert glob pattern to regexp * * @param string $glob * @return string */ protected function globToRegexp($glob) { $sourceParts = explode('*', $glob); $regexParts = array_map(function($part) { return preg_quote($part, '#'); }, $sourceParts); return implode('(.+)', $regexParts); } /** * @param PackageInterface $package */ public function installLibrary(PackageInterface $package) { // Copy project files to root $destinationPath = getcwd(); $name = $package->getName(); $extra = $package->getExtra(); if (isset($extra['project-files'])) { $this->installProjectFiles( $name, $this->getInstallPath($package), $destinationPath, $extra['project-files'] ); } } }