Coding standards
Security in ResourceSpace
Developer reference
Database
Action functions
Admin functions
Ajax functions
Annotation functions
API functions
Collections functions
Comment functions
Config functions
CSV export functions
Dash functions
Debug functions
Encryption functions
Facial recognition functions
File functions
General functions
Language functions
Log functions
Login functions
Message functions
Migration functions
Node functions
PDF functions
Plugin functions
Render functions
Reporting functions
Request functions
Research functions
Slideshow functions
Theme permission functions
User functions
Video functions
Database functions
Metadata functions
Resource functions
Search functions
Map functions
Job functions
Tab functions
Test functions

Coding standards v2.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.

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.4, therefore all code submitted must be compatible with 7.4. Versions 8.0, 8.1, 8.2 and 8.3 are also supported.

Backwards 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.

Follow the PSR-1 and PSR-12 PHP coding standards. With the following caveats specific to our coding standards:

  • Only use long opening tags <​?php ?>, do not use short-echo tags <?= ?>.

Indentation

Code must use an indent of 4 spaces for each indent level, and must not use tabs for indenting.

Line length

There is no hard limit on line length, however the soft limit is 120 characters. Ideally lines shouldn't be longer than 80 characters, lines longer than that should be split into multiple subsequent lines of no more than 80 characters each.

Control structures

if, elseif, else

An if structure looks like the following. Note the placement of parentheses, spaces, and braces; and that else and elseif are on the same line as the closing brace from the earlier body.

if ($expr1) {
    // if body
} elseif ($expr2) {
    // elseif body
} else {
    // else body;
}

The keyword 'elseif' should be used instead of 'else if' so that all control keywords look like single words.

Function Definitions

A function declaration looks like the following. Note the placement of parentheses, commas, spaces, and braces:

function fooBarBaz($arg1, &$arg2, $arg3 = [])
{
    // function body
}

Method and function arguments with default values must go at the end of the argument list. Always attempt to return a meaningful value from a function if one is appropriate.

Function Calls

When making a method or function call, there must not be a space between the method or function name and the opening parenthesis, there must not be a space after the opening parenthesis, and there must not be a space before the closing parenthesis. In the argument list, there most not be a space before each comma, and there must be one space after each comma.

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

MySQL statements

Prepared statements

All new MySQL code must use prepared statements. Please see the prepared statements documentation for further information.

When writing SQL ensure keywords are written in upper-case. For example the following prepared statement call:

ps_query("select ref, creation_date from resource where file_extension = "jpg");

Should instead be written as:

ps_query("SELECT ref, creation_date FROM resource WHERE file_extension = "jpg");

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.

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 Joseph Brooke, 6th September 2024.