Coding standards v1.0

Coding standards are important in any development project, but particularly when multiple developers are working on the same project. Having coding standards helps ensure that the code is of high quality, has fewer bugs, and is easily maintained.

Security

Security should be first and foremost in the minds of developers. It is easy to accidentally introduce a new vulnerability.

Developers should familiarise themselves with the OWASP guidelines, in particular the OWASP Top Ten.

Cross-Site Request Forgery (CSRF) - version 8.5+

Use generateFormToken($form_id) to render a hidden input tag with the CSRF token for this form (mentioned in the form_id argument). Most common use is:

generateFormToken($form_id);

Use enforcePostRequest($ajax) when processing state-changing operations. Most common use case should be enforcePostRequest(getval("ajax", false)). Add CSRF tokens until you no longer have failed CSRF validation errors. Add enforcePostRequest() where needed and double check process works by attempting a GET request.

For AJAX requests, please use echo generateAjaxToken($form_id); in your post data. This will add a JSON "identifier: value" pair. IMPORTANT: make sure generateAjaxToken() is always used at the end of post data and there is no comma after it as this function will return an empty string if CSRF is disabled on a system.

If there is a need to use these in a pure JS file, then the identifier should be set using the $CSRF_token_identifier configuration option and the token generated using generateCSRFToken().

Functionality

Subversion is used to ensure that ResourceSpace is kept up to date and ready to run at all times. Code submitted to the codebase should be applied to the most recent version in a working and tested form in order to produce quality builds with continued functionality and compatible releases for all users in mind.

PHP 5.3

ResourceSpace maintains compatibility with PHP back to version 5.3. All code submitted must be compatible with 5.3. This is for security reasons as versions prior to 5.3 are no longer supported by PHP group.

MySQL Strict Mode

Strict mode seems to be the default in most Windows MySQL installations, as a result all code submitted should be compatible with MySQL strict mode. A development option exists to enable strict mode in ResourceSpace for development purposes. Enter the following line into your /include/config.php file to enable strict mode:

$mysql_force_strict_mode=true;

Backward Compatibility

ResourceSpace maintains a backward compatibility policy that all code submitted should allow users upgrading to the next release to do so by replacing installed files with versions from the next release. See files in the dbstruct folder for more information on making additions to database files.

File Format

All files contributed to the repository should:

  • Be stored as ASCII text
  • Use UTF-8 character encoding
  • Mark line ends using the ASCII character LF (UNIX style, not Windows style).
  • All interpreted files must end in .php

Coding Style

Always use <‚Äč?php and ?> to open and close sections of php code rather than short or asp style tags. This ensures broader compatibility across multiple systems.

Pages which produce no output do not need a closing ?> tag. Omitting the closing tag helps prevent unintentional white space being introduced.

Indentation

Use spaces to indent, not tabs. Indent size should be four spaces.

Please use Whitesmiths style indentation.

Line Length

There is no set limit for line length except concerning documentation blocks. Use your judgement based on the nature of the line and readability.

Control Structures

These include if, for, while, switch, etc. Here is an example if statement, since it is the most complicated:

if ((condition1) || (condition2))
    {
    action1;
    } 
elseif ((condition3) && (condition4))
    {
    action2;
    } 
else
    {
    defaultaction;
    }

You are strongly encouraged to always use curly braces even in situations where they are technically optional. Bracing all control structures increases readability and makes addition of any statments 'safe'.

Function Calls

Functions should be called with no spaces between the function name and the opening parenthesis, and no space between this and the first parameter; a space after the comma between each parameter (if they are present), and no space between the last parameter and the closing parenthesis, and the semicolon. Here's an example:

$var = foo($bar, $baz, $quux);

As displayed above, there should be space before and one space after the equals sign used to assign the return value of a function to a variable. In the case of a block of related assignments, spaces may be inserted to promote readability:

$short          = foo($bar);
$long_variable  = foo($baz);

Function Definitions

function example_function($arg1, $arg2 = '')
    {
    if (condition)
        {
        statement;
        }
    return $val;
    }

Arguments with default values should be placed at the end of the argument list. Always attempt to return a meaningful value from a function if one is appropriate.

MySQL Statements

All parameters included in MySQL queries should be enclosed within single quotes, even if numeric. They must also have passed through either getvalescaped() or escape_check() to ensure that they are safe for insertion into SQL. See example:

sql_query("update resource SET is_transcoding = 1 WHERE ref = '". escape_check($ref) ."'");

Readability of Code Blocks

Related lines of code should be grouped into blocks, seperated from each other to keep readability as high as possible. The definition of "related" depends on the code.

For example:

if ($foo)
    {
    $bar = 1;
    }

if ($spam)
    {
    $ham = 1;
    }

if ($pinky)
    {
    $brain = 1;
    }

Return Early

To keep readability in functions and methods, simple conditions should be evaluated before the main logic of the function. This avoids issues such as Example 1 where the main logic is inside an if statement. Example 2 is a demonstration of how returning early should be used.

Example 1 - Not Returning Early

function foo($bar, $baz)
    {
    if ($foo)
        {
        //assume
        //that
        //here
        //is
        //the
        //whole
        //logic
        //of
        //this
        //method
        return $calculated_value;
        }
    else
        {
        return null;
        }
    }

Example 2 - Refactored Code to Return Early

function foo($bar, $baz)
    {
    if (!$foo)
        {
        return null;
        }

    //assume
    //that
    //here
    //is
    //the
    //whole
    //logic
    //of
    //this
    //method
    return $calculated_value;
    }

Avoiding cross-site scripting vulnerabilities (XSS)

To reduce the risk of XSS any anchor links that are rendered on a page should be generated using the generateURL() function.

This function is particularly useful if you have a set of query string parameters that will repeatedly used for a number of links on a page.

The default query string parameters should first be stored in an array. An example is shown below.

$defaultparams= array(
    'search'                        => $search,
    'display'                       => $display,
    'order_by'                      => $order_by,
    'offset'                        => $offset,
    'per_page'                      => $per_page,
    'archive'                       => $archive,
    'sort'                          => $sort,
    'restypes'                      => $restypes
    )

The URL is then generated by calling the function with the following arguments

URL The page URL
Default parameters An array of default query string parameters to be added to the URL
Override parameters (optional) An additional array of query string parameters

Any override parameters will replace those set in the default array, or will be added if they are not already present e.g.

generateURL($baseurl_short . "pages/view.php", $defaultparams, array("ref"=>$ref));
Will produce a URL with encoded parameters similar to the one below:-
/pages/view.php?search=tree&display=thumbs&order_by=relevance&offset=0&per_page=48&archive=&sort=DESC&restypes=1%2C2%2C3%2C4&ref=119434

This is a Controlled Document. Last updated by Neil Braddy, 8th November 2018.