Linter rules¶
Every linter rule of the extension, grouped by what it checks. Each group has a page, and each rule has an entry there. An entry starts with the rule's level and what its fix does. Then it names the section of Drupal's coding standards that the rule checks, or, for a check that the standards don't cover, where the check comes from. Last come the checks ported by the rule, from Coder, core's own phpcs or PHPStan config, or phpstan-drupal. What the rule reports follows, and, where it skips cases, what it leaves alone.
Coder 9 is the parity target. Where the written standards ask for less than Coder, the rules follow Coder. Where they ask for more, some rules follow the standards, and their entries say so. The collapsed "Compared with Coder" note under an entry lists where the rule and Coder differ.
Every code starts with drupal/. The codes are stable, since projects write them into baselines
and @mago-expect comments. See Development.
Bugs and security¶
Rules for code that runs input it shouldn't trust, or reads the wrong value.
| Rule | Level | What it reports |
|---|---|---|
drupal/insecure-unserialize |
error | Reports an unserialize() call that doesn't limit the allowed classes. |
drupal/preg-security |
error | Reports a preg pattern with the e modifier, which evaluates the replacement as PHP. |
drupal/remote-address |
error | Reports a read of $_SERVER['REMOTE_ADDR'], which ignores Drupal's reverse-proxy settings. |
drupal/weak-hash |
warning | Reports an md5(), sha1() or crc32() call, and a hash() call that uses one of those algorithms. |
Using the right API¶
Rules for calls that a Drupal API replaces, and for strings that Drupal's tools read from the source.
| Rule | Level | What it reports |
|---|---|---|
drupal/deprecation-message |
warning | Reports an E_USER_DEPRECATED message that breaks the documented deprecation grammar. |
drupal/global-function |
warning | Reports a procedural Drupal function called from inside a class. |
drupal/translatable-literal |
warning | Reports a translatable string that isn't a literal, a first-class callable such as t(...), and a string joined after the call. |
drupal/translatable-string |
warning | Reports a translatable string built with ".", an empty or padded one, a call with no string, and an escaped quote. |
drupal/translated-exception |
warning | Reports an exception message passed through t(). |
drupal/unsilenced-deprecation |
error | Reports a trigger_error() deprecation notice without an "@" right before it. |
Procedural files¶
Rules for the procedural files of a module. They take the module name from the file name, the part
before the first dot. All of them report only in .module and .install files, except
drupal/global-variable, which checks every file.
| Rule | Level | What it reports |
|---|---|---|
drupal/const-prefix |
warning | Reports a const constant that doesn't start with the module name. |
drupal/constant-prefix |
warning | Reports a define() constant that doesn't start with the module name. |
drupal/empty-install-hook |
error | Reports a hook_install() or hook_uninstall() implementation with an empty body. |
drupal/function-prefix |
error | Reports a function in a .module file whose name doesn't start with the module name. |
drupal/global-variable |
error | Reports a global variable that doesn't start with an underscore. |
drupal/install-hook-location |
error | Reports an install-time hook declared in a .module file instead of a .install file. |
drupal/t-in-hook-schema |
error | Reports a t() call inside hook_schema(), whose strings Drupal never shows to users. |
Files and PHP tags¶
Rules for the bytes of a file and for its open and close tags.
| Rule | Level | What it reports |
|---|---|---|
drupal/byte-order-mark |
error | Reports a UTF-8 or UTF-16 byte order mark at the start of a file. |
drupal/closing-tag-statement |
error | Reports a closing tag at the end of a file that ends a statement with no semicolon. |
drupal/empty-php-tags |
warning | Reports an open tag that a close tag follows with only whitespace between. |
drupal/file-encoding |
warning | Reports a file whose bytes aren't valid UTF-8. |
drupal/file-start-whitespace |
error | Reports a file with whitespace before its first PHP open tag. |
drupal/short-echo-tag |
error | Reports a <?= echo tag, where Drupal writes <?php echo. |
drupal/tab-character |
error | Reports a tab in a comment or in the HTML outside the PHP tags. |
Info and routing files¶
Rules for the .info.yml file of a module, theme or profile and for .routing.yml files. They need
yml in Mago's extensions, as Install shows. Mago reads a YAML file as text
outside PHP tags, and these rules read the YAML in it.
| Rule | Level | What it reports |
|---|---|---|
drupal/info-auto-added-keys |
warning | Reports a key of an .info.yml file that drupal.org packaging adds. |
drupal/info-core-version-requirement |
warning | Reports an .info.yml file without a core_version_requirement key. |
drupal/info-dependencies-array |
error | Reports a dependencies key of an .info.yml file that isn't a list. |
drupal/info-description |
warning | Reports an .info.yml file with no description or an empty one. |
drupal/info-namespaced-dependency |
warning | Reports a dependency in an .info.yml file without its project name. |
drupal/routing-access |
warning | Reports an open route without a comment, and a route that asks for the "access administration pages" permission. |
Naming and imports¶
Rules for the names of classes, constants, functions, methods, properties and variables, and for
use statements. Mago's own naming rules cover the rest, see
Configuration.
| Rule | Level | What it reports |
|---|---|---|
drupal/class-name-acronym |
error | Reports a class-like name that starts with three capitals and doesn't have a lower-case letter, such as HTTP. |
drupal/define-name |
error | Reports a define() constant whose name isn't upper case. |
drupal/enum-case-name |
error | Reports an enum case that doesn't use UpperCamelCase. |
drupal/exception-suffix |
error | Reports an exception class whose name doesn't end in Exception. |
drupal/fully-qualified-name |
error | Reports a namespaced class referenced in full instead of through a use statement. |
drupal/function-name |
error | Reports a function whose name isn't lower case. |
drupal/global-class-backslash |
error | Reports a global class written without a leading backslash in a file with no namespace. |
drupal/hook-attribute-name |
warning | Reports a Hook attribute whose name starts with hook_. |
drupal/literal-constant-case |
error | Reports a fully qualified \true, \false or \null that is not written in upper case. |
drupal/method-name |
error | Reports a method name that doesn't use lowerCamelCase. |
drupal/method-name-underscore |
warning | Reports a method name that starts with an underscore, other than a PHP magic method. |
drupal/old-style-constructor |
error | Reports a method named after its class in a class without __construct(). |
drupal/property-name |
error | Reports a class property that doesn't use lowerCamelCase. |
drupal/psr4-namespace |
error | Reports a namespace that doesn't match the path of its file under src/ or tests/src/. |
drupal/redundant-use |
error | Reports a use statement that imports a class from the global namespace. |
drupal/test-class-suffix |
error | Reports a test class whose name doesn't end in Test, which PHPUnit never runs. |
drupal/use-leading-backslash |
error | Reports a use statement whose first name starts with a backslash. |
drupal/variable-name |
error | Reports a variable whose name starts with a capital letter. |
Statements and declarations¶
Rules for switch statements, ternaries and returns, for variables that are written and never read, and for how methods, properties and parameters are declared.
| Rule | Level | What it reports |
|---|---|---|
drupal/case-break-blank-line |
error | Reports a statement that ends a switch case and isn't followed by exactly one blank line. |
drupal/case-fall-through |
error | Reports a non-empty switch case that falls through to the next case with no comment. |
drupal/case-label-line |
error | Reports a comment before a case or default label on the label's line. |
drupal/case-semicolon |
error | Reports a case or default label that ends with a semicolon instead of a colon. |
drupal/comment-in-expression |
error | Reports a comment right after a cast, or between yield and from. |
drupal/else-if |
error | Reports an "else if" where Drupal writes "elseif". |
drupal/empty-switch |
error | Reports a switch statement that doesn't have a case label. |
drupal/explicit-nullable-param |
error | Reports a typed parameter with a null default whose type doesn't allow null. |
drupal/function-blank-line |
error | Reports a function declaration with no blank line between it and the code or comment before it. |
drupal/inequality-operator |
error | Reports the <> operator, which is written != in Drupal. |
drupal/method-visibility |
error | Reports a method declared without an explicit visibility keyword. |
drupal/non-capturing-catch |
error | Reports a catch variable that's never read, which the clause can leave out from PHP 8.0. |
drupal/null-coalesce |
error | Reports an isset() or strict null check in a ternary that "??" replaces. |
drupal/parameter-blank-line |
error | Reports a blank line in a multi-line function declaration. |
drupal/property-per-statement |
error | Reports a statement that declares more than one property. |
drupal/property-visibility |
error | Reports a property declared with var or without an explicit visibility keyword. |
drupal/redundant-return |
warning | Reports a bare return; that is the last statement of a function body. |
drupal/short-ternary |
error | Reports a ternary that repeats its condition, which "?:" replaces. |
drupal/short-list |
error | Reports a list(...) destructuring that can be written as [...]. |
drupal/unused-variable |
warning | Reports a variable that is written and never read in its function, closure or file. |
drupal/variable-redeclaration |
warning | Reports a variable that its function declares again, such as a parameter redeclared with static. |
Comment text¶
These rules check comments without comparing them against the declaration that they document. They
cover the part of Drupal.Commenting.* that works that way, the DrupalPractice comment checks, the
@author ban, the line-length check for comments and the docblock side of unused imports. For the
comment whitespace set by mago format, see
Comment whitespace and the formatter.
| Rule | Level | What it reports |
|---|---|---|
drupal/author-tag |
warning | Reports an @author tag in a docblock. |
drupal/comment-line-length |
warning | Reports a comment line longer than 80 characters. |
drupal/doc-comment-array-syntax |
warning | Reports an array() literal inside a docblock @code example. |
drupal/doc-type-namespace |
warning | Reports a docblock tag, such as @param or @see, that names a class imported only for docblocks by its short name. |
drupal/expected-exception-tag |
warning | Reports a legacy PHPUnit @expectedException* docblock tag. |
drupal/gender-neutral-comment |
warning | Reports a gendered pronoun in a comment. |
drupal/inline-comment |
warning | Reports a // comment without one space after // or without a capital letter, a # comment, and a docblock inside code. |
drupal/inline-comment-blank-line |
warning | Reports a // comment on its own line that a blank line follows. |
drupal/inline-comment-punctuation |
warning | Reports a // comment that doesn't end with terminal punctuation. |
drupal/long-description-punctuation |
warning | Reports a docblock long description that ends with a letter. |
drupal/post-statement-comment |
warning | Reports a // comment on the same line as the statement before it, and a comment after the opening or closing brace of a class. |
drupal/todo-comment |
warning | Reports a to-do comment that doesn't follow the "@todo Fix problem X here." format. |
Docblock structure¶
These rules check the docblocks asked for in Drupal's
API documentation and comment standards:
a docblock on every file, class, function and property, its summary and description, and its tags.
They don't check the types in a docblock against the real signature, which is done by
mago analyze, see
Docblock types and the analyzer.
| Rule | Level | What it reports |
|---|---|---|
drupal/class-comment |
error | Reports a comment of the wrong style above a class, interface, trait or enum, a blank line below its docblock, and a summary that repeats the name. |
drupal/constant-comment |
error | Reports a blank line between a docblock and the constant or enum case below it. |
drupal/deprecated-tag |
warning | Reports a @deprecated docblock tag whose wording breaks the documented grammar, and a missing or malformed @see tag after it. |
drupal/doc-comment |
error | Reports a docblock with a wrong opener, closer, blank lines or spaces, or with @inheritdoc without braces. |
drupal/doc-see-tag |
error | Reports a @see tag with no reference, or with text or punctuation after the reference. |
drupal/doc-sentence |
error | Reports a docblock summary, @param or @throws description with a wrong first letter or ending, a long description that starts with a lower-case letter, and a summary on more than one line. |
drupal/doc-tag-descriptions |
error | Reports a @param or @return with no description, a @param that repeats one or is out of order, and a method parameter with no @param when others have one. |
drupal/doc-tag-groups |
error | Reports a docblock whose tags of one kind aren't in one group with @param first, or whose tag groups don't have the right blank lines around them. |
drupal/doc-tag-layout |
error | Reports a @param, @return or @throws tag whose description is on the wrong line or has the wrong indent, or whose spacing is wrong. |
drupal/doc-tag-types |
error | Reports a @param with no type or variable name, a @return or @throws with no type, and a second @return. |
drupal/doc-type-name |
error | Reports a @param, @return or @var type spelled another way than the standard asks, such as integer for int. |
drupal/file-comment |
error | Reports a comment that starts a PHP file and has the wrong style, no @file tag or no blank line below it, and a comment at the start of a namespaced class file. |
drupal/function-comment |
error | Reports a comment of the wrong style above a function or method, and a blank line below its docblock. |
drupal/hook-comment |
warning | Reports a hook implementation whose docblock doesn't follow the "Implements hook_x()." convention. |
drupal/inline-variable-comment |
warning | Reports an inline @var type declaration in a // comment, or with the variable name before the type. |
drupal/missing-class-comment |
error | Reports a class, interface, trait or enum with no docblock. |
drupal/missing-file-comment |
error | Reports a PHP file that isn't a class file and doesn't have a comment at its start. |
drupal/missing-function-comment |
error | Reports a function or method with no docblock, a constructor excepted. |
drupal/missing-property-comment |
error | Reports a class property with no docblock. |
drupal/missing-summary |
error | Reports a docblock with tags and no short description. |
drupal/variable-comment |
error | Reports a comment of the wrong style above a class property, and a missing or malformed @var tag in its docblock. |
DrupalPractice checks¶
These rules port sniffs of Coder's DrupalPractice standard not run by core's phpcs.xml.dist, so
they're off in Drupal core.
| Rule | Level | What it reports |
|---|---|---|
drupal/class-prefix |
warning | Reports a class or interface in the global namespace that doesn't start with the module name. |
drupal/curl-ssl-verify |
warning | Reports a curl_setopt() call that turns off CURLOPT_SSL_VERIFYPEER. |
drupal/escaped-placeholder |
warning | Reports a check_plain() or Html::escape() call as the value of an @, % or : placeholder, which escapes the value already. |
drupal/form-alter-comment |
warning | Reports a function documented as hook_form_alter() that isn't named after the module. |
drupal/global-constant |
warning | Reports a top-level const statement or define() call, as DrupalPractice does. |
drupal/request-superglobal |
error | Reports a use of $_GET, $_POST, $_COOKIE, $_FILES or $_REQUEST, where the request stack gives the same data. |
drupal/strict-config-schema |
error | Reports a test class that turns off strict config schema checking. |
drupal/untranslated-description |
warning | Reports a plain string as the #description of a form element or render array. |
drupal/untranslated-options |
warning | Reports a plain string in the #options of a checkboxes, radios, select or tableselect element. |
Drupal 7 era¶
These rules check APIs removed in Drupal 8, so they don't find anything in a modern codebase. Core's
phpcs.xml.dist enables the matching sniffs and Coder 9 ships them, so without these rules a part
of the standard would go unchecked.
| Rule | Level | What it reports |
|---|---|---|
drupal/link-text-translatable |
error | Reports an l() call whose link text is a literal without a t() wrapper. |
drupal/t-in-hook-menu |
error | Reports a t() call inside hook_menu(), whose strings Drupal translates when it renders them. |
drupal/watchdog-message |
error | Reports a watchdog() message wrapped in t() or built by concatenation. |
Ported from phpstan-drupal¶
These rules port checks of phpstan-drupal that need only the syntax.
| Rule | Level | What it reports |
|---|---|---|
drupal/discouraged-function |
error | Reports a call to a devel dump helper or to fnmatch(), which some PHP builds don't have. |
drupal/render-callback |
error | Reports a render array callback that isn't a closure, a service:method string or a class method. |
drupal/symfony-yaml-parse |
warning | Reports a Symfony\Component\Yaml\Yaml::parse() call, which bypasses Drupal\Component\Serialization\Yaml::decode(). |
drupal/todo-current-issue |
error | Reports a @todo comment that links the issue of the current GitLab merge request. |