WordPress Coding Standards(WPCS) is the Best Team Tool

7 min read
4503

WordPress Coding Standards(WPCS) the list of PHP_CodeSniffer (PHPCS) ruleset (sniffs) to check your code inside WordPress. It can improve your code quality and adhere to basic code conventions for WordPress.

Do you work in a team or want to upgrade code quality? Then it would be best if you thought about a single coding standard. I’m afraid you, but if there is more than one person in your team, it doesn’t work without quality control tools.

The control quality tool for coding standard names the linter and exists for each programming language.

Lint, or a linter, is a static code analysis tool used to flag programming errors, bugs, stylistic errors, and suspicious constructs.

Wikipedia

As example for Python – Pylint, for PHP – PHP_CodeSniffer, for JavaScript – ESLint or JSHint, etc.

The WordPress Coding Standard includes as simple rules about spaces and blanks as brutal rules about security rules, caching, etc.

How to install WordPress Conding Standards?

Just use the composer:

composer require wp-coding-standards/wpcs --dev

When you add any packages to PHP_CodeSniffer, you need to add these packages to the scope of PHPCS. The best solution is a package that automatically adds all packages from your vendor in the scope of PHPCS.

composer require dealerdirect/phpcodesniffer-composer-installer --dev

And now you can easy to check or fix a file(s):

vendor/bin/phpcs --standard=WordPress path/to/some/file.php 
vendor/bin/phpcbf --standard=WordPress path/to/some/file.php 

How to set up WPCS inside the PhpStorm?

Firstly, we need to set up the PHP interpreter:

PHPStorm -> Settings -> Languages & Frameworks -> PHP -> CLI Interpreter and choose your current PHP version.

Secondly, set up the PHP_CodeSniffer:

PHPStorm -> Settings -> Languages & Frameworks -> PHP -> Quality Tools -> PHP_CodeSniffer -> Configuration and click on the ‘…’ button

Fill in the PHP_CodeSniffer path:

path/to/vendor/squizlabs/php_codesniffer/bin/phpcs

and fill in the Path to phpcbf:

path/to/vendor/squizlabs/php_codesniffer/bin/phpcsbf

Press on the Validate button and accept that your paths are correct.

Last but not least, set up the PhpStorm editor:

PHPStorm -> Settings -> Editor -> Inspection -> Quality Tools -> PHP_CodeSniffer validation:

Check the Show sniff name field.

Choose WordPress in the Coding Standard list. Also, you can see other packages: WordPress-Core, WordPress-Docs, WordPress-Extra. The WordPress package includes all of them.

And now, if you violate coding standards in the editor, the lines will be underlined. If you hover over the highlighted line, you will see an error.

If after this detailed article you don't implement CS verification in your project, then I will come to you in a dream and kick your ass - WP Punk

How to ignore some WPCS rules?

Sometimes your code can’t be fully compatible with WPCS. For example:

global $wpdb;
$id       = 15;
$my_query = $wpdb->get_results( 'SELECT name FROM my_table WHERE id=' . $id );

In this example, we have a few notices:

  • WordPress.DB.PreparedSQL.NotPrepared
  • WordPress.DB.DirectDatabaseQuery.NoCaching
  • WordPress.DB.DirectDatabaseQuery.DirectQuery

Raw data is a potential XSS backdoor. We can fix it using the $wpdb->prepare method. Caching some queries is also great for performance, and we also can do it. But what do you need to do with a direct query? The right way is adding the ignore rule, but it is essential to understand the reason. If you add an ignore rule, you can read it as a developer’s signature about that line, and a reviewer can read it as “(name) confirms the direct query is necessary here”.

global $wpdb;
$id       = 15;
$my_query = wp_cache_get( 'my_query' );
if ( ! $my_query ) {
	// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
	$my_query = $wpdb->get_results(
		$wpdb->prepare( 'SELECT name FROM my_table WHERE id=%d', $id )
	);
	wp_cache_set( 'my_query', $my_query );
}

phpcs:ignore is ignoring the next line of your code. The best practice you’re php:ignore with a rule description or a few rules description via comma to ignore specific rules.

// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
$wpdb->query( ... );

Also, you can ignore a code block use the phpcs:disable instead. Pay attention that we must enable rules at the end of a block:

//phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery
$my_query = $wpdb->get_results(
	$wpdb->prepare(
		'SELECT name FROM my_table WHERE id=%d',
		$id
	)
);
//phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery

Own Coding Standard Based on WPCS

In my opinion, for projects of medium and large size, you need to create your coding standard. It’s effortless, just make a phpcs.xml file:

<?xml version="1.0"?>
<ruleset name="AwesomeCS">
	<description>Custom coding standards.</description>
	<rule ref="WordPress"/>
</ruleset>

We created the AwesomeCS coding standard based on the WordPress Coding Standards. Let’s add some interesting stuff to our config.

CLI arguments for Condig Standard

You can add arguments from CLI for your config to simplify the run. For example, argument extensions that can help you work only with the PHP files:

<ruleset name="AwesomeCS">
	<!-- ... -->	
	<arg value="ps"/>
	<arg name="colors"/>
	<arg name="parallel" value="100"/>
	<arg name="extensions" value="php"/>
	<!-- ... -->
</ruleset>
  • The ps can show results of check real-time;
  • The colors is just adds the colored output;
  • The parallel checks your files in separate processes. Unfortunately, but this feature based on the PCNTL library and doesn’t works on Non-Unix systems (Windows). But can add the super boost for your speed in the GH actions;
  • The extensions describes the extensions for the checking;

Exclude some files and directories from your CS

Add the list of patterns where phpcs doesn’t check files and directories:

<ruleset name="AwesomeCS">
	<!-- ... -->
	<exclude-pattern>\.github/*</exclude-pattern>
	<exclude-pattern>vendor/*</exclude-pattern>
	<exclude-pattern>node_modues/*</exclude-pattern>
	<exclude-pattern>\.idea/*</exclude-pattern>
	<exclude-pattern>assets/*</exclude-pattern>
	<!-- ... -->
</ruleset>

Pay attention, dots should be slashing here.

Use short array syntax instead of long for your CS

Frankly speaking, the short array syntax it’s uncomfortable and legacy, but is part of the WordPress coding standard. But I slightly prefer to use the short array syntax:

<ruleset name="AwesomeCS">
	<!-- ... -->
	<!-- Allow short array syntax -->
	<rule ref="Generic.Arrays.DisallowShortArraySyntax.Found">
		<severity>0</severity>
	</rule>
	<rule ref="Generic.Arrays.DisallowLongArraySyntax.Found"/>
	<!-- ... -->
</ruleset>

Classes and files naming due to PSR-4 for your CS

I always use composer autoloading, but WPCS has a different approach to naming classes and files:

<ruleset name="AwesomeCS">
	<!-- ... -->
	<rule ref="WordPress">
		<!-- PSR4 -->
		<exclude name="WordPress.Files.FileName.InvalidClassFileName"/>
		<exclude name="WordPress.Files.FileName.NotHyphenatedLowercase"/>
	</rule>
	<!-- ... -->
</ruleset>

Cyclomatic Complexity for your CS

Cyclomatic complexity is a software metric used to indicate the complexity of a program. It is a quantitative measure of the number of linearly independent paths through a program’s source code.

Wikipedia

This metric can help you control code complications and encourage writing more small and simple functions:

<ruleset name="AwesomeCS">
	<!-- ... -->
	<rule ref="Generic.Metrics.CyclomaticComplexity">
		<properties>
			<property name="complexity" value="4"/>
			<property name="absoluteComplexity" value="5"/>
		</properties>
	</rule>
	<!-- ... -->
</ruleset>
  • If the cyclomatic complexity is higher than 4, you will see a warning
  • If the cyclomatic complexity is higher than 5, you will see the error

Nested Level for your CS

<ruleset name="AwesomeCS">
	<!-- ... -->
	<rule ref="Generic.Metrics.NestingLevel">
		<properties>
			<property name="absoluteNestingLevel" value="1"/>
		</properties>
	</rule>
	<!-- ... -->
</ruleset>

The nesting level is nesting your functions and statements. It is a great way to simplify your functions and methods:

function awesome_function( $items ) { // Nested level 2
	if ( is_array( $items ) {
		foreach( $items as $item ) {
			// ...
		}
	}
}

function awesome_function( $items ) { // Nested level 1
	if ( ! is_array( $items ) {
		return false;
	}
	foreach( $items as $item ) {
		// ...
	}
}

PHPCompatibility

Just awesome coding standard PHPCompatibility which you can add the minimal support PHP version and phpcs will detect in your code any problem for it. It’s really a very well library for public plugins when you need to support the form PHP5.6 to PHP7.4 version. Just run your test in php7.4 and this library can help you find any problem with PHP compatibility in 5.6

Let’s install this library and update the config:

composer require phpcompatibility/php-compatibility --dev
<ruleset name="AwesomeCS">
	<!-- ... -->
	<config name="testVersion" value="5.6-"/>
	<rule ref="PHPCompatibility"/>
	<!-- ... -->
</ruleset>

Thanks to this, you can check the compatibility from PHP5.6 to the version on which you are checking the files.

Add your own config to PHPStorm

File -> Settings -> Editor -> Inspection -> Quality Tools -> PHP_CodeSniffer

In the list of Coding Standards select Custom and specify the path to our phpcs.xml

Full config

<?xml version="1.0"?>
<ruleset name="CS">
	<description>Custom coding standards.</description>
	<config name="testVersion" value="5.6-"/>
	<exclude-pattern>\.codeception/*</exclude-pattern>
	<exclude-pattern>\.github/*</exclude-pattern>
	<exclude-pattern>vendor/*</exclude-pattern>
	<exclude-pattern>node_modues/*</exclude-pattern>
	<exclude-pattern>\.idea/*</exclude-pattern>
	<exclude-pattern>assets/*</exclude-pattern>

	<arg value="ps"/>
	<arg name="colors"/>
	<arg name="parallel" value="100"/>
	<arg name="extensions" value="php"/>
	<arg name="cache" value=".phpcs.cache"/>

	<rule ref="WordPress">
		<!-- PSR4 -->
		<exclude name="WordPress.Files.FileName.InvalidClassFileName"/>
		<exclude name="WordPress.Files.FileName.NotHyphenatedLowercase"/>
	</rule>

	<rule ref="PHPCompatibility"/>

	<rule ref="Generic.Metrics.CyclomaticComplexity">
		<properties>
			<property name="complexity" value="3"/>
			<property name="absoluteComplexity" value="5"/>
		</properties>
	</rule>

	<rule ref="Generic.Metrics.NestingLevel">
		<properties>
			<property name="absoluteNestingLevel" value="3"/>
		</properties>
	</rule>

	<!-- Allow short array syntax -->
	<rule ref="Generic.Arrays.DisallowShortArraySyntax.Found">
		<severity>0</severity>
	</rule>
	<rule ref="Generic.Arrays.DisallowLongArraySyntax.Found"/>
</ruleset>

Composer scripts

Add the scripts to run your CS using the composer scripts. Just add to the composer.json next code:

{
...
  "scripts": {
    "cs": "phpcs --standard=.phpcs.xml .",
    "cbf": "phpcbf --standard=.phpcs.xml .",
    ...
  }
...
}

And now you can just run your coding standards and code beautifier and fixer:

composer cs
composer cbf

CS in the GitHub Actions

Create the file .github/workflows/php.yml in your project:

name: My GH Actions

on: push

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2

    - name: Install dependencies
      run: composer install --prefer-dist --no-progress --no-suggest

    - name: Run CS
      run: vendor/bin/phpcs --standard=phpcs.xml .

After push action, your code will be checked on coding standards and you can see results on GitHub.

If after this detailed article you don’t implement CS verification in your project, then I will come to you in a dream and kick your ass.

What the next? You can read how to write your own sniffs for PHP_CodeSniffer.

If the content was useful, share it on social networks

Leave a Reply

Your email address will not be published.

Subscribe to news. I promise not to spam :)
Follow me, don't be shy