Coding standards

From Mothership
Jump to: navigation, search

When submitting a pull request to Mothership, please adhere to our coding standards.

PHP

General code style

  • All code must be compatible with PHP 5.4
  • PHP files should consist of PHP only. For view files, use Twig
  • Do not use closing PHP tags: ?>
  • Only use the standard PHP opening tag: <?php
  • Do not insert HTML into strings. HTML should only appear in Twig view files.
  • Do not pointlessly concatenate strings:
// Good
$foo = 'this string can be declared on a single line and does not need any concatenation';

// Bad
$foo = 'this '
    . 'string '
    . 'could have been '
    . 'declared on one line';

$bar = 'this is ';
$bar .= 'bad ';
$bar .= 'too!';
  • Braces on loops, if statements, try-catch blocks etc, should be on the same line, e.g.:
// Good
if (true) {
    // do stuff
}

// Bad
if (true)
{
    // do stuff
}
  • Do not use constant operators, i.e. use && instead of and:
// Good
if ($foo && $bar) {
    // do stuff
}

if ($foo || $bar) {
    // do stuff
}

// Bad
if ($foo and $bar) {
    // do stuff
}

if ($foo or $bar) {
    // do stuff
}
  • Use shorthand array syntax:
// Good
$array = [
    'one',
    'two',
    'three'
];

// Bar
$array = array(
    'one',
    'two',
    'three'
);
  • Use PHP_EOL instead of \n or \r

Tabs vs Spaces

Contrary to PSR-2, the platform uses tabs for indentation. Regardless of your opinion of this, consistency is more important than following the PSR2 standard, and makes the code much easier to read in Github.

In order to make the code easier to read, line up related declarations that sit next to each other using spaces, eg:

$name     = 'foo';
$longName = 'bar';

Class declarations

  • Class declarations should start with a capital letter (or underscore if it is a Database migration), and be camel cased, e.g.:
// Good
class MyClass
{

}

// Bad
class My_Class
{

}

class myClass
{

}
  • Braces should be dropped to the following line. Nothing else should be on this line, e.g.:
// Good
class MyClass
{
}

// Bad
class MyClass {

}

class MyClass
{ public $var; }
  • Classes must be loaded using PSR-4 autoloading
  • Classes must be namespaced, and all of Mothership's core and modules must come under the Message\Mothership namespace. Mothership-related classes (e.g. the installer, the base theme, etc.) must come under the Mothership namespace
  • Follow the 'single responsibility principle', i.e. a class should do one thing and do it well
  • Only declare one class per file
  • In most cases, the class should be accessed via the service container

Methods

  • Methods should only be declared as public only if they are intended to be accessed from outside the class
  • Methods should only be declared as protected if they are intended to be inherited by higher level classes
  • All other methods should be declared as private
  • As with classes, braces must be dropped down to a new line
  • Method name should be be camel cased:
// Good
public function myMethod()
{

}

// Bad
public function my_method()
{

}

public function mymethod()
{

}
  • Methods must have an empty line before the return statement (unless the return is within an if statement or loop), e.g.:
public function myMethod()
{
    if (false) {
        return false;
    }

    return true;
}

Variables

  • Variable names must have descriptive names that are as concise as possible
  • Variable names must be camel cased, i.e. $varName is good, $var_name is bad

Exceptions

  • Never throw vanilla \Exception classes
  • Throw \InvalidArgumentException if the problem is related to a parameter being the wrong type or class instance
  • Throw \LogicException if the problem relates to any other code issues, or user-input
  • Throw \RuntimeException if the issue is related to the system, such as a file not found, or a database connection failing to establish
  • Ideally, write new exceptions for specific purposes, extending \InvalidArgumentException, \LogicException or \RuntimeException as per the rules outlined above

Docblocks

Docblocks for methods must:

  • Contain a description about what the method does
  • State expected variable type for each parameter, as well as give a description of what it does
  • State any exceptions that might get thrown and while
  • State the variable type that is returned
  • Leave an empty line before the return
  • Line up text appropriately

An example of a good docblock is as follows:

/**
 * This method will return $foo unless $bar is false
 *
 * @param string $foo        This is a string that will get returned
 * @param bool $bar          This determines whether or not $foo will be returned
 * @throws \LogicException   Throws an exception if $bar is false
 *
 * @return string            Will return $foo
 */
public function myMethod($foo, $bar)
{
     if (!$bar) {
        throw new \LogicException('This is an exception');
     }

     return $foo;
}