AntonLV пре 12 година
родитељ
комит
4502aaacd7
26 измењених фајлова са 922 додато и 0 уклоњено
  1. 71 0
      modules/boonex/notifications/classes/BxNtfsConfig.php
  2. 135 0
      modules/boonex/notifications/classes/BxNtfsDb.php
  3. 127 0
      modules/boonex/notifications/classes/BxNtfsModule.php
  4. 63 0
      modules/boonex/notifications/classes/BxNtfsResponse.php
  5. 145 0
      modules/boonex/notifications/classes/BxNtfsTemplate.php
  6. 75 0
      modules/boonex/notifications/install/config.php
  7. 22 0
      modules/boonex/notifications/install/installer.php
  8. 19 0
      modules/boonex/notifications/install/langs/en.xml
  9. 27 0
      modules/boonex/notifications/install/sql/disable.sql
  10. 40 0
      modules/boonex/notifications/install/sql/enable.sql
  11. 46 0
      modules/boonex/notifications/install/sql/install.sql
  12. 12 0
      modules/boonex/notifications/install/sql/uninstall.sql
  13. 28 0
      modules/boonex/notifications/js/main.js
  14. 42 0
      modules/boonex/notifications/js/view.js
  15. 19 0
      modules/boonex/notifications/request.php
  16. 6 0
      modules/boonex/notifications/template/block_view.html
  17. 0 0
      modules/boonex/notifications/template/css/view-media-desktop.css
  18. 0 0
      modules/boonex/notifications/template/css/view-media-tablet.css
  19. 24 0
      modules/boonex/notifications/template/css/view.css
  20. 1 0
      modules/boonex/notifications/template/empty.html
  21. 18 0
      modules/boonex/notifications/template/event.html
  22. 2 0
      modules/boonex/notifications/template/events.html
  23. BIN
      modules/boonex/notifications/template/images/icons/std-mi.png
  24. BIN
      modules/boonex/notifications/template/images/icons/std-pi.png
  25. BIN
      modules/boonex/notifications/template/images/icons/std-si.png
  26. BIN
      modules/boonex/notifications/template/images/icons/std-wi.png

+ 71 - 0
modules/boonex/notifications/classes/BxNtfsConfig.php

@@ -0,0 +1,71 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    Notifications Notifications
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import('BxDolPrivacy');
+bx_import('BxBaseModNotificationsConfig');
+
+class BxNtfsConfig extends BxBaseModNotificationsConfig
+{  
+    /**
+     * Constructor
+     */
+    public function __construct($aModule)
+    {
+        parent::__construct($aModule);
+
+		$this->_aPrefixes = array(
+        	'style' => 'bx-ntfs',
+        	'language' => '_bx_ntfs',
+        	'option' => 'bx_notifications_'
+        );
+
+        $this->_aHandlerDescriptor = array('module_name' => '', 'module_method' => '', 'module_class' => '');
+        $this->_sHandlersMethod = 'get_notifications_data';
+
+        $this->_aJsClass = array(
+            'main' => 'BxNtfsMain',
+        	'view' => 'BxNtfsView',
+        );
+        $this->_aJsObjects = array(
+            'view' => 'oBxNtfsView',
+        );
+
+        $sHtmlPrefix = str_replace('_', '-', $this->_sName);
+        $this->_aHtmlIds = array(
+        	'view' => array(
+        		'block' => $sHtmlPrefix,
+        		'events' => $sHtmlPrefix . '-events',
+        		'event' => $sHtmlPrefix . '-event-'
+        	)
+        );
+    }
+
+    public function init(&$oDb)
+    {
+    	parent::init($oDb);
+
+    	$sOptionPrefix = $this->getPrefix('option');
+    	$this->_aPerPage = array(
+    		'default' => (int)getParam($sOptionPrefix . 'events_per_page')
+    	);
+    }
+
+    /**
+     * Ancillary functions
+     */
+    public function getViewUrl()
+    {
+        bx_import('BxDolPermalinks');
+        return BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=notifications-view');
+    }
+}
+
+/** @} */

+ 135 - 0
modules/boonex/notifications/classes/BxNtfsDb.php

@@ -0,0 +1,135 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    Notifications Notifications
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import('BxBaseModNotificationsDb');
+
+class BxNtfsDb extends BxBaseModNotificationsDb
+{
+    protected $_sTableEvt2Usr;
+
+    /*
+     * Constructor.
+     */
+    function __construct(&$oConfig)
+    {
+        parent::__construct($oConfig);
+        $this->_sTableEvt2Usr = $this->_sPrefix . 'events2users';
+    }
+
+    
+    public function getEvents($aParams, $bReturnCount = false)
+    {
+        $sMethod = 'getAll';
+        $sJoinClause = $sWhereClause = $sOrderClause = $sLimitClause = "";
+
+        if(isset($aParams['active']))
+        	$sWhereClause .= $this->prepare("AND `{$this->_sTable}`.`active`=? ", (int)$aParams['active']);
+
+        switch($aParams['browse']) {
+            case 'id':
+                $sMethod = 'getRow';
+                $sWhereClause = $this->prepare("AND `{$this->_sTable}`.`id`=? ", $aParams['value']);
+                $sLimitClause = "LIMIT 1";
+                break;
+
+            case 'descriptor':
+                $sMethod = 'getRow';
+                $sWhereClause = $this->prepare("AND `{$this->_sTable}`.`type`=? AND `{$this->_sTable}`.`action`=? AND `{$this->_sTable}`.`object_id`=? ", $aParams['type'], $aParams['action'], $aParams['object_id']);
+                $sLimitClause = "LIMIT 1";
+                break;
+
+            case 'first':
+            case 'last':
+            case 'list':
+                //--- Apply modules or handlers filter
+                $sWhereModuleFilter = '';
+                if(isset($aParams['modules']) && !empty($aParams['modules']) && is_array($aParams['modules']))
+                    $sWhereModuleFilter = "AND `type` IN (" . $this->implode_escape($aParams['modules']) . ") ";
+
+                if($sWhereModuleFilter == '') {
+                    $aHidden = $this->_oConfig->getHandlersHidden();
+                    $sWhereModuleFilter = is_array($aHidden) && !empty($aHidden) ? "AND `th`.`id` NOT IN (" . $this->implode_escape($aHidden) . ") " : "";
+                }
+
+                if($sWhereModuleFilter == '')
+                    $sWhereClause .= $sWhereModuleFilter;
+
+				//--- Check flag 'New'
+            	if(!empty($aParams['new']) && !empty($aParams['owner_id'])) {
+            		$sSql = $this->prepare("SELECT `event_id` FROM `" . $this->_sTableEvt2Usr . "` WHERE `user_id`=? LIMIT 1", (int)$aParams['owner_id']);
+    				$iId = (int)$this->getOne($sSql);
+
+        			$sWhereClause .= $this->prepare("AND `{$this->_sTable}`.`id`>? ", $iId);
+            	}
+
+                //--- Check type
+                if(!empty($aParams['owner_id']))
+                    switch($aParams['type']) {
+                        case BX_BASE_MOD_NTFS_TYPE_OWNER:
+                            $sWhereClause .= $this->prepare("AND `{$this->_sTable}`.`owner_id`=? ", $aParams['owner_id']);
+                            break;
+
+                        case BX_BASE_MOD_NTFS_TYPE_CONNECTIONS:
+                            bx_import('BxDolConnection');
+                            $oConnection = BxDolConnection::getObjectInstance($this->_oConfig->getObject('conn_subscriptions'));
+
+                            $aQueryParts = $oConnection->getConnectedContentAsSQLParts($this->_sPrefix . "events", 'owner_id', $aParams['owner_id']);
+                            $sJoinClause .= ' ' . $aQueryParts['join'];
+                            break;
+                    }
+
+                switch($aParams['browse']) {
+                	case 'first':
+                        $sMethod = 'getRow';
+                        $sOrderClause = "ORDER BY `{$this->_sTable}`.`date` DESC";
+                        $sLimitClause = "LIMIT 1";
+                        break;
+                    case 'last':
+                        $sMethod = 'getRow';
+                        $sOrderClause = "ORDER BY `{$this->_sTable}`.`date` ASC";
+                        $sLimitClause = "LIMIT 1";
+                        break;
+                    case 'list':
+                        $sOrderClause = "ORDER BY `{$this->_sTable}`.`date` DESC";
+                        $sLimitClause = isset($aParams['per_page']) ? "LIMIT " . $aParams['start'] . ", " . $aParams['per_page'] : "";
+                        break;
+                }
+                break;
+        }
+
+        $sSql = "SELECT " . ($bReturnCount ? "SQL_CALC_FOUND_ROWS" : "") . "
+                `{$this->_sTable}`.`id` AS `id`,
+                `{$this->_sTable}`.`owner_id` AS `owner_id`,
+                `{$this->_sTable}`.`type` AS `type`,
+                `{$this->_sTable}`.`action` AS `action`,
+                `{$this->_sTable}`.`object_id` AS `object_id`,
+                `{$this->_sTable}`.`content` AS `content`,
+                `{$this->_sTable}`.`date` AS `date`,
+                YEAR(FROM_UNIXTIME(`{$this->_sTable}`.`date`)) AS `year`
+            FROM `{$this->_sTable}`
+            LEFT JOIN `{$this->_sTableHandlers}` ON `{$this->_sTable}`.`type`=`{$this->_sTableHandlers}`.`alert_unit` AND `{$this->_sTable}`.`action`=`{$this->_sTableHandlers}`.`alert_action` " . $sJoinClause . "
+            WHERE 1 " . $sWhereClause . " " . $sOrderClause . " " . $sLimitClause;
+
+        $aEntries = $this->$sMethod($sSql);
+        if(!$bReturnCount)
+        	return $aEntries;
+
+        return array($aEntries, (int)$this->getOne("SELECT FOUND_ROWS()"));
+    }
+
+    public function markAsRead($iUserId, $iEventId)
+    {
+    	$sSql = $this->prepare("REPLACE `" . $this->_sTableEvt2Usr . "` SET `user_id`=?, `event_id`=?", $iUserId, $iEventId);
+    	return (int)$this->query($sSql) > 0;
+    }
+}
+
+/** @} */

+ 127 - 0
modules/boonex/notifications/classes/BxNtfsModule.php

@@ -0,0 +1,127 @@
+<?php use nspace\func;
+defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    Notifications Notifications
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import('BxDolAcl');
+bx_import('BxBaseModNotificationsModule');
+
+define('BX_NTFS_TYPE_DEFAULT', BX_BASE_MOD_NTFS_TYPE_CONNECTIONS);
+
+class BxNtfsModule extends BxBaseModNotificationsModule
+{
+    /**
+     * Constructor
+     */
+    function __construct($aModule)
+    {
+        parent::__construct($aModule);
+
+        $this->_iOwnerId = $this->getUserId();
+    }
+
+    /**
+     * ACTION METHODS
+     */
+    function actionGetPosts()
+    {
+        $aParams = $this->_prepareParamsGet();
+        $sEvents = $this->_oTemplate->getPosts($aParams);
+
+        $this->_echoResultJson(array('events' => $sEvents));
+    }
+
+    /**
+     * SERVICE METHODS
+     * 
+     * Get View block for a separate page. Will return a block with "Empty" message if nothing found.
+     */
+    public function serviceGetBlockView($iStart = -1, $iPerPage = -1, $aModules = array())
+    {
+    	$iOwnerId = $this->getUserId();
+        if(!$iOwnerId)
+            return array('content' => MsgBox(_t('_bx_timeline_txt_msg_no_results')));
+
+		$aParams = $this->_prepareParams(BX_NTFS_TYPE_DEFAULT, $iOwnerId, $iStart, $iPerPage, $aModules);
+		$sContent = $this->_oTemplate->getViewBlock($aParams);
+
+		$aParams['browse'] = 'first';
+    	$aEvent = $this->_oDb->getEvents($aParams);
+    	if(!empty($aEvent))
+			$this->_oDb->markAsRead($iOwnerId, $aEvent['id']);
+
+        return array('content' => $sContent); 
+    }
+
+    public function serviceGetUnreadNotificationsNum($iOwnerId = 0)
+    {
+    	if(!$iOwnerId)
+			$iOwnerId = $this->getUserId();
+
+		if(!$iOwnerId)
+			return 0;
+
+		$aParams = $this->_prepareParams(BX_NTFS_TYPE_DEFAULT, $iOwnerId);
+		$aParams['new'] = 1;
+
+		list($aEvent, $iCount) = $this->_oDb->getEvents($aParams, true);
+		return $iCount;
+    }
+
+    /*
+     * COMMON METHODS
+     */
+    public function onPost($iId)
+    {
+    	//--- Event -> Post for Alerts Engine ---//
+        bx_import('BxDolAlerts');
+        $oAlert = new BxDolAlerts($this->_oConfig->getSystemName('alert'), 'post', $iId);
+        $oAlert->alert();
+        //--- Event -> Post for Alerts Engine ---//
+    }
+
+    protected function _prepareParams($sType = '', $iOwnerId = 0, $iStart = -1, $iPerPage = -1, $aModules = array())
+    {
+        $aParams = array();
+        $aParams['browse'] = 'list';
+        $aParams['type'] = !empty($sType) ? $sType : BX_NTFS_TYPE_DEFAULT;
+        $aParams['owner_id'] = (int)$iOwnerId != 0 ? $iOwnerId : $this->getUserId();
+        $aParams['start'] = (int)$iStart > 0 ? $iStart : 0;
+        $aParams['per_page'] = (int)$iPerPage > 0 ? $iPerPage : $this->_oConfig->getPerPage();
+        $aParams['modules'] = is_array($aModules) && !empty($aModules) ? $aModules : array();
+        $aParams['active'] = 1;
+
+        return $aParams;
+    }
+
+	protected function _prepareParamsGet()
+    {
+        $aParams = array();
+        $aParams['browse'] = 'list';
+
+        $sType = bx_get('type');
+        $aParams['type'] = $sType !== false ? bx_process_input($sType, BX_DATA_TEXT) : BX_NTFS_TYPE_DEFAULT;
+
+        $aParams['owner_id'] = $sType !== false ? bx_process_input(bx_get('owner_id'), BX_DATA_INT) : $this->getUserId();
+
+        $iStart = bx_get('start');
+        $aParams['start'] = $iStart !== false ? bx_process_input($iStart, BX_DATA_INT) : 0;
+
+        $iPerPage = bx_get('per_page');
+        $aParams['per_page'] = $iPerPage !== false ? bx_process_input($iPerPage, BX_DATA_INT) : $this->_oConfig->getPerPage();
+
+        $aModules = bx_get('modules');
+        $aParams['modules'] = $aModules !== false ? bx_process_input($aModules, BX_DATA_TEXT) : array();
+
+        return $aParams;
+    }
+}
+
+/** @} */

+ 63 - 0
modules/boonex/notifications/classes/BxNtfsResponse.php

@@ -0,0 +1,63 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    Notifications Notifications
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import('BxBaseModNotificationsResponse');
+
+class BxNtfsResponse extends BxBaseModNotificationsResponse
+{
+    public function __construct()
+    {
+        parent::__construct();
+
+        bx_import('BxDolModule');
+        $this->_oModule = BxDolModule::getInstance('bx_notifications');
+    }
+
+    /**
+     * Overwtire the method of parent class.
+     *
+     * @param BxDolAlerts $oAlert an instance of alert.
+     */
+    public function response($oAlert)
+    {
+    	$iPrivacyView = $this->_getPrivacyView($oAlert->aExtras);
+        if($iPrivacyView == BX_DOL_PG_HIDDEN)
+            return;
+
+        $aHandler = $this->_oModule->_oConfig->getHandlers($oAlert->sUnit . '_' . $oAlert->sAction);
+        switch($aHandler['type']) {
+            case BX_BASE_MOD_NTFS_HANDLER_TYPE_INSERT:
+                $iId = $this->_oModule->_oDb->insertEvent(array(
+                    'owner_id' => $oAlert->iSender,
+                    'type' => $oAlert->sUnit,
+                    'action' => $oAlert->sAction,
+                    'object_id' => $oAlert->iObject,
+                    'object_privacy_view' => $iPrivacyView,
+                    'content' => '',
+                ));
+
+				if(!empty($iId))
+					$this->_oModule->onPost($iId);
+
+				break;
+
+            case BX_BASE_MOD_NTFS_HANDLER_TYPE_UPDATE:
+                $this->_oModule->_oDb->updateEvent(array('object_privacy_view' => $iPrivacyView), array('type' => $oAlert->sUnit, 'object_id' => $oAlert->iObject));
+                break;
+
+            case BX_BASE_MOD_NTFS_HANDLER_TYPE_DELETE:
+                $this->_oModule->_oDb->deleteEvent(array('type' => $oAlert->sUnit, 'object_id' => $oAlert->iObject));
+                break;
+        }
+    }
+}
+
+/** @} */

+ 145 - 0
modules/boonex/notifications/classes/BxNtfsTemplate.php

@@ -0,0 +1,145 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    Notifications Notifications
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import('BxBaseModNotificationsTemplate');
+
+class BxNtfsTemplate extends BxBaseModNotificationsTemplate
+{
+    function __construct(&$oConfig, &$oDb)
+    {
+        parent::__construct($oConfig, $oDb);
+    }
+
+    public function getViewBlock($aParams)
+    {
+        return $this->parseHtmlByName('block_view.html', array(
+        	'html_id_view_block' => $this->_oConfig->getHtmlIds('view', 'block'),
+        	'html_id_events' => $this->_oConfig->getHtmlIds('view', 'events'),
+            'style_prefix' => $this->_oConfig->getPrefix('style'),
+            'content' => $this->getPosts($aParams),
+            'js_content' => $this->getJsCode('view', array(
+                'type' => $aParams['type'],
+                'owner_id' => $aParams['owner_id'],
+                'start' => $aParams['start'],
+                'per_page' => $aParams['per_page'],
+                'modules' => $aParams['modules']
+            ))
+        ));
+    }
+
+    public function getPosts($aParams)
+    {
+    	$sJsObject = $this->_oConfig->getJsObject('view');
+
+    	$aParamsDb = $aParams;
+    	$aParamsDb['per_page'] = $aParamsDb['per_page'] + 1;
+
+        $aEvents = $this->_oDb->getEvents($aParamsDb);
+        if(empty($aEvents))
+        	return $this->getEmpty();
+
+        bx_import('BxTemplPaginate');
+        $oPaginate = new BxTemplPaginate(array(
+        	'start' => $aParams['start'],
+            'per_page' => $aParams['per_page'],
+        	'page_url' => $this->_oConfig->getViewUrl(),
+        	'on_change_page' => $sJsObject . ".changePage(this, {start}, {per_page})"
+        ));
+        $oPaginate->setNumFromDataArray($aEvents);
+
+        $sEvents = '';
+        foreach($aEvents as $aEvent) {
+            $sEvent = $this->getPost($aEvent, $aParams);
+            if(empty($sEvent))
+                continue;
+
+            $sEvents .= $sEvent;
+        }
+
+        return $this->parseHtmlByName('events.html', array(
+        	'style_prefix' => $this->_oConfig->getPrefix('style'),
+        	'events' => $sEvents,
+        	'paginate' => $oPaginate->getSimplePaginate()
+        ));
+    }
+
+    public function getPost(&$aEvent, $aBrowseParams = array())
+    {
+    	$oModule = $this->getModule();
+
+    	if(empty($aEvent['content'])) {
+    		$aContent = $this->_getContent($aEvent);
+    		if(!empty($aContent) && is_array($aContent)) {
+    			$aEvent['content'] = serialize($aContent);
+
+    			$this->_oDb->updateEvent(array('content' => $aEvent['content']), array('id' => $aEvent['id']));
+    		}
+    	}
+
+        list($sOwnerName, $sOwnerUrl, $sOwnerIcon) = $oModule->getUserInfo($aEvent['owner_id']);
+        $bAuthorIcon = !empty($sOwnerIcon);
+
+        $aContent = unserialize($aEvent['content']);
+        $aContent['owner_name'] = $sOwnerName;
+        $aContent['owner_link'] = $sOwnerUrl;
+
+    	$sContent = _t(!empty($aContent['lang_key']) ? $aContent['lang_key'] : '_bx_ntfs_txt_item_added');
+    	$sContent = $this->parseHtmlByContent($sContent, $aContent, array('{', '}'));
+
+        return $this->parseHtmlByName('event.html', array (
+        	'html_id' => $this->_oConfig->getHtmlIds('view', 'event') . $aEvent['id'],
+            'style_prefix' => $this->_oConfig->getPrefix('style'),
+            'js_object' => $this->_oConfig->getJsObject('view'),
+            'id' => $aEvent['id'],
+            'bx_if:show_icon' => array(
+                'condition' => $bAuthorIcon,
+                'content' => array(
+                    'author_icon' => $sOwnerIcon
+                )
+            ),
+            'bx_if:show_icon_empty' => array(
+                'condition' => !$bAuthorIcon,
+                'content' => array()
+            ),
+            'content' => $sContent,
+            'date' => bx_time_js($aEvent['date']),
+        ));
+    }
+
+    public function getEmpty($bVisible = true)
+    {
+        return $this->parseHtmlByName('empty.html', array(
+            'style_prefix' => $this->_oConfig->getPrefix('style'),
+            'visible' => $bVisible ? 'block' : 'none',
+            'content' => MsgBox(_t('_bx_ntfs_txt_msg_no_results'))
+        ));
+    }
+
+    protected function _getContent(&$aEvent)
+    {
+        $sHandler = $aEvent['type'] . '_' . $aEvent['action'];
+        if(!$this->_oConfig->isHandler($sHandler))
+            return array();
+
+        $aHandler = $this->_oConfig->getHandlers($sHandler);
+        if(!empty($aHandler['module_name']) && !empty($aHandler['module_class']) && !empty($aHandler['module_method']))
+        	return BxDolService::call($aHandler['module_name'], $aHandler['module_method'], array($aEvent), $aHandler['module_class']);
+        
+
+        $sMethod = 'display' . bx_gen_method_name($aHandler['alert_unit'] . '_' . $aHandler['alert_action']);
+		if(!method_exists($this, $sMethod))
+        	return array();
+
+		return $this->$sMethod($aEvent);
+    }
+}
+
+/** @} */

+ 75 - 0
modules/boonex/notifications/install/config.php

@@ -0,0 +1,75 @@
+<?php
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    Notifications Notifications
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_notifications',
+    'title' => 'Notifications',
+    'note' => 'Notifications module.',
+    'version' => '8.0.0',
+    'vendor' => 'BoonEx',
+    'update_url' => '',
+
+    'compatible_with' => array(
+        '8.0.x'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/notifications/',
+    'home_uri' => 'notifications',
+
+    'db_prefix' => 'bx_notifications_',
+    'class_prefix' => 'BxNtfs',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Notifications',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'uninstall' => array (
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'enable' => array(
+        'execute_sql' => 1,
+        'recompile_permalinks' => 1,
+        'recompile_alerts' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable' => array (
+        'execute_sql' => 1,
+        'recompile_permalinks' => 1,
+        'recompile_alerts' => 1,
+        'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Dependencies Section
+     */
+    'dependencies' => array(),
+
+);
+
+/** @} */

+ 22 - 0
modules/boonex/notifications/install/installer.php

@@ -0,0 +1,22 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    Notifications Notifications
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import('BxBaseModNotificationsInstaller');
+
+class BxNtfsInstaller extends BxBaseModNotificationsInstaller
+{
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+    }
+}
+
+/** @} */

+ 19 - 0
modules/boonex/notifications/install/langs/en.xml

@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources name="en" flag="gb" title="English">
+	<string name="_bx_ntfs"><![CDATA[Notifications]]></string>
+
+	<string name="_bx_ntfs_page_title_system_view"><![CDATA[Notifications]]></string>
+	<string name="_bx_ntfs_page_title_view"><![CDATA[Notifications]]></string>
+	<string name="_bx_ntfs_page_block_title_view"><![CDATA[Notifications]]></string>
+
+    <string name="_bx_ntfs_menu_item_title_system_notifications"><![CDATA[Notifications]]></string>
+    <string name="_bx_ntfs_menu_item_title_notifications"><![CDATA[Notifications]]></string>
+
+	<string name="_bx_ntfs_option_events_per_page"><![CDATA[Number of events are displayed on View page]]></string>
+	<string name="_bx_ntfs_option_events_hide"><![CDATA[Hide events from Notifications]]></string>
+
+	<string name="_bx_ntfs_alert_action_added"><![CDATA[add]]></string>
+
+	<string name="_bx_ntfs_txt_msg_no_results"><![CDATA[Empty]]></string>
+	<string name="_bx_ntfs_txt_item_added"><![CDATA[<a href="{owner_link}">{owner_name}</a> added a new {entry_sample} <a href="{entry_url}">{entry_caption}</a>]]></string>
+</resources>

+ 27 - 0
modules/boonex/notifications/install/sql/disable.sql

@@ -0,0 +1,27 @@
+SET @sName = 'bx_notifications';
+
+
+-- PAGES & BLOCKS
+DELETE FROM `sys_objects_page` WHERE `module` = @sName;
+DELETE FROM `sys_pages_blocks` WHERE `module` = @sName;
+
+
+-- MENU
+DELETE FROM `sys_menu_items` WHERE `module` = @sName;
+
+
+-- SETTINGS
+SET @iTypeId = (SELECT `ID` FROM `sys_options_types` WHERE `name` = @sName LIMIT 1);
+SET @iCategId = (SELECT `ID` FROM `sys_options_categories` WHERE `type_id` = @iTypeId LIMIT 1);
+DELETE FROM `sys_options` WHERE `category_id` = @iCategId;
+DELETE FROM `sys_options_categories` WHERE `type_id` = @iTypeId;
+DELETE FROM `sys_options_types` WHERE `id` = @iTypeId;
+
+
+-- ALERTS
+SET @iHandlerId = (SELECT `id` FROM `sys_alerts_handlers` WHERE `name` = @sName LIMIT 1);
+DELETE FROM `sys_alerts_handlers` WHERE `id` = @iHandlerId LIMIT 1;
+
+
+-- MODULES' CONNECTIONS
+DELETE FROM `sys_modules_connections` WHERE `module`=@sName LIMIT 1;

+ 40 - 0
modules/boonex/notifications/install/sql/enable.sql

@@ -0,0 +1,40 @@
+SET @sName = 'bx_notifications';
+
+
+-- PAGES & BLOCKS
+INSERT INTO `sys_objects_page`(`object`, `title_system`, `title`, `module`, `layout_id`, `visible_for_levels`, `visible_for_levels_editable`, `uri`, `url`, `meta_description`, `meta_keywords`, `meta_robots`, `cache_lifetime`, `cache_editable`, `deletable`, `override_class_name`, `override_class_file`) VALUES 
+('bx_notifications_view', '_bx_ntfs_page_title_system_view', '_bx_ntfs_page_title_view', @sName, 5, 2147483647, 1, 'notifications-view', 'page.php?i=notifications-view', '', '', '', 0, 1, 0, '', '');
+
+INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES
+('bx_notifications_view', 1, @sName, '_bx_ntfs_page_block_title_view', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:16:"bx_notifications";s:6:"method";s:14:"get_block_view";}', 0, 0, 1);
+
+
+-- MENU: Notifications
+SET @iMIOrder = (SELECT MAX(`order`) FROM `sys_menu_items` WHERE `set_name` = 'sys_account_notifications');
+INSERT INTO `sys_menu_items` (`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `addon`, `submenu_object`, `visible_for_levels`, `active`, `copyable`, `order`) VALUES
+('sys_account_notifications', @sName, 'notifications-notifications', '_bx_ntfs_menu_item_title_system_notifications', '_bx_ntfs_menu_item_title_notifications', 'page.php?i=notifications-view', '', '', 'bell col-green3', 'a:2:{s:6:"module";s:16:"bx_notifications";s:6:"method";s:28:"get_unread_notifications_num";}', '', 2147483646, 1, 0, @iMIOrder + 1);
+
+
+-- SETTINGS
+SET @iTypeOrder = (SELECT MAX(`order`) FROM `sys_options_types` WHERE `group` = 'modules');
+INSERT INTO `sys_options_types`(`group`, `name`, `caption`, `icon`, `order`) VALUES 
+('modules', @sName, '_bx_ntfs', 'bx_notifications@modules/boonex/notifications/|std-mi.png', IF(ISNULL(@iTypeOrder), 1, @iTypeOrder + 1));
+SET @iTypeId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options_categories` (`type_id`, `name`, `caption`, `order`)
+VALUES (@iTypeId, @sName, '_bx_ntfs', 1);
+SET @iCategId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options` (`name`, `value`, `category_id`, `caption`, `type`, `check`, `check_params`, `check_error`, `extra`, `order`) VALUES
+('bx_notifications_events_per_page', '10', @iCategId, '_bx_ntfs_option_events_per_page', 'digit', '', '', '', '', 1),
+('bx_notifications_events_hide', '', @iCategId, '_bx_ntfs_option_events_hide', 'list', '', '', '', 'a:2:{s:6:"module";s:16:"bx_notifications";s:6:"method";s:21:"get_actions_checklist";}', 2);
+
+
+-- ALERTS
+INSERT INTO `sys_alerts_handlers`(`name`, `class`, `file`, `service_call`) VALUES 
+(@sName, 'BxNtfsResponse', 'modules/boonex/notifications/classes/BxNtfsResponse.php', '');
+
+
+-- MODULES' CONNECTIONS
+INSERT INTO `sys_modules_connections` (`module`, `on_install`, `on_uninstall`, `on_enable`, `on_disable`) VALUES
+(@sName, '', 'delete_module_events', 'add_handlers', 'delete_handlers');

+ 46 - 0
modules/boonex/notifications/install/sql/install.sql

@@ -0,0 +1,46 @@
+SET @sName = 'bx_notifications';
+
+
+-- TABLES
+CREATE TABLE IF NOT EXISTS `bx_notifications_events` (
+  `id` int(11) NOT NULL auto_increment,
+  `owner_id` int(11) unsigned NOT NULL default '0',
+  `type` varchar(255) collate utf8_unicode_ci NOT NULL,
+  `action` varchar(255) collate utf8_unicode_ci NOT NULL,
+  `object_id` text collate utf8_unicode_ci NOT NULL,
+  `object_privacy_view` int(11) NOT NULL default '3',
+  `content` text collate utf8_unicode_ci NOT NULL,
+  `date` int(11) NOT NULL default '0',
+  `active` tinyint(4) NOT NULL default '1',
+  PRIMARY KEY  (`id`),
+  KEY `owner_id` (`owner_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_notifications_events2users` (
+  `user_id` int(11) NOT NULL DEFAULT '0',
+  `event_id` int(11) NOT NULL DEFAULT '0',
+  PRIMARY KEY (`user_id`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
+
+CREATE TABLE IF NOT EXISTS `bx_notifications_handlers` (
+  `id` int(11) NOT NULL auto_increment,
+  `type` enum('insert','update','delete') NOT NULL DEFAULT 'insert',
+  `alert_unit` varchar(64) NOT NULL default '',
+  `alert_action` varchar(64) NOT NULL default '',
+  `content` text collate utf8_unicode_ci NOT NULL,
+  PRIMARY KEY  (`id`),
+  UNIQUE `handler` (`alert_unit`, `alert_action`)
+);
+
+
+-- STUDIO PAGE & WIDGET
+INSERT INTO `sys_std_pages`(`index`, `name`, `header`, `caption`, `icon`) VALUES
+(3, @sName, '_bx_ntfs', '_bx_ntfs', 'bx_notifications@modules/boonex/notifications/|std-pi.png');
+SET @iPageId = LAST_INSERT_ID();
+
+SET @iParentPageId = (SELECT `id` FROM `sys_std_pages` WHERE `name` = 'home');
+SET @iParentPageOrder = (SELECT MAX(`order`) FROM `sys_std_pages_widgets` WHERE `page_id` = @iParentPageId);
+INSERT INTO `sys_std_widgets` (`page_id`, `module`, `url`, `click`, `icon`, `caption`, `cnt_notices`, `cnt_actions`) VALUES
+(@iPageId, @sName, '{url_studio}module.php?name=bx_notifications', '', 'bx_notifications@modules/boonex/notifications/|std-wi.png', '_bx_ntfs', '', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:11:"get_actions";s:6:"params";a:0:{}s:5:"class";s:18:"TemplStudioModules";}');
+INSERT INTO `sys_std_pages_widgets` (`page_id`, `widget_id`, `order`) VALUES
+(@iParentPageId, LAST_INSERT_ID(), IF(ISNULL(@iParentPageOrder), 1, @iParentPageOrder + 1));

+ 12 - 0
modules/boonex/notifications/install/sql/uninstall.sql

@@ -0,0 +1,12 @@
+SET @sName = 'bx_notifications';
+
+
+DROP TABLE IF EXISTS `bx_notifications_events`;
+DROP TABLE IF EXISTS `bx_notifications_events2users`;
+DROP TABLE IF EXISTS `bx_notifications_handlers`;
+
+
+-- STUDIO PAGE & WIDGET
+DELETE FROM `tp`, `tw`, `tpw`
+USING `sys_std_pages` AS `tp`, `sys_std_widgets` AS `tw`, `sys_std_pages_widgets` AS `tpw`
+WHERE `tp`.`id` = `tw`.`page_id` AND `tw`.`id` = `tpw`.`widget_id` AND `tp`.`name` = @sName;

+ 28 - 0
modules/boonex/notifications/js/main.js

@@ -0,0 +1,28 @@
+function BxNtfsMain() {}
+
+BxNtfsMain.prototype.loadingInButton = function(e, bShow) {
+	if($(e).length)
+		bx_loading_btn($(e), bShow);
+	else
+		bx_loading($('body'), bShow);	
+};
+
+BxNtfsMain.prototype.loadingInItem = function(e, bShow) {
+	var oParent = $(e).length ? $(e).parents('.bx-ntfs-item:first') : $('body'); 
+	bx_loading(oParent, bShow);
+};
+
+BxNtfsMain.prototype.loadingInBlock = function(e, bShow) {
+	var oParent = $(e).length ? $(e).parents('.bx-db-container:first') : $('body'); 
+	bx_loading(oParent, bShow);
+};
+
+BxNtfsMain.prototype._loading = function(e, bShow) {
+	var oParent = $(e).length ? $(e) : $('body'); 
+	bx_loading(oParent, bShow);
+};
+
+BxNtfsMain.prototype._getDefaultData = function () {
+	var oDate = new Date();
+    return jQuery.extend({}, this._oRequestParams, {_t:oDate.getTime()});
+};

+ 42 - 0
modules/boonex/notifications/js/view.js

@@ -0,0 +1,42 @@
+function BxNtfsView(oOptions) {
+	this._sActionsUri = oOptions.sActionUri;
+    this._sActionsUrl = oOptions.sActionUrl;
+    this._sObjName = oOptions.sObjName == undefined ? 'oNtfsView' : oOptions.sObjName;
+    this._iOwnerId = oOptions.iOwnerId == undefined ? 0 : oOptions.iOwnerId;
+    this._sAnimationEffect = oOptions.sAnimationEffect == undefined ? 'slide' : oOptions.sAnimationEffect;
+    this._iAnimationSpeed = oOptions.iAnimationSpeed == undefined ? 'slow' : oOptions.iAnimationSpeed;
+    this._aHtmlIds = oOptions.aHtmlIds == undefined ? {} : oOptions.aHtmlIds;
+    this._oRequestParams = oOptions.oRequestParams == undefined ? {} : oOptions.oRequestParams;
+}
+
+BxNtfsView.prototype = new BxNtfsMain();
+
+BxNtfsView.prototype.changePage = function(oElement, iStart, iPerPage) {
+	this._oRequestParams.start = iStart;
+    this._oRequestParams.per_page = iPerPage;
+
+    this._getPosts(oElement);
+};
+
+BxNtfsView.prototype._getPosts = function(oElement) {
+    var $this = this;
+
+    this.loadingInBlock(oElement, true);
+
+    jQuery.get(
+        this._sActionsUrl + 'get_posts/',
+        this._getDefaultData(),
+        function(oData) {
+        	if(oData && oData.events != undefined) {
+        		var sEvents = $.trim(oData.events);
+
+        		$this.loadingInBlock(oElement, false);
+
+    			$('#' + $this._aHtmlIds['events']).bx_anim('hide', $this._sAnimationEffect, $this._iAnimationSpeed, function() {
+	                $(this).html(sEvents).show().bxTime();
+	            });
+        	}
+        },
+        'json'
+    );
+};

+ 19 - 0
modules/boonex/notifications/request.php

@@ -0,0 +1,19 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    Persons Persons
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+require_once(BX_DIRECTORY_PATH_INC . "design.inc.php");
+
+bx_import('BxDolLanguages');
+bx_import('BxDolRequest');
+
+BxDolRequest::processAsAction($GLOBALS['aModule'], $GLOBALS['aRequest']);
+
+/** @} */

+ 6 - 0
modules/boonex/notifications/template/block_view.html

@@ -0,0 +1,6 @@
+<div id="__html_id_view_block__" class="__style_prefix__-view bx-def-bc-margin">
+	<div class="__style_prefix__-cnt">
+		<div id="__html_id_events__" class="__style_prefix__-events">__content__</div>
+	</div>
+    __js_content__
+</div>

+ 0 - 0
modules/boonex/notifications/template/css/view-media-desktop.css


+ 0 - 0
modules/boonex/notifications/template/css/view-media-tablet.css


+ 24 - 0
modules/boonex/notifications/template/css/view.css

@@ -0,0 +1,24 @@
+/*--- View Block Style ---*/
+div.bx-ntfs-view {
+	position: relative;
+}
+
+/*--- Event Style ---*/
+div.bx-ntfs-event {
+	position: relative;
+}
+div.bx-ntfs-event-cnt {
+	position: relative;
+	overflow: hidden;
+}
+div.bx-ntfs-owner-avatar {
+	position: absolute;
+	top: 0px;
+	left: 0px;
+}
+
+/*--- Empty Style ---*/
+div.bx-ntfs-empty div.bx-msg-box-container {
+	margin-top: 0px;
+	margin-bottom: 0px;
+}

+ 1 - 0
modules/boonex/notifications/template/empty.html

@@ -0,0 +1 @@
+<div class="__style_prefix__-empty" style="display:__visible__;">__content__</div>

+ 18 - 0
modules/boonex/notifications/template/event.html

@@ -0,0 +1,18 @@
+<div id="__html_id__" class="__style_prefix__-event bx-def-margin-sec-top-auto bx-def-round-corners bx-def-color-bg-sec">
+    <div class="__style_prefix__-event-gap bx-def-padding-sec">
+    	<div class="__style_prefix__-event-cnt">
+	       	<div class="__style_prefix__-owner-avatar bx-def-thumb bx-def-thumb-size">
+				<bx_if:show_icon>
+					<img class="bx-def-thumb bx-def-thumb-size" src="__author_icon__" />
+				</bx_if:show_icon>
+				<bx_if:show_icon_empty>
+					<i class="sys-icon user"></i>
+				</bx_if:show_icon_empty>
+			</div>
+			<div class="__style_prefix__-body bx-def-thumb-size-min-height bx-def-thumb-size-left-indent">
+				<div class="__style_prefix__-content">__content__</div>
+				<div class="__style_prefix__-date bx-def-margin-sec-top">__date__</div>
+			</div>
+		</div>
+	</div>
+</div>

+ 2 - 0
modules/boonex/notifications/template/events.html

@@ -0,0 +1,2 @@
+__events__
+<div class="__style_prefix__-paginate bx-def-margin-sec-top">__paginate__</div>

BIN
modules/boonex/notifications/template/images/icons/std-mi.png


BIN
modules/boonex/notifications/template/images/icons/std-pi.png


BIN
modules/boonex/notifications/template/images/icons/std-si.png


BIN
modules/boonex/notifications/template/images/icons/std-wi.png