diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index 5cbe9de..6c1fd54 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -11,7 +11,7 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: ref: ${{ github.event.pull_request.head.ref }} fetch-depth: 0 @@ -34,7 +34,7 @@ jobs: - name: Cache Composer packages if: github.event_name == 'pull_request' id: composer-cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: vendor key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} diff --git a/Module.php b/Module.php index ea7cc01..f20b151 100644 --- a/Module.php +++ b/Module.php @@ -13,32 +13,6 @@ class Module extends BaseModule */ public $resourcesPath = 'resources'; - // Define the namespace for web controllers - public $controllerNamespace = 'humhub\modules\composer\controllers'; - - // Define the namespace for console commands - public $commandNamespace = 'humhub\modules\composer\commands'; - - public function init() - { - parent::init(); - if (Yii::$app instanceof \yii\console\Application) { - // Set controller namespace to default web controllers namespace for console application - $this->controllerNamespace = 'humhub\modules\composer\controllers'; - // Define console command mappings - $this->controllerMap = [ - 'theme' => 'humhub\modules\composer\commands\ThemeController', - ]; - } - } - - public function actions() - { - return [ - 'theme/compile' => 'humhub\modules\composer\commands\ThemeController', - ]; - } - /** * @inheritdoc */ diff --git a/commands/ThemeController.php b/commands/ThemeController.php deleted file mode 100644 index 3cbbcbe..0000000 --- a/commands/ThemeController.php +++ /dev/null @@ -1,98 +0,0 @@ -stderr("Error: Theme '$themeName' not found.\n", \yii\helpers\Console::FG_RED); - return self::EXIT_CODE_ERROR; - } - - // Get the path to the specified theme's directory - $themePath = $themes[$themeName]->getBasePath(); - - // Define the paths for the LESS and CSS files - $lessDir = "$themePath/less"; - $cssFile = "$themePath/css/theme.css"; - $cssFileDark = "$themePath/css/dark/dark.css"; - - // Modify variables in the build.less file for dark theme - $buildLessContent = file_get_contents("$lessDir/build.less"); - $buildLessContent = str_replace( - ['@background-color: #ffffff;', '@text-color: #000000;'], - ['@background-color: #000000;', '@text-color: #ffffff;'], - $buildLessContent - ); - file_put_contents("$lessDir/build.less", $buildLessContent); - - // Get the path to the lessc binary - $lesscBinary = Yii::getAlias('@app/modules/composer/vendor/oyejorge/less.php/bin/lessc'); - - // Execute lessc command to compile the LESS files into CSS files for light theme - $lesscCommand = "$lesscBinary $lessDir/build.less $cssFile"; - exec($lesscCommand, $output, $returnVar); - - // Check if the compilation for light theme was successful - if ($returnVar !== 0) { - $this->stderr("Error: Compilation for light theme failed.\n", \yii\helpers\Console::FG_RED); - return self::EXIT_CODE_ERROR; - } - - // Execute lessc command to compile the LESS files into CSS files for dark theme - $lesscCommandDark = "$lesscBinary $lessDir/build.less $cssFileDark"; - exec($lesscCommandDark, $outputDark, $returnVarDark); - - // Check if the compilation for dark theme was successful - if ($returnVarDark !== 0) { - $this->stderr("Error: Compilation for dark theme failed.\n", \yii\helpers\Console::FG_RED); - return self::EXIT_CODE_ERROR; - } - - // Restore the original content of build.less - $buildLessContentOriginal = str_replace( - ['@background-color: #000000;', '@text-color: #ffffff;'], - ['@background-color: #ffffff;', '@text-color: #000000;'], - $buildLessContent - ); - file_put_contents("$lessDir/build.less", $buildLessContentOriginal); - - // Clear caches - Yii::$app->cache->flush(); - - // Output success message - $this->stdout("Theme '$themeName' compiled successfully for both light and dark themes, and cache cleared.\n", \yii\helpers\Console::FG_GREEN); - - return self::EXIT_CODE_NORMAL; - } -} diff --git a/composer.json b/composer.json index 55c7997..7112d61 100644 --- a/composer.json +++ b/composer.json @@ -12,8 +12,7 @@ "require": { "php": "^8.2", "symfony/process": "^7.1", - "composer/installers": "^2.2", - "oyejorge/less.php": "^1.7" + "composer/installers": "^2.2" }, "require-dev": { "composer/composer": "^2.7" @@ -29,9 +28,9 @@ "type": "package", "package": { "name": "gruntjs/grunt", - "version": "1.4.1", + "version": "1.6.1", "dist": { - "url": "https://registry.npmjs.org/grunt/-/grunt-1.4.1.tgz", + "url": "https://registry.npmjs.org/grunt/-/grunt-1.6.1.tgz", "type": "tar" }, "autoload": { diff --git a/composer.lock b/composer.lock index b1084a1..12af300 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "2c442c443255fac888b09b282486465f", + "content-hash": "4cf8b4ab6f6cbde8a3c92565d186e310", "packages": [ { "name": "composer/installers", @@ -152,73 +152,6 @@ ], "time": "2024-06-24T20:46:46+00:00" }, - { - "name": "oyejorge/less.php", - "version": "v1.7.0.14", - "source": { - "type": "git", - "url": "https://github.com/oyejorge/less.php.git", - "reference": "42925c5a01a07d67ca7e82dfc8fb31814d557bc9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/oyejorge/less.php/zipball/42925c5a01a07d67ca7e82dfc8fb31814d557bc9", - "reference": "42925c5a01a07d67ca7e82dfc8fb31814d557bc9", - "shasum": "" - }, - "require": { - "php": ">=5.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.8.24" - }, - "bin": [ - "bin/lessc" - ], - "type": "library", - "autoload": { - "psr-0": { - "Less": "lib/" - }, - "classmap": [ - "lessc.inc.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "Matt Agar", - "homepage": "https://github.com/agar" - }, - { - "name": "Martin Jantošovič", - "homepage": "https://github.com/Mordred" - }, - { - "name": "Josh Schmidt", - "homepage": "https://github.com/oyejorge" - } - ], - "description": "PHP port of the Javascript version of LESS http://lesscss.org (Originally maintained by Josh Schmidt)", - "homepage": "http://lessphp.gpeasy.com", - "keywords": [ - "css", - "less", - "less.js", - "lesscss", - "php", - "stylesheet" - ], - "support": { - "issues": "https://github.com/oyejorge/less.php/issues", - "source": "https://github.com/oyejorge/less.php/tree/master" - }, - "abandoned": true, - "time": "2017-03-28T22:19:25+00:00" - }, { "name": "symfony/process", "version": "v7.1.5", @@ -2347,12 +2280,12 @@ ], "aliases": [], "minimum-stability": "dev", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": true, "prefer-lowest": false, "platform": { "php": "^8.2" }, - "platform-dev": [], - "plugin-api-version": "2.3.0" + "platform-dev": {}, + "plugin-api-version": "2.6.0" } diff --git a/controllers/GruntController.php b/controllers/GruntController.php index b8dee45..996c8af 100644 --- a/controllers/GruntController.php +++ b/controllers/GruntController.php @@ -46,26 +46,6 @@ public function actionBuildAssets() } } - /** - * Builds a theme using Grunt. - * - * @param string|null $themeName The name of the theme to build. - * @return string The rendering result. - */ - public function actionBuildTheme() - { - $themeName = Yii::$app->request->post('themeName'); - - if ($themeName === null) { - throw new \yii\web\BadRequestHttpException('Theme name cannot be null.'); - } - - $gruntService = new GruntService(); - $output = $gruntService->buildTheme($themeName); - - return $this->asJson(['success' => true, 'output' => $output]); - } - /** * Builds the search index using Grunt. * diff --git a/package.json b/package.json index 614594c..bdf6e2d 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,9 @@ { "name": "greenmeteor/composer", - "version": "1.0.0", + "version": "1.0.1", "description": "Update your Composer installed HumHub instance", "scripts": { "grunt-build-assets": "grunt build-assets", - "grunt-build-theme": "grunt build-theme", "grunt-build-search": "grunt build-search", "grunt-migrate-up": "grunt migrate-up" }, @@ -14,8 +13,8 @@ }, "license": "AGPL-3.0-or-later", "devDependencies": { - "grunt": "^1.4.1", - "grunt-cli": "^1.4.3", - "symfony/process": "^5.0" + "grunt": "^1.6.1", + "grunt-cli": "^1.5.0", + "symfony/process": "^7.1" } -} \ No newline at end of file +} diff --git a/services/GruntService.php b/services/GruntService.php index 1ab7f3b..33e4d0c 100644 --- a/services/GruntService.php +++ b/services/GruntService.php @@ -14,7 +14,6 @@ class GruntService * Executes a Grunt command and returns the output. * * @param string $command The Grunt command to execute. - * @param string|null $themeName The name of the theme to build (optional). * @return array The output of the Grunt command. * @throws \yii\web\ForbiddenHttpException If the user is not allowed to perform this action. * @throws \yii\web\ServerErrorHttpException If the working directory is invalid. @@ -63,17 +62,6 @@ public function buildAssets(): array return $this->executeCommand('build-assets'); } - /** - * Builds a theme using Grunt. - * - * @param string $themeName The name of the theme to build. - * @return array The output of the Grunt build-theme command. - */ - public function buildTheme(string $themeName): array - { - return $this->executeCommand('build-theme', $themeName); - } - /** * Builds the search index using Grunt. * diff --git a/vendor/bin/composer b/vendor/bin/composer old mode 100644 new mode 100755 index b8ca913..fd55d73 --- a/vendor/bin/composer +++ b/vendor/bin/composer @@ -112,9 +112,8 @@ if (PHP_VERSION_ID < 80000) { (function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true)) || (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) ) { - include("phpvfscomposer://" . __DIR__ . '/..'.'/composer/composer/bin/composer'); - exit(0); + return include("phpvfscomposer://" . __DIR__ . '/..'.'/composer/composer/bin/composer'); } } -include __DIR__ . '/..'.'/composer/composer/bin/composer'; +return include __DIR__ . '/..'.'/composer/composer/bin/composer'; diff --git a/vendor/bin/jsonlint b/vendor/bin/jsonlint old mode 100644 new mode 100755 index b8170cf..ca6e04d --- a/vendor/bin/jsonlint +++ b/vendor/bin/jsonlint @@ -112,9 +112,8 @@ if (PHP_VERSION_ID < 80000) { (function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true)) || (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) ) { - include("phpvfscomposer://" . __DIR__ . '/..'.'/seld/jsonlint/bin/jsonlint'); - exit(0); + return include("phpvfscomposer://" . __DIR__ . '/..'.'/seld/jsonlint/bin/jsonlint'); } } -include __DIR__ . '/..'.'/seld/jsonlint/bin/jsonlint'; +return include __DIR__ . '/..'.'/seld/jsonlint/bin/jsonlint'; diff --git a/vendor/bin/lessc b/vendor/bin/lessc deleted file mode 100644 index a718641..0000000 --- a/vendor/bin/lessc +++ /dev/null @@ -1,120 +0,0 @@ -#!/usr/bin/env php -realpath = realpath($opened_path) ?: $opened_path; - $opened_path = $this->realpath; - $this->handle = fopen($this->realpath, $mode); - $this->position = 0; - - return (bool) $this->handle; - } - - public function stream_read($count) - { - $data = fread($this->handle, $count); - - if ($this->position === 0) { - $data = preg_replace('{^#!.*\r?\n}', '', $data); - } - - $this->position += strlen($data); - - return $data; - } - - public function stream_cast($castAs) - { - return $this->handle; - } - - public function stream_close() - { - fclose($this->handle); - } - - public function stream_lock($operation) - { - return $operation ? flock($this->handle, $operation) : true; - } - - public function stream_seek($offset, $whence) - { - if (0 === fseek($this->handle, $offset, $whence)) { - $this->position = ftell($this->handle); - return true; - } - - return false; - } - - public function stream_tell() - { - return $this->position; - } - - public function stream_eof() - { - return feof($this->handle); - } - - public function stream_stat() - { - return array(); - } - - public function stream_set_option($option, $arg1, $arg2) - { - return true; - } - - public function url_stat($path, $flags) - { - $path = substr($path, 17); - if (file_exists($path)) { - return stat($path); - } - - return false; - } - } - } - - if ( - (function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true)) - || (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) - ) { - include("phpvfscomposer://" . __DIR__ . '/..'.'/oyejorge/less.php/bin/lessc'); - exit(0); - } -} - -include __DIR__ . '/..'.'/oyejorge/less.php/bin/lessc'; diff --git a/vendor/bin/validate-json b/vendor/bin/validate-json old mode 100644 new mode 100755 index d077db5..8be90f4 --- a/vendor/bin/validate-json +++ b/vendor/bin/validate-json @@ -112,9 +112,8 @@ if (PHP_VERSION_ID < 80000) { (function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true)) || (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) ) { - include("phpvfscomposer://" . __DIR__ . '/..'.'/justinrainbow/json-schema/bin/validate-json'); - exit(0); + return include("phpvfscomposer://" . __DIR__ . '/..'.'/justinrainbow/json-schema/bin/validate-json'); } } -include __DIR__ . '/..'.'/justinrainbow/json-schema/bin/validate-json'; +return include __DIR__ . '/..'.'/justinrainbow/json-schema/bin/validate-json'; diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php index afef3fa..7824d8f 100644 --- a/vendor/composer/ClassLoader.php +++ b/vendor/composer/ClassLoader.php @@ -42,35 +42,37 @@ */ class ClassLoader { - /** @var ?string */ + /** @var \Closure(string):void */ + private static $includeFile; + + /** @var string|null */ private $vendorDir; // PSR-4 /** - * @var array[] - * @psalm-var array> + * @var array> */ private $prefixLengthsPsr4 = array(); /** - * @var array[] - * @psalm-var array> + * @var array> */ private $prefixDirsPsr4 = array(); /** - * @var array[] - * @psalm-var array + * @var list */ private $fallbackDirsPsr4 = array(); // PSR-0 /** - * @var array[] - * @psalm-var array> + * List of PSR-0 prefixes + * + * Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2'))) + * + * @var array>> */ private $prefixesPsr0 = array(); /** - * @var array[] - * @psalm-var array + * @var list */ private $fallbackDirsPsr0 = array(); @@ -78,8 +80,7 @@ class ClassLoader private $useIncludePath = false; /** - * @var string[] - * @psalm-var array + * @var array */ private $classMap = array(); @@ -87,29 +88,29 @@ class ClassLoader private $classMapAuthoritative = false; /** - * @var bool[] - * @psalm-var array + * @var array */ private $missingClasses = array(); - /** @var ?string */ + /** @var string|null */ private $apcuPrefix; /** - * @var self[] + * @var array */ private static $registeredLoaders = array(); /** - * @param ?string $vendorDir + * @param string|null $vendorDir */ public function __construct($vendorDir = null) { $this->vendorDir = $vendorDir; + self::initializeIncludeClosure(); } /** - * @return string[] + * @return array> */ public function getPrefixes() { @@ -121,8 +122,7 @@ public function getPrefixes() } /** - * @return array[] - * @psalm-return array> + * @return array> */ public function getPrefixesPsr4() { @@ -130,8 +130,7 @@ public function getPrefixesPsr4() } /** - * @return array[] - * @psalm-return array + * @return list */ public function getFallbackDirs() { @@ -139,8 +138,7 @@ public function getFallbackDirs() } /** - * @return array[] - * @psalm-return array + * @return list */ public function getFallbackDirsPsr4() { @@ -148,8 +146,7 @@ public function getFallbackDirsPsr4() } /** - * @return string[] Array of classname => path - * @psalm-return array + * @return array Array of classname => path */ public function getClassMap() { @@ -157,8 +154,7 @@ public function getClassMap() } /** - * @param string[] $classMap Class to filename map - * @psalm-param array $classMap + * @param array $classMap Class to filename map * * @return void */ @@ -175,24 +171,25 @@ public function addClassMap(array $classMap) * Registers a set of PSR-0 directories for a given prefix, either * appending or prepending to the ones previously set for this prefix. * - * @param string $prefix The prefix - * @param string[]|string $paths The PSR-0 root directories - * @param bool $prepend Whether to prepend the directories + * @param string $prefix The prefix + * @param list|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories * * @return void */ public function add($prefix, $paths, $prepend = false) { + $paths = (array) $paths; if (!$prefix) { if ($prepend) { $this->fallbackDirsPsr0 = array_merge( - (array) $paths, + $paths, $this->fallbackDirsPsr0 ); } else { $this->fallbackDirsPsr0 = array_merge( $this->fallbackDirsPsr0, - (array) $paths + $paths ); } @@ -201,19 +198,19 @@ public function add($prefix, $paths, $prepend = false) $first = $prefix[0]; if (!isset($this->prefixesPsr0[$first][$prefix])) { - $this->prefixesPsr0[$first][$prefix] = (array) $paths; + $this->prefixesPsr0[$first][$prefix] = $paths; return; } if ($prepend) { $this->prefixesPsr0[$first][$prefix] = array_merge( - (array) $paths, + $paths, $this->prefixesPsr0[$first][$prefix] ); } else { $this->prefixesPsr0[$first][$prefix] = array_merge( $this->prefixesPsr0[$first][$prefix], - (array) $paths + $paths ); } } @@ -222,9 +219,9 @@ public function add($prefix, $paths, $prepend = false) * Registers a set of PSR-4 directories for a given namespace, either * appending or prepending to the ones previously set for this namespace. * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param string[]|string $paths The PSR-4 base directories - * @param bool $prepend Whether to prepend the directories + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param list|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories * * @throws \InvalidArgumentException * @@ -232,17 +229,18 @@ public function add($prefix, $paths, $prepend = false) */ public function addPsr4($prefix, $paths, $prepend = false) { + $paths = (array) $paths; if (!$prefix) { // Register directories for the root namespace. if ($prepend) { $this->fallbackDirsPsr4 = array_merge( - (array) $paths, + $paths, $this->fallbackDirsPsr4 ); } else { $this->fallbackDirsPsr4 = array_merge( $this->fallbackDirsPsr4, - (array) $paths + $paths ); } } elseif (!isset($this->prefixDirsPsr4[$prefix])) { @@ -252,18 +250,18 @@ public function addPsr4($prefix, $paths, $prepend = false) throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); } $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; - $this->prefixDirsPsr4[$prefix] = (array) $paths; + $this->prefixDirsPsr4[$prefix] = $paths; } elseif ($prepend) { // Prepend directories for an already registered namespace. $this->prefixDirsPsr4[$prefix] = array_merge( - (array) $paths, + $paths, $this->prefixDirsPsr4[$prefix] ); } else { // Append directories for an already registered namespace. $this->prefixDirsPsr4[$prefix] = array_merge( $this->prefixDirsPsr4[$prefix], - (array) $paths + $paths ); } } @@ -272,8 +270,8 @@ public function addPsr4($prefix, $paths, $prepend = false) * Registers a set of PSR-0 directories for a given prefix, * replacing any others previously set for this prefix. * - * @param string $prefix The prefix - * @param string[]|string $paths The PSR-0 base directories + * @param string $prefix The prefix + * @param list|string $paths The PSR-0 base directories * * @return void */ @@ -290,8 +288,8 @@ public function set($prefix, $paths) * Registers a set of PSR-4 directories for a given namespace, * replacing any others previously set for this namespace. * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param string[]|string $paths The PSR-4 base directories + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param list|string $paths The PSR-4 base directories * * @throws \InvalidArgumentException * @@ -425,7 +423,8 @@ public function unregister() public function loadClass($class) { if ($file = $this->findFile($class)) { - includeFile($file); + $includeFile = self::$includeFile; + $includeFile($file); return true; } @@ -476,9 +475,9 @@ public function findFile($class) } /** - * Returns the currently registered loaders indexed by their corresponding vendor directories. + * Returns the currently registered loaders keyed by their corresponding vendor directories. * - * @return self[] + * @return array */ public static function getRegisteredLoaders() { @@ -555,18 +554,26 @@ private function findFileWithExtension($class, $ext) return false; } -} -/** - * Scope isolated include. - * - * Prevents access to $this/self from included files. - * - * @param string $file - * @return void - * @private - */ -function includeFile($file) -{ - include $file; + /** + * @return void + */ + private static function initializeIncludeClosure() + { + if (self::$includeFile !== null) { + return; + } + + /** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + * + * @param string $file + * @return void + */ + self::$includeFile = \Closure::bind(static function($file) { + include $file; + }, null, null); + } } diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php index c6b54af..51e734a 100644 --- a/vendor/composer/InstalledVersions.php +++ b/vendor/composer/InstalledVersions.php @@ -98,7 +98,7 @@ public static function isInstalled($packageName, $includeDevRequirements = true) { foreach (self::getInstalled() as $installed) { if (isset($installed['versions'][$packageName])) { - return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']); + return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false; } } @@ -119,7 +119,7 @@ public static function isInstalled($packageName, $includeDevRequirements = true) */ public static function satisfies(VersionParser $parser, $packageName, $constraint) { - $constraint = $parser->parseConstraints($constraint); + $constraint = $parser->parseConstraints((string) $constraint); $provided = $parser->parseConstraints(self::getVersionRanges($packageName)); return $provided->matches($constraint); @@ -328,7 +328,9 @@ private static function getInstalled() if (isset(self::$installedByVendor[$vendorDir])) { $installed[] = self::$installedByVendor[$vendorDir]; } elseif (is_file($vendorDir.'/composer/installed.php')) { - $installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php'; + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = require $vendorDir.'/composer/installed.php'; + $installed[] = self::$installedByVendor[$vendorDir] = $required; if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { self::$installed = $installed[count($installed) - 1]; } @@ -340,12 +342,17 @@ private static function getInstalled() // only require the installed.php file if this file is loaded from its dumped location, // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 if (substr(__DIR__, -8, 1) !== 'C') { - self::$installed = require __DIR__ . '/installed.php'; + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = require __DIR__ . '/installed.php'; + self::$installed = $required; } else { self::$installed = array(); } } - $installed[] = self::$installed; + + if (self::$installed !== array()) { + $installed[] = self::$installed; + } return $installed; } diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 24a9355..ac6b399 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -16,5 +16,4 @@ 'Stringable' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Stringable.php', 'UnhandledMatchError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php', 'ValueError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/ValueError.php', - 'lessc' => $vendorDir . '/oyejorge/less.php/lessc.inc.php', ); diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php index ef72ee2..e041d46 100644 --- a/vendor/composer/autoload_files.php +++ b/vendor/composer/autoload_files.php @@ -8,12 +8,12 @@ return array( '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', '320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php', + '6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php', '8825ede83f2f289127722d4e842cf7e8' => $vendorDir . '/symfony/polyfill-intl-grapheme/bootstrap.php', 'e69f7f6ee287b969198c3c9d6777bd38' => $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php', - 'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php', - '6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php', 'b6b991a57620e2fb6b2f66f03fe9ddc2' => $vendorDir . '/symfony/string/Resources/functions.php', 'ad155f8f1cf0d418fe49e248db8c661b' => $vendorDir . '/react/promise/src/functions_include.php', '0d59ee240a4cd96ddbb4ff164fccea4d' => $vendorDir . '/symfony/polyfill-php73/bootstrap.php', + 'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php', '23c18046f52bef3eea034657bafda50f' => $vendorDir . '/symfony/polyfill-php81/bootstrap.php', ); diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php index ad45484..15a2ff3 100644 --- a/vendor/composer/autoload_namespaces.php +++ b/vendor/composer/autoload_namespaces.php @@ -6,5 +6,4 @@ $baseDir = dirname($vendorDir); return array( - 'Less' => array($vendorDir . '/oyejorge/less.php/lib'), ); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index dae47fd..f476087 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -33,25 +33,18 @@ public static function getLoader() $loader->register(true); - $includeFiles = \Composer\Autoload\ComposerStaticInit36415fde8bca83fb5a9697ecee092d83::$files; - foreach ($includeFiles as $fileIdentifier => $file) { - composerRequire36415fde8bca83fb5a9697ecee092d83($fileIdentifier, $file); + $filesToLoad = \Composer\Autoload\ComposerStaticInit36415fde8bca83fb5a9697ecee092d83::$files; + $requireFile = \Closure::bind(static function ($fileIdentifier, $file) { + if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { + $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; + + require $file; + } + }, null, null); + foreach ($filesToLoad as $fileIdentifier => $file) { + $requireFile($fileIdentifier, $file); } return $loader; } } - -/** - * @param string $fileIdentifier - * @param string $file - * @return void - */ -function composerRequire36415fde8bca83fb5a9697ecee092d83($fileIdentifier, $file) -{ - if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { - $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; - - require $file; - } -} diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 0247489..47d6e8f 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -9,13 +9,13 @@ class ComposerStaticInit36415fde8bca83fb5a9697ecee092d83 public static $files = array ( '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php', + '6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php', '8825ede83f2f289127722d4e842cf7e8' => __DIR__ . '/..' . '/symfony/polyfill-intl-grapheme/bootstrap.php', 'e69f7f6ee287b969198c3c9d6777bd38' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/bootstrap.php', - 'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php', - '6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php', 'b6b991a57620e2fb6b2f66f03fe9ddc2' => __DIR__ . '/..' . '/symfony/string/Resources/functions.php', 'ad155f8f1cf0d418fe49e248db8c661b' => __DIR__ . '/..' . '/react/promise/src/functions_include.php', '0d59ee240a4cd96ddbb4ff164fccea4d' => __DIR__ . '/..' . '/symfony/polyfill-php73/bootstrap.php', + 'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php', '23c18046f52bef3eea034657bafda50f' => __DIR__ . '/..' . '/symfony/polyfill-php81/bootstrap.php', ); @@ -185,16 +185,6 @@ class ComposerStaticInit36415fde8bca83fb5a9697ecee092d83 ), ); - public static $prefixesPsr0 = array ( - 'L' => - array ( - 'Less' => - array ( - 0 => __DIR__ . '/..' . '/oyejorge/less.php/lib', - ), - ), - ); - public static $classMap = array ( 'Attribute' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Attribute.php', 'CURLStringFile' => __DIR__ . '/..' . '/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php', @@ -206,7 +196,6 @@ class ComposerStaticInit36415fde8bca83fb5a9697ecee092d83 'Stringable' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Stringable.php', 'UnhandledMatchError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php', 'ValueError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/ValueError.php', - 'lessc' => __DIR__ . '/..' . '/oyejorge/less.php/lessc.inc.php', ); public static function getInitializer(ClassLoader $loader) @@ -214,7 +203,6 @@ public static function getInitializer(ClassLoader $loader) return \Closure::bind(function () use ($loader) { $loader->prefixLengthsPsr4 = ComposerStaticInit36415fde8bca83fb5a9697ecee092d83::$prefixLengthsPsr4; $loader->prefixDirsPsr4 = ComposerStaticInit36415fde8bca83fb5a9697ecee092d83::$prefixDirsPsr4; - $loader->prefixesPsr0 = ComposerStaticInit36415fde8bca83fb5a9697ecee092d83::$prefixesPsr0; $loader->classMap = ComposerStaticInit36415fde8bca83fb5a9697ecee092d83::$classMap; }, null, ClassLoader::class); diff --git a/vendor/composer/ca-bundle/composer.json b/vendor/composer/ca-bundle/composer.json index a998783..c2ce2bb 100644 --- a/vendor/composer/ca-bundle/composer.json +++ b/vendor/composer/ca-bundle/composer.json @@ -27,9 +27,9 @@ "php": "^7.2 || ^8.0" }, "require-dev": { - "symfony/phpunit-bridge": "^4.2 || ^5", + "phpunit/phpunit": "^8 || ^9", "phpstan/phpstan": "^1.10", - "psr/log": "^1.0", + "psr/log": "^1.0 || ^2.0 || ^3.0", "symfony/process": "^4.0 || ^5.0 || ^6.0 || ^7.0" }, "autoload": { @@ -48,7 +48,7 @@ } }, "scripts": { - "test": "vendor/bin/simple-phpunit", - "phpstan": "vendor/bin/phpstan analyse" + "test": "@php phpunit", + "phpstan": "@php phpstan analyse" } } diff --git a/vendor/composer/ca-bundle/res/cacert.pem b/vendor/composer/ca-bundle/res/cacert.pem index f78a610..f2c24a5 100644 --- a/vendor/composer/ca-bundle/res/cacert.pem +++ b/vendor/composer/ca-bundle/res/cacert.pem @@ -1,7 +1,9 @@ ## ## Bundle of CA Root Certificates ## -## Certificate data from Mozilla as of: Mon Mar 11 15:25:27 2024 GMT +## Certificate data from Mozilla as of: Tue Sep 24 03:12:04 2024 GMT +## +## Find updated versions here: https://curl.se/docs/caextract.html ## ## This is a bundle of X.509 certificates of public Certificate Authorities ## (CA). These were automatically extracted from Mozilla's root certificates @@ -14,7 +16,7 @@ ## Just configure this file as the SSLCACertificateFile. ## ## Conversion done with mk-ca-bundle.pl version 1.29. -## SHA256: 4d96bd539f4719e9ace493757afbe4a23ee8579de1c97fbebc50bba3c12e8c1e +## SHA256: 36105b01631f9fc03b1eca779b44a30a1a5890b9bf8dc07ccb001a07301e01cf ## @@ -2600,36 +2602,6 @@ vLtoURMMA/cVi4RguYv/Uo7njLwcAjA8+RHUjE7AwWHCFUyqqx0LMV87HOIAl0Qx5v5zli/altP+ CAezNIm8BZ/3Hobui3A= -----END CERTIFICATE----- -GLOBALTRUST 2020 -================ ------BEGIN CERTIFICATE----- -MIIFgjCCA2qgAwIBAgILWku9WvtPilv6ZeUwDQYJKoZIhvcNAQELBQAwTTELMAkGA1UEBhMCQVQx -IzAhBgNVBAoTGmUtY29tbWVyY2UgbW9uaXRvcmluZyBHbWJIMRkwFwYDVQQDExBHTE9CQUxUUlVT -VCAyMDIwMB4XDTIwMDIxMDAwMDAwMFoXDTQwMDYxMDAwMDAwMFowTTELMAkGA1UEBhMCQVQxIzAh -BgNVBAoTGmUtY29tbWVyY2UgbW9uaXRvcmluZyBHbWJIMRkwFwYDVQQDExBHTE9CQUxUUlVTVCAy -MDIwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAri5WrRsc7/aVj6B3GyvTY4+ETUWi -D59bRatZe1E0+eyLinjF3WuvvcTfk0Uev5E4C64OFudBc/jbu9G4UeDLgztzOG53ig9ZYybNpyrO -VPu44sB8R85gfD+yc/LAGbaKkoc1DZAoouQVBGM+uq/ufF7MpotQsjj3QWPKzv9pj2gOlTblzLmM -CcpL3TGQlsjMH/1WljTbjhzqLL6FLmPdqqmV0/0plRPwyJiT2S0WR5ARg6I6IqIoV6Lr/sCMKKCm -fecqQjuCgGOlYx8ZzHyyZqjC0203b+J+BlHZRYQfEs4kUmSFC0iAToexIiIwquuuvuAC4EDosEKA -A1GqtH6qRNdDYfOiaxaJSaSjpCuKAsR49GiKweR6NrFvG5Ybd0mN1MkGco/PU+PcF4UgStyYJ9OR -JitHHmkHr96i5OTUawuzXnzUJIBHKWk7buis/UDr2O1xcSvy6Fgd60GXIsUf1DnQJ4+H4xj04KlG -DfV0OoIu0G4skaMxXDtG6nsEEFZegB31pWXogvziB4xiRfUg3kZwhqG8k9MedKZssCz3AwyIDMvU -clOGvGBG85hqwvG/Q/lwIHfKN0F5VVJjjVsSn8VoxIidrPIwq7ejMZdnrY8XD2zHc+0klGvIg5rQ -mjdJBKuxFshsSUktq6HQjJLyQUp5ISXbY9e2nKd+Qmn7OmMCAwEAAaNjMGEwDwYDVR0TAQH/BAUw -AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFNwuH9FhN3nkq9XVsxJxaD1qaJwiMB8GA1Ud -IwQYMBaAFNwuH9FhN3nkq9XVsxJxaD1qaJwiMA0GCSqGSIb3DQEBCwUAA4ICAQCR8EICaEDuw2jA -VC/f7GLDw56KoDEoqoOOpFaWEhCGVrqXctJUMHytGdUdaG/7FELYjQ7ztdGl4wJCXtzoRlgHNQIw -4Lx0SsFDKv/bGtCwr2zD/cuz9X9tAy5ZVp0tLTWMstZDFyySCstd6IwPS3BD0IL/qMy/pJTAvoe9 -iuOTe8aPmxadJ2W8esVCgmxcB9CpwYhgROmYhRZf+I/KARDOJcP5YBugxZfD0yyIMaK9MOzQ0MAS -8cE54+X1+NZK3TTN+2/BT+MAi1bikvcoskJ3ciNnxz8RFbLEAwW+uxF7Cr+obuf/WEPPm2eggAe2 -HcqtbepBEX4tdJP7wry+UUTF72glJ4DjyKDUEuzZpTcdN3y0kcra1LGWge9oXHYQSa9+pTeAsRxS -vTOBTI/53WXZFM2KJVj04sWDpQmQ1GwUY7VA3+vA/MRYfg0UFodUJ25W5HCEuGwyEn6CMUO+1918 -oa2u1qsgEu8KwxCMSZY13At1XrFP1U80DhEgB3VDRemjEdqso5nCtnkn4rnvyOL2NSl6dPrFf4IF -YqYK6miyeUcGbvJXqBUzxvd4Sj1Ce2t+/vdG6tHrju+IaFvowdlxfv1k7/9nR4hYJS8+hge9+6jl -gqispdNpQ80xiEmEU5LAsTkbOYMBMMTyqfrQA71yN2BWHzZ8vTmR9W0Nv3vXkg== ------END CERTIFICATE----- - ANF Secure Server Root CA ========================= -----BEGIN CERTIFICATE----- @@ -3579,3 +3551,116 @@ wPfc5+pbrrLMtTWGS9DiP7bY+A4A7l3j941Y/8+LN+ljX273CXE2whJdV/LItM3z7gLfEdxquVeE HVlNjM7IDiPCtyaaEBRx/pOyiriA8A4QntOoUAw3gi/q4Iqd4Sw5/7W0cwDk90imc6y/st53BIe0 o82bNSQ3+pCTE4FCxpgmdTdmQRCsu/WU48IxK63nI1bMNSWSs1A= -----END CERTIFICATE----- + +FIRMAPROFESIONAL CA ROOT-A WEB +============================== +-----BEGIN CERTIFICATE----- +MIICejCCAgCgAwIBAgIQMZch7a+JQn81QYehZ1ZMbTAKBggqhkjOPQQDAzBuMQswCQYDVQQGEwJF +UzEcMBoGA1UECgwTRmlybWFwcm9mZXNpb25hbCBTQTEYMBYGA1UEYQwPVkFURVMtQTYyNjM0MDY4 +MScwJQYDVQQDDB5GSVJNQVBST0ZFU0lPTkFMIENBIFJPT1QtQSBXRUIwHhcNMjIwNDA2MDkwMTM2 +WhcNNDcwMzMxMDkwMTM2WjBuMQswCQYDVQQGEwJFUzEcMBoGA1UECgwTRmlybWFwcm9mZXNpb25h +bCBTQTEYMBYGA1UEYQwPVkFURVMtQTYyNjM0MDY4MScwJQYDVQQDDB5GSVJNQVBST0ZFU0lPTkFM +IENBIFJPT1QtQSBXRUIwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARHU+osEaR3xyrq89Zfe9MEkVz6 +iMYiuYMQYneEMy3pA4jU4DP37XcsSmDq5G+tbbT4TIqk5B/K6k84Si6CcyvHZpsKjECcfIr28jlg +st7L7Ljkb+qbXbdTkBgyVcUgt5SjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUk+FD +Y1w8ndYn81LsF7Kpryz3dvgwHQYDVR0OBBYEFJPhQ2NcPJ3WJ/NS7Beyqa8s93b4MA4GA1UdDwEB +/wQEAwIBBjAKBggqhkjOPQQDAwNoADBlAjAdfKR7w4l1M+E7qUW/Runpod3JIha3RxEL2Jq68cgL +cFBTApFwhVmpHqTm6iMxoAACMQD94vizrxa5HnPEluPBMBnYfubDl94cT7iJLzPrSA8Z94dGXSaQ +pYXFuXqUPoeovQA= +-----END CERTIFICATE----- + +TWCA CYBER Root CA +================== +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIQQAE0jMIAAAAAAAAAATzyxjANBgkqhkiG9w0BAQwFADBQMQswCQYDVQQG +EwJUVzESMBAGA1UEChMJVEFJV0FOLUNBMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJUV0NB +IENZQkVSIFJvb3QgQ0EwHhcNMjIxMTIyMDY1NDI5WhcNNDcxMTIyMTU1OTU5WjBQMQswCQYDVQQG +EwJUVzESMBAGA1UEChMJVEFJV0FOLUNBMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJUV0NB +IENZQkVSIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDG+Moe2Qkgfh1s +Ts6P40czRJzHyWmqOlt47nDSkvgEs1JSHWdyKKHfi12VCv7qze33Kc7wb3+szT3vsxxFavcokPFh +V8UMxKNQXd7UtcsZyoC5dc4pztKFIuwCY8xEMCDa6pFbVuYdHNWdZsc/34bKS1PE2Y2yHer43CdT +o0fhYcx9tbD47nORxc5zb87uEB8aBs/pJ2DFTxnk684iJkXXYJndzk834H/nY62wuFm40AZoNWDT +Nq5xQwTxaWV4fPMf88oon1oglWa0zbfuj3ikRRjpJi+NmykosaS3Om251Bw4ckVYsV7r8Cibt4LK +/c/WMw+f+5eesRycnupfXtuq3VTpMCEobY5583WSjCb+3MX2w7DfRFlDo7YDKPYIMKoNM+HvnKkH +IuNZW0CP2oi3aQiotyMuRAlZN1vH4xfyIutuOVLF3lSnmMlLIJXcRolftBL5hSmO68gnFSDAS9TM +fAxsNAwmmyYxpjyn9tnQS6Jk/zuZQXLB4HCX8SS7K8R0IrGsayIyJNN4KsDAoS/xUgXJP+92ZuJF +2A09rZXIx4kmyA+upwMu+8Ff+iDhcK2wZSA3M2Cw1a/XDBzCkHDXShi8fgGwsOsVHkQGzaRP6AzR +wyAQ4VRlnrZR0Bp2a0JaWHY06rc3Ga4udfmW5cFZ95RXKSWNOkyrTZpB0F8mAwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBSdhWEUfMFib5do5E83 +QOGt4A1WNzAdBgNVHQ4EFgQUnYVhFHzBYm+XaORPN0DhreANVjcwDQYJKoZIhvcNAQEMBQADggIB +AGSPesRiDrWIzLjHhg6hShbNcAu3p4ULs3a2D6f/CIsLJc+o1IN1KriWiLb73y0ttGlTITVX1olN +c79pj3CjYcya2x6a4CD4bLubIp1dhDGaLIrdaqHXKGnK/nZVekZn68xDiBaiA9a5F/gZbG0jAn/x +X9AKKSM70aoK7akXJlQKTcKlTfjF/biBzysseKNnTKkHmvPfXvt89YnNdJdhEGoHK4Fa0o635yDR +IG4kqIQnoVesqlVYL9zZyvpoBJ7tRCT5dEA7IzOrg1oYJkK2bVS1FmAwbLGg+LhBoF1JSdJlBTrq +/p1hvIbZv97Tujqxf36SNI7JAG7cmL3c7IAFrQI932XtCwP39xaEBDG6k5TY8hL4iuO/Qq+n1M0R +FxbIQh0UqEL20kCGoE8jypZFVmAGzbdVAaYBlGX+bgUJurSkquLvWL69J1bY73NxW0Qz8ppy6rBe +Pm6pUlvscG21h483XjyMnM7k8M4MZ0HMzvaAq07MTFb1wWFZk7Q+ptq4NxKfKjLji7gh7MMrZQzv +It6IKTtM1/r+t+FHvpw+PoP7UV31aPcuIYXcv/Fa4nzXxeSDwWrruoBa3lwtcHb4yOWHh8qgnaHl +IhInD0Q9HWzq1MKLL295q39QpsQZp6F6t5b5wR9iWqJDB0BeJsas7a5wFsWqynKKTbDPAYsDP27X +-----END CERTIFICATE----- + +SecureSign Root CA12 +==================== +-----BEGIN CERTIFICATE----- +MIIDcjCCAlqgAwIBAgIUZvnHwa/swlG07VOX5uaCwysckBYwDQYJKoZIhvcNAQELBQAwUTELMAkG +A1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28uLCBMdGQuMR0wGwYDVQQDExRT +ZWN1cmVTaWduIFJvb3QgQ0ExMjAeFw0yMDA0MDgwNTM2NDZaFw00MDA0MDgwNTM2NDZaMFExCzAJ +BgNVBAYTAkpQMSMwIQYDVQQKExpDeWJlcnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMU +U2VjdXJlU2lnbiBSb290IENBMTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6OcE3 +emhFKxS06+QT61d1I02PJC0W6K6OyX2kVzsqdiUzg2zqMoqUm048luT9Ub+ZyZN+v/mtp7JIKwcc +J/VMvHASd6SFVLX9kHrko+RRWAPNEHl57muTH2SOa2SroxPjcf59q5zdJ1M3s6oYwlkm7Fsf0uZl +fO+TvdhYXAvA42VvPMfKWeP+bl+sg779XSVOKik71gurFzJ4pOE+lEa+Ym6b3kaosRbnhW70CEBF +EaCeVESE99g2zvVQR9wsMJvuwPWW0v4JhscGWa5Pro4RmHvzC1KqYiaqId+OJTN5lxZJjfU+1Uef +NzFJM3IFTQy2VYzxV4+Kh9GtxRESOaCtAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P +AQH/BAQDAgEGMB0GA1UdDgQWBBRXNPN0zwRL1SXm8UC2LEzZLemgrTANBgkqhkiG9w0BAQsFAAOC +AQEAPrvbFxbS8hQBICw4g0utvsqFepq2m2um4fylOqyttCg6r9cBg0krY6LdmmQOmFxv3Y67ilQi +LUoT865AQ9tPkbeGGuwAtEGBpE/6aouIs3YIcipJQMPTw4WJmBClnW8Zt7vPemVV2zfrPIpyMpce +mik+rY3moxtt9XUa5rBouVui7mlHJzWhhpmA8zNL4WukJsPvdFlseqJkth5Ew1DgDzk9qTPxpfPS +vWKErI4cqc1avTc7bgoitPQV55FYxTpE05Uo2cBl6XLK0A+9H7MV2anjpEcJnuDLN/v9vZfVvhga +aaI5gdka9at/yOPiZwud9AzqVN/Ssq+xIvEg37xEHA== +-----END CERTIFICATE----- + +SecureSign Root CA14 +==================== +-----BEGIN CERTIFICATE----- +MIIFcjCCA1qgAwIBAgIUZNtaDCBO6Ncpd8hQJ6JaJ90t8sswDQYJKoZIhvcNAQEMBQAwUTELMAkG +A1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28uLCBMdGQuMR0wGwYDVQQDExRT +ZWN1cmVTaWduIFJvb3QgQ0ExNDAeFw0yMDA0MDgwNzA2MTlaFw00NTA0MDgwNzA2MTlaMFExCzAJ +BgNVBAYTAkpQMSMwIQYDVQQKExpDeWJlcnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMU +U2VjdXJlU2lnbiBSb290IENBMTQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDF0nqh +1oq/FjHQmNE6lPxauG4iwWL3pwon71D2LrGeaBLwbCRjOfHw3xDG3rdSINVSW0KZnvOgvlIfX8xn +bacuUKLBl422+JX1sLrcneC+y9/3OPJH9aaakpUqYllQC6KxNedlsmGy6pJxaeQp8E+BgQQ8sqVb +1MWoWWd7VRxJq3qdwudzTe/NCcLEVxLbAQ4jeQkHO6Lo/IrPj8BGJJw4J+CDnRugv3gVEOuGTgpa +/d/aLIJ+7sr2KeH6caH3iGicnPCNvg9JkdjqOvn90Ghx2+m1K06Ckm9mH+Dw3EzsytHqunQG+bOE +kJTRX45zGRBdAuVwpcAQ0BB8b8VYSbSwbprafZX1zNoCr7gsfXmPvkPx+SgojQlD+Ajda8iLLCSx +jVIHvXiby8posqTdDEx5YMaZ0ZPxMBoH064iwurO8YQJzOAUbn8/ftKChazcqRZOhaBgy/ac18iz +ju3Gm5h1DVXoX+WViwKkrkMpKBGk5hIwAUt1ax5mnXkvpXYvHUC0bcl9eQjs0Wq2XSqypWa9a4X0 +dFbD9ed1Uigspf9mR6XU/v6eVL9lfgHWMI+lNpyiUBzuOIABSMbHdPTGrMNASRZhdCyvjG817XsY +AFs2PJxQDcqSMxDxJklt33UkN4Ii1+iW/RVLApY+B3KVfqs9TC7XyvDf4Fg/LS8EmjijAQIDAQAB +o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUBpOjCl4oaTeq +YR3r6/wtbyPk86AwDQYJKoZIhvcNAQEMBQADggIBAJaAcgkGfpzMkwQWu6A6jZJOtxEaCnFxEM0E +rX+lRVAQZk5KQaID2RFPeje5S+LGjzJmdSX7684/AykmjbgWHfYfM25I5uj4V7Ibed87hwriZLoA +ymzvftAj63iP/2SbNDefNWWipAA9EiOWWF3KY4fGoweITedpdopTzfFP7ELyk+OZpDc8h7hi2/Ds +Hzc/N19DzFGdtfCXwreFamgLRB7lUe6TzktuhsHSDCRZNhqfLJGP4xjblJUK7ZGqDpncllPjYYPG +FrojutzdfhrGe0K22VoF3Jpf1d+42kd92jjbrDnVHmtsKheMYc2xbXIBw8MgAGJoFjHVdqqGuw6q +nsb58Nn4DSEC5MUoFlkRudlpcyqSeLiSV5sI8jrlL5WwWLdrIBRtFO8KvH7YVdiI2i/6GaX7i+B/ +OfVyK4XELKzvGUWSTLNhB9xNH27SgRNcmvMSZ4PPmz+Ln52kuaiWA3rF7iDeM9ovnhp6dB7h7sxa +OgTdsxoEqBRjrLdHEoOabPXm6RUVkRqEGQ6UROcSjiVbgGcZ3GOTEAtlLor6CZpO2oYofaphNdgO +pygau1LgePhsumywbrmHXumZNTfxPWQrqaA0k89jL9WB365jJ6UeTo3cKXhZ+PmhIIynJkBugnLN +eLLIjzwec+fBH7/PzqUqm9tEZDKgu39cJRNItX+S +-----END CERTIFICATE----- + +SecureSign Root CA15 +==================== +-----BEGIN CERTIFICATE----- +MIICIzCCAamgAwIBAgIUFhXHw9hJp75pDIqI7fBw+d23PocwCgYIKoZIzj0EAwMwUTELMAkGA1UE +BhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28uLCBMdGQuMR0wGwYDVQQDExRTZWN1 +cmVTaWduIFJvb3QgQ0ExNTAeFw0yMDA0MDgwODMyNTZaFw00NTA0MDgwODMyNTZaMFExCzAJBgNV +BAYTAkpQMSMwIQYDVQQKExpDeWJlcnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMUU2Vj +dXJlU2lnbiBSb290IENBMTUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQLUHSNZDKZmbPSYAi4Io5G +dCx4wCtELW1fHcmuS1Iggz24FG1Th2CeX2yF2wYUleDHKP+dX+Sq8bOLbe1PL0vJSpSRZHX+AezB +2Ot6lHhWGENfa4HL9rzatAy2KZMIaY+jQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMB0GA1UdDgQWBBTrQciu/NWeUUj1vYv0hyCTQSvT9DAKBggqhkjOPQQDAwNoADBlAjEA2S6J +fl5OpBEHvVnCB96rMjhTKkZEBhd6zlHp4P9mLQlO4E/0BdGF9jVg3PVys0Z9AjBEmEYagoUeYWmJ +SwdLZrWeqrqgHkHZAXQ6bkU6iYAZezKYVWOr62Nuk22rGwlgMU4= +-----END CERTIFICATE----- diff --git a/vendor/composer/class-map-generator/composer.json b/vendor/composer/class-map-generator/composer.json index 59aa759..8d22b72 100644 --- a/vendor/composer/class-map-generator/composer.json +++ b/vendor/composer/class-map-generator/composer.json @@ -19,7 +19,7 @@ "composer/pcre": "^2.1 || ^3.1" }, "require-dev": { - "symfony/phpunit-bridge": "^5", + "phpunit/phpunit": "^8", "phpstan/phpstan": "^1.6", "phpstan/phpstan-deprecation-rules": "^1", "phpstan/phpstan-strict-rules": "^1.1", @@ -42,7 +42,7 @@ } }, "scripts": { - "test": "SYMFONY_PHPUNIT_REMOVE_RETURN_TYPEHINT=1 vendor/bin/simple-phpunit", - "phpstan": "phpstan analyse" + "test": "@php phpunit", + "phpstan": "@php phpstan analyse" } } diff --git a/vendor/composer/class-map-generator/src/ClassMap.php b/vendor/composer/class-map-generator/src/ClassMap.php index d6e2899..0d06366 100644 --- a/vendor/composer/class-map-generator/src/ClassMap.php +++ b/vendor/composer/class-map-generator/src/ClassMap.php @@ -12,6 +12,8 @@ namespace Composer\ClassMapGenerator; +use Composer\Pcre\Preg; + /** * @author Jordi Boggiano */ @@ -28,7 +30,7 @@ class ClassMap implements \Countable private $ambiguousClasses = []; /** - * @var string[] + * @var array> */ private $psrViolations = []; @@ -55,7 +57,13 @@ public function getMap(): array */ public function getPsrViolations(): array { - return $this->psrViolations; + if (\count($this->psrViolations) === 0) { + return []; + } + + return array_map(static function (array $violation): string { + return $violation['warning']; + }, array_merge(...array_values($this->psrViolations))); } /** @@ -65,11 +73,36 @@ public function getPsrViolations(): array * * To get the path the class is being mapped to, call getClassPath * + * By default, paths that contain test(s), fixture(s), example(s) or stub(s) are ignored + * as those are typically not problematic when they're dummy classes in the tests folder. + * If you want to get these back as well you can pass false to $duplicatesFilter. Or + * you can pass your own pattern to exclude if you need to change the default. + * + * @param non-empty-string|false $duplicatesFilter + * * @return array> */ - public function getAmbiguousClasses(): array + public function getAmbiguousClasses($duplicatesFilter = '{/(test|fixture|example|stub)s?/}i'): array { - return $this->ambiguousClasses; + if (false === $duplicatesFilter) { + return $this->ambiguousClasses; + } + + if (true === $duplicatesFilter) { + throw new \InvalidArgumentException('$duplicatesFilter should be false or a string with a valid regex, got true.'); + } + + $ambiguousClasses = []; + foreach ($this->ambiguousClasses as $class => $paths) { + $paths = array_filter($paths, function ($path) use ($duplicatesFilter) { + return !Preg::isMatch($duplicatesFilter, strtr($path, '\\', '/')); + }); + if (\count($paths) > 0) { + $ambiguousClasses[$class] = array_values($paths); + } + } + + return $ambiguousClasses; } /** @@ -86,6 +119,8 @@ public function sort(): void */ public function addClass(string $className, string $path): void { + unset($this->psrViolations[strtr($path, '\\', '/')]); + $this->map[$className] = $path; } @@ -110,9 +145,22 @@ public function hasClass(string $className): bool return isset($this->map[$className]); } - public function addPsrViolation(string $warning): void + public function addPsrViolation(string $warning, string $className, string $path): void { - $this->psrViolations[] = $warning; + $path = rtrim(strtr($path, '\\', '/'), '/'); + + $this->psrViolations[$path][] = ['warning' => $warning, 'className' => $className]; + } + + public function clearPsrViolationsByPath(string $pathPrefix): void + { + $pathPrefix = rtrim(strtr($pathPrefix, '\\', '/'), '/'); + + foreach ($this->psrViolations as $path => $violations) { + if ($path === $pathPrefix || 0 === \strpos($path, $pathPrefix.'/')) { + unset($this->psrViolations[$path]); + } + } } /** diff --git a/vendor/composer/class-map-generator/src/ClassMapGenerator.php b/vendor/composer/class-map-generator/src/ClassMapGenerator.php index 53f9a42..8f040e0 100644 --- a/vendor/composer/class-map-generator/src/ClassMapGenerator.php +++ b/vendor/composer/class-map-generator/src/ClassMapGenerator.php @@ -97,10 +97,11 @@ public function getClassMap(): ClassMap * @param non-empty-string|null $excluded Regex that matches file paths to be excluded from the classmap * @param 'classmap'|'psr-0'|'psr-4' $autoloadType Optional autoload standard to use mapping rules with the namespace instead of purely doing a classmap * @param string|null $namespace Optional namespace prefix to filter by, only for psr-0/psr-4 autoloading + * @param array $excludedDirs Optional dirs to exclude from search relative to $path * * @throws \RuntimeException When the path is neither an existing file nor directory */ - public function scanPaths($path, ?string $excluded = null, string $autoloadType = 'classmap', ?string $namespace = null): void + public function scanPaths($path, ?string $excluded = null, string $autoloadType = 'classmap', ?string $namespace = null, array $excludedDirs = []): void { if (!in_array($autoloadType, ['psr-0', 'psr-4', 'classmap'], true)) { throw new \InvalidArgumentException('$autoloadType must be one of: "psr-0", "psr-4" or "classmap"'); @@ -124,7 +125,8 @@ public function scanPaths($path, ?string $excluded = null, string $autoloadType ->files() ->followLinks() ->name('/\.(?:'.implode('|', array_map('preg_quote', $this->extensions)).')$/') - ->in($path); + ->in($path) + ->exclude($excludedDirs); } else { throw new \RuntimeException( 'Could not scan for classes inside "'.$path.'" which does not appear to be a file nor a folder' @@ -189,7 +191,7 @@ public function scanPaths($path, ?string $excluded = null, string $autoloadType foreach ($classes as $class) { if (!$this->classMap->hasClass($class)) { $this->classMap->addClass($class, $filePath); - } elseif ($filePath !== $this->classMap->getClassPath($class) && !Preg::isMatch('{/(test|fixture|example|stub)s?/}i', strtr($this->classMap->getClassPath($class).' '.$filePath, '\\', '/'))) { + } elseif ($filePath !== $this->classMap->getClassPath($class)) { $this->classMap->addAmbiguousClass($class, $filePath); } } @@ -216,10 +218,6 @@ private function filterByNamespace(array $classes, string $filePath, string $bas $realSubPath = substr($realSubPath, 0, $dotPosition === false ? PHP_INT_MAX : $dotPosition); foreach ($classes as $class) { - // silently skip if ns doesn't have common root - if ('' !== $baseNamespace && 0 !== strpos($class, $baseNamespace)) { - continue; - } // transform class name to file path and validate if ('psr-0' === $namespaceType) { $namespaceLength = strrpos($class, '\\'); @@ -245,8 +243,16 @@ private function filterByNamespace(array $classes, string $filePath, string $bas } // warn only if no valid classes, else silently skip invalid if (\count($validClasses) === 0) { + $cwd = realpath(self::getCwd()); + if ($cwd === false) { + $cwd = self::getCwd(); + } + $cwd = self::normalizePath($cwd); + $shortPath = Preg::replace('{^'.preg_quote($cwd).'}', '.', self::normalizePath($filePath), 1); + $shortBasePath = Preg::replace('{^'.preg_quote($cwd).'}', '.', self::normalizePath($basePath), 1); + foreach ($rejectedClasses as $class) { - $this->classMap->addPsrViolation("Class $class located in ".Preg::replace('{^'.preg_quote(self::getCwd()).'}', '.', $filePath, 1)." does not comply with $namespaceType autoloading standard. Skipping."); + $this->classMap->addPsrViolation("Class $class located in $shortPath does not comply with $namespaceType autoloading standard (rule: $baseNamespace => $shortBasePath). Skipping.", $class, $filePath); } return []; diff --git a/vendor/composer/class-map-generator/src/PhpFileParser.php b/vendor/composer/class-map-generator/src/PhpFileParser.php index b678aee..78622de 100644 --- a/vendor/composer/class-map-generator/src/PhpFileParser.php +++ b/vendor/composer/class-map-generator/src/PhpFileParser.php @@ -63,8 +63,8 @@ public static function findClasses(string $path): array Preg::matchAll('{ (?: - \b(?])(?Pclass|interface|trait'.$extraTypes.') \s++ (?P[a-zA-Z_\x7f-\xff:][a-zA-Z0-9_\x7f-\xff:\-]*+) - | \b(?])(?Pnamespace) (?P\s++[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+(?:\s*+\\\\\s*+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+)*+)? \s*+ [\{;] + \b(?])(?Pclass|interface|trait'.$extraTypes.') \s++ (?P[a-zA-Z_\x7f-\xff:][a-zA-Z0-9_\x7f-\xff:\-]*+) + | \b(?])(?Pnamespace) (?P\s++[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+(?:\s*+\\\\\s*+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+)*+)? \s*+ [\{;] ) }ix', $contents, $matches); @@ -118,7 +118,10 @@ private static function getExtraTypes(): string $extraTypes .= '|enum'; } - PhpFileCleaner::setTypeConfig(array_merge(['class', 'interface', 'trait'], array_filter(explode('|', $extraTypes)))); + $extraTypesArray = array_filter(explode('|', $extraTypes), function (string $type) { + return $type !== ''; + }); + PhpFileCleaner::setTypeConfig(array_merge(['class', 'interface', 'trait'], $extraTypesArray)); } return $extraTypes; diff --git a/vendor/composer/composer/bin/compile b/vendor/composer/composer/bin/compile old mode 100644 new mode 100755 diff --git a/vendor/composer/composer/bin/composer b/vendor/composer/composer/bin/composer old mode 100644 new mode 100755 diff --git a/vendor/composer/composer/composer.json b/vendor/composer/composer/composer.json index 2cbcfa7..a943cd7 100644 --- a/vendor/composer/composer/composer.json +++ b/vendor/composer/composer/composer.json @@ -23,34 +23,34 @@ ], "require": { "php": "^7.2.5 || ^8.0", - "composer/ca-bundle": "^1.0", - "composer/class-map-generator": "^1.0", + "composer/ca-bundle": "^1.5", + "composer/class-map-generator": "^1.4.0", "composer/metadata-minifier": "^1.0", - "composer/semver": "^3.2.5", + "composer/semver": "^3.3", "composer/spdx-licenses": "^1.5.7", "composer/xdebug-handler": "^2.0.2 || ^3.0.3", - "justinrainbow/json-schema": "^5.2.11", + "justinrainbow/json-schema": "^5.3", "psr/log": "^1.0 || ^2.0 || ^3.0", "seld/jsonlint": "^1.4", "seld/phar-utils": "^1.2", - "symfony/console": "^5.4.11 || ^6.0.11 || ^7", - "symfony/filesystem": "^5.4 || ^6.0 || ^7", - "symfony/finder": "^5.4 || ^6.0 || ^7", - "symfony/process": "^5.4 || ^6.0 || ^7", - "react/promise": "^2.8 || ^3", - "composer/pcre": "^2.1 || ^3.1", + "symfony/console": "^5.4.35 || ^6.3.12 || ^7.0.3", + "symfony/filesystem": "^5.4.35 || ^6.3.12 || ^7.0.3", + "symfony/finder": "^5.4.35 || ^6.3.12 || ^7.0.3", + "symfony/process": "^5.4.35 || ^6.3.12 || ^7.0.3", + "react/promise": "^3.2", + "composer/pcre": "^2.2 || ^3.2", "symfony/polyfill-php73": "^1.24", "symfony/polyfill-php80": "^1.24", "symfony/polyfill-php81": "^1.24", "seld/signal-handler": "^2.0" }, "require-dev": { - "symfony/phpunit-bridge": "^6.4.1 || ^7.0.1", - "phpstan/phpstan": "^1.9.3", - "phpstan/phpstan-phpunit": "^1.0", - "phpstan/phpstan-deprecation-rules": "^1", - "phpstan/phpstan-strict-rules": "^1", - "phpstan/phpstan-symfony": "^1.2.10" + "symfony/phpunit-bridge": "^6.4.3 || ^7.0.1", + "phpstan/phpstan": "^1.11.8", + "phpstan/phpstan-phpunit": "^1.4.0", + "phpstan/phpstan-deprecation-rules": "^1.2.0", + "phpstan/phpstan-strict-rules": "^1.6.0", + "phpstan/phpstan-symfony": "^1.4.0" }, "suggest": { "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages", @@ -65,7 +65,7 @@ }, "extra": { "branch-alias": { - "dev-main": "2.7-dev" + "dev-main": "2.8-dev" }, "phpstan": { "includes": [ @@ -81,7 +81,13 @@ "autoload-dev": { "psr-4": { "Composer\\Test\\": "tests/Composer/Test/" - } + }, + "exclude-from-classmap": [ + "tests/Composer/Test/Fixtures/", + "tests/Composer/Test/Autoload/Fixtures", + "tests/Composer/Test/Autoload/MinimumVersionSupport", + "tests/Composer/Test/Plugin/Fixtures" + ] }, "bin": [ "bin/composer" diff --git a/vendor/composer/composer/composer.lock b/vendor/composer/composer/composer.lock index 5127fa4..770ebda 100644 --- a/vendor/composer/composer/composer.lock +++ b/vendor/composer/composer/composer.lock @@ -4,32 +4,32 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "bbb9ffc97dcec54f38fdc5b4bf9a287d", + "content-hash": "7c2f8d4d04b8146b2fcd203cb81fa8d5", "packages": [ { "name": "composer/ca-bundle", - "version": "1.4.1", + "version": "1.5.2", "source": { "type": "git", "url": "https://github.com/composer/ca-bundle.git", - "reference": "3ce240142f6d59b808dd65c1f52f7a1c252e6cfd" + "reference": "48a792895a2b7a6ee65dd5442c299d7b835b6137" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/ca-bundle/zipball/3ce240142f6d59b808dd65c1f52f7a1c252e6cfd", - "reference": "3ce240142f6d59b808dd65c1f52f7a1c252e6cfd", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/48a792895a2b7a6ee65dd5442c299d7b835b6137", + "reference": "48a792895a2b7a6ee65dd5442c299d7b835b6137", "shasum": "" }, "require": { "ext-openssl": "*", "ext-pcre": "*", - "php": "^5.3.2 || ^7.0 || ^8.0" + "php": "^7.2 || ^8.0" }, "require-dev": { - "phpstan/phpstan": "^0.12.55", - "psr/log": "^1.0", - "symfony/phpunit-bridge": "^4.2 || ^5", - "symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0" + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^8 || ^9", + "psr/log": "^1.0 || ^2.0 || ^3.0", + "symfony/process": "^4.0 || ^5.0 || ^6.0 || ^7.0" }, "type": "library", "extra": { @@ -64,7 +64,7 @@ "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/ca-bundle/issues", - "source": "https://github.com/composer/ca-bundle/tree/1.4.1" + "source": "https://github.com/composer/ca-bundle/tree/1.5.2" }, "funding": [ { @@ -80,20 +80,20 @@ "type": "tidelift" } ], - "time": "2024-02-23T10:16:52+00:00" + "time": "2024-09-25T07:49:53+00:00" }, { "name": "composer/class-map-generator", - "version": "1.1.0", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/composer/class-map-generator.git", - "reference": "953cc4ea32e0c31f2185549c7d216d7921f03da9" + "reference": "98bbf6780e56e0fd2404fe4b82eb665a0f93b783" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/class-map-generator/zipball/953cc4ea32e0c31f2185549c7d216d7921f03da9", - "reference": "953cc4ea32e0c31f2185549c7d216d7921f03da9", + "url": "https://api.github.com/repos/composer/class-map-generator/zipball/98bbf6780e56e0fd2404fe4b82eb665a0f93b783", + "reference": "98bbf6780e56e0fd2404fe4b82eb665a0f93b783", "shasum": "" }, "require": { @@ -106,8 +106,8 @@ "phpstan/phpstan-deprecation-rules": "^1", "phpstan/phpstan-phpunit": "^1", "phpstan/phpstan-strict-rules": "^1.1", - "symfony/filesystem": "^5.4 || ^6", - "symfony/phpunit-bridge": "^5" + "phpunit/phpunit": "^8", + "symfony/filesystem": "^5.4 || ^6" }, "type": "library", "extra": { @@ -137,7 +137,7 @@ ], "support": { "issues": "https://github.com/composer/class-map-generator/issues", - "source": "https://github.com/composer/class-map-generator/tree/1.1.0" + "source": "https://github.com/composer/class-map-generator/tree/1.4.0" }, "funding": [ { @@ -153,7 +153,7 @@ "type": "tidelift" } ], - "time": "2023-06-30T13:58:57+00:00" + "time": "2024-10-03T18:14:00+00:00" }, { "name": "composer/metadata-minifier", @@ -226,30 +226,38 @@ }, { "name": "composer/pcre", - "version": "2.1.2", + "version": "2.3.1", "source": { "type": "git", "url": "https://github.com/composer/pcre.git", - "reference": "02b8774a434b1b71edd8824440ceac1e3e49ee2b" + "reference": "26859a860a7f140fc08422c3cc14ad9c2a287d79" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/02b8774a434b1b71edd8824440ceac1e3e49ee2b", - "reference": "02b8774a434b1b71edd8824440ceac1e3e49ee2b", + "url": "https://api.github.com/repos/composer/pcre/zipball/26859a860a7f140fc08422c3cc14ad9c2a287d79", + "reference": "26859a860a7f140fc08422c3cc14ad9c2a287d79", "shasum": "" }, "require": { "php": "^7.2 || ^8.0" }, + "conflict": { + "phpstan/phpstan": "<1.11.10" + }, "require-dev": { - "phpstan/phpstan": "^1.3", + "phpstan/phpstan": "^1.11.10", "phpstan/phpstan-strict-rules": "^1.1", - "symfony/phpunit-bridge": "^5" + "phpunit/phpunit": "^8 || ^9" }, "type": "library", "extra": { "branch-alias": { "dev-main": "2.x-dev" + }, + "phpstan": { + "includes": [ + "extension.neon" + ] } }, "autoload": { @@ -277,7 +285,7 @@ ], "support": { "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/2.1.2" + "source": "https://github.com/composer/pcre/tree/2.3.1" }, "funding": [ { @@ -293,28 +301,28 @@ "type": "tidelift" } ], - "time": "2024-03-07T14:52:56+00:00" + "time": "2024-08-27T12:02:26+00:00" }, { "name": "composer/semver", - "version": "3.4.0", + "version": "3.4.3", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32" + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/35e8d0af4486141bc745f23a29cc2091eb624a32", - "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32", + "url": "https://api.github.com/repos/composer/semver/zipball/4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", "shasum": "" }, "require": { "php": "^5.3.2 || ^7.0 || ^8.0" }, "require-dev": { - "phpstan/phpstan": "^1.4", - "symfony/phpunit-bridge": "^4.2 || ^5" + "phpstan/phpstan": "^1.11", + "symfony/phpunit-bridge": "^3 || ^7" }, "type": "library", "extra": { @@ -358,7 +366,7 @@ "support": { "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.4.0" + "source": "https://github.com/composer/semver/tree/3.4.3" }, "funding": [ { @@ -374,7 +382,7 @@ "type": "tidelift" } ], - "time": "2023-08-31T09:50:34+00:00" + "time": "2024-09-19T14:15:21+00:00" }, { "name": "composer/spdx-licenses", @@ -458,16 +466,16 @@ }, { "name": "composer/xdebug-handler", - "version": "3.0.3", + "version": "3.0.5", "source": { "type": "git", "url": "https://github.com/composer/xdebug-handler.git", - "reference": "ced299686f41dce890debac69273b47ffe98a40c" + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c", - "reference": "ced299686f41dce890debac69273b47ffe98a40c", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef", "shasum": "" }, "require": { @@ -478,7 +486,7 @@ "require-dev": { "phpstan/phpstan": "^1.0", "phpstan/phpstan-strict-rules": "^1.1", - "symfony/phpunit-bridge": "^6.0" + "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5" }, "type": "library", "autoload": { @@ -502,9 +510,9 @@ "performance" ], "support": { - "irc": "irc://irc.freenode.org/composer", + "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/xdebug-handler/issues", - "source": "https://github.com/composer/xdebug-handler/tree/3.0.3" + "source": "https://github.com/composer/xdebug-handler/tree/3.0.5" }, "funding": [ { @@ -520,24 +528,24 @@ "type": "tidelift" } ], - "time": "2022-02-25T21:32:43+00:00" + "time": "2024-05-06T16:37:16+00:00" }, { "name": "justinrainbow/json-schema", - "version": "v5.2.13", + "version": "5.3.0", "source": { "type": "git", - "url": "https://github.com/justinrainbow/json-schema.git", - "reference": "fbbe7e5d79f618997bc3332a6f49246036c45793" + "url": "https://github.com/jsonrainbow/json-schema.git", + "reference": "feb2ca6dd1cebdaf1ed60a4c8de2e53ce11c4fd8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/fbbe7e5d79f618997bc3332a6f49246036c45793", - "reference": "fbbe7e5d79f618997bc3332a6f49246036c45793", + "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/feb2ca6dd1cebdaf1ed60a4c8de2e53ce11c4fd8", + "reference": "feb2ca6dd1cebdaf1ed60a4c8de2e53ce11c4fd8", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "require-dev": { "friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1", @@ -548,11 +556,6 @@ "bin/validate-json" ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0.x-dev" - } - }, "autoload": { "psr-4": { "JsonSchema\\": "src/JsonSchema/" @@ -587,10 +590,10 @@ "schema" ], "support": { - "issues": "https://github.com/justinrainbow/json-schema/issues", - "source": "https://github.com/justinrainbow/json-schema/tree/v5.2.13" + "issues": "https://github.com/jsonrainbow/json-schema/issues", + "source": "https://github.com/jsonrainbow/json-schema/tree/5.3.0" }, - "time": "2023-09-26T02:20:38+00:00" + "time": "2024-07-06T21:00:26+00:00" }, { "name": "psr/container", @@ -692,16 +695,16 @@ }, { "name": "react/promise", - "version": "v3.1.0", + "version": "v3.2.0", "source": { "type": "git", "url": "https://github.com/reactphp/promise.git", - "reference": "e563d55d1641de1dea9f5e84f3cccc66d2bfe02c" + "reference": "8a164643313c71354582dc850b42b33fa12a4b63" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/reactphp/promise/zipball/e563d55d1641de1dea9f5e84f3cccc66d2bfe02c", - "reference": "e563d55d1641de1dea9f5e84f3cccc66d2bfe02c", + "url": "https://api.github.com/repos/reactphp/promise/zipball/8a164643313c71354582dc850b42b33fa12a4b63", + "reference": "8a164643313c71354582dc850b42b33fa12a4b63", "shasum": "" }, "require": { @@ -753,7 +756,7 @@ ], "support": { "issues": "https://github.com/reactphp/promise/issues", - "source": "https://github.com/reactphp/promise/tree/v3.1.0" + "source": "https://github.com/reactphp/promise/tree/v3.2.0" }, "funding": [ { @@ -761,27 +764,27 @@ "type": "open_collective" } ], - "time": "2023-11-16T16:21:57+00:00" + "time": "2024-05-24T10:39:05+00:00" }, { "name": "seld/jsonlint", - "version": "1.10.2", + "version": "1.11.0", "source": { "type": "git", "url": "https://github.com/Seldaek/jsonlint.git", - "reference": "9bb7db07b5d66d90f6ebf542f09fc67d800e5259" + "reference": "1748aaf847fc731cfad7725aec413ee46f0cc3a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/9bb7db07b5d66d90f6ebf542f09fc67d800e5259", - "reference": "9bb7db07b5d66d90f6ebf542f09fc67d800e5259", + "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/1748aaf847fc731cfad7725aec413ee46f0cc3a2", + "reference": "1748aaf847fc731cfad7725aec413ee46f0cc3a2", "shasum": "" }, "require": { "php": "^5.3 || ^7.0 || ^8.0" }, "require-dev": { - "phpstan/phpstan": "^1.5", + "phpstan/phpstan": "^1.11", "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^8.5.13" }, "bin": [ @@ -813,7 +816,7 @@ ], "support": { "issues": "https://github.com/Seldaek/jsonlint/issues", - "source": "https://github.com/Seldaek/jsonlint/tree/1.10.2" + "source": "https://github.com/Seldaek/jsonlint/tree/1.11.0" }, "funding": [ { @@ -825,7 +828,7 @@ "type": "tidelift" } ], - "time": "2024-02-07T12:57:50+00:00" + "time": "2024-07-11T14:55:45+00:00" }, { "name": "seld/phar-utils", @@ -938,16 +941,16 @@ }, { "name": "symfony/console", - "version": "v5.4.36", + "version": "v5.4.44", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "39f75d9d73d0c11952fdcecf4877b4d0f62a8f6e" + "reference": "5b5a0aa66e3296e303e22490f90f521551835a83" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/39f75d9d73d0c11952fdcecf4877b4d0f62a8f6e", - "reference": "39f75d9d73d0c11952fdcecf4877b4d0f62a8f6e", + "url": "https://api.github.com/repos/symfony/console/zipball/5b5a0aa66e3296e303e22490f90f521551835a83", + "reference": "5b5a0aa66e3296e303e22490f90f521551835a83", "shasum": "" }, "require": { @@ -1017,7 +1020,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.4.36" + "source": "https://github.com/symfony/console/tree/v5.4.44" }, "funding": [ { @@ -1033,20 +1036,20 @@ "type": "tidelift" } ], - "time": "2024-02-20T16:33:57+00:00" + "time": "2024-09-20T07:56:40+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v2.5.2", + "version": "v2.5.3", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66" + "reference": "80d075412b557d41002320b96a096ca65aa2c98d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66", - "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/80d075412b557d41002320b96a096ca65aa2c98d", + "reference": "80d075412b557d41002320b96a096ca65aa2c98d", "shasum": "" }, "require": { @@ -1084,7 +1087,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.2" + "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.3" }, "funding": [ { @@ -1100,20 +1103,20 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:53:40+00:00" + "time": "2023-01-24T14:02:46+00:00" }, { "name": "symfony/filesystem", - "version": "v5.4.35", + "version": "v5.4.44", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "5a553607d4ffbfa9c0ab62facadea296c9db7086" + "reference": "76c3818964e9d32be3862c9318ae3ba9aa280ddc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/5a553607d4ffbfa9c0ab62facadea296c9db7086", - "reference": "5a553607d4ffbfa9c0ab62facadea296c9db7086", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/76c3818964e9d32be3862c9318ae3ba9aa280ddc", + "reference": "76c3818964e9d32be3862c9318ae3ba9aa280ddc", "shasum": "" }, "require": { @@ -1122,6 +1125,9 @@ "symfony/polyfill-mbstring": "~1.8", "symfony/polyfill-php80": "^1.16" }, + "require-dev": { + "symfony/process": "^5.4|^6.4" + }, "type": "library", "autoload": { "psr-4": { @@ -1148,7 +1154,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v5.4.35" + "source": "https://github.com/symfony/filesystem/tree/v5.4.44" }, "funding": [ { @@ -1164,20 +1170,20 @@ "type": "tidelift" } ], - "time": "2024-01-23T13:51:25+00:00" + "time": "2024-09-16T14:52:48+00:00" }, { "name": "symfony/finder", - "version": "v5.4.35", + "version": "v5.4.43", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "abe6d6f77d9465fed3cd2d029b29d03b56b56435" + "reference": "ae25a9145a900764158d439653d5630191155ca0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/abe6d6f77d9465fed3cd2d029b29d03b56b56435", - "reference": "abe6d6f77d9465fed3cd2d029b29d03b56b56435", + "url": "https://api.github.com/repos/symfony/finder/zipball/ae25a9145a900764158d439653d5630191155ca0", + "reference": "ae25a9145a900764158d439653d5630191155ca0", "shasum": "" }, "require": { @@ -1211,7 +1217,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v5.4.35" + "source": "https://github.com/symfony/finder/tree/v5.4.43" }, "funding": [ { @@ -1227,24 +1233,24 @@ "type": "tidelift" } ], - "time": "2024-01-23T13:51:25+00:00" + "time": "2024-08-13T14:03:51+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.29.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4" + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4", - "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-ctype": "*" @@ -1290,7 +1296,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0" }, "funding": [ { @@ -1306,24 +1312,24 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.29.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f" + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/32a9da87d7b3245e09ac426c83d334ae9f06f80f", - "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "suggest": { "ext-intl": "For best performance" @@ -1368,7 +1374,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.31.0" }, "funding": [ { @@ -1384,24 +1390,24 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.29.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "bc45c394692b948b4d383a08d7753968bed9a83d" + "reference": "3833d7255cc303546435cb650316bff708a1c75c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/bc45c394692b948b4d383a08d7753968bed9a83d", - "reference": "bc45c394692b948b4d383a08d7753968bed9a83d", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "suggest": { "ext-intl": "For best performance" @@ -1449,7 +1455,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.31.0" }, "funding": [ { @@ -1465,24 +1471,24 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.29.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec" + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec", - "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-mbstring": "*" @@ -1529,7 +1535,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0" }, "funding": [ { @@ -1545,24 +1551,24 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-php73", - "version": "v1.29.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "21bd091060673a1177ae842c0ef8fe30893114d2" + "reference": "0f68c03565dcaaf25a890667542e8bd75fe7e5bb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/21bd091060673a1177ae842c0ef8fe30893114d2", - "reference": "21bd091060673a1177ae842c0ef8fe30893114d2", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/0f68c03565dcaaf25a890667542e8bd75fe7e5bb", + "reference": "0f68c03565dcaaf25a890667542e8bd75fe7e5bb", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "type": "library", "extra": { @@ -1605,7 +1611,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-php73/tree/v1.31.0" }, "funding": [ { @@ -1621,24 +1627,24 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.29.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b" + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", - "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "type": "library", "extra": { @@ -1685,7 +1691,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.31.0" }, "funding": [ { @@ -1701,24 +1707,24 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-php81", - "version": "v1.29.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "c565ad1e63f30e7477fc40738343c62b40bc672d" + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/c565ad1e63f30e7477fc40738343c62b40bc672d", - "reference": "c565ad1e63f30e7477fc40738343c62b40bc672d", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "type": "library", "extra": { @@ -1761,7 +1767,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-php81/tree/v1.31.0" }, "funding": [ { @@ -1777,20 +1783,20 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/process", - "version": "v5.4.36", + "version": "v5.4.44", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "4fdf34004f149cc20b2f51d7d119aa500caad975" + "reference": "1b9fa82b5c62cd49da8c9e3952dd8531ada65096" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/4fdf34004f149cc20b2f51d7d119aa500caad975", - "reference": "4fdf34004f149cc20b2f51d7d119aa500caad975", + "url": "https://api.github.com/repos/symfony/process/zipball/1b9fa82b5c62cd49da8c9e3952dd8531ada65096", + "reference": "1b9fa82b5c62cd49da8c9e3952dd8531ada65096", "shasum": "" }, "require": { @@ -1823,7 +1829,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v5.4.36" + "source": "https://github.com/symfony/process/tree/v5.4.44" }, "funding": [ { @@ -1839,20 +1845,20 @@ "type": "tidelift" } ], - "time": "2024-02-12T15:49:53+00:00" + "time": "2024-09-17T12:46:43+00:00" }, { "name": "symfony/service-contracts", - "version": "v2.5.2", + "version": "v2.5.3", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c" + "reference": "a2329596ddc8fd568900e3fc76cba42489ecc7f3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/4b426aac47d6427cc1a1d0f7e2ac724627f5966c", - "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/a2329596ddc8fd568900e3fc76cba42489ecc7f3", + "reference": "a2329596ddc8fd568900e3fc76cba42489ecc7f3", "shasum": "" }, "require": { @@ -1906,7 +1912,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v2.5.2" + "source": "https://github.com/symfony/service-contracts/tree/v2.5.3" }, "funding": [ { @@ -1922,20 +1928,20 @@ "type": "tidelift" } ], - "time": "2022-05-30T19:17:29+00:00" + "time": "2023-04-21T15:04:16+00:00" }, { "name": "symfony/string", - "version": "v5.4.36", + "version": "v5.4.44", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "4e232c83622bd8cd32b794216aa29d0d266d353b" + "reference": "832caa16b6d9aac6bf11747315225f5aba384c24" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/4e232c83622bd8cd32b794216aa29d0d266d353b", - "reference": "4e232c83622bd8cd32b794216aa29d0d266d353b", + "url": "https://api.github.com/repos/symfony/string/zipball/832caa16b6d9aac6bf11747315225f5aba384c24", + "reference": "832caa16b6d9aac6bf11747315225f5aba384c24", "shasum": "" }, "require": { @@ -1992,7 +1998,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v5.4.36" + "source": "https://github.com/symfony/string/tree/v5.4.44" }, "funding": [ { @@ -2008,22 +2014,22 @@ "type": "tidelift" } ], - "time": "2024-02-01T08:49:30+00:00" + "time": "2024-09-20T07:56:40+00:00" } ], "packages-dev": [ { "name": "phpstan/phpstan", - "version": "1.10.60", + "version": "1.12.5", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "95dcea7d6c628a3f2f56d091d8a0219485a86bbe" + "reference": "7e6c6cb7cecb0a6254009a1a8a7d54ec99812b17" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/95dcea7d6c628a3f2f56d091d8a0219485a86bbe", - "reference": "95dcea7d6c628a3f2f56d091d8a0219485a86bbe", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/7e6c6cb7cecb0a6254009a1a8a7d54ec99812b17", + "reference": "7e6c6cb7cecb0a6254009a1a8a7d54ec99812b17", "shasum": "" }, "require": { @@ -2066,35 +2072,30 @@ { "url": "https://github.com/phpstan", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", - "type": "tidelift" } ], - "time": "2024-03-07T13:30:19+00:00" + "time": "2024-09-26T12:45:22+00:00" }, { "name": "phpstan/phpstan-deprecation-rules", - "version": "1.1.4", + "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-deprecation-rules.git", - "reference": "089d8a8258ed0aeefdc7b68b6c3d25572ebfdbaa" + "reference": "f94d246cc143ec5a23da868f8f7e1393b50eaa82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-deprecation-rules/zipball/089d8a8258ed0aeefdc7b68b6c3d25572ebfdbaa", - "reference": "089d8a8258ed0aeefdc7b68b6c3d25572ebfdbaa", + "url": "https://api.github.com/repos/phpstan/phpstan-deprecation-rules/zipball/f94d246cc143ec5a23da868f8f7e1393b50eaa82", + "reference": "f94d246cc143ec5a23da868f8f7e1393b50eaa82", "shasum": "" }, "require": { "php": "^7.2 || ^8.0", - "phpstan/phpstan": "^1.10.3" + "phpstan/phpstan": "^1.12" }, "require-dev": { "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/phpstan-php-parser": "^1.1", "phpstan/phpstan-phpunit": "^1.0", "phpunit/phpunit": "^9.5" }, @@ -2118,27 +2119,27 @@ "description": "PHPStan rules for detecting usage of deprecated classes, methods, properties, constants and traits.", "support": { "issues": "https://github.com/phpstan/phpstan-deprecation-rules/issues", - "source": "https://github.com/phpstan/phpstan-deprecation-rules/tree/1.1.4" + "source": "https://github.com/phpstan/phpstan-deprecation-rules/tree/1.2.1" }, - "time": "2023-08-05T09:02:04+00:00" + "time": "2024-09-11T15:52:35+00:00" }, { "name": "phpstan/phpstan-phpunit", - "version": "1.3.16", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-phpunit.git", - "reference": "d5242a59d035e46774f2e634b374bc39ff62cb95" + "reference": "f3ea021866f4263f07ca3636bf22c64be9610c11" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/d5242a59d035e46774f2e634b374bc39ff62cb95", - "reference": "d5242a59d035e46774f2e634b374bc39ff62cb95", + "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/f3ea021866f4263f07ca3636bf22c64be9610c11", + "reference": "f3ea021866f4263f07ca3636bf22c64be9610c11", "shasum": "" }, "require": { "php": "^7.2 || ^8.0", - "phpstan/phpstan": "^1.10" + "phpstan/phpstan": "^1.11" }, "conflict": { "phpunit/phpunit": "<7.0" @@ -2170,27 +2171,27 @@ "description": "PHPUnit extensions and rules for PHPStan", "support": { "issues": "https://github.com/phpstan/phpstan-phpunit/issues", - "source": "https://github.com/phpstan/phpstan-phpunit/tree/1.3.16" + "source": "https://github.com/phpstan/phpstan-phpunit/tree/1.4.0" }, - "time": "2024-02-23T09:51:20+00:00" + "time": "2024-04-20T06:39:00+00:00" }, { "name": "phpstan/phpstan-strict-rules", - "version": "1.5.2", + "version": "1.6.1", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-strict-rules.git", - "reference": "7a50e9662ee9f3942e4aaaf3d603653f60282542" + "reference": "daeec748b53de80a97498462513066834ec28f8b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/7a50e9662ee9f3942e4aaaf3d603653f60282542", - "reference": "7a50e9662ee9f3942e4aaaf3d603653f60282542", + "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/daeec748b53de80a97498462513066834ec28f8b", + "reference": "daeec748b53de80a97498462513066834ec28f8b", "shasum": "" }, "require": { "php": "^7.2 || ^8.0", - "phpstan/phpstan": "^1.10.34" + "phpstan/phpstan": "^1.12.4" }, "require-dev": { "nikic/php-parser": "^4.13.0", @@ -2219,28 +2220,28 @@ "description": "Extra strict and opinionated rules for PHPStan", "support": { "issues": "https://github.com/phpstan/phpstan-strict-rules/issues", - "source": "https://github.com/phpstan/phpstan-strict-rules/tree/1.5.2" + "source": "https://github.com/phpstan/phpstan-strict-rules/tree/1.6.1" }, - "time": "2023-10-30T14:35:06+00:00" + "time": "2024-09-20T14:04:44+00:00" }, { "name": "phpstan/phpstan-symfony", - "version": "1.3.8", + "version": "1.4.10", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-symfony.git", - "reference": "d8a0bc03a68d95288b6471c37d435647fbdaff1a" + "reference": "f7d5782044bedf93aeb3f38e09c91148ee90e5a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-symfony/zipball/d8a0bc03a68d95288b6471c37d435647fbdaff1a", - "reference": "d8a0bc03a68d95288b6471c37d435647fbdaff1a", + "url": "https://api.github.com/repos/phpstan/phpstan-symfony/zipball/f7d5782044bedf93aeb3f38e09c91148ee90e5a1", + "reference": "f7d5782044bedf93aeb3f38e09c91148ee90e5a1", "shasum": "" }, "require": { "ext-simplexml": "*", "php": "^7.2 || ^8.0", - "phpstan/phpstan": "^1.10.36" + "phpstan/phpstan": "^1.12" }, "conflict": { "symfony/framework-bundle": "<3.0" @@ -2291,22 +2292,22 @@ "description": "Symfony Framework extensions and rules for PHPStan", "support": { "issues": "https://github.com/phpstan/phpstan-symfony/issues", - "source": "https://github.com/phpstan/phpstan-symfony/tree/1.3.8" + "source": "https://github.com/phpstan/phpstan-symfony/tree/1.4.10" }, - "time": "2024-03-05T16:33:08+00:00" + "time": "2024-09-26T18:14:50+00:00" }, { "name": "symfony/phpunit-bridge", - "version": "v7.0.4", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/phpunit-bridge.git", - "reference": "54ca13ec990a40411ad978e08d994fca6cdd865f" + "reference": "e876eb90e32a8fc4c4911d458e09f88d65877d1c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/54ca13ec990a40411ad978e08d994fca6cdd865f", - "reference": "54ca13ec990a40411ad978e08d994fca6cdd865f", + "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/e876eb90e32a8fc4c4911d458e09f88d65877d1c", + "reference": "e876eb90e32a8fc4c4911d458e09f88d65877d1c", "shasum": "" }, "require": { @@ -2338,7 +2339,8 @@ "Symfony\\Bridge\\PhpUnit\\": "" }, "exclude-from-classmap": [ - "/Tests/" + "/Tests/", + "/bin/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -2358,7 +2360,7 @@ "description": "Provides utilities for PHPUnit, especially user deprecation notices management", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/phpunit-bridge/tree/v7.0.4" + "source": "https://github.com/symfony/phpunit-bridge/tree/v7.1.4" }, "funding": [ { @@ -2374,18 +2376,18 @@ "type": "tidelift" } ], - "time": "2024-02-08T19:22:56+00:00" + "time": "2024-08-13T14:28:19+00:00" } ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, "platform": { "php": "^7.2.5 || ^8.0" }, - "platform-dev": [], + "platform-dev": {}, "platform-overrides": { "php": "7.2.5" }, diff --git a/vendor/composer/composer/res/composer-lock-schema.json b/vendor/composer/composer/res/composer-lock-schema.json new file mode 100644 index 0000000..b1ef31c --- /dev/null +++ b/vendor/composer/composer/res/composer-lock-schema.json @@ -0,0 +1,101 @@ +{ + "$schema": "https://json-schema.org/draft-04/schema#", + "title": "Composer Lock File", + "type": "object", + "required": [ "content-hash", "packages", "packages-dev" ], + "additionalProperties": true, + "properties": { + "_readme": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Informational text for humans reading the file" + }, + "content-hash": { + "type": "string", + "description": "Hash of all relevant properties of the composer.json that was used to create this lock file." + }, + "packages": { + "type": "array", + "description": "An array of packages that are required.", + "items": { + "$ref": "./composer-schema.json", + "required": ["name", "version"] + } + }, + "packages-dev": { + "type": "array", + "description": "An array of packages that are required in require-dev.", + "items": { + "$ref": "./composer-schema.json" + } + }, + "aliases": { + "type": "array", + "description": "Inline aliases defined in the root package.", + "items": { + "type": "object", + "required": [ "package", "version", "alias", "alias_normalized" ], + "properties": { + "package": { + "type": "string" + }, + "version": { + "type": "string" + }, + "alias": { + "type": "string" + }, + "alias_normalized": { + "type": "string" + } + } + } + }, + "minimum-stability": { + "type": "string", + "description": "The minimum-stability used to generate this lock file." + }, + "stability-flags": { + "type": "object", + "description": "Root package stability flags changing the minimum-stability for specific packages.", + "additionalProperties": { + "type": "integer" + } + }, + "prefer-stable": { + "type": "boolean", + "description": "Whether the --prefer-stable flag was used when building this lock file." + }, + "prefer-lowest": { + "type": "boolean", + "description": "Whether the --prefer-lowest flag was used when building this lock file." + }, + "platform": { + "type": "object", + "description": "Platform requirements of the root package.", + "additionalProperties": { + "type": "string" + } + }, + "platform-dev": { + "type": "object", + "description": "Platform dev-requirements of the root package.", + "additionalProperties": { + "type": "string" + } + }, + "platform-overrides": { + "type": "object", + "description": "Platform config overrides of the root package.", + "additionalProperties": { + "type": "string" + } + }, + "plugin-api-version": { + "type": "string", + "description": "The composer-plugin-api version that was used to generate this lock file." + } + } +} diff --git a/vendor/composer/composer/res/composer-repository-schema.json b/vendor/composer/composer/res/composer-repository-schema.json index adcc299..223f63a 100644 --- a/vendor/composer/composer/res/composer-repository-schema.json +++ b/vendor/composer/composer/res/composer-repository-schema.json @@ -1,11 +1,12 @@ { "$schema": "https://json-schema.org/draft-04/schema#", - "description": "A representation of packages metadata.", + "title": "Composer Package Repository", "type": "object", "oneOf": [ { "required": [ "packages" ] }, { "required": [ "providers" ] }, - { "required": [ "provider-includes", "providers-url" ] } + { "required": [ "provider-includes", "providers-url" ] }, + { "required": [ "metadata-url" ] } ], "properties": { "packages": { @@ -13,31 +14,124 @@ "description": "A hashmap of package names in the form of /.", "additionalProperties": { "$ref": "#/definitions/versions" } }, + "metadata-url": { + "type": "string", + "description": "Endpoint to retrieve package metadata data from, in Composer v2 format, e.g. '/p2/%package%.json'." + }, + "available-packages": { + "type": "array", + "items": { + "type": "string" + }, + "description": "If your repository only has a small number of packages, and you want to avoid serving many 404s, specify all the package names that your repository contains here." + }, + "available-package-patterns": { + "type": "array", + "items": { + "type": "string" + }, + "description": "If your repository only has a small number of packages, and you want to avoid serving many 404s, specify package name patterns containing wildcards (*) that your repository contains here." + }, + "security-advisories": { + "type": "array", + "items": { + "type": "object", + "required": ["metadata", "api-url"], + "properties": { + "metadata": { + "type": "boolean", + "description": "Whether metadata files contain security advisory data or whether it should always be queried using the API URL." + }, + "api-url": { + "type": "string", + "description": "Endpoint to call to retrieve security advisories data." + } + } + } + }, + "metadata-changes-url": { + "type": "string", + "description": "Endpoint to retrieve package metadata updates from. This should receive a timestamp since last call to be able to return new changes. e.g. '/metadata/changes.json'." + }, + "providers-api": { + "type": "string", + "description": "Endpoint to retrieve package names providing a given name from, e.g. '/providers/%package%.json'." + }, + "notify-batch": { + "type": "string", + "description": "Endpoint to call after multiple packages have been installed, e.g. '/downloads/'." + }, + "search": { + "type": "string", + "description": "Endpoint that provides search capabilities, e.g. '/search.json?q=%query%&type=%type%'." + }, + "list": { + "type": "string", + "description": "Endpoint that provides a full list of packages present in the repository. It should accept an optional `?filter=xx` query param, which can contain `*` as wildcards matching any substring. e.g. '/list.json'." + }, + "warnings": { + "type": "array", + "items": { + "type": "object", + "required": ["message", "versions"], + "properties": { + "message": { + "type": "string", + "description": "A message that will be output by Composer as a warning when this source is consulted." + }, + "versions": { + "type": "string", + "description": "A version constraint to limit to which Composer versions the warning should be shown." + } + } + } + }, + "infos": { + "type": "array", + "items": { + "type": "object", + "required": ["message", "versions"], + "properties": { + "message": { + "type": "string", + "description": "A message that will be output by Composer as info when this source is consulted." + }, + "versions": { + "type": "string", + "description": "A version constraint to limit to which Composer versions the info should be shown." + } + } + } + }, "providers-url": { "type": "string", - "description": "Endpoint to retrieve provider data from, e.g. '/p/%package%$%hash%.json'." + "description": "DEPRECATED: Endpoint to retrieve provider data from, e.g. '/p/%package%$%hash%.json'." }, "provider-includes": { "type": "object", - "description": "A hashmap of provider listings.", + "description": "DEPRECATED: A hashmap of provider listings.", "additionalProperties": { "$ref": "#/definitions/provider" } }, "providers": { "type": "object", - "description": "A hashmap of package names in the form of /.", + "description": "DEPRECATED: A hashmap of package names in the form of /.", "additionalProperties": { "$ref": "#/definitions/provider" } }, - "notify-batch": { + "warning": { "type": "string", - "description": "Endpoint to call after multiple packages have been installed, e.g. '/downloads/'." + "description": "DEPRECATED: A message that will be output by Composer as a warning when this source is consulted." }, - "search": { + "warning-versions": { "type": "string", - "description": "Endpoint that provides search capabilities, e.g. '/search.json?q=%query%&type=%type%'." + "description": "DEPRECATED: A version constraint to limit to which Composer versions the warning should be shown." }, - "warning": { + "info": { + "type": "string", + "description": "DEPRECATED: A message that will be output by Composer as a info when this source is consulted." + }, + "info-versions": { "type": "string", - "description": "A message that will be output by Composer as a warning when this source is consulted." + "description": "DEPRECATED: A version constraint to limit to which Composer versions the info should be shown." } }, "definitions": { diff --git a/vendor/composer/composer/res/composer-schema.json b/vendor/composer/composer/res/composer-schema.json index a77becb..9f76bc4 100644 --- a/vendor/composer/composer/res/composer-schema.json +++ b/vendor/composer/composer/res/composer-schema.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft-04/schema#", - "title": "Package", + "title": "Composer Package", "type": "object", "properties": { "name": { @@ -288,6 +288,64 @@ } } }, + "php-ext": { + "type": "object", + "description": "Settings for PHP extension packages.", + "properties": { + "extension-name": { + "type": "string", + "description": "If specified, this will be used as the name of the extension, where needed by tooling. If this is not specified, the extension name will be derived from the Composer package name (e.g. `vendor/name` would become `ext-name`). The extension name may be specified with or without the `ext-` prefix, and tools that use this must normalise this appropriately.", + "example": "ext-xdebug" + }, + "priority": { + "type": "integer", + "description": "This is used to add a prefix to the INI file, e.g. `90-xdebug.ini` which affects the loading order. The priority is a number in the range 10-99 inclusive, with 10 being the highest priority (i.e. will be processed first), and 99 being the lowest priority (i.e. will be processed last). There are two digits so that the files sort correctly on any platform, whether the sorting is natural or not.", + "minimum": 10, + "maximum": 99, + "example": 80, + "default": 80 + }, + "support-zts": { + "type": "boolean", + "description": "Does this package support Zend Thread Safety", + "example": false, + "default": true + }, + "support-nts": { + "type": "boolean", + "description": "Does this package support non-Thread Safe mode", + "example": false, + "default": true + }, + "configure-options": { + "type": "array", + "description": "These configure options make up the flags that can be passed to ./configure when installing the extension.", + "items": { + "type": "object", + "required": ["name"], + "properties": { + "name": { + "type": "string", + "description": "The name of the flag, this would typically be prefixed with `--`, for example, the value 'the-flag' would be passed as `./configure --the-flag`.", + "example": "without-xdebug-compression", + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9-_]*$" + }, + "needs-value": { + "type": "boolean", + "description": "If this is set to true, the flag needs a value (e.g. --with-somelib=), otherwise it is a flag without a value (e.g. --enable-some-feature).", + "example": false, + "default": false + }, + "description": { + "type": "string", + "description": "The description of what the flag does or means.", + "example": "Disable compression through zlib" + } + } + } + } + } + }, "config": { "type": "object", "description": "Composer options.", @@ -610,6 +668,14 @@ "platform-check": { "type": ["boolean", "string"], "description": "Defaults to \"php-only\" which checks only the PHP version. Setting to true will also check the presence of required PHP extensions. If set to false, Composer will not create and require a platform_check.php file as part of the autoloader bootstrap." + }, + "bump-after-update": { + "type": ["string", "boolean"], + "description": "Defaults to false and can be any of true, false, \"dev\"` or \"no-dev\"`. If set to true, Composer will run the bump command after running the update command. If set to \"dev\" or \"no-dev\" then only the corresponding dependencies will be bumped." + }, + "allow-missing-requirements": { + "type": ["boolean"], + "description": "Defaults to false. If set to true, Composer will allow install when lock file is not up to date with the latest changes in composer.json." } } }, diff --git a/vendor/composer/composer/src/Composer/Advisory/Auditor.php b/vendor/composer/composer/src/Composer/Advisory/Auditor.php index f0dc76a..de8034b 100644 --- a/vendor/composer/composer/src/Composer/Advisory/Auditor.php +++ b/vendor/composer/composer/src/Composer/Advisory/Auditor.php @@ -19,7 +19,6 @@ use Composer\Package\PackageInterface; use Composer\Repository\RepositorySet; use Composer\Util\PackageInfo; -use Composer\Util\Platform; use InvalidArgumentException; use Symfony\Component\Console\Formatter\OutputFormatter; @@ -47,17 +46,25 @@ class Auditor public const ABANDONED_REPORT = 'report'; public const ABANDONED_FAIL = 'fail'; + /** @internal */ + public const ABANDONEDS = [ + self::ABANDONED_IGNORE, + self::ABANDONED_REPORT, + self::ABANDONED_FAIL, + ]; + /** * @param PackageInterface[] $packages * @param self::FORMAT_* $format The format that will be used to output audit results. * @param bool $warningOnly If true, outputs a warning. If false, outputs an error. * @param string[] $ignoreList List of advisory IDs, remote IDs or CVE IDs that reported but not listed as vulnerabilities. * @param self::ABANDONED_* $abandoned + * @param array $ignoredSeverities List of ignored severity levels * * @return int Amount of packages with vulnerabilities found * @throws InvalidArgumentException If no packages are passed in */ - public function audit(IOInterface $io, RepositorySet $repoSet, array $packages, string $format, bool $warningOnly = true, array $ignoreList = [], string $abandoned = self::ABANDONED_FAIL): int + public function audit(IOInterface $io, RepositorySet $repoSet, array $packages, string $format, bool $warningOnly = true, array $ignoreList = [], string $abandoned = self::ABANDONED_FAIL, array $ignoredSeverities = []): int { $allAdvisories = $repoSet->getMatchingSecurityAdvisories($packages, $format === self::FORMAT_SUMMARY); // we need the CVE & remote IDs set to filter ignores correctly so if we have any matches using the optimized codepath above @@ -65,7 +72,7 @@ public function audit(IOInterface $io, RepositorySet $repoSet, array $packages, if (count($allAdvisories) > 0 && $ignoreList !== [] && $format === self::FORMAT_SUMMARY) { $allAdvisories = $repoSet->getMatchingSecurityAdvisories($packages, false); } - ['advisories' => $advisories, 'ignoredAdvisories' => $ignoredAdvisories] = $this->processAdvisories($allAdvisories, $ignoreList); + ['advisories' => $advisories, 'ignoredAdvisories' => $ignoredAdvisories] = $this->processAdvisories($allAdvisories, $ignoreList, $ignoredSeverities); $abandonedCount = 0; $affectedPackagesCount = 0; @@ -83,8 +90,9 @@ public function audit(IOInterface $io, RepositorySet $repoSet, array $packages, if ($ignoredAdvisories !== []) { $json['ignored-advisories'] = $ignoredAdvisories; } - $json['abandoned'] = array_reduce($abandonedPackages, static function(array $carry, CompletePackageInterface $package): array { + $json['abandoned'] = array_reduce($abandonedPackages, static function (array $carry, CompletePackageInterface $package): array { $carry[$package->getPrettyName()] = $package->getReplacementPackage(); + return $carry; }, []); @@ -139,11 +147,12 @@ private function filterAbandonedPackages(array $packages): array /** * @phpstan-param array> $allAdvisories * @param array|array $ignoreList List of advisory IDs, remote IDs or CVE IDs that reported but not listed as vulnerabilities. + * @param array $ignoredSeverities List of ignored severity levels * @phpstan-return array{advisories: array>, ignoredAdvisories: array>} */ - private function processAdvisories(array $allAdvisories, array $ignoreList): array + private function processAdvisories(array $allAdvisories, array $ignoreList, array $ignoredSeverities): array { - if ($ignoreList === []) { + if ($ignoreList === [] && $ignoredSeverities === []) { return ['advisories' => $allAdvisories, 'ignoredAdvisories' => []]; } @@ -167,6 +176,11 @@ private function processAdvisories(array $allAdvisories, array $ignoreList): arr } if ($advisory instanceof SecurityAdvisory) { + if (in_array($advisory->severity, $ignoredSeverities, true)) { + $isActive = false; + $ignoreReason = "Ignored via --ignore-severity={$advisory->severity}"; + } + if (in_array($advisory->cve, $ignoredIds, true)) { $isActive = false; $ignoreReason = $ignoreList[$advisory->cve] ?? null; @@ -264,6 +278,10 @@ private function outputAdvisoriesTable(ConsoleIO $io, array $advisories): void $advisory->affectedVersions->getPrettyString(), $advisory->reportedAt->format(DATE_ATOM), ]; + if ($advisory->cve === null) { + $headers[] = 'Advisory ID'; + $row[] = $advisory->advisoryId; + } if ($advisory instanceof IgnoredSecurityAdvisory) { $headers[] = 'Ignore reason'; $row[] = $advisory->ignoreReason ?? 'None specified'; @@ -294,6 +312,9 @@ private function outputAdvisoriesPlain(IOInterface $io, array $advisories): void $error[] = "Package: ".$advisory->packageName; $error[] = "Severity: ".$this->getSeverity($advisory); $error[] = "CVE: ".$this->getCVE($advisory); + if ($advisory->cve === null) { + $error[] = "Advisory ID: ".$advisory->advisoryId; + } $error[] = "Title: ".OutputFormatter::escape($advisory->title); $error[] = "URL: ".$this->getURL($advisory); $error[] = "Affected versions: ".OutputFormatter::escape($advisory->affectedVersions->getPrettyString()); @@ -380,5 +401,4 @@ private function getURL(SecurityAdvisory $advisory): string return 'link).'>'.OutputFormatter::escape($advisory->link).''; } - } diff --git a/vendor/composer/composer/src/Composer/Autoload/AutoloadGenerator.php b/vendor/composer/composer/src/Composer/Autoload/AutoloadGenerator.php index 844b802..86c9f18 100644 --- a/vendor/composer/composer/src/Composer/Autoload/AutoloadGenerator.php +++ b/vendor/composer/composer/src/Composer/Autoload/AutoloadGenerator.php @@ -173,7 +173,7 @@ public function setPlatformRequirementFilter(PlatformRequirementFilterInterface * @throws \Seld\JsonLint\ParsingException * @throws \RuntimeException */ - public function dump(Config $config, InstalledRepositoryInterface $localRepo, RootPackageInterface $rootPackage, InstallationManager $installationManager, string $targetDir, bool $scanPsrPackages = false, ?string $suffix = null, ?Locker $locker = null) + public function dump(Config $config, InstalledRepositoryInterface $localRepo, RootPackageInterface $rootPackage, InstallationManager $installationManager, string $targetDir, bool $scanPsrPackages = false, ?string $suffix = null, ?Locker $locker = null, bool $strictAmbiguous = false) { if ($this->classMapAuthoritative) { // Force scanPsrPackages when classmap is authoritative @@ -319,7 +319,7 @@ public static function autoload(\$class) EOF; } - $excluded = null; + $excluded = []; if (!empty($autoloads['exclude-from-classmap'])) { $excluded = $autoloads['exclude-from-classmap']; } @@ -348,14 +348,26 @@ public static function autoload(\$class) continue; } - $classMapGenerator->scanPaths($dir, $this->buildExclusionRegex($dir, $excluded), $group['type'], $namespace); + // if the vendor dir is contained within a psr-0/psr-4 dir being scanned we exclude it + if (str_contains($vendorPath, $dir.'/')) { + $exclusionRegex = $this->buildExclusionRegex($dir, array_merge($excluded, [$vendorPath.'/'])); + } else { + $exclusionRegex = $this->buildExclusionRegex($dir, $excluded); + } + + $classMapGenerator->scanPaths($dir, $exclusionRegex, $group['type'], $namespace); } } } } $classMap = $classMapGenerator->getClassMap(); - foreach ($classMap->getAmbiguousClasses() as $className => $ambiguousPaths) { + if ($strictAmbiguous) { + $ambiguousClasses = $classMap->getAmbiguousClasses(false); + } else { + $ambiguousClasses = $classMap->getAmbiguousClasses(); + } + foreach ($ambiguousClasses as $className => $ambiguousPaths) { if (count($ambiguousPaths) > 1) { $this->io->writeError( 'Warning: Ambiguous class resolution, "'.$className.'"'. @@ -368,6 +380,9 @@ public static function autoload(\$class) ); } } + + // output PSR violations which are not coming from the vendor dir + $classMap->clearPsrViolationsByPath($vendorPath); foreach ($classMap->getPsrViolations() as $msg) { $this->io->writeError("$msg"); } @@ -400,14 +415,14 @@ public static function autoload(\$class) // carry over existing autoload.php's suffix if possible and none is configured if (null === $suffix && Filesystem::isReadable($vendorPath.'/autoload.php')) { - $content = file_get_contents($vendorPath.'/autoload.php'); + $content = (string) file_get_contents($vendorPath.'/autoload.php'); if (Preg::isMatch('{ComposerAutoloaderInit([^:\s]+)::}', $content, $match)) { $suffix = $match[1]; } } if (null === $suffix) { - $suffix = $locker !== null && $locker->isLocked() ? $locker->getLockData()['content-hash'] : md5(uniqid('', true)); + $suffix = $locker !== null && $locker->isLocked() ? $locker->getLockData()['content-hash'] : bin2hex(random_bytes(16)); } } @@ -460,12 +475,12 @@ public static function autoload(\$class) } /** - * @param array|null $excluded + * @param array $excluded * @return non-empty-string|null */ - private function buildExclusionRegex(string $dir, ?array $excluded): ?string + private function buildExclusionRegex(string $dir, array $excluded): ?string { - if (null === $excluded) { + if ([] === $excluded) { return null; } @@ -602,7 +617,7 @@ public function createLoader(array $autoloads, ?string $vendorDir = null) } if (isset($autoloads['classmap'])) { - $excluded = null; + $excluded = []; if (!empty($autoloads['exclude-from-classmap'])) { $excluded = $autoloads['exclude-from-classmap']; } @@ -1042,7 +1057,7 @@ public static function getLoader() } if ($this->apcu) { - $apcuPrefix = var_export(($this->apcuPrefix !== null ? $this->apcuPrefix : substr(base64_encode(md5(uniqid('', true), true)), 0, -3)), true); + $apcuPrefix = var_export(($this->apcuPrefix !== null ? $this->apcuPrefix : bin2hex(random_bytes(10))), true); $file .= <<setApcuPrefix($apcuPrefix); @@ -1231,6 +1246,10 @@ protected function parseAutoloadsType(array $packageMap, string $type, RootPacka } foreach ($autoload[$type] as $namespace => $paths) { + if (in_array($type, ['psr-4', 'psr-0'], true)) { + // normalize namespaces to ensure "\" becomes "" and others do not have leading separators as they are not needed + $namespace = ltrim($namespace, '\\'); + } foreach ((array) $paths as $path) { if (($type === 'files' || $type === 'classmap' || $type === 'exclude-from-classmap') && $package->getTargetDir() && !Filesystem::isReadable($installPath.'/'.$path)) { // remove target-dir from file paths of the root package @@ -1255,10 +1274,8 @@ protected function parseAutoloadsType(array $packageMap, string $type, RootPacka $path = Preg::replaceCallback( '{^((?:(?:\\\\\\.){1,2}+/)+)}', static function ($matches) use (&$updir): string { - if (isset($matches[1])) { - // undo preg_quote for the matched string - $updir = str_replace('\\.', '.', $matches[1]); - } + // undo preg_quote for the matched string + $updir = str_replace('\\.', '.', $matches[1]); return ''; }, @@ -1300,7 +1317,8 @@ static function ($matches) use (&$updir): string { */ protected function getFileIdentifier(PackageInterface $package, string $path) { - return md5($package->getName() . ':' . $path); + // TODO composer v3 change this to sha1 or xxh3? Possibly not worth the potential breakage though + return hash('md5', $package->getName() . ':' . $path); } /** diff --git a/vendor/composer/composer/src/Composer/Cache.php b/vendor/composer/composer/src/Composer/Cache.php index 1a216c5..e18715f 100644 --- a/vendor/composer/composer/src/Composer/Cache.php +++ b/vendor/composer/composer/src/Composer/Cache.php @@ -53,7 +53,7 @@ public function __construct(IOInterface $io, string $cacheDir, string $allowlist $this->root = rtrim($cacheDir, '/\\') . '/'; $this->allowlist = $allowlist; $this->filesystem = $filesystem ?: new Filesystem(); - $this->readOnly = (bool) $readOnly; + $this->readOnly = $readOnly; if (!self::isUsable($cacheDir)) { $this->enabled = false; @@ -65,7 +65,7 @@ public function __construct(IOInterface $io, string $cacheDir, string $allowlist */ public function setReadOnly(bool $readOnly) { - $this->readOnly = (bool) $readOnly; + $this->readOnly = $readOnly; } /** @@ -144,7 +144,7 @@ public function write(string $file, string $contents) $this->io->writeError('Writing '.$this->root . $file.' into cache', true, IOInterface::DEBUG); - $tempFileName = $this->root . $file . uniqid('.', true) . '.tmp'; + $tempFileName = $this->root . $file . bin2hex(random_bytes(5)) . '.tmp'; try { return file_put_contents($tempFileName, $contents) !== false && rename($tempFileName, $this->root . $file); } catch (\ErrorException $e) { @@ -198,7 +198,7 @@ public function copyFrom(string $file, string $source) $this->io->writeError('Writing '.$this->root . $file.' into cache from '.$source); } - return copy($source, $this->root . $file); + return $this->filesystem->copy($source, $this->root . $file); } return false; @@ -224,7 +224,7 @@ public function copyTo(string $file, string $target) $this->io->writeError('Reading '.$this->root . $file.' from cache', true, IOInterface::DEBUG); - return copy($this->root . $file, $target); + return $this->filesystem->copy($this->root . $file, $target); } } @@ -357,7 +357,7 @@ public function sha1(string $file) if ($this->isEnabled()) { $file = Preg::replace('{[^'.$this->allowlist.']}i', '-', $file); if (file_exists($this->root . $file)) { - return sha1_file($this->root . $file); + return hash_file('sha1', $this->root . $file); } } diff --git a/vendor/composer/composer/src/Composer/Command/ArchiveCommand.php b/vendor/composer/composer/src/Composer/Command/ArchiveCommand.php index e018910..b71f4e2 100644 --- a/vendor/composer/composer/src/Composer/Command/ArchiveCommand.php +++ b/vendor/composer/composer/src/Composer/Command/ArchiveCommand.php @@ -169,7 +169,7 @@ protected function selectPackage(IOInterface $io, string $packageName, ?string $ } if ($version !== null && Preg::isMatchStrictGroups('{@(stable|RC|beta|alpha|dev)$}i', $version, $match)) { - $minStability = $match[1]; + $minStability = VersionParser::normalizeStability($match[1]); $version = (string) substr($version, 0, -strlen($match[0])); } diff --git a/vendor/composer/composer/src/Composer/Command/AuditCommand.php b/vendor/composer/composer/src/Composer/Command/AuditCommand.php index 1097bb7..e4a2094 100644 --- a/vendor/composer/composer/src/Composer/Command/AuditCommand.php +++ b/vendor/composer/composer/src/Composer/Command/AuditCommand.php @@ -33,6 +33,8 @@ protected function configure(): void new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables auditing of require-dev packages.'), new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Output format. Must be "table", "plain", "json", or "summary".', Auditor::FORMAT_TABLE, Auditor::FORMATS), new InputOption('locked', null, InputOption::VALUE_NONE, 'Audit based on the lock file instead of the installed packages.'), + new InputOption('abandoned', null, InputOption::VALUE_REQUIRED, 'Behavior on abandoned packages. Must be "ignore", "report", or "fail".', null, Auditor::ABANDONEDS), + new InputOption('ignore-severity', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Ignore advisories of a certain severity level.', [], ['low', 'medium', 'high', 'critical']), ]) ->setHelp( <<getConfig()->get('audit'); - return min(255, $auditor->audit($this->getIO(), $repoSet, $packages, $this->getAuditFormat($input, 'format'), false, $auditConfig['ignore'] ?? [], $auditConfig['abandoned'] ?? Auditor::ABANDONED_FAIL)); + $abandoned = $input->getOption('abandoned'); + if ($abandoned !== null && !in_array($abandoned, Auditor::ABANDONEDS, true)) { + throw new \InvalidArgumentException('--audit must be one of '.implode(', ', Auditor::ABANDONEDS).'.'); + } + + $abandoned = $abandoned ?? $auditConfig['abandoned'] ?? Auditor::ABANDONED_FAIL; + + $ignoreSeverities = $input->getOption('ignore-severity') ?? []; + + return min(255, $auditor->audit( + $this->getIO(), + $repoSet, + $packages, + $this->getAuditFormat($input, 'format'), + false, + $auditConfig['ignore'] ?? [], + $abandoned, + $ignoreSeverities + )); + } /** diff --git a/vendor/composer/composer/src/Composer/Command/BaseDependencyCommand.php b/vendor/composer/composer/src/Composer/Command/BaseDependencyCommand.php index 2fb3639..bb2a642 100644 --- a/vendor/composer/composer/src/Composer/Command/BaseDependencyCommand.php +++ b/vendor/composer/composer/src/Composer/Command/BaseDependencyCommand.php @@ -13,6 +13,7 @@ namespace Composer\Command; use Composer\Package\Link; +use Composer\Package\Package; use Composer\Package\PackageInterface; use Composer\Package\CompletePackageInterface; use Composer\Package\RootPackage; @@ -24,6 +25,8 @@ use Composer\Repository\RepositoryFactory; use Composer\Plugin\CommandEvent; use Composer\Plugin\PluginEvents; +use Composer\Semver\Constraint\Bound; +use Composer\Util\Platform; use Symfony\Component\Console\Formatter\OutputFormatter; use Symfony\Component\Console\Formatter\OutputFormatterStyle; use Composer\Package\Version\VersionParser; @@ -102,13 +105,27 @@ protected function doExecute(InputInterface $input, OutputInterface $output, boo // If the version we ask for is not installed then we need to locate it in remote repos and add it. // This is needed for why-not to resolve conflicts from an uninstalled version against installed packages. - if (!$installedRepo->findPackage($needle, $textConstraint)) { + $matchedPackage = $installedRepo->findPackage($needle, $textConstraint); + if (!$matchedPackage) { $defaultRepos = new CompositeRepository(RepositoryFactory::defaultRepos($this->getIO(), $composer->getConfig(), $composer->getRepositoryManager())); if ($match = $defaultRepos->findPackage($needle, $textConstraint)) { $installedRepo->addRepository(new InstalledArrayRepository([clone $match])); + } elseif (PlatformRepository::isPlatformPackage($needle)) { + $parser = new VersionParser(); + $constraint = $parser->parseConstraints($textConstraint); + if ($constraint->getLowerBound() !== Bound::zero()) { + $tempPlatformPkg = new Package($needle, $constraint->getLowerBound()->getVersion(), $constraint->getLowerBound()->getVersion()); + $installedRepo->addRepository(new InstalledArrayRepository([$tempPlatformPkg])); + } } else { $this->getIO()->writeError('Package "'.$needle.'" could not be found with constraint "'.$textConstraint.'", results below will most likely be incomplete.'); } + } elseif (PlatformRepository::isPlatformPackage($needle)) { + $extraNotice = ''; + if (($matchedPackage->getExtra()['config.platform'] ?? false) === true) { + $extraNotice = ' (version provided by config.platform)'; + } + $this->getIO()->writeError('Package "'.$needle.' '.$textConstraint.'" found in version "'.$matchedPackage->getPrettyVersion().'"'.$extraNotice.'.'); } // Include replaced packages for inverted lookups as they are then the actual starting point to consider @@ -154,7 +171,7 @@ protected function doExecute(InputInterface $input, OutputInterface $output, boo $this->printTable($output, $results); } - if ($inverted && $input->hasArgument(self::ARGUMENT_CONSTRAINT)) { + if ($inverted && $input->hasArgument(self::ARGUMENT_CONSTRAINT) && !PlatformRepository::isPlatformPackage($needle)) { $composerCommand = 'update'; foreach ($composer->getPackage()->getRequires() as $rootRequirement) { diff --git a/vendor/composer/composer/src/Composer/Command/BumpCommand.php b/vendor/composer/composer/src/Composer/Command/BumpCommand.php index db5b946..5cd7a0f 100644 --- a/vendor/composer/composer/src/Composer/Command/BumpCommand.php +++ b/vendor/composer/composer/src/Composer/Command/BumpCommand.php @@ -12,6 +12,7 @@ namespace Composer\Command; +use Composer\IO\IOInterface; use Composer\Package\AliasPackage; use Composer\Package\BasePackage; use Composer\Package\Locker; @@ -72,9 +73,28 @@ protected function configure(): void */ protected function execute(InputInterface $input, OutputInterface $output): int { + return $this->doBump( + $this->getIO(), + $input->getOption('dev-only'), + $input->getOption('no-dev-only'), + $input->getOption('dry-run'), + $input->getArgument('packages') + ); + } + + /** + * @param string[] $packagesFilter + * @throws \Seld\JsonLint\ParsingException + */ + public function doBump( + IOInterface $io, + bool $devOnly, + bool $noDevOnly, + bool $dryRun, + array $packagesFilter + ): int { /** @readonly */ $composerJsonPath = Factory::getComposerFile(); - $io = $this->getIO(); if (!Filesystem::isReadable($composerJsonPath)) { $io->writeError(''.$composerJsonPath.' is not readable.'); @@ -112,7 +132,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $repo = $composer->getRepositoryManager()->getLocalRepository(); } - if ($composer->getPackage()->getType() !== 'project' && !$input->getOption('dev-only')) { + if ($composer->getPackage()->getType() !== 'project' && !$devOnly) { $io->writeError('Warning: Bumping dependency constraints is not recommended for libraries as it will narrow down your dependencies and may cause problems for your users.'); $contents = $composerJson->read(); @@ -125,14 +145,13 @@ protected function execute(InputInterface $input, OutputInterface $output): int $bumper = new VersionBumper(); $tasks = []; - if (!$input->getOption('dev-only')) { + if (!$devOnly) { $tasks['require'] = $composer->getPackage()->getRequires(); } - if (!$input->getOption('no-dev-only')) { + if (!$noDevOnly) { $tasks['require-dev'] = $composer->getPackage()->getDevRequires(); } - $packagesFilter = $input->getArgument('packages'); if (count($packagesFilter) > 0) { $pattern = BasePackage::packageNamesToRegexp(array_unique(array_map('strtolower', $packagesFilter))); foreach ($tasks as $key => $reqs) { @@ -171,8 +190,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int } } - $dryRun = $input->getOption('dry-run'); - if (!$dryRun && !$this->updateFileCleanly($composerJson, $updates)) { $composerDefinition = $composerJson->read(); foreach ($updates as $key => $packages) { diff --git a/vendor/composer/composer/src/Composer/Command/ClearCacheCommand.php b/vendor/composer/composer/src/Composer/Command/ClearCacheCommand.php index 028aa42..77ed517 100644 --- a/vendor/composer/composer/src/Composer/Command/ClearCacheCommand.php +++ b/vendor/composer/composer/src/Composer/Command/ClearCacheCommand.php @@ -45,7 +45,13 @@ protected function configure(): void protected function execute(InputInterface $input, OutputInterface $output): int { - $config = Factory::createConfig(); + $composer = $this->tryComposer(); + if ($composer !== null) { + $config = $composer->getConfig(); + } else { + $config = Factory::createConfig(); + } + $io = $this->getIO(); $cachePaths = [ diff --git a/vendor/composer/composer/src/Composer/Command/CompletionTrait.php b/vendor/composer/composer/src/Composer/Command/CompletionTrait.php index 89c6b68..444d695 100644 --- a/vendor/composer/composer/src/Composer/Command/CompletionTrait.php +++ b/vendor/composer/composer/src/Composer/Command/CompletionTrait.php @@ -117,6 +117,36 @@ private function suggestInstalledPackage(bool $includeRootPackage = true, bool $ }; } + /** + * Suggest package names from installed. + */ + private function suggestInstalledPackageTypes(bool $includeRootPackage = true): \Closure + { + return function (CompletionInput $input) use ($includeRootPackage): array { + $composer = $this->requireComposer(); + $installedRepos = []; + + if ($includeRootPackage) { + $installedRepos[] = new RootPackageRepository(clone $composer->getPackage()); + } + + $locker = $composer->getLocker(); + if ($locker->isLocked()) { + $installedRepos[] = $locker->getLockedRepository(true); + } else { + $installedRepos[] = $composer->getRepositoryManager()->getLocalRepository(); + } + + $installedRepo = new InstalledRepository($installedRepos); + + return array_values(array_unique( + array_map(static function (PackageInterface $package) { + return $package->getType(); + }, $installedRepo->getPackages()) + )); + }; + } + /** * Suggest package names available on all configured repositories. */ diff --git a/vendor/composer/composer/src/Composer/Command/ConfigCommand.php b/vendor/composer/composer/src/Composer/Command/ConfigCommand.php index cbdc174..de3bd36 100644 --- a/vendor/composer/composer/src/Composer/Command/ConfigCommand.php +++ b/vendor/composer/composer/src/Composer/Command/ConfigCommand.php @@ -291,7 +291,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $source = $this->config->getSourceOfValue($settingKey); if (Preg::isMatch('/^repos?(?:itories)?(?:\.(.+))?/', $settingKey, $matches)) { - if (!isset($matches[1]) || $matches[1] === '') { + if (!isset($matches[1])) { $value = $data['repositories'] ?? []; } else { if (!isset($data['repositories'][$matches[1]])) { @@ -469,6 +469,18 @@ static function ($val) { 'prepend-autoloader' => [$booleanValidator, $booleanNormalizer], 'disable-tls' => [$booleanValidator, $booleanNormalizer], 'secure-http' => [$booleanValidator, $booleanNormalizer], + 'bump-after-update' => [ + static function ($val): bool { + return in_array($val, ['dev', 'no-dev', 'true', 'false', '1', '0'], true); + }, + static function ($val) { + if ('dev' === $val || 'no-dev' === $val) { + return $val; + } + + return $val !== 'false' && (bool) $val; + }, + ], 'cafile' => [ static function ($val): bool { return file_exists($val) && Filesystem::isReadable($val); @@ -664,7 +676,7 @@ static function ($vals) { }], 'minimum-stability' => [ static function ($val): bool { - return isset(BasePackage::$stabilities[VersionParser::normalizeStability($val)]); + return isset(BasePackage::STABILITIES[VersionParser::normalizeStability($val)]); }, static function ($val): string { return VersionParser::normalizeStability($val); @@ -771,8 +783,12 @@ static function ($vals) { foreach ($bits as $bit) { $currentValue = $currentValue[$bit] ?? null; } - if (is_array($currentValue)) { - $value = array_merge($currentValue, $value); + if (is_array($currentValue) && is_array($value)) { + if (array_is_list($currentValue) && array_is_list($value)) { + $value = array_merge($currentValue, $value); + } else { + $value = $value + $currentValue; + } } } } @@ -1009,7 +1025,7 @@ private function getAuthConfigFile(InputInterface $input, Config $config): strin } /** - * Suggest setting-keys, while taking given options in acount. + * Suggest setting-keys, while taking given options in account. */ private function suggestSettingKeys(): \Closure { diff --git a/vendor/composer/composer/src/Composer/Command/CreateProjectCommand.php b/vendor/composer/composer/src/Composer/Command/CreateProjectCommand.php index b7e8736..0454efa 100644 --- a/vendor/composer/composer/src/Composer/Command/CreateProjectCommand.php +++ b/vendor/composer/composer/src/Composer/Command/CreateProjectCommand.php @@ -319,14 +319,6 @@ public function installProject(IOInterface $io, Config $config, InputInterface $ $composer->getEventDispatcher()->dispatchScript(ScriptEvents::POST_CREATE_PROJECT_CMD, $installDevPackages); chdir($oldCwd); - $vendorComposerDir = $config->get('vendor-dir').'/composer'; - if (is_dir($vendorComposerDir) && $fs->isDirEmpty($vendorComposerDir)) { - Silencer::call('rmdir', $vendorComposerDir); - $vendorDir = $config->get('vendor-dir'); - if (is_dir($vendorDir) && $fs->isDirEmpty($vendorDir)) { - Silencer::call('rmdir', $vendorDir); - } - } return 0; } @@ -338,10 +330,6 @@ public function installProject(IOInterface $io, Config $config, InputInterface $ */ protected function installRootPackage(InputInterface $input, IOInterface $io, Config $config, string $packageName, PlatformRequirementFilterInterface $platformRequirementFilter, ?string $directory = null, ?string $packageVersion = null, ?string $stability = 'stable', bool $preferSource = false, bool $preferDist = false, bool $installDevPackages = false, ?array $repositories = null, bool $disablePlugins = false, bool $disableScripts = false, bool $noProgress = false, bool $secureHttp = true): bool { - if (!$secureHttp) { - $config->merge(['config' => ['secure-http' => false]], Config::SOURCE_COMMAND); - } - $parser = new VersionParser(); $requirements = $parser->parseNameVersionPairs([$packageName]); $name = strtolower($requirements[0]['name']); @@ -354,12 +342,22 @@ protected function installRootPackage(InputInterface $input, IOInterface $io, Co $parts = explode("/", $name, 2); $directory = Platform::getCwd() . DIRECTORY_SEPARATOR . array_pop($parts); } + $directory = rtrim($directory, '/\\'); $process = new ProcessExecutor($io); $fs = new Filesystem($process); if (!$fs->isAbsolutePath($directory)) { $directory = Platform::getCwd() . DIRECTORY_SEPARATOR . $directory; } + if ('' === $directory) { + throw new \UnexpectedValueException('Got an empty target directory, something went wrong'); + } + + // set the base dir to ensure $config->all() below resolves the correct absolute paths to vendor-dir etc + $config->setBaseDir($directory); + if (!$secureHttp) { + $config->merge(['config' => ['secure-http' => false]], Config::SOURCE_COMMAND); + } $io->writeError('Creating a "' . $packageName . '" project at "' . $fs->findShortestPath(Platform::getCwd(), $directory, true) . '"'); @@ -375,7 +373,7 @@ protected function installRootPackage(InputInterface $input, IOInterface $io, Co if (null === $stability) { if (null === $packageVersion) { $stability = 'stable'; - } elseif (Preg::isMatchStrictGroups('{^[^,\s]*?@('.implode('|', array_keys(BasePackage::$stabilities)).')$}i', $packageVersion, $match)) { + } elseif (Preg::isMatchStrictGroups('{^[^,\s]*?@('.implode('|', array_keys(BasePackage::STABILITIES)).')$}i', $packageVersion, $match)) { $stability = $match[1]; } else { $stability = VersionParser::parseStability($packageVersion); @@ -384,12 +382,14 @@ protected function installRootPackage(InputInterface $input, IOInterface $io, Co $stability = VersionParser::normalizeStability($stability); - if (!isset(BasePackage::$stabilities[$stability])) { - throw new \InvalidArgumentException('Invalid stability provided ('.$stability.'), must be one of: '.implode(', ', array_keys(BasePackage::$stabilities))); + if (!isset(BasePackage::STABILITIES[$stability])) { + throw new \InvalidArgumentException('Invalid stability provided ('.$stability.'), must be one of: '.implode(', ', array_keys(BasePackage::STABILITIES))); } $composer = $this->createComposerInstance($input, $io, $config->all(), $disablePlugins, $disableScripts); $config = $composer->getConfig(); + // set the base dir here again on the new config instance, as otherwise in case the vendor dir is defined in an env var for example it would still override the value set above by $config->all() + $config->setBaseDir($directory); $rm = $composer->getRepositoryManager(); $repositorySet = new RepositorySet($stability); @@ -424,16 +424,21 @@ protected function installRootPackage(InputInterface $input, IOInterface $io, Co throw new \InvalidArgumentException($errorMessage .'.'); } + $oldCwd = Platform::getCwd(); // handler Ctrl+C aborts gracefully @mkdir($directory, 0777, true); if (false !== ($realDir = realpath($directory))) { - $signalHandler = SignalHandler::create([SignalHandler::SIGINT, SignalHandler::SIGTERM, SignalHandler::SIGHUP], function (string $signal, SignalHandler $handler) use ($realDir) { + $signalHandler = SignalHandler::create([SignalHandler::SIGINT, SignalHandler::SIGTERM, SignalHandler::SIGHUP], function (string $signal, SignalHandler $handler) use ($realDir, $oldCwd) { + chdir($oldCwd); $this->getIO()->writeError('Received '.$signal.', aborting', true, IOInterface::DEBUG); $fs = new Filesystem(); $fs->removeDirectory($realDir); $handler->exitWithLastSignal(); }); } + if (!chdir($directory)) { + throw new \RuntimeException('Failed to chdir into the new project dir at '.$directory); + } // avoid displaying 9999999-dev as version if default-branch was selected if ($package instanceof AliasPackage && $package->getPrettyVersion() === VersionParser::DEFAULT_BRANCH_ALIAS) { @@ -467,7 +472,6 @@ protected function installRootPackage(InputInterface $input, IOInterface $io, Co $installedFromVcs = 'source' === $package->getInstallationSource(); $io->writeError('Created project in ' . $directory . ''); - chdir($directory); // ensure that the env var being set does not interfere with create-project // as it is probably not meant to be used here, so we do not use it if a composer.json can be found diff --git a/vendor/composer/composer/src/Composer/Command/DiagnoseCommand.php b/vendor/composer/composer/src/Composer/Command/DiagnoseCommand.php index fc594f7..263ee06 100644 --- a/vendor/composer/composer/src/Composer/Command/DiagnoseCommand.php +++ b/vendor/composer/composer/src/Composer/Command/DiagnoseCommand.php @@ -19,6 +19,8 @@ use Composer\Downloader\TransportException; use Composer\IO\BufferIO; use Composer\Json\JsonFile; +use Composer\Json\JsonValidationException; +use Composer\Package\Locker; use Composer\Package\RootPackage; use Composer\Package\Version\VersionParser; use Composer\Pcre\Preg; @@ -44,6 +46,8 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Process\ExecutableFinder; +use Composer\Util\Http\ProxyManager; +use Composer\Util\Http\RequestProxy; /** * @author Jordi Boggiano @@ -87,6 +91,12 @@ protected function execute(InputInterface $input, OutputInterface $output): int $io->write('Checking composer.json: ', false); $this->outputResult($this->checkComposerSchema()); + + if ($composer->getLocker()->isLocked()) { + $io->write('Checking composer.lock: ', false); + $this->outputResult($this->checkComposerLockSchema($composer->getLocker())); + } + $this->process = $composer->getLoop()->getProcessExecutor() ?? new ProcessExecutor($io); } else { $this->process = new ProcessExecutor($io); @@ -115,10 +125,40 @@ protected function execute(InputInterface $input, OutputInterface $output): int $io->write('Checking https connectivity to packagist: ', false); $this->outputResult($this->checkHttp('https', $config)); - $opts = stream_context_get_options(StreamContextFactory::getContext('http://example.org')); - if (!empty($opts['http']['proxy'])) { + foreach ($config->getRepositories() as $repo) { + if (($repo['type'] ?? null) === 'composer' && isset($repo['url'])) { + $composerRepo = new ComposerRepository($repo, $this->getIO(), $config, $this->httpDownloader); + $reflMethod = new \ReflectionMethod($composerRepo, 'getPackagesJsonUrl'); + if (PHP_VERSION_ID < 80100) { + $reflMethod->setAccessible(true); + } + $url = $reflMethod->invoke($composerRepo); + if (!str_starts_with($url, 'http')) { + continue; + } + if (str_starts_with($url, 'https://repo.packagist.org')) { + continue; + } + $io->write('Checking connectivity to ' . $repo['url'].': ', false); + $this->outputResult($this->checkComposerRepo($url, $config)); + } + } + + $proxyManager = ProxyManager::getInstance(); + $protos = $config->get('disable-tls') === true ? ['http'] : ['http', 'https']; + try { + foreach ($protos as $proto) { + $proxy = $proxyManager->getProxyForRequest($proto.'://repo.packagist.org'); + if ($proxy->getStatus() !== '') { + $type = $proxy->isSecure() ? 'HTTPS' : 'HTTP'; + $io->write('Checking '.$type.' proxy with '.$proto.': ', false); + $this->outputResult($this->checkHttpProxy($proxy, $proto)); + } + } + } catch (TransportException $e) { $io->write('Checking HTTP proxy: ', false); - $this->outputResult($this->checkHttpProxy()); + $status = $this->checkConnectivityAndComposerNetworkHttpEnablement(); + $this->outputResult(is_string($status) ? $status : $e); } if (count($oauth = $config->get('github-oauth')) > 0) { @@ -135,7 +175,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int } elseif (10 > $rate['remaining']) { $io->write('WARNING'); $io->write(sprintf( - 'Github has a rate limit on their API. ' + 'GitHub has a rate limit on their API. ' . 'You currently have %u ' . 'out of %u requests left.' . PHP_EOL . 'See https://developer.github.com/v3/#rate-limiting and also' . PHP_EOL @@ -186,7 +226,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int } $io->write('OpenSSL version: ' . (defined('OPENSSL_VERSION_TEXT') ? ''.OPENSSL_VERSION_TEXT.'' : 'missing')); - $io->write('cURL version: ' . $this->getCurlVersion()); + $io->write('curl version: ' . $this->getCurlVersion()); $finder = new ExecutableFinder; $hasSystemUnzip = (bool) $finder->find('unzip'); @@ -235,6 +275,27 @@ private function checkComposerSchema() return true; } + /** + * @return string|true + */ + private function checkComposerLockSchema(Locker $locker) + { + $json = $locker->getJsonFile(); + + try { + $json->validateSchema(JsonFile::LOCK_SCHEMA); + } catch (JsonValidationException $e) { + $output = ''; + foreach ($e->getErrors() as $error) { + $output .= ''.$error.''.PHP_EOL; + } + + return trim($output); + } + + return true; + } + private function checkGit(): string { if (!function_exists('proc_open')) { @@ -298,31 +359,77 @@ private function checkHttp(string $proto, Config $config) } /** - * @return string|true|\Exception + * @return string|string[]|true + */ + private function checkComposerRepo(string $url, Config $config) + { + $result = $this->checkConnectivityAndComposerNetworkHttpEnablement(); + if ($result !== true) { + return $result; + } + + $result = []; + if (str_starts_with($url, 'https://') && $config->get('disable-tls') === true) { + $tlsWarning = 'Composer is configured to disable SSL/TLS protection. This will leave remote HTTPS requests vulnerable to Man-In-The-Middle attacks.'; + } + + try { + $this->httpDownloader->get($url); + } catch (TransportException $e) { + $hints = HttpDownloader::getExceptionHints($e); + if (null !== $hints && count($hints) > 0) { + foreach ($hints as $hint) { + $result[] = $hint; + } + } + + $result[] = '[' . get_class($e) . '] ' . $e->getMessage() . ''; + } + + if (isset($tlsWarning)) { + $result[] = $tlsWarning; + } + + if (count($result) > 0) { + return $result; + } + + return true; + } + + /** + * @return string|\Exception */ - private function checkHttpProxy() + private function checkHttpProxy(RequestProxy $proxy, string $protocol) { $result = $this->checkConnectivityAndComposerNetworkHttpEnablement(); if ($result !== true) { return $result; } - $protocol = extension_loaded('openssl') ? 'https' : 'http'; try { - $json = $this->httpDownloader->get($protocol . '://repo.packagist.org/packages.json')->decodeJson(); - $hash = reset($json['provider-includes']); - $hash = $hash['sha256']; - $path = str_replace('%hash%', $hash, key($json['provider-includes'])); - $provider = $this->httpDownloader->get($protocol . '://repo.packagist.org/'.$path)->getBody(); - - if (hash('sha256', $provider) !== $hash) { - return 'It seems that your proxy is modifying http traffic on the fly'; + $proxyStatus = $proxy->getStatus(); + + if ($proxy->isExcludedByNoProxy()) { + return 'SKIP Because repo.packagist.org is '.$proxyStatus.''; } + + $json = $this->httpDownloader->get($protocol.'://repo.packagist.org/packages.json')->decodeJson(); + if (isset($json['provider-includes'])) { + $hash = reset($json['provider-includes']); + $hash = $hash['sha256']; + $path = str_replace('%hash%', $hash, key($json['provider-includes'])); + $provider = $this->httpDownloader->get($protocol.'://repo.packagist.org/'.$path)->getBody(); + + if (hash('sha256', $provider) !== $hash) { + return 'It seems that your proxy ('.$proxyStatus.') is modifying '.$protocol.' traffic on the fly'; + } + } + + return 'OK '.$proxyStatus.''; } catch (\Exception $e) { return $e; } - - return true; } /** @@ -610,7 +717,7 @@ private function checkPlatform() $errors['ioncube'] = ioncube_loader_version(); } - if (PHP_VERSION_ID < 70205) { + if (\PHP_VERSION_ID < 70205) { $errors['php'] = PHP_VERSION; } @@ -658,6 +765,12 @@ private function checkPlatform() $warnings['onedrive'] = PHP_VERSION; } + if (extension_loaded('uopz') + && !(filter_var(ini_get('uopz.disable'), FILTER_VALIDATE_BOOLEAN) + || filter_var(ini_get('uopz.exit'), FILTER_VALIDATE_BOOLEAN))) { + $warnings['uopz'] = true; + } + if (!empty($errors)) { foreach ($errors as $error => $current) { switch ($error) { @@ -771,6 +884,11 @@ private function checkPlatform() $text .= "Upgrade your PHP ({$current}) to use this location with Composer.".PHP_EOL; break; + case 'uopz': + $text = "The uopz extension ignores exit calls and may not work with all Composer commands.".PHP_EOL; + $text .= "Disabling it when using Composer is recommended."; + break; + default: throw new \InvalidArgumentException(sprintf("DiagnoseCommand: Unknown warning type \"%s\". Please report at https://github.com/composer/composer/issues/new.", $warning)); } diff --git a/vendor/composer/composer/src/Composer/Command/DumpAutoloadCommand.php b/vendor/composer/composer/src/Composer/Command/DumpAutoloadCommand.php index c30fae7..cc0d7bf 100644 --- a/vendor/composer/composer/src/Composer/Command/DumpAutoloadCommand.php +++ b/vendor/composer/composer/src/Composer/Command/DumpAutoloadCommand.php @@ -12,6 +12,7 @@ namespace Composer\Command; +use Composer\Package\AliasPackage; use Composer\Plugin\CommandEvent; use Composer\Plugin\PluginEvents; use Symfony\Component\Console\Input\InputInterface; @@ -43,6 +44,7 @@ protected function configure() new InputOption('ignore-platform-req', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Ignore a specific platform requirement (php & ext- packages).'), new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore all platform requirements (php & ext- packages).'), new InputOption('strict-psr', null, InputOption::VALUE_NONE, 'Return a failed status code (1) if PSR-4 or PSR-0 mapping errors are present. Requires --optimize to work.'), + new InputOption('strict-ambiguous', null, InputOption::VALUE_NONE, 'Return a failed status code (2) if the same class is found in multiple files. Requires --optimize to work.'), ]) ->setHelp( <<getPackage(); $config = $composer->getConfig(); + $missingDependencies = false; + foreach ($localRepo->getCanonicalPackages() as $localPkg) { + $installPath = $installationManager->getInstallPath($localPkg); + if ($installPath !== null && file_exists($installPath) === false) { + $missingDependencies = true; + $this->getIO()->write('Not all dependencies are installed. Make sure to run a "composer install" to install missing dependencies'); + + break; + } + } + $optimize = $input->getOption('optimize') || $config->get('optimize-autoloader'); $authoritative = $input->getOption('classmap-authoritative') || $config->get('classmap-authoritative'); $apcuPrefix = $input->getOption('apcu-prefix'); @@ -74,6 +87,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int if ($input->getOption('strict-psr') && !$optimize && !$authoritative) { throw new \InvalidArgumentException('--strict-psr mode only works with optimized autoloader, use --optimize or --classmap-authoritative if you want a strict return value.'); } + if ($input->getOption('strict-ambiguous') && !$optimize && !$authoritative) { + throw new \InvalidArgumentException('--strict-ambiguous mode only works with optimized autoloader, use --optimize or --classmap-authoritative if you want a strict return value.'); + } if ($authoritative) { $this->getIO()->write('Generating optimized autoload files (authoritative)'); @@ -108,7 +124,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int 'composer', $optimize, null, - $composer->getLocker() + $composer->getLocker(), + $input->getOption('strict-ambiguous') ); $numberOfClasses = count($classMap); @@ -120,10 +137,14 @@ protected function execute(InputInterface $input, OutputInterface $output): int $this->getIO()->write('Generated autoload files'); } - if ($input->getOption('strict-psr') && count($classMap->getPsrViolations()) > 0) { + if ($missingDependencies || ($input->getOption('strict-psr') && count($classMap->getPsrViolations()) > 0)) { return 1; } + if ($input->getOption('strict-ambiguous') && count($classMap->getAmbiguousClasses(false)) > 0) { + return 2; + } + return 0; } } diff --git a/vendor/composer/composer/src/Composer/Command/GlobalCommand.php b/vendor/composer/composer/src/Composer/Command/GlobalCommand.php index c6fc7fe..2841c2a 100644 --- a/vendor/composer/composer/src/Composer/Command/GlobalCommand.php +++ b/vendor/composer/composer/src/Composer/Command/GlobalCommand.php @@ -33,9 +33,13 @@ public function complete(CompletionInput $input, CompletionSuggestions $suggesti { $application = $this->getApplication(); if ($input->mustSuggestArgumentValuesFor('command-name')) { - $suggestions->suggestValues(array_values(array_filter(array_map(static function (Command $command) { - return $command->isHidden() ? null : $command->getName(); - }, $application->all())))); + $suggestions->suggestValues(array_values(array_filter( + array_map(static function (Command $command) { + return $command->isHidden() ? null : $command->getName(); + }, $application->all()), function (?string $cmd) { + return $cmd !== null; + } + ))); return; } diff --git a/vendor/composer/composer/src/Composer/Command/InitCommand.php b/vendor/composer/composer/src/Composer/Command/InitCommand.php index 606bff8..6d7311d 100644 --- a/vendor/composer/composer/src/Composer/Command/InitCommand.php +++ b/vendor/composer/composer/src/Composer/Command/InitCommand.php @@ -21,6 +21,7 @@ use Composer\Repository\CompositeRepository; use Composer\Repository\PlatformRepository; use Composer\Repository\RepositoryFactory; +use Composer\Spdx\SpdxLicenses; use Composer\Util\Filesystem; use Composer\Util\Silencer; use Symfony\Component\Console\Input\ArrayInput; @@ -57,11 +58,11 @@ protected function configure() new InputOption('name', null, InputOption::VALUE_REQUIRED, 'Name of the package'), new InputOption('description', null, InputOption::VALUE_REQUIRED, 'Description of package'), new InputOption('author', null, InputOption::VALUE_REQUIRED, 'Author name of package'), - new InputOption('type', null, InputOption::VALUE_OPTIONAL, 'Type of package (e.g. library, project, metapackage, composer-plugin)'), + new InputOption('type', null, InputOption::VALUE_REQUIRED, 'Type of package (e.g. library, project, metapackage, composer-plugin)'), new InputOption('homepage', null, InputOption::VALUE_REQUIRED, 'Homepage of package'), new InputOption('require', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Package to require with a version constraint, e.g. foo/bar:1.0.0 or foo/bar=1.0.0 or "foo/bar 1.0.0"', null, $this->suggestAvailablePackageInclPlatform()), new InputOption('require-dev', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Package to require for development with a version constraint, e.g. foo/bar:1.0.0 or foo/bar=1.0.0 or "foo/bar 1.0.0"', null, $this->suggestAvailablePackageInclPlatform()), - new InputOption('stability', 's', InputOption::VALUE_REQUIRED, 'Minimum stability (empty or one of: '.implode(', ', array_keys(BasePackage::$stabilities)).')'), + new InputOption('stability', 's', InputOption::VALUE_REQUIRED, 'Minimum stability (empty or one of: '.implode(', ', array_keys(BasePackage::STABILITIES)).')'), new InputOption('license', 'l', InputOption::VALUE_REQUIRED, 'License of package'), new InputOption('repository', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Add custom repositories, either by URL or using JSON arrays'), new InputOption('autoload', 'a', InputOption::VALUE_REQUIRED, 'Add PSR-4 autoload mapping. Maps your package\'s namespace to the provided directory. (Expects a relative path, e.g. src/)'), @@ -87,7 +88,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $io = $this->getIO(); $allowlist = ['name', 'description', 'author', 'type', 'homepage', 'require', 'require-dev', 'stability', 'license', 'autoload']; - $options = array_filter(array_intersect_key($input->getOptions(), array_flip($allowlist))); + $options = array_filter(array_intersect_key($input->getOptions(), array_flip($allowlist)), function ($val) { return $val !== null && $val !== []; }); if (isset($options['name']) && !Preg::isMatch('{^[a-z0-9_.-]+/[a-z0-9_.-]+$}D', $options['name'])) { throw new \InvalidArgumentException( @@ -364,10 +365,10 @@ static function ($value) use ($minimumStability) { return $minimumStability; } - if (!isset(BasePackage::$stabilities[$value])) { + if (!isset(BasePackage::STABILITIES[$value])) { throw new \InvalidArgumentException( 'Invalid minimum stability "'.$value.'". Must be empty or one of: '. - implode(', ', array_keys(BasePackage::$stabilities)) + implode(', ', array_keys(BasePackage::STABILITIES)) ); } @@ -378,11 +379,14 @@ static function ($value) use ($minimumStability) { ); $input->setOption('stability', $minimumStability); - $type = $input->getOption('type') ?: false; + $type = $input->getOption('type'); $type = $io->ask( 'Package Type (e.g. library, project, metapackage, composer-plugin) ['.$type.']: ', $type ); + if ($type === '' || $type === false) { + $type = null; + } $input->setOption('type', $type); if (null === $license = $input->getOption('license')) { @@ -395,6 +399,10 @@ static function ($value) use ($minimumStability) { 'License ['.$license.']: ', $license ); + $spdx = new SpdxLicenses(); + if (null !== $license && !$spdx->validate($license) && $license !== 'proprietary') { + throw new \InvalidArgumentException('Invalid license provided: '.$license.'. Only SPDX license identifiers (https://spdx.org/licenses/) or "proprietary" are accepted.'); + } $input->setOption('license', $license); $io->writeError(['', 'Define your dependencies.', '']); @@ -465,8 +473,6 @@ static function ($value) use ($autoload) { private function parseAuthorString(string $author): array { if (Preg::isMatch('/^(?P[- .,\p{L}\p{N}\p{Mn}\'’"()]+)(?:\s+<(?P.+?)>)?$/u', $author, $match)) { - assert(is_string($match['name'])); - if (null !== $match['email'] && !$this->isValidEmail($match['email'])) { throw new \InvalidArgumentException('Invalid email "'.$match['email'].'"'); } diff --git a/vendor/composer/composer/src/Composer/Command/OutdatedCommand.php b/vendor/composer/composer/src/Composer/Command/OutdatedCommand.php index 139fe45..0fea6dc 100644 --- a/vendor/composer/composer/src/Composer/Command/OutdatedCommand.php +++ b/vendor/composer/composer/src/Composer/Command/OutdatedCommand.php @@ -71,6 +71,18 @@ protected function execute(InputInterface $input, OutputInterface $output): int 'command' => 'show', '--latest' => true, ]; + if ($input->getOption('no-interaction')) { + $args['--no-interaction'] = true; + } + if ($input->getOption('no-plugins')) { + $args['--no-plugins'] = true; + } + if ($input->getOption('no-scripts')) { + $args['--no-scripts'] = true; + } + if ($input->getOption('no-cache')) { + $args['--no-cache'] = true; + } if (!$input->getOption('all')) { $args['--outdated'] = true; } diff --git a/vendor/composer/composer/src/Composer/Command/PackageDiscoveryTrait.php b/vendor/composer/composer/src/Composer/Command/PackageDiscoveryTrait.php index d95e06d..0bbd2a4 100644 --- a/vendor/composer/composer/src/Composer/Command/PackageDiscoveryTrait.php +++ b/vendor/composer/composer/src/Composer/Command/PackageDiscoveryTrait.php @@ -16,6 +16,7 @@ use Composer\Filter\PlatformRequirementFilter\IgnoreAllPlatformRequirementFilter; use Composer\Filter\PlatformRequirementFilter\PlatformRequirementFilterFactory; use Composer\IO\IOInterface; +use Composer\Package\BasePackage; use Composer\Package\CompletePackageInterface; use Composer\Package\PackageInterface; use Composer\Package\Version\VersionParser; @@ -52,6 +53,9 @@ protected function getRepos(): CompositeRepository return $this->repos; } + /** + * @param key-of|null $minimumStability + */ private function getRepositorySet(InputInterface $input, ?string $minimumStability = null): RepositorySet { $key = $minimumStability ?? 'default'; @@ -64,6 +68,9 @@ private function getRepositorySet(InputInterface $input, ?string $minimumStabili return $this->repositorySets[$key]; } + /** + * @return key-of + */ private function getMinimumStability(InputInterface $input): string { if ($input->hasOption('stability')) { // @phpstan-ignore-line as InitCommand does have this option but not all classes using this trait do @@ -96,7 +103,7 @@ final protected function determineRequirements(InputInterface $input, OutputInte foreach ($requires as $requirement) { if (isset($requirement['version']) && Preg::isMatch('{^\d+(\.\d+)?$}', $requirement['version'])) { - $io->writeError('The "'.$requirement['version'].'" constraint for "'.$requirement['name'].'" appears too strict and will likely not match what you want. See https://getcomposer.org/constraints'); + $io->writeError('The "'.$requirement['version'].'" constraint for "'.$requirement['name'].'" appears too strict and will likely not match what you want. See https://getcomposer.org/constraints'); } if (!isset($requirement['version'])) { diff --git a/vendor/composer/composer/src/Composer/Command/ReinstallCommand.php b/vendor/composer/composer/src/Composer/Command/ReinstallCommand.php index 446d9ee..cb7882a 100644 --- a/vendor/composer/composer/src/Composer/Command/ReinstallCommand.php +++ b/vendor/composer/composer/src/Composer/Command/ReinstallCommand.php @@ -51,7 +51,8 @@ protected function configure(): void new InputOption('apcu-autoloader-prefix', null, InputOption::VALUE_REQUIRED, 'Use a custom prefix for the APCu autoloader cache. Implicitly enables --apcu-autoloader'), new InputOption('ignore-platform-req', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Ignore a specific platform requirement (php & ext- packages).'), new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore all platform requirements (php & ext- packages).'), - new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::REQUIRED, 'List of package names to reinstall, can include a wildcard (*) to match any substring.', null, $this->suggestInstalledPackage(false)), + new InputOption('type', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Filter packages to reinstall by type(s)', null, $this->suggestInstalledPackageTypes(false)), + new InputArgument('packages', InputArgument::IS_ARRAY, 'List of package names to reinstall, can include a wildcard (*) to match any substring.', null, $this->suggestInstalledPackage(false)), ]) ->setHelp( <<getRepositoryManager()->getLocalRepository(); $packagesToReinstall = []; $packageNamesToReinstall = []; - foreach ($input->getArgument('packages') as $pattern) { - $patternRegexp = BasePackage::packageNameToRegexp($pattern); - $matched = false; + if (\count($input->getOption('type')) > 0) { + if (\count($input->getArgument('packages')) > 0) { + throw new \InvalidArgumentException('You cannot specify package names and filter by type at the same time.'); + } foreach ($localRepo->getCanonicalPackages() as $package) { - if (Preg::isMatch($patternRegexp, $package->getName())) { - $matched = true; + if (in_array($package->getType(), $input->getOption('type'), true)) { $packagesToReinstall[] = $package; $packageNamesToReinstall[] = $package->getName(); } } + } else { + if (\count($input->getArgument('packages')) === 0) { + throw new \InvalidArgumentException('You must pass one or more package names to be reinstalled.'); + } + foreach ($input->getArgument('packages') as $pattern) { + $patternRegexp = BasePackage::packageNameToRegexp($pattern); + $matched = false; + foreach ($localRepo->getCanonicalPackages() as $package) { + if (Preg::isMatch($patternRegexp, $package->getName())) { + $matched = true; + $packagesToReinstall[] = $package; + $packageNamesToReinstall[] = $package->getName(); + } + } - if (!$matched) { - $io->writeError('Pattern "' . $pattern . '" does not match any currently installed packages.'); + if (!$matched) { + $io->writeError('Pattern "' . $pattern . '" does not match any currently installed packages.'); + } } } - if (!$packagesToReinstall) { + if (0 === \count($packagesToReinstall)) { $io->writeError('Found no packages to reinstall, aborting.'); return 1; diff --git a/vendor/composer/composer/src/Composer/Command/RemoveCommand.php b/vendor/composer/composer/src/Composer/Command/RemoveCommand.php index b40fb77..9803190 100644 --- a/vendor/composer/composer/src/Composer/Command/RemoveCommand.php +++ b/vendor/composer/composer/src/Composer/Command/RemoveCommand.php @@ -43,7 +43,7 @@ protected function configure() { $this ->setName('remove') - ->setAliases(['rm']) + ->setAliases(['rm', 'uninstall']) ->setDescription('Removes a package from the require or require-dev') ->setDefinition([ new InputArgument('packages', InputArgument::IS_ARRAY, 'Packages that should be removed.', null, $this->suggestRootRequirement()), diff --git a/vendor/composer/composer/src/Composer/Command/RequireCommand.php b/vendor/composer/composer/src/Composer/Command/RequireCommand.php index b7ee156..6f1b9ea 100644 --- a/vendor/composer/composer/src/Composer/Command/RequireCommand.php +++ b/vendor/composer/composer/src/Composer/Command/RequireCommand.php @@ -402,6 +402,8 @@ private function getPackagesByRequireKey(): array /** * @param array $requirements + * @param 'require'|'require-dev' $requireKey + * @param 'require'|'require-dev' $removeKey * @throws \Exception */ private function doUpdate(InputInterface $input, OutputInterface $output, IOInterface $io, array $requirements, string $requireKey, string $removeKey): int @@ -559,10 +561,16 @@ private function updateRequirementsAfterResolution(array $requirementsToUpdate, } $lockFile = Factory::getLockFile($this->json->getPath()); if (file_exists($lockFile)) { + $stabilityFlags = RootPackageLoader::extractStabilityFlags($requirements, $composer->getPackage()->getMinimumStability(), []); + $lockMtime = filemtime($lockFile); $lock = new JsonFile($lockFile); $lockData = $lock->read(); $lockData['content-hash'] = Locker::getContentHash($contents); + foreach ($stabilityFlags as $packageName => $flag) { + $lockData['stability-flags'][$packageName] = $flag; + } + ksort($lockData['stability-flags']); $lock->write($lockData); if (is_int($lockMtime)) { @touch($lockFile, $lockMtime); diff --git a/vendor/composer/composer/src/Composer/Command/SelfUpdateCommand.php b/vendor/composer/composer/src/Composer/Command/SelfUpdateCommand.php index 26d9f75..6ca0112 100644 --- a/vendor/composer/composer/src/Composer/Command/SelfUpdateCommand.php +++ b/vendor/composer/composer/src/Composer/Command/SelfUpdateCommand.php @@ -146,7 +146,7 @@ class_exists('Composer\Downloader\FilesystemException'); $homeDirOwnerId = fileowner($home); if (is_array($composerUser) && $homeDirOwnerId !== false) { $homeOwner = posix_getpwuid($homeDirOwnerId); - if (is_array($homeOwner) && isset($composerUser['name'], $homeOwner['name']) && $composerUser['name'] !== $homeOwner['name']) { + if (is_array($homeOwner) && $composerUser['name'] !== $homeOwner['name']) { $io->writeError('You are running Composer as "'.$composerUser['name'].'", while "'.$home.'" is owned by "'.$homeOwner['name'].'"'); } } @@ -328,8 +328,8 @@ class_exists('Composer\Downloader\FilesystemException'); $verified = 1 === openssl_verify((string) file_get_contents($tempFilename), $signatureSha384, $pubkeyid, $algo); // PHP 8 automatically frees the key instance and deprecates the function - if (PHP_VERSION_ID < 80000) { - // @phpstan-ignore-next-line + if (\PHP_VERSION_ID < 80000) { + // @phpstan-ignore function.deprecated openssl_free_key($pubkeyid); } diff --git a/vendor/composer/composer/src/Composer/Command/ShowCommand.php b/vendor/composer/composer/src/Composer/Command/ShowCommand.php index 92a6e62..14c9a4c 100644 --- a/vendor/composer/composer/src/Composer/Command/ShowCommand.php +++ b/vendor/composer/composer/src/Composer/Command/ShowCommand.php @@ -43,6 +43,7 @@ use Composer\Semver\Semver; use Composer\Spdx\SpdxLicenses; use Composer\Util\PackageInfo; +use DateTimeInterface; use Symfony\Component\Console\Completion\CompletionInput; use Symfony\Component\Console\Formatter\OutputFormatter; use Symfony\Component\Console\Formatter\OutputFormatterStyle; @@ -493,7 +494,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $writeVersion = !$input->getOption('name-only') && !$input->getOption('path') && $showVersion; $writeLatest = $writeVersion && $showLatest; $writeDescription = !$input->getOption('name-only') && !$input->getOption('path'); - $writeReleaseDate = $writeLatest && $input->getOption('sort-by-age'); + $writeReleaseDate = $writeLatest && ($input->getOption('sort-by-age') || $format === 'json'); $hasOutdatedPackages = false; @@ -535,10 +536,13 @@ protected function execute(InputInterface $input, OutputInterface $output): int $packageViewData['homepage'] = $package instanceof CompletePackageInterface ? $package->getHomepage() : null; $packageViewData['source'] = PackageInfo::getViewSourceUrl($package); } - $nameLength = max($nameLength, strlen($package->getPrettyName())); + $nameLength = max($nameLength, strlen($packageViewData['name'])); if ($writeVersion) { $packageViewData['version'] = $package->getFullPrettyVersion(); - $versionLength = max($versionLength, strlen($package->getFullPrettyVersion())); + if ($format === 'text') { + $packageViewData['version'] = ltrim($packageViewData['version'], 'v'); + } + $versionLength = max($versionLength, strlen($packageViewData['version'])); } if ($writeReleaseDate) { if ($package->getReleaseDate() !== null) { @@ -547,14 +551,25 @@ protected function execute(InputInterface $input, OutputInterface $output): int $packageViewData['release-age'] = 'from '.$packageViewData['release-age']; } $releaseDateLength = max($releaseDateLength, strlen($packageViewData['release-age'])); + $packageViewData['release-date'] = $package->getReleaseDate()->format(DateTimeInterface::ATOM); } else { $packageViewData['release-age'] = ''; + $packageViewData['release-date'] = ''; } } if ($writeLatest && $latestPackage) { $packageViewData['latest'] = $latestPackage->getFullPrettyVersion(); + if ($format === 'text') { + $packageViewData['latest'] = ltrim($packageViewData['latest'], 'v'); + } $packageViewData['latest-status'] = $this->getUpdateStatus($latestPackage, $package); $latestLength = max($latestLength, strlen($packageViewData['latest'])); + + if ($latestPackage->getReleaseDate() !== null) { + $packageViewData['latest-release-date'] = $latestPackage->getReleaseDate()->format(DateTimeInterface::ATOM); + } else { + $packageViewData['latest-release-date'] = ''; + } } elseif ($writeLatest) { $packageViewData['latest'] = '[none matched]'; $packageViewData['latest-status'] = 'up-to-date'; @@ -802,7 +817,8 @@ protected function getPackage(InstalledRepository $installedRepo, RepositoryInte $pool = $repositorySet->createPoolForPackage($name); } $matches = $pool->whatProvides($name, $constraint); - foreach ($matches as $index => $package) { + $literals = []; + foreach ($matches as $package) { // avoid showing the 9999999-dev alias if the default branch has no branch-alias set if ($package instanceof AliasPackage && $package->getVersion() === VersionParser::DEFAULT_BRANCH_ALIAS) { $package = $package->getAliasOf(); @@ -814,11 +830,12 @@ protected function getPackage(InstalledRepository $installedRepo, RepositoryInte } $versions[$package->getPrettyVersion()] = $package->getVersion(); - $matches[$index] = $package->getId(); + $literals[] = $package->getId(); } // select preferred package according to policy rules - if (null === $matchedPackage && $matches && $preferred = $policy->selectPreferredPackages($pool, $matches)) { + if (null === $matchedPackage && \count($literals) > 0) { + $preferred = $policy->selectPreferredPackages($pool, $literals); $matchedPackage = $pool->literalToPackage($preferred[0]); } @@ -1448,7 +1465,7 @@ private function findLatestPackage(PackageInterface $package, Composer $composer $stability = $composer->getPackage()->getMinimumStability(); $flags = $composer->getPackage()->getStabilityFlags(); if (isset($flags[$name])) { - $stability = array_search($flags[$name], BasePackage::$stabilities, true); + $stability = array_search($flags[$name], BasePackage::STABILITIES, true); } $bestStability = $stability; diff --git a/vendor/composer/composer/src/Composer/Command/UpdateCommand.php b/vendor/composer/composer/src/Composer/Command/UpdateCommand.php index 40e5661..6747242 100644 --- a/vendor/composer/composer/src/Composer/Command/UpdateCommand.php +++ b/vendor/composer/composer/src/Composer/Command/UpdateCommand.php @@ -16,20 +16,28 @@ use Composer\DependencyResolver\Request; use Composer\Installer; use Composer\IO\IOInterface; +use Composer\Package\BasePackage; use Composer\Package\Loader\RootPackageLoader; +use Composer\Package\PackageInterface; +use Composer\Package\Version\VersionSelector; use Composer\Pcre\Preg; use Composer\Plugin\CommandEvent; use Composer\Plugin\PluginEvents; use Composer\Package\Version\VersionParser; +use Composer\Repository\CompositeRepository; +use Composer\Repository\PlatformRepository; +use Composer\Repository\RepositoryInterface; +use Composer\Repository\RepositorySet; +use Composer\Semver\Constraint\MultiConstraint; use Composer\Semver\Intervals; use Composer\Util\HttpDownloader; use Composer\Advisory\Auditor; +use Composer\Util\Platform; use Symfony\Component\Console\Helper\Table; use Symfony\Component\Console\Input\InputInterface; use Composer\Console\Input\InputOption; use Composer\Console\Input\InputArgument; use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Question\Question; /** * @author Jordi Boggiano @@ -76,8 +84,10 @@ protected function configure() new InputOption('prefer-stable', null, InputOption::VALUE_NONE, 'Prefer stable versions of dependencies (can also be set via the COMPOSER_PREFER_STABLE=1 env var).'), new InputOption('prefer-lowest', null, InputOption::VALUE_NONE, 'Prefer lowest versions of dependencies (can also be set via the COMPOSER_PREFER_LOWEST=1 env var).'), new InputOption('minimal-changes', 'm', InputOption::VALUE_NONE, 'During a partial update with -w/-W, only perform absolutely necessary changes to transitive dependencies (can also be set via the COMPOSER_MINIMAL_CHANGES=1 env var).'), + new InputOption('patch-only', null, InputOption::VALUE_NONE, 'Only allow patch version updates for currently installed dependencies.'), new InputOption('interactive', 'i', InputOption::VALUE_NONE, 'Interactive interface with autocompletion to select the packages to update.'), new InputOption('root-reqs', null, InputOption::VALUE_NONE, 'Restricts the update to your first degree dependencies.'), + new InputOption('bump-after-update', null, InputOption::VALUE_OPTIONAL, 'Runs bump after performing the update.', false, ['dev', 'no-dev', 'all']), ]) ->setHelp( <<getOption('patch-only')) { + if (!$composer->getLocker()->isLocked()) { + throw new \InvalidArgumentException('patch-only can only be used with a lock file present'); + } + foreach ($composer->getLocker()->getLockedRepository(true)->getCanonicalPackages() as $package) { + if ($package->isDev()) { + continue; + } + if (!Preg::isMatch('{^(\d+\.\d+\.\d+)}', $package->getVersion(), $match)) { + continue; + } + $constraint = $parser->parseConstraints('~'.$match[1]); + if (isset($temporaryConstraints[$package->getName()])) { + $temporaryConstraints[$package->getName()] = MultiConstraint::create([$temporaryConstraints[$package->getName()], $constraint], true); + } else { + $temporaryConstraints[$package->getName()] = $constraint; + } + } + } + if ($input->getOption('interactive')) { $packages = $this->getPackagesInteractively($io, $input, $output, $composer, $packages); } @@ -248,7 +278,28 @@ protected function execute(InputInterface $input, OutputInterface $output): int $install->disablePlugins(); } - return $install->run(); + $result = $install->run(); + + if ($result === 0) { + $bumpAfterUpdate = $input->getOption('bump-after-update'); + if (false === $bumpAfterUpdate) { + $bumpAfterUpdate = $composer->getConfig()->get('bump-after-update'); + } + + if (false !== $bumpAfterUpdate) { + $io->writeError('Bumping dependencies'); + $bumpCommand = new BumpCommand(); + $bumpCommand->setComposer($composer); + $result = $bumpCommand->doBump( + $io, + $bumpAfterUpdate === 'dev', + $bumpAfterUpdate === 'no-dev', + $input->getOption('dry-run'), + $input->getArgument('packages') + ); + } + } + return $result; } /** @@ -261,46 +312,53 @@ private function getPackagesInteractively(IOInterface $io, InputInterface $input throw new \InvalidArgumentException('--interactive cannot be used in non-interactive terminals.'); } + $platformReqFilter = $this->getPlatformRequirementFilter($input); + $stabilityFlags = $composer->getPackage()->getStabilityFlags(); $requires = array_merge( $composer->getPackage()->getRequires(), $composer->getPackage()->getDevRequires() ); - $autocompleterValues = []; - foreach ($requires as $require) { - $target = $require->getTarget(); - $autocompleterValues[strtolower($target)] = $target; - } - - $installedPackages = $composer->getRepositoryManager()->getLocalRepository()->getPackages(); - foreach ($installedPackages as $package) { - $autocompleterValues[$package->getName()] = $package->getPrettyName(); - } - $helper = $this->getHelper('question'); - $question = new Question('Enter package name: ', null); + $filter = \count($packages) > 0 ? BasePackage::packageNamesToRegexp($packages) : null; - $io->writeError('Press enter without value to end submission'); - - do { - $autocompleterValues = array_diff($autocompleterValues, $packages); - $question->setAutocompleterValues($autocompleterValues); - $addedPackage = $helper->ask($input, $output, $question); - - if (!is_string($addedPackage) || empty($addedPackage)) { - break; + $io->writeError('Loading packages that can be updated...'); + $autocompleterValues = []; + $installedPackages = $composer->getLocker()->isLocked() ? $composer->getLocker()->getLockedRepository(true)->getPackages() : $composer->getRepositoryManager()->getLocalRepository()->getPackages(); + $versionSelector = $this->createVersionSelector($composer); + foreach ($installedPackages as $package) { + if ($filter !== null && !Preg::isMatch($filter, $package->getName())) { + continue; } - - $addedPackage = strtolower($addedPackage); - if (!in_array($addedPackage, $packages)) { - $packages[] = $addedPackage; + $currentVersion = $package->getPrettyVersion(); + $constraint = isset($requires[$package->getName()]) ? $requires[$package->getName()]->getPrettyConstraint() : null; + $stability = isset($stabilityFlags[$package->getName()]) ? (string) array_search($stabilityFlags[$package->getName()], BasePackage::STABILITIES, true) : $composer->getPackage()->getMinimumStability(); + $latestVersion = $versionSelector->findBestCandidate($package->getName(), $constraint, $stability, $platformReqFilter); + if ($latestVersion !== false && ($package->getVersion() !== $latestVersion->getVersion() || $latestVersion->isDev())) { + $autocompleterValues[$package->getName()] = '' . $currentVersion . ' => ' . $latestVersion->getPrettyVersion() . ''; + } + } + if (0 === \count($installedPackages)) { + foreach ($requires as $req => $constraint) { + if (PlatformRepository::isPlatformPackage($req)) { + continue; + } + $autocompleterValues[$req] = ''; } - } while (true); + } - $packages = array_filter($packages); - if (!$packages) { - throw new \InvalidArgumentException('You must enter minimum one package.'); + if (0 === \count($autocompleterValues)) { + throw new \RuntimeException('Could not find any package with new versions available'); } + $packages = $io->select( + 'Select packages: (Select more than one value separated by comma) ', + $autocompleterValues, + false, + 1, + 'No package named "%s" is installed.', + true + ); + $table = new Table($output); $table->setHeaders(['Selected packages']); foreach ($packages as $package) { @@ -317,4 +375,14 @@ private function getPackagesInteractively(IOInterface $io, InputInterface $input throw new \RuntimeException('Installation aborted.'); } + + private function createVersionSelector(Composer $composer): VersionSelector + { + $repositorySet = new RepositorySet(); + $repositorySet->addRepository(new CompositeRepository(array_filter($composer->getRepositoryManager()->getRepositories(), function (RepositoryInterface $repository) { + return !$repository instanceof PlatformRepository; + }))); + + return new VersionSelector($repositorySet); + } } diff --git a/vendor/composer/composer/src/Composer/Compiler.php b/vendor/composer/composer/src/Composer/Compiler.php index 9a2e27f..def3ff8 100644 --- a/vendor/composer/composer/src/Composer/Compiler.php +++ b/vendor/composer/composer/src/Composer/Compiler.php @@ -120,6 +120,7 @@ public function compile(string $pharFile = 'composer.phar'): void ->notPath('/bin\/(jsonlint|validate-json|simple-phpunit|phpstan|phpstan\.phar)(\.bat)?$/') ->notPath('justinrainbow/json-schema/demo/') ->notPath('justinrainbow/json-schema/dist/') + ->notPath('composer/pcre/extension.neon') ->notPath('composer/LICENSE') ->exclude('Tests') ->exclude('tests') diff --git a/vendor/composer/composer/src/Composer/Composer.php b/vendor/composer/composer/src/Composer/Composer.php index 542c5bc..4d5aefb 100644 --- a/vendor/composer/composer/src/Composer/Composer.php +++ b/vendor/composer/composer/src/Composer/Composer.php @@ -51,9 +51,9 @@ class Composer extends PartialComposer * * @see getVersion() */ - public const VERSION = '2.7.2'; + public const VERSION = '2.8.1'; public const BRANCH_ALIAS_VERSION = ''; - public const RELEASE_DATE = '2024-03-11 17:12:18'; + public const RELEASE_DATE = '2024-10-04 11:31:01'; public const SOURCE_VERSION = ''; /** diff --git a/vendor/composer/composer/src/Composer/Config.php b/vendor/composer/composer/src/Composer/Config.php index 8d2885a..f39579e 100644 --- a/vendor/composer/composer/src/Composer/Config.php +++ b/vendor/composer/composer/src/Composer/Config.php @@ -84,6 +84,8 @@ class Config 'gitlab-token' => [], 'http-basic' => [], 'bearer' => [], + 'bump-after-update' => false, + 'allow-missing-requirements' => false, ]; /** @var array */ @@ -96,7 +98,7 @@ class Config /** @var array */ private $config; - /** @var ?string */ + /** @var ?non-empty-string */ private $baseDir; /** @var array */ private $repositories; @@ -125,7 +127,7 @@ public function __construct(bool $useEnvironment = true, ?string $baseDir = null $this->config = static::$defaultConfig; $this->repositories = static::$defaultRepositories; - $this->useEnvironment = (bool) $useEnvironment; + $this->useEnvironment = $useEnvironment; $this->baseDir = is_string($baseDir) && '' !== $baseDir ? $baseDir : null; foreach ($this->config as $configKey => $configValue) { @@ -137,6 +139,18 @@ public function __construct(bool $useEnvironment = true, ?string $baseDir = null } } + /** + * Changing this can break path resolution for relative config paths so do not call this without knowing what you are doing + * + * The $baseDir should be an absolute path and without trailing slash + * + * @param non-empty-string|null $baseDir + */ + public function setBaseDir(?string $baseDir): void + { + $this->baseDir = $baseDir; + } + public function setConfigSource(ConfigSourceInterface $source): void { $this->configSource = $source; @@ -440,9 +454,9 @@ public function get(string $key, int $flags = 0) $result = $this->config[$key]; $abandonedEnv = $this->getComposerEnv('COMPOSER_AUDIT_ABANDONED'); if (false !== $abandonedEnv) { - if (!in_array($abandonedEnv, $validChoices = [Auditor::ABANDONED_IGNORE, Auditor::ABANDONED_REPORT, Auditor::ABANDONED_FAIL], true)) { + if (!in_array($abandonedEnv, $validChoices = Auditor::ABANDONEDS, true)) { throw new \RuntimeException( - "Invalid value for COMPOSER_AUDIT_ABANDONED: {$abandonedEnv}. Expected ".Auditor::ABANDONED_IGNORE.", ".Auditor::ABANDONED_REPORT." or ".Auditor::ABANDONED_FAIL + "Invalid value for COMPOSER_AUDIT_ABANDONED: {$abandonedEnv}. Expected one of ".implode(', ', Auditor::ABANDONEDS)."." ); } $result['abandoned'] = $abandonedEnv; @@ -529,7 +543,6 @@ private function process($value, int $flags) } return Preg::replaceCallback('#\{\$(.+)\}#', function ($match) use ($flags) { - assert(is_string($match[1])); return $this->get($match[1], $flags); }, $value); } @@ -545,7 +558,7 @@ private function realpath(string $path): string return $path; } - return $this->baseDir ? $this->baseDir . '/' . $path : $path; + return $this->baseDir !== null ? $this->baseDir . '/' . $path : $path; } /** @@ -584,8 +597,8 @@ private function disableRepoByName(string $name): void */ public function prohibitUrlByConfig(string $url, ?IOInterface $io = null, array $repoOptions = []): void { - // Return right away if the URL is malformed or custom (see issue #5173) - if (false === filter_var($url, FILTER_VALIDATE_URL)) { + // Return right away if the URL is malformed or custom (see issue #5173), but only for non-HTTP(S) URLs + if (false === filter_var($url, FILTER_VALIDATE_URL) && !Preg::isMatch('{^https?://}', $url)) { return; } diff --git a/vendor/composer/composer/src/Composer/Config/JsonConfigSource.php b/vendor/composer/composer/src/Composer/Config/JsonConfigSource.php index db3d36d..596d14f 100644 --- a/vendor/composer/composer/src/Composer/Config/JsonConfigSource.php +++ b/vendor/composer/composer/src/Composer/Config/JsonConfigSource.php @@ -162,7 +162,7 @@ public function addProperty(string $name, $value): void public function removeProperty(string $name): void { $this->manipulateJson('removeProperty', static function (&$config, $key): void { - if (strpos($key, 'extra.') === 0 || strpos($key, 'scripts.') === 0) { + if (strpos($key, 'extra.') === 0 || strpos($key, 'scripts.') === 0 || stripos($key, 'autoload.') === 0 || stripos($key, 'autoload-dev.') === 0) { $bits = explode('.', $key); $last = array_pop($bits); $arr = &$config[reset($bits)]; diff --git a/vendor/composer/composer/src/Composer/Console/Application.php b/vendor/composer/composer/src/Composer/Console/Application.php index fa78553..dcf777f 100644 --- a/vendor/composer/composer/src/Composer/Console/Application.php +++ b/vendor/composer/composer/src/Composer/Console/Application.php @@ -12,6 +12,7 @@ namespace Composer\Console; +use Composer\Installer; use Composer\IO\NullIO; use Composer\Util\Filesystem; use Composer\Util\Platform; @@ -32,6 +33,7 @@ use Composer\Command; use Composer\Composer; use Composer\Factory; +use Composer\Downloader\TransportException; use Composer\IO\IOInterface; use Composer\IO\ConsoleIO; use Composer\Json\JsonValidationException; @@ -150,7 +152,10 @@ public function doRun(InputInterface $input, OutputInterface $output): int $this->disablePluginsByDefault = $input->hasParameterOption('--no-plugins'); $this->disableScriptsByDefault = $input->hasParameterOption('--no-scripts'); - $stdin = defined('STDIN') ? STDIN : fopen('php://stdin', 'r'); + static $stdin = null; + if (null === $stdin) { + $stdin = defined('STDIN') ? STDIN : fopen('php://stdin', 'r'); + } if (Platform::getEnv('COMPOSER_TESTS_ARE_RUNNING') !== '1' && (Platform::getEnv('COMPOSER_NO_INTERACTION') || $stdin === false || !Platform::isTty($stdin))) { $input->setInteractive(false); } @@ -190,13 +195,29 @@ public function doRun(InputInterface $input, OutputInterface $output): int } // prompt user for dir change if no composer.json is present in current dir - if ($io->isInteractive() && null === $newWorkDir && !in_array($commandName, ['', 'list', 'init', 'about', 'help', 'diagnose', 'self-update', 'global', 'create-project', 'outdated'], true) && !file_exists(Factory::getComposerFile()) && ($useParentDirIfNoJsonAvailable = $this->getUseParentDirConfigValue()) !== false) { + if ( + null === $newWorkDir + // do not prompt for commands that can function without composer.json + && !in_array($commandName, ['', 'list', 'init', 'about', 'help', 'diagnose', 'self-update', 'global', 'create-project', 'outdated'], true) + && !file_exists(Factory::getComposerFile()) + // if use-parent-dir is disabled we should not prompt + && ($useParentDirIfNoJsonAvailable = $this->getUseParentDirConfigValue()) !== false + // config --file ... should not prompt + && ($commandName !== 'config' || ($input->hasParameterOption('--file', true) === false && $input->hasParameterOption('-f', true) === false)) + // calling a command's help should not prompt + && $input->hasParameterOption('--help', true) === false + && $input->hasParameterOption('-h', true) === false + ) { $dir = dirname(Platform::getCwd(true)); $home = realpath(Platform::getEnv('HOME') ?: Platform::getEnv('USERPROFILE') ?: '/'); // abort when we reach the home dir or top of the filesystem while (dirname($dir) !== $dir && $dir !== $home) { if (file_exists($dir.'/'.Factory::getComposerFile())) { + if ($useParentDirIfNoJsonAvailable !== true && !$io->isInteractive()) { + $io->writeError('No composer.json in current directory, to use the one at '.$dir.' run interactively or set config.use-parent-dir to true'); + break; + } if ($useParentDirIfNoJsonAvailable === true || $io->askConfirmation('No composer.json in current directory, do you want to use the one at '.$dir.'? [Y,n]? ')) { if ($useParentDirIfNoJsonAvailable === true) { $io->writeError('No composer.json in current directory, changing working directory to '.$dir.''); @@ -210,12 +231,13 @@ public function doRun(InputInterface $input, OutputInterface $output): int } $dir = dirname($dir); } + unset($dir, $home); } $needsSudoCheck = !Platform::isWindows() && function_exists('exec') && !Platform::getEnv('COMPOSER_ALLOW_SUPERUSER') - && (ini_get('open_basedir') || !file_exists('/.dockerenv')); + && !Platform::isDocker(); $isNonAllowedRoot = false; // Clobber sudo credentials if COMPOSER_ALLOW_SUPERUSER is not set before loading plugins @@ -318,7 +340,7 @@ public function doRun(InputInterface $input, OutputInterface $output): int function_exists('php_uname') ? php_uname('s') . ' / ' . php_uname('r') : 'Unknown OS' ), true, IOInterface::DEBUG); - if (PHP_VERSION_ID < 70205) { + if (\PHP_VERSION_ID < 70205) { $io->writeError('Composer supports PHP 7.2.5 and above, you will most likely encounter problems with your PHP '.PHP_VERSION.'. Upgrading is strongly recommended but you can use Composer 2.2.x LTS as a fallback.'); } @@ -345,7 +367,7 @@ function_exists('php_uname') ? php_uname('s') . ' / ' . php_uname('r') : 'Unknow // Check system temp folder for usability as it can cause weird runtime issues otherwise Silencer::call(static function () use ($io): void { $pid = function_exists('getmypid') ? getmypid() . '-' : ''; - $tempfile = sys_get_temp_dir() . '/temp-' . $pid . md5(microtime()); + $tempfile = sys_get_temp_dir() . '/temp-' . $pid . bin2hex(random_bytes(5)); if (!(file_put_contents($tempfile, __FILE__) && (file_get_contents($tempfile) === __FILE__) && unlink($tempfile) && !file_exists($tempfile))) { $io->writeError(sprintf('PHP temp directory (%s) does not exist or is not writable to Composer. Set sys_temp_dir in your php.ini', sys_get_temp_dir())); } @@ -395,7 +417,7 @@ function_exists('php_uname') ? php_uname('s') . ' / ' . php_uname('r') : 'Unknow } if (isset($startTime)) { - $io->writeError('Memory usage: '.round(memory_get_usage() / 1024 / 1024, 2).'MiB (peak: '.round(memory_get_peak_usage() / 1024 / 1024, 2).'MiB), time: '.round(microtime(true) - $startTime, 2).'s'); + $io->writeError('Memory usage: '.round(memory_get_usage() / 1024 / 1024, 2).'MiB (peak: '.round(memory_get_peak_usage() / 1024 / 1024, 2).'MiB), time: '.round(microtime(true) - $startTime, 2).'s'); } return $result; @@ -425,6 +447,14 @@ function_exists('php_uname') ? php_uname('s') . ' / ' . php_uname('r') : 'Unknow return max(1, $e->getCode()); } + // override TransportException's code for the purpose of parent::run() using it as process exit code + // as http error codes are all beyond the 255 range of permitted exit codes + if ($e instanceof TransportException) { + $reflProp = new \ReflectionProperty($e, 'code'); + $reflProp->setAccessible(true); + $reflProp->setValue($e, Installer::ERROR_TRANSPORT_EXCEPTION); + } + throw $e; } finally { restore_error_handler(); @@ -472,6 +502,11 @@ private function hintCommonErrors(\Throwable $exception, OutputInterface $output } Silencer::restore(); + if ($exception instanceof TransportException && str_contains($exception->getMessage(), 'Unable to use a proxy')) { + $io->writeError('The following exception indicates your proxy is misconfigured', true, IOInterface::QUIET); + $io->writeError('Check https://getcomposer.org/doc/faqs/how-to-use-composer-behind-a-proxy.md for details', true, IOInterface::QUIET); + } + if (Platform::isWindows() && false !== strpos($exception->getMessage(), 'The system cannot find the path specified')) { $io->writeError('The following exception may be caused by a stale entry in your cmd.exe AutoRun', true, IOInterface::QUIET); $io->writeError('Check https://getcomposer.org/doc/articles/troubleshooting.md#-the-system-cannot-find-the-path-specified-windows- for details', true, IOInterface::QUIET); diff --git a/vendor/composer/composer/src/Composer/Console/Input/InputArgument.php b/vendor/composer/composer/src/Composer/Console/Input/InputArgument.php index b6d064f..19aff8c 100644 --- a/vendor/composer/composer/src/Composer/Console/Input/InputArgument.php +++ b/vendor/composer/composer/src/Composer/Console/Input/InputArgument.php @@ -26,7 +26,7 @@ * * @internal * - * TODO drop when PHP 8.1 / symfony 6.1+ can be required + * TODO symfony/console:6.1 drop when PHP 8.1 / symfony 6.1+ can be required */ class InputArgument extends BaseInputArgument { @@ -59,7 +59,7 @@ public function __construct(string $name, ?int $mode = null, string $description public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void { $values = $this->suggestedValues; - if ($values instanceof \Closure && !\is_array($values = $values($input, $suggestions))) { // @phpstan-ignore-line + if ($values instanceof \Closure && !\is_array($values = $values($input, $suggestions))) { // @phpstan-ignore function.impossibleType throw new LogicException(sprintf('Closure for option "%s" must return an array. Got "%s".', $this->getName(), get_debug_type($values))); } if ([] !== $values) { diff --git a/vendor/composer/composer/src/Composer/Console/Input/InputOption.php b/vendor/composer/composer/src/Composer/Console/Input/InputOption.php index 75bfe90..b5ff333 100644 --- a/vendor/composer/composer/src/Composer/Console/Input/InputOption.php +++ b/vendor/composer/composer/src/Composer/Console/Input/InputOption.php @@ -26,7 +26,7 @@ * * @internal * - * TODO drop when PHP 8.1 / symfony 6.1+ can be required + * TODO symfony/console:6.1 drop when PHP 8.1 / symfony 6.1+ can be required */ class InputOption extends BaseInputOption { @@ -62,7 +62,7 @@ public function __construct(string $name, $shortcut = null, ?int $mode = null, s public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void { $values = $this->suggestedValues; - if ($values instanceof \Closure && !\is_array($values = $values($input, $suggestions))) { // @phpstan-ignore-line + if ($values instanceof \Closure && !\is_array($values = $values($input, $suggestions))) { // @phpstan-ignore function.impossibleType throw new LogicException(sprintf('Closure for argument "%s" must return an array. Got "%s".', $this->getName(), get_debug_type($values))); } if ([] !== $values) { diff --git a/vendor/composer/composer/src/Composer/DependencyResolver/Decisions.php b/vendor/composer/composer/src/Composer/DependencyResolver/Decisions.php index 9a5c9c2..5991107 100644 --- a/vendor/composer/composer/src/Composer/DependencyResolver/Decisions.php +++ b/vendor/composer/composer/src/Composer/DependencyResolver/Decisions.php @@ -28,7 +28,7 @@ class Decisions implements \Iterator, \Countable /** @var array */ protected $decisionMap; /** - * @var array + * @var array */ protected $decisionQueue = []; @@ -69,12 +69,12 @@ public function conflict(int $literal): bool public function decided(int $literalOrPackageId): bool { - return !empty($this->decisionMap[abs($literalOrPackageId)]); + return ($this->decisionMap[abs($literalOrPackageId)] ?? 0) !== 0; } public function undecided(int $literalOrPackageId): bool { - return empty($this->decisionMap[abs($literalOrPackageId)]); + return ($this->decisionMap[abs($literalOrPackageId)] ?? 0) === 0; } public function decidedInstall(int $literalOrPackageId): bool @@ -94,7 +94,7 @@ public function decisionLevel(int $literalOrPackageId): int return 0; } - public function decisionRule(int $literalOrPackageId): ?Rule + public function decisionRule(int $literalOrPackageId): Rule { $packageId = abs($literalOrPackageId); @@ -104,7 +104,7 @@ public function decisionRule(int $literalOrPackageId): ?Rule } } - return null; + throw new \LogicException('Did not find a decision rule using '.$literalOrPackageId); } /** @@ -219,7 +219,7 @@ public function toString(?Pool $pool = null): string ksort($decisionMap); $str = '['; foreach ($decisionMap as $packageId => $level) { - $str .= (($pool) ? $pool->literalToPackage($packageId) : $packageId).':'.$level.','; + $str .= ($pool !== null ? $pool->literalToPackage($packageId) : $packageId).':'.$level.','; } $str .= ']'; diff --git a/vendor/composer/composer/src/Composer/DependencyResolver/DefaultPolicy.php b/vendor/composer/composer/src/Composer/DependencyResolver/DefaultPolicy.php index f8176ae..5901870 100644 --- a/vendor/composer/composer/src/Composer/DependencyResolver/DefaultPolicy.php +++ b/vendor/composer/composer/src/Composer/DependencyResolver/DefaultPolicy.php @@ -30,7 +30,7 @@ class DefaultPolicy implements PolicyInterface private $preferLowest; /** @var array|null */ private $preferredVersions; - /** @var array>> */ + /** @var array>> */ private $preferredPackageResultCachePerPool; /** @var array> */ private $sortingCachePerPool; @@ -53,11 +53,11 @@ public function __construct(bool $preferStable = false, bool $preferLowest = fal public function versionCompare(PackageInterface $a, PackageInterface $b, string $operator): bool { if ($this->preferStable && ($stabA = $a->getStability()) !== ($stabB = $b->getStability())) { - return BasePackage::$stabilities[$stabA] < BasePackage::$stabilities[$stabB]; + return BasePackage::STABILITIES[$stabA] < BasePackage::STABILITIES[$stabB]; } // dev versions need to be compared as branches via matchSpecific's special treatment, the rest can be optimized with compiling matcher - if (strpos($a->getVersion(), 'dev-') === 0 || strpos($b->getVersion(), 'dev-') === 0) { + if (($a->isDev() && str_starts_with($a->getVersion(), 'dev-')) || ($b->isDev() && str_starts_with($b->getVersion(), 'dev-'))) { $constraint = new Constraint($operator, $b->getVersion()); $version = new Constraint('==', $a->getVersion()); @@ -68,9 +68,8 @@ public function versionCompare(PackageInterface $a, PackageInterface $b, string } /** - * @param int[] $literals - * @param string $requiredPackage - * @return int[] + * @param non-empty-list $literals + * @return non-empty-list */ public function selectPreferredPackages(Pool $pool, array $literals, ?string $requiredPackage = null): array { @@ -118,8 +117,8 @@ public function selectPreferredPackages(Pool $pool, array $literals, ?string $re } /** - * @param int[] $literals - * @return array + * @param non-empty-list $literals + * @return non-empty-array> */ protected function groupLiteralsByName(Pool $pool, array $literals): array { @@ -164,7 +163,7 @@ public function compareByPriority(Pool $pool, BasePackage $a, BasePackage $b, ?s // for replacers not replacing each other, put a higher prio on replacing // packages with the same vendor as the required package - if ($requiredPackage && false !== ($pos = strpos($requiredPackage, '/'))) { + if ($requiredPackage !== null && false !== ($pos = strpos($requiredPackage, '/'))) { $requiredVendor = substr($requiredPackage, 0, $pos); $aIsSameVendor = strpos($a->getName(), $requiredVendor) === 0; @@ -205,8 +204,8 @@ protected function replaces(BasePackage $source, BasePackage $target): bool } /** - * @param int[] $literals - * @return int[] + * @param list $literals + * @return list */ protected function pruneToBestVersion(Pool $pool, array $literals): array { @@ -252,8 +251,8 @@ protected function pruneToBestVersion(Pool $pool, array $literals): array * * If no package is a local alias, nothing happens * - * @param int[] $literals - * @return int[] + * @param list $literals + * @return list */ protected function pruneRemoteAliases(Pool $pool, array $literals): array { diff --git a/vendor/composer/composer/src/Composer/DependencyResolver/GenericRule.php b/vendor/composer/composer/src/Composer/DependencyResolver/GenericRule.php index f7cf7f2..64dd7a2 100644 --- a/vendor/composer/composer/src/Composer/DependencyResolver/GenericRule.php +++ b/vendor/composer/composer/src/Composer/DependencyResolver/GenericRule.php @@ -46,7 +46,10 @@ public function getLiterals(): array */ public function getHash() { - $data = unpack('ihash', md5(implode(',', $this->literals), true)); + $data = unpack('ihash', (string) hash(\PHP_VERSION_ID > 80100 ? 'xxh3' : 'sha1', implode(',', $this->literals), true)); + if (false === $data) { + throw new \RuntimeException('Failed unpacking: '.implode(', ', $this->literals)); + } return $data['hash']; } diff --git a/vendor/composer/composer/src/Composer/DependencyResolver/MultiConflictRule.php b/vendor/composer/composer/src/Composer/DependencyResolver/MultiConflictRule.php index 4826489..a610947 100644 --- a/vendor/composer/composer/src/Composer/DependencyResolver/MultiConflictRule.php +++ b/vendor/composer/composer/src/Composer/DependencyResolver/MultiConflictRule.php @@ -19,11 +19,11 @@ */ class MultiConflictRule extends Rule { - /** @var list */ + /** @var non-empty-list */ protected $literals; /** - * @param list $literals + * @param non-empty-list $literals */ public function __construct(array $literals, $reason, $reasonData) { @@ -40,7 +40,7 @@ public function __construct(array $literals, $reason, $reasonData) } /** - * @return list + * @return non-empty-list */ public function getLiterals(): array { @@ -52,7 +52,10 @@ public function getLiterals(): array */ public function getHash() { - $data = unpack('ihash', md5('c:'.implode(',', $this->literals), true)); + $data = unpack('ihash', (string) hash(\PHP_VERSION_ID > 80100 ? 'xxh3' : 'sha1', 'c:'.implode(',', $this->literals), true)); + if (false === $data) { + throw new \RuntimeException('Failed unpacking: '.implode(', ', $this->literals)); + } return $data['hash']; } diff --git a/vendor/composer/composer/src/Composer/DependencyResolver/PolicyInterface.php b/vendor/composer/composer/src/Composer/DependencyResolver/PolicyInterface.php index 928e7e0..b4511d0 100644 --- a/vendor/composer/composer/src/Composer/DependencyResolver/PolicyInterface.php +++ b/vendor/composer/composer/src/Composer/DependencyResolver/PolicyInterface.php @@ -26,8 +26,8 @@ interface PolicyInterface public function versionCompare(PackageInterface $a, PackageInterface $b, string $operator): bool; /** - * @param int[] $literals - * @return int[] + * @param non-empty-list $literals + * @return non-empty-list */ public function selectPreferredPackages(Pool $pool, array $literals, ?string $requiredPackage = null): array; } diff --git a/vendor/composer/composer/src/Composer/DependencyResolver/PoolBuilder.php b/vendor/composer/composer/src/Composer/DependencyResolver/PoolBuilder.php index d84d409..241acf9 100644 --- a/vendor/composer/composer/src/Composer/DependencyResolver/PoolBuilder.php +++ b/vendor/composer/composer/src/Composer/DependencyResolver/PoolBuilder.php @@ -40,7 +40,7 @@ class PoolBuilder { /** * @var int[] - * @phpstan-var array + * @phpstan-var array, BasePackage::STABILITY_*> */ private $acceptableStabilities; /** @@ -95,7 +95,7 @@ class PoolBuilder */ private $loadedPerRepo = []; /** - * @var BasePackage[] + * @var array */ private $packages = []; /** @@ -106,6 +106,10 @@ class PoolBuilder private $updateAllowList = []; /** @var array> */ private $skippedLoad = []; + /** @var list */ + private $ignoredTypes = []; + /** @var list|null */ + private $allowedTypes = null; /** * If provided, only these package names are loaded @@ -149,7 +153,7 @@ class PoolBuilder /** * @param int[] $acceptableStabilities array of stability => BasePackage::STABILITY_* value - * @phpstan-param array $acceptableStabilities + * @phpstan-param array, BasePackage::STABILITY_*> $acceptableStabilities * @param int[] $stabilityFlags an array of package name => BasePackage::STABILITY_* value * @phpstan-param array $stabilityFlags * @param array[] $rootAliases @@ -170,6 +174,26 @@ public function __construct(array $acceptableStabilities, array $stabilityFlags, $this->temporaryConstraints = $temporaryConstraints; } + /** + * Packages of those types are ignored + * + * @param list $types + */ + public function setIgnoredTypes(array $types): void + { + $this->ignoredTypes = $types; + } + + /** + * Only packages of those types are allowed if set to non-null + * + * @param list|null $types + */ + public function setAllowedTypes(?array $types): void + { + $this->allowedTypes = $types; + } + /** * @param RepositoryInterface[] $repositories */ @@ -177,10 +201,14 @@ public function buildPool(array $repositories, Request $request): Pool { $this->restrictedPackagesList = $request->getRestrictedPackages() !== null ? array_flip($request->getRestrictedPackages()) : null; - if ($request->getUpdateAllowList()) { + if (\count($request->getUpdateAllowList()) > 0) { $this->updateAllowList = $request->getUpdateAllowList(); $this->warnAboutNonMatchingUpdateAllowList($request); + if (null === $request->getLockedRepository()) { + throw new \LogicException('No lock repo present and yet a partial update was requested.'); + } + foreach ($request->getLockedRepository()->getPackages() as $lockedPackage) { if (!$this->isUpdateAllowed($lockedPackage)) { // remember which packages we skipped loading remote content for in this partial update @@ -247,7 +275,7 @@ public function buildPool(array $repositories, Request $request): Pool } } - while (!empty($this->packagesToLoad)) { + while (\count($this->packagesToLoad) > 0) { $this->loadPackagesMarkedForLoading($request, $repositories); } @@ -279,7 +307,7 @@ public function buildPool(array $repositories, Request $request): Pool } } - if ($this->eventDispatcher) { + if ($this->eventDispatcher !== null) { $prePoolCreateEvent = new PrePoolCreateEvent( PluginEvents::PRE_POOL_CREATE, $repositories, @@ -389,7 +417,7 @@ private function loadPackagesMarkedForLoading(Request $request, array $repositor $this->packagesToLoad = []; foreach ($repositories as $repoIndex => $repository) { - if (empty($packageBatch)) { + if (0 === \count($packageBatch)) { break; } @@ -406,6 +434,10 @@ private function loadPackagesMarkedForLoading(Request $request, array $repositor } foreach ($result['packages'] as $package) { $this->loadedPerRepo[$repoIndex][$package->getName()][$package->getVersion()] = $package; + + if (in_array($package->getType(), $this->ignoredTypes, true) || ($this->allowedTypes !== null && !in_array($package->getType(), $this->allowedTypes, true))) { + continue; + } $this->loadPackage($request, $repositories, $package, !isset($this->pathRepoUnlocked[$package->getName()])); } } @@ -471,7 +503,7 @@ private function loadPackage(Request $request, array $repositories, BasePackage if ($propagateUpdate && $request->getUpdateAllowTransitiveDependencies()) { $skippedRootRequires = $this->getSkippedRootRequires($request, $require); - if ($request->getUpdateAllowTransitiveRootDependencies() || !$skippedRootRequires) { + if ($request->getUpdateAllowTransitiveRootDependencies() || 0 === \count($skippedRootRequires)) { $this->unlockPackage($request, $repositories, $require); $this->markPackageNameForLoading($request, $require, $linkConstraint); } else { @@ -500,7 +532,7 @@ private function loadPackage(Request $request, array $repositories, BasePackage if (isset($this->loadedPackages[$replace], $this->skippedLoad[$replace])) { $skippedRootRequires = $this->getSkippedRootRequires($request, $replace); - if ($request->getUpdateAllowTransitiveRootDependencies() || !$skippedRootRequires) { + if ($request->getUpdateAllowTransitiveRootDependencies() || 0 === \count($skippedRootRequires)) { $this->unlockPackage($request, $repositories, $replace); // the replaced package only needs to be loaded if something else requires it $this->markPackageNameForLoadingIfRequired($request, $replace); @@ -587,7 +619,13 @@ private function isUpdateAllowed(BasePackage $package): bool private function warnAboutNonMatchingUpdateAllowList(Request $request): void { + if (null === $request->getLockedRepository()) { + throw new \LogicException('No lock repo present and yet a partial update was requested.'); + } + foreach ($this->updateAllowList as $pattern) { + $matchedPlatformPackage = false; + $patternRegexp = BasePackage::packageNameToRegexp($pattern); // update pattern matches a locked package? => all good foreach ($request->getLockedRepository()->getPackages() as $package) { @@ -598,10 +636,16 @@ private function warnAboutNonMatchingUpdateAllowList(Request $request): void // update pattern matches a root require? => all good, probably a new package foreach ($request->getRequires() as $packageName => $constraint) { if (Preg::isMatch($patternRegexp, $packageName)) { + if (PlatformRepository::isPlatformPackage($packageName)) { + $matchedPlatformPackage = true; + continue; + } continue 2; } } - if (strpos($pattern, '*') !== false) { + if ($matchedPlatformPackage) { + $this->io->writeError('Pattern "' . $pattern . '" listed for update matches platform packages, but these cannot be updated by Composer.'); + } elseif (strpos($pattern, '*') !== false) { $this->io->writeError('Pattern "' . $pattern . '" listed for update does not match any locked packages.'); } else { $this->io->writeError('Package "' . $pattern . '" listed for update is not locked.'); diff --git a/vendor/composer/composer/src/Composer/DependencyResolver/PoolOptimizer.php b/vendor/composer/composer/src/Composer/DependencyResolver/PoolOptimizer.php index c53891f..3de9e03 100644 --- a/vendor/composer/composer/src/Composer/DependencyResolver/PoolOptimizer.php +++ b/vendor/composer/composer/src/Composer/DependencyResolver/PoolOptimizer.php @@ -207,7 +207,7 @@ private function optimizeByIdenticalDependencies(Request $request, Pool $pool): $groupHashParts[] = 'require:' . (string) $requireConstraint; } - if ($package->getReplaces()) { + if (\count($package->getReplaces()) > 0) { foreach ($package->getReplaces() as $link) { if (CompilingMatcher::match($link->getConstraint(), Constraint::OP_EQ, $package->getVersion())) { // Use the same hash part as the regular require hash because that's what the replacement does @@ -224,7 +224,7 @@ private function optimizeByIdenticalDependencies(Request $request, Pool $pool): } } - if (!$groupHashParts) { + if (0 === \count($groupHashParts)) { continue; } @@ -371,7 +371,7 @@ private function keepPackage(BasePackage $package, array $identicalDefinitionsPe */ private function optimizeImpossiblePackagesAway(Request $request, Pool $pool): void { - if (count($request->getLockedPackages()) === 0) { + if (\count($request->getLockedPackages()) === 0) { return; } diff --git a/vendor/composer/composer/src/Composer/DependencyResolver/Problem.php b/vendor/composer/composer/src/Composer/DependencyResolver/Problem.php index cf2cb38..5576845 100644 --- a/vendor/composer/composer/src/Composer/DependencyResolver/Problem.php +++ b/vendor/composer/composer/src/Composer/DependencyResolver/Problem.php @@ -25,6 +25,7 @@ use Composer\Semver\Constraint\ConstraintInterface; use Composer\Package\Version\VersionParser; use Composer\Repository\PlatformRepository; +use Composer\Semver\Constraint\MultiConstraint; /** * Represents a problem detected while solving dependencies @@ -79,7 +80,7 @@ public function getPrettyString(RepositorySet $repositorySet, Request $request, // TODO doesn't this entirely defeat the purpose of the problem sections? what's the point of sections? $reasons = array_merge(...array_reverse($this->reasons)); - if (count($reasons) === 1) { + if (\count($reasons) === 1) { reset($reasons); $rule = current($reasons); @@ -92,14 +93,65 @@ public function getPrettyString(RepositorySet $repositorySet, Request $request, $constraint = $reasonData['constraint']; $packages = $pool->whatProvides($packageName, $constraint); - if (count($packages) === 0) { + if (\count($packages) === 0) { return "\n ".implode(self::getMissingPackageReason($repositorySet, $request, $pool, $isVerbose, $packageName, $constraint)); } } + usort($reasons, function (Rule $rule1, Rule $rule2) use ($pool) { + $rule1Prio = $this->getRulePriority($rule1); + $rule2Prio = $this->getRulePriority($rule2); + if ($rule1Prio !== $rule2Prio) { + return $rule2Prio - $rule1Prio; + } + + return $this->getSortableString($pool, $rule1) <=> $this->getSortableString($pool, $rule2); + }); + return self::formatDeduplicatedRules($reasons, ' ', $repositorySet, $request, $pool, $isVerbose, $installedMap, $learnedPool); } + private function getSortableString(Pool $pool, Rule $rule): string + { + switch ($rule->getReason()) { + case Rule::RULE_ROOT_REQUIRE: + return $rule->getReasonData()['packageName']; + case Rule::RULE_FIXED: + return (string) $rule->getReasonData()['package']; + case Rule::RULE_PACKAGE_CONFLICT: + case Rule::RULE_PACKAGE_REQUIRES: + return $rule->getSourcePackage($pool) . '//' . $rule->getReasonData()->getPrettyString($rule->getSourcePackage($pool)); + case Rule::RULE_PACKAGE_SAME_NAME: + case Rule::RULE_PACKAGE_ALIAS: + case Rule::RULE_PACKAGE_INVERSE_ALIAS: + return (string) $rule->getReasonData(); + case Rule::RULE_LEARNED: + return implode('-', $rule->getLiterals()); + } + + throw new \LogicException('Unknown rule type: '.$rule->getReason()); + } + + private function getRulePriority(Rule $rule): int + { + switch ($rule->getReason()) { + case Rule::RULE_FIXED: + return 3; + case Rule::RULE_ROOT_REQUIRE: + return 2; + case Rule::RULE_PACKAGE_CONFLICT: + case Rule::RULE_PACKAGE_REQUIRES: + return 1; + case Rule::RULE_PACKAGE_SAME_NAME: + case Rule::RULE_LEARNED: + case Rule::RULE_PACKAGE_ALIAS: + case Rule::RULE_PACKAGE_INVERSE_ALIAS: + return 0; + } + + throw new \LogicException('Unknown rule type: '.$rule->getReason()); + } + /** * @param Rule[] $rules * @param array $installedMap A map of all present packages @@ -136,7 +188,7 @@ public static function formatDeduplicatedRules(array $rules, string $indent, Rep if (!$isVerbose) { $versions = self::condenseVersionList($versions, 1); } - if (count($versions) > 1) { + if (\count($versions) > 1) { // remove the s from requires/conflicts to correct grammar $message = Preg::replace('{^(%s%s (?:require|conflict))s}', '$1', $message); $result[] = sprintf($message, $package, '['.implode(', ', $versions).']'); @@ -224,16 +276,21 @@ public static function getMissingPackageReason(RepositorySet $repositorySet, Req $ext = substr($packageName, 4); $msg = "- Root composer.json requires PHP extension ".$packageName.self::constraintToText($constraint).' but '; - $version = self::getPlatformPackageVersion($pool, $packageName, phpversion($ext) ?: '0'); + $version = self::getPlatformPackageVersion($pool, $packageName, phpversion($ext) === false ? '0' : phpversion($ext)); if (null === $version) { + $providersStr = self::getProvidersList($repositorySet, $packageName, 5); + if ($providersStr !== null) { + $providersStr = "\n\n Alternatively you can require one of these packages that provide the extension (or parts of it):\n$providersStr"; + } + if (extension_loaded($ext)) { return [ $msg, - 'the '.$packageName.' package is disabled by your platform config. Enable it again with "composer config platform.'.$packageName.' --unset".', + 'the '.$packageName.' package is disabled by your platform config. Enable it again with "composer config platform.'.$packageName.' --unset".' . $providersStr, ]; } - return [$msg, 'it is missing from your system. Install or enable PHP\'s '.$ext.' extension.']; + return [$msg, 'it is missing from your system. Install or enable PHP\'s '.$ext.' extension.' . $providersStr]; } return [$msg, 'it has the wrong version installed ('.$version.').']; @@ -247,7 +304,12 @@ public static function getMissingPackageReason(RepositorySet $repositorySet, Req return ["- Root composer.json requires linked library ".$packageName.self::constraintToText($constraint).' but ', $error]; } - return ["- Root composer.json requires linked library ".$packageName.self::constraintToText($constraint).' but ', 'it has the wrong version installed or is missing from your system, make sure to load the extension providing it.']; + $providersStr = self::getProvidersList($repositorySet, $packageName, 5); + if ($providersStr !== null) { + $providersStr = "\n\n Alternatively you can require one of these packages that provide the library (or parts of it):\n$providersStr"; + } + + return ["- Root composer.json requires linked library ".$packageName.self::constraintToText($constraint).' but ', 'it has the wrong version installed or is missing from your system, make sure to load the extension providing it.'.$providersStr]; } } @@ -262,9 +324,21 @@ public static function getMissingPackageReason(RepositorySet $repositorySet, Req } } + if ($constraint instanceof Constraint && $constraint->getOperator() === Constraint::STR_OP_EQ && Preg::isMatch('{^dev-.*#.*}', $constraint->getPrettyString())) { + $newConstraint = Preg::replace('{ +as +([^,\s|]+)$}', '', $constraint->getPrettyString()); + $packages = $repositorySet->findPackages($packageName, new MultiConstraint([ + new Constraint(Constraint::STR_OP_EQ, $newConstraint), + new Constraint(Constraint::STR_OP_EQ, str_replace('#', '+', $newConstraint)) + ], false)); + if (\count($packages) > 0) { + return ["- Root composer.json requires $packageName".self::constraintToText($constraint) . ', ', 'found '.self::getPackageList($packages, $isVerbose, $pool, $constraint).'. The # character in branch names is replaced by a + character. Make sure to require it as "'.str_replace('#', '+', $constraint->getPrettyString()).'".']; + } + } + // first check if the actual requested package is found in normal conditions // if so it must mean it is rejected by another constraint than the one given here - if ($packages = $repositorySet->findPackages($packageName, $constraint)) { + $packages = $repositorySet->findPackages($packageName, $constraint); + if (\count($packages) > 0) { $rootReqs = $repositorySet->getRootRequires(); if (isset($rootReqs[$packageName])) { $filtered = array_filter($packages, static function ($p) use ($rootReqs, $packageName): bool { @@ -285,7 +359,7 @@ public static function getMissingPackageReason(RepositorySet $repositorySet, Req } } - if ($lockedPackage) { + if ($lockedPackage !== null) { $fixedConstraint = new Constraint('==', $lockedPackage->getVersion()); $filtered = array_filter($packages, static function ($p) use ($fixedConstraint): bool { return $fixedConstraint->matches(new Constraint('==', $p->getVersion())); @@ -299,7 +373,7 @@ public static function getMissingPackageReason(RepositorySet $repositorySet, Req return !$p->getRepository() instanceof LockArrayRepository; }); - if (!$nonLockedPackages) { + if (0 === \count($nonLockedPackages)) { return ["- Root composer.json requires $packageName".self::constraintToText($constraint) . ', ', 'found '.self::getPackageList($packages, $isVerbose, $pool, $constraint).' in the lock file but not in remote repositories, make sure you avoid updating this package to keep the one from the lock file.']; } @@ -307,9 +381,11 @@ public static function getMissingPackageReason(RepositorySet $repositorySet, Req } // check if the package is found when bypassing stability checks - if ($packages = $repositorySet->findPackages($packageName, $constraint, RepositorySet::ALLOW_UNACCEPTABLE_STABILITIES)) { + $packages = $repositorySet->findPackages($packageName, $constraint, RepositorySet::ALLOW_UNACCEPTABLE_STABILITIES); + if (\count($packages) > 0) { // we must first verify if a valid package would be found in a lower priority repository - if ($allReposPackages = $repositorySet->findPackages($packageName, $constraint, RepositorySet::ALLOW_SHADOWED_REPOSITORIES)) { + $allReposPackages = $repositorySet->findPackages($packageName, $constraint, RepositorySet::ALLOW_SHADOWED_REPOSITORIES); + if (\count($allReposPackages) > 0) { return self::computeCheckForLowerPrioRepo($pool, $isVerbose, $packageName, $packages, $allReposPackages, 'minimum-stability', $constraint); } @@ -317,9 +393,11 @@ public static function getMissingPackageReason(RepositorySet $repositorySet, Req } // check if the package is found when bypassing the constraint and stability checks - if ($packages = $repositorySet->findPackages($packageName, null, RepositorySet::ALLOW_UNACCEPTABLE_STABILITIES)) { + $packages = $repositorySet->findPackages($packageName, null, RepositorySet::ALLOW_UNACCEPTABLE_STABILITIES); + if (\count($packages) > 0) { // we must first verify if a valid package would be found in a lower priority repository - if ($allReposPackages = $repositorySet->findPackages($packageName, $constraint, RepositorySet::ALLOW_SHADOWED_REPOSITORIES)) { + $allReposPackages = $repositorySet->findPackages($packageName, $constraint, RepositorySet::ALLOW_SHADOWED_REPOSITORIES); + if (\count($allReposPackages) > 0) { return self::computeCheckForLowerPrioRepo($pool, $isVerbose, $packageName, $packages, $allReposPackages, 'constraint', $constraint); } @@ -349,17 +427,8 @@ public static function getMissingPackageReason(RepositorySet $repositorySet, Req return ["- Root composer.json requires $packageName, it ", 'could not be found, it looks like its name is invalid, "'.$illegalChars.'" is not allowed in package names.']; } - if ($providers = $repositorySet->getProviders($packageName)) { - $maxProviders = 20; - $providersStr = implode(array_map(static function ($p): string { - $description = $p['description'] ? ' '.substr($p['description'], 0, 100) : ''; - - return ' - '.$p['name'].$description."\n"; - }, count($providers) > $maxProviders + 1 ? array_slice($providers, 0, $maxProviders) : $providers)); - if (count($providers) > $maxProviders + 1) { - $providersStr .= ' ... and '.(count($providers) - $maxProviders).' more.'."\n"; - } - + $providersStr = self::getProvidersList($repositorySet, $packageName, 15); + if ($providersStr !== null) { return ["- Root composer.json requires $packageName".self::constraintToText($constraint).", it ", "could not be found in any version, but the following packages provide it:\n".$providersStr." Consider requiring one of these to satisfy the $packageName requirement."]; } @@ -377,12 +446,12 @@ public static function getPackageList(array $packages, bool $isVerbose, ?Pool $p foreach ($packages as $package) { $prepared[$package->getName()]['name'] = $package->getPrettyName(); $prepared[$package->getName()]['versions'][$package->getVersion()] = $package->getPrettyVersion().($package instanceof AliasPackage ? ' (alias of '.$package->getAliasOf()->getPrettyVersion().')' : ''); - if ($pool && $constraint) { + if ($pool !== null && $constraint !== null) { foreach ($pool->getRemovedVersions($package->getName(), $constraint) as $version => $prettyVersion) { $prepared[$package->getName()]['versions'][$version] = $prettyVersion; } } - if ($pool && $useRemovedVersionGroup) { + if ($pool !== null && $useRemovedVersionGroup) { foreach ($pool->getRemovedVersionsByPackage(spl_object_hash($package)) as $version => $prettyVersion) { $prepared[$package->getName()]['versions'][$version] = $prettyVersion; } @@ -418,7 +487,7 @@ private static function getPlatformPackageVersion(Pool $pool, string $packageNam { $available = $pool->whatProvides($packageName); - if (count($available)) { + if (\count($available) > 0) { $selected = null; foreach ($available as $pkg) { if ($pkg->getRepository() instanceof PlatformRepository) { @@ -443,7 +512,7 @@ private static function getPlatformPackageVersion(Pool $pool, string $packageNam $version = $selected->getPrettyVersion(); $extra = $selected->getExtra(); if ($selected instanceof CompletePackageInterface && isset($extra['config.platform']) && $extra['config.platform'] === true) { - $version .= '; ' . str_replace('Package ', '', $selected->getDescription()); + $version .= '; ' . str_replace('Package ', '', (string) $selected->getDescription()); } } else { return null; @@ -504,8 +573,8 @@ private static function hasMultipleNames(array $packages): bool } /** - * @param PackageInterface[] $higherRepoPackages - * @param PackageInterface[] $allReposPackages + * @param non-empty-array $higherRepoPackages + * @param non-empty-array $allReposPackages * @return array{0: string, 1: string} */ private static function computeCheckForLowerPrioRepo(Pool $pool, bool $isVerbose, string $packageName, array $higherRepoPackages, array $allReposPackages, string $reason, ?ConstraintInterface $constraint = null): array @@ -522,7 +591,9 @@ private static function computeCheckForLowerPrioRepo(Pool $pool, bool $isVerbose } } - if ($higherRepoPackages) { + assert(null !== $nextRepo); + + if (\count($higherRepoPackages) > 0) { $topPackage = reset($higherRepoPackages); if ($topPackage instanceof RootPackageInterface) { return [ @@ -570,6 +641,25 @@ protected static function constraintToText(?ConstraintInterface $constraint = nu return ' ' . $constraint->getPrettyString() . ' (exact version match: ' . (count($versions) > 1 ? implode(', ', array_slice($versions, 0, -1)) . ' or ' . end($versions) : $versions[0]) . ')'; } - return $constraint ? ' '.$constraint->getPrettyString() : ''; + return $constraint !== null ? ' '.$constraint->getPrettyString() : ''; + } + + private static function getProvidersList(RepositorySet $repositorySet, string $packageName, int $maxProviders): ?string + { + $providers = $repositorySet->getProviders($packageName); + if (\count($providers) > 0) { + $providersStr = implode(array_map(static function ($p): string { + $description = $p['description'] !== '' ? ' '.substr($p['description'], 0, 100) : ''; + + return ' - '.$p['name'].$description."\n"; + }, count($providers) > $maxProviders + 1 ? array_slice($providers, 0, $maxProviders) : $providers)); + if (count($providers) > $maxProviders + 1) { + $providersStr .= ' ... and '.(count($providers) - $maxProviders).' more.'."\n"; + } + + return $providersStr; + } + + return null; } } diff --git a/vendor/composer/composer/src/Composer/DependencyResolver/Request.php b/vendor/composer/composer/src/Composer/DependencyResolver/Request.php index 300093f..b11f4e1 100644 --- a/vendor/composer/composer/src/Composer/DependencyResolver/Request.php +++ b/vendor/composer/composer/src/Composer/DependencyResolver/Request.php @@ -190,7 +190,7 @@ public function getFixedOrLockedPackages(): array } /** - * @return array + * @return ($packageIds is true ? array : array) * * @TODO look into removing the packageIds option, the only place true is used * is for the installed map in the solver problems. @@ -201,7 +201,7 @@ public function getPresentMap(bool $packageIds = false): array { $presentMap = []; - if ($this->lockedRepository) { + if ($this->lockedRepository !== null) { foreach ($this->lockedRepository->getPackages() as $package) { $presentMap[$packageIds ? $package->getId() : spl_object_hash($package)] = $package; } @@ -215,7 +215,7 @@ public function getPresentMap(bool $packageIds = false): array } /** - * @return BasePackage[] + * @return array */ public function getFixedPackagesMap(): array { diff --git a/vendor/composer/composer/src/Composer/DependencyResolver/Rule.php b/vendor/composer/composer/src/Composer/DependencyResolver/Rule.php index 1b2f1aa..8dde02b 100644 --- a/vendor/composer/composer/src/Composer/DependencyResolver/Rule.php +++ b/vendor/composer/composer/src/Composer/DependencyResolver/Rule.php @@ -137,12 +137,12 @@ public function enable(): void public function isDisabled(): bool { - return (bool) (($this->bitfield & (255 << self::BITFIELD_DISABLED)) >> self::BITFIELD_DISABLED); + return 0 !== (($this->bitfield & (255 << self::BITFIELD_DISABLED)) >> self::BITFIELD_DISABLED); } public function isEnabled(): bool { - return !(($this->bitfield & (255 << self::BITFIELD_DISABLED)) >> self::BITFIELD_DISABLED); + return 0 === (($this->bitfield & (255 << self::BITFIELD_DISABLED)) >> self::BITFIELD_DISABLED); } abstract public function isAssertion(): bool; @@ -153,7 +153,7 @@ public function isCausedByLock(RepositorySet $repositorySet, Request $request, P if (PlatformRepository::isPlatformPackage($this->getReasonData()->getTarget())) { return false; } - if ($request->getLockedRepository()) { + if ($request->getLockedRepository() !== null) { foreach ($request->getLockedRepository()->getPackages() as $package) { if ($package->getName() === $this->getReasonData()->getTarget()) { if ($pool->isUnacceptableFixedOrLockedPackage($package)) { @@ -176,7 +176,7 @@ public function isCausedByLock(RepositorySet $repositorySet, Request $request, P if (PlatformRepository::isPlatformPackage($this->getReasonData()['packageName'])) { return false; } - if ($request->getLockedRepository()) { + if ($request->getLockedRepository() !== null) { foreach ($request->getLockedRepository()->getPackages() as $package) { if ($package->getName() === $this->getReasonData()['packageName']) { if ($pool->isUnacceptableFixedOrLockedPackage($package)) { @@ -215,7 +215,7 @@ public function getSourcePackage(Pool $pool): BasePackage return $package2; case self::RULE_PACKAGE_REQUIRES: - $sourceLiteral = array_shift($literals); + $sourceLiteral = $literals[0]; $sourcePackage = $this->deduplicateDefaultBranchAlias($pool->literalToPackage($sourceLiteral)); return $sourcePackage; @@ -240,14 +240,14 @@ public function getPrettyString(RepositorySet $repositorySet, Request $request, $constraint = $reasonData['constraint']; $packages = $pool->whatProvides($packageName, $constraint); - if (!$packages) { + if (0 === \count($packages)) { return 'No package found to satisfy root composer.json require '.$packageName.' '.$constraint->getPrettyString(); } $packagesNonAlias = array_values(array_filter($packages, static function ($p): bool { return !($p instanceof AliasPackage); })); - if (count($packagesNonAlias) === 1) { + if (\count($packagesNonAlias) === 1) { $package = $packagesNonAlias[0]; if ($request->isLockedPackage($package)) { return $package->getPrettyName().' is locked to version '.$package->getPrettyVersion()." and an update of this package was not requested."; @@ -305,6 +305,7 @@ public function getPrettyString(RepositorySet $repositorySet, Request $request, return $package2->getPrettyString().' conflicts with '.$conflictTarget.'.'; case self::RULE_PACKAGE_REQUIRES: + assert(\count($literals) > 0); $sourceLiteral = array_shift($literals); $sourcePackage = $this->deduplicateDefaultBranchAlias($pool->literalToPackage($sourceLiteral)); $reasonData = $this->getReasonData(); @@ -315,7 +316,7 @@ public function getPrettyString(RepositorySet $repositorySet, Request $request, } $text = $reasonData->getPrettyString($sourcePackage); - if ($requires) { + if (\count($requires) > 0) { $text .= ' -> satisfiable by ' . $this->formatPackagesUnique($pool, $requires, $isVerbose, $reasonData->getConstraint()) . '.'; } else { $targetName = $reasonData->getTarget(); @@ -333,19 +334,18 @@ public function getPrettyString(RepositorySet $repositorySet, Request $request, $package = $pool->literalToPackage($literal); $packageNames[$package->getName()] = true; } + unset($literal); $replacedName = $this->getReasonData(); - if (count($packageNames) > 1) { - $reason = null; - + if (\count($packageNames) > 1) { if (!isset($packageNames[$replacedName])) { - $reason = 'They '.(count($literals) === 2 ? 'both' : 'all').' replace '.$replacedName.' and thus cannot coexist.'; + $reason = 'They '.(\count($literals) === 2 ? 'both' : 'all').' replace '.$replacedName.' and thus cannot coexist.'; } else { $replacerNames = $packageNames; unset($replacerNames[$replacedName]); $replacerNames = array_keys($replacerNames); - if (count($replacerNames) === 1) { + if (\count($replacerNames) === 1) { $reason = $replacerNames[0] . ' replaces '; } else { $reason = '['.implode(', ', $replacerNames).'] replace '; @@ -363,7 +363,7 @@ public function getPrettyString(RepositorySet $repositorySet, Request $request, } } - if ($installedPackages && $removablePackages) { + if (\count($installedPackages) > 0 && \count($removablePackages) > 0) { return $this->formatPackagesUnique($pool, $removablePackages, $isVerbose, null, true).' cannot be installed as that would require removing '.$this->formatPackagesUnique($pool, $installedPackages, $isVerbose, null, true).'. '.$reason; } @@ -381,7 +381,7 @@ public function getPrettyString(RepositorySet $repositorySet, Request $request, // } $learnedString = ' (conflict analysis result)'; - if (count($literals) === 1) { + if (\count($literals) === 1) { $ruleText = $pool->literalToPrettyString($literals[0], $installedMap); } else { $groups = []; @@ -397,7 +397,7 @@ public function getPrettyString(RepositorySet $repositorySet, Request $request, } $ruleTexts = []; foreach ($groups as $group => $packages) { - $ruleTexts[] = $group . (count($packages) > 1 ? ' one of' : '').' ' . $this->formatPackagesUnique($pool, $packages, $isVerbose); + $ruleTexts[] = $group . (\count($packages) > 1 ? ' one of' : '').' ' . $this->formatPackagesUnique($pool, $packages, $isVerbose); } $ruleText = implode(' | ', $ruleTexts); @@ -439,14 +439,13 @@ public function getPrettyString(RepositorySet $repositorySet, Request $request, } /** - * @param array $packages An array containing packages or literals + * @param array $literalsOrPackages An array containing packages or literals */ - protected function formatPackagesUnique(Pool $pool, array $packages, bool $isVerbose, ?ConstraintInterface $constraint = null, bool $useRemovedVersionGroup = false): string + protected function formatPackagesUnique(Pool $pool, array $literalsOrPackages, bool $isVerbose, ?ConstraintInterface $constraint = null, bool $useRemovedVersionGroup = false): string { - foreach ($packages as $index => $package) { - if (!\is_object($package)) { - $packages[$index] = $pool->literalToPackage($package); - } + $packages = []; + foreach ($literalsOrPackages as $package) { + $packages[] = \is_object($package) ? $package : $pool->literalToPackage($package); } return Problem::getPackageList($packages, $isVerbose, $pool, $constraint, $useRemovedVersionGroup); diff --git a/vendor/composer/composer/src/Composer/DependencyResolver/Rule2Literals.php b/vendor/composer/composer/src/Composer/DependencyResolver/Rule2Literals.php index 17bfaf8..33d0ed0 100644 --- a/vendor/composer/composer/src/Composer/DependencyResolver/Rule2Literals.php +++ b/vendor/composer/composer/src/Composer/DependencyResolver/Rule2Literals.php @@ -43,7 +43,7 @@ public function __construct(int $literal1, int $literal2, $reason, $reasonData) } /** - * @return list + * @return non-empty-list */ public function getLiterals(): array { diff --git a/vendor/composer/composer/src/Composer/DependencyResolver/RuleSet.php b/vendor/composer/composer/src/Composer/DependencyResolver/RuleSet.php index 4a40623..cca9eb1 100644 --- a/vendor/composer/composer/src/Composer/DependencyResolver/RuleSet.php +++ b/vendor/composer/composer/src/Composer/DependencyResolver/RuleSet.php @@ -179,7 +179,7 @@ public function getPrettyString(?RepositorySet $repositorySet = null, ?Request $ foreach ($this->rules as $type => $rules) { $string .= str_pad(self::TYPES[$type], 8, ' ') . ": "; foreach ($rules as $rule) { - $string .= ($repositorySet && $request && $pool ? $rule->getPrettyString($repositorySet, $request, $pool, $isVerbose) : $rule)."\n"; + $string .= ($repositorySet !== null && $request !== null && $pool !== null ? $rule->getPrettyString($repositorySet, $request, $pool, $isVerbose) : $rule)."\n"; } $string .= "\n\n"; } diff --git a/vendor/composer/composer/src/Composer/DependencyResolver/RuleSetGenerator.php b/vendor/composer/composer/src/Composer/DependencyResolver/RuleSetGenerator.php index 69d1191..08c874f 100644 --- a/vendor/composer/composer/src/Composer/DependencyResolver/RuleSetGenerator.php +++ b/vendor/composer/composer/src/Composer/DependencyResolver/RuleSetGenerator.php @@ -56,7 +56,7 @@ public function __construct(PolicyInterface $policy, Pool $pool) * * @phpstan-param ReasonData $reasonData */ - protected function createRequireRule(BasePackage $package, array $providers, $reason, $reasonData = null): ?Rule + protected function createRequireRule(BasePackage $package, array $providers, $reason, $reasonData): ?Rule { $literals = [-$package->id]; @@ -77,7 +77,7 @@ protected function createRequireRule(BasePackage $package, array $providers, $re * The rule is (A|B|C) with A, B and C different packages. If the given * set of packages is empty an impossible rule is generated. * - * @param BasePackage[] $packages The set of packages to choose from + * @param non-empty-array $packages The set of packages to choose from * @param Rule::RULE_* $reason A RULE_* constant describing the reason for * generating this rule * @param mixed $reasonData Additional data like the root require or fix request info @@ -109,7 +109,7 @@ protected function createInstallOneOfRule(array $packages, $reason, $reasonData) * * @phpstan-param ReasonData $reasonData */ - protected function createRule2Literals(BasePackage $issuer, BasePackage $provider, $reason, $reasonData = null): ?Rule + protected function createRule2Literals(BasePackage $issuer, BasePackage $provider, $reason, $reasonData): ?Rule { // ignore self conflict if ($issuer === $provider) { @@ -120,7 +120,7 @@ protected function createRule2Literals(BasePackage $issuer, BasePackage $provide } /** - * @param BasePackage[] $packages + * @param non-empty-array $packages * @param Rule::RULE_* $reason A RULE_* constant * @param mixed $reasonData * @@ -151,7 +151,7 @@ protected function createMultiConflictRule(array $packages, $reason, $reasonData */ private function addRule($type, ?Rule $newRule = null): void { - if (!$newRule) { + if (null === $newRule) { return; } @@ -276,7 +276,7 @@ protected function addRulesForRequest(Request $request, PlatformRequirementFilte } $packages = $this->pool->whatProvides($packageName, $constraint); - if ($packages) { + if (\count($packages) > 0) { foreach ($packages as $package) { $this->addRulesForPackage($package, $platformRequirementFilter); } @@ -307,7 +307,7 @@ protected function addRulesForRootAliases(PlatformRequirementFilterInterface $pl public function getRulesFor(Request $request, ?PlatformRequirementFilterInterface $platformRequirementFilter = null): RuleSet { - $platformRequirementFilter = $platformRequirementFilter ?: PlatformRequirementFilterFactory::ignoreNothing(); + $platformRequirementFilter = $platformRequirementFilter ?? PlatformRequirementFilterFactory::ignoreNothing(); $this->addRulesForRequest($request, $platformRequirementFilter); diff --git a/vendor/composer/composer/src/Composer/DependencyResolver/RuleSetIterator.php b/vendor/composer/composer/src/Composer/DependencyResolver/RuleSetIterator.php index 2bf67f5..3b8383d 100644 --- a/vendor/composer/composer/src/Composer/DependencyResolver/RuleSetIterator.php +++ b/vendor/composer/composer/src/Composer/DependencyResolver/RuleSetIterator.php @@ -14,7 +14,7 @@ /** * @author Nils Adermann - * @implements \Iterator + * @implements \Iterator */ class RuleSetIterator implements \Iterator { diff --git a/vendor/composer/composer/src/Composer/DependencyResolver/Solver.php b/vendor/composer/composer/src/Composer/DependencyResolver/Solver.php index 373e832..b8aa847 100644 --- a/vendor/composer/composer/src/Composer/DependencyResolver/Solver.php +++ b/vendor/composer/composer/src/Composer/DependencyResolver/Solver.php @@ -43,7 +43,7 @@ class Solver /** @var int */ protected $propagateIndex; - /** @var mixed[] */ + /** @var array, int}> */ protected $branches = []; /** @var Problem[] */ protected $problems = []; @@ -109,7 +109,7 @@ private function makeAssertionRuleDecisions(): void $conflict = $this->decisions->decisionRule($literal); - if ($conflict && RuleSet::TYPE_PACKAGE === $conflict->getType()) { + if (RuleSet::TYPE_PACKAGE === $conflict->getType()) { $problem = new Problem(); $problem->addRule($rule); @@ -164,7 +164,7 @@ protected function checkForRootRequireProblems(Request $request, PlatformRequire $constraint = $platformRequirementFilter->filterConstraint($packageName, $constraint); } - if (!$this->pool->whatProvides($packageName, $constraint)) { + if (0 === \count($this->pool->whatProvides($packageName, $constraint))) { $problem = new Problem(); $problem->addRule(new GenericRule([], Rule::RULE_ROOT_REQUIRE, ['packageName' => $packageName, 'constraint' => $constraint])); $this->problems[] = $problem; @@ -174,7 +174,7 @@ protected function checkForRootRequireProblems(Request $request, PlatformRequire public function solve(Request $request, ?PlatformRequirementFilterInterface $platformRequirementFilter = null): LockTransaction { - $platformRequirementFilter = $platformRequirementFilter ?: PlatformRequirementFilterFactory::ignoreNothing(); + $platformRequirementFilter = $platformRequirementFilter ?? PlatformRequirementFilterFactory::ignoreNothing(); $this->setupFixedMap($request); @@ -199,7 +199,7 @@ public function solve(Request $request, ?PlatformRequirementFilterInterface $pla $this->io->writeError('', true, IOInterface::DEBUG); $this->io->writeError(sprintf('Dependency resolution completed in %.3f seconds', microtime(true) - $before), true, IOInterface::VERBOSE); - if ($this->problems) { + if (\count($this->problems) > 0) { throw new SolverProblemsException($this->problems, $this->learnedPool); } @@ -227,7 +227,7 @@ protected function propagate(int $level): ?Rule $this->propagateIndex++; - if ($conflict) { + if ($conflict !== null) { return $conflict; } } @@ -257,7 +257,7 @@ private function revert(int $level): void $this->propagateIndex = \count($this->decisions); } - while (!empty($this->branches) && $this->branches[\count($this->branches) - 1][self::BRANCH_LEVEL] >= $level) { + while (\count($this->branches) > 0 && $this->branches[\count($this->branches) - 1][self::BRANCH_LEVEL] >= $level) { array_pop($this->branches); } } @@ -274,10 +274,8 @@ private function revert(int $level): void * rule (always unit) and re-propagate. * * returns the new solver level or 0 if unsolvable - * - * @param string|int $literal */ - private function setPropagateLearn(int $level, $literal, Rule $rule): int + private function setPropagateLearn(int $level, int $literal, Rule $rule): int { $level++; @@ -291,7 +289,9 @@ private function setPropagateLearn(int $level, $literal, Rule $rule): int } if ($level === 1) { - return $this->analyzeUnsolvable($rule); + $this->analyzeUnsolvable($rule); + + return 0; } // conflict @@ -322,7 +322,7 @@ private function setPropagateLearn(int $level, $literal, Rule $rule): int } /** - * @param int[] $decisionQueue + * @param non-empty-list $decisionQueue */ private function selectAndInstall(int $level, array $decisionQueue, Rule $rule): int { @@ -332,7 +332,7 @@ private function selectAndInstall(int $level, array $decisionQueue, Rule $rule): $selectedLiteral = array_shift($literals); // if there are multiple candidates, then branch - if (\count($literals)) { + if (\count($literals) > 0) { $this->branches[] = [$literals, $level]; } @@ -349,7 +349,8 @@ protected function analyze(int $level, Rule $rule): array $num = 0; $l1num = 0; $seen = []; - $learnedLiterals = [null]; + $learnedLiteral = null; + $otherLearnedLiterals = []; $decisionId = \count($this->decisions); @@ -382,7 +383,7 @@ protected function analyze(int $level, Rule $rule): array $num++; } else { // not level1 or conflict level, add to new rule - $learnedLiterals[] = $literal; + $otherLearnedLiterals[] = $literal; if ($l > $ruleLevel) { $ruleLevel = $l; @@ -423,16 +424,14 @@ protected function analyze(int $level, Rule $rule): array if ($literal < 0) { $this->testFlagLearnedPositiveLiteral = true; } - $learnedLiterals[0] = -$literal; + $learnedLiteral = -$literal; - if (!$l1num) { + if (0 === $l1num) { break 2; } - foreach ($learnedLiterals as $i => $learnedLiteral) { - if ($i !== 0) { - unset($seen[abs($learnedLiteral)]); - } + foreach ($otherLearnedLiterals as $otherLiteral) { + unset($seen[abs($otherLiteral)]); } // only level 1 marks left $l1num++; @@ -442,24 +441,24 @@ protected function analyze(int $level, Rule $rule): array $rule = $decision[Decisions::DECISION_REASON]; if ($rule instanceof MultiConflictRule) { - // there is only ever exactly one positive decision in a multiconflict rule - foreach ($rule->getLiterals() as $literal) { - if (!isset($seen[abs($literal)]) && $this->decisions->satisfy(-$literal)) { + // there is only ever exactly one positive decision in a MultiConflictRule + foreach ($rule->getLiterals() as $ruleLiteral) { + if (!isset($seen[abs($ruleLiteral)]) && $this->decisions->satisfy(-$ruleLiteral)) { $this->learnedPool[\count($this->learnedPool) - 1][] = $rule; - $l = $this->decisions->decisionLevel($literal); + $l = $this->decisions->decisionLevel($ruleLiteral); if (1 === $l) { $l1num++; } elseif ($level === $l) { $num++; } else { // not level1 or conflict level, add to new rule - $learnedLiterals[] = $literal; + $otherLearnedLiterals[] = $ruleLiteral; if ($l > $ruleLevel) { $ruleLevel = $l; } } - $seen[abs($literal)] = true; + $seen[abs($ruleLiteral)] = true; break; } } @@ -475,15 +474,16 @@ protected function analyze(int $level, Rule $rule): array $why = \count($this->learnedPool) - 1; - if (null === $learnedLiterals[0]) { + if (null === $learnedLiteral) { throw new SolverBugException( "Did not find a learnable literal in analyzed rule $analyzedRule." ); } - $newRule = new GenericRule($learnedLiterals, Rule::RULE_LEARNED, $why); + array_unshift($otherLearnedLiterals, $learnedLiteral); + $newRule = new GenericRule($otherLearnedLiterals, Rule::RULE_LEARNED, $why); - return [$learnedLiterals[0], $ruleLevel, $newRule, $why]; + return [$learnedLiteral, $ruleLevel, $newRule, $why]; } /** @@ -516,7 +516,7 @@ private function analyzeUnsolvableRule(Problem $problem, Rule $conflictRule, arr $problem->addRule($conflictRule); } - private function analyzeUnsolvable(Rule $conflictRule): int + private function analyzeUnsolvable(Rule $conflictRule): void { $problem = new Problem(); $problem->addRule($conflictRule); @@ -539,10 +539,10 @@ private function analyzeUnsolvable(Rule $conflictRule): int } foreach ($this->decisions as $decision) { - $literal = $decision[Decisions::DECISION_LITERAL]; + $decisionLiteral = $decision[Decisions::DECISION_LITERAL]; // skip literals that are not in this rule - if (!isset($seen[abs($literal)])) { + if (!isset($seen[abs($decisionLiteral)])) { continue; } @@ -552,7 +552,6 @@ private function analyzeUnsolvable(Rule $conflictRule): int $this->analyzeUnsolvableRule($problem, $why, $ruleSeen); $literals = $why->getLiterals(); - foreach ($literals as $literal) { // skip the one true literal if ($this->decisions->satisfy($literal)) { @@ -561,8 +560,6 @@ private function analyzeUnsolvable(Rule $conflictRule): int $seen[abs($literal)] = true; } } - - return 0; } private function runSat(): void @@ -586,9 +583,7 @@ private function runSat(): void if (1 === $level) { $conflictRule = $this->propagate($level); if (null !== $conflictRule) { - if ($this->analyzeUnsolvable($conflictRule)) { - continue; - } + $this->analyzeUnsolvable($conflictRule); return; } @@ -612,7 +607,7 @@ private function runSat(): void } } - if ($noneSatisfied && \count($decisionQueue)) { + if ($noneSatisfied && \count($decisionQueue) > 0) { // if any of the options in the decision queue are fixed, only use those $prunedQueue = []; foreach ($decisionQueue as $literal) { @@ -620,12 +615,12 @@ private function runSat(): void $prunedQueue[] = $literal; } } - if (!empty($prunedQueue)) { + if (\count($prunedQueue) > 0) { $decisionQueue = $prunedQueue; } } - if ($noneSatisfied && \count($decisionQueue)) { + if ($noneSatisfied && \count($decisionQueue) > 0) { $oLevel = $level; $level = $this->selectAndInstall($level, $decisionQueue, $rule); @@ -719,7 +714,7 @@ private function runSat(): void } // minimization step - if (\count($this->branches)) { + if (\count($this->branches) > 0) { $lastLiteral = null; $lastLevel = null; $lastBranchIndex = 0; @@ -729,7 +724,7 @@ private function runSat(): void [$literals, $l] = $this->branches[$i]; foreach ($literals as $offset => $literal) { - if ($literal && $literal > 0 && $this->decisions->decisionLevel($literal) > $l + 1) { + if ($literal > 0 && $this->decisions->decisionLevel($literal) > $l + 1) { $lastLiteral = $literal; $lastBranchIndex = $i; $lastBranchOffset = $offset; @@ -738,7 +733,8 @@ private function runSat(): void } } - if ($lastLiteral) { + if ($lastLiteral !== null) { + assert($lastLevel !== null); unset($this->branches[$lastBranchIndex][self::BRANCH_LITERALS][$lastBranchOffset]); $level = $lastLevel; diff --git a/vendor/composer/composer/src/Composer/DependencyResolver/SolverProblemsException.php b/vendor/composer/composer/src/Composer/DependencyResolver/SolverProblemsException.php index 5870c0c..bd76e4f 100644 --- a/vendor/composer/composer/src/Composer/DependencyResolver/SolverProblemsException.php +++ b/vendor/composer/composer/src/Composer/DependencyResolver/SolverProblemsException.php @@ -38,7 +38,7 @@ public function __construct(array $problems, array $learnedPool) $this->problems = $problems; $this->learnedPool = $learnedPool; - parent::__construct('Failed resolving dependencies with '.count($problems).' problems, call getPrettyString to get formatted details', self::ERROR_DEPENDENCY_RESOLUTION_FAILED); + parent::__construct('Failed resolving dependencies with '.\count($problems).' problems, call getPrettyString to get formatted details', self::ERROR_DEPENDENCY_RESOLUTION_FAILED); } public function getPrettyString(RepositorySet $repositorySet, Request $request, Pool $pool, bool $isVerbose, bool $isDevExtraction = false): string @@ -63,11 +63,11 @@ public function getPrettyString(RepositorySet $repositorySet, Request $request, } $hints = []; - if (!$isDevExtraction && (strpos($text, 'could not be found') || strpos($text, 'no matching package found'))) { + if (!$isDevExtraction && (str_contains($text, 'could not be found') || str_contains($text, 'no matching package found'))) { $hints[] = "Potential causes:\n - A typo in the package name\n - The package is not available in a stable-enough version according to your minimum-stability setting\n see for more details.\n - It's a private package and you forgot to add a custom repository to find it\n\nRead for further common problems."; } - if (!empty($missingExtensions)) { + if (\count($missingExtensions) > 0) { $hints[] = $this->createExtensionHint($missingExtensions); } @@ -75,17 +75,17 @@ public function getPrettyString(RepositorySet $repositorySet, Request $request, $hints[] = "Use the option --with-all-dependencies (-W) to allow upgrades, downgrades and removals for packages currently locked to specific versions."; } - if (strpos($text, 'found composer-plugin-api[2.0.0] but it does not match') && strpos($text, '- ocramius/package-versions')) { + if (str_contains($text, 'found composer-plugin-api[2.0.0] but it does not match') && str_contains($text, '- ocramius/package-versions')) { $hints[] = "ocramius/package-versions only provides support for Composer 2 in 1.8+, which requires PHP 7.4.\nIf you can not upgrade PHP you can require composer/package-versions-deprecated to resolve this with PHP 7.0+."; } if (!class_exists('PHPUnit\Framework\TestCase', false)) { - if (strpos($text, 'found composer-plugin-api[2.0.0] but it does not match')) { + if (str_contains($text, 'found composer-plugin-api[2.0.0] but it does not match')) { $hints[] = "You are using Composer 2, which some of your plugins seem to be incompatible with. Make sure you update your plugins or report a plugin-issue to ask them to support Composer 2."; } } - if ($hints) { + if (\count($hints) > 0) { $text .= "\n" . implode("\n\n", $hints); } diff --git a/vendor/composer/composer/src/Composer/DependencyResolver/Transaction.php b/vendor/composer/composer/src/Composer/DependencyResolver/Transaction.php index ef6860c..3443dd7 100644 --- a/vendor/composer/composer/src/Composer/DependencyResolver/Transaction.php +++ b/vendor/composer/composer/src/Composer/DependencyResolver/Transaction.php @@ -123,7 +123,7 @@ protected function calculateOperations(): array $visited = []; $processed = []; - while (!empty($stack)) { + while (\count($stack) > 0) { $package = array_pop($stack); if (isset($processed[spl_object_hash($package)])) { @@ -283,17 +283,18 @@ private function movePluginsToFront(array $operations): array continue; } - $isDownloadsModifyingPlugin = $package->getType() === 'composer-plugin' && ($extra = $package->getExtra()) && isset($extra['plugin-modifies-downloads']) && $extra['plugin-modifies-downloads'] === true; + $extra = $package->getExtra(); + $isDownloadsModifyingPlugin = $package->getType() === 'composer-plugin' && isset($extra['plugin-modifies-downloads']) && $extra['plugin-modifies-downloads'] === true; // is this a downloads modifying plugin or a dependency of one? - if ($isDownloadsModifyingPlugin || count(array_intersect($package->getNames(), $dlModifyingPluginRequires))) { + if ($isDownloadsModifyingPlugin || \count(array_intersect($package->getNames(), $dlModifyingPluginRequires)) > 0) { // get the package's requires, but filter out any platform requirements $requires = array_filter(array_keys($package->getRequires()), static function ($req): bool { return !PlatformRepository::isPlatformPackage($req); }); // is this a plugin with no meaningful dependencies? - if ($isDownloadsModifyingPlugin && !count($requires)) { + if ($isDownloadsModifyingPlugin && 0 === \count($requires)) { // plugins with no dependencies go to the very front array_unshift($dlModifyingPluginsNoDeps, $op); } else { @@ -311,14 +312,14 @@ private function movePluginsToFront(array $operations): array $isPlugin = $package->getType() === 'composer-plugin' || $package->getType() === 'composer-installer'; // is this a plugin or a dependency of a plugin? - if ($isPlugin || count(array_intersect($package->getNames(), $pluginRequires))) { + if ($isPlugin || \count(array_intersect($package->getNames(), $pluginRequires)) > 0) { // get the package's requires, but filter out any platform requirements $requires = array_filter(array_keys($package->getRequires()), static function ($req): bool { return !PlatformRepository::isPlatformPackage($req); }); // is this a plugin with no meaningful dependencies? - if ($isPlugin && !count($requires)) { + if ($isPlugin && 0 === \count($requires)) { // plugins with no dependencies go to the very front array_unshift($pluginsNoDeps, $op); } else { diff --git a/vendor/composer/composer/src/Composer/Downloader/ArchiveDownloader.php b/vendor/composer/composer/src/Composer/Downloader/ArchiveDownloader.php index 6de51ee..ff132e2 100644 --- a/vendor/composer/composer/src/Composer/Downloader/ArchiveDownloader.php +++ b/vendor/composer/composer/src/Composer/Downloader/ArchiveDownloader.php @@ -68,7 +68,7 @@ public function install(PackageInterface $package, string $path, bool $output = } do { - $temporaryDir = $vendorDir.'/composer/'.substr(md5(uniqid('', true)), 0, 8); + $temporaryDir = $vendorDir.'/composer/'.bin2hex(random_bytes(4)); } while (is_dir($temporaryDir)); $this->addCleanupPath($package, $temporaryDir); diff --git a/vendor/composer/composer/src/Composer/Downloader/FileDownloader.php b/vendor/composer/composer/src/Composer/Downloader/FileDownloader.php index 2a2847f..2e1207b 100644 --- a/vendor/composer/composer/src/Composer/Downloader/FileDownloader.php +++ b/vendor/composer/composer/src/Composer/Downloader/FileDownloader.php @@ -27,6 +27,7 @@ use Composer\Plugin\PreFileDownloadEvent; use Composer\EventDispatcher\EventDispatcher; use Composer\Util\Filesystem; +use Composer\Util\Http\Response; use Composer\Util\Platform; use Composer\Util\Silencer; use Composer\Util\HttpDownloader; @@ -99,9 +100,9 @@ public function __construct(IOInterface $io, Config $config, HttpDownloader $htt $this->httpDownloader = $httpDownloader; $this->cache = $cache; $this->process = $process ?? new ProcessExecutor($io); - $this->filesystem = $filesystem ?: new Filesystem($this->process); + $this->filesystem = $filesystem ?? new Filesystem($this->process); - if ($this->cache && $this->cache->gcIsNecessary()) { + if ($this->cache !== null && $this->cache->gcIsNecessary()) { $this->io->writeError('Running cache garbage collection', true, IOInterface::VERY_VERBOSE); $this->cache->gc($config->get('cache-files-ttl'), $config->get('cache-files-maxsize')); } @@ -120,12 +121,12 @@ public function getInstallationSource(): string */ public function download(PackageInterface $package, string $path, ?PackageInterface $prevPackage = null, bool $output = true): PromiseInterface { - if (!$package->getDistUrl()) { + if (null === $package->getDistUrl()) { throw new \InvalidArgumentException('The given package is missing url information'); } $cacheKeyGenerator = static function (PackageInterface $package, $key): string { - $cacheKey = sha1($key); + $cacheKey = hash('sha1', $key); return $package->getName().'/'.$cacheKey.'.'.$package->getDistType(); }; @@ -152,21 +153,15 @@ public function download(PackageInterface $package, string $path, ?PackageInterf $this->filesystem->ensureDirectoryExists($path); $this->filesystem->ensureDirectoryExists(dirname($fileName)); - $io = $this->io; - $cache = $this->cache; - $httpDownloader = $this->httpDownloader; - $eventDispatcher = $this->eventDispatcher; - $filesystem = $this->filesystem; - $accept = null; $reject = null; - $download = function () use ($io, $output, $httpDownloader, $cache, $cacheKeyGenerator, $eventDispatcher, $package, $fileName, &$urls, &$accept, &$reject) { + $download = function () use ($output, $cacheKeyGenerator, $package, $fileName, &$urls, &$accept, &$reject) { $url = reset($urls); $index = key($urls); - if ($eventDispatcher) { - $preFileDownloadEvent = new PreFileDownloadEvent(PluginEvents::PRE_FILE_DOWNLOAD, $httpDownloader, $url['processed'], 'package', $package); - $eventDispatcher->dispatch($preFileDownloadEvent->getName(), $preFileDownloadEvent); + if ($this->eventDispatcher !== null) { + $preFileDownloadEvent = new PreFileDownloadEvent(PluginEvents::PRE_FILE_DOWNLOAD, $this->httpDownloader, $url['processed'], 'package', $package); + $this->eventDispatcher->dispatch($preFileDownloadEvent->getName(), $preFileDownloadEvent); if ($preFileDownloadEvent->getCustomCacheKey() !== null) { $url['cacheKey'] = $cacheKeyGenerator($package, $preFileDownloadEvent->getCustomCacheKey()); } elseif ($preFileDownloadEvent->getProcessedUrl() !== $url['processed']) { @@ -181,27 +176,27 @@ public function download(PackageInterface $package, string $path, ?PackageInterf $cacheKey = $url['cacheKey']; // use from cache if it is present and has a valid checksum or we have no checksum to check against - if ($cache && (!$checksum || $checksum === $cache->sha1($cacheKey)) && $cache->copyTo($cacheKey, $fileName)) { + if ($this->cache !== null && ($checksum === null || $checksum === '' || $checksum === $this->cache->sha1($cacheKey)) && $this->cache->copyTo($cacheKey, $fileName)) { if ($output) { - $io->writeError(" - Loading " . $package->getName() . " (" . $package->getFullPrettyVersion() . ") from cache", true, IOInterface::VERY_VERBOSE); + $this->io->writeError(" - Loading " . $package->getName() . " (" . $package->getFullPrettyVersion() . ") from cache", true, IOInterface::VERY_VERBOSE); } // mark the file as having been written in cache even though it is only read from cache, so that if // the cache is corrupt the archive will be deleted and the next attempt will re-download it // see https://github.com/composer/composer/issues/10028 - if (!$cache->isReadOnly()) { + if (!$this->cache->isReadOnly()) { $this->lastCacheWrites[$package->getName()] = $cacheKey; } $result = \React\Promise\resolve($fileName); } else { if ($output) { - $io->writeError(" - Downloading " . $package->getName() . " (" . $package->getFullPrettyVersion() . ")"); + $this->io->writeError(" - Downloading " . $package->getName() . " (" . $package->getFullPrettyVersion() . ")"); } - $result = $httpDownloader->addCopy($url['processed'], $fileName, $package->getTransportOptions()) + $result = $this->httpDownloader->addCopy($url['processed'], $fileName, $package->getTransportOptions()) ->then($accept, $reject); } - return $result->then(static function ($result) use ($fileName, $checksum, $url, $package, $eventDispatcher): string { + return $result->then(function ($result) use ($fileName, $checksum, $url, $package): string { // in case of retry, the first call's Promise chain finally calls this twice at the end, // once with $result being the returned $fileName from $accept, and then once for every // failed request with a null result, which can be skipped. @@ -214,31 +209,35 @@ public function download(PackageInterface $package, string $path, ?PackageInterf .' directory is writable and you have internet connectivity'); } - if ($checksum && hash_file('sha1', $fileName) !== $checksum) { + if ($checksum !== null && $checksum !== '' && hash_file('sha1', $fileName) !== $checksum) { throw new \UnexpectedValueException('The checksum verification of the file failed (downloaded from '.$url['base'].')'); } - if ($eventDispatcher) { + if ($this->eventDispatcher !== null) { $postFileDownloadEvent = new PostFileDownloadEvent(PluginEvents::POST_FILE_DOWNLOAD, $fileName, $checksum, $url['processed'], 'package', $package); - $eventDispatcher->dispatch($postFileDownloadEvent->getName(), $postFileDownloadEvent); + $this->eventDispatcher->dispatch($postFileDownloadEvent->getName(), $postFileDownloadEvent); } return $fileName; }); }; - $accept = function ($response) use ($cache, $package, $fileName, &$urls): string { + $accept = function (Response $response) use ($package, $fileName, &$urls): string { $url = reset($urls); $cacheKey = $url['cacheKey']; - FileDownloader::$downloadMetadata[$package->getName()] = @filesize($fileName) ?: $response->getHeader('Content-Length') ?: '?'; + $fileSize = @filesize($fileName); + if (false === $fileSize) { + $fileSize = $response->getHeader('Content-Length') ?? '?'; + } + FileDownloader::$downloadMetadata[$package->getName()] = $fileSize; if (Platform::getEnv('GITHUB_ACTIONS') !== false && Platform::getEnv('COMPOSER_TESTS_ARE_RUNNING') === false) { FileDownloader::$responseHeaders[$package->getName()] = $response->getHeaders(); } - if ($cache && !$cache->isReadOnly()) { + if ($this->cache !== null && !$this->cache->isReadOnly()) { $this->lastCacheWrites[$package->getName()] = $cacheKey; - $cache->copyFrom($cacheKey, $fileName); + $this->cache->copyFrom($cacheKey, $fileName); } $response->collect(); @@ -246,10 +245,10 @@ public function download(PackageInterface $package, string $path, ?PackageInterf return $fileName; }; - $reject = function ($e) use ($io, &$urls, $download, $fileName, $package, &$retries, $filesystem) { + $reject = function ($e) use (&$urls, $download, $fileName, $package, &$retries) { // clean up if (file_exists($fileName)) { - $filesystem->unlink($fileName); + $this->filesystem->unlink($fileName); } $this->clearLastCacheWrite($package); @@ -263,7 +262,7 @@ public function download(PackageInterface $package, string $path, ?PackageInterf if ($e instanceof TransportException) { // if we got an http response with a proper code, then requesting again will probably not help, abort - if ((0 !== $e->getCode() && !in_array($e->getCode(), [500, 502, 503, 504])) || !$retries) { + if (0 !== $e->getCode() && !in_array($e->getCode(), [500, 502, 503, 504], true)) { $retries = 0; } } @@ -274,7 +273,7 @@ public function download(PackageInterface $package, string $path, ?PackageInterf $urls = []; } - if ($retries) { + if ($retries > 0) { usleep(500000); $retries--; @@ -282,12 +281,12 @@ public function download(PackageInterface $package, string $path, ?PackageInterf } array_shift($urls); - if ($urls) { - if ($io->isDebug()) { - $io->writeError(' Failed downloading '.$package->getName().': ['.get_class($e).'] '.$e->getCode().': '.$e->getMessage()); - $io->writeError(' Trying the next URL for '.$package->getName()); + if (\count($urls) > 0) { + if ($this->io->isDebug()) { + $this->io->writeError(' Failed downloading '.$package->getName().': ['.get_class($e).'] '.$e->getCode().': '.$e->getMessage()); + $this->io->writeError(' Trying the next URL for '.$package->getName()); } else { - $io->writeError(' Failed downloading '.$package->getName().', trying the next URL ('.$e->getCode().': '.$e->getMessage().')'); + $this->io->writeError(' Failed downloading '.$package->getName().', trying the next URL ('.$e->getCode().': '.$e->getMessage().')'); } $retries = 3; @@ -328,8 +327,8 @@ public function cleanup(string $type, PackageInterface $package, string $path, ? ]; if (isset($this->additionalCleanupPaths[$package->getName()])) { - foreach ($this->additionalCleanupPaths[$package->getName()] as $path) { - $this->filesystem->remove($path); + foreach ($this->additionalCleanupPaths[$package->getName()] as $pathToClean) { + $this->filesystem->remove($pathToClean); } } @@ -355,19 +354,20 @@ public function install(PackageInterface $package, string $path, bool $output = $this->filesystem->ensureDirectoryExists($path); $this->filesystem->rename($this->getFileName($package, $path), $path . '/' . $this->getDistPath($package, PATHINFO_BASENAME)); - if ($package->getBinaries()) { - // Single files can not have a mode set like files in archives - // so we make sure if the file is a binary that it is executable - foreach ($package->getBinaries() as $bin) { - if (file_exists($path . '/' . $bin) && !is_executable($path . '/' . $bin)) { - Silencer::call('chmod', $path . '/' . $bin, 0777 & ~umask()); - } + // Single files can not have a mode set like files in archives + // so we make sure if the file is a binary that it is executable + foreach ($package->getBinaries() as $bin) { + if (file_exists($path . '/' . $bin) && !is_executable($path . '/' . $bin)) { + Silencer::call('chmod', $path . '/' . $bin, 0777 & ~umask()); } } return \React\Promise\resolve(null); } + /** + * @param PATHINFO_EXTENSION|PATHINFO_BASENAME $component + */ protected function getDistPath(PackageInterface $package, int $component): string { return pathinfo((string) parse_url(strtr((string) $package->getDistUrl(), '\\', '/'), PHP_URL_PATH), $component); @@ -375,7 +375,7 @@ protected function getDistPath(PackageInterface $package, int $component): strin protected function clearLastCacheWrite(PackageInterface $package): void { - if ($this->cache && isset($this->lastCacheWrites[$package->getName()])) { + if ($this->cache !== null && isset($this->lastCacheWrites[$package->getName()])) { $this->cache->remove($this->lastCacheWrites[$package->getName()]); unset($this->lastCacheWrites[$package->getName()]); } @@ -389,7 +389,7 @@ protected function addCleanupPath(PackageInterface $package, string $path): void protected function removeCleanupPath(PackageInterface $package, string $path): void { if (isset($this->additionalCleanupPaths[$package->getName()])) { - $idx = array_search($path, $this->additionalCleanupPaths[$package->getName()]); + $idx = array_search($path, $this->additionalCleanupPaths[$package->getName()], true); if (false !== $idx) { unset($this->additionalCleanupPaths[$package->getName()][$idx]); } @@ -441,7 +441,7 @@ protected function getFileName(PackageInterface $package, string $path): string $extension = $package->getDistType(); } - return rtrim($this->config->get('vendor-dir') . '/composer/tmp-' . md5($package . spl_object_hash($package)) . '.' . $extension, '.'); + return rtrim($this->config->get('vendor-dir') . '/composer/tmp-' . hash('md5', $package . spl_object_hash($package)) . '.' . $extension, '.'); } /** @@ -469,7 +469,7 @@ protected function processUrl(PackageInterface $package, string $url): string throw new \RuntimeException('You must enable the openssl extension to download files via https'); } - if ($package->getDistReference()) { + if ($package->getDistReference() !== null) { $url = UrlUtil::updateDistReference($this->config, $url, $package->getDistReference()); } @@ -495,10 +495,22 @@ public function getLocalChanges(PackageInterface $package, string $path): ?strin $this->filesystem->removeDirectory($targetDir.'_compare'); } - $this->download($package, $targetDir.'_compare', null, false); + $promise = $this->download($package, $targetDir.'_compare', null, false); + $promise->then(null, function ($ex) use (&$e) { + $e = $ex; + }); $this->httpDownloader->wait(); - $this->install($package, $targetDir.'_compare', false); + if ($e !== null) { + throw $e; + } + $promise = $this->install($package, $targetDir.'_compare', false); + $promise->then(null, function ($ex) use (&$e) { + $e = $ex; + }); $this->process->wait(); + if ($e !== null) { + throw $e; + } $comparer = new Comparer(); $comparer->setSource($targetDir.'_compare'); @@ -511,8 +523,12 @@ public function getLocalChanges(PackageInterface $package, string $path): ?strin $this->io = $prevIO; - if ($e) { - throw $e; + if ($e !== null) { + if ($this->io->isDebug()) { + throw $e; + } + + return 'Failed to detect changes: ['.get_class($e).'] '.$e->getMessage(); } $output = trim($output); diff --git a/vendor/composer/composer/src/Composer/Downloader/GitDownloader.php b/vendor/composer/composer/src/Composer/Downloader/GitDownloader.php index 0840219..f29d745 100644 --- a/vendor/composer/composer/src/Composer/Downloader/GitDownloader.php +++ b/vendor/composer/composer/src/Composer/Downloader/GitDownloader.php @@ -67,7 +67,7 @@ protected function doDownload(PackageInterface $package, string $path, string $u GitUtil::cleanEnv(); - $cachePath = $this->config->get('cache-vcs-dir').'/'.Preg::replace('{[^a-z0-9.]}i', '-', $url).'/'; + $cachePath = $this->config->get('cache-vcs-dir').'/'.Preg::replace('{[^a-z0-9.]}i', '-', Url::sanitize($url)).'/'; $gitVersion = GitUtil::getVersion($this->process); // --dissociate option is only available since git 2.3.0-rc0 @@ -92,7 +92,7 @@ protected function doInstall(PackageInterface $package, string $path, string $ur { GitUtil::cleanEnv(); $path = $this->normalizePath($path); - $cachePath = $this->config->get('cache-vcs-dir').'/'.Preg::replace('{[^a-z0-9.]}i', '-', $url).'/'; + $cachePath = $this->config->get('cache-vcs-dir').'/'.Preg::replace('{[^a-z0-9.]}i', '-', Url::sanitize($url)).'/'; $ref = $package->getSourceReference(); $flag = Platform::isWindows() ? '/D ' : ''; @@ -161,7 +161,7 @@ protected function doUpdate(PackageInterface $initial, PackageInterface $target, throw new \RuntimeException('The .git directory is missing from '.$path.', see https://getcomposer.org/commit-deps for more information'); } - $cachePath = $this->config->get('cache-vcs-dir').'/'.Preg::replace('{[^a-z0-9.]}i', '-', $url).'/'; + $cachePath = $this->config->get('cache-vcs-dir').'/'.Preg::replace('{[^a-z0-9.]}i', '-', Url::sanitize($url)).'/'; $ref = $target->getSourceReference(); if (!empty($this->cachedPackages[$target->getId()][$ref])) { @@ -255,7 +255,7 @@ public function getUnpushedChanges(PackageInterface $package, string $path): ?st } $headRef = $match[1]; - if (!Preg::isMatchAllStrictGroups('{^'.$headRef.' refs/heads/(.+)$}mi', $refs, $matches)) { + if (!Preg::isMatchAllStrictGroups('{^'.preg_quote($headRef).' refs/heads/(.+)$}mi', $refs, $matches)) { // not on a branch, we are either on a not-modified tag or some sort of detached head, so skip this return null; } @@ -294,9 +294,9 @@ public function getUnpushedChanges(PackageInterface $package, string $path): ?st $unpushedChanges = null; } foreach ($remoteBranches as $remoteBranch) { - $command = sprintf('git diff --name-status %s...%s --', $remoteBranch, $branch); + $command = ['git', 'diff', '--name-status', $remoteBranch.'...'.$branch, '--']; if (0 !== $this->process->execute($command, $output, $path)) { - throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput()); + throw new \RuntimeException('Failed to execute ' . implode(' ', $command) . "\n\n" . $this->process->getErrorOutput()); } $output = trim($output); diff --git a/vendor/composer/composer/src/Composer/Downloader/PathDownloader.php b/vendor/composer/composer/src/Composer/Downloader/PathDownloader.php index 791521b..8997f56 100644 --- a/vendor/composer/composer/src/Composer/Downloader/PathDownloader.php +++ b/vendor/composer/composer/src/Composer/Downloader/PathDownloader.php @@ -43,6 +43,9 @@ public function download(PackageInterface $package, string $path, ?PackageInterf { $path = Filesystem::trimTrailingSlash($path); $url = $package->getDistUrl(); + if (null === $url) { + throw new \RuntimeException('The package '.$package->getPrettyName().' has no dist url configured, cannot download.'); + } $realUrl = realpath($url); if (false === $realUrl || !file_exists($realUrl) || !is_dir($realUrl)) { throw new \RuntimeException(sprintf( @@ -79,7 +82,13 @@ public function install(PackageInterface $package, string $path, bool $output = { $path = Filesystem::trimTrailingSlash($path); $url = $package->getDistUrl(); + if (null === $url) { + throw new \RuntimeException('The package '.$package->getPrettyName().' has no dist url configured, cannot install.'); + } $realUrl = realpath($url); + if (false === $realUrl) { + throw new \RuntimeException('Failed to realpath '.$url); + } if (realpath($path) === $realUrl) { if ($output) { @@ -111,16 +120,16 @@ public function install(PackageInterface $package, string $path, bool $output = } $this->filesystem->junction($realUrl, $path); } else { - $absolutePath = $path; - if (!$this->filesystem->isAbsolutePath($absolutePath)) { - $absolutePath = Platform::getCwd() . DIRECTORY_SEPARATOR . $path; - } - $shortestPath = $this->filesystem->findShortestPath($absolutePath, $realUrl); $path = rtrim($path, "/"); if ($output) { $this->io->writeError(sprintf('Symlinking from %s', $url), false); } - if ($transportOptions['relative']) { + if ($transportOptions['relative'] === true) { + $absolutePath = $path; + if (!$this->filesystem->isAbsolutePath($absolutePath)) { + $absolutePath = Platform::getCwd() . DIRECTORY_SEPARATOR . $path; + } + $shortestPath = $this->filesystem->findShortestPath($absolutePath, $realUrl, false, true); $symfonyFilesystem->symlink($shortestPath.'/', $path); } else { $symfonyFilesystem->symlink($realUrl.'/', $path); @@ -185,13 +194,18 @@ public function remove(PackageInterface $package, string $path, bool $output = t return \React\Promise\resolve(null); } + $url = $package->getDistUrl(); + if (null === $url) { + throw new \RuntimeException('The package '.$package->getPrettyName().' has no dist url configured, cannot remove.'); + } + // ensure that the source path (dist url) is not the same as the install path, which // can happen when using custom installers, see https://github.com/composer/composer/pull/9116 // not using realpath here as we do not want to resolve the symlink to the original dist url // it points to $fs = new Filesystem; $absPath = $fs->isAbsolutePath($path) ? $path : Platform::getCwd() . '/' . $path; - $absDistUrl = $fs->isAbsolutePath($package->getDistUrl()) ? $package->getDistUrl() : Platform::getCwd() . '/' . $package->getDistUrl(); + $absDistUrl = $fs->isAbsolutePath($url) ? $url : Platform::getCwd() . '/' . $url; if ($fs->normalizePath($absPath) === $fs->normalizePath($absDistUrl)) { if ($output) { $this->io->writeError(" - " . UninstallOperation::format($package).", source is still present in $path"); @@ -214,7 +228,8 @@ public function getVcsReference(PackageInterface $package, string $path): ?strin $dumper = new ArrayDumper; $packageConfig = $dumper->dump($package); - if ($packageVersion = $guesser->guessVersion($packageConfig, $path)) { + $packageVersion = $guesser->guessVersion($packageConfig, $path); + if ($packageVersion !== null) { return $packageVersion['commit']; } @@ -226,7 +241,14 @@ public function getVcsReference(PackageInterface $package, string $path): ?strin */ protected function getInstallOperationAppendix(PackageInterface $package, string $path): string { - $realUrl = realpath($package->getDistUrl()); + $url = $package->getDistUrl(); + if (null === $url) { + throw new \RuntimeException('The package '.$package->getPrettyName().' has no dist url configured, cannot install.'); + } + $realUrl = realpath($url); + if (false === $realUrl) { + throw new \RuntimeException('Failed to realpath '.$url); + } if (realpath($path) === $realUrl) { return ': Source already present'; @@ -257,7 +279,7 @@ private function computeAllowedStrategies(array $transportOptions): array $allowedStrategies = [self::STRATEGY_SYMLINK, self::STRATEGY_MIRROR]; $mirrorPathRepos = Platform::getEnv('COMPOSER_MIRROR_PATH_REPOS'); - if ($mirrorPathRepos) { + if ((bool) $mirrorPathRepos) { $currentStrategy = self::STRATEGY_MIRROR; } diff --git a/vendor/composer/composer/src/Composer/Downloader/TransportException.php b/vendor/composer/composer/src/Composer/Downloader/TransportException.php index c91897c..a30842e 100644 --- a/vendor/composer/composer/src/Composer/Downloader/TransportException.php +++ b/vendor/composer/composer/src/Composer/Downloader/TransportException.php @@ -26,6 +26,11 @@ class TransportException extends \RuntimeException /** @var array */ protected $responseInfo = []; + public function __construct(string $message = "", int $code = 400, ?\Throwable $previous = null) + { + parent::__construct($message, $code, $previous); + } + /** * @param array $headers */ diff --git a/vendor/composer/composer/src/Composer/Downloader/ZipDownloader.php b/vendor/composer/composer/src/Composer/Downloader/ZipDownloader.php index 9d0f353..1904668 100644 --- a/vendor/composer/composer/src/Composer/Downloader/ZipDownloader.php +++ b/vendor/composer/composer/src/Composer/Downloader/ZipDownloader.php @@ -35,7 +35,7 @@ class ZipDownloader extends ArchiveDownloader private static $isWindows; /** @var ZipArchive|null */ - private $zipArchiveObject; // @phpstan-ignore-line helper property that is set via reflection for testing purposes + private $zipArchiveObject; // @phpstan-ignore property.onlyRead (helper property that is set via reflection for testing purposes) /** * @inheritDoc @@ -144,6 +144,10 @@ private function extractWithSystemUnzip(PackageInterface $package, string $file, throw $processError; } + if (str_contains($processError->getMessage(), 'zip bomb')) { + throw $processError; + } + if (!is_file($file)) { $io->writeError(' '.$processError->getMessage().''); $io->writeError(' This most likely is due to a custom installer plugin not handling the returned Promise from the downloader'); @@ -208,7 +212,27 @@ private function extractWithZipArchive(PackageInterface $package, string $file, } else { $retval = $zipArchive->open($file); } + if (true === $retval) { + $totalSize = 0; + $archiveSize = filesize($file); + $totalFiles = $zipArchive->count(); + if ($totalFiles > 0) { + for ($i = 0; $i < min($totalFiles, 5); $i++) { + $stat = $zipArchive->statIndex(random_int(0, $totalFiles - 1)); + if ($stat === false) { + continue; + } + $totalSize += $stat['size']; + if ($stat['size'] > $stat['comp_size'] * 200) { + throw new \RuntimeException('Invalid zip file with compression ratio >99% (possible zip bomb)'); + } + } + if ($archiveSize !== false && $totalSize > $archiveSize * 100 && $totalSize > 50*1024*1024) { + throw new \RuntimeException('Invalid zip file with compression ratio >99% (possible zip bomb)'); + } + } + $extractResult = $zipArchive->extractTo($path); if (true === $extractResult) { diff --git a/vendor/composer/composer/src/Composer/EventDispatcher/EventDispatcher.php b/vendor/composer/composer/src/Composer/EventDispatcher/EventDispatcher.php index b91b4e8..2d8af9e 100644 --- a/vendor/composer/composer/src/Composer/EventDispatcher/EventDispatcher.php +++ b/vendor/composer/composer/src/Composer/EventDispatcher/EventDispatcher.php @@ -90,7 +90,7 @@ public function __construct(PartialComposer $composer, IOInterface $io, ?Process */ public function setRunScripts(bool $runScripts = true): self { - $this->runScripts = (bool) $runScripts; + $this->runScripts = $runScripts; return $this; } @@ -194,13 +194,20 @@ protected function doDispatch(Event $event) $this->pushEvent($event); + $autoloadersBefore = spl_autoload_functions(); + try { $returnMax = 0; foreach ($listeners as $callable) { $return = 0; $this->ensureBinDirIsInPath(); - $formattedEventNameWithArgs = $event->getName() . ($event->getArguments() !== [] ? ' (' . implode(', ', $event->getArguments()) . ')' : ''); + $additionalArgs = $event->getArguments(); + if (is_string($callable) && str_contains($callable, '@no_additional_args')) { + $callable = Preg::replace('{ ?@no_additional_args}', '', $callable); + $additionalArgs = []; + } + $formattedEventNameWithArgs = $event->getName() . ($additionalArgs !== [] ? ' (' . implode(', ', $additionalArgs) . ')' : ''); if (!is_string($callable)) { if (!is_callable($callable)) { $className = is_object($callable[0]) ? get_class($callable[0]) : $callable[0]; @@ -218,7 +225,12 @@ protected function doDispatch(Event $event) $scriptName = $script[0]; unset($script[0]); - $args = array_merge($script, $event->getArguments()); + $index = array_search('@additional_args', $script, true); + if ($index !== false) { + $args = array_splice($script, $index, 0, $additionalArgs); + } else { + $args = array_merge($script, $additionalArgs); + } $flags = $event->getFlags(); if (isset($flags['script-alias-input'])) { $argsString = implode(' ', array_map(static function ($arg) { return ProcessExecutor::escape($arg); }, $script)); @@ -292,12 +304,12 @@ protected function doDispatch(Event $event) $app->add($cmd); $app->setDefaultCommand((string) $cmd->getName(), true); try { - $args = implode(' ', array_map(static function ($arg) { return ProcessExecutor::escape($arg); }, $event->getArguments())); + $args = implode(' ', array_map(static function ($arg) { return ProcessExecutor::escape($arg); }, $additionalArgs)); // reusing the output from $this->io is mostly needed for tests, but generally speaking // it does not hurt to keep the same stream as the current Application if ($this->io instanceof ConsoleIO) { $reflProp = new \ReflectionProperty($this->io, 'output'); - if (PHP_VERSION_ID < 80100) { + if (\PHP_VERSION_ID < 80100) { $reflProp->setAccessible(true); } $output = $reflProp->getValue($this->io); @@ -311,13 +323,17 @@ protected function doDispatch(Event $event) throw $e; } } else { - $args = implode(' ', array_map(['Composer\Util\ProcessExecutor', 'escape'], $event->getArguments())); + $args = implode(' ', array_map(['Composer\Util\ProcessExecutor', 'escape'], $additionalArgs)); // @putenv does not receive arguments if (strpos($callable, '@putenv ') === 0) { $exec = $callable; } else { - $exec = $callable . ($args === '' ? '' : ' '.$args); + if (str_contains($callable, '@additional_args')) { + $exec = str_replace('@additional_args', $args, $callable); + } else { + $exec = $callable . ($args === '' ? '' : ' '.$args); + } } if ($this->io->isVerbose()) { @@ -328,7 +344,7 @@ protected function doDispatch(Event $event) } $possibleLocalBinaries = $this->composer->getPackage()->getBinaries(); - if ($possibleLocalBinaries) { + if (count($possibleLocalBinaries) > 0) { foreach ($possibleLocalBinaries as $localExec) { if (Preg::isMatch('{\b'.preg_quote($callable).'$}', $localExec)) { $caller = BinaryInstaller::determineBinaryCaller($localExec); @@ -352,7 +368,7 @@ protected function doDispatch(Event $event) $pathAndArgs = substr($exec, 5); if (Platform::isWindows()) { $pathAndArgs = Preg::replaceCallback('{^\S+}', static function ($path) { - return str_replace('/', '\\', (string) $path[0]); + return str_replace('/', '\\', $path[0]); }, $pathAndArgs); } // match somename (not in quote, and not a qualified path) and if it is not a valid path from CWD then try to find it @@ -382,8 +398,6 @@ protected function doDispatch(Event $event) if (Platform::isWindows()) { $exec = Preg::replaceCallback('{^\S+}', static function ($path) { - assert(is_string($path[0])); - return str_replace('/', '\\', $path[0]); }, $exec); } @@ -411,6 +425,26 @@ protected function doDispatch(Event $event) } } finally { $this->popEvent(); + + $knownIdentifiers = []; + foreach ($autoloadersBefore as $key => $cb) { + $knownIdentifiers[$this->getCallbackIdentifier($cb)] = ['key' => $key, 'callback' => $cb]; + } + foreach (spl_autoload_functions() as $cb) { + // once we get to the first known autoloader, we can leave any appended autoloader without problems + if (isset($knownIdentifiers[$this->getCallbackIdentifier($cb)]) && $knownIdentifiers[$this->getCallbackIdentifier($cb)]['key'] === 0) { + break; + } + + // other newly appeared prepended autoloaders should be appended instead to ensure Composer loads its classes first + if ($cb instanceof ClassLoader) { + $cb->unregister(); + $cb->register(false); + } else { + spl_autoload_unregister($cb); + spl_autoload_register($cb); + } + } } return $returnMax; @@ -638,4 +672,23 @@ private function ensureBinDirIsInPath(): void } } } + + /** + * @param callable $cb DO NOT MOVE TO TYPE HINT as private autoload callbacks are not technically callable + */ + private function getCallbackIdentifier($cb): string + { + if (is_string($cb)) { + return 'fn:'.$cb; + } + if (is_object($cb)) { + return 'obj:'.spl_object_hash($cb); + } + if (is_array($cb)) { + return 'array:'.(is_string($cb[0]) ? $cb[0] : get_class($cb[0]) .'#'.spl_object_hash($cb[0])).'::'.$cb[1]; + } + + // not great but also do not want to break everything here + return 'unsupported'; + } } diff --git a/vendor/composer/composer/src/Composer/Factory.php b/vendor/composer/composer/src/Composer/Factory.php index 03a5fa2..3d6d583 100644 --- a/vendor/composer/composer/src/Composer/Factory.php +++ b/vendor/composer/composer/src/Composer/Factory.php @@ -216,29 +216,26 @@ public static function createConfig(?IOInterface $io = null, ?string $cwd = null } $config->setAuthConfigSource(new JsonConfigSource($file, true)); - // load COMPOSER_AUTH environment variable if set - if ($composerAuthEnv = Platform::getEnv('COMPOSER_AUTH')) { - $authData = json_decode($composerAuthEnv); - if (null === $authData) { - throw new \UnexpectedValueException('COMPOSER_AUTH environment variable is malformed, should be a valid JSON object'); - } else { - if ($io instanceof IOInterface) { - $io->writeError('Loading auth config from COMPOSER_AUTH', true, IOInterface::DEBUG); - } - self::validateJsonSchema($io, $authData, JsonFile::AUTH_SCHEMA, 'COMPOSER_AUTH'); - $authData = json_decode($composerAuthEnv, true); - if (null !== $authData) { - $config->merge(['config' => $authData], 'COMPOSER_AUTH'); - } - } - } + self::loadComposerAuthEnv($config, $io); return $config; } public static function getComposerFile(): string { - return trim((string) Platform::getEnv('COMPOSER')) ?: './composer.json'; + $env = Platform::getEnv('COMPOSER'); + if (is_string($env)) { + $env = trim($env); + if ('' !== $env) { + if (is_dir($env)) { + throw new \RuntimeException('The COMPOSER environment variable is set to '.$env.' which is a directory, this variable should point to a composer.json or be left unset.'); + } + + return $env; + } + } + + return './composer.json'; } public static function getLockFile(string $composerFile): string @@ -341,6 +338,9 @@ public function createComposer(IOInterface $io, $localConfig = null, $disablePlu } } + // make sure we load the auth env again over the local auth.json + composer.json config + self::loadComposerAuthEnv($config, $io); + $vendorDir = $config->get('vendor-dir'); // initialize composer @@ -678,10 +678,32 @@ public static function createHttpDownloader(IOInterface $io, Config $config, arr return $httpDownloader; } + private static function loadComposerAuthEnv(Config $config, ?IOInterface $io): void + { + $composerAuthEnv = Platform::getEnv('COMPOSER_AUTH'); + if (false === $composerAuthEnv || '' === $composerAuthEnv) { + return; + } + + $authData = json_decode($composerAuthEnv); + if (null === $authData) { + throw new \UnexpectedValueException('COMPOSER_AUTH environment variable is malformed, should be a valid JSON object'); + } + + if ($io instanceof IOInterface) { + $io->writeError('Loading auth config from COMPOSER_AUTH', true, IOInterface::DEBUG); + } + self::validateJsonSchema($io, $authData, JsonFile::AUTH_SCHEMA, 'COMPOSER_AUTH'); + $authData = json_decode($composerAuthEnv, true); + if (null !== $authData) { + $config->merge(['config' => $authData], 'COMPOSER_AUTH'); + } + } + private static function useXdg(): bool { foreach (array_keys($_SERVER) as $key) { - if (strpos($key, 'XDG_') === 0) { + if (strpos((string) $key, 'XDG_') === 0) { return true; } } diff --git a/vendor/composer/composer/src/Composer/IO/BaseIO.php b/vendor/composer/composer/src/Composer/IO/BaseIO.php index 710f5a1..55ac166 100644 --- a/vendor/composer/composer/src/Composer/IO/BaseIO.php +++ b/vendor/composer/composer/src/Composer/IO/BaseIO.php @@ -15,6 +15,7 @@ use Composer\Config; use Composer\Pcre\Preg; use Composer\Util\ProcessExecutor; +use Composer\Util\Silencer; use Psr\Log\LogLevel; abstract class BaseIO implements IOInterface @@ -175,50 +176,85 @@ public function loadConfiguration(Config $config) ProcessExecutor::setTimeout($config->get('process-timeout')); } + /** + * @param string|\Stringable $message + */ public function emergency($message, array $context = []): void { $this->log(LogLevel::EMERGENCY, $message, $context); } + /** + * @param string|\Stringable $message + */ public function alert($message, array $context = []): void { $this->log(LogLevel::ALERT, $message, $context); } + /** + * @param string|\Stringable $message + */ public function critical($message, array $context = []): void { $this->log(LogLevel::CRITICAL, $message, $context); } + /** + * @param string|\Stringable $message + */ public function error($message, array $context = []): void { $this->log(LogLevel::ERROR, $message, $context); } + /** + * @param string|\Stringable $message + */ public function warning($message, array $context = []): void { $this->log(LogLevel::WARNING, $message, $context); } + /** + * @param string|\Stringable $message + */ public function notice($message, array $context = []): void { $this->log(LogLevel::NOTICE, $message, $context); } + /** + * @param string|\Stringable $message + */ public function info($message, array $context = []): void { $this->log(LogLevel::INFO, $message, $context); } + /** + * @param string|\Stringable $message + */ public function debug($message, array $context = []): void { $this->log(LogLevel::DEBUG, $message, $context); } + /** + * @param mixed|LogLevel::* $level + * @param string|\Stringable $message + */ public function log($level, $message, array $context = []): void { $message = (string) $message; + if ($context !== []) { + $json = Silencer::call('json_encode', $context, JSON_INVALID_UTF8_IGNORE|JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE); + if ($json !== false) { + $message .= ' ' . $json; + } + } + if (in_array($level, [LogLevel::EMERGENCY, LogLevel::ALERT, LogLevel::CRITICAL, LogLevel::ERROR])) { $this->writeError(''.$message.''); } elseif ($level === LogLevel::WARNING) { diff --git a/vendor/composer/composer/src/Composer/IO/BufferIO.php b/vendor/composer/composer/src/Composer/IO/BufferIO.php index 0404287..6cf962b 100644 --- a/vendor/composer/composer/src/Composer/IO/BufferIO.php +++ b/vendor/composer/composer/src/Composer/IO/BufferIO.php @@ -14,6 +14,8 @@ use Composer\Pcre\Preg; use Symfony\Component\Console\Helper\QuestionHelper; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\StreamOutput; use Symfony\Component\Console\Formatter\OutputFormatterInterface; use Symfony\Component\Console\Input\StreamableInputInterface; @@ -25,17 +27,16 @@ */ class BufferIO extends ConsoleIO { - /** @var StringInput */ - protected $input; - /** @var StreamOutput */ - protected $output; - public function __construct(string $input = '', int $verbosity = StreamOutput::VERBOSITY_NORMAL, ?OutputFormatterInterface $formatter = null) { $input = new StringInput($input); $input->setInteractive(false); - $output = new StreamOutput(fopen('php://memory', 'rw'), $verbosity, $formatter ? $formatter->isDecorated() : false, $formatter); + $stream = fopen('php://memory', 'rw'); + if ($stream === false) { + throw new \RuntimeException('Unable to open memory output stream'); + } + $output = new StreamOutput($stream, $verbosity, $formatter !== null ? $formatter->isDecorated() : false, $formatter); parent::__construct($input, $output, new HelperSet([ new QuestionHelper(), @@ -47,13 +48,12 @@ public function __construct(string $input = '', int $verbosity = StreamOutput::V */ public function getOutput(): string { + assert($this->output instanceof StreamOutput); fseek($this->output->getStream(), 0); - $output = stream_get_contents($this->output->getStream()); + $output = (string) stream_get_contents($this->output->getStream()); $output = Preg::replaceCallback("{(?<=^|\n|\x08)(.+?)(\x08+)}", static function ($matches): string { - assert(is_string($matches[1])); - assert(is_string($matches[2])); $pre = strip_tags($matches[1]); if (strlen($pre) === strlen($matches[2])) { @@ -85,11 +85,14 @@ public function setUserInputs(array $inputs): void /** * @param string[] $inputs * - * @return false|resource stream + * @return resource stream */ private function createStream(array $inputs) { $stream = fopen('php://memory', 'r+'); + if ($stream === false) { + throw new \RuntimeException('Unable to open memory output stream'); + } foreach ($inputs as $input) { fwrite($stream, $input.PHP_EOL); diff --git a/vendor/composer/composer/src/Composer/Installer.php b/vendor/composer/composer/src/Composer/Installer.php index fe50c8f..2502a7d 100644 --- a/vendor/composer/composer/src/Composer/Installer.php +++ b/vendor/composer/composer/src/Composer/Installer.php @@ -80,6 +80,8 @@ class Installer // used/declared in SolverProblemsException, carried over here for completeness public const ERROR_DEPENDENCY_RESOLUTION_FAILED = 2; public const ERROR_AUDIT_FAILED = 5; + // technically exceptions are thrown with various status codes >400, but the process exit code is normalized to 100 + public const ERROR_TRANSPORT_EXCEPTION = 100; /** * @var IOInterface @@ -176,6 +178,10 @@ class Installer protected $errorOnAudit = false; /** @var Auditor::FORMAT_* */ protected $auditFormat = Auditor::FORMAT_SUMMARY; + /** @var list */ + private $ignoredTypes = ['php-ext', 'php-ext-zend']; + /** @var list|null */ + private $allowedTypes = null; /** @var bool */ protected $updateMirrors = false; @@ -492,7 +498,7 @@ protected function doUpdate(InstalledRepositoryInterface $localRepo, bool $doIns $request->setUpdateAllowList($this->updateAllowList, $this->updateAllowTransitiveDependencies); } - $pool = $repositorySet->createPool($request, $this->io, $this->eventDispatcher, $this->createPoolOptimizer($policy)); + $pool = $repositorySet->createPool($request, $this->io, $this->eventDispatcher, $this->createPoolOptimizer($policy), $this->ignoredTypes, $this->allowedTypes); $this->io->writeError('Updating dependencies'); @@ -532,10 +538,7 @@ protected function doUpdate(InstalledRepositoryInterface $localRepo, bool $doIns return $exitCode; } - // exists as of composer/semver 3.3.0 - if (method_exists('Composer\Semver\CompilingMatcher', 'clear')) { // @phpstan-ignore-line - \Composer\Semver\CompilingMatcher::clear(); - } + \Composer\Semver\CompilingMatcher::clear(); // write lock $platformReqs = $this->extractPlatformRequirements($this->package->getRequires()); @@ -739,18 +742,33 @@ protected function doInstall(InstalledRepositoryInterface $localRepo, bool $alre if ($missingRequirementInfo !== []) { $this->io->writeError($missingRequirementInfo); - return self::ERROR_LOCK_FILE_INVALID; + if (!$this->config->get('allow-missing-requirements')) { + return self::ERROR_LOCK_FILE_INVALID; + } } foreach ($lockedRepository->getPackages() as $package) { $request->fixLockedPackage($package); } + $rootRequires = $this->package->getRequires(); + if ($this->devMode) { + $rootRequires = array_merge($rootRequires, $this->package->getDevRequires()); + } + foreach ($rootRequires as $link) { + if (PlatformRepository::isPlatformPackage($link->getTarget())) { + $request->requireName($link->getTarget(), $link->getConstraint()); + } + } + foreach ($this->locker->getPlatformRequirements($this->devMode) as $link) { - $request->requireName($link->getTarget(), $link->getConstraint()); + if (!isset($rootRequires[$link->getTarget()])) { + $request->requireName($link->getTarget(), $link->getConstraint()); + } } + unset($rootRequires, $link); - $pool = $repositorySet->createPool($request, $this->io, $this->eventDispatcher); + $pool = $repositorySet->createPool($request, $this->io, $this->eventDispatcher, null, $this->ignoredTypes, $this->allowedTypes); // solve dependencies $solver = new Solver($policy, $pool, $this->io); @@ -894,7 +912,7 @@ private function createRepositorySet(bool $forUpdate, PlatformRepository $platfo $this->fixedRootPackage->setRequires([]); $this->fixedRootPackage->setDevRequires([]); - $stabilityFlags[$this->package->getName()] = BasePackage::$stabilities[VersionParser::parseStability($this->package->getVersion())]; + $stabilityFlags[$this->package->getName()] = BasePackage::STABILITIES[VersionParser::parseStability($this->package->getVersion())]; $repositorySet = new RepositorySet($minimumStability, $stabilityFlags, $rootAliases, $this->package->getReferences(), $rootRequires, $this->temporaryConstraints); $repositorySet->addRepository(new RootPackageRepository($this->fixedRootPackage)); @@ -1103,6 +1121,32 @@ public static function create(IOInterface $io, Composer $composer): self ); } + /** + * Packages of those types are ignored, by default php-ext and php-ext-zend are ignored + * + * @param list $types + * @return $this + */ + public function setIgnoredTypes(array $types): self + { + $this->ignoredTypes = $types; + + return $this; + } + + /** + * Only packages of those types are allowed if set to non-null + * + * @param list|null $types + * @return $this + */ + public function setAllowedTypes(?array $types): self + { + $this->allowedTypes = $types; + + return $this; + } + /** * @return $this */ @@ -1131,7 +1175,7 @@ public function setTemporaryConstraints(array $constraints): self */ public function setDryRun(bool $dryRun = true): self { - $this->dryRun = (bool) $dryRun; + $this->dryRun = $dryRun; return $this; } @@ -1163,7 +1207,7 @@ public function setDownloadOnly(bool $downloadOnly = true): self */ public function setPreferSource(bool $preferSource = true): self { - $this->preferSource = (bool) $preferSource; + $this->preferSource = $preferSource; return $this; } @@ -1175,7 +1219,7 @@ public function setPreferSource(bool $preferSource = true): self */ public function setPreferDist(bool $preferDist = true): self { - $this->preferDist = (bool) $preferDist; + $this->preferDist = $preferDist; return $this; } @@ -1187,7 +1231,7 @@ public function setPreferDist(bool $preferDist = true): self */ public function setOptimizeAutoloader(bool $optimizeAutoloader): self { - $this->optimizeAutoloader = (bool) $optimizeAutoloader; + $this->optimizeAutoloader = $optimizeAutoloader; if (!$this->optimizeAutoloader) { // Force classMapAuthoritative off when not optimizing the // autoloader @@ -1205,7 +1249,7 @@ public function setOptimizeAutoloader(bool $optimizeAutoloader): self */ public function setClassMapAuthoritative(bool $classMapAuthoritative): self { - $this->classMapAuthoritative = (bool) $classMapAuthoritative; + $this->classMapAuthoritative = $classMapAuthoritative; if ($this->classMapAuthoritative) { // Force optimizeAutoloader when classmap is authoritative $this->setOptimizeAutoloader(true); @@ -1234,7 +1278,7 @@ public function setApcuAutoloader(bool $apcuAutoloader, ?string $apcuAutoloaderP */ public function setUpdate(bool $update): self { - $this->update = (bool) $update; + $this->update = $update; return $this; } @@ -1246,7 +1290,7 @@ public function setUpdate(bool $update): self */ public function setInstall(bool $install): self { - $this->install = (bool) $install; + $this->install = $install; return $this; } @@ -1258,7 +1302,7 @@ public function setInstall(bool $install): self */ public function setDevMode(bool $devMode = true): self { - $this->devMode = (bool) $devMode; + $this->devMode = $devMode; return $this; } @@ -1272,7 +1316,7 @@ public function setDevMode(bool $devMode = true): self */ public function setDumpAutoloader(bool $dumpAutoloader = true): self { - $this->dumpAutoloader = (bool) $dumpAutoloader; + $this->dumpAutoloader = $dumpAutoloader; return $this; } @@ -1287,7 +1331,7 @@ public function setDumpAutoloader(bool $dumpAutoloader = true): self */ public function setRunScripts(bool $runScripts = true): self { - $this->runScripts = (bool) $runScripts; + $this->runScripts = $runScripts; return $this; } @@ -1311,7 +1355,7 @@ public function setConfig(Config $config): self */ public function setVerbose(bool $verbose = true): self { - $this->verbose = (bool) $verbose; + $this->verbose = $verbose; return $this; } diff --git a/vendor/composer/composer/src/Composer/Installer/BinaryInstaller.php b/vendor/composer/composer/src/Composer/Installer/BinaryInstaller.php index ba50fe1..54ecd94 100644 --- a/vendor/composer/composer/src/Composer/Installer/BinaryInstaller.php +++ b/vendor/composer/composer/src/Composer/Installer/BinaryInstaller.php @@ -213,7 +213,7 @@ protected function generateUnixyProxyCode(string $bin, string $link): string $binDir = ProcessExecutor::escape(dirname($binPath)); $binFile = basename($binPath); - $binContents = file_get_contents($bin); + $binContents = (string) file_get_contents($bin, false, null, 0, 500); // For php files, we generate a PHP proxy instead of a shell one, // which allows calling the proxy with a custom php process if (Preg::isMatch('{^(#!.*\r?\n)?[\r\n\t ]*<\?php}', $binContents, $match)) { @@ -224,8 +224,13 @@ protected function generateUnixyProxyCode(string $bin, string $link): string $globalsCode = '$GLOBALS[\'_composer_bin_dir\'] = __DIR__;'."\n"; $phpunitHack1 = $phpunitHack2 = ''; // Don't expose autoload path when vendor dir was not set in custom installers - if ($this->vendorDir) { - $globalsCode .= '$GLOBALS[\'_composer_autoload_path\'] = ' . $this->filesystem->findShortestPathCode($link, $this->vendorDir . '/autoload.php', false, true).";\n"; + if ($this->vendorDir !== null) { + // ensure comparisons work accurately if the CWD is a symlink, as $link is realpath'd already + $vendorDirReal = realpath($this->vendorDir); + if ($vendorDirReal === false) { + $vendorDirReal = $this->vendorDir; + } + $globalsCode .= '$GLOBALS[\'_composer_autoload_path\'] = ' . $this->filesystem->findShortestPathCode($link, $vendorDirReal . '/autoload.php', false, true).";\n"; } // Add workaround for PHPUnit process isolation if ($this->filesystem->normalizePath($bin) === $this->filesystem->normalizePath($this->vendorDir.'/phpunit/phpunit/phpunit')) { @@ -237,7 +242,7 @@ protected function generateUnixyProxyCode(string $bin, string $link): string $data = str_replace(\'__DIR__\', var_export(dirname($this->realpath), true), $data); $data = str_replace(\'__FILE__\', var_export($this->realpath, true), $data);'; } - if (trim((string) $match[0]) !== ' */ + /** @var list */ private $installers = []; /** @var array */ private $cache = []; @@ -180,7 +180,7 @@ public function ensureBinariesPresence(PackageInterface $package): void */ public function execute(InstalledRepositoryInterface $repo, array $operations, bool $devMode = true, bool $runScripts = true, bool $downloadOnly = false): void { - /** @var array> */ + /** @var array> $cleanupPromises */ $cleanupPromises = []; $signalHandler = SignalHandler::create([SignalHandler::SIGINT, SignalHandler::SIGTERM, SignalHandler::SIGHUP], function (string $signal, SignalHandler $handler) use (&$cleanupPromises) { @@ -197,25 +197,28 @@ public function execute(InstalledRepositoryInterface $repo, array $operations, b foreach ($operations as $index => $operation) { if ($operation instanceof UpdateOperation || $operation instanceof InstallOperation) { $package = $operation instanceof UpdateOperation ? $operation->getTargetPackage() : $operation->getPackage(); - if ($package->getType() === 'composer-plugin' && ($extra = $package->getExtra()) && isset($extra['plugin-modifies-downloads']) && $extra['plugin-modifies-downloads'] === true) { - if ($batch) { - $batches[] = $batch; + if ($package->getType() === 'composer-plugin') { + $extra = $package->getExtra(); + if (isset($extra['plugin-modifies-downloads']) && $extra['plugin-modifies-downloads'] === true) { + if (count($batch) > 0) { + $batches[] = $batch; + } + $batches[] = [$index => $operation]; + $batch = []; + + continue; } - $batches[] = [$index => $operation]; - $batch = []; - - continue; } } $batch[$index] = $operation; } - if ($batch) { + if (count($batch) > 0) { $batches[] = $batch; } - foreach ($batches as $batch) { - $this->downloadAndExecuteBatch($repo, $batch, $cleanupPromises, $devMode, $runScripts, $downloadOnly, $operations); + foreach ($batches as $batchToExecute) { + $this->downloadAndExecuteBatch($repo, $batchToExecute, $cleanupPromises, $devMode, $runScripts, $downloadOnly, $operations); } } catch (\Exception $e) { $this->runCleanup($cleanupPromises); @@ -248,7 +251,7 @@ private function downloadAndExecuteBatch(InstalledRepositoryInterface $repo, arr $opType = $operation->getOperationType(); // ignoring alias ops as they don't need to execute anything at this stage - if (!in_array($opType, ['update', 'install', 'uninstall'])) { + if (!in_array($opType, ['update', 'install', 'uninstall'], true)) { continue; } @@ -266,7 +269,7 @@ private function downloadAndExecuteBatch(InstalledRepositoryInterface $repo, arr $cleanupPromises[$index] = static function () use ($opType, $installer, $package, $initialPackage): ?PromiseInterface { // avoid calling cleanup if the download was not even initialized for a package // as without installation source configured nothing will work - if (!$package->getInstallationSource()) { + if (null === $package->getInstallationSource()) { return \React\Promise\resolve(null); } @@ -282,7 +285,7 @@ private function downloadAndExecuteBatch(InstalledRepositoryInterface $repo, arr } // execute all downloads first - if (count($promises)) { + if (count($promises) > 0) { $this->waitOnPromises($promises); } @@ -299,7 +302,7 @@ private function downloadAndExecuteBatch(InstalledRepositoryInterface $repo, arr if ($operation instanceof InstallOperation || $operation instanceof UpdateOperation) { $package = $operation instanceof UpdateOperation ? $operation->getTargetPackage() : $operation->getPackage(); if ($package->getType() === 'composer-plugin' || $package->getType() === 'composer-installer') { - if ($batch) { + if (count($batch) > 0) { $batches[] = $batch; } $batches[] = [$index => $operation]; @@ -311,12 +314,12 @@ private function downloadAndExecuteBatch(InstalledRepositoryInterface $repo, arr $batch[$index] = $operation; } - if ($batch) { + if (count($batch) > 0) { $batches[] = $batch; } - foreach ($batches as $batch) { - $this->executeBatch($repo, $batch, $cleanupPromises, $devMode, $runScripts, $allOperations); + foreach ($batches as $batchToExecute) { + $this->executeBatch($repo, $batchToExecute, $cleanupPromises, $devMode, $runScripts, $allOperations); } } @@ -334,7 +337,7 @@ private function executeBatch(InstalledRepositoryInterface $repo, array $operati $opType = $operation->getOperationType(); // ignoring alias ops as they don't need to execute anything - if (!in_array($opType, ['update', 'install', 'uninstall'])) { + if (!in_array($opType, ['update', 'install', 'uninstall'], true)) { // output alias ops in debug verbosity as they have no output otherwise if ($this->io->isDebug()) { $this->io->writeError(' - ' . $operation->show(false)); @@ -360,9 +363,9 @@ private function executeBatch(InstalledRepositoryInterface $repo, array $operati 'install' => PackageEvents::PRE_PACKAGE_INSTALL, 'update' => PackageEvents::PRE_PACKAGE_UPDATE, 'uninstall' => PackageEvents::PRE_PACKAGE_UNINSTALL, - ][$opType] ?? null; + ][$opType]; - if (null !== $eventName && $runScripts && $this->eventDispatcher) { + if ($runScripts && $this->eventDispatcher !== null) { $this->eventDispatcher->dispatchPackageEvent($eventName, $devMode, $repo, $allOperations, $operation); } @@ -389,9 +392,9 @@ private function executeBatch(InstalledRepositoryInterface $repo, array $operati 'install' => PackageEvents::POST_PACKAGE_INSTALL, 'update' => PackageEvents::POST_PACKAGE_UPDATE, 'uninstall' => PackageEvents::POST_PACKAGE_UNINSTALL, - ][$opType] ?? null; + ][$opType]; - if (null !== $eventName && $runScripts && $dispatcher) { + if ($runScripts && $dispatcher !== null) { $postExecCallbacks[] = static function () use ($dispatcher, $eventName, $devMode, $repo, $allOperations, $operation): void { $dispatcher->dispatchPackageEvent($eventName, $devMode, $repo, $allOperations, $operation); }; @@ -401,7 +404,7 @@ private function executeBatch(InstalledRepositoryInterface $repo, array $operati } // execute all prepare => installs/updates/removes => cleanup steps - if (count($promises)) { + if (count($promises) > 0) { $this->waitOnPromises($promises); } @@ -421,14 +424,14 @@ private function waitOnPromises(array $promises): void if ( $this->outputProgress && $this->io instanceof ConsoleIO - && !Platform::getEnv('CI') + && !((bool) Platform::getEnv('CI')) && !$this->io->isDebug() && count($promises) > 1 ) { $progress = $this->io->getProgressBar(); } $this->loop->wait($promises, $progress); - if ($progress) { + if ($progress !== null) { $progress->clear(); // ProgressBar in non-decorated output does not output a final line-break and clear() does nothing if (!$this->io->isDecorated()) { @@ -573,7 +576,7 @@ public function notifyInstalls(IOInterface $io): void try { foreach ($this->notifiablePackages as $repoUrl => $packages) { // non-batch API, deprecated - if (strpos($repoUrl, '%package%')) { + if (str_contains($repoUrl, '%package%')) { foreach ($packages as $package) { $url = str_replace('%package%', $package->getPrettyName(), $repoUrl); @@ -635,7 +638,7 @@ public function notifyInstalls(IOInterface $io): void private function markForNotification(PackageInterface $package): void { - if ($package->getNotificationUrl()) { + if ($package->getNotificationUrl() !== null) { $this->notifiablePackages[$package->getNotificationUrl()][$package->getName()] = $package; } } @@ -663,7 +666,7 @@ private function runCleanup(array $cleanupPromises): void }); } - if (!empty($promises)) { + if (count($promises) > 0) { $this->loop->wait($promises); } } diff --git a/vendor/composer/composer/src/Composer/Json/JsonFile.php b/vendor/composer/composer/src/Composer/Json/JsonFile.php index 7f9814d..02ce519 100644 --- a/vendor/composer/composer/src/Composer/Json/JsonFile.php +++ b/vendor/composer/composer/src/Composer/Json/JsonFile.php @@ -32,6 +32,7 @@ class JsonFile public const LAX_SCHEMA = 1; public const STRICT_SCHEMA = 2; public const AUTH_SCHEMA = 3; + public const LOCK_SCHEMA = 4; /** @deprecated Use \JSON_UNESCAPED_SLASHES */ public const JSON_UNESCAPED_SLASHES = 64; @@ -41,6 +42,7 @@ class JsonFile public const JSON_UNESCAPED_UNICODE = 256; public const COMPOSER_SCHEMA_PATH = __DIR__ . '/../../../res/composer-schema.json'; + public const LOCK_SCHEMA_PATH = __DIR__ . '/../../../res/composer-lock-schema.json'; public const INDENT_DEFAULT = ' '; @@ -228,8 +230,12 @@ public static function validateJsonSchema(string $source, $data, int $schema, ?s { $isComposerSchemaFile = false; if (null === $schemaFile) { - $isComposerSchemaFile = true; - $schemaFile = self::COMPOSER_SCHEMA_PATH; + if ($schema === self::LOCK_SCHEMA) { + $schemaFile = self::LOCK_SCHEMA_PATH; + } else { + $isComposerSchemaFile = true; + $schemaFile = self::COMPOSER_SCHEMA_PATH; + } } // Prepend with file:// only when not using a special schema already (e.g. in the phar) @@ -284,7 +290,7 @@ public static function encode($data, int $options = 448, string $indent = self:: return Preg::replaceCallback( '#^ {4,}#m', static function ($match) use ($indent): string { - return str_repeat($indent, (int)(strlen($match[0] ?? '') / 4)); + return str_repeat($indent, (int)(strlen($match[0]) / 4)); }, $json ); diff --git a/vendor/composer/composer/src/Composer/Json/JsonFormatter.php b/vendor/composer/composer/src/Composer/Json/JsonFormatter.php index 0063656..fa1a3c5 100644 --- a/vendor/composer/composer/src/Composer/Json/JsonFormatter.php +++ b/vendor/composer/composer/src/Composer/Json/JsonFormatter.php @@ -67,9 +67,7 @@ public static function format(string $json, bool $unescapeUnicode, bool $unescap if ($unescapeUnicode && function_exists('mb_convert_encoding')) { // https://stackoverflow.com/questions/2934563/how-to-decode-unicode-escape-sequences-like-u00ed-to-proper-utf-8-encoded-cha - $buffer = Preg::replaceCallback('/(\\\\+)u([0-9a-f]{4})/i', static function ($match) { - assert(is_string($match[1])); - assert(is_string($match[2])); + $buffer = Preg::replaceCallback('/(\\\\+)u([0-9a-f]{4})/i', static function ($match): string { $l = strlen($match[1]); if ($l % 2) { diff --git a/vendor/composer/composer/src/Composer/Json/JsonManipulator.php b/vendor/composer/composer/src/Composer/Json/JsonManipulator.php index 8d67596..c6c5eb5 100644 --- a/vendor/composer/composer/src/Composer/Json/JsonManipulator.php +++ b/vendor/composer/composer/src/Composer/Json/JsonManipulator.php @@ -214,6 +214,14 @@ public function removeProperty(string $name): bool return $this->removeSubNode('scripts', substr($name, 8)); } + if (strpos($name, 'autoload.') === 0) { + return $this->removeSubNode('autoload', substr($name, 9)); + } + + if (strpos($name, 'autoload-dev.') === 0) { + return $this->removeSubNode('autoload-dev', substr($name, 13)); + } + return $this->removeMainKey($name); } @@ -416,6 +424,9 @@ public function removeSubNode(string $mainNode, string $name): bool if ($subName !== null) { $curVal = json_decode($children, true); unset($curVal[$name][$subName]); + if ($curVal[$name] === []) { + $curVal[$name] = new \ArrayObject(); + } $this->addSubNode($mainNode, $name, $curVal[$name]); } @@ -427,7 +438,10 @@ public function removeSubNode(string $mainNode, string $name): bool if ($subName !== null) { $curVal = json_decode($matches['content'], true); unset($curVal[$name][$subName]); - $childrenClean = $this->format($curVal); + if ($curVal[$name] === []) { + $curVal[$name] = new \ArrayObject(); + } + $childrenClean = $this->format($curVal, 0, true); } return $matches['start'] . $childrenClean . $matches['end']; @@ -534,12 +548,19 @@ public function removeMainKeyIfEmpty(string $key): bool /** * @param mixed $data */ - public function format($data, int $depth = 0): string + public function format($data, int $depth = 0, bool $wasObject = false): string { + if ($data instanceof \stdClass || $data instanceof \ArrayObject) { + $data = (array) $data; + $wasObject = true; + } + if (is_array($data)) { - reset($data); + if (\count($data) === 0) { + return $wasObject ? '{' . $this->newline . str_repeat($this->indent, $depth + 1) . '}' : '[]'; + } - if (is_numeric(key($data))) { + if (array_is_list($data)) { foreach ($data as $key => $val) { $data[$key] = $this->format($val, $depth + 1); } @@ -550,7 +571,7 @@ public function format($data, int $depth = 0): string $out = '{' . $this->newline; $elems = []; foreach ($data as $key => $val) { - $elems[] = str_repeat($this->indent, $depth + 2) . JsonFile::encode($key). ': '.$this->format($val, $depth + 1); + $elems[] = str_repeat($this->indent, $depth + 2) . JsonFile::encode((string) $key). ': '.$this->format($val, $depth + 1); } return $out . implode(','.$this->newline, $elems) . $this->newline . str_repeat($this->indent, $depth + 1) . '}'; diff --git a/vendor/composer/composer/src/Composer/PHPStan/ConfigReturnTypeExtension.php b/vendor/composer/composer/src/Composer/PHPStan/ConfigReturnTypeExtension.php index e7ff6e5..88cd635 100644 --- a/vendor/composer/composer/src/Composer/PHPStan/ConfigReturnTypeExtension.php +++ b/vendor/composer/composer/src/Composer/PHPStan/ConfigReturnTypeExtension.php @@ -61,28 +61,26 @@ public function isMethodSupported(MethodReflection $methodReflection): bool return strtolower($methodReflection->getName()) === 'get'; } - public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope): Type + public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope): ?Type { $args = $methodCall->getArgs(); - $defaultReturn = ParametersAcceptorSelector::selectSingle($methodReflection->getVariants())->getReturnType(); - if (count($args) < 1) { - return $defaultReturn; + return null; } $keyType = $scope->getType($args[0]->value); - if (method_exists($keyType, 'getConstantStrings')) { // @phpstan-ignore-line - depending on PHPStan version, this method will always exist, or not. + if (method_exists($keyType, 'getConstantStrings')) { // @phpstan-ignore function.alreadyNarrowedType (- depending on PHPStan version, this method will always exist, or not.) $strings = $keyType->getConstantStrings(); } else { // for compat with old phpstan versions, we use a deprecated phpstan method. - $strings = TypeUtils::getConstantStrings($keyType); // @phpstan-ignore-line ignore deprecation + $strings = TypeUtils::getConstantStrings($keyType); // @phpstan-ignore staticMethod.deprecated (ignore deprecation) } if ($strings !== []) { $types = []; foreach($strings as $string) { if (!isset($this->properties[$string->getValue()])) { - return $defaultReturn; + return null; } $types[] = $this->properties[$string->getValue()]; } @@ -90,7 +88,7 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method return TypeCombinator::union(...$types); } - return $defaultReturn; + return null; } /** diff --git a/vendor/composer/composer/src/Composer/Package/AliasPackage.php b/vendor/composer/composer/src/Composer/Package/AliasPackage.php index 75d3158..932ea36 100644 --- a/vendor/composer/composer/src/Composer/Package/AliasPackage.php +++ b/vendor/composer/composer/src/Composer/Package/AliasPackage.php @@ -351,6 +351,11 @@ public function getIncludePaths(): array return $this->aliasOf->getIncludePaths(); } + public function getPhpExt(): ?array + { + return $this->aliasOf->getPhpExt(); + } + public function getReleaseDate(): ?\DateTimeInterface { return $this->aliasOf->getReleaseDate(); diff --git a/vendor/composer/composer/src/Composer/Package/Archiver/ArchivableFilesFinder.php b/vendor/composer/composer/src/Composer/Package/Archiver/ArchivableFilesFinder.php index b2b6b87..2cf7ffc 100644 --- a/vendor/composer/composer/src/Composer/Package/Archiver/ArchivableFilesFinder.php +++ b/vendor/composer/composer/src/Composer/Package/Archiver/ArchivableFilesFinder.php @@ -47,7 +47,11 @@ public function __construct(string $sources, array $excludes, bool $ignoreFilter { $fs = new Filesystem(); - $sources = $fs->normalizePath(realpath($sources)); + $sourcesRealPath = realpath($sources); + if ($sourcesRealPath === false) { + throw new \RuntimeException('Could not realpath() the source directory "'.$sources.'"'); + } + $sources = $fs->normalizePath($sourcesRealPath); if ($ignoreFilters) { $filters = []; @@ -61,14 +65,18 @@ public function __construct(string $sources, array $excludes, bool $ignoreFilter $this->finder = new Finder(); $filter = static function (\SplFileInfo $file) use ($sources, $filters, $fs): bool { - if ($file->isLink() && ($file->getRealPath() === false || strpos($file->getRealPath(), $sources) !== 0)) { + $realpath = $file->getRealPath(); + if ($realpath === false) { + return false; + } + if ($file->isLink() && strpos($realpath, $sources) !== 0) { return false; } $relativePath = Preg::replace( '#^'.preg_quote($sources, '#').'#', '', - $fs->normalizePath($file->getRealPath()) + $fs->normalizePath($realpath) ); $exclude = false; @@ -79,10 +87,6 @@ public function __construct(string $sources, array $excludes, bool $ignoreFilter return !$exclude; }; - if (method_exists($filter, 'bindTo')) { - $filter = $filter->bindTo(null); - } - $this->finder ->in($sources) ->filter($filter) diff --git a/vendor/composer/composer/src/Composer/Package/Archiver/ArchiveManager.php b/vendor/composer/composer/src/Composer/Package/Archiver/ArchiveManager.php index 6efa479..77c3ebe 100644 --- a/vendor/composer/composer/src/Composer/Package/Archiver/ArchiveManager.php +++ b/vendor/composer/composer/src/Composer/Package/Archiver/ArchiveManager.php @@ -96,10 +96,12 @@ public function getPackageFilenameParts(CompletePackageInterface $package): arra $sourceReference = $package->getSourceReference(); if (null !== $sourceReference) { - $parts['source_reference'] = substr(sha1($sourceReference), 0, 6); + $parts['source_reference'] = substr(hash('sha1', $sourceReference), 0, 6); } - $parts = array_filter($parts); + $parts = array_filter($parts, function (?string $part) { + return $part !== null; + }); foreach ($parts as $key => $part) { $parts[$key] = str_replace('/', '-', $part); } @@ -169,7 +171,7 @@ public function archive(CompletePackageInterface $package, string $format, strin $sourcePath = realpath('.'); } else { // Directory used to download the sources - $sourcePath = sys_get_temp_dir().'/composer_archive'.uniqid(); + $sourcePath = sys_get_temp_dir().'/composer_archive'.bin2hex(random_bytes(5)); $filesystem->ensureDirectoryExists($sourcePath); try { @@ -214,7 +216,7 @@ public function archive(CompletePackageInterface $package, string $format, strin } // Create the archive - $tempTarget = sys_get_temp_dir().'/composer_archive'.uniqid().'.'.$format; + $tempTarget = sys_get_temp_dir().'/composer_archive'.bin2hex(random_bytes(5)).'.'.$format; $filesystem->ensureDirectoryExists(dirname($tempTarget)); $archivePath = $usableArchiver->archive( diff --git a/vendor/composer/composer/src/Composer/Package/BasePackage.php b/vendor/composer/composer/src/Composer/Package/BasePackage.php index d6d37d3..764fdb4 100644 --- a/vendor/composer/composer/src/Composer/Package/BasePackage.php +++ b/vendor/composer/composer/src/Composer/Package/BasePackage.php @@ -40,8 +40,7 @@ abstract class BasePackage implements PackageInterface public const STABILITY_ALPHA = 15; public const STABILITY_DEV = 20; - /** @var array */ - public static $stabilities = [ + public const STABILITIES = [ 'stable' => self::STABILITY_STABLE, 'RC' => self::STABILITY_RC, 'beta' => self::STABILITY_BETA, @@ -49,6 +48,14 @@ abstract class BasePackage implements PackageInterface 'dev' => self::STABILITY_DEV, ]; + /** + * @deprecated + * @readonly + * @var array, self::STABILITY_*> + * @phpstan-ignore property.readOnlyByPhpDocDefaultValue + */ + public static $stabilities = self::STABILITIES; + /** * READ-ONLY: The package id, public for fast access in dependency solver * @var int @@ -234,7 +241,7 @@ public function getFullPrettyVersion(bool $truncate = true, int $displayMode = P */ public function getStabilityPriority(): int { - return self::$stabilities[$this->getStability()]; + return self::STABILITIES[$this->getStability()]; } public function __clone() diff --git a/vendor/composer/composer/src/Composer/Package/Comparer/Comparer.php b/vendor/composer/composer/src/Composer/Package/Comparer/Comparer.php index 1fd79b8..70a7a28 100644 --- a/vendor/composer/composer/src/Composer/Package/Comparer/Comparer.php +++ b/vendor/composer/composer/src/Composer/Package/Comparer/Comparer.php @@ -136,7 +136,7 @@ private function doTree(string $dir, array &$array) return false; } } elseif (is_file($dir.'/'.$file) && filesize($dir.'/'.$file)) { - $array[$dir][$file] = md5_file($dir.'/'.$file); + $array[$dir][$file] = hash_file(\PHP_VERSION_ID > 80100 ? 'xxh3' : 'sha1', $dir.'/'.$file); } } } diff --git a/vendor/composer/composer/src/Composer/Package/Dumper/ArrayDumper.php b/vendor/composer/composer/src/Composer/Package/Dumper/ArrayDumper.php index f713fbe..046ba66 100644 --- a/vendor/composer/composer/src/Composer/Package/Dumper/ArrayDumper.php +++ b/vendor/composer/composer/src/Composer/Package/Dumper/ArrayDumper.php @@ -44,11 +44,11 @@ public function dump(PackageInterface $package): array $data['version'] = $package->getPrettyVersion(); $data['version_normalized'] = $package->getVersion(); - if ($package->getTargetDir()) { + if ($package->getTargetDir() !== null) { $data['target-dir'] = $package->getTargetDir(); } - if ($package->getSourceType()) { + if ($package->getSourceType() !== null) { $data['source']['type'] = $package->getSourceType(); $data['source']['url'] = $package->getSourceUrl(); if (null !== ($value = $package->getSourceReference())) { @@ -59,7 +59,7 @@ public function dump(PackageInterface $package): array } } - if ($package->getDistType()) { + if ($package->getDistType() !== null) { $data['dist']['type'] = $package->getDistType(); $data['dist']['url'] = $package->getDistUrl(); if (null !== ($value = $package->getDistReference())) { @@ -74,15 +74,18 @@ public function dump(PackageInterface $package): array } foreach (BasePackage::$supportedLinkTypes as $type => $opts) { - if ($links = $package->{'get'.ucfirst($opts['method'])}()) { - foreach ($links as $link) { - $data[$type][$link->getTarget()] = $link->getPrettyConstraint(); - } - ksort($data[$type]); + $links = $package->{'get'.ucfirst($opts['method'])}(); + if (\count($links) === 0) { + continue; } + foreach ($links as $link) { + $data[$type][$link->getTarget()] = $link->getPrettyConstraint(); + } + ksort($data[$type]); } - if ($packages = $package->getSuggests()) { + $packages = $package->getSuggests(); + if (\count($packages) > 0) { ksort($packages); $data['suggest'] = $packages; } @@ -130,7 +133,7 @@ public function dump(PackageInterface $package): array if ($package instanceof RootPackageInterface) { $minimumStability = $package->getMinimumStability(); - if ($minimumStability) { + if ($minimumStability !== '') { $data['minimum-stability'] = $minimumStability; } } diff --git a/vendor/composer/composer/src/Composer/Package/Loader/ArrayLoader.php b/vendor/composer/composer/src/Composer/Package/Loader/ArrayLoader.php index daa540b..887f291 100644 --- a/vendor/composer/composer/src/Composer/Package/Loader/ArrayLoader.php +++ b/vendor/composer/composer/src/Composer/Package/Loader/ArrayLoader.php @@ -228,6 +228,10 @@ private function configureObject(PackageInterface $package, array $config): Base $package->setIncludePaths($config['include-path']); } + if (isset($config['php-ext'])) { + $package->setPhpExt($config['php-ext']); + } + if (!empty($config['time'])) { $time = Preg::isMatch('/^\d++$/D', $config['time']) ? '@'.$config['time'] : $config['time']; diff --git a/vendor/composer/composer/src/Composer/Package/Loader/RootPackageLoader.php b/vendor/composer/composer/src/Composer/Package/Loader/RootPackageLoader.php index 9796bb3..81cb375 100644 --- a/vendor/composer/composer/src/Composer/Package/Loader/RootPackageLoader.php +++ b/vendor/composer/composer/src/Composer/Package/Loader/RootPackageLoader.php @@ -88,7 +88,7 @@ public function load(array $config, string $class = 'Composer\Package\RootPackag // override with env var if available if (Platform::getEnv('COMPOSER_ROOT_VERSION')) { - $config['version'] = Platform::getEnv('COMPOSER_ROOT_VERSION'); + $config['version'] = $this->versionGuesser->getRootVersionFromEnv(); } else { $versionData = $this->versionGuesser->guessVersion($config, $cwd ?? Platform::getCwd(true)); if ($versionData) { @@ -99,7 +99,7 @@ public function load(array $config, string $class = 'Composer\Package\RootPackag } if (!isset($config['version'])) { - if ($this->io !== null && $config['name'] !== '__root__') { + if ($this->io !== null && $config['name'] !== '__root__' && 'project' !== ($config['type'] ?? '')) { $this->io->warning( sprintf( "Composer could not detect the root package (%s) version, defaulting to '1.0.0'. See https://getcomposer.org/root-version", @@ -227,6 +227,7 @@ private function extractAliases(array $requires, array $aliases): array * * @param array $requires * @param array $stabilityFlags + * @param key-of $minimumStability * * @return array * @@ -235,8 +236,7 @@ private function extractAliases(array $requires, array $aliases): array */ public static function extractStabilityFlags(array $requires, string $minimumStability, array $stabilityFlags): array { - $stabilities = BasePackage::$stabilities; - /** @var int $minimumStability */ + $stabilities = BasePackage::STABILITIES; $minimumStability = $stabilities[$minimumStability]; foreach ($requires as $reqName => $reqVersion) { $constraints = []; diff --git a/vendor/composer/composer/src/Composer/Package/Loader/ValidatingArrayLoader.php b/vendor/composer/composer/src/Composer/Package/Loader/ValidatingArrayLoader.php index a94448a..a6431d2 100644 --- a/vendor/composer/composer/src/Composer/Package/Loader/ValidatingArrayLoader.php +++ b/vendor/composer/composer/src/Composer/Package/Loader/ValidatingArrayLoader.php @@ -247,6 +247,12 @@ public function load(array $config, string $class = 'Composer\Package\CompletePa } } + $this->validateArray('php-ext'); + if (isset($this->config['php-ext']) && !in_array($this->config['type'] ?? '', ['php-ext', 'php-ext-zend'], true)) { + $this->errors[] = 'php-ext can only be set by packages of type "php-ext" or "php-ext-zend" which must be C extensions'; + unset($this->config['php-ext']); + } + $unboundConstraint = new Constraint('=', '10000000-dev'); foreach (array_keys(BasePackage::$supportedLinkTypes) as $linkType) { @@ -317,8 +323,8 @@ public function load(array $config, string $class = 'Composer\Package\CompletePa } if ($this->validateString('minimum-stability') && isset($this->config['minimum-stability'])) { - if (!isset(BasePackage::$stabilities[strtolower($this->config['minimum-stability'])]) && $this->config['minimum-stability'] !== 'RC') { - $this->errors[] = 'minimum-stability : invalid value ('.$this->config['minimum-stability'].'), must be one of '.implode(', ', array_keys(BasePackage::$stabilities)); + if (!isset(BasePackage::STABILITIES[strtolower($this->config['minimum-stability'])]) && $this->config['minimum-stability'] !== 'RC') { + $this->errors[] = 'minimum-stability : invalid value ('.$this->config['minimum-stability'].'), must be one of '.implode(', ', array_keys(BasePackage::STABILITIES)); unset($this->config['minimum-stability']); } } diff --git a/vendor/composer/composer/src/Composer/Package/Locker.php b/vendor/composer/composer/src/Composer/Package/Locker.php index f832e79..5b5ec46 100644 --- a/vendor/composer/composer/src/Composer/Package/Locker.php +++ b/vendor/composer/composer/src/Composer/Package/Locker.php @@ -66,13 +66,21 @@ public function __construct(IOInterface $io, JsonFile $lockFile, InstallationMan { $this->lockFile = $lockFile; $this->installationManager = $installationManager; - $this->hash = md5($composerFileContents); + $this->hash = hash('md5', $composerFileContents); $this->contentHash = self::getContentHash($composerFileContents); $this->loader = new ArrayLoader(null, true); $this->dumper = new ArrayDumper(); $this->process = $process ?? new ProcessExecutor($io); } + /** + * @internal + */ + public function getJsonFile(): JsonFile + { + return $this->lockFile; + } + /** * Returns the md5 hash of the sorted content of the composer file. * @@ -107,7 +115,7 @@ public static function getContentHash(string $composerFileContents): string ksort($relevantContent); - return md5(JsonFile::encode($relevantContent, 0)); + return hash('md5', JsonFile::encode($relevantContent, 0)); } /** @@ -247,6 +255,9 @@ public function getPlatformRequirements(bool $withDevReqs = false): array return $requirements; } + /** + * @return key-of + */ public function getMinimumStability(): string { $lockData = $this->getLockData(); @@ -365,18 +376,22 @@ public function setLockData(array $packages, ?array $devPackages, array $platfor 'packages-dev' => null, 'aliases' => $aliases, 'minimum-stability' => $minimumStability, - 'stability-flags' => $stabilityFlags, + 'stability-flags' => \count($stabilityFlags) > 0 ? $stabilityFlags : new \stdClass, 'prefer-stable' => $preferStable, 'prefer-lowest' => $preferLowest, ]; + if (is_array($lock['stability-flags'])) { + ksort($lock['stability-flags']); + } + $lock['packages'] = $this->lockPackages($packages); if (null !== $devPackages) { $lock['packages-dev'] = $this->lockPackages($devPackages); } - $lock['platform'] = $platformReqs; - $lock['platform-dev'] = $platformDevReqs; + $lock['platform'] = \count($platformReqs) > 0 ? $platformReqs : new \stdClass; + $lock['platform-dev'] = \count($platformDevReqs) > 0 ? $platformDevReqs : new \stdClass; if (\count($platformOverrides) > 0) { $lock['platform-overrides'] = $platformOverrides; } diff --git a/vendor/composer/composer/src/Composer/Package/Package.php b/vendor/composer/composer/src/Composer/Package/Package.php index 295bbd2..ad17538 100644 --- a/vendor/composer/composer/src/Composer/Package/Package.php +++ b/vendor/composer/composer/src/Composer/Package/Package.php @@ -98,6 +98,8 @@ class Package extends BasePackage protected $isDefaultBranch = false; /** @var mixed[] */ protected $transportOptions = []; + /** @var array{priority?: int, configure-options?: list}|null */ + protected $phpExt = null; /** * Creates a new in memory package. @@ -590,6 +592,24 @@ public function getIncludePaths(): array return $this->includePaths; } + /** + * Sets the list of paths added to PHP's include path. + * + * @param array{extension-name?: string, priority?: int, support-zts?: bool, support-nts?: bool, configure-options?: list}|null $phpExt List of directories. + */ + public function setPhpExt(?array $phpExt): void + { + $this->phpExt = $phpExt; + } + + /** + * @inheritDoc + */ + public function getPhpExt(): ?array + { + return $this->phpExt; + } + /** * Sets the notification URL */ diff --git a/vendor/composer/composer/src/Composer/Package/PackageInterface.php b/vendor/composer/composer/src/Composer/Package/PackageInterface.php index 4d874ef..6e723d5 100644 --- a/vendor/composer/composer/src/Composer/Package/PackageInterface.php +++ b/vendor/composer/composer/src/Composer/Package/PackageInterface.php @@ -181,6 +181,8 @@ public function getDistReference(): ?string; /** * Returns the sha1 checksum for the distribution archive of this version * + * Can be an empty string which should be treated as null + * * @return ?string */ public function getDistSha1Checksum(): ?string; @@ -321,6 +323,13 @@ public function getDevAutoload(): array; */ public function getIncludePaths(): array; + /** + * Returns the settings for php extension packages + * + * @return array{extension-name?: string, priority?: int, support-zts?: bool, support-nts?: bool, configure-options?: list}|null + */ + public function getPhpExt(): ?array; + /** * Stores a reference to the repository that owns the package */ diff --git a/vendor/composer/composer/src/Composer/Package/RootPackage.php b/vendor/composer/composer/src/Composer/Package/RootPackage.php index e130542..a0f8e65 100644 --- a/vendor/composer/composer/src/Composer/Package/RootPackage.php +++ b/vendor/composer/composer/src/Composer/Package/RootPackage.php @@ -21,7 +21,7 @@ class RootPackage extends CompletePackage implements RootPackageInterface { public const DEFAULT_PRETTY_VERSION = '1.0.0+no-version-set'; - /** @var string */ + /** @var key-of */ protected $minimumStability = 'stable'; /** @var bool */ protected $preferStable = false; diff --git a/vendor/composer/composer/src/Composer/Package/RootPackageInterface.php b/vendor/composer/composer/src/Composer/Package/RootPackageInterface.php index 4adad6c..8a08060 100644 --- a/vendor/composer/composer/src/Composer/Package/RootPackageInterface.php +++ b/vendor/composer/composer/src/Composer/Package/RootPackageInterface.php @@ -33,6 +33,8 @@ public function getAliases(): array; /** * Returns the minimum stability of the package + * + * @return key-of */ public function getMinimumStability(): string; @@ -120,12 +122,14 @@ public function setDevAutoload(array $devAutoload): void; /** * Set the stabilityFlags * - * @param array $stabilityFlags + * @phpstan-param array $stabilityFlags */ public function setStabilityFlags(array $stabilityFlags): void; /** * Set the minimumStability + * + * @phpstan-param key-of $minimumStability */ public function setMinimumStability(string $minimumStability): void; diff --git a/vendor/composer/composer/src/Composer/Package/Version/StabilityFilter.php b/vendor/composer/composer/src/Composer/Package/Version/StabilityFilter.php index 172901d..7e0182a 100644 --- a/vendor/composer/composer/src/Composer/Package/Version/StabilityFilter.php +++ b/vendor/composer/composer/src/Composer/Package/Version/StabilityFilter.php @@ -23,11 +23,11 @@ class StabilityFilter * Checks if any of the provided package names in the given stability match the configured acceptable stability and flags * * @param int[] $acceptableStabilities array of stability => BasePackage::STABILITY_* value - * @phpstan-param array $acceptableStabilities + * @phpstan-param array, BasePackage::STABILITY_*> $acceptableStabilities * @param int[] $stabilityFlags an array of package name => BasePackage::STABILITY_* value * @phpstan-param array $stabilityFlags * @param string[] $names The package name(s) to check for stability flags - * @param string $stability one of 'stable', 'RC', 'beta', 'alpha' or 'dev' + * @param key-of $stability one of 'stable', 'RC', 'beta', 'alpha' or 'dev' * @return bool true if any package name is acceptable */ public static function isPackageAcceptable(array $acceptableStabilities, array $stabilityFlags, array $names, string $stability): bool @@ -35,7 +35,7 @@ public static function isPackageAcceptable(array $acceptableStabilities, array $ foreach ($names as $name) { // allow if package matches the package-specific stability flag if (isset($stabilityFlags[$name])) { - if (BasePackage::$stabilities[$stability] <= $stabilityFlags[$name]) { + if (BasePackage::STABILITIES[$stability] <= $stabilityFlags[$name]) { return true; } } elseif (isset($acceptableStabilities[$stability])) { diff --git a/vendor/composer/composer/src/Composer/Package/Version/VersionBumper.php b/vendor/composer/composer/src/Composer/Package/Version/VersionBumper.php index e6dbdeb..b100d0e 100644 --- a/vendor/composer/composer/src/Composer/Package/Version/VersionBumper.php +++ b/vendor/composer/composer/src/Composer/Package/Version/VersionBumper.php @@ -39,6 +39,8 @@ class VersionBumper * * ^1.2 || ^2.3 + 2.4.0 -> ^1.2 || ^2.4 * * ^3@dev + 3.2.99999-dev -> ^3.2@dev * * ~2 + 2.0-beta.1 -> ~2 + * * ~2.0.0 + 2.0.3 -> ~2.0.3 + * * ~2.0 + 2.0.3 -> ^2.0.3 * * dev-master + dev-master -> dev-master * * * + 1.2.3 -> >=1.2.3 */ @@ -84,7 +86,7 @@ public function bumpRequirement(ConstraintInterface $constraint, PackageInterfac (?<=,|\ |\||^) # leading separator (?P \^v?'.$major.'(?:\.\d+)* # e.g. ^2.anything - | ~v?'.$major.'(?:\.\d+){0,2} # e.g. ~2 or ~2.2 or ~2.2.2 but no more + | ~v?'.$major.'(?:\.\d+){1,3} # e.g. ~2.2 or ~2.2.2 or ~2.2.2.2 | v?'.$major.'(?:\.[*x])+ # e.g. 2.* or 2.*.* or 2.x.x.x etc | >=v?\d(?:\.\d+)* # e.g. >=2 or >=1.2 etc | \* # full wildcard @@ -99,8 +101,11 @@ public function bumpRequirement(ConstraintInterface $constraint, PackageInterfac if (substr_count($match[0], '.') === 2 && substr_count($versionWithoutSuffix, '.') === 1) { $suffix = '.0'; } - if (str_starts_with($match[0], '~') && substr_count($match[0], '.') === 2) { - $replacement = '~'.$versionWithoutSuffix.$suffix; + if (str_starts_with($match[0], '~') && substr_count($match[0], '.') !== 1) { + // take as many version bits from the current version as we have in the constraint to bump it without making it more specific + $versionBits = explode('.', $versionWithoutSuffix); + $versionBits = array_pad($versionBits, substr_count($match[0], '.') + 1, '0'); + $replacement = '~'.implode('.', array_slice($versionBits, 0, substr_count($match[0], '.') + 1)); } elseif ($match[0] === '*' || str_starts_with($match[0], '>=')) { $replacement = '>='.$versionWithoutSuffix.$suffix; } else { diff --git a/vendor/composer/composer/src/Composer/Package/Version/VersionGuesser.php b/vendor/composer/composer/src/Composer/Package/Version/VersionGuesser.php index 2b2b197..bfc16d5 100644 --- a/vendor/composer/composer/src/Composer/Package/Version/VersionGuesser.php +++ b/vendor/composer/composer/src/Composer/Package/Version/VersionGuesser.php @@ -173,7 +173,7 @@ private function guessGitVersion(array $packageConfig, string $path): array $featurePrettyVersion = $prettyVersion; // try to find the best (nearest) version branch to assume this feature's version - $result = $this->guessFeatureVersion($packageConfig, $version, $branches, 'git rev-list %candidate%..%branch%', $path); + $result = $this->guessFeatureVersion($packageConfig, $version, $branches, ['git', 'rev-list', '%candidate%..%branch%'], $path); $version = $result['version']; $prettyVersion = $result['pretty_version']; } @@ -248,7 +248,7 @@ private function guessHgVersion(array $packageConfig, string $path): ?array $branches = array_map('strval', array_keys($driver->getBranches())); // try to find the best (nearest) version branch to assume this feature's version - $result = $this->guessFeatureVersion($packageConfig, $version, $branches, 'hg log -r "not ancestors(\'%candidate%\') and ancestors(\'%branch%\')" --template "{node}\\n"', $path); + $result = $this->guessFeatureVersion($packageConfig, $version, $branches, ['hg', 'log', '-r', 'not ancestors(\'%candidate%\') and ancestors(\'%branch%\')', '--template', '"{node}\\n"'], $path); $result['commit'] = ''; $result['feature_version'] = $version; $result['feature_pretty_version'] = $version; @@ -261,13 +261,12 @@ private function guessHgVersion(array $packageConfig, string $path): ?array /** * @param array $packageConfig - * @param string[] $branches - * - * @phpstan-param non-empty-string $scmCmdline + * @param list $branches + * @param list $scmCmdline * * @return array{version: string|null, pretty_version: string|null} */ - private function guessFeatureVersion(array $packageConfig, ?string $version, array $branches, string $scmCmdline, string $path): array + private function guessFeatureVersion(array $packageConfig, ?string $version, array $branches, array $scmCmdline, string $path): array { $prettyVersion = $version; @@ -285,7 +284,7 @@ private function guessFeatureVersion(array $packageConfig, ?string $version, arr } // sort local branches first then remote ones - // and sort numeric branches below named ones, to make sure if the branch has the same distance from main and 1.10 and 1.9 for example, main is picked + // and sort numeric branches below named ones, to make sure if the branch has the same distance from main and 1.10 and 1.9 for example, 1.9 is picked // and sort using natural sort so that 1.10 will appear before 1.9 usort($branches, static function ($a, $b): int { $aRemote = 0 === strpos($a, 'remotes/'); @@ -301,7 +300,8 @@ private function guessFeatureVersion(array $packageConfig, ?string $version, arr $promises = []; $this->process->setMaxJobs(30); try { - foreach ($branches as $candidate) { + $lastIndex = -1; + foreach ($branches as $index => $candidate) { $candidateVersion = Preg::replace('{^remotes/\S+/}', '', $candidate); // do not compare against itself or other feature branches @@ -309,14 +309,20 @@ private function guessFeatureVersion(array $packageConfig, ?string $version, arr continue; } - $cmdLine = str_replace(['%candidate%', '%branch%'], [$candidate, $branch], $scmCmdline); - $promises[] = $this->process->executeAsync($cmdLine, $path)->then(function (Process $process) use (&$length, &$version, &$prettyVersion, $candidateVersion, &$promises): void { + $cmdLine = array_map(static function (string $component) use ($candidate, $branch) { + return str_replace(['%candidate%', '%branch%'], [$candidate, $branch], $component); + }, $scmCmdline); + $promises[] = $this->process->executeAsync($cmdLine, $path)->then(function (Process $process) use (&$lastIndex, $index, &$length, &$version, &$prettyVersion, $candidateVersion, &$promises): void { if (!$process->isSuccessful()) { return; } $output = $process->getOutput(); - if (strlen($output) < $length) { + // overwrite existing if we have a shorter diff, or we have an equal diff and an index that comes later in the array (i.e. older version) + // as newer versions typically have more commits, if the feature branch is based on a newer branch it should have a longer diff to the old version + // but if it doesn't and they have equal diffs, then it probably is based on the old version + if (strlen($output) < $length || (strlen($output) === $length && $lastIndex < $index)) { + $lastIndex = $index; $length = strlen($output); $version = $this->versionParser->normalizeBranch($candidateVersion); $prettyVersion = 'dev-' . $candidateVersion; @@ -419,4 +425,17 @@ private function guessSvnVersion(array $packageConfig, string $path): ?array return null; } + + public function getRootVersionFromEnv(): string + { + $version = Platform::getEnv('COMPOSER_ROOT_VERSION'); + if (!is_string($version) || $version === '') { + throw new \RuntimeException('COMPOSER_ROOT_VERSION not set or empty'); + } + if (Preg::isMatch('{^(\d+(?:\.\d+)*)-dev$}i', $version, $match)) { + $version = $match[1].'.x-dev'; + } + + return $version; + } } diff --git a/vendor/composer/composer/src/Composer/Package/Version/VersionSelector.php b/vendor/composer/composer/src/Composer/Package/Version/VersionSelector.php index 9ab3220..7c0c61a 100644 --- a/vendor/composer/composer/src/Composer/Package/Version/VersionSelector.php +++ b/vendor/composer/composer/src/Composer/Package/Version/VersionSelector.php @@ -71,7 +71,7 @@ public function __construct(RepositorySet $repositorySet, ?PlatformRepository $p */ public function findBestCandidate(string $packageName, ?string $targetPackageVersion = null, string $preferredStability = 'stable', $platformRequirementFilter = null, int $repoSetFlags = 0, ?IOInterface $io = null, $showWarnings = true) { - if (!isset(BasePackage::$stabilities[$preferredStability])) { + if (!isset(BasePackage::STABILITIES[$preferredStability])) { // If you get this, maybe you are still relying on the Composer 1.x signature where the 3rd arg was the php version throw new \UnexpectedValueException('Expected a valid stability name as 3rd argument, got '.$preferredStability); } @@ -86,7 +86,7 @@ public function findBestCandidate(string $packageName, ?string $targetPackageVer $constraint = $targetPackageVersion ? $this->getParser()->parseConstraints($targetPackageVersion) : null; $candidates = $this->repositorySet->findPackages(strtolower($packageName), $constraint, $repoSetFlags); - $minPriority = BasePackage::$stabilities[$preferredStability]; + $minPriority = BasePackage::STABILITIES[$preferredStability]; usort($candidates, static function (PackageInterface $a, PackageInterface $b) use ($minPriority) { $aPriority = $a->getStabilityPriority(); $bPriority = $b->getStabilityPriority(); @@ -121,6 +121,7 @@ public function findBestCandidate(string $packageName, ?string $targetPackageVer foreach ($candidates as $pkg) { $reqs = $pkg->getRequires(); + $skip = false; foreach ($reqs as $name => $link) { if (!PlatformRepository::isPlatformPackage($name) || $platformRequirementFilter->isIgnored($name)) { continue; @@ -151,8 +152,8 @@ public function findBestCandidate(string $packageName, ?string $targetPackageVer $isLatestVersion = !isset($alreadySeenNames[$pkg->getName()]); $alreadySeenNames[$pkg->getName()] = true; if ($io !== null && ($showWarnings === true || (is_callable($showWarnings) && $showWarnings($pkg)))) { - $isFirstWarning = !isset($alreadyWarnedNames[$pkg->getName()]); - $alreadyWarnedNames[$pkg->getName()] = true; + $isFirstWarning = !isset($alreadyWarnedNames[$pkg->getName().'/'.$link->getTarget()]); + $alreadyWarnedNames[$pkg->getName().'/'.$link->getTarget()] = true; $latest = $isLatestVersion ? "'s latest version" : ''; $io->writeError( 'Cannot use '.$pkg->getPrettyName().$latest.' '.$pkg->getPrettyVersion().' as it '.$link->getDescription().' '.$link->getTarget().' '.$link->getPrettyConstraint().' which '.$reason.'.', @@ -162,7 +163,11 @@ public function findBestCandidate(string $packageName, ?string $targetPackageVer } // skip candidate - continue 2; + $skip = true; + } + + if ($skip) { + continue; } $package = $pkg; diff --git a/vendor/composer/composer/src/Composer/Platform/Runtime.php b/vendor/composer/composer/src/Composer/Platform/Runtime.php index b05af08..940c02d 100644 --- a/vendor/composer/composer/src/Composer/Platform/Runtime.php +++ b/vendor/composer/composer/src/Composer/Platform/Runtime.php @@ -56,9 +56,12 @@ public function hasClass(string $class): bool } /** - * @param class-string $class + * @template T of object * @param mixed[] $arguments * + * @phpstan-param class-string $class + * @phpstan-return T + * * @throws \ReflectionException */ public function construct(string $class, array $arguments = []): object diff --git a/vendor/composer/composer/src/Composer/Plugin/PluginManager.php b/vendor/composer/composer/src/Composer/Plugin/PluginManager.php index f594478..7cd0806 100644 --- a/vendor/composer/composer/src/Composer/Plugin/PluginManager.php +++ b/vendor/composer/composer/src/Composer/Plugin/PluginManager.php @@ -20,11 +20,13 @@ use Composer\Package\CompletePackage; use Composer\Package\Locker; use Composer\Package\Package; +use Composer\Package\RootPackageInterface; use Composer\Package\Version\VersionParser; use Composer\PartialComposer; use Composer\Pcre\Preg; use Composer\Repository\RepositoryInterface; use Composer\Repository\InstalledRepository; +use Composer\Repository\RepositoryUtils; use Composer\Repository\RootPackageRepository; use Composer\Package\PackageInterface; use Composer\Package\Link; @@ -98,7 +100,7 @@ public function loadInstalledPlugins(): void { if (!$this->arePluginsDisabled('local')) { $repo = $this->composer->getRepositoryManager()->getLocalRepository(); - $this->loadRepository($repo, false); + $this->loadRepository($repo, false, $this->composer->getPackage()); } if ($this->globalComposer !== null && !$this->arePluginsDisabled('global')) { @@ -445,9 +447,11 @@ public function uninstallPlugin(PluginInterface $plugin): void * * @param RepositoryInterface $repo Repository to scan for plugins to install * + * @phpstan-param ($isGlobalRepo is true ? null : RootPackageInterface) $rootPackage + * * @throws \RuntimeException */ - private function loadRepository(RepositoryInterface $repo, bool $isGlobalRepo): void + private function loadRepository(RepositoryInterface $repo, bool $isGlobalRepo, ?RootPackageInterface $rootPackage = null): void { $packages = $repo->getPackages(); @@ -462,10 +466,28 @@ private function loadRepository(RepositoryInterface $repo, bool $isGlobalRepo): } $sortedPackages = PackageSorter::sortPackages($packages, $weights); + if (!$isGlobalRepo) { + $requiredPackages = RepositoryUtils::filterRequiredPackages($packages, $rootPackage, true); + } + foreach ($sortedPackages as $package) { if (!($package instanceof CompletePackage)) { continue; } + + if (!in_array($package->getType(), ['composer-plugin', 'composer-installer'], true)) { + continue; + } + + if ( + !$isGlobalRepo + && !in_array($package, $requiredPackages, true) + && !$this->isPluginAllowed($package->getName(), false, true, false) + ) { + $this->io->writeError('The "'.$package->getName().'" plugin was not loaded as it is not listed in allow-plugins and is not required by the root package anymore.'); + continue; + } + if ('composer-plugin' === $package->getType()) { $this->registerPackage($package, false, $isGlobalRepo); // Backward compatibility @@ -668,7 +690,7 @@ public function disablePlugins(): void /** * @internal */ - public function isPluginAllowed(string $package, bool $isGlobalPlugin, bool $optional = false): bool + public function isPluginAllowed(string $package, bool $isGlobalPlugin, bool $optional = false, bool $prompt = true): bool { if ($isGlobalPlugin) { $rules = &$this->allowGlobalPluginRules; @@ -703,7 +725,7 @@ public function isPluginAllowed(string $package, bool $isGlobalPlugin, bool $opt return false; } - if ($this->io->isInteractive()) { + if ($this->io->isInteractive() && $prompt) { $composer = $isGlobalPlugin && $this->globalComposer !== null ? $this->globalComposer : $this->composer; $this->io->writeError(''.$package.($isGlobalPlugin || $this->runningInGlobalDir ? ' (installed globally)' : '').' contains a Composer plugin which is currently not in your allow-plugins config. See https://getcomposer.org/allow-plugins'); @@ -728,7 +750,15 @@ public function isPluginAllowed(string $package, bool $isGlobalPlugin, bool $opt // persist answer in composer.json if it wasn't simply discarded if ($answer === 'y' || $answer === 'n') { - $composer->getConfig()->getConfigSource()->addConfigSetting('allow-plugins.'.$package, $allow); + $allowPlugins = $composer->getConfig()->get('allow-plugins'); + if (is_array($allowPlugins)) { + $allowPlugins[$package] = $allow; + if ($composer->getConfig()->get('sort-packages')) { + ksort($allowPlugins); + } + $composer->getConfig()->getConfigSource()->addConfigSetting('allow-plugins', $allowPlugins); + $composer->getConfig()->merge(['config' => ['allow-plugins' => $allowPlugins]]); + } } return $allow; diff --git a/vendor/composer/composer/src/Composer/Plugin/PostFileDownloadEvent.php b/vendor/composer/composer/src/Composer/Plugin/PostFileDownloadEvent.php index e789916..a8d9a02 100644 --- a/vendor/composer/composer/src/Composer/Plugin/PostFileDownloadEvent.php +++ b/vendor/composer/composer/src/Composer/Plugin/PostFileDownloadEvent.php @@ -59,7 +59,7 @@ class PostFileDownloadEvent extends Event */ public function __construct(string $name, ?string $fileName, ?string $checksum, string $url, string $type, $context = null) { - /** @phpstan-ignore-next-line */ + /** @phpstan-ignore instanceof.alwaysFalse, booleanAnd.alwaysFalse */ if ($context === null && $type instanceof PackageInterface) { $context = $type; $type = 'package'; diff --git a/vendor/composer/composer/src/Composer/Question/StrictConfirmationQuestion.php b/vendor/composer/composer/src/Composer/Question/StrictConfirmationQuestion.php index c27753b..9cbc74e 100644 --- a/vendor/composer/composer/src/Composer/Question/StrictConfirmationQuestion.php +++ b/vendor/composer/composer/src/Composer/Question/StrictConfirmationQuestion.php @@ -40,7 +40,7 @@ class StrictConfirmationQuestion extends Question */ public function __construct(string $question, bool $default = true, string $trueAnswerRegex = '/^y(?:es)?$/i', string $falseAnswerRegex = '/^no?$/i') { - parent::__construct($question, (bool) $default); + parent::__construct($question, $default); $this->trueAnswerRegex = $trueAnswerRegex; $this->falseAnswerRegex = $falseAnswerRegex; diff --git a/vendor/composer/composer/src/Composer/Repository/ArtifactRepository.php b/vendor/composer/composer/src/Composer/Repository/ArtifactRepository.php index f73f4e9..78176fa 100644 --- a/vendor/composer/composer/src/Composer/Repository/ArtifactRepository.php +++ b/vendor/composer/composer/src/Composer/Repository/ArtifactRepository.php @@ -129,7 +129,7 @@ private function getComposerInformation(\SplFileInfo $file): ?BasePackage $package['dist'] = [ 'type' => $fileType, 'url' => strtr($file->getPathname(), '\\', '/'), - 'shasum' => sha1_file($file->getRealPath()), + 'shasum' => hash_file('sha1', $file->getRealPath()), ]; try { diff --git a/vendor/composer/composer/src/Composer/Repository/ComposerRepository.php b/vendor/composer/composer/src/Composer/Repository/ComposerRepository.php index ec244b1..fe93fb7 100644 --- a/vendor/composer/composer/src/Composer/Repository/ComposerRepository.php +++ b/vendor/composer/composer/src/Composer/Repository/ComposerRepository.php @@ -432,8 +432,7 @@ private function getVendorNames(): array $uniques = []; foreach ($names as $name) { - // @phpstan-ignore-next-line - $uniques[substr($name, 0, strpos($name, '/'))] = true; + $uniques[explode('/', $name, 2)[0]] = true; } $vendors = array_keys($uniques); @@ -828,7 +827,7 @@ private function hasProviders(): bool /** * @param string $name package name * @param array|null $acceptableStabilities - * @phpstan-param array|null $acceptableStabilities + * @phpstan-param array, BasePackage::STABILITY_*>|null $acceptableStabilities * @param array|null $stabilityFlags an array of package name => BasePackage::STABILITY_* value * @phpstan-param array|null $stabilityFlags * @param array> $alreadyLoaded @@ -998,7 +997,7 @@ public function addPackage(PackageInterface $package) * @param array $packageNames array of package name => ConstraintInterface|null - if a constraint is provided, only * packages matching it will be loaded * @param array|null $acceptableStabilities - * @phpstan-param array|null $acceptableStabilities + * @phpstan-param array, BasePackage::STABILITY_*>|null $acceptableStabilities * @param array|null $stabilityFlags an array of package name => BasePackage::STABILITY_* value * @phpstan-param array|null $stabilityFlags * @param array> $alreadyLoaded @@ -1130,7 +1129,7 @@ private function startCachedAsyncDownload(string $fileName, ?string $packageName * @param string $name package name (must be lowercased already) * @param array $versionData * @param array|null $acceptableStabilities - * @phpstan-param array|null $acceptableStabilities + * @phpstan-param array, BasePackage::STABILITY_*>|null $acceptableStabilities * @param array|null $stabilityFlags an array of package name => BasePackage::STABILITY_* value * @phpstan-param array|null $stabilityFlags */ diff --git a/vendor/composer/composer/src/Composer/Repository/PathRepository.php b/vendor/composer/composer/src/Composer/Repository/PathRepository.php index 06676e7..1d9e4e7 100644 --- a/vendor/composer/composer/src/Composer/Repository/PathRepository.php +++ b/vendor/composer/composer/src/Composer/Repository/PathRepository.php @@ -181,7 +181,7 @@ protected function initialize(): void if ('none' === $reference) { $package['dist']['reference'] = null; } elseif ('config' === $reference || 'auto' === $reference) { - $package['dist']['reference'] = sha1($json . serialize($this->options)); + $package['dist']['reference'] = hash('sha1', $json . serialize($this->options)); } // copy symlink/relative options to transport options @@ -198,7 +198,7 @@ protected function initialize(): void && 0 === $this->process->execute('git rev-parse HEAD', $ref2) && $ref1 === $ref2 ) { - $package['version'] = $rootVersion; + $package['version'] = $this->versionGuesser->getRootVersionFromEnv(); } } diff --git a/vendor/composer/composer/src/Composer/Repository/PlatformRepository.php b/vendor/composer/composer/src/Composer/Repository/PlatformRepository.php index 2f8f206..f5a2eb5 100644 --- a/vendor/composer/composer/src/Composer/Repository/PlatformRepository.php +++ b/vendor/composer/composer/src/Composer/Repository/PlatformRepository.php @@ -110,6 +110,8 @@ protected function initialize(): void { parent::initialize(); + $libraries = []; + $this->versionParser = new VersionParser(); // Add each of the override versions as options. @@ -207,12 +209,12 @@ protected function initialize(): void // librabbitmq version => 0.9.0 if (Preg::isMatch('/^librabbitmq version => (?.+)$/im', $info, $librabbitmqMatches)) { - $this->addLibrary($name.'-librabbitmq', $librabbitmqMatches['version'], 'AMQP librabbitmq version'); + $this->addLibrary($libraries, $name.'-librabbitmq', $librabbitmqMatches['version'], 'AMQP librabbitmq version'); } // AMQP protocol version => 0-9-1 if (Preg::isMatchStrictGroups('/^AMQP protocol version => (?.+)$/im', $info, $protocolMatches)) { - $this->addLibrary($name.'-protocol', str_replace('-', '.', $protocolMatches['version']), 'AMQP protocol version'); + $this->addLibrary($libraries, $name.'-protocol', str_replace('-', '.', $protocolMatches['version']), 'AMQP protocol version'); } break; @@ -221,13 +223,13 @@ protected function initialize(): void // BZip2 Version => 1.0.6, 6-Sept-2010 if (Preg::isMatch('/^BZip2 Version => (?.*),/im', $info, $matches)) { - $this->addLibrary($name, $matches['version']); + $this->addLibrary($libraries, $name, $matches['version']); } break; case 'curl': $curlVersion = $this->runtime->invoke('curl_version'); - $this->addLibrary($name, $curlVersion['version']); + $this->addLibrary($libraries, $name, $curlVersion['version']); $info = $this->runtime->getExtensionInfo($name); @@ -236,25 +238,25 @@ protected function initialize(): void $library = strtolower($sslMatches['library']); if ($library === 'openssl') { $parsedVersion = Version::parseOpenssl($sslMatches['version'], $isFips); - $this->addLibrary($name.'-openssl'.($isFips ? '-fips' : ''), $parsedVersion, 'curl OpenSSL version ('.$parsedVersion.')', [], $isFips ? ['curl-openssl'] : []); + $this->addLibrary($libraries, $name.'-openssl'.($isFips ? '-fips' : ''), $parsedVersion, 'curl OpenSSL version ('.$parsedVersion.')', [], $isFips ? ['curl-openssl'] : []); } else { if ($library === '(securetransport) openssl') { $shortlib = 'securetransport'; } else { $shortlib = $library; } - $this->addLibrary($name.'-'.$shortlib, $sslMatches['version'], 'curl '.$library.' version ('.$sslMatches['version'].')', ['curl-openssl']); + $this->addLibrary($libraries, $name.'-'.$shortlib, $sslMatches['version'], 'curl '.$library.' version ('.$sslMatches['version'].')', ['curl-openssl']); } } // libSSH Version => libssh2/1.4.3 if (Preg::isMatchStrictGroups('{^libSSH Version => (?[^/]+)/(?.+?)(?:/.*)?$}im', $info, $sshMatches)) { - $this->addLibrary($name.'-'.strtolower($sshMatches['library']), $sshMatches['version'], 'curl '.$sshMatches['library'].' version'); + $this->addLibrary($libraries, $name.'-'.strtolower($sshMatches['library']), $sshMatches['version'], 'curl '.$sshMatches['library'].' version'); } // ZLib Version => 1.2.8 if (Preg::isMatchStrictGroups('{^ZLib Version => (?.+)$}im', $info, $zlibMatches)) { - $this->addLibrary($name.'-zlib', $zlibMatches['version'], 'curl zlib version'); + $this->addLibrary($libraries, $name.'-zlib', $zlibMatches['version'], 'curl zlib version'); } break; @@ -263,7 +265,7 @@ protected function initialize(): void // timelib version => 2018.03 if (Preg::isMatchStrictGroups('/^timelib version => (?.+)$/im', $info, $timelibMatches)) { - $this->addLibrary($name.'-timelib', $timelibMatches['version'], 'date timelib version'); + $this->addLibrary($libraries, $name.'-timelib', $timelibMatches['version'], 'date timelib version'); } // Timezone Database => internal @@ -272,9 +274,9 @@ protected function initialize(): void if (Preg::isMatchStrictGroups('/^"Olson" Timezone Database Version => (?.+?)(?:\.system)?$/im', $info, $zoneinfoMatches)) { // If the timezonedb is provided by ext/timezonedb, register that version as a replacement if ($external && in_array('timezonedb', $loadedExtensions, true)) { - $this->addLibrary('timezonedb-zoneinfo', $zoneinfoMatches['version'], 'zoneinfo ("Olson") database for date (replaced by timezonedb)', [$name.'-zoneinfo']); + $this->addLibrary($libraries, 'timezonedb-zoneinfo', $zoneinfoMatches['version'], 'zoneinfo ("Olson") database for date (replaced by timezonedb)', [$name.'-zoneinfo']); } else { - $this->addLibrary($name.'-zoneinfo', $zoneinfoMatches['version'], 'zoneinfo ("Olson") database for date'); + $this->addLibrary($libraries, $name.'-zoneinfo', $zoneinfoMatches['version'], 'zoneinfo ("Olson") database for date'); } } } @@ -285,39 +287,39 @@ protected function initialize(): void // libmagic => 537 if (Preg::isMatch('/^libmagic => (?.+)$/im', $info, $magicMatches)) { - $this->addLibrary($name.'-libmagic', $magicMatches['version'], 'fileinfo libmagic version'); + $this->addLibrary($libraries, $name.'-libmagic', $magicMatches['version'], 'fileinfo libmagic version'); } break; case 'gd': - $this->addLibrary($name, $this->runtime->getConstant('GD_VERSION')); + $this->addLibrary($libraries, $name, $this->runtime->getConstant('GD_VERSION')); $info = $this->runtime->getExtensionInfo($name); if (Preg::isMatchStrictGroups('/^libJPEG Version => (?.+?)(?: compatible)?$/im', $info, $libjpegMatches)) { - $this->addLibrary($name.'-libjpeg', Version::parseLibjpeg($libjpegMatches['version']), 'libjpeg version for gd'); + $this->addLibrary($libraries, $name.'-libjpeg', Version::parseLibjpeg($libjpegMatches['version']), 'libjpeg version for gd'); } if (Preg::isMatchStrictGroups('/^libPNG Version => (?.+)$/im', $info, $libpngMatches)) { - $this->addLibrary($name.'-libpng', $libpngMatches['version'], 'libpng version for gd'); + $this->addLibrary($libraries, $name.'-libpng', $libpngMatches['version'], 'libpng version for gd'); } if (Preg::isMatchStrictGroups('/^FreeType Version => (?.+)$/im', $info, $freetypeMatches)) { - $this->addLibrary($name.'-freetype', $freetypeMatches['version'], 'freetype version for gd'); + $this->addLibrary($libraries, $name.'-freetype', $freetypeMatches['version'], 'freetype version for gd'); } if (Preg::isMatchStrictGroups('/^libXpm Version => (?\d+)$/im', $info, $libxpmMatches)) { - $this->addLibrary($name.'-libxpm', Version::convertLibxpmVersionId((int) $libxpmMatches['versionId']), 'libxpm version for gd'); + $this->addLibrary($libraries, $name.'-libxpm', Version::convertLibxpmVersionId((int) $libxpmMatches['versionId']), 'libxpm version for gd'); } break; case 'gmp': - $this->addLibrary($name, $this->runtime->getConstant('GMP_VERSION')); + $this->addLibrary($libraries, $name, $this->runtime->getConstant('GMP_VERSION')); break; case 'iconv': - $this->addLibrary($name, $this->runtime->getConstant('ICONV_VERSION')); + $this->addLibrary($libraries, $name, $this->runtime->getConstant('ICONV_VERSION')); break; case 'intl': @@ -326,47 +328,49 @@ protected function initialize(): void $description = 'The ICU unicode and globalization support library'; // Truthy check is for testing only so we can make the condition fail if ($this->runtime->hasConstant('INTL_ICU_VERSION')) { - $this->addLibrary('icu', $this->runtime->getConstant('INTL_ICU_VERSION'), $description); + $this->addLibrary($libraries, 'icu', $this->runtime->getConstant('INTL_ICU_VERSION'), $description); } elseif (Preg::isMatch('/^ICU version => (?.+)$/im', $info, $matches)) { - $this->addLibrary('icu', $matches['version'], $description); + $this->addLibrary($libraries, 'icu', $matches['version'], $description); } // ICU TZData version => 2019c if (Preg::isMatchStrictGroups('/^ICU TZData version => (?.*)$/im', $info, $zoneinfoMatches) && null !== ($version = Version::parseZoneinfoVersion($zoneinfoMatches['version']))) { - $this->addLibrary('icu-zoneinfo', $version, 'zoneinfo ("Olson") database for icu'); + $this->addLibrary($libraries, 'icu-zoneinfo', $version, 'zoneinfo ("Olson") database for icu'); } // Add a separate version for the CLDR library version if ($this->runtime->hasClass('ResourceBundle')) { $resourceBundle = $this->runtime->invoke(['ResourceBundle', 'create'], ['root', 'ICUDATA', false]); if ($resourceBundle !== null) { - $this->addLibrary('icu-cldr', $resourceBundle->get('Version'), 'ICU CLDR project version'); + $this->addLibrary($libraries, 'icu-cldr', $resourceBundle->get('Version'), 'ICU CLDR project version'); } } if ($this->runtime->hasClass('IntlChar')) { - $this->addLibrary('icu-unicode', implode('.', array_slice($this->runtime->invoke(['IntlChar', 'getUnicodeVersion']), 0, 3)), 'ICU unicode version'); + $this->addLibrary($libraries, 'icu-unicode', implode('.', array_slice($this->runtime->invoke(['IntlChar', 'getUnicodeVersion']), 0, 3)), 'ICU unicode version'); } break; case 'imagick': + // @phpstan-ignore staticMethod.dynamicCall (called like this for mockability) $imageMagickVersion = $this->runtime->construct('Imagick')->getVersion(); // 6.x: ImageMagick 6.2.9 08/24/06 Q16 http://www.imagemagick.org // 7.x: ImageMagick 7.0.8-34 Q16 x86_64 2019-03-23 https://imagemagick.org - Preg::match('/^ImageMagick (?[\d.]+)(?:-(?\d+))?/', $imageMagickVersion['versionString'], $matches); - $version = $matches['version']; - if (isset($matches['patch'])) { - $version .= '.'.$matches['patch']; - } + if (Preg::isMatch('/^ImageMagick (?[\d.]+)(?:-(?\d+))?/', $imageMagickVersion['versionString'], $matches)) { + $version = $matches['version']; + if (isset($matches['patch'])) { + $version .= '.'.$matches['patch']; + } - $this->addLibrary($name.'-imagemagick', $version, null, ['imagick']); + $this->addLibrary($libraries, $name.'-imagemagick', $version, null, ['imagick']); + } break; case 'ldap': $info = $this->runtime->getExtensionInfo($name); if (Preg::isMatchStrictGroups('/^Vendor Version => (?\d+)$/im', $info, $matches) && Preg::isMatchStrictGroups('/^Vendor Name => (?.+)$/im', $info, $vendorMatches)) { - $this->addLibrary($name.'-'.strtolower($vendorMatches['vendor']), Version::convertOpenldapVersionId((int) $matches['versionId']), $vendorMatches['vendor'].' version of ldap'); + $this->addLibrary($libraries, $name.'-'.strtolower($vendorMatches['vendor']), Version::convertOpenldapVersionId((int) $matches['versionId']), $vendorMatches['vendor'].' version of ldap'); } break; @@ -375,7 +379,7 @@ protected function initialize(): void $libxmlProvides = array_map(static function ($extension): string { return $extension . '-libxml'; }, array_intersect($loadedExtensions, ['dom', 'simplexml', 'xml', 'xmlreader', 'xmlwriter'])); - $this->addLibrary($name, $this->runtime->getConstant('LIBXML_DOTTED_VERSION'), 'libxml library version', [], $libxmlProvides); + $this->addLibrary($libraries, $name, $this->runtime->getConstant('LIBXML_DOTTED_VERSION'), 'libxml library version', [], $libxmlProvides); break; @@ -384,16 +388,16 @@ protected function initialize(): void // libmbfl version => 1.3.2 if (Preg::isMatch('/^libmbfl version => (?.+)$/im', $info, $libmbflMatches)) { - $this->addLibrary($name.'-libmbfl', $libmbflMatches['version'], 'mbstring libmbfl version'); + $this->addLibrary($libraries, $name.'-libmbfl', $libmbflMatches['version'], 'mbstring libmbfl version'); } if ($this->runtime->hasConstant('MB_ONIGURUMA_VERSION')) { - $this->addLibrary($name.'-oniguruma', $this->runtime->getConstant('MB_ONIGURUMA_VERSION'), 'mbstring oniguruma version'); + $this->addLibrary($libraries, $name.'-oniguruma', $this->runtime->getConstant('MB_ONIGURUMA_VERSION'), 'mbstring oniguruma version'); // Multibyte regex (oniguruma) version => 5.9.5 // oniguruma version => 6.9.0 } elseif (Preg::isMatch('/^(?:oniguruma|Multibyte regex \(oniguruma\)) version => (?.+)$/im', $info, $onigurumaMatches)) { - $this->addLibrary($name.'-oniguruma', $onigurumaMatches['version'], 'mbstring oniguruma version'); + $this->addLibrary($libraries, $name.'-oniguruma', $onigurumaMatches['version'], 'mbstring oniguruma version'); } break; @@ -403,7 +407,7 @@ protected function initialize(): void // libmemcached version => 1.0.18 if (Preg::isMatch('/^libmemcached version => (?.+)$/im', $info, $matches)) { - $this->addLibrary($name.'-libmemcached', $matches['version'], 'libmemcached version'); + $this->addLibrary($libraries, $name.'-libmemcached', $matches['version'], 'libmemcached version'); } break; @@ -411,18 +415,18 @@ protected function initialize(): void // OpenSSL 1.1.1g 21 Apr 2020 if (Preg::isMatchStrictGroups('{^(?:OpenSSL|LibreSSL)?\s*(?\S+)}i', $this->runtime->getConstant('OPENSSL_VERSION_TEXT'), $matches)) { $parsedVersion = Version::parseOpenssl($matches['version'], $isFips); - $this->addLibrary($name.($isFips ? '-fips' : ''), $parsedVersion, $this->runtime->getConstant('OPENSSL_VERSION_TEXT'), [], $isFips ? [$name] : []); + $this->addLibrary($libraries, $name.($isFips ? '-fips' : ''), $parsedVersion, $this->runtime->getConstant('OPENSSL_VERSION_TEXT'), [], $isFips ? [$name] : []); } break; case 'pcre': - $this->addLibrary($name, Preg::replace('{^(\S+).*}', '$1', $this->runtime->getConstant('PCRE_VERSION'))); + $this->addLibrary($libraries, $name, Preg::replace('{^(\S+).*}', '$1', $this->runtime->getConstant('PCRE_VERSION'))); $info = $this->runtime->getExtensionInfo($name); // PCRE Unicode Version => 12.1.0 if (Preg::isMatchStrictGroups('/^PCRE Unicode Version => (?.+)$/im', $info, $pcreUnicodeMatches)) { - $this->addLibrary($name.'-unicode', $pcreUnicodeMatches['version'], 'PCRE Unicode version support'); + $this->addLibrary($libraries, $name.'-unicode', $pcreUnicodeMatches['version'], 'PCRE Unicode version support'); } break; @@ -432,7 +436,7 @@ protected function initialize(): void $info = $this->runtime->getExtensionInfo($name); if (Preg::isMatchStrictGroups('/^(?:Client API version|Version) => mysqlnd (?.+?) /mi', $info, $matches)) { - $this->addLibrary($name.'-mysqlnd', $matches['version'], 'mysqlnd library version for '.$name); + $this->addLibrary($libraries, $name.'-mysqlnd', $matches['version'], 'mysqlnd library version for '.$name); } break; @@ -440,17 +444,17 @@ protected function initialize(): void $info = $this->runtime->getExtensionInfo($name); if (Preg::isMatchStrictGroups('/^libmongoc bundled version => (?.+)$/im', $info, $libmongocMatches)) { - $this->addLibrary($name.'-libmongoc', $libmongocMatches['version'], 'libmongoc version of mongodb'); + $this->addLibrary($libraries, $name.'-libmongoc', $libmongocMatches['version'], 'libmongoc version of mongodb'); } if (Preg::isMatchStrictGroups('/^libbson bundled version => (?.+)$/im', $info, $libbsonMatches)) { - $this->addLibrary($name.'-libbson', $libbsonMatches['version'], 'libbson version of mongodb'); + $this->addLibrary($libraries, $name.'-libbson', $libbsonMatches['version'], 'libbson version of mongodb'); } break; case 'pgsql': if ($this->runtime->hasConstant('PGSQL_LIBPQ_VERSION')) { - $this->addLibrary('pgsql-libpq', $this->runtime->getConstant('PGSQL_LIBPQ_VERSION'), 'libpq for pgsql'); + $this->addLibrary($libraries, 'pgsql-libpq', $this->runtime->getConstant('PGSQL_LIBPQ_VERSION'), 'libpq for pgsql'); break; } // intentional fall-through to next case... @@ -459,7 +463,7 @@ protected function initialize(): void $info = $this->runtime->getExtensionInfo($name); if (Preg::isMatch('/^PostgreSQL\(libpq\) Version => (?.*)$/im', $info, $matches)) { - $this->addLibrary($name.'-libpq', $matches['version'], 'libpq for '.$name); + $this->addLibrary($libraries, $name.'-libpq', $matches['version'], 'libpq for '.$name); } break; @@ -469,7 +473,7 @@ protected function initialize(): void // Used Library => Compiled => Linked // libpq => 14.3 (Ubuntu 14.3-1.pgdg22.04+1) => 15.0.2 if (Preg::isMatch('/^libpq => (?.+) => (?.+)$/im', $info, $matches)) { - $this->addLibrary($name.'-libpq', $matches['linked'], 'libpq for '.$name); + $this->addLibrary($libraries, $name.'-libpq', $matches['linked'], 'libpq for '.$name); } break; @@ -485,14 +489,15 @@ protected function initialize(): void * pre-release ID in practice is always 0xff even for RCs etc, so we ignore it */ $libRdKafkaVersionInt = $this->runtime->getConstant('RD_KAFKA_VERSION'); - $this->addLibrary($name.'-librdkafka', sprintf('%d.%d.%d', ($libRdKafkaVersionInt & 0xFF000000) >> 24, ($libRdKafkaVersionInt & 0x00FF0000) >> 16, ($libRdKafkaVersionInt & 0x0000FF00) >> 8), 'librdkafka for '.$name); + $this->addLibrary($libraries, $name.'-librdkafka', sprintf('%d.%d.%d', ($libRdKafkaVersionInt & 0xFF000000) >> 24, ($libRdKafkaVersionInt & 0x00FF0000) >> 16, ($libRdKafkaVersionInt & 0x0000FF00) >> 8), 'librdkafka for '.$name); } break; case 'libsodium': case 'sodium': if ($this->runtime->hasConstant('SODIUM_LIBRARY_VERSION')) { - $this->addLibrary('libsodium', $this->runtime->getConstant('SODIUM_LIBRARY_VERSION')); + $this->addLibrary($libraries, 'libsodium', $this->runtime->getConstant('SODIUM_LIBRARY_VERSION')); + $this->addLibrary($libraries, 'libsodium', $this->runtime->getConstant('SODIUM_LIBRARY_VERSION')); } break; @@ -501,7 +506,7 @@ protected function initialize(): void $info = $this->runtime->getExtensionInfo($name); if (Preg::isMatch('/^SQLite Library => (?.+)$/im', $info, $matches)) { - $this->addLibrary($name.'-sqlite', $matches['version']); + $this->addLibrary($libraries, $name.'-sqlite', $matches['version']); } break; @@ -509,16 +514,16 @@ protected function initialize(): void $info = $this->runtime->getExtensionInfo($name); if (Preg::isMatch('/^libssh2 version => (?.+)$/im', $info, $matches)) { - $this->addLibrary($name.'-libssh2', $matches['version']); + $this->addLibrary($libraries, $name.'-libssh2', $matches['version']); } break; case 'xsl': - $this->addLibrary('libxslt', $this->runtime->getConstant('LIBXSLT_DOTTED_VERSION'), null, ['xsl']); + $this->addLibrary($libraries, 'libxslt', $this->runtime->getConstant('LIBXSLT_DOTTED_VERSION'), null, ['xsl']); $info = $this->runtime->getExtensionInfo('xsl'); if (Preg::isMatch('/^libxslt compiled against libxml Version => (?.+)$/im', $info, $matches)) { - $this->addLibrary('libxslt-libxml', $matches['version'], 'libxml version libxslt is compiled against'); + $this->addLibrary($libraries, 'libxslt-libxml', $matches['version'], 'libxml version libxslt is compiled against'); } break; @@ -526,23 +531,23 @@ protected function initialize(): void $info = $this->runtime->getExtensionInfo('yaml'); if (Preg::isMatch('/^LibYAML Version => (?.+)$/im', $info, $matches)) { - $this->addLibrary($name.'-libyaml', $matches['version'], 'libyaml version of yaml'); + $this->addLibrary($libraries, $name.'-libyaml', $matches['version'], 'libyaml version of yaml'); } break; case 'zip': if ($this->runtime->hasConstant('LIBZIP_VERSION', 'ZipArchive')) { - $this->addLibrary($name.'-libzip', $this->runtime->getConstant('LIBZIP_VERSION', 'ZipArchive'), null, ['zip']); + $this->addLibrary($libraries, $name.'-libzip', $this->runtime->getConstant('LIBZIP_VERSION', 'ZipArchive'), null, ['zip']); } break; case 'zlib': if ($this->runtime->hasConstant('ZLIB_VERSION')) { - $this->addLibrary($name, $this->runtime->getConstant('ZLIB_VERSION')); + $this->addLibrary($libraries, $name, $this->runtime->getConstant('ZLIB_VERSION')); // Linked Version => 1.2.8 } elseif (Preg::isMatch('/^Linked Version => (?.+)$/im', $this->runtime->getExtensionInfo($name), $matches)) { - $this->addLibrary($name, $matches['version']); + $this->addLibrary($libraries, $name, $matches['version']); } break; @@ -661,6 +666,7 @@ private function addExtension(string $name, string $prettyVersion): void $packageName = $this->buildPackageName($name); $ext = new CompletePackage($packageName, $version, $prettyVersion); $ext->setDescription('The '.$name.' PHP extension'.$extraDescription); + $ext->setType('php-ext'); if ($name === 'uuid') { $ext->setReplaces([ @@ -677,10 +683,11 @@ private function buildPackageName(string $name): string } /** - * @param string[] $replaces - * @param string[] $provides + * @param array $libraries + * @param array $replaces + * @param array $provides */ - private function addLibrary(string $name, ?string $prettyVersion, ?string $description = null, array $replaces = [], array $provides = []): void + private function addLibrary(array &$libraries, string $name, ?string $prettyVersion, ?string $description = null, array $replaces = [], array $provides = []): void { if (null === $prettyVersion) { return; @@ -691,6 +698,13 @@ private function addLibrary(string $name, ?string $prettyVersion, ?string $descr return; } + // avoid adding the same lib twice even if two conflicting extensions provide the same lib + // see https://github.com/composer/composer/issues/12082 + if (isset($libraries['lib-'.$name])) { + return; + } + $libraries['lib-'.$name] = true; + if ($description === null) { $description = 'The '.$name.' library'; } diff --git a/vendor/composer/composer/src/Composer/Repository/RepositoryFactory.php b/vendor/composer/composer/src/Composer/Repository/RepositoryFactory.php index 62e9183..52da0d6 100644 --- a/vendor/composer/composer/src/Composer/Repository/RepositoryFactory.php +++ b/vendor/composer/composer/src/Composer/Repository/RepositoryFactory.php @@ -178,7 +178,7 @@ private static function createRepos(RepositoryManager $rm, array $repoConfigs): /** * @param int|string $index * @param array{url?: string} $repo - * @param array $existingRepos + * @param array $existingRepos */ public static function generateRepositoryName($index, array $repo, array $existingRepos): string { diff --git a/vendor/composer/composer/src/Composer/Repository/RepositoryInterface.php b/vendor/composer/composer/src/Composer/Repository/RepositoryInterface.php index c262488..3bcb1ea 100644 --- a/vendor/composer/composer/src/Composer/Repository/RepositoryInterface.php +++ b/vendor/composer/composer/src/Composer/Repository/RepositoryInterface.php @@ -72,12 +72,13 @@ public function getPackages(); * - The namesFound returned are names which should be considered as canonically found in this repository, that should not be looked up in any further lower priority repositories * * @param ConstraintInterface[] $packageNameMap package names pointing to constraints - * @param array $acceptableStabilities array of stability => BasePackage::STABILITY_* value + * @param array $acceptableStabilities array of stability => BasePackage::STABILITY_* value * @param array $stabilityFlags an array of package name => BasePackage::STABILITY_* value * @param array> $alreadyLoaded an array of package name => package version => package * * @return array * + * @phpstan-param array, BasePackage::STABILITY_*> $acceptableStabilities * @phpstan-param array $packageNameMap * @phpstan-return array{namesFound: array, packages: array} */ diff --git a/vendor/composer/composer/src/Composer/Repository/RepositorySet.php b/vendor/composer/composer/src/Composer/Repository/RepositorySet.php index 48cf424..96c0c00 100644 --- a/vendor/composer/composer/src/Composer/Repository/RepositorySet.php +++ b/vendor/composer/composer/src/Composer/Repository/RepositorySet.php @@ -65,7 +65,7 @@ class RepositorySet /** * @var int[] array of stability => BasePackage::STABILITY_* value - * @phpstan-var array + * @phpstan-var array, BasePackage::STABILITY_*> */ private $acceptableStabilities; @@ -96,6 +96,7 @@ class RepositorySet * passing minimumStability is all you need to worry about. The rest is for advanced pool creation including * aliases, pinned references and other special cases. * + * @param key-of $minimumStability * @param int[] $stabilityFlags an array of package name => BasePackage::STABILITY_* value * @phpstan-param array $stabilityFlags * @param array[] $rootAliases @@ -112,8 +113,8 @@ public function __construct(string $minimumStability = 'stable', array $stabilit $this->rootReferences = $rootReferences; $this->acceptableStabilities = []; - foreach (BasePackage::$stabilities as $stability => $value) { - if ($value <= BasePackage::$stabilities[$minimumStability]) { + foreach (BasePackage::STABILITIES as $stability => $value) { + if ($value <= BasePackage::STABILITIES[$minimumStability]) { $this->acceptableStabilities[$stability] = $value; } } @@ -195,7 +196,7 @@ public function findPackages(string $name, ?ConstraintInterface $constraint = nu } } else { foreach ($this->repositories as $repository) { - $result = $repository->loadPackages([$name => $constraint], $ignoreStability ? BasePackage::$stabilities : $this->acceptableStabilities, $ignoreStability ? [] : $this->stabilityFlags); + $result = $repository->loadPackages([$name => $constraint], $ignoreStability ? BasePackage::STABILITIES : $this->acceptableStabilities, $ignoreStability ? [] : $this->stabilityFlags); $packages[] = $result['packages']; foreach ($result['namesFound'] as $nameFound) { @@ -300,8 +301,8 @@ public function getProviders(string $packageName): array /** * Check for each given package name whether it would be accepted by this RepositorySet in the given $stability * - * @param string[] $names - * @param string $stability one of 'stable', 'RC', 'beta', 'alpha' or 'dev' + * @param string[] $names + * @param key-of $stability one of 'stable', 'RC', 'beta', 'alpha' or 'dev' */ public function isPackageAcceptable(array $names, string $stability): bool { @@ -310,10 +311,15 @@ public function isPackageAcceptable(array $names, string $stability): bool /** * Create a pool for dependency resolution from the packages in this repository set. + * + * @param list $ignoredTypes Packages of those types are ignored + * @param list|null $allowedTypes Only packages of those types are allowed if set to non-null */ - public function createPool(Request $request, IOInterface $io, ?EventDispatcher $eventDispatcher = null, ?PoolOptimizer $poolOptimizer = null): Pool + public function createPool(Request $request, IOInterface $io, ?EventDispatcher $eventDispatcher = null, ?PoolOptimizer $poolOptimizer = null, array $ignoredTypes = [], ?array $allowedTypes = null): Pool { $poolBuilder = new PoolBuilder($this->acceptableStabilities, $this->stabilityFlags, $this->rootAliases, $this->rootReferences, $io, $eventDispatcher, $poolOptimizer, $this->temporaryConstraints); + $poolBuilder->setIgnoredTypes($ignoredTypes); + $poolBuilder->setAllowedTypes($allowedTypes); foreach ($this->repositories as $repo) { if (($repo instanceof InstalledRepositoryInterface || $repo instanceof InstalledRepository) && !$this->allowInstalledRepositories) { diff --git a/vendor/composer/composer/src/Composer/Repository/RepositoryUtils.php b/vendor/composer/composer/src/Composer/Repository/RepositoryUtils.php index 62e1c5b..e6960c6 100644 --- a/vendor/composer/composer/src/Composer/Repository/RepositoryUtils.php +++ b/vendor/composer/composer/src/Composer/Repository/RepositoryUtils.php @@ -24,23 +24,28 @@ class RepositoryUtils /** * Find all of $packages which are required by $requirer, either directly or transitively * - * Require-dev is ignored + * Require-dev is ignored by default, you can enable the require-dev of the initial $requirer + * packages by passing $includeRequireDev=true, but require-dev of transitive dependencies + * are always ignored. * * @template T of PackageInterface * @param array $packages * @param list $bucket Do not pass this in, only used to avoid recursion with circular deps * @return list */ - public static function filterRequiredPackages(array $packages, PackageInterface $requirer, array $bucket = []): array + public static function filterRequiredPackages(array $packages, PackageInterface $requirer, bool $includeRequireDev = false, array $bucket = []): array { $requires = $requirer->getRequires(); + if ($includeRequireDev) { + $requires = array_merge($requires, $requirer->getDevRequires()); + } foreach ($packages as $candidate) { foreach ($candidate->getNames() as $name) { if (isset($requires[$name])) { if (!in_array($candidate, $bucket, true)) { $bucket[] = $candidate; - $bucket = self::filterRequiredPackages($packages, $candidate, $bucket); + $bucket = self::filterRequiredPackages($packages, $candidate, false, $bucket); } break; } diff --git a/vendor/composer/composer/src/Composer/Repository/Vcs/GitDriver.php b/vendor/composer/composer/src/Composer/Repository/Vcs/GitDriver.php index 75ede69..f3f7a91 100644 --- a/vendor/composer/composer/src/Composer/Repository/Vcs/GitDriver.php +++ b/vendor/composer/composer/src/Composer/Repository/Vcs/GitDriver.php @@ -52,7 +52,7 @@ public function initialize(): void throw new \RuntimeException('GitDriver requires a usable cache directory, and it looks like you set it to be disabled'); } - $this->repoDir = $this->config->get('cache-vcs-dir') . '/' . Preg::replace('{[^a-z0-9.]}i', '-', $this->url) . '/'; + $this->repoDir = $this->config->get('cache-vcs-dir') . '/' . Preg::replace('{[^a-z0-9.]}i', '-', Url::sanitize($this->url)) . '/'; GitUtil::cleanEnv(); @@ -153,7 +153,7 @@ public function getFileContent(string $file, string $identifier): ?string $resource = sprintf('%s:%s', ProcessExecutor::escape($identifier), ProcessExecutor::escape($file)); $this->process->execute(sprintf('git show %s', $resource), $content, $this->repoDir); - if (!trim($content)) { + if (trim($content) === '') { return null; } @@ -182,9 +182,9 @@ public function getTags(): array $this->tags = []; $this->process->execute('git show-ref --tags --dereference', $output, $this->repoDir); - foreach ($output = $this->process->splitLines($output) as $tag) { - if ($tag && Preg::isMatch('{^([a-f0-9]{40}) refs/tags/(\S+?)(\^\{\})?$}', $tag, $match)) { - $this->tags[$match[2]] = (string) $match[1]; + foreach ($this->process->splitLines($output) as $tag) { + if ($tag !== '' && Preg::isMatch('{^([a-f0-9]{40}) refs/tags/(\S+?)(\^\{\})?$}', $tag, $match)) { + $this->tags[$match[2]] = $match[1]; } } } @@ -202,7 +202,7 @@ public function getBranches(): array $this->process->execute('git branch --no-color --no-abbrev -v', $output, $this->repoDir); foreach ($this->process->splitLines($output) as $branch) { - if ($branch && !Preg::isMatch('{^ *[^/]+/HEAD }', $branch)) { + if ($branch !== '' && !Preg::isMatch('{^ *[^/]+/HEAD }', $branch)) { if (Preg::isMatchStrictGroups('{^(?:\* )? *(\S+) *([a-f0-9]+)(?: .*)?$}', $branch, $match) && $match[1][0] !== '-') { $branches[$match[1]] = $match[2]; } diff --git a/vendor/composer/composer/src/Composer/Repository/Vcs/GitHubDriver.php b/vendor/composer/composer/src/Composer/Repository/Vcs/GitHubDriver.php index 44766a1..09beb76 100644 --- a/vendor/composer/composer/src/Composer/Repository/Vcs/GitHubDriver.php +++ b/vendor/composer/composer/src/Composer/Repository/Vcs/GitHubDriver.php @@ -63,8 +63,6 @@ public function initialize(): void throw new \InvalidArgumentException(sprintf('The GitHub repository URL %s is invalid.', $this->url)); } - assert(is_string($match[3])); - assert(is_string($match[4])); $this->owner = $match[3]; $this->repository = $match[4]; $this->originUrl = strtolower($match[1] ?? (string) $match[2]); @@ -286,6 +284,9 @@ private function getFundingInfo() case 'community_bridge': $result[$key]['url'] = 'https://funding.communitybridge.org/projects/' . basename($item['url']); break; + case 'buy_me_a_coffee': + $result[$key]['url'] = 'https://www.buymeacoffee.com/' . basename($item['url']); + break; } } diff --git a/vendor/composer/composer/src/Composer/Repository/Vcs/GitLabDriver.php b/vendor/composer/composer/src/Composer/Repository/Vcs/GitLabDriver.php index 3721419..09fb425 100644 --- a/vendor/composer/composer/src/Composer/Repository/Vcs/GitLabDriver.php +++ b/vendor/composer/composer/src/Composer/Repository/Vcs/GitLabDriver.php @@ -97,8 +97,6 @@ public function initialize(): void throw new \InvalidArgumentException(sprintf('The GitLab repository URL %s is invalid. It must be the HTTP URL of a GitLab project.', $this->url)); } - assert(is_string($match['parts'])); - assert(is_string($match['repo'])); $guessedDomain = $match['domain'] ?? (string) $match['domain2']; $configuredDomains = $this->config->get('gitlab-domains'); $urlParts = explode('/', $match['parts']); @@ -109,13 +107,13 @@ public function initialize(): void ; $origin = self::determineOrigin($configuredDomains, $guessedDomain, $urlParts, $match['port']); if (false === $origin) { - throw new \LogicException('It should not be possible to create a gitlab driver with an unparseable origin URL ('.$this->url.')'); + throw new \LogicException('It should not be possible to create a gitlab driver with an unparsable origin URL ('.$this->url.')'); } $this->originUrl = $origin; if (is_string($protocol = $this->config->get('gitlab-protocol'))) { // https treated as a synonym for http. - if (!in_array($protocol, ['git', 'http', 'https'])) { + if (!in_array($protocol, ['git', 'http', 'https'], true)) { throw new \RuntimeException('gitlab-protocol must be one of git, http.'); } $this->protocol = $protocol === 'git' ? 'ssh' : 'http'; @@ -566,8 +564,6 @@ public static function supports(IOInterface $io, Config $config, string $url, bo return false; } - assert(is_string($match['parts'])); - assert(is_string($match['repo'])); $scheme = $match['scheme']; $guessedDomain = $match['domain'] ?? (string) $match['domain2']; $urlParts = explode('/', $match['parts']); diff --git a/vendor/composer/composer/src/Composer/Repository/Vcs/HgDriver.php b/vendor/composer/composer/src/Composer/Repository/Vcs/HgDriver.php index e70b9a6..e468ca7 100644 --- a/vendor/composer/composer/src/Composer/Repository/Vcs/HgDriver.php +++ b/vendor/composer/composer/src/Composer/Repository/Vcs/HgDriver.php @@ -19,6 +19,7 @@ use Composer\Util\ProcessExecutor; use Composer\Util\Filesystem; use Composer\IO\IOInterface; +use Composer\Util\Url; /** * @author Per Bernhardt @@ -47,7 +48,7 @@ public function initialize(): void } $cacheDir = $this->config->get('cache-vcs-dir'); - $this->repoDir = $cacheDir . '/' . Preg::replace('{[^a-z0-9]}i', '-', $this->url) . '/'; + $this->repoDir = $cacheDir . '/' . Preg::replace('{[^a-z0-9]}i', '-', Url::sanitize($this->url)) . '/'; $fs = new Filesystem(); $fs->ensureDirectoryExists($cacheDir); diff --git a/vendor/composer/composer/src/Composer/Repository/Vcs/SvnDriver.php b/vendor/composer/composer/src/Composer/Repository/Vcs/SvnDriver.php index ea8158e..d4f3180 100644 --- a/vendor/composer/composer/src/Composer/Repository/Vcs/SvnDriver.php +++ b/vendor/composer/composer/src/Composer/Repository/Vcs/SvnDriver.php @@ -177,8 +177,7 @@ public function getFileContent(string $file, string $identifier): ?string { $identifier = '/' . trim($identifier, '/') . '/'; - Preg::match('{^(.+?)(@\d+)?/$}', $identifier, $match); - if (!empty($match[2])) { + if (Preg::isMatch('{^(.+?)(@\d+)?/$}', $identifier, $match) && $match[2] !== null) { $path = $match[1]; $rev = $match[2]; } else { @@ -189,7 +188,7 @@ public function getFileContent(string $file, string $identifier): ?string try { $resource = $path.$file; $output = $this->execute('svn cat', $this->baseUrl . $resource . $rev); - if (!trim($output)) { + if ('' === trim($output)) { return null; } } catch (\RuntimeException $e) { @@ -206,8 +205,7 @@ public function getChangeDate(string $identifier): ?\DateTimeImmutable { $identifier = '/' . trim($identifier, '/') . '/'; - Preg::match('{^(.+?)(@\d+)?/$}', $identifier, $match); - if (null !== $match[2] && null !== $match[1]) { + if (Preg::isMatch('{^(.+?)(@\d+)?/$}', $identifier, $match) && null !== $match[2]) { $path = $match[1]; $rev = $match[2]; } else { @@ -217,7 +215,7 @@ public function getChangeDate(string $identifier): ?\DateTimeImmutable $output = $this->execute('svn info', $this->baseUrl . $path . $rev); foreach ($this->process->splitLines($output) as $line) { - if ($line && Preg::isMatchStrictGroups('{^Last Changed Date: ([^(]+)}', $line, $match)) { + if ($line !== '' && Preg::isMatchStrictGroups('{^Last Changed Date: ([^(]+)}', $line, $match)) { return new \DateTimeImmutable($match[1], new \DateTimeZone('UTC')); } } @@ -235,20 +233,18 @@ public function getTags(): array if ($this->tagsPath !== false) { $output = $this->execute('svn ls --verbose', $this->baseUrl . '/' . $this->tagsPath); - if ($output) { + if ($output !== '') { $lastRev = 0; foreach ($this->process->splitLines($output) as $line) { $line = trim($line); - if ($line && Preg::isMatch('{^\s*(\S+).*?(\S+)\s*$}', $line, $match)) { - if (isset($match[1], $match[2])) { - if ($match[2] === './') { - $lastRev = (int) $match[1]; - } else { - $tags[rtrim($match[2], '/')] = $this->buildIdentifier( - '/' . $this->tagsPath . '/' . $match[2], - max($lastRev, (int) $match[1]) - ); - } + if ($line !== '' && Preg::isMatch('{^\s*(\S+).*?(\S+)\s*$}', $line, $match)) { + if ($match[2] === './') { + $lastRev = (int) $match[1]; + } else { + $tags[rtrim($match[2], '/')] = $this->buildIdentifier( + '/' . $this->tagsPath . '/' . $match[2], + max($lastRev, (int) $match[1]) + ); } } } @@ -276,11 +272,11 @@ public function getBranches(): array } $output = $this->execute('svn ls --verbose', $trunkParent); - if ($output) { + if ($output !== '') { foreach ($this->process->splitLines($output) as $line) { $line = trim($line); - if ($line && Preg::isMatch('{^\s*(\S+).*?(\S+)\s*$}', $line, $match)) { - if (isset($match[1], $match[2]) && $match[2] === './') { + if ($line !== '' && Preg::isMatch('{^\s*(\S+).*?(\S+)\s*$}', $line, $match)) { + if ($match[2] === './') { $branches['trunk'] = $this->buildIdentifier( '/' . $this->trunkPath, (int) $match[1] @@ -295,20 +291,18 @@ public function getBranches(): array if ($this->branchesPath !== false) { $output = $this->execute('svn ls --verbose', $this->baseUrl . '/' . $this->branchesPath); - if ($output) { + if ($output !== '') { $lastRev = 0; foreach ($this->process->splitLines(trim($output)) as $line) { $line = trim($line); - if ($line && Preg::isMatch('{^\s*(\S+).*?(\S+)\s*$}', $line, $match)) { - if (isset($match[1], $match[2])) { - if ($match[2] === './') { - $lastRev = (int) $match[1]; - } else { - $branches[rtrim($match[2], '/')] = $this->buildIdentifier( - '/' . $this->branchesPath . '/' . $match[2], - max($lastRev, (int) $match[1]) - ); - } + if ($line !== '' && Preg::isMatch('{^\s*(\S+).*?(\S+)\s*$}', $line, $match)) { + if ($match[2] === './') { + $lastRev = (int) $match[1]; + } else { + $branches[rtrim($match[2], '/')] = $this->buildIdentifier( + '/' . $this->branchesPath . '/' . $match[2], + max($lastRev, (int) $match[1]) + ); } } } diff --git a/vendor/composer/composer/src/Composer/Repository/VcsRepository.php b/vendor/composer/composer/src/Composer/Repository/VcsRepository.php index d10ad87..a5b17b5 100644 --- a/vendor/composer/composer/src/Composer/Repository/VcsRepository.php +++ b/vendor/composer/composer/src/Composer/Repository/VcsRepository.php @@ -217,11 +217,6 @@ protected function initialize() foreach ($driver->getTags() as $tag => $identifier) { $tag = (string) $tag; $msg = 'Reading composer.json of ' . ($this->packageName ?: $this->url) . ' (' . $tag . ')'; - if ($isVeryVerbose) { - $this->io->writeError($msg); - } elseif ($isVerbose) { - $this->io->overwriteError($msg, false); - } // strip the release- prefix from tags if present $tag = str_replace('release-', '', $tag); @@ -245,6 +240,12 @@ protected function initialize() continue; } + if ($isVeryVerbose) { + $this->io->writeError($msg); + } elseif ($isVerbose) { + $this->io->overwriteError($msg, false); + } + try { $data = $driver->getComposerInformation($identifier); if (null === $data) { @@ -341,7 +342,8 @@ protected function initialize() // make sure branch packages have a dev flag if (strpos($parsedBranch, 'dev-') === 0 || VersionParser::DEFAULT_BRANCH_ALIAS === $parsedBranch) { - $version = 'dev-' . $branch; + $version = 'dev-' . str_replace('#', '+', $branch); + $parsedBranch = str_replace('#', '+', $parsedBranch); } else { $prefix = strpos($branch, 'v') === 0 ? 'v' : ''; $version = $prefix . Preg::replace('{(\.9{7})+}', '.x', $parsedBranch); diff --git a/vendor/composer/composer/src/Composer/SelfUpdate/Versions.php b/vendor/composer/composer/src/Composer/SelfUpdate/Versions.php index 045fb22..8cc7d45 100644 --- a/vendor/composer/composer/src/Composer/SelfUpdate/Versions.php +++ b/vendor/composer/composer/src/Composer/SelfUpdate/Versions.php @@ -89,7 +89,7 @@ public function getLatest(?string $channel = null): array $versions = $this->getVersionsData(); foreach ($versions[$channel ?: $this->getChannel()] as $version) { - if ($version['min-php'] <= PHP_VERSION_ID) { + if ($version['min-php'] <= \PHP_VERSION_ID) { return $version; } } diff --git a/vendor/composer/composer/src/Composer/Util/ComposerMirror.php b/vendor/composer/composer/src/Composer/Util/ComposerMirror.php index 106e76c..6be5396 100644 --- a/vendor/composer/composer/src/Composer/Util/ComposerMirror.php +++ b/vendor/composer/composer/src/Composer/Util/ComposerMirror.php @@ -28,9 +28,9 @@ class ComposerMirror public static function processUrl(string $mirrorUrl, string $packageName, string $version, ?string $reference, ?string $type, ?string $prettyVersion = null): string { if ($reference) { - $reference = Preg::isMatch('{^([a-f0-9]*|%reference%)$}', $reference) ? $reference : md5($reference); + $reference = Preg::isMatch('{^([a-f0-9]*|%reference%)$}', $reference) ? $reference : hash('md5', $reference); } - $version = strpos($version, '/') === false ? $version : md5($version); + $version = strpos($version, '/') === false ? $version : hash('md5', $version); $from = ['%package%', '%version%', '%reference%', '%type%']; $to = [$packageName, $version, $reference, $type]; diff --git a/vendor/composer/composer/src/Composer/Util/ErrorHandler.php b/vendor/composer/composer/src/Composer/Util/ErrorHandler.php index 4ed0cfe..d06b577 100644 --- a/vendor/composer/composer/src/Composer/Util/ErrorHandler.php +++ b/vendor/composer/composer/src/Composer/Util/ErrorHandler.php @@ -40,7 +40,7 @@ public static function handle(int $level, string $message, string $file, int $li $isDeprecationNotice = $level === E_DEPRECATED || $level === E_USER_DEPRECATED; // error code is not included in error_reporting - if (!$isDeprecationNotice && !(error_reporting() & $level)) { + if (!$isDeprecationNotice && 0 === (error_reporting() & $level)) { return true; } @@ -53,7 +53,7 @@ public static function handle(int $level, string $message, string $file, int $li throw new \ErrorException($message, 0, $level, $file, $line); } - if (self::$io) { + if (self::$io !== null) { self::$io->writeError('Deprecation Notice: '.$message.' in '.$file.':'.$line.''); if (self::$io->isVerbose()) { self::$io->writeError('Stack trace:'); @@ -63,7 +63,9 @@ public static function handle(int $level, string $message, string $file, int $li } return null; - }, array_slice(debug_backtrace(), 2)))); + }, array_slice(debug_backtrace(), 2)), function (?string $line) { + return $line !== null; + })); } } @@ -76,7 +78,7 @@ public static function handle(int $level, string $message, string $file, int $li public static function register(?IOInterface $io = null): void { set_error_handler([__CLASS__, 'handle']); - error_reporting(E_ALL | E_STRICT); + error_reporting(E_ALL); self::$io = $io; } } diff --git a/vendor/composer/composer/src/Composer/Util/Filesystem.php b/vendor/composer/composer/src/Composer/Util/Filesystem.php index ad0aae9..099747a 100644 --- a/vendor/composer/composer/src/Composer/Util/Filesystem.php +++ b/vendor/composer/composer/src/Composer/Util/Filesystem.php @@ -13,6 +13,7 @@ namespace Composer\Util; use Composer\Pcre\Preg; +use ErrorException; use React\Promise\PromiseInterface; use RecursiveDirectoryIterator; use RecursiveIteratorIterator; @@ -367,7 +368,29 @@ public function copy(string $source, string $target) $target = $this->normalizePath($target); if (!is_dir($source)) { - return copy($source, $target); + try { + return copy($source, $target); + } catch (ErrorException $e) { + // if copy fails we attempt to copy it manually as this can help bypass issues with VirtualBox shared folders + // see https://github.com/composer/composer/issues/12057 + if (str_contains($e->getMessage(), 'Bad address')) { + $sourceHandle = fopen($source, 'r'); + $targetHandle = fopen($target, 'w'); + if (false === $sourceHandle || false === $targetHandle) { + throw $e; + } + while (!feof($sourceHandle)) { + if (false === fwrite($targetHandle, (string) fread($sourceHandle, 1024 * 1024))) { + throw $e; + } + } + fclose($sourceHandle); + fclose($targetHandle); + + return true; + } + throw $e; + } } $it = new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS); @@ -436,10 +459,11 @@ public function rename(string $source, string $target) * Returns the shortest path from $from to $to * * @param bool $directories if true, the source/target are considered to be directories + * @param bool $preferRelative if true, relative paths will be preferred even if longer * @throws \InvalidArgumentException * @return string */ - public function findShortestPath(string $from, string $to, bool $directories = false) + public function findShortestPath(string $from, string $to, bool $directories = false, bool $preferRelative = false) { if (!$this->isAbsolutePath($from) || !$this->isAbsolutePath($to)) { throw new \InvalidArgumentException(sprintf('$from (%s) and $to (%s) must be absolute paths.', $from, $to)); @@ -471,7 +495,7 @@ public function findShortestPath(string $from, string $to, bool $directories = f $commonPathCode = str_repeat('../', $sourcePathDepth); // allow top level /foo & /bar dirs to be addressed relatively as this is common in Docker setups - if ('/' === $commonPath && $sourcePathDepth > 1) { + if (!$preferRelative && '/' === $commonPath && $sourcePathDepth > 1) { return $to; } @@ -487,10 +511,11 @@ public function findShortestPath(string $from, string $to, bool $directories = f * Returns PHP code that, when executed in $from, will return the path to $to * * @param bool $directories if true, the source/target are considered to be directories + * @param bool $preferRelative if true, relative paths will be preferred even if longer * @throws \InvalidArgumentException * @return string */ - public function findShortestPathCode(string $from, string $to, bool $directories = false, bool $staticCode = false) + public function findShortestPathCode(string $from, string $to, bool $directories = false, bool $staticCode = false, bool $preferRelative = false) { if (!$this->isAbsolutePath($from) || !$this->isAbsolutePath($to)) { throw new \InvalidArgumentException(sprintf('$from (%s) and $to (%s) must be absolute paths.', $from, $to)); @@ -520,7 +545,7 @@ public function findShortestPathCode(string $from, string $to, bool $directories $sourcePathDepth = substr_count((string) substr($from, \strlen($commonPath)), '/') + (int) $directories; // allow top level /foo & /bar dirs to be addressed relatively as this is common in Docker setups - if ('/' === $commonPath && $sourcePathDepth > 1) { + if (!$preferRelative && '/' === $commonPath && $sourcePathDepth > 1) { return var_export($to, true); } @@ -608,7 +633,6 @@ public function normalizePath(string $path) // ensure c: is normalized to C: $prefix = Preg::replaceCallback('{(^|://)[a-z]:$}i', static function (array $m) { - assert(is_string($m[0])); return strtoupper($m[0]); }, $prefix); @@ -638,7 +662,13 @@ public static function trimTrailingSlash(string $path) */ public static function isLocalPath(string $path) { - return Preg::isMatch('{^(file://(?!//)|/(?!/)|/?[a-z]:[\\\\/]|\.\.[\\\\/]|[a-z0-9_.-]+[\\\\/])}i', $path); + // on windows, \\foo indicates network paths so we exclude those from local paths, however it is unsafe + // on linux as file:////foo (which would be a network path \\foo on windows) will resolve to /foo which could be a local path + if (Platform::isWindows()) { + return Preg::isMatch('{^(file://(?!//)|/(?!/)|/?[a-z]:[\\\\/]|\.\.[\\\\/]|[a-z0-9_.-]+[\\\\/])}i', $path); + } + + return Preg::isMatch('{^(file://|/|/?[a-z]:[\\\\/]|\.\.[\\\\/]|[a-z0-9_.-]+[\\\\/])}i', $path); } /** diff --git a/vendor/composer/composer/src/Composer/Util/Git.php b/vendor/composer/composer/src/Composer/Util/Git.php index 67af22e..58df0ad 100644 --- a/vendor/composer/composer/src/Composer/Util/Git.php +++ b/vendor/composer/composer/src/Composer/Util/Git.php @@ -32,6 +32,8 @@ class Git protected $process; /** @var Filesystem */ protected $filesystem; + /** @var HttpDownloader */ + protected $httpDownloader; public function __construct(IOInterface $io, Config $config, ProcessExecutor $process, Filesystem $fs) { @@ -41,6 +43,11 @@ public function __construct(IOInterface $io, Config $config, ProcessExecutor $pr $this->filesystem = $fs; } + public function setHttpDownloader(HttpDownloader $httpDownloader): void + { + $this->httpDownloader = $httpDownloader; + } + /** * @param mixed $commandOutput the output will be written into this var if passed by ref * if a callable is passed it will be used as output handler @@ -69,6 +76,7 @@ public function runCommand(callable $commandCallable, string $url, ?string $cwd, $protocols = $this->config->get('github-protocols'); // public github, autoswitch protocols + // @phpstan-ignore composerPcre.maybeUnsafeStrictGroups if (Preg::isMatchStrictGroups('{^(?:https?|git)://' . self::getGitHubDomainsRegex($this->config) . '/(.*)}', $url, $match)) { $messages = []; foreach ($protocols as $protocol) { @@ -104,7 +112,9 @@ public function runCommand(callable $commandCallable, string $url, ?string $cwd, if ($bypassSshForGitHub || 0 !== $this->process->execute($command, $commandOutput, $cwd)) { $errorMsg = $this->process->getErrorOutput(); // private github repository without ssh key access, try https with auth + // @phpstan-ignore composerPcre.maybeUnsafeStrictGroups if (Preg::isMatchStrictGroups('{^git@' . self::getGitHubDomainsRegex($this->config) . ':(.+?)\.git$}i', $url, $match) + // @phpstan-ignore composerPcre.maybeUnsafeStrictGroups || Preg::isMatchStrictGroups('{^https?://' . self::getGitHubDomainsRegex($this->config) . '/(.*?)(?:\.git)?$}i', $url, $match) ) { if (!$this->io->hasAuthentication($match[1])) { @@ -127,52 +137,74 @@ public function runCommand(callable $commandCallable, string $url, ?string $cwd, $credentials = [rawurlencode($auth['username']), rawurlencode($auth['password'])]; $errorMsg = $this->process->getErrorOutput(); } - } elseif (Preg::isMatchStrictGroups('{^https://(bitbucket\.org)/(.*?)(?:\.git)?$}i', $url, $match)) { //bitbucket oauth - $bitbucketUtil = new Bitbucket($this->io, $this->config, $this->process); - - if (!$this->io->hasAuthentication($match[1])) { + // @phpstan-ignore composerPcre.maybeUnsafeStrictGroups + } elseif ( + Preg::isMatchStrictGroups('{^(https?)://(bitbucket\.org)/(.*?)(?:\.git)?$}i', $url, $match) + || Preg::isMatchStrictGroups('{^(git)@(bitbucket\.org):(.+?\.git)$}i', $url, $match) + ) { //bitbucket either through oauth or app password, with fallback to ssh. + $bitbucketUtil = new Bitbucket($this->io, $this->config, $this->process, $this->httpDownloader); + + $domain = $match[2]; + $repo_with_git_part = $match[3]; + if (!str_ends_with($repo_with_git_part, '.git')) { + $repo_with_git_part .= '.git'; + } + if (!$this->io->hasAuthentication($domain)) { $message = 'Enter your Bitbucket credentials to access private repos'; - if (!$bitbucketUtil->authorizeOAuth($match[1]) && $this->io->isInteractive()) { + if (!$bitbucketUtil->authorizeOAuth($domain) && $this->io->isInteractive()) { $bitbucketUtil->authorizeOAuthInteractively($match[1], $message); $accessToken = $bitbucketUtil->getToken(); - $this->io->setAuthentication($match[1], 'x-token-auth', $accessToken); + $this->io->setAuthentication($domain, 'x-token-auth', $accessToken); + } + } + + // First we try to authenticate with whatever we have stored. + // This will be successful if there is for example an app + // password in there. + if ($this->io->hasAuthentication($domain)) { + $auth = $this->io->getAuthentication($domain); + $authUrl = 'https://' . rawurlencode($auth['username']) . ':' . rawurlencode($auth['password']) . '@' . $domain . '/' . $repo_with_git_part; + + $command = $commandCallable($authUrl); + if (0 === $this->process->execute($command, $commandOutput, $cwd)) { + // Well if that succeeded on our first try, let's just + // take the win. + return; } - } else { //We're authenticating with a locally stored consumer. - $auth = $this->io->getAuthentication($match[1]); //We already have an access_token from a previous request. if ($auth['username'] !== 'x-token-auth') { - $accessToken = $bitbucketUtil->requestToken($match[1], $auth['username'], $auth['password']); + $accessToken = $bitbucketUtil->requestToken($domain, $auth['username'], $auth['password']); if (!empty($accessToken)) { - $this->io->setAuthentication($match[1], 'x-token-auth', $accessToken); + $this->io->setAuthentication($domain, 'x-token-auth', $accessToken); } } } - if ($this->io->hasAuthentication($match[1])) { - $auth = $this->io->getAuthentication($match[1]); - $authUrl = 'https://' . rawurlencode($auth['username']) . ':' . rawurlencode($auth['password']) . '@' . $match[1] . '/' . $match[2] . '.git'; - + if ($this->io->hasAuthentication($domain)) { + $auth = $this->io->getAuthentication($domain); + $authUrl = 'https://' . rawurlencode($auth['username']) . ':' . rawurlencode($auth['password']) . '@' . $domain . '/' . $repo_with_git_part; $command = $commandCallable($authUrl); if (0 === $this->process->execute($command, $commandOutput, $cwd)) { return; } $credentials = [rawurlencode($auth['username']), rawurlencode($auth['password'])]; - $errorMsg = $this->process->getErrorOutput(); - } else { // Falling back to ssh - $sshUrl = 'git@bitbucket.org:' . $match[2] . '.git'; - $this->io->writeError(' No bitbucket authentication configured. Falling back to ssh.'); - $command = $commandCallable($sshUrl); - if (0 === $this->process->execute($command, $commandOutput, $cwd)) { - return; - } - - $errorMsg = $this->process->getErrorOutput(); } + //Falling back to ssh + $sshUrl = 'git@bitbucket.org:' . $repo_with_git_part; + $this->io->writeError(' No bitbucket authentication configured. Falling back to ssh.'); + $command = $commandCallable($sshUrl); + if (0 === $this->process->execute($command, $commandOutput, $cwd)) { + return; + } + + $errorMsg = $this->process->getErrorOutput(); } elseif ( + // @phpstan-ignore composerPcre.maybeUnsafeStrictGroups Preg::isMatchStrictGroups('{^(git)@' . self::getGitLabDomainsRegex($this->config) . ':(.+?\.git)$}i', $url, $match) + // @phpstan-ignore composerPcre.maybeUnsafeStrictGroups || Preg::isMatchStrictGroups('{^(https?)://' . self::getGitLabDomainsRegex($this->config) . '/(.*)}i', $url, $match) ) { if ($match[1] === 'git') { @@ -191,9 +223,9 @@ public function runCommand(callable $commandCallable, string $url, ?string $cwd, if ($this->io->hasAuthentication($match[2])) { $auth = $this->io->getAuthentication($match[2]); if ($auth['password'] === 'private-token' || $auth['password'] === 'oauth2' || $auth['password'] === 'gitlab-ci-token') { - $authUrl = $match[1] . '://' . rawurlencode($auth['password']) . ':' . rawurlencode($auth['username']) . '@' . $match[2] . '/' . $match[3]; // swap username and password + $authUrl = $match[1] . '://' . rawurlencode($auth['password']) . ':' . rawurlencode((string) $auth['username']) . '@' . $match[2] . '/' . $match[3]; // swap username and password } else { - $authUrl = $match[1] . '://' . rawurlencode($auth['username']) . ':' . rawurlencode($auth['password']) . '@' . $match[2] . '/' . $match[3]; + $authUrl = $match[1] . '://' . rawurlencode((string) $auth['username']) . ':' . rawurlencode((string) $auth['password']) . '@' . $match[2] . '/' . $match[3]; } $command = $commandCallable($authUrl); @@ -201,11 +233,11 @@ public function runCommand(callable $commandCallable, string $url, ?string $cwd, return; } - $credentials = [rawurlencode($auth['username']), rawurlencode($auth['password'])]; + $credentials = [rawurlencode((string) $auth['username']), rawurlencode((string) $auth['password'])]; $errorMsg = $this->process->getErrorOutput(); } - } elseif ($this->isAuthenticationFailure($url, $match)) { // private non-github/gitlab/bitbucket repo that failed to authenticate - if (strpos($match[2], '@')) { + } elseif (null !== ($match = $this->getAuthenticationFailure($url))) { // private non-github/gitlab/bitbucket repo that failed to authenticate + if (str_contains($match[2], '@')) { [$authParts, $match[2]] = explode('@', $match[2], 2); } @@ -214,8 +246,8 @@ public function runCommand(callable $commandCallable, string $url, ?string $cwd, $auth = $this->io->getAuthentication($match[2]); } elseif ($this->io->isInteractive()) { $defaultUsername = null; - if (isset($authParts) && $authParts) { - if (false !== strpos($authParts, ':')) { + if (isset($authParts) && $authParts !== '') { + if (str_contains($authParts, ':')) { [$defaultUsername, ] = explode(':', $authParts, 2); } else { $defaultUsername = $authParts; @@ -232,7 +264,7 @@ public function runCommand(callable $commandCallable, string $url, ?string $cwd, } if (null !== $auth) { - $authUrl = $match[1] . rawurlencode($auth['username']) . ':' . rawurlencode($auth['password']) . '@' . $match[2] . $match[3]; + $authUrl = $match[1] . rawurlencode((string) $auth['username']) . ':' . rawurlencode((string) $auth['password']) . '@' . $match[2] . $match[3]; $command = $commandCallable($authUrl); if (0 === $this->process->execute($command, $commandOutput, $cwd)) { @@ -243,7 +275,7 @@ public function runCommand(callable $commandCallable, string $url, ?string $cwd, return; } - $credentials = [rawurlencode($auth['username']), rawurlencode($auth['password'])]; + $credentials = [rawurlencode((string) $auth['username']), rawurlencode((string) $auth['password'])]; $errorMsg = $this->process->getErrorOutput(); } } @@ -262,7 +294,7 @@ public function runCommand(callable $commandCallable, string $url, ?string $cwd, public function syncMirror(string $url, string $dir): bool { - if (Platform::getEnv('COMPOSER_DISABLE_NETWORK') && Platform::getEnv('COMPOSER_DISABLE_NETWORK') !== 'prime') { + if ((bool) Platform::getEnv('COMPOSER_DISABLE_NETWORK') && Platform::getEnv('COMPOSER_DISABLE_NETWORK') !== 'prime') { $this->io->writeError('Aborting git mirror sync of '.$url.' as network is disabled'); return false; @@ -298,7 +330,7 @@ public function syncMirror(string $url, string $dir): bool return true; } - public function fetchRefOrSyncMirror(string $url, string $dir, string $ref, string $prettyVersion = null): bool + public function fetchRefOrSyncMirror(string $url, string $dir, string $ref, ?string $prettyVersion = null): bool { if ($this->checkRefIsInMirror($dir, $ref)) { if (Preg::isMatch('{^[a-f0-9]{40}$}', $ref) && $prettyVersion !== null) { @@ -357,13 +389,12 @@ private function checkRefIsInMirror(string $dir, string $ref): bool } /** - * @param array $match - * @param-out array $match + * @return array|null */ - private function isAuthenticationFailure(string $url, array &$match): bool + private function getAuthenticationFailure(string $url): ?array { if (!Preg::isMatchStrictGroups('{^(https?://)([^/]+)(.*)$}i', $url, $match)) { - return false; + return null; } $authFailures = [ @@ -377,11 +408,11 @@ private function isAuthenticationFailure(string $url, array &$match): bool $errorOutput = $this->process->getErrorOutput(); foreach ($authFailures as $authFailure) { if (strpos($errorOutput, $authFailure) !== false) { - return true; + return $match; } } - return false; + return null; } public function getMirrorDefaultBranch(string $url, string $dir, bool $isLocalPathRepository): ?string @@ -405,7 +436,7 @@ public function getMirrorDefaultBranch(string $url, string $dir, bool $isLocalPa $lines = $this->process->splitLines($output); foreach ($lines as $line) { - if (Preg::match('{^\s*HEAD branch:\s(.+)\s*$}m', $line, $matches) > 0) { + if (Preg::isMatch('{^\s*HEAD branch:\s(.+)\s*$}m', $line, $matches)) { return $matches[1]; } } diff --git a/vendor/composer/composer/src/Composer/Util/Hg.php b/vendor/composer/composer/src/Composer/Util/Hg.php index 0e9f6e5..2810758 100644 --- a/vendor/composer/composer/src/Composer/Util/Hg.php +++ b/vendor/composer/composer/src/Composer/Util/Hg.php @@ -58,10 +58,20 @@ public function runCommand(callable $commandCallable, string $url, ?string $cwd) } // Try with the authentication information available - if (Preg::isMatch('{^(https?)://((.+)(?:\:(.+))?@)?([^/]+)(/.*)?}mi', $url, $match) && $this->io->hasAuthentication((string) $match[5])) { - $auth = $this->io->getAuthentication((string) $match[5]); - $authenticatedUrl = $match[1] . '://' . rawurlencode($auth['username']) . ':' . rawurlencode($auth['password']) . '@' . $match[5] . $match[6]; - + if ( + Preg::isMatch('{^(?Pssh|https?)://(?:(?P[^:@]+)(?::(?P[^:@]+))?@)?(?P[^/]+)(?P/.*)?}mi', $url, $matches) + && $this->io->hasAuthentication($matches['host']) + ) { + if ($matches['proto'] === 'ssh') { + $user = ''; + if ($matches['user'] !== null) { + $user = rawurlencode($matches['user']) . '@'; + } + $authenticatedUrl = $matches['proto'] . '://' . $user . $matches['host'] . $matches['path']; + } else { + $auth = $this->io->getAuthentication($matches['host']); + $authenticatedUrl = $matches['proto'] . '://' . rawurlencode((string) $auth['username']) . ':' . rawurlencode((string) $auth['password']) . '@' . $matches['host'] . $matches['path']; + } $command = $commandCallable($authenticatedUrl); if (0 === $this->process->execute($command, $ignoredOutput, $cwd)) { @@ -70,10 +80,10 @@ public function runCommand(callable $commandCallable, string $url, ?string $cwd) $error = $this->process->getErrorOutput(); } else { - $error = 'The given URL (' . $url . ') does not match the required format (http(s)://(username:password@)example.com/path-to-repository)'; + $error = 'The given URL (' .$url. ') does not match the required format (ssh|http(s)://(username:password@)example.com/path-to-repository)'; } - $this->throwException('Failed to clone ' . $url . ', ' . "\n\n" . $error, $url); + $this->throwException("Failed to clone $url, \n\n" . $error, $url); } /** @@ -84,7 +94,9 @@ public function runCommand(callable $commandCallable, string $url, ?string $cwd) private function throwException($message, string $url): void { if (null === self::getVersion($this->process)) { - throw new \RuntimeException(Url::sanitize('Failed to clone ' . $url . ', hg was not found, check that it is installed and in your PATH env.' . "\n\n" . $this->process->getErrorOutput())); + throw new \RuntimeException(Url::sanitize( + 'Failed to clone ' . $url . ', hg was not found, check that it is installed and in your PATH env.' . "\n\n" . $this->process->getErrorOutput() + )); } throw new \RuntimeException(Url::sanitize($message)); diff --git a/vendor/composer/composer/src/Composer/Util/Http/CurlDownloader.php b/vendor/composer/composer/src/Composer/Util/Http/CurlDownloader.php index f5bbe24..577c81b 100644 --- a/vendor/composer/composer/src/Composer/Util/Http/CurlDownloader.php +++ b/vendor/composer/composer/src/Composer/Util/Http/CurlDownloader.php @@ -23,19 +23,20 @@ use Composer\Util\Url; use Composer\Util\HttpDownloader; use React\Promise\Promise; +use Symfony\Component\HttpFoundation\IpUtils; /** * @internal * @author Jordi Boggiano * @author Nicolas Grekas * @phpstan-type Attributes array{retryAuthFailure: bool, redirects: int<0, max>, retries: int<0, max>, storeAuth: 'prompt'|bool, ipResolve: 4|6|null} - * @phpstan-type Job array{url: non-empty-string, origin: string, attributes: Attributes, options: mixed[], progress: mixed[], curlHandle: \CurlHandle, filename: string|null, headerHandle: resource, bodyHandle: resource, resolve: callable, reject: callable} + * @phpstan-type Job array{url: non-empty-string, origin: string, attributes: Attributes, options: mixed[], progress: mixed[], curlHandle: \CurlHandle, filename: string|null, headerHandle: resource, bodyHandle: resource, resolve: callable, reject: callable, primaryIp: string} */ class CurlDownloader { - /** @var ?resource */ + /** @var \CurlMultiHandle */ private $multiHandle; - /** @var ?resource */ + /** @var \CurlShareHandle */ private $shareHandle; /** @var Job[] */ private $jobs = []; @@ -51,10 +52,6 @@ class CurlDownloader private $maxRedirects = 20; /** @var int */ private $maxRetries = 3; - /** @var ProxyManager */ - private $proxyManager; - /** @var bool */ - private $supportsSecureProxy; /** @var array */ protected $multiErrors = [ CURLM_BAD_HANDLE => ['CURLM_BAD_HANDLE', 'The passed-in handle is not a valid CURLM handle.'], @@ -102,7 +99,7 @@ public function __construct(IOInterface $io, Config $config, array $options = [] $this->multiHandle = $mh = curl_multi_init(); if (function_exists('curl_multi_setopt')) { - curl_multi_setopt($mh, CURLMOPT_PIPELINING, PHP_VERSION_ID >= 70400 ? /* CURLPIPE_MULTIPLEX */ 2 : /*CURLPIPE_HTTP1 | CURLPIPE_MULTIPLEX*/ 3); + curl_multi_setopt($mh, CURLMOPT_PIPELINING, \PHP_VERSION_ID >= 70400 ? /* CURLPIPE_MULTIPLEX */ 2 : /*CURLPIPE_HTTP1 | CURLPIPE_MULTIPLEX*/ 3); if (defined('CURLMOPT_MAX_HOST_CONNECTIONS') && !defined('HHVM_VERSION')) { curl_multi_setopt($mh, CURLMOPT_MAX_HOST_CONNECTIONS, 8); } @@ -116,11 +113,6 @@ public function __construct(IOInterface $io, Config $config, array $options = [] } $this->authHelper = new AuthHelper($io, $config); - $this->proxyManager = ProxyManager::getInstance(); - - $version = curl_version(); - $features = $version['features']; - $this->supportsSecureProxy = defined('CURL_VERSION_HTTPS_PROXY') && ($features & CURL_VERSION_HTTPS_PROXY); } /** @@ -184,12 +176,13 @@ private function initDownload(callable $resolve, callable $reject, string $origi } $errorMessage = ''; - // @phpstan-ignore-next-line - set_error_handler(static function ($code, $msg) use (&$errorMessage): void { + set_error_handler(static function (int $code, string $msg) use (&$errorMessage): bool { if ($errorMessage) { $errorMessage .= "\n"; } $errorMessage .= Preg::replace('{^fopen\(.*?\): }', '', $msg); + + return true; }); $bodyHandle = fopen($bodyTarget, 'w+b'); restore_error_handler(); @@ -225,10 +218,16 @@ private function initDownload(callable $resolve, callable $reject, string $origi $version = curl_version(); $features = $version['features']; - if (0 === strpos($url, 'https://') && \defined('CURL_VERSION_HTTP2') && \defined('CURL_HTTP_VERSION_2_0') && (CURL_VERSION_HTTP2 & $features)) { + if (0 === strpos($url, 'https://') && \defined('CURL_VERSION_HTTP2') && \defined('CURL_HTTP_VERSION_2_0') && (CURL_VERSION_HTTP2 & $features) !== 0) { curl_setopt($curlHandle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0); } + // curl 8.7.0 - 8.7.1 has a bug whereas automatic accept-encoding header results in an error when reading the response + // https://github.com/composer/composer/issues/11913 + if (isset($version['version']) && in_array($version['version'], ['8.7.0', '8.7.1'], true) && \defined('CURL_VERSION_LIBZ') && (CURL_VERSION_LIBZ & $features) !== 0) { + curl_setopt($curlHandle, CURLOPT_ENCODING, "gzip"); + } + $options['http']['header'] = $this->authHelper->addAuthenticationHeader($options['http']['header'], $origin, $url); $options = StreamContextFactory::initOptions($url, $options, true); @@ -244,26 +243,8 @@ private function initDownload(callable $resolve, callable $reject, string $origi } } - // Always set CURLOPT_PROXY to enable/disable proxy handling - // Any proxy authorization is included in the proxy url - $proxy = $this->proxyManager->getProxyForRequest($url); - if ($proxy->getUrl() !== '') { - curl_setopt($curlHandle, CURLOPT_PROXY, $proxy->getUrl()); - } - - // Curl needs certificate locations for secure proxies. - // CURLOPT_PROXY_SSL_VERIFY_PEER/HOST are enabled by default - if ($proxy->isSecure()) { - if (!$this->supportsSecureProxy) { - throw new TransportException('Connecting to a secure proxy using curl is not supported on PHP versions below 7.3.0.'); - } - if (!empty($options['ssl']['cafile'])) { - curl_setopt($curlHandle, CURLOPT_PROXY_CAINFO, $options['ssl']['cafile']); - } - if (!empty($options['ssl']['capath'])) { - curl_setopt($curlHandle, CURLOPT_PROXY_CAPATH, $options['ssl']['capath']); - } - } + $proxy = ProxyManager::getInstance()->getProxyForRequest($url); + curl_setopt_array($curlHandle, $proxy->getCurlOptions($options['ssl'] ?? [])); $progress = array_diff_key(curl_getinfo($curlHandle), self::$timeInfo); @@ -279,9 +260,10 @@ private function initDownload(callable $resolve, callable $reject, string $origi 'bodyHandle' => $bodyHandle, 'resolve' => $resolve, 'reject' => $reject, + 'primaryIp' => '', ]; - $usingProxy = $proxy->getFormattedUrl(' using proxy (%s)'); + $usingProxy = $proxy->getStatus(' using proxy (%s)'); $ifModified = false !== stripos(implode(',', $options['http']['header']), 'if-modified-since:') ? ' if modified' : ''; if ($attributes['redirects'] === 0 && $attributes['retries'] === 0) { $this->io->writeError('Downloading ' . Url::sanitize($url) . $usingProxy . $ifModified, true, IOInterface::DEBUG); @@ -381,7 +363,7 @@ public function tick(): void continue; } - if ($errno === 28 /* CURLE_OPERATION_TIMEDOUT */ && PHP_VERSION_ID >= 70300 && $progress['namelookup_time'] === 0.0 && !$timeoutWarning) { + if ($errno === 28 /* CURLE_OPERATION_TIMEDOUT */ && \PHP_VERSION_ID >= 70300 && $progress['namelookup_time'] === 0.0 && !$timeoutWarning) { $timeoutWarning = true; $this->io->writeError('A connection timeout was encountered. If you intend to run Composer without connecting to the internet, run the command again prefixed with COMPOSER_DISABLE_NETWORK=1 to make Composer run in offline mode.'); } @@ -505,6 +487,18 @@ public function tick(): void } } + if (isset($progress['primary_ip']) && $progress['primary_ip'] !== $this->jobs[$i]['primaryIp']) { + if ( + isset($this->jobs[$i]['options']['prevent_ip_access_callable']) && + is_callable($this->jobs[$i]['options']['prevent_ip_access_callable']) && + $this->jobs[$i]['options']['prevent_ip_access_callable']($progress['primary_ip']) + ) { + $this->rejectJob($this->jobs[$i], new TransportException(sprintf('IP "%s" is blocked for "%s".', $progress['primary_ip'], $progress['url']))); + } + + $this->jobs[$i]['primaryIp'] = (string) $progress['primary_ip']; + } + // TODO progress } } diff --git a/vendor/composer/composer/src/Composer/Util/Http/ProxyHelper.php b/vendor/composer/composer/src/Composer/Util/Http/ProxyHelper.php deleted file mode 100644 index f2d864f..0000000 --- a/vendor/composer/composer/src/Composer/Util/Http/ProxyHelper.php +++ /dev/null @@ -1,183 +0,0 @@ - - * Jordi Boggiano - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Composer\Util\Http; - -/** - * Proxy discovery and helper class - * - * @internal - * @author John Stevenson - */ -class ProxyHelper -{ - /** - * Returns proxy environment values - * - * @return array{string|null, string|null, string|null} httpProxy, httpsProxy, noProxy values - * - * @throws \RuntimeException on malformed url - */ - public static function getProxyData(): array - { - $httpProxy = null; - $httpsProxy = null; - - // Handle http_proxy/HTTP_PROXY on CLI only for security reasons - if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { - if ($env = self::getProxyEnv(['http_proxy', 'HTTP_PROXY'], $name)) { - $httpProxy = self::checkProxy($env, $name); - } - } - - // Prefer CGI_HTTP_PROXY if available - if ($env = self::getProxyEnv(['CGI_HTTP_PROXY'], $name)) { - $httpProxy = self::checkProxy($env, $name); - } - - // Handle https_proxy/HTTPS_PROXY - if ($env = self::getProxyEnv(['https_proxy', 'HTTPS_PROXY'], $name)) { - $httpsProxy = self::checkProxy($env, $name); - } else { - $httpsProxy = $httpProxy; - } - - // Handle no_proxy - $noProxy = self::getProxyEnv(['no_proxy', 'NO_PROXY'], $name); - - return [$httpProxy, $httpsProxy, $noProxy]; - } - - /** - * Returns http context options for the proxy url - * - * @return array{http: array{proxy: string, header?: string}} - */ - public static function getContextOptions(string $proxyUrl): array - { - $proxy = parse_url($proxyUrl); - - // Remove any authorization - $proxyUrl = self::formatParsedUrl($proxy, false); - $proxyUrl = str_replace(['http://', 'https://'], ['tcp://', 'ssl://'], $proxyUrl); - - $options['http']['proxy'] = $proxyUrl; - - // Handle any authorization - if (isset($proxy['user'])) { - $auth = rawurldecode($proxy['user']); - - if (isset($proxy['pass'])) { - $auth .= ':' . rawurldecode($proxy['pass']); - } - $auth = base64_encode($auth); - // Set header as a string - $options['http']['header'] = "Proxy-Authorization: Basic {$auth}"; - } - - return $options; - } - - /** - * Sets/unsets request_fulluri value in http context options array - * - * @param mixed[] $options Set by method - */ - public static function setRequestFullUri(string $requestUrl, array &$options): void - { - if ('http' === parse_url($requestUrl, PHP_URL_SCHEME)) { - $options['http']['request_fulluri'] = true; - } else { - unset($options['http']['request_fulluri']); - } - } - - /** - * Searches $_SERVER for case-sensitive values - * - * @param non-empty-list $names Names to search for - * @param string|null $name Name of any found value, you should only rely on it if the function returned a non-null value - * - * @return string|null The found value - * - * @param-out string $name - */ - private static function getProxyEnv(array $names, ?string &$name): ?string - { - foreach ($names as $name) { - if (!empty($_SERVER[$name])) { - return $_SERVER[$name]; - } - } - - return null; - } - - /** - * Checks and formats a proxy url from the environment - * - * @throws \RuntimeException on malformed url - * @return string The formatted proxy url - */ - private static function checkProxy(string $proxyUrl, string $envName): string - { - $error = sprintf('malformed %s url', $envName); - $proxy = parse_url($proxyUrl); - - // We need parse_url to have identified a host - if (!isset($proxy['host'])) { - throw new \RuntimeException($error); - } - - $proxyUrl = self::formatParsedUrl($proxy, true); - - // We need a port because streams and curl use different defaults - if (!parse_url($proxyUrl, PHP_URL_PORT)) { - throw new \RuntimeException($error); - } - - return $proxyUrl; - } - - /** - * Formats a url from its component parts - * - * @param array{scheme?: string, host: string, port?: int, user?: string, pass?: string} $proxy - * - * @return string The formatted value - */ - private static function formatParsedUrl(array $proxy, bool $includeAuth): string - { - $proxyUrl = isset($proxy['scheme']) ? strtolower($proxy['scheme']) . '://' : ''; - - if ($includeAuth && isset($proxy['user'])) { - $proxyUrl .= $proxy['user']; - - if (isset($proxy['pass'])) { - $proxyUrl .= ':' . $proxy['pass']; - } - $proxyUrl .= '@'; - } - - $proxyUrl .= $proxy['host']; - - if (isset($proxy['port'])) { - $proxyUrl .= ':' . $proxy['port']; - } elseif (strpos($proxyUrl, 'http://') === 0) { - $proxyUrl .= ':80'; - } elseif (strpos($proxyUrl, 'https://') === 0) { - $proxyUrl .= ':443'; - } - - return $proxyUrl; - } -} diff --git a/vendor/composer/composer/src/Composer/Util/Http/ProxyItem.php b/vendor/composer/composer/src/Composer/Util/Http/ProxyItem.php new file mode 100644 index 0000000..2839be9 --- /dev/null +++ b/vendor/composer/composer/src/Composer/Util/Http/ProxyItem.php @@ -0,0 +1,119 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Util\Http; + +/** + * @internal + * @author John Stevenson + */ +class ProxyItem +{ + /** @var non-empty-string */ + private $url; + /** @var non-empty-string */ + private $safeUrl; + /** @var ?non-empty-string */ + private $curlAuth; + /** @var string */ + private $optionsProxy; + /** @var ?non-empty-string */ + private $optionsAuth; + + /** + * @param string $proxyUrl The value from the environment + * @param string $envName The name of the environment variable + * @throws \RuntimeException If the proxy url is invalid + */ + public function __construct(string $proxyUrl, string $envName) + { + $syntaxError = sprintf('unsupported `%s` syntax', $envName); + + if (strpbrk($proxyUrl, "\r\n\t") !== false) { + throw new \RuntimeException($syntaxError); + } + if (false === ($proxy = parse_url($proxyUrl))) { + throw new \RuntimeException($syntaxError); + } + if (!isset($proxy['host'])) { + throw new \RuntimeException('unable to find proxy host in ' . $envName); + } + + $scheme = isset($proxy['scheme']) ? strtolower($proxy['scheme']) . '://' : 'http://'; + $safe = ''; + + if (isset($proxy['user'])) { + $safe = '***'; + $user = $proxy['user']; + $auth = rawurldecode($proxy['user']); + + if (isset($proxy['pass'])) { + $safe .= ':***'; + $user .= ':' . $proxy['pass']; + $auth .= ':' . rawurldecode($proxy['pass']); + } + + $safe .= '@'; + + if (strlen($user) > 0) { + $this->curlAuth = $user; + $this->optionsAuth = 'Proxy-Authorization: Basic ' . base64_encode($auth); + } + } + + $host = $proxy['host']; + $port = null; + + if (isset($proxy['port'])) { + $port = $proxy['port']; + } elseif ($scheme === 'http://') { + $port = 80; + } elseif ($scheme === 'https://') { + $port = 443; + } + + // We need a port because curl uses 1080 for http. Port 0 is reserved, + // but is considered valid depending on the PHP or Curl version. + if ($port === null) { + throw new \RuntimeException('unable to find proxy port in ' . $envName); + } + if ($port === 0) { + throw new \RuntimeException('port 0 is reserved in ' . $envName); + } + + $this->url = sprintf('%s%s:%d', $scheme, $host, $port); + $this->safeUrl = sprintf('%s%s%s:%d', $scheme, $safe, $host, $port); + + $scheme = str_replace(['http://', 'https://'], ['tcp://', 'ssl://'], $scheme); + $this->optionsProxy = sprintf('%s%s:%d', $scheme, $host, $port); + } + + /** + * Returns a RequestProxy instance for the scheme of the request url + * + * @param string $scheme The scheme of the request url + */ + public function toRequestProxy(string $scheme): RequestProxy + { + $options = ['http' => ['proxy' => $this->optionsProxy]]; + + if ($this->optionsAuth !== null) { + $options['http']['header'] = $this->optionsAuth; + } + + if ($scheme === 'http') { + $options['http']['request_fulluri'] = true; + } + + return new RequestProxy($this->url, $this->curlAuth, $options, $this->safeUrl); + } +} diff --git a/vendor/composer/composer/src/Composer/Util/Http/ProxyManager.php b/vendor/composer/composer/src/Composer/Util/Http/ProxyManager.php index 731638a..247105f 100644 --- a/vendor/composer/composer/src/Composer/Util/Http/ProxyManager.php +++ b/vendor/composer/composer/src/Composer/Util/Http/ProxyManager.php @@ -14,7 +14,6 @@ use Composer\Downloader\TransportException; use Composer\Util\NoProxyPattern; -use Composer\Util\Url; /** * @internal @@ -24,40 +23,28 @@ class ProxyManager { /** @var ?string */ private $error = null; - /** @var array{http: ?string, https: ?string} */ - private $fullProxy; - /** @var array{http: ?string, https: ?string} */ - private $safeProxy; - /** @var array{http: array{options: mixed[]|null}, https: array{options: mixed[]|null}} */ - private $streams; - /** @var bool */ - private $hasProxy; - /** @var ?string */ - private $info = null; + /** @var ?ProxyItem */ + private $httpProxy = null; + /** @var ?ProxyItem */ + private $httpsProxy = null; /** @var ?NoProxyPattern */ private $noProxyHandler = null; - /** @var ?ProxyManager */ + /** @var ?self */ private static $instance = null; private function __construct() { - $this->fullProxy = $this->safeProxy = [ - 'http' => null, - 'https' => null, - ]; - - $this->streams['http'] = $this->streams['https'] = [ - 'options' => null, - ]; - - $this->hasProxy = false; - $this->initProxyData(); + try { + $this->getProxyData(); + } catch (\RuntimeException $e) { + $this->error = $e->getMessage(); + } } public static function getInstance(): ProxyManager { - if (!self::$instance) { + if (self::$instance === null) { self::$instance = new self(); } @@ -79,96 +66,92 @@ public static function reset(): void */ public function getProxyForRequest(string $requestUrl): RequestProxy { - if ($this->error) { + if ($this->error !== null) { throw new TransportException('Unable to use a proxy: '.$this->error); } - $scheme = parse_url($requestUrl, PHP_URL_SCHEME) ?: 'http'; - $proxyUrl = ''; - $options = []; - $formattedProxyUrl = ''; - - if ($this->hasProxy && in_array($scheme, ['http', 'https'], true) && $this->fullProxy[$scheme]) { - if ($this->noProxy($requestUrl)) { - $formattedProxyUrl = 'excluded by no_proxy'; - } else { - $proxyUrl = $this->fullProxy[$scheme]; - $options = $this->streams[$scheme]['options']; - assert(is_array($options)); - ProxyHelper::setRequestFullUri($requestUrl, $options); - $formattedProxyUrl = $this->safeProxy[$scheme]; - } + $scheme = (string) parse_url($requestUrl, PHP_URL_SCHEME); + $proxy = $this->getProxyForScheme($scheme); + + if ($proxy === null) { + return RequestProxy::none(); } - return new RequestProxy($proxyUrl, $options, $formattedProxyUrl); - } + if ($this->noProxy($requestUrl)) { + return RequestProxy::noProxy(); + } - /** - * Returns true if a proxy is being used - * - * @return bool If false any error will be in $message - */ - public function isProxying(): bool - { - return $this->hasProxy; + return $proxy->toRequestProxy($scheme); } /** - * Returns proxy configuration info which can be shown to the user - * - * @return string|null Safe proxy URL or an error message if setting up proxy failed or null if no proxy was configured + * Returns a ProxyItem if one is set for the scheme, otherwise null */ - public function getFormattedProxy(): ?string + private function getProxyForScheme(string $scheme): ?ProxyItem { - return $this->hasProxy ? $this->info : $this->error; + if ($scheme === 'http') { + return $this->httpProxy; + } + + if ($scheme === 'https') { + return $this->httpsProxy; + } + + return null; } /** - * Initializes proxy values from the environment + * Finds proxy values from the environment and sets class properties */ - private function initProxyData(): void + private function getProxyData(): void { - try { - [$httpProxy, $httpsProxy, $noProxy] = ProxyHelper::getProxyData(); - } catch (\RuntimeException $e) { - $this->error = $e->getMessage(); - - return; + // Handle http_proxy/HTTP_PROXY on CLI only for security reasons + if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { + [$env, $name] = $this->getProxyEnv('http_proxy'); + if ($env !== null) { + $this->httpProxy = new ProxyItem($env, $name); + } } - $info = []; - - if ($httpProxy) { - $info[] = $this->setData($httpProxy, 'http'); + // Handle cgi_http_proxy/CGI_HTTP_PROXY if needed + if ($this->httpProxy === null) { + [$env, $name] = $this->getProxyEnv('cgi_http_proxy'); + if ($env !== null) { + $this->httpProxy = new ProxyItem($env, $name); + } } - if ($httpsProxy) { - $info[] = $this->setData($httpsProxy, 'https'); + + // Handle https_proxy/HTTPS_PROXY + [$env, $name] = $this->getProxyEnv('https_proxy'); + if ($env !== null) { + $this->httpsProxy = new ProxyItem($env, $name); } - if ($this->hasProxy) { - $this->info = implode(', ', $info); - if ($noProxy) { - $this->noProxyHandler = new NoProxyPattern($noProxy); - } + + // Handle no_proxy/NO_PROXY + [$env, $name] = $this->getProxyEnv('no_proxy'); + if ($env !== null) { + $this->noProxyHandler = new NoProxyPattern($env); } } /** - * Sets initial data + * Searches $_SERVER for case-sensitive values * - * @param non-empty-string $url Proxy url - * @param 'http'|'https' $scheme Environment variable scheme - * - * @return non-empty-string + * @return array{0: string|null, 1: string} value, name */ - private function setData($url, $scheme): string + private function getProxyEnv(string $envName): array { - $safeProxy = Url::sanitize($url); - $this->fullProxy[$scheme] = $url; - $this->safeProxy[$scheme] = $safeProxy; - $this->streams[$scheme]['options'] = ProxyHelper::getContextOptions($url); - $this->hasProxy = true; + $names = [strtolower($envName), strtoupper($envName)]; - return sprintf('%s=%s', $scheme, $safeProxy); + foreach ($names as $name) { + if (is_string($_SERVER[$name] ?? null)) { + if ($_SERVER[$name] !== '') { + return [$_SERVER[$name], $name]; + } + } + } + + return [null, '']; } /** @@ -176,6 +159,10 @@ private function setData($url, $scheme): string */ private function noProxy(string $requestUrl): bool { - return $this->noProxyHandler && $this->noProxyHandler->test($requestUrl); + if ($this->noProxyHandler === null) { + return false; + } + + return $this->noProxyHandler->test($requestUrl); } } diff --git a/vendor/composer/composer/src/Composer/Util/Http/RequestProxy.php b/vendor/composer/composer/src/Composer/Util/Http/RequestProxy.php index c80c879..d9df688 100644 --- a/vendor/composer/composer/src/Composer/Util/Http/RequestProxy.php +++ b/vendor/composer/composer/src/Composer/Util/Http/RequestProxy.php @@ -12,78 +12,157 @@ namespace Composer\Util\Http; -use Composer\Util\Url; +use Composer\Downloader\TransportException; /** * @internal * @author John Stevenson + * + * @phpstan-type contextOptions array{http: array{proxy: string, header?: string, request_fulluri?: bool}} */ class RequestProxy { - /** @var mixed[] */ + /** @var ?contextOptions */ private $contextOptions; - /** @var bool */ - private $isSecure; - /** @var string */ - private $formattedUrl; - /** @var string */ + /** @var ?non-empty-string */ + private $status; + /** @var ?non-empty-string */ private $url; + /** @var ?non-empty-string */ + private $auth; /** - * @param mixed[] $contextOptions + * @param ?non-empty-string $url The proxy url, without authorization + * @param ?non-empty-string $auth Authorization for curl + * @param ?contextOptions $contextOptions + * @param ?non-empty-string $status */ - public function __construct(string $url, array $contextOptions, string $formattedUrl) + public function __construct(?string $url, ?string $auth, ?array $contextOptions, ?string $status) { $this->url = $url; + $this->auth = $auth; $this->contextOptions = $contextOptions; - $this->formattedUrl = $formattedUrl; - $this->isSecure = 0 === strpos($url, 'https://'); + $this->status = $status; + } + + public static function none(): RequestProxy + { + return new self(null, null, null, null); + } + + public static function noProxy(): RequestProxy + { + return new self(null, null, null, 'excluded by no_proxy'); } /** - * Returns an array of context options + * Returns the context options to use for this request, otherwise null * - * @return mixed[] + * @return ?contextOptions */ - public function getContextOptions(): array + public function getContextOptions(): ?array { return $this->contextOptions; } /** - * Returns the safe proxy url from the last request + * Returns an array of curl proxy options + * + * @param array $sslOptions + * @return array + */ + public function getCurlOptions(array $sslOptions): array + { + if ($this->isSecure() && !$this->supportsSecureProxy()) { + throw new TransportException('Cannot use an HTTPS proxy. PHP >= 7.3 and cUrl >= 7.52.0 are required.'); + } + + // Always set a proxy url, even an empty value, because it tells curl + // to ignore proxy environment variables + $options = [CURLOPT_PROXY => (string) $this->url]; + + // If using a proxy, tell curl to ignore no_proxy environment variables + if ($this->url !== null) { + $options[CURLOPT_NOPROXY] = ''; + } + + // Set any authorization + if ($this->auth !== null) { + $options[CURLOPT_PROXYAUTH] = CURLAUTH_BASIC; + $options[CURLOPT_PROXYUSERPWD] = $this->auth; + } + + if ($this->isSecure()) { + if (isset($sslOptions['cafile'])) { + $options[CURLOPT_PROXY_CAINFO] = $sslOptions['cafile']; + } + if (isset($sslOptions['capath'])) { + $options[CURLOPT_PROXY_CAPATH] = $sslOptions['capath']; + } + } + + return $options; + } + + /** + * Returns proxy info associated with this request * - * @param string|null $format Output format specifier - * @return string Safe proxy, no proxy or empty + * An empty return value means that the user has not set a proxy. + * A non-empty value will either be the sanitized proxy url if a proxy is + * required, or a message indicating that a no_proxy value has disabled the + * proxy. + * + * @param ?string $format Output format specifier */ - public function getFormattedUrl(?string $format = ''): string + public function getStatus(?string $format = null): string { - $result = ''; - if ($this->formattedUrl) { - $format = $format ?: '%s'; - $result = sprintf($format, $this->formattedUrl); + if ($this->status === null) { + return ''; + } + + $format = $format ?? '%s'; + if (strpos($format, '%s') !== false) { + return sprintf($format, $this->status); } - return $result; + throw new \InvalidArgumentException('String format specifier is missing'); } /** - * Returns the proxy url + * Returns true if the request url has been excluded by a no_proxy value * - * @return string Proxy url or empty + * A false value can also mean that the user has not set a proxy. */ - public function getUrl(): string + public function isExcludedByNoProxy(): bool { - return $this->url; + return $this->status !== null && $this->url === null; } /** - * Returns true if this is a secure-proxy + * Returns true if this is a secure (HTTPS) proxy * - * @return bool False if not secure or there is no proxy + * A false value means that this is either an HTTP proxy, or that a proxy + * is not required for this request, or that the user has not set a proxy. */ public function isSecure(): bool { - return $this->isSecure; + return 0 === strpos((string) $this->url, 'https://'); + } + + /** + * Returns true if an HTTPS proxy can be used. + * + * This depends on PHP7.3+ for CURL_VERSION_HTTPS_PROXY + * and curl including the feature (from version 7.52.0) + */ + public function supportsSecureProxy(): bool + { + if (false === ($version = curl_version()) || !defined('CURL_VERSION_HTTPS_PROXY')) { + return false; + } + + $features = $version['features']; + + return (bool) ($features & CURL_VERSION_HTTPS_PROXY); } } diff --git a/vendor/composer/composer/src/Composer/Util/Http/Response.php b/vendor/composer/composer/src/Composer/Util/Http/Response.php index 5e5d18a..e355f25 100644 --- a/vendor/composer/composer/src/Composer/Util/Http/Response.php +++ b/vendor/composer/composer/src/Composer/Util/Http/Response.php @@ -36,7 +36,7 @@ class Response */ public function __construct(array $request, ?int $code, array $headers, ?string $body) { - if (!isset($request['url'])) { // @phpstan-ignore-line + if (!isset($request['url'])) { throw new \LogicException('url key missing from request array'); } $this->request = $request; @@ -101,8 +101,7 @@ public function decodeJson() */ public function collect(): void { - /** @phpstan-ignore-next-line */ - $this->request = $this->code = $this->headers = $this->body = null; + unset($this->request, $this->code, $this->headers, $this->body); } /** diff --git a/vendor/composer/composer/src/Composer/Util/Perforce.php b/vendor/composer/composer/src/Composer/Util/Perforce.php index d24209a..ff93115 100644 --- a/vendor/composer/composer/src/Composer/Util/Perforce.php +++ b/vendor/composer/composer/src/Composer/Util/Perforce.php @@ -342,7 +342,7 @@ public function isLoggedIn(): bool public function connectClient(): void { $p4CreateClientCommand = $this->generateP4Command( - 'client -i < ' . str_replace(" ", "\\ ", $this->getP4ClientSpec()) + 'client -i < ' . ProcessExecutor::escape($this->getP4ClientSpec()) ); $this->executeCommand($p4CreateClientCommand); } diff --git a/vendor/composer/composer/src/Composer/Util/Platform.php b/vendor/composer/composer/src/Composer/Util/Platform.php index 33ff620..b13fe5b 100644 --- a/vendor/composer/composer/src/Composer/Util/Platform.php +++ b/vendor/composer/composer/src/Composer/Util/Platform.php @@ -25,6 +25,8 @@ class Platform private static $isVirtualBoxGuest = null; /** @var ?bool */ private static $isWindowsSubsystemForLinux = null; + /** @var ?bool */ + private static $isDocker = null; /** * getcwd() equivalent which always returns a string @@ -76,7 +78,6 @@ public static function getEnv(string $name) */ public static function putEnv(string $name, string $value): void { - $value = (string) $value; putenv($name . '=' . $value); $_SERVER[$name] = $_ENV[$name] = $value; } @@ -100,12 +101,12 @@ public static function expandPath(string $path): string } return Preg::replaceCallback('#^(\$|(?P%))(?P\w++)(?(percent)%)(?P.*)#', static function ($matches): string { - assert(is_string($matches['var'])); - assert('' !== $matches['var']); - // Treat HOME as an alias for USERPROFILE on Windows for legacy reasons if (Platform::isWindows() && $matches['var'] === 'HOME') { - return (Platform::getEnv('HOME') ?: Platform::getEnv('USERPROFILE')) . $matches['path']; + if ((bool) Platform::getEnv('HOME')) { + return Platform::getEnv('HOME') . $matches['path']; + } + return Platform::getEnv('USERPROFILE') . $matches['path']; } return Platform::getEnv($matches['var']) . $matches['path']; @@ -129,7 +130,9 @@ public static function getUserDirectory(): string if (\function_exists('posix_getuid') && \function_exists('posix_getpwuid')) { $info = posix_getpwuid(posix_getuid()); - return $info['dir']; + if (is_array($info)) { + return $info['dir']; + } } throw new \RuntimeException('Could not determine user directory'); @@ -149,10 +152,10 @@ public static function isWindowsSubsystemForLinux(): bool } if ( - !ini_get('open_basedir') + !(bool) ini_get('open_basedir') && is_readable('/proc/version') && false !== stripos((string)Silencer::call('file_get_contents', '/proc/version'), 'microsoft') - && !file_exists('/.dockerenv') // docker running inside WSL should not be seen as WSL + && !self::isDocker() // Docker and Podman running inside WSL should not be seen as WSL ) { return self::$isWindowsSubsystemForLinux = true; } @@ -169,6 +172,46 @@ public static function isWindows(): bool return \defined('PHP_WINDOWS_VERSION_BUILD'); } + public static function isDocker(): bool + { + if (null !== self::$isDocker) { + return self::$isDocker; + } + + // cannot check so assume no + if ((bool) ini_get('open_basedir')) { + return self::$isDocker = false; + } + + // .dockerenv and .containerenv are present in some cases but not reliably + if (file_exists('/.dockerenv') || file_exists('/run/.containerenv') || file_exists('/var/run/.containerenv')) { + return self::$isDocker = true; + } + + // see https://www.baeldung.com/linux/is-process-running-inside-container + $cgroups = [ + '/proc/self/mountinfo', // cgroup v2 + '/proc/1/cgroup', // cgroup v1 + ]; + foreach ($cgroups as $cgroup) { + if (!is_readable($cgroup)) { + continue; + } + // suppress errors as some environments have these files as readable but system restrictions prevent the read from succeeding + // see https://github.com/composer/composer/issues/12095 + try { + $data = @file_get_contents($cgroup); + } catch (\Throwable $e) { + break; + } + if (is_string($data) && str_contains($data, '/var/lib/docker/')) { + return self::$isDocker = true; + } + } + + return self::$isDocker = false; + } + /** * @return int return a guaranteed binary length of the string, regardless of silly mbstring configs */ @@ -176,7 +219,7 @@ public static function strlen(string $str): int { static $useMbString = null; if (null === $useMbString) { - $useMbString = \function_exists('mb_strlen') && ini_get('mbstring.func_overload'); + $useMbString = \function_exists('mb_strlen') && (bool) ini_get('mbstring.func_overload'); } if ($useMbString) { @@ -200,7 +243,7 @@ public static function isTty($fd = null): bool // detect msysgit/mingw and assume this is a tty because detection // does not work correctly, see https://github.com/composer/composer/issues/9690 - if (in_array(strtoupper(self::getEnv('MSYSTEM') ?: ''), ['MINGW32', 'MINGW64'], true)) { + if (in_array(strtoupper((string) self::getEnv('MSYSTEM')), ['MINGW32', 'MINGW64'], true)) { return true; } @@ -216,8 +259,11 @@ public static function isTty($fd = null): bool } $stat = @fstat($fd); + if ($stat === false) { + return false; + } // Check if formatted mode is S_IFCHR - return $stat ? 0020000 === ($stat['mode'] & 0170000) : false; + return 0020000 === ($stat['mode'] & 0170000); } /** @@ -250,7 +296,7 @@ private static function isVirtualBoxGuest(): bool if (function_exists('posix_getpwuid') && function_exists('posix_geteuid')) { $processUser = posix_getpwuid(posix_geteuid()); - if ($processUser && $processUser['name'] === 'vagrant') { + if (is_array($processUser) && $processUser['name'] === 'vagrant') { return self::$isVirtualBoxGuest = true; } } diff --git a/vendor/composer/composer/src/Composer/Util/ProcessExecutor.php b/vendor/composer/composer/src/Composer/Util/ProcessExecutor.php index 25e4c90..bf4b498 100644 --- a/vendor/composer/composer/src/Composer/Util/ProcessExecutor.php +++ b/vendor/composer/composer/src/Composer/Util/ProcessExecutor.php @@ -33,6 +33,13 @@ class ProcessExecutor private const STATUS_FAILED = 4; private const STATUS_ABORTED = 5; + private const GIT_CMDS_NEED_GIT_DIR = [ + ['show'], + ['log'], + ['branch'], + ['remote', 'set-url'] + ]; + /** @var int */ protected static $timeout = 300; @@ -97,22 +104,18 @@ public function executeTty($command, ?string $cwd = null): int /** * @param string|list $command + * @param array|null $env * @param mixed $output */ - private function doExecute($command, ?string $cwd, bool $tty, &$output = null): int + private function runProcess($command, ?string $cwd, ?array $env, bool $tty, &$output = null): ?int { - $this->outputCommandRun($command, $cwd, false); - - $this->captureOutput = func_num_args() > 3; - $this->errorOutput = ''; - if (is_string($command)) { - $process = Process::fromShellCommandline($command, $cwd, null, null, static::getTimeout()); + $process = Process::fromShellCommandline($command, $cwd, $env, null, static::getTimeout()); } else { - $process = new Process($command, $cwd, null, null, static::getTimeout()); + $process = new Process($command, $cwd, $env, null, static::getTimeout()); } - if (!Platform::isWindows() && $tty) { + if (! Platform::isWindows() && $tty) { try { $process->setTty(true); } catch (RuntimeException $e) { @@ -124,11 +127,18 @@ private function doExecute($command, ?string $cwd, bool $tty, &$output = null): $this->outputHandler($type, $buffer); }; - $signalHandler = SignalHandler::create([SignalHandler::SIGINT, SignalHandler::SIGTERM, SignalHandler::SIGHUP], function (string $signal) { - if ($this->io !== null) { - $this->io->writeError('Received '.$signal.', aborting when child process is done', true, IOInterface::DEBUG); + $signalHandler = SignalHandler::create( + [SignalHandler::SIGINT, SignalHandler::SIGTERM, SignalHandler::SIGHUP], + function (string $signal) { + if ($this->io !== null) { + $this->io->writeError( + 'Received '.$signal.', aborting when child process is done', + true, + IOInterface::DEBUG + ); + } } - }); + ); try { $process->run($callback); @@ -150,6 +160,35 @@ private function doExecute($command, ?string $cwd, bool $tty, &$output = null): return $process->getExitCode(); } + /** + * @param string|list $command + * @param mixed $output + */ + private function doExecute($command, ?string $cwd, bool $tty, &$output = null): int + { + $this->outputCommandRun($command, $cwd, false); + + $this->captureOutput = func_num_args() > 3; + $this->errorOutput = ''; + + $env = null; + + $requiresGitDirEnv = $this->requiresGitDirEnv($command); + if ($cwd !== null && $requiresGitDirEnv) { + $isBareRepository = !is_dir(sprintf('%s/.git', rtrim($cwd, '/'))); + if ($isBareRepository) { + $configValue = ''; + $this->runProcess('git config safe.bareRepository', $cwd, ['GIT_DIR' => $cwd], $tty, $configValue); + $configValue = trim($configValue); + if ($configValue === 'explicit') { + $env = ['GIT_DIR' => $cwd]; + } + } + } + + return $this->runProcess($command, $cwd, $env, $tty, $output); + } + /** * starts a process on the commandline in async mode * @@ -416,8 +455,6 @@ private function outputCommandRun($command, ?string $cwd, bool $async): void $commandString = is_string($command) ? $command : implode(' ', array_map(self::class.'::escape', $command)); $safeCommand = Preg::replaceCallback('{://(?P[^:/\s]+):(?P[^@\s/]+)@}i', static function ($m): string { - assert(is_string($m['user'])); - // if the username looks like a long (12char+) hex string, or a modern github token (e.g. ghp_xxx) we obfuscate that if (Preg::isMatch('{^([a-f0-9]{12,}|gh[a-z]_[a-zA-Z0-9_]+)$}', $m['user'])) { return '://***:***@'; @@ -456,7 +493,23 @@ private static function escapeArgument($argument): string } // New lines break cmd.exe command parsing - $argument = strtr($argument, "\n", ' '); + // and special chars like the fullwidth quote can be used to break out + // of parameter encoding via "Best Fit" encoding conversion + $argument = strtr($argument, [ + "\n" => ' ', + "\u{ff02}" => '"', + "\u{02ba}" => '"', + "\u{301d}" => '"', + "\u{301e}" => '"', + "\u{030e}" => '"', + "\u{ff1a}" => ':', + "\u{0589}" => ':', + "\u{2236}" => ':', + "\u{ff0f}" => '/', + "\u{2044}" => '/', + "\u{2215}" => '/', + "\u{00b4}" => '/', + ]); // In addition to whitespace, commas need quoting to preserve paths $quote = strpbrk($argument, " \t,") !== false; @@ -478,4 +531,23 @@ private static function escapeArgument($argument): string return $argument; } + + /** + * @param string[]|string $command + */ + public function requiresGitDirEnv($command): bool + { + $cmd = !is_array($command) ? explode(' ', $command) : $command; + if ($cmd[0] !== 'git') { + return false; + } + + foreach (self::GIT_CMDS_NEED_GIT_DIR as $gitCmd) { + if (array_intersect($cmd, $gitCmd) === $gitCmd) { + return true; + } + } + + return false; + } } diff --git a/vendor/composer/composer/src/Composer/Util/RemoteFilesystem.php b/vendor/composer/composer/src/Composer/Util/RemoteFilesystem.php index 0cc9df7..cafdee2 100644 --- a/vendor/composer/composer/src/Composer/Util/RemoteFilesystem.php +++ b/vendor/composer/composer/src/Composer/Util/RemoteFilesystem.php @@ -64,8 +64,6 @@ class RemoteFilesystem private $redirects; /** @var int */ private $maxRedirects = 20; - /** @var ProxyManager */ - private $proxyManager; /** * Constructor. @@ -91,7 +89,6 @@ public function __construct(IOInterface $io, Config $config, array $options = [] $this->options = array_replace_recursive($this->options, $options); $this->config = $config; $this->authHelper = $authHelper ?? new AuthHelper($io, $config); - $this->proxyManager = ProxyManager::getInstance(); } /** @@ -249,6 +246,10 @@ protected function get(string $originUrl, string $fileUrl, array $additionalOpti $origFileUrl = $fileUrl; + if (isset($options['prevent_ip_access_callable'])) { + throw new \RuntimeException("RemoteFilesystem doesn't support the 'prevent_ip_access_callable' config."); + } + if (isset($options['gitlab-token'])) { $fileUrl .= (false === strpos($fileUrl, '?') ? '?' : '&') . 'access_token='.$options['gitlab-token']; unset($options['gitlab-token']); @@ -272,8 +273,8 @@ protected function get(string $originUrl, string $fileUrl, array $additionalOpti $ctx = StreamContextFactory::getContext($fileUrl, $options, ['notification' => [$this, 'callbackGet']]); - $proxy = $this->proxyManager->getProxyForRequest($fileUrl); - $usingProxy = $proxy->getFormattedUrl(' using proxy (%s)'); + $proxy = ProxyManager::getInstance()->getProxyForRequest($fileUrl); + $usingProxy = $proxy->getStatus(' using proxy (%s)'); $this->io->writeError((strpos($origFileUrl, 'http') === 0 ? 'Downloading ' : 'Reading ') . Url::sanitize($origFileUrl) . $usingProxy, true, IOInterface::DEBUG); unset($origFileUrl, $proxy, $usingProxy); @@ -532,7 +533,12 @@ protected function getRemoteContents(string $originUrl, string $fileUrl, $contex } // https://www.php.net/manual/en/reserved.variables.httpresponseheader.php - $responseHeaders = $http_response_header ?? []; + if (\PHP_VERSION_ID >= 80400) { + $responseHeaders = http_get_last_response_headers(); + http_clear_last_response_headers(); + } else { + $responseHeaders = $http_response_header ?? []; + } if (null !== $e) { throw $e; diff --git a/vendor/composer/composer/src/Composer/Util/Silencer.php b/vendor/composer/composer/src/Composer/Util/Silencer.php index f2b9f73..6dd0efb 100644 --- a/vendor/composer/composer/src/Composer/Util/Silencer.php +++ b/vendor/composer/composer/src/Composer/Util/Silencer.php @@ -33,7 +33,7 @@ class Silencer public static function suppress(?int $mask = null): int { if (!isset($mask)) { - $mask = E_WARNING | E_NOTICE | E_USER_WARNING | E_USER_NOTICE | E_DEPRECATED | E_USER_DEPRECATED | E_STRICT; + $mask = E_WARNING | E_NOTICE | E_USER_WARNING | E_USER_NOTICE | E_DEPRECATED | E_USER_DEPRECATED; } $old = error_reporting(); self::$stack[] = $old; diff --git a/vendor/composer/composer/src/Composer/Util/StreamContextFactory.php b/vendor/composer/composer/src/Composer/Util/StreamContextFactory.php index 57fbe0f..be4c976 100644 --- a/vendor/composer/composer/src/Composer/Util/StreamContextFactory.php +++ b/vendor/composer/composer/src/Composer/Util/StreamContextFactory.php @@ -76,7 +76,8 @@ public static function initOptions(string $url, array $options, bool $forCurl = // Add stream proxy options if there is a proxy if (!$forCurl) { $proxy = ProxyManager::getInstance()->getProxyForRequest($url); - if ($proxyOptions = $proxy->getContextOptions()) { + $proxyOptions = $proxy->getContextOptions(); + if ($proxyOptions !== null) { $isHttpsRequest = 0 === strpos($url, 'https://'); if ($proxy->isSecure()) { diff --git a/vendor/composer/composer/src/Composer/Util/TlsHelper.php b/vendor/composer/composer/src/Composer/Util/TlsHelper.php index aca2272..da0801a 100644 --- a/vendor/composer/composer/src/Composer/Util/TlsHelper.php +++ b/vendor/composer/composer/src/Composer/Util/TlsHelper.php @@ -76,13 +76,18 @@ public static function getCertificateNames($certificate): ?array if (isset($info['extensions']['subjectAltName'])) { $subjectAltNames = Preg::split('{\s*,\s*}', $info['extensions']['subjectAltName']); - $subjectAltNames = array_filter(array_map(static function ($name): ?string { - if (0 === strpos($name, 'DNS:')) { - return strtolower(ltrim(substr($name, 4))); + $subjectAltNames = array_filter( + array_map(static function ($name): ?string { + if (0 === strpos($name, 'DNS:')) { + return strtolower(ltrim(substr($name, 4))); + } + + return null; + }, $subjectAltNames), + function (?string $san) { + return $san !== null; } - - return null; - }, $subjectAltNames)); + ); $subjectAltNames = array_values($subjectAltNames); } @@ -145,7 +150,7 @@ public static function getCertificateFingerprint(string $certificate): string $pemtrim = substr($pubkeypem, strpos($pubkeypem, $start) + strlen($start), (strlen($pubkeypem) - strpos($pubkeypem, $end)) * (-1)); $der = base64_decode($pemtrim); - return sha1($der); + return hash('sha1', $der); } /** diff --git a/vendor/composer/composer/src/Composer/Util/Url.php b/vendor/composer/composer/src/Composer/Util/Url.php index 5d703a2..32f6134 100644 --- a/vendor/composer/composer/src/Composer/Util/Url.php +++ b/vendor/composer/composer/src/Composer/Util/Url.php @@ -75,7 +75,7 @@ public static function getOrigin(Config $config, string $url): string $origin .= ':'.$port; } - if (strpos($origin, '.github.com') === (strlen($origin) - 11)) { + if (str_ends_with($origin, '.github.com') && $origin !== 'codeload.github.com') { return 'github.com'; } @@ -110,7 +110,6 @@ public static function sanitize(string $url): string $url = Preg::replace('{([&?]access_token=)[^&]+}', '$1***', $url); $url = Preg::replaceCallback('{^(?P[a-z0-9]+://)?(?P[^:/\s@]+):(?P[^@\s/]+)@}i', static function ($m): string { - assert(is_string($m['user'])); // if the username looks like a long (12char+) hex string, or a modern github token (e.g. ghp_xxx) we obfuscate that if (Preg::isMatch('{^([a-f0-9]{12,}|gh[a-z]_[a-zA-Z0-9_]+|github_pat_[a-zA-Z0-9_]+)$}', $m['user'])) { return $m['prefix'].'***:***@'; diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index a3729d2..733b2ec 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -2,17 +2,17 @@ "packages": [ { "name": "composer/ca-bundle", - "version": "1.5.0", - "version_normalized": "1.5.0.0", + "version": "1.5.2", + "version_normalized": "1.5.2.0", "source": { "type": "git", "url": "https://github.com/composer/ca-bundle.git", - "reference": "0c5ccfcfea312b5c5a190a21ac5cef93f74baf99" + "reference": "48a792895a2b7a6ee65dd5442c299d7b835b6137" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/ca-bundle/zipball/0c5ccfcfea312b5c5a190a21ac5cef93f74baf99", - "reference": "0c5ccfcfea312b5c5a190a21ac5cef93f74baf99", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/48a792895a2b7a6ee65dd5442c299d7b835b6137", + "reference": "48a792895a2b7a6ee65dd5442c299d7b835b6137", "shasum": "" }, "require": { @@ -22,11 +22,11 @@ }, "require-dev": { "phpstan/phpstan": "^1.10", - "psr/log": "^1.0", - "symfony/phpunit-bridge": "^4.2 || ^5", + "phpunit/phpunit": "^8 || ^9", + "psr/log": "^1.0 || ^2.0 || ^3.0", "symfony/process": "^4.0 || ^5.0 || ^6.0 || ^7.0" }, - "time": "2024-03-15T14:00:32+00:00", + "time": "2024-09-25T07:49:53+00:00", "type": "library", "extra": { "branch-alias": { @@ -61,7 +61,7 @@ "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/ca-bundle/issues", - "source": "https://github.com/composer/ca-bundle/tree/1.5.0" + "source": "https://github.com/composer/ca-bundle/tree/1.5.2" }, "funding": [ { @@ -81,17 +81,17 @@ }, { "name": "composer/class-map-generator", - "version": "1.1.1", - "version_normalized": "1.1.1.0", + "version": "1.4.0", + "version_normalized": "1.4.0.0", "source": { "type": "git", "url": "https://github.com/composer/class-map-generator.git", - "reference": "8286a62d243312ed99b3eee20d5005c961adb311" + "reference": "98bbf6780e56e0fd2404fe4b82eb665a0f93b783" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/class-map-generator/zipball/8286a62d243312ed99b3eee20d5005c961adb311", - "reference": "8286a62d243312ed99b3eee20d5005c961adb311", + "url": "https://api.github.com/repos/composer/class-map-generator/zipball/98bbf6780e56e0fd2404fe4b82eb665a0f93b783", + "reference": "98bbf6780e56e0fd2404fe4b82eb665a0f93b783", "shasum": "" }, "require": { @@ -104,10 +104,10 @@ "phpstan/phpstan-deprecation-rules": "^1", "phpstan/phpstan-phpunit": "^1", "phpstan/phpstan-strict-rules": "^1.1", - "symfony/filesystem": "^5.4 || ^6", - "symfony/phpunit-bridge": "^5" + "phpunit/phpunit": "^8", + "symfony/filesystem": "^5.4 || ^6" }, - "time": "2024-03-15T12:53:41+00:00", + "time": "2024-10-03T18:14:00+00:00", "type": "library", "extra": { "branch-alias": { @@ -137,7 +137,7 @@ ], "support": { "issues": "https://github.com/composer/class-map-generator/issues", - "source": "https://github.com/composer/class-map-generator/tree/1.1.1" + "source": "https://github.com/composer/class-map-generator/tree/1.4.0" }, "funding": [ { @@ -157,63 +157,63 @@ }, { "name": "composer/composer", - "version": "2.7.2", - "version_normalized": "2.7.2.0", + "version": "2.8.1", + "version_normalized": "2.8.1.0", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "b826edb791571ab1eaf281eb1bd6e181a1192adc" + "reference": "e52b8672276cf436670cdd6bd5de4353740e83b2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/b826edb791571ab1eaf281eb1bd6e181a1192adc", - "reference": "b826edb791571ab1eaf281eb1bd6e181a1192adc", + "url": "https://api.github.com/repos/composer/composer/zipball/e52b8672276cf436670cdd6bd5de4353740e83b2", + "reference": "e52b8672276cf436670cdd6bd5de4353740e83b2", "shasum": "" }, "require": { - "composer/ca-bundle": "^1.0", - "composer/class-map-generator": "^1.0", + "composer/ca-bundle": "^1.5", + "composer/class-map-generator": "^1.4.0", "composer/metadata-minifier": "^1.0", - "composer/pcre": "^2.1 || ^3.1", - "composer/semver": "^3.2.5", + "composer/pcre": "^2.2 || ^3.2", + "composer/semver": "^3.3", "composer/spdx-licenses": "^1.5.7", "composer/xdebug-handler": "^2.0.2 || ^3.0.3", - "justinrainbow/json-schema": "^5.2.11", + "justinrainbow/json-schema": "^5.3", "php": "^7.2.5 || ^8.0", "psr/log": "^1.0 || ^2.0 || ^3.0", - "react/promise": "^2.8 || ^3", + "react/promise": "^3.2", "seld/jsonlint": "^1.4", "seld/phar-utils": "^1.2", "seld/signal-handler": "^2.0", - "symfony/console": "^5.4.11 || ^6.0.11 || ^7", - "symfony/filesystem": "^5.4 || ^6.0 || ^7", - "symfony/finder": "^5.4 || ^6.0 || ^7", + "symfony/console": "^5.4.35 || ^6.3.12 || ^7.0.3", + "symfony/filesystem": "^5.4.35 || ^6.3.12 || ^7.0.3", + "symfony/finder": "^5.4.35 || ^6.3.12 || ^7.0.3", "symfony/polyfill-php73": "^1.24", "symfony/polyfill-php80": "^1.24", "symfony/polyfill-php81": "^1.24", - "symfony/process": "^5.4 || ^6.0 || ^7" + "symfony/process": "^5.4.35 || ^6.3.12 || ^7.0.3" }, "require-dev": { - "phpstan/phpstan": "^1.9.3", - "phpstan/phpstan-deprecation-rules": "^1", - "phpstan/phpstan-phpunit": "^1.0", - "phpstan/phpstan-strict-rules": "^1", - "phpstan/phpstan-symfony": "^1.2.10", - "symfony/phpunit-bridge": "^6.4.1 || ^7.0.1" + "phpstan/phpstan": "^1.11.8", + "phpstan/phpstan-deprecation-rules": "^1.2.0", + "phpstan/phpstan-phpunit": "^1.4.0", + "phpstan/phpstan-strict-rules": "^1.6.0", + "phpstan/phpstan-symfony": "^1.4.0", + "symfony/phpunit-bridge": "^6.4.3 || ^7.0.1" }, "suggest": { "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages", "ext-zip": "Enabling the zip extension allows you to unzip archives", "ext-zlib": "Allow gzip compression of HTTP requests" }, - "time": "2024-03-11T16:12:18+00:00", + "time": "2024-10-04T09:31:01+00:00", "bin": [ "bin/composer" ], "type": "library", "extra": { "branch-alias": { - "dev-main": "2.7-dev" + "dev-main": "2.8-dev" }, "phpstan": { "includes": [ @@ -254,7 +254,7 @@ "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/composer/issues", "security": "https://github.com/composer/composer/security/policy", - "source": "https://github.com/composer/composer/tree/2.7.2" + "source": "https://github.com/composer/composer/tree/2.8.1" }, "funding": [ { @@ -274,41 +274,39 @@ }, { "name": "composer/installers", - "version": "v1.12.0", - "version_normalized": "1.12.0.0", + "version": "v2.3.0", + "version_normalized": "2.3.0.0", "source": { "type": "git", "url": "https://github.com/composer/installers.git", - "reference": "d20a64ed3c94748397ff5973488761b22f6d3f19" + "reference": "12fb2dfe5e16183de69e784a7b84046c43d97e8e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/installers/zipball/d20a64ed3c94748397ff5973488761b22f6d3f19", - "reference": "d20a64ed3c94748397ff5973488761b22f6d3f19", + "url": "https://api.github.com/repos/composer/installers/zipball/12fb2dfe5e16183de69e784a7b84046c43d97e8e", + "reference": "12fb2dfe5e16183de69e784a7b84046c43d97e8e", "shasum": "" }, "require": { - "composer-plugin-api": "^1.0 || ^2.0" - }, - "replace": { - "roundcube/plugin-installer": "*", - "shama/baton": "*" + "composer-plugin-api": "^1.0 || ^2.0", + "php": "^7.2 || ^8.0" }, "require-dev": { - "composer/composer": "1.6.* || ^2.0", - "composer/semver": "^1 || ^3", - "phpstan/phpstan": "^0.12.55", - "phpstan/phpstan-phpunit": "^0.12.16", - "symfony/phpunit-bridge": "^4.2 || ^5", - "symfony/process": "^2.3" + "composer/composer": "^1.10.27 || ^2.7", + "composer/semver": "^1.7.2 || ^3.4.0", + "phpstan/phpstan": "^1.11", + "phpstan/phpstan-phpunit": "^1", + "symfony/phpunit-bridge": "^7.1.1", + "symfony/process": "^5 || ^6 || ^7" }, - "time": "2021-09-13T08:19:44+00:00", + "time": "2024-06-24T20:46:46+00:00", "type": "composer-plugin", "extra": { "class": "Composer\\Installers\\Plugin", "branch-alias": { - "dev-main": "1.x-dev" - } + "dev-main": "2.x-dev" + }, + "plugin-modifies-install-path": true }, "installation-source": "dist", "autoload": { @@ -330,7 +328,6 @@ "description": "A multi-framework Composer library installer", "homepage": "https://composer.github.io/installers/", "keywords": [ - "Craft", "Dolibarr", "Eliasis", "Hurad", @@ -351,7 +348,6 @@ "Whmcs", "WolfCMS", "agl", - "aimeos", "annotatecms", "attogram", "bitrix", @@ -360,6 +356,7 @@ "cockpit", "codeigniter", "concrete5", + "concreteCMS", "croogo", "dokuwiki", "drupal", @@ -370,7 +367,6 @@ "grav", "installer", "itop", - "joomla", "known", "kohana", "laravel", @@ -379,6 +375,7 @@ "magento", "majima", "mako", + "matomo", "mediawiki", "miaoxing", "modulework", @@ -398,9 +395,7 @@ "silverstripe", "sydes", "sylius", - "symfony", "tastyigniter", - "typo3", "wordpress", "yawik", "zend", @@ -408,7 +403,7 @@ ], "support": { "issues": "https://github.com/composer/installers/issues", - "source": "https://github.com/composer/installers/tree/v1.12.0" + "source": "https://github.com/composer/installers/tree/v2.3.0" }, "funding": [ { @@ -500,32 +495,40 @@ }, { "name": "composer/pcre", - "version": "3.1.3", - "version_normalized": "3.1.3.0", + "version": "3.3.1", + "version_normalized": "3.3.1.0", "source": { "type": "git", "url": "https://github.com/composer/pcre.git", - "reference": "5b16e25a5355f1f3afdfc2f954a0a80aec4826a8" + "reference": "63aaeac21d7e775ff9bc9d45021e1745c97521c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/5b16e25a5355f1f3afdfc2f954a0a80aec4826a8", - "reference": "5b16e25a5355f1f3afdfc2f954a0a80aec4826a8", + "url": "https://api.github.com/repos/composer/pcre/zipball/63aaeac21d7e775ff9bc9d45021e1745c97521c4", + "reference": "63aaeac21d7e775ff9bc9d45021e1745c97521c4", "shasum": "" }, "require": { "php": "^7.4 || ^8.0" }, + "conflict": { + "phpstan/phpstan": "<1.11.10" + }, "require-dev": { - "phpstan/phpstan": "^1.3", + "phpstan/phpstan": "^1.11.10", "phpstan/phpstan-strict-rules": "^1.1", - "symfony/phpunit-bridge": "^5" + "phpunit/phpunit": "^8 || ^9" }, - "time": "2024-03-19T10:26:25+00:00", + "time": "2024-08-27T18:44:43+00:00", "type": "library", "extra": { "branch-alias": { "dev-main": "3.x-dev" + }, + "phpstan": { + "includes": [ + "extension.neon" + ] } }, "installation-source": "dist", @@ -554,7 +557,7 @@ ], "support": { "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/3.1.3" + "source": "https://github.com/composer/pcre/tree/3.3.1" }, "funding": [ { @@ -574,27 +577,27 @@ }, { "name": "composer/semver", - "version": "3.4.0", - "version_normalized": "3.4.0.0", + "version": "3.4.3", + "version_normalized": "3.4.3.0", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32" + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/35e8d0af4486141bc745f23a29cc2091eb624a32", - "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32", + "url": "https://api.github.com/repos/composer/semver/zipball/4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", "shasum": "" }, "require": { "php": "^5.3.2 || ^7.0 || ^8.0" }, "require-dev": { - "phpstan/phpstan": "^1.4", - "symfony/phpunit-bridge": "^4.2 || ^5" + "phpstan/phpstan": "^1.11", + "symfony/phpunit-bridge": "^3 || ^7" }, - "time": "2023-08-31T09:50:34+00:00", + "time": "2024-09-19T14:15:21+00:00", "type": "library", "extra": { "branch-alias": { @@ -638,7 +641,7 @@ "support": { "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.4.0" + "source": "https://github.com/composer/semver/tree/3.4.3" }, "funding": [ { @@ -741,17 +744,17 @@ }, { "name": "composer/xdebug-handler", - "version": "3.0.4", - "version_normalized": "3.0.4.0", + "version": "3.0.5", + "version_normalized": "3.0.5.0", "source": { "type": "git", "url": "https://github.com/composer/xdebug-handler.git", - "reference": "4f988f8fdf580d53bdb2d1278fe93d1ed5462255" + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/4f988f8fdf580d53bdb2d1278fe93d1ed5462255", - "reference": "4f988f8fdf580d53bdb2d1278fe93d1ed5462255", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef", "shasum": "" }, "require": { @@ -764,7 +767,7 @@ "phpstan/phpstan-strict-rules": "^1.1", "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5" }, - "time": "2024-03-26T18:29:49+00:00", + "time": "2024-05-06T16:37:16+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -790,7 +793,7 @@ "support": { "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/xdebug-handler/issues", - "source": "https://github.com/composer/xdebug-handler/tree/3.0.4" + "source": "https://github.com/composer/xdebug-handler/tree/3.0.5" }, "funding": [ { @@ -810,37 +813,32 @@ }, { "name": "justinrainbow/json-schema", - "version": "v5.2.13", - "version_normalized": "5.2.13.0", + "version": "5.3.0", + "version_normalized": "5.3.0.0", "source": { "type": "git", - "url": "https://github.com/justinrainbow/json-schema.git", - "reference": "fbbe7e5d79f618997bc3332a6f49246036c45793" + "url": "https://github.com/jsonrainbow/json-schema.git", + "reference": "feb2ca6dd1cebdaf1ed60a4c8de2e53ce11c4fd8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/fbbe7e5d79f618997bc3332a6f49246036c45793", - "reference": "fbbe7e5d79f618997bc3332a6f49246036c45793", + "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/feb2ca6dd1cebdaf1ed60a4c8de2e53ce11c4fd8", + "reference": "feb2ca6dd1cebdaf1ed60a4c8de2e53ce11c4fd8", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "require-dev": { "friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1", "json-schema/json-schema-test-suite": "1.2.0", "phpunit/phpunit": "^4.8.35" }, - "time": "2023-09-26T02:20:38+00:00", + "time": "2024-07-06T21:00:26+00:00", "bin": [ "bin/validate-json" ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0.x-dev" - } - }, "installation-source": "dist", "autoload": { "psr-4": { @@ -876,81 +874,11 @@ "schema" ], "support": { - "issues": "https://github.com/justinrainbow/json-schema/issues", - "source": "https://github.com/justinrainbow/json-schema/tree/v5.2.13" + "issues": "https://github.com/jsonrainbow/json-schema/issues", + "source": "https://github.com/jsonrainbow/json-schema/tree/5.3.0" }, "install-path": "../justinrainbow/json-schema" }, - { - "name": "oyejorge/less.php", - "version": "v1.7.0.14", - "version_normalized": "1.7.0.14", - "source": { - "type": "git", - "url": "https://github.com/oyejorge/less.php.git", - "reference": "42925c5a01a07d67ca7e82dfc8fb31814d557bc9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/oyejorge/less.php/zipball/42925c5a01a07d67ca7e82dfc8fb31814d557bc9", - "reference": "42925c5a01a07d67ca7e82dfc8fb31814d557bc9", - "shasum": "" - }, - "require": { - "php": ">=5.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.8.24" - }, - "time": "2017-03-28T22:19:25+00:00", - "bin": [ - "bin/lessc" - ], - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-0": { - "Less": "lib/" - }, - "classmap": [ - "lessc.inc.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "Matt Agar", - "homepage": "https://github.com/agar" - }, - { - "name": "Martin Jantošovič", - "homepage": "https://github.com/Mordred" - }, - { - "name": "Josh Schmidt", - "homepage": "https://github.com/oyejorge" - } - ], - "description": "PHP port of the Javascript version of LESS http://lesscss.org (Originally maintained by Josh Schmidt)", - "homepage": "http://lessphp.gpeasy.com", - "keywords": [ - "css", - "less", - "less.js", - "lesscss", - "php", - "stylesheet" - ], - "support": { - "issues": "https://github.com/oyejorge/less.php/issues", - "source": "https://github.com/oyejorge/less.php/tree/master" - }, - "abandoned": true, - "install-path": "../oyejorge/less.php" - }, { "name": "psr/container", "version": "2.0.2", @@ -1009,23 +937,23 @@ }, { "name": "psr/log", - "version": "3.0.0", - "version_normalized": "3.0.0.0", + "version": "3.0.2", + "version_normalized": "3.0.2.0", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", "shasum": "" }, "require": { "php": ">=8.0.0" }, - "time": "2021-07-14T16:46:02+00:00", + "time": "2024-09-11T13:17:53+00:00", "type": "library", "extra": { "branch-alias": { @@ -1056,23 +984,23 @@ "psr-3" ], "support": { - "source": "https://github.com/php-fig/log/tree/3.0.0" + "source": "https://github.com/php-fig/log/tree/3.0.2" }, "install-path": "../psr/log" }, { "name": "react/promise", - "version": "v3.1.0", - "version_normalized": "3.1.0.0", + "version": "v3.2.0", + "version_normalized": "3.2.0.0", "source": { "type": "git", "url": "https://github.com/reactphp/promise.git", - "reference": "e563d55d1641de1dea9f5e84f3cccc66d2bfe02c" + "reference": "8a164643313c71354582dc850b42b33fa12a4b63" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/reactphp/promise/zipball/e563d55d1641de1dea9f5e84f3cccc66d2bfe02c", - "reference": "e563d55d1641de1dea9f5e84f3cccc66d2bfe02c", + "url": "https://api.github.com/repos/reactphp/promise/zipball/8a164643313c71354582dc850b42b33fa12a4b63", + "reference": "8a164643313c71354582dc850b42b33fa12a4b63", "shasum": "" }, "require": { @@ -1082,7 +1010,7 @@ "phpstan/phpstan": "1.10.39 || 1.4.10", "phpunit/phpunit": "^9.6 || ^7.5" }, - "time": "2023-11-16T16:21:57+00:00", + "time": "2024-05-24T10:39:05+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -1126,7 +1054,7 @@ ], "support": { "issues": "https://github.com/reactphp/promise/issues", - "source": "https://github.com/reactphp/promise/tree/v3.1.0" + "source": "https://github.com/reactphp/promise/tree/v3.2.0" }, "funding": [ { @@ -1138,27 +1066,27 @@ }, { "name": "seld/jsonlint", - "version": "1.10.2", - "version_normalized": "1.10.2.0", + "version": "1.11.0", + "version_normalized": "1.11.0.0", "source": { "type": "git", "url": "https://github.com/Seldaek/jsonlint.git", - "reference": "9bb7db07b5d66d90f6ebf542f09fc67d800e5259" + "reference": "1748aaf847fc731cfad7725aec413ee46f0cc3a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/9bb7db07b5d66d90f6ebf542f09fc67d800e5259", - "reference": "9bb7db07b5d66d90f6ebf542f09fc67d800e5259", + "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/1748aaf847fc731cfad7725aec413ee46f0cc3a2", + "reference": "1748aaf847fc731cfad7725aec413ee46f0cc3a2", "shasum": "" }, "require": { "php": "^5.3 || ^7.0 || ^8.0" }, "require-dev": { - "phpstan/phpstan": "^1.5", + "phpstan/phpstan": "^1.11", "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^8.5.13" }, - "time": "2024-02-07T12:57:50+00:00", + "time": "2024-07-11T14:55:45+00:00", "bin": [ "bin/jsonlint" ], @@ -1189,7 +1117,7 @@ ], "support": { "issues": "https://github.com/Seldaek/jsonlint/issues", - "source": "https://github.com/Seldaek/jsonlint/tree/1.10.2" + "source": "https://github.com/Seldaek/jsonlint/tree/1.11.0" }, "funding": [ { @@ -1320,50 +1248,49 @@ }, { "name": "symfony/console", - "version": "v6.4.4", - "version_normalized": "6.4.4.0", + "version": "v7.1.5", + "version_normalized": "7.1.5.0", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "0d9e4eb5ad413075624378f474c4167ea202de78" + "reference": "0fa539d12b3ccf068a722bbbffa07ca7079af9ee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/0d9e4eb5ad413075624378f474c4167ea202de78", - "reference": "0d9e4eb5ad413075624378f474c4167ea202de78", + "url": "https://api.github.com/repos/symfony/console/zipball/0fa539d12b3ccf068a722bbbffa07ca7079af9ee", + "reference": "0fa539d12b3ccf068a722bbbffa07ca7079af9ee", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", + "php": ">=8.2", "symfony/polyfill-mbstring": "~1.0", "symfony/service-contracts": "^2.5|^3", - "symfony/string": "^5.4|^6.0|^7.0" + "symfony/string": "^6.4|^7.0" }, "conflict": { - "symfony/dependency-injection": "<5.4", - "symfony/dotenv": "<5.4", - "symfony/event-dispatcher": "<5.4", - "symfony/lock": "<5.4", - "symfony/process": "<5.4" + "symfony/dependency-injection": "<6.4", + "symfony/dotenv": "<6.4", + "symfony/event-dispatcher": "<6.4", + "symfony/lock": "<6.4", + "symfony/process": "<6.4" }, "provide": { "psr/log-implementation": "1.0|2.0|3.0" }, "require-dev": { "psr/log": "^1|^2|^3", - "symfony/config": "^5.4|^6.0|^7.0", - "symfony/dependency-injection": "^5.4|^6.0|^7.0", - "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", "symfony/http-foundation": "^6.4|^7.0", "symfony/http-kernel": "^6.4|^7.0", - "symfony/lock": "^5.4|^6.0|^7.0", - "symfony/messenger": "^5.4|^6.0|^7.0", - "symfony/process": "^5.4|^6.0|^7.0", - "symfony/stopwatch": "^5.4|^6.0|^7.0", - "symfony/var-dumper": "^5.4|^6.0|^7.0" + "symfony/lock": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" }, - "time": "2024-02-22T20:27:10+00:00", + "time": "2024-09-20T08:28:38+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -1397,7 +1324,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.4.4" + "source": "https://github.com/symfony/console/tree/v7.1.5" }, "funding": [ { @@ -1417,27 +1344,27 @@ }, { "name": "symfony/deprecation-contracts", - "version": "v3.4.0", - "version_normalized": "3.4.0.0", + "version": "v3.5.0", + "version_normalized": "3.5.0.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" + "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", + "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", "shasum": "" }, "require": { "php": ">=8.1" }, - "time": "2023-05-23T14:45:45+00:00", + "time": "2024-04-18T09:32:20+00:00", "type": "library", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -1467,7 +1394,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.0" }, "funding": [ { @@ -1487,25 +1414,28 @@ }, { "name": "symfony/filesystem", - "version": "v6.4.3", - "version_normalized": "6.4.3.0", + "version": "v7.1.5", + "version_normalized": "7.1.5.0", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "7f3b1755eb49297a0827a7575d5d2b2fd11cc9fb" + "reference": "61fe0566189bf32e8cfee78335d8776f64a66f5a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/7f3b1755eb49297a0827a7575d5d2b2fd11cc9fb", - "reference": "7f3b1755eb49297a0827a7575d5d2b2fd11cc9fb", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/61fe0566189bf32e8cfee78335d8776f64a66f5a", + "reference": "61fe0566189bf32e8cfee78335d8776f64a66f5a", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.8" }, - "time": "2024-01-23T14:51:35+00:00", + "require-dev": { + "symfony/process": "^6.4|^7.0" + }, + "time": "2024-09-17T09:16:35+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -1533,7 +1463,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v6.4.3" + "source": "https://github.com/symfony/filesystem/tree/v7.1.5" }, "funding": [ { @@ -1553,26 +1483,26 @@ }, { "name": "symfony/finder", - "version": "v6.4.0", - "version_normalized": "6.4.0.0", + "version": "v7.1.4", + "version_normalized": "7.1.4.0", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "11d736e97f116ac375a81f96e662911a34cd50ce" + "reference": "d95bbf319f7d052082fb7af147e0f835a695e823" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/11d736e97f116ac375a81f96e662911a34cd50ce", - "reference": "11d736e97f116ac375a81f96e662911a34cd50ce", + "url": "https://api.github.com/repos/symfony/finder/zipball/d95bbf319f7d052082fb7af147e0f835a695e823", + "reference": "d95bbf319f7d052082fb7af147e0f835a695e823", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "symfony/filesystem": "^6.0|^7.0" + "symfony/filesystem": "^6.4|^7.0" }, - "time": "2023-10-31T17:30:12+00:00", + "time": "2024-08-13T14:28:19+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -1600,7 +1530,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v6.4.0" + "source": "https://github.com/symfony/finder/tree/v7.1.4" }, "funding": [ { @@ -1620,21 +1550,21 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.29.0", - "version_normalized": "1.29.0.0", + "version": "v1.31.0", + "version_normalized": "1.31.0.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4" + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4", - "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-ctype": "*" @@ -1642,7 +1572,7 @@ "suggest": { "ext-ctype": "For best performance" }, - "time": "2024-01-29T20:11:03+00:00", + "time": "2024-09-09T11:45:10+00:00", "type": "library", "extra": { "thanks": { @@ -1682,7 +1612,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0" }, "funding": [ { @@ -1702,26 +1632,26 @@ }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.29.0", - "version_normalized": "1.29.0.0", + "version": "v1.31.0", + "version_normalized": "1.31.0.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f" + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/32a9da87d7b3245e09ac426c83d334ae9f06f80f", - "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "suggest": { "ext-intl": "For best performance" }, - "time": "2024-01-29T20:11:03+00:00", + "time": "2024-09-09T11:45:10+00:00", "type": "library", "extra": { "thanks": { @@ -1763,7 +1693,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.31.0" }, "funding": [ { @@ -1783,26 +1713,26 @@ }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.29.0", - "version_normalized": "1.29.0.0", + "version": "v1.31.0", + "version_normalized": "1.31.0.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "bc45c394692b948b4d383a08d7753968bed9a83d" + "reference": "3833d7255cc303546435cb650316bff708a1c75c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/bc45c394692b948b4d383a08d7753968bed9a83d", - "reference": "bc45c394692b948b4d383a08d7753968bed9a83d", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "suggest": { "ext-intl": "For best performance" }, - "time": "2024-01-29T20:11:03+00:00", + "time": "2024-09-09T11:45:10+00:00", "type": "library", "extra": { "thanks": { @@ -1847,7 +1777,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.31.0" }, "funding": [ { @@ -1867,21 +1797,21 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.29.0", - "version_normalized": "1.29.0.0", + "version": "v1.31.0", + "version_normalized": "1.31.0.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec" + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec", - "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-mbstring": "*" @@ -1889,7 +1819,7 @@ "suggest": { "ext-mbstring": "For best performance" }, - "time": "2024-01-29T20:11:03+00:00", + "time": "2024-09-09T11:45:10+00:00", "type": "library", "extra": { "thanks": { @@ -1930,7 +1860,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0" }, "funding": [ { @@ -1950,23 +1880,23 @@ }, { "name": "symfony/polyfill-php73", - "version": "v1.29.0", - "version_normalized": "1.29.0.0", + "version": "v1.31.0", + "version_normalized": "1.31.0.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "21bd091060673a1177ae842c0ef8fe30893114d2" + "reference": "0f68c03565dcaaf25a890667542e8bd75fe7e5bb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/21bd091060673a1177ae842c0ef8fe30893114d2", - "reference": "21bd091060673a1177ae842c0ef8fe30893114d2", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/0f68c03565dcaaf25a890667542e8bd75fe7e5bb", + "reference": "0f68c03565dcaaf25a890667542e8bd75fe7e5bb", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, - "time": "2024-01-29T20:11:03+00:00", + "time": "2024-09-09T11:45:10+00:00", "type": "library", "extra": { "thanks": { @@ -2009,7 +1939,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-php73/tree/v1.31.0" }, "funding": [ { @@ -2029,23 +1959,23 @@ }, { "name": "symfony/polyfill-php80", - "version": "v1.29.0", - "version_normalized": "1.29.0.0", + "version": "v1.31.0", + "version_normalized": "1.31.0.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b" + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", - "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, - "time": "2024-01-29T20:11:03+00:00", + "time": "2024-09-09T11:45:10+00:00", "type": "library", "extra": { "thanks": { @@ -2092,7 +2022,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.31.0" }, "funding": [ { @@ -2112,23 +2042,23 @@ }, { "name": "symfony/polyfill-php81", - "version": "v1.29.0", - "version_normalized": "1.29.0.0", + "version": "v1.31.0", + "version_normalized": "1.31.0.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "c565ad1e63f30e7477fc40738343c62b40bc672d" + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/c565ad1e63f30e7477fc40738343c62b40bc672d", - "reference": "c565ad1e63f30e7477fc40738343c62b40bc672d", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, - "time": "2024-01-29T20:11:03+00:00", + "time": "2024-09-09T11:45:10+00:00", "type": "library", "extra": { "thanks": { @@ -2171,7 +2101,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-php81/tree/v1.31.0" }, "funding": [ { @@ -2191,24 +2121,23 @@ }, { "name": "symfony/process", - "version": "v5.4.36", - "version_normalized": "5.4.36.0", + "version": "v7.1.5", + "version_normalized": "7.1.5.0", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "4fdf34004f149cc20b2f51d7d119aa500caad975" + "reference": "5c03ee6369281177f07f7c68252a280beccba847" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/4fdf34004f149cc20b2f51d7d119aa500caad975", - "reference": "4fdf34004f149cc20b2f51d7d119aa500caad975", + "url": "https://api.github.com/repos/symfony/process/zipball/5c03ee6369281177f07f7c68252a280beccba847", + "reference": "5c03ee6369281177f07f7c68252a280beccba847", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.2" }, - "time": "2024-02-12T15:49:53+00:00", + "time": "2024-09-19T21:48:23+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -2236,7 +2165,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v5.4.36" + "source": "https://github.com/symfony/process/tree/v7.1.5" }, "funding": [ { @@ -2256,31 +2185,32 @@ }, { "name": "symfony/service-contracts", - "version": "v3.4.1", - "version_normalized": "3.4.1.0", + "version": "v3.5.0", + "version_normalized": "3.5.0.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0" + "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/fe07cbc8d837f60caf7018068e350cc5163681a0", - "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", + "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", "shasum": "" }, "require": { "php": ">=8.1", - "psr/container": "^1.1|^2.0" + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" }, "conflict": { "ext-psr": "<1.1|>=2" }, - "time": "2023-12-26T14:02:43+00:00", + "time": "2024-04-18T09:32:20+00:00", "type": "library", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -2321,7 +2251,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.4.1" + "source": "https://github.com/symfony/service-contracts/tree/v3.5.0" }, "funding": [ { @@ -2341,21 +2271,21 @@ }, { "name": "symfony/string", - "version": "v6.4.4", - "version_normalized": "6.4.4.0", + "version": "v7.1.5", + "version_normalized": "7.1.5.0", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "4e465a95bdc32f49cf4c7f07f751b843bbd6dcd9" + "reference": "d66f9c343fa894ec2037cc928381df90a7ad4306" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/4e465a95bdc32f49cf4c7f07f751b843bbd6dcd9", - "reference": "4e465a95bdc32f49cf4c7f07f751b843bbd6dcd9", + "url": "https://api.github.com/repos/symfony/string/zipball/d66f9c343fa894ec2037cc928381df90a7ad4306", + "reference": "d66f9c343fa894ec2037cc928381df90a7ad4306", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-intl-grapheme": "~1.0", "symfony/polyfill-intl-normalizer": "~1.0", @@ -2365,13 +2295,14 @@ "symfony/translation-contracts": "<2.5" }, "require-dev": { - "symfony/error-handler": "^5.4|^6.0|^7.0", - "symfony/http-client": "^5.4|^6.0|^7.0", - "symfony/intl": "^6.2|^7.0", + "symfony/emoji": "^7.1", + "symfony/error-handler": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", "symfony/translation-contracts": "^2.5|^3.0", - "symfony/var-exporter": "^5.4|^6.0|^7.0" + "symfony/var-exporter": "^6.4|^7.0" }, - "time": "2024-02-01T13:16:41+00:00", + "time": "2024-09-20T08:28:38+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -2410,7 +2341,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.4.4" + "source": "https://github.com/symfony/string/tree/v7.1.5" }, "funding": [ { @@ -2455,6 +2386,7 @@ "symfony/polyfill-intl-normalizer", "symfony/polyfill-mbstring", "symfony/polyfill-php73", + "symfony/polyfill-php80", "symfony/polyfill-php81", "symfony/service-contracts", "symfony/string" diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index 97484c0..f2f45e8 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -1,9 +1,9 @@ array( 'name' => 'greenmeteor/composer', - 'pretty_version' => '1.0.0+no-version-set', - 'version' => '1.0.0.0', - 'reference' => NULL, + 'pretty_version' => 'dev-develop', + 'version' => 'dev-develop', + 'reference' => '406fce02653afbc603e30dccabb6bd5f09117159', 'type' => 'humhub-module', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -11,36 +11,36 @@ ), 'versions' => array( 'composer/ca-bundle' => array( - 'pretty_version' => '1.5.0', - 'version' => '1.5.0.0', - 'reference' => '0c5ccfcfea312b5c5a190a21ac5cef93f74baf99', + 'pretty_version' => '1.5.2', + 'version' => '1.5.2.0', + 'reference' => '48a792895a2b7a6ee65dd5442c299d7b835b6137', 'type' => 'library', 'install_path' => __DIR__ . '/./ca-bundle', 'aliases' => array(), 'dev_requirement' => true, ), 'composer/class-map-generator' => array( - 'pretty_version' => '1.1.1', - 'version' => '1.1.1.0', - 'reference' => '8286a62d243312ed99b3eee20d5005c961adb311', + 'pretty_version' => '1.4.0', + 'version' => '1.4.0.0', + 'reference' => '98bbf6780e56e0fd2404fe4b82eb665a0f93b783', 'type' => 'library', 'install_path' => __DIR__ . '/./class-map-generator', 'aliases' => array(), 'dev_requirement' => true, ), 'composer/composer' => array( - 'pretty_version' => '2.7.2', - 'version' => '2.7.2.0', - 'reference' => 'b826edb791571ab1eaf281eb1bd6e181a1192adc', + 'pretty_version' => '2.8.1', + 'version' => '2.8.1.0', + 'reference' => 'e52b8672276cf436670cdd6bd5de4353740e83b2', 'type' => 'library', 'install_path' => __DIR__ . '/./composer', 'aliases' => array(), 'dev_requirement' => true, ), 'composer/installers' => array( - 'pretty_version' => 'v1.12.0', - 'version' => '1.12.0.0', - 'reference' => 'd20a64ed3c94748397ff5973488761b22f6d3f19', + 'pretty_version' => 'v2.3.0', + 'version' => '2.3.0.0', + 'reference' => '12fb2dfe5e16183de69e784a7b84046c43d97e8e', 'type' => 'composer-plugin', 'install_path' => __DIR__ . '/./installers', 'aliases' => array(), @@ -56,18 +56,18 @@ 'dev_requirement' => true, ), 'composer/pcre' => array( - 'pretty_version' => '3.1.3', - 'version' => '3.1.3.0', - 'reference' => '5b16e25a5355f1f3afdfc2f954a0a80aec4826a8', + 'pretty_version' => '3.3.1', + 'version' => '3.3.1.0', + 'reference' => '63aaeac21d7e775ff9bc9d45021e1745c97521c4', 'type' => 'library', 'install_path' => __DIR__ . '/./pcre', 'aliases' => array(), 'dev_requirement' => true, ), 'composer/semver' => array( - 'pretty_version' => '3.4.0', - 'version' => '3.4.0.0', - 'reference' => '35e8d0af4486141bc745f23a29cc2091eb624a32', + 'pretty_version' => '3.4.3', + 'version' => '3.4.3.0', + 'reference' => '4313d26ada5e0c4edfbd1dc481a92ff7bff91f12', 'type' => 'library', 'install_path' => __DIR__ . '/./semver', 'aliases' => array(), @@ -83,41 +83,32 @@ 'dev_requirement' => true, ), 'composer/xdebug-handler' => array( - 'pretty_version' => '3.0.4', - 'version' => '3.0.4.0', - 'reference' => '4f988f8fdf580d53bdb2d1278fe93d1ed5462255', + 'pretty_version' => '3.0.5', + 'version' => '3.0.5.0', + 'reference' => '6c1925561632e83d60a44492e0b344cf48ab85ef', 'type' => 'library', 'install_path' => __DIR__ . '/./xdebug-handler', 'aliases' => array(), 'dev_requirement' => true, ), 'greenmeteor/composer' => array( - 'pretty_version' => '1.0.0+no-version-set', - 'version' => '1.0.0.0', - 'reference' => NULL, + 'pretty_version' => 'dev-develop', + 'version' => 'dev-develop', + 'reference' => '406fce02653afbc603e30dccabb6bd5f09117159', 'type' => 'humhub-module', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev_requirement' => false, ), 'justinrainbow/json-schema' => array( - 'pretty_version' => 'v5.2.13', - 'version' => '5.2.13.0', - 'reference' => 'fbbe7e5d79f618997bc3332a6f49246036c45793', + 'pretty_version' => '5.3.0', + 'version' => '5.3.0.0', + 'reference' => 'feb2ca6dd1cebdaf1ed60a4c8de2e53ce11c4fd8', 'type' => 'library', 'install_path' => __DIR__ . '/../justinrainbow/json-schema', 'aliases' => array(), 'dev_requirement' => true, ), - 'oyejorge/less.php' => array( - 'pretty_version' => 'v1.7.0.14', - 'version' => '1.7.0.14', - 'reference' => '42925c5a01a07d67ca7e82dfc8fb31814d557bc9', - 'type' => 'library', - 'install_path' => __DIR__ . '/../oyejorge/less.php', - 'aliases' => array(), - 'dev_requirement' => false, - ), 'psr/container' => array( 'pretty_version' => '2.0.2', 'version' => '2.0.2.0', @@ -128,9 +119,9 @@ 'dev_requirement' => true, ), 'psr/log' => array( - 'pretty_version' => '3.0.0', - 'version' => '3.0.0.0', - 'reference' => 'fe5ea303b0887d5caefd3d431c3e61ad47037001', + 'pretty_version' => '3.0.2', + 'version' => '3.0.2.0', + 'reference' => 'f16e1d5863e37f8d8c2a01719f5b34baa2b714d3', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/log', 'aliases' => array(), @@ -143,24 +134,18 @@ ), ), 'react/promise' => array( - 'pretty_version' => 'v3.1.0', - 'version' => '3.1.0.0', - 'reference' => 'e563d55d1641de1dea9f5e84f3cccc66d2bfe02c', + 'pretty_version' => 'v3.2.0', + 'version' => '3.2.0.0', + 'reference' => '8a164643313c71354582dc850b42b33fa12a4b63', 'type' => 'library', 'install_path' => __DIR__ . '/../react/promise', 'aliases' => array(), 'dev_requirement' => true, ), - 'roundcube/plugin-installer' => array( - 'dev_requirement' => false, - 'replaced' => array( - 0 => '*', - ), - ), 'seld/jsonlint' => array( - 'pretty_version' => '1.10.2', - 'version' => '1.10.2.0', - 'reference' => '9bb7db07b5d66d90f6ebf542f09fc67d800e5259', + 'pretty_version' => '1.11.0', + 'version' => '1.11.0.0', + 'reference' => '1748aaf847fc731cfad7725aec413ee46f0cc3a2', 'type' => 'library', 'install_path' => __DIR__ . '/../seld/jsonlint', 'aliases' => array(), @@ -184,133 +169,127 @@ 'aliases' => array(), 'dev_requirement' => true, ), - 'shama/baton' => array( - 'dev_requirement' => false, - 'replaced' => array( - 0 => '*', - ), - ), 'symfony/console' => array( - 'pretty_version' => 'v6.4.4', - 'version' => '6.4.4.0', - 'reference' => '0d9e4eb5ad413075624378f474c4167ea202de78', + 'pretty_version' => 'v7.1.5', + 'version' => '7.1.5.0', + 'reference' => '0fa539d12b3ccf068a722bbbffa07ca7079af9ee', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/console', 'aliases' => array(), 'dev_requirement' => true, ), 'symfony/deprecation-contracts' => array( - 'pretty_version' => 'v3.4.0', - 'version' => '3.4.0.0', - 'reference' => '7c3aff79d10325257a001fcf92d991f24fc967cf', + 'pretty_version' => 'v3.5.0', + 'version' => '3.5.0.0', + 'reference' => '0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/deprecation-contracts', 'aliases' => array(), 'dev_requirement' => true, ), 'symfony/filesystem' => array( - 'pretty_version' => 'v6.4.3', - 'version' => '6.4.3.0', - 'reference' => '7f3b1755eb49297a0827a7575d5d2b2fd11cc9fb', + 'pretty_version' => 'v7.1.5', + 'version' => '7.1.5.0', + 'reference' => '61fe0566189bf32e8cfee78335d8776f64a66f5a', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/filesystem', 'aliases' => array(), 'dev_requirement' => true, ), 'symfony/finder' => array( - 'pretty_version' => 'v6.4.0', - 'version' => '6.4.0.0', - 'reference' => '11d736e97f116ac375a81f96e662911a34cd50ce', + 'pretty_version' => 'v7.1.4', + 'version' => '7.1.4.0', + 'reference' => 'd95bbf319f7d052082fb7af147e0f835a695e823', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/finder', 'aliases' => array(), 'dev_requirement' => true, ), 'symfony/polyfill-ctype' => array( - 'pretty_version' => 'v1.29.0', - 'version' => '1.29.0.0', - 'reference' => 'ef4d7e442ca910c4764bce785146269b30cb5fc4', + 'pretty_version' => 'v1.31.0', + 'version' => '1.31.0.0', + 'reference' => 'a3cc8b044a6ea513310cbd48ef7333b384945638', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-ctype', 'aliases' => array(), 'dev_requirement' => true, ), 'symfony/polyfill-intl-grapheme' => array( - 'pretty_version' => 'v1.29.0', - 'version' => '1.29.0.0', - 'reference' => '32a9da87d7b3245e09ac426c83d334ae9f06f80f', + 'pretty_version' => 'v1.31.0', + 'version' => '1.31.0.0', + 'reference' => 'b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-intl-grapheme', 'aliases' => array(), 'dev_requirement' => true, ), 'symfony/polyfill-intl-normalizer' => array( - 'pretty_version' => 'v1.29.0', - 'version' => '1.29.0.0', - 'reference' => 'bc45c394692b948b4d383a08d7753968bed9a83d', + 'pretty_version' => 'v1.31.0', + 'version' => '1.31.0.0', + 'reference' => '3833d7255cc303546435cb650316bff708a1c75c', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-intl-normalizer', 'aliases' => array(), 'dev_requirement' => true, ), 'symfony/polyfill-mbstring' => array( - 'pretty_version' => 'v1.29.0', - 'version' => '1.29.0.0', - 'reference' => '9773676c8a1bb1f8d4340a62efe641cf76eda7ec', + 'pretty_version' => 'v1.31.0', + 'version' => '1.31.0.0', + 'reference' => '85181ba99b2345b0ef10ce42ecac37612d9fd341', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-mbstring', 'aliases' => array(), 'dev_requirement' => true, ), 'symfony/polyfill-php73' => array( - 'pretty_version' => 'v1.29.0', - 'version' => '1.29.0.0', - 'reference' => '21bd091060673a1177ae842c0ef8fe30893114d2', + 'pretty_version' => 'v1.31.0', + 'version' => '1.31.0.0', + 'reference' => '0f68c03565dcaaf25a890667542e8bd75fe7e5bb', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-php73', 'aliases' => array(), 'dev_requirement' => true, ), 'symfony/polyfill-php80' => array( - 'pretty_version' => 'v1.29.0', - 'version' => '1.29.0.0', - 'reference' => '87b68208d5c1188808dd7839ee1e6c8ec3b02f1b', + 'pretty_version' => 'v1.31.0', + 'version' => '1.31.0.0', + 'reference' => '60328e362d4c2c802a54fcbf04f9d3fb892b4cf8', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-php80', 'aliases' => array(), - 'dev_requirement' => false, + 'dev_requirement' => true, ), 'symfony/polyfill-php81' => array( - 'pretty_version' => 'v1.29.0', - 'version' => '1.29.0.0', - 'reference' => 'c565ad1e63f30e7477fc40738343c62b40bc672d', + 'pretty_version' => 'v1.31.0', + 'version' => '1.31.0.0', + 'reference' => '4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-php81', 'aliases' => array(), 'dev_requirement' => true, ), 'symfony/process' => array( - 'pretty_version' => 'v5.4.36', - 'version' => '5.4.36.0', - 'reference' => '4fdf34004f149cc20b2f51d7d119aa500caad975', + 'pretty_version' => 'v7.1.5', + 'version' => '7.1.5.0', + 'reference' => '5c03ee6369281177f07f7c68252a280beccba847', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/process', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/service-contracts' => array( - 'pretty_version' => 'v3.4.1', - 'version' => '3.4.1.0', - 'reference' => 'fe07cbc8d837f60caf7018068e350cc5163681a0', + 'pretty_version' => 'v3.5.0', + 'version' => '3.5.0.0', + 'reference' => 'bd1d9e59a81d8fa4acdcea3f617c581f7475a80f', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/service-contracts', 'aliases' => array(), 'dev_requirement' => true, ), 'symfony/string' => array( - 'pretty_version' => 'v6.4.4', - 'version' => '6.4.4.0', - 'reference' => '4e465a95bdc32f49cf4c7f07f751b843bbd6dcd9', + 'pretty_version' => 'v7.1.5', + 'version' => '7.1.5.0', + 'reference' => 'd66f9c343fa894ec2037cc928381df90a7ad4306', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/string', 'aliases' => array(), diff --git a/vendor/composer/installers/.github/workflows/continuous-integration.yml b/vendor/composer/installers/.github/workflows/continuous-integration.yml index 34b8f91..2ecae13 100644 --- a/vendor/composer/installers/.github/workflows/continuous-integration.yml +++ b/vendor/composer/installers/.github/workflows/continuous-integration.yml @@ -8,6 +8,9 @@ env: COMPOSER_FLAGS: "--ansi --no-interaction --no-progress --prefer-dist" SYMFONY_PHPUNIT_REMOVE_RETURN_TYPEHINT: "1" +permissions: + contents: read + jobs: tests: name: "CI" @@ -17,12 +20,6 @@ jobs: strategy: matrix: php-version: - - "5.3" - - "5.4" - - "5.5" - - "5.6" - - "7.0" - - "7.1" - "7.2" - "7.3" - "7.4" @@ -30,7 +27,7 @@ jobs: - "8.1" dependencies: [locked] include: - - php-version: "5.3" + - php-version: "7.2" dependencies: lowest - php-version: "8.1" dependencies: lowest @@ -61,16 +58,8 @@ jobs: if: "contains(matrix.dependencies, 'lowest')" run: "echo \"COMPOSER_FLAGS=$COMPOSER_FLAGS --prefer-lowest\" >> $GITHUB_ENV" - - name: "Upgrade phpunit-bridge if needed for php 8 lowest build" - if: "contains(matrix.php-version, '8.')" - run: | - composer require symfony/phpunit-bridge:^5.3.3 --dev --no-update - - name: "Install latest dependencies" - run: | - # Remove PHPStan as it requires a newer PHP - composer remove phpstan/phpstan phpstan/phpstan-phpunit --dev --no-update - composer update ${{ env.COMPOSER_FLAGS }} + run: "composer update ${{ env.COMPOSER_FLAGS }}" - name: "Run tests" run: "vendor/bin/simple-phpunit --verbose" diff --git a/vendor/composer/installers/.github/workflows/lint.yml b/vendor/composer/installers/.github/workflows/lint.yml index 81a1ac4..61b5633 100644 --- a/vendor/composer/installers/.github/workflows/lint.yml +++ b/vendor/composer/installers/.github/workflows/lint.yml @@ -4,6 +4,9 @@ on: - push - pull_request +permissions: + contents: read + jobs: tests: name: "Lint" @@ -13,8 +16,8 @@ jobs: strategy: matrix: php-version: - - "5.3" - - "8.0" + - "7.2" + - "latest" steps: - name: "Checkout" diff --git a/vendor/composer/installers/.github/workflows/phpstan.yml b/vendor/composer/installers/.github/workflows/phpstan.yml index ac4c4a9..c638b44 100644 --- a/vendor/composer/installers/.github/workflows/phpstan.yml +++ b/vendor/composer/installers/.github/workflows/phpstan.yml @@ -8,6 +8,9 @@ env: COMPOSER_FLAGS: "--ansi --no-interaction --no-progress --prefer-dist" SYMFONY_PHPUNIT_VERSION: "" +permissions: + contents: read + jobs: tests: name: "PHPStan" @@ -17,8 +20,7 @@ jobs: strategy: matrix: php-version: - # pinned to 7.4 because we need PHPUnit 7.5 which does not support PHP 8 - - "7.4" + - "8.0" steps: - name: "Checkout" @@ -45,7 +47,6 @@ jobs: run: "composer update ${{ env.COMPOSER_FLAGS }}" - name: Run PHPStan - # Locked to phpunit 7.5 here as newer ones have void return types which break inheritance run: | - composer require --dev phpunit/phpunit:^7.5.20 --with-all-dependencies ${{ env.COMPOSER_FLAGS }} + composer require --dev phpunit/phpunit:^8.5.18 --with-all-dependencies ${{ env.COMPOSER_FLAGS }} vendor/bin/phpstan analyse diff --git a/vendor/composer/installers/composer.json b/vendor/composer/installers/composer.json index 4a7fd3c..9103484 100644 --- a/vendor/composer/installers/composer.json +++ b/vendor/composer/installers/composer.json @@ -5,7 +5,6 @@ "description": "A multi-framework Composer library installer", "keywords": [ "installer", - "Aimeos", "AGL", "AnnotateCms", "Attogram", @@ -15,7 +14,7 @@ "Cockpit", "CodeIgniter", "concrete5", - "Craft", + "ConcreteCMS", "Croogo", "DokuWiki", "Dolibarr", @@ -29,7 +28,6 @@ "Hurad", "ImageCMS", "iTop", - "Joomla", "Kanboard", "Known", "Kohana", @@ -41,6 +39,7 @@ "majima", "Mako", "MantisBT", + "Matomo", "Mautic", "Maya", "MODX", @@ -69,10 +68,8 @@ "Starbug", "SyDES", "Sylius", - "symfony", "TastyIgniter", "Thelia", - "TYPO3", "WHMCS", "WolfCMS", "WordPress", @@ -97,26 +94,24 @@ "extra": { "class": "Composer\\Installers\\Plugin", "branch-alias": { - "dev-main": "1.x-dev" - } - }, - "replace": { - "shama/baton": "*", - "roundcube/plugin-installer": "*" + "dev-main": "2.x-dev" + }, + "plugin-modifies-install-path": true }, "require": { + "php": "^7.2 || ^8.0", "composer-plugin-api": "^1.0 || ^2.0" }, "require-dev": { - "composer/composer": "1.6.* || ^2.0", - "composer/semver": "^1 || ^3", - "symfony/phpunit-bridge": "^4.2 || ^5", - "phpstan/phpstan": "^0.12.55", - "symfony/process": "^2.3", - "phpstan/phpstan-phpunit": "^0.12.16" + "composer/composer": "^1.10.27 || ^2.7", + "composer/semver": "^1.7.2 || ^3.4.0", + "symfony/phpunit-bridge": "^7.1.1", + "phpstan/phpstan": "^1.11", + "symfony/process": "^5 || ^6 || ^7", + "phpstan/phpstan-phpunit": "^1" }, "scripts": { - "test": "SYMFONY_PHPUNIT_REMOVE_RETURN_TYPEHINT=1 vendor/bin/simple-phpunit", - "phpstan": "vendor/bin/phpstan analyse" + "test": "@php vendor/bin/simple-phpunit", + "phpstan": "@php vendor/bin/phpstan analyse" } } diff --git a/vendor/composer/installers/phpstan.neon.dist b/vendor/composer/installers/phpstan.neon.dist deleted file mode 100644 index 8e3d81e..0000000 --- a/vendor/composer/installers/phpstan.neon.dist +++ /dev/null @@ -1,10 +0,0 @@ -parameters: - level: 5 - paths: - - src - - tests - excludes_analyse: - - tests/Composer/Installers/Test/PolyfillTestCase.php - -includes: - - vendor/phpstan/phpstan-phpunit/extension.neon diff --git a/vendor/composer/installers/src/Composer/Installers/AglInstaller.php b/vendor/composer/installers/src/Composer/Installers/AglInstaller.php index 01b8a41..b0996a6 100644 --- a/vendor/composer/installers/src/Composer/Installers/AglInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/AglInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'module' => 'More/{$name}/', ); @@ -10,12 +12,18 @@ class AglInstaller extends BaseInstaller /** * Format package name to CamelCase */ - public function inflectPackageVars($vars) + public function inflectPackageVars(array $vars): array { - $vars['name'] = preg_replace_callback('/(?:^|_|-)(.?)/', function ($matches) { + $name = preg_replace_callback('/(?:^|_|-)(.?)/', function ($matches) { return strtoupper($matches[1]); }, $vars['name']); + if (null === $name) { + throw new \RuntimeException('Failed to run preg_replace_callback: '.preg_last_error()); + } + + $vars['name'] = $name; + return $vars; } } diff --git a/vendor/composer/installers/src/Composer/Installers/AimeosInstaller.php b/vendor/composer/installers/src/Composer/Installers/AimeosInstaller.php deleted file mode 100644 index 79a0e95..0000000 --- a/vendor/composer/installers/src/Composer/Installers/AimeosInstaller.php +++ /dev/null @@ -1,9 +0,0 @@ - 'ext/{$name}/', - ); -} diff --git a/vendor/composer/installers/src/Composer/Installers/AkauntingInstaller.php b/vendor/composer/installers/src/Composer/Installers/AkauntingInstaller.php new file mode 100644 index 0000000..c504c70 --- /dev/null +++ b/vendor/composer/installers/src/Composer/Installers/AkauntingInstaller.php @@ -0,0 +1,23 @@ + */ + protected $locations = array( + 'module' => 'modules/{$name}', + ); + + /** + * Format package name to CamelCase + */ + public function inflectPackageVars(array $vars): array + { + $vars['name'] = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } +} diff --git a/vendor/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php b/vendor/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php index 89d7ad9..58a0f66 100644 --- a/vendor/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'module' => 'addons/modules/{$name}/', 'component' => 'addons/components/{$name}/', diff --git a/vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php b/vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php index 22dad1b..f01b399 100644 --- a/vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'module' => 'Modules/{$name}/', 'theme' => 'Themes/{$name}/' @@ -14,9 +16,8 @@ class AsgardInstaller extends BaseInstaller * For package type asgard-module, cut off a trailing '-plugin' if present. * * For package type asgard-theme, cut off a trailing '-theme' if present. - * */ - public function inflectPackageVars($vars) + public function inflectPackageVars(array $vars): array { if ($vars['type'] === 'asgard-module') { return $this->inflectPluginVars($vars); @@ -29,18 +30,26 @@ public function inflectPackageVars($vars) return $vars; } - protected function inflectPluginVars($vars) + /** + * @param array $vars + * @return array + */ + protected function inflectPluginVars(array $vars): array { - $vars['name'] = preg_replace('/-module$/', '', $vars['name']); + $vars['name'] = $this->pregReplace('/-module$/', '', $vars['name']); $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); return $vars; } - protected function inflectThemeVars($vars) + /** + * @param array $vars + * @return array + */ + protected function inflectThemeVars(array $vars): array { - $vars['name'] = preg_replace('/-theme$/', '', $vars['name']); + $vars['name'] = $this->pregReplace('/-theme$/', '', $vars['name']); $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); diff --git a/vendor/composer/installers/src/Composer/Installers/AttogramInstaller.php b/vendor/composer/installers/src/Composer/Installers/AttogramInstaller.php index d62fd8f..bd7dd8d 100644 --- a/vendor/composer/installers/src/Composer/Installers/AttogramInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/AttogramInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'module' => 'modules/{$name}/', ); diff --git a/vendor/composer/installers/src/Composer/Installers/BaseInstaller.php b/vendor/composer/installers/src/Composer/Installers/BaseInstaller.php index 70dde90..663ec2a 100644 --- a/vendor/composer/installers/src/Composer/Installers/BaseInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/BaseInstaller.php @@ -1,4 +1,5 @@ */ protected $locations = array(); + /** @var Composer */ protected $composer; + /** @var PackageInterface */ protected $package; + /** @var IOInterface */ protected $io; /** * Initializes base installer. - * - * @param PackageInterface $package - * @param Composer $composer - * @param IOInterface $io */ - public function __construct(PackageInterface $package = null, Composer $composer = null, IOInterface $io = null) + public function __construct(PackageInterface $package, Composer $composer, IOInterface $io) { $this->composer = $composer; $this->package = $package; @@ -28,12 +29,8 @@ public function __construct(PackageInterface $package = null, Composer $composer /** * Return the install path based on package type. - * - * @param PackageInterface $package - * @param string $frameworkType - * @return string */ - public function getInstallPath(PackageInterface $package, $frameworkType = '') + public function getInstallPath(PackageInterface $package, string $frameworkType = ''): string { $type = $this->package->getType(); @@ -52,18 +49,16 @@ public function getInstallPath(PackageInterface $package, $frameworkType = '') $availableVars['name'] = $extra['installer-name']; } - if ($this->composer->getPackage()) { - $extra = $this->composer->getPackage()->getExtra(); - if (!empty($extra['installer-paths'])) { - $customPath = $this->mapCustomInstallPaths($extra['installer-paths'], $prettyName, $type, $vendor); - if ($customPath !== false) { - return $this->templatePath($customPath, $availableVars); - } + $extra = $this->composer->getPackage()->getExtra(); + if (!empty($extra['installer-paths'])) { + $customPath = $this->mapCustomInstallPaths($extra['installer-paths'], $prettyName, $type, $vendor); + if ($customPath !== false) { + return $this->templatePath($customPath, $availableVars); } } $packageType = substr($type, strlen($frameworkType) + 1); - $locations = $this->getLocations(); + $locations = $this->getLocations($frameworkType); if (!isset($locations[$packageType])) { throw new \InvalidArgumentException(sprintf('Package type "%s" is not supported', $type)); } @@ -77,7 +72,7 @@ public function getInstallPath(PackageInterface $package, $frameworkType = '') * @param array $vars This will normally receive array{name: string, vendor: string, type: string} * @return array */ - public function inflectPackageVars($vars) + public function inflectPackageVars(array $vars): array { return $vars; } @@ -87,7 +82,7 @@ public function inflectPackageVars($vars) * * @return array map of package types => install path */ - public function getLocations() + public function getLocations(string $frameworkType) { return $this->locations; } @@ -95,11 +90,9 @@ public function getLocations() /** * Replace vars in a path * - * @param string $path * @param array $vars - * @return string */ - protected function templatePath($path, array $vars = array()) + protected function templatePath(string $path, array $vars = array()): string { if (strpos($path, '{') !== false) { extract($vars); @@ -117,13 +110,10 @@ protected function templatePath($path, array $vars = array()) /** * Search through a passed paths array for a custom install path. * - * @param array $paths - * @param string $name - * @param string $type - * @param string $vendor = NULL + * @param array $paths * @return string|false */ - protected function mapCustomInstallPaths(array $paths, $name, $type, $vendor = NULL) + protected function mapCustomInstallPaths(array $paths, string $name, string $type, ?string $vendor = null) { foreach ($paths as $path => $names) { $names = (array) $names; @@ -134,4 +124,14 @@ protected function mapCustomInstallPaths(array $paths, $name, $type, $vendor = N return false; } + + protected function pregReplace(string $pattern, string $replacement, string $subject): string + { + $result = preg_replace($pattern, $replacement, $subject); + if (null === $result) { + throw new \RuntimeException('Failed to run preg_replace with '.$pattern.': '.preg_last_error()); + } + + return $result; + } } diff --git a/vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php b/vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php index e80cd1e..705ecb4 100644 --- a/vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php @@ -9,9 +9,9 @@ * - `bitrix-d7-module` — copy the module to directory `bitrix/modules/.`. * - `bitrix-d7-component` — copy the component to directory `bitrix/components//`. * - `bitrix-d7-template` — copy the template to directory `bitrix/templates/_`. - * + * * You can set custom path to directory with Bitrix kernel in `composer.json`: - * + * * ```json * { * "extra": { @@ -25,6 +25,7 @@ */ class BitrixInstaller extends BaseInstaller { + /** @var array */ protected $locations = array( 'module' => '{$bitrix_dir}/modules/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken) 'component' => '{$bitrix_dir}/components/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken) @@ -35,15 +36,13 @@ class BitrixInstaller extends BaseInstaller ); /** - * @var array Storage for informations about duplicates at all the time of installation packages. + * @var string[] Storage for informations about duplicates at all the time of installation packages. */ private static $checkedDuplicates = array(); - /** - * {@inheritdoc} - */ - public function inflectPackageVars($vars) + public function inflectPackageVars(array $vars): array { + /** @phpstan-ignore-next-line */ if ($this->composer->getPackage()) { $extra = $this->composer->getPackage()->getExtra(); @@ -62,7 +61,7 @@ public function inflectPackageVars($vars) /** * {@inheritdoc} */ - protected function templatePath($path, array $vars = array()) + protected function templatePath(string $path, array $vars = array()): string { $templatePath = parent::templatePath($path, $vars); $this->checkDuplicates($templatePath, $vars); @@ -73,10 +72,9 @@ protected function templatePath($path, array $vars = array()) /** * Duplicates search packages. * - * @param string $path - * @param array $vars + * @param array $vars */ - protected function checkDuplicates($path, array $vars = array()) + protected function checkDuplicates(string $path, array $vars = array()): void { $packageType = substr($vars['type'], strlen('bitrix') + 1); $localDir = explode('/', $vars['bitrix_dir']); @@ -94,8 +92,7 @@ protected function checkDuplicates($path, array $vars = array()) return; } - if ($oldPath !== $path && file_exists($oldPath) && $this->io && $this->io->isInteractive()) { - + if ($oldPath !== $path && file_exists($oldPath) && $this->io->isInteractive()) { $this->io->writeError(' Duplication of packages:'); $this->io->writeError(' Package ' . $oldPath . ' will be called instead package ' . $path . ''); diff --git a/vendor/composer/installers/src/Composer/Installers/BonefishInstaller.php b/vendor/composer/installers/src/Composer/Installers/BonefishInstaller.php index da3aad2..ab022d9 100644 --- a/vendor/composer/installers/src/Composer/Installers/BonefishInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/BonefishInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'package' => 'Packages/{$vendor}/{$name}/' ); diff --git a/vendor/composer/installers/src/Composer/Installers/BotbleInstaller.php b/vendor/composer/installers/src/Composer/Installers/BotbleInstaller.php new file mode 100644 index 0000000..35e1cb8 --- /dev/null +++ b/vendor/composer/installers/src/Composer/Installers/BotbleInstaller.php @@ -0,0 +1,12 @@ + */ + protected $locations = array( + 'plugin' => 'platform/plugins/{$name}/', + 'theme' => 'platform/themes/{$name}/', + ); +} diff --git a/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php b/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php index 1e2ddd0..12b4ed4 100644 --- a/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php @@ -1,4 +1,5 @@ */ protected $locations = array( 'plugin' => 'Plugin/{$name}/', ); @@ -13,7 +15,7 @@ class CakePHPInstaller extends BaseInstaller /** * Format package name to CamelCase */ - public function inflectPackageVars($vars) + public function inflectPackageVars(array $vars): array { if ($this->matchesCakeVersion('>=', '3.0.0')) { return $vars; @@ -21,7 +23,7 @@ public function inflectPackageVars($vars) $nameParts = explode('/', $vars['name']); foreach ($nameParts as &$value) { - $value = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $value)); + $value = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $value)); $value = str_replace(array('-', '_'), ' ', $value); $value = str_replace(' ', '', ucwords($value)); } @@ -33,7 +35,7 @@ public function inflectPackageVars($vars) /** * Change the default plugin location when cakephp >= 3.0 */ - public function getLocations() + public function getLocations(string $frameworkType): array { if ($this->matchesCakeVersion('>=', '3.0.0')) { $this->locations['plugin'] = $this->composer->getConfig()->get('vendor-dir') . '/{$vendor}/{$name}/'; @@ -44,19 +46,18 @@ public function getLocations() /** * Check if CakePHP version matches against a version * - * @param string $matcher - * @param string $version - * @return bool - * @phpstan-param Constraint::STR_OP_* $matcher + * @phpstan-param '='|'=='|'<'|'<='|'>'|'>='|'<>'|'!=' $matcher */ - protected function matchesCakeVersion($matcher, $version) + protected function matchesCakeVersion(string $matcher, string $version): bool { $repositoryManager = $this->composer->getRepositoryManager(); - if (! $repositoryManager) { + /** @phpstan-ignore-next-line */ + if (!$repositoryManager) { return false; } $repos = $repositoryManager->getLocalRepository(); + /** @phpstan-ignore-next-line */ if (!$repos) { return false; } diff --git a/vendor/composer/installers/src/Composer/Installers/ChefInstaller.php b/vendor/composer/installers/src/Composer/Installers/ChefInstaller.php index ab2f9aa..b0d3c5f 100644 --- a/vendor/composer/installers/src/Composer/Installers/ChefInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/ChefInstaller.php @@ -1,11 +1,12 @@ */ protected $locations = array( 'cookbook' => 'Chef/{$vendor}/{$name}/', 'role' => 'Chef/roles/{$name}/', ); } - diff --git a/vendor/composer/installers/src/Composer/Installers/CiviCrmInstaller.php b/vendor/composer/installers/src/Composer/Installers/CiviCrmInstaller.php index 6673aea..1c52e0c 100644 --- a/vendor/composer/installers/src/Composer/Installers/CiviCrmInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/CiviCrmInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'ext' => 'ext/{$name}/' ); diff --git a/vendor/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php b/vendor/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php index c887815..2c943b2 100644 --- a/vendor/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php @@ -1,10 +1,12 @@ 'CCF/orbit/{$name}/', - 'theme' => 'CCF/app/themes/{$name}/', - ); -} \ No newline at end of file + /** @var array */ + protected $locations = array( + 'ship' => 'CCF/orbit/{$name}/', + 'theme' => 'CCF/app/themes/{$name}/', + ); +} diff --git a/vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php b/vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php index 053f3ff..d3fcdf7 100644 --- a/vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'module' => 'cockpit/modules/addons/{$name}/', ); @@ -11,10 +13,8 @@ class CockpitInstaller extends BaseInstaller * Format module name. * * Strip `module-` prefix from package name. - * - * {@inheritDoc} */ - public function inflectPackageVars($vars) + public function inflectPackageVars(array $vars): array { if ($vars['type'] == 'cockpit-module') { return $this->inflectModuleVars($vars); @@ -23,9 +23,13 @@ public function inflectPackageVars($vars) return $vars; } - public function inflectModuleVars($vars) + /** + * @param array $vars + * @return array + */ + public function inflectModuleVars(array $vars): array { - $vars['name'] = ucfirst(preg_replace('/cockpit-/i', '', $vars['name'])); + $vars['name'] = ucfirst($this->pregReplace('/cockpit-/i', '', $vars['name'])); return $vars; } diff --git a/vendor/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php b/vendor/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php index 3b4a4ec..a183e07 100644 --- a/vendor/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'library' => 'application/libraries/{$name}/', 'third-party' => 'application/third_party/{$name}/', diff --git a/vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php b/vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php index 5c01baf..2f5fecb 100644 --- a/vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php +++ b/vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'core' => 'concrete/', 'block' => 'application/blocks/{$name}/', diff --git a/vendor/composer/installers/src/Composer/Installers/ConcreteCMSInstaller.php b/vendor/composer/installers/src/Composer/Installers/ConcreteCMSInstaller.php new file mode 100644 index 0000000..b6e7f00 --- /dev/null +++ b/vendor/composer/installers/src/Composer/Installers/ConcreteCMSInstaller.php @@ -0,0 +1,15 @@ + */ + protected $locations = array( + 'core' => 'concrete/', + 'block' => 'application/blocks/{$name}/', + 'package' => 'packages/{$name}/', + 'theme' => 'application/themes/{$name}/', + 'update' => 'updates/{$name}/', + ); +} diff --git a/vendor/composer/installers/src/Composer/Installers/CraftInstaller.php b/vendor/composer/installers/src/Composer/Installers/CraftInstaller.php deleted file mode 100644 index d37a77a..0000000 --- a/vendor/composer/installers/src/Composer/Installers/CraftInstaller.php +++ /dev/null @@ -1,35 +0,0 @@ - 'craft/plugins/{$name}/', - ); - - /** - * Strip `craft-` prefix and/or `-plugin` suffix from package names - * - * @param array $vars - * - * @return array - */ - final public function inflectPackageVars($vars) - { - return $this->inflectPluginVars($vars); - } - - private function inflectPluginVars($vars) - { - $vars['name'] = preg_replace('/-' . self::NAME_SUFFIX . '$/i', '', $vars['name']); - $vars['name'] = preg_replace('/^' . self::NAME_PREFIX . '-/i', '', $vars['name']); - - return $vars; - } -} diff --git a/vendor/composer/installers/src/Composer/Installers/CroogoInstaller.php b/vendor/composer/installers/src/Composer/Installers/CroogoInstaller.php index d94219d..31d4939 100644 --- a/vendor/composer/installers/src/Composer/Installers/CroogoInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/CroogoInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'plugin' => 'Plugin/{$name}/', 'theme' => 'View/Themed/{$name}/', @@ -11,7 +13,7 @@ class CroogoInstaller extends BaseInstaller /** * Format package name to CamelCase */ - public function inflectPackageVars($vars) + public function inflectPackageVars(array $vars): array { $vars['name'] = strtolower(str_replace(array('-', '_'), ' ', $vars['name'])); $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); diff --git a/vendor/composer/installers/src/Composer/Installers/DecibelInstaller.php b/vendor/composer/installers/src/Composer/Installers/DecibelInstaller.php index f4837a6..88f53f7 100644 --- a/vendor/composer/installers/src/Composer/Installers/DecibelInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/DecibelInstaller.php @@ -1,9 +1,11 @@ */ protected $locations = array( 'app' => 'app/{$name}/', ); diff --git a/vendor/composer/installers/src/Composer/Installers/DframeInstaller.php b/vendor/composer/installers/src/Composer/Installers/DframeInstaller.php index 7078816..196f60e 100644 --- a/vendor/composer/installers/src/Composer/Installers/DframeInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/DframeInstaller.php @@ -4,6 +4,7 @@ class DframeInstaller extends BaseInstaller { + /** @var array */ protected $locations = array( 'module' => 'modules/{$vendor}/{$name}/', ); diff --git a/vendor/composer/installers/src/Composer/Installers/DokuWikiInstaller.php b/vendor/composer/installers/src/Composer/Installers/DokuWikiInstaller.php index cfd638d..aa3a2e6 100644 --- a/vendor/composer/installers/src/Composer/Installers/DokuWikiInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/DokuWikiInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'plugin' => 'lib/plugins/{$name}/', 'template' => 'lib/tpl/{$name}/', @@ -11,15 +13,13 @@ class DokuWikiInstaller extends BaseInstaller /** * Format package name. * - * For package type dokuwiki-plugin, cut off a trailing '-plugin', + * For package type dokuwiki-plugin, cut off a trailing '-plugin', * or leading dokuwiki_ if present. - * - * For package type dokuwiki-template, cut off a trailing '-template' if present. * + * For package type dokuwiki-template, cut off a trailing '-template' if present. */ - public function inflectPackageVars($vars) + public function inflectPackageVars(array $vars): array { - if ($vars['type'] === 'dokuwiki-plugin') { return $this->inflectPluginVars($vars); } @@ -31,20 +31,27 @@ public function inflectPackageVars($vars) return $vars; } - protected function inflectPluginVars($vars) + /** + * @param array $vars + * @return array + */ + protected function inflectPluginVars(array $vars): array { - $vars['name'] = preg_replace('/-plugin$/', '', $vars['name']); - $vars['name'] = preg_replace('/^dokuwiki_?-?/', '', $vars['name']); + $vars['name'] = $this->pregReplace('/-plugin$/', '', $vars['name']); + $vars['name'] = $this->pregReplace('/^dokuwiki_?-?/', '', $vars['name']); return $vars; } - protected function inflectTemplateVars($vars) + /** + * @param array $vars + * @return array + */ + protected function inflectTemplateVars(array $vars): array { - $vars['name'] = preg_replace('/-template$/', '', $vars['name']); - $vars['name'] = preg_replace('/^dokuwiki_?-?/', '', $vars['name']); + $vars['name'] = $this->pregReplace('/-template$/', '', $vars['name']); + $vars['name'] = $this->pregReplace('/^dokuwiki_?-?/', '', $vars['name']); return $vars; } - } diff --git a/vendor/composer/installers/src/Composer/Installers/DolibarrInstaller.php b/vendor/composer/installers/src/Composer/Installers/DolibarrInstaller.php index 21f7e8e..c583619 100644 --- a/vendor/composer/installers/src/Composer/Installers/DolibarrInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/DolibarrInstaller.php @@ -1,4 +1,5 @@ */ protected $locations = array( 'module' => 'htdocs/custom/{$name}/', ); diff --git a/vendor/composer/installers/src/Composer/Installers/DrupalInstaller.php b/vendor/composer/installers/src/Composer/Installers/DrupalInstaller.php index 7328239..65a3a91 100644 --- a/vendor/composer/installers/src/Composer/Installers/DrupalInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/DrupalInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'core' => 'core/', 'module' => 'modules/{$name}/', @@ -18,5 +20,6 @@ class DrupalInstaller extends BaseInstaller 'console' => 'console/{$name}/', 'console-language' => 'console/language/{$name}/', 'config' => 'config/sync/', + 'recipe' => 'recipes/{$name}', ); } diff --git a/vendor/composer/installers/src/Composer/Installers/ElggInstaller.php b/vendor/composer/installers/src/Composer/Installers/ElggInstaller.php index c0bb609..48ef2ec 100644 --- a/vendor/composer/installers/src/Composer/Installers/ElggInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/ElggInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'plugin' => 'mod/{$name}/', ); diff --git a/vendor/composer/installers/src/Composer/Installers/EliasisInstaller.php b/vendor/composer/installers/src/Composer/Installers/EliasisInstaller.php index 6f3dc97..d7dd9a9 100644 --- a/vendor/composer/installers/src/Composer/Installers/EliasisInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/EliasisInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'component' => 'components/{$name}/', 'module' => 'modules/{$name}/', diff --git a/vendor/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php b/vendor/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php index d5321a8..fe1d468 100644 --- a/vendor/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php @@ -1,29 +1,31 @@ */ private $ee2Locations = array( 'addon' => 'system/expressionengine/third_party/{$name}/', 'theme' => 'themes/third_party/{$name}/', ); + /** @var array */ private $ee3Locations = array( 'addon' => 'system/user/addons/{$name}/', 'theme' => 'themes/user/{$name}/', ); - public function getInstallPath(PackageInterface $package, $frameworkType = '') + public function getLocations(string $frameworkType): array { + if ($frameworkType === 'ee2') { + $this->locations = $this->ee2Locations; + } else { + $this->locations = $this->ee3Locations; + } - $version = "{$frameworkType}Locations"; - $this->locations = $this->$version; - - return parent::getInstallPath($package, $frameworkType); + return $this->locations; } } diff --git a/vendor/composer/installers/src/Composer/Installers/EzPlatformInstaller.php b/vendor/composer/installers/src/Composer/Installers/EzPlatformInstaller.php index f30ebcc..1f5b84e 100644 --- a/vendor/composer/installers/src/Composer/Installers/EzPlatformInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/EzPlatformInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'meta-assets' => 'web/assets/ezplatform/', 'assets' => 'web/assets/ezplatform/{$name}/', diff --git a/vendor/composer/installers/src/Composer/Installers/ForkCMSInstaller.php b/vendor/composer/installers/src/Composer/Installers/ForkCMSInstaller.php new file mode 100644 index 0000000..cf62926 --- /dev/null +++ b/vendor/composer/installers/src/Composer/Installers/ForkCMSInstaller.php @@ -0,0 +1,58 @@ + */ + protected $locations = [ + 'module' => 'src/Modules/{$name}/', + 'theme' => 'src/Themes/{$name}/' + ]; + + /** + * Format package name. + * + * For package type fork-cms-module, cut off a trailing '-plugin' if present. + * + * For package type fork-cms-theme, cut off a trailing '-theme' if present. + */ + public function inflectPackageVars(array $vars): array + { + if ($vars['type'] === 'fork-cms-module') { + return $this->inflectModuleVars($vars); + } + + if ($vars['type'] === 'fork-cms-theme') { + return $this->inflectThemeVars($vars); + } + + return $vars; + } + + /** + * @param array $vars + * @return array + */ + protected function inflectModuleVars(array $vars): array + { + $vars['name'] = $this->pregReplace('/^fork-cms-|-module|ForkCMS|ForkCms|Forkcms|forkcms|Module$/', '', $vars['name']); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); // replace hyphens with spaces + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); // make module name camelcased + + return $vars; + } + + /** + * @param array $vars + * @return array + */ + protected function inflectThemeVars(array $vars): array + { + $vars['name'] = $this->pregReplace('/^fork-cms-|-theme|ForkCMS|ForkCms|Forkcms|forkcms|Theme$/', '', $vars['name']); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); // replace hyphens with spaces + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); // make theme name camelcased + + return $vars; + } +} diff --git a/vendor/composer/installers/src/Composer/Installers/FuelInstaller.php b/vendor/composer/installers/src/Composer/Installers/FuelInstaller.php index 6eba2e3..5948572 100644 --- a/vendor/composer/installers/src/Composer/Installers/FuelInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/FuelInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'module' => 'fuel/app/modules/{$name}/', 'package' => 'fuel/packages/{$name}/', diff --git a/vendor/composer/installers/src/Composer/Installers/FuelphpInstaller.php b/vendor/composer/installers/src/Composer/Installers/FuelphpInstaller.php index 29d980b..b4d80ed 100644 --- a/vendor/composer/installers/src/Composer/Installers/FuelphpInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/FuelphpInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'component' => 'components/{$name}/', ); diff --git a/vendor/composer/installers/src/Composer/Installers/GravInstaller.php b/vendor/composer/installers/src/Composer/Installers/GravInstaller.php index dbe63e0..f5792e3 100644 --- a/vendor/composer/installers/src/Composer/Installers/GravInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/GravInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'plugin' => 'user/plugins/{$name}/', 'theme' => 'user/themes/{$name}/', @@ -10,17 +12,14 @@ class GravInstaller extends BaseInstaller /** * Format package name - * - * @param array $vars - * - * @return array */ - public function inflectPackageVars($vars) + public function inflectPackageVars(array $vars): array { $restrictedWords = implode('|', array_keys($this->locations)); $vars['name'] = strtolower($vars['name']); - $vars['name'] = preg_replace('/^(?:grav-)?(?:(?:'.$restrictedWords.')-)?(.*?)(?:-(?:'.$restrictedWords.'))?$/ui', + $vars['name'] = $this->pregReplace( + '/^(?:grav-)?(?:(?:'.$restrictedWords.')-)?(.*?)(?:-(?:'.$restrictedWords.'))?$/ui', '$1', $vars['name'] ); diff --git a/vendor/composer/installers/src/Composer/Installers/HuradInstaller.php b/vendor/composer/installers/src/Composer/Installers/HuradInstaller.php index 8fe017f..dd76c5b 100644 --- a/vendor/composer/installers/src/Composer/Installers/HuradInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/HuradInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'plugin' => 'plugins/{$name}/', 'theme' => 'plugins/{$name}/', @@ -11,11 +13,11 @@ class HuradInstaller extends BaseInstaller /** * Format package name to CamelCase */ - public function inflectPackageVars($vars) + public function inflectPackageVars(array $vars): array { $nameParts = explode('/', $vars['name']); foreach ($nameParts as &$value) { - $value = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $value)); + $value = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $value)); $value = str_replace(array('-', '_'), ' ', $value); $value = str_replace(' ', '', ucwords($value)); } diff --git a/vendor/composer/installers/src/Composer/Installers/ImageCMSInstaller.php b/vendor/composer/installers/src/Composer/Installers/ImageCMSInstaller.php index 5e2142e..4157cec 100644 --- a/vendor/composer/installers/src/Composer/Installers/ImageCMSInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/ImageCMSInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'template' => 'templates/{$name}/', 'module' => 'application/modules/{$name}/', diff --git a/vendor/composer/installers/src/Composer/Installers/Installer.php b/vendor/composer/installers/src/Composer/Installers/Installer.php index 9c9c24f..862d8ae 100644 --- a/vendor/composer/installers/src/Composer/Installers/Installer.php +++ b/vendor/composer/installers/src/Composer/Installers/Installer.php @@ -6,6 +6,7 @@ use Composer\Installer\BinaryInstaller; use Composer\Installer\LibraryInstaller; use Composer\IO\IOInterface; +use Composer\Package\Package; use Composer\Package\PackageInterface; use Composer\Repository\InstalledRepositoryInterface; use Composer\Util\Filesystem; @@ -13,19 +14,19 @@ class Installer extends LibraryInstaller { - /** * Package types to installer class map * - * @var array + * @var array */ private $supportedTypes = array( - 'aimeos' => 'AimeosInstaller', + 'akaunting' => 'AkauntingInstaller', 'asgard' => 'AsgardInstaller', 'attogram' => 'AttogramInstaller', 'agl' => 'AglInstaller', 'annotatecms' => 'AnnotateCmsInstaller', 'bitrix' => 'BitrixInstaller', + 'botble' => 'BotbleInstaller', 'bonefish' => 'BonefishInstaller', 'cakephp' => 'CakePHPInstaller', 'chef' => 'ChefInstaller', @@ -34,7 +35,7 @@ class Installer extends LibraryInstaller 'cockpit' => 'CockpitInstaller', 'codeigniter' => 'CodeIgniterInstaller', 'concrete5' => 'Concrete5Installer', - 'craft' => 'CraftInstaller', + 'concretecms' => 'ConcreteCMSInstaller', 'croogo' => 'CroogoInstaller', 'dframe' => 'DframeInstaller', 'dokuwiki' => 'DokuWikiInstaller', @@ -46,6 +47,7 @@ class Installer extends LibraryInstaller 'ee3' => 'ExpressionEngineInstaller', 'ee2' => 'ExpressionEngineInstaller', 'ezplatform' => 'EzPlatformInstaller', + 'fork' => 'ForkCMSInstaller', 'fuel' => 'FuelInstaller', 'fuelphp' => 'FuelphpInstaller', 'grav' => 'GravInstaller', @@ -53,13 +55,11 @@ class Installer extends LibraryInstaller 'tastyigniter' => 'TastyIgniterInstaller', 'imagecms' => 'ImageCMSInstaller', 'itop' => 'ItopInstaller', - 'joomla' => 'JoomlaInstaller', 'kanboard' => 'KanboardInstaller', - 'kirby' => 'KirbyInstaller', 'known' => 'KnownInstaller', 'kodicms' => 'KodiCMSInstaller', 'kohana' => 'KohanaInstaller', - 'lms' => 'LanManagementSystemInstaller', + 'lms' => 'LanManagementSystemInstaller', 'laravel' => 'LaravelInstaller', 'lavalite' => 'LavaLiteInstaller', 'lithium' => 'LithiumInstaller', @@ -67,6 +67,7 @@ class Installer extends LibraryInstaller 'majima' => 'MajimaInstaller', 'mantisbt' => 'MantisBTInstaller', 'mako' => 'MakoInstaller', + 'matomo' => 'MatomoInstaller', 'maya' => 'MayaInstaller', 'mautic' => 'MauticInstaller', 'mediawiki' => 'MediaWikiInstaller', @@ -82,7 +83,6 @@ class Installer extends LibraryInstaller 'osclass' => 'OsclassInstaller', 'pxcms' => 'PxcmsInstaller', 'phpbb' => 'PhpBBInstaller', - 'pimcore' => 'PimcoreInstaller', 'piwik' => 'PiwikInstaller', 'plentymarkets'=> 'PlentymarketsInstaller', 'ppi' => 'PPIInstaller', @@ -103,12 +103,9 @@ class Installer extends LibraryInstaller 'starbug' => 'StarbugInstaller', 'sydes' => 'SyDESInstaller', 'sylius' => 'SyliusInstaller', - 'symfony1' => 'Symfony1Installer', 'tao' => 'TaoInstaller', 'thelia' => 'TheliaInstaller', 'tusk' => 'TuskInstaller', - 'typo3-cms' => 'TYPO3CmsInstaller', - 'typo3-flow' => 'TYPO3FlowInstaller', 'userfrosting' => 'UserFrostingInstaller', 'vanilla' => 'VanillaInstaller', 'whmcs' => 'WHMCSInstaller', @@ -122,26 +119,17 @@ class Installer extends LibraryInstaller ); /** - * Installer constructor. - * * Disables installers specified in main composer extra installer-disable * list - * - * @param IOInterface $io - * @param Composer $composer - * @param string $type - * @param Filesystem|null $filesystem - * @param BinaryInstaller|null $binaryInstaller */ public function __construct( IOInterface $io, Composer $composer, - $type = 'library', - Filesystem $filesystem = null, - BinaryInstaller $binaryInstaller = null + string $type = 'library', + ?Filesystem $filesystem = null, + ?BinaryInstaller $binaryInstaller = null ) { - parent::__construct($io, $composer, $type, $filesystem, - $binaryInstaller); + parent::__construct($io, $composer, $type, $filesystem, $binaryInstaller); $this->removeDisabledInstallers(); } @@ -160,9 +148,17 @@ public function getInstallPath(PackageInterface $package) } $class = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType]; + /** + * @var BaseInstaller + */ $installer = new $class($package, $this->composer, $this->getIO()); - return $installer->getInstallPath($package, $frameworkType); + $path = $installer->getInstallPath($package, $frameworkType); + if (!$this->filesystem->isAbsolutePath($path)) { + $path = getcwd() . '/' . $path; + } + + return $path; } public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package) @@ -188,6 +184,8 @@ public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $ /** * {@inheritDoc} + * + * @param string $packageType */ public function supports($packageType) { @@ -205,10 +203,9 @@ public function supports($packageType) /** * Finds a supported framework type if it exists and returns it * - * @param string $type * @return string|false */ - protected function findFrameworkType($type) + protected function findFrameworkType(string $type) { krsort($this->supportedTypes); @@ -224,30 +221,24 @@ protected function findFrameworkType($type) /** * Get the second part of the regular expression to check for support of a * package type - * - * @param string $frameworkType - * @return string */ - protected function getLocationPattern($frameworkType) + protected function getLocationPattern(string $frameworkType): string { - $pattern = false; + $pattern = null; if (!empty($this->supportedTypes[$frameworkType])) { $frameworkClass = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType]; /** @var BaseInstaller $framework */ - $framework = new $frameworkClass(null, $this->composer, $this->getIO()); - $locations = array_keys($framework->getLocations()); - $pattern = $locations ? '(' . implode('|', $locations) . ')' : false; + $framework = new $frameworkClass(new Package('dummy/pkg', '1.0.0.0', '1.0.0'), $this->composer, $this->getIO()); + $locations = array_keys($framework->getLocations($frameworkType)); + if ($locations) { + $pattern = '(' . implode('|', $locations) . ')'; + } } - return $pattern ? : '(\w+)'; + return $pattern ?: '(\w+)'; } - /** - * Get I/O object - * - * @return IOInterface - */ - private function getIO() + private function getIO(): IOInterface { return $this->io; } @@ -260,10 +251,8 @@ private function getIO() * - true, "all", and "*" - disable all installers. * - false - enable all installers (useful with * wikimedia/composer-merge-plugin or similar) - * - * @return void */ - protected function removeDisabledInstallers() + protected function removeDisabledInstallers(): void { $extra = $this->composer->getPackage()->getExtra(); @@ -286,12 +275,13 @@ protected function removeDisabledInstallers() if (!empty($intersect)) { // Disable all installers $this->supportedTypes = array(); - } else { - // Disable specified installers - foreach ($disable as $key => $installer) { - if (is_string($installer) && key_exists($installer, $this->supportedTypes)) { - unset($this->supportedTypes[$installer]); - } + return; + } + + // Disable specified installers + foreach ($disable as $key => $installer) { + if (is_string($installer) && key_exists($installer, $this->supportedTypes)) { + unset($this->supportedTypes[$installer]); } } } diff --git a/vendor/composer/installers/src/Composer/Installers/ItopInstaller.php b/vendor/composer/installers/src/Composer/Installers/ItopInstaller.php index c6c1b33..06af068 100644 --- a/vendor/composer/installers/src/Composer/Installers/ItopInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/ItopInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'extension' => 'extensions/{$name}/', ); diff --git a/vendor/composer/installers/src/Composer/Installers/JoomlaInstaller.php b/vendor/composer/installers/src/Composer/Installers/JoomlaInstaller.php deleted file mode 100644 index 9ee7759..0000000 --- a/vendor/composer/installers/src/Composer/Installers/JoomlaInstaller.php +++ /dev/null @@ -1,15 +0,0 @@ - 'components/{$name}/', - 'module' => 'modules/{$name}/', - 'template' => 'templates/{$name}/', - 'plugin' => 'plugins/{$name}/', - 'library' => 'libraries/{$name}/', - ); - - // TODO: Add inflector for mod_ and com_ names -} diff --git a/vendor/composer/installers/src/Composer/Installers/KanboardInstaller.php b/vendor/composer/installers/src/Composer/Installers/KanboardInstaller.php index 9cb7b8c..bca954b 100644 --- a/vendor/composer/installers/src/Composer/Installers/KanboardInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/KanboardInstaller.php @@ -1,4 +1,5 @@ */ protected $locations = array( 'plugin' => 'plugins/{$name}/', ); diff --git a/vendor/composer/installers/src/Composer/Installers/KirbyInstaller.php b/vendor/composer/installers/src/Composer/Installers/KirbyInstaller.php deleted file mode 100644 index 36b2f84..0000000 --- a/vendor/composer/installers/src/Composer/Installers/KirbyInstaller.php +++ /dev/null @@ -1,11 +0,0 @@ - 'site/plugins/{$name}/', - 'field' => 'site/fields/{$name}/', - 'tag' => 'site/tags/{$name}/' - ); -} diff --git a/vendor/composer/installers/src/Composer/Installers/KnownInstaller.php b/vendor/composer/installers/src/Composer/Installers/KnownInstaller.php index c5d08c5..61910a8 100644 --- a/vendor/composer/installers/src/Composer/Installers/KnownInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/KnownInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'plugin' => 'IdnoPlugins/{$name}/', 'theme' => 'Themes/{$name}/', diff --git a/vendor/composer/installers/src/Composer/Installers/KodiCMSInstaller.php b/vendor/composer/installers/src/Composer/Installers/KodiCMSInstaller.php index 7143e23..2505ac6 100644 --- a/vendor/composer/installers/src/Composer/Installers/KodiCMSInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/KodiCMSInstaller.php @@ -1,10 +1,12 @@ */ protected $locations = array( 'plugin' => 'cms/plugins/{$name}/', 'media' => 'cms/media/vendor/{$name}/' ); -} \ No newline at end of file +} diff --git a/vendor/composer/installers/src/Composer/Installers/KohanaInstaller.php b/vendor/composer/installers/src/Composer/Installers/KohanaInstaller.php index dcd6d26..b6aa809 100644 --- a/vendor/composer/installers/src/Composer/Installers/KohanaInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/KohanaInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'module' => 'modules/{$name}/', ); diff --git a/vendor/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php b/vendor/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php index 903143a..7fe9d9b 100644 --- a/vendor/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php @@ -5,6 +5,7 @@ class LanManagementSystemInstaller extends BaseInstaller { + /** @var array */ protected $locations = array( 'plugin' => 'plugins/{$name}/', 'template' => 'templates/{$name}/', @@ -15,13 +16,12 @@ class LanManagementSystemInstaller extends BaseInstaller /** * Format package name to CamelCase */ - public function inflectPackageVars($vars) + public function inflectPackageVars(array $vars): array { - $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); + $vars['name'] = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); return $vars; } - } diff --git a/vendor/composer/installers/src/Composer/Installers/LaravelInstaller.php b/vendor/composer/installers/src/Composer/Installers/LaravelInstaller.php index be4d53a..a69dc88 100644 --- a/vendor/composer/installers/src/Composer/Installers/LaravelInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/LaravelInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'library' => 'libraries/{$name}/', ); diff --git a/vendor/composer/installers/src/Composer/Installers/LavaLiteInstaller.php b/vendor/composer/installers/src/Composer/Installers/LavaLiteInstaller.php index 412c0b5..e4a7c7d 100644 --- a/vendor/composer/installers/src/Composer/Installers/LavaLiteInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/LavaLiteInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'package' => 'packages/{$vendor}/{$name}/', 'theme' => 'public/themes/{$name}/', diff --git a/vendor/composer/installers/src/Composer/Installers/LithiumInstaller.php b/vendor/composer/installers/src/Composer/Installers/LithiumInstaller.php index 47bbd4c..b24bea2 100644 --- a/vendor/composer/installers/src/Composer/Installers/LithiumInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/LithiumInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'library' => 'libraries/{$name}/', 'source' => 'libraries/_source/{$name}/', diff --git a/vendor/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php b/vendor/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php index 9c2e9fb..369e8b4 100644 --- a/vendor/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'module' => 'modules/{$name}/', ); diff --git a/vendor/composer/installers/src/Composer/Installers/MODXEvoInstaller.php b/vendor/composer/installers/src/Composer/Installers/MODXEvoInstaller.php index 5a66460..062a839 100644 --- a/vendor/composer/installers/src/Composer/Installers/MODXEvoInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/MODXEvoInstaller.php @@ -1,4 +1,5 @@ */ protected $locations = array( 'snippet' => 'assets/snippets/{$name}/', 'plugin' => 'assets/plugins/{$name}/', diff --git a/vendor/composer/installers/src/Composer/Installers/MagentoInstaller.php b/vendor/composer/installers/src/Composer/Installers/MagentoInstaller.php index cf18e94..ec07cd6 100644 --- a/vendor/composer/installers/src/Composer/Installers/MagentoInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/MagentoInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'theme' => 'app/design/frontend/{$name}/', 'skin' => 'skin/frontend/default/{$name}/', diff --git a/vendor/composer/installers/src/Composer/Installers/MajimaInstaller.php b/vendor/composer/installers/src/Composer/Installers/MajimaInstaller.php index e463756..6fc3089 100644 --- a/vendor/composer/installers/src/Composer/Installers/MajimaInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/MajimaInstaller.php @@ -1,4 +1,5 @@ */ protected $locations = array( 'plugin' => 'plugins/{$name}/', ); /** * Transforms the names - * @param array $vars - * @return array + * + * @param array $vars + * @return array */ - public function inflectPackageVars($vars) + public function inflectPackageVars(array $vars): array { return $this->correctPluginName($vars); } /** * Change hyphenated names to camelcase - * @param array $vars - * @return array + * + * @param array $vars + * @return array */ - private function correctPluginName($vars) + private function correctPluginName(array $vars): array { $camelCasedName = preg_replace_callback('/(-[a-z])/', function ($matches) { return strtoupper($matches[0][1]); }, $vars['name']); + + if (null === $camelCasedName) { + throw new \RuntimeException('Failed to run preg_replace_callback: '.preg_last_error()); + } + $vars['name'] = ucfirst($camelCasedName); return $vars; } diff --git a/vendor/composer/installers/src/Composer/Installers/MakoInstaller.php b/vendor/composer/installers/src/Composer/Installers/MakoInstaller.php index ca3cfac..cbe3760 100644 --- a/vendor/composer/installers/src/Composer/Installers/MakoInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/MakoInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'package' => 'app/packages/{$name}/', ); diff --git a/vendor/composer/installers/src/Composer/Installers/MantisBTInstaller.php b/vendor/composer/installers/src/Composer/Installers/MantisBTInstaller.php index dadb1db..98e230f 100644 --- a/vendor/composer/installers/src/Composer/Installers/MantisBTInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/MantisBTInstaller.php @@ -1,10 +1,12 @@ */ protected $locations = array( 'plugin' => 'plugins/{$name}/', ); @@ -12,9 +14,9 @@ class MantisBTInstaller extends BaseInstaller /** * Format package name to CamelCase */ - public function inflectPackageVars($vars) + public function inflectPackageVars(array $vars): array { - $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); + $vars['name'] = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); diff --git a/vendor/composer/installers/src/Composer/Installers/PimcoreInstaller.php b/vendor/composer/installers/src/Composer/Installers/MatomoInstaller.php similarity index 53% rename from vendor/composer/installers/src/Composer/Installers/PimcoreInstaller.php rename to vendor/composer/installers/src/Composer/Installers/MatomoInstaller.php index 4781fa6..57fdb03 100644 --- a/vendor/composer/installers/src/Composer/Installers/PimcoreInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/MatomoInstaller.php @@ -1,8 +1,15 @@ */ protected $locations = array( 'plugin' => 'plugins/{$name}/', ); @@ -10,9 +17,9 @@ class PimcoreInstaller extends BaseInstaller /** * Format package name to CamelCase */ - public function inflectPackageVars($vars) + public function inflectPackageVars(array $vars): array { - $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); + $vars['name'] = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); diff --git a/vendor/composer/installers/src/Composer/Installers/MauticInstaller.php b/vendor/composer/installers/src/Composer/Installers/MauticInstaller.php index c3dd2b6..e48c133 100644 --- a/vendor/composer/installers/src/Composer/Installers/MauticInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/MauticInstaller.php @@ -1,17 +1,19 @@ */ protected $locations = array( 'plugin' => 'plugins/{$name}/', 'theme' => 'themes/{$name}/', 'core' => 'app/', ); - private function getDirectoryName() + private function getDirectoryName(): string { $extra = $this->package->getExtra(); if (!empty($extra['install-directory-name'])) { @@ -21,12 +23,7 @@ private function getDirectoryName() return $this->toCamelCase($this->package->getPrettyName()); } - /** - * @param string $packageName - * - * @return string - */ - private function toCamelCase($packageName) + private function toCamelCase(string $packageName): string { return str_replace(' ', '', ucwords(str_replace('-', ' ', basename($packageName)))); } @@ -34,9 +31,8 @@ private function toCamelCase($packageName) /** * Format package name of mautic-plugins to CamelCase */ - public function inflectPackageVars($vars) + public function inflectPackageVars(array $vars): array { - if ($vars['type'] == 'mautic-plugin' || $vars['type'] == 'mautic-theme') { $directoryName = $this->getDirectoryName(); $vars['name'] = $directoryName; @@ -44,5 +40,4 @@ public function inflectPackageVars($vars) return $vars; } - } diff --git a/vendor/composer/installers/src/Composer/Installers/MayaInstaller.php b/vendor/composer/installers/src/Composer/Installers/MayaInstaller.php index 30a9167..df486da 100644 --- a/vendor/composer/installers/src/Composer/Installers/MayaInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/MayaInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'module' => 'modules/{$name}/', ); @@ -11,9 +13,8 @@ class MayaInstaller extends BaseInstaller * Format package name. * * For package type maya-module, cut off a trailing '-module' if present. - * */ - public function inflectPackageVars($vars) + public function inflectPackageVars(array $vars): array { if ($vars['type'] === 'maya-module') { return $this->inflectModuleVars($vars); @@ -22,9 +23,13 @@ public function inflectPackageVars($vars) return $vars; } - protected function inflectModuleVars($vars) + /** + * @param array $vars + * @return array + */ + protected function inflectModuleVars(array $vars): array { - $vars['name'] = preg_replace('/-module$/', '', $vars['name']); + $vars['name'] = $this->pregReplace('/-module$/', '', $vars['name']); $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); diff --git a/vendor/composer/installers/src/Composer/Installers/MediaWikiInstaller.php b/vendor/composer/installers/src/Composer/Installers/MediaWikiInstaller.php index f5a8957..8e9d771 100644 --- a/vendor/composer/installers/src/Composer/Installers/MediaWikiInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/MediaWikiInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'core' => 'core/', 'extension' => 'extensions/{$name}/', @@ -16,11 +18,9 @@ class MediaWikiInstaller extends BaseInstaller * to CamelCase keeping existing uppercase chars. * * For package type mediawiki-skin, cut off a trailing '-skin' if present. - * */ - public function inflectPackageVars($vars) + public function inflectPackageVars(array $vars): array { - if ($vars['type'] === 'mediawiki-extension') { return $this->inflectExtensionVars($vars); } @@ -32,20 +32,27 @@ public function inflectPackageVars($vars) return $vars; } - protected function inflectExtensionVars($vars) + /** + * @param array $vars + * @return array + */ + protected function inflectExtensionVars(array $vars): array { - $vars['name'] = preg_replace('/-extension$/', '', $vars['name']); + $vars['name'] = $this->pregReplace('/-extension$/', '', $vars['name']); $vars['name'] = str_replace('-', ' ', $vars['name']); $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); return $vars; } - protected function inflectSkinVars($vars) + /** + * @param array $vars + * @return array + */ + protected function inflectSkinVars(array $vars): array { - $vars['name'] = preg_replace('/-skin$/', '', $vars['name']); + $vars['name'] = $this->pregReplace('/-skin$/', '', $vars['name']); return $vars; } - } diff --git a/vendor/composer/installers/src/Composer/Installers/MiaoxingInstaller.php b/vendor/composer/installers/src/Composer/Installers/MiaoxingInstaller.php index 66d8369..0254177 100644 --- a/vendor/composer/installers/src/Composer/Installers/MiaoxingInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/MiaoxingInstaller.php @@ -4,6 +4,7 @@ class MiaoxingInstaller extends BaseInstaller { + /** @var array */ protected $locations = array( 'plugin' => 'plugins/{$name}/', ); diff --git a/vendor/composer/installers/src/Composer/Installers/MicroweberInstaller.php b/vendor/composer/installers/src/Composer/Installers/MicroweberInstaller.php index b7d9703..a4d97ab 100644 --- a/vendor/composer/installers/src/Composer/Installers/MicroweberInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/MicroweberInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'module' => 'userfiles/modules/{$install_item_dir}/', 'module-skin' => 'userfiles/modules/{$install_item_dir}/templates/', @@ -18,13 +20,10 @@ class MicroweberInstaller extends BaseInstaller * For package type microweber-module, cut off a trailing '-module' if present * * For package type microweber-template, cut off a trailing '-template' if present. - * */ - public function inflectPackageVars($vars) + public function inflectPackageVars(array $vars): array { - - - if ($this->package->getTargetDir()) { + if ($this->package->getTargetDir() !== null && $this->package->getTargetDir() !== '') { $vars['install_item_dir'] = $this->package->getTargetDir(); } else { $vars['install_item_dir'] = $vars['name']; @@ -54,65 +53,92 @@ public function inflectPackageVars($vars) } } - return $vars; } - protected function inflectTemplateVars($vars) + /** + * @param array $vars + * @return array + */ + protected function inflectTemplateVars(array $vars): array { - $vars['install_item_dir'] = preg_replace('/-template$/', '', $vars['install_item_dir']); - $vars['install_item_dir'] = preg_replace('/template-$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = $this->pregReplace('/-template$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = $this->pregReplace('/template-$/', '', $vars['install_item_dir']); return $vars; } - protected function inflectTemplatesVars($vars) + /** + * @param array $vars + * @return array + */ + protected function inflectTemplatesVars(array $vars): array { - $vars['install_item_dir'] = preg_replace('/-templates$/', '', $vars['install_item_dir']); - $vars['install_item_dir'] = preg_replace('/templates-$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = $this->pregReplace('/-templates$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = $this->pregReplace('/templates-$/', '', $vars['install_item_dir']); return $vars; } - protected function inflectCoreVars($vars) + /** + * @param array $vars + * @return array + */ + protected function inflectCoreVars(array $vars): array { - $vars['install_item_dir'] = preg_replace('/-providers$/', '', $vars['install_item_dir']); - $vars['install_item_dir'] = preg_replace('/-provider$/', '', $vars['install_item_dir']); - $vars['install_item_dir'] = preg_replace('/-adapter$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = $this->pregReplace('/-providers$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = $this->pregReplace('/-provider$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = $this->pregReplace('/-adapter$/', '', $vars['install_item_dir']); return $vars; } - protected function inflectModuleVars($vars) + /** + * @param array $vars + * @return array + */ + protected function inflectModuleVars(array $vars): array { - $vars['install_item_dir'] = preg_replace('/-module$/', '', $vars['install_item_dir']); - $vars['install_item_dir'] = preg_replace('/module-$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = $this->pregReplace('/-module$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = $this->pregReplace('/module-$/', '', $vars['install_item_dir']); return $vars; } - protected function inflectModulesVars($vars) + /** + * @param array $vars + * @return array + */ + protected function inflectModulesVars(array $vars): array { - $vars['install_item_dir'] = preg_replace('/-modules$/', '', $vars['install_item_dir']); - $vars['install_item_dir'] = preg_replace('/modules-$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = $this->pregReplace('/-modules$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = $this->pregReplace('/modules-$/', '', $vars['install_item_dir']); return $vars; } - protected function inflectSkinVars($vars) + /** + * @param array $vars + * @return array + */ + protected function inflectSkinVars(array $vars): array { - $vars['install_item_dir'] = preg_replace('/-skin$/', '', $vars['install_item_dir']); - $vars['install_item_dir'] = preg_replace('/skin-$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = $this->pregReplace('/-skin$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = $this->pregReplace('/skin-$/', '', $vars['install_item_dir']); return $vars; } - protected function inflectElementVars($vars) + /** + * @param array $vars + * @return array + */ + protected function inflectElementVars(array $vars): array { - $vars['install_item_dir'] = preg_replace('/-elements$/', '', $vars['install_item_dir']); - $vars['install_item_dir'] = preg_replace('/elements-$/', '', $vars['install_item_dir']); - $vars['install_item_dir'] = preg_replace('/-element$/', '', $vars['install_item_dir']); - $vars['install_item_dir'] = preg_replace('/element-$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = $this->pregReplace('/-elements$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = $this->pregReplace('/elements-$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = $this->pregReplace('/-element$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = $this->pregReplace('/element-$/', '', $vars['install_item_dir']); return $vars; } diff --git a/vendor/composer/installers/src/Composer/Installers/ModxInstaller.php b/vendor/composer/installers/src/Composer/Installers/ModxInstaller.php index 0ee140a..e2dddec 100644 --- a/vendor/composer/installers/src/Composer/Installers/ModxInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/ModxInstaller.php @@ -1,4 +1,5 @@ */ protected $locations = array( 'extra' => 'core/packages/{$name}/' ); diff --git a/vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php b/vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php index 0531799..eb2b8ac 100644 --- a/vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'mod' => 'mod/{$name}/', 'admin_report' => 'admin/report/{$name}/', @@ -11,6 +13,7 @@ class MoodleInstaller extends BaseInstaller 'assignment' => 'mod/assignment/type/{$name}/', 'assignsubmission' => 'mod/assign/submission/{$name}/', 'assignfeedback' => 'mod/assign/feedback/{$name}/', + 'antivirus' => 'lib/antivirus/{$name}/', 'auth' => 'auth/{$name}/', 'availability' => 'availability/condition/{$name}/', 'block' => 'blocks/{$name}/', @@ -18,27 +21,37 @@ class MoodleInstaller extends BaseInstaller 'cachestore' => 'cache/stores/{$name}/', 'cachelock' => 'cache/locks/{$name}/', 'calendartype' => 'calendar/type/{$name}/', + 'communication' => 'communication/provider/{$name}/', + 'customfield' => 'customfield/field/{$name}/', 'fileconverter' => 'files/converter/{$name}/', 'format' => 'course/format/{$name}/', 'coursereport' => 'course/report/{$name}/', + 'contenttype' => 'contentbank/contenttype/{$name}/', 'customcertelement' => 'mod/customcert/element/{$name}/', 'datafield' => 'mod/data/field/{$name}/', + 'dataformat' => 'dataformat/{$name}/', 'datapreset' => 'mod/data/preset/{$name}/', 'editor' => 'lib/editor/{$name}/', 'enrol' => 'enrol/{$name}/', 'filter' => 'filter/{$name}/', + 'forumreport' => 'mod/forum/report/{$name}/', 'gradeexport' => 'grade/export/{$name}/', 'gradeimport' => 'grade/import/{$name}/', 'gradereport' => 'grade/report/{$name}/', 'gradingform' => 'grade/grading/form/{$name}/', + 'h5plib' => 'h5p/h5plib/{$name}/', 'local' => 'local/{$name}/', 'logstore' => 'admin/tool/log/store/{$name}/', 'ltisource' => 'mod/lti/source/{$name}/', 'ltiservice' => 'mod/lti/service/{$name}/', + 'media' => 'media/player/{$name}/', 'message' => 'message/output/{$name}/', + 'mlbackend' => 'lib/mlbackend/{$name}/', 'mnetservice' => 'mnet/service/{$name}/', + 'paygw' => 'payment/gateway/{$name}/', 'plagiarism' => 'plagiarism/{$name}/', 'portfolio' => 'portfolio/{$name}/', + 'qbank' => 'question/bank/{$name}/', 'qbehaviour' => 'question/behaviour/{$name}/', 'qformat' => 'question/format/{$name}/', 'qtype' => 'question/type/{$name}/', @@ -49,6 +62,7 @@ class MoodleInstaller extends BaseInstaller 'scormreport' => 'mod/scorm/report/{$name}/', 'search' => 'search/engine/{$name}/', 'theme' => 'theme/{$name}/', + 'tiny' => 'lib/editor/tiny/plugins/{$name}/', 'tinymce' => 'lib/editor/tinymce/plugins/{$name}/', 'profilefield' => 'user/profile/field/{$name}/', 'webservice' => 'webservice/{$name}/', diff --git a/vendor/composer/installers/src/Composer/Installers/OctoberInstaller.php b/vendor/composer/installers/src/Composer/Installers/OctoberInstaller.php index 489ef02..524f17d 100644 --- a/vendor/composer/installers/src/Composer/Installers/OctoberInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/OctoberInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'module' => 'modules/{$name}/', 'plugin' => 'plugins/{$vendor}/{$name}/', @@ -15,9 +17,8 @@ class OctoberInstaller extends BaseInstaller * For package type october-plugin, cut off a trailing '-plugin' if present. * * For package type october-theme, cut off a trailing '-theme' if present. - * */ - public function inflectPackageVars($vars) + public function inflectPackageVars(array $vars): array { if ($vars['type'] === 'october-plugin') { return $this->inflectPluginVars($vars); @@ -30,18 +31,26 @@ public function inflectPackageVars($vars) return $vars; } - protected function inflectPluginVars($vars) + /** + * @param array $vars + * @return array + */ + protected function inflectPluginVars(array $vars): array { - $vars['name'] = preg_replace('/^oc-|-plugin$/', '', $vars['name']); - $vars['vendor'] = preg_replace('/[^a-z0-9_]/i', '', $vars['vendor']); + $vars['name'] = $this->pregReplace('/^oc-|-plugin$/', '', $vars['name']); + $vars['vendor'] = $this->pregReplace('/[^a-z0-9_]/i', '', $vars['vendor']); return $vars; } - protected function inflectThemeVars($vars) + /** + * @param array $vars + * @return array + */ + protected function inflectThemeVars(array $vars): array { - $vars['name'] = preg_replace('/^oc-|-theme$/', '', $vars['name']); - $vars['vendor'] = preg_replace('/[^a-z0-9_]/i', '', $vars['vendor']); + $vars['name'] = $this->pregReplace('/^oc-|-theme$/', '', $vars['name']); + $vars['vendor'] = $this->pregReplace('/[^a-z0-9_]/i', '', $vars['vendor']); return $vars; } diff --git a/vendor/composer/installers/src/Composer/Installers/OntoWikiInstaller.php b/vendor/composer/installers/src/Composer/Installers/OntoWikiInstaller.php index 5dd3438..fd20c1a 100644 --- a/vendor/composer/installers/src/Composer/Installers/OntoWikiInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/OntoWikiInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'extension' => 'extensions/{$name}/', 'theme' => 'extensions/themes/{$name}/', @@ -12,12 +14,12 @@ class OntoWikiInstaller extends BaseInstaller /** * Format package name to lower case and remove ".ontowiki" suffix */ - public function inflectPackageVars($vars) + public function inflectPackageVars(array $vars): array { $vars['name'] = strtolower($vars['name']); - $vars['name'] = preg_replace('/.ontowiki$/', '', $vars['name']); - $vars['name'] = preg_replace('/-theme$/', '', $vars['name']); - $vars['name'] = preg_replace('/-translation$/', '', $vars['name']); + $vars['name'] = $this->pregReplace('/.ontowiki$/', '', $vars['name']); + $vars['name'] = $this->pregReplace('/-theme$/', '', $vars['name']); + $vars['name'] = $this->pregReplace('/-translation$/', '', $vars['name']); return $vars; } diff --git a/vendor/composer/installers/src/Composer/Installers/OsclassInstaller.php b/vendor/composer/installers/src/Composer/Installers/OsclassInstaller.php index 3ca7954..e61d61f 100644 --- a/vendor/composer/installers/src/Composer/Installers/OsclassInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/OsclassInstaller.php @@ -1,14 +1,14 @@ */ protected $locations = array( 'plugin' => 'oc-content/plugins/{$name}/', 'theme' => 'oc-content/themes/{$name}/', 'language' => 'oc-content/languages/{$name}/', ); - } diff --git a/vendor/composer/installers/src/Composer/Installers/OxidInstaller.php b/vendor/composer/installers/src/Composer/Installers/OxidInstaller.php index 1797a22..6e1e862 100644 --- a/vendor/composer/installers/src/Composer/Installers/OxidInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/OxidInstaller.php @@ -1,59 +1,49 @@ .+)\/.+/'; + const VENDOR_PATTERN = '/^modules\/(?P.+)\/.+/'; + /** @var array */ protected $locations = array( 'module' => 'modules/{$name}/', 'theme' => 'application/views/{$name}/', 'out' => 'out/{$name}/', ); - /** - * getInstallPath - * - * @param PackageInterface $package - * @param string $frameworkType - * @return string - */ - public function getInstallPath(PackageInterface $package, $frameworkType = '') - { - $installPath = parent::getInstallPath($package, $frameworkType); - $type = $this->package->getType(); - if ($type === 'oxid-module') { - $this->prepareVendorDirectory($installPath); - } - return $installPath; - } - - /** - * prepareVendorDirectory - * - * Makes sure there is a vendormetadata.php file inside - * the vendor folder if there is a vendor folder. - * - * @param string $installPath - * @return void - */ - protected function prepareVendorDirectory($installPath) - { - $matches = ''; - $hasVendorDirectory = preg_match(self::VENDOR_PATTERN, $installPath, $matches); - if (!$hasVendorDirectory) { - return; - } - - $vendorDirectory = $matches['vendor']; - $vendorPath = getcwd() . '/modules/' . $vendorDirectory; - if (!file_exists($vendorPath)) { - mkdir($vendorPath, 0755, true); - } - - $vendorMetaDataPath = $vendorPath . '/vendormetadata.php'; - touch($vendorMetaDataPath); - } + public function getInstallPath(PackageInterface $package, string $frameworkType = ''): string + { + $installPath = parent::getInstallPath($package, $frameworkType); + $type = $this->package->getType(); + if ($type === 'oxid-module') { + $this->prepareVendorDirectory($installPath); + } + return $installPath; + } + + /** + * Makes sure there is a vendormetadata.php file inside + * the vendor folder if there is a vendor folder. + */ + protected function prepareVendorDirectory(string $installPath): void + { + $matches = ''; + $hasVendorDirectory = preg_match(self::VENDOR_PATTERN, $installPath, $matches); + if (!$hasVendorDirectory) { + return; + } + + $vendorDirectory = $matches['vendor']; + $vendorPath = getcwd() . '/modules/' . $vendorDirectory; + if (!file_exists($vendorPath)) { + mkdir($vendorPath, 0755, true); + } + + $vendorMetaDataPath = $vendorPath . '/vendormetadata.php'; + touch($vendorMetaDataPath); + } } diff --git a/vendor/composer/installers/src/Composer/Installers/PPIInstaller.php b/vendor/composer/installers/src/Composer/Installers/PPIInstaller.php index 170136f..714c467 100644 --- a/vendor/composer/installers/src/Composer/Installers/PPIInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/PPIInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'module' => 'modules/{$name}/', ); diff --git a/vendor/composer/installers/src/Composer/Installers/PhiftyInstaller.php b/vendor/composer/installers/src/Composer/Installers/PhiftyInstaller.php index 4e59a8a..3c970e2 100644 --- a/vendor/composer/installers/src/Composer/Installers/PhiftyInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/PhiftyInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'bundle' => 'bundles/{$name}/', 'library' => 'libraries/{$name}/', diff --git a/vendor/composer/installers/src/Composer/Installers/PhpBBInstaller.php b/vendor/composer/installers/src/Composer/Installers/PhpBBInstaller.php index deb2b77..d53ee4f 100644 --- a/vendor/composer/installers/src/Composer/Installers/PhpBBInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/PhpBBInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'extension' => 'ext/{$vendor}/{$name}/', 'language' => 'language/{$name}/', diff --git a/vendor/composer/installers/src/Composer/Installers/PiwikInstaller.php b/vendor/composer/installers/src/Composer/Installers/PiwikInstaller.php index c17f457..b2faf44 100644 --- a/vendor/composer/installers/src/Composer/Installers/PiwikInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/PiwikInstaller.php @@ -1,4 +1,5 @@ */ protected $locations = array( 'plugin' => 'plugins/{$name}/', ); /** * Format package name to CamelCase - * @param array $vars - * - * @return array */ - public function inflectPackageVars($vars) + public function inflectPackageVars(array $vars): array { - $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); + $vars['name'] = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); diff --git a/vendor/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php b/vendor/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php index 903e55f..0c06359 100644 --- a/vendor/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php @@ -1,28 +1,27 @@ */ protected $locations = array( 'plugin' => '{$name}/' ); /** * Remove hyphen, "plugin" and format to camelcase - * @param array $vars - * - * @return array */ - public function inflectPackageVars($vars) + public function inflectPackageVars(array $vars): array { - $vars['name'] = explode("-", $vars['name']); - foreach ($vars['name'] as $key => $name) { - $vars['name'][$key] = ucfirst($vars['name'][$key]); + $nameBits = explode("-", $vars['name']); + foreach ($nameBits as $key => $name) { + $nameBits[$key] = ucfirst($name); if (strcasecmp($name, "Plugin") == 0) { - unset($vars['name'][$key]); + unset($nameBits[$key]); } } - $vars['name'] = implode("",$vars['name']); + $vars['name'] = implode('', $nameBits); return $vars; } diff --git a/vendor/composer/installers/src/Composer/Installers/Plugin.php b/vendor/composer/installers/src/Composer/Installers/Plugin.php index e60da0e..437a949 100644 --- a/vendor/composer/installers/src/Composer/Installers/Plugin.php +++ b/vendor/composer/installers/src/Composer/Installers/Plugin.php @@ -8,20 +8,21 @@ class Plugin implements PluginInterface { + /** @var Installer */ private $installer; - public function activate(Composer $composer, IOInterface $io) + public function activate(Composer $composer, IOInterface $io): void { $this->installer = new Installer($io, $composer); $composer->getInstallationManager()->addInstaller($this->installer); } - public function deactivate(Composer $composer, IOInterface $io) + public function deactivate(Composer $composer, IOInterface $io): void { $composer->getInstallationManager()->removeInstaller($this->installer); } - public function uninstall(Composer $composer, IOInterface $io) + public function uninstall(Composer $composer, IOInterface $io): void { } } diff --git a/vendor/composer/installers/src/Composer/Installers/PortoInstaller.php b/vendor/composer/installers/src/Composer/Installers/PortoInstaller.php index dbf85e6..a01d7a0 100644 --- a/vendor/composer/installers/src/Composer/Installers/PortoInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/PortoInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'container' => 'app/Containers/{$name}/', ); diff --git a/vendor/composer/installers/src/Composer/Installers/PrestashopInstaller.php b/vendor/composer/installers/src/Composer/Installers/PrestashopInstaller.php index 4c8421e..23f156f 100644 --- a/vendor/composer/installers/src/Composer/Installers/PrestashopInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/PrestashopInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'module' => 'modules/{$name}/', 'theme' => 'themes/{$name}/', diff --git a/vendor/composer/installers/src/Composer/Installers/ProcessWireInstaller.php b/vendor/composer/installers/src/Composer/Installers/ProcessWireInstaller.php index e6834a0..a7eb1ee 100644 --- a/vendor/composer/installers/src/Composer/Installers/ProcessWireInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/ProcessWireInstaller.php @@ -4,6 +4,7 @@ class ProcessWireInstaller extends BaseInstaller { + /** @var array */ protected $locations = array( 'module' => 'site/modules/{$name}/', ); @@ -11,9 +12,9 @@ class ProcessWireInstaller extends BaseInstaller /** * Format package name to CamelCase */ - public function inflectPackageVars($vars) + public function inflectPackageVars(array $vars): array { - $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); + $vars['name'] = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); diff --git a/vendor/composer/installers/src/Composer/Installers/PuppetInstaller.php b/vendor/composer/installers/src/Composer/Installers/PuppetInstaller.php index 77cc3dd..1a0a8a3 100644 --- a/vendor/composer/installers/src/Composer/Installers/PuppetInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/PuppetInstaller.php @@ -5,6 +5,7 @@ class PuppetInstaller extends BaseInstaller { + /** @var array */ protected $locations = array( 'module' => 'modules/{$name}/', ); diff --git a/vendor/composer/installers/src/Composer/Installers/PxcmsInstaller.php b/vendor/composer/installers/src/Composer/Installers/PxcmsInstaller.php index 6551058..fc58b8a 100644 --- a/vendor/composer/installers/src/Composer/Installers/PxcmsInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/PxcmsInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'module' => 'app/Modules/{$name}/', 'theme' => 'themes/{$name}/', @@ -10,12 +12,8 @@ class PxcmsInstaller extends BaseInstaller /** * Format package name. - * - * @param array $vars - * - * @return array */ - public function inflectPackageVars($vars) + public function inflectPackageVars(array $vars): array { if ($vars['type'] === 'pxcms-module') { return $this->inflectModuleVars($vars); @@ -31,30 +29,31 @@ public function inflectPackageVars($vars) /** * For package type pxcms-module, cut off a trailing '-plugin' if present. * - * return string + * @param array $vars + * @return array */ - protected function inflectModuleVars($vars) + protected function inflectModuleVars(array $vars): array { $vars['name'] = str_replace('pxcms-', '', $vars['name']); // strip out pxcms- just incase (legacy) $vars['name'] = str_replace('module-', '', $vars['name']); // strip out module- - $vars['name'] = preg_replace('/-module$/', '', $vars['name']); // strip out -module + $vars['name'] = $this->pregReplace('/-module$/', '', $vars['name']); // strip out -module $vars['name'] = str_replace('-', '_', $vars['name']); // make -'s be _'s $vars['name'] = ucwords($vars['name']); // make module name camelcased return $vars; } - /** * For package type pxcms-module, cut off a trailing '-plugin' if present. * - * return string + * @param array $vars + * @return array */ - protected function inflectThemeVars($vars) + protected function inflectThemeVars(array $vars): array { $vars['name'] = str_replace('pxcms-', '', $vars['name']); // strip out pxcms- just incase (legacy) $vars['name'] = str_replace('theme-', '', $vars['name']); // strip out theme- - $vars['name'] = preg_replace('/-theme$/', '', $vars['name']); // strip out -theme + $vars['name'] = $this->pregReplace('/-theme$/', '', $vars['name']); // strip out -theme $vars['name'] = str_replace('-', '_', $vars['name']); // make -'s be _'s $vars['name'] = ucwords($vars['name']); // make module name camelcased diff --git a/vendor/composer/installers/src/Composer/Installers/RadPHPInstaller.php b/vendor/composer/installers/src/Composer/Installers/RadPHPInstaller.php index 0f78b5c..4caae51 100644 --- a/vendor/composer/installers/src/Composer/Installers/RadPHPInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/RadPHPInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'bundle' => 'src/{$name}/' ); @@ -10,11 +12,11 @@ class RadPHPInstaller extends BaseInstaller /** * Format package name to CamelCase */ - public function inflectPackageVars($vars) + public function inflectPackageVars(array $vars): array { $nameParts = explode('/', $vars['name']); foreach ($nameParts as &$value) { - $value = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $value)); + $value = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $value)); $value = str_replace(array('-', '_'), ' ', $value); $value = str_replace(' ', '', ucwords($value)); } diff --git a/vendor/composer/installers/src/Composer/Installers/ReIndexInstaller.php b/vendor/composer/installers/src/Composer/Installers/ReIndexInstaller.php index 252c733..a19eaaf 100644 --- a/vendor/composer/installers/src/Composer/Installers/ReIndexInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/ReIndexInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'theme' => 'themes/{$name}/', 'plugin' => 'plugins/{$name}/' diff --git a/vendor/composer/installers/src/Composer/Installers/Redaxo5Installer.php b/vendor/composer/installers/src/Composer/Installers/Redaxo5Installer.php index 23a2034..b62c926 100644 --- a/vendor/composer/installers/src/Composer/Installers/Redaxo5Installer.php +++ b/vendor/composer/installers/src/Composer/Installers/Redaxo5Installer.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'addon' => 'redaxo/src/addons/{$name}/', 'bestyle-plugin' => 'redaxo/src/addons/be_style/plugins/{$name}/' diff --git a/vendor/composer/installers/src/Composer/Installers/RedaxoInstaller.php b/vendor/composer/installers/src/Composer/Installers/RedaxoInstaller.php index 0954457..26b3aa8 100644 --- a/vendor/composer/installers/src/Composer/Installers/RedaxoInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/RedaxoInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'addon' => 'redaxo/include/addons/{$name}/', 'bestyle-plugin' => 'redaxo/include/addons/be_style/plugins/{$name}/' diff --git a/vendor/composer/installers/src/Composer/Installers/RoundcubeInstaller.php b/vendor/composer/installers/src/Composer/Installers/RoundcubeInstaller.php index d8d795b..7e71674 100644 --- a/vendor/composer/installers/src/Composer/Installers/RoundcubeInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/RoundcubeInstaller.php @@ -1,19 +1,18 @@ */ protected $locations = array( 'plugin' => 'plugins/{$name}/', ); /** * Lowercase name and changes the name to a underscores - * - * @param array $vars - * @return array */ - public function inflectPackageVars($vars) + public function inflectPackageVars(array $vars): array { $vars['name'] = strtolower(str_replace('-', '_', $vars['name'])); diff --git a/vendor/composer/installers/src/Composer/Installers/SMFInstaller.php b/vendor/composer/installers/src/Composer/Installers/SMFInstaller.php index 1acd3b1..7321046 100644 --- a/vendor/composer/installers/src/Composer/Installers/SMFInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/SMFInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'module' => 'Sources/{$name}/', 'theme' => 'Themes/{$name}/', diff --git a/vendor/composer/installers/src/Composer/Installers/ShopwareInstaller.php b/vendor/composer/installers/src/Composer/Installers/ShopwareInstaller.php index 7d20d27..82b8e28 100644 --- a/vendor/composer/installers/src/Composer/Installers/ShopwareInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/ShopwareInstaller.php @@ -1,4 +1,5 @@ */ protected $locations = array( 'backend-plugin' => 'engine/Shopware/Plugins/Local/Backend/{$name}/', 'core-plugin' => 'engine/Shopware/Plugins/Local/Core/{$name}/', @@ -18,29 +20,32 @@ class ShopwareInstaller extends BaseInstaller /** * Transforms the names - * @param array $vars - * @return array */ - public function inflectPackageVars($vars) + public function inflectPackageVars(array $vars): array { if ($vars['type'] === 'shopware-theme') { return $this->correctThemeName($vars); } - return $this->correctPluginName($vars); + return $this->correctPluginName($vars); } /** * Changes the name to a camelcased combination of vendor and name - * @param array $vars - * @return array + * + * @param array $vars + * @return array */ - private function correctPluginName($vars) + private function correctPluginName(array $vars): array { $camelCasedName = preg_replace_callback('/(-[a-z])/', function ($matches) { return strtoupper($matches[0][1]); }, $vars['name']); + if (null === $camelCasedName) { + throw new \RuntimeException('Failed to run preg_replace_callback: '.preg_last_error()); + } + $vars['name'] = ucfirst($vars['vendor']) . ucfirst($camelCasedName); return $vars; @@ -48,10 +53,11 @@ private function correctPluginName($vars) /** * Changes the name to a underscore separated name - * @param array $vars - * @return array + * + * @param array $vars + * @return array */ - private function correctThemeName($vars) + private function correctThemeName(array $vars): array { $vars['name'] = str_replace('-', '_', $vars['name']); diff --git a/vendor/composer/installers/src/Composer/Installers/SilverStripeInstaller.php b/vendor/composer/installers/src/Composer/Installers/SilverStripeInstaller.php index 81910e9..aa2de21 100644 --- a/vendor/composer/installers/src/Composer/Installers/SilverStripeInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/SilverStripeInstaller.php @@ -1,10 +1,12 @@ */ protected $locations = array( 'module' => '{$name}/', 'theme' => 'themes/{$name}/', @@ -15,12 +17,8 @@ class SilverStripeInstaller extends BaseInstaller * * Relies on built-in BaseInstaller behaviour with one exception: silverstripe/framework * must be installed to 'sapphire' and not 'framework' if the version is <3.0.0 - * - * @param PackageInterface $package - * @param string $frameworkType - * @return string */ - public function getInstallPath(PackageInterface $package, $frameworkType = '') + public function getInstallPath(PackageInterface $package, string $frameworkType = ''): string { if ( $package->getName() == 'silverstripe/framework' diff --git a/vendor/composer/installers/src/Composer/Installers/SiteDirectInstaller.php b/vendor/composer/installers/src/Composer/Installers/SiteDirectInstaller.php index 762d94c..0af3239 100644 --- a/vendor/composer/installers/src/Composer/Installers/SiteDirectInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/SiteDirectInstaller.php @@ -4,17 +4,26 @@ class SiteDirectInstaller extends BaseInstaller { + /** @var array */ protected $locations = array( 'module' => 'modules/{$vendor}/{$name}/', 'plugin' => 'plugins/{$vendor}/{$name}/' ); - public function inflectPackageVars($vars) + /** + * @param array $vars + * @return array + */ + public function inflectPackageVars(array $vars): array { return $this->parseVars($vars); } - protected function parseVars($vars) + /** + * @param array $vars + * @return array + */ + protected function parseVars(array $vars): array { $vars['vendor'] = strtolower($vars['vendor']) == 'sitedirect' ? 'SiteDirect' : $vars['vendor']; $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); diff --git a/vendor/composer/installers/src/Composer/Installers/StarbugInstaller.php b/vendor/composer/installers/src/Composer/Installers/StarbugInstaller.php index a31c9fd..72afa08 100644 --- a/vendor/composer/installers/src/Composer/Installers/StarbugInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/StarbugInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'module' => 'modules/{$name}/', 'theme' => 'themes/{$name}/', diff --git a/vendor/composer/installers/src/Composer/Installers/SyDESInstaller.php b/vendor/composer/installers/src/Composer/Installers/SyDESInstaller.php index 8626a9b..24673d2 100644 --- a/vendor/composer/installers/src/Composer/Installers/SyDESInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/SyDESInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'module' => 'app/modules/{$name}/', 'theme' => 'themes/{$name}/', @@ -12,10 +14,8 @@ class SyDESInstaller extends BaseInstaller * Format module name. * * Strip `sydes-` prefix and a trailing '-theme' or '-module' from package name if present. - * - * {@inerhitDoc} */ - public function inflectPackageVars($vars) + public function inflectPackageVars(array $vars): array { if ($vars['type'] == 'sydes-module') { return $this->inflectModuleVars($vars); @@ -28,18 +28,26 @@ public function inflectPackageVars($vars) return $vars; } - public function inflectModuleVars($vars) + /** + * @param array $vars + * @return array + */ + public function inflectModuleVars(array $vars): array { - $vars['name'] = preg_replace('/(^sydes-|-module$)/i', '', $vars['name']); + $vars['name'] = $this->pregReplace('/(^sydes-|-module$)/i', '', $vars['name']); $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); return $vars; } - protected function inflectThemeVars($vars) + /** + * @param array $vars + * @return array + */ + protected function inflectThemeVars(array $vars): array { - $vars['name'] = preg_replace('/(^sydes-|-theme$)/', '', $vars['name']); + $vars['name'] = $this->pregReplace('/(^sydes-|-theme$)/', '', $vars['name']); $vars['name'] = strtolower($vars['name']); return $vars; diff --git a/vendor/composer/installers/src/Composer/Installers/SyliusInstaller.php b/vendor/composer/installers/src/Composer/Installers/SyliusInstaller.php index 4357a35..c82bd85 100644 --- a/vendor/composer/installers/src/Composer/Installers/SyliusInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/SyliusInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'theme' => 'themes/{$name}/', ); diff --git a/vendor/composer/installers/src/Composer/Installers/Symfony1Installer.php b/vendor/composer/installers/src/Composer/Installers/Symfony1Installer.php deleted file mode 100644 index 1675c4f..0000000 --- a/vendor/composer/installers/src/Composer/Installers/Symfony1Installer.php +++ /dev/null @@ -1,26 +0,0 @@ - - */ -class Symfony1Installer extends BaseInstaller -{ - protected $locations = array( - 'plugin' => 'plugins/{$name}/', - ); - - /** - * Format package name to CamelCase - */ - public function inflectPackageVars($vars) - { - $vars['name'] = preg_replace_callback('/(-[a-z])/', function ($matches) { - return strtoupper($matches[0][1]); - }, $vars['name']); - - return $vars; - } -} diff --git a/vendor/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php b/vendor/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php deleted file mode 100644 index b1663e8..0000000 --- a/vendor/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php +++ /dev/null @@ -1,16 +0,0 @@ - - */ -class TYPO3CmsInstaller extends BaseInstaller -{ - protected $locations = array( - 'extension' => 'typo3conf/ext/{$name}/', - ); -} diff --git a/vendor/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php b/vendor/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php deleted file mode 100644 index 42572f4..0000000 --- a/vendor/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php +++ /dev/null @@ -1,38 +0,0 @@ - 'Packages/Application/{$name}/', - 'framework' => 'Packages/Framework/{$name}/', - 'plugin' => 'Packages/Plugins/{$name}/', - 'site' => 'Packages/Sites/{$name}/', - 'boilerplate' => 'Packages/Boilerplates/{$name}/', - 'build' => 'Build/{$name}/', - ); - - /** - * Modify the package name to be a TYPO3 Flow style key. - * - * @param array $vars - * @return array - */ - public function inflectPackageVars($vars) - { - $autoload = $this->package->getAutoload(); - if (isset($autoload['psr-0']) && is_array($autoload['psr-0'])) { - $namespace = key($autoload['psr-0']); - $vars['name'] = str_replace('\\', '.', $namespace); - } - if (isset($autoload['psr-4']) && is_array($autoload['psr-4'])) { - $namespace = key($autoload['psr-4']); - $vars['name'] = rtrim(str_replace('\\', '.', $namespace), '.'); - } - - return $vars; - } -} diff --git a/vendor/composer/installers/src/Composer/Installers/TaoInstaller.php b/vendor/composer/installers/src/Composer/Installers/TaoInstaller.php index 4f79a45..8c1d814 100644 --- a/vendor/composer/installers/src/Composer/Installers/TaoInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/TaoInstaller.php @@ -1,4 +1,5 @@ */ protected $locations = array( 'extension' => '{$name}' ); - public function inflectPackageVars($vars) + public function inflectPackageVars(array $vars): array { $extra = $this->package->getExtra(); diff --git a/vendor/composer/installers/src/Composer/Installers/TastyIgniterInstaller.php b/vendor/composer/installers/src/Composer/Installers/TastyIgniterInstaller.php index e20e65b..39ceae0 100644 --- a/vendor/composer/installers/src/Composer/Installers/TastyIgniterInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/TastyIgniterInstaller.php @@ -4,10 +4,12 @@ class TastyIgniterInstaller extends BaseInstaller { - protected $locations = array( + /** @var array */ + protected $locations = [ + 'module' => 'app/{$name}/', 'extension' => 'extensions/{$vendor}/{$name}/', 'theme' => 'themes/{$name}/', - ); + ]; /** * Format package name. @@ -16,17 +18,68 @@ class TastyIgniterInstaller extends BaseInstaller * Strip vendor name of characters that is not alphanumeric or an underscore * */ - public function inflectPackageVars($vars) + public function inflectPackageVars(array $vars): array { + $extra = $this->package->getExtra(); + + if ($vars['type'] === 'tastyigniter-module') { + return $this->inflectModuleVars($vars); + } + if ($vars['type'] === 'tastyigniter-extension') { - $vars['vendor'] = preg_replace('/[^a-z0-9_]/i', '', $vars['vendor']); - $vars['name'] = preg_replace('/^ti-ext-/', '', $vars['name']); + return $this->inflectExtensionVars($vars, $extra); } if ($vars['type'] === 'tastyigniter-theme') { - $vars['name'] = preg_replace('/^ti-theme-/', '', $vars['name']); + return $this->inflectThemeVars($vars, $extra); + } + + return $vars; + } + + /** + * @param array $vars + * @return array + */ + protected function inflectModuleVars(array $vars): array + { + $vars['name'] = $this->pregReplace('/^ti-module-/', '', $vars['name']); + + return $vars; + } + + /** + * @param array $vars + * @param array $extra + * @return array + */ + protected function inflectExtensionVars(array $vars, array $extra): array + { + if (!empty($extra['tastyigniter-extension']['code'])) { + $parts = explode('.', $extra['tastyigniter-extension']['code']); + $vars['vendor'] = (string)$parts[0]; + $vars['name'] = (string)($parts[1] ?? ''); + } + + $vars['vendor'] = $this->pregReplace('/[^a-z0-9_]/i', '', $vars['vendor']); + $vars['name'] = $this->pregReplace('/^ti-ext-/', '', $vars['name']); + + return $vars; + } + + /** + * @param array $vars + * @param array $extra + * @return array + */ + protected function inflectThemeVars(array $vars, array $extra): array + { + if (!empty($extra['tastyigniter-theme']['code'])) { + $vars['name'] = $extra['tastyigniter-theme']['code']; } + $vars['name'] = $this->pregReplace('/^ti-theme-/', '', $vars['name']); + return $vars; } -} \ No newline at end of file +} diff --git a/vendor/composer/installers/src/Composer/Installers/TheliaInstaller.php b/vendor/composer/installers/src/Composer/Installers/TheliaInstaller.php index 158af52..896bed5 100644 --- a/vendor/composer/installers/src/Composer/Installers/TheliaInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/TheliaInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'module' => 'local/modules/{$name}/', 'frontoffice-template' => 'templates/frontOffice/{$name}/', diff --git a/vendor/composer/installers/src/Composer/Installers/TuskInstaller.php b/vendor/composer/installers/src/Composer/Installers/TuskInstaller.php index 7c0113b..3b5f142 100644 --- a/vendor/composer/installers/src/Composer/Installers/TuskInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/TuskInstaller.php @@ -1,14 +1,17 @@ - */ - class TuskInstaller extends BaseInstaller - { - protected $locations = array( - 'task' => '.tusk/tasks/{$name}/', - 'command' => '.tusk/commands/{$name}/', - 'asset' => 'assets/tusk/{$name}/', - ); - } + +namespace Composer\Installers; + +/** + * Composer installer for 3rd party Tusk utilities + * @author Drew Ewing + */ +class TuskInstaller extends BaseInstaller +{ + /** @var array */ + protected $locations = array( + 'task' => '.tusk/tasks/{$name}/', + 'command' => '.tusk/commands/{$name}/', + 'asset' => 'assets/tusk/{$name}/', + ); +} diff --git a/vendor/composer/installers/src/Composer/Installers/UserFrostingInstaller.php b/vendor/composer/installers/src/Composer/Installers/UserFrostingInstaller.php index fcb414a..a646c5b 100644 --- a/vendor/composer/installers/src/Composer/Installers/UserFrostingInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/UserFrostingInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'sprinkle' => 'app/sprinkles/{$name}/', ); diff --git a/vendor/composer/installers/src/Composer/Installers/VanillaInstaller.php b/vendor/composer/installers/src/Composer/Installers/VanillaInstaller.php index 24ca645..06d5db3 100644 --- a/vendor/composer/installers/src/Composer/Installers/VanillaInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/VanillaInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'plugin' => 'plugins/{$name}/', 'theme' => 'themes/{$name}/', diff --git a/vendor/composer/installers/src/Composer/Installers/VgmcpInstaller.php b/vendor/composer/installers/src/Composer/Installers/VgmcpInstaller.php index 7d90c5e..cf094dd 100644 --- a/vendor/composer/installers/src/Composer/Installers/VgmcpInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/VgmcpInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'bundle' => 'src/{$vendor}/{$name}/', 'theme' => 'themes/{$name}/' @@ -16,7 +18,7 @@ class VgmcpInstaller extends BaseInstaller * For package type vgmcp-theme, cut off a trailing '-theme' if present. * */ - public function inflectPackageVars($vars) + public function inflectPackageVars(array $vars): array { if ($vars['type'] === 'vgmcp-bundle') { return $this->inflectPluginVars($vars); @@ -29,18 +31,26 @@ public function inflectPackageVars($vars) return $vars; } - protected function inflectPluginVars($vars) + /** + * @param array $vars + * @return array + */ + protected function inflectPluginVars(array $vars): array { - $vars['name'] = preg_replace('/-bundle$/', '', $vars['name']); + $vars['name'] = $this->pregReplace('/-bundle$/', '', $vars['name']); $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); return $vars; } - protected function inflectThemeVars($vars) + /** + * @param array $vars + * @return array + */ + protected function inflectThemeVars(array $vars): array { - $vars['name'] = preg_replace('/-theme$/', '', $vars['name']); + $vars['name'] = $this->pregReplace('/-theme$/', '', $vars['name']); $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); diff --git a/vendor/composer/installers/src/Composer/Installers/WHMCSInstaller.php b/vendor/composer/installers/src/Composer/Installers/WHMCSInstaller.php index b65dbba..91b19fd 100644 --- a/vendor/composer/installers/src/Composer/Installers/WHMCSInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/WHMCSInstaller.php @@ -4,6 +4,7 @@ class WHMCSInstaller extends BaseInstaller { + /** @var array */ protected $locations = array( 'addons' => 'modules/addons/{$vendor}_{$name}/', 'fraud' => 'modules/fraud/{$vendor}_{$name}/', diff --git a/vendor/composer/installers/src/Composer/Installers/WinterInstaller.php b/vendor/composer/installers/src/Composer/Installers/WinterInstaller.php index cff1bf1..f75a681 100644 --- a/vendor/composer/installers/src/Composer/Installers/WinterInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/WinterInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'module' => 'modules/{$name}/', 'plugin' => 'plugins/{$vendor}/{$name}/', @@ -15,9 +17,8 @@ class WinterInstaller extends BaseInstaller * For package type winter-plugin, cut off a trailing '-plugin' if present. * * For package type winter-theme, cut off a trailing '-theme' if present. - * */ - public function inflectPackageVars($vars) + public function inflectPackageVars(array $vars): array { if ($vars['type'] === 'winter-module') { return $this->inflectModuleVars($vars); @@ -34,24 +35,36 @@ public function inflectPackageVars($vars) return $vars; } - protected function inflectModuleVars($vars) + /** + * @param array $vars + * @return array + */ + protected function inflectModuleVars(array $vars): array { - $vars['name'] = preg_replace('/^wn-|-module$/', '', $vars['name']); + $vars['name'] = $this->pregReplace('/^wn-|-module$/', '', $vars['name']); return $vars; } - protected function inflectPluginVars($vars) + /** + * @param array $vars + * @return array + */ + protected function inflectPluginVars(array $vars): array { - $vars['name'] = preg_replace('/^wn-|-plugin$/', '', $vars['name']); - $vars['vendor'] = preg_replace('/[^a-z0-9_]/i', '', $vars['vendor']); + $vars['name'] = $this->pregReplace('/^wn-|-plugin$/', '', $vars['name']); + $vars['vendor'] = $this->pregReplace('/[^a-z0-9_]/i', '', $vars['vendor']); return $vars; } - protected function inflectThemeVars($vars) + /** + * @param array $vars + * @return array + */ + protected function inflectThemeVars(array $vars): array { - $vars['name'] = preg_replace('/^wn-|-theme$/', '', $vars['name']); + $vars['name'] = $this->pregReplace('/^wn-|-theme$/', '', $vars['name']); return $vars; } diff --git a/vendor/composer/installers/src/Composer/Installers/WolfCMSInstaller.php b/vendor/composer/installers/src/Composer/Installers/WolfCMSInstaller.php index cb38788..58a9587 100644 --- a/vendor/composer/installers/src/Composer/Installers/WolfCMSInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/WolfCMSInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'plugin' => 'wolf/plugins/{$name}/', ); diff --git a/vendor/composer/installers/src/Composer/Installers/WordPressInstaller.php b/vendor/composer/installers/src/Composer/Installers/WordPressInstaller.php index 91c46ad..d46d5ab 100644 --- a/vendor/composer/installers/src/Composer/Installers/WordPressInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/WordPressInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'plugin' => 'wp-content/plugins/{$name}/', 'theme' => 'wp-content/themes/{$name}/', diff --git a/vendor/composer/installers/src/Composer/Installers/YawikInstaller.php b/vendor/composer/installers/src/Composer/Installers/YawikInstaller.php index 27f429f..d609dea 100644 --- a/vendor/composer/installers/src/Composer/Installers/YawikInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/YawikInstaller.php @@ -1,32 +1,23 @@ */ protected $locations = array( 'module' => 'module/{$name}/', ); /** * Format package name to CamelCase - * @param array $vars - * - * @return array */ - public function inflectPackageVars($vars) + public function inflectPackageVars(array $vars): array { - $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); + $vars['name'] = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); return $vars; } -} \ No newline at end of file +} diff --git a/vendor/composer/installers/src/Composer/Installers/ZendInstaller.php b/vendor/composer/installers/src/Composer/Installers/ZendInstaller.php index bde9bc8..ccfcd4a 100644 --- a/vendor/composer/installers/src/Composer/Installers/ZendInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/ZendInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'library' => 'library/{$name}/', 'extra' => 'extras/library/{$name}/', diff --git a/vendor/composer/installers/src/Composer/Installers/ZikulaInstaller.php b/vendor/composer/installers/src/Composer/Installers/ZikulaInstaller.php index 56cdf5d..d1fd1d7 100644 --- a/vendor/composer/installers/src/Composer/Installers/ZikulaInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/ZikulaInstaller.php @@ -1,8 +1,10 @@ */ protected $locations = array( 'module' => 'modules/{$vendor}-{$name}/', 'theme' => 'themes/{$vendor}-{$name}/' diff --git a/vendor/composer/installers/src/bootstrap.php b/vendor/composer/installers/src/bootstrap.php index 0de276e..a5bb9ad 100644 --- a/vendor/composer/installers/src/bootstrap.php +++ b/vendor/composer/installers/src/bootstrap.php @@ -1,9 +1,14 @@ + */ +class InvalidRegexPatternRule implements Rule +{ + public function getNodeType(): string + { + return StaticCall::class; + } + + public function processNode(Node $node, Scope $scope): array + { + $patterns = $this->extractPatterns($node, $scope); + + $errors = []; + foreach ($patterns as $pattern) { + $errorMessage = $this->validatePattern($pattern); + if ($errorMessage === null) { + continue; + } + + $errors[] = RuleErrorBuilder::message(sprintf('Regex pattern is invalid: %s', $errorMessage))->identifier('regexp.pattern')->build(); + } + + return $errors; + } + + /** + * @return string[] + */ + private function extractPatterns(StaticCall $node, Scope $scope): array + { + if (!$node->class instanceof FullyQualified) { + return []; + } + $isRegex = $node->class->toString() === Regex::class; + $isPreg = $node->class->toString() === Preg::class; + if (!$isRegex && !$isPreg) { + return []; + } + if (!$node->name instanceof Node\Identifier || !Preg::isMatch('{^(match|isMatch|grep|replace|split)}', $node->name->name)) { + return []; + } + + $functionName = $node->name->name; + if (!isset($node->getArgs()[0])) { + return []; + } + + $patternNode = $node->getArgs()[0]->value; + $patternType = $scope->getType($patternNode); + + $patternStrings = []; + + foreach ($patternType->getConstantStrings() as $constantStringType) { + if ($functionName === 'replaceCallbackArray') { + continue; + } + + $patternStrings[] = $constantStringType->getValue(); + } + + foreach ($patternType->getConstantArrays() as $constantArrayType) { + if ( + in_array($functionName, [ + 'replace', + 'replaceCallback', + ], true) + ) { + foreach ($constantArrayType->getValueTypes() as $arrayKeyType) { + foreach ($arrayKeyType->getConstantStrings() as $constantString) { + $patternStrings[] = $constantString->getValue(); + } + } + } + + if ($functionName !== 'replaceCallbackArray') { + continue; + } + + foreach ($constantArrayType->getKeyTypes() as $arrayKeyType) { + foreach ($arrayKeyType->getConstantStrings() as $constantString) { + $patternStrings[] = $constantString->getValue(); + } + } + } + + return $patternStrings; + } + + private function validatePattern(string $pattern): ?string + { + try { + $msg = null; + $prev = set_error_handler(function (int $severity, string $message, string $file) use (&$msg): bool { + $msg = preg_replace("#^preg_match(_all)?\\(.*?\\): #", '', $message); + + return true; + }); + + if ($pattern === '') { + return 'Empty string is not a valid regular expression'; + } + + Preg::match($pattern, ''); + if ($msg !== null) { + return $msg; + } + } catch (PcreException $e) { + if ($e->getCode() === PREG_INTERNAL_ERROR && $msg !== null) { + return $msg; + } + + return preg_replace('{.*? failed executing ".*": }', '', $e->getMessage()); + } finally { + restore_error_handler(); + } + + return null; + } + +} diff --git a/vendor/composer/pcre/src/PHPStan/PregMatchFlags.php b/vendor/composer/pcre/src/PHPStan/PregMatchFlags.php new file mode 100644 index 0000000..aa30ab3 --- /dev/null +++ b/vendor/composer/pcre/src/PHPStan/PregMatchFlags.php @@ -0,0 +1,70 @@ +getType($flagsArg->value); + + $constantScalars = $flagsType->getConstantScalarValues(); + if ($constantScalars === []) { + return null; + } + + $internalFlagsTypes = []; + foreach ($flagsType->getConstantScalarValues() as $constantScalarValue) { + if (!is_int($constantScalarValue)) { + return null; + } + + $internalFlagsTypes[] = new ConstantIntegerType($constantScalarValue | PREG_UNMATCHED_AS_NULL); + } + return TypeCombinator::union(...$internalFlagsTypes); + } + + static public function removeNullFromMatches(Type $matchesType): Type + { + return TypeTraverser::map($matchesType, static function (Type $type, callable $traverse): Type { + if ($type instanceof UnionType || $type instanceof IntersectionType) { + return $traverse($type); + } + + if ($type instanceof ConstantArrayType) { + return new ConstantArrayType( + $type->getKeyTypes(), + array_map(static function (Type $valueType) use ($traverse): Type { + return $traverse($valueType); + }, $type->getValueTypes()), + $type->getNextAutoIndexes(), + [], + $type->isList() + ); + } + + if ($type instanceof ArrayType) { + return new ArrayType($type->getKeyType(), $traverse($type->getItemType())); + } + + return TypeCombinator::removeNull($type); + }); + } + +} diff --git a/vendor/composer/pcre/src/PHPStan/PregMatchParameterOutTypeExtension.php b/vendor/composer/pcre/src/PHPStan/PregMatchParameterOutTypeExtension.php new file mode 100644 index 0000000..e0d6020 --- /dev/null +++ b/vendor/composer/pcre/src/PHPStan/PregMatchParameterOutTypeExtension.php @@ -0,0 +1,65 @@ +regexShapeMatcher = $regexShapeMatcher; + } + + public function isStaticMethodSupported(MethodReflection $methodReflection, ParameterReflection $parameter): bool + { + return + $methodReflection->getDeclaringClass()->getName() === Preg::class + && in_array($methodReflection->getName(), [ + 'match', 'isMatch', 'matchStrictGroups', 'isMatchStrictGroups', + 'matchAll', 'isMatchAll', 'matchAllStrictGroups', 'isMatchAllStrictGroups' + ], true) + && $parameter->getName() === 'matches'; + } + + public function getParameterOutTypeFromStaticMethodCall(MethodReflection $methodReflection, StaticCall $methodCall, ParameterReflection $parameter, Scope $scope): ?Type + { + $args = $methodCall->getArgs(); + $patternArg = $args[0] ?? null; + $matchesArg = $args[2] ?? null; + $flagsArg = $args[3] ?? null; + + if ( + $patternArg === null || $matchesArg === null + ) { + return null; + } + + $flagsType = PregMatchFlags::getType($flagsArg, $scope); + if ($flagsType === null) { + return null; + } + + if (stripos($methodReflection->getName(), 'matchAll') !== false) { + return $this->regexShapeMatcher->matchAllExpr($patternArg->value, $flagsType, TrinaryLogic::createMaybe(), $scope); + } + + return $this->regexShapeMatcher->matchExpr($patternArg->value, $flagsType, TrinaryLogic::createMaybe(), $scope); + } + +} diff --git a/vendor/composer/pcre/src/PHPStan/PregMatchTypeSpecifyingExtension.php b/vendor/composer/pcre/src/PHPStan/PregMatchTypeSpecifyingExtension.php new file mode 100644 index 0000000..cf22f60 --- /dev/null +++ b/vendor/composer/pcre/src/PHPStan/PregMatchTypeSpecifyingExtension.php @@ -0,0 +1,105 @@ +regexShapeMatcher = $regexShapeMatcher; + } + + public function setTypeSpecifier(TypeSpecifier $typeSpecifier): void + { + $this->typeSpecifier = $typeSpecifier; + } + + public function getClass(): string + { + return Preg::class; + } + + public function isStaticMethodSupported(MethodReflection $methodReflection, StaticCall $node, TypeSpecifierContext $context): bool + { + return in_array($methodReflection->getName(), [ + 'match', 'isMatch', 'matchStrictGroups', 'isMatchStrictGroups', + 'matchAll', 'isMatchAll', 'matchAllStrictGroups', 'isMatchAllStrictGroups' + ], true) + && !$context->null(); + } + + public function specifyTypes(MethodReflection $methodReflection, StaticCall $node, Scope $scope, TypeSpecifierContext $context): SpecifiedTypes + { + $args = $node->getArgs(); + $patternArg = $args[0] ?? null; + $matchesArg = $args[2] ?? null; + $flagsArg = $args[3] ?? null; + + if ( + $patternArg === null || $matchesArg === null + ) { + return new SpecifiedTypes(); + } + + $flagsType = PregMatchFlags::getType($flagsArg, $scope); + if ($flagsType === null) { + return new SpecifiedTypes(); + } + + if (stripos($methodReflection->getName(), 'matchAll') !== false) { + $matchedType = $this->regexShapeMatcher->matchAllExpr($patternArg->value, $flagsType, TrinaryLogic::createFromBoolean($context->true()), $scope); + } else { + $matchedType = $this->regexShapeMatcher->matchExpr($patternArg->value, $flagsType, TrinaryLogic::createFromBoolean($context->true()), $scope); + } + + if ($matchedType === null) { + return new SpecifiedTypes(); + } + + if ( + in_array($methodReflection->getName(), ['matchStrictGroups', 'isMatchStrictGroups', 'matchAllStrictGroups', 'isMatchAllStrictGroups'], true) + ) { + $matchedType = PregMatchFlags::removeNullFromMatches($matchedType); + } + + $overwrite = false; + if ($context->false()) { + $overwrite = true; + $context = $context->negate(); + } + + return $this->typeSpecifier->create( + $matchesArg->value, + $matchedType, + $context, + $overwrite, + $scope, + $node + ); + } +} diff --git a/vendor/composer/pcre/src/PHPStan/PregReplaceCallbackClosureTypeExtension.php b/vendor/composer/pcre/src/PHPStan/PregReplaceCallbackClosureTypeExtension.php new file mode 100644 index 0000000..7b95367 --- /dev/null +++ b/vendor/composer/pcre/src/PHPStan/PregReplaceCallbackClosureTypeExtension.php @@ -0,0 +1,91 @@ +regexShapeMatcher = $regexShapeMatcher; + } + + public function isStaticMethodSupported(MethodReflection $methodReflection, ParameterReflection $parameter): bool + { + return in_array($methodReflection->getDeclaringClass()->getName(), [Preg::class, Regex::class], true) + && in_array($methodReflection->getName(), ['replaceCallback', 'replaceCallbackStrictGroups'], true) + && $parameter->getName() === 'replacement'; + } + + public function getTypeFromStaticMethodCall(MethodReflection $methodReflection, StaticCall $methodCall, ParameterReflection $parameter, Scope $scope): ?Type + { + $args = $methodCall->getArgs(); + $patternArg = $args[0] ?? null; + $flagsArg = $args[5] ?? null; + + if ( + $patternArg === null + ) { + return null; + } + + $flagsType = PregMatchFlags::getType($flagsArg, $scope); + + $matchesType = $this->regexShapeMatcher->matchExpr($patternArg->value, $flagsType, TrinaryLogic::createYes(), $scope); + if ($matchesType === null) { + return null; + } + + if ($methodReflection->getName() === 'replaceCallbackStrictGroups' && count($matchesType->getConstantArrays()) === 1) { + $matchesType = $matchesType->getConstantArrays()[0]; + $matchesType = new ConstantArrayType( + $matchesType->getKeyTypes(), + array_map(static function (Type $valueType): Type { + if (count($valueType->getConstantArrays()) === 1) { + $valueTypeArray = $valueType->getConstantArrays()[0]; + return new ConstantArrayType( + $valueTypeArray->getKeyTypes(), + array_map(static function (Type $valueType): Type { + return TypeCombinator::removeNull($valueType); + }, $valueTypeArray->getValueTypes()), + $valueTypeArray->getNextAutoIndexes(), + [], + $valueTypeArray->isList() + ); + } + return TypeCombinator::removeNull($valueType); + }, $matchesType->getValueTypes()), + $matchesType->getNextAutoIndexes(), + [], + $matchesType->isList() + ); + } + + return new ClosureType( + [ + new NativeParameterReflection($parameter->getName(), $parameter->isOptional(), $matchesType, $parameter->passedByReference(), $parameter->isVariadic(), $parameter->getDefaultValue()), + ], + new StringType() + ); + } +} diff --git a/vendor/composer/pcre/src/PHPStan/UnsafeStrictGroupsCallRule.php b/vendor/composer/pcre/src/PHPStan/UnsafeStrictGroupsCallRule.php new file mode 100644 index 0000000..5bced50 --- /dev/null +++ b/vendor/composer/pcre/src/PHPStan/UnsafeStrictGroupsCallRule.php @@ -0,0 +1,112 @@ + + */ +final class UnsafeStrictGroupsCallRule implements Rule +{ + /** + * @var RegexArrayShapeMatcher + */ + private $regexShapeMatcher; + + public function __construct(RegexArrayShapeMatcher $regexShapeMatcher) + { + $this->regexShapeMatcher = $regexShapeMatcher; + } + + public function getNodeType(): string + { + return StaticCall::class; + } + + public function processNode(Node $node, Scope $scope): array + { + if (!$node->class instanceof FullyQualified) { + return []; + } + $isRegex = $node->class->toString() === Regex::class; + $isPreg = $node->class->toString() === Preg::class; + if (!$isRegex && !$isPreg) { + return []; + } + if (!$node->name instanceof Node\Identifier || !in_array($node->name->name, ['matchStrictGroups', 'isMatchStrictGroups', 'matchAllStrictGroups', 'isMatchAllStrictGroups'], true)) { + return []; + } + + $args = $node->getArgs(); + if (!isset($args[0])) { + return []; + } + + $patternArg = $args[0] ?? null; + if ($isPreg) { + if (!isset($args[2])) { // no matches set, skip as the matches won't be used anyway + return []; + } + $flagsArg = $args[3] ?? null; + } else { + $flagsArg = $args[2] ?? null; + } + + if ($patternArg === null) { + return []; + } + + $flagsType = PregMatchFlags::getType($flagsArg, $scope); + if ($flagsType === null) { + return []; + } + + $matchedType = $this->regexShapeMatcher->matchExpr($patternArg->value, $flagsType, TrinaryLogic::createYes(), $scope); + if ($matchedType === null) { + return [ + RuleErrorBuilder::message(sprintf('The %s call is potentially unsafe as $matches\' type could not be inferred.', $node->name->name)) + ->identifier('composerPcre.maybeUnsafeStrictGroups') + ->build(), + ]; + } + + if (count($matchedType->getConstantArrays()) === 1) { + $matchedType = $matchedType->getConstantArrays()[0]; + $nullableGroups = []; + foreach ($matchedType->getValueTypes() as $index => $type) { + if (TypeCombinator::containsNull($type)) { + $nullableGroups[] = $matchedType->getKeyTypes()[$index]->getValue(); + } + } + + if (\count($nullableGroups) > 0) { + return [ + RuleErrorBuilder::message(sprintf( + 'The %s call is unsafe as match group%s "%s" %s optional and may be null.', + $node->name->name, + \count($nullableGroups) > 1 ? 's' : '', + implode('", "', $nullableGroups), + \count($nullableGroups) > 1 ? 'are' : 'is' + ))->identifier('composerPcre.unsafeStrictGroups')->build(), + ]; + } + } + + return []; + } +} diff --git a/vendor/composer/pcre/src/Preg.php b/vendor/composer/pcre/src/Preg.php index 2f54a99..400abbf 100644 --- a/vendor/composer/pcre/src/Preg.php +++ b/vendor/composer/pcre/src/Preg.php @@ -203,7 +203,7 @@ public static function replaceCallback($pattern, callable $replacement, $subject * * @param-out int<0, max> $count */ - public static function replaceCallbackStrictGroups(string $pattern, callable $replacement, $subject, int $limit = -1, int &$count = null, int $flags = 0): string + public static function replaceCallbackStrictGroups(string $pattern, callable $replacement, $subject, int $limit = -1, ?int &$count = null, int $flags = 0): string { return self::replaceCallback($pattern, function (array $matches) use ($pattern, $replacement) { return $replacement(self::enforceNonNullMatches($pattern, $matches, 'replaceCallback')); diff --git a/vendor/composer/pcre/src/Regex.php b/vendor/composer/pcre/src/Regex.php index 21564a4..038cf06 100644 --- a/vendor/composer/pcre/src/Regex.php +++ b/vendor/composer/pcre/src/Regex.php @@ -43,6 +43,7 @@ public static function match(string $pattern, string $subject, int $flags = 0, i */ public static function matchStrictGroups(string $pattern, string $subject, int $flags = 0, int $offset = 0): MatchStrictGroupsResult { + // @phpstan-ignore composerPcre.maybeUnsafeStrictGroups $count = Preg::matchStrictGroups($pattern, $subject, $matches, $flags, $offset); return new MatchStrictGroupsResult($count, $matches); @@ -87,6 +88,7 @@ public static function matchAllStrictGroups(string $pattern, string $subject, in self::checkOffsetCapture($flags, 'matchAllWithOffsets'); self::checkSetOrder($flags); + // @phpstan-ignore composerPcre.maybeUnsafeStrictGroups $count = Preg::matchAllStrictGroups($pattern, $subject, $matches, $flags, $offset); return new MatchAllStrictGroupsResult($count, $matches); diff --git a/vendor/composer/platform_check.php b/vendor/composer/platform_check.php index 4c3a5d6..d32d90c 100644 --- a/vendor/composer/platform_check.php +++ b/vendor/composer/platform_check.php @@ -4,8 +4,8 @@ $issues = array(); -if (!(PHP_VERSION_ID >= 80100)) { - $issues[] = 'Your Composer dependencies require a PHP version ">= 8.1.0". You are running ' . PHP_VERSION . '.'; +if (!(PHP_VERSION_ID >= 80200)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 8.2.0". You are running ' . PHP_VERSION . '.'; } if ($issues) { diff --git a/vendor/composer/semver/CHANGELOG.md b/vendor/composer/semver/CHANGELOG.md index 3b11161..bad46cd 100644 --- a/vendor/composer/semver/CHANGELOG.md +++ b/vendor/composer/semver/CHANGELOG.md @@ -3,6 +3,18 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +### [3.4.3] 2024-09-19 + + * Fixed some type annotations + +### [3.4.2] 2024-07-12 + + * Fixed PHP 5.3 syntax error + +### [3.4.1] 2024-07-12 + + * Fixed normalizeStability's return type to enforce valid stabilities + ### [3.4.0] 2023-08-31 * Support larger major version numbers (#149) @@ -179,6 +191,9 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Namespace: `Composer\Test\Package\LinkConstraint` -> `Composer\Test\Semver\Constraint` * Changed: code style using php-cs-fixer. +[3.4.3]: https://github.com/composer/semver/compare/3.4.2...3.4.3 +[3.4.2]: https://github.com/composer/semver/compare/3.4.1...3.4.2 +[3.4.1]: https://github.com/composer/semver/compare/3.4.0...3.4.1 [3.4.0]: https://github.com/composer/semver/compare/3.3.2...3.4.0 [3.3.2]: https://github.com/composer/semver/compare/3.3.1...3.3.2 [3.3.1]: https://github.com/composer/semver/compare/3.3.0...3.3.1 diff --git a/vendor/composer/semver/composer.json b/vendor/composer/semver/composer.json index f3a6f4c..1fad9e5 100644 --- a/vendor/composer/semver/composer.json +++ b/vendor/composer/semver/composer.json @@ -34,8 +34,8 @@ "php": "^5.3.2 || ^7.0 || ^8.0" }, "require-dev": { - "symfony/phpunit-bridge": "^4.2 || ^5", - "phpstan/phpstan": "^1.4" + "symfony/phpunit-bridge": "^3 || ^7", + "phpstan/phpstan": "^1.11" }, "autoload": { "psr-4": { diff --git a/vendor/composer/semver/phpstan-baseline.neon b/vendor/composer/semver/phpstan-baseline.neon deleted file mode 100644 index 933cf20..0000000 --- a/vendor/composer/semver/phpstan-baseline.neon +++ /dev/null @@ -1,11 +0,0 @@ -parameters: - ignoreErrors: - - - message: "#^Parameter \\#1 \\$operator of class Composer\\\\Semver\\\\Constraint\\\\Constraint constructor expects '\\!\\='\\|'\\<'\\|'\\<\\='\\|'\\<\\>'\\|'\\='\\|'\\=\\='\\|'\\>'\\|'\\>\\=', non\\-falsy\\-string given\\.$#" - count: 1 - path: src/VersionParser.php - - - - message: "#^Strict comparison using \\=\\=\\= between null and non\\-empty\\-string will always evaluate to false\\.$#" - count: 2 - path: src/VersionParser.php diff --git a/vendor/composer/semver/src/CompilingMatcher.php b/vendor/composer/semver/src/CompilingMatcher.php index 45bce70..aea1d3b 100644 --- a/vendor/composer/semver/src/CompilingMatcher.php +++ b/vendor/composer/semver/src/CompilingMatcher.php @@ -64,7 +64,7 @@ public static function clear() * @phpstan-param Constraint::OP_* $operator * @param string $version * - * @return mixed + * @return bool */ public static function match(ConstraintInterface $constraint, $operator, $version) { diff --git a/vendor/composer/semver/src/VersionParser.php b/vendor/composer/semver/src/VersionParser.php index 9318629..305a0fa 100644 --- a/vendor/composer/semver/src/VersionParser.php +++ b/vendor/composer/semver/src/VersionParser.php @@ -82,11 +82,16 @@ public static function parseStability($version) * @param string $stability * * @return string + * @phpstan-return 'stable'|'RC'|'beta'|'alpha'|'dev' */ public static function normalizeStability($stability) { $stability = strtolower((string) $stability); + if (!in_array($stability, array('stable', 'rc', 'beta', 'alpha', 'dev'), true)) { + throw new \InvalidArgumentException('Invalid stability string "'.$stability.'", expected one of stable, RC, beta, alpha or dev'); + } + return $stability === 'rc' ? 'RC' : $stability; } diff --git a/vendor/composer/xdebug-handler/CHANGELOG.md b/vendor/composer/xdebug-handler/CHANGELOG.md index 49fdc45..62ebe22 100644 --- a/vendor/composer/xdebug-handler/CHANGELOG.md +++ b/vendor/composer/xdebug-handler/CHANGELOG.md @@ -1,5 +1,8 @@ ## [Unreleased] +## [3.0.5] - 2024-05-06 + * Fixed: fail restart if PHP_BINARY is not available + ## [3.0.4] - 2024-03-26 * Added: Functional tests. * Fixed: Incompatibility with PHPUnit 10. @@ -112,9 +115,10 @@ * Break: the following class was renamed: - `Composer\XdebugHandler` -> `Composer\XdebugHandler\XdebugHandler` -[Unreleased]: https://github.com/composer/xdebug-handler/compare/3.0.4...HEAD -[3.0.3]: https://github.com/composer/xdebug-handler/compare/3.0.3...3.0.4 -[3.0.2]: https://github.com/composer/xdebug-handler/compare/3.0.2...3.0.3 +[Unreleased]: https://github.com/composer/xdebug-handler/compare/3.0.5...HEAD +[3.0.5]: https://github.com/composer/xdebug-handler/compare/3.0.4...3.0.5 +[3.0.4]: https://github.com/composer/xdebug-handler/compare/3.0.3...3.0.4 +[3.0.3]: https://github.com/composer/xdebug-handler/compare/3.0.2...3.0.3 [3.0.2]: https://github.com/composer/xdebug-handler/compare/3.0.1...3.0.2 [3.0.1]: https://github.com/composer/xdebug-handler/compare/3.0.0...3.0.1 [3.0.0]: https://github.com/composer/xdebug-handler/compare/2.0.3...3.0.0 diff --git a/vendor/composer/xdebug-handler/src/XdebugHandler.php b/vendor/composer/xdebug-handler/src/XdebugHandler.php index 37fc313..a665939 100644 --- a/vendor/composer/xdebug-handler/src/XdebugHandler.php +++ b/vendor/composer/xdebug-handler/src/XdebugHandler.php @@ -590,6 +590,11 @@ private function checkConfiguration(?string &$info): bool return false; } + if (!file_exists(PHP_BINARY)) { + $info = 'PHP_BINARY is not available'; + return false; + } + if (extension_loaded('uopz') && !((bool) ini_get('uopz.disable'))) { // uopz works at opcode level and disables exit calls if (function_exists('uopz_allow_exit')) { diff --git a/vendor/justinrainbow/json-schema/bin/validate-json b/vendor/justinrainbow/json-schema/bin/validate-json old mode 100644 new mode 100755 diff --git a/vendor/justinrainbow/json-schema/composer.json b/vendor/justinrainbow/json-schema/composer.json index fcacd40..8c32267 100644 --- a/vendor/justinrainbow/json-schema/composer.json +++ b/vendor/justinrainbow/json-schema/composer.json @@ -27,18 +27,13 @@ } ], "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "require-dev": { "friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1", "json-schema/json-schema-test-suite": "1.2.0", "phpunit/phpunit": "^4.8.35" }, - "extra": { - "branch-alias": { - "dev-master": "5.0.x-dev" - } - }, "autoload": { "psr-4": { "JsonSchema\\": "src/JsonSchema/" @@ -67,10 +62,10 @@ "bin/validate-json" ], "scripts": { - "coverage": "phpunit --coverage-text", - "style-check": "php-cs-fixer fix --dry-run --verbose --diff", - "style-fix": "php-cs-fixer fix --verbose", - "test": "phpunit", - "testOnly": "phpunit --colors --filter" + "coverage": "@php phpunit --coverage-text", + "style-check": "@php php-cs-fixer fix --dry-run --verbose --diff", + "style-fix": "@php php-cs-fixer fix --verbose", + "test": "@php phpunit", + "testOnly": "@php phpunit --colors --filter" } } diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/BaseConstraint.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/BaseConstraint.php index 6396821..9a4ea1e 100644 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/BaseConstraint.php +++ b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/BaseConstraint.php @@ -38,12 +38,12 @@ class BaseConstraint /** * @param Factory $factory */ - public function __construct(Factory $factory = null) + public function __construct(?Factory $factory = null) { $this->factory = $factory ?: new Factory(); } - public function addError(JsonPointer $path = null, $message, $constraint = '', array $more = null) + public function addError(?JsonPointer $path, $message, $constraint = '', ?array $more = null) { $error = array( 'property' => $this->convertJsonPointerIntoPropertyPath($path ?: new JsonPointer('')), diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/CollectionConstraint.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/CollectionConstraint.php index d1384b8..a5ddd35 100644 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/CollectionConstraint.php +++ b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/CollectionConstraint.php @@ -22,7 +22,7 @@ class CollectionConstraint extends Constraint /** * {@inheritdoc} */ - public function check(&$value, $schema = null, JsonPointer $path = null, $i = null) + public function check(&$value, $schema = null, ?JsonPointer $path = null, $i = null) { // Verify minItems if (isset($schema->minItems) && count($value) < $schema->minItems) { @@ -61,7 +61,7 @@ public function check(&$value, $schema = null, JsonPointer $path = null, $i = nu * @param JsonPointer|null $path * @param string $i */ - protected function validateItems(&$value, $schema = null, JsonPointer $path = null, $i = null) + protected function validateItems(&$value, $schema = null, ?JsonPointer $path = null, $i = null) { if (is_object($schema->items)) { // just one type definition for the whole array diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Constraint.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Constraint.php index c61b89a..5aaa718 100644 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Constraint.php +++ b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Constraint.php @@ -39,7 +39,7 @@ abstract class Constraint extends BaseConstraint implements ConstraintInterface * * @return JsonPointer; */ - protected function incrementPath(JsonPointer $path = null, $i) + protected function incrementPath(?JsonPointer $path, $i) { $path = $path ?: new JsonPointer(''); @@ -65,7 +65,7 @@ protected function incrementPath(JsonPointer $path = null, $i) * @param JsonPointer|null $path * @param mixed $i */ - protected function checkArray(&$value, $schema = null, JsonPointer $path = null, $i = null) + protected function checkArray(&$value, $schema = null, ?JsonPointer $path = null, $i = null) { $validator = $this->factory->createInstanceFor('collection'); $validator->check($value, $schema, $path, $i); @@ -83,7 +83,7 @@ protected function checkArray(&$value, $schema = null, JsonPointer $path = null, * @param mixed $additionalProperties * @param mixed $patternProperties */ - protected function checkObject(&$value, $schema = null, JsonPointer $path = null, $properties = null, + protected function checkObject(&$value, $schema = null, ?JsonPointer $path = null, $properties = null, $additionalProperties = null, $patternProperties = null, $appliedDefaults = array()) { $validator = $this->factory->createInstanceFor('object'); @@ -100,7 +100,7 @@ protected function checkObject(&$value, $schema = null, JsonPointer $path = null * @param JsonPointer|null $path * @param mixed $i */ - protected function checkType(&$value, $schema = null, JsonPointer $path = null, $i = null) + protected function checkType(&$value, $schema = null, ?JsonPointer $path = null, $i = null) { $validator = $this->factory->createInstanceFor('type'); $validator->check($value, $schema, $path, $i); @@ -116,7 +116,7 @@ protected function checkType(&$value, $schema = null, JsonPointer $path = null, * @param JsonPointer|null $path * @param mixed $i */ - protected function checkUndefined(&$value, $schema = null, JsonPointer $path = null, $i = null, $fromDefault = false) + protected function checkUndefined(&$value, $schema = null, ?JsonPointer $path = null, $i = null, $fromDefault = false) { $validator = $this->factory->createInstanceFor('undefined'); @@ -133,7 +133,7 @@ protected function checkUndefined(&$value, $schema = null, JsonPointer $path = n * @param JsonPointer|null $path * @param mixed $i */ - protected function checkString($value, $schema = null, JsonPointer $path = null, $i = null) + protected function checkString($value, $schema = null, ?JsonPointer $path = null, $i = null) { $validator = $this->factory->createInstanceFor('string'); $validator->check($value, $schema, $path, $i); @@ -149,7 +149,7 @@ protected function checkString($value, $schema = null, JsonPointer $path = null, * @param JsonPointer $path * @param mixed $i */ - protected function checkNumber($value, $schema = null, JsonPointer $path = null, $i = null) + protected function checkNumber($value, $schema = null, ?JsonPointer $path = null, $i = null) { $validator = $this->factory->createInstanceFor('number'); $validator->check($value, $schema, $path, $i); @@ -165,7 +165,7 @@ protected function checkNumber($value, $schema = null, JsonPointer $path = null, * @param JsonPointer|null $path * @param mixed $i */ - protected function checkEnum($value, $schema = null, JsonPointer $path = null, $i = null) + protected function checkEnum($value, $schema = null, ?JsonPointer $path = null, $i = null) { $validator = $this->factory->createInstanceFor('enum'); $validator->check($value, $schema, $path, $i); @@ -181,7 +181,7 @@ protected function checkEnum($value, $schema = null, JsonPointer $path = null, $ * @param JsonPointer|null $path * @param mixed $i */ - protected function checkFormat($value, $schema = null, JsonPointer $path = null, $i = null) + protected function checkFormat($value, $schema = null, ?JsonPointer $path = null, $i = null) { $validator = $this->factory->createInstanceFor('format'); $validator->check($value, $schema, $path, $i); diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/ConstraintInterface.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/ConstraintInterface.php index 442268e..a5a235a 100644 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/ConstraintInterface.php +++ b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/ConstraintInterface.php @@ -40,7 +40,7 @@ public function addErrors(array $errors); * @param string $constraint the constraint/rule that is broken, e.g.: 'minLength' * @param array $more more array elements to add to the error */ - public function addError(JsonPointer $path = null, $message, $constraint='', array $more = null); + public function addError(?JsonPointer $path, $message, $constraint='', ?array $more = null); /** * checks if the validator has not raised errors @@ -61,5 +61,5 @@ public function isValid(); * * @throws \JsonSchema\Exception\ExceptionInterface */ - public function check(&$value, $schema = null, JsonPointer $path = null, $i = null); + public function check(&$value, $schema = null, ?JsonPointer $path = null, $i = null); } diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/EnumConstraint.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/EnumConstraint.php index 0fd2b6a..da61c13 100644 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/EnumConstraint.php +++ b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/EnumConstraint.php @@ -22,7 +22,7 @@ class EnumConstraint extends Constraint /** * {@inheritdoc} */ - public function check(&$element, $schema = null, JsonPointer $path = null, $i = null) + public function check(&$element, $schema = null, ?JsonPointer $path = null, $i = null) { // Only validate enum if the attribute exists if ($element instanceof UndefinedConstraint && (!isset($schema->required) || !$schema->required)) { diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Factory.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Factory.php index 4e771c1..840854b 100644 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Factory.php +++ b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Factory.php @@ -74,8 +74,8 @@ class Factory * @param int $checkMode */ public function __construct( - SchemaStorageInterface $schemaStorage = null, - UriRetrieverInterface $uriRetriever = null, + ?SchemaStorageInterface $schemaStorage = null, + ?UriRetrieverInterface $uriRetriever = null, $checkMode = Constraint::CHECK_MODE_NORMAL ) { // set provided config options diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/FormatConstraint.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/FormatConstraint.php index 578cdb1..29843e6 100644 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/FormatConstraint.php +++ b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/FormatConstraint.php @@ -24,7 +24,7 @@ class FormatConstraint extends Constraint /** * {@inheritdoc} */ - public function check(&$element, $schema = null, JsonPointer $path = null, $i = null) + public function check(&$element, $schema = null, ?JsonPointer $path = null, $i = null) { if (!isset($schema->format) || $this->factory->getConfig(self::CHECK_MODE_DISABLE_FORMAT)) { return; diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/NumberConstraint.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/NumberConstraint.php index d4c31a4..b2ade8e 100644 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/NumberConstraint.php +++ b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/NumberConstraint.php @@ -22,7 +22,7 @@ class NumberConstraint extends Constraint /** * {@inheritdoc} */ - public function check(&$element, $schema = null, JsonPointer $path = null, $i = null) + public function check(&$element, $schema = null, ?JsonPointer $path = null, $i = null) { // Verify minimum if (isset($schema->exclusiveMinimum)) { diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/ObjectConstraint.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/ObjectConstraint.php index 0010d29..e99c44b 100644 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/ObjectConstraint.php +++ b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/ObjectConstraint.php @@ -27,7 +27,7 @@ class ObjectConstraint extends Constraint /** * {@inheritdoc} */ - public function check(&$element, $schema = null, JsonPointer $path = null, $properties = null, + public function check(&$element, $schema = null, ?JsonPointer $path = null, $properties = null, $additionalProp = null, $patternProperties = null, $appliedDefaults = array()) { if ($element instanceof UndefinedConstraint) { @@ -51,7 +51,7 @@ public function check(&$element, $schema = null, JsonPointer $path = null, $prop $this->validateElement($element, $matches, $schema, $path, $properties, $additionalProp); } - public function validatePatternProperties($element, JsonPointer $path = null, $patternProperties) + public function validatePatternProperties($element, ?JsonPointer $path, $patternProperties) { $try = array('/', '#', '+', '~', '%'); $matches = array(); @@ -90,7 +90,7 @@ public function validatePatternProperties($element, JsonPointer $path = null, $p * @param \StdClass $properties Properties * @param mixed $additionalProp Additional properties */ - public function validateElement($element, $matches, $schema = null, JsonPointer $path = null, + public function validateElement($element, $matches, $schema = null, ?JsonPointer $path = null, $properties = null, $additionalProp = null) { $this->validateMinMaxConstraint($element, $schema, $path); @@ -132,7 +132,7 @@ public function validateElement($element, $matches, $schema = null, JsonPointer * @param \stdClass $properties Property definitions * @param JsonPointer|null $path Path? */ - public function validateProperties(&$element, $properties = null, JsonPointer $path = null) + public function validateProperties(&$element, $properties = null, ?JsonPointer $path = null) { $undefinedConstraint = $this->factory->createInstanceFor('undefined'); @@ -174,7 +174,7 @@ protected function &getProperty(&$element, $property, $fallback = null) * @param \stdClass $objectDefinition ObjectConstraint definition * @param JsonPointer|null $path Path to test? */ - protected function validateMinMaxConstraint($element, $objectDefinition, JsonPointer $path = null) + protected function validateMinMaxConstraint($element, $objectDefinition, ?JsonPointer $path = null) { // Verify minimum number of properties if (isset($objectDefinition->minProperties) && !is_object($objectDefinition->minProperties)) { diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/SchemaConstraint.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/SchemaConstraint.php index db665ad..74979eb 100644 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/SchemaConstraint.php +++ b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/SchemaConstraint.php @@ -28,7 +28,7 @@ class SchemaConstraint extends Constraint /** * {@inheritdoc} */ - public function check(&$element, $schema = null, JsonPointer $path = null, $i = null) + public function check(&$element, $schema = null, ?JsonPointer $path = null, $i = null) { if ($schema !== null) { // passed schema diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/StringConstraint.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/StringConstraint.php index c66af1e..d6189ce 100644 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/StringConstraint.php +++ b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/StringConstraint.php @@ -22,7 +22,7 @@ class StringConstraint extends Constraint /** * {@inheritdoc} */ - public function check(&$element, $schema = null, JsonPointer $path = null, $i = null) + public function check(&$element, $schema = null, ?JsonPointer $path = null, $i = null) { // Verify maxLength if (isset($schema->maxLength) && $this->strlen($element) > $schema->maxLength) { diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeConstraint.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeConstraint.php index efc0abb..9940fd5 100644 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeConstraint.php +++ b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeConstraint.php @@ -39,7 +39,7 @@ class TypeConstraint extends Constraint /** * {@inheritdoc} */ - public function check(&$value = null, $schema = null, JsonPointer $path = null, $i = null) + public function check(&$value = null, $schema = null, ?JsonPointer $path = null, $i = null) { $type = isset($schema->type) ? $schema->type : null; $isValid = false; diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/UndefinedConstraint.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/UndefinedConstraint.php index 1e984a3..26e45f7 100644 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/UndefinedConstraint.php +++ b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/UndefinedConstraint.php @@ -31,7 +31,7 @@ class UndefinedConstraint extends Constraint /** * {@inheritdoc} */ - public function check(&$value, $schema = null, JsonPointer $path = null, $i = null, $fromDefault = false) + public function check(&$value, $schema = null, ?JsonPointer $path = null, $i = null, $fromDefault = false) { if (is_null($schema) || !is_object($schema)) { return; diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Exception/JsonDecodingException.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Exception/JsonDecodingException.php index c771982..7641f61 100644 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Exception/JsonDecodingException.php +++ b/vendor/justinrainbow/json-schema/src/JsonSchema/Exception/JsonDecodingException.php @@ -14,7 +14,7 @@ */ class JsonDecodingException extends RuntimeException { - public function __construct($code = JSON_ERROR_NONE, \Exception $previous = null) + public function __construct($code = JSON_ERROR_NONE, ?\Exception $previous = null) { switch ($code) { case JSON_ERROR_DEPTH: diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/SchemaStorage.php b/vendor/justinrainbow/json-schema/src/JsonSchema/SchemaStorage.php index 31da668..36ba349 100644 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/SchemaStorage.php +++ b/vendor/justinrainbow/json-schema/src/JsonSchema/SchemaStorage.php @@ -17,8 +17,8 @@ class SchemaStorage implements SchemaStorageInterface protected $schemas = array(); public function __construct( - UriRetrieverInterface $uriRetriever = null, - UriResolverInterface $uriResolver = null + ?UriRetrieverInterface $uriRetriever = null, + ?UriResolverInterface $uriResolver = null ) { $this->uriRetriever = $uriRetriever ?: new UriRetriever(); $this->uriResolver = $uriResolver ?: new UriResolver(); diff --git a/vendor/oyejorge/less.php/.gitattributes b/vendor/oyejorge/less.php/.gitattributes deleted file mode 100644 index 8a678ca..0000000 --- a/vendor/oyejorge/less.php/.gitattributes +++ /dev/null @@ -1,3 +0,0 @@ -test/ export-ignore -.travis.yml export-ignore -phpunit.xml export-ignore diff --git a/vendor/oyejorge/less.php/.gitignore b/vendor/oyejorge/less.php/.gitignore deleted file mode 100644 index 8734cb1..0000000 --- a/vendor/oyejorge/less.php/.gitignore +++ /dev/null @@ -1,14 +0,0 @@ -.buildpath -.project -.settings -.idea -.DS_Store? -ehthumbs.db -Icon? -Thumbs.db -*.komodoproject -composer.lock -vendor/ -x_* -X_* -_* \ No newline at end of file diff --git a/vendor/oyejorge/less.php/CHANGES.md b/vendor/oyejorge/less.php/CHANGES.md deleted file mode 100644 index cdcd965..0000000 --- a/vendor/oyejorge/less.php/CHANGES.md +++ /dev/null @@ -1,31 +0,0 @@ -# 1.7.0.13 - - [All Changes](https://github.com/Asenar/less.php/compare/v1.7.0.12...v1.7.0.13) - - Fix composer.json (PSR-4 was invalid) - -# 1.7.0.12 - - [All Changes](https://github.com/Asenar/less.php/compare/v1.7.0.11...v1.7.0.12) - - set bin/lessc bit executable - - Add 'gettingVariables' method in Less_Parser - -# 1.7.0.11 - - [All Changes](https://github.com/Asenar/less.php/compare/v1.7.0.10...v1.7.0.11) - - Fix realpath issue (windows) - - Set Less_Tree_Call property back to public ( Fix 258 266 267 issues from oyejorge/less.php) - -# 1.7.0.10 - - - [All Changes](https://github.com/oyejorge/less.php/compare/v1.7.0.9...v1.7.10) - - Add indentation option - - Add 'optional' modifier for @import - - fix $color in Exception messages - - don't use set_time_limit when running cli - - take relative-url into account when building the cache filename - - urlArgs should be string no array() - - add bug-report fixtures [#6dc898f](https://github.com/oyejorge/less.php/commit/6dc898f5d75b447464906bdf19d79c2e19d95e33) - - fix #269, missing on NameValue type [#a8dac63](https://github.com/oyejorge/less.php/commit/a8dac63d93fb941c54fb78b12588abf635747c1b) - -# 1.7.0.9 - - - [All Changes](https://github.com/oyejorge/less.php/compare/v1.7.0.8...v1.7.0.9) - - Remove space at beginning of Version.php - - Revert require() paths in test interface diff --git a/vendor/oyejorge/less.php/LICENSE b/vendor/oyejorge/less.php/LICENSE deleted file mode 100644 index 82216a5..0000000 --- a/vendor/oyejorge/less.php/LICENSE +++ /dev/null @@ -1,178 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - diff --git a/vendor/oyejorge/less.php/README.md b/vendor/oyejorge/less.php/README.md deleted file mode 100644 index f22c52a..0000000 --- a/vendor/oyejorge/less.php/README.md +++ /dev/null @@ -1,336 +0,0 @@ -[Less.php](http://lessphp.typesettercms.com) -======== - -This is a PHP port of the official LESS processor . [![Build Status](https://travis-ci.org/oyejorge/less.php.png?branch=master)](https://travis-ci.org/oyejorge/less.php) - -* [About](#about) -* [Installation](#installation) -* [Basic Use](#basic-use) -* [Caching](#caching) -* [Source Maps](#source-maps) -* [Command Line](#command-line) -* [Integration with other projects](#integration-with-other-projects) -* [Transitioning from Leafo/lessphp](#transitioning-from-leafolessphp) -* [Credits](#credits) - - - -About ---- -The code structure of less.php mirrors that of the official processor which helps us ensure compatibility and allows for easy maintenance. - -Please note, there are a few unsupported LESS features: - -- Evaluation of JavaScript expressions within back-ticks (for obvious reasons). -- Definition of custom functions. - - -Installation ---- - -You can install the library with composer or manually. - -#### Composer - -Step 1. Edit your `composer.json`: - -```json -{ - "require": { - "oyejorge/less.php": "~1.7.0.9" - } -} -``` - -Step 2. Install it: - -```bash -$ curl -sS https://getcomposer.org/installer | php -$ php composer.phar install -``` - -#### Manually From Release - -Step 1. [Download the latest release](https://github.com/oyejorge/less.php/releases) and upload the php files to your server. - -Step 2. Include the library: - -```php -require_once '[path to less.php]/Less.php'; -``` - -#### Manually From Source - -Step 1. [Download the source](https://github.com/oyejorge/less.php/archive/master.zip) and upload the files in /lib/Less to a folder on your server. - -Step 2. Include the library and register the Autoloader - -```php -require_once '[path to less.php]/Autoloader.php'; -Less_Autoloader::register(); -``` - -Basic Use ---- - -#### Parsing Strings - -```php -$parser = new Less_Parser(); -$parser->parse( '@color: #4D926F; #header { color: @color; } h2 { color: @color; }' ); -$css = $parser->getCss(); -``` - - -#### Parsing Less Files -The parseFile() function takes two arguments: - -1. The absolute path of the .less file to be parsed -2. The url root to prepend to any relative image or @import urls in the .less file. - -```php -$parser = new Less_Parser(); -$parser->parseFile( '/var/www/mysite/bootstrap.less', 'http://example.com/mysite/' ); -$css = $parser->getCss(); -``` - - -#### Handling Invalid Less -An exception will be thrown if the compiler encounters invalid less - -```php -try{ - $parser = new Less_Parser(); - $parser->parseFile( '/var/www/mysite/bootstrap.less', 'http://example.com/mysite/' ); - $css = $parser->getCss(); -}catch(Exception $e){ - $error_message = $e->getMessage(); -} -``` - - -#### Parsing Multiple Sources -less.php can parse multiple sources to generate a single css file - -```php -$parser = new Less_Parser(); -$parser->parseFile( '/var/www/mysite/bootstrap.less', '/mysite/' ); -$parser->parse( '@color: #4D926F; #header { color: @color; } h2 { color: @color; }' ); -$css = $parser->getCss(); -``` - -#### Getting Info About The Parsed Files -less.php can tell you which .less files were imported and parsed. - -```php -$parser = new Less_Parser(); -$parser->parseFile( '/var/www/mysite/bootstrap.less', '/mysite/' ); -$css = $parser->getCss(); -$imported_files = $parser->allParsedFiles(); -``` - - -#### Compressing Output -You can tell less.php to remove comments and whitespace to generate minimized css files. - -```php -$options = array( 'compress'=>true ); -$parser = new Less_Parser( $options ); -$parser->parseFile( '/var/www/mysite/bootstrap.less', '/mysite/' ); -$css = $parser->getCss(); -``` - -#### Getting Variables -You can use the getVariables() method to get an all variables defined and -their value in a php associative array. Note than less have to be previously -compiled -```php -$parser = new Less_Parser; -$parser->parseFile( '/var/www/mysite/bootstrap.less'); -$css = $parser->getCss(); -$variables = $parser->getVariables(); - -``` - - - -#### Setting Variables -You can use the ModifyVars() method to customize your css if you have variables stored in php associative arrays - -```php -$parser = new Less_Parser(); -$parser->parseFile( '/var/www/mysite/bootstrap.less', '/mysite/' ); -$parser->ModifyVars( array('font-size-base'=>'16px') ); -$css = $parser->getCss(); -``` - - -#### Import Directories -By default, less.php will look for @imports in the directory of the file passed to parsefile(). -If you're using parse() or if @imports reside in different directories, you can tell less.php where to look. - -```php -$directories = array( '/var/www/mysite/bootstrap/' => '/mysite/bootstrap/' ); -$parser = new Less_Parser(); -$parser->SetImportDirs( $directories ); -$parser->parseFile( '/var/www/mysite/theme.less', '/mysite/' ); -$css = $parser->getCss(); -``` - - -Caching ---- -Compiling less code into css is a time consuming process, caching your results is highly recommended. - - -#### Caching CSS -Use the Less_Cache class to save and reuse the results of compiled less files. -This method will check the modified time and size of each less file (including imported files) and regenerate a new css file when changes are found. -Note: When changes are found, this method will return a different file name for the new cached content. - -```php -$less_files = array( '/var/www/mysite/bootstrap.less' => '/mysite/' ); -$options = array( 'cache_dir' => '/var/www/writable_folder' ); -$css_file_name = Less_Cache::Get( $less_files, $options ); -$compiled = file_get_contents( '/var/www/writable_folder/'.$css_file_name ); -``` - -#### Caching CSS With Variables -Passing options to Less_Cache::Get() - -```php -$less_files = array( '/var/www/mysite/bootstrap.less' => '/mysite/' ); -$options = array( 'cache_dir' => '/var/www/writable_folder' ); -$variables = array( 'width' => '100px' ); -$css_file_name = Less_Cache::Get( $less_files, $options, $variables ); -$compiled = file_get_contents( '/var/www/writable_folder/'.$css_file_name ); -``` - - -#### Parser Caching -less.php will save serialized parser data for each .less file if a writable folder is passed to the SetCacheDir() method. -Note: This feature only caches intermediate parsing results to improve the performance of repeated css generation. -Your application should cache any css generated by less.php. - -```php -$options = array('cache_dir'=>'/var/www/writable_folder'); -$parser = new Less_Parser( $options ); -$parser->parseFile( '/var/www/mysite/bootstrap.less', '/mysite/' ); -$css = $parser->getCss(); -``` - -You can specify the caching technique used by changing the ```cache_method``` option. Supported methods are: -* ```php```: Creates valid PHP files which can be included without any changes (default method). -* ```var_export```: Like "php", but using PHPs ```var_export()``` function without any optimizations. - It's recommended to use "php" instead. -* ```serialize```: Faster, but pretty memory-intense. -* ```callback```: Use custom callback functions to implement your own caching method. Give the "cache_callback_get" and - "cache_callback_set" options with callables (see PHPs ```call_user_func()``` and ```is_callable()``` functions). less.php - will pass the parser object (class ```Less_Parser```), the path to the parsed .less file ("/some/path/to/file.less") and - an identifier that will change every time the .less file is modified. The ```get``` callback must return the ruleset - (an array with ```Less_Tree``` objects) provided as fourth parameter of the ```set``` callback. If something goes wrong, - return ```NULL``` (cache doesn't exist) or ```FALSE```. - - - -Source Maps ---- -Less.php supports v3 sourcemaps - -#### Inline -The sourcemap will be appended to the generated css file. - -```php -$options = array( 'sourceMap' => true ); -$parser = new Less_Parser($options); -$parser->parseFile( '/var/www/mysite/bootstrap.less', '/mysite/' ); -$css = $parser->getCss(); -``` - -#### Saving to Map File - -```php -$options = array( - 'sourceMap' => true, - 'sourceMapWriteTo' => '/var/www/mysite/writable_folder/filename.map', - 'sourceMapURL' => '/mysite/writable_folder/filename.map', - ); -$parser = new Less_Parser($options); -$parser->parseFile( '/var/www/mysite/bootstrap.less', '/mysite/' ); -$css = $parser->getCss(); -``` - - -Command line ---- -An additional script has been included to use the compiler from the command line. -In the simplest invocation, you specify an input file and the compiled css is written to standard out: - -``` -$ lessc input.less > output.css -``` - -By using the -w flag you can watch a specified input file and have it compile as needed to the output file: - -``` -$ lessc -w input.less output.css -``` - -Errors from watch mode are written to standard out. - -For more help, run `lessc --help` - - -Integration with other projects ---- - -#### Drupal 7 - -This library can be used as drop-in replacement of lessphp to work with [Drupal 7 less module](https://drupal.org/project/less). - -How to install: - -1. [Download the less.php source code](https://github.com/oyejorge/less.php/archive/master.zip) and unzip it so that 'lessc.inc.php' is located at 'sites/all/libraries/lessphp/lessc.inc.php'. -2. Download and install [Drupal 7 less module](https://drupal.org/project/less) as usual. -3. That's it :) - -#### JBST WordPress theme - -JBST has a built-in LESS compiler based on lessphp. Customize your WordPress theme with LESS. - -How to use / install: - -1. [Download the latest release](https://github.com/bassjobsen/jamedo-bootstrap-start-theme) copy the files to your {wordpress/}wp-content/themes folder and activate it. -2. Find the compiler under Appearance > LESS Compiler in your WordPress dashboard -3. Enter your LESS code in the text area and press (re)compile - -Use the built-in compiler to: -- set any [Bootstrap](http://getbootstrap.com/customize/) variable or use Bootstrap's mixins: - -`@navbar-default-color: blue;` - - create a custom button: `.btn-custom { - .button-variant(white; red; blue); -}` -- set any built-in LESS variable: for example `@footer_bg_color: black;` sets the background color of the footer to black -- use built-in mixins: - add a custom font: `.include-custom-font(@family: arial,@font-path, @path: @custom-font-dir, @weight: normal, @style: normal);` - -The compiler can also be download as [plugin](http://wordpress.org/plugins/wp-less-to-css/) - -#### WordPress - -This simple plugin will simply make the library available to other plugins and themes and can be used as a dependency using the [TGM Library](http://tgmpluginactivation.com/) - -How to install: - -1. Install the plugin from your WordPress Dashboard: http://wordpress.org/plugins/lessphp/ -2. That's it :) - - -Transitioning from Leafo/lessphp ---- -Projects looking for an easy transition from leafo/lessphp can use the lessc.inc.php adapter. To use, [Download the less.php source code](https://github.com/oyejorge/less.php/archive/master.zip) and unzip the files into your project so that the new 'lessc.inc.php' replaces the existing 'lessc.inc.php'. - -Note, the 'setPreserveComments' will no longer have any effect on the compiled less. - -Credits ---- -less.php was originally ported to php by [Matt Agar](https://github.com/agar) and then updated by [Martin Jantošovič](https://github.com/Mordred). diff --git a/vendor/oyejorge/less.php/bin/lessc b/vendor/oyejorge/less.php/bin/lessc deleted file mode 100644 index fa1fb95..0000000 --- a/vendor/oyejorge/less.php/bin/lessc +++ /dev/null @@ -1,191 +0,0 @@ -#!/usr/bin/env php - false, 'relativeUrls' => false); -$silent = false; -$watch = false; -$rootpath = ''; - -// Check for arguments -array_shift($argv); -if (!count($argv)) { - $argv[] = '-h'; -} - -// parse arguments -foreach ($argv as $key => $arg) { - if (preg_match('/^--?([a-z][0-9a-z-]*)(?:=([^\s]+))?$/i', $arg, $matches)) { - $option = $matches[1]; - $value = isset($matches[2]) ? $matches[2] : false; - unset($argv[$key]); - - switch ($option) { - case 'h': - case 'help': - echo << 1) { - $output = array_pop($argv); - $inputs = $argv; -} -else { - $inputs = $argv; - $output = false; -} - -if (!count($inputs)) { - echo("lessc: no input files\n"); - exit; -} - -if ($watch) { - if (!$output) { - echo("lessc: you must specify the output file if --watch is given\n"); - exit; - } - - $lastAction = 0; - - echo("lessc: watching input files\n"); - - while (1) { - clearstatcache(); - - $updated = false; - foreach ($inputs as $input) { - if ($input == '-') { - if (count($inputs) == 1) { - echo("lessc: during watching files is not possible to watch stdin\n"); - exit; - } - else { - continue; - } - } - - if (filemtime($input) > $lastAction) { - $updated = true; - break; - } - } - - if ($updated) { - $lastAction = time(); - $parser = new Less_Parser($env); - foreach ($inputs as $input) { - try { - $parser->parseFile($input, $rootpath); - } - catch (Exception $e) { - echo("lessc: " . $e->getMessage() . " \n"); - continue; // Invalid processing - } - } - - file_put_contents($output, $parser->getCss()); - echo("lessc: output file recompiled\n"); - } - - sleep(1); - } -} -else { - $parser = new Less_Parser($env); - foreach ($inputs as $input) { - if ($input == '-') { - $content = file_get_contents('php://stdin'); - $parser->parse($content); - } - else { - try { - $parser->parseFile($input); - } - catch (Exception $e) { - if (!$silent) { - echo("lessc: " . ((string)$e) . " \n"); - } - } - } - } - - if ($output) { - file_put_contents($output, $parser->getCss()); - } - else { - echo $parser->getCss(); - } -} diff --git a/vendor/oyejorge/less.php/composer.json b/vendor/oyejorge/less.php/composer.json deleted file mode 100644 index d16ce5e..0000000 --- a/vendor/oyejorge/less.php/composer.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "name": "oyejorge/less.php", - "description": "PHP port of the Javascript version of LESS http://lesscss.org (Originally maintained by Josh Schmidt)", - "keywords": [ "less", "css", "php", "stylesheet", "less.js", "lesscss" ], - "homepage": "http://lessphp.gpeasy.com", - "license": "Apache-2.0", - "authors": [ - { - "name": "Josh Schmidt", - "homepage": "https://github.com/oyejorge" - }, - { - "name": "Matt Agar", - "homepage": "https://github.com/agar" - }, - { - "name": "Martin Jantošovič", - "homepage": "https://github.com/Mordred" - } - ], - "require": { - "PHP" : ">=5.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.8.24" - }, - "scripts": { - "test": [ - "phpunit" - ] - }, - "autoload": { - "psr-0": { "Less": "lib/" }, - "classmap": ["lessc.inc.php"] - }, - "bin": [ - "bin/lessc" - ] -} diff --git a/vendor/oyejorge/less.php/lessc.inc.php b/vendor/oyejorge/less.php/lessc.inc.php deleted file mode 100644 index e6cdf20..0000000 --- a/vendor/oyejorge/less.php/lessc.inc.php +++ /dev/null @@ -1,276 +0,0 @@ -importDir = (array)$dirs; - } - - public function addImportDir( $dir ) { - $this->importDir = (array)$this->importDir; - $this->importDir[] = $dir; - } - - public function setFormatter( $name ) { - $this->formatterName = $name; - } - - public function setPreserveComments( $preserve ) {} - - public function registerFunction( $name, $func ) { - $this->libFunctions[$name] = $func; - } - - public function unregisterFunction( $name ) { - unset( $this->libFunctions[$name] ); - } - - public function setVariables( $variables ){ - foreach ( $variables as $name => $value ) { - $this->setVariable( $name, $value ); - } - } - - public function setVariable( $name, $value ) { - $this->registeredVars[$name] = $value; - } - - public function unsetVariable( $name ) { - unset( $this->registeredVars[$name] ); - } - - public function setOptions( $options ) { - foreach ( $options as $name => $value ) { - $this->setOption( $name, $value); - } - } - - public function setOption( $name, $value ) { - $this->options[$name] = $value; - } - - public function parse( $buffer, $presets = array() ) { - - $this->setVariables( $presets ); - - $parser = new Less_Parser( $this->getOptions() ); - $parser->setImportDirs( $this->getImportDirs() ); - foreach ( $this->libFunctions as $name => $func ) { - $parser->registerFunction( $name, $func ); - } - $parser->parse($buffer); - if ( count( $this->registeredVars ) ) { - $parser->ModifyVars( $this->registeredVars ); - } - - return $parser->getCss(); - } - - protected function getOptions() { - $options = array( 'relativeUrls'=>false ); - switch( $this->formatterName ) { - case 'compressed': - $options['compress'] = true; - break; - } - if (is_array($this->options)) - { - $options = array_merge($options, $this->options); - } - return $options; - } - - protected function getImportDirs() { - $dirs_ = (array)$this->importDir; - $dirs = array(); - foreach ( $dirs_ as $dir ) { - $dirs[$dir] = ''; - } - return $dirs; - } - - public function compile( $string, $name = null ) { - - $oldImport = $this->importDir; - $this->importDir = (array)$this->importDir; - - $this->allParsedFiles = array(); - - $parser = new Less_Parser( $this->getOptions() ); - $parser->SetImportDirs( $this->getImportDirs() ); - if ( count( $this->registeredVars ) ) { - $parser->ModifyVars( $this->registeredVars ); - } - foreach ( $this->libFunctions as $name => $func ) { - $parser->registerFunction( $name, $func ); - } - $parser->parse( $string ); - $out = $parser->getCss(); - - $parsed = Less_Parser::AllParsedFiles(); - foreach ( $parsed as $file ) { - $this->addParsedFile( $file ); - } - - $this->importDir = $oldImport; - - return $out; - } - - public function compileFile( $fname, $outFname = null ) { - if ( !is_readable( $fname ) ) { - throw new Exception( 'load error: failed to find '.$fname ); - } - - $pi = pathinfo( $fname ); - - $oldImport = $this->importDir; - - $this->importDir = (array)$this->importDir; - $this->importDir[] = Less_Parser::AbsPath( $pi['dirname'] ).'/'; - - $this->allParsedFiles = array(); - $this->addParsedFile( $fname ); - - $parser = new Less_Parser( $this->getOptions() ); - $parser->SetImportDirs( $this->getImportDirs() ); - if ( count( $this->registeredVars ) ) { - $parser->ModifyVars( $this->registeredVars ); - } - foreach ( $this->libFunctions as $name => $func ) { - $parser->registerFunction( $name, $func ); - } - $parser->parseFile( $fname ); - $out = $parser->getCss(); - - $parsed = Less_Parser::AllParsedFiles(); - foreach ( $parsed as $file ) { - $this->addParsedFile( $file ); - } - - $this->importDir = $oldImport; - - if ( $outFname !== null ) { - return file_put_contents( $outFname, $out ); - } - - return $out; - } - - public function checkedCompile( $in, $out ) { - if ( !is_file( $out ) || filemtime( $in ) > filemtime( $out ) ) { - $this->compileFile($in, $out); - return true; - } - return false; - } - - - /** - * Execute lessphp on a .less file or a lessphp cache structure - * - * The lessphp cache structure contains information about a specific - * less file having been parsed. It can be used as a hint for future - * calls to determine whether or not a rebuild is required. - * - * The cache structure contains two important keys that may be used - * externally: - * - * compiled: The final compiled CSS - * updated: The time (in seconds) the CSS was last compiled - * - * The cache structure is a plain-ol' PHP associative array and can - * be serialized and unserialized without a hitch. - * - * @param mixed $in Input - * @param bool $force Force rebuild? - * @return array lessphp cache structure - */ - public function cachedCompile( $in, $force = false ) { - // assume no root - $root = null; - - if ( is_string( $in ) ) { - $root = $in; - } elseif ( is_array( $in ) and isset( $in['root'] ) ) { - if ( $force or ! isset( $in['files'] ) ) { - // If we are forcing a recompile or if for some reason the - // structure does not contain any file information we should - // specify the root to trigger a rebuild. - $root = $in['root']; - } elseif ( isset( $in['files'] ) and is_array( $in['files'] ) ) { - foreach ( $in['files'] as $fname => $ftime ) { - if ( !file_exists( $fname ) or filemtime( $fname ) > $ftime ) { - // One of the files we knew about previously has changed - // so we should look at our incoming root again. - $root = $in['root']; - break; - } - } - } - } else { - // TODO: Throw an exception? We got neither a string nor something - // that looks like a compatible lessphp cache structure. - return null; - } - - if ( $root !== null ) { - // If we have a root value which means we should rebuild. - $out = array(); - $out['root'] = $root; - $out['compiled'] = $this->compileFile($root); - $out['files'] = $this->allParsedFiles(); - $out['updated'] = time(); - return $out; - } else { - // No changes, pass back the structure - // we were given initially. - return $in; - } - } - - public function ccompile( $in, $out, $less = null ) { - if ( $less === null ) { - $less = new self; - } - return $less->checkedCompile( $in, $out ); - } - - public static function cexecute( $in, $force = false, $less = null ) { - if ( $less === null ) { - $less = new self; - } - return $less->cachedCompile($in, $force); - } - - public function allParsedFiles() { - return $this->allParsedFiles; - } - - protected function addParsedFile( $file ) { - $this->allParsedFiles[Less_Parser::AbsPath( $file )] = filemtime( $file ); - } -} diff --git a/vendor/oyejorge/less.php/lib/Less/.easymin/ignore_prefixes b/vendor/oyejorge/less.php/lib/Less/.easymin/ignore_prefixes deleted file mode 100644 index ca953b2..0000000 --- a/vendor/oyejorge/less.php/lib/Less/.easymin/ignore_prefixes +++ /dev/null @@ -1,2 +0,0 @@ -.easymin -Autoloader.php diff --git a/vendor/oyejorge/less.php/lib/Less/Autoloader.php b/vendor/oyejorge/less.php/lib/Less/Autoloader.php deleted file mode 100644 index b6300c0..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Autoloader.php +++ /dev/null @@ -1,79 +0,0 @@ - '/'); - } - - - // generate name for compiled css file - $hash = md5(json_encode($less_files)); - $list_file = Less_Cache::$cache_dir . Less_Cache::$prefix . $hash . '.list'; - - // check cached content - if( !isset($parser_options['use_cache']) || $parser_options['use_cache'] === true ){ - if( file_exists($list_file) ){ - - self::ListFiles($list_file, $list, $cached_name); - $compiled_name = self::CompiledName($list, $hash); - - // if $cached_name is the same as the $compiled name, don't regenerate - if( !$cached_name || $cached_name === $compiled_name ){ - - $output_file = self::OutputFile($compiled_name, $parser_options ); - - if( $output_file && file_exists($output_file) ){ - @touch($list_file); - return basename($output_file); // for backwards compatibility, we just return the name of the file - } - } - } - } - - $compiled = self::Cache( $less_files, $parser_options ); - if( !$compiled ){ - return false; - } - - $compiled_name = self::CompiledName( $less_files, $hash ); - $output_file = self::OutputFile($compiled_name, $parser_options ); - - - //save the file list - $list = $less_files; - $list[] = $compiled_name; - $cache = implode("\n",$list); - file_put_contents( $list_file, $cache ); - - - //save the css - file_put_contents( $output_file, $compiled ); - - - //clean up - self::CleanCache(); - - return basename($output_file); - } - - /** - * Force the compiler to regenerate the cached css file - * - * @param array $less_files Array of .less files to compile - * @param array $parser_options Array of compiler options - * @param array $modify_vars Array of variables - * @return string Name of the css file - */ - public static function Regen( $less_files, $parser_options = array(), $modify_vars = array() ){ - $parser_options['use_cache'] = false; - return self::Get( $less_files, $parser_options, $modify_vars ); - } - - public static function Cache( &$less_files, $parser_options = array() ){ - - - // get less.php if it exists - $file = dirname(__FILE__) . '/Less.php'; - if( file_exists($file) && !class_exists('Less_Parser') ){ - require_once($file); - } - - $parser_options['cache_dir'] = Less_Cache::$cache_dir; - $parser = new Less_Parser($parser_options); - - - // combine files - foreach($less_files as $file_path => $uri_or_less ){ - - //treat as less markup if there are newline characters - if( strpos($uri_or_less,"\n") !== false ){ - $parser->Parse( $uri_or_less ); - continue; - } - - $parser->ParseFile( $file_path, $uri_or_less ); - } - - $compiled = $parser->getCss(); - - - $less_files = $parser->allParsedFiles(); - - return $compiled; - } - - - private static function OutputFile( $compiled_name, $parser_options ){ - - //custom output file - if( !empty($parser_options['output']) ){ - - //relative to cache directory? - if( preg_match('#[\\\\/]#',$parser_options['output']) ){ - return $parser_options['output']; - } - - return Less_Cache::$cache_dir.$parser_options['output']; - } - - return Less_Cache::$cache_dir.$compiled_name; - } - - - private static function CompiledName( $files, $extrahash ){ - - //save the file list - $temp = array(Less_Version::cache_version); - foreach($files as $file){ - $temp[] = filemtime($file)."\t".filesize($file)."\t".$file; - } - - return Less_Cache::$prefix.sha1(json_encode($temp).$extrahash).'.css'; - } - - - public static function SetCacheDir( $dir ){ - Less_Cache::$cache_dir = $dir; - self::CheckCacheDir(); - } - - public static function CheckCacheDir(){ - - Less_Cache::$cache_dir = str_replace('\\','/',Less_Cache::$cache_dir); - Less_Cache::$cache_dir = rtrim(Less_Cache::$cache_dir,'/').'/'; - - if( !file_exists(Less_Cache::$cache_dir) ){ - if( !mkdir(Less_Cache::$cache_dir) ){ - throw new Less_Exception_Parser('Less.php cache directory couldn\'t be created: '.Less_Cache::$cache_dir); - } - - }elseif( !is_dir(Less_Cache::$cache_dir) ){ - throw new Less_Exception_Parser('Less.php cache directory doesn\'t exist: '.Less_Cache::$cache_dir); - - }elseif( !is_writable(Less_Cache::$cache_dir) ){ - throw new Less_Exception_Parser('Less.php cache directory isn\'t writable: '.Less_Cache::$cache_dir); - - } - - } - - - /** - * Delete unused less.php files - * - */ - public static function CleanCache(){ - static $clean = false; - - - if( $clean || empty(Less_Cache::$cache_dir) ){ - return; - } - - $clean = true; - - // only remove files with extensions created by less.php - // css files removed based on the list files - $remove_types = array('lesscache'=>1,'list'=>1,'less'=>1,'map'=>1); - - $files = scandir(Less_Cache::$cache_dir); - if( !$files ){ - return; - } - - $check_time = time() - self::$gc_lifetime; - foreach($files as $file){ - - - // don't delete if the file wasn't created with less.php - if( strpos($file,Less_Cache::$prefix) !== 0 ){ - continue; - } - - $parts = explode('.',$file); - $type = array_pop($parts); - - - if( !isset($remove_types[$type]) ){ - continue; - } - - $full_path = Less_Cache::$cache_dir . $file; - $mtime = filemtime($full_path); - - // don't delete if it's a relatively new file - if( $mtime > $check_time ){ - continue; - } - - - // delete the list file and associated css file - if( $type === 'list' ){ - self::ListFiles($full_path, $list, $css_file_name); - if( $css_file_name ){ - $css_file = Less_Cache::$cache_dir . $css_file_name; - if( file_exists($css_file) ){ - unlink($css_file); - } - } - } - - unlink($full_path); - } - - - } - - - /** - * Get the list of less files and generated css file from a list file - * - */ - static function ListFiles($list_file, &$list, &$css_file_name ){ - - $list = explode("\n",file_get_contents($list_file)); - - //pop the cached name that should match $compiled_name - $css_file_name = array_pop($list); - - if( !preg_match('/^' . Less_Cache::$prefix . '[a-f0-9]+\.css$/',$css_file_name) ){ - $list[] = $css_file_name; - $css_file_name = false; - } - - } - -} diff --git a/vendor/oyejorge/less.php/lib/Less/Colors.php b/vendor/oyejorge/less.php/lib/Less/Colors.php deleted file mode 100644 index ad3f31d..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Colors.php +++ /dev/null @@ -1,170 +0,0 @@ -'#f0f8ff', - 'antiquewhite'=>'#faebd7', - 'aqua'=>'#00ffff', - 'aquamarine'=>'#7fffd4', - 'azure'=>'#f0ffff', - 'beige'=>'#f5f5dc', - 'bisque'=>'#ffe4c4', - 'black'=>'#000000', - 'blanchedalmond'=>'#ffebcd', - 'blue'=>'#0000ff', - 'blueviolet'=>'#8a2be2', - 'brown'=>'#a52a2a', - 'burlywood'=>'#deb887', - 'cadetblue'=>'#5f9ea0', - 'chartreuse'=>'#7fff00', - 'chocolate'=>'#d2691e', - 'coral'=>'#ff7f50', - 'cornflowerblue'=>'#6495ed', - 'cornsilk'=>'#fff8dc', - 'crimson'=>'#dc143c', - 'cyan'=>'#00ffff', - 'darkblue'=>'#00008b', - 'darkcyan'=>'#008b8b', - 'darkgoldenrod'=>'#b8860b', - 'darkgray'=>'#a9a9a9', - 'darkgrey'=>'#a9a9a9', - 'darkgreen'=>'#006400', - 'darkkhaki'=>'#bdb76b', - 'darkmagenta'=>'#8b008b', - 'darkolivegreen'=>'#556b2f', - 'darkorange'=>'#ff8c00', - 'darkorchid'=>'#9932cc', - 'darkred'=>'#8b0000', - 'darksalmon'=>'#e9967a', - 'darkseagreen'=>'#8fbc8f', - 'darkslateblue'=>'#483d8b', - 'darkslategray'=>'#2f4f4f', - 'darkslategrey'=>'#2f4f4f', - 'darkturquoise'=>'#00ced1', - 'darkviolet'=>'#9400d3', - 'deeppink'=>'#ff1493', - 'deepskyblue'=>'#00bfff', - 'dimgray'=>'#696969', - 'dimgrey'=>'#696969', - 'dodgerblue'=>'#1e90ff', - 'firebrick'=>'#b22222', - 'floralwhite'=>'#fffaf0', - 'forestgreen'=>'#228b22', - 'fuchsia'=>'#ff00ff', - 'gainsboro'=>'#dcdcdc', - 'ghostwhite'=>'#f8f8ff', - 'gold'=>'#ffd700', - 'goldenrod'=>'#daa520', - 'gray'=>'#808080', - 'grey'=>'#808080', - 'green'=>'#008000', - 'greenyellow'=>'#adff2f', - 'honeydew'=>'#f0fff0', - 'hotpink'=>'#ff69b4', - 'indianred'=>'#cd5c5c', - 'indigo'=>'#4b0082', - 'ivory'=>'#fffff0', - 'khaki'=>'#f0e68c', - 'lavender'=>'#e6e6fa', - 'lavenderblush'=>'#fff0f5', - 'lawngreen'=>'#7cfc00', - 'lemonchiffon'=>'#fffacd', - 'lightblue'=>'#add8e6', - 'lightcoral'=>'#f08080', - 'lightcyan'=>'#e0ffff', - 'lightgoldenrodyellow'=>'#fafad2', - 'lightgray'=>'#d3d3d3', - 'lightgrey'=>'#d3d3d3', - 'lightgreen'=>'#90ee90', - 'lightpink'=>'#ffb6c1', - 'lightsalmon'=>'#ffa07a', - 'lightseagreen'=>'#20b2aa', - 'lightskyblue'=>'#87cefa', - 'lightslategray'=>'#778899', - 'lightslategrey'=>'#778899', - 'lightsteelblue'=>'#b0c4de', - 'lightyellow'=>'#ffffe0', - 'lime'=>'#00ff00', - 'limegreen'=>'#32cd32', - 'linen'=>'#faf0e6', - 'magenta'=>'#ff00ff', - 'maroon'=>'#800000', - 'mediumaquamarine'=>'#66cdaa', - 'mediumblue'=>'#0000cd', - 'mediumorchid'=>'#ba55d3', - 'mediumpurple'=>'#9370d8', - 'mediumseagreen'=>'#3cb371', - 'mediumslateblue'=>'#7b68ee', - 'mediumspringgreen'=>'#00fa9a', - 'mediumturquoise'=>'#48d1cc', - 'mediumvioletred'=>'#c71585', - 'midnightblue'=>'#191970', - 'mintcream'=>'#f5fffa', - 'mistyrose'=>'#ffe4e1', - 'moccasin'=>'#ffe4b5', - 'navajowhite'=>'#ffdead', - 'navy'=>'#000080', - 'oldlace'=>'#fdf5e6', - 'olive'=>'#808000', - 'olivedrab'=>'#6b8e23', - 'orange'=>'#ffa500', - 'orangered'=>'#ff4500', - 'orchid'=>'#da70d6', - 'palegoldenrod'=>'#eee8aa', - 'palegreen'=>'#98fb98', - 'paleturquoise'=>'#afeeee', - 'palevioletred'=>'#d87093', - 'papayawhip'=>'#ffefd5', - 'peachpuff'=>'#ffdab9', - 'peru'=>'#cd853f', - 'pink'=>'#ffc0cb', - 'plum'=>'#dda0dd', - 'powderblue'=>'#b0e0e6', - 'purple'=>'#800080', - 'red'=>'#ff0000', - 'rosybrown'=>'#bc8f8f', - 'royalblue'=>'#4169e1', - 'saddlebrown'=>'#8b4513', - 'salmon'=>'#fa8072', - 'sandybrown'=>'#f4a460', - 'seagreen'=>'#2e8b57', - 'seashell'=>'#fff5ee', - 'sienna'=>'#a0522d', - 'silver'=>'#c0c0c0', - 'skyblue'=>'#87ceeb', - 'slateblue'=>'#6a5acd', - 'slategray'=>'#708090', - 'slategrey'=>'#708090', - 'snow'=>'#fffafa', - 'springgreen'=>'#00ff7f', - 'steelblue'=>'#4682b4', - 'tan'=>'#d2b48c', - 'teal'=>'#008080', - 'thistle'=>'#d8bfd8', - 'tomato'=>'#ff6347', - 'turquoise'=>'#40e0d0', - 'violet'=>'#ee82ee', - 'wheat'=>'#f5deb3', - 'white'=>'#ffffff', - 'whitesmoke'=>'#f5f5f5', - 'yellow'=>'#ffff00', - 'yellowgreen'=>'#9acd32' - ); - - public static function hasOwnProperty($color) { - return isset(self::$colors[$color]); - } - - - public static function color($color) { - return self::$colors[$color]; - } - -} diff --git a/vendor/oyejorge/less.php/lib/Less/Configurable.php b/vendor/oyejorge/less.php/lib/Less/Configurable.php deleted file mode 100644 index aa7fd3e..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Configurable.php +++ /dev/null @@ -1,69 +0,0 @@ -defaultOptions); - $this->options = array_merge($this->defaultOptions, $this->options, $options); - } - - - /** - * Get an option value by name - * - * If the option is empty or not set a NULL value will be returned. - * - * @param string $name - * @param mixed $default Default value if confiuration of $name is not present - * @return mixed - */ - public function getOption($name, $default = null){ - if(isset($this->options[$name])){ - return $this->options[$name]; - } - return $default; - } - - - /** - * Set an option - * - * @param string $name - * @param mixed $value - */ - public function setOption($name, $value){ - $this->options[$name] = $value; - } - -} \ No newline at end of file diff --git a/vendor/oyejorge/less.php/lib/Less/Environment.php b/vendor/oyejorge/less.php/lib/Less/Environment.php deleted file mode 100644 index b220301..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Environment.php +++ /dev/null @@ -1,166 +0,0 @@ - ',', - ': ' => ':', - '' => '', - ' ' => ' ', - ':' => ' :', - '+' => '+', - '~' => '~', - '>' => '>', - '|' => '|', - '^' => '^', - '^^' => '^^' - ); - - }else{ - - Less_Environment::$_outputMap = array( - ',' => ', ', - ': ' => ': ', - '' => '', - ' ' => ' ', - ':' => ' :', - '+' => ' + ', - '~' => ' ~ ', - '>' => ' > ', - '|' => '|', - '^' => ' ^ ', - '^^' => ' ^^ ' - ); - - } - } - - - public function copyEvalEnv($frames = array() ){ - $new_env = new Less_Environment(); - $new_env->frames = $frames; - return $new_env; - } - - - public static function isMathOn(){ - return !Less_Parser::$options['strictMath'] || Less_Environment::$parensStack; - } - - public static function isPathRelative($path){ - return !preg_match('/^(?:[a-z-]+:|\/)/',$path); - } - - - /** - * Canonicalize a path by resolving references to '/./', '/../' - * Does not remove leading "../" - * @param string path or url - * @return string Canonicalized path - * - */ - public static function normalizePath($path){ - - $segments = explode('/',$path); - $segments = array_reverse($segments); - - $path = array(); - $path_len = 0; - - while( $segments ){ - $segment = array_pop($segments); - switch( $segment ) { - - case '.': - break; - - case '..': - if( !$path_len || ( $path[$path_len-1] === '..') ){ - $path[] = $segment; - $path_len++; - }else{ - array_pop($path); - $path_len--; - } - break; - - default: - $path[] = $segment; - $path_len++; - break; - } - } - - return implode('/',$path); - } - - - public function unshiftFrame($frame){ - array_unshift($this->frames, $frame); - } - - public function shiftFrame(){ - return array_shift($this->frames); - } - -} diff --git a/vendor/oyejorge/less.php/lib/Less/Exception/Chunk.php b/vendor/oyejorge/less.php/lib/Less/Exception/Chunk.php deleted file mode 100644 index fcce1b4..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Exception/Chunk.php +++ /dev/null @@ -1,203 +0,0 @@ -message = 'ParseError: Unexpected input'; //default message - - $this->index = $index; - - $this->currentFile = $currentFile; - - $this->input = $input; - $this->input_len = strlen($input); - - $this->Chunks(); - $this->genMessage(); - } - - - /** - * See less.js chunks() - * We don't actually need the chunks - * - */ - protected function Chunks(){ - $level = 0; - $parenLevel = 0; - $lastMultiCommentEndBrace = null; - $lastOpening = null; - $lastMultiComment = null; - $lastParen = null; - - for( $this->parserCurrentIndex = 0; $this->parserCurrentIndex < $this->input_len; $this->parserCurrentIndex++ ){ - $cc = $this->CharCode($this->parserCurrentIndex); - if ((($cc >= 97) && ($cc <= 122)) || ($cc < 34)) { - // a-z or whitespace - continue; - } - - switch ($cc) { - - // ( - case 40: - $parenLevel++; - $lastParen = $this->parserCurrentIndex; - continue; - - // ) - case 41: - $parenLevel--; - if( $parenLevel < 0 ){ - return $this->fail("missing opening `(`"); - } - continue; - - // ; - case 59: - //if (!$parenLevel) { $this->emitChunk(); } - continue; - - // { - case 123: - $level++; - $lastOpening = $this->parserCurrentIndex; - continue; - - // } - case 125: - $level--; - if( $level < 0 ){ - return $this->fail("missing opening `{`"); - - } - //if (!$level && !$parenLevel) { $this->emitChunk(); } - continue; - // \ - case 92: - if ($this->parserCurrentIndex < $this->input_len - 1) { $this->parserCurrentIndex++; continue; } - return $this->fail("unescaped `\\`"); - - // ", ' and ` - case 34: - case 39: - case 96: - $matched = 0; - $currentChunkStartIndex = $this->parserCurrentIndex; - for ($this->parserCurrentIndex = $this->parserCurrentIndex + 1; $this->parserCurrentIndex < $this->input_len; $this->parserCurrentIndex++) { - $cc2 = $this->CharCode($this->parserCurrentIndex); - if ($cc2 > 96) { continue; } - if ($cc2 == $cc) { $matched = 1; break; } - if ($cc2 == 92) { // \ - if ($this->parserCurrentIndex == $this->input_len - 1) { - return $this->fail("unescaped `\\`"); - } - $this->parserCurrentIndex++; - } - } - if ($matched) { continue; } - return $this->fail("unmatched `" . chr($cc) . "`", $currentChunkStartIndex); - - // /, check for comment - case 47: - if ($parenLevel || ($this->parserCurrentIndex == $this->input_len - 1)) { continue; } - $cc2 = $this->CharCode($this->parserCurrentIndex+1); - if ($cc2 == 47) { - // //, find lnfeed - for ($this->parserCurrentIndex = $this->parserCurrentIndex + 2; $this->parserCurrentIndex < $this->input_len; $this->parserCurrentIndex++) { - $cc2 = $this->CharCode($this->parserCurrentIndex); - if (($cc2 <= 13) && (($cc2 == 10) || ($cc2 == 13))) { break; } - } - } else if ($cc2 == 42) { - // /*, find */ - $lastMultiComment = $currentChunkStartIndex = $this->parserCurrentIndex; - for ($this->parserCurrentIndex = $this->parserCurrentIndex + 2; $this->parserCurrentIndex < $this->input_len - 1; $this->parserCurrentIndex++) { - $cc2 = $this->CharCode($this->parserCurrentIndex); - if ($cc2 == 125) { $lastMultiCommentEndBrace = $this->parserCurrentIndex; } - if ($cc2 != 42) { continue; } - if ($this->CharCode($this->parserCurrentIndex+1) == 47) { break; } - } - if ($this->parserCurrentIndex == $this->input_len - 1) { - return $this->fail("missing closing `*/`", $currentChunkStartIndex); - } - } - continue; - - // *, check for unmatched */ - case 42: - if (($this->parserCurrentIndex < $this->input_len - 1) && ($this->CharCode($this->parserCurrentIndex+1) == 47)) { - return $this->fail("unmatched `/*`"); - } - continue; - } - } - - if( $level !== 0 ){ - if( ($lastMultiComment > $lastOpening) && ($lastMultiCommentEndBrace > $lastMultiComment) ){ - return $this->fail("missing closing `}` or `*/`", $lastOpening); - } else { - return $this->fail("missing closing `}`", $lastOpening); - } - } else if ( $parenLevel !== 0 ){ - return $this->fail("missing closing `)`", $lastParen); - } - - - //chunk didn't fail - - - //$this->emitChunk(true); - } - - public function CharCode($pos){ - return ord($this->input[$pos]); - } - - - public function fail( $msg, $index = null ){ - - if( !$index ){ - $this->index = $this->parserCurrentIndex; - }else{ - $this->index = $index; - } - $this->message = 'ParseError: '.$msg; - } - - - /* - function emitChunk( $force = false ){ - $len = $this->parserCurrentIndex - $this->emitFrom; - if ((($len < 512) && !$force) || !$len) { - return; - } - $chunks[] = substr($this->input, $this->emitFrom, $this->parserCurrentIndex + 1 - $this->emitFrom ); - $this->emitFrom = $this->parserCurrentIndex + 1; - } - */ - -} diff --git a/vendor/oyejorge/less.php/lib/Less/Exception/Compiler.php b/vendor/oyejorge/less.php/lib/Less/Exception/Compiler.php deleted file mode 100644 index 713e030..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Exception/Compiler.php +++ /dev/null @@ -1,11 +0,0 @@ -previous = $previous; - parent::__construct($message, $code); - } else { - parent::__construct($message, $code, $previous); - } - - $this->currentFile = $currentFile; - $this->index = $index; - - $this->genMessage(); - } - - - protected function getInput(){ - - if( !$this->input && $this->currentFile && $this->currentFile['filename'] && file_exists($this->currentFile['filename']) ){ - $this->input = file_get_contents( $this->currentFile['filename'] ); - } - } - - - - /** - * Converts the exception to string - * - * @return string - */ - public function genMessage(){ - - if( $this->currentFile && $this->currentFile['filename'] ){ - $this->message .= ' in '.basename($this->currentFile['filename']); - } - - if( $this->index !== null ){ - $this->getInput(); - if( $this->input ){ - $line = self::getLineNumber(); - $this->message .= ' on line '.$line.', column '.self::getColumn(); - - $lines = explode("\n",$this->input); - - $count = count($lines); - $start_line = max(0, $line-3); - $last_line = min($count, $start_line+6); - $num_len = strlen($last_line); - for( $i = $start_line; $i < $last_line; $i++ ){ - $this->message .= "\n".str_pad($i+1,$num_len,'0',STR_PAD_LEFT).'| '.$lines[$i]; - } - } - } - - } - - /** - * Returns the line number the error was encountered - * - * @return integer - */ - public function getLineNumber(){ - if( $this->index ){ - // https://bugs.php.net/bug.php?id=49790 - if (ini_get("mbstring.func_overload")) { - return substr_count(substr($this->input, 0, $this->index), "\n") + 1; - } else { - return substr_count($this->input, "\n", 0, $this->index) + 1; - } - } - return 1; - } - - - /** - * Returns the column the error was encountered - * - * @return integer - */ - public function getColumn(){ - - $part = substr($this->input, 0, $this->index); - $pos = strrpos($part,"\n"); - return $this->index - $pos; - } - -} diff --git a/vendor/oyejorge/less.php/lib/Less/Functions.php b/vendor/oyejorge/less.php/lib/Less/Functions.php deleted file mode 100644 index a61e5ac..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Functions.php +++ /dev/null @@ -1,1188 +0,0 @@ -env = $env; - $this->currentFileInfo = $currentFileInfo; - } - - /** - * @param string $op - */ - public static function operate( $op, $a, $b ){ - switch ($op) { - case '+': return $a + $b; - case '-': return $a - $b; - case '*': return $a * $b; - case '/': return $a / $b; - } - } - - public static function clamp($val, $max = 1){ - return min( max($val, 0), $max); - } - - public static function fround( $value ){ - - if( $value === 0 ){ - return $value; - } - - if( Less_Parser::$options['numPrecision'] ){ - $p = pow(10, Less_Parser::$options['numPrecision']); - return round( $value * $p) / $p; - } - return $value; - } - - public static function number($n){ - - if ($n instanceof Less_Tree_Dimension) { - return floatval( $n->unit->is('%') ? $n->value / 100 : $n->value); - } else if (is_numeric($n)) { - return $n; - } else { - throw new Less_Exception_Compiler("color functions take numbers as parameters"); - } - } - - public static function scaled($n, $size = 255 ){ - if( $n instanceof Less_Tree_Dimension && $n->unit->is('%') ){ - return (float)$n->value * $size / 100; - } else { - return Less_Functions::number($n); - } - } - - public function rgb ($r = null, $g = null, $b = null){ - if (is_null($r) || is_null($g) || is_null($b)) { - throw new Less_Exception_Compiler("rgb expects three parameters"); - } - return $this->rgba($r, $g, $b, 1.0); - } - - public function rgba($r = null, $g = null, $b = null, $a = null){ - $rgb = array($r, $g, $b); - $rgb = array_map(array('Less_Functions','scaled'),$rgb); - - $a = self::number($a); - return new Less_Tree_Color($rgb, $a); - } - - public function hsl($h, $s, $l){ - return $this->hsla($h, $s, $l, 1.0); - } - - public function hsla($h, $s, $l, $a){ - - $h = fmod(self::number($h), 360) / 360; // Classic % operator will change float to int - $s = self::clamp(self::number($s)); - $l = self::clamp(self::number($l)); - $a = self::clamp(self::number($a)); - - $m2 = $l <= 0.5 ? $l * ($s + 1) : $l + $s - $l * $s; - - $m1 = $l * 2 - $m2; - - return $this->rgba( self::hsla_hue($h + 1/3, $m1, $m2) * 255, - self::hsla_hue($h, $m1, $m2) * 255, - self::hsla_hue($h - 1/3, $m1, $m2) * 255, - $a); - } - - /** - * @param double $h - */ - public function hsla_hue($h, $m1, $m2){ - $h = $h < 0 ? $h + 1 : ($h > 1 ? $h - 1 : $h); - if ($h * 6 < 1) return $m1 + ($m2 - $m1) * $h * 6; - else if ($h * 2 < 1) return $m2; - else if ($h * 3 < 2) return $m1 + ($m2 - $m1) * (2/3 - $h) * 6; - else return $m1; - } - - public function hsv($h, $s, $v) { - return $this->hsva($h, $s, $v, 1.0); - } - - /** - * @param double $a - */ - public function hsva($h, $s, $v, $a) { - $h = ((Less_Functions::number($h) % 360) / 360 ) * 360; - $s = Less_Functions::number($s); - $v = Less_Functions::number($v); - $a = Less_Functions::number($a); - - $i = floor(($h / 60) % 6); - $f = ($h / 60) - $i; - - $vs = array( $v, - $v * (1 - $s), - $v * (1 - $f * $s), - $v * (1 - (1 - $f) * $s)); - - $perm = array(array(0, 3, 1), - array(2, 0, 1), - array(1, 0, 3), - array(1, 2, 0), - array(3, 1, 0), - array(0, 1, 2)); - - return $this->rgba($vs[$perm[$i][0]] * 255, - $vs[$perm[$i][1]] * 255, - $vs[$perm[$i][2]] * 255, - $a); - } - - public function hue($color = null){ - if (!$color instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The first argument to hue must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - - $c = $color->toHSL(); - return new Less_Tree_Dimension(Less_Parser::round($c['h'])); - } - - public function saturation($color = null){ - if (!$color instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The first argument to saturation must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - - $c = $color->toHSL(); - return new Less_Tree_Dimension(Less_Parser::round($c['s'] * 100), '%'); - } - - public function lightness($color = null){ - if (!$color instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The first argument to lightness must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - - $c = $color->toHSL(); - return new Less_Tree_Dimension(Less_Parser::round($c['l'] * 100), '%'); - } - - public function hsvhue( $color = null ){ - if (!$color instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The first argument to hsvhue must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - - $hsv = $color->toHSV(); - return new Less_Tree_Dimension( Less_Parser::round($hsv['h']) ); - } - - - public function hsvsaturation( $color = null ){ - if (!$color instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The first argument to hsvsaturation must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - - $hsv = $color->toHSV(); - return new Less_Tree_Dimension( Less_Parser::round($hsv['s'] * 100), '%' ); - } - - public function hsvvalue( $color = null ){ - if (!$color instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The first argument to hsvvalue must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - - $hsv = $color->toHSV(); - return new Less_Tree_Dimension( Less_Parser::round($hsv['v'] * 100), '%' ); - } - - public function red($color = null) { - if (!$color instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The first argument to red must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - - return new Less_Tree_Dimension( $color->rgb[0] ); - } - - public function green($color = null) { - if (!$color instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The first argument to green must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - - return new Less_Tree_Dimension( $color->rgb[1] ); - } - - public function blue($color = null) { - if (!$color instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The first argument to blue must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - - return new Less_Tree_Dimension( $color->rgb[2] ); - } - - public function alpha($color = null){ - if (!$color instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The first argument to alpha must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - - $c = $color->toHSL(); - return new Less_Tree_Dimension($c['a']); - } - - public function luma ($color = null) { - if (!$color instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The first argument to luma must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - - return new Less_Tree_Dimension(Less_Parser::round( $color->luma() * $color->alpha * 100), '%'); - } - - public function luminance( $color = null ){ - if (!$color instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The first argument to luminance must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - - $luminance = - (0.2126 * $color->rgb[0] / 255) - + (0.7152 * $color->rgb[1] / 255) - + (0.0722 * $color->rgb[2] / 255); - - return new Less_Tree_Dimension(Less_Parser::round( $luminance * $color->alpha * 100), '%'); - } - - public function saturate($color = null, $amount = null){ - // filter: saturate(3.2); - // should be kept as is, so check for color - if ($color instanceof Less_Tree_Dimension) { - return null; - } - - if (!$color instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The first argument to saturate must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - if (!$amount instanceof Less_Tree_Dimension) { - throw new Less_Exception_Compiler('The second argument to saturate must be a percentage' . ($amount instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - - $hsl = $color->toHSL(); - - $hsl['s'] += $amount->value / 100; - $hsl['s'] = self::clamp($hsl['s']); - - return $this->hsla($hsl['h'], $hsl['s'], $hsl['l'], $hsl['a']); - } - - /** - * @param Less_Tree_Dimension $amount - */ - public function desaturate($color = null, $amount = null){ - if (!$color instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The first argument to desaturate must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - if (!$amount instanceof Less_Tree_Dimension) { - throw new Less_Exception_Compiler('The second argument to desaturate must be a percentage' . ($amount instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - - $hsl = $color->toHSL(); - - $hsl['s'] -= $amount->value / 100; - $hsl['s'] = self::clamp($hsl['s']); - - return $this->hsla($hsl['h'], $hsl['s'], $hsl['l'], $hsl['a']); - } - - - - public function lighten($color = null, $amount=null){ - if (!$color instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The first argument to lighten must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - if (!$amount instanceof Less_Tree_Dimension) { - throw new Less_Exception_Compiler('The second argument to lighten must be a percentage' . ($amount instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - - $hsl = $color->toHSL(); - - $hsl['l'] += $amount->value / 100; - $hsl['l'] = self::clamp($hsl['l']); - - return $this->hsla($hsl['h'], $hsl['s'], $hsl['l'], $hsl['a']); - } - - public function darken($color = null, $amount = null){ - if (!$color instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The first argument to darken must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - if (!$amount instanceof Less_Tree_Dimension) { - throw new Less_Exception_Compiler('The second argument to darken must be a percentage' . ($amount instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - - $hsl = $color->toHSL(); - $hsl['l'] -= $amount->value / 100; - $hsl['l'] = self::clamp($hsl['l']); - - return $this->hsla($hsl['h'], $hsl['s'], $hsl['l'], $hsl['a']); - } - - public function fadein($color = null, $amount = null){ - if (!$color instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The first argument to fadein must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - if (!$amount instanceof Less_Tree_Dimension) { - throw new Less_Exception_Compiler('The second argument to fadein must be a percentage' . ($amount instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - - $hsl = $color->toHSL(); - $hsl['a'] += $amount->value / 100; - $hsl['a'] = self::clamp($hsl['a']); - return $this->hsla($hsl['h'], $hsl['s'], $hsl['l'], $hsl['a']); - } - - public function fadeout($color = null, $amount = null){ - if (!$color instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The first argument to fadeout must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - if (!$amount instanceof Less_Tree_Dimension) { - throw new Less_Exception_Compiler('The second argument to fadeout must be a percentage' . ($amount instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - - $hsl = $color->toHSL(); - $hsl['a'] -= $amount->value / 100; - $hsl['a'] = self::clamp($hsl['a']); - return $this->hsla($hsl['h'], $hsl['s'], $hsl['l'], $hsl['a']); - } - - public function fade($color = null, $amount = null){ - if (!$color instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The first argument to fade must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - if (!$amount instanceof Less_Tree_Dimension) { - throw new Less_Exception_Compiler('The second argument to fade must be a percentage' . ($amount instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - - $hsl = $color->toHSL(); - - $hsl['a'] = $amount->value / 100; - $hsl['a'] = self::clamp($hsl['a']); - return $this->hsla($hsl['h'], $hsl['s'], $hsl['l'], $hsl['a']); - } - - - - public function spin($color = null, $amount = null){ - if (!$color instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The first argument to spin must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - if (!$amount instanceof Less_Tree_Dimension) { - throw new Less_Exception_Compiler('The second argument to spin must be a number' . ($amount instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - - $hsl = $color->toHSL(); - $hue = fmod($hsl['h'] + $amount->value, 360); - - $hsl['h'] = $hue < 0 ? 360 + $hue : $hue; - - return $this->hsla($hsl['h'], $hsl['s'], $hsl['l'], $hsl['a']); - } - - // - // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein - // http://sass-lang.com - // - - /** - * @param Less_Tree_Color $color1 - */ - public function mix($color1 = null, $color2 = null, $weight = null){ - if (!$color1 instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The first argument to mix must be a color' . ($color1 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - if (!$color2 instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The second argument to mix must be a color' . ($color2 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - if (!$weight) { - $weight = new Less_Tree_Dimension('50', '%'); - } - if (!$weight instanceof Less_Tree_Dimension) { - throw new Less_Exception_Compiler('The third argument to contrast must be a percentage' . ($weight instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - - $p = $weight->value / 100.0; - $w = $p * 2 - 1; - $hsl1 = $color1->toHSL(); - $hsl2 = $color2->toHSL(); - $a = $hsl1['a'] - $hsl2['a']; - - $w1 = (((($w * $a) == -1) ? $w : ($w + $a) / (1 + $w * $a)) + 1) / 2; - $w2 = 1 - $w1; - - $rgb = array($color1->rgb[0] * $w1 + $color2->rgb[0] * $w2, - $color1->rgb[1] * $w1 + $color2->rgb[1] * $w2, - $color1->rgb[2] * $w1 + $color2->rgb[2] * $w2); - - $alpha = $color1->alpha * $p + $color2->alpha * (1 - $p); - - return new Less_Tree_Color($rgb, $alpha); - } - - public function greyscale($color){ - return $this->desaturate($color, new Less_Tree_Dimension(100,'%')); - } - - - public function contrast( $color, $dark = null, $light = null, $threshold = null){ - // filter: contrast(3.2); - // should be kept as is, so check for color - if (!$color instanceof Less_Tree_Color) { - return null; - } - if( !$light ){ - $light = $this->rgba(255, 255, 255, 1.0); - } - if( !$dark ){ - $dark = $this->rgba(0, 0, 0, 1.0); - } - - if (!$dark instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The second argument to contrast must be a color' . ($dark instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - if (!$light instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The third argument to contrast must be a color' . ($light instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - - //Figure out which is actually light and dark! - if( $dark->luma() > $light->luma() ){ - $t = $light; - $light = $dark; - $dark = $t; - } - if( !$threshold ){ - $threshold = 0.43; - } else { - $threshold = Less_Functions::number($threshold); - } - - if( $color->luma() < $threshold ){ - return $light; - } else { - return $dark; - } - } - - public function e ($str){ - if( is_string($str) ){ - return new Less_Tree_Anonymous($str); - } - return new Less_Tree_Anonymous($str instanceof Less_Tree_JavaScript ? $str->expression : $str->value); - } - - public function escape ($str){ - - $revert = array('%21'=>'!', '%2A'=>'*', '%27'=>"'",'%3F'=>'?','%26'=>'&','%2C'=>',','%2F'=>'/','%40'=>'@','%2B'=>'+','%24'=>'$'); - - return new Less_Tree_Anonymous(strtr(rawurlencode($str->value), $revert)); - } - - - /** - * todo: This function will need some additional work to make it work the same as less.js - * - */ - public function replace( $string, $pattern, $replacement, $flags = null ){ - $result = $string->value; - - $expr = '/'.str_replace('/','\\/',$pattern->value).'/'; - if( $flags && $flags->value){ - $expr .= self::replace_flags($flags->value); - } - - $result = preg_replace($expr,$replacement->value,$result); - - - if( property_exists($string,'quote') ){ - return new Less_Tree_Quoted( $string->quote, $result, $string->escaped); - } - return new Less_Tree_Quoted( '', $result ); - } - - public static function replace_flags($flags){ - $flags = str_split($flags,1); - $new_flags = ''; - - foreach($flags as $flag){ - switch($flag){ - case 'e': - case 'g': - break; - - default: - $new_flags .= $flag; - break; - } - } - - return $new_flags; - } - - public function _percent(){ - $string = func_get_arg(0); - - $args = func_get_args(); - array_shift($args); - $result = $string->value; - - foreach($args as $arg){ - if( preg_match('/%[sda]/i',$result, $token) ){ - $token = $token[0]; - $value = stristr($token, 's') ? $arg->value : $arg->toCSS(); - $value = preg_match('/[A-Z]$/', $token) ? urlencode($value) : $value; - $result = preg_replace('/%[sda]/i',$value, $result, 1); - } - } - $result = str_replace('%%', '%', $result); - - return new Less_Tree_Quoted( $string->quote , $result, $string->escaped); - } - - public function unit( $val, $unit = null) { - if( !($val instanceof Less_Tree_Dimension) ){ - throw new Less_Exception_Compiler('The first argument to unit must be a number' . ($val instanceof Less_Tree_Operation ? '. Have you forgotten parenthesis?' : '.') ); - } - - if( $unit ){ - if( $unit instanceof Less_Tree_Keyword ){ - $unit = $unit->value; - } else { - $unit = $unit->toCSS(); - } - } else { - $unit = ""; - } - return new Less_Tree_Dimension($val->value, $unit ); - } - - public function convert($val, $unit){ - return $val->convertTo($unit->value); - } - - public function round($n, $f = false) { - - $fraction = 0; - if( $f !== false ){ - $fraction = $f->value; - } - - return $this->_math('Less_Parser::round',null, $n, $fraction); - } - - public function pi(){ - return new Less_Tree_Dimension(M_PI); - } - - public function mod($a, $b) { - return new Less_Tree_Dimension( $a->value % $b->value, $a->unit); - } - - - - public function pow($x, $y) { - if( is_numeric($x) && is_numeric($y) ){ - $x = new Less_Tree_Dimension($x); - $y = new Less_Tree_Dimension($y); - }elseif( !($x instanceof Less_Tree_Dimension) || !($y instanceof Less_Tree_Dimension) ){ - throw new Less_Exception_Compiler('Arguments must be numbers'); - } - - return new Less_Tree_Dimension( pow($x->value, $y->value), $x->unit ); - } - - // var mathFunctions = [{name:"ce ... - public function ceil( $n ){ return $this->_math('ceil', null, $n); } - public function floor( $n ){ return $this->_math('floor', null, $n); } - public function sqrt( $n ){ return $this->_math('sqrt', null, $n); } - public function abs( $n ){ return $this->_math('abs', null, $n); } - - public function tan( $n ){ return $this->_math('tan', '', $n); } - public function sin( $n ){ return $this->_math('sin', '', $n); } - public function cos( $n ){ return $this->_math('cos', '', $n); } - - public function atan( $n ){ return $this->_math('atan', 'rad', $n); } - public function asin( $n ){ return $this->_math('asin', 'rad', $n); } - public function acos( $n ){ return $this->_math('acos', 'rad', $n); } - - private function _math() { - $args = func_get_args(); - $fn = array_shift($args); - $unit = array_shift($args); - - if ($args[0] instanceof Less_Tree_Dimension) { - - if( $unit === null ){ - $unit = $args[0]->unit; - }else{ - $args[0] = $args[0]->unify(); - } - $args[0] = (float)$args[0]->value; - return new Less_Tree_Dimension( call_user_func_array($fn, $args), $unit); - } else if (is_numeric($args[0])) { - return call_user_func_array($fn,$args); - } else { - throw new Less_Exception_Compiler("math functions take numbers as parameters"); - } - } - - /** - * @param boolean $isMin - */ - private function _minmax( $isMin, $args ){ - - $arg_count = count($args); - - if( $arg_count < 1 ){ - throw new Less_Exception_Compiler( 'one or more arguments required'); - } - - $j = null; - $unitClone = null; - $unitStatic = null; - - - $order = array(); // elems only contains original argument values. - $values = array(); // key is the unit.toString() for unified tree.Dimension values, - // value is the index into the order array. - - - for( $i = 0; $i < $arg_count; $i++ ){ - $current = $args[$i]; - if( !($current instanceof Less_Tree_Dimension) ){ - if( is_array($args[$i]->value) ){ - $args[] = $args[$i]->value; - } - continue; - } - - if( $current->unit->toString() === '' && !$unitClone ){ - $temp = new Less_Tree_Dimension($current->value, $unitClone); - $currentUnified = $temp->unify(); - }else{ - $currentUnified = $current->unify(); - } - - if( $currentUnified->unit->toString() === "" && !$unitStatic ){ - $unit = $unitStatic; - }else{ - $unit = $currentUnified->unit->toString(); - } - - if( $unit !== '' && !$unitStatic || $unit !== '' && $order[0]->unify()->unit->toString() === "" ){ - $unitStatic = $unit; - } - - if( $unit != '' && !$unitClone ){ - $unitClone = $current->unit->toString(); - } - - if( isset($values['']) && $unit !== '' && $unit === $unitStatic ){ - $j = $values['']; - }elseif( isset($values[$unit]) ){ - $j = $values[$unit]; - }else{ - - if( $unitStatic && $unit !== $unitStatic ){ - throw new Less_Exception_Compiler( 'incompatible types'); - } - $values[$unit] = count($order); - $order[] = $current; - continue; - } - - - if( $order[$j]->unit->toString() === "" && $unitClone ){ - $temp = new Less_Tree_Dimension( $order[$j]->value, $unitClone); - $referenceUnified = $temp->unify(); - }else{ - $referenceUnified = $order[$j]->unify(); - } - if( ($isMin && $currentUnified->value < $referenceUnified->value) || (!$isMin && $currentUnified->value > $referenceUnified->value) ){ - $order[$j] = $current; - } - } - - if( count($order) == 1 ){ - return $order[0]; - } - $args = array(); - foreach($order as $a){ - $args[] = $a->toCSS($this->env); - } - return new Less_Tree_Anonymous( ($isMin?'min(':'max(') . implode(Less_Environment::$_outputMap[','],$args).')'); - } - - public function min(){ - $args = func_get_args(); - return $this->_minmax( true, $args ); - } - - public function max(){ - $args = func_get_args(); - return $this->_minmax( false, $args ); - } - - public function getunit($n){ - return new Less_Tree_Anonymous($n->unit); - } - - public function argb($color) { - if (!$color instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The first argument to argb must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - - return new Less_Tree_Anonymous($color->toARGB()); - } - - public function percentage($n) { - return new Less_Tree_Dimension($n->value * 100, '%'); - } - - public function color($n) { - - if( $n instanceof Less_Tree_Quoted ){ - $colorCandidate = $n->value; - $returnColor = Less_Tree_Color::fromKeyword($colorCandidate); - if( $returnColor ){ - return $returnColor; - } - if( preg_match('/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/',$colorCandidate) ){ - return new Less_Tree_Color(substr($colorCandidate, 1)); - } - throw new Less_Exception_Compiler("argument must be a color keyword or 3/6 digit hex e.g. #FFF"); - } else { - throw new Less_Exception_Compiler("argument must be a string"); - } - } - - - public function iscolor($n) { - return $this->_isa($n, 'Less_Tree_Color'); - } - - public function isnumber($n) { - return $this->_isa($n, 'Less_Tree_Dimension'); - } - - public function isstring($n) { - return $this->_isa($n, 'Less_Tree_Quoted'); - } - - public function iskeyword($n) { - return $this->_isa($n, 'Less_Tree_Keyword'); - } - - public function isurl($n) { - return $this->_isa($n, 'Less_Tree_Url'); - } - - public function ispixel($n) { - return $this->isunit($n, 'px'); - } - - public function ispercentage($n) { - return $this->isunit($n, '%'); - } - - public function isem($n) { - return $this->isunit($n, 'em'); - } - - /** - * @param string $unit - */ - public function isunit( $n, $unit ){ - - if( is_object($unit) && property_exists($unit,'value') ){ - $unit = $unit->value; - } - - return ($n instanceof Less_Tree_Dimension) && $n->unit->is($unit) ? new Less_Tree_Keyword('true') : new Less_Tree_Keyword('false'); - } - - /** - * @param string $type - */ - private function _isa($n, $type) { - return is_a($n, $type) ? new Less_Tree_Keyword('true') : new Less_Tree_Keyword('false'); - } - - public function tint($color, $amount = null) { - return $this->mix( $this->rgb(255,255,255), $color, $amount); - } - - public function shade($color, $amount = null) { - return $this->mix($this->rgb(0, 0, 0), $color, $amount); - } - - public function extract($values, $index ){ - $index = (int)$index->value - 1; // (1-based index) - // handle non-array values as an array of length 1 - // return 'undefined' if index is invalid - if( property_exists($values,'value') && is_array($values->value) ){ - if( isset($values->value[$index]) ){ - return $values->value[$index]; - } - return null; - - }elseif( (int)$index === 0 ){ - return $values; - } - - return null; - } - - public function length($values){ - $n = (property_exists($values,'value') && is_array($values->value)) ? count($values->value) : 1; - return new Less_Tree_Dimension($n); - } - - public function datauri($mimetypeNode, $filePathNode = null ) { - - $filePath = ( $filePathNode ? $filePathNode->value : null ); - $mimetype = $mimetypeNode->value; - - $args = 2; - if( !$filePath ){ - $filePath = $mimetype; - $args = 1; - } - - $filePath = str_replace('\\','/',$filePath); - if( Less_Environment::isPathRelative($filePath) ){ - - if( Less_Parser::$options['relativeUrls'] ){ - $temp = $this->currentFileInfo['currentDirectory']; - } else { - $temp = $this->currentFileInfo['entryPath']; - } - - if( !empty($temp) ){ - $filePath = Less_Environment::normalizePath(rtrim($temp,'/').'/'.$filePath); - } - - } - - - // detect the mimetype if not given - if( $args < 2 ){ - - /* incomplete - $mime = require('mime'); - mimetype = mime.lookup(path); - - // use base 64 unless it's an ASCII or UTF-8 format - var charset = mime.charsets.lookup(mimetype); - useBase64 = ['US-ASCII', 'UTF-8'].indexOf(charset) < 0; - if (useBase64) mimetype += ';base64'; - */ - - $mimetype = Less_Mime::lookup($filePath); - - $charset = Less_Mime::charsets_lookup($mimetype); - $useBase64 = !in_array($charset,array('US-ASCII', 'UTF-8')); - if( $useBase64 ){ $mimetype .= ';base64'; } - - }else{ - $useBase64 = preg_match('/;base64$/',$mimetype); - } - - - if( file_exists($filePath) ){ - $buf = @file_get_contents($filePath); - }else{ - $buf = false; - } - - - // IE8 cannot handle a data-uri larger than 32KB. If this is exceeded - // and the --ieCompat flag is enabled, return a normal url() instead. - $DATA_URI_MAX_KB = 32; - $fileSizeInKB = round( strlen($buf) / 1024 ); - if( $fileSizeInKB >= $DATA_URI_MAX_KB ){ - $url = new Less_Tree_Url( ($filePathNode ? $filePathNode : $mimetypeNode), $this->currentFileInfo); - return $url->compile($this); - } - - if( $buf ){ - $buf = $useBase64 ? base64_encode($buf) : rawurlencode($buf); - $filePath = '"data:' . $mimetype . ',' . $buf . '"'; - } - - return new Less_Tree_Url( new Less_Tree_Anonymous($filePath) ); - } - - //svg-gradient - public function svggradient( $direction ){ - - $throw_message = 'svg-gradient expects direction, start_color [start_position], [color position,]..., end_color [end_position]'; - $arguments = func_get_args(); - - if( count($arguments) < 3 ){ - throw new Less_Exception_Compiler( $throw_message ); - } - - $stops = array_slice($arguments,1); - $gradientType = 'linear'; - $rectangleDimension = 'x="0" y="0" width="1" height="1"'; - $useBase64 = true; - $directionValue = $direction->toCSS(); - - - switch( $directionValue ){ - case "to bottom": - $gradientDirectionSvg = 'x1="0%" y1="0%" x2="0%" y2="100%"'; - break; - case "to right": - $gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="0%"'; - break; - case "to bottom right": - $gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="100%"'; - break; - case "to top right": - $gradientDirectionSvg = 'x1="0%" y1="100%" x2="100%" y2="0%"'; - break; - case "ellipse": - case "ellipse at center": - $gradientType = "radial"; - $gradientDirectionSvg = 'cx="50%" cy="50%" r="75%"'; - $rectangleDimension = 'x="-50" y="-50" width="101" height="101"'; - break; - default: - throw new Less_Exception_Compiler( "svg-gradient direction must be 'to bottom', 'to right', 'to bottom right', 'to top right' or 'ellipse at center'" ); - } - - $returner = '' . - '' . - '<' . $gradientType . 'Gradient id="gradient" gradientUnits="userSpaceOnUse" ' . $gradientDirectionSvg . '>'; - - for( $i = 0; $i < count($stops); $i++ ){ - if( is_object($stops[$i]) && property_exists($stops[$i],'value') ){ - $color = $stops[$i]->value[0]; - $position = $stops[$i]->value[1]; - }else{ - $color = $stops[$i]; - $position = null; - } - - if( !($color instanceof Less_Tree_Color) || (!(($i === 0 || $i+1 === count($stops)) && $position === null) && !($position instanceof Less_Tree_Dimension)) ){ - throw new Less_Exception_Compiler( $throw_message ); - } - if( $position ){ - $positionValue = $position->toCSS(); - }elseif( $i === 0 ){ - $positionValue = '0%'; - }else{ - $positionValue = '100%'; - } - $alpha = $color->alpha; - $returner .= ''; - } - - $returner .= ''; - - - if( $useBase64 ){ - $returner = "'data:image/svg+xml;base64,".base64_encode($returner)."'"; - }else{ - $returner = "'data:image/svg+xml,".$returner."'"; - } - - return new Less_Tree_URL( new Less_Tree_Anonymous( $returner ) ); - } - - - /** - * Php version of javascript's `encodeURIComponent` function - * - * @param string $string The string to encode - * @return string The encoded string - */ - public static function encodeURIComponent($string){ - $revert = array('%21' => '!', '%2A' => '*', '%27' => "'", '%28' => '(', '%29' => ')'); - return strtr(rawurlencode($string), $revert); - } - - - // Color Blending - // ref: http://www.w3.org/TR/compositing-1 - - public function colorBlend( $mode, $color1, $color2 ){ - $ab = $color1->alpha; // backdrop - $as = $color2->alpha; // source - $r = array(); // result - - $ar = $as + $ab * (1 - $as); - for( $i = 0; $i < 3; $i++ ){ - $cb = $color1->rgb[$i] / 255; - $cs = $color2->rgb[$i] / 255; - $cr = call_user_func( $mode, $cb, $cs ); - if( $ar ){ - $cr = ($as * $cs + $ab * ($cb - $as * ($cb + $cs - $cr))) / $ar; - } - $r[$i] = $cr * 255; - } - - return new Less_Tree_Color($r, $ar); - } - - public function multiply($color1 = null, $color2 = null ){ - if (!$color1 instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The first argument to multiply must be a color' . ($color1 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - if (!$color2 instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The second argument to multiply must be a color' . ($color2 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - - return $this->colorBlend( array($this,'colorBlendMultiply'), $color1, $color2 ); - } - - private function colorBlendMultiply($cb, $cs){ - return $cb * $cs; - } - - public function screen($color1 = null, $color2 = null ){ - if (!$color1 instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The first argument to screen must be a color' . ($color1 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - if (!$color2 instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The second argument to screen must be a color' . ($color2 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - - return $this->colorBlend( array($this,'colorBlendScreen'), $color1, $color2 ); - } - - private function colorBlendScreen( $cb, $cs){ - return $cb + $cs - $cb * $cs; - } - - public function overlay($color1 = null, $color2 = null){ - if (!$color1 instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The first argument to overlay must be a color' . ($color1 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - if (!$color2 instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The second argument to overlay must be a color' . ($color2 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - - return $this->colorBlend( array($this,'colorBlendOverlay'), $color1, $color2 ); - } - - private function colorBlendOverlay($cb, $cs ){ - $cb *= 2; - return ($cb <= 1) - ? $this->colorBlendMultiply($cb, $cs) - : $this->colorBlendScreen($cb - 1, $cs); - } - - public function softlight($color1 = null, $color2 = null){ - if (!$color1 instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The first argument to softlight must be a color' . ($color1 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - if (!$color2 instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The second argument to softlight must be a color' . ($color2 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - - return $this->colorBlend( array($this,'colorBlendSoftlight'), $color1, $color2 ); - } - - private function colorBlendSoftlight($cb, $cs ){ - $d = 1; - $e = $cb; - if( $cs > 0.5 ){ - $e = 1; - $d = ($cb > 0.25) ? sqrt($cb) - : ((16 * $cb - 12) * $cb + 4) * $cb; - } - return $cb - (1 - 2 * $cs) * $e * ($d - $cb); - } - - public function hardlight($color1 = null, $color2 = null){ - if (!$color1 instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The first argument to hardlight must be a color' . ($color1 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - if (!$color2 instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The second argument to hardlight must be a color' . ($color2 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - - return $this->colorBlend( array($this,'colorBlendHardlight'), $color1, $color2 ); - } - - private function colorBlendHardlight( $cb, $cs ){ - return $this->colorBlendOverlay($cs, $cb); - } - - public function difference($color1 = null, $color2 = null) { - if (!$color1 instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The first argument to difference must be a color' . ($color1 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - if (!$color2 instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The second argument to difference must be a color' . ($color2 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - - return $this->colorBlend( array($this,'colorBlendDifference'), $color1, $color2 ); - } - - private function colorBlendDifference( $cb, $cs ){ - return abs($cb - $cs); - } - - public function exclusion( $color1 = null, $color2 = null ){ - if (!$color1 instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The first argument to exclusion must be a color' . ($color1 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - if (!$color2 instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The second argument to exclusion must be a color' . ($color2 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - - return $this->colorBlend( array($this,'colorBlendExclusion'), $color1, $color2 ); - } - - private function colorBlendExclusion( $cb, $cs ){ - return $cb + $cs - 2 * $cb * $cs; - } - - public function average($color1 = null, $color2 = null){ - if (!$color1 instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The first argument to average must be a color' . ($color1 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - if (!$color2 instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The second argument to average must be a color' . ($color2 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - - return $this->colorBlend( array($this,'colorBlendAverage'), $color1, $color2 ); - } - - // non-w3c functions: - public function colorBlendAverage($cb, $cs ){ - return ($cb + $cs) / 2; - } - - public function negation($color1 = null, $color2 = null ){ - if (!$color1 instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The first argument to negation must be a color' . ($color1 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - if (!$color2 instanceof Less_Tree_Color) { - throw new Less_Exception_Compiler('The second argument to negation must be a color' . ($color2 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') ); - } - - return $this->colorBlend( array($this,'colorBlendNegation'), $color1, $color2 ); - } - - public function colorBlendNegation($cb, $cs){ - return 1 - abs($cb + $cs - 1); - } - - // ~ End of Color Blending - -} diff --git a/vendor/oyejorge/less.php/lib/Less/Less.php.combine b/vendor/oyejorge/less.php/lib/Less/Less.php.combine deleted file mode 100644 index d63cc78..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Less.php.combine +++ /dev/null @@ -1,17 +0,0 @@ - -./Parser.php -./Colors.php -./Environment.php -./Functions.php -./Mime.php -./Tree.php -./Output.php -./Visitor.php -./VisitorReplacing.php -./Configurable.php -./Tree -./Visitor -./Exception/Parser.php -./Exception/ -./Output -./SourceMap diff --git a/vendor/oyejorge/less.php/lib/Less/Mime.php b/vendor/oyejorge/less.php/lib/Less/Mime.php deleted file mode 100644 index 109ecd3..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Mime.php +++ /dev/null @@ -1,41 +0,0 @@ - 'text/html', - '.html'=> 'text/html', - '.gif' => 'image/gif', - '.jpg' => 'image/jpeg', - '.jpeg'=> 'image/jpeg', - '.png' => 'image/png', - '.ttf' => 'application/x-font-ttf', - '.otf' => 'application/x-font-otf', - '.eot' => 'application/vnd.ms-fontobject', - '.woff' => 'application/x-font-woff', - '.svg' => 'image/svg+xml', - ); - - public static function lookup( $filepath ){ - $parts = explode('.',$filepath); - $ext = '.'.strtolower(array_pop($parts)); - - if( !isset(self::$_types[$ext]) ){ - return null; - } - return self::$_types[$ext]; - } - - public static function charsets_lookup( $type = null ){ - // assumes all text types are UTF-8 - return $type && preg_match('/^text\//',$type) ? 'UTF-8' : ''; - } -} diff --git a/vendor/oyejorge/less.php/lib/Less/Output.php b/vendor/oyejorge/less.php/lib/Less/Output.php deleted file mode 100644 index f1b2b2a..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Output.php +++ /dev/null @@ -1,49 +0,0 @@ -strs[] = $chunk; - } - - /** - * Is the output empty? - * - * @return boolean - */ - public function isEmpty(){ - return count($this->strs) === 0; - } - - - /** - * Converts the output to string - * - * @return string - */ - public function toString(){ - return implode('',$this->strs); - } - -} \ No newline at end of file diff --git a/vendor/oyejorge/less.php/lib/Less/Output/Mapped.php b/vendor/oyejorge/less.php/lib/Less/Output/Mapped.php deleted file mode 100644 index 884490a..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Output/Mapped.php +++ /dev/null @@ -1,122 +0,0 @@ -contentsMap = $contentsMap; - $this->generator = $generator; - } - - /** - * Adds a chunk to the stack - * The $index for less.php may be different from less.js since less.php does not chunkify inputs - * - * @param string $chunk - * @param string $fileInfo - * @param integer $index - * @param mixed $mapLines - */ - public function add($chunk, $fileInfo = null, $index = 0, $mapLines = null){ - - //ignore adding empty strings - if( $chunk === '' ){ - return; - } - - - $sourceLines = array(); - $sourceColumns = ' '; - - - if( $fileInfo ){ - - $url = $fileInfo['currentUri']; - - if( isset($this->contentsMap[$url]) ){ - $inputSource = substr($this->contentsMap[$url], 0, $index); - $sourceLines = explode("\n", $inputSource); - $sourceColumns = end($sourceLines); - }else{ - throw new Exception('Filename '.$url.' not in contentsMap'); - } - - } - - $lines = explode("\n", $chunk); - $columns = end($lines); - - if($fileInfo){ - - if(!$mapLines){ - $this->generator->addMapping( - $this->lineNumber + 1, // generated_line - $this->column, // generated_column - count($sourceLines), // original_line - strlen($sourceColumns), // original_column - $fileInfo - ); - }else{ - for($i = 0, $count = count($lines); $i < $count; $i++){ - $this->generator->addMapping( - $this->lineNumber + $i + 1, // generated_line - $i === 0 ? $this->column : 0, // generated_column - count($sourceLines) + $i, // original_line - $i === 0 ? strlen($sourceColumns) : 0, // original_column - $fileInfo - ); - } - } - } - - if(count($lines) === 1){ - $this->column += strlen($columns); - }else{ - $this->lineNumber += count($lines) - 1; - $this->column = strlen($columns); - } - - // add only chunk - parent::add($chunk); - } - -} \ No newline at end of file diff --git a/vendor/oyejorge/less.php/lib/Less/Parser.php b/vendor/oyejorge/less.php/lib/Less/Parser.php deleted file mode 100644 index 2c9d879..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Parser.php +++ /dev/null @@ -1,2816 +0,0 @@ - false, // option - whether to compress - 'strictUnits' => false, // whether units need to evaluate correctly - 'strictMath' => false, // whether math has to be within parenthesis - 'relativeUrls' => true, // option - whether to adjust URL's to be relative - 'urlArgs' => '', // whether to add args into url tokens - 'numPrecision' => 8, - - 'import_dirs' => array(), - 'import_callback' => null, - 'cache_dir' => null, - 'cache_method' => 'php', // false, 'serialize', 'php', 'var_export', 'callback'; - 'cache_callback_get' => null, - 'cache_callback_set' => null, - - 'sourceMap' => false, // whether to output a source map - 'sourceMapBasepath' => null, - 'sourceMapWriteTo' => null, - 'sourceMapURL' => null, - - 'indentation' => ' ', - - 'plugins' => array(), - - ); - - public static $options = array(); - - - private $input; // Less input string - private $input_len; // input string length - private $pos; // current index in `input` - private $saveStack = array(); // holds state for backtracking - private $furthest; - private $mb_internal_encoding = ''; // for remember exists value of mbstring.internal_encoding - - /** - * @var Less_Environment - */ - private $env; - - protected $rules = array(); - - private static $imports = array(); - - public static $has_extends = false; - - public static $next_id = 0; - - /** - * Filename to contents of all parsed the files - * - * @var array - */ - public static $contentsMap = array(); - - - /** - * @param Less_Environment|array|null $env - */ - public function __construct( $env = null ){ - - // Top parser on an import tree must be sure there is one "env" - // which will then be passed around by reference. - if( $env instanceof Less_Environment ){ - $this->env = $env; - }else{ - $this->SetOptions(Less_Parser::$default_options); - $this->Reset( $env ); - } - - // mbstring.func_overload > 1 bugfix - // The encoding value must be set for each source file, - // therefore, to conserve resources and improve the speed of this design is taken here - if (ini_get('mbstring.func_overload')) { - $this->mb_internal_encoding = ini_get('mbstring.internal_encoding'); - @ini_set('mbstring.internal_encoding', 'ascii'); - } - - } - - - /** - * Reset the parser state completely - * - */ - public function Reset( $options = null ){ - $this->rules = array(); - self::$imports = array(); - self::$has_extends = false; - self::$imports = array(); - self::$contentsMap = array(); - - $this->env = new Less_Environment($options); - - //set new options - if( is_array($options) ){ - $this->SetOptions(Less_Parser::$default_options); - $this->SetOptions($options); - } - - $this->env->Init(); - } - - /** - * Set one or more compiler options - * options: import_dirs, cache_dir, cache_method - * - */ - public function SetOptions( $options ){ - foreach($options as $option => $value){ - $this->SetOption($option,$value); - } - } - - /** - * Set one compiler option - * - */ - public function SetOption($option,$value){ - - switch($option){ - - case 'import_dirs': - $this->SetImportDirs($value); - return; - - case 'cache_dir': - if( is_string($value) ){ - Less_Cache::SetCacheDir($value); - Less_Cache::CheckCacheDir(); - } - return; - } - - Less_Parser::$options[$option] = $value; - } - - /** - * Registers a new custom function - * - * @param string $name function name - * @param callable $callback callback - */ - public function registerFunction($name, $callback) { - $this->env->functions[$name] = $callback; - } - - /** - * Removed an already registered function - * - * @param string $name function name - */ - public function unregisterFunction($name) { - if( isset($this->env->functions[$name]) ) - unset($this->env->functions[$name]); - } - - - /** - * Get the current css buffer - * - * @return string - */ - public function getCss(){ - - $precision = ini_get('precision'); - @ini_set('precision',16); - $locale = setlocale(LC_NUMERIC, 0); - setlocale(LC_NUMERIC, "C"); - - try { - - $root = new Less_Tree_Ruleset(array(), $this->rules ); - $root->root = true; - $root->firstRoot = true; - - - $this->PreVisitors($root); - - self::$has_extends = false; - $evaldRoot = $root->compile($this->env); - - - - $this->PostVisitors($evaldRoot); - - if( Less_Parser::$options['sourceMap'] ){ - $generator = new Less_SourceMap_Generator($evaldRoot, Less_Parser::$contentsMap, Less_Parser::$options ); - // will also save file - // FIXME: should happen somewhere else? - $css = $generator->generateCSS(); - }else{ - $css = $evaldRoot->toCSS(); - } - - if( Less_Parser::$options['compress'] ){ - $css = preg_replace('/(^(\s)+)|((\s)+$)/', '', $css); - } - - } catch (Exception $exc) { - // Intentional fall-through so we can reset environment - } - - //reset php settings - @ini_set('precision',$precision); - setlocale(LC_NUMERIC, $locale); - - // If you previously defined $this->mb_internal_encoding - // is required to return the encoding as it was before - if ($this->mb_internal_encoding != '') { - @ini_set("mbstring.internal_encoding", $this->mb_internal_encoding); - $this->mb_internal_encoding = ''; - } - - // Rethrow exception after we handled resetting the environment - if (!empty($exc)) { - throw $exc; - } - - return $css; - } - - public function findValueOf($varName) - { - foreach($this->rules as $rule){ - if(isset($rule->variable) && ($rule->variable == true) && (str_replace("@","",$rule->name) == $varName)){ - return $this->getVariableValue($rule); - } - } - return null; - } - - /** - * - * this function gets the private rules variable and returns an array of the found variables - * it uses a helper method getVariableValue() that contains the logic ot fetch the value from the rule object - * - * @return array - */ - public function getVariables() - { - $variables = array(); - - $not_variable_type = array( - 'Comment', // this include less comments ( // ) and css comments (/* */) - 'Import', // do not search variables in included files @import - 'Ruleset', // selectors (.someclass, #someid, …) - 'Operation', // - ); - - // @TODO run compilation if not runned yet - foreach ($this->rules as $key => $rule) { - if (in_array($rule->type, $not_variable_type)) { - continue; - } - - // Note: it seems rule->type is always Rule when variable = true - if ($rule->type == 'Rule' && $rule->variable) { - $variables[$rule->name] = $this->getVariableValue($rule); - } else { - if ($rule->type == 'Comment') { - $variables[] = $this->getVariableValue($rule); - } - } - } - return $variables; - } - - public function findVarByName($var_name) - { - foreach($this->rules as $rule){ - if(isset($rule->variable) && ($rule->variable == true)){ - if($rule->name == $var_name){ - return $this->getVariableValue($rule); - } - } - } - return null; - } - - /** - * - * This method gets the value of the less variable from the rules object. - * Since the objects vary here we add the logic for extracting the css/less value. - * - * @param $var - * - * @return bool|string - */ - private function getVariableValue($var) - { - if (!is_a($var, 'Less_Tree')) { - throw new Exception('var is not a Less_Tree object'); - } - - switch ($var->type) { - case 'Color': - return $this->rgb2html($var->rgb); - case 'Unit': - return $var->value. $var->unit->numerator[0]; - case 'Variable': - return $this->findVarByName($var->name); - case 'Keyword': - return $var->value; - case 'Rule': - return $this->getVariableValue($var->value); - case 'Value': - $value = ''; - foreach ($var->value as $sub_value) { - $value .= $this->getVariableValue($sub_value).' '; - } - return $value; - case 'Quoted': - return $var->quote.$var->value.$var->quote; - case 'Dimension': - $value = $var->value; - if ($var->unit && $var->unit->numerator) { - $value .= $var->unit->numerator[0]; - } - return $value; - case 'Expression': - $value = ""; - foreach($var->value as $item) { - $value .= $this->getVariableValue($item)." "; - } - return $value; - case 'Operation': - throw new Exception('getVariables() require Less to be compiled. please use $parser->getCss() before calling getVariables()'); - case 'Comment': - case 'Import': - case 'Ruleset': - default: - throw new Exception("type missing in switch/case getVariableValue for ".$var->type); - } - return false; - } - - private function rgb2html($r, $g=-1, $b=-1) - { - if (is_array($r) && sizeof($r) == 3) - list($r, $g, $b) = $r; - - $r = intval($r); $g = intval($g); - $b = intval($b); - - $r = dechex($r<0?0:($r>255?255:$r)); - $g = dechex($g<0?0:($g>255?255:$g)); - $b = dechex($b<0?0:($b>255?255:$b)); - - $color = (strlen($r) < 2?'0':'').$r; - $color .= (strlen($g) < 2?'0':'').$g; - $color .= (strlen($b) < 2?'0':'').$b; - return '#'.$color; - } - - /** - * Run pre-compile visitors - * - */ - private function PreVisitors($root){ - - if( Less_Parser::$options['plugins'] ){ - foreach(Less_Parser::$options['plugins'] as $plugin){ - if( !empty($plugin->isPreEvalVisitor) ){ - $plugin->run($root); - } - } - } - } - - - /** - * Run post-compile visitors - * - */ - private function PostVisitors($evaldRoot){ - - $visitors = array(); - $visitors[] = new Less_Visitor_joinSelector(); - if( self::$has_extends ){ - $visitors[] = new Less_Visitor_processExtends(); - } - $visitors[] = new Less_Visitor_toCSS(); - - - if( Less_Parser::$options['plugins'] ){ - foreach(Less_Parser::$options['plugins'] as $plugin){ - if( property_exists($plugin,'isPreEvalVisitor') && $plugin->isPreEvalVisitor ){ - continue; - } - - if( property_exists($plugin,'isPreVisitor') && $plugin->isPreVisitor ){ - array_unshift( $visitors, $plugin); - }else{ - $visitors[] = $plugin; - } - } - } - - - for($i = 0; $i < count($visitors); $i++ ){ - $visitors[$i]->run($evaldRoot); - } - - } - - - /** - * Parse a Less string into css - * - * @param string $str The string to convert - * @param string $uri_root The url of the file - * @return Less_Tree_Ruleset|Less_Parser - */ - public function parse( $str, $file_uri = null ){ - - if( !$file_uri ){ - $uri_root = ''; - $filename = 'anonymous-file-'.Less_Parser::$next_id++.'.less'; - }else{ - $file_uri = self::WinPath($file_uri); - $filename = $file_uri; - $uri_root = dirname($file_uri); - } - - $previousFileInfo = $this->env->currentFileInfo; - $uri_root = self::WinPath($uri_root); - $this->SetFileInfo($filename, $uri_root); - - $this->input = $str; - $this->_parse(); - - if( $previousFileInfo ){ - $this->env->currentFileInfo = $previousFileInfo; - } - - return $this; - } - - - /** - * Parse a Less string from a given file - * - * @throws Less_Exception_Parser - * @param string $filename The file to parse - * @param string $uri_root The url of the file - * @param bool $returnRoot Indicates whether the return value should be a css string a root node - * @return Less_Tree_Ruleset|Less_Parser - */ - public function parseFile( $filename, $uri_root = '', $returnRoot = false){ - - if( !file_exists($filename) ){ - $this->Error(sprintf('File `%s` not found.', $filename)); - } - - - // fix uri_root? - // Instead of The mixture of file path for the first argument and directory path for the second argument has bee - if( !$returnRoot && !empty($uri_root) && basename($uri_root) == basename($filename) ){ - $uri_root = dirname($uri_root); - } - - - $previousFileInfo = $this->env->currentFileInfo; - - - if( $filename ){ - $filename = self::AbsPath($filename, true); - } - $uri_root = self::WinPath($uri_root); - - $this->SetFileInfo($filename, $uri_root); - - self::AddParsedFile($filename); - - if( $returnRoot ){ - $rules = $this->GetRules( $filename ); - $return = new Less_Tree_Ruleset(array(), $rules ); - }else{ - $this->_parse( $filename ); - $return = $this; - } - - if( $previousFileInfo ){ - $this->env->currentFileInfo = $previousFileInfo; - } - - return $return; - } - - - /** - * Allows a user to set variables values - * @param array $vars - * @return Less_Parser - */ - public function ModifyVars( $vars ){ - - $this->input = Less_Parser::serializeVars( $vars ); - $this->_parse(); - - return $this; - } - - - /** - * @param string $filename - */ - public function SetFileInfo( $filename, $uri_root = ''){ - - $filename = Less_Environment::normalizePath($filename); - $dirname = preg_replace('/[^\/\\\\]*$/','',$filename); - - if( !empty($uri_root) ){ - $uri_root = rtrim($uri_root,'/').'/'; - } - - $currentFileInfo = array(); - - //entry info - if( isset($this->env->currentFileInfo) ){ - $currentFileInfo['entryPath'] = $this->env->currentFileInfo['entryPath']; - $currentFileInfo['entryUri'] = $this->env->currentFileInfo['entryUri']; - $currentFileInfo['rootpath'] = $this->env->currentFileInfo['rootpath']; - - }else{ - $currentFileInfo['entryPath'] = $dirname; - $currentFileInfo['entryUri'] = $uri_root; - $currentFileInfo['rootpath'] = $dirname; - } - - $currentFileInfo['currentDirectory'] = $dirname; - $currentFileInfo['currentUri'] = $uri_root.basename($filename); - $currentFileInfo['filename'] = $filename; - $currentFileInfo['uri_root'] = $uri_root; - - - //inherit reference - if( isset($this->env->currentFileInfo['reference']) && $this->env->currentFileInfo['reference'] ){ - $currentFileInfo['reference'] = true; - } - - $this->env->currentFileInfo = $currentFileInfo; - } - - - /** - * @deprecated 1.5.1.2 - * - */ - public function SetCacheDir( $dir ){ - - if( !file_exists($dir) ){ - if( mkdir($dir) ){ - return true; - } - throw new Less_Exception_Parser('Less.php cache directory couldn\'t be created: '.$dir); - - }elseif( !is_dir($dir) ){ - throw new Less_Exception_Parser('Less.php cache directory doesn\'t exist: '.$dir); - - }elseif( !is_writable($dir) ){ - throw new Less_Exception_Parser('Less.php cache directory isn\'t writable: '.$dir); - - }else{ - $dir = self::WinPath($dir); - Less_Cache::$cache_dir = rtrim($dir,'/').'/'; - return true; - } - } - - - /** - * Set a list of directories or callbacks the parser should use for determining import paths - * - * @param array $dirs - */ - public function SetImportDirs( $dirs ){ - Less_Parser::$options['import_dirs'] = array(); - - foreach($dirs as $path => $uri_root){ - - $path = self::WinPath($path); - if( !empty($path) ){ - $path = rtrim($path,'/').'/'; - } - - if ( !is_callable($uri_root) ){ - $uri_root = self::WinPath($uri_root); - if( !empty($uri_root) ){ - $uri_root = rtrim($uri_root,'/').'/'; - } - } - - Less_Parser::$options['import_dirs'][$path] = $uri_root; - } - } - - /** - * @param string $file_path - */ - private function _parse( $file_path = null ){ - $this->rules = array_merge($this->rules, $this->GetRules( $file_path )); - } - - - /** - * Return the results of parsePrimary for $file_path - * Use cache and save cached results if possible - * - * @param string|null $file_path - */ - private function GetRules( $file_path ){ - - $this->SetInput($file_path); - - $cache_file = $this->CacheFile( $file_path ); - if( $cache_file ){ - if( Less_Parser::$options['cache_method'] == 'callback' ){ - if( is_callable(Less_Parser::$options['cache_callback_get']) ){ - $cache = call_user_func_array( - Less_Parser::$options['cache_callback_get'], - array($this, $file_path, $cache_file) - ); - - if( $cache ){ - $this->UnsetInput(); - return $cache; - } - } - - }elseif( file_exists($cache_file) ){ - switch(Less_Parser::$options['cache_method']){ - - // Using serialize - // Faster but uses more memory - case 'serialize': - $cache = unserialize(file_get_contents($cache_file)); - if( $cache ){ - touch($cache_file); - $this->UnsetInput(); - return $cache; - } - break; - - - // Using generated php code - case 'var_export': - case 'php': - $this->UnsetInput(); - return include($cache_file); - } - } - } - - $rules = $this->parsePrimary(); - - if( $this->pos < $this->input_len ){ - throw new Less_Exception_Chunk($this->input, null, $this->furthest, $this->env->currentFileInfo); - } - - $this->UnsetInput(); - - - //save the cache - if( $cache_file ){ - if( Less_Parser::$options['cache_method'] == 'callback' ){ - if( is_callable(Less_Parser::$options['cache_callback_set']) ){ - call_user_func_array( - Less_Parser::$options['cache_callback_set'], - array($this, $file_path, $cache_file, $rules) - ); - } - - }else{ - //msg('write cache file'); - switch(Less_Parser::$options['cache_method']){ - case 'serialize': - file_put_contents( $cache_file, serialize($rules) ); - break; - case 'php': - file_put_contents( $cache_file, '' ); - break; - case 'var_export': - //Requires __set_state() - file_put_contents( $cache_file, '' ); - break; - } - - Less_Cache::CleanCache(); - } - } - - return $rules; - } - - - /** - * Set up the input buffer - * - */ - public function SetInput( $file_path ){ - - if( $file_path ){ - $this->input = file_get_contents( $file_path ); - } - - $this->pos = $this->furthest = 0; - - // Remove potential UTF Byte Order Mark - $this->input = preg_replace('/\\G\xEF\xBB\xBF/', '', $this->input); - $this->input_len = strlen($this->input); - - - if( Less_Parser::$options['sourceMap'] && $this->env->currentFileInfo ){ - $uri = $this->env->currentFileInfo['currentUri']; - Less_Parser::$contentsMap[$uri] = $this->input; - } - - } - - - /** - * Free up some memory - * - */ - public function UnsetInput(){ - unset($this->input, $this->pos, $this->input_len, $this->furthest); - $this->saveStack = array(); - } - - - public function CacheFile( $file_path ){ - - if( $file_path && $this->CacheEnabled() ){ - - $env = get_object_vars($this->env); - unset($env['frames']); - - $parts = array(); - $parts[] = $file_path; - $parts[] = filesize( $file_path ); - $parts[] = filemtime( $file_path ); - $parts[] = $env; - $parts[] = Less_Version::cache_version; - $parts[] = Less_Parser::$options['cache_method']; - return Less_Cache::$cache_dir . Less_Cache::$prefix . base_convert( sha1(json_encode($parts) ), 16, 36) . '.lesscache'; - } - } - - - static function AddParsedFile($file){ - self::$imports[] = $file; - } - - static function AllParsedFiles(){ - return self::$imports; - } - - /** - * @param string $file - */ - static function FileParsed($file){ - return in_array($file,self::$imports); - } - - - function save() { - $this->saveStack[] = $this->pos; - } - - private function restore() { - $this->pos = array_pop($this->saveStack); - } - - private function forget(){ - array_pop($this->saveStack); - } - - /** - * Determine if the character at the specified offset from the current position is a white space. - * - * @param int $offset - * - * @return bool - */ - private function isWhitespace($offset = 0) { - return strpos(" \t\n\r\v\f", $this->input[$this->pos + $offset]) !== false; - } - - /** - * Parse from a token, regexp or string, and move forward if match - * - * @param array $toks - * @return array - */ - private function match($toks){ - - // The match is confirmed, add the match length to `this::pos`, - // and consume any extra white-space characters (' ' || '\n') - // which come after that. The reason for this is that LeSS's - // grammar is mostly white-space insensitive. - // - - foreach($toks as $tok){ - - $char = $tok[0]; - - if( $char === '/' ){ - $match = $this->MatchReg($tok); - - if( $match ){ - return count($match) === 1 ? $match[0] : $match; - } - - }elseif( $char === '#' ){ - $match = $this->MatchChar($tok[1]); - - }else{ - // Non-terminal, match using a function call - $match = $this->$tok(); - - } - - if( $match ){ - return $match; - } - } - } - - /** - * @param string[] $toks - * - * @return string - */ - private function MatchFuncs($toks){ - - if( $this->pos < $this->input_len ){ - foreach($toks as $tok){ - $match = $this->$tok(); - if( $match ){ - return $match; - } - } - } - - } - - // Match a single character in the input, - private function MatchChar($tok){ - if( ($this->pos < $this->input_len) && ($this->input[$this->pos] === $tok) ){ - $this->skipWhitespace(1); - return $tok; - } - } - - // Match a regexp from the current start point - private function MatchReg($tok){ - - if( preg_match($tok, $this->input, $match, 0, $this->pos) ){ - $this->skipWhitespace(strlen($match[0])); - return $match; - } - } - - - /** - * Same as match(), but don't change the state of the parser, - * just return the match. - * - * @param string $tok - * @return integer - */ - public function PeekReg($tok){ - return preg_match($tok, $this->input, $match, 0, $this->pos); - } - - /** - * @param string $tok - */ - public function PeekChar($tok){ - //return ($this->input[$this->pos] === $tok ); - return ($this->pos < $this->input_len) && ($this->input[$this->pos] === $tok ); - } - - - /** - * @param integer $length - */ - public function skipWhitespace($length){ - - $this->pos += $length; - - for(; $this->pos < $this->input_len; $this->pos++ ){ - $c = $this->input[$this->pos]; - - if( ($c !== "\n") && ($c !== "\r") && ($c !== "\t") && ($c !== ' ') ){ - break; - } - } - } - - - /** - * @param string $tok - * @param string|null $msg - */ - public function expect($tok, $msg = NULL) { - $result = $this->match( array($tok) ); - if (!$result) { - $this->Error( $msg ? "Expected '" . $tok . "' got '" . $this->input[$this->pos] . "'" : $msg ); - } else { - return $result; - } - } - - /** - * @param string $tok - */ - public function expectChar($tok, $msg = null ){ - $result = $this->MatchChar($tok); - if( !$result ){ - $msg = $msg ? $msg : "Expected '" . $tok . "' got '" . $this->input[$this->pos] . "'"; - $this->Error( $msg ); - }else{ - return $result; - } - } - - // - // Here in, the parsing rules/functions - // - // The basic structure of the syntax tree generated is as follows: - // - // Ruleset -> Rule -> Value -> Expression -> Entity - // - // Here's some LESS code: - // - // .class { - // color: #fff; - // border: 1px solid #000; - // width: @w + 4px; - // > .child {...} - // } - // - // And here's what the parse tree might look like: - // - // Ruleset (Selector '.class', [ - // Rule ("color", Value ([Expression [Color #fff]])) - // Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]])) - // Rule ("width", Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]])) - // Ruleset (Selector [Element '>', '.child'], [...]) - // ]) - // - // In general, most rules will try to parse a token with the `$()` function, and if the return - // value is truly, will return a new node, of the relevant type. Sometimes, we need to check - // first, before parsing, that's when we use `peek()`. - // - - // - // The `primary` rule is the *entry* and *exit* point of the parser. - // The rules here can appear at any level of the parse tree. - // - // The recursive nature of the grammar is an interplay between the `block` - // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule, - // as represented by this simplified grammar: - // - // primary → (ruleset | rule)+ - // ruleset → selector+ block - // block → '{' primary '}' - // - // Only at one point is the primary rule not called from the - // block rule: at the root level. - // - private function parsePrimary(){ - $root = array(); - - while( true ){ - - if( $this->pos >= $this->input_len ){ - break; - } - - $node = $this->parseExtend(true); - if( $node ){ - $root = array_merge($root,$node); - continue; - } - - //$node = $this->MatchFuncs( array( 'parseMixinDefinition', 'parseRule', 'parseRuleset', 'parseMixinCall', 'parseComment', 'parseDirective')); - $node = $this->MatchFuncs( array( 'parseMixinDefinition', 'parseNameValue', 'parseRule', 'parseRuleset', 'parseMixinCall', 'parseComment', 'parseRulesetCall', 'parseDirective')); - - if( $node ){ - $root[] = $node; - }elseif( !$this->MatchReg('/\\G[\s\n;]+/') ){ - break; - } - - if( $this->PeekChar('}') ){ - break; - } - } - - return $root; - } - - - - // We create a Comment node for CSS comments `/* */`, - // but keep the LeSS comments `//` silent, by just skipping - // over them. - private function parseComment(){ - - if( $this->input[$this->pos] !== '/' ){ - return; - } - - if( $this->input[$this->pos+1] === '/' ){ - $match = $this->MatchReg('/\\G\/\/.*/'); - return $this->NewObj4('Less_Tree_Comment',array($match[0], true, $this->pos, $this->env->currentFileInfo)); - } - - //$comment = $this->MatchReg('/\\G\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/'); - $comment = $this->MatchReg('/\\G\/\*(?s).*?\*+\/\n?/');//not the same as less.js to prevent fatal errors - if( $comment ){ - return $this->NewObj4('Less_Tree_Comment',array($comment[0], false, $this->pos, $this->env->currentFileInfo)); - } - } - - private function parseComments(){ - $comments = array(); - - while( $this->pos < $this->input_len ){ - $comment = $this->parseComment(); - if( !$comment ){ - break; - } - - $comments[] = $comment; - } - - return $comments; - } - - - - // - // A string, which supports escaping " and ' - // - // "milky way" 'he\'s the one!' - // - private function parseEntitiesQuoted() { - $j = $this->pos; - $e = false; - $index = $this->pos; - - if( $this->input[$this->pos] === '~' ){ - $j++; - $e = true; // Escaped strings - } - - $char = $this->input[$j]; - if( $char !== '"' && $char !== "'" ){ - return; - } - - if ($e) { - $this->MatchChar('~'); - } - - - $matched = $this->MatchQuoted($char, $j+1); - if( $matched === false ){ - return; - } - - $quoted = $char.$matched.$char; - return $this->NewObj5('Less_Tree_Quoted',array($quoted, $matched, $e, $index, $this->env->currentFileInfo) ); - } - - - /** - * When PCRE JIT is enabled in php, regular expressions don't work for matching quoted strings - * - * $regex = '/\\G\'((?:[^\'\\\\\r\n]|\\\\.|\\\\\r\n|\\\\[\n\r\f])*)\'/'; - * $regex = '/\\G"((?:[^"\\\\\r\n]|\\\\.|\\\\\r\n|\\\\[\n\r\f])*)"/'; - * - */ - private function MatchQuoted($quote_char, $i){ - - $matched = ''; - while( $i < $this->input_len ){ - $c = $this->input[$i]; - - //escaped character - if( $c === '\\' ){ - $matched .= $c . $this->input[$i+1]; - $i += 2; - continue; - } - - if( $c === $quote_char ){ - $this->pos = $i+1; - $this->skipWhitespace(0); - return $matched; - } - - if( $c === "\r" || $c === "\n" ){ - return false; - } - - $i++; - $matched .= $c; - } - - return false; - } - - - // - // A catch-all word, such as: - // - // black border-collapse - // - private function parseEntitiesKeyword(){ - - //$k = $this->MatchReg('/\\G[_A-Za-z-][_A-Za-z0-9-]*/'); - $k = $this->MatchReg('/\\G%|\\G[_A-Za-z-][_A-Za-z0-9-]*/'); - if( $k ){ - $k = $k[0]; - $color = $this->fromKeyword($k); - if( $color ){ - return $color; - } - return $this->NewObj1('Less_Tree_Keyword',$k); - } - } - - // duplicate of Less_Tree_Color::FromKeyword - private function FromKeyword( $keyword ){ - $keyword = strtolower($keyword); - - if( Less_Colors::hasOwnProperty($keyword) ){ - // detect named color - return $this->NewObj1('Less_Tree_Color',substr(Less_Colors::color($keyword), 1)); - } - - if( $keyword === 'transparent' ){ - return $this->NewObj3('Less_Tree_Color', array( array(0, 0, 0), 0, true)); - } - } - - // - // A function call - // - // rgb(255, 0, 255) - // - // We also try to catch IE's `alpha()`, but let the `alpha` parser - // deal with the details. - // - // The arguments are parsed with the `entities.arguments` parser. - // - private function parseEntitiesCall(){ - $index = $this->pos; - - if( !preg_match('/\\G([\w-]+|%|progid:[\w\.]+)\(/', $this->input, $name,0,$this->pos) ){ - return; - } - $name = $name[1]; - $nameLC = strtolower($name); - - if ($nameLC === 'url') { - return null; - } - - $this->pos += strlen($name); - - if( $nameLC === 'alpha' ){ - $alpha_ret = $this->parseAlpha(); - if( $alpha_ret ){ - return $alpha_ret; - } - } - - $this->MatchChar('('); // Parse the '(' and consume whitespace. - - $args = $this->parseEntitiesArguments(); - - if( !$this->MatchChar(')') ){ - return; - } - - if ($name) { - return $this->NewObj4('Less_Tree_Call',array($name, $args, $index, $this->env->currentFileInfo) ); - } - } - - /** - * Parse a list of arguments - * - * @return array - */ - private function parseEntitiesArguments(){ - - $args = array(); - while( true ){ - $arg = $this->MatchFuncs( array('parseEntitiesAssignment','parseExpression') ); - if( !$arg ){ - break; - } - - $args[] = $arg; - if( !$this->MatchChar(',') ){ - break; - } - } - return $args; - } - - private function parseEntitiesLiteral(){ - return $this->MatchFuncs( array('parseEntitiesDimension','parseEntitiesColor','parseEntitiesQuoted','parseUnicodeDescriptor') ); - } - - // Assignments are argument entities for calls. - // They are present in ie filter properties as shown below. - // - // filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* ) - // - private function parseEntitiesAssignment() { - - $key = $this->MatchReg('/\\G\w+(?=\s?=)/'); - if( !$key ){ - return; - } - - if( !$this->MatchChar('=') ){ - return; - } - - $value = $this->parseEntity(); - if( $value ){ - return $this->NewObj2('Less_Tree_Assignment',array($key[0], $value)); - } - } - - // - // Parse url() tokens - // - // We use a specific rule for urls, because they don't really behave like - // standard function calls. The difference is that the argument doesn't have - // to be enclosed within a string, so it can't be parsed as an Expression. - // - private function parseEntitiesUrl(){ - - - if( $this->input[$this->pos] !== 'u' || !$this->matchReg('/\\Gurl\(/') ){ - return; - } - - $value = $this->match( array('parseEntitiesQuoted','parseEntitiesVariable','/\\Gdata\:.*?[^\)]+/','/\\G(?:(?:\\\\[\(\)\'"])|[^\(\)\'"])+/') ); - if( !$value ){ - $value = ''; - } - - - $this->expectChar(')'); - - - if( isset($value->value) || $value instanceof Less_Tree_Variable ){ - return $this->NewObj2('Less_Tree_Url',array($value, $this->env->currentFileInfo)); - } - - return $this->NewObj2('Less_Tree_Url', array( $this->NewObj1('Less_Tree_Anonymous',$value), $this->env->currentFileInfo) ); - } - - - // - // A Variable entity, such as `@fink`, in - // - // width: @fink + 2px - // - // We use a different parser for variable definitions, - // see `parsers.variable`. - // - private function parseEntitiesVariable(){ - $index = $this->pos; - if ($this->PeekChar('@') && ($name = $this->MatchReg('/\\G@@?[\w-]+/'))) { - return $this->NewObj3('Less_Tree_Variable', array( $name[0], $index, $this->env->currentFileInfo)); - } - } - - - // A variable entity using the protective {} e.g. @{var} - private function parseEntitiesVariableCurly() { - $index = $this->pos; - - if( $this->input_len > ($this->pos+1) && $this->input[$this->pos] === '@' && ($curly = $this->MatchReg('/\\G@\{([\w-]+)\}/')) ){ - return $this->NewObj3('Less_Tree_Variable',array('@'.$curly[1], $index, $this->env->currentFileInfo)); - } - } - - // - // A Hexadecimal color - // - // #4F3C2F - // - // `rgb` and `hsl` colors are parsed through the `entities.call` parser. - // - private function parseEntitiesColor(){ - if ($this->PeekChar('#') && ($rgb = $this->MatchReg('/\\G#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/'))) { - return $this->NewObj1('Less_Tree_Color',$rgb[1]); - } - } - - // - // A Dimension, that is, a number and a unit - // - // 0.5em 95% - // - private function parseEntitiesDimension(){ - - $c = @ord($this->input[$this->pos]); - - //Is the first char of the dimension 0-9, '.', '+' or '-' - if (($c > 57 || $c < 43) || $c === 47 || $c == 44){ - return; - } - - $value = $this->MatchReg('/\\G([+-]?\d*\.?\d+)(%|[a-z]+)?/'); - if( $value ){ - - if( isset($value[2]) ){ - return $this->NewObj2('Less_Tree_Dimension', array($value[1],$value[2])); - } - return $this->NewObj1('Less_Tree_Dimension',$value[1]); - } - } - - - // - // A unicode descriptor, as is used in unicode-range - // - // U+0?? or U+00A1-00A9 - // - function parseUnicodeDescriptor() { - $ud = $this->MatchReg('/\\G(U\+[0-9a-fA-F?]+)(\-[0-9a-fA-F?]+)?/'); - if( $ud ){ - return $this->NewObj1('Less_Tree_UnicodeDescriptor', $ud[0]); - } - } - - - // - // JavaScript code to be evaluated - // - // `window.location.href` - // - private function parseEntitiesJavascript(){ - $e = false; - $j = $this->pos; - if( $this->input[$j] === '~' ){ - $j++; - $e = true; - } - if( $this->input[$j] !== '`' ){ - return; - } - if( $e ){ - $this->MatchChar('~'); - } - $str = $this->MatchReg('/\\G`([^`]*)`/'); - if( $str ){ - return $this->NewObj3('Less_Tree_Javascript', array($str[1], $this->pos, $e)); - } - } - - - // - // The variable part of a variable definition. Used in the `rule` parser - // - // @fink: - // - private function parseVariable(){ - if ($this->PeekChar('@') && ($name = $this->MatchReg('/\\G(@[\w-]+)\s*:/'))) { - return $name[1]; - } - } - - - // - // The variable part of a variable definition. Used in the `rule` parser - // - // @fink(); - // - private function parseRulesetCall(){ - - if( $this->input[$this->pos] === '@' && ($name = $this->MatchReg('/\\G(@[\w-]+)\s*\(\s*\)\s*;/')) ){ - return $this->NewObj1('Less_Tree_RulesetCall', $name[1] ); - } - } - - - // - // extend syntax - used to extend selectors - // - function parseExtend($isRule = false){ - - $index = $this->pos; - $extendList = array(); - - - if( !$this->MatchReg( $isRule ? '/\\G&:extend\(/' : '/\\G:extend\(/' ) ){ return; } - - do{ - $option = null; - $elements = array(); - while( true ){ - $option = $this->MatchReg('/\\G(all)(?=\s*(\)|,))/'); - if( $option ){ break; } - $e = $this->parseElement(); - if( !$e ){ break; } - $elements[] = $e; - } - - if( $option ){ - $option = $option[1]; - } - - $extendList[] = $this->NewObj3('Less_Tree_Extend', array( $this->NewObj1('Less_Tree_Selector',$elements), $option, $index )); - - }while( $this->MatchChar(",") ); - - $this->expect('/\\G\)/'); - - if( $isRule ){ - $this->expect('/\\G;/'); - } - - return $extendList; - } - - - // - // A Mixin call, with an optional argument list - // - // #mixins > .square(#fff); - // .rounded(4px, black); - // .button; - // - // The `while` loop is there because mixins can be - // namespaced, but we only support the child and descendant - // selector for now. - // - private function parseMixinCall(){ - - $char = $this->input[$this->pos]; - if( $char !== '.' && $char !== '#' ){ - return; - } - - $index = $this->pos; - $this->save(); // stop us absorbing part of an invalid selector - - $elements = $this->parseMixinCallElements(); - - if( $elements ){ - - if( $this->MatchChar('(') ){ - $returned = $this->parseMixinArgs(true); - $args = $returned['args']; - $this->expectChar(')'); - }else{ - $args = array(); - } - - $important = $this->parseImportant(); - - if( $this->parseEnd() ){ - $this->forget(); - return $this->NewObj5('Less_Tree_Mixin_Call', array( $elements, $args, $index, $this->env->currentFileInfo, $important)); - } - } - - $this->restore(); - } - - - private function parseMixinCallElements(){ - $elements = array(); - $c = null; - - while( true ){ - $elemIndex = $this->pos; - $e = $this->MatchReg('/\\G[#.](?:[\w-]|\\\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/'); - if( !$e ){ - break; - } - $elements[] = $this->NewObj4('Less_Tree_Element', array($c, $e[0], $elemIndex, $this->env->currentFileInfo)); - $c = $this->MatchChar('>'); - } - - return $elements; - } - - - - /** - * @param boolean $isCall - */ - private function parseMixinArgs( $isCall ){ - $expressions = array(); - $argsSemiColon = array(); - $isSemiColonSeperated = null; - $argsComma = array(); - $expressionContainsNamed = null; - $name = null; - $returner = array('args'=>array(), 'variadic'=> false); - - $this->save(); - - while( true ){ - if( $isCall ){ - $arg = $this->MatchFuncs( array( 'parseDetachedRuleset','parseExpression' ) ); - } else { - $this->parseComments(); - if( $this->input[ $this->pos ] === '.' && $this->MatchReg('/\\G\.{3}/') ){ - $returner['variadic'] = true; - if( $this->MatchChar(";") && !$isSemiColonSeperated ){ - $isSemiColonSeperated = true; - } - - if( $isSemiColonSeperated ){ - $argsSemiColon[] = array('variadic'=>true); - }else{ - $argsComma[] = array('variadic'=>true); - } - break; - } - $arg = $this->MatchFuncs( array('parseEntitiesVariable','parseEntitiesLiteral','parseEntitiesKeyword') ); - } - - if( !$arg ){ - break; - } - - - $nameLoop = null; - if( $arg instanceof Less_Tree_Expression ){ - $arg->throwAwayComments(); - } - $value = $arg; - $val = null; - - if( $isCall ){ - // Variable - if( property_exists($arg,'value') && count($arg->value) == 1 ){ - $val = $arg->value[0]; - } - } else { - $val = $arg; - } - - - if( $val instanceof Less_Tree_Variable ){ - - if( $this->MatchChar(':') ){ - if( $expressions ){ - if( $isSemiColonSeperated ){ - $this->Error('Cannot mix ; and , as delimiter types'); - } - $expressionContainsNamed = true; - } - - // we do not support setting a ruleset as a default variable - it doesn't make sense - // However if we do want to add it, there is nothing blocking it, just don't error - // and remove isCall dependency below - $value = null; - if( $isCall ){ - $value = $this->parseDetachedRuleset(); - } - if( !$value ){ - $value = $this->parseExpression(); - } - - if( !$value ){ - if( $isCall ){ - $this->Error('could not understand value for named argument'); - } else { - $this->restore(); - $returner['args'] = array(); - return $returner; - } - } - - $nameLoop = ($name = $val->name); - }elseif( !$isCall && $this->MatchReg('/\\G\.{3}/') ){ - $returner['variadic'] = true; - if( $this->MatchChar(";") && !$isSemiColonSeperated ){ - $isSemiColonSeperated = true; - } - if( $isSemiColonSeperated ){ - $argsSemiColon[] = array('name'=> $arg->name, 'variadic' => true); - }else{ - $argsComma[] = array('name'=> $arg->name, 'variadic' => true); - } - break; - }elseif( !$isCall ){ - $name = $nameLoop = $val->name; - $value = null; - } - } - - if( $value ){ - $expressions[] = $value; - } - - $argsComma[] = array('name'=>$nameLoop, 'value'=>$value ); - - if( $this->MatchChar(',') ){ - continue; - } - - if( $this->MatchChar(';') || $isSemiColonSeperated ){ - - if( $expressionContainsNamed ){ - $this->Error('Cannot mix ; and , as delimiter types'); - } - - $isSemiColonSeperated = true; - - if( count($expressions) > 1 ){ - $value = $this->NewObj1('Less_Tree_Value', $expressions); - } - $argsSemiColon[] = array('name'=>$name, 'value'=>$value ); - - $name = null; - $expressions = array(); - $expressionContainsNamed = false; - } - } - - $this->forget(); - $returner['args'] = ($isSemiColonSeperated ? $argsSemiColon : $argsComma); - return $returner; - } - - - - // - // A Mixin definition, with a list of parameters - // - // .rounded (@radius: 2px, @color) { - // ... - // } - // - // Until we have a finer grained state-machine, we have to - // do a look-ahead, to make sure we don't have a mixin call. - // See the `rule` function for more information. - // - // We start by matching `.rounded (`, and then proceed on to - // the argument list, which has optional default values. - // We store the parameters in `params`, with a `value` key, - // if there is a value, such as in the case of `@radius`. - // - // Once we've got our params list, and a closing `)`, we parse - // the `{...}` block. - // - private function parseMixinDefinition(){ - $cond = null; - - $char = $this->input[$this->pos]; - if( ($char !== '.' && $char !== '#') || ($char === '{' && $this->PeekReg('/\\G[^{]*\}/')) ){ - return; - } - - $this->save(); - - $match = $this->MatchReg('/\\G([#.](?:[\w-]|\\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/'); - if( $match ){ - $name = $match[1]; - - $argInfo = $this->parseMixinArgs( false ); - $params = $argInfo['args']; - $variadic = $argInfo['variadic']; - - - // .mixincall("@{a}"); - // looks a bit like a mixin definition.. - // also - // .mixincall(@a: {rule: set;}); - // so we have to be nice and restore - if( !$this->MatchChar(')') ){ - $this->furthest = $this->pos; - $this->restore(); - return; - } - - - $this->parseComments(); - - if ($this->MatchReg('/\\Gwhen/')) { // Guard - $cond = $this->expect('parseConditions', 'Expected conditions'); - } - - $ruleset = $this->parseBlock(); - - if( is_array($ruleset) ){ - $this->forget(); - return $this->NewObj5('Less_Tree_Mixin_Definition', array( $name, $params, $ruleset, $cond, $variadic)); - } - - $this->restore(); - }else{ - $this->forget(); - } - } - - // - // Entities are the smallest recognized token, - // and can be found inside a rule's value. - // - private function parseEntity(){ - - return $this->MatchFuncs( array('parseEntitiesLiteral','parseEntitiesVariable','parseEntitiesUrl','parseEntitiesCall','parseEntitiesKeyword','parseEntitiesJavascript','parseComment') ); - } - - // - // A Rule terminator. Note that we use `peek()` to check for '}', - // because the `block` rule will be expecting it, but we still need to make sure - // it's there, if ';' was omitted. - // - private function parseEnd(){ - return $this->MatchChar(';') || $this->PeekChar('}'); - } - - // - // IE's alpha function - // - // alpha(opacity=88) - // - private function parseAlpha(){ - - if ( ! $this->MatchReg('/\\G\(opacity=/i')) { - return; - } - - $value = $this->MatchReg('/\\G[0-9]+/'); - if( $value ){ - $value = $value[0]; - }else{ - $value = $this->parseEntitiesVariable(); - if( !$value ){ - return; - } - } - - $this->expectChar(')'); - return $this->NewObj1('Less_Tree_Alpha',$value); - } - - - // - // A Selector Element - // - // div - // + h1 - // #socks - // input[type="text"] - // - // Elements are the building blocks for Selectors, - // they are made out of a `Combinator` (see combinator rule), - // and an element name, such as a tag a class, or `*`. - // - private function parseElement(){ - $c = $this->parseCombinator(); - $index = $this->pos; - - $e = $this->match( array('/\\G(?:\d+\.\d+|\d+)%/', '/\\G(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/', - '#*', '#&', 'parseAttribute', '/\\G\([^()@]+\)/', '/\\G[\.#](?=@)/', 'parseEntitiesVariableCurly') ); - - if( is_null($e) ){ - $this->save(); - if( $this->MatchChar('(') ){ - if( ($v = $this->parseSelector()) && $this->MatchChar(')') ){ - $e = $this->NewObj1('Less_Tree_Paren',$v); - $this->forget(); - }else{ - $this->restore(); - } - }else{ - $this->forget(); - } - } - - if( !is_null($e) ){ - return $this->NewObj4('Less_Tree_Element',array( $c, $e, $index, $this->env->currentFileInfo)); - } - } - - // - // Combinators combine elements together, in a Selector. - // - // Because our parser isn't white-space sensitive, special care - // has to be taken, when parsing the descendant combinator, ` `, - // as it's an empty space. We have to check the previous character - // in the input, to see if it's a ` ` character. - // - private function parseCombinator(){ - if( $this->pos < $this->input_len ){ - $c = $this->input[$this->pos]; - if ($c === '>' || $c === '+' || $c === '~' || $c === '|' || $c === '^' ){ - - $this->pos++; - if( $this->input[$this->pos] === '^' ){ - $c = '^^'; - $this->pos++; - } - - $this->skipWhitespace(0); - - return $c; - } - - if( $this->pos > 0 && $this->isWhitespace(-1) ){ - return ' '; - } - } - } - - // - // A CSS selector (see selector below) - // with less extensions e.g. the ability to extend and guard - // - private function parseLessSelector(){ - return $this->parseSelector(true); - } - - // - // A CSS Selector - // - // .class > div + h1 - // li a:hover - // - // Selectors are made out of one or more Elements, see above. - // - private function parseSelector( $isLess = false ){ - $elements = array(); - $extendList = array(); - $condition = null; - $when = false; - $extend = false; - $e = null; - $c = null; - $index = $this->pos; - - while( ($isLess && ($extend = $this->parseExtend())) || ($isLess && ($when = $this->MatchReg('/\\Gwhen/') )) || ($e = $this->parseElement()) ){ - if( $when ){ - $condition = $this->expect('parseConditions', 'expected condition'); - }elseif( $condition ){ - //error("CSS guard can only be used at the end of selector"); - }elseif( $extend ){ - $extendList = array_merge($extendList,$extend); - }else{ - //if( count($extendList) ){ - //error("Extend can only be used at the end of selector"); - //} - if( $this->pos < $this->input_len ){ - $c = $this->input[ $this->pos ]; - } - $elements[] = $e; - $e = null; - } - - if( $c === '{' || $c === '}' || $c === ';' || $c === ',' || $c === ')') { break; } - } - - if( $elements ){ - return $this->NewObj5('Less_Tree_Selector',array($elements, $extendList, $condition, $index, $this->env->currentFileInfo)); - } - if( $extendList ) { - $this->Error('Extend must be used to extend a selector, it cannot be used on its own'); - } - } - - private function parseTag(){ - return ( $tag = $this->MatchReg('/\\G[A-Za-z][A-Za-z-]*[0-9]?/') ) ? $tag : $this->MatchChar('*'); - } - - private function parseAttribute(){ - - $val = null; - - if( !$this->MatchChar('[') ){ - return; - } - - $key = $this->parseEntitiesVariableCurly(); - if( !$key ){ - $key = $this->expect('/\\G(?:[_A-Za-z0-9-\*]*\|)?(?:[_A-Za-z0-9-]|\\\\.)+/'); - } - - $op = $this->MatchReg('/\\G[|~*$^]?=/'); - if( $op ){ - $val = $this->match( array('parseEntitiesQuoted','/\\G[0-9]+%/','/\\G[\w-]+/','parseEntitiesVariableCurly') ); - } - - $this->expectChar(']'); - - return $this->NewObj3('Less_Tree_Attribute',array( $key, $op[0], $val)); - } - - // - // The `block` rule is used by `ruleset` and `mixin.definition`. - // It's a wrapper around the `primary` rule, with added `{}`. - // - private function parseBlock(){ - if( $this->MatchChar('{') ){ - $content = $this->parsePrimary(); - if( $this->MatchChar('}') ){ - return $content; - } - } - } - - private function parseBlockRuleset(){ - $block = $this->parseBlock(); - - if( $block ){ - $block = $this->NewObj2('Less_Tree_Ruleset',array( null, $block)); - } - - return $block; - } - - private function parseDetachedRuleset(){ - $blockRuleset = $this->parseBlockRuleset(); - if( $blockRuleset ){ - return $this->NewObj1('Less_Tree_DetachedRuleset',$blockRuleset); - } - } - - // - // div, .class, body > p {...} - // - private function parseRuleset(){ - $selectors = array(); - - $this->save(); - - while( true ){ - $s = $this->parseLessSelector(); - if( !$s ){ - break; - } - $selectors[] = $s; - $this->parseComments(); - - if( $s->condition && count($selectors) > 1 ){ - $this->Error('Guards are only currently allowed on a single selector.'); - } - - if( !$this->MatchChar(',') ){ - break; - } - if( $s->condition ){ - $this->Error('Guards are only currently allowed on a single selector.'); - } - $this->parseComments(); - } - - - if( $selectors ){ - $rules = $this->parseBlock(); - if( is_array($rules) ){ - $this->forget(); - return $this->NewObj2('Less_Tree_Ruleset',array( $selectors, $rules)); //Less_Environment::$strictImports - } - } - - // Backtrack - $this->furthest = $this->pos; - $this->restore(); - } - - /** - * Custom less.php parse function for finding simple name-value css pairs - * ex: width:100px; - * - */ - private function parseNameValue(){ - - $index = $this->pos; - $this->save(); - - - //$match = $this->MatchReg('/\\G([a-zA-Z\-]+)\s*:\s*((?:\'")?[a-zA-Z0-9\-% \.,!]+?(?:\'")?)\s*([;}])/'); - $match = $this->MatchReg('/\\G([a-zA-Z\-]+)\s*:\s*([\'"]?[#a-zA-Z0-9\-%\.,]+?[\'"]?) *(! *important)?\s*([;}])/'); - if( $match ){ - - if( $match[4] == '}' ){ - $this->pos = $index + strlen($match[0])-1; - } - - if( $match[3] ){ - $match[2] .= ' !important'; - } - - return $this->NewObj4('Less_Tree_NameValue',array( $match[1], $match[2], $index, $this->env->currentFileInfo)); - } - - $this->restore(); - } - - - private function parseRule( $tryAnonymous = null ){ - - $merge = false; - $startOfRule = $this->pos; - - $c = $this->input[$this->pos]; - if( $c === '.' || $c === '#' || $c === '&' ){ - return; - } - - $this->save(); - $name = $this->MatchFuncs( array('parseVariable','parseRuleProperty')); - - if( $name ){ - - $isVariable = is_string($name); - - $value = null; - if( $isVariable ){ - $value = $this->parseDetachedRuleset(); - } - - $important = null; - if( !$value ){ - - // prefer to try to parse first if its a variable or we are compressing - // but always fallback on the other one - //if( !$tryAnonymous && is_string($name) && $name[0] === '@' ){ - if( !$tryAnonymous && (Less_Parser::$options['compress'] || $isVariable) ){ - $value = $this->MatchFuncs( array('parseValue','parseAnonymousValue')); - }else{ - $value = $this->MatchFuncs( array('parseAnonymousValue','parseValue')); - } - - $important = $this->parseImportant(); - - // a name returned by this.ruleProperty() is always an array of the form: - // [string-1, ..., string-n, ""] or [string-1, ..., string-n, "+"] - // where each item is a tree.Keyword or tree.Variable - if( !$isVariable && is_array($name) ){ - $nm = array_pop($name); - if( $nm->value ){ - $merge = $nm->value; - } - } - } - - - if( $value && $this->parseEnd() ){ - $this->forget(); - return $this->NewObj6('Less_Tree_Rule',array( $name, $value, $important, $merge, $startOfRule, $this->env->currentFileInfo)); - }else{ - $this->furthest = $this->pos; - $this->restore(); - if( $value && !$tryAnonymous ){ - return $this->parseRule(true); - } - } - }else{ - $this->forget(); - } - } - - function parseAnonymousValue(){ - - if( preg_match('/\\G([^@+\/\'"*`(;{}-]*);/',$this->input, $match, 0, $this->pos) ){ - $this->pos += strlen($match[1]); - return $this->NewObj1('Less_Tree_Anonymous',$match[1]); - } - } - - // - // An @import directive - // - // @import "lib"; - // - // Depending on our environment, importing is done differently: - // In the browser, it's an XHR request, in Node, it would be a - // file-system operation. The function used for importing is - // stored in `import`, which we pass to the Import constructor. - // - private function parseImport(){ - - $this->save(); - - $dir = $this->MatchReg('/\\G@import?\s+/'); - - if( $dir ){ - $options = $this->parseImportOptions(); - $path = $this->MatchFuncs( array('parseEntitiesQuoted','parseEntitiesUrl')); - - if( $path ){ - $features = $this->parseMediaFeatures(); - if( $this->MatchChar(';') ){ - if( $features ){ - $features = $this->NewObj1('Less_Tree_Value',$features); - } - - $this->forget(); - return $this->NewObj5('Less_Tree_Import',array( $path, $features, $options, $this->pos, $this->env->currentFileInfo)); - } - } - } - - $this->restore(); - } - - private function parseImportOptions(){ - - $options = array(); - - // list of options, surrounded by parens - if( !$this->MatchChar('(') ){ - return $options; - } - do{ - $optionName = $this->parseImportOption(); - if( $optionName ){ - $value = true; - switch( $optionName ){ - case "css": - $optionName = "less"; - $value = false; - break; - case "once": - $optionName = "multiple"; - $value = false; - break; - } - $options[$optionName] = $value; - if( !$this->MatchChar(',') ){ break; } - } - }while( $optionName ); - $this->expectChar(')'); - return $options; - } - - private function parseImportOption(){ - $opt = $this->MatchReg('/\\G(less|css|multiple|once|inline|reference|optional)/'); - if( $opt ){ - return $opt[1]; - } - } - - private function parseMediaFeature() { - $nodes = array(); - - do{ - $e = $this->MatchFuncs(array('parseEntitiesKeyword','parseEntitiesVariable')); - if( $e ){ - $nodes[] = $e; - } elseif ($this->MatchChar('(')) { - $p = $this->parseProperty(); - $e = $this->parseValue(); - if ($this->MatchChar(')')) { - if ($p && $e) { - $r = $this->NewObj7('Less_Tree_Rule', array( $p, $e, null, null, $this->pos, $this->env->currentFileInfo, true)); - $nodes[] = $this->NewObj1('Less_Tree_Paren',$r); - } elseif ($e) { - $nodes[] = $this->NewObj1('Less_Tree_Paren',$e); - } else { - return null; - } - } else - return null; - } - } while ($e); - - if ($nodes) { - return $this->NewObj1('Less_Tree_Expression',$nodes); - } - } - - private function parseMediaFeatures() { - $features = array(); - - do{ - $e = $this->parseMediaFeature(); - if( $e ){ - $features[] = $e; - if (!$this->MatchChar(',')) break; - }else{ - $e = $this->parseEntitiesVariable(); - if( $e ){ - $features[] = $e; - if (!$this->MatchChar(',')) break; - } - } - } while ($e); - - return $features ? $features : null; - } - - private function parseMedia() { - if( $this->MatchReg('/\\G@media/') ){ - $features = $this->parseMediaFeatures(); - $rules = $this->parseBlock(); - - if( is_array($rules) ){ - return $this->NewObj4('Less_Tree_Media',array( $rules, $features, $this->pos, $this->env->currentFileInfo)); - } - } - } - - - // - // A CSS Directive - // - // @charset "utf-8"; - // - private function parseDirective(){ - - if( !$this->PeekChar('@') ){ - return; - } - - $rules = null; - $index = $this->pos; - $hasBlock = true; - $hasIdentifier = false; - $hasExpression = false; - $hasUnknown = false; - - - $value = $this->MatchFuncs(array('parseImport','parseMedia')); - if( $value ){ - return $value; - } - - $this->save(); - - $name = $this->MatchReg('/\\G@[a-z-]+/'); - - if( !$name ) return; - $name = $name[0]; - - - $nonVendorSpecificName = $name; - $pos = strpos($name,'-', 2); - if( $name[1] == '-' && $pos > 0 ){ - $nonVendorSpecificName = "@" . substr($name, $pos + 1); - } - - - switch( $nonVendorSpecificName ){ - /* - case "@font-face": - case "@viewport": - case "@top-left": - case "@top-left-corner": - case "@top-center": - case "@top-right": - case "@top-right-corner": - case "@bottom-left": - case "@bottom-left-corner": - case "@bottom-center": - case "@bottom-right": - case "@bottom-right-corner": - case "@left-top": - case "@left-middle": - case "@left-bottom": - case "@right-top": - case "@right-middle": - case "@right-bottom": - hasBlock = true; - break; - */ - case "@charset": - $hasIdentifier = true; - $hasBlock = false; - break; - case "@namespace": - $hasExpression = true; - $hasBlock = false; - break; - case "@keyframes": - $hasIdentifier = true; - break; - case "@host": - case "@page": - case "@document": - case "@supports": - $hasUnknown = true; - break; - } - - if( $hasIdentifier ){ - $value = $this->parseEntity(); - if( !$value ){ - $this->error("expected " . $name . " identifier"); - } - } else if( $hasExpression ){ - $value = $this->parseExpression(); - if( !$value ){ - $this->error("expected " . $name. " expression"); - } - } else if ($hasUnknown) { - - $value = $this->MatchReg('/\\G[^{;]+/'); - if( $value ){ - $value = $this->NewObj1('Less_Tree_Anonymous',trim($value[0])); - } - } - - if( $hasBlock ){ - $rules = $this->parseBlockRuleset(); - } - - if( $rules || (!$hasBlock && $value && $this->MatchChar(';'))) { - $this->forget(); - return $this->NewObj5('Less_Tree_Directive',array($name, $value, $rules, $index, $this->env->currentFileInfo)); - } - - $this->restore(); - } - - - // - // A Value is a comma-delimited list of Expressions - // - // font-family: Baskerville, Georgia, serif; - // - // In a Rule, a Value represents everything after the `:`, - // and before the `;`. - // - private function parseValue(){ - $expressions = array(); - - do{ - $e = $this->parseExpression(); - if( $e ){ - $expressions[] = $e; - if (! $this->MatchChar(',')) { - break; - } - } - }while($e); - - if( $expressions ){ - return $this->NewObj1('Less_Tree_Value',$expressions); - } - } - - private function parseImportant (){ - if( $this->PeekChar('!') && $this->MatchReg('/\\G! *important/') ){ - return ' !important'; - } - } - - private function parseSub (){ - - if( $this->MatchChar('(') ){ - $a = $this->parseAddition(); - if( $a ){ - $this->expectChar(')'); - return $this->NewObj2('Less_Tree_Expression',array( array($a), true) ); //instead of $e->parens = true so the value is cached - } - } - } - - - /** - * Parses multiplication operation - * - * @return Less_Tree_Operation|null - */ - function parseMultiplication(){ - - $return = $m = $this->parseOperand(); - if( $return ){ - while( true ){ - - $isSpaced = $this->isWhitespace( -1 ); - - if( $this->PeekReg('/\\G\/[*\/]/') ){ - break; - } - - $op = $this->MatchChar('/'); - if( !$op ){ - $op = $this->MatchChar('*'); - if( !$op ){ - break; - } - } - - $a = $this->parseOperand(); - - if(!$a) { break; } - - $m->parensInOp = true; - $a->parensInOp = true; - $return = $this->NewObj3('Less_Tree_Operation',array( $op, array( $return, $a ), $isSpaced) ); - } - } - return $return; - - } - - - /** - * Parses an addition operation - * - * @return Less_Tree_Operation|null - */ - private function parseAddition (){ - - $return = $m = $this->parseMultiplication(); - if( $return ){ - while( true ){ - - $isSpaced = $this->isWhitespace( -1 ); - - $op = $this->MatchReg('/\\G[-+]\s+/'); - if( $op ){ - $op = $op[0]; - }else{ - if( !$isSpaced ){ - $op = $this->match(array('#+','#-')); - } - if( !$op ){ - break; - } - } - - $a = $this->parseMultiplication(); - if( !$a ){ - break; - } - - $m->parensInOp = true; - $a->parensInOp = true; - $return = $this->NewObj3('Less_Tree_Operation',array($op, array($return, $a), $isSpaced)); - } - } - - return $return; - } - - - /** - * Parses the conditions - * - * @return Less_Tree_Condition|null - */ - private function parseConditions() { - $index = $this->pos; - $return = $a = $this->parseCondition(); - if( $a ){ - while( true ){ - if( !$this->PeekReg('/\\G,\s*(not\s*)?\(/') || !$this->MatchChar(',') ){ - break; - } - $b = $this->parseCondition(); - if( !$b ){ - break; - } - - $return = $this->NewObj4('Less_Tree_Condition',array('or', $return, $b, $index)); - } - return $return; - } - } - - private function parseCondition() { - $index = $this->pos; - $negate = false; - $c = null; - - if ($this->MatchReg('/\\Gnot/')) $negate = true; - $this->expectChar('('); - $a = $this->MatchFuncs(array('parseAddition','parseEntitiesKeyword','parseEntitiesQuoted')); - - if( $a ){ - $op = $this->MatchReg('/\\G(?:>=|<=|=<|[<=>])/'); - if( $op ){ - $b = $this->MatchFuncs(array('parseAddition','parseEntitiesKeyword','parseEntitiesQuoted')); - if( $b ){ - $c = $this->NewObj5('Less_Tree_Condition',array($op[0], $a, $b, $index, $negate)); - } else { - $this->Error('Unexpected expression'); - } - } else { - $k = $this->NewObj1('Less_Tree_Keyword','true'); - $c = $this->NewObj5('Less_Tree_Condition',array('=', $a, $k, $index, $negate)); - } - $this->expectChar(')'); - return $this->MatchReg('/\\Gand/') ? $this->NewObj3('Less_Tree_Condition',array('and', $c, $this->parseCondition())) : $c; - } - } - - /** - * An operand is anything that can be part of an operation, - * such as a Color, or a Variable - * - */ - private function parseOperand (){ - - $negate = false; - $offset = $this->pos+1; - if( $offset >= $this->input_len ){ - return; - } - $char = $this->input[$offset]; - if( $char === '@' || $char === '(' ){ - $negate = $this->MatchChar('-'); - } - - $o = $this->MatchFuncs(array('parseSub','parseEntitiesDimension','parseEntitiesColor','parseEntitiesVariable','parseEntitiesCall')); - - if( $negate ){ - $o->parensInOp = true; - $o = $this->NewObj1('Less_Tree_Negative',$o); - } - - return $o; - } - - - /** - * Expressions either represent mathematical operations, - * or white-space delimited Entities. - * - * 1px solid black - * @var * 2 - * - * @return Less_Tree_Expression|null - */ - private function parseExpression (){ - $entities = array(); - - do{ - $e = $this->MatchFuncs(array('parseAddition','parseEntity')); - if( $e ){ - $entities[] = $e; - // operations do not allow keyword "/" dimension (e.g. small/20px) so we support that here - if( !$this->PeekReg('/\\G\/[\/*]/') ){ - $delim = $this->MatchChar('/'); - if( $delim ){ - $entities[] = $this->NewObj1('Less_Tree_Anonymous',$delim); - } - } - } - }while($e); - - if( $entities ){ - return $this->NewObj1('Less_Tree_Expression',$entities); - } - } - - - /** - * Parse a property - * eg: 'min-width', 'orientation', etc - * - * @return string - */ - private function parseProperty (){ - $name = $this->MatchReg('/\\G(\*?-?[_a-zA-Z0-9-]+)\s*:/'); - if( $name ){ - return $name[1]; - } - } - - - /** - * Parse a rule property - * eg: 'color', 'width', 'height', etc - * - * @return string - */ - private function parseRuleProperty(){ - $offset = $this->pos; - $name = array(); - $index = array(); - $length = 0; - - - $this->rulePropertyMatch('/\\G(\*?)/', $offset, $length, $index, $name ); - while( $this->rulePropertyMatch('/\\G((?:[\w-]+)|(?:@\{[\w-]+\}))/', $offset, $length, $index, $name )); // ! - - if( (count($name) > 1) && $this->rulePropertyMatch('/\\G\s*((?:\+_|\+)?)\s*:/', $offset, $length, $index, $name) ){ - // at last, we have the complete match now. move forward, - // convert name particles to tree objects and return: - $this->skipWhitespace($length); - - if( $name[0] === '' ){ - array_shift($name); - array_shift($index); - } - foreach($name as $k => $s ){ - if( !$s || $s[0] !== '@' ){ - $name[$k] = $this->NewObj1('Less_Tree_Keyword',$s); - }else{ - $name[$k] = $this->NewObj3('Less_Tree_Variable',array('@' . substr($s,2,-1), $index[$k], $this->env->currentFileInfo)); - } - } - return $name; - } - - - } - - private function rulePropertyMatch( $re, &$offset, &$length, &$index, &$name ){ - preg_match($re, $this->input, $a, 0, $offset); - if( $a ){ - $index[] = $this->pos + $length; - $length += strlen($a[0]); - $offset += strlen($a[0]); - $name[] = $a[1]; - return true; - } - } - - public static function serializeVars( $vars ){ - $s = ''; - - foreach($vars as $name => $value){ - $s .= (($name[0] === '@') ? '' : '@') . $name .': '. $value . ((substr($value,-1) === ';') ? '' : ';'); - } - - return $s; - } - - - /** - * Some versions of php have trouble with method_exists($a,$b) if $a is not an object - * - * @param string $b - */ - public static function is_method($a,$b){ - return is_object($a) && method_exists($a,$b); - } - - - /** - * Round numbers similarly to javascript - * eg: 1.499999 to 1 instead of 2 - * - */ - public static function round($i, $precision = 0){ - - $precision = pow(10,$precision); - $i = $i*$precision; - - $ceil = ceil($i); - $floor = floor($i); - if( ($ceil - $i) <= ($i - $floor) ){ - return $ceil/$precision; - }else{ - return $floor/$precision; - } - } - - - /** - * Create Less_Tree_* objects and optionally generate a cache string - * - * @return mixed - */ - public function NewObj0($class){ - $obj = new $class(); - if( $this->CacheEnabled() ){ - $obj->cache_string = ' new '.$class.'()'; - } - return $obj; - } - - public function NewObj1($class, $arg){ - $obj = new $class( $arg ); - if( $this->CacheEnabled() ){ - $obj->cache_string = ' new '.$class.'('.Less_Parser::ArgString($arg).')'; - } - return $obj; - } - - public function NewObj2($class, $args){ - $obj = new $class( $args[0], $args[1] ); - if( $this->CacheEnabled() ){ - $this->ObjCache( $obj, $class, $args); - } - return $obj; - } - - public function NewObj3($class, $args){ - $obj = new $class( $args[0], $args[1], $args[2] ); - if( $this->CacheEnabled() ){ - $this->ObjCache( $obj, $class, $args); - } - return $obj; - } - - public function NewObj4($class, $args){ - $obj = new $class( $args[0], $args[1], $args[2], $args[3] ); - if( $this->CacheEnabled() ){ - $this->ObjCache( $obj, $class, $args); - } - return $obj; - } - - public function NewObj5($class, $args){ - $obj = new $class( $args[0], $args[1], $args[2], $args[3], $args[4] ); - if( $this->CacheEnabled() ){ - $this->ObjCache( $obj, $class, $args); - } - return $obj; - } - - public function NewObj6($class, $args){ - $obj = new $class( $args[0], $args[1], $args[2], $args[3], $args[4], $args[5] ); - if( $this->CacheEnabled() ){ - $this->ObjCache( $obj, $class, $args); - } - return $obj; - } - - public function NewObj7($class, $args){ - $obj = new $class( $args[0], $args[1], $args[2], $args[3], $args[4], $args[5], $args[6] ); - if( $this->CacheEnabled() ){ - $this->ObjCache( $obj, $class, $args); - } - return $obj; - } - - //caching - public function ObjCache($obj, $class, $args=array()){ - $obj->cache_string = ' new '.$class.'('. self::ArgCache($args).')'; - } - - public function ArgCache($args){ - return implode(',',array_map( array('Less_Parser','ArgString'),$args)); - } - - - /** - * Convert an argument to a string for use in the parser cache - * - * @return string - */ - public static function ArgString($arg){ - - $type = gettype($arg); - - if( $type === 'object'){ - $string = $arg->cache_string; - unset($arg->cache_string); - return $string; - - }elseif( $type === 'array' ){ - $string = ' Array('; - foreach($arg as $k => $a){ - $string .= var_export($k,true).' => '.self::ArgString($a).','; - } - return $string . ')'; - } - - return var_export($arg,true); - } - - public function Error($msg){ - throw new Less_Exception_Parser($msg, null, $this->furthest, $this->env->currentFileInfo); - } - - public static function WinPath($path){ - return str_replace('\\', '/', $path); - } - - public static function AbsPath($path, $winPath = false){ - if (strpos($path, '//') !== false && preg_match('_^(https?:)?//\\w+(\\.\\w+)+/\\w+_i', $path)) { - return $winPath ? '' : false; - } else { - $path = realpath($path); - if ($winPath) { - $path = self::WinPath($path); - } - return $path; - } - } - - public function CacheEnabled(){ - return (Less_Parser::$options['cache_method'] && (Less_Cache::$cache_dir || (Less_Parser::$options['cache_method'] == 'callback'))); - } - -} diff --git a/vendor/oyejorge/less.php/lib/Less/SourceMap/Base64VLQ.php b/vendor/oyejorge/less.php/lib/Less/SourceMap/Base64VLQ.php deleted file mode 100644 index f5b200c..0000000 --- a/vendor/oyejorge/less.php/lib/Less/SourceMap/Base64VLQ.php +++ /dev/null @@ -1,187 +0,0 @@ - 0, 'B' => 1, 'C' => 2, 'D' => 3, 'E' => 4, 'F' => 5, 'G' => 6, - 'H' => 7,'I' => 8, 'J' => 9, 'K' => 10, 'L' => 11, 'M' => 12, 'N' => 13, - 'O' => 14, 'P' => 15, 'Q' => 16, 'R' => 17, 'S' => 18, 'T' => 19, 'U' => 20, - 'V' => 21, 'W' => 22, 'X' => 23, 'Y' => 24, 'Z' => 25, 'a' => 26, 'b' => 27, - 'c' => 28, 'd' => 29, 'e' => 30, 'f' => 31, 'g' => 32, 'h' => 33, 'i' => 34, - 'j' => 35, 'k' => 36, 'l' => 37, 'm' => 38, 'n' => 39, 'o' => 40, 'p' => 41, - 'q' => 42, 'r' => 43, 's' => 44, 't' => 45, 'u' => 46, 'v' => 47, 'w' => 48, - 'x' => 49, 'y' => 50, 'z' => 51, 0 => 52, 1 => 53, 2 => 54, 3 => 55, 4 => 56, - 5 => 57, 6 => 58, 7 => 59, 8 => 60, 9 => 61, '+' => 62, '/' => 63, - ); - - /** - * Integer to char map - * - * @var array - */ - private $intToCharMap = array( - 0 => 'A', 1 => 'B', 2 => 'C', 3 => 'D', 4 => 'E', 5 => 'F', 6 => 'G', - 7 => 'H', 8 => 'I', 9 => 'J', 10 => 'K', 11 => 'L', 12 => 'M', 13 => 'N', - 14 => 'O', 15 => 'P', 16 => 'Q', 17 => 'R', 18 => 'S', 19 => 'T', 20 => 'U', - 21 => 'V', 22 => 'W', 23 => 'X', 24 => 'Y', 25 => 'Z', 26 => 'a', 27 => 'b', - 28 => 'c', 29 => 'd', 30 => 'e', 31 => 'f', 32 => 'g', 33 => 'h', 34 => 'i', - 35 => 'j', 36 => 'k', 37 => 'l', 38 => 'm', 39 => 'n', 40 => 'o', 41 => 'p', - 42 => 'q', 43 => 'r', 44 => 's', 45 => 't', 46 => 'u', 47 => 'v', 48 => 'w', - 49 => 'x', 50 => 'y', 51 => 'z', 52 => '0', 53 => '1', 54 => '2', 55 => '3', - 56 => '4', 57 => '5', 58 => '6', 59 => '7', 60 => '8', 61 => '9', 62 => '+', - 63 => '/', - ); - - /** - * Constructor - */ - public function __construct(){ - // I leave it here for future reference - // foreach(str_split('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/') as $i => $char) - // { - // $this->charToIntMap[$char] = $i; - // $this->intToCharMap[$i] = $char; - // } - } - - /** - * Convert from a two-complement value to a value where the sign bit is - * is placed in the least significant bit. For example, as decimals: - * 1 becomes 2 (10 binary), -1 becomes 3 (11 binary) - * 2 becomes 4 (100 binary), -2 becomes 5 (101 binary) - * We generate the value for 32 bit machines, hence -2147483648 becomes 1, not 4294967297, - * even on a 64 bit machine. - * @param string $aValue - */ - public function toVLQSigned($aValue){ - return 0xffffffff & ($aValue < 0 ? ((-$aValue) << 1) + 1 : ($aValue << 1) + 0); - } - - /** - * Convert to a two-complement value from a value where the sign bit is - * is placed in the least significant bit. For example, as decimals: - * 2 (10 binary) becomes 1, 3 (11 binary) becomes -1 - * 4 (100 binary) becomes 2, 5 (101 binary) becomes -2 - * We assume that the value was generated with a 32 bit machine in mind. - * Hence - * 1 becomes -2147483648 - * even on a 64 bit machine. - * @param integer $aValue - */ - public function fromVLQSigned($aValue){ - return $aValue & 1 ? $this->zeroFill(~$aValue + 2, 1) | (-1 - 0x7fffffff) : $this->zeroFill($aValue, 1); - } - - /** - * Return the base 64 VLQ encoded value. - * - * @param string $aValue The value to encode - * @return string The encoded value - */ - public function encode($aValue){ - $encoded = ''; - $vlq = $this->toVLQSigned($aValue); - do - { - $digit = $vlq & $this->mask; - $vlq = $this->zeroFill($vlq, $this->shift); - if($vlq > 0){ - $digit |= $this->continuationBit; - } - $encoded .= $this->base64Encode($digit); - } while($vlq > 0); - - return $encoded; - } - - /** - * Return the value decoded from base 64 VLQ. - * - * @param string $encoded The encoded value to decode - * @return integer The decoded value - */ - public function decode($encoded){ - $vlq = 0; - $i = 0; - do - { - $digit = $this->base64Decode($encoded[$i]); - $vlq |= ($digit & $this->mask) << ($i * $this->shift); - $i++; - } while($digit & $this->continuationBit); - - return $this->fromVLQSigned($vlq); - } - - /** - * Right shift with zero fill. - * - * @param integer $a number to shift - * @param integer $b number of bits to shift - * @return integer - */ - public function zeroFill($a, $b){ - return ($a >= 0) ? ($a >> $b) : ($a >> $b) & (PHP_INT_MAX >> ($b - 1)); - } - - /** - * Encode single 6-bit digit as base64. - * - * @param integer $number - * @return string - * @throws Exception If the number is invalid - */ - public function base64Encode($number){ - if($number < 0 || $number > 63){ - throw new Exception(sprintf('Invalid number "%s" given. Must be between 0 and 63.', $number)); - } - return $this->intToCharMap[$number]; - } - - /** - * Decode single 6-bit digit from base64 - * - * @param string $char - * @return number - * @throws Exception If the number is invalid - */ - public function base64Decode($char){ - if(!array_key_exists($char, $this->charToIntMap)){ - throw new Exception(sprintf('Invalid base 64 digit "%s" given.', $char)); - } - return $this->charToIntMap[$char]; - } - -} diff --git a/vendor/oyejorge/less.php/lib/Less/SourceMap/Generator.php b/vendor/oyejorge/less.php/lib/Less/SourceMap/Generator.php deleted file mode 100644 index ff73af0..0000000 --- a/vendor/oyejorge/less.php/lib/Less/SourceMap/Generator.php +++ /dev/null @@ -1,365 +0,0 @@ - '', - - // an optional name of the generated code that this source map is associated with. - 'sourceMapFilename' => null, - - // url of the map - 'sourceMapURL' => null, - - // absolute path to a file to write the map to - 'sourceMapWriteTo' => null, - - // output source contents? - 'outputSourceFiles' => false, - - // base path for filename normalization - 'sourceMapRootpath' => '', - - // base path for filename normalization - 'sourceMapBasepath' => '' - ); - - /** - * The base64 VLQ encoder - * - * @var Less_SourceMap_Base64VLQ - */ - protected $encoder; - - /** - * Array of mappings - * - * @var array - */ - protected $mappings = array(); - - /** - * The root node - * - * @var Less_Tree_Ruleset - */ - protected $root; - - /** - * Array of contents map - * - * @var array - */ - protected $contentsMap = array(); - - /** - * File to content map - * - * @var array - */ - protected $sources = array(); - protected $source_keys = array(); - - /** - * Constructor - * - * @param Less_Tree_Ruleset $root The root node - * @param array $options Array of options - */ - public function __construct(Less_Tree_Ruleset $root, $contentsMap, $options = array()){ - $this->root = $root; - $this->contentsMap = $contentsMap; - $this->encoder = new Less_SourceMap_Base64VLQ(); - - $this->SetOptions($options); - - $this->options['sourceMapRootpath'] = $this->fixWindowsPath($this->options['sourceMapRootpath'], true); - $this->options['sourceMapBasepath'] = $this->fixWindowsPath($this->options['sourceMapBasepath'], true); - } - - /** - * Generates the CSS - * - * @return string - */ - public function generateCSS(){ - $output = new Less_Output_Mapped($this->contentsMap, $this); - - // catch the output - $this->root->genCSS($output); - - - $sourceMapUrl = $this->getOption('sourceMapURL'); - $sourceMapFilename = $this->getOption('sourceMapFilename'); - $sourceMapContent = $this->generateJson(); - $sourceMapWriteTo = $this->getOption('sourceMapWriteTo'); - - if( !$sourceMapUrl && $sourceMapFilename ){ - $sourceMapUrl = $this->normalizeFilename($sourceMapFilename); - } - - // write map to a file - if( $sourceMapWriteTo ){ - $this->saveMap($sourceMapWriteTo, $sourceMapContent); - } - - // inline the map - if( !$sourceMapUrl ){ - $sourceMapUrl = sprintf('data:application/json,%s', Less_Functions::encodeURIComponent($sourceMapContent)); - } - - if( $sourceMapUrl ){ - $output->add( sprintf('/*# sourceMappingURL=%s */', $sourceMapUrl) ); - } - - return $output->toString(); - } - - /** - * Saves the source map to a file - * - * @param string $file The absolute path to a file - * @param string $content The content to write - * @throws Exception If the file could not be saved - */ - protected function saveMap($file, $content){ - $dir = dirname($file); - // directory does not exist - if( !is_dir($dir) ){ - // FIXME: create the dir automatically? - throw new Exception(sprintf('The directory "%s" does not exist. Cannot save the source map.', $dir)); - } - // FIXME: proper saving, with dir write check! - if(file_put_contents($file, $content) === false){ - throw new Exception(sprintf('Cannot save the source map to "%s"', $file)); - } - return true; - } - - /** - * Normalizes the filename - * - * @param string $filename - * @return string - */ - protected function normalizeFilename($filename){ - - $filename = $this->fixWindowsPath($filename); - - $rootpath = $this->getOption('sourceMapRootpath'); - $basePath = $this->getOption('sourceMapBasepath'); - - // "Trim" the 'sourceMapBasepath' from the output filename. - if (strpos($filename, $basePath) === 0) { - $filename = substr($filename, strlen($basePath)); - } - - // Remove extra leading path separators. - if(strpos($filename, '\\') === 0 || strpos($filename, '/') === 0){ - $filename = substr($filename, 1); - } - - return $rootpath . $filename; - } - - /** - * Adds a mapping - * - * @param integer $generatedLine The line number in generated file - * @param integer $generatedColumn The column number in generated file - * @param integer $originalLine The line number in original file - * @param integer $originalColumn The column number in original file - * @param string $sourceFile The original source file - */ - public function addMapping($generatedLine, $generatedColumn, $originalLine, $originalColumn, $fileInfo ){ - - $this->mappings[] = array( - 'generated_line' => $generatedLine, - 'generated_column' => $generatedColumn, - 'original_line' => $originalLine, - 'original_column' => $originalColumn, - 'source_file' => $fileInfo['currentUri'] - ); - - $this->sources[$fileInfo['currentUri']] = $fileInfo['filename']; - } - - - /** - * Generates the JSON source map - * - * @return string - * @see https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit# - */ - protected function generateJson(){ - - $sourceMap = array(); - $mappings = $this->generateMappings(); - - // File version (always the first entry in the object) and must be a positive integer. - $sourceMap['version'] = self::VERSION; - - - // An optional name of the generated code that this source map is associated with. - $file = $this->getOption('sourceMapFilename'); - if( $file ){ - $sourceMap['file'] = $file; - } - - - // An optional source root, useful for relocating source files on a server or removing repeated values in the 'sources' entry. This value is prepended to the individual entries in the 'source' field. - $root = $this->getOption('sourceRoot'); - if( $root ){ - $sourceMap['sourceRoot'] = $root; - } - - - // A list of original sources used by the 'mappings' entry. - $sourceMap['sources'] = array(); - foreach($this->sources as $source_uri => $source_filename){ - $sourceMap['sources'][] = $this->normalizeFilename($source_filename); - } - - - // A list of symbol names used by the 'mappings' entry. - $sourceMap['names'] = array(); - - // A string with the encoded mapping data. - $sourceMap['mappings'] = $mappings; - - if( $this->getOption('outputSourceFiles') ){ - // An optional list of source content, useful when the 'source' can't be hosted. - // The contents are listed in the same order as the sources above. - // 'null' may be used if some original sources should be retrieved by name. - $sourceMap['sourcesContent'] = $this->getSourcesContent(); - } - - // less.js compat fixes - if( count($sourceMap['sources']) && empty($sourceMap['sourceRoot']) ){ - unset($sourceMap['sourceRoot']); - } - - return json_encode($sourceMap); - } - - /** - * Returns the sources contents - * - * @return array|null - */ - protected function getSourcesContent(){ - if(empty($this->sources)){ - return; - } - $content = array(); - foreach($this->sources as $sourceFile){ - $content[] = file_get_contents($sourceFile); - } - return $content; - } - - /** - * Generates the mappings string - * - * @return string - */ - public function generateMappings(){ - - if( !count($this->mappings) ){ - return ''; - } - - $this->source_keys = array_flip(array_keys($this->sources)); - - - // group mappings by generated line number. - $groupedMap = $groupedMapEncoded = array(); - foreach($this->mappings as $m){ - $groupedMap[$m['generated_line']][] = $m; - } - ksort($groupedMap); - - $lastGeneratedLine = $lastOriginalIndex = $lastOriginalLine = $lastOriginalColumn = 0; - - foreach($groupedMap as $lineNumber => $line_map){ - while(++$lastGeneratedLine < $lineNumber){ - $groupedMapEncoded[] = ';'; - } - - $lineMapEncoded = array(); - $lastGeneratedColumn = 0; - - foreach($line_map as $m){ - $mapEncoded = $this->encoder->encode($m['generated_column'] - $lastGeneratedColumn); - $lastGeneratedColumn = $m['generated_column']; - - // find the index - if( $m['source_file'] ){ - $index = $this->findFileIndex($m['source_file']); - if( $index !== false ){ - $mapEncoded .= $this->encoder->encode($index - $lastOriginalIndex); - $lastOriginalIndex = $index; - - // lines are stored 0-based in SourceMap spec version 3 - $mapEncoded .= $this->encoder->encode($m['original_line'] - 1 - $lastOriginalLine); - $lastOriginalLine = $m['original_line'] - 1; - - $mapEncoded .= $this->encoder->encode($m['original_column'] - $lastOriginalColumn); - $lastOriginalColumn = $m['original_column']; - } - } - - $lineMapEncoded[] = $mapEncoded; - } - - $groupedMapEncoded[] = implode(',', $lineMapEncoded) . ';'; - } - - return rtrim(implode($groupedMapEncoded), ';'); - } - - /** - * Finds the index for the filename - * - * @param string $filename - * @return integer|false - */ - protected function findFileIndex($filename){ - return $this->source_keys[$filename]; - } - - /** - * fix windows paths - * @param string $path - * @return string - */ - public function fixWindowsPath($path, $addEndSlash = false){ - $slash = ($addEndSlash) ? '/' : ''; - if( !empty($path) ){ - $path = str_replace('\\', '/', $path); - $path = rtrim($path,'/') . $slash; - } - - return $path; - } - -} \ No newline at end of file diff --git a/vendor/oyejorge/less.php/lib/Less/Tree.php b/vendor/oyejorge/less.php/lib/Less/Tree.php deleted file mode 100644 index 6fb104b..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Tree.php +++ /dev/null @@ -1,90 +0,0 @@ -genCSS($output); - return $output->toString(); - } - - - /** - * Generate CSS by adding it to the output object - * - * @param Less_Output $output The output - * @return void - */ - public function genCSS($output){} - - - /** - * @param Less_Tree_Ruleset[] $rules - */ - public static function outputRuleset( $output, $rules ){ - - $ruleCnt = count($rules); - Less_Environment::$tabLevel++; - - - // Compressed - if( Less_Parser::$options['compress'] ){ - $output->add('{'); - for( $i = 0; $i < $ruleCnt; $i++ ){ - $rules[$i]->genCSS( $output ); - } - - $output->add( '}' ); - Less_Environment::$tabLevel--; - return; - } - - - // Non-compressed - $tabSetStr = "\n".str_repeat( Less_Parser::$options['indentation'] , Less_Environment::$tabLevel-1 ); - $tabRuleStr = $tabSetStr.Less_Parser::$options['indentation']; - - $output->add( " {" ); - for($i = 0; $i < $ruleCnt; $i++ ){ - $output->add( $tabRuleStr ); - $rules[$i]->genCSS( $output ); - } - Less_Environment::$tabLevel--; - $output->add( $tabSetStr.'}' ); - - } - - public function accept($visitor){} - - - public static function ReferencedArray($rules){ - foreach($rules as $rule){ - if( method_exists($rule, 'markReferenced') ){ - $rule->markReferenced(); - } - } - } - - - /** - * Requires php 5.3+ - */ - public static function __set_state($args){ - - $class = get_called_class(); - $obj = new $class(null,null,null,null); - foreach($args as $key => $val){ - $obj->$key = $val; - } - return $obj; - } - -} diff --git a/vendor/oyejorge/less.php/lib/Less/Tree/Alpha.php b/vendor/oyejorge/less.php/lib/Less/Tree/Alpha.php deleted file mode 100644 index 935377d..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Tree/Alpha.php +++ /dev/null @@ -1,51 +0,0 @@ -value = $val; - } - - //function accept( $visitor ){ - // $this->value = $visitor->visit( $this->value ); - //} - - public function compile($env){ - - if( is_object($this->value) ){ - $this->value = $this->value->compile($env); - } - - return $this; - } - - /** - * @see Less_Tree::genCSS - */ - public function genCSS( $output ){ - - $output->add( "alpha(opacity=" ); - - if( is_string($this->value) ){ - $output->add( $this->value ); - }else{ - $this->value->genCSS( $output); - } - - $output->add( ')' ); - } - - public function toCSS(){ - return "alpha(opacity=" . (is_string($this->value) ? $this->value : $this->value->toCSS()) . ")"; - } - - -} \ No newline at end of file diff --git a/vendor/oyejorge/less.php/lib/Less/Tree/Anonymous.php b/vendor/oyejorge/less.php/lib/Less/Tree/Anonymous.php deleted file mode 100644 index 8889dc0..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Tree/Anonymous.php +++ /dev/null @@ -1,58 +0,0 @@ -value = $value; - $this->index = $index; - $this->mapLines = $mapLines; - $this->currentFileInfo = $currentFileInfo; - } - - public function compile(){ - return new Less_Tree_Anonymous($this->value, $this->index, $this->currentFileInfo, $this->mapLines); - } - - public function compare($x){ - if( !is_object($x) ){ - return -1; - } - - $left = $this->toCSS(); - $right = $x->toCSS(); - - if( $left === $right ){ - return 0; - } - - return $left < $right ? -1 : 1; - } - - /** - * @see Less_Tree::genCSS - */ - public function genCSS( $output ){ - $output->add( $this->value, $this->currentFileInfo, $this->index, $this->mapLines ); - } - - public function toCSS(){ - return $this->value; - } - -} diff --git a/vendor/oyejorge/less.php/lib/Less/Tree/Assignment.php b/vendor/oyejorge/less.php/lib/Less/Tree/Assignment.php deleted file mode 100644 index 2380006..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Tree/Assignment.php +++ /dev/null @@ -1,39 +0,0 @@ -key = $key; - $this->value = $val; - } - - public function accept( $visitor ){ - $this->value = $visitor->visitObj( $this->value ); - } - - public function compile($env) { - return new Less_Tree_Assignment( $this->key, $this->value->compile($env)); - } - - /** - * @see Less_Tree::genCSS - */ - public function genCSS( $output ){ - $output->add( $this->key . '=' ); - $this->value->genCSS( $output ); - } - - public function toCss(){ - return $this->key . '=' . $this->value->toCSS(); - } -} diff --git a/vendor/oyejorge/less.php/lib/Less/Tree/Attribute.php b/vendor/oyejorge/less.php/lib/Less/Tree/Attribute.php deleted file mode 100644 index 32b8900..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Tree/Attribute.php +++ /dev/null @@ -1,54 +0,0 @@ -key = $key; - $this->op = $op; - $this->value = $value; - } - - public function compile($env){ - - $key_obj = is_object($this->key); - $val_obj = is_object($this->value); - - if( !$key_obj && !$val_obj ){ - return $this; - } - - return new Less_Tree_Attribute( - $key_obj ? $this->key->compile($env) : $this->key , - $this->op, - $val_obj ? $this->value->compile($env) : $this->value); - } - - /** - * @see Less_Tree::genCSS - */ - public function genCSS( $output ){ - $output->add( $this->toCSS() ); - } - - public function toCSS(){ - $value = $this->key; - - if( $this->op ){ - $value .= $this->op; - $value .= (is_object($this->value) ? $this->value->toCSS() : $this->value); - } - - return '[' . $value . ']'; - } -} \ No newline at end of file diff --git a/vendor/oyejorge/less.php/lib/Less/Tree/Call.php b/vendor/oyejorge/less.php/lib/Less/Tree/Call.php deleted file mode 100644 index 3c3382d..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Tree/Call.php +++ /dev/null @@ -1,121 +0,0 @@ -name = $name; - $this->args = $args; - $this->index = $index; - $this->currentFileInfo = $currentFileInfo; - } - - public function accept( $visitor ){ - $this->args = $visitor->visitArray( $this->args ); - } - - // - // When evaluating a function call, - // we either find the function in `tree.functions` [1], - // in which case we call it, passing the evaluated arguments, - // or we simply print it out as it appeared originally [2]. - // - // The *functions.js* file contains the built-in functions. - // - // The reason why we evaluate the arguments, is in the case where - // we try to pass a variable to a function, like: `saturate(@color)`. - // The function should receive the value, not the variable. - // - public function compile($env=null){ - $args = array(); - foreach($this->args as $a){ - $args[] = $a->compile($env); - } - - $nameLC = strtolower($this->name); - switch($nameLC){ - case '%': - $nameLC = '_percent'; - break; - - case 'get-unit': - $nameLC = 'getunit'; - break; - - case 'data-uri': - $nameLC = 'datauri'; - break; - - case 'svg-gradient': - $nameLC = 'svggradient'; - break; - } - - $result = null; - if( $nameLC === 'default' ){ - $result = Less_Tree_DefaultFunc::compile(); - - }else{ - - if( method_exists('Less_Functions',$nameLC) ){ // 1. - try { - - $func = new Less_Functions($env, $this->currentFileInfo); - $result = call_user_func_array( array($func,$nameLC),$args); - - } catch (Exception $e) { - throw new Less_Exception_Compiler('error evaluating function `' . $this->name . '` '.$e->getMessage().' index: '. $this->index); - } - } elseif( isset( $env->functions[$nameLC] ) && is_callable( $env->functions[$nameLC] ) ) { - try { - $result = call_user_func_array( $env->functions[$nameLC], $args ); - } catch (Exception $e) { - throw new Less_Exception_Compiler('error evaluating function `' . $this->name . '` '.$e->getMessage().' index: '. $this->index); - } - } - } - - if( $result !== null ){ - return $result; - } - - - return new Less_Tree_Call( $this->name, $args, $this->index, $this->currentFileInfo ); - } - - /** - * @see Less_Tree::genCSS - */ - public function genCSS( $output ){ - - $output->add( $this->name . '(', $this->currentFileInfo, $this->index ); - $args_len = count($this->args); - for($i = 0; $i < $args_len; $i++ ){ - $this->args[$i]->genCSS( $output ); - if( $i + 1 < $args_len ){ - $output->add( ', ' ); - } - } - - $output->add( ')' ); - } - - - //public function toCSS(){ - // return $this->compile()->toCSS(); - //} - -} diff --git a/vendor/oyejorge/less.php/lib/Less/Tree/Color.php b/vendor/oyejorge/less.php/lib/Less/Tree/Color.php deleted file mode 100644 index 77af07a..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Tree/Color.php +++ /dev/null @@ -1,230 +0,0 @@ -rgb = $rgb; - $this->alpha = $a; - $this->isTransparentKeyword = true; - return; - } - - $this->rgb = array(); - if( is_array($rgb) ){ - $this->rgb = $rgb; - }else if( strlen($rgb) == 6 ){ - foreach(str_split($rgb, 2) as $c){ - $this->rgb[] = hexdec($c); - } - }else{ - foreach(str_split($rgb, 1) as $c){ - $this->rgb[] = hexdec($c.$c); - } - } - $this->alpha = is_numeric($a) ? $a : 1; - } - - public function compile(){ - return $this; - } - - public function luma(){ - $r = $this->rgb[0] / 255; - $g = $this->rgb[1] / 255; - $b = $this->rgb[2] / 255; - - $r = ($r <= 0.03928) ? $r / 12.92 : pow((($r + 0.055) / 1.055), 2.4); - $g = ($g <= 0.03928) ? $g / 12.92 : pow((($g + 0.055) / 1.055), 2.4); - $b = ($b <= 0.03928) ? $b / 12.92 : pow((($b + 0.055) / 1.055), 2.4); - - return 0.2126 * $r + 0.7152 * $g + 0.0722 * $b; - } - - /** - * @see Less_Tree::genCSS - */ - public function genCSS( $output ){ - $output->add( $this->toCSS() ); - } - - public function toCSS( $doNotCompress = false ){ - $compress = Less_Parser::$options['compress'] && !$doNotCompress; - $alpha = Less_Functions::fround( $this->alpha ); - - - // - // If we have some transparency, the only way to represent it - // is via `rgba`. Otherwise, we use the hex representation, - // which has better compatibility with older browsers. - // Values are capped between `0` and `255`, rounded and zero-padded. - // - if( $alpha < 1 ){ - if( ( $alpha === 0 || $alpha === 0.0 ) && isset($this->isTransparentKeyword) && $this->isTransparentKeyword ){ - return 'transparent'; - } - - $values = array(); - foreach($this->rgb as $c){ - $values[] = Less_Functions::clamp( round($c), 255); - } - $values[] = $alpha; - - $glue = ($compress ? ',' : ', '); - return "rgba(" . implode($glue, $values) . ")"; - }else{ - - $color = $this->toRGB(); - - if( $compress ){ - - // Convert color to short format - if( $color[1] === $color[2] && $color[3] === $color[4] && $color[5] === $color[6]) { - $color = '#'.$color[1] . $color[3] . $color[5]; - } - } - - return $color; - } - } - - // - // Operations have to be done per-channel, if not, - // channels will spill onto each other. Once we have - // our result, in the form of an integer triplet, - // we create a new Color node to hold the result. - // - - /** - * @param string $op - */ - public function operate( $op, $other) { - $rgb = array(); - $alpha = $this->alpha * (1 - $other->alpha) + $other->alpha; - for ($c = 0; $c < 3; $c++) { - $rgb[$c] = Less_Functions::operate( $op, $this->rgb[$c], $other->rgb[$c]); - } - return new Less_Tree_Color($rgb, $alpha); - } - - public function toRGB(){ - return $this->toHex($this->rgb); - } - - public function toHSL(){ - $r = $this->rgb[0] / 255; - $g = $this->rgb[1] / 255; - $b = $this->rgb[2] / 255; - $a = $this->alpha; - - $max = max($r, $g, $b); - $min = min($r, $g, $b); - $l = ($max + $min) / 2; - $d = $max - $min; - - $h = $s = 0; - if( $max !== $min ){ - $s = $l > 0.5 ? $d / (2 - $max - $min) : $d / ($max + $min); - - switch ($max) { - case $r: $h = ($g - $b) / $d + ($g < $b ? 6 : 0); break; - case $g: $h = ($b - $r) / $d + 2; break; - case $b: $h = ($r - $g) / $d + 4; break; - } - $h /= 6; - } - return array('h' => $h * 360, 's' => $s, 'l' => $l, 'a' => $a ); - } - - //Adapted from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript - public function toHSV() { - $r = $this->rgb[0] / 255; - $g = $this->rgb[1] / 255; - $b = $this->rgb[2] / 255; - $a = $this->alpha; - - $max = max($r, $g, $b); - $min = min($r, $g, $b); - - $v = $max; - - $d = $max - $min; - if ($max === 0) { - $s = 0; - } else { - $s = $d / $max; - } - - $h = 0; - if( $max !== $min ){ - switch($max){ - case $r: $h = ($g - $b) / $d + ($g < $b ? 6 : 0); break; - case $g: $h = ($b - $r) / $d + 2; break; - case $b: $h = ($r - $g) / $d + 4; break; - } - $h /= 6; - } - return array('h'=> $h * 360, 's'=> $s, 'v'=> $v, 'a' => $a ); - } - - public function toARGB(){ - $argb = array_merge( (array) Less_Parser::round($this->alpha * 255), $this->rgb); - return $this->toHex( $argb ); - } - - public function compare($x){ - - if( !property_exists( $x, 'rgb' ) ){ - return -1; - } - - - return ($x->rgb[0] === $this->rgb[0] && - $x->rgb[1] === $this->rgb[1] && - $x->rgb[2] === $this->rgb[2] && - $x->alpha === $this->alpha) ? 0 : -1; - } - - public function toHex( $v ){ - - $ret = '#'; - foreach($v as $c){ - $c = Less_Functions::clamp( Less_Parser::round($c), 255); - if( $c < 16 ){ - $ret .= '0'; - } - $ret .= dechex($c); - } - - return $ret; - } - - - /** - * @param string $keyword - */ - public static function fromKeyword( $keyword ){ - $keyword = strtolower($keyword); - - if( Less_Colors::hasOwnProperty($keyword) ){ - // detect named color - return new Less_Tree_Color(substr(Less_Colors::color($keyword), 1)); - } - - if( $keyword === 'transparent' ){ - return new Less_Tree_Color( array(0, 0, 0), 0, true); - } - } - -} diff --git a/vendor/oyejorge/less.php/lib/Less/Tree/Comment.php b/vendor/oyejorge/less.php/lib/Less/Tree/Comment.php deleted file mode 100644 index 7261284..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Tree/Comment.php +++ /dev/null @@ -1,51 +0,0 @@ -value = $value; - $this->silent = !! $silent; - $this->currentFileInfo = $currentFileInfo; - } - - /** - * @see Less_Tree::genCSS - */ - public function genCSS( $output ){ - //if( $this->debugInfo ){ - //$output->add( tree.debugInfo($env, $this), $this->currentFileInfo, $this->index); - //} - $output->add( trim($this->value) );//TODO shouldn't need to trim, we shouldn't grab the \n - } - - public function toCSS(){ - return Less_Parser::$options['compress'] ? '' : $this->value; - } - - public function isSilent(){ - $isReference = ($this->currentFileInfo && isset($this->currentFileInfo['reference']) && (!isset($this->isReferenced) || !$this->isReferenced) ); - $isCompressed = Less_Parser::$options['compress'] && !preg_match('/^\/\*!/', $this->value); - return $this->silent || $isReference || $isCompressed; - } - - public function compile(){ - return $this; - } - - public function markReferenced(){ - $this->isReferenced = true; - } - -} diff --git a/vendor/oyejorge/less.php/lib/Less/Tree/Condition.php b/vendor/oyejorge/less.php/lib/Less/Tree/Condition.php deleted file mode 100644 index 929d33b..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Tree/Condition.php +++ /dev/null @@ -1,72 +0,0 @@ -op = trim($op); - $this->lvalue = $l; - $this->rvalue = $r; - $this->index = $i; - $this->negate = $negate; - } - - public function accept($visitor){ - $this->lvalue = $visitor->visitObj( $this->lvalue ); - $this->rvalue = $visitor->visitObj( $this->rvalue ); - } - - public function compile($env) { - $a = $this->lvalue->compile($env); - $b = $this->rvalue->compile($env); - - switch( $this->op ){ - case 'and': - $result = $a && $b; - break; - - case 'or': - $result = $a || $b; - break; - - default: - if( Less_Parser::is_method($a, 'compare') ){ - $result = $a->compare($b); - }elseif( Less_Parser::is_method($b, 'compare') ){ - $result = $b->compare($a); - }else{ - throw new Less_Exception_Compiler('Unable to perform comparison', null, $this->index); - } - - switch ($result) { - case -1: - $result = $this->op === '<' || $this->op === '=<' || $this->op === '<='; - break; - - case 0: - $result = $this->op === '=' || $this->op === '>=' || $this->op === '=<' || $this->op === '<='; - break; - - case 1: - $result = $this->op === '>' || $this->op === '>='; - break; - } - break; - } - - return $this->negate ? !$result : $result; - } - -} diff --git a/vendor/oyejorge/less.php/lib/Less/Tree/DefaultFunc.php b/vendor/oyejorge/less.php/lib/Less/Tree/DefaultFunc.php deleted file mode 100644 index c2dbf74..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Tree/DefaultFunc.php +++ /dev/null @@ -1,34 +0,0 @@ -ruleset = $ruleset; - $this->frames = $frames; - } - - public function accept($visitor) { - $this->ruleset = $visitor->visitObj($this->ruleset); - } - - public function compile($env){ - if( $this->frames ){ - $frames = $this->frames; - }else{ - $frames = $env->frames; - } - return new Less_Tree_DetachedRuleset($this->ruleset, $frames); - } - - public function callEval($env) { - if( $this->frames ){ - return $this->ruleset->compile( $env->copyEvalEnv( array_merge($this->frames,$env->frames) ) ); - } - return $this->ruleset->compile( $env ); - } -} - diff --git a/vendor/oyejorge/less.php/lib/Less/Tree/Dimension.php b/vendor/oyejorge/less.php/lib/Less/Tree/Dimension.php deleted file mode 100644 index 2bfb9d5..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Tree/Dimension.php +++ /dev/null @@ -1,201 +0,0 @@ -value = floatval($value); - - if( $unit && ($unit instanceof Less_Tree_Unit) ){ - $this->unit = $unit; - }elseif( $unit ){ - $this->unit = new Less_Tree_Unit( array($unit) ); - }else{ - $this->unit = new Less_Tree_Unit( ); - } - } - - public function accept( $visitor ){ - $this->unit = $visitor->visitObj( $this->unit ); - } - - public function compile(){ - return $this; - } - - public function toColor() { - return new Less_Tree_Color(array($this->value, $this->value, $this->value)); - } - - /** - * @see Less_Tree::genCSS - */ - public function genCSS( $output ){ - - if( Less_Parser::$options['strictUnits'] && !$this->unit->isSingular() ){ - throw new Less_Exception_Compiler("Multiple units in dimension. Correct the units or use the unit function. Bad unit: ".$this->unit->toString()); - } - - $value = Less_Functions::fround( $this->value ); - $strValue = (string)$value; - - if( $value !== 0 && $value < 0.000001 && $value > -0.000001 ){ - // would be output 1e-6 etc. - $strValue = number_format($strValue,10); - $strValue = preg_replace('/\.?0+$/','', $strValue); - } - - if( Less_Parser::$options['compress'] ){ - // Zero values doesn't need a unit - if( $value === 0 && $this->unit->isLength() ){ - $output->add( $strValue ); - return $strValue; - } - - // Float values doesn't need a leading zero - if( $value > 0 && $value < 1 && $strValue[0] === '0' ){ - $strValue = substr($strValue,1); - } - } - - $output->add( $strValue ); - $this->unit->genCSS( $output ); - } - - public function __toString(){ - return $this->toCSS(); - } - - // In an operation between two Dimensions, - // we default to the first Dimension's unit, - // so `1px + 2em` will yield `3px`. - - /** - * @param string $op - */ - public function operate( $op, $other){ - - $value = Less_Functions::operate( $op, $this->value, $other->value); - $unit = clone $this->unit; - - if( $op === '+' || $op === '-' ){ - - if( !$unit->numerator && !$unit->denominator ){ - $unit->numerator = $other->unit->numerator; - $unit->denominator = $other->unit->denominator; - }elseif( !$other->unit->numerator && !$other->unit->denominator ){ - // do nothing - }else{ - $other = $other->convertTo( $this->unit->usedUnits()); - - if( Less_Parser::$options['strictUnits'] && $other->unit->toString() !== $unit->toCSS() ){ - throw new Less_Exception_Compiler("Incompatible units. Change the units or use the unit function. Bad units: '" . $unit->toString() . "' and " . $other->unit->toString() . "'."); - } - - $value = Less_Functions::operate( $op, $this->value, $other->value); - } - }elseif( $op === '*' ){ - $unit->numerator = array_merge($unit->numerator, $other->unit->numerator); - $unit->denominator = array_merge($unit->denominator, $other->unit->denominator); - sort($unit->numerator); - sort($unit->denominator); - $unit->cancel(); - }elseif( $op === '/' ){ - $unit->numerator = array_merge($unit->numerator, $other->unit->denominator); - $unit->denominator = array_merge($unit->denominator, $other->unit->numerator); - sort($unit->numerator); - sort($unit->denominator); - $unit->cancel(); - } - return new Less_Tree_Dimension( $value, $unit); - } - - public function compare($other) { - if ($other instanceof Less_Tree_Dimension) { - - if( $this->unit->isEmpty() || $other->unit->isEmpty() ){ - $a = $this; - $b = $other; - } else { - $a = $this->unify(); - $b = $other->unify(); - if( $a->unit->compare($b->unit) !== 0 ){ - return -1; - } - } - $aValue = $a->value; - $bValue = $b->value; - - if ($bValue > $aValue) { - return -1; - } elseif ($bValue < $aValue) { - return 1; - } else { - return 0; - } - } else { - return -1; - } - } - - public function unify() { - return $this->convertTo(array('length'=> 'px', 'duration'=> 's', 'angle' => 'rad' )); - } - - public function convertTo($conversions) { - $value = $this->value; - $unit = clone $this->unit; - - if( is_string($conversions) ){ - $derivedConversions = array(); - foreach( Less_Tree_UnitConversions::$groups as $i ){ - if( isset(Less_Tree_UnitConversions::${$i}[$conversions]) ){ - $derivedConversions = array( $i => $conversions); - } - } - $conversions = $derivedConversions; - } - - - foreach($conversions as $groupName => $targetUnit){ - $group = Less_Tree_UnitConversions::${$groupName}; - - //numerator - foreach($unit->numerator as $i => $atomicUnit){ - $atomicUnit = $unit->numerator[$i]; - if( !isset($group[$atomicUnit]) ){ - continue; - } - - $value = $value * ($group[$atomicUnit] / $group[$targetUnit]); - - $unit->numerator[$i] = $targetUnit; - } - - //denominator - foreach($unit->denominator as $i => $atomicUnit){ - $atomicUnit = $unit->denominator[$i]; - if( !isset($group[$atomicUnit]) ){ - continue; - } - - $value = $value / ($group[$atomicUnit] / $group[$targetUnit]); - - $unit->denominator[$i] = $targetUnit; - } - } - - $unit->cancel(); - - return new Less_Tree_Dimension( $value, $unit); - } -} diff --git a/vendor/oyejorge/less.php/lib/Less/Tree/Directive.php b/vendor/oyejorge/less.php/lib/Less/Tree/Directive.php deleted file mode 100644 index 04a1e46..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Tree/Directive.php +++ /dev/null @@ -1,100 +0,0 @@ -name = $name; - $this->value = $value; - if( $rules ){ - $this->rules = $rules; - $this->rules->allowImports = true; - } - - $this->index = $index; - $this->currentFileInfo = $currentFileInfo; - $this->debugInfo = $debugInfo; - } - - - public function accept( $visitor ){ - if( $this->rules ){ - $this->rules = $visitor->visitObj( $this->rules ); - } - if( $this->value ){ - $this->value = $visitor->visitObj( $this->value ); - } - } - - - /** - * @see Less_Tree::genCSS - */ - public function genCSS( $output ){ - $value = $this->value; - $rules = $this->rules; - $output->add( $this->name, $this->currentFileInfo, $this->index ); - if( $this->value ){ - $output->add(' '); - $this->value->genCSS($output); - } - if( $this->rules ){ - Less_Tree::outputRuleset( $output, array($this->rules)); - } else { - $output->add(';'); - } - } - - public function compile($env){ - - $value = $this->value; - $rules = $this->rules; - if( $value ){ - $value = $value->compile($env); - } - - if( $rules ){ - $rules = $rules->compile($env); - $rules->root = true; - } - - return new Less_Tree_Directive( $this->name, $value, $rules, $this->index, $this->currentFileInfo, $this->debugInfo ); - } - - - public function variable($name){ - if( $this->rules ){ - return $this->rules->variable($name); - } - } - - public function find($selector){ - if( $this->rules ){ - return $this->rules->find($selector, $this); - } - } - - //rulesets: function () { if (this.rules) return tree.Ruleset.prototype.rulesets.apply(this.rules); }, - - public function markReferenced(){ - $this->isReferenced = true; - if( $this->rules ){ - Less_Tree::ReferencedArray($this->rules->rules); - } - } - -} diff --git a/vendor/oyejorge/less.php/lib/Less/Tree/Element.php b/vendor/oyejorge/less.php/lib/Less/Tree/Element.php deleted file mode 100644 index 9cea5e4..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Tree/Element.php +++ /dev/null @@ -1,75 +0,0 @@ -value = $value; - $this->value_is_object = is_object($value); - - if( $combinator ){ - $this->combinator = $combinator; - } - - $this->index = $index; - $this->currentFileInfo = $currentFileInfo; - } - - public function accept( $visitor ){ - if( $this->value_is_object ){ //object or string - $this->value = $visitor->visitObj( $this->value ); - } - } - - public function compile($env){ - - if( Less_Environment::$mixin_stack ){ - return new Less_Tree_Element($this->combinator, ($this->value_is_object ? $this->value->compile($env) : $this->value), $this->index, $this->currentFileInfo ); - } - - if( $this->value_is_object ){ - $this->value = $this->value->compile($env); - } - - return $this; - } - - /** - * @see Less_Tree::genCSS - */ - public function genCSS( $output ){ - $output->add( $this->toCSS(), $this->currentFileInfo, $this->index ); - } - - public function toCSS(){ - - if( $this->value_is_object ){ - $value = $this->value->toCSS(); - }else{ - $value = $this->value; - } - - - if( $value === '' && $this->combinator && $this->combinator === '&' ){ - return ''; - } - - - return Less_Environment::$_outputMap[$this->combinator] . $value; - } - -} diff --git a/vendor/oyejorge/less.php/lib/Less/Tree/Expression.php b/vendor/oyejorge/less.php/lib/Less/Tree/Expression.php deleted file mode 100644 index d834354..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Tree/Expression.php +++ /dev/null @@ -1,97 +0,0 @@ -value = $value; - $this->parens = $parens; - } - - public function accept( $visitor ){ - $this->value = $visitor->visitArray( $this->value ); - } - - public function compile($env) { - - $doubleParen = false; - - if( $this->parens && !$this->parensInOp ){ - Less_Environment::$parensStack++; - } - - $returnValue = null; - if( $this->value ){ - - $count = count($this->value); - - if( $count > 1 ){ - - $ret = array(); - foreach($this->value as $e){ - $ret[] = $e->compile($env); - } - $returnValue = new Less_Tree_Expression($ret); - - }else{ - - if( ($this->value[0] instanceof Less_Tree_Expression) && $this->value[0]->parens && !$this->value[0]->parensInOp ){ - $doubleParen = true; - } - - $returnValue = $this->value[0]->compile($env); - } - - } else { - $returnValue = $this; - } - - if( $this->parens ){ - if( !$this->parensInOp ){ - Less_Environment::$parensStack--; - - }elseif( !Less_Environment::isMathOn() && !$doubleParen ){ - $returnValue = new Less_Tree_Paren($returnValue); - - } - } - return $returnValue; - } - - /** - * @see Less_Tree::genCSS - */ - public function genCSS( $output ){ - $val_len = count($this->value); - for( $i = 0; $i < $val_len; $i++ ){ - $this->value[$i]->genCSS( $output ); - if( $i + 1 < $val_len ){ - $output->add( ' ' ); - } - } - } - - public function throwAwayComments() { - - if( is_array($this->value) ){ - $new_value = array(); - foreach($this->value as $v){ - if( $v instanceof Less_Tree_Comment ){ - continue; - } - $new_value[] = $v; - } - $this->value = $new_value; - } - } -} diff --git a/vendor/oyejorge/less.php/lib/Less/Tree/Extend.php b/vendor/oyejorge/less.php/lib/Less/Tree/Extend.php deleted file mode 100644 index 8f21e93..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Tree/Extend.php +++ /dev/null @@ -1,77 +0,0 @@ -selector = $selector; - $this->option = $option; - $this->index = $index; - - switch($option){ - case "all": - $this->allowBefore = true; - $this->allowAfter = true; - break; - default: - $this->allowBefore = false; - $this->allowAfter = false; - break; - } - - $this->object_id = $i++; - $this->parent_ids = array($this->object_id); - } - - public function accept( $visitor ){ - $this->selector = $visitor->visitObj( $this->selector ); - } - - public function compile( $env ){ - Less_Parser::$has_extends = true; - $this->selector = $this->selector->compile($env); - return $this; - //return new Less_Tree_Extend( $this->selector->compile($env), $this->option, $this->index); - } - - public function findSelfSelectors( $selectors ){ - $selfElements = array(); - - - for( $i = 0, $selectors_len = count($selectors); $i < $selectors_len; $i++ ){ - $selectorElements = $selectors[$i]->elements; - // duplicate the logic in genCSS function inside the selector node. - // future TODO - move both logics into the selector joiner visitor - if( $i && $selectorElements && $selectorElements[0]->combinator === "") { - $selectorElements[0]->combinator = ' '; - } - $selfElements = array_merge( $selfElements, $selectors[$i]->elements ); - } - - $this->selfSelectors = array(new Less_Tree_Selector($selfElements)); - } - -} \ No newline at end of file diff --git a/vendor/oyejorge/less.php/lib/Less/Tree/Import.php b/vendor/oyejorge/less.php/lib/Less/Tree/Import.php deleted file mode 100644 index 4e14afe..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Tree/Import.php +++ /dev/null @@ -1,304 +0,0 @@ -options = $options; - $this->index = $index; - $this->path = $path; - $this->features = $features; - $this->currentFileInfo = $currentFileInfo; - - if( is_array($options) ){ - $this->options += array('inline'=>false); - - if( isset($this->options['less']) || $this->options['inline'] ){ - $this->css = !isset($this->options['less']) || !$this->options['less'] || $this->options['inline']; - } else { - $pathValue = $this->getPath(); - if( $pathValue && preg_match('/css([\?;].*)?$/',$pathValue) ){ - $this->css = true; - } - } - } - } - -// -// The actual import node doesn't return anything, when converted to CSS. -// The reason is that it's used at the evaluation stage, so that the rules -// it imports can be treated like any other rules. -// -// In `eval`, we make sure all Import nodes get evaluated, recursively, so -// we end up with a flat structure, which can easily be imported in the parent -// ruleset. -// - - public function accept($visitor){ - - if( $this->features ){ - $this->features = $visitor->visitObj($this->features); - } - $this->path = $visitor->visitObj($this->path); - - if( !$this->options['inline'] && $this->root ){ - $this->root = $visitor->visit($this->root); - } - } - - /** - * @see Less_Tree::genCSS - */ - public function genCSS( $output ){ - if( $this->css ){ - - $output->add( '@import ', $this->currentFileInfo, $this->index ); - - $this->path->genCSS( $output ); - if( $this->features ){ - $output->add( ' ' ); - $this->features->genCSS( $output ); - } - $output->add( ';' ); - } - } - - public function toCSS(){ - $features = $this->features ? ' ' . $this->features->toCSS() : ''; - - if ($this->css) { - return "@import " . $this->path->toCSS() . $features . ";\n"; - } else { - return ""; - } - } - - /** - * @return string - */ - public function getPath(){ - if ($this->path instanceof Less_Tree_Quoted) { - $path = $this->path->value; - $path = ( isset($this->css) || preg_match('/(\.[a-z]*$)|([\?;].*)$/',$path)) ? $path : $path . '.less'; - } else if ($this->path instanceof Less_Tree_URL) { - $path = $this->path->value->value; - }else{ - return null; - } - - //remove query string and fragment - return preg_replace('/[\?#][^\?]*$/','',$path); - } - - public function compileForImport( $env ){ - return new Less_Tree_Import( $this->path->compile($env), $this->features, $this->options, $this->index, $this->currentFileInfo); - } - - public function compilePath($env) { - $path = $this->path->compile($env); - $rootpath = ''; - if( $this->currentFileInfo && $this->currentFileInfo['rootpath'] ){ - $rootpath = $this->currentFileInfo['rootpath']; - } - - - if( !($path instanceof Less_Tree_URL) ){ - if( $rootpath ){ - $pathValue = $path->value; - // Add the base path if the import is relative - if( $pathValue && Less_Environment::isPathRelative($pathValue) ){ - $path->value = $this->currentFileInfo['uri_root'].$pathValue; - } - } - $path->value = Less_Environment::normalizePath($path->value); - } - - - - return $path; - } - - public function compile( $env ){ - - $evald = $this->compileForImport($env); - - //get path & uri - $path_and_uri = null; - if( is_callable(Less_Parser::$options['import_callback']) ){ - $path_and_uri = call_user_func(Less_Parser::$options['import_callback'],$evald); - } - - if( !$path_and_uri ){ - $path_and_uri = $evald->PathAndUri(); - } - - if( $path_and_uri ){ - list($full_path, $uri) = $path_and_uri; - }else{ - $full_path = $uri = $evald->getPath(); - } - - - //import once - if( $evald->skip( $full_path, $env) ){ - return array(); - } - - if( $this->options['inline'] ){ - //todo needs to reference css file not import - //$contents = new Less_Tree_Anonymous($this->root, 0, array('filename'=>$this->importedFilename), true ); - - Less_Parser::AddParsedFile($full_path); - $contents = new Less_Tree_Anonymous( file_get_contents($full_path), 0, array(), true ); - - if( $this->features ){ - return new Less_Tree_Media( array($contents), $this->features->value ); - } - - return array( $contents ); - } - - // optional (need to be before "CSS" to support optional CSS imports. CSS should be checked only if empty($this->currentFileInfo)) - if( isset($this->options['optional']) && $this->options['optional'] && !file_exists($full_path) && (!$evald->css || !empty($this->currentFileInfo))) { - return array(); - } - - - // css ? - if( $evald->css ){ - $features = ( $evald->features ? $evald->features->compile($env) : null ); - return new Less_Tree_Import( $this->compilePath( $env), $features, $this->options, $this->index); - } - - - return $this->ParseImport( $full_path, $uri, $env ); - } - - - /** - * Using the import directories, get the full absolute path and uri of the import - * - * @param Less_Tree_Import $evald - */ - public function PathAndUri(){ - - $evald_path = $this->getPath(); - - if( $evald_path ){ - - $import_dirs = array(); - - if( Less_Environment::isPathRelative($evald_path) ){ - //if the path is relative, the file should be in the current directory - $import_dirs[ $this->currentFileInfo['currentDirectory'] ] = $this->currentFileInfo['uri_root']; - - }else{ - //otherwise, the file should be relative to the server root - $import_dirs[ $this->currentFileInfo['entryPath'] ] = $this->currentFileInfo['entryUri']; - - //if the user supplied entryPath isn't the actual root - $import_dirs[ $_SERVER['DOCUMENT_ROOT'] ] = ''; - - } - - // always look in user supplied import directories - $import_dirs = array_merge( $import_dirs, Less_Parser::$options['import_dirs'] ); - - - foreach( $import_dirs as $rootpath => $rooturi){ - if( is_callable($rooturi) ){ - list($path, $uri) = call_user_func($rooturi, $evald_path); - if( is_string($path) ){ - $full_path = $path; - return array( $full_path, $uri ); - } - }elseif( !empty($rootpath) ){ - - $path = rtrim($rootpath,'/\\').'/'.ltrim($evald_path,'/\\'); - - if( file_exists($path) ){ - $full_path = Less_Environment::normalizePath($path); - $uri = Less_Environment::normalizePath(dirname($rooturi.$evald_path)); - return array( $full_path, $uri ); - } elseif( file_exists($path.'.less') ){ - $full_path = Less_Environment::normalizePath($path.'.less'); - $uri = Less_Environment::normalizePath(dirname($rooturi.$evald_path.'.less')); - return array( $full_path, $uri ); - } - } - } - } - } - - - /** - * Parse the import url and return the rules - * - * @return Less_Tree_Media|array - */ - public function ParseImport( $full_path, $uri, $env ){ - - $import_env = clone $env; - if( (isset($this->options['reference']) && $this->options['reference']) || isset($this->currentFileInfo['reference']) ){ - $import_env->currentFileInfo['reference'] = true; - } - - if( (isset($this->options['multiple']) && $this->options['multiple']) ){ - $import_env->importMultiple = true; - } - - $parser = new Less_Parser($import_env); - $root = $parser->parseFile($full_path, $uri, true); - - - $ruleset = new Less_Tree_Ruleset(array(), $root->rules ); - $ruleset->evalImports($import_env); - - return $this->features ? new Less_Tree_Media($ruleset->rules, $this->features->value) : $ruleset->rules; - } - - - /** - * Should the import be skipped? - * - * @return boolean|null - */ - private function Skip($path, $env){ - - $path = Less_Parser::AbsPath($path, true); - - if( $path && Less_Parser::FileParsed($path) ){ - - if( isset($this->currentFileInfo['reference']) ){ - return true; - } - - return !isset($this->options['multiple']) && !$env->importMultiple; - } - - } -} diff --git a/vendor/oyejorge/less.php/lib/Less/Tree/Javascript.php b/vendor/oyejorge/less.php/lib/Less/Tree/Javascript.php deleted file mode 100644 index 1b03183..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Tree/Javascript.php +++ /dev/null @@ -1,30 +0,0 @@ -escaped = $escaped; - $this->expression = $string; - $this->index = $index; - } - - public function compile(){ - return new Less_Tree_Anonymous('/* Sorry, can not do JavaScript evaluation in PHP... :( */'); - } - -} diff --git a/vendor/oyejorge/less.php/lib/Less/Tree/Keyword.php b/vendor/oyejorge/less.php/lib/Less/Tree/Keyword.php deleted file mode 100644 index e1d98c4..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Tree/Keyword.php +++ /dev/null @@ -1,44 +0,0 @@ -value = $value; - } - - public function compile(){ - return $this; - } - - /** - * @see Less_Tree::genCSS - */ - public function genCSS( $output ){ - - if( $this->value === '%') { - throw new Less_Exception_Compiler("Invalid % without number"); - } - - $output->add( $this->value ); - } - - public function compare($other) { - if ($other instanceof Less_Tree_Keyword) { - return $other->value === $this->value ? 0 : 1; - } else { - return -1; - } - } -} diff --git a/vendor/oyejorge/less.php/lib/Less/Tree/Media.php b/vendor/oyejorge/less.php/lib/Less/Tree/Media.php deleted file mode 100644 index f9ee9d4..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Tree/Media.php +++ /dev/null @@ -1,179 +0,0 @@ -index = $index; - $this->currentFileInfo = $currentFileInfo; - - $selectors = $this->emptySelectors(); - - $this->features = new Less_Tree_Value($features); - - $this->rules = array(new Less_Tree_Ruleset($selectors, $value)); - $this->rules[0]->allowImports = true; - } - - public function accept( $visitor ){ - $this->features = $visitor->visitObj($this->features); - $this->rules = $visitor->visitArray($this->rules); - } - - /** - * @see Less_Tree::genCSS - */ - public function genCSS( $output ){ - - $output->add( '@media ', $this->currentFileInfo, $this->index ); - $this->features->genCSS( $output ); - Less_Tree::outputRuleset( $output, $this->rules); - - } - - public function compile($env) { - - $media = new Less_Tree_Media(array(), array(), $this->index, $this->currentFileInfo ); - - $strictMathBypass = false; - if( Less_Parser::$options['strictMath'] === false) { - $strictMathBypass = true; - Less_Parser::$options['strictMath'] = true; - } - - $media->features = $this->features->compile($env); - - if( $strictMathBypass ){ - Less_Parser::$options['strictMath'] = false; - } - - $env->mediaPath[] = $media; - $env->mediaBlocks[] = $media; - - array_unshift($env->frames, $this->rules[0]); - $media->rules = array($this->rules[0]->compile($env)); - array_shift($env->frames); - - array_pop($env->mediaPath); - - return !$env->mediaPath ? $media->compileTop($env) : $media->compileNested($env); - } - - public function variable($name) { - return $this->rules[0]->variable($name); - } - - public function find($selector) { - return $this->rules[0]->find($selector, $this); - } - - public function emptySelectors(){ - $el = new Less_Tree_Element('','&', $this->index, $this->currentFileInfo ); - $sels = array( new Less_Tree_Selector(array($el), array(), null, $this->index, $this->currentFileInfo) ); - $sels[0]->mediaEmpty = true; - return $sels; - } - - public function markReferenced(){ - $this->rules[0]->markReferenced(); - $this->isReferenced = true; - Less_Tree::ReferencedArray($this->rules[0]->rules); - } - - // evaltop - public function compileTop($env) { - $result = $this; - - if (count($env->mediaBlocks) > 1) { - $selectors = $this->emptySelectors(); - $result = new Less_Tree_Ruleset($selectors, $env->mediaBlocks); - $result->multiMedia = true; - } - - $env->mediaBlocks = array(); - $env->mediaPath = array(); - - return $result; - } - - public function compileNested($env) { - $path = array_merge($env->mediaPath, array($this)); - - // Extract the media-query conditions separated with `,` (OR). - foreach ($path as $key => $p) { - $value = $p->features instanceof Less_Tree_Value ? $p->features->value : $p->features; - $path[$key] = is_array($value) ? $value : array($value); - } - - // Trace all permutations to generate the resulting media-query. - // - // (a, b and c) with nested (d, e) -> - // a and d - // a and e - // b and c and d - // b and c and e - - $permuted = $this->permute($path); - $expressions = array(); - foreach($permuted as $path){ - - for( $i=0, $len=count($path); $i < $len; $i++){ - $path[$i] = Less_Parser::is_method($path[$i], 'toCSS') ? $path[$i] : new Less_Tree_Anonymous($path[$i]); - } - - for( $i = count($path) - 1; $i > 0; $i-- ){ - array_splice($path, $i, 0, array(new Less_Tree_Anonymous('and'))); - } - - $expressions[] = new Less_Tree_Expression($path); - } - $this->features = new Less_Tree_Value($expressions); - - - - // Fake a tree-node that doesn't output anything. - return new Less_Tree_Ruleset(array(), array()); - } - - public function permute($arr) { - if (!$arr) - return array(); - - if (count($arr) == 1) - return $arr[0]; - - $result = array(); - $rest = $this->permute(array_slice($arr, 1)); - foreach ($rest as $r) { - foreach ($arr[0] as $a) { - $result[] = array_merge( - is_array($a) ? $a : array($a), - is_array($r) ? $r : array($r) - ); - } - } - - return $result; - } - - public function bubbleSelectors($selectors) { - - if( !$selectors) return; - - $this->rules = array(new Less_Tree_Ruleset( $selectors, array($this->rules[0]))); - } - -} diff --git a/vendor/oyejorge/less.php/lib/Less/Tree/Mixin/Call.php b/vendor/oyejorge/less.php/lib/Less/Tree/Mixin/Call.php deleted file mode 100644 index 04eb426..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Tree/Mixin/Call.php +++ /dev/null @@ -1,202 +0,0 @@ -selector = new Less_Tree_Selector($elements); - $this->arguments = $args; - $this->index = $index; - $this->currentFileInfo = $currentFileInfo; - $this->important = $important; - } - - //function accept($visitor){ - // $this->selector = $visitor->visit($this->selector); - // $this->arguments = $visitor->visit($this->arguments); - //} - - - public function compile($env){ - - $rules = array(); - $match = false; - $isOneFound = false; - $candidates = array(); - $defaultUsed = false; - $conditionResult = array(); - - $args = array(); - foreach($this->arguments as $a){ - $args[] = array('name'=> $a['name'], 'value' => $a['value']->compile($env) ); - } - - foreach($env->frames as $frame){ - - $mixins = $frame->find($this->selector); - - if( !$mixins ){ - continue; - } - - $isOneFound = true; - $defNone = 0; - $defTrue = 1; - $defFalse = 2; - - // To make `default()` function independent of definition order we have two "subpasses" here. - // At first we evaluate each guard *twice* (with `default() == true` and `default() == false`), - // and build candidate list with corresponding flags. Then, when we know all possible matches, - // we make a final decision. - - $mixins_len = count($mixins); - for( $m = 0; $m < $mixins_len; $m++ ){ - $mixin = $mixins[$m]; - - if( $this->IsRecursive( $env, $mixin ) ){ - continue; - } - - if( $mixin->matchArgs($args, $env) ){ - - $candidate = array('mixin' => $mixin, 'group' => $defNone); - - if( $mixin instanceof Less_Tree_Ruleset ){ - - for( $f = 0; $f < 2; $f++ ){ - Less_Tree_DefaultFunc::value($f); - $conditionResult[$f] = $mixin->matchCondition( $args, $env); - } - if( $conditionResult[0] || $conditionResult[1] ){ - if( $conditionResult[0] != $conditionResult[1] ){ - $candidate['group'] = $conditionResult[1] ? $defTrue : $defFalse; - } - - $candidates[] = $candidate; - } - }else{ - $candidates[] = $candidate; - } - - $match = true; - } - } - - Less_Tree_DefaultFunc::reset(); - - - $count = array(0, 0, 0); - for( $m = 0; $m < count($candidates); $m++ ){ - $count[ $candidates[$m]['group'] ]++; - } - - if( $count[$defNone] > 0 ){ - $defaultResult = $defFalse; - } else { - $defaultResult = $defTrue; - if( ($count[$defTrue] + $count[$defFalse]) > 1 ){ - throw new Exception( 'Ambiguous use of `default()` found when matching for `' . $this->format($args) . '`' ); - } - } - - - $candidates_length = count($candidates); - $length_1 = ($candidates_length == 1); - - for( $m = 0; $m < $candidates_length; $m++){ - $candidate = $candidates[$m]['group']; - if( ($candidate === $defNone) || ($candidate === $defaultResult) ){ - try{ - $mixin = $candidates[$m]['mixin']; - if( !($mixin instanceof Less_Tree_Mixin_Definition) ){ - $mixin = new Less_Tree_Mixin_Definition('', array(), $mixin->rules, null, false); - $mixin->originalRuleset = $mixins[$m]->originalRuleset; - } - $rules = array_merge($rules, $mixin->evalCall($env, $args, $this->important)->rules); - } catch (Exception $e) { - //throw new Less_Exception_Compiler($e->getMessage(), $e->index, null, $this->currentFileInfo['filename']); - throw new Less_Exception_Compiler($e->getMessage(), null, null, $this->currentFileInfo); - } - } - } - - if( $match ){ - if( !$this->currentFileInfo || !isset($this->currentFileInfo['reference']) || !$this->currentFileInfo['reference'] ){ - Less_Tree::ReferencedArray($rules); - } - - return $rules; - } - } - - if( $isOneFound ){ - throw new Less_Exception_Compiler('No matching definition was found for `'.$this->Format( $args ).'`', null, $this->index, $this->currentFileInfo); - - }else{ - throw new Less_Exception_Compiler(trim($this->selector->toCSS()) . " is undefined in ".$this->currentFileInfo['filename'], null, $this->index); - } - - } - - /** - * Format the args for use in exception messages - * - */ - private function Format($args){ - $message = array(); - if( $args ){ - foreach($args as $a){ - $argValue = ''; - if( $a['name'] ){ - $argValue .= $a['name'] . ':'; - } - if( is_object($a['value']) ){ - $argValue .= $a['value']->toCSS(); - }else{ - $argValue .= '???'; - } - $message[] = $argValue; - } - } - return implode(', ',$message); - } - - - /** - * Are we in a recursive mixin call? - * - * @return bool - */ - private function IsRecursive( $env, $mixin ){ - - foreach($env->frames as $recur_frame){ - if( !($mixin instanceof Less_Tree_Mixin_Definition) ){ - - if( $mixin === $recur_frame ){ - return true; - } - - if( isset($recur_frame->originalRuleset) && $mixin->ruleset_id === $recur_frame->originalRuleset ){ - return true; - } - } - } - - return false; - } - -} - - diff --git a/vendor/oyejorge/less.php/lib/Less/Tree/Mixin/Definition.php b/vendor/oyejorge/less.php/lib/Less/Tree/Mixin/Definition.php deleted file mode 100644 index b16d688..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Tree/Mixin/Definition.php +++ /dev/null @@ -1,241 +0,0 @@ -name = $name; - $this->selectors = array(new Less_Tree_Selector(array( new Less_Tree_Element(null, $name)))); - - $this->params = $params; - $this->condition = $condition; - $this->variadic = $variadic; - $this->rules = $rules; - - if( $params ){ - $this->arity = count($params); - foreach( $params as $p ){ - if (! isset($p['name']) || ($p['name'] && !isset($p['value']))) { - $this->required++; - } - } - } - - $this->frames = $frames; - $this->SetRulesetIndex(); - } - - - - //function accept( $visitor ){ - // $this->params = $visitor->visit($this->params); - // $this->rules = $visitor->visit($this->rules); - // $this->condition = $visitor->visit($this->condition); - //} - - - public function toCSS(){ - return ''; - } - - // less.js : /lib/less/tree/mixin.js : tree.mixin.Definition.evalParams - public function compileParams($env, $mixinFrames, $args = array() , &$evaldArguments = array() ){ - $frame = new Less_Tree_Ruleset(null, array()); - $params = $this->params; - $mixinEnv = null; - $argsLength = 0; - - if( $args ){ - $argsLength = count($args); - for($i = 0; $i < $argsLength; $i++ ){ - $arg = $args[$i]; - - if( $arg && $arg['name'] ){ - $isNamedFound = false; - - foreach($params as $j => $param){ - if( !isset($evaldArguments[$j]) && $arg['name'] === $params[$j]['name']) { - $evaldArguments[$j] = $arg['value']->compile($env); - array_unshift($frame->rules, new Less_Tree_Rule( $arg['name'], $arg['value']->compile($env) ) ); - $isNamedFound = true; - break; - } - } - if ($isNamedFound) { - array_splice($args, $i, 1); - $i--; - $argsLength--; - continue; - } else { - throw new Less_Exception_Compiler("Named argument for " . $this->name .' '.$args[$i]['name'] . ' not found'); - } - } - } - } - - $argIndex = 0; - foreach($params as $i => $param){ - - if ( isset($evaldArguments[$i]) ){ continue; } - - $arg = null; - if( isset($args[$argIndex]) ){ - $arg = $args[$argIndex]; - } - - if (isset($param['name']) && $param['name']) { - - if( isset($param['variadic']) ){ - $varargs = array(); - for ($j = $argIndex; $j < $argsLength; $j++) { - $varargs[] = $args[$j]['value']->compile($env); - } - $expression = new Less_Tree_Expression($varargs); - array_unshift($frame->rules, new Less_Tree_Rule($param['name'], $expression->compile($env))); - }else{ - $val = ($arg && $arg['value']) ? $arg['value'] : false; - - if ($val) { - $val = $val->compile($env); - } else if ( isset($param['value']) ) { - - if( !$mixinEnv ){ - $mixinEnv = new Less_Environment(); - $mixinEnv->frames = array_merge( array($frame), $mixinFrames); - } - - $val = $param['value']->compile($mixinEnv); - $frame->resetCache(); - } else { - throw new Less_Exception_Compiler("Wrong number of arguments for " . $this->name . " (" . $argsLength . ' for ' . $this->arity . ")"); - } - - array_unshift($frame->rules, new Less_Tree_Rule($param['name'], $val)); - $evaldArguments[$i] = $val; - } - } - - if ( isset($param['variadic']) && $args) { - for ($j = $argIndex; $j < $argsLength; $j++) { - $evaldArguments[$j] = $args[$j]['value']->compile($env); - } - } - $argIndex++; - } - - ksort($evaldArguments); - $evaldArguments = array_values($evaldArguments); - - return $frame; - } - - public function compile($env) { - if( $this->frames ){ - return new Less_Tree_Mixin_Definition($this->name, $this->params, $this->rules, $this->condition, $this->variadic, $this->frames ); - } - return new Less_Tree_Mixin_Definition($this->name, $this->params, $this->rules, $this->condition, $this->variadic, $env->frames ); - } - - public function evalCall($env, $args = NULL, $important = NULL) { - - Less_Environment::$mixin_stack++; - - $_arguments = array(); - - if( $this->frames ){ - $mixinFrames = array_merge($this->frames, $env->frames); - }else{ - $mixinFrames = $env->frames; - } - - $frame = $this->compileParams($env, $mixinFrames, $args, $_arguments); - - $ex = new Less_Tree_Expression($_arguments); - array_unshift($frame->rules, new Less_Tree_Rule('@arguments', $ex->compile($env))); - - - $ruleset = new Less_Tree_Ruleset(null, $this->rules); - $ruleset->originalRuleset = $this->ruleset_id; - - - $ruleSetEnv = new Less_Environment(); - $ruleSetEnv->frames = array_merge( array($this, $frame), $mixinFrames ); - $ruleset = $ruleset->compile( $ruleSetEnv ); - - if( $important ){ - $ruleset = $ruleset->makeImportant(); - } - - Less_Environment::$mixin_stack--; - - return $ruleset; - } - - - public function matchCondition($args, $env) { - - if( !$this->condition ){ - return true; - } - - // set array to prevent error on array_merge - if(!is_array($this->frames)) { - $this->frames = array(); - } - - $frame = $this->compileParams($env, array_merge($this->frames,$env->frames), $args ); - - $compile_env = new Less_Environment(); - $compile_env->frames = array_merge( - array($frame) // the parameter variables - , $this->frames // the parent namespace/mixin frames - , $env->frames // the current environment frames - ); - - $compile_env->functions = $env->functions; - - return (bool)$this->condition->compile($compile_env); - } - - public function matchArgs($args, $env = NULL){ - $argsLength = count($args); - - if( !$this->variadic ){ - if( $argsLength < $this->required ){ - return false; - } - if( $argsLength > count($this->params) ){ - return false; - } - }else{ - if( $argsLength < ($this->required - 1)){ - return false; - } - } - - $len = min($argsLength, $this->arity); - - for( $i = 0; $i < $len; $i++ ){ - if( !isset($this->params[$i]['name']) && !isset($this->params[$i]['variadic']) ){ - if( $args[$i]['value']->compile($env)->toCSS() != $this->params[$i]['value']->compile($env)->toCSS() ){ - return false; - } - } - } - - return true; - } - -} diff --git a/vendor/oyejorge/less.php/lib/Less/Tree/NameValue.php b/vendor/oyejorge/less.php/lib/Less/Tree/NameValue.php deleted file mode 100644 index 31cbe03..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Tree/NameValue.php +++ /dev/null @@ -1,51 +0,0 @@ - color:#FF0000; - * - * @package Less - * @subpackage tree - */ -class Less_Tree_NameValue extends Less_Tree{ - - public $name; - public $value; - public $index; - public $currentFileInfo; - public $type = 'NameValue'; - public $important = ''; - - public function __construct($name, $value = null, $index = null, $currentFileInfo = null ){ - $this->name = $name; - $this->value = $value; - $this->index = $index; - $this->currentFileInfo = $currentFileInfo; - } - - public function genCSS( $output ){ - - $output->add( - $this->name - . Less_Environment::$_outputMap[': '] - . $this->value - . $this->important - . (((Less_Environment::$lastRule && Less_Parser::$options['compress'])) ? "" : ";") - , $this->currentFileInfo, $this->index); - } - - public function compile ($env){ - return $this; - } - - public function makeImportant(){ - $new = new Less_Tree_NameValue($this->name, $this->value, $this->index, $this->currentFileInfo); - $new->important = ' !important'; - return $new; - } - - -} diff --git a/vendor/oyejorge/less.php/lib/Less/Tree/Negative.php b/vendor/oyejorge/less.php/lib/Less/Tree/Negative.php deleted file mode 100644 index 507443e..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Tree/Negative.php +++ /dev/null @@ -1,37 +0,0 @@ -value = $node; - } - - //function accept($visitor) { - // $this->value = $visitor->visit($this->value); - //} - - /** - * @see Less_Tree::genCSS - */ - public function genCSS( $output ){ - $output->add( '-' ); - $this->value->genCSS( $output ); - } - - public function compile($env) { - if( Less_Environment::isMathOn() ){ - $ret = new Less_Tree_Operation('*', array( new Less_Tree_Dimension(-1), $this->value ) ); - return $ret->compile($env); - } - return new Less_Tree_Negative( $this->value->compile($env) ); - } -} \ No newline at end of file diff --git a/vendor/oyejorge/less.php/lib/Less/Tree/Operation.php b/vendor/oyejorge/less.php/lib/Less/Tree/Operation.php deleted file mode 100644 index e69e0da..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Tree/Operation.php +++ /dev/null @@ -1,70 +0,0 @@ -op = trim($op); - $this->operands = $operands; - $this->isSpaced = $isSpaced; - } - - public function accept($visitor) { - $this->operands = $visitor->visitArray($this->operands); - } - - public function compile($env){ - $a = $this->operands[0]->compile($env); - $b = $this->operands[1]->compile($env); - - - if( Less_Environment::isMathOn() ){ - - if( $a instanceof Less_Tree_Dimension && $b instanceof Less_Tree_Color ){ - $a = $a->toColor(); - - }elseif( $b instanceof Less_Tree_Dimension && $a instanceof Less_Tree_Color ){ - $b = $b->toColor(); - - } - - if( !method_exists($a,'operate') ){ - throw new Less_Exception_Compiler("Operation on an invalid type"); - } - - return $a->operate( $this->op, $b); - } - - return new Less_Tree_Operation($this->op, array($a, $b), $this->isSpaced ); - } - - - /** - * @see Less_Tree::genCSS - */ - public function genCSS( $output ){ - $this->operands[0]->genCSS( $output ); - if( $this->isSpaced ){ - $output->add( " " ); - } - $output->add( $this->op ); - if( $this->isSpaced ){ - $output->add( ' ' ); - } - $this->operands[1]->genCSS( $output ); - } - -} diff --git a/vendor/oyejorge/less.php/lib/Less/Tree/Paren.php b/vendor/oyejorge/less.php/lib/Less/Tree/Paren.php deleted file mode 100644 index 0186455..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Tree/Paren.php +++ /dev/null @@ -1,35 +0,0 @@ -value = $value; - } - - public function accept($visitor){ - $this->value = $visitor->visitObj($this->value); - } - - /** - * @see Less_Tree::genCSS - */ - public function genCSS( $output ){ - $output->add( '(' ); - $this->value->genCSS( $output ); - $output->add( ')' ); - } - - public function compile($env) { - return new Less_Tree_Paren($this->value->compile($env)); - } - -} diff --git a/vendor/oyejorge/less.php/lib/Less/Tree/Quoted.php b/vendor/oyejorge/less.php/lib/Less/Tree/Quoted.php deleted file mode 100644 index 80063b5..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Tree/Quoted.php +++ /dev/null @@ -1,81 +0,0 @@ -escaped = $escaped; - $this->value = $content; - if( $str ){ - $this->quote = $str[0]; - } - $this->index = $index; - $this->currentFileInfo = $currentFileInfo; - } - - /** - * @see Less_Tree::genCSS - */ - public function genCSS( $output ){ - if( !$this->escaped ){ - $output->add( $this->quote, $this->currentFileInfo, $this->index ); - } - $output->add( $this->value ); - if( !$this->escaped ){ - $output->add( $this->quote ); - } - } - - public function compile($env){ - - $value = $this->value; - if( preg_match_all('/`([^`]+)`/', $this->value, $matches) ){ - foreach($matches as $i => $match){ - $js = new Less_Tree_JavaScript($matches[1], $this->index, true); - $js = $js->compile()->value; - $value = str_replace($matches[0][$i], $js, $value); - } - } - - if( preg_match_all('/@\{([\w-]+)\}/',$value,$matches) ){ - foreach($matches[1] as $i => $match){ - $v = new Less_Tree_Variable('@' . $match, $this->index, $this->currentFileInfo ); - $v = $v->compile($env); - $v = ($v instanceof Less_Tree_Quoted) ? $v->value : $v->toCSS(); - $value = str_replace($matches[0][$i], $v, $value); - } - } - - return new Less_Tree_Quoted($this->quote . $value . $this->quote, $value, $this->escaped, $this->index, $this->currentFileInfo); - } - - public function compare($x) { - - if( !Less_Parser::is_method($x, 'toCSS') ){ - return -1; - } - - $left = $this->toCSS(); - $right = $x->toCSS(); - - if ($left === $right) { - return 0; - } - - return $left < $right ? -1 : 1; - } -} diff --git a/vendor/oyejorge/less.php/lib/Less/Tree/Rule.php b/vendor/oyejorge/less.php/lib/Less/Tree/Rule.php deleted file mode 100644 index ee4a9e2..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Tree/Rule.php +++ /dev/null @@ -1,115 +0,0 @@ -name = $name; - $this->value = ($value instanceof Less_Tree_Value || $value instanceof Less_Tree_Ruleset) ? $value : new Less_Tree_Value(array($value)); - $this->important = $important ? ' ' . trim($important) : ''; - $this->merge = $merge; - $this->index = $index; - $this->currentFileInfo = $currentFileInfo; - $this->inline = $inline; - $this->variable = ( is_string($name) && $name[0] === '@'); - } - - public function accept($visitor) { - $this->value = $visitor->visitObj( $this->value ); - } - - /** - * @see Less_Tree::genCSS - */ - public function genCSS( $output ){ - - $output->add( $this->name . Less_Environment::$_outputMap[': '], $this->currentFileInfo, $this->index); - try{ - $this->value->genCSS( $output); - - }catch( Less_Exception_Parser $e ){ - $e->index = $this->index; - $e->currentFile = $this->currentFileInfo; - throw $e; - } - $output->add( $this->important . (($this->inline || (Less_Environment::$lastRule && Less_Parser::$options['compress'])) ? "" : ";"), $this->currentFileInfo, $this->index); - } - - public function compile ($env){ - - $name = $this->name; - if( is_array($name) ){ - // expand 'primitive' name directly to get - // things faster (~10% for benchmark.less): - if( count($name) === 1 && $name[0] instanceof Less_Tree_Keyword ){ - $name = $name[0]->value; - }else{ - $name = $this->CompileName($env,$name); - } - } - - $strictMathBypass = Less_Parser::$options['strictMath']; - if( $name === "font" && !Less_Parser::$options['strictMath'] ){ - Less_Parser::$options['strictMath'] = true; - } - - try { - $evaldValue = $this->value->compile($env); - - if( !$this->variable && $evaldValue->type === "DetachedRuleset") { - throw new Less_Exception_Compiler("Rulesets cannot be evaluated on a property.", null, $this->index, $this->currentFileInfo); - } - - if( Less_Environment::$mixin_stack ){ - $return = new Less_Tree_Rule($name, $evaldValue, $this->important, $this->merge, $this->index, $this->currentFileInfo, $this->inline); - }else{ - $this->name = $name; - $this->value = $evaldValue; - $return = $this; - } - - }catch( Less_Exception_Parser $e ){ - if( !is_numeric($e->index) ){ - $e->index = $this->index; - $e->currentFile = $this->currentFileInfo; - } - throw $e; - } - - Less_Parser::$options['strictMath'] = $strictMathBypass; - - return $return; - } - - - public function CompileName( $env, $name ){ - $output = new Less_Output(); - foreach($name as $n){ - $n->compile($env)->genCSS($output); - } - return $output->toString(); - } - - public function makeImportant(){ - return new Less_Tree_Rule($this->name, $this->value, '!important', $this->merge, $this->index, $this->currentFileInfo, $this->inline); - } - -} diff --git a/vendor/oyejorge/less.php/lib/Less/Tree/Ruleset.php b/vendor/oyejorge/less.php/lib/Less/Tree/Ruleset.php deleted file mode 100644 index bdf9fec..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Tree/Ruleset.php +++ /dev/null @@ -1,643 +0,0 @@ -ruleset_id = Less_Parser::$next_id++; - $this->originalRuleset = $this->ruleset_id; - - if( $this->selectors ){ - foreach($this->selectors as $sel){ - if( $sel->_oelements ){ - $this->first_oelements[$sel->_oelements[0]] = true; - } - } - } - } - - public function __construct($selectors, $rules, $strictImports = null){ - $this->selectors = $selectors; - $this->rules = $rules; - $this->lookups = array(); - $this->strictImports = $strictImports; - $this->SetRulesetIndex(); - } - - public function accept( $visitor ){ - if( $this->paths ){ - $paths_len = count($this->paths); - for($i = 0,$paths_len; $i < $paths_len; $i++ ){ - $this->paths[$i] = $visitor->visitArray($this->paths[$i]); - } - }elseif( $this->selectors ){ - $this->selectors = $visitor->visitArray($this->selectors); - } - - if( $this->rules ){ - $this->rules = $visitor->visitArray($this->rules); - } - } - - public function compile($env){ - - $ruleset = $this->PrepareRuleset($env); - - - // Store the frames around mixin definitions, - // so they can be evaluated like closures when the time comes. - $rsRuleCnt = count($ruleset->rules); - for( $i = 0; $i < $rsRuleCnt; $i++ ){ - if( $ruleset->rules[$i] instanceof Less_Tree_Mixin_Definition || $ruleset->rules[$i] instanceof Less_Tree_DetachedRuleset ){ - $ruleset->rules[$i] = $ruleset->rules[$i]->compile($env); - } - } - - $mediaBlockCount = 0; - if( $env instanceof Less_Environment ){ - $mediaBlockCount = count($env->mediaBlocks); - } - - // Evaluate mixin calls. - $this->EvalMixinCalls( $ruleset, $env, $rsRuleCnt ); - - - // Evaluate everything else - for( $i=0; $i<$rsRuleCnt; $i++ ){ - if(! ($ruleset->rules[$i] instanceof Less_Tree_Mixin_Definition || $ruleset->rules[$i] instanceof Less_Tree_DetachedRuleset) ){ - $ruleset->rules[$i] = $ruleset->rules[$i]->compile($env); - } - } - - // Evaluate everything else - for( $i=0; $i<$rsRuleCnt; $i++ ){ - $rule = $ruleset->rules[$i]; - - // for rulesets, check if it is a css guard and can be removed - if( $rule instanceof Less_Tree_Ruleset && $rule->selectors && count($rule->selectors) === 1 ){ - - // check if it can be folded in (e.g. & where) - if( $rule->selectors[0]->isJustParentSelector() ){ - array_splice($ruleset->rules,$i--,1); - $rsRuleCnt--; - - for($j = 0; $j < count($rule->rules); $j++ ){ - $subRule = $rule->rules[$j]; - if( !($subRule instanceof Less_Tree_Rule) || !$subRule->variable ){ - array_splice($ruleset->rules, ++$i, 0, array($subRule)); - $rsRuleCnt++; - } - } - - } - } - } - - - // Pop the stack - $env->shiftFrame(); - - if ($mediaBlockCount) { - $len = count($env->mediaBlocks); - for($i = $mediaBlockCount; $i < $len; $i++ ){ - $env->mediaBlocks[$i]->bubbleSelectors($ruleset->selectors); - } - } - - return $ruleset; - } - - /** - * Compile Less_Tree_Mixin_Call objects - * - * @param Less_Tree_Ruleset $ruleset - * @param integer $rsRuleCnt - */ - private function EvalMixinCalls( $ruleset, $env, &$rsRuleCnt ){ - for($i=0; $i < $rsRuleCnt; $i++){ - $rule = $ruleset->rules[$i]; - - if( $rule instanceof Less_Tree_Mixin_Call ){ - $rule = $rule->compile($env); - - $temp = array(); - foreach($rule as $r){ - if( ($r instanceof Less_Tree_Rule) && $r->variable ){ - // do not pollute the scope if the variable is - // already there. consider returning false here - // but we need a way to "return" variable from mixins - if( !$ruleset->variable($r->name) ){ - $temp[] = $r; - } - }else{ - $temp[] = $r; - } - } - $temp_count = count($temp)-1; - array_splice($ruleset->rules, $i, 1, $temp); - $rsRuleCnt += $temp_count; - $i += $temp_count; - $ruleset->resetCache(); - - }elseif( $rule instanceof Less_Tree_RulesetCall ){ - - $rule = $rule->compile($env); - $rules = array(); - foreach($rule->rules as $r){ - if( ($r instanceof Less_Tree_Rule) && $r->variable ){ - continue; - } - $rules[] = $r; - } - - array_splice($ruleset->rules, $i, 1, $rules); - $temp_count = count($rules); - $rsRuleCnt += $temp_count - 1; - $i += $temp_count-1; - $ruleset->resetCache(); - } - - } - } - - - /** - * Compile the selectors and create a new ruleset object for the compile() method - * - */ - private function PrepareRuleset($env){ - - $hasOnePassingSelector = false; - $selectors = array(); - if( $this->selectors ){ - Less_Tree_DefaultFunc::error("it is currently only allowed in parametric mixin guards,"); - - foreach($this->selectors as $s){ - $selector = $s->compile($env); - $selectors[] = $selector; - if( $selector->evaldCondition ){ - $hasOnePassingSelector = true; - } - } - - Less_Tree_DefaultFunc::reset(); - } else { - $hasOnePassingSelector = true; - } - - if( $this->rules && $hasOnePassingSelector ){ - $rules = $this->rules; - }else{ - $rules = array(); - } - - $ruleset = new Less_Tree_Ruleset($selectors, $rules, $this->strictImports); - - $ruleset->originalRuleset = $this->ruleset_id; - - $ruleset->root = $this->root; - $ruleset->firstRoot = $this->firstRoot; - $ruleset->allowImports = $this->allowImports; - - - // push the current ruleset to the frames stack - $env->unshiftFrame($ruleset); - - - // Evaluate imports - if( $ruleset->root || $ruleset->allowImports || !$ruleset->strictImports ){ - $ruleset->evalImports($env); - } - - return $ruleset; - } - - function evalImports($env) { - - $rules_len = count($this->rules); - for($i=0; $i < $rules_len; $i++){ - $rule = $this->rules[$i]; - - if( $rule instanceof Less_Tree_Import ){ - $rules = $rule->compile($env); - if( is_array($rules) ){ - array_splice($this->rules, $i, 1, $rules); - $temp_count = count($rules)-1; - $i += $temp_count; - $rules_len += $temp_count; - }else{ - array_splice($this->rules, $i, 1, array($rules)); - } - - $this->resetCache(); - } - } - } - - function makeImportant(){ - - $important_rules = array(); - foreach($this->rules as $rule){ - if( $rule instanceof Less_Tree_Rule || $rule instanceof Less_Tree_Ruleset || $rule instanceof Less_Tree_NameValue ){ - $important_rules[] = $rule->makeImportant(); - }else{ - $important_rules[] = $rule; - } - } - - return new Less_Tree_Ruleset($this->selectors, $important_rules, $this->strictImports ); - } - - public function matchArgs($args){ - return !$args; - } - - // lets you call a css selector with a guard - public function matchCondition( $args, $env ){ - $lastSelector = end($this->selectors); - - if( !$lastSelector->evaldCondition ){ - return false; - } - if( $lastSelector->condition && !$lastSelector->condition->compile( $env->copyEvalEnv( $env->frames ) ) ){ - return false; - } - return true; - } - - function resetCache(){ - $this->_rulesets = null; - $this->_variables = null; - $this->lookups = array(); - } - - public function variables(){ - $this->_variables = array(); - foreach( $this->rules as $r){ - if ($r instanceof Less_Tree_Rule && $r->variable === true) { - $this->_variables[$r->name] = $r; - } - } - } - - public function variable($name){ - - if( is_null($this->_variables) ){ - $this->variables(); - } - return isset($this->_variables[$name]) ? $this->_variables[$name] : null; - } - - public function find( $selector, $self = null ){ - - $key = implode(' ',$selector->_oelements); - - if( !isset($this->lookups[$key]) ){ - - if( !$self ){ - $self = $this->ruleset_id; - } - - $this->lookups[$key] = array(); - - $first_oelement = $selector->_oelements[0]; - - foreach($this->rules as $rule){ - if( $rule instanceof Less_Tree_Ruleset && $rule->ruleset_id != $self ){ - - if( isset($rule->first_oelements[$first_oelement]) ){ - - foreach( $rule->selectors as $ruleSelector ){ - $match = $selector->match($ruleSelector); - if( $match ){ - if( $selector->elements_len > $match ){ - $this->lookups[$key] = array_merge($this->lookups[$key], $rule->find( new Less_Tree_Selector(array_slice($selector->elements, $match)), $self)); - } else { - $this->lookups[$key][] = $rule; - } - break; - } - } - } - } - } - } - - return $this->lookups[$key]; - } - - - /** - * @see Less_Tree::genCSS - */ - public function genCSS( $output ){ - - if( !$this->root ){ - Less_Environment::$tabLevel++; - } - - $tabRuleStr = $tabSetStr = ''; - if( !Less_Parser::$options['compress'] ){ - if( Less_Environment::$tabLevel ){ - $tabRuleStr = "\n".str_repeat( Less_Parser::$options['indentation'] , Less_Environment::$tabLevel ); - $tabSetStr = "\n".str_repeat( Less_Parser::$options['indentation'] , Less_Environment::$tabLevel-1 ); - }else{ - $tabSetStr = $tabRuleStr = "\n"; - } - } - - - $ruleNodes = array(); - $rulesetNodes = array(); - foreach($this->rules as $rule){ - - $class = get_class($rule); - if( ($class === 'Less_Tree_Media') || ($class === 'Less_Tree_Directive') || ($this->root && $class === 'Less_Tree_Comment') || ($class === 'Less_Tree_Ruleset' && $rule->rules) ){ - $rulesetNodes[] = $rule; - }else{ - $ruleNodes[] = $rule; - } - } - - // If this is the root node, we don't render - // a selector, or {}. - if( !$this->root ){ - - /* - debugInfo = tree.debugInfo(env, this, tabSetStr); - - if (debugInfo) { - output.add(debugInfo); - output.add(tabSetStr); - } - */ - - $paths_len = count($this->paths); - for( $i = 0; $i < $paths_len; $i++ ){ - $path = $this->paths[$i]; - $firstSelector = true; - - foreach($path as $p){ - $p->genCSS( $output, $firstSelector ); - $firstSelector = false; - } - - if( $i + 1 < $paths_len ){ - $output->add( ',' . $tabSetStr ); - } - } - - $output->add( (Less_Parser::$options['compress'] ? '{' : " {") . $tabRuleStr ); - } - - // Compile rules and rulesets - $ruleNodes_len = count($ruleNodes); - $rulesetNodes_len = count($rulesetNodes); - for( $i = 0; $i < $ruleNodes_len; $i++ ){ - $rule = $ruleNodes[$i]; - - // @page{ directive ends up with root elements inside it, a mix of rules and rulesets - // In this instance we do not know whether it is the last property - if( $i + 1 === $ruleNodes_len && (!$this->root || $rulesetNodes_len === 0 || $this->firstRoot ) ){ - Less_Environment::$lastRule = true; - } - - $rule->genCSS( $output ); - - if( !Less_Environment::$lastRule ){ - $output->add( $tabRuleStr ); - }else{ - Less_Environment::$lastRule = false; - } - } - - if( !$this->root ){ - $output->add( $tabSetStr . '}' ); - Less_Environment::$tabLevel--; - } - - $firstRuleset = true; - $space = ($this->root ? $tabRuleStr : $tabSetStr); - for( $i = 0; $i < $rulesetNodes_len; $i++ ){ - - if( $ruleNodes_len && $firstRuleset ){ - $output->add( $space ); - }elseif( !$firstRuleset ){ - $output->add( $space ); - } - $firstRuleset = false; - $rulesetNodes[$i]->genCSS( $output); - } - - if( !Less_Parser::$options['compress'] && $this->firstRoot ){ - $output->add( "\n" ); - } - - } - - - function markReferenced(){ - if( !$this->selectors ){ - return; - } - foreach($this->selectors as $selector){ - $selector->markReferenced(); - } - } - - public function joinSelectors( $context, $selectors ){ - $paths = array(); - if( is_array($selectors) ){ - foreach($selectors as $selector) { - $this->joinSelector( $paths, $context, $selector); - } - } - return $paths; - } - - public function joinSelector( &$paths, $context, $selector){ - - $hasParentSelector = false; - - foreach($selector->elements as $el) { - if( $el->value === '&') { - $hasParentSelector = true; - } - } - - if( !$hasParentSelector ){ - if( $context ){ - foreach($context as $context_el){ - $paths[] = array_merge($context_el, array($selector) ); - } - }else { - $paths[] = array($selector); - } - return; - } - - - // The paths are [[Selector]] - // The first list is a list of comma separated selectors - // The inner list is a list of inheritance separated selectors - // e.g. - // .a, .b { - // .c { - // } - // } - // == [[.a] [.c]] [[.b] [.c]] - // - - // the elements from the current selector so far - $currentElements = array(); - // the current list of new selectors to add to the path. - // We will build it up. We initiate it with one empty selector as we "multiply" the new selectors - // by the parents - $newSelectors = array(array()); - - - foreach( $selector->elements as $el){ - - // non parent reference elements just get added - if( $el->value !== '&' ){ - $currentElements[] = $el; - } else { - // the new list of selectors to add - $selectorsMultiplied = array(); - - // merge the current list of non parent selector elements - // on to the current list of selectors to add - if( $currentElements ){ - $this->mergeElementsOnToSelectors( $currentElements, $newSelectors); - } - - // loop through our current selectors - foreach($newSelectors as $sel){ - - // if we don't have any parent paths, the & might be in a mixin so that it can be used - // whether there are parents or not - if( !$context ){ - // the combinator used on el should now be applied to the next element instead so that - // it is not lost - if( $sel ){ - $sel[0]->elements = array_slice($sel[0]->elements,0); - $sel[0]->elements[] = new Less_Tree_Element($el->combinator, '', $el->index, $el->currentFileInfo ); - } - $selectorsMultiplied[] = $sel; - }else { - - // and the parent selectors - foreach($context as $parentSel){ - // We need to put the current selectors - // then join the last selector's elements on to the parents selectors - - // our new selector path - $newSelectorPath = array(); - // selectors from the parent after the join - $afterParentJoin = array(); - $newJoinedSelectorEmpty = true; - - //construct the joined selector - if & is the first thing this will be empty, - // if not newJoinedSelector will be the last set of elements in the selector - if( $sel ){ - $newSelectorPath = $sel; - $lastSelector = array_pop($newSelectorPath); - $newJoinedSelector = $selector->createDerived( array_slice($lastSelector->elements,0) ); - $newJoinedSelectorEmpty = false; - } - else { - $newJoinedSelector = $selector->createDerived(array()); - } - - //put together the parent selectors after the join - if ( count($parentSel) > 1) { - $afterParentJoin = array_merge($afterParentJoin, array_slice($parentSel,1) ); - } - - if ( $parentSel ){ - $newJoinedSelectorEmpty = false; - - // join the elements so far with the first part of the parent - $newJoinedSelector->elements[] = new Less_Tree_Element( $el->combinator, $parentSel[0]->elements[0]->value, $el->index, $el->currentFileInfo); - - $newJoinedSelector->elements = array_merge( $newJoinedSelector->elements, array_slice($parentSel[0]->elements, 1) ); - } - - if (!$newJoinedSelectorEmpty) { - // now add the joined selector - $newSelectorPath[] = $newJoinedSelector; - } - - // and the rest of the parent - $newSelectorPath = array_merge($newSelectorPath, $afterParentJoin); - - // add that to our new set of selectors - $selectorsMultiplied[] = $newSelectorPath; - } - } - } - - // our new selectors has been multiplied, so reset the state - $newSelectors = $selectorsMultiplied; - $currentElements = array(); - } - } - - // if we have any elements left over (e.g. .a& .b == .b) - // add them on to all the current selectors - if( $currentElements ){ - $this->mergeElementsOnToSelectors($currentElements, $newSelectors); - } - foreach( $newSelectors as $new_sel){ - if( $new_sel ){ - $paths[] = $new_sel; - } - } - } - - function mergeElementsOnToSelectors( $elements, &$selectors){ - - if( !$selectors ){ - $selectors[] = array( new Less_Tree_Selector($elements) ); - return; - } - - - foreach( $selectors as &$sel){ - - // if the previous thing in sel is a parent this needs to join on to it - if( $sel ){ - $last = count($sel)-1; - $sel[$last] = $sel[$last]->createDerived( array_merge($sel[$last]->elements, $elements) ); - }else{ - $sel[] = new Less_Tree_Selector( $elements ); - } - } - } -} diff --git a/vendor/oyejorge/less.php/lib/Less/Tree/RulesetCall.php b/vendor/oyejorge/less.php/lib/Less/Tree/RulesetCall.php deleted file mode 100644 index ed4c723..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Tree/RulesetCall.php +++ /dev/null @@ -1,26 +0,0 @@ -variable = $variable; - } - - public function accept($visitor) {} - - public function compile( $env ){ - $variable = new Less_Tree_Variable($this->variable); - $detachedRuleset = $variable->compile($env); - return $detachedRuleset->callEval($env); - } -} - diff --git a/vendor/oyejorge/less.php/lib/Less/Tree/Selector.php b/vendor/oyejorge/less.php/lib/Less/Tree/Selector.php deleted file mode 100644 index 6b9dae6..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Tree/Selector.php +++ /dev/null @@ -1,168 +0,0 @@ -elements = $elements; - $this->elements_len = count($elements); - $this->extendList = $extendList; - $this->condition = $condition; - if( $currentFileInfo ){ - $this->currentFileInfo = $currentFileInfo; - } - $this->isReferenced = $isReferenced; - if( !$condition ){ - $this->evaldCondition = true; - } - - $this->CacheElements(); - } - - public function accept($visitor) { - $this->elements = $visitor->visitArray($this->elements); - $this->extendList = $visitor->visitArray($this->extendList); - if( $this->condition ){ - $this->condition = $visitor->visitObj($this->condition); - } - - if( $visitor instanceof Less_Visitor_extendFinder ){ - $this->CacheElements(); - } - } - - public function createDerived( $elements, $extendList = null, $evaldCondition = null ){ - $newSelector = new Less_Tree_Selector( $elements, ($extendList ? $extendList : $this->extendList), null, $this->index, $this->currentFileInfo, $this->isReferenced); - $newSelector->evaldCondition = $evaldCondition ? $evaldCondition : $this->evaldCondition; - return $newSelector; - } - - - public function match( $other ){ - - if( !$other->_oelements || ($this->elements_len < $other->_oelements_len) ){ - return 0; - } - - for( $i = 0; $i < $other->_oelements_len; $i++ ){ - if( $this->elements[$i]->value !== $other->_oelements[$i]) { - return 0; - } - } - - return $other->_oelements_len; // return number of matched elements - } - - - public function CacheElements(){ - - $this->_oelements = array(); - $css = ''; - - foreach($this->elements as $v){ - - $css .= $v->combinator; - if( !$v->value_is_object ){ - $css .= $v->value; - continue; - } - - if( !property_exists($v->value,'value') || !is_string($v->value->value) ){ - $this->cacheable = false; - return; - } - $css .= $v->value->value; - } - - $this->_oelements_len = preg_match_all('/[,&#\.\w-](?:[\w-]|(?:\\\\.))*/', $css, $matches); - if( $this->_oelements_len ){ - $this->_oelements = $matches[0]; - - if( $this->_oelements[0] === '&' ){ - array_shift($this->_oelements); - $this->_oelements_len--; - } - } - } - - public function isJustParentSelector(){ - return !$this->mediaEmpty && - count($this->elements) === 1 && - $this->elements[0]->value === '&' && - ($this->elements[0]->combinator === ' ' || $this->elements[0]->combinator === ''); - } - - public function compile($env) { - - $elements = array(); - foreach($this->elements as $el){ - $elements[] = $el->compile($env); - } - - $extendList = array(); - foreach($this->extendList as $el){ - $extendList[] = $el->compile($el); - } - - $evaldCondition = false; - if( $this->condition ){ - $evaldCondition = $this->condition->compile($env); - } - - return $this->createDerived( $elements, $extendList, $evaldCondition ); - } - - - /** - * @see Less_Tree::genCSS - */ - public function genCSS( $output, $firstSelector = true ){ - - if( !$firstSelector && $this->elements[0]->combinator === "" ){ - $output->add(' ', $this->currentFileInfo, $this->index); - } - - foreach($this->elements as $element){ - $element->genCSS( $output ); - } - } - - public function markReferenced(){ - $this->isReferenced = true; - } - - public function getIsReferenced(){ - return !isset($this->currentFileInfo['reference']) || !$this->currentFileInfo['reference'] || $this->isReferenced; - } - - public function getIsOutput(){ - return $this->evaldCondition; - } - -} diff --git a/vendor/oyejorge/less.php/lib/Less/Tree/UnicodeDescriptor.php b/vendor/oyejorge/less.php/lib/Less/Tree/UnicodeDescriptor.php deleted file mode 100644 index 8c4707e..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Tree/UnicodeDescriptor.php +++ /dev/null @@ -1,29 +0,0 @@ -value = $value; - } - - /** - * @see Less_Tree::genCSS - */ - public function genCSS( $output ){ - $output->add( $this->value ); - } - - public function compile(){ - return $this; - } -} - diff --git a/vendor/oyejorge/less.php/lib/Less/Tree/Unit.php b/vendor/oyejorge/less.php/lib/Less/Tree/Unit.php deleted file mode 100644 index e13b100..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Tree/Unit.php +++ /dev/null @@ -1,147 +0,0 @@ -numerator = $numerator; - $this->denominator = $denominator; - $this->backupUnit = $backupUnit; - } - - public function __clone(){ - } - - /** - * @see Less_Tree::genCSS - */ - public function genCSS( $output ){ - - if( $this->numerator ){ - $output->add( $this->numerator[0] ); - }elseif( $this->denominator ){ - $output->add( $this->denominator[0] ); - }elseif( !Less_Parser::$options['strictUnits'] && $this->backupUnit ){ - $output->add( $this->backupUnit ); - return ; - } - } - - public function toString(){ - $returnStr = implode('*',$this->numerator); - foreach($this->denominator as $d){ - $returnStr .= '/'.$d; - } - return $returnStr; - } - - public function __toString(){ - return $this->toString(); - } - - - /** - * @param Less_Tree_Unit $other - */ - public function compare($other) { - return $this->is( $other->toString() ) ? 0 : -1; - } - - public function is($unitString){ - return $this->toString() === $unitString; - } - - public function isLength(){ - $css = $this->toCSS(); - return !!preg_match('/px|em|%|in|cm|mm|pc|pt|ex/',$css); - } - - public function isAngle() { - return isset( Less_Tree_UnitConversions::$angle[$this->toCSS()] ); - } - - public function isEmpty(){ - return !$this->numerator && !$this->denominator; - } - - public function isSingular() { - return count($this->numerator) <= 1 && !$this->denominator; - } - - - public function usedUnits(){ - $result = array(); - - foreach(Less_Tree_UnitConversions::$groups as $groupName){ - $group = Less_Tree_UnitConversions::${$groupName}; - - foreach($this->numerator as $atomicUnit){ - if( isset($group[$atomicUnit]) && !isset($result[$groupName]) ){ - $result[$groupName] = $atomicUnit; - } - } - - foreach($this->denominator as $atomicUnit){ - if( isset($group[$atomicUnit]) && !isset($result[$groupName]) ){ - $result[$groupName] = $atomicUnit; - } - } - } - - return $result; - } - - public function cancel(){ - $counter = array(); - $backup = null; - - foreach($this->numerator as $atomicUnit){ - if( !$backup ){ - $backup = $atomicUnit; - } - $counter[$atomicUnit] = ( isset($counter[$atomicUnit]) ? $counter[$atomicUnit] : 0) + 1; - } - - foreach($this->denominator as $atomicUnit){ - if( !$backup ){ - $backup = $atomicUnit; - } - $counter[$atomicUnit] = ( isset($counter[$atomicUnit]) ? $counter[$atomicUnit] : 0) - 1; - } - - $this->numerator = array(); - $this->denominator = array(); - - foreach($counter as $atomicUnit => $count){ - if( $count > 0 ){ - for( $i = 0; $i < $count; $i++ ){ - $this->numerator[] = $atomicUnit; - } - }elseif( $count < 0 ){ - for( $i = 0; $i < -$count; $i++ ){ - $this->denominator[] = $atomicUnit; - } - } - } - - if( !$this->numerator && !$this->denominator && $backup ){ - $this->backupUnit = $backup; - } - - sort($this->numerator); - sort($this->denominator); - } - - -} - diff --git a/vendor/oyejorge/less.php/lib/Less/Tree/UnitConversions.php b/vendor/oyejorge/less.php/lib/Less/Tree/UnitConversions.php deleted file mode 100644 index c86b290..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Tree/UnitConversions.php +++ /dev/null @@ -1,35 +0,0 @@ - 1, - 'cm'=> 0.01, - 'mm'=> 0.001, - 'in'=> 0.0254, - 'px'=> 0.000264583, // 0.0254 / 96, - 'pt'=> 0.000352778, // 0.0254 / 72, - 'pc'=> 0.004233333, // 0.0254 / 72 * 12 - ); - - public static $duration = array( - 's'=> 1, - 'ms'=> 0.001 - ); - - public static $angle = array( - 'rad' => 0.1591549430919, // 1/(2*M_PI), - 'deg' => 0.002777778, // 1/360, - 'grad'=> 0.0025, // 1/400, - 'turn'=> 1 - ); - -} \ No newline at end of file diff --git a/vendor/oyejorge/less.php/lib/Less/Tree/Url.php b/vendor/oyejorge/less.php/lib/Less/Tree/Url.php deleted file mode 100644 index ef9c3c6..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Tree/Url.php +++ /dev/null @@ -1,76 +0,0 @@ -value = $value; - $this->currentFileInfo = $currentFileInfo; - $this->isEvald = $isEvald; - } - - public function accept( $visitor ){ - $this->value = $visitor->visitObj($this->value); - } - - /** - * @see Less_Tree::genCSS - */ - public function genCSS( $output ){ - $output->add( 'url(' ); - $this->value->genCSS( $output ); - $output->add( ')' ); - } - - /** - * @param Less_Functions $ctx - */ - public function compile($ctx){ - $val = $this->value->compile($ctx); - - if( !$this->isEvald ){ - // Add the base path if the URL is relative - if( Less_Parser::$options['relativeUrls'] - && $this->currentFileInfo - && is_string($val->value) - && Less_Environment::isPathRelative($val->value) - ){ - $rootpath = $this->currentFileInfo['uri_root']; - if ( !$val->quote ){ - $rootpath = preg_replace('/[\(\)\'"\s]/', '\\$1', $rootpath ); - } - $val->value = $rootpath . $val->value; - } - - $val->value = Less_Environment::normalizePath( $val->value); - } - - // Add cache buster if enabled - if( Less_Parser::$options['urlArgs'] ){ - if( !preg_match('/^\s*data:/',$val->value) ){ - $delimiter = strpos($val->value,'?') === false ? '?' : '&'; - $urlArgs = $delimiter . Less_Parser::$options['urlArgs']; - $hash_pos = strpos($val->value,'#'); - if( $hash_pos !== false ){ - $val->value = substr_replace($val->value,$urlArgs, $hash_pos, 0); - } else { - $val->value .= $urlArgs; - } - } - } - - return new Less_Tree_URL($val, $this->currentFileInfo, true); - } - -} diff --git a/vendor/oyejorge/less.php/lib/Less/Tree/Value.php b/vendor/oyejorge/less.php/lib/Less/Tree/Value.php deleted file mode 100644 index 9f077bc..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Tree/Value.php +++ /dev/null @@ -1,48 +0,0 @@ -value = $value; - } - - public function accept($visitor) { - $this->value = $visitor->visitArray($this->value); - } - - public function compile($env){ - - $ret = array(); - $i = 0; - foreach($this->value as $i => $v){ - $ret[] = $v->compile($env); - } - if( $i > 0 ){ - return new Less_Tree_Value($ret); - } - return $ret[0]; - } - - /** - * @see Less_Tree::genCSS - */ - function genCSS( $output ){ - $len = count($this->value); - for($i = 0; $i < $len; $i++ ){ - $this->value[$i]->genCSS( $output ); - if( $i+1 < $len ){ - $output->add( Less_Environment::$_outputMap[','] ); - } - } - } - -} diff --git a/vendor/oyejorge/less.php/lib/Less/Tree/Variable.php b/vendor/oyejorge/less.php/lib/Less/Tree/Variable.php deleted file mode 100644 index cc0182c..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Tree/Variable.php +++ /dev/null @@ -1,52 +0,0 @@ -name = $name; - $this->index = $index; - $this->currentFileInfo = $currentFileInfo; - } - - public function compile($env) { - - if( $this->name[1] === '@' ){ - $v = new Less_Tree_Variable(substr($this->name, 1), $this->index + 1, $this->currentFileInfo); - $name = '@' . $v->compile($env)->value; - }else{ - $name = $this->name; - } - - if ($this->evaluating) { - throw new Less_Exception_Compiler("Recursive variable definition for " . $name, null, $this->index, $this->currentFileInfo); - } - - $this->evaluating = true; - - foreach($env->frames as $frame){ - if( $v = $frame->variable($name) ){ - $r = $v->value->compile($env); - $this->evaluating = false; - return $r; - } - } - - throw new Less_Exception_Compiler("variable " . $name . " is undefined in file ".$this->currentFileInfo["filename"], null, $this->index, $this->currentFileInfo); - } - -} diff --git a/vendor/oyejorge/less.php/lib/Less/Version.php b/vendor/oyejorge/less.php/lib/Less/Version.php deleted file mode 100644 index dceefe5..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Version.php +++ /dev/null @@ -1,15 +0,0 @@ -_visitFnCache = get_class_methods(get_class($this)); - $this->_visitFnCache = array_flip($this->_visitFnCache); - } - - public function visitObj( $node ){ - - $funcName = 'visit'.$node->type; - if( isset($this->_visitFnCache[$funcName]) ){ - - $visitDeeper = true; - $this->$funcName( $node, $visitDeeper ); - - if( $visitDeeper ){ - $node->accept($this); - } - - $funcName = $funcName . "Out"; - if( isset($this->_visitFnCache[$funcName]) ){ - $this->$funcName( $node ); - } - - }else{ - $node->accept($this); - } - - return $node; - } - - public function visitArray( $nodes ){ - - array_map( array($this,'visitObj'), $nodes); - return $nodes; - } -} - diff --git a/vendor/oyejorge/less.php/lib/Less/Visitor/extendFinder.php b/vendor/oyejorge/less.php/lib/Less/Visitor/extendFinder.php deleted file mode 100644 index 22b3aac..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Visitor/extendFinder.php +++ /dev/null @@ -1,114 +0,0 @@ -contexts = array(); - $this->allExtendsStack = array(array()); - parent::__construct(); - } - - /** - * @param Less_Tree_Ruleset $root - */ - public function run($root){ - $root = $this->visitObj($root); - $root->allExtends =& $this->allExtendsStack[0]; - return $root; - } - - public function visitRule($ruleNode, &$visitDeeper ){ - $visitDeeper = false; - } - - public function visitMixinDefinition( $mixinDefinitionNode, &$visitDeeper ){ - $visitDeeper = false; - } - - public function visitRuleset($rulesetNode){ - - if( $rulesetNode->root ){ - return; - } - - $allSelectorsExtendList = array(); - - // get &:extend(.a); rules which apply to all selectors in this ruleset - if( $rulesetNode->rules ){ - foreach($rulesetNode->rules as $rule){ - if( $rule instanceof Less_Tree_Extend ){ - $allSelectorsExtendList[] = $rule; - $rulesetNode->extendOnEveryPath = true; - } - } - } - - - // now find every selector and apply the extends that apply to all extends - // and the ones which apply to an individual extend - foreach($rulesetNode->paths as $selectorPath){ - $selector = end($selectorPath); //$selectorPath[ count($selectorPath)-1]; - - $j = 0; - foreach($selector->extendList as $extend){ - $this->allExtendsStackPush($rulesetNode, $selectorPath, $extend, $j); - } - foreach($allSelectorsExtendList as $extend){ - $this->allExtendsStackPush($rulesetNode, $selectorPath, $extend, $j); - } - } - - $this->contexts[] = $rulesetNode->selectors; - } - - public function allExtendsStackPush($rulesetNode, $selectorPath, $extend, &$j){ - $this->foundExtends = true; - $extend = clone $extend; - $extend->findSelfSelectors( $selectorPath ); - $extend->ruleset = $rulesetNode; - if( $j === 0 ){ - $extend->firstExtendOnThisSelectorPath = true; - } - - $end_key = count($this->allExtendsStack)-1; - $this->allExtendsStack[$end_key][] = $extend; - $j++; - } - - - public function visitRulesetOut( $rulesetNode ){ - if( !is_object($rulesetNode) || !$rulesetNode->root ){ - array_pop($this->contexts); - } - } - - public function visitMedia( $mediaNode ){ - $mediaNode->allExtends = array(); - $this->allExtendsStack[] =& $mediaNode->allExtends; - } - - public function visitMediaOut(){ - array_pop($this->allExtendsStack); - } - - public function visitDirective( $directiveNode ){ - $directiveNode->allExtends = array(); - $this->allExtendsStack[] =& $directiveNode->allExtends; - } - - public function visitDirectiveOut(){ - array_pop($this->allExtendsStack); - } -} - - diff --git a/vendor/oyejorge/less.php/lib/Less/Visitor/import.php b/vendor/oyejorge/less.php/lib/Less/Visitor/import.php deleted file mode 100644 index f79a36d..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Visitor/import.php +++ /dev/null @@ -1,139 +0,0 @@ -env = $evalEnv; - $this->importCount = 0; - parent::__construct(); - } - - - function run( $root ){ - $root = $this->visitObj($root); - $this->isFinished = true; - - //if( $this->importCount === 0) { - // $this->_finish(); - //} - } - - function visitImport($importNode, &$visitDeeper ){ - $importVisitor = $this; - $inlineCSS = $importNode->options['inline']; - - if( !$importNode->css || $inlineCSS ){ - $evaldImportNode = $importNode->compileForImport($this->env); - - if( $evaldImportNode && (!$evaldImportNode->css || $inlineCSS) ){ - $importNode = $evaldImportNode; - $this->importCount++; - $env = clone $this->env; - - if( (isset($importNode->options['multiple']) && $importNode->options['multiple']) ){ - $env->importMultiple = true; - } - - //get path & uri - $path_and_uri = null; - if( is_callable(Less_Parser::$options['import_callback']) ){ - $path_and_uri = call_user_func(Less_Parser::$options['import_callback'],$importNode); - } - - if( !$path_and_uri ){ - $path_and_uri = $importNode->PathAndUri(); - } - - if( $path_and_uri ){ - list($full_path, $uri) = $path_and_uri; - }else{ - $full_path = $uri = $importNode->getPath(); - } - - - //import once - if( $importNode->skip( $full_path, $env) ){ - return array(); - } - - if( $importNode->options['inline'] ){ - //todo needs to reference css file not import - //$contents = new Less_Tree_Anonymous($importNode->root, 0, array('filename'=>$importNode->importedFilename), true ); - - Less_Parser::AddParsedFile($full_path); - $contents = new Less_Tree_Anonymous( file_get_contents($full_path), 0, array(), true ); - - if( $importNode->features ){ - return new Less_Tree_Media( array($contents), $importNode->features->value ); - } - - return array( $contents ); - } - - - // css ? - if( $importNode->css ){ - $features = ( $importNode->features ? $importNode->features->compile($env) : null ); - return new Less_Tree_Import( $importNode->compilePath( $env), $features, $importNode->options, $this->index); - } - - return $importNode->ParseImport( $full_path, $uri, $env ); - } - - } - - $visitDeeper = false; - return $importNode; - } - - - function visitRule( $ruleNode, &$visitDeeper ){ - $visitDeeper = false; - return $ruleNode; - } - - function visitDirective($directiveNode, $visitArgs){ - array_unshift($this->env->frames,$directiveNode); - return $directiveNode; - } - - function visitDirectiveOut($directiveNode) { - array_shift($this->env->frames); - } - - function visitMixinDefinition($mixinDefinitionNode, $visitArgs) { - array_unshift($this->env->frames,$mixinDefinitionNode); - return $mixinDefinitionNode; - } - - function visitMixinDefinitionOut($mixinDefinitionNode) { - array_shift($this->env->frames); - } - - function visitRuleset($rulesetNode, $visitArgs) { - array_unshift($this->env->frames,$rulesetNode); - return $rulesetNode; - } - - function visitRulesetOut($rulesetNode) { - array_shift($this->env->frames); - } - - function visitMedia($mediaNode, $visitArgs) { - array_unshift($this->env->frames, $mediaNode->ruleset); - return $mediaNode; - } - - function visitMediaOut($mediaNode) { - array_shift($this->env->frames); - } - -} -*/ - - diff --git a/vendor/oyejorge/less.php/lib/Less/Visitor/joinSelector.php b/vendor/oyejorge/less.php/lib/Less/Visitor/joinSelector.php deleted file mode 100644 index f62af1a..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Visitor/joinSelector.php +++ /dev/null @@ -1,70 +0,0 @@ -visitObj($root); - } - - public function visitRule( $ruleNode, &$visitDeeper ){ - $visitDeeper = false; - } - - public function visitMixinDefinition( $mixinDefinitionNode, &$visitDeeper ){ - $visitDeeper = false; - } - - public function visitRuleset( $rulesetNode ){ - - $paths = array(); - - if( !$rulesetNode->root ){ - $selectors = array(); - - if( $rulesetNode->selectors && $rulesetNode->selectors ){ - foreach($rulesetNode->selectors as $selector){ - if( $selector->getIsOutput() ){ - $selectors[] = $selector; - } - } - } - - if( !$selectors ){ - $rulesetNode->selectors = null; - $rulesetNode->rules = null; - }else{ - $context = end($this->contexts); //$context = $this->contexts[ count($this->contexts) - 1]; - $paths = $rulesetNode->joinSelectors( $context, $selectors); - } - - $rulesetNode->paths = $paths; - } - - $this->contexts[] = $paths; //different from less.js. Placed after joinSelectors() so that $this->contexts will get correct $paths - } - - public function visitRulesetOut(){ - array_pop($this->contexts); - } - - public function visitMedia($mediaNode) { - $context = end($this->contexts); //$context = $this->contexts[ count($this->contexts) - 1]; - - if( !count($context) || (is_object($context[0]) && $context[0]->multiMedia) ){ - $mediaNode->rules[0]->root = true; - } - } - -} - diff --git a/vendor/oyejorge/less.php/lib/Less/Visitor/processExtends.php b/vendor/oyejorge/less.php/lib/Less/Visitor/processExtends.php deleted file mode 100644 index bb5f082..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Visitor/processExtends.php +++ /dev/null @@ -1,469 +0,0 @@ -run( $root ); - if( !$extendFinder->foundExtends){ - return $root; - } - - $root->allExtends = $this->doExtendChaining( $root->allExtends, $root->allExtends); - - $this->allExtendsStack = array(); - $this->allExtendsStack[] = &$root->allExtends; - - return $this->visitObj( $root ); - } - - private function doExtendChaining( $extendsList, $extendsListTarget, $iterationCount = 0){ - // - // chaining is different from normal extension.. if we extend an extend then we are not just copying, altering and pasting - // the selector we would do normally, but we are also adding an extend with the same target selector - // this means this new extend can then go and alter other extends - // - // this method deals with all the chaining work - without it, extend is flat and doesn't work on other extend selectors - // this is also the most expensive.. and a match on one selector can cause an extension of a selector we had already processed if - // we look at each selector at a time, as is done in visitRuleset - - $extendsToAdd = array(); - - - //loop through comparing every extend with every target extend. - // a target extend is the one on the ruleset we are looking at copy/edit/pasting in place - // e.g. .a:extend(.b) {} and .b:extend(.c) {} then the first extend extends the second one - // and the second is the target. - // the separation into two lists allows us to process a subset of chains with a bigger set, as is the - // case when processing media queries - for( $extendIndex = 0, $extendsList_len = count($extendsList); $extendIndex < $extendsList_len; $extendIndex++ ){ - for( $targetExtendIndex = 0; $targetExtendIndex < count($extendsListTarget); $targetExtendIndex++ ){ - - $extend = $extendsList[$extendIndex]; - $targetExtend = $extendsListTarget[$targetExtendIndex]; - - // look for circular references - if( in_array($targetExtend->object_id, $extend->parent_ids,true) ){ - continue; - } - - // find a match in the target extends self selector (the bit before :extend) - $selectorPath = array( $targetExtend->selfSelectors[0] ); - $matches = $this->findMatch( $extend, $selectorPath); - - - if( $matches ){ - - // we found a match, so for each self selector.. - foreach($extend->selfSelectors as $selfSelector ){ - - - // process the extend as usual - $newSelector = $this->extendSelector( $matches, $selectorPath, $selfSelector); - - // but now we create a new extend from it - $newExtend = new Less_Tree_Extend( $targetExtend->selector, $targetExtend->option, 0); - $newExtend->selfSelectors = $newSelector; - - // add the extend onto the list of extends for that selector - end($newSelector)->extendList = array($newExtend); - //$newSelector[ count($newSelector)-1]->extendList = array($newExtend); - - // record that we need to add it. - $extendsToAdd[] = $newExtend; - $newExtend->ruleset = $targetExtend->ruleset; - - //remember its parents for circular references - $newExtend->parent_ids = array_merge($newExtend->parent_ids,$targetExtend->parent_ids,$extend->parent_ids); - - // only process the selector once.. if we have :extend(.a,.b) then multiple - // extends will look at the same selector path, so when extending - // we know that any others will be duplicates in terms of what is added to the css - if( $targetExtend->firstExtendOnThisSelectorPath ){ - $newExtend->firstExtendOnThisSelectorPath = true; - $targetExtend->ruleset->paths[] = $newSelector; - } - } - } - } - } - - if( $extendsToAdd ){ - // try to detect circular references to stop a stack overflow. - // may no longer be needed. $this->extendChainCount++; - if( $iterationCount > 100) { - - try{ - $selectorOne = $extendsToAdd[0]->selfSelectors[0]->toCSS(); - $selectorTwo = $extendsToAdd[0]->selector->toCSS(); - }catch(Exception $e){ - $selectorOne = "{unable to calculate}"; - $selectorTwo = "{unable to calculate}"; - } - - throw new Less_Exception_Parser("extend circular reference detected. One of the circular extends is currently:" . $selectorOne . ":extend(" . $selectorTwo . ")"); - } - - // now process the new extends on the existing rules so that we can handle a extending b extending c ectending d extending e... - $extendsToAdd = $this->doExtendChaining( $extendsToAdd, $extendsListTarget, $iterationCount+1); - } - - return array_merge($extendsList, $extendsToAdd); - } - - - protected function visitRule( $ruleNode, &$visitDeeper ){ - $visitDeeper = false; - } - - protected function visitMixinDefinition( $mixinDefinitionNode, &$visitDeeper ){ - $visitDeeper = false; - } - - protected function visitSelector( $selectorNode, &$visitDeeper ){ - $visitDeeper = false; - } - - protected function visitRuleset($rulesetNode){ - - - if( $rulesetNode->root ){ - return; - } - - $allExtends = end($this->allExtendsStack); - $paths_len = count($rulesetNode->paths); - - // look at each selector path in the ruleset, find any extend matches and then copy, find and replace - foreach($allExtends as $allExtend){ - for($pathIndex = 0; $pathIndex < $paths_len; $pathIndex++ ){ - - // extending extends happens initially, before the main pass - if( isset($rulesetNode->extendOnEveryPath) && $rulesetNode->extendOnEveryPath ){ - continue; - } - - $selectorPath = $rulesetNode->paths[$pathIndex]; - - if( end($selectorPath)->extendList ){ - continue; - } - - $this->ExtendMatch( $rulesetNode, $allExtend, $selectorPath); - - } - } - } - - - private function ExtendMatch( $rulesetNode, $extend, $selectorPath ){ - $matches = $this->findMatch($extend, $selectorPath); - - if( $matches ){ - foreach($extend->selfSelectors as $selfSelector ){ - $rulesetNode->paths[] = $this->extendSelector($matches, $selectorPath, $selfSelector); - } - } - } - - - - private function findMatch($extend, $haystackSelectorPath ){ - - - if( !$this->HasMatches($extend, $haystackSelectorPath) ){ - return false; - } - - - // - // look through the haystack selector path to try and find the needle - extend.selector - // returns an array of selector matches that can then be replaced - // - $needleElements = $extend->selector->elements; - $potentialMatches = array(); - $potentialMatches_len = 0; - $potentialMatch = null; - $matches = array(); - - - - // loop through the haystack elements - $haystack_path_len = count($haystackSelectorPath); - for($haystackSelectorIndex = 0; $haystackSelectorIndex < $haystack_path_len; $haystackSelectorIndex++ ){ - $hackstackSelector = $haystackSelectorPath[$haystackSelectorIndex]; - - $haystack_elements_len = count($hackstackSelector->elements); - for($hackstackElementIndex = 0; $hackstackElementIndex < $haystack_elements_len; $hackstackElementIndex++ ){ - - $haystackElement = $hackstackSelector->elements[$hackstackElementIndex]; - - // if we allow elements before our match we can add a potential match every time. otherwise only at the first element. - if( $extend->allowBefore || ($haystackSelectorIndex === 0 && $hackstackElementIndex === 0) ){ - $potentialMatches[] = array('pathIndex'=> $haystackSelectorIndex, 'index'=> $hackstackElementIndex, 'matched'=> 0, 'initialCombinator'=> $haystackElement->combinator); - $potentialMatches_len++; - } - - for($i = 0; $i < $potentialMatches_len; $i++ ){ - - $potentialMatch = &$potentialMatches[$i]; - $potentialMatch = $this->PotentialMatch( $potentialMatch, $needleElements, $haystackElement, $hackstackElementIndex ); - - - // if we are still valid and have finished, test whether we have elements after and whether these are allowed - if( $potentialMatch && $potentialMatch['matched'] === $extend->selector->elements_len ){ - $potentialMatch['finished'] = true; - - if( !$extend->allowAfter && ($hackstackElementIndex+1 < $haystack_elements_len || $haystackSelectorIndex+1 < $haystack_path_len) ){ - $potentialMatch = null; - } - } - - // if null we remove, if not, we are still valid, so either push as a valid match or continue - if( $potentialMatch ){ - if( $potentialMatch['finished'] ){ - $potentialMatch['length'] = $extend->selector->elements_len; - $potentialMatch['endPathIndex'] = $haystackSelectorIndex; - $potentialMatch['endPathElementIndex'] = $hackstackElementIndex + 1; // index after end of match - $potentialMatches = array(); // we don't allow matches to overlap, so start matching again - $potentialMatches_len = 0; - $matches[] = $potentialMatch; - } - continue; - } - - array_splice($potentialMatches, $i, 1); - $potentialMatches_len--; - $i--; - } - } - } - - return $matches; - } - - - // Before going through all the nested loops, lets check to see if a match is possible - // Reduces Bootstrap 3.1 compile time from ~6.5s to ~5.6s - private function HasMatches($extend, $haystackSelectorPath){ - - if( !$extend->selector->cacheable ){ - return true; - } - - $first_el = $extend->selector->_oelements[0]; - - foreach($haystackSelectorPath as $hackstackSelector){ - if( !$hackstackSelector->cacheable ){ - return true; - } - - if( in_array($first_el, $hackstackSelector->_oelements) ){ - return true; - } - } - - return false; - } - - - /** - * @param integer $hackstackElementIndex - */ - private function PotentialMatch( $potentialMatch, $needleElements, $haystackElement, $hackstackElementIndex ){ - - - if( $potentialMatch['matched'] > 0 ){ - - // selectors add " " onto the first element. When we use & it joins the selectors together, but if we don't - // then each selector in haystackSelectorPath has a space before it added in the toCSS phase. so we need to work out - // what the resulting combinator will be - $targetCombinator = $haystackElement->combinator; - if( $targetCombinator === '' && $hackstackElementIndex === 0 ){ - $targetCombinator = ' '; - } - - if( $needleElements[ $potentialMatch['matched'] ]->combinator !== $targetCombinator ){ - return null; - } - } - - // if we don't match, null our match to indicate failure - if( !$this->isElementValuesEqual( $needleElements[$potentialMatch['matched'] ]->value, $haystackElement->value) ){ - return null; - } - - $potentialMatch['finished'] = false; - $potentialMatch['matched']++; - - return $potentialMatch; - } - - - private function isElementValuesEqual( $elementValue1, $elementValue2 ){ - - if( $elementValue1 === $elementValue2 ){ - return true; - } - - if( is_string($elementValue1) || is_string($elementValue2) ) { - return false; - } - - if( $elementValue1 instanceof Less_Tree_Attribute ){ - return $this->isAttributeValuesEqual( $elementValue1, $elementValue2 ); - } - - $elementValue1 = $elementValue1->value; - if( $elementValue1 instanceof Less_Tree_Selector ){ - return $this->isSelectorValuesEqual( $elementValue1, $elementValue2 ); - } - - return false; - } - - - /** - * @param Less_Tree_Selector $elementValue1 - */ - private function isSelectorValuesEqual( $elementValue1, $elementValue2 ){ - - $elementValue2 = $elementValue2->value; - if( !($elementValue2 instanceof Less_Tree_Selector) || $elementValue1->elements_len !== $elementValue2->elements_len ){ - return false; - } - - for( $i = 0; $i < $elementValue1->elements_len; $i++ ){ - - if( $elementValue1->elements[$i]->combinator !== $elementValue2->elements[$i]->combinator ){ - if( $i !== 0 || ($elementValue1->elements[$i]->combinator || ' ') !== ($elementValue2->elements[$i]->combinator || ' ') ){ - return false; - } - } - - if( !$this->isElementValuesEqual($elementValue1->elements[$i]->value, $elementValue2->elements[$i]->value) ){ - return false; - } - } - - return true; - } - - - /** - * @param Less_Tree_Attribute $elementValue1 - */ - private function isAttributeValuesEqual( $elementValue1, $elementValue2 ){ - - if( $elementValue1->op !== $elementValue2->op || $elementValue1->key !== $elementValue2->key ){ - return false; - } - - if( !$elementValue1->value || !$elementValue2->value ){ - if( $elementValue1->value || $elementValue2->value ) { - return false; - } - return true; - } - - $elementValue1 = ($elementValue1->value->value ? $elementValue1->value->value : $elementValue1->value ); - $elementValue2 = ($elementValue2->value->value ? $elementValue2->value->value : $elementValue2->value ); - - return $elementValue1 === $elementValue2; - } - - - private function extendSelector($matches, $selectorPath, $replacementSelector){ - - //for a set of matches, replace each match with the replacement selector - - $currentSelectorPathIndex = 0; - $currentSelectorPathElementIndex = 0; - $path = array(); - $selectorPath_len = count($selectorPath); - - for($matchIndex = 0, $matches_len = count($matches); $matchIndex < $matches_len; $matchIndex++ ){ - - - $match = $matches[$matchIndex]; - $selector = $selectorPath[ $match['pathIndex'] ]; - - $firstElement = new Less_Tree_Element( - $match['initialCombinator'], - $replacementSelector->elements[0]->value, - $replacementSelector->elements[0]->index, - $replacementSelector->elements[0]->currentFileInfo - ); - - if( $match['pathIndex'] > $currentSelectorPathIndex && $currentSelectorPathElementIndex > 0 ){ - $last_path = end($path); - $last_path->elements = array_merge( $last_path->elements, array_slice( $selectorPath[$currentSelectorPathIndex]->elements, $currentSelectorPathElementIndex)); - $currentSelectorPathElementIndex = 0; - $currentSelectorPathIndex++; - } - - $newElements = array_merge( - array_slice($selector->elements, $currentSelectorPathElementIndex, ($match['index'] - $currentSelectorPathElementIndex) ) // last parameter of array_slice is different than the last parameter of javascript's slice - , array($firstElement) - , array_slice($replacementSelector->elements,1) - ); - - if( $currentSelectorPathIndex === $match['pathIndex'] && $matchIndex > 0 ){ - $last_key = count($path)-1; - $path[$last_key]->elements = array_merge($path[$last_key]->elements,$newElements); - }else{ - $path = array_merge( $path, array_slice( $selectorPath, $currentSelectorPathIndex, $match['pathIndex'] )); - $path[] = new Less_Tree_Selector( $newElements ); - } - - $currentSelectorPathIndex = $match['endPathIndex']; - $currentSelectorPathElementIndex = $match['endPathElementIndex']; - if( $currentSelectorPathElementIndex >= count($selectorPath[$currentSelectorPathIndex]->elements) ){ - $currentSelectorPathElementIndex = 0; - $currentSelectorPathIndex++; - } - } - - if( $currentSelectorPathIndex < $selectorPath_len && $currentSelectorPathElementIndex > 0 ){ - $last_path = end($path); - $last_path->elements = array_merge( $last_path->elements, array_slice($selectorPath[$currentSelectorPathIndex]->elements, $currentSelectorPathElementIndex)); - $currentSelectorPathIndex++; - } - - $slice_len = $selectorPath_len - $currentSelectorPathIndex; - $path = array_merge($path, array_slice($selectorPath, $currentSelectorPathIndex, $slice_len)); - - return $path; - } - - - protected function visitMedia( $mediaNode ){ - $newAllExtends = array_merge( $mediaNode->allExtends, end($this->allExtendsStack) ); - $this->allExtendsStack[] = $this->doExtendChaining($newAllExtends, $mediaNode->allExtends); - } - - protected function visitMediaOut(){ - array_pop( $this->allExtendsStack ); - } - - protected function visitDirective( $directiveNode ){ - $newAllExtends = array_merge( $directiveNode->allExtends, end($this->allExtendsStack) ); - $this->allExtendsStack[] = $this->doExtendChaining($newAllExtends, $directiveNode->allExtends); - } - - protected function visitDirectiveOut(){ - array_pop($this->allExtendsStack); - } - -} \ No newline at end of file diff --git a/vendor/oyejorge/less.php/lib/Less/Visitor/toCSS.php b/vendor/oyejorge/less.php/lib/Less/Visitor/toCSS.php deleted file mode 100644 index 8aaca96..0000000 --- a/vendor/oyejorge/less.php/lib/Less/Visitor/toCSS.php +++ /dev/null @@ -1,292 +0,0 @@ -visitObj($root); - } - - public function visitRule( $ruleNode ){ - if( $ruleNode->variable ){ - return array(); - } - return $ruleNode; - } - - public function visitMixinDefinition($mixinNode){ - // mixin definitions do not get eval'd - this means they keep state - // so we have to clear that state here so it isn't used if toCSS is called twice - $mixinNode->frames = array(); - return array(); - } - - public function visitExtend(){ - return array(); - } - - public function visitComment( $commentNode ){ - if( $commentNode->isSilent() ){ - return array(); - } - return $commentNode; - } - - public function visitMedia( $mediaNode, &$visitDeeper ){ - $mediaNode->accept($this); - $visitDeeper = false; - - if( !$mediaNode->rules ){ - return array(); - } - return $mediaNode; - } - - public function visitDirective( $directiveNode ){ - if( isset($directiveNode->currentFileInfo['reference']) && (!property_exists($directiveNode,'isReferenced') || !$directiveNode->isReferenced) ){ - return array(); - } - if( $directiveNode->name === '@charset' ){ - // Only output the debug info together with subsequent @charset definitions - // a comment (or @media statement) before the actual @charset directive would - // be considered illegal css as it has to be on the first line - if( isset($this->charset) && $this->charset ){ - - //if( $directiveNode->debugInfo ){ - // $comment = new Less_Tree_Comment('/* ' . str_replace("\n",'',$directiveNode->toCSS())." */\n"); - // $comment->debugInfo = $directiveNode->debugInfo; - // return $this->visit($comment); - //} - - - return array(); - } - $this->charset = true; - } - return $directiveNode; - } - - public function checkPropertiesInRoot( $rulesetNode ){ - - if( !$rulesetNode->firstRoot ){ - return; - } - - foreach($rulesetNode->rules as $ruleNode){ - if( $ruleNode instanceof Less_Tree_Rule && !$ruleNode->variable ){ - $msg = "properties must be inside selector blocks, they cannot be in the root. Index ".$ruleNode->index.($ruleNode->currentFileInfo ? (' Filename: '.$ruleNode->currentFileInfo['filename']) : null); - throw new Less_Exception_Compiler($msg); - } - } - } - - - public function visitRuleset( $rulesetNode, &$visitDeeper ){ - - $visitDeeper = false; - - $this->checkPropertiesInRoot( $rulesetNode ); - - if( $rulesetNode->root ){ - return $this->visitRulesetRoot( $rulesetNode ); - } - - $rulesets = array(); - $rulesetNode->paths = $this->visitRulesetPaths($rulesetNode); - - - // Compile rules and rulesets - $nodeRuleCnt = $rulesetNode->rules?count($rulesetNode->rules):0; - for( $i = 0; $i < $nodeRuleCnt; ){ - $rule = $rulesetNode->rules[$i]; - - if( property_exists($rule,'rules') ){ - // visit because we are moving them out from being a child - $rulesets[] = $this->visitObj($rule); - array_splice($rulesetNode->rules,$i,1); - $nodeRuleCnt--; - continue; - } - $i++; - } - - - // accept the visitor to remove rules and refactor itself - // then we can decide now whether we want it or not - if( $nodeRuleCnt > 0 ){ - $rulesetNode->accept($this); - - if( $rulesetNode->rules ){ - - if( count($rulesetNode->rules) > 1 ){ - $this->_mergeRules( $rulesetNode->rules ); - $this->_removeDuplicateRules( $rulesetNode->rules ); - } - - // now decide whether we keep the ruleset - if( $rulesetNode->paths ){ - //array_unshift($rulesets, $rulesetNode); - array_splice($rulesets,0,0,array($rulesetNode)); - } - } - - } - - - if( count($rulesets) === 1 ){ - return $rulesets[0]; - } - return $rulesets; - } - - - /** - * Helper function for visitiRuleset - * - * return array|Less_Tree_Ruleset - */ - private function visitRulesetRoot( $rulesetNode ){ - $rulesetNode->accept( $this ); - if( $rulesetNode->firstRoot || $rulesetNode->rules ){ - return $rulesetNode; - } - return array(); - } - - - /** - * Helper function for visitRuleset() - * - * @return array - */ - private function visitRulesetPaths($rulesetNode){ - - $paths = array(); - foreach($rulesetNode->paths as $p){ - if( $p[0]->elements[0]->combinator === ' ' ){ - $p[0]->elements[0]->combinator = ''; - } - - foreach($p as $pi){ - if( $pi->getIsReferenced() && $pi->getIsOutput() ){ - $paths[] = $p; - break; - } - } - } - - return $paths; - } - - protected function _removeDuplicateRules( &$rules ){ - // remove duplicates - $ruleCache = array(); - for( $i = count($rules)-1; $i >= 0 ; $i-- ){ - $rule = $rules[$i]; - if( $rule instanceof Less_Tree_Rule || $rule instanceof Less_Tree_NameValue ){ - - if( !isset($ruleCache[$rule->name]) ){ - $ruleCache[$rule->name] = $rule; - }else{ - $ruleList =& $ruleCache[$rule->name]; - - if( $ruleList instanceof Less_Tree_Rule || $ruleList instanceof Less_Tree_NameValue ){ - $ruleList = $ruleCache[$rule->name] = array( $ruleCache[$rule->name]->toCSS() ); - } - - $ruleCSS = $rule->toCSS(); - if( array_search($ruleCSS,$ruleList) !== false ){ - array_splice($rules,$i,1); - }else{ - $ruleList[] = $ruleCSS; - } - } - } - } - } - - protected function _mergeRules( &$rules ){ - $groups = array(); - - //obj($rules); - - $rules_len = count($rules); - for( $i = 0; $i < $rules_len; $i++ ){ - $rule = $rules[$i]; - - if( ($rule instanceof Less_Tree_Rule) && $rule->merge ){ - - $key = $rule->name; - if( $rule->important ){ - $key .= ',!'; - } - - if( !isset($groups[$key]) ){ - $groups[$key] = array(); - }else{ - array_splice($rules, $i--, 1); - $rules_len--; - } - - $groups[$key][] = $rule; - } - } - - - foreach($groups as $parts){ - - if( count($parts) > 1 ){ - $rule = $parts[0]; - $spacedGroups = array(); - $lastSpacedGroup = array(); - $parts_mapped = array(); - foreach($parts as $p){ - if( $p->merge === '+' ){ - if( $lastSpacedGroup ){ - $spacedGroups[] = self::toExpression($lastSpacedGroup); - } - $lastSpacedGroup = array(); - } - $lastSpacedGroup[] = $p; - } - - $spacedGroups[] = self::toExpression($lastSpacedGroup); - $rule->value = self::toValue($spacedGroups); - } - } - - } - - public static function toExpression($values){ - $mapped = array(); - foreach($values as $p){ - $mapped[] = $p->value; - } - return new Less_Tree_Expression( $mapped ); - } - - public static function toValue($values){ - //return new Less_Tree_Value($values); ?? - - $mapped = array(); - foreach($values as $p){ - $mapped[] = $p; - } - return new Less_Tree_Value($mapped); - } -} - diff --git a/vendor/oyejorge/less.php/lib/Less/VisitorReplacing.php b/vendor/oyejorge/less.php/lib/Less/VisitorReplacing.php deleted file mode 100644 index 5923170..0000000 --- a/vendor/oyejorge/less.php/lib/Less/VisitorReplacing.php +++ /dev/null @@ -1,75 +0,0 @@ -type; - if( isset($this->_visitFnCache[$funcName]) ){ - - $visitDeeper = true; - $node = $this->$funcName( $node, $visitDeeper ); - - if( $node ){ - if( $visitDeeper && is_object($node) ){ - $node->accept($this); - } - - $funcName = $funcName . "Out"; - if( isset($this->_visitFnCache[$funcName]) ){ - $this->$funcName( $node ); - } - } - - }else{ - $node->accept($this); - } - - return $node; - } - - public function visitArray( $nodes ){ - - $newNodes = array(); - foreach($nodes as $node){ - $evald = $this->visitObj($node); - if( $evald ){ - if( is_array($evald) ){ - self::flatten($evald,$newNodes); - }else{ - $newNodes[] = $evald; - } - } - } - return $newNodes; - } - - public function flatten( $arr, &$out ){ - - foreach($arr as $item){ - if( !is_array($item) ){ - $out[] = $item; - continue; - } - - foreach($item as $nestedItem){ - if( is_array($nestedItem) ){ - self::flatten( $nestedItem, $out); - }else{ - $out[] = $nestedItem; - } - } - } - - return $out; - } - -} - - diff --git a/vendor/psr/log/src/LoggerAwareInterface.php b/vendor/psr/log/src/LoggerAwareInterface.php index cc46a95..0621870 100644 --- a/vendor/psr/log/src/LoggerAwareInterface.php +++ b/vendor/psr/log/src/LoggerAwareInterface.php @@ -9,10 +9,6 @@ interface LoggerAwareInterface { /** * Sets a logger instance on the object. - * - * @param LoggerInterface $logger - * - * @return void */ public function setLogger(LoggerInterface $logger): void; } diff --git a/vendor/psr/log/src/LoggerAwareTrait.php b/vendor/psr/log/src/LoggerAwareTrait.php index 4fb57a2..85104db 100644 --- a/vendor/psr/log/src/LoggerAwareTrait.php +++ b/vendor/psr/log/src/LoggerAwareTrait.php @@ -9,15 +9,11 @@ trait LoggerAwareTrait { /** * The logger instance. - * - * @var LoggerInterface|null */ protected ?LoggerInterface $logger = null; /** * Sets a logger. - * - * @param LoggerInterface $logger */ public function setLogger(LoggerInterface $logger): void { diff --git a/vendor/psr/log/src/LoggerInterface.php b/vendor/psr/log/src/LoggerInterface.php index b3a24b5..cb4cf64 100644 --- a/vendor/psr/log/src/LoggerInterface.php +++ b/vendor/psr/log/src/LoggerInterface.php @@ -22,10 +22,7 @@ interface LoggerInterface /** * System is unusable. * - * @param string|\Stringable $message * @param mixed[] $context - * - * @return void */ public function emergency(string|\Stringable $message, array $context = []): void; @@ -35,10 +32,7 @@ public function emergency(string|\Stringable $message, array $context = []): voi * Example: Entire website down, database unavailable, etc. This should * trigger the SMS alerts and wake you up. * - * @param string|\Stringable $message * @param mixed[] $context - * - * @return void */ public function alert(string|\Stringable $message, array $context = []): void; @@ -47,10 +41,7 @@ public function alert(string|\Stringable $message, array $context = []): void; * * Example: Application component unavailable, unexpected exception. * - * @param string|\Stringable $message * @param mixed[] $context - * - * @return void */ public function critical(string|\Stringable $message, array $context = []): void; @@ -58,10 +49,7 @@ public function critical(string|\Stringable $message, array $context = []): void * Runtime errors that do not require immediate action but should typically * be logged and monitored. * - * @param string|\Stringable $message * @param mixed[] $context - * - * @return void */ public function error(string|\Stringable $message, array $context = []): void; @@ -71,20 +59,14 @@ public function error(string|\Stringable $message, array $context = []): void; * Example: Use of deprecated APIs, poor use of an API, undesirable things * that are not necessarily wrong. * - * @param string|\Stringable $message * @param mixed[] $context - * - * @return void */ public function warning(string|\Stringable $message, array $context = []): void; /** * Normal but significant events. * - * @param string|\Stringable $message * @param mixed[] $context - * - * @return void */ public function notice(string|\Stringable $message, array $context = []): void; @@ -93,32 +75,23 @@ public function notice(string|\Stringable $message, array $context = []): void; * * Example: User logs in, SQL logs. * - * @param string|\Stringable $message * @param mixed[] $context - * - * @return void */ public function info(string|\Stringable $message, array $context = []): void; /** * Detailed debug information. * - * @param string|\Stringable $message * @param mixed[] $context - * - * @return void */ public function debug(string|\Stringable $message, array $context = []): void; /** * Logs with an arbitrary level. * - * @param mixed $level - * @param string|\Stringable $message + * @param mixed $level * @param mixed[] $context * - * @return void - * * @throws \Psr\Log\InvalidArgumentException */ public function log($level, string|\Stringable $message, array $context = []): void; diff --git a/vendor/psr/log/src/LoggerTrait.php b/vendor/psr/log/src/LoggerTrait.php index 9c8733f..a5d9980 100644 --- a/vendor/psr/log/src/LoggerTrait.php +++ b/vendor/psr/log/src/LoggerTrait.php @@ -14,11 +14,6 @@ trait LoggerTrait { /** * System is unusable. - * - * @param string|\Stringable $message - * @param array $context - * - * @return void */ public function emergency(string|\Stringable $message, array $context = []): void { @@ -30,11 +25,6 @@ public function emergency(string|\Stringable $message, array $context = []): voi * * Example: Entire website down, database unavailable, etc. This should * trigger the SMS alerts and wake you up. - * - * @param string|\Stringable $message - * @param array $context - * - * @return void */ public function alert(string|\Stringable $message, array $context = []): void { @@ -45,11 +35,6 @@ public function alert(string|\Stringable $message, array $context = []): void * Critical conditions. * * Example: Application component unavailable, unexpected exception. - * - * @param string|\Stringable $message - * @param array $context - * - * @return void */ public function critical(string|\Stringable $message, array $context = []): void { @@ -59,11 +44,6 @@ public function critical(string|\Stringable $message, array $context = []): void /** * Runtime errors that do not require immediate action but should typically * be logged and monitored. - * - * @param string|\Stringable $message - * @param array $context - * - * @return void */ public function error(string|\Stringable $message, array $context = []): void { @@ -75,11 +55,6 @@ public function error(string|\Stringable $message, array $context = []): void * * Example: Use of deprecated APIs, poor use of an API, undesirable things * that are not necessarily wrong. - * - * @param string|\Stringable $message - * @param array $context - * - * @return void */ public function warning(string|\Stringable $message, array $context = []): void { @@ -88,11 +63,6 @@ public function warning(string|\Stringable $message, array $context = []): void /** * Normal but significant events. - * - * @param string|\Stringable $message - * @param array $context - * - * @return void */ public function notice(string|\Stringable $message, array $context = []): void { @@ -103,11 +73,6 @@ public function notice(string|\Stringable $message, array $context = []): void * Interesting events. * * Example: User logs in, SQL logs. - * - * @param string|\Stringable $message - * @param array $context - * - * @return void */ public function info(string|\Stringable $message, array $context = []): void { @@ -116,11 +81,6 @@ public function info(string|\Stringable $message, array $context = []): void /** * Detailed debug information. - * - * @param string|\Stringable $message - * @param array $context - * - * @return void */ public function debug(string|\Stringable $message, array $context = []): void { @@ -130,11 +90,7 @@ public function debug(string|\Stringable $message, array $context = []): void /** * Logs with an arbitrary level. * - * @param mixed $level - * @param string|\Stringable $message - * @param array $context - * - * @return void + * @param mixed $level * * @throws \Psr\Log\InvalidArgumentException */ diff --git a/vendor/psr/log/src/NullLogger.php b/vendor/psr/log/src/NullLogger.php index c1cc3c0..de0561e 100644 --- a/vendor/psr/log/src/NullLogger.php +++ b/vendor/psr/log/src/NullLogger.php @@ -15,11 +15,7 @@ class NullLogger extends AbstractLogger /** * Logs with an arbitrary level. * - * @param mixed $level - * @param string|\Stringable $message - * @param array $context - * - * @return void + * @param mixed[] $context * * @throws \Psr\Log\InvalidArgumentException */ diff --git a/vendor/react/promise/CHANGELOG.md b/vendor/react/promise/CHANGELOG.md index ae5bbeb..c5d7303 100644 --- a/vendor/react/promise/CHANGELOG.md +++ b/vendor/react/promise/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## 3.2.0 (2024-05-24) + +* Feature: Improve PHP 8.4+ support by avoiding implicitly nullable type declarations. + (#260 by @Ayesh) + +* Feature: Include previous exceptions when reporting unhandled promise rejections. + (#262 by @clue) + +* Update test suite to improve PHP 8.4+ support. + (#261 by @SimonFrings) + ## 3.1.0 (2023-11-16) * Feature: Full PHP 8.3 compatibility. diff --git a/vendor/react/promise/README.md b/vendor/react/promise/README.md index 5cb6f7d..2108d98 100644 --- a/vendor/react/promise/README.md +++ b/vendor/react/promise/README.md @@ -664,7 +664,7 @@ This project follows [SemVer](https://semver.org/). This will install the latest supported version from this branch: ```bash -composer require react/promise:^3.1 +composer require react/promise:^3.2 ``` See also the [CHANGELOG](CHANGELOG.md) for details about version upgrades. diff --git a/vendor/react/promise/src/Deferred.php b/vendor/react/promise/src/Deferred.php index dac6b2b..80b8fcf 100644 --- a/vendor/react/promise/src/Deferred.php +++ b/vendor/react/promise/src/Deferred.php @@ -21,7 +21,7 @@ final class Deferred /** * @param (callable(callable(T):void,callable(\Throwable):void):void)|null $canceller */ - public function __construct(callable $canceller = null) + public function __construct(?callable $canceller = null) { $this->promise = new Promise(function ($resolve, $reject): void { $this->resolveCallback = $resolve; diff --git a/vendor/react/promise/src/Internal/FulfilledPromise.php b/vendor/react/promise/src/Internal/FulfilledPromise.php index 3c02b43..8664ffd 100644 --- a/vendor/react/promise/src/Internal/FulfilledPromise.php +++ b/vendor/react/promise/src/Internal/FulfilledPromise.php @@ -34,7 +34,7 @@ public function __construct($value = null) * @param ?(callable((T is void ? null : T)): (PromiseInterface|TFulfilled)) $onFulfilled * @return PromiseInterface<($onFulfilled is null ? T : TFulfilled)> */ - public function then(callable $onFulfilled = null, callable $onRejected = null): PromiseInterface + public function then(?callable $onFulfilled = null, ?callable $onRejected = null): PromiseInterface { if (null === $onFulfilled) { return $this; diff --git a/vendor/react/promise/src/Internal/RejectedPromise.php b/vendor/react/promise/src/Internal/RejectedPromise.php index 348ca6d..aa1dff3 100644 --- a/vendor/react/promise/src/Internal/RejectedPromise.php +++ b/vendor/react/promise/src/Internal/RejectedPromise.php @@ -37,8 +37,7 @@ public function __destruct() $handler = set_rejection_handler(null); if ($handler === null) { - $message = 'Unhandled promise rejection with ' . \get_class($this->reason) . ': ' . $this->reason->getMessage() . ' in ' . $this->reason->getFile() . ':' . $this->reason->getLine() . PHP_EOL; - $message .= 'Stack trace:' . PHP_EOL . $this->reason->getTraceAsString(); + $message = 'Unhandled promise rejection with ' . $this->reason; \error_log($message); return; @@ -47,8 +46,9 @@ public function __destruct() try { $handler($this->reason); } catch (\Throwable $e) { - $message = 'Fatal error: Uncaught ' . \get_class($e) . ' from unhandled promise rejection handler: ' . $e->getMessage() . ' in ' . $e->getFile() . ':' . $e->getLine() . PHP_EOL; - $message .= 'Stack trace:' . PHP_EOL . $e->getTraceAsString(); + \preg_match('/^([^:\s]++)(.*+)$/sm', (string) $e, $match); + \assert(isset($match[1], $match[2])); + $message = 'Fatal error: Uncaught ' . $match[1] . ' from unhandled promise rejection handler' . $match[2]; \error_log($message); exit(255); @@ -61,7 +61,7 @@ public function __destruct() * @param ?(callable(\Throwable): (PromiseInterface|TRejected)) $onRejected * @return PromiseInterface<($onRejected is null ? never : TRejected)> */ - public function then(callable $onFulfilled = null, callable $onRejected = null): PromiseInterface + public function then(?callable $onFulfilled = null, ?callable $onRejected = null): PromiseInterface { if (null === $onRejected) { return $this; diff --git a/vendor/react/promise/src/Promise.php b/vendor/react/promise/src/Promise.php index c46b41f..4ac2700 100644 --- a/vendor/react/promise/src/Promise.php +++ b/vendor/react/promise/src/Promise.php @@ -29,7 +29,7 @@ final class Promise implements PromiseInterface * @param callable(callable(T):void,callable(\Throwable):void):void $resolver * @param (callable(callable(T):void,callable(\Throwable):void):void)|null $canceller */ - public function __construct(callable $resolver, callable $canceller = null) + public function __construct(callable $resolver, ?callable $canceller = null) { $this->canceller = $canceller; @@ -41,7 +41,7 @@ public function __construct(callable $resolver, callable $canceller = null) $this->call($cb); } - public function then(callable $onFulfilled = null, callable $onRejected = null): PromiseInterface + public function then(?callable $onFulfilled = null, ?callable $onRejected = null): PromiseInterface { if (null !== $this->result) { return $this->result->then($onFulfilled, $onRejected); @@ -166,7 +166,7 @@ public function always(callable $onFulfilledOrRejected): PromiseInterface return $this->finally($onFulfilledOrRejected); } - private function resolver(callable $onFulfilled = null, callable $onRejected = null): callable + private function resolver(?callable $onFulfilled = null, ?callable $onRejected = null): callable { return function (callable $resolve, callable $reject) use ($onFulfilled, $onRejected): void { $this->handlers[] = static function (PromiseInterface $promise) use ($onFulfilled, $onRejected, $resolve, $reject): void { diff --git a/vendor/seld/jsonlint/README.md b/vendor/seld/jsonlint/README.md index ab4346d..e658f72 100644 --- a/vendor/seld/jsonlint/README.md +++ b/vendor/seld/jsonlint/README.md @@ -35,6 +35,7 @@ You can also pass additional flags to `JsonParser::lint/parse` that tweak the fu - `JsonParser::ALLOW_DUPLICATE_KEYS` collects duplicate keys. e.g. if you have two `foo` keys they will end up as `foo` and `foo.2`. - `JsonParser::PARSE_TO_ASSOC` parses to associative arrays instead of stdClass objects. - `JsonParser::ALLOW_COMMENTS` parses while allowing (and ignoring) inline `//` and multiline `/* */` comments in the JSON document. +- `JsonParser::ALLOW_DUPLICATE_KEYS_TO_ARRAY` collects duplicate keys. e.g. if you have two `foo` keys the `foo` key will become an object (or array in assoc mode) with all `foo` values accessible as an array in `$result->foo->__duplicates__` (or `$result['foo']['__duplicates__']` in assoc mode). Example: diff --git a/vendor/seld/jsonlint/bin/jsonlint b/vendor/seld/jsonlint/bin/jsonlint old mode 100644 new mode 100755 diff --git a/vendor/seld/jsonlint/composer.json b/vendor/seld/jsonlint/composer.json index 3f8afc5..dbc48e3 100644 --- a/vendor/seld/jsonlint/composer.json +++ b/vendor/seld/jsonlint/composer.json @@ -16,7 +16,7 @@ }, "require-dev": { "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^8.5.13", - "phpstan/phpstan": "^1.5" + "phpstan/phpstan": "^1.11" }, "autoload": { "psr-4": { "Seld\\JsonLint\\": "src/Seld/JsonLint/" } diff --git a/vendor/seld/jsonlint/src/Seld/JsonLint/JsonParser.php b/vendor/seld/jsonlint/src/Seld/JsonLint/JsonParser.php index 420c0fd..cec4a87 100644 --- a/vendor/seld/jsonlint/src/Seld/JsonLint/JsonParser.php +++ b/vendor/seld/jsonlint/src/Seld/JsonLint/JsonParser.php @@ -31,6 +31,7 @@ class JsonParser const ALLOW_DUPLICATE_KEYS = 2; const PARSE_TO_ASSOC = 4; const ALLOW_COMMENTS = 8; + const ALLOW_DUPLICATE_KEYS_TO_ARRAY = 16; /** @var Lexer */ private $lexer; @@ -201,6 +202,10 @@ public function lint($input, $flags = 0) */ public function parse($input, $flags = 0) { + if (($flags & self::ALLOW_DUPLICATE_KEYS_TO_ARRAY) && ($flags & self::ALLOW_DUPLICATE_KEYS)) { + throw new \InvalidArgumentException('Only one of ALLOW_DUPLICATE_KEYS and ALLOW_DUPLICATE_KEYS_TO_ARRAY can be used, you passed in both.'); + } + $this->failOnBOM($input); $this->flags = $flags; @@ -334,7 +339,7 @@ public function parse($input, $flags = 0) } // this shouldn't happen, unless resolve defaults are off - if (\is_array($action[0]) && \count($action) > 1) { // @phpstan-ignore-line + if (\is_array($action[0]) && \count($action) > 1) { throw new ParsingException('Parse Error: multiple actions possible at state: ' . $state . ', token: ' . $symbol); } @@ -484,14 +489,21 @@ private function performAction($currentToken, $yytext, $yyleng, $yylineno, $yyst $errStr .= $this->lexer->showPosition() . "\n"; $errStr .= "Duplicate key: ".$this->vstack[$len][0]; throw new DuplicateKeyException($errStr, $this->vstack[$len][0], array('line' => $yylineno+1)); - } elseif (($this->flags & self::ALLOW_DUPLICATE_KEYS) && isset($this->vstack[$len-2][$key])) { + } + if (($this->flags & self::ALLOW_DUPLICATE_KEYS) && isset($this->vstack[$len-2][$key])) { $duplicateCount = 1; do { $duplicateKey = $key . '.' . $duplicateCount++; } while (isset($this->vstack[$len-2][$duplicateKey])); - $key = $duplicateKey; + $this->vstack[$len-2][$duplicateKey] = $this->vstack[$len][1]; + } elseif (($this->flags & self::ALLOW_DUPLICATE_KEYS_TO_ARRAY) && isset($this->vstack[$len-2][$key])) { + if (!isset($this->vstack[$len-2][$key]['__duplicates__']) || !is_array($this->vstack[$len-2][$key]['__duplicates__'])) { + $this->vstack[$len-2][$key] = array('__duplicates__' => array($this->vstack[$len-2][$key])); + } + $this->vstack[$len-2][$key]['__duplicates__'][] = $this->vstack[$len][1]; + } else { + $this->vstack[$len-2][$key] = $this->vstack[$len][1]; } - $this->vstack[$len-2][$key] = $this->vstack[$len][1]; } else { assert($this->vstack[$len-2] instanceof stdClass); $token = $this->vstack[$len-2]; @@ -500,19 +512,26 @@ private function performAction($currentToken, $yytext, $yyleng, $yylineno, $yyst } else { $key = $this->vstack[$len][0]; } - if (($this->flags & self::DETECT_KEY_CONFLICTS) && isset($this->vstack[$len-2]->{$key})) { + if (($this->flags & self::DETECT_KEY_CONFLICTS) && isset($this->vstack[$len-2]->$key)) { $errStr = 'Parse error on line ' . ($yylineno+1) . ":\n"; $errStr .= $this->lexer->showPosition() . "\n"; $errStr .= "Duplicate key: ".$this->vstack[$len][0]; throw new DuplicateKeyException($errStr, $this->vstack[$len][0], array('line' => $yylineno+1)); - } elseif (($this->flags & self::ALLOW_DUPLICATE_KEYS) && isset($this->vstack[$len-2]->{$key})) { + } + if (($this->flags & self::ALLOW_DUPLICATE_KEYS) && isset($this->vstack[$len-2]->$key)) { $duplicateCount = 1; do { $duplicateKey = $key . '.' . $duplicateCount++; } while (isset($this->vstack[$len-2]->$duplicateKey)); - $key = $duplicateKey; + $this->vstack[$len-2]->$duplicateKey = $this->vstack[$len][1]; + } elseif (($this->flags & self::ALLOW_DUPLICATE_KEYS_TO_ARRAY) && isset($this->vstack[$len-2]->$key)) { + if (!isset($this->vstack[$len-2]->$key->__duplicates__)) { + $this->vstack[$len-2]->$key = (object) array('__duplicates__' => array($this->vstack[$len-2]->$key)); + } + $this->vstack[$len-2]->$key->__duplicates__[] = $this->vstack[$len][1]; + } else { + $this->vstack[$len-2]->$key = $this->vstack[$len][1]; } - $this->vstack[$len-2]->$key = $this->vstack[$len][1]; } break; case 18: diff --git a/vendor/symfony/console/Application.php b/vendor/symfony/console/Application.php index b97d087..87eb7a6 100644 --- a/vendor/symfony/console/Application.php +++ b/vendor/symfony/console/Application.php @@ -75,8 +75,6 @@ class Application implements ResetInterface private array $commands = []; private bool $wantHelps = false; private ?Command $runningCommand = null; - private string $name; - private string $version; private ?CommandLoaderInterface $commandLoader = null; private bool $catchExceptions = true; private bool $catchErrors = false; @@ -91,15 +89,15 @@ class Application implements ResetInterface private ?SignalRegistry $signalRegistry = null; private array $signalsToDispatchEvent = []; - public function __construct(string $name = 'UNKNOWN', string $version = 'UNKNOWN') - { - $this->name = $name; - $this->version = $version; + public function __construct( + private string $name = 'UNKNOWN', + private string $version = 'UNKNOWN', + ) { $this->terminal = new Terminal(); $this->defaultCommand = 'list'; if (\defined('SIGINT') && SignalRegistry::isSupported()) { $this->signalRegistry = new SignalRegistry(); - $this->signalsToDispatchEvent = [\SIGINT, \SIGTERM, \SIGUSR1, \SIGUSR2]; + $this->signalsToDispatchEvent = [\SIGINT, \SIGQUIT, \SIGTERM, \SIGUSR1, \SIGUSR2]; } } @@ -111,10 +109,7 @@ public function setDispatcher(EventDispatcherInterface $dispatcher): void $this->dispatcher = $dispatcher; } - /** - * @return void - */ - public function setCommandLoader(CommandLoaderInterface $commandLoader) + public function setCommandLoader(CommandLoaderInterface $commandLoader): void { $this->commandLoader = $commandLoader; } @@ -128,10 +123,7 @@ public function getSignalRegistry(): SignalRegistry return $this->signalRegistry; } - /** - * @return void - */ - public function setSignalsToDispatchEvent(int ...$signalsToDispatchEvent) + public function setSignalsToDispatchEvent(int ...$signalsToDispatchEvent): void { $this->signalsToDispatchEvent = $signalsToDispatchEvent; } @@ -224,7 +216,7 @@ public function run(?InputInterface $input = null, ?OutputInterface $output = nu * * @return int 0 if everything went fine, or an error code */ - public function doRun(InputInterface $input, OutputInterface $output) + public function doRun(InputInterface $input, OutputInterface $output): int { if (true === $input->hasParameterOption(['--version', '-V'], true)) { $output->writeln($this->getLongVersion()); @@ -327,17 +319,11 @@ public function doRun(InputInterface $input, OutputInterface $output) return $exitCode; } - /** - * @return void - */ - public function reset() + public function reset(): void { } - /** - * @return void - */ - public function setHelperSet(HelperSet $helperSet) + public function setHelperSet(HelperSet $helperSet): void { $this->helperSet = $helperSet; } @@ -350,10 +336,7 @@ public function getHelperSet(): HelperSet return $this->helperSet ??= $this->getDefaultHelperSet(); } - /** - * @return void - */ - public function setDefinition(InputDefinition $definition) + public function setDefinition(InputDefinition $definition): void { $this->definition = $definition; } @@ -423,10 +406,8 @@ public function areExceptionsCaught(): bool /** * Sets whether to catch exceptions or not during commands execution. - * - * @return void */ - public function setCatchExceptions(bool $boolean) + public function setCatchExceptions(bool $boolean): void { $this->catchExceptions = $boolean; } @@ -449,10 +430,8 @@ public function isAutoExitEnabled(): bool /** * Sets whether to automatically exit after a command execution or not. - * - * @return void */ - public function setAutoExit(bool $boolean) + public function setAutoExit(bool $boolean): void { $this->autoExit = $boolean; } @@ -467,10 +446,8 @@ public function getName(): string /** * Sets the application name. - * - * @return void */ - public function setName(string $name) + public function setName(string $name): void { $this->name = $name; } @@ -485,20 +462,16 @@ public function getVersion(): string /** * Sets the application version. - * - * @return void */ - public function setVersion(string $version) + public function setVersion(string $version): void { $this->version = $version; } /** * Returns the long version of the application. - * - * @return string */ - public function getLongVersion() + public function getLongVersion(): string { if ('UNKNOWN' !== $this->getName()) { if ('UNKNOWN' !== $this->getVersion()) { @@ -525,10 +498,8 @@ public function register(string $name): Command * If a Command is not enabled it will not be added. * * @param Command[] $commands An array of commands - * - * @return void */ - public function addCommands(array $commands) + public function addCommands(array $commands): void { foreach ($commands as $command) { $this->add($command); @@ -540,10 +511,8 @@ public function addCommands(array $commands) * * If a command with the same name already exists, it will be overridden. * If the command is not enabled it will not be added. - * - * @return Command|null */ - public function add(Command $command) + public function add(Command $command): ?Command { $this->init(); @@ -576,11 +545,9 @@ public function add(Command $command) /** * Returns a registered command by name or alias. * - * @return Command - * * @throws CommandNotFoundException When given command name does not exist */ - public function get(string $name) + public function get(string $name): Command { $this->init(); @@ -653,7 +620,7 @@ public function findNamespace(string $namespace): string $expr = implode('[^:]*:', array_map('preg_quote', explode(':', $namespace))).'[^:]*'; $namespaces = preg_grep('{^'.$expr.'}', $allNamespaces); - if (empty($namespaces)) { + if (!$namespaces) { $message = sprintf('There are no commands defined in the "%s" namespace.', $namespace); if ($alternatives = $this->findAlternatives($namespace, $allNamespaces)) { @@ -683,11 +650,9 @@ public function findNamespace(string $namespace): string * Contrary to get, this command tries to find the best * match if you give it an abbreviation of a name or alias. * - * @return Command - * * @throws CommandNotFoundException When command name is incorrect or ambiguous */ - public function find(string $name) + public function find(string $name): Command { $this->init(); @@ -709,12 +674,12 @@ public function find(string $name) $expr = implode('[^:]*:', array_map('preg_quote', explode(':', $name))).'[^:]*'; $commands = preg_grep('{^'.$expr.'}', $allCommands); - if (empty($commands)) { + if (!$commands) { $commands = preg_grep('{^'.$expr.'}i', $allCommands); } // if no commands matched or we just matched namespaces - if (empty($commands) || \count(preg_grep('{^'.$expr.'$}i', $commands)) < 1) { + if (!$commands || \count(preg_grep('{^'.$expr.'$}i', $commands)) < 1) { if (false !== $pos = strrpos($name, ':')) { // check if a namespace exists and contains commands $this->findNamespace(substr($name, 0, $pos)); @@ -749,7 +714,7 @@ public function find(string $name) $aliases[$nameOrAlias] = $commandName; - return $commandName === $nameOrAlias || !\in_array($commandName, $commands); + return $commandName === $nameOrAlias || !\in_array($commandName, $commands, true); })); } @@ -795,7 +760,7 @@ public function find(string $name) * * @return Command[] */ - public function all(?string $namespace = null) + public function all(?string $namespace = null): array { $this->init(); @@ -936,10 +901,8 @@ protected function doRenderThrowable(\Throwable $e, OutputInterface $output): vo /** * Configures the input and output instances based on the user arguments and options. - * - * @return void */ - protected function configureIO(InputInterface $input, OutputInterface $output) + protected function configureIO(InputInterface $input, OutputInterface $output): void { if (true === $input->hasParameterOption(['--ansi'], true)) { $output->setDecorated(true); @@ -1004,7 +967,7 @@ protected function configureIO(InputInterface $input, OutputInterface $output) * * @return int 0 if everything went fine, or an error code */ - protected function doRunCommand(Command $command, InputInterface $input, OutputInterface $output) + protected function doRunCommand(Command $command, InputInterface $input, OutputInterface $output): int { foreach ($command->getHelperSet() as $helper) { if ($helper instanceof InputAwareInterface) { @@ -1021,7 +984,7 @@ protected function doRunCommand(Command $command, InputInterface $input, OutputI if (Terminal::hasSttyAvailable()) { $sttyMode = shell_exec('stty -g'); - foreach ([\SIGINT, \SIGTERM] as $signal) { + foreach ([\SIGINT, \SIGQUIT, \SIGTERM] as $signal) { $this->signalRegistry->register($signal, static fn () => shell_exec('stty '.$sttyMode)); } } @@ -1038,11 +1001,6 @@ protected function doRunCommand(Command $command, InputInterface $input, OutputI // If the command is signalable, we call the handleSignal() method if (\in_array($signal, $commandSignals, true)) { $exitCode = $command->handleSignal($signal, $exitCode); - // BC layer for Symfony <= 5 - if (null === $exitCode) { - trigger_deprecation('symfony/console', '6.3', 'Not returning an exit code from "%s::handleSignal()" is deprecated, return "false" to keep the command running or "0" to exit successfully.', get_debug_type($command)); - $exitCode = 0; - } } if (false !== $exitCode) { @@ -1060,14 +1018,7 @@ protected function doRunCommand(Command $command, InputInterface $input, OutputI foreach ($commandSignals as $signal) { $this->signalRegistry->register($signal, function (int $signal) use ($command): void { - $exitCode = $command->handleSignal($signal); - // BC layer for Symfony <= 5 - if (null === $exitCode) { - trigger_deprecation('symfony/console', '6.3', 'Not returning an exit code from "%s::handleSignal()" is deprecated, return "false" to keep the command running or "0" to exit successfully.', get_debug_type($command)); - $exitCode = 0; - } - - if (false !== $exitCode) { + if (false !== $exitCode = $command->handleSignal($signal)) { exit($exitCode); } }); diff --git a/vendor/symfony/console/Attribute/AsCommand.php b/vendor/symfony/console/Attribute/AsCommand.php index b337f54..6066d7c 100644 --- a/vendor/symfony/console/Attribute/AsCommand.php +++ b/vendor/symfony/console/Attribute/AsCommand.php @@ -17,6 +17,12 @@ #[\Attribute(\Attribute::TARGET_CLASS)] class AsCommand { + /** + * @param string $name The name of the command, used when calling it (i.e. "cache:clear") + * @param string|null $description The description of the command, displayed with the help page + * @param string[] $aliases The list of aliases of the command. The command will be executed when using one of them (i.e. "cache:clean") + * @param bool $hidden If true, the command won't be shown when listing all the available commands, but it can still be run as any other command + */ public function __construct( public string $name, public ?string $description = null, diff --git a/vendor/symfony/console/CHANGELOG.md b/vendor/symfony/console/CHANGELOG.md index 9ccb41d..25d7f71 100644 --- a/vendor/symfony/console/CHANGELOG.md +++ b/vendor/symfony/console/CHANGELOG.md @@ -1,6 +1,19 @@ CHANGELOG ========= +7.1 +--- + + * Add `ArgvInput::getRawTokens()` + +7.0 +--- + + * Add method `__toString()` to `InputInterface` + * Remove `Command::$defaultName` and `Command::$defaultDescription`, use the `AsCommand` attribute instead + * Require explicit argument when calling `*Command::setApplication()`, `*FormatterStyle::setForeground/setBackground()`, `Helper::setHelpSet()`, `Input*::setDefault()` and `Question::setAutocompleterCallback/setValidator()` + * Remove `StringInput::REGEX_STRING` + 6.4 --- diff --git a/vendor/symfony/console/Command/Command.php b/vendor/symfony/console/Command/Command.php index 9f9cb2f..03da6db 100644 --- a/vendor/symfony/console/Command/Command.php +++ b/vendor/symfony/console/Command/Command.php @@ -39,20 +39,6 @@ class Command public const FAILURE = 1; public const INVALID = 2; - /** - * @var string|null The default command name - * - * @deprecated since Symfony 6.1, use the AsCommand attribute instead - */ - protected static $defaultName; - - /** - * @var string|null The default command description - * - * @deprecated since Symfony 6.1, use the AsCommand attribute instead - */ - protected static $defaultDescription; - private ?Application $application = null; private ?string $name = null; private ?string $processTitle = null; @@ -70,40 +56,20 @@ class Command public static function getDefaultName(): ?string { - $class = static::class; - - if ($attribute = (new \ReflectionClass($class))->getAttributes(AsCommand::class)) { + if ($attribute = (new \ReflectionClass(static::class))->getAttributes(AsCommand::class)) { return $attribute[0]->newInstance()->name; } - $r = new \ReflectionProperty($class, 'defaultName'); - - if ($class !== $r->class || null === static::$defaultName) { - return null; - } - - trigger_deprecation('symfony/console', '6.1', 'Relying on the static property "$defaultName" for setting a command name is deprecated. Add the "%s" attribute to the "%s" class instead.', AsCommand::class, static::class); - - return static::$defaultName; + return null; } public static function getDefaultDescription(): ?string { - $class = static::class; - - if ($attribute = (new \ReflectionClass($class))->getAttributes(AsCommand::class)) { + if ($attribute = (new \ReflectionClass(static::class))->getAttributes(AsCommand::class)) { return $attribute[0]->newInstance()->description; } - $r = new \ReflectionProperty($class, 'defaultDescription'); - - if ($class !== $r->class || null === static::$defaultDescription) { - return null; - } - - trigger_deprecation('symfony/console', '6.1', 'Relying on the static property "$defaultDescription" for setting a command description is deprecated. Add the "%s" attribute to the "%s" class instead.', AsCommand::class, static::class); - - return static::$defaultDescription; + return null; } /** @@ -141,22 +107,14 @@ public function __construct(?string $name = null) * Ignores validation errors. * * This is mainly useful for the help command. - * - * @return void */ - public function ignoreValidationErrors() + public function ignoreValidationErrors(): void { $this->ignoreValidationErrors = true; } - /** - * @return void - */ - public function setApplication(?Application $application = null) + public function setApplication(?Application $application): void { - if (1 > \func_num_args()) { - trigger_deprecation('symfony/console', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); - } $this->application = $application; if ($application) { $this->setHelperSet($application->getHelperSet()); @@ -167,10 +125,7 @@ public function setApplication(?Application $application = null) $this->fullDefinition = null; } - /** - * @return void - */ - public function setHelperSet(HelperSet $helperSet) + public function setHelperSet(HelperSet $helperSet): void { $this->helperSet = $helperSet; } @@ -196,10 +151,8 @@ public function getApplication(): ?Application * * Override this to check for x or y and return false if the command cannot * run properly under the current conditions. - * - * @return bool */ - public function isEnabled() + public function isEnabled(): bool { return true; } @@ -227,7 +180,7 @@ protected function configure() * * @see setCode() */ - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { throw new LogicException('You must override the execute() method in the concrete command class.'); } @@ -324,17 +277,13 @@ public function run(InputInterface $input, OutputInterface $output): int $statusCode = ($this->code)($input, $output); } else { $statusCode = $this->execute($input, $output); - - if (!\is_int($statusCode)) { - throw new \TypeError(sprintf('Return value of "%s::execute()" must be of the type int, "%s" returned.', static::class, get_debug_type($statusCode))); - } } return is_numeric($statusCode) ? (int) $statusCode : 0; } /** - * Adds suggestions to $suggestions for the current completion input (e.g. option or argument). + * Supplies suggestions when resolving possible completion options for input (e.g. option or argument). */ public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void { @@ -452,20 +401,16 @@ public function getNativeDefinition(): InputDefinition /** * Adds an argument. * - * @param $mode The argument mode: InputArgument::REQUIRED or InputArgument::OPTIONAL - * @param $default The default value (for InputArgument::OPTIONAL mode only) + * @param $mode The argument mode: InputArgument::REQUIRED or InputArgument::OPTIONAL + * @param $default The default value (for InputArgument::OPTIONAL mode only) * @param array|\Closure(CompletionInput,CompletionSuggestions):list $suggestedValues The values used for input completion * * @return $this * * @throws InvalidArgumentException When argument mode is not valid */ - public function addArgument(string $name, ?int $mode = null, string $description = '', mixed $default = null /* array|\Closure $suggestedValues = null */): static + public function addArgument(string $name, ?int $mode = null, string $description = '', mixed $default = null, array|\Closure $suggestedValues = []): static { - $suggestedValues = 5 <= \func_num_args() ? func_get_arg(4) : []; - if (!\is_array($suggestedValues) && !$suggestedValues instanceof \Closure) { - throw new \TypeError(sprintf('Argument 5 passed to "%s()" must be array or \Closure, "%s" given.', __METHOD__, get_debug_type($suggestedValues))); - } $this->definition->addArgument(new InputArgument($name, $mode, $description, $default, $suggestedValues)); $this->fullDefinition?->addArgument(new InputArgument($name, $mode, $description, $default, $suggestedValues)); @@ -475,21 +420,17 @@ public function addArgument(string $name, ?int $mode = null, string $description /** * Adds an option. * - * @param $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts - * @param $mode The option mode: One of the InputOption::VALUE_* constants - * @param $default The default value (must be null for InputOption::VALUE_NONE) + * @param $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts + * @param $mode The option mode: One of the InputOption::VALUE_* constants + * @param $default The default value (must be null for InputOption::VALUE_NONE) * @param array|\Closure(CompletionInput,CompletionSuggestions):list $suggestedValues The values used for input completion * * @return $this * * @throws InvalidArgumentException If option mode is invalid or incompatible */ - public function addOption(string $name, string|array|null $shortcut = null, ?int $mode = null, string $description = '', mixed $default = null /* array|\Closure $suggestedValues = [] */): static + public function addOption(string $name, string|array|null $shortcut = null, ?int $mode = null, string $description = '', mixed $default = null, array|\Closure $suggestedValues = []): static { - $suggestedValues = 6 <= \func_num_args() ? func_get_arg(5) : []; - if (!\is_array($suggestedValues) && !$suggestedValues instanceof \Closure) { - throw new \TypeError(sprintf('Argument 5 passed to "%s()" must be array or \Closure, "%s" given.', __METHOD__, get_debug_type($suggestedValues))); - } $this->definition->addOption(new InputOption($name, $shortcut, $mode, $description, $default, $suggestedValues)); $this->fullDefinition?->addOption(new InputOption($name, $shortcut, $mode, $description, $default, $suggestedValues)); @@ -695,12 +636,10 @@ public function getUsages(): array /** * Gets a helper instance by name. * - * @return HelperInterface - * * @throws LogicException if no HelperSet is defined * @throws InvalidArgumentException if the helper is not defined */ - public function getHelper(string $name): mixed + public function getHelper(string $name): HelperInterface { if (null === $this->helperSet) { throw new LogicException(sprintf('Cannot retrieve helper "%s" because there is no HelperSet defined. Did you forget to add your command to the application or to set the application on the command using the setApplication() method? You can also set the HelperSet directly using the setHelperSet() method.', $name)); diff --git a/vendor/symfony/console/Command/CompleteCommand.php b/vendor/symfony/console/Command/CompleteCommand.php index 23be557..38aa737 100644 --- a/vendor/symfony/console/Command/CompleteCommand.php +++ b/vendor/symfony/console/Command/CompleteCommand.php @@ -34,18 +34,7 @@ final class CompleteCommand extends Command { public const COMPLETION_API_VERSION = '1'; - /** - * @deprecated since Symfony 6.1 - */ - protected static $defaultName = '|_complete'; - - /** - * @deprecated since Symfony 6.1 - */ - protected static $defaultDescription = 'Internal command to provide shell completion suggestions'; - private array $completionOutputs; - private bool $isDebug = false; /** diff --git a/vendor/symfony/console/Command/DumpCompletionCommand.php b/vendor/symfony/console/Command/DumpCompletionCommand.php index 51b613a..be6f545 100644 --- a/vendor/symfony/console/Command/DumpCompletionCommand.php +++ b/vendor/symfony/console/Command/DumpCompletionCommand.php @@ -27,16 +27,6 @@ #[AsCommand(name: 'completion', description: 'Dump the shell completion script')] final class DumpCompletionCommand extends Command { - /** - * @deprecated since Symfony 6.1 - */ - protected static $defaultName = 'completion'; - - /** - * @deprecated since Symfony 6.1 - */ - protected static $defaultDescription = 'Dump the shell completion script'; - private array $supportedShells; protected function configure(): void diff --git a/vendor/symfony/console/Command/HelpCommand.php b/vendor/symfony/console/Command/HelpCommand.php index e6447b0..a2a72da 100644 --- a/vendor/symfony/console/Command/HelpCommand.php +++ b/vendor/symfony/console/Command/HelpCommand.php @@ -27,10 +27,7 @@ class HelpCommand extends Command { private Command $command; - /** - * @return void - */ - protected function configure() + protected function configure(): void { $this->ignoreValidationErrors(); @@ -57,10 +54,7 @@ protected function configure() ; } - /** - * @return void - */ - public function setCommand(Command $command) + public function setCommand(Command $command): void { $this->command = $command; } diff --git a/vendor/symfony/console/Command/LazyCommand.php b/vendor/symfony/console/Command/LazyCommand.php index b94da66..fd2c300 100644 --- a/vendor/symfony/console/Command/LazyCommand.php +++ b/vendor/symfony/console/Command/LazyCommand.php @@ -27,17 +27,21 @@ final class LazyCommand extends Command { private \Closure|Command $command; - private ?bool $isEnabled; - public function __construct(string $name, array $aliases, string $description, bool $isHidden, \Closure $commandFactory, ?bool $isEnabled = true) - { + public function __construct( + string $name, + array $aliases, + string $description, + bool $isHidden, + \Closure $commandFactory, + private ?bool $isEnabled = true, + ) { $this->setName($name) ->setAliases($aliases) ->setHidden($isHidden) ->setDescription($description); $this->command = $commandFactory; - $this->isEnabled = $isEnabled; } public function ignoreValidationErrors(): void @@ -45,11 +49,8 @@ public function ignoreValidationErrors(): void $this->getCommand()->ignoreValidationErrors(); } - public function setApplication(?Application $application = null): void + public function setApplication(?Application $application): void { - if (1 > \func_num_args()) { - trigger_deprecation('symfony/console', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); - } if ($this->command instanceof parent) { $this->command->setApplication($application); } @@ -116,9 +117,8 @@ public function getNativeDefinition(): InputDefinition /** * @param array|\Closure(CompletionInput,CompletionSuggestions):list $suggestedValues The values used for input completion */ - public function addArgument(string $name, ?int $mode = null, string $description = '', mixed $default = null /* array|\Closure $suggestedValues = [] */): static + public function addArgument(string $name, ?int $mode = null, string $description = '', mixed $default = null, array|\Closure $suggestedValues = []): static { - $suggestedValues = 5 <= \func_num_args() ? func_get_arg(4) : []; $this->getCommand()->addArgument($name, $mode, $description, $default, $suggestedValues); return $this; @@ -127,9 +127,8 @@ public function addArgument(string $name, ?int $mode = null, string $description /** * @param array|\Closure(CompletionInput,CompletionSuggestions):list $suggestedValues The values used for input completion */ - public function addOption(string $name, string|array|null $shortcut = null, ?int $mode = null, string $description = '', mixed $default = null /* array|\Closure $suggestedValues = [] */): static + public function addOption(string $name, string|array|null $shortcut = null, ?int $mode = null, string $description = '', mixed $default = null, array|\Closure $suggestedValues = []): static { - $suggestedValues = 6 <= \func_num_args() ? func_get_arg(5) : []; $this->getCommand()->addOption($name, $shortcut, $mode, $description, $default, $suggestedValues); return $this; diff --git a/vendor/symfony/console/Command/ListCommand.php b/vendor/symfony/console/Command/ListCommand.php index 5850c3d..61b4b1b 100644 --- a/vendor/symfony/console/Command/ListCommand.php +++ b/vendor/symfony/console/Command/ListCommand.php @@ -25,10 +25,7 @@ */ class ListCommand extends Command { - /** - * @return void - */ - protected function configure() + protected function configure(): void { $this ->setName('list') diff --git a/vendor/symfony/console/Command/LockableTrait.php b/vendor/symfony/console/Command/LockableTrait.php index cd7548f..f0001cc 100644 --- a/vendor/symfony/console/Command/LockableTrait.php +++ b/vendor/symfony/console/Command/LockableTrait.php @@ -26,6 +26,8 @@ trait LockableTrait { private ?LockInterface $lock = null; + private ?LockFactory $lockFactory = null; + /** * Locks a command. */ @@ -39,13 +41,17 @@ private function lock(?string $name = null, bool $blocking = false): bool throw new LogicException('A lock is already in place.'); } - if (SemaphoreStore::isSupported()) { - $store = new SemaphoreStore(); - } else { - $store = new FlockStore(); + if (null === $this->lockFactory) { + if (SemaphoreStore::isSupported()) { + $store = new SemaphoreStore(); + } else { + $store = new FlockStore(); + } + + $this->lockFactory = (new LockFactory($store)); } - $this->lock = (new LockFactory($store))->createLock($name ?: $this->getName()); + $this->lock = $this->lockFactory->createLock($name ?: $this->getName()); if (!$this->lock->acquire($blocking)) { $this->lock = null; diff --git a/vendor/symfony/console/Command/SignalableCommandInterface.php b/vendor/symfony/console/Command/SignalableCommandInterface.php index f8eb8e5..40b301d 100644 --- a/vendor/symfony/console/Command/SignalableCommandInterface.php +++ b/vendor/symfony/console/Command/SignalableCommandInterface.php @@ -26,9 +26,7 @@ public function getSubscribedSignals(): array; /** * The method will be called when the application is signaled. * - * @param int|false $previousExitCode - * * @return int|false The exit code to return or false to continue the normal execution */ - public function handleSignal(int $signal, /* int|false $previousExitCode = 0 */); + public function handleSignal(int $signal, int|false $previousExitCode = 0): int|false; } diff --git a/vendor/symfony/console/CommandLoader/ContainerCommandLoader.php b/vendor/symfony/console/CommandLoader/ContainerCommandLoader.php index bfa0ac4..84e25be 100644 --- a/vendor/symfony/console/CommandLoader/ContainerCommandLoader.php +++ b/vendor/symfony/console/CommandLoader/ContainerCommandLoader.php @@ -22,16 +22,13 @@ */ class ContainerCommandLoader implements CommandLoaderInterface { - private ContainerInterface $container; - private array $commandMap; - /** * @param array $commandMap An array with command names as keys and service ids as values */ - public function __construct(ContainerInterface $container, array $commandMap) - { - $this->container = $container; - $this->commandMap = $commandMap; + public function __construct( + private ContainerInterface $container, + private array $commandMap, + ) { } public function get(string $name): Command diff --git a/vendor/symfony/console/CommandLoader/FactoryCommandLoader.php b/vendor/symfony/console/CommandLoader/FactoryCommandLoader.php index 9ced75a..ae16bf6 100644 --- a/vendor/symfony/console/CommandLoader/FactoryCommandLoader.php +++ b/vendor/symfony/console/CommandLoader/FactoryCommandLoader.php @@ -21,14 +21,12 @@ */ class FactoryCommandLoader implements CommandLoaderInterface { - private array $factories; - /** * @param callable[] $factories Indexed by command names */ - public function __construct(array $factories) - { - $this->factories = $factories; + public function __construct( + private array $factories, + ) { } public function has(string $name): bool diff --git a/vendor/symfony/console/Completion/CompletionInput.php b/vendor/symfony/console/Completion/CompletionInput.php index 7ba41c0..79c2f65 100644 --- a/vendor/symfony/console/Completion/CompletionInput.php +++ b/vendor/symfony/console/Completion/CompletionInput.php @@ -53,7 +53,7 @@ public static function fromString(string $inputStr, int $currentIndex): self * Create an input based on an COMP_WORDS token list. * * @param string[] $tokens the set of split tokens (e.g. COMP_WORDS or argv) - * @param $currentIndex the index of the cursor (e.g. COMP_CWORD) + * @param int $currentIndex the index of the cursor (e.g. COMP_CWORD) */ public static function fromTokens(array $tokens, int $currentIndex): self { diff --git a/vendor/symfony/console/Completion/Output/FishCompletionOutput.php b/vendor/symfony/console/Completion/Output/FishCompletionOutput.php index d2c414e..356a974 100644 --- a/vendor/symfony/console/Completion/Output/FishCompletionOutput.php +++ b/vendor/symfony/console/Completion/Output/FishCompletionOutput.php @@ -21,11 +21,14 @@ class FishCompletionOutput implements CompletionOutputInterface { public function write(CompletionSuggestions $suggestions, OutputInterface $output): void { - $values = $suggestions->getValueSuggestions(); + $values = []; + foreach ($suggestions->getValueSuggestions() as $value) { + $values[] = $value->getValue().($value->getDescription() ? "\t".$value->getDescription() : ''); + } foreach ($suggestions->getOptionSuggestions() as $option) { - $values[] = '--'.$option->getName(); + $values[] = '--'.$option->getName().($option->getDescription() ? "\t".$option->getDescription() : ''); if ($option->isNegatable()) { - $values[] = '--no-'.$option->getName(); + $values[] = '--no-'.$option->getName().($option->getDescription() ? "\t".$option->getDescription() : ''); } } $output->write(implode("\n", $values)); diff --git a/vendor/symfony/console/Completion/Suggestion.php b/vendor/symfony/console/Completion/Suggestion.php index 7392965..3251b07 100644 --- a/vendor/symfony/console/Completion/Suggestion.php +++ b/vendor/symfony/console/Completion/Suggestion.php @@ -20,7 +20,7 @@ class Suggestion implements \Stringable { public function __construct( private readonly string $value, - private readonly string $description = '' + private readonly string $description = '', ) { } diff --git a/vendor/symfony/console/Cursor.php b/vendor/symfony/console/Cursor.php index 69fd382..965f996 100644 --- a/vendor/symfony/console/Cursor.php +++ b/vendor/symfony/console/Cursor.php @@ -18,16 +18,16 @@ */ final class Cursor { - private OutputInterface $output; /** @var resource */ private $input; /** * @param resource|null $input */ - public function __construct(OutputInterface $output, $input = null) - { - $this->output = $output; + public function __construct( + private OutputInterface $output, + $input = null, + ) { $this->input = $input ?? (\defined('STDIN') ? \STDIN : fopen('php://input', 'r+')); } diff --git a/vendor/symfony/console/DependencyInjection/AddConsoleCommandPass.php b/vendor/symfony/console/DependencyInjection/AddConsoleCommandPass.php index 27705dd..f712c61 100644 --- a/vendor/symfony/console/DependencyInjection/AddConsoleCommandPass.php +++ b/vendor/symfony/console/DependencyInjection/AddConsoleCommandPass.php @@ -29,10 +29,7 @@ */ class AddConsoleCommandPass implements CompilerPassInterface { - /** - * @return void - */ - public function process(ContainerBuilder $container) + public function process(ContainerBuilder $container): void { $commandServices = $container->findTaggedServiceIds('console.command', true); $lazyCommandMap = []; diff --git a/vendor/symfony/console/Descriptor/ApplicationDescription.php b/vendor/symfony/console/Descriptor/ApplicationDescription.php index ef9e8a6..5149fde 100644 --- a/vendor/symfony/console/Descriptor/ApplicationDescription.php +++ b/vendor/symfony/console/Descriptor/ApplicationDescription.php @@ -24,9 +24,6 @@ class ApplicationDescription { public const GLOBAL_NAMESPACE = '_global'; - private Application $application; - private ?string $namespace; - private bool $showHidden; private array $namespaces; /** @@ -39,11 +36,11 @@ class ApplicationDescription */ private array $aliases = []; - public function __construct(Application $application, ?string $namespace = null, bool $showHidden = false) - { - $this->application = $application; - $this->namespace = $namespace; - $this->showHidden = $showHidden; + public function __construct( + private Application $application, + private ?string $namespace = null, + private bool $showHidden = false, + ) { } public function getNamespaces(): array diff --git a/vendor/symfony/console/Descriptor/DescriptorInterface.php b/vendor/symfony/console/Descriptor/DescriptorInterface.php index ab468a2..04e5a7c 100644 --- a/vendor/symfony/console/Descriptor/DescriptorInterface.php +++ b/vendor/symfony/console/Descriptor/DescriptorInterface.php @@ -20,8 +20,5 @@ */ interface DescriptorInterface { - /** - * @return void - */ - public function describe(OutputInterface $output, object $object, array $options = []); + public function describe(OutputInterface $output, object $object, array $options = []): void; } diff --git a/vendor/symfony/console/Descriptor/ReStructuredTextDescriptor.php b/vendor/symfony/console/Descriptor/ReStructuredTextDescriptor.php index d4423fd..f12fecb 100644 --- a/vendor/symfony/console/Descriptor/ReStructuredTextDescriptor.php +++ b/vendor/symfony/console/Descriptor/ReStructuredTextDescriptor.php @@ -226,7 +226,7 @@ private function getNonDefaultOptions(InputDefinition $definition): array $nonDefaultOptions = []; foreach ($definition->getOptions() as $option) { // Skip global options. - if (!\in_array($option->getName(), $globalOptions)) { + if (!\in_array($option->getName(), $globalOptions, true)) { $nonDefaultOptions[] = $option; } } diff --git a/vendor/symfony/console/Descriptor/XmlDescriptor.php b/vendor/symfony/console/Descriptor/XmlDescriptor.php index 866c718..8e44c88 100644 --- a/vendor/symfony/console/Descriptor/XmlDescriptor.php +++ b/vendor/symfony/console/Descriptor/XmlDescriptor.php @@ -208,7 +208,7 @@ private function getInputOptionDocument(InputOption $option): \DOMDocument $defaults = \is_array($option->getDefault()) ? $option->getDefault() : (\is_bool($option->getDefault()) ? [var_export($option->getDefault(), true)] : ($option->getDefault() ? [$option->getDefault()] : [])); $objectXML->appendChild($defaultsXML = $dom->createElement('defaults')); - if (!empty($defaults)) { + if ($defaults) { foreach ($defaults as $default) { $defaultsXML->appendChild($defaultXML = $dom->createElement('default')); $defaultXML->appendChild($dom->createTextNode($default)); diff --git a/vendor/symfony/console/Event/ConsoleErrorEvent.php b/vendor/symfony/console/Event/ConsoleErrorEvent.php index 7be2ff8..1c0d626 100644 --- a/vendor/symfony/console/Event/ConsoleErrorEvent.php +++ b/vendor/symfony/console/Event/ConsoleErrorEvent.php @@ -22,14 +22,15 @@ */ final class ConsoleErrorEvent extends ConsoleEvent { - private \Throwable $error; private int $exitCode; - public function __construct(InputInterface $input, OutputInterface $output, \Throwable $error, ?Command $command = null) - { + public function __construct( + InputInterface $input, + OutputInterface $output, + private \Throwable $error, + ?Command $command = null, + ) { parent::__construct($command, $input, $output); - - $this->error = $error; } public function getError(): \Throwable diff --git a/vendor/symfony/console/Event/ConsoleEvent.php b/vendor/symfony/console/Event/ConsoleEvent.php index 6ba1615..2f9f077 100644 --- a/vendor/symfony/console/Event/ConsoleEvent.php +++ b/vendor/symfony/console/Event/ConsoleEvent.php @@ -23,16 +23,11 @@ */ class ConsoleEvent extends Event { - protected $command; - - private InputInterface $input; - private OutputInterface $output; - - public function __construct(?Command $command, InputInterface $input, OutputInterface $output) - { - $this->command = $command; - $this->input = $input; - $this->output = $output; + public function __construct( + protected ?Command $command, + private InputInterface $input, + private OutputInterface $output, + ) { } /** diff --git a/vendor/symfony/console/Event/ConsoleSignalEvent.php b/vendor/symfony/console/Event/ConsoleSignalEvent.php index 95af1f9..b27f08a 100644 --- a/vendor/symfony/console/Event/ConsoleSignalEvent.php +++ b/vendor/symfony/console/Event/ConsoleSignalEvent.php @@ -20,14 +20,14 @@ */ final class ConsoleSignalEvent extends ConsoleEvent { - private int $handlingSignal; - private int|false $exitCode; - - public function __construct(Command $command, InputInterface $input, OutputInterface $output, int $handlingSignal, int|false $exitCode = 0) - { + public function __construct( + Command $command, + InputInterface $input, + OutputInterface $output, + private int $handlingSignal, + private int|false $exitCode = 0, + ) { parent::__construct($command, $input, $output); - $this->handlingSignal = $handlingSignal; - $this->exitCode = $exitCode; } public function getHandlingSignal(): int diff --git a/vendor/symfony/console/EventListener/ErrorListener.php b/vendor/symfony/console/EventListener/ErrorListener.php index c9ec244..49915a4 100644 --- a/vendor/symfony/console/EventListener/ErrorListener.php +++ b/vendor/symfony/console/EventListener/ErrorListener.php @@ -24,17 +24,12 @@ */ class ErrorListener implements EventSubscriberInterface { - private ?LoggerInterface $logger; - - public function __construct(?LoggerInterface $logger = null) - { - $this->logger = $logger; + public function __construct( + private ?LoggerInterface $logger = null, + ) { } - /** - * @return void - */ - public function onConsoleError(ConsoleErrorEvent $event) + public function onConsoleError(ConsoleErrorEvent $event): void { if (null === $this->logger) { return; @@ -51,10 +46,7 @@ public function onConsoleError(ConsoleErrorEvent $event) $this->logger->critical('Error thrown while running command "{command}". Message: "{message}"', ['exception' => $error, 'command' => $inputString, 'message' => $error->getMessage()]); } - /** - * @return void - */ - public function onConsoleTerminate(ConsoleTerminateEvent $event) + public function onConsoleTerminate(ConsoleTerminateEvent $event): void { if (null === $this->logger) { return; diff --git a/vendor/symfony/console/Exception/CommandNotFoundException.php b/vendor/symfony/console/Exception/CommandNotFoundException.php index 541b32b..246f04f 100644 --- a/vendor/symfony/console/Exception/CommandNotFoundException.php +++ b/vendor/symfony/console/Exception/CommandNotFoundException.php @@ -18,19 +18,19 @@ */ class CommandNotFoundException extends \InvalidArgumentException implements ExceptionInterface { - private array $alternatives; - /** * @param string $message Exception message to throw * @param string[] $alternatives List of similar defined names * @param int $code Exception code * @param \Throwable|null $previous Previous exception used for the exception chaining */ - public function __construct(string $message, array $alternatives = [], int $code = 0, ?\Throwable $previous = null) - { + public function __construct( + string $message, + private array $alternatives = [], + int $code = 0, + ?\Throwable $previous = null, + ) { parent::__construct($message, $code, $previous); - - $this->alternatives = $alternatives; } /** diff --git a/vendor/symfony/console/Formatter/NullOutputFormatterStyle.php b/vendor/symfony/console/Formatter/NullOutputFormatterStyle.php index ae23dec..06fa6e4 100644 --- a/vendor/symfony/console/Formatter/NullOutputFormatterStyle.php +++ b/vendor/symfony/console/Formatter/NullOutputFormatterStyle.php @@ -21,19 +21,13 @@ public function apply(string $text): string return $text; } - public function setBackground(?string $color = null): void + public function setBackground(?string $color): void { - if (1 > \func_num_args()) { - trigger_deprecation('symfony/console', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); - } // do nothing } - public function setForeground(?string $color = null): void + public function setForeground(?string $color): void { - if (1 > \func_num_args()) { - trigger_deprecation('symfony/console', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); - } // do nothing } diff --git a/vendor/symfony/console/Formatter/OutputFormatter.php b/vendor/symfony/console/Formatter/OutputFormatter.php index 3e4897c..8e81e59 100644 --- a/vendor/symfony/console/Formatter/OutputFormatter.php +++ b/vendor/symfony/console/Formatter/OutputFormatter.php @@ -83,10 +83,7 @@ public function __construct(bool $decorated = false, array $styles = []) $this->styleStack = new OutputFormatterStyleStack(); } - /** - * @return void - */ - public function setDecorated(bool $decorated) + public function setDecorated(bool $decorated): void { $this->decorated = $decorated; } @@ -96,10 +93,7 @@ public function isDecorated(): bool return $this->decorated; } - /** - * @return void - */ - public function setStyle(string $name, OutputFormatterStyleInterface $style) + public function setStyle(string $name, OutputFormatterStyleInterface $style): void { $this->styles[strtolower($name)] = $style; } @@ -123,10 +117,7 @@ public function format(?string $message): ?string return $this->formatAndWrap($message, 0); } - /** - * @return string - */ - public function formatAndWrap(?string $message, int $width) + public function formatAndWrap(?string $message, int $width): string { if (null === $message) { return ''; diff --git a/vendor/symfony/console/Formatter/OutputFormatterInterface.php b/vendor/symfony/console/Formatter/OutputFormatterInterface.php index 433cd41..947347f 100644 --- a/vendor/symfony/console/Formatter/OutputFormatterInterface.php +++ b/vendor/symfony/console/Formatter/OutputFormatterInterface.php @@ -20,10 +20,8 @@ interface OutputFormatterInterface { /** * Sets the decorated flag. - * - * @return void */ - public function setDecorated(bool $decorated); + public function setDecorated(bool $decorated): void; /** * Whether the output will decorate messages. @@ -32,10 +30,8 @@ public function isDecorated(): bool; /** * Sets a new style. - * - * @return void */ - public function setStyle(string $name, OutputFormatterStyleInterface $style); + public function setStyle(string $name, OutputFormatterStyleInterface $style): void; /** * Checks if output formatter has style with specified name. diff --git a/vendor/symfony/console/Formatter/OutputFormatterStyle.php b/vendor/symfony/console/Formatter/OutputFormatterStyle.php index 21e7f5a..20a65b5 100644 --- a/vendor/symfony/console/Formatter/OutputFormatterStyle.php +++ b/vendor/symfony/console/Formatter/OutputFormatterStyle.php @@ -38,25 +38,13 @@ public function __construct(?string $foreground = null, ?string $background = nu $this->color = new Color($this->foreground = $foreground ?: '', $this->background = $background ?: '', $this->options = $options); } - /** - * @return void - */ - public function setForeground(?string $color = null) + public function setForeground(?string $color): void { - if (1 > \func_num_args()) { - trigger_deprecation('symfony/console', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); - } $this->color = new Color($this->foreground = $color ?: '', $this->background, $this->options); } - /** - * @return void - */ - public function setBackground(?string $color = null) + public function setBackground(?string $color): void { - if (1 > \func_num_args()) { - trigger_deprecation('symfony/console', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); - } $this->color = new Color($this->foreground, $this->background = $color ?: '', $this->options); } @@ -65,19 +53,13 @@ public function setHref(string $url): void $this->href = $url; } - /** - * @return void - */ - public function setOption(string $option) + public function setOption(string $option): void { $this->options[] = $option; $this->color = new Color($this->foreground, $this->background, $this->options); } - /** - * @return void - */ - public function unsetOption(string $option) + public function unsetOption(string $option): void { $pos = array_search($option, $this->options); if (false !== $pos) { @@ -87,10 +69,7 @@ public function unsetOption(string $option) $this->color = new Color($this->foreground, $this->background, $this->options); } - /** - * @return void - */ - public function setOptions(array $options) + public function setOptions(array $options): void { $this->color = new Color($this->foreground, $this->background, $this->options = $options); } diff --git a/vendor/symfony/console/Formatter/OutputFormatterStyleInterface.php b/vendor/symfony/console/Formatter/OutputFormatterStyleInterface.php index 3b15098..0374192 100644 --- a/vendor/symfony/console/Formatter/OutputFormatterStyleInterface.php +++ b/vendor/symfony/console/Formatter/OutputFormatterStyleInterface.php @@ -20,38 +20,28 @@ interface OutputFormatterStyleInterface { /** * Sets style foreground color. - * - * @return void */ - public function setForeground(?string $color); + public function setForeground(?string $color): void; /** * Sets style background color. - * - * @return void */ - public function setBackground(?string $color); + public function setBackground(?string $color): void; /** * Sets some specific style option. - * - * @return void */ - public function setOption(string $option); + public function setOption(string $option): void; /** * Unsets some specific style option. - * - * @return void */ - public function unsetOption(string $option); + public function unsetOption(string $option): void; /** * Sets multiple style options at once. - * - * @return void */ - public function setOptions(array $options); + public function setOptions(array $options): void; /** * Applies the style to a given text. diff --git a/vendor/symfony/console/Formatter/OutputFormatterStyleStack.php b/vendor/symfony/console/Formatter/OutputFormatterStyleStack.php index 62d2ca0..4985213 100644 --- a/vendor/symfony/console/Formatter/OutputFormatterStyleStack.php +++ b/vendor/symfony/console/Formatter/OutputFormatterStyleStack.php @@ -34,20 +34,16 @@ public function __construct(?OutputFormatterStyleInterface $emptyStyle = null) /** * Resets stack (ie. empty internal arrays). - * - * @return void */ - public function reset() + public function reset(): void { $this->styles = []; } /** * Pushes a style in the stack. - * - * @return void */ - public function push(OutputFormatterStyleInterface $style) + public function push(OutputFormatterStyleInterface $style): void { $this->styles[] = $style; } diff --git a/vendor/symfony/console/Formatter/WrappableOutputFormatterInterface.php b/vendor/symfony/console/Formatter/WrappableOutputFormatterInterface.php index 746cd27..412d997 100644 --- a/vendor/symfony/console/Formatter/WrappableOutputFormatterInterface.php +++ b/vendor/symfony/console/Formatter/WrappableOutputFormatterInterface.php @@ -20,8 +20,6 @@ interface WrappableOutputFormatterInterface extends OutputFormatterInterface { /** * Formats a message according to the given styles, wrapping at `$width` (0 means no wrapping). - * - * @return string */ - public function formatAndWrap(?string $message, int $width); + public function formatAndWrap(?string $message, int $width): string; } diff --git a/vendor/symfony/console/Helper/DescriptorHelper.php b/vendor/symfony/console/Helper/DescriptorHelper.php index eb32bce..300c7b1 100644 --- a/vendor/symfony/console/Helper/DescriptorHelper.php +++ b/vendor/symfony/console/Helper/DescriptorHelper.php @@ -50,11 +50,9 @@ public function __construct() * * format: string, the output format name * * raw_text: boolean, sets output type as raw * - * @return void - * * @throws InvalidArgumentException when the given format is not supported */ - public function describe(OutputInterface $output, ?object $object, array $options = []) + public function describe(OutputInterface $output, ?object $object, array $options = []): void { $options = array_merge([ 'raw_text' => false, diff --git a/vendor/symfony/console/Helper/Dumper.php b/vendor/symfony/console/Helper/Dumper.php index a3b8e39..0cd01e6 100644 --- a/vendor/symfony/console/Helper/Dumper.php +++ b/vendor/symfony/console/Helper/Dumper.php @@ -21,17 +21,13 @@ */ final class Dumper { - private OutputInterface $output; - private ?CliDumper $dumper; - private ?ClonerInterface $cloner; private \Closure $handler; - public function __construct(OutputInterface $output, ?CliDumper $dumper = null, ?ClonerInterface $cloner = null) - { - $this->output = $output; - $this->dumper = $dumper; - $this->cloner = $cloner; - + public function __construct( + private OutputInterface $output, + private ?CliDumper $dumper = null, + private ?ClonerInterface $cloner = null, + ) { if (class_exists(CliDumper::class)) { $this->handler = function ($var): string { $dumper = $this->dumper ??= new CliDumper(null, null, CliDumper::DUMP_LIGHT_ARRAY | CliDumper::DUMP_COMMA_SEPARATOR); diff --git a/vendor/symfony/console/Helper/Helper.php b/vendor/symfony/console/Helper/Helper.php index 05be647..de09006 100644 --- a/vendor/symfony/console/Helper/Helper.php +++ b/vendor/symfony/console/Helper/Helper.php @@ -21,16 +21,10 @@ */ abstract class Helper implements HelperInterface { - protected $helperSet; + protected ?HelperSet $helperSet = null; - /** - * @return void - */ - public function setHelperSet(?HelperSet $helperSet = null) + public function setHelperSet(?HelperSet $helperSet): void { - if (1 > \func_num_args()) { - trigger_deprecation('symfony/console', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); - } $this->helperSet = $helperSet; } @@ -91,10 +85,7 @@ public static function substr(?string $string, int $from, ?int $length = null): return mb_substr($string, $from, $length, $encoding); } - /** - * @return string - */ - public static function formatTime(int|float $secs, int $precision = 1) + public static function formatTime(int|float $secs, int $precision = 1): string { $secs = (int) floor($secs); @@ -134,10 +125,7 @@ public static function formatTime(int|float $secs, int $precision = 1) return implode(', ', array_reverse($times)); } - /** - * @return string - */ - public static function formatMemory(int $memory) + public static function formatMemory(int $memory): string { if ($memory >= 1024 * 1024 * 1024) { return sprintf('%.1f GiB', $memory / 1024 / 1024 / 1024); @@ -154,10 +142,7 @@ public static function formatMemory(int $memory) return sprintf('%d B', $memory); } - /** - * @return string - */ - public static function removeDecoration(OutputFormatterInterface $formatter, ?string $string) + public static function removeDecoration(OutputFormatterInterface $formatter, ?string $string): string { $isDecorated = $formatter->isDecorated(); $formatter->setDecorated(false); diff --git a/vendor/symfony/console/Helper/HelperInterface.php b/vendor/symfony/console/Helper/HelperInterface.php index ab626c9..8c4da3c 100644 --- a/vendor/symfony/console/Helper/HelperInterface.php +++ b/vendor/symfony/console/Helper/HelperInterface.php @@ -20,10 +20,8 @@ interface HelperInterface { /** * Sets the helper set associated with this helper. - * - * @return void */ - public function setHelperSet(?HelperSet $helperSet); + public function setHelperSet(?HelperSet $helperSet): void; /** * Gets the helper set associated with this helper. @@ -32,8 +30,6 @@ public function getHelperSet(): ?HelperSet; /** * Returns the canonical name of this helper. - * - * @return string */ - public function getName(); + public function getName(): string; } diff --git a/vendor/symfony/console/Helper/HelperSet.php b/vendor/symfony/console/Helper/HelperSet.php index f8c74ca..30df9f9 100644 --- a/vendor/symfony/console/Helper/HelperSet.php +++ b/vendor/symfony/console/Helper/HelperSet.php @@ -35,10 +35,7 @@ public function __construct(array $helpers = []) } } - /** - * @return void - */ - public function set(HelperInterface $helper, ?string $alias = null) + public function set(HelperInterface $helper, ?string $alias = null): void { $this->helpers[$helper->getName()] = $helper; if (null !== $alias) { diff --git a/vendor/symfony/console/Helper/InputAwareHelper.php b/vendor/symfony/console/Helper/InputAwareHelper.php index 6f82259..47126bd 100644 --- a/vendor/symfony/console/Helper/InputAwareHelper.php +++ b/vendor/symfony/console/Helper/InputAwareHelper.php @@ -21,12 +21,9 @@ */ abstract class InputAwareHelper extends Helper implements InputAwareInterface { - protected $input; + protected InputInterface $input; - /** - * @return void - */ - public function setInput(InputInterface $input) + public function setInput(InputInterface $input): void { $this->input = $input; } diff --git a/vendor/symfony/console/Helper/OutputWrapper.php b/vendor/symfony/console/Helper/OutputWrapper.php index 2ec819c..0ea2b70 100644 --- a/vendor/symfony/console/Helper/OutputWrapper.php +++ b/vendor/symfony/console/Helper/OutputWrapper.php @@ -49,7 +49,7 @@ final class OutputWrapper private const URL_PATTERN = 'https?://\S+'; public function __construct( - private bool $allowCutUrls = false + private bool $allowCutUrls = false, ) { } diff --git a/vendor/symfony/console/Helper/ProgressBar.php b/vendor/symfony/console/Helper/ProgressBar.php index f4eec05..7c22b7d 100644 --- a/vendor/symfony/console/Helper/ProgressBar.php +++ b/vendor/symfony/console/Helper/ProgressBar.php @@ -183,9 +183,9 @@ public function setMessage(string $message, string $name = 'message'): void $this->messages[$name] = $message; } - public function getMessage(string $name = 'message'): string + public function getMessage(string $name = 'message'): ?string { - return $this->messages[$name]; + return $this->messages[$name] ?? null; } public function getStartTime(): int @@ -195,7 +195,7 @@ public function getStartTime(): int public function getMaxSteps(): int { - return $this->max; + return $this->max ?? 0; } public function getProgress(): int @@ -215,7 +215,7 @@ public function getProgressPercent(): float public function getBarOffset(): float { - return floor($this->max ? $this->percent * $this->barWidth : (null === $this->redrawFreq ? (int) (min(5, $this->barWidth / 15) * $this->writeCount) : $this->step) % $this->barWidth); + return floor(null !== $this->max ? $this->percent * $this->barWidth : (null === $this->redrawFreq ? (int) (min(5, $this->barWidth / 15) * $this->writeCount) : $this->step) % $this->barWidth); } public function getEstimated(): float @@ -253,7 +253,7 @@ public function setBarCharacter(string $char): void public function getBarCharacter(): string { - return $this->barChar ?? ($this->max ? '=' : $this->emptyBarChar); + return $this->barChar ?? (null !== $this->max ? '=' : $this->emptyBarChar); } public function setEmptyBarCharacter(string $char): void @@ -315,7 +315,21 @@ public function maxSecondsBetweenRedraws(float $seconds): void */ public function iterate(iterable $iterable, ?int $max = null): iterable { - $this->start($max ?? (is_countable($iterable) ? \count($iterable) : 0)); + if (0 === $max) { + $max = null; + } + + $max ??= is_countable($iterable) ? \count($iterable) : null; + + if (0 === $max) { + $this->max = 0; + $this->stepWidth = 2; + $this->finish(); + + return; + } + + $this->start($max); foreach ($iterable as $key => $value) { yield $key => $value; @@ -373,11 +387,15 @@ public function setProgress(int $step): void $step = 0; } - $redrawFreq = $this->redrawFreq ?? (($this->max ?: 10) / 10); - $prevPeriod = (int) ($this->step / $redrawFreq); - $currPeriod = (int) ($step / $redrawFreq); + $redrawFreq = $this->redrawFreq ?? (($this->max ?? 10) / 10); + $prevPeriod = $redrawFreq ? (int) ($this->step / $redrawFreq) : 0; + $currPeriod = $redrawFreq ? (int) ($step / $redrawFreq) : 0; $this->step = $step; - $this->percent = $this->max ? (float) $this->step / $this->max : 0; + $this->percent = match ($this->max) { + null => 0, + 0 => 1, + default => (float) $this->step / $this->max, + }; $timeInterval = microtime(true) - $this->lastWriteTime; // Draw regardless of other limits @@ -398,11 +416,20 @@ public function setProgress(int $step): void } } - public function setMaxSteps(int $max): void + public function setMaxSteps(?int $max): void { + if (0 === $max) { + $max = null; + } + $this->format = null; - $this->max = max(0, $max); - $this->stepWidth = $this->max ? Helper::width((string) $this->max) : 4; + if (null === $max) { + $this->max = null; + $this->stepWidth = 4; + } else { + $this->max = max(0, $max); + $this->stepWidth = Helper::width((string) $this->max); + } } /** @@ -410,16 +437,16 @@ public function setMaxSteps(int $max): void */ public function finish(): void { - if (!$this->max) { + if (null === $this->max) { $this->max = $this->step; } - if ($this->step === $this->max && !$this->overwrite) { + if (($this->step === $this->max || null === $this->max) && !$this->overwrite) { // prevent double 100% output return; } - $this->setProgress($this->max); + $this->setProgress($this->max ?? $this->step); } /** @@ -542,14 +569,14 @@ private static function initPlaceholderFormatters(): array }, 'elapsed' => fn (self $bar) => Helper::formatTime(time() - $bar->getStartTime(), 2), 'remaining' => function (self $bar) { - if (!$bar->getMaxSteps()) { + if (null === $bar->getMaxSteps()) { throw new LogicException('Unable to display the remaining time if the maximum number of steps is not set.'); } return Helper::formatTime($bar->getRemaining(), 2); }, 'estimated' => function (self $bar) { - if (!$bar->getMaxSteps()) { + if (null === $bar->getMaxSteps()) { throw new LogicException('Unable to display the estimated time if the maximum number of steps is not set.'); } diff --git a/vendor/symfony/console/Helper/ProgressIndicator.php b/vendor/symfony/console/Helper/ProgressIndicator.php index 92106ca..969d835 100644 --- a/vendor/symfony/console/Helper/ProgressIndicator.php +++ b/vendor/symfony/console/Helper/ProgressIndicator.php @@ -31,13 +31,11 @@ class ProgressIndicator 'very_verbose_no_ansi' => ' %message% (%elapsed:6s%, %memory:6s%)', ]; - private OutputInterface $output; private int $startTime; private ?string $format = null; private ?string $message = null; private array $indicatorValues; private int $indicatorCurrent; - private int $indicatorChangeInterval; private float $indicatorUpdateTime; private bool $started = false; @@ -50,9 +48,12 @@ class ProgressIndicator * @param int $indicatorChangeInterval Change interval in milliseconds * @param array|null $indicatorValues Animated indicator characters */ - public function __construct(OutputInterface $output, ?string $format = null, int $indicatorChangeInterval = 100, ?array $indicatorValues = null) - { - $this->output = $output; + public function __construct( + private OutputInterface $output, + ?string $format = null, + private int $indicatorChangeInterval = 100, + ?array $indicatorValues = null, + ) { $format ??= $this->determineBestFormat(); $indicatorValues ??= ['-', '\\', '|', '/']; @@ -63,17 +64,14 @@ public function __construct(OutputInterface $output, ?string $format = null, int } $this->format = self::getFormatDefinition($format); - $this->indicatorChangeInterval = $indicatorChangeInterval; $this->indicatorValues = $indicatorValues; $this->startTime = time(); } /** * Sets the current indicator message. - * - * @return void */ - public function setMessage(?string $message) + public function setMessage(?string $message): void { $this->message = $message; @@ -82,10 +80,8 @@ public function setMessage(?string $message) /** * Starts the indicator output. - * - * @return void */ - public function start(string $message) + public function start(string $message): void { if ($this->started) { throw new LogicException('Progress indicator already started.'); @@ -102,10 +98,8 @@ public function start(string $message) /** * Advances the indicator. - * - * @return void */ - public function advance() + public function advance(): void { if (!$this->started) { throw new LogicException('Progress indicator has not yet been started.'); @@ -129,10 +123,8 @@ public function advance() /** * Finish the indicator with message. - * - * @return void */ - public function finish(string $message) + public function finish(string $message): void { if (!$this->started) { throw new LogicException('Progress indicator has not yet been started.'); @@ -156,10 +148,8 @@ public static function getFormatDefinition(string $name): ?string * Sets a placeholder formatter for a given name. * * This method also allow you to override an existing placeholder. - * - * @return void */ - public static function setPlaceholderFormatterDefinition(string $name, callable $callable) + public static function setPlaceholderFormatterDefinition(string $name, callable $callable): void { self::$formatters ??= self::initPlaceholderFormatters(); diff --git a/vendor/symfony/console/Helper/QuestionHelper.php b/vendor/symfony/console/Helper/QuestionHelper.php index b40b131..54825c6 100644 --- a/vendor/symfony/console/Helper/QuestionHelper.php +++ b/vendor/symfony/console/Helper/QuestionHelper.php @@ -34,11 +34,6 @@ */ class QuestionHelper extends Helper { - /** - * @var resource|null - */ - private $inputStream; - private static bool $stty = true; private static bool $stdinIsInteractive; @@ -59,16 +54,15 @@ public function ask(InputInterface $input, OutputInterface $output, Question $qu return $this->getDefaultAnswer($question); } - if ($input instanceof StreamableInputInterface && $stream = $input->getStream()) { - $this->inputStream = $stream; - } + $inputStream = $input instanceof StreamableInputInterface ? $input->getStream() : null; + $inputStream ??= STDIN; try { if (!$question->getValidator()) { - return $this->doAsk($output, $question); + return $this->doAsk($inputStream, $output, $question); } - $interviewer = fn () => $this->doAsk($output, $question); + $interviewer = fn () => $this->doAsk($inputStream, $output, $question); return $this->validateAttempts($interviewer, $output, $question); } catch (MissingInputException $exception) { @@ -89,10 +83,8 @@ public function getName(): string /** * Prevents usage of stty. - * - * @return void */ - public static function disableStty() + public static function disableStty(): void { self::$stty = false; } @@ -100,13 +92,14 @@ public static function disableStty() /** * Asks the question to the user. * + * @param resource $inputStream + * * @throws RuntimeException In case the fallback is deactivated and the response cannot be hidden */ - private function doAsk(OutputInterface $output, Question $question): mixed + private function doAsk($inputStream, OutputInterface $output, Question $question): mixed { $this->writePrompt($output, $question); - $inputStream = $this->inputStream ?: \STDIN; $autocomplete = $question->getAutocompleterCallback(); if (null === $autocomplete || !self::$stty || !Terminal::hasSttyAvailable()) { @@ -190,10 +183,8 @@ private function getDefaultAnswer(Question $question): mixed /** * Outputs the question prompt. - * - * @return void */ - protected function writePrompt(OutputInterface $output, Question $question) + protected function writePrompt(OutputInterface $output, Question $question): void { $message = $question->getQuestion(); @@ -228,10 +219,8 @@ protected function formatChoiceQuestionChoices(ChoiceQuestion $question, string /** * Outputs an error message. - * - * @return void */ - protected function writeError(OutputInterface $output, \Exception $error) + protected function writeError(OutputInterface $output, \Exception $error): void { if (null !== $this->getHelperSet() && $this->getHelperSet()->has('formatter')) { $message = $this->getHelperSet()->get('formatter')->formatBlock($error->getMessage(), 'error'); diff --git a/vendor/symfony/console/Helper/SymfonyQuestionHelper.php b/vendor/symfony/console/Helper/SymfonyQuestionHelper.php index 8ebc843..48d947b 100644 --- a/vendor/symfony/console/Helper/SymfonyQuestionHelper.php +++ b/vendor/symfony/console/Helper/SymfonyQuestionHelper.php @@ -25,10 +25,7 @@ */ class SymfonyQuestionHelper extends QuestionHelper { - /** - * @return void - */ - protected function writePrompt(OutputInterface $output, Question $question) + protected function writePrompt(OutputInterface $output, Question $question): void { $text = OutputFormatter::escapeTrailingBackslash($question->getQuestion()); $default = $question->getDefault(); @@ -83,10 +80,7 @@ protected function writePrompt(OutputInterface $output, Question $question) $output->write($prompt); } - /** - * @return void - */ - protected function writeError(OutputInterface $output, \Exception $error) + protected function writeError(OutputInterface $output, \Exception $error): void { if ($output instanceof SymfonyStyle) { $output->newLine(); diff --git a/vendor/symfony/console/Helper/Table.php b/vendor/symfony/console/Helper/Table.php index 6aad9e9..09709a2 100644 --- a/vendor/symfony/console/Helper/Table.php +++ b/vendor/symfony/console/Helper/Table.php @@ -45,7 +45,6 @@ class Table private array $rows = []; private array $effectiveColumnWidths = []; private int $numberOfColumns; - private OutputInterface $output; private TableStyle $style; private array $columnStyles = []; private array $columnWidths = []; @@ -55,10 +54,9 @@ class Table private static array $styles; - public function __construct(OutputInterface $output) - { - $this->output = $output; - + public function __construct( + private OutputInterface $output, + ) { self::$styles ??= self::initStyles(); $this->setStyle('default'); @@ -66,10 +64,8 @@ public function __construct(OutputInterface $output) /** * Sets a style definition. - * - * @return void */ - public static function setStyleDefinition(string $name, TableStyle $style) + public static function setStyleDefinition(string $name, TableStyle $style): void { self::$styles ??= self::initStyles(); @@ -194,7 +190,7 @@ public function setHeaders(array $headers): static /** * @return $this */ - public function setRows(array $rows) + public function setRows(array $rows): static { $this->rows = []; @@ -312,10 +308,8 @@ public function setVertical(bool $vertical = true): static * | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens | * | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien | * +---------------+-----------------------+------------------+ - * - * @return void */ - public function render() + public function render(): void { $divider = new TableSeparator(); $isCellWithColspan = static fn ($cell) => $cell instanceof TableCell && $cell->getColspan() >= 2; @@ -371,8 +365,9 @@ public function render() if ($headers && !$containsColspan) { if (0 === $idx) { $rows[] = [sprintf( - '%s: %s', - str_pad($headers[$i] ?? '', $maxHeaderLength, ' ', \STR_PAD_LEFT), + '%s%s: %s', + str_repeat(' ', $maxHeaderLength - Helper::width(Helper::removeDecoration($formatter, $headers[$i] ?? ''))), + $headers[$i] ?? '', $part )]; } else { @@ -724,7 +719,7 @@ private function fillNextRows(array $rows, int $line): array foreach ($unmergedRows as $unmergedRowKey => $unmergedRow) { // we need to know if $unmergedRow will be merged or inserted into $rows - if (isset($rows[$unmergedRowKey]) && \is_array($rows[$unmergedRowKey]) && ($this->getNumberOfColumns($rows[$unmergedRowKey]) + $this->getNumberOfColumns($unmergedRows[$unmergedRowKey]) <= $this->numberOfColumns)) { + if (isset($rows[$unmergedRowKey]) && \is_array($rows[$unmergedRowKey]) && ($this->getNumberOfColumns($rows[$unmergedRowKey]) + $this->getNumberOfColumns($unmergedRow) <= $this->numberOfColumns)) { foreach ($unmergedRow as $cellKey => $cell) { // insert cell into row at cellKey position array_splice($rows[$unmergedRowKey], $cellKey, 0, [$cell]); @@ -732,8 +727,8 @@ private function fillNextRows(array $rows, int $line): array } else { $row = $this->copyRow($rows, $unmergedRowKey - 1); foreach ($unmergedRow as $column => $cell) { - if (!empty($cell)) { - $row[$column] = $unmergedRow[$column]; + if ($cell) { + $row[$column] = $cell; } } array_splice($rows, $unmergedRowKey, 0, [$row]); diff --git a/vendor/symfony/console/Helper/TableCell.php b/vendor/symfony/console/Helper/TableCell.php index 394b2bc..1c4eeea 100644 --- a/vendor/symfony/console/Helper/TableCell.php +++ b/vendor/symfony/console/Helper/TableCell.php @@ -18,17 +18,16 @@ */ class TableCell { - private string $value; private array $options = [ 'rowspan' => 1, 'colspan' => 1, 'style' => null, ]; - public function __construct(string $value = '', array $options = []) - { - $this->value = $value; - + public function __construct( + private string $value = '', + array $options = [], + ) { // check option names if ($diff = array_diff(array_keys($options), array_keys($this->options))) { throw new InvalidArgumentException(sprintf('The TableCell does not support the following options: \'%s\'.', implode('\', \'', $diff))); diff --git a/vendor/symfony/console/Helper/TableCellStyle.php b/vendor/symfony/console/Helper/TableCellStyle.php index 9419dcb..49b97f8 100644 --- a/vendor/symfony/console/Helper/TableCellStyle.php +++ b/vendor/symfony/console/Helper/TableCellStyle.php @@ -67,7 +67,7 @@ public function getTagOptions(): array { return array_filter( $this->getOptions(), - fn ($key) => \in_array($key, self::TAG_OPTIONS) && isset($this->options[$key]), + fn ($key) => \in_array($key, self::TAG_OPTIONS, true) && isset($this->options[$key]), \ARRAY_FILTER_USE_KEY ); } diff --git a/vendor/symfony/console/Helper/TableRows.php b/vendor/symfony/console/Helper/TableRows.php index 97d0772..fb2dc27 100644 --- a/vendor/symfony/console/Helper/TableRows.php +++ b/vendor/symfony/console/Helper/TableRows.php @@ -16,11 +16,9 @@ */ class TableRows implements \IteratorAggregate { - private \Closure $generator; - - public function __construct(\Closure $generator) - { - $this->generator = $generator; + public function __construct( + private \Closure $generator, + ) { } public function getIterator(): \Traversable diff --git a/vendor/symfony/console/Input/ArgvInput.php b/vendor/symfony/console/Input/ArgvInput.php index ab9f28c..95703ba 100644 --- a/vendor/symfony/console/Input/ArgvInput.php +++ b/vendor/symfony/console/Input/ArgvInput.php @@ -40,9 +40,11 @@ */ class ArgvInput extends Input { + /** @var list */ private array $tokens; private array $parsed; + /** @param list|null $argv */ public function __construct(?array $argv = null, ?InputDefinition $definition = null) { $argv ??= $_SERVER['argv'] ?? []; @@ -55,18 +57,13 @@ public function __construct(?array $argv = null, ?InputDefinition $definition = parent::__construct($definition); } - /** - * @return void - */ - protected function setTokens(array $tokens) + /** @param list $tokens */ + protected function setTokens(array $tokens): void { $this->tokens = $tokens; } - /** - * @return void - */ - protected function parse() + protected function parse(): void { $parseOptions = true; $this->parsed = $this->tokens; @@ -348,6 +345,35 @@ public function getParameterOption(string|array $values, string|bool|int|float|a return $default; } + /** + * Returns un-parsed and not validated tokens. + * + * @param bool $strip Whether to return the raw parameters (false) or the values after the command name (true) + * + * @return list + */ + public function getRawTokens(bool $strip = false): array + { + if (!$strip) { + return $this->tokens; + } + + $parameters = []; + $keep = false; + foreach ($this->tokens as $value) { + if (!$keep && $value === $this->getFirstArgument()) { + $keep = true; + + continue; + } + if ($keep) { + $parameters[] = $value; + } + } + + return $parameters; + } + /** * Returns a stringified representation of the args passed to the command. */ diff --git a/vendor/symfony/console/Input/ArrayInput.php b/vendor/symfony/console/Input/ArrayInput.php index c1bc914..d27ff41 100644 --- a/vendor/symfony/console/Input/ArrayInput.php +++ b/vendor/symfony/console/Input/ArrayInput.php @@ -25,12 +25,10 @@ */ class ArrayInput extends Input { - private array $parameters; - - public function __construct(array $parameters, ?InputDefinition $definition = null) - { - $this->parameters = $parameters; - + public function __construct( + private array $parameters, + ?InputDefinition $definition = null, + ) { parent::__construct($definition); } @@ -113,10 +111,7 @@ public function __toString(): string return implode(' ', $params); } - /** - * @return void - */ - protected function parse() + protected function parse(): void { foreach ($this->parameters as $key => $value) { if ('--' === $key) { diff --git a/vendor/symfony/console/Input/Input.php b/vendor/symfony/console/Input/Input.php index 1c21573..5a8b9a2 100644 --- a/vendor/symfony/console/Input/Input.php +++ b/vendor/symfony/console/Input/Input.php @@ -27,12 +27,12 @@ */ abstract class Input implements InputInterface, StreamableInputInterface { - protected $definition; + protected InputDefinition $definition; /** @var resource */ protected $stream; - protected $options = []; - protected $arguments = []; - protected $interactive = true; + protected array $options = []; + protected array $arguments = []; + protected bool $interactive = true; public function __construct(?InputDefinition $definition = null) { @@ -44,10 +44,7 @@ public function __construct(?InputDefinition $definition = null) } } - /** - * @return void - */ - public function bind(InputDefinition $definition) + public function bind(InputDefinition $definition): void { $this->arguments = []; $this->options = []; @@ -58,15 +55,10 @@ public function bind(InputDefinition $definition) /** * Processes command line arguments. - * - * @return void */ - abstract protected function parse(); + abstract protected function parse(): void; - /** - * @return void - */ - public function validate() + public function validate(): void { $definition = $this->definition; $givenArguments = $this->arguments; @@ -83,10 +75,7 @@ public function isInteractive(): bool return $this->interactive; } - /** - * @return void - */ - public function setInteractive(bool $interactive) + public function setInteractive(bool $interactive): void { $this->interactive = $interactive; } @@ -105,10 +94,7 @@ public function getArgument(string $name): mixed return $this->arguments[$name] ?? $this->definition->getArgument($name)->getDefault(); } - /** - * @return void - */ - public function setArgument(string $name, mixed $value) + public function setArgument(string $name, mixed $value): void { if (!$this->definition->hasArgument($name)) { throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name)); @@ -144,10 +130,7 @@ public function getOption(string $name): mixed return \array_key_exists($name, $this->options) ? $this->options[$name] : $this->definition->getOption($name)->getDefault(); } - /** - * @return void - */ - public function setOption(string $name, mixed $value) + public function setOption(string $name, mixed $value): void { if ($this->definition->hasNegation($name)) { $this->options[$this->definition->negationToName($name)] = !$value; @@ -175,10 +158,8 @@ public function escapeToken(string $token): string /** * @param resource $stream - * - * @return void */ - public function setStream($stream) + public function setStream($stream): void { $this->stream = $stream; } diff --git a/vendor/symfony/console/Input/InputArgument.php b/vendor/symfony/console/Input/InputArgument.php index 4ef79fe..a5d9492 100644 --- a/vendor/symfony/console/Input/InputArgument.php +++ b/vendor/symfony/console/Input/InputArgument.php @@ -25,37 +25,47 @@ */ class InputArgument { + /** + * Providing an argument is required (e.g. just 'app:foo' is not allowed). + */ public const REQUIRED = 1; + + /** + * Providing an argument is optional (e.g. 'app:foo' and 'app:foo bar' are both allowed). This is the default behavior of arguments. + */ public const OPTIONAL = 2; + + /** + * The argument accepts multiple values and turn them into an array (e.g. 'app:foo bar baz' will result in value ['bar', 'baz']). + */ public const IS_ARRAY = 4; - private string $name; private int $mode; - private string|int|bool|array|null|float $default; - private array|\Closure $suggestedValues; - private string $description; + private string|int|bool|array|float|null $default; /** * @param string $name The argument name - * @param int|null $mode The argument mode: a bit mask of self::REQUIRED, self::OPTIONAL and self::IS_ARRAY + * @param int-mask-of|null $mode The argument mode: a bit mask of self::REQUIRED, self::OPTIONAL and self::IS_ARRAY * @param string $description A description text * @param string|bool|int|float|array|null $default The default value (for self::OPTIONAL mode only) * @param array|\Closure(CompletionInput,CompletionSuggestions):list $suggestedValues The values used for input completion * * @throws InvalidArgumentException When argument mode is not valid */ - public function __construct(string $name, ?int $mode = null, string $description = '', string|bool|int|float|array|null $default = null, \Closure|array $suggestedValues = []) - { + public function __construct( + private string $name, + ?int $mode = null, + private string $description = '', + string|bool|int|float|array|null $default = null, + private \Closure|array $suggestedValues = [], + ) { if (null === $mode) { $mode = self::OPTIONAL; - } elseif ($mode > 7 || $mode < 1) { + } elseif ($mode >= (self::IS_ARRAY << 1) || $mode < 1) { throw new InvalidArgumentException(sprintf('Argument mode "%s" is not valid.', $mode)); } - $this->name = $name; $this->mode = $mode; - $this->description = $description; - $this->suggestedValues = $suggestedValues; $this->setDefault($default); } @@ -90,16 +100,9 @@ public function isArray(): bool /** * Sets the default value. - * - * @return void - * - * @throws LogicException When incorrect default value is given */ - public function setDefault(string|bool|int|float|array|null $default = null) + public function setDefault(string|bool|int|float|array|null $default): void { - if (1 > \func_num_args()) { - trigger_deprecation('symfony/console', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); - } if ($this->isRequired() && null !== $default) { throw new LogicException('Cannot set a default value except for InputArgument::OPTIONAL mode.'); } @@ -123,13 +126,16 @@ public function getDefault(): string|bool|int|float|array|null return $this->default; } + /** + * Returns true if the argument has values for input completion. + */ public function hasCompletion(): bool { return [] !== $this->suggestedValues; } /** - * Adds suggestions to $suggestions for the current completion input. + * Supplies suggestions when command resolves possible completion options for input. * * @see Command::complete() */ diff --git a/vendor/symfony/console/Input/InputAwareInterface.php b/vendor/symfony/console/Input/InputAwareInterface.php index 0ad27b4..ba4664c 100644 --- a/vendor/symfony/console/Input/InputAwareInterface.php +++ b/vendor/symfony/console/Input/InputAwareInterface.php @@ -21,8 +21,6 @@ interface InputAwareInterface { /** * Sets the Console Input. - * - * @return void */ - public function setInput(InputInterface $input); + public function setInput(InputInterface $input): void; } diff --git a/vendor/symfony/console/Input/InputDefinition.php b/vendor/symfony/console/Input/InputDefinition.php index b7162d7..f27e297 100644 --- a/vendor/symfony/console/Input/InputDefinition.php +++ b/vendor/symfony/console/Input/InputDefinition.php @@ -46,10 +46,8 @@ public function __construct(array $definition = []) /** * Sets the definition of the input. - * - * @return void */ - public function setDefinition(array $definition) + public function setDefinition(array $definition): void { $arguments = []; $options = []; @@ -69,10 +67,8 @@ public function setDefinition(array $definition) * Sets the InputArgument objects. * * @param InputArgument[] $arguments An array of InputArgument objects - * - * @return void */ - public function setArguments(array $arguments = []) + public function setArguments(array $arguments = []): void { $this->arguments = []; $this->requiredCount = 0; @@ -85,10 +81,8 @@ public function setArguments(array $arguments = []) * Adds an array of InputArgument objects. * * @param InputArgument[] $arguments An array of InputArgument objects - * - * @return void */ - public function addArguments(?array $arguments = []) + public function addArguments(?array $arguments = []): void { if (null !== $arguments) { foreach ($arguments as $argument) { @@ -98,11 +92,9 @@ public function addArguments(?array $arguments = []) } /** - * @return void - * * @throws LogicException When incorrect argument is given */ - public function addArgument(InputArgument $argument) + public function addArgument(InputArgument $argument): void { if (isset($this->arguments[$argument->getName()])) { throw new LogicException(sprintf('An argument with name "%s" already exists.', $argument->getName())); @@ -198,10 +190,8 @@ public function getArgumentDefaults(): array * Sets the InputOption objects. * * @param InputOption[] $options An array of InputOption objects - * - * @return void */ - public function setOptions(array $options = []) + public function setOptions(array $options = []): void { $this->options = []; $this->shortcuts = []; @@ -213,10 +203,8 @@ public function setOptions(array $options = []) * Adds an array of InputOption objects. * * @param InputOption[] $options An array of InputOption objects - * - * @return void */ - public function addOptions(array $options = []) + public function addOptions(array $options = []): void { foreach ($options as $option) { $this->addOption($option); @@ -224,11 +212,9 @@ public function addOptions(array $options = []) } /** - * @return void - * * @throws LogicException When option given already exist */ - public function addOption(InputOption $option) + public function addOption(InputOption $option): void { if (isset($this->options[$option->getName()]) && !$option->equals($this->options[$option->getName()])) { throw new LogicException(sprintf('An option named "%s" already exists.', $option->getName())); diff --git a/vendor/symfony/console/Input/InputInterface.php b/vendor/symfony/console/Input/InputInterface.php index aaed5fd..c177d96 100644 --- a/vendor/symfony/console/Input/InputInterface.php +++ b/vendor/symfony/console/Input/InputInterface.php @@ -18,9 +18,6 @@ * InputInterface is the interface implemented by all input classes. * * @author Fabien Potencier - * - * @method string __toString() Returns a stringified representation of the args passed to the command. - * InputArguments MUST be escaped as well as the InputOption values passed to the command. */ interface InputInterface { @@ -53,28 +50,22 @@ public function hasParameterOption(string|array $values, bool $onlyParams = fals * @param string|array $values The value(s) to look for in the raw parameters (can be an array) * @param string|bool|int|float|array|null $default The default value to return if no result is found * @param bool $onlyParams Only check real parameters, skip those following an end of options (--) signal - * - * @return mixed */ - public function getParameterOption(string|array $values, string|bool|int|float|array|null $default = false, bool $onlyParams = false); + public function getParameterOption(string|array $values, string|bool|int|float|array|null $default = false, bool $onlyParams = false): mixed; /** * Binds the current Input instance with the given arguments and options. * - * @return void - * * @throws RuntimeException */ - public function bind(InputDefinition $definition); + public function bind(InputDefinition $definition): void; /** * Validates the input. * - * @return void - * * @throws RuntimeException When not enough arguments are given */ - public function validate(); + public function validate(): void; /** * Returns all the given arguments merged with the default values. @@ -86,20 +77,16 @@ public function getArguments(): array; /** * Returns the argument value for a given argument name. * - * @return mixed - * * @throws InvalidArgumentException When argument given doesn't exist */ - public function getArgument(string $name); + public function getArgument(string $name): mixed; /** * Sets an argument value by name. * - * @return void - * * @throws InvalidArgumentException When argument given doesn't exist */ - public function setArgument(string $name, mixed $value); + public function setArgument(string $name, mixed $value): void; /** * Returns true if an InputArgument object exists by name or position. @@ -116,20 +103,16 @@ public function getOptions(): array; /** * Returns the option value for a given option name. * - * @return mixed - * * @throws InvalidArgumentException When option given doesn't exist */ - public function getOption(string $name); + public function getOption(string $name): mixed; /** * Sets an option value by name. * - * @return void - * * @throws InvalidArgumentException When option given doesn't exist */ - public function setOption(string $name, mixed $value); + public function setOption(string $name, mixed $value): void; /** * Returns true if an InputOption object exists by name. @@ -143,8 +126,13 @@ public function isInteractive(): bool; /** * Sets the input interactivity. + */ + public function setInteractive(bool $interactive): void; + + /** + * Returns a stringified representation of the args passed to the command. * - * @return void + * InputArguments MUST be escaped as well as the InputOption values passed to the command. */ - public function setInteractive(bool $interactive); + public function __toString(): string; } diff --git a/vendor/symfony/console/Input/InputOption.php b/vendor/symfony/console/Input/InputOption.php index bb53380..617c348 100644 --- a/vendor/symfony/console/Input/InputOption.php +++ b/vendor/symfony/console/Input/InputOption.php @@ -46,32 +46,36 @@ class InputOption public const VALUE_IS_ARRAY = 8; /** - * The option may have either positive or negative value (e.g. --ansi or --no-ansi). + * The option allows passing a negated variant (e.g. --ansi or --no-ansi). */ public const VALUE_NEGATABLE = 16; private string $name; - private string|array|null $shortcut; + private ?string $shortcut; private int $mode; - private string|int|bool|array|null|float $default; - private array|\Closure $suggestedValues; - private string $description; + private string|int|bool|array|float|null $default; /** * @param string|array|null $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts - * @param int|null $mode The option mode: One of the VALUE_* constants + * @param int-mask-of|null $mode The option mode: One of the VALUE_* constants * @param string|bool|int|float|array|null $default The default value (must be null for self::VALUE_NONE) * @param array|\Closure(CompletionInput,CompletionSuggestions):list $suggestedValues The values used for input completion * * @throws InvalidArgumentException If option mode is invalid or incompatible */ - public function __construct(string $name, string|array|null $shortcut = null, ?int $mode = null, string $description = '', string|bool|int|float|array|null $default = null, array|\Closure $suggestedValues = []) - { + public function __construct( + string $name, + string|array|null $shortcut = null, + ?int $mode = null, + private string $description = '', + string|bool|int|float|array|null $default = null, + private array|\Closure $suggestedValues = [], + ) { if (str_starts_with($name, '--')) { $name = substr($name, 2); } - if (empty($name)) { + if (!$name) { throw new InvalidArgumentException('An option name cannot be empty.'); } @@ -101,8 +105,6 @@ public function __construct(string $name, string|array|null $shortcut = null, ?i $this->name = $name; $this->shortcut = $shortcut; $this->mode = $mode; - $this->description = $description; - $this->suggestedValues = $suggestedValues; if ($suggestedValues && !$this->acceptValue()) { throw new LogicException('Cannot set suggested values if the option does not accept a value.'); @@ -173,19 +175,21 @@ public function isArray(): bool return self::VALUE_IS_ARRAY === (self::VALUE_IS_ARRAY & $this->mode); } + /** + * Returns true if the option allows passing a negated variant. + * + * @return bool true if mode is self::VALUE_NEGATABLE, false otherwise + */ public function isNegatable(): bool { return self::VALUE_NEGATABLE === (self::VALUE_NEGATABLE & $this->mode); } /** - * @return void + * Sets the default value. */ - public function setDefault(string|bool|int|float|array|null $default = null) + public function setDefault(string|bool|int|float|array|null $default): void { - if (1 > \func_num_args()) { - trigger_deprecation('symfony/console', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); - } if (self::VALUE_NONE === (self::VALUE_NONE & $this->mode) && null !== $default) { throw new LogicException('Cannot set a default value when using InputOption::VALUE_NONE mode.'); } @@ -217,13 +221,16 @@ public function getDescription(): string return $this->description; } + /** + * Returns true if the option has values for input completion. + */ public function hasCompletion(): bool { return [] !== $this->suggestedValues; } /** - * Adds suggestions to $suggestions for the current completion input. + * Supplies suggestions when command resolves possible completion options for input. * * @see Command::complete() */ diff --git a/vendor/symfony/console/Input/StreamableInputInterface.php b/vendor/symfony/console/Input/StreamableInputInterface.php index 4b95fcb..4a0dc01 100644 --- a/vendor/symfony/console/Input/StreamableInputInterface.php +++ b/vendor/symfony/console/Input/StreamableInputInterface.php @@ -25,10 +25,8 @@ interface StreamableInputInterface extends InputInterface * This is mainly useful for testing purpose. * * @param resource $stream The input stream - * - * @return void */ - public function setStream($stream); + public function setStream($stream): void; /** * Returns the input stream. diff --git a/vendor/symfony/console/Input/StringInput.php b/vendor/symfony/console/Input/StringInput.php index 82bd214..8357001 100644 --- a/vendor/symfony/console/Input/StringInput.php +++ b/vendor/symfony/console/Input/StringInput.php @@ -24,10 +24,6 @@ */ class StringInput extends ArgvInput { - /** - * @deprecated since Symfony 6.1 - */ - public const REGEX_STRING = '([^\s]+?)(?:\s|(? + * * @throws InvalidArgumentException When unable to parse input (should never happen) */ private function tokenize(string $input): array diff --git a/vendor/symfony/console/Logger/ConsoleLogger.php b/vendor/symfony/console/Logger/ConsoleLogger.php index fddef50..ad6e49c 100644 --- a/vendor/symfony/console/Logger/ConsoleLogger.php +++ b/vendor/symfony/console/Logger/ConsoleLogger.php @@ -29,7 +29,6 @@ class ConsoleLogger extends AbstractLogger public const INFO = 'info'; public const ERROR = 'error'; - private OutputInterface $output; private array $verbosityLevelMap = [ LogLevel::EMERGENCY => OutputInterface::VERBOSITY_NORMAL, LogLevel::ALERT => OutputInterface::VERBOSITY_NORMAL, @@ -52,9 +51,11 @@ class ConsoleLogger extends AbstractLogger ]; private bool $errored = false; - public function __construct(OutputInterface $output, array $verbosityLevelMap = [], array $formatLevelMap = []) - { - $this->output = $output; + public function __construct( + private OutputInterface $output, + array $verbosityLevelMap = [], + array $formatLevelMap = [], + ) { $this->verbosityLevelMap = $verbosityLevelMap + $this->verbosityLevelMap; $this->formatLevelMap = $formatLevelMap + $this->formatLevelMap; } diff --git a/vendor/symfony/console/Messenger/RunCommandMessageHandler.php b/vendor/symfony/console/Messenger/RunCommandMessageHandler.php index 14f9c17..1bc4994 100644 --- a/vendor/symfony/console/Messenger/RunCommandMessageHandler.php +++ b/vendor/symfony/console/Messenger/RunCommandMessageHandler.php @@ -22,8 +22,9 @@ */ final class RunCommandMessageHandler { - public function __construct(private readonly Application $application) - { + public function __construct( + private readonly Application $application, + ) { } public function __invoke(RunCommandMessage $message): RunCommandContext diff --git a/vendor/symfony/console/Output/AnsiColorMode.php b/vendor/symfony/console/Output/AnsiColorMode.php index 5f9f744..ca40ffb 100644 --- a/vendor/symfony/console/Output/AnsiColorMode.php +++ b/vendor/symfony/console/Output/AnsiColorMode.php @@ -63,7 +63,7 @@ public function convertFromHexToAnsiColorCode(string $hexColor): string return match ($this) { self::Ansi4 => (string) $this->convertFromRGB($r, $g, $b), self::Ansi8 => '8;5;'.((string) $this->convertFromRGB($r, $g, $b)), - self::Ansi24 => sprintf('8;2;%d;%d;%d', $r, $g, $b) + self::Ansi24 => sprintf('8;2;%d;%d;%d', $r, $g, $b), }; } @@ -72,7 +72,7 @@ private function convertFromRGB(int $r, int $g, int $b): int return match ($this) { self::Ansi4 => $this->degradeHexColorToAnsi4($r, $g, $b), self::Ansi8 => $this->degradeHexColorToAnsi8($r, $g, $b), - default => throw new InvalidArgumentException("RGB cannot be converted to {$this->name}.") + default => throw new InvalidArgumentException("RGB cannot be converted to {$this->name}."), }; } diff --git a/vendor/symfony/console/Output/BufferedOutput.php b/vendor/symfony/console/Output/BufferedOutput.php index ef5099b..3c8d390 100644 --- a/vendor/symfony/console/Output/BufferedOutput.php +++ b/vendor/symfony/console/Output/BufferedOutput.php @@ -29,10 +29,7 @@ public function fetch(): string return $content; } - /** - * @return void - */ - protected function doWrite(string $message, bool $newline) + protected function doWrite(string $message, bool $newline): void { $this->buffer .= $message; diff --git a/vendor/symfony/console/Output/ConsoleOutput.php b/vendor/symfony/console/Output/ConsoleOutput.php index 5837e74..2ad3dbc 100644 --- a/vendor/symfony/console/Output/ConsoleOutput.php +++ b/vendor/symfony/console/Output/ConsoleOutput.php @@ -64,28 +64,19 @@ public function section(): ConsoleSectionOutput return new ConsoleSectionOutput($this->getStream(), $this->consoleSectionOutputs, $this->getVerbosity(), $this->isDecorated(), $this->getFormatter()); } - /** - * @return void - */ - public function setDecorated(bool $decorated) + public function setDecorated(bool $decorated): void { parent::setDecorated($decorated); $this->stderr->setDecorated($decorated); } - /** - * @return void - */ - public function setFormatter(OutputFormatterInterface $formatter) + public function setFormatter(OutputFormatterInterface $formatter): void { parent::setFormatter($formatter); $this->stderr->setFormatter($formatter); } - /** - * @return void - */ - public function setVerbosity(int $level) + public function setVerbosity(int $level): void { parent::setVerbosity($level); $this->stderr->setVerbosity($level); @@ -96,10 +87,7 @@ public function getErrorOutput(): OutputInterface return $this->stderr; } - /** - * @return void - */ - public function setErrorOutput(OutputInterface $error) + public function setErrorOutput(OutputInterface $error): void { $this->stderr = $error; } diff --git a/vendor/symfony/console/Output/ConsoleOutputInterface.php b/vendor/symfony/console/Output/ConsoleOutputInterface.php index 9c0049c..1f8f147 100644 --- a/vendor/symfony/console/Output/ConsoleOutputInterface.php +++ b/vendor/symfony/console/Output/ConsoleOutputInterface.php @@ -24,10 +24,7 @@ interface ConsoleOutputInterface extends OutputInterface */ public function getErrorOutput(): OutputInterface; - /** - * @return void - */ - public function setErrorOutput(OutputInterface $error); + public function setErrorOutput(OutputInterface $error): void; public function section(): ConsoleSectionOutput; } diff --git a/vendor/symfony/console/Output/ConsoleSectionOutput.php b/vendor/symfony/console/Output/ConsoleSectionOutput.php index f2d7933..09aa7fe 100644 --- a/vendor/symfony/console/Output/ConsoleSectionOutput.php +++ b/vendor/symfony/console/Output/ConsoleSectionOutput.php @@ -60,12 +60,10 @@ public function setMaxHeight(int $maxHeight): void * Clears previous output for this section. * * @param int $lines Number of lines to clear. If null, then the entire output of this section is cleared - * - * @return void */ - public function clear(?int $lines = null) + public function clear(?int $lines = null): void { - if (empty($this->content) || !$this->isDecorated()) { + if (!$this->content || !$this->isDecorated()) { return; } @@ -83,10 +81,8 @@ public function clear(?int $lines = null) /** * Overwrites the previous output with a new message. - * - * @return void */ - public function overwrite(string|iterable $message) + public function overwrite(string|iterable $message): void { $this->clear(); $this->writeln($message); @@ -162,10 +158,7 @@ public function addNewLineOfInputSubmit(): void ++$this->lines; } - /** - * @return void - */ - protected function doWrite(string $message, bool $newline) + protected function doWrite(string $message, bool $newline): void { // Simulate newline behavior for consistent output formatting, avoiding extra logic if (!$newline && str_ends_with($message, \PHP_EOL)) { diff --git a/vendor/symfony/console/Output/NullOutput.php b/vendor/symfony/console/Output/NullOutput.php index f3aa15b..40ae332 100644 --- a/vendor/symfony/console/Output/NullOutput.php +++ b/vendor/symfony/console/Output/NullOutput.php @@ -26,10 +26,7 @@ class NullOutput implements OutputInterface { private NullOutputFormatter $formatter; - /** - * @return void - */ - public function setFormatter(OutputFormatterInterface $formatter) + public function setFormatter(OutputFormatterInterface $formatter): void { // do nothing } @@ -40,10 +37,7 @@ public function getFormatter(): OutputFormatterInterface return $this->formatter ??= new NullOutputFormatter(); } - /** - * @return void - */ - public function setDecorated(bool $decorated) + public function setDecorated(bool $decorated): void { // do nothing } @@ -53,10 +47,7 @@ public function isDecorated(): bool return false; } - /** - * @return void - */ - public function setVerbosity(int $level) + public function setVerbosity(int $level): void { // do nothing } @@ -86,18 +77,12 @@ public function isDebug(): bool return false; } - /** - * @return void - */ - public function writeln(string|iterable $messages, int $options = self::OUTPUT_NORMAL) + public function writeln(string|iterable $messages, int $options = self::OUTPUT_NORMAL): void { // do nothing } - /** - * @return void - */ - public function write(string|iterable $messages, bool $newline = false, int $options = self::OUTPUT_NORMAL) + public function write(string|iterable $messages, bool $newline = false, int $options = self::OUTPUT_NORMAL): void { // do nothing } diff --git a/vendor/symfony/console/Output/Output.php b/vendor/symfony/console/Output/Output.php index 00f481e..2bb1057 100644 --- a/vendor/symfony/console/Output/Output.php +++ b/vendor/symfony/console/Output/Output.php @@ -44,10 +44,7 @@ public function __construct(?int $verbosity = self::VERBOSITY_NORMAL, bool $deco $this->formatter->setDecorated($decorated); } - /** - * @return void - */ - public function setFormatter(OutputFormatterInterface $formatter) + public function setFormatter(OutputFormatterInterface $formatter): void { $this->formatter = $formatter; } @@ -57,10 +54,7 @@ public function getFormatter(): OutputFormatterInterface return $this->formatter; } - /** - * @return void - */ - public function setDecorated(bool $decorated) + public function setDecorated(bool $decorated): void { $this->formatter->setDecorated($decorated); } @@ -70,10 +64,7 @@ public function isDecorated(): bool return $this->formatter->isDecorated(); } - /** - * @return void - */ - public function setVerbosity(int $level) + public function setVerbosity(int $level): void { $this->verbosity = $level; } @@ -103,18 +94,12 @@ public function isDebug(): bool return self::VERBOSITY_DEBUG <= $this->verbosity; } - /** - * @return void - */ - public function writeln(string|iterable $messages, int $options = self::OUTPUT_NORMAL) + public function writeln(string|iterable $messages, int $options = self::OUTPUT_NORMAL): void { $this->write($messages, true, $options); } - /** - * @return void - */ - public function write(string|iterable $messages, bool $newline = false, int $options = self::OUTPUT_NORMAL) + public function write(string|iterable $messages, bool $newline = false, int $options = self::OUTPUT_NORMAL): void { if (!is_iterable($messages)) { $messages = [$messages]; @@ -148,8 +133,6 @@ public function write(string|iterable $messages, bool $newline = false, int $opt /** * Writes a message to the output. - * - * @return void */ - abstract protected function doWrite(string $message, bool $newline); + abstract protected function doWrite(string $message, bool $newline): void; } diff --git a/vendor/symfony/console/Output/OutputInterface.php b/vendor/symfony/console/Output/OutputInterface.php index 19a8179..41315fb 100644 --- a/vendor/symfony/console/Output/OutputInterface.php +++ b/vendor/symfony/console/Output/OutputInterface.php @@ -36,29 +36,23 @@ interface OutputInterface * @param bool $newline Whether to add a newline * @param int $options A bitmask of options (one of the OUTPUT or VERBOSITY constants), * 0 is considered the same as self::OUTPUT_NORMAL | self::VERBOSITY_NORMAL - * - * @return void */ - public function write(string|iterable $messages, bool $newline = false, int $options = 0); + public function write(string|iterable $messages, bool $newline = false, int $options = 0): void; /** * Writes a message to the output and adds a newline at the end. * * @param int $options A bitmask of options (one of the OUTPUT or VERBOSITY constants), * 0 is considered the same as self::OUTPUT_NORMAL | self::VERBOSITY_NORMAL - * - * @return void */ - public function writeln(string|iterable $messages, int $options = 0); + public function writeln(string|iterable $messages, int $options = 0): void; /** * Sets the verbosity of the output. * * @param self::VERBOSITY_* $level - * - * @return void */ - public function setVerbosity(int $level); + public function setVerbosity(int $level): void; /** * Gets the current verbosity of the output. @@ -89,20 +83,15 @@ public function isDebug(): bool; /** * Sets the decorated flag. - * - * @return void */ - public function setDecorated(bool $decorated); + public function setDecorated(bool $decorated): void; /** * Gets the decorated flag. */ public function isDecorated(): bool; - /** - * @return void - */ - public function setFormatter(OutputFormatterInterface $formatter); + public function setFormatter(OutputFormatterInterface $formatter): void; /** * Returns current output formatter instance. diff --git a/vendor/symfony/console/Output/StreamOutput.php b/vendor/symfony/console/Output/StreamOutput.php index 218bc9e..e94a5eb 100644 --- a/vendor/symfony/console/Output/StreamOutput.php +++ b/vendor/symfony/console/Output/StreamOutput.php @@ -63,10 +63,7 @@ public function getStream() return $this->stream; } - /** - * @return void - */ - protected function doWrite(string $message, bool $newline) + protected function doWrite(string $message, bool $newline): void { if ($newline) { $message .= \PHP_EOL; @@ -93,7 +90,7 @@ protected function doWrite(string $message, bool $newline) protected function hasColorSupport(): bool { // Follow https://no-color.org/ - if (isset($_SERVER['NO_COLOR']) || false !== getenv('NO_COLOR')) { + if ('' !== (($_SERVER['NO_COLOR'] ?? getenv('NO_COLOR'))[0] ?? '')) { return false; } diff --git a/vendor/symfony/console/Output/TrimmedBufferOutput.php b/vendor/symfony/console/Output/TrimmedBufferOutput.php index 23a2be8..c1862a2 100644 --- a/vendor/symfony/console/Output/TrimmedBufferOutput.php +++ b/vendor/symfony/console/Output/TrimmedBufferOutput.php @@ -45,10 +45,7 @@ public function fetch(): string return $content; } - /** - * @return void - */ - protected function doWrite(string $message, bool $newline) + protected function doWrite(string $message, bool $newline): void { $this->buffer .= $message; diff --git a/vendor/symfony/console/Question/ChoiceQuestion.php b/vendor/symfony/console/Question/ChoiceQuestion.php index e449ff6..d062ce7 100644 --- a/vendor/symfony/console/Question/ChoiceQuestion.php +++ b/vendor/symfony/console/Question/ChoiceQuestion.php @@ -20,25 +20,26 @@ */ class ChoiceQuestion extends Question { - private array $choices; private bool $multiselect = false; private string $prompt = ' > '; private string $errorMessage = 'Value "%s" is invalid'; /** - * @param string $question The question to ask to the user - * @param array $choices The list of available choices - * @param mixed $default The default answer to return + * @param string $question The question to ask to the user + * @param array $choices The list of available choices + * @param string|bool|int|float|null $default The default answer to return */ - public function __construct(string $question, array $choices, mixed $default = null) - { + public function __construct( + string $question, + private array $choices, + string|bool|int|float|null $default = null, + ) { if (!$choices) { throw new \LogicException('Choice question must have at least 1 choice available.'); } parent::__construct($question, $default); - $this->choices = $choices; $this->setValidator($this->getDefaultValidator()); $this->setAutocompleterValues($choices); } diff --git a/vendor/symfony/console/Question/ConfirmationQuestion.php b/vendor/symfony/console/Question/ConfirmationQuestion.php index 40eab24..951d681 100644 --- a/vendor/symfony/console/Question/ConfirmationQuestion.php +++ b/vendor/symfony/console/Question/ConfirmationQuestion.php @@ -18,18 +18,18 @@ */ class ConfirmationQuestion extends Question { - private string $trueAnswerRegex; - /** * @param string $question The question to ask to the user * @param bool $default The default answer to return, true or false * @param string $trueAnswerRegex A regex to match the "yes" answer */ - public function __construct(string $question, bool $default = true, string $trueAnswerRegex = '/^y/i') - { + public function __construct( + string $question, + bool $default = true, + private string $trueAnswerRegex = '/^y/i', + ) { parent::__construct($question, $default); - $this->trueAnswerRegex = $trueAnswerRegex; $this->setNormalizer($this->getDefaultNormalizer()); } diff --git a/vendor/symfony/console/Question/Question.php b/vendor/symfony/console/Question/Question.php index 94c688f..46a60c7 100644 --- a/vendor/symfony/console/Question/Question.php +++ b/vendor/symfony/console/Question/Question.php @@ -21,13 +21,11 @@ */ class Question { - private string $question; private ?int $attempts = null; private bool $hidden = false; private bool $hiddenFallback = true; private ?\Closure $autocompleterCallback = null; private ?\Closure $validator = null; - private string|int|bool|null|float $default; private ?\Closure $normalizer = null; private bool $trimmable = true; private bool $multiline = false; @@ -36,10 +34,10 @@ class Question * @param string $question The question to ask to the user * @param string|bool|int|float|null $default The default answer to return if the user enters nothing */ - public function __construct(string $question, string|bool|int|float|null $default = null) - { - $this->question = $question; - $this->default = $default; + public function __construct( + private string $question, + private string|bool|int|float|null $default = null, + ) { } /** @@ -175,11 +173,8 @@ public function getAutocompleterCallback(): ?callable * * @return $this */ - public function setAutocompleterCallback(?callable $callback = null): static + public function setAutocompleterCallback(?callable $callback): static { - if (1 > \func_num_args()) { - trigger_deprecation('symfony/console', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); - } if ($this->hidden && null !== $callback) { throw new LogicException('A hidden question cannot use the autocompleter.'); } @@ -194,11 +189,8 @@ public function setAutocompleterCallback(?callable $callback = null): static * * @return $this */ - public function setValidator(?callable $validator = null): static + public function setValidator(?callable $validator): static { - if (1 > \func_num_args()) { - trigger_deprecation('symfony/console', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); - } $this->validator = null === $validator ? null : $validator(...); return $this; @@ -266,10 +258,7 @@ public function getNormalizer(): ?callable return $this->normalizer; } - /** - * @return bool - */ - protected function isAssoc(array $array) + protected function isAssoc(array $array): bool { return (bool) \count(array_filter(array_keys($array), 'is_string')); } diff --git a/vendor/symfony/console/README.md b/vendor/symfony/console/README.md index e901318..92f70e7 100644 --- a/vendor/symfony/console/README.md +++ b/vendor/symfony/console/README.md @@ -7,14 +7,7 @@ interfaces. Sponsor ------- -The Console component for Symfony 6.4 is [backed][1] by [Les-Tilleuls.coop][2]. - -Les-Tilleuls.coop is a team of 70+ Symfony experts who can help you design, develop and -fix your projects. They provide a wide range of professional services including development, -consulting, coaching, training and audits. They also are highly skilled in JS, Go and DevOps. -They are a worker cooperative! - -Help Symfony by [sponsoring][3] its development! +Help Symfony by [sponsoring][1] its development! Resources --------- @@ -31,6 +24,4 @@ Credits `Resources/bin/hiddeninput.exe` is a third party binary provided within this component. Find sources and license at https://github.com/Seldaek/hidden-input. -[1]: https://symfony.com/backers -[2]: https://les-tilleuls.coop -[3]: https://symfony.com/sponsor +[1]: https://symfony.com/sponsor diff --git a/vendor/symfony/console/Resources/completion.bash b/vendor/symfony/console/Resources/completion.bash index 0d76eac..64c6a33 100644 --- a/vendor/symfony/console/Resources/completion.bash +++ b/vendor/symfony/console/Resources/completion.bash @@ -17,7 +17,7 @@ _sf_{{ COMMAND_NAME }}() { done # Use newline as only separator to allow space in completion values - IFS=$'\n' + local IFS=$'\n' local sf_cmd="${COMP_WORDS[0]}" # for an alias, get the real script behind it diff --git a/vendor/symfony/console/Resources/completion.fish b/vendor/symfony/console/Resources/completion.fish index 1c34292..1853dd8 100644 --- a/vendor/symfony/console/Resources/completion.fish +++ b/vendor/symfony/console/Resources/completion.fish @@ -19,11 +19,7 @@ function _sf_{{ COMMAND_NAME }} set completecmd $completecmd "-c$c" - set sfcomplete ($completecmd) - - for i in $sfcomplete - echo $i - end + $completecmd end complete -c '{{ COMMAND_NAME }}' -a '(_sf_{{ COMMAND_NAME }})' -f diff --git a/vendor/symfony/console/Style/OutputStyle.php b/vendor/symfony/console/Style/OutputStyle.php index ddfa8de..9f62ea3 100644 --- a/vendor/symfony/console/Style/OutputStyle.php +++ b/vendor/symfony/console/Style/OutputStyle.php @@ -23,17 +23,12 @@ */ abstract class OutputStyle implements OutputInterface, StyleInterface { - private OutputInterface $output; - - public function __construct(OutputInterface $output) - { - $this->output = $output; + public function __construct( + private OutputInterface $output, + ) { } - /** - * @return void - */ - public function newLine(int $count = 1) + public function newLine(int $count = 1): void { $this->output->write(str_repeat(\PHP_EOL, $count)); } @@ -43,26 +38,17 @@ public function createProgressBar(int $max = 0): ProgressBar return new ProgressBar($this->output, $max); } - /** - * @return void - */ - public function write(string|iterable $messages, bool $newline = false, int $type = self::OUTPUT_NORMAL) + public function write(string|iterable $messages, bool $newline = false, int $type = self::OUTPUT_NORMAL): void { $this->output->write($messages, $newline, $type); } - /** - * @return void - */ - public function writeln(string|iterable $messages, int $type = self::OUTPUT_NORMAL) + public function writeln(string|iterable $messages, int $type = self::OUTPUT_NORMAL): void { $this->output->writeln($messages, $type); } - /** - * @return void - */ - public function setVerbosity(int $level) + public function setVerbosity(int $level): void { $this->output->setVerbosity($level); } @@ -72,10 +58,7 @@ public function getVerbosity(): int return $this->output->getVerbosity(); } - /** - * @return void - */ - public function setDecorated(bool $decorated) + public function setDecorated(bool $decorated): void { $this->output->setDecorated($decorated); } @@ -85,10 +68,7 @@ public function isDecorated(): bool return $this->output->isDecorated(); } - /** - * @return void - */ - public function setFormatter(OutputFormatterInterface $formatter) + public function setFormatter(OutputFormatterInterface $formatter): void { $this->output->setFormatter($formatter); } @@ -118,10 +98,7 @@ public function isDebug(): bool return $this->output->isDebug(); } - /** - * @return OutputInterface - */ - protected function getErrorOutput() + protected function getErrorOutput(): OutputInterface { if (!$this->output instanceof ConsoleOutputInterface) { return $this->output; diff --git a/vendor/symfony/console/Style/StyleInterface.php b/vendor/symfony/console/Style/StyleInterface.php index 6bced15..fcc5bc7 100644 --- a/vendor/symfony/console/Style/StyleInterface.php +++ b/vendor/symfony/console/Style/StyleInterface.php @@ -20,73 +20,53 @@ interface StyleInterface { /** * Formats a command title. - * - * @return void */ - public function title(string $message); + public function title(string $message): void; /** * Formats a section title. - * - * @return void */ - public function section(string $message); + public function section(string $message): void; /** * Formats a list. - * - * @return void */ - public function listing(array $elements); + public function listing(array $elements): void; /** * Formats informational text. - * - * @return void */ - public function text(string|array $message); + public function text(string|array $message): void; /** * Formats a success result bar. - * - * @return void */ - public function success(string|array $message); + public function success(string|array $message): void; /** * Formats an error result bar. - * - * @return void */ - public function error(string|array $message); + public function error(string|array $message): void; /** * Formats an warning result bar. - * - * @return void */ - public function warning(string|array $message); + public function warning(string|array $message): void; /** * Formats a note admonition. - * - * @return void */ - public function note(string|array $message); + public function note(string|array $message): void; /** * Formats a caution admonition. - * - * @return void */ - public function caution(string|array $message); + public function caution(string|array $message): void; /** * Formats a table. - * - * @return void */ - public function table(array $headers, array $rows); + public function table(array $headers, array $rows): void; /** * Asks a question. @@ -110,29 +90,21 @@ public function choice(string $question, array $choices, mixed $default = null): /** * Add newline(s). - * - * @return void */ - public function newLine(int $count = 1); + public function newLine(int $count = 1): void; /** * Starts the progress output. - * - * @return void */ - public function progressStart(int $max = 0); + public function progressStart(int $max = 0): void; /** * Advances the progress output X steps. - * - * @return void */ - public function progressAdvance(int $step = 1); + public function progressAdvance(int $step = 1): void; /** * Finishes the progress output. - * - * @return void */ - public function progressFinish(); + public function progressFinish(): void; } diff --git a/vendor/symfony/console/Style/SymfonyStyle.php b/vendor/symfony/console/Style/SymfonyStyle.php index 03bda87..19ad892 100644 --- a/vendor/symfony/console/Style/SymfonyStyle.php +++ b/vendor/symfony/console/Style/SymfonyStyle.php @@ -40,30 +40,27 @@ class SymfonyStyle extends OutputStyle { public const MAX_LINE_LENGTH = 120; - private InputInterface $input; - private OutputInterface $output; private SymfonyQuestionHelper $questionHelper; private ProgressBar $progressBar; private int $lineLength; private TrimmedBufferOutput $bufferedOutput; - public function __construct(InputInterface $input, OutputInterface $output) - { - $this->input = $input; + public function __construct( + private InputInterface $input, + private OutputInterface $output, + ) { $this->bufferedOutput = new TrimmedBufferOutput(\DIRECTORY_SEPARATOR === '\\' ? 4 : 2, $output->getVerbosity(), false, clone $output->getFormatter()); // Windows cmd wraps lines as soon as the terminal width is reached, whether there are following chars or not. $width = (new Terminal())->getWidth() ?: self::MAX_LINE_LENGTH; $this->lineLength = min($width - (int) (\DIRECTORY_SEPARATOR === '\\'), self::MAX_LINE_LENGTH); - parent::__construct($this->output = $output); + parent::__construct($output); } /** * Formats a message as a block of text. - * - * @return void */ - public function block(string|array $messages, ?string $type = null, ?string $style = null, string $prefix = ' ', bool $padding = false, bool $escape = true) + public function block(string|array $messages, ?string $type = null, ?string $style = null, string $prefix = ' ', bool $padding = false, bool $escape = true): void { $messages = \is_array($messages) ? array_values($messages) : [$messages]; @@ -72,10 +69,7 @@ public function block(string|array $messages, ?string $type = null, ?string $sty $this->newLine(); } - /** - * @return void - */ - public function title(string $message) + public function title(string $message): void { $this->autoPrependBlock(); $this->writeln([ @@ -85,10 +79,7 @@ public function title(string $message) $this->newLine(); } - /** - * @return void - */ - public function section(string $message) + public function section(string $message): void { $this->autoPrependBlock(); $this->writeln([ @@ -98,10 +89,7 @@ public function section(string $message) $this->newLine(); } - /** - * @return void - */ - public function listing(array $elements) + public function listing(array $elements): void { $this->autoPrependText(); $elements = array_map(fn ($element) => sprintf(' * %s', $element), $elements); @@ -110,10 +98,7 @@ public function listing(array $elements) $this->newLine(); } - /** - * @return void - */ - public function text(string|array $message) + public function text(string|array $message): void { $this->autoPrependText(); @@ -125,68 +110,46 @@ public function text(string|array $message) /** * Formats a command comment. - * - * @return void */ - public function comment(string|array $message) + public function comment(string|array $message): void { $this->block($message, null, null, ' // ', false, false); } - /** - * @return void - */ - public function success(string|array $message) + public function success(string|array $message): void { $this->block($message, 'OK', 'fg=black;bg=green', ' ', true); } - /** - * @return void - */ - public function error(string|array $message) + public function error(string|array $message): void { $this->block($message, 'ERROR', 'fg=white;bg=red', ' ', true); } - /** - * @return void - */ - public function warning(string|array $message) + public function warning(string|array $message): void { $this->block($message, 'WARNING', 'fg=black;bg=yellow', ' ', true); } - /** - * @return void - */ - public function note(string|array $message) + public function note(string|array $message): void { $this->block($message, 'NOTE', 'fg=yellow', ' ! '); } /** * Formats an info message. - * - * @return void */ - public function info(string|array $message) + public function info(string|array $message): void { $this->block($message, 'INFO', 'fg=green', ' ', true); } - /** - * @return void - */ - public function caution(string|array $message) + public function caution(string|array $message): void { $this->block($message, 'CAUTION', 'fg=white;bg=red', ' ! ', true); } - /** - * @return void - */ - public function table(array $headers, array $rows) + public function table(array $headers, array $rows): void { $this->createTable() ->setHeaders($headers) @@ -199,10 +162,8 @@ public function table(array $headers, array $rows) /** * Formats a horizontal table. - * - * @return void */ - public function horizontalTable(array $headers, array $rows) + public function horizontalTable(array $headers, array $rows): void { $this->createTable() ->setHorizontal(true) @@ -221,10 +182,8 @@ public function horizontalTable(array $headers, array $rows) * * 'A title' * * ['key' => 'value'] * * new TableSeparator() - * - * @return void */ - public function definitionList(string|array|TableSeparator ...$list) + public function definitionList(string|array|TableSeparator ...$list): void { $headers = []; $row = []; @@ -285,27 +244,18 @@ public function choice(string $question, array $choices, mixed $default = null, return $this->askQuestion($questionChoice); } - /** - * @return void - */ - public function progressStart(int $max = 0) + public function progressStart(int $max = 0): void { $this->progressBar = $this->createProgressBar($max); $this->progressBar->start(); } - /** - * @return void - */ - public function progressAdvance(int $step = 1) + public function progressAdvance(int $step = 1): void { $this->getProgressBar()->advance($step); } - /** - * @return void - */ - public function progressFinish() + public function progressFinish(): void { $this->getProgressBar()->finish(); $this->newLine(2); @@ -366,10 +316,7 @@ public function askQuestion(Question $question): mixed return $answer; } - /** - * @return void - */ - public function writeln(string|iterable $messages, int $type = self::OUTPUT_NORMAL) + public function writeln(string|iterable $messages, int $type = self::OUTPUT_NORMAL): void { if (!is_iterable($messages)) { $messages = [$messages]; @@ -381,10 +328,7 @@ public function writeln(string|iterable $messages, int $type = self::OUTPUT_NORM } } - /** - * @return void - */ - public function write(string|iterable $messages, bool $newline = false, int $type = self::OUTPUT_NORMAL) + public function write(string|iterable $messages, bool $newline = false, int $type = self::OUTPUT_NORMAL): void { if (!is_iterable($messages)) { $messages = [$messages]; @@ -396,10 +340,7 @@ public function write(string|iterable $messages, bool $newline = false, int $typ } } - /** - * @return void - */ - public function newLine(int $count = 1) + public function newLine(int $count = 1): void { parent::newLine($count); $this->bufferedOutput->write(str_repeat("\n", $count)); diff --git a/vendor/symfony/console/Terminal.php b/vendor/symfony/console/Terminal.php index 3eda037..0972adc 100644 --- a/vendor/symfony/console/Terminal.php +++ b/vendor/symfony/console/Terminal.php @@ -140,7 +140,7 @@ private static function initDimensions(): void // or [w, h] from "wxh" self::$width = (int) $matches[1]; self::$height = isset($matches[4]) ? (int) $matches[4] : (int) $matches[2]; - } elseif (!self::hasVt100Support() && self::hasSttyAvailable()) { + } elseif (!sapi_windows_vt100_support(fopen('php://stdout', 'w')) && self::hasSttyAvailable()) { // only use stty on Windows if the terminal does not support vt100 (e.g. Windows 7 + git-bash) // testing for stty in a Windows 10 vt100-enabled console will implicitly disable vt100 support on STDOUT self::initDimensionsUsingStty(); @@ -154,14 +154,6 @@ private static function initDimensions(): void } } - /** - * Returns whether STDOUT has vt100 support (some Windows 10+ configurations). - */ - private static function hasVt100Support(): bool - { - return \function_exists('sapi_windows_vt100_support') && sapi_windows_vt100_support(fopen('php://stdout', 'w')); - } - /** * Initializes dimensions using the output of an stty columns line. */ @@ -217,8 +209,7 @@ private static function readFromProcess(string|array $command): ?string $cp = \function_exists('sapi_windows_cp_set') ? sapi_windows_cp_get() : 0; - $process = proc_open($command, $descriptorspec, $pipes, null, null, ['suppress_errors' => true]); - if (!\is_resource($process)) { + if (!$process = proc_open($command, $descriptorspec, $pipes, null, null, ['suppress_errors' => true])) { return null; } diff --git a/vendor/symfony/console/Tester/ApplicationTester.php b/vendor/symfony/console/Tester/ApplicationTester.php index 58aee54..cebb6f8 100644 --- a/vendor/symfony/console/Tester/ApplicationTester.php +++ b/vendor/symfony/console/Tester/ApplicationTester.php @@ -28,11 +28,9 @@ class ApplicationTester { use TesterTrait; - private Application $application; - - public function __construct(Application $application) - { - $this->application = $application; + public function __construct( + private Application $application, + ) { } /** diff --git a/vendor/symfony/console/Tester/CommandCompletionTester.php b/vendor/symfony/console/Tester/CommandCompletionTester.php index a90fe52..76cbaf1 100644 --- a/vendor/symfony/console/Tester/CommandCompletionTester.php +++ b/vendor/symfony/console/Tester/CommandCompletionTester.php @@ -22,11 +22,9 @@ */ class CommandCompletionTester { - private Command $command; - - public function __construct(Command $command) - { - $this->command = $command; + public function __construct( + private Command $command, + ) { } /** diff --git a/vendor/symfony/console/Tester/CommandTester.php b/vendor/symfony/console/Tester/CommandTester.php index 2ff813b..d39cde7 100644 --- a/vendor/symfony/console/Tester/CommandTester.php +++ b/vendor/symfony/console/Tester/CommandTester.php @@ -24,11 +24,9 @@ class CommandTester { use TesterTrait; - private Command $command; - - public function __construct(Command $command) - { - $this->command = $command; + public function __construct( + private Command $command, + ) { } /** diff --git a/vendor/symfony/console/composer.json b/vendor/symfony/console/composer.json index 1610f73..0ed1bd9 100644 --- a/vendor/symfony/console/composer.json +++ b/vendor/symfony/console/composer.json @@ -16,34 +16,33 @@ } ], "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", + "php": ">=8.2", "symfony/polyfill-mbstring": "~1.0", "symfony/service-contracts": "^2.5|^3", - "symfony/string": "^5.4|^6.0|^7.0" + "symfony/string": "^6.4|^7.0" }, "require-dev": { - "symfony/config": "^5.4|^6.0|^7.0", - "symfony/event-dispatcher": "^5.4|^6.0|^7.0", - "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", "symfony/http-foundation": "^6.4|^7.0", "symfony/http-kernel": "^6.4|^7.0", - "symfony/lock": "^5.4|^6.0|^7.0", - "symfony/messenger": "^5.4|^6.0|^7.0", - "symfony/process": "^5.4|^6.0|^7.0", - "symfony/stopwatch": "^5.4|^6.0|^7.0", - "symfony/var-dumper": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/lock": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0", "psr/log": "^1|^2|^3" }, "provide": { "psr/log-implementation": "1.0|2.0|3.0" }, "conflict": { - "symfony/dependency-injection": "<5.4", - "symfony/dotenv": "<5.4", - "symfony/event-dispatcher": "<5.4", - "symfony/lock": "<5.4", - "symfony/process": "<5.4" + "symfony/dependency-injection": "<6.4", + "symfony/dotenv": "<6.4", + "symfony/event-dispatcher": "<6.4", + "symfony/lock": "<6.4", + "symfony/process": "<6.4" }, "autoload": { "psr-4": { "Symfony\\Component\\Console\\": "" }, diff --git a/vendor/symfony/deprecation-contracts/composer.json b/vendor/symfony/deprecation-contracts/composer.json index c6d02d8..ceb6c07 100644 --- a/vendor/symfony/deprecation-contracts/composer.json +++ b/vendor/symfony/deprecation-contracts/composer.json @@ -25,7 +25,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", diff --git a/vendor/symfony/filesystem/CHANGELOG.md b/vendor/symfony/filesystem/CHANGELOG.md index fcb7170..80818d1 100644 --- a/vendor/symfony/filesystem/CHANGELOG.md +++ b/vendor/symfony/filesystem/CHANGELOG.md @@ -1,6 +1,16 @@ CHANGELOG ========= +7.1 +--- + + * Add the `Filesystem::readFile()` method + +7.0 +--- + + * Add argument `$lock` to `Filesystem::appendToFile()` + 5.4 --- diff --git a/vendor/symfony/filesystem/Exception/IOException.php b/vendor/symfony/filesystem/Exception/IOException.php index df3a085..46ab8b4 100644 --- a/vendor/symfony/filesystem/Exception/IOException.php +++ b/vendor/symfony/filesystem/Exception/IOException.php @@ -20,12 +20,12 @@ */ class IOException extends \RuntimeException implements IOExceptionInterface { - private ?string $path; - - public function __construct(string $message, int $code = 0, ?\Throwable $previous = null, ?string $path = null) - { - $this->path = $path; - + public function __construct( + string $message, + int $code = 0, + ?\Throwable $previous = null, + private ?string $path = null, + ) { parent::__construct($message, $code, $previous); } diff --git a/vendor/symfony/filesystem/Filesystem.php b/vendor/symfony/filesystem/Filesystem.php index 0a25f88..11f03ed 100644 --- a/vendor/symfony/filesystem/Filesystem.php +++ b/vendor/symfony/filesystem/Filesystem.php @@ -31,12 +31,10 @@ class Filesystem * If the target file is newer, it is overwritten only when the * $overwriteNewerFiles option is set to true. * - * @return void - * * @throws FileNotFoundException When originFile doesn't exist * @throws IOException When copy fails */ - public function copy(string $originFile, string $targetFile, bool $overwriteNewerFiles = false) + public function copy(string $originFile, string $targetFile, bool $overwriteNewerFiles = false): void { $originIsLocal = stream_is_local($originFile) || 0 === stripos($originFile, 'file://'); if ($originIsLocal && !is_file($originFile)) { @@ -74,6 +72,9 @@ public function copy(string $originFile, string $targetFile, bool $overwriteNewe // Like `cp`, preserve executable permission bits self::box('chmod', $targetFile, fileperms($targetFile) | (fileperms($originFile) & 0111)); + // Like `cp`, preserve the file modification time + self::box('touch', $targetFile, filemtime($originFile)); + if ($bytesCopied !== $bytesOrigin = filesize($originFile)) { throw new IOException(sprintf('Failed to copy the whole content of "%s" to "%s" (%g of %g bytes copied).', $originFile, $targetFile, $bytesCopied, $bytesOrigin), 0, null, $originFile); } @@ -84,11 +85,9 @@ public function copy(string $originFile, string $targetFile, bool $overwriteNewe /** * Creates a directory recursively. * - * @return void - * * @throws IOException On any directory creation failure */ - public function mkdir(string|iterable $dirs, int $mode = 0777) + public function mkdir(string|iterable $dirs, int $mode = 0777): void { foreach ($this->toIterable($dirs) as $dir) { if (is_dir($dir)) { @@ -127,11 +126,9 @@ public function exists(string|iterable $files): bool * @param int|null $time The touch time as a Unix timestamp, if not supplied the current system time is used * @param int|null $atime The access time as a Unix timestamp, if not supplied the current system time is used * - * @return void - * * @throws IOException When touch fails */ - public function touch(string|iterable $files, ?int $time = null, ?int $atime = null) + public function touch(string|iterable $files, ?int $time = null, ?int $atime = null): void { foreach ($this->toIterable($files) as $file) { if (!($time ? self::box('touch', $file, $time, $atime) : self::box('touch', $file))) { @@ -143,11 +140,9 @@ public function touch(string|iterable $files, ?int $time = null, ?int $atime = n /** * Removes files or directories. * - * @return void - * * @throws IOException When removal fails */ - public function remove(string|iterable $files) + public function remove(string|iterable $files): void { if ($files instanceof \Traversable) { $files = iterator_to_array($files, false); @@ -169,7 +164,7 @@ private static function doRemove(array $files, bool $isRecursive): void } } elseif (is_dir($file)) { if (!$isRecursive) { - $tmpName = \dirname(realpath($file)).'/.'.strrev(strtr(base64_encode(random_bytes(2)), '/=', '-_')); + $tmpName = \dirname(realpath($file)).'/.!'.strrev(strtr(base64_encode(random_bytes(2)), '/=', '-!')); if (file_exists($tmpName)) { try { @@ -198,7 +193,7 @@ private static function doRemove(array $files, bool $isRecursive): void throw new IOException(sprintf('Failed to remove directory "%s": ', $file).$lastError); } - } elseif (!self::box('unlink', $file) && (str_contains(self::$lastError, 'Permission denied') || file_exists($file))) { + } elseif (!self::box('unlink', $file) && ((self::$lastError && str_contains(self::$lastError, 'Permission denied')) || file_exists($file))) { throw new IOException(sprintf('Failed to remove file "%s": ', $file).self::$lastError); } } @@ -211,11 +206,9 @@ private static function doRemove(array $files, bool $isRecursive): void * @param int $umask The mode mask (octal) * @param bool $recursive Whether change the mod recursively or not * - * @return void - * * @throws IOException When the change fails */ - public function chmod(string|iterable $files, int $mode, int $umask = 0000, bool $recursive = false) + public function chmod(string|iterable $files, int $mode, int $umask = 0000, bool $recursive = false): void { foreach ($this->toIterable($files) as $file) { if (!self::box('chmod', $file, $mode & ~$umask)) { @@ -230,14 +223,15 @@ public function chmod(string|iterable $files, int $mode, int $umask = 0000, bool /** * Change the owner of an array of files or directories. * + * This method always throws on Windows, as the underlying PHP function is not supported. + * @see https://www.php.net/chown + * * @param string|int $user A user name or number * @param bool $recursive Whether change the owner recursively or not * - * @return void - * * @throws IOException When the change fails */ - public function chown(string|iterable $files, string|int $user, bool $recursive = false) + public function chown(string|iterable $files, string|int $user, bool $recursive = false): void { foreach ($this->toIterable($files) as $file) { if ($recursive && is_dir($file) && !is_link($file)) { @@ -258,14 +252,15 @@ public function chown(string|iterable $files, string|int $user, bool $recursive /** * Change the group of an array of files or directories. * + * This method always throws on Windows, as the underlying PHP function is not supported. + * @see https://www.php.net/chgrp + * * @param string|int $group A group name or number * @param bool $recursive Whether change the group recursively or not * - * @return void - * * @throws IOException When the change fails */ - public function chgrp(string|iterable $files, string|int $group, bool $recursive = false) + public function chgrp(string|iterable $files, string|int $group, bool $recursive = false): void { foreach ($this->toIterable($files) as $file) { if ($recursive && is_dir($file) && !is_link($file)) { @@ -286,12 +281,10 @@ public function chgrp(string|iterable $files, string|int $group, bool $recursive /** * Renames a file or a directory. * - * @return void - * * @throws IOException When target file or directory already exists * @throws IOException When origin cannot be renamed */ - public function rename(string $origin, string $target, bool $overwrite = false) + public function rename(string $origin, string $target, bool $overwrite = false): void { // we check that target does not exist if (!$overwrite && $this->isReadable($target)) { @@ -329,11 +322,9 @@ private function isReadable(string $filename): bool /** * Creates a symbolic link or copy a directory. * - * @return void - * * @throws IOException When symlink fails */ - public function symlink(string $originDir, string $targetDir, bool $copyOnWindows = false) + public function symlink(string $originDir, string $targetDir, bool $copyOnWindows = false): void { self::assertFunctionExists('symlink'); @@ -367,12 +358,10 @@ public function symlink(string $originDir, string $targetDir, bool $copyOnWindow * * @param string|string[] $targetFiles The target file(s) * - * @return void - * * @throws FileNotFoundException When original file is missing or not a file * @throws IOException When link fails, including if link already exists */ - public function hardlink(string $originFile, string|iterable $targetFiles) + public function hardlink(string $originFile, string|iterable $targetFiles): void { self::assertFunctionExists('link'); @@ -526,11 +515,9 @@ public function makePathRelative(string $endPath, string $startPath): string * - $options['copy_on_windows'] Whether to copy files instead of links on Windows (see symlink(), defaults to false) * - $options['delete'] Whether to delete files that are not in the source directory (defaults to false) * - * @return void - * * @throws IOException When file type is unknown */ - public function mirror(string $originDir, string $targetDir, ?\Traversable $iterator = null, array $options = []) + public function mirror(string $originDir, string $targetDir, ?\Traversable $iterator = null, array $options = []): void { $targetDir = rtrim($targetDir, '/\\'); $originDir = rtrim($originDir, '/\\'); @@ -652,11 +639,9 @@ public function tempnam(string $dir, string $prefix, string $suffix = ''): strin * * @param string|resource $content The data to write into the file * - * @return void - * * @throws IOException if the file cannot be written to */ - public function dumpFile(string $filename, $content) + public function dumpFile(string $filename, $content): void { if (\is_array($content)) { throw new \TypeError(sprintf('Argument 2 passed to "%s()" must be string or resource, array given.', __METHOD__)); @@ -683,11 +668,15 @@ public function dumpFile(string $filename, $content) throw new IOException(sprintf('Failed to write file "%s": ', $filename).self::$lastError, 0, null, $filename); } - self::box('chmod', $tmpFile, file_exists($filename) ? fileperms($filename) : 0666 & ~umask()); + self::box('chmod', $tmpFile, self::box('fileperms', $filename) ?: 0666 & ~umask()); $this->rename($tmpFile, $filename, true); } finally { if (file_exists($tmpFile)) { + if ('\\' === \DIRECTORY_SEPARATOR && !is_writable($tmpFile)) { + self::box('chmod', $tmpFile, self::box('fileperms', $tmpFile) | 0200); + } + self::box('unlink', $tmpFile); } } @@ -699,11 +688,9 @@ public function dumpFile(string $filename, $content) * @param string|resource $content The content to append * @param bool $lock Whether the file should be locked when writing to it * - * @return void - * * @throws IOException If the file is not writable */ - public function appendToFile(string $filename, $content/* , bool $lock = false */) + public function appendToFile(string $filename, $content, bool $lock = false): void { if (\is_array($content)) { throw new \TypeError(sprintf('Argument 2 passed to "%s()" must be string or resource, array given.', __METHOD__)); @@ -715,13 +702,30 @@ public function appendToFile(string $filename, $content/* , bool $lock = false * $this->mkdir($dir); } - $lock = \func_num_args() > 2 && func_get_arg(2); - if (false === self::box('file_put_contents', $filename, $content, \FILE_APPEND | ($lock ? \LOCK_EX : 0))) { throw new IOException(sprintf('Failed to write file "%s": ', $filename).self::$lastError, 0, null, $filename); } } + /** + * Returns the content of a file as a string. + * + * @throws IOException If the file cannot be read + */ + public function readFile(string $filename): string + { + if (is_dir($filename)) { + throw new IOException(sprintf('Failed to read file "%s": File is a directory.', $filename)); + } + + $content = self::box('file_get_contents', $filename); + if (false === $content) { + throw new IOException(sprintf('Failed to read file "%s": ', $filename).self::$lastError, 0, null, $filename); + } + + return $content; + } + private function toIterable(string|iterable $files): iterable { return is_iterable($files) ? $files : [$files]; diff --git a/vendor/symfony/filesystem/Path.php b/vendor/symfony/filesystem/Path.php index 01b5617..db9ce4b 100644 --- a/vendor/symfony/filesystem/Path.php +++ b/vendor/symfony/filesystem/Path.php @@ -346,13 +346,13 @@ public static function changeExtension(string $path, string $extension): string $extension = ltrim($extension, '.'); // No extension for paths - if ('/' === substr($path, -1)) { + if (str_ends_with($path, '/')) { return $path; } // No actual extension in path - if (empty($actualExtension)) { - return $path.('.' === substr($path, -1) ? '' : '.').$extension; + if (!$actualExtension) { + return $path.(str_ends_with($path, '.') ? '' : '.').$extension; } return substr($path, 0, -\strlen($actualExtension)).$extension; @@ -365,7 +365,7 @@ public static function isAbsolute(string $path): bool } // Strip scheme - if (false !== $schemeSeparatorPosition = strpos($path, '://')) { + if (false !== ($schemeSeparatorPosition = strpos($path, '://')) && 1 !== $schemeSeparatorPosition) { $path = substr($path, $schemeSeparatorPosition + 3); } @@ -668,7 +668,7 @@ public static function join(string ...$paths): string } // Only add slash if previous part didn't end with '/' or '\' - if (!\in_array(substr($finalPath, -1), ['/', '\\'])) { + if (!\in_array(substr($finalPath, -1), ['/', '\\'], true)) { $finalPath .= '/'; } diff --git a/vendor/symfony/filesystem/composer.json b/vendor/symfony/filesystem/composer.json index 10a7a53..c781e55 100644 --- a/vendor/symfony/filesystem/composer.json +++ b/vendor/symfony/filesystem/composer.json @@ -16,10 +16,13 @@ } ], "require": { - "php": ">=8.1", + "php": ">=8.2", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.8" }, + "require-dev": { + "symfony/process": "^6.4|^7.0" + }, "autoload": { "psr-4": { "Symfony\\Component\\Filesystem\\": "" }, "exclude-from-classmap": [ diff --git a/vendor/symfony/finder/Comparator/Comparator.php b/vendor/symfony/finder/Comparator/Comparator.php index bd68583..c3d40e7 100644 --- a/vendor/symfony/finder/Comparator/Comparator.php +++ b/vendor/symfony/finder/Comparator/Comparator.php @@ -16,16 +16,16 @@ */ class Comparator { - private string $target; private string $operator; - public function __construct(string $target, string $operator = '==') - { + public function __construct( + private string $target, + string $operator = '==', + ) { if (!\in_array($operator, ['>', '<', '>=', '<=', '==', '!='])) { throw new \InvalidArgumentException(sprintf('Invalid operator "%s".', $operator)); } - $this->target = $target; $this->operator = $operator; } diff --git a/vendor/symfony/finder/Finder.php b/vendor/symfony/finder/Finder.php index 0fd283c..0894dcd 100644 --- a/vendor/symfony/finder/Finder.php +++ b/vendor/symfony/finder/Finder.php @@ -124,7 +124,7 @@ public function files(): static public function depth(string|int|array $levels): static { foreach ((array) $levels as $level) { - $this->depths[] = new Comparator\NumberComparator($level); + $this->depths[] = new NumberComparator($level); } return $this; @@ -152,7 +152,7 @@ public function depth(string|int|array $levels): static public function date(string|array $dates): static { foreach ((array) $dates as $date) { - $this->dates[] = new Comparator\DateComparator($date); + $this->dates[] = new DateComparator($date); } return $this; @@ -307,7 +307,7 @@ public function notPath(string|array $patterns): static public function size(string|int|array $sizes): static { foreach ((array) $sizes as $size) { - $this->sizes[] = new Comparator\NumberComparator($size); + $this->sizes[] = new NumberComparator($size); } return $this; @@ -397,10 +397,8 @@ public function ignoreVCSIgnored(bool $ignoreVCSIgnored): static * @see ignoreVCS() * * @param string|string[] $pattern VCS patterns to ignore - * - * @return void */ - public static function addVCSPattern(string|array $pattern) + public static function addVCSPattern(string|array $pattern): void { foreach ((array) $pattern as $p) { self::$vcsPatterns[] = $p; @@ -438,7 +436,7 @@ public function sort(\Closure $closure): static */ public function sortByExtension(): static { - $this->sort = Iterator\SortableIterator::SORT_BY_EXTENSION; + $this->sort = SortableIterator::SORT_BY_EXTENSION; return $this; } @@ -454,7 +452,7 @@ public function sortByExtension(): static */ public function sortByName(bool $useNaturalSort = false): static { - $this->sort = $useNaturalSort ? Iterator\SortableIterator::SORT_BY_NAME_NATURAL : Iterator\SortableIterator::SORT_BY_NAME; + $this->sort = $useNaturalSort ? SortableIterator::SORT_BY_NAME_NATURAL : SortableIterator::SORT_BY_NAME; return $this; } @@ -470,7 +468,7 @@ public function sortByName(bool $useNaturalSort = false): static */ public function sortByCaseInsensitiveName(bool $useNaturalSort = false): static { - $this->sort = $useNaturalSort ? Iterator\SortableIterator::SORT_BY_NAME_NATURAL_CASE_INSENSITIVE : Iterator\SortableIterator::SORT_BY_NAME_CASE_INSENSITIVE; + $this->sort = $useNaturalSort ? SortableIterator::SORT_BY_NAME_NATURAL_CASE_INSENSITIVE : SortableIterator::SORT_BY_NAME_CASE_INSENSITIVE; return $this; } @@ -486,7 +484,7 @@ public function sortByCaseInsensitiveName(bool $useNaturalSort = false): static */ public function sortBySize(): static { - $this->sort = Iterator\SortableIterator::SORT_BY_SIZE; + $this->sort = SortableIterator::SORT_BY_SIZE; return $this; } @@ -502,7 +500,7 @@ public function sortBySize(): static */ public function sortByType(): static { - $this->sort = Iterator\SortableIterator::SORT_BY_TYPE; + $this->sort = SortableIterator::SORT_BY_TYPE; return $this; } @@ -520,7 +518,7 @@ public function sortByType(): static */ public function sortByAccessedTime(): static { - $this->sort = Iterator\SortableIterator::SORT_BY_ACCESSED_TIME; + $this->sort = SortableIterator::SORT_BY_ACCESSED_TIME; return $this; } @@ -552,7 +550,7 @@ public function reverseSorting(): static */ public function sortByChangedTime(): static { - $this->sort = Iterator\SortableIterator::SORT_BY_CHANGED_TIME; + $this->sort = SortableIterator::SORT_BY_CHANGED_TIME; return $this; } @@ -570,7 +568,7 @@ public function sortByChangedTime(): static */ public function sortByModifiedTime(): static { - $this->sort = Iterator\SortableIterator::SORT_BY_MODIFIED_TIME; + $this->sort = SortableIterator::SORT_BY_MODIFIED_TIME; return $this; } @@ -588,9 +586,8 @@ public function sortByModifiedTime(): static * * @see CustomFilterIterator */ - public function filter(\Closure $closure /* , bool $prune = false */): static + public function filter(\Closure $closure, bool $prune = false): static { - $prune = 1 < \func_num_args() ? func_get_arg(1) : false; $this->filters[] = $closure; if ($prune) { @@ -674,7 +671,7 @@ public function getIterator(): \Iterator $iterator = $this->searchInDirectory($this->dirs[0]); if ($this->sort || $this->reverseSorting) { - $iterator = (new Iterator\SortableIterator($iterator, $this->sort, $this->reverseSorting))->getIterator(); + $iterator = (new SortableIterator($iterator, $this->sort, $this->reverseSorting))->getIterator(); } return $iterator; @@ -690,7 +687,7 @@ public function getIterator(): \Iterator } if ($this->sort || $this->reverseSorting) { - $iterator = (new Iterator\SortableIterator($iterator, $this->sort, $this->reverseSorting))->getIterator(); + $iterator = (new SortableIterator($iterator, $this->sort, $this->reverseSorting))->getIterator(); } return $iterator; @@ -793,13 +790,13 @@ private function searchInDirectory(string $dir): \Iterator $iterator = new Iterator\RecursiveDirectoryIterator($dir, $flags, $this->ignoreUnreadableDirs); if ($exclude) { - $iterator = new Iterator\ExcludeDirectoryFilterIterator($iterator, $exclude); + $iterator = new ExcludeDirectoryFilterIterator($iterator, $exclude); } $iterator = new \RecursiveIteratorIterator($iterator, \RecursiveIteratorIterator::SELF_FIRST); if ($minDepth > 0 || $maxDepth < \PHP_INT_MAX) { - $iterator = new Iterator\DepthRangeFilterIterator($iterator, $minDepth, $maxDepth); + $iterator = new DepthRangeFilterIterator($iterator, $minDepth, $maxDepth); } if ($this->mode) { @@ -807,23 +804,23 @@ private function searchInDirectory(string $dir): \Iterator } if ($this->names || $this->notNames) { - $iterator = new Iterator\FilenameFilterIterator($iterator, $this->names, $this->notNames); + $iterator = new FilenameFilterIterator($iterator, $this->names, $this->notNames); } if ($this->contains || $this->notContains) { - $iterator = new Iterator\FilecontentFilterIterator($iterator, $this->contains, $this->notContains); + $iterator = new FilecontentFilterIterator($iterator, $this->contains, $this->notContains); } if ($this->sizes) { - $iterator = new Iterator\SizeRangeFilterIterator($iterator, $this->sizes); + $iterator = new SizeRangeFilterIterator($iterator, $this->sizes); } if ($this->dates) { - $iterator = new Iterator\DateRangeFilterIterator($iterator, $this->dates); + $iterator = new DateRangeFilterIterator($iterator, $this->dates); } if ($this->filters) { - $iterator = new Iterator\CustomFilterIterator($iterator, $this->filters); + $iterator = new CustomFilterIterator($iterator, $this->filters); } if ($this->paths || $notPaths) { diff --git a/vendor/symfony/finder/Iterator/MultiplePcreFilterIterator.php b/vendor/symfony/finder/Iterator/MultiplePcreFilterIterator.php index 82a9df3..3450c49 100644 --- a/vendor/symfony/finder/Iterator/MultiplePcreFilterIterator.php +++ b/vendor/symfony/finder/Iterator/MultiplePcreFilterIterator.php @@ -23,8 +23,8 @@ */ abstract class MultiplePcreFilterIterator extends \FilterIterator { - protected $matchRegexps = []; - protected $noMatchRegexps = []; + protected array $matchRegexps = []; + protected array $noMatchRegexps = []; /** * @param \Iterator $iterator The Iterator to filter @@ -80,11 +80,7 @@ protected function isAccepted(string $string): bool */ protected function isRegex(string $str): bool { - $availableModifiers = 'imsxuADU'; - - if (\PHP_VERSION_ID >= 80200) { - $availableModifiers .= 'n'; - } + $availableModifiers = 'imsxuADUn'; if (preg_match('/^(.{3,}?)['.$availableModifiers.']*$/', $str, $m)) { $start = substr($m[1], 0, 1); diff --git a/vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php b/vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php index 34cced6..f5fd2d4 100644 --- a/vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php +++ b/vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php @@ -63,8 +63,9 @@ public function current(): SplFileInfo $subPathname .= $this->directorySeparator; } $subPathname .= $this->getFilename(); + $basePath = $this->rootPath; - if ('/' !== $basePath = $this->rootPath) { + if ('/' !== $basePath && !str_ends_with($basePath, $this->directorySeparator) && !str_ends_with($basePath, '/')) { $basePath .= $this->directorySeparator; } diff --git a/vendor/symfony/finder/Iterator/VcsIgnoredFilterIterator.php b/vendor/symfony/finder/Iterator/VcsIgnoredFilterIterator.php index ddd7007..b278706 100644 --- a/vendor/symfony/finder/Iterator/VcsIgnoredFilterIterator.php +++ b/vendor/symfony/finder/Iterator/VcsIgnoredFilterIterator.php @@ -37,9 +37,9 @@ public function __construct(\Iterator $iterator, string $baseDir) { $this->baseDir = $this->normalizePath($baseDir); - foreach ($this->parentDirectoriesUpwards($this->baseDir) as $parentDirectory) { - if (@is_dir("{$parentDirectory}/.git")) { - $this->baseDir = $parentDirectory; + foreach ([$this->baseDir, ...$this->parentDirectoriesUpwards($this->baseDir)] as $directory) { + if (@is_dir("{$directory}/.git")) { + $this->baseDir = $directory; break; } } diff --git a/vendor/symfony/finder/SplFileInfo.php b/vendor/symfony/finder/SplFileInfo.php index 867e8e8..2afc378 100644 --- a/vendor/symfony/finder/SplFileInfo.php +++ b/vendor/symfony/finder/SplFileInfo.php @@ -18,19 +18,17 @@ */ class SplFileInfo extends \SplFileInfo { - private string $relativePath; - private string $relativePathname; - /** * @param string $file The file name * @param string $relativePath The relative path * @param string $relativePathname The relative path name */ - public function __construct(string $file, string $relativePath, string $relativePathname) - { + public function __construct( + string $file, + private string $relativePath, + private string $relativePathname, + ) { parent::__construct($file); - $this->relativePath = $relativePath; - $this->relativePathname = $relativePathname; } /** diff --git a/vendor/symfony/finder/composer.json b/vendor/symfony/finder/composer.json index bbc9d7f..2b70600 100644 --- a/vendor/symfony/finder/composer.json +++ b/vendor/symfony/finder/composer.json @@ -16,10 +16,10 @@ } ], "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "symfony/filesystem": "^6.0|^7.0" + "symfony/filesystem": "^6.4|^7.0" }, "autoload": { "psr-4": { "Symfony\\Component\\Finder\\": "" }, diff --git a/vendor/symfony/polyfill-ctype/composer.json b/vendor/symfony/polyfill-ctype/composer.json index b222fda..131ca7a 100644 --- a/vendor/symfony/polyfill-ctype/composer.json +++ b/vendor/symfony/polyfill-ctype/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-ctype": "*" diff --git a/vendor/symfony/polyfill-intl-grapheme/composer.json b/vendor/symfony/polyfill-intl-grapheme/composer.json index a20d3fa..0eea417 100644 --- a/vendor/symfony/polyfill-intl-grapheme/composer.json +++ b/vendor/symfony/polyfill-intl-grapheme/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=7.1" + "php": ">=7.2" }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Intl\\Grapheme\\": "" }, diff --git a/vendor/symfony/polyfill-intl-normalizer/composer.json b/vendor/symfony/polyfill-intl-normalizer/composer.json index 1b93573..9bd04e8 100644 --- a/vendor/symfony/polyfill-intl-normalizer/composer.json +++ b/vendor/symfony/polyfill-intl-normalizer/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=7.1" + "php": ">=7.2" }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Intl\\Normalizer\\": "" }, diff --git a/vendor/symfony/polyfill-mbstring/Mbstring.php b/vendor/symfony/polyfill-mbstring/Mbstring.php index 2e0b969..3d45c9d 100644 --- a/vendor/symfony/polyfill-mbstring/Mbstring.php +++ b/vendor/symfony/polyfill-mbstring/Mbstring.php @@ -48,6 +48,11 @@ * - mb_strstr - Finds first occurrence of a string within another * - mb_strwidth - Return width of string * - mb_substr_count - Count the number of substring occurrences + * - mb_ucfirst - Make a string's first character uppercase + * - mb_lcfirst - Make a string's first character lowercase + * - mb_trim - Strip whitespace (or other characters) from the beginning and end of a string + * - mb_ltrim - Strip whitespace (or other characters) from the beginning of a string + * - mb_rtrim - Strip whitespace (or other characters) from the end of a string * * Not implemented: * - mb_convert_kana - Convert "kana" one from another ("zen-kaku", "han-kaku" and more) @@ -80,6 +85,15 @@ final class Mbstring public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null) { + if (\is_array($s)) { + $r = []; + foreach ($s as $str) { + $r[] = self::mb_convert_encoding($str, $toEncoding, $fromEncoding); + } + + return $r; + } + if (\is_array($fromEncoding) || (null !== $fromEncoding && false !== strpos($fromEncoding, ','))) { $fromEncoding = self::mb_detect_encoding($s, $fromEncoding); } else { @@ -410,12 +424,6 @@ public static function mb_encoding_aliases($encoding) public static function mb_check_encoding($var = null, $encoding = null) { - if (PHP_VERSION_ID < 70200 && \is_array($var)) { - trigger_error('mb_check_encoding() expects parameter 1 to be string, array given', \E_USER_WARNING); - - return null; - } - if (null === $encoding) { if (null === $var) { return false; @@ -437,7 +445,6 @@ public static function mb_check_encoding($var = null, $encoding = null) } return true; - } public static function mb_detect_encoding($str, $encodingList = null, $strict = false) @@ -827,7 +834,7 @@ public static function mb_ord($s, $encoding = null) return $code; } - public static function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = \STR_PAD_RIGHT, string $encoding = null): string + public static function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = \STR_PAD_RIGHT, ?string $encoding = null): string { if (!\in_array($pad_type, [\STR_PAD_RIGHT, \STR_PAD_LEFT, \STR_PAD_BOTH], true)) { throw new \ValueError('mb_str_pad(): Argument #4 ($pad_type) must be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH'); @@ -835,17 +842,8 @@ public static function mb_str_pad(string $string, int $length, string $pad_strin if (null === $encoding) { $encoding = self::mb_internal_encoding(); - } - - try { - $validEncoding = @self::mb_check_encoding('', $encoding); - } catch (\ValueError $e) { - throw new \ValueError(sprintf('mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given', $encoding)); - } - - // BC for PHP 7.3 and lower - if (!$validEncoding) { - throw new \ValueError(sprintf('mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given', $encoding)); + } else { + self::assertEncoding($encoding, 'mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given'); } if (self::mb_strlen($pad_string, $encoding) <= 0) { @@ -871,6 +869,34 @@ public static function mb_str_pad(string $string, int $length, string $pad_strin } } + public static function mb_ucfirst(string $string, ?string $encoding = null): string + { + if (null === $encoding) { + $encoding = self::mb_internal_encoding(); + } else { + self::assertEncoding($encoding, 'mb_ucfirst(): Argument #2 ($encoding) must be a valid encoding, "%s" given'); + } + + $firstChar = mb_substr($string, 0, 1, $encoding); + $firstChar = mb_convert_case($firstChar, \MB_CASE_TITLE, $encoding); + + return $firstChar.mb_substr($string, 1, null, $encoding); + } + + public static function mb_lcfirst(string $string, ?string $encoding = null): string + { + if (null === $encoding) { + $encoding = self::mb_internal_encoding(); + } else { + self::assertEncoding($encoding, 'mb_lcfirst(): Argument #2 ($encoding) must be a valid encoding, "%s" given'); + } + + $firstChar = mb_substr($string, 0, 1, $encoding); + $firstChar = mb_convert_case($firstChar, \MB_CASE_LOWER, $encoding); + + return $firstChar.mb_substr($string, 1, null, $encoding); + } + private static function getSubpart($pos, $part, $haystack, $encoding) { if (false === $pos) { @@ -944,4 +970,76 @@ private static function getEncoding($encoding) return $encoding; } + + public static function mb_trim(string $string, ?string $characters = null, ?string $encoding = null): string + { + return self::mb_internal_trim('{^[%s]+|[%1$s]+$}Du', $string, $characters, $encoding, __FUNCTION__); + } + + public static function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): string + { + return self::mb_internal_trim('{^[%s]+}Du', $string, $characters, $encoding, __FUNCTION__); + } + + public static function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null): string + { + return self::mb_internal_trim('{[%s]+$}D', $string, $characters, $encoding, __FUNCTION__); + } + + private static function mb_internal_trim(string $regex, string $string, ?string $characters, ?string $encoding, string $function): string + { + if (null === $encoding) { + $encoding = self::mb_internal_encoding(); + } else { + self::assertEncoding($encoding, $function.'(): Argument #3 ($encoding) must be a valid encoding, "%s" given'); + } + + if ('' === $characters) { + return null === $encoding ? $string : self::mb_convert_encoding($string, $encoding); + } + + if ('UTF-8' === $encoding) { + $encoding = null; + if (!preg_match('//u', $string)) { + $string = @iconv('UTF-8', 'UTF-8//IGNORE', $string); + } + if (null !== $characters && !preg_match('//u', $characters)) { + $characters = @iconv('UTF-8', 'UTF-8//IGNORE', $characters); + } + } else { + $string = iconv($encoding, 'UTF-8//IGNORE', $string); + + if (null !== $characters) { + $characters = iconv($encoding, 'UTF-8//IGNORE', $characters); + } + } + + if (null === $characters) { + $characters = "\\0 \f\n\r\t\v\u{00A0}\u{1680}\u{2000}\u{2001}\u{2002}\u{2003}\u{2004}\u{2005}\u{2006}\u{2007}\u{2008}\u{2009}\u{200A}\u{2028}\u{2029}\u{202F}\u{205F}\u{3000}\u{0085}\u{180E}"; + } else { + $characters = preg_quote($characters); + } + + $string = preg_replace(sprintf($regex, $characters), '', $string); + + if (null === $encoding) { + return $string; + } + + return iconv('UTF-8', $encoding.'//IGNORE', $string); + } + + private static function assertEncoding(string $encoding, string $errorFormat): void + { + try { + $validEncoding = @self::mb_check_encoding('', $encoding); + } catch (\ValueError $e) { + throw new \ValueError(sprintf($errorFormat, $encoding)); + } + + // BC for PHP 7.3 and lower + if (!$validEncoding) { + throw new \ValueError(sprintf($errorFormat, $encoding)); + } + } } diff --git a/vendor/symfony/polyfill-mbstring/bootstrap.php b/vendor/symfony/polyfill-mbstring/bootstrap.php index ecf1a03..ff51ae0 100644 --- a/vendor/symfony/polyfill-mbstring/bootstrap.php +++ b/vendor/symfony/polyfill-mbstring/bootstrap.php @@ -136,6 +136,27 @@ function mb_str_split($string, $length = 1, $encoding = null) { return p\Mbstrin function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = STR_PAD_RIGHT, ?string $encoding = null): string { return p\Mbstring::mb_str_pad($string, $length, $pad_string, $pad_type, $encoding); } } +if (!function_exists('mb_ucfirst')) { + function mb_ucfirst(string $string, ?string $encoding = null): string { return p\Mbstring::mb_ucfirst($string, $encoding); } +} + +if (!function_exists('mb_lcfirst')) { + function mb_lcfirst(string $string, ?string $encoding = null): string { return p\Mbstring::mb_lcfirst($string, $encoding); } +} + +if (!function_exists('mb_trim')) { + function mb_trim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_trim($string, $characters, $encoding); } +} + +if (!function_exists('mb_ltrim')) { + function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_ltrim($string, $characters, $encoding); } +} + +if (!function_exists('mb_rtrim')) { + function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_rtrim($string, $characters, $encoding); } +} + + if (extension_loaded('mbstring')) { return; } diff --git a/vendor/symfony/polyfill-mbstring/bootstrap80.php b/vendor/symfony/polyfill-mbstring/bootstrap80.php index 2f9fb5b..5be7d20 100644 --- a/vendor/symfony/polyfill-mbstring/bootstrap80.php +++ b/vendor/symfony/polyfill-mbstring/bootstrap80.php @@ -93,7 +93,7 @@ function mb_strrpos(?string $haystack, ?string $needle, ?int $offset = 0, ?strin function mb_strstr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_strstr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); } } if (!function_exists('mb_get_info')) { - function mb_get_info(?string $type = 'all'): array|string|int|false { return p\Mbstring::mb_get_info((string) $type); } + function mb_get_info(?string $type = 'all'): array|string|int|false|null { return p\Mbstring::mb_get_info((string) $type); } } if (!function_exists('mb_http_output')) { function mb_http_output(?string $encoding = null): string|bool { return p\Mbstring::mb_http_output($encoding); } @@ -132,6 +132,26 @@ function mb_str_split(?string $string, ?int $length = 1, ?string $encoding = nul function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = STR_PAD_RIGHT, ?string $encoding = null): string { return p\Mbstring::mb_str_pad($string, $length, $pad_string, $pad_type, $encoding); } } +if (!function_exists('mb_ucfirst')) { + function mb_ucfirst($string, ?string $encoding = null): string { return p\Mbstring::mb_ucfirst($string, $encoding); } +} + +if (!function_exists('mb_lcfirst')) { + function mb_lcfirst($string, ?string $encoding = null): string { return p\Mbstring::mb_lcfirst($string, $encoding); } +} + +if (!function_exists('mb_trim')) { + function mb_trim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_trim($string, $characters, $encoding); } +} + +if (!function_exists('mb_ltrim')) { + function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_ltrim($string, $characters, $encoding); } +} + +if (!function_exists('mb_rtrim')) { + function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_rtrim($string, $characters, $encoding); } +} + if (extension_loaded('mbstring')) { return; } diff --git a/vendor/symfony/polyfill-mbstring/composer.json b/vendor/symfony/polyfill-mbstring/composer.json index bd99d4b..4ed241a 100644 --- a/vendor/symfony/polyfill-mbstring/composer.json +++ b/vendor/symfony/polyfill-mbstring/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-mbstring": "*" diff --git a/vendor/symfony/polyfill-php73/composer.json b/vendor/symfony/polyfill-php73/composer.json index 3d47d15..09d98cb 100644 --- a/vendor/symfony/polyfill-php73/composer.json +++ b/vendor/symfony/polyfill-php73/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=7.1" + "php": ">=7.2" }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Php73\\": "" }, diff --git a/vendor/symfony/polyfill-php80/composer.json b/vendor/symfony/polyfill-php80/composer.json index 46ccde2..a503b03 100644 --- a/vendor/symfony/polyfill-php80/composer.json +++ b/vendor/symfony/polyfill-php80/composer.json @@ -20,7 +20,7 @@ } ], "require": { - "php": ">=7.1" + "php": ">=7.2" }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Php80\\": "" }, diff --git a/vendor/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php b/vendor/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php index eb5952e..5ff93fc 100644 --- a/vendor/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php +++ b/vendor/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php @@ -32,7 +32,7 @@ public function __set(string $name, $value): void } if (is_object($value) ? !method_exists($value, '__toString') : !is_scalar($value)) { - throw new \TypeError('Cannot assign '.gettype($value).' to property CURLStringFile::$data of type string'); + throw new TypeError('Cannot assign '.gettype($value).' to property CURLStringFile::$data of type string'); } $this->name = 'data://application/octet-stream;base64,'.base64_encode($value); diff --git a/vendor/symfony/polyfill-php81/composer.json b/vendor/symfony/polyfill-php81/composer.json index 381af79..28b6408 100644 --- a/vendor/symfony/polyfill-php81/composer.json +++ b/vendor/symfony/polyfill-php81/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=7.1" + "php": ">=7.2" }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Php81\\": "" }, diff --git a/vendor/symfony/process/CHANGELOG.md b/vendor/symfony/process/CHANGELOG.md index 31b9ee6..3e33cd0 100644 --- a/vendor/symfony/process/CHANGELOG.md +++ b/vendor/symfony/process/CHANGELOG.md @@ -1,6 +1,18 @@ CHANGELOG ========= +7.1 +--- + + * Add `Process::setIgnoredSignals()` to disable signal propagation to the child process + +6.4 +--- + + * Add `PhpSubprocess` to handle PHP subprocesses that take over the + configuration from their parent + * Add `RunProcessMessage` and `RunProcessMessageHandler` + 5.2.0 ----- diff --git a/vendor/symfony/process/Exception/ProcessFailedException.php b/vendor/symfony/process/Exception/ProcessFailedException.php index 328acfd..499809e 100644 --- a/vendor/symfony/process/Exception/ProcessFailedException.php +++ b/vendor/symfony/process/Exception/ProcessFailedException.php @@ -20,7 +20,7 @@ */ class ProcessFailedException extends RuntimeException { - private $process; + private Process $process; public function __construct(Process $process) { @@ -47,7 +47,7 @@ public function __construct(Process $process) $this->process = $process; } - public function getProcess() + public function getProcess(): Process { return $this->process; } diff --git a/vendor/symfony/process/Exception/ProcessSignaledException.php b/vendor/symfony/process/Exception/ProcessSignaledException.php index d4d3227..0fed8ac 100644 --- a/vendor/symfony/process/Exception/ProcessSignaledException.php +++ b/vendor/symfony/process/Exception/ProcessSignaledException.php @@ -20,7 +20,7 @@ */ final class ProcessSignaledException extends RuntimeException { - private $process; + private Process $process; public function __construct(Process $process) { diff --git a/vendor/symfony/process/Exception/ProcessStartFailedException.php b/vendor/symfony/process/Exception/ProcessStartFailedException.php new file mode 100644 index 0000000..9bd5a03 --- /dev/null +++ b/vendor/symfony/process/Exception/ProcessStartFailedException.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Process\Exception; + +use Symfony\Component\Process\Process; + +/** + * Exception for processes failed during startup. + */ +class ProcessStartFailedException extends ProcessFailedException +{ + private Process $process; + + public function __construct(Process $process, ?string $message) + { + if ($process->isStarted()) { + throw new InvalidArgumentException('Expected a process that failed during startup, but the given process was started successfully.'); + } + + $error = sprintf('The command "%s" failed.'."\n\nWorking directory: %s\n\nError: %s", + $process->getCommandLine(), + $process->getWorkingDirectory(), + $message ?? 'unknown' + ); + + // Skip parent constructor + RuntimeException::__construct($error); + + $this->process = $process; + } + + public function getProcess(): Process + { + return $this->process; + } +} diff --git a/vendor/symfony/process/Exception/ProcessTimedOutException.php b/vendor/symfony/process/Exception/ProcessTimedOutException.php index 94391a4..252e111 100644 --- a/vendor/symfony/process/Exception/ProcessTimedOutException.php +++ b/vendor/symfony/process/Exception/ProcessTimedOutException.php @@ -23,8 +23,8 @@ class ProcessTimedOutException extends RuntimeException public const TYPE_GENERAL = 1; public const TYPE_IDLE = 2; - private $process; - private $timeoutType; + private Process $process; + private int $timeoutType; public function __construct(Process $process, int $timeoutType) { @@ -38,32 +38,27 @@ public function __construct(Process $process, int $timeoutType) )); } - public function getProcess() + public function getProcess(): Process { return $this->process; } - public function isGeneralTimeout() + public function isGeneralTimeout(): bool { return self::TYPE_GENERAL === $this->timeoutType; } - public function isIdleTimeout() + public function isIdleTimeout(): bool { return self::TYPE_IDLE === $this->timeoutType; } - public function getExceededTimeout() + public function getExceededTimeout(): ?float { - switch ($this->timeoutType) { - case self::TYPE_GENERAL: - return $this->process->getTimeout(); - - case self::TYPE_IDLE: - return $this->process->getIdleTimeout(); - - default: - throw new \LogicException(sprintf('Unknown timeout type "%d".', $this->timeoutType)); - } + return match ($this->timeoutType) { + self::TYPE_GENERAL => $this->process->getTimeout(), + self::TYPE_IDLE => $this->process->getIdleTimeout(), + default => throw new \LogicException(sprintf('Unknown timeout type "%d".', $this->timeoutType)), + }; } } diff --git a/vendor/symfony/process/ExecutableFinder.php b/vendor/symfony/process/ExecutableFinder.php index f392c96..ceb7a55 100644 --- a/vendor/symfony/process/ExecutableFinder.php +++ b/vendor/symfony/process/ExecutableFinder.php @@ -19,12 +19,12 @@ */ class ExecutableFinder { - private $suffixes = ['.exe', '.bat', '.cmd', '.com']; + private array $suffixes = ['.exe', '.bat', '.cmd', '.com']; /** * Replaces default suffixes of executable. */ - public function setSuffixes(array $suffixes) + public function setSuffixes(array $suffixes): void { $this->suffixes = $suffixes; } @@ -32,7 +32,7 @@ public function setSuffixes(array $suffixes) /** * Adds new possible suffix to check for executable. */ - public function addSuffix(string $suffix) + public function addSuffix(string $suffix): void { $this->suffixes[] = $suffix; } @@ -43,30 +43,13 @@ public function addSuffix(string $suffix) * @param string $name The executable name (without the extension) * @param string|null $default The default to return if no executable is found * @param array $extraDirs Additional dirs to check into - * - * @return string|null */ - public function find(string $name, ?string $default = null, array $extraDirs = []) + public function find(string $name, ?string $default = null, array $extraDirs = []): ?string { - if (\ini_get('open_basedir')) { - $searchPath = array_merge(explode(\PATH_SEPARATOR, \ini_get('open_basedir')), $extraDirs); - $dirs = []; - foreach ($searchPath as $path) { - // Silencing against https://bugs.php.net/69240 - if (@is_dir($path)) { - $dirs[] = $path; - } else { - if (basename($path) == $name && @is_executable($path)) { - return $path; - } - } - } - } else { - $dirs = array_merge( - explode(\PATH_SEPARATOR, getenv('PATH') ?: getenv('Path')), - $extraDirs - ); - } + $dirs = array_merge( + explode(\PATH_SEPARATOR, getenv('PATH') ?: getenv('Path')), + $extraDirs + ); $suffixes = ['']; if ('\\' === \DIRECTORY_SEPARATOR) { @@ -78,9 +61,18 @@ public function find(string $name, ?string $default = null, array $extraDirs = [ if (@is_file($file = $dir.\DIRECTORY_SEPARATOR.$name.$suffix) && ('\\' === \DIRECTORY_SEPARATOR || @is_executable($file))) { return $file; } + + if (!@is_dir($dir) && basename($dir) === $name.$suffix && @is_executable($dir)) { + return $dir; + } } } + $command = '\\' === \DIRECTORY_SEPARATOR ? 'where' : 'command -v --'; + if (\function_exists('exec') && ($executablePath = strtok(@exec($command.' '.escapeshellarg($name)), \PHP_EOL)) && @is_executable($executablePath)) { + return $executablePath; + } + return $default; } } diff --git a/vendor/symfony/process/InputStream.php b/vendor/symfony/process/InputStream.php index 0c45b52..cd91029 100644 --- a/vendor/symfony/process/InputStream.php +++ b/vendor/symfony/process/InputStream.php @@ -22,17 +22,16 @@ */ class InputStream implements \IteratorAggregate { - /** @var callable|null */ - private $onEmpty = null; - private $input = []; - private $open = true; + private ?\Closure $onEmpty = null; + private array $input = []; + private bool $open = true; /** * Sets a callback that is called when the write buffer becomes empty. */ - public function onEmpty(?callable $onEmpty = null) + public function onEmpty(?callable $onEmpty = null): void { - $this->onEmpty = $onEmpty; + $this->onEmpty = null !== $onEmpty ? $onEmpty(...) : null; } /** @@ -41,7 +40,7 @@ public function onEmpty(?callable $onEmpty = null) * @param resource|string|int|float|bool|\Traversable|null $input The input to append as scalar, * stream resource or \Traversable */ - public function write($input) + public function write(mixed $input): void { if (null === $input) { return; @@ -55,7 +54,7 @@ public function write($input) /** * Closes the write buffer. */ - public function close() + public function close(): void { $this->open = false; } @@ -63,16 +62,12 @@ public function close() /** * Tells whether the write buffer is closed or not. */ - public function isClosed() + public function isClosed(): bool { return !$this->open; } - /** - * @return \Traversable - */ - #[\ReturnTypeWillChange] - public function getIterator() + public function getIterator(): \Traversable { $this->open = true; diff --git a/vendor/symfony/process/Messenger/RunProcessContext.php b/vendor/symfony/process/Messenger/RunProcessContext.php index b5ade07..5e22304 100644 --- a/vendor/symfony/process/Messenger/RunProcessContext.php +++ b/vendor/symfony/process/Messenger/RunProcessContext.php @@ -27,7 +27,7 @@ public function __construct( Process $process, ) { $this->exitCode = $process->getExitCode(); - $this->output = $process->isOutputDisabled() ? null : $process->getOutput(); - $this->errorOutput = $process->isOutputDisabled() ? null : $process->getErrorOutput(); + $this->output = !$process->isStarted() || $process->isOutputDisabled() ? null : $process->getOutput(); + $this->errorOutput = !$process->isStarted() || $process->isOutputDisabled() ? null : $process->getErrorOutput(); } } diff --git a/vendor/symfony/process/PhpExecutableFinder.php b/vendor/symfony/process/PhpExecutableFinder.php index 45dbcca..4a882e0 100644 --- a/vendor/symfony/process/PhpExecutableFinder.php +++ b/vendor/symfony/process/PhpExecutableFinder.php @@ -19,7 +19,7 @@ */ class PhpExecutableFinder { - private $executableFinder; + private ExecutableFinder $executableFinder; public function __construct() { @@ -28,15 +28,13 @@ public function __construct() /** * Finds The PHP executable. - * - * @return string|false */ - public function find(bool $includeArgs = true) + public function find(bool $includeArgs = true): string|false { if ($php = getenv('PHP_BINARY')) { if (!is_executable($php)) { $command = '\\' === \DIRECTORY_SEPARATOR ? 'where' : 'command -v --'; - if ($php = strtok(exec($command.' '.escapeshellarg($php)), \PHP_EOL)) { + if (\function_exists('exec') && $php = strtok(exec($command.' '.escapeshellarg($php)), \PHP_EOL)) { if (!is_executable($php)) { return false; } @@ -88,10 +86,8 @@ public function find(bool $includeArgs = true) /** * Finds the PHP executable arguments. - * - * @return array */ - public function findArguments() + public function findArguments(): array { $arguments = []; if ('phpdbg' === \PHP_SAPI) { diff --git a/vendor/symfony/process/PhpProcess.php b/vendor/symfony/process/PhpProcess.php index 3a1d147..01d8895 100644 --- a/vendor/symfony/process/PhpProcess.php +++ b/vendor/symfony/process/PhpProcess.php @@ -50,18 +50,12 @@ public function __construct(string $script, ?string $cwd = null, ?array $env = n parent::__construct($php, $cwd, $env, $script, $timeout); } - /** - * {@inheritdoc} - */ - public static function fromShellCommandline(string $command, ?string $cwd = null, ?array $env = null, $input = null, ?float $timeout = 60) + public static function fromShellCommandline(string $command, ?string $cwd = null, ?array $env = null, mixed $input = null, ?float $timeout = 60): static { throw new LogicException(sprintf('The "%s()" method cannot be called when using "%s".', __METHOD__, self::class)); } - /** - * {@inheritdoc} - */ - public function start(?callable $callback = null, array $env = []) + public function start(?callable $callback = null, array $env = []): void { if (null === $this->getCommandLine()) { throw new RuntimeException('Unable to find the PHP executable.'); diff --git a/vendor/symfony/process/PhpSubprocess.php b/vendor/symfony/process/PhpSubprocess.php index a97f8b2..04fd8ea 100644 --- a/vendor/symfony/process/PhpSubprocess.php +++ b/vendor/symfony/process/PhpSubprocess.php @@ -106,7 +106,7 @@ private function writeTmpIni(array $iniFiles, string $tmpDir): string throw new RuntimeException('Unable to read ini: '.$file); } // Check and remove directives after HOST and PATH sections - if (preg_match('/^\s*\[(?:PATH|HOST)\s*=/mi', $data, $matches)) { + if (preg_match('/^\s*\[(?:PATH|HOST)\s*=/mi', $data, $matches, \PREG_OFFSET_CAPTURE)) { $data = substr($data, 0, $matches[0][1]); } diff --git a/vendor/symfony/process/Pipes/AbstractPipes.php b/vendor/symfony/process/Pipes/AbstractPipes.php index 656dc03..cbbb727 100644 --- a/vendor/symfony/process/Pipes/AbstractPipes.php +++ b/vendor/symfony/process/Pipes/AbstractPipes.php @@ -20,31 +20,27 @@ */ abstract class AbstractPipes implements PipesInterface { - public $pipes = []; + public array $pipes = []; - private $inputBuffer = ''; + private string $inputBuffer = ''; + /** @var resource|string|\Iterator */ private $input; - private $blocked = true; - private $lastError; + private bool $blocked = true; + private ?string $lastError = null; /** - * @param resource|string|int|float|bool|\Iterator|null $input + * @param resource|string|\Iterator $input */ public function __construct($input) { if (\is_resource($input) || $input instanceof \Iterator) { $this->input = $input; - } elseif (\is_string($input)) { - $this->inputBuffer = $input; } else { $this->inputBuffer = (string) $input; } } - /** - * {@inheritdoc} - */ - public function close() + public function close(): void { foreach ($this->pipes as $pipe) { if (\is_resource($pipe)) { @@ -69,7 +65,7 @@ protected function hasSystemCallBeenInterrupted(): bool /** * Unblocks streams. */ - protected function unblock() + protected function unblock(): void { if (!$this->blocked) { return; @@ -173,7 +169,7 @@ protected function write(): ?array /** * @internal */ - public function handleError(int $type, string $msg) + public function handleError(int $type, string $msg): void { $this->lastError = $msg; } diff --git a/vendor/symfony/process/Pipes/PipesInterface.php b/vendor/symfony/process/Pipes/PipesInterface.php index 50eb5c4..967f8de 100644 --- a/vendor/symfony/process/Pipes/PipesInterface.php +++ b/vendor/symfony/process/Pipes/PipesInterface.php @@ -57,5 +57,5 @@ public function haveReadSupport(): bool; /** * Closes file handles and pipes. */ - public function close(); + public function close(): void; } diff --git a/vendor/symfony/process/Pipes/UnixPipes.php b/vendor/symfony/process/Pipes/UnixPipes.php index 5a0e9d4..7bd0db0 100644 --- a/vendor/symfony/process/Pipes/UnixPipes.php +++ b/vendor/symfony/process/Pipes/UnixPipes.php @@ -22,11 +22,11 @@ */ class UnixPipes extends AbstractPipes { - private $ttyMode; - private $ptyMode; - private $haveReadSupport; + private ?bool $ttyMode; + private bool $ptyMode; + private bool $haveReadSupport; - public function __construct(?bool $ttyMode, bool $ptyMode, $input, bool $haveReadSupport) + public function __construct(?bool $ttyMode, bool $ptyMode, mixed $input, bool $haveReadSupport) { $this->ttyMode = $ttyMode; $this->ptyMode = $ptyMode; @@ -40,7 +40,7 @@ public function __sleep(): array throw new \BadMethodCallException('Cannot serialize '.__CLASS__); } - public function __wakeup() + public function __wakeup(): void { throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); } @@ -50,9 +50,6 @@ public function __destruct() $this->close(); } - /** - * {@inheritdoc} - */ public function getDescriptors(): array { if (!$this->haveReadSupport) { @@ -88,17 +85,11 @@ public function getDescriptors(): array ]; } - /** - * {@inheritdoc} - */ public function getFiles(): array { return []; } - /** - * {@inheritdoc} - */ public function readAndWrite(bool $blocking, bool $close = false): array { $this->unblock(); @@ -109,7 +100,7 @@ public function readAndWrite(bool $blocking, bool $close = false): array unset($r[0]); // let's have a look if something changed in streams - set_error_handler([$this, 'handleError']); + set_error_handler($this->handleError(...)); if (($r || $w) && false === stream_select($r, $w, $e, 0, $blocking ? Process::TIMEOUT_PRECISION * 1E6 : 0)) { restore_error_handler(); // if a system call has been interrupted, forget about it, let's try again @@ -145,17 +136,11 @@ public function readAndWrite(bool $blocking, bool $close = false): array return $read; } - /** - * {@inheritdoc} - */ public function haveReadSupport(): bool { return $this->haveReadSupport; } - /** - * {@inheritdoc} - */ public function areOpen(): bool { return (bool) $this->pipes; diff --git a/vendor/symfony/process/Pipes/WindowsPipes.php b/vendor/symfony/process/Pipes/WindowsPipes.php index 968dd02..8033442 100644 --- a/vendor/symfony/process/Pipes/WindowsPipes.php +++ b/vendor/symfony/process/Pipes/WindowsPipes.php @@ -26,16 +26,16 @@ */ class WindowsPipes extends AbstractPipes { - private $files = []; - private $fileHandles = []; - private $lockHandles = []; - private $readBytes = [ + private array $files = []; + private array $fileHandles = []; + private array $lockHandles = []; + private array $readBytes = [ Process::STDOUT => 0, Process::STDERR => 0, ]; - private $haveReadSupport; + private bool $haveReadSupport; - public function __construct($input, bool $haveReadSupport) + public function __construct(mixed $input, bool $haveReadSupport) { $this->haveReadSupport = $haveReadSupport; @@ -93,7 +93,7 @@ public function __sleep(): array throw new \BadMethodCallException('Cannot serialize '.__CLASS__); } - public function __wakeup() + public function __wakeup(): void { throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); } @@ -103,9 +103,6 @@ public function __destruct() $this->close(); } - /** - * {@inheritdoc} - */ public function getDescriptors(): array { if (!$this->haveReadSupport) { @@ -128,17 +125,11 @@ public function getDescriptors(): array ]; } - /** - * {@inheritdoc} - */ public function getFiles(): array { return $this->files; } - /** - * {@inheritdoc} - */ public function readAndWrite(bool $blocking, bool $close = false): array { $this->unblock(); @@ -171,26 +162,17 @@ public function readAndWrite(bool $blocking, bool $close = false): array return $read; } - /** - * {@inheritdoc} - */ public function haveReadSupport(): bool { return $this->haveReadSupport; } - /** - * {@inheritdoc} - */ public function areOpen(): bool { return $this->pipes && $this->fileHandles; } - /** - * {@inheritdoc} - */ - public function close() + public function close(): void { parent::close(); foreach ($this->fileHandles as $type => $handle) { diff --git a/vendor/symfony/process/Process.php b/vendor/symfony/process/Process.php index a4b0a78..baa7d95 100644 --- a/vendor/symfony/process/Process.php +++ b/vendor/symfony/process/Process.php @@ -15,9 +15,9 @@ use Symfony\Component\Process\Exception\LogicException; use Symfony\Component\Process\Exception\ProcessFailedException; use Symfony\Component\Process\Exception\ProcessSignaledException; +use Symfony\Component\Process\Exception\ProcessStartFailedException; use Symfony\Component\Process\Exception\ProcessTimedOutException; use Symfony\Component\Process\Exception\RuntimeException; -use Symfony\Component\Process\Pipes\PipesInterface; use Symfony\Component\Process\Pipes\UnixPipes; use Symfony\Component\Process\Pipes\WindowsPipes; @@ -51,45 +51,47 @@ class Process implements \IteratorAggregate public const ITER_SKIP_OUT = 4; // Use this flag to skip STDOUT while iterating public const ITER_SKIP_ERR = 8; // Use this flag to skip STDERR while iterating - private $callback; - private $hasCallback = false; - private $commandline; - private $cwd; - private $env = []; + private ?\Closure $callback = null; + private array|string $commandline; + private ?string $cwd; + private array $env = []; + /** @var resource|string|\Iterator|null */ private $input; - private $starttime; - private $lastOutputTime; - private $timeout; - private $idleTimeout; - private $exitcode; - private $fallbackStatus = []; - private $processInformation; - private $outputDisabled = false; + private ?float $starttime = null; + private ?float $lastOutputTime = null; + private ?float $timeout = null; + private ?float $idleTimeout = null; + private ?int $exitcode = null; + private array $fallbackStatus = []; + private array $processInformation; + private bool $outputDisabled = false; + /** @var resource */ private $stdout; + /** @var resource */ private $stderr; + /** @var resource|null */ private $process; - private $status = self::STATUS_READY; - private $incrementalOutputOffset = 0; - private $incrementalErrorOutputOffset = 0; - private $tty = false; - private $pty; - private $options = ['suppress_errors' => true, 'bypass_shell' => true]; + private string $status = self::STATUS_READY; + private int $incrementalOutputOffset = 0; + private int $incrementalErrorOutputOffset = 0; + private bool $tty = false; + private bool $pty; + private array $options = ['suppress_errors' => true, 'bypass_shell' => true]; + private array $ignoredSignals = []; - private $useFileHandles = false; - /** @var PipesInterface */ - private $processPipes; + private WindowsPipes|UnixPipes $processPipes; - private $latestSignal; - private $cachedExitCode; + private ?int $latestSignal = null; + private ?int $cachedExitCode = null; - private static $sigchild; + private static ?bool $sigchild = null; /** * Exit codes translation table. * * User-defined errors must use exit codes in the 64-113 range. */ - public static $exitCodes = [ + public static array $exitCodes = [ 0 => 'OK', 1 => 'General error', 2 => 'Misuse of shell builtins', @@ -141,7 +143,7 @@ class Process implements \IteratorAggregate * * @throws LogicException When proc_open is not installed */ - public function __construct(array $command, ?string $cwd = null, ?array $env = null, $input = null, ?float $timeout = 60) + public function __construct(array $command, ?string $cwd = null, ?array $env = null, mixed $input = null, ?float $timeout = 60) { if (!\function_exists('proc_open')) { throw new LogicException('The Process class relies on proc_open, which is not available on your PHP installation.'); @@ -163,7 +165,6 @@ public function __construct(array $command, ?string $cwd = null, ?array $env = n $this->setInput($input); $this->setTimeout($timeout); - $this->useFileHandles = '\\' === \DIRECTORY_SEPARATOR; $this->pty = false; } @@ -186,11 +187,9 @@ public function __construct(array $command, ?string $cwd = null, ?array $env = n * @param mixed $input The input as stream resource, scalar or \Traversable, or null for no input * @param int|float|null $timeout The timeout in seconds or null to disable * - * @return static - * * @throws LogicException When proc_open is not installed */ - public static function fromShellCommandline(string $command, ?string $cwd = null, ?array $env = null, $input = null, ?float $timeout = 60) + public static function fromShellCommandline(string $command, ?string $cwd = null, ?array $env = null, mixed $input = null, ?float $timeout = 60): static { $process = new static([], $cwd, $env, $input, $timeout); $process->commandline = $command; @@ -198,15 +197,12 @@ public static function fromShellCommandline(string $command, ?string $cwd = null return $process; } - /** - * @return array - */ - public function __sleep() + public function __sleep(): array { throw new \BadMethodCallException('Cannot serialize '.__CLASS__); } - public function __wakeup() + public function __wakeup(): void { throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); } @@ -240,11 +236,11 @@ public function __clone() * * @return int The exit status code * - * @throws RuntimeException When process can't be launched - * @throws RuntimeException When process is already running - * @throws ProcessTimedOutException When process timed out - * @throws ProcessSignaledException When process stopped after receiving signal - * @throws LogicException In case a callback is provided and output has been disabled + * @throws ProcessStartFailedException When process can't be launched + * @throws RuntimeException When process is already running + * @throws ProcessTimedOutException When process timed out + * @throws ProcessSignaledException When process stopped after receiving signal + * @throws LogicException In case a callback is provided and output has been disabled * * @final */ @@ -267,7 +263,7 @@ public function run(?callable $callback = null, array $env = []): int * * @final */ - public function mustRun(?callable $callback = null, array $env = []): self + public function mustRun(?callable $callback = null, array $env = []): static { if (0 !== $this->run($callback, $env)) { throw new ProcessFailedException($this); @@ -291,11 +287,11 @@ public function mustRun(?callable $callback = null, array $env = []): self * @param callable|null $callback A PHP callback to run whenever there is some * output available on STDOUT or STDERR * - * @throws RuntimeException When process can't be launched - * @throws RuntimeException When process is already running - * @throws LogicException In case a callback is provided and output has been disabled + * @throws ProcessStartFailedException When process can't be launched + * @throws RuntimeException When process is already running + * @throws LogicException In case a callback is provided and output has been disabled */ - public function start(?callable $callback = null, array $env = []) + public function start(?callable $callback = null, array $env = []): void { if ($this->isRunning()) { throw new RuntimeException('Process is already running.'); @@ -304,8 +300,7 @@ public function start(?callable $callback = null, array $env = []) $this->resetProcessData(); $this->starttime = $this->lastOutputTime = microtime(true); $this->callback = $this->buildCallback($callback); - $this->hasCallback = null !== $callback; - $descriptors = $this->getDescriptors(); + $descriptors = $this->getDescriptors(null !== $callback); if ($this->env) { $env += '\\' === \DIRECTORY_SEPARATOR ? array_diff_ukey($this->env, $env, 'strcasecmp') : $this->env; @@ -314,29 +309,25 @@ public function start(?callable $callback = null, array $env = []) $env += '\\' === \DIRECTORY_SEPARATOR ? array_diff_ukey($this->getDefaultEnv(), $env, 'strcasecmp') : $this->getDefaultEnv(); if (\is_array($commandline = $this->commandline)) { - $commandline = implode(' ', array_map([$this, 'escapeArgument'], $commandline)); - - if ('\\' !== \DIRECTORY_SEPARATOR) { - // exec is mandatory to deal with sending a signal to the process - $commandline = 'exec '.$commandline; - } + $commandline = array_values(array_map(strval(...), $commandline)); } else { $commandline = $this->replacePlaceholders($commandline, $env); } if ('\\' === \DIRECTORY_SEPARATOR) { $commandline = $this->prepareWindowsCommandLine($commandline, $env); - } elseif (!$this->useFileHandles && $this->isSigchildEnabled()) { + } elseif ($this->isSigchildEnabled()) { // last exit code is output on the fourth pipe and caught to work around --enable-sigchild $descriptors[3] = ['pipe', 'w']; + if (\is_array($commandline)) { + // exec is mandatory to deal with sending a signal to the process + $commandline = 'exec '.$this->buildShellCommandline($commandline); + } + // See https://unix.stackexchange.com/questions/71205/background-process-pipe-input $commandline = '{ ('.$commandline.') <&3 3<&- 3>/dev/null & } 3<&0;'; $commandline .= 'pid=$!; echo $pid >&3; wait $pid 2>/dev/null; code=$?; echo $code >&3; exit $code'; - - // Workaround for the bug, when PTS functionality is enabled. - // @see : https://bugs.php.net/69442 - $ptsWorkaround = fopen(__FILE__, 'r'); } $envPairs = []; @@ -350,11 +341,41 @@ public function start(?callable $callback = null, array $env = []) throw new RuntimeException(sprintf('The provided cwd "%s" does not exist.', $this->cwd)); } - $this->process = @proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $envPairs, $this->options); + $lastError = null; + set_error_handler(function ($type, $msg) use (&$lastError) { + $lastError = $msg; + + return true; + }); - if (!\is_resource($this->process)) { - throw new RuntimeException('Unable to launch a new process.'); + $oldMask = []; + + if ($this->ignoredSignals && \function_exists('pcntl_sigprocmask')) { + // we block signals we want to ignore, as proc_open will use fork / posix_spawn which will copy the signal mask this allow to block + // signals in the child process + pcntl_sigprocmask(\SIG_BLOCK, $this->ignoredSignals, $oldMask); } + + try { + $process = @proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $envPairs, $this->options); + + // Ensure array vs string commands behave the same + if (!$process && \is_array($commandline)) { + $process = @proc_open('exec '.$this->buildShellCommandline($commandline), $descriptors, $this->processPipes->pipes, $this->cwd, $envPairs, $this->options); + } + } finally { + if ($this->ignoredSignals && \function_exists('pcntl_sigprocmask')) { + // we restore the signal mask here to avoid any side effects + pcntl_sigprocmask(\SIG_SETMASK, $oldMask); + } + + restore_error_handler(); + } + + if (!$process) { + throw new ProcessStartFailedException($this, $lastError); + } + $this->process = $process; $this->status = self::STATUS_STARTED; if (isset($descriptors[3])) { @@ -377,16 +398,14 @@ public function start(?callable $callback = null, array $env = []) * @param callable|null $callback A PHP callback to run whenever there is some * output available on STDOUT or STDERR * - * @return static - * - * @throws RuntimeException When process can't be launched - * @throws RuntimeException When process is already running + * @throws ProcessStartFailedException When process can't be launched + * @throws RuntimeException When process is already running * * @see start() * * @final */ - public function restart(?callable $callback = null, array $env = []): self + public function restart(?callable $callback = null, array $env = []): static { if ($this->isRunning()) { throw new RuntimeException('Process is already running.'); @@ -413,7 +432,7 @@ public function restart(?callable $callback = null, array $env = []): self * @throws ProcessSignaledException When process stopped after receiving signal * @throws LogicException When process is not yet started */ - public function wait(?callable $callback = null) + public function wait(?callable $callback = null): int { $this->requireProcessIsStarted(__FUNCTION__); @@ -496,7 +515,7 @@ public function waitUntil(callable $callback): bool * * @return int|null The process id if running, null otherwise */ - public function getPid() + public function getPid(): ?int { return $this->isRunning() ? $this->processInformation['pid'] : null; } @@ -512,7 +531,7 @@ public function getPid() * @throws RuntimeException In case --enable-sigchild is activated and the process can't be killed * @throws RuntimeException In case of failure */ - public function signal(int $signal) + public function signal(int $signal): static { $this->doSignal($signal, true); @@ -527,7 +546,7 @@ public function signal(int $signal) * @throws RuntimeException In case the process is already running * @throws LogicException if an idle timeout is set */ - public function disableOutput() + public function disableOutput(): static { if ($this->isRunning()) { throw new RuntimeException('Disabling output while the process is running is not possible.'); @@ -548,7 +567,7 @@ public function disableOutput() * * @throws RuntimeException In case the process is already running */ - public function enableOutput() + public function enableOutput(): static { if ($this->isRunning()) { throw new RuntimeException('Enabling output while the process is running is not possible.'); @@ -561,10 +580,8 @@ public function enableOutput() /** * Returns true in case the output is disabled, false otherwise. - * - * @return bool */ - public function isOutputDisabled() + public function isOutputDisabled(): bool { return $this->outputDisabled; } @@ -572,12 +589,10 @@ public function isOutputDisabled() /** * Returns the current output of the process (STDOUT). * - * @return string - * * @throws LogicException in case the output has been disabled * @throws LogicException In case the process is not started */ - public function getOutput() + public function getOutput(): string { $this->readPipesForOutput(__FUNCTION__); @@ -594,12 +609,10 @@ public function getOutput() * In comparison with the getOutput method which always return the whole * output, this one returns the new output since the last call. * - * @return string - * * @throws LogicException in case the output has been disabled * @throws LogicException In case the process is not started */ - public function getIncrementalOutput() + public function getIncrementalOutput(): string { $this->readPipesForOutput(__FUNCTION__); @@ -623,8 +636,7 @@ public function getIncrementalOutput() * @throws LogicException in case the output has been disabled * @throws LogicException In case the process is not started */ - #[\ReturnTypeWillChange] - public function getIterator(int $flags = 0) + public function getIterator(int $flags = 0): \Generator { $this->readPipesForOutput(__FUNCTION__, false); @@ -676,7 +688,7 @@ public function getIterator(int $flags = 0) * * @return $this */ - public function clearOutput() + public function clearOutput(): static { ftruncate($this->stdout, 0); fseek($this->stdout, 0); @@ -688,12 +700,10 @@ public function clearOutput() /** * Returns the current error output of the process (STDERR). * - * @return string - * * @throws LogicException in case the output has been disabled * @throws LogicException In case the process is not started */ - public function getErrorOutput() + public function getErrorOutput(): string { $this->readPipesForOutput(__FUNCTION__); @@ -711,12 +721,10 @@ public function getErrorOutput() * whole error output, this one returns the new error output since the last * call. * - * @return string - * * @throws LogicException in case the output has been disabled * @throws LogicException In case the process is not started */ - public function getIncrementalErrorOutput() + public function getIncrementalErrorOutput(): string { $this->readPipesForOutput(__FUNCTION__); @@ -735,7 +743,7 @@ public function getIncrementalErrorOutput() * * @return $this */ - public function clearErrorOutput() + public function clearErrorOutput(): static { ftruncate($this->stderr, 0); fseek($this->stderr, 0); @@ -749,7 +757,7 @@ public function clearErrorOutput() * * @return int|null The exit status code, null if the Process is not terminated */ - public function getExitCode() + public function getExitCode(): ?int { $this->updateStatus(false); @@ -767,7 +775,7 @@ public function getExitCode() * @see http://tldp.org/LDP/abs/html/exitcodes.html * @see http://en.wikipedia.org/wiki/Unix_signal */ - public function getExitCodeText() + public function getExitCodeText(): ?string { if (null === $exitcode = $this->getExitCode()) { return null; @@ -778,10 +786,8 @@ public function getExitCodeText() /** * Checks if the process ended successfully. - * - * @return bool */ - public function isSuccessful() + public function isSuccessful(): bool { return 0 === $this->getExitCode(); } @@ -791,11 +797,9 @@ public function isSuccessful() * * It always returns false on Windows. * - * @return bool - * * @throws LogicException In case the process is not terminated */ - public function hasBeenSignaled() + public function hasBeenSignaled(): bool { $this->requireProcessIsTerminated(__FUNCTION__); @@ -807,12 +811,10 @@ public function hasBeenSignaled() * * It is only meaningful if hasBeenSignaled() returns true. * - * @return int - * * @throws RuntimeException In case --enable-sigchild is activated * @throws LogicException In case the process is not terminated */ - public function getTermSignal() + public function getTermSignal(): int { $this->requireProcessIsTerminated(__FUNCTION__); @@ -828,11 +830,9 @@ public function getTermSignal() * * It always returns false on Windows. * - * @return bool - * * @throws LogicException In case the process is not terminated */ - public function hasBeenStopped() + public function hasBeenStopped(): bool { $this->requireProcessIsTerminated(__FUNCTION__); @@ -844,11 +844,9 @@ public function hasBeenStopped() * * It is only meaningful if hasBeenStopped() returns true. * - * @return int - * * @throws LogicException In case the process is not terminated */ - public function getStopSignal() + public function getStopSignal(): int { $this->requireProcessIsTerminated(__FUNCTION__); @@ -857,10 +855,8 @@ public function getStopSignal() /** * Checks if the process is currently running. - * - * @return bool */ - public function isRunning() + public function isRunning(): bool { if (self::STATUS_STARTED !== $this->status) { return false; @@ -873,20 +869,16 @@ public function isRunning() /** * Checks if the process has been started with no regard to the current state. - * - * @return bool */ - public function isStarted() + public function isStarted(): bool { return self::STATUS_READY != $this->status; } /** * Checks if the process is terminated. - * - * @return bool */ - public function isTerminated() + public function isTerminated(): bool { $this->updateStatus(false); @@ -897,10 +889,8 @@ public function isTerminated() * Gets the process status. * * The status is one of: ready, started, terminated. - * - * @return string */ - public function getStatus() + public function getStatus(): string { $this->updateStatus(false); @@ -915,7 +905,7 @@ public function getStatus() * * @return int|null The exit-code of the process or null if it's not running */ - public function stop(float $timeout = 10, ?int $signal = null) + public function stop(float $timeout = 10, ?int $signal = null): ?int { $timeoutMicro = microtime(true) + $timeout; if ($this->isRunning()) { @@ -949,7 +939,7 @@ public function stop(float $timeout = 10, ?int $signal = null) * * @internal */ - public function addOutput(string $line) + public function addOutput(string $line): void { $this->lastOutputTime = microtime(true); @@ -963,7 +953,7 @@ public function addOutput(string $line) * * @internal */ - public function addErrorOutput(string $line) + public function addErrorOutput(string $line): void { $this->lastOutputTime = microtime(true); @@ -982,30 +972,24 @@ public function getLastOutputTime(): ?float /** * Gets the command line to be executed. - * - * @return string */ - public function getCommandLine() + public function getCommandLine(): string { - return \is_array($this->commandline) ? implode(' ', array_map([$this, 'escapeArgument'], $this->commandline)) : $this->commandline; + return $this->buildShellCommandline($this->commandline); } /** * Gets the process timeout in seconds (max. runtime). - * - * @return float|null */ - public function getTimeout() + public function getTimeout(): ?float { return $this->timeout; } /** * Gets the process idle timeout in seconds (max. time since last output). - * - * @return float|null */ - public function getIdleTimeout() + public function getIdleTimeout(): ?float { return $this->idleTimeout; } @@ -1019,7 +1003,7 @@ public function getIdleTimeout() * * @throws InvalidArgumentException if the timeout is negative */ - public function setTimeout(?float $timeout) + public function setTimeout(?float $timeout): static { $this->timeout = $this->validateTimeout($timeout); @@ -1036,7 +1020,7 @@ public function setTimeout(?float $timeout) * @throws LogicException if the output is disabled * @throws InvalidArgumentException if the timeout is negative */ - public function setIdleTimeout(?float $timeout) + public function setIdleTimeout(?float $timeout): static { if (null !== $timeout && $this->outputDisabled) { throw new LogicException('Idle timeout cannot be set while the output is disabled.'); @@ -1054,7 +1038,7 @@ public function setIdleTimeout(?float $timeout) * * @throws RuntimeException In case the TTY mode is not supported */ - public function setTty(bool $tty) + public function setTty(bool $tty): static { if ('\\' === \DIRECTORY_SEPARATOR && $tty) { throw new RuntimeException('TTY mode is not supported on Windows platform.'); @@ -1071,10 +1055,8 @@ public function setTty(bool $tty) /** * Checks if the TTY mode is enabled. - * - * @return bool */ - public function isTty() + public function isTty(): bool { return $this->tty; } @@ -1084,7 +1066,7 @@ public function isTty() * * @return $this */ - public function setPty(bool $bool) + public function setPty(bool $bool): static { $this->pty = $bool; @@ -1093,20 +1075,16 @@ public function setPty(bool $bool) /** * Returns PTY state. - * - * @return bool */ - public function isPty() + public function isPty(): bool { return $this->pty; } /** * Gets the working directory. - * - * @return string|null */ - public function getWorkingDirectory() + public function getWorkingDirectory(): ?string { if (null === $this->cwd) { // getcwd() will return false if any one of the parent directories does not have @@ -1122,7 +1100,7 @@ public function getWorkingDirectory() * * @return $this */ - public function setWorkingDirectory(string $cwd) + public function setWorkingDirectory(string $cwd): static { $this->cwd = $cwd; @@ -1131,10 +1109,8 @@ public function setWorkingDirectory(string $cwd) /** * Gets the environment variables. - * - * @return array */ - public function getEnv() + public function getEnv(): array { return $this->env; } @@ -1146,7 +1122,7 @@ public function getEnv() * * @return $this */ - public function setEnv(array $env) + public function setEnv(array $env): static { $this->env = $env; @@ -1168,13 +1144,13 @@ public function getInput() * * This content will be passed to the underlying process standard input. * - * @param string|int|float|bool|resource|\Traversable|null $input The content + * @param string|resource|\Traversable|self|null $input The content * * @return $this * * @throws LogicException In case the process is running */ - public function setInput($input) + public function setInput(mixed $input): static { if ($this->isRunning()) { throw new LogicException('Input cannot be set while the process is running.'); @@ -1193,7 +1169,7 @@ public function setInput($input) * * @throws ProcessTimedOutException In case the timeout was reached */ - public function checkTimeout() + public function checkTimeout(): void { if (self::STATUS_STARTED !== $this->status) { return; @@ -1232,7 +1208,7 @@ public function getStartTime(): float * Enabling the "create_new_console" option allows a subprocess to continue * to run after the main process exited, on both Windows and *nix */ - public function setOptions(array $options) + public function setOptions(array $options): void { if ($this->isRunning()) { throw new RuntimeException('Setting options while the process is running is not possible.'); @@ -1250,6 +1226,20 @@ public function setOptions(array $options) } } + /** + * Defines a list of posix signals that will not be propagated to the process. + * + * @param list<\SIG*> $signals + */ + public function setIgnoredSignals(array $signals): void + { + if ($this->isRunning()) { + throw new RuntimeException('Setting ignored signals while the process is running is not possible.'); + } + + $this->ignoredSignals = $signals; + } + /** * Returns whether TTY is supported on the current operating system. */ @@ -1257,19 +1247,13 @@ public static function isTtySupported(): bool { static $isTtySupported; - if (null === $isTtySupported) { - $isTtySupported = (bool) @proc_open('echo 1 >/dev/null', [['file', '/dev/tty', 'r'], ['file', '/dev/tty', 'w'], ['file', '/dev/tty', 'w']], $pipes); - } - - return $isTtySupported; + return $isTtySupported ??= ('/' === \DIRECTORY_SEPARATOR && stream_isatty(\STDOUT) && @is_writable('/dev/tty')); } /** * Returns whether PTY is supported on the current operating system. - * - * @return bool */ - public static function isPtySupported() + public static function isPtySupported(): bool { static $result; @@ -1287,15 +1271,15 @@ public static function isPtySupported() /** * Creates the descriptors needed by the proc_open. */ - private function getDescriptors(): array + private function getDescriptors(bool $hasCallback): array { if ($this->input instanceof \Iterator) { $this->input->rewind(); } if ('\\' === \DIRECTORY_SEPARATOR) { - $this->processPipes = new WindowsPipes($this->input, !$this->outputDisabled || $this->hasCallback); + $this->processPipes = new WindowsPipes($this->input, !$this->outputDisabled || $hasCallback); } else { - $this->processPipes = new UnixPipes($this->isTty(), $this->isPty(), $this->input, !$this->outputDisabled || $this->hasCallback); + $this->processPipes = new UnixPipes($this->isTty(), $this->isPty(), $this->input, !$this->outputDisabled || $hasCallback); } return $this->processPipes->getDescriptors(); @@ -1308,15 +1292,11 @@ private function getDescriptors(): array * the user callback (if present) with the received output. * * @param callable|null $callback The user defined PHP callback - * - * @return \Closure */ - protected function buildCallback(?callable $callback = null) + protected function buildCallback(?callable $callback = null): \Closure { if ($this->outputDisabled) { - return function ($type, $data) use ($callback): bool { - return null !== $callback && $callback($type, $data); - }; + return fn ($type, $data): bool => null !== $callback && $callback($type, $data); } $out = self::OUT; @@ -1337,7 +1317,7 @@ protected function buildCallback(?callable $callback = null) * * @param bool $blocking Whether to use a blocking read call */ - protected function updateStatus(bool $blocking) + protected function updateStatus(bool $blocking): void { if (self::STATUS_STARTED !== $this->status) { return; @@ -1372,10 +1352,8 @@ protected function updateStatus(bool $blocking) /** * Returns whether PHP has been compiled with the '--enable-sigchild' option or not. - * - * @return bool */ - protected function isSigchildEnabled() + protected function isSigchildEnabled(): bool { if (null !== self::$sigchild) { return self::$sigchild; @@ -1399,7 +1377,7 @@ protected function isSigchildEnabled() * * @throws LogicException in case output has been disabled or process is not started */ - private function readPipesForOutput(string $caller, bool $blocking = false) + private function readPipesForOutput(string $caller, bool $blocking = false): void { if ($this->outputDisabled) { throw new LogicException('Output has been disabled.'); @@ -1434,7 +1412,7 @@ private function validateTimeout(?float $timeout): ?float * @param bool $blocking Whether to use blocking calls or not * @param bool $close Whether to close file handles or not */ - private function readPipes(bool $blocking, bool $close) + private function readPipes(bool $blocking, bool $close): void { $result = $this->processPipes->readAndWrite($blocking, $close); @@ -1456,8 +1434,9 @@ private function readPipes(bool $blocking, bool $close) private function close(): int { $this->processPipes->close(); - if (\is_resource($this->process)) { + if ($this->process) { proc_close($this->process); + $this->process = null; } $this->exitcode = $this->processInformation['exitcode']; $this->status = self::STATUS_TERMINATED; @@ -1483,13 +1462,13 @@ private function close(): int /** * Resets data related to the latest run of the process. */ - private function resetProcessData() + private function resetProcessData(): void { $this->starttime = null; $this->callback = null; $this->exitcode = null; $this->fallbackStatus = []; - $this->processInformation = null; + $this->processInformation = []; $this->stdout = fopen('php://temp/maxmemory:'.(1024 * 1024), 'w+'); $this->stderr = fopen('php://temp/maxmemory:'.(1024 * 1024), 'w+'); $this->process = null; @@ -1511,6 +1490,11 @@ private function resetProcessData() */ private function doSignal(int $signal, bool $throwException): bool { + // Signal seems to be send when sigchild is enable, this allow blocking the signal correctly in this case + if ($this->isSigchildEnabled() && \in_array($signal, $this->ignoredSignals)) { + return false; + } + if (null === $pid = $this->getPid()) { if ($throwException) { throw new LogicException('Cannot send signal on a non running process.'); @@ -1553,11 +1537,19 @@ private function doSignal(int $signal, bool $throwException): bool return true; } - private function prepareWindowsCommandLine(string $cmd, array &$env): string + private function buildShellCommandline(string|array $commandline): string + { + if (\is_string($commandline)) { + return $commandline; + } + + return implode(' ', array_map($this->escapeArgument(...), $commandline)); + } + + private function prepareWindowsCommandLine(string|array $cmd, array &$env): string { + $cmd = $this->buildShellCommandline($cmd); $uid = uniqid('', true); - $varCount = 0; - $varCache = []; $cmd = preg_replace_callback( '/"(?:( [^"%!^]*+ @@ -1566,7 +1558,9 @@ private function prepareWindowsCommandLine(string $cmd, array &$env): string [^"%!^]*+ )++ ) | [^"]*+ )"/x', - function ($m) use (&$env, &$varCache, &$varCount, $uid) { + function ($m) use (&$env, $uid) { + static $varCount = 0; + static $varCache = []; if (!isset($m[1])) { return $m[0]; } @@ -1604,7 +1598,7 @@ function ($m) use (&$env, &$varCache, &$varCount, $uid) { * * @throws LogicException if the process has not run */ - private function requireProcessIsStarted(string $functionName) + private function requireProcessIsStarted(string $functionName): void { if (!$this->isStarted()) { throw new LogicException(sprintf('Process must be started before calling "%s()".', $functionName)); @@ -1616,7 +1610,7 @@ private function requireProcessIsStarted(string $functionName) * * @throws LogicException if the process is not yet terminated */ - private function requireProcessIsTerminated(string $functionName) + private function requireProcessIsTerminated(string $functionName): void { if (!$this->isTerminated()) { throw new LogicException(sprintf('Process must be terminated before calling "%s()".', $functionName)); @@ -1645,7 +1639,7 @@ private function escapeArgument(?string $argument): string return '"'.str_replace(['"', '^', '%', '!', "\n"], ['""', '"^^"', '"^%"', '"^!"', '!LF!'], $argument).'"'; } - private function replacePlaceholders(string $commandline, array $env) + private function replacePlaceholders(string $commandline, array $env): string { return preg_replace_callback('/"\$\{:([_a-zA-Z]++[_a-zA-Z0-9]*+)\}"/', function ($matches) use ($commandline, $env) { if (!isset($env[$matches[1]]) || false === $env[$matches[1]]) { diff --git a/vendor/symfony/process/ProcessUtils.php b/vendor/symfony/process/ProcessUtils.php index 2a7aff7..092c5cc 100644 --- a/vendor/symfony/process/ProcessUtils.php +++ b/vendor/symfony/process/ProcessUtils.php @@ -35,19 +35,14 @@ private function __construct() * @param string $caller The name of method call that validates the input * @param mixed $input The input to validate * - * @return mixed - * * @throws InvalidArgumentException In case the input is not valid */ - public static function validateInput(string $caller, $input) + public static function validateInput(string $caller, mixed $input): mixed { if (null !== $input) { if (\is_resource($input)) { return $input; } - if (\is_string($input)) { - return $input; - } if (\is_scalar($input)) { return (string) $input; } diff --git a/vendor/symfony/process/README.md b/vendor/symfony/process/README.md index 8777de4..afce5e4 100644 --- a/vendor/symfony/process/README.md +++ b/vendor/symfony/process/README.md @@ -3,17 +3,6 @@ Process Component The Process component executes commands in sub-processes. -Sponsor -------- - -The Process component for Symfony 5.4/6.0 is [backed][1] by [SensioLabs][2]. - -As the creator of Symfony, SensioLabs supports companies using Symfony, with an -offering encompassing consultancy, expertise, services, training, and technical -assistance to ensure the success of web application development projects. - -Help Symfony by [sponsoring][3] its development! - Resources --------- @@ -22,7 +11,3 @@ Resources * [Report issues](https://github.com/symfony/symfony/issues) and [send Pull Requests](https://github.com/symfony/symfony/pulls) in the [main Symfony repository](https://github.com/symfony/symfony) - -[1]: https://symfony.com/backers -[2]: https://sensiolabs.com -[3]: https://symfony.com/sponsor diff --git a/vendor/symfony/process/composer.json b/vendor/symfony/process/composer.json index 1669eba..dda5575 100644 --- a/vendor/symfony/process/composer.json +++ b/vendor/symfony/process/composer.json @@ -16,8 +16,7 @@ } ], "require": { - "php": ">=7.2.5", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.2" }, "autoload": { "psr-4": { "Symfony\\Component\\Process\\": "" }, diff --git a/vendor/symfony/service-contracts/Attribute/SubscribedService.php b/vendor/symfony/service-contracts/Attribute/SubscribedService.php index d98e1df..f850b84 100644 --- a/vendor/symfony/service-contracts/Attribute/SubscribedService.php +++ b/vendor/symfony/service-contracts/Attribute/SubscribedService.php @@ -11,15 +11,15 @@ namespace Symfony\Contracts\Service\Attribute; +use Symfony\Contracts\Service\ServiceMethodsSubscriberTrait; use Symfony\Contracts\Service\ServiceSubscriberInterface; -use Symfony\Contracts\Service\ServiceSubscriberTrait; /** * For use as the return value for {@see ServiceSubscriberInterface}. * * @example new SubscribedService('http_client', HttpClientInterface::class, false, new Target('githubApi')) * - * Use with {@see ServiceSubscriberTrait} to mark a method's return type + * Use with {@see ServiceMethodsSubscriberTrait} to mark a method's return type * as a subscribed service. * * @author Kevin Bond diff --git a/vendor/symfony/service-contracts/ServiceCollectionInterface.php b/vendor/symfony/service-contracts/ServiceCollectionInterface.php new file mode 100644 index 0000000..2333139 --- /dev/null +++ b/vendor/symfony/service-contracts/ServiceCollectionInterface.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Service; + +/** + * A ServiceProviderInterface that is also countable and iterable. + * + * @author Kevin Bond + * + * @template-covariant T of mixed + * + * @extends ServiceProviderInterface + * @extends \IteratorAggregate + */ +interface ServiceCollectionInterface extends ServiceProviderInterface, \Countable, \IteratorAggregate +{ +} diff --git a/vendor/symfony/service-contracts/ServiceMethodsSubscriberTrait.php b/vendor/symfony/service-contracts/ServiceMethodsSubscriberTrait.php new file mode 100644 index 0000000..0d89d9f --- /dev/null +++ b/vendor/symfony/service-contracts/ServiceMethodsSubscriberTrait.php @@ -0,0 +1,80 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Service; + +use Psr\Container\ContainerInterface; +use Symfony\Contracts\Service\Attribute\Required; +use Symfony\Contracts\Service\Attribute\SubscribedService; + +/** + * Implementation of ServiceSubscriberInterface that determines subscribed services + * from methods that have the #[SubscribedService] attribute. + * + * Service ids are available as "ClassName::methodName" so that the implementation + * of subscriber methods can be just `return $this->container->get(__METHOD__);`. + * + * @author Kevin Bond + */ +trait ServiceMethodsSubscriberTrait +{ + protected ContainerInterface $container; + + public static function getSubscribedServices(): array + { + $services = method_exists(get_parent_class(self::class) ?: '', __FUNCTION__) ? parent::getSubscribedServices() : []; + + foreach ((new \ReflectionClass(self::class))->getMethods() as $method) { + if (self::class !== $method->getDeclaringClass()->name) { + continue; + } + + if (!$attribute = $method->getAttributes(SubscribedService::class)[0] ?? null) { + continue; + } + + if ($method->isStatic() || $method->isAbstract() || $method->isGenerator() || $method->isInternal() || $method->getNumberOfRequiredParameters()) { + throw new \LogicException(sprintf('Cannot use "%s" on method "%s::%s()" (can only be used on non-static, non-abstract methods with no parameters).', SubscribedService::class, self::class, $method->name)); + } + + if (!$returnType = $method->getReturnType()) { + throw new \LogicException(sprintf('Cannot use "%s" on methods without a return type in "%s::%s()".', SubscribedService::class, $method->name, self::class)); + } + + /* @var SubscribedService $attribute */ + $attribute = $attribute->newInstance(); + $attribute->key ??= self::class.'::'.$method->name; + $attribute->type ??= $returnType instanceof \ReflectionNamedType ? $returnType->getName() : (string) $returnType; + $attribute->nullable = $returnType->allowsNull(); + + if ($attribute->attributes) { + $services[] = $attribute; + } else { + $services[$attribute->key] = ($attribute->nullable ? '?' : '').$attribute->type; + } + } + + return $services; + } + + #[Required] + public function setContainer(ContainerInterface $container): ?ContainerInterface + { + $ret = null; + if (method_exists(get_parent_class(self::class) ?: '', __FUNCTION__)) { + $ret = parent::setContainer($container); + } + + $this->container = $container; + + return $ret; + } +} diff --git a/vendor/symfony/service-contracts/ServiceSubscriberTrait.php b/vendor/symfony/service-contracts/ServiceSubscriberTrait.php index f3b450c..cc3bc32 100644 --- a/vendor/symfony/service-contracts/ServiceSubscriberTrait.php +++ b/vendor/symfony/service-contracts/ServiceSubscriberTrait.php @@ -15,17 +15,23 @@ use Symfony\Contracts\Service\Attribute\Required; use Symfony\Contracts\Service\Attribute\SubscribedService; +trigger_deprecation('symfony/contracts', 'v3.5', '"%s" is deprecated, use "ServiceMethodsSubscriberTrait" instead.', ServiceSubscriberTrait::class); + /** - * Implementation of ServiceSubscriberInterface that determines subscribed services from - * method return types. Service ids are available as "ClassName::methodName". + * Implementation of ServiceSubscriberInterface that determines subscribed services + * from methods that have the #[SubscribedService] attribute. + * + * Service ids are available as "ClassName::methodName" so that the implementation + * of subscriber methods can be just `return $this->container->get(__METHOD__);`. + * + * @property ContainerInterface $container * * @author Kevin Bond + * + * @deprecated since symfony/contracts v3.5, use ServiceMethodsSubscriberTrait instead */ trait ServiceSubscriberTrait { - /** @var ContainerInterface */ - protected $container; - public static function getSubscribedServices(): array { $services = method_exists(get_parent_class(self::class) ?: '', __FUNCTION__) ? parent::getSubscribedServices() : []; diff --git a/vendor/symfony/service-contracts/composer.json b/vendor/symfony/service-contracts/composer.json index 32bb8a3..fc8674a 100644 --- a/vendor/symfony/service-contracts/composer.json +++ b/vendor/symfony/service-contracts/composer.json @@ -17,7 +17,8 @@ ], "require": { "php": ">=8.1", - "psr/container": "^1.1|^2.0" + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" }, "conflict": { "ext-psr": "<1.1|>=2" @@ -31,7 +32,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", diff --git a/vendor/symfony/string/AbstractString.php b/vendor/symfony/string/AbstractString.php index f55c721..253d2dc 100644 --- a/vendor/symfony/string/AbstractString.php +++ b/vendor/symfony/string/AbstractString.php @@ -39,8 +39,8 @@ abstract class AbstractString implements \Stringable, \JsonSerializable public const PREG_SPLIT_DELIM_CAPTURE = \PREG_SPLIT_DELIM_CAPTURE; public const PREG_SPLIT_OFFSET_CAPTURE = \PREG_SPLIT_OFFSET_CAPTURE; - protected $string = ''; - protected $ignoreCase = false; + protected string $string = ''; + protected ?bool $ignoreCase = false; abstract public function __construct(string $string = ''); diff --git a/vendor/symfony/string/AbstractUnicodeString.php b/vendor/symfony/string/AbstractUnicodeString.php index 673ad8c..2cb2917 100644 --- a/vendor/symfony/string/AbstractUnicodeString.php +++ b/vendor/symfony/string/AbstractUnicodeString.php @@ -155,7 +155,7 @@ public function ascii(array $rules = []): self public function camel(): static { $str = clone $this; - $str->string = str_replace(' ', '', preg_replace_callback('/\b.(?![A-Z]{2,})/u', static function ($m) { + $str->string = str_replace(' ', '', preg_replace_callback('/\b.(?!\p{Lu})/u', static function ($m) { static $i = 0; return 1 === ++$i ? ('İ' === $m[0] ? 'i̇' : mb_strtolower($m[0], 'UTF-8')) : mb_convert_case($m[0], \MB_CASE_TITLE, 'UTF-8'); @@ -190,7 +190,7 @@ public function folded(bool $compat = true): static if (!$compat || !\defined('Normalizer::NFKC_CF')) { $str->string = normalizer_normalize($str->string, $compat ? \Normalizer::NFKC : \Normalizer::NFC); - $str->string = mb_strtolower(str_replace(self::FOLD_FROM, self::FOLD_TO, $this->string), 'UTF-8'); + $str->string = mb_strtolower(str_replace(self::FOLD_FROM, self::FOLD_TO, $str->string), 'UTF-8'); } else { $str->string = normalizer_normalize($str->string, \Normalizer::NFKC_CF); } @@ -220,6 +220,21 @@ public function lower(): static return $str; } + /** + * @param string $locale In the format language_region (e.g. tr_TR) + */ + public function localeLower(string $locale): static + { + if (null !== $transliterator = $this->getLocaleTransliterator($locale, 'Lower')) { + $str = clone $this; + $str->string = $transliterator->transliterate($str->string); + + return $str; + } + + return $this->lower(); + } + public function match(string $regexp, int $flags = 0, int $offset = 0): array { $match = ((\PREG_PATTERN_ORDER | \PREG_SET_ORDER) & $flags) ? 'preg_match_all' : 'preg_match'; @@ -363,6 +378,21 @@ public function title(bool $allWords = false): static return $str; } + /** + * @param string $locale In the format language_region (e.g. tr_TR) + */ + public function localeTitle(string $locale): static + { + if (null !== $transliterator = $this->getLocaleTransliterator($locale, 'Title')) { + $str = clone $this; + $str->string = $transliterator->transliterate($str->string); + + return $str; + } + + return $this->title(); + } + public function trim(string $chars = " \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}"): static { if (" \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}" !== $chars && !preg_match('//u', $chars)) { @@ -450,6 +480,21 @@ public function upper(): static return $str; } + /** + * @param string $locale In the format language_region (e.g. tr_TR) + */ + public function localeUpper(string $locale): static + { + if (null !== $transliterator = $this->getLocaleTransliterator($locale, 'Upper')) { + $str = clone $this; + $str->string = $transliterator->transliterate($str->string); + + return $str; + } + + return $this->upper(); + } + public function width(bool $ignoreAnsiDecoration = true): int { $width = 0; @@ -587,4 +632,33 @@ private function wcswidth(string $string): int return $width; } + + private function getLocaleTransliterator(string $locale, string $id): ?\Transliterator + { + $rule = $locale.'-'.$id; + if (\array_key_exists($rule, self::$transliterators)) { + return self::$transliterators[$rule]; + } + + if (null !== $transliterator = self::$transliterators[$rule] = \Transliterator::create($rule)) { + return $transliterator; + } + + // Try to find a parent locale (nl_BE -> nl) + if (false === $i = strpos($locale, '_')) { + return null; + } + + $parentRule = substr_replace($locale, '-'.$id, $i); + + // Parent locale was already cached, return and store as current locale + if (\array_key_exists($parentRule, self::$transliterators)) { + return self::$transliterators[$rule] = self::$transliterators[$parentRule]; + } + + // Create transliterator based on parent locale and cache the result on both initial and parent locale values + $transliterator = \Transliterator::create($parentRule); + + return self::$transliterators[$rule] = self::$transliterators[$parentRule] = $transliterator; + } } diff --git a/vendor/symfony/string/ByteString.php b/vendor/symfony/string/ByteString.php index 3ebe43c..e6b56ae 100644 --- a/vendor/symfony/string/ByteString.php +++ b/vendor/symfony/string/ByteString.php @@ -11,6 +11,7 @@ namespace Symfony\Component\String; +use Random\Randomizer; use Symfony\Component\String\Exception\ExceptionInterface; use Symfony\Component\String\Exception\InvalidArgumentException; use Symfony\Component\String\Exception\RuntimeException; @@ -55,6 +56,10 @@ public static function fromRandom(int $length = 16, ?string $alphabet = null): s throw new InvalidArgumentException('The length of the alphabet must in the [2^1, 2^56] range.'); } + if (\PHP_VERSION_ID >= 80300) { + return new static((new Randomizer())->getBytesFromString($alphabet, $length)); + } + $ret = ''; while ($length > 0) { $urandomLength = (int) ceil(2 * $length * $bits / 8.0); diff --git a/vendor/symfony/string/CHANGELOG.md b/vendor/symfony/string/CHANGELOG.md index 31a3b54..621cedf 100644 --- a/vendor/symfony/string/CHANGELOG.md +++ b/vendor/symfony/string/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +7.1 +--- + + * Add `localeLower()`, `localeUpper()`, `localeTitle()` methods to `AbstractUnicodeString` + 6.2 --- diff --git a/vendor/symfony/string/Inflector/EnglishInflector.php b/vendor/symfony/string/Inflector/EnglishInflector.php index dc7b08e..c41bade 100644 --- a/vendor/symfony/string/Inflector/EnglishInflector.php +++ b/vendor/symfony/string/Inflector/EnglishInflector.php @@ -25,8 +25,35 @@ final class EnglishInflector implements InflectorInterface // Fourth entry: Whether the suffix may succeed a consonant // Fifth entry: singular suffix, normal - // bacteria (bacterium), criteria (criterion), phenomena (phenomenon) - ['a', 1, true, true, ['on', 'um']], + // bacteria (bacterium) + ['airetcab', 8, true, true, 'bacterium'], + + // corpora (corpus) + ['aroproc', 7, true, true, 'corpus'], + + // criteria (criterion) + ['airetirc', 8, true, true, 'criterion'], + + // curricula (curriculum) + ['alucirruc', 9, true, true, 'curriculum'], + + // quora (quorum) + ['arouq', 5, true, true, 'quorum'], + + // genera (genus) + ['areneg', 6, true, true, 'genus'], + + // media (medium) + ['aidem', 5, true, true, 'medium'], + + // memoranda (memorandum) + ['adnaromem', 9, true, true, 'memorandum'], + + // phenomena (phenomenon) + ['anemonehp', 9, true, true, 'phenomenon'], + + // strata (stratum) + ['atarts', 6, true, true, 'stratum'], // nebulae (nebula) ['ea', 2, true, true, 'a'], @@ -97,6 +124,9 @@ final class EnglishInflector implements InflectorInterface // statuses (status) ['sesutats', 8, true, true, 'status'], + // article (articles), ancle (ancles) + ['sel', 3, true, true, 'le'], + // analyses (analysis), ellipses (ellipsis), fungi (fungus), // neuroses (neurosis), theses (thesis), emphases (emphasis), // oases (oasis), crises (crisis), houses (house), bases (base), @@ -141,7 +171,7 @@ final class EnglishInflector implements InflectorInterface // shoes (shoe) ['se', 2, true, true, ['', 'e']], - // status (status) + // status (status) ['sutats', 6, true, true, 'status'], // tags (tag) @@ -238,7 +268,13 @@ final class EnglishInflector implements InflectorInterface // teeth (tooth) ['htoot', 5, true, true, 'teeth'], - // bacteria (bacterium), criteria (criterion), phenomena (phenomenon) + // albums (album) + ['mubla', 5, true, true, 'albums'], + + // quorums (quorum) + ['murouq', 6, true, true, ['quora', 'quorums']], + + // bacteria (bacterium), curricula (curriculum), media (medium), memoranda (memorandum), phenomena (phenomenon), strata (stratum) ['mu', 2, true, true, 'a'], // men (man), women (woman) @@ -247,20 +283,11 @@ final class EnglishInflector implements InflectorInterface // people (person) ['nosrep', 6, true, true, ['persons', 'people']], - // bacteria (bacterium), criteria (criterion), phenomena (phenomenon) - ['noi', 3, true, true, 'ions'], - - // coupon (coupons) - ['nop', 3, true, true, 'pons'], + // criteria (criterion) + ['noiretirc', 9, true, true, 'criteria'], - // seasons (season), treasons (treason), poisons (poison), lessons (lesson) - ['nos', 3, true, true, 'sons'], - - // icons (icon) - ['noc', 3, true, true, 'cons'], - - // bacteria (bacterium), criteria (criterion), phenomena (phenomenon) - ['no', 2, true, true, 'a'], + // phenomena (phenomenon) + ['nonemonehp', 10, true, true, 'phenomena'], // echoes (echo) ['ohce', 4, true, true, 'echoes'], @@ -271,6 +298,9 @@ final class EnglishInflector implements InflectorInterface // atlases (atlas) ['salta', 5, true, true, 'atlases'], + // aliases (alias) + ['saila', 5, true, true, 'aliases'], + // irises (iris) ['siri', 4, true, true, 'irises'], @@ -396,6 +426,9 @@ final class EnglishInflector implements InflectorInterface // aircraft 'tfarcria', + + // hardware + 'erawdrah', ]; public function singularize(string $plural): array diff --git a/vendor/symfony/string/LazyString.php b/vendor/symfony/string/LazyString.php index 1af3769..8f2bbbf 100644 --- a/vendor/symfony/string/LazyString.php +++ b/vendor/symfony/string/LazyString.php @@ -129,7 +129,7 @@ private static function getPrettyName(callable $callback): string } elseif ($callback instanceof \Closure) { $r = new \ReflectionFunction($callback); - if (str_contains($r->name, '{closure}') || !$class = \PHP_VERSION_ID >= 80111 ? $r->getClosureCalledClass() : $r->getClosureScopeClass()) { + if ($r->isAnonymous() || !$class = $r->getClosureCalledClass()) { return $r->name; } diff --git a/vendor/symfony/string/Resources/data/wcswidth_table_wide.php b/vendor/symfony/string/Resources/data/wcswidth_table_wide.php index 8314c8f..6a75094 100644 --- a/vendor/symfony/string/Resources/data/wcswidth_table_wide.php +++ b/vendor/symfony/string/Resources/data/wcswidth_table_wide.php @@ -3,8 +3,8 @@ /* * This file has been auto-generated by the Symfony String Component for internal use. * - * Unicode version: 15.1.0 - * Date: 2023-09-13T11:47:12+00:00 + * Unicode version: 16.0.0 + * Date: 2024-09-11T08:21:22+00:00 */ return [ @@ -44,6 +44,10 @@ 9748, 9749, ], + [ + 9776, + 9783, + ], [ 9800, 9811, @@ -52,6 +56,10 @@ 9855, 9855, ], + [ + 9866, + 9871, + ], [ 9875, 9875, @@ -394,7 +402,7 @@ ], [ 12736, - 12771, + 12773, ], [ 12783, @@ -452,6 +460,10 @@ 13312, 19903, ], + [ + 19904, + 19967, + ], [ 19968, 40959, @@ -836,6 +848,10 @@ 101120, 101589, ], + [ + 101631, + 101631, + ], [ 101632, 101640, @@ -880,6 +896,14 @@ 110960, 111355, ], + [ + 119552, + 119638, + ], + [ + 119648, + 119670, + ], [ 126980, 126980, @@ -1054,23 +1078,19 @@ ], [ 129664, - 129672, - ], - [ - 129680, - 129725, + 129673, ], [ - 129727, - 129733, + 129679, + 129734, ], [ 129742, - 129755, + 129756, ], [ - 129760, - 129768, + 129759, + 129769, ], [ 129776, diff --git a/vendor/symfony/string/Resources/data/wcswidth_table_zero.php b/vendor/symfony/string/Resources/data/wcswidth_table_zero.php index e5b26a2..fdd7f3c 100644 --- a/vendor/symfony/string/Resources/data/wcswidth_table_zero.php +++ b/vendor/symfony/string/Resources/data/wcswidth_table_zero.php @@ -3,8 +3,8 @@ /* * This file has been auto-generated by the Symfony String Component for internal use. * - * Unicode version: 15.1.0 - * Date: 2023-09-13T11:47:13+00:00 + * Unicode version: 16.0.0 + * Date: 2024-09-11T08:21:22+00:00 */ return [ @@ -109,7 +109,7 @@ 2139, ], [ - 2200, + 2199, 2207, ], [ @@ -916,12 +916,16 @@ 68900, 68903, ], + [ + 68969, + 68973, + ], [ 69291, 69292, ], [ - 69373, + 69372, 69375, ], [ @@ -1044,6 +1048,26 @@ 70512, 70516, ], + [ + 70587, + 70592, + ], + [ + 70606, + 70606, + ], + [ + 70608, + 70608, + ], + [ + 70610, + 70610, + ], + [ + 70625, + 70626, + ], [ 70712, 70719, @@ -1122,6 +1146,10 @@ ], [ 71453, + 71453, + ], + [ + 71455, 71455, ], [ @@ -1276,6 +1304,10 @@ 73538, 73538, ], + [ + 73562, + 73562, + ], [ 78912, 78912, @@ -1284,6 +1316,14 @@ 78919, 78933, ], + [ + 90398, + 90409, + ], + [ + 90413, + 90415, + ], [ 92912, 92916, @@ -1400,6 +1440,10 @@ 124140, 124143, ], + [ + 124398, + 124399, + ], [ 125136, 125142, diff --git a/vendor/symfony/string/Slugger/AsciiSlugger.php b/vendor/symfony/string/Slugger/AsciiSlugger.php index a9693d4..d254532 100644 --- a/vendor/symfony/string/Slugger/AsciiSlugger.php +++ b/vendor/symfony/string/Slugger/AsciiSlugger.php @@ -11,7 +11,7 @@ namespace Symfony\Component\String\Slugger; -use Symfony\Component\Intl\Transliterator\EmojiTransliterator; +use Symfony\Component\Emoji\EmojiTransliterator; use Symfony\Component\String\AbstractUnicodeString; use Symfony\Component\String\UnicodeString; use Symfony\Contracts\Translation\LocaleAwareInterface; @@ -55,7 +55,6 @@ class AsciiSlugger implements SluggerInterface, LocaleAwareInterface 'zh' => 'Han-Latin', ]; - private ?string $defaultLocale; private \Closure|array $symbolsMap = [ 'en' => ['@' => 'at', '&' => 'and'], ]; @@ -68,16 +67,14 @@ class AsciiSlugger implements SluggerInterface, LocaleAwareInterface */ private array $transliterators = []; - public function __construct(?string $defaultLocale = null, array|\Closure|null $symbolsMap = null) - { - $this->defaultLocale = $defaultLocale; + public function __construct( + private ?string $defaultLocale = null, + array|\Closure|null $symbolsMap = null, + ) { $this->symbolsMap = $symbolsMap ?? $this->symbolsMap; } - /** - * @return void - */ - public function setLocale(string $locale) + public function setLocale(string $locale): void { $this->defaultLocale = $locale; } @@ -95,7 +92,7 @@ public function getLocale(): string public function withEmoji(bool|string $emoji = true): static { if (false !== $emoji && !class_exists(EmojiTransliterator::class)) { - throw new \LogicException(sprintf('You cannot use the "%s()" method as the "symfony/intl" package is not installed. Try running "composer require symfony/intl".', __METHOD__)); + throw new \LogicException(sprintf('You cannot use the "%s()" method as the "symfony/emoji" package is not installed. Try running "composer require symfony/emoji".', __METHOD__)); } $new = clone $this; diff --git a/vendor/symfony/string/UnicodeString.php b/vendor/symfony/string/UnicodeString.php index 75af2da..4b16caf 100644 --- a/vendor/symfony/string/UnicodeString.php +++ b/vendor/symfony/string/UnicodeString.php @@ -362,10 +362,7 @@ public function startsWith(string|iterable|AbstractString $prefix): bool return $prefix === grapheme_extract($this->string, \strlen($prefix), \GRAPHEME_EXTR_MAXBYTES); } - /** - * @return void - */ - public function __wakeup() + public function __wakeup(): void { if (!\is_string($this->string)) { throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); diff --git a/vendor/symfony/string/composer.json b/vendor/symfony/string/composer.json index 56c1368..10d0ee6 100644 --- a/vendor/symfony/string/composer.json +++ b/vendor/symfony/string/composer.json @@ -16,18 +16,19 @@ } ], "require": { - "php": ">=8.1", + "php": ">=8.2", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-intl-grapheme": "~1.0", "symfony/polyfill-intl-normalizer": "~1.0", "symfony/polyfill-mbstring": "~1.0" }, "require-dev": { - "symfony/error-handler": "^5.4|^6.0|^7.0", - "symfony/intl": "^6.2|^7.0", - "symfony/http-client": "^5.4|^6.0|^7.0", + "symfony/error-handler": "^6.4|^7.0", + "symfony/emoji": "^7.1", + "symfony/http-client": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", "symfony/translation-contracts": "^2.5|^3.0", - "symfony/var-exporter": "^5.4|^6.0|^7.0" + "symfony/var-exporter": "^6.4|^7.0" }, "conflict": { "symfony/translation-contracts": "<2.5" diff --git a/views/grunt/build-theme.php b/views/grunt/build-theme.php deleted file mode 100644 index ba07f5a..0000000 --- a/views/grunt/build-theme.php +++ /dev/null @@ -1,73 +0,0 @@ -title = 'Build Theme'; -$this->params['breadcrumbs'][] = $this->title; - -// Register PJAX library -$this->registerJsFile('@web/static/js/jquery.pjax.modified.js', ['position' => View::POS_HEAD]); -?> - -
-
-
- title) ?> -
-
-
-
- - - - -
- - 'run-command-form']); ?> - -
- 'run-command-btn', 'class' => 'btn btn-primary']) ?> -
- - -
-
- -registerJs(' - $(document).on("submit", "#run-command-form", function(event) { - event.preventDefault(); - var $form = $(this); - var $btn = $form.find(":submit"); - var formData = $form.serialize(); - - $btn.button("loading"); - - $.ajax({ - type: "POST", - url: "' . Yii::$app->urlManager->createUrl(['/composer/grunt/build-theme']) . '", - data: formData, - success: function(response) { - if (response.success) { - // Update the container with the command output - $("#output-container").html("

Output

" + Html::encode(response.output.join(\"\\n\")) + "
"); - } else { - console.error(response.error); - } - }, - error: function(xhr, status, error) { - console.error(error); - }, - complete: function() { - $btn.button("reset"); - } - }); - }); -'); -?> diff --git a/views/grunt/index.php b/views/grunt/index.php index 58a5f06..60cd2a5 100644 --- a/views/grunt/index.php +++ b/views/grunt/index.php @@ -1,8 +1,8 @@ - @@ -50,13 +47,6 @@ 'build-assets']) ?> -
- 'form-inline']) ?> - 'form-control', 'placeholder' => 'Theme Name']) ?> - 'btn btn-primary']) ?> - - 'build-theme', 'options' => ['themeName' => Yii::$app->request->post('themeName')]]) ?> -