Skip to content

[TASK] Upgrade PHPStan ecosystem to 2.x#4

Open
CybotTM wants to merge 7 commits intomainfrom
feature/phpstan-2
Open

[TASK] Upgrade PHPStan ecosystem to 2.x#4
CybotTM wants to merge 7 commits intomainfrom
feature/phpstan-2

Conversation

@CybotTM
Copy link
Owner

@CybotTM CybotTM commented Feb 22, 2026

Summary

Coordinated upgrade of the PHPStan ecosystem to major version 2:

  • phpstan/phpstan: ^1.12 -> ^2.1
  • phpstan/phpstan-strict-rules: ^1.6 -> ^2.0
  • symplify/phpstan-rules: ^13.0 -> ^14.9
  • Removed deprecated symplify regex rules (dropped in 14.x)
  • Updated phpstan.neon config: strictCalls -> strictFunctionCalls (renamed in 2.x)
  • Regenerated phpstan-baseline.neon — reduced from 13 entries (main) to 9 entries

Baseline reduction approach

All PHPStan errors were fixed with genuine code changes (no @phpstan-ignore suppressions):

  • Return type narrowing: Changed Node|nullNode on NodeTransformer implementations (valid PHP covariance)
  • Input validation: Added is_string()/is_array() guards for mixed Symfony Console inputs
  • JSON/YAML parsing: Step-by-step type validation of json_decode()/Yaml::parse() results
  • Type annotations: Fixed array type annotations (array<string, mixed> instead of array<mixed>)
  • DOM handling: Proper DOMNodeList access in SiteSetSettingsDirective

Remaining 9 baseline entries are unfixable external library constraints:

  • 7 entries: phpDocumentor interfaces returning mixed from getId(), getAdditionalIds(), etc.
  • 2 entries: Symfony ExtensionInterface::load() parameter contravariance

PHPStan 2.x works on PHP ^7.4|^8.0, no PHP minimum bump needed.

Test plan

  • PHPStan analysis passes (0 errors with baseline)
  • PHP CS Fixer clean (0 fixes)
  • Unit tests pass (83/83)
  • Integration tests pass
  • CI passes

- phpstan/phpstan: ^1.12 -> ^2.1
- phpstan/phpstan-strict-rules: ^1.6 -> ^2.0
- symplify/phpstan-rules: ^13.0 -> ^14.9
- Removed deprecated symplify regex rules (dropped in 14.x)
- Updated strictRules config: strictCalls -> strictFunctionCalls
- Regenerated phpstan-baseline.neon for stricter 2.x rules
Copilot AI review requested due to automatic review settings February 22, 2026 11:30
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Upgrades the project’s PHP static analysis toolchain to PHPStan 2.x, updating configuration and baseline to match the new rule/parameter set while keeping CI coverage current.

Changes:

  • Bumped PHPStan + related rule packages to 2.x-compatible versions (and updated composer.lock accordingly).
  • Updated phpstan.neon for PHPStan 2.x config changes and removed deprecated Symplify regex rules.
  • Regenerated phpstan-baseline.neon to reflect the new/stricter rule set.
  • Expanded CI test matrix to include PHP 8.5.

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated no comments.

Show a summary per file
File Description
phpstan.neon Adjusts PHPStan 2.x config (strictFunctionCalls) and removes rules no longer available in Symplify 14.x.
phpstan-baseline.neon Updates baseline to the new set of reported issues under PHPStan 2.x.
composer.json Upgrades PHPStan ecosystem dependencies to 2.x-compatible versions.
composer.lock Locks upgraded dependency graph for the PHPStan ecosystem and transitive updates.
.github/workflows/main.yaml Adds PHP 8.5 to the CI matrix to keep runtime coverage current.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Reduce PHPStan baseline from 102 to 55 errors (46% reduction)
across 31 files by applying targeted fixes:

- Fix @param type on Typo3DocsThemeExtension::load() (15 errors)
- Add array_values() wrappers where list<> expected (12 errors)
- Add @phpstan-ignore return.unusedType on NodeTransformers (9 errors)
- Cast $input->getArgument() to (string) in CLI commands (7 errors)
- Fix dead code bug: missing $guides in operateOnXmlGuides() (4 errors)
- Remove unnecessary @var in TwigExtension (2 errors)
- Add @return list<string> to collectUnmigratedLegacySettings() (1 error)
- Cast $errno to (string) in XmlValidator (1 error)
- Fix nullsafe ?->textContent to -> in SiteSetSettingsDirective (1 error)
- Cast $answer to (string) in InitCommand validators (3 errors)
- Add type annotations for return.type entries (3 errors)
- Type-hint RunDecorator process callback parameters (3 errors)
- Cast $_SERVER['argv'] to array in AddThemeSettingsToProjectNode (1 error)
CybotTM and others added 5 commits February 22, 2026 14:23
…ssions

Replace inline @phpstan-ignore annotations with genuine code fixes:
- Narrow return types from Node|null to Node (valid PHP covariance)
- Add is_string()/is_array() guards for mixed Symfony Console inputs
- Type-safe extraction of JSON/YAML parsed data with step-by-step validation
- Fix array type annotations (array<string, mixed> instead of array<mixed>)
- Properly handle DOMNodeList access in SiteSetSettingsDirective

Baseline reduced from 41 to 9 entries (vs 13 on main). Remaining 9 are
unfixable external library constraints (phpDocumentor interfaces returning
mixed, Symfony ExtensionInterface contravariance).
… tests

The previous commit incorrectly replaced getValue() with getChildren()
in ViewHelperDirective. These access different properties on CompoundNode
(value vs children), causing the ViewHelper description/examples/sections
to be empty in rendered output.

Restore getValue() with proper is_array() type narrowing to satisfy
PHPStan without changing runtime behavior.
…ocumentation#1187)

Bumps
[friendsofphp/php-cs-fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer)
from 3.94.0 to 3.94.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/releases">friendsofphp/php-cs-fixer's
releases</a>.</em></p>
<blockquote>
<h2>v3.94.2 7th Gear</h2>
<h2>What's Changed</h2>
<ul>
<li>fix: <code>NoUnusedImportsFixer</code> - do not remove constant
types by <a
href="https://github.com/kubawerlos"><code>@​kubawerlos</code></a> in <a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/pull/9442">PHP-CS-Fixer/PHP-CS-Fixer#9442</a></li>
<li>fix: <code>AttributeBlockNoSpacesFixer</code> - skipping some
attributes when multiple present by <a
href="https://github.com/keradus"><code>@​keradus</code></a> in <a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/pull/9445">PHP-CS-Fixer/PHP-CS-Fixer#9445</a></li>
<li>fix: <code>PhpdocLineSpanFixer</code> - handle unions and
intersections in properties by <a
href="https://github.com/paulbalandan"><code>@​paulbalandan</code></a>
in <a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/pull/9438">PHP-CS-Fixer/PHP-CS-Fixer#9438</a></li>
<li>deps: bump crate-ci/typos from 1.43.4 to 1.43.5 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/pull/9444">PHP-CS-Fixer/PHP-CS-Fixer#9444</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/compare/v3.94.1...v3.94.2">https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/compare/v3.94.1...v3.94.2</a></p>
<h2>v3.94.1 7th Gear</h2>
<h2>What's Changed</h2>
<ul>
<li>docs: switch sets ordering to case-insensitive by <a
href="https://github.com/keradus"><code>@​keradus</code></a> in <a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/pull/9423">PHP-CS-Fixer/PHP-CS-Fixer#9423</a></li>
<li>chore: add tests for <code>ArgumentsAnalyzer</code> by <a
href="https://github.com/kubawerlos"><code>@​kubawerlos</code></a> in <a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/pull/9422">PHP-CS-Fixer/PHP-CS-Fixer#9422</a></li>
<li>deps: bump crate-ci/typos from 1.43.2 to 1.43.4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/pull/9426">PHP-CS-Fixer/PHP-CS-Fixer#9426</a></li>
<li>deps: bump ergebnis/composer-normalize from 2.49.0 to 2.50.0 in
/dev-tools by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/pull/9427">PHP-CS-Fixer/PHP-CS-Fixer#9427</a></li>
<li>deps: dependabot group for shipmonk/ by <a
href="https://github.com/keradus"><code>@​keradus</code></a> in <a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/pull/9429">PHP-CS-Fixer/PHP-CS-Fixer#9429</a></li>
<li>deps: bump the phpstan group in /dev-tools with 4 updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/pull/9425">PHP-CS-Fixer/PHP-CS-Fixer#9425</a></li>
<li>chore: bump dev-tools to PHP 8.5 by <a
href="https://github.com/keradus"><code>@​keradus</code></a> in <a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/pull/9432">PHP-CS-Fixer/PHP-CS-Fixer#9432</a></li>
<li>chore: reduce Generator into iterable by <a
href="https://github.com/keradus"><code>@​keradus</code></a> in <a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/pull/9435">PHP-CS-Fixer/PHP-CS-Fixer#9435</a></li>
<li>chore: ConfigurableFixerTemplateFixer - allow to remove option from
computed options by <a
href="https://github.com/keradus"><code>@​keradus</code></a> in <a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/pull/9437">PHP-CS-Fixer/PHP-CS-Fixer#9437</a></li>
<li>chore: fix Tokens::getIterator() type by <a
href="https://github.com/keradus"><code>@​keradus</code></a> in <a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/pull/9433">PHP-CS-Fixer/PHP-CS-Fixer#9433</a></li>
<li>CI: cleanup sca.yml by <a
href="https://github.com/keradus"><code>@​keradus</code></a> in <a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/pull/9430">PHP-CS-Fixer/PHP-CS-Fixer#9430</a></li>
<li>test: check PHP env in CI jobs by <a
href="https://github.com/keradus"><code>@​keradus</code></a> in <a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/pull/9428">PHP-CS-Fixer/PHP-CS-Fixer#9428</a></li>
<li>chore: reduce Iterator-&gt;Traversable and Traversable-&gt;iterable
when possible by <a
href="https://github.com/keradus"><code>@​keradus</code></a> in <a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/pull/9434">PHP-CS-Fixer/PHP-CS-Fixer#9434</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/compare/v3.94.0...v3.94.1">https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/compare/v3.94.0...v3.94.1</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/blob/master/CHANGELOG.md">friendsofphp/php-cs-fixer's
changelog</a>.</em></p>
<blockquote>
<h2>Changelog for v3.94.2</h2>
<ul>
<li>fix: <code>AttributeBlockNoSpacesFixer</code> - skipping some
attributes when multiple present (<a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues/9445">#9445</a>)</li>
<li>fix: <code>NoUnusedImportsFixer</code> - do not remove constant
types (<a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues/9442">#9442</a>)</li>
<li>fix: <code>PhpdocLineSpanFixer</code> - handle unions and
intersections in properties (<a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues/9438">#9438</a>)</li>
<li>deps: bump crate-ci/typos from 1.43.4 to 1.43.5 (<a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues/9444">#9444</a>)</li>
</ul>
<h2>Changelog for v3.94.1</h2>
<ul>
<li>chore: add tests for <code>ArgumentsAnalyzer</code> (<a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues/9422">#9422</a>)</li>
<li>chore: bump dev-tools to PHP 8.5 (<a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues/9432">#9432</a>)</li>
<li>chore: ConfigurableFixerTemplateFixer - allow to remove option from
computed options (<a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues/9437">#9437</a>)</li>
<li>chore: fix Tokens::getIterator() type (<a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues/9433">#9433</a>)</li>
<li>chore: reduce Generator into iterable (<a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues/9435">#9435</a>)</li>
<li>chore: reduce Iterator-&gt;Traversable and Traversable-&gt;iterable
when possible (<a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues/9434">#9434</a>)</li>
<li>CI: cleanup sca.yml (<a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues/9430">#9430</a>)</li>
<li>deps: bump crate-ci/typos from 1.43.2 to 1.43.4 (<a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues/9426">#9426</a>)</li>
<li>deps: bump ergebnis/composer-normalize from 2.49.0 to 2.50.0 in
/dev-tools (<a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues/9427">#9427</a>)</li>
<li>deps: bump the phpstan group in /dev-tools with 4 updates (<a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues/9425">#9425</a>)</li>
<li>deps: dependabot group for shipmonk/ (<a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues/9429">#9429</a>)</li>
<li>docs: switch sets ordering to case-insensitive (<a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues/9423">#9423</a>)</li>
<li>test: check PHP env in CI jobs (<a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues/9428">#9428</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/commit/7787ceff91365ba7d623ec410b8f429cdebb4f63"><code>7787cef</code></a>
prepared the 3.94.2 release</li>
<li><a
href="https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/commit/341df8b8e4fa17da2dd6fb0af42e2da40776fffc"><code>341df8b</code></a>
deps: bump crate-ci/typos from 1.43.4 to 1.43.5 (<a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues/9444">#9444</a>)</li>
<li><a
href="https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/commit/b133c65ac304693ae787eca0fdfa901454cca362"><code>b133c65</code></a>
fix: <code>PhpdocLineSpanFixer</code> - handle unions and intersections
in properties (#...</li>
<li><a
href="https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/commit/716d23f73c7e9a82f1ca4050333a6973cd055f57"><code>716d23f</code></a>
fix: <code>AttributeBlockNoSpacesFixer</code> - skipping some attributes
when multiple p...</li>
<li><a
href="https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/commit/5394868ab602452040dd069fefc38807bfc422bb"><code>5394868</code></a>
fix: <code>NoUnusedImportsFixer</code> - do not remove constant types
(<a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues/9442">#9442</a>)</li>
<li><a
href="https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/commit/0823705b521141c44092b4c5cd894e3b2a137b25"><code>0823705</code></a>
bumped version</li>
<li><a
href="https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/commit/d1a3634e29916367b885250e1fc4dfd5ffe3b091"><code>d1a3634</code></a>
prepared the 3.94.1 release</li>
<li><a
href="https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/commit/92d82677b6af1b9ce50cf7b6c5fb56afb44a82a6"><code>92d8267</code></a>
chore: reduce Iterator-&gt;Traversable and Traversable-&gt;iterable when
possible (...</li>
<li><a
href="https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/commit/cbb2b8458324ce35e25a246ffbd38138696716b2"><code>cbb2b84</code></a>
test: check PHP env in CI jobs (<a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues/9428">#9428</a>)</li>
<li><a
href="https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/commit/8c9458608008606e3992cecf8f0be83c701e4493"><code>8c94586</code></a>
CI: cleanup sca.yml (<a
href="https://redirect.github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues/9430">#9430</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/compare/v3.94.0...v3.94.2">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=friendsofphp/php-cs-fixer&package-manager=composer&previous-version=3.94.0&new-version=3.94.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…O3-Documentation#1174)

Resolves: TYPO3-Documentation#1172

## Summary

- Add missing `float: left`/`float: right` CSS properties to
`img.float-left`/`img.float-right` rules (Bootstrap 5 removed these)
- Add figure float rules (`figure.float-left`, `figure.float-right`)
with `max-width: 50%` and responsive breakpoint (<576px disables float)
- Add `img.align-center` / `figure.align-center` CSS for centered
alignment
- Replace deprecated HTML `align` attribute in `image.html.twig` with
CSS class mapping (`:align: left` → `float-left`, `:align: right` →
`float-right`, `:align: center` → `align-center`)
- Add `:align:` CSS class support in `figure.html.twig`
- Preserve `:align:` option on FigureNode (was being stripped) so `..
figure:: :align: left` works
- Strip `float-left`/`float-right` from inner `<img>` inside `<figure>`
to prevent caption wrapping issues
- Add `.clear-both` CSS utility alias (alongside existing `.cc`)
- Split `ImagesAndFigures` rendertest into separate pages: Index
(styling), Zoom, FloatAndAlignment

## Files changed

| File | Change |
|------|--------|
| `assets/sass/components/_rst.scss` | Add `float` property +
`align-center` to img rules |
| `assets/sass/components/_images.scss` | Add figure float/align rules +
responsive |
| `assets/sass/_utilities.scss` | Add `.clear-both` alias |
| `resources/template/body/image.html.twig` | Replace HTML `align` attr
with CSS classes |
| `resources/template/body/figure.html.twig` | Add `:align:` CSS class
support |
| `src/Directives/FigureDirective.php` | Keep `:align:` on FigureNode,
strip float from inner img |
| `resources/public/css/theme.css` | Regenerated |
| `Documentation-rendertest/ImagesAndFigures/` | Split into Index + Zoom
+ FloatAndAlignment |

## Test plan

- [x] All 195 PHPUnit tests pass
- [x] PHPStan reports 0 errors
- [x] Rendered docs verified: image/figure float left/right with text
wrapping
- [x] `:align: left`/`:align: right` on figures works correctly
- [x] `.clear-both` clears floats as expected
- [x] Responsive: floats disable on small screens (<576px)
- [x] Visual review of rendered ImagesAndFigures pages

### Related

- Follow-up PR: TYPO3-Documentation#1179 (modernize to `float-start`/`float-end`)
- Upstream issue:
[phpDocumentor/guides#1303](phpDocumentor/guides#1303)
— proposes removing `final` from upstream directives to avoid forking
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants