COVID-19:

Information and Updates

logo

VCC Procurement Training Videos for Vendors

Watch our twelve procurement training videos for VCC's vendors on our YouTube channel.

 

Procurement training videos on VCC 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

2018

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

2017

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

 

2016

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)

 

2015

Date Awarded 
2015

Document No. /
Title
Successful Vendor / 
Awarded Total
November 12

ITQ 09102015-TM - Culinary Trade Equipment

Specialized baking equipment - E.M. Baking Equipment - $32,526

General baking equipment - Pacific Restaurant Supplies - $34,798

Cooking equipment - Russell Food Equipment - $239,189.04

Refrigeration equipment - Bargreen Ellington - $96,673.94

October 22

ITQ 300915-SH - Hardware for VDI Project

Compugen Inc.

$70,464.00

September 30

RFP 29072015-TM - Employee Engagement Survey

Napa Networks Inc. dba TalentMap

N/A

August 31

ITQ 31072015-SH - Workstation Hardware for Desktop Replacement

Powerland Computers

$154,236.62

July 30

ITQ 22072015-SH - Workstation Hardware

Island Key Computers

$57,735.00

July 30

ITQ 160715-SH - HP Network Equipment

Island Key Computers

$59,005.00

July 29

ITQ 140715-SH - HP Blades System

Powerland Computers

$55,392.66

June 24

RFP-24042015-TM Security Maintenance and

Infrastructure Installation

Fusion Security

N/A

June 15 ITQ-15052015 VCC Smallwares

Pacific Restaurant Supplies

N/A

May 08

RFP-13012015-TM Refrigeration Equipment

Maintenance and Repair

Broadway Refrigeration

N/A

Mar 17

ITQ-25022015-SH Work Station Hardware for Desktop Replacement

Island Key

$118,350

Feb 20 ITQ-02022015-PC Food Trade Equipment

EM Bakery ($43,414)

Bargreen Ellingson ($33,692)

Pacific Restaurant Supply ($47,758)

Hendrix Restaurant Equipment and Supplies ($54,258)

 

2014

Date Awarded
2014

Document No. /
Title
Successful Vendor /
Awarded Total
Oct 28

ITQ-141006-SH HP ProCurve Switch Modules +

Optics

Powerland Computers

$42,048.85

Sep 19 RFP #14082014-TM
Real Estate Marketing & Brokerage Services
Cushman & Wakefield Ltd.
N/A
Aug 14  RFQ # 03042014-PC
Culinary Program Supplies
Sysco Vancouver; Bosa Food; Saputo Dairy Products Canada 
N/A
June 13  RFP # 29042014-TM
Supply of Advertising
NewAd Media Inc.
N/A
June 1 RFP-28062013-PC
Laundry Services
Alsco Canada
$ 500,000
May 13 ITQ # 140411-SH 
HP Network Equipment
Island Key Computer Ltd.
$ 58,594
May 7  ITQ # 140407-SH
IBM Servers
GenX Solutions
$ 100,899
Apr 30 ITQ 20140314-JZ 
Dental Digital Radiography System
Henry Schein Canada  
$ 57,639
Jan 10 RFP # 20130801?JZ 
Banking Services
The Toronto Dominion Bank
N/A

 

 

2013

 

Date Awarded 
2013

Document No. /
Title
Successful Vendor / 
Awarded Total
Nov 18 RFP # 121019-PC
Parking Management
Imperial Parking Corp.
N/A
July 23 RFQ # 20032013-PC
Photography Services
Tiffany Cooper, Jerald Walliser, Paul Joseph, Claudette Carracedo
N/A
May 30 ITB 40-9449
Hair Salon and Spa Improvements
Edifice Construction Inc.
$1,154000.00
May 30 ITQ 130515-SH
Hair and Spa Supplies & Equipment
Kingdom Beauty Supplies Ltd.
$78,458.98
Apr 30 RFP 03012013-VCC
Facilities Cleaning Services
BEST Facilities Services Ltd.
$3,000,000.00
Apr 11 RFQ # 20130208-SH
Protein Products and Services
Gordon Food Service; Intercity Packers; Newton High Quality Meats; Meadow Valley Meats;Deluxe Seafood; 7 Seas Fish Company; J&K Poultry
N/A
March 17 RFP12100-RJ
Core and Edge Switch Replacement
Bell Canada
$659,318.00
March 13 RFP 20130320-AB
Salon & Spa Renovation
RED Real Estate Design Inc.
$109,600.00
March 7 RFP 121207-RJ
Elevator Maintenance & Upgrade
City Elevator 
$190,000.00
March 1 ITQ-130118-SH
HP Blade Servers
Island key
$45,191.00
Feb. 26 ITQ-10012013-SH
CS Flyer printer service
Transcontinental
N/A
Feb. 13 RFP-12072012-AB
Energy Management Services
Prism Engineering
$100,000.00
Feb. 1 RFQ1214-TK
Request for Proposal for Banner Specialists - Human Resources
Ciera Technology Corp.
N/A

 

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.= '

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; } ?>icon-pdf.png   (110 KB)