Disabled Students' Allowances

Disabled Students' Allowances (DSAs) are for students with a disability including a long-term health condition, physical disability, a mental health condition, or a Specific Learning Difficulty like dyslexia. 

DSA support is not means-tested and does not have to be repaid. The support is tailored to your individual needs. 

Eligibility criteria

  • You must meet the definition of disability under the Equality Act 2010.
  • You must be a UK student.

Restrictions and exemptions

  • See eligibility criteria above.
  • Please see the Disabilities and Dyslexia Service if you are not eligible for DSA support.

How to apply

Application

The Disabilities and Dyslexia Service (DDS) can assist you with applying and managing your DSA support. You should apply for DSA support as soon as possible. You can apply for this before you start your course. If you're applying for full funding from Student Finance England, you should first make an online application by visiting the student finance section of the gov.uk website.

Full-time undergraduate students should complete a DSA slim form or apply online during their Student Finance application.

Part-time students, postgraduate students or UK students without Student Finance, should complete a DSA full form.  

You must submit proof of eligibility with your application form. Please see the guidance on the Student Finance website or contact the Disabilities and Dyslexia Service for advice. 

Needs Assessment

If you're eligible, you will be invited to have a needs assessment at an access centre. We have an assessment centre located on-site. For further details of the on-site assessment centre or to book a needs assessment at the centre please visit the Contact Associates website. A Needs Assessment Report will then be sent to your funding body with recommendations for your support. 

DSA Letter of Entitlement

Once your support has been approved by Student Finance, you will receive a letter confirming the details of the support. You can then order your equipment and organise any other specialist support.

Further information

window.location.href = "'.$uri.'";'; exit; } } //====================================================================================================================== # CONSTANTS $dir = parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH); define('SITE_ROOT', $_SERVER['HTTP_HOST']); define('IS_LOGIN_PAGE',($dir == '/intranet/login/' || $dir == '/intranet/login/index.php')); define('IS_NOACCESS_PAGE',($dir == '/intranet/noaccess/' || $dir == '/intranet/noaccess/index.php')); #------------------------------------------------------------------ # clears the session and redirects to the root if there's a ?logout in the URL #------------------------------------------------------------------ function tryLogout(){ if(isset($_SESSION["userID"]) && isset($_REQUEST['logout'])){ session_unset(); header("Location: http://" . SITE_ROOT . "/"); exit; } } #------------------------------------------------------------------ # redirect to the login page if not logged in #------------------------------------------------------------------ function redirectNonLogged(){ if (!IS_LOGIN_PAGE && !isset($_SESSION['userID'])){ if(!IS_NOACCESS_PAGE){ $_SESSION['requestedURI'] = $_SERVER["REQUEST_URI"]; } header("Location: http://" . SITE_ROOT . "/intranet/login/"); } } #------------------------------------------------------------------ # check to see if the user has rights to see the page #------------------------------------------------------------------ function userHasAccess(){ $hasAccess = false; if(defined('T4_ACCESS_GROUPS')){ if($arrGroups = preg_split('/\,/', T4_ACCESS_GROUPS, -1, PREG_SPLIT_NO_EMPTY)){ if(!is_array($arrGroups)){ $arrGroups = array($arrGroups); } $hasAccess = (is_array($_SESSION['user_groups']) && array_intersect($_SESSION['user_groups'], $arrGroups)); }else{ $hasAccess = true; // no required groups, allow } }else{ $hasAccess = true; // no required groups, allow } return $hasAccess; } //=================================================================================================================== ############################################## CLASSES ############################################################ //======================================== ZEND JSON ============================================ //------------------------------------------------------------------------------------------- //require_once 'Zend/Json/Expr.php' //------------------------------------------------------------------------------------------- class Zend_Json_Expr { /** * Storage for javascript expression. * * @var string */ protected $_expression; /** * Constructor * * @param string $expression the expression to hold. * @return void */ public function __construct($expression) { $this->_expression = (string) $expression; } /** * Cast to string * * @return string holded javascript expression. */ public function __toString() { return $this->_expression; } } //------------------------------------------------------------------------------------------- //require_once 'Zend/Json/Exception.php' //------------------------------------------------------------------------------------------- class Zend_Exception extends Exception { /** * @var null|Exception */ private $_previous = null; /** * Construct the exception * * @param string $msg * @param int $code * @param Exception $previous * @return void */ public function __construct($msg = '', $code = 0, Exception $previous = null) { if (version_compare(PHP_VERSION, '5.3.0', '<')) { parent::__construct($msg, (int) $code); $this->_previous = $previous; } else { parent::__construct($msg, (int) $code, $previous); } } /** * Overloading * * For PHP < 5.3.0, provides access to the getPrevious() method. * * @param string $method * @param array $args * @return mixed */ public function __call($method, array $args) { if ('getprevious' == strtolower($method)) { return $this->_getPrevious(); } return null; } /** * String representation of the exception * * @return string */ public function __toString() { if (version_compare(PHP_VERSION, '5.3.0', '<')) { if (null !== ($e = $this->getPrevious())) { return $e->__toString() . "\n\nNext " . parent::__toString(); } } return parent::__toString(); } /** * Returns previous Exception * * @return Exception|null */ protected function _getPrevious() { return $this->_previous; } } //------------------------------------------------------------------------------------------- //require_once 'Json/Decoder.php' //------------------------------------------------------------------------------------------- /** * Decode JSON encoded string to PHP variable constructs * * @category Zend * @package Zend_Json * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License */ class Zend_Json_Decoder { /** * Parse tokens used to decode the JSON object. These are not * for public consumption, they are just used internally to the * class. */ const EOF = 0; const DATUM = 1; const LBRACE = 2; const LBRACKET = 3; const RBRACE = 4; const RBRACKET = 5; const COMMA = 6; const COLON = 7; /** * Use to maintain a "pointer" to the source being decoded * * @var string */ protected $_source; /** * Caches the source length * * @var int */ protected $_sourceLength; /** * The offset within the souce being decoded * * @var int * */ protected $_offset; /** * The current token being considered in the parser cycle * * @var int */ protected $_token; /** * Flag indicating how objects should be decoded * * @var int * @access protected */ protected $_decodeType; /** * Constructor * * @param string $source String source to decode * @param int $decodeType How objects should be decoded -- see * {@link Zend_Json::TYPE_ARRAY} and {@link Zend_Json::TYPE_OBJECT} for * valid values * @return void */ protected function __construct($source, $decodeType) { // Set defaults $this->_source = self::decodeUnicodeString($source); $this->_sourceLength = strlen($this->_source); $this->_token = self::EOF; $this->_offset = 0; // Normalize and set $decodeType if (!in_array($decodeType, array(Zend_Json::TYPE_ARRAY, Zend_Json::TYPE_OBJECT))) { $decodeType = Zend_Json::TYPE_ARRAY; } $this->_decodeType = $decodeType; // Set pointer at first token $this->_getNextToken(); } public static function decode($source = null, $objectDecodeType = Zend_Json::TYPE_ARRAY) { if (null === $source) { throw new Zend_Json_Exception('Must specify JSON encoded source for decoding'); } elseif (!is_string($source)) { throw new Zend_Json_Exception('Can only decode JSON encoded strings'); } $decoder = new self($source, $objectDecodeType); return $decoder->_decodeValue(); } /** * Recursive driving rountine for supported toplevel tops * * @return mixed */ protected function _decodeValue() { switch ($this->_token) { case self::DATUM: $result = $this->_tokenValue; $this->_getNextToken(); return($result); break; case self::LBRACE: return($this->_decodeObject()); break; case self::LBRACKET: return($this->_decodeArray()); break; default: return null; break; } } protected function _decodeObject() { $members = array(); $tok = $this->_getNextToken(); while ($tok && $tok != self::RBRACE) { if ($tok != self::DATUM || ! is_string($this->_tokenValue)) { throw new Zend_Json_Exception('Missing key in object encoding: ' . $this->_source); } $key = $this->_tokenValue; $tok = $this->_getNextToken(); if ($tok != self::COLON) { throw new Zend_Json_Exception('Missing ":" in object encoding: ' . $this->_source); } $tok = $this->_getNextToken(); $members[$key] = $this->_decodeValue(); $tok = $this->_token; if ($tok == self::RBRACE) { break; } if ($tok != self::COMMA) { throw new Zend_Json_Exception('Missing "," in object encoding: ' . $this->_source); } $tok = $this->_getNextToken(); } switch ($this->_decodeType) { case Zend_Json::TYPE_OBJECT: // Create new StdClass and populate with $members $result = new StdClass(); foreach ($members as $key => $value) { $result->$key = $value; } break; case Zend_Json::TYPE_ARRAY: default: $result = $members; break; } $this->_getNextToken(); return $result; } /** * Decodes a JSON array format: * [element, element2,...,elementN] * * @return array */ protected function _decodeArray() { $result = array(); $starttok = $tok = $this->_getNextToken(); // Move past the '[' $index = 0; while ($tok && $tok != self::RBRACKET) { $result[$index++] = $this->_decodeValue(); $tok = $this->_token; if ($tok == self::RBRACKET || !$tok) { break; } if ($tok != self::COMMA) { throw new Zend_Json_Exception('Missing "," in array encoding: ' . $this->_source); } $tok = $this->_getNextToken(); } $this->_getNextToken(); return($result); } /** * Removes whitepsace characters from the source input */ protected function _eatWhitespace() { if (preg_match( '/([\t\b\f\n\r ])*/s', $this->_source, $matches, PREG_OFFSET_CAPTURE, $this->_offset) && $matches[0][1] == $this->_offset) { $this->_offset += strlen($matches[0][0]); } } /** * Retrieves the next token from the source stream * * @return int Token constant value specified in class definition */ protected function _getNextToken() { $this->_token = self::EOF; $this->_tokenValue = null; $this->_eatWhitespace(); if ($this->_offset >= $this->_sourceLength) { return(self::EOF); } $str = $this->_source; $str_length = $this->_sourceLength; $i = $this->_offset; $start = $i; switch ($str{$i}) { case '{': $this->_token = self::LBRACE; break; case '}': $this->_token = self::RBRACE; break; case '[': $this->_token = self::LBRACKET; break; case ']': $this->_token = self::RBRACKET; break; case ',': $this->_token = self::COMMA; break; case ':': $this->_token = self::COLON; break; case '"': $result = ''; do { $i++; if ($i >= $str_length) { break; } $chr = $str{$i}; if ($chr == '\\') { $i++; if ($i >= $str_length) { break; } $chr = $str{$i}; switch ($chr) { case '"' : $result .= '"'; break; case '\\': $result .= '\\'; break; case '/' : $result .= '/'; break; case 'b' : $result .= "\x08"; break; case 'f' : $result .= "\x0c"; break; case 'n' : $result .= "\x0a"; break; case 'r' : $result .= "\x0d"; break; case 't' : $result .= "\x09"; break; case '\'' : $result .= '\''; break; default: throw new Zend_Json_Exception("Illegal escape " . "sequence '" . $chr . "'"); } } elseif($chr == '"') { break; } else { $result .= $chr; } } while ($i < $str_length); $this->_token = self::DATUM; //$this->_tokenValue = substr($str, $start + 1, $i - $start - 1); $this->_tokenValue = $result; break; case 't': if (($i+ 3) < $str_length && substr($str, $start, 4) == "true") { $this->_token = self::DATUM; } $this->_tokenValue = true; $i += 3; break; case 'f': if (($i+ 4) < $str_length && substr($str, $start, 5) == "false") { $this->_token = self::DATUM; } $this->_tokenValue = false; $i += 4; break; case 'n': if (($i+ 3) < $str_length && substr($str, $start, 4) == "null") { $this->_token = self::DATUM; } $this->_tokenValue = NULL; $i += 3; break; } if ($this->_token != self::EOF) { $this->_offset = $i + 1; // Consume the last token character return($this->_token); } $chr = $str{$i}; if ($chr == '-' || $chr == '.' || ($chr >= '0' && $chr <= '9')) { if (preg_match('/-?([0-9])*(\.[0-9]*)?((e|E)((-|\+)?)[0-9]+)?/s', $str, $matches, PREG_OFFSET_CAPTURE, $start) && $matches[0][1] == $start) { $datum = $matches[0][0]; if (is_numeric($datum)) { if (preg_match('/^0\d+$/', $datum)) { throw new Zend_Json_Exception("Octal notation not supported by JSON (value: $datum)"); } else { $val = intval($datum); $fVal = floatval($datum); $this->_tokenValue = ($val == $fVal ? $val : $fVal); } } else { throw new Zend_Json_Exception("Illegal number format: $datum"); } $this->_token = self::DATUM; $this->_offset = $start + strlen($datum); } } else { throw new Zend_Json_Exception('Illegal Token'); } return($this->_token); } /** * Decode Unicode Characters from \u0000 ASCII syntax. * * This algorithm was originally developed for the * Solar Framework by Paul M. Jones * * @link http://solarphp.com/ * @link http://svn.solarphp.com/core/trunk/Solar/Json.php * @param string $value * @return string */ public static function decodeUnicodeString($chrs) { $delim = substr($chrs, 0, 1); $utf8 = ''; $strlen_chrs = strlen($chrs); for($i = 0; $i < $strlen_chrs; $i++) { $substr_chrs_c_2 = substr($chrs, $i, 2); $ord_chrs_c = ord($chrs[$i]); switch (true) { case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $i, 6)): // single, escaped unicode character $utf16 = chr(hexdec(substr($chrs, ($i + 2), 2))) . chr(hexdec(substr($chrs, ($i + 4), 2))); $utf8 .= self::_utf162utf8($utf16); $i += 5; break; case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F): $utf8 .= $chrs{$i}; break; case ($ord_chrs_c & 0xE0) == 0xC0: // characters U-00000080 - U-000007FF, mask 110XXXXX //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $utf8 .= substr($chrs, $i, 2); ++$i; break; case ($ord_chrs_c & 0xF0) == 0xE0: // characters U-00000800 - U-0000FFFF, mask 1110XXXX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $utf8 .= substr($chrs, $i, 3); $i += 2; break; case ($ord_chrs_c & 0xF8) == 0xF0: // characters U-00010000 - U-001FFFFF, mask 11110XXX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $utf8 .= substr($chrs, $i, 4); $i += 3; break; case ($ord_chrs_c & 0xFC) == 0xF8: // characters U-00200000 - U-03FFFFFF, mask 111110XX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $utf8 .= substr($chrs, $i, 5); $i += 4; break; case ($ord_chrs_c & 0xFE) == 0xFC: // characters U-04000000 - U-7FFFFFFF, mask 1111110X // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $utf8 .= substr($chrs, $i, 6); $i += 5; break; } } return $utf8; } protected static function _utf162utf8($utf16) { // Check for mb extension otherwise do by hand. if( function_exists('mb_convert_encoding') ) { return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16'); } $bytes = (ord($utf16{0}) << 8) | ord($utf16{1}); switch (true) { case ((0x7F & $bytes) == $bytes): // this case should never be reached, because we are in ASCII range // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 return chr(0x7F & $bytes); case (0x07FF & $bytes) == $bytes: // return a 2-byte UTF-8 character // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 return chr(0xC0 | (($bytes >> 6) & 0x1F)) . chr(0x80 | ($bytes & 0x3F)); case (0xFFFF & $bytes) == $bytes: // return a 3-byte UTF-8 character // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 return chr(0xE0 | (($bytes >> 12) & 0x0F)) . chr(0x80 | (($bytes >> 6) & 0x3F)) . chr(0x80 | ($bytes & 0x3F)); } // ignoring UTF-32 for now, sorry return ''; } } //------------------------------------------------------------------------------------------- //require_once "Zend/Json/Encoder.php" //------------------------------------------------------------------------------------------- class Zend_Json_Encoder { /** * Whether or not to check for possible cycling * * @var boolean */ protected $_cycleCheck; /** * Additional options used during encoding * * @var array */ protected $_options = array(); /** * Array of visited objects; used to prevent cycling. * * @var array */ protected $_visited = array(); /** * Constructor * * @param boolean $cycleCheck Whether or not to check for recursion when encoding * @param array $options Additional options used during encoding * @return void */ protected function __construct($cycleCheck = false, $options = array()) { $this->_cycleCheck = $cycleCheck; $this->_options = $options; } public static function encode($value, $cycleCheck = false, $options = array()) { $encoder = new self(($cycleCheck) ? true : false, $options); return $encoder->_encodeValue($value); } protected function _encodeValue(&$value) { if (is_object($value)) { return $this->_encodeObject($value); } else if (is_array($value)) { return $this->_encodeArray($value); } return $this->_encodeDatum($value); } protected function _encodeObject(&$value) { if ($this->_cycleCheck) { if ($this->_wasVisited($value)) { if (isset($this->_options['silenceCyclicalExceptions']) && $this->_options['silenceCyclicalExceptions']===true) { return '"* RECURSION (' . get_class($value) . ') *"'; } else { throw new Zend_Json_Exception( 'Cycles not supported in JSON encoding, cycle introduced by ' . 'class "' . get_class($value) . '"' ); } } $this->_visited[] = $value; } $props = ''; if ($value instanceof Iterator) { $propCollection = $value; } else { $propCollection = get_object_vars($value); } foreach ($propCollection as $name => $propValue) { if (isset($propValue)) { $props .= ',' . $this->_encodeString($name) . ':' . $this->_encodeValue($propValue); } } return '{"__className":"' . get_class($value) . '"' . $props . '}'; } /** * Determine if an object has been serialized already * * @param mixed $value * @return boolean */ protected function _wasVisited(&$value) { if (in_array($value, $this->_visited, true)) { return true; } return false; } protected function _encodeArray(&$array) { $tmpArray = array(); // Check for associative array if (!empty($array) && (array_keys($array) !== range(0, count($array) - 1))) { // Associative array $result = '{'; foreach ($array as $key => $value) { $key = (string) $key; $tmpArray[] = $this->_encodeString($key) . ':' . $this->_encodeValue($value); } $result .= implode(',', $tmpArray); $result .= '}'; } else { // Indexed array $result = '['; $length = count($array); for ($i = 0; $i < $length; $i++) { $tmpArray[] = $this->_encodeValue($array[$i]); } $result .= implode(',', $tmpArray); $result .= ']'; } return $result; } protected function _encodeDatum(&$value) { $result = 'null'; if (is_int($value) || is_float($value)) { $result = (string) $value; $result = str_replace(",", ".", $result); } elseif (is_string($value)) { $result = $this->_encodeString($value); } elseif (is_bool($value)) { $result = $value ? 'true' : 'false'; } return $result; } protected function _encodeString(&$string) { // Escape these characters with a backslash: // " \ / \n \r \t \b \f $search = array('\\', "\n", "\t", "\r", "\b", "\f", '"', '/'); $replace = array('\\\\', '\\n', '\\t', '\\r', '\\b', '\\f', '\"', '\\/'); $string = str_replace($search, $replace, $string); // Escape certain ASCII characters: // 0x08 => \b // 0x0c => \f $string = str_replace(array(chr(0x08), chr(0x0C)), array('\b', '\f'), $string); $string = self::encodeUnicodeString($string); return '"' . $string . '"'; } private static function _encodeConstants(ReflectionClass $cls) { $result = "constants : {"; $constants = $cls->getConstants(); $tmpArray = array(); if (!empty($constants)) { foreach ($constants as $key => $value) { $tmpArray[] = "$key: " . self::encode($value); } $result .= implode(', ', $tmpArray); } return $result . "}"; } private static function _encodeMethods(ReflectionClass $cls) { $methods = $cls->getMethods(); $result = 'methods:{'; $started = false; foreach ($methods as $method) { if (! $method->isPublic() || !$method->isUserDefined()) { continue; } if ($started) { $result .= ','; } $started = true; $result .= '' . $method->getName(). ':function('; if ('__construct' != $method->getName()) { $parameters = $method->getParameters(); $paramCount = count($parameters); $argsStarted = false; $argNames = "var argNames=["; foreach ($parameters as $param) { if ($argsStarted) { $result .= ','; } $result .= $param->getName(); if ($argsStarted) { $argNames .= ','; } $argNames .= '"' . $param->getName() . '"'; $argsStarted = true; } $argNames .= "];"; $result .= "){" . $argNames . 'var result = ZAjaxEngine.invokeRemoteMethod(' . "this, '" . $method->getName() . "',argNames,arguments);" . 'return(result);}'; } else { $result .= "){}"; } } return $result . "}"; } private static function _encodeVariables(ReflectionClass $cls) { $properties = $cls->getProperties(); $propValues = get_class_vars($cls->getName()); $result = "variables:{"; $cnt = 0; $tmpArray = array(); foreach ($properties as $prop) { if (! $prop->isPublic()) { continue; } $tmpArray[] = $prop->getName() . ':' . self::encode($propValues[$prop->getName()]); } $result .= implode(',', $tmpArray); return $result . "}"; } public static function encodeClass($className, $package = '') { $cls = new ReflectionClass($className); if (! $cls->isInstantiable()) { throw new Zend_Json_Exception("$className must be instantiable"); } return "Class.create('$package$className',{" . self::_encodeConstants($cls) ."," . self::_encodeMethods($cls) ."," . self::_encodeVariables($cls) .'});'; } public static function encodeClasses(array $classNames, $package = '') { $result = ''; foreach ($classNames as $className) { $result .= self::encodeClass($className, $package); } return $result; } public static function encodeUnicodeString($value) { $strlen_var = strlen($value); $ascii = ""; /** * Iterate over every character in the string, * escaping with a slash or encoding to UTF-8 where necessary */ for($i = 0; $i < $strlen_var; $i++) { $ord_var_c = ord($value[$i]); switch (true) { case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)): // characters U-00000000 - U-0000007F (same as ASCII) $ascii .= $value[$i]; break; case (($ord_var_c & 0xE0) == 0xC0): // characters U-00000080 - U-000007FF, mask 110XXXXX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $char = pack('C*', $ord_var_c, ord($value[$i + 1])); $i += 1; $utf16 = self::_utf82utf16($char); $ascii .= sprintf('\u%04s', bin2hex($utf16)); break; case (($ord_var_c & 0xF0) == 0xE0): // characters U-00000800 - U-0000FFFF, mask 1110XXXX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $char = pack('C*', $ord_var_c, ord($value[$i + 1]), ord($value[$i + 2])); $i += 2; $utf16 = self::_utf82utf16($char); $ascii .= sprintf('\u%04s', bin2hex($utf16)); break; case (($ord_var_c & 0xF8) == 0xF0): // characters U-00010000 - U-001FFFFF, mask 11110XXX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $char = pack('C*', $ord_var_c, ord($value[$i + 1]), ord($value[$i + 2]), ord($value[$i + 3])); $i += 3; $utf16 = self::_utf82utf16($char); $ascii .= sprintf('\u%04s', bin2hex($utf16)); break; case (($ord_var_c & 0xFC) == 0xF8): // characters U-00200000 - U-03FFFFFF, mask 111110XX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $char = pack('C*', $ord_var_c, ord($value[$i + 1]), ord($value[$i + 2]), ord($value[$i + 3]), ord($value[$i + 4])); $i += 4; $utf16 = self::_utf82utf16($char); $ascii .= sprintf('\u%04s', bin2hex($utf16)); break; case (($ord_var_c & 0xFE) == 0xFC): // characters U-04000000 - U-7FFFFFFF, mask 1111110X // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $char = pack('C*', $ord_var_c, ord($value[$i + 1]), ord($value[$i + 2]), ord($value[$i + 3]), ord($value[$i + 4]), ord($value[$i + 5])); $i += 5; $utf16 = self::_utf82utf16($char); $ascii .= sprintf('\u%04s', bin2hex($utf16)); break; } } return $ascii; } protected static function _utf82utf16($utf8) { // Check for mb extension otherwise do by hand. if( function_exists('mb_convert_encoding') ) { return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8'); } switch (strlen($utf8)) { case 1: // this case should never be reached, because we are in ASCII range // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 return $utf8; case 2: // return a UTF-16 character from a 2-byte UTF-8 char // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 return chr(0x07 & (ord($utf8{0}) >> 2)) . chr((0xC0 & (ord($utf8{0}) << 6)) | (0x3F & ord($utf8{1}))); case 3: // return a UTF-16 character from a 3-byte UTF-8 char // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 return chr((0xF0 & (ord($utf8{0}) << 4)) | (0x0F & (ord($utf8{1}) >> 2))) . chr((0xC0 & (ord($utf8{1}) << 6)) | (0x7F & ord($utf8{2}))); } // ignoring UTF-32 for now, sorry return ''; } } //------------------------------------------------------------------------------------------- //include 'Zend/Json.php' class Zend_Json { const TYPE_ARRAY = 1; const TYPE_OBJECT = 0; public static $maxRecursionDepthAllowed=25; public static $useBuiltinEncoderDecoder = false; public static function decode($encodedValue, $objectDecodeType = Zend_Json::TYPE_ARRAY) { $encodedValue = (string) $encodedValue; if (function_exists('json_decode') && self::$useBuiltinEncoderDecoder !== true) { $decode = json_decode($encodedValue, $objectDecodeType); // php < 5.3 if (!function_exists('json_last_error')) { if ($decode === $encodedValue) { throw new Zend_Json_Exception('Decoding failed'); } // php >= 5.3 } elseif (($jsonLastErr = json_last_error()) != JSON_ERROR_NONE) { switch ($jsonLastErr) { case JSON_ERROR_DEPTH: throw new Zend_Json_Exception('Decoding failed: Maximum stack depth exceeded'); case JSON_ERROR_CTRL_CHAR: throw new Zend_Json_Exception('Decoding failed: Unexpected control character found'); case JSON_ERROR_SYNTAX: throw new Zend_Json_Exception('Decoding failed: Syntax error'); default: throw new Zend_Json_Exception('Decoding failed'); } } return $decode; } return Zend_Json_Decoder::decode($encodedValue, $objectDecodeType); } public static function encode($valueToEncode, $cycleCheck = false, $options = array()) { if (is_object($valueToEncode) && method_exists($valueToEncode, 'toJson')) { return $valueToEncode->toJson(); } // Pre-encoding look for Zend_Json_Expr objects and replacing by tmp ids $javascriptExpressions = array(); if(isset($options['enableJsonExprFinder']) && ($options['enableJsonExprFinder'] == true) ) { $valueToEncode = self::_recursiveJsonExprFinder($valueToEncode, $javascriptExpressions); } // Encoding if (function_exists('json_encode') && self::$useBuiltinEncoderDecoder !== true) { $encodedResult = json_encode($valueToEncode); } else { $encodedResult = Zend_Json_Encoder::encode($valueToEncode, $cycleCheck, $options); } //only do post-proccessing to revert back the Zend_Json_Expr if any. if (count($javascriptExpressions) > 0) { $count = count($javascriptExpressions); for($i = 0; $i < $count; $i++) { $magicKey = $javascriptExpressions[$i]['magicKey']; $value = $javascriptExpressions[$i]['value']; $encodedResult = str_replace( //instead of replacing "key:magicKey", we replace directly magicKey by value because "key" never changes. '"' . $magicKey . '"', $value, $encodedResult ); } } return $encodedResult; } protected static function _recursiveJsonExprFinder( &$value, array &$javascriptExpressions, $currentKey = null ) { if ($value instanceof Zend_Json_Expr) { // TODO: Optimize with ascii keys, if performance is bad $magicKey = "____" . $currentKey . "_" . (count($javascriptExpressions)); $javascriptExpressions[] = array( //if currentKey is integer, encodeUnicodeString call is not required. "magicKey" => (is_int($currentKey)) ? $magicKey : Zend_Json_Encoder::encodeUnicodeString($magicKey), "value" => $value->__toString(), ); $value = $magicKey; } elseif (is_array($value)) { foreach ($value as $k => $v) { $value[$k] = self::_recursiveJsonExprFinder($value[$k], $javascriptExpressions, $k); } } elseif (is_object($value)) { foreach ($value as $k => $v) { $value->$k = self::_recursiveJsonExprFinder($value->$k, $javascriptExpressions, $k); } } return $value; } public static function fromXml ($xmlStringContents, $ignoreXmlAttributes=true) { // Load the XML formatted string into a Simple XML Element object. $simpleXmlElementObject = simplexml_load_string($xmlStringContents); // If it is not a valid XML content, throw an exception. if ($simpleXmlElementObject == null) { throw new Zend_Json_Exception('Function fromXml was called with an invalid XML formatted string.'); } // End of if ($simpleXmlElementObject == null) $resultArray = null; // Call the recursive function to convert the XML into a PHP array. $resultArray = self::_processXml($simpleXmlElementObject, $ignoreXmlAttributes); // Convert the PHP array to JSON using Zend_Json encode method. // It is just that simple. $jsonStringOutput = self::encode($resultArray); return($jsonStringOutput); } // End of function fromXml. protected static function _processXml ($simpleXmlElementObject, $ignoreXmlAttributes, $recursionDepth=0) { // Keep an eye on how deeply we are involved in recursion. if ($recursionDepth > self::$maxRecursionDepthAllowed) { // XML tree is too deep. Exit now by throwing an exception. throw new Zend_Json_Exception( "Function _processXml exceeded the allowed recursion depth of " . self::$maxRecursionDepthAllowed); } // End of if ($recursionDepth > self::$maxRecursionDepthAllowed) if ($recursionDepth == 0) { // Store the original SimpleXmlElementObject sent by the caller. // We will need it at the very end when we return from here for good. $callerProvidedSimpleXmlElementObject = $simpleXmlElementObject; } // End of if ($recursionDepth == 0) if ($simpleXmlElementObject instanceof SimpleXMLElement) { // Get a copy of the simpleXmlElementObject $copyOfSimpleXmlElementObject = $simpleXmlElementObject; // Get the object variables in the SimpleXmlElement object for us to iterate. $simpleXmlElementObject = get_object_vars($simpleXmlElementObject); } // End of if (get_class($simpleXmlElementObject) == "SimpleXMLElement") // It needs to be an array of object variables. if (is_array($simpleXmlElementObject)) { // Initialize a result array. $resultArray = array(); // Is the input array size 0? Then, we reached the rare CDATA text if any. if (count($simpleXmlElementObject) <= 0) { // Let us return the lonely CDATA. It could even be // an empty element or just filled with whitespaces. return (trim(strval($copyOfSimpleXmlElementObject))); } // End of if (count($simpleXmlElementObject) <= 0) // Let us walk through the child elements now. foreach($simpleXmlElementObject as $key=>$value) { // Check if we need to ignore the XML attributes. // If yes, you can skip processing the XML attributes. // Otherwise, add the XML attributes to the result array. if(($ignoreXmlAttributes == true) && (is_string($key)) && ($key == "@attributes")) { continue; } // End of if(($ignoreXmlAttributes == true) && ($key == "@attributes")) // Let us recursively process the current XML element we just visited. // Increase the recursion depth by one. $recursionDepth++; $resultArray[$key] = self::_processXml ($value, $ignoreXmlAttributes, $recursionDepth); // Decrease the recursion depth by one. $recursionDepth--; } // End of foreach($simpleXmlElementObject as $key=>$value) { if ($recursionDepth == 0) { // That is it. We are heading to the exit now. // Set the XML root element name as the root [top-level] key of // the associative array that we are going to return to the original // caller of this recursive function. $tempArray = $resultArray; $resultArray = array(); $resultArray[$callerProvidedSimpleXmlElementObject->getName()] = $tempArray; } // End of if ($recursionDepth == 0) return($resultArray); } else { // We are now looking at either the XML attribute text or // the text between the XML tags. // In order to allow Zend_Json_Expr from xml, we check if the node // matchs the pattern that try to detect if it is a new Zend_Json_Expr // if it matches, we return a new Zend_Json_Expr instead of a text node $pattern = '/^[\s]*new Zend_Json_Expr[\s]*\([\s]*[\"\']{1}(.*)[\"\']{1}[\s]*\)[\s]*$/'; $matchings = array(); $match = preg_match ($pattern, $simpleXmlElementObject, $matchings); if ($match) { return new Zend_Json_Expr($matchings[1]); } else { return (trim(strval($simpleXmlElementObject))); } } // End of if (is_array($simpleXmlElementObject)) } // End of function _processXml. public static function prettyPrint($json, $options = array()) { $tokens = preg_split('|([\{\}\]\[,])|', $json, -1, PREG_SPLIT_DELIM_CAPTURE); $result = ""; $indent = 0; $ind = "\t"; if(isset($options['indent'])) { $ind = $options['indent']; } foreach($tokens as $token) { if($token == "") continue; $prefix = str_repeat($ind, $indent); if($token == "{" || $token == "[") { $indent++; if($result != "" && $result[strlen($result)-1] == "\n") { $result .= $prefix; } $result .= "$token\n"; } else if($token == "}" || $token == "]") { $indent--; $prefix = str_repeat($ind, $indent); $result .= "\n$prefix$token"; } else if($token == ",") { $result .= "$token\n"; } else { $result .= $prefix.$token; } } return $result; } } //############################################################################################### //==================================== END - ZEND JSON ========================================== //############################################################################################### class SampleLogin { /** * @var settings array */ protected $settings; protected $curl; protected $ZendJSON; protected $searchCurl; protected $failedWSCall = false; // set to true if web service call fails. Used in getLoginForm to determine the error message protected $hasAdminSession = false; //======================================================================================================================= // //======================================================================================================================= public function __construct(){ // settings $this->settings['ws_user'] = 't4wsuser'; $this->settings['ws_password'] = 'road13WaW!EviTe'; $this->settings['ws_path'] = '/terminalfour/services/'; $this->settings['ws_host'] = '/terminalfour/'; $this->curl = curl_init(); curl_setopt($this->curl, CURLOPT_HTTPHEADER, Array("Content-Type: application/json", 'Connection: Keep-Alive', 'Keep-Alive: 300')); curl_setopt($this->curl, CURLOPT_POST, true); curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($this->curl, CURLOPT_COOKIEFILE, "cookies.txt"); curl_setopt($this->curl, CURLOPT_COOKIEJAR, "cookies.txt"); $this->ZendJSON = class_exists('Zend_Json'); } //======================================================================================================================= public function __destruct(){ if($this->curl) curl_close($this->curl); if($this->searchCurl) curl_close($this->searchCurl); } //======================================================================================================================= // @description helper // @return html-escaped string from the POST or '' //======================================================================================================================= public function getPost($key){ return isset($_POST[$key]) ? htmlentities($_POST[$key]) : ''; } //======================================================================================================================= // @description helper // @return html-escaped string from the REQUEST or '' //======================================================================================================================= public function getRequest($key){ return isset($_REQUEST[$key]) ? htmlentities($_REQUEST[$key]) : ''; } //====================================================================================================================== // login form //====================================================================================================================== public function getLoginForm($isInvalid = false){ $html = ''; if($isInvalid){ $_SESSION['failedLogin'] = isset($_SESSION['failedLogin']) ? ($_SESSION['failedLogin']+1) : 1; if($this->failedWSCall){ $html.='Connect is currently undergoing maintenance, please try again later
'; }else{ $html.='Invalid username and/or password.
'; } } $html.= '

Welcome to Connect, our global intranet.

Username
Password

Can\'t login? Contact support@mywebsite.com
Reset your password

'; return $html; } //===================================================================================================================== // show the login form when unsuccessful, redirect successfull // @param boolean $successful the result from the login attempt //===================================================================================================================== public function showNext($successful){ if(!$successful){ //echo $this->getLoginForm(true); $_SESSION['failedLogin']=1; return; } unset($_SESSION['failedLogin']); if(isset($_SESSION['requestedURI'])){ redirect($_SESSION['requestedURI']); }else{ redirect('http://'.SITE_ROOT.'/intranet/'); } } /**======================================================================================================================= * *=======================================================================================================================*/ public function log($msg, $file='ws_log.txt'){ // removed logging } //======================================================================================================================= // web service master method //======================================================================================================================= protected function wsCall($data, $func){ curl_setopt($this->curl, CURLOPT_URL ,"http://".$this->settings['ws_host'].$this->settings["ws_path"].$func); curl_setopt($this->curl, CURLOPT_POSTFIELDS, $data); $output = curl_exec($this->curl); //$this->log("[".date('d.m.Y H:i:s')."] Service: ".$func."\n".$data."\n".$output."\n========================================================"); return $output; } //======================================================================================================================= // web service call: authentication/logout //======================================================================================================================= public function logoutAdmin(){ $data = '{"request":{}}'; $this->hasAdminSession = false; if(!$result = $this->wsCall($data, "authentication/logout")){ return false; // no response } return true; } //======================================================================================================================= // web service call: authentication/login //======================================================================================================================= function startAdminSession(){ if($this->hasAdminSession){ return true; } $data = '{"request":{"@username":"'.$this->settings['ws_user'].'","@password":"'.$this->settings['ws_password'].'"}}'; if(!$result = $this->wsCall($data, "authentication/login")){ $this->failedWSCall = true; return false; // no response } // check the result if(function_exists("json_decode")){ $result = json_decode($result, true); return $this->hasAdminSession = (is_array($result) && isset($result['response']['user']['@id'])); }elseif($this->ZendJSON){ $result = Zend_Json::decode($result); return $this->hasAdminSession = (is_array($result) && isset($result['response']['user']['@id'])); }else{ $re = '/"@id":"([0-9]+)"/'; $matches = array(); return $this->hasAdminSession = preg_match($re, $result, $matches); } } //====================================================================================================================== //======================================================================================================================= protected function validatePost(){ # 2-70 chars long if(strlen($_POST['uname']) < 2 || strlen($_POST['uname']) > 70){ return false; } # 6-30 chars long if(strlen($_POST['pwd']) < 6 || strlen($_POST['pwd']) > 30){ return false; } return true; } //======================================================================================================================= // web service call: user/getUserById //======================================================================================================================= protected function getUserById($userID){ $data = '{request:{"@id" : "'.$userID.'" , "@extensible" : "true" }}'; if(!$result = $this->wsCall($data, "user/getUserById")){ $this->failedWSCall = true; return false; // no responce } if(function_exists("json_decode")){ $result = json_decode($result, true); return is_array($result) && isset($result['response']['user']) ? $result['response']['user'] : false; }elseif($this->ZendJSON){ $result = Zend_Json::decode($result); return is_array($result) && isset($result['response']['user']) ? $result['response']['user'] : false; }else{ return false; // no JSON } } //======================================================================================================================= // web service call: user/getUserByUserName //======================================================================================================================= protected function getUserByUsername($username){ $data = '{request:{"@username" : "'.$username.'" , "@extensible" : "true" }}'; if(!$result = $this->wsCall($data, "user/getUserByUserName")){ $this->failedWSCall = true; return false; // no responce } if(function_exists("json_decode")){ $result = json_decode($result, true); return is_array($result) && isset($result['response']['user']['@id']) ? $result['response']['user'] : false; }elseif($this->ZendJSON){ $result = Zend_Json::decode($result); return is_array($result) && isset($result['response']['user']['@id']) ? $result['response']['user'] : false; }else{ return false; } } //======================================================================================================================= protected function isValidLogin($result){ if(function_exists("json_decode")){ $result = json_decode($result, true); $success = (is_array($result) && isset($result['response']['@valid'], $result['response']['@enabled']) && $result['response']['@valid'] == 'true' && $result['response']['@enabled'] == 'true'); }elseif($this->ZendJSON){ $result = Zend_Json::decode($result); $success = (is_array($result) && isset($result['response']['@valid'], $result['response']['@enabled']) && $result['response']['@valid'] == 'true' && $result['response']['@enabled'] == 'true'); }else{ $re = '/"@valid":"true","@enabled":"true"/'; $matches = array(); $success = preg_match($re, $result); } return $success; } //======================================================================================================================= // web service call: authentication/validateLogin //======================================================================================================================= public function checkCredentials(){ if(!$this->validatePost()){ // validation return false; //invalid post } $success = false; if(!$this->startAdminSession()){ return false; //can't start admin session } // try login $data = '{"request":{"@username":"'.$_POST['uname'].'","@password":"'.$_POST['pwd'].'"}}'; if(!$result = $this->wsCall($data, "authentication/validateLogin")){ return false; // no response } $success = $this->isValidLogin($result); if($success && $details = $this->getUserByUsername($_POST['uname'])){ $this->storeSessionDetails($details); } $this->logoutAdmin(); return $success; } //======================================================================================================================= protected function storeSessionDetails($details){ $_SESSION['userID'] = $details['@id']; // get user groups $groups = isset($details["groups"]["group"]) ? $details["groups"]["group"] : false; if(is_array($groups)){ if(isset($groups['@group_name'])){ // in case of a single group $_SESSION['user_groups'][] = $groups['@group_name']; }else{ foreach($groups as $group){ if(isset($group['@group_name'])){ $_SESSION['user_groups'][] = $group['@group_name']; } } } } $_SESSION['user_name'] = $_POST['uname']; $_SESSION['full_name'] = isset($details['@firstname'], $details['@lastname']) ? $details['@firstname'].' '.$details['@lastname'] : ''; } //======================================================================================================================= } // END SampleLogin //=================================================================================================================== ############################################## END CLASSES ######################################################### //=================================================================================================================== tryLogout(); // try login if(isset($_POST['uname'], $_POST['pwd'])){ $login = new SampleLogin(); $login->showNext($login->checkCredentials()); }else{ redirectNonLogged(); } if(!IS_LOGIN_PAGE && !IS_NOACCESS_PAGE && !userHasAccess()){ header("Location: http://" . SITE_ROOT . "/intranet/noaccess/?no_access=" . urlencode($_SERVER['REQUEST_URI'])); exit; } ?>Full-time undergraduate funding 22/23
Previous study

For specific information for your particular funding body, please follow the links below:

A group of students in the Tower Building

At a glance

Open to: Full-time / Part-time UK students
Studying at level: Undergraduate / Postgraduate
The information on this page applies to students starting courses in these academic years (as indicated):

2017/18

2018/19