diff --git a/notifications/inc/class.iface_notification.inc.php b/notifications/inc/class.iface_notification.inc.php new file mode 100644 index 0000000000..872bc56706 --- /dev/null +++ b/notifications/inc/class.iface_notification.inc.php @@ -0,0 +1,31 @@ + + * @version $Id: $ + */ + +/** + * Instant user notification + */ +interface iface_notification { + + /** + * constructor + * + * @param object $_account + * @param object $_preferences + */ + public function __construct( $_account, $_preferences ); + + /** + * sends notification + * + * @param string $_message + */ + public function send( $_message ); +} diff --git a/notifications/inc/class.notification.inc.php b/notifications/inc/class.notification.inc.php new file mode 100644 index 0000000000..f490463946 --- /dev/null +++ b/notifications/inc/class.notification.inc.php @@ -0,0 +1,128 @@ + + * @version $Id: $ + */ + +/** + * Notifies users according to there preferences. + * + * @abstract NOTE:Notifications are small messages. No subject and no attechments. + * If you need this kind of elements you probably want to send a mail, woun't you :-) + * @abstract NOTE: This is for instant notifications. If you need time dependend notifications use the + * asyncservices wrapper! + * + * The classes doing the notifications are called notification_ and should only be + * called from this class. + * The gets extractd out of the preferences labels. + * + */ +final class notification { + + /** + * Appname + */ + const _appname = 'notifications'; + + /** + * array with objects of receivers + * @var array + */ + private $receivers = array(); + + /** + * holds notification message + * @var string + */ + private $message = ''; + + /** + * sets notification message + * @param string &$message + */ + public function set_message($_message) { + $this->message = $_message; + return true; + } + + /** + * Set receivers for the current notification + * + * @param array $_receivers array with objects of accounts + * as long as the accounts class isn't a nice object, it's an array of account id's :-( + */ + public function set_receivers(array $_receivers) { + foreach ($_receivers as $receiver_id) { + $receiver = $GLOBALS['egw']->accounts->get_account_data($receiver_id); + $receiver[$receiver_id]['id'] = $receiver_id; + $this->receivers[$receiver_id] = (object)$receiver[$receiver_id]; + } + } + + /** + * sends notification + */ + public function send() { + if (empty($this->receivers) || !$this->message) { + throw new Exception('Error: Coud not send notification. No receiver or no message where supplied'); + } + + foreach ($this->receivers as $receiver) { + $prefs = new preferences($receiver->id); + $preferences = $prefs->read(); + $preferences = (object)$preferences[self::_appname ]; + + if (!$preferences->disable_ajaxpopup) { + $notification_backends[] = 'notification_popup'; + } + + $send_succseed = 0; + foreach ((array)$notification_backends as $notification_backend) { + try { + require_once(EGW_INCLUDE_ROOT. SEP. self::_appname. SEP. 'inc'. SEP. 'class.'. $notification_backend. '.inc.php'); + + $obj = @new $notification_backend( $receiver, $preferences ); + if ( !is_a( $obj, iface_notification )) { + unset ( $obj ); + throw new Exception('Error: '.$notification_backend. ' is no implementation of iface_notification'); + } + + $obj->send( $this->message ); + $send_succseed++; + } + catch (Exception $exception) { + $send_succseed--; + echo $exception->getMessage(), "\n"; + } + } + + if ($send_succseed == 0) { + throw new Exception('Error: Was not able to send Notification to user!'); + } + } + } + + /** + * gets message + * + * @return string + */ + public function get_message() { + return $this->message; + } + + /** + * gets receivers + * + * @return array of account objects + */ + public function get_receivers() { + return $this->receivers; + } + +} diff --git a/notifications/inc/class.notification_popup.inc.php b/notifications/inc/class.notification_popup.inc.php new file mode 100644 index 0000000000..452ed22db6 --- /dev/null +++ b/notifications/inc/class.notification_popup.inc.php @@ -0,0 +1,163 @@ + + * @version $Id: $ + */ + +require_once('class.iface_notification.inc.php'); + +/** + * Instant user notification with egroupware popup. + * egwpopup is a two stage notification. In the first stage + * notification is written into self::_notification_egwpopup + * table. In the second stage a request from the client reads + * out the table to look if there is a notificaton for this + * client. (multidisplay is supported) + */ +class notification_popup implements iface_notification { + + /** + * Notification window {div|alert} + */ + const _window = 'div'; + + /** + * Appname + */ + const _appname = 'notifications'; + + /** + * Notification table in SQL database + */ + const _notification_table = 'egw_notificationpopup'; + + /** + * holds account object for user to notify + * + * @var object + */ + private $account; + + /** + * holds preferences object of user to notify + * + * @var unknown_type + */ + private $preferences; + + /** + * holds db object of SQL database + * + * @var unknown_type + */ + private $db; + + /** + * constructor of notification_egwpopup + * + * @param object $_account + * @param object $_preferences + */ + public function __construct( $_account=false, $_preferences=false) { + // If we are called from class notification account and prefs are objects. + // otherwise we have to fetch this objects for current user. + if (!is_object($_account)) { + $account_id = $GLOBALS['egw_info']['user']['account_id']; + $this->account = $GLOBALS['egw']->accounts->get_account_data($account_id); + $this->account[$account_id]['id'] = $account_id; + $this->account = (object)$this->account[$account_id]; + } + else { + $this->account = $_account; + } + $this->preferences = is_object($_preferences) ? $_preferences : $GLOBALS['egw']->preferences; + $this->db = &$GLOBALS['egw']->db; + $this->db->set_app( self::_appname ); + } + + /** + * sends notification if user is online + * + * @param string $_message + */ + public function send( $_message ) { + $sessions = $GLOBALS['egw']->session->list_sessions(0, 'asc', 'session_dla', true); + $user_sessions = array(); + foreach ($sessions as $session) { + if ($session['session_lid'] == $this->account->lid. '@'. $GLOBALS['egw_info']['user']['domain']) { + $user_sessions[] = $session['session_id']; + } + } + if ( empty($user_sessions) ) throw new Exception("Notice: User isn't online. Can't send notification via popup"); + $this->save( $_message, $user_sessions ); + } + + /** + * Gets all notification for current user. + * Requests and response is done via xajax + * + * @return xajax response + */ + public function ajax_get_notifications() { + $response =& new xajaxResponse(); + $session_id = $GLOBALS['egw_info']['user']['sessionid']; + $message = ''; + $this->db->select(self::_notification_table, + '*', array( + 'account_id' => $this->account->id, + 'session_id' => $session_id, + ), + __LINE__,__FILE__); + if ($this->db->num_rows() != 0) { + while ($notification = $this->db->row(true)) { + switch (self::_window ) { + case 'div' : + $message .= nl2br($notification['message']). '
'; + break; + case 'alert' : + $message .= $notification['message']. "\n"; + break; + } + } + $this->db->delete(self::_notification_table,array( + 'account_id' =>$this->account->id, + 'session_id' => $session_id, + ),__LINE__,__FILE__); + + switch (self::_window) { + case 'div' : + $response->addAppend('notificationwindow_message','innerHTML',$message); + $response->addScript('notificationwindow_display();'); + break; + case 'alert' : + $response->addAlert($message); + break; + } + } + return $response->getXML(); + } + + /** + * saves notification into database so that the client can fetch it from + * there via notification->get + * + * @param string $_message + * @param array $_user_sessions + */ + private function save( $_message, array $_user_sessions ) { + foreach ($_user_sessions as $user_session) { + $result =& $this->db->insert( self::_notification_table, array( + 'account_id' => $this->account->id, + 'session_id' => $user_session, + 'message' => $_message + ), false,__LINE__,__FILE__); + } + if ($result === false) throw new Exception("Error: Can't save notification into SQL table"); + } +} diff --git a/notifications/inc/class.uinotificationprefs.inc.php b/notifications/inc/class.uinotificationprefs.inc.php new file mode 100644 index 0000000000..b6644a34c7 --- /dev/null +++ b/notifications/inc/class.uinotificationprefs.inc.php @@ -0,0 +1,83 @@ + + * @version $Id: $ + */ + +require_once(EGW_INCLUDE_ROOT. SEP. 'etemplate'. SEP. 'inc'. SEP. 'class.etemplate.inc.php'); + +class uinotificationprefs { + + const _appname = 'notifications'; + + public $public_functions = array( + 'index' => true, + ); + + /** + * This are the preferences for notifications + * + * @var array + */ + private $notification_preferences = array( + 'disable_ajaxpopup' => '', // bool: true / false + ); + + /** + * Holds preferences object for current user + * + * @var object + */ + private $preferences; + + public function __construct($_account_id = 0, $_referer = false) { + $account_id = $_account_id > 0 ? $_account_id : $GLOBALS['egw_info']['user']['account_id']; + $this->preferences = new preferences($account_id); + $GLOBALS['egw_info']['flags']['app_header'] = lang('Preferences for notification'); + } + + public function index($_content = false) { + $et = new etemplate(self::_appname. '.prefsindex'); + $content = array(); + $sel_options = array(); + $readonlys = array(); + $preserv = array(); + if (is_array($_content)) { + if (is_array($_content['button'])) { + $preferences = array_intersect_key($_content, $this->notification_preferences); + list($button) = each($_content['button']); + switch ($button) { + case 'save' : + $this->save($preferences); + $GLOBALS['egw']->redirect_link($_content['referer']); + case 'apply' : + $this->save($preferences); + break; + case 'cancel' : + default : + $GLOBALS['egw']->redirect_link($_content['referer']); + } + } + } + else { + $preferences = $this->preferences->read(); + $preferences = $preferences[self::_appname]; + $preserv['referer'] = $GLOBALS['egw']->common->get_referer(); + } + + $content = array_merge($content,(array)$preferences); + return $et->exec(self::_appname. '.uinotificationprefs.index',$content,$sel_options,$readonlys,$preserv); + } + + private function save($_preferences) { + $this->preferences->read(); + $this->preferences->user[self::_appname] = $_preferences; + $this->preferences->save_repository(); + return; + } +} \ No newline at end of file diff --git a/notifications/inc/hook_after_navbar.inc.php b/notifications/inc/hook_after_navbar.inc.php new file mode 100644 index 0000000000..5e96f7325a --- /dev/null +++ b/notifications/inc/hook_after_navbar.inc.php @@ -0,0 +1,29 @@ + + * @version $Id: $ + * @todo check if user wants notifications via egw popup! + */ +$GLOBALS['egw']->translation->add_app('notifications'); +if (!$GLOBALS['egw_info']['user']['preferences']['notifications']['disable_ajaxpopup']) { + echo ''; + echo ''; + echo ' +