Introduction to Using
Coding Standards in
Your WordPress Project

WordPress Suffolk, August 2018


Gary Jones
@GaryJ

The Bug

Apple’s “gotofail” Code

...
if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0)
    goto fail;
if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
    goto fail;
    goto fail;
if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0)
    goto fail;
...
...
if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0) {
    goto fail;
}
if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0) {
    goto fail;
    goto fail;
}
if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0) {
    goto fail;
}
...
...
if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0) {
    goto fail;
}
if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0) {
    goto fail;
}
goto fail;
if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0) {
    goto fail;
}
...

Our Goal

Introduce you to the coding standards, and how to apply them in your WordPress work

Contents

  • What is a coding standard?
  • What is the WordPress coding standard?
  • .editorconfig
  • PHP_CodeSniffer (PHPCS) tool
  • WordPress Coding Standards (WPCS)
  • Other standards
  • Using PHPCS
  • Auto-fixing Code
  • Workflow

What is a coding standard?

What are coding conventions?

Conventions quote

Coding conventions are a set of guidelines for a specific programming language that recommend programming style, practices, and methods for each aspect of a program written in that language.

Convention guidelines

  • Indentation
  • Comments
  • Declarations
  • Statements
  • White space
  • Naming conventions
  • Best practices
  • Programming principles

Conventions become standards

Where coding conventions have been specifically designed to produce high-quality code, and have then been formally adopted, they then become coding standards.

Code Quality?

Not a (direct) measure of code quality!

Why follow a coding standard?

Consistency

  • For yourself: maintainability
  • For your colleagues: code review
  • For your industry peers: readability
  • For computers: task automation

(And not introducing bugs like Apple!)


What are the WordPress coding standards?

https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/

PHP CS Handbook

The Biggest patch

  • Changeset 42343, December 2017
  • 1103 files changed
  • 71,221 errors and 19,581 warnings fixed
  • 3,554 errors and 1,235 warnings remain
  • 105,650 lines added, 77,558 lines removed, with an 11MB diff
  • First time in 12 years WordPress core had come close to following its own standards

.editorconfig

https://editorconfig.org/

Editorconfig website

.editorconfig Example

root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = tab

[*.yml]
indent_style = space
indent_size = 2

[*.txt]
end_of_line = crlf

[*.md]
trim_trailing_whitespace = false

PHP_CodeSniffer (PHPCS)

https://github.com/squizlabs/PHP_CodeSniffer

Can install with Composer, Git, PEAR or as a PHAR.

PHP_CodeSniffer website

Rulesets → Sniffs → Checks

Tokens

function wpsuffolk_get_attendees() {

}
Process token 1: T_FUNCTION => function
Process token 2: T_WHITESPACE => ·
Process token 3: T_STRING => wpsuffolk_get_attendees
Process token 4: T_OPEN_PARENTHESIS => (
Process token 5: T_CLOSE_PARENTHESIS => )
Process token 6: T_WHITESPACE => ·
Process token 7: T_OPEN_CURLY_BRACKET => {
Process token 8: T_WHITESPACE => \n\n
Process token 9: T_CLOSE_CURLY_BRACKET => }
Process token 10: T_WHITESPACE => \n

PHPCS Built-in Standards

  • PEAR
  • PSR1
  • PSR2
  • Zend
  • MySource
  • Squiz

Configuration Options

Basic Ruleset

<?xml version="1.0"?>
<ruleset name="MyPluginSlug">
	<description>Custom ruleset for plugin.</description>
	<file>.</file>
	<exclude-pattern>./vendor/</exclude-pattern>
	<arg value="sp"/>
	<arg name="extensions" value="php"/>
	<rule ref="PSR2"/>
</ruleset>

Auto-found filenames

  1. .phpcs.xml
  2. phpcs.xml
  3. .phpcs.xml.dist
  4. phpcs.xml.dist

.gitignore

/node_modules/
/vendor/
/composer.lock
/.phpcs.xml
/phpcs.xml

Userland Standards

  • CodeIgniter
  • Drupal
  • Laravel
  • Magento
  • Neutron
  • PHPCompatibility
  • Symfony2
  • WordPress

WordPress Coding Standards (WPCS)

https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards

Existed since April 2009

1.0.0 released July 2018

WordPress Rulesets

  • WordPress — complete set with all of the sniffs in the project
    • WordPress-Core — main ruleset for WordPress core coding standards
    • WordPress-Docs — additional ruleset for WordPress inline documentation standards
    • WordPress-Extra — extended ruleset for recommended best practices, not sufficiently covered in the WordPress core coding standards. Includes WordPress-Core

Ruleset with WordPress

<?xml version="1.0"?>
<ruleset name="MyPluginSlug">
	<file>.</file>
	<exclude-pattern>./vendor/</exclude-pattern>

	<rule ref="WordPress-Extra"/>
	<rule ref="WordPress-Docs"/>
</ruleset>
	<config name="minimum_supported_wp_version" value="4.7"/>

	<rule ref="WordPress.Files.FileName">
		<properties>
			<property name="strict_class_file_names" value="false"/>
		</properties>
		<exclude name="WordPress.Files.FileName.NotHyphenatedLowercase"/>
	</rule>
	<rule ref="WordPress.NamingConventions.PrefixAllGlobals">
		<properties>
			<property name="prefixes" type="array">
				<element name="plugin_slug"/>
			</property>
		</properties>
	</rule>
	<rule ref="WordPress.WP.I18n">
		<properties>
			<property name="text_domain" type="array">
				<element name="plugin-slug"/>
			</property>
		</properties>
	</rule>

PHPCompatibilityWP

Wrapper for PHPCompatibility standard: excludes back-fills and poly-fills which are provided by WordPress.

Ruleset with PHPCompatibilityWP

<?xml version="1.0"?>
<ruleset name="MyPluginSlug">
	<file>.</file>
	<exclude-pattern>./vendor/</exclude-pattern>

	<rule ref="PHPCompatibilityWP"/>
	<config name="testVersion" value="7.1-"/>
</ruleset>

PHP compatibility examples

namespace PurpleHippo\AwesomeTheme;

Namespaces only added in PHP 5.3.

$array = [ 'foo', 'bar' ];

Short array syntax only added in PHP 5.4.

function wpandup_count_health_hubs(): int {
    return 4;
};

Scalar return types added in PHP 7.0.

empty( '' );
empty( array() );
empty( trim( $name ) );
empty( $variable + 0 );

Only variables can be passed to empty() prior to PHP 5.5.

$f = function () use ( $_SERVER ) {};
$g = function () use ( $this ) {};
$h = function ( $param ) use ( $param ) {};

Variables bound to a closure via the use construct cannot use the same name as any superglobals, $this, or any parameter, since PHP 7.1.

Neutron PHP Standard

By Automattic: https://github.com/Automattic/phpcs-neutron-standard

For PHP 7+

Using PHPCS

function wpsuffolk_get_attendees () {

}

PHPCS Result

Auto-fixing Code

Indicated by [x] in reports

Not all violations can be fixed

But many (mostly whitespace-related) can!

Great timesaver

Can quickly address code style violation noise, so can focus on security, best practices etc.

Auto-fixing Example

PHPCS Reports

https://github.com/squizlabs/PHP_CodeSniffer/wiki/Reporting

  • Checkstyle
  • Code
  • CSV
  • Diff
  • Emacs
  • Full (default)
  • Git Blame
  • HG Blame
  • Information
  • JSON
  • JUnit
  • Notify-Send
  • Source
  • Summary
  • SVN Blame
  • XML

Workflow

IDE / Editor integration

Get violations highlighted as you write code.

Screenshot of a PHPCS violation in PhpStorm

Composer script (for complex needs)

PHP 7.0+, except for main plugin file.

{
	"scripts": {
		"phpcs": "phpcs && phpcs ./plugin-slug.php -sp --standard=PHPCompatibility --runtime-set testVersion 5.2"
	}
}

composer phpcs

Pre-Commit Hooks

Run PHPCS before any local commit is allowed to be accepted.

https://github.com/php-composter/php-composter-phpcs-wpcs

Continuous Integration

Travis CI, Circle CI, etc.
Run PHPCS as part of any new commit / pull request.

Conclusion

Q & A

Slides: https://gmj.to/wpcs-wpsuffolk


Gary Jones

@GaryJ      @GaryJones