Giter Site home page Giter Site logo

mglaman / phpstan-drupal Goto Github PK

View Code? Open in Web Editor NEW
183.0 9.0 70.0 1018 KB

Extension for PHPStan to allow analysis of Drupal code.

Home Page: https://phpstan-drupal.mglaman.dev/

License: MIT License

PHP 99.91% Shell 0.09%
phpstan drupal static-analysis php hacktoberfest

phpstan-drupal's Introduction

phpstan-drupal

Tests CircleCI

Extension for PHPStan to allow analysis of Drupal code.

PHPStan is able to discover symbols by using autoloading provided by Composer. However, Drupal does not provide autoloading information for modules and themes. This project registers those namespaces so that PHPStan can properly discover symbols in your Drupal code base automatically.

Sponsors

undpaul Optasy Fame Helsinki

Would you like to sponsor?

Usage

When you are using phpstan/extension-installer, phpstan.neon will be automatically included.

Manual installation

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

includes:
    - vendor/mglaman/phpstan-drupal/extension.neon

To include Drupal specific analysis rules, include this file:

includes:
    - vendor/mglaman/phpstan-drupal/rules.neon

Getting help

Ask for assistance in the discussions or #phpstan channel on Drupal Slack.

Excluding tests from analysis

To exclude tests from analysis, add the following parameter

parameters:
	excludePaths:
		- *Test.php
		- *TestBase.php

Deprecation testing

This project depends on phpstan/phpstan-deprecation-rules which adds deprecation rules. We provide Drupal-specific deprecated scope resolvers.

To only handle deprecation testing, use a phpstan.neon like this:

parameters:
	customRulesetUsed: true
	reportUnmatchedIgnoredErrors: false
	# Ignore phpstan-drupal extension's rules.
	ignoreErrors:
		- '#\Drupal calls should be avoided in classes, use dependency injection instead#'
		- '#Plugin definitions cannot be altered.#'
		- '#Missing cache backend declaration for performance.#'
		- '#Plugin manager has cache backend specified but does not declare cache tags.#'
includes:
	- vendor/mglaman/phpstan-drupal/extension.neon
	- vendor/phpstan/phpstan-deprecation-rules/rules.neon

To disable deprecation rules while using phpstan/extension-installer, you can do the following:

{
  "extra": {
    "phpstan/extension-installer": {
      "ignore": [
        "phpstan/phpstan-deprecation-rules"
      ]
    }
  }
}

See the extension-installer documentation for more information: https://github.com/phpstan/extension-installer#ignoring-a-particular-extension

Adapting to your project

Specifying your Drupal project's root

By default, the PHPStan Drupal extension will try to determine your Drupal project's root directory based on the working directory that PHPStan is checking. If this is not working properly, you can explicitly define the Drupal project's root directory using the drupal.drupal_root parameter.

parameters:
	drupal:
		drupal_root: /path/to/drupal

You can also use container parameters. For instance you can always set it to the current working directory.

parameters:
	drupal:
		drupal_root: %currentWorkingDirectory%

Entity storage mappings.

The EntityTypeManagerGetStorageDynamicReturnTypeExtension service helps map dynamic return types. This inspects the passed entity type ID and tries to return a known storage class, besides the default EntityStorageInterface. The default mapping can be found in extension.neon. For example:

parameters:
	drupal:
		entityMapping:
			block:
				class: Drupal\block\Entity\Block
				storage: Drupal\Core\Config\Entity\ConfigEntityStorage
			node:
				class: Drupal\node\Entity\Node
				storage: Drupal\node\NodeStorage
			taxonomy_term:
				class: Drupal\taxonomy\Entity\Term
				storage: Drupal\taxonomy\TermStorage
			user:
				class: Drupal\user\Entity\User
				storage: Drupal\user\UserStorage

To add support for custom entities, you may add the same definition in your project's phpstan.neon. See the following example for adding a mapping for Search API:

parameters:
	drupal:
		entityMapping:
			search_api_index:
				class: Drupal\search_api\Entity\Index
				storage: Drupal\search_api\Entity\SearchApiConfigEntityStorage
			search_api_server:
				class: Drupal\search_api\Entity\Server
				storage: Drupal\search_api\Entity\SearchApiConfigEntityStorage			    

Similarly, the EntityStorageDynamicReturnTypeExtension service helps to determine the type of the entity which is loaded, created etc.. when using an entity storage. For instance when using

$node = \Drupal::entityTypeManager()->getStorage('node')->create(['type' => 'page', 'title' => 'foo']);

It helps with knowing the type of the $node variable is Drupal\node\Entity\Node.

The default mapping can be found in extension.neon:

parameters:
	drupal:
		entityMapping:
			block:
				class: Drupal\block\Entity\Block
				storage: Drupal\Core\Config\Entity\ConfigEntityStorage
			node:
				class: Drupal\node\Entity\Node
				storage: Drupal\node\NodeStorage
			taxonomy_term:
				class: Drupal\taxonomy\Entity\Term
				storage: Drupal\taxonomy\TermStorage
			user:
				class: Drupal\user\Entity\User
				storage: Drupal\user\UserStorage

To add support for custom entities, you may add the same definition in your project's phpstan.neon likewise.

Providing entity type mappings for a contrib module

Contributed modules can provide their own mapping that can be automatically registered with a user's code base when they use the phpstan/extension-installer. The extension installer scans installed package's composer.json for a value in extra.phpstan. This will automatically bundle the defined include that contains an entity mapping configuration.

For example, the Paragraphs module could have the following entity_mapping.neon file:

parameters:
	entityMapping:
		paragraph:
			class: Drupal\paragraphs\Entity\Paragraph
		paragraphs_type:
			class: Drupal\paragraphs\Entity\ParagraphsType

Then in the composer.json for Paragraphs, the entity_mapping.neon would be provided as a PHPStan include

{
  "name": "drupal/paragraphs",
  "description": "Enables the creation of Paragraphs entities.",
  "type": "drupal-module",
  "license": "GPL-2.0-or-later",
  "require": {
    "drupal/entity_reference_revisions": "~1.3"
  },
  "extra": {
    "phpstan": {
      "includes": [
        "entity_mapping.neon"
      ]
    }
  }
}

phpstan-drupal's People

Contributors

alexpott avatar attrib avatar boegie avatar brambaud avatar cmlara avatar codebymikey avatar dependabot[bot] avatar dpi avatar drupol avatar eiriksm avatar goba avatar jacktonkin avatar jibran avatar larowlan avatar longwave avatar mad-briller avatar makertim avatar mallezie avatar mglaman avatar mparker17 avatar muglug avatar neclimdul avatar ondrejmirtes avatar ptt-homme avatar simonbaese avatar szepeviktor avatar traviscarden avatar tstoeckler avatar vaish avatar xendk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

phpstan-drupal's Issues

Can your extension be used standalone on a module ?

Hi,

I'm trying to use your extension for a specific module. Which means that I placed the phpstan.neon file at the root of my module, and not at the root of a complete drupal installation.
My module is a separate project, registered in a private composer index (satis) and has a specific continuous integration tunnel configured in gitlab. I need to be able to analyse the code standalone.

This is my configuration file :

parameters:
	level: 7
includes:
	- vendor/phpstan/phpstan-phpunit/extension.neon
	- vendor/mglaman//phpstan-drupal/extension.neon

And this is the output of the phpstan analyse src command

ote: Using configuration file /app/phpstan.neon.
PHP Fatal error:  Uncaught TypeError: is_dir() expects parameter 1 to be a valid path, boolean given in /app/vendor/mglaman/phpstan-drupal/src/Drupal/ExtensionDiscovery.php:320
Stack trace:
#0 /app/vendor/mglaman/phpstan-drupal/src/Drupal/ExtensionDiscovery.php(320): is_dir(false)
#1 /app/vendor/mglaman/phpstan-drupal/src/Drupal/ExtensionDiscovery.php(139): PHPStan\Drupal\ExtensionDiscovery->scanDirectory('')
#2 /app/vendor/mglaman/phpstan-drupal/src/DependencyInjection/DrupalExtension.php(83): PHPStan\Drupal\ExtensionDiscovery->scan('profile')
#3 /composer/vendor/nette/di/src/DI/Compiler.php(215): PHPStan\DependencyInjection\DrupalExtension->loadConfiguration()
#4 /composer/vendor/nette/di/src/DI/Compiler.php(175): Nette\DI\Compiler->processExtensions()
#5 /composer/vendor/nette/bootstrap/src/Bootstrap/Configurator.php(306): Nette\DI\Compiler->compile()
#6 [internal function]: Nette\Configurator->generateContainer(Object(Nette\DI\Compiler))
#7 /composer/vendor/nette/di/src/DI/ContainerLoader.php(125): call_user_func_array(Arr in /app/vendor/mglaman/phpstan-drupal/src/Drupal/ExtensionDiscovery.php on line 320

When I remove your extension from the includes section, everything works as it should !

Thanks in advance !

Extension service provider classes are not autoloaded.

The pattern is camel case of the extension with ServiceProvider appended.

 ------ ------------------------------------------------------------------------- 
  Line   src/EntityReferenceRevisionsServiceProvider.php                          
 ------ ------------------------------------------------------------------------- 
         Class                                                                    
         Drupal\entity_reference_revisions\EntityReferenceRevisionsServiceProvid  
         er was not found while trying to analyse it - autoloading is probably    
         not configured properly.                                                 
 ------ ------------------------------------------------------------------------- 

Some functions are not recognized

In a Drupal 8.8 context I'm checking my module drd_agent and get the following 3 errors:

  22     Function _locale_translation_default_update_options not found.  
  24     Function locale_translation_batch_update_build not found.       
  27     Function locale_config_batch_update_components not found.       

The corresponding PHP code is this:

    if ($this->moduleHandler->moduleExists('locale')) {
      $this->moduleHandler->loadInclude('locale', 'fetch.inc');
      $this->moduleHandler->loadInclude('locale', 'bulk.inc');

      $langcodes = array_keys(locale_translatable_language_list());

      // Set the translation import options. This determines if existing
      // translations will be overwritten by imported strings.
      $options = _locale_translation_default_update_options();
      locale_translation_clear_status();
      $batch = locale_translation_batch_update_build([], $langcodes, $options);
      batch_set($batch);
      // Set a batch to update configuration as well.
      if ($batch = locale_config_batch_update_components($options, $langcodes)) {
        batch_set($batch);
      }
      batch_process();

That's strange for several reasons:

  • The functions do exist
  • The locale module is enabled
  • What confuses me the most: not all functions in this code block get complaints, just the 3

I wasn't able to figure out what should be wrong with my code. Or is it the drupal-check tool? Any help much appreciated.

Support *.inc files provided by module

How is drupal-check installed?

  • drupal-check is installed using the phar

Environment:

  • Linux
  • PHP Version: 7.2
  • Drupal core: 8.7.x

Describe the bug
Function not found while the module that contains the function is declared as dependency.
For example i have a dependency to the update manager module - drupal:update that contains update_calculate_project_data function, at the execution of drupal-check, I have the following error :

Function update_calculate_project_data not found.

Console output

Performing deprecation checks
Performing analysis checks
Current working directory: /var/www/html/www
Using Drupal root: /var/www/html/www
Using vendor root: /var/www/html/vendor
Using autoloader: /var/www/html/vendor/autoload.php
/var/www/html/www/modules/custom/available_updates/src/Controller/AvailableUpdatesController.php
/var/www/html/www/modules/custom/available_updates/tests/src/Functional/AvailableUpdatesTest.php


Line src/Controller/AvailableUpdatesController.php


51 Function update_calculate_project_data not found.


[ERROR] Found 1 error

\Drupal\Core\Config\ExtensionInstallStorage::__construct should be triggering deprecations.

Service definition:

config.storage.schema:
    class: Drupal\Core\Config\ExtensionInstallStorage
    arguments: ['@config.storage', 'config/schema', '', true, '%install_profile%']

__construct

  public function __construct(StorageInterface $config_storage, $directory = self::CONFIG_INSTALL_DIRECTORY, $collection = StorageInterface::DEFAULT_COLLECTION, $include_profile = TRUE, $profile = NULL) {
    parent::__construct($directory, $collection);
    $this->configStorage = $config_storage;
    $this->includeProfile = $include_profile;
    if (is_null($profile)) {
      @trigger_error('Install profile will be a mandatory parameter in Drupal 9.0.', E_USER_DEPRECATED);
    }
    $this->installProfile = $profile ?: \Drupal::installProfile();
  }

Need to test if the parameter is empty. If so, why no trigger.

Autoloading is broken after PHPStan builds an analysis cache

Replicate:

Clear PHPStan cache.

PHPSTAN_CACHE_DIR=$(php -r "print sys_get_temp_dir() . '/phpstan';")
rm -rf $PHPSTAN_CACHE_DIR

Run analyze

./bin/phpstan analyze web/modules/contrib/address

๐Ÿ‘runs

Run it again:

./bin/phpstan analyze web/modules/contrib/address

errors about loading.

This is due to #7

Is it normal that Drupal has around 1500 errors with the following config?

Hi,

I'm trying out phpstan for drupal for the first time and was wondering if it's normal to have lots of errors (+/- 1500) after a level one run on Drupal Core 8.7.5:

includes:
    - vendor/mglaman/phpstan-drupal/extension.neon
drupal:
    drupal_root: /home/verbral/github/verbruggenalex/drupal-project/web
parameters:
    excludes_analyse:
        - *Test.php
        - *TestBase.php
        - *sites/default/files/php/twig/*
        - *modules/contrib/*
    customRulesetUsed: true
    reportUnmatchedIgnoredErrors: false
    ignoreErrors:
        - '#\Drupal calls should be avoided in classes, use dependency injection instead#'
vendor/bin/phpstan analyse web --level 1 ``` verbral@ubuntu:~/github/verbruggenalex/drupal-project$ time docker-compose exec web vendor/bin/phpstan analyse web --level 1 Note: Using configuration file /home/verbral/github/verbruggenalex/drupal-project/phpstan.neon. 2843/5277 [โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘] 53%PHP Warning: sprintf(): Too few arguments in /home/verbral/github/verbruggenalex/drupal-project/vendor/phpstan/phpstan/src/Type/Php/SprintfFunctionDynamicReturnTypeExtension.php on line 39

Warning: sprintf(): Too few arguments in /home/verbral/github/verbruggenalex/drupal-project/vendor/phpstan/phpstan/src/Type/Php/SprintfFunctionDynamicReturnTypeExtension.php on line 39
4474/5277 [โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–‘โ–‘โ–‘โ–‘โ–‘] 84%PHP Warning: sprintf(): Too few arguments in /home/verbral/github/verbruggenalex/drupal-project/vendor/phpstan/phpstan/src/Type/Php/SprintfFunctionDynamicReturnTypeExtension.php on line 39

Warning: sprintf(): Too few arguments in /home/verbral/github/verbruggenalex/drupal-project/vendor/phpstan/phpstan/src/Type/Php/SprintfFunctionDynamicReturnTypeExtension.php on line 39
5277/5277 [โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–“] 100%


Line core/authorize.php


57 Function authorize_access_allowed not found while trying to analyse it - autoloading is probably not configured properly.
72 Variable $request might not be defined.
89 Function authorize_access_allowed not found.



Line core/includes/batch.inc


107 Variable $response might not be defined.
186 Function _batch_process invoked with 1 parameter, 0 required.
348 Variable $old_set might not be defined.
349 Variable $old_set might not be defined.
350 Variable $old_set might not be defined.
355 Variable $finished might not be defined.
474 Variable $_SESSION in isset() always exists and is not nullable.



Line core/includes/common.inc


738 Variable $tabledrag_id in isset() always exists and is not nullable.
1303 Variable $updaters in isset() always exists and is not nullable.
1323 Variable $info in isset() always exists and is not nullable.



Line core/includes/errors.inc


260 Function install_display_output invoked with 3 parameters, 2 required.



Line core/includes/file.inc


1026 Variable $dir_has_slash might not be defined.



Line core/includes/install.core.inc


1776 Function locale_translate_get_interface_translation_files not found.
1801 Function locale_translation_clear_cache_projects not found.
1802 Function locale_translation_check_projects_local not found.
1829 Function locale_translation_build_projects not found.
1833 Function _locale_translation_default_update_options not found.
1834 Function locale_translation_batch_update_build not found.
1840 Function locale_config_batch_update_components not found.



Line core/includes/install.inc


277 Function _drupal_rewrite_settings_is_array_index invoked with 2 parameters, 1 required.
288 Variable $index might not be defined.
291 Variable $index might not be defined.
306 Variable $current might not be defined.
308 Variable $index might not be defined.



Line core/includes/pager.inc


151 Variable $query in isset() always exists and is not nullable.
282 Variable $items might not be defined.



Line core/includes/theme.maintenance.inc


56 Variable $custom_theme might not be defined.



Line core/lib/Drupal/Component/Assertion/Handle.php


32 Class AssertionError constructor invoked with 5 parameters, 0-3 required.



Line core/lib/Drupal/Component/Datetime/DateTimePlus.php


265 Variable $test_time might not be defined.
327 Call to an undefined method Drupal\Component\Datetime\DateTimePlus::getTimeZone().
703 Variable $value might not be defined.



Line core/lib/Drupal/Component/DependencyInjection/Dumper/OptimizedPhpArrayDumper.php


64 Access to an undefined property Drupal\Component\DependencyInjection\Dumper\OptimizedPhpArrayDumper::$aliases.
408 Class Symfony\Component\ExpressionLanguage\Expression not found.
449 Access to an undefined property Drupal\Component\DependencyInjection\Dumper\OptimizedPhpArrayDumper::$aliases.



Line core/lib/Drupal/Component/DependencyInjection/PhpArrayContainer.php


30 Drupal\Component\DependencyInjection\PhpArrayContainer::__construct() does not call parent constructor from
Drupal\Component\DependencyInjection\Container.



Line core/lib/Drupal/Component/Diff/DiffFormatter.php


79 Variable $x0 might not be defined.
79 Variable $x0 might not be defined.
79 Variable $y0 might not be defined.
79 Variable $y0 might not be defined.
107 Variable $x0 might not be defined.
107 Variable $x0 might not be defined.
107 Variable $y0 might not be defined.
107 Variable $y0 might not be defined.



Line core/lib/Drupal/Component/Diff/Engine/DiffEngine.php


39 Access to an undefined property Drupal\Component\Diff\Engine\DiffEngine::$xchanged.
39 Access to an undefined property Drupal\Component\Diff\Engine\DiffEngine::$ychanged.
40 Access to an undefined property Drupal\Component\Diff\Engine\DiffEngine::$xv.
40 Access to an undefined property Drupal\Component\Diff\Engine\DiffEngine::$yv.
41 Access to an undefined property Drupal\Component\Diff\Engine\DiffEngine::$xind.
41 Access to an undefined property Drupal\Component\Diff\Engine\DiffEngine::$yind.
173 Access to an undefined property Drupal\Component\Diff\Engine\DiffEngine::$xv.
178 Access to an undefined property Drupal\Component\Diff\Engine\DiffEngine::$yv.
181 Access to an undefined property Drupal\Component\Diff\Engine\DiffEngine::$lcs.
182 Access to an undefined property Drupal\Component\Diff\Engine\DiffEngine::$seq.
183 Access to an undefined property Drupal\Component\Diff\Engine\DiffEngine::$in_seq.
197 Access to an undefined property Drupal\Component\Diff\Engine\DiffEngine::$xv.
197 Access to an undefined property Drupal\Component\Diff\Engine\DiffEngine::$yv.
213 Variable $k might not be defined.
214 Variable $k might not be defined.
217 Variable $k might not be defined.
218 Variable $k might not be defined.
245 Access to an undefined property Drupal\Component\Diff\Engine\DiffEngine::$lcs.
246 Access to an undefined property Drupal\Component\Diff\Engine\DiffEngine::$seq.
247 Access to an undefined property Drupal\Component\Diff\Engine\DiffEngine::$lcs.
247 Access to an undefined property Drupal\Component\Diff\Engine\DiffEngine::$seq.
248 Access to an undefined property Drupal\Component\Diff\Engine\DiffEngine::$in_seq.
249 Access to an undefined property Drupal\Component\Diff\Engine\DiffEngine::$lcs.
255 Access to an undefined property Drupal\Component\Diff\Engine\DiffEngine::$seq.
263 Access to an undefined property Drupal\Component\Diff\Engine\DiffEngine::$seq.
265 Access to an undefined property Drupal\Component\Diff\Engine\DiffEngine::$in_seq.
265 Access to an undefined property Drupal\Component\Diff\Engine\DiffEngine::$seq.
266 Access to an undefined property Drupal\Component\Diff\Engine\DiffEngine::$seq.
286 Access to an undefined property Drupal\Component\Diff\Engine\DiffEngine::$xv.
286 Access to an undefined property Drupal\Component\Diff\Engine\DiffEngine::$yv.
292 Access to an undefined property Drupal\Component\Diff\Engine\DiffEngine::$xv.
292 Access to an undefined property Drupal\Component\Diff\Engine\DiffEngine::$yv.
312 Access to an undefined property Drupal\Component\Diff\Engine\DiffEngine::$ychanged.
312 Access to an undefined property Drupal\Component\Diff\Engine\DiffEngine::$yind.
315 Access to an undefined property Drupal\Component\Diff\Engine\DiffEngine::$xchanged.
315 Access to an undefined property Drupal\Component\Diff\Engine\DiffEngine::$xind.
320 Variable $seps might not be defined.
321 Variable $seps might not be defined.
322 Variable $seps might not be defined.



Line core/lib/Drupal/Component/FileCache/NullFileCache.php


24 Constructor of class Drupal\Component\FileCache\NullFileCache has an unused parameter $cache_backend_class.
24 Constructor of class Drupal\Component\FileCache\NullFileCache has an unused parameter $cache_backend_configuration.
24 Constructor of class Drupal\Component\FileCache\NullFileCache has an unused parameter $collection.
24 Constructor of class Drupal\Component\FileCache\NullFileCache has an unused parameter $prefix.



Line core/lib/Drupal/Component/Gettext/PoStreamReader.php


352 Class Drupal\Component\Render\FormattableMarkup constructor invoked with 3 parameters, 2 required.
506 Variable $log_vars might not be defined.



Line core/lib/Drupal/Component/Plugin/ContextAwarePluginBase.php


45 Access to an undefined property Drupal\Component\Plugin\ContextAwarePluginBase::$contexts.



Line core/lib/Drupal/Component/Plugin/Discovery/StaticDiscoveryDecorator.php


22 Property Drupal\Component\Plugin\Discovery\StaticDiscoveryDecorator::$registerDefinitions has unknown class Callable as its
type.
33 Parameter $registerDefinitions of method Drupal\Component\Plugin\Discovery\StaticDiscoveryDecorator::__construct() has
invalid typehint type Callable.



Line core/lib/Drupal/Component/Plugin/PluginManagerBase.php


99 Call to an undefined method Drupal\Component\Plugin\PluginManagerBase::getFallbackPluginId().



Line core/lib/Drupal/Component/ProxyBuilder/ProxyBuilder.php


169 Variable $proxy_class_shortname might not be defined.



Line core/lib/Drupal/Component/Serialization/YamlPecl.php


23 Constant YAML_LN_BREAK not found.
23 Constant YAML_UTF8_ENCODING not found.
54 Constant YAML_BOOL_TAG not found.



Line core/lib/Drupal/Component/Transliteration/PhpTransliteration.php


271 Variable $overrides in isset() is never defined.
299 Variable $base in isset() is never defined.



Line core/lib/Drupal/Component/Utility/Color.php


84 Variable $rgb might not be defined.



Line core/lib/Drupal/Component/Utility/Html.php


460 Class DOMXPath referenced with incorrect case: DOMXpath.



Line core/lib/Drupal/Component/Utility/Variable.php


33 Static method Drupal\Component\Utility\Variable::export() invoked with 3 parameters, 1-2 required.



Line core/lib/Drupal/Component/Uuid/Pecl.php


14 Constant UUID_TYPE_DEFAULT not found.
14 Function uuid_create not found.



Line core/lib/Drupal/Core/Access/AccessResult.php


167 Variable $permission might not be defined.



Line core/lib/Drupal/Core/Action/ActionBase.php


22 Method Drupal\Core\Executable\ExecutableInterface::execute() invoked with 1 parameter, 0 required.



Line core/lib/Drupal/Core/Action/ActionManager.php


34 Plugin manager has cache backend specified but does not declare cache tags.



Line core/lib/Drupal/Core/Ajax/CloseModalDialogCommand.php


18 Drupal\Core\Ajax\CloseModalDialogCommand::__construct() does not call parent constructor from
Drupal\Core\Ajax\CloseDialogCommand.



Line core/lib/Drupal/Core/Ajax/SetDialogTitleCommand.php


21 Drupal\Core\Ajax\SetDialogTitleCommand::__construct() does not call parent constructor from
Drupal\Core\Ajax\SetDialogOptionCommand.



Line core/lib/Drupal/Core/Annotation/ContextDefinition.php


99 Drupal\Core\Annotation\ContextDefinition::__construct() does not call parent constructor from
Drupal\Component\Annotation\Plugin.



Line core/lib/Drupal/Core/Archiver/ArchiverManager.php


30 Plugin manager has cache backend specified but does not declare cache tags.



Line core/lib/Drupal/Core/Archiver/Tar.php


87 Return typehint of method Drupal\Core\Archiver\Tar::getArchive() has invalid type Drupal\Core\Archiver\Archive_Tar.



Line core/lib/Drupal/Core/Asset/CssCollectionGrouper.php


66 Variable $group_keys might not be defined.
75 Variable $group_keys might not be defined.



Line core/lib/Drupal/Core/Asset/Exception/InvalidLibraryFileException.php


8 Class RuntimeException referenced with incorrect case: RunTimeException.



Line core/lib/Drupal/Core/Asset/JsCollectionGrouper.php


52 Variable $group_keys might not be defined.
60 Variable $group_keys might not be defined.



Line core/lib/Drupal/Core/Block/BlockManager.php


47 Plugin manager has cache backend specified but does not declare cache tags.



Line core/lib/Drupal/Core/Cache/Apcu4Backend.php


18 Instantiated class APCIterator not found.



Line core/lib/Drupal/Core/Cache/ApcuBackend.php


270 Class APCuIterator referenced with incorrect case: APCUIterator.



Line core/lib/Drupal/Core/Cache/BackendChain.php


38 Constructor of class Drupal\Core\Cache\BackendChain has an unused parameter $bin.



Line core/lib/Drupal/Core/Cache/Context/AccountPermissionsCacheContext.php


31 Drupal\Core\Cache\Context\AccountPermissionsCacheContext::__construct() does not call parent constructor from
Drupal\Core\Cache\Context\UserCacheContextBase.



Line core/lib/Drupal/Core/Cache/Context/CacheContextsManager.php


265 Access to an undefined property Drupal\Core\Cache\Context\CacheContextsManager::$validContextTokens.



Line core/lib/Drupal/Core/Cache/NullBackend.php


26 Constructor of class Drupal\Core\Cache\NullBackend has an unused parameter $bin.



Line core/lib/Drupal/Core/Cache/PhpBackend.php


255 Access to an undefined property Drupal\Core\Cache\PhpBackend::$storage.



Line core/lib/Drupal/Core/Condition/ConditionManager.php


40 Plugin manager has cache backend specified but does not declare cache tags.



Line core/lib/Drupal/Core/Config/ConfigInstaller.php


241 Method Drupal\Core\Config\ConfigInstaller::createConfiguration() invoked with 3 parameters, 2 required.



Line core/lib/Drupal/Core/Config/ConfigRenameEvent.php


25 Drupal\Core\Config\ConfigRenameEvent::__construct() does not call parent constructor from
Drupal\Core\Config\ConfigCrudEvent.



Line core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php


193 Method Drupal\Core\Entity\EntityStorageBase::mapFromStorageRecords() invoked with 2 parameters, 1 required.
425 Return typehint of method Drupal\Core\Config\Entity\ConfigEntityStorage::_doCreateFromStorageRecord() has invalid type
Drupal\Core\Config\ConfigEntityInterface.



Line core/lib/Drupal/Core/Config/Entity/Query/Condition.php


160 Variable $value in isset() always exists and is not nullable.
163 Variable $value in isset() always exists and is not nullable.



Line core/lib/Drupal/Core/Config/Entity/Query/QueryFactory.php


54 Access to an undefined property Drupal\Core\Config\Entity\Query\QueryFactory::$keyValueFactory.
55 Access to an undefined property Drupal\Core\Config\Entity\Query\QueryFactory::$configManager.
63 Access to an undefined property Drupal\Core\Config\Entity\Query\QueryFactory::$keyValueFactory.
83 Access to an undefined property Drupal\Core\Config\Entity\Query\QueryFactory::$keyValueFactory.
227 Access to an undefined property Drupal\Core\Config\Entity\Query\QueryFactory::$configManager.
229 Access to an undefined property Drupal\Core\Config\Entity\Query\QueryFactory::$configManager.
242 Access to an undefined property Drupal\Core\Config\Entity\Query\QueryFactory::$configManager.
244 Access to an undefined property Drupal\Core\Config\Entity\Query\QueryFactory::$configManager.



Line core/lib/Drupal/Core/Config/ExtensionInstallStorage.php


125 Variable $theme_list might not be defined.



Line core/lib/Drupal/Core/Config/TypedConfigManager.php


54 Drupal\Core\Config\TypedConfigManager::__construct() does not call parent constructor from
Drupal\Core\TypedData\TypedDataManager.
54 Plugin manager has cache backend specified but does not declare cache tags.



Line core/lib/Drupal/Core/Controller/ControllerResolver.php


52 Drupal\Core\Controller\ControllerResolver::__construct() does not call parent constructor from
Symfony\Component\HttpKernel\Controller\ControllerResolver.
132 Call to sprintf contains 1 placeholder, 2 values given.
132 Class Drupal\Core\Controller\ArgumentResolverInterface not found.



Line core/lib/Drupal/Core/Database/Driver/mysql/Connection.php


527 Call to an undefined static method Drupal\Core\Database\Connection::serialize().



Line core/lib/Drupal/Core/Database/Driver/pgsql/Connection.php


321 Call to static method getDefault() on an unknown class Locale.



Line core/lib/Drupal/Core/Database/Driver/pgsql/Select.php


72 Variable $table_field might not be defined.



Line core/lib/Drupal/Core/Database/Driver/sqlite/Connection.php


227 Variable $args might not be defined.



Line core/lib/Drupal/Core/Database/Query/Select.php


146 Access to an undefined property Drupal\Core\Database\Query\Select::$alterTags.
154 Access to an undefined property Drupal\Core\Database\Query\Select::$alterTags.
161 Access to an undefined property Drupal\Core\Database\Query\Select::$alterTags.
168 Access to an undefined property Drupal\Core\Database\Query\Select::$alterTags.
175 Access to an undefined property Drupal\Core\Database\Query\Select::$alterMetaData.
183 Access to an undefined property Drupal\Core\Database\Query\Select::$alterMetaData.



Line core/lib/Drupal/Core/Database/Query/Truncate.php


40 Access to an undefined property Drupal\Core\Database\Query\Truncate::$condition.
47 Access to an undefined property Drupal\Core\Database\Query\Truncate::$condition.



Line core/lib/Drupal/Core/Database/Schema.php


653 Call to an undefined method Drupal\Core\Database\Schema::createTableSql().



Line core/lib/Drupal/Core/Database/Statement.php


63 Variable $query_start might not be defined.



Line core/lib/Drupal/Core/Database/StatementPrefetch.php


189 Variable $query_start might not be defined.
285 Function array_unshift invoked with 1 parameter, at least 2 required.



Line core/lib/Drupal/Core/Datetime/DateFormatter.php


289 Variable $interval_output might not be defined.
289 Variable $interval_output might not be defined.



Line core/lib/Drupal/Core/DependencyInjection/ContainerBuilder.php


39 Return typehint of method Drupal\Core\DependencyInjection\ContainerBuilder::getProxyInstantiator() has invalid type
Drupal\Core\DependencyInjection\InstantiatorInterface.



Line core/lib/Drupal/Core/DependencyInjection/YamlFileLoader.php


398 Class Symfony\Component\DependencyInjection\Reference constructor invoked with 3 parameters, 1-2 required.



Line core/lib/Drupal/Core/Display/VariantManager.php


30 Plugin manager has cache backend specified but does not declare cache tags.



Line core/lib/Drupal/Core/DrupalKernel.php


945 Variable $container might not be defined.
947 Variable $container might not be defined.
976 Variable $container_definition might not be defined.



Line core/lib/Drupal/Core/Entity/ContentEntityBase.php


189 Drupal\Core\Entity\ContentEntityBase::__construct() does not call parent constructor from Drupal\Core\Entity\EntityBase.



Line core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php


957 Variable $current_affected in isset() always exists and is not nullable.



Line core/lib/Drupal/Core/Entity/Element/EntityAutocomplete.php


298 Variable $id might not be defined.



Line core/lib/Drupal/Core/Entity/Entity/EntityFormDisplay.php


93 Variable $candidate_ids might not be defined.
99 Variable $candidate_ids might not be defined.



Line core/lib/Drupal/Core/Entity/EntityAutocompleteMatcher.php


61 Variable $string in isset() always exists and is not nullable.



Line core/lib/Drupal/Core/Entity/EntityBase.php


438 Access to an undefined property Drupal\Core\Entity\EntityBase::$id.



Line core/lib/Drupal/Core/Entity/EntityDisplayBase.php


570 Access to an undefined property Drupal\Core\Entity\EntityDisplayBase::$_serializedKeys.
580 Access to an undefined property Drupal\Core\Entity\EntityDisplayBase::$_serializedKeys.



Line core/lib/Drupal/Core/Entity/EntityReferenceSelection/SelectionPluginManager.php


24 Plugin manager has cache backend specified but does not declare cache tags.



Line core/lib/Drupal/Core/Entity/EntityResolverManager.php


237 Access to an undefined property Drupal\Core\Entity\EntityResolverManager::$entityTypes.



Line core/lib/Drupal/Core/Entity/EntityTypeEvent.php


35 Drupal\Core\Entity\EntityTypeEvent::__construct() does not call parent constructor from
Symfony\Component\EventDispatcher\GenericEvent.



Line core/lib/Drupal/Core/Entity/Plugin/EntityReferenceSelection/DefaultSelection.php


286 Variable $bundle_options might not be defined.



Line core/lib/Drupal/Core/Entity/Query/QueryBase.php


149 Access to an undefined property Drupal\Core\Entity\Query\QueryBase::$conjunction.



Line core/lib/Drupal/Core/Entity/Query/Sql/Query.php


110 Access to an undefined property Drupal\Core\Entity\Query\Sql\Query::$conjunction.



Line core/lib/Drupal/Core/Entity/Query/Sql/Tables.php


285 Variable $relationship_specifier might not be defined.
286 Variable $relationship_specifier might not be defined.
289 Variable $relationship_specifier might not be defined.
289 Variable $relationship_specifier might not be defined.
292 Variable $relationship_specifier might not be defined.
302 Variable $next_index_prefix might not be defined.
305 Variable $relationship_specifier might not be defined.
309 Variable $sql_column might not be defined.
309 Variable $table might not be defined.



Line core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php


1405 Variable $revision_query might not be defined.
1422 Variable $revision_query might not be defined.



Line core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php


1719 Variable $transaction might not be defined.
1810 Variable $transaction might not be defined.



Line core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php


87 Access to an undefined property Drupal\Core\EventSubscriber\FinishResponseSubscriber::$cacheContextsManager.
158 Access to an undefined property Drupal\Core\EventSubscriber\FinishResponseSubscriber::$cacheContextsManager.



Line core/lib/Drupal/Core/EventSubscriber/RedirectResponseSubscriber.php


38 Access to an undefined property Drupal\Core\EventSubscriber\RedirectResponseSubscriber::$requestContext.
74 Access to an undefined property Drupal\Core\EventSubscriber\RedirectResponseSubscriber::$requestContext.



Line core/lib/Drupal/Core/Extension/Discovery/RecursiveExtensionFilterIterator.php


136 Call to an undefined method Drupal\Core\Extension\Discovery\RecursiveExtensionFilterIterator::isDir().



Line core/lib/Drupal/Core/Extension/ModuleHandler.php


233 Variable $graph might not be defined.



Line core/lib/Drupal/Core/Extension/ModuleInstaller.php


266 Variable $source_storage might not be defined.



Line core/lib/Drupal/Core/Field/Entity/BaseFieldOverride.php


198 Access to an undefined property Drupal\Core\Field\Entity\BaseFieldOverride::$original.
199 Access to an undefined property Drupal\Core\Field\Entity\BaseFieldOverride::$original.
201 Access to an undefined property Drupal\Core\Field\Entity\BaseFieldOverride::$original.
202 Access to an undefined property Drupal\Core\Field\Entity\BaseFieldOverride::$original.
204 Access to an undefined property Drupal\Core\Field\Entity\BaseFieldOverride::$original.



Line core/lib/Drupal/Core/Field/FieldConfigBase.php


590 Access to an undefined property Drupal\Core\Field\FieldConfigBase::$definition.



Line core/lib/Drupal/Core/Field/FieldDefinition.php


179 Variable $callback in isset() always exists and is not nullable.



Line core/lib/Drupal/Core/Field/FieldItemList.php


255 Variable $values might not be defined.



Line core/lib/Drupal/Core/Field/FieldStorageDefinitionEvent.php


35 Drupal\Core\Field\FieldStorageDefinitionEvent::__construct() does not call parent constructor from
Symfony\Component\EventDispatcher\GenericEvent.



Line core/lib/Drupal/Core/Field/FieldTypePluginManager.php


42 Plugin manager has cache backend specified but does not declare cache tags.



Line core/lib/Drupal/Core/Field/FormatterPluginManager.php


44 Plugin manager has cache backend specified but does not declare cache tags.


.........................
.......................
..........................


Line sites/default/default.settings.php


675 Undefined variable: $app_root
675 Undefined variable: $site_path



Line sites/default/settings.php


675 Undefined variable: $app_root
675 Undefined variable: $site_path


[ERROR] Found 1429 errors

real 2m57.977s
user 0m0.712s
sys 0m0.461s

</details>

Ignore test database fixtures

While debugging failed migrate_drupal inspections, I saw this on my deprecation bot:

18:45:33 mmap() failed: [12] Cannot allocate memory
18:45:33 
18:45:33 mmap() failed: [12] Cannot allocate memory
18:45:33 PHP Fatal error:  Out of memory (allocated 2441084928) (tried to allocate 262144 bytes) in phar:///usr/local/bin/drupal-check/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinter/Standard.php on line 945

I'm going to bet it is due to the test fixtures.

Conflicts with Drush over nikic/php-parser (locked at v3.1.5)

Example output:

Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Installation request for nikic/php-parser (locked at v3.1.5) -> satisfiable by nikic/php-parser[v3.1.5].
    - drupal/upgrade_status 1.x-dev requires mglaman/phpstan-drupal 0.11.3 -> satisfiable by mglaman/phpstan-drupal[0.11.3].
    - drupal/upgrade_status 1.0.0-alpha1 requires mglaman/phpstan-drupal 0.11.3 -> satisfiable by mglaman/phpstan-drupal[0.11.3].
    - Conclusion: don't install mglaman/phpstan-drupal 0.11.3
    - Installation request for drupal/upgrade_status ^1.0 -> satisfiable by drupal/upgrade_status[1.x-dev, 1.0.0-alpha1].

PHPStan requires nikic/php-parser v4.

Drush requires "psy/psysh": "~0.6",. This allows for ^2 || ^3 || ^4. Composer installs v3. While ^4 is valid, Composer dies over the jump to a major version.

Don't load excluded files

I have a problem because I have the blazy module in my system. That module declares token_theme, if it does not exist.

Now the autoloader loads first https://cgit.drupalcode.org/blazy/tree/tests/modules/blazy_test/blazy_test.module#n91
and after that the "real" token_theme function. That fails with:

Fatal error: Cannot redeclare token_theme

I wanted to specify an exclude in my config, but that doesn't work

parameters:
  excludes_analyse:
    - blazy_test.module

What do you think is the best way to fix it?

Breaks when using PHPStan globally

This is a regressions from #25. We need to determine the Drupal root based on the global/magical "autoloaderInWorkingDirectory" variable

        $finder = new DrupalFinder();
        $finder->locateRoot(dirname($GLOBALS['autoloaderInWorkingDirectory'], 2));

Tests are not loading `config7.neon` as expected.

In the phpunit-drupal-phpstan.neon file we have the following declared:

parameters:
	level: 7

However, the level parameter means nothing outside of CommandHelper. We need to include the specific file properly

includes:
	- ../../../extension.neon
	- ../../../vendor/phpstan/phpstan/conf/config.level7.neon

TestSuites classes are not autoloaded

 ------ ------------------------------------------------------------------------- 
  Line   TestSuites/FunctionalTestSuite.php                                       
 ------ ------------------------------------------------------------------------- 
         Class Drupal\Tests\TestSuites\FunctionalTestSuite was not found while    
         trying to analyse it - autoloading is probably not configured properly.  
 ------ ------------------------------------------------------------------------- 
 ------ ------------------------------------------------------------------------- 
  Line   TestSuites/KernelTestSuite.php                                           
 ------ ------------------------------------------------------------------------- 
         Class Drupal\Tests\TestSuites\KernelTestSuite was not found while        
         trying to analyse it - autoloading is probably not configured properly.  
 ------ ------------------------------------------------------------------------- 
 ------ ------------------------------------------------------------------------ 
  Line   TestSuites/TestSuiteBase.php                                            
 ------ ------------------------------------------------------------------------ 
         Class Drupal\Tests\TestSuites\TestSuiteBase was not found while trying  
         to analyse it - autoloading is probably not configured properly.        
 ------ ------------------------------------------------------------------------ 
 ------ ------------------------------------------------------------------------ 
  Line   TestSuites/UnitTestSuite.php                                            
 ------ ------------------------------------------------------------------------ 
         Class Drupal\Tests\TestSuites\UnitTestSuite was not found while trying  
         to analyse it - autoloading is probably not configured properly.        
 ------ ------------------------------------------------------------------------ 

Run phpstan under webroot

Currently, phpstan only works when running the command in the directory where Drupal is located.

Is it possible to run the command under the webroot? e.g.:
www/vendor/bin/phpstan analyse www/modules/custom

Improve the extension

Hi, I'd like to discourage you from using the CompilerExtension concept. The fact that PHPStan uses Nette\DI is not a public API and can break. Also, it means that this PHPStan extension is not usable with phpstan-shim (PHAR) where Nette is prefixed.

Also, I will remove the global variables in the next version, I didn't realize that someone would access and read them intentionally - they're not part of PHPStan's official API :)

Redeclared function error

How is drupal-check installed?

  • drupal-check is installed using the phar
  • drupal-check is installed globally via Composer
  • drupal-check is installed globally using consolidation/cgr
  • [ x ] drupal-check is installed as a dependency to my project

Environment:

  • OS: Windows/macOS/Linux
  • PHP Version: 7.1
  • Drupal core: 8.7.3

Describe the bug
When Slick 8.x-1.1 and video_embed_field 8.x-1.x are in the codebase, you get an error like this, even when scanning the modules/custom folder.

PHP Fatal error:  Cannot redeclare video_embed_media_media_bundle_insert() (previously declared in modules/contrib/slick/tests/modules/slick_test/slick_test.module:39) in modules/contrib/video_embed_field/modules/video_embed_media/video_embed_media.module on line 18

Fatal error: Cannot redeclare video_embed_media_media_bundle_insert() (previously declared in modules/contrib/slick/tests/modules/slick_test/slick_test.module:39) in modules/contrib/video_embed_field/modules/video_embed_media/video_embed_media.module on line 18

In slick_test.module, the code is this

if (!function_exists('video_embed_media_media_bundle_insert')) {

  /**
   * Dummy function.
   */
  function video_embed_media_media_bundle_insert() {
    // Empty block to satisfy coder.
  }

}

Console output

$ vendor/bin/drupal-check htdocs/modules/custom -vvv
Current working directory: /Users/dieterblomme/.dropsolid_launchpad/projects/beobank
Using Drupal root: /Users/dieterblomme/.dropsolid_launchpad/projects/beobank/htdocs
Using vendor root: /Users/dieterblomme/.dropsolid_launchpad/projects/beobank/vendor
Using autoloader: /Users/dieterblomme/.dropsolid_launchpad/projects/beobank/vendor/autoload.php
PHP Fatal error:  Cannot redeclare video_embed_media_media_bundle_insert() (previously declared in /Users/dieterblomme/.dropsolid_launchpad/projects/beobank/htdocs/modules/contrib/slick/tests/modules/slick_test/slick_test.module:39) in /Users/dieterblomme/.dropsolid_launchpad/projects/beobank/htdocs/modules/contrib/video_embed_field/modules/video_embed_media/video_embed_media.module on line 18

Fatal error: Cannot redeclare video_embed_media_media_bundle_insert() (previously declared in /Users/dieterblomme/.dropsolid_launchpad/projects/beobank/htdocs/modules/contrib/slick/tests/modules/slick_test/slick_test.module:39) in /Users/dieterblomme/.dropsolid_launchpad/projects/beobank/htdocs/modules/contrib/video_embed_field/modules/video_embed_media/video_embed_media.module on line 18

Errors when loading extension files should not halt the inspection

An example is the Mandrill module.

// Load Mandrill library if found in module's /lib directory.
if (file_exists(drupal_get_path('module', 'mandrill') . '/lib/mandrill/src/Mandrill.php')) {
  require drupal_get_path('module', 'mandrill') . '/lib/mandrill/src/Mandrill.php';
}

This is due to drupal_get_path which calls drupal_get_filename and taps into the service container.

It is fixed with

                try {
                    require $module_dir . '/' . $module->getExtensionFilename();
                } catch (\Throwable $e) {
                    // Something prevent the extension file from loading.
                }

Issues installing latest versions

Hello,

I tried to install PHPStan on a new client this morning, and I got this:

john@tandem:~/lando/aer (updates)$ lando composer require --dev mglaman/phpstan-drupal phpstan/phpstan-deprecation-rules
Using version ^0.11.13 for mglaman/phpstan-drupal
Using version ^0.12.0 for phpstan/phpstan-deprecation-rules
./composer.json has been updated
> Drupal\Composer\Composer::ensureComposerVersion
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - phpstan/phpstan-deprecation-rules 0.12.0 conflicts with mglaman/phpstan-drupal[0.11.13].
    - phpstan/phpstan-deprecation-rules 0.12.x-dev conflicts with mglaman/phpstan-drupal[0.11.13].
    - Installation request for mglaman/phpstan-drupal ^0.11.13 -> satisfiable by mglaman/phpstan-drupal[0.11.13].
    - Installation request for phpstan/phpstan-deprecation-rules ^0.12.0 -> satisfiable by phpstan/phpstan-deprecation-rules[0.12.0, 0.12.x-dev].


Installation failed, reverting ./composer.json to its original content.

A workaround for now was to install everything via:

composer require --dev mglaman/phpstan-drupal:0.11.12 phpstan/phpstan-deprecation-rules:0.11.2

Enable configuration of docroot

Right now the extension assumes you have either docroot or web as your docroot. However, in one of our instances we use public_html and cannot chance this for the time being.

It would be great if we could configure the used docroot. If someone can point to the right extension points I would be more than interested to contribute.

Uncaught error: Cannot unset string offsets

I'm having issues getting this set up. When I try and run it, I get this error:

Note: Using configuration file /var/www/html/phpstan.neon.
PHP Fatal error:  Uncaught Error: Cannot unset string offsets in /var/www/html/vendor/mglaman/phpstan-drupal/src/DependencyInjection/DrupalExtension.php:152
Stack trace:
#0 /var/www/html/vendor/nette/di/src/DI/Compiler.php(229): PHPStan\DependencyInjection\DrupalExtension->loadConfiguration()
#1 /var/www/html/vendor/nette/di/src/DI/Compiler.php(204): Nette\DI\Compiler->processExtensions()
#2 /var/www/html/vendor/nette/di/src/DI/ContainerLoader.php(119): Nette\DI\Compiler->compile()
#3 /var/www/html/vendor/nette/di/src/DI/ContainerLoader.php(79): Nette\DI\ContainerLoader->generate('Container_bdd2b...', Array)
#4 /var/www/html/vendor/nette/di/src/DI/ContainerLoader.php(44): Nette\DI\ContainerLoader->loadFile('Container_bdd2b...', Array)
#5 /var/www/html/vendor/nette/bootstrap/src/Bootstrap/Configurator.php(242): Nette\DI\ContainerLoader->load(Array, Array)
#6 /var/www/html/vendor/nette/bootstrap/src/Bootstrap/Configurator.php(221): Nette\Configurator->loadContainer()
#7 /var/www/html/vendor/phpstan/phpstan/src/DependencyInjectio in /var/www/html/vendor/mglaman/phpstan-drupal/src/DependencyInjection/DrupalExtension.php on line 152'

This is the command that I'm running, though I get the same output if I run it inside the container:

ddev exec -d /var/www/html vendor/bin/phpstan web/modules/custom

The site repo is at https://github.com/PHPSouthWales/php-south-wales-drupal, it's a Drupal 8.7.3 built based on https://github.com/drupal-composer/drupal-project. I'm running PHP 7.3, though I get the same with 7.2 or 7.1.

It's my first time trying to set this up, so I could definitely be doing something wrong!

Gracefully handle and report ContainerNotInitializedException

Reference: mglaman/drupal-check#42

Currently, we skip known Drupal core modules which call \Drupal:: outside of the scope of any function in their .install file.

                $ignored_install_files = ['entity_test', 'entity_test_update', 'update_test_schema'];
                if (!in_array($module_name, $ignored_install_files, true)) {
                    require $module_dir . '/' . $module_name . '.install';
                }

Turns out that the Examples module does this, too, in tabledrag_example.

module_load_include('inc', 'tabledrag_example', 'tabledrag_example.data');

The loading of modules should be wrapped in a try/catch for this exception and throw a custom scoped exception. This can help the end user understand why this happened and how to fix it.

Fatal error - how to debug

Trying to use drupal-check -ad -vvv web/modules/custom/ but getting fatal
Not clear how to get which line causes it, because I have this issue only in 1 module but phpstorm shown all fine with it
Less verbose tells... but no way to pass --debug

 ------ ------------------------------------------------------------------------------------ 
         Internal error: Call to undefined method PhpParser\Node\Name::isSpecialClassName()  
         Run PHPStan with --debug option and post the stack trace to:                        
         https://github.com/phpstan/phpstan/issues/new

The -vvv tells

Performing deprecation checks
Performing analysis checks
Current working directory: /mnt
Using Drupal root: /mnt/web
Using vendor root: /mnt/vendor
Using autoloader: /mnt/vendor/autoload.php
/mnt/web/modules/custom/custom_stock/custom_stock.module

PHP Fatal error:  Uncaught Error: Call to a member function isSpecialClassName() on string in phar:///usr/local/bin/drupal-check/vendor/nikic/php-parser/lib/PhpParser/ParserAbstract.php:1004
Stack trace:
#0 phar:///usr/local/bin/drupal-check/vendor/nikic/php-parser/lib/PhpParser/Parser/Php7.php(1230): PhpParser\ParserAbstract->checkUseUse(Object(PhpParser\Node\Stmt\UseUse), 3)
#1 phar:///usr/local/bin/drupal-check/vendor/nikic/php-parser/lib/PhpParser/ParserAbstract.php(284): PhpParser\Parser\Php7->PhpParser\Parser\{closure}(3)
#2 phar:///usr/local/bin/drupal-check/vendor/nikic/php-parser/lib/PhpParser/ParserAbstract.php(158): PhpParser\ParserAbstract->doParse()
#3 phar:///usr/local/bin/drupal-check/vendor/phpstan/phpstan/src/Parser/DirectParser.php(43): PhpParser\ParserAbstract->parse('<?php\n\n/**\n * @...', Object(PhpParser\ErrorHandler\Collecting))
#4 phar:///usr/local/bin/drupal-check/vendor/phpstan/phpstan/src/Parser/DirectParser.php(33): PHPStan\Parser\DirectParser->parseString('<?php\n\n/**\n * @...')
#5 phar:///usr/lo in phar:///usr/local/bin/drupal-check/vendor/nikic/php-parser/lib/PhpParser/ParserAbstract.php on line 1004

Fatal error: Uncaught Error: Call to a member function isSpecialClassName() on string in phar:///usr/local/bin/drupal-check/vendor/nikic/php-parser/lib/PhpParser/ParserAbstract.php:1004
Stack trace:
#0 phar:///usr/local/bin/drupal-check/vendor/nikic/php-parser/lib/PhpParser/Parser/Php7.php(1230): PhpParser\ParserAbstract->checkUseUse(Object(PhpParser\Node\Stmt\UseUse), 3)
#1 phar:///usr/local/bin/drupal-check/vendor/nikic/php-parser/lib/PhpParser/ParserAbstract.php(284): PhpParser\Parser\Php7->PhpParser\Parser\{closure}(3)
#2 phar:///usr/local/bin/drupal-check/vendor/nikic/php-parser/lib/PhpParser/ParserAbstract.php(158): PhpParser\ParserAbstract->doParse()
#3 phar:///usr/local/bin/drupal-check/vendor/phpstan/phpstan/src/Parser/DirectParser.php(43): PhpParser\ParserAbstract->parse('<?php\n\n/**\n * @...', Object(PhpParser\ErrorHandler\Collecting))
#4 phar:///usr/local/bin/drupal-check/vendor/phpstan/phpstan/src/Parser/DirectParser.php(33): PHPStan\Parser\DirectParser->parseString('<?php\n\n/**\n * @...')
#5 phar:///usr/lo in phar:///usr/local/bin/drupal-check/vendor/nikic/php-parser/lib/PhpParser/ParserAbstract.php on line 1004

Allow configuration of installed modules for inspection

Currently, this extension loads all available modules. In reality, we should be allowed to limit the scope of this.

This would require moving the bootstrap process into the container somehow, so the list of modules can be provided as a parameter. If its empty we can assume "all of the things."

Add profile namespaces.

Right now if you have classes/tests in custom profile \PHPStan\Drupal\Bootstrap::register() doesn't add them to autoloader.

Provide some way to disable rules provided

Currently, to use this project and only do deprecation testing one would need to add the following to their phpstan.neon:

	# Ignore phpstan-drupal extension's rules.
	ignoreErrors:
		- '#\Drupal calls should be avoided in classes, use dependency injection instead#'
		- '#Plugin definitions cannot be altered.#'
		- '#Missing cache backend declaration for performance.#'
		- '#Plugin manager has cache backend specified but does not declare cache tags.#'

It would be nice if there was an easier way to kill this as the rules grow.

Library doesn't work with Nette/di v3.0.0-RC2

Since yesterday evening I got the following error on https://travis-ci.org/BurdaMagazinOrg/thunder-distribution/jobs/511585322:

PHP Fatal error:  Uncaught Nette\MemberAccessException: Call to undefined method Nette\DI\Definitions\ImportedDefinition::getFactory(). in /home/travis/build/BurdaMagazinOrg/test-dir/vendor/nette/utils/src/Utils/ObjectHelpers.php:65
Stack trace:
#0 /home/travis/build/BurdaMagazinOrg/test-dir/vendor/nette/utils/src/Utils/SmartObject.php(42): Nette\Utils\ObjectHelpers::strictCall('Nette\\DI\\Defini...', 'getFactory')
#1 /home/travis/build/BurdaMagazinOrg/test-dir/vendor/mglaman/phpstan-drupal/src/DependencyInjection/DrupalExtension.php(71): Nette\DI\Definitions\Definition->__call('getFactory', Array)
#2 /home/travis/build/BurdaMagazinOrg/test-dir/vendor/nette/di/src/DI/Compiler.php(233): PHPStan\DependencyInjection\DrupalExtension->loadConfiguration()
#3 /home/travis/build/BurdaMagazinOrg/test-dir/vendor/nette/di/src/DI/Compiler.php(185): Nette\DI\Compiler->processExtensions()
#4 /home/travis/build/BurdaMagazinOrg/test-dir/vendor/nette/di/src/DI/ContainerLoader.php(119): Nette\DI\Compiler->compile()
#5 /home/travis/build/BurdaMa in /home/travis/build/BurdaMagazinOrg/test-dir/vendor/nette/utils/src/Utils/ObjectHelpers.php on line 65

Looks like they changed something and broke the API

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.