PHPackages                             topotru/psalm-conditional-final - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. topotru/psalm-conditional-final

ActivePsalm-plugin[Database &amp; ORM](/categories/database)

topotru/psalm-conditional-final
===============================

Smart final/abstract class enforcement with attributes-based exclusions for Psalm. Perfect for Doctrine entities.

1.0.1(3w ago)071↓15.5%MITPHPPHP ^8.3CI passing

Since May 14Pushed 3w agoCompare

[ Source](https://github.com/topotru/psalm-conditional-final)[ Packagist](https://packagist.org/packages/topotru/psalm-conditional-final)[ RSS](/packages/topotru-psalm-conditional-final/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (2)Dependencies (2)Versions (3)Used By (0)

Conditional Final for Psalm
===========================

[](#conditional-final-for-psalm)

Smart `final`/`abstract` class enforcement with attributes-based exclusions for Psalm.

[![Latest Stable Version](https://camo.githubusercontent.com/884747af79c314c5be03b673d810583f77915795ab5682bc3319f9a34ccc8984/68747470733a2f2f736869656c64732e696f)](https://packagist.org)[![License](https://camo.githubusercontent.com/884747af79c314c5be03b673d810583f77915795ab5682bc3319f9a34ccc8984/68747470733a2f2f736869656c64732e696f)](https://packagist.org)

Enforce `final` or `abstract` on your PHP classes without breaking your **Doctrine Entities** or other proxy-reliant classes.

This plugin replaces dumb token-based linters (like PHPCS) with smart, attributes-aware architectural control on top of the Psalm static analysis engine.

The Problem
-----------

[](#the-problem)

Standard linters (e.g., `SlevomatCodingStandard.Classes.RequireAbstractOrFinal`) force you to make every class `final`. However, **Doctrine Entities** (or MappedSuperclasses) **must not be final** because Doctrine needs to extend them to generate lazy-loading proxy classes at runtime.

If you accidentally make an Entity `final`, it usually works fine in `dev` environment but **crashes with a Fatal Error on production**. To avoid this, you are forced to litter your codebase with ugly comments:

```
#[ORM\Entity]
// phpcs:ignore SlevomatCodingStandard.Classes.RequireAbstractOrFinal
class User {} // Annoying and error-prone!
```

The Solution
------------

[](#the-solution)

**Conditional Final** reverses the logic:

1. Every class **must** be `final` or `abstract` by default.
2. If a class has a forbidden attribute (like `#[ORM\Entity]`), it **must not** be `final` (protects your production).
3. Completely config-driven. No more inline ignore comments!
4. Zero-dependency core (does not require `doctrine/orm` to be installed).

Installation
------------

[](#installation)

```
composer require --dev topotru/psalm-conditional-final
```

Enable the plugin in your `psalm.xml`:

```
vendor/bin/psalm-plugin enable topotru/psalm-conditional-final
```

Configuration
-------------

[](#configuration)

By default, the plugin requires all classes to be `final` or `abstract` and has an empty exclusion list.

### Integration with Doctrine ORM

[](#integration-with-doctrine-orm)

To enable the built-in preset for Doctrine (`#[Entity]` and `#[MappedSuperclass]`), simply add the `` tag inside the plugin configuration in your `psalm.xml`:

```

```

### Custom Configurations

[](#custom-configurations)

You can add any custom proxy or framework attributes (like API Platform or custom annotations) to the exclusion list manually inside the `forbiddenFinalAttributes` section:

```

            App\Attributes\CustomProxy
            ApiPlatform\Metadata\ApiResource

```

Errors Handled
--------------

[](#errors-handled)

- `ClassShouldNotBeFinal` — Triggers when an entity/proxy class is accidentally marked as `final` (prevents production crashes).
- `ClassShouldBeFinal` — Triggers when a standard class (service, repository, etc.) misses the `final` keyword.

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE) for more information.

###  Health Score

43

—

FairBetter than 89% of packages

Maintenance94

Actively maintained with recent releases

Popularity13

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity49

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

2

Last Release

26d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/9f9126019bdf91fccb433f70ad58119b2a8359b8a22e5fd2f62b2b01607b9d16?d=identicon)[topotru](/maintainers/topotru)

---

Top Contributors

[![topotru](https://avatars.githubusercontent.com/u/6192218?v=4)](https://github.com/topotru "topotru (7 commits)")

---

Tags

static analysisdoctrinearchitecturepsalmfinal

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/topotru-psalm-conditional-final/health.svg)

```
[![Health](https://phpackages.com/badges/topotru-psalm-conditional-final/health.svg)](https://phpackages.com/packages/topotru-psalm-conditional-final)
```

###  Alternatives

[doctrine/common

PHP Doctrine Common project is a library that provides additional functionality that other Doctrine projects depend on such as better reflection support, proxies and much more.

5.8k371.8M1.3k](/packages/doctrine-common)[gedmo/doctrine-extensions

Doctrine behavioral extensions

4.1k122.6M405](/packages/gedmo-doctrine-extensions)[symfony/property-info

Extracts information about PHP class' properties using metadata of popular sources

2.2k270.7M1.1k](/packages/symfony-property-info)[weirdan/doctrine-psalm-plugin

Stubs to let Psalm understand Doctrine better

897.2M58](/packages/weirdan-doctrine-psalm-plugin)[beberlei/doctrineextensions

A set of extensions to Doctrine 2 that add support for additional query functions available in MySQL, Oracle, PostgreSQL and SQLite.

2.1k78.1M168](/packages/beberlei-doctrineextensions)[psalm/plugin-laravel

Psalm plugin for Laravel

3325.1M337](/packages/psalm-plugin-laravel)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
