class to send push notifications to a logged in user

This commit is contained in:
Ralf Becker 2014-08-22 14:29:18 +00:00
parent b0e97a61e6
commit 3b49416788
2 changed files with 328 additions and 206 deletions

View File

@ -15,7 +15,6 @@
*/
class egw_json_request
{
private static $_hadJSONRequest = false;
/**
@ -166,198 +165,10 @@ class egw_json_request
}
/**
* Class used to send ajax responses
* Abstract class implementing different type of JSON messages understood by client-side
*/
class egw_json_response
abstract class egw_json_msg
{
/**
* 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
*/
private $hasData = false;
/**
* Array containing all beforeSendData callbacks
*/
protected $beforeSendDataProcs = array();
/**
* Holds the actual response data which is then encoded to JSON
* once the "getJSON" function is called
*
* @var array
*/
protected $responseArray = array();
/**
* Holding instance of class for singelton egw_json_response::get()
*
* @var egw_json_response
*/
private static $response = null;
/**
* Force use of singleton: $response = egw_json_response::get();
*/
private function __construct()
{
}
/**
* Singelton for class
*
* @return egw_json_response
*/
public static function get()
{
if (!isset(self::$response))
{
self::$response = new egw_json_response();
self::sendHeader();
}
return self::$response;
}
public static function isJSONResponse()
{
return isset(self::$response);
}
/**
* Do we have a JSON response to send back
*
* @return boolean
*/
public function haveJSONResponse()
{
return $this->responseArray || $this->beforeSendDataProcs;
}
/**
* Private function used to send the HTTP header of the JSON response
*/
private function sendHeader()
{
$file = $line = null;
if (headers_sent($file, $line))
{
error_log(__METHOD__."() header already sent by $file line $line: ".function_backtrace());
}
else
{
//Send the character encoding header
header('content-type: application/json; charset='.translation::charset());
}
}
/**
* Private function which is used to send the result via HTTP
*/
public static function sendResult()
{
$inst = self::get();
//Call each attached before send data proc
foreach ($inst->beforeSendDataProcs as $proc)
{
call_user_func_array($proc['proc'], $proc['params']);
}
// check if application made some direct output
if (($output = ob_get_clean()))
{
if (!$inst->haveJSONResponse())
{
error_log(__METHOD__."() adding output with inst->addGeneric('html', '$output')");
$inst->addGeneric('html', $output);
}
else
{
$inst->alert('Application echoed something', $output);
}
}
echo $inst->getJSON();
$inst->initResponseArray();
}
/**
* Return json response data, after running beforeSendDataProcs
*
* Used to send json response with etemplate data in GET request
*
* @return array responseArray
*/
public static function returnResult()
{
$inst = self::get();
//Call each attached before send data proc
foreach ($inst->beforeSendDataProcs as $proc)
{
call_user_func_array($proc['proc'], $proc['params']);
}
return $inst->initResponseArray();
}
/**
* xAjax compatibility function
*/
public function printOutput()
{
// do nothing, as output is triggered by egw::__destruct()
}
/**
* Adds any type of data to the response array
*/
protected function addGeneric($key, $data)
{
self::get()->responseArray[] = array(
'type' => $key,
'data' => $data,
);
}
/**
* Init responseArray
*
* @param array $arr
* @return array previous content
*/
public function initResponseArray()
{
$return = $this->responseArray;
$this->responseArray = $this->beforeSendDataProcs = array();
$this->hasData = false;
return $return;
}
/**
* 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.
*/
public function data($data)
{
/* Only allow adding the data response once */
$inst = self::get();
if (!$inst->hasData)
{
$inst->addGeneric('data', $data);
$inst->hasData = true;
}
else
{
throw new Exception("Adding more than one data response to a JSON response is not allowed.");
}
}
/**
* Adds an "alert" to the response which can be handeled on the client side.
*
@ -401,7 +212,7 @@ class egw_json_response
/**
* Allows to call a global javascript function with given parameters: window[$func].apply(window, $parameters)
*
* @param string $func name of the global (window) javascript function to call
* @param string $function name of the global (window) javascript function to call
* @param array $parameters =array()
*/
public function apply($function,array $parameters=array())
@ -555,7 +366,213 @@ class egw_json_response
{
if (is_string($url))
{
self::get()->addGeneric('js', $url);
$this->addGeneric('js', $url);
}
}
/**
* Adds any type of data to the message
*
* @param string $key
* @param mixed $data
*/
abstract protected function addGeneric($key, $data);
}
/**
* Class used to send ajax responses
*/
class egw_json_response extends egw_json_msg
{
/**
* 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
*/
private $hasData = false;
/**
* Array containing all beforeSendData callbacks
*/
protected $beforeSendDataProcs = array();
/**
* Holds the actual response data which is then encoded to JSON
* once the "getJSON" function is called
*
* @var array
*/
protected $responseArray = array();
/**
* Holding instance of class for singelton egw_json_response::get()
*
* @var egw_json_response
*/
private static $response = null;
/**
* Force use of singleton: $response = egw_json_response::get();
*/
protected function __construct()
{
}
/**
* Singelton for class
*
* @return egw_json_response
*/
public static function get()
{
if (!isset(self::$response))
{
self::$response = new egw_json_response();
self::sendHeader();
}
return self::$response;
}
public static function isJSONResponse()
{
return isset(self::$response);
}
/**
* Do we have a JSON response to send back
*
* @return boolean
*/
public function haveJSONResponse()
{
return $this->responseArray || $this->beforeSendDataProcs;
}
/**
* Private function used to send the HTTP header of the JSON response
*/
private function sendHeader()
{
$file = $line = null;
if (headers_sent($file, $line))
{
error_log(__METHOD__."() header already sent by $file line $line: ".function_backtrace());
}
else
{
//Send the character encoding header
header('content-type: application/json; charset='.translation::charset());
}
}
/**
* Private function which is used to send the result via HTTP
*/
public static function sendResult()
{
$inst = self::get();
//Call each attached before send data proc
foreach ($inst->beforeSendDataProcs as $proc)
{
call_user_func_array($proc['proc'], $proc['params']);
}
// check if application made some direct output
if (($output = ob_get_clean()))
{
if (!$inst->haveJSONResponse())
{
error_log(__METHOD__."() adding output with inst->addGeneric('html', '$output')");
$inst->addGeneric('html', $output);
}
else
{
$inst->alert('Application echoed something', $output);
}
}
echo $inst->getJSON();
$inst->initResponseArray();
}
/**
* Return json response data, after running beforeSendDataProcs
*
* Used to send json response with etemplate data in GET request
*
* @return array responseArray
*/
public static function returnResult()
{
$inst = self::get();
//Call each attached before send data proc
foreach ($inst->beforeSendDataProcs as $proc)
{
call_user_func_array($proc['proc'], $proc['params']);
}
return $inst->initResponseArray();
}
/**
* xAjax compatibility function
*/
public function printOutput()
{
// do nothing, as output is triggered by egw::__destruct()
}
/**
* Adds any type of data to the message
*
* @param string $key
* @param mixed $data
*/
protected function addGeneric($key, $data)
{
self::get()->responseArray[] = array(
'type' => $key,
'data' => $data,
);
}
/**
* Init responseArray
*
* @param array $arr
* @return array previous content
*/
public function initResponseArray()
{
$return = $this->responseArray;
$this->responseArray = $this->beforeSendDataProcs = array();
$this->hasData = false;
return $return;
}
/**
* 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.
*/
public function data($data)
{
/* Only allow adding the data response once */
$inst = self::get();
if (!$inst->hasData)
{
$inst->addGeneric('data', $data);
$inst->hasData = true;
}
else
{
throw new Exception("Adding more than one data response to a JSON response is not allowed.");
}
}

View File

@ -0,0 +1,105 @@
<?php
/**
* EGroupware API: push JSON commands to client
*
* @link http://www.egroupware.org
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package api
* @subpackage ajax
* @author Ralf Becker <rb@stylite.de>
* @version $Id$
*/
/**
* Class to push JSON commands to client
*/
class egw_json_push extends egw_json_msg
{
/**
* Available backends to try
*
* @var array
*/
protected static $backends = array(
'notifications_push',
);
/**
* Backend to use
*
* @var egw_json_push_backend
*/
protected static $backend;
/**
* account_id we are pushing too
*
* @var int
*/
protected $account_id;
/**
*
* @param int $account_id account_id of user to push to
*/
public function __construct($account_id)
{
$this->account_id = $account_id;
}
/**
* Adds any type of data to the message
*
* @param string $key
* @param mixed $data
* @throws egw_json_push_exception_not_online if $account_id is not online
*/
protected function addGeneric($key, $data)
{
if (!isset(self::$backend))
{
foreach(self::$backends as $class)
{
if (class_exists($class))
{
try {
self::$backend = new $class;
break;
}
catch (Exception $e) {
// ignore exception
unset($e, self::$backend);
}
}
}
if (!isset(self::$backend))
{
throw new egw_json_push_exception_not_online('No valid push-backend found!');
}
}
self::$backend->addGeneric($this->account_id, $key, $data);
}
}
/**
* Interface for push backends
*/
interface egw_json_push_backend
{
/**
* Adds any type of data to the message
*
* @param int $account_id account_id to push message too
* @param string $key
* @param mixed $data
* @throws egw_json_push_exception_not_online if $account_id is not online
*/
public function addGeneric($account_id, $key, $data);
}
/**
* Exception thrown, if message can not be pushed
*/
class egw_json_push_exception_not_online extends egw_exception_not_found
{
}