forked from extern/egroupware
Restored old, working xmlrpc.php which uses the api classes; Moved more recent version to .old for now
This commit is contained in:
parent
c49d1cf3be
commit
e30974493b
247
xmlrpc.php
247
xmlrpc.php
@ -13,14 +13,6 @@
|
||||
/* $Id$ */
|
||||
/* $Source$ */
|
||||
|
||||
// NOTE! This file is still in the experimental stages, use at your own risk!
|
||||
// The only current documentation for it is the code and the comments
|
||||
// A document explaining its usage should be done shortly
|
||||
// PLEASE, do *NOT* make any changes to this file without talking to me
|
||||
// directly first. Until I get it fully undercontrol.
|
||||
// There might be possiable security holes in this, I haven't fully tested it
|
||||
// (jengo)
|
||||
|
||||
$GLOBALS['phpgw_info'] = array();
|
||||
$GLOBALS['phpgw_info']['flags'] = array(
|
||||
'currentapp' => 'login',
|
||||
@ -29,8 +21,15 @@
|
||||
);
|
||||
include('header.inc.php');
|
||||
|
||||
$server = CreateObject('phpgwapi.xmlrpc_server');
|
||||
$server->authed = False;
|
||||
// debug($server);exit;
|
||||
|
||||
/* uncomment here if you want to show all of the testing functions for compatibility */
|
||||
// include(PHPGW_API_INC . '/xmlrpc.interop.php');
|
||||
|
||||
// If XML-RPC isn't enabled in PHP, return an XML-RPC response stating so
|
||||
if (! function_exists('xmlrpc_server_create'))
|
||||
if(!function_exists('xmlrpc_server_create'))
|
||||
{
|
||||
echo "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n";
|
||||
echo "<methodResponse>\n";
|
||||
@ -57,232 +56,22 @@
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
// Return all PHP errors as faults
|
||||
$GLOBALS['xmlrpc_server'] = xmlrpc_server_create();
|
||||
error_reporting(E_ERROR | E_WARNING | E_PARSE);
|
||||
set_error_handler('xmlrpc_custom_error');
|
||||
|
||||
/* Note: this command only available under Apache */
|
||||
$headers = getallheaders();
|
||||
if (ereg('Basic',$headers['Authorization']))
|
||||
|
||||
if(ereg('Basic',$headers['Authorization']))
|
||||
{
|
||||
$tmp = $headers['Authorization'];
|
||||
$tmp = ereg_replace(' ','',$tmp);
|
||||
$tmp = ereg_replace('Basic','',$tmp);
|
||||
$tmp = $headers['Authorization'];
|
||||
$tmp = ereg_replace(' ','',$tmp);
|
||||
$tmp = ereg_replace('Basic','',$tmp);
|
||||
$auth = base64_decode(trim($tmp));
|
||||
list($sessionid,$kp3) = split(':',$auth);
|
||||
|
||||
if ($GLOBALS['phpgw']->session->verify($sessionid,$kp3))
|
||||
if($GLOBALS['phpgw']->session->verify($sessionid,$kp3))
|
||||
{
|
||||
$GLOBALS['xmlrpc_server'] = xmlrpc_server_create();
|
||||
$request_xml = $HTTP_RAW_POST_DATA;
|
||||
|
||||
// Find out what method they are calling
|
||||
// This function is odd, you *NEED* to assign the results
|
||||
// to a value, or $method is never returned. (jengo)
|
||||
$null = xmlrpc_decode_request($request_xml, &$method);
|
||||
$GLOBALS['phpgw']->session->xmlrpc_method_called = $method;
|
||||
$GLOBALS['phpgw']->session->update_dla();
|
||||
|
||||
// Check permissions and load the class, register all methods
|
||||
// for that class, and execute it
|
||||
list($app,$class,$func) = explode('.',$method);
|
||||
|
||||
if ($method == 'system.logout' || $GLOBALS['phpgw_info']['user']['apps'][$app] || $app == 'phpgwapi')
|
||||
{
|
||||
$GLOBALS['obj'] = CreateObject($app . '.' . $class);
|
||||
|
||||
xmlrpc_server_register_method($xmlrpc_server,sprintf('%s.%s.%s',$app,$class,'listMethods'),'xmlrpc_list_methods');
|
||||
xmlrpc_server_register_method($xmlrpc_server,sprintf('%s.%s.%s',$app,$class,'describeMethods'),xmlrpc_describe_methods);
|
||||
xmlrpc_server_register_method($xmlrpc_server,'system.logout','xmlrpc_logout');
|
||||
|
||||
while (list(,$new_method) = @each($obj->xmlrpc_methods))
|
||||
{
|
||||
$full_method_name = sprintf('%s.%s.%s',$app,$class,$new_method['name']);
|
||||
|
||||
xmlrpc_server_register_method($xmlrpc_server,$full_method_name,'xmlrpc_call_wrapper');
|
||||
// The following function is listed as being in the API, but doesn't actually exisit.
|
||||
// This is more of a mental note to track down its exisitence
|
||||
//xmlrpc_server_set_method_description($xmlrpc_server,$full_method_name,$new_method);
|
||||
}
|
||||
}
|
||||
else if ($method != 'system.listMethods' && $method != 'system.describeMethods')
|
||||
{
|
||||
xmlrpc_error(1001,'Access not permitted');
|
||||
}
|
||||
|
||||
echo xmlrpc_server_call_method($xmlrpc_server,$request_xml,'');
|
||||
xmlrpc_server_destroy($xmlrpc_server);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Session is invailed
|
||||
xmlrpc_error(1001,'Session expired');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// First, create a single method being system.login
|
||||
// If they don't request this, then just return a failed session error
|
||||
$xmlrpc_server = xmlrpc_server_create();
|
||||
$request_xml = $HTTP_RAW_POST_DATA;
|
||||
|
||||
// Find out what method they are calling
|
||||
// This function is odd, you *NEED* to assign the results
|
||||
// to a value, or $method is never returned. (jengo)
|
||||
$null = xmlrpc_decode_request($request_xml, &$method);
|
||||
|
||||
if ($method == 'system.login')
|
||||
{
|
||||
xmlrpc_server_register_method($xmlrpc_server,'system.login','xmlrpc_login');
|
||||
echo xmlrpc_server_call_method($xmlrpc_server,$request_xml,'');
|
||||
xmlrpc_server_destroy($xmlrpc_server);
|
||||
|
||||
exit;
|
||||
}
|
||||
else
|
||||
{
|
||||
// They didn't request system.login and they didn't pass sessionid or
|
||||
// kp3, this is an invailed session (The session could have also been killed or expired)
|
||||
xmlrpc_error(1001,'Session expired');
|
||||
$server->authed = True;
|
||||
}
|
||||
}
|
||||
|
||||
// When PHP returns an error, return that error with a fault instead of
|
||||
// HTML with will make most parsers fall apart
|
||||
function xmlrpc_custom_error($error_number, $error_string, $filename, $line, $vars)
|
||||
{
|
||||
if (error_reporting() & $error_number)
|
||||
{
|
||||
$error_string .= sprintf("\nFilename: %s\nLine: %s",$filename,$line);
|
||||
|
||||
xmlrpc_error(1005,$error_string);
|
||||
}
|
||||
}
|
||||
|
||||
// This will create an XML-RPC error
|
||||
// FIXME! This needs to be expanded to handle PHP errors themselfs
|
||||
// it will make debugging easier
|
||||
function xmlrpc_error($error_number, $error_string)
|
||||
{
|
||||
$values = array(
|
||||
'faultString' => $error_string,
|
||||
'faultCode' => $error_number
|
||||
);
|
||||
|
||||
echo xmlrpc_encode_request(NULL,$values);
|
||||
|
||||
xmlrpc_server_destroy($GLOBALS['xmlrpc_server']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// This will dynamicly create the avaiable methods for each class
|
||||
function xmlrpc_list_methods($method)
|
||||
{
|
||||
list($app,$class,$func) = explode('.',$method);
|
||||
$methods[] = 'system.login';
|
||||
$methods[] = 'system.logout';
|
||||
$methods[] = $method;
|
||||
$methods[] = $app . '.' . $class . 'describeMethods';
|
||||
for ($i=0; $i<count($GLOBALS['obj']->xmlrpc_methods); $i++)
|
||||
{
|
||||
$methods[] = $GLOBALS['obj']->xmlrpc_methods[$i]['name'];
|
||||
}
|
||||
|
||||
return $methods;
|
||||
}
|
||||
|
||||
function xmlrpc_describe_methods($method)
|
||||
{
|
||||
list($app,$class,$func) = explode('.',$method);
|
||||
// FIXME! Add the missing pre-defined methods, example: system.login
|
||||
for ($i=0; $i<count($GLOBALS['obj']->xmlrpc_methods); $i++)
|
||||
{
|
||||
$methods[] = $GLOBALS['obj']->xmlrpc_methods[$i];
|
||||
}
|
||||
|
||||
return $methods;
|
||||
}
|
||||
|
||||
// I know everyone hates wrappers, but this is the best way this can be done
|
||||
// The XML-RPC functions pass method_name as the first parameter, which is
|
||||
// unacceptable.
|
||||
// Another reason for this, is it might be possiable to pass the sessionid
|
||||
// and kp3 instead of using HTTP_AUTH features.
|
||||
// Would be a nice workaround for librarys that don't support it, as its
|
||||
// not in the XML-RPC spec.
|
||||
function xmlrpc_call_wrapper($method_name, $parameters)
|
||||
{
|
||||
$a = explode('.',$method_name);
|
||||
|
||||
if (count($parameters) == 0)
|
||||
{
|
||||
$return = $GLOBALS['obj']->$a[2]();
|
||||
}
|
||||
else if (count($parameters) == 1)
|
||||
{
|
||||
$return = $GLOBALS['obj']->$a[2]($parameters[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
for ($i=0; $i<count($parameters); $i++)
|
||||
{
|
||||
$p[] = '$parameters[' . $i . ']';
|
||||
}
|
||||
eval('$return = $GLOBALS[\'obj\']->$a[2](' . implode(',',$p) . ');');
|
||||
}
|
||||
|
||||
// This needs to be expanded and more fully tested
|
||||
if (gettype($return) == 'NULL')
|
||||
{
|
||||
return xmlrpc_error(1002,'No return value detected');
|
||||
}
|
||||
else
|
||||
{
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
|
||||
// The following are common functions used ONLY by XML-RPC
|
||||
function xmlrpc_login($method_name, $parameters)
|
||||
{
|
||||
$p = $parameters[0];
|
||||
|
||||
if ($p['domain'])
|
||||
{
|
||||
$username = $p['username'] . '@' . $p['domain'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$username = $p['username'];
|
||||
}
|
||||
|
||||
$sessionid = $GLOBALS['phpgw']->session->create($username,$p['password'],'text');
|
||||
$kp3 = $GLOBALS['phpgw']->session->kp3;
|
||||
$domain = $GLOBALS['phpgw']->session->account_domain;
|
||||
|
||||
if ($sessionid && $kp3)
|
||||
{
|
||||
return array(
|
||||
'sessionid' => $sessionid,
|
||||
'kp3' => $kp3,
|
||||
'domain' => $domain
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlrpc_error(1001,'Login failed');
|
||||
}
|
||||
}
|
||||
|
||||
function xmlrpc_logout($method, $parameters)
|
||||
{
|
||||
// We have already verified the session upon before this method is even created
|
||||
// As long as nothing happens upon, its safe to destroy the session without
|
||||
// fear of it being a hijacked session
|
||||
$GLOBALS['phpgw']->session->destroy($GLOBALS['phpgw']->session->sessionid,$GLOBALS['phpgw']->session->kp3);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
$server->service($HTTP_SERVER_VARS['HTTP_RAW_POST_DATA']);
|
||||
?>
|
||||
|
290
xmlrpc.php.old
Normal file
290
xmlrpc.php.old
Normal file
@ -0,0 +1,290 @@
|
||||
<?php
|
||||
/**************************************************************************\
|
||||
* phpGroupWare xmlrpc server *
|
||||
* http://www.phpgroupware.org *
|
||||
* This file written by Joseph Engo <jengo@phpgroupware.org> *
|
||||
* -------------------------------------------- *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||
* option) any later version. *
|
||||
\**************************************************************************/
|
||||
|
||||
/* $Id$ */
|
||||
/* $Source$ */
|
||||
|
||||
// NOTE! This file is still in the experimental stages, use at your own risk!
|
||||
// The only current documentation for it is the code and the comments
|
||||
// A document explaining its usage should be done shortly
|
||||
// PLEASE, do *NOT* make any changes to this file without talking to me
|
||||
// directly first. Until I get it fully undercontrol.
|
||||
// There might be possiable security holes in this, I haven't fully tested it
|
||||
// (jengo)
|
||||
|
||||
exit;
|
||||
|
||||
$GLOBALS['phpgw_info'] = array();
|
||||
$GLOBALS['phpgw_info']['flags'] = array(
|
||||
'currentapp' => 'login',
|
||||
'noheader' => True,
|
||||
'disable_Template_class' => True
|
||||
);
|
||||
include('header.inc.php');
|
||||
|
||||
// If XML-RPC isn't enabled in PHP, return an XML-RPC response stating so
|
||||
if (! function_exists('xmlrpc_server_create'))
|
||||
{
|
||||
echo "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n";
|
||||
echo "<methodResponse>\n";
|
||||
echo "<fault>\n";
|
||||
echo " <value>\n";
|
||||
echo " <struct>\n";
|
||||
echo " <member>\n";
|
||||
echo " <name>faultString</name>\n";
|
||||
echo " <value>\n";
|
||||
echo " <string>XML-RPC support NOT enabled in PHP installation</string>\n";
|
||||
echo " </value>\n";
|
||||
echo " </member>\n";
|
||||
echo " <member>\n";
|
||||
echo " <name>faultCode</name>\n";
|
||||
echo " <value>\n";
|
||||
echo " <int>1005</int>\n";
|
||||
echo " </value>\n";
|
||||
echo " </member>\n";
|
||||
echo " </struct>\n";
|
||||
echo " </value>\n";
|
||||
echo "</fault>\n";
|
||||
echo "</methodResponse>\n";
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
// Return all PHP errors as faults
|
||||
$GLOBALS['xmlrpc_server'] = xmlrpc_server_create();
|
||||
error_reporting(E_ERROR | E_WARNING | E_PARSE);
|
||||
set_error_handler('xmlrpc_custom_error');
|
||||
|
||||
$headers = getallheaders();
|
||||
if (ereg('Basic',$headers['Authorization']))
|
||||
{
|
||||
$tmp = $headers['Authorization'];
|
||||
$tmp = ereg_replace(' ','',$tmp);
|
||||
$tmp = ereg_replace('Basic','',$tmp);
|
||||
$auth = base64_decode(trim($tmp));
|
||||
list($sessionid,$kp3) = split(':',$auth);
|
||||
|
||||
if ($GLOBALS['phpgw']->session->verify($sessionid,$kp3))
|
||||
{
|
||||
$GLOBALS['xmlrpc_server'] = xmlrpc_server_create();
|
||||
$request_xml = $HTTP_RAW_POST_DATA;
|
||||
|
||||
// Find out what method they are calling
|
||||
// This function is odd, you *NEED* to assign the results
|
||||
// to a value, or $method is never returned. (jengo)
|
||||
$null = xmlrpc_decode_request($request_xml, &$method);
|
||||
$GLOBALS['phpgw']->session->xmlrpc_method_called = $method;
|
||||
$GLOBALS['phpgw']->session->update_dla();
|
||||
|
||||
// Check permissions and load the class, register all methods
|
||||
// for that class, and execute it
|
||||
list($app,$class,$func) = explode('.',$method);
|
||||
|
||||
if ($method == 'system.logout' || $GLOBALS['phpgw_info']['user']['apps'][$app] || $app == 'phpgwapi')
|
||||
{
|
||||
$GLOBALS['obj'] = CreateObject($app . '.' . $class);
|
||||
|
||||
xmlrpc_server_register_method($xmlrpc_server,sprintf('%s.%s.%s',$app,$class,'listMethods'),'xmlrpc_list_methods');
|
||||
xmlrpc_server_register_method($xmlrpc_server,sprintf('%s.%s.%s',$app,$class,'describeMethods'),xmlrpc_describe_methods);
|
||||
xmlrpc_server_register_method($xmlrpc_server,'system.logout','xmlrpc_logout');
|
||||
|
||||
while (list(,$new_method) = @each($obj->xmlrpc_methods))
|
||||
{
|
||||
$full_method_name = sprintf('%s.%s.%s',$app,$class,$new_method['name']);
|
||||
|
||||
xmlrpc_server_register_method($xmlrpc_server,$full_method_name,'xmlrpc_call_wrapper');
|
||||
// The following function is listed as being in the API, but doesn't actually exisit.
|
||||
// This is more of a mental note to track down its exisitence
|
||||
//xmlrpc_server_set_method_description($xmlrpc_server,$full_method_name,$new_method);
|
||||
}
|
||||
}
|
||||
else if ($method != 'system.listMethods' && $method != 'system.describeMethods')
|
||||
{
|
||||
xmlrpc_error(1001,'Access not permitted');
|
||||
}
|
||||
|
||||
echo xmlrpc_server_call_method($xmlrpc_server,$request_xml,'');
|
||||
xmlrpc_server_destroy($xmlrpc_server);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Session is invailed
|
||||
xmlrpc_error(1001,'Session expired');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// First, create a single method being system.login
|
||||
// If they don't request this, then just return a failed session error
|
||||
$xmlrpc_server = xmlrpc_server_create();
|
||||
$request_xml = $HTTP_RAW_POST_DATA;
|
||||
|
||||
// Find out what method they are calling
|
||||
// This function is odd, you *NEED* to assign the results
|
||||
// to a value, or $method is never returned. (jengo)
|
||||
$null = xmlrpc_decode_request($request_xml, &$method);
|
||||
|
||||
if ($method == 'system.login')
|
||||
{
|
||||
xmlrpc_server_register_method($xmlrpc_server,'system.login','xmlrpc_login');
|
||||
echo xmlrpc_server_call_method($xmlrpc_server,$request_xml,'');
|
||||
xmlrpc_server_destroy($xmlrpc_server);
|
||||
|
||||
exit;
|
||||
}
|
||||
else
|
||||
{
|
||||
// They didn't request system.login and they didn't pass sessionid or
|
||||
// kp3, this is an invailed session (The session could have also been killed or expired)
|
||||
xmlrpc_error(1001,'Session expired');
|
||||
}
|
||||
}
|
||||
|
||||
// When PHP returns an error, return that error with a fault instead of
|
||||
// HTML with will make most parsers fall apart
|
||||
function xmlrpc_custom_error($error_number, $error_string, $filename, $line, $vars)
|
||||
{
|
||||
if (error_reporting() & $error_number)
|
||||
{
|
||||
$error_string .= sprintf("\nFilename: %s\nLine: %s",$filename,$line);
|
||||
|
||||
xmlrpc_error(1005,$error_string);
|
||||
}
|
||||
}
|
||||
|
||||
// This will create an XML-RPC error
|
||||
// FIXME! This needs to be expanded to handle PHP errors themselfs
|
||||
// it will make debugging easier
|
||||
function xmlrpc_error($error_number, $error_string)
|
||||
{
|
||||
$values = array(
|
||||
'faultString' => $error_string,
|
||||
'faultCode' => $error_number
|
||||
);
|
||||
|
||||
echo xmlrpc_encode_request(NULL,$values);
|
||||
|
||||
xmlrpc_server_destroy($GLOBALS['xmlrpc_server']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// This will dynamicly create the avaiable methods for each class
|
||||
function xmlrpc_list_methods($method)
|
||||
{
|
||||
list($app,$class,$func) = explode('.',$method);
|
||||
$methods[] = 'system.login';
|
||||
$methods[] = 'system.logout';
|
||||
$methods[] = $method;
|
||||
$methods[] = $app . '.' . $class . 'describeMethods';
|
||||
for ($i=0; $i<count($GLOBALS['obj']->xmlrpc_methods); $i++)
|
||||
{
|
||||
$methods[] = $GLOBALS['obj']->xmlrpc_methods[$i]['name'];
|
||||
}
|
||||
|
||||
return $methods;
|
||||
}
|
||||
|
||||
function xmlrpc_describe_methods($method)
|
||||
{
|
||||
list($app,$class,$func) = explode('.',$method);
|
||||
// FIXME! Add the missing pre-defined methods, example: system.login
|
||||
for ($i=0; $i<count($GLOBALS['obj']->xmlrpc_methods); $i++)
|
||||
{
|
||||
$methods[] = $GLOBALS['obj']->xmlrpc_methods[$i];
|
||||
}
|
||||
|
||||
return $methods;
|
||||
}
|
||||
|
||||
// I know everyone hates wrappers, but this is the best way this can be done
|
||||
// The XML-RPC functions pass method_name as the first parameter, which is
|
||||
// unacceptable.
|
||||
// Another reason for this, is it might be possiable to pass the sessionid
|
||||
// and kp3 instead of using HTTP_AUTH features.
|
||||
// Would be a nice workaround for librarys that don't support it, as its
|
||||
// not in the XML-RPC spec.
|
||||
function xmlrpc_call_wrapper($method_name, $parameters)
|
||||
{
|
||||
$a = explode('.',$method_name);
|
||||
|
||||
if (count($parameters) == 0)
|
||||
{
|
||||
$return = $GLOBALS['obj']->$a[2]();
|
||||
}
|
||||
else if (count($parameters) == 1)
|
||||
{
|
||||
$return = $GLOBALS['obj']->$a[2]($parameters[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
for ($i=0; $i<count($parameters); $i++)
|
||||
{
|
||||
$p[] = '$parameters[' . $i . ']';
|
||||
}
|
||||
eval('$return = $GLOBALS[\'obj\']->$a[2](' . implode(',',$p) . ');');
|
||||
}
|
||||
|
||||
// This needs to be expanded and more fully tested
|
||||
if (gettype($return) == 'NULL')
|
||||
{
|
||||
return xmlrpc_error(1002,'No return value detected');
|
||||
}
|
||||
else
|
||||
{
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
|
||||
// The following are common functions used ONLY by XML-RPC
|
||||
function xmlrpc_login($method_name, $parameters)
|
||||
{
|
||||
$p = $parameters[0];
|
||||
|
||||
if ($p['domain'])
|
||||
{
|
||||
$username = $p['username'] . '@' . $p['domain'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$username = $p['username'];
|
||||
}
|
||||
|
||||
$sessionid = $GLOBALS['phpgw']->session->create($username,$p['password'],'text');
|
||||
$kp3 = $GLOBALS['phpgw']->session->kp3;
|
||||
$domain = $GLOBALS['phpgw']->session->account_domain;
|
||||
|
||||
if ($sessionid && $kp3)
|
||||
{
|
||||
return array(
|
||||
'sessionid' => $sessionid,
|
||||
'kp3' => $kp3,
|
||||
'domain' => $domain
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlrpc_error(1001,'Login failed');
|
||||
}
|
||||
}
|
||||
|
||||
function xmlrpc_logout($method, $parameters)
|
||||
{
|
||||
// We have already verified the session upon before this method is even created
|
||||
// As long as nothing happens upon, its safe to destroy the session without
|
||||
// fear of it being a hijacked session
|
||||
$GLOBALS['phpgw']->session->destroy($GLOBALS['phpgw']->session->sessionid,$GLOBALS['phpgw']->session->kp3);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user