WordCamp Ottawa 2019
@remyperona
WordCamp Ottawa 2019
@remyperona
WordCamp Ottawa 2019
@remyperona
WHAT IS IT?
Keeps track of source code changes over time in software projects
WordCamp Ottawa 2019
@remyperona
MAIN SYSTEMS
Subversion (SVN): used by WordPress
Git: used by thousands of plugins & themesdevelopers
WordCamp Ottawa 2019
@remyperona
ADVANTAGES
History of all changes in the source code
Easier teamwork: branches and merge system
Traceability for project management
WordCamp Ottawa 2019
@remyperona
PLATFORMS
GitHub - GitLab - BitBucket
WordCamp Ottawa 2019
@remyperona
PRIVATE OR PUBLIC REPOSITORY?
Except if you have a good reason, always public!
WordCamp Ottawa 2019
@remyperona
WordCamp Ottawa 2019
@remyperona
Current minimum version of PHP for WordPress
5.6
WordCamp Ottawa 2019
@remyperona
Minimum version of PHP for your project
YOU DECIDE
(recommend at least PHP 7.2)
WordCamp Ottawa 2019
@remyperona
WordPress still maintains versions down to
3.7
WordCamp Ottawa 2019
@remyperona
Version of WordPress you need to be compatible with
YOU DECIDE
WordCamp Ottawa 2019
@remyperona
WordCamp Ottawa 2019
@remyperona
NAMESPACES
Organization of code in a virtual hierarchy to prevent name conflicts
WordCamp Ottawa 2019
@remyperona
NAMESPACES
namespace WP_Rocket;
class Plugin {
public function init() {}
}
WordCamp Ottawa 2019
@remyperona
NAMESPACES
namespace Imagify;
class Plugin {
public function init() {}
}
WordCamp Ottawa 2019
@remyperona
NAMESPACES
namespace WP_Rocket\Admin\Settings;
class Page {
public function configure() {}
}
Filepath: wp-rocket/inc/classes/Admin/Settings/Page.php
WordCamp Ottawa 2019
@remyperona
TRAITS
Mechanism for code reuse to reduce some limitations in single inheritance
Enable to share sets of methods in independent classes
WordCamp Ottawa 2019
@remyperona
TRAITS
trait Path_Rewriter {
public function rewrite_paths( $file, $content ) {
return \Minify_CSS_UriRewriter::rewrite(
dirname( $file ),
$content
);
}
}
WordCamp Ottawa 2019
@remyperona
TRAITS
class Minify {
use Path_Rewriter;
public function minify( $file ) {
// code before
$file_content = $this->rewrite_paths( $file, $file_content );
// code after
}
}
WordCamp Ottawa 2019
@remyperona
TRAITS
class Remove_Query_String {
use Path_Rewriter;
public function replace_url( $url ) {
// code before
$content = $this->rewrite_paths( $file, $content );
// code after
}
}
WordCamp Ottawa 2019
@remyperona
ANONYMOUS FUNCTIONS
Create functions without giving them a name
Enable to simplify code for one-time use functions and loops
Especially useful for functions with a callback parameter like array_map()
WordCamp Ottawa 2019
@remyperona
BEFORE
foreach ( $matches as $i => $match ) {
// one-time use function
if ( ! rocket_is_match( $match ) ) {
unset( $matches[ $i ];
}
}
WordCamp Ottawa 2019
@remyperona
AFTER
$matches = array_map(
function( $match ) {
if ( false === \strpos( $match[1], 'GoogleAnalyticsObject' ) ) {
return;
}
return $match;
},
$matches
);
WordCamp Ottawa 2019
@remyperona
AVOID
// anonymous function on a WordPress hook.
// Can't be removed (or really hard)
add_filter( 'the_content', function( $content ) {
return 'hello world';
}
WordCamp Ottawa 2019
@remyperona
WordCamp Ottawa 2019
@remyperona
Group of rules established by PHP-FIG (Framework Interoperability Group)
The goal is to establish commonalities between projects
https://www.php-fig.org
WordCamp Ottawa 2019
@remyperona
These established recommendations allow to standardize and share between projects:
- How to write code
- How to load code
- How to interact with specific interfaces
WordCamp Ottawa 2019
@remyperona
WordCamp Ottawa 2019
@remyperona
WordCamp Ottawa 2019
@remyperona
WordCamp Ottawa 2019
@remyperona
WordCamp Ottawa 2019
@remyperona
DEPENDENCY MANAGER FOR PHP
https://getcomposer.org
https://packagist.org
WordCamp Ottawa 2019
@remyperona
ADVANTAGES
Simplify maintenance of dependencies in the source code: installation & update
Automatic inclusion of dependencies code in your project with the autoloader
WordCamp Ottawa 2019
@remyperona
COMPOSER.JSON
{
"name": "wp-media/wp-rocket",
"type": "wordpress-plugin",
"require": {
"php": ">=5.4.0",
"a5hleyrich/wp-background-processing": "1.1 as 1.0",
"composer/installers": "~1.0",
"jamesryanbell/cloudflare": "^1.11",
"matthiasmullie/minify": "1.3.*"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "^0.4.4",
"phpcompatibility/phpcompatibility-wp": "*",
"squizlabs/php_codesniffer": "^3.2",
"wp-coding-standards/wpcs": "^1.0.0"
}
}
WordCamp Ottawa 2019
@remyperona
COMMANDS
// Installs dependencies listed in composer.json
composer install
// Updates dependencies in composer.json
composer update
// Adds a dependency to the current set and installs it
composer require author/package
WordCamp Ottawa 2019
@remyperona
WordCamp Ottawa 2019
@remyperona
WHAT IS IT?
Automatic loading of PHP files/classes when you need it (if they are not yet)
WordCamp Ottawa 2019
@remyperona
WITHOUT AUTOLOADING
require WP_ROCKET_FUNCTIONS_PATH . 'files.php';
require WP_ROCKET_FUNCTIONS_PATH . 'posts.php';
require WP_ROCKET_FUNCTIONS_PATH . 'admin.php';
require WP_ROCKET_FUNCTIONS_PATH . 'formatting.php';
require WP_ROCKET_FUNCTIONS_PATH . 'cdn.php';
require WP_ROCKET_FUNCTIONS_PATH . 'i18n.php';
require WP_ROCKET_FUNCTIONS_PATH . 'bots.php';
WordCamp Ottawa 2019
@remyperona
WITH COMPOSER AUTOLOADER
require 'vendor/autoload.php';
$wp_rocket = new WP_Rocket\Plugin();
$wp_rocket->load();
WordCamp Ottawa 2019
@remyperona
COMPOSER.JSON
In composer.json
...
"autoload": {
"psr-4" : {"WP_Rocket\\" : "inc"}
}
...
WordCamp Ottawa 2019
@remyperona
WordCamp Ottawa 2019
@remyperona
GOAL
Any code in a project follow the same coding style independently of who wrote it
WordCamp Ottawa 2019
@remyperona
ADVANTAGES
- Anyone can read and modify part of the code, no matter when or who wrote it
- Helps to eliminate common errors
- Improves code visibility
WordCamp Ottawa 2019
@remyperona
VARIOUS STANDARDS
WordPress Coding Standards
https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/
PSR-1 (basic coding standard) & PSR-2 (coding style guide)
WordCamp Ottawa 2019
@remyperona
TOOLS
PHP CodeSniffer
https://github.com/squizlabs/PHP_CodeSniffer
WordPress Coding Standards
https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards
WordCamp Ottawa 2019
@remyperona
EXAMPLE
FILE: /wp-rocket/inc/functions/formatting.php
----------------------------------------------------------------------------------------------------------------------------------
FOUND 2 ERRORS AFFECTING 2 LINES
----------------------------------------------------------------------------------------------------------------------------------
191 | ERROR | [ ] Functions declared by a theme/plugin should start with the
theme/plugin prefix. Found: "get_rocket_parse_url".
322 | ERROR | [x] No space found after comma in function call
----------------------------------------------------------------------------------------------------------------------------------
WordCamp Ottawa 2019
@remyperona
WordCamp Ottawa 2019
@remyperona
Tool to detect potential issues in the source code
https://phpmd.org
WordCamp Ottawa 2019
@remyperona
HELPS FOR
Potential bugs
Unused variables, parameters or methods
Too long or too complex code
WordCamp Ottawa 2019
@remyperona
EXAMPLE
/wp-rocket/inc/classes/class-rocket-background-database.php
- The method task() has 103 lines of code.
Current threshold is set to 100. Avoid really long methods.
- The method task uses an else expression.
Else is never necessary and you can simplify the code to work without else.
- Avoid unused parameters such as '$data
WordCamp Ottawa 2019
@remyperona
WordCamp Ottawa 2019
@remyperona
REDUCE TIME NEEDED TO EXECUTE REPETITIVE TASKS
WordCamp Ottawa 2019
@remyperona
DEPLOYMENT OF A NEW PLUGIN VERSION (BEFORE)
- Creation of a new release on GitHub
- Download zip file
- Extract zip file
- Rename folder
- composer install --no-dev for dependencies
- Recompress folder with the correct filename format
- Connection and upload to the FTP
- Update version in the website admin
WordCamp Ottawa 2019
@remyperona
DEPLOYMENT OF A NEW PLUGIN VERSION (AFTER WITH ANSIBLE)
- Creation of a new release on GitHub
- ansible-playbook deploy-plugin.yml -i servers
- Update version in the website admin
https://www.ansible.com
WordCamp Ottawa 2019
@remyperona
WordCamp Ottawa 2019
@remyperona
UNIT TESTS
Test return of each unit (function or method) to ensure it is the expected result in complete isolation, without any external dependent on the overall state of the system.
https://phpunit.de/index.html
WordCamp Ottawa 2019
@remyperona
INTEGRATION TESTS
Test the behaviour of the code when integrated in the system: here, WordPress
https://make.wordpress.org/core/handbook/testing/automated-testing/writing-phpunit-tests/
WordCamp Ottawa 2019
@remyperona
AUTOMATIZATION
Execute tests in a continuous integration system like
Travis-CI / CircleCI / Etc
WordCamp Ottawa 2019
@remyperona
- Modern PHP - O'Reilly
- PHP Objects, Patterns and Practice - Apress
- Carl Alexander https://carlalexander.ca
- Alain Schlesser https://www.alainschlesser.com/
- Josh Pollock https://joshpress.net - https://torquemag.io/author/joshp/
- Tonya Mork https://knowthecode.io - https://hellofromtonya.com
WordCamp Ottawa 2019
@remyperona
Lead developer of WP Rocket at WP Media