Resources

Here you can find a collection of links, documentation and other resources for developers.

Useful modules

drush/drush
A command line shell and scripting interface for Drupal

drupal/admin_toolbar
Improve the default Toolbar to transform it into a drop-down menu, providing a fast access to all administration pages.

drupal/coder
Coder is a library for automated Drupal code reviews and coding standard fixes. It defines rules for PHP_CodeSniffer.

drupal/webprofiler
Adds a toolbar at the bottom of every page and shows you all sorts of stats

drupal/config_inspector
Let you to inspect configuration values and the use of schemas on top of them.

drupal/devel
Contains helper functions and pages for Drupal developers and inquisitive admins

drupal/devel_kint_extras
Offers to display methods and statics available for an object when using Kint

edgedesign/phpqa
Analyze PHP code with one command.

enlightn/security-checker
A PHP dependency vulnerabilities scanner based on the Security Advisories Database.

php-parallel-lint/php-console-highlighter
Highlight PHP code in console in terminal

php-parallel-lint/php-parallel-lint
Checks the syntax of PHP files in parallel.

phpstan/phpstan PHP Static Analysis Tool

phpstan/phpstan-deprecation-rules
PHPStan rules for detecting usage of deprecated classes, methods, properties, constants and traits.

squizlabs/php_codesniffer
Tokenizes PHP files and detects violations of a defined set of coding standards.

Let’s start (with DDev)

mkdir my-drupal10-site
cd my-drupal10-site
ddev config --docroot=web --project-type=drupal10 --create-docroot
ddev composer create drupal/recommended-project
ddev composer require drush/drush drupal/admin_toolbar
ddev composer require --dev drupal/coder drupal/webprofiler drupal/config_inspector drupal/devel drupal/devel_kint_extras edgedesign
/phpqa enlightn/security-checker php-parallel-lint/php-console-highlighter php-parallel-lint/php-parallel-lint phpstan/phpstan phpstan/phpstan-deprecation-rule
s squizlabs/php_codesniffer

Customize DDev

You can create custom commands for DDev, create bash scripts in .ddev/command/web.

To have a command build to automate the site building process, create the file .ddev/commands/web/build with following content:

#!/bin/bash

## Description: Build the website.
## Usage: build

composer install --prefer-dist
drush si -y --account-pass=admin
drush en -y admin_toolbar config_inspector webprofiler

Instead to have a command qa to launch PHPQA, create the file .ddev/commands/web/qa with following content:

#!/bin/bash

## Description: Run static analysis on the codebase.
## Usage: qa

phpqa --config=phpqa $@

Build our project

Now to build our project launch: ddev build

Customize settings.local.php for development

Put following content in your settings.local.php

Click to expand file content
/**
* Prevent banning (IP or user) during development
 */
$config['user.flood']['ip_window'] = 60;
$config['user.flood']['ip_limit'] = 1000;
$config['user.flood']['user_window'] = 60;
$config['user.flood']['user_limit'] = 1000;

/**
 * Disable permissions hardening
 */
$settings['skip_permissions_hardening'] = TRUE;

/**
 * Set Kint max depth and restore class methos, statics and iterators tabs
 */
if (class_exists('Kint')) {
  \Kint::$depth_limit = 3;

  \Kint::$plugins = array_merge(\Kint::$plugins, [
  	'\\Kint\\Parser\\ClassMethodsPlugin',
  	'\\Kint\\Parser\\ClassStaticsPlugin',
  	'\\Kint\\Parser\\IteratorPlugin',
  ]);
}

/**
 * Enable local development services.
 */
$settings['container_yamls'][] = DRUPAL_ROOT . '/sites/development.services.yml';

/**
 * Disable CSS and JS aggregation.
 */
$config['system.performance']['css']['preprocess'] = FALSE;
$config['system.performance']['js']['preprocess'] = FALSE;

/**
 * Disable cache
 */
$settings['cache']['bins']['render'] = 'cache.backend.null';
$settings['cache']['bins']['dynamic_page_cache'] = 'cache.backend.null';
$settings['cache']['bins']['page'] = 'cache.backend.null';

Configure PHPQA

Create folders with mkdir -p phpqa/reports.
Create the file phpqa/.phpqa.yml with following content:

Click to expand file content
phpqa:

  # Directories to analyze.
  analyzedDirs:
    # Uncomment following line modules development
    #- web/modules/custom
    # Uncomment following line for themes development
    #- web/themes/custom
  # Where place the reports.
  buildDir: phpqa/reports
  # Ignore dirs and files.
  ignoredDirs:
    - vendor,contrib,sites,tests,node_modules
  ignoredFiles: ""
  # Tools.
  tools:
    - phploc
    - phpcs:0
    - pdepend
    - phpmd:0
    - phpmetrics
    # Require composer autoload. Active only if have installed libraries dependencies of project.
    - phpstan:0
    #- psalm:0
    - parallel-lint
    - security-checker
  # Extension.
  extensions:
    - php
    - inc
    - module
    - install
    - profile
    - theme
    - yml
  # Configurations.
  report: true
  verbose: true
  #execution: no-parallel

phpcs:
  # alternatively you can use an array to define multiple standards (https://github.com/squizlabs/PHP_CodeSniffer/wiki/Usage#specifying-a-coding-standard)
  standard:
    - vendor/drupal/coder/coder_sniffer/DrupalPractice
    - vendor/drupal/coder/coder_sniffer/Drupal
  # number of allowed errors is compared with warnings+errors, or just errors from checkstyle.xml
  ignoreWarnings: false
  # https://github.com/squizlabs/PHP_CodeSniffer/wiki/Reporting
  reports:
    cli:
      - full
    file:
      checkstyle: checkstyle.xml

phpmd:
  # alternatively you can use an array to define multiple rule sets (https://phpmd.org/documentation/index.html#using-multiple-rule-sets)
  standard: phpmd.xml

pdepend:
# coverageReport: build/coverage-clover.xml

phpcpd:
  minLines: 5
  minTokens: 70

phpmetrics:
  # v1
  config: null
  # v2
  git: false
  # junit: build/log-junit.xml
  # composer: composer.json

phpstan:
  level: 3
  # https://github.com/phpstan/phpstan#configuration
  standard: phpstan.neon

psalm:
  config: .psalm.xml
  deadCode: false
  threads: 1
  showInfo: true
  allowMissingFiles: true

Create the file phpqa/phpmd.xml with following content:

Click to expand file content
<?xml version="1.0"?>
<ruleset xmlns="http://pmd.sourceforge.net/ruleset/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         name="PMD Ruleset for Drupal"
         xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
  <description>
    A PMD Ruleset for Drupal coding standards.
  </description>

  <!--
    Include each rule explicitly so we know what we have.
    @see https://github.com/phpmd/phpmd/blob/master/src/main/resources/rulesets/
  -->

  <!-- Clean Code -->
  <!--
  These don't align with Drupal standards, so they are excluded.
  @todo Static calls are hard to test and extend, is there a way to whitelist the ones that are OK?
  <rule ref="rulesets/cleancode.xml/BooleanArgumentFlag"/>
  <rule ref="rulesets/cleancode.xml/ElseExpression"/>
  <rule ref="rulesets/cleancode.xml/StaticAccess"/>
  -->

  <!-- Code Size -->
  <rule ref="rulesets/codesize.xml/CyclomaticComplexity"/>
  <rule ref="rulesets/codesize.xml/NPathComplexity"/>
  <rule ref="rulesets/codesize.xml/ExcessiveMethodLength"/>
  <rule ref="rulesets/codesize.xml/ExcessiveClassLength"/>
  <rule ref="rulesets/codesize.xml/ExcessiveParameterList"/>
  <rule ref="rulesets/codesize.xml/ExcessivePublicCount"/>
  <rule ref="rulesets/codesize.xml/TooManyFields"/>

  <!-- Controversial -->
  <rule ref="rulesets/controversial.xml/Superglobals"/>
  <!--
  These checks do not need to be included since PHPCS will check for style.
  <rule ref="rulesets/controversial.xml/CamelCaseClassName"/>
  <rule ref="rulesets/controversial.xml/CamelCasePropertyName"/>
  <rule ref="rulesets/controversial.xml/CamelCaseMethodName"/>
  <rule ref="rulesets/controversial.xml/CamelCaseParameterName"/>
  <rule ref="rulesets/controversial.xml/CamelCaseVariableName"/>
  -->

  <!-- Design -->
  <rule ref="rulesets/design.xml/ExitExpression"/>
  <rule ref="rulesets/design.xml/EvalExpression"/>
  <rule ref="rulesets/design.xml/GotoStatement"/>
  <rule ref="rulesets/design.xml/NumberOfChildren"/>
  <rule ref="rulesets/design.xml/DepthOfInheritance"/>
  <rule ref="rulesets/design.xml/CouplingBetweenObjects"/>
  <rule ref="rulesets/design.xml/DevelopmentCodeFragment"/>

  <!-- Naming -->
  <rule ref="rulesets/naming.xml/ShortVariable">
    <properties>
      <!-- Allow id,op,iv,af as a variable names. -->
      <property name="exceptions" description="Comma-separated list of exceptions" value="id,op,iv,af,IT,EN"/>
    </properties>
  </rule>
  <rule ref="rulesets/naming.xml/LongVariable">
    <properties>
      <!-- Bump variable length to a more reasonable number. -->
      <property name="maximum" description="The variable length reporting threshold" value="35"/>
    </properties>
  </rule>
  <rule ref="rulesets/naming.xml/ShortMethodName">
    <properties>
      <!-- Allow $id as a method name. -->
      <property name="exceptions" description="Comma-separated list of exceptions" value="id"/>
    </properties>
  </rule>
  <rule ref="rulesets/naming.xml/ConstructorWithNameAsEnclosingClass"/>
  <rule ref="rulesets/naming.xml/ConstantNamingConventions"/>
  <rule ref="rulesets/naming.xml/BooleanGetMethodName"/>

  <!-- Unused Code -->
  <rule ref="rulesets/unusedcode.xml/UnusedPrivateField"/>
  <!-- <rule ref="rulesets/unusedcode.xml/UnusedLocalVariable"/> -->
  <rule ref="rulesets/unusedcode.xml/UnusedPrivateMethod"/>
  <!--
  Hooks often have unused parameters, so ignore this warning.
  @todo is there a way to allow unused parameters in hooks but not elsewhere?
  <rule ref="rulesets/unusedcode.xml/UnusedFormalParameter"/>
  -->

</ruleset>

Feel free to correct me, add or expand contents, or interact as you prefer :-)