Skip to content

Commit 4e94b9b

Browse files
committed
feat: move more rules from phpcs to php-cs-fixer
1 parent 4169952 commit 4e94b9b

3 files changed

Lines changed: 30 additions & 96 deletions

File tree

IxDFCodingStandard/PhpCsFixer/Rules.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public static function get(): array
3838
'class_attributes_separation' => ['elements' => ['method' => 'one']],
3939
'declare_strict_types' => true,
4040
'explicit_string_variable' => true,
41+
'final_class' => true,
4142
'final_public_method_for_abstract_class' => true,
4243
'general_phpdoc_annotation_remove' => [
4344
'annotations' => [
@@ -64,10 +65,14 @@ public static function get(): array
6465
'import_classes' => false,
6566
'import_constants' => false,
6667
],
68+
'heredoc_to_nowdoc' => true,
69+
'is_null' => true,
70+
'logical_operators' => true,
6771
'modernize_types_casting' => true,
6872
'mb_str_functions' => true,
6973
'multiline_whitespace_before_semicolons' => ['strategy' => 'no_multi_line'],
70-
'no_alias_functions' => true,
74+
'native_constant_invocation' => ['strict' => false], // non-strict: keep `\` on userland global constants (e.g. PHPCS token constants)
75+
'native_function_casing' => true,
7176
'no_binary_string' => true,
7277
'no_empty_comment' => true,
7378
'no_empty_phpdoc' => true,
@@ -79,11 +84,13 @@ public static function get(): array
7984
'no_short_bool_cast' => true,
8085
'no_singleline_whitespace_before_semicolons' => true,
8186
'no_spaces_around_offset' => true,
87+
'no_superfluous_phpdoc_tags' => true,
8288
'no_trailing_comma_in_singleline' => [
8389
'elements' => ['arguments', 'array', 'group_import'], // excludes 'array_destructuring' enabled by default
8490
],
8591
'no_unneeded_braces' => true,
8692
'no_unneeded_control_parentheses' => true,
93+
'no_unneeded_import_alias' => true,
8794
'no_unneeded_final_method' => true,
8895
'no_unreachable_default_argument_value' => true,
8996
'no_unused_imports' => true,
@@ -132,17 +139,23 @@ public static function get(): array
132139
'phpdoc_single_line_var_spacing' => true,
133140
'phpdoc_tag_casing' => true,
134141
'phpdoc_types' => true,
142+
'phpdoc_types_order' => ['null_adjustment' => 'always_last', 'sort_algorithm' => 'none'],
135143
'protected_to_private' => true,
136144
'psr_autoloading' => true,
137145
'self_accessor' => true,
138146
'self_static_accessor' => true,
139147
'single_line_comment_spacing' => true,
140148
'single_line_comment_style' => ['comment_types' => ['asterisk', 'hash']],
149+
'single_quote' => true,
141150
'space_after_semicolon' => true,
142151
'standardize_not_equals' => true,
152+
'static_lambda' => true,
143153
'strict_param' => true,
154+
'ternary_to_elvis_operator' => true,
144155
'ternary_to_null_coalescing' => true,
145156
'trim_array_spaces' => true,
157+
// Deliberately narrower than PER-CS 2.0+ (arrays only, not arguments/parameters/match):
158+
// PHPCS forbids trailing commas in calls and declarations via SlevomatCodingStandard.Functions.DisallowTrailingComma* sniffs.
146159
'trailing_comma_in_multiline' => true,
147160
'type_declaration_spaces' => true,
148161
'types_spaces' => ['space' => 'single'],

IxDFCodingStandard/ruleset.xml

Lines changed: 13 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@
2222
<exclude name="PSR1.Files.SideEffects.FoundWithSymbols"/>
2323
</rule>
2424
<rule ref="PSR1.Classes.ClassDeclaration"/>
25-
<rule ref="PSR1.Methods.CamelCapsMethodName"/>
25+
<rule ref="PSR1.Methods.CamelCapsMethodName">
26+
<!-- PHP-CS-Fixer's php_unit_method_casing renames test methods to snake_case -->
27+
<exclude-pattern>*/tests/*</exclude-pattern>
28+
</rule>
2629

2730
<!-- Generic ruleset: -->
2831
<!-- Forbid duplicate classes -->
@@ -32,8 +35,6 @@
3235
<!-- But allow empty catch -->
3336
<exclude name="Generic.CodeAnalysis.EmptyStatement.DetectedCatch"/>
3437
</rule>
35-
<!-- Warn about variable assignments inside conditions -->
36-
<rule ref="Generic.CodeAnalysis.AssignmentInCondition"/>
3738
<!-- Forbid useless empty method overrides -->
3839
<rule ref="Generic.CodeAnalysis.UselessOverridingMethod"/>
3940
<!-- Detects the usage of one and the same incrementer into an outer and an inner -->
@@ -48,11 +49,6 @@
4849
<property name="ignoreComments" value="true"/>
4950
</properties>
5051
</rule>
51-
<!-- Ensure there is a single class/interface/trait per file -->
52-
<rule ref="Generic.Files.OneObjectStructurePerFile"/>
53-
<!--
54-
<rule ref="Generic.Formatting.SpaceAfterNot"/>&lt;!&ndash; Force whitespace after `!` &ndash;&gt;
55-
-->
5652
<!-- Checks how many level deep that code is nested within a function. -->
5753
<rule ref="Generic.Metrics.NestingLevel">
5854
<properties>
@@ -69,56 +65,28 @@
6965
<rule ref="Generic.PHP.CharacterBeforePHPOpeningTag"/>
7066
<!-- Forbid deprecated functions -->
7167
<rule ref="Generic.PHP.DeprecatedFunctions"/>
72-
<!-- Array values are specified by using a string representation of the array. -->
68+
<!--
69+
Only functions PHP-CS-Fixer cannot handle are listed here.
70+
Aliases (join, sizeof, chop, …) are fixed by no_alias_functions,
71+
intval/boolval/… by modernize_types_casting, rand/mt_rand by random_api_migration,
72+
print by no_mixed_echo_print, is_null by the is_null fixer.
73+
-->
7374
<rule ref="Generic.PHP.ForbiddenFunctions">
7475
<properties>
7576
<property name="forbiddenFunctions" type="array">
7677
<element key="array_push" value="null"/>
77-
<element key="chop" value="rtrim"/>
78-
<element key="close" value="closedir"/>
79-
<element key="create_function" value="null"/>
8078
<!-- See https://youtu.be/8rdTSYljts4?t=2932 -->
8179
<element key="extract" value="null"/>
8280
<element key="compact" value="null"/>
83-
<element key="delete" value="unset"/>
84-
<element key="doubleval" value="floatval"/>
85-
<element key="fputs" value="fwrite"/>
86-
<element key="ini_alter" value="ini_alter"/>
87-
<element key="is_double" value="is_float"/>
88-
<element key="is_integer" value="is_int"/>
89-
<element key="is_long" value="is_int"/>
90-
<element key="is_null" value="null"/>
91-
<element key="is_real" value="is_float"/>
92-
<element key="is_writeable" value="is_writable"/>
93-
<element key="join" value="implode"/>
94-
<element key="key_exists" value="array_key_exists"/>
95-
<element key="pos" value="current"/>
96-
<element key="print" value="echo"/>
97-
<element key="show_source" value="highlight_file"/>
98-
<element key="sizeof" value="count"/>
99-
<element key="strchr" value="strstr"/>
10081
<element key="die" value="null"/>
10182
<element key="exit" value="null"/>
10283
<element key="env" value="config"/>
103-
<element key="intval" value="(int)"/>
104-
<element key="floatval" value="(float)"/>
105-
<element key="doubleval" value="(float)"/>
106-
<element key="boolval" value="(bool)"/>
107-
<element key="strval" value="(string)"/>
108-
<element key="mt_rand" value="random_int"/>
109-
<element key="rand" value="random_int"/>
11084
<element key="var_dump" value="null"/>
11185
</property>
11286
</properties>
11387
<!-- Added to ignore env() in config files, it's better to remove it and use env() in a separate rule. -->
11488
<exclude-pattern>.config/*</exclude-pattern>
11589
</rule>
116-
<rule ref="Generic.Strings.UnnecessaryStringConcat">
117-
<!-- But multiline is useful for readability -->
118-
<properties>
119-
<property name="allowMultiline" value="true"/>
120-
</properties>
121-
</rule>
12290
<!-- Detects merge conflict artifacts left in files -->
12391
<rule ref="Generic.VersionControl.GitMergeConflict"/>
12492
<!-- Generic ruleset end. -->
@@ -128,7 +96,6 @@
12896
<!-- Array must have keys specified for either all or none of the values. -->
12997
<rule ref="SlevomatCodingStandard.Arrays.DisallowPartiallyKeyed"/>
13098
<rule ref="SlevomatCodingStandard.Arrays.MultiLineArrayEndBracketPlacement"/>
131-
<rule ref="SlevomatCodingStandard.Arrays.SingleLineArrayWhitespace"/>
13299
<rule ref="SlevomatCodingStandard.Attributes.AttributeAndTargetSpacing">
133100
<!-- For code like private function processUser(Member $member, #[\SensitiveParameter] string $password): void -->
134101
<exclude name="SlevomatCodingStandard.Attributes.AttributeAndTargetSpacing.IncorrectLinesCountBetweenAttributeAndTarget"/>
@@ -137,7 +104,6 @@
137104
<rule ref="SlevomatCodingStandard.Attributes.DisallowMultipleAttributesPerLine"/>
138105
<rule ref="SlevomatCodingStandard.Attributes.RequireAttributeAfterDocComment"/>
139106
<rule ref="SlevomatCodingStandard.Classes.BackedEnumTypeSpacing"/>
140-
<rule ref="SlevomatCodingStandard.Classes.ClassConstantVisibility"/>
141107
<rule ref="SlevomatCodingStandard.Classes.ClassLength"/>
142108
<rule ref="SlevomatCodingStandard.Classes.ClassMemberSpacing"/>
143109
<rule ref="SlevomatCodingStandard.Classes.ConstantSpacing"/>
@@ -149,15 +115,12 @@
149115
<rule ref="SlevomatCodingStandard.Classes.ParentCallSpacing"/>
150116
<rule ref="SlevomatCodingStandard.Classes.PropertyDeclaration"/>
151117
<rule ref="SlevomatCodingStandard.Classes.PropertySpacing"/>
152-
<rule ref="SlevomatCodingStandard.Classes.RequireAbstractOrFinal"/>
153118
<rule ref="SlevomatCodingStandard.Classes.RequireMultiLineMethodSignature"/>
154-
<rule ref="SlevomatCodingStandard.Classes.RequireSelfReference"/>
155119
<rule ref="SlevomatCodingStandard.Classes.RequireSingleLineMethodSignature"/>
156120
<rule ref="SlevomatCodingStandard.Classes.SuperfluousErrorNaming"/>
157121
<rule ref="SlevomatCodingStandard.Classes.SuperfluousExceptionNaming"/>
158122
<rule ref="SlevomatCodingStandard.Classes.SuperfluousInterfaceNaming"/>
159123
<rule ref="SlevomatCodingStandard.Classes.SuperfluousTraitNaming"/>
160-
<rule ref="SlevomatCodingStandard.Classes.TraitUseDeclaration"/>
161124
<rule ref="SlevomatCodingStandard.Classes.TraitUseSpacing">
162125
<properties>
163126
<property name="linesCountBeforeFirstUse" value="0"/>
@@ -172,7 +135,6 @@
172135
<property name="linesCountBetweenAnnotationsGroups" value="0"/>
173136
</properties>
174137
</rule>
175-
<rule ref="SlevomatCodingStandard.Commenting.ForbiddenAnnotations"/>
176138
<rule ref="SlevomatCodingStandard.Commenting.ForbiddenComments">
177139
<properties>
178140
<property name="forbiddenCommentPatterns" type="array">
@@ -189,9 +151,11 @@
189151
<exclude name="SlevomatCodingStandard.Commenting.InlineDocCommentDeclaration.MissingVariable"/>
190152
<include-pattern>routes/</include-pattern>
191153
</rule>
154+
<!-- Allow cognitive complexity up to 10, report anything above -->
192155
<rule ref="SlevomatCodingStandard.Complexity.Cognitive">
193156
<properties>
194-
<property name="maxComplexity" value="10"/>
157+
<property name="warningThreshold" value="11"/>
158+
<property name="errorThreshold" value="11"/>
195159
</properties>
196160
</rule>
197161
<rule ref="SlevomatCodingStandard.ControlStructures.AssignmentInCondition"/>
@@ -200,15 +164,13 @@
200164
</rule>
201165
<rule ref="SlevomatCodingStandard.ControlStructures.DisallowContinueWithoutIntegerOperandInSwitch"/>
202166
<rule ref="SlevomatCodingStandard.ControlStructures.DisallowTrailingMultiLineTernaryOperator"/>
203-
<rule ref="SlevomatCodingStandard.ControlStructures.LanguageConstructWithParentheses"/>
204167
<rule ref="SlevomatCodingStandard.ControlStructures.RequireMultiLineCondition"/>
205168
<rule ref="SlevomatCodingStandard.ControlStructures.RequireMultiLineTernaryOperator">
206169
<properties>
207170
<property name="lineLengthLimit" value="120"/>
208171
</properties>
209172
</rule>
210173
<rule ref="SlevomatCodingStandard.ControlStructures.RequireNullSafeObjectOperator"/>
211-
<rule ref="SlevomatCodingStandard.ControlStructures.RequireShortTernaryOperator"/>
212174
<rule ref="SlevomatCodingStandard.ControlStructures.RequireSingleLineCondition"/>
213175
<rule ref="SlevomatCodingStandard.ControlStructures.RequireTernaryOperator"/>
214176
<rule ref="SlevomatCodingStandard.ControlStructures.UselessIfConditionWithReturn"/>
@@ -217,11 +179,6 @@
217179
<rule ref="SlevomatCodingStandard.Exceptions.ReferenceThrowableOnly"/>
218180
<rule ref="SlevomatCodingStandard.Exceptions.RequireNonCapturingCatch"/>
219181
<rule ref="SlevomatCodingStandard.Files.FileLength"/>
220-
<rule ref="SlevomatCodingStandard.Functions.ArrowFunctionDeclaration">
221-
<properties>
222-
<property name="spacesCountAfterKeyword" value="0"/>
223-
</properties>
224-
</rule>
225182
<rule ref="SlevomatCodingStandard.Functions.DisallowEmptyFunction"/>
226183
<rule ref="SlevomatCodingStandard.Functions.DisallowTrailingCommaInCall"/>
227184
<rule ref="SlevomatCodingStandard.Functions.DisallowTrailingCommaInClosureUse">
@@ -244,10 +201,7 @@
244201
</properties>
245202
</rule>
246203
<rule ref="SlevomatCodingStandard.Functions.RequireSingleLineCall"/>
247-
<rule ref="SlevomatCodingStandard.Functions.StaticClosure"/>
248-
<rule ref="SlevomatCodingStandard.Functions.StrictCall"/>
249204
<rule ref="SlevomatCodingStandard.Functions.UnusedInheritedVariablePassedToClosure"/>
250-
<rule ref="SlevomatCodingStandard.Functions.UselessParameterDefaultValue"/>
251205
<rule ref="SlevomatCodingStandard.Namespaces.DisallowGroupUse"/>
252206
<rule ref="SlevomatCodingStandard.Namespaces.FullyQualifiedClassNameInAnnotation">
253207
<properties>
@@ -256,23 +210,9 @@
256210
</property>
257211
</properties>
258212
</rule>
259-
<rule ref="SlevomatCodingStandard.Namespaces.FullyQualifiedGlobalConstants"/>
260213
<rule ref="SlevomatCodingStandard.Namespaces.NamespaceDeclaration"/>
261-
<rule ref="SlevomatCodingStandard.Namespaces.NamespaceSpacing"/>
262214
<rule ref="SlevomatCodingStandard.Namespaces.RequireOneNamespaceInFile"/>
263-
<rule ref="SlevomatCodingStandard.Namespaces.UnusedUses">
264-
<properties>
265-
<property name="searchAnnotations" value="true"/>
266-
</properties>
267-
<severity>6</severity>
268-
</rule>
269215
<rule ref="SlevomatCodingStandard.Namespaces.UseFromSameNamespace"/>
270-
<rule ref="SlevomatCodingStandard.Namespaces.UseSpacing">
271-
<properties>
272-
<property name="linesCountBetweenUseTypes" value="1"/>
273-
</properties>
274-
</rule>
275-
<rule ref="SlevomatCodingStandard.Namespaces.UselessAlias"/>
276216
<rule ref="SlevomatCodingStandard.Operators.DisallowEqualOperators"/>
277217
<rule ref="SlevomatCodingStandard.Operators.RequireCombinedAssignmentOperator"/>
278218
<rule ref="SlevomatCodingStandard.Operators.RequireOnlyStandaloneIncrementAndDecrementOperators"/>
@@ -287,8 +227,6 @@
287227
<rule ref="SlevomatCodingStandard.PHP.ForbiddenClasses"/>
288228
<rule ref="SlevomatCodingStandard.PHP.OptimizedFunctionsWithoutUnpacking"/>
289229
<rule ref="SlevomatCodingStandard.PHP.ReferenceSpacing"/>
290-
<rule ref="SlevomatCodingStandard.PHP.RequireNowdoc"/>
291-
<rule ref="SlevomatCodingStandard.Strings.DisallowVariableParsing"/>
292230
<rule ref="SlevomatCodingStandard.TypeHints.DeclareStrictTypes">
293231
<properties>
294232
<property name="declareOnFirstLine" value="true"/>
@@ -297,8 +235,6 @@
297235
</rule>
298236
<rule ref="SlevomatCodingStandard.TypeHints.DisallowMixedTypeHint"/>
299237
<rule ref="SlevomatCodingStandard.TypeHints.DNFTypeHintFormat"/>
300-
<rule ref="SlevomatCodingStandard.TypeHints.LongTypeHints"/>
301-
<rule ref="SlevomatCodingStandard.TypeHints.NullTypeHintOnLastPosition"/>
302238
<rule ref="SlevomatCodingStandard.TypeHints.ParameterTypeHint">
303239
<!-- Native type hints may break inheritance -->
304240
<exclude name="SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint"/>
@@ -362,11 +298,6 @@
362298
<!-- Squiz ruleset: -->
363299
<!-- Checks for empty catch clause without a comment. -->
364300
<rule ref="Squiz.Commenting.EmptyCatchComment"/>
365-
<!-- Force phpDoc alignment -->
366-
<rule ref="Squiz.Commenting.DocCommentAlignment">
367-
<!-- Allow extra spaces after star, i.e. for indented annotations -->
368-
<exclude name="Squiz.Commenting.DocCommentAlignment.SpaceAfterStar"/>
369-
</rule>
370301
<!-- Force rules for function PHPDoc -->
371302
<rule ref="Squiz.Commenting.FunctionComment">
372303
<!-- Allow `@throws` without description -->
@@ -406,10 +337,6 @@
406337
<!-- It is too strict - we are more flexible -->
407338
<exclude name="Squiz.Commenting.FunctionComment.ThrowsNoFullStop"/>
408339
</rule>
409-
<!-- Forbid class being in a file with different name -->
410-
<rule ref="Squiz.Classes.ClassFileName"/>
411-
<!-- Forbid `AND` and `OR`, require `&&` and `||` -->
412-
<rule ref="Squiz.Operators.ValidLogicalOperators"/>
413340
<!-- Force camelCase variables -->
414341
<rule ref="Squiz.NamingConventions.ValidVariableName">
415342
<!-- Eloquent attributes -->
@@ -418,20 +345,12 @@
418345
</rule>
419346
<!-- Forbid `global` -->
420347
<rule ref="Squiz.PHP.GlobalKeyword"/>
421-
<!-- Require PHP function calls in lowercase -->
422-
<rule ref="Squiz.PHP.LowercasePHPFunctions"/>
423348
<!-- Discourages the use of debug functions. -->
424349
<rule ref="Squiz.PHP.DiscouragedFunctions"/>
425350
<!-- Warns about code that can never been executed. -->
426351
<rule ref="Squiz.PHP.NonExecutableCode"/>
427-
<!-- Verifies that class members have scope modifiers. -->
428-
<rule ref="Squiz.Scope.MemberVarScope"/>
429352
<!-- Checks for usage of $this in static methods, which will cause runtime errors. -->
430353
<rule ref="Squiz.Scope.StaticThisUsage"/>
431-
<!-- Use singular quotes by default -->
432-
<rule ref="Squiz.Strings.DoubleQuoteUsage.NotRequired"/>
433-
<!-- Forbid braces around string in `echo` -->
434-
<rule ref="Squiz.Strings.EchoedStrings"/>
435354
<!-- Squiz ruleset end. -->
436355

437356
<!--IxDFCodingStandard custom rules: -->

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@
88
An opinionated coding standard for PHP and Laravel projects, built on [PER-CS 3.0](https://www.php-fig.org/per/coding-style/).
99
Focuses on:
1010
- **High signal-to-noise ratio** (concise but informative PHPDoc, e.g. array shapes)
11+
- **Strict, explicit code**: `strict_types`, strict comparisons, final by default, no magic (`extract()`, variable variables, superglobals)
1112
- **Harmony with static analysis tools** (PHPStan, Psalm, Rector, etc.)
12-
- **Auto-fixing** (violations are not only reported but fixed automatically, when possible)
13+
- **Auto-fixing over reporting** (violations are not only reported but fixed automatically, when possible)
14+
- **PHP and Laravel best practices** (enforced, not just suggested)
1315

1416
Two tools, two roles, meant to run together:
1517
- **PHP-CS-Fixer** (primary): fast PER-CS 3+ auto-formatting and modernization rules.

0 commit comments

Comments
 (0)