array("'none'"), 'base-uri' => array("'self'"), 'connect-src' => array("'self'"), // 'form-action' => array("'self'"), // Needed for /features/tools/formFaker/ 'style-src' => array('/a/css/'), 'script-src' => array('/a/js/'), 'img-src' => array("'self'"), 'frame-src' => array(), ); if ($GLOBALS['tplTracking'] !== false) { $csp_directives['script-src'][] = 'https://www.google-analytics.com'; $csp_directives['connect-src'][] = 'https://www.google-analytics.com'; } //-------------------------------------------------- // Build CSP if ($csp_enforced) { $header = 'Content-Security-Policy'; } else { $header = 'Content-Security-Policy-Report-Only'; } if ($csp_framing == 'DENY') { $csp_directives['frame-ancestors'] = "'none'"; } else if ($csp_framing == 'SAMEORIGIN') { $csp_directives['frame-ancestors'] = "'self'"; } if ($csp_report_uri && !array_key_exists('report-uri', $csp_directives)) { // isset returns false for NULL $csp_directives['report-uri'] = $csp_report_uri; } $output = array(); $domain = NULL; foreach ($csp_directives as $directive => $value) { if ($value !== NULL) { if (is_array($value)) { foreach ($value as $k => $v) { if (str_starts_with($v, '/')) { if (!$domain) { $domain = ($GLOBALS['tplHttpsUsed'] ? 'https://' : 'http://') . $GLOBALS['webHost']; } $value[$k] = $domain . $v; } } $value = implode(' ', $value); } if ($value == '') { $output[] = $directive . " 'none'"; } else { $output[] = $directive . ' ' . str_replace('"', "'", $value); } } } if ($GLOBALS['tplHttpsUsed']) { $output[] = 'block-all-mixed-content'; } //-------------------------------------------------- // Send CSP header($header . ': ' . head(implode('; ', $output))); if (extension_loaded('newrelic')) { newrelic_disable_autorum(); } //-------------------------------------------------- // Cookies require_once(ROOT . '/a/php/cookie.php'); //-------------------------------------------------- // Set location variables function setLocationVariables($scriptFilePath) { //-------------------------------------------------- // Generate an organised folder array based on // the current page the website visitor is // viewing. The human version takes the name // out of camel notation (spaces). $GLOBALS['tplFolder'] = str_replace('\\', '/', realpath($scriptFilePath)); $GLOBALS['tplFolder'] = preg_replace('/^' . preg_quote(ROOT, '/') . '\/?(([^\/]*\/)*).*$/', '\1', $GLOBALS['tplFolder']); $GLOBALS['tplFolder'] = explode('/', $GLOBALS['tplFolder']); $GLOBALS['tplFolder'] = array_pad($GLOBALS['tplFolder'], 3, ''); $GLOBALS['tplFolderHuman'] = array(); foreach ($GLOBALS['tplFolder'] as $f) { $GLOBALS['tplFolderHuman'][] = ucfirst(preg_replace('/([a-z])([A-Z])/', '\1 \2', $f)); } //-------------------------------------------------- // Generate the page ID for the body tag and // any scripts which require it $GLOBALS['tplPageId'] = ''; foreach ($GLOBALS['tplFolder'] as $f) { $GLOBALS['tplPageId'] .= ucfirst($f); } if ($GLOBALS['tplPageId'] == '') { $GLOBALS['tplPageId'] = 'Home'; } $GLOBALS['tplPageId'] = 'p' . $GLOBALS['tplPageId']; //-------------------------------------------------- // Generate the page title $GLOBALS['tplPageTitle'] = implode(' | ', $GLOBALS['tplFolderHuman']); $GLOBALS['tplPageTitle'] = preg_replace('/^[ \|]*(.*?)[ \|]*$/', '\1', $GLOBALS['tplPageTitle']); if ($GLOBALS['tplPageTitle'] != '') { $GLOBALS['tplPageTitle'] = ' | ' . $GLOBALS['tplPageTitle']; } } if (!$GLOBALS['useUrlRewrite']) { setLocationVariables($_SERVER['SCRIPT_FILENAME']); } //-------------------------------------------------- // Return submitted values function returnSubmittedValue($variable, $method = 'request', $validation = 0) { //-------------------------------------------------- // Get value $value = ''; $method = strtolower($method); if ($method == 'post') { if (isset($_POST[$variable])) { $value = $_POST[$variable]; } } elseif ($method == 'cookie') { if (isset($_COOKIE[$variable])) { $value = $_COOKIE[$variable]; } } elseif ($method == 'request') { if (isset($_REQUEST[$variable])) { $value = $_REQUEST[$variable]; } } else { if (isset($_GET[$variable])) { $value = $_GET[$variable]; } } //-------------------------------------------------- // Remove bad characters if ($GLOBALS['pageCharset'] == 'ISO-8859-1') { $badCharacters = array(chr(145), chr(146), chr(147), chr(148), chr(150), chr(151)); $goodCharacters = array("'", "'", '"', '"', '-', '--'); $value = str_replace($badCharacters, $goodCharacters, $value); } //-------------------------------------------------- // Strip slashes (IF NESS) if (ini_get('magic_quotes_gpc')) { $value = stripslashesdeep($value); } //-------------------------------------------------- // Validation + string manipulation if ($validation & 1) $value = trim($value); if ($validation & 2) $value = strip_tags($value); if ($validation & 4) $value = strtolower($value); if ($validation & 8) $value = intval($value); //-------------------------------------------------- // Return value return $value; } //-------------------------------------------------- // Check that an email address is valid function isemail($email) { if (preg_match('/^\w[-.+\'\w]*@(\w[-._\w]*\.[a-zA-Z]{2,})$/', $email, $matches)) { if (function_exists('checkdnsrr')) { if (checkdnsrr($matches[1] . '.', 'MX')) return true; // If a 'mail exchange' record exists if (checkdnsrr($matches[1] . '.', 'A')) return true; // Mail servers can fall back on 'A' records } else { return true; // For Windows } } return false; } //-------------------------------------------------- // Take a postcode and format it correctly, an // invalid postcode will return NULL function formatBritishPostcode($postcode) { //-------------------------------------------------- // Clean up the user input $postcode = strtoupper($postcode); $postcode = preg_replace('/[^A-Z0-9]/', '', $postcode); $postcode = preg_replace('/([A-Z0-9]{3})$/', ' \1', $postcode); $postcode = trim($postcode); //-------------------------------------------------- // Check that the submitted value is a valid // British postcode: AN NAA | ANN NAA | AAN NAA | // AANN NAA | ANA NAA | AANA NAA if (preg_match('/^[a-z](\d[a-z\d]?|[a-z]\d[a-z\d]?) \d[a-z]{2}$/i', $postcode)) { return $postcode; } else { return NULL; } } //-------------------------------------------------- // A recursive function for running stripslashes // on all items of a variable / array. function stripslashesdeep($value) { return (is_array($value) ? array_map('stripslashesdeep', $value) : stripslashes($value)); } //-------------------------------------------------- // Quick functions used to convert text into a safe // form of HTML/XML/CSV without having to write the // full native function in the script. function html($text) { // if ($GLOBALS['pageCharset'] == 'UTF-8') { // $current = mb_detect_encoding($text, 'UTF-8, ISO-8859-1'); // if ($current != $charset) { // $text = mb_convert_encoding($text, $GLOBALS['pageCharset'], $current); // } // } return htmlspecialchars($text, ENT_QUOTES, $GLOBALS['pageCharset']); } function htmlDecode($text) { return html_entity_decode($text, ENT_QUOTES, $GLOBALS['pageCharset']); } function xml($text) { $text = str_replace('&', '&', $text); $text = str_replace('"', '"', $text); $text = str_replace("'", ''', $text); $text = str_replace('>', '>', $text); $text = str_replace('<', '<', $text); return $text; } function csv($text) { return str_replace('"', '""', $text); } function head($text) { return preg_replace('/(\r|\n)/', '', $text); } //-------------------------------------------------- // A two quick text formatting function which // converts camel notation text into or from human function camel2human($text) { return ucfirst(preg_replace('/([a-z])([A-Z])/', '\1 \2', $text)); } function human2camel($text) { $text = ucwords(strtolower($text)); $text = preg_replace('/[^a-zA-Z0-9]/', '', $text); if (strlen($text) > 0) { // Min of 1 char $text[0] = strtolower($text[0]); } return $text; } //-------------------------------------------------- // Convert a UNIX time-stamp into human text function unix2human($unix) { //-------------------------------------------------- // Maths $sec = $unix % 60; $unix -= $sec; $minSeconds = $unix % 3600; $unix -= $minSeconds; $min = ($minSeconds / 60); $hourSeconds = $unix % 86400; $unix -= $hourSeconds; $hour = ($hourSeconds / 3600); $daySeconds = $unix % 604800; $unix -= $daySeconds; $day = ($daySeconds / 86400); $week = ($unix / 604800); //-------------------------------------------------- // Text $output = ''; if ($week > 0) $output .= ', ' . $week . ' week' . ($week != 1 ? 's' : ''); if ($day > 0) $output .= ', ' . $day . ' day' . ($day != 1 ? 's' : ''); if ($hour > 0) $output .= ', ' . $hour . ' hour' . ($hour != 1 ? 's' : ''); if ($min > 0) $output .= ', ' . $min . ' minute' . ($min != 1 ? 's' : ''); if ($sec > 0 || $output == '') { $output .= ', ' . $sec . ' second' . ($sec != 1 ? 's' : ''); } //-------------------------------------------------- // Grammar $output = substr($output, 2); $output = preg_replace('/, ([^,]+)$/', ' and $1', $output); //-------------------------------------------------- // Return the output return $output; } //-------------------------------------------------- // Function to convert a file-size into something // human readable function fileSize2human($size) { $units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'); foreach ($units as $unit) { if ($size >= 1024 && $unit != 'YB') { $size = ($size / 1024); } else { return round($size, 0) . $unit; } } } //-------------------------------------------------- // Function to send the user onto another page. // This takes into IE6 into consideration when // redirecting from a HTTPS connection to the // standard HTTP function redirect($url, $httpResponseCode = 302) { $htmlNext = '

Goto next page

'; if (isset($GLOBALS['createDebugOutput']) && $GLOBALS['createDebugOutput'] && ob_get_length() > 0) { ob_end_flush(); exit($htmlNext); } if ($GLOBALS['tplHttpsUsed'] && substr($url, 0, 7) == 'http://') { if (isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 6') !== false) { header('Refresh: 0; URL=' . head($url)); exit('

Loading...

'); } } header('Location: ' . head($url), true, $httpResponseCode); exit($htmlNext); } //-------------------------------------------------- // Function to cut a string to X words, function cutStringLength($text, $words) { $text = strip_tags($text); $text = explode(' ', $text, $words + 1); if (count($text) > $words) { $dumpData = array_pop($text); } return implode(' ', $text); } //-------------------------------------------------- // Random key, which is URL safe, using a base 58 // value (base64url does exist by using slashes and // hyphens, but special characters can raise a // usability problem, as well as mixing 0, O, I and l. function random_key($length) { // https://stackoverflow.com/q/24515903/generating-random-characters-for-a-url-in-php $key = ''; do { $input = array( getmypid(), // Process IDs are not unique, so a weak entropy source (not secure). uniqid('', true), // Based on the current time in microseconds (not secure). mt_rand(), // Mersenne Twister pseudorandom number generator (not secure). lcg_value(), // Combined linear congruential generator (not secure). (isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : ''), (isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : ''), ); if (function_exists('openssl_random_pseudo_bytes')) { $input[] = openssl_random_pseudo_bytes($length); // Second argument shows if strong (or not), and it might not always be random (https://wiki.openssl.org/index.php/Random_fork-safety and https://github.com/paragonie/random_compat/issues/96) } if (function_exists('mcrypt_create_iv')) { $input[] = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM); // PHP 5.6 defaults to /dev/random due to low entropy on some servers (e.g Amazon EC2 servers can take over 1 minute). } $input = implode('', $input); // Many different sources of entropy, the more the better (even if predictable or broken). $input = hash('sha256', $input, true); // 256 bits of raw binary output, not in hexadecimal (a base 16 system, using [0-9a-f]). $input = base64_encode($input); // Use printable characters, as a base64 system. $input = str_replace(array('0', 'O', 'I', 'l', '/', '+'), '', $input); // Make URL safe (base58), and avoid similar looking characters. $input = preg_replace('/[^a-zA-Z0-9]/', '', $input); // Make sure we don't have bad characters (e.g. "="). $key .= $input; } while (strlen($key) < $length); $key = substr($key, 0, $length); if (strlen($key) != $length) { exit_with_error('Cannot create a key of ' . $length . ' characters (' . $key . ')'); } else if (preg_match('/[^a-zA-Z0-9]/', $key)) { exit_with_error('Invalid characters detected in key "' . $key . '"'); } return $key; } //-------------------------------------------------- // Replace a variable in a URL function urlReplaceVariable($variable, $value = NULL, $url = NULL) { //-------------------------------------------------- // Split if ($url === NULL) { $path = (isset($_SERVER['SCRIPT_URL']) ? $_SERVER['SCRIPT_URL'] : ''); $query = (isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : ''); } else { if (($pos = strpos($url, '?')) !== false) { $path = substr($url, 0, $pos); $query = substr($url, ($pos + 1)); } else { $path = $url; $query = ''; } } //-------------------------------------------------- // Remove or replace variable if (preg_match('/(.*)(^|&)' . preg_quote($variable, '/') . '=[^&]*(&|$)(.*)/', $query, $m)) { if ($value !== NULL) { $query = $m[1] . $m[2] . $variable . '=' . urlencode($value) . $m[3] . $m[4]; } else { $query = $m[1] . ($m[1] != '' && $m[4] != '' ? $m[2] : '') . ($m[1] != '' && $m[2] == '' && $m[4] != '' ? $m[3] : '') . $m[4]; } } else if ($value !== NULL) { $query .= ($query == '' ? '' : '&') . $variable . '=' . urlencode($value); } //-------------------------------------------------- // Return return $path . ($query == '' ? '' : '?') . $query; } //-------------------------------------------------- // Database if (is_file(ROOT . '/a/php/database.php')) { require_once(ROOT . '/a/php/database.php'); if (isset($GLOBALS['dbHost'])) { // Some sites might not have the db config yet. $db = new db($GLOBALS['dbHost'], $GLOBALS['dbUser'], $GLOBALS['dbPass'], $GLOBALS['dbName']); $GLOBALS['db'] =& $db; // Effectively does nothing, but shows where the GLOBALS is set in a site wide-search and replace } } //-------------------------------------------------- // Error if (is_file(ROOT . '/a/php/error.php')) { require_once(ROOT . '/a/php/error.php'); } //-------------------------------------------------- // Debug if (isset($GLOBALS['createDebugOutput']) && $GLOBALS['createDebugOutput']) { require_once(ROOT . '/a/php/debug.php'); } //-------------------------------------------------- // System - site specific functions if (is_file(ROOT . '/a/php/system.php')) { require_once(ROOT . '/a/php/system.php'); } ?>