Sfoglia il codice sorgente

修改c端接口;获取资讯详情

15313670163 5 mesi fa
parent
commit
e61535c12d

+ 56 - 11
app/JsonRpc/NewsService.php

@@ -548,8 +548,8 @@ class NewsService implements NewsServiceInterface
     public function selectWebsiteArticleInfo(array $data): array
     {
         $where = [
-            'article.id' => $data['id'],
-            'article.status' => 1,
+        'article.id' => $data['id'],
+        'article.status' => 1,
         ];
 
         $result = Article::where($where)
@@ -559,15 +559,27 @@ class NewsService implements NewsServiceInterface
             $query->whereRaw("JSON_CONTAINS(ignore_ids, '" . intval($data['website_id']) . "') = 0")
             ->orWhereNull("ignore_ids");
         })
-        ->select('article.*','article_data.content','article_data.article_id',
-            'article_extend.website_url','article_extend.email','article_extend.contacts', 
-            'article_extend.contacts_mobile','article_extend.contacts_address','article_extend.zip_code',
+        ->select(
+            'article.*',
+            'article_data.content',
+            'article_data.article_id',
+            'article_extend.website_url',
+            'article_extend.email',
+            'article_extend.contacts',
+            'article_extend.contacts_mobile',
+            'article_extend.contacts_address',
+            'article_extend.zip_code',
             'article_extend.enterprise_name'
         )
         ->first();
         if (empty($result)) {
         return Result::error("暂无此新闻!", 0);
         }
+        if(!empty($result['publiced_at']))
+        {
+            $result['updated_at'] = $result['publiced_at'];
+        }
+
         $category = WebsiteCategory::leftJoin('website', 'website.id', '=', 'website_category.website_id')
         ->select('website_category.*', 'website.website_name', 'website.suffix')
         ->where('website_category.website_id', $data['website_id'])
@@ -578,17 +590,50 @@ class NewsService implements NewsServiceInterface
         }
         //手动推荐文章
         $commend_ids = $result['commend_id'] ? json_decode($result['commend_id']) : [];
-        $commendArticle = Article::whereIn('id', $commend_ids)
-        ->where('status', 1)
-        ->select('id', 'title', 'catid', 'imgurl', 'hits', 'created_at')
-        ->orderBy('updated_at', 'desc')
-        ->limit(5)
-        ->get();
+        if (empty($commend_ids)) {
+        $commendArticle = [];
+        } else {
+            //去除不存在的文章ID
+            $commendArticle = Article::whereIn('article.id', $commend_ids)
+                ->leftjoin('website_category', 'website_category.category_id', '=', 'article.catid')
+                ->where('article.status', 1)
+                ->where('website_category.website_id', $data['website_id'])
+                ->select('article.id', 'article.cat_arr_id', 'article.title', 'article.catid', 'article.imgurl', 'article.hits', 'article.created_at', 'website_category.alias', 'website_category.alias_pinyin', 'website_category.website_id')
+                ->orderByRaw("FIELD(article.id, " . implode(',', $commend_ids) . ")")
+                // ->orderBy('article.updated_at', 'desc')
+                ->limit(5)
+                ->get();
+            //循环数组,取出cat_arr_id中的不重复值,再从website_category取出alias_pinyin,再将cat_arr_id的json转成路径/隔开
+            foreach ($commendArticle as $k => $v) {
+                $cat_arr_id = json_decode($v->cat_arr_id, true);
+                if (!empty($cat_arr_id) && is_array($cat_arr_id)) {
+                    $cat_arr_id = array_unique($cat_arr_id);
+                    // 从website_category取出alias_pinyin
+                    $cat_arr  = WebsiteCategory::where('website_id', $data['website_id'])
+                        ->whereIn('category_id', $cat_arr_id)
+                        ->pluck('alias_pinyin', 'category_id')
+                        ->toArray();
+
+                    // 将cat_arr_id的json转成路径/隔开
+                    $path_parts = [];
+                    foreach ($cat_arr_id as $cat_id) {
+                        if (isset($cat_arr[$cat_id])) {
+                        $path_parts[] = $cat_arr[$cat_id];
+                        }
+                    }
+                    $v->alias_pinyin = implode('/', $path_parts);
+                } else {
+                    $v->alias_pinyin = '';
+                }
+            }
+        }
+
         $result['category_id'] = $category['category_id'];
         $result['cat_name'] = $category['alias'];
         $result['website_name'] = $category['website_name'] ?? "";
         $result['suffix'] = $category['suffix'] ?? "";
         $result['commendArticle'] = $commendArticle;
+        $result['commend_ids'] = $commend_ids;
         return Result::success($result);
     }
     /**

+ 10 - 0
vendor/composer/autoload_classmap.php

@@ -42,6 +42,7 @@ return array(
     'App\\Model\\WebsiteColumn' => $baseDir . '/app/Model/WebsiteColumn.php',
     'App\\Model\\WebsiteRole' => $baseDir . '/app/Model/WebsiteRole.php',
     'App\\Model\\WebsiteRoleUser' => $baseDir . '/app/Model/WebsiteRoleUser.php',
+    'App\\Model\\WhiteRouter' => $baseDir . '/app/Model/WhiteRouter.php',
     'App\\Tools\\Result' => $baseDir . '/app/Tools/Result.php',
     'Attribute' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
     'CURLStringFile' => $vendorDir . '/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php',
@@ -336,6 +337,7 @@ return array(
     'Fidry\\CpuCoreCounter\\Finder\\CpuCoreFinder' => $vendorDir . '/fidry/cpu-core-counter/src/Finder/CpuCoreFinder.php',
     'Fidry\\CpuCoreCounter\\Finder\\CpuInfoFinder' => $vendorDir . '/fidry/cpu-core-counter/src/Finder/CpuInfoFinder.php',
     'Fidry\\CpuCoreCounter\\Finder\\DummyCpuCoreFinder' => $vendorDir . '/fidry/cpu-core-counter/src/Finder/DummyCpuCoreFinder.php',
+    'Fidry\\CpuCoreCounter\\Finder\\EnvVariableFinder' => $vendorDir . '/fidry/cpu-core-counter/src/Finder/EnvVariableFinder.php',
     'Fidry\\CpuCoreCounter\\Finder\\FinderRegistry' => $vendorDir . '/fidry/cpu-core-counter/src/Finder/FinderRegistry.php',
     'Fidry\\CpuCoreCounter\\Finder\\HwLogicalFinder' => $vendorDir . '/fidry/cpu-core-counter/src/Finder/HwLogicalFinder.php',
     'Fidry\\CpuCoreCounter\\Finder\\HwPhysicalFinder' => $vendorDir . '/fidry/cpu-core-counter/src/Finder/HwPhysicalFinder.php',
@@ -353,6 +355,7 @@ return array(
     'Fidry\\CpuCoreCounter\\Finder\\WmicPhysicalFinder' => $vendorDir . '/fidry/cpu-core-counter/src/Finder/WmicPhysicalFinder.php',
     'Fidry\\CpuCoreCounter\\Finder\\_NProcessorFinder' => $vendorDir . '/fidry/cpu-core-counter/src/Finder/_NProcessorFinder.php',
     'Fidry\\CpuCoreCounter\\NumberOfCpuCoreNotFound' => $vendorDir . '/fidry/cpu-core-counter/src/NumberOfCpuCoreNotFound.php',
+    'Fidry\\CpuCoreCounter\\ParallelisationResult' => $vendorDir . '/fidry/cpu-core-counter/src/ParallelisationResult.php',
     'Fig\\Http\\Message\\RequestMethodInterface' => $vendorDir . '/fig/http-message-util/src/RequestMethodInterface.php',
     'Fig\\Http\\Message\\StatusCodeInterface' => $vendorDir . '/fig/http-message-util/src/StatusCodeInterface.php',
     'GrahamCampbell\\ResultType\\Error' => $vendorDir . '/graham-campbell/result-type/src/Error.php',
@@ -3393,6 +3396,7 @@ return array(
     'PhpCsFixer\\Fixer\\ArrayNotation\\WhitespaceAfterCommaInArrayFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/ArrayNotation/WhitespaceAfterCommaInArrayFixer.php',
     'PhpCsFixer\\Fixer\\ArrayNotation\\YieldFromArrayToYieldsFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/ArrayNotation/YieldFromArrayToYieldsFixer.php',
     'PhpCsFixer\\Fixer\\AttributeNotation\\AttributeEmptyParenthesesFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/AttributeNotation/AttributeEmptyParenthesesFixer.php',
+    'PhpCsFixer\\Fixer\\AttributeNotation\\GeneralAttributeRemoveFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/AttributeNotation/GeneralAttributeRemoveFixer.php',
     'PhpCsFixer\\Fixer\\AttributeNotation\\OrderedAttributesFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/AttributeNotation/OrderedAttributesFixer.php',
     'PhpCsFixer\\Fixer\\Basic\\BracesFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/Basic/BracesFixer.php',
     'PhpCsFixer\\Fixer\\Basic\\BracesPositionFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/Basic/BracesPositionFixer.php',
@@ -3567,6 +3571,7 @@ return array(
     'PhpCsFixer\\Fixer\\PhpUnit\\PhpUnitAssertNewNamesFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitAssertNewNamesFixer.php',
     'PhpCsFixer\\Fixer\\PhpUnit\\PhpUnitAttributesFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitAttributesFixer.php',
     'PhpCsFixer\\Fixer\\PhpUnit\\PhpUnitConstructFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitConstructFixer.php',
+    'PhpCsFixer\\Fixer\\PhpUnit\\PhpUnitDataProviderMethodOrderFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitDataProviderMethodOrderFixer.php',
     'PhpCsFixer\\Fixer\\PhpUnit\\PhpUnitDataProviderNameFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitDataProviderNameFixer.php',
     'PhpCsFixer\\Fixer\\PhpUnit\\PhpUnitDataProviderReturnTypeFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitDataProviderReturnTypeFixer.php',
     'PhpCsFixer\\Fixer\\PhpUnit\\PhpUnitDataProviderStaticFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitDataProviderStaticFixer.php',
@@ -3666,6 +3671,7 @@ return array(
     'PhpCsFixer\\Fixer\\Whitespace\\TypeDeclarationSpacesFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/TypeDeclarationSpacesFixer.php',
     'PhpCsFixer\\Fixer\\Whitespace\\TypesSpacesFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/TypesSpacesFixer.php',
     'PhpCsFixer\\Fixer\\WhitespacesAwareFixerInterface' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/WhitespacesAwareFixerInterface.php',
+    'PhpCsFixer\\Hasher' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Hasher.php',
     'PhpCsFixer\\Indicator\\PhpUnitTestCaseIndicator' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Indicator/PhpUnitTestCaseIndicator.php',
     'PhpCsFixer\\Linter\\CachingLinter' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Linter/CachingLinter.php',
     'PhpCsFixer\\Linter\\Linter' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Linter/Linter.php',
@@ -3711,6 +3717,7 @@ return array(
     'PhpCsFixer\\RuleSet\\Sets\\PHP80MigrationRiskySet' => $vendorDir . '/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHP80MigrationRiskySet.php',
     'PhpCsFixer\\RuleSet\\Sets\\PHP80MigrationSet' => $vendorDir . '/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHP80MigrationSet.php',
     'PhpCsFixer\\RuleSet\\Sets\\PHP81MigrationSet' => $vendorDir . '/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHP81MigrationSet.php',
+    'PhpCsFixer\\RuleSet\\Sets\\PHP82MigrationRiskySet' => $vendorDir . '/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHP82MigrationRiskySet.php',
     'PhpCsFixer\\RuleSet\\Sets\\PHP82MigrationSet' => $vendorDir . '/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHP82MigrationSet.php',
     'PhpCsFixer\\RuleSet\\Sets\\PHP83MigrationSet' => $vendorDir . '/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHP83MigrationSet.php',
     'PhpCsFixer\\RuleSet\\Sets\\PHP84MigrationSet' => $vendorDir . '/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHP84MigrationSet.php',
@@ -3738,6 +3745,8 @@ return array(
     'PhpCsFixer\\RuleSet\\Sets\\PhpCsFixerSet' => $vendorDir . '/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PhpCsFixerSet.php',
     'PhpCsFixer\\RuleSet\\Sets\\SymfonyRiskySet' => $vendorDir . '/friendsofphp/php-cs-fixer/src/RuleSet/Sets/SymfonyRiskySet.php',
     'PhpCsFixer\\RuleSet\\Sets\\SymfonySet' => $vendorDir . '/friendsofphp/php-cs-fixer/src/RuleSet/Sets/SymfonySet.php',
+    'PhpCsFixer\\Runner\\Event\\AnalysisStarted' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Runner/Event/AnalysisStarted.php',
+    'PhpCsFixer\\Runner\\Event\\FileProcessed' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Runner/Event/FileProcessed.php',
     'PhpCsFixer\\Runner\\FileCachingLintingFileIterator' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Runner/FileCachingLintingFileIterator.php',
     'PhpCsFixer\\Runner\\FileFilterIterator' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Runner/FileFilterIterator.php',
     'PhpCsFixer\\Runner\\LintingFileIterator' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Runner/LintingFileIterator.php',
@@ -3777,6 +3786,7 @@ return array(
     'PhpCsFixer\\Tokenizer\\Analyzer\\CommentsAnalyzer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/CommentsAnalyzer.php',
     'PhpCsFixer\\Tokenizer\\Analyzer\\ControlCaseStructuresAnalyzer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/ControlCaseStructuresAnalyzer.php',
     'PhpCsFixer\\Tokenizer\\Analyzer\\DataProviderAnalyzer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/DataProviderAnalyzer.php',
+    'PhpCsFixer\\Tokenizer\\Analyzer\\FullyQualifiedNameAnalyzer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/FullyQualifiedNameAnalyzer.php',
     'PhpCsFixer\\Tokenizer\\Analyzer\\FunctionsAnalyzer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/FunctionsAnalyzer.php',
     'PhpCsFixer\\Tokenizer\\Analyzer\\GotoLabelAnalyzer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/GotoLabelAnalyzer.php',
     'PhpCsFixer\\Tokenizer\\Analyzer\\NamespaceUsesAnalyzer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/NamespaceUsesAnalyzer.php',

+ 10 - 0
vendor/composer/autoload_static.php

@@ -762,6 +762,7 @@ class ComposerStaticInit88f2a4d4a4e81dc7d415bcdf39930654
         'App\\Model\\WebsiteColumn' => __DIR__ . '/../..' . '/app/Model/WebsiteColumn.php',
         'App\\Model\\WebsiteRole' => __DIR__ . '/../..' . '/app/Model/WebsiteRole.php',
         'App\\Model\\WebsiteRoleUser' => __DIR__ . '/../..' . '/app/Model/WebsiteRoleUser.php',
+        'App\\Model\\WhiteRouter' => __DIR__ . '/../..' . '/app/Model/WhiteRouter.php',
         'App\\Tools\\Result' => __DIR__ . '/../..' . '/app/Tools/Result.php',
         'Attribute' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
         'CURLStringFile' => __DIR__ . '/..' . '/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php',
@@ -1056,6 +1057,7 @@ class ComposerStaticInit88f2a4d4a4e81dc7d415bcdf39930654
         'Fidry\\CpuCoreCounter\\Finder\\CpuCoreFinder' => __DIR__ . '/..' . '/fidry/cpu-core-counter/src/Finder/CpuCoreFinder.php',
         'Fidry\\CpuCoreCounter\\Finder\\CpuInfoFinder' => __DIR__ . '/..' . '/fidry/cpu-core-counter/src/Finder/CpuInfoFinder.php',
         'Fidry\\CpuCoreCounter\\Finder\\DummyCpuCoreFinder' => __DIR__ . '/..' . '/fidry/cpu-core-counter/src/Finder/DummyCpuCoreFinder.php',
+        'Fidry\\CpuCoreCounter\\Finder\\EnvVariableFinder' => __DIR__ . '/..' . '/fidry/cpu-core-counter/src/Finder/EnvVariableFinder.php',
         'Fidry\\CpuCoreCounter\\Finder\\FinderRegistry' => __DIR__ . '/..' . '/fidry/cpu-core-counter/src/Finder/FinderRegistry.php',
         'Fidry\\CpuCoreCounter\\Finder\\HwLogicalFinder' => __DIR__ . '/..' . '/fidry/cpu-core-counter/src/Finder/HwLogicalFinder.php',
         'Fidry\\CpuCoreCounter\\Finder\\HwPhysicalFinder' => __DIR__ . '/..' . '/fidry/cpu-core-counter/src/Finder/HwPhysicalFinder.php',
@@ -1073,6 +1075,7 @@ class ComposerStaticInit88f2a4d4a4e81dc7d415bcdf39930654
         'Fidry\\CpuCoreCounter\\Finder\\WmicPhysicalFinder' => __DIR__ . '/..' . '/fidry/cpu-core-counter/src/Finder/WmicPhysicalFinder.php',
         'Fidry\\CpuCoreCounter\\Finder\\_NProcessorFinder' => __DIR__ . '/..' . '/fidry/cpu-core-counter/src/Finder/_NProcessorFinder.php',
         'Fidry\\CpuCoreCounter\\NumberOfCpuCoreNotFound' => __DIR__ . '/..' . '/fidry/cpu-core-counter/src/NumberOfCpuCoreNotFound.php',
+        'Fidry\\CpuCoreCounter\\ParallelisationResult' => __DIR__ . '/..' . '/fidry/cpu-core-counter/src/ParallelisationResult.php',
         'Fig\\Http\\Message\\RequestMethodInterface' => __DIR__ . '/..' . '/fig/http-message-util/src/RequestMethodInterface.php',
         'Fig\\Http\\Message\\StatusCodeInterface' => __DIR__ . '/..' . '/fig/http-message-util/src/StatusCodeInterface.php',
         'GrahamCampbell\\ResultType\\Error' => __DIR__ . '/..' . '/graham-campbell/result-type/src/Error.php',
@@ -4113,6 +4116,7 @@ class ComposerStaticInit88f2a4d4a4e81dc7d415bcdf39930654
         'PhpCsFixer\\Fixer\\ArrayNotation\\WhitespaceAfterCommaInArrayFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/ArrayNotation/WhitespaceAfterCommaInArrayFixer.php',
         'PhpCsFixer\\Fixer\\ArrayNotation\\YieldFromArrayToYieldsFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/ArrayNotation/YieldFromArrayToYieldsFixer.php',
         'PhpCsFixer\\Fixer\\AttributeNotation\\AttributeEmptyParenthesesFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/AttributeNotation/AttributeEmptyParenthesesFixer.php',
+        'PhpCsFixer\\Fixer\\AttributeNotation\\GeneralAttributeRemoveFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/AttributeNotation/GeneralAttributeRemoveFixer.php',
         'PhpCsFixer\\Fixer\\AttributeNotation\\OrderedAttributesFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/AttributeNotation/OrderedAttributesFixer.php',
         'PhpCsFixer\\Fixer\\Basic\\BracesFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/Basic/BracesFixer.php',
         'PhpCsFixer\\Fixer\\Basic\\BracesPositionFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/Basic/BracesPositionFixer.php',
@@ -4287,6 +4291,7 @@ class ComposerStaticInit88f2a4d4a4e81dc7d415bcdf39930654
         'PhpCsFixer\\Fixer\\PhpUnit\\PhpUnitAssertNewNamesFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitAssertNewNamesFixer.php',
         'PhpCsFixer\\Fixer\\PhpUnit\\PhpUnitAttributesFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitAttributesFixer.php',
         'PhpCsFixer\\Fixer\\PhpUnit\\PhpUnitConstructFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitConstructFixer.php',
+        'PhpCsFixer\\Fixer\\PhpUnit\\PhpUnitDataProviderMethodOrderFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitDataProviderMethodOrderFixer.php',
         'PhpCsFixer\\Fixer\\PhpUnit\\PhpUnitDataProviderNameFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitDataProviderNameFixer.php',
         'PhpCsFixer\\Fixer\\PhpUnit\\PhpUnitDataProviderReturnTypeFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitDataProviderReturnTypeFixer.php',
         'PhpCsFixer\\Fixer\\PhpUnit\\PhpUnitDataProviderStaticFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitDataProviderStaticFixer.php',
@@ -4386,6 +4391,7 @@ class ComposerStaticInit88f2a4d4a4e81dc7d415bcdf39930654
         'PhpCsFixer\\Fixer\\Whitespace\\TypeDeclarationSpacesFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/TypeDeclarationSpacesFixer.php',
         'PhpCsFixer\\Fixer\\Whitespace\\TypesSpacesFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/TypesSpacesFixer.php',
         'PhpCsFixer\\Fixer\\WhitespacesAwareFixerInterface' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/WhitespacesAwareFixerInterface.php',
+        'PhpCsFixer\\Hasher' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Hasher.php',
         'PhpCsFixer\\Indicator\\PhpUnitTestCaseIndicator' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Indicator/PhpUnitTestCaseIndicator.php',
         'PhpCsFixer\\Linter\\CachingLinter' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Linter/CachingLinter.php',
         'PhpCsFixer\\Linter\\Linter' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Linter/Linter.php',
@@ -4431,6 +4437,7 @@ class ComposerStaticInit88f2a4d4a4e81dc7d415bcdf39930654
         'PhpCsFixer\\RuleSet\\Sets\\PHP80MigrationRiskySet' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHP80MigrationRiskySet.php',
         'PhpCsFixer\\RuleSet\\Sets\\PHP80MigrationSet' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHP80MigrationSet.php',
         'PhpCsFixer\\RuleSet\\Sets\\PHP81MigrationSet' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHP81MigrationSet.php',
+        'PhpCsFixer\\RuleSet\\Sets\\PHP82MigrationRiskySet' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHP82MigrationRiskySet.php',
         'PhpCsFixer\\RuleSet\\Sets\\PHP82MigrationSet' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHP82MigrationSet.php',
         'PhpCsFixer\\RuleSet\\Sets\\PHP83MigrationSet' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHP83MigrationSet.php',
         'PhpCsFixer\\RuleSet\\Sets\\PHP84MigrationSet' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHP84MigrationSet.php',
@@ -4458,6 +4465,8 @@ class ComposerStaticInit88f2a4d4a4e81dc7d415bcdf39930654
         'PhpCsFixer\\RuleSet\\Sets\\PhpCsFixerSet' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PhpCsFixerSet.php',
         'PhpCsFixer\\RuleSet\\Sets\\SymfonyRiskySet' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/RuleSet/Sets/SymfonyRiskySet.php',
         'PhpCsFixer\\RuleSet\\Sets\\SymfonySet' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/RuleSet/Sets/SymfonySet.php',
+        'PhpCsFixer\\Runner\\Event\\AnalysisStarted' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Runner/Event/AnalysisStarted.php',
+        'PhpCsFixer\\Runner\\Event\\FileProcessed' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Runner/Event/FileProcessed.php',
         'PhpCsFixer\\Runner\\FileCachingLintingFileIterator' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Runner/FileCachingLintingFileIterator.php',
         'PhpCsFixer\\Runner\\FileFilterIterator' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Runner/FileFilterIterator.php',
         'PhpCsFixer\\Runner\\LintingFileIterator' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Runner/LintingFileIterator.php',
@@ -4497,6 +4506,7 @@ class ComposerStaticInit88f2a4d4a4e81dc7d415bcdf39930654
         'PhpCsFixer\\Tokenizer\\Analyzer\\CommentsAnalyzer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/CommentsAnalyzer.php',
         'PhpCsFixer\\Tokenizer\\Analyzer\\ControlCaseStructuresAnalyzer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/ControlCaseStructuresAnalyzer.php',
         'PhpCsFixer\\Tokenizer\\Analyzer\\DataProviderAnalyzer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/DataProviderAnalyzer.php',
+        'PhpCsFixer\\Tokenizer\\Analyzer\\FullyQualifiedNameAnalyzer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/FullyQualifiedNameAnalyzer.php',
         'PhpCsFixer\\Tokenizer\\Analyzer\\FunctionsAnalyzer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/FunctionsAnalyzer.php',
         'PhpCsFixer\\Tokenizer\\Analyzer\\GotoLabelAnalyzer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/GotoLabelAnalyzer.php',
         'PhpCsFixer\\Tokenizer\\Analyzer\\NamespaceUsesAnalyzer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/NamespaceUsesAnalyzer.php',

+ 5 - 0
vendor/fidry/cpu-core-counter/.envrc

@@ -0,0 +1,5 @@
+use nix --packages \
+  gnumake \
+  yamllint
+
+source_env_if_exists .envrc.local

+ 69 - 0
vendor/fidry/cpu-core-counter/src/Finder/EnvVariableFinder.php

@@ -0,0 +1,69 @@
+<?php
+
+/*
+ * This file is part of the Fidry CPUCounter Config package.
+ *
+ * (c) Théo FIDRY <theo.fidry@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+declare(strict_types=1);
+
+namespace Fidry\CpuCoreCounter\Finder;
+
+use function getenv;
+use function preg_match;
+use function sprintf;
+use function var_export;
+
+final class EnvVariableFinder implements CpuCoreFinder
+{
+    /** @var string */
+    private $environmentVariableName;
+
+    public function __construct(string $environmentVariableName)
+    {
+        $this->environmentVariableName = $environmentVariableName;
+    }
+
+    public function diagnose(): string
+    {
+        $value = getenv($this->environmentVariableName);
+
+        return sprintf(
+            'parse(getenv(%s)=%s)=%s',
+            $this->environmentVariableName,
+            var_export($value, true),
+            self::isPositiveInteger($value) ? $value : 'null'
+        );
+    }
+
+    public function find(): ?int
+    {
+        $value = getenv($this->environmentVariableName);
+
+        return self::isPositiveInteger($value)
+            ? (int) $value
+            : null;
+    }
+
+    public function toString(): string
+    {
+        return sprintf(
+            'getenv(%s)',
+            $this->environmentVariableName
+        );
+    }
+
+    /**
+     * @param string|false $value
+     */
+    private static function isPositiveInteger($value): bool
+    {
+        return false !== $value
+            && 1 === preg_match('/^\d+$/', $value)
+            && (int) $value > 0;
+    }
+}

+ 87 - 0
vendor/fidry/cpu-core-counter/src/ParallelisationResult.php

@@ -0,0 +1,87 @@
+<?php
+
+/*
+ * This file is part of the Fidry CPUCounter Config package.
+ *
+ * (c) Théo FIDRY <theo.fidry@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+declare(strict_types=1);
+
+namespace Fidry\CpuCoreCounter;
+
+/**
+ * @readonly
+ */
+final class ParallelisationResult
+{
+    /**
+     * @var positive-int|0
+     */
+    public $passedReservedCpus;
+
+    /**
+     * @var non-zero-int|null
+     */
+    public $passedCountLimit;
+
+    /**
+     * @var float|null
+     */
+    public $passedLoadLimit;
+
+    /**
+     * @var float|null
+     */
+    public $passedSystemLoadAverage;
+
+    /**
+     * @var non-zero-int|null
+     */
+    public $correctedCountLimit;
+
+    /**
+     * @var float|null
+     */
+    public $correctedSystemLoadAverage;
+
+    /**
+     * @var positive-int
+     */
+    public $totalCoresCount;
+
+    /**
+     * @var positive-int
+     */
+    public $availableCpus;
+
+    /**
+     * @param positive-int|0    $passedReservedCpus
+     * @param non-zero-int|null $passedCountLimit
+     * @param non-zero-int|null $correctedCountLimit
+     * @param positive-int      $totalCoresCount
+     * @param positive-int      $availableCpus
+     */
+    public function __construct(
+        int $passedReservedCpus,
+        ?int $passedCountLimit,
+        ?float $passedLoadLimit,
+        ?float $passedSystemLoadAverage,
+        ?int $correctedCountLimit,
+        ?float $correctedSystemLoadAverage,
+        int $totalCoresCount,
+        int $availableCpus
+    ) {
+        $this->passedReservedCpus = $passedReservedCpus;
+        $this->passedCountLimit = $passedCountLimit;
+        $this->passedLoadLimit = $passedLoadLimit;
+        $this->passedSystemLoadAverage = $passedSystemLoadAverage;
+        $this->correctedCountLimit = $correctedCountLimit;
+        $this->correctedSystemLoadAverage = $correctedSystemLoadAverage;
+        $this->totalCoresCount = $totalCoresCount;
+        $this->availableCpus = $availableCpus;
+    }
+}

+ 142 - 0
vendor/friendsofphp/php-cs-fixer/src/Fixer/AttributeNotation/GeneralAttributeRemoveFixer.php

@@ -0,0 +1,142 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * This file is part of PHP CS Fixer.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *     Dariusz Rumiński <dariusz.ruminski@gmail.com>
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace PhpCsFixer\Fixer\AttributeNotation;
+
+use PhpCsFixer\AbstractFixer;
+use PhpCsFixer\Fixer\ConfigurableFixerInterface;
+use PhpCsFixer\Fixer\ConfigurableFixerTrait;
+use PhpCsFixer\FixerConfiguration\FixerConfigurationResolver;
+use PhpCsFixer\FixerConfiguration\FixerConfigurationResolverInterface;
+use PhpCsFixer\FixerConfiguration\FixerOptionBuilder;
+use PhpCsFixer\FixerDefinition\CodeSample;
+use PhpCsFixer\FixerDefinition\FixerDefinition;
+use PhpCsFixer\FixerDefinition\FixerDefinitionInterface;
+use PhpCsFixer\Tokenizer\Analyzer\Analysis\AttributeAnalysis;
+use PhpCsFixer\Tokenizer\Analyzer\AttributeAnalyzer;
+use PhpCsFixer\Tokenizer\Tokens;
+
+/**
+ * @author Raffaele Carelle <raffaele.carelle@gmail.com>
+ *
+ * @implements ConfigurableFixerInterface<_AutogeneratedInputConfiguration, _AutogeneratedComputedConfiguration>
+ *
+ * @phpstan-import-type _AttributeItems from AttributeAnalysis
+ * @phpstan-import-type _AttributeItem from AttributeAnalysis
+ *
+ * @phpstan-type _AutogeneratedInputConfiguration array{
+ *  attributes?: list<class-string>,
+ * }
+ * @phpstan-type _AutogeneratedComputedConfiguration array{
+ *  attributes: list<class-string>,
+ * }
+ */
+final class GeneralAttributeRemoveFixer extends AbstractFixer implements ConfigurableFixerInterface
+{
+    /** @use ConfigurableFixerTrait<_AutogeneratedInputConfiguration, _AutogeneratedComputedConfiguration> */
+    use ConfigurableFixerTrait;
+
+    public function getDefinition(): FixerDefinitionInterface
+    {
+        return new FixerDefinition(
+            'Removes configured attributes by their respective FQN.',
+            [
+                new CodeSample(
+                    '<?php
+#[\A\B\Foo]
+function foo() {}
+',
+                    ['attributes' => ['\A\B\Foo']]
+                ),
+                new CodeSample(
+                    '<?php
+use A\B\Bar as BarAlias;
+
+#[\A\B\Foo]
+#[BarAlias]
+function foo() {}
+',
+                    ['attributes' => ['\A\B\Foo', 'A\B\Bar']]
+                ),
+            ]
+        );
+    }
+
+    public function getPriority(): int
+    {
+        return 0;
+    }
+
+    public function isCandidate(Tokens $tokens): bool
+    {
+        return \defined('T_ATTRIBUTE') && $tokens->isTokenKindFound(T_ATTRIBUTE);
+    }
+
+    protected function applyFix(\SplFileInfo $file, Tokens $tokens): void
+    {
+        if (0 === \count($this->configuration['attributes'])) {
+            return;
+        }
+
+        $index = 0;
+
+        while (null !== $index = $tokens->getNextTokenOfKind($index, [[T_ATTRIBUTE]])) {
+            $attributeAnalysis = AttributeAnalyzer::collectOne($tokens, $index);
+
+            $endIndex = $attributeAnalysis->getEndIndex();
+
+            $removedCount = 0;
+            foreach ($attributeAnalysis->getAttributes() as $element) {
+                $fullname = AttributeAnalyzer::determineAttributeFullyQualifiedName($tokens, $element['name'], $element['start']);
+
+                if (!\in_array($fullname, $this->configuration['attributes'], true)) {
+                    continue;
+                }
+
+                $tokens->clearRange($element['start'], $element['end']);
+                ++$removedCount;
+
+                $siblingIndex = $tokens->getNonEmptySibling($element['end'], 1);
+
+                // Clear element comma
+                if (',' === $tokens[$siblingIndex]->getContent()) {
+                    $tokens->clearAt($siblingIndex);
+                }
+            }
+
+            // Clear whole attribute if all are removed (multiline attribute case)
+            if (\count($attributeAnalysis->getAttributes()) === $removedCount) {
+                $tokens->clearRange($attributeAnalysis->getStartIndex(), $attributeAnalysis->getEndIndex());
+            }
+
+            // Clear trailing comma
+            $tokenIndex = $tokens->getMeaningfulTokenSibling($attributeAnalysis->getClosingBracketIndex(), -1);
+            if (',' === $tokens[$tokenIndex]->getContent()) {
+                $tokens->clearAt($tokenIndex);
+            }
+
+            $index = $endIndex;
+        }
+    }
+
+    protected function createConfigurationDefinition(): FixerConfigurationResolverInterface
+    {
+        return new FixerConfigurationResolver([
+            (new FixerOptionBuilder('attributes', 'List of FQNs of attributes for removal.'))
+                ->setAllowedTypes(['class-string[]'])
+                ->setDefault([])
+                ->getOption(),
+        ]);
+    }
+}

+ 288 - 0
vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitDataProviderMethodOrderFixer.php

@@ -0,0 +1,288 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * This file is part of PHP CS Fixer.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *     Dariusz Rumiński <dariusz.ruminski@gmail.com>
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace PhpCsFixer\Fixer\PhpUnit;
+
+use PhpCsFixer\Fixer\AbstractPhpUnitFixer;
+use PhpCsFixer\Fixer\ClassNotation\OrderedClassElementsFixer;
+use PhpCsFixer\Fixer\ConfigurableFixerInterface;
+use PhpCsFixer\Fixer\ConfigurableFixerTrait;
+use PhpCsFixer\FixerConfiguration\FixerConfigurationResolver;
+use PhpCsFixer\FixerConfiguration\FixerConfigurationResolverInterface;
+use PhpCsFixer\FixerConfiguration\FixerOptionBuilder;
+use PhpCsFixer\FixerDefinition\CodeSample;
+use PhpCsFixer\FixerDefinition\FixerDefinition;
+use PhpCsFixer\FixerDefinition\FixerDefinitionInterface;
+use PhpCsFixer\Tokenizer\Analyzer\DataProviderAnalyzer;
+use PhpCsFixer\Tokenizer\Tokens;
+
+/**
+ * @implements ConfigurableFixerInterface<_AutogeneratedInputConfiguration, _AutogeneratedComputedConfiguration>
+ *
+ * @phpstan-type _AutogeneratedInputConfiguration array{
+ *  placement?: 'after'|'before',
+ * }
+ * @phpstan-type _AutogeneratedComputedConfiguration array{
+ *  placement: 'after'|'before',
+ * }
+ *
+ * @phpstan-import-type _ClassElement from OrderedClassElementsFixer
+ */
+final class PhpUnitDataProviderMethodOrderFixer extends AbstractPhpUnitFixer implements ConfigurableFixerInterface
+{
+    /** @use ConfigurableFixerTrait<_AutogeneratedInputConfiguration, _AutogeneratedComputedConfiguration> */
+    use ConfigurableFixerTrait;
+
+    public function getDefinition(): FixerDefinitionInterface
+    {
+        return new FixerDefinition(
+            'Data provider method must be placed after/before the last/first test where used.',
+            [
+                new CodeSample(
+                    '<?php
+class FooTest extends TestCase {
+    public function dataProvider() {}
+    /**
+     * @dataProvider dataProvider
+     */
+    public function testSomething($expected, $actual) {}
+}
+',
+                ),
+                new CodeSample(
+                    '<?php
+class FooTest extends TestCase {
+    /**
+     * @dataProvider dataProvider
+     */
+    public function testSomething($expected, $actual) {}
+    public function dataProvider() {}
+}
+',
+                    [
+                        'placement' => 'before',
+                    ]
+                ),
+            ]
+        );
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * Must run before ClassAttributesSeparationFixer, NoBlankLinesAfterClassOpeningFixer.
+     * Must run after OrderedClassElementsFixer.
+     */
+    public function getPriority(): int
+    {
+        return 64;
+    }
+
+    protected function createConfigurationDefinition(): FixerConfigurationResolverInterface
+    {
+        return new FixerConfigurationResolver([
+            (new FixerOptionBuilder('placement', 'Where to place the data provider relative to the test where used.'))
+                ->setAllowedValues(['after', 'before'])
+                ->setDefault('after')
+                ->getOption(),
+        ]);
+    }
+
+    protected function applyPhpUnitClassFix(Tokens $tokens, int $startIndex, int $endIndex): void
+    {
+        $elements = $this->getElements($tokens, $startIndex);
+
+        if (0 === \count($elements)) {
+            return;
+        }
+
+        $endIndex = $elements[array_key_last($elements)]['end'];
+
+        $dataProvidersWithUsagePairs = $this->getDataProvidersWithUsagePairs($tokens, $startIndex, $endIndex);
+        $origUsageDataProviderOrderPairs = $this->getOrigUsageDataProviderOrderPairs($dataProvidersWithUsagePairs);
+
+        $sorted = $elements;
+        $providersPlaced = [];
+        if ('before' === $this->configuration['placement']) {
+            foreach ($origUsageDataProviderOrderPairs as [$usageName, $providerName]) {
+                if (!isset($providersPlaced[$providerName])) {
+                    $providersPlaced[$providerName] = true;
+
+                    $sorted = $this->moveMethodElement($sorted, $usageName, $providerName, false);
+                }
+            }
+        } else {
+            $sameUsageName = false;
+            $sameProviderName = false;
+            foreach ($origUsageDataProviderOrderPairs as [$usageName, $providerName]) {
+                if (!isset($providersPlaced[$providerName])) {
+                    $providersPlaced[$providerName] = true;
+
+                    $sortedBefore = $sorted;
+                    $sorted = $this->moveMethodElement(
+                        $sorted,
+                        $usageName === $sameUsageName // @phpstan-ignore argument.type (https://github.com/phpstan/phpstan/issues/12482)
+                            ? $sameProviderName
+                            : $usageName,
+                        $providerName,
+                        true
+                    );
+
+                    // honor multiple providers order for one test
+                    $sameUsageName = $usageName;
+                    $sameProviderName = $providerName;
+
+                    // keep placement after the first test
+                    if ($sortedBefore !== $sorted) {
+                        unset($providersPlaced[$providerName]);
+                    }
+                }
+            }
+        }
+
+        if ($sorted !== $elements) {
+            $this->sortTokens($tokens, $startIndex, $endIndex, $sorted);
+        }
+    }
+
+    /**
+     * @return list<_ClassElement>
+     */
+    private function getElements(Tokens $tokens, int $startIndex): array
+    {
+        $methodOrderFixer = new OrderedClassElementsFixer();
+
+        return \Closure::bind(static fn () => $methodOrderFixer->getElements($tokens, $startIndex), null, OrderedClassElementsFixer::class)();
+    }
+
+    /**
+     * @param list<_ClassElement> $elements
+     */
+    private function sortTokens(Tokens $tokens, int $startIndex, int $endIndex, array $elements): void
+    {
+        $methodOrderFixer = new OrderedClassElementsFixer();
+
+        \Closure::bind(static fn () => $methodOrderFixer->sortTokens($tokens, $startIndex, $endIndex, $elements), null, OrderedClassElementsFixer::class)();
+    }
+
+    /**
+     * @param list<_ClassElement> $elements
+     *
+     * @return list<_ClassElement>
+     */
+    private function moveMethodElement(array $elements, string $nameKeep, string $nameToMove, bool $after): array
+    {
+        $i = 0;
+        $iKeep = false;
+        $iToMove = false;
+        foreach ($elements as $element) {
+            if ('method' === $element['type']) {
+                if ($element['name'] === $nameKeep) {
+                    $iKeep = $i;
+                } elseif ($element['name'] === $nameToMove) {
+                    $iToMove = $i;
+                }
+            }
+
+            ++$i;
+        }
+        \assert(false !== $iKeep);
+        \assert(false !== $iToMove);
+
+        if ($iToMove === $iKeep + ($after ? 1 : -1)) {
+            return $elements;
+        }
+
+        $elementToMove = $elements[$iToMove]; // @phpstan-ignore offsetAccess.notFound
+        unset($elements[$iToMove]);
+
+        $c = $iKeep
+            + ($after ? 1 : 0)
+            + ($iToMove < $iKeep ? -1 : 0);
+
+        return [
+            ...\array_slice($elements, 0, $c),
+            $elementToMove,
+            ...\array_slice($elements, $c),
+        ];
+    }
+
+    /**
+     * @return list<array{
+     *   array{int, string},
+     *   non-empty-list<array{int, string, int}>
+     * }>
+     */
+    private function getDataProvidersWithUsagePairs(Tokens $tokens, int $startIndex, int $endIndex): array
+    {
+        $dataProvidersWithUsagePairs = [];
+
+        $dataProviderAnalyzer = new DataProviderAnalyzer();
+        foreach ($dataProviderAnalyzer->getDataProviders($tokens, $startIndex, $endIndex) as $dataProviderAnalysis) {
+            $usages = [];
+            foreach ($dataProviderAnalysis->getUsageIndices() as $usageIndex) {
+                $methodNameTokens = $tokens->findSequence([[T_FUNCTION], [T_STRING]], $usageIndex[0], $endIndex);
+                if (null === $methodNameTokens) {
+                    continue;
+                }
+
+                $usages[] = [
+                    array_key_last($methodNameTokens),
+                    end($methodNameTokens)->getContent(),
+                    $usageIndex[1],
+                ];
+            }
+            \assert([] !== $usages);
+
+            $dataProvidersWithUsagePairs[] = [
+                [$dataProviderAnalysis->getNameIndex(), $dataProviderAnalysis->getName()],
+                $usages,
+            ];
+        }
+
+        return $dataProvidersWithUsagePairs;
+    }
+
+    /**
+     * @param list<array{
+     *   array{int, string},
+     *   non-empty-list<array{int, string, int}>
+     * }> $dataProvidersWithUsagePairs
+     *
+     * @return list<array{string, string}>
+     */
+    private function getOrigUsageDataProviderOrderPairs(array $dataProvidersWithUsagePairs): array
+    {
+        $origUsagesOrderPairs = [];
+        foreach ($dataProvidersWithUsagePairs as [$dataProviderPair, $usagePairs]) {
+            foreach ($usagePairs as $usagePair) {
+                $origUsagesOrderPairs[] = [$usagePair, $dataProviderPair[1]];
+            }
+        }
+        uasort($origUsagesOrderPairs, static function (array $a, array $b): int {
+            $cmp = $a[0][0] <=> $b[0][0];
+
+            return 0 !== $cmp
+                ? $cmp
+                : $a[0][2] <=> $b[0][2];
+        });
+
+        $origUsageDataProviderOrderPairs = [];
+        foreach (array_map(static fn (array $v): array => [$v[0][1], $v[1]], $origUsagesOrderPairs) as [$usageName, $providerName]) {
+            $origUsageDataProviderOrderPairs[] = [$usageName, $providerName];
+        }
+
+        return $origUsageDataProviderOrderPairs;
+    }
+}

+ 38 - 0
vendor/friendsofphp/php-cs-fixer/src/Hasher.php

@@ -0,0 +1,38 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * This file is part of PHP CS Fixer.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *     Dariusz Rumiński <dariusz.ruminski@gmail.com>
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace PhpCsFixer;
+
+/**
+ * @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
+ *
+ * @internal
+ */
+final class Hasher
+{
+    private function __construct()
+    {
+        // cannot create instance of util. class
+    }
+
+    /**
+     * @return non-empty-string
+     */
+    public static function calculate(string $code): string
+    {
+        return \PHP_VERSION_ID >= 8_01_00
+            ? hash('xxh128', $code)
+            : md5($code);
+    }
+}

+ 31 - 0
vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHP82MigrationRiskySet.php

@@ -0,0 +1,31 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * This file is part of PHP CS Fixer.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *     Dariusz Rumiński <dariusz.ruminski@gmail.com>
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace PhpCsFixer\RuleSet\Sets;
+
+use PhpCsFixer\RuleSet\AbstractMigrationSetDescription;
+
+/**
+ * @internal
+ */
+final class PHP82MigrationRiskySet extends AbstractMigrationSetDescription
+{
+    public function getRules(): array
+    {
+        return [
+            '@PHP80Migration:risky' => true,
+            'phpdoc_readonly_class_comment_to_keyword' => true,
+        ];
+    }
+}

+ 54 - 0
vendor/friendsofphp/php-cs-fixer/src/Runner/Event/AnalysisStarted.php

@@ -0,0 +1,54 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * This file is part of PHP CS Fixer.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *     Dariusz Rumiński <dariusz.ruminski@gmail.com>
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace PhpCsFixer\Runner\Event;
+
+use Symfony\Contracts\EventDispatcher\Event;
+
+/**
+ * Event that is fired when Fixer starts analysis.
+ *
+ * @author Greg Korba <greg@codito.dev>
+ *
+ * @internal
+ */
+final class AnalysisStarted extends Event
+{
+    public const NAME = 'fixer.analysis_started';
+    public const MODE_SEQUENTIAL = 'sequential';
+    public const MODE_PARALLEL = 'parallel';
+
+    /** @var self::MODE_* */
+    private string $mode;
+    private bool $dryRun;
+
+    /**
+     * @param self::MODE_* $mode
+     */
+    public function __construct(string $mode, bool $dryRun)
+    {
+        $this->mode = $mode;
+        $this->dryRun = $dryRun;
+    }
+
+    public function getMode(): string
+    {
+        return $this->mode;
+    }
+
+    public function isDryRun(): bool
+    {
+        return $this->dryRun;
+    }
+}

+ 75 - 0
vendor/friendsofphp/php-cs-fixer/src/Runner/Event/FileProcessed.php

@@ -0,0 +1,75 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * This file is part of PHP CS Fixer.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *     Dariusz Rumiński <dariusz.ruminski@gmail.com>
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace PhpCsFixer\Runner\Event;
+
+use Symfony\Contracts\EventDispatcher\Event;
+
+/**
+ * Event that is fired when file was processed by Fixer.
+ *
+ * @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
+ *
+ * @internal
+ */
+final class FileProcessed extends Event
+{
+    /**
+     * Event name.
+     */
+    public const NAME = 'fixer.file_processed';
+
+    public const STATUS_INVALID = 1;
+    public const STATUS_SKIPPED = 2;
+    public const STATUS_NO_CHANGES = 3;
+    public const STATUS_FIXED = 4;
+    public const STATUS_EXCEPTION = 5;
+    public const STATUS_LINT = 6;
+
+    /**
+     * @var self::STATUS_*
+     */
+    private int $status;
+
+    private ?string $fileRelativePath;
+    private ?string $fileHash;
+
+    /**
+     * @param self::STATUS_* $status
+     */
+    public function __construct(int $status, ?string $fileRelativePath = null, ?string $fileHash = null)
+    {
+        $this->status = $status;
+        $this->fileRelativePath = $fileRelativePath;
+        $this->fileHash = $fileHash;
+    }
+
+    /**
+     * @return self::STATUS_*
+     */
+    public function getStatus(): int
+    {
+        return $this->status;
+    }
+
+    public function getFileRelativePath(): ?string
+    {
+        return $this->fileRelativePath;
+    }
+
+    public function getFileHash(): ?string
+    {
+        return $this->fileHash;
+    }
+}

+ 103 - 0
vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/FullyQualifiedNameAnalyzer.php

@@ -0,0 +1,103 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * This file is part of PHP CS Fixer.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *     Dariusz Rumiński <dariusz.ruminski@gmail.com>
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace PhpCsFixer\Tokenizer\Analyzer;
+
+use PhpCsFixer\Tokenizer\Analyzer\Analysis\NamespaceAnalysis;
+use PhpCsFixer\Tokenizer\Analyzer\Analysis\NamespaceUseAnalysis;
+use PhpCsFixer\Tokenizer\Tokens;
+
+/**
+ * @internal
+ */
+final class FullyQualifiedNameAnalyzer
+{
+    private Tokens $tokens;
+
+    /**
+     * @var list<NamespaceAnalysis>
+     */
+    private array $namespaceAnalyses = [];
+
+    /**
+     * @var array<int, list<NamespaceUseAnalysis>>
+     */
+    private array $namespaceUseAnalyses = [];
+
+    public function __construct(Tokens $tokens)
+    {
+        $this->tokens = $tokens;
+    }
+
+    /**
+     * @param NamespaceUseAnalysis::TYPE_* $importType
+     */
+    public function getFullyQualifiedName(string $name, int $indexInNamespace, int $importType): string
+    {
+        return ltrim($this->getFullyQualifiedNameWithPossiblyLeadingSlash($name, $indexInNamespace, $importType), '\\');
+    }
+
+    /**
+     * @param NamespaceUseAnalysis::TYPE_* $importType
+     */
+    private function getFullyQualifiedNameWithPossiblyLeadingSlash(string $name, int $indexInNamespace, int $importType): string
+    {
+        if ('\\' === $name[0]) {
+            return $name;
+        }
+
+        $namespaceAnalysis = $this->getNamespaceAnalysis($indexInNamespace);
+
+        $this->namespaceUseAnalyses[$namespaceAnalysis->getStartIndex()] ??= (new NamespaceUsesAnalyzer())->getDeclarationsInNamespace($this->tokens, $namespaceAnalysis);
+        \assert(isset($this->namespaceUseAnalyses[$namespaceAnalysis->getStartIndex()]));
+
+        $declarations = [];
+        foreach ($this->namespaceUseAnalyses[$namespaceAnalysis->getStartIndex()] as $namespaceUseAnalysis) {
+            if ($namespaceUseAnalysis->getType() !== $importType) {
+                continue;
+            }
+            $declarations[strtolower($namespaceUseAnalysis->getShortName())] = $namespaceUseAnalysis->getFullName();
+        }
+
+        $lowercaseName = strtolower($name);
+        foreach ($declarations as $lowercaseShortName => $fullName) {
+            if ($lowercaseName === $lowercaseShortName) {
+                return $fullName;
+            }
+
+            if (!str_starts_with($lowercaseName, $lowercaseShortName.'\\')) {
+                continue;
+            }
+
+            return $fullName.substr($name, \strlen($lowercaseShortName));
+        }
+
+        return $namespaceAnalysis->getFullName().'\\'.$name;
+    }
+
+    private function getNamespaceAnalysis(int $index): NamespaceAnalysis
+    {
+        foreach ($this->namespaceAnalyses as $namespace) {
+            if ($namespace->getScopeStartIndex() <= $index && $namespace->getScopeEndIndex() >= $index) {
+                return $namespace;
+            }
+        }
+
+        $namespace = (new NamespacesAnalyzer())->getNamespaceAt($this->tokens, $index);
+
+        $this->namespaceAnalyses[] = $namespace;
+
+        return $namespace;
+    }
+}