Kerio APIs Client Library for PHP 1.4.0.234
  • Namespace
  • Class
  • Tree
  • Deprecated

Namespaces

  • None
  • PHP

Classes

  • KerioApi
  • KerioApiSocket
  • KerioConnectApi
  • KerioControlApi
  • KerioDirectoryApi
  • KerioOperatorApi
  • KerioWorkspaceApi
  • SamepageApi

Interfaces

  • KerioApiInterface
  • KerioApiSocketInterface

Exceptions

  • KerioApiException
  1 <?php
  2 /**
  3  * This file is part of the kerio-api-php.
  4  *
  5  * Copyright (c) Kerio Technologies s.r.o.
  6  *
  7  * For the full copyright and license information, please view
  8  * the file license.txt that was distributed with this source code
  9  * or visit Developer Zone. (http://www.kerio.com/developers)
 10  *
 11  * Do not modify this source code.
 12  * Any changes may be overwritten by a new version.
 13  */
 14 
 15 require_once(dirname(__FILE__) . '/KerioApiInterface.php');
 16 require_once(dirname(__FILE__) . '/KerioApiSocket.php');
 17 require_once(dirname(__FILE__) . '/KerioApiException.php');
 18 
 19 /**
 20  * Kerio API Class.
 21  *
 22  * This is main class.
 23  *
 24  * Example:
 25  * <code>
 26  * <?php
 27  * require_once(dirname(__FILE__) . '/src/KerioApi.php');
 28  *
 29  * class MyApi extents KerioApi {
 30  *
 31  *     public function __contruct($name, $vendor, $version) {
 32  *         parent::__construct($name, $vendor, $version);
 33  *     }
 34  *
 35  *     public function getFoo() {
 36  *         return $this->sendRequest('...');
 37  *     }
 38  * }
 39  * ?>
 40  * </code>
 41  *
 42  * @copyright   Copyright &copy; 2012-2012 Kerio Technologies s.r.o.
 43  * @license     http://www.kerio.com/developers/license/sdk-agreement
 44  * @version     1.4.0.234
 45  */
 46 class KerioApi implements KerioApiInterface {
 47 
 48     /**
 49      * End-Line format
 50      */
 51     const CRLF = "\r\n";
 52 
 53     /**
 54      * HTTP server status
 55      */
 56     const HTTP_SERVER_OK = 200;
 57 
 58     /**
 59      * Library name
 60      * @var string
 61      */
 62     public $name = 'Kerio APIs Client Library for PHP';
 63 
 64     /**
 65      * Library version
 66      * @var string
 67      */
 68     public $version = '1.4.0.234';
 69 
 70     /**
 71      * Debug mode
 72      * @var boolean
 73      */
 74     private $debug = FALSE;
 75 
 76     /**
 77      * Unique id used in request
 78      * @var integer
 79      */
 80     private $requestId = 0;
 81 
 82     /**
 83      * Hostname
 84      * @var string
 85      */
 86     protected $hostname = '';
 87 
 88     /**
 89      * X-Token
 90      * @var string
 91      */
 92     protected $token = '';
 93 
 94     /**
 95      * Cookies
 96      * @var string
 97      */
 98     protected $cookies = '';
 99 
100     /**
101      * Application details
102      * @var array
103      */
104     protected $application = array('name' => '', 'vendor' => '', 'version' => '');
105 
106     /**
107      * JSON-RPC settings
108      * @var array
109      */
110     protected $jsonRpc = array('version' => '', 'port' => '', 'api' => '');
111 
112     /**
113      * HTTP headers
114      * @var array
115      */
116     protected $headers = array();
117 
118     /**
119      * Socket handler
120      * @var resource
121      */
122     private $socketHandler = '';
123 
124     /**
125      * Socket timeout
126      * @var integer
127      */
128     private $timeout = '';
129 
130     /**
131      * Class contructor.
132      *
133      * @param   string  Application name
134      * @param   string  Application vendor
135      * @param   string  Application version
136      * @return  void
137      * @throws  KerioApiException
138      */
139     public function __construct($name, $vendor, $version) {
140         $this->checkPhpEnvironment();
141         $this->setApplication($name, $vendor, $version);
142         $this->setJsonRpc($this->jsonRpc['version'], $this->jsonRpc['port'], $this->jsonRpc['api']);
143     }
144 
145     /**
146      * Check PHP environment.
147      *
148      *  @param  void
149      *  @return void
150      */
151     private function checkPhpEnvironment() {
152         if (version_compare(PHP_VERSION, '5.1.0', '<')) {
153             die(sprintf('<h1>kerio-api-php error</h1>Minimum PHP version required is 5.1.0. Your installation is %s.<br>Please, upgrade your PHP installation.', phpversion()));
154         }
155         if (FALSE === function_exists('openssl_open')) {
156             die('<h1>kerio-api-php error</h1>Your PHP installation does not have OpenSSL enabled.<br>To configure OpenSSL support in PHP, please edit your php.ini config file and enable row with php_openssl module, e.g. extension=php_openssl.dll<br>For more information see <a href="http://www.php.net/manual/en/openssl.installation.php">http://www.php.net/manual/en/openssl.installation.php</a>.');
157         }
158         if (FALSE === function_exists('json_decode')) {
159             die('<h1>kerio-api-php error</h1>Your PHP installation does not have JSON enabled.<br>To configure JSON support in PHP, please edit your php.ini config file and enable row with php_json module, e.g. extension=php_json.dll<br>For more information see <a href="http://www.php.net/manual/en/json.installation.php">http://www.php.net/manual/en/json.installation.php</a>.');
160         }
161     }
162 
163     /**
164      * Set application to identify on server.
165      *
166      * @param   string  Application name
167      * @param   string  Vendor
168      * @param   string  Version
169      * @return  void
170      * @throws  KerioApiException
171      */
172     private function setApplication($name, $vendor, $version) {
173         if (empty($name) && empty($vendor) && empty($version)) {
174             throw new KerioApiException('Application not defined.');
175         }
176         else {
177             $this->debug(sprintf("Registering application '%s' by '%s' version '%s'<br>", $name, $vendor, $version));
178             $this->application = array(
179                 'name'      => $name,
180                 'vendor'    => $vendor,
181                 'version'   => $version
182             );
183         }
184     }
185 
186     /**
187      * Get application detail.
188      *
189      * @param   void
190      * @return  array   Application details
191      */
192     public final function getApplication() {
193         return $this->application;
194     }
195 
196     /**
197      * Set JSON-RPC settings.
198      *
199      * @see class/KerioApiInterface::setJsonRpc()
200      * @param   string  JSON-RPC version
201      * @param   integer JSON-RPC port
202      * @param   string  JSON-RPC URI
203      * @return  void
204      * @throws  KerioApiException
205      */
206     public final function setJsonRpc($version, $port, $api) {
207         if (empty($version) && empty($port) && empty($api)) {
208             throw new KerioApiException('JSON-RPC not defined.');
209         }
210         else {
211             $this->debug(sprintf("Registering JSON-RPC %s on %s using port %d", $version, $api, $port));
212             $this->jsonRpc = array(
213                 'version'   => $version,
214                 'port'      => $port,
215                 'api'       => $api
216             );
217         }
218     }
219 
220     /**
221      * Get JSON-RPC settings.
222      *
223      * @param   void
224      * @return  array   JSON-RPC settings
225      */
226     public final function getJsonRpc() {
227         return $this->jsonRpc;
228     }
229 
230     /**
231      * Enable or disable of displaying debug messages.
232      *
233      * @param   boolean
234      * @return  void
235      */
236     public final function setDebug($boolean) {
237         $this->debug = (bool) $boolean;
238     }
239 
240     /**
241      * Get debug settings.
242      *
243      * @param   void
244      * @return  boolean
245      */
246     public final function getDebug() {
247         return $this->debug;
248     }
249 
250     /**
251      * Display a message if debug is TRUE.
252      *
253      * @param   string  Message
254      * @param   string  CSS class
255      * @return  string  Message in &lt;div&gt; tags
256      */
257     public function debug($message, $css = 'debug') {
258         if ($this->debug) {
259             printf('<div class="%s">%s</div>%s', $css, $message, "\n");
260         }
261     }
262 
263     /**
264      * Get product API version.
265      *
266      * @param   void
267      * @return  integer API version
268      */
269     public function getApiVersion() {
270         $method = 'Version.getApiVersion';
271         $response = $this->sendRequest($method);
272         return $response['apiVersion'];     
273     }
274 
275     /**
276      * Login method.
277      *
278      * @see class/KerioApiInterface::login()
279      * @param   string  Hostname
280      * @param   string  Username
281      * @param   string  Password
282      * @return  array   Result
283      * @throws  KerioApiException
284      */
285     public function login($hostname, $username, $password) {
286         $this->clean();
287 
288         if (empty($hostname)) {
289             throw new KerioApiException('Cannot login. Hostname not set.');
290         }
291         elseif (empty($username)) {
292             throw new KerioApiException('Cannot login. Username not set.');
293         }
294         elseif (empty($this->application)) {
295             throw new KerioApiException('Cannot login. Application not defined.');
296         }
297 
298         $this->setHostname($hostname);
299 
300         $method = 'Session.login';
301         $params = array(
302             'userName'      => $username,
303             'password'      => $password,
304             'application'   => $this->application
305         );
306 
307         $response = $this->sendRequest($method, $params);
308         return $response;
309     }
310 
311     /**
312      * Logout method.
313      *
314      * @see class/KerioApiInterface::logout()
315      * @param   void
316      * @return  array   Result
317      */
318     public function logout() {
319         $method = 'Session.logout';
320         $response = $this->sendRequest($method);
321         $this->clean();
322         return $response;
323     }
324 
325     /**
326      * Clean data.
327      *
328      * @param   void
329      * @return  void
330      */
331     public function clean() {
332         if ($this->token) {
333             $this->debug('Removing X-Token.');
334             $this->token = '';
335         }
336         if ($this->cookies) {
337             $this->debug('Removing Cookies.');
338             $this->cookies = '';
339         }
340         $this->hostname = '';
341         $this->socketHandler = '';
342     }
343 
344     /**
345      * Get full HTTP request.
346      *
347      * @param   string  HTTP method [POST,GET,PUT]
348      * @param   string  HTTP body
349      * @return  string  HTTP request
350      * @throws  KerioApiException
351      */
352     protected function getHttpRequest($method, $body) {
353         /* Clean data */
354         $this->headers = array();
355         $bodyRequest = '';
356         $fullRequest = '';
357 
358         /* Prepare headers and get request body*/
359         switch ($method) {
360             case 'POST': // common requests
361                 $bodyRequest = $this->getHttpPostRequest($body);
362                 break;
363             case 'GET': // download
364                 $bodyRequest = $this->getHttpGetRequest($body);
365                 break;
366             case 'PUT': // upload
367                 $bodyRequest = $this->getHttpPutRequest($body);
368                 break;
369             default:
370                 throw new KerioApiException('Cannot send request, unknown method.');
371         }
372 
373         /* Add port to headers if non-default is used */
374         $port = ($this->jsonRpc['port'] == 443)
375             ? ''
376             : sprintf(':%d', $this->jsonRpc['port']);
377 
378         /* Set common headers */
379         $this->headers['Host:']             = sprintf('%s%s', $this->hostname, $port);
380         $this->headers['Content-Length:']   = strlen($bodyRequest);
381         $this->headers['Connection:']       = 'close';
382 
383         /* Set X-Token and Cookies */
384         if ($this->token) {
385             $this->headers['Cookie:']   = $this->cookies;
386             $this->headers['X-Token:']  = $this->token;
387         }
388 
389         /* Build request */
390         foreach ($this->headers as $item => $value){
391             $fullRequest .= $item . ' ' . $value . self::CRLF;
392         }
393         $fullRequest .= self::CRLF;
394         $fullRequest .= $bodyRequest;
395 
396         /* Return */
397         return $fullRequest;
398     }
399 
400     /**
401      * Get headers for POST request.
402      *
403      * @param   string  Request body
404      * @return  string  Request body
405      */
406     protected function getHttpPostRequest($data) {
407         $this->headers['POST']          = sprintf('%s HTTP/1.1', $this->jsonRpc['api']);
408         $this->headers['Accept:']       = 'application/json-rpc';
409         $this->headers['Content-Type:'] = 'application/json-rpc; charset=UTF-8';
410         $this->headers['User-Agent:']   = sprintf('%s/%s', $this->name, $this->version);
411 
412         return str_replace(array("\r", "\r\n", "\n", "\t"), '', $data) . self::CRLF;
413     }
414 
415     /**
416      * Get headers for GET request.
417      *
418      * @param   string  Request body
419      * @return  string  Request body
420      */
421     protected function getHttpGetRequest($data) {
422         $this->headers['GET']               = sprintf('%s HTTP/1.1', $data);
423         $this->headers['Accept:']           = '*/*';
424 
425         return $data . self::CRLF;
426     }
427 
428     /**
429      * Get headers for PUT request.
430      *
431      * @param   string  Request body
432      * @return  string  Request body
433      */
434     protected function getHttpPutRequest($data) {
435         $boundary = sprintf('---------------------%s', substr(md5(rand(0,32000)), 0, 10));
436 
437         $this->headers['POST']          = sprintf('%s%s HTTP/1.1', $this->jsonRpc['api'], 'upload/');
438         $this->headers['Accept:']       = '*/*';
439         $this->headers['Content-Type:'] = sprintf('multipart/form-data; boundary=%s', $boundary);
440 
441         $body = '--' . $boundary . self::CRLF;
442         $body .= 'Content-Disposition: form-data; name="unknown"; filename="newFile.bin"' . self::CRLF;
443         $body .= self::CRLF;
444         $body .= $data . self::CRLF;
445         $body .= '--' . $boundary . '--' . self::CRLF;
446 
447         return $body;
448     }
449 
450     /**
451      * Send request using method and its params.
452      *
453      * @see class/KerioApiInterface::sendRequest()
454      * @param   string  Interface.method
455      * @param   array   Params of 'Interface.method'.
456      * @return  array   Returns same type as param is, e.g. JSON if method is also JSON
457      */
458     public function sendRequest($method, $params = '') {
459         $request = array(
460             'jsonrpc'   =>  $this->jsonRpc['version'],
461             'id'        =>  $this->getRequestId(),
462             'token'     =>  $this->token,
463             'method'    =>  $method,
464             'params'    =>  $params
465         );
466 
467         if (empty($this->token)) {
468             unset($request['token']);
469         }
470         if (empty($params)) {
471             unset($request['params']);
472         }
473 
474         $json_request = json_encode($request);
475 
476         /* Send data to server */
477         $json_response = $this->send('POST', $json_request);
478 
479         /* Return */
480         $response = json_decode($json_response, TRUE);
481         return $response['result'];
482     }
483 
484     /**
485      * Send JSON request.
486      *
487      * @param   string  JSON request
488      * @return  string  JSON response
489      */
490     public function sendRequestJson($json) {
491         return $this->send('POST', $json);
492     }
493 
494     /**
495      * Send data to server.
496      *
497      * @param   string  Request method [POST,GET,PUT]
498      * @param   string  Request body
499      * @return  string  Server response
500      * @throws  KerioApiException
501      */
502     protected function send($method, $data) {
503         if (empty($this->hostname)) {
504             throw new KerioApiException('Cannot send data before login.');
505         }
506 
507         /* Get full HTTP request */
508         $request = $this->getHttpRequest($method, $data);
509         $this->debug(sprintf("&rarr; Raw request:\n<pre>%s</pre>", $request));
510 
511         /* Open socket */
512         $this->socketHandler = new KerioApiSocket($this->hostname, $this->jsonRpc['port'], $this->timeout);
513 
514         /* Send data */
515         $rawResponse = $this->socketHandler->send($request);
516         $this->debug(sprintf("&larr; Raw response:\n<pre>%s</pre>", $rawResponse));
517 
518         /* Parse response */
519         $headers    = $this->socketHandler->getHeaders();
520         $body       = $this->socketHandler->getBody();
521         $this->checkHttpResponse(self::HTTP_SERVER_OK, $headers);
522 
523         /* Decode JSON response */
524         $response = stripslashes($body);
525         $response = json_decode($body, TRUE);
526         if (($method == 'POST') && empty($response)) {
527             throw new KerioApiException('Invalid JSON data, cannot parse response.');
528         }
529 
530         /* Set CSRF token */
531         if (empty($this->token)) {
532             if (isset($response['result']['token'])) {
533                 $this->setToken($response['result']['token']);
534             }
535         }
536 
537         /* Handle errors */
538         if (isset($response['error'])) {
539             if (FALSE === empty($response['error'])) {
540                 $message    = $response['error']['message'];
541                 $code       = $response['error']['code'];
542                 $params = (isset($response['error']['data']))
543                     ? $response['error']['data']['messageParameters']['positionalParameters']
544                     : '';
545                 throw new KerioApiException($message, $code, $params, $data, $body);
546             }
547         }
548         elseif (isset($response['result']['errors'])) {
549             if (FALSE === empty($response['result']['errors'])) {
550                 $message    = $response['result']['errors'][0]['message'];
551                 $code       = $response['result']['errors'][0]['code'];
552                 $params     = $response['result']['errors'][0]['messageParameters']['positionalParameters'];
553                 throw new KerioApiException($message, $code, $params, $data, $body);
554             }
555         }
556 
557         /* Handle Cookies */
558         if (empty($this->cookies)) {
559             $this->setCookieFromHeaders($headers);
560         }
561 
562         /* Return */
563         return $body;
564     }
565 
566     /**
567      * Get a file from server.
568      *
569      * @param   string  File url
570      * @param   string  Save directory
571      * @param   string  Save as, optional. Default is file.bin
572      * @return  boolean True on success
573      * @throws  KerioApiException
574      */
575     public function downloadFile($url, $directory, $filename = '') {
576         $saveAs = (empty($filename)) ? 'file.bin' : $filename;
577         $saveAs = sprintf('%s/%s', $directory, $filename);
578 
579         $data = $this->send('GET', $url);
580 
581         $this->debug(sprintf('Saving file %s', $saveAs));
582         if (FALSE === @file_put_contents($saveAs, $data)) {
583             throw new KerioApiException(sprintf('Unable to save file %s', $saveAs));
584         }
585         return TRUE;
586     }
587     
588     /**
589      * Get a file from server.
590      *
591      * @param   string  File url
592      * @return  string  File content
593      */
594     public function getFile($url) {
595         return $this->send('GET', $url);
596     }
597 
598     /**
599      * Put a file to server.
600      *
601      * @param   string  Absolute path to file
602      * @param   integer Reference ID where uploaded file belongs to, optional
603      * @return  array   Result
604      * @throws  KerioApiException
605      */
606     public function uploadFile($filename, $id = null) {
607         $data = @file_get_contents($filename);
608 
609         if ($data) {
610             $this->debug(sprintf('Uploading file %s', $filename));
611             $json_response = $this->send('PUT', $data);
612         }
613         else {
614             throw new KerioApiException(sprintf('Unable to open file %s', $filename));
615         }
616 
617         $response = json_decode($json_response, TRUE);
618         return $response['result'];
619     }
620 
621     /**
622      * Check HTTP/1.1 reponse header.
623      *
624      * @param   integer Requested HTTP code
625      * @param   string  HTTP headers
626      * @return  boolean True if match
627      * @throws  KerioApiException
628      */
629     protected function checkHttpResponse($code, $headers) {
630         preg_match('#HTTP/\d+\.\d+ (\d+) (.+)#', $headers, $result);
631         switch ($result[1]) {
632             case $code:
633                 return TRUE;
634             default:
635                 $remote = sprintf('https://%s:%d%s', $this->hostname, $this->jsonRpc['port'], $this->jsonRpc['api']);
636                 throw new KerioApiException(sprintf('%d - %s on remote server %s', $result[1], $result[2], $remote));
637         }
638     }
639 
640     /**
641      * Set hostname.
642      *
643      * @param   string  Hostname
644      * @return  void
645      */
646     public function setHostname($hostname) {
647         $hostname = preg_split('/:/', $hostname);
648         $this->hostname = $hostname[0];
649         if (isset($hostname[1])) {
650             $this->setJsonRpc($this->jsonRpc['version'], $hostname[1], $this->jsonRpc['api']);
651         }
652     }
653 
654     /**
655      * Get request ID.
656      *
657      * @param   void
658      * @return  integer
659      */
660     private function getRequestId() {
661         $this->requestId++;
662         return $this->requestId;
663     }
664 
665     /**
666      * Set security Cross-Site Request Forgery X-Token.
667      *
668      * @param   string  X-Token value
669      * @return  void
670      */
671     protected function setToken($token) {
672         $this->debug(sprintf('Setting X-Token %s.', $token));
673         $this->token = $token;
674     }
675 
676     /**
677      * Get security Cross-Site Request Forgery X-Token.
678      *
679      * @param   void
680      * @return  string  X-Token value
681      */
682     public function getToken() {
683         return $this->token;
684     }
685 
686     /**
687      * Set Cookies.
688      *
689      * @param   string  Cookies
690      * @return  void
691      */
692     protected function setCookie($cookies) {
693         $this->cookies = $cookies;
694     }
695 
696     /**
697      * Get Cookies.
698      *
699      * @param   void
700      * @return  string  Cookies
701      */
702     public function getCookie() {
703         return $this->cookies;
704     }
705 
706     /**
707      * Set Cookie from response.
708      *
709      * @param   string  HTTP headers
710      * @return  void
711      */
712     private function setCookieFromHeaders($headers) {
713         foreach (explode("\n", $headers) as $line) {
714             if (preg_match_all('/Set-Cookie:\s(\w*)=(\w*)/', $line, $result)) {
715                 foreach ($result[1] as $index => $cookie) {
716                     $this->debug(sprintf('Setting %s=%s.', $cookie, $result[2][$index]));
717                     $this->setCookie(sprintf('%s %s=%s;', $this->getCookie(), $cookie, $result[2][$index]));
718                 }
719             }
720         }
721     }
722 
723     /**
724      * Set connection timeout.
725      *
726      * @param   integer Timeout in seconds
727      * @return  void
728      */
729     public function setTimeout($timeout) {
730         $this->timeout = (integer) $timeout;
731     }
732 }
733 
Kerio APIs Client Library for PHP 1.4.0.234 API documentation generated by ApiGen 2.8.0