/
home
/
obinna
/
html
/
restaurants
/
vendor
/
symfony
/
flex
/
src
/
Upload File
HOME
<?php /* * This file is part of the Symfony package. * * (c) Fabien Potencier <fabien@symfony.com> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Flex; use Composer\Json\JsonFile; use Composer\Json\JsonManipulator; use Composer\Semver\Constraint\ConstraintInterface; use Composer\Semver\Intervals; use Composer\Semver\VersionParser; /** * Synchronize package.json files detected in installed PHP packages with * the current application. */ class PackageJsonSynchronizer { private $rootDir; private $vendorDir; public function __construct(string $rootDir, string $vendorDir = 'vendor') { $this->rootDir = $rootDir; $this->vendorDir = $vendorDir; } public function shouldSynchronize(): bool { return $this->rootDir && file_exists($this->rootDir.'/package.json'); } public function synchronize(array $phpPackages): bool { // Remove all links and add again only the existing packages $didAddLink = $this->removePackageJsonLinks((new JsonFile($this->rootDir.'/package.json'))->read()); foreach ($phpPackages as $k => $phpPackage) { if (\is_string($phpPackage)) { // support for smooth upgrades from older flex versions $phpPackages[$k] = $phpPackage = [ 'name' => $phpPackage, 'keywords' => ['symfony-ux'], ]; } $didAddLink = $this->addPackageJsonLink($phpPackage) || $didAddLink; } $this->registerPeerDependencies($phpPackages); // Register controllers and entrypoints in controllers.json $this->registerWebpackResources($phpPackages); return $didAddLink; } private function removePackageJsonLinks(array $packageJson): bool { $didRemoveLink = false; $jsDependencies = $packageJson['dependencies'] ?? []; $jsDevDependencies = $packageJson['devDependencies'] ?? []; foreach (['dependencies' => $jsDependencies, 'devDependencies' => $jsDevDependencies] as $key => $packages) { foreach ($packages as $name => $version) { if ('@' !== $name[0] || 0 !== strpos($version, 'file:')) { continue; } $manipulator = new JsonManipulator(file_get_contents($this->rootDir.'/package.json')); $manipulator->removeSubNode('devDependencies', $name); file_put_contents($this->rootDir.'/package.json', $manipulator->getContents()); $didRemoveLink = true; } } return $didRemoveLink; } private function addPackageJsonLink(array $phpPackage): bool { if (!$packageJson = $this->resolvePackageJson($phpPackage)) { return false; } $manipulator = new JsonManipulator(file_get_contents($this->rootDir.'/package.json')); $manipulator->addSubNode('devDependencies', '@'.$phpPackage['name'], 'file:'.substr($packageJson->getPath(), 1 + \strlen($this->rootDir), -13)); $content = json_decode($manipulator->getContents(), true); $devDependencies = $content['devDependencies']; uksort($devDependencies, 'strnatcmp'); $manipulator->addMainKey('devDependencies', $devDependencies); file_put_contents($this->rootDir.'/package.json', $manipulator->getContents()); return true; } private function registerWebpackResources(array $phpPackages) { if (!file_exists($controllersJsonPath = $this->rootDir.'/assets/controllers.json')) { return; } $previousControllersJson = (new JsonFile($controllersJsonPath))->read(); $newControllersJson = [ 'controllers' => [], 'entrypoints' => $previousControllersJson['entrypoints'], ]; foreach ($phpPackages as $phpPackage) { if (!$packageJson = $this->resolvePackageJson($phpPackage)) { continue; } $name = '@'.$phpPackage['name']; foreach ($packageJson->read()['symfony']['controllers'] ?? [] as $controllerName => $defaultConfig) { // If the package has just been added (no config), add the default config provided by the package if (!isset($previousControllersJson['controllers'][$name][$controllerName])) { $config = []; $config['enabled'] = $defaultConfig['enabled']; $config['fetch'] = $defaultConfig['fetch'] ?? 'eager'; if (isset($defaultConfig['autoimport'])) { $config['autoimport'] = $defaultConfig['autoimport']; } $newControllersJson['controllers'][$name][$controllerName] = $config; continue; } // Otherwise, the package exists: merge new config with uer config $previousConfig = $previousControllersJson['controllers'][$name][$controllerName]; $config = []; $config['enabled'] = $previousConfig['enabled']; $config['fetch'] = $previousConfig['fetch'] ?? 'eager'; if (isset($defaultConfig['autoimport'])) { $config['autoimport'] = []; // Use for each autoimport either the previous config if one existed or the default config otherwise foreach ($defaultConfig['autoimport'] as $autoimport => $enabled) { $config['autoimport'][$autoimport] = $previousConfig['autoimport'][$autoimport] ?? $enabled; } } $newControllersJson['controllers'][$name][$controllerName] = $config; } foreach ($packageJson->read()['symfony']['entrypoints'] ?? [] as $entrypoint => $filename) { if (!isset($newControllersJson['entrypoints'][$entrypoint])) { $newControllersJson['entrypoints'][$entrypoint] = $filename; } } } file_put_contents($controllersJsonPath, json_encode($newControllersJson, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES)."\n"); } public function registerPeerDependencies(array $phpPackages) { $peerDependencies = []; foreach ($phpPackages as $phpPackage) { if (!$packageJson = $this->resolvePackageJson($phpPackage)) { continue; } $versionParser = new VersionParser(); foreach ($packageJson->read()['peerDependencies'] ?? [] as $peerDependency => $constraint) { $peerDependencies[$peerDependency][$constraint] = $versionParser->parseConstraints($constraint); } } if (!$peerDependencies) { return; } $manipulator = new JsonManipulator(file_get_contents($this->rootDir.'/package.json')); $content = json_decode($manipulator->getContents(), true); $devDependencies = $content['devDependencies'] ?? []; foreach ($peerDependencies as $peerDependency => $constraints) { $devDependencies[$peerDependency] = $this->compactConstraints($constraints); } uksort($devDependencies, 'strnatcmp'); $manipulator->addMainKey('devDependencies', $devDependencies); file_put_contents($this->rootDir.'/package.json', $manipulator->getContents()); } private function resolvePackageJson(array $phpPackage): ?JsonFile { $packageDir = $this->rootDir.'/'.$this->vendorDir.'/'.$phpPackage['name']; if (!\in_array('symfony-ux', $phpPackage['keywords'] ?? [], true)) { return null; } foreach (['/assets', '/Resources/assets'] as $subdir) { $packageJsonPath = $packageDir.$subdir.'/package.json'; if (!file_exists($packageJsonPath)) { continue; } return new JsonFile($packageJsonPath); } return null; } /** * @param ConstraintInterface[] $constraints */ private function compactConstraints(array $constraints): string { if (method_exists(Intervals::class, 'isSubsetOf')) { foreach ($constraints as $k1 => $constraint1) { foreach ($constraints as $k2 => $constraint2) { if ($k1 !== $k2 && Intervals::isSubsetOf($constraint1, $constraint2)) { unset($constraints[$k2]); } } } } uksort($constraints, 'strnatcmp'); foreach ($constraints as $k => $constraint) { $constraints[$k] = \count($constraints) > 1 && false !== strpos($k, '|') ? '('.$k.')' : $k; } return implode(',', $constraints); } }