2010-06-01 14:38:41 +02:00
|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* eGroupWare API: JSON - Contains functions and classes for doing JSON requests.
|
|
|
|
*
|
|
|
|
* @link http://www.egroupware.org
|
|
|
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
2010-06-01 16:20:55 +02:00
|
|
|
* @package api$request['menuaction'], $parameters
|
2010-06-01 14:38:41 +02:00
|
|
|
* @subpackage ajax
|
2010-06-01 20:54:31 +02:00
|
|
|
* @author Andreas Stoeckel <as@stylite.de>
|
2010-06-01 16:20:55 +02:00
|
|
|
* @version $Id$
|
2010-06-01 14:38:41 +02:00
|
|
|
*/
|
|
|
|
|
2010-06-01 20:54:31 +02:00
|
|
|
/**
|
|
|
|
* Class handling JSON requests to the server
|
|
|
|
*/
|
2010-06-01 14:38:41 +02:00
|
|
|
class egw_json_request
|
|
|
|
{
|
2010-06-01 20:54:31 +02:00
|
|
|
/**
|
|
|
|
* Parses the raw input data supplied with the input_data parameter and calls the menuaction
|
|
|
|
* passing all parameters supplied in the request to it.
|
|
|
|
*
|
|
|
|
* @param string menuaction to call
|
|
|
|
* @param string $input_data is the RAW input data as it was received from the client
|
|
|
|
* @returns NULL if parsing the request failed, or the result of the callback function if the request has been successfully decoded.
|
|
|
|
*/
|
2010-06-01 16:20:55 +02:00
|
|
|
public function parseRequest($menuaction, $input_data)
|
2010-06-01 14:38:41 +02:00
|
|
|
{
|
2010-06-01 16:20:55 +02:00
|
|
|
if (empty($input_data))
|
2010-06-01 14:38:41 +02:00
|
|
|
{
|
2010-06-01 16:20:55 +02:00
|
|
|
$this->handleRequest($menuaction, array());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-06-09 15:46:35 +02:00
|
|
|
if (get_magic_quotes_gpc())
|
2010-06-09 14:57:36 +02:00
|
|
|
{
|
2010-06-09 15:46:35 +02:00
|
|
|
$input_data[0] = stripslashes($input_data[0]);
|
2010-06-09 14:57:36 +02:00
|
|
|
}
|
2010-06-09 15:46:35 +02:00
|
|
|
|
|
|
|
//Decode the JSON input data into associative arrays
|
|
|
|
if (($json = json_decode($input_data[0], true)) !== false)
|
2010-06-01 14:38:41 +02:00
|
|
|
{
|
2010-06-09 15:46:35 +02:00
|
|
|
$parameters = array();
|
|
|
|
|
2010-06-01 16:20:55 +02:00
|
|
|
//Get the request array
|
|
|
|
if (isset($json['request']))
|
2010-06-01 14:38:41 +02:00
|
|
|
{
|
2010-06-01 16:20:55 +02:00
|
|
|
$request = $json['request'];
|
|
|
|
|
2010-06-01 14:38:41 +02:00
|
|
|
//Check whether any parameters were supplied along with the request
|
|
|
|
if (isset($request['parameters']))
|
2010-06-09 15:46:35 +02:00
|
|
|
$parameters = $request['parameters'];
|
|
|
|
/*$parameters = array_stripslashes($request['parameters']);*/
|
2010-06-01 14:38:41 +02:00
|
|
|
}
|
2010-06-09 15:46:35 +02:00
|
|
|
|
|
|
|
//Call the supplied callback function along with the menuaction and the passed parameters
|
|
|
|
$this->handleRequest($menuaction, $parameters);
|
2010-06-01 14:38:41 +02:00
|
|
|
}
|
2010-06-01 16:20:55 +02:00
|
|
|
}
|
2010-06-01 14:38:41 +02:00
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2010-06-01 20:54:31 +02:00
|
|
|
/**
|
|
|
|
* Request handler
|
|
|
|
*
|
|
|
|
* @param string $menuaction
|
|
|
|
* @param array $parameters
|
|
|
|
*/
|
|
|
|
public function handleRequest($menuaction, array $parameters)
|
2010-06-01 16:20:55 +02:00
|
|
|
{
|
|
|
|
if (strpos($menuaction,'::') !== false && strpos($menuaction,'.') === false) // static method name app_something::method
|
|
|
|
{
|
|
|
|
@list($className,$functionName,$handler) = explode('::',$menuaction);
|
|
|
|
list($appName) = explode('_',$className);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
@list($appName, $className, $functionName, $handler) = explode('.',$menuaction);
|
|
|
|
}
|
2010-06-02 20:11:15 +02:00
|
|
|
//error_log("json.php: appName=$appName, className=$className, functionName=$functionName, handler=$handler");
|
2010-06-01 16:20:55 +02:00
|
|
|
|
|
|
|
switch($handler)
|
|
|
|
{
|
2010-06-09 15:46:35 +02:00
|
|
|
case '/etemplate/process_exec':
|
2010-06-01 16:20:55 +02:00
|
|
|
$menuaction = $appName.'.'.$className.'.'.$functionName;
|
|
|
|
$appName = $className = 'etemplate';
|
|
|
|
$functionName = 'process_exec';
|
|
|
|
$menuaction = 'etemplate.etemplate.process_exec';
|
|
|
|
|
2010-06-09 15:46:35 +02:00
|
|
|
$parameters = array(
|
2010-06-01 16:20:55 +02:00
|
|
|
$argList[0]['etemplate_exec_id'],
|
|
|
|
$argList[0]['submit_button'],
|
|
|
|
$argList[0],
|
|
|
|
'xajaxResponse',
|
|
|
|
);
|
|
|
|
//error_log("xajax_doXMLHTTP() /etemplate/process_exec handler: arg0='$menuaction', menuaction='$_GET[menuaction]'");
|
2010-06-09 15:46:35 +02:00
|
|
|
break;
|
2010-06-01 16:20:55 +02:00
|
|
|
case 'etemplate': // eg. ajax code in an eTemplate widget
|
|
|
|
$menuaction = ($appName = 'etemplate').'.'.$className.'.'.$functionName;
|
|
|
|
break;
|
|
|
|
case 'template':
|
|
|
|
$menuaction = $appName.'.'.$className.'.'.$functionName;
|
|
|
|
list($template) = explode('_', $className);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(substr($className,0,4) != 'ajax' && substr($className,-4) != 'ajax' &&
|
|
|
|
$menuaction != 'etemplate.etemplate.process_exec' && substr($functionName,0,4) != 'ajax' ||
|
|
|
|
!preg_match('/^[A-Za-z0-9_]+(\.[A-Za-z0-9_]+\.|::)[A-Za-z0-9_]+$/',$menuaction))
|
|
|
|
{
|
|
|
|
// stopped for security reasons
|
|
|
|
error_log($_SERVER['PHP_SELF']. ' stopped for security reason. '.$menuaction.' is not valid. class- or function-name must start with ajax!!!');
|
|
|
|
// send message also to the user
|
|
|
|
throw new Exception($_SERVER['PHP_SELF']. ' stopped for security reason. '.$menuaction.' is not valid. class- or function-name must start with ajax!!!');
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isset($template))
|
|
|
|
{
|
2010-06-02 20:11:15 +02:00
|
|
|
if (!class_exists($className)) require_once(EGW_SERVER_ROOT.'/phpgwapi/templates/'.$template.'/class.'.$className.'.inc.php');
|
2010-06-01 16:20:55 +02:00
|
|
|
$ajaxClass = new $className;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$ajaxClass = CreateObject($appName.'.'.$className);
|
|
|
|
}
|
|
|
|
|
|
|
|
$parameters = translation::convert($parameters, 'utf-8');
|
|
|
|
|
|
|
|
call_user_func_array(array($ajaxClass, $functionName), $parameters);
|
|
|
|
}
|
2010-06-01 14:38:41 +02:00
|
|
|
}
|
|
|
|
|
2010-06-01 20:54:31 +02:00
|
|
|
/**
|
|
|
|
* Class used to send ajax responses
|
|
|
|
*/
|
2010-06-01 14:38:41 +02:00
|
|
|
class egw_json_response
|
|
|
|
{
|
2010-06-01 20:54:31 +02:00
|
|
|
/**
|
|
|
|
* A response can only contain one generic data part.
|
|
|
|
* This variable is used to store, whether a data part had already been added to the response.
|
|
|
|
*
|
|
|
|
* @var boolean
|
|
|
|
*/
|
2010-06-01 14:38:41 +02:00
|
|
|
private $hasData = false;
|
|
|
|
|
2010-06-01 20:54:31 +02:00
|
|
|
/**
|
|
|
|
* Holds the actual response data which is then encoded to JSON
|
|
|
|
* once the "getJSON" function is called
|
|
|
|
*
|
|
|
|
* @var array
|
|
|
|
*/
|
2010-06-01 14:38:41 +02:00
|
|
|
protected $responseArray = array();
|
|
|
|
|
2010-06-01 20:54:31 +02:00
|
|
|
/**
|
|
|
|
* Holding instance of class for singelton egw_json_response::get()
|
|
|
|
*
|
|
|
|
* @var egw_json_response
|
|
|
|
*/
|
2010-06-01 16:20:55 +02:00
|
|
|
private static $response = null;
|
|
|
|
|
2010-06-01 20:54:31 +02:00
|
|
|
/**
|
|
|
|
* Singelton for class
|
|
|
|
*
|
|
|
|
* @return egw_json_response
|
|
|
|
*/
|
2010-06-01 16:20:55 +02:00
|
|
|
public static function get()
|
|
|
|
{
|
|
|
|
if (!isset(self::$response))
|
|
|
|
{
|
|
|
|
self::$response = new egw_json_response();
|
|
|
|
}
|
|
|
|
return self::$response;
|
|
|
|
}
|
|
|
|
|
2010-06-01 20:54:31 +02:00
|
|
|
/**
|
|
|
|
* Private function used to send the HTTP header of the JSON response
|
|
|
|
*/
|
2010-06-01 16:20:55 +02:00
|
|
|
private function sendHeader()
|
|
|
|
{
|
|
|
|
//Send the character encoding header
|
|
|
|
header('content-type: application/json; charset='.translation::charset());
|
|
|
|
}
|
|
|
|
|
2010-06-01 20:54:31 +02:00
|
|
|
/**
|
|
|
|
* Private function which is used to send the result via HTTP
|
|
|
|
*/
|
|
|
|
public function sendResult()
|
2010-06-01 16:20:55 +02:00
|
|
|
{
|
|
|
|
$this->sendHeader();
|
|
|
|
echo $this->getJSON();
|
|
|
|
}
|
2010-06-01 20:54:31 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* xAjax compatibility function
|
|
|
|
*/
|
|
|
|
public function printOutput()
|
|
|
|
{
|
|
|
|
// do nothing, as output is triggered by destructor
|
|
|
|
}
|
2010-06-01 16:20:55 +02:00
|
|
|
|
2010-06-01 20:54:31 +02:00
|
|
|
/**
|
|
|
|
* Adds any type of data to the response array
|
|
|
|
*/
|
2010-06-01 14:38:41 +02:00
|
|
|
protected function addGeneric($key, $data)
|
|
|
|
{
|
|
|
|
$this->responseArray[] = array(
|
2010-06-01 20:54:31 +02:00
|
|
|
'type' => $key,
|
|
|
|
'data' => $data,
|
|
|
|
);
|
2010-06-01 14:38:41 +02:00
|
|
|
}
|
|
|
|
|
2010-06-01 20:54:31 +02:00
|
|
|
/**
|
|
|
|
* Adds a "data" response to the json response.
|
|
|
|
*
|
|
|
|
* This function may only be called once for a single JSON response object.
|
|
|
|
*
|
|
|
|
* @param object|array|string $data can be of any data type and will be added JSON Encoded to your response.
|
|
|
|
*/
|
2010-06-01 16:20:55 +02:00
|
|
|
public function data($data)
|
2010-06-01 14:38:41 +02:00
|
|
|
{
|
|
|
|
/* Only allow adding the data response once */
|
|
|
|
if (!$this->hasData)
|
|
|
|
{
|
|
|
|
$this->addGeneric('data', $data);
|
|
|
|
$this->hasData = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
throw new Exception("Adding more than one data response to a JSON response is not allowed.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-06-01 20:54:31 +02:00
|
|
|
/**
|
|
|
|
* Adds an "alert" to the response which can be handeled on the client side.
|
|
|
|
*
|
|
|
|
* The default implementation simply displays the text supplied here with the JavaScript function "alert".
|
|
|
|
*
|
|
|
|
* @param string $message contains the actual message being sent to the client.
|
|
|
|
* @param string $details (optional) can be used to inform the user on the client side about additional details about the error. This might be information how the error can be resolved/why it was raised or simply some debug data.
|
|
|
|
*/
|
2010-06-01 16:20:55 +02:00
|
|
|
public function alert($message, $details = '')
|
2010-06-01 14:38:41 +02:00
|
|
|
{
|
|
|
|
if (is_string($message) && is_string($details))
|
|
|
|
{
|
|
|
|
$this->addGeneric('alert', array(
|
|
|
|
"message" => $message,
|
|
|
|
"details" => $details));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
throw new Exception("Invalid parameters supplied.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-06-01 20:54:31 +02:00
|
|
|
/**
|
|
|
|
* Allows to add a generic java script to the response which will be executed upon the request gets received.
|
|
|
|
*
|
|
|
|
* @deprecated
|
|
|
|
* @param string $script the script code which should be executed upon receiving
|
|
|
|
*/
|
2010-06-01 16:20:55 +02:00
|
|
|
public function script($script)
|
2010-06-01 14:38:41 +02:00
|
|
|
{
|
|
|
|
if (is_string($script))
|
|
|
|
{
|
|
|
|
$this->addGeneric('script', $script);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
throw new Exception("Invalid parameters supplied.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-06-01 20:54:31 +02:00
|
|
|
/**
|
|
|
|
* Adds an html assign to the response, which is excecuted upon the request is received.
|
|
|
|
*
|
|
|
|
* @deprecated just for compatibility with XAJAX
|
|
|
|
* @param string $id id of dom element to modify
|
|
|
|
* @param string $key attribute name of dom element which should be modified
|
|
|
|
* @param string $value the value which should be assigned to the given attribute
|
|
|
|
*/
|
2010-06-01 16:20:55 +02:00
|
|
|
public function assign($id, $key, $value)
|
2010-06-01 14:38:41 +02:00
|
|
|
{
|
|
|
|
if (is_string($id) && is_string($key) && (is_string($value) || is_numeric($value)))
|
|
|
|
{
|
|
|
|
$this->addGeneric('assign', array(
|
2010-06-01 20:54:31 +02:00
|
|
|
'id' => $id,
|
|
|
|
'key' => $key,
|
|
|
|
'value' => $value,
|
|
|
|
));
|
2010-06-01 14:38:41 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
throw new Exception("Invalid parameters supplied");
|
|
|
|
}
|
|
|
|
}
|
2010-06-01 20:54:31 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Redirect to given url
|
|
|
|
*
|
|
|
|
* @param string $url
|
|
|
|
*/
|
|
|
|
public function redirect($url)
|
|
|
|
{
|
2010-06-02 10:10:43 +02:00
|
|
|
//self::script("location.href = '$url';");
|
|
|
|
$this->addGeneric('redirect', $url);
|
2010-06-01 20:54:31 +02:00
|
|
|
}
|
2010-06-01 14:38:41 +02:00
|
|
|
|
2010-06-01 20:54:31 +02:00
|
|
|
/**
|
|
|
|
* Returns the actual JSON code generated by calling the above "add" function.
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
2010-06-01 14:38:41 +02:00
|
|
|
public function getJSON()
|
|
|
|
{
|
|
|
|
/* Wrap the result array into a parent "response" Object */
|
2010-06-01 20:54:31 +02:00
|
|
|
$res = array('response' => $this->responseArray);
|
|
|
|
|
2010-06-02 20:11:15 +02:00
|
|
|
return json_encode($res); //PHP5.3+, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP);
|
2010-06-01 14:38:41 +02:00
|
|
|
}
|
2010-06-01 16:20:55 +02:00
|
|
|
|
2010-06-01 20:54:31 +02:00
|
|
|
/**
|
|
|
|
* Destructor
|
|
|
|
*/
|
2010-06-01 16:20:55 +02:00
|
|
|
public function __destruct()
|
|
|
|
{
|
|
|
|
$this->sendResult();
|
|
|
|
}
|
2010-06-01 14:38:41 +02:00
|
|
|
}
|
2010-06-09 15:46:35 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Deprecated legacy xajax wrapper functions for the new egw_json interface
|
|
|
|
*/
|
|
|
|
|
|
|
|
class xajaxResponse extends egw_json_response
|
|
|
|
{
|
|
|
|
public function addScript($script)
|
|
|
|
{
|
|
|
|
$this->script($script);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function addAlert($message)
|
|
|
|
{
|
|
|
|
$this->alert($message, '');
|
|
|
|
}
|
|
|
|
|
|
|
|
public function addAssign($id, $key, $value)
|
|
|
|
{
|
|
|
|
$this->assign($id, $key, $value);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function addRedirect($url)
|
|
|
|
{
|
|
|
|
$this->redirect($url);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getXML()
|
|
|
|
{
|
|
|
|
return '';
|
|
|
|
}
|
|
|
|
}
|