Skip to content

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.