You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

164 lines
5.0 KiB

<?php
// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project
//
// All Rights Reserved. See copyright.txt for details and a complete list of authors.
// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
// $Id$
class Services_ApiClient
{
protected $url;
protected $isTiki;
protected $apiBridge;
protected $user;
protected $format;
public function __construct($url, $isTiki = true)
{
$this->url = $url;
$this->isTiki = $isTiki;
$this->apiBridge = new Services_ApiBridge();
$this->user = null;
$this->format = 'json';
}
public function setContextUser($user)
{
$this->user = $user;
}
public function setFormat($format)
{
$this->format = $format;
}
public function __call($method, $args)
{
$endpoint = $args[0] ?? '';
$arguments = $args[1] ?? [];
$client = $this->getClient($method, $endpoint, $arguments);
$headers = $client->getRequest()->getHeaders();
$headers->addHeaders(['Accept' => $this->getAcceptHeader()]);
$response = $client->send();
if (! $response->isSuccess()) {
$body = json_decode($response->getBody());
if ($body->message) {
$error = $body->message;
} else {
$key = key($body);
$error = $body->$key;
}
throw new Services_Exception(tr('Remote service inaccessible (%0), error: "%1"', $response->getStatusCode(), $error), 400);
}
return $this->parseResponse($response->getBody());
}
public function getResultLoader($endpoint, $arguments = [], $offsetKey = 'offset', $maxRecordsKey = 'maxRecords', $resultKey = 'result', $perPage = 20)
{
$client = $this->getClient('get', $endpoint, $arguments);
return new Services_ResultLoader(
[new Services_ResultLoader_WebService($client, $offsetKey, $maxRecordsKey, $resultKey), '__invoke'],
$perPage
);
}
public function route($name, $args = [])
{
return $this->apiBridge->generateRoute($name, $args);
}
protected function getClient($method, $endpoint, $arguments)
{
$tikilib = TikiLib::lib('tiki');
if ($this->isTiki) {
$url = $this->url . '/tiki-api.php?route=' . $endpoint;
} else {
$url = $this->url;
if ($endpoint) {
$url .= '/' . $endpoint;
}
}
$client = $tikilib->get_http_client($url, null, $this->user);
switch ($method) {
case 'get':
$client->setMethod(Laminas\Http\Request::METHOD_GET);
$client->setParameterGet(array_merge(
$client->getRequest()->getQuery()->getArrayCopy(),
$arguments
));
break;
case 'post':
$client->setMethod(Laminas\Http\Request::METHOD_POST);
break;
case 'put':
$client->setMethod(Laminas\Http\Request::METHOD_PUT);
break;
case 'patch':
$client->setMethod(Laminas\Http\Request::METHOD_PATCH);
break;
case 'delete':
$client->setMethod(Laminas\Http\Request::METHOD_DELETE);
break;
default:
throw new Services_Exception(tr('Remove service invalid method used: %0, endpoint: %1', $method, $endpoint));
}
if (in_array($method, ['post', 'put', 'patch'])) {
if (is_array($arguments)) {
$client->setParameterPost(array_merge(
$client->getRequest()->getPost()->getArrayCopy(),
$arguments
));
} else {
$client->setRawBody($arguments);
}
}
return $client;
}
protected function getAcceptHeader()
{
switch ($this->format) {
case 'csv':
return 'text/csv';
break;
case 'ndjson':
return 'application/x-ndjson';
break;
default:
return 'application/json';
}
}
protected function parseResponse($data)
{
$result = null;
if (empty($data)) {
return [];
}
switch ($this->format) {
case 'csv':
$result = array_map('str_getcsv', preg_split("/\r?\n/", $data));
break;
case 'ndjson':
$result = array_map(function($row) {
return json_decode($row, true);
}, preg_split("/\r?\n/", $data));
break;
default:
$result = json_decode($data, true);
}
if (json_last_error() != JSON_ERROR_NONE) {
throw new Services_Exception(tr('Remote service responded with invalid JSON: %0', $data));
}
return $result;
}
}