diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php index 9ca5f3ae5..a5f4be066 100644 --- a/.php-cs-fixer.php +++ b/.php-cs-fixer.php @@ -16,12 +16,13 @@ $finder = PhpCsFixer\Finder::create() ->in(__DIR__.'/tests') ->name('*.php') ->notPath('Fixtures') + ->notPath(__DIR__.'/src/Composer/Autoload/ClassLoader.php') + ->notPath(__DIR__.'/src/Composer/InstalledVersions.php') ; $config = new PhpCsFixer\Config(); return $config->setRules([ '@PSR2' => true, - 'array_syntax' => array('syntax' => 'long'), 'binary_operator_spaces' => true, 'blank_line_before_statement' => array('statements' => array('declare', 'return')), 'cast_spaces' => array('space' => 'single'), @@ -59,6 +60,18 @@ return $config->setRules([ //'global_namespace_import' => ['import_classes' => true], 'no_leading_import_slash' => true, 'single_import_per_statement' => true, + + // PHP 7.2 migration + // TODO later once 2.2 is more stable + // 'array_syntax' => true, + // 'list_syntax' => true, + 'visibility_required' => ['elements' => ['property', 'method', /* TODO 'const' but need to review them all */]], + 'non_printable_character' => true, + 'combine_nested_dirname' => true, + 'random_api_migration' => true, + 'ternary_to_null_coalescing' => true, + //'declare_strict_types' => true, + //'void_return' => true, ]) ->setUsingCache(true) ->setRiskyAllowed(true) diff --git a/src/Composer/Command/ConfigCommand.php b/src/Composer/Command/ConfigCommand.php index 332d7b4a8..8b67042fe 100644 --- a/src/Composer/Command/ConfigCommand.php +++ b/src/Composer/Command/ConfigCommand.php @@ -263,7 +263,7 @@ EOT $data = $this->config->all(); if (Preg::isMatch('/^repos?(?:itories)?(?:\.(.+))?/', $settingKey, $matches)) { if (!isset($matches[1]) || $matches[1] === '') { - $value = isset($data['repositories']) ? $data['repositories'] : array(); + $value = $data['repositories'] ?? array(); } else { if (!isset($data['repositories'][$matches[1]])) { throw new \InvalidArgumentException('There is no '.$matches[1].' repository defined'); @@ -699,7 +699,7 @@ EOT $currentValue = $this->configFile->read(); $bits = explode('.', $settingKey); foreach ($bits as $bit) { - $currentValue = isset($currentValue[$bit]) ? $currentValue[$bit] : null; + $currentValue = $currentValue[$bit] ?? null; } if (is_array($currentValue)) { $value = array_merge($currentValue, $value); @@ -877,7 +877,7 @@ EOT continue; } - $rawVal = isset($rawContents[$key]) ? $rawContents[$key] : null; + $rawVal = $rawContents[$key] ?? null; if (is_array($value) && (!is_numeric(key($value)) || ($key === 'repositories' && null === $k))) { $k .= Preg::replace('{^config\.}', '', $key . '.'); diff --git a/src/Composer/Command/DiagnoseCommand.php b/src/Composer/Command/DiagnoseCommand.php index e08a71984..a39ffd541 100644 --- a/src/Composer/Command/DiagnoseCommand.php +++ b/src/Composer/Command/DiagnoseCommand.php @@ -447,7 +447,7 @@ EOT return ''.$version['version'].' '. 'libz '.(!empty($version['libz_version']) ? $version['libz_version'] : 'missing').' '. - 'ssl '.(isset($version['ssl_version']) ? $version['ssl_version'] : 'missing').''; + 'ssl '.($version['ssl_version'] ?? 'missing').''; } return 'missing, using php streams fallback, which reduces performance'; diff --git a/src/Composer/Command/HomeCommand.php b/src/Composer/Command/HomeCommand.php index 533bed826..a44546c55 100644 --- a/src/Composer/Command/HomeCommand.php +++ b/src/Composer/Command/HomeCommand.php @@ -104,7 +104,7 @@ EOT private function handlePackage(CompletePackageInterface $package, $showHomepage, $showOnly) { $support = $package->getSupport(); - $url = isset($support['source']) ? $support['source'] : $package->getSourceUrl(); + $url = $support['source'] ?? $package->getSourceUrl(); if (!$url || $showHomepage) { $url = $package->getHomepage(); } diff --git a/src/Composer/Command/SearchCommand.php b/src/Composer/Command/SearchCommand.php index 0299767bc..9a404482f 100644 --- a/src/Composer/Command/SearchCommand.php +++ b/src/Composer/Command/SearchCommand.php @@ -107,7 +107,7 @@ EOT } $nameLength += 1; foreach ($results as $result) { - $description = isset($result['description']) ? $result['description'] : ''; + $description = $result['description'] ?? ''; $warning = !empty($result['abandoned']) ? '! Abandoned ! ' : ''; $remaining = $width - $nameLength - strlen($warning) - 2; if (strlen($description) > $remaining) { diff --git a/src/Composer/Command/SelfUpdateCommand.php b/src/Composer/Command/SelfUpdateCommand.php index d3a1a3343..af8d511e7 100644 --- a/src/Composer/Command/SelfUpdateCommand.php +++ b/src/Composer/Command/SelfUpdateCommand.php @@ -213,7 +213,7 @@ EOT return 0; } - $tempFilename = $tmpDir . '/' . basename($localFilename, '.phar').'-temp'.rand(0, 10000000).'.phar'; + $tempFilename = $tmpDir . '/' . basename($localFilename, '.phar').'-temp'.random_int(0, 10000000).'.phar'; $backupFile = sprintf( '%s/%s-%s%s', $rollbackDir, diff --git a/src/Composer/Compiler.php b/src/Composer/Compiler.php index ab059312f..362deeb34 100644 --- a/src/Composer/Compiler.php +++ b/src/Composer/Compiler.php @@ -204,7 +204,7 @@ class Compiler private function getRelativeFilePath($file) { $realPath = $file->getRealPath(); - $pathPrefix = dirname(dirname(__DIR__)).DIRECTORY_SEPARATOR; + $pathPrefix = dirname(__DIR__, 2).DIRECTORY_SEPARATOR; $pos = strpos($realPath, $pathPrefix); $relativePath = ($pos !== false) ? substr_replace($realPath, '', $pos, strlen($pathPrefix)) : $realPath; diff --git a/src/Composer/Config.php b/src/Composer/Config.php index 06abf6ad0..a83f70175 100644 --- a/src/Composer/Config.php +++ b/src/Composer/Config.php @@ -461,7 +461,7 @@ class Config { $this->get($key); - return isset($this->sourceOfConfigValue[$key]) ? $this->sourceOfConfigValue[$key] : self::SOURCE_UNKNOWN; + return $this->sourceOfConfigValue[$key] ?? self::SOURCE_UNKNOWN; } /** diff --git a/src/Composer/DependencyResolver/Decisions.php b/src/Composer/DependencyResolver/Decisions.php index 6a4809d5d..2df464bc1 100644 --- a/src/Composer/DependencyResolver/Decisions.php +++ b/src/Composer/DependencyResolver/Decisions.php @@ -256,7 +256,7 @@ class Decisions implements \Iterator, \Countable { $packageId = abs($literal); - $previousDecision = isset($this->decisionMap[$packageId]) ? $this->decisionMap[$packageId] : null; + $previousDecision = $this->decisionMap[$packageId] ?? null; if ($previousDecision != 0) { $literalString = $this->pool->literalToPrettyString($literal, array()); $package = $this->pool->literalToPackage($literal); diff --git a/src/Composer/DependencyResolver/PoolBuilder.php b/src/Composer/DependencyResolver/PoolBuilder.php index 2b2240fa7..8ca7050fd 100644 --- a/src/Composer/DependencyResolver/PoolBuilder.php +++ b/src/Composer/DependencyResolver/PoolBuilder.php @@ -376,7 +376,7 @@ class PoolBuilder if ($repository instanceof PlatformRepository || $repository === $request->getLockedRepository()) { continue; } - $result = $repository->loadPackages($packageBatch, $this->acceptableStabilities, $this->stabilityFlags, isset($this->loadedPerRepo[$repoIndex]) ? $this->loadedPerRepo[$repoIndex] : array()); + $result = $repository->loadPackages($packageBatch, $this->acceptableStabilities, $this->stabilityFlags, $this->loadedPerRepo[$repoIndex] ?? array()); foreach ($result['namesFound'] as $name) { // avoid loading the same package again from other repositories once it has been found diff --git a/src/Composer/Downloader/PathDownloader.php b/src/Composer/Downloader/PathDownloader.php index 5482bf43d..74c36f136 100644 --- a/src/Composer/Downloader/PathDownloader.php +++ b/src/Composer/Downloader/PathDownloader.php @@ -260,7 +260,7 @@ class PathDownloader extends FileDownloader implements VcsCapableDownloaderInter $currentStrategy = self::STRATEGY_MIRROR; } - $symlinkOption = isset($transportOptions['symlink']) ? $transportOptions['symlink'] : null; + $symlinkOption = $transportOptions['symlink'] ?? null; if (true === $symlinkOption) { $currentStrategy = self::STRATEGY_SYMLINK; diff --git a/src/Composer/EventDispatcher/EventDispatcher.php b/src/Composer/EventDispatcher/EventDispatcher.php index da4b7708c..29b1f5de7 100644 --- a/src/Composer/EventDispatcher/EventDispatcher.php +++ b/src/Composer/EventDispatcher/EventDispatcher.php @@ -428,10 +428,10 @@ class EventDispatcher if (is_string($params)) { $this->addListener($eventName, array($subscriber, $params)); } elseif (is_string($params[0])) { - $this->addListener($eventName, array($subscriber, $params[0]), isset($params[1]) ? $params[1] : 0); + $this->addListener($eventName, array($subscriber, $params[0]), $params[1] ?? 0); } else { foreach ($params as $listener) { - $this->addListener($eventName, array($subscriber, $listener[0]), isset($listener[1]) ? $listener[1] : 0); + $this->addListener($eventName, array($subscriber, $listener[0]), $listener[1] ?? 0); } } } diff --git a/src/Composer/Factory.php b/src/Composer/Factory.php index e481a801a..5911b6633 100644 --- a/src/Composer/Factory.php +++ b/src/Composer/Factory.php @@ -248,7 +248,7 @@ class Factory */ public static function getComposerFile() { - return trim(Platform::getEnv('COMPOSER')) ?: './composer.json'; + return trim((string) Platform::getEnv('COMPOSER')) ?: './composer.json'; } /** diff --git a/src/Composer/Package/Loader/ArrayLoader.php b/src/Composer/Package/Loader/ArrayLoader.php index bc4a14139..403da9a45 100644 --- a/src/Composer/Package/Loader/ArrayLoader.php +++ b/src/Composer/Package/Loader/ArrayLoader.php @@ -185,7 +185,7 @@ class ArrayLoader implements LoaderInterface } $package->setSourceType($config['source']['type']); $package->setSourceUrl($config['source']['url']); - $package->setSourceReference(isset($config['source']['reference']) ? $config['source']['reference'] : null); + $package->setSourceReference($config['source']['reference'] ?? null); if (isset($config['source']['mirrors'])) { $package->setSourceMirrors($config['source']['mirrors']); } @@ -202,8 +202,8 @@ class ArrayLoader implements LoaderInterface } $package->setDistType($config['dist']['type']); $package->setDistUrl($config['dist']['url']); - $package->setDistReference(isset($config['dist']['reference']) ? $config['dist']['reference'] : null); - $package->setDistSha1Checksum(isset($config['dist']['shasum']) ? $config['dist']['shasum'] : null); + $package->setDistReference($config['dist']['reference'] ?? null); + $package->setDistSha1Checksum($config['dist']['shasum'] ?? null); if (isset($config['dist']['mirrors'])) { $package->setDistMirrors($config['dist']['mirrors']); } diff --git a/src/Composer/Package/Locker.php b/src/Composer/Package/Locker.php index a5c262158..5a306d14d 100644 --- a/src/Composer/Package/Locker.php +++ b/src/Composer/Package/Locker.php @@ -234,7 +234,7 @@ class Locker '__root__', '1.0.0', Link::TYPE_REQUIRE, - isset($lockData['platform']) ? $lockData['platform'] : array() + $lockData['platform'] ?? array() ); } @@ -243,7 +243,7 @@ class Locker '__root__', '1.0.0', Link::TYPE_REQUIRE, - isset($lockData['platform-dev']) ? $lockData['platform-dev'] : array() + $lockData['platform-dev'] ?? array() ); $requirements = array_merge($requirements, $devRequirements); @@ -259,7 +259,7 @@ class Locker { $lockData = $this->getLockData(); - return isset($lockData['minimum-stability']) ? $lockData['minimum-stability'] : 'stable'; + return $lockData['minimum-stability'] ?? 'stable'; } /** @@ -269,7 +269,7 @@ class Locker { $lockData = $this->getLockData(); - return isset($lockData['stability-flags']) ? $lockData['stability-flags'] : array(); + return $lockData['stability-flags'] ?? array(); } /** @@ -281,7 +281,7 @@ class Locker // return null if not set to allow caller logic to choose the // right behavior since old lock files have no prefer-stable - return isset($lockData['prefer-stable']) ? $lockData['prefer-stable'] : null; + return $lockData['prefer-stable'] ?? null; } /** @@ -293,7 +293,7 @@ class Locker // return null if not set to allow caller logic to choose the // right behavior since old lock files have no prefer-lowest - return isset($lockData['prefer-lowest']) ? $lockData['prefer-lowest'] : null; + return $lockData['prefer-lowest'] ?? null; } /** @@ -303,7 +303,7 @@ class Locker { $lockData = $this->getLockData(); - return isset($lockData['platform-overrides']) ? $lockData['platform-overrides'] : array(); + return $lockData['platform-overrides'] ?? array(); } /** @@ -315,7 +315,7 @@ class Locker { $lockData = $this->getLockData(); - return isset($lockData['aliases']) ? $lockData['aliases'] : array(); + return $lockData['aliases'] ?? array(); } /** @@ -442,7 +442,7 @@ class Locker unset($spec['version_normalized']); // always move time to the end of the package definition - $time = isset($spec['time']) ? $spec['time'] : null; + $time = $spec['time'] ?? null; unset($spec['time']); if ($package->isDev() && $package->getInstallationSource() === 'source') { // use the exact commit time of the current reference if it's a dev package diff --git a/src/Composer/Repository/ComposerRepository.php b/src/Composer/Repository/ComposerRepository.php index 3e22df054..8fa6bf03b 100644 --- a/src/Composer/Repository/ComposerRepository.php +++ b/src/Composer/Repository/ComposerRepository.php @@ -623,8 +623,8 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito } $result[$candidate['name']] = array( 'name' => $candidate['name'], - 'description' => isset($candidate['description']) ? $candidate['description'] : '', - 'type' => isset($candidate['type']) ? $candidate['type'] : '', + 'description' => $candidate['description'] ?? '', + 'type' => $candidate['type'] ?? '', ); } } @@ -900,7 +900,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito $lastModified = null; if ($contents = $this->cache->read($cacheKey)) { $contents = json_decode($contents, true); - $lastModified = isset($contents['last-modified']) ? $contents['last-modified'] : null; + $lastModified = $contents['last-modified'] ?? null; } $promises[] = $this->asyncFetchFile($url, $cacheKey, $lastModified) @@ -1275,7 +1275,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito return $packageInstances; } catch (\Exception $e) { - throw new \RuntimeException('Could not load packages '.(isset($packages[0]['name']) ? $packages[0]['name'] : json_encode($packages)).' in '.$this->getRepoName().($source ? ' from '.$source : '').': ['.get_class($e).'] '.$e->getMessage(), 0, $e); + throw new \RuntimeException('Could not load packages '.($packages[0]['name'] ?? json_encode($packages)).' in '.$this->getRepoName().($source ? ' from '.$source : '').': ['.get_class($e).'] '.$e->getMessage(), 0, $e); } } diff --git a/src/Composer/Repository/PathRepository.php b/src/Composer/Repository/PathRepository.php index b531603b6..725a50360 100644 --- a/src/Composer/Repository/PathRepository.php +++ b/src/Composer/Repository/PathRepository.php @@ -120,7 +120,7 @@ class PathRepository extends ArrayRepository implements ConfigurableRepositoryIn $this->process = new ProcessExecutor($io); $this->versionGuesser = new VersionGuesser($config, $this->process, new VersionParser()); $this->repoConfig = $repoConfig; - $this->options = isset($repoConfig['options']) ? $repoConfig['options'] : array(); + $this->options = $repoConfig['options'] ?? array(); if (!isset($this->options['relative'])) { $filesystem = new Filesystem(); $this->options['relative'] = !$filesystem->isAbsolutePath($this->url); diff --git a/src/Composer/Repository/Vcs/VcsDriver.php b/src/Composer/Repository/Vcs/VcsDriver.php index 510e7efe8..b7f7fb976 100644 --- a/src/Composer/Repository/Vcs/VcsDriver.php +++ b/src/Composer/Repository/Vcs/VcsDriver.php @@ -167,7 +167,7 @@ abstract class VcsDriver implements VcsDriverInterface */ protected function getContents($url) { - $options = isset($this->repoConfig['options']) ? $this->repoConfig['options'] : array(); + $options = $this->repoConfig['options'] ?? array(); return $this->httpDownloader->get($url, $options); } diff --git a/src/Composer/Repository/VcsRepository.php b/src/Composer/Repository/VcsRepository.php index 65b4dc281..b5b85cd14 100644 --- a/src/Composer/Repository/VcsRepository.php +++ b/src/Composer/Repository/VcsRepository.php @@ -92,7 +92,7 @@ class VcsRepository extends ArrayRepository implements ConfigurableRepositoryInt $this->url = $repoConfig['url']; $this->io = $io; - $this->type = isset($repoConfig['type']) ? $repoConfig['type'] : 'vcs'; + $this->type = $repoConfig['type'] ?? 'vcs'; $this->isVerbose = $io->isVerbose(); $this->isVeryVerbose = $io->isVeryVerbose(); $this->config = $config; @@ -290,7 +290,7 @@ class VcsRepository extends ArrayRepository implements ConfigurableRepositoryInt continue; } - $tagPackageName = $this->packageName ?: (isset($data['name']) ? $data['name'] : ''); + $tagPackageName = $this->packageName ?: ($data['name'] ?? ''); if ($existingPackage = $this->findPackage($tagPackageName, $data['version_normalized'])) { if ($isVeryVerbose) { $this->io->writeError('Skipped tag '.$tag.', it conflicts with an another tag ('.$existingPackage->getPrettyVersion().') as both resolve to '.$data['version_normalized'].' internally'); @@ -439,7 +439,7 @@ class VcsRepository extends ArrayRepository implements ConfigurableRepositoryInt // keep the name of the main identifier for all packages // this ensures that a package can be renamed in one place and that all old tags // will still be installable using that new name without requiring re-tagging - $dataPackageName = isset($data['name']) ? $data['name'] : null; + $dataPackageName = $data['name'] ?? null; $data['name'] = $this->packageName ?: $dataPackageName; if (!isset($data['dist'])) { diff --git a/src/Composer/Util/ConfigValidator.php b/src/Composer/Util/ConfigValidator.php index aab3e3220..c7447a2a8 100644 --- a/src/Composer/Util/ConfigValidator.php +++ b/src/Composer/Util/ConfigValidator.php @@ -159,8 +159,8 @@ class ConfigValidator } // check for commit references - $require = isset($manifest['require']) ? $manifest['require'] : array(); - $requireDev = isset($manifest['require-dev']) ? $manifest['require-dev'] : array(); + $require = $manifest['require'] ?? array(); + $requireDev = $manifest['require-dev'] ?? array(); $packages = array_merge($require, $requireDev); foreach ($packages as $package => $version) { if (Preg::isMatch('/#/', $version)) { @@ -172,8 +172,8 @@ class ConfigValidator } // report scripts-descriptions for non-existent scripts - $scriptsDescriptions = isset($manifest['scripts-descriptions']) ? $manifest['scripts-descriptions'] : array(); - $scripts = isset($manifest['scripts']) ? $manifest['scripts'] : array(); + $scriptsDescriptions = $manifest['scripts-descriptions'] ?? array(); + $scripts = $manifest['scripts'] ?? array(); foreach ($scriptsDescriptions as $scriptName => $scriptDescription) { if (!array_key_exists($scriptName, $scripts)) { $warnings[] = sprintf( diff --git a/src/Composer/Util/RemoteFilesystem.php b/src/Composer/Util/RemoteFilesystem.php index f07ccf824..28982a8e9 100644 --- a/src/Composer/Util/RemoteFilesystem.php +++ b/src/Composer/Util/RemoteFilesystem.php @@ -91,7 +91,7 @@ class RemoteFilesystem // handle the other externally set options normally. $this->options = array_replace_recursive($this->options, $options); $this->config = $config; - $this->authHelper = isset($authHelper) ? $authHelper : new AuthHelper($io, $config); + $this->authHelper = $authHelper ?? new AuthHelper($io, $config); $this->proxyManager = ProxyManager::getInstance(); } @@ -531,7 +531,7 @@ class RemoteFilesystem } // https://www.php.net/manual/en/reserved.variables.httpresponseheader.php - $responseHeaders = isset($http_response_header) ? $http_response_header : array(); + $responseHeaders = $http_response_header ?? array(); if (null !== $e) { throw $e; diff --git a/tests/Composer/Test/DependencyResolver/PoolOptimizerTest.php b/tests/Composer/Test/DependencyResolver/PoolOptimizerTest.php index 2023811aa..442b156ef 100644 --- a/tests/Composer/Test/DependencyResolver/PoolOptimizerTest.php +++ b/tests/Composer/Test/DependencyResolver/PoolOptimizerTest.php @@ -56,8 +56,8 @@ class PoolOptimizerTest extends TestCase $request->requireName($package, $parser->parseConstraints($constraint)); } - $preferStable = isset($requestData['preferStable']) ? $requestData['preferStable'] : false; - $preferLowest = isset($requestData['preferLowest']) ? $requestData['preferLowest'] : false; + $preferStable = $requestData['preferStable'] ?? false; + $preferLowest = $requestData['preferLowest'] ?? false; $pool = new Pool($packagesBefore); $poolOptimizer = new PoolOptimizer(new DefaultPolicy($preferStable, $preferLowest)); diff --git a/tests/Composer/Test/InstallerTest.php b/tests/Composer/Test/InstallerTest.php index d59e70cf3..c0ea9b1af 100644 --- a/tests/Composer/Test/InstallerTest.php +++ b/tests/Composer/Test/InstallerTest.php @@ -142,9 +142,9 @@ class InstallerTest extends TestCase $output = str_replace("\r", '', $io->getOutput()); $this->assertEquals(0, $result, $output); - $expectedInstalled = isset($options['install']) ? $options['install'] : array(); - $expectedUpdated = isset($options['update']) ? $options['update'] : array(); - $expectedUninstalled = isset($options['uninstall']) ? $options['uninstall'] : array(); + $expectedInstalled = $options['install'] ?? array(); + $expectedUpdated = $options['update'] ?? array(); + $expectedUninstalled = $options['uninstall'] ?? array(); $installed = $installationManager->getInstalledPackages(); $this->assertEquals($this->makePackagesComparable($expectedInstalled), $this->makePackagesComparable($installed)); @@ -575,8 +575,8 @@ class InstallerTest extends TestCase if (!empty($testData['EXPECT-INSTALLED'])) { $expectInstalled = JsonFile::parseJson($testData['EXPECT-INSTALLED']); } - $expectOutput = isset($testData['EXPECT-OUTPUT']) ? $testData['EXPECT-OUTPUT'] : null; - $expectOutputOptimized = isset($testData['EXPECT-OUTPUT-OPTIMIZED']) ? $testData['EXPECT-OUTPUT-OPTIMIZED'] : null; + $expectOutput = $testData['EXPECT-OUTPUT'] ?? null; + $expectOutputOptimized = $testData['EXPECT-OUTPUT-OPTIMIZED'] ?? null; $expect = $testData['EXPECT']; if (!empty($testData['EXPECT-EXCEPTION'])) { $expectResult = $testData['EXPECT-EXCEPTION']; diff --git a/tests/Composer/Test/TestCase.php b/tests/Composer/Test/TestCase.php index 153bad697..e6a171621 100644 --- a/tests/Composer/Test/TestCase.php +++ b/tests/Composer/Test/TestCase.php @@ -73,7 +73,7 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase $root = sys_get_temp_dir(); do { - $unique = $root . DIRECTORY_SEPARATOR . uniqid('composer-test-' . rand(1000, 9000)); + $unique = $root . DIRECTORY_SEPARATOR . uniqid('composer-test-' . random_int(1000, 9000)); if (!file_exists($unique) && Silencer::call('mkdir', $unique, 0777)) { return realpath($unique);