The University of Dubuque has been accredited since 1921.

The public is invited to submit signed comments regarding the University:

Third Party Comment on University of Dubuque
The Higher Learning Commission
230 South LaSalle Street, Suite 7-500
Chicago, IL 60604-1411

The public may also submit comments on the Commission's Web site at www.ncahlc.org

Comments must address substantive matters related to the quality of the institution or its academic programs. Comments must be in writing.

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 == '/terminalfour/sample-site/intranet/login/' || $dir == '/terminalfour/sample-site/intranet/login/index.php')); define('IS_NOACCESS_PAGE',($dir == '/terminalfour/sample-site/intranet/noaccess/' || $dir == '/terminalfour/sample-site/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 . "/terminalfour/sample-site/"); 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 . "/terminalfour/sample-site/" . "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'] = 'localhost:8080'; $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 [email protected]
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 . "/terminalfour/sample-site/" . "intranet/noaccess/?no_access=" . urlencode($_SERVER['REQUEST_URI'])); exit; } ?>Style Guide