Watch our twelve procurement training videos for VCC's vendors on our YouTube channel.
All VCC procurement awards can now be found by clicking on the following Bonfire Procurement Portal link: https://vcc.bonfirehub.ca/portal/?tab=pastOpportunities
2020
Date Awarded 2020 |
Document No. / Title | Successful Vendor / Awarded Total |
Jan 16 | ITQ05122019-PC - Speciality Paper Supplies | Spicers Canada - N/A |
Jan 20 | RFQ04112019-FV - Supply of Consumable for Transportation Programs |
1. Concept Finishes 2. Lordco Parts 3. NAPA Auto Parts |
Feb 21 | NRFP31102019-TM - Financial Audit Services | KPMG - $133,515.00 |
Mar 24 | ITB 40-B557 - Elevator Modernization | Action Electric - $1,198,835.00 |
May 22 | NRFP04032020-VL - Refrigerator Repair and Maintenance Services | Coral Canada Wide Ltd - $100,000.00 |
2019
Date Awarded 2019 |
Document No. / Title | Successful Vendor / Awarded Total |
Nov 29 | NRFP 26092019-FV - Campus Access Control | Axis Systems Group - $400,000.00 |
Nov 12 | ITQ 24102019-SH - Firewall Software Subscription Support Services | Long View Systems Corporation - $127,445.43 |
Nov 05 | NRFP 03092019-FV - Dental Equipment Repairs and Maintenance | Henry Schein - $23,000/yr |
Oct 24 | NRFP 16082019-FV - Elevator Consultant | Gunn Consultants - $38,100.00 |
Oct 24 | NRFP 09072019-FV - Event Production and Webcast Services | SE Event Technology - N/A |
Oct 11 | ITQ 09092019-FV - Supply and Install Pot Washer | Bargreen Ellington - $91,787.00 |
Oct 04 | NRFP 09082019-FV Kitchen Equipment Repairs and Maintenance | Key Food Equipment Services - $45,000/yr |
Sept 19 | NRFP 05072019-FV - Supply and Delivery of Dental Consumables | Henry Schein - $170,000/yr |
Sept 06 | RFQ 03072019-TM - General Contractors |
1. Alfred Horie Construction Co. Ltd 2. Chandos Construction 3. Finlink Construction Ltd. 4. GBS Construction Managers Inc. 5. Hodgson King and Marble Ltd 6. Holaco Construction Ltd 7. KDS Construction Ltd 8. Magil Construction Pacific Inc. |
June 11 | RFQ 22032019-FV - Event Photography Services |
1. Christian Tisdale Photography 2. Union Photographers |
June 11 | RFQ 22032019-01-FV - Creative Photography Services |
1. Christian Tisdale Photography 2. Jerald Walliser Photography 3. North Light Images 4. Roger Mahler Photography |
May 05 | NRFP 25022019-FV - Parking Management Services |
Imperial Parking Canada Corporation - N/A |
April 11 | NRFP 24012019-FV - Energy Management Services |
Prism Engineering - $150,000.00 |
March 08 | ITQ 30012019-FV - Printing Services |
Simon Fraser University Document Solutions - $60,000.00 |
February 07 | NRFP 20112018 - Brand and Marketing Research |
Academica Group - $75,000.00 |
January 22 | ITQ 20122018-FV - Dental Equipment | Henry Schein - $101,062.83 |
Date Awarded 2018 |
Document No. / Title | Successful Vendor / Awarded Total |
December 21 | ITB 40-B504 - Lighting Upgrade Project Broadway Campus | Energy Network Services - $227,065.11 |
December 13 | NRFP 28092018-FV - All Flash Storage Equipment | EMC Corporation of Canada - $456,660.00 |
December 07 | NRFP 03102018-FV - Banking Services | Royal Bank of Canada |
November 05 | RFP 10072018-FV - Digital Advertising Media Buyer | NichePlus Digital Inc - $210,000.00 |
November 02 | RFQ 17082018-FV - Request for Qualifications Photography Services |
Service Area 1: Sarah Murray Photographer Service Area 2: Sarah Murray Photographer Fama Photography |
October 22 | RFQ 03082018-FV - Request for Qualifications Architectural Services |
Chernoff Thompson Architects Colbourne Architectural Group DA Architects + Planners Elemental Architectural and Building Solutions IBI Group Architects (Canada) Kasian Architecture Interior Design & Planning KMBR Architects Planners Thinkspace Architecture Planning Interior Design |
September 06 | ITQ 02082018-FV - Commercial Kitchen Smallwares and Small Tools | Russell Hendrix Foodservice Equipment |
August 24 | RFP 06072018-FV - Privacy Consulting Services | Hooper Access and Privacy Consulting Ltd. |
August 23 | RFP 28062018-FV - Sign Language Interpreting Services | A.S.L. Interpreting Inc. |
July 09 | 9425 - Master Plan Consultant Services | DIALOG BC - $338,076.00 |
June 22 | ITQ 24052018-SH - Flyer Printing Services | Central Web Offset Limit - $144,000.00 |
June 05 | RFQ 03042018-TM - General Contractors |
Edifice Construction Inc., GBS Construction Managers Inc., Halse Martin Construction Co Ltd., Hodgson King & Marble Ltd., Holaco Construction Ltd., KDS Construction Ltd. |
January 23 | ITQ 01092018-SH - Purchasing of F5 Virtual Appliance |
Scalar Decisions Inc. - $67,808.00 |
January 04 | RFP 10112017-TM - Actuarial Services |
Geoge & Bell Consulting Inc.- $10,000.00 |
January 02 | ITQ 21112017-SH - Computer Hardware Replacement |
Microserve V8205 - $155,828.23 |
Date Awarded 2017 |
Document No. / Title | Successful Vendor / Awarded Total |
December 21 | ITB 40-B330 - Downtown Washroom Upgrade |
C3M Construction Group Inc. - $199,999.00 |
December 20 | RFP 10112017-TM - Actuarial Services |
George & Bell Consulting Inc. - $10,000.00 |
December 12 | ITQ 20171109-JZ - Sundries and Inventory System for Collision |
White & Peters - $53,579.59 |
December 11 | ITQ 21112017-SH - Computer Hardware Replacement |
Microserve V8205 - $166,273.93; Island Key - $37,063 |
December 06 | ITB 40-B422 - Lighting Upgrade Downtown Campus |
Energy Network Services Inc. - $66,044.12 |
December 06 | ITB 40-B421 - Lighting Upgrade Broadway Campus |
Energy Network Services Inc. - $138,179.86 |
N/a | ITQ 20171024-JZ - Forklift Truck |
Competition Cancelled |
August 03 | ITB 40-B341 - Cafeteria Renovation |
C3M Construction Group Inc.- $267,768.00 |
August 03 | ITQ 29062017-SH - Computer Hardware Replacement |
GenX Solutions - $162,129.18 |
June 27 | ITB 40-B317 - Roof Replacement Project |
Flynn Canada - $1,055,879.00 |
April 06 | ITQ-03012017-SH - Computer Hardware Replacement |
Island Key Computers - $31,140.00 GenX Solutions - $333,216.71 |
March 29 | ITQ#20170131-JZ - Automotive Paints |
White & Peters - $225,000.00 |
February 03 | ITQ#01142016-JZ - Keyscan and Altronix Hardware |
Canem Systems - $27,037.00 |
January 18 | ITQ-05122016-TM - Food Trade Equipment |
EM Bakery - $26,696.00 Russell Hendrix - $53,785.00 Russell Food Equipment - $95,946.00 |
Date Awarded 2016 |
Document No. / Title | Successful Vendor / Awarded Total |
December 06 | RFP#02092016-TM - Roof Consultant | Elemental Architecture and Interiors Inc.- $15,180 |
December 06 | RFP#14072016-TM - Supply of Library Collection Books | ProQuest LLC - N/A |
November 30 | ITQ#10182016-TM - Food Trade Equipment |
RF Bakery - $54,150.00 Pacific Restaurant Supplies - $15,420.00 Hendrix Restaurant Equipment & Supplies - $17,000 |
November 22 | ITQ#02112016-TM - MS Surface Pro4s | Elco Systems Inc. - $36,510.20 |
November 18 | ITQ#02112016-SH - Lenovo and HP Hardware Replacement | Island Key - $167,946.30 |
August 24 | ITQ#27072016-SH - Computer Hardware Replacement | Microserve Computers - $163,327.42 |
June 24 | RFP#21042016-TM - Telephone System Support | Mitel Networks - $185,299.56 |
April 14 | RFP#24022016-TM - Kitchen Equipment Maintenance and Repair | Key Food Equipment Services - N/A |
February 04 | ITQ#01142016-PC - Key Scan and Altronix Hardware | Canem Systems Ltd. - $27,037.00 |
January 28 | RFP#21102015-TM - Security Services | Concord Security Corporation - $2,051,356.00 |
January 12 | RFP#20150929-JZ - Automotive Hoist Repairs and Maintenance | Alberta Sales Auto Quip BC - $50,000.00 |
January 06 | RFP#15102015-TM - Curriculum Management System | Leepfrog Technologies Inc. - $142,430.50 (USD) |
2014
|
|
Procurement Award Listing prior to 2013 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'] = '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.= '
Can\\'t login? Contact support@mywebsite.com
Reset your password