Files
XC_VM/build/phpcs.xml.dist
T
Divarion_D ef88d7e325 style(phpcs): convert muted rules to comment/exclude toggles
Replace the `<severity>0</severity>` mute block with single-line toggles so
disabled sniffs can be re-enabled one at a time, per the technical-debt
ratchet. Two mechanisms, because phpcs `<exclude>` cannot be overridden by a
later ref:
  - sniffs with their own `<rule ref>` are commented out in place (uncomment
    to enable): CamelCapsFunctionName, MultiLineAssignment,
    UnnecessaryStringConcat, SAPIUsage, AbstractClassNamePrefix,
    InterfaceNameSuffix, TraitNameSuffix, DeprecatedFunctions, ClassFileName,
    GlobalKeyword;
  - sniffs pulled in by the PSR12 parent are `<exclude>`d inside it (delete the
    exclude to enable): CamelCapsMethodName, FileHeader.IncorrectOrder,
    MethodDeclaration.Underscore, SwitchDeclaration.TerminatingComment,
    PSR1.Classes.ClassDeclaration, PropertyDeclaration.Underscore,
    ValidClassName;
  - CyclomaticComplexity/NestingLevel MaxExceeded are message-level excludes on
    their own refs (TooHigh warning still reports).

ControlStructureSpacing and PEAR FunctionCallSignature (tab-incompatible) and
ParameterTypeHint (null-crash fixer footgun) are marked DO NOT ENABLE. Added a
ratchet legend documenting every toggle, its violation count, and a suggested
enable order. `make cs` stays green (0 errors) and `make cs-fix` converges;
both toggle directions verified.
2026-09-18 13:44:50 +03:00

353 lines
18 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<ruleset name="XC_VM PSR-12"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../vendor/squizlabs/php_codesniffer/phpcs.xsd">
<description>
PSR-12 strict coding standard
Run via `make cs` (report) / `make cs-fix` (auto-fix, = phpcbf).
</description>
<!-- Analyzed set mirrors the old cs-fixer Finder (paths passed on the CLI by
the Makefile; these are the exclusions). -->
<exclude-pattern>*/vendor/*</exclude-pattern>
<exclude-pattern>*/Infrastructure/Tmdb/lib/*</exclude-pattern>
<exclude-pattern>*/tmp/*</exclude-pattern>
<exclude-pattern>*/backups/*</exclude-pattern>
<exclude-pattern>*/Public/Views/*</exclude-pattern>
<exclude-pattern>*/Modules/*/views/*</exclude-pattern>
<!-- Analyse PHP only. phpcbf's default extension list also covers js/css
(legacy tokenizers), which would otherwise reformat those files. -->
<arg name="extensions" value="php"/>
<!-- Indentation is a real tab (rendered 4 wide), not PSR-12's 4 spaces. -->
<arg name="tab-width" value="4"/>
<!-- Code MUST follow PSR-12, EXCEPT brace placement: this project uses
K&R / one-true-brace (opening brace on the SAME line), not PSR-12's
Allman placement. The Allman-enforcing sniffs are excluded here and the
K&R sniffs are added at the end of this ruleset. -->
<rule ref="PSR12">
<exclude name="Generic.Functions.OpeningFunctionBraceBsdAllman"/>
<exclude name="PSR2.Classes.ClassDeclaration.OpenBraceNewLine"/>
<exclude name="Generic.WhiteSpace.DisallowTabIndent"/>
<!-- Multi-line function declarations also keep the brace on the same
line (K&R), so drop PSR-12's "brace on new line" for them. -->
<exclude name="Squiz.Functions.MultiLineFunctionDeclaration.BraceOnSameLine"/>
<!-- ── Temporarily disabled PSR-family sniffs (technical-debt ratchet) ──
These come from the PSR12 parent, so they can only be switched off
here with <exclude>. To ENABLE one: DELETE its exclude line, run
`make cs`, fix the fallout, commit. (…N) = current violation count. -->
<exclude name="PSR1.Methods.CamelCapsMethodName"/> <!-- 40: legacy snake_case methods -->
<exclude name="PSR1.Classes.ClassDeclaration"/> <!-- 2: legacy non-namespaced (XC_Bootstrap) -->
<exclude name="PSR2.Classes.PropertyDeclaration.Underscore"/> <!-- 2: legacy _property names -->
<exclude name="PSR2.Methods.MethodDeclaration.Underscore"/> <!-- 12: legacy _method names -->
<exclude name="PSR2.ControlStructures.SwitchDeclaration.TerminatingComment"/> <!-- 6: add `// no break` -->
<exclude name="PSR12.Files.FileHeader.IncorrectOrder"/> <!-- 29: header declare/namespace/use order -->
<exclude name="Squiz.Classes.ValidClassName"/> <!-- 1: legacy class name -->
<!-- ── PERMANENTLY disabled — DO NOT ENABLE ──
Space-alignment sniff that cannot converge under tab indentation:
LineIndent counts SPACES ("expected 12, found 8" on 3 tabs) and
FirstExpressionLine/CloseParenthesisLine force the expanded PSR-12
layout, so phpcbf oscillates → FAILED TO FIX. The tab-safe
equivalent PEAR.ControlStructures.MultiLineCondition is enabled
below and enforces the same multi-line `if` layout. See 689663d4. -->
<exclude name="PSR12.ControlStructures.ControlStructureSpacing"/>
</rule>
<!-- Indentation MUST use tabs (one tab per level), not PSR-12's 4 spaces. -->
<rule ref="Generic.WhiteSpace.DisallowSpaceIndent"/>
<rule ref="Generic.WhiteSpace.ScopeIndent">
<properties>
<property name="indent" value="4"/>
<property name="tabIndent" value="true"/>
</properties>
</rule>
<!-- Generic rules -->
<!-- All values in multiline arrays must be indented with 4 spaces. -->
<rule ref="Generic.Arrays.ArrayIndent"/>
<!-- The short array syntax MUST be used to define arrays. -->
<rule ref="Generic.Arrays.DisallowLongArraySyntax"/>
<!-- There MUST NOT be duplicate class names. -->
<rule ref="Generic.Classes.DuplicateClassName"/>
<!-- The final keyword on methods MUST be omitted in final classes. -->
<rule ref="Generic.CodeAnalysis.UnnecessaryFinalModifier"/>
<!-- Detects unnecessary overridden methods that simply call their parent. -->
<rule ref="Generic.CodeAnalysis.UselessOverridingMethod"/>
<!-- There MUST be one whitespace after a type casting operator. -->
<rule ref="Generic.Formatting.SpaceAfterCast"/>
<!-- Checks the cyclomatic complexity (McCabe) for functions. The hard
MaxExceeded ERROR is disabled (174 God-methods); the softer TooHigh
WARNING still reports. To enforce: delete the exclude, run `make cs`,
refactor the fallout. -->
<rule ref="Generic.Metrics.CyclomaticComplexity">
<exclude name="Generic.Metrics.CyclomaticComplexity.MaxExceeded"/>
</rule>
<!-- Checks the nesting level for methods. MaxExceeded ERROR disabled (2),
TooHigh WARNING still reports; delete the exclude to enforce. -->
<rule ref="Generic.Metrics.NestingLevel">
<exclude name="Generic.Metrics.NestingLevel.MaxExceeded"/>
</rule>
<!-- Checks that abstract classes are prefixed by Abstract.
DISABLED (2) — uncomment to enable. -->
<!-- <rule ref="Generic.NamingConventions.AbstractClassNamePrefix"/> -->
<!-- Ensures method and functions are named correctly.
DISABLED (187) — legacy snake_case function names; renames break
callers. Uncomment to enable. -->
<!-- <rule ref="Generic.NamingConventions.CamelCapsFunctionName"/> -->
<!-- Checks that interfaces are suffixed by Interface.
DISABLED (1) — uncomment to enable. -->
<!-- <rule ref="Generic.NamingConventions.InterfaceNameSuffix"/> -->
<!-- Checks that traits are suffixed by Trait.
DISABLED (1) — uncomment to enable. -->
<!-- <rule ref="Generic.NamingConventions.TraitNameSuffix"/> -->
<!-- The backtick operator MUST NOT be used. -->
<rule ref="Generic.PHP.BacktickOperator"/>
<!-- Deprecated PHP functions MUST be avoided.
DISABLED (1) — uncomment to enable. -->
<!-- <rule ref="Generic.PHP.DeprecatedFunctions"/> -->
<!-- The PHP `goto` language construct SHOULD NOT be used. -->
<rule ref="Generic.PHP.DiscourageGoto"/>
<!-- Alias functions SHOULD NOT be used. -->
<rule ref="Generic.PHP.ForbiddenFunctions">
<properties>
<property name="forbiddenFunctions" type="array">
<element key="chop" value="rtrim"/>
<element key="close" value="closedir"/>
<element key="compact" value="null"/>
<element key="delete" value="unset"/>
<element key="doubleval" value="floatval"/>
<element key="extract" value="null"/>
<element key="fputs" value="fwrite"/>
<element key="ini_alter" value="ini_set"/>
<element key="is_double" value="is_float"/>
<element key="is_integer" value="is_int"/>
<element key="is_long" value="is_int"/>
<element key="is_real" value="is_float"/>
<element key="join" value="implode"/>
<element key="key_exists" value="array_key_exists"/>
<element key="pos" value="current"/>
<element key="settype" value="null"/>
<element key="show_source" value="highlight_file"/>
<element key="sizeof" value="count"/>
<element key="strchr" value="strstr"/>
</property>
</properties>
</rule>
<!-- Throws an error or warning when any code prefixed with an asperand is encountered. -->
<rule ref="Generic.PHP.NoSilencedErrors"/>
<!-- Checks that the `strict_types` has been declared. -->
<!-- <rule ref="Generic.PHP.RequireStrictTypes"/> -->
<!-- The constant `PHP_SAPI` SHOULD be used instead of the `php_sapi_name()` function.
DISABLED (7) — uncomment to enable (mechanical: php_sapi_name() → PHP_SAPI). -->
<!-- <rule ref="Generic.PHP.SAPIUsage"/> -->
<!-- Checks that two strings are not concatenated together; suggests using one string instead.
DISABLED (41) — uncomment to enable. -->
<!-- <rule ref="Generic.Strings.UnnecessaryStringConcat"/> -->
<!-- Check & fix whitespace on the inside of arbitrary parentheses. -->
<rule ref="Generic.WhiteSpace.ArbitraryParenthesesSpacing"/>
<!-- Verifies spacing between the spread operator and the variable/function call it applies to. -->
<rule ref="Generic.WhiteSpace.SpreadOperatorSpacingAfter"/>
<!-- PEAR rules -->
<!-- Verifies that control statements conform to their coding standards. -->
<rule ref="PEAR.ControlStructures.ControlSignature"/>
<!-- Ensure multi-line `if` conditions are defined correctly. Tab-safe
replacement for the disabled PSR12 ControlStructureSpacing (see the
PSR12 exclude block above). -->
<rule ref="PEAR.ControlStructures.MultiLineCondition"/>
<!-- If an assignment goes over two lines, ensure the equal sign is indented.
DISABLED (49) — uncomment to enable. -->
<!-- <rule ref="PEAR.Formatting.MultiLineAssignment"/> -->
<!-- Ensure single and multi-line function declarations are defined correctly. -->
<rule ref="PEAR.Functions.FunctionDeclaration">
<!-- K&R: opening brace stays on the same line, incl. multi-line signatures. -->
<exclude name="PEAR.Functions.FunctionDeclaration.BraceOnSameLine"/>
</rule>
<!-- Checks that object operators are indented correctly. -->
<rule ref="PEAR.WhiteSpace.ObjectOperatorIndent"/>
<!-- Checks that the closing braces of scopes are aligned correctly. -->
<rule ref="PEAR.WhiteSpace.ScopeClosingBrace"/>
<!-- Squiz rules -->
<!-- Checks the declaration of the class and its inheritance is correct. -->
<rule ref="Squiz.Classes.ClassDeclaration">
<!-- K&R: class opening brace on the SAME line (see Generic.Classes.OpeningBraceSameLine). -->
<exclude name="Squiz.Classes.ClassDeclaration.OpenBraceNewLine"/>
</rule>
<!-- The file name MUST match the case of the terminating class name.
DISABLED (1) — uncomment to enable. -->
<!-- <rule ref="Squiz.Classes.ClassFileName"/> -->
<!-- For self-reference a class lower-case `self::` MUST be used
without spaces around the scope resolution operator. -->
<rule ref="Squiz.Classes.SelfMemberReference"/>
<!-- The `&&` and `||` operators SHOULD be used instead of `and` and `or`. -->
<rule ref="Squiz.Operators.ValidLogicalOperators"/>
<!-- The `global` keyword MUST NOT be used.
DISABLED (478) — architectural `global $db` → DatabaseAware migration;
not a quick style fix. Uncomment to enable. -->
<!-- <rule ref="Squiz.PHP.GlobalKeyword"/> -->
<!-- PHP function calls MUST be in lowercase. -->
<rule ref="Squiz.PHP.LowercasePHPFunctions"/>
<!-- Non executable code MUST be removed. -->
<rule ref="Squiz.PHP.NonExecutableCode"/>
<!-- The pseudo-variable `$this` MUST NOT be called inside a static method or function. -->
<rule ref="Squiz.Scope.StaticThisUsage"/>
<!-- Makes sure there are no spaces around the concatenation operator. -->
<rule ref="Squiz.Strings.ConcatenationSpacing">
<properties>
<property name="spacing" value="1" />
<!-- Don't collapse indentation into a single space on multi-line
concatenations (the `.` at the start of an indented continuation
line) — that fights the indent sniff and prevents phpcbf from
converging. -->
<property name="ignoreNewlines" value="true" />
</properties>
</rule>
<!-- Checks the separation between functions and methods. -->
<rule ref="Squiz.WhiteSpace.FunctionSpacing">
<properties>
<property name="spacing" value="1" />
<property name="spacingBeforeFirst" value="0" />
<property name="spacingAfterLast" value="0" />
</properties>
</rule>
<!-- There MUST NOT be any white space around the object operator UNLESS multilines are used. -->
<rule ref="Squiz.WhiteSpace.LogicalOperatorSpacing"/>
<!-- Verifies that class members are spaced correctly. -->
<rule ref="Squiz.WhiteSpace.MemberVarSpacing">
<properties>
<property name="spacing" value="1" />
<property name="spacingBeforeFirst" value="0" />
</properties>
</rule>
<!-- Ensure there is no whitespace before/after an object operator. -->
<rule ref="Squiz.WhiteSpace.ObjectOperatorSpacing">
<properties>
<property name="ignoreNewlines" value="true"/>
</properties>
</rule>
<!-- Verifies that operators have valid spacing surrounding them. -->
<rule ref="Squiz.WhiteSpace.OperatorSpacing">
<properties>
<property name="ignoreNewlines" value="true"/>
</properties>
</rule>
<!-- There MUST NOT be a space before a semicolon. Redundant semicolons SHOULD be avoided. -->
<rule ref="Squiz.WhiteSpace.SemicolonSpacing"/>
<!-- ══════════════════════════════════════════════════════════════════
PERMANENTLY disabled — DO NOT ENABLE (not part of the ratchet).
Space-alignment sniffs that align multi-line continuations with SPACES
relative to a tab-indented base. phpcbf inserts the spaces,
Generic.WhiteSpace.DisallowSpaceIndent strips them back, and the fixer
never converges → FAILED TO FIX. Multi-line call-argument alignment has
no tab-safe fixer, so this stays off (multi-line `if` layout IS enforced,
via PEAR.ControlStructures.MultiLineCondition above). -->
<!-- <rule ref="PEAR.Functions.FunctionCallSignature"/> -->
<!-- SlevomatCodingStandard.TypeHints.ParameterTypeHint — DO NOT ENABLE yet.
As a FIXER it auto-added native param types from @param docblocks that
crash on null at runtime (the "null given" footgun — see TYPE_AUDIT.md).
Keep off until that audit is worked through; then uncomment. -->
<!--
<rule ref="SlevomatCodingStandard.TypeHints.ParameterTypeHint">
<properties>
<property name="enableObjectTypeHint" value="true"/>
</properties>
</rule>
-->
<!-- ── K&R / one-true-brace style (overrides PSR-12 Allman) ──────────
Opening brace on the SAME line as the declaration, for classes and
for functions/methods/closures. Both sniffs are phpcbf-fixable. -->
<rule ref="Generic.Classes.OpeningBraceSameLine"/>
<rule ref="Generic.Functions.OpeningFunctionBraceKernighanRitchie">
<properties>
<property name="checkClosures" value="true"/>
</properties>
</rule>
<!-- ══════════════════════════════════════════════════════════════════
Technical-debt ratchet — how to gradually tighten this ruleset.
Sniffs that legacy code still violates are DISABLED so `make cs` stays
green and can act as a baseline. Enable ONE at a time: flip its toggle,
run `make cs`, fix the fallout, run `make cs-fix` (confirm it converges,
no FAILED TO FIX), commit. Do NOT add new violations under a disabled
rule. Each disabled rule is a single-line toggle:
• Own `<rule ref>` commented out above → UNCOMMENT the line:
CamelCapsFunctionName(187), MultiLineAssignment(49),
UnnecessaryStringConcat(41), SAPIUsage(7), AbstractClassNamePrefix(2),
InterfaceNameSuffix(1), TraitNameSuffix(1), DeprecatedFunctions(1),
Squiz.Classes.ClassFileName(1), Squiz.PHP.GlobalKeyword(478).
• <exclude> in the PSR12 block above → DELETE the exclude line:
CamelCapsMethodName(40), FileHeader.IncorrectOrder(29),
MethodDeclaration.Underscore(12), SwitchDeclaration.TerminatingComment(6),
PSR1.Classes.ClassDeclaration(2), PropertyDeclaration.Underscore(2),
Squiz.Classes.ValidClassName(1).
• <exclude> in the Metrics refs above → DELETE the exclude line:
CyclomaticComplexity.MaxExceeded(201), NestingLevel.MaxExceeded(2).
Suggested order (cheapest / lowest-risk first): SAPIUsage,
DeprecatedFunctions, SwitchDeclaration.TerminatingComment,
MultiLineAssignment, UnnecessaryStringConcat, FileHeader.IncorrectOrder,
the small naming/rename sniffs, then the underscore renames. Leave the
architectural ones (GlobalKeyword, Cyclomatic/Nesting, CamelCaps names)
for dedicated refactors. See the "PERMANENTLY disabled" blocks for the
two that must stay off.
Warnings (line length, cyclomatic "too high", silenced errors, …) are
reported but do NOT fail the run:
══════════════════════════════════════════════════════════════════════ -->
<config name="ignore_warnings_on_exit" value="1"/>
</ruleset>