Collections functions
General functions
Node functions
Render functions
Theme permission functions
User functions
Resource functions

Coding standards v1.3

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.

Our Security in ResourceSpace section teaches developers how to prevent common vulnearbilities in the application.

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

Documentation

Please document all functions using the PHPDoc standard.

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 version

ResourceSpace maintains compatibility with PHP back to version 7.2.5, therefore all code submitted must be compatible with 7.2.5. Version 8.0 is supported.

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

Please follow our Software Design Principals.

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

Prepared statements

All new code must use prepared statements and an effort is underway to port existing code. Please see the prepared statements documentation for further information.

sql_query() - legacy code only

All parameters included in MySQL queries using the older sql_query() function 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) ."'");

Whenever you need to use the values of an array inside a SQL statement, always use escape_check_array_values(). Please note, you will still have to ensure each value is wrapped within single quotes.

For example:

# Having an array like:
$resource_types = array(1, 2, 3, "'SQLi possible");

# which will be used in a SQL statement as follows (NOTE: wrapping single quotes):
$sql_filter .= "resource_type IN ('" . join("', '", escape_check_array_values($resource_types)) . "')";

Do not use this function for new code - all new code must use prepared statements.

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)
        {
        // function logic here
        
        return $calculated_value;
        }
    else
        {
        return null;
        }
    }

Example 2 - Refactored Code to Return Early

function foo($bar, $baz)
    {
    if (!$foo)
        {
        return null;
        }
        
    // function logic here
    
    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 Dan Huby, 4th May 2022.