PHPackages                             cambis/silverstan - 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. [Testing &amp; Quality](/categories/testing)
4. /
5. cambis/silverstan

ActivePhpstan-extension[Testing &amp; Quality](/categories/testing)

cambis/silverstan
=================

PHPStan extensions and rules for Silverstripe CMS.

v2.1.9(5mo ago)679.9k—1.4%4[1 issues](https://github.com/Cambis/silverstan/issues)20MITPHPPHP ^7.4 || ^8.0CI passing

Since Mar 10Pushed 3mo ago2 watchersCompare

[ Source](https://github.com/Cambis/silverstan)[ Packagist](https://packagist.org/packages/cambis/silverstan)[ Docs](https://github.com/Cambis/silverstan)[ GitHub Sponsors](https://github.com/Cambis)[ RSS](/packages/cambis-silverstan/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (3)Versions (55)Used By (20)

Silverstan | Kaitiaki Ponga
===========================

[](#silverstan--kaitiaki-ponga)

[PHPStan extensions and rules](https://github.com/phpstan/phpstan) for [Silverstripe CMS](https://github.com/silverstripe).

 [ ![Latest stable version](https://camo.githubusercontent.com/4df91a616a477e05d13c1cfab4f914bfb97e79a0415247f3fe1e36288bc15d70/68747470733a2f2f706f7365722e707567782e6f72672f63616d6269732f73696c7665727374616e2f76) ](https://packagist.org/packages/cambis/silverstan) [ ![Total downloads](https://camo.githubusercontent.com/2b0c66804066762077b41dd402087e1b9e2a2c97e06d31fbd4c5c4330c3df054/68747470733a2f2f706f7365722e707567782e6f72672f63616d6269732f73696c7665727374616e2f646f776e6c6f616473) ](https://packagist.org/packages/cambis/silverstan/stats) [ ![Licence](https://camo.githubusercontent.com/dd8652cf454effa9876a41fa9b0c88738ff5994d3eb08634a38b6068598e60c7/68747470733a2f2f706f7365722e707567782e6f72672f63616d6269732f73696c7665727374616e2f6c6963656e7365) ](https://packagist.org/packages/cambis/silverstan) [ ![Build status](https://github.com/Cambis/silverstan/actions/workflows/test.yml/badge.svg) ](https://github.com/Cambis/silverstan/actions)

Features ✨
----------

[](#features-)

Here are some of the nice features this extension provides:

- Recognition that configuration properties are always [read and written](https://phpstan.org/developing-extensions/always-read-written-properties).
- Correct return type for `SilverStripe\Config\Collections\ConfigCollectionInterface::get()`.
- Correct return type for `SilverStripe\Core\Config\Config_ForClass::get()`.
- Resolution of `SilverStripe\Core\Extensible` magic methods and properties.
- Type specification for `SilverStripe\Core\Extensible::hasExtension()` and `SilverStripe\Core\Extensible::hasMethod()` methods.
- Correct return types for `SilverStripe\Core\Extension::$owner` and `SilverStripe\Core\Extension::getOwner()`.
- Correct return types for `SilverStripe\Core\Injector\Injector::get()` and `SilverStripe\Core\Injector\Injector::create()`.
- Correct return type for `SilverStripe\ORM\DataObject::dbObject()`.
- Type specification for `SilverStripe\Model\ModelData::hasField()` method.
- Type specification for `SilverStripe\View\ViewableData::hasField()` method.
- Various correct return types for commonly used Silverstripe modules.
- [Customisable rules to help make your application safer](docs/rules_overview.md).

Installation 👷‍♀️
-----------------

[](#installation-‍️)

Install via composer.

```
composer require --dev cambis/silverstan
```

If you also install [phpstan/extension-installer](https://github.com/phpstan/extension-installer) then you're all set!

 Manual installationIf you don't want to use `phpstan/extension-installer`, include extension.neon in your project's PHPStan config:

```
includes:
    - vendor/cambis/silverstan/extension.neon
```

### Silverstripe 5.2 or greater is recommended

[](#silverstripe-52-or-greater-is-recommended)

While this extension is not tied to a specific Silverstripe version it is recommended that you are on at least Silverstripe 5.2.

Silverstripe 5.2 introduces [generic typehints](https://docs.silverstripe.org/en/5/changelogs/beta/5.2.0-beta1/#generics). These changes allow the module to infer the types of objects without relying on an extension.

To make the best use of this module, make sure that your classes are correctly annotated using a combination of generics, and property/method annotations.

Bleeding edge 🔪
---------------

[](#bleeding-edge-)

New and experimental features are available via the bleeding edge config. You can opt in by including the relevant config file.

```
includes:
    - vendor/cambis/silverstan/bleedingEdge.neon
```

Rules 🚨
-------

[](#rules-)

Silverstan provides a set of customisable rules that can help make your application safer.

Each rule can be enabled/disabled individually using the configuration options, please refer to the [rules overview](docs/rules_overview.md) for the available options.

SilverStripe\\Dev\\TestOnly 👨‍🔬
-------------------------------

[](#silverstripedevtestonly-‍)

Complex analysis of `SilverStripe\Dev\TestOnly` classes is disabled by default. This is because these classes often contain dependencies that aren't provided by Silverstripe.

To enable complex analysis of these classes, please check the following option in your configuration file:

```
parameters:
    silverstan:
        includeTestOnly: true
```

If PHPStan complains about missing classes, be sure to add the corresponding package to your dev dependencies.

SilverStripe\\Core\\Extensible 🧑‍🔬
----------------------------------

[](#silverstripecoreextensible-‍)

### Solving magic methods and properties

[](#solving-magic-methods-and-properties)

Silverstan provides support for magic `SilverStripe\Core\Extensible` methods and properties.

Silverstan will attempt to resolve magic methods/properties by searching for existing annotations in the class ancestry first. If no annotation is found it will access the configuration API in order to resolve the magic method/property.

Using annotations is preferred, as they can often provide more information, have stricter types, and reduce the number of calls to the configuration API.

You can use [Silverstripe Rector](https://github.com/Cambis/silverstripe-rector) to create the annotations for you.

### Solving SilverStripe\\Core\\Extensible::hasExtension() and SilverStripe\\Core\\Extensible::hasMethod()

[](#solving-silverstripecoreextensiblehasextension-and-silverstripecoreextensiblehasmethod)

Silverstan provides type specifying extensions for these cases. However, these extensions can only be applied on a per class basis.

The default configuration applies these extensions to `SilverStripe\View\ViewableData` and `SilverStripe\Model\ModelData` only. If you wish to add them to other `SilverStripe\Core\Extensible` classes that aren't subclasses of the former you can use the following configuration:

```
services:
    -
        # Solves `Foo::hasExtension()`
        class: Cambis\Silverstan\Type\TypeSpecifyingExtension\ExtensibleHasExtensionTypeSpecifyingExtension
        tags: [phpstan.typeSpecifier.methodTypeSpecifyingExtension]
        arguments:
            className: 'Foo'
    -
        # Solves `Foo::hasMethod()`
        class: Cambis\Silverstan\Type\TypeSpecifyingExtension\ExtensibleHasMethodTypeSpecifyingExtension
        tags: [phpstan.typeSpecifier.methodTypeSpecifyingExtension]
        arguments:
            className: 'Foo'
```

### Solving SilverStripe\\Core\\Extensible::has\_extension()

[](#solving-silverstripecoreextensiblehas_extension)

Warning

Silverstan does not support type specification for `SilverStripe\Core\Extensible::has_extension()`. If you use this method in your codebase, consider using one of the following examples to help solve errors that may be reported by PHPStan.

In the example below, we are adding a typehint to inform PHPStan of the expected type.

```
if (\SilverStripe\View\ViewableData::has_extension(Foo::class, FooExtension::class)) {
+  /** @var Foo&FooExtension $foo */
  $foo = Foo::create();
}
```

In the example below, we are changing the calls to use the dynamic `SilverStripe\Core\Extensible::hasExtension()` method which is supported by Silverstan.

```
$foo = Foo::create();

- if ($foo->has_extension(FooExtension::class)) {
+ if ($foo->hasExtension(FooExtension::class)) {
  // ...
}

- if ($foo::has_extension(FooExtension::class)) {
+ if ($foo->hasExtension(FooExtension::class)) {
  // ...
}
```

SilverStripe\\Core\\Config\\Configurable 🧑‍🏭
--------------------------------------------

[](#silverstripecoreconfigconfigurable-‍)

The `missingType.iterableValue` error on configuration properties is ignored by default. This is because adding iterable information isn't useful unless the property is modified or accessed inside the current scope.

You can disable this behaviour in your configuration file.

```
parameters:
    silverstan:
        ignoreConfigurationPropertyTypeIterableValue: false
```

SilverStripe\\Core\\Config\\Config\_ForClass 👩‍🔬
------------------------------------------------

[](#silverstripecoreconfigconfig_forclass-‍)

Warning

Silverstan cannot resolve the type of a property fetch on `SilverStripe\Core\Config\Config_ForClass`, use `SilverStripe\Core\Config\Config_ForClass::get()` instead. [See the rules overview](docs/rules_overview.md#disallowpropertyfetchonconfigforclassrule).

###  Health Score

53

—

FairBetter than 97% of packages

Maintenance75

Regular maintenance activity

Popularity39

Limited adoption so far

Community27

Small or concentrated contributor base

Maturity60

Established project with proven stability

 Bus Factor1

Top contributor holds 99.7% 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 ~12 days

Recently: every ~22 days

Total

53

Last Release

151d ago

Major Versions

v1.1.4 → v2.1.42025-06-04

v1.1.5 → v2.1.52025-06-10

v1.1.6 → v2.1.62025-07-01

v1.1.7 → v2.1.82025-10-23

1.x-dev → v2.1.92025-12-18

PHP version history (3 changes)v0.0.1PHP ^8.1

v1.0.0-alpha1PHP ^7.4 || ^8.0

1.x-devPHP ^8.3

### Community

Maintainers

![](https://www.gravatar.com/avatar/0a4237641d319299706ec73bdcf9e998a82bc10343c3f03b5130409ca53baec2?d=identicon)[Cambis](/maintainers/Cambis)

---

Top Contributors

[![Cambis](https://avatars.githubusercontent.com/u/12287346?v=4)](https://github.com/Cambis "Cambis (344 commits)")[![maxime-rainville](https://avatars.githubusercontent.com/u/1168676?v=4)](https://github.com/maxime-rainville "maxime-rainville (1 commits)")

---

Tags

phpstansilverstripePHPStanstatic analysissilverstripe

### Embed Badge

![Health badge](/badges/cambis-silverstan/health.svg)

```
[![Health](https://phpackages.com/badges/cambis-silverstan/health.svg)](https://phpackages.com/packages/cambis-silverstan)
```

###  Alternatives

[larastan/larastan

Larastan - Discover bugs in your code without running it. A phpstan/phpstan extension for Laravel

6.4k43.5M5.2k](/packages/larastan-larastan)[ekino/phpstan-banned-code

Detected banned code using PHPStan

2925.6M92](/packages/ekino-phpstan-banned-code)[shipmonk/dead-code-detector

Dead code detector to find unused PHP code via PHPStan extension. Can automatically remove dead PHP code. Supports libraries like Symfony, Doctrine, PHPUnit etc. Detects dead cycles. Can detect dead code that is tested.

3462.2M52](/packages/shipmonk-dead-code-detector)[szepeviktor/phpstan-wordpress

WordPress extensions for PHPStan

3287.8M898](/packages/szepeviktor-phpstan-wordpress)[staabm/phpstan-dba

2912.3M2](/packages/staabm-phpstan-dba)[staabm/phpstan-todo-by

1991.8M55](/packages/staabm-phpstan-todo-by)

PHPackages © 2026

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