Skip to content

Commit ae83465

Browse files
authored
Add ruleset for WordPress (#5)
1 parent bf952a3 commit ae83465

File tree

4 files changed

+249
-38
lines changed

4 files changed

+249
-38
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
<div align="center">
22
<strong>💅 phpcs-ruleset</strong>
3-
<p>PHP Coding Standard applied to Syntatis projects</p>
3+
<p>Curated Coding Standards for PHP and WordPress</p>
44

55
![Packagist PHP Version](https://img.shields.io/packagist/dependency-v/syntatis/coding-standard/php)
66
</div>
77

88
---
99

10-
A collection of rulesets to apply standard PHP coding practices across Syntatis projects. The rulesets are based on some established PHP coding standards, such as [PSR-12](https://www.php-fig.org/psr/psr-12/), [Doctrine](https://github.com/doctrine/coding-standard), [Slevomat](https://github.com/slevomat/coding-standard), and are extended with a few additional rules to suit with the specific projects' needs.
10+
A collection of rulesets to apply standard PHP coding practices. The rulesets are based on some established PHP coding standards, such as [PSR-12](https://www.php-fig.org/psr/psr-12/), [Doctrine](https://github.com/doctrine/coding-standard), [Slevomat](https://github.com/slevomat/coding-standard), and are extended with a few additional rules to suit with the specific projects' needs.

Syntatis/ruleset.xml

Lines changed: 132 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,43 +3,33 @@
33
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
44
xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/squizlabs/PHP_CodeSniffer/master/phpcs.xsd"
55
name="Syntatis">
6-
<description>PHP Coding Standard</description>
6+
<description>Curated Coding Standard for PHP</description>
77

8-
<!-- Use colors in output -->
9-
<arg name="colors"/>
8+
<!--
9+
Trigger error if PHPCSUtils cannot be found.
10+
PHPCSUtils does not contain any sniffs, so this rule isn't strictly necessary, but
11+
by having this here anyway, if PHPCSUtils is missing, the user will get a
12+
descriptive error message during the loading of the ruleset instead of
13+
a fatal "class not found" error once the sniffs start running.
14+
-->
15+
<rule ref="PHPCSUtils"/>
1016

11-
<!-- Show progress of the run -->
12-
<arg value="p"/>
13-
14-
<!-- Show sniff codes in all reports -->
15-
<arg value="s"/>
16-
17-
<!-- Only check files with PHP extension -->
18-
<arg name="extensions" value="php"/>
19-
20-
<!-- Show the warning but exit with 0. The Warning is fine -->
21-
<config name="ignore_warnings_on_exit" value="1"/>
22-
23-
<!-- Include full Doctrine Coding Standard -->
17+
<!-- Doctrine and Slevomat rules -->
2418
<rule ref="Doctrine">
2519
<exclude name="Generic.Formatting.MultipleStatementAlignment"/>
2620
<exclude name="Generic.WhiteSpace.DisallowTabIndent"/>
2721
<exclude name="SlevomatCodingStandard.Classes.SuperfluousExceptionNaming"/>
2822
<exclude name="SlevomatCodingStandard.PHP.RequireExplicitAssertion"/>
2923

30-
<!-- Some of the projects still require to support PHP 7.4 which does not support the follow features -->
24+
<!-- Skip features not in PHP 7.4 -->
3125
<exclude name="SlevomatCodingStandard.Classes.RequireConstructorPropertyPromotion"/>
3226
<exclude name="SlevomatCodingStandard.Functions.RequireTrailingCommaInDeclaration"/>
3327
</rule>
3428
<rule ref="SlevomatCodingStandard.Commenting.DocCommentSpacing">
3529
<properties>
3630
<property name="annotationsGroups" type="array">
3731
<element value="@phpcsSuppress"/>
38-
<!--
39-
Tests annotation
40-
@link https://phpunit.readthedocs.io/en/7.0/annotations.html
41-
The @author annotation is excluded from the list, use @group or @ticket instead.
42-
-->
32+
<!-- PHPUnit annotations (see link) -->
4333
<element value="
4434
@after,
4535
@afterClass,
@@ -68,8 +58,15 @@
6858
@ticket,
6959
@uses"
7060
/>
71-
<!-- Psalm annotations essentially overrides PHP docBlocks -->
72-
<element value="@phpstan-consistent-constructor, @phpstan-import-type, @phpstan-type, @psalm-consistent-constructor, @psalm-import-type, @phpstan-type"/>
61+
<!-- Psalm & PHPStan annotations -->
62+
<element value="
63+
@phpstan-consistent-constructor,
64+
@phpstan-import-type,
65+
@phpstan-type,
66+
@psalm-consistent-constructor,
67+
@psalm-import-type,
68+
@psalm-type"
69+
/>
7370
<element value="@template, @template-implements, @template-extends"/>
7471
<element value="@example, @see, @link, @todo"/>
7572
<element value="@method, @property"/>
@@ -86,20 +83,121 @@
8683
<exclude-pattern>/tests/</exclude-pattern>
8784
</rule>
8885

89-
<!-- Generic -->
90-
<rule ref="Generic.Files.LineLength">
91-
<properties>
92-
<property name="ignoreComments" value="true"/>
93-
</properties>
86+
<!-- Avoid using the "goto" statement -->
87+
<rule ref="Generic.PHP.DiscourageGoto">
88+
<type>error</type>
89+
<message>The "goto" language construct should not be used.</message>
9490
</rule>
91+
92+
<!-- "eval()" is a security risk, so don't use it -->
93+
<rule ref="Squiz.PHP.Eval.Discouraged">
94+
<type>error</type>
95+
<message>eval() is a security risk so not allowed.</message>
96+
</rule>
97+
98+
<!-- PHP tags for multiline PHP code in HTML should be on their own lines -->
99+
<rule ref="Squiz.PHP.EmbeddedPhp"/>
100+
101+
<!-- Always use full PHP tags, not shorthand -->
102+
<rule ref="Generic.PHP.DisallowShortOpenTag"/>
103+
<rule ref="Generic.PHP.DisallowAlternativePHPTags"/>
104+
105+
<!-- Prefer require[_once] for unconditional includes -->
106+
<rule ref="PEAR.Files.IncludingFile.UseRequire">
107+
<type>warning</type>
108+
</rule>
109+
<rule ref="PEAR.Files.IncludingFile.UseRequireOnce">
110+
<type>warning</type>
111+
</rule>
112+
<!-- Prevent issues with content before headers -->
113+
<rule ref="Generic.Files.ByteOrderMark"/>
114+
115+
<!-- Magic constants (__*__) should be uppercase -->
116+
<rule ref="Universal.Constants.UppercaseMagicConstants"/>
117+
118+
<!-- The ::class keyword should be lowercase -->
119+
<rule ref="Universal.Constants.LowercaseClassResolutionKeyword"/>
120+
121+
<!-- Only one namespace declaration per file -->
122+
<rule ref="Universal.Namespaces.OneDeclarationPerFile"/>
123+
124+
<!-- Don't use curly brace syntax for namespaces -->
125+
<rule ref="Universal.Namespaces.DisallowCurlyBraceSyntax"/>
126+
127+
<!-- No explicit global namespace declarations -->
128+
<rule ref="Universal.Namespaces.DisallowDeclarationWithoutName"/>
129+
130+
<!-- Prefer __DIR__ over dirname(__FILE__) and use dirname(__DIR__, $levels) over nested dirname() -->
131+
<rule ref="Modernize.FunctionCalls.Dirname"/>
132+
133+
<!-- Avoid ambiguous conditions -->
134+
<rule ref="Generic.CodeAnalysis.RequireExplicitBooleanOperatorPrecedence"/>
135+
136+
<!-- Use real tabs and not spaces. -->
95137
<rule ref="Generic.WhiteSpace.DisallowSpaceIndent"/>
96-
<rule ref="Generic.WhiteSpace.ScopeIndent">
138+
<rule ref="Universal.WhiteSpace.PrecisionAlignment"/>
139+
140+
<!-- Ensure functions use all passed parameters -->
141+
<rule ref="Generic.CodeAnalysis.UnusedFunctionParameter">
142+
<!-- Allow for callbacks that may not use all parameters -->
143+
<exclude name="Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed"/>
144+
<!-- Allow for extended class/interface functions -->
145+
<exclude name="Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass"/>
146+
<exclude name="Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed"/>
147+
<exclude name="Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassAfterLastUsed"/>
148+
<exclude name="Generic.CodeAnalysis.UnusedFunctionParameter.FoundInImplementedInterface"/>
149+
<exclude name="Generic.CodeAnalysis.UnusedFunctionParameter.FoundInImplementedInterfaceBeforeLastUsed"/>
150+
<exclude name="Generic.CodeAnalysis.UnusedFunctionParameter.FoundInImplementedInterfaceAfterLastUsed"/>
151+
</rule>
152+
153+
<!-- All line endings should be \n. -->
154+
<rule ref="Generic.Files.LineEndings">
97155
<properties>
98-
<property name="indent" value="4" />
99-
<property name="tabIndent" value="true" />
156+
<property name="eolChar" value="\n"/>
100157
</properties>
101158
</rule>
102-
<rule ref="Generic.Files.LineLength.TooLong">
103-
<exclude-pattern>/tests/</exclude-pattern>
159+
160+
<!-- Don't commit commented-out code -->
161+
<rule ref="Squiz.PHP.CommentedOutCode">
162+
<properties>
163+
<property name="maxPercentage" value="40"/>
164+
</properties>
104165
</rule>
166+
167+
<!-- Always have a lowertag PHP open tag. -->
168+
<rule ref="Universal.PHP.LowercasePHPTag"/>
169+
170+
<!-- Check for duplicate array keys -->
171+
<rule ref="Universal.Arrays.DuplicateArrayKey"/>
172+
173+
<!-- No return types for constructors/destructors, or returning values -->
174+
<rule ref="Universal.CodeAnalysis.ConstructorDestructorReturn"/>
175+
176+
<!-- Detect foreach loops using the same variable for key and value -->
177+
<rule ref="Universal.CodeAnalysis.ForeachUniqueAssignment"/>
178+
179+
<!-- Use self instead of static in final classes -->
180+
<rule ref="Universal.CodeAnalysis.StaticInFinalClass"/>
181+
182+
<!-- Avoid if statements as the only statement in an else block -->
183+
<rule ref="Universal.ControlStructures.DisallowLonelyIf"/>
184+
185+
<!-- Separate functions and object-oriented code -->
186+
<rule ref="Universal.Files.SeparateFunctionsFromOO"/>
187+
188+
<!-- Detect useless "echo sprintf(...)" -->
189+
<rule ref="Universal.CodeAnalysis.NoEchoSprintf"/>
190+
191+
<!-- Avoid double negatives "!!" -->
192+
<rule ref="Universal.CodeAnalysis.NoDoubleNegative"/>
193+
194+
<!-- Avoid reserved keywords as function parameter names. -->
195+
<rule ref="Universal.NamingConventions.NoReservedKeywordParameterNames"/>
196+
197+
<!-- General PHP best practices -->
198+
<rule ref="Generic.PHP.BacktickOperator"/>
199+
<rule ref="Universal.UseStatements.NoUselessAliases"/>
200+
<rule ref="Squiz.Functions.FunctionDuplicateArgument"/>
201+
<rule ref="Squiz.PHP.DisallowSizeFunctionsInLoops"/>
202+
<rule ref="Squiz.Operators.IncrementDecrementUsage"/>
105203
</ruleset>

SyntatisWP/ruleset.xml

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
<?xml version="1.0"?>
2+
<ruleset
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/squizlabs/PHP_CodeSniffer/master/phpcs.xsd"
5+
name="SyntatisWP"
6+
>
7+
<description>Curated Coding Standard for WordPress</description>
8+
9+
<rule ref="Syntatis"/>
10+
11+
<!-- Use lowercase letters for variable, action/filter, and function names. Separate words with underscores. -->
12+
<rule ref="WordPress.NamingConventions.ValidFunctionName"/>
13+
<rule ref="WordPress.NamingConventions.ValidHookName"/>
14+
15+
<!-- Avoid direct database access. -->
16+
<rule ref="WordPress.DB.RestrictedFunctions"/>
17+
<rule ref="WordPress.DB.RestrictedClasses"/>
18+
19+
<!-- Escape data as close to the query as possible, ideally using $wpdb->prepare(). -->
20+
<rule ref="WordPress.DB.PreparedSQL"/>
21+
22+
<!-- In $wpdb->prepare, use %s for strings and %d for integers. These placeholders are not quoted! -->
23+
<rule ref="WordPress.DB.PreparedSQLPlaceholders"/>
24+
25+
<!-- create_function() is deprecated in PHP 7.2 and removed in PHP 8.0. Do not use it. -->
26+
<rule ref="WordPress.PHP.RestrictedPHPFunctions"/>
27+
28+
<!-- Use Perl-compatible regular expressions instead of POSIX ones. -->
29+
<rule ref="WordPress.PHP.POSIXFunctions"/>
30+
31+
<!-- Ensure proper use of WordPress internationalization functions. -->
32+
<rule ref="WordPress.WP.I18n"/>
33+
34+
<!-- Ensure correct spelling of "WordPress". -->
35+
<rule ref="WordPress.WP.CapitalPDangit"/>
36+
37+
<!-- Use appropriate DateTime functions. See: https://github.com/WordPress/WordPress-Coding-Standards/issues/1713 -->
38+
<rule ref="WordPress.DateTime.RestrictedFunctions"/>
39+
40+
<!-- Don't use current_time() to get a timestamp. -->
41+
<rule ref="WordPress.DateTime.CurrentTimeTimestamp"/>
42+
43+
<!-- Ensure class name references use the correct case. -->
44+
<rule ref="WordPress.WP.ClassNameCase"/>
45+
46+
<rule ref="WordPress.Security.EscapeOutput"/>
47+
48+
<!-- Prefer wp_safe_redirect() to avoid open redirect vulnerabilities. See: https://github.com/WordPress/WordPress-Coding-Standards/pull/1264 -->
49+
<rule ref="WordPress.Security.SafeRedirect"/>
50+
51+
<!-- Verify nonce checks before using values in superglobals. See: https://github.com/WordPress/WordPress-Coding-Standards/issues/73 -->
52+
<rule ref="WordPress.Security.NonceVerification"/>
53+
54+
<rule ref="WordPress.PHP.DevelopmentFunctions"/>
55+
<rule ref="WordPress.PHP.DiscouragedPHPFunctions"/>
56+
<rule ref="WordPress.WP.DeprecatedFunctions"/>
57+
<rule ref="WordPress.WP.DeprecatedClasses"/>
58+
<rule ref="WordPress.WP.DeprecatedParameters"/>
59+
<rule ref="WordPress.WP.DeprecatedParameterValues"/>
60+
<rule ref="WordPress.WP.AlternativeFunctions"/>
61+
<rule ref="WordPress.WP.DiscouragedConstants"/>
62+
<rule ref="WordPress.WP.DiscouragedFunctions"/>
63+
64+
<!-- Verify correct use of capabilities. -->
65+
<rule ref="WordPress.WP.Capabilities"/>
66+
67+
<!-- Scripts and styles should be enqueued. -->
68+
<rule ref="WordPress.WP.EnqueuedResources"/>
69+
70+
<!-- Warn against overriding WordPress global variables. -->
71+
<rule ref="WordPress.WP.GlobalVariablesOverride"/>
72+
73+
<!-- Detect incorrect or risky use of ini_set(). -->
74+
<rule ref="WordPress.PHP.IniSet"/>
75+
76+
<!-- Ensure styles and scripts have version and in_footer parameters set when enqueuing or registering. -->
77+
<rule ref="WordPress.WP.EnqueuedResourceParameters"/>
78+
79+
<!-- Make translators comment check stricter than the core one. -->
80+
<rule ref="WordPress.WP.I18n.MissingTranslatorsComment">
81+
<type>error</type>
82+
</rule>
83+
<rule ref="WordPress.WP.I18n.TranslatorsCommentWrongStyle">
84+
<type>error</type>
85+
</rule>
86+
87+
<!-- Ensure everything in the global namespace is prefixed. -->
88+
<rule ref="WordPress.NamingConventions.PrefixAllGlobals"/>
89+
90+
<!-- Ensure post type slugs have valid characters, length, and don't use reserved keywords. -->
91+
<rule ref="WordPress.NamingConventions.ValidPostTypeSlug"/>
92+
93+
<!-- Check for some regex best practices. -->
94+
<rule ref="WordPress.PHP.PregQuoteDelimiter"/>
95+
96+
<!-- The Core ruleset respects the PHP allowed functions list. -->
97+
<rule ref="WordPress.PHP.NoSilencedErrors">
98+
<properties>
99+
<property name="usePHPFunctionsList" value="false"/>
100+
</properties>
101+
</rule>
102+
103+
<!-- Prevent common mistakes. -->
104+
<rule ref="WordPress.CodeAnalysis.EscapedNotTranslated"/>
105+
106+
<!-- General best practices -->
107+
<rule ref="WordPress.PHP.DontExtract"/>
108+
<rule ref="WordPress.PHP.StrictInArray"/>
109+
<rule ref="WordPress.Security.PluginMenuSlug"/>
110+
<rule ref="WordPress.WP.CronInterval"/>
111+
<rule ref="WordPress.WP.PostsPerPage"/>
112+
</ruleset>

composer.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "syntatis/coding-standard",
33
"type": "phpcodesniffer-standard",
4-
"description": "PHP Coding Standard applied to Syntatis projects",
4+
"description": "Curated Coding Standards for PHP and WordPress",
55
"license": "MIT",
66
"keywords": [
77
"php",
@@ -19,7 +19,8 @@
1919
"require": {
2020
"php": ">=7.4",
2121
"dealerdirect/phpcodesniffer-composer-installer": "^1.0",
22-
"doctrine/coding-standard": "^12.0"
22+
"doctrine/coding-standard": "^12.0",
23+
"wp-coding-standards/wpcs": "^3.0"
2324
},
2425
"config": {
2526
"allow-plugins": {

0 commit comments

Comments
 (0)