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.
 
 
 
 
 
 

427 lines
12 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$
require_once 'lib/ointegratelib.php';
require_once 'soap/soaplib.php';
require_once 'soap/wsdllib.php';
/**
* Tiki_Webservice
*
*/
class Tiki_Webservice
{
private $name;
public $url;
public $body;
public $operation;
public $wstype;
public $schemaVersion;
public $schemaDocumentation;
public $allowCookies;
private $templates = [];
private $all = false;
/**
* @param $name
* @return Tiki_Webservice
*/
public static function create($name)
{
if (! ctype_alpha($name) || self::getService($name)) {
return null;
}
$ws = new self();
$ws->name = strtolower($name);
return $ws;
}
/**
* @param $name
* @return Tiki_Webservice
*/
public static function getService($name)
{
$name = strtolower($name);
global $tikilib;
$result = $tikilib->query(
"SELECT url, operation, wstype, body, schema_version, schema_documentation FROM tiki_webservice WHERE service = ?",
[ $name ]
);
while ($row = $result->fetchRow()) {
$service = new self();
$service->name = $name;
$service->url = $row['url'];
$service->body = $row['body'];
$service->operation = $row['operation'];
$service->wstype = $row['wstype'];
$service->schemaVersion = $row['schema_version'];
$service->schemaDocumentation = $row['schema_documentation'];
return $service;
}
}
/**
* @return array
*/
public static function getTypes()
{
return ['REST', 'SOAP'];
}
/**
* @return array
*/
public static function getList()
{
global $tikilib;
$result = $tikilib->query("SELECT service FROM tiki_webservice ORDER BY service");
$list = [];
while ($row = $result->fetchRow()) {
$list[] = $row['service'];
}
return $list;
}
public function save()
{
global $tikilib;
$tikilib->query("DELETE FROM tiki_webservice WHERE service = ?", [ $this->name ]);
$tikilib->query(
"INSERT INTO tiki_webservice (service, url, operation, wstype, body, schema_version, schema_documentation) VALUES(?,?,?,?,?,?,?)",
[
$this->name,
$this->url,
$this->operation,
$this->wstype,
$this->body,
$this->schemaVersion,
$this->schemaDocumentation,
]
);
}
public function delete()
{
global $tikilib;
$tikilib->query("DELETE FROM tiki_webservice WHERE service = ?", [ $this->name ]);
$tikilib->query("DELETE FROM tiki_webservice_template WHERE service = ?", [ $this->name ]);
}
/**
* @param $newName
* @return $this|null
*/
public function rename($newName)
{
$tiki_webservice = TikiDb::get()->table('tiki_webservice');
if (ctype_alpha($newName) && $tiki_webservice->fetchCount(['service' => $newName]) == 0) {
TikiDb::get()->table('tiki_webservice_template')->updateMultiple(
['service' => $newName,],
['service' => $this->name]
);
$tiki_webservice->update(['service' => $newName,], ['service' => $this->name]);
$this->name = $newName;
return $this;
} else {
return null;
}
}
/**
* @return array
*/
public function getParameters()
{
global $wsdllib;
switch ($this->wstype) {
case 'SOAP':
return $wsdllib->getParametersNames($this->url, $this->operation);
case 'REST':
default:
if (preg_match_all("/%(\w+)%/", $this->url . ' ' . $this->body, $matches, PREG_PATTERN_ORDER)) {
return array_diff($matches[1], [ 'service', 'template' ]);
} else {
return [];
}
}
}
/**
* @param $params
* @return array
*/
public function getParameterMap($params)
{
$parameters = [];
foreach ($this->getParameters() as $key => $name) {
if (isset($params[$name])) {
$parameters[$name] = $params[$name];
} else {
$parameters[$name] = '';
}
}
return $parameters;
}
/*
* If fullResponse = true, "out" parameters from .NET calls are included in the response.
* If false, only the <request>Response part of the reply is included.
* fullResponse has no effect for REST calls
*/
/**
* @param $params
* @param bool $fullReponse
* @return bool|OIntegrate_Response
*/
public function performRequest($params, $fullReponse = false, $clearCache = false)
{
global $soaplib, $prefs;
$built = $this->url;
$builtBody = $this->body;
$map = $this->getParameterMap($params);
if ($built) {
switch ($this->wstype) {
case 'SOAP':
if (! empty($this->operation)) {
$options = [ 'encoding' => 'UTF-8' ];
if ($prefs['use_proxy'] == 'y' && ! strpos($built, 'localhost')) {
$options['proxy_host'] = $prefs['proxy_host'];
$options['proxy_port'] = $prefs['proxy_port'];
}
$response = new OIntegrate_Response();
$soaplib->allowCookies = $this->allowCookies;
try {
$response->data = $soaplib->performRequest($built, $this->operation, $map, $options, $fullReponse);
} catch (Exception $e) {
Feedback::error(tr('Webservice error on %0 request "%1"', $this->wstype, $this->url)
. '<br>' . $e->getMessage());
}
return $response;
}
return false;
case 'REST':
default:
foreach ($map as $name => $value) {
$built = str_replace("%$name%", urlencode($value), $built);
$builtBody = str_replace("%$name%", urlencode($value), $builtBody);
}
$ointegrate = new OIntegrate();
$ointegrate->addAcceptTemplate('smarty', 'tikiwiki');
$ointegrate->addAcceptTemplate('smarty', 'html');
$ointegrate->addAcceptTemplate('javascript', 'html');
if ($this->schemaVersion) {
$ointegrate->addSchemaVersion($this->schemaVersion);
}
try {
$response = $ointegrate->performRequest($built, $builtBody, $clearCache);
} catch (Exception $e) {
Feedback::error(tr('Webservice error on %0 request "%1"', $this->wstype, $this->url)
. '<br>' . $e->getMessage());
$response = null;
}
return $response;
}
}
}
/**
* @param $name
* @return Tiki_Webservice_Template
*/
public function addTemplate($name)
{
if (! ctype_alpha($name) || empty($name)) {
return;
}
$template = new Tiki_Webservice_Template();
$template->webservice = $this;
$template->name = strtolower($name);
$this->templates[$name] = $template;
return $template;
}
/**
* @param $name
*/
public function removeTemplate($name)
{
global $tikilib;
$tikilib->query("DELETE FROM tiki_webservice_template WHERE service = ? AND template = ?", [ $this->name, $name ]);
}
/**
* @return array
*/
public function getTemplates()
{
if ($this->all) {
return $this->templates;
}
global $tikilib;
$result = $tikilib->query(
"SELECT template, last_modif, engine, output, content FROM tiki_webservice_template WHERE service = ?",
[ $this->name ]
);
while ($row = $result->fetchRow()) {
$template = new Tiki_Webservice_Template();
$template->webservice = $this;
$template->name = $row['template'];
$template->lastModif = $row['last_modif'];
$template->engine = $row['engine'];
$template->output = $row['output'];
$template->content = $row['content'];
$this->templates[$template->name] = $template;
}
$this->all = true;
return $this->templates;
}
/**
* @param $name
* @return Tiki_Webservice_Template
*/
public function getTemplate($name)
{
if (isset($this->templates[$name])) {
return $this->templates[$name];
}
global $tikilib;
$result = $tikilib->query(
"SELECT last_modif, engine, output, content FROM tiki_webservice_template WHERE service = ? AND template = ?",
[ $this->name, $name ]
);
while ($row = $result->fetchRow()) {
$template = new Tiki_Webservice_Template();
$template->webservice = $this;
$template->name = $name;
$template->lastModif = $row['last_modif'];
$template->engine = $row['engine'];
$template->output = $row['output'];
$template->content = $row['content'];
$this->templates[$name] = $template;
return $template;
}
}
public function getName()
{
return $this->name;
}
}
/**
* Tiki_Webservice_Template
*
*/
class Tiki_Webservice_Template
{
public $webservice;
public $name;
public $engine;
public $output;
public $content;
public $lastModif;
public function save()
{
global $tikilib;
$tikilib->query(
"DELETE FROM tiki_webservice_template WHERE service = ? AND template = ?",
[ $this->webservice->getName(), $this->name ]
);
$tikilib->query(
"INSERT INTO tiki_webservice_template (service, template, engine, output, content, last_modif) VALUES(?,?,?,?,?,?)",
[
$this->webservice->getName(),
$this->name,
$this->engine,
$this->output,
$this->content,
time(),
]
);
if ($this->engine === 'index') {
if ($this->output === 'mindex') {
Feedback::warning(tra('You will need to rebuild the search index to see these changes'));
}
require_once 'lib/search/refresh-functions.php';
refresh_index('webservice', $this->name);
}
}
/**
* @return string
*/
public function getTemplateFile()
{
$token = sprintf("%s_%s", $this->webservice->getName(), $this->name);
$file = "temp/cache/" . md5($token) . '.tpl';
if (! file_exists($file) || $this->lastModif > filemtime($file)) {
file_put_contents($file, $this->content);
}
return realpath($file);
}
/**
* @param OIntegrate_Response $response
* @param $outputContext
* @return mixed|string
*/
public function render(OIntegrate_Response $response, $outputContext)
{
return $response->render($this->engine, $this->output, $outputContext, $this->getTemplateFile());
}
}